Extension: Geometries
#include "dg/geometries/geometries.h"
ds.h
Go to the documentation of this file.
1#pragma once
2
3#include "dg/algorithm.h"
4#include "fieldaligned.h"
5#ifdef MPI_VERSION
6#include "mpi_fieldaligned.h"
7#endif //MPI_VERSION
8#include "magnetic_field.h"
9
15namespace dg{
16namespace geo{
17
65namespace detail
66{
67struct DSCentered
68{
69 DSCentered( double alpha, double beta) : m_alpha(alpha), m_beta(beta){}
71 void operator()( double& dsf, double fm, double fo, double fp, double hm,
72 double hp)
73 {
74 dsf = m_alpha*(
75 fm*( 1./(hp+hm) - 1./hm) +
76 fo*( 1./hm - 1./hp) +
77 fp*( 1./hp - 1./(hp+hm))
78 ) + m_beta*dsf;
79 };
80
81 private:
82 double m_alpha, m_beta;
83};
84struct DSSCentered
85{
86 DSSCentered( double alpha, double beta, double delta) : m_alpha(alpha), m_beta(beta), m_delta(delta){}
88 void operator()( double& dssf, double fm, double fo, double fp, double hm,
89 double hp)
90 {
91 dssf = m_alpha*(
92 2.*fm/(hp+hm)/hm - 2.*fo/hp/hm + 2.*fp/(hp+hm)/hp
93 ) + m_beta*dssf;
94 };
95
97 void operator()( double& dssf, double fm, double fo, double fp,
98 double bPm, double bP0, double bPp)
99 {
100 double bP2 = (bPp+bP0)/2.;
101 double bM2 = (bPm+bP0)/2.;
102 double fm2 = (fo-fm)/m_delta;
103 double fp2 = (fp-fo)/m_delta;
104
105 dssf = m_alpha*bP0*( bP2*fp2 - bM2*fm2)/m_delta + m_beta*dssf;
106 }
107
108 private:
109 double m_alpha, m_beta, m_delta;
110};
111struct DSSDCentered
112{
113 DSSDCentered( double alpha, double beta, double delta) :
114 m_alpha( alpha), m_beta(beta), m_delta(delta){}
116 void operator()( double& dssdf, double fm, double fo, double fp, double Gm,
117 double Go, double Gp, double bPm, double bP0, double bPp)
118 {
119 // various combinations of bP do not seem to matter
120 double bP2 = (bPp+bP0)/2.;
121 double bM2 = (bPm+bP0)/2.;
122 double fm2 = (fo-fm)/m_delta;
123 double fp2 = (fp-fo)/m_delta;
124 double gp2 = (Gp + Go)/Go/2.;
125 double gm2 = (Gm + Go)/Go/2.;
126
127 dssdf = m_alpha*( gp2*fp2*bP2*bP2 - bM2*bM2*gm2*fm2)/m_delta + m_beta*dssdf;
128
129 // does not seem to conserve nicely
130 //dssdf = m_alpha*( fp*gp2*bP2*bP2 - 2*bP0*bP0*fo + bM2*bM2*gm2*fm)/(hp)/(hm) + m_beta*dssdf;
131 //dssdf = m_alpha*( fp*Gp/Go*bPp*bPp - 2*bP0*bP0*fo + bPm*bPm*Gm/Go*fm)/(hp)/(hm) + m_beta*dssdf;
132 };
133
134 private:
135 double m_alpha, m_beta, m_delta;
136};
137
138}//namespace detail
140
169template<class FieldAligned, class container>
170void assign_bc_along_field_2nd( const FieldAligned& fa, const container& fm,
171 const container& f, const container& fp, container& fmg, container& fpg,
172 dg::bc bound, std::array<double,2> boundary_value = {0,0})
173{
174 double delta = fa.deltaPhi();
175 if( bound == dg::NEU)
176 {
177 double dbm = boundary_value[0], dbp = boundary_value[1];
178 dg::blas1::subroutine( [dbm, dbp, delta]DG_DEVICE( double fm, double fo,
179 double fp, double& fmg, double& fpg,
180 double hbm, double hbp, double bbm, double bbo, double bbp
181 ){
182 //formula derived for non-equidistant grid
183 double hm = delta, hp = delta;
184 double plus=0, minus=0, bothP=0, bothM = 0;
185 plus = dbp*hp*(hm+hp)/(2.*hbp+hm) +
186 fo*(2.*hbp+hm-hp)*(hm+hp)/hm/(2.*hbp+hm) + fm*hp*(-2.*hbp +
187 hp)/hm/(2.*hbp + hm);
188 minus = fp*hm*(-2.*hbm+hm)/hp/(2.*hbm+hp) -
189 dbm*hm*(hm+hp)/(2.*hbm+hp) +
190 fo*(2.*hbm-hm+hp)*(hm+hp)/hp/(2.*hbm+hp);
191 bothM = fo + dbp*hm*(-2.*hbm + hm)/2./(hbm+hbp) -
192 dbm*hm*(2.*hbp+hm)/2./(hbm+hbp);
193 bothP = fo + dbp*hp*(2.*hbm + hp)/2./(hbm+hbp) +
194 dbm*hp*(2.*hbp-hp)/2./(hbm+hbp);
195 fmg = (1.-bbo-bbm)*fm + bbm*minus + bbo*bothM;
196 fpg = (1.-bbo-bbp)*fp + bbp*plus + bbo*bothP;
197 }, fm, f, fp, fmg, fpg, fa.hbm(), fa.hbp(), fa.bbm(),
198 fa.bbo(), fa.bbp() );
199 }
200 else// if( bound == dg:DIR)
201 {
202 double fbm = boundary_value[0], fbp = boundary_value[1];
203 dg::blas1::subroutine( [fbm, fbp, delta]DG_DEVICE( double fm, double fo,
204 double fp, double& fmg, double& fpg,
205 double hbm, double hbp, double bbm, double bbo, double bbp
206 ){
207 //formula derived for non-equidistant grid
208 double hm = delta, hp = delta;
209 double plus=0, minus=0, bothP=0, bothM = 0;
210 plus = fm*hp*(-hbp + hp)/hm/(hbp+hm) + fo*(hbp-hp)*(hm+hp)/hbp/hm
211 +fbp*hp*(hm+hp)/hbp/(hbp+hm);
212 minus = +fo*(hbm-hm)*(hm+hp)/hbm/hp + fbm*hm*(hm+hp)/hbm/(hbm+hp)
213 + fp*hm*(-hbm+hm)/hp/(hbm+hp);
214 bothM = fbp*hm*(-hbm+hm)/hbp/(hbm+hbp) +
215 fo*(hbm-hm)*(hbp+hm)/hbm/hbp + fbm*hm*(hbp+hm)/hbm/(hbm+hbp);
216 bothP = fo*(hbp-hp)*(hbm+hp)/hbm/hbp +
217 fbp*hp*(hbm+hp)/hbp/(hbm+hbp) + fbm*hp*(-hbp+hp)/hbm/(hbm+hbp);
218 fmg = (1.-bbo-bbm)*fm + bbm*minus + bbo*bothM;
219 fpg = (1.-bbo-bbp)*fp + bbp*plus + bbo*bothP;
220 }, fm, f, fp, fmg, fpg, fa.hbm(), fa.hbp(), fa.bbm(),
221 fa.bbo(), fa.bbp());
222 }
223
224}
241template<class FieldAligned, class container>
242void assign_bc_along_field_1st( const FieldAligned& fa, const container& fm,
243 const container& fp, container& fmg, container& fpg,
244 dg::bc bound, std::array<double,2> boundary_value = {0,0})
245{
246 double delta = fa.deltaPhi();
247 if( bound == dg::NEU)
248 {
249 double dbm = boundary_value[0], dbp = boundary_value[1];
250 dg::blas1::subroutine( [dbm, dbp, delta]DG_DEVICE( double fm, double fp,
251 double& fmg, double& fpg, double bbm, double bbp
252 ){
253 double hm = delta, hp = delta;
254 double plus=0, minus=0;
255 plus = fm + dbp*(hp+hm);
256 minus = fp - dbm*(hp+hm);
257 fmg = (1.-bbm)*fm + bbm*minus;
258 fpg = (1.-bbp)*fp + bbp*plus;
259 }, fm, fp, fmg, fpg, fa.bbm(), fa.bbp() );
260 }
261 else// if( bound == dg:DIR)
262 {
263 double fbm = boundary_value[0], fbp = boundary_value[1];
264 dg::blas1::subroutine( [fbm, fbp, delta]DG_DEVICE( double fm, double fp,
265 double& fmg, double& fpg, double hbm,
266 double hbp, double bbm, double bbo, double bbp
267 ){
268 double hm = delta, hp = delta;
269 double plus=0, minus=0, bothP=0, bothM = 0;
270 plus = fm + (fbp-fm)/(hbp+hm)*(hp+hm) ;
271 minus = fp - (hp+hm)*(fp-fbm)/(hp+hbm);
272 bothM = fbp + (fbp-fbm)/(hbp+hbm)*(hp+hbm);
273 bothP = fbp - (fbp-fbm)/(hbp+hbm)*(hbp+hm);
274 fmg = (1.-bbo-bbm)*fm + bbm*minus + bbo*bothM;
275 fpg = (1.-bbo-bbp)*fp + bbp*plus + bbo*bothP;
276 }, fm, fp, fmg, fpg, fa.hbm(), fa.hbp(), fa.bbm(),
277 fa.bbo(), fa.bbp());
278 }
279}
280
306template<class FieldAligned, class container>
307void swap_bc_perp( const FieldAligned& fa, const container& fm,
308 const container& fp, container& fmg, container& fpg)
309{
310 dg::blas1::subroutine( []DG_DEVICE( double fm, double fp,
311 double& fmg, double& fpg,
312 double bbm, double bbo, double bbp
313 ){
314 fmg = (1.-bbo-bbm)*fm + (bbm+bbo)*(-fm);
315 fpg = (1.-bbo-bbp)*fp + (bbp+bbo)*(-fp);
316 }, fm, fp, fmg, fpg, fa.bbm(), fa.bbo(), fa.bbp() );
317
318}
319
347template< class ProductGeometry, class IMatrix, class Matrix, class container >
348struct DS
349{
352 DS(){}
353
361 template <class Limiter>
362 DS(const dg::geo::TokamakMagneticField& vec, const ProductGeometry& grid,
363 dg::bc bcx = dg::NEU,
364 dg::bc bcy = dg::NEU,
365 Limiter limit = FullLimiter(),
366 double eps = 1e-5,
367 unsigned mx=10, unsigned my=10,
368 double deltaPhi=-1, std::string interpolation_method = "dg",
369 bool benchmark=true):
370 DS( FA( vec, grid, bcx, bcy, limit, eps, mx, my, deltaPhi,
371 interpolation_method, benchmark) )
372 {
373 }
381 template<class Limiter>
382 DS(const dg::geo::CylindricalVectorLvl1& vec, const ProductGeometry& grid,
383 dg::bc bcx = dg::NEU,
384 dg::bc bcy = dg::NEU,
385 Limiter limit = FullLimiter(),
386 double eps = 1e-5,
387 unsigned mx=10, unsigned my=10,
388 double deltaPhi=-1, std::string interpolation_method = "dg",
389 bool benchmark=true):
390 DS( FA( vec, grid, bcx, bcy, limit, eps, mx, my, deltaPhi,
391 interpolation_method, benchmark))
392 {
393 }
405 template<class ...Params>
406 void construct( Params&& ...ps)
407 {
408 //construct and swap
409 *this = DS( std::forward<Params>( ps)...);
410 }
411
413 void set_boundaries( dg::bc bcz, double left, double right){
414 m_fa.set_boundaries( bcz, left, right);
415 }
417 void set_boundaries( dg::bc bcz, const container& left, const container& right){
418 m_fa.set_boundaries( bcz, left, right);
419 }
421 void set_boundaries( dg::bc bcz, const container& global, double scal_left, double scal_right){
422 m_fa.set_boundaries( bcz, global, scal_left, scal_right);
423 }
424
431 void forward( double alpha, const container& f, double beta, container& g){
432 m_fa(zeroForw, f, m_tempO);
433 m_fa(einsPlus, f, m_tempP);
434 ds_forward( m_fa, alpha, m_tempO, m_tempP, beta, g);
435 }
442 void forward2( double alpha, const container& f, double beta, container& g){
443 m_fa(zeroForw, f, m_tempO);
444 m_fa(einsPlus, f, m_tempP);
445 m_fa(einsPlus, m_tempP, m_tempM);
446 ds_forward2( m_fa, alpha, m_tempO, m_tempP, m_tempM, beta, g);
447 }
454 void backward( double alpha, const container& f, double beta, container& g){
455 m_fa(einsMinus, f, m_tempM);
456 m_fa(zeroForw, f, m_tempO);
457 ds_backward( m_fa, alpha, m_tempM, m_tempO, beta, g);
458 }
465 void backward2( double alpha, const container& f, double beta, container& g){
466 m_fa(einsMinus, f, m_tempM);
467 m_fa(einsMinus, m_tempM, m_tempP);
468 m_fa(zeroForw, f, m_tempO);
469 ds_backward2( m_fa, alpha, m_tempP, m_tempM, m_tempO, beta, g);
470 }
481 void centered( double alpha, const container& f, double beta, container& g){
482 m_fa(einsPlus, f, m_tempP);
483 m_fa(einsMinus, f, m_tempM);
484 ds_centered( m_fa, alpha, m_tempM, m_tempP, beta, g);
485 }
488 double alpha, const container& f, double beta, container& g, dg::bc bound,
489 std::array<double,2> boundary_value = {0,0}){
490 m_fa(einsPlus, f, m_tempP);
491 m_fa(einsMinus, f, m_tempM);
492 assign_bc_along_field_2nd( m_fa, m_tempM, f, m_tempP, m_tempM, m_tempP,
493 bound, boundary_value);
494 ds_centered( m_fa, alpha, m_tempM, m_tempP, beta, g);
495
496 }
503 void backward( const container& f, container& g){
504 backward(1., f,0.,g);
505 }
512 void forward( const container& f, container& g){
513 forward(1.,f, 0.,g);
514 }
521 void centered( const container& f, container& g){
522 centered(1.,f,0.,g);
523 }
524
528 void divForward( double alpha, const container& f, double beta, container& g){
529 m_fa(einsPlus, f, m_tempP);
530 m_fa(zeroForw, f, m_tempO);
531 ds_divForward( m_fa, alpha, m_tempO, m_tempP, beta, g);
532 }
536 void divBackward( double alpha, const container& f, double beta, container& g){
537 m_fa(einsMinus, f, m_tempM);
538 m_fa(zeroForw, f, m_tempO);
539 ds_divBackward( m_fa, alpha, m_tempM, m_tempO, beta, g);
540 }
544 void divCentered(double alpha, const container& f, double beta, container& g){
545 m_fa(einsPlus, f, m_tempP);
546 m_fa(einsMinus, f, m_tempM);
547 ds_divCentered( m_fa, alpha, m_tempM, m_tempP, beta, g);
548 }
552 void divForward(const container& f, container& g){
553 divForward( 1.,f,0.,g);
554 }
558 void divBackward(const container& f, container& g){
559 divBackward( 1.,f,0.,g);
560 }
564 void divCentered(const container& f, container& g){
565 divCentered( 1.,f,0.,g);
566 }
567
574 void ds(dg::direction dir, const container& f, container& g){
575 ds(dir, 1., f, 0., g);
576 }
583 void ds(dg::direction dir, double alpha, const container& f, double beta, container& g);
591 void div(dg::direction dir, const container& f, container& g){
592 div(dir, 1., f, 0., g);
593 }
601 void div(dg::direction dir, double alpha, const container& f, double beta, container& g);
602
609 void symv( const container& f, container& g){ symv( 1., f, 0., g);}
616 void symv( double alpha, const container& f, double beta, container& g);
624 void dss( const container& f, container& g){
625 dss( 1., f, 0., g);}
633 void dss( double alpha, const container& f, double beta, container& g){
634 m_fa(einsPlus, f, m_tempP);
635 m_fa(einsMinus, f, m_tempM);
636 m_fa(zeroForw, f, m_tempO);
637 dss_centered( m_fa, alpha, m_tempM, m_tempO, m_tempP, beta, g);
638 }
641 double alpha, const container& f, double beta, container& g, dg::bc bound,
642 std::array<double,2> boundary_value = {0,0}){
643 m_fa(einsPlus, f, m_tempP);
644 m_fa(einsMinus, f, m_tempM);
645 m_fa(zeroForw, f, m_tempO);
646 assign_bc_along_field_2nd( m_fa, m_tempM, m_tempO, m_tempP, m_tempM, m_tempP,
647 bound, boundary_value);
648 dss_centered( m_fa, alpha, m_tempM, m_tempO, m_tempP, beta, g);
649 }
651 void dssd( double alpha, const container& f, double
652 beta, container& g){
653 m_fa(einsPlus, f, m_tempP);
654 m_fa(einsMinus, f, m_tempM);
655 m_fa(zeroForw, f, m_tempO);
656 dssd_centered( m_fa, alpha, m_tempM, m_tempO, m_tempP, beta, g);
657 }
659 void dssd_bc_along_field( double alpha, const
660 container& f, double beta, container& g, dg::bc bound,
661 std::array<double,2> boundary_value = {0,0}){
662 m_fa(einsPlus, f, m_tempP);
663 m_fa(einsMinus, f, m_tempM);
664 m_fa(zeroForw, f, m_tempO);
665 assign_bc_along_field_2nd( m_fa, m_tempM, m_tempO, m_tempP, m_tempM, m_tempP,
666 bound, boundary_value);
667 dssd_centered( m_fa, alpha, m_tempM, f, m_tempP, beta, g);
668 }
673 void set_jfactor( double new_jfactor) {m_jfactor = new_jfactor;}
678 double get_jfactor() const {return m_jfactor;}
679
681 const container& weights()const {
682 return m_fa.sqrtG();
683 }
684
690 FA& fieldaligned(){return m_fa;}
691 const FA& fieldaligned()const{return m_fa;}
692 private:
694 container m_tempP, m_tempO, m_tempM;
695 Matrix m_jumpX, m_jumpY;
696 double m_jfactor = 1.;
697};
698
701
702template<class Geometry, class I, class M, class container>
703DS<Geometry, I, M,container>::DS( Fieldaligned<Geometry, I, container> fa): m_fa(fa)
704{
705 dg::blas2::transfer( dg::create::jumpX( fa.grid(), fa.bcx()), m_jumpX);
706 dg::blas2::transfer( dg::create::jumpY( fa.grid(), fa.bcy()), m_jumpY);
707 m_tempP = fa.sqrtG(), m_tempM = m_tempO = m_tempP;
708}
709
710template<class G, class I, class M, class container>
711inline void DS<G,I,M,container>::ds( dg::direction dir, double alpha,
712 const container& f, double beta, container& dsf) {
713 switch( dir){
714 case dg::centered:
715 return centered( alpha, f, beta, dsf);
716 case dg::forward:
717 return forward( alpha, f, beta, dsf);
718 case dg::backward:
719 return backward( alpha, f, beta, dsf);
720 }
721}
722template<class G, class I, class M, class container>
723inline void DS<G,I,M,container>::div( dg::direction dir, double alpha,
724 const container& f, double beta, container& dsf) {
725 switch( dir){
726 case dg::centered:
727 return divCentered( alpha, f, beta, dsf);
728 case dg::forward:
729 return divForward( alpha, f, beta, dsf);
730 case dg::backward:
731 return divBackward( alpha, f, beta, dsf);
732 }
733}
734
735
736template<class G,class I, class M, class container>
737void DS<G,I,M,container>::symv( double alpha, const container& f, double beta, container& dsTdsf)
738{
739 dssd( alpha, f, beta, dsTdsf);
740 // add jump terms
741 if( m_jfactor !=0 && m_fa.method() == "dg")
742 {
743 dg::blas2::symv( -m_jfactor*alpha, m_jumpX, f, 1., dsTdsf);
744 dg::blas2::symv( -m_jfactor*alpha, m_jumpY, f, 1., dsTdsf);
745 }
746};
748
759template<class FieldAligned, class container>
760void ds_forward(const FieldAligned& fa, double alpha, const container& f,
761 const container& fp, double beta, container& g)
762{
763 //direct
764 double delta = fa.deltaPhi();
765 dg::blas1::subroutine( [ alpha, beta, delta]DG_DEVICE(
766 double& dsf, double fo, double fp, double bphi){
767 dsf = alpha*bphi*( fp - fo)/delta + beta*dsf;
768 },
769 g, f, fp, fa.bphi());
770}
781template<class FieldAligned, class container>
782void ds_forward2(const FieldAligned& fa, double alpha, const container& f,
783 const container& fp, const container& fpp, double beta, container& g)
784{
785 //direct
786 double delta = fa.deltaPhi();
787 dg::blas1::subroutine( [ alpha, beta, delta]DG_DEVICE(
788 double& dsf, double fo, double fp, double fpp, double bphi){
789 dsf = alpha*bphi*( -3.*fo + 4.*fp - fpp)/2./delta
790 + beta*dsf;
791 },
792 g, f, fp, fpp, fa.bphi());
793}
794
805template<class FieldAligned, class container>
806void ds_backward( const FieldAligned& fa, double alpha, const container& fm,
807 const container& f, double beta, container& g)
808{
809 //direct
810 double delta = fa.deltaPhi();
811 dg::blas1::subroutine( [ alpha, beta, delta] DG_DEVICE(
812 double& dsf, double fo, double fm, double bphi){
813 dsf = alpha*bphi*( fo - fm)/delta + beta*dsf;
814 },
815 g, f, fm, fa.bphi());
816
817}
828template<class FieldAligned, class container>
829void ds_backward2( const FieldAligned& fa, double alpha, const container& fmm, const container& fm, const container& f, double beta, container& g)
830{
831 //direct
832 double delta = fa.deltaPhi();
833 dg::blas1::subroutine( [ alpha, beta, delta] DG_DEVICE(
834 double& dsf, double fo, double fm, double fmm, double bphi){
835 dsf = alpha*bphi*( 3.*fo - 4.*fm + fmm)/2./delta
836 + beta*dsf;
837 },
838 g, f, fm, fmm, fa.bphi());
839
840}
841
842
857template<class FieldAligned, class container>
858void ds_centered( const FieldAligned& fa, double alpha, const container& fm,
859 const container& fp, double beta, container& g)
860{
861 //direct discretisation
862 double delta=fa.deltaPhi();
863 dg::blas1::subroutine( [alpha,beta,delta]DG_DEVICE( double& g, double fm,
864 double fp, double bphi){
865 g = alpha*bphi*(fp-fm)/2./delta + beta*g;
866 }, g, fm, fp, fa.bphi());
867}
883template<class FieldAligned, class container>
884void dss_centered( const FieldAligned& fa, double alpha, const container& fm,
885 const container& f, const container& fp, double beta, container& g)
886{
887 dg::blas1::subroutine( detail::DSSCentered( alpha, beta, fa.deltaPhi()),
888 g, fm, f, fp, fa.bphiM(), fa.bphi(), fa.bphiP());
889}
901template<class FieldAligned, class container>
902void dssd_centered( const FieldAligned& fa, double alpha, const container& fm,
903 const container& f, const container& fp, double beta, container& g)
904{
905 dg::blas1::subroutine( detail::DSSDCentered( alpha, beta, fa.deltaPhi()),
906 g, fm, f, fp, fa.sqrtGm(), fa.sqrtG(), fa.sqrtGp(),
907 fa.bphiM(), fa.bphi(), fa.bphiP());
908}
909
923template<class FieldAligned, class container>
924void ds_divBackward( const FieldAligned& fa, double alpha, const container& fm,
925 const container& f, double beta, container& g)
926{
927 double delta = fa.deltaPhi();
928 dg::blas1::subroutine( [alpha,beta,delta] DG_DEVICE( double& dsf, double f0,
929 double f1, double Gm, double G0, double bPm, double bP0){
930 dsf = alpha*(bP0*G0*f0 - bPm*Gm*f1)/G0/delta + beta*dsf; },
931 g, f, fm, fa.sqrtGm(), fa.sqrtG(), fa.bphiM(), fa.bphi());
932}
933
947template<class FieldAligned, class container>
948void ds_divForward( const FieldAligned& fa, double alpha, const container& f,
949 const container& fp, double beta, container& g)
950{
951 double delta = fa.deltaPhi();
952 dg::blas1::subroutine( [alpha,beta,delta] DG_DEVICE( double& dsf, double f0,
953 double f1, double Gp, double G0, double bPp, double bP0){
954 dsf = alpha*(bPp*Gp*f1 - bP0*G0*f0)/G0/delta + beta*dsf; },
955 g, f, fp, fa.sqrtGp(), fa.sqrtG(), fa.bphiP(), fa.bphi());
956}
970template<class FieldAligned, class container>
971void ds_divCentered( const FieldAligned& fa, double alpha, const container& fm, const container& fp,
972 double beta, container& g)
973{
974 double delta = fa.deltaPhi();
975 dg::blas1::subroutine( [alpha,beta,delta]DG_DEVICE( double& dsf, double fm,
976 double fp, double Gm, double Gp, double G0,
977 double bPm, double bP0, double bPp)
978 {
979 dsf = alpha*( fp*Gp*bPp - fm*Gm*bPm )/G0/2./delta + beta*dsf;
980 }, g, fm, fp, fa.sqrtGm(),
981 fa.sqrtGp(), fa.sqrtG(), fa.bphiM(), fa.bphi(), fa.bphiP());
982
983}
984
1000template<class FieldAligned, class container>
1001void ds_average( const FieldAligned& fa, double alpha,
1002 const container& fm, const container& fp, double beta, container& g)
1003{
1004 dg::blas1::subroutine( [alpha,beta]DG_DEVICE( double& g, double fm, double fp
1005 ){
1006 g = alpha*(fp+fm)/2. + beta*g;
1007 }, g, fm, fp);
1008}
1025template<class FieldAligned, class container>
1026void ds_slope( const FieldAligned& fa, double alpha,
1027 const container& fm, const container& fp, double beta, container& g)
1028{
1029 ds_centered( fa, alpha, fm, fp, beta, g);
1030}
1031
1032
1033}//namespace geo
1034
1036template< class G, class I, class M, class V>
1037struct TensorTraits< geo::DS<G,I,M, V> >
1038{
1039 using value_type = double;
1040 using tensor_category = SelfMadeMatrixTag;
1041};
1043}//namespace dg
#define DG_DEVICE
void plus(ContainerType &x, get_value_type< ContainerType > alpha)
void subroutine(Subroutine f, ContainerType &&x, ContainerTypes &&... xs)
void transfer(const MatrixType &x, AnotherMatrixType &y)
void symv(MatrixType &&M, const ContainerType1 &x, ContainerType2 &y)
EllSparseBlockMat< real_type > jumpX(const aRealTopology2d< real_type > &g, bc bcx)
direction
EllSparseBlockMat< real_type > jumpY(const aRealTopology2d< real_type > &g, bc bcy)
backward
centered
void dssd_centered(const FieldAligned &fa, double alpha, const container &fm, const container &f, const container &fp, double beta, container &g)
Centered derivative .
Definition: ds.h:902
void ds_divForward(const FieldAligned &fa, double alpha, const container &f, const container &fp, double beta, container &g)
forward derivative
Definition: ds.h:948
void assign_bc_along_field_1st(const FieldAligned &fa, const container &fm, const container &fp, container &fmg, container &fpg, dg::bc bound, std::array< double, 2 > boundary_value={0, 0})
Assign boundary conditions along magnetic field lines interpolating a 1st order polynomial (a line)
Definition: ds.h:242
void assign_bc_along_field_2nd(const FieldAligned &fa, const container &fm, const container &f, const container &fp, container &fmg, container &fpg, dg::bc bound, std::array< double, 2 > boundary_value={0, 0})
Assign boundary conditions along magnetic field lines interpolating a 2nd order polynomial.
Definition: ds.h:170
void ds_backward(const FieldAligned &fa, double alpha, const container &fm, const container &f, double beta, container &g)
backward derivative
Definition: ds.h:806
void ds_centered(const FieldAligned &fa, double alpha, const container &fm, const container &fp, double beta, container &g)
centered derivative
Definition: ds.h:858
void ds_divBackward(const FieldAligned &fa, double alpha, const container &fm, const container &f, double beta, container &g)
backward derivative
Definition: ds.h:924
void ds_average(const FieldAligned &fa, double alpha, const container &fm, const container &fp, double beta, container &g)
Compute average along a fieldline .
Definition: ds.h:1001
void dss_centered(const FieldAligned &fa, double alpha, const container &fm, const container &f, const container &fp, double beta, container &g)
Centered derivative .
Definition: ds.h:884
void ds_backward2(const FieldAligned &fa, double alpha, const container &fmm, const container &fm, const container &f, double beta, container &g)
2nd order backward derivative
Definition: ds.h:829
void ds_divCentered(const FieldAligned &fa, double alpha, const container &fm, const container &fp, double beta, container &g)
centered derivative
Definition: ds.h:971
void ds_forward2(const FieldAligned &fa, double alpha, const container &f, const container &fp, const container &fpp, double beta, container &g)
2nd order forward derivative
Definition: ds.h:782
ONE FullLimiter
Full Limiter means there is a limiter everywhere.
Definition: fieldaligned.h:31
void ds_forward(const FieldAligned &fa, double alpha, const container &f, const container &fp, double beta, container &g)
forward derivative
Definition: ds.h:760
void ds_slope(const FieldAligned &fa, double alpha, const container &fm, const container &fp, double beta, container &g)
Compute simple slope along a fieldline .
Definition: ds.h:1026
void swap_bc_perp(const FieldAligned &fa, const container &fm, const container &fp, container &fmg, container &fpg)
Swap the perp boundary condition.
Definition: ds.h:307
@ einsMinus
minus interpolation in previous plane
Definition: fieldaligned.h:20
@ zeroForw
from dg to transformed coordinates
Definition: fieldaligned.h:26
@ einsPlus
plus interpolation in next plane
Definition: fieldaligned.h:18
Operator< real_type > delta(unsigned n)
NotATensorTag tensor_category
This struct bundles a vector field and its divergence.
Definition: fluxfunctions.h:440
Class for the evaluation of parallel derivatives.
Definition: ds.h:349
void dssd(double alpha, const container &f, double beta, container &g)
Same as dg::geo::dssd_centered.
Definition: ds.h:651
void set_boundaries(dg::bc bcz, const container &global, double scal_left, double scal_right)
Set boundary conditions in the limiter region.
Definition: ds.h:421
void set_boundaries(dg::bc bcz, const container &left, const container &right)
Set boundary conditions in the limiter region.
Definition: ds.h:417
void ds(dg::direction dir, const container &f, container &g)
Discretizes .
Definition: ds.h:574
void backward(const container &f, container &g)
backward derivative
Definition: ds.h:503
void set_boundaries(dg::bc bcz, double left, double right)
Set boundary conditions in the limiter region.
Definition: ds.h:413
void forward(double alpha, const container &f, double beta, container &g)
forward derivative
Definition: ds.h:431
double get_jfactor() const
Get the currently used jfactor ( )
Definition: ds.h:678
void centered_bc_along_field(double alpha, const container &f, double beta, container &g, dg::bc bound, std::array< double, 2 > boundary_value={0, 0})
Same as dg::geo::ds_centered after dg::geo::ds_assign_bc_along_field_2nd.
Definition: ds.h:487
void dss_bc_along_field(double alpha, const container &f, double beta, container &g, dg::bc bound, std::array< double, 2 > boundary_value={0, 0})
Same as dg::geo::dss_centered after dg::geo::ds_assign_bc_along_field_2nd.
Definition: ds.h:640
void divBackward(const container &f, container &g)
backward divergence
Definition: ds.h:558
void dssd_bc_along_field(double alpha, const container &f, double beta, container &g, dg::bc bound, std::array< double, 2 > boundary_value={0, 0})
Same as dg::geo::dssd_centered after dg::geo::ds_assign_bc_along_field_2nd.
Definition: ds.h:659
void dss(double alpha, const container &f, double beta, container &g)
Discretizes .
Definition: ds.h:633
void div(dg::direction dir, const container &f, container &g)
Discretizes .
Definition: ds.h:591
DS(FA fieldaligned)
Re-construct from a given Fieldaligned object.
void ds(dg::direction dir, double alpha, const container &f, double beta, container &g)
Discretizes .
void backward(double alpha, const container &f, double beta, container &g)
backward derivative
Definition: ds.h:454
FA & fieldaligned()
access the underlying Fieldaligned object
Definition: ds.h:690
void divCentered(double alpha, const container &f, double beta, container &g)
centered divergence
Definition: ds.h:544
void divForward(const container &f, container &g)
forward divergence
Definition: ds.h:552
void divForward(double alpha, const container &f, double beta, container &g)
forward divergence
Definition: ds.h:528
void symv(const container &f, container &g)
Discretizes .
Definition: ds.h:609
DS(const dg::geo::CylindricalVectorLvl1 &vec, const ProductGeometry &grid, dg::bc bcx=dg::NEU, dg::bc bcy=dg::NEU, Limiter limit=FullLimiter(), double eps=1e-5, unsigned mx=10, unsigned my=10, double deltaPhi=-1, std::string interpolation_method="dg", bool benchmark=true)
Use the given vector field to construct.
Definition: ds.h:382
const FA & fieldaligned() const
Definition: ds.h:691
void forward2(double alpha, const container &f, double beta, container &g)
2nd order forward derivative
Definition: ds.h:442
void centered(const container &f, container &g)
centered derivative
Definition: ds.h:521
void dss(const container &f, container &g)
Discretizes .
Definition: ds.h:624
void div(dg::direction dir, double alpha, const container &f, double beta, container &g)
Discretizes .
dg::geo::Fieldaligned< ProductGeometry, IMatrix, container > FA
Definition: ds.h:350
void symv(double alpha, const container &f, double beta, container &g)
Discretizes as a symmetric matrix.
void centered(double alpha, const container &f, double beta, container &g)
centered derivative
Definition: ds.h:481
void backward2(double alpha, const container &f, double beta, container &g)
2nd order backward derivative
Definition: ds.h:465
void divCentered(const container &f, container &g)
centered divergence
Definition: ds.h:564
DS(const dg::geo::TokamakMagneticField &vec, const ProductGeometry &grid, dg::bc bcx=dg::NEU, dg::bc bcy=dg::NEU, Limiter limit=FullLimiter(), double eps=1e-5, unsigned mx=10, unsigned my=10, double deltaPhi=-1, std::string interpolation_method="dg", bool benchmark=true)
Create the magnetic unit vector field and construct.
Definition: ds.h:362
void set_jfactor(double new_jfactor)
Set the currently used jfactor ( )
Definition: ds.h:673
void forward(const container &f, container &g)
forward derivative
Definition: ds.h:512
DS()
No memory allocation; all member calls except construct are invalid.
Definition: ds.h:352
const container & weights() const
The volume form with dG weights.
Definition: ds.h:681
void divBackward(double alpha, const container &f, double beta, container &g)
backward divergence
Definition: ds.h:536
void construct(Params &&...ps)
Perfect forward parameters to one of the constructors.
Definition: ds.h:406
Create and manage interpolation matrices from fieldline integration.
Definition: fieldaligned.h:433
A tokamak field as given by R0, Psi and Ipol plus Meta-data like shape and equilibrium.
Definition: magnetic_field.h:162