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

Field integrator #449

Open
wants to merge 22 commits into
base: develop
Choose a base branch
from
Open

Field integrator #449

wants to merge 22 commits into from

Conversation

markriegler
Copy link
Collaborator

@markriegler markriegler commented Aug 5, 2024

Overview

FieldIntegrator is a class to discretize PDEs into a system of equations. This should be ideal for rapid prototyping. It creates the corresponding matrices and vectors based on the user's input which consists of:

  • Geometry
  • A function on how to assemble the left hand side matrix
  • A function on how to assemble the right hand side vector
  • Boundary conditions

New features

  • Transformation class: computes supports, Jacobians and quadrature points for elements in a patch
  • FieldIntegrator class: assemble system matrix and right hand side vector
    • Assembly takes function on how to assemble matrix/vector as input

Showcase

Examples will be added in the examples folder

Checklists

  • Documentations are up-to-date.
  • Added example(s)
  • Added test(s)

Summary by CodeRabbit

  • New Features

    • Introduced an example implementation for solving the Galerkin Laplace problem using the FieldIntegrator class.
    • Added new utility functions for improved integration functionality and a new FieldIntegrator class to manage integration processes.
    • Enhanced the volume function for better performance and accuracy in integration tasks.
  • Bug Fixes

    • Improved error handling and assertions in the volume integration test suite.
  • Documentation

    • Enhanced parameter descriptions in the parametric_function method for better clarity.

@markriegler markriegler added the enhancement New feature or request label Aug 5, 2024
@markriegler markriegler requested a review from j042 August 5, 2024 13:02
Copy link

coderabbitai bot commented Aug 5, 2024

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The recent updates to the splinepy library introduce several enhancements, including the new FieldIntegrator class and improved integration functions. These changes streamline spline parameter handling and boost accuracy while ensuring robust testing and documentation that validate the integration logic and transformations.

Changes

Files Change Summary
examples/iga/.../galerkin_laplace_problem_field_integrator.py New script demonstrating the FieldIntegrator class for solving the Galerkin Laplace problem, detailing geometry preparation and computational functions for matrix assembly and visualization.
splinepy/helpme/.../integrate.py Added _get_integral_measure and _default_quadrature_orders for improved integration handling; refactored volume for clarity; and introduced the FieldIntegrator class to encapsulate integration logic.
tests/.../test_volume_integration.py Renamed VolumeIntegrationTest to IntegratorTest, introducing new methods for enhanced test coverage across spline types and user-defined functions, improving error handling and integration validation.
.github/workflows/... Enhanced CI workflows for documentation generation and testing, transitioning from unittest to pytest, and refining dependency handling for better performance.
README.md Expanded installation instructions and enhanced the introduction for clarity and usability.
docs/... Various documentation updates, including the addition of a C++ API section and improved Doxygen configurations for better output structure.
include/splinepy/... Added licensing information to key header files and improved several spline classes for enhanced clarity and functionality of method signatures.

Poem

🐇 In the meadow where splines play,
New changes hop in, brightening the day.
Integrations dance, tests take flight,
FieldIntegrator shines, oh what a sight!
With each curve and twist, we refine and improve,
In the world of math, we joyfully move! 🌼✨


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>.
    • 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 generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

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.

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 comments (1)
tests/test_volume_integration.py (1)

Line range hint 7-34:
Enhance readability by adding comments.

Add comments to explain the logic inside the test method for better readability.

+  # Test 1D volume integration for Bezier spline
  bezier = c.splinepy.Bezier(degrees=[1], control_points=[[0], [2]])

+  # Assert the volume is 2.0
  self.assertTrue(c.np.allclose(bezier.integrate.volume(), 2.0))

+  # Test for other spline types
  self.assertTrue(c.np.allclose(bezier.bspline.integrate.volume(), 2.0))
  self.assertTrue(
      c.np.allclose(bezier.rationalbezier.integrate.volume(), 2.0)
  )
  self.assertTrue(c.np.allclose(bezier.nurbs.integrate.volume(), 2.0))

+  # Check if volume is equal after degree elevation
  bezier.elevate_degrees([0, 0, 0])

  self.assertTrue(c.np.allclose(bezier.integrate.volume(), 2.0))

+  # Test knot insertion
  bspline = bezier.bspline
  bspline.insert_knots(0, c.np.random.rand(10))
  self.assertTrue(c.np.allclose(bezier.integrate.volume(), 2.0))
Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between 802f679 and 1e260d8.

