1d_fd_simple_shear

continuum model for granular flows with pore-pressure dynamics
git clone git://src.adamsgaard.dk/1d_fd_simple_shear
Log | Files | Refs | README | LICENSE Back to index

commit 2ac6bc191520c22444978580b39a69749d6bb804
parent 9bfaf834812f4c720008acdaba8c75db2f254915
Author: Anders Damsgaard <anders@adamsgaard.dk>
Date:   Thu, 16 Apr 2020 12:56:42 +0200

Move simulation struct out of global scope for main program

Diffstat:
M1d_fd_simple_shear.c | 28++++++++++++++--------------
Mfluid.c | 161++++++++++++++++++++++++++++++++++++++++---------------------------------------
Mfluid.h | 10+++++-----
Mparameter_defaults.h | 117++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msimulation.c | 666++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msimulation.h | 43+++++++++++++++++++++++--------------------
6 files changed, 517 insertions(+), 508 deletions(-)

diff --git a/1d_fd_simple_shear.c b/1d_fd_simple_shear.c @@ -2,10 +2,11 @@ #include <math.h> #include <string.h> #include <time.h> +#include <unistd.h> #include "simulation.h" -#include "fluid.h" #include "arg.h" +#include "fluid.h" #include "parameter_defaults.h" @@ -17,7 +18,6 @@ /*#define BENCHMARK_PERFORMANCE*/ char *argv0; -struct simulation sim; static void usage(void) @@ -69,6 +69,7 @@ main(int argc, char* argv[]) int i, normalize; unsigned long iter; double new_phi, new_k, filetimeclock; + struct simulation sim; #ifdef BENCHMARK_PERFORMANCE clock_t t_begin, t_end; double t_elapsed; @@ -81,9 +82,7 @@ main(int argc, char* argv[]) } #endif - atexit(free_arrays); - - init_sim(); + init_sim(&sim); normalize = 0; new_phi = sim.phi[0]; new_k = sim.k[0]; @@ -223,7 +222,7 @@ main(int argc, char* argv[]) if (sim.nz < 1) sim.nz = (int)ceil(sim.L_z/sim.d); - prepare_arrays(); + prepare_arrays(&sim); if (!isnan(new_phi)) for (i=0; i<sim.nz; ++i) @@ -232,15 +231,15 @@ main(int argc, char* argv[]) for (i=0; i<sim.nz; ++i) sim.k[i] = new_k; - lithostatic_pressure_distribution(); + lithostatic_pressure_distribution(&sim); if (sim.fluid) { - hydrostatic_fluid_pressure_distribution(); - set_largest_fluid_timestep(0.5); + hydrostatic_fluid_pressure_distribution(&sim); + set_largest_fluid_timestep(&sim, 0.5); } - compute_effective_stress(); /* Eq. 9 */ + compute_effective_stress(&sim); - check_simulation_parameters(); + check_simulation_parameters(&sim); filetimeclock = 0.0; iter = 0; @@ -250,7 +249,7 @@ main(int argc, char* argv[]) t_begin = clock(); #endif - if (coupled_shear_solver(MAX_ITER_1D_FD_SIMPLE_SHEAR, RTOL)) + if (coupled_shear_solver(&sim, MAX_ITER_1D_FD_SIMPLE_SHEAR, RTOL)) exit(10); #ifdef BENCHMARK_PERFORMANCE @@ -266,14 +265,15 @@ main(int argc, char* argv[]) if ((filetimeclock - sim.dt >= sim.file_dt || iter == 1) && strncmp(sim.name, DEFAULT_SIMULATION_NAME, sizeof(DEFAULT_SIMULATION_NAME)) != 0) { - write_output_file(normalize); + write_output_file(&sim, normalize); filetimeclock = 0.0; if (iter == 1) sim.t = 0.0; } } - print_output(stdout, normalize); + print_output(&sim, stdout, normalize); + free_arrays(&sim); return 0; } diff --git a/fluid.c b/fluid.c @@ -6,12 +6,12 @@ /* #define DEBUG true */ void -hydrostatic_fluid_pressure_distribution() +hydrostatic_fluid_pressure_distribution(struct simulation *sim) { int i; - for (i=0; i<sim.nz; ++i) - sim.p_f_ghost[i+1] = sim.p_f_top - + sim.phi[i]*sim.rho_f*sim.G*(sim.L_z - sim.z[i]); + for (i=0; i<sim->nz; ++i) + sim->p_f_ghost[i+1] = sim->p_f_top + + sim->phi[i]*sim->rho_f*sim->G*(sim->L_z - sim->z[i]); } /* Determines the largest time step for the current simulation state. Note @@ -19,15 +19,15 @@ hydrostatic_fluid_pressure_distribution() * (i.e., permeabilities, porosities, viscosities, or compressibilities) * change. The safety factor should be in ]0;1] */ void -set_largest_fluid_timestep(const double safety) +set_largest_fluid_timestep(struct simulation *sim, const double safety) { int i; double dx_min, diff, diff_max; double *dx; - dx = spacing(sim.z, sim.nz); + dx = spacing(sim->z, sim->nz); dx_min = INFINITY; - for (i=0; i<sim.nz-1; ++i) { + for (i=0; i<sim->nz-1; ++i) { if (dx[i] < 0.0) { fprintf(stderr, "error: cell spacing negative (%g) in cell %d\n", dx[i], i); @@ -39,14 +39,14 @@ set_largest_fluid_timestep(const double safety) free(dx); diff_max = -INFINITY; - for (i=0; i<sim.nz; ++i) { - diff = sim.k[i]/(sim.phi[i]*sim.beta_f*sim.mu_f); + for (i=0; i<sim->nz; ++i) { + diff = sim->k[i]/(sim->phi[i]*sim->beta_f*sim->mu_f); if (diff > diff_max) diff_max = diff; } - sim.dt = safety*0.5*dx_min*dx_min/diff_max; - if (sim.file_dt*0.5 < sim.dt) - sim.dt = sim.file_dt; + sim->dt = safety*0.5*dx_min*dx_min/diff_max; + if (sim->file_dt*0.5 < sim->dt) + sim->dt = sim->file_dt; } static double @@ -86,15 +86,15 @@ square_pulse(const double time, } static void -set_fluid_bcs(const double p_f_top) +set_fluid_bcs(struct simulation *sim, const double p_f_top) { - set_bc_dirichlet(sim.p_f_ghost, sim.nz, +1, p_f_top); - sim.p_f_ghost[sim.nz] = p_f_top; /* Include top node in BC */ - set_bc_neumann(sim.p_f_ghost, - sim.nz, + set_bc_dirichlet(sim->p_f_ghost, sim->nz, +1, p_f_top); + sim->p_f_ghost[sim->nz] = p_f_top; /* Include top node in BC */ + set_bc_neumann(sim->p_f_ghost, + sim->nz, -1, - sim.phi[0]*sim.rho_f*sim.G, - sim.dz); + sim->phi[0]*sim->rho_f*sim->G, + sim->dz); } static double @@ -135,11 +135,12 @@ darcy_pressure_change_1d(const int i, /* TODO: add advective term */ return 1.0/(beta_f*phi[i]*mu_f)*div_k_grad_p - - 1.0/(beta_f*(1.0 - phi[i]))*phi_dot[i]; + - 1.0/(beta_f*(1.0 - phi[i]))*phi_dot[i]; } int -darcy_solver_1d(const int max_iter, +darcy_solver_1d(struct simulation *sim, + const int max_iter, const double rel_tol) { int i, iter, solved; @@ -162,104 +163,104 @@ darcy_solver_1d(const int max_iter, /* TODO: values other than 1.0 do not work! */ theta = 1.0; - if (isnan(sim.p_f_mod_pulse_time)) - p_f_top = sim.p_f_top - + sine_wave(sim.t, - sim.p_f_mod_ampl, - sim.p_f_mod_freq, - sim.p_f_mod_phase); + if (isnan(sim->p_f_mod_pulse_time)) + p_f_top = sim->p_f_top + + sine_wave(sim->t, + sim->p_f_mod_ampl, + sim->p_f_mod_freq, + sim->p_f_mod_phase); else - if (sim.p_f_mod_pulse_shape == 1) - p_f_top = sim.p_f_top - + square_pulse(sim.t, - sim.p_f_mod_ampl, - sim.p_f_mod_freq, - sim.p_f_mod_pulse_time); + if (sim->p_f_mod_pulse_shape == 1) + p_f_top = sim->p_f_top + + square_pulse(sim->t, + sim->p_f_mod_ampl, + sim->p_f_mod_freq, + sim->p_f_mod_pulse_time); else - p_f_top = sim.p_f_top - + triangular_pulse(sim.t, - sim.p_f_mod_ampl, - sim.p_f_mod_freq, - sim.p_f_mod_pulse_time); + p_f_top = sim->p_f_top + + triangular_pulse(sim->t, + sim->p_f_mod_ampl, + sim->p_f_mod_freq, + sim->p_f_mod_pulse_time); /* set fluid BCs (1 of 2) */ - set_fluid_bcs(p_f_top); + set_fluid_bcs(sim, p_f_top); solved = 0; if (epsilon < 1.0) { /* compute explicit solution to pressure change */ - dp_f_dt_expl = zeros(sim.nz); - for (i=0; i<sim.nz; ++i) + dp_f_dt_expl = zeros(sim->nz); + for (i=0; i<sim->nz; ++i) dp_f_dt_expl[i] = darcy_pressure_change_1d(i, - sim.nz, - sim.p_f_ghost, - sim.phi, - sim.phi_dot, - sim.k, - sim.dz, - sim.beta_f, - sim.mu_f); + sim->nz, + sim->p_f_ghost, + sim->phi, + sim->phi_dot, + sim->k, + sim->dz, + sim->beta_f, + sim->mu_f); } if (epsilon > 0.0) { /* compute implicit solution with Jacobian iterations */ - dp_f_dt_impl = zeros(sim.nz); - p_f_ghost_new = zeros(sim.nz+2); - r_norm = zeros(sim.nz); - p_f_ghost_old = empty(sim.nz+2); - copy_values(sim.p_f_ghost, p_f_ghost_old, sim.nz+2); + dp_f_dt_impl = zeros(sim->nz); + p_f_ghost_new = zeros(sim->nz+2); + r_norm = zeros(sim->nz); + p_f_ghost_old = empty(sim->nz+2); + copy_values(sim->p_f_ghost, p_f_ghost_old, sim->nz+2); for (iter=0; iter<max_iter; ++iter) { /* set fluid BCs (2 of 2) */ - set_fluid_bcs( p_f_top); + set_fluid_bcs(sim, p_f_top); #ifdef DEBUG puts(".. p_f_ghost after BC:"); - print_array(sim.p_f_ghost, sim.nz+2); + print_array(sim->p_f_ghost, sim->nz+2); #endif - for (i=0; i<sim.nz-1; ++i) + for (i=0; i<sim->nz-1; ++i) dp_f_dt_impl[i] = darcy_pressure_change_1d(i, - sim.nz, - sim.p_f_ghost, - sim.phi, - sim.phi_dot, - sim.k, - sim.dz, - sim.beta_f, - sim.mu_f); - - for (i=0; i<sim.nz-1; ++i) { + sim->nz, + sim->p_f_ghost, + sim->phi, + sim->phi_dot, + sim->k, + sim->dz, + sim->beta_f, + sim->mu_f); + + for (i=0; i<sim->nz-1; ++i) { #ifdef DEBUG printf("dp_f_expl[%d] = %g\ndp_f_impl[%d] = %g\n", i, dp_f_dt_expl[i], i, dp_f_dt_impl[i]); #endif p_f_ghost_new[i+1] = p_f_ghost_old[i+1] - + epsilon*dp_f_dt_impl[i]*sim.dt; + + epsilon*dp_f_dt_impl[i]*sim->dt; if (epsilon < 1.0) p_f_ghost_new[i+1] += (1.0 - epsilon) - *dp_f_dt_expl[i]*sim.dt; + *dp_f_dt_expl[i]*sim->dt; p_f_ghost_new[i+1] = p_f_ghost_old[i+1]*(1.0 - theta) + p_f_ghost_new[i+1]*theta; - r_norm[i] = fabs((p_f_ghost_new[i+1] - sim.p_f_ghost[i+1]) - /(sim.p_f_ghost[i+1] + 1e-16)); + r_norm[i] = fabs((p_f_ghost_new[i+1] - sim->p_f_ghost[i+1]) + /(sim->p_f_ghost[i+1] + 1e-16)); } - r_norm_max = max(r_norm, sim.nz); + r_norm_max = max(r_norm, sim->nz); #ifdef DEBUG puts(".. p_f_ghost_new:"); - print_array(p_f_ghost_new, sim.nz+2); + print_array(p_f_ghost_new, sim->nz+2); #endif - copy_values(p_f_ghost_new, sim.p_f_ghost, sim.nz+2); + copy_values(p_f_ghost_new, sim->p_f_ghost, sim->nz+2); #ifdef DEBUG puts(".. p_f_ghost after update:"); - print_array(sim.p_f_ghost, sim.nz+2); + print_array(sim->p_f_ghost, sim->nz+2); #endif if (r_norm_max <= rel_tol) { @@ -281,17 +282,17 @@ darcy_solver_1d(const int max_iter, fprintf(stderr, ".. Residual normalized error: %f\n", r_norm_max); } } else { - for (i=0; i<sim.nz; ++i) - sim.p_f_ghost[i+1] += dp_f_dt_expl[i]*sim.dt; + for (i=0; i<sim->nz; ++i) + sim->p_f_ghost[i+1] += dp_f_dt_expl[i]*sim->dt; solved = 1; #ifdef DEBUG puts(".. dp_f_dt_expl:"); - print_array(dp_f_dt_expl, sim.nz); + print_array(dp_f_dt_expl, sim->nz); puts(".. p_f_ghost after explicit solution:"); - print_array(sim.p_f_ghost, sim.nz+2); + print_array(sim->p_f_ghost, sim->nz+2); #endif } - set_fluid_bcs(p_f_top); + set_fluid_bcs(sim, p_f_top); if (epsilon < 1.0) free(dp_f_dt_expl); diff --git a/fluid.h b/fluid.h @@ -5,12 +5,12 @@ extern struct simulation sim; -void hydrostatic_fluid_pressure_distribution(); +void hydrostatic_fluid_pressure_distribution(struct simulation *sim); -void set_largest_fluid_timestep(const double safety); +void set_largest_fluid_timestep(struct simulation *sim, const double safety); -int darcy_solver_1d( - const int max_iter, - const double rel_tol); +int darcy_solver_1d(struct simulation *sim, + const int max_iter, + const double rel_tol); #endif diff --git a/parameter_defaults.h b/parameter_defaults.h @@ -1,5 +1,5 @@ -#ifndef ONED_FD_SIMPLE_SHEAR_ -#define ONED_FD_SIMPLE_SHEAR_ +#ifndef PARAMETER_DEFAULTS_H_ +#define PARAMETER_DEFAULTS_H_ #include <math.h> #include <stdio.h> @@ -10,106 +10,107 @@ /* Simulation settings */ void -init_sim() +init_sim(struct simulation *sim) { - snprintf(sim.name, sizeof(sim.name), DEFAULT_SIMULATION_NAME); + snprintf(sim->name, sizeof(sim->name), DEFAULT_SIMULATION_NAME); - sim.G = 9.81; + sim->G = 9.81; - sim.P_wall = 120e3; - sim.mu_wall = 0.45; - sim.v_x_bot = 0.0; - sim.v_x_fix = NAN; - sim.v_x_limit = NAN; + sim->P_wall = 120e3; + sim->mu_wall = 0.45; + sim->v_x_bot = 0.0; + sim->v_x_fix = NAN; + sim->v_x_limit = NAN; - sim.nz = -1; /* cell size equals grain size if negative */ + sim->nz = -1; /* cell size equals grain size if negative */ /* lower values of A mean that the velocity curve can have sharper curves, * e.g. at the transition from μ ≈ μ_s */ - sim.A = 0.40; /* Loose fit to Damsgaard et al 2013 */ + sim->A = 0.40; /* Loose fit to Damsgaard et al 2013 */ /* lower values of b mean larger shear velocity for a given stress ratio * above yield */ - sim.b = 0.9377; /* Henann and Kamrin 2016 */ + sim->b = 0.9377; /* Henann and Kamrin 2016 */ /* Henann and Kamrin 2016 */ - /* sim.mu_s = 0.3819; */ - /* sim.C = 0.0; */ + /* sim->mu_s = 0.3819; */ + /* sim->C = 0.0; */ /* Damsgaard et al 2013 */ - sim.mu_s = tan(DEG2RAD(22.0)); - sim.C = 0.0; - sim.phi = initval(0.25, 1); - sim.d = 0.04; /* Damsgaard et al 2013 */ + sim->mu_s = tan(DEG2RAD(22.0)); + sim->C = 0.0; + sim->phi = initval(0.25, 1); + sim->d = 0.04; /* Damsgaard et al 2013 */ - sim.phi_min = 0.25; - sim.phi_max = 0.55; - sim.dilatancy_angle = 1.0; + sim->transient = 0; + sim->phi_min = 0.25; + sim->phi_max = 0.55; + sim->dilatancy_angle = 1.0; /* Iverson et al 1997, 1998: Storglaciaren till */ - /* sim.mu_s = tan(DEG2RAD(26.3)); */ - /* sim.C = 5.0e3; */ - /* sim.phi = initval(0.22, 1); */ - /* sim.d = ??; */ + /* sim->mu_s = tan(DEG2RAD(26.3)); */ + /* sim->C = 5.0e3; */ + /* sim->phi = initval(0.22, 1); */ + /* sim->d = ??; */ /* Iverson et al 1997, 1998: Two Rivers till */ - /* sim.mu_s = tan(DEG2RAD(17.8)); */ - /* sim.C = 14.0e3; */ - /* sim.phi = initval(0.37, 1); */ - /* sim.d = ??; */ + /* sim->mu_s = tan(DEG2RAD(17.8)); */ + /* sim->C = 14.0e3; */ + /* sim->phi = initval(0.37, 1); */ + /* sim->d = ??; */ /* Tulaczyk et al 2000a: Upstream B till */ - /* sim.mu_s = tan(DEG2RAD(23.9)); */ - /* sim.C = 3.0e3; */ - /* sim.phi = initval(0.35, 1); */ - /* sim.d = ??; */ + /* sim->mu_s = tan(DEG2RAD(23.9)); */ + /* sim->C = 3.0e3; */ + /* sim->phi = initval(0.35, 1); */ + /* sim->d = ??; */ /* grain material density [kg/m^3] */ - sim.rho_s = 2.6e3; /* Damsgaard et al 2013 */ + sim->rho_s = 2.6e3; /* Damsgaard et al 2013 */ /* spatial settings */ - sim.origo_z = 0.0; - sim.L_z = 1.0; + sim->origo_z = 0.0; + sim->L_z = 1.0; /* temporal settings */ - sim.t = 0.0; - sim.dt = 2.0; - sim.t_end = 1.0; - sim.file_dt = 0.1; - sim.n_file = 0; + sim->t = 0.0; + sim->dt = 2.0; + sim->t_end = 1.0; + sim->file_dt = 0.1; + sim->n_file = 0; /* fluid settings */ - sim.fluid = 0; + sim->fluid = 0; - sim.rho_f = 1e3; + sim->rho_f = 1e3; /* Water at 20 deg C, Goren et al 2011 */ - /* sim.beta_f = 4.5e-10; */ - /* sim.mu_f = 1.0-3; */ + /* sim->beta_f = 4.5e-10; */ + /* sim->mu_f = 1.0-3; */ /* Water at 0 deg C */ - sim.beta_f = 3.9e-10; /* doi:10.1063/1.1679903 */ - sim.mu_f = 1.787e-3; /* Cuffey and Paterson 2010 */ + sim->beta_f = 3.9e-10; /* doi:10.1063/1.1679903 */ + sim->mu_f = 1.787e-3; /* Cuffey and Paterson 2010 */ /* Damsgaard et al 2015 */ - sim.k = initval(1.9e-15, 1); + sim->k = initval(1.9e-15, 1); /* Iverson et al 1994: Storglaciaren */ - /* sim.k = initval(1.3e-14, 1); */ + /* sim->k = initval(1.3e-14, 1); */ /* Engelhardt et al 1990: Upstream B */ - /* sim.k = initval(2.0e-16, 1); */ + /* sim->k = initval(2.0e-16, 1); */ /* Leeman et al 2016: Upstream B till */ - /* sim.k = initval(4.9e-17, 1); */ + /* sim->k = initval(4.9e-17, 1); */ /* no fluid-pressure variations */ - sim.p_f_top = 0.0; - sim.p_f_mod_ampl = 0.0; - sim.p_f_mod_freq = 1.0; - sim.p_f_mod_phase = 0.0; - sim.p_f_mod_pulse_time = NAN; - sim.p_f_mod_pulse_shape = 0; + sim->p_f_top = 0.0; + sim->p_f_mod_ampl = 0.0; + sim->p_f_mod_freq = 1.0; + sim->p_f_mod_phase = 0.0; + sim->p_f_mod_pulse_time = NAN; + sim->p_f_mod_pulse_shape = 0; } #endif diff --git a/simulation.c b/simulation.c @@ -20,62 +20,59 @@ #define MAX_ITER_STRESS 20000 void -prepare_arrays() +prepare_arrays(struct simulation *sim) { - if (sim.nz < 2) { + if (sim->nz < 2) { fprintf(stderr, "error: grid size (nz) must be at least 2 but is %d\n", - sim.nz); + sim->nz); exit(1); } - free(sim.phi); - free(sim.phi_c); - free(sim.phi_dot); - free(sim.k); - free(sim.g_local); - - sim.z = linspace(sim.origo_z, /* spatial coordinates */ - sim.origo_z + sim.L_z, - sim.nz); - sim.dz = sim.z[1] - sim.z[0]; /* cell spacing */ - sim.mu = zeros(sim.nz); /* stress ratio */ - sim.mu_c = zeros(sim.nz); /* critical-state stress ratio */ - sim.sigma_n_eff = zeros(sim.nz); /* effective normal stress */ - sim.sigma_n = zeros(sim.nz); /* normal stess */ - sim.p_f_ghost = zeros(sim.nz+2); /* fluid pressure with ghost nodes */ - sim.phi = zeros(sim.nz); /* porosity */ - sim.phi_c = zeros(sim.nz); /* critical-state porosity */ - sim.phi_dot = zeros(sim.nz); /* rate of porosity change */ - sim.k = zeros(sim.nz); /* permeability */ - sim.xi = zeros(sim.nz); /* cooperativity length */ - sim.gamma_dot_p = zeros(sim.nz); /* shear velocity */ - sim.v_x = zeros(sim.nz); /* shear velocity */ - sim.g_local = zeros(sim.nz); /* local fluidity */ - sim.g_ghost = zeros(sim.nz+2); /* fluidity with ghost nodes */ - sim.I = zeros(sim.nz); /* inertia number */ - sim.tan_psi = zeros(sim.nz); /* tan(dilatancy_angle) */ + free(sim->phi); + free(sim->k); + + sim->z = linspace(sim->origo_z, /* spatial coordinates */ + sim->origo_z + sim->L_z, + sim->nz); + sim->dz = sim->z[1] - sim->z[0]; /* cell spacing */ + sim->mu = zeros(sim->nz); /* stress ratio */ + sim->mu_c = zeros(sim->nz); /* critical-state stress ratio */ + sim->sigma_n_eff = zeros(sim->nz); /* effective normal stress */ + sim->sigma_n = zeros(sim->nz); /* normal stess */ + sim->p_f_ghost = zeros(sim->nz+2); /* fluid pressure with ghost nodes */ + sim->phi = zeros(sim->nz); /* porosity */ + sim->phi_c = zeros(sim->nz); /* critical-state porosity */ + sim->phi_dot = zeros(sim->nz); /* rate of porosity change */ + sim->k = zeros(sim->nz); /* permeability */ + sim->xi = zeros(sim->nz); /* cooperativity length */ + sim->gamma_dot_p = zeros(sim->nz); /* shear velocity */ + sim->v_x = zeros(sim->nz); /* shear velocity */ + sim->g_local = zeros(sim->nz); /* local fluidity */ + sim->g_ghost = zeros(sim->nz+2); /* fluidity with ghost nodes */ + sim->I = zeros(sim->nz); /* inertia number */ + sim->tan_psi = zeros(sim->nz); /* tan(dilatancy_angle) */ } void -free_arrays() +free_arrays(struct simulation *sim) { - free(sim.z); - free(sim.mu); - free(sim.mu_c); - free(sim.sigma_n_eff); - free(sim.sigma_n); - free(sim.p_f_ghost); - free(sim.k); - free(sim.phi); - free(sim.phi_c); - free(sim.phi_dot); - free(sim.xi); - free(sim.gamma_dot_p); - free(sim.v_x); - free(sim.g_local); - free(sim.g_ghost); - free(sim.I); - free(sim.tan_psi); + free(sim->z); + free(sim->mu); + free(sim->mu_c); + free(sim->sigma_n_eff); + free(sim->sigma_n); + free(sim->p_f_ghost); + free(sim->k); + free(sim->phi); + free(sim->phi_c); + free(sim->phi_dot); + free(sim->xi); + free(sim->gamma_dot_p); + free(sim->v_x); + free(sim->g_local); + free(sim->g_ghost); + free(sim->I); + free(sim->tan_psi); } static void @@ -110,156 +107,156 @@ check_float(const char name[], const double value, int* return_status) } void -check_simulation_parameters() +check_simulation_parameters(struct simulation *sim) { int return_status; return_status = 0; - check_float("sim.G", sim.G, &return_status); - if (sim.G < 0.0) - warn_parameter_value("sim.G is negative", sim.G, &return_status); + check_float("sim->G", sim->G, &return_status); + if (sim->G < 0.0) + warn_parameter_value("sim->G is negative", sim->G, &return_status); - check_float("sim.P_wall", sim.P_wall, &return_status); - if (sim.P_wall < 0.0) - warn_parameter_value("sim.P_wall is negative", sim.P_wall, + check_float("sim->P_wall", sim->P_wall, &return_status); + if (sim->P_wall < 0.0) + warn_parameter_value("sim->P_wall is negative", sim->P_wall, &return_status); - check_float("sim.v_x_bot", sim.v_x_bot, &return_status); + check_float("sim->v_x_bot", sim->v_x_bot, &return_status); - check_float("sim.mu_wall", sim.mu_wall, &return_status); - if (sim.mu_wall < 0.0) - warn_parameter_value("sim.mu_wall is negative", sim.mu_wall, + check_float("sim->mu_wall", sim->mu_wall, &return_status); + if (sim->mu_wall < 0.0) + warn_parameter_value("sim->mu_wall is negative", sim->mu_wall, &return_status); - check_float("sim.A", sim.A, &return_status); - if (sim.A < 0.0) - warn_parameter_value("sim.A is negative", sim.A, &return_status); + check_float("sim->A", sim->A, &return_status); + if (sim->A < 0.0) + warn_parameter_value("sim->A is negative", sim->A, &return_status); - check_float("sim.b", sim.b, &return_status); - if (sim.b < 0.0) - warn_parameter_value("sim.b is negative", sim.b, &return_status); + check_float("sim->b", sim->b, &return_status); + if (sim->b < 0.0) + warn_parameter_value("sim->b is negative", sim->b, &return_status); - check_float("sim.mu_s", sim.mu_s, &return_status); - if (sim.mu_s < 0.0) - warn_parameter_value("sim.mu_s is negative", sim.mu_s, + check_float("sim->mu_s", sim->mu_s, &return_status); + if (sim->mu_s < 0.0) + warn_parameter_value("sim->mu_s is negative", sim->mu_s, &return_status); - check_float("sim.C", sim.C, &return_status); + check_float("sim->C", sim->C, &return_status); - check_float("sim.d", sim.d, &return_status); - if (sim.d <= 0.0) - warn_parameter_value("sim.d is not a positive number", sim.d, + check_float("sim->d", sim->d, &return_status); + if (sim->d <= 0.0) + warn_parameter_value("sim->d is not a positive number", sim->d, &return_status); - check_float("sim.rho_s", sim.rho_s, &return_status); - if (sim.rho_s <= 0.0) - warn_parameter_value("sim.rho_s is not a positive number", sim.rho_s, + check_float("sim->rho_s", sim->rho_s, &return_status); + if (sim->rho_s <= 0.0) + warn_parameter_value("sim->rho_s is not a positive number", sim->rho_s, &return_status); - if (sim.nz <= 0) - warn_parameter_value("sim.nz is not a positive number", sim.nz, + if (sim->nz <= 0) + warn_parameter_value("sim->nz is not a positive number", sim->nz, &return_status); - check_float("sim.origo_z", sim.origo_z, &return_status); - check_float("sim.L_z", sim.L_z, &return_status); - if (sim.L_z <= sim.origo_z) - warn_parameter_value("sim.L_z is smaller or equal to sim.origo_z", - sim.L_z, &return_status); + check_float("sim->origo_z", sim->origo_z, &return_status); + check_float("sim->L_z", sim->L_z, &return_status); + if (sim->L_z <= sim->origo_z) + warn_parameter_value("sim->L_z is smaller or equal to sim->origo_z", + sim->L_z, &return_status); - if (sim.nz <= 0) - warn_parameter_value("sim.nz is not a positive number", sim.nz, + if (sim->nz <= 0) + warn_parameter_value("sim->nz is not a positive number", sim->nz, &return_status); - check_float("sim.dz", sim.dz, &return_status); - if (sim.dz <= 0.0) - warn_parameter_value("sim.dz is not a positive number", sim.dz, + check_float("sim->dz", sim->dz, &return_status); + if (sim->dz <= 0.0) + warn_parameter_value("sim->dz is not a positive number", sim->dz, &return_status); - check_float("sim.t", sim.t, &return_status); - if (sim.t < 0.0) - warn_parameter_value("sim.t is a negative number", - sim.t, &return_status); - - check_float("sim.t_end", sim.t_end, &return_status); - if (sim.t > sim.t_end) - warn_parameter_value("sim.t_end is smaller than sim.t", - sim.t, &return_status); - - check_float("sim.dt", sim.dt, &return_status); - if (sim.dt <= 0.0) - warn_parameter_value("sim.dt is not a positive number", - sim.dt, &return_status); - - check_float("sim.file_dt", sim.file_dt, &return_status); - if (sim.file_dt < 0.0) - warn_parameter_value("sim.file_dt is a negative number", - sim.file_dt, &return_status); - - check_float("sim.phi[0]", sim.phi[0], &return_status); - if (sim.phi[0] < 0.0 || sim.phi[0] > 1.0) - warn_parameter_value("sim.phi[0] is not within [0;1]", - sim.phi[0], &return_status); - - check_float("sim.phi_min", sim.phi_min, &return_status); - if (sim.phi_min < 0.0 || sim.phi_min > 1.0) - warn_parameter_value("sim.phi_min is not within [0;1]", - sim.phi_min, &return_status); - - check_float("sim.phi_max", sim.phi_max, &return_status); - if (sim.phi_max < 0.0 || sim.phi_max > 1.0) - warn_parameter_value("sim.phi_max is not within [0;1]", - sim.phi_max, &return_status); - - check_float("sim.dilatancy_angle", sim.dilatancy_angle, &return_status); - if (sim.dilatancy_angle < 0.0 || sim.dilatancy_angle > 100.0) - warn_parameter_value("sim.dilatancy_angle is not within [0;100]", - sim.dilatancy_angle, &return_status); - - if (sim.fluid != 0 && sim.fluid != 1) - warn_parameter_value("sim.fluid has an invalid value", - (double)sim.fluid, &return_status); - - if (sim.transient != 0 && sim.transient != 1) - warn_parameter_value("sim.fluid has an invalid value", - (double)sim.fluid, &return_status); - - if (sim.fluid) { - - check_float("sim.p_f_mod_ampl", sim.p_f_mod_ampl, &return_status); - if (sim.p_f_mod_ampl < 0.0) - warn_parameter_value("sim.p_f_mod_ampl is not a zero or positive", - sim.p_f_mod_ampl, &return_status); - - if (sim.P_wall - sim.p_f_mod_ampl < 0.0) - warn_parameter_value("sim.P_wall - sim.p_f_mod_ampl is negative", - sim.P_wall - sim.p_f_mod_ampl, + check_float("sim->t", sim->t, &return_status); + if (sim->t < 0.0) + warn_parameter_value("sim->t is a negative number", + sim->t, &return_status); + + check_float("sim->t_end", sim->t_end, &return_status); + if (sim->t > sim->t_end) + warn_parameter_value("sim->t_end is smaller than sim->t", + sim->t, &return_status); + + check_float("sim->dt", sim->dt, &return_status); + if (sim->dt <= 0.0) + warn_parameter_value("sim->dt is not a positive number", + sim->dt, &return_status); + + check_float("sim->file_dt", sim->file_dt, &return_status); + if (sim->file_dt < 0.0) + warn_parameter_value("sim->file_dt is a negative number", + sim->file_dt, &return_status); + + check_float("sim->phi[0]", sim->phi[0], &return_status); + if (sim->phi[0] < 0.0 || sim->phi[0] > 1.0) + warn_parameter_value("sim->phi[0] is not within [0;1]", + sim->phi[0], &return_status); + + check_float("sim->phi_min", sim->phi_min, &return_status); + if (sim->phi_min < 0.0 || sim->phi_min > 1.0) + warn_parameter_value("sim->phi_min is not within [0;1]", + sim->phi_min, &return_status); + + check_float("sim->phi_max", sim->phi_max, &return_status); + if (sim->phi_max < 0.0 || sim->phi_max > 1.0) + warn_parameter_value("sim->phi_max is not within [0;1]", + sim->phi_max, &return_status); + + check_float("sim->dilatancy_angle", sim->dilatancy_angle, &return_status); + if (sim->dilatancy_angle < 0.0 || sim->dilatancy_angle > 100.0) + warn_parameter_value("sim->dilatancy_angle is not within [0;100]", + sim->dilatancy_angle, &return_status); + + if (sim->fluid != 0 && sim->fluid != 1) + warn_parameter_value("sim->fluid has an invalid value", + (double)sim->fluid, &return_status); + + if (sim->transient != 0 && sim->transient != 1) + warn_parameter_value("sim->transient has an invalid value", + (double)sim->transient, &return_status); + + if (sim->fluid) { + + check_float("sim->p_f_mod_ampl", sim->p_f_mod_ampl, &return_status); + if (sim->p_f_mod_ampl < 0.0) + warn_parameter_value("sim->p_f_mod_ampl is not a zero or positive", + sim->p_f_mod_ampl, &return_status); + + if (sim->P_wall - sim->p_f_mod_ampl < 0.0) + warn_parameter_value("sim->P_wall - sim->p_f_mod_ampl is negative", + sim->P_wall - sim->p_f_mod_ampl, &return_status); - check_float("sim.p_f_mod_freq", sim.p_f_mod_freq, &return_status); - if (sim.p_f_mod_freq < 0.0) - warn_parameter_value("sim.p_f_mod_freq is not a zero or positive", - sim.p_f_mod_freq, &return_status); - - check_float("sim.beta_f", sim.beta_f, &return_status); - if (sim.beta_f <= 0.0) - warn_parameter_value("sim.beta_f is not positive", - sim.beta_f, &return_status); - - check_float("sim.mu_f", sim.mu_f, &return_status); - if (sim.mu_f <= 0.0) - warn_parameter_value("sim.mu_f is not positive", - sim.mu_f, &return_status); - - check_float("sim.rho_f", sim.rho_f, &return_status); - if (sim.rho_f <= 0.0) - warn_parameter_value("sim.rho_f is not positive", - sim.rho_f, &return_status); - - check_float("sim.k[0]", sim.k[0], &return_status); - if (sim.k[0] <= 0.0) - warn_parameter_value("sim.k[0] is not positive", - sim.k[0], &return_status); + check_float("sim->p_f_mod_freq", sim->p_f_mod_freq, &return_status); + if (sim->p_f_mod_freq < 0.0) + warn_parameter_value("sim->p_f_mod_freq is not a zero or positive", + sim->p_f_mod_freq, &return_status); + + check_float("sim->beta_f", sim->beta_f, &return_status); + if (sim->beta_f <= 0.0) + warn_parameter_value("sim->beta_f is not positive", + sim->beta_f, &return_status); + + check_float("sim->mu_f", sim->mu_f, &return_status); + if (sim->mu_f <= 0.0) + warn_parameter_value("sim->mu_f is not positive", + sim->mu_f, &return_status); + + check_float("sim->rho_f", sim->rho_f, &return_status); + if (sim->rho_f <= 0.0) + warn_parameter_value("sim->rho_f is not positive", + sim->rho_f, &return_status); + + check_float("sim->k[0]", sim->k[0], &return_status); + if (sim->k[0] <= 0.0) + warn_parameter_value("sim->k[0] is not positive", + sim->k[0], &return_status); } if (return_status != 0) { @@ -269,102 +266,102 @@ check_simulation_parameters() } void -lithostatic_pressure_distribution() +lithostatic_pressure_distribution(struct simulation *sim) { int i; - for (i=0; i<sim.nz; ++i) - sim.sigma_n[i] = sim.P_wall + - (1.0 - sim.phi[i])*sim.rho_s*sim.G* - (sim.L_z - sim.z[i]); + for (i=0; i<sim->nz; ++i) + sim->sigma_n[i] = sim->P_wall + + (1.0 - sim->phi[i])*sim->rho_s*sim->G* + (sim->L_z - sim->z[i]); } /* NEW FUNCTIONS START */ void -compute_inertia_number() +compute_inertia_number(struct simulation *sim) { int i; - for (i=0; i<sim.nz; ++i) - sim.I[i] = sim.gamma_dot_p[i]*sim.d - /sqrt(sim.sigma_n_eff[i]/sim.rho_s); + for (i=0; i<sim->nz; ++i) + sim->I[i] = sim->gamma_dot_p[i]*sim->d + /sqrt(sim->sigma_n_eff[i]/sim->rho_s); } void -compute_critical_state_porosity() +compute_critical_state_porosity(struct simulation *sim) { int i; - for (i=0; i<sim.nz; ++i) - sim.phi_c[i] = sim.phi_min + (sim.phi_max - sim.phi_min)*sim.I[i]; + for (i=0; i<sim->nz; ++i) + sim->phi_c[i] = sim->phi_min + (sim->phi_max - sim->phi_min)*sim->I[i]; } void -compute_critical_state_friction() +compute_critical_state_friction(struct simulation *sim) { int i; - if (sim.fluid) - for (i=0; i<sim.nz; ++i) - sim.mu_c[i] = sim.mu_wall/ - (sim.sigma_n_eff[i]/(sim.P_wall - sim.p_f_top)); + if (sim->fluid) + for (i=0; i<sim->nz; ++i) + sim->mu_c[i] = sim->mu_wall/ + (sim->sigma_n_eff[i]/(sim->P_wall - sim->p_f_top)); else - for (i=0; i<sim.nz; ++i) - sim.mu_c[i] = sim.mu_wall/ - (1.0 + (1.0 - sim.phi[i])*sim.rho_s*sim.G* - (sim.L_z - sim.z[i])/sim.P_wall); + for (i=0; i<sim->nz; ++i) + sim->mu_c[i] = sim->mu_wall/ + (1.0 + (1.0 - sim->phi[i])*sim->rho_s*sim->G* + (sim->L_z - sim->z[i])/sim->P_wall); } void -compute_friction() +compute_friction(struct simulation *sim) { int i; - if (sim.transient) - for (i=0; i<sim.nz; ++i) - sim.mu[i] = sim.tan_psi[i] + sim.mu_c[i]; + if (sim->transient) + for (i=0; i<sim->nz; ++i) + sim->mu[i] = sim->tan_psi[i] + sim->mu_c[i]; else - for (i=0; i<sim.nz; ++i) - sim.mu[i] = sim.mu_c[i]; + for (i=0; i<sim->nz; ++i) + sim->mu[i] = sim->mu_c[i]; } void -compute_tan_dilatancy_angle() +compute_tan_dilatancy_angle(struct simulation *sim) { int i; - for (i=0; i<sim.nz; ++i) - sim.tan_psi[i] = sim.dilatancy_angle*(sim.phi_c[i] - sim.phi[i]); + for (i=0; i<sim->nz; ++i) + sim->tan_psi[i] = sim->dilatancy_angle*(sim->phi_c[i] - sim->phi[i]); } void -compute_porosity_change() +compute_porosity_change(struct simulation *sim) { int i; - for (i=0; i<sim.nz; ++i) { - sim.phi_dot[i] = sim.tan_psi[i]*sim.gamma_dot_p[i]*sim.phi[i]; - sim.phi[i] += sim.phi_dot[i]*sim.dt; + for (i=0; i<sim->nz; ++i) { + sim->phi_dot[i] = sim->tan_psi[i]*sim->gamma_dot_p[i]*sim->phi[i]; + sim->phi[i] += sim->phi_dot[i]*sim->dt; } } void -compute_permeability() +compute_permeability(struct simulation *sim) { int i; - for (i=0; i<sim.nz; ++i) - sim.k[i] = pow(sim.d, 2.0)/180.0 - *pow(sim.phi[i], 3.0)/pow(1.0 - sim.phi[i], 2.0); + for (i=0; i<sim->nz; ++i) + sim->k[i] = pow(sim->d, 2.0)/180.0 + *pow(sim->phi[i], 3.0)/pow(1.0 - sim->phi[i], 2.0); } /* NEW FUNCTIONS END */ /*void -compute_friction() +compute_friction(struct simulation *sim) { int i; - if (sim.fluid) - for (i=0; i<sim.nz; ++i) - sim.mu[i] = sim.mu_wall/ - (sim.sigma_n_eff[i]/(sim.P_wall - sim.p_f_top)); + if (sim->fluid) + for (i=0; i<sim->nz; ++i) + sim->mu[i] = sim->mu_wall/ + (sim->sigma_n_eff[i]/(sim->P_wall - sim->p_f_top)); else - for (i=0; i<sim.nz; ++i) - sim.mu[i] = sim.mu_wall/ - (1.0 + (1.0 - sim.phi[i])*sim.rho_s*sim.G* - (sim.L_z - sim.z[i])/sim.P_wall); + for (i=0; i<sim->nz; ++i) + sim->mu[i] = sim->mu_wall/ + (1.0 + (1.0 - sim->phi[i])*sim->rho_s*sim->G* + (sim->L_z - sim->z[i])/sim->P_wall); }*/ double @@ -374,37 +371,37 @@ shear_strain_rate_plastic(const double fluidity, const double friction) } void -compute_shear_strain_rate_plastic() +compute_shear_strain_rate_plastic(struct simulation *sim) { int i; - for (i=0; i<sim.nz; ++i) - sim.gamma_dot_p[i] = shear_strain_rate_plastic(sim.g_ghost[i+1], - sim.mu[i]); + for (i=0; i<sim->nz; ++i) + sim->gamma_dot_p[i] = shear_strain_rate_plastic(sim->g_ghost[i+1], + sim->mu[i]); } void -compute_shear_velocity() +compute_shear_velocity(struct simulation *sim) { int i; /* TODO: implement iterative solver for v_x from gamma_dot_p field */ /* Dirichlet BC at bottom */ - sim.v_x[0] = sim.v_x_bot; + sim->v_x[0] = sim->v_x_bot; - for (i=1; i<sim.nz; ++i) - sim.v_x[i] = sim.v_x[i-1] + sim.gamma_dot_p[i]*sim.dz; + for (i=1; i<sim->nz; ++i) + sim->v_x[i] = sim->v_x[i-1] + sim->gamma_dot_p[i]*sim->dz; } void -compute_effective_stress() +compute_effective_stress(struct simulation *sim) { int i; - if (sim.fluid) - for (i=0; i<sim.nz; ++i) - sim.sigma_n_eff[i] = sim.sigma_n[i] - sim.p_f_ghost[i+1]; + if (sim->fluid) + for (i=0; i<sim->nz; ++i) + sim->sigma_n_eff[i] = sim->sigma_n[i] - sim->p_f_ghost[i+1]; else - for (i=0; i<sim.nz; ++i) - sim.sigma_n_eff[i] = sim.sigma_n[i]; + for (i=0; i<sim->nz; ++i) + sim->sigma_n_eff[i] = sim->sigma_n[i]; } static double @@ -419,16 +416,16 @@ cooperativity_length(const double A, } void -compute_cooperativity_length() +compute_cooperativity_length(struct simulation *sim) { int i; - for (i=0; i<sim.nz; ++i) - sim.xi[i] = cooperativity_length(sim.A, - sim.d, - sim.mu[i], - sim.sigma_n_eff[i], - sim.mu_s, - sim.C); + for (i=0; i<sim->nz; ++i) + sim->xi[i] = cooperativity_length(sim->A, + sim->d, + sim->mu[i], + sim->sigma_n_eff[i], + sim->mu_s, + sim->C); } static double @@ -447,17 +444,17 @@ local_fluidity(const double p, } void -compute_local_fluidity() +compute_local_fluidity(struct simulation *sim) { int i; - for (i=0; i<sim.nz; ++i) - sim.g_local[i] = local_fluidity(sim.sigma_n_eff[i], - sim.mu[i], - sim.mu_s, - sim.C, - sim.b, - sim.rho_s, - sim.d); + for (i=0; i<sim->nz; ++i) + sim->g_local[i] = local_fluidity(sim->sigma_n_eff[i], + sim->mu[i], + sim->mu_s, + sim->C, + sim->b, + sim->rho_s, + sim->d); } void @@ -529,7 +526,8 @@ poisson_solver_1d_cell_update(int i, } int -implicit_1d_jacobian_poisson_solver(const int max_iter, +implicit_1d_jacobian_poisson_solver(struct simulation *sim, + const int max_iter, const double rel_tol) { double r_norm_max; @@ -537,42 +535,42 @@ implicit_1d_jacobian_poisson_solver(const int max_iter, int iter, i; r_norm_max = NAN; - g_ghost_out = empty(sim.nz+2); - r_norm = empty(sim.nz); + g_ghost_out = empty(sim->nz+2); + r_norm = empty(sim->nz); for (iter=0; iter<max_iter; ++iter) { #ifdef DEBUG printf("\n@@@ ITERATION %d @@@\n", iter); #endif /* Dirichlet BCs resemble fixed particle velocities */ - set_bc_dirichlet(sim.g_ghost, sim.nz, -1, 0.0); - set_bc_dirichlet(sim.g_ghost, sim.nz, +1, 0.0); + set_bc_dirichlet(sim->g_ghost, sim->nz, -1, 0.0); + set_bc_dirichlet(sim->g_ghost, sim->nz, +1, 0.0); /* Neumann BCs resemble free surfaces */ - /* set_bc_neumann(sim.g_ghost, sim.nz, +1, 0.0, sim.dz); */ + /* set_bc_neumann(sim->g_ghost, sim->nz, +1, 0.0, sim->dz); */ - for (i=0; i<sim.nz; ++i) + for (i=0; i<sim->nz; ++i) poisson_solver_1d_cell_update(i, - sim.g_ghost, - sim.g_local, + sim->g_ghost, + sim->g_local, g_ghost_out, r_norm, - sim.dz, - sim.mu, - sim.sigma_n_eff, - sim.xi, - sim.mu_s, - sim.C, - sim.b, - sim.rho_s, - sim.d); - r_norm_max = max(r_norm, sim.nz); - - copy_values(g_ghost_out, sim.g_ghost, sim.nz+2); + sim->dz, + sim->mu, + sim->sigma_n_eff, + sim->xi, + sim->mu_s, + sim->C, + sim->b, + sim->rho_s, + sim->d); + r_norm_max = max(r_norm, sim->nz); + + copy_values(g_ghost_out, sim->g_ghost, sim->nz+2); if (r_norm_max <= rel_tol) { - set_bc_dirichlet(sim.g_ghost, sim.nz, -1, 0.0); - set_bc_dirichlet(sim.g_ghost, sim.nz, +1, 0.0); + set_bc_dirichlet(sim->g_ghost, sim->nz, -1, 0.0); + set_bc_dirichlet(sim->g_ghost, sim->nz, +1, 0.0); free(g_ghost_out); free(r_norm); /* printf(".. Solution converged after %d iterations\n", iter); */ @@ -589,16 +587,16 @@ implicit_1d_jacobian_poisson_solver(const int max_iter, } void -write_output_file(const int normalize) +write_output_file(struct simulation *sim, const int normalize) { char outfile[200]; FILE *fp; snprintf(outfile, sizeof(outfile), "%s.output%05d.txt", - sim.name, sim.n_file++); + sim->name, sim->n_file++); if ((fp = fopen(outfile, "w")) != NULL) { - print_output(fp, normalize); + print_output(sim, fp, normalize); fclose(fp); } else { fprintf(stderr, "could not open output file: %s", outfile); @@ -607,43 +605,46 @@ write_output_file(const int normalize) } void -print_output(FILE* fp, const int norm) +print_output(struct simulation *sim, FILE* fp, const int norm) { int i; double *v_x_out; if (norm) - v_x_out = normalize(sim.v_x, sim.nz); + v_x_out = normalize(sim->v_x, sim->nz); else - v_x_out = copy(sim.v_x, sim.nz); + v_x_out = copy(sim->v_x, sim->nz); - for (i=0; i<sim.nz; ++i) + for (i=0; i<sim->nz; ++i) fprintf(fp, - "%.17g\t%.17g\t%.17g\t" - "%.17g\t%.17g\t%.17g\t" - "%.17g\t%.17g\t%.17g\n", - sim.z[i], + "%.17g\t%.17g\t%.17g\t" + "%.17g\t%.17g\t%.17g\t" + "%.17g\t%.17g\t%.17g\n", + sim->z[i], v_x_out[i], - sim.sigma_n_eff[i], - sim.p_f_ghost[i+1], - sim.mu[i], - sim.gamma_dot_p[i], - sim.phi[i], - sim.I[i], - sim.mu[i]*sim.sigma_n_eff[i]); + sim->sigma_n_eff[i], + sim->p_f_ghost[i+1], + sim->mu[i], + sim->gamma_dot_p[i], + sim->phi[i], + sim->I[i], + sim->mu[i]*sim->sigma_n_eff[i]); free(v_x_out); } int -coupled_shear_solver(const int max_iter, +coupled_shear_solver(struct simulation *sim, + const int max_iter, const double rel_tol) { int coupled_iter, stress_iter; - double res_norm, mu_wall_orig; + double res_norm, r_norm_max, mu_wall_orig; + double *r_norm; - res_norm = NAN; - mu_wall_orig = sim.mu_wall; + r_norm_max = NAN; + r_norm = empty(sim->nz); + mu_wall_orig = sim->mu_wall; stress_iter = 0; do { /* stress iterations */ @@ -651,86 +652,89 @@ coupled_shear_solver(const int max_iter, coupled_iter = 0; do { /* coupled iterations */ - if (sim.transient) { + if (sim->transient) { /* step 1 */ - compute_inertia_number(); /* Eq. 1 */ + compute_inertia_number(sim); /* Eq. 1 */ /* step 2 */ - compute_critical_state_porosity(); /* Eq. 2 */ + compute_critical_state_porosity(sim); /* Eq. 2 */ /* step 3 */ - compute_tan_dilatancy_angle(); /* Eq. 5 */ + compute_tan_dilatancy_angle(sim); /* Eq. 5 */ } - compute_critical_state_friction(); /* Eq. 7 */ + compute_critical_state_friction(sim); /* Eq. 7 */ /* step 4 */ - if (sim.transient) { - compute_porosity_change(); /* Eq. 3 */ - compute_permeability(); /* Eq. 6 */ + if (sim->transient) { + compute_porosity_change(sim); /* Eq. 3 */ + compute_permeability(sim); /* Eq. 6 */ } - compute_friction(); /* Eq. 4 */ + compute_friction(sim); /* Eq. 4 */ /* step 5, Eq. 13 */ - if (sim.fluid) - if (darcy_solver_1d(MAX_ITER_DARCY, RTOL_DARCY)) + if (sim->fluid) + if (darcy_solver_1d(sim, MAX_ITER_DARCY, RTOL_DARCY)) exit(11); /* step 6 */ - compute_effective_stress(); /* Eq. 9 */ + compute_effective_stress(sim); /* Eq. 9 */ /* step 7 */ - compute_local_fluidity(); /* Eq. 10 */ - compute_cooperativity_length(); /* Eq. 12 */ + compute_local_fluidity(sim); /* Eq. 10 */ + compute_cooperativity_length(sim); /* Eq. 12 */ /* step 8, Eq. 11 */ - if (implicit_1d_jacobian_poisson_solver(MAX_ITER_GRANULAR, + if (implicit_1d_jacobian_poisson_solver(sim, + MAX_ITER_GRANULAR, RTOL_GRANULAR)) exit(12); /* step 9 */ - compute_shear_strain_rate_plastic(); /* Eq. 8 */ - compute_inertia_number(); - compute_shear_velocity(); + compute_shear_strain_rate_plastic(sim); /* Eq. 8 */ + compute_inertia_number(sim); + compute_shear_velocity(sim); #ifdef DEBUG - for (i=0; i<sim.nz) { - printf("\nsim.t = %g s\n", sim.t); - printf("sim.I[%d] = %g\n", i, sim.I[i]); - printf("sim.phi_c[%d] = %g\n", i, sim.phi_c[i]); - printf("sim.tan_psi[%d] = %g\n", i, sim.tan_psi[i]); - printf("sim.mu_c[%d] = %g\n", i, sim.mu_c[i]); - printf("sim.phi_dot[%d] = %g\n", i, sim.phi_dot[i]); - printf("sim.k[%d] = %g\n", i, sim.k[i]); - printf("sim.mu[%d] = %g\n", i, sim.mu[i]); + for (i=0; i<sim->nz) { + printf("\nsim->t = %g s\n", sim->t); + printf("sim->I[%d] = %g\n", i, sim->I[i]); + printf("sim->phi_c[%d] = %g\n", i, sim->phi_c[i]); + printf("sim->tan_psi[%d] = %g\n", i, sim->tan_psi[i]); + printf("sim->mu_c[%d] = %g\n", i, sim->mu_c[i]); + printf("sim->phi_dot[%d] = %g\n", i, sim->phi_dot[i]); + printf("sim->k[%d] = %g\n", i, sim->k[i]); + printf("sim->mu[%d] = %g\n", i, sim->mu[i]); } #endif - if (!isnan(sim.v_x_limit) || !isnan(sim.v_x_fix)) { - if (!isnan(sim.v_x_limit)) { - res_norm = (sim.v_x_limit - sim.v_x[sim.nz-1]) - /(sim.v_x[sim.nz-1] + 1e-12); + if (!isnan(sim->v_x_limit) || !isnan(sim->v_x_fix)) { + if (!isnan(sim->v_x_limit)) { + res_norm = (sim->v_x_limit - sim->v_x[sim->nz-1]) + /(sim->v_x[sim->nz-1] + 1e-12); if (res_norm > 0.0) res_norm = 0.0; } else { - res_norm = (sim.v_x_fix - sim.v_x[sim.nz-1]) - /(sim.v_x[sim.nz-1] + 1e-12); + res_norm = (sim->v_x_fix - sim->v_x[sim->nz-1]) + /(sim->v_x[sim->nz-1] + 1e-12); } - sim.mu_wall *= 1.0 + (res_norm*1e-2); + sim->mu_wall *= 1.0 + (res_norm*1e-2); } if (++stress_iter > MAX_ITER_STRESS) { fprintf(stderr, "error: stress solution did not converge:\n"); fprintf(stderr, "v_x=%g, v_x_fix=%g, v_x_limit=%g, " - "res_norm=%g, mu_wall=%g\n", - sim.v_x[sim.nz-1], sim.v_x_fix, sim.v_x_limit, - res_norm, sim.mu_wall); + "res_norm=%g, mu_wall=%g\n", + sim->v_x[sim->nz-1], sim->v_x_fix, sim->v_x_limit, + res_norm, sim->mu_wall); return 10; } } while (0); - } while ((!isnan(sim.v_x_fix) || !isnan(sim.v_x_limit)) + } while ((!isnan(sim->v_x_fix) || !isnan(sim->v_x_limit)) && fabs(res_norm) > RTOL_STRESS); - if (!isnan(sim.v_x_limit)) - sim.mu_wall = mu_wall_orig; + if (!isnan(sim->v_x_limit)) + sim->mu_wall = mu_wall_orig; + + free(r_norm); return 0; } diff --git a/simulation.h b/simulation.h @@ -115,19 +115,19 @@ struct simulation { double* tan_psi; /* tan(dilatancy_angle) [-] */ }; -void prepare_arrays(); -void free_arrays(); +void prepare_arrays(struct simulation *sim); +void free_arrays(struct simulation *sim); -void check_simulation_parameters(); +void check_simulation_parameters(struct simulation *sim); -void lithostatic_pressure_distribution(); +void lithostatic_pressure_distribution(struct simulation *sim); -void compute_inertia_number(); -void compute_critical_state_porosity(); -void compute_critical_state_friction(); -void compute_porosity_change(); -void compute_permeability(); -void compute_tan_dilatancy_angle(); +void compute_inertia_number(struct simulation *sim); +void compute_critical_state_porosity(struct simulation *sim); +void compute_critical_state_friction(struct simulation *sim); +void compute_porosity_change(struct simulation *sim); +void compute_permeability(struct simulation *sim); +void compute_tan_dilatancy_angle(struct simulation *sim); void set_bc_neumann(double* g_ghost, const int nz, @@ -140,19 +140,22 @@ void set_bc_dirichlet(double* g_ghost, const int boundary, const double value); -void compute_cooperativity_length(); -void compute_local_fluidity(); -void compute_shear_strain_rate_plastic(); -void compute_shear_velocity(); -void compute_effective_stress(); -void compute_friction(); +void compute_cooperativity_length(struct simulation *sim); +void compute_local_fluidity(struct simulation *sim); +void compute_shear_strain_rate_plastic(struct simulation *sim); +void compute_shear_velocity(struct simulation *sim); +void compute_effective_stress(struct simulation *sim); +void compute_friction(struct simulation *sim); -int implicit_1d_jacobian_poisson_solver(const int max_iter, +int implicit_1d_jacobian_poisson_solver(struct simulation *sim, + const int max_iter, const double rel_tol); -void write_output_file(const int normalize); -void print_output(FILE* fp, const int normalize); +void write_output_file(struct simulation *sim, const int normalize); +void print_output(struct simulation *sim, FILE* fp, const int normalize); -int coupled_shear_solver(const int max_iter, const double rel_tol); +int coupled_shear_solver(struct simulation *sim, + const int max_iter, + const double rel_tol); #endif