Skip to content

Commit

Permalink
Create coordset using computed extent (#1053)
Browse files Browse the repository at this point in the history
* Create coordset using computed extent, after padding user's requested data extent

* Document changes.

* Expand doxygen with ascii art and more commentary

* Orient ASCII art the same way the array is printed out.

* Fix a doubled line.

* More clarifications.

* Fix topo stride

* Clarifying rephrase.

* save out underlying points as topology and field data as assoced with the point topo so we can plot for debugging

Co-authored-by: Cyrus Harrison <cyrush@llnl.gov>
  • Loading branch information
agcapps and cyrush committed Dec 21, 2022
1 parent 8fe1519 commit 09770be
Show file tree
Hide file tree
Showing 4 changed files with 220 additions and 58 deletions.
19 changes: 14 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,20 @@ and this project aspires to adhere to [Semantic Versioning](https://semver.org/s
### Added
#### General
- Added Node::move and Node::swap methods, which provide efficient ways to help build Node trees by consuming other Nodes.
- Added Node::reset methods to C and Fortran interfaces
- Added support for Wedges and Pyramids to Blueprint.
- Added Node::reset methods to C and Fortran interfaces

#### Blueprint
- Added support for Wedges and Pyramids
- Added helper function `blueprint::mesh::generate_strip` to generate a 2D "strip mesh" topology, and dependent other Blueprint mesh parts, from a 1D mesh.

### Changed
#### General
- Updated to BLT v0.5.2
- Updated to BLT v0.5.2

### Fixed
#### Blueprint
- Fixed bug with `blueprint::mesh::examples::strided_structured` so it correctly generates a coordset with padding
- Fixes (correctness and performance) to `topology::unstructured::generate_offsets`
- Changed `Schema::has_path()` (and transitively `Node::has_path()` ) to ignore leading `/`s.

### Fixed
Expand All @@ -27,6 +35,7 @@ and this project aspires to adhere to [Semantic Versioning](https://semver.org/s
- Updated `conduit.relay.io.blueprint.{load_mesh|read_mesh} to only the read the necessary subset of root file entries. Updated MPI version to only read root file entries on rank 0 and broadcast them to other ranks.



## [0.8.4] - Released 2022-08-22

### Added
Expand All @@ -38,7 +47,7 @@ and this project aspires to adhere to [Semantic Versioning](https://semver.org/s
- Added Schema and Python Buffer variants to Python `Node.set()` and `Node.set_external()`.

#### Blueprint
- Added `blueprint::mesh::paint_adjset`, which paints fields that encode adjacency set counts and ordering details.
- Added `blueprint::mesh::paint_adjset`, which paints fields that encode adjacency set counts and ordering details.
- Added `blueprint::mesh::examples::strided_structured` which creates a structured mesh with arbitrarily strided vertex and element fields.
- Added support for mixed element topologies to the mesh blueprint.
- Added `blueprint::mesh::examples::braid` examples with mixed element topologies (`mesh_type={"mixed", "mixed_2d"}`)
Expand Down Expand Up @@ -75,7 +84,7 @@ and this project aspires to adhere to [Semantic Versioning](https://semver.org/s
#### Blueprint
- Fixed a bug with `blueprint::mesh::index::generate`, where a uniform grid with no origin would lead to invalid coordinate system name `logical` in the resulting index. This case now defaults to `cartesian`.
- Improved `relay::io::blueprint::{save_mesh|write_mesh}` blueprint index generation for cases where fields do not exist on all domains.
- Fixed a bug that labeled internal faces as shared in generated adjsets.
- Fixed a bug that labeled internal faces as shared in generated adjsets.

#### Relay
- Fixed a bug with blueprint root file creation, where the `file_pattern` was not relative to the root file location
Expand Down
58 changes: 29 additions & 29 deletions src/libs/blueprint/conduit_blueprint_mesh_examples.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3374,46 +3374,46 @@ strided_structured(Node &desc, // shape of requested data arrays
}

braid_init_example_state(res);
braid_init_explicit_coordset(npts_x,
npts_y,
npts_z,
braid_init_explicit_coordset(pts_extent[0],
pts_extent[1],
pts_extent[2],
res["coordsets/coords"]);

res["topologies/mesh/type"] = "structured";
res["topologies/mesh/coordset"] = "coords";

Node &dims = res["topologies/mesh/elements/dims"];
Node &dims = res["topologies/mesh/elements/dims"];

dims["i"] = (int32)nele_x;
dims["j"] = (int32)nele_y;
dims["j"] = (int32)nele_y;
if(nele_z > 0)
{
dims["k"] = (int32)nele_z;
dims["k"] = (int32)nele_z;
}

index_t dimensions = 2;
if (npts_z > 0)
{
dimensions += 1;
}
dims["offsets"].set(DataType::int32(dimensions));
dims["strides"].set(DataType::int32(dimensions));
int32 *offsets = dims["offsets"].value();
int32 *strides = dims["strides"].value();
// fill offsets
offsets[0] = ele_origin[0];
offsets[1] = ele_origin[1];
if (npts_z > 0)
{
offsets[2] = ele_origin[2];
}
// fill strides
strides[0] = 1;
strides[1] = strides[0] * ele_extent[0];
if (npts_z > 0)
{
strides[2] = strides[1] * ele_extent[1];
}
index_t dimensions = 2;
if (npts_z > 0)
{
dimensions += 1;
}
dims["offsets"].set(DataType::int32(dimensions));
dims["strides"].set(DataType::int32(dimensions));
int32 *offsets = dims["offsets"].value();
int32 *strides = dims["strides"].value();
// fill offsets
offsets[0] = ele_origin[0];
offsets[1] = ele_origin[1];
if (npts_z > 0)
{
offsets[2] = ele_origin[2];
}
// fill strides
strides[0] = 1;
strides[1] = strides[0] * pts_extent[0];
if (npts_z > 0)
{
strides[2] = strides[1] * pts_extent[1];
}

Node &fields = res["fields"];

Expand Down
140 changes: 116 additions & 24 deletions src/libs/blueprint/conduit_blueprint_mesh_examples.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,12 @@ namespace examples
conduit::index_t nz,
conduit::Node &res);

/// Generates a structured grid with an element field and a vertex field,
/// each element of which contains a sequentially increasing value.
/// Calling code can specify the shape of the storage array for the fields.
/// Pass the extra specifications with a conduit::Node:
/// Generates a strided structured grid with an element field and a vertex
/// field, each element of which contains a sequentially increasing value.
/// Calling code can specify the shape of the storage array for the fields
/// and the location of the field values within the array.
///
/// Pass the extra specifications with a conduit::Node desc:
///
/// \code{.yaml}
/// vertex_data:
Expand All @@ -72,14 +74,104 @@ namespace examples
/// too small to contain the requested mesh data at the specified
/// origin.
///
/// For example, if the function were called like this:
/// The following example shows how to produce a structured grid with 3x2
/// elements for data and two elements padding each end of each dimension.
/// Thus, element field values will be located at origin (2, 2) in a 7x6
/// array.
///
/// We will also use a custom-sized array for vertex fields. In other
/// Blueprint meshes, fields over vertices are stored in arrays larger by
/// one element in each dimension than arrays that store fields over
/// elements. In strided structured meshes, the array dimensions of vertex
/// and element fields are decoupled. In this example, vertex fields will
/// use a 7x6 array, not an 8x7 array as required by other Blueprint meshes.
/// Since there are 3x2 mesh elements, there will be 4x3 vertex field
/// values. To match the element fields' padding as closely as possible,
/// the vertex field values are located at origin (2, 2).
///
/// The diagram below shows the mesh. Note that the diagram origin is at
/// the top left. For elements, a space indicates a padding element and a
/// `d` indicates a data element. For vertices, an `o` indicates a padding
/// vertex, an asterisk `*` indicates a data vertex, and a space indicates a
/// mesh vertex that has no field data.
///
/// \verbatim
/// o--o--o--o--o--o--o--
/// | | | | | | | |
/// o--o--o--o--o--o--o--
/// | | | | | | | |
/// o--o--*--*--*--*--o--
/// | | |d |d |d | | |
/// o--o--*--*--*--*--o--
/// | | |d |d |d | | |
/// o--o--*--*--*--*--o--
/// | | | | | | | |
/// o--o--o--o--o--o--o--
/// | | | | | | | |
/// -- -- -- -- -- -- --
/// \endverbatim
///
/// In summary, this will be a mesh with 4x3 vertices (therefore, 3x2
/// elements). The shape of each array storing a vertex field will be
/// [7, 6, 0] with a data origin of [2, 2, 0]. The shape of each array
/// storing a field over elements will be [7, 6, 0] with a data origin of
/// [2, 2, 0].
///
/// Here is code to produce this mesh.
/// \code
/// conduit::Node desc; // empty description node: use default shape and origin
/// // Data mesh dimensions (the part we care about, not the padding)
/// index_t npts_x = 4;
/// index_t npts_y = 3;
/// index_t npts_z = 0;
///
/// index_t nelts_x = npts_x - 1;
/// index_t nelts_y = npts_y - 1;
/// index_t nelts_z = 0;
///
/// // Total padding in each dimension
/// index_t total_elt_pad = 4; // two on each end
/// index_t total_pt_pad = 3; // two on the low end, one on the high end
///
/// // Origin: where the data starts in the arrays
/// index_t origin_x = 2;
/// index_t origin_y = 2;
///
/// // A mesh with "two elements of padding and equal sized element and vertex
/// // field arrays" is a common use case. It is the default that will be produced
/// // if code passes an empty desc node to strided_structured().
///
/// conduit::Node desc; // description node
/// conduit::Node res; // result node will contain mesh
/// strided_structured(desc, 3, 2, 0, res);
///
/// // Equivalently, we can fill in the description node:
///
/// desc["vertex_data/shape"].set(DataType::index_t(3));
/// index_t_array vertex_shape = desc["vertex_data/shape"].as_index_t_array();
/// vertex_shape[0] = npts_x + total_pt_pad;
/// vertex_shape[1] = npts_y + total_pt_pad;
/// vertex_shape[2] = 0;
/// desc["vertex_data/origin"].set(DataType::index_t(3));
/// index_t_array vertex_origin = desc["vertex_data/origin"].as_index_t_array();
/// vertex_origin[0] = origin_x;
/// vertex_origin[1] = origin_y;
/// vertex_origin[2] = 0;
/// desc["element_data/shape"].set(DataType::index_t(3));
/// index_t_array element_shape = desc["element_data/shape"].as_index_t_array();
/// element_shape[0] = nelts_x + total_elt_pad;
/// element_shape[1] = nelts_y + total_elt_pad;
/// element_shape[2] = 0;
/// desc["element_data/origin"].set(DataType::index_t(3));
/// index_t_array element_origin = desc["element_data/origin"].as_index_t_array();
/// element_origin[0] = origin_x;
/// element_origin[1] = origin_y;
/// element_origin[2] = 0;
///
/// // Generate the mesh into res
/// strided_structured(desc, npts_x, npts_y, npts_z, res);
/// \endcode
///
/// the node `res` would contain the following structure:
/// The node `res` will contain the following structure (edited slightly
/// for clarity):
/// \verbatim
/// state:
/// time: 3.1415
Expand All @@ -88,18 +180,18 @@ namespace examples
/// coords:
/// type: "explicit"
/// values:
/// x: [-2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0,
/// -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0,
/// -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0,
/// -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0,
/// -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0,
/// -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0]
/// y: [-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0,
/// 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
/// 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
/// 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
/// 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0,
/// 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0]
/// x: [-10.0, -6.67, -3.33, 0.0, 3.33, 6.67, 10.0,
/// -10.0, -6.67, -3.33, 0.0, 3.33, 6.67, 10.0,
/// -10.0, -6.67, -3.33, 0.0, 3.33, 6.67, 10.0,
/// -10.0, -6.67, -3.33, 0.0, 3.33, 6.67, 10.0,
/// -10.0, -6.67, -3.33, 0.0, 3.33, 6.67, 10.0,
/// -10.0, -6.67, -3.33, 0.0, 3.33, 6.67, 10.0]
/// y: [-10.0, -10.0, -10.0, -10.0, -10.0, -10.0, -10.0,
/// -6.0, -6.0, -6.0, -6.0, -6.0, -6.0, -6.0,
/// -2.0, -2.0, -2.0, -2.0, -2.0, -2.0, -2.0,
/// 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
/// 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0,
/// 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0]
/// topologies:
/// mesh:
/// type: "structured"
Expand Down Expand Up @@ -155,11 +247,11 @@ namespace examples
/// - `strides` tells how big the `values` array is.
/// - `offsets` tells where to start looking within `values`.
/// - The size of the mesh named by `topology` tells what elements to use
/// from `array`. Anything outside that is ignored.
/// from `array`. Any array element outside this range is ignored.
void CONDUIT_BLUEPRINT_API strided_structured(conduit::Node &desc,
conduit::index_t nx,
conduit::index_t ny,
conduit::index_t nz,
conduit::index_t npts_x,
conduit::index_t npts_y,
conduit::index_t npts_z,
conduit::Node &res);

/// Generates a multidomain uniform grid of 'basic' examples for each
Expand Down
61 changes: 61 additions & 0 deletions src/tests/blueprint/t_blueprint_mesh_examples.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,21 @@ TEST(conduit_blueprint_mesh_examples, strided_structured_2d)
EXPECT_TRUE(blueprint::mesh::verify(res, info));
CONDUIT_INFO(info.to_yaml());

// also add a topo that shows the orig points
// and fields assoced with orig points for debugging
res["topologies/orig_pts/type"] = "points";
res["topologies/orig_pts/coordset"] = "coords";

res["fields/orig_vert_vals"] = res["fields/vert_vals"];
res["fields/orig_vert_vals"].remove("offsets");
res["fields/orig_vert_vals"].remove("strides");
res["fields/orig_vert_vals/topology"] = "orig_pts";

res["fields/orig_ele_vals"] = res["fields/ele_vals"];
res["fields/orig_ele_vals"].remove("offsets");
res["fields/orig_ele_vals"].remove("strides");
res["fields/orig_ele_vals/topology"] = "orig_pts";

test_save_mesh_helper(res, "strided_structured_2d");

res.reset();
Expand Down Expand Up @@ -469,6 +484,21 @@ TEST(conduit_blueprint_mesh_examples, strided_structured_2d)
EXPECT_TRUE(blueprint::mesh::verify(res, info));
CONDUIT_INFO(info.to_yaml());

// also add a topo that shows the orig points
// and fields assoced with orig points for debugging
res["topologies/orig_pts/type"] = "points";
res["topologies/orig_pts/coordset"] = "coords";

res["fields/orig_vert_vals"] = res["fields/vert_vals"];
res["fields/orig_vert_vals"].remove("offsets");
res["fields/orig_vert_vals"].remove("strides");
res["fields/orig_vert_vals/topology"] = "orig_pts";

res["fields/orig_ele_vals"] = res["fields/ele_vals"];
res["fields/orig_ele_vals"].remove("offsets");
res["fields/orig_ele_vals"].remove("strides");
res["fields/orig_ele_vals/topology"] = "orig_pts";

test_save_mesh_helper(res, "strided_structured_2d_pad");
}

Expand All @@ -482,6 +512,21 @@ TEST(conduit_blueprint_mesh_examples, strided_structured_3d)
EXPECT_TRUE(blueprint::mesh::verify(res, info));
CONDUIT_INFO(info.to_yaml());

// also add a topo that shows the orig points
// and fields assoced with orig points for debugging
res["topologies/orig_pts/type"] = "points";
res["topologies/orig_pts/coordset"] = "coords";

res["fields/orig_vert_vals"] = res["fields/vert_vals"];
res["fields/orig_vert_vals"].remove("offsets");
res["fields/orig_vert_vals"].remove("strides");
res["fields/orig_vert_vals/topology"] = "orig_pts";

res["fields/orig_ele_vals"] = res["fields/ele_vals"];
res["fields/orig_ele_vals"].remove("offsets");
res["fields/orig_ele_vals"].remove("strides");
res["fields/orig_ele_vals/topology"] = "orig_pts";

test_save_mesh_helper(res, "strided_structured_3d");

res.reset();
Expand Down Expand Up @@ -513,7 +558,23 @@ TEST(conduit_blueprint_mesh_examples, strided_structured_3d)
EXPECT_TRUE(blueprint::mesh::verify(res, info));
CONDUIT_INFO(info.to_yaml());

// also add a topo that shows the orig points
// and fields assoced with orig points for debugging
res["topologies/orig_pts/type"] = "points";
res["topologies/orig_pts/coordset"] = "coords";

res["fields/orig_vert_vals"] = res["fields/vert_vals"];
res["fields/orig_vert_vals"].remove("offsets");
res["fields/orig_vert_vals"].remove("strides");
res["fields/orig_vert_vals/topology"] = "orig_pts";

res["fields/orig_ele_vals"] = res["fields/ele_vals"];
res["fields/orig_ele_vals"].remove("offsets");
res["fields/orig_ele_vals"].remove("strides");
res["fields/orig_ele_vals/topology"] = "orig_pts";

test_save_mesh_helper(res, "strided_structured_3d_pad");

}


Expand Down

0 comments on commit 09770be

Please sign in to comment.