feat(cpp-object-oriented-modular-refactoring): step 13 - element-definition-domain
This commit is contained in:
@@ -230,7 +230,7 @@ struct WriterModelData {
|
||||
};
|
||||
|
||||
bool IsShellDomain(const Domain& domain) noexcept {
|
||||
return !domain.ShellElements().empty();
|
||||
return !domain.ShellElements().Empty();
|
||||
}
|
||||
|
||||
const char* ShellSourceTypeName(const ShellSourceElementType type) {
|
||||
@@ -261,7 +261,7 @@ bool ComputeLocalAxes(const Domain& domain,
|
||||
const EulerBeam3DDefinition& element, AxisSet& axes) {
|
||||
if (element.node_indices[0U] >= domain.Nodes().size() ||
|
||||
element.node_indices[1U] >= domain.Nodes().size() ||
|
||||
element.section_index >= domain.Sections().size()) {
|
||||
element.section_index >= domain.Sections().Size()) {
|
||||
return false;
|
||||
}
|
||||
const auto& first = domain.Nodes()[element.node_indices[0U]].coordinates;
|
||||
@@ -300,12 +300,14 @@ bool SizeProductFits(const std::size_t left, const std::size_t right,
|
||||
|
||||
Status ValidateShellWriterInput(const Domain& domain,
|
||||
const AnalysisState& state) {
|
||||
if (!domain.Elements().empty()) {
|
||||
if (!domain.BeamElements().Empty()) {
|
||||
return OutputFailure(
|
||||
"invalid-result-identity",
|
||||
"Schema v0 does not combine B33 and FESA-MITC4 element inventories.");
|
||||
}
|
||||
for (const auto& material : domain.Materials()) {
|
||||
for (std::size_t index = 0U; index < domain.LinearElasticMaterials().Size();
|
||||
++index) {
|
||||
const auto& material = domain.LinearElasticMaterials()[index];
|
||||
if (material.name.empty() || !IsValidUtf8(material.name) ||
|
||||
!std::isfinite(material.youngs_modulus) ||
|
||||
!std::isfinite(material.poisson_ratio) ||
|
||||
@@ -315,32 +317,34 @@ Status ValidateShellWriterInput(const Domain& domain,
|
||||
"finite constitutive data.");
|
||||
}
|
||||
}
|
||||
for (const auto& section : domain.ShellSections()) {
|
||||
for (std::size_t index = 0U; index < domain.ShellSections().Size(); ++index) {
|
||||
const auto& section = domain.ShellSections()[index];
|
||||
if (section.name.empty() || !IsValidUtf8(section.name) ||
|
||||
section.material_index >= domain.Materials().size() ||
|
||||
section.material_index >= domain.LinearElasticMaterials().Size() ||
|
||||
!std::isfinite(section.thickness) || !(section.thickness > 0.0)) {
|
||||
return OutputFailure("invalid-result-identity",
|
||||
"Every shell section requires stable material "
|
||||
"identity and positive finite thickness.");
|
||||
}
|
||||
}
|
||||
for (const auto& element : domain.ShellElements()) {
|
||||
for (std::size_t index = 0U; index < domain.ShellElements().Size(); ++index) {
|
||||
const auto& element = domain.ShellElements()[index];
|
||||
if ((element.source_type != ShellSourceElementType::kS4 &&
|
||||
element.source_type != ShellSourceElementType::kS4r) ||
|
||||
element.source_id.source_label <= 0 ||
|
||||
element.source_id.source_label_text.empty() ||
|
||||
!IsValidUtf8(element.source_id.instance_name) ||
|
||||
!IsValidUtf8(element.source_id.source_label_text) ||
|
||||
element.material_index >= domain.Materials().size() ||
|
||||
element.section_index >= domain.ShellSections().size() ||
|
||||
element.node_indices.size() != kShellNodeCount ||
|
||||
element.material_index >= domain.LinearElasticMaterials().Size() ||
|
||||
element.section_index >= domain.ShellSections().Size() ||
|
||||
domain.ShellSections()[element.section_index].material_index !=
|
||||
element.material_index) {
|
||||
return OutputFailure("invalid-result-identity",
|
||||
"Every shell element requires stable source, "
|
||||
"material, and section identity.");
|
||||
}
|
||||
std::array<EntityIndex, kShellNodeCount> sorted_nodes =
|
||||
element.node_indices;
|
||||
auto sorted_nodes = element.node_indices;
|
||||
std::sort(sorted_nodes.begin(), sorted_nodes.end());
|
||||
if (sorted_nodes.back() >= domain.Nodes().size() ||
|
||||
std::adjacent_find(sorted_nodes.begin(), sorted_nodes.end()) !=
|
||||
@@ -368,7 +372,7 @@ Status ValidateShellWriterInput(const Domain& domain,
|
||||
}
|
||||
|
||||
std::size_t expected_rows = 0U;
|
||||
if (!SizeProductFits(domain.ShellElements().size(), kShellLocationCount,
|
||||
if (!SizeProductFits(domain.ShellElements().Size(), kShellLocationCount,
|
||||
expected_rows) ||
|
||||
state.ShellResults().size() != expected_rows) {
|
||||
return OutputFailure("invalid-result-rows",
|
||||
@@ -487,15 +491,16 @@ Status ValidateWriterInput(const std::filesystem::path& output_path,
|
||||
}
|
||||
|
||||
model_data.beam_local_axes.clear();
|
||||
model_data.beam_local_axes.reserve(domain.Elements().size());
|
||||
for (const EulerBeam3DDefinition& element : domain.Elements()) {
|
||||
model_data.beam_local_axes.reserve(domain.BeamElements().Size());
|
||||
for (std::size_t index = 0U; index < domain.BeamElements().Size(); ++index) {
|
||||
const EulerBeam3DDefinition& element = domain.BeamElements()[index];
|
||||
AxisSet axes{};
|
||||
if (element.source_id.source_label <= 0 ||
|
||||
element.source_id.source_label_text.empty() ||
|
||||
!IsValidUtf8(element.source_id.instance_name) ||
|
||||
!IsValidUtf8(element.source_id.source_label_text) ||
|
||||
element.node_indices[0U] == element.node_indices[1U] ||
|
||||
element.material_index >= domain.Materials().size() ||
|
||||
element.material_index >= domain.LinearElasticMaterials().Size() ||
|
||||
!ComputeLocalAxes(domain, element, axes)) {
|
||||
return OutputFailure("invalid-result-identity",
|
||||
"Every element requires valid source, connectivity, "
|
||||
@@ -506,9 +511,9 @@ Status ValidateWriterInput(const std::filesystem::path& output_path,
|
||||
|
||||
std::size_t endpoint_count = 0U;
|
||||
std::size_t gauss_count = 0U;
|
||||
if (!SizeProductFits(domain.Elements().size(), kEndpointCount,
|
||||
if (!SizeProductFits(domain.BeamElements().Size(), kEndpointCount,
|
||||
endpoint_count) ||
|
||||
!SizeProductFits(domain.Elements().size(), kGaussPointCount,
|
||||
!SizeProductFits(domain.BeamElements().Size(), kGaussPointCount,
|
||||
gauss_count) ||
|
||||
state.EndpointResults().size() != endpoint_count ||
|
||||
state.GaussResults().size() != gauss_count) {
|
||||
@@ -522,7 +527,7 @@ Status ValidateWriterInput(const std::filesystem::path& output_path,
|
||||
static_cast<EntityIndex>(row_index / kEndpointCount);
|
||||
const int expected_endpoint = static_cast<int>(row_index % kEndpointCount);
|
||||
const EndpointResultRow& row = state.EndpointResults()[row_index];
|
||||
const auto& element = domain.Elements()[expected_element];
|
||||
const auto& element = domain.BeamElements()[expected_element];
|
||||
const auto& expected_node =
|
||||
domain.Nodes()[element.node_indices[static_cast<std::size_t>(
|
||||
expected_endpoint)]];
|
||||
@@ -552,9 +557,9 @@ Status ValidateWriterInput(const std::filesystem::path& output_path,
|
||||
}
|
||||
|
||||
std::size_t stress_index = 0U;
|
||||
for (std::size_t element_index = 0U; element_index < domain.Elements().size();
|
||||
++element_index) {
|
||||
const auto& element = domain.Elements()[element_index];
|
||||
for (std::size_t element_index = 0U;
|
||||
element_index < domain.BeamElements().Size(); ++element_index) {
|
||||
const auto& element = domain.BeamElements()[element_index];
|
||||
const auto& section_points =
|
||||
domain.Sections()[element.section_index].section_points;
|
||||
for (std::size_t gauss = 0U; gauss < kGaussPointCount; ++gauss) {
|
||||
@@ -973,9 +978,9 @@ void WriteNodes(const hid_t file, const Domain& domain) {
|
||||
void WriteBeamElements(const hid_t file, const Domain& domain,
|
||||
const std::vector<AxisSet>& axes) {
|
||||
std::vector<ElementWriteRow> rows;
|
||||
rows.reserve(domain.Elements().size());
|
||||
for (std::size_t index = 0U; index < domain.Elements().size(); ++index) {
|
||||
const auto& element = domain.Elements()[index];
|
||||
rows.reserve(domain.BeamElements().Size());
|
||||
for (std::size_t index = 0U; index < domain.BeamElements().Size(); ++index) {
|
||||
const auto& element = domain.BeamElements()[index];
|
||||
ElementWriteRow row{static_cast<std::uint64_t>(index),
|
||||
element.source_id.instance_name.c_str(),
|
||||
element.source_id.source_label_text.c_str(),
|
||||
@@ -1047,8 +1052,8 @@ void WriteBeamElements(const hid_t file, const Domain& domain,
|
||||
|
||||
void WriteShellElements(const hid_t file, const Domain& domain) {
|
||||
std::vector<ShellElementWriteRow> rows;
|
||||
rows.reserve(domain.ShellElements().size());
|
||||
for (std::size_t index = 0U; index < domain.ShellElements().size(); ++index) {
|
||||
rows.reserve(domain.ShellElements().Size());
|
||||
for (std::size_t index = 0U; index < domain.ShellElements().Size(); ++index) {
|
||||
const auto& element = domain.ShellElements()[index];
|
||||
rows.push_back({static_cast<std::uint64_t>(index),
|
||||
element.source_id.instance_name.c_str(),
|
||||
@@ -1127,9 +1132,10 @@ void WriteShellElements(const hid_t file, const Domain& domain) {
|
||||
|
||||
void WriteShellMaterials(const hid_t file, const Domain& domain) {
|
||||
std::vector<ShellMaterialWriteRow> rows;
|
||||
rows.reserve(domain.Materials().size());
|
||||
for (std::size_t index = 0U; index < domain.Materials().size(); ++index) {
|
||||
const auto& material = domain.Materials()[index];
|
||||
rows.reserve(domain.LinearElasticMaterials().Size());
|
||||
for (std::size_t index = 0U; index < domain.LinearElasticMaterials().Size();
|
||||
++index) {
|
||||
const auto& material = domain.LinearElasticMaterials()[index];
|
||||
rows.push_back({static_cast<std::uint64_t>(index), material.name.c_str(),
|
||||
material.youngs_modulus, material.poisson_ratio});
|
||||
}
|
||||
@@ -1171,13 +1177,14 @@ void WriteShellMaterials(const hid_t file, const Domain& domain) {
|
||||
|
||||
void WriteShellSections(const hid_t file, const Domain& domain) {
|
||||
std::vector<std::string> source_files;
|
||||
source_files.reserve(domain.ShellSections().size());
|
||||
for (const auto& section : domain.ShellSections()) {
|
||||
source_files.reserve(domain.ShellSections().Size());
|
||||
for (std::size_t index = 0U; index < domain.ShellSections().Size(); ++index) {
|
||||
const auto& section = domain.ShellSections()[index];
|
||||
source_files.push_back(NormalizedPathString(section.location.file));
|
||||
}
|
||||
std::vector<ShellSectionWriteRow> rows;
|
||||
rows.reserve(domain.ShellSections().size());
|
||||
for (std::size_t index = 0U; index < domain.ShellSections().size(); ++index) {
|
||||
rows.reserve(domain.ShellSections().Size());
|
||||
for (std::size_t index = 0U; index < domain.ShellSections().Size(); ++index) {
|
||||
const auto& section = domain.ShellSections()[index];
|
||||
rows.push_back({static_cast<std::uint64_t>(index),
|
||||
source_files[index].c_str(),
|
||||
@@ -1423,7 +1430,7 @@ void WriteShellResultDatasets(const hid_t file, const Domain& domain,
|
||||
}
|
||||
|
||||
const hsize_t element_count =
|
||||
static_cast<hsize_t>(domain.ShellElements().size());
|
||||
static_cast<hsize_t>(domain.ShellElements().Size());
|
||||
const std::string root = std::string{kStepRoot} + "/element/shell";
|
||||
const std::string frame_path = root + "/local_frame";
|
||||
WriteDoubleDataset(file, frame_path, {element_count, 4U, 3U, 3U},
|
||||
@@ -1578,10 +1585,10 @@ void WriteResultDatasets(const hid_t file, const Domain& domain,
|
||||
}
|
||||
|
||||
const std::vector<hsize_t> endpoint_action_dimensions = {
|
||||
static_cast<hsize_t>(domain.Elements().size()), kEndpointCount,
|
||||
static_cast<hsize_t>(domain.BeamElements().Size()), kEndpointCount,
|
||||
kEndActionComponentCount};
|
||||
const std::vector<hsize_t> generalized_dimensions = {
|
||||
static_cast<hsize_t>(domain.Elements().size()), kEndpointCount,
|
||||
static_cast<hsize_t>(domain.BeamElements().Size()), kEndpointCount,
|
||||
kGeneralizedComponentCount};
|
||||
const auto end_actions =
|
||||
FlattenEndpointValues(state.EndpointResults(), false);
|
||||
@@ -2052,18 +2059,19 @@ void SelfCheckFile(const std::filesystem::path& path, const Domain& domain,
|
||||
if (IsShellDomain(domain)) {
|
||||
RequireCompoundDataset(
|
||||
file.Get(), "/model/elements",
|
||||
static_cast<hsize_t>(domain.ShellElements().size()),
|
||||
static_cast<hsize_t>(domain.ShellElements().Size()),
|
||||
{"internal_element_id", "instance_name", "source_label",
|
||||
"source_element_type", "internal_formulation", "node_internal_ids",
|
||||
"shell_section_internal_id", "material_internal_id"});
|
||||
auto elements = OpenDatasetForCheck(file.Get(), "/model/elements");
|
||||
RequireStringAttribute(elements.Get(), "formulation", "FESA-MITC4");
|
||||
RequireCompoundDataset(file.Get(), "/model/shell/materials",
|
||||
static_cast<hsize_t>(domain.Materials().size()),
|
||||
{"internal_material_id", "name", "E", "nu"});
|
||||
RequireCompoundDataset(
|
||||
file.Get(), "/model/shell/materials",
|
||||
static_cast<hsize_t>(domain.LinearElasticMaterials().Size()),
|
||||
{"internal_material_id", "name", "E", "nu"});
|
||||
RequireCompoundDataset(
|
||||
file.Get(), "/model/shell/sections",
|
||||
static_cast<hsize_t>(domain.ShellSections().size()),
|
||||
static_cast<hsize_t>(domain.ShellSections().Size()),
|
||||
{"internal_section_id", "source_file", "source_line", "source_elset",
|
||||
"material_internal_id", "thickness"});
|
||||
|
||||
@@ -2114,7 +2122,7 @@ void SelfCheckFile(const std::filesystem::path& path, const Domain& domain,
|
||||
"BOTTOM,MIDDLE,TOP");
|
||||
|
||||
const hsize_t element_count =
|
||||
static_cast<hsize_t>(domain.ShellElements().size());
|
||||
static_cast<hsize_t>(domain.ShellElements().Size());
|
||||
const std::string shell_root = std::string{kStepRoot} + "/element/shell";
|
||||
RequireDoubleDataset(file.Get(), (shell_root + "/local_frame").c_str(),
|
||||
{element_count, 4U, 3U, 3U}, "X,Y,Z", "1,1,1",
|
||||
@@ -2181,17 +2189,17 @@ void SelfCheckFile(const std::filesystem::path& path, const Domain& domain,
|
||||
}
|
||||
} else {
|
||||
RequireCompoundDataset(file.Get(), "/model/elements",
|
||||
static_cast<hsize_t>(domain.Elements().size()),
|
||||
static_cast<hsize_t>(domain.BeamElements().Size()),
|
||||
{"internal_element_id", "instance_name",
|
||||
"source_label", "node_internal_ids", "local_axes"});
|
||||
auto elements = OpenDatasetForCheck(file.Get(), "/model/elements");
|
||||
RequireStringAttribute(elements.Get(), "formulation",
|
||||
"B33-3D-Euler-Bernoulli");
|
||||
const std::vector<hsize_t> end_dimensions = {
|
||||
static_cast<hsize_t>(domain.Elements().size()), kEndpointCount,
|
||||
static_cast<hsize_t>(domain.BeamElements().Size()), kEndpointCount,
|
||||
kEndActionComponentCount};
|
||||
const std::vector<hsize_t> generalized_dimensions = {
|
||||
static_cast<hsize_t>(domain.Elements().size()), kGaussPointCount,
|
||||
static_cast<hsize_t>(domain.BeamElements().Size()), kGaussPointCount,
|
||||
kGeneralizedComponentCount};
|
||||
RequireDoubleDataset(
|
||||
file.Get(), "/steps/Step-1/frames/0/element/end_force_local",
|
||||
|
||||
Reference in New Issue
Block a user