mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Add MaxPressure NLDD domain ordering option, make it default.
This commit is contained in:
@@ -695,26 +695,33 @@ private:
|
|||||||
const auto& solution = ebosSimulator.model().solution(0);
|
const auto& solution = ebosSimulator.model().solution(0);
|
||||||
|
|
||||||
std::vector<int> domain_order(domains_.size());
|
std::vector<int> domain_order(domains_.size());
|
||||||
|
|
||||||
switch (model_.param().local_solve_approach_) {
|
switch (model_.param().local_solve_approach_) {
|
||||||
case DomainSolveApproach::GaussSeidel: {
|
case DomainSolveApproach::GaussSeidel: {
|
||||||
|
// Calculate the measure used to order the domains.
|
||||||
|
std::vector<std::pair<double, int>> measure_per_domain(domains_.size());
|
||||||
switch (model_.param().local_domain_ordering_) {
|
switch (model_.param().local_domain_ordering_) {
|
||||||
case DomainOrderingMeasure::AveragePressure: {
|
case DomainOrderingMeasure::AveragePressure: {
|
||||||
// Use average pressures to order domains.
|
// Use average pressures to order domains.
|
||||||
std::vector<std::pair<double, int>> avgpress_per_domain(domains_.size());
|
|
||||||
for (const auto& domain : domains_) {
|
for (const auto& domain : domains_) {
|
||||||
double press_sum = 0.0;
|
double press_sum = 0.0;
|
||||||
for (const int c : domain.cells) {
|
for (const int c : domain.cells) {
|
||||||
press_sum += solution[c][Indices::pressureSwitchIdx];
|
press_sum += solution[c][Indices::pressureSwitchIdx];
|
||||||
}
|
}
|
||||||
const double avgpress = press_sum / domain.cells.size();
|
const double avgpress = press_sum / domain.cells.size();
|
||||||
avgpress_per_domain[domain.index] = std::make_pair(avgpress, domain.index);
|
measure_per_domain[domain.index] = std::make_pair(avgpress, domain.index);
|
||||||
}
|
}
|
||||||
// Lexicographical sort by pressure, then index.
|
break;
|
||||||
std::sort(avgpress_per_domain.begin(), avgpress_per_domain.end());
|
}
|
||||||
// Reverse since we want high-pressure regions solved first.
|
case DomainOrderingMeasure::MaxPressure: {
|
||||||
std::reverse(avgpress_per_domain.begin(), avgpress_per_domain.end());
|
// Use max pressures to order domains.
|
||||||
for (std::size_t ii = 0; ii < domains_.size(); ++ii) {
|
std::vector<std::pair<double, int>> maxpress_per_domain(domains_.size());
|
||||||
domain_order[ii] = avgpress_per_domain[ii].second;
|
for (const auto& domain : domains_) {
|
||||||
|
double maxpress = 0.0;
|
||||||
|
for (const int c : domain.cells) {
|
||||||
|
maxpress = std::max(maxpress, solution[c][Indices::pressureSwitchIdx]);
|
||||||
|
}
|
||||||
|
measure_per_domain[domain.index] = std::make_pair(maxpress, domain.index);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -730,20 +737,24 @@ private:
|
|||||||
maxres = std::max(maxres, std::fabs(residual[c][ii]));
|
maxres = std::max(maxres, std::fabs(residual[c][ii]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
maxres_per_domain[domain.index] = std::make_pair(maxres, domain.index);
|
measure_per_domain[domain.index] = std::make_pair(maxres, domain.index);
|
||||||
}
|
}
|
||||||
// Lexicographical sort by pressure, then index.
|
break;
|
||||||
std::sort(maxres_per_domain.begin(), maxres_per_domain.end());
|
}
|
||||||
// Reverse since we want high-pressure regions solved first.
|
} // end of switch (model_.param().local_domain_ordering_)
|
||||||
std::reverse(maxres_per_domain.begin(), maxres_per_domain.end());
|
|
||||||
|
|
||||||
|
// Sort by largest measure, keeping index order if equal.
|
||||||
|
std::stable_sort(measure_per_domain.begin(), measure_per_domain.end(),
|
||||||
|
[](const auto& m1, const auto& m2){ return m1.first > m2.first; });
|
||||||
|
|
||||||
|
// Assign domain order.
|
||||||
for (std::size_t ii = 0; ii < domains_.size(); ++ii) {
|
for (std::size_t ii = 0; ii < domains_.size(); ++ii) {
|
||||||
domain_order[ii] = maxres_per_domain[ii].second;
|
domain_order[ii] = measure_per_domain[ii].second;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
} // end of case DomainSolveApproach::GaussSeidel
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case DomainSolveApproach::Jacobi:
|
case DomainSolveApproach::Jacobi:
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -439,7 +439,7 @@ struct LocalDomainsPartitioningMethod<TypeTag, TTag::FlowModelParameters> {
|
|||||||
};
|
};
|
||||||
template<class TypeTag>
|
template<class TypeTag>
|
||||||
struct LocalDomainsOrderingMeasure<TypeTag, TTag::FlowModelParameters> {
|
struct LocalDomainsOrderingMeasure<TypeTag, TTag::FlowModelParameters> {
|
||||||
static constexpr auto value = "pressure";
|
static constexpr auto value = "maxpressure";
|
||||||
};
|
};
|
||||||
// if openMP is available, determine the number threads per process automatically.
|
// if openMP is available, determine the number threads per process automatically.
|
||||||
#if _OPENMP
|
#if _OPENMP
|
||||||
@@ -579,7 +579,7 @@ namespace Opm
|
|||||||
int num_local_domains_{0};
|
int num_local_domains_{0};
|
||||||
double local_domain_partition_imbalance_{1.03};
|
double local_domain_partition_imbalance_{1.03};
|
||||||
std::string local_domain_partition_method_;
|
std::string local_domain_partition_method_;
|
||||||
DomainOrderingMeasure local_domain_ordering_{DomainOrderingMeasure::AveragePressure};
|
DomainOrderingMeasure local_domain_ordering_{DomainOrderingMeasure::MaxPressure};
|
||||||
|
|
||||||
bool write_partitions_{false};
|
bool write_partitions_{false};
|
||||||
|
|
||||||
@@ -642,7 +642,9 @@ namespace Opm
|
|||||||
std::string measure = EWOMS_GET_PARAM(TypeTag, std::string, LocalDomainsOrderingMeasure);
|
std::string measure = EWOMS_GET_PARAM(TypeTag, std::string, LocalDomainsOrderingMeasure);
|
||||||
if (measure == "residual") {
|
if (measure == "residual") {
|
||||||
local_domain_ordering_ = DomainOrderingMeasure::Residual;
|
local_domain_ordering_ = DomainOrderingMeasure::Residual;
|
||||||
} else if (measure == "pressure") {
|
} else if (measure == "maxpressure") {
|
||||||
|
local_domain_ordering_ = DomainOrderingMeasure::MaxPressure;
|
||||||
|
} else if (measure == "averagepressure") {
|
||||||
local_domain_ordering_ = DomainOrderingMeasure::AveragePressure;
|
local_domain_ordering_ = DomainOrderingMeasure::AveragePressure;
|
||||||
} else {
|
} else {
|
||||||
throw std::runtime_error("Invalid domain ordering '" + measure + "' specified.");
|
throw std::runtime_error("Invalid domain ordering '" + measure + "' specified.");
|
||||||
@@ -701,7 +703,7 @@ namespace Opm
|
|||||||
EWOMS_REGISTER_PARAM(TypeTag, std::string, LocalDomainsPartitioningMethod, "Subdomain partitioning method. "
|
EWOMS_REGISTER_PARAM(TypeTag, std::string, LocalDomainsPartitioningMethod, "Subdomain partitioning method. "
|
||||||
"Allowed values are 'zoltan', 'simple', and the name of a partition file ending with '.partition'.");
|
"Allowed values are 'zoltan', 'simple', and the name of a partition file ending with '.partition'.");
|
||||||
EWOMS_REGISTER_PARAM(TypeTag, std::string, LocalDomainsOrderingMeasure, "Subdomain ordering measure. "
|
EWOMS_REGISTER_PARAM(TypeTag, std::string, LocalDomainsOrderingMeasure, "Subdomain ordering measure. "
|
||||||
"Allowed values are 'pressure' and 'residual'.");
|
"Allowed values are 'maxpressure', 'averagepressure' and 'residual'.");
|
||||||
|
|
||||||
EWOMS_REGISTER_PARAM(TypeTag, bool, DebugEmitCellPartition, "Whether or not to emit cell partitions as a debugging aid.");
|
EWOMS_REGISTER_PARAM(TypeTag, bool, DebugEmitCellPartition, "Whether or not to emit cell partitions as a debugging aid.");
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ namespace Opm
|
|||||||
//! \brief Measure to use for domain ordering.
|
//! \brief Measure to use for domain ordering.
|
||||||
enum class DomainOrderingMeasure {
|
enum class DomainOrderingMeasure {
|
||||||
AveragePressure,
|
AveragePressure,
|
||||||
|
MaxPressure,
|
||||||
Residual
|
Residual
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user