Skip to content
Snippets Groups Projects
Commit 2767475c authored by Lisa Julia Nebel's avatar Lisa Julia Nebel
Browse files

Add geometry file for moebiusstrip

parent 19f2899f
No related branches found
No related tags found
1 merge request!72Cosserat-Continuum-Nonplanar
#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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment