/* Initialize libstokes * Basic parameters for the libstorks * and pos[] are set from init_aggregate. */ void SDsystem::initFlowModel(int num_of_particle_, int lub_correction_, bool prepare_vectors){ if (num_of_particle_ > 0) np = num_of_particle_; nm = np ; /* nm : number of mobile particles */ sd = stokes_init(); // ---> libstokes sd->twobody_lub = lub_correction_; // For shear flows,"FTS version" is required. sd->version = 2; /* 0 = F, 1 = FT, 2 = FTS */ sd->periodic = 0; /* 0 = non periodic, 1 = periodic */ stokes_set_np(sd, np, nm); if (type_of_flow == 'u'){ /* * The velocity of uniform flow is alywas (1,0,0) */ stokes_set_Ui(sd, 1.0, 0.0, 0.0); } else if (type_of_flow == 's'){ /* * The shear rate of shear flow is always 1.0 */ sd->Ui[0] = 0; sd->Oi[1] = 1.0/2; sd->Ei[2] = 1.0/2; } else { cerr << "Type of flow should be given. (shear or uniform)" << endl; } if (prepare_vectors){ try{ velocity = new double [ np*3 ]; omega = new double [ np*3 ]; strain_velocity = new double [ np*5 ]; force = new double [ np*3 ]; torque = new double [ np*3 ]; stresslet = new double [ np*5 ]; } catch (bad_alloc &){ cerr << "bad_alloc at System::init()" << endl; } } }
/* check make_matrix_mob_ewald_3all() for mono and poly(a=1) * with SC config with N=2 * INPUT * version : 0 (F), 1 (FT), 2 (FTS) * dir : direction of the config, 0 (x), 1 (y), 2(z). * phi : volume fraction, that is, phi = (4/3)pi a^3/l^3 * ewald_tr : * ewald_eps : * verbose : if non-zero, print results * tiny : small number for check * OUTPUT * (returned value) : 0 => passed * otherwise => failed */ int check_make_matrix_mob_ewald_3all_poly_SC_2 (int version, int dir, double phi, double ewald_tr, double ewald_eps, int verbose, double tiny) { if (verbose != 0) { fprintf (stdout, "==================================================\n" "check_make_matrix_mob_ewald_3all_poly_SC_2\n" "(%d,dir=%d,phi=%f,tr=%f,eps=%f): start\n", version, dir, phi, ewald_tr, ewald_eps); } // initialize struct stokes *sys struct stokes *sys = stokes_init (); CHECK_MALLOC (sys, "check_make_matrix_mob_ewald_3all_poly_SC_2"); sys->version = version; int np = 2; stokes_set_np (sys, np, np); //sys->lubmin = 2.0000000001; sys->lubmin2 = 4.0000000001; stokes_set_iter (sys, "gmres", 2000, 20, 1.0e-6, 1, stderr); // periodic sys->periodic = 1; double l; l = pow (M_PI / 0.75 / phi, 1.0 / 3.0); if (dir == 1) { // x direction stokes_set_l (sys, 2.0*l, l, l); sys->pos [0] = 0.0; sys->pos [1] = 0.0; sys->pos [2] = 0.0; sys->pos [3] = l; sys->pos [4] = 0.0; sys->pos [5] = 0.0; } else if (dir == 2) { // y direction stokes_set_l (sys, l, 2.0*l, l); sys->pos [0] = 0.0; sys->pos [1] = 0.0; sys->pos [2] = 0.0; sys->pos [3] = 0.0; sys->pos [4] = l; sys->pos [5] = 0.0; } else { // z direction stokes_set_l (sys, l, l, 2.0*l); sys->pos [0] = 0.0; sys->pos [1] = 0.0; sys->pos [2] = 0.0; sys->pos [3] = 0.0; sys->pos [4] = 0.0; sys->pos [5] = l; } double xi = xi_by_tratio (sys, ewald_tr); stokes_set_xi (sys, xi, ewald_eps); int n; if (version == 0) n = 3 * np; else if (version == 1) n = 6 * np; else n = 11 * np; // case 1) -- mono double *mat1 = (double *)malloc (sizeof (double) * n * n); CHECK_MALLOC (mat1, "check_make_matrix_mob_ewald_3all_poly_SC_2"); double t0, t; t0 = ptime_ms_d (); make_matrix_mob_ewald_3all (sys, mat1); t = ptime_ms_d (); double ptime_mono = t - t0; // set sys->a to test poly version double a [2] = {1.0, 1.0}; stokes_set_radius (sys, a); // case 2) -- poly double *mat2 = (double *)malloc (sizeof (double) * n * n); CHECK_MALLOC (mat2, "check_make_matrix_mob_ewald_3all_poly_SC_2"); t0 = ptime_ms_d (); make_matrix_mob_ewald_3all (sys, mat2); t = ptime_ms_d (); double ptime_poly = t - t0; // compare int check = 0; double max = 0.0; char label [80]; int i, j; for (i = 0; i < n; i ++) { for (j = 0; j < n; j ++) { sprintf (label, " (%d, %d) ", i, j); check += compare_max (mat1[i*n+j], mat2[i*n+j], label, verbose, tiny, &max); } } free (mat1); free (mat2); stokes_free (sys); if (verbose != 0) { fprintf (stdout, " ptime mono, poly = %.3f %.3f, poly/mono = %f\n", ptime_mono, ptime_poly, ptime_poly / ptime_mono); fprintf (stdout, " max error = %e vs tiny = %e\n", max, tiny); if (check == 0) fprintf (stdout, " => PASSED\n\n"); else fprintf (stdout, " => FAILED\n\n"); } return (check); }
/* check atimes_ewald_3all() for mono and poly(a=1) with SC config with N=1 * INPUT * version : 0 (F), 1 (FT), 2 (FTS) * phi : volume fraction, that is, phi = (4/3)pi a^3/l^3 * ewald_tr : * ewald_eps : * verbose : if non-zero, print results * tiny : small number for check * OUTPUT * (returned value) : 0 => passed * otherwise => failed */ int check_atimes_ewald_3all_poly_SC_1 (int version, double phi, double ewald_tr, double ewald_eps, int verbose, double tiny) { if (verbose != 0) { fprintf (stdout, "==================================================\n" "check_atimes_ewald_3all_poly_SC_1\n" "(%d,phi=%f,tr=%f,eps=%f)" ": start\n", version, phi, ewald_tr, ewald_eps); } // initialize struct stokes *sys struct stokes *sys = stokes_init (); CHECK_MALLOC (sys, "check_atimes_ewald_3all_poly_SC_1"); sys->version = version; int np = 1; stokes_set_np (sys, np, np); sys->pos [0] = 0.0; sys->pos [1] = 0.0; sys->pos [2] = 0.0; sys->lubmin2 = 4.0000000001; stokes_set_iter (sys, "gmres", 2000, 20, 1.0e-6, 1, stderr); // periodic sys->periodic = 1; double l; l = pow (M_PI / 0.75 / phi, 1.0 / 3.0); stokes_set_l (sys, l, l, l); double xi = xi_by_tratio (sys, ewald_tr); stokes_set_xi (sys, xi, ewald_eps); int n; if (version == 0) n = 3 * np; else if (version == 1) n = 6 * np; else n = 11 * np; double *x = (double *)malloc (sizeof (double) * n); CHECK_MALLOC (x, "check_atimes_ewald_3all_poly_SC_1"); int i; for (i = 0; i < n; i ++) { x[i] = 1.0; } // case 1) -- mono code double *y1 = (double *)malloc (sizeof (double) * n); CHECK_MALLOC (y1, "check_atimes_ewald_3all_poly_SC_1"); double t0, t; t0 = ptime_ms_d (); atimes_ewald_3all (n, x, y1, (void *)sys); t = ptime_ms_d (); double ptime_mono = t - t0; // set sys->a to test poly version double a [1] = {1.0}; stokes_set_radius (sys, a); // case 2) -- poly code double *y2 = (double *)malloc (sizeof (double) * n); CHECK_MALLOC (y2, "check_atimes_ewald_3all_poly_SC_1"); t0 = ptime_ms_d (); atimes_ewald_3all (n, x, y2, (void *)sys); t = ptime_ms_d (); double ptime_poly = t - t0; // compare int check = 0; double max = 0.0; char label [80]; for (i = 0; i < n; i ++) { sprintf (label, " (%d) ", i); check += compare_max (y1[i], y2[i], label, verbose, tiny, &max); } free (x); free (y1); free (y2); stokes_free (sys); if (verbose != 0) { fprintf (stdout, " ptime mono, poly = %.3f %.3f, poly/mono = %f\n", ptime_mono, ptime_poly, ptime_poly / ptime_mono); fprintf (stdout, " max error = %e vs tiny = %e\n", max, tiny); if (check == 0) fprintf (stdout, " => PASSED\n\n"); else fprintf (stdout, " => FAILED\n\n"); } return (check); }
int check_CF_sphere_calc_force (double R, int verbose, double tiny) { if (verbose != 0) { fprintf (stdout, "==================================================\n" "check_CF_sphere_calc_force (R=%f) : start\n", R); } int check = 0; double max = 0.0; struct confinement *cf = CF_init (0, // sphere R, 0.0, // r, 0.0, // x, 0.0, // y, 0.0, // z, 0.0, // R2, 0.0, // L, 1, // flag_LJ 10.0, // e R + 2.0); // r0 // note now r is in [0, 2R) and a = 1, so it is to prevent overflow. CHECK_MALLOC (cf, "check_CF_sphere_calc_force"); // set struct stokes *sys int np = 1; double *f = (double *)malloc (sizeof (double) * np * 3); CHECK_MALLOC (f, "check_CF_sphere_calc_force"); struct stokes *sys = stokes_init (); CHECK_MALLOC (sys, "check_CF_sphere_calc_force"); stokes_set_np (sys, np, np); char label[80]; int i; for (i = 0; i < 100; i ++) { double r = (double)i / 100.0 * 2.0 * R; int j; for (j = 0; j < 10; j ++) { double theta = M_PI * (double)j / 10.0; int k; for (k = 0; k < 20; k ++) { double phi = 2.0 * M_PI * (double) k / 20.0; sys->pos[0] = r * sin(theta) * cos(phi); sys->pos[1] = r * sin(theta) * sin(phi); sys->pos[2] = r * cos(theta); CF_sphere_calc_force (cf, sys, f, 0 /* zero-clear */); if (r <= (R-1.0)) { sprintf (label, " sphere (%f,%5.1f,%5.1f) fx", r, 180.0/M_PI*theta, 180.0/M_PI*phi); check += compare_max (f[0], 0.0, label, verbose, tiny, &max); sprintf (label, " sphere (%f,%5.1f,%5.1f) fy", r, 180.0/M_PI*theta, 180.0/M_PI*phi); check += compare_max (f[1], 0.0, label, verbose, tiny, &max); sprintf (label, " sphere (%f,%5.1f,%5.1f) fz", r, 180.0/M_PI*theta, 180.0/M_PI*phi); check += compare_max (f[2], 0.0, label, verbose, tiny, &max); } else { double x = r - (R-1.0); // depth of overlap double LJ_r = cf->r0 - x; double fr = 12.0 * cf->e * pow (cf->r0 / LJ_r, 7.0) * (pow (cf->r0 / LJ_r, 6.0) - 1.0); double fx = -fr * sin(theta) * cos(phi); double fy = -fr * sin(theta) * sin(phi); double fz = -fr * cos(theta); sprintf (label, " sphere (%f,%5.1f,%5.1f) fx", r, 180.0/M_PI*theta, 180.0/M_PI*phi); check += compare_max (f[0], fx, label, verbose, tiny, &max); sprintf (label, " sphere (%f,%5.1f,%5.1f) fy", r, 180.0/M_PI*theta, 180.0/M_PI*phi); check += compare_max (f[1], fy, label, verbose, tiny, &max); sprintf (label, " sphere (%f,%5.1f,%5.1f) fz", r, 180.0/M_PI*theta, 180.0/M_PI*phi); check += compare_max (f[2], fz, label, verbose, tiny, &max); } } } } CF_free (cf); if (verbose != 0) { fprintf (stdout, " max error = %e vs tiny = %e\n", max, tiny); if (check == 0) fprintf (stdout, " => PASSED\n\n"); else fprintf (stdout, " => FAILED\n\n"); } return (check); }
/* check reading SCM script */ int check_EV_LJ_calc_force (double r, int verbose, double tiny) { if (verbose != 0) { fprintf (stdout, "==================================================\n" "check_EV_LJ_calc_force : start\n"); } int check = 0; double max = 0.0; int n = 2; // two particle problem double *f = (double *)malloc (sizeof (double) * 3 * n); CHECK_MALLOC (f, "check_EV_LJ_calc_force"); // set struct stokes *sys struct stokes *sys = stokes_init (); CHECK_MALLOC (sys, "check_EV_LJ_calc_force"); stokes_set_np (sys, n, n); sys->pos[0] = 0.0; sys->pos[1] = 0.0; sys->pos[2] = 0.0; sys->pos[3] = r; sys->pos[4] = 0.0; sys->pos[5] = 0.0; struct EV_LJ *ev_LJ = EV_LJ_init (n); CHECK_MALLOC (ev_LJ, "check_EV_LJ_calc_force"); // parameters double e = 10.0; // in kT double r0 = 2.0; // in length ==> r can be in the range (0, 2). ev_LJ->e[0] = e; ev_LJ->e[1] = e; ev_LJ->r0[0] = r0; ev_LJ->r0[1] = r0; // scale double peclet = 1.0; EV_LJ_scale (ev_LJ, peclet); check += compare_max (ev_LJ->e[0], e / peclet / r0, " e[0]", verbose, tiny, &max); check += compare_max (ev_LJ->e[1], e / peclet / r0, " e[1]", verbose, tiny, &max); EV_LJ_calc_force (ev_LJ, sys, f, 0); // after zero-clear check += compare_max (f[1], 0.0, " Fy(0,0,0)", verbose, tiny, &max); check += compare_max (f[2], 0.0, " Fz(0,0,0)", verbose, tiny, &max); check += compare_max (f[4], 0.0, " Fy(r,0,0)", verbose, tiny, &max); check += compare_max (f[5], 0.0, " Fz(r,0,0)", verbose, tiny, &max); // scalar part of the force is positive double overlap = 2.0 - r; double r_LJ = r0 - overlap; if (r_LJ < 0.0) { r_LJ = 1.0e-12; } double ri = r0 / r_LJ; double ri6 = pow (ri, 6.0); double ri7 = ri6 * ri; double f_check = 12.0 * e * ri7 * (ri6 - 1.0); if (overlap < 0.0) { check += compare_max (f[0], 0.0, " Fx(0,0,0)", verbose, tiny, &max); check += compare_max (f[3], 0.0, " Fx(r,0,0)", verbose, tiny, &max); } else { check += compare_max (f[0], -f_check, " Fx(0,0,0)", verbose, tiny, &max); check += compare_max (f[3], f_check, " Fx(r,0,0)", verbose, tiny, &max); } free (f); stokes_free (sys); EV_LJ_free (ev_LJ); if (verbose != 0) { fprintf (stdout, " max error = %e vs tiny = %e\n", max, tiny); if (check == 0) fprintf (stdout, " => PASSED\n\n"); else fprintf (stdout, " => FAILED\n\n"); } return (check); }
/* main program */ int main (int argc, char** argv) { struct stokes *sys = stokes_init (); int np, nm; np = 8; nm = 8; stokes_set_np (sys, np, nm); sys->periodic = 1; // periodic boundary condition double lx, ly, lz; lx = 10.0; ly = 10.0; lz = 10.0; stokes_set_l (sys, lx, ly, lz); double ewald_tr = 60.25; double xi = xi_by_tratio (sys, ewald_tr); double ewald_eps = 1.0e-12; stokes_set_xi (sys, xi, ewald_eps); fprintf (stdout, "xi = %f\n", xi); //sys->lubmin = 2.0000000001; sys->lubmin2 = 4.0000000001; sys->lubmax = 4.0; stokes_set_iter (sys, "gmres", 2000, 20, 1.0e-6, 1, stdout); int i; double * pos; double * u; double * f; pos = (double *)calloc (np * 3, sizeof (double)); u = (double *)calloc (np * 3, sizeof (double)); f = (double *)calloc (np * 3, sizeof (double)); pos[ 0] = 0.0; // x component pos[ 1] = 0.0; // y component pos[ 2] = 0.0; // z component pos[ 3] = 5.0; pos[ 4] = 0.0; pos[ 5] = 0.0; pos[ 6] = 0.0; pos[ 7] = 5.0; pos[ 8] = 0.0; pos[ 9] = 0.0; pos[10] = 0.0; pos[11] = 5.0; pos[12] = 5.0; pos[13] = 5.0; pos[14] = 0.0; pos[15] = 0.0; pos[16] = 5.0; pos[17] = 5.0; pos[18] = 5.0; pos[19] = 0.0; pos[20] = 5.0; pos[21] = 5.0; pos[22] = 5.0; pos[23] = 5.0; for (i = 0; i < np * 3; i ++) { u[i] = 1.0; } fprintf (stdout, "pos:\n"); for (i = 0; i < np; i ++) { fprintf (stdout, "%d %f %f %f\n", i, pos[i*3 + 0], pos[i*3 + 1], pos[i*3 + 2]); } fprintf (stdout, "u:\n"); for (i = 0; i < np; i ++) { fprintf (stdout, "%d %f %f %f\n", i, u[i*3 + 0], u[i*3 + 1], u[i*3 + 2]); } stokes_set_pos (sys, pos); solve_res_3f (sys, u, f); fprintf (stdout, "f:\n"); for (i = 0; i < np; i ++) { fprintf (stdout, "%d %f %f %f\n", i, f[i*3 + 0], f[i*3 + 1], f[i*3 + 2]); } return 0; }
/* * INPUT * verbose : if non-zero, print results * OUTPUT * (returned value) : 0 => passed * otherwise => failed */ int check_bd (int ncheb, int np, double r, int verbose, double tiny) { char label[80]; sprintf (label, "check-bd (ncheb=%d, eps=%e)", ncheb, tiny); if (verbose != 0) { fprintf (stdout, "==================================================\n" "%s : start\n", label); } int check = 0; double max = 0.0; struct KIrand *rng = KIrand_init (); struct stokes *sys = stokes_init (); stokes_set_np (sys, np, np); // all mobile particles sys->lubmin2 = 4.0000000001; sys->lubmax = 4.0; stokes_set_iter (sys, "gmres", 2000, 20, 1.0e-6, 1, stdout); double *pos = (double *)malloc (sizeof (double) * np * 3); CHECK_MALLOC (pos, "test-bd"); double x0 = (double)np * r / 2.0; int i; for (i = 0; i < np; i ++) { pos [i*3 ] = (double)i * r - x0; pos [i*3+1] = 0.0; pos [i*3+2] = 0.0; } stokes_set_pos (sys, pos); // F version sys->version = 0; int n = sys->np * 3; double eig[2]; dsaupd_wrap_min_max (n, eig, atimes_3all, (void *)sys, 1.0e-12); //dnaupd_wrap_min_max (n, eig, atimes_3all, (void *)sys, 1.0e-12); // prepare chebyshev coefficients for f(x) = 1/sqrt(x) double *a_cheb = (double *)malloc (sizeof (double) * ncheb); CHECK_MALLOC (a_cheb, "test_bd"); chebyshev_coef (ncheb, check_bd_my_inv_sqrt, eig[0], eig[1], a_cheb); double *y = (double *)malloc (sizeof (double) * n); double *z = (double *)malloc (sizeof (double) * n); CHECK_MALLOC (y, "test_bd"); CHECK_MALLOC (z, "test_bd"); for (i = 0; i < n; i ++) { y[i] = KIrand_Gaussian (rng); } // calc vector z = (M)^{-1/2}.y chebyshev_eval_atimes (ncheb, a_cheb, n, y, z, eig[0], eig[1], atimes_3all, (void *)sys); double err_cheb = chebyshev_error_minvsqrt (n, y, z, atimes_3all, (void *)sys); free (y); free (z); free (a_cheb); free (pos); stokes_free (sys); KIrand_free (rng); check += compare_max (err_cheb+1.0, 1.0, label, verbose, tiny, &max); if (verbose != 0) { fprintf (stdout, " max error = %e vs tiny = %e\n", max, tiny); if (check == 0) fprintf (stdout, " => PASSED\n\n"); else fprintf (stdout, " => FAILED\n\n"); } return (check); }