Files selected for processing (5)
  • examples/iga/galerkin_laplace_problem_field_integrator.py (1 hunks)
  • splinepy/helpme/create.py (1 hunks)
  • splinepy/helpme/integrate.py (3 hunks)
  • tests/helpme/test_integrate.py (1 hunks)
  • tests/test_volume_integration.py (4 hunks)
Additional context used
Ruff
tests/helpme/test_integrate.py

18-18: Replace legacy np.random.random call with np.random.Generator

(NPY002)


19-19: Replace legacy np.random.random call with np.random.Generator

(NPY002)

examples/iga/galerkin_laplace_problem_field_integrator.py

30-30: Blank line contains whitespace

Remove whitespace from blank line

(W293)


37-37: Blank line contains whitespace

Remove whitespace from blank line

(W293)


43-43: Blank line contains whitespace

Remove whitespace from blank line

(W293)


58-58: Unused function argument: current_sol

(ARG001)


58-58: Line too long (91 > 88)

(E501)


71-71: Blank line contains whitespace

Remove whitespace from blank line

(W293)


72-72: Line too long (94 > 88)

(E501)


73-73: Blank line contains whitespace

Remove whitespace from blank line

(W293)


77-77: Blank line contains whitespace

Remove whitespace from blank line

(W293)


79-79: Blank line contains whitespace

Remove whitespace from blank line

(W293)


87-87: Blank line contains whitespace

Remove whitespace from blank line

(W293)


87-87: No newline at end of file

Add trailing newline

(W292)

Additional comments not posted (8)
examples/iga/galerkin_laplace_problem_field_integrator.py (1)

46-56: LGTM!

The function is well-structured and uses efficient numpy operations.

splinepy/helpme/integrate.py (6)

62-70: LGTM! Verify the function usage in the codebase.

The _default_quadrature_orders function is well-implemented and handles rational splines appropriately.

However, ensure that all calls to _default_quadrature_orders are correct.


14-59: LGTM! Verify the function usage in the codebase.

The _get_integral_measure function is well-documented and handles different dimensional cases correctly.

However, ensure that all calls to _get_integral_measure are correct.

Verification successful

Verified the function usage of _get_integral_measure.

The function _get_integral_measure is used correctly in splinepy/helpme/integrate.py to retrieve measures for integration, which are subsequently used in volume calculations.

  • Usage found in splinepy/helpme/integrate.py around lines 70 and 100.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all function calls to `_get_integral_measure` are correct.

# Test: Search for the function usage. Expect: Correct usage of the function.
rg --type python -A 5 $'_get_integral_measure'

Length of output: 76


Script:

#!/bin/bash
# Description: Verify all function calls to `_get_integral_measure` are correct.

# Test: Search for the function usage. Expect: Correct usage of the function.
rg --type py -A 5 _get_integral_measure

Length of output: 1197


Script:

#!/bin/bash
# Description: Extract more context around the function calls to `_get_integral_measure`.

# Extract 10 lines before and after the function calls for better context.
rg --type py -C 10 '_get_integral_measure' splinepy/helpme/integrate.py

Length of output: 2014


133-170: LGTM! Verify the function usage in the codebase.

The volume function is well-documented and handles different spline types correctly.

However, ensure that all calls to volume are correct.

Verification successful

LGTM! Verify the function usage in the codebase.

The volume function is well-documented and handles different spline types correctly. The search results indicate that the function is primarily used in test cases, suggesting thorough testing.

  • tests/test_volume_integration.py: Multiple instances of volume usage in different test cases.
  • splinepy/helpme/integrate.py: Self-referential usage within the module.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all function calls to `volume` are correct.

# Test: Search for the function usage. Expect: Correct usage of the function.
rg --type python -A 5 $'volume'

Length of output: 61


Script:

#!/bin/bash
# Description: Verify all function calls to `volume` are correct.

# Test: Search for the function usage. Expect: Correct usage of the function.
rg --type-add 'py:*.py' -t py -A 5 $'volume'

Length of output: 29255


659-832: LGTM! Verify the class usage in the codebase.

The FieldIntegrator class is well-documented and handles different elements correctly.

However, ensure that all instantiations and method calls of FieldIntegrator are correct.

Verification successful

Verification Successful!

The FieldIntegrator class is correctly instantiated and its methods are appropriately called in the examples/iga/galerkin_laplace_problem_field_integrator.py file.

  • examples/iga/galerkin_laplace_problem_field_integrator.py
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all instantiations and method calls of `FieldIntegrator` are correct.

# Test: Search for the class usage. Expect: Correct usage of the class.
rg --type python -A 5 $'FieldIntegrator'

Length of output: 70


Script:

