Merge e3362f3b01
into 9a0ccfd853
This commit is contained in:
commit
a2d0f38812
@ -297,10 +297,8 @@ protected:
|
||||
typename Vector::field_type Kmin = K[0];
|
||||
typename Vector::field_type Kmax = K[0];
|
||||
for (int compIdx=1; compIdx<numComponents; ++compIdx){
|
||||
if (K[compIdx] < Kmin)
|
||||
Kmin = K[compIdx];
|
||||
else if (K[compIdx] >= Kmax)
|
||||
Kmax = K[compIdx];
|
||||
Kmin = std::min(Kmin, K[compIdx]);
|
||||
Kmax = std::max(Kmin, K[compIdx]);
|
||||
}
|
||||
|
||||
// Lower and upper bound for solution
|
||||
@ -308,11 +306,16 @@ protected:
|
||||
auto Lmax = Kmax / (Kmax - 1);
|
||||
|
||||
// Check if Lmin < Lmax, and switch if not
|
||||
if (Lmin > Lmax)
|
||||
{
|
||||
auto Ltmp = Lmin;
|
||||
Lmin = Lmax;
|
||||
Lmax = Ltmp;
|
||||
if (Lmin > Lmax) {
|
||||
std::swap(Lmin, Lmax);
|
||||
}
|
||||
|
||||
Lmin = std::clamp(Lmin, 0., 1.);
|
||||
Lmax = std::clamp(Lmax, 0., 1.);
|
||||
|
||||
if (Lmin == Lmax) {
|
||||
Lmin = 0.;
|
||||
Lmax = 1.0;
|
||||
}
|
||||
|
||||
// Initial guess
|
||||
@ -335,8 +338,7 @@ protected:
|
||||
L -= delta;
|
||||
|
||||
// Check if L is within the bounds, and if not, we apply bisection method
|
||||
if (L < Lmin || L > Lmax)
|
||||
{
|
||||
if (L < Lmin || L > Lmax) {
|
||||
// Print info
|
||||
if (verbosity == 3 || verbosity == 4) {
|
||||
std::cout << "L is not within the the range [Lmin, Lmax], solve using Bisection method!" << std::endl;
|
||||
@ -602,27 +604,34 @@ protected:
|
||||
|
||||
// Calculate composition using nonlinear solver
|
||||
// Newton
|
||||
bool converged = false;
|
||||
if (flash_2p_method == "newton") {
|
||||
if (verbosity >= 1) {
|
||||
std::cout << "Calculate composition using Newton." << std::endl;
|
||||
}
|
||||
newtonComposition_(K_scalar, L_scalar, fluid_state_scalar, z_scalar, verbosity);
|
||||
converged = newtonComposition_(K_scalar, L_scalar, fluid_state_scalar, z_scalar, verbosity);
|
||||
} else if (flash_2p_method == "ssi") {
|
||||
// Successive substitution
|
||||
if (verbosity >= 1) {
|
||||
std::cout << "Calculate composition using Succcessive Substitution." << std::endl;
|
||||
}
|
||||
successiveSubstitutionComposition_(K_scalar, L_scalar, fluid_state_scalar, z_scalar, false, verbosity);
|
||||
converged = successiveSubstitutionComposition_(K_scalar, L_scalar, fluid_state_scalar, z_scalar, false, verbosity);
|
||||
} else if (flash_2p_method == "ssi+newton") {
|
||||
successiveSubstitutionComposition_(K_scalar, L_scalar, fluid_state_scalar, z_scalar, true, verbosity);
|
||||
newtonComposition_(K_scalar, L_scalar, fluid_state_scalar, z_scalar, verbosity);
|
||||
converged = successiveSubstitutionComposition_(K_scalar, L_scalar, fluid_state_scalar, z_scalar, true, verbosity);
|
||||
if (!converged) {
|
||||
converged = newtonComposition_(K_scalar, L_scalar, fluid_state_scalar, z_scalar, verbosity);
|
||||
}
|
||||
} else {
|
||||
throw std::runtime_error("unknown two phase flash method " + flash_2p_method + " is specified");
|
||||
throw std::logic_error("unknown two phase flash method " + flash_2p_method + " is specified");
|
||||
}
|
||||
|
||||
if (!converged) {
|
||||
throw std::runtime_error("flash calculation did not get converged with " + flash_2p_method);
|
||||
}
|
||||
}
|
||||
|
||||
template <class FlashFluidState, class ComponentVector>
|
||||
static void newtonComposition_(ComponentVector& K, typename FlashFluidState::Scalar& L,
|
||||
static bool newtonComposition_(ComponentVector& K, typename FlashFluidState::Scalar& L,
|
||||
FlashFluidState& fluid_state, const ComponentVector& z,
|
||||
int verbosity)
|
||||
{
|
||||
@ -780,6 +789,7 @@ protected:
|
||||
}
|
||||
L = Opm::getValue(l);
|
||||
fluid_state.setLvalue(L);
|
||||
return converged;
|
||||
}
|
||||
|
||||
// TODO: the interface will need to refactor for later usage
|
||||
@ -1121,11 +1131,11 @@ protected:
|
||||
|
||||
// TODO: or use typename FlashFluidState::Scalar
|
||||
template <class FlashFluidState, class ComponentVector>
|
||||
static void successiveSubstitutionComposition_(ComponentVector& K, typename ComponentVector::field_type& L, FlashFluidState& fluid_state, const ComponentVector& z,
|
||||
static bool successiveSubstitutionComposition_(ComponentVector& K, typename ComponentVector::field_type& L, FlashFluidState& fluid_state, const ComponentVector& z,
|
||||
const bool newton_afterwards, const int verbosity)
|
||||
{
|
||||
// Determine max. iterations based on if it will be used as a standalone flash or as a pre-process to Newton (or other) method.
|
||||
const int maxIterations = newton_afterwards ? 3 : 100;
|
||||
const int maxIterations = newton_afterwards ? 5 : 100;
|
||||
|
||||
// Store cout format before manipulation
|
||||
std::ios_base::fmtflags f(std::cout.flags());
|
||||
@ -1182,7 +1192,7 @@ protected:
|
||||
}
|
||||
|
||||
// Check convergence
|
||||
if (convFugRatio.two_norm() < 1e-6) {
|
||||
if (convFugRatio.two_norm() < 1.e-6) {
|
||||
// Restore cout format
|
||||
std::cout.flags(f);
|
||||
|
||||
@ -1209,9 +1219,8 @@ protected:
|
||||
std::cout << "L = " << L << std::endl;
|
||||
}
|
||||
// Restore cout format format
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
// If convergence is not met, K is updated in a successive substitution manner
|
||||
else {
|
||||
// Update K
|
||||
@ -1222,12 +1231,13 @@ protected:
|
||||
// Solve Rachford-Rice to get L from updated K
|
||||
L = solveRachfordRice_g_(K, z, 0);
|
||||
}
|
||||
|
||||
}
|
||||
if (!newton_afterwards) {
|
||||
throw std::runtime_error(
|
||||
"Successive substitution composition update did not converge within maxIterations " + std::to_string(maxIterations));
|
||||
// did not get converged. check whether will do more newton later afterward
|
||||
if (newton_afterwards && verbosity > 0) {
|
||||
std::cout << "Successive substitution composition update did not converge within maxIterations "
|
||||
<< maxIterations << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
};//end PTFlash
|
||||
|
Loading…
Reference in New Issue
Block a user