/* solve natural mobility problem with fixed particles in FT version * without HI * for both periodic and non-periodic boundary conditions * INPUT * sys : system parameters * f [nm * 3] : * t [nm * 3] : * uf [nf * 3] : * of [nf * 3] : * OUTPUT * u [nm * 3] : * o [nm * 3] : * ff [nf * 3] : * tf [nf * 3] : */ void solve_mix_3ft_noHI (struct stokes *sys, const double *f, const double *t, const double *uf, const double *of, double *u, double *o, double *ff, double *tf) { if (sys->version != 1) { fprintf (stderr, "libstokes solve_mix_3ft_noHI :" " the version is wrong. reset to FT\n"); sys->version = 1; } int np = sys->np; int nm = sys->nm; int i; // for fixed particles int nf = np - nm; if (nf > 0) { double *uf0 = (double *) malloc (sizeof (double) * nf * 3); double *of0 = (double *) malloc (sizeof (double) * nf * 3); CHECK_MALLOC (uf0, "solve_mix_3ft_noHI"); CHECK_MALLOC (of0, "solve_mix_3ft_noHI"); shift_labo_to_rest_U (sys, nf, uf, uf0); shift_labo_to_rest_O (sys, nf, of, of0); /* the main calculation is done in the the fluid-rest frame; * u(x)=0 as |x|-> infty */ for (i = 0; i < nf * 3; i ++) { ff[i] = uf0[i]; tf[i] = of0[i] / 0.75; } free (uf0); free (of0); } // for mobile particles for (i = 0; i < nm * 3; i ++) { u[i] = f[i]; o[i] = t[i] * 0.75; } /* for the interface, we are in the labo frame, that is * u(x) is given by the imposed flow field as |x|-> infty */ shift_rest_to_labo_U (sys, nm, u); shift_rest_to_labo_O (sys, nm, o); }
/* solve natural mobility problem in FT version * for both periodic and non-periodic boundary conditions * INPUT * sys : system parameters * f [np * 3] : * t [np * 3] : * OUTPUT * u [np * 3] : * o [np * 3] : */ void solve_mob_3ft_matrix (struct stokes * sys, const double *f, const double *t, double *u, double *o) { if (sys->version != 1) { fprintf (stderr, "libstokes solve_mob_3ft_matrix :" " the version is wrong. reset to FT\n"); sys->version = 1; } int np = sys->np; int n6 = np * 6; double *mat = (double *)malloc (sizeof (double) * n6 * n6); double *b = (double *)malloc (sizeof (double) * n6); double *x = (double *)malloc (sizeof (double) * n6); CHECK_MALLOC (mat, "solve_mob_3ft_matrix"); CHECK_MALLOC (b, "solve_mob_3ft_matrix"); CHECK_MALLOC (x, "solve_mob_3ft_matrix"); /* the main calculation is done in the the fluid-rest frame; * u(x)=0 as |x|-> infty */ /* b := (FTE) */ set_ft_by_FT (np, b, f, t); // M make_matrix_mob_3all (sys, mat); // sys->version is 1 (FT) // x = M.b dot_prod_matrix (mat, n6, n6, b, x); set_FT_by_ft (np, u, o, x); free (mat); free (b); free (x); /* for the interface, we are in the labo frame, that is * u(x) is given by the imposed flow field as |x|-> infty */ shift_rest_to_labo_U (sys, sys->np, u); shift_rest_to_labo_O (sys, sys->np, o); }
/* solve natural mobility problem with lubrication * with fixed particles in FT version * for both periodic and non-periodic boundary conditions * INPUT * sys : system parameters * f [nm * 3] : * t [nm * 3] : * uf [nf * 3] : * of [nf * 3] : * OUTPUT * u [nm * 3] : * o [nm * 3] : * ff [nf * 3] : * tf [nf * 3] : */ void solve_mix_lub_3ft_matrix (struct stokes * sys, const double *f, const double *t, const double *uf, const double *of, double *u, double *o, double *ff, double *tf) { if (sys->version != 1) { fprintf (stderr, "libstokes solve_mix_lub_3ft_matrix :" " the version is wrong. reset to FT\n"); sys->version = 1; } int np = sys->np; int nm = sys->nm; if (np == nm) { solve_mob_lub_3ft_matrix (sys, f, t, u, o); return; } int n6 = np * 6; int nf = np - nm; int nm6 = nm * 6; int nl = nm * 6; int nh = n6 - nl; double *uf0 = (double *) malloc (sizeof (double) * nf * 3); double *of0 = (double *) malloc (sizeof (double) * nf * 3); double *mat = (double *) malloc (sizeof (double) * n6 * n6); double *lub = (double *) malloc (sizeof (double) * n6 * n6); double *tmp = (double *) malloc (sizeof (double) * n6 * n6); double *mat_ll = (double *) malloc (sizeof (double) * nl * nl); double *mat_lh = (double *) malloc (sizeof (double) * nl * nh); double *mat_hl = (double *) malloc (sizeof (double) * nh * nl); double *mat_hh = (double *) malloc (sizeof (double) * nh * nh); double *mob_ll = (double *) malloc (sizeof (double) * nl * nl); double *mob_lh = (double *) malloc (sizeof (double) * nl * nh); double *mob_hl = (double *) malloc (sizeof (double) * nh * nl); double *mob_hh = (double *) malloc (sizeof (double) * nh * nh); double *b = (double *) malloc (sizeof (double) * n6); double *x = (double *) malloc (sizeof (double) * n6); CHECK_MALLOC (uf0, "solve_mix_lub_3ft_matrix"); CHECK_MALLOC (of0, "solve_mix_lub_3ft_matrix"); CHECK_MALLOC (mat, "solve_mix_lub_3ft_matrix"); CHECK_MALLOC (lub, "solve_mix_lub_3ft_matrix"); CHECK_MALLOC (tmp, "solve_mix_lub_3ft_matrix"); CHECK_MALLOC (mat_ll, "solve_mix_lub_3ft_matrix"); CHECK_MALLOC (mat_lh, "solve_mix_lub_3ft_matrix"); CHECK_MALLOC (mat_hl, "solve_mix_lub_3ft_matrix"); CHECK_MALLOC (mat_hh, "solve_mix_lub_3ft_matrix"); CHECK_MALLOC (mob_ll, "solve_mix_lub_3ft_matrix"); CHECK_MALLOC (mob_lh, "solve_mix_lub_3ft_matrix"); CHECK_MALLOC (mob_hl, "solve_mix_lub_3ft_matrix"); CHECK_MALLOC (mob_hh, "solve_mix_lub_3ft_matrix"); CHECK_MALLOC (b, "solve_mix_lub_3ft_matrix"); CHECK_MALLOC (x, "solve_mix_lub_3ft_matrix"); shift_labo_to_rest_U (sys, nf, uf, uf0); shift_labo_to_rest_O (sys, nf, of, of0); /* the main calculation is done in the the fluid-rest frame; * u(x)=0 as |x|-> infty */ /* b := (FT,UfOf) */ set_ft_by_FT (nm, b, f, t); set_ft_by_FT (nf, b + nm6, uf0, of0); free (uf0); free (of0); /* mob */ make_matrix_mob_3all (sys, mat); // sys->version is 1 (FT) split_matrix_fix_3ft (np, nm, mat, mat_ll, mat_lh, mat_hl, mat_hh); /* lub */ make_matrix_lub_3ft (sys, lub); /* tmp := M.L */ mul_matrices (mat, n6, n6, lub, n6, n6, tmp); /* note: at this point, lub[] is free to use. * so that I_?? use lub [] */ double *I_ll = lub; double *I_lh = I_ll + nl * nl; double *I_hl = I_lh + nl * nh; double *I_hh = I_hl + nh * nl; /* tmp := I + (M.T).(L.T) */ int i; for (i = 0; i < n6; ++i) { tmp [i * n6 + i] += 1.0; } split_matrix_fix_3ft (np, nm, tmp, I_ll, I_lh, I_hl, I_hh); free (tmp); solve_gen_linear (nl, nh, I_ll, I_lh, I_hl, I_hh, mat_ll, mat_lh, mat_hl, mat_hh, mob_ll, mob_lh, mob_hl, mob_hh); /* note: at this point, I_??, therefore lub[], is free to use. */ free (lub); merge_matrix_fix_3ft (np, nm, mob_ll, mob_lh, mob_hl, mob_hh, mat); dot_prod_matrix (mat, n6, n6, b, x); set_FT_by_ft (nm, u, o, x); set_FT_by_ft (nf, ff, tf, x + nm6); free (mat); free (mat_ll); free (mat_lh); free (mat_hl); free (mat_hh); free (mob_ll); free (mob_lh); free (mob_hl); free (mob_hh); free (b); free (x); /* for the interface, we are in the labo frame, that is * u(x) is given by the imposed flow field as |x|-> infty */ shift_rest_to_labo_U (sys, nm, u); shift_rest_to_labo_O (sys, nm, o); }
/* solve natural mobility problem with lubrication * with fixed particles in FT version * for both periodic and non-periodic boundary conditions * INPUT * sys : system parameters * f [nm * 3] : * t [nm * 3] : * uf [nf * 3] : * of [nf * 3] : * OUTPUT * u [nm * 3] : * o [nm * 3] : * ff [nf * 3] : * tf [nf * 3] : */ void solve_mix_3ft_matrix (struct stokes * sys, const double *f, const double *t, const double *uf, const double *of, double *u, double *o, double *ff, double *tf) { if (sys->version != 1) { fprintf (stderr, "libstokes solve_mix_3ft_matrix :" " the version is wrong. reset to FT\n"); sys->version = 1; } int np = sys->np; int nm = sys->nm; if (np == nm) { solve_mob_3ft_matrix (sys, f, t, u, o); return; } int n6 = np * 6; int nf = np - nm; int nm6 = nm * 6; int nl = nm * 6; int nh = n6 - nl; double *uf0 = (double *) malloc (sizeof (double) * nf * 3); double *of0 = (double *) malloc (sizeof (double) * nf * 3); double *mat = (double *) malloc (sizeof (double) * n6 * n6); double *mat_ll = (double *) malloc (sizeof (double) * nl * nl); double *mat_lh = (double *) malloc (sizeof (double) * nl * nh); double *mat_hl = (double *) malloc (sizeof (double) * nh * nl); double *mat_hh = (double *) malloc (sizeof (double) * nh * nh); double *mob_ll = (double *) malloc (sizeof (double) * nl * nl); double *mob_lh = (double *) malloc (sizeof (double) * nl * nh); double *mob_hl = (double *) malloc (sizeof (double) * nh * nl); double *mob_hh = (double *) malloc (sizeof (double) * nh * nh); double *b = (double *) malloc (sizeof (double) * n6); double *x = (double *) malloc (sizeof (double) * n6); CHECK_MALLOC (uf0, "solve_mix_3ft_matrix"); CHECK_MALLOC (of0, "solve_mix_3ft_matrix"); CHECK_MALLOC (mat, "solve_mix_3ft_matrix"); CHECK_MALLOC (mat_ll, "solve_mix_3ft_matrix"); CHECK_MALLOC (mat_lh, "solve_mix_3ft_matrix"); CHECK_MALLOC (mat_hl, "solve_mix_3ft_matrix"); CHECK_MALLOC (mat_hh, "solve_mix_3ft_matrix"); CHECK_MALLOC (mob_ll, "solve_mix_3ft_matrix"); CHECK_MALLOC (mob_lh, "solve_mix_3ft_matrix"); CHECK_MALLOC (mob_hl, "solve_mix_3ft_matrix"); CHECK_MALLOC (mob_hh, "solve_mix_3ft_matrix"); CHECK_MALLOC (b, "solve_mix_3ft_matrix"); CHECK_MALLOC (x, "solve_mix_3ft_matrix"); shift_labo_to_rest_U (sys, nf, uf, uf0); shift_labo_to_rest_O (sys, nf, of, of0); /* the main calculation is done in the the fluid-rest frame; * u(x)=0 as |x|-> infty */ /* b := (FT,UfOf) */ set_ft_by_FT (nm, b, f, t); //set_ft_by_FT (nf, b + nm6, uf, of); set_ft_by_FT (nf, b + nm6, uf0, of0); free (uf0); free (of0); /* mobility matrix in EXTRACTED form */ make_matrix_mob_3all (sys, mat); // sys->version is 1 (FT) split_matrix_fix_3ft (np, nm, mat, mat_ll, mat_lh, mat_hl, mat_hh); solve_linear (nh, nl, mat_hh, mat_hl, mat_lh, mat_ll, mob_hh, mob_hl, mob_lh, mob_ll); merge_matrix_fix_3ft (np, nm, mob_ll, mob_lh, mob_hl, mob_hh, mat); dot_prod_matrix (mat, n6, n6, b, x); set_FT_by_ft (nm, u, o, x); set_FT_by_ft (nf, ff, tf, x + nm6); free (mat); free (mat_ll); free (mat_lh); free (mat_hl); free (mat_hh); free (mob_ll); free (mob_lh); free (mob_hl); free (mob_hh); free (b); free (x); /* for the interface, we are in the labo frame, that is * u(x) is given by the imposed flow field as |x|-> infty */ shift_rest_to_labo_U (sys, nm, u); shift_rest_to_labo_O (sys, nm, o); }
/* solve natural mobility problem in FT version * for both periodic and non-periodic boundary conditions * INPUT * sys : system parameters * f [np * 3] : * t [np * 3] : * OUTPUT * u [np * 3] : * o [np * 3] : */ void solve_mob_lub_3ft_matrix (struct stokes * sys, const double *f, const double *t, double *u, double *o) { if (sys->version != 1) { fprintf (stderr, "libstokes solve_mob_lub_3ft_matrix :" " the version is wrong. reset to FT\n"); sys->version = 1; } int np = sys->np; int n6 = np * 6; double *mat = (double *) malloc (sizeof (double) * n6 * n6); double *lub = (double *) malloc (sizeof (double) * n6 * n6); double *iml = (double *) malloc (sizeof (double) * n6 * n6); double *b = (double *) malloc (sizeof (double) * n6); double *x = (double *) malloc (sizeof (double) * n6); CHECK_MALLOC (mat, "solve_mob_lub_3ft_matrix"); CHECK_MALLOC (lub, "solve_mob_lub_3ft_matrix"); CHECK_MALLOC (iml, "solve_mob_lub_3ft_matrix"); CHECK_MALLOC (b, "solve_mob_lub_3ft_matrix"); CHECK_MALLOC (x, "solve_mob_lub_3ft_matrix"); /* the main calculation is done in the the fluid-rest frame; * u(x)=0 as |x|-> infty */ // M make_matrix_mob_3all (sys, mat); // sys->version is 1 (FT) // L make_matrix_lub_3ft (sys, lub); // IML := M.L mul_matrices (mat, n6, n6, lub, n6, n6, iml); free (lub); /* b := (FT) */ set_ft_by_FT (np, b, f, t); // x := M.(FT) dot_prod_matrix (mat, n6, n6, b, x); // IML = I + M.L int i; for (i = 0; i < n6; ++i) { iml [i * n6 + i] += 1.0; } // b := (I+M.L)^-1.M.(FT) /* // IML^-1 lapack_inv_ (n6, iml); dot_prod_matrix (iml, n6, n6, x, b); */ lapack_solve_lin (n6, iml, x, b); set_FT_by_ft (np, u, o, b); free (mat); free (iml); free (b); free (x); /* for the interface, we are in the labo frame, that is * u(x) is given by the imposed flow field as |x|-> infty */ shift_rest_to_labo_U (sys, sys->np, u); shift_rest_to_labo_O (sys, sys->np, o); }