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

absolute tagging #902

Closed
wants to merge 11 commits into from
Closed

absolute tagging #902

wants to merge 11 commits into from

Conversation

nicolasaunai
Copy link
Member

@nicolasaunai nicolasaunai commented Oct 11, 2024

is on top of #893
the PR only concerns the diff in default hybrid tagging and adds absolute values to the tagging formula.
Or alternatively, only the last commit ("tagging better")
current master formula (also in the paper) leads to this refinement if increasing the threshold

image

clearly the two current layers being similar in terms of scales and magnetic jump they should be refined the same way.
This comes from the absolute value missing in the denominator that makes the positive and negative derivatives of B leading to different values of tagging formula hence difference response to the thresholding.

adding the absolute value and testing it for different tagging thresholds leads to

image

Which behaves better, see the pic above that tested the same configuration as above for different thresholds:

  • at 0.8 there is no refinement
  • at 0.6 there is L1 but no L2
  • at 0.4 there is an L2 mapping the 2 current layers
  • at 0.1, things are a bit similar to 0.4
  • at 0.05 L1 remains about the same, but L2 grows a bit, there are more patches
  • at 0.01, L1 becomes wider, there is almost no space in between the two current sheets that is not refined
  • at 0.001 L2 is larger and L1 occupies all space in between the current layers.

Summary by CodeRabbit

  • New Features

    • Enhanced simulation configurability with new parameters for load balancing and Ohm's law.
    • Introduced hyper_mode for improved validation of simulation parameters.
    • Added methods for better handling of magnetic and electric field relationships in Yee grid layouts.
  • Bug Fixes

    • Improved error handling for unregistered simulation electrons.
  • Refactor

    • Updated constructors and method signatures to accommodate new features and improve clarity.

Copy link

coderabbitai bot commented Oct 11, 2024

📝 Walkthrough

Walkthrough

The pull request introduces significant modifications across several files, primarily focusing on enhancing simulation parameters and functionalities. Key updates include the expansion of the populateDict function to incorporate new parameters for Ohm's law and load balancing, adjustments to the Simulation class to accept a new hyper_mode keyword, and the addition of methods to handle particle arrays and grid layouts. Furthermore, error handling improvements and refinements in numerical stability for field calculations are also included.

Changes

File Path Change Summary
pyphare/pyphare/pharein/__init__.py Modified populateDict to add parameters for Ohm's law and load balancing. Included error handling for unregistered electrons.
pyphare/pyphare/pharein/simulation.py Added hyper_mode keyword argument to the checker decorator and updated the Simulation class __init__ method to accept it.
src/amr/resources_manager/amr_utils.hpp Updated layoutFromPatch to include lvlNbr parameter in its return statement.
src/amr/solvers/solver_ppc.hpp Introduced static method add_to in SolverPPC for managing ParticleArray objects in a map.
src/amr/tagging/default_hybrid_tagger_strategy.hpp Modified tag method in DefaultHybridTaggerStrategy for improved numerical stability in field difference calculations.
src/core/data/grid/gridlayout.hpp Enhanced GridLayout constructor with level_number parameter and added static methods for linear interpolation. Added levelNumber() method to return levelNumber_.
src/core/data/grid/gridlayoutimplyee.hpp Added methods in GridLayoutImplYee for converting between magnetic and electric field components.
src/core/data/tensorfield/tensorfield.hpp Improved formatting of lambda expressions in getCompileTimeResourcesViewList methods.
src/core/data/vecfield/vecfield.hpp Added a commented-out function template norm for computing the norm of a vector field.
src/core/numerics/ohm/ohm.hpp Introduced HyperMode enum, updated constructor to initialize hyper_mode, and modified hyperresistive_ method to accept additional parameters. Renamed original method and added spatial_hyperresistive_.

Possibly related PRs

  • tagging thresholds from python #879: The changes in this PR involve modifications to the Simulation class and the as_paths function, which are related to the handling of simulation parameters, including the addition of new parameters for tagging thresholds. This aligns with the changes in the main PR that also involve modifications to simulation parameters, specifically the addition of new parameters in the populateDict function.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@nicolasaunai nicolasaunai changed the title Absnu absolute tagging Oct 11, 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: 6

🧹 Outside diff range and nitpick comments (12)
src/amr/solvers/solver_ppc.hpp (2)

