Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
b50fb73
inital blackoil version where classes intended to change for sequent…
hnil Apr 29, 2020
9f15a19
Introduced linearization type
hnil Jun 5, 2020
847fce0
Draft of sequential
hnil Jun 5, 2020
9d6e023
Draft of pressure update for sequential
hnil Jun 6, 2020
45b9f83
pressure draft almost ok
hnil Jun 6, 2020
c2d6c65
sequential pressure solver compile
hnil Jun 7, 2020
3055f17
draft of new flux calculations
hnil Jun 8, 2020
67730ce
draft sequential implicit
hnil Jun 8, 2020
ed0dee7
fixed forgotten return of report
hnil Jun 8, 2020
92ca7f9
compiling version of new eclfluxmodule
hnil Jun 9, 2020
3c20d36
added cappilary contribution and made checking better
hnil Jun 9, 2020
b6b40f1
seems to be correct with for test without capillary and gravity
hnil Jun 9, 2020
039450a
added pressure and total saturation to eclproblem. better checking of…
hnil Jun 10, 2020
59807d7
added pressure as type to convergenceReport
hnil Jun 10, 2020
f249701
added update of varibles in case timestepping is changed from step to…
hnil Jun 10, 2020
542ad82
added pressure convergence criteria
hnil Jun 10, 2020
51e34ff
added storage of totalflux fixed recusive error
hnil Jun 10, 2020
fde90a6
added totalFlux for compatibility, need to remove all calles in flow...
hnil Jun 11, 2020
aa2c87b
added SimulationType
hnil Jun 11, 2020
e5007f0
made pressure 3 vector
hnil Jun 11, 2020
a2ef74a
fixed missin report in step
hnil Jun 11, 2020
0f0410e
fixed upwind of ST and a whitespace in text
hnil Jun 11, 2020
d1a877c
added writing of pressure system, fixed solving of pressure
hnil Jun 12, 2020
73142e5
fixed cmake file with new system
hnil Jun 12, 2020
417a7e7
fixing the parallel compilation related to parallelInformation_
GitPaean Jun 12, 2020
9e9b46d
adding assembleControlEqSeqTrans to StandardWell
GitPaean Jun 12, 2020
995cbe1
calculate the perforation reservoir rates and total reservoir rates.
GitPaean Jun 12, 2020
9a3d9f6
fixed some convergence criteria for sequential, some sequential simul…
hnil Jun 12, 2020
8ade2cd
Working code we separate blackoil quantities
hnil Jun 17, 2020
98dc501
quite much work for the sequential
hnil Jun 20, 2020
98283df
Seems like a lot of thing go through
hnil Jun 20, 2020
1947441
fixed timestepping for zero error
hnil Jun 21, 2020
263f688
tried to make less updates to prepeare for iterations
hnil Jun 21, 2020
20bde84
explitly disable storagechace when implicite sequential: NB give dif…
hnil Jun 21, 2020
0968361
fixed sign
hnil Jun 22, 2020
3fefe86
fixed unincial
hnil Jun 23, 2020
21d006f
Try to fix the well part
hnil Jun 23, 2020
9b7df50
adding perfTotalResRates to WellStateFullyImplicitBlackoil
GitPaean Jun 23, 2020
df134c1
added possibility to solve wells
hnil Jun 23, 2020
8210505
added solving of wells
hnil Jun 23, 2020
50410c7
tried to make minimal change for using wellstate
hnil Jun 23, 2020
e9d6749
compile again
hnil Jun 23, 2020
9ad2c97
some fixes
hnil Jun 24, 2020
c9af1fb
Force ST to be 1 at start of sequential step
hnil Jun 24, 2020
49d237c
tried to clean up the stepping
hnil Jun 24, 2020
434dc6a
added writout of saturation, fixed bug in total saturation update
hnil Jun 25, 2020
59ca45c
added reseting of totalsaturation
hnil Jun 25, 2020
a5b3843
make safer total saturation update if failed
hnil Jun 25, 2020
0c9edda
renameing for easier search after totalSaturation
hnil Jun 25, 2020
8780d52
using previous well state for flux cacluation in sequential
hnil Jun 26, 2020
79bb58f
hopefully a working version
hnil Jun 26, 2020
fb9c2bb
fixing compilation after the rebasing.
GitPaean Jun 26, 2020
facd42b
fixing the running of flow_blackoil with this branch
GitPaean Jun 29, 2020
838ee46
saving two pressures in eclproblem
GitPaean Jul 29, 2020
a230b5b
not updating the explicit quantities for well for transport solve
GitPaean Jul 29, 2020
6038edf
fixing the compilation after rebasing to master
GitPaean Jul 30, 2020
9594da0
Fixing to make both MPI and no-MPI work.
atgeirr Jul 31, 2020
5d4b8b5
Use four digits for timesteps in extra output file names.
atgeirr Jul 31, 2020
b889471
for now do now switching when updating presssure
hnil Aug 4, 2020
045877d
added fix to get min(rs,rsSat)
hnil Aug 5, 2020
7c15117
fixed Rv error
hnil Aug 5, 2020
83d8965
fix RV part for limiting RV on pressure solve
hnil Aug 5, 2020
a694575
working version for spe1case2
hnil Aug 7, 2020
acec19d
added chopping off sT, for now hardcoded.
hnil Aug 7, 2020
d04b4bf
fixing the bug when chopping the delta in eclblackoilnewtonmethod
GitPaean Aug 10, 2020
f0d1a86
using umfpack as the default pressure solver
GitPaean Aug 10, 2020
9db26ac
trying to add a test for sequential running for SPE1CASE2
GitPaean Aug 10, 2020
d7e9530
fixing the time step calculation
GitPaean Aug 11, 2020
2f02b8d
go back to have state to be undersaturationed with rs=min(rsSat,rs) a…
hnil Aug 12, 2020
25be861
Move mis-merged block of debug code.
atgeirr Aug 12, 2020
58243e9
adding two totalSaturation_ in eclproblem
GitPaean Aug 12, 2020
8dad639
fixing the compilatin of ebos_plain
GitPaean Aug 12, 2020
ac6947e
During pressure solve, testing the perforation rates
GitPaean Aug 12, 2020
1bc2bd1
only writing extra_out for sequential running.
GitPaean Aug 12, 2020
db3988a
added report on timing iteration ++ for pressure and transport solve
hnil Aug 13, 2020
59af419
removing solveWells function in BlackoilWellModel
GitPaean Aug 14, 2020
2a05642
cleaing up the well code a little bit
GitPaean Aug 14, 2020
fc7eead
eclblackoilprimaryvariables adapts the changes in
GitPaean Aug 14, 2020
f1f4b85
restructuring to prepare for iterative
hnil Aug 17, 2020
ce76599
removed default argument for timeidx, fixed bug for refactored code
hnil Aug 17, 2020
7f5c38a
trying to output unconverged well residuals
GitPaean Aug 18, 2020
444e26d
Better logging
hnil Aug 18, 2020
8c5524e
added parameters and refactored use of pressure linear solver
hnil Aug 18, 2020
5b598ac
made policy more like mrst.
hnil Aug 18, 2020
735c4c0
changed policy fixed output
hnil Aug 18, 2020
86b48cb
eclblackoilprimaryvariables inherits blackoilprimaryvariables
GitPaean Aug 19, 2020
77dd11c
Introduced more settings for pressure solver and reuse of pressure ma…
hnil Aug 19, 2020
f9f4657
removing the duplicated assignNaive in eclblackoilprimaryvariables.hh
GitPaean Aug 19, 2020
2c92bb5
adapting the changes in eclblackoilintensivequantities.hh
GitPaean Aug 20, 2020
bd70a6b
adding output of the well convergence information for debugging purpose.
GitPaean Aug 21, 2020
b751342
cleaning up EclBlackOilNewtonMethod
GitPaean Aug 21, 2020
35e2d68
corrected output of total saturation
hnil Aug 21, 2020
cf98503
Merge branch 'master' into hnil_sequential_september
GitPaean Sep 22, 2020
b1ab757
fixing compilation after merging master.
GitPaean Sep 22, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,25 @@ opm_add_test(flow_blackoil_dunecpr
DEPENDS opmsimulators
LIBRARIES opmsimulators)

