Sample Examples¶
This Jupyter Notebook demonstrates various operations and methods involving a sample data structure using the PLAID library. It includes examples of:
Initializing an Empty Sample and Adding Data
Accessing and Modifying Sample Data
Set and Get default values
Saving and Loading Samples
This notebook provides detailed examples of using the Sample class to manage and manipulate sample data structures.
Each section is documented and explained.
# Import required libraries
from pathlib import Path
import numpy as np
# Import necessary libraries and functions
import CGNS.PAT.cgnskeywords as CGK
from Muscat.Bridges.CGNSBridge import MeshToCGNS
from Muscat.MeshTools import MeshCreationTools as MCT
from plaid import Sample
from plaid.utils import cgns_helper as CGH
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
# Print Sample util
def show_sample(sample: Sample):
print(f"sample = {sample}")
sample.show_tree()
print(f"{sample.get_scalar_names() = }")
print(f"{sample.get_field_names() = }")
Section 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
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,) [-0.18230699 0.20132337 -0.35795691 0.30930634 -1.71411408] 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,) [ 0.73251128 -0.09362226 0.14392204] 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")
show_sample(sample)
#---# Empty Sample
Sample(0 globals, 0 timestamps, 0 fields)
sample = Sample(0 globals, 0 timestamps, 0 fields)
sample.get_scalar_names() = []
sample.get_field_names() = []
Add a scalars to a Sample¶
# Add a rotation scalar to this Sample
sample.add_scalar("rotation", np.random.randn())
show_sample(sample)
sample = Sample(1 global, 1 timestamp, 0 fields)
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.12480164] float64 DataArray_t
sample.get_scalar_names() = ['rotation']
sample.get_field_names() = []
# Add a more scalars to this Sample
sample.add_scalar("speed", np.random.randn())
sample.add_scalar("other", np.random.randn())
show_sample(sample)
sample = Sample(3 globals, 1 timestamp, 0 fields)
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.12480164] float64 DataArray_t
|_ speed : (1,) [0.03616332] float64 DataArray_t
|_ other : (1,) [-0.49013933] float64 DataArray_t
sample.get_scalar_names() = ['rotation', 'speed', 'other']
sample.get_field_names() = []
Add a CGNS Tree to a Sample and display it¶
# Add the previously created CGNS tree to the sample
sample.features.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.12480164] float64 DataArray_t
|_ speed : (1,) [0.03616332] float64 DataArray_t
|_ other : (1,) [-0.49013933] 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,) [-0.18230699 0.20132337 -0.35795691 0.30930634 -1.71411408] 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,) [ 0.73251128 -0.09362226 0.14392204] 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.features.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: 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)
show_sample(sample)
#---# Empty Sample
Sample(0 globals, 0 timestamps, 0 fields)
sample = Sample(0 globals, 1 timestamp, 0 fields)
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
sample.get_scalar_names() = []
sample.get_field_names() = []
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_name="TestZoneName", base_name="SurfaceMesh", time=0.0)
show_sample(sample)
sample = Sample(0 globals, 1 timestamp, 0 fields)
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 : (3,) [5 3 0] int64 Zone_t
|_ ZoneType : (12,) Unstructured |S1 ZoneType_t
sample.get_scalar_names() = []
sample.get_field_names() = []
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_points == set_nodes == set_vertices
sample.set_nodes(points, base_name="SurfaceMesh", zone_name="TestZoneName", time=0.0)
show_sample(sample)
sample = Sample(0 globals, 1 timestamp, 0 fields)
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 : (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
sample.get_scalar_names() = []
sample.get_field_names() = []
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_name="SurfaceMesh",
zone_name="TestZoneName",
time=0.0,
)
show_sample(sample)
sample = Sample(0 globals, 1 timestamp, 1 field)
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 : (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,) [-0.16839151 0.56414076 2.30755068 0.54676417 -0.19702951] float64 DataArray_t
sample.get_scalar_names() = []
sample.get_field_names() = ['Pressure']
# Add another field
sample.add_field(
"Temperature",
np.random.randn(len(points)),
base_name="SurfaceMesh",
zone_name="TestZoneName",
time=0.0,
)
show_sample(sample)
sample = Sample(0 globals, 1 timestamp, 2 fields)
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 : (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,) [-0.16839151 0.56414076 2.30755068 0.54676417 -0.19702951] float64 DataArray_t
|_ Temperature : (5,) [ 0.21642966 -0.04592594 -1.24979778 0.12633374 -0.20706711] float64 DataArray_t
sample.get_scalar_names() = []
sample.get_field_names() = ['Pressure', 'Temperature']
Access scalars data in Sample¶
# It will look for a default base if no base and zone are given
print(f"{sample.get_scalar_names() = }")
print(f"{sample.get_scalar('omega') = }")
print(f"{sample.get_scalar('rotation') = }")
sample.get_scalar_names() = []
sample.get_scalar('omega') = None
sample.get_scalar('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.21642966, -0.04592594, -1.24979778, 0.12633374, -0.20706711])
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.features.get_points() = }") # same as get_nodes
print(f"{sample.features.get_vertices() = }") # same as get_nodes
sample.get_nodes() = array([[0. , 0. ],
[1. , 0. ],
[1. , 1. ],
[0. , 1. ],
[0.5, 1.5]])
sample.features.get_points() = array([[0. , 0. ],
[1. , 0. ],
[1. , 1. ],
[0. , 1. ],
[0.5, 1.5]])
sample.features.get_vertices() = 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.features.add_tree(tree)
print("element connectivity = \n", f"{tmp_sample.features.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.features.get_base_names()
# Get full base path
full_bases_names = sample.features.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.features.get_base_names()[0]
# Get base node
base_node_content = sample.features.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([-0.16839151, 0.56414076, 2.30755068, 0.54676417, -0.19702951]), [], 'DataArray_t'], ['Temperature', array([ 0.21642966, -0.04592594, -1.24979778, 0.12633374, -0.20706711]), [], 'DataArray_t']], 'FlowSolution_t']], 'Zone_t']], 'CGNSBase_t']
Check if a base exists in a Sample¶
# Get the first base name
base_name = sample.features.get_base_names()[0]
print(f"{sample.features.has_base(base_name) = }")
print(f"{sample.features.has_base('unknown_base_name') = }")
sample.features.has_base(base_name) = True
sample.features.has_base('unknown_base_name') = False
Access the available zone from a CGNS tree base¶
# Get the first base name
base_name = sample.features.get_base_names()[0]
# Get zones associated with the first base
zones_names = sample.features.get_zone_names(base_name)
# Get full path of zones associated with the first base
full_zones_names = sample.features.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.features.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([-0.16839151, 0.56414076, 2.30755068, 0.54676417, -0.19702951]), [], 'DataArray_t'], ['Temperature', array([ 0.21642966, -0.04592594, -1.24979778, 0.12633374, -0.20706711]), [], '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.features.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.features.has_zone(zone_name, base_name) = }")
print(f"{sample.features.has_zone('unknown_zone_name', base_name) = }")
sample.features.has_zone(zone_name, base_name) = True
sample.features.has_zone('unknown_zone_name', base_name) = False
Get mesh from sample¶
sample_mesh = sample.get_tree()
print(sample_mesh)
['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([-0.16839151, 0.56414076, 2.30755068, 0.54676417, -0.19702951]), [], 'DataArray_t'], ['Temperature', array([ 0.21642966, -0.04592594, -1.24979778, 0.12633374, -0.20706711]), [], 'DataArray_t']], 'FlowSolution_t']], 'Zone_t']], 'CGNSBase_t']], 'CGNSTree_t']
Get all mesh time available in Sample¶
# Before adding new tree
print(f"{sample.features.get_all_time_values() = }")
# Add one CGNS tree at time 1.
sample.features.add_tree(tree, 1.0)
# After adding new tree
print(f"{sample.features.get_all_time_values() = }")
sample.features.get_all_time_values() = [0.0]
sample.features.get_all_time_values() = [0.0, 1.0]
Creating a Sample Hierarchy with bases, zones, and associated data.¶
bases_names = sample.features.get_base_names()
full_bases_names = sample.features.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.features.get_zone_names(b_name)
full_zones_names = sample.features.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.features.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 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.features.get_all_time_values() = }")
print(f"{sample.features.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.features.resolve_time() = }", end="\n\n")
# Print the tree at time 1.0
sample.show_tree() # == sample.show_tree(1.0)
sample.features.get_all_time_values() = [0.0, 1.0]
sample.features.resolve_time() = 0.0
sample.features.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,) [-0.18230699 0.20132337 -0.35795691 0.30930634 -1.71411408] 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,) [ 0.73251128 -0.09362226 0.14392204] 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 : (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,) [-0.16839151 0.56414076 2.30755068 0.54676417 -0.19702951] float64 DataArray_t
|_ Temperature : (5,) [ 0.21642966 -0.04592594 -1.24979778 0.12633374 -0.20706711] float64 DataArray_t
Set and use default base and time in a Sample¶
# Reset default time
sample.features._default_active_time = None
# Without a provided default time, it searches the first time available in all mesh times
print(f"{sample.features.resolve_time() = }", end="\n\n")
# Create new bases
sample.init_base(1, 1, "new_base", 0.0)
print(f"{sample.features.get_topological_dim('new_base', 0.0) = }")
print(f"{sample.features.get_physical_dim('new_base', 0.0) = }")
sample.features.resolve_time() = 1.0
sample.features.get_topological_dim('new_base', 0.0) = np.int32(1)
sample.features.get_physical_dim('new_base', 0.0) = np.int32(1)
# Attempting to get a base when the default base is not set, and there are multiple bases available.
print(f"{sample.features.get_base_names() = }", end="\n\n")
try:
sample.features.resolve_base()
except KeyError as e:
print(str(e))
sample.features.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.features.resolve_time() = }")
print(f"{sample.features.resolve_base() = }", end="\n\n")
# Print the topological and physical dim for the default base == 'SurfaceMesh'
print(f"{sample.features.get_topological_dim() = }")
print(f"{sample.features.get_physical_dim() = }")
sample.features.resolve_time() = 0.0
sample.features.resolve_base() = 'SurfaceMesh'
sample.features.get_topological_dim() = np.int32(2)
sample.features.get_physical_dim() = np.int32(3)
# If base is specified as an argument in a function, it takes precedence over the default base.
print(
f"{sample.features.get_physical_dim('new_base') = }"
) # Print the 'new_base' physical dim instead of the default base physical dim
sample.features.get_physical_dim('new_base') = np.int32(1)
Set and use default base, zone and time in a Sample¶
# Reset default base and time
sample.features._default_active_time = None
sample.features._default_active_base = None
# Without a provided default time, it searches the first time available in all mesh times
print(f"{sample.features.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_name="new_zone",
base_name="SurfaceMesh",
)
print(f"{sample.features.get_zone_type('TestZoneName', 'SurfaceMesh') = }")
print(f"{sample.features.get_zone_type('new_zone', 'SurfaceMesh') = }")
sample.features.resolve_time() = 0.0
sample.features.get_zone_type('TestZoneName', 'SurfaceMesh') = 'Unstructured'
sample.features.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.features.get_zone_names() = }", end="\n\n")
try:
sample.features.resolve_zone()
except KeyError as e:
print(str(e))
sample.features.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.features._default_active_time = None
sample.features._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.features.resolve_time() = }")
print(f"{sample.features.resolve_base() = }")
print(f"{sample.features.resolve_zone() = }", end="\n\n")
# Print the type of the default zone (from the default base)
print(f"{sample.features.get_zone_type() = }")
# Print the default zone content (from the default base)
print(f"{sample.features.get_zone() = }")
sample.features.resolve_time() = 0.0
sample.features.resolve_base() = 'SurfaceMesh'
sample.features.resolve_zone() = 'TestZoneName'
sample.features.get_zone_type() = 'Unstructured'
sample.features.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([-0.16839151, 0.56414076, 2.30755068, 0.54676417, -0.19702951]), [], 'DataArray_t'], ['Temperature', array([ 0.21642966, -0.04592594, -1.24979778, 0.12633374, -0.20706711]), [], '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.features.get_zone_type('new_zone') = }"
) # Print the 'new_zone' type instead of the default zone type
sample.features.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 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(sample_save_fname)
saving path: /tmp/test_safe_to_delete_1669366265/test
Load a Sample from a directory via initialization¶
new_sample = Sample(path=sample_save_fname)
show_sample(new_sample)
sample = Sample(0 globals, 1 timestamp, 3 fields)
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,) [-0.18230699 0.20132337 -0.35795691 0.30930634 -1.71411408] 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,) [ 0.73251128 -0.09362226 0.14392204] 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
sample.get_scalar_names() = []
sample.get_field_names() = ['OriginalIds', 'test_elem_field_1', 'test_node_field_1']
Load a Sample from a directory via the Sample class¶
new_sample_2 = Sample.load_from_dir(test_pth / "test")
show_sample(new_sample_2)
sample = Sample(0 globals, 1 timestamp, 3 fields)
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,) [-0.18230699 0.20132337 -0.35795691 0.30930634 -1.71411408] 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,) [ 0.73251128 -0.09362226 0.14392204] 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
sample.get_scalar_names() = []
sample.get_field_names() = ['OriginalIds', 'test_elem_field_1', 'test_node_field_1']
Load the Sample from a directory via a Sample instance¶
new_sample = Sample()
new_sample.load(sample_save_fname)
show_sample(new_sample)
sample = Sample(0 globals, 1 timestamp, 3 fields)
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,) [-0.18230699 0.20132337 -0.35795691 0.30930634 -1.71411408] 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,) [ 0.73251128 -0.09362226 0.14392204] 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
sample.get_scalar_names() = []
sample.get_field_names() = ['OriginalIds', 'test_elem_field_1', 'test_node_field_1']