This example shows how to write a model where the topology changes between time steps (model is remeshed).
The example writes out a very simple model which consists of one triangle in the first time step, which is then changed ("remeshed") into two triangles in the second time step. The example also includes a scalar result (with per element mapping) for the two time steps.
To setup an adaptive topology model, you first write out all the unique element blocks and node blocks. You then specify the sequence of the element blocks in the GeometryBlock. Use the add addElementBlockForState() method to specify a given element block for a given state.
Please note that you either have to provide geometry setup for all time steps or one geometry setup for each step in your analysis. However, if you have a changing topology on only some time steps, you can reuse the element and node blocks by referring to them from several time steps.
const cee::Str fileName =
"ExampleAdaptiveTopology.vtfx";
if (!file->
create(fileName, fileSettings))
{
return EXIT_FAILURE;
}
{
{
const float NODES[] =
{
0.0f, 0.0f, 0.0f,
2.0f, 0.0f, 0.0f,
2.0f, 2.0f, 0.0f,
};
std::vector<float> nodesPart(NODES, NODES + sizeof(NODES) / sizeof(NODES[0]));
{
return EXIT_FAILURE;
}
{
return EXIT_FAILURE;
}
}
{
const int CONNECTS[] = { 0, 1, 2};
std::vector<int> elementNodes(CONNECTS, CONNECTS + sizeof(CONNECTS) / sizeof(CONNECTS[0]));
{
return EXIT_FAILURE;
}
{
return EXIT_FAILURE;
}
}
}
{
{
const float NODES[] =
{
0.0f, 0.0f, 0.0f,
2.0f, 0.0f, 0.0f,
2.0f, 2.0f, 0.0f,
0.9f, 1.1f, 0.0f,
};
std::vector<float> nodesPart(NODES, NODES + sizeof(NODES) / sizeof(NODES[0]));
{
return EXIT_FAILURE;
}
{
return EXIT_FAILURE;
}
}
{
const int CONNECTS[] = { 0, 1, 3, 1, 2, 3};
std::vector<int> elementNodes(CONNECTS, CONNECTS + sizeof(CONNECTS) / sizeof(CONNECTS[0]));
{
return EXIT_FAILURE;
}
{
return EXIT_FAILURE;
}
}
}
{
size_t geoIdx = 0;
int partId = 1;
{
return EXIT_FAILURE;
}
{
return EXIT_FAILURE;
}
{
return EXIT_FAILURE;
}
}
{
{
return EXIT_FAILURE;
}
}
{
{
{
const float RESULT_VALUES[] = { 1.0f };
std::vector<float> resultValues(RESULT_VALUES, RESULT_VALUES + sizeof(RESULT_VALUES) / sizeof(RESULT_VALUES[0]));
{
return EXIT_FAILURE;
}
}
{
const float RESULT_VALUES[] = { 1.0f, 2.0f };
std::vector<float> resultValues(RESULT_VALUES, RESULT_VALUES + sizeof(RESULT_VALUES) / sizeof(RESULT_VALUES[0]));
{
return EXIT_FAILURE;
}
}
}
scalarResult->
setName(
"My scalar result");
{
return EXIT_FAILURE;
}
}
{
partSettings->
setValue(
"context_geometry_index", static_cast<unsigned int>(0));
partSettings->
setValue(
"context_part_id", 1);
partSettings->
setValue(
"draw_style",
"surface_mesh");
scalarSelection->
setValue(
"fringes_result_id", 1);
std::vector<cee::Variant> stateIds(STATE_IDS, STATE_IDS + sizeof(STATE_IDS) / sizeof(STATE_IDS[0]));
stateSelection->
setValue(
"state_ids", stateIds);
if (!singleCase->setProperties(vtfxProps.
get()))
{
return EXIT_FAILURE;
}
}
{
return EXIT_FAILURE;
}
std::cout <<
"Exported successfully to file: " << fileName.
toStdString() << std::endl;
std::cout << std::endl << "Press enter to exit..." << std::endl;
std::cin.ignore();
return EXIT_SUCCESS;