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

Files changed (50) hide show
  1. structuralcodes/__init__.py +17 -0
  2. structuralcodes/codes/__init__.py +79 -0
  3. structuralcodes/codes/ec2_2004/__init__.py +133 -0
  4. structuralcodes/codes/ec2_2004/_concrete_material_properties.py +239 -0
  5. structuralcodes/codes/ec2_2004/_reinforcement_material_properties.py +104 -0
  6. structuralcodes/codes/ec2_2004/_section_7_3_crack_control.py +941 -0
  7. structuralcodes/codes/ec2_2004/annex_b_shrink_and_creep.py +257 -0
  8. structuralcodes/codes/ec2_2004/shear.py +506 -0
  9. structuralcodes/codes/ec2_2023/__init__.py +104 -0
  10. structuralcodes/codes/ec2_2023/_annexB_time_dependent.py +17 -0
  11. structuralcodes/codes/ec2_2023/_section5_materials.py +1160 -0
  12. structuralcodes/codes/ec2_2023/_section9_sls.py +325 -0
  13. structuralcodes/codes/mc2010/__init__.py +169 -0
  14. structuralcodes/codes/mc2010/_concrete_creep_and_shrinkage.py +704 -0
  15. structuralcodes/codes/mc2010/_concrete_interface_different_casting_times.py +104 -0
  16. structuralcodes/codes/mc2010/_concrete_material_properties.py +463 -0
  17. structuralcodes/codes/mc2010/_concrete_punching.py +543 -0
  18. structuralcodes/codes/mc2010/_concrete_shear.py +749 -0
  19. structuralcodes/codes/mc2010/_concrete_torsion.py +164 -0
  20. structuralcodes/codes/mc2010/_reinforcement_material_properties.py +105 -0
  21. structuralcodes/core/__init__.py +1 -0
  22. structuralcodes/core/_section_results.py +211 -0
  23. structuralcodes/core/base.py +260 -0
  24. structuralcodes/geometry/__init__.py +25 -0
  25. structuralcodes/geometry/_geometry.py +875 -0
  26. structuralcodes/geometry/_steel_sections.py +2155 -0
  27. structuralcodes/materials/__init__.py +9 -0
  28. structuralcodes/materials/concrete/__init__.py +82 -0
  29. structuralcodes/materials/concrete/_concrete.py +114 -0
  30. structuralcodes/materials/concrete/_concreteEC2_2004.py +477 -0
  31. structuralcodes/materials/concrete/_concreteEC2_2023.py +435 -0
  32. structuralcodes/materials/concrete/_concreteMC2010.py +494 -0
  33. structuralcodes/materials/constitutive_laws.py +979 -0
  34. structuralcodes/materials/reinforcement/__init__.py +84 -0
  35. structuralcodes/materials/reinforcement/_reinforcement.py +172 -0
  36. structuralcodes/materials/reinforcement/_reinforcementEC2_2004.py +103 -0
  37. structuralcodes/materials/reinforcement/_reinforcementEC2_2023.py +93 -0
  38. structuralcodes/materials/reinforcement/_reinforcementMC2010.py +98 -0
  39. structuralcodes/sections/__init__.py +23 -0
  40. structuralcodes/sections/_generic.py +1249 -0
  41. structuralcodes/sections/_reinforcement.py +115 -0
  42. structuralcodes/sections/section_integrators/__init__.py +14 -0
  43. structuralcodes/sections/section_integrators/_factory.py +41 -0
  44. structuralcodes/sections/section_integrators/_fiber_integrator.py +238 -0
  45. structuralcodes/sections/section_integrators/_marin_integration.py +47 -0
  46. structuralcodes/sections/section_integrators/_marin_integrator.py +222 -0
  47. structuralcodes/sections/section_integrators/_section_integrator.py +49 -0
  48. structuralcodes-0.0.1.dist-info/METADATA +40 -0
  49. structuralcodes-0.0.1.dist-info/RECORD +50 -0
  50. structuralcodes-0.0.1.dist-info/WHEEL +4 -0
