Skip to content
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

Explicit dynamics #14658

Merged
merged 17 commits into from May 19, 2020
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 22 additions & 0 deletions framework/doc/content/source/timeintegrators/CentralDifference.md
@@ -0,0 +1,22 @@
# CentralDifference

!syntax description /Executioner/TimeIntegrator/CentralDifference

## Description

Central difference integration is a common explicit integration scheme, typically used in structural dynamics. For a variable, $u$, at time $t$ with a time step, $\Delta t$, the central difference approximations for the first and second time derivatives, $\dot{u}$ and $\ddot{u}$, are given as,

\begin{equation}
\begin{aligned}
\mathbf{\dot{u}}(t) &=& \frac{\mathbf{u}(t+\Delta t)-\mathbf{u}(t-\Delta t)}{2 \Delta t} \\
\mathbf{\ddot{u}}(t) &=& \frac{\mathbf{u}(t+\Delta t)-2\mathbf{u}(t)+\mathbf{u}(t-\Delta t)}{\Delta t^2}
\end{aligned}
\end{equation}

The central difference time integrator derives from the [`ActuallyExplicitEuler`](ActuallyExplicitEuler.md) class and therefore circumvents the nonlinear solver. It can be used with `consistent`, `lumped` or `lump_preconditioned`, `solve_type` options. Information on these solve options can be found on the [`ActuallyExplicitEuler`](ActuallyExplicitEuler.md) page.

!syntax parameters /Executioner/TimeIntegrator/CentralDifference

!syntax inputs /Executioner/TimeIntegrator/CentralDifference

!syntax children /Executioner/TimeIntegrator/CentralDifference
Expand Up @@ -65,11 +65,11 @@ is used in the linear system, but the linear solve is preconditioned using the
lumped mass matrix. This compromise retains the accuracy of the `consistent`
option while benefiting from some of the speedup offered by the `lumped` option.

The lumped mass matrix preconditioner is applied with a helper class, `LumpedPreconditioner`:
The lumped mass matrix preconditioner is applied with the class, `LumpedPreconditioner`:

!listing framework/include/timeintegrators/ExplicitTimeIntegrator.h line=class LumpedPreconditioner
!listing framework/include/timeintegrators/LumpedPreconditioner.h

This helper object simply applies the inverse of the diagonal, lumped
This object simply applies the inverse of the diagonal, lumped
mass-matrix as the preconditioner for the linear solve, which is very
efficient. Note that when this option is applied you shouldn't specify any other
preconditioners using command-line syntax or they will override this option.
Expand Down
18 changes: 15 additions & 3 deletions framework/include/interfaces/Coupleable.h
Expand Up @@ -164,6 +164,16 @@ class Coupleable
virtual const VariableValue &
coupledVectorTagValue(const std::string & var_name, TagID tag, unsigned int comp = 0);

/**
* Returns dof value of a coupled variable for a given tag
* @param var_name Name of coupled variable
* @param tag vector tag ID
* @param comp Component number for vector of coupled variables
* @return Reference to a DofValue for the coupled variable
*/
virtual const VariableValue &
coupledVectorTagDofValue(const std::string & var_name, TagID tag, unsigned int comp = 0);

/**
* Returns value of a coupled variable for a given tag. This couples the diag vector of matrix
* @param var_name Name of coupled variable
Expand Down Expand Up @@ -514,23 +524,25 @@ class Coupleable
* Second time derivative of a coupled variable
* @param var_name Name of coupled variable
* @param comp Component number for vector of coupled variables
* @return Reference to a VariableValue containing the time derivative of the coupled variable
* @return Reference to a VariableValue containing the second time derivative of the coupled
* variable
*/
virtual const VariableValue & coupledDotDot(const std::string & var_name, unsigned int comp = 0);

/**
* Old time derivative of a coupled variable
* @param var_name Name of coupled variable
* @param comp Component number for vector of coupled variables
* @return Reference to a VariableValue containing the time derivative of the coupled variable
* @return Reference to a VariableValue containing the old time derivative of the coupled variable
*/
virtual const VariableValue & coupledDotOld(const std::string & var_name, unsigned int comp = 0);

/**
* Old second time derivative of a coupled variable
* @param var_name Name of coupled variable
* @param comp Component number for vector of coupled variables
* @return Reference to a VariableValue containing the time derivative of the coupled variable
* @return Reference to a VariableValue containing the old second time derivative of the coupled
* variable
*/
virtual const VariableValue & coupledDotDotOld(const std::string & var_name,
unsigned int comp = 0);
Expand Down
8 changes: 8 additions & 0 deletions framework/include/kernels/TimeKernel.h
Expand Up @@ -30,6 +30,14 @@ class TimeKernel : public Kernel

