Skip to content

Commit

Permalink
blueprint: added polyhedral_chain example
Browse files Browse the repository at this point in the history
  • Loading branch information
JustinPrivitera committed Jul 7, 2021
1 parent de9d180 commit 3948a0e
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 0 deletions.
159 changes: 159 additions & 0 deletions src/libs/blueprint/conduit_blueprint_mesh_examples.cpp
Expand Up @@ -3421,6 +3421,165 @@ adjset_uniform(Node &res)
}
}

//-----------------------------------------------------------------------------
void
polyhedral_chain(index_t howmany, // how long the chain ought to be
Node &chain)
{
Node &chain_coords = chain["coordsets/coords"];
Node &chain_topo = chain["topologies/topo"];
Node &chain_fields = chain["fields"];

chain_coords["type"] = "explicit";

// Each cube requires 8 vertices, and each triangular prism requires 6
// There are two prisms for every cube, so 8+6+6 = 20 vertices
chain_coords["values/x"].set(conduit::DataType::int64(howmany * 20));
chain_coords["values/y"].set(conduit::DataType::int64(howmany * 20));
chain_coords["values/z"].set(conduit::DataType::int64(howmany * 20));

int64* values_x = chain_coords["values/x"].value();
int64* values_y = chain_coords["values/y"].value();
int64* values_z = chain_coords["values/z"].value();

for (int i = 0; i < howmany; i ++)
{
// points for the cubes
values_x[i * 20] = 1 + i * 2; values_y[i * 20] = 1; values_z[i * 20] = 1 + i * 2;
values_x[i * 20 + 1] = 1 + i * 2; values_y[i * 20 + 1] = 1; values_z[i * 20 + 1] = -1 + i * 2;
values_x[i * 20 + 2] = -1 + i * 2; values_y[i * 20 + 2] = 1; values_z[i * 20 + 2] = -1 + i * 2;
values_x[i * 20 + 3] = -1 + i * 2; values_y[i * 20 + 3] = 1; values_z[i * 20 + 3] = 1 + i * 2;
values_x[i * 20 + 4] = 1 + i * 2; values_y[i * 20 + 4] = -1; values_z[i * 20 + 4] = 1 + i * 2;
values_x[i * 20 + 5] = 1 + i * 2; values_y[i * 20 + 5] = -1; values_z[i * 20 + 5] = -1 + i * 2;
values_x[i * 20 + 6] = -1 + i * 2; values_y[i * 20 + 6] = -1; values_z[i * 20 + 6] = -1 + i * 2;
values_x[i * 20 + 7] = -1 + i * 2; values_y[i * 20 + 7] = -1; values_z[i * 20 + 7] = 1 + i * 2;

// points for half the triangular prisms
values_x[i * 20 + 8] = 1 + i * 2; values_y[i * 20 + 8] = 1; values_z[i * 20 + 8] = -1 + i * 2 + 2;
values_x[i * 20 + 9] = -1 + i * 2; values_y[i * 20 + 9] = 1; values_z[i * 20 + 9] = -1 + i * 2 + 2;
values_x[i * 20 + 10] = -1 + i * 2 + 2; values_y[i * 20 + 10] = 1; values_z[i * 20 + 10] = 1 + i * 2 + 2;
values_x[i * 20 + 11] = 1 + i * 2; values_y[i * 20 + 11] = -1; values_z[i * 20 + 11] = -1 + i * 2 + 2;
values_x[i * 20 + 12] = -1 + i * 2; values_y[i * 20 + 12] = -1; values_z[i * 20 + 12] = -1 + i * 2 + 2;
values_x[i * 20 + 13] = -1 + i * 2 + 2; values_y[i * 20 + 13] = -1; values_z[i * 20 + 13] = 1 + i * 2 + 2;

// points for the other half
values_x[i * 20 + 14] = 1 + i * 2; values_y[i * 20 + 14] = 1; values_z[i * 20 + 14] = -1 + i * 2 + 2;
values_x[i * 20 + 15] = -1 + i * 2 + 2; values_y[i * 20 + 15] = 1; values_z[i * 20 + 15] = -1 + i * 2;
values_x[i * 20 + 16] = -1 + i * 2 + 4; values_y[i * 20 + 16] = 1; values_z[i * 20 + 16] = 1 + i * 2;
values_x[i * 20 + 17] = 1 + i * 2; values_y[i * 20 + 17] = -1; values_z[i * 20 + 17] = -1 + i * 2 + 2;
values_x[i * 20 + 18] = -1 + i * 2 + 2; values_y[i * 20 + 18] = -1; values_z[i * 20 + 18] = -1 + i * 2;
values_x[i * 20 + 19] = -1 + i * 2 + 4; values_y[i * 20 + 19] = -1; values_z[i * 20 + 19] = 1 + i * 2;
}

chain_topo["type"] = "unstructured";
chain_topo["coordset"] = "coords";
chain_topo["elements/shape"] = "polyhedral";

// 6 cube faces + 5 prism faces * 2 prisms makes 16
chain_topo["elements/connectivity"].set(conduit::DataType::int64(howmany * 16));
int64* connec = chain_topo["elements/connectivity"].value();
for (int i = 0; i < howmany * 16; i ++)
{
// our faces are specified in order and no faces are reused
connec[i] = i;
}

// this is 3 because every time howmany is increased by 1, 3 more polyhedra are added,
// the cube and two prisms
chain_topo["elements/sizes"].set(conduit::DataType::int64(howmany * 3));
int64* sizes = chain_topo["elements/sizes"].value();
for (int i = 0; i < howmany * 3; i ++)
{
// this ensures that sizes will be of the form {6,5,5, 6,5,5, 6,5,5, ..., 6,5,5}
sizes[i] = ((i % 3) > 0) ? 5 : 6;
}

chain_topo["elements/offsets"].set(conduit::DataType::int64(howmany * 3));
int64* offsets = chain_topo["elements/offsets"].value();
offsets[0] = 0;
for (int i = 1; i < howmany * 3; i ++)
{
offsets[i] = offsets[i - 1] + sizes[i - 1];
}

chain_topo["subelements/shape"] = "polygonal";
// 24 points -> 6 sides -> a cube
// 18 points -> 5 sides -> triangular prism
// so 24 + 18 * 2 = 60
chain_topo["subelements/connectivity"].set(conduit::DataType::int64(howmany * 60));
int64* sub_connec = chain_topo["subelements/connectivity"].value();
for (int i = 0; i < howmany; i ++)
{
// CUBE
// top // bottom
sub_connec[i * 60] = 0 + i * 20; sub_connec[i * 60 + 4] = 4 + i * 20;
sub_connec[i * 60 + 1] = 1 + i * 20; sub_connec[i * 60 + 5] = 5 + i * 20;
sub_connec[i * 60 + 2] = 2 + i * 20; sub_connec[i * 60 + 6] = 6 + i * 20;
sub_connec[i * 60 + 3] = 3 + i * 20; sub_connec[i * 60 + 7] = 7 + i * 20;

// side where x = 1 // side where x = -1
sub_connec[i * 60 + 8] = 0 + i * 20; sub_connec[i * 60 + 12] = 2 + i * 20;
sub_connec[i * 60 + 9] = 1 + i * 20; sub_connec[i * 60 + 13] = 3 + i * 20;
sub_connec[i * 60 + 10] = 5 + i * 20; sub_connec[i * 60 + 14] = 7 + i * 20;
sub_connec[i * 60 + 11] = 4 + i * 20; sub_connec[i * 60 + 15] = 6 + i * 20;

// side where z = 1 // side where z = -1
sub_connec[i * 60 + 16] = 0 + i * 20; sub_connec[i * 60 + 20] = 1 + i * 20;
sub_connec[i * 60 + 17] = 3 + i * 20; sub_connec[i * 60 + 21] = 2 + i * 20;
sub_connec[i * 60 + 18] = 7 + i * 20; sub_connec[i * 60 + 22] = 6 + i * 20;
sub_connec[i * 60 + 19] = 4 + i * 20; sub_connec[i * 60 + 23] = 5 + i * 20;

// PRISM 1
sub_connec[i * 60 + 24] = 9 + i * 20; sub_connec[i * 60 + 28] = 8 + i * 20; sub_connec[i * 60 + 32] = 8 + i * 20;
sub_connec[i * 60 + 25] = 10 + i * 20; sub_connec[i * 60 + 29] = 9 + i * 20; sub_connec[i * 60 + 33] = 10 + i * 20;
sub_connec[i * 60 + 26] = 13 + i * 20; sub_connec[i * 60 + 30] = 12 + i * 20; sub_connec[i * 60 + 34] = 13 + i * 20;
sub_connec[i * 60 + 27] = 12 + i * 20; sub_connec[i * 60 + 31] = 11 + i * 20; sub_connec[i * 60 + 35] = 11 + i * 20;

sub_connec[i * 60 + 36] = 8 + i * 20; sub_connec[i * 60 + 39] = 11 + i * 20;
sub_connec[i * 60 + 37] = 9 + i * 20; sub_connec[i * 60 + 40] = 12 + i * 20;
sub_connec[i * 60 + 38] = 10 + i * 20; sub_connec[i * 60 + 41] = 13 + i * 20;

// PRISM 2
sub_connec[i * 60 + 42] = 15 + i * 20; sub_connec[i * 60 + 46] = 14 + i * 20; sub_connec[i * 60 + 50] = 14 + i * 20;
sub_connec[i * 60 + 43] = 16 + i * 20; sub_connec[i * 60 + 47] = 15 + i * 20; sub_connec[i * 60 + 51] = 16 + i * 20;
sub_connec[i * 60 + 44] = 19 + i * 20; sub_connec[i * 60 + 48] = 18 + i * 20; sub_connec[i * 60 + 52] = 19 + i * 20;
sub_connec[i * 60 + 45] = 18 + i * 20; sub_connec[i * 60 + 49] = 17 + i * 20; sub_connec[i * 60 + 53] = 17 + i * 20;

sub_connec[i * 60 + 54] = 14 + i * 20; sub_connec[i * 60 + 57] = 17 + i * 20;
sub_connec[i * 60 + 55] = 15 + i * 20; sub_connec[i * 60 + 58] = 18 + i * 20;
sub_connec[i * 60 + 56] = 16 + i * 20; sub_connec[i * 60 + 59] = 19 + i * 20;
}

chain_topo["subelements/sizes"].set(conduit::DataType::int64(howmany * 16));
int64* sub_sizes = chain_topo["subelements/sizes"].value();
for (int i = 0; i < howmany * 16; i ++)
{
// this ensures sizes will be of the form {4,4,4,4,4,4,4,4,4,3,3,4,4,4,3,3, 4,4,4,4,4,4,4,4,4,3,3,4,4,4,3,3, ...}
int imod16 = i % 16;
sub_sizes[i] = ((imod16 < 9) || ((imod16 > 10) && (imod16 < 14))) ? 4 : 3;
}

chain_topo["subelements/offsets"].set(conduit::DataType::int64(howmany * 16));
int64* sub_offsets = chain_topo["subelements/offsets"].value();
sub_offsets[0] = 0;
for (int i = 1; i < howmany * 16; i ++)
{
sub_offsets[i] = sub_offsets[i - 1] + sub_sizes[i - 1];
}

chain_fields["chain/topology"] = "topo";
chain_fields["chain/association"] = "element";
chain_fields["chain/volume_dependent"] = "false";
chain_fields["chain/values"].set(conduit::DataType::int64(howmany * 3));
int64* field_values = chain_fields["chain/values"].value();

for (int i = 0; i < howmany * 3; i ++)
{
// ensures that the field is of the form {0,1,1, 0,1,1, ..., 0,1,1}
field_values[i] = (i % 3) == 0 ? 0 : 1;
}
}

}
//-----------------------------------------------------------------------------
// -- end conduit::blueprint::mesh::examples --
Expand Down
4 changes: 4 additions & 0 deletions src/libs/blueprint/conduit_blueprint_mesh_examples.hpp
Expand Up @@ -80,6 +80,10 @@ namespace examples

/// Generates a mesh that uses uniform adjsets
void CONDUIT_BLUEPRINT_API adjset_uniform(conduit::Node &res);

// Generates a chain of cubes and triangular prisms
void CONDUIT_BLUEPRINT_API polyhedral_chain(conduit::index_t howmany,
conduit::Node &chain);
}
//-----------------------------------------------------------------------------
// -- end conduit::blueprint::mesh::examples --
Expand Down
15 changes: 15 additions & 0 deletions src/tests/blueprint/t_blueprint_mesh_examples.cpp
Expand Up @@ -966,6 +966,21 @@ TEST(conduit_blueprint_mesh_examples, number_of_domains)
}


//-----------------------------------------------------------------------------
TEST(conduit_blueprint_mesh_examples, polyhedral_chain)
{
Node res;
blueprint::mesh::examples::polyhedral_chain(7, // number of cubes
res);

Node info;
EXPECT_TRUE(blueprint::mesh::verify(res,info));
CONDUIT_INFO(info.to_yaml());

test_save_mesh_helper(res,"polyhedral_chain_example");
}


//-----------------------------------------------------------------------------
int main(int argc, char* argv[])
{
Expand Down

0 comments on commit 3948a0e

Please sign in to comment.