Hi Thomas, hi Luca,
I would like to re-generate the ellipsoidal with deal.ii 9.0.1 but the
interfaces of the SphericalManifold class have changed in some release. So
I tried to re-implement the following methods
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
;
and two additional methods for the mapping from ellipsoid to sphere:
/*
* 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
;
Somehow, my implementation does not work well and the mesh is distorted
especially for points on the y- and z-axis. I am actually using the
ellipsoid as test case and would like generate a mesh consisting of a
sphere with (spherical harmonic) boundary topography.
Does anyone know what is going wrong here and the code by Thomas may used
in a newer version of deal.ii?
Best wishes,
Sebastian
Am Dienstag, 9. August 2016 19:04:07 UTC+2 schrieb thomas stephens:
>
> Luca, Thank you for the help.
>
> I now have a working Ellipsoid class:
>
> 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;
>
> };
>
>
> with member functions:
>
> 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);
> }
>
> along with the non-member function grid_transform() (which should not be
> necessary, but I cannot seem to bind the member function
> Ellipsoid<dim,spacedim>::grid_transform() to an instance of Ellipsoid and a
> dummy variable, as is done in step-53)
>
> 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);
> }
>
>
>
> At any rate, this can all be scripted using the following:
>
> 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");
>
> }
>
>
> I have attached the entire .cc file, and the output from the above code
> looks great:
>
>
> <https://lh3.googleusercontent.com/-bwkb9gP-gMw/V6oMwm7nLLI/AAAAAAAAFSU/dWS9t96oEQIsqQPjWEpWfQbPmEMoQBxAwCLcB/s1600/refined_ellipsoidal_mesh0000.png>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> On Tuesday, August 9, 2016 at 3:56:58 AM UTC-4, Luca Heltai wrote:
>>
>> There is nothing wrong with what you are doing.
>>
>> The problem is in the nature of your Manifold, since it contains 3
>> singular points. The first is the center of the ellipsoid, while the second
>> and third are the north and south poles.
>>
>> Try attaching a SphericalManifold to your deformed grid, and see if you
>> like the result. If you do, then hack the SphericalManifold. I don’t know
>> what version of deal.II you are using. Assuming you are not using the
>> latest dev, if you open up the definition of spherical manifold in
>> manifold_lib.cc, you’ll see that SphericalManifold::get_new_point does
>> something special in the case spacedim == 3, i.e., SphericalManifold is not
>> *really* a ChartManifold in 3d.
>>
>> In this case the ChartManifold mechanism cannot be used for the reason
>> above.
>>
>> A quick explanation why things are not working:
>>
>> Consider the top cell, and let us assume for a second that the north pole
>> (z=z_max) is in the center of the cell, and that the four vertices of your
>> ellipsoid lie at the same z (z=h < z_max). When you transform using
>> ChartManifold, the z gets mapped to the angle phi, and every point of the
>> cell will have the same angle phi, and different theta. If you take the
>> average of the four points in the chart manifold coordinates, you’ll see
>> that the average will have an average theta (which is ok), but it will also
>> have the same phi of the four surrounding points… in other words, the
>> average will not be in the middle of the four points (that should be the
>> north pole: a singularity of your mapping). It will lye on the same
>> latitude of the other four points.
>>
>> ChartManifold is doing exactly what you asked it to do, but in the case
>> of maps with singularities, you should not use ChartManifold…
>>
>> My suggestion is to derive EllipsoidManifold from SphericalManifold, and
>> then overload directly get_new_point, by calling internally get_new_point
>> of spherical manifold, and then projecting the result to the ellipsoid...
>>
>> Best,
>>
>> Luca.
>>
>> > On 09 Aug 2016, at 24:13, thomas stephens <[email protected]> wrote:
>> >
>> >
>> >
>> > I am trying to obtain the mesh for a codimension-1 ellipsoid and attach
>> an ellipsoidal manifold to it in order to refine the mesh. My strategy is
>> failing and I have a few questions.
>> >
>> > My strategy:
>> > some definitions:
>> > dim=2; spacedim=3; chartdim=spacedim-1; a=1; b=2;c=3;
>> >
>> > Set up codimension-1 Triangulation:
>> >
>> > Triangulation<dim,spacedim> tria;
>> >
>> >
>> > Use GridGenerator::hyper_sphere() to obtain a codimension 1 mesh:
>> >
>> >
>> > GridGenerator::hyper_sphere (tria, Point<spacedim>(0.0,0.0,0.0), 1.0);
>> >
>> > Use GridTools::transform() to map triangulation of sphere onto
>> triangulation of ellipsoid (I have a question about this, see below).
>> Here, grid_transform has signature Point<spacedim> grid_transform(const
>> Point<spacedim> X)
>> >
>> > GridTools::transform(&grid_transform, tria);
>> >
>> > Next, subclass ChartManifold<dim,spacedim,chartdim> in order to obtain
>> a push_forward() and a pull_back() function for my parametric ellipsoidal
>> manifold description. Then attach that manifold to the triangulation:
>> >
>> > Ellipsoid<dim,spacedim,chartdim> ellipsoid(a,b,c);
>> > tria.set_manifold(0,ellipsoid);
>> >
>> > Now refine the triangulation in order to see a refined ellipsoidal
>> mesh:
>> >
>> > tria.refine_global(1);
>> >
>> > The Result: Complete garbage! I also don't really have an idea why
>> this is not working - I've checked the dimensions on my push_forward() and
>> pull_back() functions, I think that I'm setting the periodicity correctly
>> in my ChartManifold superclass, and I've also checked that my simple math
>> is okay. Let me know what other information would be useful. Below is
>> the refined mesh for a=b=c=1. This should just be a sphere.
>> >
>> >
>> >
>> >
>> > The code:
>> > 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();
>> > }
>> >
>> > Attached is the .vtk of my refined ellipsoidal mesh and the .cc file
>> that generates this output (mostly reproduced above.
>> >
>> > Thank you,
>> > Tom
>> >
>> > --
>> > The deal.II project is located at http://www.dealii.org/
>> > For mailing list/forum options, see
>> https://groups.google.com/d/forum/dealii?hl=en
>> > ---
>> > You received this message because you are subscribed to the Google
>> Groups "deal.II User Group" group.
>> > To unsubscribe from this group and stop receiving emails from it, send
>> an email to [email protected].
>> > For more options, visit https://groups.google.com/d/optout.
>> > <sphere_to_ellipsoid.cc><ellipsoidal_mesh.vtk>
>>
>>
--
The deal.II project is located at http://www.dealii.org/
For mailing list/forum options, see
https://groups.google.com/d/forum/dealii?hl=en
---
You received this message because you are subscribed to the Google Groups
"deal.II User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/dealii/211cd6b5-3810-4684-89a4-6c43093e125d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
#include <deal.II/grid/tria.h>
#include <deal.II/grid/grid_out.h>
#include <deal.II/grid/manifold.h>
#include <deal.II/grid/grid_generator.h>
#include <deal.II/grid/manifold_lib.h>
#include <deal.II/grid/grid_tools.h>
#include <boost/math/special_functions.hpp>
#include <iostream>
#include <fstream>
#include <functional>
namespace EllipsoidalTest
{
using namespace dealii;
template<int dim,int spacedim>
class EllipsoidalManifold: public SphericalManifold<dim,spacedim>
{
public:
EllipsoidalManifold();
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;
/*
* mapping a (cartesian) point on a sphere to an ellipsoid
*/
Point<spacedim> push_forward(const Point<spacedim> &space_point) const;
private:
/*
* mapping a (cartesian) point on an ellipsoid to a sphere
*/
Point<spacedim> pull_back(const Point<spacedim> &space_point) const;
const double a = 1.0;
const double b = 2.0;
const double c = 3.0;
double max_axis;
const Point<spacedim> center;
};
template<int dim, int spacedim>
EllipsoidalManifold<dim,spacedim>::EllipsoidalManifold
()
:
SphericalManifold<dim,spacedim>(center),
center()
{
max_axis = std::max(std::max(a,b),c);
}
template <int dim, int spacedim>
std::unique_ptr<Manifold<dim, spacedim>>
EllipsoidalManifold<dim,spacedim>::clone() const
{
return std::make_unique<EllipsoidalManifold<dim,spacedim>>();
}
template <int dim, int spacedim>
Point<spacedim> EllipsoidalManifold<dim,spacedim>::get_intermediate_point
(const Point<spacedim> &p1,
const Point<spacedim> &p2,
const double weight) const
{
const Point<spacedim> p1_on_sphere = pull_back(p1);
const Point<spacedim> p2_on_sphere = pull_back(p2);
const Point<spacedim> intermediate_point_on_sphere
= SphericalManifold<dim,spacedim>::get_intermediate_point
(p1_on_sphere,
p2_on_sphere,
weight);
return push_forward(intermediate_point_on_sphere);
}
template <int dim, int spacedim>
void EllipsoidalManifold<dim,spacedim>::get_new_points
(const ArrayView<const Point<spacedim>> &surrounding_points,
const Table<2,double> &weights,
ArrayView<Point<spacedim>> new_points) const
{
std::vector<Point<spacedim>> surrounding_points_on_sphere;
for (typename ArrayView<const Point<spacedim>>::const_iterator
it = surrounding_points.cbegin();
it != surrounding_points.cend(); ++it)
{
const Point<spacedim> surrounding_point_on_sphere
= pull_back(*it);
surrounding_points_on_sphere.push_back(surrounding_point_on_sphere);
}
AssertDimension(surrounding_points_on_sphere.size(),
surrounding_points.size());
SphericalManifold<dim,spacedim>::get_new_points(
make_array_view(surrounding_points_on_sphere,
0,
surrounding_points_on_sphere.size()),
weights,
new_points);
for (unsigned int i=0; i<new_points.size(); ++i)
new_points[i] = push_forward(new_points[i]);
}
template <int dim, int spacedim>
Point<spacedim> EllipsoidalManifold<dim,spacedim>::get_new_point
(const ArrayView<const Point<spacedim>> &vertices,
const ArrayView<const double> &weights) const
{
std::vector<Point<spacedim>> vertices_on_sphere;
typename ArrayView<const Point<spacedim>>::const_iterator
it = vertices.cbegin(),
endit = vertices.cend();
for (; it!=endit; ++it)
{
const Point<spacedim> vertex_on_sphere = pull_back(*it);
vertices_on_sphere.push_back(vertex_on_sphere);
}
AssertDimension(vertices_on_sphere.size(),vertices.size());
const Point<spacedim> new_point_on_sphere
= SphericalManifold<dim,spacedim>::get_new_point(
make_array_view(vertices_on_sphere,
0,
vertices_on_sphere.size()),
weights);
return push_forward(new_point_on_sphere);
}
template<>
Point<3> EllipsoidalManifold<3,3>::pull_back
(const Point<3> &point_ellipsoid) const
{
const Point<3> point_on_sphere(point_ellipsoid(0) / a,
point_ellipsoid(1) / b,
point_ellipsoid(2) / c);
return point_on_sphere;
}
template<>
Point<3> EllipsoidalManifold<3,3>::push_forward
(const Point<3> &point_on_sphere) const
{
const Point<3> point_on_ellipsoid(point_on_sphere(0) * a,
point_on_sphere(1) * b,
point_on_sphere(2) * c);
return point_on_ellipsoid;
}
template<>
Point<3> EllipsoidalManifold<2,3>::pull_back
(const Point<3> &point_ellipsoid) const
{
const Point<3> point_on_sphere(point_ellipsoid(0) / a,
point_ellipsoid(1) / b,
point_ellipsoid(2) / c);
return point_on_sphere;
}
template<>
Point<3> EllipsoidalManifold<2,3>::push_forward
(const Point<3> &point_on_sphere) const
{
const Point<3> point_on_ellipsoid(point_on_sphere(0) * a,
point_on_sphere(1) * b,
point_on_sphere(2) * c);
return point_on_ellipsoid;
}
void run ()
{
const unsigned int dim = 2;
const unsigned int spacedim = 3;
Triangulation<dim,spacedim> triangulation;
EllipsoidalManifold<dim,spacedim> ellipsoid;
GridGenerator::hyper_sphere(triangulation,
Point<spacedim>(),
1.0);
GridTools::transform(
std::bind(&EllipsoidalManifold<dim,spacedim>::push_forward,
std::cref(ellipsoid),
std::placeholders::_1),
triangulation);
{
const std::string filename = "initial-mesh.vtu";
std::ofstream out (filename.c_str());
GridOut grid_out;
grid_out.write_vtu (triangulation, out);
}
triangulation.reset_all_manifolds();
triangulation.set_all_manifold_ids(0);
triangulation.set_all_manifold_ids_on_boundary(0);
triangulation.set_manifold(0, ellipsoid);
triangulation.refine_global(2);
{
const std::string filename = "final-mesh.vtu";
std::ofstream out (filename.c_str());
GridOut grid_out;
grid_out.write_vtu (triangulation, out);
}
}
}
int main ()
{
try
{
EllipsoidalTest::run();
}
catch (std::exception &exc)
{
std::cerr << std::endl << std::endl
<< "----------------------------------------------------"
<< std::endl;
std::cerr << "Exception on processing: " << std::endl
<< exc.what() << std::endl
<< "Aborting!" << std::endl
<< "----------------------------------------------------"
<< std::endl;
return 1;
}
catch (...)
{
std::cerr << std::endl << std::endl
<< "----------------------------------------------------"
<< std::endl;
std::cerr << "Unknown exception!" << std::endl
<< "Aborting!" << std::endl
<< "----------------------------------------------------"
<< std::endl;
return 1;
}
}