28#ifndef EWOMS_FV_BASE_LINEARIZER_HH
29#define EWOMS_FV_BASE_LINEARIZER_HH
34#include <opm/common/Exceptions.hpp>
35#include <opm/common/TimingMacros.hpp>
36#include <opm/grid/utility/SparseTable.hpp>
43#include <dune/common/version.hh>
44#include <dune/common/fvector.hh>
45#include <dune/common/fmatrix.hh>
57template<
class TypeTag>
58class EcfvDiscretization;
69template<
class TypeTag>
94 using Toolbox = MathToolbox<Evaluation>;
96 using Element =
typename GridView::template Codim<0>::Entity;
97 using ElementIterator =
typename GridView::template Codim<0>::Iterator;
99 using Vector = GlobalEqVector;
101 using IstlMatrix =
typename SparseMatrixAdapter::IstlMatrix;
103 enum { numEq = getPropValue<TypeTag, Properties::NumEq>() };
104 enum { historySize = getPropValue<TypeTag, Properties::TimeDiscHistorySize>() };
106 using MatrixBlock =
typename SparseMatrixAdapter::MatrixBlock;
107 using VectorBlock = Dune::FieldVector<Scalar, numEq>;
109 static const bool linearizeNonLocalElements = getPropValue<TypeTag, Properties::LinearizeNonLocalElements>();
124 auto it = elementCtx_.begin();
125 const auto& endIt = elementCtx_.end();
126 for (; it != endIt; ++it)
147 simulatorPtr_ = &simulator;
149 auto it = elementCtx_.begin();
150 const auto& endIt = elementCtx_.end();
151 for (; it != endIt; ++it){
154 elementCtx_.resize(0);
155 fullDomain_ = std::make_unique<FullDomain>(simulator.
gridView());
200 template <
class SubDomainType>
208 initFirstIteration_();
211 if (
static_cast<std::size_t
>(domain.view.size(0)) == model_().numTotalDof()) {
223 catch (
const std::exception& e)
225 std::cout <<
"rank " << simulator_().
gridView().comm().rank()
226 <<
" caught an exception while linearizing:" << e.what()
227 <<
"\n" << std::flush;
232 std::cout <<
"rank " << simulator_().
gridView().comm().rank()
233 <<
" caught an exception while linearizing"
234 <<
"\n" << std::flush;
237 succeeded = simulator_().
gridView().comm().min(succeeded);
240 throw NumericalProblem(
"A process did not succeed in linearizing the system");
244 { jacobian_->finalize(); }
256 auto& model = model_();
257 const auto& comm = simulator_().
gridView().comm();
258 for (
unsigned auxModIdx = 0; auxModIdx < model.numAuxiliaryModules(); ++auxModIdx) {
259 bool succeeded =
true;
261 model.auxiliaryModule(auxModIdx)->linearize(*jacobian_, residual_);
263 catch (
const std::exception& e) {
266 std::cout <<
"rank " << simulator_().
gridView().comm().rank()
267 <<
" caught an exception while linearizing:" << e.what()
268 <<
"\n" << std::flush;
271 succeeded = comm.min(succeeded);
274 throw NumericalProblem(
"linearization of an auxiliary equation failed");
282 {
return *jacobian_; }
285 {
return *jacobian_; }
291 {
return residual_; }
294 {
return residual_; }
297 linearizationType_ = linearizationType;
301 return linearizationType_;
324 {
return constraintsMap_; }
340 {
return floresInfo_;}
342 template <
class SubDomainType>
346 initFirstIteration_();
350 using GridViewType =
decltype(domain.view);
361 const Element& elem = *elemIt;
362 ElementContext& elemCtx = *elementCtx_[threadId];
363 elemCtx.updatePrimaryStencil(elem);
365 for (
unsigned primaryDofIdx = 0;
366 primaryDofIdx < elemCtx.numPrimaryDof(0);
369 unsigned globI = elemCtx.globalSpaceIndex(primaryDofIdx, 0);
370 residual_[globI] = 0.0;
371 jacobian_->clearRow(globI, 0.0);
379 {
return *simulatorPtr_; }
380 const Simulator& simulator_()
const
381 {
return *simulatorPtr_; }
384 {
return simulator_().
problem(); }
385 const Problem& problem_()
const
386 {
return simulator_().
problem(); }
389 {
return simulator_().
model(); }
390 const Model& model_()
const
391 {
return simulator_().
model(); }
393 const GridView& gridView_()
const
394 {
return problem_().gridView(); }
396 const ElementMapper& elementMapper_()
const
397 {
return model_().elementMapper(); }
399 const DofMapper& dofMapper_()
const
400 {
return model_().dofMapper(); }
402 void initFirstIteration_()
408 residual_.resize(model_().numTotalDof());
414 elementCtx_[threadId] =
new ElementContext(simulator_());
420 const auto& model = model_();
421 Stencil stencil(gridView_(), model_().dofMapper());
425 sparsityPattern_.clear();
426 sparsityPattern_.resize(model.numTotalDof());
428 for (
const auto& elem : elements(gridView_())) {
429 stencil.update(elem);
431 for (
unsigned primaryDofIdx = 0; primaryDofIdx < stencil.numPrimaryDof(); ++primaryDofIdx) {
432 unsigned myIdx = stencil.globalSpaceIndex(primaryDofIdx);
434 for (
unsigned dofIdx = 0; dofIdx < stencil.numDof(); ++dofIdx) {
435 unsigned neighborIdx = stencil.globalSpaceIndex(dofIdx);
436 sparsityPattern_[myIdx].insert(neighborIdx);
443 size_t numAuxMod = model.numAuxiliaryModules();
444 for (
unsigned auxModIdx = 0; auxModIdx < numAuxMod; ++auxModIdx)
445 model.auxiliaryModule(auxModIdx)->addNeighbors(sparsityPattern_);
448 jacobian_.reset(
new SparseMatrixAdapter(simulator_()));
451 jacobian_->reserve(sparsityPattern_);
464 void updateConstraintsMap_()
466 if (!enableConstraints_())
470 constraintsMap_.clear();
473 ThreadedEntityIterator<GridView, 0> threadedElemIt(gridView_());
479 ElementIterator elemIt = threadedElemIt.beginParallel();
480 for (; !threadedElemIt.isFinished(elemIt); elemIt = threadedElemIt.increment()) {
483 const Element& elem = *elemIt;
484 ElementContext& elemCtx = *elementCtx_[threadId];
485 elemCtx.updateStencil(elem);
489 for (
unsigned primaryDofIdx = 0;
490 primaryDofIdx < elemCtx.numPrimaryDof(0);
493 Constraints constraints;
494 elemCtx.problem().constraints(constraints,
498 if (constraints.isActive()) {
499 unsigned globI = elemCtx.globalSpaceIndex(primaryDofIdx, 0);
500 constraintsMap_[globI] = constraints;
509 template <
class SubDomainType>
510 void linearize_(
const SubDomainType& domain)
512 OPM_TIMEBLOCK(linearize_);
521 if (model_().newtonMethod().numIterations() == 0)
522 updateConstraintsMap_();
524 applyConstraintsToSolution_();
529 std::mutex exceptionLock;
533 std::exception_ptr exceptionPtr =
nullptr;
536 using GridViewType =
decltype(domain.view);
537 ThreadedEntityIterator<GridViewType, 0> threadedElemIt(domain.view);
542 auto elemIt = threadedElemIt.beginParallel();
543 auto nextElemIt = elemIt;
545 for (; !threadedElemIt.isFinished(elemIt); elemIt = nextElemIt) {
548 nextElemIt = threadedElemIt.increment();
549 if (!threadedElemIt.isFinished(nextElemIt)) {
550 const auto& nextElem = *nextElemIt;
551 if (linearizeNonLocalElements
552 || nextElem.partitionType() == Dune::InteriorEntity)
554 model_().prefetch(nextElem);
555 problem_().prefetch(nextElem);
559 const auto& elem = *elemIt;
560 if (!linearizeNonLocalElements && elem.partitionType() != Dune::InteriorEntity)
563 linearizeElement_(elem);
576 std::lock_guard<std::mutex> take(exceptionLock);
577 exceptionPtr = std::current_exception();
578 threadedElemIt.setFinished();
586 std::rethrow_exception(exceptionPtr);
589 applyConstraintsToLinearization_();
594 template <
class ElementType>
599 ElementContext *elementCtx = elementCtx_[threadId];
600 auto& localLinearizer = model_().localLinearizer(threadId);
603 localLinearizer.linearize(*elementCtx, elem);
606 if (getPropValue<TypeTag, Properties::UseLinearizationLock>())
607 globalMatrixMutex_.lock();
609 size_t numPrimaryDof = elementCtx->numPrimaryDof(0);
610 for (
unsigned primaryDofIdx = 0; primaryDofIdx < numPrimaryDof; ++ primaryDofIdx) {
611 unsigned globI = elementCtx->globalSpaceIndex(primaryDofIdx, 0);
614 residual_[globI] += localLinearizer.residual(primaryDofIdx);
617 for (
unsigned dofIdx = 0; dofIdx < elementCtx->numDof(0); ++ dofIdx) {
618 unsigned globJ = elementCtx->globalSpaceIndex(dofIdx, 0);
620 jacobian_->addToBlock(globJ, globI, localLinearizer.jacobian(dofIdx, primaryDofIdx));
624 if (getPropValue<TypeTag, Properties::UseLinearizationLock>())
625 globalMatrixMutex_.unlock();
630 void applyConstraintsToSolution_()
632 if (!enableConstraints_())
636 auto& sol = model_().solution(0);
637 auto& oldSol = model_().solution(1);
639 auto it = constraintsMap_.begin();
640 const auto& endIt = constraintsMap_.end();
641 for (; it != endIt; ++it) {
642 sol[it->first] = it->second;
643 oldSol[it->first] = it->second;
649 void applyConstraintsToLinearization_()
651 if (!enableConstraints_())
654 auto it = constraintsMap_.begin();
655 const auto& endIt = constraintsMap_.end();
656 for (; it != endIt; ++it) {
657 unsigned constraintDofIdx = it->first;
661 jacobian_->clearRow(constraintDofIdx, Scalar(1.0));
664 residual_[constraintDofIdx] = 0.0;
668 static bool enableConstraints_()
669 {
return getPropValue<TypeTag, Properties::EnableConstraints>(); }
671 Simulator *simulatorPtr_;
672 std::vector<ElementContext*> elementCtx_;
676 std::map<unsigned, Constraints> constraintsMap_;
685 SparseTable<FlowInfo> flowsInfo_;
686 SparseTable<FlowInfo> floresInfo_;
689 std::unique_ptr<SparseMatrixAdapter> jacobian_;
692 GlobalEqVector residual_;
694 LinearizationType linearizationType_;
696 std::mutex globalMatrixMutex_;
698 std::vector<std::set<unsigned int>> sparsityPattern_;
702 explicit FullDomain(
const GridView& v) : view (v) {}
704 std::vector<bool> interior;
709 std::unique_ptr<FullDomain> fullDomain_;
The common code for the linearizers of non-linear systems of equations.
Definition: fvbaselinearizer.hh:71
const auto & getFlowsInfo() const
Return constant reference to the flowsInfo.
Definition: fvbaselinearizer.hh:331
const GlobalEqVector & residual() const
Return constant reference to global residual vector.
Definition: fvbaselinearizer.hh:290
void setLinearizationType(LinearizationType linearizationType)
Definition: fvbaselinearizer.hh:296
SparseMatrixAdapter & jacobian()
Definition: fvbaselinearizer.hh:284
static void registerParameters()
Register all run-time parameters for the Jacobian linearizer.
Definition: fvbaselinearizer.hh:133
void linearize()
Linearize the full system of non-linear equations.
Definition: fvbaselinearizer.hh:179
void finalize()
Definition: fvbaselinearizer.hh:243
void init(Simulator &simulator)
Initialize the linearizer.
Definition: fvbaselinearizer.hh:145
void updateBoundaryConditionData()
Definition: fvbaselinearizer.hh:309
void linearizeDomain()
Linearize the part of the non-linear system of equations that is associated with the spatial domain.
Definition: fvbaselinearizer.hh:195
void resetSystem_(const SubDomainType &domain)
Definition: fvbaselinearizer.hh:343
GlobalEqVector & residual()
Definition: fvbaselinearizer.hh:293
const SparseMatrixAdapter & jacobian() const
Return constant reference to global Jacobian matrix backend.
Definition: fvbaselinearizer.hh:281
const auto & getFloresInfo() const
Return constant reference to the floresInfo.
Definition: fvbaselinearizer.hh:339
~FvBaseLinearizer()
Definition: fvbaselinearizer.hh:122
void linearizeAuxiliaryEquations()
Linearize the part of the non-linear system of equations that is associated with the spatial domain.
Definition: fvbaselinearizer.hh:250
void linearizeDomain(const SubDomainType &domain)
Definition: fvbaselinearizer.hh:201
void updateDiscretizationParameters()
Definition: fvbaselinearizer.hh:304
FvBaseLinearizer()
Definition: fvbaselinearizer.hh:116
const LinearizationType & getLinearizationType() const
Definition: fvbaselinearizer.hh:300
void updateFlowsInfo()
Definition: fvbaselinearizer.hh:314
const std::map< unsigned, Constraints > & constraintsMap() const
Returns the map of constraint degrees of freedom.
Definition: fvbaselinearizer.hh:323
void eraseMatrix()
Causes the Jacobian matrix to be recreated from scratch before the next iteration.
Definition: fvbaselinearizer.hh:165
Definition: matrixblock.hh:227
Manages the initializing and running of time dependent problems.
Definition: simulator.hh:102
Problem & problem()
Return the object which specifies the pysical setup of the simulation.
Definition: simulator.hh:306
const GridView & gridView() const
Return the grid view for which the simulation is done.
Definition: simulator.hh:287
Model & model()
Return the physical model used in the simulation.
Definition: simulator.hh:293
Simplifies multi-threaded capabilities.
Definition: threadmanager.hh:47
static unsigned maxThreads()
Return the maximum number of threads of the current process.
Definition: threadmanager.hh:118
static unsigned threadId()
Return the index of the current OpenMP thread.
Definition: threadmanager.hh:124
Provides an STL-iterator like interface to iterate over the enties of a GridView in OpenMP threaded a...
Definition: threadedentityiterator.hh:43
bool isFinished(const EntityIterator &it) const
Definition: threadedentityiterator.hh:67
EntityIterator increment()
Definition: threadedentityiterator.hh:80
EntityIterator beginParallel()
Definition: threadedentityiterator.hh:55
Declare the properties used by the infrastructure code of the finite volume discretizations.
Provides data handles for parallel communication which operate on DOFs.
Definition: blackoilboundaryratevector.hh:37
ElementType
The types of reference elements available.
Definition: vcfvstencil.hh:52
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:235
Definition: linearizationtype.hh:35