2022-12-13 07:05:17 -06:00
|
|
|
/*
|
|
|
|
Copyright 2022 Equinor.
|
|
|
|
|
|
|
|
This file is part of the Open Porous Media project (OPM).
|
|
|
|
|
|
|
|
OPM is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
OPM is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#define BOOST_TEST_MODULE TestConvergenceOutputConfiguration
|
|
|
|
|
|
|
|
#include <boost/test/unit_test.hpp>
|
|
|
|
|
|
|
|
#include <opm/simulators/flow/ConvergenceOutputConfiguration.hpp>
|
|
|
|
|
|
|
|
#include <cstddef>
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <string_view>
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_SUITE(Common_Operations)
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(None)
|
|
|
|
{
|
|
|
|
const auto config = Opm::ConvergenceOutputConfiguration{"none"};
|
|
|
|
BOOST_CHECK_MESSAGE(! config.any(),
|
|
|
|
"Configuration object with option value "
|
|
|
|
"\"none\" must NOT activate output");
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(Steps)
|
|
|
|
{
|
|
|
|
const auto config = Opm::ConvergenceOutputConfiguration{"steps"};
|
|
|
|
BOOST_CHECK_MESSAGE(config.any(),
|
|
|
|
"Configuration object with supported "
|
|
|
|
"option value must activate option");
|
|
|
|
BOOST_CHECK_MESSAGE(config.want(Opm::ConvergenceOutputConfiguration::Option::Steps),
|
|
|
|
"Configuration object with \"steps\" "
|
|
|
|
"option value must activate Steps option");
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(Steps_Alias)
|
|
|
|
{
|
|
|
|
const auto config = Opm::ConvergenceOutputConfiguration{"step"};
|
|
|
|
BOOST_CHECK_MESSAGE(config.any(),
|
|
|
|
"Configuration object with supported "
|
|
|
|
"option value must activate option");
|
|
|
|
BOOST_CHECK_MESSAGE(config.want(Opm::ConvergenceOutputConfiguration::Option::Steps),
|
|
|
|
"Configuration object with \"step\" "
|
|
|
|
"option value must activate Steps option");
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(Iterations)
|
|
|
|
{
|
|
|
|
const auto config = Opm::ConvergenceOutputConfiguration{"iterations"};
|
|
|
|
BOOST_CHECK_MESSAGE(config.any(),
|
|
|
|
"Configuration object with supported "
|
|
|
|
"option value must activate option");
|
|
|
|
BOOST_CHECK_MESSAGE(config.want(Opm::ConvergenceOutputConfiguration::Option::Iterations),
|
|
|
|
"Configuration object with \"iterations\" "
|
|
|
|
"option value must activate Steps option");
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(Iterations_Alias)
|
|
|
|
{
|
|
|
|
const auto config = Opm::ConvergenceOutputConfiguration{"iteration"};
|
|
|
|
BOOST_CHECK_MESSAGE(config.any(),
|
|
|
|
"Configuration object with supported "
|
|
|
|
"option value must activate option");
|
|
|
|
BOOST_CHECK_MESSAGE(config.want(Opm::ConvergenceOutputConfiguration::Option::Iterations),
|
|
|
|
"Configuration object with \"iterations\" "
|
|
|
|
"option value must activate Steps option");
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(Combinations)
|
|
|
|
{
|
|
|
|
const auto steps_iter = Opm::ConvergenceOutputConfiguration{"steps,iterations"};
|
|
|
|
BOOST_CHECK_MESSAGE(steps_iter.any(),
|
|
|
|
"Configuration object with supported "
|
|
|
|
"option value must activate option");
|
|
|
|
BOOST_CHECK_MESSAGE(steps_iter.want(Opm::ConvergenceOutputConfiguration::Option::Steps),
|
|
|
|
"Configuration object with \"steps\" "
|
|
|
|
"option value must activate Steps option");
|
|
|
|
BOOST_CHECK_MESSAGE(steps_iter.want(Opm::ConvergenceOutputConfiguration::Option::Iterations),
|
|
|
|
"Configuration object with \"iterations\" "
|
|
|
|
"option value must activate Steps option");
|
|
|
|
|
|
|
|
const auto iter_steps = Opm::ConvergenceOutputConfiguration{"iterations,steps"};
|
|
|
|
BOOST_CHECK_MESSAGE(iter_steps.any(),
|
|
|
|
"Configuration object with supported "
|
|
|
|
"option value must activate option");
|
|
|
|
BOOST_CHECK_MESSAGE(iter_steps.want(Opm::ConvergenceOutputConfiguration::Option::Steps),
|
|
|
|
"Configuration object with \"steps\" "
|
|
|
|
"option value must activate Steps option");
|
|
|
|
BOOST_CHECK_MESSAGE(iter_steps.want(Opm::ConvergenceOutputConfiguration::Option::Iterations),
|
|
|
|
"Configuration object with \"iterations\" "
|
|
|
|
"option value must activate Steps option");
|
|
|
|
|
|
|
|
const auto none_iter_steps = Opm::ConvergenceOutputConfiguration{"none,iterations,steps"};
|
|
|
|
BOOST_CHECK_MESSAGE(! none_iter_steps.any(),
|
|
|
|
"Configuration object with any option "
|
|
|
|
"value \"none\" must NOT activate output");
|
|
|
|
|
|
|
|
const auto iter_none_steps = Opm::ConvergenceOutputConfiguration{"iterations,none,steps"};
|
|
|
|
BOOST_CHECK_MESSAGE(! iter_none_steps.any(),
|
|
|
|
"Configuration object with any option "
|
|
|
|
"value \"none\" must NOT activate output");
|
|
|
|
|
|
|
|
const auto steps_iter_none = Opm::ConvergenceOutputConfiguration{"steps,iterations, none"};
|
|
|
|
BOOST_CHECK_MESSAGE(! steps_iter_none.any(),
|
|
|
|
"Configuration object with any option "
|
|
|
|
"value \"none\" must NOT activate output");
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_SUITE_END() // Common_Operations
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_SUITE(Failed_Construction)
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(Misprint)
|
|
|
|
{
|
|
|
|
BOOST_CHECK_THROW(Opm::ConvergenceOutputConfiguration{"nonce"},
|
|
|
|
std::invalid_argument);
|
|
|
|
|
Output Non-Linear Convergence to Separate File if Requested
This commit enables outputting non-linear convergence metrics, i.e.,
the MB and CNV values, per phase, for each non-linear iteration in
each timestep. If the user passes the option value "iterations" to
the --extra-convergence-output command line option, this commit will
create a new output file, CASE.INFOITER, that holds
* report step
* time step within that report step
* elapsed time
* MB and CNV values per phase
* well convergence status
for each non-linear iteration.
We use an asynchronous file writing procedure and confer ownership
of the report step's unprocessed convergence reports to this
procedure just before the end of
SimulatorFullyImplicitBlackoilEbos::runStep()
At that point, the convergence reports are about to go out of scope.
The asynchronous protocol uses a dedicated queue of output requests,
class ConvergenceReportQueue, into which the producer-i.e., member
function runStep()-inserts new convergence reports and from which
the output thread, ConvergenceOutputThread::writeASynchronous(),
retrieves those requests before writing the file data.
2022-12-13 08:14:05 -06:00
|
|
|
BOOST_CHECK_THROW(Opm::ConvergenceOutputConfiguration("nonce", "X"),
|
|
|
|
std::invalid_argument);
|
|
|
|
|
2022-12-13 07:05:17 -06:00
|
|
|
BOOST_CHECK_THROW(Opm::ConvergenceOutputConfiguration{"stepS"},
|
|
|
|
std::invalid_argument);
|
|
|
|
|
|
|
|
BOOST_CHECK_THROW(Opm::ConvergenceOutputConfiguration{"steps, iter"},
|
|
|
|
std::invalid_argument);
|
|
|
|
|
|
|
|
BOOST_CHECK_THROW(Opm::ConvergenceOutputConfiguration{"steps, iterations, non"},
|
|
|
|
std::invalid_argument);
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(Unknown)
|
|
|
|
{
|
|
|
|
BOOST_CHECK_THROW(Opm::ConvergenceOutputConfiguration{"Hello"},
|
|
|
|
std::invalid_argument);
|
|
|
|
BOOST_CHECK_THROW(Opm::ConvergenceOutputConfiguration{"meow"},
|
|
|
|
std::invalid_argument);
|
|
|
|
BOOST_CHECK_THROW(Opm::ConvergenceOutputConfiguration{""},
|
|
|
|
std::invalid_argument);
|
|
|
|
BOOST_CHECK_THROW(Opm::ConvergenceOutputConfiguration{"xyz,zy;;;"},
|
|
|
|
std::invalid_argument);
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_SUITE_END()
|