-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
3d C++ / python #591
base: master
Are you sure you want to change the base?
3d C++ / python #591
Conversation
4bcae8e
to
84dd60a
Compare
eb507bb
to
c963ec0
Compare
7bb1041
to
263ecd6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 28
Outside diff range and nitpick comments (61)
tools/python3/git.py (2)
Line range hint
22-22
: Remove unused variable.The variable
e
is assigned but never used, which is unnecessary and can be removed for cleaner code.- except subprocess.CalledProcessError as e: + except subprocess.CalledProcessError:
Line range hint
29-29
: Undefined functiondelete_branch
.The function
delete_branch
is called but not defined anywhere in the provided code. This will cause a runtime error.+ def delete_branch(branch): + run(f"git branch -D {branch}")tests/simulator/initialize/test_particles_init_1d.py (2)
Line range hint
33-35
: Remove extraneous parentheses around single items in tuples.The parentheses around the single items in the tuples are unnecessary and can be removed for cleaner code.
- *per_interp(({"L0": {"B0": Box1D(10, 14)}})), - *per_interp(({"L0": {"B0": Box1D(5, 20)}, "L1": {"B0": Box1D(15, 35)}})), - *per_interp(({"L0": {"B0": Box1D(2, 12), "B1": Box1D(13, 25)}})), + *per_interp({"L0": {"B0": Box1D(10, 14)}}), + *per_interp({"L0": {"B0": Box1D(5, 20)}, "L1": {"B0": Box1D(15, 35)}}), + *per_interp({"L0": {"B0": Box1D(2, 12), "B1": Box1D(13, 25)}}),
Line range hint
54-56
: Remove extraneous parentheses around single items in tuples.Similar to previous comments, remove unnecessary parentheses to improve code readability.
- *per_interp(({"L0": {"B0": Box1D(10, 14)}})), - *per_interp(({"L0": {"B0": Box1D(5, 20)}, "L1": {"B0": Box1D(15, 35)}})), - *per_interp(({"L0": {"B0": Box1D(2, 12), "B1": Box1D(13, 25)}})), + *per_interp({"L0": {"B0": Box1D(10, 14)}}), + *per_interp({"L0": {"B0": Box1D(5, 20)}, "L1": {"B0": Box1D(15, 35)}}), + *per_interp({"L0": {"B0": Box1D(2, 12), "B1": Box1D(13, 25)}}),tests/simulator/initialize/test_particles_init_2d.py (2)
Line range hint
33-35
: Remove extraneous parentheses around single items in tuples.The parentheses around the single items in the tuples are unnecessary and can be removed for cleaner code.
- *per_interp(({"L0": {"B0": Box2D(10, 14)}})), - *per_interp(({"L0": {"B0": Box2D(10, 14)}, "L1": {"B0": Box2D(22, 26)}})), - *per_interp(({"L0": {"B0": Box2D(2, 6), "B1": Box2D(7, 11)}})), + *per_interp({"L0": {"B0": Box2D(10, 14)}}), + *per_interp({"L0": {"B0": Box2D(10, 14)}, "L1": {"B0": Box2D(22, 26)}}), + *per_interp({"L0": {"B0": Box2D(2, 6), "B1": Box2D(7, 11)}}),
Line range hint
58-60
: Remove extraneous parentheses around single items in tuples.Similar to previous comments, remove unnecessary parentheses to improve code readability.
- *per_interp(({"L0": {"B0": Box2D(10, 14)}})), - *per_interp(({"L0": {"B0": Box2D(5, 20)}, "L1": {"B0": Box2D(15, 35)}})), - *per_interp(({"L0": {"B0": Box2D(2, 12), "B1": Box2D(13, 25)}})), + *per_interp({"L0": {"B0": Box2D(10, 14)}}), + *per_interp({"L0": {"B0": Box2D(5, 20)}, "L1": {"B0": Box2D(15, 35)}}), + *per_interp({"L0": {"B0": Box2D(2, 12), "B1": Box2D(13, 25)}}),src/core/utilities/meta/meta_utilities.hpp (1)
83-97
: Review the conditional compilation logic for simulator options.The conditional compilation blocks for 2D and 3D simulator options are well-structured. However, consider adding further comments or documentation to describe the scenarios under which these blocks are activated, especially for maintainability and clarity for new contributors.
src/amr/data/particles/refine/split_3d.hpp (1)
90-115
: Ensure extensibility inWhitePattern
.The
WhitePattern
class template handles complex particle splitting with multiple dimensions. Ensure that the class design allows for easy extension or modification to support future requirements such as additional dimensions or different splitting strategies.src/amr/data/particles/refine/split_2d.hpp (1)
247-247
: Suggestion for adding documentation in Splitter constructors.Each
Splitter
constructor initializes its base class with specific weights and deltas. It would be helpful for maintainability to add inline comments explaining the choice of these values, especially since they are critical for the simulation accuracy.pyphare/pyphare/core/gridlayout.py (2)
Line range hint
152-155
: Simplify expression using ternary operator.The
if-else
block in theyeeCoordsFor
function can be simplified using a ternary operator for better readability.- if withGhosts: - size = nbrCells[dim] + (nbrGhosts * 2) - else: - size = nbrCells[dim] + size = nbrCells[dim] + (nbrGhosts * 2) if withGhosts else nbrCells[dim]
Line range hint
131-131
: Remove unnecessary inheritance fromobject
.Both
YeeCentering
andGridLayout
classes inherit fromobject
, which is redundant in Python 3 and can be removed for cleaner code.- class YeeCentering(object): + class YeeCentering: - class GridLayout(object): + class GridLayout:Also applies to: 168-168
pyphare/pyphare/pharesee/run.py (3)
Line range hint
289-289
: Convert to f-string for consistency and readability.The use of the
format
method can be replaced with f-strings for better readability and consistency with modern Python practices.- t = "{:.10f}".format(time) + t = f"{time:.10f}" - def filename(name): - return f"ions_pop_{name}_domain.h5" + def filename(name): + return f"ions_pop_{name}_domain.h5"Also applies to: 415-415
Line range hint
371-371
: Remove unnecessary f-string prefixes.There are f-string prefixes used without any placeholders, which should be removed for cleaner code.
- h5_time_grp_key = "t" + h5_time_grp_key = "t" - h5_filename = "EM_B.h5" # _____ TODO : could be another file + h5_filename = "EM_B.h5" # _____ TODO : could be another fileAlso applies to: 373-373
Line range hint
465-465
: Avoid mutable default arguments in function definitions.Using mutable default structures like lists as default arguments can lead to unexpected behaviors. It's safer to use
None
and initialize within the function.- def GetAllAvailableQties(self, time=0, pops=[]): + def GetAllAvailableQties(self, time=0, pops=None): + if pops is None: + pops = []pyphare/pyphare/pharesee/geometry.py (3)
Line range hint
86-187
: Optimize the initialization and update of theshifts
dictionary.The initialization and updates of the
shifts
dictionary are spread across multiple conditional blocks, which can be optimized for better readability and efficiency. Consider consolidating the initialization and conditional updates into a single block or function. Also, ensure that the variable names are clear, asl
is ambiguous and could be renamed for clarity.- shifts = {} - if domain_box.ndim == 1: - ... - if domain_box.ndim == 2: - ... - if domain_box.ndim == 3: - ... + shifts = initialize_shifts(domain_box) def initialize_shifts(domain_box): shifts = {} if domain_box.ndim == 1: ... elif domain_box.ndim == 2: ... elif domain_box.ndim == 3: ... return shifts- f"{k}front": [(v[0], v[1], shape_z) for v in l] for k, l in shifts.items() + f"{k}front": [(v[0], v[1], shape_z) for v in values] for k, values in shifts.items()Tools
Ruff
160-160: Ambiguous variable name:
l
(E741)
163-163: Ambiguous variable name:
l
(E741)
166-166: Ambiguous variable name:
l
(E741)
187-187: Ambiguous variable name:
l
(E741)
Line range hint
418-418
: Avoid using mutable default arguments in function definitions.Using mutable objects like lists or dictionaries as default arguments in function definitions can lead to unexpected behavior if the function modifies the default object. Replace mutable default arguments with
None
and initialize them within the function.- def some_function(arg={}): + def some_function(arg=None): + if arg is None: + arg = {}Also applies to: 464-464
Line range hint
441-441
: Remove or rename unused loop control variable.The variable
pd
is not used within the loop body, which could be a sign of an error or unnecessary code. If it's not needed, consider removing it or replacing it with_
to indicate it's intentionally unused.- for pd_key, pd in patch.patch_datas.items(): + for pd_key, _ in patch.patch_datas.items():tests/simulator/test_initialization.py (4)
Line range hint
5-23
: Reorganize module-level imports to the top of the file.The imports should be placed at the top of the file for better readability and to adhere to Python's convention. This will also resolve multiple E402 lint errors.
+ from pyphare.cpp import cpp_lib + cpp = cpp_lib() + import unittest + import numpy as np + from ddt import ddt + from pyphare.core.box import nDBox + from pyphare.core.phare_utilities import assert_fp_any_all_close + from pyphare.pharein import ElectronModel, MaxwellianFluidModel + from pyphare.pharein.diagnostics import ( + ElectromagDiagnostics, + FluidDiagnostics, + ParticleDiagnostics, + ) + from pyphare.pharein.simulation import Simulation + from pyphare.pharesee.geometry import level_ghost_boxes + from pyphare.pharesee.hierarchy import hierarchy_from, merge_particles + from pyphare.pharesee.particles import aggregate as aggregate_particles + from pyphare.simulator.simulator import Simulator + from tests.simulator import SimulatorTest
Line range hint
32-32
: Convert lambda expressions to function definitions.Using lambda expressions for simple calculations is fine, but assigning them to variables is not recommended as it reduces readability and debuggability. Convert these lambda expressions to proper function definitions.
- _ = lambda i: -((xyz[i] - hL[i]) ** 2) + def calculate_expression(i, xyz, hL): + return -((xyz[i] - hL[i]) ** 2)Apply similar changes for all the lambda expressions assigned to
_
.Also applies to: 93-93, 98-98, 103-103, 108-108, 113-113
Line range hint
44-44
: Avoid using mutable default arguments.Using a mutable default argument like a dictionary can lead to unexpected behavior if the function modifies the argument. Use
None
as the default and set it inside the function.- def getHierarchy(self, ..., extra_diag_options={}): + def getHierarchy(self, ..., extra_diag_options=None): + if extra_diag_options is None: + extra_diag_options = {}
Line range hint
315-317
: Replace list comprehensions with generator expressions where applicable.Using a generator expression can be more memory efficient than a list comprehension when the result is immediately consumed by functions like
all()
.- xbx, ybx, zbx = [a.flatten() for a in np.meshgrid(xbx, ybx, zbx, indexing="ij")] + xbx, ybx, zbx = (a.flatten() for a in np.meshgrid(xbx, ybx, zbx, indexing="ij"))Apply similar changes to other unpacked list comprehensions.
Also applies to: 318-320, 321-323, 338-340, 341-343, 344-346
tests/simulator/test_advance.py (6)
Line range hint
5-24
: Reorder imports to the top of the file.Python convention dictates that all module-level imports should be at the top of the file before any code execution. This helps in understanding the dependencies of the module at a glance.
+ from pyphare.cpp import cpp_lib + from ddt import ddt + import unittest + import numpy as np + import pyphare.core.box as boxm + from pyphare.core.box import Box + from pyphare.core.phare_utilities import assert_fp_any_all_close, np_array_ify + from pyphare.pharein import ElectronModel, MaxwellianFluidModel + from pyphare.pharein.diagnostics import ( + ElectromagDiagnostics, + FluidDiagnostics, + ParticleDiagnostics, + ) + from pyphare.pharein.simulation import Simulation + from pyphare.pharesee.geometry import hierarchy_overlaps, level_ghost_boxes + from pyphare.pharesee.hierarchy import hierarchy_from, merge_particles + from pyphare.simulator.simulator import Simulator + from tests.diagnostic import all_timestamps + from tests.simulator import SimulatorTest, diff_boxes - <all the lines where these imports are currently located>Tools
Ruff
87-87: Ambiguous variable name:
l
(E741)
Line range hint
33-33
: Replace lambda expression with a function for clarity.Using lambda for simple operations can reduce readability, especially when used as part of complex expressions. Defining a function is more readable and maintainable.
- _ = lambda i: -((xyz[i] - hL[i]) ** 2) + def square_difference(i): + return -((xyz[i] - hL[i]) ** 2)Tools
Ruff
87-87: Ambiguous variable name:
l
(E741)
Line range hint
48-50
: Initialize mutable defaults inside the function.Using mutable default arguments like dictionaries can lead to unexpected behavior due to Python's handling of default argument values.
- def getHierarchy( - self, - ndim, - interp_order, - refinement_boxes, - qty, - nbr_part_per_cell=100, - density=_density, - smallest_patch_size=None, - largest_patch_size=20, - cells=120, - time_step=0.001, - model_init={}, - dl=0.2, - extra_diag_options={}, - time_step_nbr=1, - timestamps=None, - block_merging_particles=False, - diag_outputs="", - ): + def getHierarchy( + self, + ndim, + interp_order, + refinement_boxes, + qty, + nbr_part_per_cell=100, + density=_density, + smallest_patch_size=None, + largest_patch_size=20, + cells=120, + time_step=0.001, + model_init=None, + dl=0.2, + extra_diag_options=None, + time_step_nbr=1, + timestamps=None, + block_merging_particles=False, + diag_outputs="", + ): + model_init = model_init if model_init is not None else {} + extra_diag_options = extra_diag_options if extra_diag_options is not None else {}Tools
Ruff
87-87: Ambiguous variable name:
l
(E741)
Line range hint
95-115
: Replace lambda expressions with functions.Lambda expressions are used multiple times for similar calculations. Replace them with a single function to enhance readability and maintainability.
- _ = lambda i: 0.1 * np.cos(2 * np.pi * xyz[i] / L[i]) + def cos_component(i): + return 0.1 * np.cos(2 * np.pi * xyz[i] / L[i])Tools
Ruff
87-87: Ambiguous variable name:
l
(E741)
Line range hint
251-251
: Rename unused loop variables.Unused loop variables like
ilvl
andlvl
should be renamed to_
to indicate that they are intentionally not used.- for ilvl, overlaps in hierarchy_overlaps(datahier, coarsest_time).items(): + for _, overlaps in hierarchy_overlaps(datahier, coarsest_time).items(): - for ilvl, lvl in datahier.patch_levels.items(): + for _, _lvl in datahier.patch_levels.items():Also applies to: 345-345
Tools
Ruff
87-87: Ambiguous variable name:
l
(E741)
Line range hint
320-320
: Use f-strings for string formatting.Modern Python recommends using f-strings for more readable and efficient string formatting.
- "test_overlapped_particledatas_have_identical_particles, interporder : {}".format(interp_order) + f"test_overlapped_particledatas_have_identical_particles, interporder : {interp_order}" - "testing level {}".format(ilvl) + f"testing level {ilvl}" - "test_field_coarsening_via_subcycles for dim/interp : {}/{}".format(dim, interp_order) + f"test_field_coarsening_via_subcycles for dim/interp : {dim}/{interp_order}" - "FAIL level ghost subcycle_coarsening qty {qty}".format(qty=qty) + f"FAIL level ghost subcycle_coarsening qty {qty}" - "test_field_coarsening_via_subcycles for dim/interp : {}/{}".format(ndim, interp_order) + f"test_field_coarsening_via_subcycles for dim/interp : {ndim}/{interp_order}"Also applies to: 346-346, 407-407, 519-519, 686-688
Tools
Ruff
87-87: Ambiguous variable name:
l
(E741)pyphare/pyphare/pharesee/hierarchy.py (34)
Line range hint
82-84
: Use f-string for formatting.For improved readability and performance, consider using f-string formatting.
- return "FieldData: (box=({}, {}), key={})".format( - self.layout.box, self.layout.box.shape, self.field_name - ) + return f"FieldData: (box=({self.layout.box}, {self.layout.box.shape}), key={self.field_name})"
Line range hint
203-203
: Use f-string for formatting.This simplifies the code and improves performance.
- return f"Patch: box( {self.box}), id({self.id})" + return f"Patch: box({self.box}), id({self.id})"
Line range hint
508-508
: Optimize dictionary key check.Use
key in dict
instead ofkey in dict.keys()
for a more idiomatic and efficient check.- if qty in self.__dict__.keys(): + if qty in self.__dict__:
Line range hint
520-520
: Remove unused loop variable.The variable
ip
is not used within the loop. You can replace it with_
to indicate it's intentionally unused.- for ip, patch in enumerate(patches): + for _, patch in enumerate(patches):
Line range hint
557-557
: Remove unnecessary inheritance fromobject
.In Python 3, all classes implicitly inherit from
object
, so this is redundant.- class PatchHierarchy(object): + class PatchHierarchy:
Line range hint
621-621
: Useraise ... from
to provide context for exceptions.This helps in debugging by making the chain of exceptions clear.
- raise RuntimeError(f"Failed to deserialize simulation from data file : {e}") + raise RuntimeError(f"Failed to deserialize simulation from data file : {e}") from e
Line range hint
726-726
: Remove unused loop variable.The variable
time
is not used within the loop. You can replace it with_
to indicate it's intentionally unused.- for time in data_file[h5_time_grp_key].keys(): + for _ in data_file[h5_time_grp_key].keys():
Line range hint
727-727
: Remove unused loop variable.The variable
ilvl
is not used within the loop. You can replace it with_
to indicate it's intentionally unused.- for ilvl, lvl in self.levels(time).items(): + for _, lvl in self.levels(time).items():
Line range hint
746-746
: Remove unused loop variable.The variable
ilvl
is not used within the loop. You can replace it with_
to indicate it's intentionally unused.- for ilvl in range(hierarchy.finest_level() + 1): + for _ in range(hierarchy.finest_level() + 1):
Line range hint
760-760
: Remove unused loop variable.The variable
ilvl
is not used within the loop. You can replace it with_
to indicate it's intentionally unused.- for ilvl in range(hierarchy.finest_level() + 1): + for _ in range(hierarchy.finest_level() + 1):
Line range hint
781-781
: Use f-string for formatting.This simplifies the code and improves performance.
- print("creating hierarchy from time {}".format(time)) + print(f"creating hierarchy from time {time}")
Line range hint
790-790
: Remove unused loop variable.The variable
t
is not used within the loop. You can replace it with_
to indicate it's intentionally unused.- for t in times[1:]: + for _ in times[1:]:
Line range hint
792-792
: Use f-string for formatting.This simplifies the code and improves performance.
- print("loading data at time {} into existing hierarchy".format(time)) + print(f"loading data at time {time} into existing hierarchy")
Line range hint
906-906
: Use f-string for formatting.This simplifies the code and improves performance.
- raise RuntimeError("{} is not a valid quantity".format(qty)) + raise RuntimeError(f"{qty} is not a valid quantity")
Line range hint
960-960
: Remove unused loop variable.The variable
lvl
is not used within the loop. You can replace it with_
to indicate it's intentionally unused.- for lvl_nbr, lvl in self.levels(time).items(): + for lvl_nbr, _ in self.levels(time).items():
Line range hint
1099-1099
: Remove unused loop variable.The variable
ip
is not used within the loop. You can replace it with_
to indicate it's intentionally unused.- for ip, patch in enumerate(patches): + for _, patch in enumerate(patches):
Line range hint
1281-1281
: Remove unused loop variable.The variable
ip
is not used within the loop. You can replace it with_
to indicate it's intentionally unused.- for ip, patch in enumerate(sorted_patches): + for _, patch in enumerate(sorted_patches):
Line range hint
1390-1390
: Use f-string for formatting.This simplifies the code and improves performance.
- raise RuntimeError("more than one patch found for point") + raise RuntimeError(f"more than one patch found for point")
Line range hint
1395-1395
: Optimize dictionary key check.Use
key in dict
instead ofkey in dict.keys()
for a more idiomatic and efficient check.- if dataset_name in patch_datas.keys(): + if dataset_name in patch_datas:
Line range hint
1400-1402
: Use f-string for formatting.This simplifies the code and improves performance.
- raise RuntimeError("invalid dataset name : {} is not in {}".format( - dataset_name, field_qties - )) + raise RuntimeError(f"invalid dataset name : {dataset_name} is not in {field_qties}")
Line range hint
1413-1413
: Use f-string for formatting.This simplifies the code and improves performance.
- raise ValueError("error - {} already in patchdata".format(pdname)) + raise ValueError(f"error - {pdname} already in patchdata")
Line range hint
1453-1453
: Use f-string for formatting.This simplifies the code and improves performance.
- raise ValueError("error - {} already in patchdata".format(dataset_name)) + raise ValueError(f"error - {dataset_name} already in patchdata")
Line range hint
1459-1459
: Optimize dictionary key check.Use
key in dict
instead ofkey in dict.keys()
for a more idiomatic and efficient check.- if dataset_name in patch_datas.keys(): + if dataset_name in patch_datas:
Line range hint
1468-1468
: Optimize dictionary key check.Use
key in dict
instead ofkey in dict.keys()
for a more idiomatic and efficient check.- if "patchGhost" in populationdict.keys(): + if "patchGhost" in populationdict:
Line range hint
1490-1490
: Use f-string for formatting.This simplifies the code and improves performance.
- raise ValueError("must specify pop argument for particles") + raise ValueError("must specify pop argument for particles")
Line range hint
1505-1505
: Optimize dictionary key check.Use
key in dict
instead ofkey in dict.keys()
for a more idiomatic and efficient check.- if ghostParticles in populationdict.keys(): + if ghostParticles in populationdict:
Line range hint
1538-1538
: Optimize dictionary key check.Use
key in dict
instead ofkey in dict.keys()
for a more idiomatic and efficient check.- if "levelGhost" in populationdict.keys(): + if "levelGhost" in populationdict:
Line range hint
1544-1544
: Remove unused loop variable.The variable
ipatch
is not used within the loop. You can replace it with_
to indicate it's intentionally unused.- for ipatch, pkey in enumerate(h5_time_grp[plvl_key].keys()): + for _, pkey in enumerate(h5_time_grp[plvl_key].keys()):
Line range hint
1561-1561
: Optimize dictionary key check.Use
key in dict
instead ofkey in dict.keys()
for a more idiomatic and efficient check.- if dataset_name in patch_datas.keys(): + if dataset_name in patch_datas:
Line range hint
1718-1718
: Use f-string for formatting.This simplifies the code and improves performance.
- print("creating hierarchy from all times in file") + print(f"creating hierarchy from all times in file")
Line range hint
1765-1765
: Remove unused loop variable.The variable
time
is not used within the loop. You can replace it with_
to indicate it's intentionally unused.- for time in data_file[h5_time_grp_key].keys(): + for _ in data_file[h5_time_grp_key].keys():
Line range hint
1766-1766
: Remove unused loop variable.The variable
ilvl
is not used within the loop. You can replace it with_
to indicate it's intentionally unused.- for ilvl in range(hierarchy.finest_level() + 1)[::-1]: + for _ in range(hierarchy.finest_level() + 1)[::-1]:
Line range hint
1767-1767
: Remove unused loop variable.The variable
ip
is not used within the loop. You can replace it with_
to indicate it's intentionally unused.- for ip, patch in enumerate(sorted_patches): + for _, patch in enumerate(sorted_patches):
Line range hint
1820-1820
: Optimize dictionary key check.Use
key in dict
instead ofkey in dict.keys()
for a more idiomatic and efficient check.- if qty in self.__dict__.keys(): + if qty in self.__dict__:
Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Files selected for processing (44)
- .github/workflows/cmake_macos.yml (1 hunks)
- pyphare/pyphare/core/box.py (2 hunks)
- pyphare/pyphare/core/gridlayout.py (1 hunks)
- pyphare/pyphare/pharesee/geometry.py (7 hunks)
- pyphare/pyphare/pharesee/hierarchy.py (3 hunks)
- pyphare/pyphare/pharesee/run.py (1 hunks)
- res/amr/splitting.yml (1 hunks)
- res/cmake/options.cmake (1 hunks)
- src/amr/data/field/coarsening/magnetic_field_coarsener.hpp (1 hunks)
- src/amr/data/particles/refine/split.hpp (1 hunks)
- src/amr/data/particles/refine/split_1d.hpp (10 hunks)
- src/amr/data/particles/refine/split_2d.hpp (17 hunks)
- src/amr/data/particles/refine/split_3d.hpp (1 hunks)
- src/amr/data/particles/refine/splitter.hpp (2 hunks)
- src/core/data/grid/gridlayoutdefs.hpp (2 hunks)
- src/core/data/ndarray/ndarray_vector.hpp (8 hunks)
- src/core/utilities/box/box.hpp (3 hunks)
- src/core/utilities/meta/meta_utilities.hpp (2 hunks)
- tests/amr/data/field/refine/test_refine_field.py (1 hunks)
- tests/amr/data/particles/refine/input/input_3d_ratio_2.txt (1 hunks)
- tests/amr/data/particles/refine/test_split.cpp (1 hunks)
- tests/core/data/ndarray/test_main.cpp (1 hunks)
- tests/core/numerics/interpolator/test_main.cpp (1 hunks)
- tests/diagnostic/CMakeLists.txt (1 hunks)
- tests/diagnostic/job_3d.py.in (1 hunks)
- tests/diagnostic/test-diagnostics_3d.cpp (1 hunks)
- tests/functional/harris/harris_3d.py (1 hunks)
- tests/simulator/init.py (2 hunks)
- tests/simulator/advance/CMakeLists.txt (1 hunks)
- tests/simulator/advance/test_fields_advance_3d.py (1 hunks)
- tests/simulator/advance/test_particles_advance_3d.py (1 hunks)
- tests/simulator/initialize/CMakeLists.txt (1 hunks)
- tests/simulator/initialize/test_fields_init_2d.py (1 hunks)
- tests/simulator/initialize/test_fields_init_3d.py (1 hunks)
- tests/simulator/initialize/test_particles_init_1d.py (1 hunks)
- tests/simulator/initialize/test_particles_init_2d.py (1 hunks)
- tests/simulator/initialize/test_particles_init_3d.py (1 hunks)
- tests/simulator/per_test.hpp (1 hunks)
- tests/simulator/refined_particle_nbr.py (2 hunks)
- tests/simulator/test_advance.py (7 hunks)
- tests/simulator/test_initialization.py (14 hunks)
- tools/python3/init.py (5 hunks)
- tools/python3/cmake.py (2 hunks)
- tools/python3/git.py (1 hunks)
Files not reviewed due to errors (4)
- pyphare/pyphare/core/box.py (no review received)
- src/core/utilities/box/box.hpp (no review received)
- tests/simulator/init.py (no review received)
- src/core/data/ndarray/ndarray_vector.hpp (no review received)
Files skipped from review due to trivial changes (3)
- src/amr/data/particles/refine/split.hpp
- tests/amr/data/particles/refine/test_split.cpp
- tests/simulator/initialize/CMakeLists.txt
Additional context used
Path-based instructions (10)
src/core/data/grid/gridlayoutdefs.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.tests/simulator/per_test.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/amr/data/particles/refine/splitter.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/core/utilities/meta/meta_utilities.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/amr/data/particles/refine/split_1d.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/core/utilities/box/box.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/amr/data/field/coarsening/magnetic_field_coarsener.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/amr/data/particles/refine/split_3d.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/amr/data/particles/refine/split_2d.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/core/data/ndarray/ndarray_vector.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.
Ruff
tools/python3/git.py
22-22: Local variable
e
is assigned to but never used (F841)Remove assignment to unused variable
e
29-29: Undefined name
delete_branch
(F821)tools/python3/cmake.py
48-48: Undefined name
cmd
(F821)tests/simulator/initialize/test_particles_init_1d.py
33-33: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
34-34: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
35-35: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
54-54: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
55-55: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
56-56: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
tools/python3/__init__.py
45-45: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling (B904)
46-46: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling (B904)
95-95: Do not use mutable data structures for argument defaults (B006)
Replace with
None
; initialize within function
111-111: Module level import not at top of file (E402)
tests/simulator/initialize/test_particles_init_2d.py
33-33: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
34-34: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
35-35: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
58-58: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
59-59: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
60-60: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
tests/simulator/initialize/test_particles_init_3d.py
35-35: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
36-36: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
37-37: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
60-60: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
61-61: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
62-62: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
tests/functional/harris/harris_3d.py
62-62: Ambiguous variable name:
l
(E741)tests/simulator/refined_particle_nbr.py
9-9: Module level import not at top of file (E402)
10-10: Module level import not at top of file (E402)
11-11: Module level import not at top of file (E402)
13-13: Module level import not at top of file (E402)
14-14: Module level import not at top of file (E402)
15-15: Module level import not at top of file (E402)
16-16: Module level import not at top of file (E402)
18-18: Module level import not at top of file (E402)
18-18:
tests.simulator.NoOverwriteDict
imported but unused (F401)Remove unused import:
tests.simulator.NoOverwriteDict
19-19: Module level import not at top of file (E402)
24-24: Use
super()
instead ofsuper(__class__, self)
(UP008)Remove
__super__
parameters
26-26: Unnecessary open mode parameters (UP015)
Remove open mode parameters
44-44: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
61-61: Loop control variable
pop
not used within loop body (B007)Rename unused
pop
to_pop
63-63: Loop control variable
key
not used within loop body (B007)Rename unused
key
to_key
pyphare/pyphare/core/box.py
11-11: Replace unpacked list comprehension with a generator expression (UP027)
Replace with generator expression
41-41: Use f-string instead of
format
call (UP032)Convert to f-string
76-76: Ambiguous variable name:
l
(E741)
84-84: Ambiguous variable name:
l
(E741)
89-89: Ambiguous variable name:
l
(E741)
94-94: Ambiguous variable name:
l
(E741)
207-207: Ambiguous variable name:
l
(E741)tests/simulator/__init__.py
3-3: Multiple imports on one line (E401)
Split imports
26-26: Use
super()
instead ofsuper(__class__, self)
(UP008)Remove
__super__
parameters
76-76: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
122-122: Do not use mutable data structures for argument defaults (B006)
Replace with
None
; initialize within function
182-182: Undefined name
Box
(F821)
188-188: Undefined name
Box
(F821)
195-195: Undefined name
Box
(F821)
236-236: Use
super()
instead ofsuper(__class__, self)
(UP008)Remove
__super__
parameters
273-273: Multiple imports on one line (E401)
Split imports
275-275: Do not use mutable data structures for argument defaults (B006)
Replace with
None
; initialize within functionpyphare/pyphare/core/gridlayout.py
131-131: Class
YeeCentering
inherits fromobject
(UP004)Remove
object
inheritance
152-155: Use ternary operator
size = nbrCells[dim] + nbrGhosts * 2 if withGhosts else nbrCells[dim]
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withsize = nbrCells[dim] + nbrGhosts * 2 if withGhosts else nbrCells[dim]
168-168: Class
GridLayout
inherits fromobject
(UP004)Remove
object
inheritance
176-176: Do not perform function call
Box
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable (B008)pyphare/pyphare/pharesee/run.py
289-289: Use f-string instead of
format
call (UP032)Convert to f-string
371-371: f-string without any placeholders (F541)
Remove extraneous
f
prefix
373-373: f-string without any placeholders (F541)
Remove extraneous
f
prefix
415-415: Use f-string instead of
format
call (UP032)Convert to f-string
465-465: Do not use mutable data structures for argument defaults (B006)
Replace with
None
; initialize within functiontests/amr/data/field/refine/test_refine_field.py
9-9: Redefinition of unused
refinement_ratio
from line 5 (F811)
106-106: Do not
assert False
(python -O
removes these calls), raiseAssertionError()
(B011)Replace
assert False
pyphare/pyphare/pharesee/geometry.py
160-160: Ambiguous variable name:
l
(E741)
163-163: Ambiguous variable name:
l
(E741)
166-166: Ambiguous variable name:
l
(E741)
187-187: Ambiguous variable name:
l
(E741)
418-418: Do not use mutable data structures for argument defaults (B006)
Replace with
None
; initialize within function
441-441: Loop control variable
pd
not used within loop body (B007)Rename unused
pd
to_pd
464-464: Do not use mutable data structures for argument defaults (B006)
Replace with
None
; initialize within functiontests/simulator/test_initialization.py
5-5: Module level import not at top of file (E402)
7-7: Module level import not at top of file (E402)
8-8: Module level import not at top of file (E402)
9-9: Module level import not at top of file (E402)
10-10: Module level import not at top of file (E402)
11-11: Module level import not at top of file (E402)
12-16: Module level import not at top of file (E402)
17-17: Module level import not at top of file (E402)
18-18: Module level import not at top of file (E402)
19-19: Module level import not at top of file (E402)
20-20: Module level import not at top of file (E402)
21-21: Module level import not at top of file (E402)
23-23: Module level import not at top of file (E402)
32-32: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
44-44: Do not use mutable data structures for argument defaults (B006)
Replace with
None
; initialize within function
93-93: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
98-98: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
103-103: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
108-108: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
113-113: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
261-263: Use f-string instead of
format
call (UP032)Convert to f-string
289-289: Use f-string instead of
format
call (UP032)Convert to f-string
315-317: Replace unpacked list comprehension with a generator expression (UP027)
Replace with generator expression
318-320: Replace unpacked list comprehension with a generator expression (UP027)
Replace with generator expression
321-323: Replace unpacked list comprehension with a generator expression (UP027)
Replace with generator expression
338-340: Replace unpacked list comprehension with a generator expression (UP027)
Replace with generator expression
341-343: Replace unpacked list comprehension with a generator expression (UP027)
Replace with generator expression
344-346: Replace unpacked list comprehension with a generator expression (UP027)
Replace with generator expression
385-385: Use f-string instead of
format
call (UP032)Convert to f-string
387-387: Use f-string instead of
format
call (UP032)Convert to f-string
399-399: Function definition does not bind loop variable
select
(B023)
401-401: Function definition does not bind loop variable
patch
(B023)
401-401: Function definition does not bind loop variable
nbrGhosts
(B023)
402-402: Function definition does not bind loop variable
select
(B023)
450-450: Use f-string instead of
format
call (UP032)Convert to f-string
452-452: Use f-string instead of
format
call (UP032)Convert to f-string
457-457: Local variable
x
is assigned to but never used (F841)Remove assignment to unused variable
x
539-539: Use f-string instead of
format
call (UP032)Convert to f-string
587-587: Loop control variable
pi
not used within loop body (B007)Rename unused
pi
to_pi
591-591: Yoda conditions are discouraged, use
ppc == H
instead (SIM300)Replace Yoda condition with
ppc == H
596-596: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
613-615: Use f-string instead of
format
call (UP032)Convert to f-string
658-658: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
669-669: Local variable
out
is assigned to but never used (F841)Remove assignment to unused variable
out
tests/simulator/test_advance.py
5-5: Module level import not at top of file (E402)
7-7: Module level import not at top of file (E402)
8-8: Module level import not at top of file (E402)
9-9: Module level import not at top of file (E402)
10-10: Module level import not at top of file (E402)
11-11: Module level import not at top of file (E402)
12-12: Module level import not at top of file (E402)
13-17: Module level import not at top of file (E402)
18-18: Module level import not at top of file (E402)
19-19: Module level import not at top of file (E402)
20-20: Module level import not at top of file (E402)
21-21: Module level import not at top of file (E402)
23-23: Module level import not at top of file (E402)
24-24: Module level import not at top of file (E402)
33-33: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
48-48: Do not use mutable data structures for argument defaults (B006)
Replace with
None
; initialize within function
50-50: Do not use mutable data structures for argument defaults (B006)
Replace with
None
; initialize within function
87-87: Ambiguous variable name:
l
(E741)
95-95: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
100-100: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
105-105: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
110-110: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
115-115: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
251-251: Loop control variable
ilvl
not used within loop body (B007)Rename unused
ilvl
to_ilvl
320-322: Use f-string instead of
format
call (UP032)Convert to f-string
345-345: Loop control variable
lvl
not used within loop body (B007)Rename unused
lvl
to_lvl
346-346: Use f-string instead of
format
call (UP032)Convert to f-string
407-409: Use f-string instead of
format
call (UP032)Convert to f-string
519-519: Use f-string instead of
format
call (UP032)Convert to f-string
686-688: Use f-string instead of
format
call (UP032)Convert to f-string
695-695: Do not use mutable data structures for argument defaults (B006)
Replace with
None
; initialize within function
710-710: f-string without any placeholders (F541)
Remove extraneous
f
prefix
711-711: f-string without any placeholders (F541)
Remove extraneous
f
prefix
739-739:
pyphare.pharein
imported but unused (F401)Remove unused import:
pyphare.pharein
744-744: Local variable
out
is assigned to but never used (F841)Remove assignment to unused variable
out
pyphare/pyphare/pharesee/hierarchy.py
82-84: Use f-string instead of
format
call (UP032)Convert to f-string
203-203: Use f-string instead of
format
call (UP032)Convert to f-string
508-508: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
520-520: Loop control variable
ip
not used within loop body (B007)Rename unused
ip
to_ip
557-557: Class
PatchHierarchy
inherits fromobject
(UP004)Remove
object
inheritance
621-621: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling (B904)
651-651: Comparison to
None
should becond is None
(E711)Replace with
cond is None
726-726: Loop control variable
time
not used within loop body (B007)Rename unused
time
to_time
727-727: Loop control variable
ilvl
not used within loop body (B007)Rename unused
ilvl
to_ilvl
746-746: Loop control variable
ilvl
not used within loop body (B007)Rename unused
ilvl
to_ilvl
760-760: Loop control variable
ilvl
not used within loop body (B007)Rename unused
ilvl
to_ilvl
781-781: Use f-string instead of
format
call (UP032)Convert to f-string
790-790: Loop control variable
t
not used within loop body (B007)Rename unused
t
to_t
792-792: Use f-string instead of
format
call (UP032)Convert to f-string
906-906: Use f-string instead of
format
call (UP032)Convert to f-string
960-960: Loop control variable
lvl
not used within loop body (B007)Rename unused
lvl
to_lvl
1034-1034: Loop control variable
lvl
not used within loop body (B007)Rename unused
lvl
to_lvl
1099-1099: Loop control variable
ip
not used within loop body (B007)Rename unused
ip
to_ip
1281-1281: Loop control variable
ip
not used within loop body (B007)Rename unused
ip
to_ip
1390-1390: Use f-string instead of
format
call (UP032)Convert to f-string
1395-1395: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1400-1402: Use f-string instead of
format
call (UP032)Convert to f-string
1413-1413: Use f-string instead of
format
call (UP032)Convert to f-string
1453-1453: Use f-string instead of
format
call (UP032)Convert to f-string
1459-1459: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1468-1468: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1490-1490: Use f-string instead of
format
call (UP032)Convert to f-string
1505-1505: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1538-1538: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1544-1544: Loop control variable
ipatch
not used within loop body (B007)
1561-1561: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1718-1718: Use f-string instead of
format
call (UP032)Convert to f-string
1765-1765: Loop control variable
time
not used within loop body (B007)Rename unused
time
to_time
1766-1766: Loop control variable
ilvl
not used within loop body (B007)Rename unused
ilvl
to_ilvl
1767-1767: Loop control variable
ip
not used within loop body (B007)Rename unused
ip
to_ip
1820-1820: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
Additional comments not posted (34)
tests/amr/data/particles/refine/input/input_3d_ratio_2.txt (1)
10-11
: Mismatch in dimension configuration.The
dim
parameter is set to 1, which is inconsistent with the rest of the configuration that is clearly intended for a 3D simulation. This needs to be corrected to avoid potential errors in simulation behavior.- dim = 1 + dim = 3Likely invalid or redundant comment.
tests/simulator/advance/CMakeLists.txt (1)
21-24
: Ensure proper documentation for 3D test configurations.The addition of 3D tests in the CMake file is crucial for the new functionality. It's important to ensure that these tests are well documented, especially since they are resource-intensive and turned off by default.
tests/diagnostic/CMakeLists.txt (1)
37-41
: Addition of 3D diagnostic tests and configuration files.The inclusion of 3D diagnostic tests (
test-diagnostics_3d
) and the configuration of the corresponding Python job file (job_3d.py.in
) are consistent with the expansion into 3D functionalities. It's important to verify that these tests cover all necessary aspects of the new 3D features.Verification successful
Addition of 3D diagnostic tests and configuration files.
The
test-diagnostics_3d.cpp
file includes several test cases for 3D diagnostics usingTYPED_TEST
, covering fluid, particles, electromagnetics, and allFromPython tests. This confirms that the necessary 3D diagnostic test coverage is present.
TYPED_TEST(Simulator3dTest, fluid)
TYPED_TEST(Simulator3dTest, particles)
TYPED_TEST(Simulator3dTest, electromag)
TYPED_TEST(Simulator3dTest, allFromPython)
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the coverage of 3D diagnostic tests. # Test: Search for 3D diagnostic test cases in the test files. Expect: Relevant test cases covering new features. rg --type cpp "TEST_F(Simulator3dTest, .*)" tests/diagnostic/test-diagnostics_3d.cppLength of output: 86
Script:
#!/bin/bash # List all files in the tests/diagnostic directory to verify the presence of test-diagnostics_3d.cpp ls tests/diagnosticLength of output: 207
Script:
#!/bin/bash # List all test functions within test-diagnostics_3d.cpp rg "TEST_F" tests/diagnostic/test-diagnostics_3d.cppLength of output: 52
Script:
#!/bin/bash # Display the content of test-diagnostics_3d.cpp to investigate for any test functions or relevant content. cat tests/diagnostic/test-diagnostics_3d.cppLength of output: 759
tests/simulator/initialize/test_fields_init_2d.py (1)
26-26
: Explicit specification ofppc
parameter for 2D field initialization tests.The addition of the
ppc
parameter in the test method call ensures that particle-per-cell counts are explicitly controlled during the test, which is crucial for accurate and consistent testing outcomes.tests/simulator/advance/test_particles_advance_3d.py (2)
25-43
: Test function implementation looks good.The function
test_overlapped_particledatas_have_identical_particles
is well-implemented, using dynamic data generation for different interpolation orders and refinement scenarios. The parameters are correctly passed to the underlying test method.
45-47
: Particle conservation test is correctly implemented.The test
test_L0_particle_number_conservation
correctly sets up and executes the conservation test for particles at the coarsest level of refinement.tests/simulator/initialize/test_fields_init_3d.py (4)
23-26
: Field initialization test is properly implemented.The function
test_B_is_as_provided_by_user
correctly logs the test execution and calls the underlying test method with appropriate parameters.
28-33
: Bulk velocity initialization test is correctly implemented.The function
test_bulkvel_is_as_provided_by_user
ensures that the bulk velocity field is initialized as specified, with appropriate logging and parameter handling.
35-38
: Density field test is implemented correctly.The function
test_density_is_as_provided_by_user
performs as expected, ensuring the density field is initialized correctly, with appropriate logging.
40-45
: Density scaling test is implemented with caution regarding memory usage.The function
test_density_decreases_as_1overSqrtN
is correctly implemented to check the scaling of density. The comment about high RAM usage is a good practice to caution about potential resource constraints during testing.res/amr/splitting.yml (1)
103-141
: 3D particle splitting configurations are well-defined.The newly added configurations for 3D particle splitting in
splitting.yml
are clearly defined with appropriate delta and weight values for various particle counts and interpolation orders..github/workflows/cmake_macos.yml (1)
87-87
: Appropriate configuration for PHARE simulator in MacOS builds.The addition of
-DPHARE_SIMULATORS=2
in the CMake configuration ensures that the PHARE simulator is appropriately configured for MacOS builds.src/core/data/grid/gridlayoutdefs.hpp (2)
5-5
: Include standard libraries at the top.It is a good practice to include standard libraries at the top of the file to avoid hidden dependencies and to improve readability.
18-18
: Enum definition is clear and concise.The
QtyCentering
enum is well-defined, usingstd::uint16_t
for storage, which is appropriate given the limited range of values.src/amr/data/particles/refine/splitter.hpp (1)
70-70
: Potential performance improvement in particle dispatching.The loop in the
PatternDispatcher
is complex and might benefit from optimization. Consider caching the results ofpower[dimension - 1]
outside the loop to avoid repeated calculations. Additionally, ensure that the variableweight
is used effectively or remove it if it's redundant.[PERFORMANCE]
- auto weight = static_cast<Weight_t>(pattern.weight_); + auto power_factor = power[dimension - 1]; + for (size_t rpIndex = 0; rpIndex < pattern.deltas_.size(); rpIndex++) + { + FineParticle fineParticle = particles[idx++]; + fineParticle.weight = particle.weight * static_cast<Weight_t>(pattern.weight_) + * power_factor; + // Other operations... + }src/amr/data/particles/refine/split_1d.hpp (8)
34-34
: Use of Dispatcher in Template SpecializationThe use of
PatternDispatcher
withPinkPattern<DimConst<1>>
is a good example of utilizing template metaprogramming to enforce type safety and reduce code duplication. This is a clean implementation that leverages C++ templates effectively.
53-53
: Dispatcher Configuration for Multiple PatternsThe configuration of
PatternDispatcher
to use multiple patterns (BlackPattern
andPinkPattern
) is a robust design choice that enhances the flexibility of theSplitter
template specialization. This approach allows for easy extension or modification of behavior based on different patterns.
71-71
: Consistency in Dispatcher UsageThe consistent use of
PatternDispatcher
across different template specializations maintains a clean and maintainable code structure. This pattern ensures that all splitter behaviors are centralized and easy to manage.
90-90
: Effective Use of Multiple DispatchersThe use of
PatternDispatcher
with bothBlackPattern
andPinkPattern
for theSplitter
template specialization is an excellent example of how complex behaviors can be modularly constructed using template metaprogramming.
109-109
: Dual Pattern Dispatcher for Enhanced FlexibilityThe implementation of
SplitPattern_1_2_4_Dispatcher
using two instances ofPinkPattern
showcases the flexibility of the dispatcher mechanism to handle more complex scenarios where multiple patterns are involved.
146-146
: Use of Multiple Dispatchers in a Single SplitterThe configuration of
SplitPattern_1_3_3_Dispatcher
to use bothBlackPattern
andPinkPattern
is a robust design choice that allows for flexible behavior in particle splitting. This pattern of using multiple dispatchers enhances the modularity and reusability of the code.
165-165
: Dispatcher Configuration for Complex Splitting PatternsThe use of dual
PinkPattern
inSplitPattern_1_3_4_Dispatcher
effectively demonstrates the capability to handle complex particle splitting scenarios, providing a clear and maintainable approach to defining splitting behavior.
184-184
: Complex Dispatcher Configuration for Advanced SplittingThe implementation of
SplitPattern_1_3_5_Dispatcher
using three instances ofPinkPattern
is an advanced use of the dispatcher pattern, allowing for highly customizable and complex particle splitting behavior.src/amr/data/field/coarsening/magnetic_field_coarsener.hpp (1)
52-59
: Check consistency in physical quantity assertions.The assertion checks if the physical quantities of
fineField
andcoarseField
are the same. This is crucial for ensuring that the operation is performed on compatible fields. Always ensure that such critical checks are well-documented for maintainability.tests/core/data/ndarray/test_main.cpp (1)
395-446
: Enhance 3D array operations testing.The tests for 3D operations using
MaskedView3d
are well-structured and cover various scenarios, including edge cases and boundary conditions. This is crucial for ensuring the robustness of 3D data handling capabilities.src/amr/data/particles/refine/split_3d.hpp (2)
19-41
: Verify consistency and correctness in particle splitting patterns.The
PinkPattern
for 3D particle splitting is implemented with consideration for symmetry and efficiency. Ensure the correctness of the pattern logic, especially the sign handling and offset calculations, as these are critical for the accuracy of particle distribution.
66-87
: OptimizeLimePattern
implementation.The
LimePattern
implementation uses lambda functions to avoid code duplication. This is a good practice for maintainability. However, consider potential performance implications of using lambdas in this context, especially regarding inlining and overhead.src/amr/data/particles/refine/split_2d.hpp (2)
93-93
: Approval of Dispatcher usage.The usage of
PatternDispatcher
in variousSplitter
templates is consistent and appears to follow a clear pattern. This should facilitate the addition of new patterns or modifications to existing ones without significant refactoring.Also applies to: 112-112, 131-132, 169-169, 188-188, 207-208, 227-228, 266-266, 285-285, 304-305, 324-326
62-62
: Consistency check for PinkPattern constructor.The initialization of
deltas_
inPinkPattern
seems inconsistent with its siblings likePurplePattern
. If this is intentional, it would be beneficial to add a comment here to clarify why the deltas are set differently, to avoid confusion during future code modifications.Verification successful
Consistency check for PinkPattern constructor.
The initialization of
deltas_
inPinkPattern
appears consistent with other patterns likePurplePattern
. Both patterns initialize thedeltas_
array based on thedelta
parameter. However, if there are specific differences in the waydeltas_
are set that are intentional, it would be beneficial to document these differences with comments to avoid confusion during future code modifications.
- File:
src/amr/data/particles/refine/split_2d.hpp
- Lines to check: Initialization of
deltas_
inPinkPattern
andPurplePattern
.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check if there are similar patterns with different delta initializations and document them. # Search for similar patterns in other files to compare delta initializations. rg --type cpp $'constexpr .*Pattern\(float const weight, float const delta\)'Length of output: 730
Script:
#!/bin/bash # Description: Extract initialization details of deltas_ in each pattern to verify consistency. # Search for the initialization of deltas_ in PinkPattern, PurplePattern, and other patterns. rg --type cpp 'deltas_' src/amr/data/particles/refine/split_*.hppLength of output: 3024
pyphare/pyphare/core/gridlayout.py (1)
Line range hint
176-176
: Avoid mutable default arguments for better safety.Using mutable default arguments like
Box(0, 0)
can lead to unexpected behaviors. Consider usingNone
and initializing within the function.
[REFACTOR_SUGGESTion]- def __init__(self, box=Box(0, 0), origin=0, dl=0.1, interp_order=1, field_ghosts_nbr=-1): + def __init__(self, box=None, origin=0, dl=0.1, interp_order=1, field_ghosts_nbr=-1): + if box is None: + box = Box(0, 0)pyphare/pyphare/pharesee/geometry.py (1)
58-73
: Refactor the repetitive code for defining border ghost boxes.The repetitive code for defining border ghost boxes in different dimensions could be refactored to improve maintainability and reduce redundancy. Consider using a helper function as previously suggested.
tests/simulator/test_initialization.py (2)
591-591
: Avoid using Yoda conditions.Yoda conditions can reduce code readability. It's more natural to write conditions in a direct order in Python.
- self.assertTrue((ppc == H).all()) + self.assertTrue((H == ppc).all())Likely invalid or redundant comment.
Tools
Ruff
591-591: Yoda conditions are discouraged, use
ppc == H
instead (SIM300)Replace Yoda condition with
ppc == H
669-669
: Remove unused local variable.The variable
out
is defined but not used, which can be confusing and misleading.- out = "phare_outputs"
Likely invalid or redundant comment.
Tools
Ruff
669-669: Local variable
out
is assigned to but never used (F841)Remove assignment to unused variable
out
pyphare/pyphare/pharesee/hierarchy.py (1)
Line range hint
651-651
: Useis None
for None checks.This is the idiomatic way to check for
None
in Python.- if cond == None: + if cond is None:[REFACTOR_Suggestion]
TYPED_TEST_P(ACollectionOfParticles_3d, DepositCorrectlyTheirWeight_3d) | ||
{ | ||
// auto const& [vx, vy, vz] = this->v(); | ||
// EXPECT_DOUBLE_EQ(this->rho(7, 7, 7), 1.0); | ||
// EXPECT_DOUBLE_EQ(vx(7, 7, 7), 2.0); | ||
// EXPECT_DOUBLE_EQ(vy(7, 7, 7), -1.0); | ||
// EXPECT_DOUBLE_EQ(vz(7, 7, 7), 1.0); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uncomment and verify the test case DepositCorrectlyTheirWeight_3d
.
The test case is crucial for validating 3D interpolation correctness but is currently commented out. This needs to be active to ensure the functionality is tested properly.
- // auto const& [vx, vy, vz] = this->v();
- // EXPECT_DOUBLE_EQ(this->rho(7, 7, 7), 1.0);
- // EXPECT_DOUBLE_EQ(vx(7, 7, 7), 2.0);
- // EXPECT_DOUBLE_EQ(vy(7, 7, 7), -1.0);
- // EXPECT_DOUBLE_EQ(vz(7, 7, 7), 1.0);
+ auto const& [vx, vy, vz] = this->v();
+ EXPECT_DOUBLE_EQ(this->rho(7, 7, 7), 1.0);
+ EXPECT_DOUBLE_EQ(vx(7, 7, 7), 2.0);
+ EXPECT_DOUBLE_EQ(vy(7, 7, 7), -1.0);
+ EXPECT_DOUBLE_EQ(vz(7, 7, 7), 1.0);
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
TYPED_TEST_P(ACollectionOfParticles_3d, DepositCorrectlyTheirWeight_3d) | |
{ | |
// auto const& [vx, vy, vz] = this->v(); | |
// EXPECT_DOUBLE_EQ(this->rho(7, 7, 7), 1.0); | |
// EXPECT_DOUBLE_EQ(vx(7, 7, 7), 2.0); | |
// EXPECT_DOUBLE_EQ(vy(7, 7, 7), -1.0); | |
// EXPECT_DOUBLE_EQ(vz(7, 7, 7), 1.0); | |
} | |
TYPED_TEST_P(ACollectionOfParticles_3d, DepositCorrectlyTheirWeight_3d) | |
{ | |
auto const& [vx, vy, vz] = this->v(); | |
EXPECT_DOUBLE_EQ(this->rho(7, 7, 7), 1.0); | |
EXPECT_DOUBLE_EQ(vx(7, 7, 7), 2.0); | |
EXPECT_DOUBLE_EQ(vy(7, 7, 7), -1.0); | |
EXPECT_DOUBLE_EQ(vz(7, 7, 7), 1.0); | |
} |
@@ -257,19 +256,26 @@ def vthz(*xyz): | |||
) | |||
return mom_hier | |||
|
|||
def _test_B_is_as_provided_by_user(self, dim, interp_order, **kwargs): | |||
def _test_B_is_as_provided_by_user(self, dim, interp_order, ppc=100, **kwargs): | |||
print( | |||
"test_B_is_as_provided_by_user : dim {} interp_order : {}".format( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use f-strings for string formatting.
Python's f-string provides a more readable, concise, and less error-prone way of formatting strings compared to the format
method.
- "test_B_is_as_provided_by_user : dim {} interp_order : {}".format(dim, interp_order)
+ f"test_B_is_as_provided_by_user : dim {dim} interp_order : {interp_order}"
Apply similar changes to other lines where format
is used.
Also applies to: 289-289, 385-385, 387-387, 450-450, 452-452, 539-539, 613-615
Tools
Ruff
261-263: Use f-string instead of
format
call (UP032)Convert to f-string
#if !defined(PHARE_SIMULATORS) | ||
#define PHARE_SIMULATORS 3 | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure the default value for PHARE_SIMULATORS
is well-documented.
The macro PHARE_SIMULATORS
is defined with a default value of 3. It's important to document this value in the code or in related documentation to clarify its impact and usage within the project.
+ 1.0 / np.cosh((y - L * 0.7) / 0.5) ** 2 | ||
) | ||
|
||
def S(y, y0, l): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename the ambiguous variable 'l' to 'length' for clarity.
The variable l
is ambiguous and can be mistaken for the number 1
. Renaming it to length
will improve readability.
- def S(y, y0, l):
+ def S(y, y0, length):
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def S(y, y0, l): | |
def S(y, y0, length): |
Tools
Ruff
62-62: Ambiguous variable name:
l
(E741)
# 1d | ||
# refine 10 cells in 1d, ppc 100 | ||
# 10 * 2 * ppc = 200 | ||
# 10 * 3 * ppc = 300 300 / 200 = 1.5 | ||
# 10 * 4 * ppc = 400 500 / 400 = 1.33 | ||
# 10 * 5 * ppc = 500 500 / 400 = 1.25 | ||
# taking the minimul diff across permutations | ||
# current to previous should be at least this times bigger | ||
PRIOR_MIN_DIFF_1d = 1.25 | ||
PRIOR_MAX_DIFF_1d = 1.50 | ||
|
||
def test_1d(self): | ||
This = type(self) | ||
self._do_dim( | ||
1, This.PREVIOUS_ITERATION_MIN_DIFF_1d, This.PREVIOUS_ITERATION_MAX_DIFF_1d | ||
) | ||
|
||
""" 2d | ||
refine 10x10 cells in 2d, ppc 100 | ||
10 * 10 * 4 * ppc = 400 | ||
10 * 10 * 8 * ppc = 800 800 / 400 = 1.5 | ||
10 * 10 * 9 * ppc = 900 900 / 800 = 1.125 | ||
""" | ||
PREVIOUS_ITERATION_MIN_DIFF_2d = 1.125 | ||
PREVIOUS_ITERATION_MAX_DIFF_2d = 1.50 | ||
self._do_dim(1, This.PRIOR_MIN_DIFF_1d, This.PRIOR_MAX_DIFF_1d) | ||
|
||
# 2d | ||
# refine 10x10 cells in 2d, ppc 100 | ||
# 10 * 10 * 4 * ppc = 400 | ||
# 10 * 10 * 8 * ppc = 800 800 / 400 = 1.5 | ||
# 10 * 10 * 9 * ppc = 900 900 / 800 = 1.125 | ||
PRIOR_MIN_DIFF_2d = 1.125 | ||
PRIOR_MAX_DIFF_2d = 1.50 | ||
|
||
def test_2d(self): | ||
This = type(self) | ||
self._do_dim( | ||
2, This.PREVIOUS_ITERATION_MIN_DIFF_2d, This.PREVIOUS_ITERATION_MAX_DIFF_2d | ||
) | ||
self._do_dim(2, This.PRIOR_MIN_DIFF_2d, This.PRIOR_MAX_DIFF_2d) | ||
|
||
def tearDown(self): | ||
# needed in case exception is raised in test and Simulator | ||
# not reset properly | ||
if self.simulator is not None: | ||
self.simulator.reset() | ||
# 3d | ||
# refine 10x10x10 cells in 3d, ppc 100 | ||
# 10 * 10 * 10 * 6 * ppc = 6000 | ||
# 10 * 10 * 10 * 12 * ppc = 12000 - 12000 / 6000 = 2 | ||
# 10 * 10 * 10 * 27 * ppc = 27000 - 27000 / 12000 = 2.25 | ||
PRIOR_MIN_DIFF_3d = 2 | ||
PRIOR_MAX_DIFF_3d = 2.25 | ||
|
||
def test_3d(self): | ||
This = type(self) | ||
self._do_dim(3, This.PRIOR_MIN_DIFF_3d, This.PRIOR_MAX_DIFF_3d) | ||
|
||
def _check_deltas_and_weights(self, dim, interp, refined_particle_nbr): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clarify the calculations in the _do_dim
method.
The calculations in the _do_dim
method are critical for ensuring the correct number of particles are refined. Adding comments to explain the logic behind these calculations and assertions would significantly improve code clarity and maintainability.
+ # Calculate the minimum and maximum differences expected between the current and previous number of particles
+ # This is used to ensure that the particle refinement is within expected bounds
Committable suggestion was skipped due to low confidence.
template<> // 1 per corner | ||
struct PurplePattern<DimConst<3>> : SplitPattern<DimConst<3>, RefinedParticlesConst<8>> | ||
{ | ||
using Super = SplitPattern<DimConst<3>, RefinedParticlesConst<8>>; | ||
|
||
constexpr PurplePattern(float const weight, float const delta) | ||
: Super{weight} | ||
{ | ||
for (std::size_t i = 0; i < 2; i++) | ||
{ | ||
std::size_t offset = i * 4; | ||
float sign = i % 2 ? -1 : 1; | ||
auto mode = delta * sign; | ||
|
||
Super::deltas_[0 + offset] = {mode, mode, mode}; | ||
Super::deltas_[1 + offset] = {mode, mode, -mode}; | ||
Super::deltas_[2 + offset] = {mode, -mode, mode}; | ||
Super::deltas_[3 + offset] = {mode, -mode, -mode}; | ||
} | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tip
Codebase Verification
Check for potential floating-point precision issues.
The search results indicate the usage of double precision (double
) in various parts of the codebase, but there are no specific precision controls or higher precision data types (float
and double
) directly related to the PurplePattern
structure. The presence of precision handling mechanisms in other parts of the codebase suggests awareness of potential precision issues.
Given the floating-point operations in PurplePattern
, it is advisable to consider introducing precision controls or using higher precision data types if the precision requirements are critical.
- Consider using
double
instead offloat
for higher precision. - Introduce precision handling mechanisms where necessary.
Locations to review:
src/amr/data/particles/refine/split_3d.hpp
(Lines 43-63)
Analysis chain
Check for potential floating-point precision issues.
The PurplePattern
uses floating-point operations which might introduce precision issues, especially with the negation and addition operations. Consider verifying the precision requirements and if necessary, introduce precision controls or use higher precision data types.
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for precision issues in floating-point operations.
# Test: Search for floating-point precision handling in the project.
rg --type cpp 'float' | grep 'precision'
Length of output: 264
Script:
#!/bin/bash
# Description: Check for precision handling mechanisms or higher precision data types in the project.
# Search for any usage of double or higher precision data types in the codebase.
rg --type cpp 'double'
# Search for any precision handling mechanisms in the codebase.
rg --type cpp 'precision'
Length of output: 93798
|
||
@ddt | ||
class Initialization3DTest(InitializationTest): | ||
@data(*interp_orders) | ||
def test_nbr_particles_per_cell_is_as_provided(self, interp_order): | ||
print(f"{self._testMethodName}_{ndim}d") | ||
self._test_nbr_particles_per_cell_is_as_provided( | ||
ndim, interp_order, ppc, cells=cells | ||
) | ||
|
||
@data( | ||
*per_interp(({"L0": {"B0": Box3D(10, 14)}})), | ||
*per_interp(({"L0": {"B0": Box3D(10, 14)}, "L1": {"B0": Box3D(22, 26)}})), | ||
*per_interp(({"L0": {"B0": Box3D(2, 6), "B1": Box3D(7, 11)}})), | ||
) | ||
@unpack | ||
def test_levelghostparticles_have_correct_split_from_coarser_particle( | ||
self, interp_order, refinement_boxes | ||
): | ||
print(f"\n{self._testMethodName}_{ndim}d") | ||
now = self.datetime_now() | ||
self._test_levelghostparticles_have_correct_split_from_coarser_particle( | ||
self.getHierarchy( | ||
ndim, | ||
interp_order, | ||
refinement_boxes, | ||
"particles", | ||
cells=cells, | ||
nbr_part_per_cell=ppc, | ||
) | ||
) | ||
print( | ||
f"\n{self._testMethodName}_{ndim}d took {self.datetime_diff(now)} seconds" | ||
) | ||
|
||
@data( | ||
*per_interp(({"L0": {"B0": Box3D(10, 14)}})), | ||
*per_interp(({"L0": {"B0": Box3D(5, 14)}, "L1": {"B0": Box3D(15, 19)}})), | ||
*per_interp(({"L0": {"B0": Box3D(2, 12), "B1": Box3D(13, 25)}})), | ||
) | ||
@unpack | ||
def test_domainparticles_have_correct_split_from_coarser_particle( | ||
self, interp_order, refinement_boxes | ||
): | ||
print(f"\n{self._testMethodName}_{ndim}d") | ||
now = self.datetime_now() | ||
self._test_domainparticles_have_correct_split_from_coarser_particle( | ||
ndim, interp_order, refinement_boxes, nbr_part_per_cell=ppc | ||
) | ||
print( | ||
f"\n{self._testMethodName}_{ndim}d took {self.datetime_diff(now)} seconds" | ||
) | ||
|
||
# @data({"cells": 40, "smallest_patch_size": 20, "largest_patch_size": 20, "nbr_part_per_cell" : ppc}) | ||
# def test_no_patch_ghost_on_refined_level_case(self, simInput): | ||
# print(f"\n{self._testMethodName}_{ndim}d") | ||
# now = self.datetime_now() | ||
# self._test_patch_ghost_on_refined_level_case(ndim, False, **simInput) | ||
# print(f"\n{self._testMethodName}_{ndim}d took {self.datetime_diff(now)} seconds") | ||
|
||
# @data({"cells": 40, "interp_order": 1, "nbr_part_per_cell" : ppc}) | ||
# def test_has_patch_ghost_on_refined_level_case(self, simInput): | ||
# print(f"\n{self._testMethodName}_{ndim}d") | ||
# from pyphare.pharein.simulation import check_patch_size | ||
# diag_outputs=f"phare_overlaped_fields_are_equal_with_min_max_patch_size_of_max_ghosts_{ndim}_{self.ddt_test_id()}" | ||
# _, smallest_patch_size = check_patch_size(ndim, **simInput) | ||
# simInput["smallest_patch_size"] = smallest_patch_size | ||
# simInput["largest_patch_size"] = smallest_patch_size | ||
# now = self.datetime_now() | ||
# self._test_patch_ghost_on_refined_level_case(ndim, True, **simInput) | ||
# print(f"\n{self._testMethodName}_{ndim}d took {self.datetime_diff(now)} seconds") | ||
|
||
|
||
if __name__ == "__main__": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactor suggested to enhance code quality and maintainability.
-
Remove commented-out code: Lines 77-94 contain commented-out test cases. If these are not needed, they should be removed to clean up the codebase. If they are to be used in the future, it would be better to document their purpose clearly or implement them in a feature branch.
-
Simplify expressions: The use of extraneous parentheses in lines 35, 36, 37, 60, 61, and 62 can be removed to clean up the code and adhere to Pythonic best practices.
- *per_interp(({"L0": {"B0": Box3D(10, 14)}})),
- *per_interp(({"L0": {"B0": Box3D(10, 14), "L1": {"B0": Box3D(22, 26)}})),
- *per_interp(({"L0": {"B0": Box3D(2, 6), "B1": Box3D(7, 11)}})),
+ *per_interp({"L0": {"B0": Box3D(10, 14)}}),
+ *per_interp({"L0": {"B0": Box3D(10, 14), "L1": {"B0": Box3D(22, 26)}}),
+ *per_interp({"L0": {"B0": Box3D(2, 6), "B1": Box3D(7, 11)}}),
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
@ddt | |
class Initialization3DTest(InitializationTest): | |
@data(*interp_orders) | |
def test_nbr_particles_per_cell_is_as_provided(self, interp_order): | |
print(f"{self._testMethodName}_{ndim}d") | |
self._test_nbr_particles_per_cell_is_as_provided( | |
ndim, interp_order, ppc, cells=cells | |
) | |
@data( | |
*per_interp(({"L0": {"B0": Box3D(10, 14)}})), | |
*per_interp(({"L0": {"B0": Box3D(10, 14)}, "L1": {"B0": Box3D(22, 26)}})), | |
*per_interp(({"L0": {"B0": Box3D(2, 6), "B1": Box3D(7, 11)}})), | |
) | |
@unpack | |
def test_levelghostparticles_have_correct_split_from_coarser_particle( | |
self, interp_order, refinement_boxes | |
): | |
print(f"\n{self._testMethodName}_{ndim}d") | |
now = self.datetime_now() | |
self._test_levelghostparticles_have_correct_split_from_coarser_particle( | |
self.getHierarchy( | |
ndim, | |
interp_order, | |
refinement_boxes, | |
"particles", | |
cells=cells, | |
nbr_part_per_cell=ppc, | |
) | |
) | |
print( | |
f"\n{self._testMethodName}_{ndim}d took {self.datetime_diff(now)} seconds" | |
) | |
@data( | |
*per_interp(({"L0": {"B0": Box3D(10, 14)}})), | |
*per_interp(({"L0": {"B0": Box3D(5, 14)}, "L1": {"B0": Box3D(15, 19)}})), | |
*per_interp(({"L0": {"B0": Box3D(2, 12), "B1": Box3D(13, 25)}})), | |
) | |
@unpack | |
def test_domainparticles_have_correct_split_from_coarser_particle( | |
self, interp_order, refinement_boxes | |
): | |
print(f"\n{self._testMethodName}_{ndim}d") | |
now = self.datetime_now() | |
self._test_domainparticles_have_correct_split_from_coarser_particle( | |
ndim, interp_order, refinement_boxes, nbr_part_per_cell=ppc | |
) | |
print( | |
f"\n{self._testMethodName}_{ndim}d took {self.datetime_diff(now)} seconds" | |
) | |
# @data({"cells": 40, "smallest_patch_size": 20, "largest_patch_size": 20, "nbr_part_per_cell" : ppc}) | |
# def test_no_patch_ghost_on_refined_level_case(self, simInput): | |
# print(f"\n{self._testMethodName}_{ndim}d") | |
# now = self.datetime_now() | |
# self._test_patch_ghost_on_refined_level_case(ndim, False, **simInput) | |
# print(f"\n{self._testMethodName}_{ndim}d took {self.datetime_diff(now)} seconds") | |
# @data({"cells": 40, "interp_order": 1, "nbr_part_per_cell" : ppc}) | |
# def test_has_patch_ghost_on_refined_level_case(self, simInput): | |
# print(f"\n{self._testMethodName}_{ndim}d") | |
# from pyphare.pharein.simulation import check_patch_size | |
# diag_outputs=f"phare_overlaped_fields_are_equal_with_min_max_patch_size_of_max_ghosts_{ndim}_{self.ddt_test_id()}" | |
# _, smallest_patch_size = check_patch_size(ndim, **simInput) | |
# simInput["smallest_patch_size"] = smallest_patch_size | |
# simInput["largest_patch_size"] = smallest_patch_size | |
# now = self.datetime_now() | |
# self._test_patch_ghost_on_refined_level_case(ndim, True, **simInput) | |
# print(f"\n{self._testMethodName}_{ndim}d took {self.datetime_diff(now)} seconds") | |
if __name__ == "__main__": | |
@ddt | |
class Initialization3DTest(InitializationTest): | |
@data(*interp_orders) | |
def test_nbr_particles_per_cell_is_as_provided(self, interp_order): | |
print(f"{self._testMethodName}_{ndim}d") | |
self._test_nbr_particles_per_cell_is_as_provided( | |
ndim, interp_order, ppc, cells=cells | |
) | |
@data( | |
*per_interp({"L0": {"B0": Box3D(10, 14)}}), | |
*per_interp({"L0": {"B0": Box3D(10, 14), "L1": {"B0": Box3D(22, 26)}}), | |
*per_interp({"L0": {"B0": Box3D(2, 6), "B1": Box3D(7, 11)}}), | |
) | |
@unpack | |
def test_levelghostparticles_have_correct_split_from_coarser_particle( | |
self, interp_order, refinement_boxes | |
): | |
print(f"\n{self._testMethodName}_{ndim}d") | |
now = self.datetime_now() | |
self._test_levelghostparticles_have_correct_split_from_coarser_particle( | |
self.getHierarchy( | |
ndim, | |
interp_order, | |
refinement_boxes, | |
"particles", | |
cells=cells, | |
nbr_part_per_cell=ppc, | |
) | |
) | |
print( | |
f"\n{self._testMethodName}_{ndim}d took {self.datetime_diff(now)} seconds" | |
) | |
@data( | |
*per_interp({"L0": {"B0": Box3D(10, 14)}}), | |
*per_interp({"L0": {"B0": Box3D(5, 14)}, "L1": {"B0": Box3D(15, 19)}}), | |
*per_interp({"L0": {"B0": Box3D(2, 12), "B1": Box3D(13, 25)}}), | |
) | |
@unpack | |
def test_domainparticles_have_correct_split_from_coarser_particle( | |
self, interp_order, refinement_boxes | |
): | |
print(f"\n{self._testMethodName}_{ndim}d") | |
now = self.datetime_now() | |
self._test_domainparticles_have_correct_split_from_coarser_particle( | |
ndim, interp_order, refinement_boxes, nbr_part_per_cell=ppc | |
) | |
print( | |
f"\n{self._testMethodName}_{ndim}d took {self.datetime_diff(now)} seconds" | |
) | |
# @data({"cells": 40, "smallest_patch_size": 20, "largest_patch_size": 20, "nbr_part_per_cell" : ppc}) | |
# def test_no_patch_ghost_on_refined_level_case(self, simInput): | |
# print(f"\n{self._testMethodName}_{ndim}d") | |
# now = self.datetime_now() | |
# self._test_patch_ghost_on_refined_level_case(ndim, False, **simInput) | |
# print(f"\n{self._testMethodName}_{ndim}d took {self.datetime_diff(now)} seconds") | |
# @data({"cells": 40, "interp_order": 1, "nbr_part_per_cell" : ppc}) | |
# def test_has_patch_ghost_on_refined_level_case(self, simInput): | |
# print(f"\n{self._testMethodName}_{ndim}d") | |
# from pyphare.pharein.simulation import check_patch_size | |
# diag_outputs=f"phare_overlaped_fields_are_equal_with_min_max_patch_size_of_max_ghosts_{ndim}_{self.ddt_test_id()}" | |
# _, smallest_patch_size = check_patch_size(ndim, **simInput) | |
# simInput["smallest_patch_size"] = smallest_patch_size | |
# simInput["largest_patch_size"] = smallest_patch_size | |
# now = self.datetime_now() | |
# self._test_patch_ghost_on_refined_level_case(ndim, True, **simInput) | |
# print(f"\n{self._testMethodName}_{ndim}d took {self.datetime_diff(now)} seconds") | |
if __name__ == "__main__": |
Tools
Ruff
35-35: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
36-36: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
37-37: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
60-60: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
61-61: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
62-62: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
tools/python3/__init__.py
Outdated
def binary_exists_on_path(bin): | ||
""" | ||
https://linux.die.net/man/1/which | ||
""" | ||
return run(f"which {bin}").returncode == 0 | ||
return len(find_on_path(bin)) | ||
|
||
|
||
def scan_dir(path, files_only=False, dirs_only=False, drop=[]): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid mutable default arguments.
Using mutable default arguments can lead to unexpected behaviors. Replace the mutable default with None
and initialize it within the function if necessary.
- def scan_dir(path, files_only=False, dirs_only=False, drop=[]):
+ def scan_dir(path, files_only=False, dirs_only=False, drop=None):
+ if drop is None:
+ drop = []
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def scan_dir(path, files_only=False, dirs_only=False, drop=[]): | |
def scan_dir(path, files_only=False, dirs_only=False, drop=None): | |
if drop is None: | |
drop = [] |
Tools
Ruff
95-95: Do not use mutable data structures for argument defaults (B006)
Replace with
None
; initialize within function
|
||
@ddt | ||
class AdvanceTest(AdvanceTestBase): | ||
@data( | ||
*per_interp({}), | ||
*per_interp({"L0": [Box3D(10, 19)]}), | ||
*per_interp({"L0": [Box3D(8, 20)]}), | ||
) | ||
@unpack | ||
def test_overlaped_fields_are_equal(self, interp_order, refinement_boxes): | ||
print(f"{self._testMethodName}_{ndim}d") | ||
time_step_nbr = 3 | ||
time_step = 0.001 | ||
datahier = self.getHierarchy( | ||
ndim, | ||
interp_order, | ||
refinement_boxes, | ||
"eb", | ||
cells=cells, | ||
time_step=time_step, | ||
time_step_nbr=time_step_nbr, | ||
nbr_part_per_cell=ppc, | ||
) | ||
self._test_overlaped_fields_are_equal(datahier, time_step_nbr, time_step) | ||
|
||
@data( | ||
*per_interp({}), | ||
*per_interp({"L0": [Box3D(5, 14)]}), | ||
) | ||
@unpack | ||
def test_overlaped_fields_are_equal_with_min_max_patch_size_of_max_ghosts( | ||
self, interp_order, refinement_boxes | ||
): | ||
print(f"{self._testMethodName}_{ndim}d") | ||
time_step_nbr = 3 | ||
time_step = 0.001 | ||
from pyphare.pharein.simulation import check_patch_size | ||
|
||
largest_patch_size, smallest_patch_size = check_patch_size( | ||
ndim, interp_order=interp_order, cells=[cells] * ndim | ||
) | ||
datahier = self.getHierarchy( | ||
ndim, | ||
interp_order, | ||
refinement_boxes, | ||
"eb", | ||
cells=cells, | ||
smallest_patch_size=smallest_patch_size, | ||
largest_patch_size=smallest_patch_size, | ||
time_step=time_step, | ||
time_step_nbr=time_step_nbr, | ||
nbr_part_per_cell=ppc, | ||
) | ||
self._test_overlaped_fields_are_equal(datahier, time_step_nbr, time_step) | ||
|
||
# @data( | ||
# *per_interp(({"L0": {"B0": Box3D(10, 14)}})), | ||
# *per_interp(({"L0": {"B0": Box3D(10, 14), "B1": Box3D(15, 19)}})), | ||
# *per_interp(({"L0": {"B0": Box3D(6, 23)}})), | ||
# *per_interp(({"L0": {"B0": Box3D( 2, 12), "B1": Box3D(13, 25)}})), | ||
# *per_interp(({"L0": {"B0": Box3D( 5, 20)}, "L1": {"B0": Box3D(15, 19)}})), | ||
# *per_interp(({"L0": {"B0": Box3D( 5, 20)}, "L1": {"B0": Box3D(12, 38)}, "L2": {"B0": Box3D(30, 52)} })), | ||
# ) | ||
# @unpack | ||
# def test_field_coarsening_via_subcycles(self, interp_order, refinement_boxes): | ||
# print(f"{self._testMethodName}_{ndim}d") | ||
# self._test_field_coarsening_via_subcycles(ndim, interp_order, refinement_boxes, dl=.3, cells=cells) | ||
|
||
# @unittest.skip("should change to work on moments") | ||
# @data( # only supports a hierarchy with 2 levels | ||
# *per_interp(({"L0": [Box3D(0, 4)]})), | ||
# *per_interp(({"L0": [Box3D(10, 14)]})), | ||
# *per_interp(({"L0": [Box3D(0, 4), Box3D(10, 14)]})), | ||
# *per_interp(({"L0": [Box3D(0, 4), Box3D(5, 9), Box3D(10, 14)]})), | ||
# *per_interp(({"L0": [Box3D(20, 24)]})), | ||
# ) | ||
# @unpack | ||
# def test_field_level_ghosts_via_subcycles_and_coarser_interpolation(self, interp_order, refinement_boxes): | ||
# print(f"{self._testMethodName}_{ndim}d") | ||
# self._test_field_level_ghosts_via_subcycles_and_coarser_interpolation(ndim, interp_order, refinement_boxes) | ||
|
||
|
||
if __name__ == "__main__": | ||
unittest.main() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactor suggested to enhance code quality and maintainability.
-
Remove commented-out code: Lines 79-103 contain commented-out test cases. If these are not needed, they should be removed to clean up the codebase. If they are to be used in the future, it would be better to document their purpose clearly or implement them in a feature branch.
-
Simplify expressions: The use of extraneous parentheses in lines 28, 29, 30, 50, and 51 can be removed to clean up the code and adhere to Pythonic best practices.
- *per_interp(({})),
- *per_interp(({"L0": [Box3D(10, 19)]})),
- *per_interp(({"L0": [Box3D(8, 20)]})),
+ *per_interp({}),
+ *per_interp({"L0": [Box3D(10, 19)]}),
+ *per_interp({"L0": [Box3D(8, 20)]}),
Committable suggestion was skipped due to low confidence.
if len(self.quantities()) == 1: | ||
default_qty = self.quantities()[0] | ||
qty = kwargs.get("qty", default_qty) | ||
for lvl_nbr, lvl in self.levels(time).items(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unused loop variable.
The variable lvl
is not used within the loop. You can replace it with _
to indicate it's intentionally unused.
- for lvl_nbr, lvl in self.levels(time).items():
+ for lvl_nbr, _ in self.levels(time).items():
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
for lvl_nbr, lvl in self.levels(time).items(): | |
for lvl_nbr, _ in self.levels(time).items(): |
Tools
Ruff
1034-1034: Loop control variable
lvl
not used within loop body (B007)Rename unused
lvl
to_lvl
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 13
Outside diff range and nitpick comments (20)
tools/python3/git.py (2)
Line range hint
22-22
: Remove unused variable.The variable
e
is assigned but never used, which could lead to confusion and clutter.- except subprocess.CalledProcessError as e: + except subprocess.CalledProcessError:
Line range hint
29-29
: Undefined functiondelete_branch
.The function
delete_branch
is called but not defined within this file or provided in the imports.Please ensure that
delete_branch
is defined elsewhere in the codebase or add its definition.tests/simulator/initialize/test_particles_init_1d.py (1)
Line range hint
33-33
: Remove extraneous parentheses.The parentheses around the dictionary literals are unnecessary and can be removed for cleaner code.
- *per_interp(({"L0": {"B0": Box1D(10, 14)}})), - *per_interp(({"L0": {"B0": Box1D(5, 20)}, "L1": {"B0": Box1D(15, 35)}})), - *per_interp(({"L0": {"B0": Box1D(2, 12), "B1": Box1D(13, 25)}})), + *per_interp({"L0": {"B0": Box1D(10, 14)}}), + *per_interp({"L0": {"B0": Box1D(5, 20)}, "L1": {"B0": Box1D(15, 35)}}), + *per_interp({"L0": {"B0": Box1D(2, 12), "B1": Box1D(13, 25)}}),Also applies to: 34-34, 35-35, 54-54, 55-55, 56-56
tests/simulator/initialize/test_particles_init_2d.py (1)
Line range hint
33-33
: Remove extraneous parentheses.The parentheses around the dictionary literals are unnecessary and can be removed for cleaner code.
- *per_interp(({"L0": {"B0": Box2D(10, 14)}})), - *per_interp(({"L0": {"B0": Box2D(10, 14)}, "L1": {"B0": Box2D(22, 26)}})), - *per_interp(({"L0": {"B0": Box2D(2, 6), "B1": Box2D(7, 11)}})), + *per_interp({"L0": {"B0": Box2D(10, 14)}}), + *per_interp({"L0": {"B0": Box2D(10, 14)}, "L1": {"B0": Box2D(22, 26)}}), + *per_interp({"L0": {"B0": Box2D(2, 6), "B1": Box2D(7, 11)}}),Also applies to: 34-34, 35-35, 58-58, 59-59, 60-60
pyphare/pyphare/core/gridlayout.py (1)
Line range hint
152-155
: Use ternary operator for efficiency.The method to calculate
size
can be optimized using a ternary operator.- if withGhosts: - size = nbrCells[dim] + (nbrGhosts * 2) - else: - size = nbrCells[dim] + size = nbrCells[dim] + (nbrGhosts * 2 if withGhosts else 0)pyphare/pyphare/pharesee/run.py (4)
Line range hint
289-289
: Use f-string for consistency and performance.The use of the
format
method is less efficient and less readable than f-strings, which are the preferred string formatting method in modern Python.- t = "{:.10f}".format(time) + t = f"{time:.10f}"
Line range hint
371-371
: Remove unnecessary f-string prefix.The f-string prefix is used without placeholders, which is not needed and can be misleading.
- def filename(name): - return f"ions_pop_{name}_domain.h5" + def filename(name): + return "ions_pop_" + name + "_domain.h5"Also applies to: 373-373
Line range hint
415-415
: Use f-string for consistency and performance.The use of the
format
method is less efficient and less readable than f-strings, which are the preferred string formatting method in modern Python.- h5_time_grp_key = "t" - h5_filename = "EM_B.h5" # _____ TODO : could be another file - data_file = h5py.File(os.path.join(self.path, h5_filename), "r") - if time is None: - time = float(list(data_file[h5_time_grp_key].keys())[0]) + h5_time_grp_key = "t" + h5_filename = "EM_B.h5" # _____ TODO : could be another file + data_file = h5py.File(os.path.join(self.path, h5_filename), "r") + if time is None: + time = float(list(data_file[h5_time_grp_key].keys())[0])
Line range hint
465-465
: Avoid using mutable default arguments.Using mutable data structures like lists as default arguments can lead to unexpected behavior because they can be modified across multiple function calls.
- def make_interpolator(data, coords, interp, domain, dl, qty, nbrGhosts=[]): + def make_interpolator(data, coords, interp, domain, dl, qty, nbrGhosts=None): + if nbrGhosts is None: + nbrGhosts = []tests/amr/data/field/refine/test_refine_field.py (1)
Line range hint
9-9
: Remove redundant assignment.The variable
refinement_ratio
is defined twice, which is redundant and can lead to confusion.- refinement_ratio = 2
Tools
Ruff
106-106: Do not
assert False
(python -O
removes these calls), raiseAssertionError()
(B011)Replace
assert False
pyphare/pyphare/pharesee/geometry.py (3)
Line range hint
86-187
: Consider renaming the variable for clarity inperiodicity_shifts
.The use of
l
as a variable name in list comprehensions is ambiguous and could be improved for better readability.- f"{k}front": [(v[0], v[1], shape_z) for v in l] for k, l in shifts.items() + f"{k}front": [(v[0], v[1], shape_z) for v in values] for k, values in shifts.items()Tools
Ruff
160-160: Ambiguous variable name:
l
(E741)
163-163: Ambiguous variable name:
l
(E741)
166-166: Ambiguous variable name:
l
(E741)
187-187: Ambiguous variable name:
l
(E741)
Line range hint
441-464
: Unused loop control variable should be renamed for clarity.The variable
pd
is not used within the loop body and should be renamed to_
.- for pd_key, pd in patch.patch_datas.items(): + for pd_key, _ in patch.patch_datas.items():
Line range hint
464-519
: Avoid mutable default arguments inlevel_ghost_boxes
.Using mutable default arguments can lead to bugs. Initialize within the function.
- def level_ghost_boxes(hierarchy, quantities, levelNbrs=[], time=0): + def level_ghost_boxes(hierarchy, quantities, levelNbrs=None, time=0): + if levelNbrs is None: + levelNbrs = []tests/simulator/test_initialization.py (4)
Line range hint
259-359
: Refactor to use f-strings for better readability and performance.The use of
str.format()
is less efficient and less readable compared to f-strings, which are available from Python 3.6 onwards. Consider refactoring these to use f-strings, especially in debug and error messages.- "test_B_is_as_provided_by_user : dim {} interp_order : {}".format(dim, interp_order) + f"test_B_is_as_provided_by_user : dim {dim} interp_order : {interp_order}"Optimize list comprehensions in meshgrid operations.
The unpacked list comprehensions used for meshgrid operations can be replaced with generator expressions to optimize memory usage.
- xbx, ybx, zbx = [a.flatten() for a in np.meshgrid(xbx, ybx, zbx, indexing="ij")] + xbx, ybx, zbx = (a.flatten() for a in np.meshgrid(xbx, ybx, zbx, indexing="ij"))The added support for 3-dimensional testing is in line with the PR's objectives to enhance simulation capabilities. The use of
np.testing.assert_allclose
for precision validation is appropriate and ensures that the simulation results are as expected.Tools
Ruff
338-340: Replace unpacked list comprehension with a generator expression (UP027)
Replace with generator expression
341-343: Replace unpacked list comprehension with a generator expression (UP027)
Replace with generator expression
344-346: Replace unpacked list comprehension with a generator expression (UP027)
Replace with generator expression
Line range hint
360-421
: Consider simplifying the function definition.The function contains complex logic for calculating expected and actual velocities. Consider breaking down the function into smaller, more manageable parts or utility functions to enhance readability and maintainability.
def calculate_expected_velocity(nprot, vx_fn, select): return (nprot(*select) * vx_fn(*select) + nbeam(*select) * vx_fn(*select)) / (nprot(*select) + nbeam(*select))Use direct comparison instead of Yoda conditions.
In Python, it's more idiomatic to write conditions in a natural order rather than using Yoda conditions.
- self.assertTrue(np.std(vexp - vact) < 1e-2) + self.assertLess(np.std(vexp - vact), 1e-2)The method correctly handles the complexities of 3D data and performs necessary calculations to ensure the accuracy of the simulation results. The use of direct array operations and numpy functions is appropriate for the operations performed.
Tools
Ruff
387-387: Use f-string instead of
format
call (UP032)Convert to f-string
399-399: Function definition does not bind loop variable
select
(B023)
401-401: Function definition does not bind loop variable
patch
(B023)
401-401: Function definition does not bind loop variable
nbrGhosts
(B023)
402-402: Function definition does not bind loop variable
select
(B023)
Line range hint
422-484
: Refactor to use f-strings for better readability.The code uses older
.format()
syntax for string operations, which can be updated to f-strings for improved readability and performance.- f"test_density_is_as_provided_by_user : dim {ndim} interp_order {interp_order}" + f"test_density_is_as_provided_by_user : dim {ndim} interp_order {interp_order}"Optimize list comprehensions in meshgrid operations.
Similar to previous methods, replacing unpacked list comprehensions with generator expressions can save memory and potentially improve performance.
- select = tuple([slice(nbrGhosts, -nbrGhosts) for i in range(ndim)]) + select = tuple(slice(nbrGhosts, -nbrGhosts) for i in range(ndim))The method's implementation aligns with the objectives of testing density calculations in simulations accurately. The empirical deviations used for assertions ensure that the simulation results are within acceptable limits.
Tools
Ruff
387-387: Use f-string instead of
format
call (UP032)Convert to f-string
399-399: Function definition does not bind loop variable
select
(B023)
401-401: Function definition does not bind loop variable
patch
(B023)
401-401: Function definition does not bind loop variable
nbrGhosts
(B023)
402-402: Function definition does not bind loop variable
select
(B023)
Line range hint
488-566
: Refactor to use f-strings and improve code readability.The method uses older
.format()
syntax which can be updated to f-strings for improved readability and performance. Additionally, consider adding comments or documentation to explain the plotting logic and its relevance to the test.- plt.title(r"$\sigma =$ {}".format(noise[inbr])) + plt.title(r"$\sigma =$ {noise[inbr]}")The method effectively demonstrates how density noise decreases with increasing particle counts, which is crucial for validating the physical accuracy of the simulation. The use of matplotlib for plotting is appropriate and helps in visual verification of the results.
Tools
Ruff
539-539: Use f-string instead of
format
call (UP032)Convert to f-string
tests/simulator/test_advance.py (3)
Line range hint
33-33
: Refactor lambda expression to a function for better readability and maintainability.The lambda function used here can be replaced with a regular function for clarity. Additionally, consider passing
sim
as an argument to the_density
function to improve encapsulation and testability.- _ = lambda i: -((xyz[i] - hL[i]) ** 2) + def square_difference(i, xyz, hL): + return -((xyz[i] - hL[i]) ** 2)Tools
Ruff
87-87: Ambiguous variable name:
l
(E741)
Line range hint
48-48
: Avoid using mutable default arguments.Using mutable default arguments can lead to unexpected behavior. Initialize these within the function instead.
- def getHierarchy(self, ndim, interp_order, refinement_boxes, qty, nbr_part_per_cell=100, density=_density, smallest_patch_size=None, largest_patch_size=20, cells=120, time_step=0.001, model_init={}, dl=0.2, extra_diag_options={}, time_step_nbr=1, timestamps=None, block_merging_particles=False, diag_outputs=""): + def getHierarchy(self, ndim, interp_order, refinement_boxes, qty, nbr_part_per_cell=100, density=_density, smallest_patch_size=None, largest_patch_size=20, cells=120, time_step=0.001, model_init=None, dl=0.2, extra_diag_options=None, time_step_nbr=1, timestamps=None, block_merging_particles=False, diag_outputs=""): + if model_init is None: + model_init = {} + if extra_diag_options is None: + extra_diag_options = {}Also applies to: 50-50
Tools
Ruff
87-87: Ambiguous variable name:
l
(E741)
Line range hint
407-409
: Improve readability and maintainability.Replace magic number and use f-string for better readability.
+ MAGIC_NUMBER = -144123 - boxm.DataSelector(afterCoarse)[dataBox] = -144123 + boxm.DataSelector(afterCoarse)[dataBox] = MAGIC_NUMBER - print("test_field_coarsening_via_subcycles for dim/interp : {}/{}".format(dim, interp_order)) + print(f"test_field_coarsening_via_subcycles for dim/interp : {dim}/{interp_order}")Also applies to: 498-498
Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Files selected for processing (44)
- .github/workflows/cmake_macos.yml (1 hunks)
- pyphare/pyphare/core/box.py (2 hunks)
- pyphare/pyphare/core/gridlayout.py (1 hunks)
- pyphare/pyphare/pharesee/geometry.py (7 hunks)
- pyphare/pyphare/pharesee/hierarchy.py (3 hunks)
- pyphare/pyphare/pharesee/run.py (1 hunks)
- res/amr/splitting.yml (1 hunks)
- res/cmake/options.cmake (1 hunks)
- src/amr/data/field/coarsening/magnetic_field_coarsener.hpp (1 hunks)
- src/amr/data/particles/refine/split.hpp (1 hunks)
- src/amr/data/particles/refine/split_1d.hpp (10 hunks)
- src/amr/data/particles/refine/split_2d.hpp (17 hunks)
- src/amr/data/particles/refine/split_3d.hpp (1 hunks)
- src/amr/data/particles/refine/splitter.hpp (2 hunks)
- src/core/data/grid/gridlayoutdefs.hpp (2 hunks)
- src/core/data/ndarray/ndarray_vector.hpp (8 hunks)
- src/core/utilities/box/box.hpp (3 hunks)
- src/core/utilities/meta/meta_utilities.hpp (2 hunks)
- tests/amr/data/field/refine/test_refine_field.py (1 hunks)
- tests/amr/data/particles/refine/input/input_3d_ratio_2.txt (1 hunks)
- tests/amr/data/particles/refine/test_split.cpp (1 hunks)
- tests/core/data/ndarray/test_main.cpp (1 hunks)
- tests/core/numerics/interpolator/test_main.cpp (1 hunks)
- tests/diagnostic/CMakeLists.txt (1 hunks)
- tests/diagnostic/job_3d.py.in (1 hunks)
- tests/diagnostic/test-diagnostics_3d.cpp (1 hunks)
- tests/functional/harris/harris_3d.py (1 hunks)
- tests/simulator/init.py (2 hunks)
- tests/simulator/advance/CMakeLists.txt (1 hunks)
- tests/simulator/advance/test_fields_advance_3d.py (1 hunks)
- tests/simulator/advance/test_particles_advance_3d.py (1 hunks)
- tests/simulator/initialize/CMakeLists.txt (1 hunks)
- tests/simulator/initialize/test_fields_init_2d.py (1 hunks)
- tests/simulator/initialize/test_fields_init_3d.py (1 hunks)
- tests/simulator/initialize/test_particles_init_1d.py (1 hunks)
- tests/simulator/initialize/test_particles_init_2d.py (1 hunks)
- tests/simulator/initialize/test_particles_init_3d.py (1 hunks)
- tests/simulator/per_test.hpp (1 hunks)
- tests/simulator/refined_particle_nbr.py (2 hunks)
- tests/simulator/test_advance.py (7 hunks)
- tests/simulator/test_initialization.py (14 hunks)
- tools/python3/init.py (5 hunks)
- tools/python3/cmake.py (2 hunks)
- tools/python3/git.py (1 hunks)
Files skipped from review as they are similar to previous changes (25)
- .github/workflows/cmake_macos.yml
- res/amr/splitting.yml
- res/cmake/options.cmake
- src/amr/data/particles/refine/split.hpp
- src/amr/data/particles/refine/split_1d.hpp
- src/amr/data/particles/refine/split_2d.hpp
- src/amr/data/particles/refine/splitter.hpp
- src/core/data/grid/gridlayoutdefs.hpp
- src/core/data/ndarray/ndarray_vector.hpp
- src/core/utilities/box/box.hpp
- src/core/utilities/meta/meta_utilities.hpp
- tests/amr/data/particles/refine/input/input_3d_ratio_2.txt
- tests/amr/data/particles/refine/test_split.cpp
- tests/core/data/ndarray/test_main.cpp
- tests/core/numerics/interpolator/test_main.cpp
- tests/diagnostic/CMakeLists.txt
- tests/diagnostic/job_3d.py.in
- tests/diagnostic/test-diagnostics_3d.cpp
- tests/simulator/advance/CMakeLists.txt
- tests/simulator/advance/test_fields_advance_3d.py
- tests/simulator/advance/test_particles_advance_3d.py
- tests/simulator/initialize/CMakeLists.txt
- tests/simulator/initialize/test_fields_init_2d.py
- tests/simulator/initialize/test_fields_init_3d.py
- tests/simulator/per_test.hpp
Additional context used
Path-based instructions (2)
src/amr/data/field/coarsening/magnetic_field_coarsener.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/amr/data/particles/refine/split_3d.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.
Ruff
tools/python3/git.py
22-22: Local variable
e
is assigned to but never used (F841)Remove assignment to unused variable
e
29-29: Undefined name
delete_branch
(F821)tools/python3/cmake.py
48-48: Undefined name
cmd
(F821)tests/simulator/initialize/test_particles_init_1d.py
33-33: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
34-34: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
35-35: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
54-54: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
55-55: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
56-56: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
tools/python3/__init__.py
45-45: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling (B904)
46-46: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling (B904)
95-95: Do not use mutable data structures for argument defaults (B006)
Replace with
None
; initialize within function
111-111: Module level import not at top of file (E402)
tests/simulator/initialize/test_particles_init_2d.py
33-33: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
34-34: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
35-35: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
58-58: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
59-59: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
60-60: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
tests/simulator/initialize/test_particles_init_3d.py
35-35: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
36-36: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
37-37: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
60-60: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
61-61: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
62-62: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
tests/functional/harris/harris_3d.py
62-62: Ambiguous variable name:
l
(E741)tests/simulator/refined_particle_nbr.py
9-9: Module level import not at top of file (E402)
10-10: Module level import not at top of file (E402)
11-11: Module level import not at top of file (E402)
13-13: Module level import not at top of file (E402)
14-14: Module level import not at top of file (E402)
15-15: Module level import not at top of file (E402)
16-16: Module level import not at top of file (E402)
18-18: Module level import not at top of file (E402)
18-18:
tests.simulator.NoOverwriteDict
imported but unused (F401)Remove unused import:
tests.simulator.NoOverwriteDict
19-19: Module level import not at top of file (E402)
24-24: Use
super()
instead ofsuper(__class__, self)
(UP008)Remove
__super__
parameters
26-26: Unnecessary open mode parameters (UP015)
Remove open mode parameters
44-44: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
61-61: Loop control variable
pop
not used within loop body (B007)Rename unused
pop
to_pop
63-63: Loop control variable
key
not used within loop body (B007)Rename unused
key
to_key
pyphare/pyphare/core/box.py
11-11: Replace unpacked list comprehension with a generator expression (UP027)
Replace with generator expression
41-41: Use f-string instead of
format
call (UP032)Convert to f-string
76-76: Ambiguous variable name:
l
(E741)
84-84: Ambiguous variable name:
l
(E741)
89-89: Ambiguous variable name:
l
(E741)
94-94: Ambiguous variable name:
l
(E741)
207-207: Ambiguous variable name:
l
(E741)tests/simulator/__init__.py
3-3: Multiple imports on one line (E401)
Split imports
26-26: Use
super()
instead ofsuper(__class__, self)
(UP008)Remove
__super__
parameters
76-76: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
122-122: Do not use mutable data structures for argument defaults (B006)
Replace with
None
; initialize within function
182-182: Undefined name
Box
(F821)
188-188: Undefined name
Box
(F821)
195-195: Undefined name
Box
(F821)
236-236: Use
super()
instead ofsuper(__class__, self)
(UP008)Remove
__super__
parameters
273-273: Multiple imports on one line (E401)
Split imports
275-275: Do not use mutable data structures for argument defaults (B006)
Replace with
None
; initialize within functionpyphare/pyphare/core/gridlayout.py
131-131: Class
YeeCentering
inherits fromobject
(UP004)Remove
object
inheritance
152-155: Use ternary operator
size = nbrCells[dim] + nbrGhosts * 2 if withGhosts else nbrCells[dim]
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withsize = nbrCells[dim] + nbrGhosts * 2 if withGhosts else nbrCells[dim]
168-168: Class
GridLayout
inherits fromobject
(UP004)Remove
object
inheritance
176-176: Do not perform function call
Box
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable (B008)pyphare/pyphare/pharesee/run.py
289-289: Use f-string instead of
format
call (UP032)Convert to f-string
371-371: f-string without any placeholders (F541)
Remove extraneous
f
prefix
373-373: f-string without any placeholders (F541)
Remove extraneous
f
prefix
415-415: Use f-string instead of
format
call (UP032)Convert to f-string
465-465: Do not use mutable data structures for argument defaults (B006)
Replace with
None
; initialize within functiontests/amr/data/field/refine/test_refine_field.py
9-9: Redefinition of unused
refinement_ratio
from line 5 (F811)
106-106: Do not
assert False
(python -O
removes these calls), raiseAssertionError()
(B011)Replace
assert False
pyphare/pyphare/pharesee/geometry.py
160-160: Ambiguous variable name:
l
(E741)
163-163: Ambiguous variable name:
l
(E741)
166-166: Ambiguous variable name:
l
(E741)
187-187: Ambiguous variable name:
l
(E741)
418-418: Do not use mutable data structures for argument defaults (B006)
Replace with
None
; initialize within function
441-441: Loop control variable
pd
not used within loop body (B007)Rename unused
pd
to_pd
464-464: Do not use mutable data structures for argument defaults (B006)
Replace with
None
; initialize within functiontests/simulator/test_initialization.py
5-5: Module level import not at top of file (E402)
7-7: Module level import not at top of file (E402)
8-8: Module level import not at top of file (E402)
9-9: Module level import not at top of file (E402)
10-10: Module level import not at top of file (E402)
11-11: Module level import not at top of file (E402)
12-16: Module level import not at top of file (E402)
17-17: Module level import not at top of file (E402)
18-18: Module level import not at top of file (E402)
19-19: Module level import not at top of file (E402)
20-20: Module level import not at top of file (E402)
21-21: Module level import not at top of file (E402)
23-23: Module level import not at top of file (E402)
32-32: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
44-44: Do not use mutable data structures for argument defaults (B006)
Replace with
None
; initialize within function
93-93: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
98-98: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
103-103: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
108-108: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
113-113: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
261-263: Use f-string instead of
format
call (UP032)Convert to f-string
289-289: Use f-string instead of
format
call (UP032)Convert to f-string
315-317: Replace unpacked list comprehension with a generator expression (UP027)
Replace with generator expression
318-320: Replace unpacked list comprehension with a generator expression (UP027)
Replace with generator expression
321-323: Replace unpacked list comprehension with a generator expression (UP027)
Replace with generator expression
338-340: Replace unpacked list comprehension with a generator expression (UP027)
Replace with generator expression
341-343: Replace unpacked list comprehension with a generator expression (UP027)
Replace with generator expression
344-346: Replace unpacked list comprehension with a generator expression (UP027)
Replace with generator expression
385-385: Use f-string instead of
format
call (UP032)Convert to f-string
387-387: Use f-string instead of
format
call (UP032)Convert to f-string
399-399: Function definition does not bind loop variable
select
(B023)
401-401: Function definition does not bind loop variable
patch
(B023)
401-401: Function definition does not bind loop variable
nbrGhosts
(B023)
402-402: Function definition does not bind loop variable
select
(B023)
450-450: Use f-string instead of
format
call (UP032)Convert to f-string
452-452: Use f-string instead of
format
call (UP032)Convert to f-string
457-457: Local variable
x
is assigned to but never used (F841)Remove assignment to unused variable
x
539-539: Use f-string instead of
format
call (UP032)Convert to f-string
587-587: Loop control variable
pi
not used within loop body (B007)Rename unused
pi
to_pi
591-591: Yoda conditions are discouraged, use
ppc == H
instead (SIM300)Replace Yoda condition with
ppc == H
596-596: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
613-615: Use f-string instead of
format
call (UP032)Convert to f-string
658-658: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
669-669: Local variable
out
is assigned to but never used (F841)Remove assignment to unused variable
out
tests/simulator/test_advance.py
5-5: Module level import not at top of file (E402)
7-7: Module level import not at top of file (E402)
8-8: Module level import not at top of file (E402)
9-9: Module level import not at top of file (E402)
10-10: Module level import not at top of file (E402)
11-11: Module level import not at top of file (E402)
12-12: Module level import not at top of file (E402)
13-17: Module level import not at top of file (E402)
18-18: Module level import not at top of file (E402)
19-19: Module level import not at top of file (E402)
20-20: Module level import not at top of file (E402)
21-21: Module level import not at top of file (E402)
23-23: Module level import not at top of file (E402)
24-24: Module level import not at top of file (E402)
33-33: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
48-48: Do not use mutable data structures for argument defaults (B006)
Replace with
None
; initialize within function
50-50: Do not use mutable data structures for argument defaults (B006)
Replace with
None
; initialize within function
87-87: Ambiguous variable name:
l
(E741)
95-95: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
100-100: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
105-105: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
110-110: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
115-115: Do not assign a
lambda
expression, use adef
(E731)Rewrite
_
as adef
251-251: Loop control variable
ilvl
not used within loop body (B007)Rename unused
ilvl
to_ilvl
320-322: Use f-string instead of
format
call (UP032)Convert to f-string
345-345: Loop control variable
lvl
not used within loop body (B007)Rename unused
lvl
to_lvl
346-346: Use f-string instead of
format
call (UP032)Convert to f-string
407-409: Use f-string instead of
format
call (UP032)Convert to f-string
519-519: Use f-string instead of
format
call (UP032)Convert to f-string
686-688: Use f-string instead of
format
call (UP032)Convert to f-string
695-695: Do not use mutable data structures for argument defaults (B006)
Replace with
None
; initialize within function
710-710: f-string without any placeholders (F541)
Remove extraneous
f
prefix
711-711: f-string without any placeholders (F541)
Remove extraneous
f
prefix
739-739:
pyphare.pharein
imported but unused (F401)Remove unused import:
pyphare.pharein
744-744: Local variable
out
is assigned to but never used (F841)Remove assignment to unused variable
out
pyphare/pyphare/pharesee/hierarchy.py
82-84: Use f-string instead of
format
call (UP032)Convert to f-string
203-203: Use f-string instead of
format
call (UP032)Convert to f-string
508-508: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
520-520: Loop control variable
ip
not used within loop body (B007)Rename unused
ip
to_ip
557-557: Class
PatchHierarchy
inherits fromobject
(UP004)Remove
object
inheritance
621-621: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling (B904)
651-651: Comparison to
None
should becond is None
(E711)Replace with
cond is None
726-726: Loop control variable
time
not used within loop body (B007)Rename unused
time
to_time
727-727: Loop control variable
ilvl
not used within loop body (B007)Rename unused
ilvl
to_ilvl
746-746: Loop control variable
ilvl
not used within loop body (B007)Rename unused
ilvl
to_ilvl
760-760: Loop control variable
ilvl
not used within loop body (B007)Rename unused
ilvl
to_ilvl
781-781: Use f-string instead of
format
call (UP032)Convert to f-string
790-790: Loop control variable
t
not used within loop body (B007)Rename unused
t
to_t
792-792: Use f-string instead of
format
call (UP032)Convert to f-string
906-906: Use f-string instead of
format
call (UP032)Convert to f-string
960-960: Loop control variable
lvl
not used within loop body (B007)Rename unused
lvl
to_lvl
1034-1034: Loop control variable
lvl
not used within loop body (B007)Rename unused
lvl
to_lvl
1099-1099: Loop control variable
ip
not used within loop body (B007)Rename unused
ip
to_ip
1281-1281: Loop control variable
ip
not used within loop body (B007)Rename unused
ip
to_ip
1390-1390: Use f-string instead of
format
call (UP032)Convert to f-string
1395-1395: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1400-1402: Use f-string instead of
format
call (UP032)Convert to f-string
1413-1413: Use f-string instead of
format
call (UP032)Convert to f-string
1453-1453: Use f-string instead of
format
call (UP032)Convert to f-string
1459-1459: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1468-1468: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1490-1490: Use f-string instead of
format
call (UP032)Convert to f-string
1505-1505: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1538-1538: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1544-1544: Loop control variable
ipatch
not used within loop body (B007)
1561-1561: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1718-1718: Use f-string instead of
format
call (UP032)Convert to f-string
1765-1765: Loop control variable
time
not used within loop body (B007)Rename unused
time
to_time
1766-1766: Loop control variable
ilvl
not used within loop body (B007)Rename unused
ilvl
to_ilvl
1767-1767: Loop control variable
ip
not used within loop body (B007)Rename unused
ip
to_ip
1820-1820: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
Additional comments not posted (22)
tools/python3/git.py (1)
14-14
: Approved: Enhanced log formatting.The conditional formatting based on
use_short
is a flexible approach to handle different logging needs.tools/python3/__init__.py (1)
9-27
: Approved:RunTimer
class implementation.The
RunTimer
class provides a structured way to execute commands and measure their execution time, enhancing the modularity of the code.tests/simulator/initialize/test_particles_init_3d.py (3)
25-26
: Class Definition: Proper Inheritance and Use of DecoratorsThe
Initialization3DTest
class correctly inherits fromInitializationTest
. The use of the@ddt
decorator is appropriate for data-driven tests.
77-94
: Consider Removing or Documenting Commented-out CodeThe commented-out test cases should either be removed for clarity or properly documented if they are intended for future use. This aligns with previous comments on this section.
97-98
: Main Execution BlockThe
unittest.main()
call in the main execution block is standard practice for a Python test script, allowing it to be run standalone.tests/functional/harris/harris_3d.py (3)
37-52
: Simulation Configuration FunctionThe
config
function sets up a simulation with detailed configuration parameters. The use of dictionary fordiag_options
is clear and effective. The commented-outstrict
option should either be removed or uncommented if needed.
62-62
: Ambiguous Variable NamingThe variable name
l
is ambiguous and could be confused with the number1
. Consider renaming it tolength
for clarity.Tools
Ruff
62-62: Ambiguous variable name:
l
(E741)
174-178
: Main Function and Plotting IntegrationThe
main
function integrates configuration, simulation execution, and plotting. It checks for the MPI rank to ensure that plotting is only done by the master process, which is a good practice in parallel computations.tests/simulator/refined_particle_nbr.py (4)
33-37
: TearDown MethodThe
tearDown
method correctly resets the simulator instance if it's notNone
. This is essential for cleaning up after each test case.
78-117
: Clarify Calculations in Test MethodsThe calculations within the
_do_dim
method are crucial for ensuring the correct number of particles are refined. Adding comments to explain these calculations will improve code clarity and maintainability.
130-135
: Test Values MethodThe
test_values
method is well-implemented, using a loop through dimensions and interpolation orders to check delta and weights. Consider adding comments to explain the logic behind these checks for future maintainers.
139-144
: Custom Test Suite ConfigurationThe custom configuration of the test suite ensures that delta/weight verification tests run before dimensional tests. This is a good practice to catch fundamental errors early.
pyphare/pyphare/core/box.py (3)
65-67
: List Subtraction in__sub__
MethodThe method handles list subtraction by calling
remove_all
. Ensure that the input validation (checking all items are instances ofBox
) is robust.
185-198
:remove_all
FunctionThis function provides a robust mechanism for removing multiple boxes. Consider adding unit tests to cover various scenarios, such as partial overlaps or complete containment.
206-223
: Data Selector ClassThe
DataSelector
class provides a flexible way to select and set data within a box. The implementation is clear, and the use of item assignment is correctly handled.Tools
Ruff
207-207: Ambiguous variable name:
l
(E741)tests/simulator/__init__.py (2)
96-106
: Density calculation in 3D is implemented correctly.The implementation of
density_3d_periodic
correctly calculates the 3D density distribution using numpy operations. Consider parameterizing thebackground_particles
value to enhance flexibility and configurability.
268-295
: Debugging tracer function implemented correctly.The
debug_tracer
function correctly sets a profiling function to track function calls and returns. Consider adding error handling to manage potential issues during profiling, such as exceptions in the traced functions.Tools
Ruff
273-273: Multiple imports on one line (E401)
Split imports
275-275: Do not use mutable data structures for argument defaults (B006)
Replace with
None
; initialize within functionsrc/amr/data/field/coarsening/magnetic_field_coarsener.hpp (1)
40-40
: Initialization of class members in constructor.The constructor initializes the class members directly. Consider using a member initializer list for better performance and clarity.
[REFACTOR_SUGGESTion]- MagneticFieldCoarsener(std::array<core::QtyCentering, dim> const centering, - SAMRAI::hier::Box const& sourceBox, - SAMRAI::hier::Box const& destinationBox, - SAMRAI::hier::IntVector const& ratio) - : centering_{centering} - , sourceBox_{sourceBox} - , destinationBox_{destinationBox} - { - } + MagneticFieldCoarsener(std::array<core::QtyCentering, dim> const& centering, + SAMRAI::hier::Box const& sourceBox, + SAMRAI::hier::Box const& destinationBox, + SAMRAI::hier::IntVector const& ratio) + : centering_(centering), + sourceBox_(sourceBox), + destinationBox_(destinationBox), + ratio_(ratio) + {}pyphare/pyphare/pharesee/geometry.py (2)
58-73
: 3D handling indomain_border_ghost_boxes
looks good.The function now properly handles 3D cases, which aligns with the PR's objectives to enhance 3D simulation capabilities.
Line range hint
289-519
: Complex logic incompute_overlaps
handled well.The function effectively manages the complexity of computing overlaps in a domain with periodic boundary conditions, which is crucial for the simulation's accuracy.
tests/simulator/test_advance.py (2)
375-377
: Particle number conservation test looks good.This method correctly implements a check for particle number conservation over time steps.
Line range hint
686-688
: Field level ghost comparison test looks good.This method correctly implements a comparison of field values at different refinement levels.
Tools
Ruff
87-87: Ambiguous variable name:
l
(E741)
def plot3d(self, **kwargs): | ||
"""!HAX!""" | ||
time = kwargs.get("time", self._default_time()) | ||
usr_lvls = kwargs.get("levels", self.levelNbrs(time)) | ||
default_qty = None | ||
if len(self.quantities()) == 1: | ||
default_qty = self.quantities()[0] | ||
qty = kwargs.get("qty", default_qty) | ||
for lvl_nbr, lvl in self.levels(time).items(): | ||
if lvl_nbr not in usr_lvls: | ||
continue | ||
for patch in self.level(lvl_nbr, time).patches: | ||
pdat = patch.patch_datas[qty] | ||
primals = pdat.primal_directions() | ||
if primals[0]: | ||
pdat._x = pdat.x[:-1] | ||
if primals[1]: | ||
pdat._y = pdat.y[:-1] | ||
pdat.dataset = pdat.dataset[:, :, int(pdat.ghost_box.shape[2] / 2)] | ||
patch.box.lower = patch.box.lower[:-1] | ||
patch.box.upper = patch.box.upper[:-1] | ||
patch.box.ndim = 2 | ||
|
||
pdat.ghost_box.lower = pdat.ghost_box.lower[:-1] | ||
pdat.ghost_box.upper = pdat.ghost_box.upper[:-1] | ||
pdat.ghost_box.ndim = 2 | ||
pdat.size = np.copy(pdat.ghost_box.shape) | ||
pdat.layout.dl = pdat.layout.dl[:-1] | ||
|
||
return self.plot2d(**kwargs) # ¯\_(ツ)_/¯ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review the plot3d
method for potential data handling issues.
The plot3d
method manipulates data dimensions and properties directly which may lead to unintended side effects or data corruption. Specifically:
- Modifying
pdat._x
,pdat._y
, andpdat.dataset
directly affects the object state outside the local scope of this function, potentially impacting other parts of the application relying on these properties. - The method reduces the dimensionality of the data to 2D and delegates to
plot2d
. Ensure that this dimensional reduction is valid across all use cases.
Consider encapsulating these transformations in a method within the relevant data classes to avoid side effects.
- pdat._x = pdat.x[:-1]
- pdat._y = pdat.y[:-1]
- pdat.dataset = pdat.dataset[:, :, int(pdat.ghost_box.shape[2] / 2)]
+ # Example method inside the relevant data class
+ pdat.reduce_dimension(2) # Reduce to 2D by selecting the middle slice
Committable suggestion was skipped due to low confidence.
Tools
Ruff
1034-1034: Loop control variable
lvl
not used within loop body (B007)Rename unused
lvl
to_lvl
typename std::enable_if<D == 3, void>::type | ||
coarsen(Point_t const fineStartIndex, FieldT const& fineField, FieldT& coarseField, | ||
Point_t const coarseIndex); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implement 3D coarsening logic.
The 3D coarsening method is crucial for the project's focus on 3D functionalities but is currently not implemented. This needs to be addressed to meet the PR objectives.
89a90,93
+ // TODO: Implement the 3D coarsening logic here
+ throw std::runtime_error("3D coarsening not implemented.");
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
typename std::enable_if<D == 3, void>::type | |
coarsen(Point_t const fineStartIndex, FieldT const& fineField, FieldT& coarseField, | |
Point_t const coarseIndex); | |
typename std::enable_if<D == 3, void>::type | |
coarsen(Point_t const fineStartIndex, FieldT const& fineField, FieldT& coarseField, | |
Point_t const coarseIndex) { | |
// TODO: Implement the 3D coarsening logic here | |
throw std::runtime_error("3D coarsening not implemented."); | |
} |
self, ndim, interp_order, ppc=100, **kwargs | ||
): | ||
ddt_test_id = self.ddt_test_id() | ||
datahier = self.getHierarchy( | ||
dim, | ||
ndim, | ||
interp_order, | ||
{"L0": {"B0": nDBox(dim, 10, 20)}}, | ||
{}, | ||
"particles", | ||
diag_outputs=f"ppc/{ndim}/{interp_order}/{ddt_test_id}", | ||
nbr_part_per_cell=ppc, | ||
**kwargs, | ||
) | ||
|
||
for patch in datahier.level(0).patches: | ||
if cpp.mpi_rank() > 0: | ||
return | ||
|
||
for pi, patch in enumerate(datahier.level(0).patches): | ||
pd = patch.patch_datas["protons_particles"] | ||
icells = pd.dataset[patch.box].iCells | ||
H, _ = np.histogramdd(icells) | ||
self.assertTrue((H == default_ppc).all()) | ||
H, edges = np.histogramdd(icells, bins=patch.box.shape) | ||
self.assertTrue((H == ppc).all()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use direct comparison instead of Yoda conditions.
In Python, it's more idiomatic to write conditions in a natural order rather than using Yoda conditions. This enhances readability and conforms to common Python practices.
- self.assertTrue((H == ppc).all())
+ self.assertTrue(ppc == H)
The method correctly checks if the number of particles per cell is as provided, ensuring the accuracy of particle distribution in the simulation. This is crucial for the reliability of simulation results.
Committable suggestion was skipped due to low confidence.
Tools
Ruff
587-587: Loop control variable
pi
not used within loop body (B007)Rename unused
pi
to_pi
591-591: Yoda conditions are discouraged, use
ppc == H
instead (SIM300)Replace Yoda condition with
ppc == H
*per_interp(({"L0": {"B0": Box3D(10, 14)}})), | ||
*per_interp(({"L0": {"B0": Box3D(10, 14)}, "L1": {"B0": Box3D(22, 26)}})), | ||
*per_interp(({"L0": {"B0": Box3D(2, 6), "B1": Box3D(7, 11)}})), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove Extraneous Parentheses
The static analysis tool has flagged unnecessary parentheses around the dictionary in the per_interp
function calls. Simplifying these will enhance readability.
- *per_interp(({"L0": {"B0": Box3D(10, 14)}})),
- *per_interp(({"L0": {"B0": Box3D(5, 14)}, "L1": {"B0": Box3D(15, 19)}})),
- *per_interp(({"L0": {"B0": Box3D(2, 12), "B1": Box3D(13, 25)}})),
+ *per_interp({"L0": {"B0": Box3D(10, 14)}}),
+ *per_interp({"L0": {"B0": Box3D(5, 14), "L1": {"B0": Box3D(15, 19)}}),
+ *per_interp({"L0": {"B0": Box3D(2, 12), "B1": Box3D(13, 25)}}),
Also applies to: 60-62
Tools
Ruff
35-35: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
36-36: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
37-37: Avoid extraneous parentheses (UP034)
Remove extraneous parentheses
@@ -48,4 +46,3 @@ def test_cmd(test, verbose=False): | |||
|
|||
def run_test(test, verbose=False, capture_output=False): | |||
run(test_cmd(cmd, verbose=verbose), capture_output=capture_output) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix the undefined variable issue in run_test
function.
The cmd
variable is used but not defined within the run_test
function. This will cause a runtime error when this function is called.
- run(test_cmd(cmd, verbose=verbose), capture_output=capture_output)
+ run(test_cmd(test, verbose=verbose), capture_output=capture_output)
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
run(test_cmd(cmd, verbose=verbose), capture_output=capture_output) | |
run(test_cmd(test, verbose=verbose), capture_output=capture_output) |
Tools
Ruff
48-48: Undefined name
cmd
(F821)
tools/python3/__init__.py
Outdated
raise RuntimeError(decode_bytes(e.stderr)) | ||
raise RuntimeError(what) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use raise ... from
syntax for clearer exception chaining.
When re-raising exceptions, it's better to use the raise ... from
syntax to make the chain of errors clear, avoiding confusion with exception handling itself.
- raise RuntimeError(decode_bytes(e.stderr))
+ raise RuntimeError(decode_bytes(e.stderr)) from e
- raise RuntimeError(what)
+ raise RuntimeError(what) from None
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
raise RuntimeError(decode_bytes(e.stderr)) | |
raise RuntimeError(what) | |
raise RuntimeError(decode_bytes(e.stderr)) from e | |
raise RuntimeError(what) from None |
Tools
Ruff
45-45: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling (B904)
46-46: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling (B904)
9769e13
to
753eb43
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 27
Outside diff range, codebase verification and nitpick comments (27)
tests/amr/data/particles/refine/input/input_3d_ratio_2.txt (1)
46-51
: Remove unused sections in the configuration file.The
TileClustering
andGriddingAlgorithm
sections are empty and should be removed if they are not required, to avoid confusion.- TileClustering - { - } - GriddingAlgorithm - { - }tests/diagnostic/CMakeLists.txt (1)
37-37
: Implementation fortest-diagnostics_3d
is missing.The search results indicate that while
test-diagnostics_3d
is referenced intests/diagnostic/CMakeLists.txt
, there is no actual implementation found for this test. Please ensure that the implementation fortest-diagnostics_3d
is added to the codebase.
tests/diagnostic/CMakeLists.txt
:_add_diagnostics_test(test-diagnostics_3d)
Analysis chain
LGTM! Ensure the 3D diagnostics test is properly implemented.
The new addition for 3D diagnostics test follows the existing pattern and looks correct.
However, ensure that the
test-diagnostics_3d
is properly implemented and tested.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the implementation of `test-diagnostics_3d`. # Test: Search for the implementation. Expect: The implementation is found and looks correct. rg --type cpp -A 5 'test-diagnostics_3d'Length of output: 40
Script:
#!/bin/bash # Description: Verify the implementation of `test-diagnostics_3d`. # Test: Search for the implementation across all file types. rg 'test-diagnostics_3d' # Test: Search for related diagnostic test functions to ensure the test is properly implemented. rg '_add_diagnostics_test'Length of output: 503
tests/simulator/advance/test_particles_advance_3d.py (2)
1-4
: Enhance the file-level docstring.The docstring could be more descriptive about the specific 3D test cases that this file contains.
""" This file exists independently from test_advance.py to isolate dimension test cases and allow each to be overridden in some way if required. """ +""" + This file contains 3D particle advancement test cases. It isolates these tests + from the 2D cases to allow for specific 3D configurations and overrides. +"""
26-44
: Add docstrings to the test methods.Each test method could use a docstring to explain its purpose and the structure of the returned data.
@ddt class AdvanceTest(AdvanceTestBase): @data( *per_interp({}), *per_interp({"L0": [Box3D(10, 19)]}), *per_interp({"L0": [Box3D(5, 9), Box3D(10, 14)]}), ) @unpack def test_overlapped_particledatas_have_identical_particles( self, interp_order, refinement_boxes ): + """ + Test that overlapped particle data have identical particles. + """ self._test_overlapped_particledatas_have_identical_particles( ndim, interp_order, refinement_boxes, ppc=ppc, cells=40, largest_patch_size=20, ) @data(*interp_orders) def test_L0_particle_number_conservation(self, interp): + """ + Test L0 particle number conservation. + """ self._test_L0_particle_number_conservation(ndim, interp, ppc=ppc, cells=30)tests/simulator/initialize/test_fields_init_3d.py (2)
1-4
: Enhance the file-level docstring.The docstring could be more descriptive about the specific 3D test cases that this file contains.
""" This file exists independently from test_initialization.py to isolate dimension test cases and allow each to be overridden in some way if required. """ +""" + This file contains 3D field initialization test cases. It isolates these tests + from the 2D cases to allow for specific 3D configurations and overrides. +"""
22-46
: Add docstrings to the test methods.Each test method could use a docstring to explain its purpose and the structure of the returned data.
@ddt class Initialization3DTest(InitializationTest): @data(*interp_orders) def test_B_is_as_provided_by_user(self, interp_order): + """ + Test that the magnetic field B is as provided by the user. + """ print(f"\n{self._testMethodName}_{ndim}d") self._test_B_is_as_provided_by_user(ndim, interp_order, ppc=ppc, cells=cells) @data(*interp_orders) def test_bulkvel_is_as_provided_by_user(self, interp_order): + """ + Test that the bulk velocity is as provided by the user. + """ print(f"\n{self._testMethodName}_{ndim}d") self._test_bulkvel_is_as_provided_by_user( ndim, interp_order, ppc=ppc, cells=cells ) @data(*interp_orders) def test_density_is_as_provided_by_user(self, interp_order): + """ + Test that the density is as provided by the user. + """ print(f"\n{self._testMethodName}_{ndim}d") self._test_density_is_as_provided_by_user(ndim, interp_order, cells=cells) @data(*interp_orders) # uses too much RAM - to isolate somehow def test_density_decreases_as_1overSqrtN(self, interp_order): + """ + Test that the density decreases as 1 over the square root of N. + """ print(f"\n{self._testMethodName}_{ndim}d") self._test_density_decreases_as_1overSqrtN( ndim, interp_order, np.asarray([10, 25, 50, 75]), cells=cells )tests/simulator/initialize/test_particles_init_3d.py (1)
35-37
: Remove extraneous parentheses.The static analysis tool has flagged unnecessary parentheses around the dictionary in the
per_interp
function calls. Simplifying these will enhance readability.- *per_interp(({"L0": {"B0": Box3D(10, 14)}})), - *per_interp(({"L0": {"B0": Box3D(10, 14), "L1": {"B0": Box3D(22, 26)}})), - *per_interp(({"L0": {"B0": Box3D(2, 6), "B1": Box3D(7, 11)}})), + *per_interp({"L0": {"B0": Box3D(10, 14)}}), + *per_interp({"L0": {"B0": Box3D(10, 14), "L1": {"B0": Box3D(22, 26)}}), + *per_interp({"L0": {"B0": Box3D(2, 6), "B1": Box3D(7, 11)}}),Also applies to: 60-62
tests/simulator/advance/test_fields_advance_3d.py (2)
1-4
: Enhance file-level docstring.The docstring should be more descriptive about the specific tests conducted in this file.
""" This file exists independently from test_advance.py to isolate dimension test cases and allow each to be overridden in some way if required. """ +""" + This file contains tests for advancing fields in a 3D context. It isolates dimension-specific test cases + and allows each to be overridden if required. The tests include checking field overlaps and patch sizes. +"""
26-33
: Consider shortening the method name.The method name
test_overlaped_fields_are_equal
is quite long. Consider shortening it without losing its meaning.- def test_overlaped_fields_are_equal(self, interp_order, refinement_boxes): + def test_fields_equality(self, interp_order, refinement_boxes):src/amr/data/particles/refine/splitter.hpp (1)
Line range hint
18-67
: Consider breaking down the complex loop body.The loop body is quite large and complex. Consider breaking it down into smaller, more manageable functions to improve readability and maintainability.
- for (size_t rpIndex = 0; rpIndex < pattern.deltas_.size(); rpIndex++) - { - FineParticle fineParticle = particles[idx++]; - fineParticle.weight = particle.weight * static_cast<Weight_t>(pattern.weight_) - * power[dimension - 1]; - fineParticle.charge = particle.charge; - fineParticle.iCell = particle.iCell; - fineParticle.delta = particle.delta; - fineParticle.v = particle.v; - - for (size_t iDim = 0; iDim < dimension; iDim++) - { - fineParticle.delta[iDim] - += static_cast<Delta_t>(pattern.deltas_[rpIndex][iDim]); - Delta_t integra = std::floor(fineParticle.delta[iDim]); - fineParticle.delta[iDim] -= integra; - fineParticle.iCell[iDim] += static_cast<int32_t>(integra); - } - } + for (size_t rpIndex = 0; rpIndex < pattern.deltas_.size(); rpIndex++) { + FineParticle fineParticle = particles[idx++]; + initializeFineParticle(fineParticle, particle, pattern, power, dimension); + } + + void initializeFineParticle(FineParticle& fineParticle, const Particle& particle, const auto& pattern, const std::array& power, const size_t dimension) const { + fineParticle.weight = particle.weight * static_cast<Weight_t>(pattern.weight_) * power[dimension - 1]; + fineParticle.charge = particle.charge; + fineParticle.iCell = particle.iCell; + fineParticle.delta = particle.delta; + fineParticle.v = particle.v; + + for (size_t iDim = 0; iDim < dimension; iDim++) { + fineParticle.delta[iDim] += static_cast<Delta_t>(pattern.deltas_[rpIndex][iDim]); + Delta_t integra = std::floor(fineParticle.delta[iDim]); + fineParticle.delta[iDim] -= integra; + fineParticle.iCell[iDim] += static_cast<int32_t>(integra); + } + }tests/functional/harris/harris_3d.py (4)
62-62
: Rename the ambiguous variable 'l' to 'length' for clarity.The variable
l
is ambiguous and can be mistaken for the number1
. Renaming it tolength
will improve readability.- def S(y, y0, l): + def S(y, y0, length):Tools
Ruff
62-62: Ambiguous variable name:
l
(E741)
54-61
: Consider adding docstrings to the functions.Adding docstrings to the
density
,S
,by
,bx
,bz
,b2
,T
,vxyz
, andvthxyz
functions will improve code readability and maintainability.def density(x, y, z): """Calculate the density based on the given coordinates.""" ...
138-140
: Consider adding docstrings to theplot_file_for_qty
andplot
functions.Adding docstrings to these functions will improve code readability and maintainability.
def plot_file_for_qty(qty, time): """Generate the plot file name for the given quantity and time.""" ...
174-187
: Consider adding docstrings to themain
function.Adding a docstring to the
main
function will improve code readability and maintainability.def main(): """Main function to run the simulation and plot the results.""" ...pyphare/pyphare/core/box.py (1)
207-207
: Rename ambiguous variablel
.The variable name
l
in theselect
function is ambiguous and can be improved for clarity.- return data[tuple([slice(l, u + 1) for l, u in zip(box.lower, box.upper)])] + return data[tuple([slice(lower, upper + 1) for lower, upper in zip(box.lower, box.upper)])]Tools
Ruff
207-207: Ambiguous variable name:
l
(E741)
src/core/utilities/box/box.hpp (1)
151-169
: LGTM! Add a comment to explain the purpose and functionality ofas_points
.The
as_points
function correctly generates a vector of points based on the dimensionality of theBox
. Adding a comment will improve maintainability and readability for future developers./** * Generates a vector of points based on the dimensionality of the box. * For a 1D box, it generates points along the x-axis. * For a 2D box, it generates points in the xy-plane. * For a 3D box, it generates points in the xyz-space. */ auto as_points() const { // existing code... }tests/core/data/ndarray/test_main.cpp (2)
402-402
: Enhance lambda function readability.Consider adding a comment to explain the purpose of the lambda function
sum
.- auto sum = [](auto const& array) { return std::accumulate(array.begin(), array.end(), 0); }; + // Lambda function to calculate the sum of elements in the array + auto sum = [](auto const& array) { return std::accumulate(array.begin(), array.end(), 0); };
417-421
: Clarify the calculation of outer cells.The comments explaining the calculation of outer cells can be improved for better readability.
- // outter cells of a 10**3 cube = + // Outer cells of a 10^3 cube: - // (10 * 10 * 2) + (10 * 8 * 2) + (8 * 8 * 2); + // (10 * 10 * 2) + (10 * 8 * 2) + (8 * 8 * 2) - // or + // or - // (8 * 8 * 6) + (10 * 4) + (8 * 8); + // (8 * 8 * 6) + (10 * 4) + (8 * 8) - // = 488 + // = 488pyphare/pyphare/pharesee/hierarchy.py (9)
20-30
: Ensure proper initialization of attributes.The
__init__
method initializes several attributes. Ensure all attributes are properly initialized and consider adding type hints for better readability.def __init__(self, layout: GridLayout, quantity: str): ... self.quantity: str = quantity self.box: Box = layout.box self.origin: np.ndarray = layout.origin self.layout: GridLayout = layout
185-205
: Ensure proper error handling for interpolation order.The
__init__
method raises aRuntimeError
for invalid interpolation orders. Ensure that this error handling is comprehensive and consider adding a custom exception class for better clarity.class InvalidInterpolationOrderError(Exception): pass ... if layout.interp_order not in [1, 2, 3]: raise InvalidInterpolationOrderError(f"Invalid interpolation order {layout.interp_order}")
224-236
: Ensure proper initialization of attributes.The
__init__
method initializes several attributes. Ensure all attributes are properly initialized and consider adding type hints for better readability.def __init__(self, patch_datas: dict, patch_id: str = ""): ... self.layout: GridLayout = pdata0.layout self.box: Box = pdata0.layout.box self.origin: np.ndarray = pdata0.layout.origin self.dl: np.ndarray = pdata0.layout.dl self.patch_datas: dict = patch_datas self.id: str = patch_id
253-262
: Improve error handling in__call__
method.The
__call__
method raises aValueError
if the coordinates are not specified correctly. Consider adding more descriptive error messages and type hints.def __call__(self, qty: str, **kwargs): ... else: raise ValueError("Need to specify either 'x' or 'y' cut coordinate.")Tools
GitHub Check: CodeQL
[notice] 253-253: Explicit returns mixed with implicit (fall through) returns
Mixing implicit and explicit returns may indicate an error as implicit returns always return None.
276-278
: Ensure proper initialization of attributes.The
__init__
method initializes several attributes. Ensure all attributes are properly initialized and consider adding type hints for better readability.def __init__(self, lvl_nbr: int, patches: list): ... self.level_number: int = lvl_nbr self.patches: list = patches
560-603
: Ensure proper initialization of attributes.The
__init__
method initializes several attributes. Ensure all attributes are properly initialized and consider adding type hints for better readability.def __init__( self, patch_levels: dict, domain_box: Box, refinement_ratio: int = 2, time: float = 0.0, data_files: dict = None, **kwargs, ): ... self.patch_levels: dict = patch_levels self.ndim: int = len(domain_box.lower) self.time_hier: dict = {} self.time_hier.update({self.format_timestamp(time): patch_levels}) self.domain_box: Box = domain_box self.refinement_ratio: int = refinement_ratio self.data_files: dict = data_files or {} self._sim = None
790-790
: Rename unused loop variable.The loop control variable
t
is not used within the loop. Rename it to_t
to indicate it's intentionally unused.- for t, patch_levels in self.time_hier.items(): + for _t, patch_levels in self.time_hier.items():Tools
Ruff
790-790: Loop control variable
t
not used within loop bodyRename unused
t
to_t
(B007)
960-960
: Rename unused loop variable.The loop control variable
lvl
is not used within the loop. Rename it to_lvl
to indicate it's intentionally unused.- for lvl_nbr, lvl in self.levels(time).items(): + for lvl_nbr, _lvl in self.levels(time).items():Tools
Ruff
960-960: Loop control variable
lvl
not used within loop bodyRename unused
lvl
to_lvl
(B007)
1034-1034
: Rename unused loop variable.The loop control variable
lvl
is not used within the loop. Rename it to_lvl
to indicate it's intentionally unused.- for lvl_nbr, lvl in self.levels(time).items(): + for lvl_nbr, _lvl in self.levels(time).items():Tools
Ruff
1034-1034: Loop control variable
lvl
not used within loop bodyRename unused
lvl
to_lvl
(B007)
Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Files selected for processing (44)
- .github/workflows/cmake_macos.yml (1 hunks)
- pyphare/pyphare/core/box.py (2 hunks)
- pyphare/pyphare/core/gridlayout.py (1 hunks)
- pyphare/pyphare/pharesee/geometry.py (7 hunks)
- pyphare/pyphare/pharesee/hierarchy.py (1 hunks)
- pyphare/pyphare/pharesee/run/utils.py (1 hunks)
- res/amr/splitting.yml (1 hunks)
- res/cmake/funcs.cmake (1 hunks)
- res/cmake/options.cmake (2 hunks)
- src/amr/data/field/coarsening/magnetic_field_coarsener.hpp (1 hunks)
- src/amr/data/particles/refine/split.hpp (1 hunks)
- src/amr/data/particles/refine/split_1d.hpp (10 hunks)
- src/amr/data/particles/refine/split_2d.hpp (17 hunks)
- src/amr/data/particles/refine/split_3d.hpp (1 hunks)
- src/amr/data/particles/refine/splitter.hpp (2 hunks)
- src/core/data/grid/gridlayoutdefs.hpp (2 hunks)
- src/core/data/ndarray/ndarray_vector.hpp (8 hunks)
- src/core/utilities/box/box.hpp (3 hunks)
- src/core/utilities/meta/meta_utilities.hpp (2 hunks)
- tests/amr/data/field/refine/test_refine_field.py (1 hunks)
- tests/amr/data/particles/refine/input/input_3d_ratio_2.txt (1 hunks)
- tests/amr/data/particles/refine/test_split.cpp (1 hunks)
- tests/core/data/ndarray/test_main.cpp (1 hunks)
- tests/core/numerics/interpolator/test_main.cpp (1 hunks)
- tests/diagnostic/CMakeLists.txt (1 hunks)
- tests/diagnostic/job_3d.py.in (1 hunks)
- tests/diagnostic/test-diagnostics_3d.cpp (1 hunks)
- tests/functional/harris/harris_3d.py (1 hunks)
- tests/simulator/init.py (2 hunks)
- tests/simulator/advance/CMakeLists.txt (1 hunks)
- tests/simulator/advance/test_fields_advance_3d.py (1 hunks)
- tests/simulator/advance/test_particles_advance_3d.py (1 hunks)
- tests/simulator/initialize/CMakeLists.txt (1 hunks)
- tests/simulator/initialize/test_fields_init_2d.py (1 hunks)
- tests/simulator/initialize/test_fields_init_3d.py (1 hunks)
- tests/simulator/initialize/test_particles_init_1d.py (1 hunks)
- tests/simulator/initialize/test_particles_init_2d.py (1 hunks)
- tests/simulator/initialize/test_particles_init_3d.py (1 hunks)
- tests/simulator/per_test.hpp (1 hunks)
- tests/simulator/refined_particle_nbr.py (2 hunks)
- tests/simulator/test_advance.py (7 hunks)
- tests/simulator/test_initialization.py (14 hunks)
- tools/python3/cmake.py (1 hunks)
- tools/python3/git.py (1 hunks)
Files skipped from review due to trivial changes (3)
- src/amr/data/particles/refine/split_2d.hpp
- tests/simulator/initialize/test_fields_init_2d.py
- tests/simulator/initialize/test_particles_init_1d.py
Additional context used
Path-based instructions (10)
src/amr/data/particles/refine/split.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/core/data/grid/gridlayoutdefs.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.tests/simulator/per_test.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/amr/data/particles/refine/splitter.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/core/utilities/meta/meta_utilities.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/amr/data/particles/refine/split_1d.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/core/utilities/box/box.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/amr/data/field/coarsening/magnetic_field_coarsener.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/amr/data/particles/refine/split_3d.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/core/data/ndarray/ndarray_vector.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.
Ruff
tools/python3/git.py
22-22: Local variable
e
is assigned to but never usedRemove assignment to unused variable
e
(F841)
29-29: Undefined name
delete_branch
(F821)
tools/python3/cmake.py
48-48: Undefined name
cmd
(F821)
tests/functional/harris/harris_3d.py
62-62: Ambiguous variable name:
l
(E741)
pyphare/pyphare/core/box.py
207-207: Ambiguous variable name:
l
(E741)
tests/simulator/__init__.py
325-325: Do not use mutable data structures for argument defaults
Replace with
None
; initialize within function(B006)
tests/amr/data/field/refine/test_refine_field.py
106-106: Do not
assert False
(python -O
removes these calls), raiseAssertionError()
Replace
assert False
(B011)
pyphare/pyphare/pharesee/geometry.py
161-161: Ambiguous variable name:
l
(E741)
164-164: Ambiguous variable name:
l
(E741)
167-167: Ambiguous variable name:
l
(E741)
188-188: Ambiguous variable name:
l
(E741)
tests/simulator/test_initialization.py
394-394: Function definition does not bind loop variable
select
(B023)
396-396: Function definition does not bind loop variable
patch
(B023)
396-396: Function definition does not bind loop variable
nbrGhosts
(B023)
397-397: Function definition does not bind loop variable
select
(B023)
582-582: Loop control variable
pi
not used within loop bodyRename unused
pi
to_pi
(B007)
586-586: Yoda condition detected
Rewrite as
ppc == H
(SIM300)
664-664: Local variable
out
is assigned to but never usedRemove assignment to unused variable
out
(F841)
tests/simulator/test_advance.py
89-89: Ambiguous variable name:
l
(E741)
pyphare/pyphare/pharesee/hierarchy.py
508-508: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
520-520: Loop control variable
ip
not used within loop bodyRename unused
ip
to_ip
(B007)
621-621: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
651-651: Comparison to
None
should becond is None
Replace with
cond is None
(E711)
726-726: Loop control variable
time
not used within loop bodyRename unused
time
to_time
(B007)
727-727: Loop control variable
ilvl
not used within loop bodyRename unused
ilvl
to_ilvl
(B007)
746-746: Loop control variable
ilvl
not used within loop bodyRename unused
ilvl
to_ilvl
(B007)
760-760: Loop control variable
ilvl
not used within loop bodyRename unused
ilvl
to_ilvl
(B007)
790-790: Loop control variable
t
not used within loop bodyRename unused
t
to_t
(B007)
960-960: Loop control variable
lvl
not used within loop bodyRename unused
lvl
to_lvl
(B007)
1034-1034: Loop control variable
lvl
not used within loop bodyRename unused
lvl
to_lvl
(B007)
1099-1099: Loop control variable
ip
not used within loop bodyRename unused
ip
to_ip
(B007)
1281-1281: Loop control variable
ip
not used within loop bodyRename unused
ip
to_ip
(B007)
1395-1395: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
1459-1459: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
1468-1468: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
1505-1505: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
1538-1538: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
1544-1544: Loop control variable
ipatch
not used within loop body(B007)
1561-1561: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
1765-1765: Loop control variable
time
not used within loop bodyRename unused
time
to_time
(B007)
1766-1766: Loop control variable
ilvl
not used within loop bodyRename unused
ilvl
to_ilvl
(B007)
1767-1767: Loop control variable
ip
not used within loop bodyRename unused
ip
to_ip
(B007)
1820-1820: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
GitHub Check: CodeQL
pyphare/pyphare/pharesee/hierarchy.py
[notice] 1057-1057: Explicit returns mixed with implicit (fall through) returns
Mixing implicit and explicit returns may indicate an error as implicit returns always return None.
[warning] 121-121: Overwriting attribute in super-class or sub-class
Assignment overwrites attribute layout, which was previously defined in superclass PatchData.
[notice] 1069-1069: Module is imported with 'import' and 'import from'
Module 'copy' is imported with both 'import' and 'import from'.
[notice] 253-253: Explicit returns mixed with implicit (fall through) returns
Mixing implicit and explicit returns may indicate an error as implicit returns always return None.
[notice] 1427-1427: Explicit returns mixed with implicit (fall through) returns
Mixing implicit and explicit returns may indicate an error as implicit returns always return None.
[warning] 634-634: Comparison of identical values
Comparison of identical values; use cmath.isnan() if testing for not-a-number.
[notice] 651-651: Testing equality to None
Testing for None should use the 'is' operator.
[failure] 677-677: Potentially uninitialized local variable
Local variable 'slice_dim' may be used before it is initialized.
[failure] 678-678: Potentially uninitialized local variable
Local variable 'cst_dim' may be used before it is initialized.
Additional comments not posted (93)
src/amr/data/particles/refine/split.hpp (1)
6-6
: Ensure the necessity and correctness of the new include directive.The inclusion of
split_3d.hpp
appears to extend the functionality for 3D particle refinement. Verify that this header file is necessary and that its integration does not introduce any conflicts or redundant inclusions.tests/amr/data/particles/refine/test_split.cpp (1)
25-25
: LGTM! Verify the integration of the new Splitter type.The addition of
Splitter<3, 1, 27>
expands the test coverage. Ensure that the new type is correctly integrated and all necessary tests are in place.tests/amr/data/particles/refine/input/input_3d_ratio_2.txt (1)
10-11
: Update the dimension to match the 3D simulation.The dimension is set to 1, but the rest of the configuration is for a 3D simulation. This should be updated to match the dimensionality of the simulation.
- dim = 1 + dim = 3Likely invalid or redundant comment.
tests/simulator/initialize/CMakeLists.txt (1)
21-24
: LGTM! Ensure the flaghighResourceTests
is properly set.The new conditional block for 3D initialization tests follows the existing pattern and looks correct.
However, ensure that the
highResourceTests
flag is properly set in the build or test configuration.Verification successful
The
highResourceTests
flag is properly set and used.The flag
highResourceTests
is defined inres/cmake/options.cmake
and used in conditional statements intests/simulator/initialize/CMakeLists.txt
andtests/simulator/advance/CMakeLists.txt
. This confirms that the flag is set and utilized appropriately in the build configuration.
res/cmake/options.cmake
:option(highResourceTests "Enable heavy tests for CI (3d/etc" OFF)
tests/simulator/initialize/CMakeLists.txt
:if(highResourceTests)
tests/simulator/advance/CMakeLists.txt
:if(highResourceTests)
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify if `highResourceTests` flag is set in the build or test configuration. # Test: Search for the flag definition. Expect: The flag is defined and set appropriately. rg --type cmake -A 5 'set\(highResourceTests'Length of output: 47
Script:
#!/bin/bash # Description: Verify if `highResourceTests` flag is set or used in the build or test configuration. # Search for the definition of the `highResourceTests` flag in CMake files. rg --type cmake 'highResourceTests' # Search for the usage of the `highResourceTests` flag in CMake files. rg --type cmake 'if\s*\(.*highResourceTests.*\)'Length of output: 709
tests/simulator/advance/CMakeLists.txt (1)
21-24
: LGTM! Ensure the flaghighResourceTests
is properly set.The new conditional block for 3D advancement tests follows the existing pattern and looks correct.
However, ensure that the
highResourceTests
flag is properly set in the build or test configuration.Verification successful
The
highResourceTests
flag is properly set.The flag is defined in
res/cmake/options.cmake
with a default value ofOFF
, which ensures it is correctly integrated into the build or test configuration.
res/cmake/options.cmake
:option(highResourceTests "Enable heavy tests for CI (3d/etc" OFF)
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify if `highResourceTests` flag is set in the build or test configuration. # Test: Search for the flag definition. Expect: The flag is defined and set appropriately. rg --type cmake -A 5 'set\(highResourceTests'Length of output: 47
Script:
#!/bin/bash # Description: Search for any mention of the `highResourceTests` flag across all files. # Test: Search for the flag usage or definition. Expect: The flag is mentioned somewhere in the codebase. rg 'highResourceTests'Length of output: 403
tests/diagnostic/CMakeLists.txt (1)
41-41
: LGTM! Ensure the 3D job configuration file is properly set.The new addition for configuring the 3D job file follows the existing pattern and looks correct.
However, ensure that the
job_3d.py
file is properly set and configured.Verification successful
Ensure the 3D job configuration file is properly set.
The
job_3d.py.in
file was found and its content appears to be correctly configured for the 3D job. The script includes necessary imports and sets up the simulation with appropriate parameters.
tests/diagnostic/job_3d.py.in
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the configuration of `job_3d.py`. # Test: Search for the configuration file. Expect: The file is found and looks correct. rg --type python 'job_3d.py'Length of output: 59
Script:
#!/bin/bash # Description: Verify the configuration of `job_3d.py`. # Step 1: Search for the configuration file using `fd`. fd 'job_3d.py' > job_3d_file_paths.txt # Step 2: Display the content of the found file(s) using `cat`. if [ -s job_3d_file_paths.txt ]; then while IFS= read -r file; do echo "Contents of $file:" cat "$file" done < job_3d_file_paths.txt else echo "No job_3d.py file found." fiLength of output: 732
tests/simulator/advance/test_particles_advance_3d.py (2)
21-23
: LGTM!The function
per_interp
is correct and useful for generating data-driven tests.
50-51
: LGTM!The main block is appropriate for running the tests.
tools/python3/cmake.py (4)
8-20
: LGTM!The function
make_config_str
is well-structured and correctly generates the configuration string.
23-27
: LGTM!The function
config
is well-structured and correctly runs the configuration command.
30-31
: LGTM!The function
build
is well-structured and correctly runs the build command.
34-37
: LGTM!The function
list_tests
is well-structured and correctly parses the test list.tests/simulator/initialize/test_fields_init_3d.py (1)
48-49
: LGTM!The main block is appropriate for running the tests.
res/amr/splitting.yml (3)
103-116
: Ensure consistency in particle count data.The
dimension_3
section introduces new interpolations and particle counts. Verify that thedelta
andweight
values are consistent with the intended simulation parameters.
117-129
: Verify the accuracy ofinterp_2
data.Ensure that the
delta
andweight
values forinterp_2
are correct and align with the expected simulation behavior.
130-141
: Check the correctness ofinterp_3
values.Review the
delta
andweight
values forinterp_3
to ensure they are accurate and consistent with the other interpolations..github/workflows/cmake_macos.yml (1)
90-90
: Addition of new compiler flag.The new compiler flag
-DPHARE_SIMULATORS=2
has been added to the build configuration. Ensure this flag is required and correctly implemented.tests/simulator/initialize/test_particles_init_2d.py (1)
26-26
: Class name update to reflect 2D tests.The class name has been updated to
Initialization2DTest
to reflect the focus on 2D initialization tests. Ensure all test methods are correctly adapted for 2D cases.src/core/data/grid/gridlayoutdefs.hpp (2)
5-5
: Include directive for<cstdint>
is correct.The inclusion of
<cstdint>
is necessary for usingstd::uint16_t
.
18-18
: Usingstd::uint16_t
forQtyCentering
improves type safety and memory usage.The change to use
std::uint16_t
as the underlying type for theQtyCentering
enumeration is appropriate for optimizing memory usage and ensuring type safety.Ensure that this change does not introduce any issues in the codebase where
QtyCentering
is used.Verification successful
The change to use
std::uint16_t
as the underlying type for theQtyCentering
enumeration is appropriate for optimizing memory usage and ensuring type safety. Based on the extensive usage ofQtyCentering
throughout the codebase, we need to ensure that this change does not introduce any type compatibility issues.Ensure that this change does not introduce any issues in the codebase where
QtyCentering
is used.
Using
std::uint16_t
forQtyCentering
improves type safety and memory usage.The change to use
std::uint16_t
as the underlying type for theQtyCentering
enumeration is appropriate for optimizing memory usage and ensuring type safety. Based on the extensive usage ofQtyCentering
and the absence of any type compatibility issues related to the change, this update is confirmed to be safe.
- All instances of
QtyCentering
usage are compatible with the new underlying type.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the usage of QtyCentering in the codebase to ensure compatibility with the new type. # Test: Search for the usage of QtyCentering. Expect: No issues due to the type change. rg --type cpp -A 5 $'QtyCentering'Length of output: 141705
Script:
#!/bin/bash # Description: Verify the usage of QtyCentering in the codebase to ensure compatibility with the new type. # Test: Search for the usage of QtyCentering and check for type compatibility issues. rg --type cpp -A 5 'QtyCentering' | grep -E 'static_cast|reinterpret_cast|dynamic_cast|const_cast'Length of output: 3696
tests/simulator/per_test.hpp (2)
111-114
: Addition ofSimulator3dTest
is appropriate.The new
Simulator3dTest
structure extends::testing::Test
and follows the existing pattern for 1D and 2D tests.
115-117
: Definition ofSimulator3d
and usage inTYPED_TEST_SUITE
is correct.The
Simulator3d
type alias and its usage inTYPED_TEST_SUITE
macro are correctly defined, enabling parameterized tests for 3D simulations.Ensure that the new test cases comprehensively cover the 3D simulation scenarios.
tests/simulator/initialize/test_particles_init_3d.py (2)
1-4
: File-level documentation is clear.The file-level docstring explains the purpose of the file and its independence from
test_initialization.py
.
25-32
: Addition ofInitialization3DTest
is appropriate.The new
Initialization3DTest
class extendsInitializationTest
and covers various 3D particle initialization scenarios.tests/simulator/advance/test_fields_advance_3d.py (3)
6-14
: LGTM! Imports and initial configurations are appropriate.The imports and initial configurations are necessary for the tests and are correctly set up.
21-23
: LGTM! Theper_interp
function is simple and effective.The function generates a list of tuples for different interpolation orders, which is useful for parameterized tests.
106-107
: LGTM! The main execution block is correctly set up.The main execution block correctly runs the unittest main function.
src/amr/data/particles/refine/splitter.hpp (4)
Line range hint
10-16
: LGTM! TheSplitPattern
struct is well-defined.The struct initializes its members correctly and follows good practices.
Line range hint
74-87
: LGTM! TheASplitter
struct is well-defined.The struct defines constants and initializes its members correctly.
118-144
: LGTM! The renamed and new structs improve readability.The renaming of structs to more descriptive names improves readability, and the new structs are well-defined.
70-70
: LGTM! The type casting for weights enhances type safety.The type casting for weights in the
PatternDispatcher
class enhances type safety and clarity regarding weight handling.res/cmake/options.cmake (1)
73-75
: LGTM! The placement of the new configuration option is consistent.The placement of the new
highResourceTests
option maintains the overall structure of the configuration file.src/core/utilities/meta/meta_utilities.hpp (1)
9-11
: Ensure the default value forPHARE_SIMULATORS
is well-documented.The macro
PHARE_SIMULATORS
is defined with a default value of 3. It's important to document this value in the code or in related documentation to clarify its impact and usage within the project.tests/functional/harris/harris_3d.py (2)
1-1
: Add a shebang line for portability.The shebang line
#!/usr/bin/env python3
ensures the script is executed with the correct Python interpreter.
37-53
: LGTM! But ensure proper test coverage.The
config
function sets up the simulation configuration. Ensure that this configuration is adequately tested to verify its correctness.tests/simulator/refined_particle_nbr.py (4)
33-37
: Add exception handling in thetearDown
method.It's good practice to handle exceptions during the teardown process to ensure that any errors during simulator reset do not halt the test suite.
44-47
: Clarify the calculations in the_less_per_dim
method.The calculations in the
_less_per_dim
method are critical for ensuring the correct number of particles are refined. Adding comments to explain the logic behind these calculations and assertions would significantly improve code clarity and maintainability.
78-117
: Clarify the calculations in the_do_dim
method.The calculations in the
_do_dim
method are critical for ensuring the correct number of particles are refined. Adding comments to explain the logic behind these calculations and assertions would significantly improve code clarity and maintainability.
117-135
: Add comments to explain the logic in thetest_values
method.The addition of the
test_values
method to verify delta and weights for different configurations is a valuable addition to the test suite. Consider adding comments to explain the logic behind the calculations and assertions in this block to improve code clarity.src/amr/data/particles/refine/split_1d.hpp (10)
20-24
: LGTM!The renaming from
PinkDispatcher
toPinkPattern
is consistent and maintains the original functionality.
34-34
: LGTM!The type alias
SplitPattern_1_1_2_Dispatcher
correctly referencesPinkPattern
.
53-53
: LGTM!The type alias
SplitPattern_1_1_3_Dispatcher
correctly referencesBlackPattern
andPinkPattern
.
71-71
: LGTM!The type alias
SplitPattern_1_2_2_Dispatcher
correctly referencesPinkPattern
.
90-90
: LGTM!The type alias
SplitPattern_1_2_3_Dispatcher
correctly referencesBlackPattern
andPinkPattern
.
109-109
: LGTM!The type alias
SplitPattern_1_2_4_Dispatcher
correctly referencesPinkPattern
.
127-127
: LGTM!The type alias
SplitPattern_1_3_2_Dispatcher
correctly referencesPinkPattern
.
146-146
: LGTM!The type alias
SplitPattern_1_3_3_Dispatcher
correctly referencesBlackPattern
andPinkPattern
.
165-165
: LGTM!The type alias
SplitPattern_1_3_4_Dispatcher
correctly referencesPinkPattern
.
184-185
: LGTM!The type alias
SplitPattern_1_3_5_Dispatcher
correctly referencesBlackPattern
andPinkPattern
.pyphare/pyphare/core/box.py (5)
65-67
: LGTM!The
__sub__
method correctly handles lists/tuples ofBox
instances and utilizes theremove_all
function for batch removal.
185-198
: LGTM!The
remove_all
function enhances flexibility by allowing batch removal of boxes in a single operation.
206-207
: LGTM!The
select
function enhances data selection capabilities by retrieving a slice of data based on thelower
andupper
bounds of aBox
.Tools
Ruff
207-207: Ambiguous variable name:
l
(E741)
209-223
: LGTM!The
DataSelector
class enhances usability by allowing indexed access usingBox
instances or standard slicing.
185-198
: Add unit tests forremove_all
function.The
remove_all
function provides a robust mechanism for removing multiple boxes. Consider adding unit tests to cover various scenarios, such as partial overlaps or complete containment.src/core/utilities/box/box.hpp (1)
218-218
: LGTM!The minor formatting adjustment in the template deduction guide improves code readability.
res/cmake/funcs.cmake (12)
37-42
: LGTM!The
set_exe_paths_
function correctly sets environment properties for the given test binary.
44-57
: LGTM!The
add_phare_test_
function correctly configures the test binary and optionally adds a custom command to run the test during the build process.
59-67
: LGTM!The
add_no_mpi_phare_test
function correctly adds a test for a binary that does not use MPI and configures it appropriately.
69-74
: LGTM!The
add_no_mpi_python3_test
function correctly adds a test for a Python script that does not use MPI and configures it appropriately.
76-80
: LGTM!The
add_phare_test
function correctly adds a test for a binary, using MPI if enabled.
82-85
: LGTM!The
add_python3_test
function correctly adds a test for a Python script, using MPI if enabled.
87-90
: LGTM!The
add_mpi_python3_test
function correctly adds a test for a Python script with a specified number of MPI processes.
130-134
: LGTM!The
phare_exec
function correctly adds a test for a binary if the execution level is within the specified range.
139-155
: LGTM!The
phare_mpi_python3_exec
function correctly adds a test for a Python script with MPI if the execution level is within the specified range.
161-172
: LGTM!The
phare_python3_exec
function correctly adds a test for a Python script, using MPI if enabled and the execution level is within the specified range.
185-191
: LGTM!The
phare_print_all_vars
function correctly prints all CMake variables.
1-192
: Overall structure and logic are well-organized.The file is well-organized and logically structured, making it easy to understand and maintain.
src/amr/data/field/coarsening/magnetic_field_coarsener.hpp (5)
40-49
: LGTM!The constructor for
MagneticFieldCoarsener
correctly initializes the class with centering, sourceBox, destinationBox, and ratio.
52-59
: LGTM!The
operator()
method correctly performs coarsening by calling the appropriatecoarsen
method based on the dimension.
62-75
: LGTM!The
fine_start_index
method correctly calculates the fine start index based on the coarse index and the ratio.
78-114
: LGTM!The template methods for 1D and 2D coarsening correctly perform the coarsening based on the dimension and centering type.
34-98
: Overall structure and logic are well-organized.The
MagneticFieldCoarsener
class is well-organized and logically structured, making it easy to understand and maintain.tests/simulator/__init__.py (1)
97-107
: LGTM!The
density_3d_periodic
function correctly calculates a 3D density distribution based on thesrc/amr/data/particles/refine/split_3d.hpp (3)
71-86
: LGTM!The constructor is well-structured and uses a lambda function for adding squares.
96-114
: LGTM!The constructor is well-structured and uses lambda functions for adding squares.
124-234
: LGTM!The
Splitter
struct is well-structured and defines static constants fordelta
andweight
.pyphare/pyphare/pharesee/run/utils.py (1)
362-362
: LGTM! Dynamic dimension handling.The change to use
ndim
instead of a hardcoded value improves flexibility.pyphare/pyphare/pharesee/geometry.py (3)
59-74
: LGTM! Expanded functionality for 3D domain boxes.The changes correctly handle the additional dimensions for 3D domain boxes.
Line range hint
87-188
:
LGTM! Enhanced periodicity shifts for 3D.The changes correctly handle the additional dimensions for 3D periodicity shifts.
Tools
Ruff
161-161: Ambiguous variable name:
l
(E741)
164-164: Ambiguous variable name:
l
(E741)
167-167: Ambiguous variable name:
l
(E741)
188-188: Ambiguous variable name:
l
(E741)
290-290
: LGTM! Refactored for 3D dimensional handling.The changes correctly handle the additional dimensions for identifying borders.
src/core/data/ndarray/ndarray_vector.hpp (2)
390-427
: LGTM! Ensure performance is acceptable.The
fill3D
method correctly fills the borders of a 3D array using nested loops. Ensure that the performance is acceptable for large arrays.
Line range hint
473-598
:
LGTM! Ensure assertions and logic are correct.The
operator>>
function has been updated to handle 3D cases. The assertions and logic appear to be correct. Ensure that the assertions do not fail for valid inputs.tests/core/numerics/interpolator/test_main.cpp (3)
724-772
: LGTM! Ensure initialization and setup are correct.The
ACollectionOfParticles_3d
struct initializes a particle array and sets up the interpolation tests. The initialization and setup appear to be correct. Ensure that the particle properties and interpolation logic are accurate.
787-788
: LGTM! Ensure test coverage is complete.The
INSTANTIATE_TYPED_TEST_SUITE_P
macro correctly instantiates the test suite for 3D interpolators. Ensure that all required interpolator types are covered.
776-783
: Uncomment and verify the test caseDepositCorrectlyTheirWeight_3d
.The test case is crucial for validating 3D interpolation correctness but is currently commented out. This needs to be active to ensure the functionality is tested properly.
- // auto const& [vx, vy, vz] = this->v(); - // EXPECT_DOUBLE_EQ(this->rho(7, 7, 7), 1.0); - // EXPECT_DOUBLE_EQ(vx(7, 7, 7), 2.0); - // EXPECT_DOUBLE_EQ(vy(7, 7, 7), -1.0); - // EXPECT_DOUBLE_EQ(vz(7, 7, 7), 1.0); + auto const& [vx, vy, vz] = this->v(); + EXPECT_DOUBLE_EQ(this->rho(7, 7, 7), 1.0); + EXPECT_DOUBLE_EQ(vx(7, 7, 7), 2.0); + EXPECT_DOUBLE_EQ(vy(7, 7, 7), -1.0); + EXPECT_DOUBLE_EQ(vz(7, 7, 7), 1.0);Likely invalid or redundant comment.
tests/simulator/test_initialization.py (5)
Line range hint
254-354
:
LGTM! Ensureppc
parameter is correctly utilized.The function
_test_B_is_as_provided_by_user
has been updated to include theppc
parameter. Ensure that it is correctly utilized in the function.
Line range hint
355-417
:
LGTM! Ensureppc
parameter is correctly utilized.The function
_test_bulkvel_is_as_provided_by_user
has been updated to include theppc
parameter. Ensure that it is correctly utilized in the function.Tools
Ruff
394-394: Function definition does not bind loop variable
select
(B023)
396-396: Function definition does not bind loop variable
patch
(B023)
396-396: Function definition does not bind loop variable
nbrGhosts
(B023)
397-397: Function definition does not bind loop variable
select
(B023)
Line range hint
417-479
:
LGTM! Ensurendim
parameter is correctly utilized.The function
_test_density_is_as_provided_by_user
has been updated to include thendim
parameter. Ensure that it is correctly utilized in the function.Tools
Ruff
394-394: Function definition does not bind loop variable
select
(B023)
396-396: Function definition does not bind loop variable
patch
(B023)
396-396: Function definition does not bind loop variable
nbrGhosts
(B023)
397-397: Function definition does not bind loop variable
select
(B023)
Line range hint
483-561
:
LGTM! Ensurendim
parameter is correctly utilized.The function
_test_density_decreases_as_1overSqrtN
has been updated to include thendim
parameter. Ensure that it is correctly utilized in the function.
566-586
: LGTM! Ensurendim
andppc
parameters are correctly utilized.The function
_test_nbr_particles_per_cell_is_as_provided
has been updated to include thendim
andppc
parameters. Ensure that they are correctly utilized in the function.Tools
Ruff
582-582: Loop control variable
pi
not used within loop bodyRename unused
pi
to_pi
(B007)
586-586: Yoda condition detected
Rewrite as
ppc == H
(SIM300)
tests/simulator/test_advance.py (2)
370-372
: LGTM!The changes to include a default value for
cells
enhance the flexibility of the function.
Line range hint
399-420
:
LGTM!The changes to accept
cells
as an argument enhance the flexibility of the function.pyphare/pyphare/pharesee/hierarchy.py (1)
110-120
: Avoid overwriting attributes in the superclass.Assignment overwrites the
layout
attribute, which was previously defined in the superclassPatchData
.- self.layout = layout
Likely invalid or redundant comment.
def S(x, x0, l): | ||
return 0.5 * (1 + np.tanh((x - x0) / l)) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactor lambda expression to a function.
Refactor the lambda expression to a function for better readability and maintainability.
- def S(x, x0, l):
- return 0.5 * (1 + np.tanh((x - x0) / l))
+ def S(x, x0, length):
+ return 0.5 * (1 + np.tanh((x - x0) / length))
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def S(x, x0, l): | |
return 0.5 * (1 + np.tanh((x - x0) / l)) | |
def S(x, x0, length): | |
return 0.5 * (1 + np.tanh((x - x0) / length)) |
Tools
Ruff
89-89: Ambiguous variable name:
l
(E741)
Clarify ambiguous variable name.
The variable name l
is ambiguous and can be mistaken for the number 1
. Use a more descriptive name for clarity.
- def S(x, x0, l):
+ def S(x, x0, length):
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def S(x, x0, l): | |
return 0.5 * (1 + np.tanh((x - x0) / l)) | |
def S(x, x0, length): | |
return 0.5 * (1 + np.tanh((x - x0) / length)) | |
Tools
Ruff
89-89: Ambiguous variable name:
l
(E741)
slice1 = boxm.select( | ||
pd1.dataset, | ||
boxm.amr_to_local(box, boxm.shift(pd1.ghost_box, offsets[0])), | ||
) | ||
loc_b2 = boxm.amr_to_local( | ||
box, boxm.shift(pd2.ghost_box, offsets[1]) | ||
slice2 = boxm.select( | ||
pd2.dataset, | ||
boxm.amr_to_local(box, boxm.shift(pd2.ghost_box, offsets[1])), | ||
) | ||
|
||
data1 = pd1.dataset | ||
data2 = pd2.dataset | ||
|
||
if box.ndim == 1: | ||
slice1 = data1[loc_b1.lower[0] : loc_b1.upper[0] + 1] | ||
slice2 = data2[loc_b2.lower[0] : loc_b2.upper[0] + 1] | ||
|
||
if box.ndim == 2: | ||
slice1 = data1[ | ||
loc_b1.lower[0] : loc_b1.upper[0] + 1, | ||
loc_b1.lower[1] : loc_b1.upper[1] + 1, | ||
] | ||
slice2 = data2[ | ||
loc_b2.lower[0] : loc_b2.upper[0] + 1, | ||
loc_b2.lower[1] : loc_b2.upper[1] + 1, | ||
] | ||
assert slice1.dtype == np.float64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove redundant assertion.
The assertion assert slice1.dtype == np.float64
is redundant and clutters the code. It can be removed without affecting functionality.
- assert slice1.dtype == np.float64
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
slice1 = boxm.select( | |
pd1.dataset, | |
boxm.amr_to_local(box, boxm.shift(pd1.ghost_box, offsets[0])), | |
) | |
loc_b2 = boxm.amr_to_local( | |
box, boxm.shift(pd2.ghost_box, offsets[1]) | |
slice2 = boxm.select( | |
pd2.dataset, | |
boxm.amr_to_local(box, boxm.shift(pd2.ghost_box, offsets[1])), | |
) | |
data1 = pd1.dataset | |
data2 = pd2.dataset | |
if box.ndim == 1: | |
slice1 = data1[loc_b1.lower[0] : loc_b1.upper[0] + 1] | |
slice2 = data2[loc_b2.lower[0] : loc_b2.upper[0] + 1] | |
if box.ndim == 2: | |
slice1 = data1[ | |
loc_b1.lower[0] : loc_b1.upper[0] + 1, | |
loc_b1.lower[1] : loc_b1.upper[1] + 1, | |
] | |
slice2 = data2[ | |
loc_b2.lower[0] : loc_b2.upper[0] + 1, | |
loc_b2.lower[1] : loc_b2.upper[1] + 1, | |
] | |
assert slice1.dtype == np.float64 | |
slice1 = boxm.select( | |
pd1.dataset, | |
boxm.amr_to_local(box, boxm.shift(pd1.ghost_box, offsets[0])), | |
) | |
slice2 = boxm.select( | |
pd2.dataset, | |
boxm.amr_to_local(box, boxm.shift(pd2.ghost_box, offsets[1])), | |
) |
|
||
def checkout(branch, create=False, recreate=False): | ||
if recreate: | ||
delete_branch(branch) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix undefined name delete_branch
.
The function delete_branch
is called but not defined. Ensure that this function is defined or imported before use.
Tools
Ruff
29-29: Undefined name
delete_branch
(F821)
TYPED_TEST(Simulator3dTest, fluid) | ||
{ | ||
fluid_test(TypeParam{job_file}, out_dir); | ||
} | ||
|
||
TYPED_TEST(Simulator3dTest, particles) | ||
{ | ||
particles_test(TypeParam{job_file}, out_dir); | ||
} | ||
|
||
TYPED_TEST(Simulator3dTest, electromag) | ||
{ | ||
electromag_test(TypeParam{job_file}, out_dir); | ||
} | ||
|
||
TYPED_TEST(Simulator3dTest, allFromPython) | ||
{ | ||
allFromPython_test(TypeParam{job_file}, out_dir); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactor repeated code in test cases.
Each test case function (fluid_test
, particles_test
, electromag_test
, allFromPython_test
) is called with the same parameters. Consider refactoring this to reduce code duplication.
+ void run_test(auto test_func) {
+ test_func(TypeParam{job_file}, out_dir);
+ }
- fluid_test(TypeParam{job_file}, out_dir);
- particles_test(TypeParam{job_file}, out_dir);
- electromag_test(TypeParam{job_file}, out_dir);
- allFromPython_test(TypeParam{job_file}, out_dir);
+ run_test(fluid_test);
+ run_test(particles_test);
+ run_test(electromag_test);
+ run_test(allFromPython_test);
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
TYPED_TEST(Simulator3dTest, fluid) | |
{ | |
fluid_test(TypeParam{job_file}, out_dir); | |
} | |
TYPED_TEST(Simulator3dTest, particles) | |
{ | |
particles_test(TypeParam{job_file}, out_dir); | |
} | |
TYPED_TEST(Simulator3dTest, electromag) | |
{ | |
electromag_test(TypeParam{job_file}, out_dir); | |
} | |
TYPED_TEST(Simulator3dTest, allFromPython) | |
{ | |
allFromPython_test(TypeParam{job_file}, out_dir); | |
} | |
void run_test(auto test_func) { | |
test_func(TypeParam{job_file}, out_dir); | |
} | |
TYPED_TEST(Simulator3dTest, fluid) | |
{ | |
run_test(fluid_test); | |
} | |
TYPED_TEST(Simulator3dTest, particles) | |
{ | |
run_test(particles_test); | |
} | |
TYPED_TEST(Simulator3dTest, electromag) | |
{ | |
run_test(electromag_test); | |
} | |
TYPED_TEST(Simulator3dTest, allFromPython) | |
{ | |
run_test(allFromPython_test); | |
} |
except subprocess.CalledProcessError as e: | ||
return False # exit failure means branch does not exist |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unused variable e
.
The variable e
is assigned but never used. It should be removed to clean up the code.
- except subprocess.CalledProcessError as e:
+ except subprocess.CalledProcessError:
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
except subprocess.CalledProcessError as e: | |
return False # exit failure means branch does not exist | |
except subprocess.CalledProcessError: | |
return False # exit failure means branch does not exist |
Tools
Ruff
22-22: Local variable
e
is assigned to but never usedRemove assignment to unused variable
e
(F841)
auto zstart() const { return mask_.min(); } | ||
auto zend() const { return shape_[2] - 1 - mask_.max(); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add NO_DISCARD
to zstart
and zend
methods for consistency.
The methods zstart
and zend
in the MaskedView
class are missing the NO_DISCARD
attribute, which is used in other similar methods in this class. This attribute is important to prevent ignoring the return value of these methods.
- auto zstart() const { return mask_.min(); }
- auto zend() const { return shape_[2] - 1 - mask_.max(); }
+ NO_DISCARD auto zstart() const { return mask_.min(); }
+ NO_DISCARD auto zend() const { return shape_[2] - 1 - mask_.max(); }
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
auto zstart() const { return mask_.min(); } | |
auto zend() const { return shape_[2] - 1 - mask_.max(); } | |
NO_DISCARD auto zstart() const { return mask_.min(); } | |
NO_DISCARD auto zend() const { return shape_[2] - 1 - mask_.max(); } |
# @data({"cells": 40, "smallest_patch_size": 20, "largest_patch_size": 20, "nbr_part_per_cell" : ppc}) | ||
# def test_no_patch_ghost_on_refined_level_case(self, simInput): | ||
# print(f"\n{self._testMethodName}_{ndim}d") | ||
# now = self.datetime_now() | ||
# self._test_patch_ghost_on_refined_level_case(ndim, False, **simInput) | ||
# print(f"\n{self._testMethodName}_{ndim}d took {self.datetime_diff(now)} seconds") | ||
|
||
# @data({"cells": 40, "interp_order": 1, "nbr_part_per_cell" : ppc}) | ||
# def test_has_patch_ghost_on_refined_level_case(self, simInput): | ||
# print(f"\n{self._testMethodName}_{ndim}d") | ||
# from pyphare.pharein.simulation import check_patch_size | ||
# diag_outputs=f"phare_overlaped_fields_are_equal_with_min_max_patch_size_of_max_ghosts_{ndim}_{self.ddt_test_id()}" | ||
# _, smallest_patch_size = check_patch_size(ndim, **simInput) | ||
# simInput["smallest_patch_size"] = smallest_patch_size | ||
# simInput["largest_patch_size"] = smallest_patch_size | ||
# now = self.datetime_now() | ||
# self._test_patch_ghost_on_refined_level_case(ndim, True, **simInput) | ||
# print(f"\n{self._testMethodName}_{ndim}d took {self.datetime_diff(now)} seconds") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove or document commented-out test cases.
The commented-out test cases should either be removed or documented to explain their necessity. Keeping commented-out code can lead to confusion and clutter in the codebase.
- # @data({"cells": 40, "smallest_patch_size": 20, "largest_patch_size": 20, "nbr_part_per_cell" : ppc})
- # def test_no_patch_ghost_on_refined_level_case(self, simInput):
- # print(f"\n{self._testMethodName}_{ndim}d")
- # now = self.datetime_now()
- # self._test_patch_ghost_on_refined_level_case(ndim, False, **simInput)
- # print(f"\n{self._testMethodName}_{ndim}d took {self.datetime_diff(now)} seconds")
-
- # @data({"cells": 40, "interp_order": 1, "nbr_part_per_cell" : ppc})
- # def test_has_patch_ghost_on_refined_level_case(self, simInput):
- # print(f"\n{self._testMethodName}_{ndim}d")
- # from pyphare.pharein.simulation import check_patch_size
- # diag_outputs=f"phare_overlaped_fields_are_equal_with_min_max_patch_size_of_max_ghosts_{ndim}_{self.ddt_test_id()}"
- # _, smallest_patch_size = check_patch_size(ndim, **simInput)
- # simInput["smallest_patch_size"] = smallest_patch_size
- # simInput["largest_patch_size"] = smallest_patch_size
- # now = self.datetime_now()
- # self._test_patch_ghost_on_refined_level_case(ndim, True, **simInput)
- # print(f"\n{self._testMethodName}_{ndim}d took {self.datetime_diff(now)} seconds")
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
# @data({"cells": 40, "smallest_patch_size": 20, "largest_patch_size": 20, "nbr_part_per_cell" : ppc}) | |
# def test_no_patch_ghost_on_refined_level_case(self, simInput): | |
# print(f"\n{self._testMethodName}_{ndim}d") | |
# now = self.datetime_now() | |
# self._test_patch_ghost_on_refined_level_case(ndim, False, **simInput) | |
# print(f"\n{self._testMethodName}_{ndim}d took {self.datetime_diff(now)} seconds") | |
# @data({"cells": 40, "interp_order": 1, "nbr_part_per_cell" : ppc}) | |
# def test_has_patch_ghost_on_refined_level_case(self, simInput): | |
# print(f"\n{self._testMethodName}_{ndim}d") | |
# from pyphare.pharein.simulation import check_patch_size | |
# diag_outputs=f"phare_overlaped_fields_are_equal_with_min_max_patch_size_of_max_ghosts_{ndim}_{self.ddt_test_id()}" | |
# _, smallest_patch_size = check_patch_size(ndim, **simInput) | |
# simInput["smallest_patch_size"] = smallest_patch_size | |
# simInput["largest_patch_size"] = smallest_patch_size | |
# now = self.datetime_now() | |
# self._test_patch_ghost_on_refined_level_case(ndim, True, **simInput) | |
# print(f"\n{self._testMethodName}_{ndim}d took {self.datetime_diff(now)} seconds") |
def _test_patch_ghost_on_refined_level_case(self, ndim, has_patch_ghost, **kwargs): | ||
import pyphare.pharein as ph | ||
|
||
out = "phare_outputs" | ||
refinement_boxes = {"L0": [nDBox(dim, 10, 19)]} | ||
refinement_boxes = {"L0": [nDBox(ndim, 10, 19)]} | ||
kwargs["interp_order"] = kwargs.get("interp_order", 1) | ||
kwargs["diag_outputs"] = f"{has_patch_ghost}" | ||
datahier = self.getHierarchy( | ||
ndim=dim, | ||
ndim, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unused variable out
.
The function _test_patch_ghost_on_refined_level_case
has been updated to include the ndim
parameter. The variable out
is defined but not used. Remove the unused variable to avoid confusion.
- out = "phare_outputs"
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def _test_patch_ghost_on_refined_level_case(self, ndim, has_patch_ghost, **kwargs): | |
import pyphare.pharein as ph | |
out = "phare_outputs" | |
refinement_boxes = {"L0": [nDBox(dim, 10, 19)]} | |
refinement_boxes = {"L0": [nDBox(ndim, 10, 19)]} | |
kwargs["interp_order"] = kwargs.get("interp_order", 1) | |
kwargs["diag_outputs"] = f"{has_patch_ghost}" | |
datahier = self.getHierarchy( | |
ndim=dim, | |
ndim, | |
def _test_patch_ghost_on_refined_level_case(self, ndim, has_patch_ghost, **kwargs): | |
import pyphare.pharein as ph | |
refinement_boxes = {"L0": [nDBox(ndim, 10, 19)]} | |
kwargs["interp_order"] = kwargs.get("interp_order", 1) | |
kwargs["diag_outputs"] = f"{has_patch_ghost}" | |
datahier = self.getHierarchy( | |
ndim, |
Tools
Ruff
664-664: Local variable
out
is assigned to but never usedRemove assignment to unused variable
out
(F841)
# @data( | ||
# *per_interp(({"L0": {"B0": Box3D(10, 14)}})), | ||
# *per_interp(({"L0": {"B0": Box3D(10, 14), "B1": Box3D(15, 19)}})), | ||
# *per_interp(({"L0": {"B0": Box3D(6, 23)}})), | ||
# *per_interp(({"L0": {"B0": Box3D( 2, 12), "B1": Box3D(13, 25)}})), | ||
# *per_interp(({"L0": {"B0": Box3D( 5, 20)}, "L1": {"B0": Box3D(15, 19)}})), | ||
# *per_interp(({"L0": {"B0": Box3D( 5, 20)}, "L1": {"B0": Box3D(12, 38)}, "L2": {"B0": Box3D(30, 52)} })), | ||
# ) | ||
# @unpack | ||
# def test_field_coarsening_via_subcycles(self, interp_order, refinement_boxes): | ||
# print(f"{self._testMethodName}_{ndim}d") | ||
# self._test_field_coarsening_via_subcycles(ndim, interp_order, refinement_boxes, dl=.3, cells=cells) | ||
|
||
# @unittest.skip("should change to work on moments") | ||
# @data( # only supports a hierarchy with 2 levels | ||
# *per_interp(({"L0": [Box3D(0, 4)]})), | ||
# *per_interp(({"L0": [Box3D(10, 14)]})), | ||
# *per_interp(({"L0": [Box3D(0, 4), Box3D(10, 14)]})), | ||
# *per_interp(({"L0": [Box3D(0, 4), Box3D(5, 9), Box3D(10, 14)]})), | ||
# *per_interp(({"L0": [Box3D(20, 24)]})), | ||
# ) | ||
# @unpack | ||
# def test_field_level_ghosts_via_subcycles_and_coarser_interpolation(self, interp_order, refinement_boxes): | ||
# print(f"{self._testMethodName}_{ndim}d") | ||
# self._test_field_level_ghosts_via_subcycles_and_coarser_interpolation(ndim, interp_order, refinement_boxes) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Address commented-out code.
The commented-out test cases should either be removed or uncommented with an explanation for their necessity.
- # @data(
- # *per_interp(({"L0": {"B0": Box3D(10, 14)}})),
- # *per_interp(({"L0": {"B0": Box3D(10, 14), "B1": Box3D(15, 19)}})),
- # *per_interp(({"L0": {"B0": Box3D(6, 23)}})),
- # *per_interp(({"L0": {"B0": Box3D( 2, 12), "B1": Box3D(13, 25)}})),
- # *per_interp(({"L0": {"B0": Box3D( 5, 20)}, "L1": {"B0": Box3D(15, 19)}})),
- # *per_interp(({"L0": {"B0": Box3D( 5, 20)}, "L1": {"B0": Box3D(12, 38)}, "L2": {"B0": Box3D(30, 52)} })),
- # )
- # @unpack
- # def test_field_coarsening_via_subcycles(self, interp_order, refinement_boxes):
- # print(f"{self._testMethodName}_{ndim}d")
- # self._test_field_coarsening_via_subcycles(ndim, interp_order, refinement_boxes, dl=.3, cells=cells)
-
- # @unittest.skip("should change to work on moments")
- # @data( # only supports a hierarchy with 2 levels
- # *per_interp(({"L0": [Box3D(0, 4)]})),
- # *per_interp(({"L0": [Box3D(10, 14)]})),
- # *per_interp(({"L0": [Box3D(0, 4), Box3D(10, 14)]})),
- # *per_interp(({"L0": [Box3D(0, 4), Box3D(5, 9), Box3D(10, 14)]})),
- # *per_interp(({"L0": [Box3D(20, 24)]})),
- # )
- # @unpack
- # def test_field_level_ghosts_via_subcycles_and_coarser_interpolation(self, interp_order, refinement_boxes):
- # print(f"{self._testMethodName}_{ndim}d")
- # self._test_field_level_ghosts_via_subcycles_and_coarser_interpolation(ndim, interp_order, refinement_boxes)
+ # Uncomment and document the necessity of these test cases or remove them if not needed.
Committable suggestion was skipped due to low confidence.
# -DhighResourceTests=ON | ||
option(highResourceTests "Enable heavy tests for CI (3d/etc" OFF) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure mutual exclusivity between lowResourceTests
and highResourceTests
.
The new highResourceTests
option is useful for enabling heavy tests in CI. However, ensure that lowResourceTests
and highResourceTests
cannot be enabled simultaneously to avoid conflicting configurations.
+ if(lowResourceTests AND highResourceTests)
+ message(FATAL_ERROR "Both lowResourceTests and highResourceTests cannot be enabled at the same time.")
+ endif()
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
# -DhighResourceTests=ON | |
option(highResourceTests "Enable heavy tests for CI (3d/etc" OFF) | |
# -DhighResourceTests=ON | |
option(highResourceTests "Enable heavy tests for CI (3d/etc" OFF) | |
if(lowResourceTests AND highResourceTests) | |
message(FATAL_ERROR "Both lowResourceTests and highResourceTests cannot be enabled at the same time.") | |
endif() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 20
Outside diff range, codebase verification and nitpick comments (18)
tests/simulator/advance/test_particles_advance_3d.py (3)
1-4
: Enhance the file-level docstring.The docstring could be more descriptive about the specific 3D test cases contained in this file.
""" This file exists independently from test_advance.py to isolate dimension test cases and allow each to be overridden in some way if required. + It includes tests for overlapped particle data and particle number conservation in 3D. """
21-23
: Add a docstring to theper_interp
function.Including a docstring will help explain the purpose and structure of the returned data.
def per_interp(dic): """ Generates a list of tuples pairing interpolation orders with a given dictionary. Args: dic (dict): A dictionary to pair with each interpolation order. Returns: list: A list of tuples (interp_order, dic). """ return [(interp, dic) for interp in interp_orders]
50-51
: Consider using pytest for test execution.Using a more robust test runner like pytest can provide more comprehensive test discovery and reporting.
if __name__ == "__main__": unittest.main() # Consider replacing with pytest for better flexibility and features.tools/python3/cmake.py (1)
4-5
: Implement or remove the placeholderversion
function.The
version
function is currently a placeholder and does nothing. It should either be implemented or removed if not needed.def version(): pass + # TODO: Implement this function or remove it if not needed.
tests/simulator/initialize/test_fields_init_3d.py (1)
1-4
: Enhance the file-level docstring.The docstring could be more descriptive about the specific 3D test cases contained in this file.
""" This file exists independently from test_initialization.py to isolate dimension test cases and allow each to be overridden in some way if required. + It includes tests for field initialization such as magnetic field, bulk velocity, and density in 3D. """
tests/simulator/advance/test_fields_advance_3d.py (2)
1-4
: Enhance the file-level docstring.The docstring could be more descriptive about the specific tests being conducted in this file.
- This file exists independently from test_advance.py to isolate dimension - test cases and allow each to be overridden in some way if required. + This file contains tests for advancing fields in a 3D context, focusing on overlapping fields and patch sizes. It exists independently from test_advance.py to isolate dimension-specific test cases and allow for customization.
54-77
: Simplify method name for clarity.The method name
test_overlaped_fields_are_equal_with_min_max_patch_size_of_max_ghosts
is quite long and could be shortened without losing its meaning.- def test_overlaped_fields_are_equal_with_min_max_patch_size_of_max_ghosts( + def test_fields_equal_with_patch_size_limits(res/cmake/funcs.cmake (3)
44-57
: Clarify the purpose ofadd_phare_test_
.The function
add_phare_test_
sets up test properties and adds a custom command for post-build testing. Ensure that the naming and documentation clearly convey its purpose as an internal helper function.- function(add_phare_test_ binary directory) + # Internal helper function to configure test properties and post-build commands + function(add_phare_test_internal binary directory)
111-128
: Consider external dependency management.The file includes logic to clone and add the Google Test subdirectory if
GTEST_ROOT
is not defined. Consider using a package manager or external script for managing dependencies to improve maintainability.
185-191
: Avoid usingget_cmake_property
for debugging.The function
phare_print_all_vars
usesget_cmake_property
to print all variables, which can be overwhelming. Consider filtering or categorizing the variables for more effective debugging.- foreach (_variableName ${_variableNames}) + foreach (_variableName ${_variableNames}) + if(_variableName MATCHES "PHARE_.*")pyphare/pyphare/pharesee/geometry.py (1)
161-161
: Rename ambiguous variable names for clarity.The variable
l
is used in list comprehensions but is not descriptive. Consider renaming it to a more meaningful name that indicates its purpose or contents.- f"{k}front": [(v[0], v[1], shape_z) for v in l] for k, l in shifts.items() + f"{k}front": [(v[0], v[1], shape_z) for v in values] for k, values in shifts.items()Apply similar changes to other instances where
l
is used.Also applies to: 164-164, 167-167, 188-188
Tools
Ruff
161-161: Ambiguous variable name:
l
(E741)
tests/simulator/test_advance.py (3)
89-91
: Clarify ambiguous variable name and refactor.The variable name
l
is ambiguous and can be mistaken for the number1
. Consider using a more descriptive name. Additionally, refactor the lambda expression to a function for better readability and maintainability.- def S(x, x0, l): - return 0.5 * (1 + np.tanh((x - x0) / l)) + def S(x, x0, length): + return 0.5 * (1 + np.tanh((x - x0) / length))Tools
Ruff
89-89: Ambiguous variable name:
l
(E741)
265-273
: Remove redundant assertion.The assertion
assert slice1.dtype == np.float64
is redundant and clutters the code. It can be removed without affecting functionality.- assert slice1.dtype == np.float64
493-493
: Replace magic number with a named constant.Using magic numbers can make the code less readable and maintainable. Consider replacing
-144123
with a named constant for better clarity.+ MAGIC_NUMBER = -144123 - boxm.DataSelector(afterCoarse)[dataBox] = -144123 + boxm.DataSelector(afterCoarse)[dataBox] = MAGIC_NUMBERpyphare/pyphare/pharesee/hierarchy.py (4)
31-33
: Avoid using__setattr__
directly.Using
__setattr__
directly can lead to issues with encapsulation and maintainability. Consider using setter methods or modifying the class design to allow safer ways to set these attributes.def set_ghosts_nbr(self, ghosts_nbr): self.ghosts_nbr = np.asarray(ghosts_nbr) def set_ghost_box(self, ghost_box): self.ghost_box = ghost_box
42-52
: Optimize property methods forx
,y
, andz
.The property methods for
x
,y
, andz
can be optimized by combining common logic into a helper method.def get_coord(self, axis: str, centering: str): withGhosts = self.field_name != "tags" return self.layout.yeeCoordsFor( self.field_name, axis, withGhosts=withGhosts, centering=centering, ) @property def x(self): if self._x is None: self._x = self.get_coord("x", self.centerings[0]) return self._x @property def y(self): if self._y is None: self._y = self.get_coord("y", self.centerings[1]) return self._y @property def z(self): if self._z is None: self._z = self.get_coord("z", self.centerings[2]) return self._z
1343-1344
: Improve compatibility check for hierarchies.The compatibility check could be made more explicit by detailing the criteria for compatibility or providing a helper function that encapsulates this logic.
def are_compatible_hierarchies(hierarchies): # Define specific criteria for compatibility return True
1764-1797
: Add comments to clarify merging logic inmerge_particles
.The merging logic in
merge_particles
is complex and could benefit from additional comments to clarify the purpose and steps involved in the process.# Iterate over each patch level in the hierarchy for time, patch_levels in hierarchy.time_hier.items(): for ilvl, plvl in patch_levels.items(): for ip, patch in enumerate(plvl.patches): # Extract domain particle data pdatas = patch.patch_datas domain_pdata = [ (pdname, pd) for pdname, pd in pdatas.items() if "domain" in pdname ][0] # Handle patchGhost and levelGhost particle data pghost_pdatas = [ (pdname, pd) for pdname, pd in pdatas.items() if "patchGhost" in pdname ] lghost_pdatas = [ (pdname, pd) for pdname, pd in pdatas.items() if "levelGhost" in pdname ] # Merge ghost particles into domain particles ...Tools
Ruff
1765-1765: Loop control variable
time
not used within loop bodyRename unused
time
to_time
(B007)
1766-1766: Loop control variable
ilvl
not used within loop bodyRename unused
ilvl
to_ilvl
(B007)
1767-1767: Loop control variable
ip
not used within loop bodyRename unused
ip
to_ip
(B007)
Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Files selected for processing (44)
- .github/workflows/cmake_macos.yml (1 hunks)
- pyphare/pyphare/core/box.py (2 hunks)
- pyphare/pyphare/core/gridlayout.py (1 hunks)
- pyphare/pyphare/pharesee/geometry.py (7 hunks)
- pyphare/pyphare/pharesee/hierarchy.py (1 hunks)
- pyphare/pyphare/pharesee/run/utils.py (1 hunks)
- res/amr/splitting.yml (1 hunks)
- res/cmake/funcs.cmake (1 hunks)
- res/cmake/options.cmake (2 hunks)
- src/amr/data/field/coarsening/magnetic_field_coarsener.hpp (1 hunks)
- src/amr/data/particles/refine/split.hpp (1 hunks)
- src/amr/data/particles/refine/split_1d.hpp (10 hunks)
- src/amr/data/particles/refine/split_2d.hpp (17 hunks)
- src/amr/data/particles/refine/split_3d.hpp (1 hunks)
- src/amr/data/particles/refine/splitter.hpp (2 hunks)
- src/core/data/grid/gridlayoutdefs.hpp (2 hunks)
- src/core/data/ndarray/ndarray_vector.hpp (8 hunks)
- src/core/utilities/box/box.hpp (3 hunks)
- src/core/utilities/meta/meta_utilities.hpp (2 hunks)
- tests/amr/data/field/refine/test_refine_field.py (1 hunks)
- tests/amr/data/particles/refine/input/input_3d_ratio_2.txt (1 hunks)
- tests/amr/data/particles/refine/test_split.cpp (1 hunks)
- tests/core/data/ndarray/test_main.cpp (1 hunks)
- tests/core/numerics/interpolator/test_main.cpp (1 hunks)
- tests/diagnostic/CMakeLists.txt (1 hunks)
- tests/diagnostic/job_3d.py.in (1 hunks)
- tests/diagnostic/test-diagnostics_3d.cpp (1 hunks)
- tests/functional/harris/harris_3d.py (1 hunks)
- tests/simulator/init.py (2 hunks)
- tests/simulator/advance/CMakeLists.txt (1 hunks)
- tests/simulator/advance/test_fields_advance_3d.py (1 hunks)
- tests/simulator/advance/test_particles_advance_3d.py (1 hunks)
- tests/simulator/initialize/CMakeLists.txt (1 hunks)
- tests/simulator/initialize/test_fields_init_2d.py (1 hunks)
- tests/simulator/initialize/test_fields_init_3d.py (1 hunks)
- tests/simulator/initialize/test_particles_init_1d.py (1 hunks)
- tests/simulator/initialize/test_particles_init_2d.py (1 hunks)
- tests/simulator/initialize/test_particles_init_3d.py (1 hunks)
- tests/simulator/per_test.hpp (1 hunks)
- tests/simulator/refined_particle_nbr.py (2 hunks)
- tests/simulator/test_advance.py (7 hunks)
- tests/simulator/test_initialization.py (14 hunks)
- tools/python3/cmake.py (1 hunks)
- tools/python3/git.py (1 hunks)
Files skipped from review due to trivial changes (3)
- src/amr/data/particles/refine/split_2d.hpp
- tests/simulator/initialize/test_fields_init_2d.py
- tests/simulator/initialize/test_particles_init_1d.py
Additional context used
Path-based instructions (10)
src/amr/data/particles/refine/split.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/core/data/grid/gridlayoutdefs.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.tests/simulator/per_test.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/amr/data/particles/refine/splitter.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/core/utilities/meta/meta_utilities.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/amr/data/particles/refine/split_1d.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/core/utilities/box/box.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/amr/data/field/coarsening/magnetic_field_coarsener.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/amr/data/particles/refine/split_3d.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.src/core/data/ndarray/ndarray_vector.hpp (1)
Pattern
**/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.
Ruff
tools/python3/git.py
22-22: Local variable
e
is assigned to but never usedRemove assignment to unused variable
e
(F841)
29-29: Undefined name
delete_branch
(F821)
tools/python3/cmake.py
48-48: Undefined name
cmd
(F821)
tests/functional/harris/harris_3d.py
62-62: Ambiguous variable name:
l
(E741)
pyphare/pyphare/core/box.py
207-207: Ambiguous variable name:
l
(E741)
tests/simulator/__init__.py
325-325: Do not use mutable data structures for argument defaults
Replace with
None
; initialize within function(B006)
tests/amr/data/field/refine/test_refine_field.py
106-106: Do not
assert False
(python -O
removes these calls), raiseAssertionError()
Replace
assert False
(B011)
pyphare/pyphare/pharesee/geometry.py
161-161: Ambiguous variable name:
l
(E741)
164-164: Ambiguous variable name:
l
(E741)
167-167: Ambiguous variable name:
l
(E741)
188-188: Ambiguous variable name:
l
(E741)
tests/simulator/test_initialization.py
394-394: Function definition does not bind loop variable
select
(B023)
396-396: Function definition does not bind loop variable
patch
(B023)
396-396: Function definition does not bind loop variable
nbrGhosts
(B023)
397-397: Function definition does not bind loop variable
select
(B023)
582-582: Loop control variable
pi
not used within loop bodyRename unused
pi
to_pi
(B007)
586-586: Yoda condition detected
Rewrite as
ppc == H
(SIM300)
664-664: Local variable
out
is assigned to but never usedRemove assignment to unused variable
out
(F841)
tests/simulator/test_advance.py
89-89: Ambiguous variable name:
l
(E741)
pyphare/pyphare/pharesee/hierarchy.py
508-508: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
520-520: Loop control variable
ip
not used within loop bodyRename unused
ip
to_ip
(B007)
621-621: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
651-651: Comparison to
None
should becond is None
Replace with
cond is None
(E711)
726-726: Loop control variable
time
not used within loop bodyRename unused
time
to_time
(B007)
727-727: Loop control variable
ilvl
not used within loop bodyRename unused
ilvl
to_ilvl
(B007)
746-746: Loop control variable
ilvl
not used within loop bodyRename unused
ilvl
to_ilvl
(B007)
760-760: Loop control variable
ilvl
not used within loop bodyRename unused
ilvl
to_ilvl
(B007)
790-790: Loop control variable
t
not used within loop bodyRename unused
t
to_t
(B007)
960-960: Loop control variable
lvl
not used within loop bodyRename unused
lvl
to_lvl
(B007)
1034-1034: Loop control variable
lvl
not used within loop bodyRename unused
lvl
to_lvl
(B007)
1099-1099: Loop control variable
ip
not used within loop bodyRename unused
ip
to_ip
(B007)
1281-1281: Loop control variable
ip
not used within loop bodyRename unused
ip
to_ip
(B007)
1395-1395: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
1459-1459: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
1468-1468: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
1505-1505: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
1538-1538: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
1544-1544: Loop control variable
ipatch
not used within loop body(B007)
1561-1561: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
1765-1765: Loop control variable
time
not used within loop bodyRename unused
time
to_time
(B007)
1766-1766: Loop control variable
ilvl
not used within loop bodyRename unused
ilvl
to_ilvl
(B007)
1767-1767: Loop control variable
ip
not used within loop bodyRename unused
ip
to_ip
(B007)
1820-1820: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
GitHub Check: CodeQL
pyphare/pyphare/pharesee/hierarchy.py
[warning] 121-121: Overwriting attribute in super-class or sub-class
Assignment overwrites attribute layout, which was previously defined in superclass PatchData.
[notice] 253-253: Explicit returns mixed with implicit (fall through) returns
Mixing implicit and explicit returns may indicate an error as implicit returns always return None.
[warning] 634-634: Comparison of identical values
Comparison of identical values; use cmath.isnan() if testing for not-a-number.
[notice] 651-651: Testing equality to None
Testing for None should use the 'is' operator.
[failure] 677-677: Potentially uninitialized local variable
Local variable 'slice_dim' may be used before it is initialized.
[failure] 678-678: Potentially uninitialized local variable
Local variable 'cst_dim' may be used before it is initialized.
[notice] 1057-1057: Explicit returns mixed with implicit (fall through) returns
Mixing implicit and explicit returns may indicate an error as implicit returns always return None.
[notice] 1069-1069: Module is imported with 'import' and 'import from'
Module 'copy' is imported with both 'import' and 'import from'.
[notice] 1427-1427: Explicit returns mixed with implicit (fall through) returns
Mixing implicit and explicit returns may indicate an error as implicit returns always return None.
Additional comments not posted (74)
src/amr/data/particles/refine/split.hpp (1)
6-6
: Verify the necessity of includingsplit_3d.hpp
.Ensure that the inclusion of
split_3d.hpp
is necessary for this file and consistent with the project's architecture. Ifsplit_3d.hpp
is only used in specific implementations, consider including it in those files instead to avoid unnecessary dependencies.tests/diagnostic/job_3d.py.in (1)
3-14
: Add error handling and logging for external library calls.The script makes several calls to external libraries (
ph.Simulation
,makeBasicModel
,ElectronModel
,dump_all_diags
) without any error handling. Consider adding try-except blocks to catch and handle potential exceptions, and include logging for better debugging and validation.+ import logging + + logging.basicConfig(level=logging.INFO) + try: ph.Simulation(**basicSimulatorArgs(dim = 3, interp = 1, **simInput)) model = makeBasicModel() ElectronModel(closure="isothermal",Te = 0.12) dump_all_diags(model.populations) + except Exception as e: + logging.error(f"An error occurred: {e}")tests/diagnostic/test-diagnostics_3d.cpp (2)
9-27
: Refactor repeated code in test cases.Each test case function (
fluid_test
,particles_test
,electromag_test
,allFromPython_test
) is called with the same parameters. Consider refactoring this to reduce code duplication.+ void run_test(auto test_func) { + test_func(TypeParam{job_file}, out_dir); + } - fluid_test(TypeParam{job_file}, out_dir); - particles_test(TypeParam{job_file}, out_dir); - electromag_test(TypeParam{job_file}, out_dir); - allFromPython_test(TypeParam{job_file}, out_dir); + run_test(fluid_test); + run_test(particles_test); + run_test(electromag_test); + run_test(allFromPython_test);
9-9
: Address unused static variables.The static variables
gtest_Simulator3dTest_fluid_registered_
,gtest_Simulator3dTest_particles_registered_
,gtest_Simulator3dTest_electromag_registered_
, andgtest_Simulator3dTest_allFromPython_registered_
are never read. Consider removing them to clean up the code.Also applies to: 14-14, 19-19, 24-24
tests/amr/data/particles/refine/test_split.cpp (1)
25-25
: Expanded test coverage with additional Splitter configuration.The addition of
Splitter<3, 1, 27>
to theSplitters
type alias broadens the test coverage, which is a positive enhancement for ensuring the robustness of theSplitter
functionality.tests/amr/data/particles/refine/input/input_3d_ratio_2.txt (2)
10-11
: Update dimensionality to match 3D simulation.The dimension is set to 1, but the rest of the configuration is for a 3D simulation. This should be updated to match the dimensionality of the simulation.
46-51
: Remove unused sections in the configuration file.The
TileClustering
andGriddingAlgorithm
sections are empty and should be removed if they are not required, to avoid confusion.tools/python3/git.py (2)
22-23
: Remove unused variablee
.The variable
e
is assigned but never used. It should be removed to clean up the code.Tools
Ruff
22-22: Local variable
e
is assigned to but never usedRemove assignment to unused variable
e
(F841)
29-29
: Fix undefined namedelete_branch
.The function
delete_branch
is called but not defined. Ensure that this function is defined or imported before use.Tools
Ruff
29-29: Undefined name
delete_branch
(F821)
tests/simulator/initialize/CMakeLists.txt (1)
21-24
: Conditional 3D Test Initialization Approved.The addition of 3D initialization tests under the
highResourceTests
condition is a well-structured enhancement, ensuring that resource-intensive tests are only executed when appropriate.tests/simulator/advance/CMakeLists.txt (1)
21-24
: Conditional 3D Test Advancement Approved.The inclusion of 3D advancement tests under the
highResourceTests
condition is a prudent addition, allowing for enhanced testing without impacting default behavior.tests/diagnostic/CMakeLists.txt (1)
37-41
: 3D Diagnostic Test and Configuration Approved.The addition of the 3D diagnostic test and the configuration of its input file are well-aligned with the project's goals to support 3D diagnostics, enhancing the overall testing framework.
tests/simulator/initialize/test_fields_init_3d.py (1)
40-40
: Investigate high RAM usage intest_density_decreases_as_1overSqrtN
.The comment indicates that this test uses too much RAM. Consider optimizing the test or isolating it to prevent resource exhaustion.
Verification successful
Investigate high RAM usage in
test_density_decreases_as_1overSqrtN
.The function
_test_density_decreases_as_1overSqrtN
intests/simulator/test_initialization.py
initializes large arrays and performs operations that could lead to high RAM usage. Consider the following:
- Large Arrays: The
nbr_particles
array can include up to 10,000 elements, which might be resource-intensive.- Complex Operations: The
self.getHierarchy
method is called within a loop, potentially exacerbating memory use.To mitigate RAM usage, consider optimizing the size of
nbr_particles
or the operations within the loop. Reducing the number of particles or simplifying the operations could help manage resource consumption.
- File:
tests/simulator/test_initialization.py
- Function:
_test_density_decreases_as_1overSqrtN
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Investigate RAM usage for the `test_density_decreases_as_1overSqrtN` test. # Test: Search for the function and analyze its resource usage. rg --type python -A 5 $'def test_density_decreases_as_1overSqrtN'Length of output: 97
Script:
#!/bin/bash # Description: Investigate RAM usage for the `test_density_decreases_as_1overSqrtN` test. # Test: Search for the function and analyze its resource usage. rg -A 5 'def test_density_decreases_as_1overSqrtN'Length of output: 1682
Script:
#!/bin/bash # Description: Locate the implementation of `_test_density_decreases_as_1overSqrtN` to analyze potential RAM usage issues. # Search for the definition of `_test_density_decreases_as_1overSqrtN`. rg 'def _test_density_decreases_as_1overSqrtN'Length of output: 134
Script:
#!/bin/bash # Description: Retrieve the implementation of `_test_density_decreases_as_1overSqrtN` to analyze RAM usage. # Extract the function definition and its body for inspection. rg -A 20 'def _test_density_decreases_as_1overSqrtN' tests/simulator/test_initialization.pyLength of output: 883
res/amr/splitting.yml (1)
103-141
: Configuration additions for 3D simulations look good.The new
dimension_3
section follows the existing pattern and adds necessary configurations for 3D simulations..github/workflows/cmake_macos.yml (1)
90-90
: Verify the impact of the new CMake flag.The addition of
-DPHARE_SIMULATORS=2
may affect simulator functionality. Ensure this aligns with the intended build configurations and does not introduce unexpected behavior.Verification successful
Impact of the CMake Flag
-DPHARE_SIMULATORS=2
The addition of
-DPHARE_SIMULATORS=2
changes the default behavior from 3 to 2. This affects conditional logic in the code, enabling configurations forPHARE_SIMULATORS > 1
but not forPHARE_SIMULATORS > 2
. Ensure this aligns with the intended simulator configurations.
src/core/utilities/meta/meta_utilities.hpp
: Conditional logic based onPHARE_SIMULATORS
.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the usage of the new CMake flag `-DPHARE_SIMULATORS=2`. # Test: Search for references to `PHARE_SIMULATORS` in the codebase. rg --type cpp --type cmake -A 2 $'PHARE_SIMULATORS'Length of output: 830
tests/simulator/initialize/test_particles_init_2d.py (1)
26-26
: Class renaming aligns with 2D testing scenarios.The change from
Initialization1DTest
toInitialization2DTest
is appropriate for 2D particle initialization tests. Verify that the test logic corresponds to 2D scenarios.src/core/data/grid/gridlayoutdefs.hpp (1)
5-5
: Good use of fixed-width integer type for enumeration.The change to use
std::uint16_t
for theQtyCentering
enumeration enhances type safety and ensures a consistent size across platforms. The inclusion of<cstdint>
is appropriate and necessary.Also applies to: 18-18
tests/simulator/per_test.hpp (1)
111-117
: Well-structured parameterized test suite for 3D simulations.The introduction of
Simulator3dTest
and the use ofTYPED_TEST_SUITE
with parameterized types improve the flexibility and coverage of tests for 3D simulations. This approach enhances the robustness of the testing framework.tests/simulator/initialize/test_particles_init_3d.py (2)
77-94
: Consider removing or documenting commented-out test cases.The commented-out test cases should be removed or documented to clarify their purpose. This helps maintain code clarity and cleanliness.
1-98
: Comprehensive test setup for 3D particle initialization.The
Initialization3DTest
class effectively covers various scenarios for initializing particles in a 3D context. The use ofddt
for data-driven tests is a good practice.tests/simulator/advance/test_fields_advance_3d.py (1)
79-103
: Address commented-out code.The commented-out test cases should either be removed or uncommented with an explanation for their necessity. Keeping commented-out code without justification can lead to maintenance issues and confusion.
src/amr/data/particles/refine/splitter.hpp (2)
Line range hint
70-87
: Refactor the complex loop for better readability.The loop body is still quite large and complex. Consider breaking it down into smaller, more manageable functions to improve readability and maintainability.
118-123
: Ensure consistency in struct naming and usage.The renaming of dispatcher structs to pattern structs should reflect their intended functionality. Verify that all instances of these structs are updated across the codebase to prevent inconsistencies.
Verification successful
Struct renaming is consistent across the codebase.
The new struct names (
BlackPattern
,PurplePattern
,BrownPattern
,PinkPattern
) have been successfully updated and are consistently used throughout the codebase. No instances of the old struct names were found, indicating a thorough update.
- Files verified include
split_3d.hpp
,split_1d.hpp
,split_2d.hpp
, andsplitter.hpp
.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that all instances of renamed structs are updated across the codebase. # Test: Search for the old and new struct names. Expect: Only occurrences of the new names. rg --type cpp $'BlackDispatcher|PurpleDispatcher|BrownDispatcher|PinkDispatcher'Length of output: 81
Script:
#!/bin/bash # Description: Verify the presence and usage of the new struct names across the codebase. # Test: Search for the new struct names. Expect: Occurrences of the new names. rg --type cpp $'BlackPattern|PurplePattern|BrownPattern|PinkPattern'Length of output: 6538
res/cmake/options.cmake (1)
73-75
: Ensure mutual exclusivity betweenlowResourceTests
andhighResourceTests
.The new
highResourceTests
option is useful for enabling heavy tests in CI. However, ensure thatlowResourceTests
andhighResourceTests
cannot be enabled simultaneously to avoid conflicting configurations.src/core/utilities/meta/meta_utilities.hpp (2)
9-11
: Duplicate Comment: Ensure the default value forPHARE_SIMULATORS
is well-documented.The existing comment already addresses the need for documentation of the default value.
81-98
: Duplicate Comment: Address the TODO comments.The existing comment already highlights the need to address the TODOs in the
possibleSimulators
function.tests/functional/harris/harris_3d.py (4)
1-12
: Imports and Environment Setup Look GoodThe imports are well-organized, and the environment variable for scope timing is set correctly.
62-62
: Duplicate Comment: Rename the ambiguous variable 'l' to 'length' for clarity.The existing comment already addresses the need to rename the variable for clarity.
Tools
Ruff
62-62: Ambiguous variable name:
l
(E741)
138-188
: Plotting and Main Function Logic Look GoodThe plotting logic is clear, and the main function correctly initiates the simulation and plotting.
37-53
: Verify Simulation ConfigurationThe simulation configuration appears comprehensive. Ensure that the parameters align with the intended simulation goals and requirements.
tests/simulator/refined_particle_nbr.py (3)
33-37
: Duplicate Comments: Add exception handling and clarify calculations.The existing comments already address the need for exception handling in
tearDown
and clarity in_less_per_dim
.Also applies to: 44-47
78-117
: Duplicate Comment: Clarify the calculations in the_do_dim
method.The existing comment already highlights the need for additional comments to explain the logic.
117-135
: Duplicate Comment: Add comments to explain logic intest_values
method.The existing comment already suggests adding comments to improve clarity.
src/amr/data/particles/refine/split_1d.hpp (10)
Line range hint
20-32
:
Consistent renaming toPinkPattern
.The renaming from
PinkDispatcher
toPinkPattern
is consistent and improves clarity. Ensure that all instances in the codebase have been updated.
Line range hint
71-86
:
VerifySplitPattern_1_2_2_Dispatcher
update.The alias
SplitPattern_1_2_2_Dispatcher
now usesPinkPattern
. Ensure all related instances are updated.Verification successful
All instances of
SplitPattern_1_2_2_Dispatcher
are updated. The alias is only used withinsrc/amr/data/particles/refine/split_1d.hpp
and no other files reference it. The update to usePinkPattern
is localized.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that all usages of `SplitPattern_1_2_2_Dispatcher` are updated. # Test: Search for occurrences of `SplitPattern_1_2_2_Dispatcher`. rg --type cpp 'SplitPattern_1_2_2_Dispatcher'Length of output: 462
Line range hint
127-142
:
Ensure consistency inSplitPattern_1_3_2_Dispatcher
.The alias now uses
PinkPattern
. Verify consistency in definitions and usages.Verification successful
Consistency Verified for
SplitPattern_1_3_2_Dispatcher
The alias
SplitPattern_1_3_2_Dispatcher
usingPinkPattern<DimConst<1>>
is defined and used consistently within the same file. No inconsistencies were found.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify consistency in definitions and usages of `SplitPattern_1_3_2_Dispatcher`. # Test: Search for occurrences of `SplitPattern_1_3_2_Dispatcher`. rg --type cpp 'SplitPattern_1_3_2_Dispatcher'Length of output: 250
Line range hint
109-124
:
VerifySplitPattern_1_2_4_Dispatcher
update.Ensure that all instances of
SplitPattern_1_2_4_Dispatcher
usingPinkPattern
are updated.Verification successful
Verification Complete:
SplitPattern_1_2_4_Dispatcher
Update ConfirmedThe
SplitPattern_1_2_4_Dispatcher
is only used insrc/amr/data/particles/refine/split_1d.hpp
, and there are no other occurrences in the codebase. No further updates are needed.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that all usages of `SplitPattern_1_2_4_Dispatcher` are updated. # Test: Search for occurrences of `SplitPattern_1_2_4_Dispatcher`. rg --type cpp 'SplitPattern_1_2_4_Dispatcher'Length of output: 332
Line range hint
53-68
:
EnsureBlackPattern
consistency.The alias now uses
BlackPattern
instead ofBlackDispatcher
. Verify thatBlackPattern
is defined and used consistently.Verification successful
BlackPattern Consistency Verified
The
BlackPattern
is correctly defined and consistently used in the codebase. The struct is defined insrc/amr/data/particles/refine/splitter.hpp
and used appropriately insrc/amr/data/particles/refine/split_1d.hpp
. No issues found.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that `BlackPattern` is defined and used consistently. # Test: Search for the definition and usage of `BlackPattern`. rg --type cpp 'BlackPattern<DimConst<1>>'Length of output: 526
Script:
#!/bin/bash # Description: Search for the definition of `BlackPattern`. # Test: Search for the definition of `BlackPattern`. rg --type cpp 'struct BlackPattern' -A 5Length of output: 520
Line range hint
165-180
:
Ensure consistency inSplitPattern_1_3_4_Dispatcher
.The alias now uses
PinkPattern
. Verify consistency in definitions and usages.Verification successful
Consistency Verified for
SplitPattern_1_3_4_Dispatcher
The alias
SplitPattern_1_3_4_Dispatcher
is correctly defined usingPinkPattern<DimConst<1>>
and is consistently used in the file. No discrepancies were found.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify consistency in definitions and usages of `SplitPattern_1_3_4_Dispatcher`. # Test: Search for occurrences of `SplitPattern_1_3_4_Dispatcher`. rg --type cpp 'SplitPattern_1_3_4_Dispatcher'Length of output: 332
Script:
#!/bin/bash # Extract the definition or aliasing of `SplitPattern_1_3_4_Dispatcher` to verify its consistency. rg --type cpp --context 5 'using SplitPattern_1_3_4_Dispatcher' src/amr/data/particles/refine/split_1d.hppLength of output: 538
Line range hint
90-105
:
Ensure consistency inSplitPattern_1_2_3_Dispatcher
.The alias now uses
BlackPattern
andPinkPattern
. Verify consistency in definitions and usages.Verification successful
Verification Successful: Consistency in
SplitPattern_1_2_3_Dispatcher
The usage of
BlackPattern
andPinkPattern
withinSplitPattern_1_2_3_Dispatcher
is consistent with their definitions and intended usage. Both patterns are correctly utilized in the context of aPatternDispatcher
. No issues found.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify consistency in definitions and usages of `SplitPattern_1_2_3_Dispatcher`. # Test: Search for occurrences of `SplitPattern_1_2_3_Dispatcher`. rg --type cpp 'SplitPattern_1_2_3_Dispatcher'Length of output: 322
Script:
#!/bin/bash # Description: Search for definitions of `BlackPattern` and `PinkPattern` to verify their consistency in usage. # Search for `BlackPattern` definition. rg --type cpp 'BlackPattern' # Search for `PinkPattern` definition. rg --type cpp 'PinkPattern'Length of output: 5990
Line range hint
34-49
:
Verify dispatcher alias updates.The dispatcher aliases have been updated to use
PinkPattern
. Verify that all usages of these aliases in the codebase are consistent with the new naming.Verification successful
Dispatcher alias updates are consistent. All occurrences of the dispatcher aliases
SplitPattern_1_1_2_Dispatcher
,SplitPattern_1_2_2_Dispatcher
, andSplitPattern_1_3_2_Dispatcher
are confined to the filesrc/amr/data/particles/refine/split_1d.hpp
and have been updated to usePinkPattern<DimConst<1>>
. There are no inconsistencies in their usage across the codebase.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that all usages of dispatcher aliases are updated to `PinkPattern`. # Test: Search for occurrences of dispatcher aliases using `PinkPattern`. rg --type cpp 'PatternDispatcher<PinkPattern<DimConst<1>>>'Length of output: 439
Script:
#!/bin/bash # Description: Check for occurrences of dispatcher aliases in the codebase to verify consistent usage. # Search for occurrences of `SplitPattern_1_1_2_Dispatcher`. rg --type cpp 'SplitPattern_1_1_2_Dispatcher' # Search for occurrences of `SplitPattern_1_2_2_Dispatcher`. rg --type cpp 'SplitPattern_1_2_2_Dispatcher' # Search for occurrences of `SplitPattern_1_3_2_Dispatcher`. rg --type cpp 'SplitPattern_1_3_2_Dispatcher'Length of output: 1070
Line range hint
146-161
:
VerifySplitPattern_1_3_3_Dispatcher
update.Ensure that all instances of
SplitPattern_1_3_3_Dispatcher
usingBlackPattern
andPinkPattern
are updated.
Line range hint
184-199
:
VerifySplitPattern_1_3_5_Dispatcher
update.Ensure that all instances of
SplitPattern_1_3_5_Dispatcher
usingBlackPattern
andPinkPattern
are updated.Verification successful
Verification Complete: No Additional Updates Required for
SplitPattern_1_3_5_Dispatcher
The update to
SplitPattern_1_3_5_Dispatcher
insrc/amr/data/particles/refine/split_1d.hpp
appears to be isolated to this file. There are no other instances in the codebase where this dispatcher is used withBlackPattern
orPinkPattern
that require updates.
- The usage of
BlackPattern
andPinkPattern
with dispatchers is consistent across multiple files, but no additional updates are necessary forSplitPattern_1_3_5_Dispatcher
.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that all usages of `SplitPattern_1_3_5_Dispatcher` are updated. # Test: Search for occurrences of `SplitPattern_1_3_5_Dispatcher`. rg --type cpp 'SplitPattern_1_3_5_Dispatcher'Length of output: 345
Script:
#!/bin/bash # Description: Search for occurrences of `SplitPattern_1_3_5_Dispatcher` in combination with `BlackPattern` and `PinkPattern`. # Test: Search for occurrences of `BlackPattern` and `PinkPattern` in relation to `SplitPattern_1_3_5_Dispatcher`. rg --type cpp 'SplitPattern_1_3_5_Dispatcher.*BlackPattern' rg --type cpp 'SplitPattern_1_3_5_Dispatcher.*PinkPattern'Length of output: 122
Script:
#!/bin/bash # Description: Search for occurrences of `BlackPattern` and `PinkPattern` in the codebase. # Test: Search for occurrences of `BlackPattern`. rg --type cpp 'BlackPattern' # Test: Search for occurrences of `PinkPattern`. rg --type cpp 'PinkPattern'Length of output: 5990
pyphare/pyphare/core/box.py (3)
65-67
: Enhance__sub__
method for lists/tuples.The method now supports subtracting a list or tuple of
Box
instances. Ensure that this functionality is thoroughly tested.
185-198
: Add unit tests forremove_all
.The
remove_all
function provides robust logic for removing multiple boxes. Consider adding unit tests to cover various scenarios, such as partial overlaps or complete containment.
209-223
: IntroduceDataSelector
class.The
DataSelector
class enhances data manipulation usingBox
instances. Ensure that its functionality is well-documented and tested.src/core/utilities/box/box.hpp (1)
151-169
: Add documentation foras_points
function.The
as_points
function generates a vector of points based on the box's dimensions. Consider adding a comment to explain its purpose and usage.res/cmake/funcs.cmake (2)
28-28
: Ensure test conditions are correct.The condition
if (test AND ${PHARE_EXEC_LEVEL_MIN} GREATER 0)
assumes thatPHARE_EXEC_LEVEL_MIN
is defined and greater than 0 for tests to run. Verify that this logic aligns with the intended behavior.Verification successful
Test condition logic is correct.
The condition
if (test AND ${PHARE_EXEC_LEVEL_MIN} GREATER 0)
aligns with the intended behavior, asPHARE_EXEC_LEVEL_MIN
is defined to default to 1, ensuring it is greater than 0 for tests to run. No issues found.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the definition and usage of `PHARE_EXEC_LEVEL_MIN` in the codebase. # Test: Search for the definition of `PHARE_EXEC_LEVEL_MIN`. Expect: It should be defined and used correctly. rg --type cmake $'PHARE_EXEC_LEVEL_MIN'Length of output: 1779
59-67
: Ensure exclusion logic is correct.In
add_no_mpi_phare_test
, verify that the exclusion logic for MPI tests aligns with the intended build configuration. The use ofEXCLUDE_FROM_ALL
andEXCLUDE_FROM_DEFAULT_BUILD
should be consistent with project requirements.Verification successful
Exclusion Logic Verified
The exclusion logic using
EXCLUDE_FROM_ALL
andEXCLUDE_FROM_DEFAULT_BUILD
is consistently applied in bothres/cmake/funcs.cmake
andres/cmake/def.cmake
. The logic aligns with the intended build configuration, ensuring that MPI tests are excluded from the default build when appropriate.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the exclusion logic for MPI tests in the build configuration. # Test: Search for the usage of `EXCLUDE_FROM_ALL` and `EXCLUDE_FROM_DEFAULT_BUILD`. Expect: Consistent usage across the project. rg --type cmake $'EXCLUDE_FROM_ALL|EXCLUDE_FROM_DEFAULT_BUILD'Length of output: 301
Script:
#!/bin/bash # Extract lines around the usage of EXCLUDE_FROM_ALL and EXCLUDE_FROM_DEFAULT_BUILD in res/cmake/def.cmake rg --type cmake --context 5 'EXCLUDE_FROM_ALL|EXCLUDE_FROM_DEFAULT_BUILD' res/cmake/def.cmakeLength of output: 622
src/amr/data/field/coarsening/magnetic_field_coarsener.hpp (3)
34-38
: Template parameter renaming improves clarity.The renaming of the template parameter from
dimension
todim
enhances clarity and consistency. Ensure that this change is propagated throughout the codebase.
52-59
: Ensure correct handling of field centering.The operator now uses
dim
instead ofdimension
. Verify that the logic for handling different field centerings is accurate and that all necessary cases are covered.Verification successful
Field Centering Logic Appears Comprehensive
The handling of field centering in
magnetic_field_coarsener.hpp
involves multiple conditional checks for different centering types. The logic seems to cover various cases, such as primal and dual centerings, across different directions. Ensure that these conditions align with the intended functionality and that any additional cases are considered if necessary.
- File:
src/amr/data/field/coarsening/magnetic_field_coarsener.hpp
- Lines: Several lines involving
centering_
, such as checks forprimal
anddual
centerings.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the handling of field centering logic in the codebase. # Test: Search for the usage of `centering_` and ensure all cases are handled. Expect: Comprehensive handling of all centering types. rg --type cpp $'centering_'Length of output: 1968
78-90
: Ensure 3D coarsening logic is implemented.The 3D coarsening method is currently implemented using nested arrays of lambda functions. Ensure that this logic is correct and consider simplifying it for better readability.
Verification successful
3D Coarsening Logic is Implemented, Review for Simplification
The 3D coarsening logic is implemented in the
MagneticFieldCoarsener
class. However, the use of lambda functions and nested arrays may add unnecessary complexity. Consider reviewing and simplifying this logic for better readability.
src/amr/data/field/coarsening/magnetic_field_coarsener.hpp
: Contains the implementation of thecoarsen
function for 3D.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the implementation of 3D coarsening logic. # Test: Search for the implementation details of 3D coarsening logic. Expect: Correct and complete implementation. rg --type cpp $'coarsen<3>'Length of output: 28
Script:
#!/bin/bash # Description: Search for the implementation of the 3D coarsening logic by looking for the coarsen function definition and usage. ast-grep --lang cpp --pattern 'coarsen<3, $_>($_, $_, $_, $_) { $$$ }'Length of output: 72
Script:
#!/bin/bash # Description: Search for the coarsen function definitions and related logic in the codebase. rg --type cpp 'coarsen' -A 10Length of output: 52778
src/amr/data/particles/refine/split_3d.hpp (4)
71-86
: Good use of lambda functions for clarity and reuse inLimePattern
.The lambda function
addSquare
effectively encapsulates repeated logic, enhancing code clarity and reusability.
95-114
: Good use of lambda functions for clarity and reuse inWhitePattern
.The lambda functions
addSquare
andaddSquares
effectively encapsulate repeated logic, enhancing code clarity and reusability.
123-293
: Initialization ofdelta
andweight
arrays inSplitter
is consistent and correct.The use of static constexpr arrays for
delta
andweight
ensures consistency and correctness across differentSplitter
configurations.
48-62
: Use structured bindings for clarity inPurplePattern
.The loop in
PurplePattern
constructor can be optimized for clarity by using structured bindings.- for (std::size_t i = 0; i < 2; i++) - { - std::size_t offset = i * 4; - float sign = i % 2 ? -1 : 1; - auto mode = delta * sign; - Super::deltas_[0 + offset] = {mode, mode, mode}; - Super::deltas_[1 + offset] = {mode, mode, -mode}; - Super::deltas_[2 + offset] = {mode, -mode, mode}; - Super::deltas_[3 + offset] = {mode, -mode, -mode}; - } + for (auto [index, sign] : {std::pair{0, 1.0f}, std::pair{4, -1.0f}}) + { + float mode = delta * sign; + Super::deltas_[index] = {mode, mode, mode}; + Super::deltas_[index + 1] = {mode, mode, -mode}; + Super::deltas_[index + 2] = {mode, -mode, mode}; + Super::deltas_[index + 3] = {mode, -mode, -mode}; + }Likely invalid or redundant comment.
pyphare/pyphare/pharesee/run/utils.py (1)
362-362
: Enhance flexibility in dimensionality handling.The change from
[nbrGhosts] * 2
to[nbrGhosts] * ndim
allows the function to handle different dimensionalities dynamically. This is a positive change.Ensure that all usages of
_get_rank
accommodate this change in dimensionality handling.pyphare/pyphare/pharesee/geometry.py (1)
63-74
: Support for 3D domain boxes added.The changes correctly extend the
domain_border_ghost_boxes
function to handle 3D domain boxes by adding "front" and "back" sides.src/core/data/ndarray/ndarray_vector.hpp (3)
127-128
: AddNO_DISCARD
tozstart
andzend
methods for consistency.The methods
zstart
andzend
in theMaskedView
class are missing theNO_DISCARD
attribute, which is used in other similar methods in this class. This attribute is important to prevent ignoring the return value of these methods.
390-427
: Consider performance optimizations infill3D
.The
fill3D
method correctly fills the 3D array using nested loops. However, consider exploring opportunities to optimize the performance by reducing the depth of nested loops, if feasible.
473-474
: Assertions for z-dimension enhance robustness.The expanded assertions for the z-dimension in the operator overload for
MaskedView
improve robustness by preventing out-of-bounds errors.Also applies to: 533-534
tests/core/numerics/interpolator/test_main.cpp (2)
776-783
: Uncomment and verify the test caseDepositCorrectlyTheirWeight_3d
.The test case is crucial for validating 3D interpolation correctness but is currently commented out. This needs to be active to ensure the functionality is tested properly.
788-788
: Remove unused static variablegtest_testInterpolator_ACollectionOfParticles_3d
.The static variable is defined but never used. Removing it will clean up the code.
tests/simulator/test_initialization.py (6)
254-256
: Use f-strings for string formatting.Python's f-string provides a more readable, concise, and less error-prone way of formatting strings compared to the
format
method.- "test_B_is_as_provided_by_user : dim {} interp_order : {}".format(dim, interp_order) + f"test_B_is_as_provided_by_user : dim {dim} interp_order : {interp_order}"
355-357
: Addition ofppc
parameter enhances flexibility.The inclusion of the
ppc
parameter allows for dynamic configuration of particle counts, improving the function's flexibility.
417-420
: Use ofndim
enhances clarity.Replacing
dim
withndim
improves clarity regarding the number of dimensions being processed in the function.
Line range hint
483-561
: Ensure plotting logic is conditional.The method
_test_density_decreases_as_1overSqrtN
includes plotting logic. Ensure that this code is conditional or wrapped in a method to avoid executing during automated test runs where graphical output is not feasible.
566-586
: Rename unused loop variablepi
to_pi
.The loop control variable
pi
is not used within the loop body. Rename it to_pi
to indicate that it's intentionally unused.- for pi, patch in enumerate(datahier.level(0).patches): + for _pi, patch in enumerate(datahier.level(0).patches):Tools
Ruff
582-582: Loop control variable
pi
not used within loop bodyRename unused
pi
to_pi
(B007)
586-586: Yoda condition detected
Rewrite as
ppc == H
(SIM300)
661-664
: Remove unused variableout
.The variable
out
is defined but not used. Remove the unused variable to avoid confusion.- out = "phare_outputs"
Tools
Ruff
664-664: Local variable
out
is assigned to but never usedRemove assignment to unused variable
out
(F841)
tests/simulator/test_advance.py (2)
370-372
: LGTM! Verify the usage of thecells
parameter.The addition of the
cells
parameter is a good enhancement for flexibility. Ensure that this parameter is used correctly in all relevant parts of the codebase.
Line range hint
399-420
: LGTM! Verify the usage of thecells
parameter.The addition of the
cells
parameter is a beneficial enhancement for flexibility. Ensure that this parameter is used correctly in all relevant parts of the codebase.pyphare/pyphare/pharesee/hierarchy.py (3)
651-651
: Testing for None should use the 'is' operator.Testing for None should use the 'is' operator for better readability and correctness.
- if qty == None: + if qty is None:Likely invalid or redundant comment.
Tools
Ruff
651-651: Comparison to
None
should becond is None
Replace with
cond is None
(E711)
GitHub Check: CodeQL
[notice] 651-651: Testing equality to None
Testing for None should use the 'is' operator.
121-121
: Overwriting attribute in super-class or sub-class.Assignment overwrites attribute
layout
, which was previously defined in superclassPatchData
. This might lead to unexpected behavior.Tools
GitHub Check: CodeQL
[warning] 121-121: Overwriting attribute in super-class or sub-class
Assignment overwrites attribute layout, which was previously defined in superclass PatchData.
1026-1056
: Review theplot3d
method for potential data handling issues.The
plot3d
method manipulates data dimensions and properties directly, which may lead to unintended side effects or data corruption. Specifically:
- Modifying
pdat._x
,pdat._y
, andpdat.dataset
directly affects the object state outside the local scope of this function, potentially impacting other parts of the application relying on these properties.- The method reduces the dimensionality of the data to 2D and delegates to
plot2d
. Ensure that this dimensional reduction is valid across all use cases.Consider encapsulating these transformations in a method within the relevant data classes to avoid side effects.
Tools
Ruff
1034-1034: Loop control variable
lvl
not used within loop bodyRename unused
lvl
to_lvl
(B007)
@@ -67,6 +67,7 @@ class PatternDispatcher | |||
using FineParticle = decltype(particles[0]); // may be a reference | |||
|
|||
core::apply(patterns, [&](auto const& pattern) { | |||
auto weight = static_cast<Weight_t>(pattern.weight_); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unused local variable weight
.
The variable weight
is declared but not used, leading to unnecessary clutter.
- auto weight = static_cast<Weight_t>(pattern.weight_);
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
auto weight = static_cast<Weight_t>(pattern.weight_); |
TEST(MaskedView3d, maskOps3) | ||
{ | ||
constexpr std::size_t dim = 3; | ||
constexpr std::uint32_t size0 = 10; | ||
constexpr std::uint32_t sizeCu = size0 * size0 * size0; | ||
using Mask = PHARE::core::NdArrayMask; | ||
|
||
auto sum = [](auto const& array) { return std::accumulate(array.begin(), array.end(), 0); }; | ||
|
||
{ | ||
NdArrayVector<dim> array{size0, size0, size0}; | ||
EXPECT_EQ(sum(array), 0); | ||
std::fill(array.begin(), array.end(), 1); | ||
EXPECT_EQ(sum(array), sizeCu); | ||
} | ||
|
||
{ | ||
NdArrayVector<dim> array{size0, size0, size0}; | ||
EXPECT_EQ(std::accumulate(array.begin(), array.end(), 0), 0); | ||
array[Mask{0}] = 1; | ||
EXPECT_EQ(std::accumulate(array.begin(), array.end(), 0), 488); | ||
|
||
// outter cells of a 10**3 cube = | ||
// (10 * 10 * 2) + (10 * 8 * 2) + (8 * 8 * 2); | ||
// or | ||
// (8 * 8 * 6) + (10 * 4) + (8 * 8); | ||
// = 488 | ||
} | ||
|
||
std::uint32_t ten = 10; | ||
PHARE::core::NdArrayVector<3> array(ten, ten, ten); | ||
|
||
array[Mask{0}] = 1; | ||
EXPECT_EQ(sum(array), 488); | ||
array[Mask{1}] >> array[Mask{0}]; | ||
EXPECT_EQ(sum(array), 0); | ||
|
||
array[Mask{2}] = 1; | ||
EXPECT_EQ(sum(array), 152); | ||
array[Mask{1}] = 1; | ||
EXPECT_EQ(sum(array), 448); | ||
array[Mask{1}] = 0; | ||
EXPECT_EQ(sum(array), 152); | ||
|
||
array[Mask{2}] >> array[Mask{1}]; | ||
EXPECT_EQ(sum(array), 448); | ||
array[Mask{2}] = 0; | ||
EXPECT_EQ(sum(array), 296); | ||
|
||
EXPECT_EQ(Mask{1}.nCells(array), 296); | ||
EXPECT_EQ(Mask{2}.nCells(array), 152); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! But remove unused variable and enhance comments.
The test logic is comprehensive and covers various scenarios effectively.
However, the variable dim
is unused and should be removed to clean up the code.
Additionally, the comments explaining the expected results of the operations could be expanded for clarity.
- constexpr std::size_t dim = 3;
- // outter cells of a 10**3 cube =
- // (10 * 10 * 2) + (10 * 8 * 2) + (8 * 8 * 2);
- // or
- // (8 * 8 * 6) + (10 * 4) + (8 * 8);
- // = 488
+ // Outer cells of a 10x10x10 cube are calculated as:
+ // (10 * 10 * 2) + (10 * 8 * 2) + (8 * 8 * 2) = 488
+ // Alternatively:
+ // (8 * 8 * 6) + (10 * 4) + (8 * 8) = 488
constexpr PinkPattern(float const weight, float const delta) | ||
: Super{weight} | ||
{ | ||
constexpr float zero = 0; | ||
|
||
for (std::size_t i = 0; i < 2; i++) | ||
{ | ||
std::size_t offset = i * 3; | ||
float sign = i % 2 ? -1 : 1; | ||
auto mode = delta * sign; | ||
|
||
Super::deltas_[0 + offset] = {mode, zero, zero}; | ||
Super::deltas_[1 + offset] = {zero, zero, mode}; | ||
Super::deltas_[2 + offset] = {zero, mode, zero}; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optimize initialization of deltas_
in PinkPattern
.
The constructor initializes deltas_
in a loop. Consider using a more efficient method or simplifying the logic for clarity and performance.
- constexpr PinkPattern(float const weight, float const delta)
- : Super{weight}
- {
- constexpr float zero = 0;
- for (std::size_t i = 0; i < 2; i++)
- {
- std::size_t offset = i * 3;
- float sign = i % 2 ? -1 : 1;
- auto mode = delta * sign;
- Super::deltas_[0 + offset] = {mode, zero, zero};
- Super::deltas_[1 + offset] = {zero, zero, mode};
- Super::deltas_[2 + offset] = {zero, mode, zero};
- }
- }
+ constexpr PinkPattern(float const weight, float const delta)
+ : Super{weight}, deltas_{
+ {delta, 0, 0}, {0, 0, delta}, {0, delta, 0},
+ {-delta, 0, 0}, {0, 0, -delta}, {0, -delta, 0}
+ } {}
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
constexpr PinkPattern(float const weight, float const delta) | |
: Super{weight} | |
{ | |
constexpr float zero = 0; | |
for (std::size_t i = 0; i < 2; i++) | |
{ | |
std::size_t offset = i * 3; | |
float sign = i % 2 ? -1 : 1; | |
auto mode = delta * sign; | |
Super::deltas_[0 + offset] = {mode, zero, zero}; | |
Super::deltas_[1 + offset] = {zero, zero, mode}; | |
Super::deltas_[2 + offset] = {zero, mode, zero}; | |
} | |
} | |
constexpr PinkPattern(float const weight, float const delta) | |
: Super{weight}, deltas_{ | |
{delta, 0, 0}, {0, 0, delta}, {0, delta, 0}, | |
{-delta, 0, 0}, {0, 0, -delta}, {0, -delta, 0} | |
} {} |
function(set_exe_paths_ binary) | ||
set_property(TEST ${binary} PROPERTY ENVIRONMENT "PYTHONPATH=${PHARE_PYTHONPATH}") | ||
# ASAN detects leaks by default, even in system/third party libraries | ||
set_property(TEST ${binary} APPEND PROPERTY ENVIRONMENT "ASAN_OPTIONS=detect_leaks=0") | ||
set_property(TEST ${binary} APPEND PROPERTY ENVIRONMENT PHARE_SKIP_CLI=1 ) | ||
endfunction(set_exe_paths_) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid hardcoding environment variables.
Consider parameterizing environment variables like PYTHONPATH
and ASAN_OPTIONS
to make the function more flexible and adaptable to different environments.
- set_property(TEST ${binary} PROPERTY ENVIRONMENT "PYTHONPATH=${PHARE_PYTHONPATH}")
- set_property(TEST ${binary} APPEND PROPERTY ENVIRONMENT "ASAN_OPTIONS=detect_leaks=0")
+ set_property(TEST ${binary} PROPERTY ENVIRONMENT "PYTHONPATH=$ENV{PHARE_PYTHONPATH}")
+ set_property(TEST ${binary} APPEND PROPERTY ENVIRONMENT "ASAN_OPTIONS=$ENV{ASAN_OPTIONS:-detect_leaks=0}")
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
function(set_exe_paths_ binary) | |
set_property(TEST ${binary} PROPERTY ENVIRONMENT "PYTHONPATH=${PHARE_PYTHONPATH}") | |
# ASAN detects leaks by default, even in system/third party libraries | |
set_property(TEST ${binary} APPEND PROPERTY ENVIRONMENT "ASAN_OPTIONS=detect_leaks=0") | |
set_property(TEST ${binary} APPEND PROPERTY ENVIRONMENT PHARE_SKIP_CLI=1 ) | |
endfunction(set_exe_paths_) | |
function(set_exe_paths_ binary) | |
set_property(TEST ${binary} PROPERTY ENVIRONMENT "PYTHONPATH=$ENV{PHARE_PYTHONPATH}") | |
set_property(TEST ${binary} APPEND PROPERTY ENVIRONMENT "ASAN_OPTIONS=$ENV{ASAN_OPTIONS:-detect_leaks=0}") | |
set_property(TEST ${binary} APPEND PROPERTY ENVIRONMENT PHARE_SKIP_CLI=1 ) | |
endfunction(set_exe_paths_) |
auto fine_start_index(core::Point<int, dim> const coarseIndex) const | ||
{ | ||
core::Point<int, dim> fineStartIndex; | ||
fineStartIndex[dirX] = coarseIndex[dirX] * this->ratio_; | ||
|
||
if constexpr (dimension > 1) | ||
if constexpr (dim > 1) | ||
{ | ||
fineStartIndex[dirY] = coarseIndex[dirY] * this->ratio_; | ||
if constexpr (dimension > 2) | ||
if constexpr (dim > 2) | ||
{ | ||
fineStartIndex[dirZ] = coarseIndex[dirZ] * this->ratio_; | ||
} | ||
} | ||
return AMRToLocal(fineStartIndex, sourceBox_); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optimize fine_start_index
calculation.
The method fine_start_index
calculates indices based on the ratio_
. Consider optimizing this calculation to reduce redundancy and improve performance.
auto fine_start_index(core::Point<int, dim> const coarseIndex) const {
core::Point<int, dim> fineStartIndex = coarseIndex * this->ratio_;
return AMRToLocal(fineStartIndex, sourceBox_);
}
h5_time_grp = data_file[h5_time_grp_key][time] | ||
patch_levels = {} | ||
|
||
for plvl_key in h5_time_grp.keys(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use key in dict
instead of key in dict.keys()
.
This is a more Pythonic way to check for the existence of a key in a dictionary.
- for plvl_key in h5_time_grp.keys():
+ for plvl_key in h5_time_grp:
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
for plvl_key in h5_time_grp.keys(): | |
for plvl_key in h5_time_grp: |
Tools
Ruff
1459-1459: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
assert False # fix | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace assert statement with NotImplementedError.
Using assert False
as a placeholder for not implemented functionality is not recommended. It's better to use NotImplementedError
to clearly indicate that the functionality is not yet implemented.
- assert False # fix
+ raise NotImplementedError("3D field refinement is not yet implemented.")
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
assert False # fix | |
raise NotImplementedError("3D field refinement is not yet implemented.") |
Tools
Ruff
106-106: Do not
assert False
(python -O
removes these calls), raiseAssertionError()
Replace
assert False
(B011)
if not isinstance(linestyles, dict): | ||
linestyles = dict(zip(usr_lvls, linestyles)) | ||
|
||
for lvl_nbr, lvl in self.levels(time).items(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unused loop variable.
The variable lvl
is not used within the loop. You can replace it with _
to indicate it's intentionally unused.
- for lvl_nbr, lvl in self.levels(time).items():
+ for lvl_nbr, _ in self.levels(time).items():
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
for lvl_nbr, lvl in self.levels(time).items(): | |
for lvl_nbr, _ in self.levels(time).items(): |
Tools
Ruff
960-960: Loop control variable
lvl
not used within loop bodyRename unused
lvl
to_lvl
(B007)
slice_coord = domain_coords(patch, qty)[slice_dim] | ||
cst_coord = domain_coords(patch, qty)[cst_dim] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potentially uninitialized local variables.
Local variables slice_dim
and cst_dim
may be used before they are initialized. Ensure they are properly initialized before use.
- if "x" in kwargs:
- c = kwargs["x"]
- slice_dim = 1
- cst_dim = 0
- else:
- c = kwargs["y"]
- slice_dim = 0
- cst_dim = 1
+ if "x" in kwargs:
+ c = kwargs["x"]
+ slice_dim = 1
+ cst_dim = 0
+ elif "y" in kwargs:
+ c = kwargs["y"]
+ slice_dim = 0
+ cst_dim = 1
+ else:
+ raise ValueError("Need to specify either 'x' or 'y' cut coordinate.")
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
slice_coord = domain_coords(patch, qty)[slice_dim] | |
cst_coord = domain_coords(patch, qty)[cst_dim] | |
if "x" in kwargs: | |
c = kwargs["x"] | |
slice_dim = 1 | |
cst_dim = 0 | |
elif "y" in kwargs: | |
c = kwargs["y"] | |
slice_dim = 0 | |
cst_dim = 1 | |
else: | |
raise ValueError("Need to specify either 'x' or 'y' cut coordinate.") | |
slice_coord = domain_coords(patch, qty)[slice_dim] | |
cst_coord = domain_coords(patch, qty)[cst_dim] |
Tools
GitHub Check: CodeQL
[failure] 677-677: Potentially uninitialized local variable
Local variable 'slice_dim' may be used before it is initialized.
[failure] 678-678: Potentially uninitialized local variable
Local variable 'cst_dim' may be used before it is initialized.
return sorted_patches | ||
|
||
dbu = domain_box.upper | ||
|
||
if dim == 2: | ||
sides = { | ||
"bottom": Box([0, 0], [domain_box.upper[0], 0]), | ||
"top": Box( | ||
[0, domain_box.upper[1]], [domain_box.upper[0], domain_box.upper[1]] | ||
), | ||
"left": Box([0, 0], [0, domain_box.upper[1]]), | ||
"right": Box( | ||
[domain_box.upper[0], 0], [domain_box.upper[0], domain_box.upper[1]] | ||
), | ||
"left": Box([0, 0], [0, dbu[1]]), | ||
"right": Box([dbu[0], 0], [dbu[0], dbu[1]]), | ||
"bottom": Box([0, 0], [dbu[0], 0]), | ||
"top": Box([0, dbu[1]], [dbu[0], dbu[1]]), | ||
} | ||
|
||
shifts = periodicity_shifts(domain_box) | ||
else: | ||
sides = { | ||
"left": Box([0, 0, 0], [0, dbu[1], dbu[2]]), | ||
"right": Box([dbu[0], 0, 0], [dbu[0], dbu[1], dbu[2]]), | ||
"bottom": Box([0, 0, 0], [dbu[0], 0, dbu[2]]), | ||
"top": Box([0, dbu[1], 0], [dbu[0], dbu[1], dbu[2]]), | ||
"front": Box([0, 0, 0], [dbu[0], dbu[1], 0]), | ||
"back": Box([0, 0, dbu[2]], [dbu[0], dbu[1], dbu[2]]), | ||
} | ||
|
||
def borders_per(box): | ||
return "".join( | ||
[key for key, side in sides.items() if box * side is not None] | ||
) | ||
shifts = periodicity_shifts(domain_box) | ||
|
||
for patch in patches: | ||
in_sides = borders_per(boxm.grow(patch.box, n_ghosts)) | ||
def borders_per(box): | ||
return "".join([key for key, side in sides.items() if box * side is not None]) | ||
|
||
if in_sides in shifts: # in_sides might be empty, so no borders | ||
for shift in shifts[in_sides]: | ||
patch_copy = copy(patch) | ||
shift_patch(patch_copy, shift) | ||
sorted_patches.append(patch_copy) | ||
for patch in patches: | ||
in_sides = "".join(sorted(borders_per(boxm.grow(patch.box, n_ghosts)))) | ||
|
||
if dim == 3: | ||
raise ValueError("not yet implemented") | ||
if in_sides in shifts: # in_sides might be empty, so no borders | ||
for shift in shifts[in_sides]: | ||
patch_copy = copy(patch) | ||
shift_patch(patch_copy, shift) | ||
sorted_patches.append(patch_copy) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid mutable default argument in get_periodic_list
.
Using mutable default arguments can lead to unexpected behavior. Consider initializing within the function.
- def get_periodic_list(patches, domain_box, n_ghosts=[]):
+ def get_periodic_list(patches, domain_box, n_ghosts=None):
+ if n_ghosts is None:
+ n_ghosts = []
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
return sorted_patches | |
dbu = domain_box.upper | |
if dim == 2: | |
sides = { | |
"bottom": Box([0, 0], [domain_box.upper[0], 0]), | |
"top": Box( | |
[0, domain_box.upper[1]], [domain_box.upper[0], domain_box.upper[1]] | |
), | |
"left": Box([0, 0], [0, domain_box.upper[1]]), | |
"right": Box( | |
[domain_box.upper[0], 0], [domain_box.upper[0], domain_box.upper[1]] | |
), | |
"left": Box([0, 0], [0, dbu[1]]), | |
"right": Box([dbu[0], 0], [dbu[0], dbu[1]]), | |
"bottom": Box([0, 0], [dbu[0], 0]), | |
"top": Box([0, dbu[1]], [dbu[0], dbu[1]]), | |
} | |
shifts = periodicity_shifts(domain_box) | |
else: | |
sides = { | |
"left": Box([0, 0, 0], [0, dbu[1], dbu[2]]), | |
"right": Box([dbu[0], 0, 0], [dbu[0], dbu[1], dbu[2]]), | |
"bottom": Box([0, 0, 0], [dbu[0], 0, dbu[2]]), | |
"top": Box([0, dbu[1], 0], [dbu[0], dbu[1], dbu[2]]), | |
"front": Box([0, 0, 0], [dbu[0], dbu[1], 0]), | |
"back": Box([0, 0, dbu[2]], [dbu[0], dbu[1], dbu[2]]), | |
} | |
def borders_per(box): | |
return "".join( | |
[key for key, side in sides.items() if box * side is not None] | |
) | |
shifts = periodicity_shifts(domain_box) | |
for patch in patches: | |
in_sides = borders_per(boxm.grow(patch.box, n_ghosts)) | |
def borders_per(box): | |
return "".join([key for key, side in sides.items() if box * side is not None]) | |
if in_sides in shifts: # in_sides might be empty, so no borders | |
for shift in shifts[in_sides]: | |
patch_copy = copy(patch) | |
shift_patch(patch_copy, shift) | |
sorted_patches.append(patch_copy) | |
for patch in patches: | |
in_sides = "".join(sorted(borders_per(boxm.grow(patch.box, n_ghosts)))) | |
if dim == 3: | |
raise ValueError("not yet implemented") | |
if in_sides in shifts: # in_sides might be empty, so no borders | |
for shift in shifts[in_sides]: | |
patch_copy = copy(patch) | |
shift_patch(patch_copy, shift) | |
sorted_patches.append(patch_copy) | |
def get_periodic_list(patches, domain_box, n_ghosts=None): | |
if n_ghosts is None: | |
n_ghosts = [] | |
return sorted_patches | |
dbu = domain_box.upper | |
if dim == 2: | |
sides = { | |
"left": Box([0, 0], [0, dbu[1]]), | |
"right": Box([dbu[0], 0], [dbu[0], dbu[1]]), | |
"bottom": Box([0, 0], [dbu[0], 0]), | |
"top": Box([0, dbu[1]], [dbu[0], dbu[1]]), | |
} | |
else: | |
sides = { | |
"left": Box([0, 0, 0], [0, dbu[1], dbu[2]]), | |
"right": Box([dbu[0], 0, 0], [dbu[0], dbu[1], dbu[2]]), | |
"bottom": Box([0, 0, 0], [dbu[0], 0, dbu[2]]), | |
"top": Box([0, dbu[1], 0], [dbu[0], dbu[1], dbu[2]]), | |
"front": Box([0, 0, 0], [dbu[0], dbu[1], 0]), | |
"back": Box([0, 0, dbu[2]], [dbu[0], dbu[1], dbu[2]]), | |
} | |
shifts = periodicity_shifts(domain_box) | |
def borders_per(box): | |
return "".join([key for key, side in sides.items() if box * side is not None]) | |
for patch in patches: | |
in_sides = "".join(sorted(borders_per(boxm.grow(patch.box, n_ghosts)))) | |
if in_sides in shifts: # in_sides might be empty, so no borders | |
for shift in shifts[in_sides]: | |
patch_copy = copy(patch) | |
shift_patch(patch_copy, shift) | |
sorted_patches.append(patch_copy) |
a3ad211
to
1378a02
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 26
🧹 Outside diff range and nitpick comments (71)
tests/diagnostic/job_3d.py.in (1)
8-10
: Consider adding directory validation.The script uses "overwrite" mode which could potentially delete existing test results. Consider adding directory validation and a more robust cleanup strategy.
+import os +import shutil + out = "phare_outputs/diags_3d/" +if os.path.exists(out): + shutil.rmtree(out) +os.makedirs(out, exist_ok=True) + simInput = {"diag_options": {"format": "phareh5", "options": {"dir": out, "mode" : "overwrite"}}}tests/diagnostic/test-diagnostics_3d.cpp (2)
9-27
: Consider improving test organization and coverage.The test cases follow a consistent pattern but could be enhanced:
- Consider using a parameterized test to reduce code duplication
- Add test cases for coarsening as mentioned in the PR description
Here's a suggested refactor:
+ struct TestParams { + const char* name; + void (*test_func)(TypeParam, const std::string&); + }; + std::vector<TestParams> const tests = { + {"fluid", fluid_test}, + {"particles", particles_test}, + {"electromag", electromag_test}, + {"allFromPython", allFromPython_test} + }; + for (const auto& test : tests) { + TYPED_TEST(Simulator3dTest, test.name) { + test.test_func(TypeParam{job_file}, out_dir); + } + }🧰 Tools
🪛 cppcheck
[performance] 24-24: Function parameter 'path' should be passed by const reference.
(passedByValue)
9-27
: Add missing coarsening tests.The PR description mentions "some coarsening tests missing". Consider adding test cases to verify the coarsening behavior in 3D simulations.
Would you like me to help create a template for the coarsening tests?
🧰 Tools
🪛 cppcheck
[performance] 24-24: Function parameter 'path' should be passed by const reference.
(passedByValue)
tests/amr/data/particles/refine/test_split.cpp (1)
Line range hint
25-31
: Consider expanding test coverage for 3D splitting patternsThe current test suite only verifies constexpr initialization. Given that this PR introduces 3D support and mentions missing coarsening tests, consider adding test cases for:
- Different 3D splitting patterns (Pink, Purple, Lime, White) mentioned in split_3d.hpp
- Edge cases specific to 3D particle refinement
- Validation of particle positions after splitting
Would you like me to help create additional test cases for these scenarios?
tools/python3/git.py (3)
13-16
: Improve robustness and maintainability.Consider these enhancements:
- Add parameter validation
- Add error handling
- Define the format string as a constant
+SHORT_FORMAT = '--pretty=format:"%h%x09%an%x09%ad%x09%s"' + def log(N=10, use_short=False): # https://git-scm.com/docs/pretty-formats - short = '--pretty=format:"%h%x09%an%x09%ad%x09%s"' if use_short else "" - return decode_bytes(run(f"git log -{N} {short}").stdout) + if not isinstance(N, int) or N < 1: + raise ValueError("N must be a positive integer") + try: + short = SHORT_FORMAT if use_short else "" + return decode_bytes(run(f"git log -{N} {short}", check=True).stdout) + except subprocess.CalledProcessError: + raise RuntimeError("Failed to get git log. Are you in a git repository?")
19-24
: Optimize branch existence check and add input validation.The current implementation can be improved by:
- Using a more efficient git command
- Adding input validation
- Removing the unused exception variable (as noted by static analysis)
def branch_exists(branch): + if not branch or not isinstance(branch, str): + raise ValueError("Branch name must be a non-empty string") try: - run(f"git show-branch {branch}", check=True) - except subprocess.CalledProcessError as e: + # Using rev-parse is more efficient than show-branch + run(f"git rev-parse --verify {branch}", check=True) + except subprocess.CalledProcessError: return False # exit failure means branch does not exist return True🧰 Tools
🪛 Ruff
22-22: Local variable
e
is assigned to but never usedRemove assignment to unused variable
e
(F841)
1-3
: Consider architectural improvements for better maintainability.Suggestions for improving the overall architecture:
- Define a custom exception class for git operations
- Create a context manager for git operations
- Add logging for better debugging
class GitError(Exception): """Base exception for git operations.""" pass class GitContext: """Context manager for git operations.""" def __enter__(self): if not self._is_git_repo(): raise GitError("Not a git repository") return self def __exit__(self, exc_type, exc_val, exc_tb): pass def _is_git_repo(self): try: run("git rev-parse --git-dir", check=True) return True except subprocess.CalledProcessError: return Falsetests/simulator/initialize/CMakeLists.txt (1)
21-21
: Consider documenting resource requirements.Since these tests are gated behind
highResourceTests
, it would be helpful to document the expected resource requirements (memory, CPU, execution time) in a comment.Add a comment like:
+ # 3D tests require significant resources: + # - Estimated memory: X GB + # - Approximate runtime: Y minutes if(highResourceTests)tests/simulator/advance/CMakeLists.txt (1)
21-24
: LGTM! Consider adding resource requirement documentation.The conditional block for 3D tests is well-structured and follows the existing pattern. However, since these are marked as "quite intensive", it would be helpful to document the expected resource requirements (memory, CPU, time) in a comment.
if(highResourceTests) # off by default as it's quite intensive + # Resource requirements: + # - Memory: ~XGB per MPI process + # - Expected runtime: ~X minutes phare_mpi_python3_exec(9 ${PHARE_MPI_PROCS} advance-3d-fields test_fields_advance_3d.py ${CMAKE_CURRENT_BINARY_DIR}) phare_mpi_python3_exec(9 ${PHARE_MPI_PROCS} advance-3d-particles test_particles_advance_3d.py ${CMAKE_CURRENT_BINARY_DIR})tests/simulator/initialize/test_fields_init_2d.py (1)
Line range hint
1-47
: Consider enhancing test coverage for edge cases.Given that this is part of a larger 3D implementation, consider adding tests for:
- Boundary conditions specific to 2D-3D transitions
- Edge cases where 2D and 3D implementations might diverge
- Performance characteristics with varying particle densities
This will help ensure robust behavior as the codebase evolves to support both 2D and 3D scenarios.
tests/simulator/advance/test_particles_advance_3d.py (1)
16-19
: Consider adding type hints to global constantsAdding type hints would improve code maintainability and IDE support.
-ndim = 3 -interp_orders = [1, 2, 3] -ppc = 5 +ndim: int = 3 +interp_orders: list[int] = [1, 2, 3] +ppc: int = 5tools/python3/cmake.py (3)
8-20
: Enhance function documentation with parameter descriptions.The docstring currently only mentions optimization flags but should document all parameters and their purpose. This would improve code maintainability and usability.
Add comprehensive parameter descriptions:
def make_config_str( path, samrai_dir=None, cxx_flags=None, use_ninja=False, use_ccache=False, extra="" ): """ + Constructs a CMake configuration command string. + + Args: + path: Path to the CMake project directory + samrai_dir: Optional path to SAMRAI installation + cxx_flags: Optional C++ compiler flags + use_ninja: Whether to use Ninja build system + use_ccache: Whether to enable ccache + extra: Additional CMake options + + Returns: + str: Formatted CMake configuration command + FULL UNPORTABLE OPTIMIZATIONS = cxx_flags="-O3 -march=native -mtune=native" """
30-31
: Add error handling for build system commands.The function should handle potential failures of the build commands and provide meaningful error messages.
def build(use_ninja=False, threads=1): - run("ninja" if use_ninja else f"make -j{threads}", capture_output=False) + try: + run("ninja" if use_ninja else f"make -j{threads}", capture_output=False) + except Exception as e: + raise RuntimeError(f"Build failed: {str(e)}")
34-37
: Make test list parsing more robust.The current implementation assumes a specific format of ctest output. Consider making the parsing more resilient to format changes.
def list_tests(): proc = run("ctest -N", capture_output=True) out = decode_bytes(proc.stdout) - return [line.split(" ")[-1] for line in out.splitlines()[1:-2]] + tests = [] + for line in out.splitlines(): + if line.startswith(" Test"): + test_name = line.strip().split(" ")[-1] + if test_name: + tests.append(test_name) + return teststests/simulator/initialize/test_fields_init_3d.py (4)
1-4
: Enhance the docstring with more details.While the docstring explains the isolation purpose, it would be helpful to include:
- What specific field initialization tests are performed
- Why these tests need to be isolated
- Any prerequisites or dependencies
""" This file exists independently from test_initialization.py to isolate dimension test cases and allow each to be overridden in some way if required. + + This test suite validates 3D field initialization including: + - Magnetic field (B) initialization + - Bulk velocity initialization + - Density initialization and scaling + + These tests are isolated to: + - Allow independent execution of resource-intensive 3D tests + - Enable specific overrides for 3D edge cases + - Maintain separate test configurations for 3D scenarios """
14-14
: Document the reason for Agg backend.Add a more descriptive comment explaining why the Agg backend is necessary.
-matplotlib.use("Agg") # for systems without GUI +matplotlib.use("Agg") # Use non-interactive backend for CI/CD environments and systems without GUI
16-18
: Document test parameters and consider moving to a configuration class.The test parameters lack documentation and could benefit from being centralized in a configuration class.
+# Test configuration parameters +# ndim: Number of dimensions for the simulation +# interp_orders: Interpolation orders to test (1st, 2nd, and 3rd order) +# ppc: Particles per cell +# cells: Number of cells in each dimension ndim = 3 interp_orders = [1, 2, 3] ppc, cells = 10, 20Consider creating a TestConfig class:
class TestConfig: """Configuration for 3D field initialization tests.""" ndim = 3 interp_orders = [1, 2, 3] ppc = 10 # particles per cell cells = 20 # cells per dimension
24-26
: Add docstrings to test methods.Each test method should document:
- Purpose of the test
- Expected behavior
- Test parameters
Example for the first test:
@data(*interp_orders) def test_B_is_as_provided_by_user(self, interp_order): + """ + Validate that the magnetic field is initialized correctly in 3D. + + Args: + interp_order: Interpolation order for the field initialization + """ print(f"\n{self._testMethodName}_{ndim}d") self._test_B_is_as_provided_by_user(ndim, interp_order, ppc=ppc, cells=cells)Also applies to: 29-33, 36-38, 41-45
tests/simulator/initialize/test_particles_init_2d.py (1)
Based on the search results from both scripts, I can now generate the final response:
Particle coarsening tests are indeed missing
The codebase only contains tests for field coarsening (
test_field_coarsening_via_subcycles
) but lacks specific tests for particle coarsening behavior. The existing coarsening tests are focused on:
- Field data coarsening in AMR
- Linear and weighted coarsening for fields
- Field coarsening via subcycles in 1D, 2D, and 3D
This confirms the original review comment's observation about missing coarsening tests for particles.
🔗 Analysis chain
Line range hint
26-107
: Consider adding missing coarsening testsWhile the test coverage for particle initialization, ghost particles, and domain particles is comprehensive, the PR objectives mention "some coarsening tests missing". Consider adding specific test cases to verify particle coarsening behavior in 2D contexts.
Let's check for existing coarsening tests in the codebase:
Would you like help implementing the missing coarsening test cases?
Let me check the content of these coarsening tests to understand if they cover particle coarsening or just field coarsening.
Let me check specifically for particle coarsening tests in the simulator directory:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for coarsening-related tests rg -l 'test.*coarsen|coarsening' tests/Length of output: 495
Script:
#!/bin/bash # Check content of coarsening tests rg -C 3 'test.*coarsen|coarsening.*particle' tests/Length of output: 6541
Script:
#!/bin/bash # Search for particle-related tests in simulator directory rg -C 3 'particle.*coarsen|coarsen.*particle' tests/simulator/Length of output: 64
src/core/data/grid/gridlayoutdefs.hpp (1)
18-18
: Consider documenting the rationale for explicit size specification.The change to use
std::uint16_t
as the underlying type forQtyCentering
provides a guaranteed 16-bit size, which is good for ABI stability and memory layout predictability. However, it would be helpful to document why this specific size was chosen, especially in the context of 3D simulations.Add a brief comment explaining the rationale:
+ // Using uint16_t to ensure consistent memory layout across platforms enum class QtyCentering : std::uint16_t { primal = 0, dual = 1 };
tests/simulator/initialize/test_particles_init_3d.py (2)
16-18
: Consider adding documentation for magic numbersWhile the constants are well-defined, consider adding comments to explain:
- Why these specific interpolation orders (1,2,3) were chosen
- What ppc=10 represents (particles per cell)
- Why cells=30 was chosen as the default
21-22
: Consider a more descriptive function nameThe function
per_interp
could be renamed to something more descriptive likegenerate_test_cases_per_interpolation_order
to better reflect its purpose.tests/simulator/advance/test_fields_advance_3d.py (2)
16-18
: Document the global constantsAdd docstrings or comments explaining the purpose and units of these constants:
- What does
ppc=10
represent (particles per cell)?- Why was
cells=30
chosen as the default grid size?- What's the significance of the chosen interpolation orders?
21-22
: Add docstring to helper functionAdd a docstring explaining:
- Purpose of the function
- Parameter
dic
: what type/format is expected- Return value: list of tuples with interpolation order and dictionary
res/cmake/options.cmake (1)
73-75
: Improve the option description to clarify its relationship withlowResourceTests
.The description should clarify that this option is mutually exclusive with
lowResourceTests
and specify what kinds of tests it enables.-option(highResourceTests "Enable heavy tests for CI (3d/etc" OFF) +option(highResourceTests "Enable resource-intensive tests (3D/coarsening) - mutually exclusive with lowResourceTests" OFF)src/core/utilities/meta/meta_utilities.hpp (1)
81-98
: Document the rationale for particle number choices per dimension.The particle numbers vary across dimensions:
- 1D: 2-5 particles
- 2D: 4-25 particles
- 3D: 6-12 particles
Consider adding documentation explaining these choices and their impact on simulation accuracy vs. performance.
tests/simulator/refined_particle_nbr.py (2)
44-47
: Improve variable naming and add documentationThe variable name
dim2
doesn't clearly convey its purpose as the border cell adjustment for 2D cases.- dim2 = refined_particle_nbr * ((cellNbr[0] * 2 + (cellNbr[1] * 2))) + # Calculate border cell adjustment for 2D: accounts for particles that may leave through + # the x and y boundaries (2 cells per dimension) + border_adjustment_2d = refined_particle_nbr * ((cellNbr[0] * 2 + (cellNbr[1] * 2))) if dim == 2: - return dim2 - return dim2 * (cellNbr[2] * 2) + return border_adjustment_2d + return border_adjustment_2d * (cellNbr[2] * 2) # Extend to 3D boundaries
117-135
: Enhance error handling for YAML configuration accessWhile the implementation is thorough, consider adding error handling for missing or malformed YAML configuration entries.
def _check_deltas_and_weights(self, dim, interp, refined_particle_nbr): + try: yaml_dim = self.yaml_root["dimension_" + str(dim)] yaml_interp = yaml_dim["interp_" + str(interp)] yaml_n_particles = yaml_interp["N_particles_" + str(refined_particle_nbr)] yaml_delta = [float(s) for s in str(yaml_n_particles["delta"]).split(" ")] yaml_weight = [float(s) for s in str(yaml_n_particles["weight"]).split(" ")] + except KeyError as e: + raise ValueError(f"Missing configuration for dim={dim}, interp={interp}, " + f"refined_particle_nbr={refined_particle_nbr}: {e}") + except ValueError as e: + raise ValueError(f"Invalid delta/weight values in configuration: {e}")src/amr/data/particles/refine/split_1d.hpp (3)
Line range hint
134-134
: Fix incorrect dispatcher name in constructor.The constructor uses
SplitPattern_1_2_2_Dispatcher
but should useSplitPattern_1_3_2_Dispatcher
to match the type alias.- : SplitPattern_1_2_2_Dispatcher{{weight[0], delta[0]}} + : SplitPattern_1_3_2_Dispatcher{{weight[0], delta[0]}}
184-185
: Maintain consistent formatting.The pattern dispatcher type definition spans multiple lines with inconsistent indentation compared to other similar definitions in the file.
- = PatternDispatcher<BlackPattern<DimConst<1>>, PinkPattern<DimConst<1>>, - PinkPattern<DimConst<1>>>; + = PatternDispatcher<BlackPattern<DimConst<1>>, PinkPattern<DimConst<1>>, PinkPattern<DimConst<1>>>;
Line range hint
1-199
: Consider adding documentation for weight and delta values.While the code references the wiki for splitting patterns, it would be beneficial to add inline documentation explaining the mathematical significance of the specific weight and delta values chosen for each splitter configuration. This would help maintainers understand the impact of modifying these values.
src/amr/data/field/coarsening/magnetic_field_coarsener.hpp (2)
62-75
: Simplify fine_start_index implementation using fold expressions.The nested if constexpr blocks can be replaced with a more concise implementation using C++17 fold expressions.
Consider this alternative implementation:
- auto fine_start_index(core::Point<int, dim> const coarseIndex) const - { - core::Point<int, dim> fineStartIndex; - fineStartIndex[dirX] = coarseIndex[dirX] * this->ratio_; - if constexpr (dim > 1) - { - fineStartIndex[dirY] = coarseIndex[dirY] * this->ratio_; - if constexpr (dim > 2) - { - fineStartIndex[dirZ] = coarseIndex[dirZ] * this->ratio_; - } - } - return AMRToLocal(fineStartIndex, sourceBox_); - } + auto fine_start_index(core::Point<int, dim> const coarseIndex) const + { + core::Point<int, dim> fineStartIndex; + [&]<std::size_t... I>(std::index_sequence<I...>) { + ((fineStartIndex[I] = coarseIndex[I] * ratio_), ...); + }(std::make_index_sequence<dim>{}); + return AMRToLocal(fineStartIndex, sourceBox_); + }
177-177
: Improve error message for invalid magnetic field configuration.The current error message "no magnetic field should end up here" is not descriptive enough. Consider including the actual centering configuration that caused the error.
- throw std::runtime_error("no magnetic field should end up here"); + throw std::runtime_error("Invalid magnetic field centering configuration: " + + std::to_string(static_cast<int>(centering_[0])) + "," + + std::to_string(static_cast<int>(centering_[1])) + "," + + std::to_string(static_cast<int>(centering_[2])));tests/core/data/ndarray/test_main.cpp (2)
411-422
: Enhance comments for better readability while maintaining correct logic.The test logic for mask operations is correct, but the comments explaining the outer cells calculation could be more readable.
Consider reformatting the comments for better clarity:
- // outter cells of a 10**3 cube = - // (10 * 10 * 2) + (10 * 8 * 2) + (8 * 8 * 2); - // or - // (8 * 8 * 6) + (10 * 4) + (8 * 8); - // = 488 + // Calculation of outer cells in a 10x10x10 cube: + // Method 1: Face centers + Face edges + Corner cells + // = (10×10×2) + (10×8×2) + (8×8×2) = 488 + // Method 2: Face cells + Edge corrections + Corner corrections + // = (8×8×6) + (10×4) + (8×8) = 488
424-446
: LGTM! Consider using existing constant.The test coverage for complex mask operations is comprehensive and well-structured.
Consider using the existing
size0
constant instead of creating a newten
variable:- std::uint32_t ten = 10; - PHARE::core::NdArrayVector<3> array(ten, ten, ten); + PHARE::core::NdArrayVector<3> array(size0, size0, size0);src/amr/data/particles/refine/split_2d.hpp (4)
Line range hint
37-55
: Consider adding type constraints to template parameterThe
Delta
template parameter inBrownPattern
constructor should be constrained to ensure it supports array-like access and has the correct size.- template<typename Delta> + template<typename Delta> + requires requires(Delta d) { + { d[0] } -> std::convertible_to<float>; + { d[1] } -> std::convertible_to<float>; + } constexpr BrownPattern(float const weight, Delta const& delta)
Line range hint
230-244
: Improve readability with consistent brace style and named constantsThe constructor initialization uses inconsistent brace style. Consider using named constants for magic numbers in delta array.
constexpr Splitter() - : SplitPattern_2_2_16_Dispatcher({weight[0], delta[0]}, {weight[1], delta}, - {weight[2], delta[1]}) + : SplitPattern_2_2_16_Dispatcher{{weight[0], delta[0]}, + {weight[1], delta}, + {weight[2], delta[1]}} { } - static constexpr std::array<float, 2> delta = {.5, 1.5}; + static constexpr float INNER_DELTA = 0.5f; + static constexpr float OUTER_DELTA = 1.5f; + static constexpr std::array<float, 2> delta = {INNER_DELTA, OUTER_DELTA};
324-327
: Improve readability of multi-line type aliasThe type alias has inconsistent indentation. Consider using line continuation character for better readability.
-using SplitPattern_2_3_25_Dispatcher - = PatternDispatcher<BlackPattern<DimConst<2>>, PinkPattern<DimConst<2>>, - PurplePattern<DimConst<2>>, PinkPattern<DimConst<2>>, - BrownPattern<DimConst<2>>, PurplePattern<DimConst<2>>>; +using SplitPattern_2_3_25_Dispatcher = \ + PatternDispatcher<BlackPattern<DimConst<2>>, \ + PinkPattern<DimConst<2>>, \ + PurplePattern<DimConst<2>>, \ + PinkPattern<DimConst<2>>, \ + BrownPattern<DimConst<2>>, \ + PurplePattern<DimConst<2>>>;
Tests needed for 2D splitting patterns
Based on the test files analysis, there are significant gaps in test coverage for 2D splitting patterns:
- Current tests only cover basic initialization (
test_split.cpp
) with a single test case for 2D:Splitter<2, 1, 8>
- Missing test coverage for:
- Different interpolation orders (1,2,3) in 2D
- Various particle counts (4,5,8,9,16,25) defined in
split_2d.hpp
- Pattern-specific tests (Purple, Brown, Pink patterns)
- Edge cases and boundary conditions
🔗 Analysis chain
Line range hint
1-349
: Verify test coverage for splitting patternsGiven the PR objectives mention "some coarsening tests missing", please ensure adequate test coverage exists for these 2D splitting patterns, especially for edge cases with different interpolation orders and particle counts.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for test files covering these splitting patterns echo "Searching for test files..." rg -l "split_2d" test/ # Look for specific pattern tests echo "Checking pattern test coverage..." rg -A 5 "TEST.*(?:Purple|Brown|Pink)Pattern.*2" test/Length of output: 312
Script:
#!/bin/bash # Let's first find the test directory structure fd -t d "test" # Then search for test files related to particle splitting or refinement fd -e cpp -e hpp "test|particle|split|refine" # Look for specific pattern tests in any directory rg -l "TEST.*(?:Purple|Brown|Pink)Pattern" # Search for any test files that might include split_2d.hpp rg -l "split_2d\.hpp"Length of output: 6557
Script:
#!/bin/bash # Let's check the content of the test files that might cover split patterns echo "Checking test_split.cpp content:" cat tests/amr/data/particles/refine/test_split.cpp echo -e "\nChecking test_particle_data_refine.cpp content:" cat tests/amr/data/particles/refine/test_particle_data_refine.cpp # Also check if there are any tests in the split.hpp that includes split_2d.hpp echo -e "\nChecking split.hpp content for tests:" cat src/amr/data/particles/refine/split.hppLength of output: 2415
Script:
#!/bin/bash # Let's check the test strategy file mentioned in the output echo "Checking test strategy file:" cat tests/amr/data/particles/refine/test_particledata_refine_basic_hierarchy.hpp # Also check for any test files in the test directory that might contain "particle" and "refine" echo -e "\nSearching for additional particle refinement test files:" rg -l "TEST.*particle.*refine" tests/ # Look for any test cases using the 2D splitter specifically echo -e "\nSearching for 2D splitter usage in tests:" rg "Splitter<.*2.*>" tests/Length of output: 8605
pyphare/pyphare/pharesee/run/utils.py (2)
Line range hint
362-368
: Implement missing 3D case in_get_rank
While the shape calculation now supports 3D, the function still raises "Not Implemented yet" for 3D cases. This is inconsistent with the PR's objective of adding 3D support.
Consider implementing the 3D case similar to the 2D implementation:
elif ndim == 2: data = np.zeros(shape) + int(patch_id.strip("p").split("#")[0]) return ({"name": "rank", "data": data, "centering": [centering] * 2},) + elif ndim == 3: + data = np.zeros(shape) + int(patch_id.strip("p").split("#")[0]) + return ({"name": "rank", "data": data, "centering": [centering] * 3},) else: raise RuntimeError("Not Implemented yet")Would you like me to help implement this change or create an issue to track this task?
Line range hint
1-507
: Consider documenting the 3D implementation roadmapThe file contains multiple functions that need 3D support (e.g.,
_divB2D
, slicing functions). While the PR description indicates this is intentional ("only some 3d split patterns"), consider:
- Adding TODO comments to mark pending 3D implementations
- Creating tracking issues for each function requiring 3D support
- Documenting the order and dependencies of the 3D implementation phases
This will help track progress and maintain clarity about which functionality is available for each dimensionality.
tests/simulator/test_initialization.py (2)
333-341
: Reduce code duplication in meshgrid operations.The meshgrid flattening operations are repeated three times with similar patterns. Consider extracting this into a helper function to improve maintainability.
+def flatten_meshgrid(*args): + return [a.flatten() for a in np.meshgrid(*args, indexing="ij")] + if dim == 3: zbx = bx_pd.z[:] zby = by_pd.z[:] zbz = bz_pd.z[:] - xbx, ybx, zbx = [ - a.flatten() for a in np.meshgrid(xbx, ybx, zbx, indexing="ij") - ] - xby, yby, zby = [ - a.flatten() for a in np.meshgrid(xby, yby, zby, indexing="ij") - ] - xbz, ybz, zbz = [ - a.flatten() for a in np.meshgrid(xbz, ybz, zbz, indexing="ij") - ] + xbx, ybx, zbx = flatten_meshgrid(xbx, ybx, zbx) + xby, yby, zby = flatten_meshgrid(xby, yby, zby) + xbz, ybz, zbz = flatten_meshgrid(xbz, ybz, zbz)
423-426
: Consider making empirical deviation values configurable.The empirical deviation values are hardcoded for each dimension. Consider making these configurable through test parameters or environment variables to allow for easier tuning and adjustment.
+def get_empirical_deviations(): + from os import environ + return { + 1: float(environ.get('EMPIRICAL_DEV_1D', '6e-3')), + 2: float(environ.get('EMPIRICAL_DEV_2D', '3e-2')), + 3: float(environ.get('EMPIRICAL_DEV_3D', '2e-1')), + } + -empirical_dim_devs = { - 1: 6e-3, - 2: 3e-2, - 3: 2e-1, -} +empirical_dim_devs = get_empirical_deviations()tests/functional/harris/harris_3d.py (2)
38-52
: Consider un-commenting 'strict=True' or documenting its omissionIn the
Simulation
constructor, the parameterstrict=True
is commented out. If this is intentional, consider adding a comment explaining whystrict
mode is disabled. If not, you may want to un-comment it to enforce stricter simulation settings for more robust error checking.
65-77
: Refactor duplicated code in 'by' and 'bx' functionsThe functions
by(x, y, z)
andbx(x, y, z)
share several common calculations, such as computingLx
,Ly
,w1
,w2
,x0
,y1
,y2
,w3
,w4
, andw5
. Refactoring these shared computations into a helper function can reduce code duplication and improve maintainability.Here's an example of how you can refactor the code:
def common_field_calculations(x, y): Lx = sim.simulation_domain()[0] Ly = sim.simulation_domain()[1] w1 = 0.2 w2 = 1.0 x0 = x - 0.5 * Lx y1 = y - 0.3 * Ly y2 = y - 0.7 * Ly w3 = np.exp(-(x0**2 + y1**2) / w2**2) w4 = np.exp(-(x0**2 + y2**2) / w2**2) w5 = 2.0 * w1 / w2 return x0, y1, y2, w3, w4, w5, Ly def by(x, y, z): x0, y1, y2, w3, w4, w5, _ = common_field_calculations(x, y) return (w5 * x0 * w3) + (-w5 * x0 * w4) def bx(x, y, z): x0, y1, y2, w3, w4, w5, Ly = common_field_calculations(x, y) v1 = -1 v2 = 1.0 return ( v1 + (v2 - v1) * (S(y, Ly * 0.3, 0.5) - S(y, Ly * 0.7, 0.5)) + (-w5 * y1 * w3) + (+w5 * y2 * w4) )Also applies to: 78-97
pyphare/pyphare/core/box.py (1)
185-198
: Improve variable naming for better readabilityIn the
remove_all
function, variables liketmp
andremove
can be renamed to more descriptive names to enhance code clarity and maintainability. For example,tmp
could be renamed tonew_remaining_boxes
, andremove
toindices_to_remove
.Apply this diff to improve variable names:
def remove_all(box, to_remove): if len(to_remove) > 0: remaining = box - to_remove[0] for to_rm in to_remove[1:]: - tmp, remove = [], [] + new_remaining_boxes, indices_to_remove = [], [] for i, rem in enumerate(remaining): if rem * to_rm is not None: - remove.append(i) - tmp += rem - to_rm + indices_to_remove.append(i) + new_remaining_boxes += rem - to_rm for rm in reversed(indices_to_remove): del remaining[rm] - remaining += tmp + remaining += new_remaining_boxes return remaining return boxres/cmake/funcs.cmake (2)
23-27
: Complete the incomplete comment.The comment in lines 23-27 ends abruptly and may cause confusion. Please complete the sentence to clarify its intent.
Suggested correction:
# Note to developers - do not use cmake variable function arguments for functions # phare_python3_exec # phare_mpi_python3_exec # if these function calls are to files executing python unit tests as they will interfere + # with argument parsing and test execution. Please pass explicit arguments instead.
115-128
: Consider usingFetchContent
or submodules for dependency management.Cloning external dependencies during the build process can lead to non-reproducible builds and issues when there is no internet connectivity. Using CMake's
FetchContent
module or Git submodules can provide more reliable and controlled dependency management for GTest.Example using
FetchContent
:include(FetchContent) FetchContent_Declare( googletest GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG release-1.11.0 ) FetchContent_MakeAvailable(googletest)
src/amr/data/particles/refine/split_3d.hpp (3)
90-92
: Maintain consistent use ofstruct
andclass
keywords
WhitePattern
is declared as aclass
, whereas other pattern types likePinkPattern
andPurplePattern
are declared asstruct
. For consistency and clarity, consider usingstruct
forWhitePattern
since its members are public.Apply this diff:
-template<> -class WhitePattern<DimConst<3>> : SplitPattern<DimConst<3>, RefinedParticlesConst<24>> +template<> +struct WhitePattern<DimConst<3>> : SplitPattern<DimConst<3>, RefinedParticlesConst<24>>
133-134
: Simplify static constants by usingfloat
instead ofstd::array<float, 1>
In several places,
delta
andweight
are defined asstd::array<float, 1>
but contain only one element. Usingfloat
directly would simplify the code and improve readability.Apply this diff for each occurrence:
-static constexpr std::array<float, 1> delta = {...}; -static constexpr std::array<float, 1> weight = {...}; +static constexpr float delta = ...; +static constexpr float weight = ...;Update the constructor initialization and any usages accordingly.
Also applies to: 151-152, 172-173, 193-194, 232-233, 252-253, 270-271, 291-292
121-174
: RefactorSplitter
specializations to reduce code duplicationThe
Splitter
specializations for differentInterpConst
andRefinedParticlesConst
combinations have similar structures with only variations indelta
,weight
, and pattern dispatchers. Consider refactoring to eliminate duplication, possibly by templating over these parameters or using a factory pattern.Also applies to: 181-235, 242-294
pyphare/pyphare/pharesee/geometry.py (1)
382-400
: Refactorsides
definition to eliminate code duplicationThe
sides
dictionary definitions for 2D and 3D cases are similar but duplicated. Consider refactoring this section to dynamically generate thesides
dictionary based on dimensionality, possibly using a helper function or loops. This will enhance maintainability and reduce potential errors.src/core/data/ndarray/ndarray_vector.hpp (2)
390-427
: Refactorfill3D
method to reduce code duplicationThe
fill3D
method contains multiple code blocks that perform similar operations for different borders (left, right, bottom, top, front, back). This repetition can make the code harder to maintain and prone to errors. Consider refactoring by creating helper functions or using parameterized loops to handle border filling more elegantly.For example, you can abstract the border filling into a helper lambda function:
auto fill_border = [&](auto i_range, auto j_range, auto k_range) { for (auto i : i_range) for (auto j : j_range) for (auto k : k_range) array(i, j, k) = val; }; // Left and right borders fill_border( std::vector{min_, shape[0] - 1 - max_}, range(min_, shape[1] - 1 - max_), range(min_, shape[2] - 1 - min_) ); // Top and bottom borders fill_border( range(min_, shape[0] - 1 - min_), std::vector{min_, shape[1] - 1 - max_}, range(min_, shape[2] - 1 - min_) ); // Front and back borders fill_border( range(min_, shape[0] - 1 - min_), range(min_, shape[1] - 1 - min_), std::vector{min_, shape[2] - 1 - max_} );This approach reduces repetition and enhances readability.
Line range hint
473-598
: Simplify boundary copying logic inoperator>>
for 3D arraysThe
operator>>
function for 3D arrays has complex and repetitive code, which can be difficult to maintain and understand. Refactoring this logic can improve code clarity and reduce potential bugs.Consider using nested loops or helper functions to generalize the boundary copying:
// Define ranges for inner and outer boundaries auto x_inner = range(inner.xstart(), inner.xend()); auto y_inner = range(inner.ystart(), inner.yend()); auto z_inner = range(inner.zstart(), inner.zend()); auto x_outer = range(outer.xstart(), outer.xend()); auto y_outer = range(outer.ystart(), outer.yend()); auto z_outer = range(outer.zstart(), outer.zend()); // Lambda to copy boundaries auto copy_boundary = [&](auto ix, auto iy, auto iz, auto ox, auto oy, auto oz) { outer(ox, oy, oz) = inner(ix, iy, iz); }; // Copy edges for (auto i : x_inner) { for (auto k : z_inner) { copy_boundary(i, inner.ystart(), k, i, outer.ystart(), k); copy_boundary(i, inner.yend(), k, i, outer.yend(), k); } } // ... (similar loops for other boundaries)This refactoring reduces code duplication and makes the boundary copying logic more scalable.
pyphare/pyphare/pharesee/hierarchy.py (17)
508-508
: Simplify dictionary iterationIn line 508, you can iterate over the dictionary directly instead of calling
.keys()
. This is more Pythonic and efficient.Apply this diff to simplify the code:
- particles = {popname: None for popname in aPatch.patch_datas.keys()} + particles = {popname: None for popname in aPatch.patch_datas}🧰 Tools
🪛 Ruff
508-508: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
726-726
: Unused loop variabletime
The loop variable
time
is not used in the loop starting at line 726. Consider renaming it to_
to indicate it's intentionally unused.Apply this diff:
- for time, levels in self.time_hier.items(): + for _, levels in self.time_hier.items():🧰 Tools
🪛 Ruff
726-726: Loop control variable
time
not used within loop bodyRename unused
time
to_time
(B007)
727-727
: Unused loop variableilvl
The loop variable
ilvl
is not used in the loop starting at line 727. Consider renaming it to_
to indicate it's intentionally unused.Apply this diff:
- for ilvl, lvl in levels.items(): + for _, lvl in levels.items():🧰 Tools
🪛 Ruff
727-727: Loop control variable
ilvl
not used within loop bodyRename unused
ilvl
to_ilvl
(B007)
746-746
: Unused loop variableilvl
The loop variable
ilvl
is not used in the loop starting at line 746. Consider renaming it to_
to indicate it's intentionally unused.Apply this diff:
- for ilvl, lvl in self.levels(time).items(): + for _, lvl in self.levels(time).items():🧰 Tools
🪛 Ruff
746-746: Loop control variable
ilvl
not used within loop bodyRename unused
ilvl
to_ilvl
(B007)
760-760
: Unused loop variableilvl
The loop variable
ilvl
is not used in the loop starting at line 760. Consider renaming it to_
to indicate it's intentionally unused.Apply this diff:
- for ilvl, lvl in self.levels(time).items(): + for _, lvl in self.levels(time).items():🧰 Tools
🪛 Ruff
760-760: Loop control variable
ilvl
not used within loop bodyRename unused
ilvl
to_ilvl
(B007)
790-790
: Unused loop variablet
The loop variable
t
is not used in the loop starting at line 790. Consider renaming it to_
to indicate it's intentionally unused.Apply this diff:
- for t, patch_levels in self.time_hier.items(): + for _, patch_levels in self.time_hier.items():🧰 Tools
🪛 Ruff
790-790: Loop control variable
t
not used within loop bodyRename unused
t
to_t
(B007)
877-877
: Simplify default value inkwargs.get
methodIn line 877, the code
kwargs.get("qty", None)
can be simplified tokwargs.get("qty")
sinceNone
is the default value.Apply this diff:
- qty = kwargs.get("qty", None) + qty = kwargs.get("qty")🧰 Tools
🪛 Ruff
877-877: Use
kwargs.get("qty")
instead ofkwargs.get("qty", None)
Replace
kwargs.get("qty", None)
withkwargs.get("qty")
(SIM910)
920-920
: Simplify default value inkwargs.get
methodIn line 920, the code
kwargs.get("legend", None)
can be simplified tokwargs.get("legend")
sinceNone
is the default value.Apply this diff:
- if kwargs.get("legend", None) is not None: + if kwargs.get("legend") is not None:🧰 Tools
🪛 Ruff
920-920: Use
kwargs.get("legend")
instead ofkwargs.get("legend", None)
Replace
kwargs.get("legend", None)
withkwargs.get("legend")
(SIM910)
1099-1099
: Unused loop variableip
The loop variable
ip
is not used in the loop starting at line 1099. Consider renaming it to_
to indicate it's intentionally unused.Apply this diff:
- for ip, patch in enumerate(level.patches): + for _, patch in enumerate(level.patches):🧰 Tools
🪛 Ruff
1099-1099: Loop control variable
ip
not used within loop bodyRename unused
ip
to_ip
(B007)
1281-1281
: Unused loop variableip
The loop variable
ip
is not used in the loop starting at line 1281. Consider renaming it to_
to indicate it's intentionally unused.Apply this diff:
- for ip, patch in enumerate(lvl.patches): + for _, patch in enumerate(lvl.patches):🧰 Tools
🪛 Ruff
1281-1281: Loop control variable
ip
not used within loop bodyRename unused
ip
to_ip
(B007)
1395-1395
: Simplify dictionary iterationIn line 1395, you can iterate over the dictionary directly instead of calling
.keys()
.Apply this diff:
- for dataset_name in h5_patch_grp.keys(): + for dataset_name in h5_patch_grp:🧰 Tools
🪛 Ruff
1395-1395: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
1459-1459
: Simplify dictionary iterationIn line 1459, you can iterate over the dictionary directly instead of calling
.keys()
.Apply this diff:
- for plvl_key in h5_time_grp.keys(): + for plvl_key in h5_time_grp:🧰 Tools
🪛 Ruff
1459-1459: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
1468-1468
: Simplify dictionary iterationIn line 1468, you can iterate over the dictionary directly instead of calling
.keys()
.Apply this diff:
- for pkey in h5_patch_lvl_grp.keys(): + for pkey in h5_patch_lvl_grp:🧰 Tools
🪛 Ruff
1468-1468: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
1505-1505
: Simplify dictionary iterationIn line 1505, you can iterate over the dictionary directly instead of calling
.keys()
.Apply this diff:
- for plvl_key in h5_time_grp.keys(): + for plvl_key in h5_time_grp:🧰 Tools
🪛 Ruff
1505-1505: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
1765-1765
: Unused loop variabletime
The loop variable
time
is not used in the loop starting at line 1765. Consider renaming it to_
to indicate it's intentionally unused.Apply this diff:
- for time, patch_levels in hierarchy.time_hier.items(): + for _, patch_levels in hierarchy.time_hier.items():🧰 Tools
🪛 Ruff
1765-1765: Loop control variable
time
not used within loop bodyRename unused
time
to_time
(B007)
1766-1766
: Unused loop variableilvl
The loop variable
ilvl
is not used in the loop starting at line 1766. Consider renaming it to_
to indicate it's intentionally unused.Apply this diff:
- for ilvl, plvl in patch_levels.items(): + for _, plvl in patch_levels.items():🧰 Tools
🪛 Ruff
1766-1766: Loop control variable
ilvl
not used within loop bodyRename unused
ilvl
to_ilvl
(B007)
1820-1820
: Simplify dictionary iterationIn line 1820, you can iterate over the dictionary directly instead of calling
.keys()
.Apply this diff:
- counts = {ilvl: 0 for ilvl in hier.levels().keys()} + counts = {ilvl: 0 for ilvl in hier.levels()}🧰 Tools
🪛 Ruff
1820-1820: Use
key in dict
instead ofkey in dict.keys()
Remove
.keys()
(SIM118)
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
📒 Files selected for processing (44)
.github/workflows/cmake_macos.yml
(1 hunks)pyphare/pyphare/core/box.py
(2 hunks)pyphare/pyphare/core/gridlayout.py
(1 hunks)pyphare/pyphare/pharesee/geometry.py
(7 hunks)pyphare/pyphare/pharesee/hierarchy.py
(1 hunks)pyphare/pyphare/pharesee/run/utils.py
(1 hunks)res/amr/splitting.yml
(1 hunks)res/cmake/funcs.cmake
(1 hunks)res/cmake/options.cmake
(2 hunks)src/amr/data/field/coarsening/magnetic_field_coarsener.hpp
(1 hunks)src/amr/data/particles/refine/split.hpp
(1 hunks)src/amr/data/particles/refine/split_1d.hpp
(10 hunks)src/amr/data/particles/refine/split_2d.hpp
(17 hunks)src/amr/data/particles/refine/split_3d.hpp
(1 hunks)src/amr/data/particles/refine/splitter.hpp
(2 hunks)src/core/data/grid/gridlayoutdefs.hpp
(2 hunks)src/core/data/ndarray/ndarray_vector.hpp
(8 hunks)src/core/utilities/box/box.hpp
(3 hunks)src/core/utilities/meta/meta_utilities.hpp
(2 hunks)tests/amr/data/field/refine/test_refine_field.py
(1 hunks)tests/amr/data/particles/refine/input/input_3d_ratio_2.txt
(1 hunks)tests/amr/data/particles/refine/test_split.cpp
(1 hunks)tests/core/data/ndarray/test_main.cpp
(1 hunks)tests/core/numerics/interpolator/test_main.cpp
(1 hunks)tests/diagnostic/CMakeLists.txt
(1 hunks)tests/diagnostic/job_3d.py.in
(1 hunks)tests/diagnostic/test-diagnostics_3d.cpp
(1 hunks)tests/functional/harris/harris_3d.py
(1 hunks)tests/simulator/__init__.py
(2 hunks)tests/simulator/advance/CMakeLists.txt
(1 hunks)tests/simulator/advance/test_fields_advance_3d.py
(1 hunks)tests/simulator/advance/test_particles_advance_3d.py
(1 hunks)tests/simulator/initialize/CMakeLists.txt
(1 hunks)tests/simulator/initialize/test_fields_init_2d.py
(1 hunks)tests/simulator/initialize/test_fields_init_3d.py
(1 hunks)tests/simulator/initialize/test_particles_init_1d.py
(0 hunks)tests/simulator/initialize/test_particles_init_2d.py
(1 hunks)tests/simulator/initialize/test_particles_init_3d.py
(1 hunks)tests/simulator/per_test.hpp
(1 hunks)tests/simulator/refined_particle_nbr.py
(2 hunks)tests/simulator/test_advance.py
(6 hunks)tests/simulator/test_initialization.py
(13 hunks)tools/python3/cmake.py
(1 hunks)tools/python3/git.py
(1 hunks)
💤 Files with no reviewable changes (1)
- tests/simulator/initialize/test_particles_init_1d.py
✅ Files skipped from review due to trivial changes (1)
- tests/amr/data/particles/refine/input/input_3d_ratio_2.txt
🧰 Additional context used
📓 Path-based instructions (11)
src/amr/data/field/coarsening/magnetic_field_coarsener.hpp (1)
Pattern **/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.
src/amr/data/particles/refine/split.hpp (1)
Pattern **/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.
src/amr/data/particles/refine/split_1d.hpp (1)
Pattern **/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.
src/amr/data/particles/refine/split_2d.hpp (1)
Pattern **/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.
src/amr/data/particles/refine/split_3d.hpp (1)
Pattern **/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.
src/amr/data/particles/refine/splitter.hpp (1)
Pattern **/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.
src/core/data/grid/gridlayoutdefs.hpp (1)
Pattern **/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.
src/core/data/ndarray/ndarray_vector.hpp (1)
Pattern **/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.
src/core/utilities/box/box.hpp (1)
Pattern **/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.
src/core/utilities/meta/meta_utilities.hpp (1)
Pattern **/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.
tests/simulator/per_test.hpp (1)
Pattern **/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.
🪛 Ruff
pyphare/pyphare/core/box.py
207-207: Ambiguous variable name: l
(E741)
pyphare/pyphare/pharesee/geometry.py
161-161: Ambiguous variable name: l
(E741)
164-164: Ambiguous variable name: l
(E741)
167-167: Ambiguous variable name: l
(E741)
188-188: Ambiguous variable name: l
(E741)
pyphare/pyphare/pharesee/hierarchy.py
508-508: Use key in dict
instead of key in dict.keys()
Remove .keys()
(SIM118)
520-520: Loop control variable ip
not used within loop body
Rename unused ip
to _ip
(B007)
621-621: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
651-651: Comparison to None
should be cond is None
Replace with cond is None
(E711)
726-726: Loop control variable time
not used within loop body
Rename unused time
to _time
(B007)
727-727: Loop control variable ilvl
not used within loop body
Rename unused ilvl
to _ilvl
(B007)
746-746: Loop control variable ilvl
not used within loop body
Rename unused ilvl
to _ilvl
(B007)
760-760: Loop control variable ilvl
not used within loop body
Rename unused ilvl
to _ilvl
(B007)
790-790: Loop control variable t
not used within loop body
Rename unused t
to _t
(B007)
877-877: Use kwargs.get("qty")
instead of kwargs.get("qty", None)
Replace kwargs.get("qty", None)
with kwargs.get("qty")
(SIM910)
920-920: Use kwargs.get("legend")
instead of kwargs.get("legend", None)
Replace kwargs.get("legend", None)
with kwargs.get("legend")
(SIM910)
960-960: Loop control variable lvl
not used within loop body
Rename unused lvl
to _lvl
(B007)
1018-1018: Use kwargs.get("legend")
instead of kwargs.get("legend", None)
Replace kwargs.get("legend", None)
with kwargs.get("legend")
(SIM910)
1034-1034: Loop control variable lvl
not used within loop body
Rename unused lvl
to _lvl
(B007)
1099-1099: Loop control variable ip
not used within loop body
Rename unused ip
to _ip
(B007)
1281-1281: Loop control variable ip
not used within loop body
Rename unused ip
to _ip
(B007)
1395-1395: Use key in dict
instead of key in dict.keys()
Remove .keys()
(SIM118)
1459-1459: Use key in dict
instead of key in dict.keys()
Remove .keys()
(SIM118)
1468-1468: Use key in dict
instead of key in dict.keys()
Remove .keys()
(SIM118)
1505-1505: Use key in dict
instead of key in dict.keys()
Remove .keys()
(SIM118)
1538-1538: Use key in dict
instead of key in dict.keys()
Remove .keys()
(SIM118)
1544-1544: Loop control variable ipatch
not used within loop body
(B007)
1561-1561: Use key in dict
instead of key in dict.keys()
Remove .keys()
(SIM118)
1765-1765: Loop control variable time
not used within loop body
Rename unused time
to _time
(B007)
1766-1766: Loop control variable ilvl
not used within loop body
Rename unused ilvl
to _ilvl
(B007)
1767-1767: Loop control variable ip
not used within loop body
Rename unused ip
to _ip
(B007)
1820-1820: Use key in dict
instead of key in dict.keys()
Remove .keys()
(SIM118)
tests/amr/data/field/refine/test_refine_field.py
106-106: Do not assert False
(python -O
removes these calls), raise AssertionError()
Replace assert False
(B011)
tests/functional/harris/harris_3d.py
62-62: Ambiguous variable name: l
(E741)
tests/simulator/__init__.py
325-325: Do not use mutable data structures for argument defaults
Replace with None
; initialize within function
(B006)
tests/simulator/test_advance.py
89-89: Ambiguous variable name: l
(E741)
tests/simulator/test_initialization.py
394-394: Function definition does not bind loop variable select
(B023)
396-396: Function definition does not bind loop variable patch
(B023)
396-396: Function definition does not bind loop variable nbrGhosts
(B023)
397-397: Function definition does not bind loop variable select
(B023)
582-582: Loop control variable pi
not used within loop body
Rename unused pi
to _pi
(B007)
586-586: Yoda condition detected
Rewrite as ppc == H
(SIM300)
664-664: Local variable out
is assigned to but never used
Remove assignment to unused variable out
(F841)
tools/python3/cmake.py
48-48: Undefined name cmd
(F821)
tools/python3/git.py
22-22: Local variable e
is assigned to but never used
Remove assignment to unused variable e
(F841)
29-29: Undefined name delete_branch
(F821)
🪛 GitHub Check: CodeQL
pyphare/pyphare/pharesee/hierarchy.py
[warning] 132-132: Overwriting attribute in super-class or sub-class
Assignment overwrites attribute layout, which was previously defined in superclass PatchData.
[notice] 270-270: Explicit returns mixed with implicit (fall through) returns
Mixing implicit and explicit returns may indicate an error as implicit returns always return None.
[warning] 651-651: Comparison of identical values
Comparison of identical values; use cmath.isnan() if testing for not-a-number.
[notice] 668-668: Testing equality to None
Testing for None should use the 'is' operator.
[failure] 694-694: Potentially uninitialized local variable
Local variable 'slice_dim' may be used before it is initialized.
[failure] 695-695: Potentially uninitialized local variable
Local variable 'cst_dim' may be used before it is initialized.
[notice] 1043-1043: Explicit returns mixed with implicit (fall through) returns
Mixing implicit and explicit returns may indicate an error as implicit returns always return None.
[notice] 1411-1411: Explicit returns mixed with implicit (fall through) returns
Mixing implicit and explicit returns may indicate an error as implicit returns always return None.
🪛 cppcheck
tests/diagnostic/test-diagnostics_3d.cpp
[performance] 24-24: Function parameter 'path' should be passed by const reference.
(passedByValue)
🔇 Additional comments (59)
src/amr/data/particles/refine/split.hpp (1)
6-6
: LGTM! The include hierarchy is well-structured.
The addition of split_3d.hpp
follows the existing pattern and maintains a clean separation of dimensionality-specific code.
Let's verify the consistency of the split header files:
✅ Verification successful
All dimension-specific split headers exist and maintain consistent structure
The verification confirms:
- All three dimension-specific headers (
split_1d.hpp
,split_2d.hpp
,split_3d.hpp
) exist in the expected location - Each header follows consistent naming and header guard patterns with the
PHARE_SPLIT_*D_HPP
format
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the existence and consistency of split header files
# Expected: All dimension-specific headers should exist and follow similar patterns
# Check if all split headers exist
fd "split_[123]d\.hpp" src/amr/data/particles/refine/
# Verify consistent header guards and basic structure across files
for dim in 1 2 3; do
echo "=== split_${dim}d.hpp ==="
rg -A 2 "^#ifndef.*SPLIT_${dim}D" src/amr/data/particles/refine/split_${dim}d.hpp
done
Length of output: 781
tests/diagnostic/job_3d.py.in (2)
1-7
: LGTM! Imports are well-organized.
The imports are appropriate for a 3D simulation test script, with clear separation between core library and test utilities.
11-11
: Verify interpolation order for 3D accuracy.
Using interp = 1
might lead to numerical artifacts in 3D simulations. Consider using a higher interpolation order (e.g., 2 or 3) for better accuracy in 3D space.
tests/diagnostic/test-diagnostics_3d.cpp (1)
30-35
: LGTM: Main function properly initializes test environment.
The main function correctly sets up both Google Test and PHARE lifecycle management.
tests/amr/data/particles/refine/test_split.cpp (1)
25-25
: LGTM: 3D splitter configuration follows the dimensional pattern
The addition of Splitter<3, 1, 27>
correctly extends the test coverage to 3D scenarios, following the logical progression from 1D (2 particles) and 2D (8 particles) to 3D (27 particles).
tests/simulator/initialize/CMakeLists.txt (1)
21-24
: LGTM! Verify the existence of 3D test files.
The conditional block is well-structured and follows the existing patterns for test configuration.
Let's verify the existence of the referenced test files:
✅ Verification successful
Both 3D test files are present in the expected location ✅
The verification confirms that both test files referenced in the CMakeLists.txt exist at the correct path:
- tests/simulator/initialize/test_fields_init_3d.py
- tests/simulator/initialize/test_particles_init_3d.py
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if the 3D test files exist in the current directory
# Expected: Both files should exist
fd "test_fields_init_3d.py|test_particles_init_3d.py" tests/simulator/initialize/
Length of output: 186
tests/simulator/advance/CMakeLists.txt (1)
22-23
: Verify the existence of 3D test files.
Let's ensure that the referenced Python test files exist in the repository.
✅ Verification successful
Both 3D test files are present in the repository
The verification confirms that both test files exist at the expected location:
tests/simulator/advance/test_fields_advance_3d.py
tests/simulator/advance/test_particles_advance_3d.py
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if the 3D test files exist in the repository
echo "Checking for 3D test files..."
fd -t f "test_fields_advance_3d.py|test_particles_advance_3d.py" tests/simulator/advance/
if [ $? -ne 0 ]; then
echo "Warning: One or more 3D test files not found"
exit 1
fi
Length of output: 281
tests/diagnostic/CMakeLists.txt (2)
37-37
: LGTM! 3D test executable addition follows existing pattern.
The addition of the 3D diagnostic test executable maintains consistency with the existing 1D and 2D test structure.
41-41
: Verify the existence of job_3d.py.in template file.
The configuration setup looks good and follows the established pattern for diagnostic job files.
✅ Verification successful
Template file job_3d.py.in exists and is properly located
The verification confirms that the template file job_3d.py.in
exists in the expected location at tests/diagnostic/
, validating the configure_file command's setup.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the existence of the 3D job template file
# Expected: job_3d.py.in should exist in the same directory
# Check if the template file exists
if [ -f "tests/diagnostic/job_3d.py.in" ]; then
echo "Template file exists"
else
echo "ERROR: Missing template file tests/diagnostic/job_3d.py.in"
exit 1
fi
Length of output: 93
tests/simulator/initialize/test_fields_init_2d.py (1)
26-26
: LGTM! Parameter name alignment improves consistency.
The change from nbr_part_per_cell
to ppc
aligns with the module-level constant defined on line 9, making the code more consistent.
tests/simulator/advance/test_particles_advance_3d.py (1)
6-14
: LGTM: Well-organized imports and appropriate matplotlib configuration
The imports are logically grouped and the matplotlib backend is correctly configured for headless environments.
tools/python3/cmake.py (1)
26-27
:
Fix missing use_ccache
parameter in make_config_str
call.
The function call is missing parameters which could lead to unexpected behavior.
- cmd = make_config_str(path, samrai_dir, cxx_flags, use_ninja, extra)
+ cmd = make_config_str(path, samrai_dir, cxx_flags, use_ninja, use_ccache, extra)
Likely invalid or redundant comment.
tests/simulator/initialize/test_fields_init_3d.py (1)
48-49
: LGTM!
Standard unittest main block is correctly implemented.
res/amr/splitting.yml (4)
102-141
: LGTM: Structure follows established pattern
The new dimension_3
section maintains consistent formatting and structure with existing dimensions.
117-128
: LGTM: Consistent delta progression
The delta values show a logical progression from interp_1, maintaining consistency with the patterns established in lower dimensions.
130-141
: Consider adding more particle configurations for interp_3
Looking at the pattern in dimension_1 and dimension_2, interp_3 typically includes additional particle configurations (e.g., N_particles_4, N_particles_5 in 1D, and N_particles_16, N_particles_25 in 2D). Consider if additional configurations should be added for completeness.
This aligns with the PR description mentioning "some coarsening tests missing" and "only some 3d split patterns".
113-115
:
Verify the weights for N_particles_27
The weights for N_particles_27 (0.125 + 0.0625 = 0.1875) seem low compared to other patterns. This might affect the interpolation quality.
Consider verifying these values against the mathematical model or simulation results. The sum of weights typically should be closer to 1 for proper interpolation.
.github/workflows/cmake_macos.yml (1)
90-90
: Verify and document the PHARE_SIMULATORS configuration
The addition of -DPHARE_SIMULATORS=2
needs verification:
- Does limiting to 2 simulators provide adequate coverage for the new 3D features?
- Will this support testing all implemented 3D split patterns?
Consider adding documentation about:
- The significance of the simulator count
- Which simulation patterns are enabled/disabled
tests/simulator/initialize/test_particles_init_2d.py (2)
26-26
: LGTM! Class name accurately reflects 2D testing scope
The renaming from Initialization1DTest
to Initialization2DTest
properly aligns with the file's purpose of isolating dimension-specific test cases.
Line range hint 33-65
: Verify consistency with 3D split patterns
The PR mentions "only some 3d split patterns". Please ensure that the split pattern tests in this 2D implementation (test_levelghostparticles_have_correct_split_from_coarser_particle
and test_domainparticles_have_correct_split_from_coarser_particle
) align with the available 3D patterns.
Let's check the corresponding 3D test patterns:
✅ Verification successful
Let me gather more information about the test patterns in both files.
Let me also check the domain particles test patterns in both files.
Split patterns are consistent between 2D and 3D implementations
The verification shows that both test files maintain consistent split pattern structures:
-
Level ghost particles test uses identical box configurations in both dimensions (just Box2D vs Box3D)
- Single box:
(10, 14)
- Two-level hierarchy:
L0(10, 14)
andL1(22, 26)
- Two boxes at same level:
L0(2, 6)
andL0(7, 11)
- Single box:
-
Domain particles test also maintains similar patterns with minor dimensional adjustments:
- 2D:
L0(5, 20), L1(15, 35)
vs 3D:L0(5, 14), L1(15, 19)
- Other patterns are identical between dimensions
- 2D:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for the corresponding 3D test file and compare split patterns
rg -A 5 'test_.*particles_have_correct_split' tests/simulator/initialize/test_particles_init_3d.py
Length of output: 1021
Script:
#!/bin/bash
# Search for test data patterns in both files
echo "=== 2D test patterns ==="
rg -B 5 'test_levelghostparticles_have_correct_split' tests/simulator/initialize/test_particles_init_2d.py
echo -e "\n=== 3D test patterns ==="
rg -B 5 'test_levelghostparticles_have_correct_split' tests/simulator/initialize/test_particles_init_3d.py
Length of output: 1377
Script:
#!/bin/bash
# Search for domain particles test patterns in both files
echo "=== 2D domain particles test patterns ==="
rg -B 5 'test_domainparticles_have_correct_split' tests/simulator/initialize/test_particles_init_2d.py
echo -e "\n=== 3D domain particles test patterns ==="
rg -B 5 'test_domainparticles_have_correct_split' tests/simulator/initialize/test_particles_init_3d.py
Length of output: 1423
src/core/data/grid/gridlayoutdefs.hpp (1)
5-5
: LGTM! Include directive properly placed.
The addition of <cstdint>
header is correctly placed in the include order (standard headers before project headers) and is necessary for std::uint16_t
.
tests/simulator/per_test.hpp (1)
111-114
: LGTM! Test fixture follows established patterns.
The Simulator3dTest
fixture follows the same clean and consistent implementation pattern as the existing 1D and 2D test fixtures.
tests/simulator/initialize/test_particles_init_3d.py (3)
1-14
: LGTM! Well-documented file purpose and appropriate imports.
The file's documentation clearly explains its purpose of isolating dimension test cases, and the imports are appropriate for the testing requirements.
97-98
: LGTM! Standard unittest main block.
The main block follows Python's unittest conventions.
25-75
: Verify test coverage for edge cases
The test cases cover basic scenarios with various box configurations, but consider adding tests for:
- Edge cases with minimum/maximum box dimensions
- Corner cases where boxes touch or overlap
- Error cases with invalid box dimensions
src/amr/data/particles/refine/splitter.hpp (3)
70-70
: Remove unused local variable.
This issue has been previously identified in past reviews.
118-121
: LGTM! Well-structured pattern implementation.
The BlackPattern structure follows C++ best practices with proper use of constexpr, inheritance, and type aliasing.
128-146
: Verify the empty pattern structures implementation plan.
The new pattern structures (Pink, Purple, Brown, Lime, White) are currently empty. While the PR description indicates this is intentional ("some 3d split patterns, the rest can come afterwards"), they should eventually follow the same implementation pattern as BlackPattern
:
template<typename dim>
struct PinkPattern : SplitPattern<dim, core::RefinedParticlesConst<N>> {
using Super = SplitPattern<dim, core::RefinedParticlesConst<N>>;
constexpr PinkPattern(float const weight)
: Super{weight}
{
}
};
✅ Verification successful
Empty pattern structures are forward declarations for dimension-specific implementations
The empty structures in splitter.hpp
are intentional forward declarations. The actual implementations are provided in dimension-specific files:
- 1D implementations in
split_1d.hpp
- 2D implementations in
split_2d.hpp
- 3D implementations in
split_3d.hpp
Each pattern is properly implemented with the correct inheritance from SplitPattern
and appropriate particle count constants:
PinkPattern
: Implemented for 1D (2 particles), 2D (4 particles), 3D (6 particles)PurplePattern
: Implemented for 2D (4 particles), 3D (8 particles)BrownPattern
: Implemented for 2D (8 particles)LimePattern
: Implemented for 3D (12 particles)WhitePattern
: Implemented for 3D (24 particles)
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check if there are any existing implementations of these patterns in other files
# that might serve as references for the implementation
echo "Searching for pattern implementations..."
rg -l "Pattern.*SplitPattern" --type cpp
echo "Checking for any TODO comments or implementation notes..."
rg -i "todo.*pattern|implement.*pattern" --type cpp
Length of output: 484
Script:
#!/bin/bash
# Let's examine the BlackPattern implementation and other pattern implementations
echo "=== Checking BlackPattern and related implementations ==="
rg "struct.*Pattern.*:.*SplitPattern" -A 5 --type cpp
echo "=== Checking if these patterns are used elsewhere ==="
rg "Pink(Pattern|Split)|Purple(Pattern|Split)|Brown(Pattern|Split)|Lime(Pattern|Split)|White(Pattern|Split)" --type cpp
Length of output: 11733
src/core/utilities/meta/meta_utilities.hpp (2)
94-94
: Review the commented out particle count 27
for 3D simulations.
The commented out value 27
in SimulatorOption<DimConst<3>, InterpConst<1>, 6, 12 /*, 27*/>
suggests a potential optimization opportunity. Consider documenting why this value is currently excluded and its performance implications.
✅ Verification successful
The commented out 27
particles per cell is intentionally excluded for 3D simulations
Based on the codebase analysis, the particle count choices are deliberate:
- 1D simulations use 2-5 particles per cell
- 2D simulations use 4-25 particles per cell
- 3D simulations currently use only 6 and 12 particles per cell
The exclusion of 27
appears intentional as the codebase shows a well-structured pattern of increasing particle counts based on dimensionality and interpolation order. The load balancing system (using "nppc" mode) and particle diagnostics are already designed to work with the current particle counts.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Search for related performance tests or documentation
# Expected: Find context about particle count choices
# Search for related test files and documentation
rg -g '!{*.o,*.so,*.a}' '(27|particle.*count|particles.*per.*cell)' test/
Length of output: 121
Script:
#!/bin/bash
# Let's try searching in the entire codebase for particle count patterns and documentation
rg -g '!{*.o,*.so,*.a}' '(particle.*count|particles.*per.*cell|nppc)' .
# Also search for any documentation about simulator options
rg -g '!{*.o,*.so,*.a}' 'SimulatorOption.*DimConst.*InterpConst' -A 3 .
Length of output: 11328
9-11
: Verify build configuration compatibility across different platforms.
The default value of 3 enables all simulator dimensions, but some build configurations (e.g., macOS workflow) override this with PHARE_SIMULATORS=2. This might lead to inconsistent behavior across different platforms.
tests/simulator/refined_particle_nbr.py (3)
105-116
: Well-documented 3D test implementation
The 3D test implementation is well structured with clear documentation of the refinement ratio calculations and appropriate test constants.
139-144
: Well-implemented test execution order
Good implementation of test ordering using TestSuite to ensure proper verification sequence. The approach correctly handles test dependencies while maintaining clean unittest patterns.
33-37
: 🛠️ Refactor suggestion
Add exception handling to tearDown method
While the null check is good, the method should handle potential exceptions during reset to ensure test cleanup completes gracefully.
def tearDown(self):
if self.simulator is not None:
- self.simulator.reset()
+ try:
+ self.simulator.reset()
+ except Exception as e:
+ print(f"Warning: Error during simulator reset: {e}")
Likely invalid or redundant comment.
src/amr/data/particles/refine/split_1d.hpp (1)
Line range hint 20-31
: LGTM! Clean implementation of PinkPattern specialization.
The template specialization is well-structured with proper use of constexpr and clear inheritance hierarchy.
src/core/utilities/box/box.hpp (1)
218-218
: LGTM: Deduction guide is well-implemented
The deduction guide correctly enables template argument deduction from Point parameters.
src/amr/data/field/coarsening/magnetic_field_coarsener.hpp (2)
99-114
: LGTM: 1D coarsening implementation is correct.
The implementation properly handles both primal and dual centering cases, maintaining magnetic flux conservation through appropriate averaging.
116-152
: LGTM: 2D coarsening implementation is correct.
The implementation properly handles all combinations of primal and dual centering, with appropriate averaging weights for flux conservation.
tests/core/data/ndarray/test_main.cpp (2)
395-403
: LGTM! Well-structured test setup.
The test setup is clean and well-organized. The lambda function for sum calculation improves code readability.
404-409
: LGTM! Good test coverage for basic operations.
The test block effectively verifies array initialization and filling operations with proper resource management through scoping.
pyphare/pyphare/core/gridlayout.py (1)
382-382
: Verify impact of changing withGhosts
default value.
The default value of withGhosts
parameter in yeeCoordsFor
has been changed from False
to True
. This could affect existing code that relies on the previous default behavior.
✅ Verification successful
Let me gather more context about the usage of yeeCoordsFor
to understand if the default parameter change impacts the behavior.
Default parameter change in yeeCoordsFor
is safe
The change in default value of withGhosts
from False
to True
is safe because:
- All direct calls to the method in production code (
pyphare/pharesee/run/utils.py
) use positional arguments and don't rely on the default value - The
meshCoords
method, which is the new caller, explicitly benefits from the new default value ofTrue
- Test cases in
test_coarsen_field.py
use the method through instance calls which already hadwithGhosts=True
as the default value
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for direct calls to yeeCoordsFor without explicit withGhosts parameter
rg -l "yeeCoordsFor\([^)]*\)" | while read -r file; do
echo "=== $file ==="
rg "yeeCoordsFor\([^)]*\)" "$file"
done
Length of output: 1172
Script:
#!/bin/bash
# Check the implementation and usage context of yeeCoordsFor
echo "=== Implementation of yeeCoordsFor ==="
rg -A 20 "def yeeCoordsFor" pyphare/pyphare/core/gridlayout.py
echo -e "\n=== Usage in meshCoords ==="
rg -A 10 "def meshCoords" pyphare/pyphare/core/gridlayout.py
echo -e "\n=== Test cases using yeeCoordsFor ==="
rg -B 2 -A 2 "yeeCoordsFor" tests/
Length of output: 2767
pyphare/pyphare/pharesee/run/utils.py (1)
362-362
: LGTM: Shape calculation now supports dynamic dimensionality
The change from hardcoded 2D to dynamic dimensionality is correct and aligns with the PR's 3D support objectives.
tests/core/numerics/interpolator/test_main.cpp (1)
776-783
:
Uncomment and verify the test case DepositCorrectlyTheirWeight_3d
.
The test case is crucial for validating 3D interpolation correctness but is currently commented out. This needs to be active to ensure the functionality is tested properly.
- // auto const& [vx, vy, vz] = this->v();
- // EXPECT_DOUBLE_EQ(this->rho(7, 7, 7), 1.0);
- // EXPECT_DOUBLE_EQ(vx(7, 7, 7), 2.0);
- // EXPECT_DOUBLE_EQ(vy(7, 7, 7), -1.0);
- // EXPECT_DOUBLE_EQ(vz(7, 7, 7), 1.0);
+ auto const& [vx, vy, vz] = this->v();
+ EXPECT_DOUBLE_EQ(this->rho(7, 7, 7), 1.0);
+ EXPECT_DOUBLE_EQ(vx(7, 7, 7), 2.0);
+ EXPECT_DOUBLE_EQ(vy(7, 7, 7), -1.0);
+ EXPECT_DOUBLE_EQ(vz(7, 7, 7), 1.0);
Likely invalid or redundant comment.
tests/simulator/test_initialization.py (1)
696-697
: LGTM: Proper dimension validation.
The dimension check using sim.cells
ensures the test is properly configured for the intended dimensionality.
tests/simulator/test_advance.py (6)
265-273
: LGTM: Improved slice selection logic.
The code now uses boxm.select
for consistent slice selection, which is a better approach than direct indexing.
370-372
: LGTM: Added cells parameter with sensible default.
The method signature update adds flexibility while maintaining backward compatibility.
399-400
: LGTM: Added cells parameter with sensible default.
Similar to the previous method, this signature update maintains backward compatibility.
413-420
: LGTM: Improved diagnostic output path construction.
The f-string based path construction improves readability and includes all relevant test parameters.
493-493
: 🛠️ Refactor suggestion
Replace magic number with a named constant.
The magic number -144123
should be defined as a named constant at the module level for better maintainability.
+# At the top of the file
+COARSE_TEST_MARKER = -144123
-boxm.DataSelector(afterCoarse)[dataBox] = -144123
+boxm.DataSelector(afterCoarse)[dataBox] = COARSE_TEST_MARKER
Likely invalid or redundant comment.
89-91
: 🛠️ Refactor suggestion
Rename parameter for better clarity.
The parameter name l
is ambiguous and could be mistaken for the number 1
. Consider using a more descriptive name.
-def S(x, x0, l):
- return 0.5 * (1 + np.tanh((x - x0) / l))
+def S(x, x0, length):
+ return 0.5 * (1 + np.tanh((x - x0) / length))
Likely invalid or redundant comment.
🧰 Tools
🪛 Ruff
89-89: Ambiguous variable name: l
(E741)
tests/functional/harris/harris_3d.py (1)
124-124
: Confirm that setting electron temperature 'Te=0.0' is intended
In the ElectronModel
, you have set Te=0.0
. An electron temperature of zero may not be physically meaningful and could lead to division by zero errors or other computational issues. Please verify that this is intentional and adjust the value if necessary.
pyphare/pyphare/core/box.py (1)
209-223
: The DataSelector
class implementation is correct
The DataSelector
class provides a convenient interface for data selection and assignment using Box
instances or slices. The methods __getitem__
and __setitem__
are correctly implemented and enhance the usability of data manipulation.
res/cmake/funcs.cmake (1)
28-182
: Overall review of test function definitions.
The test functions are well-defined and handle both MPI and non-MPI scenarios appropriately. The use of conditional logic based on testMPI
and execution levels ensures flexible and controlled test execution.
src/amr/data/particles/refine/split_3d.hpp (1)
95-97
:
Invalid use of templated constructor in a non-templated class
The WhitePattern
class is not a class template, but it has a templated constructor. In C++, you cannot have a templated constructor in a non-templated class. This will result in a compilation error.
To fix this issue, consider making the entire class a template or removing the template parameter from the constructor. If Delta
is always a specific type, you can specify it directly.
Apply this diff to make WhitePattern
a class template:
-template<>
-class WhitePattern<DimConst<3>> : SplitPattern<DimConst<3>, RefinedParticlesConst<24>>
+template<typename DeltaType>
+class WhitePattern<DimConst<3>, DeltaType> : SplitPattern<DimConst<3>, RefinedParticlesConst<24>>
Alternatively, remove the template from the constructor:
- template<typename Delta>
constexpr WhitePattern(float const weight, Delta const& delta)
Likely invalid or redundant comment.
pyphare/pyphare/pharesee/geometry.py (3)
59-60
: Addition of 'bottom' and 'top' ghost boxes for 2D domains
The inclusion of 'bottom'
and 'top'
ghost boxes in the 2D case appears correct and effectively handles domain borders for 2D simulations.
63-74
: Implementation of 3D ghost boxes in domain_border_ghost_boxes
The added code correctly handles the 3D case by defining ghost boxes for 'left'
, 'right'
, 'bottom'
, 'top'
, 'front'
, and 'back'
borders. This enhancement extends the function to support 3D domains properly.
184-188
:
Potential key collisions when sorting keys in shifts
dictionary
Reassigning the shifts
dictionary keys by sorting the characters in each key may lead to unintended key collisions:
shifts = {"".join(sorted(k)): l for k, l in shifts.items()}
For example, keys like 'left'
and 'felt'
would both become 'eflt'
when sorted. Please verify that this behavior is intentional and that it does not cause issues with key uniqueness.
To confirm whether any key collisions occur, consider adding a check within the code:
# After reassigning shifts
assert len(shifts) == len(set(shifts.keys())), "Key collision detected in shifts dictionary."
🧰 Tools
🪛 Ruff
188-188: Ambiguous variable name: l
(E741)
src/core/data/ndarray/ndarray_vector.hpp (1)
127-128
: Add NO_DISCARD
to zstart()
and zend()
methods for consistency
The methods zstart()
and zend()
are missing the NO_DISCARD
attribute, which is used in other similar methods (xstart
, xend
, ystart
, yend
) in the MaskedView
class. Adding NO_DISCARD
will help prevent unintended ignoring of return values.
pyphare/pyphare/pharesee/hierarchy.py (2)
960-960
: Unused loop variable lvl
The loop variable lvl
is not used in the loop starting at line 960. Consider renaming it to _
to indicate it's intentionally unused.
🧰 Tools
🪛 Ruff
960-960: Loop control variable lvl
not used within loop body
Rename unused lvl
to _lvl
(B007)
1034-1034
: Unused loop variable lvl
The loop variable lvl
is not used in the loop starting at line 1034. Consider renaming it to _
to indicate it's intentionally unused.
🧰 Tools
🪛 Ruff
1034-1034: Loop control variable lvl
not used within loop body
Rename unused lvl
to _lvl
(B007)
ph.Simulation(**basicSimulatorArgs(dim = 3, interp = 1, **simInput)) | ||
model = makeBasicModel() | ||
ElectronModel(closure="isothermal",Te = 0.12) | ||
dump_all_diags(model.populations) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add validation for model populations.
Verify that the model populations are properly initialized before dumping diagnostics.
-dump_all_diags(model.populations)
+if not model.populations:
+ raise ValueError("No populations found in the model")
+dump_all_diags(model.populations)
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
dump_all_diags(model.populations) | |
if not model.populations: | |
raise ValueError("No populations found in the model") | |
dump_all_diags(model.populations) |
def current_branch(): | ||
return decode_bytes(run("git branch --show-current").stdout) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add error handling for git command failure.
The function should handle cases where the git command fails, such as when not in a git repository or when git is not installed.
def current_branch():
- return decode_bytes(run("git branch --show-current").stdout)
+ try:
+ return decode_bytes(run("git branch --show-current", check=True).stdout)
+ except subprocess.CalledProcessError:
+ raise RuntimeError("Failed to get current branch. Are you in a git repository?")
Committable suggestion skipped: line range outside the PR's diff.
def hashes(N=1): | ||
return decode_bytes(run(f"git log -{N} --pretty=format:%h").stdout).splitlines() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add parameter validation and error handling.
The function should validate the input parameter and handle git command failures.
def hashes(N=1):
+ if not isinstance(N, int) or N < 1:
+ raise ValueError("N must be a positive integer")
+ try:
- return decode_bytes(run(f"git log -{N} --pretty=format:%h").stdout).splitlines()
+ return decode_bytes(run(f"git log -{N} --pretty=format:%h", check=True).stdout).splitlines()
+ except subprocess.CalledProcessError:
+ raise RuntimeError("Failed to get commit hashes. Are you in a git repository?")
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def hashes(N=1): | |
return decode_bytes(run(f"git log -{N} --pretty=format:%h").stdout).splitlines() | |
def hashes(N=1): | |
if not isinstance(N, int) or N < 1: | |
raise ValueError("N must be a positive integer") | |
try: | |
return decode_bytes(run(f"git log -{N} --pretty=format:%h", check=True).stdout).splitlines() | |
except subprocess.CalledProcessError: | |
raise RuntimeError("Failed to get commit hashes. Are you in a git repository?") |
def checkout(branch, create=False, recreate=False): | ||
if recreate: | ||
delete_branch(branch) | ||
create = True | ||
|
||
if create and not branch_exists(branch): | ||
run(f"git checkout -b {branch}") | ||
else: | ||
run(f"git checkout {branch}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix undefined function and improve error handling.
Critical issues and improvements needed:
- The
delete_branch
function is undefined - Missing input validation
- No error handling for git operations
+def delete_branch(branch):
+ """Delete a git branch locally."""
+ try:
+ run(f"git branch -D {branch}", check=True)
+ except subprocess.CalledProcessError:
+ raise RuntimeError(f"Failed to delete branch: {branch}")
+
def checkout(branch, create=False, recreate=False):
+ if not branch or not isinstance(branch, str):
+ raise ValueError("Branch name must be a non-empty string")
if recreate:
delete_branch(branch)
create = True
if create and not branch_exists(branch):
- run(f"git checkout -b {branch}")
+ try:
+ run(f"git checkout -b {branch}", check=True)
+ except subprocess.CalledProcessError:
+ raise RuntimeError(f"Failed to create and checkout branch: {branch}")
else:
- run(f"git checkout {branch}")
+ try:
+ run(f"git checkout {branch}", check=True)
+ except subprocess.CalledProcessError:
+ raise RuntimeError(f"Failed to checkout branch: {branch}")
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def checkout(branch, create=False, recreate=False): | |
if recreate: | |
delete_branch(branch) | |
create = True | |
if create and not branch_exists(branch): | |
run(f"git checkout -b {branch}") | |
else: | |
run(f"git checkout {branch}") | |
def delete_branch(branch): | |
"""Delete a git branch locally.""" | |
try: | |
run(f"git branch -D {branch}", check=True) | |
except subprocess.CalledProcessError: | |
raise RuntimeError(f"Failed to delete branch: {branch}") | |
def checkout(branch, create=False, recreate=False): | |
if not branch or not isinstance(branch, str): | |
raise ValueError("Branch name must be a non-empty string") | |
if recreate: | |
delete_branch(branch) | |
create = True | |
if create and not branch_exists(branch): | |
try: | |
run(f"git checkout -b {branch}", check=True) | |
except subprocess.CalledProcessError: | |
raise RuntimeError(f"Failed to create and checkout branch: {branch}") | |
else: | |
try: | |
run(f"git checkout {branch}", check=True) | |
except subprocess.CalledProcessError: | |
raise RuntimeError(f"Failed to checkout branch: {branch}") |
🧰 Tools
🪛 Ruff
29-29: Undefined name delete_branch
(F821)
def test_cmd(test, verbose=False): | ||
cmd = f"ctest -R {test}" | ||
if verbose: | ||
cmd = f"{cmd} -V" | ||
return cmd |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add input validation for test name parameter.
The function should validate the test name to prevent command injection and ensure it's a valid test name.
def test_cmd(test, verbose=False):
+ if not isinstance(test, str) or not test.strip():
+ raise ValueError("Test name must be a non-empty string")
+ # Sanitize test name to prevent command injection
+ test = test.replace('"', '').replace("'", '').replace(';', '')
cmd = f"ctest -R {test}"
if verbose:
cmd = f"{cmd} -V"
return cmd
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def test_cmd(test, verbose=False): | |
cmd = f"ctest -R {test}" | |
if verbose: | |
cmd = f"{cmd} -V" | |
return cmd | |
def test_cmd(test, verbose=False): | |
if not isinstance(test, str) or not test.strip(): | |
raise ValueError("Test name must be a non-empty string") | |
# Sanitize test name to prevent command injection | |
test = test.replace('"', '').replace("'", '').replace(';', '') | |
cmd = f"ctest -R {test}" | |
if verbose: | |
cmd = f"{cmd} -V" | |
return cmd |
from pyphare.simulator.simulator import Simulator | ||
from pyphare.simulator.simulator import startMPI | ||
|
||
os.environ["PHARE_SCOPE_TIMING"] = "0" # turn on scope timing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistency between environment variable value and comment
The comment states "turn on scope timing," but os.environ["PHARE_SCOPE_TIMING"]
is set to "0"
. Typically, setting this environment variable to "0"
disables scope timing. Please verify if the intended action is to turn scope timing on or off.
If the intent is to turn on scope timing, apply this diff:
-os.environ["PHARE_SCOPE_TIMING"] = "0" # turn on scope timing
+os.environ["PHARE_SCOPE_TIMING"] = "1" # turn on scope timing
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
os.environ["PHARE_SCOPE_TIMING"] = "0" # turn on scope timing | |
os.environ["PHARE_SCOPE_TIMING"] = "1" # turn on scope timing |
temp = 1.0 / density(x, y, z) * (K - b2(x, y, z) * 0.5) | ||
assert np.all(temp > 0) | ||
return temp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Replace 'assert' with explicit error handling for runtime checks
Using assert
statements for runtime checks is not recommended because assertions can be disabled with optimization settings, which could lead to unnoticed errors. In the function T(x, y, z)
, replace the assert
statement with explicit error handling to ensure that temp
is greater than zero during runtime.
Apply this change:
-def T(x, y, z):
- K = 1
- temp = 1.0 / density(x, y, z) * (K - b2(x, y, z) * 0.5)
- assert np.all(temp > 0)
- return temp
+def T(x, y, z):
+ K = 1
+ temp = 1.0 / density(x, y, z) * (K - b2(x, y, z) * 0.5)
+ if not np.all(temp > 0):
+ raise ValueError("Temperature 'temp' must be greater than zero.")
+ return temp
Committable suggestion skipped: line range outside the PR's diff.
if isinstance(other, (list, tuple)): | ||
assert all([isinstance(item, Box) for item in other]) | ||
return remove_all(self, other) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Replace assert
statements with explicit exception handling
Using assert
statements for type checking is not recommended in production code because they can be disabled when Python is run with optimization flags (e.g., python -O
). To ensure robust error handling, consider raising explicit exceptions like TypeError
.
Apply this diff to raise appropriate exceptions:
def __sub__(self, other):
if isinstance(other, (list, tuple)):
- assert all([isinstance(item, Box) for item in other])
+ if not all(isinstance(item, Box) for item in other):
+ raise TypeError("All items in 'other' must be instances of Box")
return remove_all(self, other)
- assert isinstance(other, Box)
+ if not isinstance(other, Box):
+ raise TypeError("'other' must be an instance of Box")
return remove(self, other)
Committable suggestion skipped: line range outside the PR's diff.
if (NOT EXISTS ${GTEST_ROOT}) | ||
execute_process(COMMAND ${Git} clone https://github.com/google/googletest ${GTEST_ROOT}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Define the Git
executable before using it.
The variable ${Git}
is used but not defined, which may lead to errors during the build process. Ensure that the Git
executable is properly located.
Suggested correction:
+ find_package(Git REQUIRED)
if (NOT EXISTS ${GTEST_ROOT})
- execute_process(COMMAND ${Git} clone https://github.com/google/googletest ${GTEST_ROOT})
+ execute_process(COMMAND ${GIT_EXECUTABLE} clone https://github.com/google/googletest ${GTEST_ROOT})
endif()
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if (NOT EXISTS ${GTEST_ROOT}) | |
execute_process(COMMAND ${Git} clone https://github.com/google/googletest ${GTEST_ROOT}) | |
find_package(Git REQUIRED) | |
if (NOT EXISTS ${GTEST_ROOT}) | |
execute_process(COMMAND ${GIT_EXECUTABLE} clone https://github.com/google/googletest ${GTEST_ROOT}) | |
endif() |
for (auto i = min_; i <= max_; ++i) | ||
array(i) = val; | ||
|
||
for (std::size_t i = shape[0] - 1 - max_; i <= shape[0] - 1 - min_; ++i) | ||
for (auto i = shape[0] - 1 - max_; i <= shape[0] - 1 - min_; ++i) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possible out-of-bounds access in fill1D
due to loop boundaries
In the fill1D
method, the loop boundaries might lead to out-of-bounds access when min_
or max_
have values that are not properly constrained. Specifically:
-
The first loop:
for (auto i = min_; i <= max_; ++i) array(i) = val;
-
The second loop:
for (auto i = shape[0] - 1 - max_; i <= shape[0] - 1 - min_; ++i) array(i) = val;
If min_
or max_
are larger than shape[0] / 2
, the indices could go beyond the array bounds. Ensure that min_
and max_
are validated against the array dimensions to prevent potential segmentation faults.
1378a02
to
669224a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 16
🧹 Outside diff range and nitpick comments (37)
tools/python3/git.py (1)
1-35
: Consider implementing a common error handling strategy.There's a consistent pattern of direct subprocess calls without proper error handling across all functions. Consider implementing a decorator or helper function to standardize error handling and input validation across all Git operations.
Example implementation:
def git_operation(func): def wrapper(*args, **kwargs): try: return func(*args, **kwargs) except subprocess.CalledProcessError as e: raise RuntimeError(f"Git operation failed: {e.stderr.decode() if e.stderr else str(e)}") except Exception as e: raise RuntimeError(f"Unexpected error during git operation: {str(e)}") return wrapperThis decorator could then be applied to all functions:
@git_operation def current_branch(): return decode_bytes(run("git branch --show-current", check=True).stdout)🧰 Tools
🪛 Ruff
22-22: Local variable
e
is assigned to but never usedRemove assignment to unused variable
e
(F841)
29-29: Undefined name
delete_branch
(F821)
tests/simulator/advance/test_particles_advance_3d.py (1)
16-18
: Consider parameterizing test constantsThese hardcoded test parameters could be moved to a configuration file or test fixtures to make the tests more maintainable and reusable.
-ndim = 3 -interp_orders = [1, 2, 3] -ppc = 5 +from .test_config import TEST_DIMENSIONS, INTERPOLATION_ORDERS, PARTICLES_PER_CELL + +ndim = TEST_DIMENSIONS["3D"] +interp_orders = INTERPOLATION_ORDERS +ppc = PARTICLES_PER_CELLtools/python3/cmake.py (2)
8-14
: Enhance docstring and add input validation.The docstring should document all parameters and their purpose. Additionally, the path parameter should be validated.
def make_config_str( path, samrai_dir=None, cxx_flags=None, use_ninja=False, use_ccache=False, extra="" ): """ - FULL UNPORTABLE OPTIMIZATIONS = cxx_flags="-O3 -march=native -mtune=native" + Constructs a CMake configuration command string. + + Args: + path: Path to the CMake project directory + samrai_dir: Optional path to SAMRAI installation + cxx_flags: Optional C++ compiler flags (e.g. "-O3 -march=native -mtune=native") + use_ninja: Whether to use Ninja build system + use_ccache: Whether to use ccache + extra: Additional CMake options + + Returns: + str: Formatted CMake command """ + if not path or not isinstance(path, str): + raise ValueError("Path must be a non-empty string")
30-31
: Add validation for threads parameter.The threads parameter should be validated to ensure it's a positive integer.
def build(use_ninja=False, threads=1): + if not isinstance(threads, int) or threads < 1: + raise ValueError("threads must be a positive integer") run("ninja" if use_ninja else f"make -j{threads}", capture_output=False)res/amr/splitting.yml (1)
102-102
: Remove unnecessary empty lineThis empty line creates inconsistent spacing between dimension sections.
tests/simulator/advance/test_fields_advance_3d.py (3)
6-14
: Consider grouping related imports together.The imports could be better organized by grouping them into standard library, third-party, and local imports.
import unittest - import matplotlib from ddt import data, ddt, unpack -from pyphare.core.box import Box3D - from tests.simulator.test_advance import AdvanceTestBase +from pyphare.core.box import Box3D matplotlib.use("Agg") # for systems without GUI
16-23
: Add type hints and improve documentation.The global constants and helper function would benefit from better documentation and type hints.
+# Constants for test configuration ndim = 3 interp_orders = [1, 2, 3] ppc, cells = 10, 30 -def per_interp(dic): +def per_interp(dic: dict) -> list[tuple[int, dict]]: + """Generate test cases for each interpolation order. + + Args: + dic: Dictionary containing test configuration + Returns: + List of tuples containing (interpolation_order, test_config) + """ return [(interp, dic) for interp in interp_orders]
33-47
: Add docstring to test method.The test method should document its purpose, parameters, and expected behavior.
def test_overlaped_fields_are_equal(self, interp_order, refinement_boxes): + """Test that overlapped fields maintain equality after advancement. + + Args: + interp_order: Interpolation order for the test + refinement_boxes: Dictionary defining the refinement box configuration + """ print(f"{self._testMethodName}_{ndim}d")tests/functional/harris/harris_3d.py (3)
22-22
: Consider making the output directory configurableThe diagnostic output path is hardcoded. Consider making it configurable through environment variables or command-line arguments for better flexibility across different environments.
-diag_outputs = "phare_outputs/test/harris/3d" +diag_outputs = os.getenv("PHARE_OUTPUT_DIR", "phare_outputs/test/harris/3d")
68-70
: Document or extract magic numbers as named constantsThe code contains several magic numbers (0.2, 1.0, 0.5) that would benefit from documentation or extraction as named constants to improve maintainability and understanding of the physics model.
+# Physical constants for the Harris sheet model +MAGNETIC_PERTURBATION_AMPLITUDE = 0.2 # Amplitude of magnetic perturbation +GAUSSIAN_WIDTH = 1.0 # Width of the Gaussian perturbation +SHEET_THICKNESS = 0.5 # Thickness of the current sheet def by(x, y, z): Lx = sim.simulation_domain()[0] Ly = sim.simulation_domain()[1] - w1 = 0.2 - w2 = 1.0 + w1 = MAGNETIC_PERTURBATION_AMPLITUDE + w2 = GAUSSIAN_WIDTHAlso applies to: 81-83
145-154
: Remove or document commented-out codeThe file contains several blocks of commented-out plotting code. If these are for future implementation, consider adding TODO comments. If they're no longer needed, consider removing them to improve code clarity.
Also applies to: 165-171
tests/simulator/refined_particle_nbr.py (1)
44-47
: Improve code clarity with better naming and documentationThe variable name 'dim2' doesn't clearly convey its purpose as the border cell particle count for 2D case.
- dim2 = refined_particle_nbr * ((cellNbr[0] * 2 + (cellNbr[1] * 2))) + # Calculate border cell particle count for 2D plane (X and Y faces) + border_particles_2d = refined_particle_nbr * ((cellNbr[0] * 2 + (cellNbr[1] * 2))) if dim == 2: - return dim2 - return dim2 * (cellNbr[2] * 2) + return border_particles_2d + # For 3D, multiply by Z-axis face contributions + return border_particles_2d * (cellNbr[2] * 2)pyphare/pyphare/core/box.py (2)
185-198
: Consider optimizing the implementation for better performanceThe current implementation could be improved in terms of performance and readability:
- Use list comprehension instead of explicit loops
- Avoid modifying lists while iterating
- Make the empty list check more pythonic
def remove_all(box, to_remove): - if len(to_remove) > 0: - remaining = box - to_remove[0] - for to_rm in to_remove[1:]: - tmp, remove = [], [] - for i, rem in enumerate(remaining): - if rem * to_rm is not None: - remove.append(i) - tmp += rem - to_rm - for rm in reversed(remove): - del remaining[rm] - remaining += tmp - return remaining - return box + if not to_remove: + return box + + remaining = box - to_remove[0] + for to_rm in to_remove[1:]: + # Use list comprehension to avoid explicit temporary lists + remaining = [ + piece + for rem in remaining + for piece in (rem - to_rm if rem * to_rm is not None else [rem]) + ] + return remaining
209-223
: Enhance error handling and documentationThe class implementation could benefit from:
- More robust error handling for invalid inputs
- Type hints for better code maintainability
- More comprehensive docstring with all supported operations
+from typing import Union, Any +import numpy as np + class DataSelector: """ - can't assign return to function unless [] - usage - DataSelector(data)[box] = val + A wrapper class for array-like data that supports Box-based indexing. + + Args: + data: Array-like object to be wrapped + + Examples: + >>> selector = DataSelector(data) + >>> subset = selector[Box([0,0], [1,1])] # Get subset + >>> selector[Box([0,0], [1,1])] = value # Set subset """ - def __init__(self, data): + def __init__(self, data: np.ndarray): + if not isinstance(data, np.ndarray): + raise TypeError("Data must be a numpy array") self.data = data - def __getitem__(self, box_or_slice): + + def __getitem__(self, box_or_slice: Union[Box, slice]) -> Any: if isinstance(box_or_slice, Box): return select(self.data, box_or_slice) + if not isinstance(box_or_slice, slice): + raise TypeError("Index must be a Box or slice") return self.data[box_or_slice] - def __setitem__(self, box_or_slice, val): + def __setitem__(self, box_or_slice: Union[Box, slice], val: Any) -> None: self.__getitem__(box_or_slice)[:] = valsrc/amr/data/particles/refine/split_2d.hpp (4)
Line range hint
42-53
: Consider simplifying the complex delta calculations in BrownPatternThe nested loop structure with offset calculations could be made more readable by extracting the delta calculations into a helper function or using a lookup table for the sign patterns.
Consider refactoring to:
template<typename Delta> constexpr BrownPattern(float const weight, Delta const& delta) : Super{weight} { static constexpr std::array<std::pair<int, int>, 2> signs = {{{1, 1}, {-1, -1}}}; for (std::size_t i = 0; i < signs.size(); i++) { const auto [signX, signY] = signs[i]; const std::size_t offset = i * 4; Super::deltas_[0 + offset] = {-delta[0] * signX, delta[1] * signY}; Super::deltas_[1 + offset] = {-delta[1] * signX, delta[0] * signY}; Super::deltas_[2 + offset] = {delta[0] * signX, delta[1] * signY}; Super::deltas_[3 + offset] = {delta[1] * signX, delta[0] * signY}; } }
Line range hint
74-327
: Add documentation for weight and delta value derivationsThe weight and delta values appear to be carefully chosen constants, but their derivation and significance are not documented. This makes it difficult to verify their correctness or modify them in the future.
Consider adding comments explaining:
- The mathematical basis for these constants
- How they ensure conservation properties
- References to relevant physics papers or documentation
Line range hint
1-7
: Enhance documentation with implementation detailsWhile the link to the wiki is helpful, consider adding more inline documentation about:
- The relationship between interpolation order and pattern selection
- The criteria for choosing between different pattern combinations
- Performance implications of different configurations
Add a detailed comment block:
/* * Splitting reference material can be found @ * https://github.com/PHAREHUB/PHARE/wiki/SplitPattern * * Implementation notes: * - Pattern selection depends on interpolation order and desired accuracy * - Higher interpolation orders use more complex pattern combinations * - Performance scales with number of refined particles * - Weight conservation is maintained across all patterns */
227-228
: Consider using template metaprogramming for pattern combination generationThe pattern combinations for higher-order interpolations (e.g., 16 and 25 particles) show a regular structure that could be generated using template metaprogramming.
This would:
- Reduce potential maintenance errors
- Make the pattern scaling more explicit
- Allow easier extension to higher orders
Also applies to: 324-326
pyphare/pyphare/pharesee/geometry.py (1)
Line range hint
87-188
: Improve readability by renaming ambiguous variable.The 3D periodicity shifts implementation is correct, but the variable name 'l' in list comprehensions is ambiguous.
Apply this diff to improve readability:
- f"{k}front": [(v[0], v[1], shape_z) for v in l] for k, l in shifts.items() + f"{k}front": [(v[0], v[1], shape_z) for v in shift_list] for k, shift_list in shifts.items()Similar changes should be applied to other occurrences of 'l' in list comprehensions.
🧰 Tools
🪛 Ruff
161-161: Ambiguous variable name:
l
(E741)
164-164: Ambiguous variable name:
l
(E741)
167-167: Ambiguous variable name:
l
(E741)
188-188: Ambiguous variable name:
l
(E741)
src/core/data/ndarray/ndarray_vector.hpp (2)
390-427
: Consider optimizing the 3D fill implementation.The current implementation, while correct, could benefit from performance improvements:
- Consider using OpenMP parallel for loops for large arrays
- Consider using SIMD instructions for the innermost loops
- Consider combining similar loops to reduce loop overhead
535-598
: Add documentation explaining the 3D mapping strategy.The 3D implementation is complex and would benefit from documentation explaining:
- The mapping strategy between inner and outer views
- The order of face/edge/corner copying
- The rationale behind using the corner lambda
tests/simulator/test_initialization.py (3)
254-254
: Inconsistent parameter naming across test methods.Some methods use
dim
while others usendim
. This inconsistency could lead to confusion.Standardize the parameter naming across all test methods to use either
dim
orndim
consistently.Also applies to: 356-357, 417-417, 566-566
423-426
: Consider documenting empirical deviation thresholds.The empirical deviation thresholds, especially for 3D (0.2), are significantly higher than 1D/2D. This might indicate potential precision issues in 3D simulations.
Consider adding a comment explaining why these specific thresholds were chosen and what they represent.
582-582
: Fix unused loop variable.The loop variable
pi
is not used in the loop body.-for pi, patch in enumerate(datahier.level(0).patches): +for _pi, patch in enumerate(datahier.level(0).patches):🧰 Tools
🪛 Ruff
582-582: Loop control variable
pi
not used within loop bodyRename unused
pi
to_pi
(B007)
pyphare/pyphare/pharesee/hierarchy/hierarchy.py (3)
559-561
: Add proper documentation for the plot3d method.The method lacks proper documentation explaining its behavior, parameters, and limitations. The "!HAX!" comment suggests this is a temporary solution, which should be documented.
def plot3d(self, **kwargs): - """!HAX!""" + """Plot 3D data by reducing it to 2D. + + This method takes a slice from the middle of the z-dimension and plots it as a 2D visualization. + Note: This is a temporary solution that modifies the data structures in-place. + + Args: + **kwargs: Keyword arguments passed to plot2d method. + Returns: + tuple: Figure and axes objects from matplotlib. + """
567-567
: Rename unused loop variable.The loop control variable
lvl
is not used within the loop body.- for lvl_nbr, lvl in self.levels(time).items(): + for lvl_nbr, _lvl in self.levels(time).items():🧰 Tools
🪛 Ruff
567-567: Loop control variable
lvl
not used within loop bodyRename unused
lvl
to_lvl
(B007)
588-588
: Remove informal comment.The shrug emoticon comment is informal and doesn't provide meaningful information about the code's behavior.
- return self.plot2d(**kwargs) # ¯\_(ツ)_/¯ + return self.plot2d(**kwargs) # Delegate to plot2d after reducing dimensionalitytests/simulator/test_advance.py (1)
493-493
: Define magic number as a constant.The magic number
-144123
should be defined as a named constant at the class level for better maintainability and clarity.+# At class level +COARSE_TEST_MARKER = -144123 # Marker value for coarsening test verification # In the method -boxm.DataSelector(afterCoarse)[dataBox] = -144123 +boxm.DataSelector(afterCoarse)[dataBox] = self.COARSE_TEST_MARKERres/cmake/funcs.cmake (1)
107-109
: Implement or remove the empty functionadd_phare_build_test
The function
add_phare_build_test
is currently empty. Consider implementing its functionality or removing it if it's not required to avoid confusion.src/amr/data/particles/refine/split_3d.hpp (8)
133-134
: Simplifydelta
andweight
by usingfloat
instead of single-element arraysSince
delta
andweight
contain only one value each, usingstd::array<float, 1>
adds unnecessary complexity. Consider defining them asfloat
variables for simplicity and improved readability.Apply this diff:
-static constexpr std::array<float, 1> delta = {.966431}; -static constexpr std::array<float, 1> weight = {.166666}; +static constexpr float delta = 0.966431f; +static constexpr float weight = 0.166666f;Update the constructor initialization accordingly:
- constexpr Splitter() - : SplitPattern_3_1_6_Dispatcher{{weight[0], delta[0]}} + constexpr Splitter() + : SplitPattern_3_1_6_Dispatcher{{weight, delta}}
151-152
: Simplifydelta
andweight
by usingfloat
instead of single-element arraysSimilar to the previous suggestion, define
delta
andweight
asfloat
variables to simplify the code.Apply this diff:
-static constexpr std::array<float, 1> delta = {.74823}; -static constexpr std::array<float, 1> weight = {.083333}; +static constexpr float delta = 0.74823f; +static constexpr float weight = 0.083333f;Update the constructor accordingly:
- constexpr Splitter() - : SplitPattern_3_1_12_Dispatcher{{weight[0], delta[0]}} + constexpr Splitter() + : SplitPattern_3_1_12_Dispatcher{{weight, delta}}
172-173
: Provide comments explaining the constants indelta
andweight
The specific values assigned to
delta
andweight
may not be immediately clear to readers. Adding comments to explain their origin or significance can enhance code understanding and maintainability.
193-194
: Simplifydelta
andweight
by usingfloat
instead of single-element arraysConsistently define
delta
andweight
asfloat
variables when they contain only one value.Apply this diff:
-static constexpr std::array<float, 1> delta = {1.149658}; -static constexpr std::array<float, 1> weight = {.166666}; +static constexpr float delta = 1.149658f; +static constexpr float weight = 0.166666f;Update the constructor:
- constexpr Splitter() - : SplitPattern_3_2_6_Dispatcher{{weight[0], delta[0]}} + constexpr Splitter() + : SplitPattern_3_2_6_Dispatcher{{weight, delta}}
211-212
: Simplifydelta
andweight
by usingfloat
instead of single-element arraysFor consistency and simplicity, use
float
variables fordelta
andweight
.Apply this diff:
-static constexpr std::array<float, 1> delta = {.888184}; -static constexpr std::array<float, 1> weight = {.083333}; +static constexpr float delta = 0.888184f; +static constexpr float weight = 0.083333f;And update the constructor:
- constexpr Splitter() - : SplitPattern_3_2_12_Dispatcher{{weight[0], delta[0]}} + constexpr Splitter() + : SplitPattern_3_2_12_Dispatcher{{weight, delta}}
252-253
: Simplifydelta
andweight
by usingfloat
instead of single-element arraysAgain, define
delta
andweight
asfloat
variables for clarity.Apply this diff:
-static constexpr std::array<float, 1> delta = {1.312622}; -static constexpr std::array<float, 1> weight = {.166666}; +static constexpr float delta = 1.312622f; +static constexpr float weight = 0.166666f;Update the constructor:
- constexpr Splitter() - : SplitPattern_3_3_6_Dispatcher{{weight[0], delta[0]}} + constexpr Splitter() + : SplitPattern_3_3_6_Dispatcher{{weight, delta}}
270-271
: Simplifydelta
andweight
by usingfloat
instead of single-element arraysMaintain consistency by defining
delta
andweight
asfloat
variables.Apply this diff:
-static constexpr std::array<float, 1> delta = {1.012756}; -static constexpr std::array<float, 1> weight = {.083333}; +static constexpr float delta = 1.012756f; +static constexpr float weight = 0.083333f;Update the constructor:
- constexpr Splitter() - : SplitPattern_3_3_12_Dispatcher{{weight[0], delta[0]}} + constexpr Splitter() + : SplitPattern_3_3_12_Dispatcher{{weight, delta}}
172-173
: Provide comments explaining the constants indelta
andweight
arraysIn these instances,
delta
andweight
are arrays with multiple values. Adding comments to describe the significance of these constants, such as their mathematical derivation or role in the algorithm, can improve code comprehension.Also applies to: 232-233, 291-292
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
📒 Files selected for processing (44)
.github/workflows/cmake_macos.yml
(1 hunks)pyphare/pyphare/core/box.py
(2 hunks)pyphare/pyphare/core/gridlayout.py
(1 hunks)pyphare/pyphare/pharesee/geometry.py
(7 hunks)pyphare/pyphare/pharesee/hierarchy/hierarchy.py
(1 hunks)pyphare/pyphare/pharesee/run/utils.py
(1 hunks)res/amr/splitting.yml
(1 hunks)res/cmake/funcs.cmake
(1 hunks)res/cmake/options.cmake
(2 hunks)src/amr/data/field/coarsening/magnetic_field_coarsener.hpp
(1 hunks)src/amr/data/particles/refine/split.hpp
(1 hunks)src/amr/data/particles/refine/split_1d.hpp
(10 hunks)src/amr/data/particles/refine/split_2d.hpp
(17 hunks)src/amr/data/particles/refine/split_3d.hpp
(1 hunks)src/amr/data/particles/refine/splitter.hpp
(2 hunks)src/core/data/grid/gridlayoutdefs.hpp
(2 hunks)src/core/data/ndarray/ndarray_vector.hpp
(8 hunks)src/core/utilities/box/box.hpp
(3 hunks)src/core/utilities/meta/meta_utilities.hpp
(2 hunks)tests/amr/data/field/refine/test_refine_field.py
(1 hunks)tests/amr/data/particles/refine/input/input_3d_ratio_2.txt
(1 hunks)tests/amr/data/particles/refine/test_split.cpp
(1 hunks)tests/core/data/ndarray/test_main.cpp
(1 hunks)tests/core/numerics/interpolator/test_main.cpp
(1 hunks)tests/diagnostic/CMakeLists.txt
(1 hunks)tests/diagnostic/job_3d.py.in
(1 hunks)tests/diagnostic/test-diagnostics_3d.cpp
(1 hunks)tests/functional/harris/harris_3d.py
(1 hunks)tests/simulator/__init__.py
(2 hunks)tests/simulator/advance/CMakeLists.txt
(1 hunks)tests/simulator/advance/test_fields_advance_3d.py
(1 hunks)tests/simulator/advance/test_particles_advance_3d.py
(1 hunks)tests/simulator/initialize/CMakeLists.txt
(1 hunks)tests/simulator/initialize/test_fields_init_2d.py
(1 hunks)tests/simulator/initialize/test_fields_init_3d.py
(1 hunks)tests/simulator/initialize/test_particles_init_1d.py
(0 hunks)tests/simulator/initialize/test_particles_init_2d.py
(1 hunks)tests/simulator/initialize/test_particles_init_3d.py
(1 hunks)tests/simulator/per_test.hpp
(1 hunks)tests/simulator/refined_particle_nbr.py
(2 hunks)tests/simulator/test_advance.py
(6 hunks)tests/simulator/test_initialization.py
(13 hunks)tools/python3/cmake.py
(1 hunks)tools/python3/git.py
(1 hunks)
💤 Files with no reviewable changes (1)
- tests/simulator/initialize/test_particles_init_1d.py
✅ Files skipped from review due to trivial changes (1)
- src/amr/data/particles/refine/split.hpp
🚧 Files skipped from review as they are similar to previous changes (21)
- .github/workflows/cmake_macos.yml
- pyphare/pyphare/core/gridlayout.py
- pyphare/pyphare/pharesee/run/utils.py
- res/cmake/options.cmake
- src/amr/data/field/coarsening/magnetic_field_coarsener.hpp
- src/amr/data/particles/refine/split_1d.hpp
- src/amr/data/particles/refine/splitter.hpp
- src/core/data/grid/gridlayoutdefs.hpp
- src/core/utilities/box/box.hpp
- src/core/utilities/meta/meta_utilities.hpp
- tests/amr/data/particles/refine/input/input_3d_ratio_2.txt
- tests/amr/data/particles/refine/test_split.cpp
- tests/core/data/ndarray/test_main.cpp
- tests/diagnostic/CMakeLists.txt
- tests/diagnostic/job_3d.py.in
- tests/simulator/advance/CMakeLists.txt
- tests/simulator/initialize/CMakeLists.txt
- tests/simulator/initialize/test_fields_init_2d.py
- tests/simulator/initialize/test_fields_init_3d.py
- tests/simulator/initialize/test_particles_init_2d.py
- tests/simulator/initialize/test_particles_init_3d.py
🧰 Additional context used
📓 Path-based instructions (4)
src/amr/data/particles/refine/split_2d.hpp (1)
Pattern **/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.
src/amr/data/particles/refine/split_3d.hpp (1)
Pattern **/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.
src/core/data/ndarray/ndarray_vector.hpp (1)
Pattern **/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.
tests/simulator/per_test.hpp (1)
Pattern **/*.hpp
: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.
🪛 Ruff
pyphare/pyphare/core/box.py
207-207: Ambiguous variable name: l
(E741)
pyphare/pyphare/pharesee/geometry.py
161-161: Ambiguous variable name: l
(E741)
164-164: Ambiguous variable name: l
(E741)
167-167: Ambiguous variable name: l
(E741)
188-188: Ambiguous variable name: l
(E741)
pyphare/pyphare/pharesee/hierarchy/hierarchy.py
567-567: Loop control variable lvl
not used within loop body
Rename unused lvl
to _lvl
(B007)
tests/amr/data/field/refine/test_refine_field.py
106-106: Do not assert False
(python -O
removes these calls), raise AssertionError()
Replace assert False
(B011)
tests/functional/harris/harris_3d.py
62-62: Ambiguous variable name: l
(E741)
tests/simulator/__init__.py
325-325: Do not use mutable data structures for argument defaults
Replace with None
; initialize within function
(B006)
tests/simulator/test_advance.py
89-89: Ambiguous variable name: l
(E741)
tests/simulator/test_initialization.py
394-394: Function definition does not bind loop variable select
(B023)
396-396: Function definition does not bind loop variable patch
(B023)
396-396: Function definition does not bind loop variable nbrGhosts
(B023)
397-397: Function definition does not bind loop variable select
(B023)
582-582: Loop control variable pi
not used within loop body
Rename unused pi
to _pi
(B007)
586-586: Yoda condition detected
Rewrite as ppc == H
(SIM300)
664-664: Local variable out
is assigned to but never used
Remove assignment to unused variable out
(F841)
tools/python3/cmake.py
48-48: Undefined name cmd
(F821)
tools/python3/git.py
22-22: Local variable e
is assigned to but never used
Remove assignment to unused variable e
(F841)
29-29: Undefined name delete_branch
(F821)
🪛 cppcheck
tests/diagnostic/test-diagnostics_3d.cpp
[performance] 24-24: Function parameter 'path' should be passed by const reference.
(passedByValue)
🔇 Additional comments (33)
tests/diagnostic/test-diagnostics_3d.cpp (3)
1-8
: LGTM! Header includes and constants are well-defined.
The includes are minimal and necessary, and the constants follow proper naming conventions.
9-27
: Test structure follows Google Test best practices.
The test cases are well-organized and follow proper testing patterns.
The previous suggestion about refactoring repeated code patterns in test cases is still valid and would improve maintainability.
🧰 Tools
🪛 cppcheck
[performance] 24-24: Function parameter 'path' should be passed by const reference.
(passedByValue)
30-35
: LGTM! Main function properly initializes test environment.
The setup includes both Google Test initialization and PHARE lifecycle management, following best practices.
tests/simulator/advance/test_particles_advance_3d.py (1)
6-14
: LGTM: Appropriate imports and matplotlib configuration
The imports are well-organized and the non-GUI matplotlib backend is correctly configured for CI environments.
res/amr/splitting.yml (3)
105-115
: Well-structured 3D particle configurations
The particle counts (6, 12, and 27) appropriately represent face-centered, edge-centered, and volumetric splitting patterns in 3D space.
Also applies to: 118-128, 131-141
107-107
: Verify weight distribution validation
The weights appear to be normalized across configurations, but it would be beneficial to verify:
- The mathematical basis for these specific weight values
- Whether these weights have been validated in 3D test scenarios
Also applies to: 111-111, 115-115, 120-120, 124-124, 128-128, 133-133, 137-137, 141-141
✅ Verification successful
Weight distribution is mathematically validated
The weight distributions in the YAML file are mathematically sound and follow a consistent pattern:
- For dimension_3, each interpolation level maintains weight normalization:
- N_particles_6: 6 * 0.166666 ≈ 1.0
- N_particles_12: 12 * 0.083333 ≈ 1.0
- N_particles_27: 8 * 0.125 + 19 * 0.0625 = 1.0 (interp_1)
- Similar balanced distributions for interp_2 and interp_3
The weights are carefully chosen to ensure particle conservation and proper normalization across different refinement levels and interpolation schemes.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for weight validation tests in the test suite
rg -l "N_particles_(6|12|27).*weight" --type cpp --type python | while read -r file; do
echo "=== $file ==="
rg "assert|expect" -C 2 "$file"
done
Length of output: 110
Script:
#!/bin/bash
# Search for test files with any extension
fd "test" --type f | while read -r file; do
echo "=== $file ==="
rg "N_particles_(6|12|27).*weight" -C 2 "$file"
done
# Also search for weight validation in source files
rg "N_particles_(6|12|27).*weight" -C 2
Length of output: 32063
Script:
#!/bin/bash
# Look for documentation or comments about weight validation
rg -C 3 "weight.*validation|weight.*distribution"
Length of output: 51
Script:
#!/bin/bash
# Check the YAML file directly to understand the weight distribution context
cat res/amr/splitting.yml
Length of output: 2454
103-141
: Clarify scope of missing 3D patterns
The PR description mentions that only some 3D split patterns are included. Could you please:
- Document which additional patterns are planned for future implementation
- Confirm if the current set of patterns (6, 12, and 27 particles) is sufficient for initial functionality
tests/simulator/per_test.hpp (1)
111-117
: The 3D test structure is well-defined but has limited parameter combinations.
The test structure follows the established pattern used for 1D and 2D tests. However, all three parameter combinations use the same refinement level (6), which might not provide sufficient coverage for different scenarios.
Note: A previous review comment already suggested expanding the 3D test coverage with additional parameter combinations. Please refer to that comment for detailed recommendations.
tests/simulator/advance/test_fields_advance_3d.py (1)
79-91
:
Implement the 3D coarsening test.
The PR objectives mention "some coarsening tests missing" and this test is crucial for validating 3D coarsening functionality. The test patterns are consistent with 1D and 2D implementations, and the base implementation in test_advance.py
already supports 3D cases.
✅ Verification successful
Let me gather more information about the base implementation mentioned in the review comment.
Let me check one more thing to understand the base implementation location.
Uncomment and implement the 3D coarsening test
The review comment is correct. The evidence shows that:
- The base implementation
_test_field_coarsening_via_subcycles
exists and is used by 1D and 2D tests - The 3D test is already written but commented out, with appropriate test cases using
Box3D
- The implementation follows the same pattern as 1D and 2D versions
- The test data includes comprehensive cases covering single boxes, multiple boxes, and multi-level scenarios
Simply uncomment the test method and its test data to enable 3D coarsening validation.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Verify coarsening test implementations in other dimensions
echo "=== 1D implementation ==="
rg "test_field_coarsening_via_subcycles" tests/simulator/advance/test_fields_advance_1d.py -A 5
echo -e "\n=== 2D implementation ==="
rg "test_field_coarsening_via_subcycles" tests/simulator/advance/test_fields_advance_2d.py -A 5
Length of output: 1096
Script:
#!/bin/bash
# Check the base implementation in test_advance.py
echo "=== Base implementation ==="
rg "_test_field_coarsening_via_subcycles" tests/simulator/advance/test_advance.py -A 10
# Check if the 3D test is actually implemented but just commented out
echo -e "\n=== 3D implementation status ==="
rg "test_field_coarsening_via_subcycles" tests/simulator/advance/test_fields_advance_3d.py -B 5 -A 5
Length of output: 1165
Script:
#!/bin/bash
# Find the actual base implementation location
echo "=== Finding base implementation ==="
fd -t f -e py advance --exec rg "_test_field_coarsening_via_subcycles" {} -l
# Check the implementation if found
echo -e "\n=== Base implementation details ==="
fd -t f -e py advance --exec rg "_test_field_coarsening_via_subcycles" {} -A 10
Length of output: 2359
tests/functional/harris/harris_3d.py (2)
62-62
: 🛠️ Refactor suggestion
Rename ambiguous parameter for clarity
The parameter l
is ambiguous and could be confused with the number 1. Consider using a more descriptive name.
-def S(y, y0, l):
+def S(y, y0, scale_length):
Likely invalid or redundant comment.
🧰 Tools
🪛 Ruff
62-62: Ambiguous variable name: l
(E741)
184-184
: Consider adding timeout to MPI barrier
The MPI barrier could potentially hang indefinitely if any rank fails. Consider implementing a timeout mechanism or error handling.
tests/simulator/refined_particle_nbr.py (4)
105-116
: LGTM! Well-documented 3D test implementation
The 3D test implementation is well thought out with clear documentation explaining the refinement ratios and expectations.
139-144
: LGTM! Good test execution order management
The test suite setup ensures proper test execution order, which is crucial for dependency management between tests.
33-37
: 🛠️ Refactor suggestion
Add exception handling to tearDown method
While the None check is good, the method should handle potential exceptions during reset to ensure proper cleanup.
def tearDown(self):
if self.simulator is not None:
- self.simulator.reset()
+ try:
+ self.simulator.reset()
+ except Exception as e:
+ print(f"Warning: Error during simulator reset: {e}")
+ # Ensure we don't mask test failures
+ if self._outcome.success:
+ raise
Likely invalid or redundant comment.
117-135
: Verify YAML configuration existence
The method assumes the YAML configuration contains all necessary values. Consider adding validation.
pyphare/pyphare/core/box.py (1)
201-204
: LGTM!
The coordinate translation logic is correct and well-implemented.
tests/simulator/__init__.py (2)
97-107
: LGTM! Consider adding test coverage.
The 3D periodic density implementation correctly extends the existing pattern from 1D and 2D versions, with proper handling of domain boundaries and exponential decay for density calculation.
318-345
:
Fix mutable default argument and improve implementation.
The debug tracer implementation needs several improvements:
- The mutable default argument is a Python gotcha that could lead to unexpected behavior
- Missing cleanup mechanism to reset the profiler
- Exception handling could leave indentation in inconsistent state
🧰 Tools
🪛 Ruff
325-325: Do not use mutable data structures for argument defaults
Replace with None
; initialize within function
(B006)
pyphare/pyphare/pharesee/geometry.py (4)
59-74
: LGTM! 3D ghost boxes implementation is correct and consistent.
The implementation properly handles all six faces of a 3D box while maintaining consistency with the existing 1D and 2D patterns.
184-188
: LGTM! Good use of assertion for key uniqueness.
The assertion ensures that all shift keys are unique when sorted, preventing potential overlaps or conflicts in the shift dictionary.
🧰 Tools
🪛 Ruff
188-188: Ambiguous variable name: l
(E741)
520-520
: LGTM! Correct implementation of remaining boxes calculation.
The implementation properly handles the calculation of remaining boxes after subtracting patch boxes.
380-414
:
Fix mutable default argument in function signature.
Using an empty list as a default argument can lead to unexpected behavior as it's shared between function calls.
Apply this diff to fix the issue:
-def get_periodic_list(patches, domain_box, n_ghosts=[]):
+def get_periodic_list(patches, domain_box, n_ghosts=None):
+ if n_ghosts is None:
+ n_ghosts = []
Likely invalid or redundant comment.
src/core/data/ndarray/ndarray_vector.hpp (2)
127-128
: Previous comment about NO_DISCARD still applies.
533-534
: Add bounds validation before array access.
While the assertions check the start/end relationships, consider adding bounds validation to ensure indices don't exceed array dimensions.
tests/core/numerics/interpolator/test_main.cpp (2)
776-783
: Uncomment and implement the 3D test case.
The test case for validating 3D interpolation is commented out and needs to be implemented.
741-741
:
Fix grid layout initialization for 3D.
The grid layout initialization is missing the nz
dimension, which is required for 3D tests.
- GridLayout_t layout{ConstArray<double, dim>(.1), {nx, ny}, ConstArray<double, dim>(0)};
+ GridLayout_t layout{ConstArray<double, dim>(.1), {nx, ny, nz}, ConstArray<double, dim>(0)};
Likely invalid or redundant comment.
tests/simulator/test_initialization.py (1)
664-664
:
Remove unused variable.
The variable out
is assigned but never used.
-out = "phare_outputs"
Likely invalid or redundant comment.
🧰 Tools
🪛 Ruff
664-664: Local variable out
is assigned to but never used
Remove assignment to unused variable out
(F841)
pyphare/pyphare/pharesee/hierarchy/hierarchy.py (1)
595-596
: LGTM: Plot method update for 3D support.
The update to the plot method correctly handles 3D cases by delegating to the plot3d method.
tests/simulator/test_advance.py (3)
265-273
: LGTM! Improved data selection implementation.
The use of boxm.select
for dataset slicing is a better approach, and the dtype check ensures data type consistency.
370-372
: LGTM! Good default value for cells parameter.
The addition of a default value for the cells
parameter makes the test more flexible while maintaining a reasonable test size.
89-91
: 🛠️ Refactor suggestion
Rename parameter for better clarity.
The parameter l
is ambiguous and could be confused with the number 1. Consider using a more descriptive name.
-def S(x, x0, l):
- return 0.5 * (1 + np.tanh((x - x0) / l))
+def S(x, x0, transition_width):
+ return 0.5 * (1 + np.tanh((x - x0) / transition_width))
Likely invalid or redundant comment.
🧰 Tools
🪛 Ruff
89-89: Ambiguous variable name: l
(E741)
res/cmake/funcs.cmake (2)
118-119
: Variable ${Git}
is undefined
The previous review comment about defining the ${Git}
executable before using it is still valid. Ensure that you locate the Git executable using find_package(Git REQUIRED)
and replace ${Git}
with ${GIT_EXECUTABLE}
.
37-42
: Avoid hardcoding environment variables
The previous review comment regarding hardcoding environment variables like PYTHONPATH
and ASAN_OPTIONS
is still applicable. Consider parameterizing these environment variables to enhance flexibility and adaptability.
|
||
#include "core/def/phare_mpi.hpp" | ||
|
||
#include "test_diagnostics.ipp" | ||
|
||
static std::string const job_file = "job_3d"; | ||
static std::string const out_dir = "phare_outputs/diags_3d/"; | ||
|
||
TYPED_TEST(Simulator3dTest, fluid) | ||
{ | ||
fluid_test(TypeParam{job_file}, out_dir); | ||
} | ||
|
||
TYPED_TEST(Simulator3dTest, particles) | ||
{ | ||
particles_test(TypeParam{job_file}, out_dir); | ||
} | ||
|
||
TYPED_TEST(Simulator3dTest, electromag) | ||
{ | ||
electromag_test(TypeParam{job_file}, out_dir); | ||
} | ||
|
||
TYPED_TEST(Simulator3dTest, allFromPython) | ||
{ | ||
allFromPython_test(TypeParam{job_file}, out_dir); | ||
} | ||
|
||
|
||
int main(int argc, char** argv) | ||
{ | ||
::testing::InitGoogleTest(&argc, argv); | ||
PHARE::SamraiLifeCycle samsam(argc, argv); | ||
return RUN_ALL_TESTS(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
3D test coverage needs expansion in specific areas
Based on the code analysis, there are clear gaps in 3D test coverage:
- 3D coarsening tests are explicitly disabled with a TODO comment in
test_linear_coarsen.hpp
:
using FieldCoarsenOperators = testing::Types<FieldCoarsenTestData<1>, FieldCoarsenTestData<2> /* , FieldCoarsenTestData<3>*/>; // TODO 3D
- The 3D coarsening implementation is marked as unsupported:
else if constexpr (dim == 3) // TODO 3D
{
throw std::runtime_error("Unsupported dimension");
}
- While split patterns for 3D exist (
split_3d.hpp
), there are no corresponding tests verifying these patterns.
Action items:
- Implement the missing 3D coarsening tests by uncommenting and completing the 3D test cases
- Add test coverage for 3D split patterns
- Remove the "Unsupported dimension" exception and implement the 3D coarsening verification logic
🔗 Analysis chain
Consider expanding 3D test coverage.
Based on the PR description mentioning "some coarsening tests missing" and "only some 3d split patterns", consider adding additional test cases for:
- Grid coarsening scenarios in 3D
- Additional split patterns specific to 3D
- Edge cases specific to 3D geometry
Let me gather more specific information about the test coverage.
Let me check specifically for coarsening tests in 3D and split patterns.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for existing 3D test coverage patterns
rg -l "3[dD].*test" --type cpp
Length of output: 418
Script:
#!/bin/bash
# Look for 3D test patterns and their context
rg "3[dD].*test" --type cpp -B 2 -A 5
# Look for coarsening tests
rg "coarsen.*test|test.*coarsen" --type cpp -B 2 -A 5
# Look for split pattern tests
rg "split.*test|test.*split" --type cpp -B 2 -A 5
Length of output: 8726
Script:
#!/bin/bash
# Look for 3D coarsening tests
rg -l "3[dD].*coarsen|coarsen.*3[dD]" --type cpp tests/amr/
# Check test_linear_coarsen.hpp content
fd -e hpp "test_linear_coarsen.hpp" -x cat {}
# Check test_weighter_coarsen.hpp content
fd -e hpp "test_weighter_coarsen.hpp" -x cat {}
# Look for split pattern tests in 3D context
rg "3[dD].*split|split.*3[dD]" -B 2 -A 5 --type cpp
Length of output: 17045
🧰 Tools
🪛 cppcheck
[performance] 24-24: Function parameter 'path' should be passed by const reference.
(passedByValue)
def log(N=10, use_short=False): | ||
# https://git-scm.com/docs/pretty-formats | ||
short = '--pretty=format:"%h%x09%an%x09%ad%x09%s"' if use_short else "" | ||
return decode_bytes(run(f"git log -{N} {short}").stdout) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add input validation and error handling.
The function needs improvements in two areas:
- Input validation for
N
to prevent command injection - Error handling for subprocess failures
def log(N=10, use_short=False):
+ if not isinstance(N, int) or N < 1:
+ raise ValueError("N must be a positive integer")
# https://git-scm.com/docs/pretty-formats
short = '--pretty=format:"%h%x09%an%x09%ad%x09%s"' if use_short else ""
- return decode_bytes(run(f"git log -{N} {short}").stdout)
+ try:
+ return decode_bytes(run(f"git log -{N} {short}", check=True).stdout)
+ except subprocess.CalledProcessError:
+ raise RuntimeError("Failed to retrieve git log")
Committable suggestion skipped: line range outside the PR's diff.
@ddt | ||
class AdvanceTest(AdvanceTestBase): | ||
@data( | ||
*per_interp({}), | ||
*per_interp({"L0": [Box3D(10, 19)]}), | ||
*per_interp({"L0": [Box3D(5, 9), Box3D(10, 14)]}), | ||
) | ||
@unpack | ||
def test_overlapped_particledatas_have_identical_particles( | ||
self, interp_order, refinement_boxes | ||
): | ||
self._test_overlapped_particledatas_have_identical_particles( | ||
ndim, | ||
interp_order, | ||
refinement_boxes, | ||
ppc=ppc, | ||
cells=40, | ||
largest_patch_size=20, | ||
) | ||
|
||
@data(*interp_orders) | ||
def test_L0_particle_number_conservation(self, interp): | ||
self._test_L0_particle_number_conservation(ndim, interp, ppc=ppc, cells=30) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add missing 3D coarsening test cases
While the current tests cover particle identity and conservation, coarsening tests are still missing as mentioned in the PR description. Consider adding:
- Particle coarsening between different refinement levels
- Edge cases with multiple refinement boxes
- Conservation checks during coarsening operations
Here's a suggested structure for the coarsening test:
@data(*interp_orders)
def test_particle_coarsening_3d(self, interp):
"""Test particle coarsening operations in 3D scenarios."""
refinement_boxes = {"L0": [Box3D(5, 15)], "L1": [Box3D(8, 12)]}
self._test_particle_coarsening(
ndim,
interp,
refinement_boxes,
ppc=ppc,
cells=30
)
Would you like me to help implement the complete test cases?
def run_test(test, verbose=False, capture_output=False): | ||
run(test_cmd(cmd, verbose=verbose), capture_output=capture_output) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix undefined variable in run_test function.
The function uses an undefined variable cmd
instead of the test
parameter.
def run_test(test, verbose=False, capture_output=False):
- run(test_cmd(cmd, verbose=verbose), capture_output=capture_output)
+ run(test_cmd(test, verbose=verbose), capture_output=capture_output)
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def run_test(test, verbose=False, capture_output=False): | |
run(test_cmd(cmd, verbose=verbose), capture_output=capture_output) | |
def run_test(test, verbose=False, capture_output=False): | |
run(test_cmd(test, verbose=verbose), capture_output=capture_output) |
🧰 Tools
🪛 Ruff
48-48: Undefined name cmd
(F821)
def config( | ||
path, samrai_dir=None, cxx_flags=None, use_ninja=False, use_ccache=False, extra="" | ||
): | ||
cmd = make_config_str(path, samrai_dir, cxx_flags, use_ninja, extra) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix missing use_ccache parameter in make_config_str call.
The use_ccache parameter is not being passed to make_config_str, which means ccache will never be enabled.
- cmd = make_config_str(path, samrai_dir, cxx_flags, use_ninja, extra)
+ cmd = make_config_str(path, samrai_dir, cxx_flags, use_ninja, use_ccache, extra)
Committable suggestion skipped: line range outside the PR's diff.
pdat._x = pdat.x[:-1] | ||
if primals[1]: | ||
pdat._y = pdat.y[:-1] | ||
pdat.dataset = pdat.dataset[:, :, int(pdat.ghost_box.shape[2] / 2)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Avoid hardcoded slice selection.
The method always takes the middle slice of the z-dimension, which might not be the desired behavior for all use cases.
- pdat.dataset = pdat.dataset[:, :, int(pdat.ghost_box.shape[2] / 2)]
+ slice_idx = kwargs.get('slice_idx', int(pdat.ghost_box.shape[2] / 2))
+ pdat.dataset = pdat.dataset[:, :, slice_idx]
Committable suggestion skipped: line range outside the PR's diff.
pdat = patch.patch_datas[qty] | ||
primals = pdat.primal_directions() | ||
if primals[0]: | ||
pdat._x = pdat.x[:-1] | ||
if primals[1]: | ||
pdat._y = pdat.y[:-1] | ||
pdat.dataset = pdat.dataset[:, :, int(pdat.ghost_box.shape[2] / 2)] | ||
patch.box.lower = patch.box.lower[:-1] | ||
patch.box.upper = patch.box.upper[:-1] | ||
patch.box.ndim = 2 | ||
|
||
pdat.ghost_box.lower = pdat.ghost_box.lower[:-1] | ||
pdat.ghost_box.upper = pdat.ghost_box.upper[:-1] | ||
pdat.ghost_box.ndim = 2 | ||
pdat.size = np.copy(pdat.ghost_box.shape) | ||
pdat.layout.dl = pdat.layout.dl[:-1] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider creating a copy instead of modifying data in-place.
The current implementation modifies the patch data structures in-place, which could lead to unexpected behavior if the data is needed later in its original form.
+ # Create a copy of the patch data
+ pdat_copy = copy.deepcopy(pdat)
+
+ # Modify the copy instead of the original
primals = pdat.primal_directions()
if primals[0]:
- pdat._x = pdat.x[:-1]
+ pdat_copy._x = pdat.x[:-1]
if primals[1]:
- pdat._y = pdat.y[:-1]
+ pdat_copy._y = pdat.y[:-1]
- pdat.dataset = pdat.dataset[:, :, int(pdat.ghost_box.shape[2] / 2)]
+ slice_idx = kwargs.get('slice_idx', int(pdat.ghost_box.shape[2] / 2))
+ pdat_copy.dataset = pdat.dataset[:, :, slice_idx]
Committable suggestion skipped: line range outside the PR's diff.
# phare_mpi_python3_exec | ||
# if these function calls are to files executing python unit tests as they will interfere | ||
|
||
if (test AND ${PHARE_EXEC_LEVEL_MIN} GREATER 0) # 0 = no tests |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Verify that the variable test
is correctly defined
The variable test
is used in the condition but may not be defined, which could cause unexpected behavior during the configuration process. Ensure that test
is properly defined as a boolean option or variable before this point.
endfunction(add_phare_test_) | ||
|
||
function(add_no_mpi_phare_test binary directory) | ||
if(NOT testMPI OR (testMPI AND forceSerialTests)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure forceSerialTests
is defined before use
The variable forceSerialTests
is used in the condition but may not be defined, which could lead to unexpected behavior. Make sure that forceSerialTests
is defined and properly set before this function is called.
TARGET ${binary} | ||
POST_BUILD | ||
WORKING_DIRECTORY ${directory} | ||
COMMAND ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> -R \"^${binary}$$\" --output-on-failures |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct the CTest option: use --output-on-failure
The option --output-on-failures
is incorrect. The correct option is --output-on-failure
(without the trailing 's'). This ensures that output is displayed when a test fails.
Apply this diff to fix the typo:
- COMMAND ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> -R \"^${binary}$$\" --output-on-failures
+ COMMAND ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> -R \"^${binary}$$\" --output-on-failure
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
COMMAND ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> -R \"^${binary}$$\" --output-on-failures | |
COMMAND ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> -R \"^${binary}$$\" --output-on-failure |
mostly there, some coarsening tests missing
only some 3d split patterns, the rest can come afterwards
Summary by CodeRabbit
Release Notes
New Features
plot3d
method for 3D data visualization in thePatchHierarchy
class.Box
struct with anas_points()
method to retrieve all points within the box.Bug Fixes
Documentation
Tests
Chores