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 bfb86ef9008e86da090c6d6c84e165517d0a85b0
parent 7fe3756e69502a715e4554615f16304d6ef76565
Author: Anders Damsgaard <anders@adamsgaard.dk>
Date:   Wed, 18 Nov 2020 13:55:10 +0100

preallocate arrays for iterative solvers

Diffstat:
Mfluid.c | 135++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msimulation.c | 97++++++++++++++++++++++++++++++++++++++-----------------------------------------
Msimulation.h | 6++++++
3 files changed, 121 insertions(+), 117 deletions(-)

diff --git a/fluid.c b/fluid.c @@ -111,21 +111,24 @@ set_fluid_bcs(double *p_f_ghost, struct simulation *sim, const double p_f_top) static double darcy_pressure_change_1d(const int i, - const int nz, - const double *p_f_ghost_in, - const double *phi, - const double *phi_dot, - const double *k, - const double dz, - const double beta_f, - const double alpha, - const double mu_f, - const double D) + const int nz, + const double *p_f_ghost_in, + const double *phi, + const double *phi_dot, + const double *k, + const double dz, + const double beta_f, + const double alpha, + const double mu_f, + const double D) { double k_, div_k_grad_p, k_zn, k_zp; if (D > 0.0) - return D*(p_f_ghost_in[i + 2] - 2.0 * p_f_ghost_in[i + 1] + p_f_ghost_in[i])/(dz*dz); + return D * (p_f_ghost_in[i + 2] + - 2.0 * p_f_ghost_in[i + 1] + + p_f_ghost_in[i]) + / (dz * dz); else { @@ -171,17 +174,13 @@ darcy_solver_1d(struct simulation *sim, { int i, iter, solved = 0; double epsilon, p_f_top, r_norm_max = NAN; - double *p_f_dot_expl, *p_f_dot_impl, *p_f_ghost_new; - double *tmp, *r_norm, *old_val; - - p_f_dot_impl = zeros(sim->nz); - p_f_dot_expl = zeros(sim->nz); - p_f_ghost_new = zeros(sim->nz + 2); + double *tmp; /* choose integration method, parameter in [0.0; 1.0] * epsilon = 0.0: explicit * epsilon = 0.5: Crank-Nicolson - * epsilon = 1.0: * implicit */ + * epsilon = 1.0: implicit */ + /* epsilon = 0.5; */ epsilon = 0.5; if (isnan(sim->p_f_mod_pulse_time)) @@ -205,84 +204,80 @@ darcy_solver_1d(struct simulation *sim, /* set fluid BCs (1 of 2) */ - copy_values(sim->p_f_ghost, p_f_ghost_new, sim->nz + 2); - set_fluid_bcs(p_f_ghost_new, sim, p_f_top); + set_fluid_bcs(sim->p_f_ghost, sim, p_f_top); + copy_values(sim->p_f_ghost, sim->new_ghost, sim->nz + 2); + /* explicit solution to pressure change */ if (epsilon < 1.0) { - /* compute explicit solution to pressure change */ for (i = 0; i < sim->nz; ++i) - p_f_dot_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->alpha, - sim->mu_f, - sim->D); + sim->p_f_dot_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->alpha, + sim->mu_f, + sim->D); } + + /* implicit solution with Jacobian iterations */ if (epsilon > 0.0) { - /* compute implicit solution with Jacobian iterations */ - r_norm = zeros(sim->nz); - old_val = empty(sim->nz); for (iter = 0; iter < max_iter; ++iter) { - copy_values(sim->p_f_dot, old_val, sim->nz); + copy_values(sim->p_f_dot_impl, sim->old_val, sim->nz); /* set fluid BCs (2 of 2) */ - set_fluid_bcs(p_f_ghost_new, sim, p_f_top); + set_fluid_bcs(sim->new_ghost, sim, p_f_top); #ifdef DEBUG puts(".. p_f_ghost after BC:"); - print_array(p_f_ghost_new, sim->nz + 2); + print_array(sim->new_ghost, sim->nz + 2); #endif for (i = 0; i < sim->nz - 1; ++i) - p_f_dot_impl[i] = darcy_pressure_change_1d(i, - sim->nz, - p_f_ghost_new, - sim->phi, - sim->phi_dot, - sim->k, - sim->dz, - sim->beta_f, - sim->alpha, - sim->mu_f, - sim->D); + sim->p_f_dot_impl[i] = darcy_pressure_change_1d(i, + sim->nz, + sim->new_ghost, + sim->phi, + sim->phi_dot, + sim->k, + sim->dz, + sim->beta_f, + sim->alpha, + sim->mu_f, + sim->D); for (i = 0; i < sim->nz - 1; ++i) { - sim->p_f_dot[i] = epsilon * p_f_dot_impl[i] + (1.0 - epsilon) * p_f_dot_expl[i]; - p_f_ghost_new[i + 1] += sim->p_f_dot[i] * sim->dt; - r_norm[i] = fabs(residual(sim->p_f_dot[i], old_val[i])); + sim->new_ghost[i + 1] = sim->p_f_ghost[i + 1] + + sim->p_f_dot_impl[i] * sim->dt; + sim->p_f_dot_impl_r_norm[i] = fabs(residual( + sim->p_f_dot_impl[i], sim->old_val[i])); } - r_norm_max = max(r_norm, sim->nz); + r_norm_max = max(sim->p_f_dot_impl_r_norm, sim->nz); #ifdef DEBUG puts(".. p_f_ghost_new:"); - print_array(p_f_ghost_new, sim->nz + 2); + print_array(sim->new_ghost, sim->nz + 2); #endif - tmp = p_f_ghost_new; - p_f_ghost_new = sim->p_f_ghost; + tmp = sim->new_ghost; + sim->new_ghost = sim->p_f_ghost; sim->p_f_ghost = tmp; #ifdef DEBUG puts(".. p_f_ghost after update:"); - print_array(p_f_ghost_new, sim->nz + 2); + print_array(sim->new_ghost, sim->nz + 2); #endif if (r_norm_max <= rel_tol) { #ifdef DEBUG - printf(".. Solution converged after %d iterations\n", iter); + printf(".. Iterative solution converged after %d iterations\n", iter); #endif solved = 1; break; } } - free(p_f_dot_impl); - free(p_f_dot_expl); - free(p_f_ghost_new); - free(r_norm); if (!solved) { fprintf(stderr, "darcy_solver_1d: "); fprintf(stderr, "Solution did not converge after %d iterations\n", @@ -290,15 +285,21 @@ darcy_solver_1d(struct simulation *sim, fprintf(stderr, ".. Residual normalized error: %f\n", r_norm_max); } } else { - for (i = 0; i < sim->nz; ++i) - sim->p_f_dot[i] = p_f_dot_expl[i]; solved = 1; + } + + for (i = 0; i < sim->nz; ++i) + sim->p_f_dot[i] = epsilon * sim->p_f_dot_impl[i] + + (1.0 - epsilon) * sim->p_f_dot_expl[i]; + #ifdef DEBUG + printf(".. epsilon = %s\n", epsilon); + puts(".. p_f_dot_impl:"); + print_array(sim->p_f_dot_impl, sim->nz); puts(".. p_f_dot_expl:"); - print_array(p_f_dot_expl, sim->nz); + print_array(sim->p_f_dot_expl, sim->nz); #endif - free(p_f_dot_expl); - } + set_fluid_bcs(sim->p_f_ghost, sim, p_f_top); return solved - 1; diff --git a/simulation.c b/simulation.c @@ -141,27 +141,33 @@ prepare_arrays(struct simulation *sim) free(sim->phi); free(sim->k); - sim->z = linspace(sim->origo_z, /* spatial coordinates */ + sim->z = linspace(sim->origo_z, 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->p_f_dot = zeros(sim->nz); /* fluid pressure change */ - 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) */ + sim->dz = sim->z[1] - sim->z[0]; + sim->mu = zeros(sim->nz); + sim->mu_c = zeros(sim->nz); + sim->sigma_n_eff = zeros(sim->nz); + sim->sigma_n = zeros(sim->nz); + sim->p_f_ghost = zeros(sim->nz + 2); + sim->p_f_dot = zeros(sim->nz); + sim->p_f_dot_expl = zeros(sim->nz); + sim->p_f_dot_impl = zeros(sim->nz); + sim->p_f_dot_impl_r_norm = zeros(sim->nz); + sim->phi = zeros(sim->nz); + sim->phi_c = zeros(sim->nz); + sim->phi_dot = zeros(sim->nz); + sim->k = zeros(sim->nz); + sim->xi = zeros(sim->nz); + sim->gamma_dot_p = zeros(sim->nz); + sim->v_x = zeros(sim->nz); + sim->g_local = zeros(sim->nz); + sim->g_ghost = zeros(sim->nz + 2); + sim->g_r_norm = zeros(sim->nz); + sim->I = zeros(sim->nz); + sim->tan_psi = zeros(sim->nz); + sim->old_val = empty(sim->nz); + sim->new_ghost = empty(sim->nz + 2); } void @@ -174,6 +180,9 @@ free_arrays(struct simulation *sim) free(sim->sigma_n); free(sim->p_f_ghost); free(sim->p_f_dot); + free(sim->p_f_dot_expl); + free(sim->p_f_dot_impl); + free(sim->p_f_dot_impl_r_norm); free(sim->k); free(sim->phi); free(sim->phi_c); @@ -183,8 +192,11 @@ free_arrays(struct simulation *sim) free(sim->v_x); free(sim->g_local); free(sim->g_ghost); + free(sim->g_r_norm); free(sim->I); free(sim->tan_psi); + free(sim->old_val); + free(sim->new_ghost); } static void @@ -642,11 +654,11 @@ implicit_1d_jacobian_poisson_solver(struct simulation *sim, { int iter, i; double r_norm_max = NAN; - double *tmp, *g_ghost_out = empty(sim->nz + 2), *r_norm = empty(sim->nz); + double *tmp; for (iter = 0; iter < max_iter; ++iter) { #ifdef DEBUG - printf("\n@@@ ITERATION %d @@@\n", iter); + printf("\n@@@ %s: ITERATION %d @@@\n", __func__, iter); #endif /* Dirichlet BCs resemble fixed particle velocities */ set_bc_dirichlet(sim->g_ghost, sim->nz, -1, 0.0); @@ -659,31 +671,28 @@ implicit_1d_jacobian_poisson_solver(struct simulation *sim, poisson_solver_1d_cell_update(i, sim->g_ghost, sim->g_local, - g_ghost_out, - r_norm, + sim->new_ghost, + sim->g_r_norm, sim->dz, sim->xi); - r_norm_max = max(r_norm, sim->nz); + r_norm_max = max(sim->g_r_norm, sim->nz); - tmp = g_ghost_out; - g_ghost_out = sim->g_ghost; + tmp = sim->new_ghost; + sim->new_ghost = sim->g_ghost; sim->g_ghost = tmp; 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); - free(g_ghost_out); - free(r_norm); - /* printf(".. Solution converged after %d - * iterations\n", iter); */ +#ifdef DEBUG + printf(".. Solution converged after %d iterations\n", iter + 1); +#endif return 0; } } - free(g_ghost_out); - free(r_norm); fprintf(stderr, "implicit_1d_jacobian_poisson_solver: "); - fprintf(stderr, "Solution did not converge after %d iterations\n", iter); + fprintf(stderr, "Solution did not converge after %d iterations\n", iter + 1); fprintf(stderr, ".. Residual normalized error: %f\n", r_norm_max); return 1; } @@ -753,24 +762,19 @@ temporal_increment(struct simulation *sim) int coupled_shear_solver(struct simulation *sim, - const int max_iter, - const double rel_tol) + const int max_iter, + const double rel_tol) { int i, coupled_iter, stress_iter = 0; - double *r_norm, *old_val; double r_norm_max, vel_res_norm = NAN, mu_wall_orig = sim->mu_wall; - if (sim->transient) { - r_norm = empty(sim->nz); - old_val = empty(sim->nz); - } do { /* stress iterations */ coupled_iter = 0; do { /* coupled iterations */ if (sim->transient) { - copy_values(sim->phi_dot, old_val, sim->nz); + copy_values(sim->phi_dot, sim->old_val, sim->nz); /* step 1 */ compute_inertia_number(sim); /* Eq. 1 */ @@ -828,14 +832,12 @@ coupled_shear_solver(struct simulation *sim, /* stable porosity change field == coupled solution converged */ if (sim->transient) { for (i = 0; i < sim->nz; ++i) - r_norm[i] = fabs(residual(sim->phi_dot[i], old_val[i])); - r_norm_max = max(r_norm, sim->nz); + sim->g_r_norm[i] = fabs(residual(sim->phi_dot[i], sim->old_val[i])); + r_norm_max = max(sim->g_r_norm, sim->nz); if (r_norm_max <= rel_tol) break; if (coupled_iter++ >= max_iter) { - free(r_norm); - free(old_val); fprintf(stderr, "coupled_shear_solver: "); fprintf(stderr, "Transient solution did not converge " "after %d iterations\n", coupled_iter); @@ -872,11 +874,6 @@ coupled_shear_solver(struct simulation *sim, if (!isnan(sim->v_x_limit)) sim->mu_wall = mu_wall_orig; - if (sim->transient) { - free(r_norm); - free(old_val); - } - temporal_increment(sim); return 0; diff --git a/simulation.h b/simulation.h @@ -107,6 +107,9 @@ struct simulation { double *sigma_n; /* normal stress [Pa] */ double *p_f_ghost; /* fluid pressure [Pa] */ double *p_f_dot; /* fluid pressure change [Pa/s] */ + double *p_f_dot_expl; /* fluid pressure change (explicit solution) [Pa/s] */ + double *p_f_dot_impl; /* fluid pressure change (implicit solution) [Pa/s] */ + double *p_f_dot_impl_r_norm; /* normalized residual fluid pressure change [-] */ double *k; /* hydraulic permeability [m^2] */ double *phi; /* porosity [-] */ double *phi_c; /* critical-state porosity [-] */ @@ -116,8 +119,11 @@ struct simulation { double *v_x; /* shear velocity [m/s] */ double *g_local; /* local fluidity */ double *g_ghost; /* fluidity with ghost nodes */ + double *g_r_norm; /* normalized residual of fluidity field */ double *I; /* inertia number [-] */ double *tan_psi; /* tan(dilatancy_angle) [-] */ + double *old_val; /* temporary storage for iterative solvers */ + double *new_ghost; /* temporary storage for iterative solvers */ }; void init_sim(struct simulation *sim);