Skip to content
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

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft

Conversation

PhilipDeegan
Copy link
Member

@PhilipDeegan PhilipDeegan commented Sep 27, 2021

mostly there, some coarsening tests missing
only some 3d split patterns, the rest can come afterwards

Summary by CodeRabbit

  • New Features

    • Introduced 3D simulation capabilities with new methods for plotting, interpolation, and simulation setup.
    • Added dimensionality support to enhance various functions for handling 3D domains.
  • Bug Fixes

    • Updated tests for field and particle initialization to ensure accurate results in 3D configurations.
  • Enhancements

    • Improved efficiency in handling ghost boxes, periodicity shifts, and domain borders.
    • Enhanced functionality for 3D particle interpolation and mesh coordinate calculations.
    • Refactored test and initialization scripts for improved clarity and maintainability.
  • Tests

    • Added comprehensive test cases for 3D particle data advancement, field advancements, and diagnostic simulations.
  • Chores

    • Updated CMake configuration to include options for high-resource tests and 3D diagnostic setups.

@PhilipDeegan PhilipDeegan added the WIP work in progress label Sep 27, 2021
@PHAREHUB PHAREHUB deleted a comment from lgtm-com bot Oct 2, 2021
@PHAREHUB PHAREHUB deleted a comment from lgtm-com bot Oct 2, 2021
@PHAREHUB PHAREHUB deleted a comment from lgtm-com bot Oct 5, 2021
@PHAREHUB PHAREHUB deleted a comment from lgtm-com bot Oct 5, 2021
@PHAREHUB PHAREHUB deleted a comment from lgtm-com bot Oct 5, 2021
@PhilipDeegan PhilipDeegan changed the title 3d C++ 3d C++ / python (mostly) May 17, 2022
@PHAREHUB PHAREHUB deleted a comment from lgtm-com bot Aug 1, 2022
@PhilipDeegan PhilipDeegan changed the title 3d C++ / python (mostly) 3d C++ / python Sep 3, 2022
@nicolasaunai nicolasaunai marked this pull request as draft February 8, 2023 18:22
@PHAREHUB PHAREHUB deleted a comment from coderabbitai bot Jun 24, 2024
@PHAREHUB PHAREHUB deleted a comment from coderabbitai bot Jun 24, 2024
@PHAREHUB PHAREHUB deleted a comment from coderabbitai bot Jun 24, 2024
@PHAREHUB PHAREHUB deleted a comment from coderabbitai bot Jun 24, 2024
@PHAREHUB PHAREHUB deleted a comment from coderabbitai bot Jun 24, 2024
@PHAREHUB PHAREHUB deleted a comment from coderabbitai bot Jun 24, 2024
@PHAREHUB PHAREHUB deleted a comment from coderabbitai bot Jun 24, 2024
@PHAREHUB PHAREHUB deleted a comment from coderabbitai bot Jun 24, 2024
@PHAREHUB PHAREHUB deleted a comment from coderabbitai bot Jun 24, 2024
Copy link

@coderabbitai coderabbitai bot left a 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 function delete_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 in WhitePattern.

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 the yeeCoordsFor 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 from object.

Both YeeCentering and GridLayout classes inherit from object, 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 file

Also 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 the shifts 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, as l 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 and lvl 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 of key 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 from object.

In Python 3, all classes implicitly inherit from object, so this is redundant.

- class PatchHierarchy(object):
+ class PatchHierarchy:

Line range hint 621-621: Use raise ... 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 of key 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 of key 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 of key 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 of key 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 of key 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 of key 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 of key 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

Commits

Files that changed from the base of the PR and between a07dcc8 and 914fce6.

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 with raise ... from err or raise ... from None to distinguish them from errors in exception handling (B904)


