structuralcodes 0.1.1__py3-none-any.whl → 0.2.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.

@@ -0,0 +1,133 @@
1
+ """Popovics 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 Popovics(ConstitutiveLaw):
14
+ """Class for Popovics-Mander constitutive law.
15
+
16
+ The stresses and strains are assumed negative in compression and positive
17
+ in tension.
18
+
19
+ If the relation Ec = 5000 * sqrt(fc) is used for elastic modulus, the
20
+ constitutive law is identical to the one proposed by Mander et al. (1988).
21
+
22
+ References:
23
+ Popovics, S., 1973, “A Numerical Approach to the Complete Stress-Strain
24
+ Curve of Concrete”, Cement and Concrete Research, 3(4), 583-599.
25
+
26
+ Mander, J.B., Priestley, M.J.N., Park, R., 1988, "Theoretical Stress-Strain
27
+ Model for Confined Concrete", Journal of Structural Engineering, 114(8),
28
+ 1804-1826.
29
+ """
30
+
31
+ __materials__: t.Tuple[str] = ('concrete',)
32
+
33
+ def __init__(
34
+ self,
35
+ fc: float,
36
+ eps_c: float = -0.002,
37
+ eps_cu: float = -0.0035,
38
+ Ec: t.Optional[float] = None,
39
+ name: t.Optional[str] = None,
40
+ ) -> None:
41
+ """Initialize a Popovics Material.
42
+
43
+ Arguments:
44
+ fc (float): the strength of concrete in compression
45
+
46
+ Keyword Arguments:
47
+ eps_c (float): Peak strain of concrete in compression. Default
48
+ value = -0.002.
49
+ eps_cu (float): Ultimate strain of concrete in compression. Default
50
+ value = -0.0035.
51
+ E (optional float): Elastic modulus of concrete. If None, the
52
+ equation Ec = 5000 * fc**0.5 proposed by Mander et al. (1988)
53
+ is adopted (fc in MPa). Default value = None.
54
+ name (str): A name for the constitutive law.
55
+
56
+ Raises:
57
+ ValueError: If E is less or equal to 0.
58
+
59
+ Note:
60
+ If positive values are input for fc, eps_c and eps_cu are input,
61
+ they will be assumed negative.
62
+ """
63
+ name = name if name is not None else 'PopovicsLaw'
64
+ super().__init__(name=name)
65
+ self._fc = -abs(fc)
66
+ self._eps_c = -abs(eps_c)
67
+ self._eps_cu = -abs(eps_cu)
68
+ if Ec is None:
69
+ # fc in MPa, relation of Mander et al. (1988)
70
+ Ec = 5000 * abs(fc) ** 0.5
71
+ if Ec <= 0:
72
+ raise ValueError('Elastic modulus must be a positive number.')
73
+ E_sec = self._fc / self._eps_c
74
+ self._n = Ec / (Ec - E_sec)
75
+
76
+ def get_stress(
77
+ self, eps: t.Union[float, ArrayLike]
78
+ ) -> t.Union[float, ArrayLike]:
79
+ """Return the stress given the strain."""
80
+ eps = eps if np.isscalar(eps) else np.atleast_1d(eps)
81
+ # Preprocess eps array in order
82
+ eps = self.preprocess_strains_with_limits(eps=eps)
83
+ # Compute stress
84
+ # Compression branch
85
+ eta = eps / self._eps_c
86
+
87
+ sig = self._fc * eta * self._n / (self._n - 1 + eta**self._n)
88
+
89
+ # Elsewhere stress is 0.0
90
+ if np.isscalar(eps):
91
+ if eps < self._eps_cu or eps > 0:
92
+ return 0.0
93
+ else:
94
+ sig[eps < self._eps_cu] = 0.0
95
+ sig[eps > 0] = 0.0
96
+
97
+ return sig
98
+
99
+ def get_tangent(
100
+ self, eps: t.Union[float, ArrayLike]
101
+ ) -> t.Union[float, ArrayLike]:
102
+ """Return the tangent given strain."""
103
+ eps = eps if np.isscalar(eps) else np.atleast_1d(eps)
104
+ # Preprocess eps array in order
105
+ eps = self.preprocess_strains_with_limits(eps=eps)
106
+ # Compression branch
107
+ eta = eps / self._eps_c
108
+
109
+ tangent = (
110
+ (1 - eta**self._n)
111
+ / (self._n - 1 + eta**self._n) ** 2
112
+ * self._n
113
+ * (self._n - 1)
114
+ * self._fc
115
+ / self._eps_c
116
+ )
117
+ # Elsewhere tangent is zero
118
+ if np.isscalar(eps):
119
+ if eps < self._eps_cu or eps > 0:
120
+ return 0
121
+ else:
122
+ tangent[eps < self._eps_cu] = 0.0
123
+ tangent[eps > 0] = 0.0
124
+
125
+ return tangent
126
+
127
+ def get_ultimate_strain(
128
+ self, yielding: bool = False
129
+ ) -> t.Tuple[float, float]:
130
+ """Return the ultimate strain (negative and positive)."""
131
+ if yielding:
132
+ return (self._eps_c, 100)
133
+ return (self._eps_cu, 100)
@@ -0,0 +1,115 @@
1
+ """Sargin 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 Sargin(ConstitutiveLaw):
14
+ """Class for Sargin constitutive law.
15
+
16
+ The stresses and strains are assumed negative in compression and positive
17
+ in tension.
18
+
19
+ References:
20
+ Sargin, M. (1971), "Stress-strain relationship for concrete and the
21
+ analysis of structural concrete section, Study No. 4,
22
+ Solid Mechanics Division, University of Waterloo, Ontario, Canada
23
+ """
24
+
25
+ __materials__: t.Tuple[str] = ('concrete',)
26
+
27
+ def __init__(
28
+ self,
29
+ fc: float,
30
+ eps_c1: float = -0.0023,
31
+ eps_cu1: float = -0.0035,
32
+ k: float = 2.04,
33
+ name: t.Optional[str] = None,
34
+ ) -> None:
35
+ """Initialize a Sargin Material.
36
+
37
+ Arguments:
38
+ fc (float): The strength of concrete in compression
39
+
40
+ Keyword Arguments:
41
+ eps_c1 (float): Peak strain of concrete in compression. Default
42
+ value = -0.0023.
43
+ eps_u (float): Ultimate strain of concrete in compression. Default
44
+ value = -0.0035.
45
+ k (float): Plasticity number. Default value = 2.04.
46
+ name (str): A name for the constitutive law.
47
+
48
+ Raises:
49
+ ValueError: If k is less or equal to 0.
50
+
51
+ Note:
52
+ If positive values are input for fc, eps_c1 and eps_cu1 are input,
53
+ they will be assumed negative.
54
+ """
55
+ name = name if name is not None else 'SarginLaw'
56
+ super().__init__(name=name)
57
+ self._fc = -abs(fc)
58
+ self._eps_c1 = -abs(eps_c1)
59
+ self._eps_cu1 = -abs(eps_cu1)
60
+ self._k = k
61
+
62
+ def get_stress(
63
+ self, eps: t.Union[float, ArrayLike]
64
+ ) -> t.Union[float, ArrayLike]:
65
+ """Return the stress given the strain."""
66
+ eps = eps if np.isscalar(eps) else np.atleast_1d(eps)
67
+ # Preprocess eps array in order
68
+ eps = self.preprocess_strains_with_limits(eps=eps)
69
+ # Compute stress
70
+ # Polynomial branch
71
+ eta = eps / self._eps_c1
72
+
73
+ sig = self._fc * (self._k * eta - eta**2) / (1 + (self._k - 2) * eta)
74
+
75
+ # Elsewhere stress is 0.0
76
+ if np.isscalar(eps):
77
+ if eps < self._eps_cu1 or eps > 0:
78
+ return 0.0
79
+ else:
80
+ sig[eps < self._eps_cu1] = 0.0
81
+ sig[eps > 0] = 0.0
82
+
83
+ return sig
84
+
85
+ def get_tangent(
86
+ self, eps: t.Union[float, ArrayLike]
87
+ ) -> t.Union[float, ArrayLike]:
88
+ """Return the tangent given strain."""
89
+ eps = eps if np.isscalar(eps) else np.atleast_1d(eps)
90
+ # polynomial branch
91
+ eta = eps / self._eps_c1
92
+
93
+ tangent = (
94
+ self._fc
95
+ / self._eps_c1
96
+ * ((2 - self._k) * eta**2 - 2 * eta + self._k)
97
+ / (1 + (self._k - 2) * eta) ** 2
98
+ )
99
+ # Elsewhere tangent is zero
100
+ if np.isscalar(eps):
101
+ if eps < self._eps_cu1 or eps > 0:
102
+ return 0
103
+ else:
104
+ tangent[eps < self._eps_cu1] = 0.0
105
+ tangent[eps > 0] = 0.0
106
+
107
+ return tangent
108
+
109
+ def get_ultimate_strain(
110
+ self, yielding: bool = False
111
+ ) -> t.Tuple[float, float]:
112
+ """Return the ultimate strain (negative and positive)."""
113
+ if yielding:
114
+ return (self._eps_c1, 100)
115
+ return (self._eps_cu1, 100)
@@ -0,0 +1,218 @@
1
+ """User defined 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 UserDefined(ConstitutiveLaw):
14
+ """Class for a user defined constitutive law.
15
+
16
+ The curve is defined with positive and optionally negative values. After
17
+ the last value, the stress can go to zero to simulate failure (default), or
18
+ be maintained constante, or the last tanget or secant values may be
19
+ maintained indefinetely. The flag parameter controls this behavior.
20
+ """
21
+
22
+ __materials__: t.Tuple[str] = ('concrete', 'steel', 'rebars')
23
+
24
+ def __init__(
25
+ self,
26
+ x: ArrayLike,
27
+ y: ArrayLike,
28
+ name: t.Optional[str] = None,
29
+ flag: int = 0,
30
+ ) -> None:
31
+ """Initialize a UserDefined constitutive law.
32
+
33
+ Arguments:
34
+ x (ArrayLike): Data for strains.
35
+ y (ArrayLike): Data for stresses. Must be of same length as x.
36
+
37
+ Keyword Arguments:
38
+ name (Optional, str): A name for the constitutive law.
39
+ flag (Optional): A flag specifying the behavior after the last
40
+ point. Admissible values: 0 (default): stress drops to zero
41
+ after ultimate strain, 1: stress is mantained constant, 2:
42
+ last tangent is used, 3: last secant is used.
43
+ """
44
+ name = name if name is not None else 'UserDefinedLaw'
45
+ super().__init__(name=name)
46
+ x = np.atleast_1d(np.asarray(x))
47
+ y = np.atleast_1d(np.asarray(y))
48
+ if len(x) != len(y):
49
+ raise ValueError('The two arrays should have the same length')
50
+ if not np.any(x < 0):
51
+ # User provided only positive part, reflect in negative
52
+ self._x = np.concatenate((-np.flip(x)[:-1], x))
53
+ self._y = np.concatenate((-np.flip(y)[:-1], y))
54
+ else:
55
+ # User gave both positive and negative parts
56
+ self._x = x
57
+ self._y = y
58
+ # Define what happens after last strain
59
+ if flag not in (0, 1, 2, 3):
60
+ raise ValueError('Flag can assume values 0, 1, 2 or 3.')
61
+ self._ultimate_strain_p = self._x[-1]
62
+ self._ultimate_strain_n = self._x[0]
63
+ if flag in (1, 2, 3):
64
+ x = np.insert(self._x, 0, self._x[0] * 100)
65
+ x = np.append(x, self._x[-1] * 100)
66
+ if flag == 1:
67
+ y = np.insert(self._y, 0, self._y[0])
68
+ y = np.append(y, self._y[-1])
69
+ elif flag == 2:
70
+ tangent_p = (self._y[-1] - self._y[-2]) / (
71
+ self._x[-1] - self._x[-2]
72
+ )
73
+ tangent_n = (self._y[1] - self._y[0]) / (
74
+ self._x[1] - self._x[0]
75
+ )
76
+ y = np.insert(
77
+ self._y, 0, (x[0] - x[1]) * tangent_n + self._y[0]
78
+ )
79
+ y = np.append(y, (x[-1] - x[-2]) * tangent_p + self._y[-1])
80
+ elif flag == 3:
81
+ secant_p = self._y[-1] / self._x[-1]
82
+ secant_n = self._y[0] / self._x[0]
83
+ y = np.insert(
84
+ self._y, 0, (x[0] - x[1]) * secant_n + self._y[0]
85
+ )
86
+ y = np.append(y, (x[-1] - x[-2]) * secant_p + self._y[-1])
87
+ self._x = x
88
+ self._y = y
89
+
90
+ # Compute slope of each segment
91
+ self._slopes = np.diff(self._y) / np.diff(self._x)
92
+
93
+ def get_stress(
94
+ self, eps: t.Union[float, ArrayLike]
95
+ ) -> t.Union[float, ArrayLike]:
96
+ """Return the stress given strain."""
97
+ eps = eps if np.isscalar(eps) else np.atleast_1d(eps)
98
+ # Preprocess eps array in order
99
+ eps = self.preprocess_strains_with_limits(eps=eps)
100
+ # Compute stress
101
+ return np.interp(eps, self._x, self._y, left=0, right=0)
102
+
103
+ def get_tangent(
104
+ self, eps: t.Union[float, ArrayLike]
105
+ ) -> t.Union[float, ArrayLike]:
106
+ """Return the tangent given strain."""
107
+ eps = eps if np.isscalar(eps) else np.atleast_1d(eps)
108
+
109
+ # Find the segment index for each x value
110
+ indices = np.searchsorted(self._x, eps) - 1
111
+
112
+ # Check that indices are within vlaid range
113
+ indices = np.clip(indices, 0, len(self._slopes) - 1)
114
+
115
+ # Get the corresponding slopes
116
+ tangent = self._slopes[indices]
117
+
118
+ # Elsewhere tangent is zero
119
+ if np.isscalar(eps):
120
+ if eps < self._x[0] or eps > self._x[-1]:
121
+ tangent = 0
122
+ else:
123
+ tangent[eps < self._x[0]] = 0.0
124
+ tangent[eps > self._x[-1]] = 0.0
125
+
126
+ return tangent
127
+
128
+ def __marin__(
129
+ self, strain: t.Tuple[float, float]
130
+ ) -> t.Tuple[t.List[t.Tuple], t.List[t.Tuple]]:
131
+ """Returns coefficients and strain limits for Marin integration in a
132
+ simply formatted way.
133
+
134
+ Arguments:
135
+ strain (float, float): Tuple defining the strain profile: eps =
136
+ strain[0] + strain[1]*y.
137
+
138
+ Example:
139
+ [(0, -0.002), (-0.002, -0.003)]
140
+ [(a0, a1, a2), (a0)]
141
+ """
142
+ strains = []
143
+ coeff = []
144
+ if strain[1] == 0:
145
+ # Uniform strain equal to strain[0]
146
+ # understand in which branch are we
147
+ strain[0] = self.preprocess_strains_with_limits(strain[0])
148
+ found = False
149
+ for i in range(len(self._x) - 1):
150
+ if self._x[i] <= strain[0] and self._x[i + 1] >= strain[0]:
151
+ strains = None
152
+ stiffness = (self._y[i + 1] - self._y[i]) / (
153
+ self._x[i + 1] - self._x[i]
154
+ )
155
+ a0 = stiffness * (strain[0] - self._x[i]) + self._y[i]
156
+ a1 = stiffness * strain[1]
157
+ coeff.append((a0, a1))
158
+ found = True
159
+ break
160
+ if not found:
161
+ strains = None
162
+ coeff.append((0.0,))
163
+ else:
164
+ for i in range(len(self._x) - 1):
165
+ # For each branch of the linear piecewise function
166
+ stiffness = (self._y[i + 1] - self._y[i]) / (
167
+ self._x[i + 1] - self._x[i]
168
+ )
169
+ strains.append((self._x[i], self._x[i + 1]))
170
+ a0 = stiffness * (strain[0] - self._x[i]) + self._y[i]
171
+ a1 = stiffness * strain[1]
172
+ coeff.append((a0, a1))
173
+
174
+ return strains, coeff
175
+
176
+ def get_ultimate_strain(self, **kwargs) -> t.Tuple[float, float]:
177
+ """Return the ultimate strain (negative and positive)."""
178
+ del kwargs
179
+ return (self._ultimate_strain_n, self._ultimate_strain_p)
180
+
181
+ def set_ultimate_strain(
182
+ self, eps_su=t.Union[float, t.Tuple[float, float]]
183
+ ) -> None:
184
+ """Set ultimate strains for Elastic Material if needed.
185
+
186
+ Arguments:
187
+ eps_su (float or (float, float)): Defining ultimate strain. If a
188
+ single value is provided the same is adopted for both negative
189
+ and positive strains. If a tuple is provided, it should be
190
+ given as (negative, positive).
191
+ """
192
+ if isinstance(eps_su, float):
193
+ self._ultimate_strain_p = abs(eps_su)
194
+ self._ultimate_strain_n = -abs(eps_su)
195
+ elif isinstance(eps_su, tuple):
196
+ if len(eps_su) < 2:
197
+ raise ValueError(
198
+ 'Two values need to be provided when setting the tuple'
199
+ )
200
+ eps_su_n = eps_su[0]
201
+ eps_su_p = eps_su[1]
202
+ if eps_su_p < eps_su_n:
203
+ eps_su_p, eps_su_n = eps_su_n, eps_su_p
204
+ if eps_su_p < 0:
205
+ raise ValueError(
206
+ 'Positive ultimate strain should be non-negative'
207
+ )
208
+ if eps_su_n > 0:
209
+ raise ValueError(
210
+ 'Negative utimate strain should be non-positive'
211
+ )
212
+ self._ultimate_strain_p = eps_su_p
213
+ self._ultimate_strain_n = eps_su_n
214
+ else:
215
+ raise ValueError(
216
+ 'set_ultimate_strain requires a single value or a tuple \
217
+ with two values'
218
+ )
@@ -55,6 +55,16 @@ class GenericSection(Section):
55
55
  of the section.
56
56
  name (str): The name of the section.
57
57
  integrator (str): The name of the SectionIntegrator to use.
58
+ kwargs (dict): A collection of keyword arguments to pass on to the
59
+ section calculator.
60
+
61
+ Note:
62
+ The GenericSection uses a GenericSectionCalculator for all
63
+ calculations. The GenericSectionCalculator uses a SectionIntegrator
64
+ for integrating over the section. Any additional keyword arguments
65
+ used when creating the GenericSection are passed on to the
66
+ SectionCalculator to customize the behaviour. See
67
+ GenericSectionCalculator for available keyword arguments.
58
68
  """
