1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
/* Copyright 2021 Neil Zaim
*
* This file is part of WarpX.
*
* License: BSD-3-Clause-LBNL
*/
#include "BinaryCollisionUtils.H"
#include "Particles/MultiParticleContainer.H"
#include "Particles/WarpXParticleContainer.H"
#include <AMReX_ParmParse.H>
#include <AMReX_Vector.H>
#include <string>
namespace BinaryCollisionUtils{
NuclearFusionType get_nuclear_fusion_type (const std::string collision_name,
MultiParticleContainer const * const mypc)
{
const amrex::ParmParse pp_collision_name(collision_name);
amrex::Vector<std::string> species_names;
pp_collision_name.getarr("species", species_names);
auto& species1 = mypc->GetParticleContainerFromName(species_names[0]);
auto& species2 = mypc->GetParticleContainerFromName(species_names[1]);
amrex::Vector<std::string> product_species_name;
pp_collision_name.getarr("product_species", product_species_name);
if ((species1.AmIA<PhysicalSpecies::hydrogen2>() && species2.AmIA<PhysicalSpecies::hydrogen3>())
||
(species1.AmIA<PhysicalSpecies::hydrogen3>() && species2.AmIA<PhysicalSpecies::hydrogen2>())
)
{
WARPX_ALWAYS_ASSERT_WITH_MESSAGE(
product_species_name.size() == 2u,
"ERROR: Deuterium-tritium fusion must contain exactly two product species");
auto& product_species1 = mypc->GetParticleContainerFromName(product_species_name[0]);
auto& product_species2 = mypc->GetParticleContainerFromName(product_species_name[1]);
WARPX_ALWAYS_ASSERT_WITH_MESSAGE(
(product_species1.AmIA<PhysicalSpecies::helium4>() && product_species2.AmIA<PhysicalSpecies::neutron>())
||
(product_species1.AmIA<PhysicalSpecies::neutron>() && product_species2.AmIA<PhysicalSpecies::helium4>()),
"ERROR: Product species of deuterium-tritium fusion must be of type neutron and helium4");
return NuclearFusionType::DeuteriumTritiumToNeutronHelium;
}
else if (species1.AmIA<PhysicalSpecies::hydrogen2>() && species2.AmIA<PhysicalSpecies::hydrogen2>())
{
WARPX_ALWAYS_ASSERT_WITH_MESSAGE(
product_species_name.size() == 2u,
"ERROR: Deuterium-deuterium fusion must contain exactly two product species");
auto& product_species1 = mypc->GetParticleContainerFromName(product_species_name[0]);
auto& product_species2 = mypc->GetParticleContainerFromName(product_species_name[1]);
if (
(product_species1.AmIA<PhysicalSpecies::helium3>() && product_species2.AmIA<PhysicalSpecies::neutron>())
||(product_species1.AmIA<PhysicalSpecies::neutron>() && product_species2.AmIA<PhysicalSpecies::helium3>())){
return NuclearFusionType::DeuteriumDeuteriumToNeutronHelium;
} else if (
(product_species1.AmIA<PhysicalSpecies::hydrogen3>() && product_species2.AmIA<PhysicalSpecies::proton>())
||(product_species1.AmIA<PhysicalSpecies::proton>() && product_species2.AmIA<PhysicalSpecies::hydrogen3>())
||(product_species1.AmIA<PhysicalSpecies::hydrogen3>() && product_species2.AmIA<PhysicalSpecies::hydrogen1>())
||(product_species1.AmIA<PhysicalSpecies::hydrogen1>() && product_species2.AmIA<PhysicalSpecies::hydrogen3>())){
return NuclearFusionType::DeuteriumDeuteriumToProtonTritium;
} else {
WARPX_ABORT_WITH_MESSAGE("ERROR: Product species of deuterium-deuterium fusion must be of type helium3 and neutron, or tritium and proton");
}
}
else if ((species1.AmIA<PhysicalSpecies::hydrogen2>() && species2.AmIA<PhysicalSpecies::helium3>())
||
(species1.AmIA<PhysicalSpecies::helium3>() && species2.AmIA<PhysicalSpecies::hydrogen2>())
)
{
WARPX_ALWAYS_ASSERT_WITH_MESSAGE(
product_species_name.size() == 2u,
"ERROR: Deuterium-helium fusion must contain exactly two product species");
auto& product_species1 = mypc->GetParticleContainerFromName(product_species_name[0]);
auto& product_species2 = mypc->GetParticleContainerFromName(product_species_name[1]);
WARPX_ALWAYS_ASSERT_WITH_MESSAGE(
(product_species1.AmIA<PhysicalSpecies::helium4>() && product_species2.AmIA<PhysicalSpecies::proton>())
||
(product_species1.AmIA<PhysicalSpecies::proton>() && product_species2.AmIA<PhysicalSpecies::helium4>()),
"ERROR: Product species of deuterium-helium fusion must be of type proton and helium4");
return NuclearFusionType::DeuteriumHeliumToProtonHelium;
}
else if ((species1.AmIA<PhysicalSpecies::proton>() && species2.AmIA<PhysicalSpecies::boron11>())
||
(species1.AmIA<PhysicalSpecies::boron11>() && species2.AmIA<PhysicalSpecies::proton>())
)
{
WARPX_ALWAYS_ASSERT_WITH_MESSAGE(
product_species_name.size() == 1,
"ERROR: Proton-boron must contain exactly one product species");
auto& product_species = mypc->GetParticleContainerFromName(product_species_name[0]);
WARPX_ALWAYS_ASSERT_WITH_MESSAGE(
product_species.AmIA<PhysicalSpecies::helium>(),
"ERROR: Product species of proton-boron fusion must be of type alpha");
return NuclearFusionType::ProtonBoronToAlphas;
}
WARPX_ABORT_WITH_MESSAGE("Binary nuclear fusion not implemented between species " +
species_names[0] + " of type " + species1.getSpeciesTypeName() +
" and species " + species_names[1] + " of type " +
species2.getSpeciesTypeName());
return NuclearFusionType::Undefined;
}
CollisionType get_collision_type (const std::string collision_name,
MultiParticleContainer const * const mypc)
{
const amrex::ParmParse pp_collision_name(collision_name);
std::string type;
pp_collision_name.get("type", type);
if (type == "nuclearfusion") {
const NuclearFusionType fusion_type = get_nuclear_fusion_type(collision_name, mypc);
return nuclear_fusion_type_to_collision_type(fusion_type);
}
WARPX_ABORT_WITH_MESSAGE(type + " is not a valid type of collision that creates new particles");
return CollisionType::Undefined;
}
CollisionType nuclear_fusion_type_to_collision_type (const NuclearFusionType fusion_type)
{
if (fusion_type == NuclearFusionType::DeuteriumTritiumToNeutronHelium)
return CollisionType::DeuteriumTritiumToNeutronHeliumFusion;
if (fusion_type == NuclearFusionType::DeuteriumDeuteriumToProtonTritium)
return CollisionType::DeuteriumDeuteriumToProtonTritiumFusion;
if (fusion_type == NuclearFusionType::DeuteriumDeuteriumToNeutronHelium)
return CollisionType::DeuteriumDeuteriumToNeutronHeliumFusion;
if (fusion_type == NuclearFusionType::DeuteriumHeliumToProtonHelium)
return CollisionType::DeuteriumHeliumToProtonHeliumFusion;
if (fusion_type == NuclearFusionType::ProtonBoronToAlphas)
return CollisionType::ProtonBoronToAlphasFusion;
WARPX_ABORT_WITH_MESSAGE("Invalid nuclear fusion type");
return CollisionType::Undefined;
}
}
|