Sample¶
The Sample class contains the main element of the data model: all the heterogeneity and generality capacities come from it. This Jupyter Notebook demonstrates various operations and methods involving a sample data structure using the PLAID library. We start with simple sample generation examples relying on Muscat reader, and finish with more advanced data handling examples.
Section 1: Simple sample creation using Muscat readers¶
Load a physics simulation in a given format, here in vtk.¶
# Load a vtk file
from Muscat.IO.VtkReader import VtkReader
reader = VtkReader()
try:
mesh_path = Path(__file__).resolve().parent / "mesh.vtk"
except NameError: # for jupyter notebook execution
mesh_path = Path("mesh.vtk").resolve()
mesh = reader.Read(fileName=str(mesh_path))
Kokkos::OpenMP::initialize WARNING: OMP_PROC_BIND environment variable not set
In general, for best performance with OpenMP 4.0 or better set OMP_PROC_BIND=spread and OMP_PLACES=threads
For best performance with OpenMP 3.1 set OMP_PROC_BIND=true
For unit testing set OMP_PROC_BIND=false
# Convert it to a CGNS tree using Muscat's CGNS bridge
from Muscat.Bridges.CGNSBridge import MeshToCGNS
from plaid.utils import cgns_helper as CGH
tree = MeshToCGNS(mesh)
print("#---# Show CGNS Tree")
CGH.show_cgns_tree(tree)
#---# Show CGNS Tree
CGNSLibraryVersion : (1,) [4.] float32 CGNSLibraryVersion_t
Base_2_3 : (2,) [2 3] int32 CGNSBase_t
|_ Bulk : None Family_t
|_ Zone : (1, 3) [[50 96 0]] int64 Zone_t
|_ ZoneType : (12,) Unstructured |S1 ZoneType_t
|_ GridCoordinates : None GridCoordinates_t
|_ CoordinateX : (50,) [0. ... 0.15340106] float64 DataArray_t
|_ CoordinateY : (50,) [ 0. ... -0.15340106] float64 DataArray_t
|_ CoordinateZ : (50,) [ 0.5 ... -0.45048442] float64 DataArray_t
|_ Elements_TRI_3 : (2,) [5 0] int32 Elements_t
|_ ElementRange : (2,) [ 1 96] int64 IndexRange_t
|_ ElementConnectivity : (288,) [3 ... 7] int64 DataArray_t
|_ VertexFields : None FlowSolution_t
|_ GridLocation : (6,) Vertex |S1 GridLocation_t
|_ OriginalIds : (50,) [ 1 ... 50] int64 DataArray_t
|_ Normals_0 : (50,) [0. ... 0.30680212] float32 DataArray_t
|_ Normals_1 : (50,) [ 0. ... -0.30680212] float32 DataArray_t
|_ Normals_2 : (50,) [ 1. ... -0.90096885] float32 DataArray_t
|_ CellCenterFields : None FlowSolution_t
|_ GridLocation : (10,) CellCenter |S1 GridLocation_t
|_ OriginalIds : (96,) [ 1 ... 96] int64 DataArray_t
|_ FamilyName : (4,) Bulk |S1 FamilyName_t
Initialize a plaid sample, populate it with a CGNS tree and add a global¶
Check the sample content¶
Sample Completeness Check:
==============================
Has scalars: True
Has meshes: True
Total unique fields: 4
Field names: Normals_0, Normals_1, Normals_2, OriginalIds
Sample Summary:
==================================================
Scalars (1):
- power: 1.0
Meshes (1 timestamps):
Time: 0.0
Base: Base_2_3
Zone: Zone
Nodes (50)
Location: Vertex
Fields (4): Normals_0, Normals_1, Normals_2, OriginalIds
Location: CellCenter
Fields (1): OriginalIds
Elements (96)
TRI_3 (96)
Base: Global
Section 2: Advanced data handling¶
Section 2.1: Initializing an Empty Sample and Adding Data¶
This section demonstrates how to initialize an empty Sample and add scalars, and meshes / CGNS trees.
Create and display CGNS tree from an unstructured mesh¶
# Input data
from Muscat.MeshTools import MeshCreationTools as MCT
points = np.array(
[
[0.0, 0.0],
[1.0, 0.0],
[1.0, 1.0],
[0.0, 1.0],
[0.5, 1.5],
]
)
triangles = np.array(
[
[0, 1, 2],
[0, 2, 3],
[2, 4, 3],
]
)
Mesh = MCT.CreateMeshOfTriangles(points, triangles)
Mesh.nodeFields["test_node_field_1"] = np.random.randn(5)
Mesh.elemFields["test_elem_field_1"] = np.random.randn(3)
tree = MeshToCGNS(Mesh)
print("#---# Show CGNS Tree")
CGH.show_cgns_tree(tree)
print("\n#---# Summarize CGNS Tree")
CGH.summarize_cgns_tree(tree)
print("\n#---# Summarize CGNS Tree without additional Field Information")
CGH.summarize_cgns_tree(tree, verbose=False)
#---# Show CGNS Tree
CGNSLibraryVersion : (1,) [4.] float32 CGNSLibraryVersion_t
Base_2_2 : (2,) [2 2] int32 CGNSBase_t
|_ 2D : None Family_t
|_ Zone : (1, 3) [[5 3 0]] int64 Zone_t
|_ ZoneType : (12,) Unstructured |S1 ZoneType_t
|_ GridCoordinates : None GridCoordinates_t
|_ CoordinateX : (5,) [0. 1. 1. 0. 0.5] float64 DataArray_t
|_ CoordinateY : (5,) [0. 0. 1. 1. 1.5] float64 DataArray_t
|_ Elements_TRI_3 : (2,) [5 0] int32 Elements_t
|_ ElementRange : (2,) [1 3] int64 IndexRange_t
|_ ElementConnectivity : (9,) [1 ... 4] int64 DataArray_t
|_ VertexFields : None FlowSolution_t
|_ GridLocation : (6,) Vertex |S1 GridLocation_t
|_ OriginalIds : (5,) [1 2 3 4 5] int64 DataArray_t
|_ test_node_field_1 : (5,) [ 1.57228445 -0.79812797 -0.74235336 -0.28304151 -1.1860188 ] float64 DataArray_t
|_ CellCenterFields : None FlowSolution_t
|_ GridLocation : (10,) CellCenter |S1 GridLocation_t
|_ OriginalIds : (3,) [1 2 3] int64 DataArray_t
|_ test_elem_field_1 : (3,) [-1.10621078 0.29662337 -1.18089037] float64 DataArray_t
|_ FamilyName : (2,) 2D |S1 FamilyName_t
#---# Summarize CGNS Tree
Number of Bases: 1
Number of Zones: 1
Number of Nodes: 5
Number of Elements: 3
Number of Fields: 6
Fields :
Base_2_2/Zone/VertexFields/GridLocation
Base_2_2/Zone/VertexFields/OriginalIds
Base_2_2/Zone/VertexFields/test_node_field_1
Base_2_2/Zone/CellCenterFields/GridLocation
Base_2_2/Zone/CellCenterFields/OriginalIds
Base_2_2/Zone/CellCenterFields/test_elem_field_1
#---# Summarize CGNS Tree without additional Field Information
Number of Bases: 1
Number of Zones: 1
Number of Nodes: 5
Number of Elements: 3
Number of Fields: 6
Initialize a new empty Sample and print it¶
# Initialize an empty Sample
print("#---# Empty Sample")
sample = Sample()
print(sample, end="\n\n")
print(sample.summarize())
#---# Empty Sample
Sample(0 globals, 0 timestamps, 0 fields)
Sample Summary:
==================================================
Meshes (0 timestamps):
Add a scalars to a Sample¶
# Add a rotation scalar to this Sample
sample.add_global("rotation", np.random.randn())
print(sample.summarize())
Sample Summary:
==================================================
Scalars (1):
- rotation: -0.8595603514974286
Meshes (1 timestamps):
Time: 0.0
Base: Global
# Add a more scalars to this Sample
sample.add_global("speed", np.random.randn())
sample.add_global("other", np.random.randn())
print(sample.summarize())
Sample Summary:
==================================================
Scalars (3):
- rotation: -0.8595603514974286
- speed: -0.4207686397533967
- other: -0.9008198766721682
Meshes (1 timestamps):
Time: 0.0
Base: Global
Add a CGNS Tree to a Sample and display it¶
# Add the previously created CGNS tree to the sample
sample.add_tree(tree)
# Display the Sample CGNS tree
sample.show_tree()
CGNSLibraryVersion : (1,) [4.] float32 CGNSLibraryVersion_t
Global : (2,) [1 1] int32 CGNSBase_t
|_ Time : (1,) [1] int32 BaseIterativeData_t
|_ IterationValues : (1,) [1] int32 DataArray_t
|_ TimeValues : (1,) [0.] float64 DataArray_t
|_ rotation : (1,) [-0.85956035] float64 DataArray_t
|_ speed : (1,) [-0.42076864] float64 DataArray_t
|_ other : (1,) [-0.90081988] float64 DataArray_t
Base_2_2 : (2,) [2 2] int32 CGNSBase_t
|_ 2D : None Family_t
|_ Zone : (1, 3) [[5 3 0]] int64 Zone_t
|_ ZoneType : (12,) Unstructured |S1 ZoneType_t
|_ GridCoordinates : None GridCoordinates_t
|_ CoordinateX : (5,) [0. 1. 1. 0. 0.5] float64 DataArray_t
|_ CoordinateY : (5,) [0. 0. 1. 1. 1.5] float64 DataArray_t
|_ Elements_TRI_3 : (2,) [5 0] int32 Elements_t
|_ ElementRange : (2,) [1 3] int64 IndexRange_t
|_ ElementConnectivity : (9,) [1 ... 4] int64 DataArray_t
|_ VertexFields : None FlowSolution_t
|_ GridLocation : (6,) Vertex |S1 GridLocation_t
|_ OriginalIds : (5,) [1 2 3 4 5] int64 DataArray_t
|_ test_node_field_1 : (5,) [ 1.57228445 -0.79812797 -0.74235336 -0.28304151 -1.1860188 ] float64 DataArray_t
|_ CellCenterFields : None FlowSolution_t
|_ GridLocation : (10,) CellCenter |S1 GridLocation_t
|_ OriginalIds : (3,) [1 2 3] int64 DataArray_t
|_ test_elem_field_1 : (3,) [-1.10621078 0.29662337 -1.18089037] float64 DataArray_t
|_ FamilyName : (2,) 2D |S1 FamilyName_t
|_ Time : (1,) [1] int32 BaseIterativeData_t
|_ IterationValues : (1,) [1] int32 DataArray_t
|_ TimeValues : (1,) [0.] float64 DataArray_t
Set all meshes with their corresponding time step¶
# Init an empty Sample
new_sample_mult_mesh = Sample()
# All meshes with their corresponding time step
meshes_dict = {0.0: tree, 0.5: tree, 1.0: tree}
# Set meshes in the Sample
new_sample_mult_mesh.set_trees(meshes_dict)
print(f"{new_sample_mult_mesh.get_all_time_values() = }")
new_sample_mult_mesh.get_all_time_values() = [0.0, 0.5, 1.0]
Section 2.2: Accessing and Modifying Sample Data¶
This section demonstrates how to access and modify base, zone, node, scalar and field data within the Sample.
Initialize CGNS tree base¶
# Initialize an new empty Sample
print("#---# Empty Sample")
sample = Sample()
print(sample, end="\n\n")
# Init CGNS tree base at time 0.
sample.init_base(2, 3, "SurfaceMesh", time=0.0)
print(sample.summarize())
#---# Empty Sample
Sample(0 globals, 0 timestamps, 0 fields)
Sample Summary:
==================================================
Meshes (1 timestamps):
Time: 0.0
Base: SurfaceMesh
Initialize CGNS tree zone¶
# Init CGNS tree zone to a base at time 0.
shape = np.array([[len(points), len(triangles), 0]])
sample.init_zone(shape, zone="TestZoneName", base="SurfaceMesh", time=0.0)
print(sample.summarize())
Sample Summary:
==================================================
Meshes (1 timestamps):
Time: 0.0
Base: SurfaceMesh
Zone: TestZoneName
Elements (0)
Set the coordinates of nodes for a specified base and zone¶
points = np.array(
[
[0.0, 0.0],
[1.0, 0.0],
[1.0, 1.0],
[0.0, 1.0],
[0.5, 1.5],
]
)
# Set the coordinates of nodes for a specified base and zone at a given time.
# set node coordinates
sample.set_nodes(points, base="SurfaceMesh", zone="TestZoneName", time=0.0)
print(sample.summarize())
Sample Summary:
==================================================
Meshes (1 timestamps):
Time: 0.0
Base: SurfaceMesh
Zone: TestZoneName
Nodes (5)
Elements (0)
Add a field to a specified zone in the grid¶
# Add a field to a specified zone
sample.add_field(
"Pressure",
np.random.randn(len(points)),
base="SurfaceMesh",
zone="TestZoneName",
time=0.0,
)
print(sample.summarize())
Sample Summary:
==================================================
Meshes (1 timestamps):
Time: 0.0
Base: SurfaceMesh
Zone: TestZoneName
Nodes (5)
Location: Vertex
Fields (1): Pressure
Elements (0)
# Add another field
sample.add_field(
"Temperature",
np.random.randn(len(points)),
base="SurfaceMesh",
zone="TestZoneName",
time=0.0,
)
print(sample.summarize())
Sample Summary:
==================================================
Meshes (1 timestamps):
Time: 0.0
Base: SurfaceMesh
Zone: TestZoneName
Nodes (5)
Location: Vertex
Fields (2): Pressure, Temperature
Elements (0)
Access scalars data in Sample¶
# It will look for a default base if no base and zone are given
print(f"{sample.get_global_names() = }")
print(f"{sample.get_global('omega') = }")
print(f"{sample.get_global('rotation') = }")
sample.get_global_names() = []
sample.get_global('omega') = None
sample.get_global('rotation') = None
Access fields data in Sample¶
# It will look for a default base if no base and zone are given
print(f"{sample.get_field_names() = }")
print(f"{sample.get_field('T') = }")
print(f"{sample.get_field('Temperature') = }")
sample.get_field_names() = ['Pressure', 'Temperature']
sample.get_field('T') = None
sample.get_field('Temperature') = array([ 0.58177437, 0.29638562, -0.17345189, 0.27042681, 1.23031369])
Access to points coordinates¶
# It will look for a default base if no base and zone are given
print(f"{sample.get_nodes() = }")
print(f"{sample.get_nodes() = }")
sample.get_nodes() = array([[0. , 0. ],
[1. , 0. ],
[1. , 1. ],
[0. , 1. ],
[0.5, 1.5]])
sample.get_nodes() = array([[0. , 0. ],
[1. , 0. ],
[1. , 1. ],
[0. , 1. ],
[0.5, 1.5]])
Retrieve element connectivity data¶
# Create an empty Sample
tmp_sample = Sample()
# Add the previously created CGNS tree in the Sample
tmp_sample.add_tree(tree)
print("element connectivity = \n", f"{tmp_sample.get_elements()}")
element connectivity =
{'TRI_3': array([[0, 1, 2],
[0, 2, 3],
[2, 4, 3]])}
Access the available base of the CGNS tree¶
# Get base names
bases_names = sample.get_base_names()
# Get full base path
full_bases_names = sample.get_base_names(full_path=True)
print(f"{bases_names=}")
print(f"{full_bases_names=}")
bases_names=['SurfaceMesh']
full_bases_names=['/SurfaceMesh']
# Get the first base name
base_name = sample.get_base_names()[0]
# Get base node
base_node_content = sample.get_base(base_name)
print(f"{base_node_content = }")
base_node_content = ['SurfaceMesh', array([2, 3], dtype=int32), [['Time', array([1], dtype=int32), [['IterationValues', array([1], dtype=int32), [], 'DataArray_t'], ['TimeValues', array([0.]), [], 'DataArray_t']], 'BaseIterativeData_t'], ['TestZoneName', array([[5, 3, 0]]), [['ZoneType', array([b'U', b'n', b's', b't', b'r', b'u', b'c', b't', b'u', b'r', b'e',
b'd'], dtype='|S1'), [], 'ZoneType_t'], ['GridCoordinates', None, [['CoordinateX', array([0. , 1. , 1. , 0. , 0.5]), [], 'DataArray_t'], ['CoordinateY', array([0. , 0. , 1. , 1. , 1.5]), [], 'DataArray_t']], 'GridCoordinates_t'], ['VertexFields', None, [['GridLocation', array([b'V', b'e', b'r', b't', b'e', b'x'], dtype='|S1'), [], 'GridLocation_t'], ['Pressure', array([-1.54146993, 2.65935437, 1.09965842, -0.06759072, -0.3208659 ]), [], 'DataArray_t'], ['Temperature', array([ 0.58177437, 0.29638562, -0.17345189, 0.27042681, 1.23031369]), [], 'DataArray_t']], 'FlowSolution_t']], 'Zone_t']], 'CGNSBase_t']
Check if a base exists in a Sample¶
# Get the first base name
base_name = sample.get_base_names()[0]
print(f"{sample.has_base(base_name) = }")
print(f"{sample.has_base('unknown_base_name') = }")
sample.has_base(base_name) = True
sample.has_base('unknown_base_name') = False
Access the available zone from a CGNS tree base¶
# Get the first base name
base_name = sample.get_base_names()[0]
# Get zones associated with the first base
zones_names = sample.get_zone_names(base_name)
# Get full path of zones associated with the first base
full_zones_names = sample.get_zone_names(base_name, full_path=True)
print(f" - Base : {base_name}")
print(f" - Zone(s): {zones_names}")
print(f" - Zone(s) full path: {full_zones_names}")
- Base : SurfaceMesh
- Zone(s): ['TestZoneName']
- Zone(s) full path: ['SurfaceMesh/TestZoneName']
# Get the first zone name from a base name
zone_name = zones_names[0]
# Get base node
zone_node_content = sample.get_zone(zone_name, base_name)
print(f"{zone_node_content = }")
zone_node_content = ['TestZoneName', array([[5, 3, 0]]), [['ZoneType', array([b'U', b'n', b's', b't', b'r', b'u', b'c', b't', b'u', b'r', b'e',
b'd'], dtype='|S1'), [], 'ZoneType_t'], ['GridCoordinates', None, [['CoordinateX', array([0. , 1. , 1. , 0. , 0.5]), [], 'DataArray_t'], ['CoordinateY', array([0. , 0. , 1. , 1. , 1.5]), [], 'DataArray_t']], 'GridCoordinates_t'], ['VertexFields', None, [['GridLocation', array([b'V', b'e', b'r', b't', b'e', b'x'], dtype='|S1'), [], 'GridLocation_t'], ['Pressure', array([-1.54146993, 2.65935437, 1.09965842, -0.06759072, -0.3208659 ]), [], 'DataArray_t'], ['Temperature', array([ 0.58177437, 0.29638562, -0.17345189, 0.27042681, 1.23031369]), [], 'DataArray_t']], 'FlowSolution_t']], 'Zone_t']
Get the zone type¶
# Get the first zone name from a base name
zone_name = zones_names[0]
z_type = sample.get_zone_type(zone_name, base_name)
print(f"zone type = {z_type}")
zone type = Unstructured
Check if a zone exists in a Sample¶
# Get the first zone name from a base name
zone_name = zones_names[0]
print(f"{sample.has_zone(zone_name, base_name) = }")
print(f"{sample.has_zone('unknown_zone_name', base_name) = }")
sample.has_zone(zone_name, base_name) = True
sample.has_zone('unknown_zone_name', base_name) = False
Get mesh from sample¶
['CGNSTree', None, [['CGNSLibraryVersion', array([4.], dtype=float32), [], 'CGNSLibraryVersion_t'], ['SurfaceMesh', array([2, 3], dtype=int32), [['Time', array([1], dtype=int32), [['IterationValues', array([1], dtype=int32), [], 'DataArray_t'], ['TimeValues', array([0.]), [], 'DataArray_t']], 'BaseIterativeData_t'], ['TestZoneName', array([[5, 3, 0]]), [['ZoneType', array([b'U', b'n', b's', b't', b'r', b'u', b'c', b't', b'u', b'r', b'e',
b'd'], dtype='|S1'), [], 'ZoneType_t'], ['GridCoordinates', None, [['CoordinateX', array([0. , 1. , 1. , 0. , 0.5]), [], 'DataArray_t'], ['CoordinateY', array([0. , 0. , 1. , 1. , 1.5]), [], 'DataArray_t']], 'GridCoordinates_t'], ['VertexFields', None, [['GridLocation', array([b'V', b'e', b'r', b't', b'e', b'x'], dtype='|S1'), [], 'GridLocation_t'], ['Pressure', array([-1.54146993, 2.65935437, 1.09965842, -0.06759072, -0.3208659 ]), [], 'DataArray_t'], ['Temperature', array([ 0.58177437, 0.29638562, -0.17345189, 0.27042681, 1.23031369]), [], 'DataArray_t']], 'FlowSolution_t']], 'Zone_t']], 'CGNSBase_t']], 'CGNSTree_t']
Get all mesh time available in Sample¶
# Before adding new tree
print(f"{sample.get_all_time_values() = }")
# Add one CGNS tree at time 1.
sample.add_tree(tree, 1.0)
# After adding new tree
print(f"{sample.get_all_time_values() = }")
sample.get_all_time_values() = [0.0]
sample.get_all_time_values() = [0.0, 1.0]
Creating a Sample Hierarchy with bases, zones, and associated data.¶
bases_names = sample.get_base_names()
full_bases_names = sample.get_base_names(full_path=True)
print(f"{bases_names = }")
print(f"{full_bases_names = }", end="\n\n")
for b_name in bases_names:
zones_names = sample.get_zone_names(b_name)
full_zones_names = sample.get_zone_names(b_name, full_path=True)
print(f" - Base : {b_name}")
for z_name, f_z_name in zip(zones_names, full_zones_names):
print(
f" - {z_name} -> type: {sample.get_zone_type(z_name, b_name)} | full: {f_z_name}"
)
bases_names = ['SurfaceMesh']
full_bases_names = ['/SurfaceMesh']
- Base : SurfaceMesh
- TestZoneName -> type: Unstructured | full: SurfaceMesh/TestZoneName
Section 2.3: Set and Get default values¶
This section demonstrates how to use default CGNS values in a Sample.
Set and use default time in a Sample¶
# Without a provided default time, it searches the first time available in all mesh times
print(f"{sample.get_all_time_values() = }")
print(f"{sample.resolve_time() = }", end="\n\n")
# Set default time
sample.set_default_time(1.0)
# Now that default time has been assigned, there's no need to specify it in function calls.
print(f"{sample.resolve_time() = }", end="\n\n")
# Print the tree at time 1.0
sample.show_tree() # == sample.show_tree(1.0)
sample.get_all_time_values() = [0.0, 1.0]
sample.resolve_time() = 0.0
sample.resolve_time() = 1.0
CGNSLibraryVersion : (1,) [4.] float32 CGNSLibraryVersion_t
Base_2_2 : (2,) [2 2] int32 CGNSBase_t
|_ 2D : None Family_t
|_ Zone : (1, 3) [[5 3 0]] int64 Zone_t
|_ ZoneType : (12,) Unstructured |S1 ZoneType_t
|_ GridCoordinates : None GridCoordinates_t
|_ CoordinateX : (5,) [0. 1. 1. 0. 0.5] float64 DataArray_t
|_ CoordinateY : (5,) [0. 0. 1. 1. 1.5] float64 DataArray_t
|_ Elements_TRI_3 : (2,) [5 0] int32 Elements_t
|_ ElementRange : (2,) [1 3] int64 IndexRange_t
|_ ElementConnectivity : (9,) [1 ... 4] int64 DataArray_t
|_ VertexFields : None FlowSolution_t
|_ GridLocation : (6,) Vertex |S1 GridLocation_t
|_ OriginalIds : (5,) [1 2 3 4 5] int64 DataArray_t
|_ test_node_field_1 : (5,) [ 1.57228445 -0.79812797 -0.74235336 -0.28304151 -1.1860188 ] float64 DataArray_t
|_ CellCenterFields : None FlowSolution_t
|_ GridLocation : (10,) CellCenter |S1 GridLocation_t
|_ OriginalIds : (3,) [1 2 3] int64 DataArray_t
|_ test_elem_field_1 : (3,) [-1.10621078 0.29662337 -1.18089037] float64 DataArray_t
|_ FamilyName : (2,) 2D |S1 FamilyName_t
|_ Time : (1,) [1] int32 BaseIterativeData_t
|_ IterationValues : (1,) [1] int32 DataArray_t
|_ TimeValues : (1,) [0.] float64 DataArray_t
# If time is specified as an argument in a function, it takes precedence over the default time.
sample.show_tree(0.0) # Print the tree at time 0.0 even if default time is 1.0
CGNSLibraryVersion : (1,) [4.] float32 CGNSLibraryVersion_t
SurfaceMesh : (2,) [2 3] int32 CGNSBase_t
|_ Time : (1,) [1] int32 BaseIterativeData_t
|_ IterationValues : (1,) [1] int32 DataArray_t
|_ TimeValues : (1,) [0.] float64 DataArray_t
|_ TestZoneName : (1, 3) [[5 3 0]] int64 Zone_t
|_ ZoneType : (12,) Unstructured |S1 ZoneType_t
|_ GridCoordinates : None GridCoordinates_t
|_ CoordinateX : (5,) [0. 1. 1. 0. 0.5] float64 DataArray_t
|_ CoordinateY : (5,) [0. 0. 1. 1. 1.5] float64 DataArray_t
|_ VertexFields : None FlowSolution_t
|_ GridLocation : (6,) Vertex |S1 GridLocation_t
|_ Pressure : (5,) [-1.54146993 2.65935437 1.09965842 -0.06759072 -0.3208659 ] float64 DataArray_t
|_ Temperature : (5,) [ 0.58177437 0.29638562 -0.17345189 0.27042681 1.23031369] float64 DataArray_t
Set and use default base and time in a Sample¶
# Reset default time
sample._default_active_time = None
# Without a provided default time, it searches the first time available in all mesh times
print(f"{sample.resolve_time() = }", end="\n\n")
# Create new bases
sample.init_base(1, 1, "new_base", 0.0)
print(f"{sample.get_topological_dim('new_base', 0.0) = }")
print(f"{sample.get_physical_dim('new_base', 0.0) = }")
sample.resolve_time() = 1.0
sample.get_topological_dim('new_base', 0.0) = 1
sample.get_physical_dim('new_base', 0.0) = 1
# Attempting to get a base when the default base is not set, and there are multiple bases available.
print(f"{sample.get_base_names() = }", end="\n\n")
try:
sample.resolve_base()
except KeyError as e:
print(str(e))
sample.get_base_names() = ['Base_2_2']
# Set default base and time
sample.set_default_base("SurfaceMesh", 0.0)
# Now that default base and time have been assigned, it is no longer necessary to specify them in function calls.
print(f"{sample.resolve_time() = }")
print(f"{sample.resolve_base() = }", end="\n\n")
# Print the topological and physical dim for the default base == 'SurfaceMesh'
print(f"{sample.get_topological_dim() = }")
print(f"{sample.get_physical_dim() = }")
sample.resolve_time() = 0.0
sample.resolve_base() = 'SurfaceMesh'
sample.get_topological_dim() = 2
sample.get_physical_dim() = 3
# If base is specified as an argument in a function, it takes precedence over the default base.
print(
f"{sample.get_physical_dim('new_base') = }"
) # Print the 'new_base' physical dim instead of the default base physical dim
sample.get_physical_dim('new_base') = 1
Set and use default base, zone and time in a Sample¶
import CGNS.PAT.cgnskeywords as CGK
# Reset default base and time
sample._default_active_time = None
sample._default_active_base = None
# Without a provided default time, it searches the first time available in all mesh times
print(f"{sample.resolve_time() = }", end="\n\n")
# Create a new zone in 'SurfaceMesh' base
sample.init_zone(
zone_shape=np.array([[5, 3, 0]]),
zone_type=CGK.Structured_s,
zone="new_zone",
base="SurfaceMesh",
)
print(f"{sample.get_zone_type('TestZoneName', 'SurfaceMesh') = }")
print(f"{sample.get_zone_type('new_zone', 'SurfaceMesh') = }")
sample.resolve_time() = 0.0
sample.get_zone_type('TestZoneName', 'SurfaceMesh') = 'Unstructured'
sample.get_zone_type('new_zone', 'SurfaceMesh') = 'Structured'
# Set default base
sample.set_default_base("SurfaceMesh")
# Attempting to get a zone when the default zone is not set, and there are multiple zones available in the default base.
print(f"{sample.get_zone_names() = }", end="\n\n")
try:
sample.resolve_zone()
except KeyError as e:
print(str(e))
sample.get_zone_names() = ['TestZoneName', 'new_zone']
"No default zone provided among ['TestZoneName', 'new_zone'] in the default base: SurfaceMesh"
# Reset default base and time
sample._default_active_time = None
sample._default_active_base = None
# Set default base, zone and time
sample.set_default_zone_base("TestZoneName", "SurfaceMesh", 0.0)
# Now that default base, zone and time have been assigned, it is no longer necessary to specify them in function calls.
print(f"{sample.resolve_time() = }")
print(f"{sample.resolve_base() = }")
print(f"{sample.resolve_zone() = }", end="\n\n")
# Print the type of the default zone (from the default base)
print(f"{sample.get_zone_type() = }")
# Print the default zone content (from the default base)
print(f"{sample.get_zone() = }")
sample.resolve_time() = 0.0
sample.resolve_base() = 'SurfaceMesh'
sample.resolve_zone() = 'TestZoneName'
sample.get_zone_type() = 'Unstructured'
sample.get_zone() = ['TestZoneName', array([[5, 3, 0]]), [['ZoneType', array([b'U', b'n', b's', b't', b'r', b'u', b'c', b't', b'u', b'r', b'e',
b'd'], dtype='|S1'), [], 'ZoneType_t'], ['GridCoordinates', None, [['CoordinateX', array([0. , 1. , 1. , 0. , 0.5]), [], 'DataArray_t'], ['CoordinateY', array([0. , 0. , 1. , 1. , 1.5]), [], 'DataArray_t']], 'GridCoordinates_t'], ['VertexFields', None, [['GridLocation', array([b'V', b'e', b'r', b't', b'e', b'x'], dtype='|S1'), [], 'GridLocation_t'], ['Pressure', array([-1.54146993, 2.65935437, 1.09965842, -0.06759072, -0.3208659 ]), [], 'DataArray_t'], ['Temperature', array([ 0.58177437, 0.29638562, -0.17345189, 0.27042681, 1.23031369]), [], 'DataArray_t']], 'FlowSolution_t']], 'Zone_t']
# If zone is specified as an argument in a function, it takes precedence over the default zone.
print(
f"{sample.get_zone_type('new_zone') = }"
) # Print the 'new_zone' type instead of the default zone type
sample.get_zone_type('new_zone') = 'Structured'
More information on how default values work¶
from IPython.display import Image
try:
filename = (
Path(__file__).parent.parent.parent
/ "docs"
/ "source"
/ "images"
/ "default_value_selection.png"
)
except NameError:
filename = Path("..") / ".." / "images" / "default_value_selection.png"
Image(filename=filename)

