.. _program_listing_file_include_laplace.h: Program Listing for File laplace.h ================================== |exhale_lsh| :ref:`Return to documentation for file ` (``include/laplace.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #ifndef laplace_h #define laplace_h #include "exafmm_t.h" #include "fmm_scale_invariant.h" #include "geometry.h" #include "intrinsics.h" #include "timer.h" namespace exafmm_t { class LaplaceFmm : public FmmScaleInvariant { public: LaplaceFmm() {} LaplaceFmm(int p_, int ncrit_, std::string filename_=std::string()) : FmmScaleInvariant(p_, ncrit_, filename_) { if (this->filename.empty()) { this->filename = std::string("laplace_") + (std::is_same::value ? "f" : "d") + std::string("_p") + std::to_string(p) + std::string(".dat"); } } void potential_P2P(RealVec& src_coord, RealVec& src_value, RealVec& trg_coord, RealVec& trg_value) { simdvec zero(real_t(0)); real_t newton_coef = 16; // comes from Newton's method in simd rsqrt function simdvec coef(real_t(1.0/(4*PI*newton_coef))); int nsrcs = src_coord.size() / 3; int ntrgs = trg_coord.size() / 3; int t; for (t=0; t+NSIMD<=ntrgs; t+=NSIMD) { simdvec tx(&trg_coord[3*t+0], 3*(int)sizeof(real_t)); simdvec ty(&trg_coord[3*t+1], 3*(int)sizeof(real_t)); simdvec tz(&trg_coord[3*t+2], 3*(int)sizeof(real_t)); simdvec tv(zero); for (int s=0; s zero; tv += invr * sv; } tv *= coef; for (int m=0; m zero; simdvec invr3 = (invr*invr) * invr; simdvec sv(src_value[s]); tv0 += sv * invr; sv *= invr3; tv1 += sv * sx; tv2 += sv * sy; tv3 += sv * sz; } tv0 *= coefp; tv1 *= coefg; tv2 *= coefg; tv3 *= coefg; for (int m=0; m