#ifndef NATIVE_KERNELS_H #define NATIVE_KERNELS_H #include #include typedef struct { double p, T, rho, u, h; } NativeGas; typedef struct { int velocity_index; double lower, upper; double lower_restitution, upper_restitution, lower_threshold, upper_threshold; } NativeStop; /* Discrete slip direction is stored with the sampled state, never in a global * RHS cache. Trial/Jacobian evaluations cannot change sticking/sliding mode. */ typedef struct { int velocity_index, mode_index; double velocity_threshold, breakaway_force; } NativeFriction; double native_dry_friction(double velocity, double static_share, double coulomb, double stiction, double stribeck_velocity, int stribeck, double mode); /* Constants are emitted per medium instance by the model compiler. */ typedef struct { int real_helium; double R, cp, Tref, slope, mu, muT, S; } NativeMedium; /* Caller-owned scratch for ONE model_eval. Keys use exact values and a copy of * every medium constant. No process/thread global cache or approximate reuse. */ enum { NATIVE_PROPERTY_PT=1, NATIVE_PROPERTY_H=2, NATIVE_PROPERTY_RHO=4, NATIVE_PROPERTY_MU=8, NATIVE_PROPERTY_ISENTROPIC=16 }; /* Optional observer for one evaluation, independent of cache capacity. * Slots: EOS, ideal caloric data, dynamic viscosity; each has min/max T. */ #define NATIVE_PROPERTY_DOMAINS 3 typedef struct NativeJacobianScalars NativeJacobianScalars; typedef struct { unsigned seen; double minimum[NATIVE_PROPERTY_DOMAINS], maximum[NATIVE_PROPERTY_DOMAINS]; } NativePropertyTemperatures; typedef struct { NativeMedium medium; double p, T, h, rho, mu, isentropic_factor, isentropic_exponent; unsigned valid; NativePropertyTemperatures *temperatures; NativeJacobianScalars *jacobian; } NativePropertyState; typedef struct { NativePropertyState *states; size_t count, capacity; NativePropertyTemperatures *temperatures; NativeJacobianScalars *jacobian; } NativePropertyCache; void native_properties_init(NativePropertyCache *, NativePropertyState *, size_t capacity); int native_gas_context(NativePropertyCache *, double m, double U, double V, NativeGas *); int native_medium_gas_context(NativePropertyCache *, const NativeMedium *, double m, double U, double V, NativeGas *); int native_polytropic_gas_context(NativePropertyCache *, const NativeMedium *, double mass, double T, double V, NativeGas *); /* Immutable baseline entries owned by ONE Jacobian construction. These * reviewed kernels are deterministic with a NULL property cache: no cache * seeds or temperature observations may be suppressed by a hit. */ typedef int (*NativeCanonicalGas)(NativePropertyCache *,const NativeMedium *,double,double,double,NativeGas *); typedef struct { NativeCanonicalGas kernel; double inputs[10]; /* mass, thermal state, volume, and every medium double */ NativeGas value; int medium_kind, valid; } NativeJacobianGasMemo; typedef struct { unsigned long evaluations, reuses; } NativeJacobianGasStats; int native_jacobian_gas(NativeJacobianGasMemo *,NativeCanonicalGas,const NativeMedium *, double mass,double thermal,double volume,NativeGas *,NativeJacobianGasStats *); enum { NATIVE_JACOBIAN_PH, NATIVE_JACOBIAN_DENSITY, NATIVE_JACOBIAN_PIPE, NATIVE_JACOBIAN_SCALAR_KINDS }; #define NATIVE_JACOBIAN_SCALAR_KEYS 10 typedef struct { uint64_t hash; double inputs[NATIVE_JACOBIAN_SCALAR_KEYS], value; int kind, medium_kind; size_t input_count; } NativeJacobianScalarEntry; struct NativeJacobianScalars { NativeJacobianScalarEntry *entries; size_t capacity; /* power of two; zero disables the optional cache */ int recording; unsigned long evaluations[NATIVE_JACOBIAN_SCALAR_KINDS], reuses[NATIVE_JACOBIAN_SCALAR_KINDS]; }; int native_jacobian_scalar_get(NativeJacobianScalars *,int kind,int medium_kind, const double *inputs,size_t count,double *value); void native_jacobian_scalar_put(NativeJacobianScalars *,int kind,int medium_kind, const double *inputs,size_t count,double value); double native_temperature_ph_context(NativePropertyCache *, const NativeMedium *, double p, double h); double native_density_context(NativePropertyCache *, const NativeMedium *, double p, double T); int native_orifice_context(NativePropertyCache *, double p1, double p2, double h1, double h2, double area, double opening, double *q, double *cm, double *v); int native_medium_orifice_context(NativePropertyCache *, const NativeMedium *, double p1, double p2, double h1, double h2, double area, double opening, double *q, double *cm, double *v); /* One entry per pipe branch, zero-initialized for each model_eval. Never shared * across solver trials. Exact inputs, including medium constants, form the key. */ typedef struct { NativeMedium medium; double p1, p2, T, diameter, length, roughness, flow; int kind, valid; } NativePipeCache; typedef struct { int converged, iterations, bisections; double relative_residual; } NativePipeSolve; /* Solve Re^2*f(Re)=K for the shared pipe resistance law. On failure returns * NAN, with converged=0; flow_per_re converts the local stopping test to kg/s. */ double native_pipe_resistance(double K, double roughness, double flow_per_re, NativePipeSolve *status); double native_pipe_flow_context(NativePropertyCache *, const NativeMedium *, double p1, double p2, double T, double diameter, double length, double roughness, int kind); double native_pipe_flow_cached_context(NativePropertyCache *, NativePipeCache *, const NativeMedium *, double p1, double p2, double T, double diameter, double length, double roughness, int kind); void native_pipe_diagnostics_context(NativePropertyCache *, const NativeMedium *, double q, double p, double T, double diameter, double length, double roughness, int diagnostic, double *result); int native_medium_init(const NativeMedium *, double p, double T, double V, int legacy_ideal_initial, double *mU); double native_density(const NativeMedium *, double p, double T); double native_temperature_ph(const NativeMedium *, double p, double h); double native_viscosity(const NativeMedium *, double T, int diagnostic); int native_medium_gas(const NativeMedium *, double m, double U, double V, NativeGas *); int native_medium_orifice(const NativeMedium *, double p1, double p2, double h1, double h2, double cq_area, double opening, double *q, double *cm, double *v); double native_pipe_flow(const NativeMedium *, double p1, double p2, double T, double diameter, double length, double roughness, int kind); double native_pipe_flow_cached(NativePipeCache *, const NativeMedium *, double p1, double p2, double T, double diameter, double length, double roughness, int kind); void native_pipe_diagnostics(const NativeMedium *, double q, double p, double T, double diameter, double length, double roughness, int diagnostic, double *result); double native_limit_force(double penetration, double velocity, double stiffness, double damping, double depth, int signed_force); int native_gas_init(double p, double T, double volume, double *mU); int native_gas(double m, double U, double volume, NativeGas *gas); int native_orifice(double p1, double p2, double h1, double h2, double cq_area, double opening, double *flow, double *cm, double *velocity); double native_contact(double penetration, double velocity, double stiffness, double damping, double pdis, int signed_force); void native_stop_motion(double x, double v, double lower, double upper, double *acceleration, double *velocity); double native_signal(double t, double start, int stages, int cyclic, const double *data); double native_signal_break(double t, double end, double start, int stages, int cyclic, const double *data); #endif