Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
6b03006
+run_test
JamesMcClung Oct 15, 2025
a3154a0
inc_curr*; *: rename to .cxx
JamesMcClung Jun 2, 2025
2927615
inc_push; *: rename to .cxx
JamesMcClung Jun 11, 2025
f97cd79
test_reflective_bcs*: rm accidental BgkMfields
JamesMcClung Oct 15, 2025
d8ccd5b
checks_impl: print names of diffed quantities
JamesMcClung Oct 10, 2025
e753e96
setup_particles: add missing includes
JamesMcClung May 8, 2025
d672ca7
setup_particles: get_n_in_cell takes density
JamesMcClung May 16, 2025
23aa83d
setup_particles: mv get_n_in_cell
JamesMcClung May 16, 2025
9ce7fbe
grid: +prts_per_unit_density
JamesMcClung May 16, 2025
13462de
setup_particles: use prts_per_unit_density
JamesMcClung May 16, 2025
63c598f
setup_particles: getWeight takes density
JamesMcClung Oct 10, 2025
27ac2ff
setup_particles: rename wni->weight
JamesMcClung Oct 10, 2025
5f83136
-test_bnd_prt_inflow
JamesMcClung May 8, 2025
02e9a53
+injector_boundary_inflow
JamesMcClung May 9, 2025
aec4453
injector_boundary_inflow: +ParticleGeneratorMaxwellian
JamesMcClung May 9, 2025
add4194
injector_boundary_inflow: +ctor for generator
JamesMcClung May 16, 2025
09bc090
injector_boundary_inflow: make Real types public
JamesMcClung May 16, 2025
6bd48e3
+test_injector_boundary_inflow: failing gen test
JamesMcClung May 16, 2025
b343a88
injector_boundary_inflow: store gen info
JamesMcClung May 16, 2025
0f72110
injector_boundary_inflow; test: pass w too
JamesMcClung May 16, 2025
04984de
injector_boundary_inflow: sample u
JamesMcClung May 16, 2025
4fc0c4c
injector_boundary_inflow; test: pass pos info to get
JamesMcClung May 16, 2025
92cd953
injector_boundary_inflow: template by generator
JamesMcClung May 16, 2025
9656766
test_injector_boundary_inflow: use better kind_idx
JamesMcClung May 16, 2025
eeeb64c
test_injector_boundary_inflow: +Integration test
JamesMcClung May 16, 2025
f461388
test_injector_boundary_inflow: pass inject_particles
JamesMcClung May 16, 2025
54740ac
injector_boundary_inflow: template by PushParticles
JamesMcClung May 16, 2025
397c677
injector_boundary_inflow: pass grid, do injection
JamesMcClung May 16, 2025
692ffc8
injector_boundary_inflow: update currents
JamesMcClung May 16, 2025
5b8be89
test_injector_boundary_inflow: don't put prts at edge
JamesMcClung May 20, 2025
fb944d2
injector_boundary_inflow: don't zero out fields
JamesMcClung May 20, 2025
558f1c2
test_injector_boundary_inflow: use nicell=2
JamesMcClung May 20, 2025
061100b
test_injector_boundary_inflow: use nmax=2
JamesMcClung May 20, 2025
517c97b
injector_boundary_inflow: rename to initial_idx
JamesMcClung May 20, 2025
cc16b89
injector_boundary_inflow: -w
JamesMcClung May 29, 2025
33709d3
injector_boundary_inflow: rm unused vars
JamesMcClung Jun 2, 2025
560ffd3
injector_boundary_inflow: rename prts_in_cell
JamesMcClung Jun 2, 2025
a421716
injector_boundary_inflow: use get_n_in_cell
JamesMcClung Jun 2, 2025
7e427a7
injector_boundary_inflow: rm EM stuff
JamesMcClung Jun 2, 2025
c1173db
injector_boundary_inflow: use cell_idx as initial
JamesMcClung Jun 2, 2025
53570d0
injector_boundary_inflow: rm ip
JamesMcClung Jun 2, 2025
bd50a14
injector_boundary_inflow: rm accessor
JamesMcClung Jun 2, 2025
974d08b
injector_boundary_inflow: mv/rename min_pos
JamesMcClung Jun 2, 2025
9dfcd8c
injector_boundary_inflow: cleanup assertions
JamesMcClung Jun 2, 2025
4d96af6
test_injector_boundary_inflow: use periodic BCs
JamesMcClung Oct 15, 2025
0424644
injector_boundary_inflow: deposit current in boundary
JamesMcClung Oct 15, 2025
d9fa16d
test_injector_boundary_inflow: only inject 1 particle
JamesMcClung Oct 15, 2025
ed93792
test_injector_boundary_inflow: use open BCs
JamesMcClung Oct 10, 2025
c1f3d2e
psc_bnd_fields_impl: assert 0 -> todo
JamesMcClung Oct 10, 2025
c4279cf
test_injector_boundary_inflow: assert n_patches=1
JamesMcClung Oct 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions run_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash
set -e
cd build
make $1
mkdir -p runs
cp ../bits/adios2cfg.xml runs/
cd runs
../src/libpsc/tests/$1 "${@:2}"
2 changes: 2 additions & 0 deletions src/include/grid.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ struct Grid_<T>::Normalization
double vt = sqrt(prm.tt / prm.mm);
double wp = sqrt(sqr(prm.qq) * prm.n0 / prm.eps0 / prm.mm);

