stellar_model.hpp functional span tuple type_traits utility serif/model/detail/specification_list.hpp serif/model/equilibrium_equations.hpp src/include/serif/backend/mfem/model/finite_elements.hpp src/include/serif/model/description.hpp src/include/serif/solver/continuation/family.hpp src/include/serif/solver/seed/polytrope.hpp src/include/serif/utils/serialize/model.hpp serif::model::StellarModel< EquationOfStateT, EquationDefinitionT, utils::types::TypeList< Specifications... > > serif serif::model serif::model::detail #pragmaonce #include<functional> #include<span> #include<tuple> #include<type_traits> #include<utility> #include"serif/model/detail/specification_list.hpp" #include"serif/model/equilibrium_equations.hpp" namespaceserif::model { template<typename...Specifications> conceptValidSpecificationPack=(ModelSpecification<Specifications>&&...)&& ((Specifications::ModelDefinition::role!=SpecificationRole::constitutive_law)&&...)&&detail::unique_specification_names<Specifications...>(); template<typenameEquationOfStateT,typenameEquationDefinitionT,typenameSpecificationList> classStellarModel; template<typenameEquationOfStateT,typenameEquationDefinitionT,typename...Specifications> requiresValidSpecificationPack<Specifications...>&&std::is_object_v<EquationOfStateT>&&std::is_object_v<EquationDefinitionT> classStellarModel<EquationOfStateT,EquationDefinitionT,utils::types::TypeList<Specifications...>>final { public: usingEquationOfState=EquationOfStateT; usingEquations=EquationDefinitionT; usingSpecificationTypes=utils::types::TypeList<Specifications...>; staticconstexprstd::size_tspecification_count=sizeof...(Specifications)+1; template<SpecificationRoleRole> usingSpecificationsForRole=std::conditional_t<Role==SpecificationRole::constitutive_law,utils::types::TypeList<EquationOfState>,typenamedetail::SelectRole<Role,Specifications...>::Type>; template<SpecificationRoleRole> staticconstexprstd::size_tspecification_role_count=std::size_t{Role==SpecificationRole::constitutive_law}+(std::size_t{0}+...+std::size_t{Specifications::ModelDefinition::role==Role}); template<typenameSpecification> staticconstexprboolcontains_specification=std::same_as<std::remove_cvref_t<Specification>,EquationOfState>||(std::same_as<std::remove_cvref_t<Specification>,Specifications>||...); template<typename...Arguments> requiresdetail::ArgumentsMatch<SpecificationTypes,Arguments...>::value&&(std::constructible_from<std::remove_cvref_t<Arguments>,Arguments>&&...) explicitStellarModel(EquationOfStateequation_of_state,Equationsequations,Arguments&&...specifications): m_equation_of_state(std::move(equation_of_state)),m_equations(std::move(equations)), m_specifications(detail::canonical_specifications(SpecificationTypes{},std::forward<Arguments>(specifications)...)) { } [[nodiscard]]constEquationOfState&equation_of_state()constnoexcept { returnm_equation_of_state; } [[nodiscard]]constEquations&equations()constnoexcept { returnm_equations; } template<typenameSpecification> requirescontains_specification<Specification> [[nodiscard]]conststd::remove_cvref_t<Specification>&specification()constnoexcept { ifconstexpr(std::same_as<std::remove_cvref_t<Specification>,EquationOfState>) { returnm_equation_of_state; } else { returnstd::get<std::remove_cvref_t<Specification>>(m_specifications); } } template<SpecificationRoleRole> [[nodiscard]]autospecifications_for_role()constnoexcept { return[this]<typename...Selected>(utils::types::TypeList<Selected...>) { returnstd::tuple<constSelected&...>{specification<Selected>()...}; }(SpecificationsForRole<Role>{}); } template<SpecificationRoleRole> requires(specification_role_count<Role>==1) [[nodiscard]]constauto&specification_for_role()constnoexcept { returnstd::get<0>(specifications_for_role<Role>()); } template<typenameVisitor> requiresstd::invocable<Visitor&,constEquationOfState&>&&(std::invocable<Visitor&,constSpecifications&>&&...) voidvisit_specifications(Visitor&&visitor)const { std::invoke(visitor,m_equation_of_state); (std::invoke(visitor,specification<Specifications>()),...); } template<typenameTransform> requiresstd::copy_constructible<Equations>&&std::invocable<Transform&,constEquationOfState&>&& std::same_as<std::remove_cvref_t<std::invoke_result_t<Transform&,constEquationOfState&>>,EquationOfState>&& (std::invocable<Transform&,constSpecifications&>&&...)&& (std::same_as<std::remove_cvref_t<std::invoke_result_t<Transform&,constSpecifications&>>,Specifications>&&...) [[nodiscard]]StellarModeltransform_specifications(Transform&&transform)const { returntransform_specifications(std::forward<Transform>(transform),m_equations); } template<typenameTransform> requiresstd::invocable<Transform&,constEquationOfState&>&& std::same_as<std::remove_cvref_t<std::invoke_result_t<Transform&,constEquationOfState&>>,EquationOfState>&& (std::invocable<Transform&,constSpecifications&>&&...)&& (std::same_as<std::remove_cvref_t<std::invoke_result_t<Transform&,constSpecifications&>>,Specifications>&&...) [[nodiscard]]StellarModeltransform_specifications(Transform&&transform,Equationsequations)const { returnStellarModel{std::invoke(transform,m_equation_of_state),std::move(equations),std::invoke(transform,specification<Specifications>())...}; } [[nodiscard]]staticconstexprstd::span<constSpecificationDescriptor>specification_descriptors()noexcept { staticconstexprstd::array<SpecificationDescriptor,sizeof...(Specifications)>descriptions{{ {Specifications::ModelDefinition::name,Specifications::ModelDefinition::role,Specifications::ModelDefinition::generated_state_kind}... }}; returndescriptions; } private: EquationOfStatem_equation_of_state; Equationsm_equations; std::tuple<Specifications...>m_specifications; }; template<typenameEOS,typenameDefinition,typename...Specifications> requiresValidSpecificationPack<std::remove_cvref_t<Specifications>...> StellarModel(EOS&&,Definition&&,Specifications&&...)->StellarModel<std::remove_cvref_t<EOS>,std::remove_cvref_t<Definition>,typenamedetail::CanonicalSpecifications<std::remove_cvref_t<Specifications>...>::Type>; template<typenameEOS,typenameDefinition,typename...Specifications> requiresValidSpecificationPack<std::remove_cvref_t<Specifications>...> [[nodiscard]]automake_stellar_model(EOS&&eos,Definition&&definition,Specifications&&...specifications) { returnStellarModel{std::forward<EOS>(eos),std::forward<Definition>(definition),std::forward<Specifications>(specifications)...}; } namespacedetail { template<typenameCandidate,typename=void> inlineconstexprboolis_stellar_model=false; template<typenameEOS,typenameDefinition,typenameList> inlineconstexprboolis_stellar_model<StellarModel<EOS, Definition, List>,std::void_t<typenameStellarModel<EOS,Definition,List>::SpecificationTypes>>=true; }//namespacedetail template<typenameCandidate> conceptStellarModelType=detail::is_stellar_model<std::remove_cvref_t<Candidate>>; template<SpecificationRoleRole,typenameCandidate> inlineconstexprstd::size_tspecification_role_count=[] { ifconstexpr(StellarModelType<Candidate>) { returnstd::remove_cvref_t<Candidate>::templatespecification_role_count<Role>; } else { returnstd::size_t{0}; } }(); template<SpecificationRoleRole,typenameCandidate> conceptHasUniqueSpecificationForRole=StellarModelType<Candidate>&&specification_role_count<Role, Candidate>==1; template<SpecificationRoleRole,StellarModelTypeCandidate> usingSpecificationsForRole=typenamestd::remove_cvref_t<Candidate>::templateSpecificationsForRole<Role>; }//namespaceserif::model