Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,5 @@ If you want to skip the porting part, you can directly start from the `src/kokko
## Publications

- SILVA-CUEVAS, J. J., ZYCH, M., PEYEN, K., et al. Towards a complete task-based implementation of a 3D Particle-In-Cell code: performance studies and benchmarks. Computer Physics Communications, 2025, p. 109647. https://doi.org/10.1016/j.cpc.2025.109647

- KHOURY, E. E., LOBET, M., COLOMBET, L., BIGOT, J., PEYEN, K., SILVA-CUEVAS, J. J. Exploring C++ standard parallelism for GPU programming in a particle-in-cell application (preprint). 2025. HAL: [hal-05316488](https://hal.science/hal-05316488) — PDF: [HeteroPar_EuroPar.pdf](https://hal.science/hal-05316488v1/file/HeteroPar_EuroPar.pdf)
18 changes: 18 additions & 0 deletions doc/python_tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,24 @@ Note you have to source the activation script if you are in a new terminal (and

</details>

<details>

<summary>
And also with conda:
</summary>

```sh
conda create -n minipic python=<x.y> pip -c conda-forge
conda activate minipic
```

with `<x.y>` the version of Python.
By instance, `python3.12`.
Note you have to source the activation script if you are in a new terminal (and in a Slurm job).

</details>


## `mini-run` command

The `mini-run` command is used to build (mini)miniPIC for a selection of setups, to execute it and to validate its results.
Expand Down
3 changes: 2 additions & 1 deletion libminipic/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,12 +476,13 @@ def run():
bench_dir,
"--setup",
setup,
"--no-evaluate" if not evaluate else "",
"--threshold",
threshold,
]
)

validate_setup(bench_dir, setup, threshold)
validate_setup(bench_dir, setup=setup, evaluate=evaluate, threshold=threshold)

# ____________________________________________________________________________
# Read timers (json format)
Expand Down
2 changes: 2 additions & 0 deletions libminipic/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ def validate_setup(path, setup=None, evaluate=True, threshold=THRESHOLD):
if not os.path.isdir("diags"):
raise MissingFileMiniPICError(f"Directory diags is not in {path}")

print(evaluate, threshold)

module.validate(evaluate=evaluate, threshold=threshold)

print_success(f"Setup {setup} tested with success")
Expand Down
141 changes: 86 additions & 55 deletions libminipic/validation/antenna.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@

def validate(evaluate=True, threshold=THRESHOLD):

# Get the name of the current file (without extension) to use as a label for the validation
validation_label = os.path.basename(__file__).split(".")[0]

# ______________________________________________________________________
# Check output files are created

Expand All @@ -33,25 +36,74 @@ def validate(evaluate=True, threshold=THRESHOLD):
if not (os.path.exists("diags/" + file)):
raise MissingFileMiniPICError(f"File {file} not generated")

# ______________________________________________________________________
# Reference database

references = {
"fields_final": [
600,
8.392314275494247e-06,
7.685688704219648e-08,
9.162999693074787e-04,
8.581201889410053e-06,
9.523643303672555e-04,
1.993340067202490e-34,
0.000000000000000e00,
0.000000000000000e00,
1.877328812863773e-37,
],
"fields_3d": {
"Ex": [
0.0,
82.16528908415819,
344.34858930166956,
590.8495077993598,
557.1785762453475,
835.1262141764287,
],
"Ey": [
0.0,
9.971267188545653,
38.4454341611614,
65.35670493378103,
59.67453062284768,
76.50264530492844,
],
"Ez": [
0.0,
774.7241409632107,
3237.01821064664,
5666.167748229646,
6216.341002673892,
9765.210440891475,
],
"Bx": [
0.0,
86.91713443298572,
355.1215926140225,
614.3956604220939,
634.2442079543871,
881.1441186493583,
],
"By": [
0.0,
784.3391276892934,
3246.3762073832377,
5627.157839639507,
6428.848152848923,
9793.622315394427,
],
},
}

# ______________________________________________________________________
# Check scalars

print(" > Check scalars")

# Check final scalar values for fields

reference_data = [
600,
8.392314275494247e-06,
7.685688704219648e-08,
9.162999693074787e-04,
8.581201889410053e-06,
9.523643303672555e-04,
1.993340067202490e-34,
0.000000000000000e00,
0.000000000000000e00,
1.877328812863773e-37,
]
reference_data = references["fields_final"]

with open("diags/fields.txt", "r") as f:
lines = f.readlines()
Expand Down Expand Up @@ -112,55 +164,15 @@ def validate(evaluate=True, threshold=THRESHOLD):
"By value in fields.txt is not correct",
)
# minipic_ci.evaluate(Bz, reference_data[6], 1e-2, 'relative', 'Bz value in fields.txt is not correct') ===> too small to be relevant
else:
references["fields_final"] = [iteration, Ex, Ey, Ez, Bx, By, Bz]

# ______________________________________________________________________
# Check field

print(" > Check fields")

reference_data = {
"Ex": [
0.0,
82.16528908415819,
344.34858930166956,
590.8495077993598,
557.1785762453475,
835.1262141764287,
],
"Ey": [
0.0,
9.971267188545653,
38.4454341611614,
65.35670493378103,
59.67453062284768,
76.50264530492844,
],
"Ez": [
0.0,
774.7241409632107,
3237.01821064664,
5666.167748229646,
6216.341002673892,
9765.210440891475,
],
"Bx": [
0.0,
86.91713443298572,
355.1215926140225,
614.3956604220939,
634.2442079543871,
881.1441186493583,
],
"By": [
0.0,
784.3391276892934,
3246.3762073832377,
5627.157839639507,
6428.848152848923,
9793.622315394427,
],
# 'Bz' : [0.0, 8.68335830083499e-14, 8.109979554106818e-13, 2.2881775959027207e-12, 3.4172712318143877e-12, 4.161059825829489e-12]
}
reference_data = references["fields_3d"]

for field in reference_data.keys():

Expand Down Expand Up @@ -198,3 +210,22 @@ def validate(evaluate=True, threshold=THRESHOLD):
"relative",
"{} field not similar".format(field),
)
else:
references["fields_3d"][field] = new_data

# ______________________________________________________________________
# Write updated references to JSON file if not evaluating

if not evaluate:

import json

json_file_name = validation_label

with open(json_file_name, "w") as f:
json.dump(references, f, indent=4)
print(f" > New references written to {json_file_name}")

print(
" > New references: \n {}".format(json.dumps(references, indent=4))
)
95 changes: 63 additions & 32 deletions libminipic/validation/antenna_heavy.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@

def validate(evaluate=True, threshold=THRESHOLD):

# Get the name of the current file (without extension) to use as a label for the validation
validation_label = os.path.basename(__file__).split(".")[0]

# ______________________________________________________________________
# Check output files are created

Expand All @@ -33,22 +36,51 @@ def validate(evaluate=True, threshold=THRESHOLD):
if not (os.path.exists("diags/" + file)):
raise MissingFileMiniPICError(f"File {file} not generated")

# ______________________________________________________________________
# Reference database

references = {
"fields_final": [
200,
1.178332626270596e-08,
1.121385881385788e-10,
1.372260141937414e-06,
1.217329509377536e-08,
1.397861526161067e-06,
5.139203602251246e-39,
],
"fields_3d": {
"Ex": [
0.0,
78.55592092043187,
],
"Ey": [
0.0,
9.5656799728717190,
],
"Ez": [
0.0,
748.3567468708843,
],
"Bx": [
0.0,
80.94553055070384,
],
"By": [
0.0,
754.12940596242360,
],
},
}

# ______________________________________________________________________
# Check scalars

print(" > Check scalars")

# Check final scalar values for fields

reference_data = [
200,
1.178332626270596e-08,
1.121385881385788e-10,
1.372260141937414e-06,
1.217329509377536e-08,
1.397861526161067e-06,
5.139203602251246e-39,
]
reference_data = references["fields_final"]

with open("diags/fields.txt", "r") as f:
lines = f.readlines()
Expand Down Expand Up @@ -109,35 +141,15 @@ def validate(evaluate=True, threshold=THRESHOLD):
"By value in fields.txt is not correct",
)
# minipic_ci.evaluate(Bz, reference_data[6], 1e-2, 'relative', 'Bz value in fields.txt is not correct') ===> too small to be relevant
else:
references["fields_final"] = [iteration, Ex, Ey, Ez, Bx, By, Bz]

# ______________________________________________________________________
# Check field

print(" > Check fields")

reference_data = {
"Ex": [
0.0,
78.55592092043187,
],
"Ey": [
0.0,
9.5656799728717190,
],
"Ez": [
0.0,
748.3567468708843,
],
"Bx": [
0.0,
80.94553055070384,
],
"By": [
0.0,
754.12940596242360,
],
# 'Bz' : [0.0, 8.68335830083499e-14, 8.109979554106818e-13, 2.2881775959027207e-12, 3.4172712318143877e-12, 4.161059825829489e-12]
}
reference_data = references["fields_3d"]

for field in reference_data.keys():

Expand Down Expand Up @@ -178,3 +190,22 @@ def validate(evaluate=True, threshold=THRESHOLD):
"relative",
"{} field not similar".format(field),
)
else:
references["fields_3d"][field] = new_data

# ______________________________________________________________________
# Write updated references to JSON file if not evaluating

if not evaluate:
import json

json_file_name = validation_label

with open(json_file_name, "w") as f:
json.dump(references, f, indent=4)
print(f" > New references written to {json_file_name}")

print(
" > New references: \n {}".format(json.dumps(references, indent=4))
)

Loading