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>
64template<
class TypeTag>
65class EcfvDiscretization;
76template<
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 (isNlddLocalSolve) {
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_; }
291 linearizationType_ = linearizationType;
295 {
return linearizationType_; }
318 {
return constraintsMap_; }
326 {
return flowsInfo_; }
334 {
return floresInfo_; }
343 {
return velocityInfo_; }
345 template <
class SubDomainType>
349 initFirstIteration_();
353 using GridViewType =
decltype(domain.view);
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);
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 (model_().newtonMethod().numIterations() == 0) {
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_;
The common code for the linearizers of non-linear systems of equations.
Definition: fvbaselinearizer.hh:78
const auto & getFlowsInfo() const
Return constant reference to the flowsInfo.
Definition: fvbaselinearizer.hh:325
const GlobalEqVector & residual() const
Return constant reference to global residual vector.
Definition: fvbaselinearizer.hh:284
void setLinearizationType(LinearizationType linearizationType)
Definition: fvbaselinearizer.hh:290
SparseMatrixAdapter & jacobian()
Definition: fvbaselinearizer.hh:278
FvBaseLinearizer()=default
static void registerParameters()
Register all run-time parameters for the Jacobian linearizer.
Definition: fvbaselinearizer.hh:129
void linearize()
Linearize the full system of non-linear equations.
Definition: fvbaselinearizer.hh:170
void finalize()
Definition: fvbaselinearizer.hh:236
void init(Simulator &simulator)
Initialize the linearizer.
Definition: fvbaselinearizer.hh:141
FvBaseLinearizer(const FvBaseLinearizer &)=delete
const auto & getVelocityInfo() const
Return constant reference to the velocityInfo.
Definition: fvbaselinearizer.hh:342
void updateBoundaryConditionData()
Definition: fvbaselinearizer.hh:302
void linearizeDomain()
Linearize the part of the non-linear system of equations that is associated with the spatial domain.
Definition: fvbaselinearizer.hh:186
void resetSystem_(const SubDomainType &domain)
Definition: fvbaselinearizer.hh:346
GlobalEqVector & residual()
Definition: fvbaselinearizer.hh:287
const SparseMatrixAdapter & jacobian() const
Return constant reference to global Jacobian matrix backend.
Definition: fvbaselinearizer.hh:275
const auto & getFloresInfo() const
Return constant reference to the floresInfo.
Definition: fvbaselinearizer.hh:333
void linearizeAuxiliaryEquations()
Linearize the part of the non-linear system of equations that is associated with the spatial domain.
Definition: fvbaselinearizer.hh:243
void updateDiscretizationParameters()
Definition: fvbaselinearizer.hh:297
const LinearizationType & getLinearizationType() const
Definition: fvbaselinearizer.hh:294
void updateFlowsInfo()
Definition: fvbaselinearizer.hh:307
void linearizeDomain(const SubDomainType &domain, bool isNlddLocalSolve=false)
Definition: fvbaselinearizer.hh:192
const std::map< unsigned, Constraints > & constraintsMap() const
Returns the map of constraint degrees of freedom.
Definition: fvbaselinearizer.hh:317
void eraseMatrix()
Causes the Jacobian matrix to be recreated from scratch before the next iteration.
Definition: fvbaselinearizer.hh:156
Definition: matrixblock.hh:229
Manages the initializing and running of time dependent problems.
Definition: simulator.hh:84
Problem & problem()
Return the object which specifies the pysical setup of the simulation.
Definition: simulator.hh:265
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
Simplifies multi-threaded capabilities.
Definition: threadmanager.hpp:36
static unsigned maxThreads()
Return the maximum number of threads of the current process.
Definition: threadmanager.hpp:66
static unsigned threadId()
Return the index of the current OpenMP thread.
Provides an STL-iterator like interface to iterate over the enties of a GridView in OpenMP threaded a...
Definition: threadedentityiterator.hh:42
bool isFinished(const EntityIterator &it) const
Definition: threadedentityiterator.hh:67
EntityIterator increment()
Definition: threadedentityiterator.hh:80
EntityIterator beginParallel()
Definition: threadedentityiterator.hh:54
Declare the properties used by the infrastructure code of the finite volume discretizations.
Provides data handles for parallel communication which operate on DOFs.
Definition: blackoilbioeffectsmodules.hh:45
ElementType
The types of reference elements available.
Definition: vcfvstencil.hh:56
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
Definition: linearizationtype.hh:34