From 0be2ee6810a7024f8e411cf65a5ccf805b8a6111 Mon Sep 17 00:00:00 2001 From: Francesco Parisio <francesco.parisio@protonmail.com> Date: Fri, 10 Feb 2017 12:11:23 +0100 Subject: [PATCH] Add ode system preAssemble() call. In some processes (using non-local methods, for example) the assembly is split in two parts: computation of local quantities and actual (non-local) assembly (integration) into the local matrices. --- NumLib/ODESolver/ODESystem.h | 7 +++++++ NumLib/ODESolver/TimeDiscretizedODESystem.cpp | 2 ++ ProcessLib/LocalAssemblerInterface.h | 3 +++ ProcessLib/Process.cpp | 5 +++++ ProcessLib/Process.h | 7 +++++++ ProcessLib/VectorMatrixAssembler.cpp | 11 +++++++++++ ProcessLib/VectorMatrixAssembler.h | 5 +++++ Tests/NumLib/ODEs.h | 6 ++++++ 8 files changed, 46 insertions(+) diff --git a/NumLib/ODESolver/ODESystem.h b/NumLib/ODESolver/ODESystem.h index b362403f9b5..7dd004d058d 100644 --- a/NumLib/ODESolver/ODESystem.h +++ b/NumLib/ODESolver/ODESystem.h @@ -44,6 +44,9 @@ public: static const ODESystemTag ODETag = ODESystemTag::FirstOrderImplicitQuasilinear; + //! Calls process' pre-assembly with the provided state (\c t, \c x). + virtual void preAssemble(const double t, GlobalVector const& x) = 0; + //! Assemble \c M, \c K and \c b at the provided state (\c t, \c x). virtual void assemble( const double t, GlobalVector const& x, GlobalMatrix& M, GlobalMatrix& K, @@ -73,6 +76,10 @@ class ODESystem<ODESystemTag::FirstOrderImplicitQuasilinear, NonlinearSolverTag::Picard> { public: + + //! Calls process' pre-assembly with the provided state (\c t, \c x). + virtual void preAssemble(const double t, GlobalVector const& x) = 0; + /*! Assemble \c M, \c K, \c b and the Jacobian * \f$ \mathtt{Jac} := \partial r/\partial x_N \f$ * at the provided state (\c t, \c x). diff --git a/NumLib/ODESolver/TimeDiscretizedODESystem.cpp b/NumLib/ODESolver/TimeDiscretizedODESystem.cpp index a1b6f29685c..064c3d40c56 100644 --- a/NumLib/ODESolver/TimeDiscretizedODESystem.cpp +++ b/NumLib/ODESolver/TimeDiscretizedODESystem.cpp @@ -84,6 +84,7 @@ void TimeDiscretizedODESystem<ODESystemTag::FirstOrderImplicitQuasilinear, _b->setZero(); _Jac->setZero(); + _ode.preAssemble(t, x_curr); _ode.assembleWithJacobian(t, x_curr, xdot, dxdot_dx, dx_dx, *_M, *_K, *_b, *_Jac); @@ -186,6 +187,7 @@ void TimeDiscretizedODESystem<ODESystemTag::FirstOrderImplicitQuasilinear, _K->setZero(); _b->setZero(); + _ode.preAssemble(t, x_curr); _ode.assemble(t, x_curr, *_M, *_K, *_b); LinAlg::finalizeAssembly(*_M); diff --git a/ProcessLib/LocalAssemblerInterface.h b/ProcessLib/LocalAssemblerInterface.h index bfb983f87d4..e3fc5cb7983 100644 --- a/ProcessLib/LocalAssemblerInterface.h +++ b/ProcessLib/LocalAssemblerInterface.h @@ -35,6 +35,9 @@ class LocalAssemblerInterface public: virtual ~LocalAssemblerInterface() = default; + virtual void preAssemble(double const /*t*/, + std::vector<double> const& /*local_x*/){}; + virtual void assemble(double const t, std::vector<double> const& local_x, std::vector<double>& local_M_data, std::vector<double>& local_K_data, diff --git a/ProcessLib/Process.cpp b/ProcessLib/Process.cpp index 808bb909c59..119e9063dd9 100644 --- a/ProcessLib/Process.cpp +++ b/ProcessLib/Process.cpp @@ -132,6 +132,11 @@ MathLib::MatrixSpecifications Process::getMatrixSpecifications() const &l.getGhostIndices(), &_sparsity_pattern}; } +void Process::preAssemble(const double t, GlobalVector const& x) +{ + preAssembleConcreteProcess(t, x); +} + void Process::assemble(const double t, GlobalVector const& x, GlobalMatrix& M, GlobalMatrix& K, GlobalVector& b) { diff --git a/ProcessLib/Process.h b/ProcessLib/Process.h index d067d0ff747..ef2ef4d1b09 100644 --- a/ProcessLib/Process.h +++ b/ProcessLib/Process.h @@ -77,6 +77,8 @@ public: _coupled_solutions = coupled_solutions; } + void preAssemble(const double t, GlobalVector const& x) override final; + virtual void setCoupledSolutionsForStaggeredSchemeToLocalAssemblers() {} void assemble(const double t, GlobalVector const& x, GlobalMatrix& M, GlobalMatrix& K, GlobalVector& b) final; @@ -142,6 +144,11 @@ private: MeshLib::Mesh const& mesh, unsigned const integration_order) = 0; + virtual void preAssembleConcreteProcess(const double /*t*/, + GlobalVector const& /*x*/) + { + } + virtual void assembleConcreteProcess(const double t, GlobalVector const& x, GlobalMatrix& M, GlobalMatrix& K, GlobalVector& b) = 0; diff --git a/ProcessLib/VectorMatrixAssembler.cpp b/ProcessLib/VectorMatrixAssembler.cpp index 398c7a5d45b..690c9bcc23c 100644 --- a/ProcessLib/VectorMatrixAssembler.cpp +++ b/ProcessLib/VectorMatrixAssembler.cpp @@ -55,6 +55,17 @@ VectorMatrixAssembler::VectorMatrixAssembler( { } +void VectorMatrixAssembler::preAssemble( + const std::size_t mesh_item_id, LocalAssemblerInterface& local_assembler, + const NumLib::LocalToGlobalIndexMap& dof_table, const double t, + const GlobalVector& x) +{ + auto const indices = NumLib::getIndices(mesh_item_id, dof_table); + auto const local_x = x.get(indices); + + local_assembler.preAssemble(t, local_x); +} + void VectorMatrixAssembler::assemble( const std::size_t mesh_item_id, LocalAssemblerInterface& local_assembler, const NumLib::LocalToGlobalIndexMap& dof_table, const double t, diff --git a/ProcessLib/VectorMatrixAssembler.h b/ProcessLib/VectorMatrixAssembler.h index 5f305cc482b..a1203361b4d 100644 --- a/ProcessLib/VectorMatrixAssembler.h +++ b/ProcessLib/VectorMatrixAssembler.h @@ -33,6 +33,11 @@ public: explicit VectorMatrixAssembler( std::unique_ptr<AbstractJacobianAssembler>&& jacobian_assembler); + void preAssemble(const std::size_t mesh_item_id, + LocalAssemblerInterface& local_assembler, + const NumLib::LocalToGlobalIndexMap& dof_table, + const double t, const GlobalVector& x); + //! Assembles\c M, \c K, and \c b. //! \remark Jacobian is not assembled here, see assembleWithJacobian(). void assemble(std::size_t const mesh_item_id, diff --git a/Tests/NumLib/ODEs.h b/Tests/NumLib/ODEs.h index f5326f712ff..fbe3f271563 100644 --- a/Tests/NumLib/ODEs.h +++ b/Tests/NumLib/ODEs.h @@ -26,6 +26,8 @@ class ODE1 final : public NumLib::ODESystem< NumLib::NonlinearSolverTag::Newton> { public: + void preAssemble(const double t, GlobalVector const& x) override {} + void assemble(const double /*t*/, GlobalVector const& /*x*/, GlobalMatrix& M, GlobalMatrix& K, GlobalVector& b) override { @@ -102,6 +104,8 @@ class ODE2 final : public NumLib::ODESystem< NumLib::NonlinearSolverTag::Newton> { public: + void preAssemble(const double t, GlobalVector const& x) override {} + void assemble(const double /*t*/, GlobalVector const& x, GlobalMatrix& M, GlobalMatrix& K, GlobalVector& b) override { @@ -187,6 +191,8 @@ class ODE3 final : public NumLib::ODESystem< NumLib::NonlinearSolverTag::Newton> { public: + void preAssemble(const double t, GlobalVector const& x) override {} + void assemble(const double /*t*/, GlobalVector const& x_curr, GlobalMatrix& M, GlobalMatrix& K, GlobalVector& b) override { -- GitLab