From d4886543efe401e5e3f9de0f577d7c20d3590db4 Mon Sep 17 00:00:00 2001 From: Wenqing Wang <wenqing.wang@ufz.de> Date: Thu, 19 Jan 2017 16:23:22 +0100 Subject: [PATCH] [Coupling] Changed one member type from pointer to reference and added more documentations about the staggered scheme --- ProcessLib/StaggeredCouplingTerm.cpp | 2 +- ProcessLib/StaggeredCouplingTerm.h | 34 ++++++++++++++++++++--- ProcessLib/UncoupledProcessesTimeLoop.cpp | 29 +++++++++++++------ ProcessLib/UncoupledProcessesTimeLoop.h | 17 ++++++++---- ProcessLib/VectorMatrixAssembler.cpp | 6 ++-- 5 files changed, 66 insertions(+), 22 deletions(-) diff --git a/ProcessLib/StaggeredCouplingTerm.cpp b/ProcessLib/StaggeredCouplingTerm.cpp index 76c77a949a9..1a16e880868 100644 --- a/ProcessLib/StaggeredCouplingTerm.cpp +++ b/ProcessLib/StaggeredCouplingTerm.cpp @@ -18,7 +18,7 @@ namespace ProcessLib const StaggeredCouplingTerm createVoidStaggeredCouplingTerm() { std::map<ProcessType, Process const&> coupled_pcsss; - std::map<ProcessType, GlobalVector const*> coupled_xs; + std::map<ProcessType, GlobalVector const&> coupled_xs; const bool empty = true; return StaggeredCouplingTerm(coupled_pcsss, coupled_xs, 0.0, empty); } diff --git a/ProcessLib/StaggeredCouplingTerm.h b/ProcessLib/StaggeredCouplingTerm.h index 24bf9eceb66..a9f31147bea 100644 --- a/ProcessLib/StaggeredCouplingTerm.h +++ b/ProcessLib/StaggeredCouplingTerm.h @@ -21,23 +21,45 @@ namespace ProcessLib { class Process; + +/** + * A struct to keep the references of the coupled processes and the references + * of the current solutions of the equations of the coupled processes. + * + * During un-coupling iteration, an instance of this struct is created and + * passed through interfaces to global and local assemblers for each process. + */ struct StaggeredCouplingTerm { StaggeredCouplingTerm( std::map<ProcessType, Process const&> const& coupled_processes_, - std::map<ProcessType, GlobalVector const*> const& coupled_xs_, + std::map<ProcessType, GlobalVector const&> const& coupled_xs_, const double dt_, const bool empty_ = false) : coupled_processes(coupled_processes_), coupled_xs(coupled_xs_), dt(dt_), empty(empty_) { } + /// References to the coupled processes are distinguished by the keys of + /// process types. 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; + + /// References to the current solutions of the coupled processes. + /// The coupled solutions are distinguished by the keys of process types. + std::map<ProcessType, GlobalVector const&> const& coupled_xs; + + const double dt; ///< Time step size. + const bool empty; ///< Flag to indicate whether the couping term is empty. }; +/** + * A struct to keep the references of the coupled processes, and local element + * solutions of the current and previous time step solutions of the equations + * of the coupled processes. + * + * During the global assembly loop, an instance of this struct is created for + * each element and it is then passed to local assemblers. + */ struct LocalCouplingTerm { LocalCouplingTerm(const double dt_, @@ -52,13 +74,17 @@ struct LocalCouplingTerm const double dt; ///< Time step size. + /// References to the coupled processes are distinguished by the keys of + /// process types. 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; }; +/// A function to create a void instance of StaggeredCouplingTerm; const StaggeredCouplingTerm createVoidStaggeredCouplingTerm(); } // end of ProcessLib diff --git a/ProcessLib/UncoupledProcessesTimeLoop.cpp b/ProcessLib/UncoupledProcessesTimeLoop.cpp index a6aa357a71d..d0e04085ec0 100644 --- a/ProcessLib/UncoupledProcessesTimeLoop.cpp +++ b/ProcessLib/UncoupledProcessesTimeLoop.cpp @@ -150,6 +150,7 @@ struct SingleProcessData NumLib::InternalMatrixStorage* mat_strg = nullptr; Process& process; + /// Coupled processes. std::map<ProcessType, Process const&> const coupled_processes; ProcessOutput process_output; }; @@ -487,20 +488,29 @@ UncoupledProcessesTimeLoop::UncoupledProcessesTimeLoop( { } +/** + * This function fills the vector of solutions of coupled processes of + * processes, _solutions_of_coupled_processes, and initializes the vector of + * solutions of the previous coupling iteration, + * _solutions_of_last_cpl_iteration. + * + * \return a boolean value as a flag to indicate there should be a coupling + * among process or not. + */ bool UncoupledProcessesTimeLoop::setCoupledSolutions() { if (!_global_coupling_conv_crit && _global_coupling_max_iterations == 1) return false; unsigned pcs_idx = 0; - _solutions_of_coupled_processes.resize(_per_process_data.size()); + _solutions_of_coupled_processes.reserve(_per_process_data.size()); for (auto& spd : _per_process_data) { BaseLib::RunTime time_timestep_process; time_timestep_process.start(); auto const& coupled_processes = spd->coupled_processes; - std::map<ProcessType, GlobalVector const*> coupled_xs; + std::map<ProcessType, GlobalVector const&> coupled_xs; auto it = coupled_processes.begin(); while (it != coupled_processes.end()) { @@ -517,16 +527,15 @@ bool UncoupledProcessesTimeLoop::setCoupledSolutions() if (found_item != _per_process_data.end()) { // Id of the coupled process: - const std::size_t c_id = - found_item - _per_process_data.begin(); + const std::size_t c_id = found_item - _per_process_data.begin(); - BaseLib::insertMapIfKeyUniqueElseError(coupled_xs, it->first, - _process_solutions[c_id], - "global_coupled_x"); + BaseLib::insertMapIfKeyUniqueElseError( + coupled_xs, it->first, *_process_solutions[c_id], + "global_coupled_x"); } it++; } - _solutions_of_coupled_processes[pcs_idx] = coupled_xs; + _solutions_of_coupled_processes.emplace_back(coupled_xs); const auto x = _process_solutions[pcs_idx]; @@ -604,6 +613,7 @@ bool UncoupledProcessesTimeLoop::loop() timestep, t, delta_t); bool coupling_iteration_converged = true; + // Coupling iteration for (unsigned i = 0; i < _global_coupling_max_iterations; i++) { // TODO use process name @@ -615,11 +625,12 @@ bool UncoupledProcessesTimeLoop::loop() time_timestep_process.start(); auto& x = *_process_solutions[pcs_idx]; - if (i==0) + if (i == 0) pcs.preTimestep(x, t, delta_t); if (is_staggered_coupling) { + // Create a coupling term if (i == 0) _global_coupling_conv_crit->preFirstIteration(); else diff --git a/ProcessLib/UncoupledProcessesTimeLoop.h b/ProcessLib/UncoupledProcessesTimeLoop.h index ef829722aeb..b9981da3060 100644 --- a/ProcessLib/UncoupledProcessesTimeLoop.h +++ b/ProcessLib/UncoupledProcessesTimeLoop.h @@ -54,17 +54,24 @@ private: const unsigned _global_coupling_max_iterations; /// Convergence criteria of the global coupling iterations. std::unique_ptr<NumLib::ConvergenceCriterion> _global_coupling_conv_crit; - std::vector<std::map<ProcessType, GlobalVector const*>> - _solutions_of_coupled_processes; - /// Solutions of the previous coupling iteration. + + /** + * Vector of solutions of coupled processes of processes. + * Each vector element stores the references of the solution vectors + * (stored in _process_solutions) of the coupled processes of a process. + */ + std::vector<std::map<ProcessType, GlobalVector const&>> + _solutions_of_coupled_processes; + + /// Solutions of the previous coupling iteration for the convergence + /// criteria of the coupling iteration. std::vector<GlobalVector*> _solutions_of_last_cpl_iteration; }; //! Builds an UncoupledProcessesTimeLoop from the given configuration. std::unique_ptr<UncoupledProcessesTimeLoop> createUncoupledProcessesTimeLoop( BaseLib::ConfigTree const& config, std::string const& output_directory, - std::map<std::string, std::unique_ptr<Process>> const& - processes, + std::map<std::string, std::unique_ptr<Process>> const& processes, std::map<std::string, std::unique_ptr<NumLib::NonlinearSolverBase>> const& nonlinear_solvers); diff --git a/ProcessLib/VectorMatrixAssembler.cpp b/ProcessLib/VectorMatrixAssembler.cpp index 08fb297c0c8..7071f84b0c9 100644 --- a/ProcessLib/VectorMatrixAssembler.cpp +++ b/ProcessLib/VectorMatrixAssembler.cpp @@ -52,7 +52,7 @@ getPreviousLocalSolutionsOfCoupledProcesses( static std::map<ProcessLib::ProcessType, const std::vector<double>> getCurrentLocalSolutionsOfCoupledProcesses( - const std::map<ProcessType, GlobalVector const*>& global_coupled_xs, + const std::map<ProcessType, GlobalVector const&>& global_coupled_xs, const std::vector<GlobalIndexType>& indices) { std::map<ProcessLib::ProcessType, const std::vector<double>> @@ -60,8 +60,8 @@ getCurrentLocalSolutionsOfCoupledProcesses( 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); + auto 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++; -- GitLab