/** * @brief function to check whether all initial parameters are set * @param handle FCS-object representing an FCS solver * @return whether all initial parameters are set */ static fcs_int fcs_init_check(FCS handle) { if (handle == FCS_NULL) return 0; return (fcs_get_method(handle) != FCS_METHOD_NONE && fcs_get_communicator(handle) != MPI_COMM_NULL); }
/* method to check if p3m parameters are entered into FCS */ static FCSResult fcs_p3m_check(FCS handle, const char* fnc_name) { if (handle == NULL) return fcs_result_create(FCS_ERROR_NULL_ARGUMENT, fnc_name, "null pointer supplied as handle"); if (fcs_get_method(handle) != FCS_METHOD_P3M) return fcs_result_create(FCS_ERROR_WRONG_ARGUMENT, fnc_name, "Wrong method chosen. You should choose \"p3m\"."); return NULL; }
/* method to check if mmm1d parameters are entered into FCS */ FCSResult fcs_mmm1d_check(FCS handle, const char* fnc_name) { if (handle == NULL) return fcsResult_create(FCS_NULL_ARGUMENT, fnc_name, "null pointer supplied as handle"); if (fcs_get_method(handle) != FCS_MMM1D) return fcsResult_create(FCS_WRONG_ARGUMENT, fnc_name, "Wrong method chosen. You should choose \"mmm1d\"."); return NULL; }
/** * @brief Get the discretization order. * This will affect the discretization error heavily, but a * higher value also implies more computation. Possible values * are 2 or 4. * * @param handle FCS-object that contains the parameter. * @param discretization_order Discretization order. * * @return FCSResult-object containing the return value. */ extern FCSResult fcs_vmg_get_discretization_order(FCS handle, fcs_int* discretization_order) { char fnc_name[] = "fcs_vmg_get_discretization_order"; 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\"."); *discretization_order = handle->vmg_param->discretization_order; return NULL; }
/** * @brief Get the number of near field cells for separating the * near/far field part of the potential. * * @param handle FCS-object that contains the parameter. * @param near_field_cells Number of near field cells. * * @return FCSResult-object containing the return value. */ extern FCSResult fcs_vmg_get_near_field_cells(FCS handle, fcs_int* near_field_cells) { char fnc_name[] = "fcs_vmg_get_near_field_cells"; 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\"."); *near_field_cells = handle->vmg_param->near_field_cells; return NULL; }
/** * @brief Get the cycle_type-number of the multigrid cycle used. E.g. 1 corresponds * to a V-Cycle and 2 corresponds to a W-Cycle. * * @param handle FCS-object that contains the parameter. * @param cycle_type type of multigrid cycle. * * @return FCSResult-object containing the return value. */ extern FCSResult fcs_vmg_get_cycle_type(FCS handle, fcs_int* cycle_type) { char fnc_name[] = "fcs_vmg_get_cycle_type"; 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\"."); *cycle_type = handle->vmg_param->cycle_type; return NULL; }
/** * @brief Get the precision of the vmg algorithm. Currently, the relative residual * computed in the discrete L2 norm will be tested against this value. * * @param handle FCS-object that contains the parameter. * @param precision Precision of the vmg algorithm. * * @return FCSResult-object containing the return value. */ extern FCSResult fcs_vmg_get_precision(FCS handle, fcs_float* precision) { char fnc_name[] = "fcs_vmg_get_precision"; 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\"."); *precision = handle->vmg_param->precision; return NULL; }
/** * @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; }
/** * @brief Set the interpolation order for interpolating * the gridded potential to the particle positions. * * @param handle FCS-object that contains the parameter. * @param interpolation order Interpolation order. * * @return FCSResult-object containing the return value. */ extern FCSResult fcs_vmg_set_interpolation_order(FCS handle, fcs_int interpolation_order) { char fnc_name[] = "fcs_vmg_set_interpolation_order"; 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\"."); if (interpolation_order < 3) return fcsResult_create(FCS_WRONG_ARGUMENT, fnc_name, "Interpolation order must be greater or equal three."); handle->vmg_param->interpolation_order = interpolation_order; return NULL; }
/** * @brief Set the number of pre/postsmoothing steps on each level * * @param handle FCS-object that contains the parameter * @param smoothing_steps Number of smoothing steps * * @return FCSResult-object containing the return state */ extern FCSResult fcs_vmg_set_smoothing_steps(FCS handle, fcs_int smoothing_steps) { char fnc_name[] = "fcs_vmg_set_smoothing_steps"; 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\"."); if (smoothing_steps < 1) return fcsResult_create(FCS_WRONG_ARGUMENT, fnc_name, "The number of smoothing steps must be at least one."); handle->vmg_param->smoothing_steps = smoothing_steps; return NULL; }
/** * @brief Set the maximum number of multigrid iterations. * * @param handle FCS-object that contains the parameter * @param max_iterations Number of iterations. * * @return FCSResult-object containing the return state. */ extern FCSResult fcs_vmg_set_max_iterations(FCS handle, fcs_int max_iterations) { char fnc_name[] = "fcs_vmg_set_max_iterations"; 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\"."); if (max_iterations < 1) return fcsResult_create(FCS_WRONG_ARGUMENT, fnc_name, "The maximum number of iterations must be positive."); handle->vmg_param->max_iterations = max_iterations; return NULL; }
/** * @brief Set the maximum level of the multigrid algorithm. * This sets the number of grid points to 2^max_level, so basically this * parameter ensures that the number of grid points will be a power of two. * * @param handle FCS-object that contains the parameter * @param max_level number of iterations * * @return FCSResult-object containing the return state */ extern FCSResult fcs_vmg_set_max_level(FCS handle, fcs_int max_level) { char fnc_name[] = "fcs_vmg_set_max_level"; 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\"."); if (max_level < 3) return fcsResult_create(FCS_WRONG_ARGUMENT, fnc_name, "The finest level must be at least 3."); handle->vmg_param->max_level = max_level; return NULL; }
/** * return whether the solver method supports the delegation of near-field computations */ FCSResult fcs_get_near_field_delegation(FCS handle, fcs_int *near_field_delegation) { CHECK_HANDLE_RETURN_RESULT(handle, __func__); *near_field_delegation = 0; switch (fcs_get_method(handle)) { #ifdef FCS_ENABLE_P2NFFT case FCS_METHOD_P2NFFT: *near_field_delegation = 1; break; #endif #ifdef FCS_ENABLE_P3M case FCS_METHOD_P3M: *near_field_delegation = 1; break; #endif } return FCS_RESULT_SUCCESS; }
/** * compute the near-field component of the field */ FCSResult fcs_compute_near_field(FCS handle, fcs_float dist, fcs_float *field) { switch (fcs_get_method(handle)) { #ifdef FCS_ENABLE_P2NFFT case FCS_METHOD_P2NFFT: *field = fcs_p2nfft_compute_near_field(handle, dist); return FCS_RESULT_SUCCESS; #endif #ifdef FCS_ENABLE_P3M case FCS_METHOD_P3M: { fcs_p3m_near_parameters_t params; fcs_p3m_get_near_parameters(handle, ¶ms); *field = fcs_p3m_compute_near_field(params, dist); } return FCS_RESULT_SUCCESS; #endif } return fcs_result_create(FCS_ERROR_NOT_IMPLEMENTED, __func__, "Computing the near-field component of the field not implemented for solver method '%s'", fcs_get_method_name(handle)); }
/** * compute the near-field component of the potential */ FCSResult fcs_compute_near_potential(FCS handle, fcs_float dist, fcs_float *potential) { const char *fnc_name = "fcs_compute_near_potential"; switch (fcs_get_method(handle)) { #ifdef FCS_ENABLE_P2NFFT case FCS_METHOD_P2NFFT: *potential = fcs_p2nfft_compute_near_potential(handle, dist); return FCS_RESULT_SUCCESS; #endif #ifdef FCS_ENABLE_P3M case FCS_METHOD_P3M: { fcs_p3m_near_parameters_t params; fcs_p3m_get_near_parameters(handle, ¶ms); *potential = fcs_p3m_compute_near_potential(params, dist); } return FCS_RESULT_SUCCESS; #endif } return fcs_result_create(FCS_ERROR_NOT_IMPLEMENTED, fnc_name, "Computing the near-field component of the potential not implemented for solver method '%s'", fcs_get_method_name(handle)); }
/** * @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; }