virtual void computeResidual() override;

/**
* Entry point for additional computation for the local residual after the standard calls
*
* NOTE: This is an advanced interface and in nearly all cases you should just override
* computeQpResidual()!
*/
virtual void computeResidualAdditional() {}

protected:
/// Time derivative of u
const VariableValue & _u_dot;
Expand Down
25 changes: 11 additions & 14 deletions framework/include/systems/AuxiliarySystem.h
Expand Up @@ -43,7 +43,6 @@ class AuxiliarySystem : public SystemBase, public PerfGraphInterface
AuxiliarySystem(FEProblemBase & subproblem, const std::string & name);
virtual ~AuxiliarySystem();

virtual void init() override;
virtual void addExtraVectors() override;

virtual void initialSetup();
Expand Down Expand Up @@ -158,17 +157,7 @@ class AuxiliarySystem : public SystemBase, public PerfGraphInterface
*/
bool needMaterialOnSide(BoundaryID bnd_id);

NumericVector<Number> & solution() override { return *_sys.solution; }
NumericVector<Number> & solutionOld() override { return *_sys.old_local_solution; }
NumericVector<Number> & solutionOlder() override { return *_sys.older_local_solution; }
NumericVector<Number> * solutionPreviousNewton() override { return _solution_previous_nl; }

const NumericVector<Number> & solution() const override { return *_sys.solution; }
const NumericVector<Number> & solutionOld() const override { return *_sys.old_local_solution; }
const NumericVector<Number> & solutionOlder() const override
{
return *_sys.older_local_solution;
}
const NumericVector<Number> * solutionPreviousNewton() const override
{
return _solution_previous_nl;
Expand All @@ -185,7 +174,7 @@ class AuxiliarySystem : public SystemBase, public PerfGraphInterface

void clearScalarVariableCoupleableTags();

// protected:
protected:
void computeScalarVars(ExecFlagType type);
void computeNodalVars(ExecFlagType type);
void computeNodalVecVars(ExecFlagType type);
Expand All @@ -212,8 +201,6 @@ class AuxiliarySystem : public SystemBase, public PerfGraphInterface
NumericVector<Number> & _serialized_solution;
/// Solution vector of the previous nonlinear iterate
NumericVector<Number> * _solution_previous_nl;
/// Time integrator
std::shared_ptr<TimeIntegrator> _time_integrator;
/// solution vector for u^dot
NumericVector<Number> * _u_dot;
/// solution vector for u^dotdot
Expand All @@ -224,6 +211,9 @@ class AuxiliarySystem : public SystemBase, public PerfGraphInterface
/// Old solution vector for u^dotdot
NumericVector<Number> * _u_dotdot_old;

/// The current states of the solution (0 = current, 1 = old, etc)
std::vector<NumericVector<Number> *> _solution_state;

/// Whether or not a copy of the residual needs to be made
bool _need_serialized_solution;

Expand Down Expand Up @@ -261,4 +251,11 @@ class AuxiliarySystem : public SystemBase, public PerfGraphInterface
friend class ComputeNodalKernelBcsThread;
friend class ComputeNodalKernelJacobiansThread;
friend class ComputeNodalKernelBCJacobiansThread;

NumericVector<Number> & solutionInternal() const override { return *_sys.solution; }
NumericVector<Number> & solutionOldInternal() const override { return *_sys.old_local_solution; }
NumericVector<Number> & solutionOlderInternal() const override
{
return *_sys.older_local_solution;
}
};
21 changes: 9 additions & 12 deletions framework/include/systems/DisplacedSystem.h
Expand Up @@ -30,8 +30,6 @@ class DisplacedSystem : public SystemBase
Moose::VarKindType var_kind);
virtual ~DisplacedSystem();

virtual void init() override;

virtual NumericVector<Number> & getVector(TagID tag_id) override
{
return _undisplaced_system.getVector(tag_id);
Expand Down Expand Up @@ -91,15 +89,8 @@ class DisplacedSystem : public SystemBase
return _undisplaced_system.currentSolution();
}

NumericVector<Number> & solution() override { return _undisplaced_system.solution(); }
NumericVector<Number> & solutionOld() override;
NumericVector<Number> & solutionOlder() override;
NumericVector<Number> * solutionPreviousNewton() override { return NULL; }

