22template<
class real_type>
25 Interpolate(
const thrust::host_vector<real_type>& fZeta,
26 const thrust::host_vector<real_type>& fEta,
30 g_(g2d), zeta1_(g2d.x1()), eta1_(g2d.y1()){}
31 void operator()(real_type t,
const std::array<real_type,2>& zeta, std::array<real_type,2>& fZeta)
33 fZeta[0] =
interpolate(
dg::lspace, iter0_, fmod( zeta[0]+zeta1_, zeta1_), fmod( zeta[1]+eta1_, eta1_), g_);
34 fZeta[1] =
interpolate(
dg::lspace, iter1_, fmod( zeta[0]+zeta1_, zeta1_), fmod( zeta[1]+eta1_, eta1_), g_);
38 void operator()(real_type t,
const std::array<thrust::host_vector<real_type>,2 >& zeta, std::array< thrust::host_vector<real_type>,2 >& fZeta)
40 for(
unsigned i=0; i<zeta[0].size(); i++)
42 fZeta[0][i] =
interpolate(
dg::lspace, iter0_, fmod( zeta[0][i]+zeta1_, zeta1_), fmod( zeta[1][i]+eta1_, eta1_), g_);
43 fZeta[1][i] =
interpolate(
dg::lspace, iter1_, fmod( zeta[0][i]+zeta1_, zeta1_), fmod( zeta[1][i]+eta1_, eta1_), g_);
47 thrust::host_vector<real_type> iter0_;
48 thrust::host_vector<real_type> iter1_;
50 real_type zeta1_, eta1_;
54template<
class real_type>
63 for(
unsigned i=0; i<eta.size(); i++)
91template<
class real_type>
93 const thrust::host_vector<real_type>& etaV,
94 const thrust::host_vector<real_type>& v_vec,
95 thrust::host_vector<real_type>& eta,
99 Interpolate<real_type> iter( thrust::host_vector<real_type>( etaV.size(),
101 eta.resize( v_vec.size());
102 thrust::host_vector<real_type> eta_old(v_vec.size(), 0), eta_diff( eta_old);
103 std::array<real_type,2> begin{ 0, 0}, end(begin), temp(begin);
104 begin[0] = 0., begin[1] = 0.;
106 real_type eps = 1e10, eps_old=2e10;
107 using Vec = std::array<double,2>;
110 while( (eps < eps_old||eps > 1e-7) && eps > 1e-12)
113 eps_old = eps, eta_old = eta;
114 odeint.integrate_steps( 0, begin, v_vec[0], end, steps);
116 for(
unsigned i=1; i<v_vec.size(); i++)
119 odeint.integrate_steps( v_vec[i-1], temp, v_vec[i], end, steps);
123 odeint.integrate_steps( v_vec[v_vec.size()-1], begin, 2.*M_PI, end, steps);
132template<
class real_type>
134 const thrust::host_vector<real_type>& zetaU,
135 const thrust::host_vector<real_type>& etaU,
136 const thrust::host_vector<real_type>& u_vec,
137 const thrust::host_vector<real_type>& zeta_init,
138 const thrust::host_vector<real_type>& eta_init,
139 thrust::host_vector<real_type>& zeta,
140 thrust::host_vector<real_type>& eta,
144 Interpolate<real_type> inter( zetaU, etaU, g2d);
146 real_type eps = 1e10, eps_old=2e10;
147 std::array<thrust::host_vector<real_type>,2 > begin;
148 begin[0] = zeta_init, begin[1] = eta_init;
150 std::array<thrust::host_vector<real_type>,2 > end(begin), temp(begin);
151 unsigned sizeU = u_vec.size(), sizeV = zeta_init.size();
152 unsigned size2d = sizeU*sizeV;
153 zeta.resize(size2d), eta.resize(size2d);
154 real_type u0=0, u1 = u_vec[0];
155 thrust::host_vector<real_type> zeta_old(zeta), zeta_diff( zeta), eta_old(eta), eta_diff(eta);
156 using Vec = std::array<thrust::host_vector<real_type>,2>;
159 while( (eps < eps_old || eps > 1e-6) && eps > 1e-7)
161 zeta_old = zeta, eta_old = eta; eps_old = eps;
164 for(
unsigned i=0; i<sizeU; i++)
166 u0 = i==0 ? 0 : u_vec[i-1], u1 = u_vec[i];
167 odeint.integrate_steps( u0, temp, u1, end, N);
168 for(
unsigned j=0; j<sizeV; j++)
170 unsigned idx = j*sizeU+i;
171 zeta[idx] = end[0][j], eta[idx] = end[1][j];
186template<
class Geometry,
class container>
188 const container& u_zeta,
189 const container& u_eta,
190 thrust::host_vector<double>& u_x,
191 thrust::host_vector<double>& u_y,
194 u_x.resize( u_zeta.size()), u_y.resize( u_zeta.size());
195 thrust::host_vector<double> uh_zeta, uh_eta;
219template <
class IMatrix = dg::IHMatrix,
class Matrix = dg::HMatrix,
class container = dg::HVec>
236 Hector(
const CylindricalFunctorsLvl2& psi,
double psi0,
double psi1,
double X0,
double Y0,
unsigned n = 13,
unsigned Nx = 2,
unsigned Ny = 10,
double eps_u = 1e-10,
bool verbose=
false) :
240 container u = construct_grid_and_u(
dg::geo::Constant(1), dg::geo::detail::LaplacePsi(psi), psi0, psi1, X0, Y0, eps_u , verbose);
242 m_conformal=m_orthogonal=
true;
267 Hector(
const CylindricalFunctorsLvl2& psi,
const CylindricalFunctorsLvl1& chi,
double psi0,
double psi1,
double X0,
double Y0,
unsigned n = 13,
unsigned Nx = 2,
unsigned Ny = 10,
double eps_u = 1e-10,
bool verbose=
false) :
270 dg::geo::detail::LaplaceAdaptPsi lapAdaPsi( psi, chi);
272 container u = construct_grid_and_u( chi.
f(), lapAdaPsi, psi0, psi1, X0, Y0, eps_u , verbose);
301 double psi0,
double psi1,
double X0,
double Y0,
unsigned n = 13,
unsigned Nx = 2,
unsigned Ny = 10,
double eps_u = 1e-10,
bool verbose=
false) :
305 container u = construct_grid_and_u( psi, chi,
306 psi0, psi1, X0, Y0, eps_u , verbose);
307 construct( u, psi0, psi1, chi.
xx(), chi.
xy(), chi.
yy(), verbose);
308 m_orthogonal=m_conformal=
false;
328 virtual double do_width() const override final {
return m_lu;}
329 virtual double do_height() const override final {
return 2.*
M_PI;}
335 virtual bool do_isOrthogonal() const override final {
return m_orthogonal;}
336 virtual void do_generate(
const thrust::host_vector<double>& u1d,
337 const thrust::host_vector<double>& v1d,
338 thrust::host_vector<double>& x,
339 thrust::host_vector<double>& y,
340 thrust::host_vector<double>& ux,
341 thrust::host_vector<double>& uy,
342 thrust::host_vector<double>& vx,
343 thrust::host_vector<double>& vy)
const override final
345 thrust::host_vector<double> eta_init, zeta, eta;
346 detail::compute_zev( m_etaV, v1d, eta_init, m_g2d);
347 thrust::host_vector<double> zeta_init( eta_init.size(), 0.);
348 detail::construct_grid( m_zetaU, m_etaU, u1d, zeta_init, eta_init, zeta, eta, m_g2d);
350 for(
unsigned i=0; i<eta.size(); i++)
351 eta[i] = fmod(eta[i]+2.*M_PI, 2.*M_PI);
372 container construct_grid_and_u(
const CylindricalFunctor& chi,
const CylindricalFunctor& lapChiPsi,
double psi0,
double psi1,
double X0,
double Y0,
double eps_u ,
bool verbose)
375 double eps = 1e10, eps_old = 2e10;
379 ellipticD_old.set_chi( adapt);
384 unsigned number = invert_old.solve( ellipticD_old, u_old, lapu, ellipticD_old.precond(), ellipticD_old.weights(), eps_u);
385 if(verbose) std::cout <<
"Nx "<<m_g2d.
Nx()<<
" Ny "<<m_g2d.
Ny()<<std::flush;
386 if(verbose) std::cout <<
" iter "<<number<<
" error "<<eps<<
"\n";
387 while( (eps < eps_old||eps > 1e-7) && eps > eps_u)
391 if(verbose) std::cout <<
"Nx "<<m_g2d.
Nx()<<
" Ny "<<m_g2d.
Ny()<<std::flush;
394 ellipticD.set_chi( adapt);
403 number =
invert.solve( ellipticD, u, lapu, ellipticD.precond(), ellipticD.weights(), 0.1*eps_u);
406 if(verbose) std::cout <<
" iter "<<number<<
" error "<<eps<<
"\n";
414 container construct_grid_and_u(
const CylindricalFunctorsLvl2& psi,
415 const CylindricalSymmTensorLvl1& chi,
double psi0,
double psi1,
double X0,
double Y0,
double eps_u,
bool verbose )
417 dg::geo::detail::LaplaceChiPsi lapChiPsi( psi, chi);
419 double eps = 1e10, eps_old = 2e10;
425 ellipticD_old.set_chi( chi_t);
430 unsigned number = invert_old.solve( ellipticD_old, u_old, lapu, ellipticD_old.precond(), ellipticD_old.weights(), eps_u);
431 while( (eps < eps_old||eps > 1e-7) && eps > eps_u)
435 if(verbose) std::cout <<
"Nx "<<m_g2d.
Nx()<<
" Ny "<<m_g2d.
Ny()<<std::flush;
439 ellipticD.set_chi( chi_t );
448 number =
invert.solve( ellipticD, u, lapu, ellipticD.precond(), ellipticD.weights(), 0.1*eps_u);
451 if(verbose) std::cout <<
" iter "<<number<<
" error "<<eps<<
"\n";
464 container u_zeta(u), u_eta(u);
475 container temp_zeta(u), temp_eta(u);
477 container temp_scalar(u);
479 container zetaU=temp_zeta, etaU=temp_eta;
484 container etaVinv(u_zeta), etaV(etaVinv);
488 thrust::host_vector<double> etaVinv_h;
491 container v_zeta(u), v_eta(u);
498 m_c0 = fabs( detail::construct_c0( etaVinv_h, m_g2d));
499 if( psi1 < psi0) m_c0*=-1;
500 m_lu = m_c0*(psi1-psi0);
501 if(verbose) std::cout <<
"c0 is "<<m_c0<<
"\n";
517 bool m_conformal, m_orthogonal;
519 thrust::host_vector<double> m_ux, m_uy, m_vx, m_vy;
520 thrust::host_vector<double> m_etaV, m_zetaU, m_etaU;
void assign(const from_ContainerType &from, ContainerType &to, Params &&... ps)
static DG_DEVICE double cooX1d(double x)
static DG_DEVICE double zero(double x)
void plus(ContainerType &x, get_value_type< ContainerType > alpha)
void transform(const ContainerType1 &x, ContainerType &y, UnaryOp op)
void axpby(get_value_type< ContainerType > alpha, const ContainerType1 &x, get_value_type< ContainerType > beta, ContainerType &y)
void scal(ContainerType &x, get_value_type< ContainerType > alpha)
void pointwiseDivide(get_value_type< ContainerType > alpha, const ContainerType1 &x1, const ContainerType2 &x2, get_value_type< ContainerType > beta, ContainerType &y)
void pointwiseDot(get_value_type< ContainerType > alpha, const ContainerType1 &x1, const ContainerType2 &x2, get_value_type< ContainerType > beta, ContainerType &y)
get_value_type< ContainerType1 > dot(const ContainerType1 &x, const ContainerType2 &y)
void gemv(get_value_type< ContainerType1 > alpha, MatrixType &&M, const ContainerType1 &x, get_value_type< ContainerType1 > beta, ContainerType2 &y)
void symv(MatrixType &&M, const ContainerType1 &x, ContainerType2 &y)
get_value_type< MatrixType > dot(const ContainerType1 &x, const MatrixType &m, const ContainerType2 &y)
EllSparseBlockMat< real_type > dx(const aRealTopology2d< real_type > &g, bc bcx, direction dir=centered)
EllSparseBlockMat< real_type > dy(const aRealTopology2d< real_type > &g, bc bcy, direction dir=centered)
dg::Operator< T > invert(const dg::Operator< T > &in)
thrust::host_vector< real_type > evaluate(UnaryOp f, const RealGrid1d< real_type > &g)
RealCylindricalFunctor< double > CylindricalFunctor
Most of the times we use double.
Definition: fluxfunctions.h:50
MPI_Vector< thrust::host_vector< real_type > > weights(const aRealMPITopology2d< real_type > &g)
cusp::coo_matrix< int, real_type, cusp::host_memory > interpolation(const thrust::host_vector< real_type > &x, const RealGrid1d< real_type > &g, dg::bc bcx=dg::NEU, std::string method="dg")
real_type interpolate(dg::space sp, const thrust::host_vector< real_type > &v, real_type x, const RealGrid1d< real_type > &g, dg::bc bcx=dg::NEU)
thrust::host_vector< real_type > forward_transform(const thrust::host_vector< real_type > &in, const aRealTopology2d< real_type > &g)
thrust::host_vector< real_type > pullback(const Functor &f, const aRealGeometryX2d< real_type > &g)
void pushForwardPerp(const Functor1 &vR, const Functor2 &vZ, container &vx, container &vy, const Geometry &g)
void multiply2d(const ContainerTypeL &lambda, const SparseTensor< ContainerType0 > &t, const ContainerType1 &in0, const ContainerType2 &in1, const ContainerTypeM &mu, ContainerType3 &out0, ContainerType4 &out1)
ContainerType volume(const SparseTensor< ContainerType > &t)
IHMatrix_t< double > IHMatrix
thrust::host_vector< double > HVec
SparseTensor transpose() const
const container & value(size_t i, size_t j) const
std::vector< thrust::host_vector< real_type > > map() const
SparseTensor< thrust::host_vector< real_type > > metric() const
void multiplyCellNumbers(real_type fx, real_type fy)
Definition: fluxfunctions.h:114
This struct bundles a function and its first derivatives.
Definition: fluxfunctions.h:182
const CylindricalFunctor & f() const
Definition: fluxfunctions.h:203
This struct bundles a function and its first and second derivatives.
Definition: fluxfunctions.h:219
Definition: fluxfunctions.h:361
const CylindricalFunctor & yy() const
yy component
Definition: fluxfunctions.h:400
const CylindricalFunctor & xy() const
xy component
Definition: fluxfunctions.h:398
const CylindricalFunctor & xx() const
xy component
Definition: fluxfunctions.h:396
The High PrEcision Conformal grid generaTOR.
Definition: hector.h:221
bool isConformal() const
Definition: hector.h:326
Hector(const CylindricalFunctorsLvl2 &psi, const CylindricalFunctorsLvl1 &chi, double psi0, double psi1, double X0, double Y0, unsigned n=13, unsigned Nx=2, unsigned Ny=10, double eps_u=1e-10, bool verbose=false)
Construct an orthogonal grid with adaption.
Definition: hector.h:267
const dg::geo::CurvilinearGrid2d & internal_grid() const
Return the internally used orthogonal grid.
Definition: hector.h:324
Hector(const CylindricalFunctorsLvl2 &psi, double psi0, double psi1, double X0, double Y0, unsigned n=13, unsigned Nx=2, unsigned Ny=10, double eps_u=1e-10, bool verbose=false)
Construct a conformal grid.
Definition: hector.h:236
virtual Hector * clone() const override final
Abstract clone method that returns a copy on the heap.
Definition: hector.h:325
Hector(const CylindricalFunctorsLvl2 &psi, const CylindricalSymmTensorLvl1 &chi, double psi0, double psi1, double X0, double Y0, unsigned n=13, unsigned Nx=2, unsigned Ny=10, double eps_u=1e-10, bool verbose=false)
Construct a curvilinear grid with monitor metric.
Definition: hector.h:300
Same as the Ribeiro class just but uses psi as a flux label directly.
Definition: flux.h:238
The abstract generator base class.
Definition: generator.h:20