structuralcodes 0.4.0__py3-none-any.whl → 0.6.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of structuralcodes might be problematic. Click here for more details.
- structuralcodes/__init__.py +1 -1
- structuralcodes/codes/ec2_2004/__init__.py +2 -0
- structuralcodes/codes/ec2_2004/shear.py +44 -4
- structuralcodes/codes/mc2010/__init__.py +18 -0
- structuralcodes/codes/mc2010/_concrete_creep_and_shrinkage.py +2 -2
- structuralcodes/codes/mc2010/_concrete_punching.py +300 -388
- structuralcodes/core/base.py +116 -5
- structuralcodes/geometry/__init__.py +2 -8
- structuralcodes/geometry/_circular.py +3 -10
- structuralcodes/geometry/_geometry.py +58 -114
- structuralcodes/geometry/_rectangular.py +3 -10
- structuralcodes/geometry/_reinforcement.py +9 -14
- structuralcodes/geometry/profiles/__init__.py +19 -0
- structuralcodes/geometry/profiles/_base_profile.py +305 -0
- structuralcodes/geometry/profiles/_common_functions.py +194 -0
- structuralcodes/geometry/profiles/_he.py +192 -0
- structuralcodes/geometry/profiles/_ipe.py +130 -0
- structuralcodes/geometry/profiles/_ipn.py +329 -0
- structuralcodes/geometry/profiles/_ub.py +264 -0
- structuralcodes/geometry/profiles/_ubp.py +227 -0
- structuralcodes/geometry/profiles/_uc.py +276 -0
- structuralcodes/geometry/profiles/_upn.py +315 -0
- structuralcodes/materials/__init__.py +2 -1
- structuralcodes/materials/basic/__init__.py +11 -0
- structuralcodes/materials/basic/_elastic.py +69 -0
- structuralcodes/materials/basic/_elasticplastic.py +92 -0
- structuralcodes/materials/basic/_generic.py +43 -0
- structuralcodes/materials/concrete/__init__.py +3 -0
- structuralcodes/materials/concrete/_concrete.py +10 -1
- structuralcodes/materials/concrete/_concreteEC2_2004.py +14 -0
- structuralcodes/materials/concrete/_concreteEC2_2023.py +14 -0
- structuralcodes/materials/concrete/_concreteMC2010.py +19 -0
- structuralcodes/materials/constitutive_laws/__init__.py +3 -0
- structuralcodes/materials/constitutive_laws/_elasticplastic.py +2 -2
- structuralcodes/materials/constitutive_laws/_initial_strain.py +130 -0
- structuralcodes/materials/reinforcement/__init__.py +6 -0
- structuralcodes/materials/reinforcement/_reinforcement.py +10 -1
- structuralcodes/materials/reinforcement/_reinforcementEC2_2004.py +15 -1
- structuralcodes/materials/reinforcement/_reinforcementEC2_2023.py +15 -1
- structuralcodes/materials/reinforcement/_reinforcementMC2010.py +15 -1
- structuralcodes/sections/_generic.py +53 -14
- structuralcodes/sections/_rc_utils.py +15 -5
- structuralcodes/sections/section_integrators/__init__.py +3 -1
- structuralcodes/sections/section_integrators/_fiber_integrator.py +19 -11
- structuralcodes/sections/section_integrators/_marin_integrator.py +25 -20
- {structuralcodes-0.4.0.dist-info → structuralcodes-0.6.0.dist-info}/METADATA +2 -2
- structuralcodes-0.6.0.dist-info/RECORD +77 -0
- structuralcodes/geometry/_steel_sections.py +0 -2155
- structuralcodes-0.4.0.dist-info/RECORD +0 -63
- /structuralcodes/{sections/section_integrators → core}/_marin_integration.py +0 -0
- {structuralcodes-0.4.0.dist-info → structuralcodes-0.6.0.dist-info}/WHEEL +0 -0
- {structuralcodes-0.4.0.dist-info → structuralcodes-0.6.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""A material class with elastic plastic properties."""
|
|
2
|
+
|
|
3
|
+
import typing as t
|
|
4
|
+
|
|
5
|
+
from ...core.base import Material
|
|
6
|
+
from ..constitutive_laws import create_constitutive_law
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ElasticPlasticMaterial(Material):
|
|
10
|
+
"""A material class with elastic plastic properties."""
|
|
11
|
+
|
|
12
|
+
_E: float
|
|
13
|
+
_fy: float
|
|
14
|
+
_Eh: float
|
|
15
|
+
_eps_su: float
|
|
16
|
+
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
E: float,
|
|
20
|
+
fy: float,
|
|
21
|
+
density: float,
|
|
22
|
+
Eh: float = 0,
|
|
23
|
+
eps_su: t.Optional[float] = None,
|
|
24
|
+
initial_strain: t.Optional[float] = None,
|
|
25
|
+
initial_stress: t.Optional[float] = None,
|
|
26
|
+
strain_compatibility: t.Optional[float] = None,
|
|
27
|
+
name: t.Optional[str] = None,
|
|
28
|
+
):
|
|
29
|
+
"""Initialize a material with an elastic plastic constitutive law.
|
|
30
|
+
|
|
31
|
+
Arguments:
|
|
32
|
+
E (float): The Young's modulus.
|
|
33
|
+
fy (float): The yield stress.
|
|
34
|
+
density (float): The density.
|
|
35
|
+
Eh (float, optional): The hardening modulus, default value 0.
|
|
36
|
+
eps_su (float, optional): The ultimate strain, default value None.
|
|
37
|
+
initial_strain (Optional[float]): Initial strain of the material.
|
|
38
|
+
initial_stress (Optional[float]): Initial stress of the material.
|
|
39
|
+
strain_compatibility (Optional[bool]): Only relevant if
|
|
40
|
+
initial_strain or initial_stress are different from zero. If
|
|
41
|
+
True, the material deforms with the geometry. If False, the
|
|
42
|
+
stress in the material upon loading is kept constant
|
|
43
|
+
corresponding to the initial strain.
|
|
44
|
+
name (str, optional): The name of the material, default value None.
|
|
45
|
+
"""
|
|
46
|
+
super().__init__(
|
|
47
|
+
density=density,
|
|
48
|
+
initial_strain=initial_strain,
|
|
49
|
+
initial_stress=initial_stress,
|
|
50
|
+
strain_compatibility=strain_compatibility,
|
|
51
|
+
name=name if name else 'ElasticPlasticMaterial',
|
|
52
|
+
)
|
|
53
|
+
self._E = E
|
|
54
|
+
self._fy = fy
|
|
55
|
+
self._Eh = Eh
|
|
56
|
+
self._eps_su = eps_su
|
|
57
|
+
|
|
58
|
+
self._constitutive_law = create_constitutive_law(
|
|
59
|
+
'elasticplastic', self
|
|
60
|
+
)
|
|
61
|
+
self._apply_initial_strain()
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def E(self) -> float:
|
|
65
|
+
"""Returns the Young's modulus."""
|
|
66
|
+
return self._E
|
|
67
|
+
|
|
68
|
+
@property
|
|
69
|
+
def fy(self) -> float:
|
|
70
|
+
"""Returns the yield stress."""
|
|
71
|
+
return self._fy
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def Eh(self) -> float:
|
|
75
|
+
"""Returns the hardening modulus."""
|
|
76
|
+
return self._Eh
|
|
77
|
+
|
|
78
|
+
@property
|
|
79
|
+
def eps_su(self) -> float:
|
|
80
|
+
"""Returns the ultimate strain."""
|
|
81
|
+
return self._eps_su
|
|
82
|
+
|
|
83
|
+
def __elasticplastic__(self) -> dict:
|
|
84
|
+
"""Returns kwargs for ElasticPlastic constitutive law with strain
|
|
85
|
+
hardening.
|
|
86
|
+
"""
|
|
87
|
+
return {
|
|
88
|
+
'E': self.E,
|
|
89
|
+
'fy': self.fy,
|
|
90
|
+
'Eh': self.Eh,
|
|
91
|
+
'eps_su': self.eps_su,
|
|
92
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""A generic material that could hold any type of constitutive law."""
|
|
2
|
+
|
|
3
|
+
import typing as t
|
|
4
|
+
|
|
5
|
+
from ...core.base import ConstitutiveLaw, Material
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class GenericMaterial(Material):
|
|
9
|
+
"""A material class that accepts any constitutive law."""
|
|
10
|
+
|
|
11
|
+
def __init__(
|
|
12
|
+
self,
|
|
13
|
+
density: float,
|
|
14
|
+
constitutive_law: ConstitutiveLaw,
|
|
15
|
+
initial_strain: t.Optional[float] = None,
|
|
16
|
+
initial_stress: t.Optional[float] = None,
|
|
17
|
+
strain_compatibility: t.Optional[bool] = None,
|
|
18
|
+
name: t.Optional[str] = None,
|
|
19
|
+
):
|
|
20
|
+
"""Initialize a material with a constitutive law.
|
|
21
|
+
|
|
22
|
+
Arguments:
|
|
23
|
+
density (float): The density.
|
|
24
|
+
constitutive_law (ConstitutiveLaw): The constitutive law of the
|
|
25
|
+
material.
|
|
26
|
+
initial_strain (Optional[float]): Initial strain of the material.
|
|
27
|
+
initial_stress (Optional[float]): Initial stress of the material.
|
|
28
|
+
strain_compatibility (Optional[bool]): Only relevant if
|
|
29
|
+
initial_strain or initial_stress are different from zero. If
|
|
30
|
+
True, the material deforms with the geometry. If False, the
|
|
31
|
+
stress in the material upon loading is kept constant
|
|
32
|
+
corresponding to the initial strain.
|
|
33
|
+
name (str, optional): The name of the material, default value None.
|
|
34
|
+
"""
|
|
35
|
+
super().__init__(
|
|
36
|
+
density=density,
|
|
37
|
+
initial_strain=initial_strain,
|
|
38
|
+
initial_stress=initial_stress,
|
|
39
|
+
strain_compatibility=strain_compatibility,
|
|
40
|
+
name=name if name else 'GenericMaterial',
|
|
41
|
+
)
|
|
42
|
+
self._constitutive_law = constitutive_law
|
|
43
|
+
self._apply_initial_strain()
|
|
@@ -49,6 +49,9 @@ def create_concrete(
|
|
|
49
49
|
desired standard. If None (default) the globally used design
|
|
50
50
|
standard will be adopted. Otherwise the design standard specified
|
|
51
51
|
will be used for the instance of the material.
|
|
52
|
+
**kwargs: Other valid keyword arguments that are collected and passed
|
|
53
|
+
to the specific concrete material. Please inspect the documentation
|
|
54
|
+
of the other concrete materials to see valid arguments.
|
|
52
55
|
|
|
53
56
|
Raises:
|
|
54
57
|
ValueError: if the design code is not valid or does not cover concrete
|
|
@@ -21,10 +21,19 @@ class Concrete(Material):
|
|
|
21
21
|
density: float = 2400,
|
|
22
22
|
gamma_c: t.Optional[float] = None,
|
|
23
23
|
existing: t.Optional[bool] = False,
|
|
24
|
+
initial_strain: t.Optional[float] = None,
|
|
25
|
+
initial_stress: t.Optional[float] = None,
|
|
26
|
+
strain_compatibility: t.Optional[bool] = None,
|
|
24
27
|
) -> None:
|
|
25
28
|
"""Initializes an abstract concrete material."""
|
|
26
29
|
name = name if name is not None else 'Concrete'
|
|
27
|
-
super().__init__(
|
|
30
|
+
super().__init__(
|
|
31
|
+
density=density,
|
|
32
|
+
initial_strain=initial_strain,
|
|
33
|
+
initial_stress=initial_stress,
|
|
34
|
+
strain_compatibility=strain_compatibility,
|
|
35
|
+
name=name,
|
|
36
|
+
)
|
|
28
37
|
|
|
29
38
|
self._fck = abs(fck)
|
|
30
39
|
if existing:
|
|
@@ -46,6 +46,9 @@ class ConcreteEC2_2004(Concrete): # noqa: N801
|
|
|
46
46
|
ConstitutiveLaw,
|
|
47
47
|
]
|
|
48
48
|
] = 'parabolarectangle',
|
|
49
|
+
initial_strain: t.Optional[float] = None,
|
|
50
|
+
initial_stress: t.Optional[float] = None,
|
|
51
|
+
strain_compatibility: t.Optional[bool] = None,
|
|
49
52
|
fcm: t.Optional[float] = None,
|
|
50
53
|
fctm: t.Optional[float] = None,
|
|
51
54
|
fctk_5: t.Optional[float] = None,
|
|
@@ -80,6 +83,13 @@ class ConcreteEC2_2004(Concrete): # noqa: N801
|
|
|
80
83
|
law type for concrete. (valid options for string: 'elastic',
|
|
81
84
|
'parabolarectangle', 'bilinearcompression', 'sargin',
|
|
82
85
|
'popovics').
|
|
86
|
+
initial_strain (Optional[float]): Initial strain of the material.
|
|
87
|
+
initial_stress (Optional[float]): Initial stress of the material.
|
|
88
|
+
strain_compatibility (Optional[bool]): Only relevant if
|
|
89
|
+
initial_strain or initial_stress are different from zero. If
|
|
90
|
+
True, the material deforms with the geometry. If False, the
|
|
91
|
+
stress in the material upon loading is kept constant
|
|
92
|
+
corresponding to the initial strain.
|
|
83
93
|
fcm (float, optional): The mean compressive strength.
|
|
84
94
|
fctm (float, optional): The mean tensile strength.
|
|
85
95
|
fctk_5 (float, optional): The 5% fractile for the tensile strength.
|
|
@@ -130,6 +140,9 @@ class ConcreteEC2_2004(Concrete): # noqa: N801
|
|
|
130
140
|
density=density,
|
|
131
141
|
existing=False,
|
|
132
142
|
gamma_c=gamma_c,
|
|
143
|
+
initial_strain=initial_strain,
|
|
144
|
+
initial_stress=initial_stress,
|
|
145
|
+
strain_compatibility=strain_compatibility,
|
|
133
146
|
)
|
|
134
147
|
self._alpha_cc = alpha_cc
|
|
135
148
|
self._fcm = abs(fcm) if fcm is not None else None
|
|
@@ -165,6 +178,7 @@ class ConcreteEC2_2004(Concrete): # noqa: N801
|
|
|
165
178
|
raise ValueError(
|
|
166
179
|
'The provided constitutive law is not valid for concrete.'
|
|
167
180
|
)
|
|
181
|
+
self._apply_initial_strain()
|
|
168
182
|
|
|
169
183
|
def __post_init__(self):
|
|
170
184
|
"""Validator for the attributes that are set in the constructor."""
|
|
@@ -48,6 +48,9 @@ class ConcreteEC2_2023(Concrete): # noqa: N801
|
|
|
48
48
|
ConstitutiveLaw,
|
|
49
49
|
]
|
|
50
50
|
] = 'parabolarectangle',
|
|
51
|
+
initial_strain: t.Optional[float] = None,
|
|
52
|
+
initial_stress: t.Optional[float] = None,
|
|
53
|
+
strain_compatibility: t.Optional[bool] = None,
|
|
51
54
|
fcm: t.Optional[float] = None,
|
|
52
55
|
fctm: t.Optional[float] = None,
|
|
53
56
|
fctk_5: t.Optional[float] = None,
|
|
@@ -80,6 +83,13 @@ class ConcreteEC2_2023(Concrete): # noqa: N801
|
|
|
80
83
|
law type for concrete. (valid options for string: 'elastic',
|
|
81
84
|
'parabolarectangle', 'bilinearcompression', 'sargin',
|
|
82
85
|
'popovics').
|
|
86
|
+
initial_strain (Optional[float]): Initial strain of the material.
|
|
87
|
+
initial_stress (Optional[float]): Initial stress of the material.
|
|
88
|
+
strain_compatibility (Optional[bool]): Only relevant if
|
|
89
|
+
initial_strain or initial_stress are different from zero. If
|
|
90
|
+
True, the material deforms with the geometry. If False, the
|
|
91
|
+
stress in the material upon loading is kept constant
|
|
92
|
+
corresponding to the initial strain.
|
|
83
93
|
fcm (float, optional): The mean compressive strength.
|
|
84
94
|
fctm (float, optional): The mean tensile strength.
|
|
85
95
|
fctk_5 (float, optional): The 5% fractile for the tensile strength.
|
|
@@ -124,6 +134,9 @@ class ConcreteEC2_2023(Concrete): # noqa: N801
|
|
|
124
134
|
density=density,
|
|
125
135
|
existing=False,
|
|
126
136
|
gamma_c=gamma_c,
|
|
137
|
+
initial_strain=initial_strain,
|
|
138
|
+
initial_stress=initial_stress,
|
|
139
|
+
strain_compatibility=strain_compatibility,
|
|
127
140
|
)
|
|
128
141
|
self._kE = kE
|
|
129
142
|
self._strength_dev_class = strength_dev_class.strip().lower()
|
|
@@ -158,6 +171,7 @@ class ConcreteEC2_2023(Concrete): # noqa: N801
|
|
|
158
171
|
raise ValueError(
|
|
159
172
|
'The provided constitutive law is not valid for concrete.'
|
|
160
173
|
)
|
|
174
|
+
self._apply_initial_strain()
|
|
161
175
|
|
|
162
176
|
def __post_init__(self):
|
|
163
177
|
"""Validator for the attributes that are set in the constructor."""
|
|
@@ -48,6 +48,9 @@ class ConcreteMC2010(Concrete):
|
|
|
48
48
|
ConstitutiveLaw,
|
|
49
49
|
]
|
|
50
50
|
] = 'parabolarectangle',
|
|
51
|
+
initial_strain: t.Optional[float] = None,
|
|
52
|
+
initial_stress: t.Optional[float] = None,
|
|
53
|
+
strain_compatibility: t.Optional[bool] = None,
|
|
51
54
|
fcm: t.Optional[float] = None,
|
|
52
55
|
fctm: t.Optional[float] = None,
|
|
53
56
|
fctkmin: t.Optional[float] = None,
|
|
@@ -77,6 +80,18 @@ class ConcreteMC2010(Concrete):
|
|
|
77
80
|
alpha_cc (float, optional): A factor for considering long-term
|
|
78
81
|
effects on the strength, and effects that arise from the way
|
|
79
82
|
the load is applied.
|
|
83
|
+
consitutive_law (ConstitutiveLaw | str): A valid ConstitutiveLaw
|
|
84
|
+
object for concrete or a string defining a valid constitutive
|
|
85
|
+
law type for concrete. (valid options for string: 'elastic',
|
|
86
|
+
'parabolarectangle', 'bilinearcompression', 'sargin',
|
|
87
|
+
'popovics').
|
|
88
|
+
initial_strain (Optional[float]): Initial strain of the material.
|
|
89
|
+
initial_stress (Optional[float]): Initial stress of the material.
|
|
90
|
+
strain_compatibility (Optional[bool]): Only relevant if
|
|
91
|
+
initial_strain or initial_stress are different from zero. If
|
|
92
|
+
True, the material deforms with the geometry. If False, the
|
|
93
|
+
stress in the material upon loading is kept constant
|
|
94
|
+
corresponding to the initial strain.
|
|
80
95
|
fcm (float, optional): The mean compressive strength.
|
|
81
96
|
fctm (float, optional): The mean tensile strength.
|
|
82
97
|
fctkmin (float, optional): The minimum tensile strength.
|
|
@@ -126,6 +141,9 @@ class ConcreteMC2010(Concrete):
|
|
|
126
141
|
name=name,
|
|
127
142
|
density=density,
|
|
128
143
|
gamma_c=gamma_c,
|
|
144
|
+
initial_strain=initial_strain,
|
|
145
|
+
initial_stress=initial_stress,
|
|
146
|
+
strain_compatibility=strain_compatibility,
|
|
129
147
|
)
|
|
130
148
|
self._alpha_cc = alpha_cc
|
|
131
149
|
self._fcm = abs(fcm) if fcm is not None else None
|
|
@@ -162,6 +180,7 @@ class ConcreteMC2010(Concrete):
|
|
|
162
180
|
raise ValueError(
|
|
163
181
|
'The provided constitutive law is not valid for concrete.'
|
|
164
182
|
)
|
|
183
|
+
self._apply_initial_strain()
|
|
165
184
|
|
|
166
185
|
def __post_init__(self):
|
|
167
186
|
"""Validator for the attributes that are set in the constructor."""
|
|
@@ -6,6 +6,7 @@ from ...core.base import ConstitutiveLaw, Material
|
|
|
6
6
|
from ._bilinearcompression import BilinearCompression
|
|
7
7
|
from ._elastic import Elastic
|
|
8
8
|
from ._elasticplastic import ElasticPlastic
|
|
9
|
+
from ._initial_strain import InitialStrain
|
|
9
10
|
from ._parabolarectangle import ParabolaRectangle
|
|
10
11
|
from ._popovics import Popovics
|
|
11
12
|
from ._sargin import Sargin
|
|
@@ -19,6 +20,7 @@ __all__ = [
|
|
|
19
20
|
'Popovics',
|
|
20
21
|
'Sargin',
|
|
21
22
|
'UserDefined',
|
|
23
|
+
'InitialStrain',
|
|
22
24
|
'get_constitutive_laws_list',
|
|
23
25
|
'create_constitutive_law',
|
|
24
26
|
]
|
|
@@ -31,6 +33,7 @@ CONSTITUTIVE_LAWS: t.Dict[str, ConstitutiveLaw] = {
|
|
|
31
33
|
'parabolarectangle': ParabolaRectangle,
|
|
32
34
|
'popovics': Popovics,
|
|
33
35
|
'sargin': Sargin,
|
|
36
|
+
'initialstrain': InitialStrain,
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
|
|
@@ -34,8 +34,8 @@ class ElasticPlastic(ConstitutiveLaw):
|
|
|
34
34
|
|
|
35
35
|
Keyword Arguments:
|
|
36
36
|
Eh (float): The hardening modulus.
|
|
37
|
-
eps_su (float): The ultimate strain.
|
|
38
|
-
name (str): A descriptive name for the constitutive law.
|
|
37
|
+
eps_su (float, optional): The ultimate strain.
|
|
38
|
+
name (str, optional): A descriptive name for the constitutive law.
|
|
39
39
|
"""
|
|
40
40
|
name = name if name is not None else 'ElasticPlasticLaw'
|
|
41
41
|
super().__init__(name=name)
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"""Initial strain constitutive law."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations # To have clean hints of ArrayLike in docs
|
|
4
|
+
|
|
5
|
+
import typing as t
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
from numpy.typing import ArrayLike
|
|
9
|
+
|
|
10
|
+
from ...core.base import ConstitutiveLaw
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class InitialStrain(ConstitutiveLaw):
|
|
14
|
+
"""Class for initial strain Constitutive Law."""
|
|
15
|
+
|
|
16
|
+
_strain_compatibility: bool = True
|
|
17
|
+
|
|
18
|
+
__materials__: t.Tuple[str] = (
|
|
19
|
+
'steel',
|
|
20
|
+
'rebars',
|
|
21
|
+
'concrete',
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
_wrapped_law: ConstitutiveLaw = None
|
|
25
|
+
|
|
26
|
+
def __init__(
|
|
27
|
+
self,
|
|
28
|
+
constitutive_law: ConstitutiveLaw,
|
|
29
|
+
initial_strain: float,
|
|
30
|
+
strain_compatibility: bool = True,
|
|
31
|
+
name: t.Optional[str] = None,
|
|
32
|
+
) -> None:
|
|
33
|
+
"""Initialize an Initial Strain Constitutive Law.
|
|
34
|
+
|
|
35
|
+
This constitutive law is a wrapper for another constitutive law
|
|
36
|
+
that assigns an initial strain.
|
|
37
|
+
|
|
38
|
+
Arguments:
|
|
39
|
+
constitutive_law (ConstitutiveLaw): Wrapped constitutive law.
|
|
40
|
+
initial_strain (float): The initial strain to be applied.
|
|
41
|
+
strain_compatibility (bool): If True, the strain compatibility is
|
|
42
|
+
enforced, otherwise the strain compatibility is released. This
|
|
43
|
+
is helpful for instance for modelling unbonded tendons.
|
|
44
|
+
Default value True.
|
|
45
|
+
"""
|
|
46
|
+
name = name if name is not None else 'InitialStrainLaw'
|
|
47
|
+
super().__init__(name=name)
|
|
48
|
+
if not isinstance(constitutive_law, ConstitutiveLaw):
|
|
49
|
+
raise TypeError(
|
|
50
|
+
f'Expected a ConstitutiveLaw instance, '
|
|
51
|
+
f'got {type(constitutive_law)}'
|
|
52
|
+
)
|
|
53
|
+
self._wrapped_law = constitutive_law
|
|
54
|
+
self._initial_strain = initial_strain
|
|
55
|
+
self._initial_stress = self._wrapped_law.get_stress(initial_strain)
|
|
56
|
+
self._strain_compatibility = strain_compatibility
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def strain_compatibility(self) -> bool:
|
|
60
|
+
"""Return the strain compatibility status."""
|
|
61
|
+
return self._strain_compatibility
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def wrapped_law(self) -> ConstitutiveLaw:
|
|
65
|
+
"""Return the wrapped constitutive law."""
|
|
66
|
+
return self._wrapped_law
|
|
67
|
+
|
|
68
|
+
def get_stress(
|
|
69
|
+
self, eps: t.Union[float, ArrayLike]
|
|
70
|
+
) -> t.Union[float, ArrayLike]:
|
|
71
|
+
"""Return the stress given strain."""
|
|
72
|
+
stress = self._wrapped_law.get_stress(eps + self._initial_strain)
|
|
73
|
+
if not self._strain_compatibility:
|
|
74
|
+
# If strain compatibility is enforced, return initial stress
|
|
75
|
+
return np.ones_like(stress) * self._initial_stress
|
|
76
|
+
return stress
|
|
77
|
+
|
|
78
|
+
def get_tangent(
|
|
79
|
+
self, eps: t.Union[float, ArrayLike]
|
|
80
|
+
) -> t.Union[float, ArrayLike]:
|
|
81
|
+
"""Return the tangent for given strain."""
|
|
82
|
+
if not self._strain_compatibility:
|
|
83
|
+
return self._wrapped_law.get_tangent(0) * 1e-6
|
|
84
|
+
return self._wrapped_law.get_tangent(eps + self._initial_strain)
|
|
85
|
+
|
|
86
|
+
def __marin__(
|
|
87
|
+
self, strain: t.Tuple[float, float]
|
|
88
|
+
) -> t.Tuple[t.List[t.Tuple], t.List[t.Tuple]]:
|
|
89
|
+
"""Returns coefficients and strain limits for Marin integration in a
|
|
90
|
+
simply formatted way.
|
|
91
|
+
|
|
92
|
+
Arguments:
|
|
93
|
+
strain (float, float): Tuple defining the strain profile: eps =
|
|
94
|
+
strain[0] + strain[1]*y.
|
|
95
|
+
|
|
96
|
+
Example:
|
|
97
|
+
[(0, -0.002), (-0.002, -0.003)]
|
|
98
|
+
[(a0, a1, a2), (a0)]
|
|
99
|
+
"""
|
|
100
|
+
return self._wrapped_law.__marin__(
|
|
101
|
+
strain=[strain[0] + self._initial_strain, strain[1]]
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
def __marin_tangent__(
|
|
105
|
+
self, strain: t.Tuple[float, float]
|
|
106
|
+
) -> t.Tuple[t.List[t.Tuple], t.List[t.Tuple]]:
|
|
107
|
+
"""Returns coefficients and strain limits for Marin integration of
|
|
108
|
+
tangent in a simply formatted way.
|
|
109
|
+
|
|
110
|
+
Arguments:
|
|
111
|
+
strain (float, float): Tuple defining the strain profile: eps =
|
|
112
|
+
strain[0] + strain[1]*y.
|
|
113
|
+
|
|
114
|
+
Example:
|
|
115
|
+
[(0, -0.002), (-0.002, -0.003)]
|
|
116
|
+
[(a0, a1, a2), (a0)]
|
|
117
|
+
"""
|
|
118
|
+
return self._wrapped_law.__marin_tangent__(
|
|
119
|
+
strain=[strain[0] + self._initial_strain, strain[1]]
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
def get_ultimate_strain(
|
|
123
|
+
self, yielding: bool = False
|
|
124
|
+
) -> t.Tuple[float, float]:
|
|
125
|
+
"""Return the ultimate strain (negative and positive)."""
|
|
126
|
+
ult_strain = self._wrapped_law.get_ultimate_strain(yielding=yielding)
|
|
127
|
+
return (
|
|
128
|
+
ult_strain[0] - self._initial_strain,
|
|
129
|
+
ult_strain[1] - self._initial_strain,
|
|
130
|
+
)
|
|
@@ -33,6 +33,7 @@ def create_reinforcement(
|
|
|
33
33
|
name: t.Optional[str] = None,
|
|
34
34
|
density: float = 7850,
|
|
35
35
|
design_code: t.Optional[str] = None,
|
|
36
|
+
**kwargs,
|
|
36
37
|
) -> t.Optional[Reinforcement]:
|
|
37
38
|
"""A factory function to create the correct type of reinforcement based on
|
|
38
39
|
the desired design code.
|
|
@@ -50,6 +51,10 @@ def create_reinforcement(
|
|
|
50
51
|
desired standard. If None (default) the globally used design
|
|
51
52
|
standard will be adopted. Otherwise the design standard specified
|
|
52
53
|
will be used for the instance of the material.
|
|
54
|
+
**kwargs: Other valid keyword arguments that are collected and passed
|
|
55
|
+
to the specific reinforcement material. Please inspect the
|
|
56
|
+
documentation of the other reinforcement materials to see valid
|
|
57
|
+
arguments.
|
|
53
58
|
|
|
54
59
|
Raises:
|
|
55
60
|
ValueError: If the design code is not valid or does not cover
|
|
@@ -80,5 +85,6 @@ def create_reinforcement(
|
|
|
80
85
|
ftk=ftk,
|
|
81
86
|
epsuk=epsuk,
|
|
82
87
|
gamma_s=gamma_s,
|
|
88
|
+
**kwargs,
|
|
83
89
|
)
|
|
84
90
|
return None
|
|
@@ -24,10 +24,19 @@ class Reinforcement(Material):
|
|
|
24
24
|
epsuk: float,
|
|
25
25
|
gamma_s: t.Optional[float] = None,
|
|
26
26
|
name: t.Optional[str] = None,
|
|
27
|
+
initial_strain: t.Optional[float] = None,
|
|
28
|
+
initial_stress: t.Optional[float] = None,
|
|
29
|
+
strain_compatibility: t.Optional[bool] = None,
|
|
27
30
|
) -> None:
|
|
28
31
|
"""Initializes an abstract reinforcement material."""
|
|
29
32
|
name = name if name is not None else 'Reinforcement'
|
|
30
|
-
super().__init__(
|
|
33
|
+
super().__init__(
|
|
34
|
+
density=density,
|
|
35
|
+
initial_strain=initial_strain,
|
|
36
|
+
initial_stress=initial_stress,
|
|
37
|
+
strain_compatibility=strain_compatibility,
|
|
38
|
+
name=name,
|
|
39
|
+
)
|
|
31
40
|
|
|
32
41
|
self._fyk = abs(fyk)
|
|
33
42
|
self._Es = abs(Es)
|
|
@@ -31,6 +31,9 @@ class ReinforcementEC2_2004(Reinforcement): # noqa: N801
|
|
|
31
31
|
ConstitutiveLaw,
|
|
32
32
|
]
|
|
33
33
|
] = 'elasticplastic',
|
|
34
|
+
initial_strain: t.Optional[float] = None,
|
|
35
|
+
initial_stress: t.Optional[float] = None,
|
|
36
|
+
strain_compatibility: t.Optional[bool] = None,
|
|
34
37
|
):
|
|
35
38
|
"""Initializes a new instance of Reinforcement for EC2 2004.
|
|
36
39
|
|
|
@@ -53,6 +56,13 @@ class ReinforcementEC2_2004(Reinforcement): # noqa: N801
|
|
|
53
56
|
constitutive law type for reinforcement. (valid options for
|
|
54
57
|
string: 'elastic', 'elasticplastic', or
|
|
55
58
|
'elasticperfectlyplastic').
|
|
59
|
+
initial_strain (Optional[float]): Initial strain of the material.
|
|
60
|
+
initial_stress (Optional[float]): Initial stress of the material.
|
|
61
|
+
strain_compatibility (Optional[bool]): Only relevant if
|
|
62
|
+
initial_strain or initial_stress are different from zero. If
|
|
63
|
+
True, the material deforms with the geometry. If False, the
|
|
64
|
+
stress in the material upon loading is kept constant
|
|
65
|
+
corresponding to the initial strain.
|
|
56
66
|
|
|
57
67
|
Raises:
|
|
58
68
|
ValueError: If the constitutive law name is not available for the
|
|
@@ -71,6 +81,9 @@ class ReinforcementEC2_2004(Reinforcement): # noqa: N801
|
|
|
71
81
|
ftk=ftk,
|
|
72
82
|
epsuk=epsuk,
|
|
73
83
|
gamma_s=gamma_s,
|
|
84
|
+
initial_strain=initial_strain,
|
|
85
|
+
initial_stress=initial_stress,
|
|
86
|
+
strain_compatibility=strain_compatibility,
|
|
74
87
|
)
|
|
75
88
|
self._gamma_eps = gamma_eps
|
|
76
89
|
self._constitutive_law = (
|
|
@@ -84,6 +97,7 @@ class ReinforcementEC2_2004(Reinforcement): # noqa: N801
|
|
|
84
97
|
raise ValueError(
|
|
85
98
|
'The provided constitutive law is not valid for reinforcement.'
|
|
86
99
|
)
|
|
100
|
+
self._apply_initial_strain()
|
|
87
101
|
|
|
88
102
|
def fyd(self) -> float:
|
|
89
103
|
"""The design yield strength."""
|
|
@@ -129,7 +143,7 @@ class ReinforcementEC2_2004(Reinforcement): # noqa: N801
|
|
|
129
143
|
"""Returns kwargs for ElasticPlastic constitutive law with strain
|
|
130
144
|
hardening.
|
|
131
145
|
"""
|
|
132
|
-
Eh = (self.ftd() - self.fyd()) / (self.
|
|
146
|
+
Eh = (self.ftd() - self.fyd()) / (self.epsud() - self.epsyd)
|
|
133
147
|
return {
|
|
134
148
|
'E': self.Es,
|
|
135
149
|
'fy': self.fyd(),
|
|
@@ -30,6 +30,9 @@ class ReinforcementEC2_2023(Reinforcement): # noqa: N801
|
|
|
30
30
|
ConstitutiveLaw,
|
|
31
31
|
]
|
|
32
32
|
] = 'elasticplastic',
|
|
33
|
+
initial_strain: t.Optional[float] = None,
|
|
34
|
+
initial_stress: t.Optional[float] = None,
|
|
35
|
+
strain_compatibility: t.Optional[bool] = None,
|
|
33
36
|
):
|
|
34
37
|
"""Initializes a new instance of Reinforcement for EC2 2023.
|
|
35
38
|
|
|
@@ -50,6 +53,13 @@ class ReinforcementEC2_2023(Reinforcement): # noqa: N801
|
|
|
50
53
|
constitutive law type for reinforcement. (valid options for
|
|
51
54
|
string: 'elastic', 'elasticplastic', or
|
|
52
55
|
'elasticperfectlyplastic').
|
|
56
|
+
initial_strain (Optional[float]): Initial strain of the material.
|
|
57
|
+
initial_stress (Optional[float]): Initial stress of the material.
|
|
58
|
+
strain_compatibility (Optional[bool]): Only relevant if
|
|
59
|
+
initial_strain or initial_stress are different from zero. If
|
|
60
|
+
True, the material deforms with the geometry. If False, the
|
|
61
|
+
stress in the material upon loading is kept constant
|
|
62
|
+
corresponding to the initial strain.
|
|
53
63
|
|
|
54
64
|
Raises:
|
|
55
65
|
ValueError: If the constitutive law name is not available for the
|
|
@@ -67,6 +77,9 @@ class ReinforcementEC2_2023(Reinforcement): # noqa: N801
|
|
|
67
77
|
ftk=ftk,
|
|
68
78
|
epsuk=epsuk,
|
|
69
79
|
gamma_s=gamma_s,
|
|
80
|
+
initial_strain=initial_strain,
|
|
81
|
+
initial_stress=initial_stress,
|
|
82
|
+
strain_compatibility=strain_compatibility,
|
|
70
83
|
)
|
|
71
84
|
self._constitutive_law = (
|
|
72
85
|
constitutive_law
|
|
@@ -79,6 +92,7 @@ class ReinforcementEC2_2023(Reinforcement): # noqa: N801
|
|
|
79
92
|
raise ValueError(
|
|
80
93
|
'The provided constitutive law is not valid for reinforcement.'
|
|
81
94
|
)
|
|
95
|
+
self._apply_initial_strain()
|
|
82
96
|
|
|
83
97
|
def fyd(self) -> float:
|
|
84
98
|
"""The design yield strength."""
|
|
@@ -117,7 +131,7 @@ class ReinforcementEC2_2023(Reinforcement): # noqa: N801
|
|
|
117
131
|
"""Returns kwargs for ElasticPlastic constitutive law with strain
|
|
118
132
|
hardening.
|
|
119
133
|
"""
|
|
120
|
-
Eh = (self.ftd() - self.fyd()) / (self.
|
|
134
|
+
Eh = (self.ftd() - self.fyd()) / (self.epsud() - self.epsyd)
|
|
121
135
|
return {
|
|
122
136
|
'E': self.Es,
|
|
123
137
|
'fy': self.fyd(),
|
|
@@ -31,6 +31,9 @@ class ReinforcementMC2010(Reinforcement):
|
|
|
31
31
|
ConstitutiveLaw,
|
|
32
32
|
]
|
|
33
33
|
] = 'elasticplastic',
|
|
34
|
+
initial_strain: t.Optional[float] = None,
|
|
35
|
+
initial_stress: t.Optional[float] = None,
|
|
36
|
+
strain_compatibility: t.Optional[bool] = None,
|
|
34
37
|
):
|
|
35
38
|
"""Initializes a new instance of Reinforcement for MC2010.
|
|
36
39
|
|
|
@@ -53,6 +56,13 @@ class ReinforcementMC2010(Reinforcement):
|
|
|
53
56
|
constitutive law type for reinforcement. (valid options for
|
|
54
57
|
string: 'elastic', 'elasticplastic', or
|
|
55
58
|
'elasticperfectlyplastic').
|
|
59
|
+
initial_strain (Optional[float]): Initial strain of the material.
|
|
60
|
+
initial_stress (Optional[float]): Initial stress of the material.
|
|
61
|
+
strain_compatibility (Optional[bool]): Only relevant if
|
|
62
|
+
initial_strain or initial_stress are different from zero. If
|
|
63
|
+
True, the material deforms with the geometry. If False, the
|
|
64
|
+
stress in the material upon loading is kept constant
|
|
65
|
+
corresponding to the initial strain.
|
|
56
66
|
|
|
57
67
|
Raises:
|
|
58
68
|
ValueError: If the constitutive law name is not available for the
|
|
@@ -71,6 +81,9 @@ class ReinforcementMC2010(Reinforcement):
|
|
|
71
81
|
ftk=ftk,
|
|
72
82
|
epsuk=epsuk,
|
|
73
83
|
gamma_s=gamma_s,
|
|
84
|
+
initial_strain=initial_strain,
|
|
85
|
+
initial_stress=initial_stress,
|
|
86
|
+
strain_compatibility=strain_compatibility,
|
|
74
87
|
)
|
|
75
88
|
self._gamma_eps = gamma_eps
|
|
76
89
|
self._constitutive_law = (
|
|
@@ -84,6 +97,7 @@ class ReinforcementMC2010(Reinforcement):
|
|
|
84
97
|
raise ValueError(
|
|
85
98
|
'The provided constitutive law is not valid for reinforcement.'
|
|
86
99
|
)
|
|
100
|
+
self._apply_initial_strain()
|
|
87
101
|
|
|
88
102
|
def fyd(self) -> float:
|
|
89
103
|
"""The design yield strength."""
|
|
@@ -125,7 +139,7 @@ class ReinforcementMC2010(Reinforcement):
|
|
|
125
139
|
"""Returns kwargs for ElasticPlastic constitutive law with strain
|
|
126
140
|
hardening.
|
|
127
141
|
"""
|
|
128
|
-
Eh = (self.ftd() - self.fyd()) / (self.
|
|
142
|
+
Eh = (self.ftd() - self.fyd()) / (self.epsud() - self.epsyd)
|
|
129
143
|
return {
|
|
130
144
|
'E': self.Es,
|
|
131
145
|
'fy': self.fyd(),
|