diff --git a/sectionproperties/analysis/section.py b/sectionproperties/analysis/section.py index 286230e2..2191812d 100644 --- a/sectionproperties/analysis/section.py +++ b/sectionproperties/analysis/section.py @@ -1313,7 +1313,7 @@ def plot_mesh( :param mask: Mask array, of length ``num_nodes``, to mask out triangles :type mask: list[bool] :param string title: Plot title - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -1408,7 +1408,7 @@ def plot_centroids(self, title="Centroids", **kwargs): axis, if they have been calculated, on top of the finite element mesh. :param string title: Plot title - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -2592,7 +2592,7 @@ def plot_stress_contour(self, sigs, title, cmap, normalize, **kwargs): :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axe object :rtype: :class:`matplotlib.axes` @@ -2658,7 +2658,7 @@ def plot_stress_vector(self, sigxs, sigys, title, cmap, normalize, **kwargs): :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -2872,7 +2872,7 @@ def plot_stress_n_zz( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -2921,7 +2921,7 @@ def plot_stress_mxx_zz( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -2970,7 +2970,7 @@ def plot_stress_myy_zz( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -3019,7 +3019,7 @@ def plot_stress_m11_zz( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -3068,7 +3068,7 @@ def plot_stress_m22_zz( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -3117,7 +3117,7 @@ def plot_stress_m_zz( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -3167,7 +3167,7 @@ def plot_stress_mzz_zx( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -3216,7 +3216,7 @@ def plot_stress_mzz_zy( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -3265,7 +3265,7 @@ def plot_stress_mzz_zxy( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -3314,7 +3314,7 @@ def plot_vector_mzz_zxy( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -3365,7 +3365,7 @@ def plot_stress_vx_zx( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -3414,7 +3414,7 @@ def plot_stress_vx_zy( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -3463,7 +3463,7 @@ def plot_stress_vx_zxy( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -3513,7 +3513,7 @@ def plot_vector_vx_zxy( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -3564,7 +3564,7 @@ def plot_stress_vy_zx( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -3613,7 +3613,7 @@ def plot_stress_vy_zy( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -3662,7 +3662,7 @@ def plot_stress_vy_zxy( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -3711,7 +3711,7 @@ def plot_vector_vy_zxy( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -3763,7 +3763,7 @@ def plot_stress_v_zx( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -3814,7 +3814,7 @@ def plot_stress_v_zy( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -3865,7 +3865,7 @@ def plot_stress_v_zxy( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -3916,7 +3916,7 @@ def plot_vector_v_zxy( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -3968,7 +3968,7 @@ def plot_stress_zz( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -4018,7 +4018,7 @@ def plot_stress_zx( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -4068,7 +4068,7 @@ def plot_stress_zy( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -4118,7 +4118,7 @@ def plot_stress_zxy( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -4168,7 +4168,7 @@ def plot_vector_zxy( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -4220,7 +4220,7 @@ def plot_stress_1( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -4280,7 +4280,7 @@ def plot_stress_3( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -4340,7 +4340,7 @@ def plot_stress_vm( :param string cmap: Matplotlib color map. :param bool normalize: If set to true, the CenteredNorm is used to scale the colormap. If set to false, the default linear scaling is used. - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -4392,7 +4392,7 @@ def plot_mohrs_circles(self, x, y, title=None, **kwargs): :param float x: x-coordinate of the point to draw Mohr's Circle :param float y: y-coordinate of the point to draw Mohr's Circle :param string title: Plot title - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` diff --git a/sectionproperties/post/post.py b/sectionproperties/post/post.py index 1716b096..49b01886 100644 --- a/sectionproperties/post/post.py +++ b/sectionproperties/post/post.py @@ -25,7 +25,7 @@ def plotting_context( This may be a tuple if a 2D array of plots is returned. The default value of None will select the top left plot. :type axis_index: Union[None, int, Tuple(int)] - :param \**kwargs: Passed to :func:`matplotlib.pyplot.subplots` + :param kwargs: Passed to :func:`matplotlib.pyplot.subplots` """ if filename: diff --git a/sectionproperties/pre/geometry.py b/sectionproperties/pre/geometry.py index 91f57aec..5b39cdc3 100644 --- a/sectionproperties/pre/geometry.py +++ b/sectionproperties/pre/geometry.py @@ -144,10 +144,10 @@ def from_points( being holes or voids. The point can be located anywhere within the hole region. Only one point is required per hole region. :vartype holes: list[list[float, float]] - :cvar materials: Optional. A list of :class:`~sectionproperties.pre.pre.Material` objects that are to be - assigned, in order, to the regions defined by the given control_points. If not given, then - the :class:`~sectionproperties.pre.pre.DEFAULT_MATERIAL` will be used for each region. - :vartype materials: list[:class:`~sectionproperties.pre.pre.Material`] + :cvar material: Optional. A :class:`~sectionproperties.pre.pre.Material` object + that is to be assigned. If not given, then the + :class:`~sectionproperties.pre.pre.DEFAULT_MATERIAL` will be used. + :vartype materials: :class:`~sectionproperties.pre.pre.Material` """ if len(control_points) != 1: raise ValueError( @@ -225,7 +225,7 @@ def from_3dm(cls, filepath: Union[str, pathlib.Path], **kwargs) -> Geometry: :param filepath: File path to the rhino `.3dm` file. :type filepath: Union[str, pathlib.Path] - :param \**kwargs: + :param kwargs: See below. :raises RuntimeError: A RuntimeError is raised if two or more polygons are found. @@ -290,7 +290,7 @@ def from_rhino_encoding(cls, r3dm_brep: str, **kwargs) -> Geometry: :param r3dm_brep: A Rhino3dm.Brep encoded as a string. :type r3dm_brep: str - :param \**kwargs: + :param kwargs: See below. :return: A Geometry object found in the encoded string. @@ -871,7 +871,7 @@ def plot_geometry( to indicate no labels. Default is ["control_points"] :type labels: list[str] :param string title: Plot title - :param \**kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` + :param kwargs: Passed to :func:`~sectionproperties.post.post.plotting_context` :return: Matplotlib axes object :rtype: :class:`matplotlib.axes` @@ -1242,6 +1242,13 @@ def from_points( ) if holes is None: holes = list() + if materials is not pre.DEFAULT_MATERIAL: + if len(materials) != len(control_points): + raise ValueError( + f"If materials are provided, the number of materials in the list must " + "match the number of control_points provided.\n" + f"len(materials)=={len(materials)}, len(control_points)=={len(control_points)}." + ) # First, generate all invidual polygons from points and facets current_polygon_points = [] @@ -1297,17 +1304,34 @@ def from_points( f"does not match the number of control_points given ({len(control_points)})." ) if not interiors: - return CompoundGeometry( - [ - Geometry(exterior, control_points=control_points[idx]) - for idx, exterior in enumerate(exteriors) - ] - ) + if materials is pre.DEFAULT_MATERIAL: + return CompoundGeometry( + [ + Geometry( + exterior, + control_points=control_points[idx], + material=materials, + ) + for idx, exterior in enumerate(exteriors) + ] + ) + else: + return CompoundGeometry( + [ + Geometry( + exterior, + control_points=control_points[idx], + material=materials[idx], + ) + for idx, exterior in enumerate(exteriors) + ] + ) + else: # "Punch" all holes through each exterior geometry punched_exteriors = [] punched_exterior_geometries = [] - for exterior in exteriors: + for idx, exterior in enumerate(exteriors): punched_exterior = exterior for interior in interiors: punched_exterior = punched_exterior - interior @@ -1322,12 +1346,25 @@ def from_points( f"Control points given are not contained within the geometry" f" once holes are subtracted: {control_points}" ) - exterior_geometry = Geometry( - punched_exterior, control_points=exterior_control_point - ) - punched_exterior_geometries.append(exterior_geometry) + if materials is pre.DEFAULT_MATERIAL: + + exterior_geometry = Geometry( + punched_exterior, + control_points=exterior_control_point, + material=materials, + ) + punched_exterior_geometries.append(exterior_geometry) + + else: + + exterior_geometry = Geometry( + punched_exterior, + control_points=exterior_control_point, + material=materials[idx], + ) + punched_exterior_geometries.append(exterior_geometry) - return CompoundGeometry(punched_exterior_geometries) + return CompoundGeometry(punched_exterior_geometries) @classmethod def from_3dm(cls, filepath: Union[str, pathlib.Path], **kwargs) -> CompoundGeometry: @@ -1336,7 +1373,7 @@ def from_3dm(cls, filepath: Union[str, pathlib.Path], **kwargs) -> CompoundGeome :param filepath: File path to the rhino `.3dm` file. :type filepath: Union[str, pathlib.Path] - :param \**kwargs: + :param kwargs: See below. :return: A `CompoundGeometry` object. diff --git a/sectionproperties/pre/rhino.py b/sectionproperties/pre/rhino.py index a1043d83..8d0a855a 100644 --- a/sectionproperties/pre/rhino.py +++ b/sectionproperties/pre/rhino.py @@ -10,7 +10,7 @@ def load_3dm(r3dm_filepath: Union[pathlib.Path, str], **kwargs) -> List[Polygon] :param r3dm_filepath: File path to the rhino `.3dm` file. :type r3dm_filepath: pathlib.Path or string - :param \**kwargs: + :param kwargs: See below. :raises RuntimeError: A RuntimeError is raised if no polygons are found in the file. @@ -64,7 +64,7 @@ def load_brep_encoding(brep: str, **kwargs) -> Polygon: :param brep: Rhino3dm.Brep encoded as a string. :type brep: str - :param \**kwargs: + :param kwargs: See below. :raises RuntimeError: A RuntimeError is raised if no polygons are found in the encoding. diff --git a/sectionproperties/tests/test_sections.py b/sectionproperties/tests/test_sections.py index a3b9a379..02ad843d 100644 --- a/sectionproperties/tests/test_sections.py +++ b/sectionproperties/tests/test_sections.py @@ -118,13 +118,26 @@ def test_geometry_from_points(): ] control_points = [[0, 0]] holes = [[0, 6], [0, -6]] + material = Material( + name="mat1", + elastic_modulus=2, + poissons_ratio=0.3, + density=1e-6, + yield_strength=5, + color="grey", + ) new_geom = Geometry.from_points( - points=points, facets=facets, control_points=control_points, holes=holes + points=points, + facets=facets, + control_points=control_points, + holes=holes, + material=material, ) wkt_test_geom = shapely.wkt.loads( "POLYGON ((6 10, 6 -10, -6 -10, -6 10, 6 10), (-4 4, 4 4, 4 8, -4 8, -4 4), (4 -8, 4 -4, -4 -4, -4 -8, 4 -8))" ) assert (new_geom.geom - wkt_test_geom) == Polygon() + assert (new_geom.material) == material def test_compound_geometry_from_points(): @@ -162,12 +175,35 @@ def test_compound_geometry_from_points(): [9, 6], ] control_points = [[0, 0], [0, -2 * a - t / 2]] - new_geom = CompoundGeometry.from_points(points, facets, control_points) + mat1 = Material( + name="mat1", + elastic_modulus=2, + poissons_ratio=0.3, + density=1e-6, + yield_strength=5, + color="grey", + ) + mat2 = Material( + name="mat2", + elastic_modulus=5, + poissons_ratio=0.2, + density=2e-6, + yield_strength=10, + color="blue", + ) + materials = [mat1, mat2] + new_geom = CompoundGeometry.from_points( + points, facets, control_points, materials=materials + ) wkt_test_geom = shapely.wkt.loads( "MULTIPOLYGON (((-0.05 -2, 0.05 -2, 0.05 -0.05, 1 -0.05, 1 0.05, -0.05 0.05, -0.05 -2)), ((-1 -2, 1 -2, 1 -2.1, -1 -2.1, -1 -2)))" ) assert (new_geom.geom - wkt_test_geom) == Polygon() + # test materials + for idx, geom in enumerate(new_geom.geoms): + assert geom.material == materials[idx] + def test_multi_nested_compound_geometry_from_points(): """ @@ -215,8 +251,37 @@ def test_multi_nested_compound_geometry_from_points(): ] control_points = [[-43.75, 0.0], [-31.25, 0.0], [-18.75, 0.0]] holes = [[0, 0]] + mat1 = Material( + name="mat1", + elastic_modulus=2, + poissons_ratio=0.3, + density=1e-6, + yield_strength=5, + color="grey", + ) + mat2 = Material( + name="mat2", + elastic_modulus=5, + poissons_ratio=0.2, + density=2e-6, + yield_strength=10, + color="blue", + ) + mat3 = Material( + name="mat3", + elastic_modulus=1, + poissons_ratio=0.25, + density=1.5e-6, + yield_strength=3, + color="green", + ) + materials = [mat1, mat2, mat3] nested_compound = CompoundGeometry.from_points( - points=points, facets=facets, control_points=control_points, holes=holes + points=points, + facets=facets, + control_points=control_points, + holes=holes, + materials=materials, ) wkt_test_geom = shapely.wkt.loads( "MULTIPOLYGON (((50 50, 50 -50, -50 -50, -50 50, 50 50), (12.5 12.5, -12.5 12.5, -12.5 -12.5, 12.5 -12.5, 12.5 12.5)), ((-37.5 -37.5, -37.5 37.5, 37.5 37.5, 37.5 -37.5, -37.5 -37.5), (12.5 12.5, -12.5 12.5, -12.5 -12.5, 12.5 -12.5, 12.5 12.5)), ((-25 -25, -25 25, 25 25, 25 -25, -25 -25), (12.5 12.5, -12.5 12.5, -12.5 -12.5, 12.5 -12.5, 12.5 12.5)))" @@ -230,6 +295,10 @@ def test_multi_nested_compound_geometry_from_points(): ] assert nested_compound.holes == [(0, 0)] + # test materials + for idx, geom in enumerate(nested_compound.geoms): + assert geom.material == materials[idx] + # Section contains overlapping geometries which will result in potentially incorrect # plastic properties calculation (depends on user intent and geometry). # Test to ensure a warning is raised about this to notify the user.