Repository: adtzlr/felupe

Issue:
Throw error if one wants to create a region on a container.

Discussion:

Solution patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3f682575..1bbf3676 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file. The format
 - Add a new argument to apply a callable on the assembled vector/matrix of a solid body, `SolidBody(..., apply=None)`. This may be used to sum the list of sub-blocks instead of stacking them together, `SolidBody(..., block=False, apply=None)`. This is useful for mixed formulations where both the deformation gradient and the displacement values are required.
 - Add support for non-symmetric bilinear mixed forms in `IntegralForm`.
 - Add `element.Element` to the top-level package namespace.
+- Raise a TypeError if a mesh container is used as the `mesh`-argument in a region. The error message explains that the container is not supported. A mesh must be used instead.
 
 ### Changed
 - The first Piola-Kirchhoff stress tensor is evaluated if `ViewSolid(stress_type=None)`.
diff --git a/src/felupe/region/_region.py b/src/felupe/region/_region.py
index 6f4de780..71ba0842 100644
--- a/src/felupe/region/_region.py
+++ b/src/felupe/region/_region.py
@@ -310,6 +310,12 @@ class Region:
         region = self
 
         if mesh is not None:
+
+            if "container" in type(mesh).__name__.lower():
+                raise TypeError(
+                    "A mesh container is not supported by a region, use a mesh instead."
+                )
+
             region.mesh = mesh
 
         if element is not None:
diff --git a/src/felupe/region/_templates.py b/src/felupe/region/_templates.py
index a316fdc4..3cdac385 100644
--- a/src/felupe/region/_templates.py
+++ b/src/felupe/region/_templates.py
@@ -82,6 +82,11 @@ class RegionQuad(Region):
     def __init__(
         self, mesh, quadrature=GaussLegendre(order=1, dim=2), grad=True, **kwargs
     ):
+        if "container" in type(mesh).__name__.lower():
+            raise TypeError(
+                "A mesh container is not supported by a region, use a mesh instead."
+            )
+
         element = Quad()
 
         if len(mesh.cells.T) > 4:
@@ -117,6 +122,11 @@ class RegionQuadraticQuad(Region):
     def __init__(
         self, mesh, quadrature=GaussLegendre(order=2, dim=2), grad=True, **kwargs
     ):
+        if "container" in type(mesh).__name__.lower():
+            raise TypeError(
+                "A mesh container is not supported by a region, use a mesh instead."
+            )
+
         element = QuadraticQuad()
 
         if len(mesh.cells.T) > 8:
@@ -358,6 +368,11 @@ class RegionHexahedron(Region):
     def __init__(
         self, mesh, quadrature=GaussLegendre(order=1, dim=3), grad=True, **kwargs
     ):
+        if "container" in type(mesh).__name__.lower():
+            raise TypeError(
+                "A mesh container is not supported by a region, use a mesh instead."
+            )
+
         element = Hexahedron()
 
         if len(mesh.cells.T) > 8:
@@ -443,6 +458,11 @@ class RegionQuadraticHexahedron(Region):
     def __init__(
         self, mesh, quadrature=GaussLegendre(order=2, dim=3), grad=True, **kwargs
     ):
+        if "container" in type(mesh).__name__.lower():
+            raise TypeError(
+                "A mesh container is not supported by a region, use a mesh instead."
+            )
+
         element = QuadraticHexahedron()
 
         if len(mesh.cells.T) > 20:
@@ -647,6 +667,11 @@ class RegionTriangle(Region):
     def __init__(
         self, mesh, quadrature=TriangleQuadrature(order=1), grad=True, **kwargs
     ):
+        if "container" in type(mesh).__name__.lower():
+            raise TypeError(
+                "A mesh container is not supported by a region, use a mesh instead."
+            )
+
         element = Triangle()
 
         if len(mesh.cells.T) > 3:
@@ -682,6 +707,11 @@ class RegionTetra(Region):
     """
 
     def __init__(self, mesh, quadrature=TetraQuadrature(order=1), grad=True, **kwargs):
+        if "container" in type(mesh).__name__.lower():
+            raise TypeError(
+                "A mesh container is not supported by a region, use a mesh instead."
+            )
+
         element = Tetra()
 
         if len(mesh.cells.T) > 4:


Test patch:
diff --git a/tests/test_region.py b/tests/test_region.py
index 93b1ccb1..b0cd7180 100644
--- a/tests/test_region.py
+++ b/tests/test_region.py
@@ -175,6 +175,40 @@ def test_region_negative_volumes_cells():
         region = fem.RegionQuad(mesh)
 
 
+def test_container_warning():
+
+    mesh = fem.MeshContainer([fem.Rectangle()])
+    element = fem.Quad()
+    quadrature = fem.GaussLegendre(order=1, dim=2)
+    with pytest.raises(TypeError):
+        region = fem.Region(mesh, element, quadrature)
+
+    mesh = fem.MeshContainer([fem.Rectangle()])
+    with pytest.raises(TypeError):
+        region = fem.RegionQuad(mesh)
+
+    mesh = fem.MeshContainer([fem.Rectangle().add_midpoints_edges()])
+    with pytest.raises(TypeError):
+        region = fem.RegionQuadraticQuad(mesh)
+
+    mesh = fem.MeshContainer([fem.Rectangle().triangulate()])
+    with pytest.raises(TypeError):
+        region = fem.RegionTriangle(mesh)
+
+    mesh = fem.MeshContainer([fem.Cube()])
+    with pytest.raises(TypeError):
+        region = fem.RegionHexahedron(mesh)
+
+    mesh = fem.MeshContainer([fem.Cube().add_midpoints_edges()])
+    with pytest.raises(TypeError):
+        region = fem.RegionQuadraticHexahedron(mesh)
+
+    mesh = fem.MeshContainer([fem.Cube().triangulate()])
+    with pytest.raises(TypeError):
+        region = fem.RegionTetra(mesh)
+
+
 if __name__ == "__main__":
     test_region()
     test_region_negative_volumes_cells()
+    test_container_warning()