59
69
  if name is None:
60
70
  name = 'GenericSection'
@@ -98,7 +108,7 @@ class GenericSectionCalculator(SectionCalculator):
98
108
  (default = 'marin').
99
109
 
100
110
  Note:
101
- When using 'fiber' integrator the kwarg 'mesh_size' can be used to
111
+ When using `fiber` integrator the kwarg `mesh_size` can be used to
102
112
  specify a dimensionless number (between 0 and 1) specifying the
103
113
  size of the resulting mesh.
104
114
  """
@@ -142,13 +152,13 @@ class GenericSectionCalculator(SectionCalculator):
142
152
  # Computation of surface area, reinforcement area, EA (axial rigidity)
143
153
  # and mass: Morten -> problem with units! how do we deal with it?
144
154
  for geo in self.section.geometry.geometries:
145
- gp.ea += geo.area * geo.material.get_tangent(eps=0)[0]
155
+ gp.ea += geo.area * geo.material.get_tangent(eps=0)
146
156
  if geo.density is not None:
147
157
  # this assumes area in mm2 and density in kg/m3
148
158
  gp.mass += geo.area * geo.density * 1e-9
149
159
 
150
160
  for geo in self.section.geometry.point_geometries:
151
- gp.ea += geo.area * geo.material.get_tangent(eps=0)[0]
161
+ gp.ea += geo.area * geo.material.get_tangent(eps=0)
152
162
  gp.area_reinforcement += geo.area
153
163
  if geo.density is not None:
154
164
  # this assumes area in mm2 and density in kg/m3
@@ -103,9 +103,7 @@ class FiberIntegrator(SectionIntegrator):
103
103
  # define the maximum area of the triangles
104
104
  max_area = g.area * mesh_size
105
105
  # triangulate the geometry getting back the mesh
106
- mesh = triangle.triangulate(
107
- tri, f'pq{30:.1f}Aa{max_area:.1f}o1'
108
- )
106
+ mesh = triangle.triangulate(tri, f'pq{30:.1f}Aa{max_area}o1')
109
107
  mat = g.material
110
108
  # Get x and y coordinates (centroid) and area for each fiber
111
109
  x = []
@@ -143,7 +143,7 @@ class MarinIntegrator(SectionIntegrator):
143
143
  strain = strain_rotated[0] + strain_rotated[1] * yp
144
144
  x.append(xp)
145
145
  y.append(yp)
146
- F.append(pg.material.get_stress(strain)[0] * A)
146
+ F.append(pg.material.get_stress(strain) * A)
147
147
  prepared_input.append((1, np.array(x), np.array(y), np.array(F)))
148
148
 
149
149
  return angle, prepared_input
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: structuralcodes
3
- Version: 0.1.1
3
+ Version: 0.2.0
4
4
  Summary: A Python package that contains models from structural design codes.
5
5
  Author-email: fib - International Federation for Structural Concrete <info@fib-international.org>
6
6
  Requires-Python: >=3.8
@@ -1,10 +1,10 @@
1
- structuralcodes/__init__.py,sha256=4WhcwbLVv6pNyZiQjaNHUXYs0YzQTVU0kkM9EMA9ZyE,390
1
+ structuralcodes/__init__.py,sha256=pxmTgFCzRRSx9OPXM_I5KbP045gFiNqoR_v6N1Ni7as,390
2
2
  structuralcodes/codes/__init__.py,sha256=g5xMAJ3jEZHFd0cypvZY6lMCi7XeVEntsO8zHzI2mWc,2803
3
- structuralcodes/codes/ec2_2004/__init__.py,sha256=_PdL9kX7qlfn9VBfqUCJQy6V9fWmIyugzIiSZczjNAA,1986
3
+ structuralcodes/codes/ec2_2004/__init__.py,sha256=DljXFNrCGE1lZIOsgyZgJ7Xo-xUidJomDrDKyfOHcH8,2431
4
+ structuralcodes/codes/ec2_2004/_concrete_creep_and_shrinkage.py,sha256=y4HhOpaXwNMCHh4wu4LSn14oD1ylpPNvVJOJXLxStzQ,15284
4
5
  structuralcodes/codes/ec2_2004/_concrete_material_properties.py,sha256=Ol51tzcVOHUvc2Vea24WQJ4FABxXc-9cB5RVu2N1pio,5964
5
6
  structuralcodes/codes/ec2_2004/_reinforcement_material_properties.py,sha256=_ZlvdHcOswu1Ge1XjSvt4j5ue-znDceMOlA0s528IqM,2779
6
7
  structuralcodes/codes/ec2_2004/_section_7_3_crack_control.py,sha256=a91tWQKNTxB2SpSKu0Wtm-P5GdmifRLggNlEHIQ3XMY,31981
7
- structuralcodes/codes/ec2_2004/annex_b_shrink_and_creep.py,sha256=kaMXZ_Ufp-k1wYQDXB27Tt2BUmi_lGYYuNzQxGtC6SQ,7348
8
8
  structuralcodes/codes/ec2_2004/shear.py,sha256=gzhgIa-EgoD9gLO_Hfa8VeCmjAxuPK0wZ0soDKC7W5w,17095
9
9
  structuralcodes/codes/ec2_2023/__init__.py,sha256=UohRxikCUqPAUpHj4uSWHw5drICjZm3zvJJw7clljo0,1618
10
10
  structuralcodes/codes/ec2_2023/_annexB_time_dependent.py,sha256=ykRAHBHzqtMSErkVA-rwTHBdUq8-L7q2AOaEd2YW5wc,472
@@ -21,31 +21,38 @@ structuralcodes/codes/mc2010/_reinforcement_material_properties.py,sha256=FELmgM
21
21
  structuralcodes/codes/mc2020/__init__.py,sha256=5hrAfBtAeG69N_lroFpG10_ZKB1SuNlKBnuHug2DI3E,174
22
22
  structuralcodes/core/__init__.py,sha256=spnvZIm_w3jX_lV-v3bloDjgHh8lrH6UHpA1Nv1zeAI,55
23
23
  structuralcodes/core/_section_results.py,sha256=hHXoS71TpSmWqw276pBeLiLrEEiMEWclOd28ArRW_Kk,8280
24
- structuralcodes/core/base.py,sha256=TqgsXzIXITQmER3tKNjzjPrbSN5uT_PqCpG3PVMd3Yw,8562
24
+ structuralcodes/core/base.py,sha256=7cpDM2hvBZp9nyU714XRiMzDPNdydJqLtIHHvcXZctE,8935
25
25
  structuralcodes/geometry/__init__.py,sha256=FwzywfyGKOk6v96ZyOfyBo5iVeuK_W0TQVz5llAkYW4,559
26
- structuralcodes/geometry/_geometry.py,sha256=kmY7TER5yS-TVw0XY4EuwNviLuEhExtLoon8oO2TJbA,31175
26
+ structuralcodes/geometry/_geometry.py,sha256=8usT5UfDlT-A8sMwM6Bh4YKIB9QuyAU5tGgsujeACEA,31240
27
27
  structuralcodes/geometry/_reinforcement.py,sha256=N2wTH-NoZ1fG-_vRT9gGX2Kk3zlW7CbDtl1oqS_lMv0,4144
28
28
  structuralcodes/geometry/_steel_sections.py,sha256=UdJmhhnK8r5gEfBzvWsMFHGs5gmuoOhFoduBanlRMQg,60225
29
29
  structuralcodes/materials/__init__.py,sha256=r5E5vsXVKB-BGZXTnEbsrYJbH6rr6Xlc_b4LlcUPIbc,173
30
- structuralcodes/materials/constitutive_laws.py,sha256=DX_yuC4OpgDCl_g3sl0Hi2ee7lFD2fy3yO4PTINKBzE,34455
31
30
  structuralcodes/materials/concrete/__init__.py,sha256=GRD5WcbYrnE4iN-L7qVkhVTi7w_PUP7pnbGueOaVeFs,2576
32
31
  structuralcodes/materials/concrete/_concrete.py,sha256=3zMTFtaqFeUl7ne7-pe9wF4LryzqvGpUwThnHTidCZU,3774
33
32
  structuralcodes/materials/concrete/_concreteEC2_2004.py,sha256=gWG3O9yeGw3UeftCjYTajZco_XYDmBxPGqhAEpH3nY0,14666
34
33
  structuralcodes/materials/concrete/_concreteEC2_2023.py,sha256=vguNzlfoPuaieTVw9T3xWU0wb230WvER4Vy1jswcdlo,14017
35
34
  structuralcodes/materials/concrete/_concreteMC2010.py,sha256=lHy-WYiVpXPwiNAyjUBxuGWuGFd0-Uirh6KiolMH4MY,15313
35
+ structuralcodes/materials/constitutive_laws/__init__.py,sha256=r817qyeimqZyyan2mU8cVwjwMkiB--f-BOIBSzXKiZo,2954
36
+ structuralcodes/materials/constitutive_laws/_bilinearcompression.py,sha256=mkuMSiKpfZv-meIvHedrlILfRBdOsR46QCiaiyxPxVs,4528
37
+ structuralcodes/materials/constitutive_laws/_elastic.py,sha256=Kl-A_3W2qoJUEPE3meWABSqUlNChMExiq2LdRehbqrI,3722
38
+ structuralcodes/materials/constitutive_laws/_elasticplastic.py,sha256=GDIIXJ93nqV-G8-o6HxXGUTd3TgNWiHQqXbULFcCGUI,6096
39
+ structuralcodes/materials/constitutive_laws/_parabolarectangle.py,sha256=CvjmiGCmNTqxY6d5jNqCo6MAh_BUkypvv_-ZJB9JyQE,6489
40
+ structuralcodes/materials/constitutive_laws/_popovics.py,sha256=dpXFQ9KHE245C9dgOLz9KXYHZiAYrRan5exgj0j_JxM,4322
41
+ structuralcodes/materials/constitutive_laws/_sargin.py,sha256=WJGw0EtqkPh-d3N6vTPRIfhE1Ypyc16JpGcoi-0U1A8,3495
42
+ structuralcodes/materials/constitutive_laws/_userdefined.py,sha256=urt0yuJicO51jnQ2S8bfmrgVTyYh09Olnzy9_tISGK4,8292
36
43
  structuralcodes/materials/reinforcement/__init__.py,sha256=-UA04GSNN6_xLKqnH_5taiOmgxYwD_wtT6Nw8UbfkJY,2757
37
44
  structuralcodes/materials/reinforcement/_reinforcement.py,sha256=zrSdBvHKTYqOHpkJzxit8w_b2JG2pggviOvgZyH246Q,5029
38
45
  structuralcodes/materials/reinforcement/_reinforcementEC2_2004.py,sha256=svLpubjaTH_DepwY68TQIA8fRwadoAE3Y3KsyViGQHk,3265
39
46
  structuralcodes/materials/reinforcement/_reinforcementEC2_2023.py,sha256=3tKpFcMNYK52s5K2K_PctRcuSgwZTe-QXX3xziHPUno,2887
40
47
  structuralcodes/materials/reinforcement/_reinforcementMC2010.py,sha256=az_IAQJNKSF6Vv9KMoXjWTdYkWI6xcEm7s8i8GETn3A,2939
41
48
  structuralcodes/sections/__init__.py,sha256=qPoD5eS31at-uveYtxtVkXGLNHPrIMRrxGYY3wOLQ4s,441
42
- structuralcodes/sections/_generic.py,sha256=jpubO8wBsVWJajpOkUYzBpunf4ltse8rmiNFyiwDuoI,49968
49
+ structuralcodes/sections/_generic.py,sha256=I_YQNeK9ww3wDtkSBlhF7u6gXVAj2I5Sttv9i-uk8UI,50525
43
50
  structuralcodes/sections/section_integrators/__init__.py,sha256=PK4ixV0XrfHXN-itIrB1r90npoWo3aIJqMcenqcaees,399
44
51
  structuralcodes/sections/section_integrators/_factory.py,sha256=MHp14hfWU-oXTiIutCKLJEC47LirYsHgEAAmHVtnFMY,1242
45
- structuralcodes/sections/section_integrators/_fiber_integrator.py,sha256=5sxcfbmxMJfy45Pfd84I4sAh6HpPc5B4r6ab0WpjSNI,9305
52
+ structuralcodes/sections/section_integrators/_fiber_integrator.py,sha256=Ucas8nA9BB4ILfFPplJp3WkgLc9ntf9UN7AmcUwqA_A,9263
46
53
  structuralcodes/sections/section_integrators/_marin_integration.py,sha256=SZgya6d_Tequ3jez7UEBlYioZepW2IDKaAxn_6WrMbU,1563
47
- structuralcodes/sections/section_integrators/_marin_integrator.py,sha256=rtEtd1X0QYAWNcaH7Pjd_b6LEzVjHqD_fbIrX64p7fg,9121
54
+ structuralcodes/sections/section_integrators/_marin_integrator.py,sha256=DHAJwurHhVp68K9fozw0MbmxZvk_NAKnNVi5abp65sY,9118
48
55
  structuralcodes/sections/section_integrators/_section_integrator.py,sha256=O-jsG1Pu_doovgRJsFG1Sf0KlkN2wNfQdmgkJiSHNN0,1590
49
- structuralcodes-0.1.1.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
50
- structuralcodes-0.1.1.dist-info/METADATA,sha256=CDs31oS5sYYBt1hk-gRLTGPJtfa6SiM1H5QP3IlGecI,2444
51
- structuralcodes-0.1.1.dist-info/RECORD,,
56
+ structuralcodes-0.2.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
57
+ structuralcodes-0.2.0.dist-info/METADATA,sha256=7RAyKNKlQYjXC3sFiVRWTwp3HUMAhN5SvJAvcF2LTZ0,2444
58
+ structuralcodes-0.2.0.dist-info/RECORD,,