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

accuracy.sh (3134B)


      1 #!/bin/sh
      2 # accuracy.sh - Compare numerical accuracy between two cngf-pf output files
      3 #
      4 # Usage:
      5 #   ./accuracy.sh reference.txt test.txt
      6 #   ./accuracy.sh -t 1e-6 reference.txt test.txt  # Set tolerance
      7 #
      8 # Computes relative error for each field and reports max/mean errors.
      9 # Fields: z, v_x, sigma_n_eff, p_f, mu, gamma_dot_p, phi, I, tau, d_x
     10 
     11 set -e
     12 
     13 TOLERANCE=1e-10
     14 FIELDS="z v_x sigma_n_eff p_f mu gamma_dot_p phi I tau d_x"
     15 
     16 usage() {
     17     echo "Usage: $0 [-t tolerance] reference.txt test.txt"
     18     echo "  -t tol    Tolerance for pass/fail (default: 1e-10)"
     19     exit 1
     20 }
     21 
     22 # Parse arguments
     23 while [ $# -gt 0 ]; do
     24     case "$1" in
     25         -t) TOLERANCE="$2"; shift 2 ;;
     26         -h|--help) usage ;;
     27         -*) usage ;;
     28         *) break ;;
     29     esac
     30 done
     31 
     32 if [ $# -ne 2 ]; then
     33     usage
     34 fi
     35 
     36 REF="$1"
     37 TEST="$2"
     38 
     39 if [ ! -f "$REF" ]; then
     40     echo "Error: Reference file not found: $REF" >&2
     41     exit 1
     42 fi
     43 
     44 if [ ! -f "$TEST" ]; then
     45     echo "Error: Test file not found: $TEST" >&2
     46     exit 1
     47 fi
     48 
     49 # Check line counts match
     50 ref_lines=$(wc -l < "$REF" | tr -d ' ')
     51 test_lines=$(wc -l < "$TEST" | tr -d ' ')
     52 
     53 if [ "$ref_lines" -ne "$test_lines" ]; then
     54     echo "Error: Line count mismatch: reference=$ref_lines, test=$test_lines" >&2
     55     exit 1
     56 fi
     57 
     58 # Create temporary files for awk processing
     59 tmp_ref=$(mktemp)
     60 tmp_test=$(mktemp)
     61 trap 'rm -f "$tmp_ref" "$tmp_test"' EXIT
     62 
     63 cp "$REF" "$tmp_ref"
     64 cp "$TEST" "$tmp_test"
     65 
     66 # Compute relative errors using awk
     67 awk -v tol="$TOLERANCE" '
     68 BEGIN {
     69     split("z v_x sigma_n_eff p_f mu gamma_dot_p phi I tau d_x", field_names, " ")
     70     for (i = 1; i <= 10; i++) {
     71         max_err[i] = 0
     72         sum_err[i] = 0
     73         count[i] = 0
     74     }
     75 }
     76 
     77 FNR == NR {
     78     for (i = 1; i <= NF; i++) {
     79         ref[FNR, i] = $i
     80     }
     81     nlines = FNR
     82     next
     83 }
     84 
     85 {
     86     for (i = 1; i <= NF; i++) {
     87         test_val = $i
     88         ref_val = ref[FNR, i]
     89 
     90         # Compute relative error
     91         if (ref_val == 0 && test_val == 0) {
     92             rel_err = 0
     93         } else if (ref_val == 0) {
     94             rel_err = (test_val > 0) ? test_val : -test_val
     95         } else {
     96             diff = test_val - ref_val
     97             if (diff < 0) diff = -diff
     98             denom = ref_val
     99             if (denom < 0) denom = -denom
    100             rel_err = diff / denom
    101         }
    102 
    103         if (rel_err > max_err[i]) max_err[i] = rel_err
    104         sum_err[i] += rel_err
    105         count[i]++
    106     }
    107 }
    108 
    109 END {
    110     print "Field            Max RelErr   Mean RelErr  Status"
    111     print "---------------- ------------ ------------ ------"
    112 
    113     all_pass = 1
    114     for (i = 1; i <= 10; i++) {
    115         if (count[i] > 0) {
    116             mean_err = sum_err[i] / count[i]
    117         } else {
    118             mean_err = 0
    119         }
    120 
    121         status = (max_err[i] <= tol) ? "PASS" : "FAIL"
    122         if (status == "FAIL") all_pass = 0
    123 
    124         printf "%-16s %12.4e %12.4e %s\n", field_names[i], max_err[i], mean_err, status
    125     }
    126 
    127     print ""
    128     if (all_pass) {
    129         print "Overall: PASS (all fields within tolerance " tol ")"
    130         exit 0
    131     } else {
    132         print "Overall: FAIL (some fields exceed tolerance " tol ")"
    133         exit 1
    134     }
    135 }
    136 ' "$tmp_ref" "$tmp_test"