Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
dumux
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
dumux-repositories
dumux
Commits
94218714
Commit
94218714
authored
9 years ago
by
Dennis Gläser
Committed by
Timo Koch
8 years ago
Browse files
Options
Downloads
Patches
Plain Diff
[CCTpfa] Add a local residual for the CCTpfa models
parent
686e7f54
No related branches found
Branches containing commit
No related tags found
Tags containing commit
Loading
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
dumux/implicit/cellcentered/tpfa/localresidual.hh
+294
-0
294 additions, 0 deletions
dumux/implicit/cellcentered/tpfa/localresidual.hh
with
294 additions
and
0 deletions
dumux/implicit/cellcentered/tpfa/localresidual.hh
0 → 100644
+
294
−
0
View file @
94218714
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*****************************************************************************
* See the file COPYING for full copying permissions. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*****************************************************************************/
/*!
* \file
* \brief Calculates the residual of models based on the box scheme element-wise.
*/
#ifndef DUMUX_CC_TPFA_LOCAL_RESIDUAL_HH
#define DUMUX_CC_TPFA_LOCAL_RESIDUAL_HH
#include
<dune/istl/matrix.hh>
#include
<dumux/common/valgrind.hh>
#include
<dumux/implicit/localresidual.hh>
#include
"properties.hh"
namespace
Dumux
{
/*!
* \ingroup CCModel
* \ingroup CCLocalResidual
* \brief Element-wise calculation of the residual for models
* based on the fully implicit cell-centered scheme.
*
* \todo Please doc me more!
*/
template
<
class
TypeTag
>
class
CCTpfaLocalResidual
:
public
ImplicitLocalResidual
<
TypeTag
>
{
typedef
ImplicitLocalResidual
<
TypeTag
>
ParentType
;
friend
class
ImplicitLocalResidual
<
TypeTag
>
;
typedef
typename
GET_PROP_TYPE
(
TypeTag
,
GridView
)
GridView
;
enum
{
numEq
=
GET_PROP_VALUE
(
TypeTag
,
NumEq
)
};
typedef
typename
GridView
::
template
Codim
<
0
>
::
Entity
Element
;
typedef
typename
GET_PROP_TYPE
(
TypeTag
,
PrimaryVariables
)
PrimaryVariables
;
typedef
typename
GET_PROP_TYPE
(
TypeTag
,
BoundaryTypes
)
BoundaryTypes
;
typedef
typename
GET_PROP_TYPE
(
TypeTag
,
FVElementGeometry
)
FVElementGeometry
;
typedef
typename
FVElementGeometry
::
SubControlVolumeFace
SCVFace
;
// copying the local residual class is not a good idea
CCTpfaLocalResidual
(
const
CCTpfaLocalResidual
&
);
public
:
CCTpfaLocalResidual
()
:
ParentType
()
{
}
protected
:
void
computeFlux_
(
PrimaryVariables
&
flux
,
SubControlVolumeFace
&
scvFace
)
{
if
(
!
scvFace
.
boundary
()
/*TODO: || GET_PROP_VALUE(TypeTag, BoundaryReconstruction)*/
)
{
asImp_
().
computeFlux
(
flux
,
scvFace
);
}
else
evalBoundary_
(
flux
,
scvFace
);
}
void
evalBoundary_
(
PrimaryVariables
&
flux
,
SubControlVolumeFace
&
scvFace
)
{
evalBoundaryFluxes_
(
flux
,
scvFace
);
// additionally treat mixed D/N conditions in a strong sense
if
(
bcTypes_
().
hasDirichlet
())
asImp_
().
evalDirichlet_
();
}
/*!
* \brief Add all fluxes resulting from Neumann, outflow and pure Dirichlet
* boundary conditions to the local residual.
*/
void
evalBoundaryFluxes_
(
PrimaryVariables
&
flux
,
SubControlVolumeFace
&
scvFace
)
{
BoundaryTypes
bcTypes
=
this
->
problem_
().
boundaryTypes
(
scvFace
);
// evaluate the Neumann conditions at the boundary face
if
(
bcTypes
.
hasNeumann
())
evalNeumannSegment_
(
flux
,
scvFace
,
bcTypes
);
// TODO: evaluate the outflow conditions at the boundary face
//if (bcTypes.hasOutflow())
// evalOutflowSegment_(&intersection, bcTypes);
// evaluate the pure Dirichlet conditions at the boundary face
if
(
bcTypes
.
hasDirichlet
()
&&
!
bcTypes
.
hasNeumann
())
evalDirichletSegment_
(
&
intersection
,
bcTypes
);
}
/*!
* \brief Evaluate Dirichlet conditions on faces that have mixed
* Dirichlet/Neumann boundary conditions.
*/
void
evalDirichlet_
()
{
for
(
const
auto
&
intersection
:
intersections
(
this
->
gridView_
(),
this
->
element_
()))
{
// handle only faces on the boundary
if
(
!
intersection
.
boundary
())
continue
;
BoundaryTypes
bcTypes
;
this
->
problem_
().
boundaryTypes
(
bcTypes
,
intersection
);
if
(
bcTypes
.
hasDirichlet
()
&&
bcTypes
.
hasNeumann
())
this
->
asImp_
().
evalDirichletSegmentMixed_
(
&
intersection
,
bcTypes
);
}
}
/*!
* \brief Add Neumann boundary conditions for a single scv face
*/
void
evalNeumannSegment_
(
PrimaryVariables
&
flux
,
const
SubControlVolumeFace
&
scvFace
,
const
BoundaryTypes
&
bcTypes
)
{
// temporary vector to store the neumann boundary fluxes
PrimaryVariables
values
;
Valgrind
::
SetUndefined
(
values
);
values
=
this
->
problem_
().
neumann
(
scvFace
);
// multiply neumann fluxes with the area and the extrusion factor
auto
&
scv
=
this
->
problem_
().
model
().
fvGeometries
().
subControlVolume
(
scvFace
.
insideScvIdx
())
values
*=
scvFace
.
area
()
*
problem_
().
model
().
curVolVars
(
scv
).
extrusionFactor
();
// add fluxes to the residual
Valgrind
::
CheckDefined
(
values
);
for
(
int
eqIdx
=
0
;
eqIdx
<
numEq
;
++
eqIdx
)
if
(
bcTypes
.
isNeumann
(
eqIdx
))
this
->
residual_
[
0
][
eqIdx
]
+=
values
[
eqIdx
];
}
/*!
* \brief Add outflow boundary conditions for a single intersection
*/
template
<
class
IntersectionIterator
>
void
evalOutflowSegment_
(
const
IntersectionIterator
&
isIt
,
const
BoundaryTypes
&
bcTypes
)
{
if
(
this
->
element_
().
geometry
().
type
().
isCube
()
==
false
)
DUNE_THROW
(
Dune
::
InvalidStateException
,
"for cell-centered models, outflow BCs only work for cubes."
);
// store pointer to the current FVElementGeometry
const
FVElementGeometry
*
oldFVGeometryPtr
=
this
->
fvElemGeomPtr_
;
// copy the current FVElementGeometry to a local variable
// and set the pointer to this local variable
FVElementGeometry
fvGeometry
=
this
->
fvGeometry_
();
this
->
fvElemGeomPtr_
=
&
fvGeometry
;
// get the index of the boundary face
unsigned
bfIdx
=
isIt
->
indexInInside
();
unsigned
oppositeIdx
=
bfIdx
^
1
;
// manipulate the corresponding subcontrolvolume face
SCVFace
&
boundaryFace
=
fvGeometry
.
boundaryFace
[
bfIdx
];
// set the second flux approximation index for the boundary face
for
(
int
nIdx
=
0
;
nIdx
<
fvGeometry
.
numNeighbors
-
1
;
nIdx
++
)
{
// check whether the two faces are opposite of each other
if
(
fvGeometry
.
subContVolFace
[
nIdx
].
fIdx
==
oppositeIdx
)
{
boundaryFace
.
j
=
nIdx
+
1
;
break
;
}
}
boundaryFace
.
fapIndices
[
1
]
=
boundaryFace
.
j
;
boundaryFace
.
grad
[
0
]
*=
-
0.5
;
boundaryFace
.
grad
[
1
]
*=
-
0.5
;
// temporary vector to store the outflow boundary fluxes
PrimaryVariables
values
;
Valgrind
::
SetUndefined
(
values
);
this
->
asImp_
().
computeFlux
(
values
,
bfIdx
,
true
);
values
*=
this
->
curVolVars_
(
0
).
extrusionFactor
();
// add fluxes to the residual
Valgrind
::
CheckDefined
(
values
);
for
(
int
eqIdx
=
0
;
eqIdx
<
numEq
;
++
eqIdx
)
{
if
(
bcTypes
.
isOutflow
(
eqIdx
))
this
->
residual_
[
0
][
eqIdx
]
+=
values
[
eqIdx
];
}
// restore the pointer to the FVElementGeometry
this
->
fvElemGeomPtr_
=
oldFVGeometryPtr
;
}
/*!
* \brief Treat Dirichlet boundary conditions in a weak sense for a single
* intersection that only has Dirichlet boundary conditions
*/
template
<
class
IntersectionIterator
>
void
evalDirichletSegment_
(
const
IntersectionIterator
&
isIt
,
const
BoundaryTypes
&
bcTypes
)
{
// temporary vector to store the Dirichlet boundary fluxes
PrimaryVariables
values
;
Valgrind
::
SetUndefined
(
values
);
unsigned
bfIdx
=
isIt
->
indexInInside
();
this
->
asImp_
().
computeFlux
(
values
,
bfIdx
,
true
);
values
*=
this
->
curVolVars_
(
0
).
extrusionFactor
();
// add fluxes to the residual
Valgrind
::
CheckDefined
(
values
);
for
(
int
eqIdx
=
0
;
eqIdx
<
numEq
;
++
eqIdx
)
{
if
(
bcTypes
.
isDirichlet
(
eqIdx
))
this
->
residual_
[
0
][
eqIdx
]
+=
values
[
eqIdx
];
}
}
/*!
* \brief Treat Dirichlet boundary conditions in a strong sense for a
* single intersection that has mixed D/N boundary conditions
*/
template
<
class
IntersectionIterator
>
void
evalDirichletSegmentMixed_
(
const
IntersectionIterator
&
isIt
,
const
BoundaryTypes
&
bcTypes
)
{
// temporary vector to store the Dirichlet boundary fluxes
PrimaryVariables
values
;
Valgrind
::
SetUndefined
(
values
);
this
->
problem_
().
dirichlet
(
values
,
*
isIt
);
Valgrind
::
CheckDefined
(
values
);
// set Dirichlet conditions in a strong sense
for
(
int
eqIdx
=
0
;
eqIdx
<
numEq
;
++
eqIdx
)
{
if
(
bcTypes
.
isDirichlet
(
eqIdx
))
{
int
pvIdx
=
bcTypes
.
eqToDirichletIndex
(
eqIdx
);
this
->
residual_
[
0
][
eqIdx
]
=
this
->
curPriVar_
(
0
,
pvIdx
)
-
values
[
pvIdx
];
}
}
}
/*!
* \brief Add the flux terms to the local residual of the current element
*/
void
evalFluxes_
()
{
// calculate the mass flux over the faces and subtract
// it from the local rates
int
fIdx
=
-
1
;
for
(
const
auto
&
intersection
:
intersections
(
this
->
gridView_
(),
this
->
element_
()))
{
if
(
!
intersection
.
neighbor
())
continue
;
fIdx
++
;
PrimaryVariables
flux
;
Valgrind
::
SetUndefined
(
flux
);
this
->
asImp_
().
computeFlux
(
flux
,
fIdx
);
Valgrind
::
CheckDefined
(
flux
);
flux
*=
this
->
curVolVars_
(
0
).
extrusionFactor
();
this
->
residual_
[
0
]
+=
flux
;
}
}
};
}
#endif // DUMUX_CC_TPFA_LOCAL_RESIDUAL_HH
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment