Extension: Geometries
#include "dg/geometries/geometries.h"
solovev.h
Go to the documentation of this file.
1#pragma once
2
3#include <iostream>
4#include <cmath>
5#include <vector>
6
7#include "dg/blas.h"
8
9#include "dg/algorithm.h"
10#include "solovev_parameters.h"
11#include "magnetic_field.h"
12#include "modified.h"
13
14
19namespace dg
20{
21namespace geo
22{
28namespace solovev
29{
32
60struct Psip: public aCylindricalFunctor<Psip>
61{
67 Psip( Parameters gp ): m_R0(gp.R_0), m_A(gp.A), m_pp(gp.pp), m_c(gp.c) {}
68 double do_compute(double R, double Z) const
69 {
70 double Rn,Rn2,Rn4,Zn,Zn2,Zn3,Zn4,Zn5,Zn6,lgRn;
71 Rn = R/m_R0; Rn2 = Rn*Rn; Rn4 = Rn2*Rn2;
72 Zn = Z/m_R0; Zn2 = Zn*Zn; Zn3 = Zn2*Zn; Zn4 = Zn2*Zn2; Zn5 = Zn3*Zn2; Zn6 = Zn3*Zn3;
73 lgRn= log(Rn);
74 return m_R0*m_pp*( Rn4/8.+ m_A * ( 1./2.* Rn2* lgRn-(Rn4)/8.)
75 + m_c[0] //m_c[0] entspricht c_1
76 + m_c[1] *Rn2
77 + m_c[2] *(Zn2 - Rn2 * lgRn )
78 + m_c[3] *(Rn4 - 4.* Rn2*Zn2 )
79 + m_c[4] *(3.* Rn4 * lgRn -9.*Rn2*Zn2 -12.* Rn2*Zn2 * lgRn + 2.*Zn4)
80 + m_c[5] *(Rn4*Rn2-12.* Rn4*Zn2 +8.* Rn2 *Zn4 )
81 + m_c[6] *(-15.*Rn4*Rn2 * lgRn + 75.* Rn4 *Zn2 + 180.* Rn4*Zn2 * lgRn
82 -140.*Rn2*Zn4 - 120.* Rn2*Zn4 *lgRn + 8.* Zn6 )
83 + m_c[7] *Zn
84 + m_c[8] *Rn2*Zn
85 + m_c[9] *(Zn2*Zn - 3.* Rn2*Zn * lgRn)
86 + m_c[10] *( 3. * Rn4*Zn - 4. * Rn2*Zn3)
87 + m_c[11] *(-45.* Rn4*Zn + 60.* Rn4*Zn* lgRn - 80.* Rn2*Zn3* lgRn + 8. * Zn5)
88 );
89 }
90 private:
91 double m_R0, m_A, m_pp;
92 std::vector<double> m_c;
93};
94
113struct PsipR: public aCylindricalFunctor<PsipR>
114{
116 PsipR( Parameters gp ): m_R0(gp.R_0), m_A(gp.A), m_pp(gp.pp), m_c(gp.c) {}
117 double do_compute(double R, double Z) const
118 {
119 double Rn,Rn2,Rn3,Rn5,Zn,Zn2,Zn3,Zn4,lgRn;
120 Rn = R/m_R0; Rn2 = Rn*Rn; Rn3 = Rn2*Rn; Rn5 = Rn3*Rn2;
121 Zn = Z/m_R0; Zn2 =Zn*Zn; Zn3 = Zn2*Zn; Zn4 = Zn2*Zn2;
122 lgRn= log(Rn);
123 return m_pp*(Rn3/2. + (Rn/2. - Rn3/2. + Rn*lgRn)* m_A +
124 2.* Rn* m_c[1] + (-Rn - 2.* Rn*lgRn)* m_c[2] + (4.*Rn3 - 8.* Rn *Zn2)* m_c[3] +
125 (3. *Rn3 - 30.* Rn *Zn2 + 12. *Rn3*lgRn - 24.* Rn *Zn2*lgRn)* m_c[4]
126 + (6 *Rn5 - 48 *Rn3 *Zn2 + 16.* Rn *Zn4)*m_c[5]
127 + (-15. *Rn5 + 480. *Rn3 *Zn2 - 400.* Rn *Zn4 - 90. *Rn5*lgRn +
128 720. *Rn3 *Zn2*lgRn - 240.* Rn *Zn4*lgRn)* m_c[6] +
129 2.* Rn *Zn *m_c[8] + (-3. *Rn *Zn - 6.* Rn* Zn*lgRn)* m_c[9] + (12. *Rn3* Zn - 8.* Rn *Zn3)* m_c[10] + (-120. *Rn3* Zn - 80.* Rn *Zn3 + 240. *Rn3* Zn*lgRn -
130 160.* Rn *Zn3*lgRn) *m_c[11]
131 );
132 }
133 private:
134 double m_R0, m_A, m_pp;
135 std::vector<double> m_c;
136};
154struct PsipRR: public aCylindricalFunctor<PsipRR>
155{
157 PsipRR( Parameters gp ): m_R0(gp.R_0), m_A(gp.A), m_pp(gp.pp), m_c(gp.c) {}
158 double do_compute(double R, double Z) const
159 {
160 double Rn,Rn2,Rn4,Zn,Zn2,Zn3,Zn4,lgRn;
161 Rn = R/m_R0; Rn2 = Rn*Rn; Rn4 = Rn2*Rn2;
162 Zn = Z/m_R0; Zn2 =Zn*Zn; Zn3 = Zn2*Zn; Zn4 = Zn2*Zn2;
163 lgRn= log(Rn);
164 return m_pp/m_R0*( (3.* Rn2)/2. + (3./2. - (3. *Rn2)/2. +lgRn) *m_A + 2.* m_c[1] + (-3. - 2.*lgRn)* m_c[2] + (12. *Rn2 - 8. *Zn2) *m_c[3] +
165 (21. *Rn2 - 54. *Zn2 + 36. *Rn2*lgRn - 24. *Zn2*lgRn)* m_c[4]
166 + (30. *Rn4 - 144. *Rn2 *Zn2 + 16.*Zn4)*m_c[5] + (-165. *Rn4 + 2160. *Rn2 *Zn2 - 640. *Zn4 - 450. *Rn4*lgRn +
167 2160. *Rn2 *Zn2*lgRn - 240. *Zn4*lgRn)* m_c[6] +
168 2.* Zn* m_c[8] + (-9. *Zn - 6.* Zn*lgRn) *m_c[9]
169 + (36. *Rn2* Zn - 8. *Zn3) *m_c[10]
170 + (-120. *Rn2* Zn - 240. *Zn3 + 720. *Rn2* Zn*lgRn - 160. *Zn3*lgRn)* m_c[11]);
171 }
172 private:
173 double m_R0, m_A, m_pp;
174 std::vector<double> m_c;
175};
190struct PsipZ: public aCylindricalFunctor<PsipZ>
191{
193 PsipZ( Parameters gp ): m_R0(gp.R_0), m_pp(gp.pp), m_c(gp.c) { }
194 double do_compute(double R, double Z) const
195 {
196 double Rn,Rn2,Rn4,Zn,Zn2,Zn3,Zn4,Zn5,lgRn;
197 Rn = R/m_R0; Rn2 = Rn*Rn; Rn4 = Rn2*Rn2;
198 Zn = Z/m_R0; Zn2 = Zn*Zn; Zn3 = Zn2*Zn; Zn4 = Zn2*Zn2; Zn5 = Zn3*Zn2;
199 lgRn= log(Rn);
200
201 return m_pp*(2.* Zn* m_c[2]
202 - 8. *Rn2* Zn* m_c[3] +
203 ((-18.)*Rn2 *Zn + 8. *Zn3 - 24. *Rn2* Zn*lgRn) *m_c[4]
204 + ((-24.) *Rn4* Zn + 32. *Rn2 *Zn3)* m_c[5]
205 + (150. *Rn4* Zn - 560. *Rn2 *Zn3 + 48. *Zn5 + 360. *Rn4* Zn*lgRn - 480. *Rn2 *Zn3*lgRn)* m_c[6]
206 + m_c[7]
207 + Rn2 * m_c[8]
208 + (3. *Zn2 - 3. *Rn2*lgRn)* m_c[9]
209 + (3. *Rn4 - 12. *Rn2 *Zn2) *m_c[10]
210 + ((-45.)*Rn4 + 40. *Zn4 + 60. *Rn4*lgRn - 240. *Rn2 *Zn2*lgRn)* m_c[11]);
211
212 }
213 private:
214 double m_R0, m_pp;
215 std::vector<double> m_c;
216};
228struct PsipZZ: public aCylindricalFunctor<PsipZZ>
229{
231 PsipZZ( Parameters gp): m_R0(gp.R_0), m_pp(gp.pp), m_c(gp.c) { }
232 double do_compute(double R, double Z) const
233 {
234 double Rn,Rn2,Rn4,Zn,Zn2,Zn3,Zn4,lgRn;
235 Rn = R/m_R0; Rn2 = Rn*Rn; Rn4 = Rn2*Rn2;
236 Zn = Z/m_R0; Zn2 =Zn*Zn; Zn3 = Zn2*Zn; Zn4 = Zn2*Zn2;
237 lgRn= log(Rn);
238 return m_pp/m_R0*( 2.* m_c[2] - 8. *Rn2* m_c[3] + (-18. *Rn2 + 24. *Zn2 - 24. *Rn2*lgRn) *m_c[4] + (-24.*Rn4 + 96. *Rn2 *Zn2) *m_c[5]
239 + (150. *Rn4 - 1680. *Rn2 *Zn2 + 240. *Zn4 + 360. *Rn4*lgRn - 1440. *Rn2 *Zn2*lgRn)* m_c[6] + 6.* Zn* m_c[9] - 24. *Rn2 *Zn *m_c[10] + (160. *Zn3 - 480. *Rn2* Zn*lgRn) *m_c[11]);
240 }
241 private:
242 double m_R0, m_pp;
243 std::vector<double> m_c;
244};
258struct PsipRZ: public aCylindricalFunctor<PsipRZ>
259{
261 PsipRZ( Parameters gp ): m_R0(gp.R_0), m_pp(gp.pp), m_c(gp.c) { }
262 double do_compute(double R, double Z) const
263 {
264 double Rn,Rn2,Rn3,Zn,Zn2,Zn3,lgRn;
265 Rn = R/m_R0; Rn2 = Rn*Rn; Rn3 = Rn2*Rn;
266 Zn = Z/m_R0; Zn2 =Zn*Zn; Zn3 = Zn2*Zn;
267 lgRn= log(Rn);
268 return m_pp/m_R0*(
269 -16.* Rn* Zn* m_c[3] + (-60.* Rn* Zn - 48.* Rn* Zn*lgRn)* m_c[4] + (-96. *Rn3* Zn + 64.*Rn *Zn3)* m_c[5]
270 + (960. *Rn3 *Zn - 1600.* Rn *Zn3 + 1440. *Rn3* Zn*lgRn - 960. *Rn *Zn3*lgRn) *m_c[6] + 2.* Rn* m_c[8] + (-3.* Rn - 6.* Rn*lgRn)* m_c[9]
271 + (12. *Rn3 - 24.* Rn *Zn2) *m_c[10] + (-120. *Rn3 - 240. *Rn *Zn2 + 240. *Rn3*lgRn - 480.* Rn *Zn2*lgRn)* m_c[11]
272 );
273 }
274 private:
275 double m_R0, m_pp;
276 std::vector<double> m_c;
277};
278
284struct Ipol: public aCylindricalFunctor<Ipol>
285{
292 Ipol( Parameters gp, std::function<double(double,double)> psip ): m_R0(gp.R_0), m_A(gp.A), m_pp(gp.pp), m_pi(gp.pi), m_psip(psip) {
293 if( gp.pp == 0.)
294 m_pp = 1.; //safety measure to avoid divide by zero errors
295 }
296 double do_compute(double R, double Z) const
297 {
298 return m_pi*sqrt(-2.*m_A* m_psip(R,Z) /m_R0/m_pp + 1.);
299 }
300 private:
301 double m_R0, m_A, m_pp, m_pi;
302 std::function<double(double,double)> m_psip;
303};
307struct IpolR: public aCylindricalFunctor<IpolR>
308{
313 IpolR( Parameters gp, std::function<double(double,double)> psip, std::function<double(double,double)> psipR ):
314 m_R0(gp.R_0), m_A(gp.A), m_pp(gp.pp), m_pi(gp.pi), m_psip(psip), m_psipR(psipR) {
315 if( gp.pp == 0.)
316 m_pp = 1.; //safety measure to avoid divide by zero errors
317 }
318 double do_compute(double R, double Z) const
319 {
320 return -m_pi/sqrt(-2.*m_A* m_psip(R,Z) /m_R0/m_pp + 1.)*(m_A*m_psipR(R,Z)/m_R0/m_pp);
321 }
322 private:
323 double m_R0, m_A, m_pp, m_pi;
324 std::function<double(double,double)> m_psip, m_psipR;
325};
329struct IpolZ: public aCylindricalFunctor<IpolZ>
330{
335 IpolZ( Parameters gp, std::function<double(double,double)> psip, std::function<double(double,double)> psipZ ):
336 m_R0(gp.R_0), m_A(gp.A), m_pp(gp.pp), m_pi(gp.pi), m_psip(psip), m_psipZ(psipZ) {
337 if( gp.pp == 0.)
338 m_pp = 1.; //safety measure to avoid divide by zero errors
339 }
340 double do_compute(double R, double Z) const
341 {
342 return -m_pi/sqrt(-2.*m_A* m_psip(R,Z) /m_R0/m_pp + 1.)*(m_A*m_psipZ(R,Z)/m_R0/m_pp);
343 }
344 private:
345 double m_R0, m_A, m_pp, m_pi;
346 std::function<double(double,double)> m_psip, m_psipZ;
347};
348
350{
351 return CylindricalFunctorsLvl2( Psip(gp), PsipR(gp), PsipZ(gp),
352 PsipRR(gp), PsipRZ(gp), PsipZZ(gp));
353}
355{
357 solovev::Ipol(gp, psip.f()),
358 solovev::IpolR(gp,psip.f(), psip.dfx()),
359 solovev::IpolZ(gp,psip.f(), psip.dfy()));
360}
361
364
365} //namespace solovev
366
377{
379 equilibrium::solovev, modifier::none, str2description.at( gp.description)};
382}
401 dg::geo::solovev::Parameters gp, double psi0, double alpha, double sign = -1)
402{
404 equilibrium::solovev, modifier::heaviside, str2description.at( gp.description)};
405 return TokamakMagneticField( gp.R_0,
406 mod::createPsip( mod::everywhere, solovev::createPsip(gp), psi0, alpha, sign),
407 solovev::createIpol( gp, mod::createPsip( mod::everywhere, solovev::createPsip(gp), psi0, alpha, sign)),
408 params);
409}
410
411} //namespace geo
412} //namespace dg
413
@ none
no modification
@ heaviside
Psip is dampened to a constant outside a critical value.
@ solovev
dg::geo::solovev::Psip
static dg::geo::CylindricalFunctorsLvl2 createPsip(const std::function< bool(double, double)> predicate, const CylindricalFunctorsLvl2 &psip, double psi0, double alpha, double sign=-1)
Definition: modified.h:175
static dg::geo::CylindricalFunctorsLvl1 createIpol(const Parameters &gp, const CylindricalFunctorsLvl1 &psip)
Definition: solovev.h:354
static dg::geo::TokamakMagneticField createModifiedSolovevField(dg::geo::solovev::Parameters gp, double psi0, double alpha, double sign=-1)
DEPRECATED Create a modified Solovev Magnetic field.
Definition: solovev.h:400
static dg::geo::TokamakMagneticField createSolovevField(dg::geo::solovev::Parameters gp)
Create a Solovev Magnetic field.
Definition: solovev.h:375
static dg::geo::CylindricalFunctorsLvl2 createPsip(const Parameters &gp)
Definition: solovev.h:349
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
Meta-data about the magnetic field in particular the flux function.
Definition: magnetic_field.h:91
A tokamak field as given by R0, Psi and Ipol plus Meta-data like shape and equilibrium.
Definition: magnetic_field.h:162
Represent functions written in cylindrical coordinates that are independent of the angle phi serving ...
Definition: fluxfunctions.h:66
Definition: solovev.h:285
Ipol(Parameters gp, std::function< double(double, double)> psip)
Construct from given geometric parameters.
Definition: solovev.h:292
double do_compute(double R, double Z) const
Definition: solovev.h:296
Definition: solovev.h:308
IpolR(Parameters gp, std::function< double(double, double)> psip, std::function< double(double, double)> psipR)
Construct from given geometric parameters.
Definition: solovev.h:313
double do_compute(double R, double Z) const
Definition: solovev.h:318
Definition: solovev.h:330
IpolZ(Parameters gp, std::function< double(double, double)> psip, std::function< double(double, double)> psipZ)
Construct from given geometric parameters.
Definition: solovev.h:335
double do_compute(double R, double Z) const
Definition: solovev.h:340
Constructs and display geometric parameters for the solovev and taylor fields.
Definition: solovev_parameters.h:46
double pp
prefactor for Psi_p
Definition: solovev_parameters.h:49
double R_0
major tokamak radius
Definition: solovev_parameters.h:48
double a
little tokamak radius
Definition: solovev_parameters.h:51
std::string description
Definition: solovev_parameters.h:55
double elongation
elongation of the magnetic surfaces
Definition: solovev_parameters.h:52
double triangularity
triangularity of the magnetic surfaces
Definition: solovev_parameters.h:53
Definition: solovev.h:61
double do_compute(double R, double Z) const
Definition: solovev.h:68
Psip(Parameters gp)
Construct from given geometric parameters.
Definition: solovev.h:67
Definition: solovev.h:114
double do_compute(double R, double Z) const
Definition: solovev.h:117
PsipR(Parameters gp)
Construct from given geometric parameters.
Definition: solovev.h:116
Definition: solovev.h:155
double do_compute(double R, double Z) const
Definition: solovev.h:158
PsipRR(Parameters gp)
Construct from given geometric parameters.
Definition: solovev.h:157
Definition: solovev.h:259
double do_compute(double R, double Z) const
Definition: solovev.h:262
PsipRZ(Parameters gp)
Construct from given geometric parameters.
Definition: solovev.h:261
Definition: solovev.h:191
PsipZ(Parameters gp)
Construct from given geometric parameters.
Definition: solovev.h:193
double do_compute(double R, double Z) const
Definition: solovev.h:194
Definition: solovev.h:229
PsipZZ(Parameters gp)
Construct from given geometric parameters.
Definition: solovev.h:231
double do_compute(double R, double Z) const
Definition: solovev.h:232