const NumericVector<Number> & solution() const override { return _undisplaced_system.solution(); }
const NumericVector<Number> & solutionOld() const override;
const NumericVector<Number> & solutionOlder() const override;
const NumericVector<Number> * solutionPreviousNewton() const override { return NULL; }
NumericVector<Number> * solutionPreviousNewton() override { return nullptr; }
const NumericVector<Number> * solutionPreviousNewton() const override { return nullptr; }

NumericVector<Number> * solutionUDot() override { return _undisplaced_system.solutionUDot(); }
NumericVector<Number> * solutionUDotDot() override
Expand Down Expand Up @@ -218,7 +209,13 @@ class DisplacedSystem : public SystemBase
void addTimeIntegrator(std::shared_ptr<TimeIntegrator> ti) override;

protected:
NumericVector<Number> & solutionInternal() const override
{
return _undisplaced_system.solution();
}
NumericVector<Number> & solutionOldInternal() const override;
NumericVector<Number> & solutionOlderInternal() const override;

SystemBase & _undisplaced_system;
TransientExplicitSystem & _sys;
};

10 changes: 3 additions & 7 deletions framework/include/systems/DumpObjectsNonlinearSystem.h
Expand Up @@ -32,16 +32,12 @@ class DumpObjectsNonlinearSystem : public NonlinearSystemBase
virtual bool converged() override { return true; }
virtual NumericVector<Number> & RHS() override { return *_dummy; }

NumericVector<Number> & solutionOld() override { return *_dummy; }
NumericVector<Number> & solutionOlder() override { return *_dummy; }

const NumericVector<Number> & solutionOld() const override { return *_dummy; }
const NumericVector<Number> & solutionOlder() const override { return *_dummy; }

virtual unsigned int getCurrentNonlinearIterationNumber() override { return 0; }
virtual void setupFiniteDifferencedPreconditioner() override {}

protected:
NumericVector<Number> & solutionOldInternal() const override { return *_dummy; }
NumericVector<Number> & solutionOlderInternal() const override { return *_dummy; }

NumericVector<Number> * _dummy;
};

24 changes: 10 additions & 14 deletions framework/include/systems/NonlinearEigenSystem.h
Expand Up @@ -84,20 +84,6 @@ class NonlinearEigenSystem : public NonlinearSystemBase

virtual NonlinearSolver<Number> * nonlinearSolver() override;

NumericVector<Number> & solutionOld() override { return *_transient_sys.old_local_solution; }

NumericVector<Number> & solutionOlder() override { return *_transient_sys.older_local_solution; }

const NumericVector<Number> & solutionOld() const override
{
return *_transient_sys.old_local_solution;
}

const NumericVector<Number> & solutionOlder() const override
{
return *_transient_sys.older_local_solution;
}

virtual TransientEigenSystem & sys() { return _transient_sys; }

/**
Expand Down Expand Up @@ -147,6 +133,16 @@ class NonlinearEigenSystem : public NonlinearSystemBase
TagID nonEigenMatrixTag() { return _A_tag; }

protected:
NumericVector<Number> & solutionOldInternal() const override
{
return *_transient_sys.old_local_solution;
}

NumericVector<Number> & solutionOlderInternal() const override
{
return *_transient_sys.older_local_solution;
}

TransientEigenSystem & _transient_sys;
EigenProblem & _eigen_problem;
std::vector<std::pair<Real, Real>> _eigen_values;
Expand Down
17 changes: 7 additions & 10 deletions framework/include/systems/NonlinearSystem.h
Expand Up @@ -64,23 +64,20 @@ class NonlinearSystem : public NonlinearSystemBase
return _transient_sys.nonlinear_solver.get();
}

NumericVector<Number> & solutionOld() override { return *_transient_sys.old_local_solution; }
const NumericVector<Number> & solutionOld() const override
virtual TransientNonlinearImplicitSystem & sys() { return _transient_sys; }

void computeScaling() override;

protected:
NumericVector<Number> & solutionOldInternal() const override
{
return *_transient_sys.old_local_solution;
}

NumericVector<Number> & solutionOlder() override { return *_transient_sys.older_local_solution; }
const NumericVector<Number> & solutionOlder() const override
NumericVector<Number> & solutionOlderInternal() const override
{
return *_transient_sys.older_local_solution;
}

virtual TransientNonlinearImplicitSystem & sys() { return _transient_sys; }

void computeScaling() override;

protected:
TransientNonlinearImplicitSystem & _transient_sys;
ComputeResidualFunctor _nl_residual_functor;
ComputeFDResidualFunctor _fd_residual_functor;
Expand Down
8 changes: 5 additions & 3 deletions framework/include/systems/NonlinearSystemBase.h
Expand Up @@ -605,9 +605,6 @@ class NonlinearSystemBase : public SystemBase, public PerfGraphInterface
*/
bool hasDiagSaveIn() const { return _has_diag_save_in || _has_nodalbc_diag_save_in; }