prts_per_unit_density = prm.nicell;
cori = 1. / prm.nicell;
double alpha_ = wp / wl;
beta = vt / cc;
Expand All @@ -299,6 +300,7 @@ struct Grid_<T>::Normalization
real_t eta = {1.};
real_t beta = {1.};
real_t cori = {1.};
real_t prts_per_unit_density;

real_t e0;
real_t b0;
Expand Down
158 changes: 158 additions & 0 deletions src/include/injector_boundary_inflow.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
#pragma once

#include <math.h>

#include "grid.hxx"
#include "rng.hxx"
#include "particle.h"
#include <psc.hxx>
#include "pushp.hxx"
#include "dim.hxx"
#include "setup_particles.hxx"
#include "../libpsc/psc_push_particles/inc_push.cxx"

class ParticleGeneratorMaxwellian
{
public:
using Real = psc::particle::Inject::Real;
using Real3 = psc::particle::Inject::Real3;

// FIXME would be nice to just pass 1 thing for kind-related info
ParticleGeneratorMaxwellian(int kind_idx, Grid_t::Kind kind, Real3 mean_u,
Real3 temperature)
: kind_idx{kind_idx}
{
for (int d = 0; d < 3; d++) {
Real stdev_u = sqrt(temperature[d] / kind.m);
vdfs[d] = VelocityDistributionFunction{mean_u[d], stdev_u};
}
}

psc::particle::Inject get(Real3 min_pos, Real3 pos_range)
{
Real3 x;
for (int d = 0; d < 3; d++) {
x[d] = min_pos[d] + uniform_dist.get() * pos_range[d];
}

Real3 u{vdfs[0].get(), vdfs[1].get(), vdfs[2].get()};
Real w = 1.0;
psc::particle::Tag tag = 0;

return {x, u, w, kind_idx, tag};
}

private:
using VelocityDistributionFunction = rng::Normal<Real>;
Vec3<VelocityDistributionFunction> vdfs;
int kind_idx;
rng::Uniform<Real> uniform_dist{0.0, 1.0};
};

