#include "fesa/boundary/SinglePointConstraint.hpp" #include "fesa/core/Domain.hpp" #include "fesa/core/Node.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 #include #include #include namespace { int require(bool condition) { return condition ? 0 : 1; } template int require_throws(Function&& function) { try { function(); } catch (const Exception&) { return 0; } catch (...) { return 1; } 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(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( 100, std::array{1, 2, 3, 4}, 500)); } int add_and_retrieve_node_by_id() { fesa::core::Domain domain; domain.addNode(fesa::core::Node{10, 1.0, 2.0, 3.0}); if (const int result = require(domain.nodeCount() == 1); result != 0) { return result; } const fesa::core::Node* found = domain.findNode(10); if (const int result = require(found != nullptr); result != 0) { return result; } if (const int result = require(found->id() == 10); result != 0) { return result; } if (const int result = require(found->x() == 1.0); result != 0) { return result; } if (const int result = require(found->y() == 2.0); result != 0) { return result; } if (const int result = require(found->z() == 3.0); result != 0) { return result; } const fesa::core::Node& direct = domain.node(10); return require(direct.id() == 10); } int missing_node_lookup_contracts() { const fesa::core::Domain domain; if (const int result = require(domain.findNode(99) == nullptr); result != 0) { return result; } return require_throws([&domain]() { (void)domain.node(99); }); } int duplicate_node_id_throws() { fesa::core::Domain domain; domain.addNode(fesa::core::Node{10, 0.0, 0.0, 0.0}); return require_throws([&domain]() { domain.addNode(fesa::core::Node{10, 1.0, 0.0, 0.0}); }); } int add_and_retrieve_element_by_id() { fesa::core::Domain domain; add_four_nodes(domain); add_material_and_property(domain); add_element(domain); if (const int result = require(domain.elementCount() == 1); result != 0) { return result; } const fesa::element::Element* found = domain.findElement(100); if (const int result = require(found != nullptr); result != 0) { return result; } if (const int result = require(found->id() == 100); result != 0) { return result; } if (const int result = require(found->type() == fesa::core::ElementType::Mitc4); result != 0) { return result; } if (const int result = require(found->propertyId() == 500); result != 0) { return result; } if (const int result = require(found->connectivity()[0] == 1); result != 0) { return result; } if (const int result = require(found->connectivity()[1] == 2); result != 0) { return result; } if (const int result = require(found->connectivity()[2] == 3); result != 0) { return result; } if (const int result = require(found->connectivity()[3] == 4); result != 0) { return result; } 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); add_material_and_property(domain); add_element(domain); return require_throws([&domain]() { domain.addElement(std::make_unique( 100, std::array{1, 2, 3, 4}, 500)); }); } int element_referencing_missing_node_throws() { 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}); add_material_and_property(domain); return require_throws([&domain]() { domain.addElement(std::make_unique( 100, std::array{1, 2, 3, 4}, 500)); }); } int element_referencing_missing_property_throws() { fesa::core::Domain domain; add_four_nodes(domain); domain.addMaterial(std::make_unique(700, 210.0, 0.3)); return require_throws([&domain]() { domain.addElement(std::make_unique( 100, std::array{1, 2, 3, 4}, 500)); }); } int missing_element_lookup_contracts() { const fesa::core::Domain domain; if (const int result = require(domain.findElement(404) == nullptr); result != 0) { return result; } return require_throws([&domain]() { (void)domain.element(404); }); } int add_and_retrieve_material_and_property() { fesa::core::Domain domain; add_material_and_property(domain); if (const int result = require(domain.materialCount() == 1); result != 0) { return result; } if (const int result = require(domain.shellPropertyCount() == 1); result != 0) { return result; } 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->id() == 700); result != 0) { return result; } const fesa::property::ShellProperty* property = domain.findShellProperty(500); if (const int result = require(property != nullptr); result != 0) { return result; } if (const int result = require(property->materialId() == 700); result != 0) { return result; } if (const int result = require(property->thickness() == 0.01); result != 0) { return result; } if (const int result = require(domain.material(700).id() == 700); result != 0) { return result; } return require(domain.shellProperty(500).id() == 500); } int duplicate_material_and_property_ids_throw() { fesa::core::Domain domain; add_material_and_property(domain); if (const int result = require_throws([&domain]() { domain.addMaterial(std::make_unique(700, 100.0, 0.25)); }); result != 0) { return result; } return require_throws([&domain]() { domain.addShellProperty(fesa::property::ShellProperty{500, 700, 0.02}); }); } int shell_property_referencing_missing_material_throws() { fesa::core::Domain domain; return require_throws([&domain]() { domain.addShellProperty(fesa::property::ShellProperty{500, 700, 0.01}); }); } int add_and_retrieve_sets() { fesa::core::Domain domain; add_four_nodes(domain); add_material_and_property(domain); add_element(domain); domain.addNodeSet("left-edge", {1, 4}); domain.addElementSet("shells", {100}); const auto* node_set = domain.findNodeSet("left-edge"); if (const int result = require(node_set != nullptr); result != 0) { return result; } if (const int result = require(node_set->size() == 2); result != 0) { return result; } if (const int result = require((*node_set)[0] == 1); result != 0) { return result; } if (const int result = require((*node_set)[1] == 4); result != 0) { return result; } const auto* element_set = domain.findElementSet("shells"); if (const int result = require(element_set != nullptr); result != 0) { return result; } if (const int result = require(element_set->size() == 1); result != 0) { return result; } if (const int result = require((*element_set)[0] == 100); result != 0) { return result; } if (const int result = require(domain.nodeSetCount() == 1); result != 0) { return result; } return require(domain.elementSetCount() == 1); } int duplicate_set_names_throw() { fesa::core::Domain domain; add_four_nodes(domain); add_material_and_property(domain); add_element(domain); domain.addNodeSet("left-edge", {1, 4}); domain.addElementSet("shells", {100}); if (const int result = require_throws([&domain]() { domain.addNodeSet("left-edge", {1}); }); result != 0) { return result; } return require_throws([&domain]() { domain.addElementSet("shells", {100}); }); } int sets_referencing_missing_ids_throw() { fesa::core::Domain domain; add_four_nodes(domain); add_material_and_property(domain); add_element(domain); if (const int result = require_throws([&domain]() { domain.addNodeSet("bad-nodes", {1, 99}); }); result != 0) { return result; } return require_throws([&domain]() { domain.addElementSet("bad-elements", {100, 404}); }); } int add_and_retrieve_boundary_condition() { fesa::core::Domain domain; domain.addNode(fesa::core::Node{1, 0.0, 0.0, 0.0}); const std::size_t index = domain.addBoundaryCondition( std::make_unique(1, fesa::core::Dof::U1, 0.0)); if (const int result = require(index == 0); result != 0) { return result; } if (const int result = require(domain.boundaryConditionCount() == 1); result != 0) { return result; } const fesa::boundary::BoundaryCondition& condition = domain.boundaryCondition(index); if (const int result = require(condition.kind() == fesa::boundary::BoundaryConditionKind::SinglePointConstraint); result != 0) { return result; } const auto& spc = static_cast(condition); if (const int result = require(spc.nodeId() == 1); result != 0) { return result; } 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.addLoad( std::make_unique(1, fesa::core::Dof::U3, -100.0)); if (const int result = require(index == 0); result != 0) { return result; } if (const int result = require(domain.loadCount() == 1); result != 0) { return result; } const fesa::load::Load& load = domain.load(index); if (const int result = require(load.kind() == fesa::load::LoadKind::Nodal); result != 0) { return result; } const auto& nodal_load = static_cast(load); if (const int result = require(nodal_load.nodeId() == 1); result != 0) { return result; } 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() { fesa::core::Domain domain; if (const int result = require_throws([&domain]() { (void)domain.addBoundaryCondition( std::make_unique(99, fesa::core::Dof::U1, 0.0)); }); result != 0) { return result; } return require_throws([&domain]() { (void)domain.addLoad( std::make_unique(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(1, fesa::core::Dof::U1, 0.0)); domain.addLoad(std::make_unique(1, fesa::core::Dof::U3, -100.0)); if (const int result = require_throws([&domain]() { (void)domain.addBoundaryCondition( std::make_unique(1, fesa::core::Dof::U1, 1.0)); }); result != 0) { return result; } return require_throws([&domain]() { (void)domain.addLoad( std::make_unique(1, fesa::core::Dof::U3, -200.0)); }); } 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( std::make_unique(1, fesa::core::Dof::U1, 0.0)); const std::size_t load = domain.addLoad( std::make_unique(1, fesa::core::Dof::U3, -100.0)); domain.addStep(fesa::core::LinearStaticStepDefinition{1, "load-step", {bc}, {load}}); if (const int result = require(domain.stepCount() == 1); result != 0) { return result; } const fesa::core::LinearStaticStepDefinition* found = domain.findStep(1); if (const int result = require(found != nullptr); result != 0) { return result; } if (const int result = require(found->id() == 1); result != 0) { return result; } if (const int result = require(found->name() == "load-step"); result != 0) { return result; } if (const int result = require(found->boundaryConditionIndices().size() == 1); result != 0) { return result; } if (const int result = require(found->boundaryConditionIndices()[0] == bc); result != 0) { return result; } if (const int result = require(found->loadIndices().size() == 1); result != 0) { return result; } return require(found->loadIndices()[0] == load); } 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( std::make_unique(1, fesa::core::Dof::U1, 0.0)); const std::size_t load = domain.addLoad( std::make_unique(1, fesa::core::Dof::U3, -100.0)); domain.addStep(fesa::core::LinearStaticStepDefinition{1, "load-step", {bc}, {load}}); if (const int result = require_throws([&domain, bc, load]() { domain.addStep(fesa::core::LinearStaticStepDefinition{1, "duplicate", {bc}, {load}}); }); result != 0) { return result; } if (const int result = require_throws([&domain, load]() { domain.addStep(fesa::core::LinearStaticStepDefinition{2, "bad-bc", {99}, {load}}); }); result != 0) { return result; } return require_throws([&domain, bc]() { domain.addStep(fesa::core::LinearStaticStepDefinition{2, "bad-load", {bc}, {99}}); }); } int const_domain_retrieval_returns_const_runtime_model_data() { fesa::core::Domain domain; add_four_nodes(domain); 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( std::make_unique(1, fesa::core::Dof::U1, 0.0)); const std::size_t load = domain.addLoad( std::make_unique(1, fesa::core::Dof::U3, -100.0)); domain.addStep(fesa::core::LinearStaticStepDefinition{1, "load-step", {bc}, {load}}); const fesa::core::Domain& const_domain = domain; if (const int result = require((std::is_same::value)); result != 0) { return result; } if (const int result = require((std::is_same::value)); result != 0) { return result; } if (const int result = require((std::is_same::value)); result != 0) { return result; } if (const int result = require((std::is_same::value)); result != 0) { return result; } if (const int result = require((std::is_same&>::value)); result != 0) { return result; } if (const int result = require((std::is_same&>::value)); result != 0) { return result; } if (const int result = require((std::is_same::value)); result != 0) { return result; } if (const int result = require((std::is_same::value)); result != 0) { return result; } return require((std::is_same::value)); } int failed_inserts_do_not_mutate_counts() { fesa::core::Domain domain; add_four_nodes(domain); 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( std::make_unique(1, fesa::core::Dof::U1, 0.0)); const std::size_t load = domain.addLoad( std::make_unique(1, fesa::core::Dof::U3, -100.0)); domain.addStep(fesa::core::LinearStaticStepDefinition{1, "load-step", {bc}, {load}}); if (const int result = require_throws([&domain]() { domain.addElement(std::make_unique( 101, std::array{1, 2, 3, 99}, 500)); }); result != 0) { return result; } if (const int result = require(domain.elementCount() == 1); result != 0) { return result; } if (const int result = require_throws([&domain]() { domain.addShellProperty(fesa::property::ShellProperty{501, 404, 0.01}); }); result != 0) { return result; } if (const int result = require(domain.shellPropertyCount() == 1); result != 0) { return result; } if (const int result = require_throws([&domain]() { domain.addNodeSet("bad-nodes", {1, 99}); }); result != 0) { return result; } if (const int result = require(domain.nodeSetCount() == 1); result != 0) { return result; } if (const int result = require_throws([&domain]() { (void)domain.addBoundaryCondition( std::make_unique(99, fesa::core::Dof::U1, 0.0)); }); result != 0) { return result; } if (const int result = require(domain.boundaryConditionCount() == 1); result != 0) { return result; } if (const int result = require_throws([&domain, bc]() { domain.addStep(fesa::core::LinearStaticStepDefinition{2, "bad-load", {bc}, {99}}); }); result != 0) { return result; } return require(domain.stepCount() == 1); } } // namespace int run_domain_storage_tests() { if (const int result = add_and_retrieve_node_by_id(); result != 0) { return result; } if (const int result = missing_node_lookup_contracts(); result != 0) { return result; } if (const int result = duplicate_node_id_throws(); result != 0) { return result; } if (const int result = add_and_retrieve_element_by_id(); result != 0) { return result; } if (const int result = duplicate_element_id_throws(); result != 0) { return result; } 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; } if (const int result = add_and_retrieve_material_and_property(); result != 0) { return result; } if (const int result = duplicate_material_and_property_ids_throw(); result != 0) { return result; } if (const int result = shell_property_referencing_missing_material_throws(); result != 0) { return result; } if (const int result = add_and_retrieve_sets(); result != 0) { return result; } if (const int result = duplicate_set_names_throw(); result != 0) { return result; } if (const int result = sets_referencing_missing_ids_throw(); result != 0) { return result; } if (const int result = add_and_retrieve_boundary_condition(); result != 0) { return result; } if (const int result = add_and_retrieve_nodal_load(); result != 0) { return result; } 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_runtime_model_data(); result != 0) { return result; } if (const int result = failed_inserts_do_not_mutate_counts(); result != 0) { return result; } return 0; }