3.5-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
cclocalassembler.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*****************************************************************************
4 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
25#ifndef DUMUX_CC_LOCAL_ASSEMBLER_HH
26#define DUMUX_CC_LOCAL_ASSEMBLER_HH
27
28#include <dune/common/reservedvector.hh>
29#include <dune/grid/common/gridenums.hh> // for GhostEntity
30#include <dune/istl/matrixindexset.hh>
31
44
45namespace Dumux {
46
56template<class TypeTag, class Assembler, class Implementation, bool implicit>
57class CCLocalAssemblerBase : public FVLocalAssemblerBase<TypeTag, Assembler, Implementation, implicit>
58{
64 using ElementVolumeVariables = typename GetPropType<TypeTag, Properties::GridVolumeVariables>::LocalView;
66
67public:
68
69 using ParentType::ParentType;
70
75 template <class PartialReassembler = DefaultPartialReassembler>
76 void assembleJacobianAndResidual(JacobianMatrix& jac, SolutionVector& res, GridVariables& gridVariables,
77 const PartialReassembler* partialReassembler)
78 {
79 this->asImp_().bindLocalViews();
80 const auto globalI = this->assembler().gridGeometry().elementMapper().index(this->element());
81 if (partialReassembler
82 && partialReassembler->elementColor(globalI) == EntityColor::green)
83 {
84 res[globalI] = this->asImp_().evalLocalResidual()[0]; // forward to the internal implementation
85 }
86 else
87 {
88 res[globalI] = this->asImp_().assembleJacobianAndResidualImpl(jac, gridVariables); // forward to the internal implementation
89 }
90 }
91
96 void assembleJacobian(JacobianMatrix& jac, GridVariables& gridVariables)
97 {
98 this->asImp_().bindLocalViews();
99 this->asImp_().assembleJacobianAndResidualImpl(jac, gridVariables); // forward to the internal implementation
100 }
101
105 void assembleResidual(SolutionVector& res)
106 {
107 this->asImp_().bindLocalViews();
108 const auto globalI = this->assembler().gridGeometry().elementMapper().index(this->element());
109 res[globalI] = this->asImp_().evalLocalResidual()[0]; // forward to the internal implementation
110
112 if constexpr (Problem::enableInternalDirichletConstraints())
113 {
114 const auto applyDirichlet = [&] (const auto& scvI,
115 const auto& dirichletValues,
116 const auto eqIdx,
117 const auto pvIdx)
118 {
119 res[scvI.dofIndex()][eqIdx] = this->curElemVolVars()[scvI].priVars()[pvIdx] - dirichletValues[pvIdx];
120 };
121
122 this->asImp_().enforceInternalDirichletConstraints(applyDirichlet);
123 }
124 }
125};
126
135template<class TypeTag, class Assembler, DiffMethod diffMethod = DiffMethod::numeric, bool implicit = true>
137
143template<class TypeTag, class Assembler>
144class CCLocalAssembler<TypeTag, Assembler, DiffMethod::numeric, /*implicit=*/true>
145: public CCLocalAssemblerBase<TypeTag, Assembler,
146 CCLocalAssembler<TypeTag, Assembler, DiffMethod::numeric, true>, true >
147{
152 using Element = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView::template Codim<0>::Entity;
154 using FVElementGeometry = typename GridGeometry::LocalView;
157 using Problem = typename GridVariables::GridVolumeVariables::Problem;
158
161
163 static constexpr int maxElementStencilSize = GridGeometry::maxElementStencilSize;
164 static constexpr bool enableGridFluxVarsCache = getPropValue<TypeTag, Properties::EnableGridFluxVariablesCache>();
165
166public:
167
169
176 NumEqVector assembleJacobianAndResidualImpl(JacobianMatrix& A, GridVariables& gridVariables)
177 {
179 // Calculate derivatives of all dofs in stencil with respect to the dofs in the element. In the //
180 // neighboring elements we do so by computing the derivatives of the fluxes which depend on the //
181 // actual element. In the actual element we evaluate the derivative of the entire residual. //
183
184 // get some aliases for convenience
185 const auto& element = this->element();
186 const auto& fvGeometry = this->fvGeometry();
187 const auto& gridGeometry = this->assembler().gridGeometry();
188 auto&& curElemVolVars = this->curElemVolVars();
189 auto&& elemFluxVarsCache = this->elemFluxVarsCache();
190
191 // get stencil informations
192 const auto globalI = gridGeometry.elementMapper().index(element);
193 const auto& connectivityMap = gridGeometry.connectivityMap();
194 const auto numNeighbors = connectivityMap[globalI].size();
195
196 // container to store the neighboring elements
197 Dune::ReservedVector<Element, maxElementStencilSize> neighborElements;
198 neighborElements.resize(numNeighbors);
199
200 // assemble the undeflected residual
202 Residuals origResiduals(numNeighbors + 1); origResiduals = 0.0;
203 origResiduals[0] = this->evalLocalResidual()[0];
204
205 // lambda for convenient evaluation of the fluxes across scvfs in the neighbors
206 // if the neighbor is a ghost we don't want to add anything to their residual
207 // so we return 0 and omit computing the flux
208 auto evalNeighborFlux = [&] (const auto& neighbor, const auto& scvf)
209 {
210 if (neighbor.partitionType() == Dune::GhostEntity)
211 return NumEqVector(0.0);
212 else
213 return this->localResidual().evalFlux(this->problem(),
214 neighbor,
215 this->fvGeometry(),
216 this->curElemVolVars(),
217 this->elemFluxVarsCache(), scvf);
218 };
219
220 // get the elements in which we need to evaluate the fluxes
221 // and calculate these in the undeflected state
222 unsigned int j = 1;
223 for (const auto& dataJ : connectivityMap[globalI])
224 {
225 neighborElements[j-1] = gridGeometry.element(dataJ.globalJ);
226 for (const auto scvfIdx : dataJ.scvfsJ)
227 origResiduals[j] += evalNeighborFlux(neighborElements[j-1], fvGeometry.scvf(scvfIdx));
228
229 ++j;
230 }
231
232 // reference to the element's scv (needed later) and corresponding vol vars
233 const auto& scv = fvGeometry.scv(globalI);
234 auto& curVolVars = ParentType::getVolVarAccess(gridVariables.curGridVolVars(), curElemVolVars, scv);
235
236 // save a copy of the original privars and vol vars in order
237 // to restore the original solution after deflection
238 const auto& curSol = this->curSol();
239 const auto origPriVars = curSol[globalI];
240 const auto origVolVars = curVolVars;
241
242 // element solution container to be deflected
243 auto elemSol = elementSolution(element, curSol, gridGeometry);
244
245 // derivatives in the neighbors with repect to the current elements
246 // in index 0 we save the derivative of the element residual with respect to it's own dofs
247 Residuals partialDerivs(numNeighbors + 1);
248
249 for (int pvIdx = 0; pvIdx < numEq; ++pvIdx)
250 {
251 partialDerivs = 0.0;
252
253 auto evalResiduals = [&](Scalar priVar)
254 {
255 Residuals partialDerivsTmp(numNeighbors + 1);
256 partialDerivsTmp = 0.0;
257 // update the volume variables and the flux var cache
258 elemSol[0][pvIdx] = priVar;
259 curVolVars.update(elemSol, this->problem(), element, scv);
260 elemFluxVarsCache.update(element, fvGeometry, curElemVolVars);
261 if (enableGridFluxVarsCache)
262 gridVariables.gridFluxVarsCache().updateElement(element, fvGeometry, curElemVolVars);
263
264 // calculate the residual with the deflected primary variables
265 partialDerivsTmp[0] = this->evalLocalResidual()[0];
266
267 // calculate the fluxes in the neighbors with the deflected primary variables
268 for (std::size_t k = 0; k < numNeighbors; ++k)
269 for (auto scvfIdx : connectivityMap[globalI][k].scvfsJ)
270 partialDerivsTmp[k+1] += evalNeighborFlux(neighborElements[k], fvGeometry.scvf(scvfIdx));
271
272 return partialDerivsTmp;
273 };
274
275 // derive the residuals numerically
276 static const NumericEpsilon<Scalar, numEq> eps_{this->problem().paramGroup()};
277 static const int numDiffMethod = getParamFromGroup<int>(this->problem().paramGroup(), "Assembly.NumericDifferenceMethod");
278 NumericDifferentiation::partialDerivative(evalResiduals, elemSol[0][pvIdx], partialDerivs, origResiduals,
279 eps_(elemSol[0][pvIdx], pvIdx), numDiffMethod);
280
281 // Correct derivative for ghost elements, i.e. set a 1 for the derivative w.r.t. the
282 // current primary variable and a 0 elsewhere. As we always solve for a delta of the
283 // solution with repect to the initial one, this results in a delta of 0 for ghosts.
284 if (this->elementIsGhost())
285 {
286 partialDerivs[0] = 0.0;
287 partialDerivs[0][pvIdx] = 1.0;
288 }
289
290 // restore the original state of the scv's volume variables
291 curVolVars = origVolVars;
292
293 // restore the current element solution
294 elemSol[0][pvIdx] = origPriVars[pvIdx];
295
296 // add the current partial derivatives to the global jacobian matrix
297 // no special treatment is needed if globalJ is a ghost because then derivatives have been assembled to 0 above
298 if constexpr (Problem::enableInternalDirichletConstraints())
299 {
300 // check if own element has internal Dirichlet constraint
301 const auto internalDirichletConstraintsOwnElement = this->problem().hasInternalDirichletConstraint(this->element(), scv);
302 const auto dirichletValues = this->problem().internalDirichlet(this->element(), scv);
303
304 for (int eqIdx = 0; eqIdx < numEq; ++eqIdx)
305 {
306 if (internalDirichletConstraintsOwnElement[eqIdx])
307 {
308 origResiduals[0][eqIdx] = origVolVars.priVars()[eqIdx] - dirichletValues[eqIdx];
309 A[globalI][globalI][eqIdx][pvIdx] = (eqIdx == pvIdx) ? 1.0 : 0.0;
310 }
311 else
312 A[globalI][globalI][eqIdx][pvIdx] += partialDerivs[0][eqIdx];
313 }
314
315 // off-diagonal entries
316 j = 1;
317 for (const auto& dataJ : connectivityMap[globalI])
318 {
319 const auto& neighborElement = neighborElements[j-1];
320 const auto& neighborScv = fvGeometry.scv(dataJ.globalJ);
321 const auto internalDirichletConstraintsNeighbor = this->problem().hasInternalDirichletConstraint(neighborElement, neighborScv);
322
323 for (int eqIdx = 0; eqIdx < numEq; ++eqIdx)
324 {
325 if (internalDirichletConstraintsNeighbor[eqIdx])
326 A[dataJ.globalJ][globalI][eqIdx][pvIdx] = 0.0;
327 else
328 A[dataJ.globalJ][globalI][eqIdx][pvIdx] += partialDerivs[j][eqIdx];
329 }
330
331 ++j;
332 }
333 }
334 else // no internal Dirichlet constraints specified
335 {
336 for (int eqIdx = 0; eqIdx < numEq; eqIdx++)
337 {
338 // the diagonal entries
339 A[globalI][globalI][eqIdx][pvIdx] += partialDerivs[0][eqIdx];
340
341 // off-diagonal entries
342 j = 1;
343 for (const auto& dataJ : connectivityMap[globalI])
344 A[dataJ.globalJ][globalI][eqIdx][pvIdx] += partialDerivs[j++][eqIdx];
345 }
346 }
347 }
348
349 // restore original state of the flux vars cache in case of global caching.
350 // This has to be done in order to guarantee that everything is in an undeflected
351 // state before the assembly of another element is called. In the case of local caching
352 // this is obsolete because the elemFluxVarsCache used here goes out of scope after this.
353 // We only have to do this for the last primary variable, for all others the flux var cache
354 // is updated with the correct element volume variables before residual evaluations
355 if (enableGridFluxVarsCache)
356 gridVariables.gridFluxVarsCache().updateElement(element, fvGeometry, curElemVolVars);
357
358 // return the original residual
359 return origResiduals[0];
360 }
361};
362
363
369template<class TypeTag, class Assembler>
370class CCLocalAssembler<TypeTag, Assembler, DiffMethod::numeric, /*implicit=*/false>
371: public CCLocalAssemblerBase<TypeTag, Assembler,
372 CCLocalAssembler<TypeTag, Assembler, DiffMethod::numeric, false>, false>
373{
378 using Element = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView::template Codim<0>::Entity;
381 using Problem = typename GridVariables::GridVolumeVariables::Problem;
382
384
385public:
387
394 NumEqVector assembleJacobianAndResidualImpl(JacobianMatrix& A, GridVariables& gridVariables)
395 {
396 if (this->assembler().isStationaryProblem())
397 DUNE_THROW(Dune::InvalidStateException, "Using explicit jacobian assembler with stationary local residual");
398
399 // assemble the undeflected residual
400 auto residual = this->evalLocalResidual()[0];
401 const auto storageResidual = this->evalLocalStorageResidual()[0];
402
404 // Calculate derivatives of all dofs in stencil with respect to the dofs in the element. In the //
405 // neighboring elements all derivatives are zero. For the assembled element only the storage //
406 // derivatives are non-zero. //
408
409 // get some aliases for convenience
410 const auto& element = this->element();
411 const auto& fvGeometry = this->fvGeometry();
412 const auto& gridGeometry = this->assembler().gridGeometry();
413 auto&& curElemVolVars = this->curElemVolVars();
414
415 // reference to the element's scv (needed later) and corresponding vol vars
416 const auto globalI = gridGeometry.elementMapper().index(element);
417 const auto& scv = fvGeometry.scv(globalI);
418 auto& curVolVars = ParentType::getVolVarAccess(gridVariables.curGridVolVars(), curElemVolVars, scv);
419
420 // save a copy of the original privars and vol vars in order
421 // to restore the original solution after deflection
422 const auto& curSol = this->curSol();
423 const auto origPriVars = curSol[globalI];
424 const auto origVolVars = curVolVars;
425
426 // element solution container to be deflected
427 auto elemSol = elementSolution(element, curSol, gridGeometry);
428
429 NumEqVector partialDeriv;
430
431 // derivatives in the neighbors with repect to the current elements
432 for (int pvIdx = 0; pvIdx < numEq; ++pvIdx)
433 {
434 // reset derivatives of element dof with respect to itself
435 partialDeriv = 0.0;
436
437 auto evalStorage = [&](Scalar priVar)
438 {
439 // update the volume variables and calculate
440 // the residual with the deflected primary variables
441 elemSol[0][pvIdx] = priVar;
442 curVolVars.update(elemSol, this->problem(), element, scv);
443 return this->evalLocalStorageResidual()[0];
444 };
445
446 // for non-ghosts compute the derivative numerically
447 if (!this->elementIsGhost())
448 {
449 static const NumericEpsilon<Scalar, numEq> eps_{this->problem().paramGroup()};
450 static const int numDiffMethod = getParamFromGroup<int>(this->problem().paramGroup(), "Assembly.NumericDifferenceMethod");
451 NumericDifferentiation::partialDerivative(evalStorage, elemSol[0][pvIdx], partialDeriv, storageResidual,
452 eps_(elemSol[0][pvIdx], pvIdx), numDiffMethod);
453 }
454
455 // for ghost elements we assemble a 1.0 where the primary variable and zero everywhere else
456 // as we always solve for a delta of the solution with repect to the initial solution this
457 // results in a delta of zero for ghosts
458 else partialDeriv[pvIdx] = 1.0;
459
460 // restore the original state of the scv's volume variables
461 curVolVars = origVolVars;
462
463 // restore the current element solution
464 elemSol[0][pvIdx] = origPriVars[pvIdx];
465
466 // add the current partial derivatives to the global jacobian matrix
467 // only diagonal entries for explicit jacobians
468 if constexpr (Problem::enableInternalDirichletConstraints())
469 {
470 // check if own element has internal Dirichlet constraint
471 const auto internalDirichletConstraints = this->problem().hasInternalDirichletConstraint(this->element(), scv);
472 const auto dirichletValues = this->problem().internalDirichlet(this->element(), scv);
473
474 for (int eqIdx = 0; eqIdx < numEq; ++eqIdx)
475 {
476 if (internalDirichletConstraints[eqIdx])
477 {
478 residual[eqIdx] = origVolVars.priVars()[eqIdx] - dirichletValues[eqIdx];
479 A[globalI][globalI][eqIdx][pvIdx] = (eqIdx == pvIdx) ? 1.0 : 0.0;
480 }
481 else
482 A[globalI][globalI][eqIdx][pvIdx] += partialDeriv[eqIdx];
483 }
484 }
485 else
486 {
487 for (int eqIdx = 0; eqIdx < numEq; eqIdx++)
488 A[globalI][globalI][eqIdx][pvIdx] += partialDeriv[eqIdx];
489 }
490 }
491
492 // return the original residual
493 return residual;
494 }
495};
496
502template<class TypeTag, class Assembler>
503class CCLocalAssembler<TypeTag, Assembler, DiffMethod::analytic, /*implicit=*/true>
504: public CCLocalAssemblerBase<TypeTag, Assembler,
505 CCLocalAssembler<TypeTag, Assembler, DiffMethod::analytic, true>, true>
506{
512 using Problem = typename GridVariables::GridVolumeVariables::Problem;
513
515
516public:
518
525 NumEqVector assembleJacobianAndResidualImpl(JacobianMatrix& A, const GridVariables& gridVariables)
526 {
527 // treat ghost separately, we always want zero update for ghosts
528 if (this->elementIsGhost())
529 {
530 const auto globalI = this->assembler().gridGeometry().elementMapper().index(this->element());
531 for (int pvIdx = 0; pvIdx < numEq; ++pvIdx)
532 A[globalI][globalI][pvIdx][pvIdx] = 1.0;
533
534 // return zero residual
535 return NumEqVector(0.0);
536 }
537
538 // assemble the undeflected residual
539 auto residual = this->evalLocalResidual()[0];
540
541 // get some aliases for convenience
542 const auto& problem = this->problem();
543 const auto& element = this->element();
544 const auto& fvGeometry = this->fvGeometry();
545 const auto& curElemVolVars = this->curElemVolVars();
546 const auto& elemFluxVarsCache = this->elemFluxVarsCache();
547
548 // get reference to the element's current vol vars
549 const auto globalI = this->assembler().gridGeometry().elementMapper().index(element);
550 const auto& scv = fvGeometry.scv(globalI);
551 const auto& volVars = curElemVolVars[scv];
552
553 // if the problem is instationary, add derivative of storage term
554 if (!this->assembler().isStationaryProblem())
555 this->localResidual().addStorageDerivatives(A[globalI][globalI], problem, element, fvGeometry, volVars, scv);
556
557 // add source term derivatives
558 this->localResidual().addSourceDerivatives(A[globalI][globalI], problem, element, fvGeometry, volVars, scv);
559
560 // add flux derivatives for each scvf
561 for (const auto& scvf : scvfs(fvGeometry))
562 {
563 // inner faces
564 if (!scvf.boundary())
565 this->localResidual().addFluxDerivatives(A[globalI], problem, element, fvGeometry, curElemVolVars, elemFluxVarsCache, scvf);
566
567 // boundary faces
568 else
569 {
570 const auto& bcTypes = problem.boundaryTypes(element, scvf);
571
572 // add Dirichlet boundary flux derivatives
573 if (bcTypes.hasDirichlet() && !bcTypes.hasNeumann())
574 this->localResidual().addCCDirichletFluxDerivatives(A[globalI], problem, element, fvGeometry, curElemVolVars, elemFluxVarsCache, scvf);
575
576 // add Robin ("solution dependent Neumann") boundary flux derivatives
577 else if (bcTypes.hasNeumann() && !bcTypes.hasDirichlet())
578 this->localResidual().addRobinFluxDerivatives(A[globalI], problem, element, fvGeometry, curElemVolVars, elemFluxVarsCache, scvf);
579
580 else
581 DUNE_THROW(Dune::NotImplemented, "Mixed boundary conditions. Use pure boundary conditions by converting Dirichlet BCs to Robin BCs");
582 }
583 }
584
585 if constexpr (Problem::enableInternalDirichletConstraints())
586 {
587 // check if own element has internal Dirichlet constraint
588 const auto internalDirichletConstraints = this->problem().hasInternalDirichletConstraint(this->element(), scv);
589 const auto dirichletValues = this->problem().internalDirichlet(this->element(), scv);
590
591 for (int pvIdx = 0; pvIdx < numEq; ++pvIdx)
592 {
593 for (int eqIdx = 0; eqIdx < numEq; ++eqIdx)
594 {
595 if (internalDirichletConstraints[eqIdx])
596 {
597 residual[eqIdx] = volVars.priVars()[eqIdx] - dirichletValues[eqIdx];
598 A[globalI][globalI][eqIdx][pvIdx] = (eqIdx == pvIdx) ? 1.0 : 0.0;
599
600 // inner faces
601 for (const auto& scvf : scvfs(fvGeometry))
602 if (!scvf.boundary())
603 A[globalI][fvGeometry.scv(scvf.outsideScvIdx()).dofIndex()][eqIdx][pvIdx] = 0.0;
604 }
605 }
606 }
607 }
608
609 // return element residual
610 return residual;
611 }
612};
613
619template<class TypeTag, class Assembler>
620class CCLocalAssembler<TypeTag, Assembler, DiffMethod::analytic, /*implicit=*/false>
621: public CCLocalAssemblerBase<TypeTag, Assembler,
622 CCLocalAssembler<TypeTag, Assembler, DiffMethod::analytic, false>, false>
623{
629 using Problem = typename GridVariables::GridVolumeVariables::Problem;
630
632
633public:
635
642 NumEqVector assembleJacobianAndResidualImpl(JacobianMatrix& A, const GridVariables& gridVariables)
643 {
644 // treat ghost separately, we always want zero update for ghosts
645 if (this->elementIsGhost())
646 {
647 const auto globalI = this->assembler().gridGeometry().elementMapper().index(this->element());
648 for (int pvIdx = 0; pvIdx < numEq; ++pvIdx)
649 A[globalI][globalI][pvIdx][pvIdx] = 1.0;
650
651 // return zero residual
652 return NumEqVector(0.0);
653 }
654
655 // assemble the undeflected residual
656 const auto residual = this->evalLocalResidual()[0];
657
658 // get reference to the element's current vol vars
659 const auto globalI = this->assembler().gridGeometry().elementMapper().index(this->element());
660 const auto& scv = this->fvGeometry().scv(globalI);
661 const auto& volVars = this->curElemVolVars()[scv];
662
663 // add hand-code derivative of storage term
664 this->localResidual().addStorageDerivatives(A[globalI][globalI], this->problem(), this->element(), this->fvGeometry(), volVars, scv);
665
666 if constexpr (Problem::enableInternalDirichletConstraints())
667 {
668 // check if own element has internal Dirichlet constraint
669 const auto internalDirichletConstraints = this->problem().hasInternalDirichletConstraint(this->element(), scv);
670 const auto dirichletValues = this->problem().internalDirichlet(this->element(), scv);
671
672 for (int pvIdx = 0; pvIdx < numEq; ++pvIdx)
673 {
674 for (int eqIdx = 0; eqIdx < numEq; ++eqIdx)
675 {
676 if (internalDirichletConstraints[eqIdx])
677 {
678 residual[eqIdx] = volVars.priVars()[eqIdx] - dirichletValues[eqIdx];
679 A[globalI][globalI][eqIdx][pvIdx] = (eqIdx == pvIdx) ? 1.0 : 0.0;
680 }
681 }
682 }
683 }
684
685 // return the original residual
686 return residual;
687 }
688};
689
690} // end namespace Dumux
691
692#endif
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.
A class for numeric differentiation.
A arithmetic block vector type based on DUNE's reserved vector.
A helper to deduce a vector with the same size as numbers of equations.
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
The flux stencil specialized for different discretization schemes.
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
typename NumEqVectorTraits< PrimaryVariables >::type NumEqVector
A vector with the same size as numbers of equations This is the default implementation and has to be ...
Definition: numeqvector.hh:46
Definition: adapt.hh:29
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property
Definition: propertysystem.hh:150
A base class for all local cell-centered assemblers.
Definition: cclocalassembler.hh:58
void assembleResidual(SolutionVector &res)
Assemble the residual only.
Definition: cclocalassembler.hh:105
void assembleJacobian(JacobianMatrix &jac, GridVariables &gridVariables)
Computes the derivatives with respect to the given element and adds them to the global matrix.
Definition: cclocalassembler.hh:96
void assembleJacobianAndResidual(JacobianMatrix &jac, SolutionVector &res, GridVariables &gridVariables, const PartialReassembler *partialReassembler)
Computes the derivatives with respect to the given element and adds them to the global matrix....
Definition: cclocalassembler.hh:76
An assembler for Jacobian and residual contribution per element (cell-centered methods)
Definition: cclocalassembler.hh:136
Cell-centered scheme local assembler using numeric differentiation and implicit time discretization.
Definition: cclocalassembler.hh:147
NumEqVector assembleJacobianAndResidualImpl(JacobianMatrix &A, GridVariables &gridVariables)
Computes the derivatives with respect to the given element and adds them to the global matrix.
Definition: cclocalassembler.hh:176
Cell-centered scheme local assembler using numeric differentiation and explicit time discretization.
Definition: cclocalassembler.hh:373
NumEqVector assembleJacobianAndResidualImpl(JacobianMatrix &A, GridVariables &gridVariables)
Computes the derivatives with respect to the given element and adds them to the global matrix.
Definition: cclocalassembler.hh:394
Cell-centered scheme local assembler using analytic (hand-coded) differentiation and implicit time di...
Definition: cclocalassembler.hh:506
NumEqVector assembleJacobianAndResidualImpl(JacobianMatrix &A, const GridVariables &gridVariables)
Computes the derivatives with respect to the given element and adds them to the global matrix.
Definition: cclocalassembler.hh:525
Cell-centered scheme local assembler using analytic (hand-coded) differentiation and explicit time di...
Definition: cclocalassembler.hh:623
NumEqVector assembleJacobianAndResidualImpl(JacobianMatrix &A, const GridVariables &gridVariables)
Computes the derivatives with respect to the given element and adds them to the global matrix.
Definition: cclocalassembler.hh:642
A base class for all local assemblers.
Definition: fvlocalassemblerbase.hh:48
ElementVolumeVariables & curElemVolVars()
The current element volume variables.
Definition: fvlocalassemblerbase.hh:265
Implementation & asImp_()
Definition: fvlocalassemblerbase.hh:309
const Assembler & assembler() const
The assembler.
Definition: fvlocalassemblerbase.hh:245
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 repect to a function parameter.
Definition: numericdifferentiation.hh:61
A arithmetic block vector type based on DUNE's reserved vector.
Definition: reservedblockvector.hh:38
The flux stencil specialized for different discretization schemes.
Definition: fluxstencil.hh:45
Declares all properties used in Dumux.
The local element solution class for cell-centered methods.