Extension: Geometries
#include "dg/geometries/geometries.h"
average.h
Go to the documentation of this file.
1#pragma once
2
3#include <thrust/host_vector.h>
5#include "magnetic_field.h"
6#include "flux.h"
7
12namespace dg
13{
14namespace geo
15{
16
25template <class container >
27{
35 FluxSurfaceIntegral(const dg::Grid2d& g2d, const TokamakMagneticField& mag, double width_factor = 1.):
36 m_f(dg::evaluate(dg::one, g2d)), m_g(m_f), m_delta(m_f),
37 m_psi( dg::evaluate( mag.psip(), g2d)),
38 m_w2d ( dg::create::weights( g2d))
39 {
40 thrust::host_vector<double> psipR = dg::evaluate( mag.psipR(), g2d);
41 thrust::host_vector<double> psipZ = dg::evaluate( mag.psipZ(), g2d);
42 double psipRmax = dg::blas1::reduce( psipR, 0., dg::AbsMax<double>() );
43 double psipZmax = dg::blas1::reduce( psipZ, 0., dg::AbsMax<double>() );
44 double deltapsi = 0.5*(psipZmax*g2d.hy() +psipRmax*g2d.hx())/g2d.nx();
45 m_eps = deltapsi*width_factor;
46 }
47 double get_deltapsi() const{return m_eps;}
48
54 void set_left( const container& f){
55 dg::blas1::copy( f, m_f);
56 }
62 void set_right( const container& g){
63 dg::blas1::copy( g, m_g);
64 }
71 double operator()(double psip0)
72 {
73 dg::GaussianX delta( psip0, m_eps, 1./(sqrt(2.*M_PI)*m_eps));
74 dg::blas1::evaluate( m_delta, dg::equals(), delta, m_psi);
75 dg::blas1::pointwiseDot( 1., m_delta, m_f, m_g, 0., m_delta);
76 return dg::blas1::dot( m_delta, m_w2d);
77 }
78 private:
79 double m_eps;
80 container m_f, m_g, m_delta, m_psi;
81 const container m_w2d;
82};
83
84//This method for computing volumes is tested against flux-aligned grids in e.g. flux_t.cu
92template<class container>
94{
101 template<class Geometry2d>
102 FluxVolumeIntegral(const Geometry2d& g2d, const TokamakMagneticField& mag):
103 m_f(dg::evaluate(dg::one, g2d)), m_g(m_f), m_heavi(m_f),
104 m_psi( dg::pullback( mag.psip(), g2d)),
105 m_w2d ( dg::create::volume( g2d))
106 {
107 }
108
114 void set_left( const container& f){
115 dg::blas1::copy( f, m_f);
116 }
122 void set_right( const container& g){
123 dg::blas1::copy( g, m_g);
124 }
131 double operator()(double psip0)
132 {
133 dg::Heaviside heavi( psip0, -1);
134 dg::blas1::evaluate( m_heavi, dg::equals(), heavi, m_psi);
135 dg::blas1::pointwiseDot( 1., m_heavi, m_f, m_g, 0., m_heavi);
136 return dg::blas1::dot( m_heavi, m_w2d);
137 }
138 private:
139 double m_eps;
140 container m_f, m_g, m_heavi, m_psi;
141 const container m_w2d;
142};
143
144
153template <class container >
155{
164 FluxSurfaceAverage( const dg::Grid2d& g2d, const TokamakMagneticField& mag, const container& f, container weights, double width_factor = 1.) :
165 m_avg( g2d,mag, width_factor), m_area( g2d, mag, width_factor)
166 {
167 m_avg.set_left( f);
168 // container gradpsi = dg::evaluate( dg::geo::GradPsip( c), g2d);
169 // dg::blas1::pointwiseDot( weights, gradpsi, weights);
170 m_avg.set_right( weights);
171 m_area.set_right( weights);
172 }
173
174 double get_deltapsi() const{return m_avg.get_deltapsi;}
175
181 void set_container( const container& f){
182 m_avg.set_left( f);
183 }
190 double operator()(double psip0)
191 {
192 return m_avg(psip0)/m_area(psip0);
193 }
194 private:
195 FluxSurfaceIntegral<container> m_avg, m_area;
196};
197
198
199
200
201
212{
219 SafetyFactorAverage(const dg::Grid2d& g2d, const TokamakMagneticField& mag, double width_factor = 1.) :
220 m_fsi( g2d, mag, width_factor)
221 {
222 thrust::host_vector<double> alpha = dg::evaluate( mag.ipol(), g2d);
223 thrust::host_vector<double> R = dg::evaluate( dg::cooX2d, g2d);
224 dg::blas1::pointwiseDivide( alpha, R, alpha);
225 m_fsi.set_left( alpha);
226 }
228 void set_weights( const thrust::host_vector<double>& weights){
229 m_fsi.set_right( weights);
230 }
236 double operator()(double psip0)
237 {
238 return m_fsi( psip0)/(2.*M_PI);
239 }
240 private:
242};
243
244
245
256{
258 m_fpsi( mag.get_psip(), mag.get_ipol(), mag.R0(), 0.,false){}
259
265 double operator()( double psip0)
266 {
267 return 1./m_fpsi( psip0);
268 }
269private:
270 dg::geo::flux::detail::Fpsi m_fpsi;
271
272};
273
274}//namespace geo
275
276}//namespace dg
#define M_PI
static DG_DEVICE double one(double x)
static DG_DEVICE double cooX2d(double x, double y)
void copy(const ContainerTypeIn &source, ContainerTypeOut &target)
OutputType reduce(const ContainerType &x, OutputType zero, BinaryOp binary_op, UnaryOp unary_op=UnaryOp())
void evaluate(ContainerType &y, BinarySubroutine f, Functor g, const ContainerType0 &x0, const ContainerTypes &...xs)
void pointwiseDivide(get_value_type< ContainerType > alpha, const ContainerType1 &x1, const ContainerType2 &x2, get_value_type< ContainerType > beta, ContainerType &y)
void pointwiseDot(get_value_type< ContainerType > alpha, const ContainerType1 &x1, const ContainerType2 &x2, get_value_type< ContainerType > beta, ContainerType &y)
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)
Operator< real_type > delta(unsigned n)
thrust::host_vector< real_type > pullback(const Functor &f, const aRealGeometryX2d< real_type > &g)
ContainerType volume(const SparseTensor< ContainerType > &t)
real_type hy() const
real_type hx() const
unsigned nx() const
Flux surface average (differential volume average) over quantity .
Definition: average.h:155
void set_container(const container &f)
Reset the function to average.
Definition: average.h:181
double get_deltapsi() const
Definition: average.h:174
double operator()(double psip0)
Calculate the Flux Surface Average.
Definition: average.h:190
FluxSurfaceAverage(const dg::Grid2d &g2d, const TokamakMagneticField &mag, const container &f, container weights, double width_factor=1.)
Construct from a field and a grid.
Definition: average.h:164
Flux surface integral of the form .
Definition: average.h:27
void set_right(const container &g)
Set the right function to integrate.
Definition: average.h:62
FluxSurfaceIntegral(const dg::Grid2d &g2d, const TokamakMagneticField &mag, double width_factor=1.)
Construct from a grid and a magnetic field f and g are default initialized to 1.
Definition: average.h:35
double operator()(double psip0)
Calculate the Flux Surface Integral.
Definition: average.h:71
void set_left(const container &f)
Set the left function to integrate.
Definition: average.h:54
double get_deltapsi() const
Definition: average.h:47
Flux volume integral of the form .
Definition: average.h:94
FluxVolumeIntegral(const Geometry2d &g2d, const TokamakMagneticField &mag)
Construct from a grid and a magnetic field f and g are default initialized to 1.
Definition: average.h:102
void set_right(const container &g)
Set the right function to integrate.
Definition: average.h:122
void set_left(const container &f)
Set the left function to integrate.
Definition: average.h:114
double operator()(double psip0)
Calculate the Flux Volume Integral.
Definition: average.h:131
Class for the evaluation of the safety factor q based on a flux-surface integral .
Definition: average.h:212
void set_weights(const thrust::host_vector< double > &weights)
Weight function H (can be used to cut away parts of the domain e.g. below the X-point)
Definition: average.h:228
SafetyFactorAverage(const dg::Grid2d &g2d, const TokamakMagneticField &mag, double width_factor=1.)
Construct from a field and a grid.
Definition: average.h:219
double operator()(double psip0)
Calculate the q(psip0)
Definition: average.h:236
Evaluation of the safety factor q based on direct integration of .
Definition: average.h:256
SafetyFactor(const TokamakMagneticField &mag)
Definition: average.h:257
double operator()(double psip0)
Calculate q(psip0)
Definition: average.h:265
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 CylindricalFunctor & ipol() const
the current
Definition: magnetic_field.h:191
const CylindricalFunctor & psipZ() const
, where R, Z are cylindrical coordinates
Definition: magnetic_field.h:183