NumericVector<Number> & solution() override { return *_sys.solution; }
const NumericVector<Number> & solution() const override { return *_sys.solution; }

virtual System & system() override { return _sys; }
virtual const System & system() const override { return _sys; }

Expand Down Expand Up @@ -719,6 +716,8 @@ class NonlinearSystemBase : public SystemBase, public PerfGraphInterface
void mortarConstraints(bool displaced);

protected:
NumericVector<Number> & solutionInternal() const override { return *_sys.solution; }

/// solution vector from nonlinear solver
const NumericVector<Number> * _current_solution;
/// ghosted form of the residual
Expand Down Expand Up @@ -931,4 +930,7 @@ class NonlinearSystemBase : public SystemBase, public PerfGraphInterface
/// The required size of the derivative storage array
std::size_t _required_derivative_size;
#endif

/// The current states of the solution (0 = current, 1 = old, etc)
std::vector<NumericVector<Number> *> _solution_state;
};
54 changes: 47 additions & 7 deletions framework/include/systems/SystemBase.h
Expand Up @@ -212,14 +212,31 @@ class SystemBase : public libMesh::ParallelObject, public ConsoleStreamInterface
*/
virtual const NumericVector<Number> * const & currentSolution() const = 0;

virtual NumericVector<Number> & solution() = 0;
virtual NumericVector<Number> & solutionOld() = 0;
virtual NumericVector<Number> & solutionOlder() = 0;
virtual NumericVector<Number> * solutionPreviousNewton() = 0;
virtual const NumericVector<Number> & solution() const = 0;
virtual const NumericVector<Number> & solutionOld() const = 0;
virtual const NumericVector<Number> & solutionOlder() const = 0;
NumericVector<Number> & solution() { return solutionState(0); }
NumericVector<Number> & solutionOld() { return solutionState(1); }
NumericVector<Number> & solutionOlder() { return solutionState(2); }
const NumericVector<Number> & solution() const { return solutionState(0); }
const NumericVector<Number> & solutionOld() const { return solutionState(1); }
const NumericVector<Number> & solutionOlder() const { return solutionState(2); }

virtual const NumericVector<Number> * solutionPreviousNewton() const = 0;
virtual NumericVector<Number> * solutionPreviousNewton() = 0;

/**
* Get a state of the solution (0 = current, 1 = old, 2 = older, etc).
*
* If the state does not exist, it will be initialized in addition to any newer
* states before it that have not been initialized.
*/
NumericVector<Number> & solutionState(const unsigned int state);

/**
* Get a state of the solution (0 = current, 1 = old, 2 = older, etc).
*
* By default, up to state _default_solution_states is added. Any older states must be
* added using the non-const solutionState().
*/
const NumericVector<Number> & solutionState(const unsigned int state) const;

virtual Number & duDotDu() { return _du_dot_du; }
virtual Number & duDotDotDu() { return _du_dotdot_du; }
Expand Down Expand Up @@ -807,6 +824,20 @@ class SystemBase : public libMesh::ParallelObject, public ConsoleStreamInterface
void cacheVarIndicesByFace(const std::vector<VariableName> & vars);

protected:
/**
* Internal getters for the states of the solution as owned by libMesh.
*
* For the first three states (0 = current, 1 = old, 2 = older), we point directly to the
* solutions in libMesh (which is why these virtuals are needed). This allows us to store a more
* generalized set of solution states in _solution_states that also enables the addition of older
* states if we need them.
*/
///@{
virtual NumericVector<Number> & solutionInternal() const = 0;
virtual NumericVector<Number> & solutionOldInternal() const = 0;
virtual NumericVector<Number> & solutionOlderInternal() const = 0;
///@}

SubProblem & _subproblem;

MooseApp & _app;
Expand Down Expand Up @@ -875,6 +906,15 @@ class SystemBase : public libMesh::ParallelObject, public ConsoleStreamInterface

/// True if printing out additional information
bool _verbose;

/// The number of default solution states to store
unsigned int _default_solution_states;

private:
/// The solution states (0 = current, 1 = old, 2 = older, etc)
std::vector<NumericVector<Number> *> _solution_states;
/// The saved solution states (0 = current, 1 = old, 2 = older, etc)
std::vector<NumericVector<Number> *> _saved_solution_states;
};

#define PARALLEL_TRY
Expand Down