Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
1c46d5c
Add particle rotation in NuclearFusionFunc.H
Yin-YinjianZhao Nov 16, 2021
be57c60
Minor
Yin-YinjianZhao Nov 16, 2021
1fd6f05
indent
Yin-YinjianZhao Nov 16, 2021
5cc92e5
initial work
lucafedeli88 May 4, 2022
fc3334d
fixed bugs and added species
lucafedeli88 May 5, 2022
d744b7a
update documentation
lucafedeli88 May 5, 2022
d768660
delete unused file
lucafedeli88 May 18, 2022
2e5d076
Add properties for neutron, hydrogen isotopes, helium isotopes
RemiLehe May 31, 2022
029f3e1
Update code to be more consistent
RemiLehe May 31, 2022
8ce861d
Correct typo
RemiLehe May 31, 2022
f716fea
Parse deuterium-tritium fusion
RemiLehe May 31, 2022
9763ad3
Start putting in place the files for deuterium-tritium
RemiLehe May 31, 2022
ea3217e
Update documentation
RemiLehe May 31, 2022
c5d067c
Prepare structures for deuterium tritium
RemiLehe May 31, 2022
9549830
Fix typo
RemiLehe May 31, 2022
c0309bd
Merge branch 'more_data' into dt_fusion
RemiLehe Jun 1, 2022
78be34e
Fix compilation
RemiLehe Jun 1, 2022
d6639d6
Add neutron
RemiLehe Jun 2, 2022
24a743d
Merge branch 'development' into improve_SpeciesPhysicalProperties
RemiLehe Jun 2, 2022
c096d29
Merge branch 'development' into improve_SpeciesPhysicalProperties
RemiLehe Jun 2, 2022
08cd304
Add correct formula for the cross-section
RemiLehe Jun 3, 2022
139eebf
Correct compilation error
RemiLehe Jun 3, 2022
c6e7c92
Fix nuclear fusion
RemiLehe Jun 3, 2022
6ab97ec
Reset benchmarks
RemiLehe Jun 3, 2022
6f7e7c0
Prepare creation functor for 2-product fusion
RemiLehe Jun 3, 2022
ff08305
First implementation of momentum initialization
RemiLehe Jun 3, 2022
428a179
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 3, 2022
fa01fdd
Use utility function for fusion
RemiLehe Jun 7, 2022
88fcaf5
Minor modification of variable names
RemiLehe Jun 7, 2022
0a59ecd
Merge branch 'dt_fusion' of github.com:RemiLehe/WarpX into dt_fusion
RemiLehe Jun 7, 2022
821356d
Fix GPU compilation
RemiLehe Jun 7, 2022
ad24117
Fix single precision compilation
RemiLehe Jun 7, 2022
ca278c6
Update types
RemiLehe Jun 8, 2022
2cdd394
Use util function in P-B fusion
RemiLehe Jun 8, 2022
3bc13d4
Correct compilation errors
RemiLehe Jun 8, 2022
eb91623
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 8, 2022
d82bb73
Correct errors
RemiLehe Jun 8, 2022
2a5cc53
Merge branch 'dt_fusion' of github.com:RemiLehe/WarpX into dt_fusion
RemiLehe Jun 8, 2022
323950d
Update values of mass and charge
RemiLehe Jun 9, 2022
61b0769
Correct compilation error
RemiLehe Jun 9, 2022
bbf95b8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 9, 2022
70c5fe6
Correct compilation error
RemiLehe Jun 9, 2022
65409f4
Correct compilation error
RemiLehe Jun 9, 2022
c82c8e7
Correct compilation error
RemiLehe Jun 9, 2022
9510dee
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 9, 2022
2a41771
Reset benchmark
RemiLehe Jun 9, 2022
24d1fc7
Use helium particle in proton-boron, to avoid resetting benchmark
RemiLehe Jun 9, 2022
73c8d9d
Fixed proton-boron test
RemiLehe Jun 10, 2022
5c31035
Revert "Fixed proton-boron test"
RemiLehe Jun 21, 2022
72fb317
Merge branch 'development' into improve_SpeciesPhysicalProperties
RemiLehe Jun 21, 2022
542d2cb
Incorporate Neil's recommendations
RemiLehe Jul 5, 2022
c9a8661
Merge branch 'development' into improve_SpeciesPhysicalProperties
RemiLehe Jul 5, 2022
b228c29
Reset benchmarks
RemiLehe Jul 5, 2022
00e5d09
Merge branch 'improve_SpeciesPhysicalProperties' into dt_fusion
RemiLehe Jul 5, 2022
dd1ca83
Merge branch 'development' into dt_fusion
RemiLehe Jul 5, 2022
665451f
Correct compilation errors
RemiLehe Jul 5, 2022
284f370
Add new deuterium tritium automated test
RemiLehe Jul 11, 2022
c3cff64
Correct formula of cross-section
RemiLehe Jul 11, 2022
67d0ff1
Correct cross-section
RemiLehe Jul 11, 2022
8137f01
Improve analysis script
RemiLehe Jul 11, 2022
637ea1b
Add test of energy conservation
RemiLehe Jul 11, 2022
a163b8a
Merge branch 'development' into dt_fusion
RemiLehe Jul 11, 2022
b11812d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 11, 2022
eb76522
Add test of conservation of momentum
RemiLehe Jul 11, 2022
a61aef3
Progress in analysis script
RemiLehe Jul 11, 2022
5b6585d
Merge branch 'dt_fusion' of github.com:RemiLehe/WarpX into dt_fusion
RemiLehe Jul 11, 2022
d1bd322
Fix error in the initial energy of the deuterium particles
RemiLehe Jul 12, 2022
e29d5ab
Add check of isotropy
RemiLehe Jul 12, 2022
a117150
Clean up the test script
RemiLehe Jul 12, 2022
e787250
Rewrite p_sq formula in a way to avoids machine-precision negative nu…
RemiLehe Jul 12, 2022
b45e99d
Add checksum
RemiLehe Jul 12, 2022
471e263
Clean up code
RemiLehe Jul 12, 2022
4d19e2b
Add test for fusion in RZ geometry
RemiLehe Jul 12, 2022
010c6cc
Update code to take into account actual timestep
RemiLehe Jul 14, 2022
e41378d
Update RZ test
RemiLehe Jul 14, 2022
042b5f5
Update RZ test
RemiLehe Jul 14, 2022
8f8afd8
Increase number of particles
RemiLehe Jul 14, 2022
00055ae
Impart radial memory on DT particles
RemiLehe Jul 14, 2022
a003d5c
Correct RZ momenta
RemiLehe Jul 14, 2022
51190a0
Merge branch 'dt_rz_test' of github.com:RemiLehe/WarpX into dt_rz_test
RemiLehe Jul 14, 2022
7d188b4
Merge branch 'collision_fusion' into dt_rz_test
RemiLehe Jul 14, 2022
c2529a3
Merge branch 'development' into dt_rz_test
RemiLehe Jul 24, 2022
27994fc
Remove unused file
RemiLehe Jul 24, 2022
e85d2c5
Update test
RemiLehe Sep 7, 2022
f1994ea
Fix definition of theta
RemiLehe Sep 16, 2022
422586b
Add new test
RemiLehe Sep 16, 2022
337b2ed
Add checksum
RemiLehe Sep 19, 2022
70a864e
Update test
RemiLehe Sep 19, 2022
55ad0e0
Update tests
RemiLehe Sep 20, 2022
54ca811
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 20, 2022
65b43eb
Fix Python analysis script
RemiLehe Sep 20, 2022
d399ac2
Remove CPU and ID from new benchmark
RemiLehe Sep 20, 2022
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
# License: BSD-3-Clause-LBNL

