mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-09-01 08:46:23 +00:00
feat(mesh): Add mesh API with topology ownership and node-to-elements mapping
Create src/mesh/api.jl defining mesh-specific abstractions:
- AbstractMesh base type for all mesh structures
- nnodes_total(), nelements() for mesh sizing
- get_node(node_id) returns Vec{Dim} coordinates
- connectivity_matrix() returns element-to-nodes mapping
- get_elements_for_node(node_id) returns node-to-elements mapping (critical for nodal assembly)
- get_element_set(name), get_node_set(name) for named sets (BCs, materials, postprocessing)
- AbstractRefineStrategy, refine() for adaptive mesh refinement
Meshes own topology (coordinates, connectivity). Multiple Physics can
share one Mesh for multiphysics coupling. Node-to-elements mapping
enables nodal assembly pattern (see docs/book/multigpu_nodal_assembly.md).
Part of systematic modular API architecture.
This commit is contained in:
+233
@@ -0,0 +1,233 @@
|
||||
# This file is a part of JuliaFEM.
|
||||
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
|
||||
|
||||
"""
|
||||
Mesh API definitions.
|
||||
|
||||
This file defines mesh-specific abstract types and interfaces.
|
||||
Must be included after core api.jl.
|
||||
"""
|
||||
|
||||
# ============================================================================
|
||||
# MESH ABSTRACTIONS
|
||||
# ============================================================================
|
||||
|
||||
"""
|
||||
AbstractMesh
|
||||
|
||||
Abstract type for all mesh structures.
|
||||
|
||||
# Interface Requirements
|
||||
|
||||
Concrete mesh types must implement:
|
||||
- `nnodes_total(mesh)` - Total number of nodes
|
||||
- `nelements(mesh)` - Total number of elements
|
||||
- `get_node(mesh, node_id)` - Get node coordinates
|
||||
- `connectivity_matrix(mesh)` - Element connectivity
|
||||
- `get_elements_for_node(mesh, node_id)` - Elements containing node
|
||||
- `get_element_set(mesh, set_name)` - Get named element set
|
||||
- `get_node_set(mesh, set_name)` - Get named node set
|
||||
|
||||
# Concrete Types
|
||||
- `Mesh{T<:AbstractTopology}` - Parametric mesh with single topology type
|
||||
- `MixedMesh` - Mesh with multiple topology types (future)
|
||||
|
||||
# Design Philosophy
|
||||
|
||||
Meshes own topology (node coordinates, connectivity).
|
||||
Physics references meshes (does not own them).
|
||||
Multiple Physics can share one Mesh (multiphysics coupling).
|
||||
|
||||
# Element Sets and Node Sets
|
||||
|
||||
Meshes support named sets for:
|
||||
- Applying boundary conditions
|
||||
- Defining material regions
|
||||
- Post-processing specific regions
|
||||
|
||||
# See Also
|
||||
- Concrete implementation: `Mesh{T}` in src/mesh/mesh.jl
|
||||
"""
|
||||
abstract type AbstractMesh end
|
||||
|
||||
# ============================================================================
|
||||
# MESH OPERATIONS
|
||||
# ============================================================================
|
||||
|
||||
"""
|
||||
nnodes_total(mesh::AbstractMesh) -> Int
|
||||
|
||||
Total number of nodes in the mesh.
|
||||
|
||||
# Examples
|
||||
```julia
|
||||
mesh = Mesh(Tet4(), nodes, connectivity)
|
||||
n = nnodes_total(mesh) # e.g., 1000 nodes
|
||||
```
|
||||
"""
|
||||
function nnodes_total end
|
||||
|
||||
"""
|
||||
nelements(mesh::AbstractMesh) -> Int
|
||||
|
||||
Total number of elements in the mesh.
|
||||
|
||||
# Examples
|
||||
```julia
|
||||
mesh = Mesh(Hex8(), nodes, connectivity)
|
||||
ne = nelements(mesh) # e.g., 500 elements
|
||||
```
|
||||
"""
|
||||
function nelements end
|
||||
|
||||
"""
|
||||
get_node(mesh::AbstractMesh, node_id::Int) -> Vec{Dim}
|
||||
|
||||
Get coordinates of a node by its ID.
|
||||
|
||||
# Arguments
|
||||
- `mesh`: Mesh structure
|
||||
- `node_id`: Node identifier (1-based)
|
||||
|
||||
# Returns
|
||||
- Node coordinates as `Vec{Dim}` (Dim = 1, 2, or 3)
|
||||
|
||||
# Examples
|
||||
```julia
|
||||
X = get_node(mesh, 42) # Vec{3}(1.0, 2.0, 3.0)
|
||||
```
|
||||
"""
|
||||
function get_node end
|
||||
|
||||
"""
|
||||
connectivity_matrix(mesh::AbstractMesh) -> Matrix{Int}
|
||||
|
||||
Get element connectivity matrix.
|
||||
|
||||
# Returns
|
||||
- Matrix where each row is an element's node IDs
|
||||
- Size: `(nelements, nnodes_per_element)`
|
||||
|
||||
# Examples
|
||||
```julia
|
||||
conn = connectivity_matrix(mesh)
|
||||
elem1_nodes = conn[1, :] # [1, 2, 3, 4] for Tet4
|
||||
```
|
||||
"""
|
||||
function connectivity_matrix end
|
||||
|
||||
"""
|
||||
get_elements_for_node(mesh::AbstractMesh, node_id::Int) -> Vector{Int}
|
||||
|
||||
Get all elements containing a given node.
|
||||
|
||||
Critical for nodal assembly (node-to-elements map).
|
||||
|
||||
# Arguments
|
||||
- `mesh`: Mesh structure
|
||||
- `node_id`: Node identifier
|
||||
|
||||
# Returns
|
||||
- Vector of element IDs containing this node
|
||||
|
||||
# Examples
|
||||
```julia
|
||||
elems = get_elements_for_node(mesh, 10) # [5, 6, 7, 8, 12, 15]
|
||||
```
|
||||
|
||||
# See Also
|
||||
- Nodal assembly: docs/book/multigpu_nodal_assembly.md
|
||||
"""
|
||||
function get_elements_for_node end
|
||||
|
||||
"""
|
||||
get_element_set(mesh::AbstractMesh, set_name::String) -> Vector{Int}
|
||||
|
||||
Get element IDs in a named element set.
|
||||
|
||||
# Arguments
|
||||
- `mesh`: Mesh structure
|
||||
- `set_name`: Name of element set (e.g., "body", "surface1")
|
||||
|
||||
# Returns
|
||||
- Vector of element IDs in the set
|
||||
|
||||
# Examples
|
||||
```julia
|
||||
body_elements = get_element_set(mesh, "body")
|
||||
surface_elements = get_element_set(mesh, "traction_surface")
|
||||
```
|
||||
|
||||
# See Also
|
||||
- [`get_node_set`](@ref) for node sets
|
||||
"""
|
||||
function get_element_set end
|
||||
|
||||
"""
|
||||
get_node_set(mesh::AbstractMesh, set_name::String) -> Vector{Int}
|
||||
|
||||
Get node IDs in a named node set.
|
||||
|
||||
# Arguments
|
||||
- `mesh`: Mesh structure
|
||||
- `set_name`: Name of node set (e.g., "fixed_nodes", "boundary")
|
||||
|
||||
# Returns
|
||||
- Vector of node IDs in the set
|
||||
|
||||
# Examples
|
||||
```julia
|
||||
fixed_nodes = get_node_set(mesh, "fixed_support")
|
||||
loaded_nodes = get_node_set(mesh, "load_application")
|
||||
```
|
||||
|
||||
# See Also
|
||||
- [`get_element_set`](@ref) for element sets
|
||||
"""
|
||||
function get_node_set end
|
||||
|
||||
# ============================================================================
|
||||
# MESH REFINEMENT
|
||||
# ============================================================================
|
||||
|
||||
"""
|
||||
AbstractRefineStrategy
|
||||
|
||||
Abstract type for mesh refinement strategies.
|
||||
|
||||
# Concrete Strategies
|
||||
- `LongestEdgeBisection`: Recursive longest edge bisection
|
||||
- `RedGreenRefinement`: Red-green triangulation
|
||||
- `Uniform`: Uniform refinement (split all elements)
|
||||
|
||||
# See Also
|
||||
- [`refine`](@ref) for refinement function
|
||||
- Implementation: src/mesh/refine.jl
|
||||
"""
|
||||
abstract type AbstractRefineStrategy end
|
||||
|
||||
"""
|
||||
refine(mesh::AbstractMesh, strategy::AbstractRefineStrategy) -> AbstractMesh
|
||||
|
||||
Refine a mesh using a refinement strategy.
|
||||
|
||||
# Arguments
|
||||
- `mesh`: Original mesh
|
||||
- `strategy`: Refinement strategy
|
||||
|
||||
# Returns
|
||||
- Refined mesh (new instance)
|
||||
|
||||
# Examples
|
||||
```julia
|
||||
# Longest edge bisection
|
||||
refined = refine(mesh, LongestEdgeBisection())
|
||||
|
||||
# Uniform refinement
|
||||
refined = refine(mesh, Uniform())
|
||||
```
|
||||
|
||||
# See Also
|
||||
- [`AbstractRefineStrategy`](@ref) for available strategies
|
||||
"""
|
||||
function refine end
|
||||
Reference in New Issue
Block a user