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 ac5ff20a46de29579ebc66ad468ed7d090c6d03a
parent 92fb592d0bd18bef9855ce1b5a596107c0fa40bb
Author: Anders Damsgaard <anders@adamsgaard.dk>
Date:   Fri,  3 Jul 2026 11:25:05 +0200

test: add wet equilibrium and in-process error-path checks

- cngf_pf_wet_equilibrium: self-validating invariant asserting the top
  physical node equals p_f_top (no .std baseline to bless a bug).
- test_error_path: in-process check that coupled_shear_solver returns a
  non-zero code instead of terminating the caller.
- Exclude self-validating tests from the regenerable STANDARDS.

Diffstat:
Mtest/Makefile | 28+++++++++++++++++++++++++---
Atest/test_error_path.c | 49+++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 74 insertions(+), 3 deletions(-)

diff --git a/test/Makefile b/test/Makefile @@ -7,6 +7,7 @@ TESTS = cngf_pf_dry \ cngf_pf_dry_cohesive \ cngf_pf_dry_vconst \ cngf_pf_wet \ + cngf_pf_wet_equilibrium \ cngf_pf_wet_norm \ cngf_pf_wet_vari \ cngf_pf_wet_vari_diff \ @@ -14,6 +15,7 @@ TESTS = cngf_pf_dry \ cngf_pf_wet_vari_pulse_vlim \ shear_flux_dry \ shear_flux_wet \ + test_error_path \ #cngf_pf_dry_transient \ # Skipped tests: @@ -23,7 +25,10 @@ TESTS = cngf_pf_dry \ # - max_depth_misc: test config uses removed -O option -STANDARDS := $(TESTS:=.std) +# Self-validating tests carry no .std baseline, so exclude them from the +# regenerable standards. +STANDARDS := $(filter-out cngf_pf_wet_equilibrium.std test_error_path.std,\ + $(TESTS:=.std)) CNGF_PF_DRY_OPTS = -o 0.03 -L 0.64 -n 40e3 CNGF_PF_DRY_NORM_OPTS = -o 0.03 -L 0.64 -n 40e3 -N @@ -81,6 +86,16 @@ cngf_pf_dry_vconst: $(BIN) cngf_pf_wet: $(BIN) ./$(BIN) $(CNGF_PF_WET_OPTS) | diff $@.std - +# Self-validating invariant (no .std baseline): starting from the hydrostatic +# initial state with a constant top pressure and no forcing, the profile must +# stay hydrostatic, so the top physical node must equal p_f_top (0 Pa here). +cngf_pf_wet_equilibrium: $(BIN) + ./$(BIN) $(CNGF_PF_WET_OPTS) | tail -n1 | \ + awk '{ d = $$4; if (d < 0) d = -d; \ + if (d > 1.0) { \ + printf "error: top p_f deviates from p_f_top: %s Pa\n", $$4; \ + exit 1 } }' + cngf_pf_wet_norm: $(BIN) ./$(BIN) $(CNGF_PF_WET_NORM_OPTS) | diff $@.std - @@ -114,6 +129,13 @@ shear_flux_dry: $(BIN) $(BIN3) shear_flux_wet: $(BIN) ./$(BIN) $(CNGF_PF_WET_OPTS) | ./$(BIN3) | diff $@.std - +# In-process check: a non-converging solver must return a non-zero code +# instead of terminating the process. +test_error_path: $(BIN) + $(CC) -I.. -o $@ $@.c ../simulation.o ../arrays.o ../fluid.o -lm + ./$@ + rm -f $@ + cngf_pf_dry.std: $(BIN) ./$(BIN) $(CNGF_PF_DRY_OPTS) > $@ @@ -166,7 +188,7 @@ $(BIN): make -C .. clean: - rm -f *.txt + rm -f *.txt test_error_path # Benchmark configurations for performance/stability testing # These are more intensive than the regression tests @@ -189,4 +211,4 @@ bench_wet_large: bench: bench_dry_small bench_dry_large bench_wet_small bench_wet_large -.PHONY: $(TESTS) test standards clean bench bench_dry_small bench_dry_large bench_wet_small bench_wet_large +.PHONY: $(TESTS) cngf_pf_wet_equilibrium test_error_path test standards clean bench bench_dry_small bench_dry_large bench_wet_small bench_wet_large diff --git a/test/test_error_path.c b/test/test_error_path.c @@ -0,0 +1,49 @@ +/* + * In-process check that a non-converging configuration makes + * coupled_shear_solver() return a non-zero error code instead of terminating + * the calling process. A host embedder (e.g. PISM) relies on this so a single + * failing column cannot kill the MPI process. + */ +#include <math.h> +#include <stdio.h> +#include <stdlib.h> + +#include "../simulation.h" + +int +main(void) +{ + int i, ret; + struct simulation sim; + + init_sim(&sim); + sim.nz = 10; + sim.origo_z = 0.03; + sim.L_z = 0.64; + sim.P_wall = 40e3; + sim.v_x_fix = 1e-3; /* velocity-driven mode */ + + if (prepare_arrays(&sim)) { + fprintf(stderr, "error: prepare_arrays failed\n"); + return 2; + } + for (i = 0; i < sim.nz; ++i) + sim.phi[i] = 0.25; + + lithostatic_pressure_distribution(&sim); + compute_effective_stress(&sim); + + /* max_iter = 0 forces the stress solver to exceed its iteration budget + * and return a non-zero code rather than aborting the process */ + ret = coupled_shear_solver(&sim, 0, 1e-5); + + free_arrays(&sim); + + if (ret == 0) { + fprintf(stderr, "error: solver unexpectedly converged (ret = 0)\n"); + return 1; + } + + printf("ok: coupled_shear_solver returned %d without terminating\n", ret); + return 0; +}