feat: bind Solid definitions to Hex8 runtime elements
This commit is contained in:
@@ -35,6 +35,8 @@ add_library(
|
||||
core/diagnostic.cpp
|
||||
core/status.cpp
|
||||
elements/element_factory.cpp
|
||||
elements/hex8_element.cpp
|
||||
elements/hex8_geometry.cpp
|
||||
elements/euler_beam_3d.cpp
|
||||
elements/finite_rotation.cpp
|
||||
elements/mitc4_shell.cpp
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "fesa/elements/euler_beam_3d.h"
|
||||
#include "fesa/elements/hex8_element.h"
|
||||
#include "fesa/elements/mitc4_shell.h"
|
||||
#include "fesa/materials/material.h"
|
||||
#include "fesa/model/domain.h"
|
||||
@@ -225,6 +226,72 @@ Result<std::unique_ptr<Element>> ElementFactory::CreateShell(
|
||||
return Result<std::unique_ptr<Element>>::Success(std::move(result));
|
||||
}
|
||||
|
||||
Result<std::unique_ptr<Element>> ElementFactory::CreateSolid(
|
||||
const ElementDefinition& definition, const Domain& domain) const {
|
||||
const auto element_index = FindElementIndex(definition, domain);
|
||||
const Hex8Definition* solid_definition = nullptr;
|
||||
for (std::size_t index = 0U; index < domain.SolidElements().Size(); ++index) {
|
||||
const auto& solid = domain.SolidElements()[index];
|
||||
if (&solid == &definition) {
|
||||
solid_definition = &solid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!element_index.has_value() || solid_definition == nullptr) {
|
||||
return FactoryFailure(
|
||||
definition, domain, "invalid-element-definition",
|
||||
"The C3D8 definition must be owned by the supplied Domain.");
|
||||
}
|
||||
if (!HasValidNodes(definition, domain, 8U)) {
|
||||
return FactoryFailure(definition, domain, "invalid-element-topology",
|
||||
"C3D8 requires eight valid Domain node indices.");
|
||||
}
|
||||
if (definition.PropertyIndex() >= domain.Properties().Size() ||
|
||||
definition.MaterialIndex() >= domain.Materials().Size()) {
|
||||
return FactoryFailure(
|
||||
definition, domain, "invalid-element-assignment",
|
||||
"C3D8 property and material indices must resolve in the Domain.");
|
||||
}
|
||||
const auto& property = domain.Properties()[definition.PropertyIndex()];
|
||||
const auto& material = domain.Materials()[definition.MaterialIndex()];
|
||||
if (property.Kind() != ElementPropertyKind::kSolidSection ||
|
||||
material.Kind() != MaterialKind::kIsotropicLinearElastic) {
|
||||
return FactoryFailure(
|
||||
definition, domain, "incompatible-element-assignment",
|
||||
"C3D8 requires a Solid section and isotropic elastic material.");
|
||||
}
|
||||
const auto& section = static_cast<const SolidSection&>(property);
|
||||
if (section.MaterialIndex() != definition.MaterialIndex()) {
|
||||
return FactoryFailure(
|
||||
definition, domain, "incompatible-element-assignment",
|
||||
"C3D8 section and definition must select the same material.");
|
||||
}
|
||||
Hex8Element::Coordinates coordinates{};
|
||||
for (std::size_t node = 0U; node < coordinates.size(); ++node) {
|
||||
coordinates[node] = domain.Nodes()[definition.NodeIndices()[node]].coordinates;
|
||||
}
|
||||
std::optional<double> density;
|
||||
for (const auto& record : domain.Densities()) {
|
||||
if (record.material_index == definition.MaterialIndex()) {
|
||||
density = record.rho;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ElementDofLayout layout{definition.SourceId(), definition.NodeIndices(),
|
||||
{DofComponent::kUx, DofComponent::kUy,
|
||||
DofComponent::kUz}};
|
||||
auto candidate = Hex8Element::Create(
|
||||
*element_index, std::move(layout), coordinates,
|
||||
static_cast<const IsotropicLinearElasticMaterial&>(material), density,
|
||||
solid_definition->location);
|
||||
if (!candidate.HasValue()) {
|
||||
return Result<std::unique_ptr<Element>>::Failure(candidate.GetStatus());
|
||||
}
|
||||
std::unique_ptr<Element> result =
|
||||
std::make_unique<Hex8Element>(std::move(candidate.Value()));
|
||||
return Result<std::unique_ptr<Element>>::Success(std::move(result));
|
||||
}
|
||||
|
||||
Result<std::unique_ptr<Element>> ElementFactory::Create(
|
||||
const ElementDefinition& definition, const Domain& domain) const {
|
||||
switch (definition.Kind()) {
|
||||
@@ -232,6 +299,8 @@ Result<std::unique_ptr<Element>> ElementFactory::Create(
|
||||
return CreateBeam(definition, domain);
|
||||
case ElementDefinitionKind::kMitc4Shell:
|
||||
return CreateShell(definition, domain);
|
||||
case ElementDefinitionKind::kHex8:
|
||||
return CreateSolid(definition, domain);
|
||||
}
|
||||
return FactoryFailure(definition, domain, "unsupported-element-definition",
|
||||
"The element definition kind is not supported.");
|
||||
|
||||
Reference in New Issue
Block a user