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; }
294 {
return linearizationType_; }
317 {
return constraintsMap_; }
325 {
return flowsInfo_; }
333 {
return floresInfo_; }
335 template <
class SubDomainType>
339 initFirstIteration_();
343 using GridViewType =
decltype(domain.view);
354 const Element& elem = *elemIt;
355 ElementContext& elemCtx = *elementCtx_[threadId];
356 elemCtx.updatePrimaryStencil(elem);
358 for (
unsigned primaryDofIdx = 0;
359 primaryDofIdx < elemCtx.numPrimaryDof(0);
362 const unsigned globI = elemCtx.globalSpaceIndex(primaryDofIdx, 0);
363 residual_[globI] = 0.0;
364 jacobian_->clearRow(globI, 0.0);
372 {
return *simulatorPtr_; }
374 const Simulator& simulator_()
const
375 {
return *simulatorPtr_; }
378 {
return simulator_().
problem(); }
380 const Problem& problem_()
const
381 {
return simulator_().
problem(); }
384 {
return simulator_().
model(); }
386 const Model& model_()
const
387 {
return simulator_().
model(); }
389 const GridView& gridView_()
const
390 {
return problem_().gridView(); }
392 const ElementMapper& elementMapper_()
const
393 {
return model_().elementMapper(); }
395 const DofMapper& dofMapper_()
const
396 {
return model_().dofMapper(); }
398 void initFirstIteration_()
404 residual_.resize(model_().numTotalDof());
411 elementCtx_.push_back(std::make_unique<ElementContext>(simulator_()));
418 const auto& model = model_();
419 Stencil stencil(gridView_(), model_().dofMapper());
423 sparsityPattern_.clear();
424 sparsityPattern_.resize(model.numTotalDof());
426 for (
const auto& elem : elements(gridView_())) {
427 stencil.update(elem);
429 for (
unsigned primaryDofIdx = 0; primaryDofIdx < stencil.numPrimaryDof(); ++primaryDofIdx) {
430 const unsigned myIdx = stencil.globalSpaceIndex(primaryDofIdx);
432 for (
unsigned dofIdx = 0; dofIdx < stencil.numDof(); ++dofIdx) {
433 const unsigned neighborIdx = stencil.globalSpaceIndex(dofIdx);
434 sparsityPattern_[myIdx].insert(neighborIdx);
441 const std::size_t numAuxMod = model.numAuxiliaryModules();
442 for (
unsigned auxModIdx = 0; auxModIdx < numAuxMod; ++auxModIdx) {
443 model.auxiliaryModule(auxModIdx)->addNeighbors(sparsityPattern_);
447 jacobian_ = std::make_unique<SparseMatrixAdapter>(simulator_());
450 jacobian_->reserve(sparsityPattern_);
463 void updateConstraintsMap_()
465 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 const 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_();
525 applyConstraintsToSolution_();
530 std::mutex exceptionLock;
534 std::exception_ptr exceptionPtr =
nullptr;
537 using GridViewType =
decltype(domain.view);
538 ThreadedEntityIterator<GridViewType, 0> threadedElemIt(domain.view);
543 auto elemIt = threadedElemIt.beginParallel();
544 auto nextElemIt = elemIt;
546 for (; !threadedElemIt.isFinished(elemIt); elemIt = nextElemIt) {
549 nextElemIt = threadedElemIt.increment();
550 if (!threadedElemIt.isFinished(nextElemIt)) {
551 const auto& nextElem = *nextElemIt;
552 if (linearizeNonLocalElements ||
553 nextElem.partitionType() == Dune::InteriorEntity)
555 model_().prefetch(nextElem);
556 problem_().prefetch(nextElem);
560 const auto& elem = *elemIt;
561 if (!linearizeNonLocalElements && elem.partitionType() != Dune::InteriorEntity) {
565 linearizeElement_(elem);
578 std::lock_guard<std::mutex> take(exceptionLock);
579 exceptionPtr = std::current_exception();
580 threadedElemIt.setFinished();
588 std::rethrow_exception(exceptionPtr);
591 applyConstraintsToLinearization_();
595 template <
class ElementType>
600 ElementContext& elementCtx = *elementCtx_[threadId];
601 auto& localLinearizer = model_().localLinearizer(threadId);
604 localLinearizer.linearize(elementCtx, elem);
607 if (getPropValue<TypeTag, Properties::UseLinearizationLock>()) {
608 globalMatrixMutex_.lock();
611 const std::size_t numPrimaryDof = elementCtx.numPrimaryDof(0);
612 for (
unsigned primaryDofIdx = 0; primaryDofIdx < numPrimaryDof; ++primaryDofIdx) {
613 const unsigned globI = elementCtx.globalSpaceIndex(primaryDofIdx, 0);
616 residual_[globI] += localLinearizer.residual(primaryDofIdx);
619 for (
unsigned dofIdx = 0; dofIdx < elementCtx.numDof(0); ++dofIdx) {
620 const unsigned globJ = elementCtx.globalSpaceIndex(dofIdx, 0);
622 jacobian_->addToBlock(globJ, globI, localLinearizer.jacobian(dofIdx, primaryDofIdx));
626 if (getPropValue<TypeTag, Properties::UseLinearizationLock>()) {
627 globalMatrixMutex_.unlock();
633 void applyConstraintsToSolution_()
635 if (!enableConstraints_()) {
640 auto& sol = model_().solution(0);
641 auto& oldSol = model_().solution(1);
643 for (
const auto& constraint : constraintsMap_) {
644 sol[constraint.first] = constraint.second;
645 oldSol[constraint.first] = constraint.second;
651 void applyConstraintsToLinearization_()
653 if (!enableConstraints_()) {
657 for (
const auto& constraint : constraintsMap_) {
660 jacobian_->clearRow(constraint.first, Scalar(1.0));
663 residual_[constraint.first] = 0.0;
667 static bool enableConstraints_()
668 {
return getPropValue<TypeTag, Properties::EnableConstraints>(); }
670 Simulator* simulatorPtr_{};
671 std::vector<std::unique_ptr<ElementContext>> elementCtx_;
675 std::map<unsigned, Constraints> constraintsMap_;
683 SparseTable<FlowInfo> flowsInfo_;
684 SparseTable<FlowInfo> floresInfo_;
687 std::unique_ptr<SparseMatrixAdapter> jacobian_;
690 GlobalEqVector residual_;
692 LinearizationType linearizationType_;
694 std::mutex globalMatrixMutex_;
696 std::vector<std::set<unsigned int>> sparsityPattern_;
700 explicit FullDomain(
const GridView& v) : view (v) {}
702 std::vector<bool> interior;
707 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:324
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
void updateBoundaryConditionData()
Definition: fvbaselinearizer.hh:301
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:336
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:332
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:296
const LinearizationType & getLinearizationType() const
Definition: fvbaselinearizer.hh:293
void updateFlowsInfo()
Definition: fvbaselinearizer.hh:306
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:316
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:43
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