cngf-pf

continuum model for granular flows with pore-pressure dynamics (renamed from 1d_fd_simple_shear)
git clone git://src.adamsgaard.dk/cngf-pf # fast
git clone https://src.adamsgaard.dk/cngf-pf.git # slow
Log | Files | Refs | README | LICENSE Back to index

commit d18eb7e0f5a9d7247f3a2641501f4ca795800d70
parent 3b38b840aa892559966075831c33ae15f8d9d74e
Author: Anders Damsgaard <anders@adamsgaard.dk>
Date:   Sat,  7 Feb 2026 09:17:02 +0100

refactor(simulation): reuse persistent solver workspace buffers

Diffstat:
Mfluid.c | 29++++++++++-------------------
Msimulation.c | 44++++++++++++++++++++++++++------------------
Msimulation.h | 15++++++++++++++-
3 files changed, 50 insertions(+), 38 deletions(-)

diff --git a/fluid.c b/fluid.c @@ -93,7 +93,14 @@ static void set_fluid_bcs(double *p_f_ghost, struct simulation *sim, int darcy_solver_1d(struct simulation *sim) { int i, solved = 0; - double p_f_top, *k_n, *phi_n; + double p_f_top; + double *a = sim->tdma_a; + double *b = sim->tdma_b; + double *c = sim->tdma_c; + double *d = sim->tdma_d; + double *x = sim->tdma_x; + double *k_n = sim->darcy_k_n; + double *phi_n = sim->darcy_phi_n; for (i = 0; i < sim->nz; ++i) sim->p_f_dot_impl[i] = sim->p_f_dot_expl[i] = 0.0; @@ -119,15 +126,6 @@ int darcy_solver_1d(struct simulation *sim) { #ifdef DEBUG printf("\nIMPLICIT SOLVER IN %s\n", __func__); #endif - double *a = empty(sim->nz); - double *b = empty(sim->nz); - double *c = empty(sim->nz); - double *d = empty(sim->nz); - double *x = empty(sim->nz); - - k_n = zeros(sim->nz); - phi_n = zeros(sim->nz); - /* Predictor step for nonlinear coefficients */ if (sim->transient) for (i = 0; i < sim->nz; ++i) { @@ -214,7 +212,8 @@ int darcy_solver_1d(struct simulation *sim) { c[sim->nz - 1] = 0.0; /* Solve */ - tridiagonal_solver(x, a, b, c, d, sim->nz); + tridiagonal_solver(x, a, b, c, d, sim->tdma_c_prime, sim->tdma_d_prime, + sim->nz); /* Store result in p_f_dot (rate) */ for (i = 0; i < sim->nz; ++i) { @@ -223,14 +222,6 @@ int darcy_solver_1d(struct simulation *sim) { sim->p_f_dot_impl[i] = sim->p_f_dot[i]; } - free(a); - free(b); - free(c); - free(d); - free(x); - free(k_n); - free(phi_n); - add_darcy_iters(1); solved = 1; } diff --git a/simulation.c b/simulation.c @@ -150,6 +150,15 @@ void prepare_arrays(struct simulation *sim) { sim->I = zeros(sim->nz); sim->tan_psi = zeros(sim->nz); sim->old_val = empty(sim->nz); + sim->tdma_a = empty(sim->nz); + sim->tdma_b = empty(sim->nz); + sim->tdma_c = empty(sim->nz); + sim->tdma_d = empty(sim->nz); + sim->tdma_x = empty(sim->nz); + sim->tdma_c_prime = empty(sim->nz); + sim->tdma_d_prime = empty(sim->nz); + sim->darcy_k_n = empty(sim->nz); + sim->darcy_phi_n = empty(sim->nz); } void free_arrays(struct simulation *sim) { @@ -177,6 +186,15 @@ void free_arrays(struct simulation *sim) { free(sim->I); free(sim->tan_psi); free(sim->old_val); + free(sim->tdma_a); + free(sim->tdma_b); + free(sim->tdma_c); + free(sim->tdma_d); + free(sim->tdma_x); + free(sim->tdma_c_prime); + free(sim->tdma_d_prime); + free(sim->darcy_k_n); + free(sim->darcy_phi_n); } static void warn_parameter_value(const char message[], const double value, @@ -562,7 +580,8 @@ double residual(double new_val, double old_val) { } void tridiagonal_solver(double *x, const double *a, const double *b, - const double *c, double *d, int n) { + const double *c, const double *d, double *c_prime, + double *d_prime, int n) { /* * TDMA (Thomas Algorithm) solver for tridiagonal system * a: sub-diagonal (means a[i] is coeff for x[i-1]) @@ -578,8 +597,6 @@ void tridiagonal_solver(double *x, const double *a, const double *b, * caller or zeroed) */ int i; - double *c_prime = empty(n); - double *d_prime = empty(n); /* Forward sweep */ c_prime[0] = c[0] / b[0]; @@ -596,9 +613,6 @@ void tridiagonal_solver(double *x, const double *a, const double *b, for (i = n - 2; i >= 0; i--) { x[i] = d_prime[i] - c_prime[i] * x[i + 1]; } - - free(c_prime); - free(d_prime); } static int implicit_1d_sor_poisson_solver(struct simulation *sim) { @@ -609,11 +623,11 @@ static int implicit_1d_sor_poisson_solver(struct simulation *sim) { */ int i; int n = sim->nz; - double *a = empty(n); - double *b = empty(n); - double *c = empty(n); - double *d = empty(n); - double *x = empty(n); + double *a = sim->tdma_a; + double *b = sim->tdma_b; + double *c = sim->tdma_c; + double *d = sim->tdma_d; + double *x = sim->tdma_x; /* Set up TDMA arrays */ for (i = 0; i < n; i++) { @@ -637,7 +651,7 @@ static int implicit_1d_sor_poisson_solver(struct simulation *sim) { a[0] = 0.0; c[n - 1] = 0.0; - tridiagonal_solver(x, a, b, c, d, n); + tridiagonal_solver(x, a, b, c, d, sim->tdma_c_prime, sim->tdma_d_prime, n); /* Copy result back to ghost array (indices 1 to n) */ set_bc_dirichlet(sim->g_ghost, sim->nz, -1, 0.0); @@ -646,12 +660,6 @@ static int implicit_1d_sor_poisson_solver(struct simulation *sim) { sim->g_ghost[i + 1] = x[i]; } - free(a); - free(b); - free(c); - free(d); - free(x); - g_stats.poisson_iters += 1; /* Count as 1 iteration for stats */ return 0; } diff --git a/simulation.h b/simulation.h @@ -125,6 +125,18 @@ struct simulation { double *I; /* inertia number [-] */ double *tan_psi; /* tan(dilatancy_angle) [-] */ double *old_val; /* temporary storage for iterative solvers */ + + /* Persistent solver workspace (size nz unless noted otherwise), allocated + * once in prepare_arrays() and reused by Darcy/Poisson TDMA paths. */ + double *tdma_a; /* shared TDMA sub-diagonal coefficients */ + double *tdma_b; /* shared TDMA diagonal coefficients */ + double *tdma_c; /* shared TDMA super-diagonal coefficients */ + double *tdma_d; /* shared TDMA RHS coefficients */ + double *tdma_x; /* shared TDMA solution vector */ + double *tdma_c_prime; /* shared TDMA forward-sweep scratch */ + double *tdma_d_prime; /* shared TDMA forward-sweep scratch */ + double *darcy_k_n; /* Darcy predictor permeability workspace */ + double *darcy_phi_n; /* Darcy predictor porosity workspace */ }; void init_sim(struct simulation *sim); @@ -158,6 +170,7 @@ void print_solver_stats(FILE *fp); void reset_solver_stats(void); void tridiagonal_solver(double *x, const double *a, const double *b, - const double *c, double *d, int n); + const double *c, const double *d, double *c_prime, + double *d_prime, int n); #endif