Пример #1
0
/**
 * run the solver method
 */
FCSResult fcs_run(FCS handle, fcs_int local_particles,
  fcs_float *positions, fcs_float *charges, fcs_float *field, fcs_float *potentials)
{
  const char *fnc_name = "fcs_run";
  FCSResult result;

  CHECK_HANDLE_RETURN_RESULT(handle, fnc_name);

  if (local_particles < 0)
    return fcs_result_create(FCS_ERROR_WRONG_ARGUMENT, fnc_name, "number of local particles must be non negative");

  if (fcs_get_values_changed(handle))
  {
    result = fcs_tune(handle, local_particles, positions, charges);
    if (result != FCS_RESULT_SUCCESS) return result;
  }

  if (!fcs_init_check(handle) || !fcs_run_check(handle))
    return fcs_result_create(FCS_ERROR_MISSING_ELEMENT, fnc_name, "not all needed data has been inserted into the given handle");

  if (handle->run == NULL)
    return fcs_result_create(FCS_ERROR_NOT_IMPLEMENTED, fnc_name, "Running solver method '%s' not implemented", fcs_get_method_name(handle));

  return handle->run(handle, local_particles, positions, charges, field, potentials);
}
Пример #2
0
/* method to check if pepc parameters are entered into checked FCS */
FCSResult fcs_pepc_check(FCS handle)
{
  const fcs_float *a,*b,*c;
  fcs_float eps, theta;
  FCSResult res;

  if ((res = fcs_pepc_get_epsilon(handle, &eps))) return res;
  if (eps == -1.0)
    return fcs_result_create(FCS_ERROR_MISSING_ELEMENT, __func__, "pepc: epsilon not set");
  if ((res = fcs_pepc_get_theta(handle, &theta))) return res;
  if (theta == -1.0)
    return fcs_result_create(FCS_ERROR_MISSING_ELEMENT, __func__, "pepc: theta not set");

  a = fcs_get_box_a(handle);
  b = fcs_get_box_b(handle);
  c = fcs_get_box_c(handle);
  if (!fcs_uses_principal_axes(a,b,c))
    printf("%s\n", "WARNING: support of pepc for non-cubic simulation boxes currently is experimental.");

  if (!fcs_get_near_field_flag(handle))
    return fcs_result_create(FCS_ERROR_INCOMPATIBLE_METHOD, __func__, 
			    "pepc performs near field computations by itself!");

  return FCS_RESULT_SUCCESS;
}
Пример #3
0
/* 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;
}
Пример #4
0
FCSResult mmm2d_tune(void* rd,
        fcs_int num_particles,
        fcs_float *positions,
        fcs_float *charges) {
  mmm2d_data_struct *d = (mmm2d_data_struct*)rd;
  const char* fnc_name = "mmm2d_tune";
  FCSResult res;
  
  /* Check for charge existence and neutrality */
  mmm2d_check_system_charges(d, num_particles, charges);
  if (!fcs_float_is_zero(d->total_charge))
    return fcs_result_create(FCS_ERROR_LOGICAL_ERROR, fnc_name, "MMM2D requires a zero net charge.");
  
  d->my_bottom = d->comm.rank*d->box_l[2]/(fcs_float)(d->comm.size);
  
  /* Broadcast charges */
  /*
  MPI_Bcast(&num_particles, 1, FCS_MPI_INT, 0, d->comm.mpicomm);
  MPI_Bcast(charges, num_particles, FCS_MPI_FLOAT, 0, d->comm.mpicomm);
  MPI_Bcast(positions, 3*num_particles, FCS_MPI_FLOAT, 0, d->comm.mpicomm);
  */
  
  ///@TODO: skip next steps if d->needs_tuning==0. Check if this is flawless
  if(d->needs_tuning==0)
    return NULL;
  
  /* precalculate some constants */
  mmm2d_setup_constants(d);
  
  /* tune near formula */
  res=mmm2d_tune_near(d);
  if (res) return res;
  
  /* tune far formula */
  if (d->comm.size*d->layers_per_node < 3) {
    d->far_cut = 0.0;
    if (d->dielectric_contrast_on)
      return fcs_result_create(FCS_ERROR_LOGICAL_ERROR, fnc_name, "Definition of dielectric contrasts requires more than 3 layers");
  } else {
      res=mmm2d_tune_far(d);
      if (res) return res;
  }
  
  d->needs_tuning=0;
  
  /*
  printf("node %d, mmm2d_tune\n", d->comm.rank);
  printf("node %d: ux: %f, uy: %f\n", d->comm.rank, d->ux, d->uy);
  printf("node %d: min_far: %f, far_cut: %f\n", d->comm.rank, d->min_far, d->far_cut);
  printf("node %d: layer_h %f\n", d->comm.rank, d->layer_h);
  printf("node %d: n_layers %d\n", d->comm.rank, d->n_layers);
  */
  
  return NULL;
}
Пример #5
0
/**
 * set whether the virial should be computed
 */
