Commit 625951c8 authored by Bernd Flemisch's avatar Bernd Flemisch
Browse files

[nonisothermal] introduce niproperties.hh, adapt effective thermal

conductivities, correct comments and spacing.

The additional properties required by the generic non-isothermal model
can be centralized in a file niproperties.hh. 

The signature of the effectiveThermalConductivity functions is unified.
They get the volume variables, spatial parameters and the arguments that
will be required for calling the spatial parameters. When attempting to
use the nonisothermal model for 3p3c, it will be seen whether this
signature is genral enough.

Reviewed by Alex K.



git-svn-id: svn://svn.iws.uni-stuttgart.de/DUMUX/dumux/trunk@13289 2fb0f335-1f38-0410-981e-8018bf24f1b0
parent 2a070b6b
......@@ -32,6 +32,7 @@
#include<dumux/implicit/box/boxproperties.hh>
#include<dumux/implicit/cellcentered/ccproperties.hh>
#include<dumux/implicit/nonisothermal/niproperties.hh>
namespace Dumux
{
......@@ -43,13 +44,13 @@ namespace Properties
// Type tags
//////////////////////////////////////////////////////////////////
//! The type tags for the implicit one-phase two-component problems
//! The type tags for the implicit isothermal one-phase two-component problems
NEW_TYPE_TAG(OnePTwoC);
NEW_TYPE_TAG(BoxOnePTwoC, INHERITS_FROM(BoxModel, OnePTwoC));
NEW_TYPE_TAG(CCOnePTwoC, INHERITS_FROM(CCModel, OnePTwoC));
//! The type tags for the implicit one-phase two-component non-isothermal problems
NEW_TYPE_TAG(NonIsothermal, INHERITS_FROM(OnePTwoC));
NEW_TYPE_TAG(OnePTwoCNI, INHERITS_FROM(NonIsothermal));
//! The type tags for the corresponding non-isothermal problems
NEW_TYPE_TAG(OnePTwoCNI, INHERITS_FROM(OnePTwoC, NonIsothermal));
NEW_TYPE_TAG(BoxOnePTwoCNI, INHERITS_FROM(BoxModel, OnePTwoCNI));
NEW_TYPE_TAG(CCOnePTwoCNI, INHERITS_FROM(CCModel, OnePTwoCNI));
......@@ -72,18 +73,6 @@ NEW_PROP_TAG(Scaling); //!< Defines Scaling of the model
NEW_PROP_TAG(SpatialParamsForchCoeff); //!< Property for the forchheimer coefficient
NEW_PROP_TAG(VtkAddVelocity); //!< Returns whether velocity vectors are written into the vtk output
//////////////////////////////////////////////////////////////////
// Property tags required for the non-isothermal model
//////////////////////////////////////////////////////////////////
NEW_PROP_TAG(IsothermalModel);
NEW_PROP_TAG(IsothermalFluxVariables);
NEW_PROP_TAG(IsothermalVolumeVariables);
NEW_PROP_TAG(IsothermalLocalResidual);
NEW_PROP_TAG(IsothermalIndices);
NEW_PROP_TAG(IsothermalNumEq);
NEW_PROP_TAG(HaveVariableFormulation);
NEW_PROP_TAG(ThermalConductivityModel); //!< The model for the effective thermal conductivity
}
// \}
}
......
......@@ -110,9 +110,8 @@ SET_SCALAR_PROP(BoxModel, SpatialParamsForchCoeff, 0.55);
SET_PROP(NonIsothermal, ThermalConductivityModel)
{ private :
typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
public:
typedef ThermalConductivityAverage<Scalar, VolumeVariables> type;
typedef ThermalConductivityAverage<Scalar> type;
};
//////////////////////////////////////////////////////////////////
......
......@@ -18,36 +18,29 @@
*****************************************************************************/
/*!
* \file
* \brief This file contains data which is required to calculate
* the heat fluxes over a face of a finite volume.
*
* This means temperature gradients and the normal matrix
* heat flux.
* \brief flux variables for the implicit non-isothermal models
*/
#ifndef DUMUX_NI_FLUX_VARIABLES_HH
#define DUMUX_NI_FLUX_VARIABLES_HH
#include <dumux/common/math.hh>
#include "niproperties.hh"
namespace Dumux
{
/*!
* \ingroup TwoPTwoCNIModel
* \ingroup NIModel
* \ingroup ImplicitFluxVariables
* \brief This template class contains data which is required to
* \brief This class contains data which is required to
* calculate the heat fluxes over a face of a finite
* volume for the non-isothermal two-phase two-component model.
* volume for the implicit non-isothermal models.
* The mass fluxes are computed in the parent class.
*
* This means temperature gradients and the normal matrix
* heat flux.
*/
template <class TypeTag>
class NIFluxVariables : public GET_PROP_TYPE(TypeTag, IsothermalFluxVariables)
{
typedef typename GET_PROP_TYPE(TypeTag, IsothermalFluxVariables) ParentType;
typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) Implementation;
typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
......@@ -55,16 +48,13 @@ class NIFluxVariables : public GET_PROP_TYPE(TypeTag, IsothermalFluxVariables)
typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
typedef typename GET_PROP_TYPE(TypeTag, ThermalConductivityModel) ThermalConductivityModel;
typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
typedef typename GridView::template Codim<0>::Entity Element;
enum { dimWorld = GridView::dimensionworld };
enum { dim = GridView::dimension };
typedef Dune::FieldVector<Scalar, dim> DimVector;
typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
// static const bool isNonIsothermal = GET_PROP_VALUE(TypeTag, IsNonIsothermal);
public:
/*!
......@@ -83,14 +73,9 @@ public:
const int faceIdx,
const ElementVolumeVariables &elemVolVars,
bool onBoundary = false)
: ParentType(problem, element, fvGeometry, faceIdx, elemVolVars, onBoundary)
: ParentType(problem, element, fvGeometry, faceIdx, elemVolVars, onBoundary)
{
faceIdx_ = faceIdx;
calculateValues_(problem, element, elemVolVars);
calculateValues_(problem, element, elemVolVars);
}
/*!
......@@ -136,8 +121,6 @@ protected:
lambdaEff_ = 0;
calculateEffThermalConductivity_(problem, element, elemVolVars);
// project the heat flux vector on the face's normal vector
normalMatrixHeatFlux_ = temperatureGrad_* this->face().normal;
normalMatrixHeatFlux_ *= -lambdaEff_;
......@@ -148,53 +131,49 @@ protected:
const ElementVolumeVariables &elemVolVars)
{
const unsigned i = this->face().i;
const unsigned j = this->face().j;
Scalar lambdaI, lambdaJ;
if (GET_PROP_VALUE(TypeTag, ImplicitIsBox))
{
lambdaI =
ThermalConductivityModel::effectiveThermalConductivity(elemVolVars[i],
problem.spatialParams().thermalConductivitySolid(element, this->fvGeometry_, i),
problem.spatialParams().porosity(element, this->fvGeometry_, i));
lambdaJ =
ThermalConductivityModel::effectiveThermalConductivity(elemVolVars[j],
problem.spatialParams().thermalConductivitySolid(element, this->fvGeometry_, j),
problem.spatialParams().porosity(element, this->fvGeometry_, j));
}
else
{
const Element& elementI = *this->fvGeometry_.neighbors[i];
FVElementGeometry fvGeometryI;
fvGeometryI.subContVol[0].global = elementI.geometry().center();
lambdaI =
ThermalConductivityModel::effectiveThermalConductivity(elemVolVars[i],
problem.spatialParams().thermalConductivitySolid(elementI, fvGeometryI, 0),
problem.spatialParams().porosity(elementI, fvGeometryI, 0));
const Element& elementJ = *this->fvGeometry_.neighbors[j];
FVElementGeometry fvGeometryJ;
fvGeometryJ.subContVol[0].global = elementJ.geometry().center();
lambdaJ =
ThermalConductivityModel::effectiveThermalConductivity(elemVolVars[j],
problem.spatialParams().thermalConductivitySolid(elementJ, fvGeometryJ, 0),
problem.spatialParams().porosity(elementJ, fvGeometryJ, 0));
}
// -> harmonic mean
lambdaEff_ = harmonicMean(lambdaI, lambdaJ);
}
const unsigned j = this->face().j;
Scalar lambdaI, lambdaJ;
if (GET_PROP_VALUE(TypeTag, ImplicitIsBox))
{
lambdaI =
ThermalConductivityModel::effectiveThermalConductivity(elemVolVars[i],
problem.spatialParams(),
element, this->fvGeometry_, i);
lambdaJ =
ThermalConductivityModel::effectiveThermalConductivity(elemVolVars[j],
problem.spatialParams(),
element, this->fvGeometry_, j);
}
else
{
const Element& elementI = *this->fvGeometry_.neighbors[i];
FVElementGeometry fvGeometryI;
fvGeometryI.subContVol[0].global = elementI.geometry().center();
lambdaI =
ThermalConductivityModel::effectiveThermalConductivity(elemVolVars[i],
problem.spatialParams(),
elementI, fvGeometryI, 0);
const Element& elementJ = *this->fvGeometry_.neighbors[j];
FVElementGeometry fvGeometryJ;
fvGeometryJ.subContVol[0].global = elementJ.geometry().center();
lambdaJ =
ThermalConductivityModel::effectiveThermalConductivity(elemVolVars[j],
problem.spatialParams(),
elementJ, fvGeometryJ, 0);
}
lambdaEff_ = harmonicMean(lambdaI, lambdaJ);
}
private:
Scalar lambdaEff_;
Scalar normalMatrixHeatFlux_;
DimVector temperatureGrad_;
int faceIdx_;
};
} // end namespace
......
......@@ -24,7 +24,7 @@
#ifndef DUMUX_NI_INDICES_HH
#define DUMUX_NI_INDICES_HH
#include "niproperties.hh"
namespace Dumux
{
......
......@@ -26,8 +26,7 @@
#ifndef DUMUX_NEW_NI_LOCAL_RESIDUAL_HH
#define DUMUX_NEW_NI_LOCAL_RESIDUAL_HH
#include "niproperties.hh"
namespace Dumux
{
......
......@@ -19,13 +19,12 @@
/*!
* \file
*
* \brief Adaption of the fully implicit scheme to the non-isothermal
* two-phase two-component flow model.
* \brief the implicit non-isothermal model
*/
#ifndef DUMUX_NEW_NI_MODEL_HH
#define DUMUX_NEW_NI_MODEL_HH
#ifndef DUMUX_NI_MODEL_HH
#define DUMUX_NI_MODEL_HH
#include "niproperties.hh"
namespace Dumux {
......@@ -51,57 +50,42 @@ public:
void addOutputVtkFields(const SolutionVector &sol,
MultiWriter &writer)
{
//Call the ParentType output function
// call the ParentType output function
ParentType::addOutputVtkFields(sol, writer);
typedef Dune::BlockVector<Dune::FieldVector<double, 1> > ScalarField;
// get the number of degrees of freedom
unsigned numDofs = this->numDofs();
unsigned numElements = this->gridView_().size(0);
// unsigned numElements = this->problem_().gridView().size(0);
//create required scalar fields
ScalarField &temperature = *writer.allocateManagedBuffer(numDofs);
//Fill the scalar fields with values
ScalarField &rank = *writer.allocateManagedBuffer(numElements);
ElementIterator eIt = this->gridView().template begin<0>();
ElementIterator eEndIt = this->gridView().template end<0>();
for (; eIt != eEndIt; ++eIt)
{
int eIdx = this->problem_().model().elementMapper().map(*eIt);
rank[eIdx] = this->gridView_().comm().rank();
FVElementGeometry fvGeometry;
fvGeometry.update(this->gridView_(), *eIt);
ElementVolumeVariables elemVolVars;
elemVolVars.update(this->problem_(),
*eIt,
fvGeometry,
false /* oldSol? */);
if (GET_PROP_VALUE(TypeTag, NiOutputLevel) == 0)
return;
for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
{
int globalIdx = this->dofMapper().map(*eIt, scvIdx, dofCodim);
temperature[globalIdx] = elemVolVars[scvIdx].temperature();
}
}
//pass the scalar fields to the vtkwriter
writer.attachDofData(temperature, "temperature", isBox);
// get the number of degrees of freedom
unsigned numDofs = this->numDofs();
// create required scalar fields
typedef Dune::BlockVector<Dune::FieldVector<double, 1> > ScalarField;
ScalarField &temperature = *writer.allocateManagedBuffer(numDofs);
ElementIterator eIt = this->gridView().template begin<0>();
ElementIterator eEndIt = this->gridView().template end<0>();
for (; eIt != eEndIt; ++eIt)
{
FVElementGeometry fvGeometry;
fvGeometry.update(this->gridView_(), *eIt);
ElementVolumeVariables elemVolVars;
elemVolVars.update(this->problem_(),
*eIt,
fvGeometry,
false /* oldSol? */);
for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
{
int globalIdx = this->dofMapper().map(*eIt, scvIdx, dofCodim);
temperature[globalIdx] = elemVolVars[scvIdx].temperature();
}
}
writer.attachDofData(temperature, "temperature", isBox);
}
};
}
#endif
// -*- 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/>. *
*****************************************************************************/
/*!
* \ingroup Properties
* \ingroup ImplicitProperties
* \ingroup NIModel
* \file
*
* \brief Defines the properties required for the
* implicit non-isothermal models.
*/
#ifndef DUMUX_NI_PROPERTIES_HH
#define DUMUX_NI_PROPERTIES_HH
#include <dumux/implicit/common/implicitproperties.hh>
namespace Dumux
{
// \{
namespace Properties
{
//////////////////////////////////////////////////////////////////
// Type tags
//////////////////////////////////////////////////////////////////
NEW_TYPE_TAG(NonIsothermal);
//////////////////////////////////////////////////////////////////
// Property tags required for the non-isothermal models
//////////////////////////////////////////////////////////////////
NEW_PROP_TAG(IsothermalModel);
NEW_PROP_TAG(IsothermalFluxVariables);
NEW_PROP_TAG(IsothermalVolumeVariables);
NEW_PROP_TAG(IsothermalLocalResidual);
NEW_PROP_TAG(IsothermalIndices);
NEW_PROP_TAG(IsothermalNumEq);
NEW_PROP_TAG(HaveVariableFormulation);
NEW_PROP_TAG(ThermalConductivityModel);
NEW_PROP_TAG(NiOutputLevel);
// forward declaration of other property tags
NEW_PROP_TAG(Indices);
NEW_PROP_TAG(NumPhases);
NEW_PROP_TAG(ImplicitMassUpwindWeight);
NEW_PROP_TAG(FluidSystem);
}
// \}
}
#endif
......@@ -19,60 +19,44 @@
/*!
* \ingroup Properties
* \ingroup ImplicitProperties
* \ingroup TwoPTwoCNIModel
* \ingroup NIModel
* \file
*
* \brief Defines default values for most properties required by the
* non-isothermal two-phase two-component fully implicit model.
* implicit non-isothermal models.
*/
#ifndef DUMUX_NI_PROPERTY_DEFAULTS_HH
#define DUMUX_NI_PROPERTY_DEFAULTS_HH
#include "niindices.hh"
#include "nimodel.hh"
#include "nilocalresidual.hh"
#include "nivolumevariables.hh"
#include "nifluxvariables.hh"
#include <dumux/material/fluidmatrixinteractions/1p/thermalconductivityaverage.hh>
namespace Dumux
{
namespace Properties
{
//////////////////////////////////////////////////////////////////
// Property values
//////////////////////////////////////////////////////////////////
//! Use the 2p2cni local jacobian operator for the 2p2cni model
SET_TYPE_PROP(NonIsothermal,
LocalResidual,
NILocalResidual<TypeTag>);
SET_TYPE_PROP(NonIsothermal, LocalResidual, NILocalResidual<TypeTag>);
SET_INT_PROP(NonIsothermal, NumEq, GET_PROP_VALUE(TypeTag, IsothermalNumEq)+1);
//! the VolumeVariables property
SET_TYPE_PROP(NonIsothermal, VolumeVariables, NIVolumeVariables<TypeTag>);
////! the FluxVariables property
SET_TYPE_PROP(NonIsothermal, FluxVariables, NIFluxVariables<TypeTag>);
////! the Indices property
//! The indices required by the non-isothermal 2p2c model
SET_TYPE_PROP(NonIsothermal, Indices, NIIndices<TypeTag, 0>);
//! the Model property
SET_TYPE_PROP(NonIsothermal, Model, NIModel<TypeTag>);
SET_BOOL_PROP(NonIsothermal, NiOutputLevel, 1);
}
......
......@@ -26,8 +26,7 @@
#ifndef DUMUX_NI_VOLUME_VARIABLES_HH
#define DUMUX_NI_VOLUME_VARIABLES_HH
#include "niproperties.hh"
namespace Dumux
{
......@@ -87,17 +86,24 @@ public:
{ return heatCapacity_; };
/*!
* \brief Returns the thermal conductivity \f$\mathrm{[W/(m*K)]}\f$ of the fluid phase in
* \brief Returns the thermal conductivity \f$\mathrm{[W/(m*K)]}\f$ of a fluid phase in
* the sub-control volume.
*/
Scalar thermalConductivity(const int phaseIdx) const
Scalar thermalConductivityFluid(const int phaseIdx) const
{ return FluidSystem::thermalConductivity(this->fluidState_, phaseIdx); };
/*!
* \brief Returns the thermal conductivity \f$\mathrm{[W/(m*K)]}\f$ of the solid phase in
* the sub-control volume.
*/
Scalar thermalConductivitySolid() const
{ return thermalConductivitySolid_; };
protected:
// // this method gets called by the parent class. since this method
// // is protected, we are friends with our parent..
friend class NIVolumeVariables::ParentType;
// The methods below get called by the parent class. Since they
// are protected, we are friends with our parent.
friend class GET_PROP_TYPE(TypeTag, IsothermalVolumeVariables);
static Scalar temperature_(const PrimaryVariables &priVars,
const Problem& problem,
......@@ -133,13 +139,16 @@ protected:
const int scvIdx,
bool isOldSol)
{
// compute and set the heat capacity of the solid phase
heatCapacity_ = problem.spatialParams().heatCapacity(element, fvGeometry, scvIdx);
Valgrind::CheckDefined(heatCapacity_);
thermalConductivitySolid_
= problem.spatialParams().thermalConductivitySolid(element, fvGeometry, scvIdx);
Valgrind::CheckDefined(thermalConductivitySolid_);
};
Scalar heatCapacity_;
Scalar thermalConductivitySolid_;
};
} // end namespace
......
......@@ -19,7 +19,7 @@
/*!
* \file
*
* \brief Relation for the saturation-dependent effective thermal conductivity
* \brief simple effective thermal conductivity
*/
#ifndef THERMALCONDUCTIVITY_AVERAGE_HH
#define THERMALCONDUCTIVITY_AVERAGE_HH
......@@ -32,58 +32,36 @@ namespace Dumux
/*!
* \ingroup fluidmatrixinteractionslaws
*
* \brief Relation for the saturation-dependent effective thermal conductivity
*
* The Somerton method computes the thermal conductivity of dry and the wet soil material
* and uses a root function of the wetting saturation to compute the
* effective thermal conductivity for a two-phase fluidsystem. The individual thermal
* conductivities are calculated as geometric mean of the thermal conductivity of the porous
* material and of the respective fluid phase.
*
* The material law is:
* \f[
\lambda_\text{eff} = \lambda_{\text{dry}} + \sqrt{(S_w)} \left(\lambda_\text{wet} - \lambda_\text{dry}\right)
\f]
*
* with
* \f[
\lambda_\text{wet} = \lambda_{solid}^{\left(1-\phi\right)}*\lambda_w^\phi
\f]
* and
*
* \f[
\lambda_\text{dry} = \lambda_{solid}^{\left(1-\phi\right)}*\lambda_n^\phi.
\f]
*
* \brief Relation for a simple effective thermal conductivity
*/
template<class Scalar, class VolumeVariables>
template<class Scalar>
class ThermalConductivityAverage
{
public:
/*!
* \brief Returns the effective thermal conductivity \f$[W/(m K)]\f$ after Somerton (1974).
*
* \param sw The saturation of the wetting phase
* \param lambdaW the thermal conductivity of the wetting phase
* \param lambdaN the thermal conductivity of the non-wetting phase
* \param lambdaSolid the thermal conductivity of the solid phase
* \param porosity The porosity
* \brief simple effective thermal conductivity \f$[W/(m K)]\f$
*
* \return Effective thermal conductivity \f$[W/(m K)]\f$ after Somerton (1974)