Unstructured mesh-based geometry type
The unstructured mesh based geometry is a by-product of the unstructured mesh-based multi-physics interface. It can be used to create a geometry universe based on an unstructured mesh.
Contents
Input Syntax
The unstructured mesh based geometry can be created by using the solid 1 or solid 3 input card.
Geometry only (solid 1)
solid 1 UNI BGUNI MESH_SPLIT MESH_DIM SZ1 SZ2 ... SZMESH_DIM POINTS_FILE FACES_FILE OWNER_FILE NEIGHBOUR_FILE MATERIALS_FILE
The first solid type creates an unstructured mesh-based geometry universe. Input values are:
UNI | : universe name for the irregular geometry |
BGUNI | : name of the background universe filling all undefined space |
MESH_SPLIT | : Splitting criterion for the adaptive search mesh (maximum number of geometry cells in search mesh cell) |
MESH_DIM | : number of levels in the adaptive search mesh |
SZi | : Size of the search mesh at level i |
POINTS_FILE | : Path to the unstructured mesh points file |
FACES_FILE | : Path to the unstructured mesh faces file |
OWNER_FILE | : Path to the unstructured mesh owner file |
NEIGHBOUR_FILE | : Path to the unstructured mesh neighbour file |
MATERIALS_FILE | : Path to the unstructured mesh materials file |
Geometry and multi-physics data (solid 3)
solid 3 UNI BGUNI INTERFACE_FILE
It is also possible to create the geometry and bring in temperature and/or density data on the same mesh. In this case, most of the parameters are given in a separate multi-physics interface file which can be re-read by Serpent to update the fields between coupled calculation iterations. The input values in the main input file are:
UNI | : universe name for the irregular geometry |
BGUNI | : name of the background universe filling all undefined space |
POINTS_FILE | : Path to the interface file containing the rest of the parameters |
The input format of each of the linked files is based on the OpenFOAM file format.
Mesh structure/quality
The mesh can consist of arbitrary polygons as long as they can be entered in the OpenFOAM file-format and some quality requirements are met:
- The cells must be closed
- The cells must be convex (i.e. all face and body diagonals must be completely within the cell volume)
- Each face must have exactly one owner cell.
- Each face must have exactly one or zero neighbor cells.
Splitting of polyhedrons
Background
Serpent will do the final neutron tracking in a tetrahedral mesh, which is automatically generated by splitting other polyhedrons to tetrahedra. Tetrahedrons are used in the neutron tracking as each of their face surfaces is defined by three points (the vertices of the face) this is exactly the number of points required to uniquely define a plane. Since Serpent tests whether a point is inside a cell by testing whether it is on the correct side of each of the surfaces making up the cell, it is important that the surfaces bounding the cell are uniquely defined.
Faces with more than three points may not be entirely planar (either due to mesh generation/deformation) or limited numerical precision. To ensure that these kinds of faces are treated in the same way in both the owner cell and the neighbor cell the mesh is split into tetrahedrons before the neutron tracking.
Smart algorithm
Dumb algorithm
Debugging
Serpent automatically runs some basic tests for the mesh before and after it has been split to tetrahedra. Serpent tests that each face of the mesh is correctly owned by its owner and neighbored by its neighbor. Serpent also tests that the barycenter of each cell calculated by (in pseudocode)
Npoints = 0 for face in cell: for point in face: baryc.x += point.x baryc.y += point.y baryc.z += point.z Npoints++ baryc.x = baryc.x/Npoints baryc.y = baryc.y/Npoints baryc.z = baryc.z/Npoints
is inside the cell. All of the cells failing this test should be non-convex, but some non-convex cells might not be caught by this test.
When reading the unstructured mesh (geometry or interface), Serpent prints out the composition of the mesh:
Reading multi-physics interface "./ifc.new"... Composition of mesh: Tetrahedrons: 0 Pyramids: 0 Prisms: 0 Hexahedrons: 142400 Other polyhedrons: 0
After the initial mesh has been read into memory, Serpent runs the tests and prints out the results:
- Checked neighbority for 420776 surfaces, 0 failed - Checked that barycenter is inside tet for 142400 cells, 0 failed
Serpent will then divide the mesh to tetrahedra if needed and check the resulting mesh:
Dividing hexahedral mesh to tetrahedrons. Checking divided mesh. - Checked neighbority for 1695952 surfaces, 0 failed - Checked that barycenter is inside tet for 854400 cells, 0 failed
If any of the cells does not pass one of the tests, the simulation will be terminated:
Checking initial mesh: - Checked neighbority for 1698578 surfaces, 0 failed - Checked that barycenter is inside tet for 587520 cells, 15900 failed ***** Fri Feb 26 10:18:49 2016: - MPI task = 0 - OpenMP thread = 0 - RNG parent seed = 1456474723 Fatal error in function CheckPolyhedMesh: There were errors in the mesh Simulation aborted.
If the code is compiled in the DEBUG-mode, Serpent will print out warnings for the cells as they fail the tests (there may be a lot of output if many cells are failing):
F1 = [ -9.658312E-01 -2.508234E+00 -1.914149E+01; -1.009252E+00 -2.452564E+00 -1.914067E+01; -1.066138E+00 -2.408068E+00 -1.914106E+01; -9.617244E-01 -2.405420E+00 -1.914097E+01; ] F2 = [ -1.009035E+00 -2.452835E+00 -1.953164E+01; -9.658705E-01 -2.508183E+00 -1.953196E+01; -9.622982E-01 -2.404919E+00 -1.953140E+01; -1.068680E+00 -2.406116E+00 -1.953142E+01; ] F3 = [ -9.622982E-01 -2.404919E+00 -1.953140E+01; -9.617244E-01 -2.405420E+00 -1.914097E+01; -9.658312E-01 -2.508234E+00 -1.914149E+01; -9.658705E-01 -2.508183E+00 -1.953196E+01; ] F4 = [ -1.066138E+00 -2.408068E+00 -1.914106E+01; -9.617244E-01 -2.405420E+00 -1.914097E+01; -9.622982E-01 -2.404919E+00 -1.953140E+01; -1.068680E+00 -2.406116E+00 -1.953142E+01; ] F5 = [ -1.009035E+00 -2.452835E+00 -1.953164E+01; -9.658705E-01 -2.508183E+00 -1.953196E+01; -9.658312E-01 -2.508234E+00 -1.914149E+01; -1.009252E+00 -2.452564E+00 -1.914067E+01; ] F6 = [ -1.009035E+00 -2.452835E+00 -1.953164E+01; -1.009252E+00 -2.452564E+00 -1.914067E+01; -1.066138E+00 -2.408068E+00 1.914106E+01; -1.068680E+00 -2.406116E+00 -1.953142E+01; ] figure(); hold on; fill3(F1(:,1),F1(:,2),F1(:,3),ones(4,1)*1.000000); fill3(F2(:,1),F2(:,2),F2(:,3),ones(4,1)*0.916667); fill3(F3(:,1),F3(:,2),F3(:,3),ones(4,1)*-0.833333); fill3(F4(:,1),F4(:,2),F4(:,3),ones(4,1)*-0.750000); fill3(F5(:,1),F5(:,2),F5(:,3),ones(4,1)*-0.666667); fill3(F6(:,1),F6(:,2),F6(:,3),ones(4,1)*-0.583333); hold off; title('Cell 23229') Barycenter (-1.001104E+00 -2.443292E+00 -1.933633E+01) ***** Fri Feb 26 10:22:56 2016 (seed = 1456474964) Warning message from function CheckPolyhedMesh: Barycenter not inside cell 23229
As seen above, in case of a failed barycenter test, Serpent will print out the faces as MATLAB/Octave matrices as well as a script-snippet that can be used to plot the failed cell in MATLAB (fill3 is not implemented in Octave at the moment). With a bit of rotating and polishing we can get the plot shown here. The color of each face indicates whether the cell owns or is neighbour to the face. Blue faces are owned by the current cell, the current cell is a neighbor of the red faces. The coordinates of the barycenter are also printed so that the barycenter can be plotted to the figure. If the barycenter falls outside the face, the cell is convex (as is the case here). If the barycenter seems to fall inside the faces, there is most likely something wrong with the owner/neighborship or the ordering of points on one of the faces so that the intended inside of the cell is actually on the wrong side of one or multiple face surfaces.