FCSResult fcs_set_compute_virial(FCS handle, fcs_int compute_virial)
{
  CHECK_HANDLE_RETURN_RESULT(handle, __func__);

  if (compute_virial != 0 && compute_virial != 1)
    return fcs_result_create(FCS_ERROR_WRONG_ARGUMENT, __func__, "parameter compute_virial must be 0 or 1");

  if (handle->set_compute_virial == NULL)
    return fcs_result_create(FCS_ERROR_NOT_IMPLEMENTED, __func__, "Setting whether the virial should be computed not implemented for solver method '%s'", fcs_get_method_name(handle));

  return handle->set_compute_virial(handle, compute_virial);
}
Пример #6
0
/**
 * return the comuputed virial
 */
FCSResult fcs_get_virial(FCS handle, fcs_float *virial)
{
  CHECK_HANDLE_RETURN_RESULT(handle, __func__);

  if (virial == NULL)
    return fcs_result_create(FCS_ERROR_NULL_ARGUMENT, __func__, "null pointer supplied as argument");

  if (handle->get_virial == NULL)
    return fcs_result_create(FCS_ERROR_NOT_IMPLEMENTED, __func__, "Returning the computed virial not implemented for solver method '%s'", fcs_get_method_name(handle));

  return handle->get_virial(handle, virial);
}
Пример #7
0
/**
 * return whether the virial should be computed
 */
