#ifndef SOLVER_H #define SOLVER_H #include #define SOLVER_MAX_POINTS 512 #define SOLVER_MAX_WARNINGS 16 #define SOLVER_WARNING_LEN 160 #define SOLVER_MAX_NODES 65 #define SOLVER_MAX_SURVEY 512 #define SOLVER_MAX_SURFACE 4096 #define SOLVER_MAX_FOURIER_HARMONICS 32 typedef struct { int schema_version; int workflow; /* 0 predictive, 1 diagnostic */ double pumping_speed; double pump_depth; double tubing_anchor_location; double rod_friction_coefficient; double stuffing_box_friction; double pump_friction; double taper_factor; double trajectory_friction_multiplier; double fluid_density_kg_m3; double gravity; double upstroke_damping; double downstroke_damping; double non_dim_damping; double molded_guide_mu_scale; double wheeled_guide_mu_scale; double other_guide_mu_scale; int has_variable_rod; int rod_node_count; double area_m2[SOLVER_MAX_NODES]; double modulus_pa[SOLVER_MAX_NODES]; double density_kg_m3[SOLVER_MAX_NODES]; double weight_n_per_m[SOLVER_MAX_NODES]; double mts_n[SOLVER_MAX_NODES]; double guide_weight_n_per_m[SOLVER_MAX_NODES]; int survey_station_count; double survey_md_m[SOLVER_MAX_SURVEY]; double survey_inc_rad[SOLVER_MAX_SURVEY]; double survey_azi_rad[SOLVER_MAX_SURVEY]; int geometry_valid; double node_curvature[SOLVER_MAX_NODES]; double node_inc_rad[SOLVER_MAX_NODES]; double node_azi_rad[SOLVER_MAX_NODES]; double node_side_load_n[SOLVER_MAX_NODES]; int surface_count; double surface_position_m[SOLVER_MAX_SURFACE]; double surface_load_n[SOLVER_MAX_SURFACE]; int surface_has_time; double surface_time_s[SOLVER_MAX_SURFACE]; double pump_diameter_m; double pump_intake_pressure_pa; double tubing_id_m; double percent_upstroke_time; double percent_downstroke_time; int pump_fillage_option; double percent_pump_fillage; double sinker_bar_diameter_m; double sinker_bar_length_m; int enable_profiles; int enable_diagnostics_detail; int enable_fourier_baseline; int fourier_harmonics; } SolverInputs; typedef struct { int point_count; double position[SOLVER_MAX_POINTS]; double polished_load[SOLVER_MAX_POINTS]; double downhole_load[SOLVER_MAX_POINTS]; double pump_position_m[SOLVER_MAX_POINTS]; double pump_velocity_m_s[SOLVER_MAX_POINTS]; double polished_stress_pa[SOLVER_MAX_POINTS]; double side_load_profile_n[SOLVER_MAX_POINTS]; int profile_node_count; double profile_md_m[SOLVER_MAX_NODES]; double profile_curvature_1pm[SOLVER_MAX_NODES]; double profile_inclination_rad[SOLVER_MAX_NODES]; double profile_azimuth_rad[SOLVER_MAX_NODES]; double profile_side_load_n[SOLVER_MAX_NODES]; double profile_friction_n[SOLVER_MAX_NODES]; int valve_traveling_open[SOLVER_MAX_POINTS]; int valve_standing_open[SOLVER_MAX_POINTS]; double chamber_pressure_pa[SOLVER_MAX_POINTS]; double gas_fraction[SOLVER_MAX_POINTS]; int fourier_harmonics_used; double fourier_polished_load[SOLVER_MAX_POINTS]; double fourier_downhole_load[SOLVER_MAX_POINTS]; double fourier_residual_rms_polished; double fourier_residual_rms_downhole; double max_polished_load; double min_polished_load; double max_downhole_load; double min_downhole_load; int gas_interference; double max_cfl; double wave_speed_ref_m_s; char warnings[SOLVER_MAX_WARNINGS][SOLVER_WARNING_LEN]; int warning_count; } SolverOutputs; /* json_stdin.c */ int solver_read_json_stdin(char **buffer_out, size_t *length_out); int solver_parse_json_inputs(const char *buffer, SolverInputs *inputs); /* trajectory.c */ void solver_trajectory_preprocess(SolverInputs *inputs, int nx, double rod_length_m); /* solver_diagnostic.c */ int solver_run_diagnostic_fdm(const SolverInputs *inputs, SolverOutputs *outputs); int solver_run_fdm(const SolverInputs *inputs, SolverOutputs *outputs); int solver_run_fea(const SolverInputs *inputs, SolverOutputs *outputs); int solver_run(const SolverInputs *inputs, SolverOutputs *outputs); int solver_compute_fourier_baseline(const SolverInputs *inputs, SolverOutputs *outputs); #endif