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 (
static_cast<std::size_t
>(domain.view.size(0)) == model_().numTotalDof()) {
216 catch (
const std::exception& e)
218 std::cout <<
"rank " << simulator_().
gridView().comm().rank()
219 <<
" caught an exception while linearizing:" << e.what()
220 <<
"\n" << std::flush;
225 std::cout <<
"rank " << simulator_().
gridView().comm().rank()
226 <<
" caught an exception while linearizing"
227 <<
"\n" << std::flush;
230 succeeded = simulator_().
gridView().comm().min(succeeded);
233 throw NumericalProblem(
"A process did not succeed in linearizing the system");
238 { jacobian_->finalize(); }
250 auto& model = model_();
251 const auto& comm = simulator_().
gridView().comm();
252 for (
unsigned auxModIdx = 0; auxModIdx < model.numAuxiliaryModules(); ++auxModIdx) {
253 bool succeeded =
true;
255 model.auxiliaryModule(auxModIdx)->linearize(*jacobian_, residual_);
257 catch (
const std::exception& e) {
260 std::cout <<
"rank " << simulator_().
gridView().comm().rank()
261 <<
" caught an exception while linearizing:" << e.what()
262 <<
"\n" << std::flush;
265 succeeded = comm.min(succeeded);
268 throw NumericalProblem(
"linearization of an auxiliary equation failed");
277 {
return *jacobian_; }
280 {
return *jacobian_; }
286 {
return residual_; }
289 {
return residual_; }
292 { linearizationType_ = linearizationType; }
295 {
return linearizationType_; }
318 {
return constraintsMap_; }
326 {
return flowsInfo_; }
334 {
return floresInfo_; }
336 template <
class SubDomainType>
340 initFirstIteration_();
344 using GridViewType =
decltype(domain.view);
355 const Element& elem = *elemIt;
356 ElementContext& elemCtx = *elementCtx_[threadId];
357 elemCtx.updatePrimaryStencil(elem);
359 for (
unsigned primaryDofIdx = 0;
360 primaryDofIdx < elemCtx.numPrimaryDof(0);
363 const unsigned globI = elemCtx.globalSpaceIndex(primaryDofIdx, 0);
364 residual_[globI] = 0.0;
365 jacobian_->clearRow(globI, 0.0);
373 {
return *simulatorPtr_; }
375 const Simulator& simulator_()
const
376 {
return *simulatorPtr_; }
379 {
return simulator_().
problem(); }
381 const Problem& problem_()
const
382 {
return simulator_().
problem(); }
385 {
return simulator_().
model(); }
387 const Model& model_()
const
388 {
return simulator_().
model(); }
390 const GridView& gridView_()
const
391 {
return problem_().gridView(); }
393 const ElementMapper& elementMapper_()
const
394 {
return model_().elementMapper(); }
396 const DofMapper& dofMapper_()
const
397 {
return model_().dofMapper(); }
399 void initFirstIteration_()
405 residual_.resize(model_().numTotalDof());
412 elementCtx_.push_back(std::make_unique<ElementContext>(simulator_()));
419 const auto& model = model_();
420 Stencil stencil(gridView_(), model_().dofMapper());
424 sparsityPattern_.clear();
425 sparsityPattern_.resize(model.numTotalDof());
427 for (
const auto& elem : elements(gridView_())) {
428 stencil.update(elem);
430 for (
unsigned primaryDofIdx = 0; primaryDofIdx < stencil.numPrimaryDof(); ++primaryDofIdx) {
431 const unsigned myIdx = stencil.globalSpaceIndex(primaryDofIdx);
433 for (
unsigned dofIdx = 0; dofIdx < stencil.numDof(); ++dofIdx) {
434 const unsigned neighborIdx = stencil.globalSpaceIndex(dofIdx);
435 sparsityPattern_[myIdx].insert(neighborIdx);
442 const std::size_t numAuxMod = model.numAuxiliaryModules();
443 for (
unsigned auxModIdx = 0; auxModIdx < numAuxMod; ++auxModIdx) {
444 model.auxiliaryModule(auxModIdx)->addNeighbors(sparsityPattern_);
448 jacobian_ = std::make_unique<SparseMatrixAdapter>(simulator_());
451 jacobian_->reserve(sparsityPattern_);
464 void updateConstraintsMap_()
466 if (!enableConstraints_()) {
471 constraintsMap_.clear();
474 ThreadedEntityIterator<GridView, 0> threadedElemIt(gridView_());
480 ElementIterator elemIt = threadedElemIt.beginParallel();
481 for (; !threadedElemIt.isFinished(elemIt); elemIt = threadedElemIt.increment()) {
484 const Element& elem = *elemIt;
485 ElementContext& elemCtx = *elementCtx_[threadId];
486 elemCtx.updateStencil(elem);
490 for (
unsigned primaryDofIdx = 0;
491 primaryDofIdx < elemCtx.numPrimaryDof(0);
494 Constraints constraints;
495 elemCtx.problem().constraints(constraints,
499 if (constraints.isActive()) {
500 const unsigned globI = elemCtx.globalSpaceIndex(primaryDofIdx, 0);
501 constraintsMap_[globI] = constraints;
510 template <
class SubDomainType>
511 void linearize_(
const SubDomainType& domain)
513 OPM_TIMEBLOCK(linearize_);
522 if (model_().newtonMethod().numIterations() == 0) {
523 updateConstraintsMap_();
526 applyConstraintsToSolution_();
531 std::mutex exceptionLock;
535 std::exception_ptr exceptionPtr =
nullptr;
538 using GridViewType =
decltype(domain.view);
539 ThreadedEntityIterator<GridViewType, 0> threadedElemIt(domain.view);
544 auto elemIt = threadedElemIt.beginParallel();
545 auto nextElemIt = elemIt;
547 for (; !threadedElemIt.isFinished(elemIt); elemIt = nextElemIt) {
550 nextElemIt = threadedElemIt.increment();
551 if (!threadedElemIt.isFinished(nextElemIt)) {
552 const auto& nextElem = *nextElemIt;
553 if (linearizeNonLocalElements ||
554 nextElem.partitionType() == Dune::InteriorEntity)
556 model_().prefetch(nextElem);
557 problem_().prefetch(nextElem);
561 const auto& elem = *elemIt;
562 if (!linearizeNonLocalElements && elem.partitionType() != Dune::InteriorEntity) {
566 linearizeElement_(elem);
579 std::lock_guard<std::mutex> take(exceptionLock);
580 exceptionPtr = std::current_exception();
581 threadedElemIt.setFinished();
589 std::rethrow_exception(exceptionPtr);
592 applyConstraintsToLinearization_();
596 template <
class ElementType>
601 ElementContext& elementCtx = *elementCtx_[threadId];
602 auto& localLinearizer = model_().localLinearizer(threadId);
605 localLinearizer.linearize(elementCtx, elem);
608 if (getPropValue<TypeTag, Properties::UseLinearizationLock>()) {
609 globalMatrixMutex_.lock();
612 const std::size_t numPrimaryDof = elementCtx.numPrimaryDof(0);
613 for (
unsigned primaryDofIdx = 0; primaryDofIdx < numPrimaryDof; ++primaryDofIdx) {
614 const unsigned globI = elementCtx.globalSpaceIndex(primaryDofIdx, 0);
617 residual_[globI] += localLinearizer.residual(primaryDofIdx);
620 for (
unsigned dofIdx = 0; dofIdx < elementCtx.numDof(0); ++dofIdx) {
621 const unsigned globJ = elementCtx.globalSpaceIndex(dofIdx, 0);
623 jacobian_->addToBlock(globJ, globI, localLinearizer.jacobian(dofIdx, primaryDofIdx));
627 if (getPropValue<TypeTag, Properties::UseLinearizationLock>()) {
628 globalMatrixMutex_.unlock();
634 void applyConstraintsToSolution_()
636 if (!enableConstraints_()) {
641 auto& sol = model_().solution(0);
642 auto& oldSol = model_().solution(1);
644 for (
const auto& constraint : constraintsMap_) {
645 sol[constraint.first] = constraint.second;
646 oldSol[constraint.first] = constraint.second;
652 void applyConstraintsToLinearization_()
654 if (!enableConstraints_()) {
658 for (
const auto& constraint : constraintsMap_) {
661 jacobian_->clearRow(constraint.first, Scalar(1.0));
664 residual_[constraint.first] = 0.0;
668 static bool enableConstraints_()
669 {
return getPropValue<TypeTag, Properties::EnableConstraints>(); }
671 Simulator* simulatorPtr_{};
672 std::vector<std::unique_ptr<ElementContext>> elementCtx_;
676 std::map<unsigned, Constraints> constraintsMap_;
684 SparseTable<FlowInfo> flowsInfo_;
685 SparseTable<FlowInfo> floresInfo_;
688 std::unique_ptr<SparseMatrixAdapter> jacobian_;
691 GlobalEqVector residual_;
693 LinearizationType linearizationType_;
695 std::mutex globalMatrixMutex_;
697 std::vector<std::set<unsigned int>> sparsityPattern_;
701 explicit FullDomain(
const GridView& v) : view (v) {}
703 std::vector<bool> interior;
708 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:285
void setLinearizationType(LinearizationType linearizationType)
Definition: fvbaselinearizer.hh:291
SparseMatrixAdapter & jacobian()
Definition: fvbaselinearizer.hh:279
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:237
void init(Simulator &simulator)
Initialize the linearizer.
Definition: fvbaselinearizer.hh:141
FvBaseLinearizer(const FvBaseLinearizer &)=delete
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:337
GlobalEqVector & residual()
Definition: fvbaselinearizer.hh:288
const SparseMatrixAdapter & jacobian() const
Return constant reference to global Jacobian matrix backend.
Definition: fvbaselinearizer.hh:276
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:244
void linearizeDomain(const SubDomainType &domain)
Definition: fvbaselinearizer.hh:192
void updateDiscretizationParameters()
Definition: fvbaselinearizer.hh:297
const LinearizationType & getLinearizationType() const
Definition: fvbaselinearizer.hh:294
void updateFlowsInfo()
Definition: fvbaselinearizer.hh:307
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:227
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: blackoilboundaryratevector.hh:39
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