/** * @brief Function to set all vmg parameters with a single call * * @param handle FCS-object that contains the parameters * @param max_level The maximum level of the algorithm, i.e. n_gridpoints = 2^max_level. * @param spline_degree The degree of the interpolating B-Splines. * @param max_iterations The maximum number of multigrid iterations. * @param smoothing_steps Number of pre/postsmoothing steps on each level. * @param cycle_type Cycle-number. * @param precision Desired precision. * @param near_field_cells Number of near field cells. * @param interpolation_order Interpolation order. * @param discretization_order Discretization order. * * @return FCSResult-object containing the return value. */ extern FCSResult fcs_vmg_setup(FCS handle, fcs_int max_level, fcs_int max_iterations, fcs_int smoothing_steps, fcs_int cycle_type, fcs_float precision, fcs_int near_field_cells, fcs_int interpolation_order, fcs_int discretization_order) { FCSResult result; char fnc_name[] = "fcs_vmg_setup"; if (handle == NULL) return fcsResult_create(FCS_NULL_ARGUMENT, fnc_name, "null pointer supplied as handle"); if (fcs_get_method(handle) != FCS_VMG) return fcsResult_create(FCS_WRONG_ARGUMENT, fnc_name, "Wrong method chosen. You should choose \"vmg\"."); result = fcs_vmg_set_max_level(handle, max_level); if (result != NULL) return result; result = fcs_vmg_set_max_iterations(handle, max_iterations); if (result != NULL) return result; result = fcs_vmg_set_smoothing_steps(handle, smoothing_steps); if (result != NULL) return result; result = fcs_vmg_set_cycle_type(handle, cycle_type); if (result != NULL) return result; result = fcs_vmg_set_precision(handle, precision); if (result != NULL) return result; result = fcs_vmg_set_near_field_cells(handle, near_field_cells); if (result != NULL) return result; result = fcs_vmg_set_interpolation_order(handle, interpolation_order); if (result != NULL) return result; result = fcs_vmg_set_discretization_order(handle, discretization_order); if (result != NULL) return result; return NULL; }
void init_fcs(void) { FCSResult res; fcs_int srf = 1; char *method; fcs_int pbc [3] = { pbc_dirs.x, pbc_dirs.y, pbc_dirs.z }; fcs_float BoxX[3] = { box_x.x, box_x.y, box_x.z }; fcs_float BoxY[3] = { box_y.x, box_y.y, box_y.z }; fcs_float BoxZ[3] = { box_z.x, box_z.y, box_z.z }; fcs_float off [3] = { 0.0, 0.0, 0.0 }; /* subtract CM momentum */ if (0 == imdrestart) { int i, k; real ptot[4], ptot_2[4], px, py, pz; ptot[0] = 0.0; ptot[1] = 0.0; ptot[2] = 0.0, ptot[3] = 0.0; for (k=0; k<NCELLS; ++k) { /* loop over all cells */ cell *p = CELLPTR(k); for (i=0; i<p->n; i++) { ptot[0] += IMPULS(p,i,X); ptot[1] += IMPULS(p,i,Y); ptot[2] += IMPULS(p,i,Z); ptot[3] += MASSE(p,i); } } #ifdef MPI MPI_Allreduce( ptot, ptot_2, 4, REAL, MPI_SUM, cpugrid); ptot[0] = ptot_2[0]; ptot[1] = ptot_2[1]; ptot[2] = ptot_2[2]; ptot[3] = ptot_2[3]; #endif px = ptot[0]/ptot[3]; py = ptot[1]/ptot[3]; pz = ptot[2]/ptot[3]; for (k=0; k<NCELLS; ++k) { /* loop over all cells */ cell *p = CELLPTR(k); for (i=0; i<p->n; i++) { IMPULS(p,i,X) -= px * MASSE(p,i); IMPULS(p,i,Y) -= py * MASSE(p,i); IMPULS(p,i,Z) -= pz * MASSE(p,i); } } } switch (fcs_method) { case FCS_METH_DIRECT: method = "direct"; break; case FCS_METH_PEPC: method = "pepc"; break; case FCS_METH_FMM: method = "fmm"; break; case FCS_METH_P3M: method = "p3m"; srf = fcs_near_field_flag; break; case FCS_METH_P2NFFT: method = "p2nfft"; srf = fcs_near_field_flag; break; case FCS_METH_VMG: method = "vmg"; break; case FCS_METH_PP3MG: method = "pp3mg"; break; } /* initialize handle and set common parameters */ res = fcs_init(&handle, method, cpugrid); ASSERT_FCS(res); res = fcs_set_common(handle, srf, BoxX, BoxY, BoxZ, off, pbc, natoms); ASSERT_FCS(res); res = fcs_require_virial(handle, 1); ASSERT_FCS(res); /* set method specific parameters */ switch (fcs_method) { #ifdef FCS_ENABLE_DIRECT case FCS_METH_DIRECT: /* nothing to do */ break; #endif #ifdef FCS_ENABLE_PEPC case FCS_METH_PEPC: res = fcs_pepc_setup(handle, (fcs_float)fcs_pepc_eps, (fcs_float)fcs_pepc_theta ); ASSERT_FCS(res); res = fcs_pepc_set_num_walk_threads( handle, (fcs_int)fcs_pepc_nthreads ); ASSERT_FCS(res); break; #endif #ifdef FCS_ENABLE_FMM case FCS_METH_FMM: res = fcs_fmm_set_absrel(handle, (fcs_int)fcs_fmm_absrel); ASSERT_FCS(res); res = fcs_fmm_set_tolerance_energy(handle, (fcs_float)fcs_tolerance); ASSERT_FCS(res); break; #endif #ifdef FCS_ENABLE_P3M case FCS_METH_P3M: if (0==srf) { res = fcs_p3m_set_r_cut(handle, (fcs_float)fcs_rcut); ASSERT_FCS(res); } res = fcs_set_tolerance(handle, FCS_TOLERANCE_TYPE_FIELD, (fcs_float)fcs_tolerance); ASSERT_FCS(res); if (fcs_grid_dim.x) res = fcs_p3m_set_grid(handle, (fcs_int)fcs_grid_dim.x); ASSERT_FCS(res); break; #endif #ifdef FCS_ENABLE_P2NFFT case FCS_METH_P2NFFT: if (0==srf) { res = fcs_p2nfft_set_r_cut(handle, (fcs_float)fcs_rcut); ASSERT_FCS(res); } res = fcs_set_tolerance(handle, FCS_TOLERANCE_TYPE_FIELD, (fcs_float)fcs_tolerance); ASSERT_FCS(res); if (fcs_grid_dim.x) { res = fcs_p2nfft_set_grid(handle, (fcs_int)fcs_grid_dim.x, (fcs_int)fcs_grid_dim.y, (fcs_int)fcs_grid_dim.z); ASSERT_FCS(res); } if (fcs_p2nfft_intpol_order) { res = fcs_p2nfft_set_pnfft_interpolation_order(handle, (fcs_int)fcs_p2nfft_intpol_order); ASSERT_FCS(res); } if (fcs_p2nfft_epsI) { res = fcs_p2nfft_set_epsI(handle, (fcs_float)fcs_p2nfft_epsI); ASSERT_FCS(res); } //res = fcs_p2nfft_set_pnfft_window_by_name(handle, "bspline"); //ASSERT_FCS(res); break; #endif #ifdef FCS_ENABLE_VMG case FCS_METH_VMG: if (fcs_vmg_near_field_cells) { res = fcs_vmg_set_near_field_cells(handle, (fcs_int)fcs_vmg_near_field_cells); ASSERT_FCS(res); } if (fcs_vmg_interpol_order) { res = fcs_vmg_set_interpolation_order(handle, (fcs_int)fcs_vmg_interpol_order); ASSERT_FCS(res); } if (fcs_vmg_discr_order) { res = fcs_vmg_set_discretization_order(handle, (fcs_int)fcs_vmg_discr_order); ASSERT_FCS(res); } if (fcs_iter_tolerance > 0) { res = fcs_vmg_set_precision(handle, (fcs_float)fcs_iter_tolerance); ASSERT_FCS(res); } break; #endif #ifdef FCS_ENABLE_PP3MG case FCS_METH_PP3MG: /* use default values, if not specified otherwise */ if (fcs_grid_dim.x) { res = fcs_pp3mg_set_cells_x(handle, (fcs_int)fcs_grid_dim.x); ASSERT_FCS(res); res = fcs_pp3mg_set_cells_y(handle, (fcs_int)fcs_grid_dim.y); ASSERT_FCS(res); res = fcs_pp3mg_set_cells_z(handle, (fcs_int)fcs_grid_dim.z); ASSERT_FCS(res); } if (fcs_pp3mg_ghosts) { res = fcs_pp3mg_set_ghosts(handle, (fcs_int)fcs_pp3mg_ghosts); ASSERT_FCS(res); } if (fcs_pp3mg_degree) { res = fcs_pp3mg_set_degree(handle, (fcs_int)fcs_pp3mg_degree); ASSERT_FCS(res); } if (fcs_pp3mg_max_part) { res = fcs_pp3mg_set_max_particles(handle, (fcs_int)fcs_pp3mg_max_part); ASSERT_FCS(res); } if (fcs_max_iter) { res = fcs_pp3mg_set_max_iterations(handle,(fcs_int)fcs_max_iter); ASSERT_FCS(res); } if (fcs_iter_tolerance > 0) { res = fcs_pp3mg_set_tol(handle, (fcs_float)fcs_iter_tolerance); ASSERT_FCS(res); } break; #endif default: error("FCS method unknown or not implemented"); break; } pack_fcs(); res = fcs_tune(handle, nloc, nloc_max, pos, chg); ASSERT_FCS(res); /* inform about tuned parameters */ switch (fcs_method) { fcs_int grid_dim[3]; fcs_float r_cut; #ifdef FCS_ENABLE_P3M case FCS_METH_P3M: res = fcs_p3m_get_r_cut(handle, &r_cut); ASSERT_FCS(res); res = fcs_p3m_get_grid(handle, grid_dim); ASSERT_FCS(res); if (0==myid) printf("FCS: Tuned grid dimensions, cutoff: %d %d %d, %f\n", grid_dim[0], grid_dim[1], grid_dim[2], r_cut); break; #endif #ifdef FCS_ENABLE_P2NFFT case FCS_METH_P2NFFT: res = fcs_p2nfft_get_grid(handle, grid_dim, grid_dim+1, grid_dim+2); ASSERT_FCS(res); res = fcs_p2nfft_get_r_cut(handle, &r_cut); ASSERT_FCS(res); if (0==myid) printf("FCS: Tuned grid dimensions, cutoff: %d %d %d, %f\n", grid_dim[0], grid_dim[1], grid_dim[2], r_cut); break; #endif #ifdef FCS_ENABLE_PP3MG case FCS_METH_PP3MG: res = fcs_pp3mg_get_cells_x(handle, grid_dim ); ASSERT_FCS(res); res = fcs_pp3mg_get_cells_y(handle, grid_dim+1); ASSERT_FCS(res); res = fcs_pp3mg_get_cells_z(handle, grid_dim+2); if (0==myid) printf("FCS: Tuned grid dimensions: %d %d %d\n", grid_dim[0], grid_dim[1], grid_dim[2]); ASSERT_FCS(res); break; #endif default: break; } /* add near-field potential, after fcs_tune */ if (0==srf) fcs_update_pottab(); }
/** * @brief function to set default values if no values are set * @param handle the FCS-obect into which the default parameters will be entered * @return FCSResult-object containing the return state */ extern FCSResult fcs_vmg_set_default(FCS handle) { MPI_Comm comm; int rank; const char fnc_name[] = "fcs_vmg_set_default"; comm = fcs_get_communicator(handle); MPI_Comm_rank(comm, &rank); if (handle == NULL) return fcsResult_create(FCS_NULL_ARGUMENT, fnc_name, "null pointer supplied as handle"); if (fcs_get_method(handle) != FCS_VMG) return fcsResult_create(FCS_WRONG_ARGUMENT, fnc_name, "Wrong method chosen. You should choose \"vmg\"."); fcs_int max_level; fcs_vmg_get_max_level(handle, &max_level); if (max_level < 0) { max_level = 6; #ifdef FCS_ENABLE_DEBUG if (rank == 0) printf("%s: Parameter %s not set. Set default to %d.\n", fnc_name, "max_level", max_level); #endif fcs_vmg_set_max_level(handle, max_level); } fcs_int max_iter; fcs_vmg_get_max_iterations(handle, &max_iter); if (max_iter < 0) { max_iter = 15; #ifdef FCS_ENABLE_DEBUG if (rank == 0) printf("%s: Parameter %s not set. Set default to %d.\n", fnc_name, "max_iterations", max_iter); #endif fcs_vmg_set_max_iterations(handle, max_iter); } fcs_int smoothing_steps; fcs_vmg_get_smoothing_steps(handle, &smoothing_steps); if (smoothing_steps < 0) { smoothing_steps = 3; #ifdef FCS_ENABLE_DEBUG if (rank == 0) printf("%s: Parameter %s not set. Set default to %d.\n", fnc_name, "smoothing_steps", smoothing_steps); #endif fcs_vmg_set_smoothing_steps(handle, smoothing_steps); } fcs_int cycle_type; fcs_vmg_get_cycle_type(handle, &cycle_type); if (cycle_type < 0) { cycle_type = 1; #ifdef FCS_ENABLE_DEBUG if (rank == 0) printf("%s: Parameter %s not set. Set default to %d.\n", fnc_name, "cycle_type", cycle_type); #endif fcs_vmg_set_cycle_type(handle, cycle_type); } fcs_float precision; fcs_vmg_get_precision(handle, &precision); if (precision < 0.0) { precision = 1.0e-8; #ifdef FCS_ENABLE_DEBUG if (rank == 0) printf("%s: Parameter %s not set. Set default to %e.\n", fnc_name, "precision", precision); #endif fcs_vmg_set_precision(handle, precision); } fcs_int near_field_cells; fcs_vmg_get_near_field_cells(handle, &near_field_cells); if (near_field_cells < 0) { near_field_cells = 4; #ifdef FCS_ENABLE_DEBUG if (rank == 0) printf("%s: Parameter %s not set. Set default to %d.\n", fnc_name, "near_field_cells", near_field_cells); #endif fcs_vmg_set_near_field_cells(handle, near_field_cells); } fcs_int interpolation_order; fcs_vmg_get_interpolation_order(handle, &interpolation_order); if (interpolation_order < 0) { interpolation_order = 5; #ifdef FCS_ENABLE_DEBUG if (rank == 0) printf("%s: Parameter %s not set. Set default to %d.\n", fnc_name, "interpolation_order", interpolation_order); #endif fcs_vmg_set_interpolation_order(handle, interpolation_order); } fcs_int discretization_order; fcs_vmg_get_discretization_order(handle, &discretization_order); if (discretization_order < 0) { discretization_order = 4; #ifdef FCS_ENABLE_DEBUG if (rank == 0) printf("%s: Parameter %s not set. Set default to %d.\n", fnc_name, "discretization_order", discretization_order); #endif fcs_vmg_set_discretization_order(handle, discretization_order); } return NULL; }