/**
 * Example 1
 * =========
 * In this example show how to construct a curved grid from a reference grid. In the concrete
 * setup we start with a 2d structured grid and make a torus parametrization. The resulting
 * curved grid in then written to a VTK file by using a subsampling VTK writer.
 **/

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <bitset>
#include <cmath>

#include <dune/common/parallel/mpihelper.hh>
#include <dune/curvedgrid/curvedgrid.hh>
#include <dune/grid/yaspgrid.hh>
#include <dune/grid/io/file/vtk.hh>

using namespace Dune;

int main(int argc, char** argv)
{
  MPIHelper::instance(argc, argv);

  // 1. Construct a (periodic) reference grid [0,2pi]x[0,2pi]
  Dune::YaspGrid<2> refGrid{ {2.0*M_PI, 2.0*M_PI}, {8, 16}, std::bitset<2>("11") };

  // 2. Define the geometry mapping
  auto torus = [r1=2.0,r2=1.0](FieldVector<double,2> const& u) -> FieldVector<double,3> {
    return {
      (r1 + r2*std::cos(u[0])) * std::cos(u[1]),
      (r1 + r2*std::cos(u[0])) * std::sin(u[1]),
            r2*std::sin(u[0])
    };
  };

  // 3. Wrap the reference grid to build a curved grid, with Lagrange elements of order 3
  CurvedGrid grid{refGrid, torus, 3};

  // 4. Write grid to vtu file
  SubsamplingVTKWriter writer{grid.leafGridView(), refinementIntervals(3)};
  writer.write("torus");
}