150 if (
mask[i] == 0) {
return 0; }
151 const auto selected_process_index =
mask[i] - 1;
152 auto const& scattering_process = scattering_processes[selected_process_index];
153 return !scattering_process.m_produces_products;
160 for (
int i = 0; i < 2; i++)
165 num_added_vec[i] =
static_cast<int>(no_product_total);
176 if (
mask[i] == 0) {
return 0; }
177 const auto selected_process_index =
mask[i] - 1;
178 auto const& scattering_process = scattering_processes[selected_process_index];
179 return scattering_process.m_produces_products;
189 const index_type num_added = with_product_total * num_products;
190 num_added_vec[i] +=
static_cast<int>(num_added);
201 products_np[i] = tile_products[i]->numParticles();
202 tile_products[i]->resize(products_np[i] + num_added_vec[i]);
205 const auto soa_0 = ptile0.getParticleTileData();
206 const auto soa_1 = ptile1.getParticleTileData();
212 soa_products.push_back(tile_products[i]->getParticleTileData());
220 device_soa_products.
begin());
223 device_products_np.
begin());
238 if (num_product_species > 2) {
239 mass_slot2 = pc_products[2]->getMass();
240 mass_slot3 = pc_products[3]->getMass();
248 if (
mask[i] == 0) {
return; }
251 const auto selected_process_index =
mask[i] - 1;
252 auto const& scattering_process = scattering_processes[selected_process_index];
253 const auto process_type = scattering_process.m_type;
255 if (!scattering_process.m_produces_products)
257 const auto slot0_idx = products_np_data[0] + no_product_offsets_data[i];
259 copy_species0[0](soa_products_data[0], soa_0,
static_cast<int>(p_pair_indices_0[i]),
260 static_cast<int>(slot0_idx), engine);
262 soa_products_data[0].m_rdata[
PIdx::w][slot0_idx] = p_pair_reaction_weight[i];
264 const auto slot1_idx = products_np_data[1] + no_product_offsets_data[i];
266 copy_species1[1](soa_products_data[1], soa_1,
static_cast<int>(p_pair_indices_1[i]),
267 static_cast<int>(slot1_idx), engine);
269 soa_products_data[1].m_rdata[
PIdx::w][slot1_idx] = p_pair_reaction_weight[i];
276 const auto src0_idx =
static_cast<int>(p_pair_indices_0[i]);
277 const auto src1_idx =
static_cast<int>(p_pair_indices_1[i]);
279 TwoProductComputeProductMomenta(
282 soa_0.m_rdata[
PIdx::uz][src0_idx], m0,
285 soa_1.m_rdata[
PIdx::uz][src1_idx], m1,
286 soa_products_data[0].m_rdata[
PIdx::ux][slot0_idx],
287 soa_products_data[0].m_rdata[
PIdx::uy][slot0_idx],
288 soa_products_data[0].m_rdata[
PIdx::uz][slot0_idx], m0,
289 soa_products_data[1].m_rdata[
PIdx::ux][slot1_idx],
290 soa_products_data[1].m_rdata[
PIdx::uy][slot1_idx],
291 soa_products_data[1].m_rdata[
PIdx::uz][slot1_idx], m1,
295 scattering_process.m_scattering_angle_model,
304 const auto src0_idx =
static_cast<int>(p_pair_indices_0[i]);
305 const auto slot2_idx = products_np_data[2] + with_product_offsets_data[i];
306 copy_species0[2](soa_products_data[2], soa_0, src0_idx,
307 static_cast<int>(slot2_idx), engine);
309 soa_products_data[2].m_rdata[
PIdx::w][slot2_idx] = p_pair_reaction_weight[i];
312 const auto src1_idx =
static_cast<int>(p_pair_indices_1[i]);
313 const auto slot3_idx = products_np_data[3] + with_product_offsets_data[i];
314 copy_species1[3](soa_products_data[3], soa_1, src1_idx,
315 static_cast<int>(slot3_idx), engine);
317 soa_products_data[3].m_rdata[
PIdx::w][slot3_idx] = p_pair_reaction_weight[i];
324#if defined(WARPX_DIM_1D_Z)
325 constexpr std::array<int, 1> position_indices = {
PIdx::z};
326#elif defined(WARPX_DIM_XZ)
327 constexpr std::array<int, 2> position_indices = {
PIdx::x,
PIdx::z};
328#elif defined(WARPX_DIM_RZ)
329 constexpr std::array<int, 3> position_indices = {PIdx::r,
PIdx::z, PIdx::theta};
330#elif defined(WARPX_DIM_RCYLINDER)
331 constexpr std::array<int, 2> position_indices = {PIdx::r, PIdx::theta};
332#elif defined(WARPX_DIM_RSPHERE)
333 constexpr std::array<int, 3> position_indices = {PIdx::r, PIdx::theta, PIdx::phi};
334#elif defined(WARPX_DIM_3D)
335 constexpr std::array<int, 3> position_indices = {
PIdx::x, PIdx::y,
PIdx::z};
338 for (
int const idim : position_indices) {
339 soa_products_data[2].m_rdata[idim][slot2_idx] = soa_1.m_rdata[idim][src1_idx];
340 soa_products_data[3].m_rdata[idim][slot3_idx] = soa_0.m_rdata[idim][src0_idx];
345 TwoProductComputeProductMomenta(
348 soa_0.m_rdata[
PIdx::uz][src0_idx], m0,
351 soa_1.m_rdata[
PIdx::uz][src1_idx], m1,
352 soa_products_data[2].m_rdata[
PIdx::ux][slot2_idx],
353 soa_products_data[2].m_rdata[
PIdx::uy][slot2_idx],
354 soa_products_data[2].m_rdata[
PIdx::uz][slot2_idx], mass_slot2,
355 soa_products_data[3].m_rdata[
PIdx::ux][slot3_idx],
356 soa_products_data[3].m_rdata[
PIdx::uy][slot3_idx],
357 soa_products_data[3].m_rdata[
PIdx::uz][slot3_idx], mass_slot3,
361 scattering_process.m_scattering_angle_model,
368 const auto slot0_idx = products_np_data[0] + no_product_total + with_product_offsets_data[i];
370 copy_species0[0](soa_products_data[0], soa_0,
static_cast<int>(p_pair_indices_0[i]),
371 static_cast<int>(slot0_idx), engine);
373 soa_products_data[0].m_rdata[
PIdx::w][slot0_idx] = p_pair_reaction_weight[i];
377 const auto slot2_idx = products_np_data[2] + with_product_offsets_data[i];
378 copy_species1[2](soa_products_data[2], soa_1,
static_cast<int>(p_pair_indices_1[i]),
379 static_cast<int>(slot2_idx), engine);
381 soa_products_data[2].m_rdata[
PIdx::w][slot2_idx] = p_pair_reaction_weight[i];
385 const auto slot3_idx = products_np_data[3] + with_product_offsets_data[i];
386 copy_species1[3](soa_products_data[3], soa_1,
static_cast<int>(p_pair_indices_1[i]),
387 static_cast<int>(slot3_idx), engine);
389 soa_products_data[3].m_rdata[
PIdx::w][slot3_idx] = p_pair_reaction_weight[i];
394 auto& ux0 = soa_products_data[0].m_rdata[
PIdx::ux][slot0_idx];
395 auto& uy0 = soa_products_data[0].m_rdata[
PIdx::uy][slot0_idx];
396 auto& uz0 = soa_products_data[0].m_rdata[
PIdx::uz][slot0_idx];
397 auto& ux2 = soa_products_data[2].m_rdata[
PIdx::ux][slot2_idx];
398 auto& uy2 = soa_products_data[2].m_rdata[
PIdx::uy][slot2_idx];
399 auto& uz2 = soa_products_data[2].m_rdata[
PIdx::uz][slot2_idx];
400 auto& ux3 = soa_products_data[3].m_rdata[
PIdx::ux][slot3_idx];
401 auto& uy3 = soa_products_data[3].m_rdata[
PIdx::uy][slot3_idx];
402 auto& uz3 = soa_products_data[3].m_rdata[
PIdx::uz][slot3_idx];
404#if defined(WARPX_DIM_RZ) || defined(WARPX_DIM_RCYLINDER)
415 soa_products_data[2].m_rdata[PIdx::theta][slot2_idx]
416 - soa_products_data[0].m_rdata[PIdx::theta][slot0_idx]
419 ux0 = ux0buf*std::cos(theta) - uy0*std::sin(theta);
420 uy0 = ux0buf*std::sin(theta) + uy0*std::cos(theta);
426 auto const uCOM_x = (m0 * ux0 + m1 * ux3) / (m0 + m1);
427 auto const uCOM_y = (m0 * uy0 + m1 * uy3) / (m0 + m1);
428 auto const uCOM_z = (m0 * uz0 + m1 * uz3) / (m0 + m1);
443 const amrex::ParticleReal E_coll = 0.5_prt * p_non_target_in * p_non_target_in * (1.0_prt/m0 + 1.0_prt/m1);
469 const amrex::ParticleReal p_non_target_out = std::sqrt( 2.0_prt * E_out / (1.0_prt / m0 + 1.0_prt / (mass_slot2 + mass_slot3) ) );
473 ux0 *= reduce_factor;
474 uy0 *= reduce_factor;
475 uz0 *= reduce_factor;
478 ux2 = -mass_ratio * ux0;
479 uy2 = -mass_ratio * uy0;
480 uz2 = -mass_ratio * uz0;
481 ux3 = -mass_ratio * ux0;
482 uy3 = -mass_ratio * uy0;
483 uz3 = -mass_ratio * uz0;
513 const amrex::ParticleReal scaled_u2_ion = scaled_ux_ion*scaled_ux_ion + scaled_uy_ion*scaled_uy_ion + scaled_uz_ion*scaled_uz_ion;
520 E_out / (1.0_prt/m0 + 0.5_prt*scaled_u2_ion/m_ion) );
526 ux0 = p_e/m0 * scaled_ux0;
527 uy0 = p_e/m0 * scaled_uy0;
528 uz0 = p_e/m0 * scaled_uz0;
529 if (mass_slot2 < mass_slot3) {
531 ux2 = p_e/m0 * scaled_ux_new;
532 uy2 = p_e/m0 * scaled_uy_new;
533 uz2 = p_e/m0 * scaled_uz_new;
534 ux3 = p_e/m_ion * scaled_ux_ion;
535 uy3 = p_e/m_ion * scaled_uy_ion;
536 uz3 = p_e/m_ion * scaled_uz_ion;
539 ux3 = p_e/m0 * scaled_ux_new;
540 uy3 = p_e/m0 * scaled_uy_new;
541 uz3 = p_e/m0 * scaled_uz_new;
542 ux2 = p_e/m_ion * scaled_ux_ion;
543 uy2 = p_e/m_ion * scaled_uy_ion;
544 uz2 = p_e/m_ion * scaled_uz_ion;
559#if defined(WARPX_DIM_RZ) || defined(WARPX_DIM_RCYLINDER)
562 ux0 = ux0buf_new*std::cos(-theta) - uy0*std::sin(-theta);
563 uy0 = ux0buf_new*std::sin(-theta) + uy0*std::cos(-theta);
571 const int start_index =
int(products_np[i]);
572 const int stop_index =
int(products_np[i] + num_added_vec[i]);
574 *pc_products[i], start_index, stop_index);
578 return num_added_vec;