155-170: LGTM! Consider a minor optimization.

The new add_to method is well-implemented and efficiently handles both new and existing keys in the map. The use of reserve before replace_from is a good practice for performance.

Consider using emplace instead of emplace followed by assignment for a slight performance improvement:

-        if (!map.count(key))
-            map.emplace(key, empty);
-        else
-            map.at(key) = empty;
+        auto [it, inserted] = map.try_emplace(key, empty);
+        if (!inserted)
+            it->second = empty;

This change reduces the number of potential allocations and moves.


225-227: LGTM! Consider using string concatenation for key construction.

The changes in the saveState_ method improve code consistency and readability by using the new add_to method. The key construction ensures unique keys for each patch and population combination.

Consider using string concatenation instead of stringstream for key construction, as it's simpler and potentially more efficient for this use case:

-            std::string const key = ss.str() + "_" + pop.name();
+            std::string const key = std::to_string(state.patch->getGlobalId()) + "_" + pop.name();

This change eliminates the need for the stringstream object and simplifies the key construction.

pyphare/pyphare/pharein/simulation.py (2)

650-650: Consider adding validation for the hyper_mode parameter.

The hyper_mode parameter has been added to the list of accepted keywords with a default value of "constant". However, there's no validation to ensure that only valid modes are accepted. Consider adding a check to validate the hyper_mode value to prevent potential issues with invalid modes.

You could add a function similar to check_clustering() to validate the hyper_mode:

def check_hyper_mode(**kwargs):
    valid_modes = ["constant", "other_valid_mode"]  # Add all valid modes here
    hyper_mode = kwargs.get("hyper_mode", "constant")
    if hyper_mode not in valid_modes:
        raise ValueError(f"Error: hyper_mode '{hyper_mode}' is not supported. Valid modes are {valid_modes}")
    return hyper_mode

Then call this function in the checker decorator:

kwargs["hyper_mode"] = check_hyper_mode(**kwargs)

723-723: LGTM! Consider adding documentation for the new hyper_mode parameter.

The addition of the hyper_mode parameter in the __init__ method is consistent with its inclusion in the checker function. The default value is maintained, which is good for consistency.

To improve the code's documentation, consider adding a description of the hyper_mode parameter in the class docstring. For example:

class Simulation(object):
    """
    ...

    :Keyword Arguments:
        ...
        * *hyper_mode* (``str``)--
          Mode for hyper-resistivity calculation (default="constant").
          Valid values are ["constant", ...] # Add other valid modes
    """
src/core/numerics/ohm/ohm.hpp (3)

352-353: Handle unexpected hyper_mode values explicitly

In the hyperresistive_ method, the else block returns 0.0 to satisfy the compiler's requirement for a return statement. This could mask unintended states if hyper_mode has an unexpected value.

For better robustness and maintainability, consider handling unexpected hyper_mode values explicitly by throwing an exception or using an assert to catch invalid states during development. For example:

else // should not happen but otherwise -Wreturn-type fails with Werror
-    return 0.;
+#ifdef NDEBUG
+    throw std::runtime_error("Invalid hyper_mode in hyperresistive_ method");
+#else
+    assert(false && "Invalid hyper_mode in hyperresistive_ method");
+#endif

360-362: Address the TODO comment for hyper-resistivity implementation

The constant_hyperresistive_ method contains a TODO comment referring to issue #3. This indicates that the implementation may be incomplete or requires further attention.

Do you need assistance in addressing this TODO? If so, I can help implement the required changes or provide guidance. Let me know if you'd like me to open a new GitHub issue to track this task.


367-389: Address the TODO comment in spatial_hyperresistive_ method

The spatial_hyperresistive_ method also contains a TODO comment referring to issue #3. This suggests that further implementation or refinement is needed for spatial hyper-resistivity.

Would you like help in completing the implementation of this method? I can provide assistance or open a GitHub issue to track this work.

src/core/data/grid/gridlayout.hpp (5)

1174-1174: Mark levelNumber() with NO_DISCARD to prevent ignored return values

To avoid situations where the return value of levelNumber() is unintentionally ignored, consider marking the function with the NO_DISCARD attribute.

Apply this diff:

-auto levelNumber() const { return levelNumber_; }
+NO_DISCARD auto levelNumber() const { return levelNumber_; }

1519-1519: Remove redundant default initialization of levelNumber_