46-46: Within an except clause, raise exceptions with raise ... from err or raise ... 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 of super(__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 of super(__class__, self) (UP008)

Remove __super__ parameters


76-76: Do not assign a lambda expression, use a def (E731)

Rewrite _ as a def


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 of super(__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 function

pyphare/pyphare/core/gridlayout.py

131-131: Class YeeCentering inherits from object (UP004)

Remove object inheritance


152-155: Use ternary operator size = nbrCells[dim] + nbrGhosts * 2 if withGhosts else nbrCells[dim] instead of if-else-block (SIM108)

Replace if-else-block with size = nbrCells[dim] + nbrGhosts * 2 if withGhosts else nbrCells[dim]


168-168: Class GridLayout inherits from object (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 function

tests/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), raise AssertionError() (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 function

tests/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 a def (E731)

Rewrite _ as a def


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 a def (E731)

Rewrite _ as a def


98-98: Do not assign a lambda expression, use a def (E731)

Rewrite _ as a def


103-103: Do not assign a lambda expression, use a def (E731)

Rewrite _ as a def


108-108: Do not assign a lambda expression, use a def (E731)

Rewrite _ as a def


113-113: Do not assign a lambda expression, use a def (E731)

Rewrite _ as a def


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 of key 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 of key 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 a def (E731)

Rewrite _ as a def


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 a def (E731)

Rewrite _ as a def


100-100: Do not assign a lambda expression, use a def (E731)

Rewrite _ as a def


105-105: Do not assign a lambda expression, use a def (E731)

Rewrite _ as a def


110-110: Do not assign a lambda expression, use a def (E731)

Rewrite _ as a def


115-115: Do not assign a lambda expression, use a def (E731)

Rewrite _ as a def


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 of key 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 from object (UP004)

Remove object inheritance


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 (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 of key 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 of key in dict.keys() (SIM118)

Remove .keys()


1468-1468: Use key in dict instead of key 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 of key in dict.keys() (SIM118)

Remove .keys()


1538-1538: Use key in dict instead of key 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 of key 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 of key 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 = 3

Likely 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 using TYPED_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.cpp

Length 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/diagnostic

Length of output: 207



Script:

#!/bin/bash
# List all test functions within test-diagnostics_3d.cpp
rg "TEST_F" tests/diagnostic/test-diagnostics_3d.cpp

Length 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.cpp

Length of output: 759

tests/simulator/initialize/test_fields_init_2d.py (1)

26-26: Explicit specification of ppc 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, using std::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 of power[dimension - 1] outside the loop to avoid repeated calculations. Additionally, ensure that the variable weight 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 Specialization

The use of PatternDispatcher with PinkPattern<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 Patterns

The configuration of PatternDispatcher to use multiple patterns (BlackPattern and PinkPattern) is a robust design choice that enhances the flexibility of the Splitter template specialization. This approach allows for easy extension or modification of behavior based on different patterns.


71-71: Consistency in Dispatcher Usage

The 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 Dispatchers

The use of PatternDispatcher with both BlackPattern and PinkPattern for the Splitter template specialization is an excellent example of how complex behaviors can be modularly constructed using template metaprogramming.


109-109: Dual Pattern Dispatcher for Enhanced Flexibility

The implementation of SplitPattern_1_2_4_Dispatcher using two instances of PinkPattern 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 Splitter

The configuration of SplitPattern_1_3_3_Dispatcher to use both BlackPattern and PinkPattern 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 Patterns

The use of dual PinkPattern in SplitPattern_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 Splitting

The implementation of SplitPattern_1_3_5_Dispatcher using three instances of PinkPattern 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 and coarseField 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: Optimize LimePattern 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 various Splitter 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_ in PinkPattern seems inconsistent with its siblings like PurplePattern. 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_ in PinkPattern appears consistent with other patterns like PurplePattern. Both patterns initialize the deltas_ array based on the delta parameter. However, if there are specific differences in the way deltas_ 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_ in PinkPattern and PurplePattern.
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_*.hpp

Length 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 using None 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: Use is None for None checks.

This is the idiomatic way to check for None in Python.

- if cond == None:
+ if cond is None:

[REFACTOR_Suggestion]

Comment on lines +776 to +783
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);
}
Copy link

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.

Suggested change
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(
Copy link

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

Comment on lines +8 to +14
out = "phare_outputs/diags_3d/"
simInput = {"diag_options": {"format": "phareh5", "options": {"dir": out, "mode" : "overwrite"}}}

ph.Simulation(**basicSimulatorArgs(dim = 3, interp = 1, **simInput))
model = makeBasicModel()
ElectronModel(closure="isothermal",Te = 0.12)
dump_all_diags(model.populations)
Copy link

Choose a reason for hiding this comment

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

Ensure proper error handling 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 from these calls.

+ 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:
+     print(f"An error occurred: {e}")
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.

Suggested change
out = "phare_outputs/diags_3d/"
simInput = {"diag_options": {"format": "phareh5", "options": {"dir": out, "mode" : "overwrite"}}}
ph.Simulation(**basicSimulatorArgs(dim = 3, interp = 1, **simInput))
model = makeBasicModel()
ElectronModel(closure="isothermal",Te = 0.12)
dump_all_diags(model.populations)
out = "phare_outputs/diags_3d/"
simInput = {"diag_options": {"format": "phareh5", "options": {"dir": out, "mode" : "overwrite"}}}
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:
print(f"An error occurred: {e}")

Comment on lines +9 to +11
#if !defined(PHARE_SIMULATORS)
#define PHARE_SIMULATORS 3
#endif
Copy link

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):
Copy link

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.

Suggested change
def S(y, y0, l):
def S(y, y0, length):
Tools
Ruff

62-62: Ambiguous variable name: l (E741)

Comment on lines +43 to +63
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};
}
}
};
Copy link

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 of float 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

