25#ifndef DUMUX_BOX_LOCAL_ASSEMBLER_HH
26#define DUMUX_BOX_LOCAL_ASSEMBLER_HH
28#include <dune/common/reservedvector.hh>
29#include <dune/istl/matrixindexset.hh>
30#include <dune/istl/bvector.hh>
42#include "volvardeflectionhelper_.hh"
55template<
class TypeTag,
class Assembler,
class Implementation,
bool implicit>
68 using ParentType::ParentType;
81 template <
class PartialReassembler = DefaultPartialReassembler>
85 this->
asImp_().bindLocalViews();
86 const auto eIdxGlobal = this->
assembler().gridGeometry().elementMapper().index(this->
element());
87 if (partialReassembler
90 const auto residual = this->
asImp_().evalLocalResidual();
91 for (
const auto& scv : scvs(this->
fvGeometry()))
92 res[scv.dofIndex()] += residual[scv.localDofIndex()];
96 const auto residual = this->
asImp_().assembleJacobianAndResidualImpl(jac, gridVariables, partialReassembler);
97 for (
const auto& scv : scvs(this->
fvGeometry()))
98 res[scv.dofIndex()] += residual[scv.localDofIndex()];
102 using GridGeometry =
typename GridVariables::GridGeometry;
103 using GridView =
typename GridGeometry::GridView;
104 static constexpr auto dim = GridView::dimension;
106 int numVerticesLocal = this->
element().subEntities(dim);
108 for (
int i = 0; i < numVerticesLocal; ++i) {
109 auto vertex = this->
element().template subEntity<dim>(i);
111 if (vertex.partitionType() == Dune::InteriorEntity ||
112 vertex.partitionType() == Dune::BorderEntity)
119 int vIdx = this->
assembler().gridGeometry().vertexMapper().index(vertex);
121 typedef typename JacobianMatrix::block_type
BlockType;
123 for (
int j = 0; j < BlockType::rows; ++j)
131 auto applyDirichlet = [&] (
const auto& scvI,
132 const auto& dirichletValues,
136 res[scvI.dofIndex()][eqIdx] = this->
curElemVolVars()[scvI].priVars()[pvIdx] - dirichletValues[pvIdx];
138 auto& row = jac[scvI.dofIndex()];
139 for (
auto col = row.begin(); col != row.end(); ++col)
140 row[col.index()][eqIdx] = 0.0;
142 jac[scvI.dofIndex()][scvI.dofIndex()][eqIdx][pvIdx] = 1.0;
145 if (this->
assembler().gridGeometry().dofOnPeriodicBoundary(scvI.dofIndex()))
147 const auto periodicDof = this->
assembler().gridGeometry().periodicallyMappedDof(scvI.dofIndex());
148 res[periodicDof][eqIdx] = this->
curElemVolVars()[scvI].priVars()[pvIdx] - dirichletValues[pvIdx];
149 const auto end = jac[periodicDof].end();
150 for (
auto it = jac[periodicDof].begin(); it != end; ++it)
151 (*it) = periodicDof != it.index() ? 0.0 : 1.0;
155 this->
asImp_().enforceDirichletConstraints(applyDirichlet);
164 this->
asImp_().bindLocalViews();
165 this->
asImp_().assembleJacobianAndResidualImpl(jac, gridVariables);
167 auto applyDirichlet = [&] (
const auto& scvI,
168 const auto& dirichletValues,
172 auto& row = jac[scvI.dofIndex()];
173 for (
auto col = row.begin(); col != row.end(); ++col)
174 row[col.index()][eqIdx] = 0.0;
176 jac[scvI.dofIndex()][scvI.dofIndex()][eqIdx][pvIdx] = 1.0;
179 this->
asImp_().enforceDirichletConstraints(applyDirichlet);
187 this->
asImp_().bindLocalViews();
190 for (
const auto& scv : scvs(this->
fvGeometry()))
191 res[scv.dofIndex()] += residual[scv.localDofIndex()];
193 auto applyDirichlet = [&] (
const auto& scvI,
194 const auto& dirichletValues,
198 res[scvI.dofIndex()][eqIdx] = this->
curElemVolVars()[scvI].priVars()[pvIdx] - dirichletValues[pvIdx];
201 this->
asImp_().enforceDirichletConstraints(applyDirichlet);
205 template<
typename ApplyFunction>
209 this->
asImp_().evalDirichletBoundaries(applyDirichlet);
211 this->
asImp_().enforceInternalDirichletConstraints(applyDirichlet);
217 template<
typename ApplyDirichletFunctionType >
224 for (
const auto& scvI : scvs(this->
fvGeometry()))
227 if (bcTypes.hasDirichlet())
229 const auto dirichletValues = this->
problem().dirichlet(this->
element(), scvI);
232 for (
int eqIdx = 0; eqIdx < numEq; ++eqIdx)
234 if (bcTypes.isDirichlet(eqIdx))
236 const auto pvIdx = bcTypes.eqToDirichletIndex(eqIdx);
237 assert(0 <= pvIdx && pvIdx < numEq);
238 applyDirichlet(scvI, dirichletValues, eqIdx, pvIdx);
256template<
class TypeTag,
class Assembler, DiffMethod diffMethod = DiffMethod::numeric,
bool implicit = true>
264template<
class TypeTag,
class Assembler>
267 BoxLocalAssembler<TypeTag, Assembler, DiffMethod::numeric, true>, true>
276 using ElementResidualVector =
typename LocalResidual::ElementResidualVector;
293 template <
class PartialReassembler = DefaultPartialReassembler>
298 const auto& element = this->element();
299 const auto& fvGeometry = this->fvGeometry();
300 const auto& curSol = this->curSol();
301 auto&& curElemVolVars = this->curElemVolVars();
304 const auto origResiduals = this->evalLocalResidual();
316 static const bool updateAllVolVars = getParamFromGroup<bool>(
317 this->problem().paramGroup(),
"Assembly.BoxVolVarsDependOnAllElementDofs",
false
321 auto elemSol =
elementSolution(element, curSol, fvGeometry.gridGeometry());
324 ElementResidualVector partialDerivs(fvGeometry.numScv());
326 Detail::VolVarsDeflectionHelper deflectionHelper(
327 [&] (
const auto& scv) -> VolumeVariables& {
328 return this->getVolVarAccess(gridVariables.curGridVolVars(), curElemVolVars, scv);
335 for (
auto&& scv : scvs(fvGeometry))
338 const auto dofIdx = scv.dofIndex();
339 deflectionHelper.setCurrent(scv);
342 for (
int pvIdx = 0; pvIdx < numEq; pvIdx++)
346 auto evalResiduals = [&](Scalar priVar)
349 elemSol[scv.localDofIndex()][pvIdx] = priVar;
350 deflectionHelper.deflect(elemSol, scv, this->problem());
351 return this->evalLocalResidual();
356 static const int numDiffMethod = getParamFromGroup<int>(this->problem().paramGroup(),
"Assembly.NumericDifferenceMethod");
358 eps_(elemSol[scv.localDofIndex()][pvIdx], pvIdx), numDiffMethod);
361 for (
auto&& scvJ : scvs(fvGeometry))
364 if (!partialReassembler
367 for (
int eqIdx = 0; eqIdx < numEq; eqIdx++)
373 A[scvJ.dofIndex()][dofIdx][eqIdx][pvIdx] += partialDerivs[scvJ.localDofIndex()][eqIdx];
379 deflectionHelper.restore(scv);
382 elemSol[scv.localDofIndex()][pvIdx] = curSol[scv.dofIndex()][pvIdx];
385 return origResiduals;
395template<
class TypeTag,
class Assembler>
398 BoxLocalAssembler<TypeTag, Assembler, DiffMethod::numeric, false>, false>
407 using ElementResidualVector =
typename LocalResidual::ElementResidualVector;
422 template <
class PartialReassembler = DefaultPartialReassembler>
426 if (partialReassembler)
427 DUNE_THROW(Dune::NotImplemented,
"partial reassembly for explicit time discretization");
430 const auto& element = this->element();
431 const auto& fvGeometry = this->fvGeometry();
432 const auto& curSol = this->curSol();
433 auto&& curElemVolVars = this->curElemVolVars();
436 const auto origResiduals = this->evalLocalResidual();
437 const auto origStorageResiduals = this->evalLocalStorageResidual();
448 auto elemSol =
elementSolution(element, curSol, fvGeometry.gridGeometry());
451 ElementResidualVector partialDerivs(fvGeometry.numScv());
454 for (
auto&& scv : scvs(fvGeometry))
457 const auto dofIdx = scv.dofIndex();
458 auto& curVolVars = this->getVolVarAccess(gridVariables.curGridVolVars(), curElemVolVars, scv);
459 const VolumeVariables origVolVars(curVolVars);
462 for (
int pvIdx = 0; pvIdx < numEq; pvIdx++)
466 auto evalStorage = [&](Scalar priVar)
469 elemSol[scv.localDofIndex()][pvIdx] = priVar;
470 curVolVars.update(elemSol, this->problem(), element, scv);
471 return this->evalLocalStorageResidual();
476 static const int numDiffMethod = getParamFromGroup<int>(this->problem().paramGroup(),
"Assembly.NumericDifferenceMethod");
478 eps_(elemSol[scv.localDofIndex()][pvIdx], pvIdx), numDiffMethod);
481 for (
int eqIdx = 0; eqIdx < numEq; eqIdx++)
487 A[dofIdx][dofIdx][eqIdx][pvIdx] += partialDerivs[scv.localDofIndex()][eqIdx];
491 curVolVars = origVolVars;
494 elemSol[scv.localDofIndex()][pvIdx] = curSol[scv.dofIndex()][pvIdx];
498 return origResiduals;
507template<
class TypeTag,
class Assembler>
510 BoxLocalAssembler<TypeTag, Assembler, DiffMethod::analytic, true>, true>
517 using ElementResidualVector =
typename LocalResidual::ElementResidualVector;
529 template <
class PartialReassembler = DefaultPartialReassembler>
533 if (partialReassembler)
534 DUNE_THROW(Dune::NotImplemented,
"partial reassembly for analytic differentiation");
537 const auto& element = this->element();
538 const auto& fvGeometry = this->fvGeometry();
539 const auto& problem = this->problem();
540 const auto& curElemVolVars = this->curElemVolVars();
541 const auto& elemFluxVarsCache = this->elemFluxVarsCache();
544 const auto origResiduals = this->evalLocalResidual();
555 for (
const auto& scv : scvs(fvGeometry))
558 const auto dofIdx = scv.dofIndex();
559 const auto& volVars = curElemVolVars[scv];
564 if (!this->assembler().isStationaryProblem())
565 this->localResidual().addStorageDerivatives(A[dofIdx][dofIdx],
574 this->localResidual().addSourceDerivatives(A[dofIdx][dofIdx],
583 for (
const auto& scvf : scvfs(fvGeometry))
585 if (!scvf.boundary())
588 this->localResidual().addFluxDerivatives(A,
601 const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx());
602 if (this->elemBcTypes().get(fvGeometry, insideScv).hasNeumann())
605 this->localResidual().addRobinFluxDerivatives(A[insideScv.dofIndex()],
616 return origResiduals;
626template<
class TypeTag,
class Assembler>
629 BoxLocalAssembler<TypeTag, Assembler, DiffMethod::analytic, false>, false>
636 using ElementResidualVector =
typename LocalResidual::ElementResidualVector;
648 template <
class PartialReassembler = DefaultPartialReassembler>
652 if (partialReassembler)
653 DUNE_THROW(Dune::NotImplemented,
"partial reassembly for explicit time discretization");
656 const auto& element = this->element();
657 const auto& fvGeometry = this->fvGeometry();
658 const auto& problem = this->problem();
659 const auto& curElemVolVars = this->curElemVolVars();
662 const auto origResiduals = this->evalLocalResidual();
673 for (
const auto& scv : scvs(fvGeometry))
676 const auto dofIdx = scv.dofIndex();
677 const auto& volVars = curElemVolVars[scv];
681 this->localResidual().addStorageDerivatives(A[dofIdx][dofIdx],
689 return origResiduals;
An enum class to define various differentiation methods available in order to compute the derivatives...
An enum class to define the colors of elements and vertices required for partial Jacobian reassembly.
An adapter class for local assemblers using numeric differentiation.
Detects which entries in the Jacobian have to be recomputed.
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
A class for numeric differentiation.
auto elementSolution(const Element &element, const SolutionVector &sol, const GridGeometry &gg) -> std::enable_if_t< GridGeometry::discMethod==DiscretizationMethods::box, BoxElementSolution< typename GridGeometry::LocalView, std::decay_t< decltype(std::declval< SolutionVector >()[0])> > >
Make an element solution for box schemes.
Definition: box/elementsolution.hh:118
DiffMethod
Differentiation methods in order to compute the derivatives of the residual i.e. the entries in the j...
Definition: diffmethod.hh:37
@ green
does not need to be reassembled
Adaption of the non-isothermal two-phase two-component flow model to problems with CO2.
Definition: adapt.hh:29
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition: propertysystem.hh:180
typename BlockTypeHelper< SolutionVector, Dune::IsNumber< SolutionVector >::value >::type BlockType
Definition: nonlinear/newtonsolver.hh:198
A base class for all local box assemblers.
Definition: boxlocalassembler.hh:57
void assembleJacobian(JacobianMatrix &jac, GridVariables &gridVariables)
Computes the derivatives with respect to the given element and adds them to the global matrix.
Definition: boxlocalassembler.hh:162
void evalDirichletBoundaries(ApplyDirichletFunctionType applyDirichlet)
Evaluates Dirichlet boundaries.
Definition: boxlocalassembler.hh:218
void enforceDirichletConstraints(const ApplyFunction &applyDirichlet)
Enforce Dirichlet constraints.
Definition: boxlocalassembler.hh:206
void bindLocalViews()
Definition: boxlocalassembler.hh:70
void assembleResidual(SolutionVector &res)
Assemble the residual only.
Definition: boxlocalassembler.hh:185
void assembleJacobianAndResidual(JacobianMatrix &jac, SolutionVector &res, GridVariables &gridVariables, const PartialReassembler *partialReassembler=nullptr)
Computes the derivatives with respect to the given element and adds them to the global matrix....
Definition: boxlocalassembler.hh:82
An assembler for Jacobian and residual contribution per element (box methods)
Definition: boxlocalassembler.hh:257
Box local assembler using numeric differentiation and implicit time discretization.
Definition: boxlocalassembler.hh:268
ElementResidualVector assembleJacobianAndResidualImpl(JacobianMatrix &A, GridVariables &gridVariables, const PartialReassembler *partialReassembler=nullptr)
Computes the derivatives with respect to the given element and adds them to the global matrix.
Definition: boxlocalassembler.hh:294
Box local assembler using numeric differentiation and explicit time discretization.
Definition: boxlocalassembler.hh:399
ElementResidualVector assembleJacobianAndResidualImpl(JacobianMatrix &A, GridVariables &gridVariables, const PartialReassembler *partialReassembler=nullptr)
Computes the derivatives with respect to the given element and adds them to the global matrix.
Definition: boxlocalassembler.hh:423
Box local assembler using analytic differentiation and implicit time discretization.
Definition: boxlocalassembler.hh:511
ElementResidualVector assembleJacobianAndResidualImpl(JacobianMatrix &A, GridVariables &gridVariables, const PartialReassembler *partialReassembler=nullptr)
Computes the derivatives with respect to the given element and adds them to the global matrix.
Definition: boxlocalassembler.hh:530
Box local assembler using analytic differentiation and explicit time discretization.
Definition: boxlocalassembler.hh:630
ElementResidualVector assembleJacobianAndResidualImpl(JacobianMatrix &A, GridVariables &gridVariables, const PartialReassembler *partialReassembler=nullptr)
Computes the derivatives with respect to the given element and adds them to the global matrix.
Definition: boxlocalassembler.hh:649
A base class for all local assemblers.
Definition: fvlocalassemblerbase.hh:48
void bindLocalViews()
Convenience function bind and prepare all relevant variables required for the evaluation of the local...
Definition: fvlocalassemblerbase.hh:185
ElementVolumeVariables & curElemVolVars()
The current element volume variables.
Definition: fvlocalassemblerbase.hh:265
ElementBoundaryTypes & elemBcTypes()
The element's boundary types.
Definition: fvlocalassemblerbase.hh:281
Implementation & asImp_()
Definition: fvlocalassemblerbase.hh:309
ElementResidualVector evalLocalResidual() const
Convenience function to evaluate the complete local residual for the current element....
Definition: fvlocalassemblerbase.hh:120
const Problem & problem() const
The problem.
Definition: fvlocalassemblerbase.hh:241
FVElementGeometry & fvGeometry()
The global finite volume geometry.
Definition: fvlocalassemblerbase.hh:261
const Assembler & assembler() const
The assembler.
Definition: fvlocalassemblerbase.hh:245
bool elementIsGhost() const
Returns if element is a ghost entity.
Definition: fvlocalassemblerbase.hh:253
const Element & element() const
The current element.
Definition: fvlocalassemblerbase.hh:249
A helper class for local assemblers using numeric differentiation to determine the epsilon.
Definition: numericepsilon.hh:41
detects which entries in the Jacobian have to be recomputed
Definition: partialreassembler.hh:432
static void partialDerivative(const Function &function, Scalar x0, FunctionEvalType &derivative, const FunctionEvalType &fx0, const int numericDifferenceMethod=1)
Computes the derivative of a function with respect to a function parameter.
Definition: numericdifferentiation.hh:61
Declares all properties used in Dumux.
The local element solution class for the box method.