The member variable levelNumber_ is default-initialized to 0 in its declaration and also set in the constructor's initializer list. The default initialization is redundant and can be removed to avoid confusion.

Apply this diff:

-int levelNumber_ = 0;
+int levelNumber_;

1077-1077: Add missing documentation for new projection methods

The newly added methods BxToEx(), BxToEy(), ByToEy(), and BzToEz() lack documentation comments. For consistency and better maintainability, please add Doxygen-style comments describing the purpose and usage of each method, similar to existing methods in the class.

Apply this diff to add comments:

+/**
+ * @brief BxToEx returns indexes and coefficients to interpolate Bx onto Ex.
+ */
 NO_DISCARD auto static constexpr BxToEx() { return GridLayoutImpl::BxToEx(); }

+/**
+ * @brief BxToEy returns indexes and coefficients to interpolate Bx onto Ey.
+ */
 NO_DISCARD auto static constexpr BxToEy() { return GridLayoutImpl::BxToEy(); }

+/**
+ * @brief ByToEy returns indexes and coefficients to interpolate By onto Ey.
+ */
 NO_DISCARD auto static constexpr ByToEy() { return GridLayoutImpl::ByToEy(); }

+/**
+ * @brief BzToEz returns indexes and coefficients to interpolate Bz onto Ez.
+ */
 NO_DISCARD auto static constexpr BzToEz() { return GridLayoutImpl::BzToEz(); }

Also applies to: 1093-1093, 1101-1101, 1125-1125


1077-1077: Adjust order of function specifiers for consistency

The order of specifiers in the methods BxToEx(), BxToEy(), ByToEy(), and BzToEz() is unconventional. In C++, the recommended order is static constexpr, followed by the return type. Adjusting the order improves readability and maintains consistency with the rest of the codebase.

Apply this diff to reorder the specifiers:

-NO_DISCARD auto static constexpr BxToEx() { return GridLayoutImpl::BxToEx(); }
+NO_DISCARD static constexpr auto BxToEx() { return GridLayoutImpl::BxToEx(); }

-NO_DISCARD auto static constexpr BxToEy() { return GridLayoutImpl::BxToEy(); }
+NO_DISCARD static constexpr auto BxToEy() { return GridLayoutImpl::BxToEy(); }

-NO_DISCARD auto static constexpr ByToEy() { return GridLayoutImpl::ByToEy(); }
+NO_DISCARD static constexpr auto ByToEy() { return GridLayoutImpl::ByToEy(); }

-NO_DISCARD auto static constexpr BzToEz() { return GridLayoutImpl::BzToEz(); }
+NO_DISCARD static constexpr auto BzToEz() { return GridLayoutImpl::BzToEz(); }

Also applies to: 1093-1093, 1101-1101, 1125-1125


1174-1174: Consistency in accessor method naming

The method levelNumber() provides access to the member variable levelNumber_. Ensure that the naming conventions for accessor methods are consistent throughout the codebase. If other accessor methods use get or another prefix, consider renaming this method to match.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 8d15f77 and fef5511.

📒 Files selected for processing (10)
  • pyphare/pyphare/pharein/init.py (1 hunks)
  • pyphare/pyphare/pharein/simulation.py (2 hunks)
  • src/amr/resources_manager/amr_utils.hpp (1 hunks)
  • src/amr/solvers/solver_ppc.hpp (2 hunks)
  • src/amr/tagging/default_hybrid_tagger_strategy.hpp (1 hunks)
  • src/core/data/grid/gridlayout.hpp (6 hunks)
  • src/core/data/grid/gridlayoutimplyee.hpp (3 hunks)
  • src/core/data/tensorfield/tensorfield.hpp (1 hunks)
  • src/core/data/vecfield/vecfield.hpp (1 hunks)
  • src/core/numerics/ohm/ohm.hpp (6 hunks)
✅ Files skipped from review due to trivial changes (2)
  • src/core/data/tensorfield/tensorfield.hpp
  • src/core/data/vecfield/vecfield.hpp
🧰 Additional context used
📓 Path-based instructions (6)
src/amr/resources_manager/amr_utils.hpp (1)

Pattern **/*.hpp: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.

src/amr/solvers/solver_ppc.hpp (1)

Pattern **/*.hpp: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.

src/amr/tagging/default_hybrid_tagger_strategy.hpp (1)

