specification.hpp array concepts limits string_view type_traits serif/dimensions/quantities.hpp serif/utils/types/strings.hpp serif/utils/types/type_list.hpp src/include/serif/model/description.hpp src/include/serif/model/detail/specification_endpoints.hpp src/include/serif/model/detail/specification_list.hpp src/include/serif/model/specifications/fixed_angular_momentum.hpp src/include/serif/model/specifications/fixed_total_mass.hpp serif::model::ScalarConstraint serif::model::SpecificationDefinition serif::model::GeneratedCoordinateOf serif::model::ConstraintOf serif::model::EnforcementOf serif::model::SpecificationDescriptor serif serif::model serif::model::detail #pragmaonce #include<array> #include<concepts> #include<limits> #include<string_view> #include<type_traits> #include"serif/dimensions/quantities.hpp" #include"serif/utils/types/strings.hpp" #include"serif/utils/types/type_list.hpp" namespaceserif::model { enumclassSpecificationRole { constitutive_law,boundary_condition,invariant,phase_condition,gauge_choice,rotation_law }; enumclassGeneratedStateKind { none,multiplier,physical_coordinate,solver_border }; template<dimensions::PhysicalQuantityTypeTarget,dimensions::PhysicalQuantityTypeCoordinate,dimensions::PhysicalQuantityTypeResidual, utils::types::FixedStringCoordinateId,utils::types::FixedStringCoordinateSymbol,utils::types::FixedStringResidualId,utils::types::FixedStringResidualSymbol> structScalarConstraint { usingTargetQuantity=Target; usingCoordinateQuantity=Coordinate; usingResidualQuantity=Residual; usingTargetValue=dimensions::QuantityValue<Target>; staticconstexprstd::string_viewcoordinate_id{CoordinateId.data(),CoordinateId.size()}; staticconstexprstd::string_viewcoordinate_symbol{CoordinateSymbol.data(),CoordinateSymbol.size()}; staticconstexprstd::string_viewresidual_id{ResidualId.data(),ResidualId.size()}; staticconstexprstd::string_viewresidual_symbol{ResidualSymbol.data(),ResidualSymbol.size()}; }; template<typename...Fields> usingReads=utils::types::TypeList<Fields...>; template<typename...Equations> usingChanges=utils::types::TypeList<Equations...>; template<typenameOwner,utils::types::FixedStringName,SpecificationRoleRole,GeneratedStateKindKind=GeneratedStateKind::none, typenameScalar=void,typenameReadFields=Reads<>,typenameChangedEquations=Changes<>> structSpecificationDefinition { usingSpecificationType=Owner; usingScalarDescription=Scalar; usingDependsOn=ReadFields; usingAffects=ChangedEquations; staticconstexprstd::string_viewname{Name.data(),Name.size()}; staticconstexprSpecificationRolerole=Role; staticconstexprGeneratedStateKindgenerated_state_kind=Kind; }; namespacedetail { [[nodiscard]]constevalboolcompatible_generated_state(SpecificationRolerole,GeneratedStateKindkind) { switch(role) { caseSpecificationRole::constitutive_law: caseSpecificationRole::boundary_condition: caseSpecificationRole::rotation_law: returnkind==GeneratedStateKind::none; caseSpecificationRole::invariant: returnkind==GeneratedStateKind::multiplier||kind==GeneratedStateKind::physical_coordinate; caseSpecificationRole::phase_condition: caseSpecificationRole::gauge_choice: returnkind==GeneratedStateKind::solver_border; } returnfalse; } template<typenameCandidate> inlineconstexprboolis_type_list=false; template<typename...Types> inlineconstexprboolis_type_list<utils::types::TypeList<Types...>>=true; }//namespacedetail template<typenameCandidate> conceptModelSpecification=requires { typenamestd::remove_cvref_t<Candidate>::ModelDefinition; requiresstd::same_as<typenamestd::remove_cvref_t<Candidate>::ModelDefinition::SpecificationType,std::remove_cvref_t<Candidate>>; {std::remove_cvref_t<Candidate>::ModelDefinition::name}->std::convertible_to<std::string_view>; requires(!std::remove_cvref_t<Candidate>::ModelDefinition::name.empty()); requiresdetail::compatible_generated_state(std::remove_cvref_t<Candidate>::ModelDefinition::role,std::remove_cvref_t<Candidate>::ModelDefinition::generated_state_kind); requiresdetail::is_type_list<typename std::remove_cvref_t<Candidate>::ModelDefinition::DependsOn>; requiresdetail::is_type_list<typename std::remove_cvref_t<Candidate>::ModelDefinition::Affects>; }; template<typenameCandidate> conceptDimensionalScalarSpecification=ModelSpecification<Candidate>&&requires(conststd::remove_cvref_t<Candidate>&specification) { requires(std::remove_cvref_t<Candidate>::ModelDefinition::generated_state_kind!=GeneratedStateKind::none); typenamestd::remove_cvref_t<Candidate>::ModelDefinition::ScalarDescription::TargetQuantity; typenamestd::remove_cvref_t<Candidate>::ModelDefinition::ScalarDescription::CoordinateQuantity; typenamestd::remove_cvref_t<Candidate>::ModelDefinition::ScalarDescription::ResidualQuantity; requiresdimensions::PhysicalQuantityType<typename std::remove_cvref_t<Candidate>::ModelDefinition::ScalarDescription::CoordinateQuantity>; requiresdimensions::PhysicalQuantityType<typename std::remove_cvref_t<Candidate>::ModelDefinition::ScalarDescription::ResidualQuantity>; {specification.target()}->std::same_as<dimensions::QuantityValue<typenamestd::remove_cvref_t<Candidate>::ModelDefinition::ScalarDescription::TargetQuantity>>; }; template<typenameSpecification> structGeneratedCoordinateOf { usingSpecificationType=Specification; staticconstexprstd::size_tscalar_arity=1; staticconstexprboolglobal_scalar=true; }; template<typenameSpecification> structConstraintOf { usingSpecificationType=Specification; staticconstexprstd::size_tscalar_arity=1; staticconstexprboolglobal_scalar=true; }; template<typenameSpecification> structEnforcementOf { usingSpecificationType=Specification; }; template<DimensionalScalarSpecificationSpecification> usingGeneratedCoordinateQuantity=typenameSpecification::ModelDefinition::ScalarDescription::CoordinateQuantity; template<DimensionalScalarSpecificationSpecification> usingConstraintQuantity=typenameSpecification::ModelDefinition::ScalarDescription::ResidualQuantity; structSpecificationDescriptor { std::string_viewname; SpecificationRolerole; GeneratedStateKindgenerated_state_kind; }; }//namespaceserif::model