/** * \file * * \copyright * Copyright (c) 2012-2021, OpenGeoSys Community (http://www.opengeosys.org) * Distributed under a Modified BSD License. * See accompanying file LICENSE.txt or * http://www.opengeosys.org/project/license */ #include "CreateTimeLoop.h" #include "BaseLib/ConfigTree.h" #include "ProcessLib/CreateProcessData.h" #include "ProcessLib/Output/CreateOutput.h" #include "ProcessLib/Output/Output.h" #include "TimeLoop.h" namespace ProcessLib { std::unique_ptr createTimeLoop( BaseLib::ConfigTree const& config, std::string const& output_directory, const std::vector>& processes, const std::map>& nonlinear_solvers, std::vector> const& meshes) { auto const& coupling_config //! \ogs_file_param{prj__time_loop__global_process_coupling} = config.getConfigSubtreeOptional("global_process_coupling"); std::vector> global_coupling_conv_criteria; int max_coupling_iterations = 1; if (coupling_config) { max_coupling_iterations //! \ogs_file_param{prj__time_loop__global_process_coupling__max_iter} = coupling_config->getConfigParameter("max_iter"); auto const& coupling_convergence_criteria_config = //! \ogs_file_param{prj__time_loop__global_process_coupling__convergence_criteria} coupling_config->getConfigSubtree("convergence_criteria"); for ( auto coupling_convergence_criterion_config : //! \ogs_file_param{prj__time_loop__global_process_coupling__convergence_criteria__convergence_criterion} coupling_convergence_criteria_config.getConfigSubtreeList( "convergence_criterion")) { global_coupling_conv_criteria.push_back( NumLib::createConvergenceCriterion( coupling_convergence_criterion_config)); } } auto output = //! \ogs_file_param{prj__time_loop__output} createOutput(config.getConfigSubtree("output"), output_directory, meshes); auto per_process_data = createPerProcessData( //! \ogs_file_param{prj__time_loop__processes} config.getConfigSubtree("processes"), processes, nonlinear_solvers); if (coupling_config) { if (global_coupling_conv_criteria.size() != per_process_data.size()) { OGS_FATAL( "The number of convergence criteria of the global staggered " "coupling loop is not identical to the number of the " "processes! Please check the element by tag " "global_process_coupling in the project file."); } } const auto minmax_iter = std::minmax_element( per_process_data.begin(), per_process_data.end(), [](std::unique_ptr const& a, std::unique_ptr const& b) { return (a->timestepper->end() < b->timestepper->end()); }); const double start_time = per_process_data[minmax_iter.first - per_process_data.begin()] ->timestepper->begin(); const double end_time = per_process_data[minmax_iter.second - per_process_data.begin()] ->timestepper->end(); return std::make_unique( std::move(output), std::move(per_process_data), max_coupling_iterations, std::move(global_coupling_conv_criteria), start_time, end_time); } } // namespace ProcessLib