Comment on lines +24 to +97

@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__":
Copy link

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.

  1. 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.

  2. 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.

Suggested change
@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

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=[]):
Copy link

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.

Suggested change
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

Comment on lines +24 to +107

@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()
Copy link

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.

  1. 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.

  2. 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():
Copy link

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.

Suggested change
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

@PHAREHUB PHAREHUB deleted a comment from coderabbitai bot Jun 24, 2024
@PHAREHUB PHAREHUB deleted a comment from coderabbitai bot Jun 24, 2024
@PHAREHUB PHAREHUB deleted a comment from coderabbitai bot Jun 24, 2024
@PHAREHUB PHAREHUB deleted a comment from coderabbitai bot Jun 24, 2024
@PHAREHUB PHAREHUB deleted a comment from coderabbitai bot Jun 24, 2024
@PHAREHUB PHAREHUB deleted a comment from coderabbitai bot Jun 24, 2024
@PHAREHUB PHAREHUB deleted a comment from coderabbitai bot Jun 24, 2024
@PHAREHUB PHAREHUB deleted a comment from coderabbitai bot Jun 24, 2024
@PHAREHUB PHAREHUB deleted a comment from coderabbitai bot Jun 24, 2024
@PHAREHUB PHAREHUB deleted a comment from coderabbitai bot Jun 24, 2024
@PHAREHUB PHAREHUB deleted a comment from coderabbitai bot Jun 24, 2024
Copy link

@coderabbitai coderabbitai bot left a 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 function delete_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), raise AssertionError() (B011)

Replace assert False

pyphare/pyphare/pharesee/geometry.py (3)

Line range hint 86-187: Consider renaming the variable for clarity in periodicity_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 in level_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

Commits

Files that changed from the base of the PR and between 914fce6 and 18577d8.

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 with raise ... from err or raise ... from None to distinguish them from errors in exception handling (B904)


46-46: Within an except clause, raise exceptions with raise ... from err or raise ... 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 of super(__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 of super(__class__, self) (UP008)

Remove __super__ parameters


76-76: Do not assign a lambda expression, use a def (E731)

Rewrite _ as a def


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 of super(__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 function

pyphare/pyphare/core/gridlayout.py

131-131: Class YeeCentering inherits from object (UP004)

Remove object inheritance


152-155: Use ternary operator size = nbrCells[dim] + nbrGhosts * 2 if withGhosts else nbrCells[dim] instead of if-else-block (SIM108)

Replace if-else-block with size = nbrCells[dim] + nbrGhosts * 2 if withGhosts else nbrCells[dim]


168-168: Class GridLayout inherits from object (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 function

tests/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), raise AssertionError() (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 function

tests/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 a def (E731)

Rewrite _ as a def


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 a def (E731)

Rewrite _ as a def


98-98: Do not assign a lambda expression, use a def (E731)

Rewrite _ as a def


103-103: Do not assign a lambda expression, use a def (E731)

Rewrite _ as a def


108-108: Do not assign a lambda expression, use a def (E731)

Rewrite _ as a def


113-113: Do not assign a lambda expression, use a def (E731)

Rewrite _ as a def


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 of key 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 of key 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 a def (E731)

Rewrite _ as a def


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 a def (E731)

Rewrite _ as a def


100-100: Do not assign a lambda expression, use a def (E731)

Rewrite _ as a def


105-105: Do not assign a lambda expression, use a def (E731)

Rewrite _ as a def


110-110: Do not assign a lambda expression, use a def (E731)

Rewrite _ as a def


115-115: Do not assign a lambda expression, use a def (E731)

Rewrite _ as a def


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 of key 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 from object (UP004)

Remove object inheritance


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 (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 of key 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 of key in dict.keys() (SIM118)

Remove .keys()


1468-1468: Use key in dict instead of key 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 of key in dict.keys() (SIM118)

Remove .keys()


1538-1538: Use key in dict instead of key 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 of key 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 of key 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 Decorators

The Initialization3DTest class correctly inherits from InitializationTest. The use of the @ddt decorator is appropriate for data-driven tests.


77-94: Consider Removing or Documenting Commented-out Code

The 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 Block

The 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 Function

The config function sets up a simulation with detailed configuration parameters. The use of dictionary for diag_options is clear and effective. The commented-out strict option should either be removed or uncommented if needed.


62-62: Ambiguous Variable Naming

The variable name l is ambiguous and could be confused with the number 1. Consider renaming it to length for clarity.

Tools
Ruff

62-62: Ambiguous variable name: l (E741)


174-178: Main Function and Plotting Integration

The 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 Method

The tearDown method correctly resets the simulator instance if it's not None. This is essential for cleaning up after each test case.


78-117: Clarify Calculations in Test Methods

The 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 Method

The 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 Configuration

The 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__ Method

The method handles list subtraction by calling remove_all. Ensure that the input validation (checking all items are instances of Box) is robust.


185-198: remove_all Function

This 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 Class

The 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 the background_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 function

src/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 in domain_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 in compute_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)

Comment on lines +1026 to +1056
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) # ¯\_(ツ)_/¯

Copy link

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, and pdat.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

Comment on lines +88 to +90
typename std::enable_if<D == 3, void>::type
coarsen(Point_t const fineStartIndex, FieldT const& fineField, FieldT& coarseField,
Point_t const coarseIndex);
Copy link

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.

Suggested change
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.");
}

Comment on lines +571 to +586
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())
Copy link

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

