Extension: Geometries
#include "dg/geometries/geometries.h"
magnetic_field.h
Go to the documentation of this file.
1#pragma once
2
3#include <map>
4#include "fluxfunctions.h"
5
10namespace dg
11{
12namespace geo
13{
23
25enum class equilibrium
26{
27 solovev,
28 taylor,
30 guenter,
31 toroidal,
33};
35enum class modifier
36{
37 none,
38 heaviside,
39 sol_pfr
40};
47enum class description
48{
49 standardO,
50 standardX,
51 doubleX,
52 none,
53 square,
55};
57static const std::map<std::string, equilibrium> str2equilibrium{
58 {"solovev", equilibrium::solovev},
59 {"taylor", equilibrium::taylor},
60 {"polynomial", equilibrium::polynomial},
61 {"guenter", equilibrium::guenter},
62 {"toroidal", equilibrium::toroidal},
63 {"circular", equilibrium::circular}
64};
65static const std::map<std::string, modifier> str2modifier{
66 {"none", modifier::none},
67 {"heaviside", modifier::heaviside},
68 {"sol_pfr", modifier::sol_pfr}
69};
70static const std::map<std::string, description> str2description{
71 {"standardO", description::standardO},
72 {"standardX", description::standardX},
73 {"doubleX", description::doubleX},
74 {"square", description::square},
75 {"none", description::none},
76 {"centeredX", description::centeredX}
77};
79
80//Meta-data about magnetic fields
81//
91{
96 m_a = 1, m_elongation = 1, m_triangularity = 0;
97 m_equilibrium = equilibrium::toroidal;
98 m_modifier = modifier::none;
99 m_description = description::none;
100 }
112 equilibrium equ, modifier mod, description des): m_a(a),
113 m_elongation(elongation),
114 m_triangularity( triangularity),
115 m_equilibrium( equ),
116 m_modifier(mod), m_description( des){}
122 double a() const{return m_a;}
128 double elongation() const{return m_elongation;}
134 double triangularity() const{return m_triangularity;}
136 equilibrium getEquilibrium() const{return m_equilibrium;}
138 modifier getModifier() const{return m_modifier;}
140 description getDescription() const{return m_description;}
141 private:
142 double m_a,
143 m_elongation,
144 m_triangularity;
145 equilibrium m_equilibrium;
146 modifier m_modifier;
147 description m_description;
148};
149
162{
167 ): m_R0(R0), m_psip(psip), m_ipol(ipol), m_params(gp){}
168 void set( double R0, const CylindricalFunctorsLvl2& psip, const
170 {
171 m_R0=R0;
172 m_psip=psip;
173 m_ipol=ipol;
174 m_params = gp;
175 }
177 double R0()const {return m_R0;}
179 const CylindricalFunctor& psip()const{return m_psip.f();}
181 const CylindricalFunctor& psipR()const{return m_psip.dfx();}
183 const CylindricalFunctor& psipZ()const{return m_psip.dfy();}
185 const CylindricalFunctor& psipRR()const{return m_psip.dfxx();}
187 const CylindricalFunctor& psipRZ()const{return m_psip.dfxy();}
189 const CylindricalFunctor& psipZZ()const{return m_psip.dfyy();}
191 const CylindricalFunctor& ipol()const{return m_ipol.f();}
193 const CylindricalFunctor& ipolR()const{return m_ipol.dfx();}
195 const CylindricalFunctor& ipolZ()const{return m_ipol.dfy();}
196
197 const CylindricalFunctorsLvl2& get_psip() const{return m_psip;}
198 const CylindricalFunctorsLvl1& get_ipol() const{return m_ipol;}
204 const MagneticFieldParameters& params() const{return m_params;}
205
206 private:
207 double m_R0;
211};
212
214static inline CylindricalFunctorsLvl1 periodify( const CylindricalFunctorsLvl1& in, double R0, double R1, double Z0, double Z1, bc bcx, bc bcy)
215{
216 return CylindricalFunctorsLvl1(
217 Periodify( in.f(), R0, R1, Z0, Z1, bcx, bcy),
218 Periodify( in.dfx(), R0, R1, Z0, Z1, inverse(bcx), bcy),
219 Periodify( in.dfy(), R0, R1, Z0, Z1, bcx, inverse(bcy)));
220}
221static inline CylindricalFunctorsLvl2 periodify( const CylindricalFunctorsLvl2& in, double R0, double R1, double Z0, double Z1, bc bcx, bc bcy)
222{
223 return CylindricalFunctorsLvl2(
224 Periodify( in.f(), R0, R1, Z0, Z1, bcx, bcy),
225 Periodify( in.dfx(), R0, R1, Z0, Z1, inverse(bcx), bcy),
226 Periodify( in.dfy(), R0, R1, Z0, Z1, bcx, inverse(bcy)),
227 Periodify( in.dfxx(), R0, R1, Z0, Z1, bcx, bcy),
228 Periodify( in.dfxy(), R0, R1, Z0, Z1, inverse(bcx), inverse(bcy)),
229 Periodify( in.dfyy(), R0, R1, Z0, Z1, bcx, bcy));
230}
232
247static inline TokamakMagneticField periodify( const TokamakMagneticField& mag, double R0, double R1, double Z0, double Z1, dg::bc bcx, dg::bc bcy)
248{
249 return TokamakMagneticField( mag.R0(),
250 periodify( mag.get_psip(), R0, R1, Z0, Z1, bcx, bcy),
251 //what if Dirichlet BC in the current? Won't that generate a NaN?
252 periodify( mag.get_ipol(), R0, R1, Z0, Z1, bcx, bcy), mag.params());
253}
254
256struct LaplacePsip : public aCylindricalFunctor<LaplacePsip>
257{
258 LaplacePsip( const TokamakMagneticField& mag): m_mag(mag) { }
259 double do_compute(double R, double Z) const
260 {
261 return m_mag.psipR()(R,Z)/R+ m_mag.psipRR()(R,Z) + m_mag.psipZZ()(R,Z);
262 }
263 private:
265};
266
268struct Bmodule : public aCylindricalFunctor<Bmodule>
269{
270 Bmodule( const TokamakMagneticField& mag): m_mag(mag) { }
271 double do_compute(double R, double Z) const
272 {
273 double psipR = m_mag.psipR()(R,Z), psipZ = m_mag.psipZ()(R,Z), ipol = m_mag.ipol()(R,Z);
274 return m_mag.R0()/R*sqrt(ipol*ipol+psipR*psipR +psipZ*psipZ);
275 }
276 private:
278};
279
287struct InvB : public aCylindricalFunctor<InvB>
288{
289 InvB( const TokamakMagneticField& mag): m_mag(mag){ }
290 double do_compute(double R, double Z) const
291 {
292 double psipR = m_mag.psipR()(R,Z), psipZ = m_mag.psipZ()(R,Z), ipol = m_mag.ipol()(R,Z);
293 return R/(m_mag.R0()*sqrt(ipol*ipol + psipR*psipR +psipZ*psipZ)) ;
294 }
295 private:
297};
298
306struct LnB : public aCylindricalFunctor<LnB>
307{
308 LnB(const TokamakMagneticField& mag): m_mag(mag) { }
309 double do_compute(double R, double Z) const
310 {
311 double psipR = m_mag.psipR()(R,Z), psipZ = m_mag.psipZ()(R,Z), ipol = m_mag.ipol()(R,Z);
312 return log(m_mag.R0()/R*sqrt(ipol*ipol + psipR*psipR +psipZ*psipZ)) ;
313 }
314 private:
316};
317
328struct BR: public aCylindricalFunctor<BR>
329{
330 BR(const TokamakMagneticField& mag): m_invB(mag), m_mag(mag) { }
331 double do_compute(double R, double Z) const
332 {
333 double Rn = R/m_mag.R0();
334 double invB = m_invB(R,Z);
335 return -1./R/invB + invB/Rn/Rn*(m_mag.ipol()(R,Z)*m_mag.ipolR()(R,Z) + m_mag.psipR()(R,Z)*m_mag.psipRR()(R,Z) + m_mag.psipZ()(R,Z)*m_mag.psipRZ()(R,Z));
336 }
337 private:
338 InvB m_invB;
340};
341
350struct BZ: public aCylindricalFunctor<BZ>
351{
352 BZ(const TokamakMagneticField& mag ): m_mag(mag), m_invB(mag) { }
353 double do_compute(double R, double Z) const
354 {
355 double Rn = R/m_mag.R0();
356 return (m_invB(R,Z)/Rn/Rn)*(m_mag.ipol()(R,Z)*m_mag.ipolZ()(R,Z) + m_mag.psipR()(R,Z)*m_mag.psipRZ()(R,Z) + m_mag.psipZ()(R,Z)*m_mag.psipZZ()(R,Z));
357 }
358 private:
360 InvB m_invB;
361};
362
367struct CurvatureNablaBR: public aCylindricalFunctor<CurvatureNablaBR>
368{
369 CurvatureNablaBR(const TokamakMagneticField& mag, int sign): m_invB(mag), m_bZ(mag) {
370 if( sign >0)
371 m_sign = +1.;
372 else
373 m_sign = -1;
374 }
375 double do_compute( double R, double Z) const
376 {
377 return -m_sign*m_invB(R,Z)*m_invB(R,Z)*m_bZ(R,Z);
378 }
379 private:
380 double m_sign;
381 InvB m_invB;
382 BZ m_bZ;
383};
384
389struct CurvatureNablaBZ: public aCylindricalFunctor<CurvatureNablaBZ>
390{
391 CurvatureNablaBZ( const TokamakMagneticField& mag, int sign): m_invB(mag), m_bR(mag) {
392 if( sign >0)
393 m_sign = +1.;
394 else
395 m_sign = -1;
396 }
397 double do_compute( double R, double Z) const
398 {
399 return m_sign*m_invB(R,Z)*m_invB(R,Z)*m_bR(R,Z);
400 }
401 private:
402 double m_sign;
403 InvB m_invB;
404 BR m_bR;
405};
406
411struct CurvatureKappaR: public aCylindricalFunctor<CurvatureKappaR>
412{
414 CurvatureKappaR( const TokamakMagneticField& mag, int sign = +1){ }
415 double do_compute( double R, double Z) const
416 {
417 return 0.;
418 }
419 private:
420};
421
426struct CurvatureKappaZ: public aCylindricalFunctor<CurvatureKappaZ>
427{
428 CurvatureKappaZ( const TokamakMagneticField& mag, int sign): m_invB(mag) {
429 if( sign >0)
430 m_sign = +1.;
431 else
432 m_sign = -1;
433 }
434 double do_compute( double R, double Z) const
435 {
436 return -m_sign*m_invB(R,Z)/R;
437 }
438 private:
439 double m_sign;
440 InvB m_invB;
441};
442
447struct DivCurvatureKappa: public aCylindricalFunctor<DivCurvatureKappa>
448{
449 DivCurvatureKappa( const TokamakMagneticField& mag, int sign): m_invB(mag), m_bZ(mag){
450 if( sign >0)
451 m_sign = +1.;
452 else
453 m_sign = -1;
454 }
455 double do_compute( double R, double Z) const
456 {
457 return m_sign*m_bZ(R,Z)*m_invB(R,Z)*m_invB(R,Z)/R;
458 }
459 private:
460 double m_sign;
461 InvB m_invB;
462 BZ m_bZ;
463};
464
469struct DivCurvatureNablaB: public aCylindricalFunctor<DivCurvatureNablaB>
470{
471 DivCurvatureNablaB( const TokamakMagneticField& mag, int sign): m_div(mag, sign){ }
472 double do_compute( double R, double Z) const
473 {
474 return -m_div(R,Z);
475 }
476 private:
477 DivCurvatureKappa m_div;
478};
482struct TrueCurvatureNablaBR: public aCylindricalFunctor<TrueCurvatureNablaBR>
483{
484 TrueCurvatureNablaBR(const TokamakMagneticField& mag): m_R0(mag.R0()), m_mag(mag), m_invB(mag), m_bZ(mag) { }
485 double do_compute( double R, double Z) const
486 {
487 double invB = m_invB(R,Z), ipol = m_mag.ipol()(R,Z);
488 return -invB*invB*invB*ipol*m_R0/R*m_bZ(R,Z);
489 }
490 private:
491 double m_R0;
493 InvB m_invB;
494 BZ m_bZ;
495};
496
500struct TrueCurvatureNablaBZ: public aCylindricalFunctor<TrueCurvatureNablaBZ>
501{
502 TrueCurvatureNablaBZ(const TokamakMagneticField& mag): m_R0(mag.R0()), m_mag(mag), m_invB(mag), m_bR(mag) { }
503 double do_compute( double R, double Z) const
504 {
505 double invB = m_invB(R,Z), ipol = m_mag.ipol()(R,Z);
506 return invB*invB*invB*ipol*m_R0/R*m_bR(R,Z);
507 }
508 private:
509 double m_R0;
511 InvB m_invB;
512 BR m_bR;
513};
514
518struct TrueCurvatureNablaBP: public aCylindricalFunctor<TrueCurvatureNablaBP>
519{
520 TrueCurvatureNablaBP(const TokamakMagneticField& mag): m_mag(mag), m_invB(mag),m_bR(mag), m_bZ(mag) { }
521 double do_compute( double R, double Z) const
522 {
523 double invB = m_invB(R,Z);
524 return m_mag.R0()*invB*invB*invB/R/R*(m_mag.psipZ()(R,Z)*m_bZ(R,Z) + m_mag.psipR()(R,Z)*m_bR(R,Z));
525 }
526 private:
528 InvB m_invB;
529 BR m_bR;
530 BZ m_bZ;
531};
532
534struct TrueCurvatureKappaR: public aCylindricalFunctor<TrueCurvatureKappaR>
535{
536 TrueCurvatureKappaR( const TokamakMagneticField& mag):m_mag(mag), m_invB(mag), m_bZ(mag){ }
537 double do_compute( double R, double Z) const
538 {
539 double invB = m_invB(R,Z);
540 return m_mag.R0()*invB*invB/R*(m_mag.ipolZ()(R,Z) - m_mag.ipol()(R,Z)*invB*m_bZ(R,Z));
541 }
542 private:
544 InvB m_invB;
545 BZ m_bZ;
546};
547
549struct TrueCurvatureKappaZ: public aCylindricalFunctor<TrueCurvatureKappaZ>
550{
551 TrueCurvatureKappaZ( const TokamakMagneticField& mag):m_mag(mag), m_invB(mag), m_bR(mag){ }
552 double do_compute( double R, double Z) const
553 {
554 double invB = m_invB(R,Z);
555 return m_mag.R0()*invB*invB/R*( - m_mag.ipolR()(R,Z) + m_mag.ipol()(R,Z)*invB*m_bR(R,Z));
556 }
557 private:
559 InvB m_invB;
560 BR m_bR;
561};
563struct TrueCurvatureKappaP: public aCylindricalFunctor<TrueCurvatureKappaP>
564{
565 TrueCurvatureKappaP( const TokamakMagneticField& mag):m_mag(mag), m_invB(mag), m_bR(mag), m_bZ(mag){ }
566 double do_compute( double R, double Z) const
567 {
568 double invB = m_invB(R,Z);
569 return m_mag.R0()*invB*invB/R/R*(
570 + invB*m_mag.psipZ()(R,Z)*m_bZ(R,Z) + invB *m_mag.psipR()(R,Z)*m_bR(R,Z)
571 + m_mag.psipR()(R,Z)/R - m_mag.psipRR()(R,Z) - m_mag.psipZZ()(R,Z));
572 }
573 private:
575 InvB m_invB;
576 BR m_bR;
577 BZ m_bZ;
578};
579
581struct TrueDivCurvatureKappa: public aCylindricalFunctor<TrueDivCurvatureKappa>
582{
583 TrueDivCurvatureKappa( const TokamakMagneticField& mag): m_mag(mag), m_invB(mag), m_bR(mag), m_bZ(mag){}
584 double do_compute( double R, double Z) const
585 {
586 double invB = m_invB(R,Z);
587 return m_mag.R0()*invB*invB*invB/R*( m_mag.ipolR()(R,Z)*m_bZ(R,Z) - m_mag.ipolZ()(R,Z)*m_bR(R,Z) );
588 }
589 private:
591 InvB m_invB;
592 BR m_bR;
593 BZ m_bZ;
594};
595
597struct TrueDivCurvatureNablaB: public aCylindricalFunctor<TrueDivCurvatureNablaB>
598{
600 double do_compute( double R, double Z) const {
601 return - m_div(R,Z);
602 }
603 private:
605};
606
612struct GradLnB: public aCylindricalFunctor<GradLnB>
613{
614 GradLnB( const TokamakMagneticField& mag): m_mag(mag), m_invB(mag), m_bR(mag), m_bZ(mag) { }
615 double do_compute( double R, double Z) const
616 {
617 double invB = m_invB(R,Z);
618 return m_mag.R0()*invB*invB*(m_bR(R,Z)*m_mag.psipZ()(R,Z)-m_bZ(R,Z)*m_mag.psipR()(R,Z))/R ;
619 }
620 private:
622 InvB m_invB;
623 BR m_bR;
624 BZ m_bZ;
625};
632struct Divb: public aCylindricalFunctor<Divb>
633{
634 Divb( const TokamakMagneticField& mag): m_gradLnB(mag) { }
635 double do_compute( double R, double Z) const
636 {
637 return -m_gradLnB(R,Z);
638 }
639 private:
640 GradLnB m_gradLnB;
641};
642
644struct BFieldP: public aCylindricalFunctor<BFieldP>
645{
646 BFieldP( const TokamakMagneticField& mag): m_mag(mag){}
647 double do_compute( double R, double Z) const
648 {
649 return m_mag.R0()*m_mag.ipol()(R,Z)/R/R;
650 }
651 private:
652
654};
655
657struct BFieldR: public aCylindricalFunctor<BFieldR>
658{
659 BFieldR( const TokamakMagneticField& mag): m_mag(mag){}
660 double do_compute( double R, double Z) const
661 {
662 return m_mag.R0()/R*m_mag.psipZ()(R,Z);
663 }
664 private:
666
667};
668
670struct BFieldZ: public aCylindricalFunctor<BFieldZ>
671{
672 BFieldZ( const TokamakMagneticField& mag): m_mag(mag){}
673 double do_compute( double R, double Z) const
674 {
675 return -m_mag.R0()/R*m_mag.psipR()(R,Z);
676 }
677 private:
679};
680
682struct BFieldT: public aCylindricalFunctor<BFieldT>
683{
684 BFieldT( const TokamakMagneticField& mag): m_R0(mag.R0()), m_fieldR(mag), m_fieldZ(mag){}
685 double do_compute(double R, double Z) const
686 {
687 double r2 = (R-m_R0)*(R-m_R0) + Z*Z;
688 return m_fieldR(R,Z)*(-Z/r2) + m_fieldZ(R,Z)*(R-m_R0)/r2;
689 }
690 private:
691 double m_R0;
692 BFieldR m_fieldR;
693 BFieldZ m_fieldZ;
694};
695
697struct BHatR: public aCylindricalFunctor<BHatR>
698{
699 BHatR( const TokamakMagneticField& mag): m_mag(mag), m_invB(mag){ }
700 double do_compute( double R, double Z) const
701 {
702 return m_invB(R,Z)*m_mag.R0()/R*m_mag.psipZ()(R,Z);
703 }
704 private:
706 InvB m_invB;
707
708};
709
711struct BHatZ: public aCylindricalFunctor<BHatZ>
712{
713 BHatZ( const TokamakMagneticField& mag): m_mag(mag), m_invB(mag){ }
714 double do_compute( double R, double Z) const
715 {
716 return -m_invB(R,Z)*m_mag.R0()/R*m_mag.psipR()(R,Z);
717 }
718 private:
720 InvB m_invB;
721};
722
724struct BHatP: public aCylindricalFunctor<BHatP>
725{
726 BHatP( const TokamakMagneticField& mag): m_mag(mag), m_invB(mag){ }
727 double do_compute( double R, double Z) const
728 {
729 return m_invB(R,Z)*m_mag.R0()*m_mag.ipol()(R,Z)/R/R;
730 }
731 private:
733 InvB m_invB;
734};
735
736
746 if( sign > 0)
747 return CylindricalVectorLvl1( Constant(0), Constant(0), [](double x, double y){ return 1./x;}, Constant(0), Constant(0));
748 return CylindricalVectorLvl1( Constant(0), Constant(0), [](double x, double y){ return -1./x;}, Constant(0), Constant(0));
749}
759 return CylindricalVectorLvl0( CurvatureNablaBR(mag, sign), CurvatureNablaBZ(mag, sign), Constant(0));
760}
770 return CylindricalVectorLvl0( CurvatureKappaR(mag, sign), CurvatureKappaZ(mag, sign), Constant(0));
771}
781}
791}
800 return CylindricalVectorLvl0( mag.psipR(), mag.psipZ(),Constant(0));
801}
802
803
805struct BHatRR: public aCylindricalFunctor<BHatRR>
806{
807 BHatRR( const TokamakMagneticField& mag): m_invB(mag), m_br(mag), m_mag(mag){}
808 double do_compute( double R, double Z) const
809 {
810 double psipZ = m_mag.psipZ()(R,Z);
811 double psipRZ = m_mag.psipRZ()(R,Z);
812 double binv = m_invB(R,Z);
813 return -psipZ*m_mag.R0()*binv/R/R + psipRZ*binv*m_mag.R0()/R
814 -psipZ*m_mag.R0()/R*binv*binv*m_br(R,Z);
815 }
816 private:
817 InvB m_invB;
818 BR m_br;
820};
822struct BHatRZ: public aCylindricalFunctor<BHatRZ>
823{
824 BHatRZ( const TokamakMagneticField& mag): m_invB(mag), m_bz(mag), m_mag(mag){}
825 double do_compute( double R, double Z) const
826 {
827 double psipZ = m_mag.psipZ()(R,Z);
828 double psipZZ = m_mag.psipZZ()(R,Z);
829 double binv = m_invB(R,Z);
830 return m_mag.R0()/R*( psipZZ*binv -binv*binv*m_bz(R,Z)*psipZ );
831 }
832 private:
833 InvB m_invB;
834 BZ m_bz;
836};
838struct BHatZR: public aCylindricalFunctor<BHatZR>
839{
840 BHatZR( const TokamakMagneticField& mag): m_invB(mag), m_br(mag), m_mag(mag){}
841 double do_compute( double R, double Z) const
842 {
843 double psipR = m_mag.psipR()(R,Z);
844 double psipRR = m_mag.psipRR()(R,Z);
845 double binv = m_invB(R,Z);
846 return +psipR*m_mag.R0()*binv/R/R - psipRR*binv*m_mag.R0()/R
847 +psipR*m_mag.R0()/R*binv*binv*m_br(R,Z);
848 }
849 private:
850 InvB m_invB;
851 BR m_br;
853};
855struct BHatZZ: public aCylindricalFunctor<BHatZZ>
856{
857 BHatZZ( const TokamakMagneticField& mag): m_invB(mag), m_bz(mag), m_mag(mag){}
858 double do_compute( double R, double Z) const
859 {
860 double psipR = m_mag.psipR()(R,Z);
861 double psipRZ = m_mag.psipRZ()(R,Z);
862 double binv = m_invB(R,Z);
863 return -m_mag.R0()/R*( psipRZ*binv -binv*binv*m_bz(R,Z)*psipR );
864 }
865 private:
866 InvB m_invB;
867 BZ m_bz;
869};
871struct BHatPR: public aCylindricalFunctor<BHatPR>
872{
873 BHatPR( const TokamakMagneticField& mag): m_mag(mag), m_invB(mag), m_br(mag){ }
874 double do_compute( double R, double Z) const
875 {
876 double binv = m_invB(R,Z);
877 double ipol = m_mag.ipol()(R,Z);
878 double ipolR = m_mag.ipolR()(R,Z);
879 return -binv*binv*m_br(R,Z)*m_mag.R0()*ipol/R/R
880 - 2./R/R/R*binv*m_mag.R0()*ipol
881 + binv *m_mag.R0()/R/R*ipolR;
882 }
883 private:
885 InvB m_invB;
886 BR m_br;
887};
889struct BHatPZ: public aCylindricalFunctor<BHatPZ>
890{
891 BHatPZ( const TokamakMagneticField& mag): m_mag(mag), m_invB(mag), m_bz(mag){ }
892 double do_compute( double R, double Z) const
893 {
894 double binv = m_invB(R,Z);
895 double ipol = m_mag.ipol()(R,Z);
896 double ipolZ = m_mag.ipolZ()(R,Z);
897 return -binv*binv*m_bz(R,Z)*m_mag.R0()*ipol/R/R
898 + binv *m_mag.R0()/R/R*ipolZ;
899 }
900 private:
902 InvB m_invB;
903 BZ m_bz;
904};
905
907struct DivVVP: public aCylindricalFunctor<DivVVP>
908{
909 DivVVP( const TokamakMagneticField& mag): m_mag(mag),
910 m_bhatP(mag){ }
911 double do_compute( double R, double Z) const
912 {
913 double ipol = m_mag.ipol()(R,Z), ipolR = m_mag.ipolR()(R,Z),
914 ipolZ = m_mag.ipolZ()(R,Z);
915 double psipR = m_mag.psipR()(R,Z), psipZ = m_mag.psipZ()(R,Z);
916 double bphi = m_bhatP(R,Z);
917 return -(psipZ*(ipolR/R - 2.*ipol/R/R) - ipolZ/R*psipR)/
918 (ipol*ipol + psipR*psipR + psipZ*psipZ)/bphi/bphi;
919 }
920 private:
922 BHatP m_bhatP;
923};
924
932 return CylindricalVectorLvl1( BHatR(mag), BHatZ(mag), BHatP(mag),
933 Divb(mag), DivVVP(mag)
934 );
935}
936
937/*@brief \f$ \sqrt{1. - \psi_p/ \psi_{p,O}} \f$
938 *
939 * @attention undefined if there is no O-point near [R_0 , 0], except for
940 * \c description::centeredX when we take psipO = -10
941 */
942struct RhoP: public aCylindricalFunctor<RhoP>
943{
944 RhoP( const TokamakMagneticField& mag): m_mag(mag){
945 double RO = m_mag.R0(), ZO = 0;
946 try{
947 findOpoint( mag.get_psip(), RO, ZO);
948 m_psipmin = m_mag.psip()(RO, ZO);
949 } catch ( dg::Error& err)
950 {
951 m_psipmin = 1.;
953 m_psipmin = -10;
954 }
955 }
956 double do_compute( double R, double Z) const
957 {
958 return sqrt( 1.-m_mag.psip()(R,Z)/m_psipmin ) ;
959 }
960 private:
961 double m_psipmin;
963
964};
965
968{
970 double do_compute( double R, double Z) const
971 {
972 double psipR = m_mag.psipR()(R,Z), psipZ = m_mag.psipZ()(R,Z), ipol = m_mag.ipol()(R,Z);
973 double psip2 = psipR*psipR+psipZ*psipZ;
974 if( psip2 == 0)
975 psip2 = 1e-16;
976 return (ipol*ipol + psip2)/R/R/psip2;
977 }
978 private:
980};
981
985struct WallDirection : public dg::geo::aCylindricalFunctor<WallDirection>
986{
995 vertical, std::vector<double> horizontal) : m_vertical(vertical),
996 m_horizontal(horizontal), m_BR( mag), m_BZ(mag){}
1004 dg::Grid2d walls) : m_vertical({walls.x0(), walls.x1()}),
1005 m_horizontal({walls.y0(), walls.y1()}), m_BR( mag), m_BZ(mag){}
1006 double do_compute ( double R, double Z) const
1007 {
1008 std::vector<double> v_dist(1,1e100), h_dist(1,1e100);
1009 for( auto v : m_vertical)
1010 v_dist.push_back( R-v );
1011 for( auto h : m_horizontal)
1012 h_dist.push_back( Z-h );
1013 double v_min = *std::min_element( v_dist.begin(), v_dist.end(),
1014 [](double a, double b){ return fabs(a) < fabs(b);} );
1015 double h_min = *std::min_element( h_dist.begin(), h_dist.end(),
1016 [](double a, double b){ return fabs(a) < fabs(b);} );
1017 if( fabs(v_min) < fabs(h_min) ) // if vertical R wall is closer
1018 {
1019 double br = m_BR( R,Z);
1020 return v_min*br < 0 ? +1 : -1;
1021 }
1022 else //horizontal Z wall is closer
1023 {
1024 double bz = m_BZ( R,Z);
1025 return h_min*bz < 0 ? +1 : -1;
1026 }
1027 }
1028 private:
1029 std::vector<double> m_vertical, m_horizontal;
1030 dg::geo::BFieldR m_BR;
1031 dg::geo::BFieldZ m_BZ;
1032};
1034
1035} //namespace geo
1036} //namespace dg
1037
static bc inverse(bc bound)
modifier
How flux-function is modified.
Definition: magnetic_field.h:36
CylindricalVectorLvl0 createCurvatureNablaB(const TokamakMagneticField &mag, int sign)
Approximate curvature vector field (CurvatureNablaBR, CurvatureNablaBZ, Constant(0))
Definition: magnetic_field.h:758
CylindricalVectorLvl0 createGradPsip(const TokamakMagneticField &mag)
Gradient Psip vector field (PsipR, PsipZ, 0)
Definition: magnetic_field.h:799
CylindricalVectorLvl0 createTrueCurvatureNablaB(const TokamakMagneticField &mag)
True curvature vector field (TrueCurvatureNablaBR, TrueCurvatureNablaBZ, TrueCurvatureNablaBP)
Definition: magnetic_field.h:789
CylindricalVectorLvl0 createTrueCurvatureKappa(const TokamakMagneticField &mag)
True curvature vector field (TrueCurvatureKappaR, TrueCurvatureKappaZ, TrueCurvatureKappaP)
Definition: magnetic_field.h:779
CylindricalVectorLvl0 createCurvatureKappa(const TokamakMagneticField &mag, int sign)
Approximate curvature vector field (CurvatureKappaR, CurvatureKappaZ, Constant(0))
Definition: magnetic_field.h:769
static TokamakMagneticField periodify(const TokamakMagneticField &mag, double R0, double R1, double Z0, double Z1, dg::bc bcx, dg::bc bcy)
Use dg::geo::Periodify to periodify every function in the magnetic field.
Definition: magnetic_field.h:247
equilibrium
How flux-function is computed. Decides how to construct magnetic field.
Definition: magnetic_field.h:26
description
How flux function looks like. Decider on whether and what flux aligned grid to construct.
Definition: magnetic_field.h:48
CylindricalVectorLvl1 createBHat(const TokamakMagneticField &mag)
Contravariant components of the magnetic unit vector field and its Divergence and derivative in cylin...
Definition: magnetic_field.h:931
CylindricalVectorLvl1 createEPhi(int sign)
Contravariant components of the unit vector field (0, 0, +/- 1/R) and its Divergence and derivative (...
Definition: magnetic_field.h:745
@ none
no modification
@ sol_pfr
Psip is dampened in the SOL and PFR regions but not in the closed field line region.
@ heaviside
Psip is dampened to a constant outside a critical value.
@ solovev
dg::geo::solovev::Psip
@ taylor
dg::geo::taylor::Psip
@ polynomial
dg::geo::polynomial::Psip
@ guenter
dg::geo::guenter::Psip
@ toroidal
dg::geo::createToroidalField
@ circular
dg::geo::circular::Psip
@ square
closed flux surfaces centered around an O-point and bordered by a square with four X-points in the co...
@ none
no shaping: Purely toroidal magnetic field
@ standardO
closed flux surfaces centered around an O-point located near (R_0, 0); flux-aligned grids can be cons...
@ doubleX
closed flux surfaces centered around an O-point located near (R_0, 0) and bordered by a separatrix wi...
@ centeredX
one X-point in the middle, no O-point, only open flux surfaces, X-grids cannot be constructed
@ standardX
closed flux surfaces centered around an O-point located near (R_0, 0) and bordered by a separatrix wi...
static int findOpoint(const CylindricalFunctorsLvl2 &psi, double &RC, double &ZC)
This function finds O-points of psi.
Definition: fluxfunctions.h:332
real_type x0() const
real_type x1() const
Definition: magnetic_field.h:645
double do_compute(double R, double Z) const
Definition: magnetic_field.h:647
BFieldP(const TokamakMagneticField &mag)
Definition: magnetic_field.h:646
Definition: magnetic_field.h:658
BFieldR(const TokamakMagneticField &mag)
Definition: magnetic_field.h:659
double do_compute(double R, double Z) const
Definition: magnetic_field.h:660
Definition: magnetic_field.h:683
BFieldT(const TokamakMagneticField &mag)
Definition: magnetic_field.h:684
double do_compute(double R, double Z) const
Definition: magnetic_field.h:685
Definition: magnetic_field.h:671
double do_compute(double R, double Z) const
Definition: magnetic_field.h:673
BFieldZ(const TokamakMagneticField &mag)
Definition: magnetic_field.h:672
Definition: magnetic_field.h:725
double do_compute(double R, double Z) const
Definition: magnetic_field.h:727
BHatP(const TokamakMagneticField &mag)
Definition: magnetic_field.h:726
Definition: magnetic_field.h:872
BHatPR(const TokamakMagneticField &mag)
Definition: magnetic_field.h:873
double do_compute(double R, double Z) const
Definition: magnetic_field.h:874
Definition: magnetic_field.h:890
double do_compute(double R, double Z) const
Definition: magnetic_field.h:892
BHatPZ(const TokamakMagneticField &mag)
Definition: magnetic_field.h:891
Definition: magnetic_field.h:698
BHatR(const TokamakMagneticField &mag)
Definition: magnetic_field.h:699
double do_compute(double R, double Z) const
Definition: magnetic_field.h:700
Definition: magnetic_field.h:806
BHatRR(const TokamakMagneticField &mag)
Definition: magnetic_field.h:807
double do_compute(double R, double Z) const
Definition: magnetic_field.h:808
Definition: magnetic_field.h:823
double do_compute(double R, double Z) const
Definition: magnetic_field.h:825
BHatRZ(const TokamakMagneticField &mag)
Definition: magnetic_field.h:824
Definition: magnetic_field.h:712
BHatZ(const TokamakMagneticField &mag)
Definition: magnetic_field.h:713
double do_compute(double R, double Z) const
Definition: magnetic_field.h:714
Definition: magnetic_field.h:839
BHatZR(const TokamakMagneticField &mag)
Definition: magnetic_field.h:840
double do_compute(double R, double Z) const
Definition: magnetic_field.h:841
Definition: magnetic_field.h:856
double do_compute(double R, double Z) const
Definition: magnetic_field.h:858
BHatZZ(const TokamakMagneticField &mag)
Definition: magnetic_field.h:857
Definition: magnetic_field.h:329
double do_compute(double R, double Z) const
Definition: magnetic_field.h:331
BR(const TokamakMagneticField &mag)
Definition: magnetic_field.h:330
Definition: magnetic_field.h:351
BZ(const TokamakMagneticField &mag)
Definition: magnetic_field.h:352
double do_compute(double R, double Z) const
Definition: magnetic_field.h:353
Definition: magnetic_field.h:269
Bmodule(const TokamakMagneticField &mag)
Definition: magnetic_field.h:270
double do_compute(double R, double Z) const
Definition: magnetic_field.h:271
Definition: fluxfunctions.h:114
Approximate .
Definition: magnetic_field.h:412
CurvatureKappaR(const TokamakMagneticField &mag, int sign=+1)
Definition: magnetic_field.h:414
CurvatureKappaR()
Definition: magnetic_field.h:413
double do_compute(double R, double Z) const
Definition: magnetic_field.h:415
Approximate .
Definition: magnetic_field.h:427
double do_compute(double R, double Z) const
Definition: magnetic_field.h:434
CurvatureKappaZ(const TokamakMagneticField &mag, int sign)
Definition: magnetic_field.h:428
Approximate .
Definition: magnetic_field.h:368
CurvatureNablaBR(const TokamakMagneticField &mag, int sign)
Definition: magnetic_field.h:369
double do_compute(double R, double Z) const
Definition: magnetic_field.h:375
Approximate .
Definition: magnetic_field.h:390
CurvatureNablaBZ(const TokamakMagneticField &mag, int sign)
Definition: magnetic_field.h:391
double do_compute(double R, double Z) const
Definition: magnetic_field.h:397
This struct bundles a function and its first derivatives.
Definition: fluxfunctions.h:182
const CylindricalFunctor & dfx() const
Definition: fluxfunctions.h:205
const CylindricalFunctor & f() const
Definition: fluxfunctions.h:203
const CylindricalFunctor & dfy() const
Definition: fluxfunctions.h:207
This struct bundles a function and its first and second derivatives.
Definition: fluxfunctions.h:219
const CylindricalFunctor & dfxy() const
Definition: fluxfunctions.h:251
const CylindricalFunctor & dfy() const
Definition: fluxfunctions.h:247
const CylindricalFunctor & dfx() const
Definition: fluxfunctions.h:245
const CylindricalFunctor & dfxx() const
Definition: fluxfunctions.h:249
const CylindricalFunctor & f() const
Definition: fluxfunctions.h:243
const CylindricalFunctor & dfyy() const
Definition: fluxfunctions.h:253
Definition: fluxfunctions.h:412
This struct bundles a vector field and its divergence.
Definition: fluxfunctions.h:440
Approximate .
Definition: magnetic_field.h:448
DivCurvatureKappa(const TokamakMagneticField &mag, int sign)
Definition: magnetic_field.h:449
double do_compute(double R, double Z) const
Definition: magnetic_field.h:455
Approximate .
Definition: magnetic_field.h:470
double do_compute(double R, double Z) const
Definition: magnetic_field.h:472
DivCurvatureNablaB(const TokamakMagneticField &mag, int sign)
Definition: magnetic_field.h:471
Definition: magnetic_field.h:908
double do_compute(double R, double Z) const
Definition: magnetic_field.h:911
DivVVP(const TokamakMagneticField &mag)
Definition: magnetic_field.h:909
Definition: magnetic_field.h:633
double do_compute(double R, double Z) const
Definition: magnetic_field.h:635
Divb(const TokamakMagneticField &mag)
Definition: magnetic_field.h:634
Definition: magnetic_field.h:613
GradLnB(const TokamakMagneticField &mag)
Definition: magnetic_field.h:614
double do_compute(double R, double Z) const
Definition: magnetic_field.h:615
Inertia factor .
Definition: magnetic_field.h:968
Hoo(dg::geo::TokamakMagneticField mag)
Definition: magnetic_field.h:969
double do_compute(double R, double Z) const
Definition: magnetic_field.h:970
Definition: magnetic_field.h:288
InvB(const TokamakMagneticField &mag)
Definition: magnetic_field.h:289
double do_compute(double R, double Z) const
Definition: magnetic_field.h:290
Definition: magnetic_field.h:257
double do_compute(double R, double Z) const
Definition: magnetic_field.h:259
LaplacePsip(const TokamakMagneticField &mag)
Definition: magnetic_field.h:258
Definition: magnetic_field.h:307
double do_compute(double R, double Z) const
Definition: magnetic_field.h:309
LnB(const TokamakMagneticField &mag)
Definition: magnetic_field.h:308
Meta-data about the magnetic field in particular the flux function.
Definition: magnetic_field.h:91
double a() const
The minor radius.
Definition: magnetic_field.h:122
modifier getModifier() const
the way the flux function is modified
Definition: magnetic_field.h:138
MagneticFieldParameters(double a, double elongation, double triangularity, equilibrium equ, modifier mod, description des)
Constructor.
Definition: magnetic_field.h:111
description getDescription() const
how the flux function looks
Definition: magnetic_field.h:140
double elongation() const
Definition: magnetic_field.h:128
double triangularity() const
Definition: magnetic_field.h:134
equilibrium getEquilibrium() const
the way the flux function is computed
Definition: magnetic_field.h:136
MagneticFieldParameters()
Default values are for a Toroidal field.
Definition: magnetic_field.h:95
Definition: magnetic_field.h:943
double do_compute(double R, double Z) const
Definition: magnetic_field.h:956
RhoP(const TokamakMagneticField &mag)
Definition: magnetic_field.h:944
A tokamak field as given by R0, Psi and Ipol plus Meta-data like shape and equilibrium.
Definition: magnetic_field.h:162
const CylindricalFunctor & psipR() const
, where R, Z are cylindrical coordinates
Definition: magnetic_field.h:181
const CylindricalFunctorsLvl2 & get_psip() const
Definition: magnetic_field.h:197
const CylindricalFunctor & psipRR() const
, where R, Z are cylindrical coordinates
Definition: magnetic_field.h:185
TokamakMagneticField()
as long as the field stays empty the access functions are undefined
Definition: magnetic_field.h:164
const CylindricalFunctor & ipol() const
the current
Definition: magnetic_field.h:191
const CylindricalFunctor & ipolR() const
Definition: magnetic_field.h:193
const CylindricalFunctor & psipZZ() const
, where R, Z are cylindrical coordinates
Definition: magnetic_field.h:189
const CylindricalFunctorsLvl1 & get_ipol() const
Definition: magnetic_field.h:198
const MagneticFieldParameters & params() const
Access Meta-data of the field.
Definition: magnetic_field.h:204
const CylindricalFunctor & psipZ() const
, where R, Z are cylindrical coordinates
Definition: magnetic_field.h:183
double R0() const
Definition: magnetic_field.h:177
const CylindricalFunctor & ipolZ() const
Definition: magnetic_field.h:195
void set(double R0, const CylindricalFunctorsLvl2 &psip, const CylindricalFunctorsLvl1 &ipol, MagneticFieldParameters gp)
Definition: magnetic_field.h:168
const CylindricalFunctor & psipRZ() const
, where R, Z are cylindrical coordinates
Definition: magnetic_field.h:187
const CylindricalFunctor & psip() const
, where R, Z are cylindrical coordinates
Definition: magnetic_field.h:179
TokamakMagneticField(double R0, const CylindricalFunctorsLvl2 &psip, const CylindricalFunctorsLvl1 &ipol, MagneticFieldParameters gp)
Definition: magnetic_field.h:165
True .
Definition: magnetic_field.h:564
TrueCurvatureKappaP(const TokamakMagneticField &mag)
Definition: magnetic_field.h:565
double do_compute(double R, double Z) const
Definition: magnetic_field.h:566
True .
Definition: magnetic_field.h:535
double do_compute(double R, double Z) const
Definition: magnetic_field.h:537
TrueCurvatureKappaR(const TokamakMagneticField &mag)
Definition: magnetic_field.h:536
True .
Definition: magnetic_field.h:550
TrueCurvatureKappaZ(const TokamakMagneticField &mag)
Definition: magnetic_field.h:551
double do_compute(double R, double Z) const
Definition: magnetic_field.h:552
True .
Definition: magnetic_field.h:519
double do_compute(double R, double Z) const
Definition: magnetic_field.h:521
TrueCurvatureNablaBP(const TokamakMagneticField &mag)
Definition: magnetic_field.h:520
True .
Definition: magnetic_field.h:483
double do_compute(double R, double Z) const
Definition: magnetic_field.h:485
TrueCurvatureNablaBR(const TokamakMagneticField &mag)
Definition: magnetic_field.h:484
True .
Definition: magnetic_field.h:501
double do_compute(double R, double Z) const
Definition: magnetic_field.h:503
TrueCurvatureNablaBZ(const TokamakMagneticField &mag)
Definition: magnetic_field.h:502
True .
Definition: magnetic_field.h:582
double do_compute(double R, double Z) const
Definition: magnetic_field.h:584
TrueDivCurvatureKappa(const TokamakMagneticField &mag)
Definition: magnetic_field.h:583
True .
Definition: magnetic_field.h:598
double do_compute(double R, double Z) const
Definition: magnetic_field.h:600
TrueDivCurvatureNablaB(const TokamakMagneticField &mag)
Definition: magnetic_field.h:599
Determine if poloidal field points towards or away from the nearest wall.
Definition: magnetic_field.h:986
WallDirection(dg::geo::TokamakMagneticField mag, std::vector< double > vertical, std::vector< double > horizontal)
Allocate lines.
Definition: magnetic_field.h:994
WallDirection(dg::geo::TokamakMagneticField mag, dg::Grid2d walls)
Allocate lines.
Definition: magnetic_field.h:1003
double do_compute(double R, double Z) const
Definition: magnetic_field.h:1006
Represent functions written in cylindrical coordinates that are independent of the angle phi serving ...
Definition: fluxfunctions.h:66