structuralcodes 0.5.0__py3-none-any.whl → 0.6.1__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/shear.py +3 -2
- structuralcodes/codes/mc2010/_concrete_creep_and_shrinkage.py +2 -2
- structuralcodes/core/base.py +138 -12
- structuralcodes/geometry/__init__.py +2 -8
- structuralcodes/geometry/_geometry.py +103 -19
- structuralcodes/geometry/_reinforcement.py +1 -3
- structuralcodes/geometry/profiles/__init__.py +33 -0
- structuralcodes/geometry/profiles/_base_profile.py +305 -0
- structuralcodes/geometry/profiles/_common_functions.py +307 -0
- structuralcodes/geometry/profiles/_hd.py +374 -0
- structuralcodes/geometry/profiles/_he.py +192 -0
- structuralcodes/geometry/profiles/_hp.py +319 -0
- structuralcodes/geometry/profiles/_ipe.py +130 -0
- structuralcodes/geometry/profiles/_ipn.py +329 -0
- structuralcodes/geometry/profiles/_l.py +528 -0
- structuralcodes/geometry/profiles/_li.py +217 -0
- structuralcodes/geometry/profiles/_u.py +173 -0
- structuralcodes/geometry/profiles/_ub.py +1356 -0
- structuralcodes/geometry/profiles/_ubp.py +227 -0
- structuralcodes/geometry/profiles/_uc.py +276 -0
- structuralcodes/geometry/profiles/_upe.py +133 -0
- structuralcodes/geometry/profiles/_upn.py +315 -0
- structuralcodes/geometry/profiles/_w.py +2157 -0
- structuralcodes/materials/basic/_elastic.py +18 -1
- structuralcodes/materials/basic/_elasticplastic.py +18 -1
- structuralcodes/materials/basic/_generic.py +18 -1
- structuralcodes/materials/concrete/__init__.py +3 -0
- structuralcodes/materials/concrete/_concrete.py +10 -1
- structuralcodes/materials/concrete/_concreteEC2_2004.py +15 -1
- structuralcodes/materials/concrete/_concreteEC2_2023.py +15 -1
- structuralcodes/materials/concrete/_concreteMC2010.py +20 -1
- 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 +14 -0
- structuralcodes/materials/reinforcement/_reinforcementEC2_2023.py +14 -0
- structuralcodes/materials/reinforcement/_reinforcementMC2010.py +14 -0
- structuralcodes/sections/section_integrators/__init__.py +3 -1
- structuralcodes/sections/section_integrators/_marin_integrator.py +1 -1
- {structuralcodes-0.5.0.dist-info → structuralcodes-0.6.1.dist-info}/METADATA +2 -2
- {structuralcodes-0.5.0.dist-info → structuralcodes-0.6.1.dist-info}/RECORD +47 -30
- structuralcodes/geometry/_steel_sections.py +0 -2155
- /structuralcodes/{sections/section_integrators → core}/_marin_integration.py +0 -0
- {structuralcodes-0.5.0.dist-info → structuralcodes-0.6.1.dist-info}/WHEEL +0 -0
- {structuralcodes-0.5.0.dist-info → structuralcodes-0.6.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -15,6 +15,9 @@ class ElasticMaterial(Material):
|
|
|
15
15
|
self,
|
|
16
16
|
E: float,
|
|
17
17
|
density: float,
|
|
18
|
+
initial_strain: t.Optional[float] = None,
|
|
19
|
+
initial_stress: t.Optional[float] = None,
|
|
20
|
+
strain_compatibility: t.Optional[float] = None,
|
|
18
21
|
name: t.Optional[str] = None,
|
|
19
22
|
):
|
|
20
23
|
"""Initialize a material with an elastic plastic constitutive law.
|
|
@@ -22,11 +25,25 @@ class ElasticMaterial(Material):
|
|
|
22
25
|
Arguments:
|
|
23
26
|
E (float): The Young's modulus.
|
|
24
27
|
density (float): The density.
|
|
28
|
+
initial_strain (Optional[float]): Initial strain of the material.
|
|
29
|
+
initial_stress (Optional[float]): Initial stress of the material.
|
|
30
|
+
strain_compatibility (Optional[bool]): Only relevant if
|
|
31
|
+
initial_strain or initial_stress are different from zero. If
|
|
32
|
+
True, the material deforms with the geometry. If False, the
|
|
33
|
+
stress in the material upon loading is kept constant
|
|
34
|
+
corresponding to the initial strain.
|
|
25
35
|
name (str, optional): The name of the material, default value None.
|
|
26
36
|
"""
|
|
27
|
-
super().__init__(
|
|
37
|
+
super().__init__(
|
|
38
|
+
density=density,
|
|
39
|
+
initial_strain=initial_strain,
|
|
40
|
+
initial_stress=initial_stress,
|
|
41
|
+
strain_compatibility=strain_compatibility,
|
|
42
|
+
name=name if name else 'ElasticMaterial',
|
|
43
|
+
)
|
|
28
44
|
self._E = E
|
|
29
45
|
self._constitutive_law = create_constitutive_law('elastic', self)
|
|
46
|
+
self._apply_initial_strain()
|
|
30
47
|
|
|
31
48
|
@property
|
|
32
49
|
def E(self) -> float:
|
|
@@ -21,6 +21,9 @@ class ElasticPlasticMaterial(Material):
|
|
|
21
21
|
density: float,
|
|
22
22
|
Eh: float = 0,
|
|
23
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,
|
|
24
27
|
name: t.Optional[str] = None,
|
|
25
28
|
):
|
|
26
29
|
"""Initialize a material with an elastic plastic constitutive law.
|
|
@@ -31,9 +34,22 @@ class ElasticPlasticMaterial(Material):
|
|
|
31
34
|
density (float): The density.
|
|
32
35
|
Eh (float, optional): The hardening modulus, default value 0.
|
|
33
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.
|
|
34
44
|
name (str, optional): The name of the material, default value None.
|
|
35
45
|
"""
|
|
36
|
-
super().__init__(
|
|
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
|
+
)
|
|
37
53
|
self._E = E
|
|
38
54
|
self._fy = fy
|
|
39
55
|
self._Eh = Eh
|
|
@@ -42,6 +58,7 @@ class ElasticPlasticMaterial(Material):
|
|
|
42
58
|
self._constitutive_law = create_constitutive_law(
|
|
43
59
|
'elasticplastic', self
|
|
44
60
|
)
|
|
61
|
+
self._apply_initial_strain()
|
|
45
62
|
|
|
46
63
|
@property
|
|
47
64
|
def E(self) -> float:
|
|
@@ -12,6 +12,9 @@ class GenericMaterial(Material):
|
|
|
12
12
|
self,
|
|
13
13
|
density: float,
|
|
14
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,
|
|
15
18
|
name: t.Optional[str] = None,
|
|
16
19
|
):
|
|
17
20
|
"""Initialize a material with a constitutive law.
|
|
@@ -20,7 +23,21 @@ class GenericMaterial(Material):
|
|
|
20
23
|
density (float): The density.
|
|
21
24
|
constitutive_law (ConstitutiveLaw): The constitutive law of the
|
|
22
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.
|
|
23
33
|
name (str, optional): The name of the material, default value None.
|
|
24
34
|
"""
|
|
25
|
-
super().__init__(
|
|
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
|
+
)
|
|
26
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."""
|
|
@@ -507,7 +521,7 @@ class ConcreteEC2_2004(Concrete): # noqa: N801
|
|
|
507
521
|
def __sargin__(self) -> dict:
|
|
508
522
|
"""Returns kwargs for creating a Sargin const law."""
|
|
509
523
|
return {
|
|
510
|
-
'fc': self.
|
|
524
|
+
'fc': self.fcm,
|
|
511
525
|
'eps_c1': self.eps_c1,
|
|
512
526
|
'eps_cu1': self.eps_cu1,
|
|
513
527
|
'k': self.k_sargin,
|
|
@@ -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."""
|
|
@@ -477,7 +491,7 @@ class ConcreteEC2_2023(Concrete): # noqa: N801
|
|
|
477
491
|
def __sargin__(self) -> dict:
|
|
478
492
|
"""Returns kwargs for creating a Sargin const law."""
|
|
479
493
|
return {
|
|
480
|
-
'fc': self.
|
|
494
|
+
'fc': self.fcm,
|
|
481
495
|
'eps_c1': self.eps_c1,
|
|
482
496
|
'eps_cu1': self.eps_cu1,
|
|
483
497
|
'k': self.k_sargin,
|
|
@@ -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."""
|
|
@@ -523,7 +542,7 @@ class ConcreteMC2010(Concrete):
|
|
|
523
542
|
def __sargin__(self) -> dict:
|
|
524
543
|
"""Returns kwargs for creating a Sargin const law."""
|
|
525
544
|
return {
|
|
526
|
-
'fc': self.
|
|
545
|
+
'fc': self.fcm,
|
|
527
546
|
'eps_c1': self.eps_c1,
|
|
528
547
|
'eps_cu1': self.eps_cu1,
|
|
529
548
|
'k': self.k_sargin,
|
|
@@ -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."""
|
|
@@ -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."""
|
|
@@ -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."""
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"""Classes for integrating the response of sections."""
|
|
2
2
|
|
|
3
|
+
from structuralcodes.core._marin_integration import marin_integration
|
|
4
|
+
|
|
3
5
|
from ._factory import integrator_factory
|
|
4
6
|
from ._fiber_integrator import FiberIntegrator
|
|
5
|
-
from ._marin_integrator import MarinIntegrator
|
|
7
|
+
from ._marin_integrator import MarinIntegrator
|
|
6
8
|
from ._section_integrator import SectionIntegrator
|
|
7
9
|
|
|
8
10
|
__all__ = [
|
|
@@ -10,13 +10,13 @@ from numpy.typing import ArrayLike, NDArray
|
|
|
10
10
|
from shapely import MultiLineString, MultiPolygon, Polygon
|
|
11
11
|
from shapely.geometry.polygon import orient
|
|
12
12
|
|
|
13
|
+
from structuralcodes.core._marin_integration import marin_integration
|
|
13
14
|
from structuralcodes.geometry import (
|
|
14
15
|
CompoundGeometry,
|
|
15
16
|
SurfaceGeometry,
|
|
16
17
|
create_line_point_angle,
|
|
17
18
|
)
|
|
18
19
|
|
|
19
|
-
from ._marin_integration import marin_integration
|
|
20
20
|
from ._section_integrator import SectionIntegrator
|
|
21
21
|
|
|
22
22
|
|