refactor: store runtime objects in domain

This commit is contained in:
김경종
2026-06-09 10:08:34 +09:00
parent 8f24213ab7
commit f4196efb10
20 changed files with 754 additions and 368 deletions
+144 -120
View File
@@ -1,12 +1,14 @@
#include "fesa/core/BoundaryCondition.hpp"
#include "fesa/boundary/SinglePointConstraint.hpp"
#include "fesa/core/Domain.hpp"
#include "fesa/core/ElementDefinition.hpp"
#include "fesa/core/LoadDefinition.hpp"
#include "fesa/core/MaterialDefinition.hpp"
#include "fesa/core/Node.hpp"
#include "fesa/core/PropertyDefinition.hpp"
#include "fesa/core/StepDefinition.hpp"
#include "fesa/element/Mitc4Element.hpp"
#include "fesa/load/NodalLoad.hpp"
#include "fesa/material/LinearElasticMaterial.hpp"
#include "fesa/property/ShellProperty.hpp"
#include <array>
#include <memory>
#include <stdexcept>
#include <type_traits>
@@ -28,6 +30,25 @@ int require_throws(Function&& function) {
return 1;
}
void add_four_nodes(fesa::core::Domain& domain) {
domain.addNode(fesa::core::Node{1, 0.0, 0.0, 0.0});
domain.addNode(fesa::core::Node{2, 1.0, 0.0, 0.0});
domain.addNode(fesa::core::Node{3, 1.0, 1.0, 0.0});
domain.addNode(fesa::core::Node{4, 0.0, 1.0, 0.0});
}
void add_material_and_property(fesa::core::Domain& domain) {
domain.addMaterial(std::make_unique<fesa::material::LinearElasticMaterial>(700, 210.0, 0.3));
domain.addShellProperty(fesa::property::ShellProperty{500, 700, 0.01});
}
void add_element(fesa::core::Domain& domain) {
domain.addElement(std::make_unique<fesa::element::Mitc4Element>(
100,
std::array<fesa::core::NodeId, 4>{1, 2, 3, 4},
500));
}
int add_and_retrieve_node_by_id() {
fesa::core::Domain domain;
@@ -55,11 +76,7 @@ int add_and_retrieve_node_by_id() {
}
const fesa::core::Node& direct = domain.node(10);
if (const int result = require(direct.id() == 10); result != 0) {
return result;
}
return 0;
return require(direct.id() == 10);
}
int missing_node_lookup_contracts() {
@@ -83,28 +100,18 @@ int duplicate_node_id_throws() {
});
}
void add_four_nodes(fesa::core::Domain& domain) {
domain.addNode(fesa::core::Node{1, 0.0, 0.0, 0.0});
domain.addNode(fesa::core::Node{2, 1.0, 0.0, 0.0});
domain.addNode(fesa::core::Node{3, 1.0, 1.0, 0.0});
domain.addNode(fesa::core::Node{4, 0.0, 1.0, 0.0});
}
int add_and_retrieve_element_by_id() {
fesa::core::Domain domain;
add_four_nodes(domain);
add_material_and_property(domain);
domain.addElement(fesa::core::ElementDefinition{
100,
fesa::core::ElementType::Mitc4,
{1, 2, 3, 4},
500});
add_element(domain);
if (const int result = require(domain.elementCount() == 1); result != 0) {
return result;
}
const fesa::core::ElementDefinition* found = domain.findElement(100);
const fesa::element::Element* found = domain.findElement(100);
if (const int result = require(found != nullptr); result != 0) {
return result;
}
@@ -130,25 +137,21 @@ int add_and_retrieve_element_by_id() {
return result;
}
const fesa::core::ElementDefinition& direct = domain.element(100);
const fesa::element::Element& direct = domain.element(100);
return require(direct.id() == 100);
}
int duplicate_element_id_throws() {
fesa::core::Domain domain;
add_four_nodes(domain);
domain.addElement(fesa::core::ElementDefinition{
100,
fesa::core::ElementType::Mitc4,
{1, 2, 3, 4},
500});
add_material_and_property(domain);
add_element(domain);
return require_throws<std::invalid_argument>([&domain]() {
domain.addElement(fesa::core::ElementDefinition{
domain.addElement(std::make_unique<fesa::element::Mitc4Element>(
100,
fesa::core::ElementType::Mitc4,
{1, 2, 3, 4},
500});
std::array<fesa::core::NodeId, 4>{1, 2, 3, 4},
500));
});
}
@@ -157,13 +160,26 @@ int element_referencing_missing_node_throws() {
domain.addNode(fesa::core::Node{1, 0.0, 0.0, 0.0});
domain.addNode(fesa::core::Node{2, 1.0, 0.0, 0.0});
domain.addNode(fesa::core::Node{3, 1.0, 1.0, 0.0});
add_material_and_property(domain);
return require_throws<std::invalid_argument>([&domain]() {
domain.addElement(fesa::core::ElementDefinition{
domain.addElement(std::make_unique<fesa::element::Mitc4Element>(
100,
fesa::core::ElementType::Mitc4,
{1, 2, 3, 4},
500});
std::array<fesa::core::NodeId, 4>{1, 2, 3, 4},
500));
});
}
int element_referencing_missing_property_throws() {
fesa::core::Domain domain;
add_four_nodes(domain);
domain.addMaterial(std::make_unique<fesa::material::LinearElasticMaterial>(700, 210.0, 0.3));
return require_throws<std::invalid_argument>([&domain]() {
domain.addElement(std::make_unique<fesa::element::Mitc4Element>(
100,
std::array<fesa::core::NodeId, 4>{1, 2, 3, 4},
500));
});
}
@@ -179,11 +195,6 @@ int missing_element_lookup_contracts() {
});
}
void add_material_and_property(fesa::core::Domain& domain) {
domain.addMaterial(fesa::core::LinearElasticMaterialDefinition{700, 210.0, 0.3});
domain.addShellProperty(fesa::core::ShellPropertyDefinition{500, 700, 0.01});
}
int add_and_retrieve_material_and_property() {
fesa::core::Domain domain;
@@ -196,18 +207,15 @@ int add_and_retrieve_material_and_property() {
return result;
}
const fesa::core::LinearElasticMaterialDefinition* material = domain.findMaterial(700);
const fesa::material::Material* material = domain.findMaterial(700);
if (const int result = require(material != nullptr); result != 0) {
return result;
}
if (const int result = require(material->youngModulus() == 210.0); result != 0) {
return result;
}
if (const int result = require(material->poissonRatio() == 0.3); result != 0) {
if (const int result = require(material->id() == 700); result != 0) {
return result;
}
const fesa::core::ShellPropertyDefinition* property = domain.findShellProperty(500);
const fesa::property::ShellProperty* property = domain.findShellProperty(500);
if (const int result = require(property != nullptr); result != 0) {
return result;
}
@@ -229,14 +237,14 @@ int duplicate_material_and_property_ids_throw() {
add_material_and_property(domain);
if (const int result = require_throws<std::invalid_argument>([&domain]() {
domain.addMaterial(fesa::core::LinearElasticMaterialDefinition{700, 100.0, 0.25});
domain.addMaterial(std::make_unique<fesa::material::LinearElasticMaterial>(700, 100.0, 0.25));
});
result != 0) {
return result;
}
return require_throws<std::invalid_argument>([&domain]() {
domain.addShellProperty(fesa::core::ShellPropertyDefinition{500, 700, 0.02});
domain.addShellProperty(fesa::property::ShellProperty{500, 700, 0.02});
});
}
@@ -244,18 +252,15 @@ int shell_property_referencing_missing_material_throws() {
fesa::core::Domain domain;
return require_throws<std::invalid_argument>([&domain]() {
domain.addShellProperty(fesa::core::ShellPropertyDefinition{500, 700, 0.01});
domain.addShellProperty(fesa::property::ShellProperty{500, 700, 0.01});
});
}
int add_and_retrieve_sets() {
fesa::core::Domain domain;
add_four_nodes(domain);
domain.addElement(fesa::core::ElementDefinition{
100,
fesa::core::ElementType::Mitc4,
{1, 2, 3, 4},
500});
add_material_and_property(domain);
add_element(domain);
domain.addNodeSet("left-edge", {1, 4});
domain.addElementSet("shells", {100});
@@ -294,11 +299,8 @@ int add_and_retrieve_sets() {
int duplicate_set_names_throw() {
fesa::core::Domain domain;
add_four_nodes(domain);
domain.addElement(fesa::core::ElementDefinition{
100,
fesa::core::ElementType::Mitc4,
{1, 2, 3, 4},
500});
add_material_and_property(domain);
add_element(domain);
domain.addNodeSet("left-edge", {1, 4});
domain.addElementSet("shells", {100});
@@ -316,11 +318,8 @@ int duplicate_set_names_throw() {
int sets_referencing_missing_ids_throw() {
fesa::core::Domain domain;
add_four_nodes(domain);
domain.addElement(fesa::core::ElementDefinition{
100,
fesa::core::ElementType::Mitc4,
{1, 2, 3, 4},
500});
add_material_and_property(domain);
add_element(domain);
if (const int result = require_throws<std::invalid_argument>([&domain]() {
domain.addNodeSet("bad-nodes", {1, 99});
@@ -338,7 +337,7 @@ int add_and_retrieve_boundary_condition() {
domain.addNode(fesa::core::Node{1, 0.0, 0.0, 0.0});
const std::size_t index = domain.addBoundaryCondition(
fesa::core::BoundaryCondition{1, fesa::core::Dof::U1, 0.0});
std::make_unique<fesa::boundary::SinglePointConstraint>(1, fesa::core::Dof::U1, 0.0));
if (const int result = require(index == 0); result != 0) {
return result;
@@ -347,38 +346,47 @@ int add_and_retrieve_boundary_condition() {
return result;
}
const fesa::core::BoundaryCondition& condition = domain.boundaryCondition(index);
if (const int result = require(condition.nodeId() == 1); result != 0) {
const fesa::boundary::BoundaryCondition& condition = domain.boundaryCondition(index);
if (const int result = require(condition.kind() == fesa::boundary::BoundaryConditionKind::SinglePointConstraint);
result != 0) {
return result;
}
if (const int result = require(condition.dof() == fesa::core::Dof::U1); result != 0) {
const auto& spc = static_cast<const fesa::boundary::SinglePointConstraint&>(condition);
if (const int result = require(spc.nodeId() == 1); result != 0) {
return result;
}
return require(condition.value() == 0.0);
if (const int result = require(spc.dof() == fesa::core::Dof::U1); result != 0) {
return result;
}
return require(spc.value() == 0.0);
}
int add_and_retrieve_nodal_load() {
fesa::core::Domain domain;
domain.addNode(fesa::core::Node{1, 0.0, 0.0, 0.0});
const std::size_t index = domain.addNodalLoad(
fesa::core::NodalLoadDefinition{1, fesa::core::Dof::U3, -100.0});
const std::size_t index = domain.addLoad(
std::make_unique<fesa::load::NodalLoad>(1, fesa::core::Dof::U3, -100.0));
if (const int result = require(index == 0); result != 0) {
return result;
}
if (const int result = require(domain.nodalLoadCount() == 1); result != 0) {
if (const int result = require(domain.loadCount() == 1); result != 0) {
return result;
}
const fesa::core::NodalLoadDefinition& load = domain.nodalLoad(index);
if (const int result = require(load.nodeId() == 1); result != 0) {
const fesa::load::Load& load = domain.load(index);
if (const int result = require(load.kind() == fesa::load::LoadKind::Nodal); result != 0) {
return result;
}
if (const int result = require(load.dof() == fesa::core::Dof::U3); result != 0) {
const auto& nodal_load = static_cast<const fesa::load::NodalLoad&>(load);
if (const int result = require(nodal_load.nodeId() == 1); result != 0) {
return result;
}
return require(load.value() == -100.0);
if (const int result = require(nodal_load.dof() == fesa::core::Dof::U3); result != 0) {
return result;
}
return require(nodal_load.value() == -100.0);
}
int missing_node_boundary_condition_and_load_throw() {
@@ -386,15 +394,36 @@ int missing_node_boundary_condition_and_load_throw() {
if (const int result = require_throws<std::invalid_argument>([&domain]() {
(void)domain.addBoundaryCondition(
fesa::core::BoundaryCondition{99, fesa::core::Dof::U1, 0.0});
std::make_unique<fesa::boundary::SinglePointConstraint>(99, fesa::core::Dof::U1, 0.0));
});
result != 0) {
return result;
}
return require_throws<std::invalid_argument>([&domain]() {
(void)domain.addNodalLoad(
fesa::core::NodalLoadDefinition{99, fesa::core::Dof::U3, -100.0});
(void)domain.addLoad(
std::make_unique<fesa::load::NodalLoad>(99, fesa::core::Dof::U3, -100.0));
});
}
int duplicate_load_and_boundary_keys_throw() {
fesa::core::Domain domain;
domain.addNode(fesa::core::Node{1, 0.0, 0.0, 0.0});
domain.addBoundaryCondition(
std::make_unique<fesa::boundary::SinglePointConstraint>(1, fesa::core::Dof::U1, 0.0));
domain.addLoad(std::make_unique<fesa::load::NodalLoad>(1, fesa::core::Dof::U3, -100.0));
if (const int result = require_throws<std::invalid_argument>([&domain]() {
(void)domain.addBoundaryCondition(
std::make_unique<fesa::boundary::SinglePointConstraint>(1, fesa::core::Dof::U1, 1.0));
});
result != 0) {
return result;
}
return require_throws<std::invalid_argument>([&domain]() {
(void)domain.addLoad(
std::make_unique<fesa::load::NodalLoad>(1, fesa::core::Dof::U3, -200.0));
});
}
@@ -402,9 +431,9 @@ int add_and_retrieve_linear_static_step() {
fesa::core::Domain domain;
domain.addNode(fesa::core::Node{1, 0.0, 0.0, 0.0});
const std::size_t bc = domain.addBoundaryCondition(
fesa::core::BoundaryCondition{1, fesa::core::Dof::U1, 0.0});
const std::size_t load = domain.addNodalLoad(
fesa::core::NodalLoadDefinition{1, fesa::core::Dof::U3, -100.0});
std::make_unique<fesa::boundary::SinglePointConstraint>(1, fesa::core::Dof::U1, 0.0));
const std::size_t load = domain.addLoad(
std::make_unique<fesa::load::NodalLoad>(1, fesa::core::Dof::U3, -100.0));
domain.addStep(fesa::core::LinearStaticStepDefinition{1, "load-step", {bc}, {load}});
@@ -438,9 +467,9 @@ int duplicate_and_invalid_step_references_throw() {
fesa::core::Domain domain;
domain.addNode(fesa::core::Node{1, 0.0, 0.0, 0.0});
const std::size_t bc = domain.addBoundaryCondition(
fesa::core::BoundaryCondition{1, fesa::core::Dof::U1, 0.0});
const std::size_t load = domain.addNodalLoad(
fesa::core::NodalLoadDefinition{1, fesa::core::Dof::U3, -100.0});
std::make_unique<fesa::boundary::SinglePointConstraint>(1, fesa::core::Dof::U1, 0.0));
const std::size_t load = domain.addLoad(
std::make_unique<fesa::load::NodalLoad>(1, fesa::core::Dof::U3, -100.0));
domain.addStep(fesa::core::LinearStaticStepDefinition{1, "load-step", {bc}, {load}});
@@ -461,22 +490,17 @@ int duplicate_and_invalid_step_references_throw() {
});
}
int const_domain_retrieval_returns_const_model_data() {
int const_domain_retrieval_returns_const_runtime_model_data() {
fesa::core::Domain domain;
add_four_nodes(domain);
domain.addMaterial(fesa::core::LinearElasticMaterialDefinition{700, 210.0, 0.3});
domain.addShellProperty(fesa::core::ShellPropertyDefinition{500, 700, 0.01});
domain.addElement(fesa::core::ElementDefinition{
100,
fesa::core::ElementType::Mitc4,
{1, 2, 3, 4},
500});
add_material_and_property(domain);
add_element(domain);
domain.addNodeSet("left-edge", {1, 4});
domain.addElementSet("shells", {100});
const std::size_t bc = domain.addBoundaryCondition(
fesa::core::BoundaryCondition{1, fesa::core::Dof::U1, 0.0});
const std::size_t load = domain.addNodalLoad(
fesa::core::NodalLoadDefinition{1, fesa::core::Dof::U3, -100.0});
std::make_unique<fesa::boundary::SinglePointConstraint>(1, fesa::core::Dof::U1, 0.0));
const std::size_t load = domain.addLoad(
std::make_unique<fesa::load::NodalLoad>(1, fesa::core::Dof::U3, -100.0));
domain.addStep(fesa::core::LinearStaticStepDefinition{1, "load-step", {bc}, {load}});
const fesa::core::Domain& const_domain = domain;
@@ -485,15 +509,15 @@ int const_domain_retrieval_returns_const_model_data() {
result != 0) {
return result;
}
if (const int result = require((std::is_same<decltype(const_domain.element(100)), const fesa::core::ElementDefinition&>::value));
if (const int result = require((std::is_same<decltype(const_domain.element(100)), const fesa::element::Element&>::value));
result != 0) {
return result;
}
if (const int result = require((std::is_same<decltype(const_domain.material(700)), const fesa::core::LinearElasticMaterialDefinition&>::value));
if (const int result = require((std::is_same<decltype(const_domain.material(700)), const fesa::material::Material&>::value));
result != 0) {
return result;
}
if (const int result = require((std::is_same<decltype(const_domain.shellProperty(500)), const fesa::core::ShellPropertyDefinition&>::value));
if (const int result = require((std::is_same<decltype(const_domain.shellProperty(500)), const fesa::property::ShellProperty&>::value));
result != 0) {
return result;
}
@@ -505,11 +529,11 @@ int const_domain_retrieval_returns_const_model_data() {
result != 0) {
return result;
}
if (const int result = require((std::is_same<decltype(const_domain.boundaryCondition(0)), const fesa::core::BoundaryCondition&>::value));
if (const int result = require((std::is_same<decltype(const_domain.boundaryCondition(0)), const fesa::boundary::BoundaryCondition&>::value));
result != 0) {
return result;
}
if (const int result = require((std::is_same<decltype(const_domain.nodalLoad(0)), const fesa::core::NodalLoadDefinition&>::value));
if (const int result = require((std::is_same<decltype(const_domain.load(0)), const fesa::load::Load&>::value));
result != 0) {
return result;
}
@@ -519,27 +543,21 @@ int const_domain_retrieval_returns_const_model_data() {
int failed_inserts_do_not_mutate_counts() {
fesa::core::Domain domain;
add_four_nodes(domain);
domain.addMaterial(fesa::core::LinearElasticMaterialDefinition{700, 210.0, 0.3});
domain.addShellProperty(fesa::core::ShellPropertyDefinition{500, 700, 0.01});
domain.addElement(fesa::core::ElementDefinition{
100,
fesa::core::ElementType::Mitc4,
{1, 2, 3, 4},
500});
add_material_and_property(domain);
add_element(domain);
domain.addNodeSet("left-edge", {1, 4});
domain.addElementSet("shells", {100});
const std::size_t bc = domain.addBoundaryCondition(
fesa::core::BoundaryCondition{1, fesa::core::Dof::U1, 0.0});
const std::size_t load = domain.addNodalLoad(
fesa::core::NodalLoadDefinition{1, fesa::core::Dof::U3, -100.0});
std::make_unique<fesa::boundary::SinglePointConstraint>(1, fesa::core::Dof::U1, 0.0));
const std::size_t load = domain.addLoad(
std::make_unique<fesa::load::NodalLoad>(1, fesa::core::Dof::U3, -100.0));
domain.addStep(fesa::core::LinearStaticStepDefinition{1, "load-step", {bc}, {load}});
if (const int result = require_throws<std::invalid_argument>([&domain]() {
domain.addElement(fesa::core::ElementDefinition{
domain.addElement(std::make_unique<fesa::element::Mitc4Element>(
101,
fesa::core::ElementType::Mitc4,
{1, 2, 3, 99},
500});
std::array<fesa::core::NodeId, 4>{1, 2, 3, 99},
500));
});
result != 0) {
return result;
@@ -549,7 +567,7 @@ int failed_inserts_do_not_mutate_counts() {
}
if (const int result = require_throws<std::invalid_argument>([&domain]() {
domain.addShellProperty(fesa::core::ShellPropertyDefinition{501, 404, 0.01});
domain.addShellProperty(fesa::property::ShellProperty{501, 404, 0.01});
});
result != 0) {
return result;
@@ -570,7 +588,7 @@ int failed_inserts_do_not_mutate_counts() {
if (const int result = require_throws<std::invalid_argument>([&domain]() {
(void)domain.addBoundaryCondition(
fesa::core::BoundaryCondition{99, fesa::core::Dof::U1, 0.0});
std::make_unique<fesa::boundary::SinglePointConstraint>(99, fesa::core::Dof::U1, 0.0));
});
result != 0) {
return result;
@@ -609,6 +627,9 @@ int run_domain_storage_tests() {
if (const int result = element_referencing_missing_node_throws(); result != 0) {
return result;
}
if (const int result = element_referencing_missing_property_throws(); result != 0) {
return result;
}
if (const int result = missing_element_lookup_contracts(); result != 0) {
return result;
}
@@ -639,13 +660,16 @@ int run_domain_storage_tests() {
if (const int result = missing_node_boundary_condition_and_load_throw(); result != 0) {
return result;
}
if (const int result = duplicate_load_and_boundary_keys_throw(); result != 0) {
return result;
}
if (const int result = add_and_retrieve_linear_static_step(); result != 0) {
return result;
}
if (const int result = duplicate_and_invalid_step_references_throw(); result != 0) {
return result;
}
if (const int result = const_domain_retrieval_returns_const_model_data(); result != 0) {
if (const int result = const_domain_retrieval_returns_const_runtime_model_data(); result != 0) {
return result;
}
if (const int result = failed_inserts_do_not_mutate_counts(); result != 0) {