JWock82 / Pynite

A 3D structural engineering finite element library for Python.
MIT License
474 stars 95 forks source link

Implement rotational springs? #153

Open Jeroen124 opened 1 year ago

Jeroen124 commented 1 year ago

I would like to implement rotational springs to the end of elements, just like the axial springs, and then two rotational constants around its strong and weak axis.

JWock82 commented 1 year ago

This is a good idea, but currently low on the priority list. You’re welcome to take a stab at it and issue a pull request. I would suggest using the Spring element’s code as a template to start with.

connorferster commented 8 months ago

A couple of engineers in my course are asking about whether PyNite can accommodate non-linear (axial) springs. I was taking a look at the Spring3D object and also the solver. It seems that, because @JWock82 has already implemented the iterative solver (for tension/compression elements) that it might not actually take a lot of work to add non-linearity to the springs.

The general idea would be that, instead of passing a constant for the spring stiffness, one could instead pass a function. This function would need to have a function signature kind of like:

def stiffness_function(force: Optional[float] = None, displacement: Optional[float] = None) -> float:
    """
    Returns a float representing a stiffness based on either the given 'force' or 
    'displacement'.
    """

There would be conditions in Spring3D to see whether a function or number was passed and, if a function, then the k matrix could be created using the calculated stiffness from the function instead of the static ks value. On the solver, a condition would need to be created to check for convergence but perhaps the convergence check itself could be added in to the Spring3D element to create a common interface.

It seems that there is an opportunity to update the k matrix of the Spring3D to implement other translational/rotational stiffnesses at the same time. Thus, it seems like it would not be too difficult to implement a fully non-linear spring that could provide constant or variable stiffness in any DOF.

I can start a PR for this but I will need some help. It would involve modifying/evolving the interface for Spring3D but I think it can be done in a non-breaking way.

@JWock82 @Jeroen124 @phil-vivant @flit-float-fly: What do you think?

JWock82 commented 8 months ago

Hi Connor,

I think this is a fairly simple task. You could actually do it without a special solver. A simple loop could do it. The idea being that you have a list of stiffnesses and corresponding displacements. You solve the model, and then check each spring to see what its stiffness should be based on the calculated displacement. If it’s got the wrong stiffness you change it and rerun the model. Loop until all the spring stiffnesses are consistent with the spring deformations.

This is essentially how tension only analysis is implemented in Pynite. Building this feature directly into a built-in solver would be pretty easy I think, and could borrow most of the code from TC analysis.

Unfortunately I just don’t have a lot of time. I’ve got too many irons in the fire. I’ve been working on pushover analysis, got really close, and then got sick of it. Some really tricky math there trying to invert a singular matrix. It solves but the numbers don’t look right. I’ll probably give it another go here soon.

Recently I switched over to streamlining the renderer to be compatible with Streamlit Cloud by using PyVista instead of VTK. Apparently Streamlit Cloud doesn’t like raw VTK. I’m finding PyVista is so much simpler to use and has a lot of built in functionality out of the box. Not sure how well it deals with large meshes yet though.

Best Regards,

Craig Brinck


From: Connor Ferster @.> Sent: Wednesday, February 28, 2024 5:22:57 PM To: JWock82/PyNite @.> Cc: Craig @.>; Mention @.> Subject: Re: [JWock82/PyNite] Implement rotational springs? (Issue #153)

A couple of engineers in my course are asking about whether PyNite can accommodate non-linear (axial) springs. I was taking a look at the Spring3D object and also the solver. It seems that, because @JWock82https://github.com/JWock82 has already implemented the iterative solver (for tension/compression elements) that it might not actually take a lot of work to add non-linearity to the springs.

The general idea would be that, instead of passing a constant for the spring stiffness, one could instead pass a function. This function would need to have a function signature kind of like:

def stiffness_function(force=None, displacement=None) -> float: """ Returns a float representing a stiffness based on either the given 'force' or 'displacement' (but not both). """

There would be conditions in Spring3D to see whether a function or number was passed and, if a function, then the k matrix could be created using the calculated stiffness from the function instead of the static ks value. On the solver, a condition would need to be created to check for convergence but perhaps the convergence check itself could be added in to the Spring3D element to create a common interface.

It seems that there is an opportunity to update the k matrix of the Spring3D to implement other translational/rotational stiffnesses at the same time. Thus, it seems like it would not be too difficult to implement a fully non-linear spring that could provide constant or variable stiffness in any DOF.

I can start a PR for this but I will need some help. It would involve modifying/evolving the interface for Spring3D but I think it can be done in a non-breaking way.

@JWock82https://github.com/JWock82 @Jeroen124https://github.com/Jeroen124 @phil-vivanthttps://github.com/phil-vivant @flit-float-flyhttps://github.com/flit-float-fly: What do you think?

— Reply to this email directly, view it on GitHubhttps://github.com/JWock82/PyNite/issues/153#issuecomment-1970019806, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AH6HUEZXY6VEK66GFHJ2NNDYV6U4DAVCNFSM6AAAAAAV6RQFTWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNZQGAYTSOBQGY. You are receiving this because you were mentioned.Message ID: @.***>

Jeroen124 commented 7 months ago

Hello @JWock82 and @connorferster, your suggestions seem workable. I believe adopting a phased approach could be beneficial. At present, I'm not aware of a straightforward method to measure the slopes at the ends of beams. How does one accomplish this within the solver, @JWock82? Knowing the angles is crucial for certain boundary conditions, correct?

If we start by establishing a simple and elegant method for slope measurement, we could then potentially leverage this technique to iteratively develop a solution incorporating a rotational spring at the member ends. Do you both concur? How should we best go about measuring the slopes? I've encountered a method that involves using segments, (https://github.com/JWock82/PyNite/discussions/159) though it appears to be somewhat inelegant. Would you agree?