25#ifndef DUMUX_FC_DIAMOND_LOCAL_ASSEMBLER_HH
26#define DUMUX_FC_DIAMOND_LOCAL_ASSEMBLER_HH
28#include <dune/grid/common/gridenums.hh>
40#include "volvardeflectionhelper_.hh"
48 template<
class... Args>
52template<
class X,
class Y>
53using Impl = std::conditional_t<!std::is_same_v<X, void>, X, Y>;
66template<
class TypeTag,
class Assembler,
class Implementation,
bool implicit>
80 using ParentType::ParentType;
92 template <
class PartialReassembler = DefaultPartialReassembler,
class CouplingFunction = Detail::NoOperator>
95 const CouplingFunction& maybeAssembleCouplingBlocks = CouplingFunction())
97 static_assert(!std::decay_t<
decltype(this->
asImp_().problem())>::enableInternalDirichletConstraints(),
"Internal Dirichlet constraints are currently not implemented for face-centered staggered models!");
99 this->
asImp_().bindLocalViews();
100 const auto& gridGeometry = this->
asImp_().problem().gridGeometry();
101 const auto eIdxGlobal = gridGeometry.elementMapper().index(this->
element());
102 if (partialReassembler
105 const auto residual = this->
asImp_().evalLocalResidual();
106 for (
const auto& scv : scvs(this->
fvGeometry()))
107 res[scv.dofIndex()] += residual[scv.localDofIndex()];
110 maybeAssembleCouplingBlocks(residual);
114 const auto residual = this->
asImp_().assembleJacobianAndResidualImpl(jac, gridVariables, partialReassembler);
115 for (
const auto& scv : scvs(this->
fvGeometry()))
116 res[scv.dofIndex()] += residual[scv.localDofIndex()];
119 maybeAssembleCouplingBlocks(residual);
123 const auto numLocalFaces = this->
element().subEntities(1);
124 for (
int i = 0; i < numLocalFaces; ++i)
127 const auto face = this->
element().template subEntity<1>(i);
128 if (face.partitionType() == Dune::InteriorEntity || face.partitionType() == Dune::BorderEntity)
132 const auto dofIndex = gridGeometry.dofMapper().index(face);
134 typedef typename JacobianMatrix::block_type
BlockType;
136 for (
int j = 0; j < BlockType::rows; ++j)
144 auto applyDirichlet = [&] (
const auto& scvI,
145 const auto& dirichletValues,
149 res[scvI.dofIndex()][eqIdx] = this->
curElemVolVars()[scvI].priVars()[pvIdx] - dirichletValues[pvIdx];
151 auto& row = jac[scvI.dofIndex()];
152 for (
auto col = row.begin(); col != row.end(); ++col)
153 row[col.index()][eqIdx] = 0.0;
155 jac[scvI.dofIndex()][scvI.dofIndex()][eqIdx][pvIdx] = 1.0;
169 this->
asImp_().enforceDirichletConstraints(applyDirichlet);
178 this->
asImp_().bindLocalViews();
179 this->
asImp_().assembleJacobianAndResidualImpl(jac, gridVariables);
181 auto applyDirichlet = [&] (
const auto& scvI,
182 const auto& dirichletValues,
186 auto& row = jac[scvI.dofIndex()];
187 for (
auto col = row.begin(); col != row.end(); ++col)
188 row[col.index()][eqIdx] = 0.0;
190 jac[scvI.dofIndex()][scvI.dofIndex()][eqIdx][pvIdx] = 1.0;
193 this->
asImp_().enforceDirichletConstraints(applyDirichlet);
201 this->
asImp_().bindLocalViews();
204 for (
const auto& scv : scvs(this->
fvGeometry()))
205 res[scv.dofIndex()] += residual[scv.localDofIndex()];
207 auto applyDirichlet = [&] (
const auto& scvI,
208 const auto& dirichletValues,
212 res[scvI.dofIndex()][eqIdx] = this->
curElemVolVars()[scvI].priVars()[pvIdx] - dirichletValues[pvIdx];
215 this->
asImp_().enforceDirichletConstraints(applyDirichlet);
221 template<
typename ApplyFunction>
225 this->
asImp_().evalDirichletBoundaries(applyDirichlet);
227 this->
asImp_().enforceInternalDirichletConstraints(applyDirichlet);
233 template<
typename ApplyDirichletFunctionType >
240 for (
const auto& scvf : scvfs(this->
fvGeometry()))
245 if (bcTypes.hasDirichlet())
247 const PrimaryVariables dirichletValues(this->
asImp_().
problem().dirichlet(this->
element(), scvf));
248 const auto& scv = this->
fvGeometry().scv(scvf.insideScvIdx());
251 for (
int eqIdx = 0; eqIdx < numEq; ++eqIdx)
253 if (bcTypes.isDirichlet(eqIdx))
255 const auto pvIdx = bcTypes.eqToDirichletIndex(eqIdx);
256 assert(0 <= pvIdx && pvIdx < numEq);
257 applyDirichlet(scv, dirichletValues, eqIdx, pvIdx);
270 template<
class... Args>
277 template<
class... Args>
289template<
class TypeTag,
class Assembler, DiffMethod diffMethod = DiffMethod::numeric,
bool implicit = true,
class Implementation =
void>
297template<
class TypeTag,
class Assembler,
class Implementation>
300 Detail::Impl<Implementation, FaceCenteredDiamondLocalAssembler<TypeTag, Assembler, DiffMethod::numeric, true, Implementation>>, true>
307 using FVElementGeometry =
typename GridGeometry::LocalView;
308 using SubControlVolume =
typename FVElementGeometry::SubControlVolume;
309 using SubControlVolumeFace =
typename FVElementGeometry::SubControlVolumeFace;
329 template <
class PartialReassembler = DefaultPartialReassembler>
334 const auto& problem = this->asImp_().problem();
335 const auto& element = this->element();
336 const auto& fvGeometry = this->fvGeometry();
337 const auto& curSol = this->asImp_().curSol();
339 auto&& curElemVolVars = this->curElemVolVars();
342 const auto origResiduals = this->evalLocalResidual();
350 static const bool updateAllVolVars = getParamFromGroup<bool>(
351 problem.paramGroup(),
"Assembly.FCDiamondVolVarsDependOnAllElementDofs",
false
355 auto elemSol =
elementSolution(element, curSol, fvGeometry.gridGeometry());
358 const auto numElementResiduals = fvGeometry.numScv();
363 Detail::VolVarsDeflectionHelper deflectionHelper(
364 [&] (
const auto& scv) -> VolumeVariables& {
365 return this->getVolVarAccess(gridVariables.curGridVolVars(), curElemVolVars, scv);
372 for (
const auto& scv : scvs(fvGeometry))
375 const auto dofIdx = scv.dofIndex();
376 deflectionHelper.setCurrent(scv);
379 for (
int pvIdx = 0; pvIdx < numEq; pvIdx++)
383 auto evalResiduals = [&](Scalar priVar)
386 elemSol[scv.localDofIndex()][pvIdx] = priVar;
387 deflectionHelper.deflect(elemSol, scv, problem);
388 this->asImp_().maybeUpdateCouplingContext(scv, elemSol, pvIdx);
389 return this->evalLocalResidual();
394 static const int numDiffMethod = getParamFromGroup<int>(problem.paramGroup(),
"Assembly.NumericDifferenceMethod");
396 eps_(elemSol[scv.localDofIndex()][pvIdx], pvIdx), numDiffMethod);
399 for (
const auto& scvJ : scvs(fvGeometry))
402 for (
int eqIdx = 0; eqIdx < numEq; eqIdx++)
408 A[scvJ.dofIndex()][dofIdx][eqIdx][pvIdx] += partialDerivs[scvJ.localDofIndex()][eqIdx];
413 deflectionHelper.restore(scv);
416 elemSol[scv.localDofIndex()][pvIdx] = curSol[scv.dofIndex()][pvIdx];
417 this->asImp_().maybeUpdateCouplingContext(scv, elemSol, pvIdx);
421 return origResiduals;
431template<
class TypeTag,
class Assembler>
434 FaceCenteredDiamondLocalAssembler<TypeTag, Assembler, DiffMethod::numeric, false>, false>
443 using ElementResidualVector =
typename LocalResidual::ElementResidualVector;
457 template <
class PartialReassembler = DefaultPartialReassembler>
461 if (partialReassembler)
462 DUNE_THROW(Dune::NotImplemented,
"partial reassembly for explicit time discretization");
465 const auto& problem = this->asImp_().problem();
466 const auto& element = this->element();
467 const auto& fvGeometry = this->fvGeometry();
468 const auto& curSol = this->asImp_().curSol();
469 auto&& curElemVolVars = this->curElemVolVars();
472 const auto origResiduals = this->evalLocalResidual();
473 const auto origStorageResiduals = this->evalLocalStorageResidual();
484 auto elemSol =
elementSolution(element, curSol, fvGeometry.gridGeometry());
487 ElementResidualVector partialDerivs(fvGeometry.numScv());
490 for (
auto&& scv : scvs(fvGeometry))
493 const auto dofIdx = scv.dofIndex();
494 auto& curVolVars = this->getVolVarAccess(gridVariables.curGridVolVars(), curElemVolVars, scv);
495 const VolumeVariables origVolVars(curVolVars);
498 for (
int pvIdx = 0; pvIdx < numEq; pvIdx++)
502 auto evalStorage = [&](Scalar priVar)
505 elemSol[scv.localDofIndex()][pvIdx] = priVar;
506 curVolVars.update(elemSol, problem, element, scv);
507 return this->evalLocalStorageResidual();
512 static const int numDiffMethod = getParamFromGroup<int>(problem.paramGroup(),
"Assembly.NumericDifferenceMethod");
514 eps_(elemSol[scv.localDofIndex()][pvIdx], pvIdx), numDiffMethod);
517 for (
int eqIdx = 0; eqIdx < numEq; eqIdx++)
523 A[dofIdx][dofIdx][eqIdx][pvIdx] += partialDerivs[scv.localDofIndex()][eqIdx];
527 curVolVars = origVolVars;
530 elemSol[scv.localDofIndex()][pvIdx] = curSol[scv.dofIndex()][pvIdx];
534 return origResiduals;
543template<
class TypeTag,
class Assembler>
546 FaceCenteredDiamondLocalAssembler<TypeTag, Assembler, DiffMethod::analytic, true>, true>
553 using ElementResidualVector =
typename LocalResidual::ElementResidualVector;
567 template <
class PartialReassembler = DefaultPartialReassembler>
571 if (partialReassembler)
572 DUNE_THROW(Dune::NotImplemented,
"partial reassembly for analytic differentiation");
575 const auto& element = this->element();
576 const auto& fvGeometry = this->fvGeometry();
577 const auto& problem = this->asImp_().problem();
578 const auto& curElemVolVars = this->curElemVolVars();
579 const auto& elemFluxVarsCache = this->elemFluxVarsCache();
582 const auto origResiduals = this->evalLocalResidual();
593 for (
const auto& scv : scvs(fvGeometry))
596 const auto dofIdx = scv.dofIndex();
597 const auto& volVars = curElemVolVars[scv];
602 if (!this->assembler().isStationaryProblem())
603 this->localResidual().addStorageDerivatives(A[dofIdx][dofIdx],
612 this->localResidual().addSourceDerivatives(A[dofIdx][dofIdx],
621 for (
const auto& scvf : scvfs(fvGeometry))
623 if (!scvf.boundary())
626 this->localResidual().addFluxDerivatives(A,
639 const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx());
640 if (this->elemBcTypes().get(fvGeometry, insideScv).hasNeumann())
643 this->localResidual().addRobinFluxDerivatives(A[insideScv.dofIndex()],
654 return origResiduals;
663template<
class TypeTag,
class Assembler>
666 FaceCenteredDiamondLocalAssembler<TypeTag, Assembler, DiffMethod::analytic, false>, false>
673 using ElementResidualVector =
typename LocalResidual::ElementResidualVector;
687 template <
class PartialReassembler = DefaultPartialReassembler>
691 if (partialReassembler)
692 DUNE_THROW(Dune::NotImplemented,
"partial reassembly for explicit time discretization");
695 const auto& element = this->element();
696 const auto& fvGeometry = this->fvGeometry();
697 const auto& problem = this->asImp_().problem();
698 const auto& curElemVolVars = this->curElemVolVars();
701 const auto origResiduals = this->evalLocalResidual();
712 for (
const auto& scv : scvs(fvGeometry))
715 const auto dofIdx = scv.dofIndex();
716 const auto& volVars = curElemVolVars[scv];
720 this->localResidual().addStorageDerivatives(A[dofIdx][dofIdx],
728 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
Definition: fcdiamondlocalassembler.hh:47
constexpr void operator()(Args &&...) const
Definition: fcdiamondlocalassembler.hh:49
A base class for all local face-centered assemblers.
Definition: fcdiamondlocalassembler.hh:68
void maybeEvalAdditionalDomainDerivatives(Args &&...)
Update the additional domain derivatives for coupled models.
Definition: fcdiamondlocalassembler.hh:278
void maybeUpdateCouplingContext(Args &&...)
Update the coupling context for coupled models.
Definition: fcdiamondlocalassembler.hh:271
void bindLocalViews()
Definition: fcdiamondlocalassembler.hh:82
void enforceDirichletConstraints(const ApplyFunction &applyDirichlet)
Enforce Dirichlet constraints.
Definition: fcdiamondlocalassembler.hh:222
void evalDirichletBoundaries(ApplyDirichletFunctionType applyDirichlet)
Evaluates Dirichlet boundaries.
Definition: fcdiamondlocalassembler.hh:234
void assembleJacobian(JacobianMatrix &jac, GridVariables &gridVariables)
Computes the derivatives with respect to the given element and adds them to the global matrix.
Definition: fcdiamondlocalassembler.hh:176
void assembleJacobianAndResidual(JacobianMatrix &jac, SolutionVector &res, GridVariables &gridVariables, const PartialReassembler *partialReassembler, const CouplingFunction &maybeAssembleCouplingBlocks=CouplingFunction())
Computes the derivatives with respect to the given element and adds them to the global matrix....
Definition: fcdiamondlocalassembler.hh:93
void assembleResidual(SolutionVector &res)
Assemble the residual only.
Definition: fcdiamondlocalassembler.hh:199
An assembler for Jacobian and residual contribution per element (Face-centered methods)
Definition: fcdiamondlocalassembler.hh:290
Face-centered scheme local assembler using numeric differentiation and implicit time discretization.
Definition: fcdiamondlocalassembler.hh:301
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: fcdiamondlocalassembler.hh:330
GetPropType< TypeTag, Properties::LocalResidual > LocalResidual
Definition: fcdiamondlocalassembler.hh:319
typename LocalResidual::ElementResidualVector ElementResidualVector
Definition: fcdiamondlocalassembler.hh:320
TODO docme.
Definition: fcdiamondlocalassembler.hh:435
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: fcdiamondlocalassembler.hh:458
TODO docme.
Definition: fcdiamondlocalassembler.hh:547
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: fcdiamondlocalassembler.hh:568
TODO docme.
Definition: fcdiamondlocalassembler.hh:667
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: fcdiamondlocalassembler.hh:688
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
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
EntityColor elementColor(size_t idx) const
Definition: partialreassembler.hh:503
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.