From 3980f2b81be1251eab9c2d8957fe1d2a99a51b9c Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 09:24:09 -0500 Subject: [PATCH 01/46] -setup_fields_vpic --- src/libpsc/vpic/setup_fields_vpic.hxx | 54 --------------------------- 1 file changed, 54 deletions(-) delete mode 100644 src/libpsc/vpic/setup_fields_vpic.hxx diff --git a/src/libpsc/vpic/setup_fields_vpic.hxx b/src/libpsc/vpic/setup_fields_vpic.hxx deleted file mode 100644 index 5571c0c22a..0000000000 --- a/src/libpsc/vpic/setup_fields_vpic.hxx +++ /dev/null @@ -1,54 +0,0 @@ - -#pragma once - -#include "setup_fields.hxx" - -// FIXME, duplicated only because vpic uses different comp numbers - -#include - -// ====================================================================== -// SetupFields - -using VpicConfig = VpicConfigPsc; - -template <> -struct detail::SetupFields -{ - using MfieldsState = VpicConfig::MfieldsState; - - template - static void run(MfieldsState& mf, FUNC func) - { - for (int p = 0; p < mf.n_patches(); ++p) { - auto& patch = mf.grid().patches[p]; - auto F = make_Fields3d(mf[p]); - - int n_ghosts = - std::max({mf.ibn()[0], mf.ibn()[1], mf.ibn()[2]}); // FIXME, not pretty - // FIXME, do we need the ghost points? - mf.grid().Foreach_3d(n_ghosts, n_ghosts, [&](int jx, int jy, int jz) { - double x_nc = patch.x_nc(jx), y_nc = patch.y_nc(jy), - z_nc = patch.z_nc(jz); - double x_cc = patch.x_cc(jx), y_cc = patch.y_cc(jy), - z_cc = patch.z_cc(jz); - - double ncc[3] = {x_nc, y_cc, z_cc}; - double cnc[3] = {x_cc, y_nc, z_cc}; - double ccn[3] = {x_cc, y_cc, z_nc}; - - double cnn[3] = {x_cc, y_nc, z_nc}; - double ncn[3] = {x_nc, y_cc, z_nc}; - double nnc[3] = {x_nc, y_nc, z_cc}; - - F(MfieldsState::BX, jx, jy, jz) += func(HX, ncc); - F(MfieldsState::BY, jx, jy, jz) += func(HY, cnc); - F(MfieldsState::BZ, jx, jy, jz) += func(HZ, ccn); - - F(MfieldsState::EX, jx, jy, jz) += func(EX, cnn); - F(MfieldsState::EY, jx, jy, jz) += func(EY, ncn); - F(MfieldsState::EZ, jx, jy, jz) += func(EZ, nnc); - }); - } - } -}; From 7de4e3b370b0f178e6e4104255581aa1cf5c8397 Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 09:36:37 -0500 Subject: [PATCH 02/46] -collision_vpic --- src/libpsc/vpic/collision_vpic.hxx | 47 ------------------------------ 1 file changed, 47 deletions(-) delete mode 100644 src/libpsc/vpic/collision_vpic.hxx diff --git a/src/libpsc/vpic/collision_vpic.hxx b/src/libpsc/vpic/collision_vpic.hxx deleted file mode 100644 index fe0ce6dd25..0000000000 --- a/src/libpsc/vpic/collision_vpic.hxx +++ /dev/null @@ -1,47 +0,0 @@ - -#pragma once - -#include "collision.hxx" -#include "vpic_iface.h" - -// ====================================================================== -// PscCollisionVpic - -class PscCollisionVpic : public CollisionBase -{ -public: - constexpr static char const* const name = "vpic"; - - PscCollisionVpic(const Grid_t& grid, int interval, double nu) - : interval_{interval} - {} - - template - void operator()(Mparticles& mprts_base) - { -#if 0 - // Note: Particles should not have moved since the last performance sort - // when calling collision operators. - // FIXME: Technically, this placement of the collision operators only - // yields a first order accurate Trotter factorization (not a second - // order accurate factorization). - - if (collision_op_list) { - // FIXME: originally, vpic_clear_accumulator_array() was called before this. - // It's now called later, though. I'm not sure why that would be necessary here, - // but it needs to be checked. - // The assert() below doesn't unfortunately catch all cases where this might go wrong - // (ie., it's missing the user_particle_collisions()) - - assert(0); - TIC ::apply_collision_op_list(collision_op_list); TOC(collision_model, 1); - } - TIC user_particle_collisions(); TOC(user_particle_collisions, 1); -#endif - } - - int interval() const { return interval_; } - -private: - int interval_; -}; From f951eb6fbfb78fea54b165ad6c0aadf2d96ded70 Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 09:37:58 -0500 Subject: [PATCH 03/46] vpic_config: -USE_VPIC chunk --- src/libpsc/vpic/vpic_config.h | 67 ----------------------------------- 1 file changed, 67 deletions(-) diff --git a/src/libpsc/vpic/vpic_config.h b/src/libpsc/vpic/vpic_config.h index dc08851934..377ae16223 100644 --- a/src/libpsc/vpic/vpic_config.h +++ b/src/libpsc/vpic/vpic_config.h @@ -40,73 +40,6 @@ #include "NoneDiag.h" -#ifdef USE_VPIC - -#include "VpicRng.h" - -#include "VpicGridBase.h" -#include "VpicMaterial.h" - -#include "VpicFieldArrayLocalOps.h" -#include "VpicFieldArrayRemoteOps.h" -#include "VpicFieldArray.h" - -#include "VpicParticleBc.h" - -#include "VpicParticlesBase.h" -#include "VpicParticlesOps.h" - -#include "VpicInterpolator.h" - -#include "VpicAccumulator.h" - -#include "VpicDiag.h" - -#include "mfields_state_vpic.hxx" -#include "mfields_hydro_vpic.hxx" -#include "mfields_interpolator_vpic.hxx" -#include "mfields_accumulator_vpic.hxx" - -struct VpicConfigWrap -{ - using Grid = VpicGridBase; - - using ParticleBcList = VpicParticleBcList; - using Particles = VpicParticlesBase; - using Mparticles = MparticlesVpic_; - - using MaterialList = VpicMaterialList; - using MfieldsState = MfieldsStateVpic; - - using AccumulateOps = VpicAccumulateOps; - - using MfieldsInterpolator = MfieldsInterpolatorVpic; - using InterpolatorOps = PscInterpolatorOps; - - using MfieldsAccumulator = MfieldsAccumulatorVpic; - using AccumulatorOps = PscAccumulatorOps; - - using MfieldsHydro = MfieldsHydroVpic; - -#if 1 // def DO_VPIC - using ParticlesOps = - VpicParticlesOps; -#else - using ParticlesOps = - PscParticlesOps; -#endif - - /* #ifdef DO_VPIC */ - /* using DiagOps = VpicDiagOps; */ - /* #else */ - /* using DiagOps = PscDiagOps; */ - /* #endif */ -}; - -#endif - struct VpicConfigPsc { using Grid = PscGridBase; From 8a7b8263995ac5628c426b189d193f3afade8a23 Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 09:38:55 -0500 Subject: [PATCH 04/46] -VpicAccumulator --- src/libpsc/vpic/VpicAccumulator.h | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 src/libpsc/vpic/VpicAccumulator.h diff --git a/src/libpsc/vpic/VpicAccumulator.h b/src/libpsc/vpic/VpicAccumulator.h deleted file mode 100644 index 611060a6a8..0000000000 --- a/src/libpsc/vpic/VpicAccumulator.h +++ /dev/null @@ -1,16 +0,0 @@ - -#pragma once - -template -struct VpicAccumulatorOps -{ - static void clear(MfieldsAccumulator& acc) { ::clear_accumulator_array(acc); } - static void reduce(MfieldsAccumulator& acc) - { - ::reduce_accumulator_array(acc); - } - static void unload(const MfieldsAccumulator& acc, FieldArray& fa) - { - ::unload_accumulator_array(&fa, acc); - } -}; From 09356bdbbb45dd5e4deee4137694175e948e1bc1 Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 09:40:25 -0500 Subject: [PATCH 05/46] -test_VpicfieldArray --- src/libpsc/vpic/tests/.gitignore | 1 - src/libpsc/vpic/tests/test_VpicFieldArray.cxx | 26 ------------------- 2 files changed, 27 deletions(-) delete mode 100644 src/libpsc/vpic/tests/test_VpicFieldArray.cxx diff --git a/src/libpsc/vpic/tests/.gitignore b/src/libpsc/vpic/tests/.gitignore index dcf9b55e06..6407504551 100644 --- a/src/libpsc/vpic/tests/.gitignore +++ b/src/libpsc/vpic/tests/.gitignore @@ -3,6 +3,5 @@ test_VpicGridBase test_PscGridBase test_VpicInterpolatorBase test_PscInterpolatorBase -test_VpicFieldArray test_PscFieldArray test_RngPool diff --git a/src/libpsc/vpic/tests/test_VpicFieldArray.cxx b/src/libpsc/vpic/tests/test_VpicFieldArray.cxx deleted file mode 100644 index 725a150054..0000000000 --- a/src/libpsc/vpic/tests/test_VpicFieldArray.cxx +++ /dev/null @@ -1,26 +0,0 @@ - -#include "testing.h" - -#include "test_FieldArray.h" - -#include "VpicGridBase.h" -#include "VpicMaterial.h" -#include "VpicFieldArrayBase.h" -#include "VpicFieldArray.h" - -void test_VpicFieldArray() -{ - typedef VpicGridBase Grid; - typedef VpicMaterialList MaterialList; - typedef VpicFieldArrayBase FieldArrayBase; - typedef VpicFieldArray FieldArray; - - test_FieldArray(); -} - -int main(int argc, char** argv) -{ - testing_init(&argc, &argv); - - test_VpicFieldArray(); -} From 3f2040475652260dfad40de92b12f0b50241a30b Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 09:40:54 -0500 Subject: [PATCH 06/46] -VpicFieldArray --- src/libpsc/vpic/VpicFieldArray.h | 35 -------------------------------- 1 file changed, 35 deletions(-) delete mode 100644 src/libpsc/vpic/VpicFieldArray.h diff --git a/src/libpsc/vpic/VpicFieldArray.h b/src/libpsc/vpic/VpicFieldArray.h deleted file mode 100644 index 7260316a02..0000000000 --- a/src/libpsc/vpic/VpicFieldArray.h +++ /dev/null @@ -1,35 +0,0 @@ - -#ifndef VPIC_FIELD_ARRAY_H -#define VPIC_FIELD_ARRAY_H - -// ====================================================================== -// VpicAccumulateOps - -template -struct VpicAccumulateOps -{ - static void clear_jf(field_array_t* fa) { fa->kernel->clear_jf(fa); } - static void synchronize_jf(field_array_t* fa) - { - fa->kernel->synchronize_jf(fa); - } - static void compute_rhob(field_array_t* fa) { fa->kernel->compute_rhob(fa); } - static void compute_curl_b(field_array_t* fa) - { - fa->kernel->compute_curl_b(fa); - } -}; - -// ====================================================================== -// VpicDiagOps - -template -struct VpicDiagOps -{ - static void energy_f(field_array_t* fa, double en[6]) - { - fa->kernel->energy_f(en, fa); - } -}; - -#endif From 9d7fb2493dcfafdcb45a6c86bde6af5109ad39c5 Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 09:43:24 -0500 Subject: [PATCH 07/46] -VpicDiag --- src/libpsc/vpic/VpicDiag.h | 776 ------------------------------------- 1 file changed, 776 deletions(-) delete mode 100644 src/libpsc/vpic/VpicDiag.h diff --git a/src/libpsc/vpic/VpicDiag.h b/src/libpsc/vpic/VpicDiag.h deleted file mode 100644 index dbdfbf66d4..0000000000 --- a/src/libpsc/vpic/VpicDiag.h +++ /dev/null @@ -1,776 +0,0 @@ - -#ifndef VPIC_DIAG_H -#define VPIC_DIAG_H - -#include "vpic/vpic.h" -#include "util/io/FileUtils.h" -#include "vpic/dumpmacros.h" - -// ---------------------------------------------------------------------- -// VpicDiag - -struct VpicDiag -{ - int interval; - int energies_interval; - int fields_interval; - int ehydro_interval; - int Hhydro_interval; - int eparticle_interval; - int Hparticle_interval; - int restart_interval; - - // state - int rtoggle; // enables save of last 2 restart dumps for safety - // Output variables - DumpParameters fdParams; - DumpParameters hedParams; - DumpParameters hHdParams; - std::vector outputParams; -}; - -// ====================================================================== -// VpicDiagOps - -#define _WRITE_HEADER_V0(dump_type, sp_id, q_m, fileIO) \ - do { \ - /* Binary compatibility information */ \ - WRITE(char, CHAR_BIT, fileIO); \ - WRITE(char, sizeof(short int), fileIO); \ - WRITE(char, sizeof(int), fileIO); \ - WRITE(char, sizeof(float), fileIO); \ - WRITE(char, sizeof(double), fileIO); \ - WRITE(short int, 0xcafe, fileIO); \ - WRITE(int, 0xdeadbeef, fileIO); \ - WRITE(float, 1.0, fileIO); \ - WRITE(double, 1.0, fileIO); \ - /* Dump type and header format version */ \ - WRITE(int, 0 /* Version */, fileIO); \ - WRITE(int, dump_type, fileIO); \ - /* High level information */ \ - WRITE(int, step, fileIO); \ - WRITE(int, nxout, fileIO); \ - WRITE(int, nyout, fileIO); \ - WRITE(int, nzout, fileIO); \ - WRITE(float, grid->dt, fileIO); \ - WRITE(float, dxout, fileIO); \ - WRITE(float, dyout, fileIO); \ - WRITE(float, dzout, fileIO); \ - WRITE(float, grid->x0, fileIO); \ - WRITE(float, grid->y0, fileIO); \ - WRITE(float, grid->z0, fileIO); \ - WRITE(float, grid->cvac, fileIO); \ - WRITE(float, grid->eps0, fileIO); \ - WRITE(float, 0 /* damp */, fileIO); \ - WRITE(int, rank, fileIO); \ - WRITE(int, nproc, fileIO); \ - /* Species parameters */ \ - WRITE(int, sp_id, fileIO); \ - WRITE(float, q_m, fileIO); \ - } while (0) - -namespace dump_type -{ -const int grid_dump = 0; -const int field_dump = 1; -const int hydro_dump = 2; -const int particle_dump = 3; -const int restart_dump = 4; -const int history_dump = 5; -} // namespace dump_type - -static FieldInfo fieldInfo[12] = { - {"Electric Field", "VECTOR", "3", "FLOATING_POINT", sizeof(float)}, - {"Electric Field Divergence Error", "SCALAR", "1", "FLOATING_POINT", - sizeof(float)}, - {"Magnetic Field", "VECTOR", "3", "FLOATING_POINT", sizeof(float)}, - {"Magnetic Field Divergence Error", "SCALAR", "1", "FLOATING_POINT", - sizeof(float)}, - {"TCA Field", "VECTOR", "3", "FLOATING_POINT", sizeof(float)}, - {"Bound Charge Density", "SCALAR", "1", "FLOATING_POINT", sizeof(float)}, - {"Free Current Field", "VECTOR", "3", "FLOATING_POINT", sizeof(float)}, - {"Charge Density", "SCALAR", "1", "FLOATING_POINT", sizeof(float)}, - {"Edge Material", "VECTOR", "3", "INTEGER", sizeof(material_id)}, - {"Node Material", "SCALAR", "1", "INTEGER", sizeof(material_id)}, - {"Face Material", "VECTOR", "3", "INTEGER", sizeof(material_id)}, - {"Cell Material", "SCALAR", "1", "INTEGER", - sizeof(material_id)}}; // fieldInfo - -static HydroInfo hydroInfo[5] = { - {"Current Density", "VECTOR", "3", "FLOATING_POINT", sizeof(float)}, - {"Charge Density", "SCALAR", "1", "FLOATING_POINT", sizeof(float)}, - {"Momentum Density", "VECTOR", "3", "FLOATING_POINT", sizeof(float)}, - {"Kinetic Energy Density", "SCALAR", "1", "FLOATING_POINT", sizeof(float)}, - {"Stress Tensor", "TENSOR", "6", "FLOATING_POINT", - sizeof(float)}}; // hydroInfo - -#undef sim_log -#define sim_log(x) \ - do { \ - int rank; \ - MPI_Comm_rank(MPI_COMM_WORLD, &rank); \ - if (rank == 0) { \ - std::cerr << "SIM_LOG: " << x << std::endl; \ - std::cerr.flush(); \ - } \ - } while (0) - -template -struct VpicDiagMixin -{ - using Grid = typename Mparticles::Grid; - - void diagnostics_init(int interval_) - { - diag_.rtoggle = 0; - - diag_.interval = interval_; - diag_.fields_interval = interval_; - diag_.ehydro_interval = interval_; - diag_.Hhydro_interval = interval_; - diag_.eparticle_interval = 8 * interval_; - diag_.Hparticle_interval = 8 * interval_; - diag_.restart_interval = 8000; - - diag_.energies_interval = 50; - - MPI_Comm comm = MPI_COMM_WORLD; - mpi_printf(comm, "interval = %d\n", diag_.interval); - mpi_printf(comm, "energies_interval: %d\n", diag_.energies_interval); - } - - void diagnostics_setup() - { - diag_.fdParams.format = band; - sim_log("Fields output format = band"); - - diag_.hedParams.format = band; - sim_log("Electron species output format = band"); - - diag_.hHdParams.format = band; - sim_log("Ion species output format = band"); - - // relative path to fields data from global header - sprintf(diag_.fdParams.baseDir, "fields"); - - // base file name for fields output - sprintf(diag_.fdParams.baseFileName, "fields"); - - diag_.fdParams.stride_x = 1; - diag_.fdParams.stride_y = 1; - diag_.fdParams.stride_z = 1; - - // add field parameters to list - diag_.outputParams.push_back(&diag_.fdParams); - - sim_log("Fields x-stride " << diag_.fdParams.stride_x); - sim_log("Fields y-stride " << diag_.fdParams.stride_y); - sim_log("Fields z-stride " << diag_.fdParams.stride_z); - - // relative path to electron species data from global header - sprintf(diag_.hedParams.baseDir, "hydro"); - - // base file name for fields output - sprintf(diag_.hedParams.baseFileName, "ehydro"); - - diag_.hedParams.stride_x = 1; - diag_.hedParams.stride_y = 1; - diag_.hedParams.stride_z = 1; - - // add electron species parameters to list - diag_.outputParams.push_back(&diag_.hedParams); - - sim_log("Electron species x-stride " << diag_.hedParams.stride_x); - sim_log("Electron species y-stride " << diag_.hedParams.stride_y); - sim_log("Electron species z-stride " << diag_.hedParams.stride_z); - - // relative path to ion species data from global header - sprintf(diag_.hHdParams.baseDir, "hydro"); - - // base file name for fields output - sprintf(diag_.hHdParams.baseFileName, "Hhydro"); - - diag_.hHdParams.stride_x = 1; - diag_.hHdParams.stride_y = 1; - diag_.hHdParams.stride_z = 1; - - sim_log("Ion species x-stride " << diag_.hHdParams.stride_x); - sim_log("Ion species y-stride " << diag_.hHdParams.stride_y); - sim_log("Ion species z-stride " << diag_.hHdParams.stride_z); - - // add ion species parameters to list - diag_.outputParams.push_back(&diag_.hHdParams); - - diag_.fdParams.output_variables(all); - diag_.hedParams.output_variables(all); - diag_.hHdParams.output_variables(all); - - char varlist[512]; - create_field_list(varlist, diag_.fdParams); - - sim_log("Fields variable list: " << varlist); - - create_hydro_list(varlist, diag_.hedParams); - - sim_log("Electron species variable list: " << varlist); - - create_hydro_list(varlist, diag_.hHdParams); - - sim_log("Ion species variable list: " << varlist); - } - -#define should_dump(x) \ - (diag_.x##_interval > 0 && remainder(step, diag_.x##_interval) == 0) - - void diagnostics_run(Mparticles& mprts, MfieldsState& mflds, - MfieldsInterpolator& interpolator, - MfieldsHydro& mflds_hydro, const int np[3]) - { - TIC - { - const Grid* g = mflds.vgrid(); - int64_t step = g->step; - - // Normal rundata dump - if (step == 0) { - dump_mkdir("fields"); - dump_mkdir("hydro"); - dump_mkdir("rundata"); - dump_mkdir("injectors"); - dump_mkdir("restart1"); // 1st backup - dump_mkdir("restart2"); // 2nd backup - dump_mkdir("particle"); - - // dump_grid("rundata/grid"); - // dump_materials("rundata/materials"); - // dump_species("rundata/species"); - global_header(g, np, "global", diag_.outputParams); - } - - // Normal rundata energies dump - if (should_dump(energies)) { - dump_energies("rundata/energies", step != 0, mprts, mflds, - interpolator); - } - - // Field data output - - if (should_dump(fields)) - field_dump(mflds, diag_.fdParams); - - // Species moment output - - if (should_dump(ehydro)) - hydro_dump(mprts, interpolator, mflds_hydro, "electron", - diag_.hedParams); - if (should_dump(Hhydro)) - hydro_dump(mprts, interpolator, mflds_hydro, "ion", diag_.hHdParams); - -#if 0 - if(step && !(step % diag->restart_interval)) { - if(!diag->rtoggle) { - diag->rtoggle = 1; - //checkpt("restart1/restart", 0); - } - else { - diag->rtoggle = 0; - //checkpt("restart2/restart", 0); - } // if - } // if -#endif - - // Dump particle data - -#if 0 - char subdir[36]; - if ( should_dump(eparticle) && step !=0 - && step > 56*(diag->fields_interval) ) { - // if ( should_dump(eparticle) && step !=0 ) { - sprintf(subdir,"particle/T.%lld",step); - dump_mkdir(subdir); - sprintf(subdir,"particle/T.%lld/eparticle",step); - simulation->dump_particles("electron", subdir); - } - - if ( should_dump(Hparticle) && step !=0 - && step > 56*(diag->fields_interval) ) { - sprintf(subdir,"particle/T.%lld/Hparticle",step); - simulation->dump_particles("ion", subdir); - } -#endif - } - TOC(user_diagnostics, 1); - } - -#undef should_dump - - void create_field_list(char* strlist, DumpParameters& dumpParams) - { - strcpy(strlist, ""); - for (int i = 0, pass = 0; i < total_field_groups; i++) { - if (dumpParams.output_vars.bitset(field_indeces[i])) { - if (i > 0 && pass) - strcat(strlist, ", "); - else - pass = 1; - strcat(strlist, fieldInfo[i].name); - } - } - } - - void create_hydro_list(char* strlist, DumpParameters& dumpParams) - { - strcpy(strlist, ""); - for (size_t i(0), pass(0); i < total_hydro_groups; i++) { - if (dumpParams.output_vars.bitset(hydro_indeces[i])) { - if (i > 0 && pass) - strcat(strlist, ", "); - else - pass = 1; - strcat(strlist, hydroInfo[i].name); - } - } - } - - static int dump_mkdir(const char* dname) - { - return FileUtils::makeDirectory(dname); - } - - static void print_hashed_comment(FileIO& fileIO, const char* comment) - { - fileIO.print("#############################################################" - "###################\n"); - fileIO.print("# %s\n", comment); - fileIO.print("#############################################################" - "###################\n"); - } - - // ---------------------------------------------------------------------- - // global_header - - void global_header(const Grid* grid, const int* np, const char* base, - std::vector dumpParams) - { - int rank; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - if (rank != 0) - return; - - // Open the file for output - char filename[256]; - sprintf(filename, "%s.vpc", base); - - FileIO fileIO; - FileIOStatus status; - - status = fileIO.open(filename, io_write); - if (status == fail) - LOG_ERROR("Failed opening file: %s", filename); - - print_hashed_comment(fileIO, "Header version information"); - fileIO.print("VPIC_HEADER_VERSION 1.0.0\n\n"); - - print_hashed_comment(fileIO, "Header size for data file headers in bytes"); - fileIO.print("DATA_HEADER_SIZE 123\n\n"); - - // Global grid inforation - print_hashed_comment(fileIO, "Time step increment"); - fileIO.print("GRID_DELTA_T %f\n\n", grid->dt); - - print_hashed_comment(fileIO, "GRID_CVAC"); - fileIO.print("GRID_CVAC %f\n\n", grid->cvac); - - print_hashed_comment(fileIO, "GRID_EPS0"); - fileIO.print("GRID_EPS0 %f\n\n", grid->eps0); - - print_hashed_comment(fileIO, "Grid extents in the x-dimension"); - fileIO.print("GRID_EXTENTS_X %f %f\n\n", grid->x0, grid->x1); - - print_hashed_comment(fileIO, "Grid extents in the y-dimension"); - fileIO.print("GRID_EXTENTS_Y %f %f\n\n", grid->y0, grid->y1); - - print_hashed_comment(fileIO, "Grid extents in the z-dimension"); - fileIO.print("GRID_EXTENTS_Z %f %f\n\n", grid->z0, grid->z1); - - print_hashed_comment(fileIO, "Spatial step increment in x-dimension"); - fileIO.print("GRID_DELTA_X %f\n\n", grid->dx); - - print_hashed_comment(fileIO, "Spatial step increment in y-dimension"); - fileIO.print("GRID_DELTA_Y %f\n\n", grid->dy); - - print_hashed_comment(fileIO, "Spatial step increment in z-dimension"); - fileIO.print("GRID_DELTA_Z %f\n\n", grid->dz); - - print_hashed_comment(fileIO, "Domain partitions in x-dimension"); - fileIO.print("GRID_TOPOLOGY_X %d\n\n", np[0]); - - print_hashed_comment(fileIO, "Domain partitions in y-dimension"); - fileIO.print("GRID_TOPOLOGY_Y %d\n\n", np[1]); - - print_hashed_comment(fileIO, "Domain partitions in z-dimension"); - fileIO.print("GRID_TOPOLOGY_Z %d\n\n", np[2]); - - // Global data information - assert(dumpParams.size() >= 2); - - print_hashed_comment(fileIO, "Field data information"); - fileIO.print("FIELD_DATA_DIRECTORY %s\n", dumpParams[0]->baseDir); - fileIO.print("FIELD_DATA_BASE_FILENAME %s\n", dumpParams[0]->baseFileName); - - // Create a variable list of field values to output. - size_t numvars = std::min( - dumpParams[0]->output_vars.bitsum(field_indeces, total_field_groups), - total_field_groups); - size_t* varlist = new size_t[numvars]; - for (size_t v(0), c(0); v < total_field_groups; v++) - if (dumpParams[0]->output_vars.bitset(field_indeces[v])) - varlist[c++] = v; - - // output variable list - fileIO.print("FIELD_DATA_VARIABLES %d\n", numvars); - - for (size_t v(0); v < numvars; v++) - fileIO.print("\"%s\" %s %s %s %d\n", fieldInfo[varlist[v]].name, - fieldInfo[varlist[v]].degree, fieldInfo[varlist[v]].elements, - fieldInfo[varlist[v]].type, fieldInfo[varlist[v]].size); - - fileIO.print("\n"); - - delete[] varlist; - varlist = NULL; - - // Create a variable list for each species to output - print_hashed_comment(fileIO, "Number of species with output data"); - fileIO.print("NUM_OUTPUT_SPECIES %d\n\n", dumpParams.size() - 1); - char species_comment[128]; - for (size_t i(1); i < dumpParams.size(); i++) { - numvars = std::min( - dumpParams[i]->output_vars.bitsum(hydro_indeces, total_hydro_groups), - total_hydro_groups); - - sprintf(species_comment, "Species(%d) data information", (int)i); - print_hashed_comment(fileIO, species_comment); - fileIO.print("SPECIES_DATA_DIRECTORY %s\n", dumpParams[i]->baseDir); - fileIO.print("SPECIES_DATA_BASE_FILENAME %s\n", - dumpParams[i]->baseFileName); - - fileIO.print("HYDRO_DATA_VARIABLES %d\n", numvars); - - varlist = new size_t[numvars]; - for (size_t v(0), c(0); v < total_hydro_groups; v++) - if (dumpParams[i]->output_vars.bitset(hydro_indeces[v])) - varlist[c++] = v; - - for (size_t v(0); v < numvars; v++) - fileIO.print("\"%s\" %s %s %s %d\n", hydroInfo[varlist[v]].name, - hydroInfo[varlist[v]].degree, - hydroInfo[varlist[v]].elements, hydroInfo[varlist[v]].type, - hydroInfo[varlist[v]].size); - - delete[] varlist; - varlist = NULL; - - if (i < dumpParams.size() - 1) - fileIO.print("\n"); - } - - if (fileIO.close()) - LOG_ERROR("File close failed on global header!!!"); - } - - // ---------------------------------------------------------------------- - // dump_energies - - void dump_energies(const char* fname, int append, Mparticles& mprts, - MfieldsState& mflds, MfieldsInterpolator& interpolator) - { - double en_f[6], en_p; - const Grid* g = mflds.vgrid(); - FileIO fileIO; - FileIOStatus status(fail); - - int rank = psc_world_rank; - - if (!fname) - LOG_ERROR("Invalid file name"); - - if (rank == 0) { - status = fileIO.open(fname, append ? io_append : io_write); - if (status == fail) - LOG_ERROR("Could not open \"%s\".", fname); - else { - if (append == 0) { - fileIO.print("%% Layout\n%% step ex ey ez bx by bz"); - for (auto& sp : mprts) { - fileIO.print(" \"%s\"", sp.name); - } - fileIO.print("\n"); - fileIO.print("%% timestep = %e\n", g->dt); - } - fileIO.print("%li", g->step); - } - } - - DiagOps::energy_f(mflds, en_f); - if (rank == 0 && status != fail) - fileIO.print(" %e %e %e %e %e %e", en_f[0], en_f[1], en_f[2], en_f[3], - en_f[4], en_f[5]); - - for (auto& sp : mprts) { - en_p = ParticlesOps::energy_p(sp, interpolator); - if (rank == 0 && status != fail) - fileIO.print(" %e", en_p); - } - - if (rank == 0 && status != fail) { - fileIO.print("\n"); - if (fileIO.close()) - LOG_ERROR("File close failed on dump energies!!!"); - } - } - - // ---------------------------------------------------------------------- - // field_dump - - void field_dump(MfieldsState& mflds, DumpParameters& dumpParams) - { - const Grid* grid = mflds.vgrid(); - auto& fa = mflds.getPatch(0); - Field3D F(fa); - int64_t step = grid->step; - int rank = psc_world_rank; - int nproc = psc_world_size; - - // Create directory for this time step - char timeDir[256]; - sprintf(timeDir, "%s/T.%ld", dumpParams.baseDir, (long)step); - dump_mkdir(timeDir); - - // Open the file for output - char filename[256]; - sprintf(filename, "%s/T.%ld/%s.%ld.%d", dumpParams.baseDir, (long)step, - dumpParams.baseFileName, (long)step, rank); - - FileIO fileIO; - FileIOStatus status; - - status = fileIO.open(filename, io_write); - if (status == fail) - LOG_ERROR("Failed opening file: %s", filename); - - // convenience - const size_t istride(dumpParams.stride_x); - const size_t jstride(dumpParams.stride_y); - const size_t kstride(dumpParams.stride_z); - - // Check stride values. - if (remainder(grid->nx, istride) != 0) - LOG_ERROR("x stride must be an integer factor of nx"); - if (remainder(grid->ny, jstride) != 0) - LOG_ERROR("y stride must be an integer factor of ny"); - if (remainder(grid->nz, kstride) != 0) - LOG_ERROR("z stride must be an integer factor of nz"); - - int dim[3]; - - /* IMPORTANT: these values are written in WRITE_HEADER_V0 */ - int nxout = (grid->nx) / istride; - int nyout = (grid->ny) / jstride; - int nzout = (grid->nz) / kstride; - float dxout = (grid->dx) * istride; - float dyout = (grid->dy) * jstride; - float dzout = (grid->dz) * kstride; - - assert(dumpParams.format == band); - - _WRITE_HEADER_V0(dump_type::field_dump, -1, 0, fileIO); - - dim[0] = nxout + 2; - dim[1] = nyout + 2; - dim[2] = nzout + 2; - - WRITE_ARRAY_HEADER((&F(0, 0, 0)), 3, dim, fileIO); - - // Create a variable list of field values to output. - size_t numvars = - std::min(dumpParams.output_vars.bitsum(), total_field_variables); - size_t* varlist = new size_t[numvars]; - - for (size_t i(0), c(0); i < total_field_variables; i++) - if (dumpParams.output_vars.bitset(i)) - varlist[c++] = i; - - if (numvars > 20) - numvars = 20; // FIXME!!! materialid are 16 bit - - // more efficient for standard case - if (istride == 1 && jstride == 1 && kstride == 1) - for (size_t v(0); v < numvars; v++) { - for (size_t k(0); k < nzout + 2; k++) { - for (size_t j(0); j < nyout + 2; j++) { - for (size_t i(0); i < nxout + 2; i++) { - const uint32_t* fref = reinterpret_cast(&F(i, j, k)); - fileIO.write(&fref[varlist[v]], 1); - } - } - } - } - - else - - for (size_t v(0); v < numvars; v++) { - for (size_t k(0); k < nzout + 2; k++) { - const size_t koff = (k == 0) ? 0 - : (k == nzout + 1) ? grid->nz + 1 - : k * kstride - 1; - for (size_t j(0); j < nyout + 2; j++) { - const size_t joff = (j == 0) ? 0 - : (j == nyout + 1) ? grid->ny + 1 - : j * jstride - 1; - for (size_t i(0); i < nxout + 2; i++) { - const size_t ioff = (i == 0) ? 0 - : (i == nxout + 1) ? grid->nx + 1 - : i * istride - 1; - const uint32_t* fref = - reinterpret_cast(&F(ioff, joff, koff)); - fileIO.write(&fref[varlist[v]], 1); - } - } - } - } - - delete[] varlist; - - if (fileIO.close()) - LOG_ERROR("File close failed on field dump!!!"); - } - - // ---------------------------------------------------------------------- - // hydro_dump - - void hydro_dump(Mparticles& mprts, MfieldsInterpolator& interpolator, - MfieldsHydro& mflds_hydro, const char* speciesname, - DumpParameters& dumpParams) - { - Field3D H{mflds_hydro.getPatch(0)}; - const Grid* grid = mflds_hydro.vgrid(); - int64_t step = grid->step; - int rank = psc_world_rank; - int nproc = psc_world_size; - - // Create directory for this time step - char timeDir[256]; - sprintf(timeDir, "%s/T.%ld", dumpParams.baseDir, (long)step); - dump_mkdir(timeDir); - - // Open the file for output - char filename[256]; - sprintf(filename, "%s/T.%ld/%s.%ld.%d", dumpParams.baseDir, (long)step, - dumpParams.baseFileName, (long)step, rank); - - FileIO fileIO; - FileIOStatus status; - - status = fileIO.open(filename, io_write); - if (status == fail) - LOG_ERROR("Failed opening file: %s", filename); - - auto& sp = *std::find_if(mprts.begin(), mprts.end(), - [&](const typename Mparticles::Species& sp) { - return strcmp(sp.name, speciesname) == 0; - }); - - HydroArrayOps::clear(mflds_hydro); - ParticlesOps::accumulate_hydro_p(mflds_hydro, sp, interpolator); - HydroArrayOps::synchronize(mflds_hydro); - - // convenience - const size_t istride(dumpParams.stride_x); - const size_t jstride(dumpParams.stride_y); - const size_t kstride(dumpParams.stride_z); - - // Check stride values. - if (remainder(grid->nx, istride) != 0) - LOG_ERROR("x stride must be an integer factor of nx"); - if (remainder(grid->ny, jstride) != 0) - LOG_ERROR("y stride must be an integer factor of ny"); - if (remainder(grid->nz, kstride) != 0) - LOG_ERROR("z stride must be an integer factor of nz"); - - int dim[3]; - - /* IMPORTANT: these values are written in WRITE_HEADER_V0 */ - int nxout = (grid->nx) / istride; - int nyout = (grid->ny) / jstride; - int nzout = (grid->nz) / kstride; - float dxout = (grid->dx) * istride; - float dyout = (grid->dy) * jstride; - float dzout = (grid->dz) * kstride; - - assert(dumpParams.format == band); - - _WRITE_HEADER_V0(dump_type::hydro_dump, sp.id, sp.q / sp.m, fileIO); - - dim[0] = nxout + 2; - dim[1] = nyout + 2; - dim[2] = nzout + 2; - - WRITE_ARRAY_HEADER((&H(0, 0, 0)), 3, dim, fileIO); - - /* - * Create a variable list of hydro values to output. - */ - size_t numvars = - std::min(dumpParams.output_vars.bitsum(), total_hydro_variables); - size_t* varlist = new size_t[numvars]; - for (size_t i(0), c(0); i < total_hydro_variables; i++) - if (dumpParams.output_vars.bitset(i)) - varlist[c++] = i; - - // More efficient for standard case - if (istride == 1 && jstride == 1 && kstride == 1) - - for (size_t v(0); v < numvars; v++) - for (size_t k(0); k < nzout + 2; k++) - for (size_t j(0); j < nyout + 2; j++) - for (size_t i(0); i < nxout + 2; i++) { - const uint32_t* href = reinterpret_cast(&H(0, 0, 0)); - fileIO.write(&href[varlist[v]], 1); - } - - else - - for (size_t v(0); v < numvars; v++) - for (size_t k(0); k < nzout + 2; k++) { - const size_t koff = (k == 0) ? 0 - : (k == nzout + 1) ? grid->nz + 1 - : k * kstride - 1; - for (size_t j(0); j < nyout + 2; j++) { - const size_t joff = (j == 0) ? 0 - : (j == nyout + 1) ? grid->ny + 1 - : j * jstride - 1; - for (size_t i(0); i < nxout + 2; i++) { - const size_t ioff = (i == 0) ? 0 - : (i == nxout + 1) ? grid->nx + 1 - : i * istride - 1; - const uint32_t* href = - reinterpret_cast(&H(ioff, joff, koff)); - fileIO.write(&href[varlist[v]], 1); - } - } - } - - delete[] varlist; - - if (fileIO.close()) - LOG_ERROR("File close failed on hydro dump!!!"); - } - -private: - VpicDiag diag_; -}; - -#endif From 3fce704c265686fddcf27fe915e172c13d95cd37 Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 09:44:08 -0500 Subject: [PATCH 08/46] -sort_vpic --- src/libpsc/vpic/sort_vpic.hxx | 131 ---------------------------------- 1 file changed, 131 deletions(-) delete mode 100644 src/libpsc/vpic/sort_vpic.hxx diff --git a/src/libpsc/vpic/sort_vpic.hxx b/src/libpsc/vpic/sort_vpic.hxx deleted file mode 100644 index a0afbc801a..0000000000 --- a/src/libpsc/vpic/sort_vpic.hxx +++ /dev/null @@ -1,131 +0,0 @@ - -#pragma once - -#include "vpic_iface.h" - -#ifdef USE_VPIC - -// ====================================================================== -// SortVpicWrap -// -// wraps the actual vpic sort; only works with Mparticles which themselves wrap -// the vpic particles - -template -struct SortVpicWrap -{ - void operator()(Mparticles& mprts) - { - auto step = mprts.grid().timestep(); - // Sort the particles for performance if desired. - - for (auto& sp : mprts[0]) { - if (sp.sort_interval > 0 && (step % sp.sort_interval) == 0) { - mpi_printf(MPI_COMM_WORLD, "Performance sorting \"%s\"\n", sp.name); - TIC ::sort_p(&sp); - TOC(sort_p, 1); - } - } - } -}; - -#endif - -// ====================================================================== -// SortVpic -// -// sorts vpic-style particles - -template -struct SortVpic -{ - using Grid = typename Mparticles::Grid; - using Species = typename Mparticles::Species; - using Particle = typename Mparticles::Particle; - - // ---------------------------------------------------------------------- - // operator() - - void operator()(Mparticles& mprts) - { - auto step = mprts.grid().timestep(); - // Sort the particles for performance if desired. - - for (auto& sp : mprts[0]) { - if (sp.sort_interval > 0 && (step % sp.sort_interval) == 0) { - mpi_printf(MPI_COMM_WORLD, "Performance sorting \"%s\"\n", sp.name); - TIC sort_p(sp); - TOC(sort_p, 1); - } - } - } - -private: - // ---------------------------------------------------------------------- - // sort_p - - static void sort_p(Species& sp) - { - const auto& g = sp.vgrid(); - sp.last_sorted = g.step; - - int n_prts = sp.np; - int vl = VOXEL(1, 1, 1, g.nx, g.ny, g.nz); - int vh = VOXEL(g.nx, g.ny, g.nz, g.nx, g.ny, g.nz) + 1; - - static int* RESTRICT ALIGNED(128) next; - if (!next) { - next = new int[g.nv]; - } - int* RESTRICT ALIGNED(128) partition = sp.partition; - - static Particle* RESTRICT ALIGNED(128) p_aux; - static size_t n_alloced; - if (n_prts > n_alloced) { - delete[] p_aux; - p_aux = new Particle[n_prts]; - n_alloced = n_prts; - } - Particle* RESTRICT ALIGNED(128) p = sp.p; - - // zero counts - for (int v = vl; v < vh; v++) { - next[v] = 0; - } - - // find counts - for (int i = 0; i < n_prts; i++) { - next[p[i].i]++; - } - - // prefix sum - int sum = 0; - for (int v = vl; v < vh; v++) { - int count = next[v]; - next[v] = sum; - partition[v] = sum; - sum += count; - } - partition[vh] = sum; - - // reorder - for (int i = 0; i < n_prts; i++) { - int v = p[i].i; - int j = next[v]++; - p_aux[j] = p[i]; - } - - // fix up unused part of partition - for (int i = 0; i < vl; i++) { - partition[i] = 0; - } - for (int i = vh; i < g.nv; i++) { - partition[i] = n_prts; - } - - // OPT: just swap pointer? - for (int i = 0; i < n_prts; i++) { - p[i] = p_aux[i]; - } - } -}; From 7fe32d12581d6aac19ea3fb6a8943decab559a1b Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 09:44:51 -0500 Subject: [PATCH 09/46] -VpicParticlesOps --- src/libpsc/vpic/VpicParticlesOps.h | 84 ------------------------------ 1 file changed, 84 deletions(-) delete mode 100644 src/libpsc/vpic/VpicParticlesOps.h diff --git a/src/libpsc/vpic/VpicParticlesOps.h b/src/libpsc/vpic/VpicParticlesOps.h deleted file mode 100644 index a47734ee7b..0000000000 --- a/src/libpsc/vpic/VpicParticlesOps.h +++ /dev/null @@ -1,84 +0,0 @@ - -#pragma once - -template -struct VpicParticlesOps -{ - using ParticleBcList = typename Mparticles::ParticleBcList; - using FieldArray = typename MfieldsState::FieldArray; - - static void advance_p(Mparticles& mprts, MfieldsAccumulator& accumulator, - MfieldsInterpolator& interpolator) - { - auto prts = mprts[0]; - for (auto sp = prts.begin(); sp != prts.end(); ++sp) { - TIC ::advance_p(&*sp, accumulator, interpolator.getPatch(0).ip()); - TOC(advance_p, 1); - } - } - - static void boundary_p(const ParticleBcList& pbc_list, Mparticles& mprts, - MfieldsState& mflds, MfieldsAccumulator& accumulator) - { - const particle_bc_t* pbc = pbc_list; - ::boundary_p(const_cast(pbc), mprts.head(), mflds, - accumulator); - } - - static void accumulate_rhob(MfieldsState& mflds, const particle_t* p, - float qsp) - { - FieldArray* fa = mflds; - ::accumulate_rhob(fa->f, p, fa->g, qsp); - } - - // ---------------------------------------------------------------------- - // drop_p - - static void drop_p(Mparticles& mprts, MfieldsState& mflds) - { - auto prts = mprts[0]; - for (auto sp = prts.begin(); sp != prts.end(); ++sp) { - if (sp->nm) { - LOG_WARN("Removing %i particles associated with unprocessed %s movers " - "(increase num_comm_round)", - sp->nm, sp->name); - } - // Drop the particles that have unprocessed movers due to a user defined - // boundary condition. Particles of this type with unprocessed movers are - // in the list of particles and move_p has set the voxel in the particle - // to 8*voxel + face. This is an incorrect voxel index and in many cases - // can in fact go out of bounds of the voxel indexing space. Removal is in - // reverse order for back filling. Particle charge is accumulated to the - // mesh before removing the particle. - int nm = sp->nm; - particle_mover_t* RESTRICT ALIGNED(16) pm = sp->pm + sp->nm - 1; - particle_t* RESTRICT ALIGNED(128) p0 = sp->p; - for (; nm; nm--, pm--) { - int i = pm->i; // particle index we are removing - p0[i].i >>= 3; // shift particle voxel down - // accumulate the particle's charge to the mesh - accumulate_rhob(mflds, p0 + i, sp->q); - p0[i] = p0[sp->np - 1]; // put the last particle into position i - sp->np--; // decrement the number of particles - } - sp->nm = 0; - } - } - - static void uncenter_p(species_t* sp, - /*const*/ MfieldsInterpolator& interpolator) - { - ::uncenter_p(sp, interpolator.getPatch(0).ip()); - } - - static void sort_p(species_t* sp) { ::sort_p(sp); } - - static double energy_p(typename Mparticles::ConstSpeciesIterator sp, - const MfieldsInterpolator& interpolator) - { - return ::energy_p(&*sp, &interpolator); - } -}; From ddba44ade0e4fb8918541c69b6092a6681209c29 Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 09:45:32 -0500 Subject: [PATCH 10/46] -bnd_vpic --- src/libpsc/vpic/bnd_vpic.hxx | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 src/libpsc/vpic/bnd_vpic.hxx diff --git a/src/libpsc/vpic/bnd_vpic.hxx b/src/libpsc/vpic/bnd_vpic.hxx deleted file mode 100644 index 79fb16b6b8..0000000000 --- a/src/libpsc/vpic/bnd_vpic.hxx +++ /dev/null @@ -1,13 +0,0 @@ - -#pragma once - -#include "bnd.hxx" - -template -struct BndVpic : BndBase -{ - BndVpic() {} - - void fill_ghosts(MfieldsState& mflds, int mb, int me) {} - void add_ghosts(MfieldsState& mflds, int mb, int me) {} -}; From 4078a7ea5e00640c449b0f74a029b6ceb7b00dca Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 09:54:22 -0500 Subject: [PATCH 11/46] test_mparticles: rm vpic stuff --- src/libpsc/tests/test_mparticles.cxx | 66 ++++------------------------ 1 file changed, 9 insertions(+), 57 deletions(-) diff --git a/src/libpsc/tests/test_mparticles.cxx b/src/libpsc/tests/test_mparticles.cxx index c98b38b66b..adb65ffb67 100644 --- a/src/libpsc/tests/test_mparticles.cxx +++ b/src/libpsc/tests/test_mparticles.cxx @@ -4,11 +4,6 @@ #include "test_common.hxx" -#include "../libpsc/vpic/PscGridBase.h" -#include "../libpsc/vpic/PscParticleBc.h" -#include "../libpsc/vpic/PscParticlesBase.h" -#include "../libpsc/vpic/mparticles_vpic.hxx" -#include "../libpsc/vpic/vpic_config.h" #include "../libpsc/psc_output_fields/fields_item_moments_1st.hxx" #include "psc_particles_double.h" #include "psc_particles_single.h" @@ -21,15 +16,6 @@ #include "particles_simple.inl" #include -#ifdef DO_VPIC -using VpicConfig = VpicConfigWrap; -#else -using VpicConfig = VpicConfigPsc; -#endif - -using Grid = VpicConfig::Grid; -using MparticlesVpic = VpicConfig::Mparticles; - template struct Config { @@ -37,15 +23,16 @@ struct Config using MakeGrid = _MakeGrid; }; -using MparticlesTestTypes = ::testing::Types< - Config, Config, - Config, Config +using MparticlesTestTypes = + ::testing::Types, + Config, + Config #ifdef USE_CUDA - , - Config, MakeTestGridYZ1>, - Config, MakeTestGridYZ> + , + Config, MakeTestGridYZ1>, + Config, MakeTestGridYZ> #endif - >; + >; TYPED_TEST_SUITE(MparticlesTest, MparticlesTestTypes); @@ -64,38 +51,13 @@ struct MparticlesTest : ::testing::Test grid_.kinds.emplace_back(Grid_t::Kind(1., 1., "test_species")); } - template - Mparticles mk_mprts(tag dummy) + Mparticles mk_mprts() { Mparticles mprts(grid_); mprts.define_species("test_species", 1., 1., 100, 10, 10, 0); return mprts; } - Mparticles mk_mprts(MparticlesVpic* dummy) - { - // FIXME, vgrid_ is bad, and this kinda belongs to where grid_ is set up - - // Setup basic grid parameters - auto& domain = grid_.domain; - double dx[3], xl[3], xh[3]; - for (int d = 0; d < 3; d++) { - dx[d] = domain.length[d] / domain.gdims[d]; - xl[d] = domain.corner[d]; - xh[d] = xl[d] + domain.length[d]; - } - vgrid_.setup(dx, grid_.dt, 1., 1.); - - // Define the grid - vgrid_.partition_periodic_box(xl, xh, domain.gdims, domain.np); - - Mparticles mprts(grid_, &vgrid_); - mprts.define_species("test_species", 1., 1., 100, 10, 10, 0); - return mprts; - } - - Mparticles mk_mprts() { return mk_mprts(static_cast(nullptr)); } - template void inject_test_particles(_Mparticles& mprts, int n_prts) { @@ -121,7 +83,6 @@ struct MparticlesTest : ::testing::Test private: Grid_t grid_; - Grid vgrid_; // FIXME }; // ----------------------------------------------------------------------- @@ -349,15 +310,6 @@ struct TestConversionFromMparticlesSingle } }; -// FIXME, MparticlesVpic can't be converted the usual way... -template <> -struct TestConversionFromMparticlesSingle -{ - using Double3 = Vec3; - - void operator()(MparticlesSingle& mprts_single) {} -}; - TYPED_TEST(MparticlesTest, ConversionFromMparticlesSingle) { MparticlesSingle mprts(this->grid()); From f033fb35952dfa3352a60cfc4aa5cc8389ef1b58 Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 10:12:11 -0500 Subject: [PATCH 12/46] testing; *: -vpic stuff --- src/libpsc/tests/test_push_particles_2.cxx | 22 ++++++++-------------- src/libpsc/tests/testing.hxx | 5 ----- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/src/libpsc/tests/test_push_particles_2.cxx b/src/libpsc/tests/test_push_particles_2.cxx index ac5d300cb1..90f4335598 100644 --- a/src/libpsc/tests/test_push_particles_2.cxx +++ b/src/libpsc/tests/test_push_particles_2.cxx @@ -2,6 +2,7 @@ #include "gtest/gtest.h" #include "testing.hxx" +#include "rng.hxx" using PushParticlesTestTypes = ::testing::TypesL}; Mparticles mprts{grid}; { @@ -57,11 +58,7 @@ TYPED_TEST(PushParticlesTest, Accel) for (int p = 0; p < grid.n_patches(); p++) { auto injector = inj[p]; for (int n = 0; n < n_prts; n++) { - injector({{rng->uniform(0, this->L), rng->uniform(0, this->L), - rng->uniform(0, this->L)}, - {}, - 1., - 0}); + injector({{dist.get(), dist.get(), dist.get()}, {}, 1., 0}); } } } @@ -126,8 +123,8 @@ TYPED_TEST(PushParticlesTest, Cyclo) }); // init particles - RngPool rngpool; - Rng* rng = rngpool[0]; + rng::Uniform dist{0.0, this->L}; + rng::Uniform dist2{0.0, 1.0}; Mparticles mprts{grid}; { @@ -135,11 +132,8 @@ TYPED_TEST(PushParticlesTest, Cyclo) for (int p = 0; p < grid.n_patches(); p++) { auto injector = inj[p]; for (int n = 0; n < n_prts; n++) { - injector({{rng->uniform(0, this->L), rng->uniform(0, this->L), - rng->uniform(0, this->L)}, - {1., 1., 1.}, - rng->uniform(0., 1.), - 0}); + injector( + {{dist.get(), dist.get(), dist.get()}, {1., 1., 1.}, dist2.get(), 0}); } } } diff --git a/src/libpsc/tests/testing.hxx b/src/libpsc/tests/testing.hxx index 1922b34cd7..502ed65ac4 100644 --- a/src/libpsc/tests/testing.hxx +++ b/src/libpsc/tests/testing.hxx @@ -29,11 +29,6 @@ // ====================================================================== // Rng hackiness -#include "../vpic/PscRng.h" - -using Rng = PscRng; -using RngPool = PscRngPool; - // ====================================================================== // TestConfig From 0632fcbd86efb7cf2e66d2d43147d946e7952231 Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 10:13:31 -0500 Subject: [PATCH 13/46] -push_particles_vpic --- src/libpsc/vpic/push_particles_vpic.hxx | 119 ------------------------ 1 file changed, 119 deletions(-) delete mode 100644 src/libpsc/vpic/push_particles_vpic.hxx diff --git a/src/libpsc/vpic/push_particles_vpic.hxx b/src/libpsc/vpic/push_particles_vpic.hxx deleted file mode 100644 index 1adbed85ef..0000000000 --- a/src/libpsc/vpic/push_particles_vpic.hxx +++ /dev/null @@ -1,119 +0,0 @@ - -#pragma once - -#include "push_particles.hxx" -#include "vpic_iface.h" - -// ====================================================================== -// PushParticlesVpic - -template -struct PushParticlesVpic : PushParticlesBase -{ - using Mparticles = _Mparticles; - using MfieldsState = _MfieldsState; - using ParticlesOps = _ParticlesOps; - using AccumulateOps = _AccumulateOps; - using AccumulatorOps = _AccumulatorOps; - using InterpolatorOps = _InterpolatorOps; - using ParticleBcList = typename Mparticles::ParticleBcList; - using MfieldsInterpolator = typename InterpolatorOps::MfieldsInterpolator; - using MfieldsAccumulator = typename AccumulatorOps::MfieldsAccumulator; - - void push_mprts(Mparticles& mprts, MfieldsState& mflds, - MfieldsInterpolator& interpolator, - MfieldsAccumulator& accumulator, - ParticleBcList& particle_bc_list, int num_comm_round) - { - // For this to work, interpolator needs to have been set from mflds E/B - // before, ie., we're not using mflds for E and B here at all. - - // At this point, fields are at E_0 and B_0 and the particle positions - // are at r_0 and u_{-1/2}. Further the mover lists for the particles - // should empty and all particles should be inside the local computational - // domain. Advance the particle lists. - if (!mprts.empty()) { - TIC AccumulatorOps::clear(accumulator); - TOC(clear_accumulators, 1); - ParticlesOps::advance_p(mprts, accumulator, interpolator); - } - - // Because the partial position push when injecting aged particles might - // place those particles onto the guard list (boundary interaction) and - // because advance_p requires an empty guard list, particle injection must - // be done after advance_p and before guard list processing. Note: - // user_particle_injection should be a stub if sl_ is empty. -#if 0 - if (emitter_list) { - TIC ::apply_emitter_list(emitter_list); TOC(emission_model, 1); - } - TIC user_particle_injection(); TOC(user_particle_injection, 1); -#endif - - // This should be after the emission and injection to allow for the - // possibility of thread parallelizing these operations - if (!mprts.empty()) { - TIC AccumulatorOps::reduce(accumulator); - TOC(reduce_accumulators, 1); - } - - // At this point, most particle positions are at r_1 and u_{1/2}. Particles - // that had boundary interactions are now on the guard list. Process the - // guard lists. Particles that absorbed are added to rhob (using a corrected - // local accumulation). - TIC for (int round = 0; round < num_comm_round; round++) - { - ParticlesOps::boundary_p(particle_bc_list, mprts, mflds, accumulator); - } - TOC(boundary_p, num_comm_round); - - // Drop the particles that have unprocessed movers at this point - ParticlesOps::drop_p(mprts, mflds); - - // At this point, all particle positions are at r_1 and u_{1/2}, the - // guard lists are empty and the accumulators on each processor are current. - // Convert the accumulators into currents. - TIC AccumulateOps::clear_jf(mflds); - TOC(clear_jf, 1); - if (!mprts.empty()) { - TIC AccumulatorOps::unload(accumulator, mflds); - TOC(unload_accumulator, 1); - } - TIC AccumulateOps::synchronize_jf(mflds); - TOC(synchronize_jf, 1); - - // At this point, the particle currents are known at jf_{1/2}. - // Let the user add their own current contributions. It is the users - // responsibility to insure injected currents are consistent across domains. - // It is also the users responsibility to update rhob according to - // rhob_1 = rhob_0 + div juser_{1/2} (corrected local accumulation) if - // the user wants electric field divergence cleaning to work. -#if 0 - TIC user_current_injection(); TOC(user_current_injection, 1); -#endif - } - - void load_interpolator(Mparticles& mprts, MfieldsState& mflds, - MfieldsInterpolator& interpolator) - { - // At end of step: - // Fields are updated ... load the interpolator for next time step and - // particle diagnostics in user_diagnostics if there are any particle - // species to worry about - - if (!mprts.empty()) { - TIC InterpolatorOps::load(interpolator, mflds); - TOC(load_interpolator, 1); - } - } - - void uncenter(Mparticles& mprts, MfieldsInterpolator& interpolator) - { - for (auto& sp : mprts[0]) { - TIC ParticlesOps::uncenter_p(&sp, interpolator); - TOC(uncenter_p, 1); - } - } -}; From 0c1decd63b0173c28151fbb4cc40d4c0864ff5cf Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 10:14:07 -0500 Subject: [PATCH 14/46] -push_fields_vpic --- src/libpsc/vpic/push_fields_vpic.hxx | 248 --------------------------- 1 file changed, 248 deletions(-) delete mode 100644 src/libpsc/vpic/push_fields_vpic.hxx diff --git a/src/libpsc/vpic/push_fields_vpic.hxx b/src/libpsc/vpic/push_fields_vpic.hxx deleted file mode 100644 index 0ddfc9d460..0000000000 --- a/src/libpsc/vpic/push_fields_vpic.hxx +++ /dev/null @@ -1,248 +0,0 @@ - -#pragma once - -#include "push_fields.hxx" -#include "vpic_iface.h" - -#ifdef USE_VPIC - -// ====================================================================== -// PushFieldsVpicWrap - -template -struct PushFieldsVpicWrap -{ - void push_E(MfieldsState& mflds, double dt_fac) - { - field_array_t* fa = mflds; - TIC return fa->kernel->advance_e(fa, dt_fac); - TOC(advance_e, 1); -#if 0 - user_field_injection(); -#endif - } - - void push_H(MfieldsState& mflds, double dt_fac) - { - field_array_t* fa = mflds; - TIC return fa->kernel->advance_b(fa, dt_fac); - TOC(advance_b, 1); - } -}; - -#endif - -// ====================================================================== -// PushFieldsVpic - -template -struct PushFieldsVpic -{ - using LocalOps = PscFieldArrayLocalOps; - using RemoteOps = PscFieldArrayRemoteOps; - using Grid = typename MfieldsState::Grid; - using SfaParams = typename MfieldsState::SfaParams; - using MaterialCoefficient = typename MfieldsState::MaterialCoefficient; - using F3D = Field3D; - - void push_E(MfieldsState& mflds, double dt_fac) - { - TIC advance_e(mflds, dt_fac); - TOC(advance_e, 1); -#if 0 - user_field_injection(); -#endif - } - - void push_H(MfieldsState& mflds, double dt_fac) - { - TIC advance_b(mflds, dt_fac); - TOC(advance_b, 1); - } - -private: - // FIXME, uses enum-based components vs struct-based components, should - // settle on one or the other - - // ---------------------------------------------------------------------- - // advance_b - -#define CBX MfieldsState::CBX -#define CBY MfieldsState::CBY -#define CBZ MfieldsState::CBZ -#define EX MfieldsState::EX -#define EY MfieldsState::EY -#define EZ MfieldsState::EZ - -#define UPDATE_CBX() \ - F(CBX, i, j, k) -= (py * (F(EZ, i, j + 1, k) - F(EZ, i, j, k)) - \ - pz * (F(EY, i, j, k + 1) - F(EY, i, j, k))) -#define UPDATE_CBY() \ - F(CBY, i, j, k) -= (pz * (F(EX, i, j, k + 1) - F(EX, i, j, k)) - \ - px * (F(EZ, i + 1, j, k) - F(EZ, i, j, k))) -#define UPDATE_CBZ() \ - F(CBZ, i, j, k) -= (px * (F(EY, i + 1, j, k) - F(EY, i, j, k)) - \ - py * (F(EX, i, j + 1, k) - F(EX, i, j, k))) - - static void advance_b(MfieldsState& mflds, double frac) - { - const auto& g = mflds.vgrid(); - auto& fa = mflds.getPatch(0); - F3D F(fa); - int nx = g.nx, ny = g.ny, nz = g.nz; - - // FIXME, invariant should be based on global dims - const float px = (nx > 1) ? frac * g.cvac * g.dt * g.rdx : 0; - const float py = (ny > 1) ? frac * g.cvac * g.dt * g.rdy : 0; - const float pz = (nz > 1) ? frac * g.cvac * g.dt * g.rdz : 0; - - // bulk - for (int k = 1; k <= nz; k++) { - for (int j = 1; j <= ny; j++) { - for (int i = 1; i <= nx; i++) { - UPDATE_CBX(); - UPDATE_CBY(); - UPDATE_CBZ(); - } - } - } - - // leftover bx - { - int i = nx + 1; - for (int k = 1; k <= nz; k++) { - for (int j = 1; j <= ny; j++) { - UPDATE_CBX(); - } - } - } - - // leftover by - { - int j = ny + 1; - for (int k = 1; k <= nz; k++) { - for (int i = 1; i <= nx; i++) { - UPDATE_CBY(); - } - } - } - - // leftover bz - { - int k = nz + 1; - for (int j = 1; j <= ny; j++) { - for (int i = 1; i <= nx; i++) { - UPDATE_CBZ(); - } - } - } - - LocalOps::local_adjust_norm_b(mflds); - } - -#undef CBX -#undef CBY -#undef CBZ -#undef EX -#undef EY -#undef EZ - - // ---------------------------------------------------------------------- - // vacuum_advance_e - - static void vacuum_advance_e(MfieldsState& mflds, double frac) - { - // Update interior fields - // Note: ex all (1:nx, 1:ny+1,1,nz+1) interior (1:nx,2:ny,2:nz) - // Note: ey all (1:nx+1,1:ny, 1:nz+1) interior (2:nx,1:ny,2:nz) - // Note: ez all (1:nx+1,1:ny+1,1:nz ) interior (1:nx,1:ny,2:nz) - - struct AdvanceE - { - AdvanceE(typename MfieldsState::Patch& fa, const Grid* g, - const MaterialCoefficient* m, const double damp_) - : F(fa), - decayx(m->decayx), - decayy(m->decayy), - decayz(m->decayz), - drivex(m->drivex), - drivey(m->drivey), - drivez(m->drivez), - px_muz(g->nx > 1 ? (1 + damp_) * g->cvac * g->dt * g->rdx * m->rmuz - : 0), - px_muy(g->nx > 1 ? (1 + damp_) * g->cvac * g->dt * g->rdx * m->rmuy - : 0), - py_mux(g->ny > 1 ? (1 + damp_) * g->cvac * g->dt * g->rdy * m->rmux - : 0), - py_muz(g->ny > 1 ? (1 + damp_) * g->cvac * g->dt * g->rdy * m->rmuz - : 0), - pz_muy(g->nz > 1 ? (1 + damp_) * g->cvac * g->dt * g->rdz * m->rmuy - : 0), - pz_mux(g->nz > 1 ? (1 + damp_) * g->cvac * g->dt * g->rdz * m->rmux - : 0), - damp(damp_), - cj(g->dt / g->eps0) - {} - - void x(int i, int j, int k) - { - F(i, j, k).tcax = ((py_muz * (F(i, j, k).cbz - F(i, j - 1, k).cbz) - - pz_muy * (F(i, j, k).cby - F(i, j, k - 1).cby)) - - damp * F(i, j, k).tcax); - F(i, j, k).ex = decayx * F(i, j, k).ex + - drivex * (F(i, j, k).tcax - cj * F(i, j, k).jfx); - } - - void y(int i, int j, int k) - { - F(i, j, k).tcay = ((pz_mux * (F(i, j, k).cbx - F(i, j, k - 1).cbx) - - px_muz * (F(i, j, k).cbz - F(i - 1, j, k).cbz)) - - damp * F(i, j, k).tcay); - F(i, j, k).ey = decayy * F(i, j, k).ey + - drivey * (F(i, j, k).tcay - cj * F(i, j, k).jfy); - } - - void z(int i, int j, int k) - { - F(i, j, k).tcaz = ((px_muy * (F(i, j, k).cby - F(i - 1, j, k).cby) - - py_mux * (F(i, j, k).cbx - F(i, j - 1, k).cbx)) - - damp * F(i, j, k).tcaz); - F(i, j, k).ez = decayz * F(i, j, k).ez + - drivez * (F(i, j, k).tcaz - cj * F(i, j, k).jfz); - } - - Field3D F; - const float decayx, decayy, decayz, drivex, drivey, drivez; - const float px_muz, px_muy, py_mux, py_muz, pz_muy, pz_mux; - const float damp, cj; - }; - - auto& fa = mflds.getPatch(0); - assert(frac == 1.); - - SfaParams& prm = mflds.params(); - assert(prm.size() == 1); - const MaterialCoefficient* m = prm[0]; - - AdvanceE advanceE(fa, &mflds.vgrid(), m, prm.damp); - - RemoteOps::begin_remote_ghost_tang_b(mflds); - - LocalOps::local_ghost_tang_b(mflds); - foreach_ec_interior(advanceE, mflds.vgrid()); - - RemoteOps::end_remote_ghost_tang_b(mflds); - - foreach_ec_boundary(advanceE, mflds.vgrid()); - LocalOps::local_adjust_tang_e(mflds); - } - - // ---------------------------------------------------------------------- - // advance_e - - static void advance_e(MfieldsState& mflds, double frac) - { - // FIXME vacuum hardcoded - return vacuum_advance_e(mflds, frac); - } -}; From 790cc54c8c200f5578cea7cf6f338aa493bff4af Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 10:19:25 -0500 Subject: [PATCH 15/46] -psc_particles_vpic; cmake --- src/libpsc/CMakeLists.txt | 1 - src/libpsc/vpic/psc_particles_vpic.cxx | 118 ------------------------- 2 files changed, 119 deletions(-) delete mode 100644 src/libpsc/vpic/psc_particles_vpic.cxx diff --git a/src/libpsc/CMakeLists.txt b/src/libpsc/CMakeLists.txt index cb99ac68eb..c2c6433f62 100644 --- a/src/libpsc/CMakeLists.txt +++ b/src/libpsc/CMakeLists.txt @@ -16,7 +16,6 @@ target_gtensor_sources(psc PRIVATE psc_balance/psc_balance.cxx - vpic/psc_particles_vpic.cxx vpic/psc_fields_vpic.cxx vpic/psc_vpic_bits.cxx vpic/vpic_base.cxx diff --git a/src/libpsc/vpic/psc_particles_vpic.cxx b/src/libpsc/vpic/psc_particles_vpic.cxx deleted file mode 100644 index ddca96e932..0000000000 --- a/src/libpsc/vpic/psc_particles_vpic.cxx +++ /dev/null @@ -1,118 +0,0 @@ - -#include "vpic_iface.h" - -#include - -#ifdef DO_VPIC -using VpicConfig = VpicConfigWrap; -#else -using VpicConfig = VpicConfigPsc; -#endif - -using Grid = VpicConfig::Grid; -using MparticlesVpic = VpicConfig::Mparticles; - -// ====================================================================== -// conversion - -template -void copy_to(MparticlesBase& mprts_from_base, MparticlesBase& mprts_to_base) -{ - auto& mprts_from = dynamic_cast(mprts_from_base); - auto& mprts_to = dynamic_cast(mprts_to_base); - auto& vgrid = mprts_from.vgrid(); - int im[3] = {vgrid.nx + 2, vgrid.ny + 2, vgrid.nz + 2}; - float dx[3] = {vgrid.dx, vgrid.dy, vgrid.dz}; - float dVi = 1.f / (dx[0] * dx[1] * dx[2]); // FIXME, vgrid->dVi? - - auto n_prts_by_patch = mprts_from.sizeByPatch(); - mprts_to.reserve_all(n_prts_by_patch); - mprts_to.clear(); - - for (int p = 0; p < mprts_to.n_patches(); p++) { - int n_prts = n_prts_by_patch[p]; - - auto prts_from = mprts_from[p]; - for (auto sp = prts_from.cbegin(); sp != prts_from.cend(); ++sp) { - assert(sp->id < mprts_to.grid().kinds.size()); - - for (unsigned int n = 0; n < sp->np; n++) { - auto& vprt = sp->p[n]; - int i = vprt.i; - int i3[3]; - i3[2] = i / (im[0] * im[1]); - i -= i3[2] * (im[0] * im[1]); - i3[1] = i / im[0]; - i -= i3[1] * im[0]; - i3[0] = i; - auto x = Vec3{(i3[0] - 1 + .5f * (1.f + vprt.dx)) * dx[0], - (i3[1] - 1 + .5f * (1.f + vprt.dy)) * dx[1], - (i3[2] - 1 + .5f * (1.f + vprt.dz)) * dx[2]}; - auto u = Vec3{vprt.ux, vprt.uy, vprt.uz}; - auto kind = sp->id; - auto qni_wni = - float(vprt.w * dVi) * float(mprts_to.grid().kinds[kind].q); - mprts_to.push_back( - p, {x, u, qni_wni, kind, psc::particle::Id{}, psc::particle::Tag{}}); - } - } - } -} - -template -void copy_from(MparticlesBase& mprts_to_base, MparticlesBase& mprts_from_base) -{ - auto& mprts_to = dynamic_cast(mprts_to_base); - auto& mprts_from = dynamic_cast(mprts_from_base); - auto& vgrid = mprts_to.vgrid(); - int im[3] = {vgrid.nx + 2, vgrid.ny + 2, vgrid.nz + 2}; - float dx[3] = {vgrid.dx, vgrid.dy, vgrid.dz}; - float dVi = 1.f / (dx[0] * dx[1] * dx[2]); // FIXME, vgrid->dVi? - - mprts_to.reset(); - mprts_to.reserve_all(mprts_from.sizeByPatch()); - - auto accessor_from = mprts_from.accessor(); - for (int p = 0; p < mprts_to.n_patches(); p++) { - auto prts_from = accessor_from[p]; - - int n_prts = prts_from.size(); - for (auto prt_from : prts_from) { - assert(prt_from.kind() < mprts_to.grid().kinds.size()); - - int i3[3]; - float dx[3]; - for (int d = 0; d < 3; d++) { - float val = prt_from.x()[d] / dx[d]; - i3[d] = (int)val; - // mprintf("d %d val %g xi %g\n", d, val, prt_from.xi); - assert(i3[d] >= -1 && i3[d] < im[d] + 1); - dx[d] = (val - i3[d]) * 2.f - 1.f; - i3[d] += 1; - } - typename MparticlesVpic::Particle prt; - prt.dx = dx[0]; - prt.dy = dx[1]; - prt.dz = dx[2]; - prt.i = (i3[2] * im[1] + i3[1]) * im[0] + i3[0]; - prt.ux = prt_from.u()[0]; - prt.uy = prt_from.u()[1]; - prt.uz = prt_from.u()[2]; - prt.w = prt_from.w() / dVi; - mprts_to.push_back(prt_from.kind(), prt); - } - } -} - -// ---------------------------------------------------------------------- -// psc_mparticles_vpic_methods - -template <> -const MparticlesVpic::Convert MparticlesVpic::convert_to_ = { - {std::type_index(typeid(MparticlesSingle)), copy_to}, -}; - -template <> -const MparticlesVpic::Convert MparticlesVpic::convert_from_ = { - {std::type_index(typeid(MparticlesSingle)), copy_from}, -}; From 687fe53a48f3c9e7379e14195e86ac6830841a19 Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 10:20:10 -0500 Subject: [PATCH 16/46] -psc_particles_vpic, psc_fields_vpic --- src/libpsc/CMakeLists.txt | 1 - src/libpsc/vpic/psc_fields_vpic.cxx | 88 ----------------------------- 2 files changed, 89 deletions(-) delete mode 100644 src/libpsc/vpic/psc_fields_vpic.cxx diff --git a/src/libpsc/CMakeLists.txt b/src/libpsc/CMakeLists.txt index c2c6433f62..2d6736b1ef 100644 --- a/src/libpsc/CMakeLists.txt +++ b/src/libpsc/CMakeLists.txt @@ -16,7 +16,6 @@ target_gtensor_sources(psc PRIVATE psc_balance/psc_balance.cxx - vpic/psc_fields_vpic.cxx vpic/psc_vpic_bits.cxx vpic/vpic_base.cxx ) diff --git a/src/libpsc/vpic/psc_fields_vpic.cxx b/src/libpsc/vpic/psc_fields_vpic.cxx deleted file mode 100644 index f32d0bbe11..0000000000 --- a/src/libpsc/vpic/psc_fields_vpic.cxx +++ /dev/null @@ -1,88 +0,0 @@ - -#include "psc_fields_c.h" -#include "psc_fields_single.h" -#include "psc.h" -#include "fields.hxx" - -#include "mrc_domain.h" -#include "mrc_bits.h" - -#include "vpic_iface.h" - -#if 0 - -static const int map_psc2vpic[MfieldsStateVpic::N_COMP] = { - [JXI] = MfieldsStateVpic::JFX, [JYI] = MfieldsStateVpic::JFY, [JZI] = MfieldsStateVpic::JFZ, - [EX] = MfieldsStateVpic::EX , [EY] = MfieldsStateVpic::EY , [EZ] = MfieldsStateVpic::EZ, - [HX] = MfieldsStateVpic::BX , [HY] = MfieldsStateVpic::BY , [HZ] = MfieldsStateVpic::BZ, - - [9] = MfieldsStateVpic::TCAX, [10] = MfieldsStateVpic::TCAY, [11] = MfieldsStateVpic::TCAZ, - [12] = MfieldsStateVpic::DIV_E_ERR, [13] = MfieldsStateVpic::DIV_B_ERR, - [14] = MfieldsStateVpic::RHOB , [15] = MfieldsStateVpic::RHOF, - [16] = 16, [17] = 17, [18] = 18, [19] = 19, -}; - -// ====================================================================== -// convert from/to "single" - -static void MfieldsStateVpic_copy_from_single(MfieldsStateBase& mflds, MfieldsStateBase& mflds_single, int mb, int me) -{ - auto& mf_single = dynamic_cast(mflds_single); - auto& mf = dynamic_cast(mflds); - for (int p = 0; p < mf.n_patches(); p++) { - fields_vpic_t flds = mf[p]; - auto F_s = mf_single[p]; - - assert(mf.n_comps() == MfieldsStateVpic::N_COMP); - for (int m = mb; m < me; m++) { - int m_vpic = map_psc2vpic[m]; - for (int jz = flds.ib_[2]; jz < flds.ib_[2] + flds.im_[2]; jz++) { - for (int jy = flds.ib_[1]; jy < flds.ib_[1] + flds.im_[1]; jy++) { - for (int jx = flds.ib_[0]; jx < flds.ib_[0] + flds.im_[0]; jx++) { - flds(m_vpic, jx,jy,jz) = F_s(m, jx,jy,jz); - } - } - } - } - } -} - -static void MfieldsStateVpic_copy_to_single(MfieldsStateBase& mflds, MfieldsStateBase& mflds_single, int mb, int me) -{ - auto& mf_single = dynamic_cast(mflds_single); - auto& mf = dynamic_cast(mflds); - for (int p = 0; p < mf.n_patches(); p++) { - fields_vpic_t flds = mf[p]; - auto flds_single = mf_single[p]; - - int ib[3], ie[3]; - for (int d = 0; d < 3; d++) { - ib[d] = MAX(flds.ib_[d], flds_single.ib_[d]); - ie[d] = MIN(flds.ib_[d] + flds.im_[d], flds_single.ib_[d] + flds_single.im_[d]); - } - - assert(mf.n_comps() == MfieldsStateVpic::N_COMP); - for (int m = mb; m < me; m++) { - int m_vpic = map_psc2vpic[m]; - for (int jz = ib[2]; jz < ie[2]; jz++) { - for (int jy = ib[1]; jy < ie[1]; jy++) { - for (int jx = ib[0]; jx < ie[0]; jx++) { - flds_single(m, jx,jy,jz) = flds(m_vpic, jx,jy,jz); - } - } - } - } - } -} - -// ====================================================================== - -const MfieldsStateBase::Convert MfieldsStateVpic::convert_to_ = { - { std::type_index(typeid(MfieldsStateSingle)), MfieldsStateVpic_copy_to_single }, -}; - -const MfieldsStateBase::Convert MfieldsStateVpic::convert_from_ = { - { std::type_index(typeid(MfieldsStateSingle)), MfieldsStateVpic_copy_from_single }, -}; - -#endif From 911247461a38111abe0c07dd61cb4d21d0bff088 Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 10:24:18 -0500 Subject: [PATCH 17/46] -deck, wrapper* --- src/libpsc/vpic/deck.cxx | 1078 ----------------------------- src/libpsc/vpic/wrapper.cxx | 4 - src/libpsc/vpic/wrapper_empty.cxx | 28 - src/libpsc/vpic/wrapper_split.cxx | 4 - 4 files changed, 1114 deletions(-) delete mode 100644 src/libpsc/vpic/deck.cxx delete mode 100644 src/libpsc/vpic/wrapper.cxx delete mode 100644 src/libpsc/vpic/wrapper_empty.cxx delete mode 100644 src/libpsc/vpic/wrapper_split.cxx diff --git a/src/libpsc/vpic/deck.cxx b/src/libpsc/vpic/deck.cxx deleted file mode 100644 index 3cf4037f68..0000000000 --- a/src/libpsc/vpic/deck.cxx +++ /dev/null @@ -1,1078 +0,0 @@ -////////////////////////////////////////////////////// -// -// Harris Sheet Reconnection - Open Boundary Model -// -////////////////////////////////////////////////////// - -////////////////////////////////////////////////////// - -// structure to hold the data for energy diagnostics -struct edata -{ - species_id sp_id; /* species id */ - double vth; /* thermal energy */ - char fname[256]; /* file to save data */ -}; - -begin_globals -{ - - int restart_interval; - int energies_interval; - int fields_interval; - int ehydro_interval; - int Hhydro_interval; - int eparticle_interval; - int Hparticle_interval; - int quota_check_interval; // How frequently to check if quota exceeded - - int rtoggle; // enables save of last 2 restart dumps for safety - double quota_sec; // Run quota in seconds - double b0; // B0 - double bg; // Guide field - double v_A; - double topology_x; // domain topology - double topology_y; - double topology_z; - - // parameters for the collision model - int ee_collisions; // Flag to signal we want to do e-e collisions. - int ei_collisions; // Flag to signal we want to do e-i collisions. - int ii_collisions; // Flag to signal we want to do i-i collisions. - - double cvar; // Base variance (dimensionless) used in particle collision - double nppc_max; // Max number of particles/cell (used to def key array size). - int tstep_coll; // Collision interval (=multiple of sort interval). - double Z; - double mi_me; - double wpewce; - - // Variables for Open BC Model - int open_bc_x; // Flag to signal we want to do open boundary condition in x - int - driven_bc_z; // Flag to signal we want to do driven boundary condition in z - double nb; // Background density - int nsp; // Number of Species - double vth[2]; // Thermal velocity of Harris components - double vthb[2]; // Thermal velocity of background components - double q[2]; // Species charge - double L_de; // Initial Harris sheet thickness - double uf[2]; // Initial Fluid Drift in Harris - double nfac; // Normalization factor to convert particles per cell to density - double rin[3]; // Relaxation parameter for inflow boundary moments - double rout[3]; // Relaxation parameter for outlfow boundary moments - double sort[2]; // Intervals where we know particles are sorted - double edrive; // Drive field for inflow boundary - double tdrive; - int left, right, top, bottom; // Keep track of boundary domains - // Moments for bottom injectors - double *nbot, *ubot, *pbot, *bbot, *fbot; - // Moments for top injectors - double *ntop, *utop, *ptop, *btop, *ftop; - // Moments for left injectors - double *nleft, *uleft, *pleft, *bleft, *fleft; - // Moments for right injectors - double *nright, *uright, *pright, *bright, *fright; - - // Output variables - DumpParameters fdParams; - DumpParameters hedParams; - DumpParameters hHdParams; - std::vector outputParams; - - // Variables for the energy diagnostics - edata ede; // parameters for electron species - edata edi; // parameters for ion species - double emax; // maximum energy (in units of me*c**2) - int nex; // number of energy bins - - // Vadim: modified restart machinary - int write_restart; // global flag for all to write restart files - int write_end_restart; // global flag for all to write restart files -}; - -begin_initialization -{ - // use natural PIC units - double ec = 1; // Charge normalization - double me = 1; // Mass normalization - double c = 1; // Speed of light - double de = 1; // Length normalization (electron inertial length) - double eps0 = 1; // Permittivity of space - - double cfl_req = 0.99; // How close to Courant should we try to run - double wpedt_max = 0.36; // Max dt allowed if Courant not too restrictive - double damp = 0.0; // Level of radiation damping - int rng_seed = 1; // Random number seed increment - - // Physics parameters - double mi_me = 25.0; // Ion mass / electron mass - double L_di = 0.5; // Sheet thickness / ion inertial length - double Ti_Te = 5.0; // Ion temperature / electron temperature - double Z = 1.0; // Ion charge - double nb_n0 = 0.228; // background plasma density - double Tbe_Te = 0.7598; // Ratio of background T_e to Harris T_e - double Tbi_Ti = 0.3039; // Ratio of background T_i to Harris T_i - double wpe_wce = 2.0; // electron plasma freq / electron cyclotron freq - double bg = 0.0; - double theta = 0; // B0 = Bx - double taui = 1.1; // 100; // simulation wci's to run - - double Lpert_Lx = 1.; // wavelength of perturbation in terms of Lx - double dbz_b0 = 0.03; // perturbation in Bz relative to B0 - - int restart_interval = 8000; - double t_intervali = 1; // output interval in terms of 1/wci - - double quota = 11.0; // run quota in hours - double quota_sec = quota * 3600; // Run quota in seconds - - double cs = cos(theta); - double sn = sin(theta); - - // derived qunatities - double mi = me * mi_me; // Ion mass - double Te = - me * c * c / - (2 * eps0 * wpe_wce * wpe_wce * (1 + Ti_Te)); // Electron temperature - double Ti = Te * Ti_Te; // Ion temperature - double vthe = sqrt(Te / me); // Electron thermal velocity - double vthi = sqrt(Ti / mi); // Ion thermal velocity - double vtheb = sqrt(Tbe_Te * Te / me); // normalized background e thermal vel. - double vthib = - sqrt(Tbi_Ti * Ti / mi); // normalized background ion thermal vel. - double wci = 1.0 / (mi_me * wpe_wce); // Ion cyclotron frequency - double wce = wci * mi_me; // Electron cyclotron freqeuncy - double wpe = wce * wpe_wce; // electron plasma frequency - double wpi = wpe / sqrt(mi_me); // ion plasma frequency - double di = c / wpi; // ion inertial length - double L = L_di * di; // Harris sheet thickness - double rhoi_L = sqrt(Ti_Te / (1.0 + Ti_Te)) / L_di; - double v_A = (wci / wpi) / sqrt(nb_n0); // based on nb - - double ion_sort_interval = 1000; // Injector moments also updated - double electron_sort_interval = 1000; // Injector moments also updated - - // Parameters for Open BC model - // Relaxation - density, velocity + particle flux, pressure tensor - int open_bc_x = 0; - int driven_bc_z = 0; - double rin[3] = {0.000, 0.06, 0.000}; - double rout[3] = {0.002, 0.002, 0.002}; - double edrive = 0.08 * v_A / (wpe_wce); // edrive = 0 gives undriven limit - // double edrive = 0.0099; // Setting edrive = 0 will give undriven limit - - double tdrive = 32000.0; - double sort_interval = 10; // Injector moments also updated at this interval - - // Numerical parameters - double nppc = 100; // Average number of macro particle per cell per species - - double Lx = 25.6 * di; // size of box in x dimension - double Ly = 1 * di; // size of box in y dimension - double Lz = 12.8 * di; // size of box in z dimension - - double topology_x = 4; // Number of domains in x, y, and z - double topology_y = 1; - double topology_z = 1; // For load balance, keep "1" or "2" for Harris sheet - - double nx = 64; - double ny = 1; - double nz = 32; - - double hx = Lx / nx; - double hy = Ly / ny; - double hz = Lz / nz; - - double b0 = me * c * wce / ec; // Asymptotic magnetic field strength - double n0 = me * eps0 * wpe * wpe / (ec * ec); // Peak electron (ion) density - double vdri = 2 * c * Ti / (ec * b0 * L); // Ion drift velocity - double vdre = -vdri / (Ti_Te); // electron drift velocity - - double Npe_sheet = - 2 * n0 * Lx * Ly * L * tanh(0.5 * Lz / L); // N physical e's in sheet - double Npe_back = nb_n0 * n0 * Ly * Lz * Lx; // N physical e's in backgrnd - double Npe = Npe_sheet + Npe_back; - double Ne = nppc * nx * ny * nz; // total macro electrons in box - double Ne_sheet = Ne * Npe_sheet / Npe; - double Ne_back = Ne * Npe_back / Npe; - Ne_sheet = trunc_granular(Ne_sheet, nproc()); // Make it divisible by nproc - Ne_back = trunc_granular(Ne_back, nproc()); // Make it divisible by nproc - Ne = Ne_sheet + Ne_back; - double qe_s = -ec * Npe_sheet / Ne_sheet; // Charge per macro electron - double qi_s = ec * Npe_sheet / Ne_sheet; // Charge per macro electron - double weight_s = ec * Npe_sheet / Ne_sheet; // Charge per macro electron - double qe_b = -ec * Npe_back / Ne_back; // Charge per macro electron - double qi_b = ec * Npe_back / Ne_back; // Charge per macro electron - double weight_b = ec * Npe_back / Ne_back; // Charge per macro electron - double nfac = qi_s / (hx * hy * hz); // Convert density to particles per cell - - double gdri = 1 / sqrt(1 - vdri * vdri / (c * c)); // gamma of ion drift frame - double gdre = - 1 / sqrt(1 - vdre * vdre / (c * c)); // gamma of electron drift frame - double udri = vdri * gdri; // 4-velocity of ion drift frame - double udre = vdre * gdre; // 4-velocity of electron drift frame - double tanhf = tanh(0.5 * Lz / L); - double Lpert = Lpert_Lx * Lx; // wavelength of perturbation - double dbz = - dbz_b0 * b0; // Perturbation in Bz relative to Bo (Only change here) - double dbx = - -dbz * Lpert / (2.0 * Lz); // Set Bx perturbation so that div(B) = 0 - - // Determine the time step - double dg = courant_length(Lx, Ly, Lz, nx, ny, nz); // courant length - double dt = cfl_req * dg / c; // courant limited time step - if (wpe * dt > wpedt_max) - dt = wpedt_max / wpe; // override timestep if plasma frequency limited - - // Intervals for output - int energies_interval = 50; - int interval = int(t_intervali / (wci * dt)); - int fields_interval = interval; - int ehydro_interval = interval; - int Hhydro_interval = interval; - int eparticle_interval = 8 * interval; - int Hparticle_interval = 8 * interval; - int quota_check_interval = 100; - - // Collision parameters - // In CGS, variance of tan theta = - // 2 pi e^4 n_e dt_coll loglambda / (m_ab^2 u^3) - - int ii_collisions = 0; // do collisions between the corresponding species - int ee_collisions = 0; - int ei_collisions = 0; - - int tstep_coll = (int)sort_interval; // How frequently to do collisions - double dt_coll = dt * (tstep_coll); // in (1/wpe) - double nuei_wce = 0.05; - double cvar = - dt_coll * 3.0 * sqrt(2.0 * M_PI) / 4.0 * pow(vthe, 3) * nuei_wce / wpe_wce; - // Max possible number of particles/cell of ea. species - // (to size the key array in collision handler) - double nppc_max = 20 * nppc; - - // Determine which domains area along the boundaries - Use macro from - // grid/partition.c. - -#define RANK_TO_INDEX(rank, ix, iy, iz) \ - BEGIN_PRIMITIVE \ - { \ - int _ix, _iy, _iz; \ - _ix = (rank); /* ix = ix+gpx*( iy+gpy*iz ) */ \ - _iy = _ix / int(topology_x); /* iy = iy+gpy*iz */ \ - _ix -= _iy * int(topology_x); /* ix = ix */ \ - _iz = _iy / int(topology_y); /* iz = iz */ \ - _iy -= _iz * int(topology_y); /* iy = iy */ \ - (ix) = _ix; \ - (iy) = _iy; \ - (iz) = _iz; \ - } \ - END_PRIMITIVE - - int ix, iy, iz, left = 0, right = 0, top = 0, bottom = 0; - RANK_TO_INDEX(int(rank()), ix, iy, iz); - if (ix == 0) - left = 1; - if (ix == topology_x - 1) - right = 1; - if (iz == 0) - bottom = 1; - if (iz == topology_z - 1) - top = 1; - - /////////////////////////////////////////////// - // Setup high level simulation parameters - num_step = int(taui / (wci * dt)); - status_interval = 100; - sync_shared_interval = status_interval / 2; - clean_div_e_interval = status_interval / 2; - clean_div_b_interval = status_interval / 2; - - global->restart_interval = restart_interval; - global->energies_interval = energies_interval; - global->fields_interval = fields_interval; - global->ehydro_interval = ehydro_interval; - global->Hhydro_interval = Hhydro_interval; - global->eparticle_interval = eparticle_interval; - global->Hparticle_interval = Hparticle_interval; - global->quota_check_interval = quota_check_interval; - global->quota_sec = quota_sec; - global->rtoggle = 0; - - global->b0 = b0; - global->bg = bg; - global->v_A = v_A; - global->edrive = edrive; - global->tdrive = tdrive; - - global->topology_x = topology_x; - global->topology_y = topology_y; - global->topology_z = topology_z; - - global->left = left; - global->right = right; - global->top = top; - global->bottom = bottom; - - // Parameters for the open boundary model - global->open_bc_x = open_bc_x; - global->driven_bc_z = driven_bc_z; - global->nsp = 2; - global->nb = nb_n0; - global->rin[0] = rin[0]; - global->rin[1] = rin[1]; - global->rin[2] = rin[2]; - global->rout[0] = rout[0]; - global->rout[1] = rout[1]; - global->rout[2] = rout[2]; - global->vth[0] = sqrt(2) * vthe; - global->vth[1] = sqrt(2) * vthi; - global->vthb[0] = sqrt(2) * vtheb; - global->vthb[1] = sqrt(2) * vthib; - global->q[0] = weight_s; - global->q[1] = weight_s; - global->uf[0] = udre; - global->uf[1] = udri; - global->sort[0] = sort_interval; - global->sort[1] = sort_interval; - global->nfac = nfac; - global->L_de = L; - - // Collision model parameters - global->ee_collisions = ee_collisions; - global->ii_collisions = ii_collisions; - global->ei_collisions = ei_collisions; - - global->cvar = cvar; - global->nppc_max = nppc_max; - global->tstep_coll = tstep_coll; - global->mi_me = mi_me; - global->Z = Z; - global->wpewce = wpe_wce; - global->nfac = nfac; - - ////////////////////////////////////////////////////////////////////////////// - // Setup the grid - - // Setup basic grid parameters - grid->dx = hx; - grid->dy = hy; - grid->dz = hz; - grid->dt = dt; - grid->cvac = c; - grid->eps0 = eps0; - // grid->damp = damp; - - // Define the grid - define_periodic_grid(0, -0.5 * Ly, -0.5 * Lz, // Low corner - Lx, 0.5 * Ly, 0.5 * Lz, // High corner - nx, ny, nz, // Resolution - topology_x, topology_y, topology_z); // Topology - - // ***** Set Field Boundary Conditions ***** - // sim_log("Absorbing fields on X & Z-boundaries"); - // if ( iz==0 ) set_domain_field_bc( BOUNDARY(0,0,-1), - // absorb_fields ); if ( iz==topology_z-1 ) set_domain_field_bc( BOUNDARY( - // 0,0,1), absorb_fields ); - if (global->open_bc_x) { - sim_log("Absorbing fields on X-boundaries"); - if (ix == 0) - set_domain_field_bc(BOUNDARY(-1, 0, 0), absorb_fields); - if (ix == topology_x - 1) - set_domain_field_bc(BOUNDARY(1, 0, 0), absorb_fields); - } - - sim_log("Conducting fields on Z-boundaries"); - if (iz == 0) - set_domain_field_bc(BOUNDARY(0, 0, -1), pec_fields); - if (iz == topology_z - 1) - set_domain_field_bc(BOUNDARY(0, 0, 1), pec_fields); - // if ( ix==0 ) set_domain_field_bc( BOUNDARY(-1,0,0), pec_fields - // ); if ( ix==topology_x-1 ) set_domain_field_bc( BOUNDARY( 1,0,0), - // pec_fields - // ); - - // ***** Set Particle Boundary Conditions ***** - - if (global->driven_bc_z) { - sim_log("Absorb particles on Z-boundaries"); - if (iz == 0) - set_domain_particle_bc(BOUNDARY(0, 0, -1), absorb_particles); - if (iz == topology_z - 1) - set_domain_particle_bc(BOUNDARY(0, 0, 1), absorb_particles); - } else { - sim_log("Reflect particles on Z-boundaries"); - if (iz == 0) - set_domain_particle_bc(BOUNDARY(0, 0, -1), reflect_particles); - if (iz == topology_z - 1) - set_domain_particle_bc(BOUNDARY(0, 0, 1), reflect_particles); - } - if (global->open_bc_x) { - sim_log("Absorb particles on X-boundaries"); - if (ix == 0) - set_domain_particle_bc(BOUNDARY(-1, 0, 0), absorb_particles); - if (ix == topology_x - 1) - set_domain_particle_bc(BOUNDARY(1, 0, 0), absorb_particles); - } - - ////////////////////////////////////////////////////////////////////////////// - // Setup materials - - sim_log("Setting up materials. "); - - define_material("vacuum", 1); - material_t* resistive = define_material("resistive", 1, 1, 1); - - define_field_array(NULL); // second argument is damp, default to 0 - - // Note: define_material defaults to isotropic materials with mu=1,sigma=0 - // Tensor electronic, magnetic and conductive materials are supported - // though. See "shapes" for how to define them and assign them to regions. - // Also, space is initially filled with the first material defined. - - ////////////////////////////////////////////////////////////////////////////// - // Finalize Field Advance - - sim_log("Finalizing Field Advance"); - - // Define resistive layer surrounding boundary --> set thickness=0 - // to eliminate this feature - double thickness = 0; -#define resistive_layer \ - ((global->open_bc_x && x < hx * thickness) || \ - (global->open_bc_x && x > Lx - hx * thickness) || \ - z < -Lz / 2 + hz * thickness || z > Lz / 2 - hz * thickness) - - if (thickness > 0) { - sim_log("Setting resistive layer of thickness " << thickness); - set_region_material(resistive_layer, resistive, resistive); - } - - ////////////////////////////////////////////////////////////////////////////// - // Setup the species - - sim_log("Setting up species. "); - double nmax = 2.0 * Ne / nproc(); - double nmovers = 0.1 * nmax; - double sort_method = 1; // 0=in place and 1=out of place - species_t* electron = define_species("electron", -ec, me, nmax, nmovers, - electron_sort_interval, sort_method); - species_t* ion = define_species("ion", ec, mi, nmax, nmovers, - ion_sort_interval, sort_method); - - /////////////////////////////////////////////////// - // Log diagnostic information about this simulation - - sim_log("***********************************************"); - sim_log("* Topology: " - << topology_x << " " << topology_y << " " << topology_z); - sim_log("tanhf = " << tanhf); - sim_log("L_di = " << L_di); - sim_log("rhoi/L = " << rhoi_L); - sim_log("Ti/Te = " << Ti_Te); - sim_log("nb/n0 = " << nb_n0); - sim_log("wpe/wce = " << wpe_wce); - sim_log("mi/me = " << mi_me); - sim_log("theta = " << theta); - sim_log("Lpert/Lx = " << Lpert_Lx); - sim_log("dbz/b0 = " << dbz_b0); - sim_log("taui = " << taui); - sim_log("t_intervali = " << t_intervali); - sim_log("intervali = " << interval); - sim_log("num_step = " << num_step); - sim_log("Lx/di = " << Lx / di); - sim_log("Lx/de = " << Lx / de); - sim_log("Ly/di = " << Ly / di); - sim_log("Ly/de = " << Ly / de); - sim_log("Lz/di = " << Lz / di); - sim_log("Lz/de = " << Lz / de); - sim_log("nx = " << nx); - sim_log("ny = " << ny); - sim_log("nz = " << nz); - sim_log("damp = " << damp); - sim_log("courant = " << c * dt / dg); - sim_log("nproc = " << nproc()); - sim_log("nppc = " << nppc); - sim_log("b0 = " << b0); - sim_log("v_A (based on nb) = " << v_A); - sim_log("di = " << di); - sim_log("Ne = " << Ne); - sim_log("Ne_sheet = " << Ne_sheet); - sim_log("Ne_back = " << Ne_back); - sim_log("total # of particles = " << 2 * Ne); - sim_log("dt*wpe = " << wpe * dt); - sim_log("dt*wce = " << wce * dt); - sim_log("dt*wci = " << wci * dt); - sim_log("energies_interval: " << energies_interval); - sim_log("dx/de = " << Lx / (de * nx)); - sim_log("dy/de = " << Ly / (de * ny)); - sim_log("dz/de = " << Lz / (de * nz)); - sim_log("dx/rhoi = " << (Lx / nx) / (vthi / wci)); - sim_log("dx/rhoe = " << (Lx / nx) / (vthe / wce)); - sim_log("L/debye = " << L / (vthe / wpe)); - sim_log("dx/debye = " << (Lx / nx) / (vthe / wpe)); - sim_log("n0 = " << n0); - sim_log("vthi/c = " << vthi / c); - sim_log("vthe/c = " << vthe / c); - sim_log("vdri/c = " << vdri / c); - sim_log("vdre/c = " << vdre / c); - sim_log("* nu/wce: " << nuei_wce); - sim_log("* nu*dt_coll: " << nuei_wce / wpe_wce * dt_coll); - sim_log("ee_collisions = " << ee_collisions); - sim_log("ei_collisions = " << ei_collisions); - sim_log("ii_collisions = " << ii_collisions); - sim_log("Open BC in x? = " << open_bc_x); - sim_log("Driven BC in z? = " << driven_bc_z); - - // Dump simulation information to file "info" - if (rank() == 0) { - FileIO fp_info; - if (!(fp_info.open("info", io_write) == ok)) - ERROR(("Cannot open file.")); - fp_info.print(" ***** Simulation parameters ***** \n"); - fp_info.print(" L/di = %e\n", L_di); - fp_info.print(" L/de = %e\n", L / de); - fp_info.print(" rhoi/L = %e\n", rhoi_L); - fp_info.print(" Ti/Te = %e\n", Ti_Te); - fp_info.print(" Tbi/Ti = %e\n", Tbi_Ti); - fp_info.print(" Tbe/Te = %e\n", Tbe_Te); - fp_info.print(" nb/n0 = %e\n", nb_n0); - fp_info.print(" wpe/wce = %e\n", wpe_wce); - fp_info.print(" mi/me = %e\n", mi_me); - fp_info.print(" theta = %e\n", theta); - fp_info.print(" taui = %e\n", taui); - fp_info.print(" num_step = %i\n", num_step); - fp_info.print(" Lx/de = %e\n", Lx / de); - fp_info.print(" Ly/de = %e\n", Ly / de); - fp_info.print(" Lz/de = %e\n", Lz / de); - fp_info.print(" Lx/di = %e\n", Lx / di); - fp_info.print(" Ly/di = %e\n", Ly / di); - fp_info.print(" Lz/di = %e\n", Lz / di); - fp_info.print(" nx = %e\n", nx); - fp_info.print(" ny = %e\n", ny); - fp_info.print(" nz = %e\n", nz); - fp_info.print(" damp = %e\n", damp); - fp_info.print(" courant = %e\n", c * dt / dg); - fp_info.print(" nproc = %i\n", nproc()); - fp_info.print(" nppc = %e\n", nppc); - fp_info.print(" b0 = %e\n", b0); - fp_info.print(" v_A (based on nb) = %e\n", v_A); - fp_info.print(" di = %e\n", di); - fp_info.print(" Ne = %e\n", Ne); - fp_info.print(" Ne_sheet = %e\n", Ne_sheet); - fp_info.print(" Ne_back = %e\n", Ne_back); - fp_info.print(" total # of particles = %e\n", 2 * Ne); - fp_info.print(" dt*wpe = %e\n", wpe * dt); - fp_info.print(" dt*wce = %e\n", wce * dt); - fp_info.print(" dt*wci = %e\n", wci * dt); - fp_info.print(" energies_interval: %i\n", - energies_interval); - fp_info.print(" dx/de = %e\n", Lx / (de * nx)); - fp_info.print(" dy/de = %e\n", Ly / (de * ny)); - fp_info.print(" dz/de = %e\n", Lz / (de * nz)); - fp_info.print(" L/debye = %e\n", - L / (vthe / wpe)); - fp_info.print(" dx/rhoi = %e\n", - (Lx / nx) / (vthi / wci)); - fp_info.print(" dx/rhoe = %e\n", - (Lx / nx) / (vthe / wce)); - fp_info.print(" dx/debye = %e\n", - (Lx / nx) / (vthe / wpe)); - fp_info.print(" n0 = %e\n", n0); - fp_info.print(" vthi/c = %e\n", vthi / c); - fp_info.print(" vthe/c = %e\n", vthe / c); - fp_info.print(" vdri/c = %e\n", vdri / c); - fp_info.print(" vdre/c = %e\n", vdre / c); - fp_info.print(" tstep_coll: %i\n", tstep_coll); - fp_info.print(" nu/wce: %g\n", nuei_wce); - fp_info.print(" nu*dt_coll: %g\n", - nuei_wce / wpe_wce * dt_coll); - fp_info.print(" ***************************\n"); - fp_info.close(); - } - - //////////////////////////// - // Load fields - - sim_log("Loading fields"); - set_region_field( - everywhere, 0, 0, 0, // Electric field - cs * b0 * tanh(z / L) + - dbx * cos(2.0 * M_PI * (x - 0.5 * Lx) / Lpert) * sin(M_PI * z / Lz), // Bx - -sn * b0 * tanh(z / L) + b0 * bg, // By - dbz * cos(M_PI * z / Lz) * sin(2.0 * M_PI * (x - 0.5 * Lx) / Lpert)); // Bz - - // Localized Perturbation to lauch a light wave - - // # define R2 ((x-0.5*Lx)*(x-0.5*Lx) + z*z)/(L*L) - // # define PERT 0.2*tanh(R2)/cosh(R2) - // set_region_field( everywhere, 0, 0, 0, // Electric - // field - // cs*b0*tanh(z/L) - z*PERT, //Bx - // b0*bg, //By - // (x-0.5*Lx)*PERT ); // Bz - - // Note: everywhere is a region that encompasses the entire simulation - // In general, regions are specied as logical equations (i.e. x>0 && x+y<2) - - // LOAD PARTICLES - - sim_log("Loading particles"); - - // Do a fast load of the particles - - seed_entropy(rank()); // Generators desynchronized - double xmin = grid->x0, xmax = grid->x0 + (grid->dx) * (grid->nx); - double ymin = grid->y0, ymax = grid->y0 + (grid->dy) * (grid->ny); - double zmin = grid->z0, zmax = grid->z0 + (grid->dz) * (grid->nz); - - // Load Harris population - - sim_log("-> Main Harris Sheet"); - - repeat(Ne_sheet / nproc()) - { - double x, y, z, ux, uy, uz, d0; - - do { - z = L * atanh(uniform(rng(0), -1, 1) * tanhf); - } while (z <= zmin || z >= zmax); - x = uniform(rng(0), xmin, xmax); - y = uniform(rng(0), ymin, ymax); - - // inject_particles() will return an error for particles no on this - // node and will not inject particle locally - - ux = normal(rng(0), 0, vthe); - uy = normal(rng(0), 0, vthe); - uz = normal(rng(0), 0, vthe); - d0 = gdre * uy + sqrt(ux * ux + uy * uy + uz * uz + 1) * udre; - uy = d0 * cs - ux * sn; - ux = d0 * sn + ux * cs; - - inject_particle(electron, x, y, z, ux, uy, uz, weight_s, 0, 0); - - ux = normal(rng(0), 0, vthi); - uy = normal(rng(0), 0, vthi); - uz = normal(rng(0), 0, vthi); - d0 = gdri * uy + sqrt(ux * ux + uy * uy + uz * uz + 1) * udri; - uy = d0 * cs - ux * sn; - ux = d0 * sn + ux * cs; - - inject_particle(ion, x, y, z, ux, uy, uz, weight_s, 0, 0); - } - - sim_log("-> Background Population"); - - repeat(Ne_back / nproc()) - { - - double x = uniform(rng(0), xmin, xmax); - double y = uniform(rng(0), ymin, ymax); - double z = uniform(rng(0), zmin, zmax); - - inject_particle(electron, x, y, z, normal(rng(0), 0, vtheb), - normal(rng(0), 0, vtheb), normal(rng(0), 0, vtheb), - weight_b, 0, 0); - - inject_particle(ion, x, y, z, normal(rng(0), 0, vthib), - normal(rng(0), 0, vthib), normal(rng(0), 0, vthib), - weight_b, 0, 0); - } - - sim_log("Finished loading particles"); - - /*-------------------------------------------------------------------------- - * New dump definition - *------------------------------------------------------------------------*/ - - /*-------------------------------------------------------------------------- - * Set data output format - * - * This option allows the user to specify the data format for an output - * dump. Legal settings are 'band' and 'band_interleave'. Band-interleave - * format is the native storage format for data in VPIC. For field data, - * this looks something like: - * - * ex0 ey0 ez0 div_e_err0 cbx0 ... ex1 ey1 ez1 div_e_err1 cbx1 ... - * - * Banded data format stores all data of a particular state variable as a - * contiguous array, and is easier for ParaView to process efficiently. - * Banded data looks like: - * - * ex0 ex1 ex2 ... exN ey0 ey1 ey2 ... - * - *------------------------------------------------------------------------*/ - - global->fdParams.format = band; - sim_log("Fields output format = band"); - - global->hedParams.format = band; - sim_log("Electron species output format = band"); - - global->hHdParams.format = band; - sim_log("Ion species output format = band"); - - /*-------------------------------------------------------------------------- - * Set stride - * - * This option allows data down-sampling at output. Data are down-sampled - * in each dimension by the stride specified for that dimension. For - * example, to down-sample the x-dimension of the field data by a factor - * of 2, i.e., half as many data will be output, select: - * - * global->fdParams.stride_x = 2; - * - * The following 2-D example shows down-sampling of a 7x7 grid (nx = 7, - * ny = 7. With ghost-cell padding the actual extents of the grid are 9x9. - * Setting the strides in x and y to equal 2 results in an output grid of - * nx = 4, ny = 4, with actual extents 6x6. - * - * G G G G G G G G G - * G X X X X X X X G - * G X X X X X X X G G G G G G G - * G X X X X X X X G G X X X X G - * G X X X X X X X G ==> G X X X X G - * G X X X X X X X G G X X X X G - * G X X X X X X X G G X X X X G - * G X X X X X X X G G G G G G G - * G G G G G G G G G - * - * Note that grid extents in each dimension must be evenly divisible by - * the stride for that dimension: - * - * nx = 150; - * global->fdParams.stride_x = 10; // legal -> 150/10 = 15 - * - * global->fdParams.stride_x = 8; // illegal!!! -> 150/8 = 18.75 - *------------------------------------------------------------------------*/ - - // relative path to fields data from global header - sprintf(global->fdParams.baseDir, "fields"); - - // base file name for fields output - sprintf(global->fdParams.baseFileName, "fields"); - - global->fdParams.stride_x = 1; - global->fdParams.stride_y = 1; - global->fdParams.stride_z = 1; - - // add field parameters to list - global->outputParams.push_back(&global->fdParams); - - sim_log("Fields x-stride " << global->fdParams.stride_x); - sim_log("Fields y-stride " << global->fdParams.stride_y); - sim_log("Fields z-stride " << global->fdParams.stride_z); - - // relative path to electron species data from global header - sprintf(global->hedParams.baseDir, "hydro"); - - // base file name for fields output - sprintf(global->hedParams.baseFileName, "ehydro"); - - global->hedParams.stride_x = 1; - global->hedParams.stride_y = 1; - global->hedParams.stride_z = 1; - - // add electron species parameters to list - global->outputParams.push_back(&global->hedParams); - - sim_log("Electron species x-stride " << global->hedParams.stride_x); - sim_log("Electron species y-stride " << global->hedParams.stride_y); - sim_log("Electron species z-stride " << global->hedParams.stride_z); - - // relative path to electron species data from global header - sprintf(global->hHdParams.baseDir, "hydro"); - - // base file name for fields output - sprintf(global->hHdParams.baseFileName, "Hhydro"); - - global->hHdParams.stride_x = 1; - global->hHdParams.stride_y = 1; - global->hHdParams.stride_z = 1; - - sim_log("Ion species x-stride " << global->hHdParams.stride_x); - sim_log("Ion species y-stride " << global->hHdParams.stride_y); - sim_log("Ion species z-stride " << global->hHdParams.stride_z); - - // add electron species parameters to list - global->outputParams.push_back(&global->hHdParams); - - /*-------------------------------------------------------------------------- - * Set output fields - * - * It is now possible to select which state-variables are output on a - * per-dump basis. Variables are selected by passing an or-list of - * state-variables by name. For example, to only output the x-component - * of the electric field and the y-component of the magnetic field, the - * user would call output_variables like: - * - * global->fdParams.output_variables( ex | cby ); - * - * NOTE: OUTPUT VARIABLES ARE ONLY USED FOR THE BANDED FORMAT. IF THE - * FORMAT IS BAND-INTERLEAVE, ALL VARIABLES ARE OUTPUT AND CALLS TO - * 'output_variables' WILL HAVE NO EFFECT. - * - * ALSO: DEFAULT OUTPUT IS NONE! THIS IS DUE TO THE WAY THAT VPIC - * HANDLES GLOBAL VARIABLES IN THE INPUT DECK AND IS UNAVOIDABLE. - * - * For convenience, the output variable 'all' is defined: - * - * global->fdParams.output_variables( all ); - *------------------------------------------------------------------------*/ - /* CUT AND PASTE AS A STARTING POINT - * REMEMBER TO ADD APPROPRIATE GLOBAL DUMPPARAMETERS VARIABLE - - output_variables( all ); - - output_variables( electric | div_e_err | magnetic | div_b_err | - tca | rhob | current | rhof | - emat | nmat | fmat | cmat ); - - output_variables( current_density | charge_density | - momentum_density | ke_density | stress_tensor ); - */ - - // global->fdParams.output_variables( electric | magnetic ); - // global->hedParams.output_variables( current_density | charge_density - // | stress_tensor ); - // global->hHdParams.output_variables( current_density | charge_density ); - // | stress_tensor ); - - global->fdParams.output_variables(all); - global->hedParams.output_variables(all); - global->hHdParams.output_variables(all); - - /*-------------------------------------------------------------------------- - * Convenience functions for simlog output - *------------------------------------------------------------------------*/ - - char varlist[512]; - create_field_list(varlist, global->fdParams); - - sim_log("Fields variable list: " << varlist); - - create_hydro_list(varlist, global->hedParams); - - sim_log("Electron species variable list: " << varlist); - - create_hydro_list(varlist, global->hHdParams); - - sim_log("Ion species variable list: " << varlist); - - /* --------------------------------------------- - Add parameters for the energy diagnostics - --------------------------------------------- */ - - global->ede.sp_id = electron->id; - global->ede.vth = sqrt(2.0) * vthe; - sprintf(global->ede.fname, global->hedParams.baseFileName); - - global->edi.sp_id = ion->id; - global->edi.vth = sqrt(2.0) * vthi; - sprintf(global->edi.fname, global->hHdParams.baseFileName); - - global->nex = 6; - global->emax = 120; - - sim_log("*** Finished with user-specified initialization ***"); - - // Upon completion of the initialization, the following occurs: - // - The synchronization error (tang E, norm B) is computed between domains - // and tang E / norm B are synchronized by averaging where discrepancies - // are encountered. - // - The initial divergence error of the magnetic field is computed and - // one pass of cleaning is done (for good measure) - // - The bound charge density necessary to give the simulation an initially - // clean divergence e is computed. - // - The particle momentum is uncentered from u_0 to u_{-1/2} - // - The user diagnostics are called on the initial state - // - The physics loop is started - // - // The physics loop consists of: - // - Advance particles from x_0,u_{-1/2} to x_1,u_{1/2} - // - User particle injection at x_{1-age}, u_{1/2} (use inject_particles) - // - User current injection (adjust field(x,y,z).jfx, jfy, jfz) - // - Advance B from B_0 to B_{1/2} - // - Advance E from E_0 to E_1 - // - User field injection to E_1 (adjust field(x,y,z).ex,ey,ez,cbx,cby,cbz) - // - Advance B from B_{1/2} to B_1 - // - (periodically) Divergence clean electric field - // - (periodically) Divergence clean magnetic field - // - (periodically) Synchronize shared tang e and norm b - // - Increment the time step - // - Call user diagnostics - // - (periodically) Print a status message - -} // begin_initialization - -#define should_dump(x) \ - (global->x##_interval > 0 && remainder(step(), global->x##_interval) == 0) - -begin_diagnostics -{ - - /*-------------------------------------------------------------------------- - * NOTE: YOU CANNOT DIRECTLY USE C FILE DESCRIPTORS OR SYSTEM CALLS ANYMORE - * - * To create a new directory, use: - * - * dump_mkdir("full-path-to-directory/directoryname") - * - * To open a file, use: FileIO class - * - * Example for file creation and use: - * - * // declare file and open for writing - * // possible modes are: io_write, io_read, io_append, - * // io_read_write, io_write_read, io_append_read - * FileIO fileIO; - * FileIOStatus status; - * status= fileIO.open("full-path-to-file/filename", io_write); - * - * // formatted ASCII output - * fileIO.print("format string", varg1, varg2, ...); - * - * // binary output - * // Write n elements from array data to file. - * // T is the type, e.g., if T=double - * // fileIO.write(double * data, size_t n); - * // All basic types are supported. - * fileIO.write(T * data, size_t n); - * - * // close file - * fileIO.close(); - *------------------------------------------------------------------------*/ - - /*-------------------------------------------------------------------------- - * Data output directories - * WARNING: The directory list passed to "global_header" must be - * consistent with the actual directories where fields and species are - * output using "field_dump" and "hydro_dump". - * - * DIRECTORY PATHES SHOULD BE RELATIVE TO - * THE LOCATION OF THE GLOBAL HEADER!!! - *------------------------------------------------------------------------*/ - - const int nsp = global->nsp; - const int nx = grid->nx; - const int ny = grid->ny; - const int nz = grid->nz; - - /*-------------------------------------------------------------------------- - * Normal rundata dump - *------------------------------------------------------------------------*/ - if (step() == 0) { - dump_mkdir("fields"); - dump_mkdir("hydro"); - dump_mkdir("rundata"); - dump_mkdir("injectors"); - dump_mkdir("restart1"); // 1st backup - dump_mkdir("restart2"); // 2nd backup - dump_mkdir("particle"); - - dump_grid("rundata/grid"); - dump_materials("rundata/materials"); - dump_species("rundata/species"); - global_header("global", global->outputParams); - } // if - - /*-------------------------------------------------------------------------- - * Normal rundata energies dump - *------------------------------------------------------------------------*/ - if (should_dump(energies)) { - dump_energies("rundata/energies", step() == 0 ? 0 : 1); - } // if - - /*-------------------------------------------------------------------------- - * Field data output - *------------------------------------------------------------------------*/ - - if (step() == -1 || should_dump(fields)) - field_dump(global->fdParams); - - /*-------------------------------------------------------------------------- - * Electron species output - *------------------------------------------------------------------------*/ - - if (should_dump(ehydro)) - hydro_dump("electron", global->hedParams); - - /*-------------------------------------------------------------------------- - * Ion species output - *------------------------------------------------------------------------*/ - - if (should_dump(Hhydro)) - hydro_dump("ion", global->hHdParams); - - /*-------------------------------------------------------------------------- - * Restart dump - *------------------------------------------------------------------------*/ - - if (step() && !(step() % global->restart_interval)) { - if (!global->rtoggle) { - global->rtoggle = 1; - checkpt("restart1/restart", 0); - } else { - global->rtoggle = 0; - checkpt("restart2/restart", 0); - } // if - } // if - - // Dump particle data - - char subdir[36]; - if (should_dump(eparticle) && step() != 0 && - step() > 56 * (global->fields_interval)) { - // if ( should_dump(eparticle) && step() !=0 ) { - sprintf(subdir, "particle/T.%d", step()); - dump_mkdir(subdir); - sprintf(subdir, "particle/T.%d/eparticle", step()); - dump_particles("electron", subdir); - } - - if (should_dump(Hparticle) && step() != 0 && - step() > 56 * (global->fields_interval)) { - sprintf(subdir, "particle/T.%d/Hparticle", step()); - dump_particles("ion", subdir); - } - - // Shut down simulation when wall clock time exceeds global->quota_sec. - // Note that the mp_elapsed() is guaranteed to return the same value for all - // processors (i.e., elapsed time on proc #0), and therefore the abort will - // be synchronized across processors. Note that this is only checked every - // few timesteps to eliminate the expensive mp_elapsed call from every - // timestep. mp_elapsed has an ALL_REDUCE in it! - - if ((step() > 0 && global->quota_check_interval > 0 && - (step() & global->quota_check_interval) == 0) || - (global->write_end_restart)) { - if ((global->write_end_restart)) { - - global->write_end_restart = 0; // reset restart flag - - sim_log("Allowed runtime exceeded for this job. Terminating....\n"); - double dumpstart = uptime(); - - checkpt("restart0/restart", 0); - - mp_barrier(); // Just to be safe - sim_log("Restart dump restart completed."); - double dumpelapsed = uptime() - dumpstart; - sim_log("Restart duration " << dumpelapsed); - exit(0); // Exit or abort? - } - if (uptime() > global->quota_sec) - global->write_end_restart = 1; - } - -} // end diagnostics - -begin_particle_injection {} - -begin_current_injection {} - -begin_field_injection {} - -begin_particle_collisions {} diff --git a/src/libpsc/vpic/wrapper.cxx b/src/libpsc/vpic/wrapper.cxx deleted file mode 100644 index 7f732595ee..0000000000 --- a/src/libpsc/vpic/wrapper.cxx +++ /dev/null @@ -1,4 +0,0 @@ - -#define INPUT_DECK deck.cxx - -#include "deck/wrapper.cc" diff --git a/src/libpsc/vpic/wrapper_empty.cxx b/src/libpsc/vpic/wrapper_empty.cxx deleted file mode 100644 index 2b50b3d954..0000000000 --- a/src/libpsc/vpic/wrapper_empty.cxx +++ /dev/null @@ -1,28 +0,0 @@ - -#include "vpic.h" - -#include - -void vpic_simulation::user_initialization(int argc, char** argv) { assert(0); } - -void vpic_simulation::user_diagnostics() { assert(0); } - -void vpic_simulation::user_field_injection() -{ - // assert(0); -} - -void vpic_simulation::user_current_injection() -{ - // assert(0); -} - -void vpic_simulation::user_particle_injection() -{ - // assert(0); -} - -void vpic_simulation::user_particle_collisions() -{ - // assert(0); -} diff --git a/src/libpsc/vpic/wrapper_split.cxx b/src/libpsc/vpic/wrapper_split.cxx deleted file mode 100644 index 2f88c410ac..0000000000 --- a/src/libpsc/vpic/wrapper_split.cxx +++ /dev/null @@ -1,4 +0,0 @@ - -#define INPUT_DECK deck_split.cxx - -#include "deck/wrapper.cc" From 61694cf482fcba0ca630dbe2552fcc52251ad768 Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 10:25:17 -0500 Subject: [PATCH 18/46] -mfields_state_vpic --- src/libpsc/vpic/mfields_state_vpic.hxx | 120 ------------------------- 1 file changed, 120 deletions(-) delete mode 100644 src/libpsc/vpic/mfields_state_vpic.hxx diff --git a/src/libpsc/vpic/mfields_state_vpic.hxx b/src/libpsc/vpic/mfields_state_vpic.hxx deleted file mode 100644 index f022069e8c..0000000000 --- a/src/libpsc/vpic/mfields_state_vpic.hxx +++ /dev/null @@ -1,120 +0,0 @@ - -#pragma once - -#include "../libpsc/vpic/VpicGridBase.h" -#include "../libpsc/vpic/VpicMaterial.h" - -#include "Field3D.h" - -#include "field_advance/field_advance.h" -#define IN_sfa -#include "field_advance/standard/sfa_private.h" - -#include -#include - -// ====================================================================== -// MfieldsStateVpic - -struct MfieldsStateVpic -{ - using real_t = float; - using Grid = VpicGridBase; - using MaterialList = VpicMaterialList; - using FieldArray = field_array_t; - using SfaParams = sfa_params_t; - - enum - { - EX = 0, - EY = 1, - EZ = 2, - DIV_E_ERR = 3, - BX = 4, - BY = 5, - BZ = 6, - DIV_B_ERR = 7, - TCAX = 8, - TCAY = 9, - TCAZ = 10, - RHOB = 11, - JFX = 12, - JFY = 13, - JFZ = 14, - RHOF = 15, - N_COMP = 20, - }; - - struct Patch - { - using Element = field_t; - - Patch(Grid* vgrid, const MaterialList& material_list, double damp = 0.) - : fa_{::new_standard_field_array(vgrid, material_list, damp)} - {} - - ~Patch() { delete_field_array(fa_); } - - Element* data() { return fa_->f; } - Grid* grid() { return static_cast(fa_->g); } - field_t operator[](int idx) const { return fa_->f[idx]; } - field_t& operator[](int idx) { return fa_->f[idx]; } - - // These operators can be used to access the field directly, - // though the performance isn't optimal, so one should use Field3D - // when performance is important - static const int N_COMP = sizeof(field_t) / sizeof(float); - - float operator()(int m, int i, int j, int k) const - { - float* f = reinterpret_cast(fa_->f); - return f[VOXEL(i, j, k, fa_->g->nx, fa_->g->ny, fa_->g->nz) * N_COMP + m]; - } - - float& operator()(int m, int i, int j, int k) - { - float* f = reinterpret_cast(fa_->f); - return f[VOXEL(i, j, k, fa_->g->nx, fa_->g->ny, fa_->g->nz) * N_COMP + m]; - } - - SfaParams& params() { return *static_cast(fa_->params); } - - operator field_array_t*() { return fa_; } - - private: - field_array_t* fa_; - }; - - using fields_view_t = kg::SArrayView; - - MfieldsStateVpic(const Grid_t& grid, Grid* vgrid, - const MaterialList& material_list, double damp = 0.) - : grid_{grid}, patch_{vgrid, material_list, damp} - { - assert(grid.n_patches() == 1); - - const int B = 1; // VPIC always uses one ghost cell (on c.c. grid) - im_ = {vgrid->nx + 2 * B, vgrid->ny + 2 * B, vgrid->nz + 2 * B}; - ib_ = {-B, -B, -B}; - } - - real_t* data() { return reinterpret_cast(patch_.data()); } - fields_view_t operator[](int p) { return {{ib_, im_}, N_COMP, data()}; } - Patch& getPatch(int p) { return patch_; } - - SfaParams& params() { return patch_.params(); } - const Grid& vgrid() { return *patch_.grid(); } - - operator FieldArray*() { return patch_; } - FieldArray* fa() { return patch_; } - - const Grid_t& grid() const { return grid_; } - int n_patches() const { return grid_.n_patches(); } - int n_comps() const { return N_COMP; } - Int3 ibn() const { return {1, 1, 1}; } - -private: - const Grid_t& grid_; - Patch patch_; - Int3 ib_, im_; -}; From dc50eab75d6e83ba0a377e5ee9f8951d74aefc6c Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 10:25:54 -0500 Subject: [PATCH 19/46] -checks_vpic --- src/libpsc/vpic/checks_vpic.hxx | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 src/libpsc/vpic/checks_vpic.hxx diff --git a/src/libpsc/vpic/checks_vpic.hxx b/src/libpsc/vpic/checks_vpic.hxx deleted file mode 100644 index b6458df944..0000000000 --- a/src/libpsc/vpic/checks_vpic.hxx +++ /dev/null @@ -1,14 +0,0 @@ - -#pragma once - -template -struct ChecksVpic : ChecksParams -{ - ChecksVpic(const Grid_t& grid, MPI_Comm comm, const ChecksParams& params) - : ChecksParams(params) - {} - - void continuity_before_particle_push(Mparticles& mprts) {} - void continuity_after_particle_push(Mparticles& mprts, MfieldsState& mflds) {} - void gauss(Mparticles& mprts, MfieldsState& mflds) {} -}; From 1c2858c182c35c2f002053ee1ad2424b6b62aaa3 Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 10:26:55 -0500 Subject: [PATCH 20/46] -bnd_fields_vpic --- src/libpsc/vpic/bnd_fields_vpic.hxx | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 src/libpsc/vpic/bnd_fields_vpic.hxx diff --git a/src/libpsc/vpic/bnd_fields_vpic.hxx b/src/libpsc/vpic/bnd_fields_vpic.hxx deleted file mode 100644 index a5c93d8aa3..0000000000 --- a/src/libpsc/vpic/bnd_fields_vpic.hxx +++ /dev/null @@ -1,12 +0,0 @@ - -#pragma once - -#include "bnd_fields.hxx" - -template -struct BndFieldsVpic : BndFieldsBase -{ - void fill_ghosts_E(MfieldsState& mflds) {} - void fill_ghosts_H(MfieldsState& mflds) {} - void add_ghosts_J(MfieldsState& mflds) {} -}; From c660ebe1e20b4d1c92e55b201f73825ec2d31e6d Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 10:32:01 -0500 Subject: [PATCH 21/46] -test_RngPool --- src/libpsc/vpic/tests/.gitignore | 1 - src/libpsc/vpic/tests/test_RngPool.cxx | 111 ------------------------- 2 files changed, 112 deletions(-) delete mode 100644 src/libpsc/vpic/tests/test_RngPool.cxx diff --git a/src/libpsc/vpic/tests/.gitignore b/src/libpsc/vpic/tests/.gitignore index 6407504551..a37297a2f7 100644 --- a/src/libpsc/vpic/tests/.gitignore +++ b/src/libpsc/vpic/tests/.gitignore @@ -4,4 +4,3 @@ test_PscGridBase test_VpicInterpolatorBase test_PscInterpolatorBase test_PscFieldArray -test_RngPool diff --git a/src/libpsc/vpic/tests/test_RngPool.cxx b/src/libpsc/vpic/tests/test_RngPool.cxx deleted file mode 100644 index b946abf0b6..0000000000 --- a/src/libpsc/vpic/tests/test_RngPool.cxx +++ /dev/null @@ -1,111 +0,0 @@ - -#include "testing.h" - -#include "VpicRng.h" -#include "PscRng.h" - -#include "util/checkpt/checkpt.h" -#include "util/mp/mp.h" - -#include -#include -#include -#include -#include -#include "mrc_common.h" - -// ---------------------------------------------------------------------- -// test_Urng -// -// test that Rng behaves like a C++ Urng, -// though in the end we're not actually using this interface, -// at least for now - -template -void test_Urng(G& g) -{ - std::cout << "-- test_Urng: " << typeid(g).name() << std::endl; - g.seed(1); - - for (int i = 0; i < 3; i++) { - std::cout << "gen " << i << " " << g() << std::endl; - } - - for (int i = 0; i < 3; i++) { - std::cout << "can " << i << " " << std::generate_canonical(g) - << std::endl; - } - - std::uniform_real_distribution uni(1, 2); - for (int i = 0; i < 3; i++) { - std::cout << "uni " << i << " " << uni(g) << std::endl; - } -} - -template -void test_Urng() -{ - // std::mt19937 mt; - // test_Urng(mt); - - Rng& rng = *(Rng::create()); - test_Urng(rng); -} - -template -void test_RngPool() -{ - mprintf("-- test_RngPool: %s\n", typeid(RngPool).name()); - - bool check = check_ref && (psc_world_rank == 0 || - (psc_world_rank == 1 && psc_world_size == 2)); - - RngPool pool; - pool.seed(0, 0); - auto rng = pool[0]; - - // reference values for VPIC's Mersenne Twister and uniform real distribution - double vals[2][3] = { - {0.93447864356331700186, -0.85443051718174234388, -0.41999871425083479259}, - {-0.44692117455683644245, -0.69362908232141173848, -0.66745219004201739033}, - }; - for (int i = 0; i < 3; i++) { - double val = rng->uniform(-1., 1.); - mprintf("uni %d %.20g\n", i, val); - assert(val >= -1. && val <= 1.); - if (check) { - assert(val == vals[psc_world_rank][i]); - } - } - - // reference values for VPIC's Mersenne Twister and normal distribution - double nvals[2][3] = { - {2.0612612026289509615, -1.7184880229355798953, 0.61942045083350327772}, - {2.6605241085475155316, -1.22946085323322718, 2.396498223337572675}, - }; - for (int i = 0; i < 3; i++) { - double val = rng->normal(1., 2.); - mprintf("nrm %d %.20g\n", i, val); - if (check) { - assert(val == nvals[psc_world_rank][i]); - } - } -} - -int main(int argc, char** argv) -{ - testing_init(&argc, &argv); - - test_Urng(); - test_Urng(); - - // The VpicRng based pools should match the exact reference result sequence - test_RngPool, true>(); - test_RngPool, true>(); - // But PscRng, while still based on a Mersenne Twister, is using - // C++-11 provided MT and distributions, so it won't match - test_RngPool, false>(); - - MPI_Finalize(); - return 0; -} From b231dac7185ce3abc333f849a4a9c48b25f4b9f1 Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 10:33:23 -0500 Subject: [PATCH 22/46] -mfields_interpolator_vpic --- src/libpsc/vpic/mfields_interpolator_vpic.hxx | 38 ------------------- 1 file changed, 38 deletions(-) delete mode 100644 src/libpsc/vpic/mfields_interpolator_vpic.hxx diff --git a/src/libpsc/vpic/mfields_interpolator_vpic.hxx b/src/libpsc/vpic/mfields_interpolator_vpic.hxx deleted file mode 100644 index cb4df53257..0000000000 --- a/src/libpsc/vpic/mfields_interpolator_vpic.hxx +++ /dev/null @@ -1,38 +0,0 @@ - -#pragma once - -// ====================================================================== -// MfieldsInterpolatorVpic - -struct MfieldsInterpolatorVpic -{ - using Grid = VpicGridBase; - using Element = interpolator_t; - - struct Patch - { - using Element = interpolator_t; - - Patch(Grid* vgrid) : ip_{new_interpolator_array(vgrid)} {} - - ~Patch() { delete_interpolator_array(ip_); } - - Element* data() { return ip_->i; } - Element operator[](int idx) const { return ip_->i[idx]; } - Element& operator[](int idx) { return ip_->i[idx]; } - - Grid* grid() { return static_cast(ip_->g); } - - interpolator_array_t* ip() { return ip_; } - - private: - interpolator_array_t* ip_; - }; - - MfieldsInterpolatorVpic(Grid* vgrid) : patch_{vgrid} {} - - Patch& getPatch(int p) { return patch_; } - -private: - Patch patch_; -}; From f662f2842b0a17c1d2fd8a9a255810c29bf8fa02 Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 10:33:45 -0500 Subject: [PATCH 23/46] -mfields_accumulator_vpic --- src/libpsc/vpic/mfields_accumulator_vpic.hxx | 55 -------------------- 1 file changed, 55 deletions(-) delete mode 100644 src/libpsc/vpic/mfields_accumulator_vpic.hxx diff --git a/src/libpsc/vpic/mfields_accumulator_vpic.hxx b/src/libpsc/vpic/mfields_accumulator_vpic.hxx deleted file mode 100644 index 9baf334e13..0000000000 --- a/src/libpsc/vpic/mfields_accumulator_vpic.hxx +++ /dev/null @@ -1,55 +0,0 @@ - -#pragma once - -#include "VpicGridBase.h" - -// ====================================================================== -// MfieldsAccumulatorVpic - -struct MfieldsAccumulatorVpic -{ - using Grid = VpicGridBase; - using Element = accumulator_t; - - struct Block - { - using Grid = VpicGridBase; - using Element = accumulator_t; - - Block(Element* arr, Grid* g) : arr_{arr}, g_{g} {} - - Element operator[](int idx) const { return arr_[idx]; } - Element& operator[](int idx) { return arr_[idx]; } - - private: - Element* arr_; - Grid* g_; - }; - - MfieldsAccumulatorVpic(Grid* vgrid) : aa_{::new_accumulator_array(vgrid)} {} - - ~MfieldsAccumulatorVpic() { ::delete_accumulator_array(aa_); } - - Grid* grid() { return static_cast(aa_->g); } - int n_pipeline() { return aa_->n_pipeline; } - int stride() { return aa_->stride; } - - Element* data() { return aa_->a; } - - // FIXME, not a great interface with arr just another index - Element& operator()(int arr, int i, int j, int k) - { - return aa_->a[arr * aa_->stride + - VOXEL(i, j, k, aa_->g->nx, aa_->g->ny, aa_->g->nz)]; - } - - Block operator[](int arr) - { - return Block(aa_->a + arr * aa_->stride, grid()); - } - - operator accumulator_array_t*() { return aa_; } - -private: - accumulator_array_t* aa_; -}; From 4ee4acc377d612ae102cea265a80a06b1828c521 Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 10:34:08 -0500 Subject: [PATCH 24/46] -mfields_hydro_vpic --- src/libpsc/vpic/mfields_hydro_vpic.hxx | 73 -------------------------- 1 file changed, 73 deletions(-) delete mode 100644 src/libpsc/vpic/mfields_hydro_vpic.hxx diff --git a/src/libpsc/vpic/mfields_hydro_vpic.hxx b/src/libpsc/vpic/mfields_hydro_vpic.hxx deleted file mode 100644 index 04fd33ce4c..0000000000 --- a/src/libpsc/vpic/mfields_hydro_vpic.hxx +++ /dev/null @@ -1,73 +0,0 @@ - -#pragma once - -// ====================================================================== -// MfieldsHydroVpic - -#include "../libpsc/vpic/VpicGridBase.h" - -struct MfieldsHydroVpic -{ - using Grid = VpicGridBase; - using real_t = float; - using Element = hydro_t; - using fields_view_t = kg::SArrayView; - - enum - { - N_COMP = 16, - }; - - static_assert(N_COMP == sizeof(Element) / sizeof(real_t), - "N_COMP doesn't match Element"); - - struct Patch - { - using Element = hydro_t; - - Patch(Grid* vgrid) : ha_{::new_hydro_array(vgrid)} - { - ::clear_hydro_array(ha_); - } - - ~Patch() { ::delete_hydro_array(ha_); } - - Element* data() { return ha_->h; } - - Element operator[](int idx) const { return ha_->h[idx]; } - Element& operator[](int idx) { return ha_->h[idx]; } - - Grid* grid() { return static_cast(ha_->g); } - - operator hydro_array_t*() { return ha_; } - - private: - hydro_array_t* ha_; - Grid* vgrid_; - }; - - MfieldsHydroVpic(const Grid_t& grid, Grid* vgrid) : grid_{grid}, patch_{vgrid} - { - assert(grid.n_patches() == 1); - - const int B = 1; // VPIC always uses one ghost cell (on c.c. grid) - im_ = {vgrid->nx + 2 * B, vgrid->ny + 2 * B, vgrid->nz + 2 * B}; - ib_ = {-B, -B, -B}; - } - - int n_patches() const { return grid_.n_patches(); } - int n_comps() const { return N_COMP; } - - real_t* data() { return reinterpret_cast(patch_.data()); } - fields_view_t operator[](int p) { return {{ib_, im_}, N_COMP, data()}; } - Patch& getPatch(int p) { return patch_; } - - Grid* vgrid() { return patch_.grid(); } - - operator hydro_array_t*() { return patch_; } - -private: - const Grid_t& grid_; - Patch patch_; - Int3 ib_, im_; -}; From 38b83d01b69a6fb061b1e39f9b7a7c639ea8c11e Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 10:36:06 -0500 Subject: [PATCH 25/46] -VpicRng --- src/libpsc/vpic/VpicRng.h | 88 --------------------------------------- 1 file changed, 88 deletions(-) delete mode 100644 src/libpsc/vpic/VpicRng.h diff --git a/src/libpsc/vpic/VpicRng.h b/src/libpsc/vpic/VpicRng.h deleted file mode 100644 index a98379bdef..0000000000 --- a/src/libpsc/vpic/VpicRng.h +++ /dev/null @@ -1,88 +0,0 @@ - -#ifndef VPIC_RNG_H -#define VPIC_RNG_H - -#include -#include - -// ====================================================================== -// Rng -// -// needs to support: -// static Rng* create() (factory) -// void seed(unsigned int) -// double uniform(double lo, double hi) -// double normal(double mu, double sigma) -// -// also supports UniformRandomBitGenerator concept, though that ends up -// only being tested but not used - -// ====================================================================== -// VpicRng - -#define IN_rng -#include "util/rng/rng_private.h" - -struct VpicRng : rng_t -{ - static VpicRng* create(int seed = 0) - { - return static_cast(::new_rng(seed)); - } - - void seed(unsigned int s) { ::seed_rng(this, s); } - - double uniform(double lo, double hi) - { - double dx = ::drand(this); - return lo * (1. - dx) + hi * dx; - } - - double normal(double mu, double sigma) { return mu + sigma * ::drandn(this); } - - unsigned int operator()() { return ::uirand(this); } - - static constexpr unsigned int min() - { - return std::numeric_limits::min(); - } - - static constexpr unsigned int max() - { - return std::numeric_limits::max(); - } -}; - -// ====================================================================== -// RngPool -// -// needs to support: -// void seed(int base, int which) -// Rng* operator[](int n) - -// ====================================================================== -// VpicRngPool - -template -struct VpicRngPool -{ - typedef R Rng; - - VpicRngPool() - { - int new_rng = 2; - rng_pool_ = new_rng_pool(new_rng, 0, 0); - } - - void seed(int base, int which) { ::seed_rng_pool(rng_pool_, base, which); } - - Rng* operator[](int n) - { - assert(n == 0); - return reinterpret_cast(rng_pool_->rng[n]); - } - - rng_pool* rng_pool_; -}; - -#endif From cd8cc8edcb9b1e880b189c3c3dfbde7f02e2f37b Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 10:37:06 -0500 Subject: [PATCH 26/46] -VpicInterpolator --- src/libpsc/vpic/VpicInterpolator.h | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 src/libpsc/vpic/VpicInterpolator.h diff --git a/src/libpsc/vpic/VpicInterpolator.h b/src/libpsc/vpic/VpicInterpolator.h deleted file mode 100644 index 04da06c9d7..0000000000 --- a/src/libpsc/vpic/VpicInterpolator.h +++ /dev/null @@ -1,14 +0,0 @@ - -#pragma once - -// ====================================================================== -// VpicInterpolatorOps - -template -struct VpicInterpolatorOps -{ - static void load(Interpolator& ip, FieldArray& fa) - { - ::load_interpolator_array(&ip, &fa); - } -}; From 209fd1d4d45fd181ce61c74e39c86fedd4f17ccc Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 10:37:42 -0500 Subject: [PATCH 27/46] -test_VpicInterpolatorBase --- src/libpsc/vpic/tests/.gitignore | 1 - .../vpic/tests/test_VpicInterpolatorBase.cxx | 16 ---------------- 2 files changed, 17 deletions(-) delete mode 100644 src/libpsc/vpic/tests/test_VpicInterpolatorBase.cxx diff --git a/src/libpsc/vpic/tests/.gitignore b/src/libpsc/vpic/tests/.gitignore index a37297a2f7..91f44d9941 100644 --- a/src/libpsc/vpic/tests/.gitignore +++ b/src/libpsc/vpic/tests/.gitignore @@ -1,6 +1,5 @@ test_VpicGridBase test_PscGridBase -test_VpicInterpolatorBase test_PscInterpolatorBase test_PscFieldArray diff --git a/src/libpsc/vpic/tests/test_VpicInterpolatorBase.cxx b/src/libpsc/vpic/tests/test_VpicInterpolatorBase.cxx deleted file mode 100644 index f742e5b56e..0000000000 --- a/src/libpsc/vpic/tests/test_VpicInterpolatorBase.cxx +++ /dev/null @@ -1,16 +0,0 @@ - -#include "testing.h" -#include "test_InterpolatorBase.h" - -#include "VpicGridBase.h" -#include "VpicInterpolatorBase.h" - -int main(int argc, char** argv) -{ - testing_init(&argc, &argv); - - typedef VpicGridBase Grid; - typedef VpicInterpolatorBase InterpolatorBase; - - test_InterpolatorBase(); -} From 04c7028149ef9b33bca4bbd4ce8ceec78e8e567f Mon Sep 17 00:00:00 2001 From: James McClung Date: Mon, 29 Dec 2025 10:38:20 -0500 Subject: [PATCH 28/46] -main --- src/libpsc/vpic/main.cxx | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 src/libpsc/vpic/main.cxx diff --git a/src/libpsc/vpic/main.cxx b/src/libpsc/vpic/main.cxx deleted file mode 100644 index 606c857c75..0000000000 --- a/src/libpsc/vpic/main.cxx +++ /dev/null @@ -1,4 +0,0 @@ - -#define main orig_main - -#include "deck/main.cc" From a33da24d10b9bf7f22ddc8469ca435d4cdf8c0eb Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 26 May 2026 10:57:02 -0400 Subject: [PATCH 29/46] -mrc_io_vpic; * --- src/libmrc/include/mrc_io_private.h | 1 - src/libmrc/src/mrc_io.c | 1 - src/libmrc/src/mrc_io_vpic.c | 620 ---------------------------- 3 files changed, 622 deletions(-) delete mode 100644 src/libmrc/src/mrc_io_vpic.c diff --git a/src/libmrc/include/mrc_io_private.h b/src/libmrc/include/mrc_io_private.h index edf06b3782..c4092a7978 100644 --- a/src/libmrc/include/mrc_io_private.h +++ b/src/libmrc/include/mrc_io_private.h @@ -64,7 +64,6 @@ extern struct diagsrv_srv_ops ds_srv_ops; extern struct diagsrv_srv_ops ds_srv_cache_ops; extern struct mrc_io_ops mrc_io_ascii_ops; -extern struct mrc_io_ops mrc_io_vpic_ops; extern struct mrc_io_ops mrc_io_xdmf_ops; extern struct mrc_io_ops mrc_io_xdmf_serial_ops; extern struct mrc_io_ops mrc_io_xdmf_to_one_ops; diff --git a/src/libmrc/src/mrc_io.c b/src/libmrc/src/mrc_io.c index 9cfbdbc9e6..93e5d35f98 100644 --- a/src/libmrc/src/mrc_io.c +++ b/src/libmrc/src/mrc_io.c @@ -686,7 +686,6 @@ static void mrc_io_init() #endif #endif mrc_class_register_subclass(&mrc_class_mrc_io, &mrc_io_ascii_ops); - mrc_class_register_subclass(&mrc_class_mrc_io, &mrc_io_vpic_ops); mrc_class_register_subclass(&mrc_class_mrc_io, &mrc_io_combined_ops); // ======================================== // Deprecated / eternally broken io types (FIXME) diff --git a/src/libmrc/src/mrc_io_vpic.c b/src/libmrc/src/mrc_io_vpic.c deleted file mode 100644 index 4d5f001db7..0000000000 --- a/src/libmrc/src/mrc_io_vpic.c +++ /dev/null @@ -1,620 +0,0 @@ - -#include "mrc_io_private.h" -#include - -#include -#include -#include -#include -#include -#include - -#define DIMENSION (3) // Grid and vector -#define MAX_FIELD_VARS (10) -#define MAX_SPECIES (10) -#define HEADER_SIZE (123) - -enum -{ - VPIC_FIELD = 1, // Field data file - VPIC_HYDRO = 2, // Hydro data file -}; - -enum -{ // Structure types - CONSTANT = 0, // Structure types - SCALAR = 1, - VECTOR = 2, - TENSOR = 3, - TENSOR9 = 4, -}; - -static const char* struct_type_to_string[] = { - [CONSTANT] = "CONSTANT", [SCALAR] = "SCALAR", [VECTOR] = "VECTOR", - [TENSOR] = "TENSOR", [TENSOR9] = "TENSOR", -}; - -static int struct_type_to_comp_size[] = { - [CONSTANT] = 1, [SCALAR] = 1, [VECTOR] = 3, [TENSOR] = 6, [TENSOR9] = 9, -}; - -enum -{ // Basic data types - FLOAT = 0, - INTEGER = 1, -}; - -static const char* basic_type_to_string[] = { - [FLOAT] = "FLOATING_POINT", - [INTEGER] = "INTEGER", -}; - -static int basic_type_to_byte_count[] = { - [FLOAT] = sizeof(float), - [INTEGER] = sizeof(int), -}; - -// ====================================================================== -// mrc_io type "vpic" - -struct field_var -{ - char* name; - int struct_type; - int basic_type; -}; - -struct dataset -{ - char* directory; - char* base_filename; - int n_vars; - struct field_var vars[MAX_FIELD_VARS]; - FILE** files; -}; - -struct mrc_io_vpic_global -{ - float delta_t; - float cvac; - float eps; - double extents[3][2]; - double delta_x[3]; - int topology[3]; -}; - -struct mrc_io_vpic -{ - // parameters - int proc_field_len; - int time_field_len; - - bool global_in_progress; - bool global_done; - struct mrc_io_vpic_global global; - - int nr_patches; - float* buf; - - struct dataset fields; - - int n_species; - struct dataset species[MAX_SPECIES]; -}; - -#define mrc_io_vpic(io) mrc_to_subobj(io, struct mrc_io_vpic) - -// ====================================================================== - -static bool is_hydro_var(struct mrc_fld* fld, int* p_n_comp, int* p_skip, - char** p_name) -{ - int n_comp, skip; - char* name; - if (strncmp(mrc_fld_name(fld), "n_", 2) == 0) { - n_comp = 1; - skip = 2; - name = "n"; - } else if (strncmp(mrc_fld_name(fld), "v_", 2) == 0) { - n_comp = 3; - skip = 2; - name = "v"; - } else if (strncmp(mrc_fld_name(fld), "p_", 2) == 0) { - n_comp = 3; - skip = 2; - name = "p"; - } else if (strncmp(mrc_fld_name(fld), "T_", 2) == 0) { - n_comp = 6; - skip = 2; - name = "T"; - } else { - return false; - } - - if (p_n_comp) - *p_n_comp = n_comp; - if (p_skip) - *p_skip = skip; - if (p_name) - *p_name = name; - return true; -} - -static void mkdir_comm(const char* path, MPI_Comm comm) -{ - int rank; - MPI_Comm_rank(comm, &rank); - if (rank == 0) { - // mprintf("MKDIR %s\n", path); - if (mkdir(path, 0777)) { - if (errno != EEXIST) { - perror("ERROR: mkdir"); - assert(0); - } - } - } - MPI_Barrier(comm); -} - -// ====================================================================== -// writing the global file - -// ---------------------------------------------------------------------- -// mrc_io_vpic_print_vars - -static void mrc_io_vpic_print_vars(struct mrc_io* io, FILE* file, - struct dataset* ds) -{ - for (int n = 0; n < ds->n_vars; n++) { - struct field_var* f = &ds->vars[n]; - fprintf(file, "\"%s\" %s %d %s %d\n", f->name, - struct_type_to_string[f->struct_type], - struct_type_to_comp_size[f->struct_type], - basic_type_to_string[f->basic_type], - basic_type_to_byte_count[f->basic_type]); - } -} - -// ---------------------------------------------------------------------- -// mrc_io_vpic_write_global_file - -static void mrc_io_vpic_write_global_file(struct mrc_io* io, FILE* file) -{ - struct mrc_io_vpic* sub = mrc_io_vpic(io); - struct mrc_io_vpic_global* g = &sub->global; - - fprintf(file, "# generated by libmrc mrc_io 'vpic' writer'\n"); - fprintf(file, "VPIC_HEADER_VERSION %s\n", "mrc_io_vpic_1"); - fprintf(file, "DATA_HEADER_SIZE %d\n", HEADER_SIZE); - fprintf(file, "GRID_DELTA_T %g\n", g->delta_t); - fprintf(file, "GRID_CVAC %g\n", g->cvac); - fprintf(file, "GRID_EPS %g\n", g->eps); - fprintf(file, "GRID_EXTENTS_X %g %g\n", g->extents[0][0], g->extents[0][1]); - fprintf(file, "GRID_EXTENTS_Y %g %g\n", g->extents[1][0], g->extents[1][1]); - fprintf(file, "GRID_EXTENTS_Z %g %g\n", g->extents[2][0], g->extents[2][1]); - fprintf(file, "GRID_DELTA_X %g\n", g->delta_x[0]); - fprintf(file, "GRID_DELTA_Y %g\n", g->delta_x[1]); - fprintf(file, "GRID_DELTA_Z %g\n", g->delta_x[02]); - fprintf(file, "GRID_TOPOLOGY_X %d\n", g->topology[0]); - fprintf(file, "GRID_TOPOLOGY_Y %d\n", g->topology[1]); - fprintf(file, "GRID_TOPOLOGY_Z %d\n", g->topology[2]); - fprintf(file, "FIELD_DATA_DIRECTORY %s\n", sub->fields.directory); - fprintf(file, "FIELD_DATA_BASE_FILENAME %s\n", sub->fields.base_filename); - fprintf(file, "FIELD_DATA_VARIABLES %d\n", sub->fields.n_vars); - mrc_io_vpic_print_vars(io, file, &sub->fields); - fprintf(file, "NUM_OUTPUT_SPECIES %d\n", sub->n_species); - for (int s = 0; s < sub->n_species; s++) { - struct dataset* ds = &sub->species[s]; - fprintf(file, "SPECIES_DATA_DIRECTORY %s\n", ds->directory); - fprintf(file, "SPECIES_DATA_BASE_FILENAME %s\n", ds->base_filename); - fprintf(file, "HYDRO_DATA_VARIABLES %d\n", ds->n_vars); - mrc_io_vpic_print_vars(io, file, ds); - } -} - -// ---------------------------------------------------------------------- -// mrc_io_vpic_open_global - -static void mrc_io_vpic_open_global(struct mrc_io* io) -{ - struct mrc_io_vpic* sub = mrc_io_vpic(io); - - if (!sub->global_done) { - sub->global_in_progress = true; - sub->global.eps = 1.f; // FIXME? - } -} - -// ---------------------------------------------------------------------- -// mrc_io_vpic_close_global - -static void mrc_io_vpic_close_global(struct mrc_io* io) -{ - struct mrc_io_vpic* sub = mrc_io_vpic(io); - - if (sub->global_in_progress) { - char filename[strlen(io->par.outdir) + strlen(io->par.basename) + 10]; - sprintf(filename, "%s/%s.vpc", io->par.outdir, io->par.basename); - FILE* global_file = fopen(filename, "w"); - assert(global_file); - mrc_io_vpic_write_global_file(io, global_file); - fclose(global_file); - sub->global_done = true; - sub->global_in_progress = false; - } -} - -// ---------------------------------------------------------------------- -// mrc_io_vpic_add_var - -static void mrc_io_vpic_add_var(struct mrc_io* io, struct dataset* ds, - const char* name, int nr_comps) -{ - int n = ds->n_vars; - assert(n < MAX_FIELD_VARS); - - if (n == 0) { // create dir, only first time around - char dirname[strlen(io->par.outdir) + strlen(ds->directory) + 10]; - sprintf(dirname, "%s/%s", io->par.outdir, ds->directory); - mkdir_comm(dirname, mrc_io_comm(io)); - } - - ds->vars[n].name = strdup(name); - - switch (nr_comps) { - case 1: ds->vars[n].struct_type = SCALAR; break; - case 3: ds->vars[n].struct_type = VECTOR; break; - case 6: ds->vars[n].struct_type = TENSOR; break; - default: mprintf("ERROR: unhandled nr_comps %d\n", nr_comps); assert(0); - } - ds->vars[n].basic_type = FLOAT; - ds->n_vars++; -} - -// ---------------------------------------------------------------------- -// mrc_io_vpic_write_fld_global - -static void mrc_io_vpic_write_fld_global(struct mrc_io* io, struct mrc_fld* fld) -{ - struct mrc_io_vpic* sub = mrc_io_vpic(io); - - if (!sub->global_in_progress) { - return; - } - - struct mrc_io_vpic_global* g = &sub->global; - - struct mrc_domain* domain = fld->_domain; - mrc_domain_get_param_int3(domain, "np", g->topology); - struct mrc_crds* crds = mrc_domain_get_crds(domain); - double xl[3], xh[3]; - // FIXME: "base" only really makes sense for amr.. - mrc_crds_get_dx_base(crds, g->delta_x); - mrc_crds_get_param_double3(crds, "l", xl); - mrc_crds_get_param_double3(crds, "h", xh); - for (int d = 0; d < 3; d++) { - g->extents[d][0] = xl[d]; - g->extents[d][1] = xh[d]; - } - - // is this field a moment (hydro var)? - int n_comp, skip; - char* name; - if (is_hydro_var(fld, &n_comp, &skip, &name)) { - int n_species = mrc_fld_nr_comps(fld) / n_comp; - - if (sub->n_species == 0) { - sub->n_species = n_species; - for (int s = 0; s < n_species; s++) { - struct dataset* ds = &sub->species[s]; - ds->directory = strdup("hydro"); - ds->base_filename = strdup(mrc_fld_comp_name(fld, s) + skip); - } - } else { - assert(sub->n_species == n_species); - } - for (int s = 0; s < n_species; s++) { - mrc_io_vpic_add_var(io, &sub->species[s], name, n_comp); - } - } else { - // otherwise, must be field variable - if (sub->fields.n_vars == 0) { - sub->fields.directory = strdup("fields"); - sub->fields.base_filename = strdup("fields"); - } - mrc_io_vpic_add_var(io, &sub->fields, mrc_fld_name(fld), - mrc_fld_nr_comps(fld)); - } -} - -// ---------------------------------------------------------------------- -// mrc_io_vpic_destroy_dataset - -static void mrc_io_vpic_destroy_dataset(struct mrc_io* io, struct dataset* ds) -{ - free(ds->directory); - free(ds->base_filename); - for (int n = 0; n < ds->n_vars; n++) { - free(ds->vars[n].name); - } - assert(!ds->files); -} - -// ====================================================================== -// main field writing related code - -// ---------------------------------------------------------------------- -// mrc_io_vpic_destroy - -static void mrc_io_vpic_destroy(struct mrc_io* io) -{ - struct mrc_io_vpic* sub = mrc_io_vpic(io); - - mrc_io_vpic_destroy_dataset(io, &sub->fields); - for (int s = 0; s < sub->n_species; s++) { - mrc_io_vpic_destroy_dataset(io, &sub->species[s]); - } - free(sub->buf); -} - -// ---------------------------------------------------------------------- -// mrc_io_vpic_write_header - -static void mrc_io_vpic_write_header(struct mrc_io* io, FILE* file, - struct mrc_fld* fld, int p, int vpic_type) -{ - struct mrc_io_vpic* sub = mrc_io_vpic(io); - - struct mrc_domain* domain = fld->_domain; - struct mrc_crds* crds = mrc_domain_get_crds(domain); - - // write magic / boiler plate - char byteSize[5] = {sizeof(long long), sizeof(short), sizeof(int), - sizeof(float), sizeof(double)}; - fwrite(byteSize, 1, 5, file); - short int cafe = 0xcafe; - fwrite(&cafe, sizeof(short int), 1, file); - int deadbeef = 0xdeadbeef; - fwrite(&deadbeef, sizeof(int), 1, file); - float floatone = 1.f; - fwrite(&floatone, sizeof(float), 1, file); - double doubleone = 1.; - fwrite(&doubleone, sizeof(double), 1, file); - - // header - - int version = 1; // FIXME? - int dumpType = vpic_type; - int dumpTime = io->step; - const int* gridSize = mrc_fld_dims(fld); // FIXME mrc_fld_spatial_dims() - float deltaTime = sub->global.delta_t; - double gridStep[DIMENSION]; - // FIXME: base only really makes sense for AMR - mrc_crds_get_dx_base(crds, gridStep); - float gridOrigin[DIMENSION] = {0., 0., 0.}; // FIXME? - float cvac = sub->global.cvac; - float epsilon = sub->global.eps; - float damp = 0.f; // FIXME? - struct mrc_patch_info info; - mrc_domain_get_local_patch_info(domain, p, &info); - int rank = info.global_patch; - int* topology = sub->global.topology; - int totalRank = topology[0] * topology[1] * topology[2]; - int spid = 0; //??? - int spqm = 0; //??? - - fwrite(&version, sizeof(int), 1, file); - fwrite(&dumpType, sizeof(int), 1, file); - - fwrite(&dumpTime, sizeof(int), 1, file); - fwrite(gridSize, sizeof(int), DIMENSION, file); - fwrite(&deltaTime, sizeof(float), 1, file); - fwrite(gridStep, sizeof(double), DIMENSION, file); - fwrite(gridOrigin, sizeof(float), DIMENSION, file); - fwrite(&cvac, sizeof(float), 1, file); - fwrite(&epsilon, sizeof(float), 1, file); - fwrite(&damp, sizeof(float), 1, file); - fwrite(&rank, sizeof(int), 1, file); - fwrite(&totalRank, sizeof(int), 1, file); - - fwrite(&spid, sizeof(int), 1, file); - fwrite(&spqm, sizeof(float), 1, file); - - // Array size / # dims / ghost dims - int recordSize = 1; - int numberOfDimensions = DIMENSION; - int ghostSize[DIMENSION] = {gridSize[0] + 2, gridSize[1] + 2, - gridSize[2] + 2}; - - fwrite(&recordSize, sizeof(int), 1, file); - fwrite(&numberOfDimensions, sizeof(int), 1, file); - fwrite(ghostSize, sizeof(int), DIMENSION, file); -} - -// ---------------------------------------------------------------------- -// mrc_io_vpic_open - -static void mrc_io_vpic_open(struct mrc_io* io, const char* mode) -{ - assert(strcmp(mode, "w") == 0); // only writing supported - - mrc_io_vpic_open_global(io); -} - -// ---------------------------------------------------------------------- -// mrc_io_vpic_close_files - -static void mrc_io_vpic_close_files(struct mrc_io* io, struct dataset* ds) -{ - struct mrc_io_vpic* sub = mrc_io_vpic(io); - - for (int p = 0; p < sub->nr_patches; p++) { - fclose(ds->files[p]); - } - free(ds->files); - ds->files = NULL; -} - -// ---------------------------------------------------------------------- -// mrc_io_vpic_close - -static void mrc_io_vpic_close(struct mrc_io* io) -{ - struct mrc_io_vpic* sub = mrc_io_vpic(io); - - mrc_io_vpic_close_global(io); - - mrc_io_vpic_close_files(io, &sub->fields); - for (int s = 0; s < sub->n_species; s++) { - mrc_io_vpic_close_files(io, &sub->species[s]); - } -} - -// ---------------------------------------------------------------------- -// mrc_io_vpic_mkdir_time - -static void mrc_io_vpic_mkdir_time(struct mrc_io* io, const char* dir) -{ - char dirname[strlen(io->par.outdir) + strlen(dir) + 20]; - sprintf(dirname, "%s/%s/T.%d", io->par.outdir, dir, io->step); - mkdir_comm(dirname, mrc_io_comm(io)); -} - -// ---------------------------------------------------------------------- -// mrc_io_vpic_open_data_files - -static FILE** mrc_io_vpic_open_files(struct mrc_io* io, const char* directory, - const char* base_filename, - struct mrc_fld* fld, int vpic_type) -{ - struct mrc_io_vpic* sub = mrc_io_vpic(io); - - mrc_io_vpic_mkdir_time(io, directory); - - FILE** files = malloc(sub->nr_patches * sizeof(*files)); - - for (int p = 0; p < sub->nr_patches; p++) { - struct mrc_patch_info info; - mrc_domain_get_local_patch_info(fld->_domain, p, &info); - char filename[strlen(io->par.outdir) + strlen(directory) + - strlen(base_filename) + 30]; - - int np[3]; - mrc_domain_get_param_int3(fld->_domain, "np", np); - int global_patch_by_dim = - ((info.idx3[2]) * np[1] + info.idx3[1]) * np[0] + info.idx3[0]; - sprintf(filename, "%s/%s/T.%d/%s.%0*d.%0*d", io->par.outdir, directory, - io->step, base_filename, sub->time_field_len, io->step, - sub->proc_field_len, global_patch_by_dim); - files[p] = fopen(filename, "w"); - assert(files[p]); - mrc_io_vpic_write_header(io, files[p], fld, p, vpic_type); - } - - return files; -} - -// ---------------------------------------------------------------------- -// mrc_io_vpic_write_data - -static void mrc_io_vpic_write_data(struct mrc_io* io, struct dataset* ds, - struct mrc_fld* fld, int s, int n_species, - int vpic_type) -{ - struct mrc_io_vpic* sub = mrc_io_vpic(io); - - if (!ds->files) { - ds->files = mrc_io_vpic_open_files(io, ds->directory, ds->base_filename, - fld, vpic_type); - } - - int n_comp = mrc_fld_nr_comps(fld) / n_species; - const int* dims = mrc_fld_dims(fld); // FIXME spatial_dims - int size = (dims[0] + 2) * (dims[1] + 2) * (dims[2] + 2); - if (!sub->buf) { - sub->buf = malloc(size * sizeof(*sub->buf)); - } - - float* buf = sub->buf; - for (int p = 0; p < mrc_fld_nr_patches(fld); p++) { - for (int m = 0; m < n_comp; m++) { - for (int k = 0; k < dims[2]; k++) { - for (int j = 0; j < dims[1]; j++) { - memcpy( - &buf[((k + 1) * (dims[1] + 2) + (j + 1)) * (dims[0] + 2) + (0 + 1)], - &MRC_S5(fld, 0, j, k, s * n_comp + m, p), dims[0] * sizeof(*buf)); - } - } - fwrite(buf, sizeof(*buf), size, ds->files[p]); - } - } -} - -// ---------------------------------------------------------------------- -// mrc_io_vpic_write_fld - -static void mrc_io_vpic_write_fld(struct mrc_io* io, const char* path, - struct mrc_fld* fld) -{ - struct mrc_io_vpic* sub = mrc_io_vpic(io); - - // mprintf("FLD path %s\n", path); - mrc_io_vpic_write_fld_global(io, fld); - - sub->nr_patches = mrc_fld_nr_patches(fld); - - if (is_hydro_var(fld, NULL, NULL, NULL)) { - for (int s = 0; s < sub->n_species; s++) { - mrc_io_vpic_write_data(io, &sub->species[s], fld, s, sub->n_species, - VPIC_HYDRO); - } - } else { - mrc_io_vpic_write_data(io, &sub->fields, fld, 0, 1, VPIC_FIELD); - } -} - -// ---------------------------------------------------------------------- -// mrc_io_vpic_write_attr - -static void mrc_io_vpic_write_attr(struct mrc_io* io, const char* path, - int type, const char* name, - union param_u* pv) -{ - struct mrc_io_vpic* sub = mrc_io_vpic(io); - - if (sub->global_in_progress) { - if (strncmp(path, "psc-", 4) == 0) { - // mprintf("ATTR path %s name %s (type %d)\n", path, name, type); - if (strcmp(name, "cc") == 0) { - sub->global.cvac = pv->u_float; - } else if (strcmp(name, "dt") == 0) { - sub->global.delta_t = pv->u_float; - } - } - } -} - -// ---------------------------------------------------------------------- -// mrc_io_vpic_descr - -#define VAR(x) (void*)offsetof(struct mrc_io_vpic, x) -static struct param mrc_io_vpic_descr[] = { - {"proc_field_len", VAR(proc_field_len), PARAM_INT(6)}, - {"time_field_len", VAR(time_field_len), PARAM_INT(8)}, - {}, -}; -#undef VAR - -// ---------------------------------------------------------------------- -// mrc_io_vpic_ops - -struct mrc_io_ops mrc_io_vpic_ops = { - .name = "vpic", - .size = sizeof(struct mrc_io_vpic), - .param_descr = mrc_io_vpic_descr, - .destroy = mrc_io_vpic_destroy, - .open = mrc_io_vpic_open, - .close = mrc_io_vpic_close, - .write_fld = mrc_io_vpic_write_fld, - .write_attr = mrc_io_vpic_write_attr, -}; From 4552ab836d4e986b8bec0eca9364561e426434ab Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 26 May 2026 10:59:23 -0400 Subject: [PATCH 30/46] psc: -vpic-like stuff --- src/include/psc.hxx | 50 --------------------------------------------- 1 file changed, 50 deletions(-) diff --git a/src/include/psc.hxx b/src/include/psc.hxx index 5f3aa2bc7d..1edd9e2d14 100644 --- a/src/include/psc.hxx +++ b/src/include/psc.hxx @@ -636,53 +636,3 @@ void setupParticles(SetupParticles& setup_particles, Mparticles& mprts, mpi_printf(MPI_COMM_WORLD, "**** Setting up particles...\n"); setup_particles.setupParticles(mprts, init_np); } - -// ====================================================================== -// VPIC-like stuff - -// ---------------------------------------------------------------------- -// define_periodic_grid - -void define_periodic_grid(const double xl[3], const double xh[3], - const int gdims[3], const int np[3]) -{} - -// ---------------------------------------------------------------------- -// set_domain_field_bc - -void set_domain_field_bc(Int3 bnd, int bc) {} - -// ---------------------------------------------------------------------- -// set_domain_particle_bc - -void set_domain_particle_bc(Int3 bnd, int bc) {} - -void grid_setup_communication() {} - -// ---------------------------------------------------------------------- -// vpic_define_grid - -void vpic_define_grid(const Grid_t& grid) {} - -// ---------------------------------------------------------------------- -// vpic_define_material - -static void vpic_define_material(MaterialList& material_list, const char* name, - double eps, double mu = 1., double sigma = 0., - double zeta = 0.) -{} - -// ---------------------------------------------------------------------- -// vpic_define_fields - -void vpic_define_fields(const Grid_t& grid) {} - -// ---------------------------------------------------------------------- -// vpic_create_diagnotics - -void vpic_create_diagnostics(int interval) {} - -// ---------------------------------------------------------------------- -// vpic_setup_diagnostics - -void vpic_setup_perform_diagnostics() {} From 6fd3902534eeaa13eac265f5435aac13f4ef131d Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 26 May 2026 12:04:42 -0400 Subject: [PATCH 31/46] -vpic_hydro_ops; * --- src/libpsc/vpic/fields_item_vpic.hxx | 10 ---------- src/libpsc/vpic/vpic_hydro_ops.hxx | 26 -------------------------- 2 files changed, 36 deletions(-) delete mode 100644 src/libpsc/vpic/vpic_hydro_ops.hxx diff --git a/src/libpsc/vpic/fields_item_vpic.hxx b/src/libpsc/vpic/fields_item_vpic.hxx index 6bd3c1f7ea..73609ab6fa 100644 --- a/src/libpsc/vpic/fields_item_vpic.hxx +++ b/src/libpsc/vpic/fields_item_vpic.hxx @@ -3,9 +3,6 @@ #include "fields_item.hxx" #include -#ifdef USE_VPIC -#include "vpic_hydro_ops.hxx" -#endif #include "psc_hydro_ops.hxx" // ---------------------------------------------------------------------- @@ -185,13 +182,6 @@ private: Grid_t::Kinds kinds_; }; -#ifdef USE_VPIC -template -using OutputHydroVpicWrap = - OutputHydroVpic_>; -#endif - template using OutputHydroVpic = diff --git a/src/libpsc/vpic/vpic_hydro_ops.hxx b/src/libpsc/vpic/vpic_hydro_ops.hxx deleted file mode 100644 index b720e26c2f..0000000000 --- a/src/libpsc/vpic/vpic_hydro_ops.hxx +++ /dev/null @@ -1,26 +0,0 @@ - -#pragma once - -#include "vpic/vpic.h" -#include "psc_vpic_bits.h" - -template -struct VpicHydroOps -{ - using Mparticles = _Mparticles; - using MfieldsHydro = _MfieldsHydro; - using MfieldsInterpolator = _MfieldsInterpolator; - - static void clear(MfieldsHydro& hydro) { ::clear_hydro_array(hydro); } - static void synchronize(MfieldsHydro& hydro) - { - ::synchronize_hydro_array(hydro); - } - static void accumulate_hydro_p(MfieldsHydro& hydro, - typename Mparticles::ConstSpeciesIterator sp, - /*const*/ MfieldsInterpolator& interpolator) - { - ::accumulate_hydro_p(hydro, &*sp, interpolator.getPatch(0).ip()); - } -}; From cb73cbdca8258742e707359c36131c1305222b62 Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 26 May 2026 12:07:07 -0400 Subject: [PATCH 32/46] -VpicParticlesBase --- src/libpsc/vpic/VpicParticlesBase.h | 81 ----------------------------- 1 file changed, 81 deletions(-) delete mode 100644 src/libpsc/vpic/VpicParticlesBase.h diff --git a/src/libpsc/vpic/VpicParticlesBase.h b/src/libpsc/vpic/VpicParticlesBase.h deleted file mode 100644 index 1470e7fe2f..0000000000 --- a/src/libpsc/vpic/VpicParticlesBase.h +++ /dev/null @@ -1,81 +0,0 @@ - -#ifndef VPIC_PARTICLES_BASE_H -#define VPIC_PARTICLES_BASE_H - -#include "VpicListBase.h" - -// ====================================================================== -// VpicParticlesBase - -template -struct VpicSpecies : species_t -{ - typedef G Grid; - - const Grid& vgrid() const { return *static_cast(g); } -}; - -template -struct VpicParticlesBase : public VpicListBase> -{ - typedef G Grid; - typedef BCL ParticleBcList; - typedef VpicSpecies Species; - typedef VpicListBase Base; - typedef particle_t Particle; - typedef particle_mover_t ParticleMover; - - using Base::head_; - using typename Base::const_iterator; - using typename Base::iterator; - - static Species* create(const char* name, float q, float m, int max_local_np, - int max_local_nm, int sort_interval, - int sort_out_of_place, Grid* grid) - { - species_t* sp = species(name, q, m, max_local_np, max_local_nm, - sort_interval, sort_out_of_place, grid); - return static_cast(sp); - } - - int getNumSpecies() { return ::num_species(head_); } - - Species* append(species_t* s) - { - species_t* sp = ::append_species(s, reinterpret_cast(&head_)); - return static_cast(sp); - } - - iterator find(int id) - { - species_t* sp = ::find_species_id(id, head_); - return iterator(static_cast(sp)); - } - - iterator find(const char* name) - { - species_t* sp = ::find_species_name(name, head_); - return iterator(static_cast(sp)); - } - - void inject_particle_reweight(const psc::particle::Inject& prt) - { - species_t* sp = &*find(prt.kind); - - extern vpic_simulation* simulation; - assert(simulation); - - simulation->inject_particle(sp, prt.x[0], prt.x[1], prt.x[2], prt.u[0], - prt.u[1], prt.u[2], prt.w, 0., 0); - } - - const Grid& vgrid() const - { - assert(head_); - return head_->vgrid(); - } - - species_t* head() { return head_; } -}; - -#endif From 1d9a69a2b46ebe13f8e64d927f3043d1ac974560 Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 26 May 2026 12:07:28 -0400 Subject: [PATCH 33/46] -VpicParticleBc --- src/libpsc/vpic/VpicParticleBc.h | 35 -------------------------------- 1 file changed, 35 deletions(-) delete mode 100644 src/libpsc/vpic/VpicParticleBc.h diff --git a/src/libpsc/vpic/VpicParticleBc.h b/src/libpsc/vpic/VpicParticleBc.h deleted file mode 100644 index 9282c646a3..0000000000 --- a/src/libpsc/vpic/VpicParticleBc.h +++ /dev/null @@ -1,35 +0,0 @@ - -#ifndef VPIC_PARTICLE_BC_H -#define VPIC_PARTICLE_BC_H - -#include "VpicListBase.h" - -#include -#include - -#define IN_boundary -#include "boundary/boundary_private.h" - -// ====================================================================== -// VpicParticleBc - -struct VpicParticleBc : particle_bc_t -{}; - -// ====================================================================== -// VpicParticleBcList - -struct VpicParticleBcList : public VpicListBase -{ - typedef VpicParticleBc ParticleBc; - - ParticleBc* append(ParticleBc* pbc) - { - return static_cast( - ::append_particle_bc(pbc, reinterpret_cast(&head_))); - } - - operator const particle_bc_t*() const { return head_; } -}; - -#endif From f45fe3d7dc1f1c13f017006580f5148eda2dc7c1 Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 26 May 2026 12:23:29 -0400 Subject: [PATCH 34/46] -vpic_base; psc, cmake: mv vpic_base_init --- src/libpsc/CMakeLists.txt | 1 - src/libpsc/psc.cxx | 40 +++++++++++++++++- src/libpsc/vpic/vpic_base.cxx | 80 ----------------------------------- 3 files changed, 39 insertions(+), 82 deletions(-) delete mode 100644 src/libpsc/vpic/vpic_base.cxx diff --git a/src/libpsc/CMakeLists.txt b/src/libpsc/CMakeLists.txt index 2d6736b1ef..860b266439 100644 --- a/src/libpsc/CMakeLists.txt +++ b/src/libpsc/CMakeLists.txt @@ -17,7 +17,6 @@ target_gtensor_sources(psc PRIVATE psc_balance/psc_balance.cxx vpic/psc_vpic_bits.cxx - vpic/vpic_base.cxx ) target_include_directories(psc PUBLIC ../include) target_link_libraries(psc PUBLIC kg mrc) diff --git a/src/libpsc/psc.cxx b/src/libpsc/psc.cxx index 7189375644..eb353ef808 100644 --- a/src/libpsc/psc.cxx +++ b/src/libpsc/psc.cxx @@ -78,7 +78,45 @@ _psc_read(struct psc *psc, struct mrc_io *io) #endif // FIXME -void vpic_base_init(int* pargc, char*** pargv); +void vpic_base_init(int* pargc, char*** pargv) +{ + static bool vpic_base_inited = false; + + if (vpic_base_inited) { + return; + } + vpic_base_inited = true; + + // boot_services( &argc, &argv ); + { + // Start up the checkpointing service. This should be first. +#ifdef USE_VPIC + boot_checkpt(pargc, pargv); + + serial.boot(pargc, pargv); + thread.boot(pargc, pargv); + + // Boot up the communications layer + // See note above about thread-core-affinity + + boot_mp(pargc, pargv); +#else + int provided; + MPI_Init_thread(pargc, pargv, MPI_THREAD_MULTIPLE, &provided); +#endif + + MPI_Comm_dup(MPI_COMM_WORLD, &psc_comm_world); + MPI_Comm_rank(psc_comm_world, &psc_world_rank); + MPI_Comm_size(psc_comm_world, &psc_world_size); + + MPI_Barrier(psc_comm_world); +#ifdef USE_VPIC + _boot_timestamp = 0; + _boot_timestamp = uptime(); +#endif + } + LOG_INFO("vpic_base_init() done\n"); +} void psc_init(int& argc, char**& argv) { diff --git a/src/libpsc/vpic/vpic_base.cxx b/src/libpsc/vpic/vpic_base.cxx deleted file mode 100644 index dcbca7ea74..0000000000 --- a/src/libpsc/vpic/vpic_base.cxx +++ /dev/null @@ -1,80 +0,0 @@ - -#include "vpic_config.h" -#include "vpic_iface.h" - -#include -#include - -vpic_simulation* simulation; // FIXME, never initialized, just a hack to make - // things link at least - -// ---------------------------------------------------------------------- -// vpic_base_init - -void vpic_base_init(int* pargc, char*** pargv) -{ - static bool vpic_base_inited = false; - - if (vpic_base_inited) { - return; - } - vpic_base_inited = true; - - // boot_services( &argc, &argv ); - { - // Start up the checkpointing service. This should be first. -#ifdef USE_VPIC - boot_checkpt(pargc, pargv); - - serial.boot(pargc, pargv); - thread.boot(pargc, pargv); - - // Boot up the communications layer - // See note above about thread-core-affinity - - boot_mp(pargc, pargv); -#else - int provided; - MPI_Init_thread(pargc, pargv, MPI_THREAD_MULTIPLE, &provided); -#endif - - MPI_Comm_dup(MPI_COMM_WORLD, &psc_comm_world); - MPI_Comm_rank(psc_comm_world, &psc_world_rank); - MPI_Comm_size(psc_comm_world, &psc_world_size); - - MPI_Barrier(psc_comm_world); -#ifdef USE_VPIC - _boot_timestamp = 0; - _boot_timestamp = uptime(); -#endif - } - LOG_INFO("vpic_base_init() done\n"); -} - -// ====================================================================== - -void Simulation_set_region_resistive_harris(vpic_harris_params* prm, - globals_physics* phys, double dx[3], - double thickness, - struct material* resistive) -{ - // Define resistive layer surrounding boundary --> set thickness=0 - // to eliminate this feature -#define resistive_layer \ - ((prm->open_bc_x && x < dx[0] * thickness) || \ - (prm->open_bc_x && x > phys->Lx - dx[0] * thickness) || \ - z < -phys->Lz / 2 + dx[2] * thickness || \ - z > phys->Lz / 2 - dx[2] * thickness) - - if (thickness > 0) { - mprintf("Setting resistive layer of thickness %g", thickness); - // FIXME!!! - assert(0); -#if 0 -#define field vpic->field - grid_t *grid = sim->grid_->g_; - set_region_material(resistive_layer, resistive, resistive); -#undef field -#endif - } -} From ad1aa31928aa9fec513ab8f79f26fb3dca7e62d2 Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 26 May 2026 12:26:12 -0400 Subject: [PATCH 35/46] psc: inline vpic_base_init --- src/libpsc/psc.cxx | 52 +++++++--------------------------------------- 1 file changed, 8 insertions(+), 44 deletions(-) diff --git a/src/libpsc/psc.cxx b/src/libpsc/psc.cxx index eb353ef808..aa8b6b59f3 100644 --- a/src/libpsc/psc.cxx +++ b/src/libpsc/psc.cxx @@ -77,54 +77,18 @@ _psc_read(struct psc *psc, struct mrc_io *io) #endif -// FIXME -void vpic_base_init(int* pargc, char*** pargv) +void psc_init(int& argc, char**& argv) { - static bool vpic_base_inited = false; - - if (vpic_base_inited) { - return; - } - vpic_base_inited = true; - - // boot_services( &argc, &argv ); - { - // Start up the checkpointing service. This should be first. -#ifdef USE_VPIC - boot_checkpt(pargc, pargv); - - serial.boot(pargc, pargv); - thread.boot(pargc, pargv); - - // Boot up the communications layer - // See note above about thread-core-affinity - - boot_mp(pargc, pargv); -#else - int provided; - MPI_Init_thread(pargc, pargv, MPI_THREAD_MULTIPLE, &provided); -#endif + // Start up the checkpointing service. This should be first. + int provided; + MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided); - MPI_Comm_dup(MPI_COMM_WORLD, &psc_comm_world); - MPI_Comm_rank(psc_comm_world, &psc_world_rank); - MPI_Comm_size(psc_comm_world, &psc_world_size); + MPI_Comm_dup(MPI_COMM_WORLD, &psc_comm_world); + MPI_Comm_rank(psc_comm_world, &psc_world_rank); + MPI_Comm_size(psc_comm_world, &psc_world_size); - MPI_Barrier(psc_comm_world); -#ifdef USE_VPIC - _boot_timestamp = 0; - _boot_timestamp = uptime(); -#endif - } - LOG_INFO("vpic_base_init() done\n"); -} + MPI_Barrier(psc_comm_world); -void psc_init(int& argc, char**& argv) -{ -#if 1 - vpic_base_init(&argc, &argv); -#else - MPI_Init(&argc, &argv); -#endif libmrc_params_init(argc, argv); mrc_set_flags(MRC_FLAG_SUPPRESS_UNPREFIXED_OPTION_WARNING); #ifdef USE_CUDA From c903dba4a44cd8ca96d6ad80bcea19db44a3d48a Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 26 May 2026 14:37:10 -0400 Subject: [PATCH 36/46] ->bits; * --- src/include/grid/domain.hxx | 2 +- src/include/input_params.hxx | 2 +- src/libpsc/CMakeLists.txt | 18 ++++++++++-------- .../{vpic/psc_vpic_bits.cxx => bits.cxx} | 2 +- src/libpsc/{vpic/psc_vpic_bits.h => bits.hxx} | 6 +++--- src/libpsc/vpic/Field3D.h | 2 +- src/libpsc/vpic/PscGridBase.h | 2 +- src/libpsc/vpic/PscMaterial.h | 2 +- src/libpsc/vpic/PscParticlesOps.h | 6 +++--- src/libpsc/vpic/PscRng.h | 2 +- src/libpsc/vpic/mfields_state_psc.hxx | 2 +- src/libpsc/vpic/mparticles_vpic.hxx | 2 +- src/libpsc/vpic/tests/testing.cxx | 2 +- 13 files changed, 26 insertions(+), 24 deletions(-) rename src/libpsc/{vpic/psc_vpic_bits.cxx => bits.cxx} (71%) rename src/libpsc/{vpic/psc_vpic_bits.h => bits.hxx} (97%) diff --git a/src/include/grid/domain.hxx b/src/include/grid/domain.hxx index 2e4661c634..141f7dbed8 100644 --- a/src/include/grid/domain.hxx +++ b/src/include/grid/domain.hxx @@ -2,7 +2,7 @@ #include #include -#include "../libpsc/vpic/psc_vpic_bits.h" +#include "../libpsc/bits.hxx" namespace psc { diff --git a/src/include/input_params.hxx b/src/include/input_params.hxx index 1b1f3613a7..c633aedacf 100644 --- a/src/include/input_params.hxx +++ b/src/include/input_params.hxx @@ -8,7 +8,7 @@ #include -#include "../libpsc/vpic/psc_vpic_bits.h" +#include "../libpsc/bits.hxx" namespace { diff --git a/src/libpsc/CMakeLists.txt b/src/libpsc/CMakeLists.txt index 860b266439..d4e7cf0d72 100644 --- a/src/libpsc/CMakeLists.txt +++ b/src/libpsc/CMakeLists.txt @@ -16,18 +16,20 @@ target_gtensor_sources(psc PRIVATE psc_balance/psc_balance.cxx - vpic/psc_vpic_bits.cxx - ) + bits.cxx +) target_include_directories(psc PUBLIC ../include) target_link_libraries(psc PUBLIC kg mrc) target_link_libraries(psc PUBLIC MPI::MPI_CXX) target_link_libraries(psc PUBLIC gtensor::gtensor) + if(USE_CUDA) target_compile_definitions(psc PUBLIC GTENSOR_USE_THRUST) endif() + target_compile_features(psc PUBLIC cxx_std_11) -if (USE_CUDA) +if(USE_CUDA) target_gtensor_sources(psc PRIVATE cuda/cuda_base.cxx @@ -59,19 +61,19 @@ if (USE_CUDA) cuda/cuda_heating.cxx cuda/mem.cxx - ) + ) target_include_directories(psc PUBLIC cuda) endif() -if (PSC_HAVE_RMM) +if(PSC_HAVE_RMM) target_link_libraries(psc PUBLIC rmm::rmm) endif() -if (PSC_BOUNDS_CHECK) +if(PSC_BOUNDS_CHECK) target_compile_definitions(psc PUBLIC BOUNDS_CHECK) endif() -if (USE_VPIC) +if(USE_VPIC) add_library(VPIC::VPIC INTERFACE IMPORTED) set_target_properties(VPIC::VPIC PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "/Users/kai/build/vpic/src" @@ -81,6 +83,6 @@ if (USE_VPIC) target_link_libraries(psc PUBLIC VPIC::VPIC) endif() -if (BUILD_TESTING) +if(BUILD_TESTING) add_subdirectory(tests) endif() diff --git a/src/libpsc/vpic/psc_vpic_bits.cxx b/src/libpsc/bits.cxx similarity index 71% rename from src/libpsc/vpic/psc_vpic_bits.cxx rename to src/libpsc/bits.cxx index 5c2322b9c6..b8f32c3e13 100644 --- a/src/libpsc/vpic/psc_vpic_bits.cxx +++ b/src/libpsc/bits.cxx @@ -1,5 +1,5 @@ -#include "psc_vpic_bits.h" +#include "bits.hxx" MPI_Comm psc_comm_world; int psc_world_rank; diff --git a/src/libpsc/vpic/psc_vpic_bits.h b/src/libpsc/bits.hxx similarity index 97% rename from src/libpsc/vpic/psc_vpic_bits.h rename to src/libpsc/bits.hxx index 3a8d50a76c..6b3d2cb8a2 100644 --- a/src/libpsc/vpic/psc_vpic_bits.h +++ b/src/libpsc/bits.hxx @@ -1,6 +1,6 @@ -#ifndef PSC_VPIC_BITS_H -#define PSC_VPIC_BITS_H +#ifndef BITS_H +#define BITS_H #include @@ -47,7 +47,7 @@ typedef int32_t SpeciesId; // Must be 32-bit wide for particle_injector_t type name[(count)] __attribute__((aligned(align))) // FIXME -#define POW2_CEIL(u, a) (((u) + (a)-1) & (~((a)-1))) +#define POW2_CEIL(u, a) (((u) + (a) - 1) & (~((a) - 1))) // FIXME #ifndef LIKELY diff --git a/src/libpsc/vpic/Field3D.h b/src/libpsc/vpic/Field3D.h index 7b20e1cf84..65d907af8c 100644 --- a/src/libpsc/vpic/Field3D.h +++ b/src/libpsc/vpic/Field3D.h @@ -2,7 +2,7 @@ #ifndef FIELD3D_H #define FIELD3D_H -#include "psc_vpic_bits.h" +#include "../bits.hxx" // ====================================================================== // Field3D diff --git a/src/libpsc/vpic/PscGridBase.h b/src/libpsc/vpic/PscGridBase.h index 69539ce349..5081077f39 100644 --- a/src/libpsc/vpic/PscGridBase.h +++ b/src/libpsc/vpic/PscGridBase.h @@ -2,7 +2,7 @@ #ifndef PSC_GRID_BASE_H #define PSC_GRID_BASE_H -#include "psc_vpic_bits.h" +#include "bits.hxx" #include "kg/Vec3.h" #include diff --git a/src/libpsc/vpic/PscMaterial.h b/src/libpsc/vpic/PscMaterial.h index 2fda8c9092..67fddaab2e 100644 --- a/src/libpsc/vpic/PscMaterial.h +++ b/src/libpsc/vpic/PscMaterial.h @@ -2,7 +2,7 @@ #ifndef PSC_MATERIAL_H #define PSC_MATERIAL_H -#include "psc_vpic_bits.h" +#include "bits.hxx" #include "VpicListBase.h" #include diff --git a/src/libpsc/vpic/PscParticlesOps.h b/src/libpsc/vpic/PscParticlesOps.h index b62e7ada3d..57eeee9472 100644 --- a/src/libpsc/vpic/PscParticlesOps.h +++ b/src/libpsc/vpic/PscParticlesOps.h @@ -1,7 +1,7 @@ #pragma once -#include "psc_vpic_bits.h" +#include "bits.hxx" #ifdef USE_VPIC #define HAS_V4_PIPELINE @@ -553,8 +553,8 @@ struct PscParticlesOps pm[nm++] = local_pm[0]; } else { n_ignored++; // Unlikely - } // if - } // if + } // if + } // if } } diff --git a/src/libpsc/vpic/PscRng.h b/src/libpsc/vpic/PscRng.h index 48e55fe5aa..b68cb00c00 100644 --- a/src/libpsc/vpic/PscRng.h +++ b/src/libpsc/vpic/PscRng.h @@ -5,7 +5,7 @@ #include #include #include "mrc_common.h" -#include "psc_vpic_bits.h" +#include "../bits.hxx" // ====================================================================== // PscRng diff --git a/src/libpsc/vpic/mfields_state_psc.hxx b/src/libpsc/vpic/mfields_state_psc.hxx index 8270009099..b4ca748cf3 100644 --- a/src/libpsc/vpic/mfields_state_psc.hxx +++ b/src/libpsc/vpic/mfields_state_psc.hxx @@ -1,7 +1,7 @@ #pragma once -#include "psc_vpic_bits.h" +#include "bits.hxx" #include "PscFieldBase.h" #include "Field3D.h" #include "fields3d.hxx" diff --git a/src/libpsc/vpic/mparticles_vpic.hxx b/src/libpsc/vpic/mparticles_vpic.hxx index 741f6f3473..4be1f094a5 100644 --- a/src/libpsc/vpic/mparticles_vpic.hxx +++ b/src/libpsc/vpic/mparticles_vpic.hxx @@ -2,7 +2,7 @@ #pragma once #include "particles.hxx" -#include "psc_vpic_bits.h" +#include "../bits.hxx" // ====================================================================== // InjectorVpic diff --git a/src/libpsc/vpic/tests/testing.cxx b/src/libpsc/vpic/tests/testing.cxx index e343c9e4c6..9207244fd5 100644 --- a/src/libpsc/vpic/tests/testing.cxx +++ b/src/libpsc/vpic/tests/testing.cxx @@ -1,7 +1,7 @@ #include "testing.h" -#include "psc_vpic_bits.h" +#include "bits.hxx" #include "src/vpic/vpic.h" From 93dca489d521cd7da2c00bd3ed7a1011445f4203 Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 26 May 2026 14:38:11 -0400 Subject: [PATCH 37/46] bits: pragma once --- src/libpsc/bits.hxx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/libpsc/bits.hxx b/src/libpsc/bits.hxx index 6b3d2cb8a2..0ba941589d 100644 --- a/src/libpsc/bits.hxx +++ b/src/libpsc/bits.hxx @@ -1,6 +1,4 @@ - -#ifndef BITS_H -#define BITS_H +#pragma once #include @@ -99,5 +97,3 @@ typedef int32_t SpeciesId; // Must be 32-bit wide for particle_injector_t mprintf("INFO at %s:%d (%s): ", __FILE__, __LINE__, __func__); \ printf(fmt); \ } while (0) - -#endif From 56485cbb03089a2ab62586e3df21ae4d8ebf4e08 Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 26 May 2026 14:39:43 -0400 Subject: [PATCH 38/46] -mfields_state_psc; * --- src/libpsc/vpic/mfields_state_psc.hxx | 265 -------------------------- src/libpsc/vpic/vpic_config.h | 1 - 2 files changed, 266 deletions(-) delete mode 100644 src/libpsc/vpic/mfields_state_psc.hxx diff --git a/src/libpsc/vpic/mfields_state_psc.hxx b/src/libpsc/vpic/mfields_state_psc.hxx deleted file mode 100644 index b4ca748cf3..0000000000 --- a/src/libpsc/vpic/mfields_state_psc.hxx +++ /dev/null @@ -1,265 +0,0 @@ - -#pragma once - -#include "bits.hxx" -#include "PscFieldBase.h" -#include "Field3D.h" -#include "fields3d.hxx" - -#include -#include -#include - -// ====================================================================== -// PscSfaParams - -template -struct PscSfaParams -{ - using Grid = G; - using MaterialList = ML; - - struct MaterialCoefficient - { - float decayx, drivex; // Decay of ex and drive of (curl H)x and Jx - float decayy, drivey; // Decay of ey and drive of (curl H)y and Jy - float decayz, drivez; // Decay of ez and drive of (curl H)z and Jz - float rmux, rmuy, rmuz; // Reciprocle of relative permeability - float nonconductive; // Divergence cleaning related coefficients - float epsx, epsy, epsz; - float pad[3]; // For 64-byte alignment and future expansion - }; - - PscSfaParams(const Grid* g, const MaterialList& m_list, float damp) - { - // Run sanity checks on the material list - - assert(!m_list.empty()); - assert(damp >= 0.); - this->damp = damp; - - float ax = g->nx > 1 ? g->cvac * g->dt * g->rdx : 0; - ax *= ax; - float ay = g->ny > 1 ? g->cvac * g->dt * g->rdy : 0; - ay *= ay; - float az = g->nz > 1 ? g->cvac * g->dt * g->rdz : 0; - az *= az; - int n_mc = 0; - for (auto m = m_list.cbegin(); m != m_list.cend(); ++m) { - if (m->sigmax / m->epsx < 0) - LOG_WARN("\"%s\" is an active medium along x", m->name); - if (m->epsy * m->muz < 0) - LOG_WARN("\"%s\" has an imaginary x speed of light (ey)", m->name); - if (m->epsz * m->muy < 0) - LOG_WARN("\"%s\" has an imaginary x speed of light (ez)", m->name); - if (m->sigmay / m->epsy < 0) - LOG_WARN("\"%s\" is an active medium along y", m->name); - if (m->epsz * m->mux < 0) - LOG_WARN("\"%s\" has an imaginary y speed of light (ez)", m->name); - if (m->epsx * m->muz < 0) - LOG_WARN("\"%s\" has an imaginary y speed of light (ex)", m->name); - if (m->sigmaz / m->epsz < 0) - LOG_WARN("\"%s\" is an an active medium along z", m->name); - if (m->epsx * m->muy < 0) - LOG_WARN("\"%s\" has an imaginary z speed of light (ex)", m->name); - if (m->epsy * m->mux < 0) - LOG_WARN("\"%s\" has an imaginary z speed of light (ey)", m->name); - float cg2 = (ax / std::min(m->epsy * m->muz, m->epsz * m->muy) + - ay / std::min(m->epsz * m->mux, m->epsx * m->muz) + - az / std::min(m->epsx * m->muy, m->epsy * m->mux)); - if (cg2 >= 1) - LOG_WARN("\"%s\" Courant condition estimate = %e", m->name, sqrt(cg2)); - if (m->zetax != 0 || m->zetay != 0 || m->zetaz != 0) - LOG_WARN("\"%s\" magnetic conductivity is not supported", m->name); - n_mc++; - } - - // Allocate the sfa parameters - - mc_ = new MaterialCoefficient[n_mc + 2]; // FIXME, why +2 ? - n_mc_ = n_mc; - - // Fill up the material coefficient array - - for (auto m = m_list.cbegin(); m != m_list.cend(); ++m) { - assert(m->id < n_mc); - MaterialCoefficient* mc = &mc_[m->id]; - - // Advance E coefficients - // Note: m ->sigma{x,y,z} = 0 -> Non conductive - // mc->decay{x,y,z} = 0 -> Perfect conductor to numerical precision - // otherwise -> Conductive - float ax = (m->sigmax * g->dt) / (m->epsx * g->eps0); - float ay = (m->sigmay * g->dt) / (m->epsy * g->eps0); - float az = (m->sigmaz * g->dt) / (m->epsz * g->eps0); - mc->decayx = exp(-ax); - mc->decayy = exp(-ay); - mc->decayz = exp(-az); - if (ax == 0) - mc->drivex = 1. / m->epsx; - else if (mc->decayx == 0) - mc->drivex = 0; - else - mc->drivex = 2. * exp(-0.5 * ax) * sinh(0.5 * ax) / (ax * m->epsx); - if (ay == 0) - mc->drivey = 1. / m->epsy; - else if (mc->decayy == 0) - mc->drivey = 0; - else - mc->drivey = 2. * exp(-0.5 * ay) * sinh(0.5 * ay) / (ay * m->epsy); - if (az == 0) - mc->drivez = 1. / m->epsz; - else if (mc->decayz == 0) - mc->drivez = 0; - else - mc->drivez = 2. * exp(-0.5 * az) * sinh(0.5 * az) / (az * m->epsz); - mc->rmux = 1. / m->mux; - mc->rmuy = 1. / m->muy; - mc->rmuz = 1. / m->muz; - - // Clean div E coefficients. Note: The charge density due to J = - // sigma E currents is not computed. Consequently, the divergence - // error inside conductors cannot computed. The divergence error - // multiplier is thus set to zero to ignore divergence errors - // inside conducting materials. - - mc->nonconductive = (ax == 0 && ay == 0 && az == 0) ? 1. : 0.; - mc->epsx = m->epsx; - mc->epsy = m->epsy; - mc->epsz = m->epsz; - } - } - - ~PscSfaParams() { delete[] mc_; } - - const MaterialCoefficient* operator[](int i) const { return &mc_[i]; } - int size() const { return n_mc_; } - - float damp; - -private: - MaterialCoefficient* mc_; - int n_mc_; -}; - -// ====================================================================== -// MfieldsStatePsc - -struct MfieldsStatePscElement -{ - float ex, ey, ez, div_e_err; // Electric field and div E error - float cbx, cby, cbz, div_b_err; // Magnetic field and div B error - float tcax, tcay, tcaz, rhob; // TCA fields and bound charge density - float jfx, jfy, jfz, rhof; // Free current and charge density - MaterialId ematx, ematy, ematz, nmat; // Material at edge centers and nodes - MaterialId fmatx, fmaty, fmatz, cmat; // Material at face and cell centers -}; - -template -struct MfieldsStatePsc -{ - using Grid = _Grid; - using MaterialList = _MaterialList; - using SfaParams = PscSfaParams; - using MaterialCoefficient = typename SfaParams::MaterialCoefficient; - using real_t = float; - using Real = real_t; - using Element = MfieldsStatePscElement; - using space = gt::space::host; - using Storage = gt::gtensor; - - // FIXME, have to settle on BX or CBX... - enum - { - CBX = 4, - CBY = 5, - CBZ = 6, - }; - - enum - { - EX = 0, - EY = 1, - EZ = 2, - DIV_E_ERR = 3, - BX = 4, - BY = 5, - BZ = 6, - DIV_B_ERR = 7, - TCAX = 8, - TCAY = 9, - TCAZ = 10, - RHOB = 11, - JFX = 12, - JFY = 13, - JFZ = 14, - RHOF = 15, - N_COMP = 20, - }; - - struct Patch - { - using Element = MfieldsStatePscElement; - - Patch(Grid* vgrid) : fa_{vgrid} {} - - Element* data() { return fa_.data(); } - Grid* grid() { return fa_.grid(); } - Element operator[](int idx) const { return fa_[idx]; } - Element& operator[](int idx) { return fa_[idx]; } - - // These operators can be used to access the field directly, - // though the performance isn't great, so one should use Field3D - // when performance is important - static const int N_COMP = sizeof(Element) / sizeof(float); - - float operator()(int m, int i, int j, int k) const - { - float* f = reinterpret_cast(data()); - return f[VOXEL(i, j, k, grid()->nx, grid()->ny, grid()->nz) * N_COMP + m]; - } - - float& operator()(int m, int i, int j, int k) - { - float* f = reinterpret_cast(data()); - return f[VOXEL(i, j, k, grid()->nx, grid()->ny, grid()->nz) * N_COMP + m]; - } - - private: - PscFieldBase fa_; - }; - - using fields_view_t = kg::SArrayView; - - MfieldsStatePsc(const Grid_t& grid, Grid* vgrid, - const MaterialList& material_list, double damp = 0.) - : grid_{grid}, patch_{vgrid}, params_{vgrid, material_list, real_t(damp)} - { - assert(grid.n_patches() == 1); - - const int B = 1; // VPIC always uses one ghost cell (on c.c. grid) - im_ = {vgrid->nx + 2 * B, vgrid->ny + 2 * B, vgrid->nz + 2 * B}; - ib_ = {-B, -B, -B}; - } - - real_t* data() { return reinterpret_cast(patch_.data()); } - fields_view_t operator[](int p) { return {{ib_, im_}, N_COMP, data()}; } - Patch& getPatch(int p) { return patch_; } - - SfaParams& params() { return params_; } - Grid& vgrid() - { - return *patch_.grid(); - } // FIXME, const version would be better - - const Grid_t& grid() const { return grid_; } - int n_patches() const { return grid_.n_patches(); } - int n_comps() const { return N_COMP; } - Int3 ibn() const { return {1, 1, 1}; } - -private: - const Grid_t& grid_; - Patch patch_; - Int3 ib_, im_; - SfaParams params_; -}; diff --git a/src/libpsc/vpic/vpic_config.h b/src/libpsc/vpic/vpic_config.h index 377ae16223..384932f250 100644 --- a/src/libpsc/vpic/vpic_config.h +++ b/src/libpsc/vpic/vpic_config.h @@ -19,7 +19,6 @@ #include "PscGridBase.h" #include "PscMaterial.h" -#include "mfields_state_psc.hxx" #include "PscFieldArrayLocalOps.h" #include "PscFieldArrayRemoteOps.h" #include "PscFieldArray.h" From 2bc45c26bcf78ecf3f2c2c6cb0c16f573ca86ce9 Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 26 May 2026 14:50:37 -0400 Subject: [PATCH 39/46] -vpic_config, -rng; * --- src/include/rngpool_iface.h | 23 --------- src/libpsc/CMakeLists.txt | 1 - src/libpsc/rngpool.cxx | 33 ------------- src/libpsc/tests/CMakeLists.txt | 1 - src/libpsc/tests/test_rng.cxx | 28 ----------- src/libpsc/vpic/PscRng.h | 74 ---------------------------- src/libpsc/vpic/vpic_config.h | 85 --------------------------------- 7 files changed, 245 deletions(-) delete mode 100644 src/include/rngpool_iface.h delete mode 100644 src/libpsc/rngpool.cxx delete mode 100644 src/libpsc/tests/test_rng.cxx delete mode 100644 src/libpsc/vpic/PscRng.h delete mode 100644 src/libpsc/vpic/vpic_config.h diff --git a/src/include/rngpool_iface.h b/src/include/rngpool_iface.h deleted file mode 100644 index 06fa18dc9a..0000000000 --- a/src/include/rngpool_iface.h +++ /dev/null @@ -1,23 +0,0 @@ - -#ifndef RNGPOOL_IFACE_H -#define RNGPOOL_IFACE_H - -#include - -#ifndef VPIC_CONFIG_H -typedef struct RngPool_ RngPool; -typedef struct Rng_ Rng; -#endif - -BEGIN_C_DECLS - -RngPool* RngPool_create(); -void RngPool_delete(RngPool* rngpool); -void RngPool_seed(RngPool* rngpool, int base); -Rng* RngPool_get(RngPool* rngpool, int n); -double Rng_uniform(Rng* rng, double lo, double hi); -double Rng_normal(Rng* rng, double mu, double sigma); - -END_C_DECLS - -#endif diff --git a/src/libpsc/CMakeLists.txt b/src/libpsc/CMakeLists.txt index d4e7cf0d72..293d3862b6 100644 --- a/src/libpsc/CMakeLists.txt +++ b/src/libpsc/CMakeLists.txt @@ -10,7 +10,6 @@ target_gtensor_sources(psc PRIVATE psc_fields_single.cxx psc_particles_impl.cxx psc_stats.cxx - rngpool.cxx psc_collision/psc_collision_impl.cxx diff --git a/src/libpsc/rngpool.cxx b/src/libpsc/rngpool.cxx deleted file mode 100644 index ca5f1eeb51..0000000000 --- a/src/libpsc/rngpool.cxx +++ /dev/null @@ -1,33 +0,0 @@ - -#include "vpic/PscRng.h" // FIXME path - -#define VPIC_CONFIG_H // FIXME, bad hack - -using Rng = PscRng; -using RngPool = PscRngPool; - -#include "rngpool_iface.h" - -// ---------------------------------------------------------------------- -// RngPool - -RngPool* RngPool_create() { return new RngPool; } - -void RngPool_delete(RngPool* rngpool) { delete rngpool; } - -void RngPool_seed(RngPool* rngpool, int base) { rngpool->seed(base, 0); } - -Rng* RngPool_get(RngPool* rngpool, int n) { return (*rngpool)[n]; } - -// ---------------------------------------------------------------------- -// Rng - -double Rng_uniform(Rng* rng, double lo, double hi) -{ - return rng->uniform(lo, hi); -} - -double Rng_normal(Rng* rng, double mu, double sigma) -{ - return rng->normal(mu, sigma); -} diff --git a/src/libpsc/tests/CMakeLists.txt b/src/libpsc/tests/CMakeLists.txt index 6ed4f28823..44266b601a 100644 --- a/src/libpsc/tests/CMakeLists.txt +++ b/src/libpsc/tests/CMakeLists.txt @@ -19,7 +19,6 @@ endmacro() add_psc_test(test_grid) add_psc_test(test_grid_2) -add_psc_test(test_rng) add_psc_test(test_mparticles_cuda) add_psc_test(test_mparticles) add_psc_test(test_output_particles) diff --git a/src/libpsc/tests/test_rng.cxx b/src/libpsc/tests/test_rng.cxx deleted file mode 100644 index 22afc0ff79..0000000000 --- a/src/libpsc/tests/test_rng.cxx +++ /dev/null @@ -1,28 +0,0 @@ - -#include - -#include "../vpic/PscRng.h" - -using Rng = PscRng; -using RngPool = PscRngPool; - -TEST(Rng, RngPool) -{ - RngPool rngpool; - Rng* rng = rngpool[0]; - - for (int i = 0; i < 100; ++i) { - double r = rng->uniform(0., 1000.); - EXPECT_GE(r, 0.); - EXPECT_LE(r, 1000.); - } -} - -int main(int argc, char** argv) -{ - MPI_Init(&argc, &argv); - ::testing::InitGoogleTest(&argc, argv); - int rc = RUN_ALL_TESTS(); - MPI_Finalize(); - return rc; -} diff --git a/src/libpsc/vpic/PscRng.h b/src/libpsc/vpic/PscRng.h deleted file mode 100644 index b68cb00c00..0000000000 --- a/src/libpsc/vpic/PscRng.h +++ /dev/null @@ -1,74 +0,0 @@ - -#ifndef PSC_RNG_H -#define PSC_RNG_H - -#include -#include -#include "mrc_common.h" -#include "../bits.hxx" - -// ====================================================================== -// PscRng - -struct PscRng -{ - typedef std::mt19937 Urng; - typedef std::uniform_real_distribution Uniform; - typedef std::normal_distribution Normal; - - static PscRng* create() { return new PscRng; } - - void seed(unsigned int seed) { urng_.seed(seed); } - unsigned int operator()() { return urng_(); } - static constexpr unsigned int min() { return Urng::min(); } - static constexpr unsigned int max() { return Urng::max(); } - - double uniform(double lo, double hi) - { - Uniform::param_type prm(lo, hi); - return uniform_(urng_, prm); - } - - double normal(double mu, double sigma) - { - Normal::param_type prm(mu, sigma); - return normal_(urng_, prm); - } - -private: - Urng urng_; - Uniform uniform_; - Normal normal_; -}; - -// ====================================================================== -// PscRngPool - -template -struct PscRngPool -{ - typedef R Rng; - - PscRngPool() - : rng_(Rng::create()), - n_rng_(2) // not really needed, but kept to keep seeds the same as vpic - {} - - void seed(int base, int which) - { - assert(which == 0); - int seed = psc_world_rank + (psc_world_size + 1) * n_rng_ * base; - rng_->seed(seed); - } - - Rng* operator[](int n) - { - assert(n == 0); - return rng_; - } - - Rng* rng_; - int n_rng_; -}; - -#endif diff --git a/src/libpsc/vpic/vpic_config.h b/src/libpsc/vpic/vpic_config.h deleted file mode 100644 index 384932f250..0000000000 --- a/src/libpsc/vpic/vpic_config.h +++ /dev/null @@ -1,85 +0,0 @@ - -#ifndef VPIC_CONFIG_H -#define VPIC_CONFIG_H - -//#define DO_VPIC 1 - -#ifdef USE_VPIC -#include "util/profile/profile.h" -#else -//#include "util/profile/profile.h" -//#undef TIC -//#undef TOC -#define TIC -#define TOC(a, b) -#endif - -#include "PscRng.h" - -#include "PscGridBase.h" -#include "PscMaterial.h" - -#include "PscFieldArrayLocalOps.h" -#include "PscFieldArrayRemoteOps.h" -#include "PscFieldArray.h" - -#include "PscParticleBc.h" - -#include "mparticles_vpic.hxx" -#include "PscParticlesBase.h" -#include "PscParticlesOps.h" - -#include "mfields_interpolator_psc.hxx" -#include "PscInterpolator.h" - -#include "PscAccumulator.h" -#include "mfields_accumulator_psc.hxx" - -#include "mfields_hydro.hxx" - -#include "NoneDiag.h" - -struct VpicConfigPsc -{ - using Grid = PscGridBase; - - using ParticleBcList = PscParticleBcList; - using Particles = PscParticlesBase; - using Mparticles = MparticlesVpic_; - - using MaterialList = PscMaterialList; - using MfieldsState = MfieldsStatePsc; - - using FieldArrayLocalOps = PscFieldArrayLocalOps; - using FieldArrayRemoteOps = PscFieldArrayRemoteOps; - using AccumulateOps = - PscAccumulateOps; - - using MfieldsInterpolator = MfieldsInterpolatorPsc; - using InterpolatorOps = PscInterpolatorOps; - - using MfieldsAccumulator = MfieldsAccumulatorPsc; - using AccumulatorOps = PscAccumulatorOps; - - using MfieldsHydro = MfieldsHydroPsc; - - using ParticlesOps = - PscParticlesOps; - - /* #ifdef DO_VPIC */ - /* using DiagOps = VpicDiagOps; */ - /* #else */ - /* using DiagOps = PscDiagOps; */ - /* #endif */ -}; - -#if 1 -typedef PscRng Rng; -typedef PscRngPool RngPool; -#else -typedef VpicRng Rng; -typedef VpicRngPool RngPool; -#endif - -#endif From 987ac9c132ae0ccfec3de92066460b8de309f220 Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 26 May 2026 14:51:49 -0400 Subject: [PATCH 40/46] -test_PscFieldArray --- src/libpsc/vpic/tests/test_PscFieldArray.cxx | 31 -------------------- 1 file changed, 31 deletions(-) delete mode 100644 src/libpsc/vpic/tests/test_PscFieldArray.cxx diff --git a/src/libpsc/vpic/tests/test_PscFieldArray.cxx b/src/libpsc/vpic/tests/test_PscFieldArray.cxx deleted file mode 100644 index f698bc1798..0000000000 --- a/src/libpsc/vpic/tests/test_PscFieldArray.cxx +++ /dev/null @@ -1,31 +0,0 @@ - -#include "testing.h" - -#include "test_FieldArray.h" - -#include "PscGridBase.h" -#include "PscMaterial.h" -#include "PscFieldArrayBase.h" -#include "PscFieldArrayLocalOps.h" -#include "VpicFieldArrayRemoteOps.h" -#include "PscFieldArray.h" - -void test_PscFieldArray() -{ - typedef PscGridBase Grid; - typedef PscMaterialList MaterialList; - typedef PscFieldArrayBase FieldArrayBase; - typedef PscFieldArrayLocalOps FieldArrayLocalOps; - typedef PscFieldArrayRemoteOps FieldArrayRemoteOps; - typedef PscFieldArray - FieldArray; - - test_FieldArray(); -} - -int main(int argc, char** argv) -{ - testing_init(&argc, &argv); - - test_PscFieldArray(); -} From ebf1c15b093d6ab4fd25043ec17af188f597ab84 Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 26 May 2026 14:51:54 -0400 Subject: [PATCH 41/46] -PscMaterial --- src/libpsc/vpic/PscMaterial.h | 84 ----------------------------------- 1 file changed, 84 deletions(-) delete mode 100644 src/libpsc/vpic/PscMaterial.h diff --git a/src/libpsc/vpic/PscMaterial.h b/src/libpsc/vpic/PscMaterial.h deleted file mode 100644 index 67fddaab2e..0000000000 --- a/src/libpsc/vpic/PscMaterial.h +++ /dev/null @@ -1,84 +0,0 @@ - -#ifndef PSC_MATERIAL_H -#define PSC_MATERIAL_H - -#include "bits.hxx" -#include "VpicListBase.h" - -#include -#include -#include - -// ====================================================================== -// PscMaterial - -struct PscMaterial -{ - PscMaterial(const char* name, float epsx, float epsy, float epsz, float mux, - float muy, float muz, float sigmax, float sigmay, float sigmaz, - float zetax, float zetay, float zetaz) - { - int len = name ? strlen(name) : 0; - if (!len) - LOG_ERROR("Cannot create a nameless material"); - this->name = strdup(name); - this->epsx = epsx, this->epsy = epsy, this->epsz = epsz; - this->mux = mux, this->muy = muy, this->muz = muz; - this->sigmax = sigmax, this->sigmay = sigmay, this->sigmaz = sigmaz; - this->zetax = zetax, this->zetay = zetay, this->zetaz = zetaz; - this->next = nullptr; - } - - ~PscMaterial() { free(name); } - - char* name; // Name of the material - float epsx, epsy, epsz; // Relative permittivity along x,y,z axes - float mux, muy, muz; // Relative permeability along x,y,z axes - float sigmax, sigmay, sigmaz; // Electrical conductivity along x,y,z axes - float zetax, zetay, zetaz; // Magnetic conductivity along x,y,z axes - MaterialId id; // Unique identifier for material - PscMaterial* next; // Next material in list -}; - -// ====================================================================== -// PscMaterialList - -struct PscMaterialList : public VpicListBase -{ - typedef PscMaterial Material; - - static Material* create(const char* name, float epsx, float epsy, float epsz, - float mux, float muy, float muz, float sigmax, - float sigmay, float sigmaz, float zetax, float zetay, - float zetaz) - { - return new Material(name, epsx, epsy, epsz, mux, muy, muz, sigmax, sigmay, - sigmaz, zetax, zetay, zetaz); - } - - const_iterator find(const char* name) const - { - assert(name); - return std::find_if(cbegin(), cend(), [&name](const Material& m) { - return strcmp(m.name, name) == 0; - }); - } - - Material* append(Material* m) - { - assert(!m->next); - if (find(m->name) != cend()) { - LOG_ERROR("There is already a material named \"%s\" in list", m->name); - } - int id = size(); - if (id >= MaterialIdMax) { - LOG_ERROR("Too many materials in list to append material \"%s\"", - m->name); - } - m->id = id; - push_front(*m); - return m; - } -}; - -#endif From c44e7b01b086537f12459a699dab76d5e1f95e15 Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 26 May 2026 14:52:33 -0400 Subject: [PATCH 42/46] -vpic/tests --- src/libpsc/vpic/tests/.gitignore | 5 -- src/libpsc/vpic/tests/test_FieldArray.h | 63 ------------------- src/libpsc/vpic/tests/test_GridBase.h | 47 -------------- src/libpsc/vpic/tests/test_InterpolatorBase.h | 41 ------------ src/libpsc/vpic/tests/test_PscGridBase.cxx | 14 ----- .../vpic/tests/test_PscInterpolatorBase.cxx | 16 ----- src/libpsc/vpic/tests/test_VpicGridBase.cxx | 14 ----- src/libpsc/vpic/tests/testing.cxx | 24 ------- src/libpsc/vpic/tests/testing.h | 7 --- 9 files changed, 231 deletions(-) delete mode 100644 src/libpsc/vpic/tests/.gitignore delete mode 100644 src/libpsc/vpic/tests/test_FieldArray.h delete mode 100644 src/libpsc/vpic/tests/test_GridBase.h delete mode 100644 src/libpsc/vpic/tests/test_InterpolatorBase.h delete mode 100644 src/libpsc/vpic/tests/test_PscGridBase.cxx delete mode 100644 src/libpsc/vpic/tests/test_PscInterpolatorBase.cxx delete mode 100644 src/libpsc/vpic/tests/test_VpicGridBase.cxx delete mode 100644 src/libpsc/vpic/tests/testing.cxx delete mode 100644 src/libpsc/vpic/tests/testing.h diff --git a/src/libpsc/vpic/tests/.gitignore b/src/libpsc/vpic/tests/.gitignore deleted file mode 100644 index 91f44d9941..0000000000 --- a/src/libpsc/vpic/tests/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ - -test_VpicGridBase -test_PscGridBase -test_PscInterpolatorBase -test_PscFieldArray diff --git a/src/libpsc/vpic/tests/test_FieldArray.h b/src/libpsc/vpic/tests/test_FieldArray.h deleted file mode 100644 index 0ab4443dad..0000000000 --- a/src/libpsc/vpic/tests/test_FieldArray.h +++ /dev/null @@ -1,63 +0,0 @@ - -#ifndef TEST_FIELD_ARRAY_H -#define TEST_FIELD_ARRAY_H - -#include "test_GridBase.h" - -template -FieldArray* test_FieldArray_create(typename FieldArray::Grid* g) -{ - typename FieldArray::MaterialList material_list; - material_list.append(material_list.create("vacuum", 1., 1., 1., 1., 1., 1., - 0., 0., 0., 0., 0., 0.)); - - return FieldArray::create(g, material_list, 0.); -} - -template -void test_FieldArray_methods(FieldArray& fa) -{ - double en[6]; - fa.energy_f(en); - - fa.advance_b(1.); - fa.advance_e(1.); - - fa.clear_jf(); - fa.synchronize_jf(); - fa.clear_rhof(); - fa.synchronize_rho(); - - fa.compute_rhob(); - fa.compute_curl_b(); - - fa.synchronize_tang_e_norm_b(); - - fa.compute_div_e_err(); - fa.compute_rms_div_e_err(); - fa.clean_div_e(); - - fa.compute_div_b_err(); - fa.compute_rms_div_b_err(); - fa.clean_div_b(); -} - -template -void test_FieldArray_destroy(FieldArray* fa) -{ - // FIXME -} - -template -void test_FieldArray() -{ - auto* g = test_GridBase_create(); - - FieldArray* fa = test_FieldArray_create(g); - test_FieldArray_methods(*fa); - test_FieldArray_destroy(fa); - - test_GridBase_destroy(g); -} - -#endif diff --git a/src/libpsc/vpic/tests/test_GridBase.h b/src/libpsc/vpic/tests/test_GridBase.h deleted file mode 100644 index 7dfd49d252..0000000000 --- a/src/libpsc/vpic/tests/test_GridBase.h +++ /dev/null @@ -1,47 +0,0 @@ - -#ifndef TEST_GRID_BASE_H -#define TEST_GRID_BASE_H - -template -Grid* test_GridBase_create() -{ - int gdims[3] = {16, 32, 1}; - double xl[3] = {-1., -2., -4.}; - double xh[3] = {1., 2., 4.}; - int np[3] = {1, 1, 1}; - double dt = .05; - double cvac = 1.; - double eps0 = 1.; - - double dx[3]; - for (int d = 0; d < 3; d++) { - dx[d] = (xh[d] - xl[d]) / gdims[d]; - } - - Grid* grid = Grid::create(); - grid->setup(dx, dt, cvac, eps0); - grid->partition_periodic_box(xl, xh, gdims, np); - - return grid; -} - -template -void test_GridBase_methods(Grid* g) -{ - (void)g->mp_send_buffer(1); - (void)g->mp_recv_buffer(1); -} - -template -void test_GridBase_destroy(Grid* g) -{} - -template -void test_GridBase() -{ - Grid* g = test_GridBase_create(); - test_GridBase_methods(g); - test_GridBase_destroy(g); -} - -#endif diff --git a/src/libpsc/vpic/tests/test_InterpolatorBase.h b/src/libpsc/vpic/tests/test_InterpolatorBase.h deleted file mode 100644 index 36a37b00e2..0000000000 --- a/src/libpsc/vpic/tests/test_InterpolatorBase.h +++ /dev/null @@ -1,41 +0,0 @@ - -#ifndef TEST_INTERPOLATOR_BASE_H -#define TEST_INTERPOLATOR_BASE_H - -#include "test_GridBase.h" -#include "test_InterpolatorBase.h" - -template -InterpolatorBase* test_InterpolatorBase_create( - typename InterpolatorBase::Grid* g) -{ - return InterpolatorBase::create(g); -} - -template -void test_InterpolatorBase_methods(InterpolatorBase* interpolator) -{ - typename InterpolatorBase::Grid* g = interpolator->grid(); - (void)g; -} - -template -void test_InterpolatorBase_destroy(InterpolatorBase* fa) -{ - // FIXME -} - -template -void test_InterpolatorBase() -{ - auto* g = test_GridBase_create(); - - InterpolatorBase* interpolator = - test_InterpolatorBase_create(g); - test_InterpolatorBase_methods(interpolator); - test_InterpolatorBase_destroy(interpolator); - - test_GridBase_destroy(g); -} - -#endif diff --git a/src/libpsc/vpic/tests/test_PscGridBase.cxx b/src/libpsc/vpic/tests/test_PscGridBase.cxx deleted file mode 100644 index cfeba76127..0000000000 --- a/src/libpsc/vpic/tests/test_PscGridBase.cxx +++ /dev/null @@ -1,14 +0,0 @@ - -#include "testing.h" -#include "test_GridBase.h" - -#include "PscGridBase.h" - -int main(int argc, char** argv) -{ - testing_init(&argc, &argv); - - typedef PscGridBase Grid; - - test_GridBase(); -} diff --git a/src/libpsc/vpic/tests/test_PscInterpolatorBase.cxx b/src/libpsc/vpic/tests/test_PscInterpolatorBase.cxx deleted file mode 100644 index edbfdb7ba1..0000000000 --- a/src/libpsc/vpic/tests/test_PscInterpolatorBase.cxx +++ /dev/null @@ -1,16 +0,0 @@ - -#include "testing.h" -#include "test_InterpolatorBase.h" - -#include "PscGridBase.h" -#include "PscInterpolatorBase.h" - -int main(int argc, char** argv) -{ - testing_init(&argc, &argv); - - typedef PscGridBase Grid; - typedef PscInterpolatorBase InterpolatorBase; - - test_InterpolatorBase(); -} diff --git a/src/libpsc/vpic/tests/test_VpicGridBase.cxx b/src/libpsc/vpic/tests/test_VpicGridBase.cxx deleted file mode 100644 index 9bdac88a22..0000000000 --- a/src/libpsc/vpic/tests/test_VpicGridBase.cxx +++ /dev/null @@ -1,14 +0,0 @@ - -#include "testing.h" -#include "test_GridBase.h" - -#include "VpicGridBase.h" - -int main(int argc, char** argv) -{ - testing_init(&argc, &argv); - - typedef VpicGridBase Grid; - - test_GridBase(); -} diff --git a/src/libpsc/vpic/tests/testing.cxx b/src/libpsc/vpic/tests/testing.cxx deleted file mode 100644 index 9207244fd5..0000000000 --- a/src/libpsc/vpic/tests/testing.cxx +++ /dev/null @@ -1,24 +0,0 @@ - -#include "testing.h" - -#include "bits.hxx" - -#include "src/vpic/vpic.h" - -MPI_Comm psc_comm_world; -int psc_world_rank; -int psc_world_size; - -void testing_init(int* argc, char*** argv) -{ - boot_checkpt(argc, argv); - serial.boot(argc, argv); - thread.boot(argc, argv); - - boot_mp(argc, argv); - // MPI_Init(argc, argv); - - MPI_Comm_dup(MPI_COMM_WORLD, &psc_comm_world); - MPI_Comm_rank(psc_comm_world, &psc_world_rank); - MPI_Comm_size(psc_comm_world, &psc_world_size); -} diff --git a/src/libpsc/vpic/tests/testing.h b/src/libpsc/vpic/tests/testing.h deleted file mode 100644 index e52c9b3e96..0000000000 --- a/src/libpsc/vpic/tests/testing.h +++ /dev/null @@ -1,7 +0,0 @@ - -#ifndef TESTING_H -#define TESTING_H - -void testing_init(int* argc, char*** argv); - -#endif From 6c5d890a440f3e40880d899d6667a5fd2aaa189c Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 26 May 2026 14:56:11 -0400 Subject: [PATCH 43/46] -vpic; * --- src/include/psc.hxx | 1 - .../output_particles_hdf5_impl.hxx | 16 - src/libpsc/vpic/Field3D.h | 63 - src/libpsc/vpic/GridLoop.h | 368 ---- src/libpsc/vpic/NoneDiag.h | 20 - src/libpsc/vpic/PscAccumulator.h | 102 -- src/libpsc/vpic/PscFieldArray.h | 287 --- src/libpsc/vpic/PscFieldArrayLocalOps.h | 454 ----- src/libpsc/vpic/PscFieldArrayRemoteOps.h | 191 -- src/libpsc/vpic/PscFieldBase.h | 49 - src/libpsc/vpic/PscGridBase.h | 503 ------ src/libpsc/vpic/PscInterpolator.h | 85 - src/libpsc/vpic/PscParticleBc.h | 35 - src/libpsc/vpic/PscParticlesBase.h | 312 ---- src/libpsc/vpic/PscParticlesOps.h | 1564 ----------------- src/libpsc/vpic/VpicFieldArrayLocalOps.h | 46 - src/libpsc/vpic/VpicFieldArrayRemoteOps.h | 37 - src/libpsc/vpic/VpicGridBase.h | 92 - src/libpsc/vpic/VpicListBase.h | 113 -- src/libpsc/vpic/VpicMaterial.h | 39 - src/libpsc/vpic/fields_item_vpic.hxx | 193 -- src/libpsc/vpic/mfields_accumulator_psc.hxx | 83 - src/libpsc/vpic/mfields_interpolator_psc.hxx | 47 - src/libpsc/vpic/mparticles_vpic.hxx | 365 ---- src/libpsc/vpic/psc_hydro_ops.hxx | 687 -------- src/libpsc/vpic/vpic_iface.h | 95 - src/psc_config.hxx | 2 - 27 files changed, 5849 deletions(-) delete mode 100644 src/libpsc/vpic/Field3D.h delete mode 100644 src/libpsc/vpic/GridLoop.h delete mode 100644 src/libpsc/vpic/NoneDiag.h delete mode 100644 src/libpsc/vpic/PscAccumulator.h delete mode 100644 src/libpsc/vpic/PscFieldArray.h delete mode 100644 src/libpsc/vpic/PscFieldArrayLocalOps.h delete mode 100644 src/libpsc/vpic/PscFieldArrayRemoteOps.h delete mode 100644 src/libpsc/vpic/PscFieldBase.h delete mode 100644 src/libpsc/vpic/PscGridBase.h delete mode 100644 src/libpsc/vpic/PscInterpolator.h delete mode 100644 src/libpsc/vpic/PscParticleBc.h delete mode 100644 src/libpsc/vpic/PscParticlesBase.h delete mode 100644 src/libpsc/vpic/PscParticlesOps.h delete mode 100644 src/libpsc/vpic/VpicFieldArrayLocalOps.h delete mode 100644 src/libpsc/vpic/VpicFieldArrayRemoteOps.h delete mode 100644 src/libpsc/vpic/VpicGridBase.h delete mode 100644 src/libpsc/vpic/VpicListBase.h delete mode 100644 src/libpsc/vpic/VpicMaterial.h delete mode 100644 src/libpsc/vpic/fields_item_vpic.hxx delete mode 100644 src/libpsc/vpic/mfields_accumulator_psc.hxx delete mode 100644 src/libpsc/vpic/mfields_interpolator_psc.hxx delete mode 100644 src/libpsc/vpic/mparticles_vpic.hxx delete mode 100644 src/libpsc/vpic/psc_hydro_ops.hxx delete mode 100644 src/libpsc/vpic/vpic_iface.h diff --git a/src/include/psc.hxx b/src/include/psc.hxx index 1edd9e2d14..364f7d9cf6 100644 --- a/src/include/psc.hxx +++ b/src/include/psc.hxx @@ -7,7 +7,6 @@ #include #include -#include "../libpsc/vpic/fields_item_vpic.hxx" #include "gauss_corrector_base.hxx" #include "diagnostic_base.hxx" #include "injector_base.hxx" diff --git a/src/libpsc/psc_output_particles/output_particles_hdf5_impl.hxx b/src/libpsc/psc_output_particles/output_particles_hdf5_impl.hxx index 02f9d547b9..604cf95319 100644 --- a/src/libpsc/psc_output_particles/output_particles_hdf5_impl.hxx +++ b/src/libpsc/psc_output_particles/output_particles_hdf5_impl.hxx @@ -11,7 +11,6 @@ #include "diagnostic_base.hxx" #include "psc_particles_single.h" -#include "../libpsc/vpic/mparticles_vpic.hxx" #ifdef USE_CUDA #include "mparticles_cuda.hxx" #endif @@ -820,21 +819,6 @@ public: prof_stop(pr_all); } - // FIXME, handles MparticlesVpic by conversion for now - template - void operator()(MparticlesVpic_& mprts) - { - const auto& grid = mprts.grid(); - - if (params_.every_step <= 0 || grid.timestep() % params_.every_step != 0) { - return; - } - - auto& mprts_single = mprts.template get_as(); - (*this)(mprts_single); - mprts.put_as(mprts_single, MP_DONT_COPY); - } - #ifdef USE_CUDA // FIXME, handles MparticlesCuda by conversion for now template diff --git a/src/libpsc/vpic/Field3D.h b/src/libpsc/vpic/Field3D.h deleted file mode 100644 index 65d907af8c..0000000000 --- a/src/libpsc/vpic/Field3D.h +++ /dev/null @@ -1,63 +0,0 @@ - -#ifndef FIELD3D_H -#define FIELD3D_H - -#include "../bits.hxx" - -// ====================================================================== -// Field3D -// -// A class to accelerate 3-d field access -// It works for VpicFieldArray and VpicInterpolatorArray, but should -// be generalized to work without knowing their internals - -template -struct Field3D -{ - typedef FA Array; - typedef typename FA::Element Element; - - Field3D(Array& fa) - : sx_(fa.grid()->nx + 2), sy_(fa.grid()->ny + 2), f_(fa.data()) - {} - - int voxel(int i, int j, int k) const { return i + sx_ * (j + sy_ * (k)); } - - // FIXME, this is an odd mix of two interfaces - // first field3d just being used for grid information, - // and providing access to the whole struct - // This interface can't easily be converted to SOA - Element& operator()(Array& fa, int i, int j, int k) - { - return fa.data()[voxel(i, j, k)]; - } - - Element operator()(Array& fa, int i, int j, int k) const - { - return fa.data()[voxel(i, j, k)]; - } - - Element& operator()(int i, int j, int k) { return f_[voxel(i, j, k)]; } - - Element operator()(int i, int j, int k) const { return f_[voxel(i, j, k)]; } - - // second, access to a particular component, but this one is - // for the specific Array used at construction time - float& operator()(int m, int i, int j, int k) - { - float* RESTRICT f = reinterpret_cast(f_); - return f[m + Array::N_COMP * voxel(i, j, k)]; - } - - float operator()(int m, int i, int j, int k) const - { - float* RESTRICT f = reinterpret_cast(f_); - return f[m + Array::N_COMP * voxel(i, j, k)]; - } - -private: - int sx_, sy_; - Element* RESTRICT f_; -}; - -#endif diff --git a/src/libpsc/vpic/GridLoop.h b/src/libpsc/vpic/GridLoop.h deleted file mode 100644 index 6dc8514a5d..0000000000 --- a/src/libpsc/vpic/GridLoop.h +++ /dev/null @@ -1,368 +0,0 @@ - -#ifndef GRID_LOOP_H -#define GRID_LOOP_H - -// ====================================================================== -// foreach - -template -static void foreach (F f, int ib, int ie, int jb, int je, int kb, int ke) -{ - for (int k = kb; k <= ke; k++) { - for (int j = jb; j <= je; j++) { - for (int i = ib; i <= ie; i++) { - f(i, j, k); - } - } - } -}; - -template -static void foreach_edge(const Grid& g, int Y, int Z, int face, F f) -{ - if (Y == 1 && Z == 2) { - foreach (f, face, face, 1, g.ny, 1, g.nz + 1) - ; - } else if (Y == 2 && Z == 1) { - foreach (f, face, face, 1, g.ny + 1, 1, g.nz) - ; - } else if (Y == 2 && Z == 0) { - foreach (f, 1, g.nx + 1, face, face, 1, g.nz) - ; - } else if (Y == 0 && Z == 2) { - foreach (f, 1, g.nx, face, face, 1, g.nz + 1) - ; - } else if (Y == 0 && Z == 1) { - foreach (f, 1, g.nx, 1, g.ny + 1, face, face) - ; - } else if (Y == 1 && Z == 0) { - foreach (f, 1, g.nx + 1, 1, g.ny, face, face) - ; - } else { - assert(0); - } -} - -template -static void foreach_node(const Grid& g, int X, int face, F f) -{ - if (X == 0) { - foreach (f, face, face, 1, g.ny + 1, 1, g.nz + 1) - ; - } else if (X == 1) { - foreach (f, 1, g.nx + 1, face, face, 1, g.nz + 1) - ; - } else if (X == 2) { - foreach (f, 1, g.nx + 1, 1, g.ny + 1, face, face) - ; - } else { - assert(0); - } -} - -template -static void foreach_face(const Grid& g, int X, int face, F f) -{ - if (X == 0) { - foreach (f, face, face, 1, g.ny, 1, g.nz) - ; - } else if (X == 1) { - foreach (f, 1, g.nx, face, face, 1, g.nz) - ; - } else if (X == 2) { - foreach (f, 1, g.nx, 1, g.ny, face, face) - ; - } else { - assert(0); - } -} - -template -static void foreach_nc_interior(F f, Grid& g) -{ - const int nx = g.nx, ny = g.ny, nz = g.nz; - foreach (f, 2, nx, 2, ny, 2, nz) - ; -} - -template -static void foreach_nc_boundary(F f, Grid& g) -{ - const int nx = g.nx, ny = g.ny, nz = g.nz; - - // z faces, x edges, y edges and all corners - foreach (f, 1, nx + 1, 1, ny + 1, 1, 1) - ; - foreach (f, 1, nx + 1, 1, ny + 1, nz + 1, nz + 1) - ; - - // y faces, z edges - foreach (f, 1, nx + 1, 1, 1, 2, nz) - ; - foreach (f, 1, nx + 1, ny + 1, ny + 1, 2, nz) - ; - - // x faces - foreach (f, 1, 1, 2, ny, 2, nz) - ; - foreach (f, nx + 1, nx + 1, 2, ny, 2, nz) - ; -} - -template -static void foreach_ec_interior(F f, Grid& g) -{ - const int nx = g.nx, ny = g.ny, nz = g.nz; - - for (int k = 2; k <= nz; k++) { - for (int j = 2; j <= ny; j++) { - for (int i = 2; i <= nx; i++) { - f.x(i, j, k); - f.y(i, j, k); - f.z(i, j, k); - } - } - } - - // Do leftover interior ex - for (int k = 2; k <= nz; k++) { - for (int j = 2; j <= ny; j++) { - f.x(1, j, k); - } - } - - // Do leftover interior ey - for (int k = 2; k <= nz; k++) { - for (int i = 2; i <= nx; i++) { - f.y(i, 1, k); - } - } - - // Do leftover interior ez - for (int j = 2; j <= ny; j++) { - for (int i = 2; i <= nx; i++) { - f.z(i, j, 1); - } - } -} - -template -static void foreach_ec_boundary(F f, Grid& g) -{ - const int nx = g.nx, ny = g.ny, nz = g.nz; - - for (int j = 1; j <= ny + 1; j++) { - for (int i = 1; i <= nx; i++) { - f.x(i, j, 1); - } - } - for (int j = 1; j <= ny + 1; j++) { - for (int i = 1; i <= nx; i++) { - f.x(i, j, nz + 1); - } - } - for (int k = 2; k <= nz; k++) { - for (int i = 1; i <= nx; i++) { - f.x(i, 1, k); - } - } - for (int k = 2; k <= nz; k++) { - for (int i = 1; i <= nx; i++) { - f.x(i, ny + 1, k); - } - } - - // Do exterior ey - for (int k = 1; k <= nz + 1; k++) { - for (int j = 1; j <= ny; j++) { - f.y(1, j, k); - } - } - for (int k = 1; k <= nz + 1; k++) { - for (int j = 1; j <= ny; j++) { - f.y(nx + 1, j, k); - } - } - for (int j = 1; j <= ny; j++) { - for (int i = 2; i <= nx; i++) { - f.y(i, j, 1); - } - } - for (int j = 1; j <= ny; j++) { - for (int i = 2; i <= nx; i++) { - f.y(i, j, nz + 1); - } - } - - // Do exterior ez - for (int k = 1; k <= nz; k++) { - for (int i = 1; i <= nx + 1; i++) { - f.z(i, 1, k); - } - } - for (int k = 1; k <= nz; k++) { - for (int i = 1; i <= nx + 1; i++) { - f.z(i, ny + 1, k); - } - } - for (int k = 1; k <= nz; k++) { - for (int j = 2; j <= ny; j++) { - f.z(1, j, k); - } - } - for (int k = 1; k <= nz; k++) { - for (int j = 2; j <= ny; j++) { - f.z(nx + 1, j, k); - } - } -} - -// ====================================================================== -// Comm - -template -struct Comm -{ - typedef G Grid; - - Comm(Grid& g) : g_(g) - { - nx_[0] = g_.nx; - nx_[1] = g_.ny; - nx_[2] = g_.nz; - } - - const int to_ijk[3][2][3] = { - { - {-1, 0, 0}, - {1, 0, 0}, - }, - { - {0, -1, 0}, - {0, 1, 0}, - }, - { - {0, 0, -1}, - {0, 0, 1}, - }, - }; - // wrap what probably should be in Grid:: - - float* get_send_buf(int dir, int side, int sz) const - { - const int* ijk = to_ijk[dir][side]; - return static_cast( - g_.size_send_port(ijk[0], ijk[1], ijk[2], sz * sizeof(float))); - } - - void begin_send_port(int dir, int side, int sz) const - { - const int* ijk = to_ijk[dir][side]; - g_.begin_send_port(ijk[0], ijk[1], ijk[2], sz * sizeof(float)); - } - - void begin_recv_port(int dir, int side, int sz) const - { - const int* ijk = to_ijk[dir][side]; - g_.begin_recv_port(ijk[0], ijk[1], ijk[2], sz * sizeof(float)); - } - - float* end_recv_port(int dir, int side) const - { - const int* ijk = to_ijk[dir][side]; - return static_cast(g_.end_recv_port(ijk[0], ijk[1], ijk[2])); - } - - void end_send_port(int dir, int side) const - { - const int* ijk = to_ijk[dir][side]; - g_.end_send_port(ijk[0], ijk[1], ijk[2]); - } - - // ---------------------------------------------------------------------- - - virtual void begin_send(int dir, int side, float* p, F3D& F) = 0; - virtual void end_recv(int dir, int side, float* p, F3D& F) = 0; - - void begin_recv(int dir, int side) - { - begin_recv_port(dir, side, buf_size_[dir]); - } - - void begin_send(int dir, int side, F3D& F) - { - float* p = get_send_buf(dir, side, buf_size_[dir]); - if (p) { - begin_send(dir, side, p, F); - begin_send_port(dir, side, buf_size_[dir]); - } - } - - void end_recv(int dir, int side, F3D& F) - { - float* p = end_recv_port(dir, side); - if (p) { - end_recv(dir, side, p, F); - } - } - - void end_send(int dir, int side) { end_send_port(dir, side); } - - void begin(int dir, F3D& F) - { - for (int side = 0; side <= 1; side++) { - begin_recv(dir, side); - } - for (int side = 0; side <= 1; side++) { - begin_send(dir, side, F); - } - } - - void end(int dir, F3D& F) - { - for (int side = 0; side <= 1; side++) { - end_recv(dir, side, F); - } - - for (int side = 0; side <= 1; side++) { - end_send(dir, side); - } - } - - void begin(F3D& F) - { - for (int side = 0; side <= 1; side++) { - for (int dir = 0; dir < 3; dir++) { - begin_recv(dir, side); - } - } - - for (int side = 0; side <= 1; side++) { - for (int dir = 0; dir < 3; dir++) { - begin_send(dir, side, F); - } - } - } - - void end(F3D& F) - { - for (int side = 0; side <= 1; side++) { - for (int dir = 0; dir < 3; dir++) { - end_recv(dir, side, F); - } - } - - for (int side = 0; side <= 1; side++) { - for (int dir = 0; dir < 3; dir++) { - end_send(dir, side); - } - } - } - -protected: - int nx_[3]; - int buf_size_[3]; - Grid& g_; -}; - -#endif diff --git a/src/libpsc/vpic/NoneDiag.h b/src/libpsc/vpic/NoneDiag.h deleted file mode 100644 index 246faf5c27..0000000000 --- a/src/libpsc/vpic/NoneDiag.h +++ /dev/null @@ -1,20 +0,0 @@ - -#ifndef NONE_DIAG_H -#define NONE_DIAG_H - -// ---------------------------------------------------------------------- -// NoneDiagMixin - -template -struct NoneDiagMixin -{ - void diagnostics_init(int interval_) {} - void diagnostics_setup() {} - void diagnostics_run(Mparticles& mprts, MfieldsState& mflds, - MfieldsInterpolator& interpolator, - MfieldsHydro& mflds_hydro, const int np[3]) - {} -}; - -#endif diff --git a/src/libpsc/vpic/PscAccumulator.h b/src/libpsc/vpic/PscAccumulator.h deleted file mode 100644 index 8671128c3e..0000000000 --- a/src/libpsc/vpic/PscAccumulator.h +++ /dev/null @@ -1,102 +0,0 @@ - -#pragma once - -template -struct PscAccumulatorOps -{ - using MfieldsAccumulator = _MfieldsAccumulator; - using MfieldsState = _MfieldsState; - using Grid = typename MfieldsAccumulator::Grid; - - // ---------------------------------------------------------------------- - // clear - - static void clear(MfieldsAccumulator& acc) - { - auto g = acc.grid(); - int n_array = acc.n_pipeline() + 1; - for (int arr = 0; arr < n_array; arr++) { - auto a_begin = &acc(arr, 1, 1, 1); - auto a_end = &acc(arr, g->nx, g->ny, g->nz); - // FIXME, the + 1 in n0 doesn't really make sense to me. And, - // originally, this was extended to 128 byte boundaries, too, - // which I dropped -- which is also a behavior change, which I - // though shouldn't matter as it's outside the local domain, but - // it might, too - memset(a_begin, 0, (a_end - a_begin + 1) * sizeof(*a_begin)); - } - } - - // ---------------------------------------------------------------------- - // reduce - - static void reduce(MfieldsAccumulator& acc) - { - auto g = acc.grid(); - int si = sizeof(typename MfieldsAccumulator::Element) / sizeof(float); - int nr = acc.n_pipeline() + 1 - 1; - int sr = si * acc.stride(); - - auto a_begin = &acc(0, 1, 1, 1); - auto a_end = &acc(0, g->nx, g->ny, g->nz); - int n = a_end - a_begin + 1; - - // a is broken into restricted rw and ro parts to allow the compiler - // to do more aggresive optimizations - - float* RESTRICT a = reinterpret_cast(a_begin); - const float* RESTRICT ALIGNED(16) b = a + sr; - - float f[si]; - - for (int i = 0; i < n; i++) { - int j = i * si; - for (int m = 0; m < si; m++) { - f[m] = a[j + m]; - } - for (int r = 0; r < nr; r++) { - int k = j + r * sr; - for (int m = 0; m < si; m++) { - f[m] += b[k + m]; - } - } - for (int m = 0; m < si; m++) { - a[j + m] = f[m]; - } - } - } - - // ---------------------------------------------------------------------- - // unload - - static void unload(/*const*/ MfieldsAccumulator& acc, MfieldsState& mflds) - { - auto g = acc.grid(); - float cx = 0.25 * g->rdy * g->rdz / g->dt; - float cy = 0.25 * g->rdz * g->rdx / g->dt; - float cz = 0.25 * g->rdx * g->rdy / g->dt; - - auto& fa = mflds.getPatch(0); - Field3D F(fa); - Field3D A(acc); - - int nx = g->nx, ny = g->ny, nz = g->nz; - // FIXME, these limits seem to go too far out compared to what we zeroed - // before - for (int k = 1; k <= nz + 1; k++) { - for (int j = 1; j <= ny + 1; j++) { - for (int i = 1; i <= nx + 1; i++) { - F(i, j, k).jfx += - cx * (A(i, j, k).jx[0] + A(i, j - 1, k).jx[1] + - A(i, j, k - 1).jx[2] + A(i, j - 1, k - 1).jx[3]); - F(i, j, k).jfy += - cy * (A(i, j, k).jy[0] + A(i, j, k - 1).jy[1] + - A(i - 1, j, k).jy[2] + A(i - 1, j, k - 1).jy[3]); - F(i, j, k).jfz += - cz * (A(i, j, k).jz[0] + A(i - 1, j, k).jz[1] + - A(i, j - 1, k).jz[2] + A(i - 1, j - 1, k).jz[3]); - } - } - } - } -}; diff --git a/src/libpsc/vpic/PscFieldArray.h b/src/libpsc/vpic/PscFieldArray.h deleted file mode 100644 index 0564587231..0000000000 --- a/src/libpsc/vpic/PscFieldArray.h +++ /dev/null @@ -1,287 +0,0 @@ - -#ifndef PSC_FIELD_ARRAY_H -#define PSC_FIELD_ARRAY_H - -#include - -// ====================================================================== -// PscAccumulateOps - -template -struct PscAccumulateOps -{ - using Grid = typename MfieldsState::Grid; - using MaterialCoefficient = typename MfieldsState::MaterialCoefficient; - using F3D = Field3D; - - // ---------------------------------------------------------------------- - // clear_jf - - static void clear_jf(MfieldsState& mflds) - { - auto& fa = mflds.getPatch(0); - const int nv = mflds.vgrid().nv; - - for (int v = 0; v < nv; v++) { - fa[v].jfx = 0; - fa[v].jfy = 0; - fa[v].jfz = 0; - } - } - - // ---------------------------------------------------------------------- - // CommJf - - template - struct CommJf : Comm - { - typedef Comm Base; - typedef G Grid; - - using Base::begin; - using Base::end; - - using Base::buf_size_; - using Base::g_; - using Base::nx_; - - CommJf(Grid& g) : Base(g) - { - for (int X = 0; X < 3; X++) { - int Y = (X + 1) % 3, Z = (X + 2) % 3; - buf_size_[X] = nx_[Y] * (nx_[Z] + 1) + nx_[Z] * (nx_[Y] + 1); - } - } - - void begin_send(int X, int side, float* p, F3D& F) - { - int Y = (X + 1) % 3, Z = (X + 2) % 3; - int face = side ? nx_[X] + 1 : 1; - foreach_edge(g_, Y, Z, face, - [&](int x, int y, int z) { *p++ = (&F(x, y, z).jfx)[Y]; }); - foreach_edge(g_, Z, Y, face, - [&](int x, int y, int z) { *p++ = (&F(x, y, z).jfx)[Z]; }); - } - - void end_recv(int X, int side, float* p, F3D& F) - { - int Y = (X + 1) % 3, Z = (X + 2) % 3; - int face = side ? 1 : nx_[X] + 1; - foreach_edge(g_, Y, Z, face, - [&](int x, int y, int z) { (&F(x, y, z).jfx)[Y] += *p++; }); - foreach_edge(g_, Z, Y, face, - [&](int x, int y, int z) { (&F(x, y, z).jfx)[Z] += *p++; }); - } - }; - - // ---------------------------------------------------------------------- - // synchronize_jf - - static void synchronize_jf(MfieldsState& mflds) - { - auto& fa = mflds.getPatch(0); - Field3D F(fa); - CommJf> comm(mflds.vgrid()); - - LocalOps::local_adjust_jf(mflds); - - for (int dir = 0; dir < 3; dir++) { - comm.begin(dir, F); - comm.end(dir, F); - } - } - - // ---------------------------------------------------------------------- - // compute_rhob - - static void compute_rhob(MfieldsState& mflds) - { - struct CalcRhoB - { - CalcRhoB(typename MfieldsState::Patch& fa, const MaterialCoefficient* m) - : F(fa), - nc(m->nonconductive), - px(fa.grid()->nx > 1 ? fa.grid()->eps0 * m->epsx * fa.grid()->rdx - : 0), - py(fa.grid()->ny > 1 ? fa.grid()->eps0 * m->epsy * fa.grid()->rdy - : 0), - pz(fa.grid()->nz > 1 ? fa.grid()->eps0 * m->epsz * fa.grid()->rdz : 0) - {} - - void operator()(int i, int j, int k) - { - F(i, j, k).rhob = - nc * (px * (F(i, j, k).ex - F(i - 1, j, k).ex) + - py * (F(i, j, k).ey - F(i, j - 1, k).ey) + - pz * (F(i, j, k).ez - F(i, j, k - 1).ez) - F(i, j, k).rhof); - } - - F3D F; - const float nc, px, py, pz; - }; - - auto& fa = mflds.getPatch(0); - auto& prm = mflds.params(); - assert(prm.size() == 1); - const MaterialCoefficient* m = prm[0]; - - CalcRhoB updater(fa, m); - - // Begin setting normal e ghosts - RemoteOps::begin_remote_ghost_norm_e(mflds); - - // Overlap local computation - LocalOps::local_ghost_norm_e(mflds); - foreach_nc_interior(updater, mflds.vgrid()); - - // Finish setting normal e ghosts - RemoteOps::end_remote_ghost_norm_e(mflds); - - // Now do points on boundary - foreach_nc_boundary(updater, mflds.vgrid()); - - LocalOps::local_adjust_rhob(mflds); - } - - // ---------------------------------------------------------------------- - // compute_curl_b - - static void vacuum_compute_curl_b(MfieldsState& mflds) - { - // Update interior fields - // Note: ex all (1:nx, 1:ny+1,1,nz+1) interior (1:nx,2:ny,2:nz) - // Note: ey all (1:nx+1,1:ny, 1:nz+1) interior (2:nx,1:ny,2:nz) - // Note: ez all (1:nx+1,1:ny+1,1:nz ) interior (1:nx,1:ny,2:nz) - - struct CurlB - { - CurlB(typename MfieldsState::Patch& fa, const Grid* g, - const MaterialCoefficient* m) - : F(fa), - px_muz(g->nx > 1 ? g->cvac * g->dt * g->rdx * m->rmuz : 0), - px_muy(g->nx > 1 ? g->cvac * g->dt * g->rdx * m->rmuy : 0), - py_mux(g->ny > 1 ? g->cvac * g->dt * g->rdy * m->rmux : 0), - py_muz(g->ny > 1 ? g->cvac * g->dt * g->rdy * m->rmuz : 0), - pz_muy(g->nz > 1 ? g->cvac * g->dt * g->rdz * m->rmuy : 0), - pz_mux(g->nz > 1 ? g->cvac * g->dt * g->rdz * m->rmux : 0) - {} - - void x(int i, int j, int k) - { - F(i, j, k).tcax = (py_muz * (F(i, j, k).cbz - F(i, j - 1, k).cbz) - - pz_muy * (F(i, j, k).cby - F(i, j, k - 1).cby)); - } - - void y(int i, int j, int k) - { - F(i, j, k).tcay = (pz_mux * (F(i, j, k).cbx - F(i, j, k - 1).cbx) - - px_muz * (F(i, j, k).cbz - F(i - 1, j, k).cbz)); - } - - void z(int i, int j, int k) - { - F(i, j, k).tcaz = (px_muy * (F(i, j, k).cby - F(i - 1, j, k).cby) - - py_mux * (F(i, j, k).cbx - F(i, j - 1, k).cbx)); - } - - F3D F; - const float px_muz, px_muy, py_mux, py_muz, pz_muy, pz_mux; - }; - - auto& fa = mflds.getPatch(0); - auto& prm = mflds.params(); - assert(prm.size() == 1); - const MaterialCoefficient* m = prm[0]; - - CurlB curlB(fa, &mflds.vgrid(), m); - - RemoteOps::begin_remote_ghost_tang_b(mflds); - - LocalOps::local_ghost_tang_b(mflds); - foreach_ec_interior(curlB, mflds.vgrid()); - - RemoteOps::end_remote_ghost_tang_b(mflds); - - foreach_ec_boundary(curlB, mflds.vgrid()); - LocalOps::local_adjust_tang_e(mflds); // FIXME, is this right here? - } - - static void compute_curl_b(MfieldsState& mflds) - { - vacuum_compute_curl_b(mflds); - } -}; - -// ====================================================================== -// PscDiagOps - -template -struct PscDiagOps -{ - using Grid = typename MfieldsState::Grid; - using F3D = Field3D; - - // ---------------------------------------------------------------------- - // vacuum_energy_f - - static void vacuum_energy_f(MfieldsState& mflds, double global[6]) - { - const auto& g = mflds.vgrid(); - auto& fa = mflds.getPatch(0); - F3D F(fa); - - auto& prm = mflds.params(); - assert(prm.size() == 1); - auto m = prm[0]; - - const int nx = g.nx, ny = g.ny, nz = g.nz; - - const float qepsx = 0.25 * m->epsx; - const float qepsy = 0.25 * m->epsy; - const float qepsz = 0.25 * m->epsz; - const float hrmux = 0.5 * m->rmux; - const float hrmuy = 0.5 * m->rmuy; - const float hrmuz = 0.5 * m->rmuz; - double en[6] = {}; - - for (int k = 1; k <= nz; k++) { - for (int j = 1; j <= ny; j++) { - for (int i = 1; i <= nx; i++) { - en[0] += - qepsx * (sqr(F(i, j, k).ex) + sqr(F(i, j + 1, k).ex) + - sqr(F(i, j, k + 1).ex) + sqr(F(i, j + 1, k + 1).ex)); - en[1] += - qepsy * (sqr(F(i, j, k).ey) + sqr(F(i, j, k + 1).ey) + - sqr(F(i + 1, j, k).ey) + sqr(F(i + 1, j, k + 1).ey)); - en[2] += - qepsz * (sqr(F(i, j, k).ez) + sqr(F(i + 1, j, k).ez) + - sqr(F(i, j + 1, k).ez) + sqr(F(i + 1, j + 1, k).ez)); - en[3] += hrmux * (sqr(F(i, j, k).cbx) + sqr(F(i + 1, j, k).cbx)); - en[4] += hrmuy * (sqr(F(i, j, k).cby) + sqr(F(i, j + 1, k).cby)); - en[5] += hrmuz * (sqr(F(i, j, k).cbz) + sqr(F(i, j, k + 1).cbz)); - } - } - } - - // Convert to physical units - double v0 = 0.5 * g.eps0 * g.dV; - for (int m = 0; m < 6; m++) { - en[m] *= v0; - } - - // Reduce results between nodes - MPI_Allreduce(en, global, 6, MPI_DOUBLE, MPI_SUM, psc_comm_world); - } - - // ---------------------------------------------------------------------- - // energy_f - - static void energy_f(MfieldsState& mflds, double en[6]) - { - vacuum_energy_f(mflds, en); - } -}; - -#include "PscFieldArrayRemoteOps.h" // FIXME, only because of Comm stuff - -#endif diff --git a/src/libpsc/vpic/PscFieldArrayLocalOps.h b/src/libpsc/vpic/PscFieldArrayLocalOps.h deleted file mode 100644 index 7e4df0816b..0000000000 --- a/src/libpsc/vpic/PscFieldArrayLocalOps.h +++ /dev/null @@ -1,454 +0,0 @@ - -#ifndef PSC_FIELD_ARRAY_LOCAL_OPS_H -#define PSC_FIELD_ARRAY_LOCAL_OPS_H - -#define XYZ_LOOP(xl, xh, yl, yh, zl, zh) \ - for (z = zl; z <= zh; z++) \ - for (y = yl; y <= yh; y++) \ - for (x = xl; x <= xh; x++) - -#define yz_EDGE_LOOP(x) XYZ_LOOP(x, x, 1, ny, 1, nz + 1) -#define zx_EDGE_LOOP(y) XYZ_LOOP(1, nx + 1, y, y, 1, nz) -#define xy_EDGE_LOOP(z) XYZ_LOOP(1, nx, 1, ny + 1, z, z) - -#define zy_EDGE_LOOP(x) XYZ_LOOP(x, x, 1, ny + 1, 1, nz) -#define xz_EDGE_LOOP(y) XYZ_LOOP(1, nx, y, y, 1, nz + 1) -#define yx_EDGE_LOOP(z) XYZ_LOOP(1, nx + 1, 1, ny, z, z) - -#define x_NODE_LOOP(x) XYZ_LOOP(x, x, 1, ny + 1, 1, nz + 1) -#define y_NODE_LOOP(y) XYZ_LOOP(1, nx + 1, y, y, 1, nz + 1) -#define z_NODE_LOOP(z) XYZ_LOOP(1, nx + 1, 1, ny + 1, z, z) - -#define x_FACE_LOOP(x) XYZ_LOOP(x, x, 1, ny, 1, nz) -#define y_FACE_LOOP(y) XYZ_LOOP(1, nx, y, y, 1, nz) -#define z_FACE_LOOP(z) XYZ_LOOP(1, nx, 1, ny, z, z) - -template -struct PscFieldArrayLocalOps -{ - using Grid = typename MfieldsState::Grid; - using FieldT = typename MfieldsState::Element; - using F3D = Field3D; - - static void local_ghost_tang_b(MfieldsState& mflds) - { - const auto& g = mflds.vgrid(); - auto& fa = mflds.getPatch(0); - F3D F(fa); - const int nx = g.nx, ny = g.ny, nz = g.nz; - const float cdt_dx = g.cvac * g.dt * g.rdx; - const float cdt_dy = g.cvac * g.dt * g.rdy; - const float cdt_dz = g.cvac * g.dt * g.rdz; - int bc, face, ghost, x, y, z; - float decay, drive, higend, t1, t2; - FieldT *fg, *fh; - - // Absorbing boundary condition is 2nd order accurate implementation - // of a 1st order Higend ABC with 15 degree annihilation cone except - // for 1d simulations where the 2nd order accurate implementation of - // a 1st order Mur boundary condition is used. - higend = (nx > 1 || ny > 1 || nz > 1) ? 1.03527618 : 1.; - -#define APPLY_LOCAL_TANG_B(i, j, k, X, Y, Z) \ - do { \ - bc = g.bc[BOUNDARY(i, j, k)]; \ - if (bc < 0 || bc >= psc_world_size) { \ - ghost = (i + j + k) < 0 ? 0 : n##X + 1; \ - face = (i + j + k) < 0 ? 1 : n##X + 1; \ - switch (bc) { \ - case Grid::anti_symmetric_fields: \ - Z##Y##_EDGE_LOOP(ghost) F(x, y, z).cb##Y = \ - F(x - i, y - j, z - k).cb##Y; \ - Y##Z##_EDGE_LOOP(ghost) F(x, y, z).cb##Z = \ - F(x - i, y - j, z - k).cb##Z; \ - break; \ - case Grid::symmetric_fields: \ - case Grid::pmc_fields: \ - Z##Y##_EDGE_LOOP(ghost) F(x, y, z).cb##Y = \ - -F(x - i, y - j, z - k).cb##Y; \ - Y##Z##_EDGE_LOOP(ghost) F(x, y, z).cb##Z = \ - -F(x - i, y - j, z - k).cb##Z; \ - break; \ - case Grid::absorb_fields: \ - drive = cdt_d##X * higend; \ - decay = (1 - drive) / (1 + drive); \ - drive = 2 * drive / (1 + drive); \ - Z##Y##_EDGE_LOOP(ghost) \ - { \ - fg = &F(x, y, z); \ - fh = &F(x - i, y - j, z - k); \ - X = face; \ - t1 = cdt_d##X * (F(x - i, y - j, z - k).e##Z - F(x, y, z).e##Z); \ - t1 = (i + j + k) < 0 ? t1 : -t1; \ - X = ghost; \ - Z++; \ - t2 = F(x - i, y - j, z - k).e##X; \ - Z--; \ - t2 = cdt_d##Z * (t2 - fh->e##X); \ - fg->cb##Y = decay * fg->cb##Y + drive * fh->cb##Y - t1 + t2; \ - } \ - Y##Z##_EDGE_LOOP(ghost) \ - { \ - fg = &F(x, y, z); \ - fh = &F(x - i, y - j, z - k); \ - X = face; \ - t1 = cdt_d##X * (F(x - i, y - j, z - k).e##Y - F(x, y, z).e##Y); \ - t1 = (i + j + k) < 0 ? t1 : -t1; \ - X = ghost; \ - Y++; \ - t2 = F(x - i, y - j, z - k).e##X; \ - Y--; \ - t2 = cdt_d##Y * (t2 - fh->e##X); \ - fg->cb##Z = decay * fg->cb##Z + drive * fh->cb##Z + t1 - t2; \ - } \ - break; \ - default: assert(0); break; \ - } \ - } \ - } while (0) - - APPLY_LOCAL_TANG_B(-1, 0, 0, x, y, z); - APPLY_LOCAL_TANG_B(0, -1, 0, y, z, x); - APPLY_LOCAL_TANG_B(0, 0, -1, z, x, y); - APPLY_LOCAL_TANG_B(1, 0, 0, x, y, z); - APPLY_LOCAL_TANG_B(0, 1, 0, y, z, x); - APPLY_LOCAL_TANG_B(0, 0, 1, z, x, y); - } - - // Note: local_adjust_div_e zeros the error on the boundaries for - // absorbing boundary conditions. Thus, ghost norm e value is - // irrevelant. - - static void local_ghost_norm_e(MfieldsState& mflds) - { - const auto& g = mflds.vgrid(); - auto& fa = mflds.getPatch(0); - F3D F(fa); - const int nx = g.nx, ny = g.ny, nz = g.nz; - int bc, face, x, y, z; - FieldT *ALIGNED(16) f0, *ALIGNED(16) f1, *ALIGNED(16) f2; - -#define APPLY_LOCAL_NORM_E(i, j, k, X, Y, Z) \ - do { \ - bc = g.bc[BOUNDARY(i, j, k)]; \ - if (bc < 0 || bc >= psc_world_size) { \ - face = (i + j + k) < 0 ? 0 : n##X + 1; \ - switch (bc) { \ - case Grid::anti_symmetric_fields: \ - X##_NODE_LOOP(face) \ - { \ - f0 = &F(x, y, z); \ - f1 = &F(x - i, y - j, z - k); \ - f0->e##X = f1->e##X; \ - f0->tca##X = f1->tca##X; \ - } \ - break; \ - case Grid::symmetric_fields: \ - case Grid::pmc_fields: \ - X##_NODE_LOOP(face) \ - { \ - f0 = &F(x, y, z); \ - f1 = &F(x - i, y - j, z - k); \ - f0->e##X = -f1->e##X; \ - f0->tca##X = -f1->tca##X; \ - } \ - break; \ - case Grid::absorb_fields: \ - X##_NODE_LOOP(face) \ - { \ - f0 = &F(x, y, z); \ - f1 = &F(x - i, y - j, z - k); \ - f2 = &F(x - i * 2, y - j * 2, z - k * 2); \ - f0->e##X = 2 * f1->e##X - f2->e##X; \ - f0->tca##X = 2 * f1->tca##X - f2->tca##X; \ - } \ - break; \ - default: LOG_ERROR("Bad boundary condition encountered."); break; \ - } \ - } \ - } while (0) - - APPLY_LOCAL_NORM_E(-1, 0, 0, x, y, z); - APPLY_LOCAL_NORM_E(0, -1, 0, y, z, x); - APPLY_LOCAL_NORM_E(0, 0, -1, z, x, y); - APPLY_LOCAL_NORM_E(1, 0, 0, x, y, z); - APPLY_LOCAL_NORM_E(0, 1, 0, y, z, x); - APPLY_LOCAL_NORM_E(0, 0, 1, z, x, y); - } - - static void local_ghost_div_b(MfieldsState& mflds) - { - const auto& g = mflds.vgrid(); - auto& fa = mflds.getPatch(0); - F3D F(fa); - const int nx = g.nx, ny = g.ny, nz = g.nz; - int bc, face, x, y, z; - -#define APPLY_LOCAL_DIV_B(i, j, k, X, Y, Z) \ - do { \ - bc = g.bc[BOUNDARY(i, j, k)]; \ - if (bc < 0 || bc >= psc_world_size) { \ - face = (i + j + k) < 0 ? 0 : n##X + 1; \ - switch (bc) { \ - case Grid::anti_symmetric_fields: \ - X##_FACE_LOOP(face) F(x, y, z).div_b_err = \ - F(x - i, y - j, z - k).div_b_err; \ - break; \ - case Grid::symmetric_fields: \ - case Grid::pmc_fields: \ - X##_FACE_LOOP(face) F(x, y, z).div_b_err = \ - -F(x - i, y - j, z - k).div_b_err; \ - break; \ - case Grid::absorb_fields: \ - X##_FACE_LOOP(face) F(x, y, z).div_b_err = 0; \ - break; \ - default: LOG_ERROR("Bad boundary condition encountered."); break; \ - } \ - } \ - } while (0) - - APPLY_LOCAL_DIV_B(-1, 0, 0, x, y, z); - APPLY_LOCAL_DIV_B(0, -1, 0, y, z, x); - APPLY_LOCAL_DIV_B(0, 0, -1, z, x, y); - APPLY_LOCAL_DIV_B(1, 0, 0, x, y, z); - APPLY_LOCAL_DIV_B(0, 1, 0, y, z, x); - APPLY_LOCAL_DIV_B(0, 0, 1, z, x, y); - } - - // FIXME: Specialty edge loops should be added to zero e_tang on local - // edges exclusively to handle concave domain geometries - - static void local_adjust_tang_e(MfieldsState& mflds) - { - const auto& g = mflds.vgrid(); - auto& fa = mflds.getPatch(0); - F3D F(fa); - const int nx = g.nx, ny = g.ny, nz = g.nz; - int bc, face, x, y, z; - FieldT* fs; - -#define ADJUST_TANG_E(i, j, k, X, Y, Z) \ - do { \ - bc = g.bc[BOUNDARY(i, j, k)]; \ - if (bc < 0 || bc >= psc_world_size) { \ - face = (i + j + k) < 0 ? 1 : n##X + 1; \ - switch (bc) { \ - case Grid::anti_symmetric_fields: \ - Y##Z##_EDGE_LOOP(face) \ - { \ - fs = &F(x, y, z); \ - fs->e##Y = 0; \ - fs->tca##Y = 0; \ - } \ - Z##Y##_EDGE_LOOP(face) \ - { \ - fs = &F(x, y, z); \ - fs->e##Z = 0; \ - fs->tca##Z = 0; \ - } \ - break; \ - case Grid::symmetric_fields: \ - case Grid::pmc_fields: \ - case Grid::absorb_fields: break; \ - default: LOG_ERROR("Bad boundary condition encountered."); break; \ - } \ - } \ - } while (0) - - ADJUST_TANG_E(-1, 0, 0, x, y, z); - ADJUST_TANG_E(0, -1, 0, y, z, x); - ADJUST_TANG_E(0, 0, -1, z, x, y); - ADJUST_TANG_E(1, 0, 0, x, y, z); - ADJUST_TANG_E(0, 1, 0, y, z, x); - ADJUST_TANG_E(0, 0, 1, z, x, y); - } - - static void local_adjust_norm_b(MfieldsState& mflds) - { - const auto& g = mflds.vgrid(); - auto& fa = mflds.getPatch(0); - F3D F(fa); - const int nx = g.nx, ny = g.ny, nz = g.nz; - int bc, face, x, y, z; - -#define ADJUST_NORM_B(i, j, k, X, Y, Z) \ - do { \ - bc = g.bc[BOUNDARY(i, j, k)]; \ - if (bc < 0 || bc >= psc_world_size) { \ - face = (i + j + k) < 0 ? 1 : n##X + 1; \ - switch (bc) { \ - case Grid::anti_symmetric_fields: \ - case Grid::pmc_fields: \ - case Grid::absorb_fields: break; \ - case Grid::symmetric_fields: \ - X##_FACE_LOOP(face) F(x, y, z).cb##X = 0; \ - break; \ - default: LOG_ERROR("Bad boundary condition encountered."); break; \ - } \ - } \ - } while (0) - - ADJUST_NORM_B(-1, 0, 0, x, y, z); - ADJUST_NORM_B(0, -1, 0, y, z, x); - ADJUST_NORM_B(0, 0, -1, z, x, y); - ADJUST_NORM_B(1, 0, 0, x, y, z); - ADJUST_NORM_B(0, 1, 0, y, z, x); - ADJUST_NORM_B(0, 0, 1, z, x, y); - } - - static void local_adjust_div_e(MfieldsState& mflds) - { - const auto& g = mflds.vgrid(); - auto& fa = mflds.getPatch(0); - F3D F(fa); - const int nx = g.nx, ny = g.ny, nz = g.nz; - int bc, face, x, y, z; - -#define ADJUST_DIV_E_ERR(i, j, k, X, Y, Z) \ - do { \ - bc = g.bc[BOUNDARY(i, j, k)]; \ - if (bc < 0 || bc >= psc_world_size) { \ - face = (i + j + k) < 0 ? 1 : n##X + 1; \ - switch (bc) { \ - case Grid::anti_symmetric_fields: \ - case Grid::absorb_fields: \ - X##_NODE_LOOP(face) F(x, y, z).div_e_err = 0; \ - break; \ - case Grid::symmetric_fields: \ - case Grid::pmc_fields: break; \ - default: LOG_ERROR("Bad boundary condition encountered."); break; \ - } \ - } \ - } while (0) - - ADJUST_DIV_E_ERR(-1, 0, 0, x, y, z); - ADJUST_DIV_E_ERR(0, -1, 0, y, z, x); - ADJUST_DIV_E_ERR(0, 0, -1, z, x, y); - ADJUST_DIV_E_ERR(1, 0, 0, x, y, z); - ADJUST_DIV_E_ERR(0, 1, 0, y, z, x); - ADJUST_DIV_E_ERR(0, 0, 1, z, x, y); - } - - // anti_symmetric => Opposite sign image charges (zero jf_tang) - // symmetric => Same sign image charges (double jf_tang) - // absorbing => No image charges, half cell accumulation (double jf_tang) - // (rhob/jf_norm account for particles that hit boundary and reflect/stick) - - static void local_adjust_jf(MfieldsState& mflds) - { - const auto& g = mflds.vgrid(); - auto& fa = mflds.getPatch(0); - Field3D F(fa); - const int nx = g.nx, ny = g.ny, nz = g.nz; - int bc, face, x, y, z; - -#define ADJUST_JF(i, j, k, X, Y, Z) \ - do { \ - bc = g.bc[BOUNDARY(i, j, k)]; \ - if (bc < 0 || bc >= psc_world_size) { \ - face = (i + j + k) < 0 ? 1 : n##X + 1; \ - switch (bc) { \ - case Grid::anti_symmetric_fields: \ - Y##Z##_EDGE_LOOP(face) F(x, y, z).jf##Y = 0; \ - Z##Y##_EDGE_LOOP(face) F(x, y, z).jf##Z = 0; \ - break; \ - case Grid::symmetric_fields: \ - case Grid::pmc_fields: \ - case Grid::absorb_fields: \ - Y##Z##_EDGE_LOOP(face) F(x, y, z).jf##Y *= 2.; \ - Z##Y##_EDGE_LOOP(face) F(x, y, z).jf##Z *= 2.; \ - break; \ - default: LOG_ERROR("Bad boundary condition encountered."); break; \ - } \ - } \ - } while (0) - - ADJUST_JF(-1, 0, 0, x, y, z); - ADJUST_JF(0, -1, 0, y, z, x); - ADJUST_JF(0, 0, -1, z, x, y); - ADJUST_JF(1, 0, 0, x, y, z); - ADJUST_JF(0, 1, 0, y, z, x); - ADJUST_JF(0, 0, 1, z, x, y); - } - - // anti_symmetric => Opposite sign image charges (zero rhof/rhob) - // symmetric => Same sign image charges (double rhof) - // => (double rhof, rhob is already correct) - // absorbing => No image charges, half cell accumulation (double rhof) - // (rhob/jf_norm account for particles that hit the boundary) - - static void local_adjust_rhof(MfieldsState& mflds) - { - const auto& g = mflds.vgrid(); - auto& fa = mflds.getPatch(0); - F3D F(fa); - const int nx = g.nx, ny = g.ny, nz = g.nz; - int bc, face, x, y, z; - -#define ADJUST_RHOF(i, j, k, X, Y, Z) \ - do { \ - bc = g.bc[BOUNDARY(i, j, k)]; \ - if (bc < 0 || bc >= psc_world_size) { \ - face = (i + j + k) < 0 ? 1 : n##X + 1; \ - switch (bc) { \ - case Grid::anti_symmetric_fields: \ - X##_NODE_LOOP(face) F(x, y, z).rhof = 0; \ - break; \ - case Grid::symmetric_fields: \ - case Grid::pmc_fields: \ - case Grid::absorb_fields: \ - X##_NODE_LOOP(face) F(x, y, z).rhof *= 2; \ - break; \ - default: LOG_ERROR("Bad boundary condition encountered."); break; \ - } \ - } \ - } while (0) - - ADJUST_RHOF(-1, 0, 0, x, y, z); - ADJUST_RHOF(0, -1, 0, y, z, x); - ADJUST_RHOF(0, 0, -1, z, x, y); - ADJUST_RHOF(1, 0, 0, x, y, z); - ADJUST_RHOF(0, 1, 0, y, z, x); - ADJUST_RHOF(0, 0, 1, z, x, y); - } - - // anti_symmetric => Opposite sign image charges (zero rhob) - // symmetric => Same sign image charges (rhob already correct) - // absorbing => No image charges, half cell accumulation (rhob already - // correct) - - static void local_adjust_rhob(MfieldsState& mflds) - { - const auto& g = mflds.vgrid(); - auto& fa = mflds.getPatch(0); - F3D F(fa); - const int nx = g.nx, ny = g.ny, nz = g.nz; - int bc, face, x, y, z; - -#define ADJUST_RHOB(i, j, k, X, Y, Z) \ - do { \ - bc = g.bc[BOUNDARY(i, j, k)]; \ - if (bc < 0 || bc >= psc_world_size) { \ - face = (i + j + k) < 0 ? 1 : n##X + 1; \ - switch (bc) { \ - case Grid::anti_symmetric_fields: \ - X##_NODE_LOOP(face) F(x, y, z).rhob = 0; \ - break; \ - case Grid::symmetric_fields: \ - case Grid::pmc_fields: \ - case Grid::absorb_fields: break; \ - default: LOG_ERROR("Bad boundary condition encountered."); break; \ - } \ - } \ - } while (0) - - ADJUST_RHOB(-1, 0, 0, x, y, z); - ADJUST_RHOB(0, -1, 0, y, z, x); - ADJUST_RHOB(0, 0, -1, z, x, y); - ADJUST_RHOB(1, 0, 0, x, y, z); - ADJUST_RHOB(0, 1, 0, y, z, x); - ADJUST_RHOB(0, 0, 1, z, x, y); - } -}; - -#endif diff --git a/src/libpsc/vpic/PscFieldArrayRemoteOps.h b/src/libpsc/vpic/PscFieldArrayRemoteOps.h deleted file mode 100644 index 56e151f457..0000000000 --- a/src/libpsc/vpic/PscFieldArrayRemoteOps.h +++ /dev/null @@ -1,191 +0,0 @@ - -#ifndef PSC_FIELD_ARRAY_REMOTE_OPS_H -#define PSC_FIELD_ARRAY_REMOTE_OPS_H - -#include "GridLoop.h" - -// ====================================================================== -// PscFieldArrayRemoteOps - -template -struct PscFieldArrayRemoteOps -{ - using Grid = typename MfieldsState::Grid; - using F3D = Field3D; - - // ---------------------------------------------------------------------- - // CommEC - - template - struct CommEC : Comm - { - typedef Comm Base; - typedef G Grid; - using Base::begin; - using Base::end; - - using Base::buf_size_; - using Base::g_; - using Base::nx_; - - CommEC(Grid& g) : Base(g) - { - for (int X = 0; X < 3; X++) { - int Y = (X + 1) % 3, Z = (X + 2) % 3; - buf_size_[X] = nx_[Y] * (nx_[Z] + 1) + nx_[Z] * (nx_[Y] + 1); - } - } - - void begin_send(int X, int side, float* p, F3D& F) - { - int Y = (X + 1) % 3, Z = (X + 2) % 3; - int face = side ? nx_[X] : 1; - foreach_edge(g_, Z, Y, face, - [&](int x, int y, int z) { *p++ = (&F(x, y, z).cbx)[Y]; }); - foreach_edge(g_, Y, Z, face, - [&](int x, int y, int z) { *p++ = (&F(x, y, z).cbx)[Z]; }); - } - - void end_recv(int X, int side, float* p, F3D& F) - { - int Y = (X + 1) % 3, Z = (X + 2) % 3; - int face = side ? 0 : nx_[X] + 1; - foreach_edge(g_, Z, Y, face, - [&](int x, int y, int z) { (&F(x, y, z).cbx)[Y] = *p++; }); - foreach_edge(g_, Y, Z, face, - [&](int x, int y, int z) { (&F(x, y, z).cbx)[Z] = *p++; }); - } - }; - - static void begin_remote_ghost_tang_b(MfieldsState& mflds) - { - auto& fa = mflds.getPatch(0); - F3D F(fa); - CommEC comm(mflds.vgrid()); - - comm.begin(F); - } - - static void end_remote_ghost_tang_b(MfieldsState& mflds) - { - auto& fa = mflds.getPatch(0); - F3D F(fa); - CommEC comm(mflds.vgrid()); - - comm.end(F); - } - - // ---------------------------------------------------------------------- - // CommNC - - template - struct CommNC : Comm - { - typedef Comm Base; - typedef G Grid; - using Base::begin; - using Base::end; - - using Base::buf_size_; - using Base::g_; - using Base::nx_; - - CommNC(Grid& g) : Base(g) - { - for (int X = 0; X < 3; X++) { - int Y = (X + 1) % 3, Z = (X + 2) % 3; - buf_size_[X] = (nx_[Y] + 1) * (nx_[Z] + 1); - } - } - - void begin_send(int X, int side, float* p, F3D& F) - { - int face = side ? nx_[X] : 1; - foreach_node(g_, X, face, - [&](int x, int y, int z) { *p++ = (&F(x, y, z).ex)[X]; }); - } - - void end_recv(int X, int side, float* p, F3D& F) - { - int face = side ? 0 : nx_[X] + 1; - foreach_node(g_, X, face, - [&](int x, int y, int z) { (&F(x, y, z).ex)[X] = *p++; }); - } - }; - - static void begin_remote_ghost_norm_e(MfieldsState& mflds) - { - auto& fa = mflds.getPatch(0); - F3D F(fa); - CommNC comm(mflds.vgrid()); - - comm.begin(F); - } - - static void end_remote_ghost_norm_e(MfieldsState& mflds) - { - auto& fa = mflds.getPatch(0); - F3D F(fa); - CommNC comm(mflds.vgrid()); - - comm.end(F); - } - - // ---------------------------------------------------------------------- - // CommCC - - template - struct CommCC : Comm - { - typedef Comm Base; - typedef G Grid; - using Base::begin; - using Base::end; - - using Base::buf_size_; - using Base::g_; - using Base::nx_; - - CommCC(Grid& g) : Base(g) - { - for (int X = 0; X < 3; X++) { - int Y = (X + 1) % 3, Z = (X + 2) % 3; - buf_size_[X] = nx_[Y] * nx_[Z]; - } - } - - void begin_send(int X, int side, float* p, F3D& F) - { - int face = side ? nx_[X] : 1; - foreach_face(g_, X, face, - [&](int x, int y, int z) { *p++ = F(x, y, z).div_b_err; }); - } - - void end_recv(int X, int side, float* p, F3D& F) - { - int face = side ? 0 : nx_[X] + 1; - foreach_face(g_, X, face, - [&](int x, int y, int z) { F(x, y, z).div_b_err = *p++; }); - } - }; - - static void begin_remote_ghost_div_b(MfieldsState& mflds) - { - auto& fa = mflds.getPatch(0); - F3D F(fa); - CommCC comm(mflds.vgrid()); - - comm.begin(F); - } - - static void end_remote_ghost_div_b(MfieldsState& mflds) - { - auto& fa = mflds.getPatch(0); - F3D F(fa); - CommCC comm(mflds.vgrid()); - - comm.end(F); - } -}; - -#endif diff --git a/src/libpsc/vpic/PscFieldBase.h b/src/libpsc/vpic/PscFieldBase.h deleted file mode 100644 index 24ab56b11b..0000000000 --- a/src/libpsc/vpic/PscFieldBase.h +++ /dev/null @@ -1,49 +0,0 @@ - -#ifndef PSC_FIELD_BASE_H -#define PSC_FIELD_BASE_H - -template -struct PscFieldBase -{ - typedef E Element; - typedef G Grid; - - PscFieldBase(Grid* grid) : g_(grid), is_owner_(true) - { - arr_ = new Element[g_->nv](); - } - - PscFieldBase(Grid* grid, Element* arr) : arr_(arr), g_(grid), is_owner_(false) - {} - - PscFieldBase(const PscFieldBase& other) - : arr_{other.arr_}, g_{other.g_}, is_owner_{other.is_owner_} - { - // FIXME, copying leaves us with two owners of the same data, which - // can't be good - assert(!is_owner_); - } - - ~PscFieldBase() - { - if (is_owner_) { - delete[] arr_; - } - } - - Element operator[](int idx) const { return arr_[idx]; } - Element& operator[](int idx) { return arr_[idx]; } - - Element* data() { return arr_; } - - Grid* grid() { return g_; } - -protected: - Element* arr_; - Grid* g_; - -private: - bool is_owner_; // OPT this could probably somehow be handled by a template... -}; - -#endif diff --git a/src/libpsc/vpic/PscGridBase.h b/src/libpsc/vpic/PscGridBase.h deleted file mode 100644 index 5081077f39..0000000000 --- a/src/libpsc/vpic/PscGridBase.h +++ /dev/null @@ -1,503 +0,0 @@ - -#ifndef PSC_GRID_BASE_H -#define PSC_GRID_BASE_H - -#include "bits.hxx" -#include "kg/Vec3.h" - -#include -#include -#include -#include -#include - -// ====================================================================== -// PscMp - -struct PscMp -{ - PscMp(int n_port) - : recv_buf_(n_port), - send_buf_(n_port), - recv_req_(n_port, MPI_REQUEST_NULL), - send_req_(n_port, MPI_REQUEST_NULL) - {} - - void size_recv_buffer(int port, int size) { recv_buf_[port].resize(size); } - - void size_send_buffer(int port, int size) { send_buf_[port].resize(size); } - - char* send_buffer(int port) { return send_buf_[port].data(); } - - char* recv_buffer(int port) { return recv_buf_[port].data(); } - - void begin_send(int port, int size, int dst, int tag) - { - MPI_Isend(send_buf_[port].data(), size, MPI_BYTE, dst, tag, MPI_COMM_WORLD, - &send_req_[port]); - } - - void end_send(int port) { MPI_Wait(&send_req_[port], MPI_STATUS_IGNORE); } - - void begin_recv(int port, int size, int src, int tag) - { - MPI_Irecv(recv_buf_[port].data(), size, MPI_BYTE, src, tag, MPI_COMM_WORLD, - &recv_req_[port]); - } - - void end_recv(int port) { MPI_Wait(&recv_req_[port], MPI_STATUS_IGNORE); } - - std::vector> recv_buf_; - std::vector> send_buf_; - std::vector recv_req_; - std::vector send_req_; -}; - -// ====================================================================== -// PscGridBase - -struct PscGridBase -{ - enum - { - anti_symmetric_fields = -1, // E_tang = 0 - pec_fields = -1, // FIXME, matching vpic for now - symmetric_fields = -2, // B_tang = 0, B_norm = 0 - pmc_fields = -3, // B_tang = 0, B_norm floats - absorb_fields = -4, - } Fbc; - - enum - { - reflect_particles = -1, // FIXME, matching vpic for now - absorb_particles = -2 - } Pbc; - - PscGridBase() - { - memset(this, 0, sizeof(*this)); // FIXME - neighbor = nullptr; // FIXME... - for (int i = 0; i < 27; i++) { - bc[i] = anti_symmetric_fields; - } - bc[BOUNDARY(0, 0, 0)] = psc_world_rank; - mp = new PscMp(27); - } - - ~PscGridBase() - { - delete[] neighbor; - delete[] range; - delete mp; - } - - static PscGridBase* create() { return new PscGridBase; } - - void setup(const double dx_[3], double dt_, double cvac_, double eps0_) - { - dx = dx_[0]; - dy = dx_[1]; - dz = dx_[2]; - dt = dt_; - cvac = cvac_; - eps0 = eps0_; - } - - Int3 rank_to_idx(int rank, const Int3& np) - { - Int3 idx; - int ix, iy, iz; - ix = rank; - iy = ix / np[0]; - ix -= iy * np[0]; - iz = iy / np[1]; - iy -= iz * np[1]; - idx[0] = ix; - idx[1] = iy; - idx[2] = iz; - return idx; - } - - unsigned int idx_to_rank(const int np[3], Int3 idx) - { - int ix = idx[0], iy = idx[1], iz = idx[2]; - while (ix >= np[0]) - ix -= np[0]; - while (ix < 0) - ix += np[0]; - while (iy >= np[1]) - iy -= np[1]; - while (iy < 0) - iy += np[1]; - while (iz >= np[2]) - iz -= np[2]; - while (iz < 0) - iz += np[2]; - return ix + np[0] * (iy + np[1] * iz); - } - -#define LOCAL_CELL_ID(x, y, z) VOXEL(x, y, z, lnx, lny, lnz) -#define REMOTE_CELL_ID(x, y, z) VOXEL(x, y, z, rnx, rny, rnz) - - void size_grid(int lnx, int lny, int lnz) - { - int64_t x, y, z; - int i, j, k; - int64_t ii, jj, kk; - - assert(lnx > 0 && lny > 0 && lnz > 0); - - // Setup phase 2 data structures - sx = 1; - sy = (lnx + 2) * sx; - sz = (lny + 2) * sy; - nv = (lnz + 2) * sz; - nx = lnx; - ny = lny; - nz = lnz; - for (k = -1; k <= 1; k++) { - for (j = -1; j <= 1; j++) { - for (i = -1; i <= 1; i++) { - bc[BOUNDARY(i, j, k)] = pec_fields; - } - } - } - bc[BOUNDARY(0, 0, 0)] = psc_world_rank; - - // Setup phase 3 data structures. This is an ugly kludge to - // interface phase 2 and phase 3 data structures - delete[] range; - range = new int64_t[psc_world_size + 1]; - ii = nv; // nv is not 64-bits - MPI_Allgather(&ii, 1, MPI_LONG_LONG, range, 1, MPI_LONG_LONG, - MPI_COMM_WORLD); - jj = 0; - range[psc_world_size] = 0; - for (i = 0; i <= psc_world_size; i++) { - kk = range[i]; - range[i] = jj; - jj += kk; - } - rangel = range[psc_world_rank]; - rangeh = range[psc_world_rank + 1] - 1; - - delete[] neighbor; - neighbor = new int64_t[6 * nv]; - - for (z = 0; z <= lnz + 1; z++) { - for (y = 0; y <= lny + 1; y++) { - for (x = 0; x <= lnx + 1; x++) { - i = 6 * LOCAL_CELL_ID(x, y, z); - neighbor[i + 0] = rangel + LOCAL_CELL_ID(x - 1, y, z); - neighbor[i + 1] = rangel + LOCAL_CELL_ID(x, y - 1, z); - neighbor[i + 2] = rangel + LOCAL_CELL_ID(x, y, z - 1); - neighbor[i + 3] = rangel + LOCAL_CELL_ID(x + 1, y, z); - neighbor[i + 4] = rangel + LOCAL_CELL_ID(x, y + 1, z); - neighbor[i + 5] = rangel + LOCAL_CELL_ID(x, y, z + 1); - // Set boundary faces appropriately - if (x == 1) - neighbor[i + 0] = reflect_particles; - if (y == 1) - neighbor[i + 1] = reflect_particles; - if (z == 1) - neighbor[i + 2] = reflect_particles; - if (x == lnx) - neighbor[i + 3] = reflect_particles; - if (y == lny) - neighbor[i + 4] = reflect_particles; - if (z == lnz) - neighbor[i + 5] = reflect_particles; - // Set ghost cells appropriately - if (x == 0 || x == lnx + 1 || y == 0 || y == lny + 1 || z == 0 || - z == lnz + 1) { - neighbor[i + 0] = reflect_particles; - neighbor[i + 1] = reflect_particles; - neighbor[i + 2] = reflect_particles; - neighbor[i + 3] = reflect_particles; - neighbor[i + 4] = reflect_particles; - neighbor[i + 5] = reflect_particles; - } - } - } - } - } - - void join_grid(int boundary, int rank) - { - int lx, ly, lz, lnx, lny, lnz, rx, ry, rz, rnx, rny, rnz, rnc; - - assert(boundary >= 0 && boundary < 27 && boundary != BOUNDARY(0, 0, 0)); - assert(rank >= 0 && rank < psc_world_size); - - // Join phase 2 data structures - bc[boundary] = rank; - - // Join phase 3 data structures - lnx = nx; - lny = ny; - lnz = nz; - rnc = range[rank + 1] - range[rank]; // Note: rnc <~ 2^31 / 6 - -#define GLUE_FACE(tag, i, j, k, X, Y, Z) \ - BEGIN_PRIMITIVE \ - { \ - if (boundary == BOUNDARY(i, j, k)) { \ - assert(rnc % ((ln##Y + 2) * (ln##Z + 2)) == 0); \ - rn##X = (rnc / ((ln##Y + 2) * (ln##Z + 2))) - 2; \ - rn##Y = ln##Y; \ - rn##Z = ln##Z; \ - l##X = (i + j + k) < 0 ? 1 : ln##X; \ - r##X = (i + j + k) < 0 ? rn##X : 1; \ - for (l##Z = 1; l##Z <= ln##Z; l##Z++) { \ - for (l##Y = 1; l##Y <= ln##Y; l##Y++) { \ - r##Y = l##Y; \ - r##Z = l##Z; \ - neighbor[6 * LOCAL_CELL_ID(lx, ly, lz) + tag] = \ - range[rank] + REMOTE_CELL_ID(rx, ry, rz); \ - } \ - } \ - return; \ - } \ - } \ - END_PRIMITIVE - - GLUE_FACE(0, -1, 0, 0, x, y, z); - GLUE_FACE(1, 0, -1, 0, y, z, x); - GLUE_FACE(2, 0, 0, -1, z, x, y); - GLUE_FACE(3, 1, 0, 0, x, y, z); - GLUE_FACE(4, 0, 1, 0, y, z, x); - GLUE_FACE(5, 0, 0, 1, z, x, y); -#undef GLUE_FACE - } - -#undef LOCAL_CELL_ID -#undef REMOTE_CELL_ID - - void partition_periodic_box(const double xl[3], const double xh[3], - const int gdims[3], const Int3 np) - { - assert(np[0] > 0 && np[1] > 0 && np[2] > 0); - assert(gdims[0] > 0 && gdims[1] > 0 && gdims[2] > 0); - assert(gdims[0] % np[0] == 0 && gdims[1] % np[1] == 0 && - gdims[2] % np[2] == 0); - - Int3 idx = rank_to_idx(psc_world_rank, np); - - double dxyz[3]; - for (int d = 0; d < 3; d++) { - dxyz[d] = (xh[d] - xl[d]) / gdims[d]; - } - dx = dxyz[0]; - dy = dxyz[1]; - dz = dxyz[2]; - dV = dxyz[0] * dxyz[1] * dxyz[2]; - - rdx = 1. / dxyz[0]; - rdy = 1. / dxyz[1]; - rdz = 1. / dxyz[2]; - r8V = 0.125 / (dxyz[0] * dxyz[1] * dxyz[2]); - - double xyz0[3], xyz1[3]; - for (int d = 0; d < 3; d++) { - double f; - f = (double)(idx[d]) / np[d]; - xyz0[d] = xl[d] * (1 - f) + xh[d] * f; - f = (double)(idx[d] + 1) / np[d]; - xyz1[d] = xl[d] * (1 - f) + xh[d] * f; - } - x0 = xyz0[0]; - y0 = xyz0[1]; - z0 = xyz0[2]; - x1 = xyz1[0]; - y1 = xyz1[1]; - z1 = xyz1[2]; - - // Size the local grid - size_grid(gdims[0] / np[0], gdims[1] / np[1], gdims[2] / np[2]); - - // Join the grid to neighbors - int px = idx[0], py = idx[1], pz = idx[2]; - join_grid(BOUNDARY(-1, 0, 0), idx_to_rank(np, {px - 1, py, pz})); - join_grid(BOUNDARY(0, -1, 0), idx_to_rank(np, {px, py - 1, pz})); - join_grid(BOUNDARY(0, 0, -1), idx_to_rank(np, {px, py, pz - 1})); - join_grid(BOUNDARY(1, 0, 0), idx_to_rank(np, {px + 1, py, pz})); - join_grid(BOUNDARY(0, 1, 0), idx_to_rank(np, {px, py + 1, pz})); - join_grid(BOUNDARY(0, 0, 1), idx_to_rank(np, {px, py, pz + 1})); - } - - void set_fbc(int boundary, int fbc) - { - assert(boundary >= 0 && boundary < 27 && boundary != BOUNDARY(0, 0, 0) && - (fbc == anti_symmetric_fields || fbc == symmetric_fields || - fbc == pmc_fields || fbc == absorb_fields)); - - bc[boundary] = fbc; - } - - void set_pbc(int boundary, int pbc) - { - assert(boundary >= 0 && boundary < 27 && boundary != BOUNDARY(0, 0, 0) && - pbc < 0); - -#define LOCAL_CELL_ID(x, y, z) VOXEL(x, y, z, nx, ny, nz) -#define SET_PBC(tag, i, j, k, X, Y, Z) \ - BEGIN_PRIMITIVE \ - { \ - if (boundary == BOUNDARY(i, j, k)) { \ - int l##X = (i + j + k) < 0 ? 1 : n##X; \ - for (int l##Z = 1; l##Z <= n##Z; l##Z++) \ - for (int l##Y = 1; l##Y <= n##Y; l##Y++) \ - neighbor[6 * LOCAL_CELL_ID(lx, ly, lz) + tag] = pbc; \ - return; \ - } \ - } \ - END_PRIMITIVE - - SET_PBC(0, -1, 0, 0, x, y, z); - SET_PBC(1, 0, -1, 0, y, z, x); - SET_PBC(2, 0, 0, -1, z, x, y); - SET_PBC(3, 1, 0, 0, x, y, z); - SET_PBC(4, 0, 1, 0, y, z, x); - SET_PBC(5, 0, 0, 1, z, x, y); - -#undef SET_PBC -#undef LOCAL_CELL_ID - } - - void mp_size_recv_buffer(int port, int size) - { - mp->size_recv_buffer(port, size); - } - - void mp_size_send_buffer(int port, int size) - { - mp->size_send_buffer(port, size); - } - - void* mp_recv_buffer(int port) { return mp->recv_buffer(port); } - - void* mp_send_buffer(int port) { return mp->send_buffer(port); } - - void mp_begin_recv(int port, int size, int src, int tag) - { - mp->begin_recv(port, size, src, tag); - } - - void mp_begin_send(int port, int size, int dst, int tag) - { - mp->begin_send(port, size, dst, tag); - } - - void mp_end_recv(int port) { mp->end_recv(port); } - - void mp_end_send(int port) { mp->end_send(port); } - - // ---------------------------------------------------------------------- - // for field communications - - void* size_send_port(int i, int j, int k, int size) - { - int port = BOUNDARY(i, j, k), dst = bc[port]; - if (dst < 0 || dst >= psc_world_size) { - return nullptr; - } - mp_size_send_buffer(port, size); - return mp_send_buffer(port); - } - - void begin_send_port(int i, int j, int k, int size) - { - int port = BOUNDARY(i, j, k), dst = bc[port]; - if (dst < 0 || dst >= psc_world_size) { - return; - } - mp_begin_send(port, size, dst, port); - } - - void end_send_port(int i, int j, int k) - { - int port = BOUNDARY(i, j, k), dst = bc[port]; - if (dst < 0 || dst >= psc_world_size) { - return; - } - mp_end_send(port); - } - - void begin_recv_port(int i, int j, int k, int size) - { - int port = BOUNDARY(-i, -j, -k), src = bc[port]; - if (src < 0 || src >= psc_world_size) { - return; - } - mp_size_recv_buffer(port, size); - mp_begin_recv(port, size, src, BOUNDARY(i, j, k)); - } - - void* end_recv_port(int i, int j, int k) - { - int port = BOUNDARY(-i, -j, -k), src = bc[port]; - if (src < 0 || src >= psc_world_size) { - return nullptr; - } - mp_end_recv(port); - return mp_recv_buffer(port); - } - - // System of units - float dt, cvac, eps0; - - // Time stepper. The simulation time is given by - // t = g->t0 + (double)g->dt*(double)g->step - int64_t step; // Current timestep - double t0; // Simulation time corresponding to step 0 - - // Phase 2 grid data structures - float x0, y0, z0; // Min corner local domain (must be coherent) - float x1, y1, z1; // Max corner local domain (must be coherent) - int nx, ny, nz; // Local voxel mesh resolution. Voxels are - // indexed FORTRAN style 0:nx+1,0:ny+1,0:nz+1 - // with voxels 1:nx,1:ny,1:nz being non-ghost - // voxels. - float dx, dy, dz, dV; // Cell dimensions and volume (CONVENIENCE ... - // USE x0,x1 WHEN DECIDING WHICH NODE TO USE!) - float rdx, rdy, rdz, r8V; // Inverse voxel dimensions and one over - // eight times the voxel volume (CONVENIENCE) - int sx, sy, sz, nv; // Voxel indexing x-, y-,z- strides and the - // number of local voxels (including ghosts, - // (nx+2)(ny+2)(nz+2)), (CONVENIENCE) - int bc[27]; // (-1:1,-1:1,-1:1) FORTRAN indexed array of - // boundary conditions to apply at domain edge - // 0 ... nproc-1 ... comm boundary condition - // <0 ... locally applied boundary condition - - // Phase 3 grid data structures - // NOTE: VOXEL INDEXING LIMITS NUMBER OF VOXELS TO 2^31 (INCLUDING - // GHOSTS) PER NODE. NEIGHBOR INDEXING FURTHER LIMITS TO - // (2^31)/6. BOUNDARY CONDITION HANDLING LIMITS TO 2^28 PER NODE - // EMITTER COMPONENT ID INDEXING FURTHER LIMITS TO 2^26 PER NODE. - // THE LIMIT IS 2^63 OVER ALL NODES THOUGH. - int64_t* ALIGNED(16) range; - // (0:nproc) indexed array giving range of - // global indexes of voxel owned by each - // processor. Replicated on each processor. - // (range[rank]:range[rank+1]-1) are global - // voxels owned by processor "rank". Note: - // range[rank+1]-range[rank] <~ 2^31 / 6 - - int64_t* ALIGNED(128) neighbor; - // (0:5,0:local_num_voxel-1) FORTRAN indexed - // array neighbor(0:5,lidx) are the global - // indexes of neighboring voxels of the - // voxel with local index "lidx". Negative - // if neighbor is a boundary condition. - - int64_t rangel, rangeh; // Redundant for move_p performance reasons: - // rangel = range[rank] - // rangeh = range[rank+1]-1. - // Note: rangeh-rangel <~ 2^26 - - // Nearest neighbor communications ports - PscMp* mp; -}; - -#endif diff --git a/src/libpsc/vpic/PscInterpolator.h b/src/libpsc/vpic/PscInterpolator.h deleted file mode 100644 index adcf7d529e..0000000000 --- a/src/libpsc/vpic/PscInterpolator.h +++ /dev/null @@ -1,85 +0,0 @@ - -#pragma once - -// ====================================================================== -// PscInterpolatorOps - -template -struct PscInterpolatorOps -{ - using MfieldsInterpolator = _MfieldsInterpolator; - - // ---------------------------------------------------------------------- - // load - - static void load(MfieldsInterpolator& interpolator, - /*const*/ MfieldsState& mflds) - { - auto& ip = interpolator.getPatch(0); - auto& fa = mflds.getPatch(0); - Field3D F(fa); - Field3D I(ip); - - auto g = ip.grid(); - const int nx = g->nx, ny = g->ny, nz = g->nz; - const float fourth = 0.25; - const float half = 0.5; - - float w0, w1, w2, w3; - - for (int k = 1; k <= nz; k++) { - for (int j = 1; j <= ny; j++) { - for (int i = 1; i <= nx; i++) { - - // ex interpolation - w0 = F(i, j, k).ex; - w1 = F(i, j + 1, k).ex; - w2 = F(i, j, k + 1).ex; - w3 = F(i, j + 1, k + 1).ex; - I(i, j, k).ex = fourth * ((w3 + w0) + (w1 + w2)); - I(i, j, k).dexdy = fourth * ((w3 - w0) + (w1 - w2)); - I(i, j, k).dexdz = fourth * ((w3 - w0) - (w1 - w2)); - I(i, j, k).d2exdydz = fourth * ((w3 + w0) - (w1 + w2)); - - // ey interpolation coefficients - w0 = F(i, j, k).ey; - w1 = F(i, j, k + 1).ey; - w2 = F(i + 1, j, k).ey; - w3 = F(i + 1, j, k + 1).ey; - I(i, j, k).ey = fourth * ((w3 + w0) + (w1 + w2)); - I(i, j, k).deydz = fourth * ((w3 - w0) + (w1 - w2)); - I(i, j, k).deydx = fourth * ((w3 - w0) - (w1 - w2)); - I(i, j, k).d2eydzdx = fourth * ((w3 + w0) - (w1 + w2)); - - // ez interpolation coefficients - w0 = F(i, j, k).ez; - w1 = F(i + 1, j, k).ez; - w2 = F(i, j + 1, k).ez; - w3 = F(i + 1, j + 1, k).ez; - I(i, j, k).ez = fourth * ((w3 + w0) + (w1 + w2)); - I(i, j, k).dezdx = fourth * ((w3 - w0) + (w1 - w2)); - I(i, j, k).dezdy = fourth * ((w3 - w0) - (w1 - w2)); - I(i, j, k).d2ezdxdy = fourth * ((w3 + w0) - (w1 + w2)); - - // bx interpolation coefficients - w0 = F(i, j, k).cbx; - w1 = F(i + 1, j, k).cbx; - I(i, j, k).cbx = half * (w1 + w0); - I(i, j, k).dcbxdx = half * (w1 - w0); - - // by interpolation coefficients - w0 = F(i, j, k).cby; - w1 = F(i, j + 1, k).cby; - I(i, j, k).cby = half * (w1 + w0); - I(i, j, k).dcbydy = half * (w1 - w0); - - // bz interpolation coefficients - w0 = F(i, j, k).cbz; - w1 = F(i, j, k + 1).cbz; - I(i, j, k).cbz = half * (w1 + w0); - I(i, j, k).dcbzdz = half * (w1 - w0); - } - } - } - } -}; diff --git a/src/libpsc/vpic/PscParticleBc.h b/src/libpsc/vpic/PscParticleBc.h deleted file mode 100644 index a3f098bcfb..0000000000 --- a/src/libpsc/vpic/PscParticleBc.h +++ /dev/null @@ -1,35 +0,0 @@ - -#ifndef PSC_PARTICLE_BC_H -#define PSC_PARTICLE_BC_H - -#include "VpicListBase.h" - -#include -#include - -// ====================================================================== -// PscParticleBc - -struct PscParticleBc -{}; - -// ====================================================================== -// PscParticleBcList - -struct PscParticleBcList : public VpicListBase -{ - typedef PscParticleBc ParticleBc; - - ParticleBc* append(ParticleBc* pbc) - { - assert(0); - return nullptr; - } - - /* operator const particle_bc_t* () const */ - /* { */ - /* return head_; */ - /* } */ -}; - -#endif diff --git a/src/libpsc/vpic/PscParticlesBase.h b/src/libpsc/vpic/PscParticlesBase.h deleted file mode 100644 index c343bb97b1..0000000000 --- a/src/libpsc/vpic/PscParticlesBase.h +++ /dev/null @@ -1,312 +0,0 @@ - -#ifndef PSC_PARTICLES_BASE_H -#define PSC_PARTICLES_BASE_H - -#include "psc_particles.h" -#include "VpicListBase.h" - -// ====================================================================== -// PscSpecies - -// FIXME: Eventually Particle (definitely) and the other formats -// (maybe) should be opaque and specific to a particular -// species_advance implementation - -struct PscParticle -{ - float dx, dy, dz; // Particle position in cell coordinates (on [-1,1]) - int32_t i; // Voxel containing the particle. Note that - /**/ // particled awaiting processing by boundary_p - /**/ // have actually set this to 8*voxel + face where - /**/ // face is the index of the face they interacted - /**/ // with (on 0:5). This limits the local number of - /**/ // voxels to 2^28 but emitter handling already - /**/ // has a stricter limit on this (2^26). - float ux, uy, uz; // Particle normalized momentum - float w; // Particle weight (number of physical particles) -}; - -// WARNING: FUNCTIONS THAT USE A PARTICLE_MOVER ASSUME THAT EVERYBODY -// WHO USES THAT PARTICLE MOVER WILL HAVE ACCESS TO PARTICLE ARRAY - -struct PscParticleMover -{ - float dispx, dispy, dispz; // Displacement of particle - int32_t i; // Index of the particle to move -}; - -// NOTE: THE LAYOUT OF A PARTICLE_INJECTOR _MUST_ BE COMPATIBLE WITH -// THE CONCATENATION OF A PARTICLE_T AND A PARTICLE_MOVER! - -struct PscParticleInjector -{ - float dx, dy, dz; // Particle position in cell coords (on [-1,1]) - int32_t i; // Index of cell containing the particle - float ux, uy, uz; // Particle normalized momentum - float w; // Particle weight (number of physical particles) - float dispx, dispy, dispz; // Displacement of particle - SpeciesId sp_id; // Species of particle -}; - -template -struct PscSpecies -{ - typedef G Grid; - - // ---------------------------------------------------------------------- - // PscSpecies::ctor - - PscSpecies(const char* name, float q, float m, int max_local_np, - int max_local_nm, int sort_interval, int sort_out_of_place, - Grid* grid) - { - memset(this, 0, sizeof(*this)); // FIXME - int len = name ? strlen(name) : 0; - assert(len); - assert(grid); - assert(grid->nv); - assert(max_local_np > 0); - assert(max_local_nm > 0); - - this->name = strdup(name); - - this->q = q; - this->m = m; - - this->p = new PscParticle[max_local_np]; - this->max_np = max_local_np; - - this->pm = new PscParticleMover[max_local_nm]; - this->max_nm = max_local_nm; - - this->last_sorted = INT64_MIN; - this->sort_interval = sort_interval; - this->sort_out_of_place = sort_out_of_place; - this->partition = new int[grid->nv + 1]; - - this->grid_ = grid; - } - - // ---------------------------------------------------------------------- - // PscSpecies::dtor - - ~PscSpecies() - { - delete[] partition; - delete[] pm; - delete[] p; - free(name); - } - - const Grid& vgrid() const { return *grid_; } - - char* name; // Species name - float q; // Species particle charge - float m; // Species particle rest mass - - int np, max_np; // Number and max local particles - PscParticle* ALIGNED(128) p; // Array of particles for the species - - int nm, max_nm; // Number and max local movers in use - PscParticleMover* ALIGNED(128) pm; // Particle movers - - int64_t last_sorted; // Step when the particles were last - // sorted. - int sort_interval; // How often to sort the species - int sort_out_of_place; // Sort method - int* ALIGNED(128) partition; // Static array indexed 0: - /**/ // (nx+2)*(ny+2)*(nz+2). Each value - /**/ // corresponds to the associated particle - /**/ // array index of the first particle in - /**/ // the cell. Array is allocated and - /**/ // values computed in sort_p. Purpose is - /**/ // for implementing collision models - /**/ // This is given in terms of the - /**/ // underlying's grids space filling - /**/ // curve indexing. Thus, immediately - /**/ // after a sort: - /**/ // sp->p[sp->partition[g->sfc[i] ]: - /**/ // sp->partition[g->sfc[i]+1]-1] - /**/ // are all the particles in voxel - /**/ // with local index i, while: - /**/ // sp->p[ sp->partition[ j ]: - /**/ // sp->partition[ j+1 ] ] - /**/ // are all the particles in voxel - /**/ // with space filling curve index j. - /**/ // Note: SFC NOT IN USE RIGHT NOW THUS - /**/ // g->sfc[i]=i ABOVE. -private: - Grid* grid_; // Underlying grid - -public: // FIXME, shouldn't be public - SpeciesId id; // Unique identifier for a species - PscSpecies* next; // Next species in the list -}; - -// ====================================================================== -// PscParticlesBase - -template -struct PscParticlesBase : public VpicListBase> -{ - typedef G Grid; - typedef BCL ParticleBcList; - typedef PscSpecies Species; - typedef VpicListBase Base; - typedef PscParticle Particle; - typedef PscParticleMover ParticleMover; - - using Base::begin; - using Base::end; - using Base::head_; - using Base::push_front; - using Base::size; - using typename Base::const_iterator; - using typename Base::iterator; - - static Species* create(const char* name, float q, float m, int max_local_np, - int max_local_nm, int sort_interval, - int sort_out_of_place, Grid* grid) - { - return new Species(name, q, m, max_local_np, max_local_nm, sort_interval, - sort_out_of_place, grid); - } - - size_t getNumSpecies() { return size(); } - - iterator find(int id) - { - return std::find_if(begin(), end(), - [&id](const Species& sp) { return sp.id == id; }); - } - - iterator find(const char* name) - { - return std::find_if(begin(), end(), [&name](const Species& sp) { - return strcmp(sp.name, name) == 0; - }); - } - - Species* append(Species* sp) - { - assert(!sp->next); - if (find(sp->name) != end()) { - LOG_ERROR("There is already a species named \"%s\" in list", sp->name); - } - sp->id = size(); - push_front(*sp); - return sp; - } - - // ---------------------------------------------------------------------- - // inject_particle_reweight - - void inject_particle_reweight(const psc::particle::Inject& prt) - { - auto sp = find(prt.kind); - assert(sp != end()); - - double x = prt.x[0], y = prt.x[1], z = prt.x[2]; - double ux = prt.u[0], uy = prt.u[1], uz = prt.u[2]; - double w = prt.w; -#if 0 - double age = 0.; - int update_rhob = 0; -#endif - - int ix, iy, iz; - - const auto& vgrid = sp->vgrid(); - double x0 = vgrid.x0, y0 = vgrid.y0, z0 = vgrid.z0; - double x1 = vgrid.x1, y1 = vgrid.y1, z1 = vgrid.z1; - int nx = vgrid.nx, ny = vgrid.ny, nz = vgrid.nz; - - // Do not inject if the particle is strictly outside the local domain - // or if a far wall of local domain shared with a neighbor - - if ((x < x0) | (x > x1) | ((x == x1) & (vgrid.bc[BOUNDARY(1, 0, 0)] >= 0))) - return; - if ((y < y0) | (y > y1) | ((y == y1) & (vgrid.bc[BOUNDARY(0, 1, 0)] >= 0))) - return; - if ((z < z0) | (z > z1) | ((z == z1) & (vgrid.bc[BOUNDARY(0, 0, 1)] >= 0))) - return; - - // This node should inject the particle - - if (sp->np >= sp->max_np) - LOG_ERROR("No room to inject particle"); - - // Compute the injection cell and coordinate in cell coordinate system - // BJA: Note the use of double precision here for accurate particle - // placement on large meshes. - - // The ifs allow for injection on the far walls of the local computational - // domain when necessary - - x = ((double)nx) * ((x - x0) / (x1 - x0)); // x is rigorously on [0,nx] - ix = (int)x; // ix is rigorously on [0,nx] - x -= (double)ix; // x is rigorously on [0,1) - x = (x + x) - 1; // x is rigorously on [-1,1) - if (ix == nx) - x = 1; // On far wall ... conditional move - if (ix == nx) - ix = nx - 1; // On far wall ... conditional move - ix++; // Adjust for mesh indexing - - y = ((double)ny) * ((y - y0) / (y1 - y0)); // y is rigorously on [0,ny] - iy = (int)y; // iy is rigorously on [0,ny] - y -= (double)iy; // y is rigorously on [0,1) - y = (y + y) - 1; // y is rigorously on [-1,1) - if (iy == ny) - y = 1; // On far wall ... conditional move - if (iy == ny) - iy = ny - 1; // On far wall ... conditional move - iy++; // Adjust for mesh indexing - - z = ((double)nz) * ((z - z0) / (z1 - z0)); // z is rigorously on [0,nz] - iz = (int)z; // iz is rigorously on [0,nz] - z -= (double)iz; // z is rigorously on [0,1) - z = (z + z) - 1; // z is rigorously on [-1,1) - if (iz == nz) - z = 1; // On far wall ... conditional move - if (iz == nz) - iz = nz - 1; // On far wall ... conditional move - iz++; // Adjust for mesh indexing - - Particle* p = sp->p + (sp->np++); - p->dx = (float)x; // Note: Might be rounded to be on [-1,1] - p->dy = (float)y; // Note: Might be rounded to be on [-1,1] - p->dz = (float)z; // Note: Might be rounded to be on [-1,1] - p->i = VOXEL(ix, iy, iz, nx, ny, nz); - p->ux = (float)ux; - p->uy = (float)uy; - p->uz = (float)uz; - p->w = w; - -#if 0 - if (update_rhob) accumulate_rhob(fa, p, -sp->q); - - if (age!=0) { - if( sp->nm >= sp->max_nm ) - LOG_WARN("No movers available to age injected particle"); - ParticleMover * pm = sp->pm + sp->nm; - age *= grid->cvac*grid->dt/sqrt( ux*ux + uy*uy + uz*uz + 1 ); - pm->dispx = ux*age*grid->rdx; - pm->dispy = uy*age*grid->rdy; - pm->dispz = uz*age*grid->rdz; - pm->i = sp->np-1; - sp->nm += move_p( sp->p, pm, accumulator[0], grid, sp->q ); - } -#endif - } - - const Grid& vgrid() const - { - assert(head_); - return head_->vgrid(); - } - - Species* head() { return head_; } -}; - -#endif diff --git a/src/libpsc/vpic/PscParticlesOps.h b/src/libpsc/vpic/PscParticlesOps.h deleted file mode 100644 index 57eeee9472..0000000000 --- a/src/libpsc/vpic/PscParticlesOps.h +++ /dev/null @@ -1,1564 +0,0 @@ - -#pragma once - -#include "bits.hxx" - -#ifdef USE_VPIC -#define HAS_V4_PIPELINE -#endif - -#ifdef HAS_V4_PIPELINE -#define USE_V4_SSE -#include "util/v4/v4.h" -#endif - -struct ParticleInjector -{ - float dx, dy, dz; // Particle position in cell coords (on [-1,1]) - int32_t i; // Index of cell containing the particle - float ux, uy, uz; // Particle normalized momentum - float w; // Particle weight (number of physical particles) - float dispx, dispy, dispz; // Displacement of particle - SpeciesId sp_id; // Species of particle -}; - -template -struct PscParticlesOps -{ - using Grid = typename Mparticles::Grid; - using Species = typename Mparticles::Species; - using Particle = typename Mparticles::Particle; - using ParticleMover = typename Mparticles::ParticleMover; - using ParticleBcList = typename Mparticles::ParticleBcList; - using AccumulatorBlock = typename MfieldsAccumulator::Block; - - // ---------------------------------------------------------------------- - // move_p - // - // move_p moves the particle m->p by m->dispx, m->dispy, m->dispz - // depositing particle current as it goes. If the particle was moved - // sucessfully (particle mover is no longer in use) returns 0. If the - // particle interacted with something this routine could not handle, - // this routine returns 1 (particle mover is still in use). On a - // successful move, the particle position is updated and m->dispx, - // m->dispy and m->dispz are zerod. On a partial move, the particle - // position is updated to the point where the particle interacted and - // m->dispx, m->dispy, m->dispz contains the remaining particle - // displacement. The displacements are the physical displacments - // normalized current cell size. - // - // Because move_p is frequently called, it does not check its input - // arguments. Higher level routines are responsible for insuring valid - // arguments. - // - // Note: changes here likely need to be reflected in SPE accelerated - // version as well. - -#define ACCUMULATE_J(u, d, X, Y, Z, offset) \ - v4 = q * u##X; /* v2 = q ux */ \ - v1 = v4 * d##Y; /* v1 = q ux dy */ \ - v0 = v4 - v1; /* v0 = q ux (1-dy) */ \ - v1 += v4; /* v1 = q ux (1+dy) */ \ - v4 = one + d##Z; /* v4 = 1+dz */ \ - v2 = v0 * v4; /* v2 = q ux (1-dy)(1+dz) */ \ - v3 = v1 * v4; /* v3 = q ux (1+dy)(1+dz) */ \ - v4 = one - d##Z; /* v4 = 1-dz */ \ - v0 *= v4; /* v0 = q ux (1-dy)(1-dz) */ \ - v1 *= v4; /* v1 = q ux (1+dy)(1-dz) */ \ - v0 += v5; /* v0 = q ux [ (1-dy)(1-dz) + uy*uz/3 ] */ \ - v1 -= v5; /* v1 = q ux [ (1+dy)(1-dz) - uy*uz/3 ] */ \ - v2 -= v5; /* v2 = q ux [ (1-dy)(1+dz) - uy*uz/3 ] */ \ - v3 += v5; /* v3 = q ux [ (1+dy)(1+dz) + uy*uz/3 ] */ \ - a[offset + 0] += v0; \ - a[offset + 1] += v1; \ - a[offset + 2] += v2; \ - a[offset + 3] += v3 - -#if defined(V4_ACCELERATION) - - // High performance variant based on SPE accelerated version - - static int move_p(Particle* RESTRICT ALIGNED(128) p, - ParticleMover* RESTRICT ALIGNED(16) pm, - AccumulatorBlock acc_block, const Grid& g, const float qsp) - { - using namespace v4; - - /*const*/ v4float one(1.f); - /*const*/ v4float tiny(1e-37f); - /*const*/ v4int sign_bits(1 << 31); - - v4float dr, r, u, q, q3; - v4float sgn_dr, s, sdr; - v4float v0, v1, v2, v3, v4, v5, _stack_vf; - v4int bits, _stack_vi; - - float* RESTRICT ALIGNED(16) stack_vf = (float*)&_stack_vf; - int* RESTRICT ALIGNED(16) stack_vi = (int*)&_stack_vi; - float f0, f1; - int32_t n, voxel; - int64_t neighbor; - int type; - - load_4x1(&pm->dispx, dr); - n = pm->i; - load_4x1(&p[n].dx, r); - voxel = p[n].i; - load_4x1(&p[n].ux, u); - - q = v4float(qsp) * splat<3>(u); // q = p_q, p_q, p_q, D/C - q3 = v4float(1.f / 3.f) * q; // q3 = p_q/3, p_q/3, p_q/3, D/C - dr = shuffle<0, 1, 2, 2>(dr); // dr = p_ddx, p_ddy, p_ddz, D/C - r = shuffle<0, 1, 2, 2>(r); // r = p_dx, p_dy, p_dz, D/C - - for (;;) { - - // At this point: - // r = current particle position in local voxel coordinates - // (note the current voxel is on [-1,1]^3. - // dr = remaining particle displacment - // (note: this is in voxel edge lengths!) - // voxel = local voxel of particle - // Thus, in the local coordinate system, it is desired to move the - // particle through all points in the local coordinate system: - // streak_r(s) = r + 2 disp s for s in [0,1] - // - // Determine the fractional length and type of current - // streak made by the particle through this voxel. The streak - // ends on either the first voxel face intersected by the - // particle track or at the end of the particle track. - // - // Note: a divide by zero cannot occur below due to the shift of - // the denominator by tiny. Also, the shift by tiny is large - // enough that the divide will never overflow when dr is tiny - // (|sgn_dr-r|<=2 => 2/tiny = 2e+37 < FLT_MAX = 3.4e38). - // Likewise, due to speed of light limitations, generally dr - // cannot get much larger than 1 or so and the numerator, if not - // zero, can generally never be smaller than FLT_EPS/2. Thus, - // likewise, the divide will never underflow either. - - // FIXME: THIS COULD PROBABLY BE DONE EVEN FASTER - sgn_dr = copysign(one, dr); - v0 = copysign(tiny, dr); - store_4x1((sgn_dr - r) / ((dr + dr) + v0), stack_vf); - /**/ type = 3; - f0 = 1; - f1 = stack_vf[0]; - if (f1 < f0) - type = 0; - if (f1 < f0) - f0 = f1; // Branchless cmov - f1 = stack_vf[1]; - if (f1 < f0) - type = 1; - if (f1 < f0) - f0 = f1; - f1 = stack_vf[2]; - if (f1 < f0) - type = 2; - if (f1 < f0) - f0 = f1; - s = v4float(f0); - - // At this point: - // type = 0,1 or 2 ... streak ends on a x,y or z-face respectively - // 3 ... streak ends at end of the particle track - // s = SPLAT( normalized length of the current streak ) - // sgn_dr indicates the sign streak displacements. This is - // useful to determine whether or not the streak hit a face. - // - // Compute the streak midpoint the normalized displacement, - // update the particle position and remaining displacment, - // compute accumulator coefficients, finish up fetching the - // voxel needed for this streak and accumule the streak. Note: - // accumulator values are 4 times the total physical charge that - // passed through the appropriate current quadrant in a - // timestep. - - sdr = s * dr; // sdr = ux, uy, uz, D/C - v5 = r + sdr; // v5 = dx, dy, dz, D/C - - dr -= sdr; // dr = p_ddx', p_ddy', p_ddz', D/C - r += sdr + sdr; // r = p_dx', p_dy', p_dz', D/C - - v4 = q * sdr; // v4 = q ux, q uy, q uz, D/C - v1 = v4 * shuffle<1, 2, 0, 3>(v5); - /**/ // v1 = q ux dy, q uy dz, q uz dx, D/C - v0 = v4 - v1; // v0 = q ux(1-dy), q uy(1-dz), q uz(1-dx), D/C - v1 += v4; // v1 = q ux(1+dy), q uy(1+dz), q uz(1+dx), D/C - - v5 = shuffle<2, 0, 1, 3>(v5); // v5 = dz, dx, dy, D/C - v4 = one + v5; // v4 = 1+dz, 1+dx, 1+dy, D/C - v2 = v0 * v4; // v2 = q ux(1-dy)(1+dz), ..., D/C - v3 = v1 * v4; // v3 = q ux(1+dy)(1+dz), ..., D/C - v4 = one - v5; // v4 = 1-dz, 1-dx, 1-dy, D/C - v0 *= v4; // v0 = q ux(1-dy)(1-dz), ..., D/C - v1 *= v4; // v1 = q ux(1+dy)(1-dz), ..., D/C - - // v4 = ((q3*splat(sdr,0))*splat(sdr,1))*splat(sdr,2); - v4 = ((q3 * splat<0>(sdr)) * splat<1>(sdr)) * splat<2>(sdr); - // FIXME: splat ambiguity in v4 prevents flattening - /**/ // v4 = q ux uy uz/3,q ux uy uz/3,q ux uy uz/3,D/C - v0 += v4; // v0 = q ux[(1-dy)(1-dz)+uy uz/3], ..., D/C - v1 -= v4; // v1 = q ux[(1+dy)(1-dz)-uy uz/3], ..., D/C - v2 -= v4; // v2 = q ux[(1-dy)(1+dz)-uy uz/3], ..., D/C - v3 += v4; // v3 = q ux[(1+dy)(1+dz)+uy uz/3], ..., D/C - - transpose(v0, v1, v2, v3); - - increment_4x1(acc_block[voxel].jx, v0); - increment_4x1(acc_block[voxel].jy, v1); - increment_4x1(acc_block[voxel].jz, v2); - - // If streak ended at the end of the particle track, this mover - // was succesfully processed. Should be just under ~50% of the - // time. - - if (type == 3) { - store_4x1(r, &p[n].dx); - p[n].i = voxel; - break; - } - - // Streak terminated on a voxel face. Determine if the particle - // crossed into a local voxel or if it hit a boundary. Convert - // the particle coordinates accordingly. Note: Crossing into a - // local voxel should happen the most of the time once we get to - // this point; hitting a structure or parallel domain boundary - // should usually be a rare event. */ - - clear_4x1(stack_vi); - stack_vi[type] = -1; - load_4x1(stack_vi, bits); - r = merge(bits, sgn_dr, r); // Avoid roundoff fiascos--put the - // particle _exactly_ on the - // boundary. - bits &= sign_bits; // bits(type)==(-0.f) and 0 elsewhere - - // Determine if the particle crossed into a local voxel or if it - // hit a boundary. Convert the particle coordinates accordingly. - // Note: Crossing into a local voxel should happen the other ~50% - // of time; hitting a structure and parallel domain boundary - // should usually be a rare event. Note: the entry / exit - // coordinate for the particle is guaranteed to be +/-1 _exactly_ - // for the particle. - - store_4x1(sgn_dr, stack_vf); - if (stack_vf[type] > 0) - type += 3; - neighbor = g->neighbor[6 * voxel + type]; - - if (UNLIKELY(neighbor == Grid::reflect_particles)) { - - // Hit a reflecting boundary condition. Reflect the particle - // momentum and remaining displacement and keep moving the - // particle. - - dr = toggle_bits(bits, dr); - u = toggle_bits(bits, u); - store_4x1(u, &p[n].ux); - continue; - } - - if (UNLIKELY(neighbor < g->rangel || neighbor > g->rangeh)) { - - // Cannot handle the boundary condition here. Save the updated - // particle position and update the remaining displacement in - // the particle mover. - - store_4x1(r, &p[n].dx); - p[n].i = 8 * voxel + type; - store_4x1(dr, &pm->dispx); - pm->i = n; - return 1; // Mover still in use - } - - // Crossed into a normal voxel. Update the voxel index, convert the - // particle coordinate system and keep moving the particle. - - voxel = (int32_t)(neighbor - g->rangel); - r = toggle_bits(bits, r); - } - - return 0; // Mover not in use - } - -#else - - static int move_p(Particle* ALIGNED(128) p0, ParticleMover* ALIGNED(16) pm, - AccumulatorBlock acc_block, const Grid& g, float qsp) - { - float s_midx, s_midy, s_midz; - float s_dispx, s_dispy, s_dispz; - float s_dir[3]; - float v0, v1, v2, v3, v4, v5, q; - int axis, face; - int64_t neighbor; - float* a; - Particle* ALIGNED(32) p = p0 + pm->i; - - // FIXME, this uses double precision constants in a bunch of places - const float one = 1.; - - q = qsp * p->w; - - for (;;) { - s_midx = p->dx; - s_midy = p->dy; - s_midz = p->dz; - - s_dispx = pm->dispx; - s_dispy = pm->dispy; - s_dispz = pm->dispz; - - s_dir[0] = (s_dispx > 0) ? 1 : -1; - s_dir[1] = (s_dispy > 0) ? 1 : -1; - s_dir[2] = (s_dispz > 0) ? 1 : -1; - - // Compute the twice the fractional distance to each potential - // streak/cell face intersection. - v0 = (s_dispx == 0) ? 3.4e38 : (s_dir[0] - s_midx) / s_dispx; - v1 = (s_dispy == 0) ? 3.4e38 : (s_dir[1] - s_midy) / s_dispy; - v2 = (s_dispz == 0) ? 3.4e38 : (s_dir[2] - s_midz) / s_dispz; - - // Determine the fractional length and axis of current streak. The - // streak ends on either the first face intersected by the - // particle track or at the end of the particle track. - // - // axis 0,1 or 2 ... streak ends on a x,y or z-face respectively - // axis 3 ... streak ends at end of the particle track - /**/ v3 = 2, axis = 3; - if (v0 < v3) - v3 = v0, axis = 0; - if (v1 < v3) - v3 = v1, axis = 1; - if (v2 < v3) - v3 = v2, axis = 2; - v3 *= 0.5; - - // Compute the midpoint and the normalized displacement of the streak - s_dispx *= v3; - s_dispy *= v3; - s_dispz *= v3; - s_midx += s_dispx; - s_midy += s_dispy; - s_midz += s_dispz; - - // Accumulate the streak. Note: accumulator values are 4 times - // the total physical charge that passed through the appropriate - // current quadrant in a time-step - v5 = q * s_dispx * s_dispy * s_dispz * (1. / 3.); - a = (float*)&acc_block[p->i]; - - ACCUMULATE_J(s_disp, s_mid, x, y, z, 0); - ACCUMULATE_J(s_disp, s_mid, y, z, x, 4); - ACCUMULATE_J(s_disp, s_mid, z, x, y, 8); - - // Compute the remaining particle displacment - pm->dispx -= s_dispx; - pm->dispy -= s_dispy; - pm->dispz -= s_dispz; - - // Compute the new particle offset - p->dx += s_dispx + s_dispx; - p->dy += s_dispy + s_dispy; - p->dz += s_dispz + s_dispz; - - // If an end streak, return success (should be ~50% of the time) - - if (axis == 3) - break; - - // Determine if the particle crossed into a local cell or if it - // hit a boundary and convert the coordinate system accordingly. - // Note: Crossing into a local cell should happen ~50% of the - // time; hitting a boundary is usually a rare event. Note: the - // entry / exit coordinate for the particle is guaranteed to be - // +/-1 _exactly_ for the particle. - - v0 = s_dir[axis]; - (&(p->dx))[axis] = v0; // Avoid roundoff fiascos--put the particle - // _exactly_ on the boundary. - face = axis; - if (v0 > 0) - face += 3; - neighbor = g.neighbor[6 * p->i + face]; - - if (UNLIKELY(neighbor == Grid::reflect_particles)) { - // Hit a reflecting boundary condition. Reflect the particle - // momentum and remaining displacement and keep moving the - // particle. - (&(p->ux))[axis] = -(&(p->ux))[axis]; - (&(pm->dispx))[axis] = -(&(pm->dispx))[axis]; - continue; - } - - if (UNLIKELY(neighbor < g.rangel || neighbor > g.rangeh)) { - // Cannot handle the boundary condition here. Save the updated - // particle position, face it hit and update the remaining - // displacement in the particle mover. - p->i = 8 * p->i + face; - return 1; // Return "mover still in use" - } - - // Crossed into a normal voxel. Update the voxel index, convert the - // particle coordinate system and keep moving the particle. - - p->i = neighbor - g.rangel; // Compute local index of neighbor - /**/ // Note: neighbor - g.rangel < 2^31 / 6 - (&(p->dx))[axis] = -v0; // Convert coordinate system - } - - return 0; // Return "mover not in use" - } - -#endif - - // ---------------------------------------------------------------------- - // advance_p - - typedef struct particle_mover_seg - { - int nm; // Number of movers used - int n_ignored; // Number of movers ignored - } particle_mover_seg_t; - - static void advance_p_pipeline(typename Mparticles::Species& sp, - AccumulatorBlock acc_block, - MfieldsInterpolator& interpolator, - particle_mover_seg_t* seg, - Particle* ALIGNED(128) p, int n, - ParticleMover* ALIGNED(16) pm, int max_nm) - { - Particle* ALIGNED(128) p0 = sp.p; - const auto& g = sp.vgrid(); - auto& ip = interpolator.getPatch(0); - - const typename MfieldsInterpolator::Element* ALIGNED(16) f; - float* ALIGNED(16) a; - - const float qdt_2mc = (sp.q * g.dt) / (2 * sp.m * g.cvac); - const float cdt_dx = g.cvac * g.dt * g.rdx; - const float cdt_dy = g.cvac * g.dt * g.rdy; - const float cdt_dz = g.cvac * g.dt * g.rdz; - const float qsp = sp.q; - - const float one = 1.; - const float one_third = 1. / 3.; - const float two_fifteenths = 2. / 15.; - - float dx, dy, dz, ux, uy, uz, q; - float hax, hay, haz, cbx, cby, cbz; - float v0, v1, v2, v3, v4, v5; - - int ii; - - DECLARE_ALIGNED_ARRAY(ParticleMover, 16, local_pm, 1); - - int nm = 0; - int n_ignored = 0; - - // Process particles for this pipeline - - for (; n; n--, p++) { - dx = p->dx; // Load position - dy = p->dy; - dz = p->dz; - ii = p->i; - f = &ip[ii]; // Interpolate E - hax = qdt_2mc * - ((f->ex + dy * f->dexdy) + dz * (f->dexdz + dy * f->d2exdydz)); - hay = qdt_2mc * - ((f->ey + dz * f->deydz) + dx * (f->deydx + dz * f->d2eydzdx)); - haz = qdt_2mc * - ((f->ez + dx * f->dezdx) + dy * (f->dezdy + dx * f->d2ezdxdy)); - cbx = f->cbx + dx * f->dcbxdx; // Interpolate B - cby = f->cby + dy * f->dcbydy; - cbz = f->cbz + dz * f->dcbzdz; - ux = p->ux; // Load momentum - uy = p->uy; - uz = p->uz; - q = p->w; - ux += hax; // Half advance E - uy += hay; - uz += haz; - v0 = qdt_2mc / sqrtf(one + (ux * ux + (uy * uy + uz * uz))); - /**/ // Boris - scalars - v1 = cbx * cbx + (cby * cby + cbz * cbz); - v2 = (v0 * v0) * v1; - v3 = v0 * (one + v2 * (one_third + v2 * two_fifteenths)); - v4 = v3 / (one + v1 * (v3 * v3)); - v4 += v4; - v0 = ux + v3 * (uy * cbz - uz * cby); // Boris - uprime - v1 = uy + v3 * (uz * cbx - ux * cbz); - v2 = uz + v3 * (ux * cby - uy * cbx); - ux += v4 * (v1 * cbz - v2 * cby); // Boris - rotation - uy += v4 * (v2 * cbx - v0 * cbz); - uz += v4 * (v0 * cby - v1 * cbx); - ux += hax; // Half advance E - uy += hay; - uz += haz; - p->ux = ux; // Store momentum - p->uy = uy; - p->uz = uz; - v0 = one / sqrtf(one + (ux * ux + (uy * uy + uz * uz))); - /**/ // Get norm displacement - ux *= cdt_dx; - uy *= cdt_dy; - uz *= cdt_dz; - ux *= v0; - uy *= v0; - uz *= v0; - v0 = dx + ux; // Streak midpoint (inbnds) - v1 = dy + uy; - v2 = dz + uz; - v3 = v0 + ux; // New position - v4 = v1 + uy; - v5 = v2 + uz; - - // FIXME-KJB: COULD SHORT CIRCUIT ACCUMULATION IN THE CASE WHERE QSP==0! - if (v3 <= one && v4 <= one && v5 <= one && // Check if inbnds - -v3 <= one && -v4 <= one && -v5 <= one) { - - // Common case (inbnds). Note: accumulator values are 4 times - // the total physical charge that passed through the appropriate - // current quadrant in a time-step - - q *= qsp; - p->dx = v3; // Store new position - p->dy = v4; - p->dz = v5; - dx = v0; // Streak midpoint - dy = v1; - dz = v2; - v5 = q * ux * uy * uz * one_third; // Compute correction - a = (float*)&acc_block[ii]; // Get accumulator - - ACCUMULATE_J(u, d, x, y, z, 0); - ACCUMULATE_J(u, d, y, z, x, 4); - ACCUMULATE_J(u, d, z, x, y, 8); - -#undef ACCUMULATE_J - - } else { // Unlikely - local_pm->dispx = ux; - local_pm->dispy = uy; - local_pm->dispz = uz; - local_pm->i = p - p0; - - if (move_p(p0, local_pm, acc_block, g, qsp)) { // Unlikely - if (nm < max_nm) { - pm[nm++] = local_pm[0]; - } else { - n_ignored++; // Unlikely - } // if - } // if - } - } - - seg->nm = nm; - seg->n_ignored = n_ignored; - } - -#if defined(V4_ACCELERATION) && defined(HAS_V4_PIPELINE) - - static void advance_p_pipeline_v4(typename Mparticles::Species& sp, - AccumulatorBlock acc_block, - MfieldsInterpolator& interpolator, - particle_mover_seg_t* seg, - Particle* ALIGNED(128) p, int n, - ParticleMover* ALIGNED(16) pm, int max_nm) - { - using namespace v4; - - Particle* ALIGNED(128) p0 = sp.p; - const auto& g = sp.vgrid(); - - float* ALIGNED(16) vp0; - float* ALIGNED(16) vp1; - float* ALIGNED(16) vp2; - float* ALIGNED(16) vp3; - - const v4float qdt_2mc = (sp.q * g->dt) / (2 * sp.m * g->cvac); - const v4float cdt_dx = g->cvac * g->dt * g->rdx; - const v4float cdt_dy = g->cvac * g->dt * g->rdy; - const v4float cdt_dz = g->cvac * g->dt * g->rdz; - const v4float qsp = sp.q; - - const v4float one = 1.; - const v4float one_third = 1. / 3.; - const v4float two_fifteenths = 2. / 15.; - const v4float neg_one = -1.; - - const float _qsp = sp.q; - - v4float dx, dy, dz, ux, uy, uz, q; - v4float hax, hay, haz, cbx, cby, cbz; - v4float v0, v1, v2, v3, v4, v5; - v4int ii, outbnd; - - DECLARE_ALIGNED_ARRAY(ParticleMover, 16, local_pm, 1); - - int nq = n >> 2; - - int nm = 0; - int n_ignored = 0; - - auto& ip = interpolator.getPatch(0); - - // Process the particle quads for this pipeline - - for (; nq; nq--, p += 4) { - load_4x4_tr(&p[0].dx, &p[1].dx, &p[2].dx, &p[3].dx, dx, dy, dz, ii); - - // Interpolate fields - vp0 = (float* ALIGNED(16))(&ip[ii(0)]); - vp1 = (float* ALIGNED(16))(&ip[ii(1)]); - vp2 = (float* ALIGNED(16))(&ip[ii(2)]); - vp3 = (float* ALIGNED(16))(&ip[ii(3)]); - load_4x4_tr(vp0, vp1, vp2, vp3, hax, v0, v1, v2); - hax = qdt_2mc * fma(fma(v2, dy, v1), dz, fma(v0, dy, hax)); - load_4x4_tr(vp0 + 4, vp1 + 4, vp2 + 4, vp3 + 4, hay, v3, v4, v5); - hay = qdt_2mc * fma(fma(v5, dz, v4), dx, fma(v3, dz, hay)); - load_4x4_tr(vp0 + 8, vp1 + 8, vp2 + 8, vp3 + 8, haz, v0, v1, v2); - haz = qdt_2mc * fma(fma(v2, dx, v1), dy, fma(v0, dx, haz)); - load_4x4_tr(vp0 + 12, vp1 + 12, vp2 + 12, vp3 + 12, cbx, v3, cby, v4); - cbx = fma(v3, dx, cbx); - /**/ cby = fma(v4, dy, cby); - load_4x2_tr(vp0 + 16, vp1 + 16, vp2 + 16, vp3 + 16, cbz, v5); - cbz = fma(v5, dz, cbz); - - // Update momentum - // If you are willing to eat a 5-10% performance hit, - // v0 = qdt_2mc/sqrt(blah) is a few ulps more accurate (but still - // quite in the noise numerically) for cyclotron frequencies - // approaching the nyquist frequency. - - load_4x4_tr(&p[0].ux, &p[1].ux, &p[2].ux, &p[3].ux, ux, uy, uz, q); - ux += hax; - uy += hay; - uz += haz; - v0 = qdt_2mc * rsqrt(one + fma(ux, ux, fma(uy, uy, uz * uz))); - v1 = fma(cbx, cbx, fma(cby, cby, cbz * cbz)); - v2 = (v0 * v0) * v1; - v3 = v0 * fma(fma(two_fifteenths, v2, one_third), v2, one); - v4 = v3 * rcp(fma(v3 * v3, v1, one)); - v4 += v4; - v0 = fma(fms(uy, cbz, uz * cby), v3, ux); - v1 = fma(fms(uz, cbx, ux * cbz), v3, uy); - v2 = fma(fms(ux, cby, uy * cbx), v3, uz); - ux = fma(fms(v1, cbz, v2 * cby), v4, ux); - uy = fma(fms(v2, cbx, v0 * cbz), v4, uy); - uz = fma(fms(v0, cby, v1 * cbx), v4, uz); - ux += hax; - uy += hay; - uz += haz; - store_4x4_tr(ux, uy, uz, q, &p[0].ux, &p[1].ux, &p[2].ux, &p[3].ux); - - // Update the position of inbnd particles - v0 = rsqrt(one + fma(ux, ux, fma(uy, uy, uz * uz))); - ux *= cdt_dx; - uy *= cdt_dy; - uz *= cdt_dz; - ux *= v0; - uy *= v0; - uz *= v0; // ux,uy,uz are normalized displ (relative to cell size) - v0 = dx + ux; - v1 = dy + uy; - v2 = dz + uz; // New particle midpoint - v3 = v0 + ux; - v4 = v1 + uy; - v5 = v2 + uz; // New particle position - outbnd = (v3 > one) | (v3 < neg_one) | (v4 > one) | (v4 < neg_one) | - (v5 > one) | (v5 < neg_one); - v3 = merge(outbnd, dx, v3); // Do not update outbnd particles - v4 = merge(outbnd, dy, v4); - v5 = merge(outbnd, dz, v5); - store_4x4_tr(v3, v4, v5, ii, &p[0].dx, &p[1].dx, &p[2].dx, &p[3].dx); - - // Accumulate current of inbnd particles - // Note: accumulator values are 4 times the total physical charge that - // passed through the appropriate current quadrant in a time-step - q = czero(outbnd, q * qsp); // Do not accumulate outbnd particles - dx = v0; // Streak midpoint (valid for inbnd only) - dy = v1; - dz = v2; - v5 = q * ux * uy * uz * one_third; // Charge conservation correction - // seems to cause a measurable slow-down - // FIXME, at least part of the solution should be to pass in a view of - // the accumulator array for the current block, which also would mesh - // better with only having a single block in the future at some point - vp0 = (float* ALIGNED(16)) & acc_block[ii(0)]; // Accumlator pointers - vp1 = (float* ALIGNED(16)) & acc_block[ii(1)]; - vp2 = (float* ALIGNED(16)) & acc_block[ii(2)]; - vp3 = (float* ALIGNED(16)) & acc_block[ii(3)]; - -#define ACCUMULATE_J(X, Y, Z, offset) \ - v4 = q * u##X; /* v4 = q ux */ \ - v1 = v4 * d##Y; /* v1 = q ux dy */ \ - v0 = v4 - v1; /* v0 = q ux (1-dy) */ \ - v1 += v4; /* v1 = q ux (1+dy) */ \ - v4 = one + d##Z; /* v4 = 1+dz */ \ - v2 = v0 * v4; /* v2 = q ux (1-dy)(1+dz) */ \ - v3 = v1 * v4; /* v3 = q ux (1+dy)(1+dz) */ \ - v4 = one - d##Z; /* v4 = 1-dz */ \ - v0 *= v4; /* v0 = q ux (1-dy)(1-dz) */ \ - v1 *= v4; /* v1 = q ux (1+dy)(1-dz) */ \ - v0 += v5; /* v0 = q ux [ (1-dy)(1-dz) + uy*uz/3 ] */ \ - v1 -= v5; /* v1 = q ux [ (1+dy)(1-dz) - uy*uz/3 ] */ \ - v2 -= v5; /* v2 = q ux [ (1-dy)(1+dz) - uy*uz/3 ] */ \ - v3 += v5; /* v3 = q ux [ (1+dy)(1+dz) + uy*uz/3 ] */ \ - transpose(v0, v1, v2, v3); \ - increment_4x1(vp0 + offset, v0); \ - increment_4x1(vp1 + offset, v1); \ - increment_4x1(vp2 + offset, v2); \ - increment_4x1(vp3 + offset, v3) - - ACCUMULATE_J(x, y, z, 0); - ACCUMULATE_J(y, z, x, 4); - ACCUMULATE_J(z, x, y, 8); - -#undef ACCUMULATE_J - - // Update position and accumulate outbnd - -#define MOVE_OUTBND(N) \ - if (outbnd(N)) { /* Unlikely */ \ - local_pm->dispx = ux(N); \ - local_pm->dispy = uy(N); \ - local_pm->dispz = uz(N); \ - local_pm->i = (p - p0) + N; \ - if (move_p(p0, local_pm, acc_block, g, _qsp)) { /* Unlikely */ \ - if (nm < max_nm) \ - copy_4x1(&pm[nm++], local_pm); \ - else \ - n_ignored++; /* Unlikely */ \ - } \ - } - - MOVE_OUTBND(0); - MOVE_OUTBND(1); - MOVE_OUTBND(2); - MOVE_OUTBND(3); - -#undef MOVE_OUTBND - } - - seg->nm = nm; - seg->n_ignored = n_ignored; - } - -#endif - - static void advance_p(typename Mparticles::Species& sp, - MfieldsAccumulator& accumulator, - MfieldsInterpolator& interpolator) - { - DECLARE_ALIGNED_ARRAY(particle_mover_seg_t, 128, seg, 1); - - sp.nm = 0; - - Particle* p = sp.p; - int n = sp.np & ~15; -#if defined(V4_ACCELERATION) && defined(HAS_V4_PIPELINE) - advance_p_pipeline_v4(sp, accumulator[1], interpolator, seg, p, n, - sp.pm + sp.nm, sp.max_nm - sp.nm); -#else - advance_p_pipeline(sp, accumulator[1], interpolator, seg, p, n, - sp.pm + sp.nm, sp.max_nm - sp.nm); -#endif - sp.nm += seg->nm; - - if (seg->n_ignored) - LOG_WARN("Pipeline %i ran out of storage for %i movers", 0, - seg->n_ignored); - - p += n; - n = sp.np - n; - advance_p_pipeline(sp, accumulator[0], interpolator, seg, p, n, - sp.pm + sp.nm, sp.max_nm - sp.nm); - sp.nm += seg->nm; - - if (seg->n_ignored) - LOG_WARN("Pipeline %i ran out of storage for %i movers", 1, - seg->n_ignored); - } - - static void advance_p(Mparticles& mprts, MfieldsAccumulator& accumulator, - MfieldsInterpolator& interpolator) - { - for (auto& sp : mprts[0]) { - TIC advance_p(sp, accumulator, interpolator); - TOC(advance_p, 1); - } - } - - // ---------------------------------------------------------------------- - // boundary_p - - static void boundary_p_(const ParticleBcList& pbc_list, Mparticles& mprts, - MfieldsState& mflds, AccumulatorBlock acc_block) - { -#ifdef V4_ACCELERATION - using namespace v4; -#endif - - enum - { - MAX_PBC = 32, - MAX_SP = 32 - }; - - // Gives the local mp port associated with a local face - static const int f2b[6] = {BOUNDARY(-1, 0, 0), BOUNDARY(0, -1, 0), - BOUNDARY(0, 0, -1), BOUNDARY(1, 0, 0), - BOUNDARY(0, 1, 0), BOUNDARY(0, 0, 1)}; - - // Gives the remote mp port associated with a local face - static const int f2rb[6] = {BOUNDARY(1, 0, 0), BOUNDARY(0, 1, 0), - BOUNDARY(0, 0, 1), BOUNDARY(-1, 0, 0), - BOUNDARY(0, -1, 0), BOUNDARY(0, 0, -1)}; - - // Gives the axis associated with a local face - static const int axis[6] = {0, 1, 2, 0, 1, 2}; - - // Gives the location of sending face on the receiver - static const float dir[6] = {1, 1, 1, -1, -1, -1}; - - // Temporary store for local particle injectors - // FIXME: Ugly static usage - static ParticleInjector* RESTRICT ALIGNED(16) ci = NULL; - static int max_ci = 0; - - int n_send[6], n_recv[6], n_ci; - - int face; - - // Check input args - - if (mprts.empty()) - return; // Nothing to do if no species - - assert(pbc_list.empty()); - - // Unpack fields - - Grid& RESTRICT g = mflds.vgrid(); - // Unpack the grid - - const int64_t* RESTRICT ALIGNED(128) neighbor = g.neighbor; - const int64_t rangel = g.rangel; - const int64_t rangeh = g.rangeh; - const int64_t rangem = g.range[psc_world_size]; - /*const*/ int bc[6], shared[6]; - /*const*/ int64_t range[6]; - for (face = 0; face < 6; face++) { - bc[face] = g.bc[f2b[face]]; - shared[face] = (bc[face] >= 0) && (bc[face] < psc_world_size) && - (bc[face] != psc_world_rank); - if (shared[face]) - range[face] = g.range[bc[face]]; - } - - // Begin receiving the particle counts - - for (face = 0; face < 6; face++) { - if (shared[face]) { - g.mp_size_recv_buffer(f2b[face], sizeof(int)); - g.mp_begin_recv(f2b[face], sizeof(int), bc[face], f2rb[face]); - } - } - - // Load the particle send and local injection buffers - do { - - ParticleInjector* RESTRICT ALIGNED(16) pi_send[6]; - - // Presize the send and injection buffers - // - // Each buffer is large enough to hold one injector corresponding - // to every mover in use (worst case, but plausible scenario in - // beam simulations, is one buffer gets all the movers). - - int nm = 0; - for (auto& sp : mprts[0]) { // FIXME, should use const iterator - nm += sp.nm; - } - - for (face = 0; face < 6; face++) - if (shared[face]) { - g.mp_size_send_buffer(f2b[face], 16 + nm * sizeof(ParticleInjector)); - pi_send[face] = - (ParticleInjector*)(((char*)g.mp_send_buffer(f2b[face])) + 16); - n_send[face] = 0; - } - - if (max_ci < nm) { - delete[] ci; - ci = new ParticleInjector[nm]; - max_ci = nm; - } - n_ci = 0; - - // For each species, load the movers - - for (auto& sp : mprts[0]) { - const float sp_q = sp.q; - const int32_t sp_id = sp.id; - - Particle* RESTRICT ALIGNED(128) p0 = sp.p; - int np = sp.np; - - ParticleMover* RESTRICT ALIGNED(16) pm = sp.pm + sp.nm - 1; - nm = sp.nm; - - ParticleInjector* RESTRICT ALIGNED(16) pi; - int i, voxel; - int64_t nn; - - // Note that particle movers for each species are processed in - // reverse order. This allows us to backfill holes in the - // particle list created by boundary conditions and/or - // communication. This assumes particle on the mover list are - // monotonically increasing. That is: pm[n].i > pm[n-1].i for - // n=1...nm-1. advance_p and inject_particle create movers with - // property if all aged particle injection occurs after - // advance_p and before this - - for (; nm; pm--, nm--) { - i = pm->i; - voxel = p0[i].i; - face = voxel & 7; - voxel >>= 3; - p0[i].i = voxel; - nn = neighbor[6 * voxel + face]; - - // Absorb - - if (nn == Grid::absorb_particles) { - // Ideally, we would batch all rhob accumulations together - // for efficiency - accumulate_rhob(mflds, p0 + i, sp_q); - goto backfill; - } - - // Send to a neighboring node - - if (((nn >= 0) & (nn < rangel)) | ((nn > rangeh) & (nn <= rangem))) { - pi = &pi_send[face][n_send[face]++]; -#ifdef V4_ACCELERATION - copy_4x1(&pi->dx, &p0[i].dx); - copy_4x1(&pi->ux, &p0[i].ux); - copy_4x1(&pi->dispx, &pm->dispx); -#else - pi->dx = p0[i].dx; - pi->dy = p0[i].dy; - pi->dz = p0[i].dz; - pi->i = nn - range[face]; - pi->ux = p0[i].ux; - pi->uy = p0[i].uy; - pi->uz = p0[i].uz; - pi->w = p0[i].w; - pi->dispx = pm->dispx; - pi->dispy = pm->dispy; - pi->dispz = pm->dispz; - pi->sp_id = sp_id; -#endif - (&pi->dx)[axis[face]] = dir[face]; - pi->i = nn - range[face]; - pi->sp_id = sp_id; - goto backfill; - } - - // Uh-oh: We fell through - - LOG_WARN("Unknown boundary interaction ... dropping particle " - "(species=%s)", - sp.name); - - backfill: - - np--; -#ifdef V4_ACCELERATION - copy_4x1(&p0[i].dx, &p0[np].dx); - copy_4x1(&p0[i].ux, &p0[np].ux); -#else - p0[i] = p0[np]; -#endif - } - - sp.np = np; - sp.nm = 0; - } - - } while (0); - - // Finish exchanging particle counts and start exchanging actual - // particles. - - for (face = 0; face < 6; face++) { - if (shared[face]) { - *((int*)g.mp_send_buffer(f2b[face])) = n_send[face]; - g.mp_begin_send(f2b[face], sizeof(int), bc[face], f2b[face]); - } - } - for (face = 0; face < 6; face++) { - if (shared[face]) { - g.mp_end_recv(f2b[face]); - n_recv[face] = *((int*)g.mp_recv_buffer(f2b[face])); - g.mp_size_recv_buffer(f2b[face], - 16 + n_recv[face] * sizeof(ParticleInjector)); - g.mp_begin_recv(f2b[face], 16 + n_recv[face] * sizeof(ParticleInjector), - bc[face], f2rb[face]); - } - } - for (face = 0; face < 6; face++) { - if (shared[face]) { - g.mp_end_send(f2b[face]); - // FIXME: ASSUMES MP WON'T MUCK WITH REST OF SEND BUFFER. IF WE - // DID MORE EFFICIENT MOVER ALLOCATION ABOVE, THIS WOULD BE - // ROBUSTED AGAINST MP IMPLEMENTATION VAGARIES - g.mp_begin_send(f2b[face], 16 + n_send[face] * sizeof(ParticleInjector), - bc[face], f2b[face]); - } - } - - do { - // Unpack the species list for random acesss - - Particle* RESTRICT ALIGNED(32) sp_p[MAX_SP]; - ParticleMover* RESTRICT ALIGNED(32) sp_pm[MAX_SP]; - float sp_q[MAX_SP]; - int sp_np[MAX_SP]; - int sp_nm[MAX_SP]; - int sp_max_np[MAX_SP], n_dropped_particles[MAX_SP]; - int sp_max_nm[MAX_SP], n_dropped_movers[MAX_SP]; - - if (mprts.getNumSpecies() > MAX_SP) { - LOG_ERROR("Update this to support more species"); - } - for (auto& sp : mprts[0]) { - sp_p[sp.id] = sp.p; - sp_pm[sp.id] = sp.pm; - sp_q[sp.id] = sp.q; - sp_np[sp.id] = sp.np; - sp_nm[sp.id] = sp.nm; - sp_max_np[sp.id] = sp.max_np; - n_dropped_particles[sp.id] = 0; - sp_max_nm[sp.id] = sp.max_nm; - n_dropped_movers[sp.id] = 0; - } - - // Inject particles. We do custom local injection first to - // increase message overlap opportunities. - - face = 5; - do { - Particle* RESTRICT ALIGNED(32) p; - ParticleMover* RESTRICT ALIGNED(16) pm; - const ParticleInjector* RESTRICT ALIGNED(16) pi; - int np, nm, n, id; - - face++; - if (face == 7) { - face = 0; - } - - if (face == 6) { - pi = ci; - n = n_ci; - } else if (shared[face]) { - g.mp_end_recv(f2b[face]); - pi = (const ParticleInjector*)(((char*)g.mp_recv_buffer(f2b[face])) + - 16); - n = n_recv[face]; - } else { - continue; - } - - // Reverse order injection is done to reduce thrashing of the - // particle list (particles are removed reverse order so the - // overall impact of removal + injection is to keep injected - // particles in order). - // - // WARNING: THIS TRUSTS THAT THE INJECTORS (INCLUDING THOSE - // RECEIVED FROM OTHER NODES) HAVE VALID PARTICLE IDS. - - pi += n - 1; - for (; n; pi--, n--) { - id = pi->sp_id; - p = sp_p[id]; - np = sp_np[id]; - pm = sp_pm[id]; - nm = sp_nm[id]; - - if (np >= sp_max_np[id]) { - n_dropped_particles[id]++; - continue; - } -#ifdef V4_ACCELERATION - copy_4x1(&p[np].dx, &pi->dx); - copy_4x1(&p[np].ux, &pi->ux); -#else - p[np].dx = pi->dx; - p[np].dy = pi->dy; - p[np].dz = pi->dz; - p[np].i = pi->i; - p[np].ux = pi->ux; - p[np].uy = pi->uy; - p[np].uz = pi->uz; - p[np].w = pi->w; -#endif - sp_np[id] = np + 1; - - if (nm >= sp_max_nm[id]) { - n_dropped_movers[id]++; - continue; - } -#ifdef V4_ACCELERATION - copy_4x1(&pm[nm].dispx, &pi->dispx); - pm[nm].i = np; -#else - pm[nm].dispx = pi->dispx; - pm[nm].dispy = pi->dispy; - pm[nm].dispz = pi->dispz; - pm[nm].i = np; -#endif - sp_nm[id] = nm + move_p(p, pm + nm, acc_block, g, sp_q[id]); - } - } while (face != 5); - - for (auto& sp : mprts[0]) { - if (n_dropped_particles[sp.id]) - LOG_WARN("Dropped %i particles from species \"%s\". Use a larger " - "local particle allocation in your simulation setup for " - "this species on this node.", - n_dropped_particles[sp.id], sp.name); - if (n_dropped_movers[sp.id]) - LOG_WARN("%i particles were not completed moved to their final " - "location this timestep for species \"%s\". Use a larger " - "local particle mover buffer in your simulation setup " - "for this species on this node.", - n_dropped_movers[sp.id], sp.name); - sp.np = sp_np[sp.id]; - sp.nm = sp_nm[sp.id]; - } - - } while (0); - - for (face = 0; face < 6; face++) { - if (shared[face]) { - g.mp_end_send(f2b[face]); - } - } - } - - static void boundary_p(const ParticleBcList& pbc_list, Mparticles& mprts, - MfieldsState& mflds, MfieldsAccumulator& accumulator) - { - boundary_p_(pbc_list, mprts, mflds, accumulator[0]); - } - - // ---------------------------------------------------------------------- - // accumulate_rhob - - static void accumulate_rhob(MfieldsState& mflds, const Particle* p, float qsp) - { - float w0 = p->dx, w1 = p->dy, w2, w3, w4, w5, w6, w7, dz = p->dz; - const auto& g = mflds.vgrid(); - int v = p->i, x, y, z, sy = g.sy, sz = g.sz; - const int nx = g.nx, ny = g.ny, nz = g.nz; - w7 = (qsp * g.r8V) * p->w; - - // Compute the trilinear weights - // See note in rhof for why FMA and FNMS are done this way. - -#define FMA(x, y, z) ((z) + (x) * (y)) -#define FNMS(x, y, z) ((z) - (x) * (y)) - w6 = FNMS(w0, w7, w7); // q(1-dx) - w7 = FMA(w0, w7, w7); // q(1+dx) - w4 = FNMS(w1, w6, w6); - w5 = FNMS(w1, w7, w7); // q(1-dx)(1-dy), q(1+dx)(1-dy) - w6 = FMA(w1, w6, w6); - w7 = FMA(w1, w7, w7); // q(1-dx)(1+dy), q(1+dx)(1+dy) - w0 = FNMS(dz, w4, w4); - w1 = FNMS(dz, w5, w5); - w2 = FNMS(dz, w6, w6); - w3 = FNMS(dz, w7, w7); - w4 = FMA(dz, w4, w4); - w5 = FMA(dz, w5, w5); - w6 = FMA(dz, w6, w6); - w7 = FMA(dz, w7, w7); -#undef FNMS -#undef FMA - - // Adjust the weights for a corrected local accumulation of rhob. - // See note in synchronize_rho why we must do this for rhob and not - // for rhof. - - x = v; - z = x / sz; - if (z == 1) - w0 += w0, w1 += w1, w2 += w2, w3 += w3; - if (z == nz) - w4 += w4, w5 += w5, w6 += w6, w7 += w7; - x -= sz * z; - y = x / sy; - if (y == 1) - w0 += w0, w1 += w1, w4 += w4, w5 += w5; - if (y == ny) - w2 += w2, w3 += w3, w6 += w6, w7 += w7; - x -= sy * y; - if (x == 1) - w0 += w0, w2 += w2, w4 += w4, w6 += w6; - if (x == nx) - w1 += w1, w3 += w3, w5 += w5, w7 += w7; - - // Reduce the particle charge to rhob - - auto& fa = mflds.getPatch(0); - fa[v].rhob += w0; - fa[v + 1].rhob += w1; - fa[v + sy].rhob += w2; - fa[v + sy + 1].rhob += w3; - fa[v + sz].rhob += w4; - fa[v + sz + 1].rhob += w5; - fa[v + sz + sy].rhob += w6; - fa[v + sz + sy + 1].rhob += w7; - } - - // ---------------------------------------------------------------------- - // drop_p - - static void drop_p(Mparticles& mprts, MfieldsState& mflds) - { - for (auto& sp : mprts[0]) { - if (sp.nm) { - LOG_WARN("Removing %i particles associated with unprocessed %s movers " - "(increase num_comm_round)", - sp.nm, sp.name); - } - // Drop the particles that have unprocessed movers due to a user defined - // boundary condition. Particles of this type with unprocessed movers are - // in the list of particles and move_p has set the voxel in the particle - // to 8*voxel + face. This is an incorrect voxel index and in many cases - // can in fact go out of bounds of the voxel indexing space. Removal is in - // reverse order for back filling. Particle charge is accumulated to the - // mesh before removing the particle. - int nm = sp.nm; - ParticleMover* RESTRICT ALIGNED(16) pm = sp.pm + sp.nm - 1; - Particle* RESTRICT ALIGNED(128) p0 = sp.p; - for (; nm; nm--, pm--) { - int i = pm->i; // particle index we are removing - p0[i].i >>= 3; // shift particle voxel down - // accumulate the particle's charge to the mesh - accumulate_rhob(mflds, p0 + i, sp.q); - p0[i] = p0[sp.np - 1]; // put the last particle into position i - sp.np--; // decrement the number of particles - } - sp.nm = 0; - } - } - - // ---------------------------------------------------------------------- - // uncenter_p - - static void uncenter_p_pipeline(Species* sp, - /*const*/ MfieldsInterpolator& interpolator, - int off, int cnt) - { - const auto& g = sp->vgrid(); - auto& ip = interpolator.getPatch(0); - const typename MfieldsInterpolator::Element* f; - // For backward half advance - const float qdt_2mc = -(sp->q * g.dt) / (2 * sp->m * g.cvac); - const float qdt_4mc = 0.5 * qdt_2mc; // For backward half rotate - const float one = 1.; - const float one_third = 1. / 3.; - const float two_fifteenths = 2. / 15.; - - float dx, dy, dz, ux, uy, uz; - float hax, hay, haz, cbx, cby, cbz; - float v0, v1, v2, v3, v4; - - int ii; - - int n = cnt; - Particle* p = sp->p + off; - - // Process particles for this pipeline - - for (; n; n--, p++) { - dx = p->dx; // Load position - dy = p->dy; - dz = p->dz; - ii = p->i; - f = &ip[ii]; // Interpolate E - hax = qdt_2mc * - ((f->ex + dy * f->dexdy) + dz * (f->dexdz + dy * f->d2exdydz)); - hay = qdt_2mc * - ((f->ey + dz * f->deydz) + dx * (f->deydx + dz * f->d2eydzdx)); - haz = qdt_2mc * - ((f->ez + dx * f->dezdx) + dy * (f->dezdy + dx * f->d2ezdxdy)); - cbx = f->cbx + dx * f->dcbxdx; // Interpolate B - cby = f->cby + dy * f->dcbydy; - cbz = f->cbz + dz * f->dcbzdz; - ux = p->ux; // Load momentum - uy = p->uy; - uz = p->uz; - v0 = qdt_4mc / (float)sqrt(one + (ux * ux + (uy * uy + uz * uz))); - /**/ // Boris - scalars - v1 = cbx * cbx + (cby * cby + cbz * cbz); - v2 = (v0 * v0) * v1; - v3 = v0 * (one + v2 * (one_third + v2 * two_fifteenths)); - v4 = v3 / (one + v1 * (v3 * v3)); - v4 += v4; - v0 = ux + v3 * (uy * cbz - uz * cby); // Boris - uprime - v1 = uy + v3 * (uz * cbx - ux * cbz); - v2 = uz + v3 * (ux * cby - uy * cbx); - ux += v4 * (v1 * cbz - v2 * cby); // Boris - rotation - uy += v4 * (v2 * cbx - v0 * cbz); - uz += v4 * (v0 * cby - v1 * cbx); - ux += hax; // Half advance E - uy += hay; - uz += haz; - p->ux = ux; // Store momentum - p->uy = uy; - p->uz = uz; - } - } - -#if defined(V4_ACCELERATION) && defined(HAS_V4_PIPELINE) - - static void uncenter_p_pipeline_v4( - Species* sp, /*const*/ MfieldsInterpolator& interpolator, int off, int cnt) - { - using namespace v4; - const auto& g = sp->vgrid(); - auto& ip = interpolator.getPatch(0); - const typename MfieldsInterpolator::Element* ALIGNED(128) f0 = ip.data(); - - Particle* ALIGNED(128) p; - const float* ALIGNED(16) vp0; - const float* ALIGNED(16) vp1; - const float* ALIGNED(16) vp2; - const float* ALIGNED(16) vp3; - - const float _qdt_2mc = (sp->q * g.dt) / (2 * sp->m * g.cvac); - - const v4float qdt_2mc(-_qdt_2mc); // For backward half advance - const v4float qdt_4mc(-0.5 * _qdt_2mc); // For backward half Boris rotate - const v4float one(1.); - const v4float one_third(1. / 3.); - const v4float two_fifteenths(2. / 15.); - - v4float dx, dy, dz, ux, uy, uz, q; - v4float hax, hay, haz, cbx, cby, cbz; - v4float v0, v1, v2, v3, v4, v5; - v4int ii; - - // Determine which particle quads this pipeline processes - - assert(off % 4 == 0); - assert(cnt % 4 == 0); - int nq = cnt >> 2; - p = sp->p + off; - - // Process the particle quads for this pipeline - - for (; nq; nq--, p += 4) { - load_4x4_tr(&p[0].dx, &p[1].dx, &p[2].dx, &p[3].dx, dx, dy, dz, ii); - - // Interpolate fields - vp0 = (const float* ALIGNED(16))(f0 + ii(0)); - vp1 = (const float* ALIGNED(16))(f0 + ii(1)); - vp2 = (const float* ALIGNED(16))(f0 + ii(2)); - vp3 = (const float* ALIGNED(16))(f0 + ii(3)); - load_4x4_tr(vp0, vp1, vp2, vp3, hax, v0, v1, v2); - hax = qdt_2mc * fma(fma(dy, v2, v1), dz, fma(dy, v0, hax)); - load_4x4_tr(vp0 + 4, vp1 + 4, vp2 + 4, vp3 + 4, hay, v3, v4, v5); - hay = qdt_2mc * fma(fma(dz, v5, v4), dx, fma(dz, v3, hay)); - load_4x4_tr(vp0 + 8, vp1 + 8, vp2 + 8, vp3 + 8, haz, v0, v1, v2); - haz = qdt_2mc * fma(fma(dx, v2, v1), dy, fma(dx, v0, haz)); - load_4x4_tr(vp0 + 12, vp1 + 12, vp2 + 12, vp3 + 12, cbx, v3, cby, v4); - cbx = fma(v3, dx, cbx); - /**/ cby = fma(v4, dy, cby); - load_4x2_tr(vp0 + 16, vp1 + 16, vp2 + 16, vp3 + 16, cbz, v5); - cbz = fma(v5, dz, cbz); - - // Update momentum - load_4x4_tr(&p[0].ux, &p[1].ux, &p[2].ux, &p[3].ux, ux, uy, uz, q); - /**/ // Could use load_4x3_tr - v0 = qdt_4mc * rsqrt(one + fma(ux, ux, fma(uy, uy, uz * uz))); - v1 = fma(cbx, cbx, fma(cby, cby, cbz * cbz)); - v2 = (v0 * v0) * v1; - v3 = v0 * fma(v2, fma(v2, two_fifteenths, one_third), one); - v4 = v3 * rcp(fma(v3 * v3, v1, one)); - v4 += v4; - v0 = fma(fms(uy, cbz, uz * cby), v3, ux); - v1 = fma(fms(uz, cbx, ux * cbz), v3, uy); - v2 = fma(fms(ux, cby, uy * cbx), v3, uz); - ux = fma(fms(v1, cbz, v2 * cby), v4, ux); - uy = fma(fms(v2, cbx, v0 * cbz), v4, uy); - uz = fma(fms(v0, cby, v1 * cbx), v4, uz); - ux += hax; - uy += hay; - uz += haz; - store_4x4_tr(ux, uy, uz, q, &p[0].ux, &p[1].ux, &p[2].ux, &p[3].ux); - /**/ // Could use store_4x3_tr - } - } - -#endif - - static void uncenter_p(Species* sp, MfieldsInterpolator& interpolator) - { - int cnt = sp->np & ~15; -#if defined(V4_ACCELERATION) && defined(HAS_V4_PIPELINE) - uncenter_p_pipeline_v4(sp, interpolator, 0, cnt); -#else - uncenter_p_pipeline(sp, interpolator, 0, cnt); -#endif - uncenter_p_pipeline(sp, interpolator, cnt, sp->np - cnt); - } - - // ---------------------------------------------------------------------- - // energy_p - - static double energy_p_pipeline(typename Mparticles::Species& sp, - MfieldsInterpolator& interpolator, int n0, - int n1) - { - const auto& g = sp.vgrid(); - auto& ip = interpolator.getPatch(0); - const typename MfieldsInterpolator::Element* RESTRICT ALIGNED(128) f = - ip.data(); - const Particle* RESTRICT ALIGNED(32) p = sp.p; - const float qdt_2mc = (sp.q * g.dt) / (2 * sp.m * g.cvac); - const float msp = sp.m; - const float one = 1; - - float dx, dy, dz; - float v0, v1, v2; - - double en = 0; - - int i, n; - - n1 += n0; - - // Process particles quads for this pipeline - - for (n = n0; n < n1; n++) { - dx = p[n].dx; - dy = p[n].dy; - dz = p[n].dz; - i = p[n].i; - v0 = p[n].ux + qdt_2mc * ((f[i].ex + dy * f[i].dexdy) + - dz * (f[i].dexdz + dy * f[i].d2exdydz)); - v1 = p[n].uy + qdt_2mc * ((f[i].ey + dz * f[i].deydz) + - dx * (f[i].deydx + dz * f[i].d2eydzdx)); - v2 = p[n].uz + qdt_2mc * ((f[i].ez + dx * f[i].dezdx) + - dy * (f[i].dezdy + dx * f[i].d2ezdxdy)); - v0 = v0 * v0 + v1 * v1 + v2 * v2; - v0 = (msp * p[n].w) * (v0 / (one + sqrtf(one + v0))); - en += (double)v0; - } - - return en; - } - -#if defined(V4_ACCELERATION) && defined(HAS_V4_PIPELINE) - - static double energy_p_pipeline_v4(typename Mparticles::Species& sp, - MfieldsInterpolator& interpolator, int n0, - int n1) - { - using namespace v4; - - const auto& g = sp.vgrid(); - - const typename MfieldsInterpolator::Element* RESTRICT ALIGNED(128) f = - interpolator.data(); - - const float* RESTRICT ALIGNED(16) vp0; - const float* RESTRICT ALIGNED(16) vp1; - const float* RESTRICT ALIGNED(16) vp2; - const float* RESTRICT ALIGNED(16) vp3; - - const v4float qdt_2mc((sp.q * g.dt) / (2 * sp.m * g.cvac)); - const v4float msp(sp.m); - const v4float one(1.); - - v4float dx, dy, dz; - v4float ex, ey, ez; - v4float v0, v1, v2, w; - v4int i; - - double en0 = 0, en1 = 0, en2 = 0, en3 = 0; - - // Determine which particle quads this pipeline processes - - const Particle* RESTRICT ALIGNED(32) p = sp.p + n0; - int nq = n1 >> 2; - - // Process the particle quads for this pipeline - - for (; nq; nq--, p += 4) { - load_4x4_tr(&p[0].dx, &p[1].dx, &p[2].dx, &p[3].dx, dx, dy, dz, i); - - // Interpolate fields - - vp0 = (float*)(f + i(0)); - vp1 = (float*)(f + i(1)); - vp2 = (float*)(f + i(2)); - vp3 = (float*)(f + i(3)); - load_4x4_tr(vp0, vp1, vp2, vp3, ex, v0, v1, v2); - ex = fma(fma(dy, v2, v1), dz, fma(dy, v0, ex)); - load_4x4_tr(vp0 + 4, vp1 + 4, vp2 + 4, vp3 + 4, ey, v0, v1, v2); - ey = fma(fma(dz, v2, v1), dx, fma(dz, v0, ey)); - load_4x4_tr(vp0 + 8, vp1 + 8, vp2 + 8, vp3 + 8, ez, v0, v1, v2); - ez = fma(fma(dx, v2, v1), dy, fma(dx, v0, ez)); - - // Update momentum to half step - // (note Boris rotation does not change energy so it is unnecessary) - - load_4x4_tr(&p[0].ux, &p[1].ux, &p[2].ux, &p[3].ux, v0, v1, v2, w); - v0 = fma(ex, qdt_2mc, v0); - v1 = fma(ey, qdt_2mc, v1); - v2 = fma(ez, qdt_2mc, v2); - - // Accumulate energy - - v0 = fma(v0, v0, fma(v1, v1, v2 * v2)); - v0 = (msp * w) * (v0 / (one + sqrt(one + v0))); - en0 += (double)v0(0); - en1 += (double)v0(1); - en2 += (double)v0(2); - en3 += (double)v0(3); - } - - return en0 + en1 + en2 + en3; - } - -#endif - - static double energy_p(typename Mparticles::Species& sp, - MfieldsInterpolator& interpolator) - { - const auto& g = sp.vgrid(); - int cnt = sp.np & ~15; -#if defined(V4_ACCELERATION) && defined(HAS_V4_PIPELINE) - double local = energy_p_pipeline_v4(sp, interpolator, 0, cnt); -#else - double local = energy_p_pipeline(sp, interpolator, 0, cnt); -#endif - local += energy_p_pipeline(sp, interpolator, cnt, sp.np - cnt); - - double global; - MPI_Allreduce(&local, &global, 1, MPI_DOUBLE, MPI_SUM, psc_comm_world); - return global * sqr(g.cvac); - } -}; diff --git a/src/libpsc/vpic/VpicFieldArrayLocalOps.h b/src/libpsc/vpic/VpicFieldArrayLocalOps.h deleted file mode 100644 index 01c7e91030..0000000000 --- a/src/libpsc/vpic/VpicFieldArrayLocalOps.h +++ /dev/null @@ -1,46 +0,0 @@ - -#ifndef VPIC_FIELD_ARRAY_LOCAL_OPS_H -#define VPIC_FIELD_ARRAY_LOCAL_OPS_H - -#define IN_sfa -#include "field_advance/standard/sfa_private.h" - -template -struct VpicFieldArrayLocalOps -{ - static void local_ghost_tang_b(FieldArray& fa) - { - ::local_ghost_tang_b(fa.f, fa.g); - } - static void local_ghost_norm_e(FieldArray& fa) - { - ::local_ghost_norm_e(fa.f, fa.g); - } - static void local_ghost_div_b(FieldArray& fa) - { - ::local_ghost_div_b(fa.f, fa.g); - } - static void local_adjust_tang_e(FieldArray& fa) - { - ::local_adjust_tang_e(fa.f, fa.g); - } - static void local_adjust_norm_b(FieldArray& fa) - { - ::local_adjust_norm_b(fa.f, fa.g); - } - static void local_adjust_div_e(FieldArray& fa) - { - ::local_adjust_div_e(fa.f, fa.g); - } - static void local_adjust_jf(FieldArray& fa) { ::local_adjust_jf(fa.f, fa.g); } - static void local_adjust_rhof(FieldArray& fa) - { - ::local_adjust_rhof(fa.f, fa.g); - } - static void local_adjust_rhob(FieldArray& fa) - { - ::local_adjust_rhob(fa.f, fa.g); - } -}; - -#endif diff --git a/src/libpsc/vpic/VpicFieldArrayRemoteOps.h b/src/libpsc/vpic/VpicFieldArrayRemoteOps.h deleted file mode 100644 index b327d3ab60..0000000000 --- a/src/libpsc/vpic/VpicFieldArrayRemoteOps.h +++ /dev/null @@ -1,37 +0,0 @@ - -#ifndef VPIC_FIELD_ARRAY_REMOTE_OPS_H -#define VPIC_FIELD_ARRAY_REMOTE_OPS_H - -#define IN_sfa -#include "field_advance/standard/sfa_private.h" - -template -struct VpicFieldArrayRemoteOps -{ - static void begin_remote_ghost_tang_b(FieldArray& fa) - { - ::begin_remote_ghost_tang_b(fa.f, fa.g); - } - static void end_remote_ghost_tang_b(FieldArray& fa) - { - ::end_remote_ghost_tang_b(fa.f, fa.g); - } - static void begin_remote_ghost_norm_e(FieldArray& fa) - { - ::begin_remote_ghost_norm_e(fa.f, fa.g); - } - static void end_remote_ghost_norm_e(FieldArray& fa) - { - ::end_remote_ghost_norm_e(fa.f, fa.g); - } - static void begin_remote_ghost_div_b(FieldArray& fa) - { - ::begin_remote_ghost_div_b(fa.f, fa.g); - } - static void end_remote_ghost_div_b(FieldArray& fa) - { - ::end_remote_ghost_div_b(fa.f, fa.g); - } -}; - -#endif diff --git a/src/libpsc/vpic/VpicGridBase.h b/src/libpsc/vpic/VpicGridBase.h deleted file mode 100644 index 4e1a171709..0000000000 --- a/src/libpsc/vpic/VpicGridBase.h +++ /dev/null @@ -1,92 +0,0 @@ - -#ifndef VPIC_GRID_BASE_H -#define VPIC_GRID_BASE_H - -#include "vpic/vpic.h" - -// ====================================================================== -// VpicGridBase - -struct VpicGridBase : grid_t -{ - enum - { - anti_symmetric_fields = ::anti_symmetric_fields, - pec_fields = ::pec_fields, - symmetric_fields = ::symmetric_fields, - pmc_fields = ::pmc_fields, - absorb_fields = ::absorb_fields, - } Fbc; - - enum - { - reflect_particles = ::reflect_particles, - absorb_particles = ::absorb_particles, - } Pbc; - - static VpicGridBase* create() - { - return static_cast(::new_grid()); - } - - void setup(const double dx_[3], double dt_, double cvac_, double eps0_) - { - dx = dx_[0]; - dy = dx_[1]; - dz = dx_[2]; - dt = dt_; - cvac = cvac_; - eps0 = eps0_; - } - - void partition_periodic_box(const double xl[3], const double xh[3], - const int gdims[3], const int np[3]) - { - ::partition_periodic_box(this, xl[0], xl[1], xl[2], xh[0], xh[1], xh[2], - gdims[0], gdims[1], gdims[2], np[0], np[1], np[2]); - } - - void set_fbc(int boundary, int fbc) { ::set_fbc(this, boundary, fbc); } - void set_pbc(int boundary, int pbc) { ::set_pbc(this, boundary, pbc); } - - void mp_size_recv_buffer(int port, int size) - { - ::mp_size_recv_buffer(mp, port, size); - } - void mp_size_send_buffer(int port, int size) - { - ::mp_size_send_buffer(mp, port, size); - } - void* mp_send_buffer(int port) { return ::mp_send_buffer(mp, port); }; - void* mp_recv_buffer(int port) { return ::mp_recv_buffer(mp, port); }; - void mp_begin_recv(int port, int size, int src, int tag) - { - ::mp_begin_recv(mp, port, size, src, tag); - } - void mp_end_recv(int port) { ::mp_end_recv(mp, port); } - void mp_begin_send(int port, int size, int dst, int tag) - { - ::mp_begin_send(mp, port, size, dst, tag); - } - void mp_end_send(int port) { ::mp_end_send(mp, port); } - - void* size_send_port(int i, int j, int k, int sz) - { - return ::size_send_port(i, j, k, sz, this); - } - void begin_send_port(int i, int j, int k, int sz) - { - ::begin_send_port(i, j, k, sz, this); - } - void end_send_port(int i, int j, int k) { ::end_send_port(i, j, k, this); } - void begin_recv_port(int i, int j, int k, int sz) - { - ::begin_recv_port(i, j, k, sz, this); - } - void* end_recv_port(int i, int j, int k) - { - return ::end_recv_port(i, j, k, this); - } -}; - -#endif diff --git a/src/libpsc/vpic/VpicListBase.h b/src/libpsc/vpic/VpicListBase.h deleted file mode 100644 index 4d9aca22ab..0000000000 --- a/src/libpsc/vpic/VpicListBase.h +++ /dev/null @@ -1,113 +0,0 @@ - -#ifndef VPIC_LIST_BASE_H -#define VPIC_LIST_BASE_H - -#include - -// ====================================================================== -// VpicListBase - -template -class VpicListBase -{ -public: - typedef T value_type; - typedef T& reference; - typedef const T& const_reference; - typedef T* pointer; - typedef const T* const_pointer; - - // ---------------------------------------------------------------------- - // class iterator - - class iterator - { - friend class VpicListBase; - - // protected: FIXME, not accessible from derived VpicListBase (?) - public: - iterator(T* node) : node_(node) {} - - public: - using iterator_category = std::forward_iterator_tag; - using value_type = T; - using difference_type = std::ptrdiff_t; - using pointer = T*; - using reference = T&; - - iterator() {} - bool operator==(const iterator& x) const { return node_ == x.node_; } - bool operator!=(const iterator& x) const { return node_ != x.node_; } - reference operator*() const { return *node_; } - pointer operator->() const { return node_; } - iterator& operator++() - { - node_ = static_cast(node_->next); - return *this; - } - - private: - T* node_; - }; - - // ---------------------------------------------------------------------- - // class const_iterator - - class const_iterator - { - friend class VpicListBase; - - protected: - const_iterator(const T* node) : node_(node) {} - - public: - using iterator_category = std::input_iterator_tag; - using value_type = T; - using difference_type = std::ptrdiff_t; - using pointer = T*; - using reference = T&; - - const_iterator() {} - const_iterator(const iterator& x) : node_(x.node_) {} - bool operator==(const const_iterator& x) const { return node_ == x.node_; } - bool operator!=(const const_iterator& x) const { return node_ != x.node_; } - const_reference operator*() const { return *node_; } - const_pointer operator->() const { return node_; } - const_iterator& operator++() - { - node_ = static_cast(node_->next); - return *this; - } - - private: - const T* node_; - }; - - // ---------------------------------------------------------------------- - // VpicListBase itself - - VpicListBase() : head_(nullptr) {} - - bool empty() const { return !head_; } - size_t size() const { return std::distance(cbegin(), cend()); } - - void push_front(T& x) - { - x.next = head_; - head_ = &x; - } - - iterator begin() { return iterator(head_); } - iterator end() { return iterator(nullptr); } - - const_iterator begin() const { return const_iterator(head_); } - const_iterator end() const { return const_iterator(nullptr); } - - const_iterator cbegin() const { return const_iterator(head_); } - const_iterator cend() const { return const_iterator(nullptr); } - -protected: - T* head_; -}; - -#endif diff --git a/src/libpsc/vpic/VpicMaterial.h b/src/libpsc/vpic/VpicMaterial.h deleted file mode 100644 index f9206a30ef..0000000000 --- a/src/libpsc/vpic/VpicMaterial.h +++ /dev/null @@ -1,39 +0,0 @@ - -#ifndef VPIC_MATERIAL_H -#define VPIC_MATERIAL_H - -#include "VpicListBase.h" - -// ====================================================================== -// VpicMaterial - -struct VpicMaterial : material_t -{}; - -// ====================================================================== -// VpicMaterialList - -struct VpicMaterialList : public VpicListBase -{ - typedef VpicMaterial Material; - - static Material* create(const char* name, float epsx, float epsy, float epsz, - float mux, float muy, float muz, float sigmax, - float sigmay, float sigmaz, float zetax, float zetay, - float zetaz) - { - return static_cast(::material(name, epsx, epsy, epsz, mux, muy, - muz, sigmax, sigmay, sigmaz, zetax, - zetay, zetaz)); - } - - Material* append(Material* m) - { - return static_cast( - ::append_material(m, reinterpret_cast(&head_))); - } - - operator const material_t*() const { return head_; } -}; - -#endif diff --git a/src/libpsc/vpic/fields_item_vpic.hxx b/src/libpsc/vpic/fields_item_vpic.hxx deleted file mode 100644 index 73609ab6fa..0000000000 --- a/src/libpsc/vpic/fields_item_vpic.hxx +++ /dev/null @@ -1,193 +0,0 @@ - -#pragma once - -#include "fields_item.hxx" -#include -#include "psc_hydro_ops.hxx" - -// ---------------------------------------------------------------------- -// OutputFieldsVpic - -template -struct OutputFieldsVpic -{ - struct Result - { - MfieldsState& mflds; - const char* name; - std::vector comp_names; - }; - - int n_comps() const { return MfieldsState::N_COMP; } - - Result operator()(MfieldsState& mflds) - { - std::vector comp_names = { - "ex_ec", "ey_ec", "ez_ec", "div_e_err_nc", "hx_fc", "hy_fc", - "hz_fc", "div_b_err_cc", "tcax_ec", "tcay_ec", "tcaz_ec", "rhob_nc", - "jx_ec", "jy_ec", "jz_ec", "rhof_nc"}; - return {mflds, "fields_vpic", comp_names}; - } -}; - -// ---------------------------------------------------------------------- -// OutputHydroVpic - -template -struct OutputHydroVpic_ -{ - using Mparticles = typename HydroOps::Mparticles; - using MfieldsHydro = typename HydroOps::MfieldsHydro; - using MfieldsInterpolator = typename HydroOps::MfieldsInterpolator; - - struct Result - { - MfieldsSingle& mflds; - const char* name; - std::vector comp_names; - }; - - static std::vector fld_names() - { - return {"jx_nc", "jy_nc", "jz_nc", "rho_nc", "px_nc", "py_nc", - "pz_nc", "ke_nc", "txx_nc", "tyy_nc", "tzz_nc", "tyz_nc", - "tzx_nc", "txy_nc", "_pad0", "_pad1"}; - } - - OutputHydroVpic_(const Grid_t& grid) - : mflds_res_{grid, - MfieldsHydro::N_COMP * int(grid.kinds.size()), - {1, 1, 1}}, - kinds_{grid.kinds} - {} - - int n_comps() const { return mflds_res_.n_comps(); } - - Result operator()(Mparticles& mprts, MfieldsHydro& mflds_hydro, - MfieldsInterpolator& interpolator) - { - // This relies on load_interpolator_array() having been called earlier - - std::vector comp_names; - comp_names.reserve(mflds_res_.n_comps()); - - for (int kind = 0; kind < kinds_.size(); ++kind) { - HydroOps::clear(mflds_hydro); - - auto prts = mprts[0]; - // FIXME, just iterate over species instead? - auto sp = std::find_if( - prts.cbegin(), prts.cend(), - [&](const typename Mparticles::Species& sp) { return sp.id == kind; }); - HydroOps::accumulate_hydro_p(mflds_hydro, sp, interpolator); - - HydroOps::synchronize(mflds_hydro); - - for (int p = 0; p < mflds_res_.n_patches(); p++) { - auto res = mflds_res_[p]; - auto H = mflds_hydro[p]; - mflds_res_.Foreach_3d(0, 0, [&](int i, int j, int k) { - for (int m = 0; m < MfieldsHydro::N_COMP; m++) { - res(m + kind * MfieldsHydro::N_COMP, i, j, k) = H(m, i, j, k); - } - }); - } - - for (int m = 0; m < MfieldsHydro::N_COMP; m++) { - comp_names.emplace_back(fld_names()[m] + "_" + kinds_[kind].name); - } - } - - return {mflds_res_, "hydro_vpic", comp_names}; - } - -private: - MfieldsSingle mflds_res_; - Grid_t::Kinds kinds_; -}; - -// ---------------------------------------------------------------------- -// OutputHydroQ - -template -struct OutputHydroQ_ -{ - using Mparticles = typename HydroOps::Mparticles; - using MfieldsHydro = typename HydroOps::MfieldsHydro; - using MfieldsInterpolator = typename HydroOps::MfieldsInterpolator; - - struct Result - { - MfieldsSingle& mflds; - const char* name; - std::vector comp_names; - }; - static std::vector fld_names() - { - return {"jx_nc", "jy_nc", "jz_nc", "rho_nc", "px_nc", "py_nc", - "pz_nc", "ke_nc", "txx_nc", "tyy_nc", "tzz_nc", "tyz_nc", - "tzx_nc", "txy_nc", "qxxx_nc", "qyyy_nc", "qzzz_nc", "qxxy_nc", - "qyyz_nc", "qzzx_nc", "qxxz_nc", "qyyx_nc", "qzzy_nc", "qxyz_nc"}; - } - - OutputHydroQ_(const Grid_t& grid) - : mflds_res_{grid, - MfieldsHydro::N_COMP * int(grid.kinds.size()), - {1, 1, 1}}, - kinds_{grid.kinds} - {} - - int n_comps() const { return mflds_res_.n_comps(); } - - Result operator()(Mparticles& mprts, MfieldsHydro& mflds_hydro, - MfieldsInterpolator& interpolator) - { - // This relies on load_interpolator_array() having been called earlier - - std::vector comp_names; - comp_names.reserve(mflds_res_.n_comps()); - - for (int kind = 0; kind < kinds_.size(); ++kind) { - HydroOps::clear(mflds_hydro); - - auto prts = mprts[0]; - // FIXME, just iterate over species instead? - auto sp = std::find_if( - prts.cbegin(), prts.cend(), - [&](const typename Mparticles::Species& sp) { return sp.id == kind; }); - HydroOps::accumulate_hydro_p(mflds_hydro, sp, interpolator); - - HydroOps::synchronize(mflds_hydro); - - for (int p = 0; p < mflds_res_.n_patches(); p++) { - auto res = make_Fields3d(mflds_res_[p]); - auto H = make_Fields3d(mflds_hydro[p]); - mflds_res_.Foreach_3d(0, 0, [&](int i, int j, int k) { - for (int m = 0; m < MfieldsHydro::N_COMP; m++) { - res(m + kind * MfieldsHydro::N_COMP, i, j, k) = H(m, i, j, k); - } - }); - } - - for (int m = 0; m < MfieldsHydro::N_COMP; m++) { - comp_names.emplace_back(fld_names()[m] + "_" + kinds_[kind].name); - } - } - - return {mflds_res_, "hydro_vpic", comp_names}; - } - -private: - MfieldsSingle mflds_res_; - Grid_t::Kinds kinds_; -}; - -template -using OutputHydroVpic = - OutputHydroVpic_>; - -template -using OutputHydroQ = - OutputHydroQ_>; diff --git a/src/libpsc/vpic/mfields_accumulator_psc.hxx b/src/libpsc/vpic/mfields_accumulator_psc.hxx deleted file mode 100644 index 4dd3368652..0000000000 --- a/src/libpsc/vpic/mfields_accumulator_psc.hxx +++ /dev/null @@ -1,83 +0,0 @@ - -#pragma once - -#include "PscFieldBase.h" - -// ====================================================================== -// MfieldsAccumulatorPsc - -template -struct MfieldsAccumulatorPsc -{ - using Grid = _Grid; - - // ====================================================================== - // MfieldsAccumulatorPsc::Element - - struct Element - { - float jx[4]; // jx0@(0,-1,-1),jx1@(0,1,-1),jx2@(0,-1,1),jx3@(0,1,1) - float jy[4]; // jy0@(-1,0,-1),jy1@(-1,0,1),jy2@(1,0,-1),jy3@(1,0,1) - float jz[4]; // jz0@(-1,-1,0),jz1@(1,-1,0),jz2@(-1,1,0),jz3@(1,1,0) - }; - - // ====================================================================== - // MfieldsAccumulatorPsc::Block - - struct Block : PscFieldBase - { - using Base = PscFieldBase; - - using Base::Base; - }; - - MfieldsAccumulatorPsc(Grid* grid) : g_(grid) - { - n_pipeline_ = aa_n_pipeline(); - stride_ = POW2_CEIL(g_->nv, 2); - arr_ = new Element[(n_pipeline_ + 1) * stride_](); - } - - ~MfieldsAccumulatorPsc() { delete[] arr_; } - - static int aa_n_pipeline(void) - { - return 2; -#if 0 - int n = serial.n_pipeline; - if (n < thread.n_pipeline) { - n = thread.n_pipeline; - } - return n; -#endif - } - - Element* data() { return arr_; } - - // FIXME, not a great interface with c just another index - Element& operator()(int c, int idx) { return arr_[c * stride_ + idx]; } - - // FIXME, not a great interface with c just another index - Element& operator()(int c, int i, int j, int k) - { - return arr_[c * stride_ + VOXEL(i, j, k, g_->nx, g_->ny, g_->nz)]; - } - - Block operator[](int c) - { - assert(c >= 0 && c < n_pipeline_); - return Block(grid(), arr_ + c * stride_); - } - - int n_pipeline() { return n_pipeline_; } - int stride() { return stride_; } - Grid* grid() { return g_; } - -private: - Element* arr_; - int n_pipeline_; // Number of pipelines supported by this accumulator - -protected: - int stride_; // Stride be each pipeline's accumulator array - Grid* g_; -}; diff --git a/src/libpsc/vpic/mfields_interpolator_psc.hxx b/src/libpsc/vpic/mfields_interpolator_psc.hxx deleted file mode 100644 index 3d40a8766e..0000000000 --- a/src/libpsc/vpic/mfields_interpolator_psc.hxx +++ /dev/null @@ -1,47 +0,0 @@ - -#pragma once - -#include "PscFieldBase.h" - -struct PscInterpolatorT -{ - float ex, dexdy, dexdz, d2exdydz; - float ey, deydz, deydx, d2eydzdx; - float ez, dezdx, dezdy, d2ezdxdy; - float cbx, dcbxdx; - float cby, dcbydy; - float cbz, dcbzdz; - float _pad[2]; // 16-byte align -}; - -// ====================================================================== -// MfieldsInterpolatorPsc - -template -struct MfieldsInterpolatorPsc -{ - using Grid = _Grid; - using Element = PscInterpolatorT; - - struct Patch - { - using Element = PscInterpolatorT; - - Patch(Grid* vgrid) : ip_{vgrid} {} - - Element* data() { return ip_.data(); } - Element operator[](int idx) const { return ip_[idx]; } - Element& operator[](int idx) { return ip_[idx]; } - - Grid* grid() { return ip_.grid(); } - - PscFieldBase ip_; - }; - - MfieldsInterpolatorPsc(Grid* vgrid) : patch_{vgrid} {} - - Patch& getPatch(int p) { return patch_; } - -private: - Patch patch_; -}; diff --git a/src/libpsc/vpic/mparticles_vpic.hxx b/src/libpsc/vpic/mparticles_vpic.hxx deleted file mode 100644 index 4be1f094a5..0000000000 --- a/src/libpsc/vpic/mparticles_vpic.hxx +++ /dev/null @@ -1,365 +0,0 @@ - -#pragma once - -#include "particles.hxx" -#include "../bits.hxx" - -// ====================================================================== -// InjectorVpic - -template -struct InjectorVpic -{ - struct Patch - { - Patch(Mparticles& mprts) : mprts_{mprts} {} - - void operator()(const psc::particle::Inject& prt) - { - const auto& vgrid = mprts_.vgrid(); - float dVi = 1.f / (vgrid.dx * vgrid.dy * vgrid.dz); - psc::particle::Inject prt_reweighted = prt; - prt_reweighted.w *= dVi; - reweight(prt_reweighted); - } - - void reweight(const psc::particle::Inject& prt) - { - mprts_.inject_particle_reweight(prt); - } - - private: - Mparticles& mprts_; - }; - - InjectorVpic(Mparticles& mprts) : mprts_{mprts} {} - - Patch operator[](int p) const { return {mprts_}; } - -private: - Mparticles& mprts_; -}; - -// ====================================================================== -// ConstParticleAccessorVpic - -template -struct ConstParticleAccessorVpic -{ - using Particle = typename Mparticles::Particle; - using real_t = typename Mparticles::real_t; - using Real3 = Vec3; - using Double3 = Vec3; - using Species = typename Mparticles::Species; - - ConstParticleAccessorVpic(const Particle& prt, const Species& sp) - : prt_{prt}, sp_{sp} - {} - - Real3 u() const { return {prt_.ux, prt_.uy, prt_.uz}; } - real_t w() const { return prt_.w * sp_.vgrid().dV; } - real_t qni_wni() const { return w() * sp_.q; } - int kind() const { return sp_.id; } - - Real3 x() const { return Real3(x_double()); } - - Double3 x_double() const - { - const auto& vgrid = sp_.vgrid(); - double x0 = vgrid.x0, y0 = vgrid.y0, z0 = vgrid.z0; - double x1 = vgrid.x1, y1 = vgrid.y1, z1 = vgrid.z1; - double nx = vgrid.nx, ny = vgrid.ny, nz = vgrid.nz; - - int i = prt_.i; - int iz = i / ((nx + 2) * (ny + 2)); - i -= iz * ((nx + 2) * (ny + 2)); - int iy = i / (nx + 2); - i -= iy * (nx + 2); - int ix = i; - - // adjust to 0-based (no ghost) - ix--; - iy--; - iz--; - - // back to physical coords - Double3 x = {ix + .5 * (prt_.dx + 1.), iy + .5 * (prt_.dy + 1.), - iz + .5 * (prt_.dz + 1.)}; - x *= (Double3{x1, y1, z1} - Double3{x0, y0, z0}) / Double3{nx, ny, nz}; - - return x; - } - - Double3 position() const - { - const auto& vgrid = sp_.vgrid(); - double x0 = vgrid.x0, y0 = vgrid.y0, z0 = vgrid.z0; - - return Double3(x_double()) + Double3{x0, y0, z0}; - } - -private: - const Particle& prt_; - const Species& sp_; -}; - -// ====================================================================== -// ConstAccessorVpic - -template -struct ConstAccessorVpic -{ - using Particle = ConstParticleAccessorVpic; - - struct Patch - { - using accessor = ConstParticleAccessorVpic; - using ConstSpeciesIterator = typename Mparticles::ConstSpeciesIterator; - using Species = typename Mparticles::Species; - - struct const_iterator - { - using iterator_category = std::forward_iterator_tag; - using value_type = accessor; - using difference_type = std::ptrdiff_t; - using pointer = const accessor*; - using reference = const accessor&; - - const_iterator(const Patch& patch, ConstSpeciesIterator sp, uint n) - : patch_{patch}, sp_{sp}, n_{n} - {} - - bool operator==(const_iterator other) const - { - return sp_ == other.sp_ && n_ == other.n_; - } - bool operator!=(const_iterator other) const { return !(*this == other); } - - const_iterator& operator++() - { - n_++; - if (n_ == sp_->np) { - n_ = 0; - ++sp_; - } - return *this; - } - - const_iterator operator++(int) - { - auto retval = *this; - ++(*this); - return retval; - } - const accessor operator*() { return {sp_->p[n_], *sp_}; } - - private: - const Patch patch_; - ConstSpeciesIterator sp_; - uint n_; - }; - - Patch(const ConstAccessorVpic& accessor) : accessor_{accessor} {} - - const_iterator begin() const - { - return {*this, accessor_.mprts_[0].begin(), 0}; - } - const_iterator end() const { return {*this, accessor_.mprts_[0].end(), 0}; } - uint size() const { return accessor_.size(0); } - - const accessor operator[](int n) const - { - for (auto& sp : accessor_.mprts_[0]) { - if (n < sp.np) { - return {sp.p[n], sp}; - } - n -= sp.np; - } - std::abort(); - } - - private: - const ConstAccessorVpic& accessor_; - }; - - ConstAccessorVpic(Mparticles& mprts) : mprts_{mprts} {} - - Patch operator[](int p) const { return {*this}; } - uint size(int p) const { return mprts_.size(); } - -private: - Mparticles& mprts_; -}; - -// ====================================================================== -// MparticlesVpic_ - -template -struct MparticlesVpic_ - : MparticlesBase - , protected _Particles -{ - using Particles = _Particles; - using Species = typename Particles::Species; - using Grid = typename Particles::Grid; - using Particle = typename Particles::Particle; - using SpeciesIterator = typename Particles::iterator; - using ConstSpeciesIterator = typename Particles::const_iterator; - using ConstAccessor = ConstAccessorVpic; - using real_t = float; - using Real3 = Vec3; - - using Particles::empty; - using Particles::getNumSpecies; - using Particles::head; - using Particles::inject_particle_reweight; - using typename Particles::ParticleBcList; - using typename Particles::ParticleMover; - - struct Patch - { - Patch(MparticlesVpic_& mprts) : mprts_{mprts} {} - - ConstSpeciesIterator cbegin() const { return mprts_.cbegin(); } - ConstSpeciesIterator cend() const { return mprts_.cend(); } - ConstSpeciesIterator begin() const { return mprts_.begin(); } - ConstSpeciesIterator end() const { return mprts_.end(); } - SpeciesIterator begin() { return mprts_.begin(); } - SpeciesIterator end() { return mprts_.end(); } - - private: - MparticlesVpic_& mprts_; - }; - - struct ConstPatch - { - ConstPatch(const MparticlesVpic_& mprts) : mprts_{mprts} {} - - ConstSpeciesIterator cbegin() const { return mprts_.cbegin(); } - ConstSpeciesIterator cend() const { return mprts_.cend(); } - ConstSpeciesIterator begin() const { return mprts_.begin(); } - ConstSpeciesIterator end() const { return mprts_.end(); } - - private: - const MparticlesVpic_& mprts_; - }; - - // ---------------------------------------------------------------------- - // ctor - - MparticlesVpic_(const Grid_t& grid, Grid* vgrid) - : MparticlesBase(grid), vgrid_(vgrid) - { - assert(grid.n_patches() == 1); - } - - // ---------------------------------------------------------------------- - // size - - int size() const override - { - int n_prts = 0; - for (auto& sp : *this) { - n_prts += sp.np; - } - - return n_prts; - } - - // ---------------------------------------------------------------------- - // sizeByPatch - - std::vector sizeByPatch() const override { return {uint(size())}; } - - // ---------------------------------------------------------------------- - // reserve_all - // - // This is a bit iffy, since we don't really want to reallocate stuff here, - // at least for now, and we wouldn't be able to know how to split this into - // the different species, anyway. - - void reserve_all(const std::vector& n_prts_by_patch) - { - for (int p = 0; p < n_patches(); p++) { - int n_prts = 0, n_prts_alloced = 0; - for (auto& sp : *this) { - n_prts += sp.np; - n_prts_alloced += sp.max_np; - } -#if 0 - if (n_prts_by_patch[p] != n_prts) { - mprintf("vpic_mparticles_reserve_all: %d (currently %d max %d)\n", - n_prts_by_patch[p], n_prts, n_prts_alloced); - } -#endif - assert(n_prts_by_patch[p] <= n_prts_alloced); - } - } - - void reset() - { - for (auto& sp : *this) { - sp.np = 0; - } - } - - using MparticlesBase::reset; - - void push_back(int kind, const Particle& prt) - { - for (auto& sp : *this) { - if (sp.id == kind) { - sp.p[sp.np++] = prt; - return; - } - } - mprintf("prt.kind %d not found in species list!\n", kind); - assert(0); - } - - Patch operator[](int p) - { - assert(p == 0); - return {*this}; - } - ConstPatch operator[](int p) const - { - assert(p == 0); - return {*this}; - } - - InjectorVpic injector() { return {*this}; } - - ConstAccessor accessor() { return {*this}; } - - Species* define_species(const char* name, double q, double m, - double max_local_np, double max_local_nm, - double sort_interval, double sort_out_of_place) - { - // Compute a reasonble number of movers if user did not specify - // Based on the twice the number of particles expected to hit the boundary - // of a wpdt=0.2 / dx=lambda species in a 3x3x3 domain - if (max_local_nm < 0) { - max_local_nm = 2 * max_local_np / 25; -#if 0 - // FIXME, don't know MAX_PIPELINE, and that's mostly gone - // could move this down into Particles.create() - if (max_local_nm < 16*(MAX_PIPELINE+1)) - max_local_nm = 16*(MAX_PIPELINE+1); -#endif - } - auto sp = this->create(name, q, m, max_local_np, max_local_nm, - sort_interval, sort_out_of_place, vgrid_); - return this->append(sp); - } - - static const Convert convert_to_, convert_from_; - const Convert& convert_to() override { return convert_to_; } - const Convert& convert_from() override { return convert_from_; } - - const Grid& vgrid() { return *vgrid_; } - -private: - Grid* vgrid_; -}; diff --git a/src/libpsc/vpic/psc_hydro_ops.hxx b/src/libpsc/vpic/psc_hydro_ops.hxx deleted file mode 100644 index 02bef2afeb..0000000000 --- a/src/libpsc/vpic/psc_hydro_ops.hxx +++ /dev/null @@ -1,687 +0,0 @@ - -#pragma once - -#include "GridLoop.h" -#include "Field3D.h" - -// Generic looping -#define XYZ_LOOP(xl, xh, yl, yh, zl, zh) \ - for (z = zl; z <= zh; z++) \ - for (y = yl; y <= yh; y++) \ - for (x = xl; x <= xh; x++) - -// x_NODE_LOOP => Loop over all non-ghost nodes at plane x -#define x_NODE_LOOP(x) XYZ_LOOP(x, x, 1, ny + 1, 1, nz + 1) -#define y_NODE_LOOP(y) XYZ_LOOP(1, nx + 1, y, y, 1, nz + 1) -#define z_NODE_LOOP(z) XYZ_LOOP(1, nx + 1, 1, ny + 1, z, z) - -// ====================================================================== -// PscHydroOps - -template -struct PscHydroOps -{ - using Mparticles = _Mparticles; - using MfieldsHydro = _MfieldsHydro; - using MfieldsInterpolator = _MfieldsInterpolator; - using Grid = typename MfieldsHydro::Grid; - using Element = typename MfieldsHydro::Element; - - // ---------------------------------------------------------------------- - // clear - - static void clear(MfieldsHydro& hydro) - { - auto h = hydro.data(); - memset(h, 0, hydro.vgrid()->nv * sizeof(*h) * MfieldsHydro::N_COMP); - } - - // ---------------------------------------------------------------------- - // synchronize - - template - struct CommHydro : Comm - { - typedef Comm Base; - typedef G Grid; - - using Base::begin; - using Base::end; - - using Base::buf_size_; - using Base::g_; - using Base::nx_; - - CommHydro(Grid& g) : Base(g) - { - for (int X = 0; X < 3; X++) { - int Y = (X + 1) % 3, Z = (X + 2) % 3; - buf_size_[X] = 14 * (nx_[Y] + 1) * (nx_[Z] + 1); - } - } - - void begin_send(int X, int side, float* p, F3D& F) - { - int face = side ? nx_[X] + 1 : 1; - foreach_node(g_, X, face, [&](int x, int y, int z) { - Element* h = &F(x, y, z); - *p++ = h->jx; - *p++ = h->jy; - *p++ = h->jz; - *p++ = h->rho; - *p++ = h->px; - *p++ = h->py; - *p++ = h->pz; - *p++ = h->ke; - *p++ = h->txx; - *p++ = h->tyy; - *p++ = h->tzz; - *p++ = h->tyz; - *p++ = h->tzx; - *p++ = h->txy; - }); - } - - void end_recv(int X, int side, float* p, F3D& F) - { - int face = side ? 1 : nx_[X] + 1; - foreach_node(g_, X, face, [&](int x, int y, int z) { - Element* h = &F(x, y, z); - h->jx += *p++; - h->jy += *p++; - h->jz += *p++; - h->rho += *p++; - h->px += *p++; - h->py += *p++; - h->pz += *p++; - h->ke += *p++; - h->txx += *p++; - h->tyy += *p++; - h->tzz += *p++; - h->tyz += *p++; - h->tzx += *p++; - h->txy += *p++; - }); - } - }; - - static void synchronize(MfieldsHydro& hydro) - { - using F3D = Field3D; - int face, bc, x, y, z; - Element* h; - - auto g = hydro.vgrid(); - const int nx = g->nx, ny = g->ny, nz = g->nz; - auto fields_hydro = hydro[0]; - F3D H{hydro.getPatch(0)}; - - // Note: synchronize_hydro assumes that hydro has not been adjusted - // at the local domain boundary. Because hydro fields are purely - // diagnostic, correct the hydro along local boundaries to account - // for accumulations over partial cell volumes - -#define ADJUST_HYDRO(i, j, k, X, Y, Z) \ - do { \ - int bc = g->bc[BOUNDARY(i, j, k)]; \ - if (bc < 0 || bc >= psc_world_size) { \ - face = (i + j + k) < 0 ? 1 : n##X + 1; \ - X##_NODE_LOOP(face) \ - { \ - h = &H(x, y, z); \ - h->jx *= 2; \ - h->jy *= 2; \ - h->jz *= 2; \ - h->rho *= 2; \ - h->px *= 2; \ - h->py *= 2; \ - h->pz *= 2; \ - h->ke *= 2; \ - h->txx *= 2; \ - h->tyy *= 2; \ - h->tzz *= 2; \ - h->tyz *= 2; \ - h->tzx *= 2; \ - h->txy *= 2; \ - } \ - } \ - } while (0) - - ADJUST_HYDRO(-1, 0, 0, x, y, z); - ADJUST_HYDRO(0, -1, 0, y, z, x); - ADJUST_HYDRO(0, 0, -1, z, x, y); - ADJUST_HYDRO(1, 0, 0, x, y, z); - ADJUST_HYDRO(0, 1, 0, y, z, x); - ADJUST_HYDRO(0, 0, 1, z, x, y); - -#undef ADJUST_HYDRO - - CommHydro comm{*hydro.vgrid()}; - - for (int dir = 0; dir < 3; dir++) { - comm.begin(dir, H); - comm.end(dir, H); - } - } - - // ---------------------------------------------------------------------- - // accumulate_hydro_p - - // accumulate_hydro_p adds the hydrodynamic fields associated with the - // supplied particle_list to the hydro array. Trilinear interpolation - // is used. hydro is known at the nodes at the same time as particle - // positions. No effort is made to fix up edges of the computational - // domain. All particles on the list must be inbounds. Note, the - // hydro jx,jy,jz are for diagnostic purposes only; they are not - // accumulated with a charge conserving algorithm. - - static void accumulate_hydro_p( - MfieldsHydro& hydro, - const typename Mparticles::ConstSpeciesIterator sp_iter, - /*const*/ MfieldsInterpolator& interpolator) - { - auto& sp = *sp_iter; - auto& ha = hydro.getPatch(0); - auto& IP = interpolator.getPatch(0); - float c, qsp, mspc, qdt_2mc, qdt_4mc2, r8V; - int np, stride_10, stride_21, stride_43; - - float dx, dy, dz, ux, uy, uz, w, vx, vy, vz, ke_mc; - float w0, w1, w2, w3, w4, w5, w6, w7, t; - int i, n; - - const auto& g = sp.vgrid(); - const auto* p = sp.p; - - c = g.cvac; - qsp = sp.q; - mspc = sp.m * c; - qdt_2mc = (qsp * g.dt) / (2 * mspc); - qdt_4mc2 = qdt_2mc / (2 * c); - r8V = g.r8V; - - np = sp.np; - stride_10 = - (VOXEL(1, 0, 0, g.nx, g.ny, g.nz) - VOXEL(0, 0, 0, g.nx, g.ny, g.nz)); - stride_21 = - (VOXEL(0, 1, 0, g.nx, g.ny, g.nz) - VOXEL(1, 0, 0, g.nx, g.ny, g.nz)); - stride_43 = - (VOXEL(0, 0, 1, g.nx, g.ny, g.nz) - VOXEL(1, 1, 0, g.nx, g.ny, g.nz)); - - for (n = 0; n < np; n++) { - - // Load the particle - dx = p[n].dx; - dy = p[n].dy; - dz = p[n].dz; - i = p[n].i; - ux = p[n].ux; - uy = p[n].uy; - uz = p[n].uz; - w = p[n].w; - - // Half advance E - ux += qdt_2mc * ((IP[i].ex + dy * IP[i].dexdy) + - dz * (IP[i].dexdz + dy * IP[i].d2exdydz)); - uy += qdt_2mc * ((IP[i].ey + dz * IP[i].deydz) + - dx * (IP[i].deydx + dz * IP[i].d2eydzdx)); - uz += qdt_2mc * ((IP[i].ez + dx * IP[i].dezdx) + - dy * (IP[i].dezdy + dx * IP[i].d2ezdxdy)); - - // Boris rotation - Interpolate B field - w5 = IP[i].cbx + dx * IP[i].dcbxdx; - w6 = IP[i].cby + dy * IP[i].dcbydy; - w7 = IP[i].cbz + dz * IP[i].dcbzdz; - - // Boris rotation - curl scalars (0.5 in v0 for half rotate) and - // kinetic energy computation. Note: gamma-1 = |u|^2 / (gamma+1) - // is the numerically accurate way to compute gamma-1 - ke_mc = ux * ux + uy * uy + uz * uz; // ke_mc = |u|^2 (invariant) - vz = sqrt(1 + ke_mc); // vz = gamma (invariant) - ke_mc *= c / (vz + 1); // ke_mc = c|u|^2/(gamma+1) = c*(gamma-1) - vz = c / vz; // vz = c/gamma - w0 = qdt_4mc2 * vz; - w1 = w5 * w5 + w6 * w6 + w7 * w7; // |cB|^2 - w2 = w0 * w0 * w1; - w3 = w0 * (1 + (1. / 3.) * w2 * (1 + 0.4 * w2)); - w4 = w3 / (1 + w1 * w3 * w3); - w4 += w4; - - // Boris rotation - uprime - w0 = ux + w3 * (uy * w7 - uz * w6); - w1 = uy + w3 * (uz * w5 - ux * w7); - w2 = uz + w3 * (ux * w6 - uy * w5); - - // Boris rotation - u - ux += w4 * (w1 * w7 - w2 * w6); - uy += w4 * (w2 * w5 - w0 * w7); - uz += w4 * (w0 * w6 - w1 * w5); - - // Compute physical velocities - vx = ux * vz; - vy = uy * vz; - vz *= uz; - - // Compute the trilinear coefficients - w0 = r8V * w; // w0 = (1/8)(w/V) - dx *= w0; // dx = (1/8)(w/V) x - w1 = w0 + dx; // w1 = (1/8)(w/V) + (1/8)(w/V)x = (1/8)(w/V)(1+x) - w0 -= dx; // w0 = (1/8)(w/V) - (1/8)(w/V)x = (1/8)(w/V)(1-x) - w3 = 1 + dy; // w3 = 1+y - w2 = w0 * w3; // w2 = (1/8)(w/V)(1-x)(1+y) - w3 *= w1; // w3 = (1/8)(w/V)(1+x)(1+y) - dy = 1 - dy; // dy = 1-y - w0 *= dy; // w0 = (1/8)(w/V)(1-x)(1-y) - w1 *= dy; // w1 = (1/8)(w/V)(1+x)(1-y) - w7 = 1 + dz; // w7 = 1+z - w4 = w0 * w7; // w4 = (1/8)(w/V)(1-x)(1-y)(1+z) = (w/V) trilin_0 *Done - w5 = w1 * w7; // w5 = (1/8)(w/V)(1+x)(1-y)(1+z) = (w/V) trilin_1 *Done - w6 = w2 * w7; // w6 = (1/8)(w/V)(1-x)(1+y)(1+z) = (w/V) trilin_2 *Done - w7 *= w3; // w7 = (1/8)(w/V)(1+x)(1+y)(1+z) = (w/V) trilin_3 *Done - dz = 1 - dz; // dz = 1-z - w0 *= dz; // w0 = (1/8)(w/V)(1-x)(1-y)(1-z) = (w/V) trilin_4 *Done - w1 *= dz; // w1 = (1/8)(w/V)(1+x)(1-y)(1-z) = (w/V) trilin_5 *Done - w2 *= dz; // w2 = (1/8)(w/V)(1-x)(1+y)(1-z) = (w/V) trilin_6 *Done - w3 *= dz; // w3 = (1/8)(w/V)(1+x)(1+y)(1-z) = (w/V) trilin_7 *Done - - // Accumulate the hydro fields -#define ACCUM_HYDRO(wn) \ - t = qsp * wn; /* t = (qsp w/V) trilin_n */ \ - ha[i].jx += t * vx; \ - ha[i].jy += t * vy; \ - ha[i].jz += t * vz; \ - ha[i].rho += t; \ - t = mspc * wn; /* t = (msp c w/V) trilin_n */ \ - dx = t * ux; /* dx = (px w/V) trilin_n */ \ - dy = t * uy; \ - dz = t * uz; \ - ha[i].px += dx; \ - ha[i].py += dy; \ - ha[i].pz += dz; \ - ha[i].ke += t * ke_mc; \ - ha[i].txx += dx * vx; \ - ha[i].tyy += dy * vy; \ - ha[i].tzz += dz * vz; \ - ha[i].tyz += dy * vz; \ - ha[i].tzx += dz * vx; \ - ha[i].txy += dx * vy - - /**/ ACCUM_HYDRO(w0); // Cell i,j,k - i += stride_10; - ACCUM_HYDRO(w1); // Cell i+1,j,k - i += stride_21; - ACCUM_HYDRO(w2); // Cell i,j+1,k - i += stride_10; - ACCUM_HYDRO(w3); // Cell i+1,j+1,k - i += stride_43; - ACCUM_HYDRO(w4); // Cell i,j,k+1 - i += stride_10; - ACCUM_HYDRO(w5); // Cell i+1,j,k+1 - i += stride_21; - ACCUM_HYDRO(w6); // Cell i,j+1,k+1 - i += stride_10; - ACCUM_HYDRO(w7); // Cell i+1,j+1,k+1 - -#undef ACCUM_HYDRO - } - } -}; - -// ====================================================================== -// PscHydroQOps - -template -struct PscHydroQOps -{ - using Mparticles = _Mparticles; - using MfieldsHydro = _MfieldsHydro; - using MfieldsInterpolator = _MfieldsInterpolator; - using Grid = typename MfieldsHydro::Grid; - using Element = typename MfieldsHydro::Element; - - // ---------------------------------------------------------------------- - // clear - - static void clear(MfieldsHydro& hydro) - { - auto h = hydro.data(); - memset(h, 0, hydro.vgrid()->nv * sizeof(*h) * MfieldsHydro::N_COMP); - } - - // ---------------------------------------------------------------------- - // synchronize - - template - struct CommHydro : Comm - { - typedef Comm Base; - typedef G Grid; - - using Base::begin; - using Base::end; - - using Base::buf_size_; - using Base::g_; - using Base::nx_; - - CommHydro(Grid& g) : Base(g) - { - for (int X = 0; X < 3; X++) { - int Y = (X + 1) % 3, Z = (X + 2) % 3; - buf_size_[X] = MfieldsHydro::N_COMP * (nx_[Y] + 1) * (nx_[Z] + 1); - } - } - - void begin_send(int X, int side, float* p, F3D& F) - { - int face = side ? nx_[X] + 1 : 1; - foreach_node(g_, X, face, [&](int x, int y, int z) { - Element* h = &F(x, y, z); - *p++ = h->jx; // 0 - *p++ = h->jy; - *p++ = h->jz; - *p++ = h->rho; - *p++ = h->px; - *p++ = h->py; // 5 - *p++ = h->pz; - *p++ = h->ke; - *p++ = h->txx; - *p++ = h->tyy; - *p++ = h->tzz; // 10 - *p++ = h->tyz; - *p++ = h->tzx; - *p++ = h->txy; - *p++ = h->qxxx; - *p++ = h->qyyy; // 15 - *p++ = h->qzzz; - *p++ = h->qxxy; - *p++ = h->qyyz; - *p++ = h->qzzx; - *p++ = h->qxxz; // 20 - *p++ = h->qyyx; - *p++ = h->qzzy; - *p++ = h->qxyz; - }); - } - - void end_recv(int X, int side, float* p, F3D& F) - { - int face = side ? 1 : nx_[X] + 1; - foreach_node(g_, X, face, [&](int x, int y, int z) { - Element* h = &F(x, y, z); - h->jx += *p++; - h->jy += *p++; - h->jz += *p++; - h->rho += *p++; - h->px += *p++; - h->py += *p++; - h->pz += *p++; - h->ke += *p++; - h->txx += *p++; - h->tyy += *p++; - h->tzz += *p++; - h->tyz += *p++; - h->tzx += *p++; - h->txy += *p++; - h->qxxx += *p++; - h->qyyy += *p++; - h->qzzz += *p++; - h->qxxy += *p++; - h->qyyz += *p++; - h->qzzx += *p++; - h->qxxz += *p++; - h->qyyx += *p++; - h->qzzy += *p++; - h->qxyz += *p++; - }); - } - }; - - static void synchronize(MfieldsHydro& hydro) - { - using F3D = Field3D; - int face, bc, x, y, z; - Element* h; - - auto g = hydro.vgrid(); - const int nx = g->nx, ny = g->ny, nz = g->nz; - auto fields_hydro = hydro[0]; - F3D H{hydro.getPatch(0)}; - - // Note: synchronize_hydro assumes that hydro has not been adjusted - // at the local domain boundary. Because hydro fields are purely - // diagnostic, correct the hydro along local boundaries to account - // for accumulations over partial cell volumes - -#define ADJUST_HYDRO(i, j, k, X, Y, Z) \ - do { \ - int bc = g->bc[BOUNDARY(i, j, k)]; \ - if (bc < 0 || bc >= psc_world_size) { \ - face = (i + j + k) < 0 ? 1 : n##X + 1; \ - X##_NODE_LOOP(face) \ - { \ - h = &H(x, y, z); \ - h->jx *= 2; \ - h->jy *= 2; \ - h->jz *= 2; \ - h->rho *= 2; \ - h->px *= 2; \ - h->py *= 2; \ - h->pz *= 2; \ - h->ke *= 2; \ - h->txx *= 2; \ - h->tyy *= 2; \ - h->tzz *= 2; \ - h->tyz *= 2; \ - h->tzx *= 2; \ - h->txy *= 2; \ - h->qxxx *= 2; \ - h->qyyy *= 2; \ - h->qzzz *= 2; \ - h->qxxy *= 2; \ - h->qyyz *= 2; \ - h->qzzx *= 2; \ - h->qxxz *= 2; \ - h->qyyx *= 2; \ - h->qzzy *= 2; \ - h->qxyz *= 2; \ - } \ - } \ - } while (0) - - ADJUST_HYDRO(-1, 0, 0, x, y, z); - ADJUST_HYDRO(0, -1, 0, y, z, x); - ADJUST_HYDRO(0, 0, -1, z, x, y); - ADJUST_HYDRO(1, 0, 0, x, y, z); - ADJUST_HYDRO(0, 1, 0, y, z, x); - ADJUST_HYDRO(0, 0, 1, z, x, y); - -#undef ADJUST_HYDRO - - CommHydro comm{*hydro.vgrid()}; - - for (int dir = 0; dir < 3; dir++) { - comm.begin(dir, H); - comm.end(dir, H); - } - } - - // ---------------------------------------------------------------------- - // accumulate_hydro_p - - // accumulate_hydro_p adds the hydrodynamic fields associated with the - // supplied particle_list to the hydro array. Trilinear interpolation - // is used. hydro is known at the nodes at the same time as particle - // positions. No effort is made to fix up edges of the computational - // domain. All particles on the list must be inbounds. Note, the - // hydro jx,jy,jz are for diagnostic purposes only; they are not - // accumulated with a charge conserving algorithm. - - static void accumulate_hydro_p( - MfieldsHydro& hydro, - const typename Mparticles::ConstSpeciesIterator sp_iter, - /*const*/ MfieldsInterpolator& interpolator) - { - auto& sp = *sp_iter; - auto& ha = hydro.getPatch(0); - auto& IP = interpolator.getPatch(0); - float c, qsp, mspc, qdt_2mc, qdt_4mc2, r8V; - int np, stride_10, stride_21, stride_43; - - float dx, dy, dz, ux, uy, uz, w, vx, vy, vz, ke_mc; - float w0, w1, w2, w3, w4, w5, w6, w7, t; - int i, n; - - const auto& g = sp.vgrid(); - const auto* p = sp.p; - - c = g.cvac; - qsp = sp.q; - mspc = sp.m * c; - qdt_2mc = (qsp * g.dt) / (2 * mspc); - qdt_4mc2 = qdt_2mc / (2 * c); - r8V = g.r8V; - - np = sp.np; - stride_10 = - (VOXEL(1, 0, 0, g.nx, g.ny, g.nz) - VOXEL(0, 0, 0, g.nx, g.ny, g.nz)); - stride_21 = - (VOXEL(0, 1, 0, g.nx, g.ny, g.nz) - VOXEL(1, 0, 0, g.nx, g.ny, g.nz)); - stride_43 = - (VOXEL(0, 0, 1, g.nx, g.ny, g.nz) - VOXEL(1, 1, 0, g.nx, g.ny, g.nz)); - - for (n = 0; n < np; n++) { - - // Load the particle - dx = p[n].dx; - dy = p[n].dy; - dz = p[n].dz; - i = p[n].i; - ux = p[n].ux; - uy = p[n].uy; - uz = p[n].uz; - w = p[n].w; - - // Half advance E - ux += qdt_2mc * ((IP[i].ex + dy * IP[i].dexdy) + - dz * (IP[i].dexdz + dy * IP[i].d2exdydz)); - uy += qdt_2mc * ((IP[i].ey + dz * IP[i].deydz) + - dx * (IP[i].deydx + dz * IP[i].d2eydzdx)); - uz += qdt_2mc * ((IP[i].ez + dx * IP[i].dezdx) + - dy * (IP[i].dezdy + dx * IP[i].d2ezdxdy)); - - // Boris rotation - Interpolate B field - w5 = IP[i].cbx + dx * IP[i].dcbxdx; - w6 = IP[i].cby + dy * IP[i].dcbydy; - w7 = IP[i].cbz + dz * IP[i].dcbzdz; - - // Boris rotation - curl scalars (0.5 in v0 for half rotate) and - // kinetic energy computation. Note: gamma-1 = |u|^2 / (gamma+1) - // is the numerically accurate way to compute gamma-1 - ke_mc = ux * ux + uy * uy + uz * uz; // ke_mc = |u|^2 (invariant) - vz = sqrt(1 + ke_mc); // vz = gamma (invariant) - ke_mc *= c / (vz + 1); // ke_mc = c|u|^2/(gamma+1) = c*(gamma-1) - vz = c / vz; // vz = c/gamma - w0 = qdt_4mc2 * vz; - w1 = w5 * w5 + w6 * w6 + w7 * w7; // |cB|^2 - w2 = w0 * w0 * w1; - w3 = w0 * (1 + (1. / 3.) * w2 * (1 + 0.4 * w2)); - w4 = w3 / (1 + w1 * w3 * w3); - w4 += w4; - - // Boris rotation - uprime - w0 = ux + w3 * (uy * w7 - uz * w6); - w1 = uy + w3 * (uz * w5 - ux * w7); - w2 = uz + w3 * (ux * w6 - uy * w5); - - // Boris rotation - u - ux += w4 * (w1 * w7 - w2 * w6); - uy += w4 * (w2 * w5 - w0 * w7); - uz += w4 * (w0 * w6 - w1 * w5); - - // Compute physical velocities - vx = ux * vz; - vy = uy * vz; - vz *= uz; - - // Compute the trilinear coefficients - w0 = r8V * w; // w0 = (1/8)(w/V) - dx *= w0; // dx = (1/8)(w/V) x - w1 = w0 + dx; // w1 = (1/8)(w/V) + (1/8)(w/V)x = (1/8)(w/V)(1+x) - w0 -= dx; // w0 = (1/8)(w/V) - (1/8)(w/V)x = (1/8)(w/V)(1-x) - w3 = 1 + dy; // w3 = 1+y - w2 = w0 * w3; // w2 = (1/8)(w/V)(1-x)(1+y) - w3 *= w1; // w3 = (1/8)(w/V)(1+x)(1+y) - dy = 1 - dy; // dy = 1-y - w0 *= dy; // w0 = (1/8)(w/V)(1-x)(1-y) - w1 *= dy; // w1 = (1/8)(w/V)(1+x)(1-y) - w7 = 1 + dz; // w7 = 1+z - w4 = w0 * w7; // w4 = (1/8)(w/V)(1-x)(1-y)(1+z) = (w/V) trilin_0 *Done - w5 = w1 * w7; // w5 = (1/8)(w/V)(1+x)(1-y)(1+z) = (w/V) trilin_1 *Done - w6 = w2 * w7; // w6 = (1/8)(w/V)(1-x)(1+y)(1+z) = (w/V) trilin_2 *Done - w7 *= w3; // w7 = (1/8)(w/V)(1+x)(1+y)(1+z) = (w/V) trilin_3 *Done - dz = 1 - dz; // dz = 1-z - w0 *= dz; // w0 = (1/8)(w/V)(1-x)(1-y)(1-z) = (w/V) trilin_4 *Done - w1 *= dz; // w1 = (1/8)(w/V)(1+x)(1-y)(1-z) = (w/V) trilin_5 *Done - w2 *= dz; // w2 = (1/8)(w/V)(1-x)(1+y)(1-z) = (w/V) trilin_6 *Done - w3 *= dz; // w3 = (1/8)(w/V)(1+x)(1+y)(1-z) = (w/V) trilin_7 *Done - - // Accumulate the hydro fields -#define ACCUM_HYDRO(wn) \ - t = qsp * wn; /* t = (qsp w/V) trilin_n */ \ - ha[i].jx += t * vx; \ - ha[i].jy += t * vy; \ - ha[i].jz += t * vz; \ - ha[i].rho += t; \ - t = mspc * wn; /* t = (msp c w/V) trilin_n */ \ - dx = t * ux; /* dx = (px w/V) trilin_n */ \ - dy = t * uy; \ - dz = t * uz; \ - ha[i].px += dx; \ - ha[i].py += dy; \ - ha[i].pz += dz; \ - ha[i].ke += t * ke_mc; \ - ha[i].txx += dx * vx; \ - ha[i].tyy += dy * vy; \ - ha[i].tzz += dz * vz; \ - ha[i].tyz += dy * vz; \ - ha[i].tzx += dz * vx; \ - ha[i].txy += dx * vy; \ - ha[i].qxxx += dx * vx * vx; \ - ha[i].qyyy += dy * vy * vy; \ - ha[i].qzzz += dz * vz * vz; \ - ha[i].qxxy += dx * vx * vy; \ - ha[i].qyyz += dy * vy * vz; \ - ha[i].qzzx += dz * vz * vx; \ - ha[i].qxxz += dx * vx * vz; \ - ha[i].qyyx += dy * vy * vx; \ - ha[i].qzzy += dz * vz * vy; \ - ha[i].qxyz += dx * vy * vz - - /**/ ACCUM_HYDRO(w0); // Cell i,j,k - i += stride_10; - ACCUM_HYDRO(w1); // Cell i+1,j,k - i += stride_21; - ACCUM_HYDRO(w2); // Cell i,j+1,k - i += stride_10; - ACCUM_HYDRO(w3); // Cell i+1,j+1,k - i += stride_43; - ACCUM_HYDRO(w4); // Cell i,j,k+1 - i += stride_10; - ACCUM_HYDRO(w5); // Cell i+1,j,k+1 - i += stride_21; - ACCUM_HYDRO(w6); // Cell i,j+1,k+1 - i += stride_10; - ACCUM_HYDRO(w7); // Cell i+1,j+1,k+1 - -#undef ACCUM_HYDRO - } - } -}; - -#undef XYZ_LOOP -#undef x_NODE_LOOP -#undef y_NODE_LOOP -#undef z_NODE_LOOP diff --git a/src/libpsc/vpic/vpic_iface.h b/src/libpsc/vpic/vpic_iface.h deleted file mode 100644 index b61b942659..0000000000 --- a/src/libpsc/vpic/vpic_iface.h +++ /dev/null @@ -1,95 +0,0 @@ - -#ifndef VPIC_IFACE_H -#define VPIC_IFACE_H - -#include "vpic_config.h" - -#include - -#include -#include - -// ---------------------------------------------------------------------- -// vpic_mparticles - -struct psc_particle_inject; - -// ---------------------------------------------------------------------- -// Simulation - -struct vpic_simulation_info; -struct field_array; - -// Harris specific -void Simulation_set_region_resistive_harris(struct vpic_harris_params* prm, - struct globals_physics* phys, - double dx[3], double thickness, - struct material* resistive); - -// ---------------------------------------------------------------------- -// vpic_kind_info - -struct vpic_kind_info -{ - double q; - double m; - char* name; -}; - -// ---------------------------------------------------------------------- -// vpic_simulation_info -// -// returned from vpic_simulation_init - -struct vpic_simulation_info -{ - int num_step; - double dt; - int nx[3]; - double dx[3]; - double x0[3]; - double x1[3]; - - int n_kinds; - struct vpic_kind_info* kinds; - - int clean_div_e_interval; - int clean_div_b_interval; - int sync_shared_interval; - int num_div_e_round; - int num_div_b_round; - - int status_interval; -}; - -struct vpic_simulation; - -// FIXME, replicated -#define BOUNDARY(i, j, k) \ - (13 + (i) + 3 * (j) + 9 * (k)) /* FORTRAN -1:1,-1:1,-1:1 */ - -#ifndef mprintf - -#include - -#define mprintf(fmt...) \ - do { \ - int __rank; \ - MPI_Comm_rank(MPI_COMM_WORLD, &__rank); \ - { \ - printf("[%d] ", __rank); \ - printf(fmt); \ - } \ - } while (0) - -#define MHERE \ - do { \ - int __rank; \ - MPI_Comm_rank(MPI_COMM_WORLD, &__rank); \ - printf("[%d] HERE: in %s() at %s:%d\n", __rank, __FUNCTION__, __FILE__, \ - __LINE__); \ - } while (0) - -#endif - -#endif diff --git a/src/psc_config.hxx b/src/psc_config.hxx index 977ed9e54d..d7e960235f 100644 --- a/src/psc_config.hxx +++ b/src/psc_config.hxx @@ -28,8 +28,6 @@ #include "../libpsc/cuda/sort_cuda_impl.hxx" #endif -#include "../libpsc/vpic/fields_item_vpic.hxx" - template using OutputParticlesDefault = OutputParticlesHdf5; From 90a30ccb446b0c07cfef7c612b9d20f25bab13cb Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 26 May 2026 15:12:48 -0400 Subject: [PATCH 44/46] -mfields_hydro --- src/include/mfields_hydro.hxx | 121 ---------------------------------- 1 file changed, 121 deletions(-) delete mode 100644 src/include/mfields_hydro.hxx diff --git a/src/include/mfields_hydro.hxx b/src/include/mfields_hydro.hxx deleted file mode 100644 index 80a3fb102c..0000000000 --- a/src/include/mfields_hydro.hxx +++ /dev/null @@ -1,121 +0,0 @@ - -#pragma once - -#include - -// ====================================================================== -// MfieldsHydroPsc - -template -struct MfieldsHydroPsc -{ - using Grid = _Grid; - using real_t = float; - using fields_view_t = kg::SArrayView; - - struct Element - { - float jx, jy, jz, rho; // Current and charge density => , - float px, py, pz, - ke; // Momentum and K.E. density => , - float txx, tyy, tzz; // Stress diagonal => , i==j - float tyz, tzx, txy; // Stress off-diagonal => , i!=j - float _pad[2]; // 16-byte align - }; - - using Patch = PscFieldBase; - - enum - { - N_COMP = 16, - }; - - static_assert(N_COMP == sizeof(Element) / sizeof(real_t), - "N_COMP doesn't match Element"); - - MfieldsHydroPsc(const Grid_t& grid, Grid* vgrid) : grid_{grid}, patch_{vgrid} - { - assert(grid.n_patches() == 1); - - const int B = 1; // VPIC always uses one ghost cell (on c.c. grid) - im_ = {vgrid->nx + 2 * B, vgrid->ny + 2 * B, vgrid->nz + 2 * B}; - ib_ = {-B, -B, -B}; - } - - int n_patches() const { return grid_.n_patches(); } - int n_comps() const { return N_COMP; } - - real_t* data() { return reinterpret_cast(patch_.data()); } - - fields_view_t operator[](int p) { return {{ib_, im_}, N_COMP, data()}; } - Patch& getPatch(int p) { return patch_; } - // FIXME the above two kinds of accessing a patch worth of data needs - // consolidation - - Grid* vgrid() { return patch_.grid(); } - -private: - const Grid_t& grid_; - Patch patch_; - Int3 ib_, im_; -}; - -// ====================================================================== -// MfieldsHydroQ - -template -struct MfieldsHydroQ -{ - using Grid = _Grid; - using real_t = float; - using fields_view_t = kg::SArrayView; - - struct Element - { - float jx, jy, jz, rho; // Current and charge density => , - float px, py, pz, - ke; // Momentum and K.E. density => , - float txx, tyy, tzz; // Stress diagonal => , i==j - float tyz, tzx, txy; // Stress off-diagonal => , i!=j - float qxxx, qyyy, qzzz; - float qxxy, qyyz, qzzx; - float qxxz, qyyx, qzzy; - float qxyz; - }; - - using Patch = PscFieldBase; - - enum - { - N_COMP = 24, - }; - - static_assert(N_COMP == sizeof(Element) / sizeof(real_t), - "N_COMP doesn't match Element"); - - MfieldsHydroQ(const Grid_t& grid, Grid* vgrid) : grid_{grid}, patch_{vgrid} - { - assert(grid.n_patches() == 1); - - const int B = 1; // VPIC always uses one ghost cell (on c.c. grid) - im_ = {vgrid->nx + 2 * B, vgrid->ny + 2 * B, vgrid->nz + 2 * B}; - ib_ = {-B, -B, -B}; - } - - int n_patches() const { return grid_.n_patches(); } - int n_comps() const { return N_COMP; } - - real_t* data() { return reinterpret_cast(patch_.data()); } - - fields_view_t operator[](int p) { return {{ib_, im_}, N_COMP, data()}; } - Patch& getPatch(int p) { return patch_; } - // FIXME the above two kinds of accessing a patch worth of data needs - // consolidation - - Grid* vgrid() { return patch_.grid(); } - -private: - const Grid_t& grid_; - Patch patch_; - Int3 ib_, im_; -}; From fa37714c7654cf0023efc68211c10984df5ed50b Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 26 May 2026 15:16:13 -0400 Subject: [PATCH 45/46] bits: -unused macros --- src/libpsc/bits.hxx | 47 --------------------------------------------- 1 file changed, 47 deletions(-) diff --git a/src/libpsc/bits.hxx b/src/libpsc/bits.hxx index 0ba941589d..da3192bedf 100644 --- a/src/libpsc/bits.hxx +++ b/src/libpsc/bits.hxx @@ -8,53 +8,6 @@ extern MPI_Comm psc_comm_world; extern int psc_world_rank; extern int psc_world_size; -// FIXME, this is chosen globally and to match vpic, but could be -// made dependent on actual MaterialList implementation -enum -{ - MaterialIdMax = 32768 -}; -typedef int16_t MaterialId; - -// FIXME, this is chosen globally and to match vpic for now -typedef int32_t SpeciesId; // Must be 32-bit wide for particle_injector_t - -// FIXME, get rid of this BOUNDARY macro -#define BOUNDARY(i, j, k) \ - (13 + (i) + 3 * (j) + 9 * (k)) /* FORTRAN -1:1,-1:1,-1:1 */ - -// FIXME, get rid of -#define VOXEL(x, y, z, nx, ny, nz) ((x) + ((nx) + 2) * ((y) + ((ny) + 2) * (z))) - -// FIXME, get rid of -#define BEGIN_PRIMITIVE do -#define END_PRIMITIVE while (0) - -// FIXME -#ifndef ALIGNED -#define ALIGNED(a) -#endif - -// FIXME -#ifndef RESTRICT -#define RESTRICT __restrict -#endif - -// FIXME -#define DECLARE_ALIGNED_ARRAY(type, align, name, count) \ - type name[(count)] __attribute__((aligned(align))) - -// FIXME -#define POW2_CEIL(u, a) (((u) + (a) - 1) & (~((a) - 1))) - -// FIXME -#ifndef LIKELY -#define LIKELY(_c) __builtin_expect((_c), 1) -#endif -#ifndef UNLIKELY -#define UNLIKELY(_c) __builtin_expect((_c), 0) -#endif - #ifndef mprintf #define mprintf(fmt...) \ do { \ From 4f0f4b70c76a3b1739e03d0c5198aa83ec74c801 Mon Sep 17 00:00:00 2001 From: James McClung Date: Tue, 26 May 2026 15:16:28 -0400 Subject: [PATCH 46/46] *: -vpic vestiges --- CMakeLists.txt | 31 +++++++++++++----------- README.md | 1 - src/include/PscConfig.h.in | 1 - src/include/checkpoint.hxx | 2 +- src/libpsc/CMakeLists.txt | 10 -------- src/libpsc/tests/CMakeLists.txt | 2 +- src/libpsc/tests/test_mparticles.cxx | 2 -- src/libpsc/tests/test_push_particles.cxx | 1 - 8 files changed, 19 insertions(+), 31 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 822488650a..9ce0ed050e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,10 @@ -cmake_minimum_required (VERSION 3.21) +cmake_minimum_required(VERSION 3.21) foreach(policy - CMP0074 # CMake 3.12 - CMP0104 # CMAKE_CUDA_ARCHITECTURES - ) + CMP0074 # CMake 3.12 + CMP0104 # CMAKE_CUDA_ARCHITECTURES +) if(POLICY ${policy}) cmake_policy(SET ${policy} NEW) endif() @@ -27,7 +27,6 @@ endfunction() set(PSC_GPU "host" CACHE STRING "Build with GPU supoort (host/cuda/hip)") set_property(CACHE PSC_GPU PROPERTY STRINGS "host;cuda;hip") -option(USE_VPIC "Interface with VPIC" OFF) option(USE_GTEST_DISCOVER_TESTS "Run tests to discover contained googletest cases" OFF) psc_option(ADIOS2 "Build with adios2 support" AUTO) option(PSC_USE_NVTX "Build with NVTX support" OFF) @@ -37,8 +36,8 @@ option(PSC_USE_PERFETTO "Turn on perfetto-based tracing" OFF) option(USE_CUDA "Build CUDA components" OFF) -if (USE_CUDA) - set(PSC_GPU "cuda" CACHE STRING "Build with GPU supoort (none/cuda/hip)") +if(USE_CUDA) + set(PSC_GPU "cuda" CACHE STRING "Build with GPU supoort (none/cuda/hip)") endif() if(PSC_GPU STREQUAL "cuda") @@ -56,6 +55,7 @@ elseif(PSC_GPU STREQUAL "hip") else() set(USE_CUDA OFF) endif() + set(GTENSOR_DEVICE "${PSC_GPU}" CACHE STRING "") CPMAddPackage( @@ -65,14 +65,14 @@ CPMAddPackage( VERSION 0.0.0 ) -if (BUILD_TESTING) +if(BUILD_TESTING) CPMAddPackage( NAME GTest GITHUB_REPOSITORY google/googletest VERSION 1.14.0 OPTIONS - "INSTALL_GTEST OFF" - "gtest_force_shared_crt ON" + "INSTALL_GTEST OFF" + "gtest_force_shared_crt ON" ) include(GoogleTest) endif() @@ -86,23 +86,24 @@ if(PSC_USE_ADIOS2 STREQUAL AUTO) elseif(PSC_USE_ADIOS2) find_package(ADIOS2 CONFIG REQUIRED) endif() + if(ADIOS2_FOUND) set(PSC_HAVE_ADIOS2 1) endif() # NVTX -if (PSC_USE_NVTX) +if(PSC_USE_NVTX) find_package(CUDAToolkit REQUIRED) set(PSC_HAVE_NVTX 1) endif() # RMM -if (PSC_USE_RMM) +if(PSC_USE_RMM) find_package(rmm 0.18.0 CONFIG REQUIRED) set(PSC_HAVE_RMM 1) endif() -if (PSC_USE_PERFETTO) +if(PSC_USE_PERFETTO) CPMAddPackage("gh:google/perfetto@24.2") find_package(Threads REQUIRED) add_library(perfetto STATIC ${perfetto_SOURCE_DIR}/sdk/perfetto.cc) @@ -113,6 +114,7 @@ endif() function(GenerateHeaderConfig) set(PSC_CONFIG_DEFINES) + foreach(OPT IN LISTS ARGN) string(APPEND PSC_CONFIG_DEFINES " /* CMake Option: PSC_USE_${OPT}=${PSC_USE_${OPT}} */ @@ -130,11 +132,12 @@ function(GenerateHeaderConfig) ) endfunction() -# FIXME, unify USE_CUDA, USE_VPIC options / autodetect +# FIXME, unify USE_CUDA options / autodetect # FIXME, mv helpers into separate file GenerateHeaderConfig(ADIOS2 NVTX RMM) include_directories(${CMAKE_CURRENT_BINARY_DIR}/src/include) + # FIXME, this seems too ugly to find mrc_config.h include_directories(${CMAKE_CURRENT_BINARY_DIR}/src/libmrc/include) diff --git a/README.md b/README.md index 8f3dbc5ea3..c366cb9ec6 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,6 @@ $ cat > cmake.sh <