FCSResult fcs_get_compute_virial(FCS handle, fcs_int *compute_virial)
{
  const char *fnc_name = "fcs_get_compute_virial";

  CHECK_HANDLE_RETURN_RESULT(handle, fnc_name);

  if (compute_virial == NULL)
    return fcs_result_create(FCS_ERROR_NULL_ARGUMENT, fnc_name, "null pointer supplied as argument");

  if (handle->get_compute_virial == NULL)
    return fcs_result_create(FCS_ERROR_NOT_IMPLEMENTED, fnc_name, "Returning whether the virial should be computed not implemented for solver method '%s'", fcs_get_method_name(handle));

  return handle->get_compute_virial(handle, compute_virial);
}
Пример #8
0
/* internal p3m-specific tuning function */
FCSResult fcs_p3m_tune(FCS handle, 
		       fcs_int local_particles,
		       fcs_float *positions, fcs_float *charges)
{
  char* fnc_name = "fcs_p3m_tune";
  FCSResult result;
  result = fcs_p3m_check(handle, fnc_name);
  if (result != NULL) return result;

  /* Handle periodicity */
  const fcs_int *periodicity = fcs_get_periodicity(handle);
  if (! (periodicity[0] && periodicity[1] && periodicity[2]))
    return fcs_result_create(FCS_ERROR_WRONG_ARGUMENT, fnc_name, 
      "p3m requires periodic boundary conditions.");
    
  /* Handle box size */
  const fcs_float *a = fcs_get_box_a(handle);
  const fcs_float *b = fcs_get_box_b(handle);
  const fcs_float *c = fcs_get_box_c(handle);
  if (!fcs_is_orthogonal(a, b, c)){
        if (ifcs_p3m_check_triclinic_box(a[1],a[2],b[2])){
            
            if(ifcs_p3m_set_triclinic_flag(handle->method_context)!=NULL)
           return ifcs_p3m_set_triclinic_flag(handle->method_context);           
        }
        else
            return fcs_result_create(FCS_ERROR_WRONG_ARGUMENT, fnc_name,
                "p3m triclinic requires the box to be as follows: \n \
                the first box vector is parallel to the x axis\n \
                the second box vector is in the yz plane.");
    } else {
        if (!fcs_uses_principal_axes(a, b, c))
Пример #9
0
/**
 * set the error tolerance of the FCS solver
 */
FCSResult fcs_set_tolerance(FCS handle, fcs_int tolerance_type, fcs_float tolerance)
{
  CHECK_HANDLE_RETURN_RESULT(handle, __func__);

  if (handle->set_tolerance == NULL)
    return fcs_result_create(FCS_ERROR_NOT_IMPLEMENTED, __func__, "Setting tolerance not implemented for solver method '%s'", fcs_get_method_name(handle));

  return handle->set_tolerance(handle, tolerance_type, tolerance);
}
Пример #10
0
FCSResult mmm2d_get_total_energy(void *rd, fcs_float *total_energy) {
  const char* fnc_name = "mmm2d_get_total_energy";
  mmm2d_data_struct *d = (mmm2d_data_struct*)rd;
  if (d->require_total_energy) {
    *total_energy = d->total_energy;
    return NULL;
  } else 
    return fcs_result_create(FCS_ERROR_LOGICAL_ERROR, fnc_name, "Trying to get total energy, but computation was not requested.");
}
Пример #11
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));
}
Пример #12
0
/**
 * set whether resort support is requested
 */
FCSResult fcs_set_resort(FCS handle, fcs_int resort)
{
  CHECK_HANDLE_RETURN_RESULT(handle, __func__);

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

  return handle->set_resort(handle, resort);
}
Пример #13
0
/**
 * return the new local number of particles
 */
FCSResult fcs_get_resort_particles(FCS handle, fcs_int *resort_particles)
{
  CHECK_HANDLE_RETURN_RESULT(handle, __func__);

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

  return handle->get_resort_particles(handle, resort_particles);
}
Пример #14
0
/**
 * return the user-defined cutoff radius for the near-field
 */
FCSResult fcs_get_r_cut(FCS handle, fcs_float *r_cut)
{
  CHECK_HANDLE_RETURN_RESULT(handle, __func__);

  if (handle->get_r_cut == NULL)
    return fcs_result_create(FCS_ERROR_NOT_IMPLEMENTED, __func__, "Returning a user-defined cutoff radius for the near-field not implemented for solver method '%s'", fcs_get_method_name(handle));

  return handle->get_r_cut(handle, r_cut);
}
Пример #15
0
/**
 * run the solver method
 */
