Timestep computation ===================== :obj:`Timestep ` determines numerical stability and is an important parameter in simulations. It can be assigned explicitly, but it can also be left at its default ``nan`` value, and it will be initialized automatically. In the DEM field, there are three constraints for critical timestep: #. particle stiffnesses (:obj:`~woo.utils.pWaveDt` and similar) which essentially estimate future contact stiffnesses from a single particle; #. current contact stiffnesses (:obj:`~woo.dem.DynDt`) sums up all stiffnesses of all contact of a node, and estimates eigenvalue, which is the proper stability criterion; #. current intra-particles stiffnesses (FEM) which are linking nodes of multi-nodal particles (:obj:`~woo.dem.DynDt` provides the interface to query those, by using :obj:`~woo.dem.IntraForce`). Initialization -------------- When timestep is not a meaningful value at the beginning of the timestep (usually the very first one), all defined fields (via ``Field::critDt``) and engines (via ``Engine::critDt``) are queried for critical timestep: #. :obj:`~woo.dem.DemField` determines critical timestep by calling :obj:`~woo.utils.pWaveDt` on its particles. #. :obj:`~woo.dem.ConveyorInlet` reports minimum timestep based on the smallest particle to be generated, and assigned material. #. :obj:`~woo.dem.RandomInlet` calls its :obj:`generators `, which, in conjunction with material information from the inlet, compute the critical timestep for particles to be generated. #. :obj:`~woo.dem.DynDt` is called to determine timestep the same as otherwise (see below). The critical timestep from all these sources is multipled by the :obj:`~woo.core.Scene.dtSafety` factor before being applied to :obj:`~woo.core.Scene.dt`. :obj:`~woo.dem.DynDt` --------------------- :obj:`~woo.dem.DynDt` uses both contact and intra-particle stiffnesses to determin critical timestep: #. if :obj:`engines ` contain :obj:`~woo.dem.IntraForce`, it will be used: for every multi-nodal particle, ``IntraForce::addIntraStiffness`` is called; this dispatches the call to shape-specific functor (if any), which in turn calls its own shape-specific ``IntraFunctor::addIntraStiffnesses``. This function is responsible for intializing internal stiffness matrices, if necessary, and reporting diagonal stiffness terms to the caller. #. for all nodes, traverse all particles attached to it, and add their normal and tangential stiffnesses.