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 Kmin = K[0];
|
||||||
typename Vector::field_type Kmax = K[0];
|
typename Vector::field_type Kmax = K[0];
|
||||||
for (int compIdx=1; compIdx<numComponents; ++compIdx){
|
for (int compIdx=1; compIdx<numComponents; ++compIdx){
|
||||||
if (K[compIdx] < Kmin)
|
Kmin = std::min(Kmin, K[compIdx]);
|
||||||
Kmin = K[compIdx];
|
Kmax = std::max(Kmin, K[compIdx]);
|
||||||
else if (K[compIdx] >= Kmax)
|
|
||||||
Kmax = K[compIdx];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lower and upper bound for solution
|
// Lower and upper bound for solution
|
||||||
@ -308,11 +306,16 @@ protected:
|
|||||||
auto Lmax = Kmax / (Kmax - 1);
|
auto Lmax = Kmax / (Kmax - 1);
|
||||||
|
|
||||||
// Check if Lmin < Lmax, and switch if not
|
// Check if Lmin < Lmax, and switch if not
|
||||||
if (Lmin > Lmax)
|
if (Lmin > Lmax) {
|
||||||
{
|
std::swap(Lmin, Lmax);
|
||||||
auto Ltmp = Lmin;
|
}
|
||||||
Lmin = Lmax;
|
|
||||||
Lmax = Ltmp;
|
Lmin = std::clamp(Lmin, 0., 1.);
|
||||||
|
Lmax = std::clamp(Lmax, 0., 1.);
|
||||||
|
|
||||||
|
if (Lmin == Lmax) {
|
||||||
|
Lmin = 0.;
|
||||||
|
Lmax = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initial guess
|
// Initial guess
|
||||||
@ -335,8 +338,7 @@ protected:
|
|||||||
L -= delta;
|
L -= delta;
|
||||||
|
|
||||||
// Check if L is within the bounds, and if not, we apply bisection method
|
// 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
|
// Print info
|
||||||
if (verbosity == 3 || verbosity == 4) {
|
if (verbosity == 3 || verbosity == 4) {
|
||||||
std::cout << "L is not within the the range [Lmin, Lmax], solve using Bisection method!" << std::endl;
|
std::cout << "L is not within the the range [Lmin, Lmax], solve using Bisection method!" << std::endl;
|
||||||
@ -353,7 +355,7 @@ protected:
|
|||||||
std::cout << "Rachford-Rice (Bisection) converged to final solution L = " << L << std::endl;
|
std::cout << "Rachford-Rice (Bisection) converged to final solution L = " << L << std::endl;
|
||||||
}
|
}
|
||||||
return L;
|
return L;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print iteration info
|
// Print iteration info
|
||||||
if (verbosity == 3 || verbosity == 4) {
|
if (verbosity == 3 || verbosity == 4) {
|
||||||
@ -602,27 +604,34 @@ protected:
|
|||||||
|
|
||||||
// Calculate composition using nonlinear solver
|
// Calculate composition using nonlinear solver
|
||||||
// Newton
|
// Newton
|
||||||
|
bool converged = false;
|
||||||
if (flash_2p_method == "newton") {
|
if (flash_2p_method == "newton") {
|
||||||
if (verbosity >= 1) {
|
if (verbosity >= 1) {
|
||||||
std::cout << "Calculate composition using Newton." << std::endl;
|
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") {
|
} else if (flash_2p_method == "ssi") {
|
||||||
// Successive substitution
|
// Successive substitution
|
||||||
if (verbosity >= 1) {
|
if (verbosity >= 1) {
|
||||||
std::cout << "Calculate composition using Succcessive Substitution." << std::endl;
|
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") {
|
} else if (flash_2p_method == "ssi+newton") {
|
||||||
successiveSubstitutionComposition_(K_scalar, L_scalar, fluid_state_scalar, z_scalar, true, verbosity);
|
converged = successiveSubstitutionComposition_(K_scalar, L_scalar, fluid_state_scalar, z_scalar, true, verbosity);
|
||||||
newtonComposition_(K_scalar, L_scalar, fluid_state_scalar, z_scalar, verbosity);
|
if (!converged) {
|
||||||
|
converged = newtonComposition_(K_scalar, L_scalar, fluid_state_scalar, z_scalar, verbosity);
|
||||||
|
}
|
||||||
} else {
|
} 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>
|
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,
|
FlashFluidState& fluid_state, const ComponentVector& z,
|
||||||
int verbosity)
|
int verbosity)
|
||||||
{
|
{
|
||||||
@ -780,6 +789,7 @@ protected:
|
|||||||
}
|
}
|
||||||
L = Opm::getValue(l);
|
L = Opm::getValue(l);
|
||||||
fluid_state.setLvalue(L);
|
fluid_state.setLvalue(L);
|
||||||
|
return converged;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: the interface will need to refactor for later usage
|
// TODO: the interface will need to refactor for later usage
|
||||||
@ -1121,11 +1131,11 @@ protected:
|
|||||||
|
|
||||||
// TODO: or use typename FlashFluidState::Scalar
|
// TODO: or use typename FlashFluidState::Scalar
|
||||||
template <class FlashFluidState, class ComponentVector>
|
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)
|
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.
|
// 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
|
// Store cout format before manipulation
|
||||||
std::ios_base::fmtflags f(std::cout.flags());
|
std::ios_base::fmtflags f(std::cout.flags());
|
||||||
@ -1182,7 +1192,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check convergence
|
// Check convergence
|
||||||
if (convFugRatio.two_norm() < 1e-6) {
|
if (convFugRatio.two_norm() < 1.e-6) {
|
||||||
// Restore cout format
|
// Restore cout format
|
||||||
std::cout.flags(f);
|
std::cout.flags(f);
|
||||||
|
|
||||||
@ -1190,7 +1200,7 @@ protected:
|
|||||||
if (verbosity >= 1) {
|
if (verbosity >= 1) {
|
||||||
std::cout << "Solution converged to the following result :" << std::endl;
|
std::cout << "Solution converged to the following result :" << std::endl;
|
||||||
std::cout << "x = [";
|
std::cout << "x = [";
|
||||||
for (int compIdx=0; compIdx<numComponents; ++compIdx){
|
for (int compIdx = 0; compIdx < numComponents; ++compIdx) {
|
||||||
if (compIdx < numComponents - 1)
|
if (compIdx < numComponents - 1)
|
||||||
std::cout << fluid_state.moleFraction(oilPhaseIdx, compIdx) << " ";
|
std::cout << fluid_state.moleFraction(oilPhaseIdx, compIdx) << " ";
|
||||||
else
|
else
|
||||||
@ -1198,7 +1208,7 @@ protected:
|
|||||||
}
|
}
|
||||||
std::cout << "]" << std::endl;
|
std::cout << "]" << std::endl;
|
||||||
std::cout << "y = [";
|
std::cout << "y = [";
|
||||||
for (int compIdx=0; compIdx<numComponents; ++compIdx){
|
for (int compIdx = 0; compIdx < numComponents; ++compIdx) {
|
||||||
if (compIdx < numComponents - 1)
|
if (compIdx < numComponents - 1)
|
||||||
std::cout << fluid_state.moleFraction(gasPhaseIdx, compIdx) << " ";
|
std::cout << fluid_state.moleFraction(gasPhaseIdx, compIdx) << " ";
|
||||||
else
|
else
|
||||||
@ -1209,11 +1219,10 @@ protected:
|
|||||||
std::cout << "L = " << L << std::endl;
|
std::cout << "L = " << L << std::endl;
|
||||||
}
|
}
|
||||||
// Restore cout format format
|
// Restore cout format format
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If convergence is not met, K is updated in a successive substitution manner
|
// If convergence is not met, K is updated in a successive substitution manner
|
||||||
else{
|
else {
|
||||||
// Update K
|
// Update K
|
||||||
for (int compIdx=0; compIdx<numComponents; ++compIdx){
|
for (int compIdx=0; compIdx<numComponents; ++compIdx){
|
||||||
K[compIdx] *= newFugRatio[compIdx];
|
K[compIdx] *= newFugRatio[compIdx];
|
||||||
@ -1222,12 +1231,13 @@ protected:
|
|||||||
// Solve Rachford-Rice to get L from updated K
|
// Solve Rachford-Rice to get L from updated K
|
||||||
L = solveRachfordRice_g_(K, z, 0);
|
L = solveRachfordRice_g_(K, z, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!newton_afterwards) {
|
// did not get converged. check whether will do more newton later afterward
|
||||||
throw std::runtime_error(
|
if (newton_afterwards && verbosity > 0) {
|
||||||
"Successive substitution composition update did not converge within maxIterations " + std::to_string(maxIterations));
|
std::cout << "Successive substitution composition update did not converge within maxIterations "
|
||||||
|
<< maxIterations << std::endl;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
};//end PTFlash
|
};//end PTFlash
|
||||||
|
Loading…
Reference in New Issue
Block a user