From 2767475c89da8df490c5890c06a8b5c3dd911529 Mon Sep 17 00:00:00 2001 From: Lisa Julia Nebel <lisa_julia.nebel@tu-dresden.de> Date: Fri, 19 Mar 2021 10:49:49 +0100 Subject: [PATCH] Add geometry file for moebiusstrip --- dune/gfe/geometries/moebiusstrip.hh | 106 ++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 dune/gfe/geometries/moebiusstrip.hh diff --git a/dune/gfe/geometries/moebiusstrip.hh b/dune/gfe/geometries/moebiusstrip.hh new file mode 100644 index 00000000..793c2283 --- /dev/null +++ b/dune/gfe/geometries/moebiusstrip.hh @@ -0,0 +1,106 @@ +#ifndef DUNE_GFE_MOEBIUSSTRIP_GRIDFUNCTION_HH +#define DUNE_GFE_MOEBIUSSTRIP_GRIDFUNCTION_HH + +#include <cmath> + +#include <dune/common/fmatrix.hh> +#include <dune/common/fvector.hh> +#include <dune/curvedgrid/gridfunctions/analyticgridfunction.hh> + +namespace Dune { + +/// \brief Functor representing a Möbius strip in 3D, where the base circle is the circle in the x-y-plane with radius_ around 0,0,0 +template <class T = double> +class MoebiusStripProjection +{ + static const int dim = 3; + using Domain = FieldVector<T,dim>; + using Jacobian = FieldMatrix<T,dim,dim>; + + T radius_; + +public: + MoebiusStripProjection (T radius) + : radius_(radius) + {} + + /// \brief Project the coordinate to the MS using closest point projection + Domain operator() (const Domain& x) const + { + double nrm = std::sqrt(x[0]*x[0] + x[1]*x[1]); + //center for the point x - it lies on the circle around (0,0,0) with radius radius_ in the x-y-plane + Domain center{x[0] * radius_/nrm, x[1] * radius_/nrm, 0}; + double cosu = x[0]/nrm; + double sinu = x[1]/nrm; + double cosuhalf = std::sqrt((1+cosu)/2); + cosuhalf *= (sinu < 0) ? (-1) : 1 ; // u goes from 0 to 2*pi, so cosuhalf is negative if sinu < 0, we multiply that here + double sinuhalf = std::sqrt((1-cosu)/2); //u goes from 0 to 2*pi, so sinuhalf is always >= 0 + + // now calculate line from center to the new point + // the direction is (cosuhalf*cosu,cosuhalf*sinu,sinuhalf), as can be seen from the formula to construct the MS, we normalize this vector + Domain centerToPointOnMS{cosuhalf*cosu,cosuhalf*sinu,sinuhalf}; + centerToPointOnMS /= centerToPointOnMS.two_norm(); + + Domain centerToX = center - x; + // We need the length, let theta be the angle between the vector centerToX and center to centerToPointOnMS + // then cos(theta) = centerToX*centerToPointOnMS/(len(centerToX)*len(centerToPointOnMS)) + // We want to project the point to MS, s.t. the angle between the MS and the projection is 90deg + // Then, length = cos(theta) * len(centerToX) = centerToX*centerToPointOnMS/len(centerToPointOnMS) = centerToX*centerToPointOnMS + double length = - centerToX * centerToPointOnMS; + centerToPointOnMS *= length; + return center + centerToPointOnMS; + } + + + /// \brief derivative of the projection to the MS + friend auto derivative (const MoebiusStripProjection& moebiusStrip) + { + DUNE_THROW(NotImplemented,"The derivative of the projection to the Möbius strip is not implemented yet!"); + return [radius = moebiusStrip.radius_](const Domain& x) + { + Jacobian out; + return out; + }; + } + + /// \brief Normal Vector of the MS + Domain normal (const Domain& x) const + { + using std::sqrt; + Domain nVec = {x[0],x[1],0}; + double nrm = std::sqrt(x[0]*x[0] + x[1]*x[1]); + double cosu = x[0]/nrm; + double sinu = x[1]/nrm; + double cosuhalf = std::sqrt((1+cosu)/2); + cosuhalf *= (sinu < 0) ? (-1) : 1 ; // u goes from 0 to 2*pi, so cosuhalf is negative if sinu < 0, we multiply that here + double sinuhalf = std::sqrt((1-cosu)/2); + nVec[2] = (-1)*cosuhalf*(cosu*x[0]+sinu*x[1])/sinuhalf; + nVec /= nVec.two_norm(); + return nVec; + } + + /// \brief The mean curvature of the MS + T mean_curvature (const Domain& /*x*/) const + { + DUNE_THROW(NotImplemented,"The mean curvature of the Möbius strip is not implemented yet!"); + return 1; + } + + /// \brief The area of the MS + T area () const + { + DUNE_THROW(NotImplemented,"The area of the Möbius strip is not implemented yet!"); + return 1; + } +}; + +/// \brief construct a grid function representing the parametrization of a MS +template <class Grid, class T> +auto moebiusStripGridFunction (T radius) +{ + return analyticGridFunction<Grid>(MoebiusStripProjection<T>{radius}); +} + +} // end namespace Dune + +#endif // DUNE_GFE_MOEBIUSSTRIP_GRIDFUNCTION_HH -- GitLab