28#include <dune/grid/common/gridenums.hh>
30#include <dune/common/dynmatrix.hh>
31#include <dune/common/dynvector.hh>
33#include <opm/grid/utility/ElementChunks.hpp>
35#include <opm/common/utility/SymmTensor.hpp>
36#include <opm/common/utility/VoigtArray.hpp>
37#include <opm/material/common/MathToolbox.hpp>
46#include <unordered_map>
56template <
class TypeTag>
71 enum { dimWorld = GridView::dimensionworld };
72 enum { historySize = getPropValue<TypeTag, Properties::SolutionHistorySizeTPSA>() };
73 enum { numEq = getPropValue<TypeTag, Properties::NumEqTPSA>() };
75 enum { disp0Idx = Indices::disp0Idx };
76 enum { rot0Idx = Indices::rot0Idx };
77 enum { solidPres0Idx = Indices::solidPres0Idx };
79 using MaterialState = MaterialStateTPSA<Evaluation>;
81 using DimVector = Dune::FieldVector<Scalar, dimWorld>;
82 using SymTensor = SymmTensor<Scalar>;
83 using PotForceVector = Dune::BlockVector<Scalar>;
146 return std::equal(this->blockVector_.begin(), this->blockVector_.end(),
155 template<
class Serializer>
171 : linearizer_(std::make_unique<Linearizer>())
172 , newtonMethod_(simulator)
173 , simulator_(simulator)
174 , element_chunks_(simulator.gridView(),
Dune::Partitions::all,
ThreadManager::maxThreads())
177 eqWeights_.resize(numEq, 1.0);
181 const std::size_t numDof = simulator_.model().numGridDof();
182 for (
unsigned timeIdx = 0; timeIdx < historySize; ++timeIdx) {
183 solution_[timeIdx] = std::make_unique<TpsaBlockVectorWrapper>(
"solution", numDof);
187 mechPotPresForce_.resize(numDof);
188 mechPotTempForce_.resize(numDof);
197 linearizer_->init(simulator_);
234 auto ghostSync = GhostSyncHandle(
solution(0),
235 simulator_.model().dofMapper());
237 simulator_.gridView().communicate(ghostSync,
238 Dune::InteriorBorder_All_Interface,
239 Dune::ForwardCommunication);
252 const auto& elementMapper = simulator_.model().elementMapper();
254#pragma omp parallel for
256 for (
const auto& chunk : element_chunks_) {
257 for (
const auto& elem : chunk) {
258 const unsigned globalIdx = elementMapper.index(elem);
259 auto& currSol =
solution(0)[globalIdx];
260 setMaterialState_(globalIdx, 0, currSol);
295 return newtonMethod_;
305 return newtonMethod_;
314 const SolutionVector&
solution(
unsigned timeIdx)
const
316 return solution_[timeIdx]->blockVector();
327 return solution_[timeIdx]->blockVector();
336 return simulator_.model().numGridDof();
356 return simulator_.model().dofTotalVolume(globalIdx);
368 return eqWeights_[eqIdx];
379 eqWeights_[eqIdx] = value;
409 const MaterialState&
materialState(
const unsigned globalIdx,
unsigned )
const
411 return materialState_[globalIdx];
423 DimVector
disp(
const unsigned globalIdx,
const bool )
const
426 for (std::size_t i = 0; i < 3; ++i) {
427 d[i] = decay<Scalar>(materialState_[globalIdx].displacement(i));
441 for (std::size_t i = 0; i < 3; ++i) {
442 rot[i] = decay<Scalar>(materialState_[globalIdx].
rotation(i));
455 return decay<Scalar>(materialState_[globalIdx].
solidPressure());
466 return stress(globalIdx,
false);
495 SymTensor linStressTensor =
stress(globalIdx,
false);
497 for (
const auto& dirIdx : SymTensor::diag_indices) {
498 linStressTensor[dirIdx] -= potForce;
500 return -1.0 * linStressTensor;
513 SymTensor
stress(
const unsigned globalIdx,
const bool )
const
515 SymTensor stressOutput;
516 const auto& stressInfo = linearizer_->getStressInfo();
517 if (!stressInfo.empty()) {
518 const auto& stressInfoGlobI = stressInfo[globalIdx];
523 std::unordered_multimap<int, std::size_t> faceIdMap;
524 std::size_t mapSize = 0;
525 for (std::size_t sInfoIdx = 0; sInfoIdx < stressInfoGlobI.size(); ++sInfoIdx) {
526 const auto faceId = stressInfoGlobI[sInfoIdx].faceId;
530 if (faceId < 0 || stressInfoGlobI[sInfoIdx].faceArea == 0.0) {
533 if (!faceIdMap.contains(faceId)) {
536 faceIdMap.insert({faceId, sInfoIdx});
544 Dune::DynamicMatrix<Scalar> mat(3 * mapSize, 6);
545 Dune::DynamicVector<Scalar> rhs(3 * mapSize);
546 std::size_t rowIdx = 0;
547 for (
auto it = faceIdMap.begin(); it != faceIdMap.end();) {
548 auto [first, last] = faceIdMap.equal_range(it->first);
551 Scalar sumFaceArea = 0.0;
552 for (
auto inner = first; inner != last; ++inner) {
553 const auto sInfoIdx = inner->second;
554 const auto& faceStressInfo = stressInfoGlobI[sInfoIdx];
557 if (inner == first) {
558 const auto& fNormal = faceStressInfo.faceNormal;
559 mat[3*rowIdx][0] = fNormal[0];
560 mat[3*rowIdx][3] = fNormal[1];
561 mat[3*rowIdx][4] = fNormal[2];
563 mat[3*rowIdx + 1][1] = fNormal[1];
564 mat[3*rowIdx + 1][3] = fNormal[0];
565 mat[3*rowIdx + 1][5] = fNormal[2];
567 mat[3*rowIdx + 2][2] = fNormal[2];
568 mat[3*rowIdx + 2][4] = fNormal[0];
569 mat[3*rowIdx + 2][5] = fNormal[1];
573 const auto& fTraction = faceStressInfo.traction;
574 rhs[3*rowIdx] += fTraction[0];
575 rhs[3*rowIdx + 1] += fTraction[1];
576 rhs[3*rowIdx + 2] += fTraction[2];
579 sumFaceArea += faceStressInfo.faceArea;
582 rhs[3*rowIdx] /= sumFaceArea;
583 rhs[3*rowIdx + 1] /= sumFaceArea;
584 rhs[3*rowIdx + 2] /= sumFaceArea;
597 stressOutput[VoigtIndex::XX] =
stress[0];
598 stressOutput[VoigtIndex::YY] =
stress[1];
599 stressOutput[VoigtIndex::ZZ] =
stress[2];
600 stressOutput[VoigtIndex::YZ] =
stress[5];
601 stressOutput[VoigtIndex::XZ] =
stress[4];
602 stressOutput[VoigtIndex::XY] =
stress[3];
616 std::array<DimVector, 6>
traction(
const unsigned globalIdx)
const
618 std::array<DimVector, 6> tractionOutput{};
619 const auto& stressInfo = linearizer_->getStressInfo();
620 if (stressInfo.empty()) {
621 return tractionOutput;
626 std::array<Scalar, 6> sumFaceArea{};
627 for (
const auto& faceStressInfo : stressInfo[globalIdx]) {
628 const auto faceId = faceStressInfo.faceId;
631 if (faceId < 0 || faceStressInfo.faceArea == 0.0) {
635 tractionOutput[faceId] += faceStressInfo.traction;
636 sumFaceArea[faceId] += faceStressInfo.faceArea;
639 for (std::size_t faceId = 0; faceId < 6; ++faceId) {
640 if (sumFaceArea[faceId] > 0.0) {
641 tractionOutput[faceId] /= sumFaceArea[faceId];
645 return tractionOutput;
655 SymTensor
strain(
const unsigned globalIdx,
const bool )
const
658 auto stressDev = this->
linstress(globalIdx);
659 Scalar traceStress = 1.0 / 3.0 * stressDev.trace();
660 stressDev[VoigtIndex::XX] -= traceStress;
661 stressDev[VoigtIndex::YY] -= traceStress;
662 stressDev[VoigtIndex::ZZ] -= traceStress;
665 auto& problem = simulator_.problem();
666 const auto sMod = problem.shearModulus(globalIdx);
667 SymTensor strainDev = 1.0 / (2.0 * sMod) * stressDev;
670 const auto lameParam = problem.lame(globalIdx);
671 Scalar strainVolTerm = traceStress / (3.0 * lameParam + 2 * sMod);
674 strainVol[VoigtIndex::XX] = strainVolTerm;
675 strainVol[VoigtIndex::YY] = strainVolTerm;
676 strainVol[VoigtIndex::ZZ] = strainVolTerm;
679 SymTensor strainOutput = strainDev + strainVol;
704 return mechPotPresForce_[globalIdx];
715 mechPotPresForce_[globalIdx] = val;
726 return mechPotTempForce_[globalIdx];
737 mechPotTempForce_[globalIdx] = val;
751 const std::size_t numDof = simulator_.model().numGridDof();
752 materialState_.resize(numDof);
768 void setMaterialState_(
const unsigned globalIdx,
const unsigned , PrimaryVariables& values)
770 auto& dofMaterialState = materialState_[globalIdx];
771 for (
unsigned dirIdx = 0; dirIdx < 3; ++dirIdx) {
772 dofMaterialState.setDisplacement(dirIdx, values.makeEvaluation(disp0Idx + dirIdx, 0));
773 dofMaterialState.setRotation(dirIdx, values.makeEvaluation(rot0Idx + dirIdx, 0));
775 dofMaterialState.setSolidPressure(values.makeEvaluation(solidPres0Idx, 0));
778 std::unique_ptr<Linearizer> linearizer_;
779 NewtonMethod newtonMethod_;
780 Simulator& simulator_;
781 ElementChunks<GridView, Dune::Partitions::All> element_chunks_;
783 std::array<std::unique_ptr<TpsaBlockVectorWrapper>, historySize> solution_;
784 std::vector<Scalar> eqWeights_;
785 std::vector<MaterialState> materialState_;
786 PotForceVector mechPotPresForce_;
787 PotForceVector mechPotTempForce_;
Data handle for parallel communication which can be used to set the values values of ghost and overla...
Definition: gridcommhandles.hh:109
Linear least squares calculations and properties.
Definition: linearleastsquares.hpp:45
const Vector & x() const
Read-only vector of calculated coefficient vector.
Definition: linearleastsquares.hpp:76
void solve()
Solve linear least squares system.
Definition: linearleastsquares.hpp:66
static void registerParameters()
Register all run-time parameters for the Newton method.
Definition: newtonmethod.hh:135
Simplifies multi-threaded capabilities.
Definition: threadmanager.hpp:36
Small block vector wrapper class for model solutions.
Definition: tpsamodel.hpp:90
bool operator==(const TpsaBlockVectorWrapper &wrapper) const
Check if incoming block vector is the same as current.
Definition: tpsamodel.hpp:144
static TpsaBlockVectorWrapper serializationTestObject()
Test function for serialization.
Definition: tpsamodel.hpp:112
TpsaBlockVectorWrapper()=default
Default constructor.
TpsaBlockVectorWrapper(const std::string &, const std::size_t size)
Constructor.
Definition: tpsamodel.hpp:100
void serializeOp(Serializer &serializer)
Serializing operation.
Definition: tpsamodel.hpp:156
const SolutionVector & blockVector() const
Get const reference of block vector.
Definition: tpsamodel.hpp:135
SolutionVector & blockVector()
Get reference of block vector.
Definition: tpsamodel.hpp:127
SolutionVector blockVector_
Definition: tpsamodel.hpp:92
TPSA geomechanics model.
Definition: tpsamodel.hpp:58
SymTensor delstress(const unsigned globalIdx) const
Output stress tensor without fracture contribution.
Definition: tpsamodel.hpp:464
NewtonMethod & newtonMethod()
Return the Newton method.
Definition: tpsamodel.hpp:303
std::size_t numAuxiliaryDof() const
Return number of auxillary degrees of freedom.
Definition: tpsamodel.hpp:395
SymTensor stress(const unsigned globalIdx, const bool) const
Output stress tensor.
Definition: tpsamodel.hpp:513
SymTensor strain(const unsigned globalIdx, const bool) const
Output strain tensor.
Definition: tpsamodel.hpp:655
void setMechPotentialTempForce(unsigned globalIdx, Scalar val)
Sets potential temperature force.
Definition: tpsamodel.hpp:735
DimVector disp(const unsigned globalIdx, const bool) const
Output displacement vector.
Definition: tpsamodel.hpp:423
void finishInit()
Initialize TPSA model.
Definition: tpsamodel.hpp:194
void setEqWeight(unsigned eqIdx, Scalar value)
Set weights for equation.
Definition: tpsamodel.hpp:377
std::size_t numGridDof() const
Return number of degrees of freedom in the grid from the Flow model.
Definition: tpsamodel.hpp:334
const Linearizer & linearizer() const
Return the linearizer.
Definition: tpsamodel.hpp:273
const NewtonMethod & newtonMethod() const
Return the Newton method.
Definition: tpsamodel.hpp:293
std::size_t numAuxiliaryModules() const
Return number of auxillary modules.
Definition: tpsamodel.hpp:386
void updateMaterialState(const unsigned)
Update material state for all cells.
Definition: tpsamodel.hpp:249
Scalar mechPotentialPressForce(unsigned globalIdx) const
Output potential pressure forces.
Definition: tpsamodel.hpp:702
Scalar mechPotentialTempForce(unsigned globalIdx) const
Output potential temparature forces.
Definition: tpsamodel.hpp:724
SymTensor linstress(const unsigned globalIdx) const
Output linear stress tensor.
Definition: tpsamodel.hpp:491
const SolutionVector & solution(unsigned timeIdx) const
Get reference to history solution vector.
Definition: tpsamodel.hpp:314
const MaterialState & materialState(const unsigned globalIdx, unsigned) const
Return current material state.
Definition: tpsamodel.hpp:409
Scalar dofTotalVolume(unsigned globalIdx) const
Return the total grid volume from the Flow model.
Definition: tpsamodel.hpp:354
void resizeMaterialState_()
Resize material state vector.
Definition: tpsamodel.hpp:749
static void registerParameters()
Register runtime parameters.
Definition: tpsamodel.hpp:206
void setMechPotentialPressForce(unsigned globalIdx, Scalar val)
Sets potential pressure force.
Definition: tpsamodel.hpp:713
Scalar eqWeight(unsigned, unsigned eqIdx) const
Return equation weights.
Definition: tpsamodel.hpp:366
TpsaModel(Simulator &simulator)
Constructor.
Definition: tpsamodel.hpp:170
std::array< DimVector, 6 > traction(const unsigned globalIdx) const
Output traction vector for each of the 6 face directions.
Definition: tpsamodel.hpp:616
SolutionVector & solution(unsigned timeIdx)
Get reference to history solution vector.
Definition: tpsamodel.hpp:325
void prepareTPSA()
Prepare TPSA model for coupled Flow-TPSA scheme.
Definition: tpsamodel.hpp:215
Scalar solidPressure(const unsigned globalIdx) const
Output solid pressure.
Definition: tpsamodel.hpp:453
SymTensor fractureStress(const unsigned) const
Output fracture stress tensor.
Definition: tpsamodel.hpp:477
std::size_t numTotalDof() const
Return the total number of degrees of freedom.
Definition: tpsamodel.hpp:343
Linearizer & linearizer()
Return the linearizer.
Definition: tpsamodel.hpp:283
void syncOverlap()
Sync primary variables in overlapping cells.
Definition: tpsamodel.hpp:226
DimVector rotation(const unsigned globalIdx) const
Output rotation vector.
Definition: tpsamodel.hpp:438
Scalar mechPotentialForce(unsigned globalIdx) const
Output total potential forces.
Definition: tpsamodel.hpp:691
Definition: fvbaseprimaryvariables.hh:161
Definition: blackoilbioeffectsmodules.hh:45
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:233
The Opm property system, traits with inheritance.