26 Fpsi(
const CylindricalFunctorsLvl2& psip,
const CylindricalFunctorsLvl1& ipol,
double x0,
double y0,
bool verbose =
false):
27 psip_(psip), fieldRZYT_(psip, ipol, x0, y0), fieldRZtau_(psip),m_verbose(verbose)
30 double R_O = x0, Z_O = y0;
33 fieldRZYT_ = dg::geo::flux::FieldRZYT(psip, ipol, R_O, Z_O);
34 X_init = x0, Y_init = y0;
35 while( fabs( psip.dfx()(X_init, Y_init)) <= 1e-10 && fabs( psip.dfy()( X_init, Y_init)) <= 1e-10)
39 void find_initial(
double psi,
double& R_0,
double& Z_0)
42 std::array<double, 2> begin2d{ {0,0} }, end2d(begin2d), end2d_old(begin2d);
43 if(m_verbose)std::cout <<
"In init function\n";
44 begin2d[0] = end2d[0] = end2d_old[0] = X_init;
45 begin2d[1] = end2d[1] = end2d_old[1] = Y_init;
46 double eps = 1e10, eps_old = 2e10;
47 using Vec = std::array<double,2>;
49 begin2d), fieldRZtau_);
50 while( (eps < eps_old || eps > 1e-7) && eps > 1e-14)
52 eps_old = eps; end2d_old = end2d;
53 N*=2; odeint.integrate_steps( psip_.f()(X_init, Y_init), begin2d,
55 eps = sqrt( (end2d[0]-end2d_old[0])*(end2d[0]-end2d_old[0]) + (end2d[1]-end2d_old[1])*(end2d[1]-end2d_old[1]));
57 X_init = R_0 = end2d_old[0], Y_init = Z_0 = end2d_old[1];
58 if(m_verbose)std::cout <<
"In init function error: psi(R,Z)-psi0: "<<psip_.f()(X_init, Y_init)-psi<<
"\n";
62 double construct_f(
double psi,
double& R_0,
double& Z_0)
64 find_initial( psi, R_0, Z_0);
65 std::array<double,3> begin{ {0,0,0} }, end(begin), end_old(begin);
66 begin[0] = R_0, begin[1] = Z_0;
67 double eps = 1e10, eps_old = 2e10;
69 unsigned nan_counter = 0;
70 using Vec = std::array<double,3>;
73 while( (eps < eps_old || eps > 1e-7)&& eps > 1e-14)
75 eps_old = eps, end_old = end; N*=2;
76 odeint.integrate_steps( 0., begin, 2*M_PI, end, N);
77 eps = sqrt( (end[0]-begin[0])*(end[0]-begin[0]) +
78 (end[1]-begin[1])*(end[1]-begin[1]));
79 if(m_verbose)std::cout <<
"\t error "<<eps<<
" with "<<N<<
" steps\t";
80 if( std::isnan( eps) && nan_counter < 4) eps = 1e10, end = end_old, nan_counter++;
82 if(m_verbose)std::cout <<
"\t error "<<eps<<
" with "<<N<<
" steps\t";
83 if(m_verbose)std::cout <<end_old[2] <<
" "<<end[2] <<
"\n";
84 double f_psi = 2.*
M_PI/end[2];
88 double operator()(
double psi)
91 return construct_f( psi, R_0, Z_0);
93 double f_prime(
double psi)
96 double deltaPsi = fabs(psi)/100.;
98 fofpsi[1] = operator()(psi-deltaPsi);
99 fofpsi[2] = operator()(psi+deltaPsi);
100 double fprime = (-0.5*fofpsi[1]+0.5*fofpsi[2])/deltaPsi, fprime_old;
101 double eps = 1e10, eps_old=2e10;
102 while( eps < eps_old)
107 fofpsi[0] = fofpsi[1], fofpsi[3] = fofpsi[2];
108 fofpsi[1] = operator()(psi-deltaPsi);
109 fofpsi[2] = operator()(psi+deltaPsi);
111 fprime = (+ 1./12.*fofpsi[0]
116 eps = fabs((fprime - fprime_old)/fprime);
123 double X_init, Y_init;
124 CylindricalFunctorsLvl1 psip_;
125 dg::geo::flux::FieldRZYT fieldRZYT_;
126 dg::geo::FieldRZtau fieldRZtau_;
160 psi_(psi), ipol_(ipol), mode_(mode), m_verbose( verbose)
162 psi0_ = psi_0, psi1_ = psi_1;
163 assert( psi_1 != psi_0);
166 flux::detail::Fpsi fpsi(psi, ipol, x0, y0, m_verbose);
167 f0_ = fabs( fpsi.construct_f( psi_0, x0_, y0_));
171 ribeiro::detail::Fpsi fpsi(psi, x0, y0, mode, m_verbose);
172 f0_ = fabs( fpsi.construct_f( psi_0, x0_, y0_));
174 if( psi_1 < psi_0) f0_*=-1;
175 lx_ = f0_*(psi_1-psi_0);
176 x0_=x0, y0_=y0, psi0_=psi_0, psi1_=psi_1;
177 if(m_verbose)std::cout <<
"lx = "<<lx_<<
"\n";
184 virtual double do_width() const override final{
return lx_;}
185 virtual double do_height() const override final{
return 2.*
M_PI;}
186 virtual void do_generate(
187 const thrust::host_vector<double>& zeta1d,
188 const thrust::host_vector<double>& eta1d,
189 thrust::host_vector<double>& x,
190 thrust::host_vector<double>& y,
191 thrust::host_vector<double>& zetaX,
192 thrust::host_vector<double>& zetaY,
193 thrust::host_vector<double>& etaX,
194 thrust::host_vector<double>& etaY)
const override final
197 thrust::host_vector<double> psi_x(zeta1d);
198 for(
unsigned i=0; i<psi_x.size(); i++)
199 psi_x[i] = zeta1d[i]/f0_ +psi0_;
201 if(m_verbose)std::cout <<
"In grid function:"<<std::endl;
202 flux::detail::Fpsi fpsi(psi_, ipol_, x0_, y0_, m_verbose);
203 dg::geo::flux::FieldRZYRYZY fieldRZYRYZY(psi_, ipol_);
204 ribeiro::detail::Fpsi fpsiRibeiro(psi_, x0_, y0_, mode_, m_verbose);
205 dg::geo::equalarc::FieldRZYRYZY fieldRZYRYZYequalarc(psi_);
206 thrust::host_vector<double> fx_;
207 fx_.resize( zeta1d.size());
208 thrust::host_vector<double> f_p(fx_);
209 unsigned Nx = zeta1d.size(), Ny = eta1d.size();
210 for(
unsigned i=0; i<zeta1d.size(); i++)
212 thrust::host_vector<double> ry, zy;
213 thrust::host_vector<double> yr,
yz, xr,
xz;
215 if(mode_==0)dg::geo::detail::compute_rzy( fpsi, fieldRZYRYZY, psi_x[i], eta1d, ry, zy, yr, yz, xr, xz, R0, Z0, fx_[i], f_p[i], m_verbose);
216 if(mode_==1)dg::geo::detail::compute_rzy( fpsiRibeiro, fieldRZYRYZYequalarc, psi_x[i], eta1d, ry, zy, yr, yz, xr, xz, R0, Z0, fx_[i], f_p[i], m_verbose);
217 for(
unsigned j=0; j<Ny; j++)
219 x[j*Nx+i] = ry[j],
y[j*Nx+i] = zy[j];
220 etaX[j*Nx+i] = yr[j], etaY[j*Nx+i] =
yz[j];
221 zetaX[j*Nx+i] = xr[j]/fx_[i]*f0_, zetaY[j*Nx+i] =
xz[j]/fx_[i]*f0_;
225 CylindricalFunctorsLvl2 psi_;
226 CylindricalFunctorsLvl1 ipol_;
227 double f0_, lx_, x0_, y0_, psi0_, psi1_;
251 psip_(psi), mode_(mode), m_verbose(verbose)
253 psi0_ = psi_0, psi1_ = psi_1;
254 assert( psi_1 != psi_0);
255 ribeiro::detail::Fpsi fpsi(psi, x0, y0, mode, m_verbose);
256 f0_ = fabs( fpsi.construct_f( psi_0, x0_, y0_));
257 if( psi_1 < psi_0) f0_*=-1;
258 lx_ = f0_*(psi_1-psi_0);
259 x0_=x0, y0_=y0, psi0_=psi_0, psi1_=psi_1;
260 if(m_verbose)std::cout <<
"lx = "<<lx_<<
"\n";
266 virtual double do_width()
const{
return lx_;}
267 virtual double do_height()
const{
return 2.*
M_PI;}
268 virtual void do_generate(
269 const thrust::host_vector<double>& zeta1d,
270 const thrust::host_vector<double>& eta1d,
271 thrust::host_vector<double>& x,
272 thrust::host_vector<double>& y,
273 thrust::host_vector<double>& zetaX,
274 thrust::host_vector<double>& zetaY,
275 thrust::host_vector<double>& etaX,
276 thrust::host_vector<double>& etaY)
const
279 thrust::host_vector<double> psi_x(zeta1d);
280 for(
unsigned i=0; i<psi_x.size(); i++)
281 psi_x[i] = zeta1d[i]/f0_ +psi0_;
283 ribeiro::detail::Fpsi fpsi(psip_, x0_, y0_, mode_, m_verbose);
284 dg::geo::ribeiro::FieldRZYRYZY fieldRZYRYZYribeiro(psip_);
285 dg::geo::equalarc::FieldRZYRYZY fieldRZYRYZYequalarc(psip_);
286 thrust::host_vector<double> fx_;
287 fx_.resize( zeta1d.size());
288 thrust::host_vector<double> f_p(fx_);
289 unsigned Nx = zeta1d.size(), Ny = eta1d.size();
290 for(
unsigned i=0; i<zeta1d.size(); i++)
292 thrust::host_vector<double> ry, zy;
293 thrust::host_vector<double> yr,
yz, xr,
xz;
295 if(mode_==0)dg::geo::detail::compute_rzy( fpsi, fieldRZYRYZYribeiro, psi_x[i], eta1d, ry, zy, yr, yz, xr, xz, R0, Z0, fx_[i], f_p[i], m_verbose);
296 if(mode_==1)dg::geo::detail::compute_rzy( fpsi, fieldRZYRYZYequalarc, psi_x[i], eta1d, ry, zy, yr, yz, xr, xz, R0, Z0, fx_[i], f_p[i], m_verbose);
297 for(
unsigned j=0; j<Ny; j++)
299 x[j*Nx+i] = ry[j],
y[j*Nx+i] = zy[j];
300 etaX[j*Nx+i] = yr[j], etaY[j*Nx+i] =
yz[j];
301 zetaX[j*Nx+i] = xr[j]/fx_[i]*f0_, zetaY[j*Nx+i] =
xz[j]/fx_[i]*f0_;
305 CylindricalFunctorsLvl2 psip_;
306 double f0_, lx_, x0_, y0_, psi0_, psi1_;
static int findOpoint(const CylindricalFunctorsLvl2 &psi, double &RC, double &ZC)
This function finds O-points of psi.
Definition: fluxfunctions.h:332
This struct bundles a function and its first derivatives.
Definition: fluxfunctions.h:182
This struct bundles a function and its first and second derivatives.
Definition: fluxfunctions.h:219
A symmetry flux generator.
Definition: flux.h:145
virtual FluxGenerator * clone() const override final
Abstract clone method that returns a copy on the heap.
Definition: flux.h:180
FluxGenerator(const CylindricalFunctorsLvl2 &psi, const CylindricalFunctorsLvl1 &ipol, double psi_0, double psi_1, double x0, double y0, int mode=0, bool verbose=false)
Construct a symmetry flux grid generator.
Definition: flux.h:159
Same as the Ribeiro class just but uses psi as a flux label directly.
Definition: flux.h:238
virtual RibeiroFluxGenerator * clone() const
Abstract clone method that returns a copy on the heap.
Definition: flux.h:262
RibeiroFluxGenerator(const CylindricalFunctorsLvl2 &psi, double psi_0, double psi_1, double x0, double y0, int mode=0, bool verbose=false)
Construct a flux aligned grid generator.
Definition: flux.h:250
The abstract generator base class.
Definition: generator.h:20