Extension: Geometries
#include "dg/geometries/geometries.h"
Loading...
Searching...
No Matches
fluxfunctions.h
Go to the documentation of this file.
1#pragma once
2#include <functional>
3#include "dg/algorithm.h"
4
5namespace dg
6{
7namespace geo
8{
9
12
24template<class real_type>
26{
34 template<class BinaryFunctor>
35 RealCylindricalFunctor( BinaryFunctor f):
36 m_f(f) {}
38 real_type operator()( real_type R, real_type Z) const{
39 return m_f(R,Z);
40 }
42 real_type operator()( real_type R, real_type Z, real_type) const{
43 return m_f(R,Z);
44 }
45 private:
46 std::function<real_type(real_type,real_type)> m_f;
47};
48
51
64template<class Derived>
66{
75 double operator()(double R, double Z) const
76 {
77 const Derived& underlying = static_cast<const Derived&>(*this);
78 return underlying.do_compute(R,Z);
79 }
88 double operator()(double R, double Z, double)const
89 {
90 const Derived& underlying = static_cast<const Derived&>(*this);
91 return underlying.do_compute(R,Z);
92 }
93#ifndef __CUDACC__ //nvcc below 10 has problems with the following construct
94 //This trick avoids that classes inherit from the wrong Base:
95 private:
96 friend Derived;
101 aCylindricalFunctor(const aCylindricalFunctor&){}
105 aCylindricalFunctor& operator=(const aCylindricalFunctor&){return *this;}
106#endif //__CUDACC__
107};
108
112struct Constant: public aCylindricalFunctor<Constant>
113{
114 Constant(double c):c_(c){}
115 double do_compute(double,double)const{return c_;}
116 private:
117 double c_;
118};
128struct ZCutter : public aCylindricalFunctor<ZCutter>
129{
130 ZCutter(double ZX, int sign = +1): m_heavi( ZX, sign){}
131 double do_compute(double, double Z) const {
132 return m_heavi(Z);
133 }
134 private:
135 dg::Heaviside m_heavi;
136};
137
142struct Periodify : public aCylindricalFunctor<Periodify>
143{
150 Periodify( CylindricalFunctor functor, dg::Grid2d g): m_g( g), m_f(functor) {}
162 Periodify( CylindricalFunctor functor, double R0, double R1, double Z0,
163 double Z1, dg::bc bcx, dg::bc bcy):
164 m_g( R0, R1, Z0, Z1, 3, 10, 10, bcx, bcy), m_f(functor)
165 {}
166 double do_compute( double R, double Z) const
167 {
168 bool negative = false;
169 dg::create::detail::shift( negative, R, m_g.bcx(), m_g.x0(), m_g.x1());
170 dg::create::detail::shift( negative, Z, m_g.bcy(), m_g.y0(), m_g.y1());
171 if( negative) return -m_f(R,Z);
172 return m_f( R, Z);
173 }
174 private:
175 dg::Grid2d m_g;
177};
178
185{
200 {
201 p_[0] = f;
202 p_[1] = fx;
203 p_[2] = fy;
204 }
206 const CylindricalFunctor& f()const{return p_[0];}
208 const CylindricalFunctor& dfx()const{return p_[1];}
210 const CylindricalFunctor& dfy()const{return p_[2];}
211 private:
212 std::array<CylindricalFunctor,3> p_;
213};
214
215
222{
240 {
241 f0.reset( f,fx,fy), f1.reset(fxx,fxy,fyy);
242 }
244 operator CylindricalFunctorsLvl1 ()const {return f0;}
246 const CylindricalFunctor& f()const{return f0.f();}
248 const CylindricalFunctor& dfx()const{return f0.dfx();}
250 const CylindricalFunctor& dfy()const{return f0.dfy();}
252 const CylindricalFunctor& dfxx()const{return f1.f();}
254 const CylindricalFunctor& dfxy()const{return f1.dfx();}
256 const CylindricalFunctor& dfyy()const{return f1.dfy();}
257 private:
259};
260
261
278inline int findCriticalPoint( const CylindricalFunctorsLvl2& psi, double& RC, double& ZC)
279{
280 std::array<double, 2> X{ {0,0} }, XN(X), X_OLD(X);
281 X[0] = RC, X[1] = ZC;
282 double eps = 1e10, eps_old= 2e10;
283 unsigned counter = 0; //safety measure to avoid deadlock
284 double psipRZ = psi.dfxy()(X[0], X[1]);
285 double psipRR = psi.dfxx()(X[0], X[1]), psipZZ = psi.dfyy()(X[0],X[1]);
286 double psipR = psi.dfx()(X[0], X[1]), psipZ = psi.dfy()(X[0], X[1]);
287 double D0 = (psipZZ*psipRR - psipRZ*psipRZ);
288 if(D0 == 0) // try to change initial guess slightly if we are very lucky
289 {
290 X[0] *= 1.0001, X[1]*=1.0001;
291 psipRZ = psi.dfxy()(X[0], X[1]);
292 psipRR = psi.dfxx()(X[0], X[1]), psipZZ = psi.dfyy()(X[0],X[1]);
293 psipR = psi.dfx()(X[0], X[1]), psipZ = psi.dfy()(X[0], X[1]);
294 D0 = (psipZZ*psipRR - psipRZ*psipRZ);
295 }
296 double Dinv = 1./D0;
297 while( (eps < eps_old || eps > 1e-7) && eps > 1e-10 && counter < 100)
298 {
299 //newton iteration
300 XN[0] = X[0] - Dinv*(psipZZ*psipR - psipRZ*psipZ);
301 XN[1] = X[1] - Dinv*(-psipRZ*psipR + psipRR*psipZ);
302 XN.swap(X);
303 eps = sqrt( (X[0]-X_OLD[0])*(X[0]-X_OLD[0]) + (X[1]-X_OLD[1])*(X[1]-X_OLD[1]));
304 X_OLD = X; eps_old= eps;
305 psipRZ = psi.dfxy()(X[0], X[1]);
306 psipRR = psi.dfxx()(X[0], X[1]), psipZZ = psi.dfyy()(X[0],X[1]);
307 psipR = psi.dfx()(X[0], X[1]), psipZ = psi.dfy()(X[0], X[1]);
308 D0 = (psipZZ*psipRR - psipRZ*psipRZ);
309 Dinv = 1./D0;
310 if( D0 == 0) break;
311 counter++;
312 }
313 if ( counter >= 100 || D0 == 0|| std::isnan( Dinv) )
314 return 0;
315 RC = X[0], ZC = X[1];
316 if( Dinv > 0 && psipRR > 0)
317 return 1; //local minimum
318 if( Dinv > 0 && psipRR < 0)
319 return 2; //local maximum
320 //if( Dinv < 0)
321 return 3; //saddle point
322}
323
335inline int findOpoint( const CylindricalFunctorsLvl2& psi, double& RC, double& ZC)
336{
337 int point = findCriticalPoint( psi, RC, ZC);
338 if( point == 3 || point == 0 )
339 throw dg::Error(dg::Message(_ping_)<<"There is no O-point near "<<RC<<" "<<ZC);
340 return point;
341}
342
353inline void findXpoint( const CylindricalFunctorsLvl2& psi, double& RC, double& ZC)
354{
355 int point = findCriticalPoint( psi, RC, ZC);
356 if( point != 3)
357 throw dg::Error(dg::Message(_ping_)<<"There is no X-point near "<<RC<<" "<<ZC);
358}
359
360
364{
369 reset( Constant(1), Constant(0), Constant(1), Constant(0), Constant(0));
370 }
383 CylindricalFunctor divChiX, CylindricalFunctor divChiY) :
384 p_{{ chi_xx,chi_xy,chi_yy,divChiX,divChiY}}
385 {
386 }
390 CylindricalFunctor divChiY)
391 {
392 p_[0] = chi_xx;
393 p_[1] = chi_xy;
394 p_[2] = chi_yy;
395 p_[3] = divChiX;
396 p_[4] = divChiY;
397 }
399 const CylindricalFunctor& xx()const{return p_[0];}
401 const CylindricalFunctor& xy()const{return p_[1];}
403 const CylindricalFunctor& yy()const{return p_[2];}
405 const CylindricalFunctor& divX()const{return p_[3];}
407 const CylindricalFunctor& divY()const{return p_[4];}
408 private:
409 std::array<CylindricalFunctor,5> p_;
410};
411
415{
424 {
425 p_[0] = v_x;
426 p_[1] = v_y;
427 p_[2] = v_z;
428 }
430 const CylindricalFunctor& x()const{return p_[0];}
432 const CylindricalFunctor& y()const{return p_[1];}
434 const CylindricalFunctor& z()const{return p_[2];}
435 private:
436 std::array<CylindricalFunctor,3> p_;
437};
438
443{
451 CylindricalFunctor divvvz
452 ): f0{v_x, v_y, v_z},
453 m_div(div), m_divvvz(divvvz) {}
459 CylindricalFunctor divvvz
460 )
461 {
462 f0.reset( v_x,v_y,v_z);
463 m_div = div;
464 m_divvvz = divvvz;
465 }
467 operator CylindricalVectorLvl0 ()const {return f0;}
469 const CylindricalFunctor& x()const{return f0.x();}
471 const CylindricalFunctor& y()const{return f0.y();}
473 const CylindricalFunctor& z()const{return f0.z();}
475 const CylindricalFunctor& div()const{return m_div;}
477 const CylindricalFunctor& divvvz()const{return m_divvvz;}
478 private:
480 CylindricalFunctor m_div, m_divvvz;
481};
482
486struct ScalarProduct : public aCylindricalFunctor<ScalarProduct>
487{
489 double do_compute( double R, double Z) const
490 {
491 return m_v.x()(R,Z)*m_w.x()(R,Z)
492 + m_v.y()(R,Z)*m_w.y()(R,Z)
493 + m_v.z()(R,Z)*m_w.z()(R,Z);
494 }
495 private:
496 CylindricalVectorLvl0 m_v, m_w;
497};
498
504struct SquareNorm : public aCylindricalFunctor<SquareNorm>
505{
507 double do_compute( double R, double Z) const
508 {
509 return sqrt(m_s(R,Z));
510 }
511 private:
512 ScalarProduct m_s;
513};
514
515
527template<class Geometry3d>
529 const dg::geo::CylindricalVectorLvl0& bhat, const Geometry3d& g)
530{
531 using host_vector = typename Geometry3d::host_vector;
533 std::array<host_vector,3> bt;
534 dg::pushForward( bhat.x(), bhat.y(), bhat.z(), bt[0], bt[1], bt[2], g);
535 std::vector<host_vector> chi(6, dg::evaluate( dg::zero,g));
536 dg::blas1::pointwiseDot( bt[0], bt[0], chi[0]);
537 dg::blas1::pointwiseDot( bt[0], bt[1], chi[1]);
538 dg::blas1::pointwiseDot( bt[0], bt[2], chi[2]);
539 dg::blas1::pointwiseDot( bt[1], bt[1], chi[3]);
540 dg::blas1::pointwiseDot( bt[1], bt[2], chi[4]);
541 dg::blas1::pointwiseDot( bt[2], bt[2], chi[5]);
542 t.idx(0,0) = 0, t.idx(0,1) = t.idx(1,0) = 1,
543 t.idx(0,2) = t.idx(2,0) = 2;
544 t.idx(1,1) = 3, t.idx(1,2) = t.idx(2,1) = 4;
545 t.idx(2,2) = 5;
546 t.values() = chi;
547 return t;
548}
560template<class Geometry3d>
562 const dg::geo::CylindricalVectorLvl0& bhat, const Geometry3d& g)
563{
564 using host_vector = typename Geometry3d::host_vector;
566 dg::SparseTensor<host_vector> m = g.metric();
567 dg::blas1::axpby( 1., m.value(0,0), -1., t.values()[0]);
568 dg::blas1::axpby( 1., m.value(0,1), -1., t.values()[1]);
569 dg::blas1::axpby( 1., m.value(0,2), -1., t.values()[2]);
570 dg::blas1::axpby( 1., m.value(1,1), -1., t.values()[3]);
571 dg::blas1::axpby( 1., m.value(1,2), -1., t.values()[4]);
572 dg::blas1::axpby( 1., m.value(2,2), -1., t.values()[5]);
573 return t;
574}
575
577}//namespace geo
578}//namespace dg
#define _ping_
DG_DEVICE T zero(T, Ts ...)
void axpby(value_type alpha, const ContainerType1 &x, value_type1 beta, ContainerType &y)
void pointwiseDot(value_type alpha, const ContainerType1 &x1, const ContainerType2 &x2, value_type1 beta, ContainerType &y)
auto evaluate(Functor &&f, const Topology &g)
dg::SparseTensor< typename Geometry3d::host_vector > createAlignmentTensor(const dg::geo::CylindricalVectorLvl0 &bhat, const Geometry3d &g)
Definition fluxfunctions.h:528
dg::SparseTensor< typename Geometry3d::host_vector > createProjectionTensor(const dg::geo::CylindricalVectorLvl0 &bhat, const Geometry3d &g)
Definition fluxfunctions.h:561
void findXpoint(const CylindricalFunctorsLvl2 &psi, double &RC, double &ZC)
This function finds X-points of psi.
Definition fluxfunctions.h:353
int findOpoint(const CylindricalFunctorsLvl2 &psi, double &RC, double &ZC)
This function finds O-points of psi.
Definition fluxfunctions.h:335
int findCriticalPoint(const CylindricalFunctorsLvl2 &psi, double &RC, double &ZC)
This function finds critical points of psi (any point with vanishing gradient, including the X-point ...
Definition fluxfunctions.h:278
void pushForward(const Functor1 &vR, const Functor2 &vZ, const Functor3 &vPhi, container &vx, container &vy, container &vz, const Geometry &g)
int idx(unsigned i, unsigned j) const
std::vector< container > & values()
const container & value(size_t i, size_t j) const
real_type x0() const
dg::bc bcy() const
real_type y0() const
real_type y1() const
real_type x1() const
dg::bc bcx() const
Definition fluxfunctions.h:113
Constant(double c)
Definition fluxfunctions.h:114
double do_compute(double, double) const
Definition fluxfunctions.h:115
This struct bundles a function and its first derivatives.
Definition fluxfunctions.h:185
void reset(CylindricalFunctor f, CylindricalFunctor fx, CylindricalFunctor fy)
copy given functors
Definition fluxfunctions.h:199
CylindricalFunctorsLvl1(CylindricalFunctor f, CylindricalFunctor fx, CylindricalFunctor fy)
Construct with given functors.
Definition fluxfunctions.h:195
const CylindricalFunctor & dfx() const
Definition fluxfunctions.h:208
const CylindricalFunctor & f() const
Definition fluxfunctions.h:206
const CylindricalFunctor & dfy() const
Definition fluxfunctions.h:210
CylindricalFunctorsLvl1()
the access functions are undefined as long as the class remains empty
Definition fluxfunctions.h:187
This struct bundles a function and its first and second derivatives.
Definition fluxfunctions.h:222
const CylindricalFunctor & dfxy() const
Definition fluxfunctions.h:254
const CylindricalFunctor & dfy() const
Definition fluxfunctions.h:250
CylindricalFunctorsLvl2(CylindricalFunctor f, CylindricalFunctor fx, CylindricalFunctor fy, CylindricalFunctor fxx, CylindricalFunctor fxy, CylindricalFunctor fyy)
Construct with given functors.
Definition fluxfunctions.h:231
CylindricalFunctorsLvl2()
the access functions are undefined as long as the class remains empty
Definition fluxfunctions.h:224
const CylindricalFunctor & dfx() const
Definition fluxfunctions.h:248
const CylindricalFunctor & dfxx() const
Definition fluxfunctions.h:252
void reset(CylindricalFunctor f, CylindricalFunctor fx, CylindricalFunctor fy, CylindricalFunctor fxx, CylindricalFunctor fxy, CylindricalFunctor fyy)
Replace with given Functors.
Definition fluxfunctions.h:237
const CylindricalFunctor & f() const
Definition fluxfunctions.h:246
const CylindricalFunctor & dfyy() const
Definition fluxfunctions.h:256
Definition fluxfunctions.h:364
void reset(CylindricalFunctor chi_xx, CylindricalFunctor chi_xy, CylindricalFunctor chi_yy, CylindricalFunctor divChiX, CylindricalFunctor divChiY)
replace with given functors
Definition fluxfunctions.h:388
const CylindricalFunctor & yy() const
yy component
Definition fluxfunctions.h:403
const CylindricalFunctor & divY() const
is the y-component of the divergence of the tensor
Definition fluxfunctions.h:407
CylindricalSymmTensorLvl1(CylindricalFunctor chi_xx, CylindricalFunctor chi_xy, CylindricalFunctor chi_yy, CylindricalFunctor divChiX, CylindricalFunctor divChiY)
Copy given functors.
Definition fluxfunctions.h:381
CylindricalSymmTensorLvl1()
Initialize with the identity tensor.
Definition fluxfunctions.h:368
const CylindricalFunctor & xy() const
xy component
Definition fluxfunctions.h:401
const CylindricalFunctor & divX() const
is the x-component of the divergence of the tensor
Definition fluxfunctions.h:405
const CylindricalFunctor & xx() const
xy component
Definition fluxfunctions.h:399
Definition fluxfunctions.h:415
const CylindricalFunctor & z() const
z-component of the vector
Definition fluxfunctions.h:434
CylindricalVectorLvl0(CylindricalFunctor v_x, CylindricalFunctor v_y, CylindricalFunctor v_z)
Copy given Functors.
Definition fluxfunctions.h:418
const CylindricalFunctor & y() const
y-component of the vector
Definition fluxfunctions.h:432
void reset(CylindricalFunctor v_x, CylindricalFunctor v_y, CylindricalFunctor v_z)
replace with given functors
Definition fluxfunctions.h:422
const CylindricalFunctor & x() const
x-component of the vector
Definition fluxfunctions.h:430
CylindricalVectorLvl0()
Definition fluxfunctions.h:416
This struct bundles a vector field and its divergence.
Definition fluxfunctions.h:443
void reset(CylindricalFunctor v_x, CylindricalFunctor v_y, CylindricalFunctor v_z, CylindricalFunctor div, CylindricalFunctor divvvz)
replace with given functors
Definition fluxfunctions.h:455
const CylindricalFunctor & y() const
y-component of the vector
Definition fluxfunctions.h:471
const CylindricalFunctor & x() const
x-component of the vector
Definition fluxfunctions.h:469
const CylindricalFunctor & div() const
Definition fluxfunctions.h:475
CylindricalVectorLvl1(CylindricalFunctor v_x, CylindricalFunctor v_y, CylindricalFunctor v_z, CylindricalFunctor div, CylindricalFunctor divvvz)
Copy given Functors.
Definition fluxfunctions.h:447
const CylindricalFunctor & divvvz() const
Definition fluxfunctions.h:477
const CylindricalFunctor & z() const
z-component of the vector
Definition fluxfunctions.h:473
CylindricalVectorLvl1()
the access functions are undefined as long as the class remains empty
Definition fluxfunctions.h:445
This function extends another function beyond the grid boundaries.
Definition fluxfunctions.h:143
Periodify(CylindricalFunctor functor, dg::Grid2d g)
Construct from grid.
Definition fluxfunctions.h:150
Periodify(CylindricalFunctor functor, double R0, double R1, double Z0, double Z1, dg::bc bcx, dg::bc bcy)
provide 2d grid boundaries by hand
Definition fluxfunctions.h:162
double do_compute(double R, double Z) const
Definition fluxfunctions.h:166
Inject both 2d and 3d operator() to a 2d functor.
Definition fluxfunctions.h:26
RealCylindricalFunctor()
Definition fluxfunctions.h:27
real_type operator()(real_type R, real_type Z, real_type) const
Definition fluxfunctions.h:42
real_type operator()(real_type R, real_type Z) const
Definition fluxfunctions.h:38
RealCylindricalFunctor(BinaryFunctor f)
Construct from any binary functor.
Definition fluxfunctions.h:35
Return scalar product of two vector fields .
Definition fluxfunctions.h:487
double do_compute(double R, double Z) const
Definition fluxfunctions.h:489
ScalarProduct(CylindricalVectorLvl0 v, CylindricalVectorLvl0 w)
Definition fluxfunctions.h:488
Return norm of scalar product of two vector fields .
Definition fluxfunctions.h:505
SquareNorm(CylindricalVectorLvl0 v, CylindricalVectorLvl0 w)
Definition fluxfunctions.h:506
double do_compute(double R, double Z) const
Definition fluxfunctions.h:507
Definition fluxfunctions.h:129
double do_compute(double, double Z) const
Definition fluxfunctions.h:131
ZCutter(double ZX, int sign=+1)
Definition fluxfunctions.h:130
Represent functions written in cylindrical coordinates that are independent of the angle phi serving ...
Definition fluxfunctions.h:66
double operator()(double R, double Z) const
do_compute(R,Z)
Definition fluxfunctions.h:75
double operator()(double R, double Z, double) const
do_compute(R,Z)
Definition fluxfunctions.h:88