refactor: store runtime objects in domain
This commit is contained in:
+91
-166
@@ -1,6 +1,11 @@
|
||||
#include "fesa/core/Domain.hpp"
|
||||
|
||||
#include "fesa/boundary/SinglePointConstraint.hpp"
|
||||
#include "fesa/core/BoundaryCondition.hpp"
|
||||
#include "fesa/core/ElementDefinition.hpp"
|
||||
#include "fesa/core/LoadDefinition.hpp"
|
||||
#include "fesa/core/MaterialDefinition.hpp"
|
||||
#include "fesa/core/PropertyDefinition.hpp"
|
||||
#include "fesa/load/NodalLoad.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
@@ -154,28 +159,37 @@ void Domain::addNode(Node node) {
|
||||
}
|
||||
}
|
||||
|
||||
void Domain::addElement(ElementDefinition element) {
|
||||
const ElementId id = element.id();
|
||||
void Domain::addElement(std::unique_ptr<fesa::element::Element> element) {
|
||||
if (!element) {
|
||||
throw std::invalid_argument("element is null");
|
||||
}
|
||||
const ElementId id = element->id();
|
||||
if (elements_.find(id) != elements_.end()) {
|
||||
throw std::invalid_argument("duplicate element id");
|
||||
}
|
||||
for (const NodeId node_id : element.connectivity()) {
|
||||
for (const NodeId node_id : element->connectivity()) {
|
||||
if (findNode(node_id) == nullptr) {
|
||||
throw std::invalid_argument("element references missing node id");
|
||||
}
|
||||
}
|
||||
if (findShellProperty(element->propertyId()) == nullptr) {
|
||||
throw std::invalid_argument("element references missing shell property id");
|
||||
}
|
||||
elements_.emplace(id, std::move(element));
|
||||
}
|
||||
|
||||
void Domain::addMaterial(LinearElasticMaterialDefinition material) {
|
||||
const MaterialId id = material.id();
|
||||
void Domain::addMaterial(std::unique_ptr<fesa::material::Material> material) {
|
||||
if (!material) {
|
||||
throw std::invalid_argument("material is null");
|
||||
}
|
||||
const MaterialId id = material->id();
|
||||
const auto inserted = materials_.emplace(id, std::move(material));
|
||||
if (!inserted.second) {
|
||||
throw std::invalid_argument("duplicate material id");
|
||||
}
|
||||
}
|
||||
|
||||
void Domain::addShellProperty(ShellPropertyDefinition property) {
|
||||
void Domain::addShellProperty(fesa::property::ShellProperty property) {
|
||||
const PropertyId id = property.id();
|
||||
if (shell_properties_.find(id) != shell_properties_.end()) {
|
||||
throw std::invalid_argument("duplicate shell property id");
|
||||
@@ -210,21 +224,48 @@ void Domain::addElementSet(std::string name, std::vector<ElementId> element_ids)
|
||||
element_sets_.emplace(std::move(name), std::move(element_ids));
|
||||
}
|
||||
|
||||
std::size_t Domain::addBoundaryCondition(BoundaryCondition condition) {
|
||||
if (findNode(condition.nodeId()) == nullptr) {
|
||||
throw std::invalid_argument("boundary condition references missing node id");
|
||||
std::size_t Domain::addBoundaryCondition(std::unique_ptr<fesa::boundary::BoundaryCondition> boundary) {
|
||||
if (!boundary) {
|
||||
throw std::invalid_argument("boundary condition is null");
|
||||
}
|
||||
if (const auto* spc = dynamic_cast<const fesa::boundary::SinglePointConstraint*>(boundary.get())) {
|
||||
if (findNode(spc->nodeId()) == nullptr) {
|
||||
throw std::invalid_argument("boundary condition references missing node id");
|
||||
}
|
||||
for (const auto& existing : boundary_conditions_) {
|
||||
const auto* existing_spc =
|
||||
dynamic_cast<const fesa::boundary::SinglePointConstraint*>(existing.get());
|
||||
if (existing_spc != nullptr &&
|
||||
existing_spc->nodeId() == spc->nodeId() &&
|
||||
existing_spc->dof() == spc->dof()) {
|
||||
throw std::invalid_argument("duplicate boundary condition key");
|
||||
}
|
||||
}
|
||||
}
|
||||
const std::size_t index = boundary_conditions_.size();
|
||||
boundary_conditions_.push_back(condition);
|
||||
boundary_conditions_.push_back(std::move(boundary));
|
||||
return index;
|
||||
}
|
||||
|
||||
std::size_t Domain::addNodalLoad(NodalLoadDefinition load) {
|
||||
if (findNode(load.nodeId()) == nullptr) {
|
||||
throw std::invalid_argument("nodal load references missing node id");
|
||||
std::size_t Domain::addLoad(std::unique_ptr<fesa::load::Load> load) {
|
||||
if (!load) {
|
||||
throw std::invalid_argument("load is null");
|
||||
}
|
||||
const std::size_t index = nodal_loads_.size();
|
||||
nodal_loads_.push_back(load);
|
||||
if (const auto* nodal = dynamic_cast<const fesa::load::NodalLoad*>(load.get())) {
|
||||
if (findNode(nodal->nodeId()) == nullptr) {
|
||||
throw std::invalid_argument("nodal load references missing node id");
|
||||
}
|
||||
for (const auto& existing : loads_) {
|
||||
const auto* existing_nodal = dynamic_cast<const fesa::load::NodalLoad*>(existing.get());
|
||||
if (existing_nodal != nullptr &&
|
||||
existing_nodal->nodeId() == nodal->nodeId() &&
|
||||
existing_nodal->dof() == nodal->dof()) {
|
||||
throw std::invalid_argument("duplicate nodal load key");
|
||||
}
|
||||
}
|
||||
}
|
||||
const std::size_t index = loads_.size();
|
||||
loads_.push_back(std::move(load));
|
||||
return index;
|
||||
}
|
||||
|
||||
@@ -239,79 +280,13 @@ void Domain::addStep(LinearStaticStepDefinition step) {
|
||||
}
|
||||
}
|
||||
for (const std::size_t index : step.loadIndices()) {
|
||||
if (index >= nodal_loads_.size()) {
|
||||
throw std::invalid_argument("step references missing nodal load");
|
||||
if (index >= loads_.size()) {
|
||||
throw std::invalid_argument("step references missing load");
|
||||
}
|
||||
}
|
||||
steps_.emplace(id, std::move(step));
|
||||
}
|
||||
|
||||
void Domain::addElementObject(std::unique_ptr<fesa::element::Element> element) {
|
||||
if (!element) {
|
||||
throw std::invalid_argument("element object is null");
|
||||
}
|
||||
const ElementId id = element->id();
|
||||
if (element_objects_.find(id) != element_objects_.end()) {
|
||||
throw std::invalid_argument("duplicate element object id");
|
||||
}
|
||||
for (const NodeId node_id : element->connectivity()) {
|
||||
if (findNode(node_id) == nullptr) {
|
||||
throw std::invalid_argument("element object references missing node id");
|
||||
}
|
||||
}
|
||||
element_objects_.emplace(id, std::move(element));
|
||||
}
|
||||
|
||||
void Domain::addMaterialObject(std::unique_ptr<fesa::material::Material> material) {
|
||||
if (!material) {
|
||||
throw std::invalid_argument("material object is null");
|
||||
}
|
||||
const MaterialId id = material->id();
|
||||
const auto inserted = material_objects_.emplace(id, std::move(material));
|
||||
if (!inserted.second) {
|
||||
throw std::invalid_argument("duplicate material object id");
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t Domain::addLoadObject(std::unique_ptr<fesa::load::Load> load) {
|
||||
if (!load) {
|
||||
throw std::invalid_argument("load object is null");
|
||||
}
|
||||
if (const auto* nodal = dynamic_cast<const fesa::load::NodalLoad*>(load.get())) {
|
||||
for (const auto& existing : load_objects_) {
|
||||
const auto* existing_nodal = dynamic_cast<const fesa::load::NodalLoad*>(existing.get());
|
||||
if (existing_nodal != nullptr &&
|
||||
existing_nodal->nodeId() == nodal->nodeId() &&
|
||||
existing_nodal->dof() == nodal->dof()) {
|
||||
throw std::invalid_argument("duplicate nodal load key");
|
||||
}
|
||||
}
|
||||
}
|
||||
const std::size_t index = load_objects_.size();
|
||||
load_objects_.push_back(std::move(load));
|
||||
return index;
|
||||
}
|
||||
|
||||
std::size_t Domain::addBoundaryObject(std::unique_ptr<fesa::boundary::BoundaryCondition> boundary) {
|
||||
if (!boundary) {
|
||||
throw std::invalid_argument("boundary object is null");
|
||||
}
|
||||
if (const auto* spc = dynamic_cast<const fesa::boundary::SinglePointConstraint*>(boundary.get())) {
|
||||
for (const auto& existing : boundary_objects_) {
|
||||
const auto* existing_spc =
|
||||
dynamic_cast<const fesa::boundary::SinglePointConstraint*>(existing.get());
|
||||
if (existing_spc != nullptr &&
|
||||
existing_spc->nodeId() == spc->nodeId() &&
|
||||
existing_spc->dof() == spc->dof()) {
|
||||
throw std::invalid_argument("duplicate boundary object key");
|
||||
}
|
||||
}
|
||||
}
|
||||
const std::size_t index = boundary_objects_.size();
|
||||
boundary_objects_.push_back(std::move(boundary));
|
||||
return index;
|
||||
}
|
||||
|
||||
const Node* Domain::findNode(NodeId id) const noexcept {
|
||||
const auto it = nodes_.find(id);
|
||||
return it == nodes_.end() ? nullptr : &it->second;
|
||||
@@ -329,13 +304,13 @@ std::size_t Domain::nodeCount() const noexcept {
|
||||
return nodes_.size();
|
||||
}
|
||||
|
||||
const ElementDefinition* Domain::findElement(ElementId id) const noexcept {
|
||||
const fesa::element::Element* Domain::findElement(ElementId id) const noexcept {
|
||||
const auto it = elements_.find(id);
|
||||
return it == elements_.end() ? nullptr : &it->second;
|
||||
return it == elements_.end() ? nullptr : it->second.get();
|
||||
}
|
||||
|
||||
const ElementDefinition& Domain::element(ElementId id) const {
|
||||
const ElementDefinition* found = findElement(id);
|
||||
const fesa::element::Element& Domain::element(ElementId id) const {
|
||||
const fesa::element::Element* found = findElement(id);
|
||||
if (found == nullptr) {
|
||||
throw std::out_of_range("element id not found");
|
||||
}
|
||||
@@ -346,13 +321,13 @@ std::size_t Domain::elementCount() const noexcept {
|
||||
return elements_.size();
|
||||
}
|
||||
|
||||
const LinearElasticMaterialDefinition* Domain::findMaterial(MaterialId id) const noexcept {
|
||||
const fesa::material::Material* Domain::findMaterial(MaterialId id) const noexcept {
|
||||
const auto it = materials_.find(id);
|
||||
return it == materials_.end() ? nullptr : &it->second;
|
||||
return it == materials_.end() ? nullptr : it->second.get();
|
||||
}
|
||||
|
||||
const LinearElasticMaterialDefinition& Domain::material(MaterialId id) const {
|
||||
const LinearElasticMaterialDefinition* found = findMaterial(id);
|
||||
const fesa::material::Material& Domain::material(MaterialId id) const {
|
||||
const fesa::material::Material* found = findMaterial(id);
|
||||
if (found == nullptr) {
|
||||
throw std::out_of_range("material id not found");
|
||||
}
|
||||
@@ -363,13 +338,13 @@ std::size_t Domain::materialCount() const noexcept {
|
||||
return materials_.size();
|
||||
}
|
||||
|
||||
const ShellPropertyDefinition* Domain::findShellProperty(PropertyId id) const noexcept {
|
||||
const fesa::property::ShellProperty* Domain::findShellProperty(PropertyId id) const noexcept {
|
||||
const auto it = shell_properties_.find(id);
|
||||
return it == shell_properties_.end() ? nullptr : &it->second;
|
||||
}
|
||||
|
||||
const ShellPropertyDefinition& Domain::shellProperty(PropertyId id) const {
|
||||
const ShellPropertyDefinition* found = findShellProperty(id);
|
||||
const fesa::property::ShellProperty& Domain::shellProperty(PropertyId id) const {
|
||||
const fesa::property::ShellProperty* found = findShellProperty(id);
|
||||
if (found == nullptr) {
|
||||
throw std::out_of_range("shell property id not found");
|
||||
}
|
||||
@@ -414,20 +389,36 @@ std::size_t Domain::elementSetCount() const noexcept {
|
||||
return element_sets_.size();
|
||||
}
|
||||
|
||||
const BoundaryCondition& Domain::boundaryCondition(std::size_t index) const {
|
||||
return boundary_conditions_.at(index);
|
||||
const fesa::boundary::BoundaryCondition* Domain::findBoundaryCondition(std::size_t index) const noexcept {
|
||||
return index < boundary_conditions_.size() ? boundary_conditions_[index].get() : nullptr;
|
||||
}
|
||||
|
||||
const fesa::boundary::BoundaryCondition& Domain::boundaryCondition(std::size_t index) const {
|
||||
const fesa::boundary::BoundaryCondition* found = findBoundaryCondition(index);
|
||||
if (found == nullptr) {
|
||||
throw std::out_of_range("boundary condition index not found");
|
||||
}
|
||||
return *found;
|
||||
}
|
||||
|
||||
std::size_t Domain::boundaryConditionCount() const noexcept {
|
||||
return boundary_conditions_.size();
|
||||
}
|
||||
|
||||
const NodalLoadDefinition& Domain::nodalLoad(std::size_t index) const {
|
||||
return nodal_loads_.at(index);
|
||||
const fesa::load::Load* Domain::findLoad(std::size_t index) const noexcept {
|
||||
return index < loads_.size() ? loads_[index].get() : nullptr;
|
||||
}
|
||||
|
||||
std::size_t Domain::nodalLoadCount() const noexcept {
|
||||
return nodal_loads_.size();
|
||||
const fesa::load::Load& Domain::load(std::size_t index) const {
|
||||
const fesa::load::Load* found = findLoad(index);
|
||||
if (found == nullptr) {
|
||||
throw std::out_of_range("load index not found");
|
||||
}
|
||||
return *found;
|
||||
}
|
||||
|
||||
std::size_t Domain::loadCount() const noexcept {
|
||||
return loads_.size();
|
||||
}
|
||||
|
||||
const LinearStaticStepDefinition* Domain::findStep(StepId id) const noexcept {
|
||||
@@ -447,70 +438,4 @@ std::size_t Domain::stepCount() const noexcept {
|
||||
return steps_.size();
|
||||
}
|
||||
|
||||
const fesa::element::Element* Domain::findElementObject(ElementId id) const noexcept {
|
||||
const auto it = element_objects_.find(id);
|
||||
return it == element_objects_.end() ? nullptr : it->second.get();
|
||||
}
|
||||
|
||||
const fesa::element::Element& Domain::elementObject(ElementId id) const {
|
||||
const fesa::element::Element* found = findElementObject(id);
|
||||
if (found == nullptr) {
|
||||
throw std::out_of_range("element object id not found");
|
||||
}
|
||||
return *found;
|
||||
}
|
||||
|
||||
std::size_t Domain::elementObjectCount() const noexcept {
|
||||
return element_objects_.size();
|
||||
}
|
||||
|
||||
const fesa::material::Material* Domain::findMaterialObject(MaterialId id) const noexcept {
|
||||
const auto it = material_objects_.find(id);
|
||||
return it == material_objects_.end() ? nullptr : it->second.get();
|
||||
}
|
||||
|
||||
const fesa::material::Material& Domain::materialObject(MaterialId id) const {
|
||||
const fesa::material::Material* found = findMaterialObject(id);
|
||||
if (found == nullptr) {
|
||||
throw std::out_of_range("material object id not found");
|
||||
}
|
||||
return *found;
|
||||
}
|
||||
|
||||
std::size_t Domain::materialObjectCount() const noexcept {
|
||||
return material_objects_.size();
|
||||
}
|
||||
|
||||
const fesa::load::Load* Domain::findLoadObject(std::size_t index) const noexcept {
|
||||
return index < load_objects_.size() ? load_objects_[index].get() : nullptr;
|
||||
}
|
||||
|
||||
const fesa::load::Load& Domain::loadObject(std::size_t index) const {
|
||||
const fesa::load::Load* found = findLoadObject(index);
|
||||
if (found == nullptr) {
|
||||
throw std::out_of_range("load object index not found");
|
||||
}
|
||||
return *found;
|
||||
}
|
||||
|
||||
std::size_t Domain::loadObjectCount() const noexcept {
|
||||
return load_objects_.size();
|
||||
}
|
||||
|
||||
const fesa::boundary::BoundaryCondition* Domain::findBoundaryObject(std::size_t index) const noexcept {
|
||||
return index < boundary_objects_.size() ? boundary_objects_[index].get() : nullptr;
|
||||
}
|
||||
|
||||
const fesa::boundary::BoundaryCondition& Domain::boundaryObject(std::size_t index) const {
|
||||
const fesa::boundary::BoundaryCondition* found = findBoundaryObject(index);
|
||||
if (found == nullptr) {
|
||||
throw std::out_of_range("boundary object index not found");
|
||||
}
|
||||
return *found;
|
||||
}
|
||||
|
||||
std::size_t Domain::boundaryObjectCount() const noexcept {
|
||||
return boundary_objects_.size();
|
||||
}
|
||||
|
||||
} // namespace fesa::core
|
||||
|
||||
Reference in New Issue
Block a user