import os
import re
import sys

import yt
Expand Down Expand Up @@ -66,15 +67,30 @@

E_fusion = 17.5893*MeV_to_Joule # Energy released during the fusion reaction

## Checks whether this is the 2D or the 3D test
warpx_used_inputs = open('./warpx_used_inputs', 'r').read()
if re.search('geometry.dims = RZ', warpx_used_inputs):
is_RZ = True
else:
is_RZ = False

## Some numerical parameters for this test
size_x = 8
size_y = 8
size_z = 16
dV_total = size_x*size_y*size_z # Total simulation volume
if is_RZ:
dV_slice = np.pi * size_x**2
yt_z_string = "particle_position_y"
nppcell_1 = 10000*8
nppcell_2 = 900*8
else:
dV_slice = size_x*size_y
yt_z_string = "particle_position_z"
nppcell_1 = 10000
nppcell_2 = 900
# Volume of a slice corresponding to a single cell in the z direction. In tests 1 and 2, all the
# particles of a given species in the same slice have the exact same momentum
dV_slice = size_x*size_y
dt = 1./(scc.c*np.sqrt(3.))

# In test 1 and 2, the energy in cells number i (in z direction) is typically Energy_step * i**2
Energy_step = 22.*keV_to_Joule

Expand All @@ -89,7 +105,7 @@ def add_existing_species_to_dict(yt_ad, data_dict, species_name, prefix, suffix)
data_dict[prefix+"_w_"+suffix] = yt_ad[species_name, "particle_weight"].v
data_dict[prefix+"_id_"+suffix] = yt_ad[species_name, "particle_id"].v
data_dict[prefix+"_cpu_"+suffix] = yt_ad[species_name, "particle_cpu"].v
data_dict[prefix+"_z_"+suffix] = yt_ad[species_name, "particle_position_z"].v
data_dict[prefix+"_z_"+suffix] = yt_ad[species_name, yt_z_string].v