opm_add_test(flow_blackoil_dunecpr_noflex
ONLY_COMPILE
DEFAULT_ENABLE_IF ${FLOW_VARIANTS_DEFAULT_ENABLE_IF}
SOURCES flow/flow_blackoil_dunecpr_noflex.cpp
$<TARGET_OBJECTS:moduleVersion>
EXE_NAME flow_blackoil_dunecpr_noflex
DEPENDS "opmsimulators"
LIBRARIES "opmsimulators")

opm_add_test(flow_blackoil_dunecpr_seq
ONLY_COMPILE
DEFAULT_ENABLE_IF ${FLOW_VARIANTS_DEFAULT_ENABLE_IF}
SOURCES flow/flow_blackoil_dunecpr_seq.cpp
$<TARGET_OBJECTS:moduleVersion>
EXE_NAME flow_blackoil_dunecpr_seq
DEPENDS "opmsimulators"
LIBRARIES "opmsimulators")


opm_add_test(flow_onephase
ONLY_COMPILE
DEFAULT_ENABLE_IF ${FLOW_VARIANTS_DEFAULT_ENABLE_IF}
Expand Down
8 changes: 8 additions & 0 deletions compareECLFiles.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,14 @@ add_test_compareECLFiles(CASENAME spe1
ABS_TOL ${abs_tol}
REL_TOL ${coarse_rel_tol})

add_test_compareECLFiles(CASENAME spe12_seq
FILENAME SPE1CASE2
SIMULATOR flow_blackoil_dunecpr_seq
ABS_TOL ${abs_tol}
REL_TOL ${rel_tol}
DIR spe1
TEST_ARGS --full-time-step-initially=true --enable-adaptive-time-stepping=false --simulation-type=seq --enable-storage-cache=false)

add_test_compareECLFiles(CASENAME spe1_2p
FILENAME SPE1CASE2_2P
SIMULATOR flow
Expand Down
2 changes: 1 addition & 1 deletion ebos/ebos_plain.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ namespace Opm::Properties {

namespace TTag {
struct EbosPlainTypeTag {
using InheritsFrom = std::tuple<EclBaseProblem, BlackOilModel>;
using InheritsFrom = std::tuple<EclBaseProblem, BlackOilModel, FlowModelParameters>;
};
}

Expand Down
560 changes: 560 additions & 0 deletions ebos/eclblackoilintensivequantities.hh

Large diffs are not rendered by default.

325 changes: 325 additions & 0 deletions ebos/eclblackoilnewtonmethod.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,325 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
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 2 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/>.

Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
*
* \copydoc Opm::BlackOilNewtonMethod
*/
#ifndef EWOMS_ECL_BLACK_OIL_NEWTON_METHOD_HH
#define EWOMS_ECL_BLACK_OIL_NEWTON_METHOD_HH

#include <opm/models/blackoil/blackoilnewtonmethod.hh>

namespace Opm {

/*!
* \ingroup BlackOilModel
*
* \brief A newton solver which is specific to the black oil model.
*/
template <class TypeTag>
class EclBlackOilNewtonMethod : public GetPropType<TypeTag, Properties::DiscNewtonMethod>
{
using ParentType = GetPropType<TypeTag, Properties::DiscNewtonMethod>;
using Simulator = GetPropType<TypeTag, Properties::Simulator>;
using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>;
using GlobalEqVector = GetPropType<TypeTag, Properties::GlobalEqVector>;
using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
using EqVector = GetPropType<TypeTag, Properties::EqVector>;
using Indices = GetPropType<TypeTag, Properties::Indices>;
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using Linearizer = GetPropType<TypeTag, Properties::Linearizer>;

static const unsigned numEq = getPropValue<TypeTag, Properties::NumEq>();

public:
EclBlackOilNewtonMethod(Simulator& simulator) : ParentType(simulator)
{
priVarOscilationThreshold_ = EWOMS_GET_PARAM(TypeTag, Scalar, PriVarOscilationThreshold);
dpMaxRel_ = EWOMS_GET_PARAM(TypeTag, Scalar, DpMaxRel);
dsMax_ = EWOMS_GET_PARAM(TypeTag, Scalar, DsMax);
projectSaturations_ = EWOMS_GET_PARAM(TypeTag, bool, ProjectSaturations);
}

/*!
* \copydoc NewtonMethod::finishInit()
*/
void finishInit()
{
ParentType::finishInit();

wasSwitched_.resize(this->model().numTotalDof());
std::fill(wasSwitched_.begin(), wasSwitched_.end(), false);
}

/*!
* \brief Register all run-time parameters for the immiscible model.
*/
static void registerParameters()
{
ParentType::registerParameters();

EWOMS_REGISTER_PARAM(TypeTag, Scalar, DpMaxRel, "Maximum relative change of pressure in a single iteration");
EWOMS_REGISTER_PARAM(TypeTag, Scalar, DsMax, "Maximum absolute change of any saturation in a single iteration");
EWOMS_REGISTER_PARAM(TypeTag, Scalar, PriVarOscilationThreshold,
"The threshold value for the primary variable switching conditions after its meaning has switched to hinder oscilations");
EWOMS_REGISTER_PARAM(TypeTag,bool, ProjectSaturations, "Option for doing saturation projection");
}

/*!
* \brief Returns the number of degrees of freedom for which the
* interpretation has changed for the most recent iteration.
*/
unsigned numPriVarsSwitched() const
{ return numPriVarsSwitched_; }

protected:
friend NewtonMethod<TypeTag>;
friend ParentType;

/*!
* \copydoc FvBaseNewtonMethod::beginIteration_
*/
void beginIteration_()
{
numPriVarsSwitched_ = 0;
ParentType::beginIteration_();
}

/*!
* \copydoc FvBaseNewtonMethod::endIteration_
*/
void endIteration_(SolutionVector& uCurrentIter,
const SolutionVector& uLastIter)
{
#if HAVE_MPI
// in the MPI enabled case we need to add up the number of DOF
// for which the interpretation changed over all processes.
int localSwitched = numPriVarsSwitched_;
MPI_Allreduce(&localSwitched,
&numPriVarsSwitched_,
/*num=*/1,
MPI_INT,
MPI_SUM,
MPI_COMM_WORLD);
#endif // HAVE_MPI

this->simulator_.model().newtonMethod().endIterMsg()
<< ", num switched=" << numPriVarsSwitched_;

ParentType::endIteration_(uCurrentIter, uLastIter);
}

public:
void update_(SolutionVector& nextSolution,
const SolutionVector& currentSolution,
const GlobalEqVector& solutionUpdate,
const GlobalEqVector& currentResidual)
{
const auto& comm = this->simulator_.gridView().comm();

int succeeded;
try {
ParentType::update_(nextSolution,
currentSolution,
solutionUpdate,
currentResidual);
succeeded = 1;
}
catch (...) {
std::cout << "Newton update threw an exception on rank "
<< comm.rank() << "\n";
succeeded = 0;
}
succeeded = comm.min(succeeded);

if (!succeeded)
throw Opm::NumericalIssue("A process did not succeed in adapting the primary variables");

numPriVarsSwitched_ = comm.sum(numPriVarsSwitched_);
}

protected:
/*!
* \copydoc FvBaseNewtonMethod::updatePrimaryVariables_
*/
void updatePrimaryVariables_(unsigned globalDofIdx,
PrimaryVariables& nextValue,
const PrimaryVariables& currentValue,
const EqVector& update,
const EqVector& currentResidual)
{
static constexpr bool enableSolvent = Indices::solventSaturationIdx >= 0;
static constexpr bool enablePolymer = Indices::polymerConcentrationIdx >= 0;
static constexpr bool enablePolymerWeight = Indices::polymerMoleWeightIdx >= 0;
static constexpr bool enableEnergy = Indices::temperatureIdx >= 0;
static constexpr bool enableFoam = Indices::foamConcentrationIdx >= 0;
static constexpr bool enableBrine = Indices::saltConcentrationIdx >= 0;

currentValue.checkDefined();
Opm::Valgrind::CheckDefined(update);
Opm::Valgrind::CheckDefined(currentResidual);

// saturation delta for each phase
Scalar deltaSw = 0.0;
Scalar deltaSo = 0.0;
Scalar deltaSg = 0.0;
Scalar deltaSs = 0.0;

if (Indices::waterEnabled) {
deltaSw = update[Indices::waterSaturationIdx];
deltaSo = -deltaSw;
}

if (Indices::gasEnabled && currentValue.primaryVarsMeaning() == PrimaryVariables::Sw_po_Sg) {
deltaSg = update[Indices::compositionSwitchIdx];
deltaSo -= deltaSg;
}

if (enableSolvent) {
deltaSs = update[Indices::solventSaturationIdx];
deltaSo -= deltaSs;
}

// maximum saturation delta
Scalar maxSatDelta = std::max(std::abs(deltaSg), std::abs(deltaSo));
maxSatDelta = std::max(maxSatDelta, std::abs(deltaSw));
maxSatDelta = std::max(maxSatDelta, std::abs(deltaSs));

// scaling factor for saturation deltas to make sure that none of them exceeds
// the specified threshold value.
Scalar satAlpha = 1.0;
if (maxSatDelta > dsMax_)
satAlpha = dsMax_/maxSatDelta;

for (int pvIdx = 0; pvIdx < int(numEq); ++pvIdx) {
// calculate the update of the current primary variable. For the black-oil
// model we limit the pressure delta relative to the pressure's current
// absolute value (Default: 30%) and saturation deltas to an absolute change
// (Default: 20%). Further, we ensure that the R factors, solvent
// "saturation" and polymer concentration do not become negative after the
// update.
Scalar delta = update[pvIdx];

// limit pressure delta
if (pvIdx == Indices::pressureSwitchIdx) {
LinearizationType linearizationType = this->model().linearizer().getLinearizationType();
if (linearizationType.type == Opm::LinearizationType::seqtransport) {
// TODO: set max update of ST
delta = Opm::signum(delta) * std::min(std::abs(delta), 0.1);
} else {
if (std::abs(delta) > dpMaxRel_*currentValue[pvIdx])
delta = Opm::signum(delta)*dpMaxRel_*currentValue[pvIdx];
}
}
// water saturation delta
else if (pvIdx == Indices::waterSaturationIdx)
delta *= satAlpha;
else if (pvIdx == Indices::compositionSwitchIdx) {
// the switching primary variable for composition is tricky because the
// "reasonable" value ranges it exhibits vary widely depending on its
// interpretation since it can represent Sg, Rs or Rv. For now, we only
// limit saturation deltas and ensure that the R factors do not become
// negative.
if (currentValue.primaryVarsMeaning() == PrimaryVariables::Sw_po_Sg)
delta *= satAlpha;
else {
if (delta > currentValue[Indices::compositionSwitchIdx])
delta = currentValue[Indices::compositionSwitchIdx];
}
}
else if (enableSolvent && pvIdx == Indices::solventSaturationIdx)
// solvent saturation updates are also subject to the Appleyard chop
delta *= satAlpha;
else if (enablePolymerWeight && pvIdx == Indices::polymerMoleWeightIdx) {
const double sign = delta >= 0. ? 1. : -1.;
// maximum change of polymer molecular weight, the unit is MDa.
// applying this limit to stabilize the simulation. The value itself is still experimental.
const double maxMolarWeightChange = 100.0;
delta = sign * std::min(std::abs(delta), maxMolarWeightChange);
delta *= satAlpha;
}

// do the actual update
nextValue[pvIdx] = currentValue[pvIdx] - delta;

// keep the solvent saturation between 0 and 1
if (enableSolvent && pvIdx == Indices::solventSaturationIdx)
nextValue[pvIdx] = std::min(std::max(nextValue[pvIdx], 0.0), 1.0);

// keep the polymer concentration above 0
if (enablePolymer && pvIdx == Indices::polymerConcentrationIdx)
nextValue[pvIdx] = std::max(nextValue[pvIdx], 0.0);

if (enablePolymerWeight && pvIdx == Indices::polymerMoleWeightIdx) {
nextValue[pvIdx] = std::max(nextValue[pvIdx], 0.0);
const double polymerConcentration = nextValue[Indices::polymerConcentrationIdx];
if (polymerConcentration < 1.e-10)
nextValue[pvIdx] = 0.0;
}

// keep the foam concentration above 0
if (enableFoam && pvIdx == Indices::foamConcentrationIdx)
nextValue[pvIdx] = std::max(nextValue[pvIdx], 0.0);

// keep the salt concentration above 0
if (enableBrine && pvIdx == Indices::saltConcentrationIdx)
nextValue[pvIdx] = std::max(nextValue[pvIdx], 0.0);

// keep the temperature above 100 and below 1000 Kelvin
if (enableEnergy && pvIdx == Indices::temperatureIdx)
nextValue[pvIdx] = std::max(std::min(nextValue[pvIdx], 1000.0), 100.0);
}

// switch the new primary variables to something which is physically meaningful.
// use a threshold value after a switch to make it harder to switch back
// immediately.
if (wasSwitched_[globalDofIdx])
wasSwitched_[globalDofIdx] = nextValue.adaptPrimaryVariables(this->problem(), globalDofIdx, priVarOscilationThreshold_);
else
wasSwitched_[globalDofIdx] = nextValue.adaptPrimaryVariables(this->problem(), globalDofIdx);

if (wasSwitched_[globalDofIdx])
++ numPriVarsSwitched_;
if(projectSaturations_){
nextValue.chopAndNormalizeSaturations();
}

nextValue.checkDefined();
}

private:
int numPriVarsSwitched_;

Scalar priVarOscilationThreshold_;
Scalar dpMaxRel_;
Scalar dsMax_;
bool projectSaturations_;

// keep track of cells where the primary variable meaning has changed
// to detect and hinder oscillations
std::vector<bool> wasSwitched_;
};
} // namespace Opm

#endif
Loading