template <typename PARTICLE_GENERATOR, typename PUSH_PARTICLES>
class InjectorBoundaryInflow
{
static const int INJECT_DIM_IDX_ = 1;

public:
using ParticleGenerator = PARTICLE_GENERATOR;
using PushParticles = PUSH_PARTICLES;

using Mparticles = typename PushParticles::Mparticles;
using MfieldsState = typename PushParticles::MfieldsState;
using AdvanceParticle_t = typename PushParticles::AdvanceParticle_t;
using Current = typename PushParticles::Current;
using Dim = typename PushParticles::Dim;
using real_t = typename PushParticles::real_t;
using Real3 = typename PushParticles::Real3;
using checks_order = typename PushParticles::checks_order;

InjectorBoundaryInflow(ParticleGenerator particle_generator, Grid_t& grid)
: partice_generator{particle_generator},
advance{grid.dt},
prts_per_unit_density{grid.norm.prts_per_unit_density}
{}

void operator()(Mparticles& mprts, MfieldsState& mflds)
{
static_assert(INJECT_DIM_IDX_ == 1,
"only injection at lower bound of y is supported");

const Grid_t& grid = mprts.grid();
auto injectors_by_patch = mprts.injector();

Real3 dxi = Real3{1., 1., 1.} / Real3(grid.domain.dx);
Current current(grid);

for (int patch_idx = 0; patch_idx < grid.n_patches(); patch_idx++) {
Int3 ilo = grid.patches[patch_idx].off;

if (ilo[INJECT_DIM_IDX_] != 0) {
continue;
}

Int3 ihi = ilo + grid.ldims;

auto&& injector = injectors_by_patch[patch_idx];
auto flds = mflds[patch_idx];
typename Current::fields_t J(flds);

for (Int3 cell_idx = ilo; cell_idx[0] < ihi[0]; cell_idx[0]++) {
for (cell_idx[2] = ilo[2]; cell_idx[2] < ihi[2]; cell_idx[2]++) {
cell_idx[INJECT_DIM_IDX_] = -1;

Real3 cell_corner =
grid.domain.corner + Double3(cell_idx) * grid.domain.dx;
int n_prts_to_try_inject =
get_n_in_cell(1.0, prts_per_unit_density, true);
real_t charge_injected = 0;

for (int prt_count = 0; prt_count < n_prts_to_try_inject;
prt_count++) {
psc::particle::Inject prt =
partice_generator.get(cell_corner, grid.domain.dx);

Real3 v = advance.calc_v(prt.u);
Real3 initial_x = prt.x;
advance.push_x(prt.x, v, 1.0);

if (prt.x[INJECT_DIM_IDX_] < grid.domain.corner[INJECT_DIM_IDX_]) {
// don't inject a particle that fails to enter the domain
continue;
}

injector(prt);

// Update currents
// Taken from push_particles_1vb.hxx PushParticlesVb::push_mprts()

Real3 initial_normalized_pos = initial_x * dxi;

Int3 final_idx;
Real3 final_normalized_pos;
find_idx_pos_1st_rel(prt.x, dxi, final_idx, final_normalized_pos,
real_t(0.));

// CURRENT DENSITY BETWEEN (n+.5)*dt and (n+1.5)*dt
real_t qni_wni = grid.kinds[prt.kind].q * prt.w;
current.calc_j(J, initial_normalized_pos, final_normalized_pos,
final_idx, cell_idx, qni_wni, v);

charge_injected += qni_wni;
}

// set current in boundary to account for injected charge
flds.storage()(cell_idx[0] + grid.ibn[0], -1 + grid.ibn[1],
cell_idx[2] + grid.ibn[2], JXI + 1) =
charge_injected * grid.domain.dx[1] / grid.dt /
prts_per_unit_density;
}
}
}
}

private:
ParticleGenerator partice_generator;
AdvanceParticle<real_t, dim_y> advance;
real_t prts_per_unit_density;
};
57 changes: 36 additions & 21 deletions src/include/setup_particles.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
#include <algorithm>
#include <functional>
#include <type_traits>

#include <mrc_profile.h>

#include "centering.hxx"
#include "particle.h"
#include "rng.hxx"

struct psc_particle_npt
Expand All @@ -24,9 +28,6 @@ struct psc_particle_np
psc::particle::Tag tag;
};

// ======================================================================
// SetupParticles

namespace
{
const centering::Centerer defaultCenterer(centering::CC);
Expand Down Expand Up @@ -92,6 +93,28 @@ private:
std::function<void(int, Double3, int, Int3, psc_particle_np&)> func;
};

// ======================================================================
// get_n_in_cell
//
// helper function for partition / particle setup

template <typename real_t>
int get_n_in_cell(real_t density, real_t prts_per_unit_density,
bool fractional_n_particles_per_cell)
{
static rng::Uniform<float> dist{0, 1};
if (density == 0.0) {
return 0;
}
if (fractional_n_particles_per_cell) {
return density * prts_per_unit_density + dist.get();
}
return std::max(1, int(density * prts_per_unit_density + .5));
}

// ======================================================================
// SetupParticles