FCSResult fcs_run(FCS handle, fcs_int local_particles,
  fcs_float *positions, fcs_float *charges, fcs_float *field, fcs_float *potentials)
{
  FCSResult result;

  CHECK_HANDLE_RETURN_RESULT(handle, __func__);

  if (local_particles < 0)
    return fcs_result_create(FCS_ERROR_WRONG_ARGUMENT, __func__, "number of local particles must be non negative");

  if (fcs_get_values_changed(handle))
  {
    result = fcs_tune(handle, local_particles, positions, charges);
    if (result != FCS_RESULT_SUCCESS) return result;
  }

  if (!fcs_init_check(handle) || !fcs_run_check(handle))
    return fcs_result_create(FCS_ERROR_MISSING_ELEMENT, __func__, "not all needed data has been inserted into the given handle");

  if (handle->run == NULL)
    return fcs_result_create(FCS_ERROR_NOT_IMPLEMENTED, __func__, "Running solver method '%s' not implemented", fcs_get_method_name(handle));

  fcs_float original_box_origin[3] = { handle->box_origin[0], handle->box_origin[1], handle->box_origin[2] };

  if (handle->shift_positions)
  {
    fcs_shift_positions(local_particles, positions, original_box_origin);
    handle->box_origin[0] = handle->box_origin[1] = handle->box_origin[2] = 0;
  }

  result = handle->run(handle, local_particles, positions, charges, field, potentials);

  if (handle->shift_positions)
  {
    fcs_unshift_positions(local_particles, positions, original_box_origin);
    handle->box_origin[0] = original_box_origin[0];
    handle->box_origin[1] = original_box_origin[1];
    handle->box_origin[2] = original_box_origin[2];
  }

  return result;
}
Пример #16
0
/**
 * disable a user-defined cutoff radius for the near-field
 */
FCSResult fcs_unset_r_cut(FCS handle)
{
  const char *fnc_name = "fcs_unset_r_cut";

  CHECK_HANDLE_RETURN_RESULT(handle, fnc_name);

  if (handle->unset_r_cut == NULL)
    return fcs_result_create(FCS_ERROR_NOT_IMPLEMENTED, fnc_name, "Disabling a user-defined cutoff radius for the near-field not implemented for solver method '%s'", fcs_get_method_name(handle));

  return handle->unset_r_cut(handle);
}
Пример #17
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));
}
Пример #18
0
/**
 * return the new local number of particles
 */
FCSResult fcs_get_resort_particles(FCS handle, fcs_int *resort_particles)
{
  const char *fnc_name = "fcs_get_resort_particles";

  CHECK_HANDLE_RETURN_RESULT(handle, fnc_name);

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

  return handle->get_resort_particles(handle, resort_particles);
}
Пример #19
0
/**
 * set whether resort support is requested
 */