Comment on lines +35 to +37
*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)}})),
Copy link

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)
Copy link

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.

Suggested change
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)

Comment on lines 45 to 46
raise RuntimeError(decode_bytes(e.stderr))
raise RuntimeError(what)
Copy link

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.

Suggested change
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 with raise ... from err or raise ... from None to distinguish them from errors in exception handling (B904)


46-46: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling (B904)

@PhilipDeegan PhilipDeegan force-pushed the 3d_base branch 2 times, most recently from 9769e13 to 753eb43 Compare August 1, 2024 12:37

return self.plot2d(**kwargs) # ¯\_(ツ)_/¯

def plot(self, **kwargs):

Check notice

Code scanning / CodeQL

Explicit returns mixed with implicit (fall through) returns Note

Mixing implicit and explicit returns may indicate an error as implicit returns always return None.
self._y = None
self._z = None

self.layout = layout

Check warning

Code scanning / CodeQL

Overwriting attribute in super-class or sub-class Warning

Assignment overwrites attribute layout, which was previously defined in superclass
PatchData
.
"""
plot phase space of a particle hierarchy
"""
import copy

Check notice

Code scanning / CodeQL

Module is imported with 'import' and 'import from' Note

Module 'copy' is imported with both 'import' and 'import from'.
def __copy__(self):
return self.copy()

def __call__(self, qty, **kwargs):

Check notice

Code scanning / CodeQL

Explicit returns mixed with implicit (fall through) returns Note

Mixing implicit and explicit returns may indicate an error as implicit returns always return None.
h5_time_grp_key = "t"


def hierarchy_fromh5(h5_filename, time, hier, silent=True):

Check notice

Code scanning / CodeQL

Explicit returns mixed with implicit (fall through) returns Note

Mixing implicit and explicit returns may indicate an error as implicit returns always return None.
self.exclusions = []

def extract(self, coord, data):
mask = coord == coord

Check warning

Code scanning / CodeQL

Comparison of identical values Warning

Comparison of identical values; use cmath.isnan() if testing for not-a-number.

if len(kwargs) < 1 or len(kwargs) > 3:
raise ValueError("Error - must provide coordinates")
if qty == None:

Check notice

Code scanning / CodeQL

Testing equality to None Note

Testing for None should use the 'is' operator.
for ilvl in ilvls:
lvl = self.patch_levels[ilvl]
for patch in lvl.patches:
slice_coord = domain_coords(patch, qty)[slice_dim]

Check failure

Code scanning / CodeQL

Potentially uninitialized local variable Error

Local variable 'slice_dim' may be used before it is initialized.
lvl = self.patch_levels[ilvl]
for patch in lvl.patches:
slice_coord = domain_coords(patch, qty)[slice_dim]
cst_coord = domain_coords(patch, qty)[cst_dim]

Check failure

Code scanning / CodeQL

Potentially uninitialized local variable Error

Local variable 'cst_dim' may be used before it is initialized.
Copy link

@coderabbitai coderabbitai bot left a 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 and GriddingAlgorithm 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 for test-diagnostics_3d is missing.

The search results indicate that while test-diagnostics_3d is referenced in tests/diagnostic/CMakeLists.txt, there is no actual implementation found for this test. Please ensure that the implementation for test-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 number 1. Renaming it to length 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, and vthxyz 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 the plot_file_for_qty and plot 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 the main 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 variable l.

The variable name l in the select 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 of as_points.

The as_points function correctly generates a vector of points based on the dimensionality of the Box. 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
+        // = 488
pyphare/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 a RuntimeError 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 a ValueError 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 body

Rename 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 body

Rename 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 body

Rename unused lvl to _lvl

(B007)

Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 18577d8 and 753eb43.

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 used

Remove 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), raise AssertionError()

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 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)

tests/simulator/test_advance.py

89-89: 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)


960-960: Loop control variable lvl not used within loop body

Rename unused lvl to _lvl

(B007)


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)

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 = 3

Likely invalid or redundant comment.

tests/simulator/initialize/CMakeLists.txt (1)

