-
Notifications
You must be signed in to change notification settings - Fork 14
Home
In this tutorial we are going to have a look at some of Florence's core functionality. To use Florence in your project, you typically add the following line at the top of your python scripts
from Florence import *
We are going to have a look at generating and preparing meshes in Florence for finite element analysis. Florence offers the possibility to define meshes on a set of predefined shapes/geometries. As of version 0.1.4, Florence supports 5 types of elements. In Florence's terminology these are
line
tri
quad
tet
hex
For instance, to create a mesh on a unit square domain, we simply define a Mesh
instance and call the Square
method on it, as follows
mesh = Mesh()
mesh.Square(nx=2, ny=2, element_type="quad")
This will create a quadrilateral mesh on a unit square domain with 4 elements. We can access the nodal coordinates and element connectivity of the mesh simply by
print(mesh.points)
print(mesh.elements)
For a more general rectangular shapes, we can define a Rectangle
mesh as follows
mesh = Mesh()
mesh.Rectangle(lower_left_point=(0,0), upper_right_point=(2,1), nx=20, ny=10, element_type="tri")
This will create a triangular mesh on the specified rectangular domain with 400 elements. Finally, if we want to mesh a quadrilateral region such as parallelogram, trapezium etc, we can call the generic and rather low level map mesher from Florence called QuadrilateralProjection
mesh = Mesh().QuadrilateralProjection(c1=(0,0), c2=(2,0), c3=(2,3), c4=(1,2), npoints=10)
This will map mesh all four sides of the quadrilateral domain using 10 elements. Other predefined shapes include (not limited to)
mesh.Circle(radius=2., nrad=10, ncirc=30)
mesh.Arc(start_angle=0, end_angle=PI/2., radius=2., nrad=10, ncirc=30)
# plate with a hole
mesh.CircularPlate(side_length=30, radius=10, center=(0.,0.), ncirc=5, nrad=5, element_type="tri")
Three-dimensional meshes can be generated in a similar fashion for instance
mesh.Cube(nx=10, ny=10, nz=10, element_type="hex")
mesh.Parallelepiped(lower_left_rear_point=(0,0,0), upper_right_front_point=(2,4,10),
nx=2, ny=4, nz=10, element_type="hex")
# for general 8 noded regions
mesh = Mesh().HexahedralProjection(c1=(0,0,0), c2=(2,0,0), c3=(2,2,0), c4=(0,2,0.),
c5=(0,1.8,3.), c6=(0.2,0,3.), c7=(2,0.2,3.), c8=(1.8,2,3.), npoints=6, equally_spaced=True)
mesh.Cylinder()
mesh.HollowCylinder()
mesh.Sphere()
Support for arbitrary order nodal Lagrange and Lagrange Gauss-Lobatto as well as modal hierarchic elements is available. For instance, to get a 4th order Lagrange element on any type of mesh, we can call the generic function
# 4th order Lagrange Gauss-Lobatto elements
mesh.GetHighOrderMesh(p=4)
# 4th order Lagrange elements
mesh.GetHighOrderMesh(p=4, equally_spaced=True)
Inquiring mesh edges/faces, boundary edges/faces is as simple as
all_edges = mesh.GetEdges()
boundary_edges = mesh.GetBoundaryEdges()
interior_edges = mesh.GetInteriorEdges()
all_faces = mesh.GetFaces()
boundary_faces = mesh.GetBoundaryFaces()
interior_faces = mesh.GetInteriorFaces()
Associativity of elements with edges/faces can also be enquired using
edge_to_element_map = mesh.GetElementsWithBoundaryEdges()
face_to_element_map = mesh.GetElementsWithBoundaryFaces()
Finding which nodes are shared between which elements can be done as follows
elements_sharing_nodes = mesh.GetNodeCommonality()
Uniform mesh refinement on all kinds of meshes is supported through the generic function Refine
mesh.Refine(level=3)
Mesh smoothing (or rather non-uniform refinement) based on a given criterion is also supported. For example, to smooth out all elements with aspect ratio 2 and above we can do
mesh.Smooth(criteria={'aspect_ratio':2})
Low and high order meshes can be partitioned for parallel processing using the built-in Partition
call
partioned_mesh, partitioned_element_indices, partitioned_nodes_indices = mesh.Partition(n=12)
Low and high order meshes can be cut through using either the RemoveElements
or GetLocalisedMesh
functions
# geometric cuts
new_mesh = mesh.RemoveElements(xyz_min_max_array)
# algebraic cuts
new_mesh = mesh.GetLocalisedMesh(elements_indices_to_remove)
Meshes can be merged together simply through the +
, -
calls
mesh = Mesh().Square() + Mesh().Square(lower_left_point=(1,0))
The Mesh
class of Florence supports reading meshes written in different formats such as Gmsh (.msh
), .obj
, GID, Salome, FRO, HDF5 etc
mesh.ReadGmsh("mesh_file_name.msh", element_type="tet")
mesh.ReadOBJ("mesh_file_name.obj", element_type="tri")
# or simply call
mesh.Read(filename, reader_type="gmsh", element_type="tet")