diff --git a/src/include/dim.hxx b/src/include/dim.hxx index 089097a27..4e4453728 100644 --- a/src/include/dim.hxx +++ b/src/include/dim.hxx @@ -22,7 +22,8 @@ struct Invar return {!InvarX::value, !InvarY::value, !InvarZ::value}; } - static bool is_invar(int dim) + // TODO c++20 make consteval? + static constexpr bool is_invar(int dim) { switch (dim) { case 0: return InvarX::value; diff --git a/src/include/rng.hxx b/src/include/rng.hxx index 9b8c7236e..2842c5710 100644 --- a/src/include/rng.hxx +++ b/src/include/rng.hxx @@ -59,6 +59,12 @@ struct Uniform Real get() { return dist(*gen); } + Real get(Real min_override, Real max_override) + { + return std::uniform_real_distribution(min_override, + max_override)(*gen); + } + private: detail::GeneratorPtr gen; std::uniform_real_distribution dist; @@ -81,11 +87,11 @@ struct Normal Normal() : Normal(0, 1) {} Real get() { return dist(*gen); } - // FIXME remove me, or make standalone func - Real get(Real mean, Real stdev) + + Real get(Real mean_override, Real stdev_override) { // should be possible to pass params to existing dist - return std::normal_distribution(mean, stdev)(*gen); + return std::normal_distribution(mean_override, stdev_override)(*gen); } private: diff --git a/src/kg/include/kg/Vec3.h b/src/kg/include/kg/Vec3.h index aff5ba926..b8cf3362a 100644 --- a/src/kg/include/kg/Vec3.h +++ b/src/kg/include/kg/Vec3.h @@ -9,6 +9,7 @@ #include "cuda_compat.h" #include #include +#include "psc_bits.h" namespace kg { @@ -102,6 +103,72 @@ struct Vec : gt::sarray return *this; } + KG_INLINE Vec& operator/=(T s) + { + for (size_t i = 0; i < N; i++) { + (*this)[i] /= s; + } + return *this; + } + + KG_INLINE T sum() const + { + T sum{0}; + for (size_t i = 0; i < N; i++) { + sum += (*this)[i]; + } + return sum; + } + + KG_INLINE T prod() const + { + T prod{1}; + for (size_t i = 0; i < N; i++) { + prod *= (*this)[i]; + } + return prod; + } + + KG_INLINE T dot(const Vec& w) const + { + T sum{0}; + for (size_t i = 0; i < N; i++) { + sum += (*this)[i] * w[i]; + } + return sum; + } + + KG_INLINE Vec cross(const Vec& w) const + { + return {(*this)[1] * w[2] - (*this)[2] * w[1], + (*this)[2] * w[0] - (*this)[0] * w[2], + (*this)[0] * w[1] - (*this)[1] * w[0]}; + } + + KG_INLINE T mag2() const { return this->dot(this); } + + KG_INLINE T mag() const { return sqrt(this->mag2()); } + + KG_INLINE T max() const + { + auto max = (*this)[0]; + for (size_t i = 1; i < N; i++) { + max = std::max(max, (*this)[i]); + } + return max; + } + + KG_INLINE Vec inv() const { return T(1) / *this; } + + KG_INLINE Vec fint() const + { + Vec res; + for (size_t i = 0; i < N; i++) { + res[i] = ::fint((*this)[i]); + } + return res; + } + // conversion to pointer KG_INLINE operator const T*() const { return this->data(); } @@ -153,6 +220,24 @@ KG_INLINE Vec operator*(T s, const Vec& v) return res; } +template +KG_INLINE Vec operator/(T s, const Vec& v) +{ + Vec res; + for (size_t i = 0; i < N; i++) { + res[i] = s / v[i]; + } + return res; +} + +template +KG_INLINE Vec operator/(const Vec& v, T s) +{ + Vec res = v; + res /= s; + return res; +} + template KG_INLINE Vec operator/(const Vec& v, const Vec& w) { diff --git a/src/libpsc/psc_push_particles/push_particles_1vb.hxx b/src/libpsc/psc_push_particles/push_particles_1vb.hxx index 912ad48ad..18c8ff180 100644 --- a/src/libpsc/psc_push_particles/push_particles_1vb.hxx +++ b/src/libpsc/psc_push_particles/push_particles_1vb.hxx @@ -24,7 +24,7 @@ struct PushParticlesVb static void push_mprts(Mparticles& mprts, MfieldsState& mflds) { const auto& grid = mprts.grid(); - Real3 dxi = Real3{1., 1., 1.} / Real3(grid.domain.dx); + Real3 dxi = Real3(grid.domain.dx).inv(); real_t dq_kind[MAX_NR_KINDS]; auto& kinds = grid.kinds; assert(kinds.size() <= MAX_NR_KINDS); @@ -60,10 +60,8 @@ struct PushParticlesVb auto v = advance.calc_v(prt.u()); advance.push_x(prt.x(), v); - Int3 final_index; - Real3 final_pos_normalized; - find_idx_pos_1st_rel(prt.x(), dxi, final_index, final_pos_normalized, - real_t(0.)); + Real3 final_pos_normalized = prt.x() * dxi; + Int3 final_index = final_pos_normalized.fint(); // CURRENT DENSITY BETWEEN (n+.5)*dt and (n+1.5)*dt int lg[3];