21-24: LGTM! Ensure the flag highResourceTests 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 in res/cmake/options.cmake and used in conditional statements in tests/simulator/initialize/CMakeLists.txt and tests/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 flag highResourceTests 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 of OFF, 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."
fi

Length 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 the delta and weight values are consistent with the intended simulation parameters.


117-129: Verify the accuracy of interp_2 data.

Ensure that the delta and weight values for interp_2 are correct and align with the expected simulation behavior.


130-141: Check the correctness of interp_3 values.

Review the delta and weight values for interp_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 using std::uint16_t.


18-18: Using std::uint16_t for QtyCentering improves type safety and memory usage.

The change to use std::uint16_t as the underlying type for the QtyCentering 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 the QtyCentering enumeration is appropriate for optimizing memory usage and ensuring type safety. Based on the extensive usage of QtyCentering 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 for QtyCentering improves type safety and memory usage.

The change to use std::uint16_t as the underlying type for the QtyCentering enumeration is appropriate for optimizing memory usage and ensuring type safety. Based on the extensive usage of QtyCentering 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 of Simulator3dTest is appropriate.

The new Simulator3dTest structure extends ::testing::Test and follows the existing pattern for 1D and 2D tests.


115-117: Definition of Simulator3d and usage in TYPED_TEST_SUITE is correct.

The Simulator3d type alias and its usage in TYPED_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 of Initialization3DTest is appropriate.

The new Initialization3DTest class extends InitializationTest 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! The per_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! The SplitPattern struct is well-defined.

The struct initializes its members correctly and follows good practices.


Line range hint 74-87: LGTM! The ASplitter 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 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.

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 the tearDown 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 the test_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 to PinkPattern is consistent and maintains the original functionality.


34-34: LGTM!

The type alias SplitPattern_1_1_2_Dispatcher correctly references PinkPattern.


53-53: LGTM!

The type alias SplitPattern_1_1_3_Dispatcher correctly references BlackPattern and PinkPattern.


71-71: LGTM!

The type alias SplitPattern_1_2_2_Dispatcher correctly references PinkPattern.


90-90: LGTM!

The type alias SplitPattern_1_2_3_Dispatcher correctly references BlackPattern and PinkPattern.


109-109: LGTM!

The type alias SplitPattern_1_2_4_Dispatcher correctly references PinkPattern.


127-127: LGTM!

The type alias SplitPattern_1_3_2_Dispatcher correctly references PinkPattern.


146-146: LGTM!

The type alias SplitPattern_1_3_3_Dispatcher correctly references BlackPattern and PinkPattern.


165-165: LGTM!

The type alias SplitPattern_1_3_4_Dispatcher correctly references PinkPattern.


184-185: LGTM!

The type alias SplitPattern_1_3_5_Dispatcher correctly references BlackPattern and PinkPattern.

pyphare/pyphare/core/box.py (5)

65-67: LGTM!

The __sub__ method correctly handles lists/tuples of Box instances and utilizes the remove_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 the lower and upper bounds of a Box.

Tools
Ruff

207-207: Ambiguous variable name: l

(E741)


209-223: LGTM!

The DataSelector class enhances usability by allowing indexed access using Box instances or standard slicing.


185-198: Add unit tests for remove_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 appropriate coarsen 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 the

src/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 for delta and weight.

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 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 (5)

Line range hint 254-354:
LGTM! Ensure ppc parameter is correctly utilized.

The function _test_B_is_as_provided_by_user has been updated to include the ppc parameter. Ensure that it is correctly utilized in the function.


Line range hint 355-417:
LGTM! Ensure ppc parameter is correctly utilized.

The function _test_bulkvel_is_as_provided_by_user has been updated to include the ppc 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! Ensure ndim parameter is correctly utilized.

The function _test_density_is_as_provided_by_user has been updated to include the ndim 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! Ensure ndim parameter is correctly utilized.

The function _test_density_decreases_as_1overSqrtN has been updated to include the ndim parameter. Ensure that it is correctly utilized in the function.


566-586: LGTM! Ensure ndim and ppc parameters are correctly utilized.

The function _test_nbr_particles_per_cell_is_as_provided has been updated to include the ndim and ppc parameters. Ensure that they are correctly utilized in the function.

Tools
Ruff

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)

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 superclass PatchData.

- self.layout = layout

Likely invalid or redundant comment.

Comment on lines +89 to +91
def S(x, x0, l):
return 0.5 * (1 + np.tanh((x - x0) / l))

Copy link

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.

Suggested change
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.

Suggested change
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)

Comment on lines +265 to +273
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
Copy link

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.

Suggested change
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])),
)

Comment on lines +3 to +14
import pyphare.pharein as ph
from pyphare.pharein import ElectronModel
from tests.simulator import basicSimulatorArgs, makeBasicModel
from tests.diagnostic import dump_all_diags

