Giter Site home page Giter Site logo

robbievanleeuwen / concrete-properties Goto Github PK

View Code? Open in Web Editor NEW
128.0 13.0 34.0 82.96 MB

Calculate section properties for reinforced concrete sections.

Home Page: https://concrete-properties.rtfd.io

License: MIT License

Python 100.00%
concrete finite-element-analysis python reinforced-concrete section-properties structural-engineering computational-mechanics cross-section prestressed-concrete post-tensioned-concrete

concrete-properties's People

Contributors

agent6-6-6 avatar ccaprani avatar darryllshanks avatar dependabot[bot] avatar robbievanleeuwen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

concrete-properties's Issues

Speed up with multiprocessing

Is your feature request related to a problem? Please describe.
Biaxial bending diagrams and to a lesser extent, interaction diagrams, can take a long time to generate. Both of these features involve a number of independent calculations, currently implemented in a for loop.

Describe the solution you'd like
Using the python multiprocessing module would allow these computations to be performed in parallel on multiple cores, vastly speeding up these analyses.

AS3600 assigning ku to zero where no axial load is present

Hi @robbievanleeuwen,
Working through the example in the documentation (https://concrete-properties.readthedocs.io/en/stable/examples/as3600.html) in a JupyterNotebook, I noted that the parameter kuo for a beam in pure bending, is incorrectly exported as 0.0000 with d_n as infinite when calculating the ultimate bending capacity. This is reflected in both my JupyterNotebook and the online documentation.

f_ult_res, ult_res, phi = design_code.ultimate_bending_capacity()
ult_res.print_results()
print(f"kuo = {ult_res.k_u:.4f}")

The bending capacity 'Muo' and factored capacity 'phi.Muo' are still correct. If I set n_star to something small (0.0001), ku is comes out correctly at 0.0898.

Working through the code I believe the error may be in as3600.py line 431, where I suspect it should be "greater than or equal to".

# regular calculation
elif n_design > 0:
    ult_res = self.concrete_section.ultimate_bending_capacity(theta=theta, n=n_design / phi)

Are you able to verify whether my understanding of what the code is doing here would still be valid with this change?

P.S. Note that kuo is correctly calculated using the more general (not code specific) module.

  • concreteproperties version: <0.6.1>

  • Python version: <3.10>

  • OS version and name: <Windows 11 Home 23H2>

  • I am on the latest
    stable concreteproperties version, installed using a recommended method.

  • I have searched the issues
    of this repo and believe that this is not a duplicate.

  • I have consulted the documentation
    for any relevant information.

Plotting stresses fails in some cases

The error is deceptive and just appears as matplotlib errors:

Click to expand
<AxesSubplot:title={'center':'Pure Bending'}>Exception in Tkinter callback
Traceback (most recent call last):
  File "/home/ccaprani/anaconda3/envs/secprop/lib/python3.9/tkinter/__init__.py", line 1892, in __call__
    return self.func(*args)
  File "/home/ccaprani/anaconda3/envs/secprop/lib/python3.9/tkinter/__init__.py", line 814, in callit
    func(*args)
  File "/home/ccaprani/anaconda3/envs/secprop/lib/python3.9/site-packages/matplotlib/backends/_backend_tk.py", line 240, in idle_draw
    self.draw()
  File "/home/ccaprani/anaconda3/envs/secprop/lib/python3.9/site-packages/matplotlib/backends/backend_tkagg.py", line 9, in draw
    super().draw()
  File "/home/ccaprani/anaconda3/envs/secprop/lib/python3.9/site-packages/matplotlib/backends/backend_agg.py", line 406, in draw
    self.figure.draw(self.renderer)
  File "/home/ccaprani/anaconda3/envs/secprop/lib/python3.9/site-packages/matplotlib/artist.py", line 74, in draw_wrapper
    result = draw(artist, renderer, *args, **kwargs)
  File "/home/ccaprani/anaconda3/envs/secprop/lib/python3.9/site-packages/matplotlib/artist.py", line 51, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/home/ccaprani/anaconda3/envs/secprop/lib/python3.9/site-packages/matplotlib/figure.py", line 2790, in draw
    mimage._draw_list_compositing_images(
  File "/home/ccaprani/anaconda3/envs/secprop/lib/python3.9/site-packages/matplotlib/image.py", line 132, in _draw_list_compositing_images
    a.draw(renderer)
  File "/home/ccaprani/anaconda3/envs/secprop/lib/python3.9/site-packages/matplotlib/artist.py", line 51, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/home/ccaprani/anaconda3/envs/secprop/lib/python3.9/site-packages/matplotlib/_api/deprecation.py", line 431, in wrapper
    return func(*inner_args, **inner_kwargs)
  File "/home/ccaprani/anaconda3/envs/secprop/lib/python3.9/site-packages/matplotlib/axes/_base.py", line 2921, in draw
    mimage._draw_list_compositing_images(renderer, self, artists)
  File "/home/ccaprani/anaconda3/envs/secprop/lib/python3.9/site-packages/matplotlib/image.py", line 132, in _draw_list_compositing_images
    a.draw(renderer)
  File "/home/ccaprani/anaconda3/envs/secprop/lib/python3.9/site-packages/matplotlib/artist.py", line 51, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/home/ccaprani/anaconda3/envs/secprop/lib/python3.9/site-packages/matplotlib/collections.py", line 350, in draw
    self.update_scalarmappable()
  File "/home/ccaprani/anaconda3/envs/secprop/lib/python3.9/site-packages/matplotlib/collections.py", line 912, in update_scalarmappable
    if self._A.ndim > 1 and not isinstance(self, QuadMesh):
AttributeError: 'list' object has no attribute 'ndim'

I've tracked it back to this line:

fig.axes[0].add_collection(patch) # type: ignore

Presumably there is something wrong in the way that the lumped reo patches are being created for my structure. Unfortunately I can't share the structure I'm working on, but I'm parking this low-effort issue notice here and will update if I find out more.

Improve adaptive curvature step in moment-curvature analysis

@Agent6-6-6:

I've noticed as well that the way the moment curvature analysis adaptively scales the curvature step it almost always just keeps increasing the curvature in each step. so by the time you get closer to the failure point the answers get very widely spaced.

if moment_diff <= delta_m_min:
                        kappa_inc *= 2
                    elif moment_diff >= delta_m_max:
                        kappa_inc *= 0.5

To demonstrate, first image is replacing 2 with 1.01, and 0.5 with 0.99 to arbitrarily limit to a much smaller step. You can appreciate the differences in the results in the below images for the same section. So by default the answer gets cruder and crude as it proceeds and you start to miss the fundamental behaviour I think. Note the general shape and higher curvature achieved when the steps are smaller.
Figure_1
Figure_2

It feels like the final point should always be undertaken at the failure strain. At the moment the final analysis point returned is only the point evaluated before a moment step goes over the failure strain. Which with a cruder step could be quite a bit lower than the actual true failure strain.

Originally posted by @Agent6-6-6 in #44 (comment)

Random tkinker errors when undertaking a biaxial interaction analysis

Hi @robbievanleeuwen

Not sure if you've come across this, or whether it is even within the control of concrete-properties. But when running a biaxial interaction analyses, you sometimes randomly get these errors note below. It randomly freezes for a while and then throws up these errors, but the analysis always completes:-

Exception ignored in: <function Variable.__del__ at 0x0000021859A91D30>
Traceback (most recent call last):
  File "C:\Users\xxxx\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 363, in __del__
    if self._tk.getboolean(self._tk.call("info", "exists", self._name)):
RuntimeError: main thread is not in main loop
Exception ignored in: <function Variable.__del__ at 0x0000021859A91D30>
Traceback (most recent call last):
  File "C:\Users\xxxx\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 363, in __del__
    if self._tk.getboolean(self._tk.call("info", "exists", self._name)):
RuntimeError: main thread is not in main loop
Exception ignored in: <function Variable.__del__ at 0x0000021859A91D30>
Traceback (most recent call last):
  File "C:\Users\xxxx\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 363, in __del__
    if self._tk.getboolean(self._tk.call("info", "exists", self._name)):
RuntimeError: main thread is not in main loop
Exception ignored in: <function Variable.__del__ at 0x0000021859A91D30>
Traceback (most recent call last):
  File "C:\Users\xxxx\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 363, in __del__
    if self._tk.getboolean(self._tk.call("info", "exists", self._name)):
RuntimeError: main thread is not in main loop
Exception ignored in: <function Image.__del__ at 0x0000021859ACF670>
Traceback (most recent call last):
  File "C:\Users\xxxx\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 4017, in __del__
    self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Exception ignored in: <function Variable.__del__ at 0x0000021859A91D30>
Traceback (most recent call last):
  File "C:\Users\xxxx\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 363, in __del__
    if self._tk.getboolean(self._tk.call("info", "exists", self._name)):
RuntimeError: main thread is not in main loop
Exception ignored in: <function Variable.__del__ at 0x0000021859A91D30>
Traceback (most recent call last):
  File "C:\Users\xxxx\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 363, in __del__
    if self._tk.getboolean(self._tk.call("info", "exists", self._name)):
RuntimeError: main thread is not in main loop
Exception ignored in: <function Variable.__del__ at 0x0000021859A91D30>
Traceback (most recent call last):
  File "C:\Users\xxxx\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 363, in __del__
    if self._tk.getboolean(self._tk.call("info", "exists", self._name)):
  ✅ Biaxial bending diagram generated                                                                                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% [ 7.2030 s ]RuntimeError: main thread is not in main loop
Exception ignored in: <function Variable.__del__ at 0x0000021859A91D30>
Traceback (most recent call last):
  File "C:\Users\xxxx\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 363, in __del__
    if self._tk.getboolean(self._tk.call("info", "exists", self._name)):
RuntimeError: main thread is not in main loop
Exception ignored in: <function Image.__del__ at 0x0000021859ACF670>
Traceback (most recent call last):
  File "C:\Users\xxxx\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 4017, in __del__
    self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
  ✅ Biaxial bending diagram generated                                                                                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% [ 7.2030 s ]

Neutral axis depth range for M-N interaction diagram not accounting for gamma effect for full section depth being in compression

Hi @robbievanleeuwen

When generating the interaction diagrams, I think you should be checking the neutral axis depth is between Zero & the Depth of section divided by the gamma factor. If you want the point where the section has all of the concrete area under full compression then because you're factoring the neutral access depth by gamma (I think in your nomenclature) to work out the depth of the compression block, you need to do this.

For example otherwise as it is currently implemented for a section of say 400mm depth when factored by gamma of 0.85 in the analysis to determine the compression block depth 'a', it will only mean you're capturing analysis points from zero compression block depth to 0.85*400 = 340 compression block depth when you determine the points you're working out the moment capacity for to generate the interaction diagram. So you're missing out on data points where the compression block is between 0.85 and 1.0 times the section depth in this example.

I was trying to work out why your interaction diagrams have a much wider spaced range between the last point before the squash load and the squash load, and believe this is one of the reasons, you're missing a few data points at larger neutral axis depths (how much depends on the value of gamma).

Hopefully that makes sense, if not let me know and I can try explain.

Moment interaction diagrams should terminate at M=0

Actions:

  • Terminate moment interaction diagrams at M=0 so that point_in_diagram() works as intended. Currently for asymmetric diagrams it is possible to have a point reported as outside the diagram when it should strictly be in the diagram (conservative). However, there should currently be no unconservative reporting.
  • Give (bring back) the option of plotting the negative diagram? (may assist with the above)
  • More efficient max_comp computation. We don't need to compute above max_comp.

See discussion here and here.

Originally posted by @Agent6-6-6 in #66 (comment)

Remove alpha_squash from Concrete object

Discussed in #32

Originally posted by Agent6-6-6 August 7, 2022

  • alpha_squash which is stored as part of the concrete material is really more specific only to a AS3600 code implementation of the interaction diagram.

To Do:

  • Remove alpha_squash from Concrete as it is now obsolete
  • Fix AS3600 to use calculated alpha_squash - perhaps implement a ConcreteAS object?

find concrete_section.ultimate_bending_capacity() needs method for max compression load check

Hi @robbievanleeuwen
concrete_section.ultimate_bending_capacity() needs a way of detecting when you analyse a section and enter an axial load that is greater than maximum compression capacity of a cross section. Not having this ability may lead to unconservative results being accepted as being true.

This could be handled within the individual design_code code if easier, by checking the axial load is less than the max compression before calling concrete_section.ultimate_bending_capacity().

But I was thinking you'd be better implementing a max_comp similar to what you did for the generation of an M/N interaction diagram within concrete_section.ultimate_bending_capacity()??

Update to support sectionproperties v3

If there are issues installing concreteproperties in the meantime, consider first installing an earlier version of sectionproperties:

pip install sectionproperties==2.1.5
pip install concreteproperties

Cracking moment calculation does not consider axial load effects.

As per the title, no in-built method exists to calculate cracking moment under the presence of axial tension or compression forces. The assumption of the built-in calculate_cracking_moment() method is N*=0 kN

Under tension or compression, there is a direct tensile stress (and potentially a moment on the assumption of the axial load acting at the geometric centroid if section is non-symmetric) that is required to be combined with the moment component of stress.

Odd moment curvature results....

I don't know if this is a bug or a misunderstanding in what is being reported. But if you review MomentCurvatureResults.n I'd expect that if undertaking an analysis at an axial load of 0 (as this is all that is currently implemented), then for equilibrium these axial loads would be zero as you're looping through all the concrete and steel geometries and adding all the force and moment contributions into the list of moment curvature results.

However this is not the case, you get a whole lot of random numbers like this:-

[0.0, -0.477399625587168, -0.7160994383370962, 0.36906589552563673, -1.042456716982997, -1.418755254032476, -1.676857578247109, 1.7723948539223784, 0.24788216741399083, 1.3830480518536206, 2.277053881669417, 2.392449132697948, 2.1055746989477484, 2.859097843946074, 3.2615732805716107, 2.495338162385451, -4.403265472748899, -5.889407494905754, 6.210181255810312, 7.746934336988488, -7.578399773250567, 10.018343768431805, 5725.446966758347, -11.60338317399146, -11.855866280500777, -13.434843217459274, -12.631551284663146, -15.377393476694124, 13.965917276596883]

If you add a few print statements to the example results in moment_curvature.ipynb examples you should see what I mean.

This seems to indicate convergence is not being achieved, as for the correct moment being reported the axial equilibrium should equal zero with no external axial load being added. Unless I'm misunderstanding here what is being reported?

I cannot seem to track down the issue (as going into the moment curvature code is like going down a rabbithole as it relies on so many other functions for evaluating stresses, strains, etc that I get a bit lost in what is being worked out/returned having not written it myself!).

But it might be related to the assumed centroid not being the geometric centroid as I noted in #9 (reply in thread)_, and the fact this can throw out either the moment or axial force equilibrium depending on which one you're evaluating. There probably should probably be a check that the axial equilibrium is equal to the external axial load, otherwise raise an exception?

Also.....
When I define my own non-linear stress/strain relationship I tend to get a moment capacity several times the maximum capacity of the section, I'm sure this is related to this issue, but cannot seem to find the culprit and guess solving the above issue my help identify the issue once code base is working as intended. EDIT - sorted this, for future reference - needed to return stress strain relationship to zero in the tension half of the relationship.

Also with the predefined ConcreteLinearNoTension & ConcreteLinear materials, there should be a horizontal part of the curve to the ultimate strain? If you address #47, then you end up with quite different moment curvature response as it is reliant on the defined curve for these classes as it tops out at 0.001 strain.

The neutral axis should not be theta

  • I have searched the issues
    of this repo and believe that this is not a duplicate.

Issue

In most analyses, it is assumed that the Angle between the neutral axis and x is theta, which in turn is the Angle between the resultant bending moment and the x axis. Is it correct?

AS 3600 extra design point at transition in phi

Discussed in #12

Originally posted by Agent6-6-6 July 24, 2022
"where you're dealing with a variable phi, when doing the interaction curve I believe for accuracy at the point where phi changes from variable to constant you should really be injecting an additional axial load point to capture exact point of change on the interaction curve."

image

add predefined unit scaling option to print_results methods

When you print results of say a ultimate bending analysis to the terminal, the resulting table values are consistent with the analysis units, for an SI analysis N & mm.

I feel having a way in these methods to return in kN and kNm via a multiplied scaling factor (like n_scale = 1e-3, m_scale = 1e-6), or other for Imperial units would be useful. As typically you're interested in the answer in these units?

By default return in N & mm, but have option to scale by another factor to units more consistent with typical analyses like kN and kNm for axial and moment respectively if working in SI units.

Thoughts?

Small ambiguity in the docs for net axial load definitions for ultimate_bending_capacity() methods.

Hi @robbievanleeuwen

I've noted in the AS3600 class (and by extension the NZS3101 class I've been developing following your lead), that the ultimate_bending_capacity method has an input n which is noted as being the net axial load.

Also, the concrete_section class ultimate_bending_capacity method has input n and is also described as net axial load. However, this one is expecting n=n/phi as an input so they are not quite the same thing when called from a design code method.

One of them is not correctly defined as they are not quite the same thing, should the design code class input be renamed something different with a description like :param n_load: axial design load/action or something like that to reflect that it is a design action and not the net axial load if that is being defined as $\displaystyle{\frac{N^*}{\phi}}$ in concrete_section class?

Potentially as well, this requires expanding on the definition in the concrete_section class that net axial load n really means net axial load, defined as axial design load/action divided by phi (n=n_load/phi) if a non-unity $\phi$ is applicable?

Perhaps also considering renaming n to n_net further separates the two different definitions?
This would also further distinguishes where n might often be utilised for a counter or something like that by a user.

Strand stress-strain profiles have compression branch.

Hi @robbievanleeuwen

Design codes often have rules around strand not being effective as compression reinforcement. So expectation would be that there would probably only be a tension branch for the strand materials not tension and compression.

If you're aware of some codes allowing strands to be utilised in compression, then a boolean variable could be added to only return the tension branch (or a boolean variable to return both branches, with a default of just the tension branch being created).

From NZS3101 for example:-
image

Analysing doubly symmetric reinforced section at 45 degree angle, weird behaviour, crashes kernel...?

Hi @robbievanleeuwen, this is a bit of a weird one that I have encountered a few times and boiled it down the following:-

Describe the bug
Running the code below results in various consistent errors occurring from crashing the kernel and returning a triangle-related error. However, it completes every now and then (often only the first time you run it from VSCode in a jupyter notebook after booting up, but the next time you run it the same errors)!

Very weird, beyond my skills to really diagnose the cause.

This behaviour seems to occur when utilising a doubly symmetric section (section and reinforcement), and with a theta of 45 degrees only.

One thing I have noted is if say you go to 45+180 or 45+90 degrees rotation for the same section effectively being analysed, it always works. So it is something specifically about 45-degree neutral axes rotation that's causing the effect as far as I can tell.

Can you confirm you see the same behaviour? Any ideas?

Error variation 1
image
Error variation 2
image

To Reproduce
Run this code

import numpy as np
import matplotlib.pyplot as plt

import concreteproperties.stress_strain_profile as ssp
from concreteproperties.material import Concrete
from concreteproperties.material import SteelBar
from sectionproperties.pre.library.concrete_sections import concrete_rectangular_section
from concreteproperties.concrete_section import ConcreteSection
from concreteproperties.results import MomentInteractionResults

concrete = Concrete(
    name="40 MPa Concrete",
    density=2.4e-6,
    stress_strain_profile=ssp.ConcreteLinear(elastic_modulus=30e3),
    ultimate_stress_strain_profile=ssp.RectangularStressBlock(
        compressive_strength=40,
        alpha=0.85,
        gamma=0.77,
        ultimate_strain=0.003,
    ),
    flexural_tensile_strength=3.4,
    colour="lightgrey",
)

steel = SteelBar(
    name="500 MPa Steel",
    density=7.85e-6,
    stress_strain_profile=ssp.SteelElasticPlastic(
        yield_strength=500,
        elastic_modulus=200e3,
        fracture_strain=0.15,
    ),
    colour="grey",
)

bar_dia = 20
geom_col = concrete_rectangular_section(
    b=600,
    d=600,
    dia_top=bar_dia,
    n_top=4,
    dia_bot=bar_dia,
    n_bot=4,
    dia_side=bar_dia,
    n_side=2,
    n_circle=8,
    cover=35 + 12,
    area_top=bar_dia**2 * np.pi / 4,
    area_bot=bar_dia**2 * np.pi / 4,
    area_side=bar_dia**2 * np.pi / 4,
    conc_mat=concrete,
    steel_mat=steel,
)

conc_sec_col = ConcreteSection(geom_col)
conc_sec_col.plot_section()

f_mi_res = conc_sec_col.moment_interaction_diagram(theta=45 * np.pi / 180)

print('Success?')
f_mi_res.plot_diagram()

Desktop (please complete the following information):

  • OS: WIndows 10
  • Same behaviour on current version 2.1.3, and the latest master
  • Python 3.10.8 (errors seem to be independent of this, checked on python 3.8 as well and same behaviour, possibly seeing kernel crash more often than the triangle error on 3.8 though).

pip install doesn't include design_codes

Describe the bug
I tried pip installing concreteproperties this morning and the design_codes module wasn't included. Is this a bug or is this feature still in development at this point?

To Reproduce
Steps to reproduce the behaviour: pip install concreteproperties

Expected behaviour
design_codes module included in installation.

Screenshots
image

image

Interaction Diagram Features

Discussed in #12

Originally posted by Agent6-6-6 July 23, 2022
"Many codes ACI318 and NZS3101 have a hard upper cutoff for the axial load a section can take... additionally it may be useful to also report the control points and have an option to plot these points on the interaction curves?"

Features to add to moment_interaction_diagram():

  • Option to provide upper compression limit to interaction curve, i.e. max_comp: Optional[float] = None.
  • Add optional control points and labels. Control points are given axial forces or neutral axis depths (useful for balanced/strain points) which get added to the interaction diagram. There will be an optional corresponding list of labels which relates to these control points. By default control points are defined at decompression (d_n=D) and pure bending (N=0).
  • Extend n_points to also have the option of providing a list between control points. By default a single value is provided, say 24. If more control points are provided this can be extended to a list e.g. [10, 24] is 10 points between 1st and 2nd control point and 24 points between 2nd and 3rd control point.

Plot multiple biaxial bending diagrams in 2D plot

While the 3D plot is a great visualization, it's hard to use in practice.

I'm sure that a more Python adept user would be able to create a matplotlib 2D plot with multiple biaxial bending diagrams (e.g. contours for different values of N), but I'm struggling.

It would be great if plot_multiple_diagrams for biaxial bending had a built-in option for a 2D flattened plot.

Add warning for simple stress-strain profiles re:moment-curvature analysis

@robbievanleeuwen:

Perhaps a warning is warranted in the docs for this one?

@Agent6-6-6:

yeah that would make sense, saying something like stress-strain relationship not intended for section capacity analyses, and only intended for section properties analyses? I guess those particular relationships are not a lot of interest from a design standpoint if you know what you're doing, but you could imagine someone incorrectly using it if they didn't understand what they were doing!

Originally posted by @Agent6-6-6 in #49 (comment)

Further refinement of moment interaction n_points, n_spacing when max_comp truncates M/N diagram?

@robbievanleeuwen, I've noted one peculiarity with the way the improvements to M/N curves have been implemented as merged in #66.

When dealing with a max_comp scenario or a proportionally lower upper limit, then when using n_points or n_spacing it puts in the evenly spaced points not between the limits being lower value of upper limit or max_comp, but over the entire default range and the unused points are truncated at max_comp. i.e. it just culls some of the points, rather than spacing the defined points between the refined limits if they were lower or higher once max_comp truncates the axial loads to consider for example.

This leads to some issues when plotting the results with a loss of fidelity in the curves due to a significantly reduced number of axial and moment points being returned.

So if you're using a relatively low max_comp, say for wall design where limits are much lower (in NZ for example singularly reinforced walls it can be as low as 0.015Agfc), then you only get a fraction of the points specified because of the significantly reduced axial load range, and potentially a very jagged plot as a result.

For example, this plot has low max_comp, but with default n_points = 24, because of the reduced range due to the upper limit only 6 intermediate points are plotted in addition to any defined control points, the others were truncated.

image

Resolution
I think it would potentially be as easy as distributing the points between the refined limits that will be returned from the method, rather than spacing them between the larger original range of axial load points. So if max_comp is lower than the axial load corresponding to the upper limit, redefine the upper limit as max_comp. Then generate the evenly spaced points between the revised limits for the full specified number of points being returned to maintain a "nice curve".

Hopefully, that's all clear and made sense!

m_xy results not maintaining sign at max tension/max compression for plotting

Hi @robbievanleeuwen

In concrete_section.calculate_ultimate_section_actions() when the m_xy results are calculated, you're effectively calculating an absolute value, so when you plot based on the m_xy moments for a given theta you get some weird results where the values bounce back off the vertical axes when you have an unsymmetrical M/N curve:-
Figure_2

Figure_3

Not quite sure how to address this, need some way of adjusting the sign appropriately based on what plan quadrant your result is in relative the neutral axis or load angle (load angle being as discussed in #31) you've analysed?

Potentially it's as easy as just checking if both m_x or m_y change sign from some prior or following value in the positive side of the curve (depending on what way it is stepping through the axial loads) that you know is past the origin. Then for the plot the m_xy resultant it's deemed negative as its crossed the origin? That would signal the results straddle an orthogonal vertical plane through the origin?.......... I'm sure it' trickier than this though given not yet working in terms of load angle for the M/N curves!

Analysis assumptions in docs

@Agent6-6-6:

I kind of think to go along with this conversation maybe the docs also need a section/page on the analysis assumptions so user is fully informed on any assumptions and possible pitfalls. Most of this is assumed in any analysis, but no harm in explicitly stating it for clarity. You know the usual stuff like for example:-

  • Plane sections remain plane (Bernoulli), i.e. sections perpendicular to the axis of bending that are plane before bending remain plane after bending

  • The strains in both the concrete and the reinforcement varies linearly through the depth of the member, i.e. cross section strains are proportional to the distance from the neutral axis

  • The strain in the reinforcement is equal to the strain in the concrete at the same level/position, i.e. a perfect bond exists between the reinforcement and the concrete

  • Any reinforcement is considered as being characterised by a single strain value at the centre of the reinforcement, i.e. for the analysis the strain gradient across the bar diameter is not considered

  • The maximum strain at the extreme concrete compression fibre is assumed to reach a maximum limiting compressive strain

  • The stresses in the concrete and reinforcement can be determined from the strains using stress-strain curves for both concrete and steel

  • The tensile strength of concrete is neglected in strength calculations

  • The member does not buckle before the ultimate strength of the cross section is attained

  • The compressive stress-strain relationship for concrete may be assumed to be rectangular, trapezoidal, bilinear, parabolic, or any other arbitrary shape that results in prediction of strength in substantial agreement with the results of comprehensive tests

  • Other???

Originally posted by @Agent6-6-6 in #9 (reply in thread)

Add support for ACI 318-19

Alright, now that you guys have made all these refinements and process improvements, I'm ready to stand on those shoulders to implement ACI 318-19.

Perhaps more accurately, I've started work on a fork implementing ACI 318-19M. I figure that if we get the bones figured out first, skinning it in imperial units (per issue #48) can be a separate undertaking. After a false start adapting Agents NZS code, I've decided to first start by adapting the AS module (easier to wrap my head around for now).

Current work is in the ACI2 branch here: https://github.com/Lomarandil/concrete-properties-ACI/tree/Lomarandil-ACI2

My apologies, I'm still a programming and Github noob, just learning by doing. Please feel free to suggest corrections or style improvements.

AS3600 Moment Interaction - change theta

AS3600.moment_interaction_diagram() does not have an option for a neutral axis angle theta not equal to zero.

Further, other variables relating to the number of points etc. are not modifiable.

example for Generic Concrete Ultimate Profile in materials.rst

Hi @robbievanleeuwen

In going through implementing #80, I've noted the following doesn't seem consistent in the numbers utilised.

The example in material.rst implies a variable youngs modulus E for the strain calculations, and stresses provided max out at 40MPa but compressive strength is defined as only 32 MPa so inputs don't seem consistent with one another. Maybe I'm missing something here though, but it seems like this needs to be modified to a constant E consistent with the specified compressive strength and the maximum compressive strength and max stress aligned so they are the same value?

from concreteproperties.stress_strain_profile import ConcreteUltimateProfile

ConcreteUltimateProfile(
  strains=[-20 / 30e3, 0, 20 / 30e3, 30 / 25e3, 40 / 20e3, 0.003],
  stresses=[0, 0, 20, 30, 40, 40],
  compressive_strength=32,
).plot_stress_strain()

I think this is a case where ultimate_strain (don't think this is even initiated for this generic profile or parent class which would presumably cause some issues if it was used for a design_code check) and possibly compressive_strength should possibly just be populated from the user input at the end of the __post_init__ method and not initiate compressive_strength as an input:-

i.e. self.ultimate_strain = max(self.strains), and similar for the concrete_strength variable.

Activate "Discussions" tab! :)

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Incorrect strain being returned from ConcreteServiceProfile

Hi @robbievanleeuwen

Describe the bug
Under StressStrainProfile class the get_ultimate_compressive_strain method returns max(self.strains)

Whereas under ConcreteServiceProfile class the get_ultimate_compressive_strain method it returns self.ultimate_strain (believe this is incorrect)

When dealing with service stress/strain profiles, some models for confined concrete mean much larger strains are possible than the defined ultimate strain of a material used for normal ultimate design, so returning this value from ConcreteServiceProfile based classes is incorrect as may not even be a variable that's defined in the service stress/strain profile as it is irrelevant (this is my case).

The various get_ultimate_compressive_strain methods should all return max(self.strains) in my opinion? Note the same applies for returning the tension cases as well, should be min(self.strains).

For ConcreteUltimateProfile the max(self.strains) is correct as ultimate profiles currently included naturally should be defined based on the maximum ultimate_strain being the maximum compressive strain based on the appropriate compression block formulation. It's never going to be higher for ultimate design checks, but for service checks concrete models can be higher.

For example a service stress/strain relationship for confined concrete based on a Mander Confined Concrete model for a concrete that at Ultimate design would be limited to 0.003 strain, shows max strain at failure when considering the effects of confinement could be substantially higher (in this case for the service profile the ultimate_strain variable is irrelevant and can have init=false applied in child classes which causes an error when you use the get_ultimate_compressive_strain method from ConcreteServiceProfile):-

mander

Hopefully that makes sense!

Expanded Material Module

Discussed in #17

Originally posted by robbievanleeuwen July 27, 2022
Improvements to the way concreteproperties handles different materials.

Currently concreteproperties only allows steel reinforcing bars to be defined as lumped masses. Further, there is no architecture in place to introduce new materials, e.g. carbon fibre, stainless steel etc. A new material module is proposed that allows steel to be considered as structural sections and the simple creation of new material models.

  classDiagram
    Material <|-- Concrete
    Material <|-- Steel
    Steel <|-- SteelBar
    Steel <|-- SteelStrand
    Material <|-- OtherMaterials
    class Material{
      str name
      float density
      StressStrainProfile stress_strain_profile
      str colour
      bool meshed = True
    }
    class Concrete{
      ConcreteUltimateProfile ultimate_stress_strain_profile
      float alpha_squash
      float flexural_tensile_strength
    }
    class SteelBar{
      bool meshed = False
    }
    class SteelStrand{
      bool meshed = False
      other_revelant_parameters
    }

Feature request: add consideration of axial load to moment curvature analyses

Is your feature request related to a problem? Please describe.
When undertaking a moment-curvature analysis, there does not seem to be any way to undertake the analysis with an axial load applied to a member when analysing a column for example?

Describe the solution you'd like
Add the ability to specify an axial load so moment curvature analyses of columns can be undertaken

Additional context
Moment curvature response is highly dependant on the axial load applied to a member for example:-
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.