26 Fpsi(
const CylindricalFunctorsLvl1& psi,
const CylindricalSymmTensorLvl1& chi,
double x0,
double y0,
int firstline):
27 psip_(psi), fieldRZYTconf_(psi, x0, y0, chi),fieldRZYTequl_(psi, x0, y0, chi), fieldRZtau_(psi, chi)
29 X_init = x0, Y_init = y0;
30 while( fabs( psi.dfx()(X_init, Y_init)) <= 1e-10 && fabs( psi.dfy()( X_init, Y_init)) <= 1e-10)
32 m_firstline = firstline;
35 void find_initial(
double psi,
double& R_0,
double& Z_0)
38 std::array<double, 2> begin2d{ {0,0} }, end2d(begin2d), end2d_old(begin2d);
39 begin2d[0] = end2d[0] = end2d_old[0] = X_init;
40 begin2d[1] = end2d[1] = end2d_old[1] = Y_init;
41 double eps = 1e10, eps_old = 2e10;
42 while( (eps < eps_old || eps > 1e-7) && eps > 1e-14)
44 eps_old = eps; end2d_old = end2d;
46 double psi0 = psip_.f()(X_init, Y_init);
47 using Vec = std::array<double,2>;
49 "Feagin-17-8-10", {0,0}), fieldRZtau_);
50 odeint.integrate_steps( psi0, begin2d, psi, end2d, N);
51 eps = sqrt( (end2d[0]-end2d_old[0])*(end2d[0]-end2d_old[0]) +
52 (end2d[1]-end2d_old[1])*(end2d[1]-end2d_old[1]));
54 X_init = R_0 = end2d_old[0], Y_init = Z_0 = end2d_old[1];
58 double construct_f(
double psi,
double& R_0,
double& Z_0)
60 find_initial( psi, R_0, Z_0);
61 std::array<double, 3> begin{ {0,0,0} }, end(begin);
62 begin[0] = R_0, begin[1] = Z_0;
63 double eps = 1e10, eps_old = 2e10;
65 while( (eps < eps_old || eps > 1e-7)&& eps > 1e-14)
68 using Vec = std::array<double,3>;
78 eps = sqrt( (end[0]-begin[0])*(end[0]-begin[0]) + (end[1]-begin[1])*(end[1]-begin[1]));
81 double f_psi = 2.*
M_PI/end[2];
85 double operator()(
double psi)
88 return construct_f( psi, R_0, Z_0);
93 double X_init, Y_init;
94 CylindricalFunctorsLvl1 psip_;
95 CylindricalSymmTensorLvl1 chi_;
96 dg::geo::ribeiro::FieldRZYT fieldRZYTconf_;
97 dg::geo::equalarc::FieldRZYT fieldRZYTequl_;
98 dg::geo::FieldRZtau fieldRZtau_;
104template<
class real_type>
105void compute_rzy(
const CylindricalFunctorsLvl1& psi,
const CylindricalSymmTensorLvl1& chi,
106 const thrust::host_vector<real_type>& y_vec,
107 thrust::host_vector<real_type>& r,
108 thrust::host_vector<real_type>& z,
109 real_type R_0, real_type Z_0, real_type f_psi,
int mode )
112 thrust::host_vector<real_type> r_old(y_vec.size(), 0), r_diff( r_old);
113 thrust::host_vector<real_type> z_old(y_vec.size(), 0), z_diff( z_old);
114 r.resize( y_vec.size()),
z.resize(y_vec.size());
115 std::array<real_type,2> begin{ {0,0} }, end(begin), temp(begin);
116 begin[0] = R_0, begin[1] = Z_0;
118 dg::geo::ribeiro::FieldRZY fieldRZYconf(psi, chi);
119 dg::geo::equalarc::FieldRZY fieldRZYequi(psi, chi);
120 fieldRZYconf.set_f(f_psi);
121 fieldRZYequi.set_f(f_psi);
123 real_type eps = 1e10, eps_old=2e10;
124 while( (eps < eps_old||eps > 1e-7) && eps > 1e-14)
127 eps_old = eps, r_old = r, z_old =
z;
128 using Vec = std::array<real_type,2>;
135 odeint.integrate_steps( 0., begin, y_vec[0], end, steps);
136 r[0] = end[0],
z[0] = end[1];
137 for(
unsigned i=1; i<y_vec.size(); i++)
140 odeint.integrate_steps( y_vec[i-1], temp, y_vec[i], end, steps);
141 r[i] = end[0],
z[i] = end[1];
150 eps = sqrt( er + ez)/sqrt(ar+az);
153 r = r_old,
z = z_old;
161 Nemov(
const CylindricalFunctorsLvl2 psi,
const CylindricalSymmTensorLvl1& chi,
double f0,
int mode):
162 f0_(f0), mode_(mode),
163 psip_(psi), chi_(chi), lapPsi_(psi,chi) { }
165 const thrust::host_vector<double>& r_init,
166 const thrust::host_vector<double>& z_init,
167 thrust::host_vector<double>& h_init)
171 unsigned size = r_init.size();
172 h_init.resize( size);
173 for(
unsigned i=0; i<size; i++)
179 double x = r_init[i],
y = z_init[i];
180 double psipR = psip_.dfx()(
x,
y), psipZ = psip_.dfy()(
x,
y);
181 double chiRR = chi_.xx()(
x,
y),
182 chiRZ = chi_.xy()(
x,
y),
183 chiZZ = chi_.yy()(
x,
y);
184 double psip2 = chiRR*psipR*psipR + 2.*chiRZ*psipR*psipZ + chiZZ*psipZ*psipZ;
185 h_init[i] = f0_/sqrt(psip2);
194 void operator()(
double t,
const std::array<thrust::host_vector<double>,3 >& y, std::array<thrust::host_vector<double>,3>& yp)
197 unsigned size =
y[0].size();
198 for(
unsigned i=0; i<size; i++)
200 double xx =
y[0][i], yy =
y[1][i];
201 double psipR = psip_.dfx()(xx, yy), psipZ = psip_.dfy()(xx,yy);
202 double chiRR = chi_.xx()(xx, yy),
203 chiRZ = chi_.xy()(xx, yy),
204 chiZZ = chi_.yy()(xx, yy);
205 double psip2 = chiRR*psipR*psipR + 2.*chiRZ*psipR*psipZ + chiZZ*psipZ*psipZ;
206 yp[0][i] = (chiRR*psipR + chiRZ*psipZ)/psip2/f0_;
207 yp[1][i] = (chiRZ*psipR + chiZZ*psipZ)/psip2/f0_;
208 yp[2][i] =
y[2][i]*( - lapPsi_(xx,yy) )/psip2/f0_;
216 CylindricalFunctorsLvl2 psip_;
217 CylindricalSymmTensorLvl1 chi_;
218 dg::geo::detail::LaplaceChiPsi lapPsi_;
222void construct_rz( Nemov nemov,
224 const thrust::host_vector<double>& x_vec,
225 const thrust::host_vector<double>& r_init,
226 const thrust::host_vector<double>& z_init,
227 thrust::host_vector<double>& r,
228 thrust::host_vector<double>& z,
229 thrust::host_vector<double>& h
233 double eps = 1e10, eps_old=2e10;
234 std::array<thrust::host_vector<double>,3> begin;
235 thrust::host_vector<double> h_init( r_init.size(), 0.);
236 nemov.initialize( r_init, z_init, h_init);
237 begin[0] = r_init, begin[1] = z_init, begin[2] = h_init;
239 std::array<thrust::host_vector<double>,3> end(begin), temp(begin);
240 unsigned sizeX = x_vec.size(), sizeY = r_init.size();
241 unsigned size2d = x_vec.size()*r_init.size();
242 r.resize(size2d),
z.resize(size2d), h.resize(size2d);
243 double x0=x_0, x1 = x_vec[0];
244 thrust::host_vector<double> r_new(r_init), r_old(r_init), r_diff(r_init);
245 thrust::host_vector<double> z_new(z_init), z_old(z_init), z_diff(z_init);
246 thrust::host_vector<double> h_new(h_init);
247 for(
unsigned i=0; i<sizeX; i++)
250 eps = 1e10, eps_old=2e10;
252 while( (eps < eps_old || eps > 1e-6) && eps > 1e-13)
254 r_old = r_new, z_old = z_new; eps_old = eps;
258 x0 = i==0?x_0:x_vec[i-1], x1 = x_vec[i];
260 using Vec = std::array<thrust::host_vector<double>,3>;
264 for(
unsigned j=0; j<sizeY; j++)
266 r_new[j] = end[0][j], z_new[j] = end[1][j];
267 h_new[j] = end[2][j];
286 r_new = r_old , z_new = z_old;
291 if( (eps > eps_old && N > 1024 && eps > 1e-6) || N > 64000)
293 "Grid generator encountered loss of convergence integrating from x = "
294 <<x0<<
" to x = "<<x1);
296 for(
unsigned j=0; j<sizeY; j++)
298 unsigned idx = sizeX*j+i;
299 r[idx] = r_new[j],
z[idx] = z_new[j], h[idx] = h_new[j];
343 psi_1,
double x0,
double y0,
double psi_firstline,
int mode =0
366 double x0,
double y0,
double psi_firstline,
int mode = 0
370 assert( psi_1 != psi_0);
372 orthogonal::detail::Fpsi fpsi(psi, chi, x0, y0, mode);
373 f0_ = fabs( fpsi.construct_f( psi_firstline, R0_, Z0_));
374 if( psi_1 < psi_0) f0_*=-1;
375 lz_ = f0_*(psi_1-psi_0);
376 m_orthogonal =
false;
377 m_zeta_first = f0_*(psi_firstline-psi_0);
385 double f0()
const{
return f0_;}
390 virtual double do_width() const override final{
return lz_;}
391 virtual double do_height() const override final{
return 2.*
M_PI;}
392 virtual bool do_isOrthogonal() const override final{
return m_orthogonal;}
393 virtual void do_generate(
394 const thrust::host_vector<double>& zeta1d,
395 const thrust::host_vector<double>& eta1d,
396 thrust::host_vector<double>& x,
397 thrust::host_vector<double>& y,
398 thrust::host_vector<double>& zetaX,
399 thrust::host_vector<double>& zetaY,
400 thrust::host_vector<double>& etaX,
401 thrust::host_vector<double>& etaY)
const override final
403 thrust::host_vector<double> r_init, z_init;
404 orthogonal::detail::compute_rzy( psi_, chi_, eta1d, r_init, z_init,
405 R0_, Z0_, f0_, m_firstline);
406 orthogonal::detail::Nemov nemov(psi_, chi_, f0_, m_firstline);
407 thrust::host_vector<double> h;
408 orthogonal::detail::construct_rz(nemov, m_zeta_first, zeta1d, r_init,
410 unsigned size =
x.size();
411 for(
unsigned idx=0; idx<size; idx++)
413 double psipR = psi_.
dfx()(
x[idx],
y[idx]);
414 double psipZ = psi_.
dfy()(
x[idx],
y[idx]);
415 double chiRR = chi_.
xx()(
x[idx],
y[idx]),
416 chiRZ = chi_.
xy()(
x[idx],
y[idx]),
417 chiZZ = chi_.
yy()(
x[idx],
y[idx]);
418 zetaX[idx] = f0_*psipR;
419 zetaY[idx] = f0_*psipZ;
420 etaX[idx] = -h[idx]*(chiRZ*psipR + chiZZ*psipZ);
421 etaY[idx] = +h[idx]*(chiRR*psipR + chiRZ*psipZ);
424 CylindricalFunctorsLvl2 psi_;
425 CylindricalSymmTensorLvl1 chi_;
426 double f0_, lz_, R0_, Z0_;
void axpby(get_value_type< ContainerType > alpha, const ContainerType1 &x, 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 integrate_steps(value_type t0, const container_type &u0, value_type t1, container_type &u1, unsigned steps)
This struct bundles a function and its first and second derivatives.
Definition: fluxfunctions.h:219
const CylindricalFunctor & dfy() const
Definition: fluxfunctions.h:247
const CylindricalFunctor & dfx() const
Definition: fluxfunctions.h:245
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
Generate a simple orthogonal grid.
Definition: simple_orthogonal.h:328
SimpleOrthogonal(const CylindricalFunctorsLvl2 &psi, const CylindricalSymmTensorLvl1 &chi, double psi_0, double psi_1, double x0, double y0, double psi_firstline, int mode=0)
Construct a simple orthogonal grid.
Definition: simple_orthogonal.h:364
double f0() const
The grid constant.
Definition: simple_orthogonal.h:385
SimpleOrthogonal(const CylindricalFunctorsLvl2 &psi, double psi_0, double psi_1, double x0, double y0, double psi_firstline, int mode=0)
Construct a simple orthogonal grid.
Definition: simple_orthogonal.h:342
virtual SimpleOrthogonal * clone() const override final
Abstract clone method that returns a copy on the heap.
Definition: simple_orthogonal.h:386
The abstract generator base class.
Definition: generator.h:20