out = "phare_outputs/diags_3d/"
simInput = {"diag_options": {"format": "phareh5", "options": {"dir": out, "mode" : "overwrite"}}}

ph.Simulation(**basicSimulatorArgs(dim = 3, interp = 1, **simInput))
model = makeBasicModel()
ElectronModel(closure="isothermal",Te = 0.12)
dump_all_diags(model.populations)
Copy link

Choose a reason for hiding this comment

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

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}")
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.

Suggested change
import pyphare.pharein as ph
from pyphare.pharein import ElectronModel
from tests.simulator import basicSimulatorArgs, makeBasicModel
from tests.diagnostic import dump_all_diags
out = "phare_outputs/diags_3d/"
simInput = {"diag_options": {"format": "phareh5", "options": {"dir": out, "mode" : "overwrite"}}}
ph.Simulation(**basicSimulatorArgs(dim = 3, interp = 1, **simInput))
model = makeBasicModel()
ElectronModel(closure="isothermal",Te = 0.12)
dump_all_diags(model.populations)
import pyphare.pharein as ph
from pyphare.pharein import ElectronModel
from tests.simulator import basicSimulatorArgs, makeBasicModel
from tests.diagnostic import dump_all_diags
import logging
logging.basicConfig(level=logging.INFO)
out = "phare_outputs/diags_3d/"
simInput = {"diag_options": {"format": "phareh5", "options": {"dir": out, "mode" : "overwrite"}}}
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}")


def checkout(branch, create=False, recreate=False):
if recreate:
delete_branch(branch)
Copy link

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)

Comment on lines +9 to +27
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);
}
Copy link

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.

Suggested change
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);
}

Comment on lines +127 to +128
auto zstart() const { return mask_.min(); }
auto zend() const { return shape_[2] - 1 - mask_.max(); }
Copy link

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.

Suggested change
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(); }

Comment on lines +77 to +94
# @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")
Copy link

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.

Suggested change
# @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")

Comment on lines +661 to +669
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,
Copy link

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.

Suggested change
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 used

Remove assignment to unused variable out

(F841)

Comment on lines +79 to +103
# @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)
Copy link

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.

Comment on lines +73 to +75
# -DhighResourceTests=ON
option(highResourceTests "Enable heavy tests for CI (3d/etc" OFF)

Copy link

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.

Suggested change
# -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()

Copy link

@coderabbitai coderabbitai bot left a 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 the per_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 placeholder version 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 of add_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 using get_cmake_property for debugging.

The function phare_print_all_vars uses get_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 number 1. 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_NUMBER
pyphare/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 for x, y, and z.

The property methods for x, y, and z 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 in merge_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 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)

Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 753eb43 and a3ad211.

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 used

Remove 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), raise AssertionError()

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 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)

tests/simulator/test_advance.py

89-89: 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)


960-960: Loop control variable lvl not used within loop body

Rename unused lvl to _lvl

(B007)


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)

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 including split_3d.hpp.

Ensure that the inclusion of split_3d.hpp is necessary for this file and consistent with the project's architecture. If split_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_, and gtest_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 the Splitters type alias broadens the test coverage, which is a positive enhancement for ensuring the robustness of the Splitter 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 and GriddingAlgorithm sections are empty and should be removed if they are not required, to avoid confusion.

tools/python3/git.py (2)

22-23: Remove unused variable e.

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 used

Remove assignment to unused variable e

(F841)


29-29: 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)

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 in test_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 in tests/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.py

Length 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 for PHARE_SIMULATORS > 1 but not for PHARE_SIMULATORS > 2. Ensure this aligns with the intended simulator configurations.

  • src/core/utilities/meta/meta_utilities.hpp: Conditional logic based on PHARE_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 to Initialization2DTest 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 the QtyCentering 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 of TYPED_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 of ddt 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, and splitter.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 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.

src/core/utilities/meta/meta_utilities.hpp (2)

9-11: Duplicate Comment: Ensure the default value for PHARE_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 Good

The 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 Good

The plotting logic is clear, and the main function correctly initiates the simulation and plotting.


37-53: Verify Simulation Configuration

The 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 in test_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 to PinkPattern.

The renaming from PinkDispatcher to PinkPattern is consistent and improves clarity. Ensure that all instances in the codebase have been updated.


Line range hint 71-86:
Verify SplitPattern_1_2_2_Dispatcher update.

The alias SplitPattern_1_2_2_Dispatcher now uses PinkPattern. Ensure all related instances are updated.

Verification successful

All instances of SplitPattern_1_2_2_Dispatcher are updated. The alias is only used within src/amr/data/particles/refine/split_1d.hpp and no other files reference it. The update to use PinkPattern 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 in SplitPattern_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 using PinkPattern<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:
Verify SplitPattern_1_2_4_Dispatcher update.

