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;
113 using MatrixBlock =
typename SparseMatrixAdapter::MatrixBlock;
114 using VectorBlock = Dune::FieldVector<Scalar, numEq>;
121 FvBaseLinearizer() =
default;
124 FvBaseLinearizer(
const FvBaseLinearizer&) =
delete;
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);
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));
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_()
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_;