Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- (sample/features) add_field: check field size consistency with geometrical support.

### Changed

### Fixes
Expand Down
3 changes: 2 additions & 1 deletion examples/containers/bench_parallel_load.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@
# ---# Add some random data
smp.add_scalar("id", i)
smp.add_scalar("s0", np.random.randn())
smp.add_field("f0", np.random.randn(100))
n_nodes = smp.get_nodes().shape[0]
smp.add_field("f0", np.random.randn(n_nodes))

dset.add_sample(smp)

Expand Down
4 changes: 2 additions & 2 deletions examples/containers/sample_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def show_sample(sample: Sample):

# %%
# Init CGNS tree zone to a base at time 0.
shape = np.array((len(points), len(triangles), 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)
Expand Down Expand Up @@ -454,7 +454,7 @@ def show_sample(sample: Sample):

# Create a new zone in 'SurfaceMesh' base
sample.init_zone(
zone_shape=np.array([5, 3, 0]),
zone_shape=np.array([[5, 3, 0]]),
zone_type=CGK.Structured_s,
zone_name="new_zone",
base_name="SurfaceMesh",
Expand Down
2 changes: 1 addition & 1 deletion examples/convert_users_data_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ def in_notebook():

# Add random field values to the sample
for j, sname in enumerate(out_fields_names):
sample.add_field(sname, np.random.rand(1, len(nodes_3D)))
sample.add_field(sname, np.random.rand(len(nodes_3D)))

samples.append(sample)

Expand Down
10 changes: 6 additions & 4 deletions examples/utils/stats_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,9 @@ def sprint(stats: dict):
for sample in samples:
sample.add_scalar("test_scalar", np.random.randn())
sample.init_base(2, 3, "test_base")
zone_shape = np.array([0, 0, 0])
zone_shape = np.array([[spatial_shape_max, 0, 0]])
sample.init_zone(zone_shape, zone_name="test_zone")
sample.set_nodes(np.zeros((spatial_shape_max, 3)))
sample.add_field("test_field", np.random.randn(spatial_shape_max))

stats.add_samples(samples)
Expand All @@ -154,12 +155,13 @@ def sprint(stats: dict):
for sample in samples:
sample.add_scalar("test_scalar", np.random.randn())
sample.init_base(2, 3, "test_base")
zone_shape = np.array([0, 0, 0])
zone_shape = np.array([[spatial_shape_max, 0, 0]])
sample.init_zone(zone_shape, zone_name="test_zone")
sample.add_field("test_field_same_size", np.random.randn(7))
sample.set_nodes(np.zeros((spatial_shape_max, 3)))
sample.add_field("test_field_same_size", np.random.randn(spatial_shape_max))
sample.add_field(
"test_field",
np.random.randn(np.random.randint(spatial_shape_max // 2, spatial_shape_max)),
np.random.randn(spatial_shape_max),
)

stats.add_samples(samples)
Expand Down
15 changes: 15 additions & 0 deletions src/plaid/containers/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -1174,6 +1174,10 @@ def add_field(
KeyError: Raised if the specified zone does not exist in the given base.
"""
assert isinstance(field, np.ndarray)
if field.ndim != 1:
raise ValueError(
f"field has {field.ndim} dimensions, but must be a 1D array."
)
_check_names([name])
# init_tree will look for default time
self.init_tree(time)
Expand All @@ -1185,6 +1189,17 @@ def add_field(
f"there is no Zone with name {zone_name} in base {base_name}. Did you check topological and physical dimensions ?"
)

# Check field size consistency with its geometrical support
n_nodes, n_elems, _ = zone_node[1][0]
if location == "Vertex" and field.shape[0] != n_nodes:
raise ValueError(
f"field has {field.shape[0]} nodes but zone has {n_nodes} nodes (based on the zone node metadata)"
)
elif location == "CellCenter" and field.shape[0] != n_elems:
raise ValueError(
f"field has {field.shape[0]} nodes but zone has {n_elems} elements (based on the zone node metadata)"
)

if field.dtype in (np.int32, np.int64):
logger.warning(
f"(add_field) provided field is of type {field.dtype} and has been converted to np.float64 for CGNS compatibility."
Expand Down
9 changes: 6 additions & 3 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ def generate_samples_no_string(nb: int, zone_name: str, base_name: str) -> list[
for i in range(nb):
sample = Sample()
sample.init_base(3, 3, base_name)
sample.init_zone(np.array([0, 0, 0]), zone_name=zone_name, base_name=base_name)
sample.init_zone(
np.array([[17, 10, 0]]), zone_name=zone_name, base_name=base_name
)
sample.add_scalar("test_scalar", float(i))
sample.add_scalar("test_scalar_2", float(i**2))
sample.add_global("global_0", 0.5 + np.ones((2, 3)))
Expand All @@ -41,9 +43,10 @@ def generate_samples_no_string(nb: int, zone_name: str, base_name: str) -> list[
)
sample.add_field(
name="test_field_2785",
field=float(i**5) * np.ones(3 * (i + 1)),
field=float(i**5) * np.ones(10),
zone_name=zone_name,
base_name=base_name,
location="CellCenter",
)
sample_list.append(sample)
return sample_list
Expand Down Expand Up @@ -150,7 +153,7 @@ def muscat_mesh(nodes, triangles, vertex_field, cell_center_field, nodal_tags):
muscat_mesh = MCT.CreateMeshOfTriangles(nodes, triangles)
muscat_mesh.GetNodalTag("tag").AddToTag(nodal_tags)
muscat_mesh.nodeFields["test_node_field_1"] = vertex_field
muscat_mesh.nodeFields["big_node_field"] = np.random.randn(50)
muscat_mesh.nodeFields["big_node_field"] = np.random.randn(5)
muscat_mesh.elemFields["test_elem_field_1"] = cell_center_field
return muscat_mesh

Expand Down
17 changes: 11 additions & 6 deletions tests/containers/test_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ def test_get_field_names(self, dataset_with_samples, nb_samples):
) == sorted(["test_field_2785", "test_field_same_size"])
assert sorted(
dataset_with_samples.get_field_names(location="Vertex")
) == sorted(["test_field_2785", "test_field_same_size"])
) == sorted(["test_field_same_size"])
assert sorted(
dataset_with_samples.get_field_names(zone_name="Zone_Name")
) == sorted(["test_field_2785", "test_field_same_size"])
Expand Down Expand Up @@ -745,13 +745,13 @@ def test_get_tabular_from_homogeneous_identifiers_inconsistent_features_through_
dataset_with_samples_with_tree_ = copy.deepcopy(dataset_with_samples_with_tree)
for sample in dataset_with_samples_with_tree_:
sample.add_field(
"test_node_field_1", np.array([0, 1]), warning_overwrite=False
"test_node_field_1", np.array([0, 1, 2, 3, 4]), warning_overwrite=False
)
with pytest.raises(AssertionError):
dataset_with_samples_with_tree_.get_tabular_from_homogeneous_identifiers(
feature_identifiers=[
FeatureIdentifier({"type": "field", "name": "test_node_field_1"}),
FeatureIdentifier({"type": "field", "name": "OriginalIds"}),
FeatureIdentifier({"type": "field", "name": "test_elem_field_1"}),
],
)

Expand All @@ -760,16 +760,21 @@ def test_get_tabular_from_homogeneous_identifiers_inconsistent_features_through_
):
dataset_with_samples_with_tree_ = copy.deepcopy(dataset_with_samples_with_tree)
dataset_with_samples_with_tree_[0].add_field(
"test_node_field_1", np.array([0, 1]), warning_overwrite=False
"test_node_field_1",
np.array([0, 1, 2, 3, 4], dtype=np.float32),
warning_overwrite=False,
)
dataset_with_samples_with_tree_[0].add_field(
"OriginalIds", np.array([0, 1]), warning_overwrite=False
"OriginalIds",
np.array([0, 1, 2], dtype=np.float32),
location="CellCenter",
warning_overwrite=False,
)
with pytest.raises(AssertionError):
dataset_with_samples_with_tree_.get_tabular_from_homogeneous_identifiers(
feature_identifiers=[
FeatureIdentifier({"type": "field", "name": "test_node_field_1"}),
FeatureIdentifier({"type": "field", "name": "OriginalIds"}),
FeatureIdentifier({"type": "field", "name": "test_elem_field_1"}),
],
)

Expand Down
Loading
Loading