Ensure that all instances of SplitPattern_1_2_4_Dispatcher using PinkPattern are updated.

Verification successful

Verification Complete: SplitPattern_1_2_4_Dispatcher Update Confirmed

The SplitPattern_1_2_4_Dispatcher is only used in src/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:
Ensure BlackPattern consistency.

The alias now uses BlackPattern instead of BlackDispatcher. Verify that BlackPattern 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 in src/amr/data/particles/refine/splitter.hpp and used appropriately in src/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 5

Length of output: 520


Line range hint 165-180:
Ensure consistency in SplitPattern_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 using PinkPattern<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.hpp

Length of output: 538


Line range hint 90-105:
Ensure consistency in SplitPattern_1_2_3_Dispatcher.

The alias now uses BlackPattern and PinkPattern. Verify consistency in definitions and usages.

Verification successful

Verification Successful: Consistency in SplitPattern_1_2_3_Dispatcher

The usage of BlackPattern and PinkPattern within SplitPattern_1_2_3_Dispatcher is consistent with their definitions and intended usage. Both patterns are correctly utilized in the context of a PatternDispatcher. 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, and SplitPattern_1_3_2_Dispatcher are confined to the file src/amr/data/particles/refine/split_1d.hpp and have been updated to use PinkPattern<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:
Verify SplitPattern_1_3_3_Dispatcher update.

Ensure that all instances of SplitPattern_1_3_3_Dispatcher using BlackPattern and PinkPattern are updated.


Line range hint 184-199:
Verify SplitPattern_1_3_5_Dispatcher update.

Ensure that all instances of SplitPattern_1_3_5_Dispatcher using BlackPattern and PinkPattern are updated.

Verification successful

Verification Complete: No Additional Updates Required for SplitPattern_1_3_5_Dispatcher

The update to SplitPattern_1_3_5_Dispatcher in src/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 with BlackPattern or PinkPattern that require updates.

  • The usage of BlackPattern and PinkPattern with dispatchers is consistent across multiple files, but no additional updates are necessary for SplitPattern_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 for remove_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: Introduce DataSelector class.

The DataSelector class enhances data manipulation using Box instances. Ensure that its functionality is well-documented and tested.

src/core/utilities/box/box.hpp (1)

151-169: Add documentation for as_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 that PHARE_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, as PHARE_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 of EXCLUDE_FROM_ALL and EXCLUDE_FROM_DEFAULT_BUILD should be consistent with project requirements.

Verification successful

Exclusion Logic Verified

The exclusion logic using EXCLUDE_FROM_ALL and EXCLUDE_FROM_DEFAULT_BUILD is consistently applied in both res/cmake/funcs.cmake and res/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.cmake

Length 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 to dim 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 of dimension. 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 for primal and dual 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 the coarsen 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 10

Length of output: 52778

src/amr/data/particles/refine/split_3d.hpp (4)

71-86: Good use of lambda functions for clarity and reuse in LimePattern.

The lambda function addSquare effectively encapsulates repeated logic, enhancing code clarity and reusability.


95-114: Good use of lambda functions for clarity and reuse in WhitePattern.

The lambda functions addSquare and addSquares effectively encapsulate repeated logic, enhancing code clarity and reusability.


123-293: Initialization of delta and weight arrays in Splitter is consistent and correct.

The use of static constexpr arrays for delta and weight ensures consistency and correctness across different Splitter configurations.


48-62: Use structured bindings for clarity in PurplePattern.

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: 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.


390-427: Consider performance optimizations in fill3D.

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 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.


788-788: Remove unused static variable gtest_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 of ppc parameter enhances flexibility.

The inclusion of the ppc parameter allows for dynamic configuration of particle counts, improving the function's flexibility.


417-420: Use of ndim enhances clarity.

Replacing dim with ndim 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 variable pi 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 body

Rename unused pi to _pi

(B007)


586-586: Yoda condition detected

Rewrite as ppc == H

(SIM300)


661-664: Remove unused variable out.

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 used

Remove assignment to unused variable out

(F841)

tests/simulator/test_advance.py (2)

370-372: LGTM! Verify the usage of the cells 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 the cells 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 be cond 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 superclass PatchData. 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 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, and pdat.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 body

Rename unused lvl to _lvl

(B007)

Comment on lines +47 to +48
def run_test(test, verbose=False, capture_output=False):
run(test_cmd(cmd, verbose=verbose), capture_output=capture_output)
Copy link

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.

Suggested change
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)

@@ -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_);
Copy link

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.

Suggested change
auto weight = static_cast<Weight_t>(pattern.weight_);

Comment on lines +395 to +446
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);
}
Copy link

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

Comment on lines +25 to +40
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};
}
}
Copy link

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.

