I am extending Garth Wells' fenics-solid-mechanics library to solve generic solid mechanics problems such as nonlinear elasticity, and viscoelasticity (It only supports Drucker-Prager and von Mises elastoplasticity currently).
Most viscoelasticity models require the time-step value for the stress and tangent calculations. An example call stack looks like this:
- QuadratureFunction.restrict() -> ConstitutiveUpdate.update() -> DruckerPrager.***
Here, QuadratureFunction
is a child function of GenericFunction
whose instances are passed on to PlasticityProblem
in the demos, which is a child class of NonlinearProblem
. The constitutive update function is where the stresses are projected back onto the yield surface, and multiple member functions of DruckerPrager
are called for the return-mapping algorithm.
Based on this model, I created my own classes that will work like the conventional finite element programs, where you have the so-called material routines for each different material. Instead of the DruckerPrager
class, I introduced my own LinearViscoelasticity class which calculates the stress and tangent, given the internal variables contained in HistoryData
instances similar to the plasticity examples.
The only problem is that the time-step interval should be accessible inside the material functions due to the time-dependence. It is sometimes the case that you even need the current time, and the number of time-steps.
I am aware that I can achieve this through the use of global variables, but it is not good practice.
I am also aware that I cannot change GenericFunction.restrict(). The time-step is a variable that is defined in the specific demo, and is not even stored inside the input forms. Is there an elegant solution to this? I am guessing I would need to modify the forms to some extent, but I have no idea other than that.
Thanks in advance.