Merge pull request #776 from atgeirr/afr_well_assembly_separate

Add well source terms to the residual separately.
This commit is contained in:
Bård Skaflestad 2023-03-31 11:59:20 +02:00 committed by GitHub
commit c452a9b88a
3 changed files with 52 additions and 13 deletions

View File

@ -562,6 +562,24 @@ public:
source[Indices::contiEnergyEqIdx] *= getPropValue<TypeTag, Properties::BlackOilEnergyScalingFactor>(); source[Indices::contiEnergyEqIdx] *= getPropValue<TypeTag, Properties::BlackOilEnergyScalingFactor>();
} }
static void computeSourceDense(RateVector& source,
const Problem& problem,
unsigned globalSpaceIdex,
unsigned timeIdx)
{
source = 0.0;
problem.addToSourceDense(source, globalSpaceIdex, timeIdx);
// deal with MICP (if present)
// deal with micp (if present)
static_assert(!enableMICP, "Relevant addSource() method must be implemented for this module before enabling.");
// MICPModule::addSource(source, elemCtx, dofIdx, timeIdx);
// scale the source term of the energy equation
if (enableEnergy)
source[Indices::contiEnergyEqIdx] *= getPropValue<TypeTag, Properties::BlackOilEnergyScalingFactor>();
}
/*! /*!
* \copydoc FvBaseLocalResidual::computeSource * \copydoc FvBaseLocalResidual::computeSource
*/ */

View File

@ -523,6 +523,7 @@ public:
IntensiveQuantities::registerParameters(); IntensiveQuantities::registerParameters();
ExtensiveQuantities::registerParameters(); ExtensiveQuantities::registerParameters();
NewtonMethod::registerParameters(); NewtonMethod::registerParameters();
Linearizer::registerParameters();
// register runtime parameters of the output modules // register runtime parameters of the output modules
VtkPrimaryVarsModule<TypeTag>::registerParameters(); VtkPrimaryVarsModule<TypeTag>::registerParameters();

View File

@ -51,8 +51,16 @@
#include <exception> // current_exception, rethrow_exception #include <exception> // current_exception, rethrow_exception
#include <mutex> #include <mutex>
namespace Opm::Properties {
template<class TypeTag, class MyTypeTag>
struct SeparateSparseSourceTerms {
using type = bool;
static constexpr type value = false;
};
}
namespace Opm { namespace Opm {
// forward declarations // forward declarations
template<class TypeTag> template<class TypeTag>
class EcfvDiscretization; class EcfvDiscretization;
@ -110,6 +118,7 @@ public:
: jacobian_() : jacobian_()
{ {
simulatorPtr_ = 0; simulatorPtr_ = 0;
separateSparseSourceTerms_ = EWOMS_GET_PARAM(TypeTag, bool, SeparateSparseSourceTerms);
} }
~TpfaLinearizer() ~TpfaLinearizer()
@ -120,7 +129,10 @@ public:
* \brief Register all run-time parameters for the Jacobian linearizer. * \brief Register all run-time parameters for the Jacobian linearizer.
*/ */
static void registerParameters() static void registerParameters()
{ } {
EWOMS_REGISTER_PARAM(TypeTag, bool, SeparateSparseSourceTerms,
"Treat well source terms all in one go, instead of on a cell by cell basis.");
}
/*! /*!
* \brief Initialize the linearizer. * \brief Initialize the linearizer.
@ -521,7 +533,6 @@ private:
void linearize_() void linearize_()
{ {
OPM_TIMEBLOCK(linearize); OPM_TIMEBLOCK(linearize);
const bool well_local = true;
resetSystem_(); resetSystem_();
unsigned numCells = model_().numTotalDof(); unsigned numCells = model_().numTotalDof();
const bool& enableFlows = simulator_().problem().eclWriter()->eclOutputModule().hasFlows(); const bool& enableFlows = simulator_().problem().eclWriter()->eclOutputModule().hasFlows();
@ -606,21 +617,29 @@ private:
residual_[globI] += res; residual_[globI] += res;
//SparseAdapter syntax: jacobian_->addToBlock(globI, globI, bMat); //SparseAdapter syntax: jacobian_->addToBlock(globI, globI, bMat);
*diagMatAddress_[globI] += bMat; *diagMatAddress_[globI] += bMat;
// wells sources for now (should be moved out)
if (well_local) { // Cell-wise source terms.
OPM_TIMEBLOCK_LOCAL(localWellAssembly); // This will include well sources if SeparateSparseSourceTerms is false.
res = 0.0; res = 0.0;
bMat = 0.0; bMat = 0.0;
adres = 0.0; adres = 0.0;
if (separateSparseSourceTerms_) {
LocalResidual::computeSourceDense(adres, problem_(), globI, 0);
} else {
LocalResidual::computeSource(adres, problem_(), globI, 0); LocalResidual::computeSource(adres, problem_(), globI, 0);
adres *= -volume;
setResAndJacobi(res, bMat, adres);
residual_[globI] += res;
//SparseAdapter syntax: jacobian_->addToBlock(globI, globI, bMat);
*diagMatAddress_[globI] += bMat;
} }
adres *= -volume;
setResAndJacobi(res, bMat, adres);
residual_[globI] += res;
//SparseAdapter syntax: jacobian_->addToBlock(globI, globI, bMat);
*diagMatAddress_[globI] += bMat;
} // end of loop for cell globI. } // end of loop for cell globI.
// Add sparse source terms. For now only wells.
if (separateSparseSourceTerms_) {
problem_().wellModel().addReservoirSourceTerms(residual_, diagMatAddress_);
}
// Boundary terms. Only looping over cells with nontrivial bcs. // Boundary terms. Only looping over cells with nontrivial bcs.
for (const auto& bdyInfo : boundaryInfo_) { for (const auto& bdyInfo : boundaryInfo_) {
VectorBlock res(0.0); VectorBlock res(0.0);
@ -709,6 +728,7 @@ private:
BoundaryConditionData bcdata; BoundaryConditionData bcdata;
}; };
std::vector<BoundaryInfo> boundaryInfo_; std::vector<BoundaryInfo> boundaryInfo_;
bool separateSparseSourceTerms_ = false;
}; };
} // namespace Opm } // namespace Opm