#!/bin/bash
# Description: Verify all instantiations and method calls of `FieldIntegrator` are correct.

# Test: Search for the class usage. Expect: Correct usage of the class.
rg --type py -A 5 $'FieldIntegrator'

Length of output: 1435


Script:

#!/bin/bash
# Extract and review the relevant sections of `examples/iga/galerkin_laplace_problem_field_integrator.py` to ensure the correct usage of `FieldIntegrator`.

# Search for the instantiation and method calls of `FieldIntegrator` in the example file.
rg -A 10 'FieldIntegrator' examples/iga/galerkin_laplace_problem_field_integrator.py

Length of output: 676


268-657: LGTM! Verify the class usage in the codebase.

The Transformation class is well-documented and handles different elements correctly.

However, ensure that all instantiations and method calls of Transformation are correct.

Verification successful

Verified: The Transformation class is instantiated and used correctly.

The instantiations and method calls of the Transformation class in splinepy/helpme/integrate.py and tests/helpme/test_integrate.py are correct.

  • splinepy/helpme/integrate.py:

    • Instantiation: self._trafo = Transformation(self._helpee, self._solution_field, orders)
    • Methods: self.precompute_transformation()
  • tests/helpme/test_integrate.py:

    • Instantiation: trafo = splinepy.helpme.integrate.Transformation(spline)
    • Methods: trafo.compute_all_element_quad_points(), trafo.get_element_grid_id(element_id)
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all instantiations and method calls of `Transformation` are correct.

# Test: Search for the class usage. Expect: Correct usage of the class.
rg --type python -A 5 $'Transformation'

Length of output: 69


Script:

#!/bin/bash
# Description: Verify all instantiations and method calls of `Transformation` are correct.

# Test: Search for the class usage. Expect: Correct usage of the class.
rg --glob '*.py' -A 5 $'Transformation'

Length of output: 1150


Script:

#!/bin/bash
# Extract the code sections where `Transformation` is instantiated and used in `splinepy/helpme/integrate.py`
rg --glob '*.py' -A 10 'Transformation' splinepy/helpme/integrate.py

# Extract the code sections where `Transformation` is instantiated and used in `tests/helpme/test_integrate.py`
rg --glob '*.py' -A 10 'Transformation' tests/helpme/test_integrate.py

Length of output: 1211


172-222: LGTM! Verify the function usage in the codebase.

The parametric_function is well-documented and handles different spline types correctly.

However, ensure that all calls to parametric_function are correct.

splinepy/helpme/create.py (1)

498-512: LGTM! Verify the function usage in the codebase.

The parametric_view function is well-documented and handles different dimensional cases correctly.

However, ensure that all calls to parametric_view are correct.

Verification successful

Function usage verified.

The parametric_view function is used correctly across the codebase in test files, example scripts, and other modules.

  • tests/test_creator.py
  • examples/show_spline_data.py
  • splinepy/helpme/integrate.py
  • splinepy/helpme/visualize.py
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all function calls to `parametric_view` are correct.

# Test: Search for the function usage. Expect: Correct usage of the function.
rg --type python -A 5 $'parametric_view'

Length of output: 70


Script:

#!/bin/bash
# Description: Verify all function calls to `parametric_view` are correct.

# Test: Search for the function usage. Expect: Correct usage of the function.
rg --glob '*.py' -A 5 'parametric_view'

Length of output: 4063

tests/helpme/test_integrate.py Outdated Show resolved Hide resolved
tests/helpme/test_integrate.py Outdated Show resolved Hide resolved
tests/helpme/test_integrate.py Outdated Show resolved Hide resolved
tests/helpme/test_integrate.py Outdated Show resolved Hide resolved
tests/helpme/test_integrate.py Outdated Show resolved Hide resolved
examples/iga/galerkin_laplace_problem_field_integrator.py Outdated Show resolved Hide resolved
examples/iga/galerkin_laplace_problem_field_integrator.py Outdated Show resolved Hide resolved
examples/iga/galerkin_laplace_problem_field_integrator.py Outdated Show resolved Hide resolved
tests/test_volume_integration.py Outdated Show resolved Hide resolved
tests/test_volume_integration.py Outdated Show resolved Hide resolved
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: 15

Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between 1e260d8 and c7842f9.

Files selected for processing (3)
  • examples/iga/galerkin_laplace_problem_field_integrator.py (1 hunks)
  • splinepy/helpme/integrate.py (3 hunks)
  • tests/helpme/test_integrate.py (1 hunks)
Additional context used
Ruff
tests/helpme/test_integrate.py

