Commit 51438329 authored by Praetorius, Simon's avatar Praetorius, Simon

intersection and boundary operators added

parent a9f97a0f
Pipeline #907 passed with stage
in 13 minutes and 4 seconds
...@@ -16,6 +16,8 @@ namespace AMDiS ...@@ -16,6 +16,8 @@ namespace AMDiS
using Geometry = typename Impl::Get<Element>::Geometry; using Geometry = typename Impl::Get<Element>::Geometry;
public: public:
/// Constructor, initializes the geometry of the element and a
/// quadrature-rule wrapper
template <class Operator> template <class Operator>
Assembler(Operator& op, Element const& element, int degree, FirstOrderType type = GRD_PHI) Assembler(Operator& op, Element const& element, int degree, FirstOrderType type = GRD_PHI)
: geometry(get_geometry(element)) : geometry(get_geometry(element))
...@@ -26,24 +28,45 @@ namespace AMDiS ...@@ -26,24 +28,45 @@ namespace AMDiS
quadrature.reset(new QuadratureRule(element, quad)); quadrature.reset(new QuadratureRule(element, quad));
} }
/// \brief Returns reference to the transformed quadrature rule
/**
* For intersections this corresponds to the points in the intersection
* geometry, but coordinates extended to the whole inside-entity. For
* elements this is a wrapper around the classical element quadrature rule.
* Access the underlying dune-quadrature rule, with `quadrature->getRule()`.
**/
auto const& getQuadrature() const auto const& getQuadrature() const
{
return quadrature->getRule();
}
auto const& getTransformedQuadrature() const
{ {
return *quadrature; return *quadrature;
} }
/// Return the geometry of the Object
/**
* The geometry is either the element geometry, or the geometry of the
* inside-element for intersections.
**/
Geometry const& getGeometry() const Geometry const& getGeometry() const
{ {
return geometry; return geometry;
} }
protected:
// transform coords from intersection coords to element coords
template <class Coordinate>
decltype(auto) map(Coordinate const& p) const
{
return get_position<Element>(geometry, p);
}
private: private:
/// transformed quadrature rule
std::shared_ptr<QuadratureRule const> quadrature; std::shared_ptr<QuadratureRule const> quadrature;
Geometry geometry; // TODO: create geometry just once for each element, e.g. in ProblemStat when traversing the grid
/// geometry() for entities or geometryInInside() for intersections
Geometry geometry;
// TODO: create geometry just once for each element, e.g. in ProblemStat when traversing the grid
}; };
} // end namespace AMDiS } // end namespace AMDiS
#pragma once
namespace AMDiS
{
template <class MeshView>
class BoundaryFacetIterator;
// An Iterator over all elements and when element hasBoundaryIntersections
template <class MeshView>
class BoundaryElementIterator
{
friend class BoundaryFacetIterator<MeshView>;
using Self = BoundaryElementIterator;
using Element = typename MeshView::template Codim<0>::Entity;
using ElementIterator = typename MeshView::template Codim<0>::Iterator;
class Iterator
{
public:
Iterator(ElementIterator elementIt, ElementIterator endIt)
: elementIt(elementIt)
, endIt(endIt)
{}
Iterator(Iterator const&) = default;
Iterator& operator=(Iterator const&) = default;
// iterate to next element that has boundary intersections
Iterator& operator++()
{
++elementIt;
while (elementIt != endIt && !elementIt->hasBoundaryIntersections())
++elementIt;
return *this;
}
Iterator operator++(int)
{
auto tmp = *this;
++(*this);
return tmp;
}
Element const& operator*() const
{
return *elementIt;
}
Element const* operator->() const
{
return &(*elementIt);
}
bool operator==(Iterator const& that) const
{
return elementIt == that.elementIt;
}
bool operator!=(Iterator const& that) const
{
return !(*this == that);
}
private:
ElementIterator elementIt;
ElementIterator endIt;
};
public:
/// Constructor.
BoundaryElementIterator(MeshView const& meshView)
: meshView(meshView)
{}
Iterator begin() {
auto elementIt = elements(meshView).begin();
auto endIt = elements(meshView).end();
while (elementIt != endIt && !elementIt->hasBoundaryIntersections())
++elementIt;
return {elementIt, endIt};
}
Iterator end() {
return {elements(meshView).end(), elements(meshView).end()};
}
private:
MeshView const& meshView;
};
/// Generator function for the boundary-element iterator
template <class MeshView>
BoundaryElementIterator<MeshView> boundary_elements(MeshView const& meshView)
{
return {meshView};
}
// An Iterator over all elements and when element hasBoundaryIntersections, then
// iterate over all boundary-intersections with given Index, oder for thos with
// predicate returns true
template <class MeshView>
class BoundaryFacetIterator
{
using Element = typename MeshView::template Codim<0>::Entity;
using Facet = typename MeshView::template Codim<1>::Entity;
using ElementIterator = typename BoundaryElementIterator<MeshView>::Iterator;
using FacetIterator = typename MeshView::IntersectionIterator;
class Iterator
{
public:
Iterator(MeshView const& meshView,
ElementIterator elementIt,
FacetIterator facetIt,
ElementIterator endIt)
: meshView(meshView)
, elementIt(elementIt)
, facetIt(facetIt)
, endIt(endIt)
{}
Iterator(Iterator const&) = default;
Iterator& operator=(Iterator const&) = default;
// iterate to next boundary face within current element or to the first
// boundary face in the next boundary element
Iterator& operator++()
{
++facetIt;
do {
auto facetEndIt = intersections(meshView, *elementIt).end();
while (facetIt != facetEndIt && !facetIt->boundary())
++facetIt;
if (facetIt != facetEndIt)
break;
++elementIt;
facetIt = intersections(meshView, *elementIt).begin();
} while (elementIt != endIt);
return *this;
}
Iterator operator++(int)
{
auto tmp = *this;
++(*this);
return tmp;
}
// returns Dune::Intersection
auto const& operator*() const
{
return *facetIt;
}
auto const* operator->() const
{
return &(*facetIt);
}
bool operator==(Iterator const& that) const
{
return elementIt == that.elementIt && (elementIt == endIt || facetIt == that.facetIt);
}
bool operator!=(Iterator const& that) const
{
return !(*this == that);
}
private:
MeshView const& meshView;
ElementIterator elementIt;
FacetIterator facetIt;
ElementIterator endIt;
};
public:
/// Constructor.
BoundaryFacetIterator(MeshView const& meshView)
: meshView(meshView)
{}
Iterator begin() {
auto elementIt = boundary_elements(meshView).begin();
auto endElementIt = boundary_elements(meshView).end();
auto facetIt = intersections(meshView, *elementIt).begin();
while (!facetIt->boundary())
++facetIt;
return {meshView, elementIt, facetIt, endElementIt};
}
Iterator end() {
auto elementIt = boundary_elements(meshView).begin();
auto endElementIt = boundary_elements(meshView).end();
auto facetIt = intersections(meshView, *elementIt).begin();
return {meshView, endElementIt, facetIt, endElementIt};
}
private:
MeshView const& meshView;
};
/// Generator function for the boundary-element iterator
template <class MeshView>
BoundaryFacetIterator<MeshView> boundary_facets(MeshView const& meshView)
{
return {meshView};
}
} // end namespace AMDiS
...@@ -30,7 +30,7 @@ namespace AMDiS ...@@ -30,7 +30,7 @@ namespace AMDiS
{ {
using Dune::Functions::interpolate; using Dune::Functions::interpolate;
test_exit(initialized, "Boundary condition not initialized!"); test_exit_dbg(initialized, "Boundary condition not initialized!");
matrix.clearDirichletRows(dirichletNodes, apply); matrix.clearDirichletRows(dirichletNodes, apply);
if (apply) { if (apply) {
......
...@@ -37,9 +37,9 @@ namespace AMDiS ...@@ -37,9 +37,9 @@ namespace AMDiS
public: public:
/// Constructor. /// Constructor.
FileWriter(std::string base, MeshView const& meshView, std::vector<std::string> const& names_) FileWriter(std::string base, MeshView const& meshView, std::vector<std::string> const& names)
: meshView(meshView) : meshView(meshView)
, names(names_) , names(names)
{ {
filename = "solution"; filename = "solution";
Parameters::get(base + "->filename", filename); Parameters::get(base + "->filename", filename);
......
...@@ -27,23 +27,23 @@ namespace AMDiS ...@@ -27,23 +27,23 @@ namespace AMDiS
: Super(op, element, 1, type) : Super(op, element, 1, type)
{ {
if (type == GRD_PHI) if (type == GRD_PHI)
op.initFot1(element, Super::getTransformedQuadrature()); op.initFot1(element, Super::getQuadrature());
else else
op.initFot2(element, Super::getTransformedQuadrature()); op.initFot2(element, Super::getQuadrature());
} }
// tag dispatching for FirstOrderType...
template <class Operator, class RowView, class ColView> template <class Operator, class RowView, class ColView>
void calculateElementMatrix(Operator& op, RowView const& rowView, ColView const& colView, void calculateElementMatrix(Operator& op, RowView const& rowView, ColView const& colView, ElementMatrix& elementMatrix)
ElementMatrix& elementMatrix)
{ {
calculateElementMatrix(op, rowView, colView, elementMatrix, std::integral_constant<FirstOrderType, type>{}); calculateElementMatrix(op, rowView, colView, elementMatrix, FirstOrderType_<type>);
} }
template <class Operator, class RowView> template <class Operator, class RowView>
void calculateElementVector(Operator& op, RowView const& rowView, ElementVector& elementVector) void calculateElementVector(Operator& op, RowView const& rowView, ElementVector& elementVector)
{ {
calculateElementVector(op, rowView, elementVector, std::integral_constant<FirstOrderType, type>{}); calculateElementVector(op, rowView, elementVector, FirstOrderType_<type>);
} }
...@@ -52,18 +52,18 @@ namespace AMDiS ...@@ -52,18 +52,18 @@ namespace AMDiS
RowView const& rowView, RowView const& rowView,
ColView const& colView, ColView const& colView,
ElementMatrix& elementMatrix, ElementMatrix& elementMatrix,
std::integral_constant<FirstOrderType, GRD_PHI>) FirstOrderType_t<GRD_PHI>)
{ {
auto geometry = rowView.element().geometry(); auto geometry = rowView.element().geometry();
auto const& quad_geometry = Super::getGeometry(); auto const& quad_geometry = Super::getGeometry();
auto const& rowLocalBasis = rowView.tree().finiteElement().localBasis(); auto const& rowLocalBasis = rowView.tree().finiteElement().localBasis();
auto const& colLocalBasis = colView.tree().finiteElement().localBasis(); auto const& colLocalBasis = colView.tree().finiteElement().localBasis();
auto const& quad = Super::getQuadrature(); auto const& quad = Super::getQuadrature().getRule();
for (std::size_t iq = 0; iq < quad.size(); ++iq) { for (std::size_t iq = 0; iq < quad.size(); ++iq) {
// Position of the current quadrature point in the reference element // Position of the current quadrature point in the reference element
decltype(auto) quadPos = get_position<Element>(quad_geometry, quad[iq].position()); decltype(auto) quadPos = Super::map(quad[iq].position());
// The transposed inverse Jacobian of the map from the reference element to the element // The transposed inverse Jacobian of the map from the reference element to the element
const auto jacobian = geometry.jacobianInverseTransposed(quadPos); const auto jacobian = geometry.jacobianInverseTransposed(quadPos);
...@@ -100,18 +100,18 @@ namespace AMDiS ...@@ -100,18 +100,18 @@ namespace AMDiS
RowView const& rowView, RowView const& rowView,
ColView const& colView, ColView const& colView,
ElementMatrix& elementMatrix, ElementMatrix& elementMatrix,
std::integral_constant<FirstOrderType, GRD_PSI>) FirstOrderType_t<GRD_PSI>)
{ {
auto geometry = rowView.element().geometry(); auto geometry = rowView.element().geometry();
auto const& quad_geometry = Super::getGeometry(); auto const& quad_geometry = Super::getGeometry();
auto const& rowLocalBasis = rowView.tree().finiteElement().localBasis(); auto const& rowLocalBasis = rowView.tree().finiteElement().localBasis();
auto const& colLocalBasis = colView.tree().finiteElement().localBasis(); auto const& colLocalBasis = colView.tree().finiteElement().localBasis();
auto const& quad = Super::getQuadrature(); auto const& quad = Super::getQuadrature().getRule();
for (std::size_t iq = 0; iq < quad.size(); ++iq) { for (std::size_t iq = 0; iq < quad.size(); ++iq) {
// Position of the current quadrature point in the reference element // Position of the current quadrature point in the reference element
decltype(auto) quadPos = get_position<Element>(quad_geometry, quad[iq].position()); decltype(auto) quadPos = Super::map(quad[iq].position());
// The transposed inverse Jacobian of the map from the reference element to the element // The transposed inverse Jacobian of the map from the reference element to the element
const auto jacobian = geometry.jacobianInverseTransposed(quadPos); const auto jacobian = geometry.jacobianInverseTransposed(quadPos);
...@@ -147,17 +147,17 @@ namespace AMDiS ...@@ -147,17 +147,17 @@ namespace AMDiS
void calculateElementVector(Operator& op, void calculateElementVector(Operator& op,
RowView const& rowView, RowView const& rowView,
ElementVector& elementVector, ElementVector& elementVector,
std::integral_constant<FirstOrderType, GRD_PSI>) FirstOrderType_t<GRD_PSI>)
{ {
auto geometry = rowView.element().geometry(); auto geometry = rowView.element().geometry();
auto const& quad_geometry = Super::getGeometry(); auto const& quad_geometry = Super::getGeometry();
auto const& rowLocalBasis = rowView.tree().finiteElement().localBasis(); auto const& rowLocalBasis = rowView.tree().finiteElement().localBasis();
auto const& quad = Super::getQuadrature(); auto const& quad = Super::getQuadrature().getRule();
for (std::size_t iq = 0; iq < quad.size(); ++iq) { for (std::size_t iq = 0; iq < quad.size(); ++iq) {
// Position of the current quadrature point in the reference element // Position of the current quadrature point in the reference element
decltype(auto) quadPos = get_position<Element>(quad_geometry, quad[iq].position()); decltype(auto) quadPos = Super::map(quad[iq].position());
// The transposed inverse Jacobian of the map from the reference element to the element // The transposed inverse Jacobian of the map from the reference element to the element
const auto jacobian = geometry.jacobianInverseTransposed(quadPos); const auto jacobian = geometry.jacobianInverseTransposed(quadPos);
...@@ -183,6 +183,4 @@ namespace AMDiS ...@@ -183,6 +183,4 @@ namespace AMDiS
} }
}; };
} // end namespace AMDiS } // end namespace AMDiS
...@@ -12,28 +12,33 @@ namespace AMDiS ...@@ -12,28 +12,33 @@ namespace AMDiS
{ {
public: public:
/// Constructs a unset Flag /// Constructs a unset Flag
Flag() : flags(0) {} constexpr Flag() = default;
/// Constructs a Flag initialized by f /// Constructs a Flag initialized by f
Flag(const unsigned long f) : flags(f) {} constexpr Flag(const unsigned long f)
: flags(f)
{}
/// Copy constructor /// Copy constructor
Flag(Flag const& f) : flags(f.flags) {} constexpr Flag(Flag const&) = default;
/// Move constructor
constexpr Flag(Flag&&) = default;
/// Compares two Flags /// Compares two Flags
bool operator==(Flag const& f) const constexpr bool operator==(Flag const& f) const
{ {
return (flags == f.flags); return (flags == f.flags);
} }
/// Compares two Flags /// Compares two Flags
bool operator!=(Flag const& f) const constexpr bool operator!=(Flag const& f) const
{ {
return !(f == *this); return !(f == *this);
} }
/// Assignment operator /// Assignment operator
Flag& operator=(Flag const& f) constexpr Flag& operator=(Flag const& f)
{ {
if (this != &f) if (this != &f)
flags = f.flags; flags = f.flags;
...@@ -41,101 +46,96 @@ namespace AMDiS ...@@ -41,101 +46,96 @@ namespace AMDiS
} }
/// Typecast /// Typecast
operator bool() const constexpr operator bool() const
{ {
return isAnySet(); return isAnySet();
} }
/// Set \ref flags /// Set \ref flags
void setFlags(const unsigned long f) constexpr void setFlags(const unsigned long f)
{ {
flags = f; flags = f;
} }
/// Set \ref flags /// Set \ref flags
void setFlags(Flag const& f) constexpr void setFlags(Flag const& f)
{ {
flags = f.flags; flags = f.flags;
} }
/// Sets \ref flags to \ref flags | f /// Sets \ref flags to \ref flags | f
void setFlag(const unsigned long f) constexpr void setFlag(const unsigned long f)
{ {
flags |= f; flags |= f;
} }
/// Sets \ref flags to \ref flags | f.flags /// Sets \ref flags to \ref flags | f.flags
void setFlag(Flag const& f) constexpr void setFlag(Flag const& f)
{ {
flags |= f.flags; flags |= f.flags;
} }
/// Sets \ref flags to \ref flags & ~f /// Sets \ref flags to \ref flags & ~f
void unsetFlag(const unsigned long f) constexpr void unsetFlag(const unsigned long f)
{ {
flags &= ~f; flags &= ~f;
} }
/// Sets \ref flags to \ref flags & ~f.flags /// Sets \ref flags to \ref flags & ~f.flags
void unsetFlag(Flag const& f) constexpr void unsetFlag(Flag const& f)
{ {
flags &= ~f.flags; flags &= ~f.flags;
} }
unsigned long getFlags() const constexpr unsigned long getFlags() const
{ {
return flags; return flags;