3#include "dg/algorithm.h"
5#include "dg/backend/timer.h"
12template <
class ProductMPIGeometry,
class MIMatrix,
class LocalContainer>
13struct Fieldaligned< ProductMPIGeometry, MIMatrix, MPI_Vector<LocalContainer> >
16 template <
class Limiter>
18 const ProductMPIGeometry&
grid,
23 unsigned mx=12,
unsigned my=12,
24 double deltaPhi = -1, std::string interpolation_method =
"linear-nearest",
25 bool benchmark =
true):
27 mx, my,
deltaPhi, interpolation_method, benchmark)
30 template <
class Limiter>
32 const ProductMPIGeometry&
grid,
37 unsigned mx=12,
unsigned my=12,
38 double deltaPhi = -1, std::string interpolation_method =
"linear-nearest",
39 bool benchmark =
true);
40 template<
class ...Params>
61 void set_boundaries(
dg::bc bcz,
const MPI_Vector<LocalContainer>& left,
const MPI_Vector<LocalContainer>& right)
68 void set_boundaries(
dg::bc bcz,
const MPI_Vector<LocalContainer>& global,
double scal_left,
double scal_right)
76 void operator()(
enum whichMatrix which,
const MPI_Vector<LocalContainer>& in, MPI_Vector<LocalContainer>& out)
const;
78 double deltaPhi()
const{
return m_deltaPhi;}
79 const MPI_Vector<LocalContainer>&
hbm()
const {
82 const MPI_Vector<LocalContainer>&
hbp()
const {
85 const MPI_Vector<LocalContainer>&
sqrtG()
const {
88 const MPI_Vector<LocalContainer>&
sqrtGm()
const {
91 const MPI_Vector<LocalContainer>&
sqrtGp()
const {
94 const MPI_Vector<LocalContainer>&
bphi()
const {
97 const MPI_Vector<LocalContainer>&
bphiM()
const {
100 const MPI_Vector<LocalContainer>&
bphiP()
const {
103 const MPI_Vector<LocalContainer>&
bbm()
const {
106 const MPI_Vector<LocalContainer>&
bbo()
const {
109 const MPI_Vector<LocalContainer>&
bbp()
const {
112 const ProductMPIGeometry&
grid()
const{
return *m_g;}
114 template<
class BinaryOp,
class UnaryOp>
115 MPI_Vector<LocalContainer>
evaluate( BinaryOp f, UnaryOp g,
unsigned p0,
116 unsigned rounds)
const;
117 std::string
method()
const{
return m_interpolation_method;}
119 void ePlus(
enum whichMatrix which,
const MPI_Vector<LocalContainer>& in, MPI_Vector<LocalContainer>& out)
const;
120 void eMinus(
enum whichMatrix which,
const MPI_Vector<LocalContainer>& in, MPI_Vector<LocalContainer>& out)
const;
121 void zero(
enum whichMatrix which,
const MPI_Vector<LocalContainer>& in, MPI_Vector<LocalContainer>& out)
const;
122 MIMatrix m_plus, m_zero, m_minus;
123 mutable MIMatrix m_plusT, m_minusT;
125 typename detail::Container2EllSparseBlockMat<LocalContainer>::type m_bx, m_by, m_inv_bx, m_inv_by;
126 bool apply_backproject =
false, apply_inv_backproject =
false;
127 mutable MPI_Vector<LocalContainer> m_temp0, m_temp1;
129 MPI_Vector<LocalContainer> m_hbm, m_hbp;
130 MPI_Vector<LocalContainer> m_G, m_Gm, m_Gp;
131 MPI_Vector<LocalContainer> m_bphi, m_bphiM, m_bphiP;
132 MPI_Vector<LocalContainer> m_bbm, m_bbp, m_bbo;
134 MPI_Vector<LocalContainer> m_left, m_right;
135 MPI_Vector<LocalContainer> m_limiter;
136 mutable MPI_Vector<LocalContainer> m_ghostM, m_ghostP;
137 mutable std::vector<MPI_Vector<dg::View<const LocalContainer>> > m_split_in;
138 mutable std::vector<MPI_Vector<dg::View<LocalContainer>> > m_split_out;
140 dg::bc m_bcx, m_bcy, m_bcz;
141 unsigned m_Nz, m_perp_size, m_mx, m_my;
142 double m_deltaPhi, m_eps;
143 std::string m_interpolation_method;
145 unsigned m_coords2, m_sizeZ;
147 mutable thrust::host_vector<double> m_buffer;
148 dg::detail::MPIContiguousGather m_from_minus, m_from_plus;
149 mutable bool m_have_adjoint =
false;
150 void updateAdjoint( ) const
157 std::array<thrust::host_vector<double>,3> yp_trafo, ym_trafo;
158 thrust::host_vector<double>
hbp,
hbm;
159 thrust::host_vector<bool> in_boxp, in_boxm;
162 make_matrices( m_vec, grid_transform, global_grid_magnetic,
163 m_bcx, m_bcy, m_eps, m_mx, m_my, m_deltaPhi,
164 m_interpolation_method,
168 minus, zero, plus,
true, minusT, plusT
172 m_have_adjoint =
true;
180 unsigned mx,
unsigned my,
181 double deltaPhi, std::string interpolation_method,
183 const MPI_Vector<thrust::host_vector<double>>& vol2d0,
184 thrust::host_vector<double>&
hbp,
185 thrust::host_vector<double>&
hbm,
186 thrust::host_vector<bool>& in_boxp,
187 thrust::host_vector<bool>& in_boxm,
188 std::array<thrust::host_vector<double>,3>& yp_trafo,
189 std::array<thrust::host_vector<double>,3>& ym_trafo,
196 MPI_Comm_rank( m_g->communicator(), &rank);
198 std::string inter_m, project_m, fine_m;
199 detail::parse_method( interpolation_method, inter_m, project_m, fine_m);
201 if( project_m !=
"dg" && fine_m ==
"dg")
203 unsigned rx = mx % grid_transform->nx(), ry = my % grid_transform->ny();
204 if( 0 != rx || 0 != ry)
206 if(rank==0)std::cerr <<
"#Warning: for projection method \"const\" mx and my must be multiples of nx and ny! Rounding up for you ...\n";
207 mx = mx + grid_transform->nx() - rx;
208 my = my + grid_transform->ny() - ry;
211 if( benchmark && rank==0)
212 std::cout <<
"# Interpolation method: \""<<inter_m
213 <<
"\" projection method: \""<<project_m
214 <<
"\" fine grid \""<<fine_m<<
"\"\n";
218 if( benchmark) t.
tic();
222 grid_magnetic->set( grid_transform->n() < 3 ? 4 : 7, grid_magnetic->Nx(), grid_magnetic->Ny());
223 global_grid_magnetic = grid_magnetic->global_geometry();
225 detail::integrate_all_fieldlines2d( vec, *global_grid_magnetic,
226 grid_transform->local(), yp_trafo, vol2d0.data(),
hbp, in_boxp,
228 detail::integrate_all_fieldlines2d( vec, *global_grid_magnetic,
229 grid_transform->local(), ym_trafo, vol2d0.data(),
hbm, in_boxm,
234 if(rank==0) std::cout <<
"# DS: Fieldline integration took: "<<t.
diff()<<
"\n";
243 for(
unsigned sub = 0; sub < grid_transform->local().Ny(); sub++)
249 grid_fine_sub.y0() + sub*grid_fine_sub.hy(),
251 sub == grid_transform->local().Ny()-1 ? grid_fine_sub.y1() :
252 grid_fine_sub.y0() + (sub+1)*grid_fine_sub.hy(),
253 grid_fine_sub.n(), grid_fine_sub.Nx(), 1,
254 grid_fine_sub.bcx(), grid_fine_sub.bcy());
260 grid_equidist_global.set( 1, grid_equidist_global.shape(0), grid_equidist_global.shape(1));
261 if( fine_m ==
"equi")
262 grid_fine_sub.set( 1, grid_fine_sub.shape(0), grid_fine_sub.shape(1));
263 grid_fine_sub.multiplyCellNumbers((
double)mx, (
double)my);
264 std::array<thrust::host_vector<double>,3> yp, ym;
268 unsigned shift = grid_transform->local().shape(0) * grid_transform->n();
269 unsigned global_shift = grid_transform->global().shape(0) * grid_transform->n();
270 if( sub <= 1 || sub >= grid_transform->local().Ny() - 2 || grid_transform->n() < 3)
273 grid_transform->local(),
dg::NEU,
dg::NEU, grid_transform->n() < 3 ?
"cubic" :
"dg");
275 inter_m ==
"dg" ? grid_transform->global() :
276 grid_equidist_global,
bcx,
bcy, inter_m);
286 for(
int i=0; i<2; i++)
292 if( sub <= 1 || sub >= grid_transform->local().Ny() -2 )
294 if( project_m ==
"dg")
311 global_shift,
projection.row_offsets().end());
314 std::array<dg::HVec*,3> xcomp{ &yp[0], &Xf, &ym[0]};
315 std::array<dg::HVec*,3> ycomp{ &yp[1], &Yf, &ym[1]};
316 std::array<dg::IHMatrix*,3> result{ &local_plus, &local_zero, &local_minus};
319 for(
unsigned u=0; u<3; u++)
325 inter_m ==
"dg" ? grid_transform->global() :
326 grid_equidist_global,
bcx,
bcy, inter_m);
327 detail::add_from_sub( *result[u], subresult, project_m);
333 if(rank==0) std::cout <<
"# DS: Assembly of matrices took: "<<t.
diff()<<
"\n";
337 std::array<dg::IHMatrix*,3> input{ &local_plus, &local_zero, &local_minus};
338 std::array<MIHMatrix*,3> result{ &
plus, &
zero, &minus};
339 std::array<MIHMatrix*,3> resultT{ &plusT, &
zero, &minusT};
340 for(
unsigned u=0; u<3; u++)
345 if( make_adjoint and u != 1)
362 std::cout <<
"# DS: MPI conversion took: "<<t.
diff()<<
"\n";
363 std::streamsize ss = std::cout.precision();
364 std::cout << std::setprecision(1) << std::fixed;
365 std::cout <<
"# DS: Average nnz per row inner (plus | zero | minus): "
366 <<(double)
plus.inner_matrix().num_nnz()/(double)
plus.inner_matrix().num_rows()<<
" | "
367 <<(double)
zero.inner_matrix().num_nnz()/(double)
zero.inner_matrix().num_rows()<<
" | "
369 if(
plus.outer_matrix().num_nnz() != 0)
370 std::cout <<
"# DS: Average nnz per row outer (plus | zero | minus): "
371 <<(double)
plus.outer_matrix().num_nnz()/(double)
plus.outer_matrix().num_rows()<<
" | "
372 <<(double)
zero.outer_matrix().num_nnz()/(double)
zero.outer_matrix().num_rows()<<
" | "
374 std::cout << std::defaultfloat << std::setprecision(ss);
380template<
class MPIGeometry,
class MIMatrix,
class LocalContainer>
381template <
class Limiter>
382Fieldaligned<MPIGeometry, MIMatrix, MPI_Vector<LocalContainer> >::Fieldaligned(
384 const MPIGeometry& grid,
386 unsigned mx,
unsigned my,
387 double deltaPhi, std::string interpolation_method,
bool benchmark
389 m_g(grid), m_bcx(bcx), m_bcy(bcy), m_bcz(grid.bcz()),
390 m_Nz( grid.local().Nz()), m_mx(mx), m_my(my), m_eps(eps),
391 m_interpolation_method(interpolation_method),
395 MPI_Comm_rank( grid.communicator(), &rank);
396 int dims[3], periods[3], coords[3];
397 dg::mpi_cart_get( m_g->communicator(), 3, dims, periods, coords);
398 m_coords2 = coords[2], m_sizeZ = dims[2];
401 if( (grid.bcx() == PER && bcx != PER) || (grid.bcx() != PER && bcx == PER) )
402 throw(
dg::Error(
dg::Message(_ping_)<<
"Fieldaligned: Got conflicting periodicity in x. The grid says "<<
bc2str(grid.bcx())<<
" while the parameter says "<<
bc2str(bcx)));
403 if( (grid.bcy() == PER && bcy != PER) || (grid.bcy() != PER && bcy == PER) )
404 throw(
dg::Error(
dg::Message(_ping_)<<
"Fieldaligned: Got conflicting boundary conditions in y. The grid says "<<
bc2str(grid.bcy())<<
" while the parameter says "<<
bc2str(bcy)));
405 if( deltaPhi <=0) deltaPhi = grid.hz();
406 m_deltaPhi = deltaPhi;
413 std::array<thrust::host_vector<double>,3> yp_trafo, ym_trafo;
414 thrust::host_vector<double> hbp, hbm;
415 thrust::host_vector<bool> in_boxp, in_boxm;
418 make_matrices( vec, grid_transform, global_grid_magnetic,
419 bcx, bcy, eps, mx, my, m_deltaPhi, interpolation_method,
420 benchmark, vol2d0, hbp, hbm,
423 minus, zero, plus,
false, minusT, plusT
428 m_have_adjoint =
false;
431 std::string inter_m, project_m, fine_m;
432 detail::parse_method( interpolation_method, inter_m, project_m, fine_m);
433 if( project_m !=
"dg")
435 apply_inv_backproject =
true;
437 dg::invert(dg::create::detail::square_backproject( grid.local().grid(0))),
440 dg::invert(dg::create::detail::square_backproject( grid.local().grid(1))),
445 apply_backproject =
true;
447 dg::create::detail::square_backproject( grid.local().grid(0)),
450 dg::create::detail::square_backproject( grid.local().grid(1)),
454 dg::HVec hbphi( yp_trafo[2]), hbphiP(hbphi), hbphiM(hbphi);
460 for(
unsigned i=0; i<hbphiP.size(); i++)
462 hbphiP[i] = vec.
z()(yp_trafo[0][i], yp_trafo[1][i]);
463 hbphiM[i] = vec.
z()(ym_trafo[0][i], ym_trafo[1][i]);
470 for(
unsigned i=0; i<yp_trafo[0].size(); i++)
473 yp_trafo[1][i], *global_grid_magnetic);
475 ym_trafo[1][i], *global_grid_magnetic);
492 m_split_in =
dg::split( (
const MPI_Vector<LocalContainer>&)m_hbm, grid);
497 m_temp0 = m_temp1 = m_hbm;
499 thrust::host_vector<double> bbm( in_boxp.size(),0.), bbo(bbm), bbp(bbm);
500 for(
unsigned i=0; i<in_boxp.size(); i++)
502 if( !in_boxp[i] && !in_boxm[i])
504 else if( !in_boxp[i] && in_boxm[i])
506 else if( in_boxp[i] && !in_boxm[i])
516 m_perp_size = grid_transform->local().size();
519 m_ghostM = m_ghostP = m_right = m_left;
522 dg::detail::MsgChunk chunk { 0, (int)m_perp_size};
524 dg::mpi_cart_shift( grid.comm(2), 0, +1, &source, &dest);
525 std::map<int, thrust::host_vector<dg::detail::MsgChunk>> recvMsgP =
526 {{ dest, thrust::host_vector<dg::detail::MsgChunk>( 1, chunk)}};
527 m_from_plus = dg::detail::MPIContiguousGather( recvMsgP, grid.comm(2));
529 dg::mpi_cart_shift( grid.comm(2), 0, -1, &source, &dest);
530 std::map<int, thrust::host_vector<dg::detail::MsgChunk>> recvMsgM =
531 {{ dest, thrust::host_vector<dg::detail::MsgChunk>( 1, chunk)}};
532 m_from_minus = dg::detail::MPIContiguousGather( recvMsgM, grid.comm(2));
536template<
class G,
class M,
class container>
537void Fieldaligned<G, M, MPI_Vector<container> >::operator()(
enum
539 MPI_Vector<container>& fe)
const
541 if( which == einsPlus || which == einsMinusT ) ePlus( which, f, fe);
542 else if(which == einsMinus || which == einsPlusT ) eMinus( which, f, fe);
543 else if(which == zeroMinus || which == zeroPlus ||
544 which == zeroMinusT|| which == zeroPlusT ||
545 which == zeroForw )
zero( which, f, fe);
547template<
class G,
class M,
class container>
548void Fieldaligned<G, M, MPI_Vector<container> >::zero(
enum whichMatrix which,
const MPI_Vector<container>& f, MPI_Vector<container>& f0)
const
552 if( apply_backproject)
556 dg::split( (
const MPI_Vector<container>&)m_temp1, m_split_in, *m_g);
559 for(
unsigned i0=0; i0<m_Nz; i0++)
561 if(which == zeroPlus)
563 else if(which == zeroMinus)
565 else if(which == zeroPlusT)
567 if( ! m_have_adjoint) updateAdjoint( );
570 else if(which == zeroMinusT)
572 if( ! m_have_adjoint) updateAdjoint( );
575 else if( which == zeroForw)
577 if ( m_interpolation_method !=
"dg" )
585 if( apply_inv_backproject)
592template<
class G,
class M,
class container>
593void Fieldaligned<G,M, MPI_Vector<container> >::ePlus(
enum whichMatrix which,
const MPI_Vector<container>& f, MPI_Vector<container>& fpe )
const
597 if( apply_backproject)
601 dg::split( (
const MPI_Vector<container>&)m_temp1, m_split_in, *m_g);
603 MPI_Vector<dg::View<container>> send_buf(
604 {m_ghostP.data().data(), m_ghostP.size()}, m_g->get_perp_comm());
606 for(
unsigned i0=0; i0<m_Nz; i0++)
609 bool comm_plane = (m_sizeZ != 1 and i0 == m_Nz -1);
610 unsigned ip = (i0==m_Nz-1) ? 0:i0+1;
611 if(which == einsPlus)
612 dg::blas2::symv( m_plus, m_split_in[ip], comm_plane ? send_buf : m_split_out[i0]);
613 else if(which == einsMinusT)
615 if( ! m_have_adjoint) updateAdjoint( );
616 dg::blas2::symv( m_minusT, m_split_in[ip], comm_plane ? send_buf : m_split_out[i0]);
623 unsigned i0 = m_Nz-1;
624 m_from_plus.global_gather_init( send_buf.data(), m_split_out[i0].data());
625 m_from_plus.global_gather_wait( m_split_out[i0].data());
627 if( apply_inv_backproject)
635 if( m_bcz !=
dg::PER && m_g->local().z1() == m_g->global().z1())
647template<
class G,
class M,
class container>
648void Fieldaligned<G, M, MPI_Vector<container> >::eMinus(
enum
649 whichMatrix which,
const MPI_Vector<container>& f, MPI_Vector<container>& fme )
const
652 MPI_Comm_rank(m_g->communicator(), &rank);
655 if( apply_backproject)
659 dg::split( (
const MPI_Vector<container>&)m_temp1, m_split_in, *m_g);
661 MPI_Vector<dg::View<container>> send_buf(
662 {m_ghostM.data().data(), m_ghostM.size()}, m_g->get_perp_comm());
664 for(
unsigned i0=0; i0<m_Nz; i0++)
667 bool comm_plane = (m_sizeZ != 1 and i0 == 0);
668 unsigned im = (i0==0) ? m_Nz-1:i0-1;
669 if(which == einsPlusT)
671 if( ! m_have_adjoint) updateAdjoint( );
672 dg::blas2::symv( m_plusT, m_split_in[im], comm_plane ? send_buf : m_split_out[i0]);
674 else if(which == einsMinus)
675 dg::blas2::symv( m_minus, m_split_in[im], comm_plane ? send_buf : m_split_out[i0]);
682 m_from_minus.global_gather_init( send_buf.data(), m_split_out[i0].data());
683 m_from_minus.global_gather_wait( m_split_out[i0].data());
685 if( apply_inv_backproject)
693 if( m_bcz !=
dg::PER && m_g->local().z0() == m_g->global().z0())
705template<
class G,
class M,
class container>
706template<
class BinaryOp,
class UnaryOp>
707MPI_Vector<container> Fieldaligned<G,M, MPI_Vector<container> >::evaluate( BinaryOp binary, UnaryOp unary,
unsigned p0,
unsigned rounds)
const
711 assert( p0 < m_g->global().Nz());
713 MPI_Vector<container> init2d =
dg::pullback( binary, *g2d);
715 unsigned globalNz = m_g->global().Nz();
716 typename detail::Container2EllSparseBlockMat<container>::type bx, by, inv_bx, inv_by;
717 if( apply_backproject)
720 dg::create::detail::square_backproject( g2d->local().grid(0)),
723 dg::create::detail::square_backproject( g2d->local().grid(1)),
726 if( apply_inv_backproject)
729 dg::invert(dg::create::detail::square_backproject( g2d->local().grid(0))),
732 dg::invert(dg::create::detail::square_backproject( g2d->local().grid(1))),
736 MPI_Vector<container> temp(init2d), tempP(init2d), tempM(init2d);
738 std::vector<MPI_Vector<container> > plus2d(globalNz, zero2d), minus2d(plus2d), result(plus2d);
739 unsigned turns = rounds;
740 if( turns ==0) turns++;
742 for(
unsigned r=0; r<turns; r++)
743 for(
unsigned i0=0; i0<globalNz; i0++)
747 unsigned rep = r*globalNz + i0;
748 for(
unsigned k=0; k<rep; k++)
750 if( apply_backproject)
759 if( apply_inv_backproject)
767 if( apply_inv_backproject)
782 for(
unsigned i0=0; i0<m_Nz; i0++)
784 int idx = (int)(i0+m_coords2*m_Nz) - (int)p0;
786 result[i0] = plus2d[idx];
788 result[i0] = minus2d[abs(idx)];
789 thrust::copy( result[i0].data().begin(), result[i0].data().end(),
790 vec3d.data().begin() + i0*m_perp_size);
795 for(
unsigned i0=0; i0<globalNz; i0++)
797 unsigned revi0 = (globalNz - i0)%globalNz;
802 for(
unsigned i0=0; i0<m_Nz; i0++)
804 int idx = ((int)i0 + m_coords2*m_Nz -(int)p0 + globalNz)%globalNz;
805 thrust::copy( result[idx].data().begin(), result[idx].data().end(),
806 vec3d.data().begin() + i0*m_perp_size);
819template<
class BinaryOp,
class UnaryOp>
823 const BinaryOp& binary,
824 const UnaryOp& unary,
829 unsigned Nz = grid.
Nz();
834 std::vector<dg::MHVec> plus2d(Nz, tempP), minus2d(plus2d), result(plus2d);
836 std::array<dg::HVec,3> yy0{
840 dg::geo::detail::DSFieldCylindrical3 cyl_field(vec);
841 double deltaPhi = grid.
hz();
842 double phiM0 = 0., phiP0 = 0.;
843 unsigned turns = rounds;
844 if( turns == 0) turns++;
845 for(
unsigned r=0; r<turns; r++)
846 for(
unsigned i0=0; i0<Nz; i0++)
848 unsigned rep = r*Nz + i0;
850 tempM = tempP = init2d;
854 "Dormand-Prince-7-4-5", std::array<double,3>{0,0,0});
857 for(
unsigned i=0; i<g2d->local().size(); i++)
860 double phiM1 = phiM0 + deltaPhi;
862 coords0{yy0[0][i],yy0[1][i],yy0[2][i]}, coords1;
863 odeint.integrate_in_domain( phiM0, coords0, phiM1,
864 coords1, deltaPhi, g2d->global(), eps);
865 yy1[0][i] = coords1[0], yy1[1][i] = coords1[1], yy1[2][i] =
867 tempM.data()[i] = binary( yy1[0][i], yy1[1][i]);
870 double phiP1 = phiP0 - deltaPhi;
871 coords0 = std::array<double,3>{xx0[0][i],xx0[1][i],xx0[2][i]};
872 odeint.integrate_in_domain( phiP0, coords0, phiP1,
873 coords1, -deltaPhi, g2d->global(), eps);
874 xx1[0][i] = coords1[0], xx1[1][i] = coords1[1], xx1[2][i] =
876 tempP.
data()[i] = binary( xx1[0][i], xx1[1][i]);
878 std::swap( yy0, yy1);
879 std::swap( xx0, xx1);
889 int dims[3], periods[3], coords[3];
890 mpi_cart_get( grid.
communicator(), 3, dims, periods, coords);
891 unsigned coords2 = coords[2];
894 for(
unsigned i0=0; i0<grid.
local().Nz(); i0++)
896 int idx = (int)(i0+coords2*grid.
local().Nz()) - (int)p0;
898 result[i0] = plus2d[idx];
900 result[i0] = minus2d[abs(idx)];
901 thrust::copy( result[i0].data().begin(), result[i0].data().end(),
902 vec3d.
data().begin() + i0*g2d->local().size());
907 for(
unsigned i0=0; i0<Nz; i0++)
909 unsigned revi0 = (Nz - i0)%Nz;
914 for(
unsigned i0=0; i0<grid.
local().Nz(); i0++)
916 int idx = ((int)i0 +coords2*grid.
local().Nz()-(
int)p0 + Nz)%Nz;
918 thrust::copy( result[idx].data().begin(), result[idx].data().end(),
919 vec3d.
data().begin() + i0*g2d->local().size());
DG_DEVICE double cooX2d(double x, double)
DG_DEVICE double cooY2d(double, double y)
DG_DEVICE T zero(T, Ts ...)
void copy(const ContainerTypeIn &source, ContainerTypeOut &target)
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)
void plus(ContainerType &x, value_type alpha)
void assign(const from_ContainerType &from, ContainerType &to, Params &&... ps)
void scal(ContainerType &x, value_type alpha)
void transfer(const MatrixType &x, AnotherMatrixType &y)
void symv(MatrixType &&M, const ContainerType1 &x, ContainerType2 &y)
std::string bc2str(bc bcx)
auto weights(const Topology &g)
auto evaluate(Functor &&f, const Topology &g)
EllSparseBlockMat< real_type, thrust::host_vector > fast_transform(unsigned coord, const dg::SquareMatrix< real_type > &opx, const aRealTopology< real_type, Nd > &t)
whichMatrix
Enum for the use in Fieldaligned.
Definition fieldaligned.h:16
thrust::host_vector< double > fieldaligned_evaluate(const aProductGeometry3d &grid, const CylindricalVectorLvl0 &vec, const BinaryOp &binary, const UnaryOp &unary, unsigned p0, unsigned rounds, double eps=1e-5)
Evaluate a 2d functor and transform to all planes along the fieldlines
Definition fieldaligned.h:1259
ONE FullLimiter
Full Limiter means there is a limiter everywhere.
Definition fieldaligned.h:30
dg::RealGrid< T, 2 > RealGrid2d
Topology::host_vector forward_transform(const typename Topology::host_vector &in, const Topology &g)
real_type interpolate(dg::space sp, const host_vector &v, real_type x, const RealGrid1d< real_type > &g, dg::bc bcx=dg::NEU)
dg::MIHMatrix_t< typename MPITopology::value_type > projection(const MPITopology &g_new, const MPITopology &g_old, std::string method="dg")
dg::SparseMatrix< int, real_type, thrust::host_vector > interpolation(const RecursiveHostVector &x, const aRealTopology< real_type, Nd > &g, std::array< dg::bc, Nd > bcx, std::string method="dg")
dg::SquareMatrix< T > invert(const dg::SquareMatrix< T > &in)
CylindricalVectorLvl1 createBHat(const TokamakMagneticField &mag)
Contravariant components of the magnetic unit vector field and its Divergence and derivative in cylin...
Definition magnetic_field.h:1154
void convertLocal2GlobalCols(dg::IHMatrix_t< real_type > &local, const ConversionPolicy &policy)
dg::IHMatrix_t< real_type > convertGlobal2LocalRows(const dg::IHMatrix_t< real_type > &global, const ConversionPolicy &row_policy)
dg::MIHMatrix_t< real_type > make_mpi_matrix(const dg::IHMatrix_t< real_type > &global_cols, const ConversionPolicy &col_policy)
Geometry::host_vector pullback(const Functor &f, const Geometry &g)
void assign3dfrom2d(const host_vector &in2d, Container &out, const Topology &grid)
void split(SharedContainer &in, std::vector< View< SharedContainer > > &out, const aRealTopology3d< real_type > &grid)
ContainerType volume(const SparseTensor< ContainerType > &t)
thrust::host_vector< double > HVec
const container & data() const
const LocalMatrixInner & inner_matrix() const
const LocalMatrixOuter & outer_matrix() const
SparseMatrix transpose() const
const Vector< Index > & column_indices() const
MPI_Comm communicator() const
const RealGrid< real_type, Nd > & local() const
aRealMPIGeometry2d< real_type > * perp_grid() const
Definition fluxfunctions.h:415
This struct bundles a vector field and its divergence.
Definition fluxfunctions.h:443
const CylindricalFunctor & z() const
z-component of the vector
Definition fluxfunctions.h:473
dg::bc bcx() const
Definition fieldaligned.h:363
const container & hbp() const
Distance between the planes .
Definition fieldaligned.h:440
const container & bphi() const
The contravariant phi component (3rd component) of the vector field .
Definition fieldaligned.h:460
const container & bbp() const
Mask plus, 1 if fieldline intersects wall in plus direction but not in minus direction,...
Definition fieldaligned.h:485
container evaluate(BinaryOp binary, UnaryOp unary, unsigned p0, unsigned rounds) const
Evaluate a 2d functor and transform to all planes along the fieldline
const container & sqrtG() const
Volume form (including weights) .
Definition fieldaligned.h:445
const container & sqrtGm() const
Volume form on minus plane (including weights) .
Definition fieldaligned.h:450
void set_boundaries(dg::bc bcz, double left, double right)
Set boundary conditions in the limiter region.
Definition fieldaligned.h:380
std::string method() const
Return the interpolation_method string given in the constructor.
Definition fieldaligned.h:550
const container & hbm() const
Distance between the planes and the boundary .
Definition fieldaligned.h:435
const container & bphiM() const
bphi on minus plane
Definition fieldaligned.h:465
dg::bc bcy() const
Definition fieldaligned.h:366
double deltaPhi() const
Definition fieldaligned.h:432
Fieldaligned()
do not allocate memory; no member call except construct is valid
Definition fieldaligned.h:315
void construct(Params &&...ps)
Perfect forward parameters to one of the constructors.
Definition fieldaligned.h:357
void operator()(enum whichMatrix which, const container &in, container &out) const
Apply the interpolation to three-dimensional vectors.
const container & bbo() const
Mask both, 1 if fieldline intersects wall in plus direction and in minus direction,...
Definition fieldaligned.h:480
const container & bbm() const
Mask minus, 1 if fieldline intersects wall in minus direction but not in plus direction,...
Definition fieldaligned.h:475
const container & sqrtGp() const
Volume form on plus plane (including weights) .
Definition fieldaligned.h:455
const container & bphiP() const
bphi on plus plane
Definition fieldaligned.h:470
const ProductGeometry & grid() const
Grid used for construction.
Definition fieldaligned.h:489
A tokamak field as given by R0, Psi and Ipol plus Meta-data like shape and equilibrium.
Definition magnetic_field.h:172