FCSResult fcs_set_resort(FCS handle, fcs_int resort)
{
  const char *fnc_name = "fcs_set_resort";

  CHECK_HANDLE_RETURN_RESULT(handle, fnc_name);

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

  return handle->set_resort(handle, resort);
}
Пример #20
0
/* getter function for maximum fmm tree depth */
FCSResult fcs_fmm_get_maxdepth(FCS handle, fcs_int *depth)
{
  FMM_CHECK_RETURN_RESULT(handle, __func__);

  if (!depth)
    return fcs_result_create(FCS_ERROR_NULL_ARGUMENT,__func__,"null pointer supplied for depth");

  *depth = handle->fmm_param->maxdepth;

  return FCS_RESULT_SUCCESS;
}
Пример #21
0
/* getter function for status of fmm define loadvector */
FCSResult fcs_fmm_get_define_loadvector(FCS handle, fcs_int *define_loadvector)
{
  FMM_CHECK_RETURN_RESULT(handle, __func__);

  if (!define_loadvector)
    return fcs_result_create(FCS_ERROR_NULL_ARGUMENT,__func__,"null pointer supplied for define_loadvector");

  *define_loadvector = handle->fmm_param->define_loadvector;

  return FCS_RESULT_SUCCESS;
}
Пример #22
0
/* setter function for fmm parameter potential */
FCSResult fcs_fmm_set_potential(FCS handle, fcs_int potential)
{
  FMM_CHECK_RETURN_RESULT(handle, __func__);

  if (!(potential == FCS_FMM_COULOMB || potential == FCS_FMM_CUSP))
    return fcs_result_create(FCS_ERROR_WRONG_ARGUMENT,__func__,"invalid (fmm) potential chosen");

  handle->fmm_param->potential = potential;

  return FCS_RESULT_SUCCESS;
}
Пример #23
0
/* getter function for fmm parameter dipole correction */
FCSResult fcs_fmm_get_dipole_correction(FCS handle, fcs_int *dipole_correction)
{
  FMM_CHECK_RETURN_RESULT(handle, __func__);

  if (!dipole_correction)
    return fcs_result_create(FCS_ERROR_NULL_ARGUMENT,__func__,"null pointer supplied for dipole_correction");

  *dipole_correction = handle->fmm_param->dipole_correction;

  return FCS_RESULT_SUCCESS;
}
Пример #24
0
/* getter function for fmm unroll limit */
FCSResult fcs_fmm_get_unroll_limit(FCS handle, fcs_int *limit)
{
  FMM_CHECK_RETURN_RESULT(handle, __func__);

  if (!limit)
    return fcs_result_create(FCS_ERROR_NULL_ARGUMENT,__func__,"null pointer supplied for limit");

  *limit = handle->fmm_param->limit;

  return FCS_RESULT_SUCCESS;
}
Пример #25
0
/* setter function for status of fmm loadvector definition */
FCSResult fcs_fmm_set_define_loadvector(FCS handle, fcs_int define_loadvector)
{
  FMM_CHECK_RETURN_RESULT(handle, __func__);

  if (define_loadvector != 1)
    return fcs_result_create(FCS_ERROR_WRONG_ARGUMENT,__func__,"invalid (fmm) define_loadvector chosen (only value 1 is current supported)");

  handle->fmm_param->define_loadvector = define_loadvector;

  return FCS_RESULT_SUCCESS;
}
Пример #26
0
/* getter function for fmm parameter potential */
FCSResult fcs_fmm_get_potential(FCS handle, fcs_int *potential)
{
  FMM_CHECK_RETURN_RESULT(handle, __func__);

  if (!potential)
    return fcs_result_create(FCS_ERROR_NULL_ARGUMENT,__func__,"null pointer supplied for potential");

  *potential = handle->fmm_param->potential;

  return FCS_RESULT_SUCCESS;
}
Пример #27
0
/* setter function for fmm parameter cusp_radius */
FCSResult fcs_fmm_set_cusp_radius(FCS handle, fcs_float radius)
{
  FMM_CHECK_RETURN_RESULT(handle, __func__);

  if (radius < 0.0)
    return fcs_result_create(FCS_ERROR_WRONG_ARGUMENT,__func__,"cusp radius must be non-negative");

  handle->fmm_param->cusp_radius = radius;

  return FCS_RESULT_SUCCESS;
}
Пример #28
0
/* getter function for fmm parameter cusp radius */
FCSResult fcs_fmm_get_cusp_radius(FCS handle, fcs_float *cusp_radius)
{
  FMM_CHECK_RETURN_RESULT(handle, __func__);

  if (!cusp_radius)
    return fcs_result_create(FCS_ERROR_NULL_ARGUMENT,__func__,"null pointer supplied for cusp_radius");

  *cusp_radius = handle->fmm_param->cusp_radius;

  return FCS_RESULT_SUCCESS;
}
Пример #29
0
/**
 * return whether resort support is available
 */
FCSResult fcs_get_resort_availability(FCS handle, fcs_int *availability)
{
  CHECK_HANDLE_RETURN_RESULT(handle, __func__);

  *availability = 0;

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

  return handle->get_resort_availability(handle, availability);
}
Пример #30
0
/* getter function for status of fmm load balancing */
FCSResult fcs_fmm_get_balanceload(FCS handle, fcs_int *load)
{
  FMM_CHECK_RETURN_RESULT(handle, __func__);

  if (!load)
    return fcs_result_create(FCS_ERROR_NULL_ARGUMENT,__func__,"null pointer supplied for load");

  *load = handle->fmm_param->balance;

  return FCS_RESULT_SUCCESS;
}