Initial commit: establish deterministic rod-string solver stack.

Set up the C solver core, Node API orchestration, TS GUI workflow, and engineering documentation with cleaned repo hygiene for private Git hosting.

Made-with: Cursor
This commit is contained in:
2026-04-16 21:59:42 -06:00
commit 725a72a773
83 changed files with 14687 additions and 0 deletions

131
solver-c/include/solver.h Normal file
View File

@@ -0,0 +1,131 @@
#ifndef SOLVER_H
#define SOLVER_H
#include <stddef.h>
#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

View File

@@ -0,0 +1,19 @@
#ifndef SOLVER_INTERNAL_H
#define SOLVER_INTERNAL_H
#include "solver.h"
double solver_clamp(double v, double lo, double hi);
double solver_signum(double v);
void solver_add_warning(SolverOutputs *outputs, const char *msg);
void solver_init_output_ranges(SolverOutputs *outputs);
void solver_update_output_ranges(SolverOutputs *outputs, double polished, double downhole);
double solver_input_or_default(double value, double fallback);
double solver_compute_side_load_node(const SolverInputs *inputs, double tension_n, int node_idx, double ds);
double solver_compute_friction_node(const SolverInputs *inputs, double side_load_n, double velocity_m_s, int node_idx);
void solver_fill_profiles(const SolverInputs *inputs, SolverOutputs *outputs, int node_count, double rod_length_m,
const double *side_load_nodes, const double *friction_nodes);
void solver_valve_state_step(const SolverInputs *inputs, SolverOutputs *outputs, int step_idx, double pump_position_m,
double pump_velocity_m_s, double downhole_load_n);
#endif