12#ifndef DUMUX_ASSEMBLER_HH
13#define DUMUX_ASSEMBLER_HH
22#include <dune/common/std/type_traits.hh>
23#include <dune/grid/common/rangegenerators.hh>
42#include "cvfelocalassembler_.hh"
46template<
class DiscretizationMethod>
52 template<
class TypeTag,
class Impl, DiffMethod diffMethod,
bool isImplicit>
56template<
class TypeTag,
class Impl, DiffMethod diffMethod,
bool isImplicit>
59>::template type<TypeTag, Impl, diffMethod, isImplicit>;
67{
return Dune::Std::is_detected<ProblemConstraintsDetector, P>::value; }
81template<
class TypeTag, DiffMethod diffMethod,
bool isImplicit = true,
class LocalRes
idual = GetPropType<TypeTag, Properties::LocalRes
idual>>
85 using GridView =
typename GridDisc::GridView;
86 using Element =
typename GridView::template Codim<0>::Entity;
87 using ElementSeed =
typename GridView::Grid::template Codim<0>::EntitySeed;
118 , isStationaryProblem_(true)
120 static_assert(isImplicit,
"Explicit assembler for stationary problem doesn't make sense!");
126 maybeComputeColors_();
137 std::shared_ptr<const TimeLoop> timeLoop,
142 , timeLoop_(timeLoop)
144 , isStationaryProblem_(!timeLoop)
151 maybeComputeColors_();
158 template<
class PartialReassembler = DefaultPartialReassembler>
161 checkAssemblerState_();
162 resetJacobian_(partialReassembler);
165 assemble_([&](
const Element& element)
167 LocalAssembler localAssembler(*
this, element, curSol);
168 localAssembler.assembleJacobianAndResidual(*jacobian_, *residual_, *gridVariables_, partialReassembler);
171 enforcePeriodicConstraints_(*jacobian_, *residual_, curSol, *gridDiscretization_);
173 auto applyDirichletConstraint = [&] (
const auto& dofIdx,
178 (*residual_)[dofIdx][eqIdx] = curSol[dofIdx][pvIdx] - values[pvIdx];
180 auto& row = (*jacobian_)[dofIdx];
181 for (
auto col = row.begin(); col != row.end(); ++col)
182 row[col.index()][eqIdx] = 0.0;
184 (*jacobian_)[dofIdx][dofIdx][eqIdx][pvIdx] = 1.0;
186 enforceProblemConstraints_(*problem_, *gridDiscretization_, applyDirichletConstraint);
194 checkAssemblerState_();
197 assemble_([&](
const Element& element)
199 LocalAssembler localAssembler(*
this, element, curSol);
200 localAssembler.assembleJacobian(*jacobian_, *gridVariables_);
203 enforcePeriodicConstraints_(*jacobian_, curSol, *gridDiscretization_);
205 auto applyDirichletConstraint = [&] (
const auto& dofIdx,
210 auto& row = (*jacobian_)[dofIdx];
211 for (
auto col = row.begin(); col != row.end(); ++col)
212 row[col.index()][eqIdx] = 0.0;
214 (*jacobian_)[dofIdx][dofIdx][eqIdx][pvIdx] = 1.0;
216 enforceProblemConstraints_(*problem_, *gridDiscretization_, applyDirichletConstraint);
229 checkAssemblerState_();
231 assemble_([&](
const Element& element)
233 LocalAssembler localAssembler(*
this, element, curSol);
234 localAssembler.assembleResidual(r);
237 enforcePeriodicConstraints_(r, curSol, *gridDiscretization_);
239 auto applyDirichletConstraint = [&] (
const auto& dofIdx,
244 r[dofIdx][eqIdx] = curSol[dofIdx][pvIdx] - values[pvIdx];
246 enforceProblemConstraints_(*problem_, *gridDiscretization_, applyDirichletConstraint);
255 std::shared_ptr<ResidualType> r)
261 if (jacobian_->buildMode() == JacobianMatrix::BuildMode::unknown)
262 jacobian_->setBuildMode(JacobianMatrix::random);
263 else if (jacobian_->buildMode() != JacobianMatrix::BuildMode::random)
264 DUNE_THROW(Dune::NotImplemented,
"Only BCRS matrices with random build mode are supported at the moment");
267 setJacobianPattern_();
276 jacobian_ = std::make_shared<JacobianMatrix>();
277 jacobian_->setBuildMode(JacobianMatrix::random);
278 residual_ = std::make_shared<ResidualType>();
281 setJacobianPattern_();
290 setJacobianPattern_();
291 maybeComputeColors_();
296 {
return gridDiscretization_->numDofs(); }
300 {
return *problem_; }
304 {
return *gridDiscretization_; }
308 {
return *gridDiscretization_; }
316 {
return *gridVariables_; }
320 {
return *gridVariables_; }
324 {
return *jacobian_; }
328 {
return *residual_; }
332 {
return *prevSol_; }
339 { timeLoop_ = timeLoop; isStationaryProblem_ = !
static_cast<bool>(timeLoop); }
352 {
return isStationaryProblem_; }
380 void setJacobianPattern_()
390 occupationPattern.exportIdx(*jacobian_);
394 void setResidualSize_()
395 { residual_->resize(
numDofs()); }
398 void maybeComputeColors_()
400 if (enableMultithreading_)
405 void resetResidual_()
409 residual_ = std::make_shared<ResidualType>();
417 template <
class PartialReassembler = DefaultPartialReassembler>
418 void resetJacobian_(
const PartialReassembler *partialReassembler =
nullptr)
422 jacobian_ = std::make_shared<JacobianMatrix>();
423 jacobian_->setBuildMode(JacobianMatrix::random);
424 setJacobianPattern_();
427 if (partialReassembler)
428 partialReassembler->resetJacobian(*
this);
434 void checkAssemblerState_()
const
436 if (!isStationaryProblem_ && !prevSol_)
437 DUNE_THROW(Dune::InvalidStateException,
"Assembling instationary problem but previous solution was not set!");
445 template<
typename AssembleElementFunc>
446 void assemble_(AssembleElementFunc&& assembleElement)
const
449 bool succeeded =
false;
454 if (enableMultithreading_)
456 assert(elementSets_.size() > 0);
462 for (
const auto& elements : elementSets_)
466 const auto element = gridView().grid().entity(elements[i]);
467 assembleElement(element);
472 for (
const auto& element : elements(
gridView()))
473 assembleElement(element);
479 catch (
const NumericalProblem& e)
481 std::cout <<
"rank " <<
gridView().comm().rank()
482 <<
" caught an exception while assembling:" << e.what()
489 succeeded =
gridView().comm().min(succeeded);
493 DUNE_THROW(NumericalProblem,
"A process did not succeed in linearizing the system");
503 if (m.first < m.second)
506 res[m.first] += res[m.second];
507 const auto end = jac[m.second].end();
508 for (
auto it = jac[m.second].begin(); it != end; ++it)
509 jac[m.first][it.index()] += (*it);
512 res[m.second] = curSol[m.second] - curSol[m.first];
515 auto setMatrixBlock = [] (
auto& matrixBlock,
double diagValue)
517 for (
int eIdx = 0; eIdx < matrixBlock.N(); ++eIdx)
518 matrixBlock[eIdx][eIdx] = diagValue;
521 for (
auto it = jac[m.second].begin(); it != end; ++it)
523 auto& matrixBlock = *it;
526 assert(matrixBlock.N() == matrixBlock.M());
527 if(it.index() == m.second)
528 setMatrixBlock(matrixBlock, 1.0);
530 if(it.index() == m.first)
531 setMatrixBlock(matrixBlock, -1.0);
546 if (m.first < m.second)
549 const auto end = jac[m.second].end();
550 for (
auto it = jac[m.second].begin(); it != end; ++it)
551 jac[m.first][it.index()] += (*it);
554 auto setMatrixBlock = [] (
auto& matrixBlock,
double diagValue)
556 for (
int eIdx = 0; eIdx < matrixBlock.N(); ++eIdx)
557 matrixBlock[eIdx][eIdx] = diagValue;
560 for (
auto it = jac[m.second].begin(); it != end; ++it)
562 auto& matrixBlock = *it;
565 assert(matrixBlock.N() == matrixBlock.M());
566 if(it.index() == m.second)
567 setMatrixBlock(matrixBlock, 1.0);
569 if(it.index() == m.first)
570 setMatrixBlock(matrixBlock, -1.0);
585 if (m.first < m.second)
588 res[m.first] += res[m.second];
591 res[m.second] = curSol[m.second] - curSol[m.first];
597 template<
class Problem,
class GG,
typename ApplyFunction>
598 void enforceProblemConstraints_(
const Problem&
problem,
const GG&,
const ApplyFunction& applyDirichletConstraint)
const
602 for (
const auto& constraintData :
problem.constraints())
604 const auto& constraintInfo = constraintData.constraintInfo();
605 const auto& values = constraintData.values();
606 const auto dofIdx = constraintData.dofIndex();
608 for (
int eqIdx = 0; eqIdx < constraintInfo.size(); ++eqIdx)
610 if (constraintInfo.isConstraintEquation(eqIdx))
612 const auto pvIdx = constraintInfo.eqToPriVarIndex(eqIdx);
613 assert(0 <= pvIdx && pvIdx < constraintInfo.size());
614 applyDirichletConstraint(dofIdx, values, eqIdx, pvIdx);
622 std::shared_ptr<const Problem> problem_;
625 std::shared_ptr<const GridDiscretization> gridDiscretization_;
628 std::shared_ptr<GridVariables> gridVariables_;
631 std::shared_ptr<const TimeLoop> timeLoop_;
637 bool isStationaryProblem_;
640 std::shared_ptr<JacobianMatrix> jacobian_;
641 std::shared_ptr<ResidualType> residual_;
644 bool enableMultithreading_ =
false;
645 std::deque<std::vector<ElementSeed>> elementSets_;
typename Dumux::Detail::NativeDuneVectorType< SolutionVector >::type ResidualType
Definition assembly/assembler.hh:97
void updateGridVariables(const SolutionVector &curSol)
Update the grid variables.
Definition assembly/assembler.hh:363
GetPropType< TypeTag, Properties::GridVariables > GridVariables
Definition assembly/assembler.hh:99
void assembleResidual(const SolutionVector &curSol)
compute the residuals using the internal residual
Definition assembly/assembler.hh:220
LocalResidual localResidual() const
Create a local residual object (used by the local assembler).
Definition assembly/assembler.hh:357
ResidualType & residual()
The residual vector (rhs).
Definition assembly/assembler.hh:327
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:159
GetPropType< TypeTag, Properties::Scalar > Scalar
Definition assembly/assembler.hh:94
void updateAfterGridAdaption()
Resizes jacobian and residual and recomputes colors.
Definition assembly/assembler.hh:287
const GridDiscretization & gridDiscretization() const
Definition assembly/assembler.hh:303
const SolutionVector & prevSol() const
Definition assembly/assembler.hh:331
std::size_t numDofs() const
Returns the number of degrees of freedom.
Definition assembly/assembler.hh:295
void assembleResidual(ResidualType &r, const SolutionVector &curSol) const
assemble a residual r
Definition assembly/assembler.hh:227
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:134
GetPropType< TypeTag, Properties::SolutionVector > SolutionVector
Definition assembly/assembler.hh:96
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:111
void setTimeLoop(std::shared_ptr< const TimeLoop > timeLoop)
Set time loop for instationary problems.
Definition assembly/assembler.hh:338
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:254
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:345
const GridView & gridView() const
The gridview.
Definition assembly/assembler.hh:311
GetPropType< TypeTag, Properties::Problem > Problem
Definition assembly/assembler.hh:104
void assembleJacobian(const SolutionVector &curSol)
Assembles only the global Jacobian of the residual.
Definition assembly/assembler.hh:192
JacobianMatrix & jacobian()
The jacobian matrix.
Definition assembly/assembler.hh:323
GridDisc GridDiscretization
Definition assembly/assembler.hh:101
bool isStationaryProblem() const
Whether we are assembling a stationary or instationary problem.
Definition assembly/assembler.hh:351
GridDisc GridGeometry
Definition assembly/assembler.hh:103
const GridVariables & gridVariables() const
The global grid variables.
Definition assembly/assembler.hh:319
void setLinearSystem()
The version without arguments uses the default constructor to create the jacobian and residual object...
Definition assembly/assembler.hh:274
GetPropType< TypeTag, Properties::JacobianMatrix > JacobianMatrix
Definition assembly/assembler.hh:95
const GridDiscretization & gridGeometry() const
support old interfaces
Definition assembly/assembler.hh:307
GridVariables & gridVariables()
Definition assembly/assembler.hh:315
void resetTimeStep(const SolutionVector &curSol)
Reset the gridVariables.
Definition assembly/assembler.hh:371
const Problem & problem() const
Definition assembly/assembler.hh:299
An assembler for Jacobian and residual contribution per element (CVFE methods).
Definition experimental/assembly/cvfelocalassembler.hh:327
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:420
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:28
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:139
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:31
Definition assembly/assembler.hh:44
constexpr bool hasGlobalConstraints()
Definition assembly/assembler.hh:66
decltype(std::declval< P >().constraints()) ProblemConstraintsDetector
helper struct detecting if problem has a constraints() function
Definition assembly/assembler.hh:63
typename LocalAssemblerChooser< typename GetPropType< TypeTag, Properties::GridGeometry >::DiscretizationMethod >::template type< TypeTag, Impl, diffMethod, isImplicit > LocalAssemblerChooser_t
Definition assembly/assembler.hh:57
Definition assembly/assembler.hh:44
bool supportsMultithreading(const GridView &gridView)
Definition gridcapabilities.hh:34
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:53
Definition assembly/assembler.hh:47
Traits specifying if a given discretization tag supports coloring.
Definition coloring.hh:296