structuralcodes 0.5.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.

Files changed (40) hide show
  1. structuralcodes/__init__.py +1 -1
  2. structuralcodes/codes/mc2010/_concrete_creep_and_shrinkage.py +2 -2
  3. structuralcodes/core/base.py +115 -4
  4. structuralcodes/geometry/__init__.py +2 -8
  5. structuralcodes/geometry/_geometry.py +11 -22
  6. structuralcodes/geometry/_reinforcement.py +1 -3
  7. structuralcodes/geometry/profiles/__init__.py +19 -0
  8. structuralcodes/geometry/profiles/_base_profile.py +305 -0
  9. structuralcodes/geometry/profiles/_common_functions.py +194 -0
  10. structuralcodes/geometry/profiles/_he.py +192 -0
  11. structuralcodes/geometry/profiles/_ipe.py +130 -0
  12. structuralcodes/geometry/profiles/_ipn.py +329 -0
  13. structuralcodes/geometry/profiles/_ub.py +264 -0
  14. structuralcodes/geometry/profiles/_ubp.py +227 -0
  15. structuralcodes/geometry/profiles/_uc.py +276 -0
  16. structuralcodes/geometry/profiles/_upn.py +315 -0
  17. structuralcodes/materials/basic/_elastic.py +18 -1
  18. structuralcodes/materials/basic/_elasticplastic.py +18 -1
  19. structuralcodes/materials/basic/_generic.py +18 -1
  20. structuralcodes/materials/concrete/__init__.py +3 -0
  21. structuralcodes/materials/concrete/_concrete.py +10 -1
  22. structuralcodes/materials/concrete/_concreteEC2_2004.py +14 -0
  23. structuralcodes/materials/concrete/_concreteEC2_2023.py +14 -0
  24. structuralcodes/materials/concrete/_concreteMC2010.py +19 -0
  25. structuralcodes/materials/constitutive_laws/__init__.py +3 -0
  26. structuralcodes/materials/constitutive_laws/_elasticplastic.py +2 -2
  27. structuralcodes/materials/constitutive_laws/_initial_strain.py +130 -0
  28. structuralcodes/materials/reinforcement/__init__.py +6 -0
  29. structuralcodes/materials/reinforcement/_reinforcement.py +10 -1
  30. structuralcodes/materials/reinforcement/_reinforcementEC2_2004.py +14 -0
  31. structuralcodes/materials/reinforcement/_reinforcementEC2_2023.py +14 -0
  32. structuralcodes/materials/reinforcement/_reinforcementMC2010.py +14 -0
  33. structuralcodes/sections/section_integrators/__init__.py +3 -1
  34. structuralcodes/sections/section_integrators/_marin_integrator.py +1 -1
  35. {structuralcodes-0.5.0.dist-info → structuralcodes-0.6.0.dist-info}/METADATA +2 -2
  36. {structuralcodes-0.5.0.dist-info → structuralcodes-0.6.0.dist-info}/RECORD +39 -29
  37. structuralcodes/geometry/_steel_sections.py +0 -2155
  38. /structuralcodes/{sections/section_integrators → core}/_marin_integration.py +0 -0
  39. {structuralcodes-0.5.0.dist-info → structuralcodes-0.6.0.dist-info}/WHEEL +0 -0
  40. {structuralcodes-0.5.0.dist-info → structuralcodes-0.6.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,315 @@
1
+ """UPN profiles."""
2
+
3
+ from shapely import (
4
+ Polygon,
5
+ )
6
+
7
+ from ._base_profile import BaseProfile
8
+ from ._common_functions import (
9
+ _create_taper_U_section,
10
+ )
11
+
12
+
13
+ class UPN(BaseProfile):
14
+ """Simple class for representing an UPN profile.
15
+
16
+ European standard channels UPN 50 - 400.
17
+
18
+ Taper flange Channels.
19
+
20
+ 14% slope in flange.
21
+ """
22
+
23
+ parameters = {
24
+ 'UPN50': {
25
+ 'h': 50.0,
26
+ 'b': 38.0,
27
+ 'tw': 5.0,
28
+ 'tf': 7.0,
29
+ 'r1': 7.0,
30
+ 'r2': 4.0,
31
+ 'd': 21.0,
32
+ },
33
+ 'UPN65': {
34
+ 'h': 65.0,
35
+ 'b': 42.0,
36
+ 'tw': 5.5,
37
+ 'tf': 7.5,
38
+ 'r1': 8.0,
39
+ 'r2': 4.0,
40
+ 'd': 34.0,
41
+ },
42
+ 'UPN80': {
43
+ 'h': 80.0,
44
+ 'b': 45.0,
45
+ 'tw': 6.0,
46
+ 'tf': 8.0,
47
+ 'r1': 8.0,
48
+ 'r2': 4.0,
49
+ 'd': 47.0,
50
+ },
51
+ 'UPN100': {
52
+ 'h': 100.0,
53
+ 'b': 50.0,
54
+ 'tw': 6.0,
55
+ 'tf': 8.5,
56
+ 'r1': 9.0,
57
+ 'r2': 5.0,
58
+ 'd': 64.0,
59
+ },
60
+ 'UPN120': {
61
+ 'h': 120.0,
62
+ 'b': 55.0,
63
+ 'tw': 7.0,
64
+ 'tf': 9.0,
65
+ 'r1': 9.0,
66
+ 'r2': 5.0,
67
+ 'd': 82.0,
68
+ },
69
+ 'UPN140': {
70
+ 'h': 140.0,
71
+ 'b': 60.0,
72
+ 'tw': 7.0,
73
+ 'tf': 10.0,
74
+ 'r1': 10.0,
75
+ 'r2': 5.0,
76
+ 'd': 98.0,
77
+ },
78
+ 'UPN160': {
79
+ 'h': 160.0,
80
+ 'b': 65.0,
81
+ 'tw': 7.5,
82
+ 'tf': 10.5,
83
+ 'r1': 11.0,
84
+ 'r2': 6.0,
85
+ 'd': 115.0,
86
+ },
87
+ 'UPN180': {
88
+ 'h': 180.0,
89
+ 'b': 70.0,
90
+ 'tw': 8.0,
91
+ 'tf': 11.0,
92
+ 'r1': 11.0,
93
+ 'r2': 6.0,
94
+ 'd': 133.0,
95
+ },
96
+ 'UPN200': {
97
+ 'h': 200.0,
98
+ 'b': 75.0,
99
+ 'tw': 8.5,
100
+ 'tf': 11.5,
101
+ 'r1': 12.0,
102
+ 'r2': 6.0,
103
+ 'd': 151.0,
104
+ },
105
+ 'UPN220': {
106
+ 'h': 220.0,
107
+ 'b': 80.0,
108
+ 'tw': 9.0,
109
+ 'tf': 12.5,
110
+ 'r1': 13.0,
111
+ 'r2': 7.0,
112
+ 'd': 167.0,
113
+ },
114
+ 'UPN240': {
115
+ 'h': 240.0,
116
+ 'b': 85.0,
117
+ 'tw': 9.5,
118
+ 'tf': 13.0,
119
+ 'r1': 13.0,
120
+ 'r2': 7.0,
121
+ 'd': 184.0,
122
+ },
123
+ 'UPN260': {
124
+ 'h': 260.0,
125
+ 'b': 90.0,
126
+ 'tw': 10.0,
127
+ 'tf': 14.0,
128
+ 'r1': 14.0,
129
+ 'r2': 7.0,
130
+ 'd': 200.0,
131
+ },
132
+ 'UPN280': {
133
+ 'h': 280.0,
134
+ 'b': 95.0,
135
+ 'tw': 10.0,
136
+ 'tf': 15.0,
137
+ 'r1': 15.0,
138
+ 'r2': 8.0,
139
+ 'd': 216.0,
140
+ },
141
+ 'UPN300': {
142
+ 'h': 300.0,
143
+ 'b': 100.0,
144
+ 'tw': 10.0,
145
+ 'tf': 16.0,
146
+ 'r1': 16.0,
147
+ 'r2': 8.0,
148
+ 'd': 232.0,
149
+ },
150
+ 'UPN320': {
151
+ 'h': 320.0,
152
+ 'b': 100.0,
153
+ 'tw': 14.0,
154
+ 'tf': 17.5,
155
+ 'r1': 18.0,
156
+ 'r2': 9.0,
157
+ 'd': 246.0,
158
+ },
159
+ 'UPN350': {
160
+ 'h': 350.0,
161
+ 'b': 100.0,
162
+ 'tw': 14.0,
163
+ 'tf': 16.0,
164
+ 'r1': 16.0,
165
+ 'r2': 8.0,
166
+ 'd': 282.0,
167
+ },
168
+ 'UPN380': {
169
+ 'h': 380.0,
170
+ 'b': 102.0,
171
+ 'tw': 13.5,
172
+ 'tf': 16.0,
173
+ 'r1': 16.0,
174
+ 'r2': 8.0,
175
+ 'd': 313.0,
176
+ },
177
+ 'UPN400': {
178
+ 'h': 400.0,
179
+ 'b': 110.0,
180
+ 'tw': 14.0,
181
+ 'tf': 18.0,
182
+ 'r1': 18.0,
183
+ 'r2': 9.0,
184
+ 'd': 324.0,
185
+ },
186
+ }
187
+
188
+ @classmethod
189
+ def get_polygon(cls, name: str) -> Polygon:
190
+ """Returns a shapely polygon representing an UPN section."""
191
+ if isinstance(name, (float, int)):
192
+ name = f'UPN{int(name):0d}'
193
+ parameters = cls.parameters.get(name)
194
+ if parameters is None:
195
+ raise ValueError(
196
+ f"Profile '{name}' not found in UPN sections. "
197
+ "Select a valid profile (available ones: "
198
+ f"{cls.profiles()})"
199
+ )
200
+ if parameters['h'] <= 300:
201
+ parameters['slope'] = 0.08
202
+ parameters['u'] = parameters['b'] / 2.0
203
+ else:
204
+ parameters['slope'] = 0.05
205
+ parameters['u'] = (parameters['b'] - parameters['tw']) / 2.0
206
+ return _create_taper_U_section(
207
+ **{
208
+ key: parameters[key]
209
+ for key in parameters
210
+ if key in ['h', 'b', 'tw', 'tf', 'r1', 'r2', 'slope', 'u']
211
+ }
212
+ )
213
+
214
+ @classmethod
215
+ def profiles(cls) -> list:
216
+ """Returns a list containing all available profiles."""
217
+ return list(cls.parameters.keys())
218
+
219
+ def __init__(self, name: str) -> None:
220
+ """Creates a new UPN object."""
221
+ if isinstance(name, (float, int)):
222
+ name = f'UPN{int(name):0d}'
223
+ parameters = self.parameters.get(name)
224
+ if parameters is None:
225
+ raise ValueError(
226
+ f"Profile '{name}' not found in UPN sections. "
227
+ "Select a valid profile (available ones: "
228
+ f"{self.profiles()})"
229
+ )
230
+ super().__init__()
231
+ self._h = parameters.get('h')
232
+ self._b = parameters.get('b')
233
+ self._tw = parameters.get('tw')
234
+ self._tf = parameters.get('tf')
235
+ self._r1 = parameters.get('r1')
236
+ self._r2 = parameters.get('r2')
237
+ if self._h <= 300:
238
+ self._flange_slope = 0.08
239
+ self._u = self._b / 2.0
240
+ else:
241
+ self._flange_slope = 0.05
242
+ self._u = (self._b - self._tw) / 2.0
243
+ self._polygon = _create_taper_U_section(
244
+ h=self._h,
245
+ b=self._b,
246
+ tw=self._tw,
247
+ tf=self._tf,
248
+ r1=self._r1,
249
+ r2=self._r2,
250
+ slope=self._flange_slope,
251
+ u=self._u,
252
+ )
253
+
254
+ @property
255
+ def polygon(self) -> Polygon:
256
+ """Returns shapely Polygon of section.
257
+
258
+ Returns:
259
+ Polygon: The represention of the UPN section.
260
+ """
261
+ return self._polygon
262
+
263
+ @property
264
+ def h(self) -> float:
265
+ """Returns height of UPN section.
266
+
267
+ Returns:
268
+ float: Height h of UPN section.
269
+ """
270
+ return self._h
271
+
272
+ @property
273
+ def b(self) -> float:
274
+ """Returns width of UPN section.
275
+
276
+ Returns:
277
+ float: Width b of UPN section.
278
+ """
279
+ return self._b
280
+
281
+ @property
282
+ def tw(self) -> float:
283
+ """Returns thickness of web of UPN section.
284
+
285
+ Returns:
286
+ float: Web thickness tw of UPN section.
287
+ """
288
+ return self._tw
289
+
290
+ @property
291
+ def tf(self) -> float:
292
+ """Returns thickness of flange of UPN section.
293
+
294
+ Returns:
295
+ float: Flange thickness tw of UPN section.
296
+ """
297
+ return self._tf
298
+
299
+ @property
300
+ def r1(self) -> float:
301
+ """Returns fillet radius of UPN section.
302
+
303
+ Returns:
304
+ float: Fillet radius r1 of UPN section.
305
+ """
306
+ return self._r1
307
+
308
+ @property
309
+ def r2(self) -> float:
310
+ """Returns fillet radius of UPN section.
311
+
312
+ Returns:
313
+ float: Fillet radius r2 of UPN section.
314
+ """
315
+ return self._r2
@@ -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__(density=density, name=name)
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__(density=density, name=name)
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__(density=density, name=name)
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__(density=density, name=name)
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)