Apply Regional Multipliers to Initial Transmissibilities

This commit adds a new member function,

    EclTransmissibility<>::applyNncMultreg_()

which applies regional transmissibility multipliers such as those
entered in the MULTREGT keyword to the explicit input NNCs.  We make
the application conditional on a new parameter, default value
'false', and pass 'true' as the argument from 'finishInit()'.

Along with TransMult::getRegionMultiplierNNC(), this implements all
known connection behaviours for inter-region connections.
Multipliers internal to a region in MULTREGT are not yet supported.
This commit is contained in:
Bård Skaflestad 2023-08-29 13:32:11 +02:00
parent b209f6af77
commit ddcafa8a91
2 changed files with 80 additions and 13 deletions

View File

@ -119,15 +119,27 @@ public:
* either but at least it seems to be much better.
*/
void finishInit(const std::function<unsigned int(unsigned int)>& map = {})
{ update(true,map); }
{
this->update(true, map, /*applyNncMultRegT = */ true);
}
/*!
* \brief Compute all transmissibilities
*
* \param global If true, update is called on all processes
* Also, this updates the "thermal half transmissibilities" if energy is enabled.
* \param[in] global Whether or not to call \c update() on all
* processes. Also, this updates the "thermal half
* transmissibilities" if energy is enabled.
*
* \param[in] map Undocumented.
*
* \param[in] applyNncMultRegT Whether or not to apply regional
* multipliers to explicit NNCs. Explicit NNCs are those entered
* directly in the input data, e.g., through the NNC/EDITNNC/EDITNNCR
* keywords, or the result of generating connections to or within
* numerical aquifers. Default value: \c false, meaning do not apply
* regional multipliers to explicit NNCs.
*/
void update(bool global, const std::function<unsigned int(unsigned int)>& map = {});
void update(bool global, const std::function<unsigned int(unsigned int)>& map = {}, bool applyNncMultRegT = false);
protected:
void updateFromEclState_(bool global);
@ -202,6 +214,8 @@ protected:
/// \brief Resets the grid transmissibilities according to EDITNNCR.
void applyEditNncrToGridTrans_(const std::unordered_map<std::size_t,int>& globalToLocal);
void applyNncMultreg_(const std::unordered_map<std::size_t,int>& globalToLocal);
void applyEditNncToGridTransHelper_(const std::unordered_map<std::size_t,int>& globalToLocal,
const std::string& keyword, const std::vector<NNCdata>& nncs,
const std::function<KeywordLocation(const NNCdata&)>& getLocation,

View File

@ -40,11 +40,18 @@
#include <fmt/format.h>
#include <algorithm>
#include <array>
#include <cassert>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <initializer_list>
#include <sstream>
#include <stdexcept>
#include <type_traits>
#include <utility>
#include <vector>
namespace {
@ -140,7 +147,7 @@ diffusivity(unsigned elemIdx1, unsigned elemIdx2) const
template<class Grid, class GridView, class ElementMapper, class CartesianIndexMapper, class Scalar>
void EclTransmissibility<Grid,GridView,ElementMapper,CartesianIndexMapper,Scalar>::
update(bool global, const std::function<unsigned int(unsigned int)>& map)
update(bool global, const std::function<unsigned int(unsigned int)>& map, const bool applyNncMultregT)
{
const auto& cartDims = cartMapper_.cartesianDimensions();
const auto& transMult = eclState_.getTransMult();
@ -453,24 +460,29 @@ update(bool global, const std::function<unsigned int(unsigned int)>& map)
}
}
// potentially overwrite and/or modify transmissibilities based on input from deck
updateFromEclState_(global);
// Potentially overwrite and/or modify transmissibilities based on input from deck
this->updateFromEclState_(global);
// Create mapping from global to local index
std::unordered_map<std::size_t,int> globalToLocal;
// loop over all elements (global grid) and store Cartesian index
// Loop over all elements (global grid) and store Cartesian index
for (const auto& elem : elements(grid_.leafGridView())) {
int elemIdx = elemMapper.index(elem);
int cartElemIdx = cartMapper_.cartesianIndex(elemIdx);
globalToLocal[cartElemIdx] = elemIdx;
}
applyEditNncToGridTrans_(globalToLocal);
applyNncToGridTrans_(globalToLocal);
applyEditNncrToGridTrans_(globalToLocal);
//remove very small non-neighbouring transmissibilities
removeSmallNonCartesianTransmissibilities_();
this->applyEditNncToGridTrans_(globalToLocal);
this->applyNncToGridTrans_(globalToLocal);
this->applyEditNncrToGridTrans_(globalToLocal);
if (applyNncMultregT) {
this->applyNncMultreg_(globalToLocal);
}
// Remove very small non-neighbouring transmissibilities.
this->removeSmallNonCartesianTransmissibilities_();
}
template<class Grid, class GridView, class ElementMapper, class CartesianIndexMapper, class Scalar>
@ -965,6 +977,47 @@ applyEditNncToGridTransHelper_(const std::unordered_map<std::size_t,int>& global
}
}
template<class Grid, class GridView, class ElementMapper, class CartesianIndexMapper, class Scalar>
void
EclTransmissibility<Grid,GridView,ElementMapper,CartesianIndexMapper,Scalar>::
applyNncMultreg_(const std::unordered_map<std::size_t,int>& cartesianToCompressed)
{
const auto& inputNNC = this->eclState_.getInputNNC();
const auto& transMult = this->eclState_.getTransMult();
auto compressedIdx = [&cartesianToCompressed](const std::size_t globIdx)
{
auto ixPos = cartesianToCompressed.find(globIdx);
return (ixPos == cartesianToCompressed.end()) ? -1 : ixPos->second;
};
// Recall: NNC::input() covers NNC keyword and numerical aquifers
// NNC::edit() covers EDITNNC keyword
// NNC::editr() covers EDITNNCR keyword
for (const auto& nncList : { &NNC::input, &NNC::edit, &NNC::editr }) {
for (const auto& nncEntry : (inputNNC.*nncList)()) {
const auto c1 = nncEntry.cell1;
const auto c2 = nncEntry.cell2;
auto low = compressedIdx(c1);
auto high = compressedIdx(c2);
if ((low == -1) || (high == -1)) {
continue;
}
if (low > high) {
std::swap(low, high);
}
auto candidate = this->trans_.find(isId(low, high));
if (candidate != this->trans_.end()) {
candidate->second *= transMult.getRegionMultiplierNNC(c1, c2);
}
}
}
}
template<class Grid, class GridView, class ElementMapper, class CartesianIndexMapper, class Scalar>
void EclTransmissibility<Grid,GridView,ElementMapper,CartesianIndexMapper,Scalar>::
computeHalfTrans_(Scalar& halfTrans,