def add_empty_species_to_dict(data_dict, species_name, prefix, suffix):
data_dict[prefix+"_px_"+suffix] = np.empty(0)
Expand Down Expand Up @@ -263,8 +279,11 @@ def expected_weight_com(E_com, reactant0_density, reactant1_density, dV, dt):
def check_macroparticle_number(data, fusion_probability_target_value, num_pair_per_cell):
## Checks that the number of macroparticles is as expected for the first and second tests

## The first slice 0 < z < 1 does not contribute to product species creation
numcells = dV_total - dV_slice
## The first slice 0 < z < 1 does not contribute to alpha creation
if is_RZ:
numcells = size_x*(size_z-1)
else:
numcells = size_x*size_y*(size_z-1)
## In these tests, the fusion_multiplier is so high that the fusion probability per pair is
## equal to the parameter fusion_probability_target_value
fusion_probability_per_pair = fusion_probability_target_value
Expand Down Expand Up @@ -315,7 +334,7 @@ def compute_E_com2(data):
p_reactant0_sq = 2.*mass[reactant_species[0]]*(Energy_step*np.arange(size_z)**2)
return p_sq_reactant1_frame_to_E_COM_frame(p_reactant0_sq)

def check_fusion_yield(data, expected_fusion_number, E_com, reactant0_density, reactant1_density):
def check_fusion_yield(data, expected_fusion_number, E_com, reactant0_density, reactant1_density, dt):
## Checks that the fusion yield is as expected for the first and second tests.
product_weight_theory = expected_weight_com(E_com/keV_to_Joule,
reactant0_density, reactant1_density, dV_slice, dt)
Expand All @@ -330,24 +349,25 @@ def check_fusion_yield(data, expected_fusion_number, E_com, reactant0_density, r
assert(np.all(is_close(product_weight_theory, product_weight_simulation,
rtol = 5.*relative_std_weight)))

def specific_check1(data):
check_isotropy(data, relative_tolerance = 3.e-2)
def specific_check1(data, dt):
if not is_RZ:
check_isotropy(data, relative_tolerance = 3.e-2)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't check for isotropy in the RZ case, since the distribution of momentum for the products is not yet correct.

expected_fusion_number = check_macroparticle_number(data,
fusion_probability_target_value = 0.002,
num_pair_per_cell = 10000)
num_pair_per_cell = nppcell_1)
E_com = compute_E_com1(data)
check_fusion_yield(data, expected_fusion_number, E_com, reactant0_density = 1.,
reactant1_density = 1.)
reactant1_density = 1., dt=dt)

