mirror of
https://github.com/OPM/opm-simulators.git
synced 2024-07-04 11:33:06 -05:00
Report CNV Violation Pore-Volume Fraction to INFOITER
This commit includes the fraction of pore-volume whose CNV targets are violated as a new per-iteration quantity in the INFOITER file (--output-extra-convergence-info=iteration), with the column header "CnvErrPvFrac". We collect the values which are already calculated in BlackoilModel<>::getReservoirConvergence() and store these as a pair of numerator and denominator in the ConvergenceReport class. Note that we need both the numerator and the denominator in order to aggregate contributions from multiple ranks. While here, also make a few more objects 'const' and calculate column widths directly instead of the maximum number of characters in writeConvergenceHeader().
This commit is contained in:
parent
f01635dcf2
commit
027eed16e9
|
@ -897,7 +897,8 @@ namespace Opm {
|
|||
Vector R_sum(numComp, 0.0 );
|
||||
Vector maxCoeff(numComp, std::numeric_limits< Scalar >::lowest() );
|
||||
std::vector<int> maxCoeffCell(numComp, -1);
|
||||
const auto [ pvSumLocal, numAquiferPvSumLocal] = localConvergenceData(R_sum, maxCoeff, B_avg, maxCoeffCell);
|
||||
const auto [ pvSumLocal, numAquiferPvSumLocal] =
|
||||
this->localConvergenceData(R_sum, maxCoeff, B_avg, maxCoeffCell);
|
||||
|
||||
// compute global sum and max of quantities
|
||||
const auto [ pvSum, numAquiferPvSum ] =
|
||||
|
@ -905,9 +906,9 @@ namespace Opm {
|
|||
numAquiferPvSumLocal,
|
||||
R_sum, maxCoeff, B_avg);
|
||||
|
||||
auto cnvErrorPvFraction = computeCnvErrorPv(B_avg, dt);
|
||||
cnvErrorPvFraction /= (pvSum - numAquiferPvSum);
|
||||
|
||||
const auto cnvErrorPvFraction =
|
||||
computeCnvErrorPv(B_avg, dt)
|
||||
/ (pvSum - numAquiferPvSum);
|
||||
|
||||
// For each iteration, we need to determine whether to use the relaxed tolerances.
|
||||
// To disable the usage of relaxed tolerances, you can set the relaxed tolerances as the strict tolerances.
|
||||
|
@ -927,7 +928,7 @@ namespace Opm {
|
|||
const bool relax_pv_fraction_cnv = cnvErrorPvFraction < param_.relaxed_max_pv_fraction_;
|
||||
const bool use_relaxed_cnv = relax_final_iteration_cnv || relax_pv_fraction_cnv || relax_iter_cnv;
|
||||
|
||||
if (relax_final_iteration_mb || relax_final_iteration_cnv) {
|
||||
if (relax_final_iteration_mb || relax_final_iteration_cnv) {
|
||||
if ( terminal_output_ ) {
|
||||
std::string message = "Number of newton iterations reached its maximum try to continue with relaxed tolerances:";
|
||||
if (relax_final_iteration_mb)
|
||||
|
@ -944,7 +945,7 @@ namespace Opm {
|
|||
// Finish computation
|
||||
std::vector<Scalar> CNV(numComp);
|
||||
std::vector<Scalar> mass_balance_residual(numComp);
|
||||
for ( int compIdx = 0; compIdx < numComp; ++compIdx )
|
||||
for (int compIdx = 0; compIdx < numComp; ++compIdx)
|
||||
{
|
||||
CNV[compIdx] = B_avg[compIdx] * dt * maxCoeff[compIdx];
|
||||
mass_balance_residual[compIdx] = std::abs(B_avg[compIdx]*R_sum[compIdx]) * dt / pvSum;
|
||||
|
@ -953,12 +954,15 @@ namespace Opm {
|
|||
|
||||
// Create convergence report.
|
||||
ConvergenceReport report{reportTime};
|
||||
report.setPoreVolCnvViolationFraction(cnvErrorPvFraction, pvSum - numAquiferPvSum);
|
||||
|
||||
using CR = ConvergenceReport;
|
||||
for (int compIdx = 0; compIdx < numComp; ++compIdx) {
|
||||
double res[2] = { mass_balance_residual[compIdx], CNV[compIdx] };
|
||||
CR::ReservoirFailure::Type types[2] = { CR::ReservoirFailure::Type::MassBalance,
|
||||
const double res[2] = { mass_balance_residual[compIdx], CNV[compIdx] };
|
||||
const CR::ReservoirFailure::Type types[2] = { CR::ReservoirFailure::Type::MassBalance,
|
||||
CR::ReservoirFailure::Type::Cnv };
|
||||
double tol[2] = { tol_mb, tol_cnv };
|
||||
const double tol[2] = { tol_mb, tol_cnv };
|
||||
|
||||
for (int ii : {0, 1}) {
|
||||
if (std::isnan(res[ii])) {
|
||||
report.setReservoirFailed({types[ii], CR::Severity::NotANumber, compIdx});
|
||||
|
|
|
@ -656,6 +656,7 @@ private:
|
|||
} else if (res[ii] > tol[ii]) {
|
||||
report.setReservoirFailed({types[ii], CR::Severity::Normal, compIdx});
|
||||
}
|
||||
|
||||
report.setReservoirConvergenceMetric(types[ii], compIdx, res[ii]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <opm/simulators/timestepping/ConvergenceReport.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <condition_variable>
|
||||
#include <cstddef>
|
||||
|
@ -40,12 +41,44 @@
|
|||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
auto fixedHeaders() noexcept
|
||||
{
|
||||
using namespace std::literals::string_literals;
|
||||
|
||||
return std::array {
|
||||
"ReportStep"s,
|
||||
"TimeStep"s,
|
||||
"Time"s,
|
||||
"CnvErrPvFrac"s,
|
||||
"Iteration"s,
|
||||
};
|
||||
}
|
||||
|
||||
template <typename HeaderSequence>
|
||||
auto maxHeaderSize(const HeaderSequence& headers)
|
||||
{
|
||||
using sz_t = std::remove_cv_t<std::remove_reference_t<
|
||||
decltype(std::declval<HeaderSequence>().front().size())>>;
|
||||
|
||||
if (headers.empty()) {
|
||||
return sz_t{0};
|
||||
}
|
||||
|
||||
return std::accumulate(headers.begin(), headers.end(), sz_t{1},
|
||||
[](const auto m, const auto& header)
|
||||
{
|
||||
return std::max(m, header.size() + 1);
|
||||
});
|
||||
}
|
||||
|
||||
std::string
|
||||
formatMetricColumn(const Opm::ConvergenceOutputThread::ComponentToPhaseName& getPhaseName,
|
||||
const Opm::ConvergenceReport::ReservoirConvergenceMetric& metric)
|
||||
|
@ -65,45 +98,49 @@ namespace {
|
|||
[&getPhaseName](const std::string::size_type maxChar,
|
||||
const Opm::ConvergenceReport::ReservoirConvergenceMetric& metric)
|
||||
{
|
||||
return std::max(maxChar, formatMetricColumn(getPhaseName, metric).size());
|
||||
return std::max(maxChar, formatMetricColumn(getPhaseName, metric).size() + 1);
|
||||
});
|
||||
}
|
||||
|
||||
std::string::size_type
|
||||
std::pair<std::string::size_type, std::string::size_type>
|
||||
writeConvergenceHeader(std::ostream& os,
|
||||
const Opm::ConvergenceOutputThread::ComponentToPhaseName& getPhaseName,
|
||||
const Opm::ConvergenceReportQueue::OutputRequest& firstRequest)
|
||||
{
|
||||
const auto minColSize = std::string::size_type{11};
|
||||
const auto initial_headers = fixedHeaders();
|
||||
const auto minColSize = maxHeaderSize(initial_headers);
|
||||
|
||||
os << std::right << std::setw(minColSize) << "ReportStep" << ' '
|
||||
<< std::right << std::setw(minColSize) << "TimeStep" << ' '
|
||||
<< std::right << std::setw(minColSize) << "Time" << ' '
|
||||
<< std::right << std::setw(minColSize) << "Iteration";
|
||||
{
|
||||
auto leadingSpace = false;
|
||||
|
||||
const auto& metrics = firstRequest.reports.front().reservoirConvergence();
|
||||
const auto maxChar = maxColHeaderSize(minColSize, getPhaseName, metrics);
|
||||
for (const auto& columnHeader : initial_headers) {
|
||||
if (leadingSpace) { os << ' '; }
|
||||
os << std::right << std::setw(minColSize) << columnHeader;
|
||||
leadingSpace = true;
|
||||
}
|
||||
}
|
||||
|
||||
const auto& metrics = firstRequest.reports.front().reservoirConvergence();
|
||||
const auto headerSize = maxColHeaderSize(minColSize, getPhaseName, metrics);
|
||||
|
||||
for (const auto& metric : metrics) {
|
||||
os << std::right << std::setw(maxChar + 1)
|
||||
os << std::right << std::setw(headerSize)
|
||||
<< formatMetricColumn(getPhaseName, metric);
|
||||
}
|
||||
|
||||
// Note: Newline character intentionally placed in separate output
|
||||
// request to not influence right-justification of column header.
|
||||
os << std::right << std::setw(maxChar + 1) << "WellStatus" << '\n';
|
||||
os << std::right << std::setw(headerSize) << "WellStatus" << '\n';
|
||||
|
||||
return maxChar;
|
||||
return { minColSize, headerSize };
|
||||
}
|
||||
|
||||
|
||||
void writeConvergenceRequest(std::ostream& os,
|
||||
const Opm::ConvergenceOutputThread::ConvertToTimeUnits& convertTime,
|
||||
std::string::size_type colSize,
|
||||
const std::string::size_type firstColSize,
|
||||
const std::string::size_type colSize,
|
||||
const Opm::ConvergenceReportQueue::OutputRequest& request)
|
||||
{
|
||||
const auto firstColSize = std::string::size_type{11};
|
||||
|
||||
os.setf(std::ios_base::scientific);
|
||||
|
||||
auto iter = 0;
|
||||
|
@ -112,19 +149,23 @@ namespace {
|
|||
<< std::setw(firstColSize) << request.currentStep << ' '
|
||||
<< std::setprecision(4) << std::setw(firstColSize)
|
||||
<< convertTime(report.reportTime()) << ' '
|
||||
<< std::setprecision(4) << std::setw(firstColSize)
|
||||
<< report.cnvViolatedPvFraction() << ' '
|
||||
<< std::setw(firstColSize) << iter;
|
||||
|
||||
for (const auto& metric : report.reservoirConvergence()) {
|
||||
os << std::setprecision(4) << std::setw(colSize + 1) << metric.value();
|
||||
os << std::setprecision(4) << std::setw(colSize) << metric.value();
|
||||
}
|
||||
|
||||
os << std::right << std::setw(colSize + 1)
|
||||
os << std::right << std::setw(colSize)
|
||||
<< (report.wellFailed() ? "FAIL" : "CONV");
|
||||
|
||||
if (report.wellFailed()) {
|
||||
for (const auto& wf : report.wellFailures()) {
|
||||
os << " " << to_string(wf);
|
||||
os << ' ' << to_string(wf);
|
||||
}
|
||||
}
|
||||
|
||||
os << '\n';
|
||||
|
||||
++iter;
|
||||
|
@ -160,6 +201,7 @@ private:
|
|||
ComponentToPhaseName getPhaseName_{};
|
||||
ConvertToTimeUnits convertTime_{};
|
||||
std::optional<std::ofstream> infoIter_{};
|
||||
std::string::size_type firstColSize_{0};
|
||||
std::string::size_type colSize_{0};
|
||||
bool haveOutputIterHeader_{false};
|
||||
bool finalRequestWritten_{false};
|
||||
|
@ -203,7 +245,7 @@ writeIterInfo(const std::vector<ConvergenceReportQueue::OutputRequest>& requests
|
|||
}
|
||||
|
||||
if (! this->haveOutputIterHeader_) {
|
||||
this->colSize_ =
|
||||
std::tie(this->firstColSize_, this->colSize_) =
|
||||
writeConvergenceHeader(this->infoIter_.value(),
|
||||
this->getPhaseName_,
|
||||
requests.front());
|
||||
|
@ -213,6 +255,7 @@ writeIterInfo(const std::vector<ConvergenceReportQueue::OutputRequest>& requests
|
|||
for (const auto& request : requests) {
|
||||
writeConvergenceRequest(this->infoIter_.value(),
|
||||
this->convertTime_,
|
||||
this->firstColSize_,
|
||||
this->colSize_,
|
||||
request);
|
||||
|
||||
|
|
|
@ -363,13 +363,16 @@ public:
|
|||
+ schedule().seconds(timer.currentStepNum()),
|
||||
timer.currentStepLength());
|
||||
simulator_.setEpisodeIndex(timer.currentStepNum());
|
||||
|
||||
if (serializer_.shouldLoad()) {
|
||||
wellModel_().prepareDeserialize(serializer_.loadStep() - 1);
|
||||
serializer_.loadState();
|
||||
simulator_.model().invalidateAndUpdateIntensiveQuantities(/*timeIdx=*/0);
|
||||
}
|
||||
solver_->model().beginReportStep();
|
||||
bool enableTUNING = Parameters::get<TypeTag, Properties::EnableTuning>();
|
||||
|
||||
this->solver_->model().beginReportStep();
|
||||
|
||||
const bool enableTUNING = Parameters::get<TypeTag, Properties::EnableTuning>();
|
||||
|
||||
// If sub stepping is enabled allow the solver to sub cycle
|
||||
// in case the report steps are too large for the solver to converge
|
||||
|
@ -442,10 +445,17 @@ public:
|
|||
report_.success.solver_time += solverTimer_->secsSinceStart();
|
||||
|
||||
if (this->grid().comm().rank() == 0) {
|
||||
// Grab the step convergence reports that are new since last we were here.
|
||||
const auto& reps = solver_->model().stepReports();
|
||||
this->writeConvergenceOutput(std::vector<StepReport>{reps.begin() + already_reported_steps_, reps.end()});
|
||||
already_reported_steps_ = reps.size();
|
||||
// Grab the step convergence reports that are new since last we
|
||||
// were here.
|
||||
const auto& reps = this->solver_->model().stepReports();
|
||||
|
||||
auto reports = std::vector<StepReport> {
|
||||
reps.begin() + this->already_reported_steps_, reps.end()
|
||||
};
|
||||
|
||||
this->writeConvergenceOutput(std::move(reports));
|
||||
|
||||
this->already_reported_steps_ = reps.size();
|
||||
}
|
||||
|
||||
// Increment timer, remember well state.
|
||||
|
|
|
@ -40,56 +40,78 @@ namespace Opm
|
|||
|
||||
// ----------- Types -----------
|
||||
|
||||
enum Status { AllGood = 0,
|
||||
ReservoirFailed = 1 << 0,
|
||||
WellFailed = 1 << 1 };
|
||||
enum struct Severity { None = 0,
|
||||
Normal = 1,
|
||||
TooLarge = 2,
|
||||
NotANumber = 3 };
|
||||
enum Status {
|
||||
AllGood = 0,
|
||||
ReservoirFailed = 1 << 0,
|
||||
WellFailed = 1 << 1,
|
||||
};
|
||||
|
||||
enum struct Severity {
|
||||
None = 0,
|
||||
Normal = 1,
|
||||
TooLarge = 2,
|
||||
NotANumber = 3,
|
||||
};
|
||||
|
||||
class ReservoirFailure
|
||||
{
|
||||
public:
|
||||
enum struct Type { Invalid, MassBalance, Cnv };
|
||||
|
||||
ReservoirFailure(Type t, Severity s, int phase)
|
||||
: type_(t), severity_(s), phase_(phase)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
Type type() const { return type_; }
|
||||
Severity severity() const { return severity_; }
|
||||
int phase() const { return phase_; }
|
||||
|
||||
private:
|
||||
Type type_;
|
||||
Severity severity_;
|
||||
int phase_;
|
||||
};
|
||||
|
||||
class ReservoirConvergenceMetric
|
||||
{
|
||||
public:
|
||||
ReservoirConvergenceMetric(ReservoirFailure::Type t, int phase, double value)
|
||||
: type_(t), phase_(phase), value_(value)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
ReservoirFailure::Type type() const { return type_; }
|
||||
int phase() const { return phase_; }
|
||||
double value() const { return value_; }
|
||||
|
||||
private:
|
||||
ReservoirFailure::Type type_;
|
||||
int phase_;
|
||||
double value_;
|
||||
};
|
||||
|
||||
class WellFailure
|
||||
{
|
||||
public:
|
||||
enum struct Type { Invalid, MassBalance, Pressure, ControlBHP, ControlTHP, ControlRate, Unsolvable, WrongFlowDirection };
|
||||
enum struct Type {
|
||||
Invalid,
|
||||
MassBalance,
|
||||
Pressure,
|
||||
ControlBHP,
|
||||
ControlTHP,
|
||||
ControlRate,
|
||||
Unsolvable,
|
||||
WrongFlowDirection,
|
||||
};
|
||||
|
||||
WellFailure(Type t, Severity s, int phase, const std::string& well_name)
|
||||
: type_(t), severity_(s), phase_(phase), well_name_(well_name)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
Type type() const { return type_; }
|
||||
Severity severity() const { return severity_; }
|
||||
int phase() const { return phase_; }
|
||||
const std::string& wellName() const { return well_name_; }
|
||||
|
||||
private:
|
||||
Type type_;
|
||||
Severity severity_;
|
||||
|
@ -101,8 +123,7 @@ namespace Opm
|
|||
|
||||
ConvergenceReport()
|
||||
: ConvergenceReport{0.0}
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
explicit ConvergenceReport(const double reportTime)
|
||||
: reportTime_{reportTime}
|
||||
|
@ -110,8 +131,7 @@ namespace Opm
|
|||
, res_failures_{}
|
||||
, well_failures_{}
|
||||
, wellGroupTargetsViolated_(false)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
void clear()
|
||||
{
|
||||
|
@ -144,6 +164,13 @@ namespace Opm
|
|||
wellGroupTargetsViolated_ = wellGroupTargetsViolated;
|
||||
}
|
||||
|
||||
void setPoreVolCnvViolationFraction(const double cnvErrorPvFraction,
|
||||
const double cnvErrorPvFractionDenom)
|
||||
{
|
||||
this->pvFracCnvViol_ = cnvErrorPvFraction;
|
||||
this->pvFracCnvViolDenom_ = cnvErrorPvFractionDenom;
|
||||
}
|
||||
|
||||
ConvergenceReport& operator+=(const ConvergenceReport& other)
|
||||
{
|
||||
reportTime_ = std::max(reportTime_, other.reportTime_);
|
||||
|
@ -154,6 +181,21 @@ namespace Opm
|
|||
assert(reservoirFailed() != res_failures_.empty());
|
||||
assert(wellFailed() != well_failures_.empty());
|
||||
wellGroupTargetsViolated_ = (wellGroupTargetsViolated_ || other.wellGroupTargetsViolated_);
|
||||
|
||||
if ((this->pvFracCnvViolDenom_ > 0.0) ||
|
||||
(other.pvFracCnvViolDenom_ > 0.0))
|
||||
{
|
||||
this->pvFracCnvViol_ = (this->pvFracCnvViol_ * this->pvFracCnvViolDenom_ +
|
||||
other.pvFracCnvViol_ * other.pvFracCnvViolDenom_)
|
||||
/ (this->pvFracCnvViolDenom_ + other.pvFracCnvViolDenom_);
|
||||
|
||||
this->pvFracCnvViolDenom_ += other.pvFracCnvViolDenom_;
|
||||
}
|
||||
else {
|
||||
this->pvFracCnvViol_ = 0.0;
|
||||
this->pvFracCnvViolDenom_ = 0.0;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -164,6 +206,16 @@ namespace Opm
|
|||
return reportTime_;
|
||||
}
|
||||
|
||||
double cnvViolatedPvFraction() const
|
||||
{
|
||||
return this->pvFracCnvViol_;
|
||||
}
|
||||
|
||||
std::pair<double, double> cnvViolatedPvFractionPack() const
|
||||
{
|
||||
return { this->pvFracCnvViol_, this->pvFracCnvViolDenom_ };
|
||||
}
|
||||
|
||||
bool converged() const
|
||||
{
|
||||
return (status_ == AllGood) && !wellGroupTargetsViolated_;
|
||||
|
@ -211,7 +263,6 @@ namespace Opm
|
|||
}
|
||||
|
||||
private:
|
||||
|
||||
// ----------- Member variables -----------
|
||||
double reportTime_;
|
||||
Status status_;
|
||||
|
@ -219,6 +270,8 @@ namespace Opm
|
|||
std::vector<WellFailure> well_failures_;
|
||||
std::vector<ReservoirConvergenceMetric> res_convergence_;
|
||||
bool wellGroupTargetsViolated_;
|
||||
double pvFracCnvViol_{};
|
||||
double pvFracCnvViolDenom_{};
|
||||
};
|
||||
|
||||
struct StepReport
|
||||
|
@ -228,7 +281,6 @@ namespace Opm
|
|||
std::vector<ConvergenceReport> report;
|
||||
};
|
||||
|
||||
|
||||
std::string to_string(const ConvergenceReport::ReservoirFailure::Type t);
|
||||
|
||||
std::string to_string(const ConvergenceReport::Severity s);
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
#include <opm/simulators/timestepping/gatherConvergenceReport.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
#if HAVE_MPI
|
||||
|
||||
#include <mpi.h>
|
||||
|
@ -76,15 +78,24 @@ namespace
|
|||
{
|
||||
// Pack the data.
|
||||
// Status will not be packed, it is possible to deduce from the other data.
|
||||
// Reservoir failures.
|
||||
double reportTime = local_report.reportTime();
|
||||
MPI_Pack(&reportTime, 1, MPI_DOUBLE, buf.data(), buf.size(), &offset, mpi_communicator);
|
||||
|
||||
{
|
||||
const auto cnvPvFrac = local_report.cnvViolatedPvFractionPack();
|
||||
|
||||
MPI_Pack(&cnvPvFrac.first , 1, MPI_DOUBLE, buf.data(), buf.size(), &offset, mpi_communicator);
|
||||
MPI_Pack(&cnvPvFrac.second, 1, MPI_DOUBLE, buf.data(), buf.size(), &offset, mpi_communicator);
|
||||
}
|
||||
|
||||
// Reservoir failures.
|
||||
const auto rf = local_report.reservoirFailures();
|
||||
int num_rf = rf.size();
|
||||
MPI_Pack(&num_rf, 1, MPI_INT, buf.data(), buf.size(), &offset, mpi_communicator);
|
||||
for (const auto& f : rf) {
|
||||
packReservoirFailure(f, buf, offset, mpi_communicator);
|
||||
}
|
||||
|
||||
// Reservoir convergence metrics.
|
||||
const auto rm = local_report.reservoirConvergence();
|
||||
int num_rm = rm.size();
|
||||
|
@ -92,6 +103,7 @@ namespace
|
|||
for (const auto& m : rm) {
|
||||
packReservoirConvergenceMetric(m, buf, offset, mpi_communicator);
|
||||
}
|
||||
|
||||
// Well failures.
|
||||
const auto wf = local_report.wellFailures();
|
||||
int num_wf = wf.size();
|
||||
|
@ -114,7 +126,7 @@ namespace
|
|||
for (const auto& f : local_report.wellFailures()) {
|
||||
wellnames_length += (f.wellName().size() + 1);
|
||||
}
|
||||
return (3 + 3*num_rf + 2*num_rm + 4*num_wf)*int_pack_size + (1 + 1*num_rm)*double_pack_size + wellnames_length;
|
||||
return (3 + 3*num_rf + 2*num_rm + 4*num_wf)*int_pack_size + (3 + 1*num_rm)*double_pack_size + wellnames_length;
|
||||
}
|
||||
|
||||
ConvergenceReport::ReservoirFailure unpackReservoirFailure(const std::vector<char>& recv_buffer, int& offset, MPI_Comm mpi_communicator)
|
||||
|
@ -169,7 +181,15 @@ namespace
|
|||
auto* data = const_cast<char*>(recv_buffer.data());
|
||||
double reportTime{0.0};
|
||||
MPI_Unpack(data, recv_buffer.size(), &offset, &reportTime, 1, MPI_DOUBLE, mpi_communicator);
|
||||
|
||||
ConvergenceReport cr{reportTime};
|
||||
|
||||
auto cnvPvFrac = std::pair { 0.0, 0.0 };
|
||||
MPI_Unpack(data, recv_buffer.size(), &offset, &cnvPvFrac.first , 1, MPI_DOUBLE, mpi_communicator);
|
||||
MPI_Unpack(data, recv_buffer.size(), &offset, &cnvPvFrac.second, 1, MPI_DOUBLE, mpi_communicator);
|
||||
|
||||
cr.setPoreVolCnvViolationFraction(cnvPvFrac.first, cnvPvFrac.second);
|
||||
|
||||
int num_rf = -1;
|
||||
MPI_Unpack(data, recv_buffer.size(), &offset, &num_rf, 1, MPI_INT, mpi_communicator);
|
||||
for (int rf = 0; rf < num_rf; ++rf) {
|
||||
|
|
|
@ -149,9 +149,8 @@ BOOST_AUTO_TEST_CASE(CheckMassBalanceWithinXXXMBE)
|
|||
BOOST_TEST_MESSAGE("---------------------------------------------------------------------------");
|
||||
|
||||
|
||||
BOOST_CHECK( max_mb[0] < 1.0e-6 );
|
||||
BOOST_CHECK( max_mb[1] < 1.0e-8 );
|
||||
BOOST_CHECK( max_mb[2] < 1.0e-10 );
|
||||
BOOST_CHECK_MESSAGE( max_mb[0] < 1.0e-6, "max_mb[0] (= " << max_mb[0] << ") is not strictly less than 1.0e-6" );
|
||||
BOOST_CHECK_MESSAGE( max_mb[1] < 1.0e-8, "max_mb[1] (= " << max_mb[1] << ") is not strictly less than 1.0e-8" );
|
||||
BOOST_CHECK_MESSAGE( max_mb[2] < 1.0e-10, "max_mb[2] (= " << max_mb[1] << ") is not strictly less than 1.0e-10" );
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user