Files
rods/solver-c/src/solver_fourier.c
Conner Majic 725a72a773 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
2026-04-16 21:59:42 -06:00

58 lines
2.0 KiB
C

#include "solver.h"
#include "solver_internal.h"
#include <math.h>
#include <string.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
static void reconstruct_series(const double *in, int n, int harmonics, double *out) {
if (n <= 0) return;
double a0 = 0.0;
for (int i = 0; i < n; i++) a0 += in[i];
a0 /= (double)n;
for (int i = 0; i < n; i++) out[i] = a0;
const int hmax = (harmonics > n / 2) ? (n / 2) : harmonics;
for (int k = 1; k <= hmax; k++) {
double ak = 0.0;
double bk = 0.0;
for (int i = 0; i < n; i++) {
const double th = 2.0 * M_PI * (double)k * (double)i / (double)n;
ak += in[i] * cos(th);
bk += in[i] * sin(th);
}
ak *= 2.0 / (double)n;
bk *= 2.0 / (double)n;
for (int i = 0; i < n; i++) {
const double th = 2.0 * M_PI * (double)k * (double)i / (double)n;
out[i] += ak * cos(th) + bk * sin(th);
}
}
}
int solver_compute_fourier_baseline(const SolverInputs *inputs, SolverOutputs *outputs) {
(void)inputs;
if (!outputs || outputs->point_count <= 0) return -1;
const int n = outputs->point_count;
const int harmonics = solver_clamp(inputs->fourier_harmonics, 1, SOLVER_MAX_FOURIER_HARMONICS);
reconstruct_series(outputs->polished_load, n, harmonics, outputs->fourier_polished_load);
reconstruct_series(outputs->downhole_load, n, harmonics, outputs->fourier_downhole_load);
double rss_p = 0.0;
double rss_d = 0.0;
for (int i = 0; i < n; i++) {
const double ep = outputs->polished_load[i] - outputs->fourier_polished_load[i];
const double ed = outputs->downhole_load[i] - outputs->fourier_downhole_load[i];
rss_p += ep * ep;
rss_d += ed * ed;
}
outputs->fourier_harmonics_used = harmonics;
outputs->fourier_residual_rms_polished = sqrt(rss_p / (double)n);
outputs->fourier_residual_rms_downhole = sqrt(rss_d / (double)n);
return 0;
}