23 Fpsi(
const CylindricalFunctorsLvl1& psi,
double x0,
double y0,
int mode,
bool verbose =
false):
24 psip_(psi), fieldRZYTribeiro_(psi,x0, y0),fieldRZYTequalarc_(psi, x0, y0), fieldRZtau_(psi), mode_(mode), m_verbose(verbose)
26 R_init = x0; Z_init = y0;
27 while( fabs( psi.dfx()(R_init, Z_init)) <= 1e-10 && fabs( psi.dfy()( R_init, Z_init)) <= 1e-10)
34 void find_initial(
double psi,
double& R_0,
double& Z_0)
37 std::array<double, 2> begin2d{ {0,0} }, end2d(begin2d), end2d_old(begin2d);
38 begin2d[0] = end2d[0] = end2d_old[0] = R_init;
39 begin2d[1] = end2d[1] = end2d_old[1] = Z_init;
40 if(m_verbose)std::cout <<
"In init function\n";
41 double eps = 1e10, eps_old = 2e10;
42 using Vec = std::array<double,2>;
44 begin2d), fieldRZtau_);
45 while( (eps < eps_old || eps > 1e-7) && eps > 1e-14)
47 eps_old = eps; end2d_old = end2d;
48 N*=2; odeint.integrate_steps( psip_.f()(R_init, Z_init), begin2d,
50 eps = sqrt( (end2d[0]-end2d_old[0])*(end2d[0]-end2d_old[0]) +
51 (end2d[1]-end2d_old[1])*(end2d[1]-end2d_old[1]));
53 R_init = R_0 = end2d_old[0], Z_init = Z_0 = end2d_old[1];
54 if(m_verbose)std::cout <<
"In init function error: psi(R,Z)-psi0: "<<psip_.f()(R_init, Z_init)-psi<<
"\n";
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), end_old(begin);
62 begin[0] = R_0, begin[1] = Z_0;
63 if(m_verbose)std::cout << begin[0]<<
" "<<begin[1]<<
" "<<begin[2]<<
"\n";
64 double eps = 1e10, eps_old = 2e10;
67 using Vec = std::array<double,3>;
71 begin), fieldRZYTribeiro_);
74 begin), fieldRZYTequalarc_);
75 while( (eps < eps_old || eps > 1e-7)&& N < 1e6)
77 eps_old = eps, end_old = end; N*=2;
79 eps = sqrt( (end[0]-begin[0])*(end[0]-begin[0]) +
80 (end[1]-begin[1])*(end[1]-begin[1]));
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_old[2];
87 double operator()(
double psi)
90 return construct_f( psi, R_0, Z_0);
101 double find_x1(
double psi_0,
double psi_1 )
104 double x1 = 0, x1_old = 0;
105 double eps=1e10, eps_old=2e10;
106 if(m_verbose)std::cout <<
"In x1 function\n";
107 while(eps < eps_old && P < 20 && eps > 1e-15)
113 if( psi_1 < psi_0) std::swap(psi_0, psi_1);
116 thrust::host_vector<double> f_vec(grid.size(), 0);
118 for(
unsigned i=0; i<psi_vec.size(); i++)
120 f_vec[i] = this->operator()( psi_vec[i]);
124 eps = fabs((x1 - x1_old)/x1);
130 double f_prime(
double psi)
133 double deltaPsi = fabs(psi)/100.;
135 fofpsi[1] = operator()(psi-deltaPsi);
136 fofpsi[2] = operator()(psi+deltaPsi);
137 double fprime = (-0.5*fofpsi[1]+0.5*fofpsi[2])/deltaPsi, fprime_old;
138 double eps = 1e10, eps_old=2e10;
139 while( eps < eps_old)
144 fofpsi[0] = fofpsi[1], fofpsi[3] = fofpsi[2];
145 fofpsi[1] = operator()(psi-deltaPsi);
146 fofpsi[2] = operator()(psi+deltaPsi);
148 fprime = (+ 1./12.*fofpsi[0]
153 eps = fabs((fprime - fprime_old)/fprime);
160 double R_init, Z_init;
161 CylindricalFunctorsLvl1 psip_;
162 dg::geo::ribeiro::FieldRZYT fieldRZYTribeiro_;
163 dg::geo::equalarc::FieldRZYT fieldRZYTequalarc_;
164 dg::geo::FieldRZtau fieldRZtau_;
172 FieldFinv(
const CylindricalFunctorsLvl1& psi,
double x0,
double y0,
unsigned N_steps,
int mode):
173 fpsi_(psi, x0, y0, mode), fieldRZYTribeiro_(psi, x0, y0), fieldRZYTequalarc_(psi, x0, y0), N_steps(N_steps), mode_(mode) { }
174 void operator()(
double t,
double psi,
double& fpsiM)
176 std::array<double, 3> begin{ {0,0,0} }, end(begin);
177 fpsi_.find_initial( psi, begin[0], begin[1]);
178 using Vec = std::array<double,3>;
182 begin), fieldRZYTribeiro_);
185 begin), fieldRZYTequalarc_);
187 fpsiM = end[2]/2./
M_PI;
192 dg::geo::ribeiro::FieldRZYT fieldRZYTribeiro_;
193 dg::geo::equalarc::FieldRZYT fieldRZYTequalarc_;
220 psi_(psi), mode_(mode), m_verbose(verbose)
222 assert( psi_1 != psi_0);
223 ribeiro::detail::Fpsi fpsi(psi, x0, y0, mode);
224 lx_ = fabs(fpsi.find_x1( psi_0, psi_1));
225 x0_=x0, y0_=y0, psi0_=psi_0, psi1_=psi_1;
226 if(m_verbose)std::cout <<
"lx = "<<lx_<<
"\n";
238 virtual double do_width() const override final{
return lx_;}
245 virtual double do_height() const override final{
return 2.*
M_PI;}
246 virtual void do_generate(
247 const thrust::host_vector<double>& zeta1d,
248 const thrust::host_vector<double>& eta1d,
249 thrust::host_vector<double>& x,
250 thrust::host_vector<double>& y,
251 thrust::host_vector<double>& zetaX,
252 thrust::host_vector<double>& zetaY,
253 thrust::host_vector<double>& etaX,
254 thrust::host_vector<double>& etaY)
const override final
257 ribeiro::detail::FieldFinv fpsiMinv_(psi_, x0_,y0_, 500, mode_);
258 thrust::host_vector<double> psi_x, fx_;
259 dg::geo::detail::construct_psi_values( fpsiMinv_, psi0_, psi1_, 0., zeta1d, lx_, psi_x, fx_);
261 if(m_verbose)std::cout <<
"In grid function:\n";
262 ribeiro::detail::Fpsi fpsi(psi_, x0_, y0_, mode_, m_verbose);
263 dg::geo::ribeiro::FieldRZYRYZY fieldRZYRYZYribeiro(psi_);
264 dg::geo::equalarc::FieldRZYRYZY fieldRZYRYZYequalarc(psi_);
265 thrust::host_vector<double> f_p(fx_);
266 unsigned Nx = zeta1d.size(), Ny = eta1d.size();
267 for(
unsigned i=0; i<zeta1d.size(); i++)
269 thrust::host_vector<double> ry, zy;
270 thrust::host_vector<double> yr,
yz, xr,
xz;
272 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);
273 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);
274 for(
unsigned j=0; j<Ny; j++)
276 x[j*Nx+i] = ry[j],
y[j*Nx+i] = zy[j];
277 etaX[j*Nx+i] = yr[j], etaY[j*Nx+i] =
yz[j];
278 zetaX[j*Nx+i] = xr[j], zetaY[j*Nx+i] =
xz[j];
282 CylindricalFunctorsLvl2 psi_;
283 double lx_, x0_, y0_, psi0_, psi1_;
static DG_DEVICE double cooX1d(double x)
get_value_type< ContainerType1 > dot(const ContainerType1 &x, const ContainerType2 &y)
thrust::host_vector< real_type > evaluate(UnaryOp f, const RealGrid1d< real_type > &g)
MPI_Vector< thrust::host_vector< real_type > > weights(const aRealMPITopology2d< real_type > &g)
void construct(Params &&...ps)
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
A two-dimensional grid based on "almost-conformal" coordinates by Ribeiro and Scott 2010.
Definition: ribeiro.h:207
virtual Ribeiro * clone() const override final
Abstract clone method that returns a copy on the heap.
Definition: ribeiro.h:228
Ribeiro(const CylindricalFunctorsLvl2 &psi, double psi_0, double psi_1, double x0, double y0, int mode=0, bool verbose=false)
Construct a near-conformal grid generator.
Definition: ribeiro.h:219
The abstract generator base class.
Definition: generator.h:20