Commit bdfd2337 authored by Timo Koch's avatar Timo Koch
Browse files

[discretization] Implement radially symmetric grid geometries

This implements wrappers for scvs and scvf that turn them into
radially symmetric counterparts by overloading the volume() and
area() functions. We support three modes:

* disc (annulus): A 1d grid is extruded into an annulus or disc
In the case of a disc (inner pos: 0) the inner scvf.area() is 0!

* ball (shell): A 1d grid is extruded into a spherical shell or a ball
In the case of a ball the inner scvf.area() is 0!

* toroid: A 2d grid is extruded into a toroid
In the case that on grid side is aligned with the axis the inner
scvf.area() for all inner scvfs is 0!
The grid points all have to be >= 0!
We also support unstructured grids and random convex shapes
parent fba977d6
......@@ -20,6 +20,9 @@ fvgridvariables.hh
fvproperties.hh
localview.hh
method.hh
rotationpolicy.hh
rotationsymmetricscv.hh
rotationsymmetricscvf.hh
scvandscvfiterators.hh
staggered.hh
subcontrolvolumebase.hh
......
// -*- 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 3 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
* \ingroup Discretization
* \brief Rotation policy for defining rotational symmetric grid geometries
*/
#ifndef DUMUX_DISCRETIZATION_ROTATION_POLICY_HH
#define DUMUX_DISCRETIZATION_ROTATION_POLICY_HH
namespace Dumux {
/*!
* \ingroup Discretization
* \brief Rotation policies
* - disc (or annulus): rotate a segment around an axis perpendicular to the line through the segment (we choose )
* - ball (or shell): rotate a segment around a point on the line through the segment
* - toroid: rotate a polygon around one of its axis (we rotate about the second axis)
*/
enum class RotationPolicy
{ disc, ball, toroid };
} // end namespace Dumux
#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 3 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
* \ingroup Discretization
* \brief Wrapper to make a sub control volume rotation symmetric
*/
#ifndef DUMUX_DISCRETIZATION_ROTATION_SYMMETRIC_SUBCONTROLVOLUME_HH
#define DUMUX_DISCRETIZATION_ROTATION_SYMMETRIC_SUBCONTROLVOLUME_HH
#include <cmath>
#include <dumux/discretization/rotationpolicy.hh>
namespace Dumux {
/*!
* \ingroup Discretization
* \brief Wrapper to make a sub control volume rotation symmetric
* \tparam SubControlVolume The wrapped scv type
* \tparam rotationPolicy the rotation policy (see enum RotationPolicy)
*/
template<class SubControlVolume, RotationPolicy rotationPolicy>
class RotationSymmetricSubControlVolume;
/*!
* \ingroup Discretization
* \brief Wrapper to make a sub control volume rotation symmetric
* \tparam SubControlVolume The wrapped scv type
* \note Specialization for the 'disc' policy (1d grid --> 2d disc)
*/
template<class SubControlVolume>
class RotationSymmetricSubControlVolume<SubControlVolume, RotationPolicy::disc>
: public SubControlVolume
{
using Scalar = typename SubControlVolume::Traits::Scalar;
static_assert(SubControlVolume::Traits::Geometry::mydimension == 1, "Rotation symmetric scv with disc policy only works with 1d grids!");
static_assert(SubControlVolume::Traits::Geometry::coorddimension == 1, "Rotation symmetric scv with disc policy only works with 1d grids!");
public:
//! Parent type constructor
using SubControlVolume::SubControlVolume;
//! The volume of the sub control volume (difference between two disks)
Scalar volume() const
{
using std::abs;
const auto radius0 = this->corner(0)[0];
const auto radius1 = this->corner(1)[0];
return M_PI*abs(radius1*radius1 - radius0*radius0);
}
};
/*!
* \ingroup Discretization
* \brief Wrapper to make a sub control volume rotation symmetric
* \tparam SubControlVolume The wrapped scv type
* \note Specialization for the 'ball' policy (1d grid --> 3d ball)
*/
template<class SubControlVolume>
class RotationSymmetricSubControlVolume<SubControlVolume, RotationPolicy::ball>
: public SubControlVolume
{
using Scalar = typename SubControlVolume::Traits::Scalar;
static_assert(SubControlVolume::Traits::Geometry::mydimension == 1, "Rotation symmetric scv with ball policy only works with 1d grids!");
static_assert(SubControlVolume::Traits::Geometry::coorddimension == 1, "Rotation symmetric scv with ball policy only works with 1d grids!");
public:
//! Parent type constructor
using SubControlVolume::SubControlVolume;
//! The volume of the sub control volume (difference between two balls)
Scalar volume() const
{
using std::abs;
const auto radius0 = this->corner(0)[0];
const auto radius1 = this->corner(1)[0];
return 4.0/3.0*M_PI*abs(radius1*radius1*radius1 - radius0*radius0*radius0);
}
};
/*!
* \ingroup Discretization
* \brief Wrapper to make a sub control volume rotation symmetric
* \tparam SubControlVolume The wrapped scv type
* \note Specialization for the 'toroid' policy (2d grid --> 3d toroid)
* \note We rotate about the second axis
*/
template<class SubControlVolume>
class RotationSymmetricSubControlVolume<SubControlVolume, RotationPolicy::toroid>
: public SubControlVolume
{
using Scalar = typename SubControlVolume::Traits::Scalar;
static_assert(SubControlVolume::Traits::Geometry::mydimension == 2, "Rotation symmetric scv with toroid policy only works with 2d grids!");
static_assert(SubControlVolume::Traits::Geometry::coorddimension == 2, "Rotation symmetric scv with toroid policy only works with 2d grids!");
public:
//! Parent type constructor
using SubControlVolume::SubControlVolume;
//! The volume of the sub control volume (Guldinus theorem)
Scalar volume() const
{
const auto radius = this->center()[1];
return SubControlVolume::volume()*2.0*M_PI*radius;
}
};
} // end namespace Dumux
#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 3 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
* \ingroup Discretization
* \brief Wrapper to make a sub control volume face rotation symmetric
*/
#ifndef DUMUX_DISCRETIZATION_ROTATION_SYMMETRIC_SUBCONTROLVOLUMEFACE_HH
#define DUMUX_DISCRETIZATION_ROTATION_SYMMETRIC_SUBCONTROLVOLUMEFACE_HH
#include <cmath>
#include <dumux/discretization/rotationpolicy.hh>
namespace Dumux {
/*!
* \ingroup Discretization
* \brief Wrapper to make a sub control volume face rotation symmetric
* \tparam SubControlVolumeFace The wrapped scvf type
* \tparam rotationPolicy the rotation policy (see enum RotationPolicy)
*/
template<class SubControlVolumeFace, RotationPolicy rotationPolicy>
class RotationSymmetricSubControlVolumeFace;
/*!
* \ingroup Discretization
* \brief Wrapper to make a sub control volume face rotation symmetric
* \tparam SubControlVolumeFace The wrapped scvf type
* \note Specialization for the 'disc' policy (1d grid --> 2d disc)
*/
template<class SubControlVolumeFace>
class RotationSymmetricSubControlVolumeFace<SubControlVolumeFace, RotationPolicy::disc>
: public SubControlVolumeFace
{
using Scalar = typename SubControlVolumeFace::Traits::Scalar;
static_assert(SubControlVolumeFace::Traits::Geometry::mydimension == 0, "Rotation symmetric scvf with disc policy only works with 1d grids!");
static_assert(SubControlVolumeFace::Traits::Geometry::coorddimension == 1, "Rotation symmetric scvf with disc policy only works with 1d grids!");
public:
//! Parent type constructor
using SubControlVolumeFace::SubControlVolumeFace;
//! The area of the sub control volume face (circumference of circle)
Scalar area() const
{
const auto radius = this->corner(0)[0];
return 2.0*M_PI*radius;
}
};
/*!
* \ingroup Discretization
* \brief Wrapper to make a sub control volume face rotation symmetric
* \tparam SubControlVolumeFace The wrapped scvf type
* \note Specialization for the 'ball' policy (1d grid --> 3d ball)
*/
template<class SubControlVolumeFace>
class RotationSymmetricSubControlVolumeFace<SubControlVolumeFace, RotationPolicy::ball>
: public SubControlVolumeFace
{
using Scalar = typename SubControlVolumeFace::Traits::Scalar;
static_assert(SubControlVolumeFace::Traits::Geometry::mydimension == 0, "Rotation symmetric scvf with ball policy only works with 1d grids!");
static_assert(SubControlVolumeFace::Traits::Geometry::coorddimension == 1, "Rotation symmetric scvf with ball policy only works with 1d grids!");
public:
//! Parent type constructor
using SubControlVolumeFace::SubControlVolumeFace;
//! The area of the sub control volume face (surface of sphere)
Scalar area() const
{
const auto radius = this->corner(0)[0];
return 4.0*M_PI*radius*radius;
}
};
/*!
* \ingroup Discretization
* \brief Wrapper to make a sub control volume face rotation symmetric
* \tparam SubControlVolumeFace The wrapped scvf type
* \note Specialization for the 'toroid' policy (2d grid --> 3d toroid)
* \note We rotate about the second axis
*/
template<class SubControlVolumeFace>
class RotationSymmetricSubControlVolumeFace<SubControlVolumeFace, RotationPolicy::toroid>
: public SubControlVolumeFace
{
using Scalar = typename SubControlVolumeFace::Traits::Scalar;
static_assert(SubControlVolumeFace::Traits::Geometry::mydimension == 1, "Rotation symmetric scvf with toroid policy only works with 2d grids!");
static_assert(SubControlVolumeFace::Traits::Geometry::coorddimension == 2, "Rotation symmetric scvf with toroid policy only works with 2d grids!");
public:
//! Parent type constructor
using SubControlVolumeFace::SubControlVolumeFace;
//! The area of the sub control volume face (Guldinus theorem)
Scalar area() const
{
const auto radius = this->center()[1];
return SubControlVolumeFace::area()*2.0*M_PI*radius;
}
};
} // end namespace Dumux
#endif
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment