tpreallocate arrays for iterative solvers - cngf-pf - continuum model for granular flows with pore-pressure dynamics (renamed from 1d_fd_simple_shear)
 (HTM) git clone git://src.adamsgaard.dk/cngf-pf
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit bfb86ef9008e86da090c6d6c84e165517d0a85b0
 (DIR) parent 7fe3756e69502a715e4554615f16304d6ef76565
 (HTM) Author: Anders Damsgaard <anders@adamsgaard.dk>
       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(-)
       ---
 (DIR) diff --git a/fluid.c b/fluid.c
       t@@ -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 {
        
       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_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",
       t@@ -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;
 (DIR) 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 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
       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 *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);
       t@@ -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;
        }
       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->nz);
        
                                        /* 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 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);
       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;
 (DIR) 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/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 [-] */
       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);