mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #854 from totto82/addBondaryFluxOutput
Add bondary flux output
This commit is contained in:
commit
a928b8ffe3
@ -515,10 +515,13 @@ public:
|
|||||||
using Dir = FaceDir::DirEnum;
|
using Dir = FaceDir::DirEnum;
|
||||||
if (dirMob_) {
|
if (dirMob_) {
|
||||||
switch(facedir) {
|
switch(facedir) {
|
||||||
|
case Dir::XMinus:
|
||||||
case Dir::XPlus:
|
case Dir::XPlus:
|
||||||
return dirMob_->mobilityX_[phaseIdx];
|
return dirMob_->mobilityX_[phaseIdx];
|
||||||
|
case Dir::YMinus:
|
||||||
case Dir::YPlus:
|
case Dir::YPlus:
|
||||||
return dirMob_->mobilityY_[phaseIdx];
|
return dirMob_->mobilityY_[phaseIdx];
|
||||||
|
case Dir::ZMinus:
|
||||||
case Dir::ZPlus:
|
case Dir::ZPlus:
|
||||||
return dirMob_->mobilityZ_[phaseIdx];
|
return dirMob_->mobilityZ_[phaseIdx];
|
||||||
default:
|
default:
|
||||||
|
@ -116,7 +116,7 @@ public:
|
|||||||
double faceArea;
|
double faceArea;
|
||||||
double thpres;
|
double thpres;
|
||||||
double dZg;
|
double dZg;
|
||||||
FaceDir::DirEnum faceDirection;
|
int dirId;
|
||||||
double Vin;
|
double Vin;
|
||||||
double Vex;
|
double Vex;
|
||||||
double inAlpha;
|
double inAlpha;
|
||||||
@ -272,11 +272,7 @@ public:
|
|||||||
const auto& globalIndexEx = stencil.globalSpaceIndex(exteriorDofIdx);
|
const auto& globalIndexEx = stencil.globalSpaceIndex(exteriorDofIdx);
|
||||||
Scalar trans = problem.transmissibility(elemCtx, interiorDofIdx, exteriorDofIdx);
|
Scalar trans = problem.transmissibility(elemCtx, interiorDofIdx, exteriorDofIdx);
|
||||||
Scalar faceArea = scvf.area();
|
Scalar faceArea = scvf.area();
|
||||||
const auto& materialLawManager = problem.materialLawManager();
|
const auto dirid = scvf.dirId();
|
||||||
FaceDir::DirEnum facedir = FaceDir::DirEnum::Unknown; // Use an arbitrary
|
|
||||||
if (materialLawManager->hasDirectionalRelperms()) {
|
|
||||||
facedir = scvf.faceDirFromDirId();
|
|
||||||
}
|
|
||||||
Scalar thpres = problem.thresholdPressure(globalIndexIn, globalIndexEx);
|
Scalar thpres = problem.thresholdPressure(globalIndexIn, globalIndexEx);
|
||||||
|
|
||||||
// estimate the gravity correction: for performance reasons we use a simplified
|
// estimate the gravity correction: for performance reasons we use a simplified
|
||||||
@ -302,7 +298,7 @@ public:
|
|||||||
const Scalar diffusivity = problem.diffusivity(globalIndexEx, globalIndexIn);
|
const Scalar diffusivity = problem.diffusivity(globalIndexEx, globalIndexIn);
|
||||||
const Scalar dispersivity = problem.dispersivity(globalIndexEx, globalIndexIn);
|
const Scalar dispersivity = problem.dispersivity(globalIndexEx, globalIndexIn);
|
||||||
|
|
||||||
const ResidualNBInfo res_nbinfo {trans, faceArea, thpres, distZ * g, facedir, Vin, Vex, inAlpha, outAlpha, diffusivity, dispersivity};
|
const ResidualNBInfo res_nbinfo {trans, faceArea, thpres, distZ * g, dirid, Vin, Vex, inAlpha, outAlpha, diffusivity, dispersivity};
|
||||||
|
|
||||||
calculateFluxes_(flux,
|
calculateFluxes_(flux,
|
||||||
darcy,
|
darcy,
|
||||||
@ -328,7 +324,7 @@ public:
|
|||||||
const Scalar thpres = nbInfo.thpres;
|
const Scalar thpres = nbInfo.thpres;
|
||||||
const Scalar trans = nbInfo.trans;
|
const Scalar trans = nbInfo.trans;
|
||||||
const Scalar faceArea = nbInfo.faceArea;
|
const Scalar faceArea = nbInfo.faceArea;
|
||||||
const FaceDir::DirEnum facedir = nbInfo.faceDirection;
|
FaceDir::DirEnum facedir = faceDirFromDirId(nbInfo.dirId);
|
||||||
|
|
||||||
for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
|
for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
|
||||||
if (!FluidSystem::phaseIsActive(phaseIdx))
|
if (!FluidSystem::phaseIsActive(phaseIdx))
|
||||||
@ -787,6 +783,16 @@ public:
|
|||||||
FluidSystem::referenceDensity(oilPhaseIdx, pvtRegionIdx);
|
FluidSystem::referenceDensity(oilPhaseIdx, pvtRegionIdx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static FaceDir::DirEnum faceDirFromDirId(const int dirId)
|
||||||
|
{
|
||||||
|
// NNC does not have a direction
|
||||||
|
if (dirId < 0 ) {
|
||||||
|
return FaceDir::DirEnum::Unknown;
|
||||||
|
}
|
||||||
|
return FaceDir::FromIntersectionIndex(dirId);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Opm
|
} // namespace Opm
|
||||||
|
@ -311,6 +311,10 @@ public:
|
|||||||
// This linearizer stores no such data.
|
// This linearizer stores no such data.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateFlowsInfo() {
|
||||||
|
// This linearizer stores no such data.
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the map of constraint degrees of freedom.
|
* \brief Returns the map of constraint degrees of freedom.
|
||||||
*
|
*
|
||||||
|
@ -434,8 +434,6 @@ private:
|
|||||||
unsigned numCells = model.numTotalDof();
|
unsigned numCells = model.numTotalDof();
|
||||||
neighborInfo_.reserve(numCells, 6 * numCells);
|
neighborInfo_.reserve(numCells, 6 * numCells);
|
||||||
std::vector<NeighborInfo> loc_nbinfo;
|
std::vector<NeighborInfo> loc_nbinfo;
|
||||||
const auto& materialLawManager = problem_().materialLawManager();
|
|
||||||
using FaceDirection = FaceDir::DirEnum;
|
|
||||||
for (const auto& elem : elements(gridView_())) {
|
for (const auto& elem : elements(gridView_())) {
|
||||||
stencil.update(elem);
|
stencil.update(elem);
|
||||||
|
|
||||||
@ -459,7 +457,6 @@ private:
|
|||||||
const Scalar thpres = problem_().thresholdPressure(myIdx, neighborIdx);
|
const Scalar thpres = problem_().thresholdPressure(myIdx, neighborIdx);
|
||||||
Scalar inAlpha {0.};
|
Scalar inAlpha {0.};
|
||||||
Scalar outAlpha {0.};
|
Scalar outAlpha {0.};
|
||||||
FaceDirection dirId = FaceDirection::Unknown;
|
|
||||||
Scalar diffusivity {0.};
|
Scalar diffusivity {0.};
|
||||||
Scalar dispersivity {0.};
|
Scalar dispersivity {0.};
|
||||||
if constexpr(enableEnergy){
|
if constexpr(enableEnergy){
|
||||||
@ -472,9 +469,7 @@ private:
|
|||||||
if (simulator_().vanguard().eclState().getSimulationConfig().rock_config().dispersion()) {
|
if (simulator_().vanguard().eclState().getSimulationConfig().rock_config().dispersion()) {
|
||||||
dispersivity = problem_().dispersivity(myIdx, neighborIdx);
|
dispersivity = problem_().dispersivity(myIdx, neighborIdx);
|
||||||
}
|
}
|
||||||
if (materialLawManager->hasDirectionalRelperms()) {
|
auto dirId = scvf.dirId();
|
||||||
dirId = scvf.faceDirFromDirId();
|
|
||||||
}
|
|
||||||
loc_nbinfo[dofIdx - 1] = NeighborInfo{neighborIdx, {trans, area, thpres, dZg, dirId, Vin, Vex, inAlpha, outAlpha, diffusivity, dispersivity}, nullptr};
|
loc_nbinfo[dofIdx - 1] = NeighborInfo{neighborIdx, {trans, area, thpres, dZg, dirId, Vin, Vex, inAlpha, outAlpha, diffusivity, dispersivity}, nullptr};
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -583,8 +578,10 @@ private:
|
|||||||
stencil.update(elem);
|
stencil.update(elem);
|
||||||
for (unsigned primaryDofIdx = 0; primaryDofIdx < stencil.numPrimaryDof(); ++primaryDofIdx) {
|
for (unsigned primaryDofIdx = 0; primaryDofIdx < stencil.numPrimaryDof(); ++primaryDofIdx) {
|
||||||
unsigned myIdx = stencil.globalSpaceIndex(primaryDofIdx);
|
unsigned myIdx = stencil.globalSpaceIndex(primaryDofIdx);
|
||||||
loc_flinfo.resize(stencil.numDof() - 1);
|
int numFaces = stencil.numBoundaryFaces() + stencil.numInteriorFaces();
|
||||||
|
loc_flinfo.resize(numFaces);
|
||||||
loc_vlinfo.resize(stencil.numDof() - 1);
|
loc_vlinfo.resize(stencil.numDof() - 1);
|
||||||
|
|
||||||
for (unsigned dofIdx = 0; dofIdx < stencil.numDof(); ++dofIdx) {
|
for (unsigned dofIdx = 0; dofIdx < stencil.numDof(); ++dofIdx) {
|
||||||
unsigned neighborIdx = stencil.globalSpaceIndex(dofIdx);
|
unsigned neighborIdx = stencil.globalSpaceIndex(dofIdx);
|
||||||
if (dofIdx > 0) {
|
if (dofIdx > 0) {
|
||||||
@ -605,7 +602,15 @@ private:
|
|||||||
loc_flinfo[dofIdx - 1] = FlowInfo{faceId, flow, nncId};
|
loc_flinfo[dofIdx - 1] = FlowInfo{faceId, flow, nncId};
|
||||||
loc_vlinfo[dofIdx - 1] = VelocityInfo{flow};
|
loc_vlinfo[dofIdx - 1] = VelocityInfo{flow};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned bdfIdx = 0; bdfIdx < stencil.numBoundaryFaces(); ++bdfIdx) {
|
||||||
|
const auto& scvf = stencil.boundaryFace(bdfIdx);
|
||||||
|
int faceId = scvf.dirId();
|
||||||
|
loc_flinfo[stencil.numInteriorFaces() + bdfIdx] = FlowInfo{faceId, flow, nncId};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (anyFlows) {
|
if (anyFlows) {
|
||||||
flowsInfo_.appendRow(loc_flinfo.begin(), loc_flinfo.end());
|
flowsInfo_.appendRow(loc_flinfo.begin(), loc_flinfo.end());
|
||||||
}
|
}
|
||||||
@ -636,6 +641,68 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateFlowsInfo() {
|
||||||
|
OPM_TIMEBLOCK(updateFlows);
|
||||||
|
const bool& enableFlows = simulator_().problem().eclWriter()->eclOutputModule().hasFlows() ||
|
||||||
|
simulator_().problem().eclWriter()->eclOutputModule().hasBlockFlows();
|
||||||
|
const bool& enableFlores = simulator_().problem().eclWriter()->eclOutputModule().hasFlores();
|
||||||
|
if (!enableFlows && !enableFlores) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const unsigned int numCells = model_().numTotalDof();
|
||||||
|
|
||||||
|
#ifdef _OPENMP
|
||||||
|
#pragma omp parallel for
|
||||||
|
#endif
|
||||||
|
for (unsigned globI = 0; globI < numCells; ++globI) {
|
||||||
|
OPM_TIMEBLOCK_LOCAL(linearizationForEachCell);
|
||||||
|
const auto& nbInfos = neighborInfo_[globI];
|
||||||
|
ADVectorBlock adres(0.0);
|
||||||
|
ADVectorBlock darcyFlux(0.0);
|
||||||
|
const IntensiveQuantities& intQuantsIn = model_().intensiveQuantities(globI, /*timeIdx*/ 0);
|
||||||
|
// Flux term.
|
||||||
|
{
|
||||||
|
OPM_TIMEBLOCK_LOCAL(fluxCalculationForEachCell);
|
||||||
|
for (const auto& nbInfo : nbInfos) {
|
||||||
|
OPM_TIMEBLOCK_LOCAL(fluxCalculationForEachFace);
|
||||||
|
unsigned globJ = nbInfo.neighbor;
|
||||||
|
assert(globJ != globI);
|
||||||
|
adres = 0.0;
|
||||||
|
darcyFlux = 0.0;
|
||||||
|
const IntensiveQuantities& intQuantsEx = model_().intensiveQuantities(globJ, /*timeIdx*/ 0);
|
||||||
|
LocalResidual::computeFlux(adres,darcyFlux, globI, globJ, intQuantsIn, intQuantsEx, nbInfo.res_nbinfo);
|
||||||
|
adres *= nbInfo.res_nbinfo.faceArea;
|
||||||
|
if (enableFlows) {
|
||||||
|
for (unsigned phaseIdx = 0; phaseIdx < numEq; ++ phaseIdx) {
|
||||||
|
flowsInfo_[globI][nbInfo.res_nbinfo.dirId].flow[phaseIdx] = adres[phaseIdx].value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (enableFlores) {
|
||||||
|
for (unsigned phaseIdx = 0; phaseIdx < numEq; ++ phaseIdx) {
|
||||||
|
floresInfo_[globI][nbInfo.res_nbinfo.dirId].flow[phaseIdx] = darcyFlux[phaseIdx].value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Boundary terms. Only looping over cells with nontrivial bcs.
|
||||||
|
for (const auto& bdyInfo : boundaryInfo_) {
|
||||||
|
ADVectorBlock adres(0.0);
|
||||||
|
const unsigned globI = bdyInfo.cell;
|
||||||
|
const IntensiveQuantities& insideIntQuants = model_().intensiveQuantities(globI, /*timeIdx*/ 0);
|
||||||
|
LocalResidual::computeBoundaryFlux(adres, problem_(), bdyInfo.bcdata, insideIntQuants, globI);
|
||||||
|
adres *= bdyInfo.bcdata.faceArea;
|
||||||
|
|
||||||
|
if (enableFlows) {
|
||||||
|
for (unsigned phaseIdx = 0; phaseIdx < numEq; ++ phaseIdx) {
|
||||||
|
flowsInfo_[globI][bdyInfo.dir].flow[phaseIdx] = adres[phaseIdx].value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO also store Flores?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <class SubDomainType>
|
template <class SubDomainType>
|
||||||
void linearize_(const SubDomainType& domain)
|
void linearize_(const SubDomainType& domain)
|
||||||
@ -655,9 +722,6 @@ private:
|
|||||||
// the full system to zero, not just our part.
|
// the full system to zero, not just our part.
|
||||||
// Instead, that must be called before starting the linearization.
|
// Instead, that must be called before starting the linearization.
|
||||||
const bool& enableDispersion = simulator_().vanguard().eclState().getSimulationConfig().rock_config().dispersion();
|
const bool& enableDispersion = simulator_().vanguard().eclState().getSimulationConfig().rock_config().dispersion();
|
||||||
const bool& enableFlows = simulator_().problem().eclWriter()->eclOutputModule().hasFlows() ||
|
|
||||||
simulator_().problem().eclWriter()->eclOutputModule().hasBlockFlows();
|
|
||||||
const bool& enableFlores = simulator_().problem().eclWriter()->eclOutputModule().hasFlores();
|
|
||||||
const unsigned int numCells = domain.cells.size();
|
const unsigned int numCells = domain.cells.size();
|
||||||
const bool on_full_domain = (numCells == model_().numTotalDof());
|
const bool on_full_domain = (numCells == model_().numTotalDof());
|
||||||
|
|
||||||
@ -694,16 +758,6 @@ private:
|
|||||||
velocityInfo_[globI][loc].velocity[phaseIdx] = darcyFlux[phaseIdx].value() / nbInfo.res_nbinfo.faceArea;
|
velocityInfo_[globI][loc].velocity[phaseIdx] = darcyFlux[phaseIdx].value() / nbInfo.res_nbinfo.faceArea;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (enableFlows) {
|
|
||||||
for (unsigned phaseIdx = 0; phaseIdx < numEq; ++ phaseIdx) {
|
|
||||||
flowsInfo_[globI][loc].flow[phaseIdx] = adres[phaseIdx].value();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (enableFlores) {
|
|
||||||
for (unsigned phaseIdx = 0; phaseIdx < numEq; ++ phaseIdx) {
|
|
||||||
floresInfo_[globI][loc].flow[phaseIdx] = darcyFlux[phaseIdx].value();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setResAndJacobi(res, bMat, adres);
|
setResAndJacobi(res, bMat, adres);
|
||||||
residual_[globI] += res;
|
residual_[globI] += res;
|
||||||
//SparseAdapter syntax: jacobian_->addToBlock(globI, globI, bMat);
|
//SparseAdapter syntax: jacobian_->addToBlock(globI, globI, bMat);
|
||||||
|
Loading…
Reference in New Issue
Block a user