feat: add ACI 318-19 concrete and reinforcement material properties#343
feat: add ACI 318-19 concrete and reinforcement material properties#343gabe-kafka wants to merge 1 commit into
Conversation
b91e308 to
f4d0636
Compare
Add the first American design code to the library. Implements material properties from ACI 318-19 Chapters 19, 20, and 22: Concrete (codes/aci318): - Ec: modulus of elasticity (Table 19.2.2.1) - fr: modulus of rupture (Eq. 19.2.3.1) - beta1: Whitney stress block depth factor (Table 22.2.2.4.3) - eps_cu: ultimate concrete strain (Section 22.2.2.1) - alpha1: stress block intensity (Section 22.2.2.4.1) - fct: splitting tensile strength (Section 19.2.4.3) - lambda_factor: lightweight modification factor (Table 19.2.4.2) Reinforcement (codes/aci318): - Es: modulus of elasticity (Section 20.2.2.2) - fy_design: design yield strength - epsyd: yield strain - reinforcement_grade_props: ASTM grade lookup (Table 20.2.2.4a) Material classes: - ConcreteACI318 with elastic, parabola-rectangle, and bilinear constitutive laws - ReinforcementACI318 with elastic and elastic-plastic laws ACI 318 uses LRFD (strength reduction factors on member capacity) rather than partial safety factors on material strength. Material classes default gamma_c=1.0 and gamma_s=1.0 accordingly. Ref: fib-international#187
f4d0636 to
a9987bf
Compare
| import typing as t | ||
|
|
||
| from . import ec2_2004, ec2_2023, mc2010, mc2020 | ||
| from . import aci318, ec2_2004, ec2_2023, mc2010, mc2020 |
There was a problem hiding this comment.
Minor comment about the naming.
For Eurocode 2 we decided to implement different generations in different modules, e.g. ec2_2004 for the first generation that was released in 2004, and ec2_2023 for the second generation that was released in 2023. The second generation is expected to become accepted as national governing design code around Europe some time in the period 2027-2028.
Please correct me if I am wrong here, but my impression is that the 19 in ACI318-19 indicates that it was released in 2019. Similarly, a slightly newer version was released in 2025 and named ACI318-25. If this is right, please consider indicating this in the name of the module, e.g. aci318_19 instead of just aci318.
There was a problem hiding this comment.
Morten, I agree with your comment. We need to keep different versions separate. When there is no change we can use the method of the previous version, but we may need to update the references and son on. So, yes it should be aci318-19
| from ._concrete import Concrete | ||
|
|
||
|
|
||
| class ConcreteACI318(Concrete): # noqa: N801 |
There was a problem hiding this comment.
Same minor comment as above, please consider renaming the class to ConcreteACI318_19.
| from ._reinforcement import Reinforcement | ||
|
|
||
|
|
||
| class ReinforcementACI318(Reinforcement): # noqa: N801 |
There was a problem hiding this comment.
Same minor comment as above, please consider renaming the class to ReinforcementACI318_19.
| self._fct = abs(fct) if fct is not None else None | ||
| self._wc = wc | ||
| self._lambda_s = lambda_s | ||
|
|
There was a problem hiding this comment.
In the other concrete classes we have implemented a .__post_init__ method which is responsible for validating the parameters that are set. See for example here. Please consider implementing a similar method here.
| """ | ||
| return { | ||
| 'fc': self.fcd(), | ||
| 'eps_0': 0.002, |
There was a problem hiding this comment.
Is there a clause in the code that sets the value eps_0 = 0.002? If it is, please consider implementing a function in the code module similar as for eps_cu. Furthermore, the value of eps_0 should preferably be taken from a property on this concrete class such that it is more transparent for the user what is routed to the constitutive laws. Please consider implementing this property, possibly calling the function for eps_0 in the code module.
| """ | ||
| return { | ||
| 'fc': self.fcd(), | ||
| 'eps_c': 0.002, |
There was a problem hiding this comment.
Same as for the comment related to eps_0 above.
| return fy / _Es | ||
|
|
||
|
|
||
| def reinforcement_grade_props( |
There was a problem hiding this comment.
Does ACI 318-19 also provide values for the strain at ultimate strength? If so, please consider including it in the return dictionary.
mortenengen
left a comment
There was a problem hiding this comment.
Thanks for this very nice contribution @gabe-kafka. I have left a couple of comments for you to consider while finalizing the PR. Please note that @talledodiego and @aperezcaldentey have also agreed to provide their reviews.
|
@gabe-kafka, in the above message you provided the following comment:
However, I have not experienced any pre-existing failues in the pipeline. Please elaborate so that we can triage this. |
|
|
||
| def fct(fc: float, lambda_s: float = 1.0) -> float: | ||
| """The approximate splitting tensile strength of concrete. | ||
|
|
There was a problem hiding this comment.
The formula used in this method does not correspond to ACI 318-19, Section 19.2.4.3, as stated. We should possibly delete this method as fct is not defined in ACI 318-19.
| @@ -0,0 +1,164 @@ | |||
| """Concrete material properties according to ACI 318-19.""" | |||
|
|
|||
There was a problem hiding this comment.
I suggest we order the methods as they appear in the code. Let's not jump from Chaper 19 to 22 and then back to 19.
| if fc >= 55: | ||
| return 0.65 | ||
| return 0.85 - 0.05 * (fc - 28) / 7 | ||
|
|
There was a problem hiding this comment.
Replace expression: 0.85 - 0.05 * (fc - 28) / 7 by 0.85-0.20/27*(fc-28) - why simplify and lose accuracy? I could drive some people crazy...
|
|
||
| Raises: | ||
| ValueError: If fc is not positive. | ||
| """ |
There was a problem hiding this comment.
According to Table 22.2.2.4.3. f'c must be greater that 17. We should set this as a lower limit. Not 0.
|
|
||
| def Ec(fc: float, wc: float = 2320.0) -> float: | ||
| """The modulus of elasticity of concrete. | ||
|
|
There was a problem hiding this comment.
Default value of concrete. The typical specific weight of concrete used in North American practice is 150 lbs/cf, which I roughly equivalent to a density of 150/(2.2*0.3048^3)≈2400 kg/m3. I understand this my have to do with going from specific weight to density using g=9.81 m/s2, but it is not clear for me how you derive it, as the units are not consistent. On the other hand, Eq. 19.2.2.1b provides a factor of 4700 which would lead to a value of w=2286 kg/m3.
| 'sand-lightweight': 0.85, | ||
| 'all-lightweight': 0.75, | ||
| } | ||
|
|
There was a problem hiding this comment.
The lambda factor in ACI-318-19 is a function of the weight and lies between 1.00 and 0.75. You provide 'sand-lightweight as an intermediate value. Consider programing the equation as a function of the weight (as done for the modulus of elasticity) or adding the values from Table 19.2.4.1 'lightweight, fine blend' and 'sand-lightweight, corase blend'
| alpha1, | ||
| beta1, | ||
| eps_cu, | ||
| fct, |
There was a problem hiding this comment.
fct not defined in ACI 318-19
| '80': {'fy': 550.0, 'fu': 690.0}, | ||
| '100': {'fy': 690.0, 'fu': 860.0}, | ||
| } | ||
|
|
There was a problem hiding this comment.
Values for Reinforcement grades based on table 20.2.1.3(a). Please add this reference to comments.
|
|
||
| def fy_design(fy: float, phi: float = 1.0) -> float: | ||
| """The design yield strength of reinforcement. | ||
|
|
There was a problem hiding this comment.
As you say, ACI does not consider a partial factor on steel. Why do we need to provide one? The user should not be able to introduce a value different that 1.00. If we need this method for compatibility reasons we shoudl delete phi as a KWARG.
| characteristic strength (fck). The parameter is named fck for | ||
| compatibility with the base class, but represents fc' in ACI | ||
| notation. An fc property is provided as an alias. | ||
|
|
There was a problem hiding this comment.
Note that fck is a 95% fractile, while f'c is a 90% fractile
| gamma_c defaults to 1.0 and should be left at 1.0 for | ||
| standard ACI 318 design. Reducing fc' via gamma_c is not | ||
| ACI 318 compliant. | ||
|
|
There was a problem hiding this comment.
I agree, so don't give the user the possibility of doing otherwise.
| (default: 2320). | ||
| gamma_c (float, optional): Partial factor for concrete. | ||
| Default is 1.0 (ACI does not use material partial | ||
| factors). |
There was a problem hiding this comment.
So we should not give the user this possibility. Delete parameter or do we need it for compatibility reasons? If so we should somehow force the user to input a value of 1.0.
| Ec (float, optional): The modulus of elasticity in MPa. | ||
| fr (float, optional): The modulus of rupture in MPa. | ||
| fct (float, optional): The splitting tensile strength | ||
| in MPa. |
There was a problem hiding this comment.
As commented above fct is not defined in ACI 318-19. We should not use it.
| fct (float, optional): The splitting tensile strength | ||
| in MPa. | ||
| wc (float): Unit weight of concrete in kg/m3 | ||
| (default: 2320). |
There was a problem hiding this comment.
Justify default value.
| Default is 1.0 for ACI 318 (no material partial | ||
| factor). | ||
| """ | ||
| return self._gamma_s or 1.0 |
There was a problem hiding this comment.
As commented on before for ACI we should set all material partial factors to 1.00 and not allow the user to change them. I don't think any good will come from this freedom.
Summary
Adds the first American design code to the library — ACI 318-19 material properties from Chapters 19, 20, and 22.
Ec,fr,beta1,eps_cu,alpha1,fct,lambda_factor— all as standalone functions following the existing EC2/MC2010 patternsEs,fy_design,epsyd,reinforcement_grade_props(ASTM grade lookup)ConcreteACI318andReinforcementACI318with constitutive law support (elastic, parabola-rectangle, bilinear for concrete; elastic, elastic-plastic for steel)All units are SI (MPa, kg/m³) to match library conventions.
ACI vs Eurocode safety philosophy
ACI 318 uses LRFD — strength reduction factors (φ) are applied at member capacity level, not material level. The material classes default
gamma_c=1.0andgamma_s=1.0. This is documented in class docstrings. See discussion in #187 about long-term architectural implications.Scope
Material properties only. No member design (shear, flexure, etc.) in this PR — that can follow once the architecture question in #187 is resolved.
Closes #187 (partially — first code added, more can follow).
Test plan
make form— ruff formatting passesmake lint— ruff linting passesmake test— 10,186 passed (73 new + 10,113 existing), 1 pre-existing failure in EC2 2023set_design_code('aci318')→create_concrete(fck=28)→.Ecreturns correct value