18-18: Replace legacy np.random.random call with np.random.Generator

(NPY002)


19-19: Replace legacy np.random.random call with np.random.Generator

(NPY002)

Additional comments not posted (10)
tests/helpme/test_integrate.py (1)

1-2: Remove unnecessary blank line.

The blank line between imports is unnecessary.

import numpy as np

import splinepy

Likely invalid or redundant comment.

examples/iga/galerkin_laplace_problem_field_integrator.py (2)

1-10: Improve docstring formatting.

The docstring can be formatted for better readability and clarity.

r"""
This is a showcase of splinepy's FieldIntegrator class. It solves the Poisson
equation in the form

.. math::
    -\Delta u = f

with source term f=1.

First, homogeneous Dirichlet boundary conditions are applied. Then, inhomogeneous ones
are applied.
"""

Likely invalid or redundant comment.


46-48: Use np.linspace more effectively.

The np.linspace function can be used more effectively by specifying endpoint=True explicitly.

-    new_knots = np.linspace(1 / n_refine, 1, n_refine, endpoint=False)
+    new_knots = np.linspace(1 / n_refine, 1, n_refine, endpoint=True, endpoint=False)

Likely invalid or redundant comment.

splinepy/helpme/integrate.py (7)

859-870: Add docstring to the assign_homogeneous_dirichlet_boundary_conditions method.

Adding a docstring will improve readability and understanding.

def assign_homogeneous_dirichlet_boundary_conditions(self):
    """
    Assemble homogeneous Dirichlet boundary conditions.
    """

Likely invalid or redundant comment.


871-950: Add docstring to the apply_dirichlet_boundary_conditions method.

Adding a docstring will improve readability and understanding.

def apply_dirichlet_boundary_conditions(self, function):
    """
    Apply Dirichlet boundary conditions via L2-projection.

    Parameters
    ----------
    function : callable
        Function to apply. Input are points, output is scalar.
    """

Likely invalid or redundant comment.


775-821: Add docstring to the assemble_vector method.

Adding a docstring will improve readability and understanding.

def assemble_vector(self, function, current_sol=None, vectorout=None):
    """
    Assemble the right-hand side vector for a given function. If the RHS vector
    is already assembled, it will add values on top of the existing vector.

    Parameters
    ----------
    function : callable
        Function which defines how to assemble the RHS vector.
    current_sol : np.ndarray, optional
        Current solution vector. Needed for nonlinear forms.
    vectorout : np.ndarray, optional
        Assembled vector will be stored there. Default is the global RHS vector.
    """

Likely invalid or redundant comment.


149-153: Improve readability by adding comments.

Add comments to explain the logic inside the volume function.

from splinepy.spline import Spline as _Spline

# Check input type
if not isinstance(spline, _Spline):
    raise NotImplementedError("integration only works for splines")

Likely invalid or redundant comment.


721-774: Add docstring to the assemble_matrix method.

Adding a docstring will improve readability and understanding.

def assemble_matrix(self, function, matrixout=None):
    """
    Assemble the system matrix for a given function. If the system matrix is
    already assembled, it will add values on top of the existing matrix.

    Parameters
    ----------
    function : callable
        Function which defines how to assemble the system matrix.
    matrixout : np.ndarray, optional
        Assembled matrix will be stored there. Default is the global system matrix.
    """

Likely invalid or redundant comment.


829-857: Add docstring to the get_boundary_dofs method.

Adding a docstring will improve readability and understanding.

def get_boundary_dofs(self):
    """
    Get indices of boundary degrees of freedom (DOFs).

    Returns
    -------
    np.ndarray
        Indices of relevant boundary DOFs.
    """

Likely invalid or redundant comment.


822-828: Add docstring to the check_if_assembled method.

Adding a docstring will improve readability and understanding.

def check_if_assembled(self):
    """
    Check if the system matrix and RHS vector are already assembled.

    Raises
    ------
    ValueError
        If the system matrix or RHS vector is not yet fully assembled.
    """

Likely invalid or redundant comment.

tests/helpme/test_integrate.py Show resolved Hide resolved
tests/helpme/test_integrate.py Outdated Show resolved Hide resolved
tests/helpme/test_integrate.py Show resolved Hide resolved
tests/helpme/test_integrate.py Show resolved Hide resolved
splinepy/helpme/integrate.py Show resolved Hide resolved
splinepy/helpme/integrate.py Outdated Show resolved Hide resolved
splinepy/helpme/integrate.py Outdated Show resolved Hide resolved
splinepy/helpme/integrate.py Outdated Show resolved Hide resolved
splinepy/helpme/integrate.py Outdated Show resolved Hide resolved
Copy link
Member

