Problem-level time integration helpers.
Time Integration (fedoo.time)
The fedoo.time module contains time integrators that are attached to a
problem rather than embedded directly in a weak form. Weak forms describe the
static equilibrium, storage, and dissipation terms, while the problem selects
which temporal scheme advances each evolution category.
For example, a mechanical weak form can expose a second-order storage term through a mass or inertia weak form, and the problem can advance it with a Newmark or generalized-alpha integrator:
pb = fd.problem.NonLinear(assembly)
pb.set_time_integrator(fd.time.SECOND_ORDER, fd.time.Newmark())
Thermal diffusion is a first-order evolution and can be advanced independently:
pb.set_time_integrator(fd.time.FIRST_ORDER, fd.time.BackwardEuler())
Static analysis
A problem remains static as long as no time integrator is attached. Weak forms may still expose storage metadata, such as a density or heat capacity, but this metadata is ignored until a compatible integrator is selected:
pb = fd.problem.NonLinear(assembly)
pb.nlsolve()
An integrator can also be removed before the problem is initialized by passing
None:
pb.set_time_integrator(fd.time.SECOND_ORDER, fd.time.Newmark())
pb.set_time_integrator(fd.time.SECOND_ORDER, None)
Once the problem has been initialized, compatible weak forms may already have been compiled into transient weak forms. At that point the integrator cannot be removed safely from the same problem object; create a new static problem, or change the assembly before removing the integrator.
Evolution categories
The predefined categories are FIRST_ORDER and SECOND_ORDER.
They are instances of TimeEvolution and are used by
fedoo.problem.NonLinear.set_time_integrator() to match weak forms with
compatible schemes.
Integrators
Backward-Euler integrator for first-order storage weakforms. |
|
Explicit central-difference integrator. |
|
|
One-corrector explicit generalized-alpha integrator. |
alias of |
|
|
Generalized-alpha time integrator for second-order evolutions. |
|
Newmark-beta time integrator. |
|
Rayleigh damping descriptor: |
|
Time-evolution category used to match weakforms and integrators. |
Second-order schemes
GeneralizedAlpha is the general second-order integrator. In fedoo’s
convention, alpha_m = 0 and alpha_f = 0 gives the classical endpoint
Newmark scheme. The default values of beta and gamma are chosen from
The Newmark constructor is kept as the compact interface for the
common case:
fd.time.Newmark(beta=0.25, gamma=0.5)
which is equivalent to:
fd.time.GeneralizedAlpha(alpha_m=0.0, alpha_f=0.0,
beta=0.25, gamma=0.5)
Explicit second-order schemes
Explicit problems use the same evolution-category attachment API, but keep the static-force and lumped-mass operations separate. Central difference can be selected with:
pb = fd.problem.ExplicitDynamic(assembly, time_step=dt)
pb.set_time_integrator(fd.time.SECOND_ORDER,
fd.time.CentralDifference())
The primary interface is a user-controlled increment loop. The fixed linear path reuses stiffness and lumped mass cached during initialization and does not update the constitutive law implicitly:
pb.initialize()
pb.apply_boundary_conditions()
while pb.time < tmax:
pb.solve()
pb.update()
Call apply_boundary_conditions() again only when boundary conditions,
loads or MPCs change. For a managed nonlinear increment, use
pb.solve_time_increment(update_weakform=True, set_start=True). For a
complete history, pb.solve_history(update_weakform=False) reuses the
fixed linear operators, while update_weakform=True updates and commits the
constitutive state every increment. Its interval_output argument selects
exact output times; increments are temporarily shortened when necessary and
the nominal time step is restored afterwards.
Finite-element mass is row-sum lumped and cached by default. Pass
mass_lumping=False to retain the consistent matrix, and request a mass
refresh explicitly only when storage changes. Configuration-dependent
assembly providers can refresh their small storage blocks independently of
the cached finite-element mass.
For controllable high-frequency dissipation, use
ExplicitGeneralizedAlpha, also available under the
ExplicitNewmark alias. Both explicit schemes use the inertia declared
by the static weak form, for example through material density or
weakform.set_inertia(...).
Dissipation
Physical damping is defined on the weak form so that only selected parts of a multi-assembly problem are damped:
wf = fd.weakform.StressEquilibrium(material)
wf.set_dissipation(alpha=0.1, beta=0.0)
The keyword form defines Rayleigh damping
\(\mathbf{C} = \alpha\mathbf{M} + \beta\mathbf{K}\). A dedicated
dissipative weak form can also be passed to set_dissipation.
Different Rayleigh coefficients may be assigned to different leaf assemblies
in an AssemblySum. Weakforms sharing one leaf assembly must use the same
coefficient pair because they also share one assembled stiffness matrix.