diff --git a/ProcessLib/LocalAssemblerInterface.h b/ProcessLib/LocalAssemblerInterface.h index aeb7329343ddb73af011d18f51c260780f2b5ea9..3cb9d7b64dacf9863e3bc1f6214fc5d5a010d511 100644 --- a/ProcessLib/LocalAssemblerInterface.h +++ b/ProcessLib/LocalAssemblerInterface.h @@ -36,11 +36,12 @@ public: std::vector<double>& local_M_data, std::vector<double>& local_K_data, std::vector<double>& local_b_data) = 0; - virtual void coupling_assemble( - double const t, std::vector<double> const& local_x, - std::vector<double>& local_M_data, std::vector<double>& local_K_data, - std::vector<double>& local_b_data, - LocalCouplingTerm const& coupled_term); + virtual void coupling_assemble(double const t, + std::vector<double> const& local_x, + std::vector<double>& local_M_data, + std::vector<double>& local_K_data, + std::vector<double>& local_b_data, + LocalCouplingTerm const& coupled_term); virtual void assembleWithJacobian(double const t, std::vector<double> const& local_x, diff --git a/ProcessLib/Process.h b/ProcessLib/Process.h index 1f55b9e9b6411a4ded91aa7c88ba5d602eb446d2..73ab1bc0395e948e0b63141110b228e39bbbc727 100644 --- a/ProcessLib/Process.h +++ b/ProcessLib/Process.h @@ -111,6 +111,12 @@ public: return _secondary_variables; } + // Get the solution of the previous time step. + virtual GlobalVector* getPreviousTimeStepSolution() const + { + return nullptr; + } + // Used as a call back for CalculateSurfaceFlux process. virtual std::vector<double> getFlux(std::size_t /*element_id*/, MathLib::Point3d const& /*p*/, diff --git a/ProcessLib/StaggeredCouplingTerm.cpp b/ProcessLib/StaggeredCouplingTerm.cpp index 5cf8ed0aa773c4e2e1986b5ee3994cc74b43d26a..76c77a949a9a6e3e89a38d032a0c1776a13ecabd 100644 --- a/ProcessLib/StaggeredCouplingTerm.cpp +++ b/ProcessLib/StaggeredCouplingTerm.cpp @@ -20,7 +20,7 @@ const StaggeredCouplingTerm createVoidStaggeredCouplingTerm() std::map<ProcessType, Process const&> coupled_pcsss; std::map<ProcessType, GlobalVector const*> coupled_xs; const bool empty = true; - return StaggeredCouplingTerm(coupled_pcsss, coupled_xs, empty); + return StaggeredCouplingTerm(coupled_pcsss, coupled_xs, 0.0, empty); } } // end of ProcessLib diff --git a/ProcessLib/StaggeredCouplingTerm.h b/ProcessLib/StaggeredCouplingTerm.h index c488fa38eb7e6a44edec6948bcda23576a5ac722..24bf9eceb66db7d26f76f160a69f74a262282de9 100644 --- a/ProcessLib/StaggeredCouplingTerm.h +++ b/ProcessLib/StaggeredCouplingTerm.h @@ -26,28 +26,36 @@ struct StaggeredCouplingTerm StaggeredCouplingTerm( std::map<ProcessType, Process const&> const& coupled_processes_, std::map<ProcessType, GlobalVector const*> const& coupled_xs_, - const bool empty_ = false) + const double dt_, const bool empty_ = false) : coupled_processes(coupled_processes_), coupled_xs(coupled_xs_), - empty(empty_) + dt(dt_), empty(empty_) { } std::map<ProcessType, Process const&> const& coupled_processes; std::map<ProcessType, GlobalVector const*> const& coupled_xs; + const double dt; ///< Time step size. const bool empty; }; struct LocalCouplingTerm { - LocalCouplingTerm( + LocalCouplingTerm(const double dt_, std::map<ProcessType, Process const&> const& coupled_processes_, + std::map<ProcessType, const std::vector<double>>&& local_coupled_xs0_, std::map<ProcessType, const std::vector<double>>&& local_coupled_xs_) - : coupled_processes(coupled_processes_), + : dt(dt_), coupled_processes(coupled_processes_), + local_coupled_xs0(std::move(local_coupled_xs0_)), local_coupled_xs(std::move(local_coupled_xs_)) { } + const double dt; ///< Time step size. + std::map<ProcessType, Process const&> const& coupled_processes; + /// Local solutions of the previous time step. + std::map<ProcessType, const std::vector<double>> const local_coupled_xs0; + /// Local solutions of the current time step. std::map<ProcessType, const std::vector<double>> const local_coupled_xs; }; diff --git a/ProcessLib/UncoupledProcessesTimeLoop.cpp b/ProcessLib/UncoupledProcessesTimeLoop.cpp index c7489c21488fb4cfc897a655cee5279a00774bcc..a6aa357a71d1388f9b32dbfef0430d93e90eb42c 100644 --- a/ProcessLib/UncoupledProcessesTimeLoop.cpp +++ b/ProcessLib/UncoupledProcessesTimeLoop.cpp @@ -626,7 +626,7 @@ bool UncoupledProcessesTimeLoop::loop() _global_coupling_conv_crit->setNoFirstIteration(); StaggeredCouplingTerm coupled_term( spd->coupled_processes, - _solutions_of_coupled_processes[pcs_idx]); + _solutions_of_coupled_processes[pcs_idx], delta_t); nonlinear_solver_succeeded = solveOneTimeStepOneProcess( x, timestep, t, delta_t, *spd, coupled_term, *_output); diff --git a/ProcessLib/VectorMatrixAssembler.cpp b/ProcessLib/VectorMatrixAssembler.cpp index 73f6681f00b7beb0e3627a81586d0e05e83893e0..08fb297c0c858d228fdc72d49878032671b4d3d0 100644 --- a/ProcessLib/VectorMatrixAssembler.cpp +++ b/ProcessLib/VectorMatrixAssembler.cpp @@ -19,6 +19,56 @@ namespace ProcessLib { +static std::map<ProcessLib::ProcessType, const std::vector<double>> +getPreviousLocalSolutionsOfCoupledProcesses( + const StaggeredCouplingTerm& coupled_term, + const std::vector<GlobalIndexType>& indices) +{ + std::map<ProcessLib::ProcessType, const std::vector<double>> + local_coupled_xs0; + auto it = coupled_term.coupled_processes.begin(); + while (it != coupled_term.coupled_processes.end()) + { + auto const& coupled_pcs = it->second; + auto const prevous_time_x = coupled_pcs.getPreviousTimeStepSolution(); + if (prevous_time_x) + { + auto const local_coupled_x0 = prevous_time_x->get(indices); + BaseLib::insertMapIfKeyUniqueElseError(local_coupled_xs0, it->first, + local_coupled_x0, + "local_coupled_x0"); + } + else + { + const std::vector<double> local_coupled_x0; + BaseLib::insertMapIfKeyUniqueElseError(local_coupled_xs0, it->first, + local_coupled_x0, + "local_coupled_x0"); + } + it++; + } + return local_coupled_xs0; +} + +static std::map<ProcessLib::ProcessType, const std::vector<double>> +getCurrentLocalSolutionsOfCoupledProcesses( + const std::map<ProcessType, GlobalVector const*>& global_coupled_xs, + const std::vector<GlobalIndexType>& indices) +{ + std::map<ProcessLib::ProcessType, const std::vector<double>> + local_coupled_xs; + auto it = global_coupled_xs.begin(); + while (it != global_coupled_xs.end()) + { + GlobalVector const* coupled_x = it->second; + auto const local_coupled_x = coupled_x->get(indices); + BaseLib::insertMapIfKeyUniqueElseError( + local_coupled_xs, it->first, local_coupled_x, "local_coupled_x"); + it++; + } + return local_coupled_xs; +} + VectorMatrixAssembler::VectorMatrixAssembler( std::unique_ptr<AbstractJacobianAssembler>&& jacobian_assembler) : _jacobian_assembler(std::move(jacobian_assembler)) @@ -45,21 +95,13 @@ void VectorMatrixAssembler::assemble( } else { - std::map<ProcessLib::ProcessType, const std::vector<double>> - local_coupled_xs; - auto it = coupled_term.coupled_xs.begin(); - while (it != coupled_term.coupled_xs.end()) - { - GlobalVector const* coupled_x = it->second; - auto const local_coupled_x = coupled_x->get(indices); - BaseLib::insertMapIfKeyUniqueElseError(local_coupled_xs, it->first, - local_coupled_x, - "local_coupled_x"); - it++; - } - + auto local_coupled_xs0 = + getPreviousLocalSolutionsOfCoupledProcesses(coupled_term, indices); + auto local_coupled_xs = getCurrentLocalSolutionsOfCoupledProcesses( + coupled_term.coupled_xs, indices); ProcessLib::LocalCouplingTerm local_coupling_term( - coupled_term.coupled_processes, std::move(local_coupled_xs)); + coupled_term.dt, coupled_term.coupled_processes, + std::move(local_coupled_xs0), std::move(local_coupled_xs)); local_assembler.coupling_assemble(t, local_x, _local_M_data, _local_K_data, _local_b_data, @@ -111,21 +153,13 @@ void VectorMatrixAssembler::assembleWithJacobian( } else { - std::map<ProcessLib::ProcessType, const std::vector<double>> - local_coupled_xs; - auto it = coupled_term.coupled_xs.begin(); - while (it != coupled_term.coupled_xs.end()) - { - GlobalVector const* coupled_x = it->second; - auto const local_coupled_x = coupled_x->get(indices); - BaseLib::insertMapIfKeyUniqueElseError(local_coupled_xs, it->first, - local_coupled_x, - "local_coupled_x"); - it++; - } - + auto local_coupled_xs0 = + getPreviousLocalSolutionsOfCoupledProcesses(coupled_term, indices); + auto local_coupled_xs = getCurrentLocalSolutionsOfCoupledProcesses( + coupled_term.coupled_xs, indices); ProcessLib::LocalCouplingTerm local_coupling_term( - coupled_term.coupled_processes, std::move(local_coupled_xs)); + coupled_term.dt, coupled_term.coupled_processes, + std::move(local_coupled_xs0), std::move(local_coupled_xs)); _jacobian_assembler->coupling_assembleWithJacobian( local_assembler, t, local_x, local_xdot, dxdot_dx, dx_dx, diff --git a/ProcessLib/VectorMatrixAssembler.h b/ProcessLib/VectorMatrixAssembler.h index 5466d6d71c008aff6937f077fcf5f3038e7e3020..26046c82ab5bc1e63dcbe1b495b06ac62352e73a 100644 --- a/ProcessLib/VectorMatrixAssembler.h +++ b/ProcessLib/VectorMatrixAssembler.h @@ -66,4 +66,4 @@ private: std::unique_ptr<AbstractJacobianAssembler> _jacobian_assembler; }; -} // namespace ProcessLib +} // namespace ProcessLib