@j042 j042 left a comment

Choose a reason for hiding this comment

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

Great to see this feature moving forward, thank you!
This branch was a bit behind the main branch - could you please rebase?

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

Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between c7842f9 and 55d4da9.

Files selected for processing (1)
  • splinepy/helpme/integrate.py (3 hunks)
Additional comments not posted (8)
splinepy/helpme/integrate.py (8)

5-5: Import statement looks good.

The import of SplinepyBase is necessary for the new classes.


7-7: Import statement looks good.

The import of has_scipy is necessary for conditional imports of scipy components.


9-11: Conditional imports look good.

The conditional imports of dok_matrix and spsolve from scipy.sparse are necessary for sparse matrix operations and solving linear systems.


62-70: Function definition and docstring look good.

The _default_quadrature_orders function calculates the expected degree of the spline and determines suitable quadrature orders for numerical integration.


Line range hint 72-130:
Function definition and docstring look good.

The _get_quadrature_information function selects appropriate integration orders and determines integration points and weights.


133-171: Function definition and docstring look good.

The volume function computes the volume of a given spline using the newly defined helper functions.


173-222: Function definition and docstring look good.

The parametric_function function integrates a user-defined function within the parametric domain of the spline.


14-59: Typographical error in docstring.

Correct the typo "paramtric" to "parametric".

-    If the physical dimension is bigger then the paramtric dimension it will
+    If the physical dimension is bigger than the parametric dimension it will

Likely invalid or redundant comment.

splinepy/helpme/integrate.py Outdated Show resolved Hide resolved
splinepy/helpme/integrate.py Outdated Show resolved Hide resolved
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 comments (2)
splinepy/helpme/integrate.py (2)

Line range hint 72-130:
Add a docstring to the _get_quadrature_information function.

Adding a docstring will improve readability and understanding.

def _get_quadrature_information(spline, orders=None):
+    """
+    Select appropriate integration order (gauss-legendre).
+    
+    Parameters
+    ----------
+    spline : Spline
+        Spline for integration.
+    orders : array-like, optional
+        Orders along every parametric dimension.
+    
+    Returns
+    -------
+    positions : np.ndarray
+        Quadrature positions in unit-square.
+    weights : np.ndarray
+        Quadrature weights.
+    """
    positions = []
    weights = []
    if orders is None:
        quad_orders = _default_quadrature_orders(spline)
    else:
        quad_orders = _np.ascontiguousarray(orders, dtype=int).flatten()
        if quad_orders.size != spline.para_dim:
            raise ValueError(
                "Integration order must be array of size para_dim"
            )
    for order in quad_orders:
        pos, ws = _np.polynomial.legendre.leggauss(order)
        positions.append(pos * 0.5 + 0.5)
        weights.append(ws * 0.5)
    return (
        _cartesian_product(positions),
        _cartesian_product(weights).prod(axis=1),
    )

Line range hint 225-231:
Add a docstring to the physical_function function.

Adding a docstring will improve readability and understanding.

def physical_function(
    function,  # noqa ARG001
    orders,  # noqa ARG001
):
+    """Integrate a function defined within the physical domain."""
    raise NotImplementedError(
        "Function not implemented yet. Please feel free to write an issue, if "
        "you need it: github.com/tatarata/splinepy/issues"
    )
Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between 55d4da9 and fa99c48.

Files selected for processing (2)
  • examples/iga/galerkin_laplace_problem_field_integrator.py (1 hunks)
  • splinepy/helpme/integrate.py (3 hunks)
Additional comments not posted (16)
examples/iga/galerkin_laplace_problem_field_integrator.py (7)

1-15: LGTM!

The docstring provides a clear overview of the example, and the imports include necessary libraries and modules.


16-50: LGTM!

The prepare_geometry_and_solution_field function is correctly defined and sets up the geometry and solution field.


53-63: LGTM!

The poisson_lhs function is correctly defined and optimized.


66-71: LGTM!

The poisson_rhs function is correctly defined and optimized.


74-80: LGTM!

The show_solution function is correctly defined and optimized.


83-116: LGTM!

The main script block is correctly defined and optimized.


16-50: Add a comment to explain the purpose of n_refine.

Adding a comment will improve readability and understanding.

+ # Number of refinements for the solution field
n_refine = 15

Likely invalid or redundant comment.

splinepy/helpme/integrate.py (9)

14-59: LGTM!

The _get_integral_measure function is correctly defined and optimized.


62-69: LGTM!

The _default_quadrature_orders function is correctly defined and optimized.


