@@ -466,82 +466,97 @@ namespace kernel {
466466 }
467467
468468 Inline void operator ()(index_t p, real_t & buff) const {
469- if (tag (p) == ParticleTag::dead ) {
469+ if (tag (p) != ParticleTag::alive ) {
470470 return ;
471471 }
472+ auto dV = ONE;
473+
472474 if constexpr (P == StatsID::Npart) {
473475 buff += ONE;
474476 return ;
475- } else if constexpr (P == StatsID::N or P == StatsID::Rho or
476- P == StatsID::Charge) {
477- buff += use_weights ? weight (p) : contrib;
478- return ;
479477 } else {
480- // for stress-energy tensor
481- real_t energy { ZERO };
482- vec_t <Dim::_3D> u_Phys { ZERO };
483- if constexpr (S == SimEngine::SRPIC) {
484- // SR
485- // stress-energy tensor for SR is computed in the tetrad (hatted) basis
486- if constexpr (M::CoordType == Coord::Cart) {
487- u_Phys[0 ] = ux1 (p);
488- u_Phys[1 ] = ux2 (p);
489- u_Phys[2 ] = ux3 (p);
478+ coord_t <D> x_Code { ZERO };
479+ if constexpr ((D == Dim::_1D) or (D == Dim::_2D) or (D == Dim::_3D)) {
480+ x_Code[0 ] = static_cast <real_t >(i1 (p)) + static_cast <real_t >(dx1 (p));
481+ }
482+ if constexpr ((D == Dim::_2D) or (D == Dim::_3D)) {
483+ x_Code[1 ] = static_cast <real_t >(i2 (p)) + static_cast <real_t >(dx2 (p));
484+ }
485+ if constexpr (D == Dim::_3D) {
486+ x_Code[2 ] = static_cast <real_t >(i3 (p)) + static_cast <real_t >(dx3 (p));
487+ }
488+ dV = metric.sqrt_det_h (x_Code);
489+ if constexpr (P == StatsID::N or P == StatsID::Rho or P == StatsID::Charge) {
490+ buff += dV * (use_weights ? weight (p) : contrib);
491+ } else {
492+ // for stress-energy tensor
493+ real_t energy { ZERO };
494+ vec_t <Dim::_3D> u_Phys { ZERO };
495+ if constexpr (S == SimEngine::SRPIC) {
496+ // SR
497+ // stress-energy tensor for SR is computed in the tetrad (hatted) basis
498+ if constexpr (M::CoordType == Coord::Cart) {
499+ u_Phys[0 ] = ux1 (p);
500+ u_Phys[1 ] = ux2 (p);
501+ u_Phys[2 ] = ux3 (p);
502+ } else {
503+ static_assert (D != Dim::_1D, " non-Cartesian SRPIC 1D" );
504+ coord_t <M::PrtlDim> x_Code { ZERO };
505+ x_Code[0 ] = static_cast <real_t >(i1 (p)) + static_cast <real_t >(dx1 (p));
506+ x_Code[1 ] = static_cast <real_t >(i2 (p)) + static_cast <real_t >(dx2 (p));
507+ if constexpr (D == Dim::_3D) {
508+ x_Code[2 ] = static_cast <real_t >(i3 (p)) +
509+ static_cast <real_t >(dx3 (p));
510+ } else {
511+ x_Code[2 ] = phi (p);
512+ }
513+ metric.template transform_xyz <Idx::XYZ, Idx::T>(
514+ x_Code,
515+ { ux1 (p), ux2 (p), ux3 (p) },
516+ u_Phys);
517+ }
518+ if (mass == ZERO) {
519+ energy = NORM (u_Phys[0 ], u_Phys[1 ], u_Phys[2 ]);
520+ } else {
521+ energy = mass * math::sqrt (
522+ ONE + NORM_SQR (u_Phys[0 ], u_Phys[1 ], u_Phys[2 ]));
523+ }
490524 } else {
491- static_assert (D != Dim::_1D, " non-Cartesian SRPIC 1D" );
492- coord_t <M::PrtlDim> x_Code { ZERO };
525+ // GR
526+ // stress-energy tensor for GR is computed in contravariant basis
527+ static_assert (D != Dim::_1D, " GRPIC 1D" );
528+ coord_t <D> x_Code { ZERO };
493529 x_Code[0 ] = static_cast <real_t >(i1 (p)) + static_cast <real_t >(dx1 (p));
494530 x_Code[1 ] = static_cast <real_t >(i2 (p)) + static_cast <real_t >(dx2 (p));
495531 if constexpr (D == Dim::_3D) {
496532 x_Code[2 ] = static_cast <real_t >(i3 (p)) + static_cast <real_t >(dx3 (p));
533+ }
534+ vec_t <Dim::_3D> u_Cntrv { ZERO };
535+ // compute u_i u^i for energy
536+ metric.template transform <Idx::D, Idx::U>(x_Code,
537+ { ux1 (p), ux2 (p), ux3 (p) },
538+ u_Cntrv);
539+ energy = u_Cntrv[0 ] * ux1 (p) + u_Cntrv[1 ] * ux2 (p) +
540+ u_Cntrv[2 ] * ux3 (p);
541+ if (mass == ZERO) {
542+ energy = math::sqrt (energy);
497543 } else {
498- x_Code[ 2 ] = phi (p );
544+ energy = mass * math::sqrt (ONE + energy );
499545 }
500- metric.template transform_xyz <Idx::XYZ, Idx::T>(
501- x_Code,
502- { ux1 (p), ux2 (p), ux3 (p) },
503- u_Phys);
546+ metric.template transform <Idx::U, Idx::PU>(x_Code, u_Cntrv, u_Phys);
504547 }
505- if (mass == ZERO) {
506- energy = NORM (u_Phys[0 ], u_Phys[1 ], u_Phys[2 ]);
507- } else {
508- energy = mass *
509- math::sqrt (ONE + NORM_SQR (u_Phys[0 ], u_Phys[1 ], u_Phys[2 ]));
510- }
511- } else {
512- // GR
513- // stress-energy tensor for GR is computed in contravariant basis
514- static_assert (D != Dim::_1D, " GRPIC 1D" );
515- coord_t <D> x_Code { ZERO };
516- x_Code[0 ] = static_cast <real_t >(i1 (p)) + static_cast <real_t >(dx1 (p));
517- x_Code[1 ] = static_cast <real_t >(i2 (p)) + static_cast <real_t >(dx2 (p));
518- if constexpr (D == Dim::_3D) {
519- x_Code[2 ] = static_cast <real_t >(i3 (p)) + static_cast <real_t >(dx3 (p));
520- }
521- vec_t <Dim::_3D> u_Cntrv { ZERO };
522- // compute u_i u^i for energy
523- metric.template transform <Idx::D, Idx::U>(x_Code,
524- { ux1 (p), ux2 (p), ux3 (p) },
525- u_Cntrv);
526- energy = u_Cntrv[0 ] * ux1 (p) + u_Cntrv[1 ] * ux2 (p) + u_Cntrv[2 ] * ux3 (p);
527- if (mass == ZERO) {
528- energy = math::sqrt (energy);
529- } else {
530- energy = mass * math::sqrt (ONE + energy);
531- }
532- metric.template transform <Idx::U, Idx::PU>(x_Code, u_Cntrv, u_Phys);
533- }
534- // compute the corresponding moment
535- real_t coeff = ONE;
548+ // compute the corresponding moment
549+ real_t coeff = ONE;
536550#pragma unroll
537- for (const auto & c : { c1, c2 }) {
538- if (c == 0 ) {
539- coeff *= energy;
540- } else {
541- coeff *= u_Phys[c - 1 ];
551+ for (const auto & c : { c1, c2 }) {
552+ if (c == 0 ) {
553+ coeff *= energy;
554+ } else {
555+ coeff *= u_Phys[c - 1 ];
556+ }
542557 }
558+ buff += dV * coeff / energy;
543559 }
544- buff += coeff / energy;
545560 }
546561 }
547562 };
0 commit comments