Section 2.4: Saving and Loading Sample¶
This section demonstrates how to save and load a Sample from a directory.
Save Sample to as a file tree¶
test_pth = Path(
f"/tmp/test_safe_to_delete_{np.random.randint(low=1, high=2_000_000_000)}"
)
test_pth.mkdir(parents=True, exist_ok=True)
sample_save_fname = test_pth / "test"
print(f"saving path: {sample_save_fname}")
sample.save_to_dir(sample_save_fname)
saving path: /tmp/test_safe_to_delete_861754285/test
Load a Sample from a directory via the Sample class¶
new_sample_from_dir = Sample.load_from_dir(sample_save_fname)
print(new_sample_from_dir.summarize())
Sample Summary:
==================================================
Meshes (1 timestamps):
Time: 0.0
Base: Base_2_2
Zone: Zone
Nodes (5)
Location: Vertex
Fields (2): OriginalIds, test_node_field_1
Location: CellCenter
Fields (2): OriginalIds, test_elem_field_1
Elements (3)
TRI_3 (3)
Load the Sample from a directory via a Sample instance¶
new_sample_via_instance = Sample()
new_sample_via_instance.load(sample_save_fname)
print(new_sample_via_instance.summarize())
Sample Summary:
==================================================
Meshes (1 timestamps):
Time: 0.0
Base: Base_2_2
Zone: Zone
Nodes (5)
Location: Vertex
Fields (2): OriginalIds, test_node_field_1
Location: CellCenter
Fields (2): OriginalIds, test_elem_field_1
Elements (3)
TRI_3 (3)