DiscreteGeometry sample boundary and interior with parameter subset

Took me a bit to figure this out with my own code, but I replicated it with the ‘parameterized_tesselated_example.py’ file from the examples.

When you try to sample with any a subset of parameters, similar to what is done in the three_fin example for monitors, you get the following error:

Traceback (most recent call last):
  File "parameterized_tesselated_example.py", line 47, in <module>
    s = geo.sample_boundary(nr_points=1000000, parameterization = subset_ranges)
  File "/modulus/modulus/geometry/geometry.py", line 474, in sample_boundary
    [
  File "/modulus/modulus/geometry/geometry.py", line 475, in <listcomp>
    curve.approx_area(parameterization, criteria=closed_boundary_criteria)
  File "/modulus/modulus/geometry/curve.py", line 134, in approx_area
    computed_criteria = criteria(s, p)
  File "/modulus/modulus/geometry/geometry.py", line 466, in boundary_criteria
    return self.boundary_criteria(invar, criteria=criteria, params=params)
  File "/modulus/modulus/geometry/geometry.py", line 387, in boundary_criteria
    sdf_normal_plus = self.sdf(
  File "/modulus/modulus/geometry/discrete_geometry.py", line 59, in sdf
    computed_sdf = f(
  File "/modulus/modulus/geometry/tessellation.py", line 115, in sdf
    minx, maxx, miny, maxy, minz, maxz = _find_mins_maxs(points)
  File "/modulus/modulus/geometry/tessellation.py", line 251, in _find_mins_maxs
    minx = float(np.min(points[:, 0]))
  File "<__array_function__ internals>", line 180, in amin
  File "/opt/conda/lib/python3.8/site-packages/numpy/core/fromnumeric.py", line 2916, in amin
    return _wrapreduction(a, np.minimum, 'min', axis, None, out,
  File "/opt/conda/lib/python3.8/site-packages/numpy/core/fromnumeric.py", line 86, in _wrapreduction
    return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
ValueError: zero-size array to reduction operation minimum which has no identity

Here is my modified version of the example file which replicates the problem:

import glob
import numpy as np

from modulus.geometry.tessellation import Tessellation
from modulus.geometry.discrete_geometry import DiscreteGeometry
from modulus.utils.io.vtk import var_to_polyvtk
from modulus.geometry.parameterization import Parameterization, Parameter

if __name__ == "__main__":
    # make geometry for each bracket
    bracket_files = glob.glob("./bracket_stl/*.stl")
    bracket_files.sort()
    brackets = []
    radius = []
    width = []
    for f in bracket_files:
        # get param values
        radius.append(float(f.split("_")[3]))
        width.append(float(f.split("_")[5][:-4]))

        # make geometry
        brackets.append(Tessellation.from_stl(f))

    # make discretely parameterized geometry
    parameterization = Parameterization(
        {
            Parameter("radius"): np.array(radius)[:, None],
            Parameter("width"): np.array(width)[:, None],
        }
    )

    subset_ranges = {
        Parameter("radius"): 0.2,
        Parameter("width"):1.0
    }
    geo = DiscreteGeometry(brackets, parameterization)

    print(parameterization)
    print(subset_ranges)

    # sample geometry over entire parameter range
    s = geo.sample_boundary(nr_points=1000000)
    var_to_polyvtk(s, "parameterized_bracket_boundary")
    s = geo.sample_interior(nr_points=1000000)
    var_to_polyvtk(s, "parameterized_bracket_interior")

    s = geo.sample_boundary(nr_points=1000000, parameterization = subset_ranges)
    var_to_polyvtk(s, "subset_sample")

I tried this one, a version that makes a secondary parameter set based on the first:

parameterization = Parameterization(
        {
            Parameter("radius"): np.array([[radius[0]]]),
            Parameter("width"): np.array([[width[0]]]),
        }
    )

and multiple other versions to test how I structured the input, but I keep getting the same error.

Let me know if you need any other information

*Edit: There is a workaround… it is to sample the entire discrete geometry range and then filter the returned values

Hi @patterson

Thank you for the report as well as the minimal working example! We appreciate it! I’ll get this added to our back log. Another potential solution would be to create a separate geometry object for the subset that only has the files that you’re interested in.

Thanks.