Pattern **/*.hpp: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.

src/core/data/grid/gridlayout.hpp (1)

Pattern **/*.hpp: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.

src/core/data/grid/gridlayoutimplyee.hpp (1)

Pattern **/*.hpp: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.

src/core/numerics/ohm/ohm.hpp (1)

Pattern **/*.hpp: Review the C++ code, point out issues relative to principles of clean code, expressiveness, and performance.

🔇 Additional comments (7)
src/core/numerics/ohm/ohm.hpp (1)

293-293: ⚠️ Potential issue

Incorrect placement of #include <cmath> inside function

The #include <cmath> directive is placed inside the pressure_ function at line 293. Including headers within function bodies is not standard practice and may lead to compilation issues or unexpected behavior.

Move the #include <cmath> directive to the top of the file with the other #include statements. Apply this diff to fix the issue:

Place #include <cmath> with the other includes:

Likely invalid or redundant comment.

pyphare/pyphare/pharein/__init__.py (3)

240-242: Verify initialization of Ohm's law parameters in Simulation

The parameters simulation.resistivity, simulation.hyper_resistivity, and simulation.hyper_mode are added to the configuration. Ensure that these attributes are initialized in the Simulation class with appropriate default values to avoid AttributeError if they are not provided by the user.

Use the following script to confirm that these attributes are defined in the Simulation class:

#!/bin/bash
# Description: Check if 'resistivity', 'hyper_resistivity', and 'hyper_mode' are initialized in 'Simulation' class.

# Search for the '__init__' method in 'Simulation' where these attributes should be set.
ast-grep --lang python --pattern $'class Simulation($$$_):
  $$$
  def __init__($$$_):
    $$$
    self.resistivity = $_
    self.hyper_resistivity = $_
    self.hyper_mode = $_
    $$$
  $$$'

242-242: Confirm consistency of configuration paths for Ohm's law parameters

Ensure that the configuration paths for resistivity, hyper_resistivity, and hyper_mode under "simulation/algo/ohm/" are consistent throughout the codebase and align with how other algorithms and parameters are structured.

Run the following script to check for other usages of the "simulation/algo/ohm/" path:

#!/bin/bash
# Description: Search for occurrences of the Ohm's law configuration path to verify consistency.

# Find all instances where the Ohm's law path is used.
rg --type py '("|\')simulation/algo/ohm/.*("|\')'

239-239: Ensure simulation.particle_pusher is properly initialized

The line adds simulation.particle_pusher to the configuration. Please verify that simulation.particle_pusher is set and valid before this point to prevent potential AttributeError exceptions if it is None or not defined.

To check where simulation.particle_pusher is set and ensure it has a default value, you can run the following script:

src/core/data/grid/gridlayout.hpp (1)

123-123: Initialize member variable in initializer list

The member variable levelNumber_ is correctly initialized in the constructor's member initializer list, ensuring it holds the intended value upon object creation.

src/core/data/grid/gridlayoutimplyee.hpp (2)

788-828: Apply the refactoring suggestion to BzToEz()

Similar to BxToEx(), the BzToEz() method has repetitive code blocks for each dimension. Refactoring this method to reduce code duplication will improve code clarity and maintainability.


923-962: Apply the refactoring suggestion to ByToEy()

The ByToEy() method also presents repetitive structures for handling different dimensions. Using the same refactoring approach as suggested for BxToEx() can enhance the codebase by reducing redundancy.

Comment on lines +111 to +114
return std::make_tuple(std::abs((F(ix + 2, iy) - F(ix, iy))
/ (1 + std::abs(F(ix + 1, iy) - F(ix, iy)))),
std::abs(F(ix, iy + 2) - F(ix, iy))
/ (std::abs(F(ix, iy + 1) - F(ix, iy)) + 1));
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Approved: Changes align with PR objectives and improve formula consistency.

The modifications to the field_diff lambda function address the PR objective of incorporating absolute values in the tagging formula. This should help in refining the two current layers uniformly across different thresholds.

A minor optimization suggestion:

Consider factoring out the common std::abs() call in the denominator of the second tuple element:

 return std::make_tuple(std::abs((F(ix + 2, iy) - F(ix, iy))
                                 / (1 + std::abs(F(ix + 1, iy) - F(ix, iy)))),
                        std::abs(F(ix, iy + 2) - F(ix, iy))
-                            / (std::abs(F(ix, iy + 1) - F(ix, iy)) + 1));
+                            / (1 + std::abs(F(ix, iy + 1) - F(ix, iy))));

