test_reset_column.c (3942B)
1 /* 2 * In-process check that reset_column() returns a used simulation struct to a 3 * state equivalent to a freshly prepared one: running the same column setup 4 * after a reset must reproduce a fresh run bit for bit. A host embedder 5 * (e.g. PISM) relies on this to reuse one allocated struct across many 6 * independent till columns. 7 */ 8 #include <math.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 13 #include "../fluid.h" 14 #include "../simulation.h" 15 16 #define NSTEPS 3 17 #define PHI_TEST 0.3 18 #define K_TEST 2e-15 19 20 static int 21 cmp(const char *name, const double *a, const double *b, int n) 22 { 23 if (memcmp(a, b, (size_t)n * sizeof(double)) != 0) { 24 fprintf(stderr, "error: %s differs between fresh and reset run\n", 25 name); 26 return 1; 27 } 28 return 0; 29 } 30 31 static int 32 setup_column(struct simulation *sim) 33 { 34 int i; 35 36 for (i = 0; i < sim->nz; ++i) { 37 sim->phi[i] = PHI_TEST; 38 sim->k[i] = K_TEST; 39 } 40 hydrostatic_fluid_pressure_distribution(sim); 41 lithostatic_pressure_distribution(sim); 42 compute_effective_stress(sim); 43 return set_largest_fluid_timestep(sim, 0.5); 44 } 45 46 static int 47 run_column(struct simulation *sim) 48 { 49 int n, ret; 50 51 for (n = 0; n < NSTEPS; ++n) 52 if ((ret = coupled_shear_solver(sim, 100000, 1e-5))) { 53 fprintf(stderr, "error: solver returned %d at step %d\n", 54 ret, n); 55 return 1; 56 } 57 return 0; 58 } 59 60 static void 61 init_column(struct simulation *sim) 62 { 63 init_sim(sim); 64 sim->nz = 10; 65 sim->origo_z = 0.03; 66 sim->L_z = 0.64; 67 sim->P_wall = 40e3; 68 sim->fluid = 1; 69 } 70 71 int 72 main(void) 73 { 74 int i, status = 0; 75 struct simulation fresh, reused; 76 77 init_column(&fresh); 78 if (prepare_arrays(&fresh)) { 79 fprintf(stderr, "error: prepare_arrays failed\n"); 80 return 2; 81 } 82 if (setup_column(&fresh) || run_column(&fresh)) 83 return 2; 84 85 /* dirty a second struct with a different column, then reset and rerun 86 * the same column as the fresh reference */ 87 init_column(&reused); 88 if (prepare_arrays(&reused)) { 89 fprintf(stderr, "error: prepare_arrays failed\n"); 90 return 2; 91 } 92 for (i = 0; i < reused.nz; ++i) { 93 reused.phi[i] = 0.2; 94 reused.k[i] = 1.9e-15; 95 } 96 hydrostatic_fluid_pressure_distribution(&reused); 97 lithostatic_pressure_distribution(&reused); 98 compute_effective_stress(&reused); 99 if (set_largest_fluid_timestep(&reused, 0.5) || run_column(&reused)) 100 return 2; 101 102 reset_column(&reused); 103 if (setup_column(&reused) || run_column(&reused)) 104 return 2; 105 106 status |= cmp("phi", fresh.phi, reused.phi, fresh.nz); 107 status |= cmp("k", fresh.k, reused.k, fresh.nz); 108 status |= cmp("v_x", fresh.v_x, reused.v_x, fresh.nz); 109 status |= cmp("d_x", fresh.d_x, reused.d_x, fresh.nz); 110 status |= cmp("mu", fresh.mu, reused.mu, fresh.nz); 111 status |= cmp("mu_c", fresh.mu_c, reused.mu_c, fresh.nz); 112 status |= cmp("sigma_n", fresh.sigma_n, reused.sigma_n, fresh.nz); 113 status |= cmp("sigma_n_eff", fresh.sigma_n_eff, reused.sigma_n_eff, 114 fresh.nz); 115 status |= cmp("gamma_dot_p", fresh.gamma_dot_p, reused.gamma_dot_p, 116 fresh.nz); 117 status |= cmp("I", fresh.I, reused.I, fresh.nz); 118 status |= cmp("tan_psi", fresh.tan_psi, reused.tan_psi, fresh.nz); 119 status |= cmp("xi", fresh.xi, reused.xi, fresh.nz); 120 status |= cmp("g_local", fresh.g_local, reused.g_local, fresh.nz); 121 status |= cmp("phi_c", fresh.phi_c, reused.phi_c, fresh.nz); 122 status |= cmp("phi_dot", fresh.phi_dot, reused.phi_dot, fresh.nz); 123 status |= cmp("p_f_dot", fresh.p_f_dot, reused.p_f_dot, fresh.nz); 124 status |= cmp("p_f_ghost", fresh.p_f_ghost, reused.p_f_ghost, 125 fresh.nz + 2); 126 status |= cmp("p_f_next_ghost", fresh.p_f_next_ghost, 127 reused.p_f_next_ghost, fresh.nz + 2); 128 status |= cmp("g_ghost", fresh.g_ghost, reused.g_ghost, fresh.nz + 2); 129 status |= cmp("t", &fresh.t, &reused.t, 1); 130 status |= cmp("mu_wall", &fresh.mu_wall, &reused.mu_wall, 1); 131 132 free_arrays(&fresh); 133 free_arrays(&reused); 134 135 if (status) 136 return 1; 137 138 printf("ok: reset_column reproduces a fresh column run\n"); 139 return 0; 140 }