예제 #1
0
/* initialization function for basic pepc parameters */
FCSResult fcs_pepc_init(FCS handle)
{
  handle->shift_positions = 1;

  handle->destroy = fcs_pepc_destroy;
  handle->set_parameter = fcs_pepc_set_parameter;
  handle->print_parameters = fcs_pepc_print_parameters;
  handle->tune = fcs_pepc_tune;
  handle->run = fcs_pepc_run;
  handle->set_compute_virial = fcs_pepc_require_virial;
  handle->get_virial = fcs_pepc_get_virial;

  handle->pepc_param = malloc(sizeof(*handle->pepc_param));
  handle->pepc_param->theta             = 0.6;
  handle->pepc_param->epsilon           = 0.0;
  handle->pepc_param->require_virial    = 0;
  handle->pepc_param->num_walk_threads  = 3;
  handle->pepc_param->load_balancing    = 0;
  handle->pepc_param->dipole_correction = 1;
  handle->pepc_param->npm               = -45.0;
  handle->pepc_param->debug_level       = 0;

  fcs_pepc_internal_t *pepc_internal;
  MPI_Comm comm  = fcs_get_communicator(handle);
  MPI_Fint fcomm = MPI_Comm_c2f(comm);

  pepc_scafacos_initialize(&fcomm);

  handle->method_context = malloc(sizeof(fcs_pepc_internal_t));
  pepc_internal = (fcs_pepc_internal_t*) handle->method_context;
  pepc_internal->work_length = -1;
  pepc_internal->work        = NULL;

  return FCS_RESULT_SUCCESS;
}
예제 #2
0
/**
 * @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);
}
예제 #3
0
/**
 * sort additional byte particle data
 */
FCSResult fcs_resort_bytes(FCS handle, void *src, void *dst, fcs_int n)
{
  CHECK_HANDLE_RETURN_RESULT(handle, __func__);

  if (handle->resort_bytes == NULL)
    return fcs_result_create(FCS_ERROR_INCOMPATIBLE_METHOD, __func__, "resorting not supported");

  return handle->resort_bytes(handle, src, dst, n, fcs_get_communicator(handle));
}
예제 #4
0
/**
 * sort additional float particle data
 */
