tpreallocate arrays for iterative solvers - cngf-pf - continuum model for granu… | |
git clone git://src.adamsgaard.dk/cngf-pf | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit bfb86ef9008e86da090c6d6c84e165517d0a85b0 | |
parent 7fe3756e69502a715e4554615f16304d6ef76565 | |
Author: Anders Damsgaard <[email protected]> | |
Date: Wed, 18 Nov 2020 13:55:10 +0100 | |
preallocate arrays for iterative solvers | |
Diffstat: | |
M fluid.c | 135 ++++++++++++++++-------------… | |
M simulation.c | 97 +++++++++++++++--------------… | |
M simulation.h | 6 ++++++ | |
3 files changed, 121 insertions(+), 117 deletions(-) | |
--- | |
diff --git a/fluid.c b/fluid.c | |
t@@ -111,21 +111,24 @@ set_fluid_bcs(double *p_f_ghost, struct simulation *sim,… | |
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_… | |
+ return D * (p_f_ghost_in[i + 2] | |
+ - 2.0 * p_f_ghost_in[i + 1] | |
+ + p_f_ghost_in[i]) | |
+ / (dz * dz); | |
else { | |
t@@ -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)) | |
t@@ -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_gh… | |
- sim->phi, | |
- sim->phi_do… | |
- sim->k, | |
- sim->dz, | |
- sim->beta_f, | |
- sim->alpha, | |
- sim->mu_f, | |
- … | |
+ sim->p_f_dot_expl[i] = darcy_pressure_change_1d(i, | |
+ sim->n… | |
+ sim->p… | |
+ sim->p… | |
+ sim->p… | |
+ sim->k, | |
+ sim->d… | |
+ sim->b… | |
+ sim->a… | |
+ sim->m… | |
+ … | |
} | |
+ | |
+ /* 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… | |
- p_f… | |
- sim… | |
- sim… | |
- sim… | |
- sim… | |
- sim… | |
- sim… | |
- sim… | |
- … | |
+ sim->p_f_dot_impl[i] = darcy_pressure_change_1… | |
+ … | |
+ … | |
+ … | |
+ … | |
+ … | |
+ … | |
+ … | |
+ … | |
+ … | |
+ … | |
for (i = 0; i < sim->nz - 1; ++i) { | |
- sim->p_f_dot[i] = epsilon * p_f_dot_impl[i] + … | |
- p_f_ghost_new[i + 1] += sim->p_f_dot[i] * sim-… | |
- r_norm[i] = fabs(residual(sim->p_f_dot[i], old… | |
+ sim->new_ghost[i + 1] = sim->p_f_ghost[i + 1] | |
+ + sim->p_f_dot_impl[i]… | |
+ 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 iterati… | |
+ printf(".. Iterative solution converged after … | |
#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 it… | |
t@@ -290,15 +285,21 @@ darcy_solver_1d(struct simulation *sim, | |
fprintf(stderr, ".. Residual normalized error: %f\n", … | |
} | |
} 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 | |
t@@ -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 node… | |
- 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 | |
t@@ -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); | |
t@@ -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 | |
t@@ -642,11 +654,11 @@ implicit_1d_jacobian_poisson_solver(struct simulation *s… | |
{ | |
int iter, i; | |
double r_norm_max = NAN; | |
- double *tmp, *g_ghost_out = empty(sim->nz + 2), *r_norm = empty(sim->n… | |
+ 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); | |
t@@ -659,31 +671,28 @@ implicit_1d_jacobian_poisson_solver(struct simulation *s… | |
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", … | |
+#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", ite… | |
+ fprintf(stderr, "Solution did not converge after %d iterations\n", ite… | |
fprintf(stderr, ".. Residual normalized error: %f\n", r_norm_max); | |
return 1; | |
} | |
t@@ -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->n… | |
/* step 1 */ | |
compute_inertia_number(sim); /* Eq. 1 */ | |
t@@ -828,14 +832,12 @@ coupled_shear_solver(struct simulation *sim, | |
/* stable porosity change field == coupled solution co… | |
if (sim->transient) { | |
for (i = 0; i < sim->nz; ++i) | |
- r_norm[i] = fabs(residual(sim->phi_dot… | |
- r_norm_max = max(r_norm, sim->nz); | |
+ sim->g_r_norm[i] = fabs(residual(sim->… | |
+ 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 di… | |
"after %d iterations\n", coupl… | |
t@@ -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 | |
t@@ -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… | |
+ double *p_f_dot_impl; /* fluid pressure change (implicit solution) [Pa… | |
+ double *p_f_dot_impl_r_norm; /* normalized residual fluid pressure cha… | |
double *k; /* hydraulic permeability [m^2] */ | |
double *phi; /* porosity [-] */ | |
double *phi_c; /* critical-state porosity [-] */ | |
t@@ -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); |