diff --git a/ProcessLib/AbstractJacobianAssembler.h b/ProcessLib/AbstractJacobianAssembler.h index 213c51dc142e3b685959e5fc7e32fd85494631dd..620968f8ddb0e2aa400c76b7906b52540717e078 100644 --- a/ProcessLib/AbstractJacobianAssembler.h +++ b/ProcessLib/AbstractJacobianAssembler.h @@ -16,9 +16,12 @@ namespace ProcessLib { class LocalAssemblerInterface; +//! Base class for Jacobian assemblers. class AbstractJacobianAssembler { public: + //! Assembles the Jacobian, the matrices \f$M\f$ and \f$K\f$, and the vector + //! \f$b\f$. virtual void assembleWithJacobian( LocalAssemblerInterface& local_assembler, double const t, std::vector<double> const& local_x, diff --git a/ProcessLib/AnalyticalJacobianAssembler.h b/ProcessLib/AnalyticalJacobianAssembler.h index 56ed30334a158ce802ba52e7142ddebe94c89918..b12d74ad6dbb2364229ed382328730bee939a8f6 100644 --- a/ProcessLib/AnalyticalJacobianAssembler.h +++ b/ProcessLib/AnalyticalJacobianAssembler.h @@ -19,9 +19,15 @@ class ConfigTree; namespace ProcessLib { +//! Assembles the Jacobian matrix using a provided "analytical" method from the +//! local assembler. class AnalyticalJacobianAssembler final : public AbstractJacobianAssembler { public: + //! Assembles the Jacobian, the matrices \f$M\f$ and \f$K\f$, and the vector + //! \f$b\f$. + //! In this implementation the call is only forwarded to the respective + //! method of the given \c local_assembler. void assembleWithJacobian( LocalAssemblerInterface& local_assembler, double const t, std::vector<double> const& local_x, diff --git a/ProcessLib/CentralDifferencesJacobianAssembler.cpp b/ProcessLib/CentralDifferencesJacobianAssembler.cpp index 62e2875e94f68aaf9ebd4df987099293e38b1ab0..77b88b3a12a0ee6c060cb48b2c9710defcd2d8a3 100644 --- a/ProcessLib/CentralDifferencesJacobianAssembler.cpp +++ b/ProcessLib/CentralDifferencesJacobianAssembler.cpp @@ -18,6 +18,8 @@ CentralDifferencesJacobianAssembler::CentralDifferencesJacobianAssembler( std::vector<double>&& absolute_epsilons) : _absolute_epsilons(std::move(absolute_epsilons)) { + if (_absolute_epsilons.empty()) + OGS_FATAL("No values for the absolute epsilons have been given."); } void CentralDifferencesJacobianAssembler::assembleWithJacobian( @@ -59,6 +61,7 @@ void CentralDifferencesJacobianAssembler::assembleWithJacobian( // afterwards. for (Eigen::MatrixXd::Index i = 0; i < num_r_c; ++i) { + // assume that local_x_data is ordered by component. auto const component = i / num_dofs_per_component; auto const eps = _absolute_epsilons[component]; diff --git a/ProcessLib/CentralDifferencesJacobianAssembler.h b/ProcessLib/CentralDifferencesJacobianAssembler.h index 38b1aad7b301f2831428186d728155ef09b40807..d99033cc2695598b16f26f1a478b51d1d5edd3c5 100644 --- a/ProcessLib/CentralDifferencesJacobianAssembler.h +++ b/ProcessLib/CentralDifferencesJacobianAssembler.h @@ -20,12 +20,35 @@ class ConfigTree; namespace ProcessLib { +//! Assembles the Jacobian matrix using central differences. class CentralDifferencesJacobianAssembler : public AbstractJacobianAssembler { public: + //! Constructs a new instance. + //! + //! \param absolute_epsilons perturbations of the components of the local + //! solution vector used for evaluating the finite differences. + //! + //! \note The size of \c absolute_epsilons defines the "number of + //! components" of the local solution vector (This is not the number of + //! elements of the vector!). Therefore the size of the local solution + //! vector must be divisible by the size of \c absolute_epsilons. This is + //! the only consistency check performed. It is not checked whether said + //! "number of components" is sensible. E.g., one could pass one epsilon per + //! node, which would be valid but would not make sense at all. explicit CentralDifferencesJacobianAssembler( std::vector<double>&& absolute_epsilons); + //! Assembles the Jacobian, the matrices \f$M\f$ and \f$K\f$, and the vector + //! \f$b\f$. + //! For the assembly the assemble() method of the given \c local_assembler + //! is called several times and the Jacobian is built from finite + //! differences. + //! The number of calls of the assemble() method is \f$2N+1\f$ if \f$N\f$ is + //! the size of \c local_x. + //! + //! \attention It is assumed that the local vectors and matrices are ordered + //! by component. void assembleWithJacobian( LocalAssemblerInterface& local_assembler, double const t, std::vector<double> const& local_x, @@ -36,6 +59,9 @@ public: private: std::vector<double> const _absolute_epsilons; + + // temporary data only stored here in order to avoid frequent memory + // reallocations. std::vector<double> _local_M_data; std::vector<double> _local_K_data; std::vector<double> _local_b_data;