This change makes the second tuple element consistent with the first one and potentially improves readability.

📝 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 std::make_tuple(std::abs((F(ix + 2, iy) - F(ix, iy))
/ (1 + std::abs(F(ix + 1, iy) - F(ix, iy)))),
std::abs(F(ix, iy + 2) - F(ix, iy))
/ (std::abs(F(ix, iy + 1) - F(ix, iy)) + 1));
return std::make_tuple(std::abs((F(ix + 2, iy) - F(ix, iy))
/ (1 + std::abs(F(ix + 1, iy) - F(ix, iy)))),
std::abs(F(ix, iy + 2) - F(ix, iy))
/ (1 + std::abs(F(ix, iy + 1) - F(ix, iy))));

Comment on lines +185 to +186
auto lvlNbr = patch.getPatchLevelNumber();
return GridLayoutT{dl, nbrCell, origin, amr::Box<int, dimension>{domain}, lvlNbr};
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider improving backwards compatibility and documentation

The addition of the patch level number (lvlNbr) to the GridLayoutT constructor is a valuable change that can enhance level-specific operations and debugging. However, this modification has some implications:

  1. The function signature change may break existing code that uses layoutFromPatch.
  2. The function's documentation hasn't been updated to reflect this new parameter.

To address these issues:

  1. Consider using a default parameter to maintain backwards compatibility:

    NO_DISCARD GridLayoutT layoutFromPatch(SAMRAI::hier::Patch const& patch, int lvlNbr = -1)

    If lvlNbr is not provided, you can still obtain it from patch.getPatchLevelNumber().

  2. Update the function documentation to describe the new lvlNbr parameter and its purpose.

Here's a suggested implementation with improved documentation:

/**
 * @brief Create a GridLayoutT from a SAMRAI::hier::Patch
 * @param patch The SAMRAI patch to create the layout from
 * @param lvlNbr The patch level number (optional, default: -1)
 * @return A GridLayoutT instance representing the patch
 */
template<typename GridLayoutT>
NO_DISCARD GridLayoutT layoutFromPatch(SAMRAI::hier::Patch const& patch, int lvlNbr = -1)
{
    // ... (existing code)

    if (lvlNbr == -1)
    {
        lvlNbr = patch.getPatchLevelNumber();
    }

    return GridLayoutT{dl, nbrCell, origin, amr::Box<int, dimension>{domain}, lvlNbr};
}

This approach maintains backwards compatibility while allowing explicit specification of the level number when needed.

Comment on lines +374 to +376
auto const nOnE = GridLayout::project(n, index, nProj);
auto b = std::sqrt(BxOnE * BxOnE + ByOnE * ByOnE + BzOnE * BzOnE);
return -nu_ * b / nOnE * lvlCoeff * layout_->laplacian(J(component), index);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Potential division by zero in spatial_hyperresistive_ method

In the spatial_hyperresistive_ method, the calculation involves dividing by nOnE, which could be zero if the electron density is zero at a given point. This may lead to division by zero errors during runtime.

Consider adding a check to ensure that nOnE is not zero before performing the division, or handle zero-density cases appropriately. For example:

auto const nOnE  = GridLayout::project(n, index, nProj);
+if (nOnE == 0.0) {
+    // Handle zero-density case to prevent division by zero
+    return 0.0;
+}
auto b           = std::sqrt(BxOnE * BxOnE + ByOnE * ByOnE + BzOnE * BzOnE);
return -nu_ * b / nOnE * lvlCoeff * layout_->laplacian(J(component), index);

Committable suggestion was skipped due to low confidence.

@@ -1508,6 +1515,8 @@ namespace core
// arrays will be accessed with [primal] and [dual] indexes.
constexpr static std::array<int, 2> nextIndexTable_{{nextPrimal_(), nextDual_()}};
constexpr static std::array<int, 2> prevIndexTable_{{prevPrimal_(), prevDual_()}};

int levelNumber_ = 0;
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider using std::size_t for levelNumber_

Since levelNumber_ represents a non-negative level index, using an unsigned type like std::size_t can prevent negative values and improve type safety.

Apply this diff:

