13#ifndef DUMUX_EXPERIMENTAL_MULTISTAGE_ASSEMBLER_HH
14#define DUMUX_EXPERIMENTAL_MULTISTAGE_ASSEMBLER_HH
21#include <dune/common/exceptions.hh>
53template<
class TypeTag, DiffMethod diffMethod>
57 using GridView =
typename GridGeo::GridView;
59 using Element =
typename GridView::template Codim<0>::Entity;
60 using ElementSeed =
typename GridView::Grid::template Codim<0>::EntitySeed;
87 : timeSteppingMethod_(msMethod)
93 if (!timeSteppingMethod_->implicit())
94 DUNE_THROW(Dune::NotImplemented,
95 "MultiStageAssembler only supports implicit (DIRK-type) time-stepping schemes; "
96 "the underlying CVFELocalAssembler has no explicit-scheme specialization.");
103 maybeComputeColors_();
114 markConstrainedDofs_();
116 spatialOperatorEvaluations_.back() = 0.0;
117 temporalOperatorEvaluations_.back() = 0.0;
119 if (stageParams_->size() != spatialOperatorEvaluations_.size())
120 DUNE_THROW(Dune::InvalidStateException,
"Wrong number of residuals");
122 assemble_([&](
const Element& element)
124 LocalAssembler localAssembler(*
this, element, curSol);
125 localAssembler.assembleJacobianAndResidual(
126 *jacobian_, *residual_, *gridVariables_,
128 temporalOperatorEvaluations_.back(),
129 spatialOperatorEvaluations_.back(),
135 auto constantResidualComponent = (*residual_);
136 constantResidualComponent = 0.0;
137 for (std::size_t k = 0; k < stageParams_->size()-1; ++k)
139 if (!stageParams_->skipTemporal(k))
140 constantResidualComponent.axpy(stageParams_->temporalWeight(k), temporalOperatorEvaluations_[k]);
141 if (!stageParams_->skipSpatial(k))
142 constantResidualComponent.axpy(stageParams_->spatialWeight(k), spatialOperatorEvaluations_[k]);
146 for (std::size_t i = 0; i < constantResidualComponent.size(); ++i)
147 for (std::size_t ii = 0; ii < constantResidualComponent[i].size(); ++ii)
148 (*residual_)[i][ii] += constrainedDofs_[i][ii] > 0.5 ? 0.0 : constantResidualComponent[i][ii];
150 applyDirichletConstraints_(curSol);
159 markConstrainedDofs_();
161 if (stageParams_->size() != spatialOperatorEvaluations_.size())
162 DUNE_THROW(Dune::InvalidStateException,
"Wrong number of residuals");
164 assembleOperatorEvaluations_(curSol);
166 const auto k = stageParams_->size() - 1;
168 residual_->axpy(stageParams_->temporalWeight(k), temporalOperatorEvaluations_.back());
169 residual_->axpy(stageParams_->spatialWeight(k), spatialOperatorEvaluations_.back());
171 auto constantResidualComponent = (*residual_);
172 constantResidualComponent = 0.0;
173 for (std::size_t i = 0; i < k; ++i)
175 if (!stageParams_->skipTemporal(i))
176 constantResidualComponent.axpy(stageParams_->temporalWeight(i), temporalOperatorEvaluations_[i]);
177 if (!stageParams_->skipSpatial(i))
178 constantResidualComponent.axpy(stageParams_->spatialWeight(i), spatialOperatorEvaluations_[i]);
181 for (std::size_t i = 0; i < constantResidualComponent.size(); ++i)
182 for (std::size_t ii = 0; ii < constantResidualComponent[i].size(); ++ii)
183 (*residual_)[i][ii] += constrainedDofs_[i][ii] > 0.5 ? 0.0 : constantResidualComponent[i][ii];
185 applyDirichletResidual_(curSol);
194 jacobian_ = std::make_shared<JacobianMatrix>();
195 jacobian_->setBuildMode(JacobianMatrix::random);
196 residual_ = std::make_shared<ResidualType>();
198 setResidualSize_(*residual_);
199 setJacobianPattern_();
207 setResidualSize_(*residual_);
208 setJacobianPattern_();
209 maybeComputeColors_();
214 {
return gridGeometry_->numDofs(); }
218 {
return *problem_; }
222 {
return *gridGeometry_; }
226 {
return *gridGeometry_; }
234 {
return *gridVariables_; }
238 {
return *gridVariables_; }
242 {
return *jacobian_; }
246 {
return *residual_; }
250 {
return *prevSol_; }
258 {
return LocalResidual(problem_.get(),
nullptr); }
277 spatialOperatorEvaluations_.clear();
278 temporalOperatorEvaluations_.clear();
279 stageParams_.reset();
282 template<
class StageParamsArg>
285 stageParams_ = std::move(params);
286 const auto curStage = stageParams_->size() - 1;
292 setProblemTime_(*problem_, stageParams_->timeAtStage(0));
296 assert(spatialOperatorEvaluations_.size() >= 0);
297 if (spatialOperatorEvaluations_.size() == 0)
299 spatialOperatorEvaluations_.push_back(*residual_);
300 temporalOperatorEvaluations_.push_back(*residual_);
301 assembleOperatorEvaluations_(*prevSol_);
310 else if (spatialOperatorEvaluations_.size() > 0)
313 spatialOperatorEvaluations_.resize(1);
314 temporalOperatorEvaluations_.resize(1);
318 if (spatialOperatorEvaluations_.size() != curStage)
319 DUNE_THROW(Dune::InvalidStateException,
320 "Invalid state. Maybe you forgot to call clearStages()");
327 setProblemTime_(*problem_, stageParams_->timeAtStage(curStage-1));
328 assembleOperatorEvaluations_(x);
331 setProblemTime_(*problem_, stageParams_->timeAtStage(curStage));
336 spatialOperatorEvaluations_.push_back(*residual_);
337 temporalOperatorEvaluations_.push_back(*residual_);
345 {
return timeSteppingMethod_->implicit(); }
351 DUNE_THROW(Dune::InvalidStateException,
"No stage params set. Call prepareStage first.");
352 const auto k = stageParams_->size() - 1;
353 return {stageParams_->temporalWeight(k), stageParams_->spatialWeight(k)};
360 spatialOperatorEvaluations_.back() = 0.0;
361 temporalOperatorEvaluations_.back() = 0.0;
362 assemble_([&](
const Element& element)
364 LocalAssembler localAssembler(*
this, element, sol);
365 localAssembler.assembleCurrentResidual(temporalOperatorEvaluations_.back(),
366 spatialOperatorEvaluations_.back());
373 void setJacobianPattern_()
385 void maybeComputeColors_()
387 if (enableMultithreading_)
392 void resetResidual_()
396 residual_ = std::make_shared<ResidualType>();
397 setResidualSize_(*residual_);
400 setResidualSize_(constrainedDofs_);
403 constrainedDofs_ = 0.0;
407 void resetJacobian_()
411 jacobian_ = std::make_shared<JacobianMatrix>();
412 jacobian_->setBuildMode(JacobianMatrix::random);
413 setJacobianPattern_();
422 void markConstrainedDofs_()
426 for (
const auto& constraintData : problem_->constraints())
428 const auto& info = constraintData.constraintInfo();
429 const auto dofIdx = constraintData.dofIndex();
430 for (
int eqIdx = 0; eqIdx < info.size(); ++eqIdx)
431 if (info.isConstraintEquation(eqIdx))
432 constrainedDofs_[dofIdx][eqIdx] = 1.0;
442 for (
const auto& constraintData : problem_->constraints())
444 const auto& info = constraintData.constraintInfo();
445 const auto& values = constraintData.values();
446 const auto dofIdx = constraintData.dofIndex();
447 for (
int eqIdx = 0; eqIdx < info.size(); ++eqIdx)
449 if (info.isConstraintEquation(eqIdx))
451 const auto pvIdx = info.eqToPriVarIndex(eqIdx);
452 (*residual_)[dofIdx][eqIdx] = curSol[dofIdx][pvIdx] - values[pvIdx];
454 auto& row = (*jacobian_)[dofIdx];
455 for (
auto col = row.begin(); col != row.end(); ++col)
456 row[col.index()][eqIdx] = 0.0;
458 (*jacobian_)[dofIdx][dofIdx][eqIdx][pvIdx] = 1.0;
470 for (
const auto& constraintData : problem_->constraints())
472 const auto& info = constraintData.constraintInfo();
473 const auto& values = constraintData.values();
474 const auto dofIdx = constraintData.dofIndex();
475 for (
int eqIdx = 0; eqIdx < info.size(); ++eqIdx)
476 if (info.isConstraintEquation(eqIdx))
478 const auto pvIdx = info.eqToPriVarIndex(eqIdx);
479 (*residual_)[dofIdx][eqIdx] = curSol[dofIdx][pvIdx] - values[pvIdx];
490 template<
typename AssembleElementFunc>
491 void assemble_(AssembleElementFunc&& assembleElement)
const
494 bool succeeded =
false;
498 if (enableMultithreading_)
500 assert(elementSets_.size() > 0);
502 for (
const auto& elements : elementSets_)
506 const auto element = gridView().grid().entity(elements[i]);
507 assembleElement(element);
512 for (
const auto& element : elements(
gridView()))
513 assembleElement(element);
517 catch (NumericalProblem &e)
519 std::cout <<
"rank " <<
gridView().comm().rank()
520 <<
" caught an exception while assembling:" << e.what()
526 succeeded =
gridView().comm().min(succeeded);
529 DUNE_THROW(NumericalProblem,
"A process did not succeed in linearizing the system");
533 void setProblemTime_(
const P& p,
const Scalar t)
535 if constexpr (
requires { p.setTime(t); })
538 static_assert(!
requires (P& q) { q.setTime(
Scalar{}); },
539 "The multi-stage assembler sets the stage time through a const problem: setTime has to be const.");
542 std::shared_ptr<const Experimental::MultiStageMethod<Scalar>> timeSteppingMethod_;
543 std::vector<ResidualType> spatialOperatorEvaluations_;
544 std::vector<ResidualType> temporalOperatorEvaluations_;
546 std::shared_ptr<const StageParams> stageParams_;
549 std::shared_ptr<const Problem> problem_;
552 std::shared_ptr<const GridGeometry> gridGeometry_;
555 std::shared_ptr<GridVariables> gridVariables_;
561 std::shared_ptr<JacobianMatrix> jacobian_;
562 std::shared_ptr<ResidualType> residual_;
565 bool enableMultithreading_ =
false;
566 std::deque<std::vector<ElementSeed>> elementSets_;
A linear system assembler (residual and Jacobian) for general discretization schemes.
void updateGridVariables(const SolutionVector &cursol)
Update the grid variables.
Definition multistageassembler.hh:263
LocalResidual localResidual() const
Create a local residual object (used by the local assembler).
Definition multistageassembler.hh:257
void resetTimeStep(const SolutionVector &cursol)
Reset the gridVariables.
Definition multistageassembler.hh:269
const GridGeometry & gridDiscretization() const
The grid discretization.
Definition multistageassembler.hh:225
void updateAfterGridAdaption()
Resizes jacobian and residual and recomputes colors.
Definition multistageassembler.hh:205
GridGeo GridGeometry
Definition multistageassembler.hh:74
GetPropType< TypeTag, Properties::GridVariables > GridVariables
Definition multistageassembler.hh:72
GetPropType< TypeTag, Properties::Problem > Problem
Definition multistageassembler.hh:75
void assembleResidual(const SolutionVector &curSol)
Assembles the residual of the current stage for the given solution.
Definition multistageassembler.hh:156
ResidualType & residual()
The residual vector (rhs).
Definition multistageassembler.hh:245
bool isImplicit() const
Definition multistageassembler.hh:344
GetPropType< TypeTag, Properties::JacobianMatrix > JacobianMatrix
Definition multistageassembler.hh:68
bool isStationaryProblem() const
TODO get rid of this (called by Newton but shouldn't be necessary).
Definition multistageassembler.hh:341
const SolutionVector & prevSol() const
The solution of the previous time step.
Definition multistageassembler.hh:249
MultiStageAssembler(std::shared_ptr< const Problem > problem, std::shared_ptr< const GridGeometry > gridGeometry, std::shared_ptr< GridVariables > gridVariables, std::shared_ptr< const Experimental::MultiStageMethod< Scalar > > msMethod, const SolutionVector &prevSol)
The constructor for instationary problems.
Definition multistageassembler.hh:82
const GridView & gridView() const
The gridview.
Definition multistageassembler.hh:229
Experimental::MultiStageParams< Scalar > StageParams
Definition multistageassembler.hh:67
void prepareStage(SolutionVector &x, StageParamsArg params)
Definition multistageassembler.hh:283
const GridVariables & gridVariables() const
The global grid variables.
Definition multistageassembler.hh:237
void clearStages()
Definition multistageassembler.hh:275
std::pair< Scalar, Scalar > currentStageWeights() const
The temporal and spatial weight of the current stage.
Definition multistageassembler.hh:348
const Problem & problem() const
The problem.
Definition multistageassembler.hh:217
void setLinearSystem()
The version without arguments uses the default constructor to create the jacobian and residual object...
Definition multistageassembler.hh:192
void assembleJacobianAndResidual(const SolutionVector &curSol)
Assembles the global Jacobian of the residual and the residual for the current solution.
Definition multistageassembler.hh:110
GetPropType< TypeTag, Properties::Scalar > Scalar
Definition multistageassembler.hh:66
GetPropType< TypeTag, Properties::SolutionVector > SolutionVector
Definition multistageassembler.hh:69
GridVariables & gridVariables()
The global grid variables.
Definition multistageassembler.hh:233
JacobianMatrix & jacobian()
The jacobian matrix.
Definition multistageassembler.hh:241
typename Dumux::Detail::NativeDuneVectorType< SolutionVector >::type ResidualType
Definition multistageassembler.hh:70
const GridGeometry & gridGeometry() const
The global finite volume geometry.
Definition multistageassembler.hh:221
std::size_t numDofs() const
Returns the number of degrees of freedom.
Definition multistageassembler.hh:213
Abstract interface for one-step multi-stage method parameters in Shu/Osher form.
Definition multistagemethods.hh:75
Data object for the parameters of a given stage.
Definition multistagetimestepper.hh:31
Coloring schemes for shared-memory-parallel assembly.
Defines all properties used in Dumux.
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.
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: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.
Parameters for different multistage time stepping methods.
A time stepper performing a single time step of a transient simulation.
constexpr bool hasGlobalConstraints()
Definition assembly/assembler.hh:66
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:36
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).
typename NativeDuneVectorTypeImpl< V, Dune::Std::is_detected< Detail::DuneVectors::StateDetector, V >{} >::type type
Definition dunevectors.hh:57
Traits specifying if a given discretization tag supports coloring.
Definition coloring.hh:296
Type traits to be used with vector types.