def specific_check2(data):
def specific_check2(data, dt):
check_xy_isotropy(data)
## Only 900 particles pairs per cell here because we ignore the 10% of reactants that are at rest
expected_fusion_number = check_macroparticle_number(data,
fusion_probability_target_value = 0.02,
num_pair_per_cell = 900)
num_pair_per_cell = nppcell_2)
E_com = compute_E_com2(data)
check_fusion_yield(data, expected_fusion_number, E_com, reactant0_density = 1.e20,
reactant1_density = 1.e26)
reactant1_density = 1.e26, dt=dt)

def check_charge_conservation(rho_start, rho_end):
assert(np.all(is_close(rho_start, rho_end, rtol=2.e-11)))
Expand All @@ -359,6 +379,7 @@ def main():
ds_start = yt.load(filename_start)
ad_end = ds_end.all_data()
ad_start = ds_start.all_data()
dt = float(ds_end.current_time - ds_start.current_time)
field_data_end = ds_end.covering_grid(level=0, left_edge=ds_end.domain_left_edge,
dims=ds_end.domain_dimensions)
field_data_start = ds_start.covering_grid(level=0, left_edge=ds_start.domain_left_edge,
Expand All @@ -379,7 +400,7 @@ def main():
generic_check(data)

# Checks that are specific to test number i
eval("specific_check"+str(i)+"(data)")
eval("specific_check"+str(i)+"(data, dt)")

rho_start = field_data_start["rho"].to_ndarray()
rho_end = field_data_end["rho"].to_ndarray()
Expand Down
129 changes: 129 additions & 0 deletions Examples/Modules/nuclear_fusion/inputs_deuterium_tritium_rz
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#################################
####### GENERAL PARAMETERS ######
#################################
## With these parameters, each cell has a size of exactly 1 by 1 by 1
max_step = 1
amr.n_cell = 8 16
amr.max_grid_size = 8
amr.blocking_factor = 8
amr.max_level = 0
geometry.dims = RZ
geometry.prob_lo = 0. 0.
geometry.prob_hi = 8. 16.

#################################
###### Boundary Condition #######
#################################
boundary.field_lo = none periodic
boundary.field_hi = pec periodic

#################################
############ NUMERICS ###########
#################################
warpx.verbose = 1
warpx.cfl = 1.0

# Order of particle shape factors
algo.particle_shape = 1

#################################
############ PLASMA #############
#################################
particles.species_names = deuterium1 tritium1 helium1 neutron1 deuterium2 tritium2 helium2 neutron2

my_constants.m_deuterium = 2.01410177812*m_u
my_constants.m_tritium = 3.0160492779*m_u
my_constants.m_reduced = m_deuterium*m_tritium/(m_deuterium+m_tritium)
my_constants.keV_to_J = 1.e3*q_e
my_constants.Energy_step = 22. * keV_to_J

deuterium1.species_type = deuterium
deuterium1.injection_style = "NRandomPerCell"
deuterium1.num_particles_per_cell = 80000
deuterium1.profile = constant
deuterium1.density = 1.
deuterium1.momentum_distribution_type = parse_momentum_function
## Thanks to the floor, all particles in the same cell have the exact same momentum
deuterium1.momentum_function_ux(x,y,z) = "u = sqrt(2*m_reduced*Energy_step*(floor(z)**2))/(m_deuterium*clight); if(x*x+y*y>0.0, -u*y/sqrt(x*x+y*y), 0.0)" # azimuthal velocity
deuterium1.momentum_function_uy(x,y,z) = "u = sqrt(2*m_reduced*Energy_step*(floor(z)**2))/(m_deuterium*clight); if(x*x+y*y>0.0, u*x/sqrt(x*x+y*y), 0.0)" # azimuthal velocity
deuterium1.momentum_function_uz(x,y,z) = "0"
deuterium1.do_not_push = 1
deuterium1.do_not_deposit = 1

tritium1.species_type = tritium
tritium1.injection_style = "NRandomPerCell"
tritium1.num_particles_per_cell = 80000
tritium1.profile = constant
tritium1.density = 1.
tritium1.momentum_distribution_type = "parse_momentum_function"
## Thanks to the floor, all particles in the same cell have the exact same momentum
tritium1.momentum_function_ux(x,y,z) = "u = sqrt(2*m_reduced*Energy_step*(floor(z)**2))/(m_tritium*clight); if(x*x+y*y>0.0, u*y/sqrt(x*x+y*y), 0.0)" # counter-streaming azimuthal velocity
tritium1.momentum_function_uy(x,y,z) = "u = sqrt(2*m_reduced*Energy_step*(floor(z)**2))/(m_tritium*clight); if(x*x+y*y>0.0, -u*x/sqrt(x*x+y*y), 0.0)" # counter-streaming azimuthal velocity
tritium1.momentum_function_uz(x,y,z) = 0
tritium1.do_not_push = 1
tritium1.do_not_deposit = 1

helium1.species_type = helium4
helium1.do_not_push = 1
helium1.do_not_deposit = 1

neutron1.species_type = neutron
neutron1.do_not_push = 1
neutron1.do_not_deposit = 1

my_constants.background_dens = 1.e26
my_constants.beam_dens = 1.e20

deuterium2.species_type = deuterium
deuterium2.injection_style = "NRandomPerCell"
deuterium2.num_particles_per_cell = 8000
deuterium2.profile = "parse_density_function"
## A tenth of the macroparticles in each cell is made of immobile high-density background deuteriums.
## The other nine tenths are made of fast low-density beam deuteriums.
deuterium2.density_function(x,y,z) = if(y - floor(y) < 0.1, 10.*background_dens, 10./9.*beam_dens)
deuterium2.momentum_distribution_type = "parse_momentum_function"
deuterium2.momentum_function_ux(x,y,z) = 0.
deuterium2.momentum_function_uy(x,y,z) = 0.
deuterium2.momentum_function_uz(x,y,z) = "if(y - floor(y) < 0.1,
0., sqrt(2*m_deuterium*Energy_step*(floor(z)**2))/(m_deuterium*clight))"
deuterium2.do_not_push = 1
deuterium2.do_not_deposit = 1

