Files
FESADev/src/fesa/io/abaqus/material_property_candidates.h
T

186 lines
6.3 KiB
C++

#ifndef FESA_IO_ABAQUS_MATERIAL_PROPERTY_CANDIDATES_H_
#define FESA_IO_ABAQUS_MATERIAL_PROPERTY_CANDIDATES_H_
#include <array>
#include <cstddef>
#include <cstdint>
#include <map>
#include <optional>
#include <string>
#include <utility>
#include <vector>
#include "fesa/model/model_types.h"
#include "io/abaqus/mapping_diagnostics.h"
namespace fesa::abaqus_internal {
enum class ElementFamily;
struct RawPart;
struct RawSection {
std::string element_set_name;
std::string material_name;
std::array<double, 5> properties;
std::array<double, 3> first_axis;
std::vector<std::array<double, 2>> section_points;
SourceLocation location;
};
struct RawShellSection {
std::string element_set_name;
std::string material_name;
double thickness;
SourceLocation location;
};
struct RawSolidSection {
std::string element_set_name;
std::string material_name;
SourceLocation location;
};
/// @brief Owns source section candidates for one part before resolution.
struct PartPropertyCandidates {
std::vector<RawSection> sections;
std::vector<RawShellSection> shell_sections;
std::vector<RawSolidSection> solid_sections;
};
/// @brief Supplies procedure policy without giving material mapping step state.
struct MaterialProcedureView {
struct Surface {
SourceLocation location;
std::string name;
};
bool frequency;
bool dynamic;
const SourceLocation& location;
const std::string& name_raw;
std::optional<Surface> first_surface;
const std::optional<SourceLocation>& physical_constants_location;
};
/// @brief Owns material candidates, their validation, and section assignments.
/// @note The context-owned diagnostics, input, and family outlive this object.
class MaterialPropertyCandidates {
public:
using Assignments =
std::map<std::int64_t, std::pair<EntityIndex, EntityIndex>>;
/// @brief Borrows context services while owning this uncommitted mapping
/// stage.
MaterialPropertyCandidates(MappingDiagnostics& diagnostics,
const ParsedInput& input,
const std::optional<ElementFamily>& family)
: diagnostics_{diagnostics},
input_{input},
model_element_family_{family} {}
/// @brief Returns the source material declaration count.
std::size_t Count() const noexcept { return materials_.size(); }
/// @brief Reports whether no source material has been declared.
bool Empty() const noexcept { return materials_.empty(); }
/// @brief Reports whether a material child may follow the current
/// declaration.
bool HasActiveMaterial() const noexcept {
return material_eligible_.has_value();
}
/// @brief Ends the optional section-point continuation scope.
void EndSection() noexcept { pending_section_.reset(); }
/// @brief Ends the material-child continuation scope.
void EndMaterial() noexcept { material_eligible_.reset(); }
/// @brief Borrows resolved beam section and material indices for one part.
const Assignments& BeamAssignments(std::size_t part) const {
return part_section_assignments_[part];
}
/// @brief Borrows resolved shell or solid property and material indices for
/// one part.
const Assignments& ShellAssignments(std::size_t part) const {
return part_shell_section_assignments_[part];
}
/// @brief Parses material-only solid assignments without introducing
/// thickness.
void ParseSolidSection(const KeywordBlock& block,
PartPropertyCandidates& properties);
/// @brief Parses centered shell thickness and source integration-point
/// metadata.
void ParseShellSection(const KeywordBlock& block,
PartPropertyCandidates& properties);
/// @brief Parses general beam properties and their global guide vector.
void ParseBeamSection(const KeywordBlock& block,
PartPropertyCandidates& properties);
/// @brief Parses optional beam stress points in the active section scope.
void ParseSectionPoints(const KeywordBlock& block,
PartPropertyCandidates& properties);
/// @brief Starts one source material after syntax ordering has been checked.
void ParseMaterial(const KeywordBlock& block);
/// @brief Parses an elastic row without conflating beam and shell material
/// ranges.
void ParseElastic(const KeywordBlock& block);
/// @brief Parses positive finite density with its source-specific failure
/// policy.
void ParseDensity(const KeywordBlock& block);
/// @brief Parses constant conductivity or specific heat in the thermal
/// subset.
void ParseThermalProperty(const KeywordBlock& block, bool conductivity);
/// @brief Appends validated material definitions in source order.
void FinalizeMaterials(ModelDefinition& definition);
/// @brief Validates part references and unique section/material assignments.
void FinalizePartsAndSections(const std::vector<RawPart>& parts,
ModelDefinition& definition);
/// @brief Checks procedure policy before appending active material densities.
void FinalizeDensities(const MaterialProcedureView& procedure,
ModelDefinition& definition);
private:
struct RawMaterial {
std::string name;
double youngs_modulus{0.0};
double poisson_ratio{0.0};
bool has_elastic{false};
std::optional<double> density;
std::optional<double> conductivity;
std::optional<double> specific_heat;
SourceLocation location;
SourceLocation elastic_location;
SourceLocation density_location;
};
bool ParseDensityValue(const std::string& text, double& value,
const SourceLocation& location);
std::optional<EntityIndex> FindMaterialIndex(const std::string& name) const;
void ValidateFrequencyPreprint(ModelDefinition& definition);
void ValidateDynamicPreprint();
bool ContainsName(const std::vector<RawMaterial>& values,
const std::string& name) const;
MappingDiagnostics& diagnostics_;
const ParsedInput& input_;
const std::optional<ElementFamily>& model_element_family_;
std::vector<RawMaterial> materials_;
std::optional<std::size_t> material_eligible_;
std::optional<std::size_t> pending_section_;
std::vector<Assignments> part_section_assignments_;
std::vector<Assignments> part_shell_section_assignments_;
};
} // namespace fesa::abaqus_internal
#endif // FESA_IO_ABAQUS_MATERIAL_PROPERTY_CANDIDATES_H_