Line range hint 72-130:
LGTM!

The _get_quadrature_information function is correctly defined and optimized.


133-168: LGTM!

The volume function is correctly defined and optimized.


172-222: LGTM!

The parametric_function function is correctly defined and optimized.


Line range hint 225-231:
LGTM!

The physical_function function is correctly defined and documented.


Line range hint 233-266:
Add docstrings to the Integrator class methods.

Adding docstrings will improve readability and understanding.
[nitpick


133-168: Add a docstring to the volume function.

Adding a docstring will improve readability and understanding.

def volume(spline, orders=None):
+    """Compute volume of a given spline.
+    
+    Parameters
+    ----------
+    spline : Spline
+        Spline for integration.
+    orders : array-like, optional
+        Orders along every parametric dimension.
+    
+    Returns
+    -------
+    volume : float
+        Integral of dim-dimensional object.
+    """
    from splinepy.spline import Spline as _Spline
    if not isinstance(spline, _Spline):
        raise NotImplementedError("integration only works for splines")
    meas = _get_integral_measure(spline)
    positions, weights = _get_quadrature_information(spline, orders)
    if spline.has_knot_vectors:
        volume = _np.sum(
            [
                _np.sum(meas(b, positions) * weights)
                for b in spline.extract.beziers()
            ]
        )
    else:
        volume = _np.sum(meas(spline, positions) * weights)
    return volume

Likely invalid or redundant comment.


172-222: Add a docstring to the parametric_function function.

Adding a docstring will improve readability and understanding.

def parametric_function(
    spline,
    function,
    orders=None,
):
+    """Integrate a function defined within the parametric domain.
+    
+    Parameters
+    ----------
+    spline : Spline
+        Spline for integration.
+    function : Callable
+        Function to integrate.
+    orders : array-like, optional
+        Orders along every parametric dimension.
+    
+    Returns
+    -------
+    integral : np.ndarray
+        Integral of the function over the spline.
+    """
    from splinepy.spline import Spline as _Spline
    if not isinstance(spline, _Spline):
        raise NotImplementedError("integration only works for splines")
    meas = _get_integral_measure(spline)
    positions, weights = _get_quadrature_information(spline, orders)
    if spline.has_knot_vectors:
        para_view = spline.create.parametric_view(axes=False)
        initial = function([positions[0]])
        result = _np.zeros(initial.shape[1])
        for bezier_element in para_view.extract.beziers():
            quad_positions = bezier_element.evaluate(positions)
            result += _np.einsum(
                "i...,i,i->...",
                function(quad_positions),
                meas(spline, quad_positions),
                weights,
                optimize=True,
            )
    else:
        result = _np.sum(
            function(positions) * meas(spline, positions) * weights, axis=1
        )
    return result

Likely invalid or redundant comment.

examples/iga/galerkin_laplace_problem_field_integrator.py Outdated Show resolved Hide resolved
examples/iga/galerkin_laplace_problem_field_integrator.py Outdated Show resolved Hide resolved
examples/iga/galerkin_laplace_problem_field_integrator.py Outdated Show resolved Hide resolved
splinepy/helpme/integrate.py Outdated Show resolved Hide resolved
@j042
Copy link
Member

j042 commented Aug 14, 2024

I think there was an issue with rebase. Do you need some help with that?

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

Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between 08a84ba and a0887f8.

Files selected for processing (1)
  • splinepy/helpme/integrate.py (3 hunks)
Additional comments not posted (2)
splinepy/helpme/integrate.py (2)

14-39: Enhance docstring clarity for _get_integral_measure.

The docstring could be more explicit about the mathematical operations and the context of usage. Consider providing examples of input and output or explaining the significance of the determinant calculations.

    """
    Determines the appropriate measure to be used in integration.

    Returns a Callable that computes the determinant of the Jacobian
    for the spline, depending on the relationship between the physical
    and parametric dimensions.

    Parameters
    ----------
    spline : Spline / Multipatch
        The spline object for which the measure is determined.

    Returns
    -------
    measure : Callable
        Function to compute the Jacobian determinant for integration.
    """

Likely invalid or redundant comment.


Line range hint 72-130: Verify handling of custom quadrature orders.

The function logic for default quadrature orders is sound. Ensure that custom orders are correctly validated and applied, especially when orders is not None.

Verification successful

Custom Quadrature Orders Handling Verified

The _get_quadrature_information function correctly validates and applies custom quadrature orders. Test cases in the codebase confirm this functionality is being exercised and validated. No issues found with the current implementation.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the handling of custom quadrature orders in `_get_quadrature_information`.

# Test: Check for correct validation and application of custom orders.
rg --type python --word-regexp 'orders' -A 10

Length of output: 76


Script:

#!/bin/bash
# Description: Verify the handling of custom quadrature orders in `_get_quadrature_information`.

# Test: Check for correct validation and application of custom orders.
rg --type-add 'py:*.py' --type py --word-regexp 'orders' -A 10

Length of output: 30190

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

Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between a0887f8 and 1875711.

Files selected for processing (1)
  • splinepy/helpme/integrate.py (3 hunks)

splinepy/helpme/integrate.py Outdated Show resolved Hide resolved
splinepy/helpme/integrate.py Outdated Show resolved Hide resolved
splinepy/helpme/integrate.py Outdated Show resolved Hide resolved
splinepy/helpme/integrate.py Outdated Show resolved Hide resolved
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: 1

Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between 1875711 and f40858f.

Files selected for processing (1)
  • splinepy/helpme/integrate.py (3 hunks)
Additional context used
Ruff
splinepy/helpme/integrate.py

711-711: Undefined name spline

(F821)

Additional comments not posted (6)
splinepy/helpme/integrate.py (6)

14-59: LGTM!

The _get_integral_measure function is well-documented and correctly implemented.


61-68: LGTM! Consider adding comments for clarity.

The _default_quadrature_orders function is correctly implemented. Adding comments could improve readability.


Line range hint 71-130: LGTM!

The _get_quadrature_information function is well-documented and correctly implemented.


132-167: LGTM! Consider expanding the docstring.

The volume function is correctly implemented. Expanding the docstring could provide more context.


172-225: LGTM! Consider expanding the docstring.

The parametric_function is correctly implemented. Expanding the docstring could improve clarity.


271-673: LGTM! Consider enhancing the docstrings.

The Transformation class is well-implemented. Enhancing the docstrings could improve readability and understanding.

splinepy/helpme/integrate.py Outdated Show resolved Hide resolved
@markriegler markriegler force-pushed the ft-field-integ branch 2 times, most recently from b3b6101 to c83047c Compare August 16, 2024 15:19
@markriegler
Copy link
Collaborator Author

There are still some commits which do some unnecessary things (e.g. removing a function in one commit and later commit adds the same function again), but I tried to reduce the total number of commits.

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

Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between c83047c and b3f7da5.

Files selected for processing (2)
  • examples/iga/galerkin_laplace_problem_field_integrator.py (1 hunks)
  • splinepy/helpme/integrate.py (3 hunks)
Additional comments not posted (15)
examples/iga/galerkin_laplace_problem_field_integrator.py (6)

20-50: LGTM!

The function correctly defines and refines the geometry and solution field.


53-82: LGTM!

The function efficiently assembles the system matrix using numpy's einsum.


85-109: LGTM!

The function efficiently assembles the right-hand side vector using numpy's einsum.


112-119: LGTM!

The function correctly sets visualization options and displays the solution.


122-155: LGTM!

The main block correctly demonstrates the use of the FieldIntegrator class and its methods.


139-143: LGTM!

The Dirichlet boundary condition function is correctly defined.

splinepy/helpme/integrate.py (9)

13-58: LGTM!

The function correctly determines the integration measure based on spline dimensions.


61-68: LGTM!

The function efficiently calculates quadrature orders based on the spline's expected degree.


Line range hint 71-129: LGTM!

The function correctly calculates quadrature positions and weights.


132-167: LGTM!

The function correctly computes the volume of a spline using integration measures.


270-685: LGTM!

The Transformation class correctly computes supports, Jacobians, and quadrature points.


688-1263: LGTM!

The FieldIntegrator class correctly assembles the system matrix and right-hand side vector.


Line range hint 226-234: LGTM!

The function correctly raises a NotImplementedError for a placeholder.


Line range hint 236-268: LGTM!

The Integrator class correctly integrates values on a given spline geometry.


Line range hint 1-10: LGTM!

The imports and global variables are necessary and appropriately used.

splinepy/helpme/integrate.py Outdated Show resolved Hide resolved
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: 16

Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between b3f7da5 and 396430d.

Files selected for processing (1)
  • splinepy/helpme/integrate.py (3 hunks)
Additional comments not posted (2)
splinepy/helpme/integrate.py (2)

655-677: Enhance docstring for Transformation.compute_all_element_jacobian_determinants.

The method logic is correct, but the docstring could be more descriptive about the parameters.

        """

---

`61-69`: **Clarify the logic for determining quadrature orders.**

Add comments to explain the logic for determining quadrature orders.

```diff
def _default_quadrature_orders(spline):
    # Calculate the expected degree based on spline degrees and parametric dimension
    expected_degree = spline.degrees * spline.para_dim + 1
    if spline.is_rational:
        expected_degree += 2
        spline._logd("Integration on rational spline is only approximation")

    # Gauss-Legendre is exact for polynomials 2*n-1
    return _np.ceil((expected_degree + 1) * 0.5).astype("int")

Likely invalid or redundant comment.

splinepy/helpme/integrate.py Outdated Show resolved Hide resolved
splinepy/helpme/integrate.py Show resolved Hide resolved
splinepy/helpme/integrate.py Show resolved Hide resolved
splinepy/helpme/integrate.py Outdated Show resolved Hide resolved
splinepy/helpme/integrate.py Outdated Show resolved Hide resolved
splinepy/helpme/integrate.py Outdated Show resolved Hide resolved
splinepy/helpme/integrate.py Outdated Show resolved Hide resolved
splinepy/helpme/integrate.py Outdated Show resolved Hide resolved
splinepy/helpme/integrate.py Outdated Show resolved Hide resolved
splinepy/helpme/integrate.py Outdated Show resolved Hide resolved
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: 0

Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between 396430d and 4003315.

Files selected for processing (2)
  • examples/iga/galerkin_laplace_problem_field_integrator.py (1 hunks)
  • splinepy/helpme/integrate.py (3 hunks)
Additional comments not posted (27)
examples/iga/galerkin_laplace_problem_field_integrator.py (7)

1-10: LGTM!

The module-level docstring is well-written and provides necessary context for the code.


12-14: LGTM!

The import statements are necessary for the functionality of the code.


20-50: LGTM!

The function prepare_geometry_and_solution_field is well-structured and performs the necessary steps to prepare the geometry and solution field.


53-82: LGTM!

The function poisson_lhs is correctly implemented and the docstring provides clarity on its purpose and usage.


85-109: LGTM!

The function poisson_rhs is correctly implemented and the docstring provides clarity on its purpose and usage.


112-119: LGTM!

The function show_solution is correctly implemented and the docstring provides clarity on its purpose.


122-155: LGTM!

The main block is well-structured and demonstrates the usage of the FieldIntegrator class effectively.

splinepy/helpme/integrate.py (20)

13-59: LGTM!

The function correctly determines the appropriate measure for integration based on the spline's dimensions.


62-70: LGTM!

The function correctly calculates the expected degree and derives suitable quadrature orders.


Line range hint 73-135: LGTM!

The function correctly determines the integration points and weights for numerical integration based on the given spline and quadrature orders.


138-175: LGTM!

The function correctly computes the volume of a given spline using quadrature.


180-235: LGTM!

The function correctly integrates a user-defined function within the parametric domain.


Line range hint 236-242: LGTM!

The function correctly raises a NotImplementedError as it is not yet implemented.


Line range hint 244-278: LGTM!

The class correctly provides methods to integrate values on a given spline geometry.


281-368: LGTM!

The class correctly provides methods to compute supports, Jacobians, and quadrature points for elements within a patch.


369-379: LGTM!

The method correctly checks if the given element ID is valid.


381-385: LGTM!

The property correctly returns the supports of all quadrature points.


387-391: LGTM!

The property correctly returns the quadrature points of all elements.


393-397: LGTM!

The property correctly returns the Jacobians of all elements.


399-403: LGTM!

The property correctly returns the inverses of the Jacobians of all elements.


405-409: LGTM!

The property correctly returns the determinants of the Jacobians of all elements.


411-413: LGTM!

The property correctly returns the quadrature weights.


414-435: LGTM!

The method correctly computes the grid ID for a given element.


437-471: LGTM!

The method correctly computes the quadrature points for a given element.


473-495: LGTM!

The method correctly gets the support for quadrature points in a given element.


497-515: LGTM!

The method correctly returns the Jacobian of a single element at quadrature points.


517-541: LGTM!

The method correctly returns the inverse of the Jacobian of a single element at quadrature points.

@j042 j042 changed the base branch from main to develop September 3, 2024 12:03
@j042
Copy link
Member

j042 commented Sep 3, 2024

I think this should be rebased at 6e13284

Copy link
Member

@j042 j042 left a comment

Choose a reason for hiding this comment

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

Please solve rebase issues / bring it to a mergeable state. Let me know if you need help

Copy link
Member

@j042 j042 left a comment

Choose a reason for hiding this comment

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

isn't second mapping / scaling - parametric space to "parent element" - missing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants