-
Notifications
You must be signed in to change notification settings - Fork 50
Experiment/results-object #289
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
…s in UltimateBendingMomentResults
| section=self.section, | ||
| eps_a=self.eps_axial[0], | ||
| chi_y=self.chi_y[0], | ||
| chi_z=self.chi_z[0], | ||
| n=self.n, | ||
| m_y=self.m_y[0], | ||
| m_z=self.m_z[0], | ||
| num_points=num_points, | ||
| seed=self.seed, | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this portion of the code be refactored out to avoid the code repetition below? We could e.g. create an internal method _create_detailed_result which sets self.detailed_result based on self.current_step, so for each of the methods create_detailed_result, next_step, previous_step and set_step we can simply set self.current_step and then call the internal method.
| for surf in self.section.geometry.geometries: | ||
| # Use surf.random_points_within to get random points | ||
| y, z = surf.random_points_within( | ||
| num_points=num_points, seed=self.seed | ||
| ) | ||
| strain = self.eps_a - self.chi_z * y + self.chi_y * z | ||
| stress = surf.material.constitutive_law.get_stress(strain) | ||
| surface_data.append( | ||
| { | ||
| 'y': y, | ||
| 'z': z, | ||
| 'strain': strain, | ||
| 'stress': stress, | ||
| 'name': getattr(surf, 'name', None), | ||
| 'group_label': getattr(surf, 'group_label', None), | ||
| } | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be great if we could store the surface data in a hierarchy similar to the point data, e.g. as a dict where the key is the group_label and the value is the dict with data.
Alternatively, and consistently for surface and point data, we could store the data in a manner that is easily input to a dataframe. For this structure, I guess one option could be to store a dict with the following keys: x, y, strain, stress, group_label, and each value is an array or a list of values for each individual point. So one dict for surface data and one for point data. This would open for really smooth filtering and plotting downstream.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are still lines that are not covered in testing. Could we perhaps add a test where we for example create detailed results for a moment curvature relation, and for each set of detailed results, integrate over the results to check if the detailed results add up to the moment, axial force, curvature and axial strain of the moment curvature relation?
mortenengen
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this valuable feature addition! I have left a couple of comments for you to consider during finalizing 😃
This is just an experiment of what I was trying before our discussion @mortenengen.
Outdated, new developments later
The current implementation is really easy even if works only with fibers it does not requires additional methods to geometry since it deals everything from triangulation data already available with fibers.
But this basically permits doing something simple like:
Obtaining:

Or even more elaborated things like:
Obtaining as an example this:

The relation between coordinates and strains at each coordinate is:
That in matrix form is:
I find somehow strange (but I can think more about it) to have this vector
as a return of the geometry since a "geometry" is nothing till when it is not inside the section, and it is when it is in the section that has that specific reference system and therefore that the vector
assumes that meaning...
I don't know if it is just me, but I find more logic having this stuff in the level of sections (or in this case results), not geometries.
New implementations
I created the following new feature in the geometries that permits us to better code the methods seen above and to make them work not only for fiber integrator, but also for marin integrator.
Moreover having such dense points within the polygon it is possible to add a
probemethod passing coordinates of a point (y,z) and returning the strain and/or stress responde of the nearest point to the input one.Get random points within polygon
Meanwhile I did a first fast implementation to get a bunch of random points uniformly distributed from the SurfaceGeometry.
I considered two possible algorithms, but I choose the fastest one.
For instance for this polygon:

we get (these are 1000 points):

Or for this geometry:
with this simple command:
we obtain instantly:
This is the path for permitting not using triangulation data (like in my current test I had) making it possible to work with both fiber or marin integrators.
Get point coordinates as a numpy array from compound geometry
I also added a method for returning a numpy array from a
CompoundGeometry. The method by default returns all point geometries. If the optionalgroup_labelparameter is passed, this is used as a filter:If the filter is not found the array will be empty.
New detailed results
As an attempt I created a
SectionDetailedResultStatethat basically stores strains and stress for all the geometry for a given state (i.e. a set of deformations / forces). For instance when they come from a computation of ultimate strength it will be the failure state, but during a moment-curvature each state corresponds to one point of the curve.For now as an attempt for testing there is a method for ceating this datastructure that remains stored (up to when we don't want to change state). In this way we can inspect (or plot) for each part of the geometry strains and / or stresses.
By default the point geometries are grouped by
group_label.This example shows the idea.
now res contains a
detailed_resultobject which containssurface_dataandpoint_data. The plotting is slightly more complicated than what I have done above for fibers, but it permits way much liberty:or
obtaining for example:

But one could do a different color map for each surface if we have more SurfaceGeometries.
In the same way one could deal with point_data, plotting (or asking for) only certain group_label or all. For instance adding prestress reinforcement and regular reinforcement (by group_label) with different color maps and bars:
obtaining:

Finally this detailed_result object could contain a probe method passing the coordinates and returning strains and stresses. Some filtering utilities could be included in the probe for instance for inspecting only surfaces, surface with a name or label, points (also with names or labels).
New detailed results for moment-curvature
I also experimented with moment curvature, permitting to advance from DetailState to DetailState. In this way one can advance from one step to next with
res.next_step()or go back withres.previous_step(); it is also possible to go to a specific step withres.set_step(). Each one of these commands prepare the detailed results objects that therefore can be used for plotting, querying etc.Playing with such functions for instance one can create an animation of strain or stress distribution during the moment-curvature analysis, like the following animation, where it is visible the suddn shift in neautral axis after yielding of bars.