Skip to content

Commit

Permalink
add specsets validation and testing (#431)
Browse files Browse the repository at this point in the history
  • Loading branch information
xjrc committed Jul 8, 2019
1 parent 16fa040 commit 1fe99fc
Show file tree
Hide file tree
Showing 8 changed files with 402 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ and this project aspires to adhere to [Semantic Versioning](https://semver.org/s

#### Blueprint

- Added the the "specsets" top-level section to the Blueprint schema, which can be used to represent multi-dimensional per-material quantities (most commonly per-material atomic composition fractions).
- Added explicit topological data generation functions for points, lines, and faces
- Added derived topology generation functions for element centroids, sides, and corners

Expand Down
19 changes: 18 additions & 1 deletion src/docs/sphinx/blueprint_mesh.rst
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,24 @@ Topology Association for Field Values

For implicit topologies, the field values are associated with the topology by fast varying logical dimensions starting with ``i``, then ``j``, then ``k``.

For explicit topologies, the field values are associated with the topology by assuming the order of the field values matches the order the elements are defined in the topology.
For explicit topologies, the field values are associated with the topology by assuming the order of the field values matches the order the elements are defined in the topology.



Species Sets
++++++++++++++++++++

Species Sets are a means of representing multi-dimensional per-material quantities, most commonly per-material substance fractions.

Individual Species Sets are entries in the ``specsets`` section of the Blueprint hierarchy, and these entries are formatted in much the same way as ``fields`` entries that describe per-material, multi-dimensional fields.
Just as with this class of ``fields`` entries, each ``specsets`` entry must specify the material set over which it is defined and enumerate its values within an **mcarray** that's organized in material-major and component-minor order.
Additionally, like ``field`` entries, each ``specsets`` item must indicate a volumetric scaling type (e.g. volume-dependent, volume-independent).
To put it in short, each entry in the ``specsets`` section of the Blueprint hierarchy must be an *Object* that follows this template:

* specsets/specset/volume_dependent: "true" | "false"
* specsets/specset/matset: "matset"
* specsets/specset/matset_values: (mcarray)



Adjacency Sets
Expand Down
22 changes: 22 additions & 0 deletions src/libs/blueprint/conduit_blueprint_mcarray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#include <algorithm>
#include <map>
#include <set>
#include <limits>

using namespace conduit;
// Easier access to the Conduit logging functions
Expand Down Expand Up @@ -346,6 +347,15 @@ verify(const std::string &/*protocol*/,
//----------------------------------------------------------------------------
bool verify(const conduit::Node &n,
Node &info)
{
return mlarray::verify(n, info, 0, std::numeric_limits<index_t>::max());
}

//----------------------------------------------------------------------------
bool verify(const conduit::Node &n,
Node &info,
const index_t min_depth,
const index_t max_depth)
{
info.reset();
bool res = true;
Expand Down Expand Up @@ -451,6 +461,18 @@ bool verify(const conduit::Node &n,
}
}

// Verify Proper Depth Level //

if(node_max_depth < min_depth || node_max_depth > max_depth)
{
std::ostringstream oss;
oss << "mlarray depth has depth " << node_max_depth <<
", which isn't in the required depth bounds of " <<
"[" << min_depth << ", " << max_depth << "]";
log::error(info,protocol,oss.str());
res = false;
}

return res;
}

Expand Down
7 changes: 7 additions & 0 deletions src/libs/blueprint/conduit_blueprint_mcarray.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,13 @@ namespace mlarray
bool CONDUIT_BLUEPRINT_API verify(const conduit::Node &n,
conduit::Node &info);


//-----------------------------------------------------------------------------
bool CONDUIT_BLUEPRINT_API verify(const conduit::Node &n,
conduit::Node &info,
const index_t min_depth,
const index_t max_pepth);

//-----------------------------------------------------------------------------
bool CONDUIT_BLUEPRINT_API verify(const std::string &protocol,
const conduit::Node &n,
Expand Down
159 changes: 153 additions & 6 deletions src/libs/blueprint/conduit_blueprint_mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ namespace conduit { namespace blueprint { namespace mesh {
static const std::vector<std::string> associations(association_list,
association_list + sizeof(association_list) / sizeof(association_list[0]));

static const std::string boolean_list[2] = {"true", "false"};
static const std::vector<std::string> booleans(boolean_list,
boolean_list + sizeof(boolean_list) / sizeof(boolean_list[0]));

static const std::string coord_type_list[3] = {"uniform", "rectilinear", "explicit"};
static const std::vector<std::string> coord_types(coord_type_list,
coord_type_list + sizeof(coord_type_list) / sizeof(coord_type_list[0]));
Expand Down Expand Up @@ -560,15 +564,17 @@ bool verify_mcarray_field(const std::string &protocol,
bool verify_mlarray_field(const std::string &protocol,
const conduit::Node &node,
conduit::Node &info,
const std::string &field_name)
const std::string &field_name,
const index_t min_depth,
const index_t max_depth)
{
Node &field_info = info[field_name];

bool res = verify_field_exists(protocol, node, info, field_name);
if(res)
{
const Node &field_node = node[field_name];
res = blueprint::mlarray::verify(field_node,field_info);
res = blueprint::mlarray::verify(field_node,field_info,min_depth,max_depth);
if(res)
{
log::info(info, protocol, log::quote(field_name) + "is an mlarray");
Expand Down Expand Up @@ -1816,6 +1822,10 @@ mesh::verify(const std::string &protocol,
{
res = matset::verify(n,info);
}
else if(protocol == "specset")
{
res = specset::verify(n,info);
}
else if(protocol == "field")
{
res = field::verify(n,info);
Expand Down Expand Up @@ -1844,6 +1854,10 @@ mesh::verify(const std::string &protocol,
{
res = matset::index::verify(n,info);
}
else if(protocol == "specset/index")
{
res = specset::index::verify(n,info);
}
else if(protocol == "field/index")
{
res = field::index::verify(n,info);
Expand Down Expand Up @@ -1940,6 +1954,33 @@ mesh::verify_single_domain(const Node &n,
}
}

// optional: "specsets", each child must conform to "mesh::specset"
if(n.has_path("specsets"))
{
if(!verify_object_field(protocol, n, info, "specsets"))
{
res = false;
}
else
{
bool sset_res = true;
NodeConstIterator itr = n["specsets"].children();
while(itr.has_next())
{
const Node &chld = itr.next();
const std::string chld_name = itr.name();
Node &chld_info = info["specsets"][chld_name];

sset_res &= specset::verify(chld, chld_info);
sset_res &= verify_reference_field(protocol, n, info,
chld, chld_info, "matset", "matsets");
}

log::validation(info["specsets"],sset_res);
res &= sset_res;
}
}

// optional: "fields", each child must conform to "mesh::field"
if(n.has_path("fields"))
{
Expand Down Expand Up @@ -2261,7 +2302,7 @@ mesh::generate_index(const Node &mesh,
std::string tp_ref_path = join_path(ref_path,"topologies");
tp_ref_path = join_path(tp_ref_path,topo_name);
idx_topo["path"] = tp_ref_path;

// a topology may also specify a grid_function
if(topo.has_child("grid_function"))
{
Expand All @@ -2285,13 +2326,38 @@ mesh::generate_index(const Node &mesh,
mats_itr.next();
idx_matset["materials"][mats_itr.name()];
}

std::string ms_ref_path = join_path(ref_path, "matsets");
ms_ref_path = join_path(ms_ref_path, matset_name);
idx_matset["path"] = ms_ref_path;
}
}

if(mesh.has_child("specsets"))
{
itr = mesh["specsets"].children();
while(itr.has_next())
{
const Node &specset = itr.next();
const std::string specset_name = itr.name();
Node &idx_specset = index_out["specsets"][specset_name];

idx_specset["matset"] = specset["matset"].as_string();
// TODO(JRC): Is the 'materials' entry necessary given that it will
// always match the 'materials' entry in the 'matset' list?
NodeConstIterator specs_itr = specset["matset_values"].child(0).children();
while(specs_itr.has_next())
{
specs_itr.next();
idx_specset["species"][specs_itr.name()];
}

std::string ms_ref_path = join_path(ref_path, "specsets");
ms_ref_path = join_path(ms_ref_path, specset_name);
idx_specset["path"] = ms_ref_path;
}
}

if(mesh.has_child("fields"))
{
itr = mesh["fields"].children();
Expand Down Expand Up @@ -3876,14 +3942,18 @@ mesh::field::verify(const Node &field,
if(has_topo)
{
res &= verify_string_field(protocol, field, info, "topology");
res &= verify_mlarray_field(protocol, field, info, "values");
res &= verify_mlarray_field(protocol, field, info, "values", 0, 1);
}
if(has_matset)
{
res &= verify_string_field(protocol, field, info, "matset");
res &= verify_mlarray_field(protocol, field, info, "matset_values");
res &= verify_mlarray_field(protocol, field, info, "matset_values", 1, 2);
}

// TODO(JRC): Enable 'volume_dependent' once it's confirmed to be a required
// entry for fields.
// res &= verify_enum_field(protocol, field, info, "volume_dependent", mesh::booleans);

log::validation(info, res);

return res;
Expand Down Expand Up @@ -3962,6 +4032,55 @@ mesh::field::index::verify(const Node &field_idx,
return res;
}

//-----------------------------------------------------------------------------
// blueprint::mesh::specset protocol interface
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
bool
mesh::specset::verify(const Node &specset,
Node &info)
{
const std::string protocol = "mesh::specset";
bool res = true;
info.reset();

res &= verify_string_field(protocol, specset, info, "matset");
res &= verify_mlarray_field(protocol, specset, info, "matset_values", 2, 2);
// TODO(JRC): Enable 'volume_dependent' once it's confirmed to be a required
// entry for specsets.
// res &= verify_enum_field(protocol, specset, info, "volume_dependent", mesh::booleans);

log::validation(info, res);

return res;
}

//-----------------------------------------------------------------------------
// blueprint::mesh::specset::index::verify protocol interface
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
bool
mesh::specset::index::verify(const Node &specset_idx,
Node &info)
{
const std::string protocol = "mesh::specset::index";
bool res = true;
info.reset();

// TODO(JRC): Determine whether or not extra verification needs to be
// performed on the "species" field.

res &= verify_string_field(protocol, specset_idx, info, "matset");
res &= verify_object_field(protocol, specset_idx, info, "species");
res &= verify_string_field(protocol, specset_idx, info, "path");

log::validation(info, res);

return res;
}

//-----------------------------------------------------------------------------
// blueprint::mesh::adjset protocol interface
//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -4227,6 +4346,34 @@ mesh::index::verify(const Node &n,
}
}

// optional: "specsets", each child must conform to
// "mesh::index::specset"
if(n.has_path("specsets"))
{
if(!verify_object_field(protocol, n, info, "specsets"))
{
res = false;
}
else
{
bool sset_res = true;
NodeConstIterator itr = n["specsets"].children();
while(itr.has_next())
{
const Node &chld = itr.next();
const std::string chld_name = itr.name();
Node &chld_info = info["specsets"][chld_name];

sset_res &= specset::index::verify(chld, chld_info);
sset_res &= verify_reference_field(protocol, n, info,
chld, chld_info, "matset", "matsets");
}

log::validation(info["specsets"],sset_res);
res &= sset_res;
}
}

// optional: "fields", each child must conform to
// "mesh::index::field"
if(n.has_path("fields"))
Expand Down
23 changes: 23 additions & 0 deletions src/libs/blueprint/conduit_blueprint_mesh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,29 @@ namespace field
// -- end conduit::blueprint::mesh::field --
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// blueprint::mesh::specset protocol interface
//-----------------------------------------------------------------------------
namespace specset
{
//-------------------------------------------------------------------------
bool CONDUIT_BLUEPRINT_API verify(const conduit::Node &n,
conduit::Node &info);

//-------------------------------------------------------------------------
// blueprint::mesh::specset::index protocol interface
//-------------------------------------------------------------------------
namespace index
{
//---------------------------------------------------------------------
bool CONDUIT_BLUEPRINT_API verify(const conduit::Node &n,
conduit::Node &info);
}
}
//-----------------------------------------------------------------------------
// -- end conduit::blueprint::mesh::specset--
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// blueprint::mesh::adjset protocol interface
//-----------------------------------------------------------------------------
Expand Down

0 comments on commit 1fe99fc

Please sign in to comment.