28 #ifndef EWOMS_FV_BASE_LINEARIZER_HH 29 #define EWOMS_FV_BASE_LINEARIZER_HH 31 #include <dune/common/fmatrix.hh> 32 #include <dune/common/fvector.hh> 33 #include <dune/common/version.hh> 35 #include <dune/grid/common/gridenums.hh> 37 #include <opm/common/Exceptions.hpp> 38 #include <opm/common/TimingMacros.hpp> 40 #include <opm/grid/utility/SparseTable.hpp> 42 #include <opm/material/common/MathToolbox.hpp> 64 template<
class TypeTag>
65 class EcfvDiscretization;
76 template<
class TypeTag>
101 using Toolbox = MathToolbox<Evaluation>;
103 using Element =
typename GridView::template Codim<0>::Entity;
104 using ElementIterator =
typename GridView::template Codim<0>::Iterator;
106 using Vector = GlobalEqVector;
108 using IstlMatrix =
typename SparseMatrixAdapter::IstlMatrix;
110 enum { numEq = getPropValue<TypeTag, Properties::NumEq>() };
111 enum { historySize = getPropValue<TypeTag, Properties::TimeDiscHistorySize>() };
113 using MatrixBlock =
typename SparseMatrixAdapter::MatrixBlock;
114 using VectorBlock = Dune::FieldVector<Scalar, numEq>;
116 static constexpr
bool linearizeNonLocalElements = getPropValue<TypeTag, Properties::LinearizeNonLocalElements>();
143 simulatorPtr_ = &simulator;
146 fullDomain_ = std::make_unique<FullDomain>(simulator.
gridView());
191 template <
class SubDomainType>
199 initFirstIteration_();
203 if (problem_().iterationContext().inLocalSolve()) {
204 resetSystem_(domain);
215 catch (
const std::exception& e)
217 std::cout <<
"rank " << simulator_().
gridView().comm().rank()
218 <<
" caught an exception while linearizing:" << e.what()
219 <<
"\n" << std::flush;
224 std::cout <<
"rank " << simulator_().
gridView().comm().rank()
225 <<
" caught an exception while linearizing" 226 <<
"\n" << std::flush;
229 succeeded = simulator_().
gridView().comm().min(succeeded);
232 throw NumericalProblem(
"A process did not succeed in linearizing the system");
237 { jacobian_->finalize(); }
249 auto& model = model_();
250 const auto& comm = simulator_().
gridView().comm();
251 for (
unsigned auxModIdx = 0; auxModIdx < model.numAuxiliaryModules(); ++auxModIdx) {
252 bool succeeded =
true;
254 model.auxiliaryModule(auxModIdx)->linearize(*jacobian_, residual_);
256 catch (
const std::exception& e) {
259 std::cout <<
"rank " << simulator_().
gridView().comm().rank()
260 <<
" caught an exception while linearizing:" << e.what()
261 <<
"\n" << std::flush;
264 succeeded = comm.min(succeeded);
267 throw NumericalProblem(
"linearization of an auxiliary equation failed");
276 {
return *jacobian_; }
279 {
return *jacobian_; }
285 {
return residual_; }
288 {
return residual_; }
290 void setLinearizationType(LinearizationType linearizationType){
291 linearizationType_ = linearizationType;
294 const LinearizationType& getLinearizationType()
const 295 {
return linearizationType_; }
297 void updateDiscretizationParameters()
302 void updateBoundaryConditionData()
307 void updateFlowsInfo()
318 {
return constraintsMap_; }
326 {
return flowsInfo_; }
334 {
return floresInfo_; }
343 {
return velocityInfo_; }
345 template <
class SubDomainType>
346 void resetSystem_(
const SubDomainType& domain)
349 initFirstIteration_();
353 using GridViewType = decltype(domain.view);
354 ThreadedEntityIterator<GridViewType, 0> threadedElemIt(domain.view);
360 auto elemIt = threadedElemIt.beginParallel();
361 MatrixBlock zeroBlock;
363 for (; !threadedElemIt.isFinished(elemIt); elemIt = threadedElemIt.increment()) {
364 const Element& elem = *elemIt;
365 ElementContext& elemCtx = *elementCtx_[threadId];
366 elemCtx.updatePrimaryStencil(elem);
368 for (
unsigned primaryDofIdx = 0;
369 primaryDofIdx < elemCtx.numPrimaryDof(0);
372 const unsigned globI = elemCtx.globalSpaceIndex(primaryDofIdx, 0);
373 residual_[globI] = 0.0;
374 jacobian_->clearRow(globI, 0.0);
381 Simulator& simulator_()
382 {
return *simulatorPtr_; }
384 const Simulator& simulator_()
const 385 {
return *simulatorPtr_; }
388 {
return simulator_().
problem(); }
390 const Problem& problem_()
const 391 {
return simulator_().
problem(); }
394 {
return simulator_().
model(); }
396 const Model& model_()
const 397 {
return simulator_().
model(); }
399 const GridView& gridView_()
const 400 {
return problem_().gridView(); }
402 const ElementMapper& elementMapper_()
const 403 {
return model_().elementMapper(); }
405 const DofMapper& dofMapper_()
const 406 {
return model_().dofMapper(); }
408 void initFirstIteration_()
414 residual_.resize(model_().numTotalDof());
421 elementCtx_.push_back(std::make_unique<ElementContext>(simulator_()));
428 const auto& model = model_();
429 Stencil stencil(gridView_(), model_().dofMapper());
433 sparsityPattern_.clear();
434 sparsityPattern_.resize(model.numTotalDof());
436 for (
const auto& elem : elements(gridView_())) {
437 stencil.update(elem);
439 for (
unsigned primaryDofIdx = 0; primaryDofIdx < stencil.numPrimaryDof(); ++primaryDofIdx) {
440 const unsigned myIdx = stencil.globalSpaceIndex(primaryDofIdx);
442 for (
unsigned dofIdx = 0; dofIdx < stencil.numDof(); ++dofIdx) {
443 const unsigned neighborIdx = stencil.globalSpaceIndex(dofIdx);
444 sparsityPattern_[myIdx].insert(neighborIdx);
451 const std::size_t numAuxMod = model.numAuxiliaryModules();
452 for (
unsigned auxModIdx = 0; auxModIdx < numAuxMod; ++auxModIdx) {
453 model.auxiliaryModule(auxModIdx)->addNeighbors(sparsityPattern_);
457 jacobian_ = std::make_unique<SparseMatrixAdapter>(simulator_());
460 jacobian_->reserve(sparsityPattern_);
473 void updateConstraintsMap_()
475 if (!enableConstraints_()) {
480 constraintsMap_.clear();
483 ThreadedEntityIterator<GridView, 0> threadedElemIt(gridView_());
489 ElementIterator elemIt = threadedElemIt.beginParallel();
490 for (; !threadedElemIt.isFinished(elemIt); elemIt = threadedElemIt.increment()) {
493 const Element& elem = *elemIt;
494 ElementContext& elemCtx = *elementCtx_[threadId];
495 elemCtx.updateStencil(elem);
499 for (
unsigned primaryDofIdx = 0;
500 primaryDofIdx < elemCtx.numPrimaryDof(0);
503 Constraints constraints;
504 elemCtx.problem().constraints(constraints,
508 if (constraints.isActive()) {
509 const unsigned globI = elemCtx.globalSpaceIndex(primaryDofIdx, 0);
510 constraintsMap_[globI] = constraints;
519 template <
class SubDomainType>
520 void linearize_(
const SubDomainType& domain)
522 OPM_TIMEBLOCK(linearize_);
531 if (problem_().iterationContext().isFirstGlobalIteration()) {
532 updateConstraintsMap_();
535 applyConstraintsToSolution_();
540 std::mutex exceptionLock;
544 std::exception_ptr exceptionPtr =
nullptr;
547 using GridViewType = decltype(domain.view);
548 ThreadedEntityIterator<GridViewType, 0> threadedElemIt(domain.view);
553 auto elemIt = threadedElemIt.beginParallel();
554 auto nextElemIt = elemIt;
556 for (; !threadedElemIt.isFinished(elemIt); elemIt = nextElemIt) {
559 nextElemIt = threadedElemIt.increment();
560 if (!threadedElemIt.isFinished(nextElemIt)) {
561 const auto& nextElem = *nextElemIt;
562 if (linearizeNonLocalElements ||
563 nextElem.partitionType() == Dune::InteriorEntity)
565 model_().prefetch(nextElem);
566 problem_().prefetch(nextElem);
570 const auto& elem = *elemIt;
571 if (!linearizeNonLocalElements && elem.partitionType() != Dune::InteriorEntity) {
575 linearizeElement_(elem);
588 std::lock_guard<std::mutex> take(exceptionLock);
589 exceptionPtr = std::current_exception();
590 threadedElemIt.setFinished();
598 std::rethrow_exception(exceptionPtr);
601 applyConstraintsToLinearization_();
605 template <
class ElementType>
610 ElementContext& elementCtx = *elementCtx_[threadId];
611 auto& localLinearizer = model_().localLinearizer(threadId);
614 localLinearizer.linearize(elementCtx, elem);
617 if (getPropValue<TypeTag, Properties::UseLinearizationLock>()) {
618 globalMatrixMutex_.lock();
621 const std::size_t numPrimaryDof = elementCtx.numPrimaryDof(0);
622 for (
unsigned primaryDofIdx = 0; primaryDofIdx < numPrimaryDof; ++primaryDofIdx) {
623 const unsigned globI = elementCtx.globalSpaceIndex(primaryDofIdx, 0);
626 residual_[globI] += localLinearizer.residual(primaryDofIdx);
629 for (
unsigned dofIdx = 0; dofIdx < elementCtx.numDof(0); ++dofIdx) {
630 const unsigned globJ = elementCtx.globalSpaceIndex(dofIdx, 0);
632 jacobian_->addToBlock(globJ, globI, localLinearizer.jacobian(dofIdx, primaryDofIdx));
636 if (getPropValue<TypeTag, Properties::UseLinearizationLock>()) {
637 globalMatrixMutex_.unlock();
643 void applyConstraintsToSolution_()
645 if (!enableConstraints_()) {
650 auto& sol = model_().solution(0);
651 auto& oldSol = model_().solution(1);
653 for (
const auto& constraint : constraintsMap_) {
654 sol[constraint.first] = constraint.second;
655 oldSol[constraint.first] = constraint.second;
661 void applyConstraintsToLinearization_()
663 if (!enableConstraints_()) {
667 for (
const auto& constraint : constraintsMap_) {
670 jacobian_->clearRow(constraint.first, Scalar(1.0));
673 residual_[constraint.first] = 0.0;
677 static bool enableConstraints_()
678 {
return getPropValue<TypeTag, Properties::EnableConstraints>(); }
680 Simulator* simulatorPtr_{};
681 std::vector<std::unique_ptr<ElementContext>> elementCtx_;
685 std::map<unsigned, Constraints> constraintsMap_;
693 SparseTable<FlowInfo> flowsInfo_;
694 SparseTable<FlowInfo> floresInfo_;
699 VectorBlock velocity;
701 SparseTable<VelocityInfo> velocityInfo_;
704 std::unique_ptr<SparseMatrixAdapter> jacobian_;
707 GlobalEqVector residual_;
709 LinearizationType linearizationType_;
711 std::mutex globalMatrixMutex_;
713 std::vector<std::set<unsigned int>> sparsityPattern_;
717 explicit FullDomain(
const GridView& v) : view (v) {}
719 std::vector<bool> interior;
724 std::unique_ptr<FullDomain> fullDomain_;
Simplifies multi-threaded capabilities.
Definition: threadmanager.hpp:35
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
const std::map< unsigned, Constraints > & constraintsMap() const
Returns the map of constraint degrees of freedom.
Definition: fvbaselinearizer.hh:317
static unsigned maxThreads()
Return the maximum number of threads of the current process.
Definition: threadmanager.hpp:66
const auto & getVelocityInfo() const
Return constant reference to the velocityInfo.
Definition: fvbaselinearizer.hh:342
const GridView & gridView() const
Return the grid view for which the simulation is done.
Definition: simulator.hh:246
Model & model()
Return the physical model used in the simulation.
Definition: simulator.hh:252
Problem & problem()
Return the object which specifies the pysical setup of the simulation.
Definition: simulator.hh:265
void init(Simulator &simulator)
Initialize the linearizer.
Definition: fvbaselinearizer.hh:141
Base class for specifying auxiliary equations.
void linearizeAuxiliaryEquations()
Linearize the part of the non-linear system of equations that is associated with the spatial domain...
Definition: fvbaselinearizer.hh:243
void linearizeDomain()
Linearize the part of the non-linear system of equations that is associated with the spatial domain...
Definition: fvbaselinearizer.hh:186
Definition: matrixblock.hh:228
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: blackoilbioeffectsmodules.hh:45
const SparseMatrixAdapter & jacobian() const
Return constant reference to global Jacobian matrix backend.
Definition: fvbaselinearizer.hh:275
void linearize()
Linearize the full system of non-linear equations.
Definition: fvbaselinearizer.hh:170
Declare the properties used by the infrastructure code of the finite volume discretizations.
Provides data handles for parallel communication which operate on DOFs.
static unsigned threadId()
Return the index of the current OpenMP thread.
Definition: threadmanager.cpp:84
const auto & getFloresInfo() const
Return constant reference to the floresInfo.
Definition: fvbaselinearizer.hh:333
The common code for the linearizers of non-linear systems of equations.
const auto & getFlowsInfo() const
Return constant reference to the flowsInfo.
Definition: fvbaselinearizer.hh:325
static void registerParameters()
Register all run-time parameters for the Jacobian linearizer.
Definition: fvbaselinearizer.hh:129
void eraseMatrix()
Causes the Jacobian matrix to be recreated from scratch before the next iteration.
Definition: fvbaselinearizer.hh:156
Simplifies multi-threaded capabilities.
Provides an STL-iterator like interface to iterate over the enties of a GridView in OpenMP threaded a...
Manages the initializing and running of time dependent problems.
Definition: simulator.hh:83
The common code for the linearizers of non-linear systems of equations.
Definition: fvbaselinearizer.hh:77
const GlobalEqVector & residual() const
Return constant reference to global residual vector.
Definition: fvbaselinearizer.hh:284
ElementType
The types of reference elements available.
Definition: vcfvstencil.hh:57