tritium2.species_type = tritium
tritium2.injection_style = "NRandomPerCell"
tritium2.num_particles_per_cell = 800
tritium2.profile = constant
tritium2.density = background_dens
tritium2.momentum_distribution_type = "constant"
tritium2.do_not_push = 1
tritium2.do_not_deposit = 1

helium2.species_type = helium4
helium2.do_not_push = 1
helium2.do_not_deposit = 1

neutron2.species_type = neutron
neutron2.do_not_push = 1
neutron2.do_not_deposit = 1

#################################
############ COLLISION ##########
#################################
collisions.collision_names = DTF1 DTF2

DTF1.species = deuterium1 tritium1
DTF1.product_species = helium1 neutron1
DTF1.type = nuclearfusion
DTF1.fusion_multiplier = 1.e50

DTF2.species = deuterium2 tritium2
DTF2.product_species = helium2 neutron2
DTF2.type = nuclearfusion
DTF2.fusion_multiplier = 1.e15
DTF2.fusion_probability_target_value = 0.02

# Diagnostics
diagnostics.diags_names = diag1
diag1.intervals = 1
diag1.diag_type = Full
diag1.fields_to_plot = rho
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,4 @@
"particle_position_z": 819255.8152412223,
"particle_weight": 1.0239999999424347e+29
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
{
"deuterium1": {
"particle_momentum_x": 1.8388106511899905e-13,
"particle_momentum_y": 1.837868790009435e-13,
"particle_momentum_z": 0.0,
"particle_position_x": 40959919.499819286,
"particle_position_y": 81919224.48541151,
"particle_theta": 32166860.23003994,
"particle_weight": 3216.984554806547
},
"deuterium2": {
"particle_momentum_x": 0.0,
"particle_momentum_y": 0.0,
"particle_momentum_z": 3.336364094249911e-14,
"particle_position_x": 4095908.9083809257,
"particle_position_y": 8192069.080030457,
"particle_theta": 3216444.348910214,
"particle_weight": 3.1898417901971444e+29
},
"helium1": {
"particle_momentum_x": 1.858124399143442e-15,
"particle_momentum_y": 1.876715110797694e-15,
"particle_momentum_z": 1.7098432207359157e-15,
"particle_position_x": 152920.23233108618,
"particle_position_y": 323733.9138644398,
"particle_theta": 120064.13771707338,
"particle_weight": 1.603083276067953e-27
},
"helium2": {
"particle_momentum_x": 1.5195006688950936e-15,
"particle_momentum_y": 1.52430083815551e-15,
"particle_momentum_z": 1.7654865863613367e-15,
"particle_position_x": 136867.63803188328,
"particle_position_y": 286903.30393175944,
"particle_theta": 107912.20520382549,
"particle_weight": 2.0862696876352987e+19
},
"lev=0": {
"rho": 0.0
},
"neutron1": {
"particle_momentum_x": 1.7160671487712845e-15,
"particle_momentum_y": 1.7154753069055672e-15,
"particle_momentum_z": 1.7098432207359157e-15,
"particle_position_x": 152920.23233108618,
"particle_position_y": 323733.9138644398,
"particle_theta": 120064.13771707338,
"particle_weight": 1.603083276067953e-27
},
"neutron2": {
"particle_momentum_x": 1.5195006688950936e-15,
"particle_momentum_y": 1.52430083815551e-15,
"particle_momentum_z": 1.5463311225724366e-15,
"particle_position_x": 136867.63803188328,
"particle_position_y": 286903.30393175944,
"particle_theta": 107912.20520382549,
"particle_weight": 2.0862696876352987e+19
},
"tritium1": {
"particle_momentum_x": 1.8384658063720362e-13,
"particle_momentum_y": 1.8381593257898129e-13,
"particle_momentum_z": 0.0,
"particle_position_x": 40961278.052658774,
"particle_position_y": 81919046.8061561,
"particle_theta": 32163925.891884565,
"particle_weight": 3217.0912552970394
},
"tritium2": {
"particle_momentum_x": 0.0,
"particle_momentum_y": 0.0,
"particle_momentum_z": 0.0,
"particle_position_x": 409793.9651940968,
"particle_position_y": 819237.3558155322,
"particle_theta": 321974.4557387621,
"particle_weight": 3.218514276139388e+29
}
}
16 changes: 16 additions & 0 deletions Regression/WarpX-tests.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2216,6 +2216,22 @@ compileTest = 0
doVis = 0
analysisRoutine = Examples/Modules/nuclear_fusion/analysis_deuterium_tritium_fusion.py

[Deuterium_Tritium_Fusion_RZ]
buildDir = .
inputFile = Examples/Modules/nuclear_fusion/inputs_deuterium_tritium_rz
runtime_params = warpx.do_dynamic_scheduling=0 warpx.serialize_initial_conditions=1
dim = 2
addToCompileString = USE_RZ=TRUE
cmakeSetupOpts = -DWarpX_DIMS=RZ
restartTest = 0
useMPI = 1
numprocs = 2
useOMP = 1
numthreads = 1
compileTest = 0
doVis = 0
analysisRoutine = Examples/Modules/nuclear_fusion/analysis_deuterium_tritium_fusion.py

[Maxwell_Hybrid_QED_solver]
buildDir = .
inputFile = Examples/Tests/Maxwell_Hybrid_QED/inputs_2d
Expand Down
Loading