batches.hpp array serif/geometry/surface/detail/evaluation.hpp serif/geometry/surface/samples.hpp src/include/serif/geometry/surface/computations.hpp serif serif::geometry serif::geometry::surface serif::geometry::surface::detail #pragmaonce #include<array> #include"serif/geometry/surface/detail/evaluation.hpp" #include"serif/geometry/surface/samples.hpp" namespaceserif::geometry::surface::detail { template<typename...Terms> [[nodiscard]]std::expected<std::size_t,SurfaceFailure>surface_sample_count(constBoundaryValues<Terms>&...columns) { ifconstexpr(sizeof...(Terms)==0) { //Apressure-onlyrelationhasoneconstantresponse,broadcastoverthecarriersampleslater. return1; } else { conststd::array<std::size_t,sizeof...(Terms)>counts{columns.values.size()...}; if(counts.front()==0) { returnstd::unexpected(SurfaceFailure{.reason=SurfaceFailureReason::empty_surface,.message="Asurfacecalculationrequiresatleastoneboundarysample."}); } for(conststd::size_tcount:counts) { if(count!=counts.front()) { returnstd::unexpected(SurfaceFailure{.reason=SurfaceFailureReason::inconsistent_sample_count,.message="Surfacetermsmustbesampledatthesameorderedboundarypoints;theirsamplecountsdiffer."}); } } returncounts.front(); } } template<PressureSurfaceFormulationTypeFormulation,typename...Terms> [[nodiscard]]SurfacePoint<Formulation>surface_point(conststd::size_tsample,constBoundaryValues<Terms>&...columns) { SurfacePoint<Formulation>point{}; ((point.fields.templateget<Terms>()=columns.values[sample]),...); returnpoint; } template<typenameValue,typenameEvaluate> [[nodiscard]]std::expected<std::vector<Value>,SurfaceFailure>collect_surface_samples(std::size_tcount,Evaluateevaluate) { std::vector<Value>result; result.reserve(count); for(std::size_tsample=0;sample<count;++sample) { autovalue=evaluate(sample); if(!value) { SurfaceFailurefailure=value.error(); failure.sample=sample; returnstd::unexpected(failure); } result.push_back(std::move(*value)); } returnresult; } template<PressureSurfaceFormulationTypeFormulation,typename...Terms> [[nodiscard]]std::expected<std::vector<SurfaceEOSResponse<Formulation>>,SurfaceFailure>evaluate_response_samples(consttypenameFormulation::EquationOfState&equation_of_state,constdimensions::PressureValuepressure,constBoundaryValues<Terms>&...columns) { constautocount=surface_sample_count(columns...); if(!count) { returnstd::unexpected(count.error()); } returncollect_surface_samples<SurfaceEOSResponse<Formulation>>(*count,[&](std::size_tsample) { returnevaluate_surface_response<Formulation>(equation_of_state,pressure,surface_point<Formulation>(sample,columns...)); }); } template<PressureSurfaceFormulationTypeFormulation> [[nodiscard]]std::expected<std::vector<SurfaceLinearization<Formulation>>,SurfaceFailure>linearize_carrier_samples(conststd::vector<SurfaceEOSResponse<Formulation>>&responses,constBoundaryValues<typenameFormulation::CarrierTerm>&carrier) { constexprboolconstant_response=std::same_as<typenameFormulation::EOSStateTerms,utils::dependencies::KeyList<>>; constautocount=surface_sample_count(carrier); if(!count) { returnstd::unexpected(count.error()); } if(responses.size()!=(constant_response?1:*count)) { returnstd::unexpected(SurfaceFailure{.reason=SurfaceFailureReason::inconsistent_sample_count,.message="ThecarrierandEOSinputsmustrefertothesameboundarypoints."}); } returncollect_surface_samples<SurfaceLinearization<Formulation>>(*count,[&](std::size_tsample)->std::expected<SurfaceLinearization<Formulation>,SurfaceFailure> { if(!std::isfinite(carrier.values[sample])) { returnstd::unexpected(SurfaceFailure{.reason=SurfaceFailureReason::non_finite_state,.message="Aboundarycarriervalueisnon-finite."}); } returnchecked_linearization<Formulation>(dimensions::PressureValue{0.0},surface_point<Formulation>(sample,carrier),responses[constant_response?0:sample]); }); } template<PressureSurfaceFormulationTypeFormulation> [[nodiscard]]std::expected<std::vector<SurfaceLinearization<Formulation>>,SurfaceFailure>linearize_pressure_samples(constIsobaricSurface&condition,conststd::vector<SurfaceEOSResponse<Formulation>>&responses) { returncollect_surface_samples<SurfaceLinearization<Formulation>>(responses.size(),[&](std::size_tsample) { returnchecked_linearization<Formulation>(condition.target_pressure(),SurfacePoint<Formulation>{},responses[sample]); }); } }//namespaceserif::geometry::surface::detail