template <typename MP>
struct SetupParticles
{
Expand All @@ -111,19 +134,11 @@ struct SetupParticles

// ----------------------------------------------------------------------
// get_n_in_cell
//
// helper function for partition / particle setup

int get_n_in_cell(const psc_particle_np& np)
int get_n_in_cell(real_t density)
{
static rng::Uniform<float> dist{0, 1};
if (np.n == 0) {
return 0;
}
if (fractional_n_particles_per_cell) {
return np.n / norm_.cori + dist.get();
}
return std::max(1, int(np.n / norm_.cori + .5));
return ::get_n_in_cell(density, real_t(norm_.prts_per_unit_density),
fractional_n_particles_per_cell);
}

// ----------------------------------------------------------------------
Expand Down Expand Up @@ -161,7 +176,7 @@ struct SetupParticles

int n_in_cell;
if (pop != neutralizing_population) {
n_in_cell = get_n_in_cell(np);
n_in_cell = get_n_in_cell(np.n);
n_q_in_cell += kinds_[np.kind].q * n_in_cell;
} else {
// FIXME, should handle the case where not the last population
Expand All @@ -180,9 +195,9 @@ struct SetupParticles
// setupParticle

psc::particle::Inject setupParticle(const psc_particle_np& np, Double3 pos,
double wni)
double weight)
{
return psc::particle::Inject{pos, np.p(), wni, np.kind, np.tag};
return psc::particle::Inject{pos, np.p(), weight, np.kind, np.tag};
}

// ----------------------------------------------------------------------
Expand Down Expand Up @@ -244,12 +259,12 @@ struct SetupParticles
// ----------------------------------------------------------------------
// getWeight

real_t getWeight(const psc_particle_np& np, int n_in_cell)
real_t getWeight(real_t density, int n_in_cell)
{
if (fractional_n_particles_per_cell) {
return 1.;
} else {
return np.n / (n_in_cell * norm_.cori);
return density * norm_.prts_per_unit_density / n_in_cell;
}
}

Expand Down Expand Up @@ -281,8 +296,8 @@ struct SetupParticles
op_cellwise(grid, p, init_np,
[&](int n_in_cell, psc_particle_np& np, Double3& pos) {
for (int cnt = 0; cnt < n_in_cell; cnt++) {
real_t wni = getWeight(np, n_in_cell);
auto prt = setupParticle(np, pos, wni);
real_t weight = getWeight(np.n, n_in_cell);
auto prt = setupParticle(np, pos, weight);
injector(prt);
}
});
Expand Down
6 changes: 4 additions & 2 deletions src/libpsc/psc_bnd_fields/psc_bnd_fields_impl.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,8 @@ struct BndFields_ : BndFieldsBase
const int* ldims = mflds.grid().ldims;
Int3 ib = mflds.ib(), im = mflds.im();

assert(0);
// TODO
// assert(0);
#if 0

if (d == 1) {
Expand Down Expand Up @@ -582,7 +583,8 @@ struct BndFields_ : BndFieldsBase
const int* ldims = mflds.grid().ldims;
Int3 ib = mflds.ib(), im = mflds.im();

assert(0);
// TODO
// assert(0);
#if 0
if (d == 1) {
int my _mrc_unused = ldims[1];
Expand Down
2 changes: 2 additions & 0 deletions src/libpsc/psc_checks/checks_impl.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ public:
MPI_Allreduce(&local_err, &max_err, 1, MPI_DOUBLE, MPI_MAX, grid.comm());

if (should_print_diffs(max_err)) {
mpi_printf(grid.comm(), "continuity: drho -- -dt*div j\n");
psc::helper::print_diff(d_rho, -dt_divj, err_threshold);
}

Expand Down Expand Up @@ -160,6 +161,7 @@ public:
max_err = std::max(max_err, patch_err);

if (should_print_diffs(patch_err)) {
mpi_printf(grid.comm(), "gauss: rho -- div E\n");
psc::helper::print_diff(patch_rho, patch_dive, err_threshold);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ GT_INLINE void deposit(Curr& curr, const int _i[3], const real_t fnqs[3],
deposition(curr, i, qni_wni, dx, xa, dim_xyz{});
}

#include "inc_curr_1vb_split.c"
#include "inc_curr_1vb_var1.c"
#include "inc_curr_1vb_2d.c"
#include "inc_curr_zigzag.c"
#include "inc_curr_1vb_split.cxx"
#include "inc_curr_1vb_var1.cxx"
#include "inc_curr_1vb_2d.cxx"
#include "inc_curr_zigzag.cxx"

template <typename _Order, typename _Dim, typename _fields_t>
struct Current1vb;
4 changes: 2 additions & 2 deletions src/libpsc/psc_push_particles/push_config.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

#include "inc_defs.h"
#include "interpolate.hxx"
#include "inc_curr.c"
#include "inc_push.c"
#include "inc_curr.cxx"
#include "inc_push.cxx"
#include "push_particles.hxx"
#include "push_particles_esirkepov.hxx"
#include "push_particles_1vb.hxx"
Expand Down
2 changes: 1 addition & 1 deletion src/libpsc/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ add_psc_test(test_reflective_bcs_integration)
add_psc_test(test_mfields)
add_psc_test(test_mfields_cuda)
add_psc_test(test_bnd)
add_psc_test(test_bnd_prt_inflow)
add_psc_test(test_injector_boundary_inflow)
add_psc_test(test_deposit)
add_psc_test(test_current_deposition)
add_psc_test(test_push_particles)
Expand Down
Loading