FCSResult fcs_resort_floats(FCS handle, fcs_float *src, fcs_float *dst, fcs_int n)
{
  const char* fnc_name = "fcs_resort_floats";

  CHECK_HANDLE_RETURN_RESULT(handle, fnc_name);

  if (handle->resort_floats == NULL)
    return fcs_result_create(FCS_ERROR_INCOMPATIBLE_METHOD, fnc_name, "resorting not supported");

  return handle->resort_floats(handle, src, dst, n, fcs_get_communicator(handle));
}
예제 #5
0
/* clean-up function for pepc */
FCSResult fcs_pepc_destroy(FCS handle)
{
  MPI_Comm comm  = fcs_get_communicator(handle);
  MPI_Fint fcomm = MPI_Comm_c2f(comm);
  pepc_scafacos_finalize(&fcomm);

  if(((fcs_pepc_internal_t*)fcs_get_method_context(handle))->work != NULL){
    free(((fcs_pepc_internal_t*)fcs_get_method_context(handle))->work);   
  }

  free(handle->method_context);

  free(handle->pepc_param);

  return FCS_RESULT_SUCCESS;
}
예제 #6
0
파일: fcs_fmm.c 프로젝트: scafacos/scafacos
/* internal fmm-specific run function */
FCSResult fcs_fmm_run(FCS handle, fcs_int local_particles,
                      fcs_float *positions, fcs_float *charges, 
                      fcs_float *field, fcs_float *potentials)
{
  FCSResult result;

  long long ll_tp;
  long long ll_lp;
  long long ll_absrel;
  long long ll_dip_corr;
  const fcs_int* periodicity;
  long long* ll_periodicity;
  int i;
  fcs_float tolerance_energy;
  fcs_float period_length;
  void* params;
  fcs_int dotune;
  long long r;
  const fcs_float* box_vector;
  void* loadptr = NULL;

  FMM_CHECK_RETURN_RESULT(handle, __func__);

  result = fcs_fmm_check(handle, local_particles);
  CHECK_RESULT_RETURN(result);

  ll_periodicity = (long long*)malloc(3*sizeof(long long));

  ll_tp = (long long)fcs_get_total_particles(handle);
  ll_lp = (long long)local_particles;

  fcs_int absrel;
  fcs_fmm_get_absrel(handle, &absrel);
  ll_absrel = absrel;

  fcs_fmm_get_tolerance_energy(handle, &tolerance_energy);

  fcs_int dip_corr;
  fcs_fmm_get_dipole_correction(handle, &dip_corr);

  ll_dip_corr = dip_corr;

  periodicity = fcs_get_periodicity(handle);
  for (i = 0; i < 3; i++)
    ll_periodicity[i] = (long long)periodicity[i];
  params = fcs_get_method_context(handle);
  box_vector = fcs_get_box_a(handle);
  period_length = fcs_norm(box_vector);

  fcs_fmm_get_internal_tuning( handle, &dotune );
  if (dotune != FCS_FMM_INHOMOGENOUS_SYSTEM && dotune != FCS_FMM_HOMOGENOUS_SYSTEM)
  {
    result = fcs_result_create(FCS_ERROR_WRONG_ARGUMENT, __func__, "wrong kind of internal tuning chosen");
    return result;
  }

  long long ll_unroll_limit = handle->fmm_param->limit;
  long long ll_maxdepth = handle->fmm_param->maxdepth;
  long long ll_balance_load = handle->fmm_param->balance;
  long long define_loadvector = handle->fmm_param->define_loadvector;
 
  if (define_loadvector == 1)
  {
    handle->fmm_param->define_loadvector = 0;
    long long ll_loadvectorsize = ll_loadvectorsize = 229074;/*local_particles*4;*/
    fcs_float val = 1e0;
    loadptr = malloc(sizeof(ll_loadvectorsize)*ll_loadvectorsize);
    fmm_cinitload(params,loadptr,ll_loadvectorsize);
    fmm_csetload(params,val);
  }

  int old_fcs_mpi_fmm_sort_front_part = fcs_mpi_fmm_sort_front_part;

  int comm_size;
  MPI_Comm_size(fcs_get_communicator(handle), &comm_size);
  fcs_float max_merge_move = fcs_pow(fcs_norm(fcs_get_box_a(handle)) * fcs_norm(fcs_get_box_b(handle)) * fcs_norm(fcs_get_box_c(handle)) / comm_size, 1.0 / 3.0);

  fcs_float max_particle_move;
  MPI_Allreduce(&handle->fmm_param->max_particle_move, &max_particle_move, 1, FCS_MPI_FLOAT, MPI_MAX, fcs_get_communicator(handle));

  if (max_particle_move >= 0 && max_particle_move < max_merge_move)
  {
/*    fmm_csetpresorted(params, 1);*/
    fcs_mpi_fmm_sort_front_part = 0;
    fcs_mpi_fmm_sort_front_merge_presorted = 1;

  } else
  {
/*    fmm_csetpresorted(params, 0);*/
    fcs_mpi_fmm_sort_front_merge_presorted = 0;
  }

  fcs_fmm_resort_destroy(&handle->fmm_param->fmm_resort);
  if (handle->fmm_param->resort) fcs_fmm_resort_create(&handle->fmm_param->fmm_resort, local_particles, fcs_get_communicator(handle));
  fmm_cinitresort(params, handle->fmm_param->fmm_resort);
  fmm_csetresort(params, (long long) handle->fmm_param->resort);

  fmm_crun(ll_lp,positions,charges,potentials,field,handle->fmm_param->virial,ll_tp,ll_absrel,tolerance_energy,
    ll_dip_corr, ll_periodicity, period_length, dotune, ll_maxdepth,ll_unroll_limit,ll_balance_load,params, &r);

  fcs_mpi_fmm_sort_front_part = old_fcs_mpi_fmm_sort_front_part;

  free(ll_periodicity);
  if (loadptr) free(loadptr);

  if (r == 0)
  {
    result = fcs_result_create(FCS_ERROR_FORTRAN_CALL, __func__, "error in fmm_run (FORTRAN)");
    return result;
  }

  return FCS_RESULT_SUCCESS;
}
예제 #7
0
파일: fcs_fmm.c 프로젝트: scafacos/scafacos
/* method to check if fmm parameters are consistent with requirements */
FCSResult fcs_fmm_check(FCS handle, fcs_int local_particles)
{
  const fcs_float *a,*b,*c;
  fcs_float norm[3],period_length;
  const fcs_int *periodicity;
  MPI_Comm comm;
  fcs_int total_particles;
  int comm_size;
  int i,p,ok;

  fcs_int absrel;
  fcs_fmm_get_absrel(handle, &absrel);
  if (absrel == -1)
    return fcs_result_create(FCS_ERROR_MISSING_ELEMENT, __func__, "fmm: absrel not set");

  fcs_float tolerance_energy;
  fcs_fmm_get_tolerance_energy(handle, &tolerance_energy);
  if (tolerance_energy == -1.0)
    return fcs_result_create(FCS_ERROR_MISSING_ELEMENT, __func__, "fmm: energy tolerance not set");

  comm = fcs_get_communicator(handle);
  MPI_Comm_size(comm, &comm_size);
  total_particles = fcs_get_total_particles(handle);
  if (total_particles < comm_size)
    return fcs_result_create(FCS_ERROR_INCOMPATIBLE_METHOD, __func__, "fmm: there have to be at least as much particles as processes");
  
  if (local_particles <= 0)
    return fcs_result_create(FCS_ERROR_INCOMPATIBLE_METHOD, __func__, "fmm: each process has to receive at least one particle");
  
  a = fcs_get_box_a(handle); 
  norm[0] = fcs_norm(a);
  b = fcs_get_box_b(handle);
  norm[1] = fcs_norm(b);
  c = fcs_get_box_c(handle);
  norm[2] = fcs_norm(c);
  periodicity = fcs_get_periodicity(handle);

  p = 0; ok = 1;
  for (i = 0; i < 3; ++i)
    if (periodicity[i]) 
    {
      if (0==p) 
        period_length = norm[i];
      else 
        ok = ok && fcs_float_is_equal( period_length, norm[i] );
      p++;
    }

  if (p && !(fcs_uses_principal_axes(a,b,c))) 
    return fcs_result_create(FCS_ERROR_INCOMPATIBLE_METHOD, __func__, 
      "fmm: with periodic boundaries, box must be arranged along principle axes");

  if (p && !ok)
    return fcs_result_create(FCS_ERROR_INCOMPATIBLE_METHOD, __func__, 
      "fmm: all periodic directions must have equal length");

  if (p && (p<3)) 
  {
    ok = 1;
    for (i = 0; i < 3; ++i)
      if (!periodicity[i]) 
        ok = ok && (norm[i] <= period_length);
    if (!ok)
      return fcs_result_create(FCS_ERROR_INCOMPATIBLE_METHOD, __func__, 
        "fmm: axes in non-periodic directions must not be longer than periodic ones");
  }

  return FCS_RESULT_SUCCESS;
}
예제 #8
0
파일: fcs_vmg.c 프로젝트: bsteinb/scafacos
FCSResult fcs_vmg_tune(FCS handle, fcs_int local_particles, fcs_int local_max_particles,
		       fcs_float* positions, fcs_float* charges)
{
  FCSResult result;
  /*
   * Set default parameters if no parameters were specified
   */
  result = fcs_vmg_set_default(handle);
  if (result)
    return result;

  /*
   * Check parameters
   */
  result = fcs_vmg_check(handle);
  if (result)
    return result;

  /*
   * Setup vmg solver
   */
  fcs_int level;
  fcs_int max_iter;
  fcs_int smoothing_steps;
  fcs_int cycle_type;
  fcs_float precision;
  fcs_int near_field_cells;
  fcs_int interpolation_order;
  fcs_int discretization_order;

  result = fcs_vmg_get_max_level(handle, &level);
  if (result)
    return result;

  fcs_int* periodic = fcs_get_periodicity(handle);

  result  = fcs_vmg_get_max_iterations(handle, &max_iter);
  if (result)
    return result;

  result  = fcs_vmg_get_smoothing_steps(handle, &smoothing_steps);
  if (result)
    return result;

  result  = fcs_vmg_get_cycle_type(handle, &cycle_type);
  if (result)
    return result;

  result  = fcs_vmg_get_precision(handle, &precision);
  if (result)
    return result;

  fcs_float *offset = fcs_get_offset(handle);
  fcs_float* box_a = fcs_get_box_a(handle);

  result  = fcs_vmg_get_near_field_cells(handle, &near_field_cells);
  if (result)
    return result;

  result  = fcs_vmg_get_interpolation_order(handle, &interpolation_order);
  if (result)
    return result;

  result  = fcs_vmg_get_discretization_order(handle, &discretization_order);
  if (result)
    return result;

  MPI_Comm comm = fcs_get_communicator(handle);

  VMG_fcs_setup(level, periodic, max_iter, smoothing_steps,
		cycle_type, precision, offset, box_a[0],
		near_field_cells, interpolation_order,
		discretization_order, comm);

  result = fcs_vmg_library_check(handle);
  if (result)
    return result;

  return NULL;
}
예제 #9
0
파일: fcs_vmg.c 프로젝트: bsteinb/scafacos
/**
 * @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;
}