dim=2; spacedim=3; chartdim=spacedim-1; a=1; b=2;c=3;
Triangulation<dim,spacedim> tria;
GridGenerator::hyper_sphere (tria, Point<spacedim>(0.0,0.0,0.0), 1.0);
GridTools::transform(&grid_transform, tria);
Ellipsoid<dim,spacedim,chartdim> ellipsoid(a,b,c);
tria.set_manifold(0,ellipsoid);
tria.refine_global(1);
template <int dim,int spacedim,int chartdim=spacedim-1>class Ellipsoid: public ChartManifold<dim,spacedim,chartdim>{public:
Ellipsoid(double,double,double);
Point<chartdim> pull_back(const Point<spacedim> &space_point) const; Point<spacedim> push_forward(const Point<chartdim> &chart_point) const;
private: double a,b,c; double max_axis; const Point<spacedim> center; SphericalManifold<dim,spacedim> reference_sphere; };
template <int dim, int spacedim, int chartdim>Ellipsoid<dim,spacedim,chartdim>::Ellipsoid(double a, double b, double c): ChartManifold<dim,spacedim,chartdim>(Point<chartdim>(2*numbers::PI, 2*numbers::PI)), a(a), b(b),c(c), center(0,0,0), reference_sphere(center) { max_axis = std::max(std::max(a,b),c);}template <int dim,int spacedim, int chartdim>Point<chartdim> Ellipsoid<dim,spacedim,chartdim>::pull_back(const Point<spacedim> &space_point) const{ double x,y,z, u,v,w; // get point on ellipsoid x = space_point[0]; y = space_point[1]; z = space_point[2];
std::cout << "using a,b,c: " << std::endl; std::cout << a << " " << b << " " << c << std::endl; std::cout << "from pull_back: " << std::endl; std::cout << "space_point: " << std::endl; std::cout << x << " " << y << " " << z << std::endl;
// map ellipsoid point onto sphere u = x/a; v = y/b; w = z/c;
std::cout << "pulls back to : " << std::endl; std::cout << u << " " << v << " " << w << std::endl; std::cout << "on sphere." << std::endl;
Point<spacedim> p(u,v,w);
// use reference_sphere's pull_back function Point<spacedim> q = reference_sphere.pull_back(p); Point<chartdim> chart_point;
std::cout << "sphere pull_back: " << std::endl; std::cout << q[0] << " " << q[1] << " " << q[2] << std::endl; std::cout << "r theta phi" << std::endl; std::cout << "..........." << std::endl;
chart_point[0] = q[1]; chart_point[1] = q[2];
// return (theta,phi) in the chart domain return chart_point;
}template <int dim,int spacedim, int chartdim>Point<spacedim> Ellipsoid<dim,spacedim,chartdim>::push_forward(const Point<chartdim> &chart_point) const{ double theta,phi, x,y,z;
phi = chart_point[0]; theta = chart_point[1];
Point<spacedim> p(max_axis,theta,phi); // map theta,phi in chart domain onto reference_sphere with radius max_axis Point<spacedim> X = reference_sphere.push_forward(p);
// map point on sphere onto ellipsoid
x = a*X[0]; y = b*X[1]; z = c*X[2];
Point<spacedim> space_point(x,y,z);
// return point on ellipsoid return space_point;}
Point<3> grid_transform (const Point<3> &X){ // transform points on sphere onto ellipsoid double a,b,c; a = 1.0; b = 1.0; c = 1.0;
double x,y,z; x = a*X(0); y = b*X(1); z = c*X(2);
return Point<3>(x,y,z);}
void assemble_mesh_and_manifold(){
const int dim = 2; const int spacedim = 3; const int chartdim = 2;
double a,b,c; a = 1; b=1; c=1;
Ellipsoid<dim,spacedim,chartdim> ellipsoid(a,b,c);
Triangulation<dim,spacedim> tria;
// generate coarse spherical mesh GridGenerator::hyper_sphere (tria, Point<spacedim>(0.0,0.0,0.0), 1.0); for (Triangulation<dim,spacedim>::active_cell_iterator cell=tria.begin_active(); cell!=tria.end(); ++cell) cell->set_all_manifold_ids(0);
print_mesh_info(tria, "spherical_mesh.vtk");
GridTools::transform(&grid_transform, tria);
tria.set_manifold(0,ellipsoid);
tria.refine_global(1);
print_mesh_info(tria, "ellipsoidal_mesh.vtk");
}
int main (){ assemble_mesh_and_manifold();}
template <int dim,int spacedim>class Ellipsoid: public SphericalManifold<dim,spacedim>{public:
Ellipsoid(double,double,double);
Point<spacedim> pull_back(const Point<spacedim> &space_point) const;
Point<spacedim> push_forward(const Point<spacedim> &chart_point) const;
Point<spacedim> get_new_point(const Quadrature<spacedim> &quad) const;
Point<spacedim> grid_transform(const Point<spacedim> &X);
private: double a,b,c; double max_axis; const Point<spacedim> center;
Point<dim> ellipsoid_pull_back(const Point<spacedim> &space_point) const;
Point<spacedim> ellipsoid_push_forward(const Point<dim> &chart_point) const;
};
template <int dim, int spacedim>Ellipsoid<dim,spacedim>::Ellipsoid(double a, double b, double c) : SphericalManifold<dim,spacedim>(center), a(a), b(b),c(c), center(0,0,0){
max_axis = std::max(std::max(a,b),c);}
template <int dim,int spacedim>
Point<spacedim> Ellipsoid<dim,spacedim>::pull_back(const Point<spacedim> &space_point) const{ Point<dim> chart_point = ellipsoid_pull_back(space_point); Point<spacedim> p; p[0] = -1; // dummy radius to match return of SphericalManifold::pull_back() p[1] = chart_point[0]; p[2] = chart_point[1];
return p;}
template <int dim,int spacedim>Point<spacedim> Ellipsoid<dim,spacedim>::push_forward(const Point<spacedim> &chart_point) const{
Point<dim> p; // p[0] = chart_point[1]; p[1] = chart_point[2];
Point<spacedim> space_point = ellipsoid_push_forward(p); return space_point;
}
template <int dim,int spacedim>Point<spacedim> Ellipsoid<dim,spacedim>::get_new_point(const Quadrature<spacedim> &quad) const{ double u,v,w; std::vector< Point<spacedim> > space_points; for (unsigned int i=0; i<quad.size(); ++i) { u = quad.point(i)[0]/a; v = quad.point(i)[1]/b; w = quad.point(i)[2]/c; space_points.push_back(Point<spacedim>(u,v,w)); }
Quadrature<spacedim> spherical_quad = Quadrature<spacedim>(space_points, quad.get_weights());
Point<spacedim> p = SphericalManifold<dim,spacedim>::get_new_point(spherical_quad); double x,y,z; x = a*p[0]; y = b*p[1]; z = c*p[2];
Point<spacedim> new_point = Point<spacedim>(x,y,z); return new_point;}
template <int dim,int spacedim>Point<dim> Ellipsoid<dim,spacedim>::ellipsoid_pull_back(const Point<spacedim> &space_point) const
{ double x,y,z, u,v,w;
// get point on ellipsoid x = space_point[0]; y = space_point[1]; z = space_point[2];
std::cout << "using a,b,c: " << std::endl; std::cout << a << " " << b << " " << c << std::endl; std::cout << "from pull_back: " << std::endl; std::cout << "space_point: " << std::endl; std::cout << x << " " << y << " " << z << std::endl;
// map ellipsoid point onto sphere u = x/a; v = y/b; w = z/c;
std::cout << "pulls back to : " << std::endl; std::cout << u << " " << v << " " << w << std::endl; std::cout << "on sphere." << std::endl;
Point<spacedim> p(u,v,w);
// use reference_sphere's pull_back function
Point<spacedim> q = pull_back(p); Point<dim> chart_point;
std::cout << "sphere pull_back: " << std::endl; std::cout << q[0] << " " << q[1] << " " << q[2] << std::endl; std::cout << "r theta phi" << std::endl; std::cout << "..........." << std::endl;
chart_point[0] = q[1]; chart_point[1] = q[2];
// return (theta,phi) in the chart domain return chart_point;
}
template <int dim,int spacedim>Point<spacedim> Ellipsoid<dim,spacedim>::ellipsoid_push_forward(const Point<dim> &chart_point) const
{ double theta,phi, x,y,z;
phi = chart_point[0]; theta = chart_point[1];
Point<spacedim> p(max_axis,theta,phi); // map theta,phi in chart domain onto reference_sphere with radius max_axis
Point<spacedim> X = push_forward(p);
// map point on sphere onto ellipsoid
x = a*X[0]; y = b*X[1]; z = c*X[2];
Point<spacedim> space_point(x,y,z);
// return point on ellipsoid return space_point;}
template<int dim, int spacedim>Point<spacedim> Ellipsoid<dim,spacedim>::grid_transform(const Point<spacedim> &X){ // transform points X from sphere onto ellipsoid
double x,y,z;
x = a*X(0); y = b*X(1); z = c*X(2);
return Point<spacedim>(x,y,z);}
Point<3> grid_transform(const Point<3> &X){ // transform points X from sphere onto ellipsoid double x,y,z; double a = 1; double b = 3; double c = 5;
x = a*X(0); y = b*X(1); z = c*X(2);
return Point<3>(x,y,z);}
void assemble_mesh_and_manifold(){
const int dim = 2; const int spacedim = 3;
double a,b,c; a = 1; b=3; c=5;
Ellipsoid<dim,spacedim> ellipsoid(a,b,c);
Triangulation<dim,spacedim> tria;
// generate coarse spherical mesh GridGenerator::hyper_sphere (tria, Point<spacedim>(0.0,0.0,0.0), 1.0); for (Triangulation<dim,spacedim>::active_cell_iterator cell=tria.begin_active(); cell!=tria.end(); ++cell) cell->set_all_manifold_ids(0);
print_mesh_info(tria, "spherical_mesh.vtk");
GridTools::transform(&grid_transform, tria);
// //GridTools::transform(std_cxx11::bind(&Ellipsoid<dim,spacedim>::grid_transform,std_cxx11::cref(ellipsoid),std_cxx11::_1), tria); // error when trying to bind to member function in same way as step-53
tria.set_manifold(0,ellipsoid);
tria.refine_global(3);
print_mesh_info(tria, "ellipsoidal_mesh.vtk");
}
virtual std::unique_ptr<Manifold<dim,spacedim>> clone() const override;
virtual Point<spacedim> get_intermediate_point(
const Point<spacedim> &p1,
const Point<spacedim> &p2,
const double weight) const override;
virtual void get_new_points(
const ArrayView<const Point<spacedim>> &surrounding_points,
const Table<2,double> &weights,
ArrayView<Point<spacedim>> new_points) const override;
virtual Point<spacedim> get_new_point(
const ArrayView<const Point<spacedim>> &vertices,
const ArrayView<const double> &weights) const override;
/*
* map a (cartesian) point on a sphere to a point on an ellipsoid
*/
Point<spacedim> push_forward(const Point<spacedim> &space_point) const;
/*
* map a (cartesian) point on an ellipsoid to a point on a sphere
*/
Point<spacedim> pull_back(const Point<spacedim> &space_point) const;
> To unsubscribe from this group and stop receiving emails from it, send an email to dea...@googlegroups.com.
get_intermediate_point
, get_new_point and
get_new_points. I am not sure which member functions I need to overload if I derive my from class SphericalManifold. I am also not sure if I should derive my class from SphericalManifold or Manifold. It would be great if you could give some advice.
Best wishes,
Sebastian