https://gitlab.opengeosys.org/ogs/ogs.git
Raw File
Tip revision: 18d3df277cc9b7539ea9852fd73adf47fdbbc9c1 authored by Dmitri Naumov on 12 June 2021, 11:20:20 UTC
[PL/TH2M] Stress/strain/saturation IP output.
Tip revision: 18d3df2
CreateTimeLoop.cpp
/**
 * \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<TimeLoop> createTimeLoop(
    BaseLib::ConfigTree const& config, std::string const& output_directory,
    const std::vector<std::unique_ptr<Process>>& processes,
    const std::map<std::string, std::unique_ptr<NumLib::NonlinearSolverBase>>&
        nonlinear_solvers,
    std::vector<std::unique_ptr<MeshLib::Mesh>> const& meshes)
{
    auto const& coupling_config
        //! \ogs_file_param{prj__time_loop__global_process_coupling}
        = config.getConfigSubtreeOptional("global_process_coupling");

    std::vector<std::unique_ptr<NumLib::ConvergenceCriterion>>
        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<int>("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<ProcessData> const& a,
           std::unique_ptr<ProcessData> 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<TimeLoop>(
        std::move(output), std::move(per_process_data), max_coupling_iterations,
        std::move(global_coupling_conv_criteria), start_time, end_time);
}
}  // namespace ProcessLib
back to top