Skip to content

feat: Add elastic fragile tension constitutive law for concrete - #376

Open
Pier53 wants to merge 5 commits into
fib-international:devfrom
Pier53:add-ElasticFragileTension-constitutive-law
Open

Pier53 wants to merge 5 commits into
fib-international:devfrom
Pier53:add-ElasticFragileTension-constitutive-law

Conversation

@Pier53

@Pier53 Pier53 commented Sep 18, 2026 •

Copy link
Copy Markdown

Hello everyone,

Please be lenient, as this is my first real public pull request. I hope I haven't made a mistake! :-)

I've started to implement ElasticFragileTension.

  • Add a basic class ElasticFragileTension(ConstitutiveLaw)
  • .get_ultimate_strain() (chapter bellow)
  • Add marin() method
  • Add marin_tangent() method
  • Add tests
  • Other ?

.get_ultimate_strain()

I had a trouble with .get_ultimate_strain() with the Parallel class because compression law returned epsillon_tension_max = 100 instead of 0.00.

compression = ParabolaRectangle(fc=45)      # ou Sargin, Popovics...
tension = ElasticFragileTension(fct=2.7, Ec=36000)
compression_tension = Parallel(constitutive_laws=[compression, tension])

compression_tension.get_ultimate_strain()

return :
[
-0.0035,
100
]

So the ultimate strains of the compression_tension made with Parallel class was wrong.

__ compression tension compression_tension
classe ParabolaRectangle ElasticFragileTension Parallel
negative -3.500 ‰ 0.000 ‰ -3.500 ‰
positive 100000.000 ‰ 0.075 ‰ 100000.000 ‰

Maybe you've already talk about it in past ?
I've thinked of different solutions.

  1. Replacing by None --> Wrong because we are going to insert None instead of float, and it's not clear to understand what it's mean to have a None Ultimate Strain...
  2. Replacing by 0.00 --> Wrong idea (break constitutive laws when they are alone)
  3. Replacing 100.0 by np.inf (or -np.inf)
  4. Replacing by NaN --> It's like np.inf

So I've made a try with np.inf !

#--- Compression law ---
def get_ultimate_strain(self, **kwargs) -> t.Tuple[float, float]:
    """Return the ultimate strain (negative and positive).
    """
    del kwargs
    return (self._eps_cu, math.inf)


#--- Parallel law ---
def get_ultimate_strain(self, yielding: bool = False) -> t.Tuple[float, float]:
    """Return the ultimate strain (negative and positive)."""
    neg = [law.get_ultimate_strain(yielding=yielding)[0] for law in self._wrapped_laws]
    pos = [law.get_ultimate_strain(yielding=yielding)[1] for law in self._wrapped_laws]

    finite_neg = [v for v in neg if np.isfinite(v)]
    finite_pos = [v for v in pos if np.isfinite(v)]

    eps_n = min(finite_neg) if finite_neg else -np.inf
    eps_p = max(finite_pos) if finite_pos else np.inf
    return (eps_n, eps_p)

With this, i got good results :

__ compression tension compression_tension
classe ParabolaRectangle ElasticFragileTension Parallel
negative -3.500 ‰ -inf ‰ -3.500 ‰
positive inf ‰ 0.075 ‰ 0.075 ‰

But this was introducing some trouble in BeamSectionCalculator so i introduce a "bracket" with a large strain of 1.0.

My test file : 2026_09_18_bending_strength_concrete_only.py

Marin

I add a minimum for eps to avoid to get an np.inf value in the discretize_law

eps_min, eps_max = self.get_ultimate_strain()
eps_min = max(eps_min, -1)
eps_max = min(eps_max, 1)

-> Do i need to add a specific marin method for ElasticFragileTension ?

Tests

All test passed.

Roadmap

  • Waiting your review and applying it
  • Add tests
  • Next ?

I reallyenjoy doing this, but I'm not used to work on project on Github, so I need your advises ! 👍

@Pier53
Pier53 marked this pull request as draft September 18, 2026 16:53
@Pier53
Pier53 marked this pull request as ready for review September 18, 2026 17:53
@mortenengen mortenengen added enhancement New feature or request constitutive laws labels Sep 18, 2026
@mortenengen mortenengen moved this to New ✨ in PR tracker Sep 18, 2026
@mortenengen
mortenengen changed the base branch from main to dev September 18, 2026 19:00
@mortenengen mortenengen moved this from New ✨ to Under review 👀 in PR tracker Sep 18, 2026
@mortenengen

Copy link
Copy Markdown
Member

Thanks for this contribution, @Pier53! I am sorry that you had to run into that issue with the strain limits. Indeed, I remember @talledodiego and I discussed what to do with the limits, and we decided to keep it like this awaiting a tensile law 😃 Thanks for elaborating on this in the message above.

Anyway, I will have a closer look after the weekend, and @talledodiego will have a look at your solution for the strain limit issue.

If possible, please go ahead implementing the __marin__ and the __marin_tangent__ methods for completeness.

@mortenengen mortenengen changed the title Add elastic fragile tension constitutive law for concrete feat: Add elastic fragile tension constitutive law for concrete Sep 18, 2026
Comment thread structuralcodes/core/base/_constitutive_law.py

@mortenengen mortenengen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this nice contribution, @Pier53! I think the use of np.inf is a clever solution. I only have one comment which I would appreciate if you could fix in order to trigger the pipelines. Final approval awaits the outcome of the pipelines, i.e. whether they pass or not, and the review from @talledodiego.

@Pier53

Pier53 commented Sep 22, 2026

Copy link
Copy Markdown
Author

I think I made a mistake with the get_ultimate_strain method. Because my result with and without rebar are inconsistent/wrong. Please wait a bit before the review because I'm going to fix it soon.
But I'm not totally available this week. Thanks

I'm also going to fix this noqa bug.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

constitutive laws enhancement New feature or request

Projects

Status: Under review 👀

Development

Successfully merging this pull request may close these issues.

Proposal: a parabola-rectangle and sargin constitutive law with a tensile branch

2 participants