Suggested change
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}
} {}

Comment on lines +369 to +381
def meshCoords(self, qty):
ndim = self.ndim
assert ndim > 0 and ndim < 4
x = self.yeeCoordsFor(qty, "x")
if ndim == 1:
return x
y = self.yeeCoordsFor(qty, "y")
if ndim == 2:
X,Y = np.meshgrid(x,y,indexing="ij")
return np.array([X.flatten(),Y.flatten()]).T.reshape((len(x), len(y), ndim))
z = self.yeeCoordsFor(qty, "z")
X ,Y, Z = np.meshgrid(x,y,z,indexing="ij")
return np.array([X.flatten(), Y.flatten(), Z.flatten()]).T.reshape((len(x), len(y), len(z), ndim))
Copy link

Choose a reason for hiding this comment

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

Enhance meshCoords method with more descriptive error handling.

Replace assertions with more descriptive error handling to provide clearer feedback to the user.

-        assert ndim > 0 and ndim < 4
+        if ndim <= 0 or ndim >= 4:
+            raise ValueError("meshCoords function supports only 1, 2, or 3 dimensions")

if not isinstance(linestyles, dict):
linestyles = dict(zip(usr_lvls, linestyles))

for lvl_nbr, lvl in self.levels(time).items():
Copy link

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.

Suggested change
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 body

Rename unused lvl to _lvl

(B007)

Comment on lines +97 to +107
def density_3d_periodic(sim, x, y, z):
xmax, ymax, zmax = sim.simulation_domain()
background_particles = 0.3 # avoids 0 density
xx, yy, zz = meshify(x, y, z)
r = (
np.exp(-((xx - 0.5 * xmax) ** 2))
* np.exp(-((yy - ymax / 2.0) ** 2))
* np.exp(-((zz - zmax / 2.0) ** 2))
+ background_particles
)
return r
Copy link

Choose a reason for hiding this comment

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

Ensure density_3d_periodic is tested.

The density_3d_periodic function is new and should be covered by tests to ensure its correctness and integration with the rest of the system.

Do you want me to generate the unit testing code or open a GitHub issue to track this task?

Comment on lines +318 to +345
def debug_tracer():
"""
print live stack trace during execution
"""

import sys, os

def tracefunc(frame, event, arg, indent=[0]):
filename = os.path.basename(frame.f_code.co_filename)
line_number = frame.f_lineno
if event == "call":
indent[0] += 2
print(
"-" * indent[0] + "> enter function",
frame.f_code.co_name,
f"{filename} {line_number}",
)
elif event == "return":
print(
"<" + "-" * indent[0],
"exit function",
frame.f_code.co_name,
f"{filename} {line_number}",
)
indent[0] -= 2
return tracefunc

sys.setprofile(tracefunc)
Copy link

Choose a reason for hiding this comment

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

Avoid mutable default arguments.

The tracefunc function uses a mutable default argument indent. This can lead to unexpected behavior. Use None as the default and initialize within the function.

-    def tracefunc(frame, event, arg, indent=[0]):
+    def tracefunc(frame, event, arg, indent=None):
+        if indent is None:
+            indent = [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.

Suggested change
def debug_tracer():
"""
print live stack trace during execution
"""
import sys, os
def tracefunc(frame, event, arg, indent=[0]):
filename = os.path.basename(frame.f_code.co_filename)
line_number = frame.f_lineno
if event == "call":
indent[0] += 2
print(
"-" * indent[0] + "> enter function",
frame.f_code.co_name,
f"{filename} {line_number}",
)
elif event == "return":
print(
"<" + "-" * indent[0],
"exit function",
frame.f_code.co_name,
f"{filename} {line_number}",
)
indent[0] -= 2
return tracefunc
sys.setprofile(tracefunc)
def debug_tracer():
"""
print live stack trace during execution
"""
import sys, os
def tracefunc(frame, event, arg, indent=None):
if indent is None:
indent = [0]
filename = os.path.basename(frame.f_code.co_filename)
line_number = frame.f_lineno
if event == "call":
indent[0] += 2
print(
"-" * indent[0] + "> enter function",
frame.f_code.co_name,
f"{filename} {line_number}",
)
elif event == "return":
print(
"<" + "-" * indent[0],
"exit function",
frame.f_code.co_name,
f"{filename} {line_number}",
)
indent[0] -= 2
return tracefunc
sys.setprofile(tracefunc)
Tools
Ruff

325-325: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

Comment on lines +677 to +678
slice_coord = domain_coords(patch, qty)[slice_dim]
cst_coord = domain_coords(patch, qty)[cst_dim]
Copy link

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.

Suggested change
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.

Comment on lines +380 to +414
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)
Copy link

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.

Suggested change
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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
WIP work in progress
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant