1. Introduction
Computational Fluid Dynamics (CFD) is increasingly applied in various engineering fields, including aerospace, rail transportation, and construction. As these applications involve increasingly complex geometries and flow fields—such as aircraft [
1], high-speed train bogies and pantographs [
2], and bridges [
3]—the challenges of mesh generation are becoming more pronounced. As a fundamental component of the CFD process, mesh generation plays a critical role, with its robustness, efficiency, and memory usage directly affecting the accuracy and effectiveness of numerical simulations for complex configurations and flow scenarios.
Compared to conventional structured and unstructured meshes, Cartesian grids offer several advantages, including high automation [
4,
5], excellent adaptability to complex configurations [
6,
7], and effective capture of flow field structures [
8,
9,
10]. These benefits make Cartesian grids especially useful for simulating complex geometries, drawing significant interest from researchers [
11,
12,
13,
14,
15,
16]. Conventional mesh generation methods involve creating spatial grids that conform to the object’s surface boundaries, typically dividing the process into generating surface and spatial meshes, as shown in
Figure 1a,b. In contrast, Cartesian grids are generated directly without relying on surface meshes, resulting in a more streamlined generation process. However, this approach necessitates determining the spatial relationship between the object surface and Cartesian grids, as shown in
Figure 1c. Consequently, the robustness, efficiency, and memory usage of Cartesian grid generation critically depend on three core components: the surface mesh data structure, the Cartesian grid data structure, and the method for determining their positional relationship.
Surface meshes are typically represented using discrete triangles, which presents a key challenge in generating Cartesian grids: efficiently reading and storing triangle details using an appropriate data structure. The subsequent tasks—such as determining the Cartesian cell type, calculating wall distances, and reconstructing wall flow variables—depend heavily on effectively retrieving and utilizing triangular information. The efficiency of these processes is closely linked to the data structure used for triangles, which directly impacts both Cartesian grid generation and flow field computation. Therefore, developing a well-designed and efficient data structure for triangles is crucial for enhancing the performance of both Cartesian grid generation and flow field computation. The most common method involves sequentially storing triangle information in an array and using a traversal query to retrieve target triangles. This approach is straightforward, easy to implement, and accurate. When the number of surface triangles is small, the computational cost remains affordable. However, for complex 3D configurations or flows, the number of triangles can reach O (10
5) to O (10
6), while the number of the Cartesian cells may soar to O (10
8) to O (10
9). The traversal retrieval method can lead to a computational load of O (10
13) to O (10
15), imposing significant demands on the overall computation source. Identifying that many triangles may not be relevant for the current calculations allows for optimizations; hence, there is no need to compute them. To address this issue, Bonet and Peraire [
17] proposed using the Alternating Digital Tree (ADT) to store triangles, significantly improving computational efficiency and making it one of the most popular methods for managing surface mesh data [
18]. The ADT abstracts each specific research object through a unique definition that does not depend on the object details, organizing each object within a binary tree structure. Moreover, the ADT cleverly introduces a mapping that extends finite-sized research objects in D-dimensional space to points in 2D space, thereby simplifying the problem of finding intersections between finite-sized objects to locating points within a target area [
19]. This enables the rapid elimination of non-target triangles during intersection checks between Cartesian cells and triangles. However, the ADT constructs the binary tree by alternately splitting the search space along the x, y, and z axes, which makes the tree structure highly dependent on the geometric complexity and the distribution density of triangles. This results in an imbalanced binary tree, ultimately leading to unstable efficiency when retrieving triangle information. Therefore, there remains a critical need to develop an efficient surface mesh data structure that can consistently enhance performance across various scenarios.
For Cartesian grids, the data structure not only stores grid information but also provides a logical framework for accessing and modifying that information. An efficient data structure can thus significantly reduce memory usage, facilitate adaptive processes, and enhance the mesh generation efficiency. Common Cartesian grid data structures include unstructured and tree-based methods. Unstructured data structures do not use hierarchical information to infer grid topology. While this method offers flexibility, it requires establishing a vertex-edge-face-cell mapping to ensure unique topological relationships between cells [
20]. This complexity results in intricate program implementation and high memory overhead, with each Cartesian cell typically occupying around 30 to 100 words of storage space [
21]. Tree-based data structures have long been the mainstream method for hierarchical storage [
22,
23,
24,
25,
26]. In a tree structure, access paths between layers are established using pointers. This compact format provides nearly all grid connectivity information, and the scalability of leaf nodes facilitates easier adaptation. However, tree-based data structures still exhibit notable shortcomings in two key areas. On the one hand, they tend to consume excessive memory. Since the size of the tree is unknown at compile time, null pointers must be allocated for each leaf node to accommodate future dynamic refinement or coarsening based on geometric or flow field changes. This leads to significant memory wastage, particularly in Cartesian grids, where the majority of cells are leaf nodes, resulting in substantial memory inefficiencies due to numerous idle null pointers. On the other hand, there is instability in neighbor query efficiency. When querying two adjacent Cartesian cells, the path needed for the query can vary depending on their relative positions in the tree, potentially requiring one or more traversals and, in the worst case, even backtracking to the root node. Therefore, further optimization of the tree structure is essential to reduce memory usage and improve neighbor query efficiency.
After reading and storing the geometric surface triangles and generating the initial uniform Cartesian grid, the next step is to determine the positional relationship between the Cartesian grid and the object surface. The accuracy of this determination is crucial for the success of grid generation and flow field calculations, while the efficiency of the process is a core factor impacting the overall performance of grid generation. Various methods exist for determining the positional relationship between the Cartesian grid and the surface. Conventional approaches include the winding number method [
27] and the ray tracing method [
28,
29,
30]. The winding number method calculates the sum of angles formed by traversing the boundary of a closed object from the perspective of a test point. If the sum is zero, the point is outside the object; otherwise, it is considered inside. However, this method is less commonly used in practice due to two main drawbacks: it involves numerous small-angle floating-point calculations that can introduce rounding errors, and it requires traversing each edge or face, leading to high computational costs. In contrast, the ray tracing method is widely adopted due to its simplicity and ease of implementation. This method casts a ray from the point in question and determines its position relative to the surface based on the number of intersection points. An even number of intersections indicates the point is outside, while an odd number suggests it is inside. However, ray tracing can sometimes misclassify points due to floating-point calculation errors, resulting in external points being classified as internal, and vice versa. To mitigate the impact of these errors, Capizzano [
20] introduced a small threshold value, η. When the result falls below this threshold, an additional ray is cast for further evaluation. While this approach enhances accuracy, it struggles with robustness, particularly for complex geometric shapes. Furthermore, to assess whether a Cartesian cell intersects with the object surface, all eight vertices must be checked. This requirement significantly reduces the efficiency of the ray tracing method, negatively affecting the overall computation cycle and complicating the demands of intricate 3D geometric and flow field calculations. Therefore, there is a pressing need to develop methods for determining the relative position between Cartesian grids and surfaces that effectively address robustness and efficiency.
In summary, this paper is oriented to complex 3D configurations, focusing on the three objectives of Cartesian mesh generation: high robustness, high efficiency, and low memory consumption. Starting from the three core aspects of Cartesian mesh generation, the surface mesh data structure, Cartesian grid data structure, and the method for determining the positional relationship between Cartesian cells and triangles, this paper analyses the reasons for the defects of the conventional method and puts forward improvement measures to develop a reasonable Cartesian mesh generation method. Building on this foundation, it evaluates the robustness, efficiency, and memory consumption of the proposed method qualitatively and quantitatively, comparing it with conventional approaches to highlight its advantages.
2. Surface Mesh Data Structure Based on Nested Bounding Boxes
To address the imbalance issues commonly associated with conventional ADT data structure, this paper proposes a method for constructing binary trees by splitting along the dimension with the maximum variance, rather than alternating between the x, y, and z axes. The data is sorted along this dimension, and the media position is used to split the data into two parts, corresponding to the left and right nodes of the binary tree. This approach ensures that both the splitting dimension and the splitting position are optimal, resulting in a well-balanced binary tree. Algorithm 1 lists the pseudocode for constructing a binary tree, where Ntri denotes the current number of triangles.
Algorithm 1: Construct the binary tree |
1: | If (Ntri = 1) then |
2: | Allocate (TreeNode % Tri) |
3: | TreeNode % Tri = The last triangle |
4: | TreeNode % Left => Null () |
5: | TreeNode % Right => Null () |
6: | Else if (Ntri = 2) then |
7: | Allocate (TreeNode % Tri) |
8: | TreeNode % Tri = The first triangle |
9: | TreeNode % Splitaxis = x-direction |
10: | If (x-coordinate of the first triangle > x-coordinate of the second triangle) then |
11: | TreeNode % Left => The second triangle |
12: | TreeNode % Right => Null () |
13: | Else |
14: | TreeNode % Left => Null () |
15: | TreeNode % Right => The second triangle |
16: |
Endif |
17: | Else |
18: | Call Find the direction of greatest discrete |
19: | TreeNode % Splitaxis = The direction of greatest discrete |
20: | Call Sort under Splitaxis |
21: | TreeNode % Tri = The median triangle |
22: | TreeNode % Left => Smaller coordinate than that of the median triangle |
23: | TreeNode % Right => Larger coordinate than that of the median triangle |
24: | Endif |
Additionally, this paper introduces an approach to spatial partitioning by storing all vertex information of triangles while constructing a binary tree. By doing so, we can create a bounding box for each tree node, representing the smallest rectangular space enclosing all triangles associated with that node. During the spatial partitioning process, these bounding boxes are divided concurrently. It is important to highlight that the bounding box for each tree node encapsulates all triangles within its spatial region, while the partitioning itself is based on planes determined by triangle centroids. This results in overlapping regions between the partitioning planes and the bounding boxes of both the left and right child nodes, as illustrated in
Figure 2a. Additionally, nesting occurs between the bounding boxes of parent and child nodes, as shown in
Figure 2b. Therefore, we refer to the constructed binary tree as the Binary Tree based on Nested Bounding Boxes (BT-NBB). This binary tree form proposed in this paper can be used to determine the spatial relationship between Cartesian cells and surface triangles, accurately excluding triangles that do not intersect with the target Cartesian cell, enhancing the robustness of the judgment. Further applications of this nested bounding box format will be elaborated in
Section 4.1.
To demonstrate the balance and efficiency of the binary tree constructed using the present method, we partition a two-dimensional space containing 17 data points and compare binary trees built using both conventional and present methods. The partitioning process and the resulting binary trees are illustrated in
Figure 3. As shown, the binary tree constructed using the conventional method has a depth of 7 and exhibits an imbalanced structure characterized by deep left branches and shallow right branches. In contrast, the binary tree built using the present method achieves a depth of only 4 and exhibits a more balanced structure. To retrieve the information for point Q, the path in the conventional ADT method is A-H-J-L-M-O-P-Q, while the path using the present method is J-O-N-P-Q. When retrieving information for all 17 points from A to Q, the conventional method requires 72 retrievals, whereas the present method only needs 59. This represents a significant improvement in retrieval efficiency. The efficiency comparison of these two methods in practical Cartesian grid generation is detailed in
Section 5.2.
3. Cartesian Grid Data Structure Based on Member Packaging and Neighbor Threading
To tackle two significant issues associated with the conventional 2N tree Cartesian grid data structure—namely, memory waste from numerous leaf nodes containing null pointers and efficiency instability due to neighbor queries potentially tracing back to the root node—this paper introduces a Cartesian grid data structure that incorporates member packaging and neighbor threading. Member packaging effectively reduces memory consumption, while neighbor-threaded design improves the efficiency of neighbor queries.
Member packaging involves encapsulating a Cartesian cell along with its siblings, resulting in a combined structure referred to as an Oct. In the conventional 2
N tree data structure, all leaf cells are allocated null pointers due to the uncertainty of whether they will require further refinement, leading to unnecessary memory usage. In contrast, the data structure based on member packaging and neighbor threading consolidates all sibling leaf cells into a single Oct, as illustrated in
Figure 4. Although the member packaging introduces additional overhead related to memory allocation for child octants, it only requires a single null pointer to allocate extra space for potential future refinements, rather than the traditional 2
N null pointers, thus optimizing memory allocation. Most importantly, since a significant proportion of cells in Cartesian grids are leaf cells, this encapsulation effectively reduces overall memory consumption. It should be noted that A and B represent root octants corresponding to the coarse Cartesian grid, which cannot be future coarsened.
Neighbor threading not only establishes pointers between parent and child nodes but also allocates four (or six in 3D) additional pointers to the neighbors of the corresponding Oct within the parent cell. This configuration creates a fully threaded access path between cells and their neighbors. As illustrated in
Figure 4, when querying the right neighbor cell b of a spatially adjacent cell a, only one operation is required, as the Oct corresponding to cell a’s parent cell stores the right neighbor. The query path is indicated by the dashed line in
Figure 4b. In theory, the average number of neighbor queries for the conventional 2
N tree data structure is approximately 2. In contrast, for the Cartesian grid data structure presented in this paper, if the neighbor is a sibling, it can be determined directly; otherwise, only one query is needed to locate the neighbor. Consequently, the average number of neighbor queries is around 0.5. This demonstrates that the Cartesian grid data structure ensures consistent efficiency in neighbor queries. A detailed quantitative comparison with the conventional 2
N data structure will be provided in
Section 5.2.
The implementation process for constructing the member packaging and neighbor threading data structure requires allocating a series of pointers and storing the essential flow field information, location information, and connectivity information, as illustrated in
Figure 5. Since all cells are grouped with their siblings into an Oct, each Oct is assigned 2
N pointers to all the cells contained within it (Son1, Son2, …, Son2N). Additionally, each Oct holds a pointer to its parent cell (OctFather). To maintain the consistency of neighbor relationships, the level difference between neighboring cells must not exceed 1, and the level of a neighboring cell must be less than or equal to that of the target cell. As a result, each Oct holds six pointers to the parent cells of its six adjacent Octs (OctNeighbor). To facilitate navigation, each Oct must also store its central coordinates (OctCenter) and level information (OctLevel), which corresponds to that of its parent cell. The Cartesian grid data structure features dual-link relationships, requiring not only that each Oct has location information and pointers but also that each Cartesian cell maintains corresponding pointers for effective communication with the Oct. Each Cartesian cell points to its child Oct (OctSon). If the Cartesian cell is a leaf cell—indicating it has not been refined—the pointer is set to null. Conversely, when a leaf cell is refined, a pointer to the appropriate Oct is established. In addition to connectivity information, each Cartesian cell must store flow field data (u, v, w, ρ, T), whether it intersects with a geometrical surface (Cross), triangles intersecting the geometrical surface (TriCross), and the relative position concerning sibling cells (Location).
4. Determination of the Spatial Relationship Between the Cartesian Cell and the Geometric Surface
Based on the relative positions of Cartesian cells and a geometric surface, we classify the cells into three categories: cells intersected with the geometric surface, cells inside the object, and cells outside the object. To facilitate subsequent flow field calculations, we further categorize the intersected cells into two subtypes: cells with centers inside the object and cells with centers outside the object. This section aims to develop a robust and efficient Cartesian cell classification method to address the limitations of conventional approaches in terms of robustness and efficiency. The process for determining the spatial relationship between the Cartesian cell and the geometric surface is illustrated in
Figure 6. For each input Cartesian cell, the first step is to use a Cartesian cell-triangle intersection algorithm based on the Separating Axis Theorem to determine whether the Cartesian cell intersects with the geometric surface (intersection check). If the Cartesian cell does not intersect the geometric surface, a painting algorithm is used to classify the cell as inside or outside the object. (inside-outside classification). If the Cartesian cell does intersect with the geometric surface, a dot product algorithm is employed to determine whether the center of the cell is inside or outside the object (center determination). Finally, output the Cartesian cell type.
4.1. Intersection Check Based on the Separating Axis Theorem
The Separating Axis Theorem (SAT) can be intuitively understood through a simple analogy: imagine shining a flashlight on two objects from various angles. By observing the shadows these objects cast on nearby surfaces, you can assess whether they intersect. If, when viewed from any angle, there are no gaps between their shadows, then the two objects must overlap. Conversely, if the shadows are discontinuous, this indicates that the objects do not touch, suggesting the presence of a separating axis between them. By utilizing SAT in our intersection check, we can reliably determine whether a Cartesian cell intersects with a triangle, thereby enhancing the accuracy of the classification process. The Separating Axis Theorem is illustrated in
Figure 7.
To apply the SAT for determining whether a Cartesian cell intersects with a triangle, we first need to identify several key parameters: face normal vectors of the Cartesian cell,
e1 = (1, 0, 0),
e2 = (0, 1, 0), and
e3 = (0, 0, 1); Cartesian cell dimensions
hx,
hy, and
hz; and cell center
c. Additionally, define three vertices of the triangle
v1,
v2, and
v3; triangle edges
l1,
l2, and
l3; and the triangle normal vector
n. To simplify calculations, shift the Cartesian cell center to the origin while maintaining the relative positions between the Cartesian cell and the triangle, as illustrated in
Figure 8. The SAT requires 13 axis tests, categorized into three types: (1) The first three tests check whether the Cartesian cell intersects with the bounding box of the triangle, using the face normal vectors of the Cartesian cell. (2) The fourth test evaluates whether the Cartesian cell intersects with the plane defined by the triangle, using the normal vector of the triangle. (3) The remaining nine tests are based on the cross-products of the Cartesian cell’s face normal vectors with triangle edges. If all 13 tests pass, it indicates that no separating axis exists, and the routine returns “The Cartesian cell intersects with the triangle.” If any test identifies a separating axis, terminate the tests immediately and return “The Cartesian cell does not intersect with the triangle.” The algorithm offers two primary advantages. First, it is efficient, employing basic vector operations, which allows for quick computations; once a separating axis is identified, the process can be halted. Second, it is accurate. Since this algorithm was initially proposed by Möllser [
31] and has applications in the existing literature [
32], the specifics of the implementation will not be discussed further in this paper.
The algorithm described above is designed to determine the intersection between a single Cartesian cell and a single triangle. In practical mesh generation scenarios, the number of geometric surface discretization triangles can range from 105 to 106, while the number of Cartesian cells can reach 108 to 109. Using a brute-force approach to check intersections between each Cartesian cell and the triangle results in a computational load on the order of 1013 to 1015, which is prohibitively high. Consequently, the efficiency of mesh generation falls short of engineering requirements. To achieve accurate intersection determination while minimizing computational costs and enhancing mesh generation efficiency, this paper proposes the following three measures:
- ➀
Exclude Cartesian cells outside the geometric minimum bounding box.
Given that the computational domain is significantly larger than the geometric minimum bounding box, any Cartesian cell outside the bounding box cannot intersect with the geometric surface. Therefore, checking for intersections between the target Cartesian cells and the geometric minimum bounding box allows for rapid elimination of cells that do not intersect with the surface.
Figure 9 illustrates the comparison of Cartesian cells before and after applying this step, highlighting a significant reduction in the number of cells to be evaluated. For those cells that remain, the Cartesian cell-triangle intersection algorithm is then applied for further precise determination.
- ➁
Use BT-NBB to quickly exclude non-target triangles.
This step is crucial for improving the efficiency of determining intersecting Cartesian cells. As previously mentioned, during the construction of the BT-NBB, each node stores the bounding box information of its corresponding space. Therefore, the positional relationship between the target Cartesian cell and the bounding box of each tree node can be assessed first. This step aims to reduce unnecessary recursive operations in the tree and quickly exclude triangles that do not intersect with the target Cartesian cell. In the actual execution of the algorithm, the process begins by checking if the target Cartesian cell intersects with the root node of the BT-NBB. If there is no intersection, it indicates that the target Cartesian cell does not intersect with the geometric surface, and the algorithm terminates, returning a value of “Non-intersection”. Conversely, check the left and right child nodes of the root node separately, recursively applying the same operation until all triangles have been evaluated. The pseudocode for determining the intersection between the Cartesian cell and triangles, integrated with the BT-NBB, is illustrated in Algorithm 2. In this code, (Tmin, Tmax) represents the coordinate information of the target Cartesian cell T. Initially, the algorithm excludes Cartesian cells that do not intersect with the geometric minimum bounding box, ensuring that only relevant checks are performed.
It is important to note that
Figure 2 illustrates the presence of nested bounding boxes, indicating that these nested regions contain triangles. As a result, the target Cartesian cell may intersect with both the left and right subtrees during the execution of the aforementioned program. In such cases, separate searches for each subtree are necessary. When this circumstance arises at a shallower level in the tree, it may require recursion to deeper nodes to determine the type attribute of the target Cartesian cell, which can lead to increased CPU time consumption. Conversely, if this intersection occurs at a deeper level of the tree, its impact on computational efficiency is minimal.
Algorithm 2: The Cartesian cell—triangle intersection determination algorithm integrated with the BT-NBB |
1: | If ((Timin, Timax) ∩ (Gimin, Gimax) = ) then |
2: | T%Status = Non-intersection |
3: |
Return |
4: | Else |
5: | Call Cartesian cell-triangle intersection determination algorithm (T) |
6: | If (T%Status = Non-intersection) then |
7: | If (the left subtree, TL, exists and TLimin, TLimax) ∩ (Gimin, Gimax) ≠ ) then |
8: | Call Cartesian cell-triangle intersection determination algorithm (TL) |
9: |
Endif |
10: | If (the right subtree, TR, exists and TRimin, TRimax) ∩ (Gimin, Gimax) ≠ ) then |
11: | Call Cartesian cell-triangle intersection determination algorithm (TR) |
12: |
Endif |
13: |
Endif |
14: | Endif |
- ➂
Store triangles that intersect with the Cartesian cell.
The process of generating a Cartesian grid primarily involves creating the background grid, recursively refining the Cartesian cells that intersect with the surface triangles, and smoothing the cells to ensure that the level difference between adjacent cells does not exceed one. Among these steps, the recursive refinement is crucial for achieving the desired cell resolution near the surface. A key prerequisite for refining intersecting cells is determining the cell type—whether a Cartesian cell intersects with the surface or not. In practical applications of Cartesian cell type determination, the initial background grid cells can be relatively large, often intersecting multiple triangles, as shown in
Figure 10. If we store and mark the triangles intersected by each Cartesian cell, then during refinement, we only need to check if the child cells intersect with the previously marked triangles when determining their intersection with the surface. This paper leverages the parent–child relationship inherent in the Cartesian grid, allowing the number of triangles to check for each Cartesian cell to decrease as the refinement progresses. This approach significantly improves the efficiency of mesh generation.
After performing the intersection determination step for all Cartesian cells, the Cartesian cells are divided into intersected cells and non-intersected cells, as shown in
Figure 11 (the non-intersected cells include the region inside the sphere). The cell type determination results are consistent with known positional relationships, proving the correctness of the algorithm. Quantitative results regarding intersection determination efficiency will be further analyzed in
Section 5.2.
4.2. Inside-Outside Classification Based on the Painting Algorithm
The painting algorithm is fundamentally an unstructured traversal method that identifies and classifies objects sharing common properties. Its primary advantage lies in the ability to quickly propagate specific attributes to neighboring units without the need to independently test each target unit, thereby reducing classification complexity. The basic principle is as follows: Mark a particular cell for which we are sure that it is outside the geometry. Investigate its neighbors not intersected by the geometry. If the neighbor is not marked, mark it and process its neighbors.
For Cartesian cells, intersected cells have been identified, and non-intersected cells need to be further distinguished. This characteristic aligns well with the painting algorithm, which is both efficient and robust. Therefore, this paper uses the painting algorithm to classify the internal and external Cartesian cells.
In the Cartesian grid framework for internal and external classification using the painting method, the first step is to identify the painting source. Since the Cartesian cell located at the bottom-left of the computational domain is an external cell, it is used as the painting source, as shown in
Figure 12, with the attribute of “external cell.” Next is the painting process based on the neighboring cell query algorithm. Mark the neighbors of the painting source as “external cells”. When a neighbor is an intersected cell, do not use this cell to propagate the painting process further. At this point, all painted cells are marked as external cells, and the remaining ones are considered internal or intersected cells. Continuing with the sphere example, a painting algorithm is employed to distinguish between interior and exterior cells. As illustrated in
Figure 13, external cells are highlighted in red, while internal cells remain blue. This method effectively and accurately differentiates between interior and exterior cells.
4.3. Determination of the Intersected Cell Center Based on the Sign of a Dot Product
Since Cartesian grids are non-body-fitted, handling the geometry boundary is crucial for this type of grid. Proper handling of the wall boundary imposes stringent requirements on the accuracy of the grid type near the geometry boundary. Currently, there are three known types of cells: intersected cell, interior cell, and exterior cell. The center of an intersected cell may be either inside or outside the geometric surface. If the center of an intersected cell is outside the geometric surface, it is considered a fluid cell and will participate in flow field calculations. Therefore, further differentiation of the centers of intersected cells is required.
This paper uses the dot product method to identify the position of the Cartesian cell center. Implementing the dot product method is as follows: First, determine the outward normal vector
n1 of the triangle intersecting with the target Cartesian cell and the vector
n2 from the center of the intersecting triangle to the center of the target Cartesian cell. Then, the position relationship between the Cartesian cell center and the geometric surface is determined by checking the sign of the dot product of these two vectors. If the dot product is positive, the center of the target Cartesian cell is on the same side as the outward normal vector of the triangle, meaning it is outside the object. Conversely, if the dot product is negative, the target Cartesian cell center is inside the object. A schematic diagram of the dot product method for determining the relative position of the Cartesian cell center is shown in
Figure 14.
It is worth noting that in the Cartesian cell-triangle intersection determination algorithm, the triangles intersecting with the Cartesian cell are already stored. As a result, only one dot product check is needed after the intersection determination. The dot product method avoids the need to re-evaluate all intersected cells as required by the conventional ray tracing method, and it involves only a few addition, subtraction, and multiplication operations, making it efficient and accurate. For example, the dot product method determines the positional relationship between the intersected cell center and the sphere, as shown in
Figure 15. Cartesian cells with centers located inside the object, denoted as C
in, are marked in orange, while those with centers outside the object, denoted as C
out, are marked in yellow. From the marking results, it can be seen that the dot product method correctly distinguishes the intersected cell centers.
6. Conclusions
This article focuses on the Cartesian grid generation method, starting with the core aspects of Cartesian grid generation: the surface mesh data structure, the Cartesian grid data structure, and the determination of the positional relationship between the Cartesian grid and the geometrical surface. This study identifies the root causes of issues such as insufficient robustness, low efficiency, and memory waste in conventional methods for Cartesian grid generation, aiming to address these challenges. First, a surface mesh data structure based on nested bounding boxes is established to store discrete triangle information. Two criteria are employed to create a balanced binary tree: using maximum variance to determine the optimal splitting dimension and median nodes to identify the optimal splitting position. The spatial locations of the triangles are stored using nested bounding boxes, which enhances the accuracy and efficiency of retrieving and accessing triangle information. Second, by member packaging and neighbor threading in the Cartesian grid data structure, redundant null pointers in leaf cells are eliminated, reducing memory usage while establishing relationships between neighbors to enhance query efficiency. Finally, a set of methods for determining Cartesian cell types is established. Specifically, the methods involve using the Separating Axis Theorem to ascertain whether the Cartesian cell intersects with the geometric surface; employing a painting algorithm to determine whether the Cartesian cell is outside or inside the object; and utilizing the dot product method to identify whether the center of the intersected Cartesian cell is located inside or outside the object. In addition, to improve the efficiency and accuracy of intersection determination between large-scale triangles and Cartesian cells, this paper proposes three measures: excluding Cartesian cells that do not intersect with the geometric minimum bounding box; employing a surface mesh data structure based on the concept of nested bounding boxes to quickly eliminate non-target triangles; and storing triangles that intersect with the Cartesian cells.
To demonstrate the feasibility and reliability of the Cartesian grid generation method presented in this paper, six geometries of varying complexity—such as a sphere, train, bogie, pantograph, car, and DPW6 aircraft—covering diverse industries, are used to evaluate the robustness, efficiency, and memory consumption of the proposed method. Regarding robustness, our proposed method successfully generates Cartesian grids for six geometries, demonstrating exceptional robustness. For efficiency, we conducted a comprehensive evaluation from five perspectives, achieving a grid generation speed of no more than two seconds per million cells—marking a substantial improvement over conventional methods. Additionally, memory consumption is reduced by 20% compared to conventional methods. Furthermore, an example of airflow past a train is provided. The pressure profile on train surface closely aligns with the wind tunnel test data, confirming that the generated Cartesian grid meets the necessary requirements for actual calculations. Overall, our method demonstrates significant advancements in robustness, efficiency, and memory usage. However, considering that geometric deformations in practical engineering may require the reconstruction of surface mesh data structures, the associated time costs could become evident. Therefore, further enhancements in this area are warranted in future work.