-int levelNumber_;
+std::size_t levelNumber_;
📝 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
int levelNumber_ = 0;
std::size_t levelNumber_ = 0;

@@ -112,14 +112,15 @@
GridLayout(std::array<double, dimension> const& meshSize,
std::array<std::uint32_t, dimension> const& nbrCells,
Point<double, dimension> const& origin,
Box<int, dimension> AMRBox = Box<int, dimension>{})
Box<int, dimension> AMRBox = Box<int, dimension>{}, int level_number = 0)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Ensure consistent parameter type for level_number

The new constructor parameter int level_number = 0 introduces the level_number as an int. Since level_number represents a non-negative value (level index), consider using std::size_t or unsigned int for consistency and to prevent negative values.

Apply this diff to change the parameter type:

-Box<int, dimension> AMRBox = Box<int, dimension>{}, int level_number = 0)
+Box<int, dimension> AMRBox = Box<int, dimension>{}, std::size_t level_number = 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
Box<int, dimension> AMRBox = Box<int, dimension>{}, int level_number = 0)
Box<int, dimension> AMRBox = Box<int, dimension>{}, std::size_t level_number = 0)

Comment on lines +688 to +728
NO_DISCARD auto static constexpr BxToEx()
{
// Bx is primal dual dual
// Ex is dual primal primal
// operation is pdd to dpp
[[maybe_unused]] auto constexpr p2dShift = primalToDual();
[[maybe_unused]] auto constexpr d2pShift = dualToPrimal();

if constexpr (dimension == 1)
{
constexpr WeightPoint<dimension> P1{Point<int, dimension>{0}, 0.5};
constexpr WeightPoint<dimension> P2{Point<int, dimension>{p2dShift}, 0.5};
return std::array<WeightPoint<dimension>, 2>{P1, P2};
}
else if constexpr (dimension == 2)
{
constexpr WeightPoint<dimension> P1{Point<int, dimension>{0, 0}, 0.25};
constexpr WeightPoint<dimension> P2{Point<int, dimension>{0, d2pShift}, 0.25};
constexpr WeightPoint<dimension> P3{Point<int, dimension>{p2dShift, 0}, 0.25};
constexpr WeightPoint<dimension> P4{Point<int, dimension>{p2dShift, d2pShift},
0.25};
return std::array<WeightPoint<dimension>, 4>{P1, P2, P3, P4};
}
else if constexpr (dimension == 3)
{
constexpr WeightPoint<dimension> P1{Point<int, dimension>{0, 0, 0}, 0.125};
constexpr WeightPoint<dimension> P2{Point<int, dimension>{0, d2pShift, 0}, 0.125};
constexpr WeightPoint<dimension> P3{Point<int, dimension>{p2dShift, 0, 0}, 0.125};
constexpr WeightPoint<dimension> P4{Point<int, dimension>{p2dShift, d2pShift, 0},
0.125};

constexpr WeightPoint<dimension> P5{Point<int, dimension>{0, 0, d2pShift}, 0.125};
constexpr WeightPoint<dimension> P6{Point<int, dimension>{0, d2pShift, d2pShift},
0.125};
constexpr WeightPoint<dimension> P7{Point<int, dimension>{p2dShift, 0, d2pShift},
0.125};
constexpr WeightPoint<dimension> P8{
Point<int, dimension>{p2dShift, d2pShift, d2pShift}, 0.125};
return std::array<WeightPoint<dimension>, 8>{P1, P2, P3, P4, P5, P6, P7, P8};
}
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider refactoring BxToEx() to reduce code duplication

The BxToEx() method contains similar code blocks for different dimensions (dimension == 1, dimension == 2, and dimension == 3). This can lead to code duplication and increase maintenance effort. To enhance maintainability and readability, consider refactoring by creating a helper function or using templates to handle the common logic across dimensions.

Comment on lines +34 to +44
// template<typename VecField, typename... Index>
// NO_DISCARD auto norm(VecField const& vf, Index... index)
// {
// using Type = typename VecField::value_type;
// std::sqrt(std::accumulate(std::begin(vf.components()), std::end(vf.components()),
// Type{0},
// [&](auto acc, auto const& c) {
// auto const v = c(index...);
// return acc(index...) + v * v;
// }));
// }

Check notice

Code scanning / CodeQL

Commented-out code Note

This comment appears to contain commented-out code.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants