12#ifndef DUMUX_ASSEMBLER_HH
13#define DUMUX_ASSEMBLER_HH
23#include <dune/common/std/type_traits.hh>
24#include <dune/grid/common/rangegenerators.hh>
44#include "cvfelocalassembler_.hh"
48template<
class DiscretizationMethod>
54 template<
class TypeTag,
class Impl, DiffMethod diffMethod,
bool isImplicit>
58template<
class TypeTag,
class Impl, DiffMethod diffMethod,
bool isImplicit>
61>::template type<TypeTag, Impl, diffMethod, isImplicit>;
69{
return Dune::Std::is_detected<ProblemConstraintsDetector, P>::value; }
83template<
class TypeTag, DiffMethod diffMethod,
bool isImplicit = true,
class LocalRes
idual = GetPropType<TypeTag, Properties::LocalRes
idual>>
87 using GridView =
typename GridDisc::GridView;
88 using Element =
typename GridView::template Codim<0>::Entity;
89 using ElementSeed =
typename GridView::Grid::template Codim<0>::EntitySeed;
120 , isStationaryProblem_(true)
122 static_assert(isImplicit,
"Explicit assembler for stationary problem doesn't make sense!");
128 maybeComputeColors_();
139 std::shared_ptr<const TimeLoop> timeLoop,
144 , timeLoop_(timeLoop)
146 , isStationaryProblem_(!timeLoop)
153 maybeComputeColors_();
160 template<
class PartialReassembler = DefaultPartialReassembler>
163 checkAssemblerState_();
164 resetJacobian_(partialReassembler);
167 assemble_([&](
const Element& element)
169 LocalAssembler localAssembler(*
this, element, curSol);
170 localAssembler.assembleJacobianAndResidual(*jacobian_, *residual_, *gridVariables_, partialReassembler);
173 enforcePeriodicConstraints_(*jacobian_, *residual_, curSol, *gridDiscretization_);
175 auto applyDirichletConstraint = [&] (
const auto& dofIdx,
180 (*residual_)[dofIdx][eqIdx] = curSol[dofIdx][pvIdx] - values[pvIdx];
182 auto& row = (*jacobian_)[dofIdx];
183 for (
auto col = row.begin(); col != row.end(); ++col)
184 row[col.index()][eqIdx] = 0.0;
186 (*jacobian_)[dofIdx][dofIdx][eqIdx][pvIdx] = 1.0;
188 enforceProblemConstraints_(*problem_, *gridDiscretization_, applyDirichletConstraint);
196 checkAssemblerState_();
199 assemble_([&](
const Element& element)
201 LocalAssembler localAssembler(*
this, element, curSol);
202 localAssembler.assembleJacobian(*jacobian_, *gridVariables_);
205 enforcePeriodicConstraints_(*jacobian_, curSol, *gridDiscretization_);
207 auto applyDirichletConstraint = [&] (
const auto& dofIdx,
212 auto& row = (*jacobian_)[dofIdx];
213 for (
auto col = row.begin(); col != row.end(); ++col)
214 row[col.index()][eqIdx] = 0.0;
216 (*jacobian_)[dofIdx][dofIdx][eqIdx][pvIdx] = 1.0;
218 enforceProblemConstraints_(*problem_, *gridDiscretization_, applyDirichletConstraint);
231 checkAssemblerState_();
233 assemble_([&](
const Element& element)
235 LocalAssembler localAssembler(*
this, element, curSol);
236 localAssembler.assembleResidual(r);
239 enforcePeriodicConstraints_(r, curSol, *gridDiscretization_);
241 auto applyDirichletConstraint = [&] (
const auto& dofIdx,
246 r[dofIdx][eqIdx] = curSol[dofIdx][pvIdx] - values[pvIdx];
248 enforceProblemConstraints_(*problem_, *gridDiscretization_, applyDirichletConstraint);
257 std::shared_ptr<ResidualType> r)
263 if (jacobian_->buildMode() == JacobianMatrix::BuildMode::unknown)
264 jacobian_->setBuildMode(JacobianMatrix::random);
265 else if (jacobian_->buildMode() != JacobianMatrix::BuildMode::random)
266 DUNE_THROW(Dune::NotImplemented,
"Only BCRS matrices with random build mode are supported at the moment");
269 setJacobianPattern_();
278 jacobian_ = std::make_shared<JacobianMatrix>();
279 jacobian_->setBuildMode(JacobianMatrix::random);
280 residual_ = std::make_shared<ResidualType>();
283 setJacobianPattern_();
292 setJacobianPattern_();
293 maybeComputeColors_();
298 {
return gridDiscretization_->numDofs(); }
302 {
return *problem_; }
306 {
return *gridDiscretization_; }
310 {
return *gridDiscretization_; }
318 {
return *gridVariables_; }
322 {
return *gridVariables_; }
326 {
return *jacobian_; }
330 {
return *residual_; }
334 {
return *prevSol_; }
341 { timeLoop_ = timeLoop; isStationaryProblem_ = !
static_cast<bool>(timeLoop); }
354 {
return isStationaryProblem_; }
382 void setJacobianPattern_()
392 occupationPattern.exportIdx(*jacobian_);
396 void setResidualSize_()
397 { residual_->resize(
numDofs()); }
400 void maybeComputeColors_()
402 if (enableMultithreading_)
407 void resetResidual_()
411 residual_ = std::make_shared<ResidualType>();
419 template <
class PartialReassembler = DefaultPartialReassembler>
420 void resetJacobian_(
const PartialReassembler *partialReassembler =
nullptr)
424 jacobian_ = std::make_shared<JacobianMatrix>();
425 jacobian_->setBuildMode(JacobianMatrix::random);
426 setJacobianPattern_();
429 if (partialReassembler)
430 partialReassembler->resetJacobian(*
this);
436 void checkAssemblerState_()
const
438 if (!isStationaryProblem_ && !prevSol_)
439 DUNE_THROW(Dune::InvalidStateException,
"Assembling instationary problem but previous solution was not set!");
447 template<
typename AssembleElementFunc>
448 void assemble_(AssembleElementFunc&& assembleElement)
const
451 bool succeeded =
false;
456 if (enableMultithreading_)
458 assert(elementSets_.size() > 0);
464 for (
const auto& elements : elementSets_)
468 const auto element = gridView().grid().entity(elements[i]);
469 assembleElement(element);
474 for (
const auto& element : elements(
gridView()))
475 assembleElement(element);
481 catch (
const NumericalProblem& e)
483 std::cout <<
"rank " <<
gridView().comm().rank()
484 <<
" caught an exception while assembling:" << e.what()
491 succeeded =
gridView().comm().min(succeeded);
495 DUNE_THROW(NumericalProblem,
"A process did not succeed in linearizing the system");
505 const auto& periodicallyMappedDofs = Dumux::Deprecated::ensureRangeOfPeriodicDofs(m.second);
506 if (std::ranges::all_of(periodicallyMappedDofs, [&](
auto second){
return m.first < second; }))
508 for (
const auto& second : periodicallyMappedDofs)
511 res[m.first] += res[second];
512 const auto end = jac[second].end();
513 for (
auto it = jac[second].begin(); it != end; ++it)
514 jac[m.first][it.index()] += (*it);
517 res[second] = curSol[second] - curSol[m.first];
520 auto setMatrixBlock = [] (
auto& matrixBlock,
double diagValue)
522 for (
int eIdx = 0; eIdx < matrixBlock.N(); ++eIdx)
523 matrixBlock[eIdx][eIdx] = diagValue;
526 for (
auto it = jac[second].begin(); it != end; ++it)
528 auto& matrixBlock = *it;
531 assert(matrixBlock.N() == matrixBlock.M());
532 if(it.index() == second)
533 setMatrixBlock(matrixBlock, 1.0);
535 if(it.index() == m.first)
536 setMatrixBlock(matrixBlock, -1.0);
552 const auto& periodicallyMappedDofs = Dumux::Deprecated::ensureRangeOfPeriodicDofs(m.second);
553 if (std::ranges::all_of(periodicallyMappedDofs, [&](
auto second){
return m.first < second; }))
555 for (
const auto& second : periodicallyMappedDofs)
558 const auto end = jac[second].end();
559 for (
auto it = jac[second].begin(); it != end; ++it)
560 jac[m.first][it.index()] += (*it);
563 auto setMatrixBlock = [] (
auto& matrixBlock,
double diagValue)
565 for (
int eIdx = 0; eIdx < matrixBlock.N(); ++eIdx)
566 matrixBlock[eIdx][eIdx] = diagValue;
569 for (
auto it = jac[second].begin(); it != end; ++it)
571 auto& matrixBlock = *it;
574 assert(matrixBlock.N() == matrixBlock.M());
575 if(it.index() == second)
576 setMatrixBlock(matrixBlock, 1.0);
578 if(it.index() == m.first)
579 setMatrixBlock(matrixBlock, -1.0);
595 const auto& periodicallyMappedDofs = Dumux::Deprecated::ensureRangeOfPeriodicDofs(m.second);
596 if (std::ranges::all_of(periodicallyMappedDofs, [&](
auto second){
return m.first < second; }))
598 for (
const auto& second : periodicallyMappedDofs)
601 res[m.first] += res[second];
604 res[second] = curSol[second] - curSol[m.first];
611 template<
class Problem,
class GG,
typename ApplyFunction>
612 void enforceProblemConstraints_(
const Problem&
problem,
const GG&,
const ApplyFunction& applyDirichletConstraint)
const
616 for (
const auto& constraintData :
problem.constraints())
618 const auto& constraintInfo = constraintData.constraintInfo();
619 const auto& values = constraintData.values();
620 const auto dofIdx = constraintData.dofIndex();
622 for (
int eqIdx = 0; eqIdx < constraintInfo.size(); ++eqIdx)
624 if (constraintInfo.isConstraintEquation(eqIdx))
626 const auto pvIdx = constraintInfo.eqToPriVarIndex(eqIdx);
627 assert(0 <= pvIdx && pvIdx < constraintInfo.size());
628 applyDirichletConstraint(dofIdx, values, eqIdx, pvIdx);
636 std::shared_ptr<const Problem> problem_;
639 std::shared_ptr<const GridDiscretization> gridDiscretization_;
642 std::shared_ptr<GridVariables> gridVariables_;
645 std::shared_ptr<const TimeLoop> timeLoop_;
651 bool isStationaryProblem_;
654 std::shared_ptr<JacobianMatrix> jacobian_;
655 std::shared_ptr<ResidualType> residual_;
658 bool enableMultithreading_ =
false;
659 std::deque<std::vector<ElementSeed>> elementSets_;
typename Dumux::Detail::NativeDuneVectorType< SolutionVector >::type ResidualType
Definition assembly/assembler.hh:99
void updateGridVariables(const SolutionVector &curSol)
Update the grid variables.
Definition assembly/assembler.hh:365
GetPropType< TypeTag, Properties::GridVariables > GridVariables
Definition assembly/assembler.hh:101
void assembleResidual(const SolutionVector &curSol)
compute the residuals using the internal residual
Definition assembly/assembler.hh:222
LocalResidual localResidual() const
Create a local residual object (used by the local assembler).
Definition assembly/assembler.hh:359
ResidualType & residual()
The residual vector (rhs).
Definition assembly/assembler.hh:329
void assembleJacobianAndResidual(const SolutionVector &curSol, const PartialReassembler *partialReassembler=nullptr)
Assembles the global Jacobian of the residual and the residual for the current solution.
Definition assembly/assembler.hh:161
GetPropType< TypeTag, Properties::Scalar > Scalar
Definition assembly/assembler.hh:96
void updateAfterGridAdaption()
Resizes jacobian and residual and recomputes colors.
Definition assembly/assembler.hh:289
const GridDiscretization & gridDiscretization() const
Definition assembly/assembler.hh:305
const SolutionVector & prevSol() const
Definition assembly/assembler.hh:333
std::size_t numDofs() const
Returns the number of degrees of freedom.
Definition assembly/assembler.hh:297
void assembleResidual(ResidualType &r, const SolutionVector &curSol) const
assemble a residual r
Definition assembly/assembler.hh:229
Assembler(std::shared_ptr< const Problem > problem, std::shared_ptr< const GridDiscretization > gridDiscretization, std::shared_ptr< GridVariables > gridVariables, std::shared_ptr< const TimeLoop > timeLoop, const SolutionVector &prevSol)
The constructor for instationary problems.
Definition assembly/assembler.hh:136
GetPropType< TypeTag, Properties::SolutionVector > SolutionVector
Definition assembly/assembler.hh:98
Assembler(std::shared_ptr< const Problem > problem, std::shared_ptr< const GridDiscretization > gridDiscretization, std::shared_ptr< GridVariables > gridVariables)
The constructor for stationary problems.
Definition assembly/assembler.hh:113
void setTimeLoop(std::shared_ptr< const TimeLoop > timeLoop)
Set time loop for instationary problems.
Definition assembly/assembler.hh:340
void setLinearSystem(std::shared_ptr< JacobianMatrix > A, std::shared_ptr< ResidualType > r)
Tells the assembler which jacobian and residual to use. This also resizes the containers to the requi...
Definition assembly/assembler.hh:256
void setPreviousSolution(const SolutionVector &u)
Sets the solution from which to start the time integration. Has to be called prior to assembly for ti...
Definition assembly/assembler.hh:347
const GridView & gridView() const
The gridview.
Definition assembly/assembler.hh:313
GetPropType< TypeTag, Properties::Problem > Problem
Definition assembly/assembler.hh:106
void assembleJacobian(const SolutionVector &curSol)
Assembles only the global Jacobian of the residual.
Definition assembly/assembler.hh:194
JacobianMatrix & jacobian()
The jacobian matrix.
Definition assembly/assembler.hh:325
GridDisc GridDiscretization
Definition assembly/assembler.hh:103
bool isStationaryProblem() const
Whether we are assembling a stationary or instationary problem.
Definition assembly/assembler.hh:353
GridDisc GridGeometry
Definition assembly/assembler.hh:105
const GridVariables & gridVariables() const
The global grid variables.
Definition assembly/assembler.hh:321
void setLinearSystem()
The version without arguments uses the default constructor to create the jacobian and residual object...
Definition assembly/assembler.hh:276
GetPropType< TypeTag, Properties::JacobianMatrix > JacobianMatrix
Definition assembly/assembler.hh:97
const GridDiscretization & gridGeometry() const
support old interfaces
Definition assembly/assembler.hh:309
GridVariables & gridVariables()
Definition assembly/assembler.hh:317
void resetTimeStep(const SolutionVector &curSol)
Reset the gridVariables.
Definition assembly/assembler.hh:373
const Problem & problem() const
Definition assembly/assembler.hh:301
An assembler for Jacobian and residual contribution per element (CVFE methods).
Definition experimental/assembly/cvfelocalassembler.hh:335
The element-wise residual for grid-based discretization schemes.
Definition assembly/localresidual.hh:39
detects which entries in the Jacobian have to be recomputed
Definition partialreassembler.hh:418
Manages the handling of time dependent problems.
Definition common/timeloop.hh:84
Coloring schemes for shared-memory-parallel assembly.
Defines all properties used in Dumux.
Manages the handling of time dependent problems.
An enum class to define various differentiation methods available in order to compute the derivatives...
Helper to extract native Dune vector types from particular Dumux types.
Some exceptions thrown in DuMux.
dune-grid capabilities compatibility layer
Dune::MatrixIndexSet getJacobianPattern(const GridGeometry &gridGeometry)
Helper function to generate Jacobian pattern for cell-centered methods.
Definition jacobianpattern.hh:29
constexpr bool isSerial()
Checking whether the backend is serial.
Definition multithreading.hh:45
void parallelFor(const std::size_t count, const FunctorType &functor)
A parallel for loop (multithreading).
Definition parallel_for.hh:160
T getParam(Args &&... args)
A free function to get a parameter from the parameter tree singleton.
Definition parameters.hh:155
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition propertysystem.hh:296
Helper function to generate Jacobian pattern for different discretization methods.
The available discretization methods in Dumux.
constexpr bool hasPeriodicDofMap()
Definition periodic.hh:24
Definition cvfe/hybrid/elementvariables.hh:32
Definition assembly/assembler.hh:46
constexpr bool hasGlobalConstraints()
Definition assembly/assembler.hh:68
decltype(std::declval< P >().constraints()) ProblemConstraintsDetector
helper struct detecting if problem has a constraints() function
Definition assembly/assembler.hh:65
typename LocalAssemblerChooser< typename GetPropType< TypeTag, Properties::GridGeometry >::DiscretizationMethod >::template type< TypeTag, Impl, diffMethod, isImplicit > LocalAssemblerChooser_t
Definition assembly/assembler.hh:59
Definition assembly/assembler.hh:46
bool supportsMultithreading(const GridView &gridView)
Definition gridcapabilities.hh:36
const Scalar PengRobinsonMixture< Scalar, StaticParameters >::u
Definition pengrobinsonmixture.hh:138
auto computeColoring(const GridGeometry &gg, int verbosity=1)
Compute iterable lists of element seeds partitioned by color.
Definition coloring.hh:243
Parallel for loop (multithreading).
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
Type traits to detect periodicity support.
typename NativeDuneVectorTypeImpl< V, Dune::Std::is_detected< Detail::DuneVectors::StateDetector, V >{} >::type type
Definition dunevectors.hh:57
Dumux::Experimental::CVFELocalAssembler< TypeTag, Impl, diffMethod, isImplicit > type
Definition assembly/assembler.hh:55
Definition assembly/assembler.hh:49
Traits specifying if a given discretization tag supports coloring.
Definition coloring.hh:296