@@ -0,0 +1,941 @@
1
+ """Collection of functions from EUROCODE 1992-1-1:2004
2
+ Chapter 7.3 - Crack control.
3
+ """
4
+
5
+ import math
6
+ import typing as t
7
+
8
+ import numpy as np
9
+ import scipy.interpolate
10
+
11
+
12
+ def w_max(
13
+ exposure_class: t.Literal[
14
+ 'X0', 'XC1', 'XC2', 'XC3', 'XC4', 'XD1', 'XD2', 'XS1', 'XS2', 'XS3'
15
+ ],
16
+ load_combination: t.Literal['f', 'qp'],
17
+ ) -> float:
18
+ """Computes the recommended value of the maximum crack width.
19
+
20
+ EUROCODE 2 1992-1-1:2004, Table (7.1N).
21
+
22
+ Args:
23
+ exposure_class (str): The exposure class. Possible values: X0, XC1,
24
+ XC2, XC3, XC4, XD1, XD2, XS1, XS2, XS3.
25
+ load_combination (str): The characteristic of the load combination.
26
+ Frequent (f), or quasi-permanent (qp).
27
+
28
+ Returns:
29
+ float: The maximum recommended value for the crack width wmax in mm.
30
+
31
+ Raises:
32
+ ValueError: if not valid exposure_class or load_combination values.
33
+ """
34
+ _load_combination = load_combination.lower().strip()
35
+ _exposure_class = exposure_class.upper().strip()
36
+ if _load_combination == 'f':
37
+ if _exposure_class in ('X0', 'XC1'):
38
+ return 0.2
39
+ if _exposure_class in ('XC2', 'XC3', 'XC4'):
40
+ return 0.2
41
+ if _load_combination == 'qp':
42
+ if _exposure_class in ('X0', 'XC1'):
43
+ return 0.4
44
+ if _exposure_class in (
45
+ 'XC2',
46
+ 'XC3',
47
+ 'XC4',
48
+ 'XD1',
49
+ 'XD2',
50
+ 'XS1',
51
+ 'XS2',
52
+ 'XS3',
53
+ ):
54
+ return 0.3
55
+ raise ValueError(
56
+ f'{exposure_class} is not a valid value for exposure_class.'
57
+ + ' Please enter one of the following: X0, XC1, XC2, XC3, XC4, XD1'
58
+ + ',XD2, XS1, XS2, XS3'
59
+ )
60
+ raise ValueError(
61
+ f'{load_combination} is not a valid value for load_combination.'
62
+ + 'Please enter "f" for frequent load combination or "qp" for'
63
+ + 'quasi-permanent load combination.'
64
+ )
65
+
66
+
67
+ def As_min(
68
+ A_ct: float, sigma_s: float, fct_eff: float, k: float, kc: float
69
+ ) -> float:
70
+ """Computes the minimum area of reinforcing steel within the tensile zone
71
+ for control of cracking areas.
72
+
73
+ EUROCODE 2 1992-1-1:2004, Eq. (7.1).
74
+
75
+ Args:
76
+ A_ct (float): is the area of concrete within the tensile zone in mm2.
77
+ The tensile zone is that part of the section which is calculated
78
+ to be in tension just before the formation of the first crack.
79
+ sigma_s (float): is the absolute value of the maximum stress in MPa
80
+ permitted in the reinforcement immediately after the formation
81
+ of the crack. This may be taken as theyield strength of the
82
+ reinforcement, fyk. A lower value may, however, be needed to
83
+ satisfy the crack width limits according to the maximum
84
+ bar size of spacing (see 7.3.3 (2)).
85
+ fct_eff (float): is the mean value of the tensile strength in MPa of
86
+ the concrete effective at the time when the cracks may first be
87
+ expected to occur: fct,eff=fct or lower (fct(t)), is cracking
88
+ is expected earlier than 28 days.
89
+ k (float): is the coefficient which allow for the effect of
90
+ non-uniform self-equilibrating stresses, which lead to a
91
+ reduction of restraint forces.
92
+ k=1 for webs w<=300mm or flanges widths less than 300mm
93
+ k=0.65 for webs w>=800mm or flanges with widths greater than 800mm
94
+ Intermediate values may be interpolated.
95
+ kc (float): is a coefficient which takes account of the stress
96
+ distribution within the section immediately prior to cracking and
97
+ the change of the lever arm.
98
+
99
+ Returns:
100
+ float: The minimum area of reinforcing steel within the tensile zone in
101
+ mm2.
102
+
103
+ Raises:
104
+ ValueError: if k value is not between 0.65 and 1 or kc is not
105
+ larger than 0 and lower than 1.
106
+ """
107
+ fct_eff = abs(fct_eff)
108
+
109
+ if A_ct <= 0:
110
+ raise ValueError(f'A_ct={A_ct} must be larger than 0')
111
+ if sigma_s < 0:
112
+ raise ValueError(f'sigma_s={sigma_s} must be equal or larger than 0')
113
+ if k < 0.65 or k > 1.0:
114
+ raise ValueError(f'k={k} must be between 0.65 and 1')
115
+ if kc > 1 or kc < 0:
116
+ raise ValueError(f'kc={kc} must be lower than 1 and larger than 0')
117
+
118
+ return kc * k * fct_eff * A_ct / sigma_s
119
+
120
+
121
+ def k(h: float) -> float:
122
+ """Is the coefficient which allow for the effect of
123
+ non-uniform self-equilibrating stresses, which lead to a
124
+ reduction of restraint forces.
125
+ k=1 for webs w<=300mm or flanges widths less than 300mm
126
+ k=0.65 for webs w>=800mm or flanges with widths greater than 800mm.
127
+
128
+ EUROCODE 2 1992-1-1:2004, Eq. (7.1).
129
+
130
+ Args:
131
+ h (float): flange length or flange width in mm
132
+
133
+ Returns:
134
+ float: k coefficient value.
135
+
136
+ Raises:
137
+ ValueError: if h is less than 0
138
+ """
139
+ if h < 0:
140
+ raise ValueError(f'h={h} cannot be less than 0mm')
141
+ if h <= 300:
142
+ return 1
143
+ if h < 800:
144
+ interpol = scipy.interpolate.interp1d((300, 800), (1, 0.65))
145
+ return interpol(h)
146
+ return 0.65
147
+
148
+
149
+ def kc_tension() -> float:
150
+ """Computes the coefficient which takes account of the stress
151
+ distribution within the section immediately prior to cracking and
152
+ the change of the lever arm in pure tension.
153
+
154
+ EUROCODE 2 1992-1-1:2004, Eq. (7.1).
155
+
156
+ Returns:
157
+ float: Value of the kc coefficient in pure tension.
158
+ """
159
+ return 1
160
+
161
+
162
+ def kc_rect_area(h: float, b: float, fct_eff: float, N_ed: float) -> float:
163
+ """Computes the coefficient which takes account of the stress distribution
164
+ within the section immediately prior to cracking and the change of the
165
+ lever arm for bending+axial combination in rectangular sections and webs of
166
+ box sections and T-sections.
167
+
168
+ EUROCODE 2 1992-1-1:2004, Eq. (7.2).
169
+
170
+ Args:
171
+ h (float): heigth of the element in mm
172
+ b (float): width of the element in mm
173
+ fct_eff (float): is the mean value of the tensile strength in MPa of
174
+ the concrete effective at the time when the cracks may first be
175
+ expected to occur: fct,eff=fct or lower (fct(t)), is cracking is
176
+ expected earlier than 28 days.
177
+ N_ed (str): axial force at the serviceability limit state acting on the
178
+ part of the cross-section under consideration (compressive force
179
+ positive). n_ed should be determined considering the characteristic
180
+ values of prestress and axial forces under the relevant combination
181
+ of actions.
182
+
183
+ Returns:
184
+ float: Value of the kc coefficient.
185
+
186
+ Raises:
187
+ ValueError: If h or b are less than 0.
188
+ """
189
+ if h < 0:
190
+ raise ValueError(f'h={h} should be larger than 0mm')
191
+ if b < 0:
192
+ raise ValueError(f'b={b} should be larger than 0mm')
193
+
194
+ h_s = min(h, 1000)
195
+ k1 = 1.5 if N_ed >= 0 else 2 * h_s / 3 / h
196
+ s_concrete = N_ed * 1000 / b / h
197
+ h_ratio = h / h_s
198
+ return min(max(0.4 * (1 - s_concrete / k1 / h_ratio / fct_eff), 0), 1)
199
+
200
+
201
+ def kc_flanges_area(f_cr: float, A_ct: float, fct_eff: float) -> float:
202
+ """Computes the coefficient which takes account of the stress
203
+ distribution within the section immediately prior to cracking and
204
+ the change of the lever arm for bending+axial combination
205
+ in rectangular sections for flanges of box sections and T-sections.
206
+
207
+ EUROCODE 2 1992-1-1:2004, Eq. (7.3).
208
+
209
+ Args:
210
+ f_cr: is the absolute value in kN of the tensile force within the
211
+ flange immediately prior to cracking due to cracking moment
212
+ calculated with fct,eff.
213
+ A_ct (float): is the area of concrete within the tensile zone in mm2.
214
+ The tensile zone is that part of the section which is calculated
215
+ to be in tension just before the formation of the first crack.
216
+ fct_eff (float): is the mean value of the tensile strength in MPa of
217
+ the concrete effective at the time when the cracks may first be
218
+ expected to occur: fct,eff=fct or lower (fct(t)), is cracking
219
+ is expected earlier than 28 days.
220
+
221
+ Returns:
222
+ float: Value of the kc coefficient.
223
+
224
+ Raises:
225
+ ValueError: If A_ct is less than 0mm2.
226
+ """
227
+ f_cr = abs(f_cr)
228
+ return max(0.9 * f_cr * 1000 / A_ct / fct_eff, 0.5)
229
+
230
+
231
+ def xi1(xi: float, phi_p: float, phi_s: float) -> float:
232
+ """Computes the adjusted ratio of bond strength taking into account
233
+ the different diameters of prestressing and reinforcing steel.
234
+
235
+ EUROCODE 2 1992-1-1:2004, Eq. (7.5).
236
+
237
+ Args:
238
+ xi (float): ratio of bond strength of prestressing and reinforcing
239
+ steel, according to Table 6.2 in 6.8.2.
240
+ phi_p (float): largest bar diameter in mm of reinforcing steel.
241
+ Equal to 0 if only prestressing is used in control cracking.
242
+ phi_s (float): equivalent diameter in mm of tendon acoording
243
+ to 6.8.2.
244
+
245
+ Returns:
246
+ float: With the value of the ratio.
247
+
248
+ Raises:
249
+ ValueError: If diameters phi_s or phi_p are lower than 0. If ratio of
250
+ bond strength xi is less than 0.15 or larger than 0.8.
251
+ """
252
+ if phi_p <= 0:
253
+ raise ValueError(f'phi_p={phi_p} cannot be less than 0')
254
+ if phi_s < 0:
255
+ raise ValueError(f'phi_s={phi_s} cannot be less than 0')
256
+ if xi < 0.15:
257
+ raise ValueError(f'The minimum value for xi={xi} is 0.15')
258
+ if xi > 0.8:
259
+ raise ValueError(f'The maximum value for xi={xi} is 0.8')
260
+
261
+ return ((xi * phi_s / phi_p) ** 0.5) if phi_s > 0 else xi**0.5
262
+
263
+
264
+ def hc_eff(h: float, d: float, x: float) -> float:
265
+ """Returns the effective height of concrete in tension surrounding the
266
+ reinforcement or prestressing tendons.
267
+
268
+ EUROCODE 2 1992-1-1:2004, Section (7.3.2-3).
269
+
270
+ Args:
271
+ h (float): total depth of the element in mm.
272
+ d (float): distance in mm to the level of the steel centroid.
273
+ x (float): distance in mm to the zero tensile stress line.
274
+
275
+ Returns:
276
+ float: The effective height in mm.
277
+
278
+ Raises:
279
+ ValueError: If any of h, d or x is lower than zero.
280
+ ValueError: If d is greater than h.
281
+ ValueError: If x is greater than h.
282
+ """
283
+ if h < 0:
284
+ raise ValueError(f'h={h} cannot be less than 0')
285
+ if d < 0:
286
+ raise ValueError(f'd={d} cannot be less than 0')
287
+ if x < 0:
288
+ raise ValueError(f'x={x} cannot be less than zero')
289
+ if d > h:
290
+ raise ValueError(f'd={d} cannot be larger than h={h}')
291
+ if x > h:
292
+ raise ValueError(f'x={x} cannot be larger than h={h}')
293
+
294
+ return min(2.5 * (h - d), (h - x) / 3, h / 2)
295
+
296
+
297
+ def As_min_p(
298
+ A_ct: float,
299
+ sigma_s: float,
300
+ fct_eff: float,
301
+ k: float,
302
+ kc: float,
303
+ Ap: float,
304
+ phi_s: float,
305
+ phi_p: float,
306
+ xi: float,
307
+ delta_s: float,
308
+ ) -> float:
309
+ """Computes the minimum area of reinforcing steel within the tensile zone
310
+ for control of cracking areas in addition with bonded tendons.
311
+
312
+ EUROCODE 2 1992-1-1:2004, Eq. (7.1).
313
+
314
+ Args:
315
+ A_ct (float): is the area of concrete within the tensile zone in mm2.
316
+ The tensile zone is that part of the section which is calculated to
317
+ be in tension just before the formation of the first crack.
318
+ sigma_s (float): is the absolute value of the maximum stress in MPa
319
+ permitted in the reinforcement immediately after the formation of
320
+ the crack. This may be taken as the yield strength of the
321
+ reinforcement, fyk. A lower value may, however, be needed to
322
+ satisfy the crack width limits according to the maximum bar size of
323
+ spacing (see 7.3.3 (2)).
324
+ fct_eff (float): is the mean value of the tensile strength in MPa of
325
+ the concrete effective at the time when the cracks may first be
326
+ expected to occur: fct,eff=fct or lower (fct(t)), is cracking is
327
+ expected earlier than 28 days.
328
+ k (float): is the coefficient which allow for the effect of non-
329
+ uniform self-equilibrating stresses, which lead to a reduction of
330
+ restraint forces. k=1 for webs w<=300mm or flanges widths less than
331
+ 300mm. k=0.65 for webs w>=800mm or flanges with widths greater than
332
+ 800mm. Intermediate values may be interpolated.
333
+ kc (float): is a coefficient which takes account of the stress
334
+ distribution within the section immediately prior to cracking and
335
+ the change of the lever arm.
336
+ Ap (float): is the area in mm2 of pre or post-tensioned tendons within
337
+ ac_eff.
338
+ phi_s (float): largest bar diameter in mm of reinforcing steel. Equal
339
+ to 0 if only prestressing is used in control cracking.
340
+ phi_p (float): equivalent diameter in mm of tendon according to 6.8.2.
341
+ xi (float): ratio of bond strength of prestressing and reinforcing
342
+ steel, according to Table 6.2 in 6.8.2.
343
+ delta_s (float): stress variation in MPa in prestressing tendons from
344
+ the state of zero strain of the concrete at the same level.
345
+
346
+ Returns:
347
+ float: The minimm area of reinforcing steel within the tensile zone in
348
+ mm2.
349
+
350
+ Raises:
351
+ ValueError: If k value is not between 0.65 and 1 or kc is not larger
352
+ than 0 and lower than 1. If diameters phi_s or phi_p are lower than 0.
353
+ If ratio of bond xi strength is less than 0.15 or larger than 0.8. If
354
+ stress variation incr_stress is less than 0.
355
+ """
356
+ fct_eff = abs(fct_eff)
357
+
358
+ if Ap < 0:
359
+ raise ValueError(f'Ap={Ap} cannot be less than 0')
360
+ if delta_s < 0:
361
+ raise ValueError(f'delta_s={delta_s} cannot be less than 0')
362
+ if A_ct <= 0:
363
+ raise ValueError(f'A_ct={A_ct} must be larger than 0')
364
+ if sigma_s < 0:
365
+ raise ValueError(f'sigma_s={sigma_s} must be equal or larger than 0')
366
+ if k < 0.65 or k > 1.0:
367
+ raise ValueError(f'k={k} must be between 0.65 and 1')
368
+ if kc > 1 or kc < 0:
369
+ raise ValueError(f'kc={kc} must be lower than 1 and larger than 0')
370
+
371
+ a1 = kc * k * fct_eff * A_ct
372
+ e1 = xi1(xi, phi_p, phi_s)
373
+ a2 = e1 * Ap * delta_s
374
+ a = a1 - a2
375
+
376
+ return a / sigma_s
377
+
378
+
379
+ def As_min_2(
380
+ wk: float,
381
+ sigma_s: float,
382
+ fct_eff: float,
383
+ h_cr: float,
384
+ h: float,
385
+ d: float,
386
+ delta_s: float = 0,
387
+ kc: t.Optional[float] = None,
388
+ ) -> t.Tuple[float, float]:
389
+ """Computes the minimum area of reinforcing steel within the tensile zone
390
+ for control of cracking areas.
391
+
392
+ EUROCODE 2 1992-1-1:2004, Table (7.2N), Table (7.3N).
393
+
394
+ Args:
395
+ wk (float): the characteristic crack width value in mm.
396
+ sigma_s (float): the steel stress value in MPa under the relevant
397
+ combination of actions.
398
+ fct_eff (float): is the mean value of the tensile strength in MPa of
399
+ the concrete effective at the time when the cracks may first be
400
+ expected to occur: fct,eff=fct or lower (fct(t)), is cracking is
401
+ expected earlier than 28 days.
402
+ h_cr (float): is the depth of the tensile zone immediately prior to
403
+ cracking, considering the characteristic values of prestress and
404
+ axial forces under the quasi-permanent combination of actions.
405
+ h (float): the overall depth of the section in mm.
406
+ d (float): is the effective depth to the centroid of the outer layer of
407
+ the reinforcement.
408
+
409
+ Keyword Args:
410
+ delta_s (float, optional): value of prestressed stress in MPa if
411
+ applicable.
412
+ kc (float, optional): is a coefficient which takes account of the
413
+ stress distribution within the section immediately prior to
414
+ cracking and the change of the lever arm in a bending section. None
415
+ for pure tensile uniform axial section.
416
+
417
+ Returns:
418
+ tuple(float, float): With the value of the maximum bar diameters in mm
419
+ in the first position and the maximum bar spacing in mm in the second
420
+ position.
421
+
422
+ Raises:
423
+ ValueError: If wk, fct_eff, h_cr, h or d are less than 0.
424
+ ValueError: If kc is not between 0 and 1.
425
+ ValueError: If combination of wk and stress values are out of scope.
426
+ """
427
+ if wk < 0:
428
+ raise ValueError(f'wk={wk} cannot be less than 0')
429
+ if fct_eff < 0:
430
+ raise ValueError(f'fct_eff={fct_eff} is less than 0')
431
+ if h_cr < 0:
432
+ raise ValueError(f'h_cr={h_cr} is less than 0')
433
+ if h < 0:
434
+ raise ValueError(f'h={h} is less than 0')
435
+ if d < 0:
436
+ raise ValueError(f'd={d} is less than 0')
437
+ if kc is not None and (kc < 0 or kc > 1):
438
+ raise ValueError(f'kc={kc} is not between 0 and 1')
439
+
440
+ s = sigma_s - delta_s
441
+ if s <= 0:
442
+ return (0, 0)
443
+
444
+ x = (0.4, 0.3, 0.2)
445
+ y_phi = (160, 200, 240, 280, 320, 360, 400, 450)
446
+ y_spa = (160, 200, 240, 280, 320, 360)
447
+ phi_s_v = (
448
+ 40,
449
+ 32,
450
+ 25,
451
+ 32,
452
+ 25,
453
+ 16,
454
+ 20,
455
+ 16,
456
+ 12,
457
+ 16,
458
+ 12,
459
+ 8,
460
+ 12,
461
+ 10,
462
+ 6,
463
+ 10,
464
+ 8,
465
+ 5,
466
+ 8,
467
+ 6,
468
+ 4,
469
+ 6,
470
+ 5,
471
+ None,
472
+ )
473
+ spa_v = (
474
+ 300,
475
+ 300,
476
+ 200,
477
+ 300,
478
+ 250,
479
+ 150,
480
+ 250,
481
+ 200,
482
+ 100,
483
+ 200,
484
+ 150,
485
+ 50,
486
+ 150,
487
+ 100,
488
+ None,
489
+ 100,
490
+ 50,
491
+ None,
492
+ )
493
+
494
+ points_phi = np.array(np.meshgrid(y_phi, x)).T.reshape(-1, 2)
495
+ points_spa = np.array(np.meshgrid(y_spa, x)).T.reshape(-1, 2)
496
+ xi = (s, wk)
497
+
498
+ phi_star = float(
499
+ scipy.interpolate.griddata(points_phi, phi_s_v, xi, method='linear')
500
+ )
501
+ if kc is not None:
502
+ phi = phi_star * (fct_eff / 2.9) * kc * h_cr / (2 * (h - d))
503
+ else:
504
+ phi = phi_star * (fct_eff / 2.9) * h_cr / (8 * (h - d))
505
+
506
+ spa = float(
507
+ scipy.interpolate.griddata(points_spa, spa_v, xi, method='linear')
508
+ )
509
+
510
+ if math.isnan(phi) or math.isnan(spa):
511
+ raise ValueError('Combination of wk or stress values out of scope')
512
+
513
+ return phi, spa
514
+
515
+
516
+ def alpha_e(Es: float, Ecm: float) -> float:
517
+ """Compute the ratio between the steel and mean concrete elastic modules.
518
+
519
+ EUROCODE 2 1992-1-1:2004, Section 7.3.4-2
520
+
521
+ Args:
522
+ Es (float): Steel elastic modulus in MPa.
523
+ Ecm (float): Concrete mean elastic modulus in MPa.
524
+
525
+ Returns:
526
+ float: Ratio between modules.
527
+
528
+ Raises:
529
+ ValueError: If any of es or ecm is lower than 0.
530
+ """
531
+ if Es < 0:
532
+ raise ValueError(f'Es={Es} cannot be less than 0')
533
+ if Ecm < 0:
534
+ raise ValueError(f'Ecm={Ecm} cannot be less than 0')
535
+
536
+ return Es / Ecm
537
+
538
+
539
+ def rho_p_eff(As: float, xi1: float, Ap: float, Ac_eff: float) -> float:
540
+ """Effective bond ratio between areas.
541
+
542
+ EUROCODE 2 1992-1-1:2004, Eq. (7.10).
543
+
544
+ Args:
545
+ As (float): Steel area in mm2.
546
+ xi1 (float): The adjusted ratio of bond according to expression (7.5).
547
+ Ap (float): The area in mm2 of post-tensioned tendons in ac_eff.
548
+ Ac_eff (float): Effective area of concrete in tension surrounding the
549
+ reinforcement or prestressing tendons of depth hc_eff.
550
+
551
+ Returns:
552
+ float: With the retio between areas.
553
+
554
+ Raises:
555
+ ValueError: If any of As, xi1, Ap or Ac_eff is less than 0.
556
+ """
557
+ if As < 0:
558
+ raise ValueError(f'As={As} cannot be less than 0')
559
+ if xi1 < 0:
560
+ raise ValueError(f'xi1={xi1} cannot be less than 0')
561
+ if Ap < 0:
562
+ raise ValueError(f'Ap={Ap} cannot be less than 0')
563
+ if Ac_eff < 0:
564
+ raise ValueError(f'Ac_eff={Ac_eff} cannot be less than 0')
565
+
566
+ return (As + xi1**2 * Ap) / Ac_eff
567
+
568
+
569
+ def kt(load_type: t.Literal['short', 'long']) -> float:
570
+ """Returns the kt factor dependent on the load duration for the crack width
571
+ calculation.
572
+
573
+ Args:
574
+ load_type (str): The load type, 'short' for term loading, 'long' for
575
+ long term loading.
576
+
577
+ Returns:
578
+ float: With the kt factor.
579
+
580
+ Raises:
581
+ ValueError: If load_type is not 'short' and not 'long'.
582
+ """
583
+ if not isinstance(load_type, str):
584
+ raise TypeError
585
+
586
+ load_type = load_type.lower().strip()
587
+ if load_type not in ('short', 'long'):
588
+ raise ValueError(
589
+ f'load_type={load_type} can only have "short" or "long" as a value'
590
+ )
591
+
592
+ return 0.6 if load_type == 'short' else 0.4
593
+
594
+
595
+ def eps_sm_eps_cm(
596
+ sigma_s: float,
597
+ alpha_e: float,
598
+ rho_p_eff: float,
599
+ kt: float,
600
+ fct_eff: float,
601
+ Es: float,
602
+ ) -> float:
603
+ """Returns the strain difference (epsilon_sm - epsilon_cm) needed to
604
+ compute the crack width. esm is the mean strain in the reinforcement under
605
+ the relevant combination of loads of imposed deformations and taking into
606
+ account the effects of tension stiffening. Only the additional tensile
607
+ strain beyond the state of zero strain of the concrete is considered.
608
+ epsilon_cm is the mean strain in the concrete between the cracks.
609
+
610
+ EUROCODE 2 1992-1-1:2004, Eq. (7.9).
611
+
612
+ Args:
613
+ sigma_s (float): Is the stress in MPa in the tension reinforcement
614
+ assuming a cracked section. For pretensioned members, s_steel may
615
+ be replaced by increment of s_steel stress variation in
616
+ prestressing tendons from the state of zero strain of the concrete
617
+ at the same level.
618
+ alpha_e (float): Is the ratio Es/Ecm.
619
+ rho_p_eff (float): Effective bond ratio between areas given by Eq.
620
+ (7.10).
621
+ kt (float): Is a factor dependent on the load duration.
622
+ fct_eff (float): Is the mean value of the tensile strength in MPa of
623
+ the concrete effective at the time when the cracks may first be
624
+ expected to occur: fct_eff=fctm or fctm(t) if crack is expected
625
+ earlier than 28 days.
626
+ Es (float): Steel elastic modulus in MPa.
627
+
628
+ Returns:
629
+ float: The strain difference between concrete and steel.
630
+
631
+ Raises:
632
+ ValueError: If any sigma_s, alpha_e, rho_p_eff, fct_eff or Es is less
633
+ than 0.
634
+ ValueError: if kt is not 0.6 and not 0.4.
635
+ """
636
+ if sigma_s < 0:
637
+ raise ValueError(f'sigma_s={sigma_s} cannot be less than 0')
638
+ if alpha_e < 0:
639
+ raise ValueError(f'alpha_e={alpha_e} cannot be less than 0')
640
+ if rho_p_eff < 0:
641
+ raise ValueError(f'rho_p_eff={rho_p_eff} cannot be less than 0')
642
+ if fct_eff < 0:
643
+ raise ValueError(f'fct_eff={fct_eff} cannot be less than 0')
644
+ if Es < 0:
645
+ raise ValueError(f'Es={Es} cannot be less than 0')
646
+ if kt not in (0.6, 0.4):
647
+ raise ValueError(f'kt={kt} can only take as values 0.4 and 0.6')
648
+
649
+ min_val = 0.6 * sigma_s / Es
650
+
651
+ a = 1 + alpha_e * rho_p_eff
652
+ b = kt * fct_eff / rho_p_eff * a
653
+ c = (sigma_s - b) / Es
654
+
655
+ return max(c, min_val)
656
+
657
+
658
+ def w_spacing(c: float, phi: float) -> float:
659
+ """Computes the distance threshold from which the maximum crack spacing is
660
+ constant.
661
+
662
+ EUROCODE 2 1992-1-1:2004, Sect. (7.3.4-3).
663
+
664
+ Args:
665
+ c (float): Cover of the longitudinal reinforcement in mm.
666
+ phi (float): Is the bar diameter in mm. Where mixed bar diameters used,
667
+ then it should be replaced for an equivalent bar diameter.
668
+
669
+ Returns:
670
+ float: Threshold distance in mm.
671
+
672
+ Raises:
673
+ ValueError: If any of c or phi is less than 0.
674
+ """
675
+ if c < 0:
676
+ raise ValueError(f'c={c} cannot be less than 0')
677
+ if phi < 0:
678
+ raise ValueError(f'phi={phi} cannot be less than 0')
679
+
680
+ return 5 * (c + phi / 2)
681
+
682
+
683
+ def phi_eq(n1: int, n2: int, phi1: float, phi2: float) -> float:
684
+ """Computes the equivalent diameter. For a section with n1 bars of diameter
685
+ phi1 and n2 bars of diameter phi2.
686
+
687
+ EUROCODE 2 1992-1-1:2004, Sect. (7.12).
688
+
689
+ Args:
690
+ n1 (int): Number of bars with diameter phi1.
691
+ n2 (int): Number of bars with diameter phi2.
692
+ phi1 (float): Diameter of n1 bars in mm.
693
+ phi2 (float): Diamater of n2 bars in mm.
694
+
695
+ Returns:
696
+ float: The equivalent diameter in mm.
697
+
698
+ Raises:
699
+ ValueError: If any of n1 or n2 is less than 0.
700
+ ValueError: If any of phi1 or phi2 is less than 0.
701
+ TypeError: If any of n1 or n2 is not an integer.
702
+ """
703
+ if n1 < 0:
704
+ raise ValueError(f'n1={n1} cannot be less than 0')
705
+ if not isinstance(n1, int):
706
+ raise TypeError(f'n1={n1} needs to be an integer value')
707
+ if n2 < 0:
708
+ raise ValueError(f'n2={n2} cannot be less than 0')
709
+ if not isinstance(n2, int):
710
+ raise TypeError(f'n2={n2} needs to be an integer value')
711
+ if phi1 < 0:
712
+ raise ValueError(f'phi1={phi1} cannot be less than 0')
713
+ if phi2 < 0:
714
+ raise ValueError(f'phi2={phi2} cannot be less than 0')
715
+
716
+ a = n1 * phi1**2 + n2 * phi2**2
717
+ b = n1 * phi1 + n2 * phi2
718
+ return a / b
719
+
720
+
721
+ def k1(bond_type: t.Literal['bond', 'plain']) -> float:
722
+ """Get the k1 coefficient which takes account of the bond properties of the
723
+ bounded reinforcement.
724
+
725
+ EUROCODE 2 1992-1-1:2004, Eq. (7.11-k1).
726
+
727
+ Args:
728
+ bond_type (str): The bond property of the reinforcement. High bond bars
729
+ (bond), or bars with an effectively plain surface (plain).
730
+
731
+ Returns:
732
+ float: Value of the k1 coefficient.
733
+
734
+ Raises:
735
+ ValueError: If bond_type is neither 'bond' nor 'plain'.
736
+ TypeError: If bond_type is not an str.
737
+ """
738
+ if not isinstance(bond_type, str):
739
+ raise TypeError(f'bond_type={bond_type} is not an str')
740
+
741
+ bond_type = bond_type.lower().strip()
742
+ if bond_type not in ('bond', 'plain'):
743
+ raise ValueError(
744
+ f'bond_type={bond_type} can only have "bond" or "plain" as values'
745
+ )
746
+
747
+ return 0.8 if bond_type == 'bond' else 1.6
748
+
749
+
750
+ def k2(eps_r: float) -> float:
751
+ """Computes a coeff. which takes into account the distribution of strain.
752
+
753
+ EUROCODE 2 1992-1-1:2004, Eq. (7.13).
754
+
755
+ Args:
756
+ eps_r (float): ratio epsilon_2/epsilon_1 where epsilon_1 is the greater
757
+ and epsilon_2 is the lesser strain at the boundaries of the section
758
+ considered, assessed on the basis of a cracked section. epsilon_r=0
759
+ for bending and epsilon_r=1 for pure tension.
760
+
761
+ Returns:
762
+ float: The k2 coefficient value.
763
+
764
+ Raises:
765
+ ValueError: If eps_r is not between 0 and 1.
766
+ """
767
+ if eps_r < 0 or eps_r > 1:
768
+ raise ValueError(f'eps_r={eps_r} must be between 0 and 1')
769
+
770
+ return (1 + eps_r) / 2
771
+
772
+
773
+ def k3():
774
+ """Returns the k3 coefficient for computing sr_max.
775
+
776
+ Returns:
777
+ float: Value for the coefficient.
778
+ """
779
+ return 3.4
780
+
781
+
782
+ def k4():
783
+ """Returns the k4 coefficient for computing sr_max.
784
+
785
+ Returns:
786
+ float: Value for the coefficient.
787
+ """
788
+ return 0.425
789
+
790
+
791
+ K_COEFFICIENTS = {'k1': k1, 'k2': k2, 'k3': k3, 'k4': k4}
792
+
793
+
794
+ def sr_max_close(
795
+ c: float,
796
+ phi: float,
797
+ rho_p_eff: float,
798
+ k1: float,
799
+ k2: float,
800
+ k3: t.Optional[float] = None,
801
+ k4: t.Optional[float] = None,
802
+ ) -> float:
803
+ """Computes the maximum crack spacing in cases where bonded reinforcement
804
+ is fixed at reasonably close centres within the tension zone
805
+ (w_spacing<=5(c+phi/2)).
806
+
807
+ EUROCODE 2 1992-1-1:2004, Eq. (7.11).
808
+
809
+ Args:
810
+ c (float): Is the cover in mm of the longitudinal reinforcement.
811
+ phi (float): Is the bar diameter in mm. Where mixed bar diameters used,
812
+ then it should be replaced for an equivalent bar diameter.
813
+ rho_p_eff (float): Effective bond ratio between areas given by Eq.
814
+ (7.10).
815
+ k1 (float): Coefficient that takes into account the bound properties
816
+ of the bonded reinforcement.
817
+ k2 (float): Coefficient that takes into account the distribution of of
818
+ the strain.
819
+
820
+ Keyword Args:
821
+ k3 (float, optional): Coefficient from the National Annex. If not
822
+ specified then k3=3.4.
823
+ k4 (float): Coefficient from the National Annex. If not specified then
824
+ k4=0.425.
825
+
826
+ Returns:
827
+ float: The maximum crack spaing in mm.
828
+
829
+ Raises:
830
+ ValueError: If one or more of c, phi, rho_p_eff, k3 or k4
831
+ is lower than zero.
832
+ ValueError: If k1 is not 0.8 or 1.6.
833
+ ValueError: If k2 is not between 0.5 and 1.0.
834
+ """
835
+ if k3 is None:
836
+ k3 = K_COEFFICIENTS['k3']()
837
+ if k4 is None:
838
+ k4 = K_COEFFICIENTS['k4']()
839
+
840
+ if c < 0:
841
+ raise ValueError(f'c={c} cannot be less than zero')
842
+ if phi < 0:
843
+ raise ValueError(f'phi={phi} cannot be less than zero')
844
+ if rho_p_eff < 0:
845
+ raise ValueError(f'rho_p_eff={rho_p_eff} cannot be less than zero')
846
+ if k3 < 0:
847
+ raise ValueError(f'k3={k3} cannot be less than zero')
848
+ if k4 < 0:
849
+ raise ValueError(f'k4={k4} cannot be less than zero')
850
+ if k1 not in (0.8, 1.6):
851
+ raise ValueError(f'k1={k1} can only take as values 0.8 and 1.6')
852
+ if k2 < 0.5 or k2 > 1:
853
+ raise ValueError(f'k2={k2} is not between 0.5 and 1.0')
854
+
855
+ return k3 * c + k1 * k2 * k4 * phi / rho_p_eff
856
+
857
+
858
+ def sr_max_far(h: float, x: float) -> float:
859
+ """Computes the maximum crack spacing in cases where bonded reinforcement
860
+ exceeds (w_spacing>5(c+phi/2)) or where there is no bonded reinforcement at
861
+ all.
862
+
863
+ EUROCODE 2 1992-1-1:2004, Eq. (7.14).
864
+
865
+ Args:
866
+ h (float): Total depth of the beam in mm.
867
+ x (float): Distance to non tension area of the element mm.
868
+
869
+ Returns:
870
+ float: Maximum crack spacing in mm.
871
+
872
+ Raises:
873
+ ValueError: If one of h or x is less than zero.
874
+ ValueError: If x is greater than h.
875
+ """
876
+ if x < 0:
877
+ raise ValueError(f'x={x} cannot be less than zero')
878
+ if h < 0:
879
+ raise ValueError(f'h={h} cannot be less than zero')
880
+ if x > h:
881
+ raise ValueError(f'x={x} cannot be larger than h={h}')
882
+
883
+ return 1.3 * (h - x)
884
+
885
+
886
+ def sr_max_theta(sr_max_y: float, sr_max_z: float, theta: float) -> float:
887
+ """Computes the crack spacing sr_max when there is an angle between the
888
+ angle of principal stress and the direction of the reinforcement, for
889
+ members in two orthogonal directions, that is significant (> 15 degrees).
890
+
891
+ EUROCODE 2 1992-1-1:2004, Eq. (7.15).
892
+
893
+ Args:
894
+ sr_max_y (float): Crack spacing in mm in the y-direction.
895
+ sr_max_z (float): Crack spacing in mm in the z-direction.
896
+ theta (float): Angle in radians between the reinforcement in the
897
+ y-direction and the direction of the principal tensile stress.
898
+
899
+ Returns:
900
+ float: The crack spacing in mm.
901
+
902
+ Raises:
903
+ ValueError: If sr_max_y or sr_max_z is negative.
904
+ ValueError: If theta is not between 0 and pi/2.
905
+ """
906
+ if sr_max_y < 0:
907
+ raise ValueError(f'sr_max_y={sr_max_y} cannot be less than zero')
908
+ if sr_max_z < 0:
909
+ raise ValueError(f'sr_max_z={sr_max_z} cannot be less than zero')
910
+
911
+ a = math.cos(theta) / sr_max_y
912
+ b = math.sin(theta) / sr_max_z
913
+ return 1 / (a + b)
914
+
915
+
916
+ def wk(sr_max: float, eps_sm_eps_cm: float) -> float:
917
+ """Computes the crack width.
918
+
919
+ EUROCODE 2 1992-1-1:2004, Eq. (7.8).
920
+
921
+ Args:
922
+ sr_max (float): The maximum crack length spacing in mm.
923
+ eps_sm_eps_cm (float): the difference between the mean strain in the
924
+ reinforcement under relevant combination of loads, including the
925
+ effect of imposed deformations and taking into account tension
926
+ stiffening and the mean strain in the concrete between cracks.
927
+
928
+ Returns:
929
+ float: Crack width in mm.
930
+
931
+ Raises:
932
+ ValueError: If any of sr_max or esm_ecm is less than zero.
933
+ """
934
+ if sr_max < 0:
935
+ raise ValueError(f'sr_max={sr_max} cannot be less than zero')
936
+ if eps_sm_eps_cm < 0:
937
+ raise ValueError(
938
+ f'eps_sm_eps_cm={eps_sm_eps_cm} cannot be less than zero'
939
+ )
940
+
941
+ return sr_max * eps_sm_eps_cm