示例#1
0
/**
 * print the parameters of an FCS solver to stdout
 */
FCSResult fcs_print_parameters(FCS handle)
{
  const char *fnc_name = "fcs_print_parameters";
  FCSResult result;

  CHECK_HANDLE_RETURN_RESULT(handle, fnc_name);

  printf("chosen method: %s\n", fcs_get_method_name(handle));

  printf("near field computations done by solver: %c\n", (fcs_get_near_field_flag(handle)?'T':'F'));
  printf("box vectors: [%10.4" FCS_LMOD_FLOAT "f %10.4" FCS_LMOD_FLOAT "f %10.4" FCS_LMOD_FLOAT "f], [%10.4" FCS_LMOD_FLOAT "f %10.4" FCS_LMOD_FLOAT "f %10.4" FCS_LMOD_FLOAT "f], [%10.4" FCS_LMOD_FLOAT "f %10.4" FCS_LMOD_FLOAT "f %10.4" FCS_LMOD_FLOAT "f]\n",
    fcs_get_box_a(handle)[0], fcs_get_box_a(handle)[1], fcs_get_box_a(handle)[2],
    fcs_get_box_b(handle)[0], fcs_get_box_b(handle)[1], fcs_get_box_b(handle)[2],
    fcs_get_box_c(handle)[0], fcs_get_box_c(handle)[1], fcs_get_box_c(handle)[2]);
  printf("box origin: [%10.4" FCS_LMOD_FLOAT "f %10.4" FCS_LMOD_FLOAT "f %10.4" FCS_LMOD_FLOAT "f]\n",
    fcs_get_box_origin(handle)[0], fcs_get_box_origin(handle)[1], fcs_get_box_origin(handle)[2]);
  printf("periodicity: %c %c %c\n", ((fcs_get_periodicity(handle)[0] == 1)?'T':'F'), ((fcs_get_periodicity(handle)[1] == 1)?'T':'F'),((fcs_get_periodicity(handle)[2] == 1)?'T':'F'));
  printf("total particles: %" FCS_LMOD_INT "d\n", fcs_get_total_particles(handle));
  printf("solver specific data:\n");

  if (handle->print_parameters)
  {
    result = handle->print_parameters(handle);
    if (result != FCS_RESULT_SUCCESS) fcs_result_print_result(result);
  }

  result = fcs_common_print_parameters(handle);
  if (result != FCS_RESULT_SUCCESS) fcs_result_print_result(result);

  return FCS_RESULT_SUCCESS;
}
示例#2
0
/* 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;
}
示例#3
0
/* 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;
}
示例#4
0
/* internal fmm-specific tuning function */
FCSResult fcs_fmm_tune(FCS handle, fcs_int local_particles, fcs_float *positions, fcs_float *charges)
{
  FCSResult result;

  fcs_int dotune;
  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;
  long long wignersize;
  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);

  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;

  fcs_fmm_get_internal_tuning( handle, &dotune );
  if (dotune == FCS_FMM_INHOMOGENOUS_SYSTEM)
  {
    if (define_loadvector == 1)
    {
      handle->fmm_param->define_loadvector = 0;
      long long ll_loadvectorsize = 4*local_particles;
      fcs_float val = 1e0;
      loadptr = malloc(sizeof(ll_loadvectorsize)*ll_loadvectorsize);
      fmm_cinitload(params,loadptr,ll_loadvectorsize);
      fmm_csetload(params,val);
    }

    fmm_ctune(ll_lp,positions,charges,ll_tp,ll_absrel,tolerance_energy,ll_dip_corr,
      ll_periodicity, period_length, ll_maxdepth, ll_unroll_limit, ll_balance_load,params, &wignersize, &r);

  } else if ( dotune == FCS_FMM_HOMOGENOUS_SYSTEM )
  {
    fmm_ctunehomogen(params,&wignersize, &r);

  } else
  {
    result = fcs_result_create(FCS_ERROR_WRONG_ARGUMENT, __func__, "wrong kind of internal tuning chosen");
    return result;
  }

  if (handle->fmm_param->wignerptr == NULL || handle->fmm_param->wignersize < wignersize)
  {
    if (handle->fmm_param->wignerptr) free(handle->fmm_param->wignerptr);

    handle->fmm_param->wignersize = wignersize;
    handle->fmm_param->wignerptr = malloc(wignersize);
  }

  fmm_ccomputewigner(handle->fmm_param->wignerptr,params,dotune);

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

  if (r == 0)
  {
    result = fcs_result_create(FCS_ERROR_FORTRAN_CALL, __func__, "error in fmm_ctune (FORTRAN)");
    return result;
  }
  
  return FCS_RESULT_SUCCESS;
}
示例#5
0
/* internal pepc-specific run function */
FCSResult fcs_pepc_run(FCS handle, fcs_int local_particles,
		       fcs_float *positions, fcs_float *charges, 
		       fcs_float *field, fcs_float *potentials)
{
  FCSResult result;
  fcs_int pcnt;
  fcs_int nparts_tot;
  fcs_pepc_internal_t *pepc_internal;

  nparts_tot = fcs_get_total_particles(handle);

  pepc_internal = (fcs_pepc_internal_t*) fcs_get_method_context(handle);
  
  if((local_particles != pepc_internal->work_length) || (handle->pepc_param->load_balancing==0)){
    
    if(pepc_internal->work != NULL){
      free(pepc_internal->work);
    }
    
    pepc_internal->work = (fcs_float*)malloc(sizeof(fcs_float)*local_particles);
    pepc_internal->work_length = local_particles;

    for(int pcnt=0; pcnt<pepc_internal->work_length; pcnt++)
      pepc_internal->work[pcnt] = 1.0;
  }
  
  result = fcs_pepc_check(handle);
  CHECK_RESULT_RETURN(result);

  fcs_int max_local_particles = fcs_get_max_local_particles(handle);
  if (local_particles > max_local_particles) max_local_particles = local_particles;

  if (handle->pepc_param->debug_level > 3) {
    printf("*** run pepc kernel\n");
    printf("** local particles:        %" FCS_LMOD_INT "d\n", local_particles);
    printf("** max local particles:    %" FCS_LMOD_INT "d\n", max_local_particles);
    printf("** total particles:        %" FCS_LMOD_INT "d\n", nparts_tot);
    printf("** epsilon:                %" FCS_LMOD_FLOAT "f\n", handle->pepc_param->epsilon);
    printf("** theta:                  %" FCS_LMOD_FLOAT "f\n", handle->pepc_param->theta);
    printf("** npm:                    %" FCS_LMOD_FLOAT "f\n", handle->pepc_param->npm);
    printf("** debug_level:            %" FCS_LMOD_INT "d\n", handle->pepc_param->debug_level);
    printf("** require virial:         %" FCS_LMOD_INT "d\n", handle->pepc_param->require_virial);
    printf("** num walk threads:       %" FCS_LMOD_INT "d\n", handle->pepc_param->num_walk_threads);
    printf("** dipole correction:      %" FCS_LMOD_INT "d\n", handle->pepc_param->dipole_correction);
    printf("** use load balancing:     %" FCS_LMOD_INT "d\n", handle->pepc_param->load_balancing);
    printf("** size int:               %d\n", (int)sizeof(fcs_int));
    printf("** size float:             %d\n", (int)sizeof(fcs_float));
    printf("** debug lattice pointers: %p\n", fcs_get_box_a(handle));
    printf("** debug lattice pointers: %p\n", fcs_get_box_b(handle));
    printf("** debug lattice pointers: %p\n", fcs_get_box_c(handle));

    printf("** debug output lattice in x %" FCS_LMOD_FLOAT "f %" FCS_LMOD_FLOAT "f %" FCS_LMOD_FLOAT "f\n", 
	   fcs_get_box_a(handle)[0], fcs_get_box_a(handle)[1], fcs_get_box_a(handle)[2]);
    printf("** debug output lattice in y %" FCS_LMOD_FLOAT "f %" FCS_LMOD_FLOAT "f %" FCS_LMOD_FLOAT "f\n", 
	   fcs_get_box_b(handle)[0], fcs_get_box_b(handle)[1], fcs_get_box_b(handle)[2]);
    printf("** debug output lattice in z %" FCS_LMOD_FLOAT "f %" FCS_LMOD_FLOAT "f %" FCS_LMOD_FLOAT "f\n", 
	   fcs_get_box_c(handle)[0], fcs_get_box_c(handle)[1], fcs_get_box_c(handle)[2]);
  }

  pepc_scafacos_run(&local_particles, &nparts_tot, positions, charges,
		    field, potentials, pepc_internal->work,
		    ((fcs_pepc_internal_t*)(handle->method_context))->virial,
		    fcs_get_box_a(handle), fcs_get_box_b(handle), fcs_get_box_c(handle),
		    fcs_get_periodicity(handle), &handle->pepc_param->dipole_correction,
		    &handle->pepc_param->epsilon, &handle->pepc_param->theta, &handle->pepc_param->debug_level, &handle->pepc_param->num_walk_threads, &handle->pepc_param->npm);

  if (handle->pepc_param->debug_level > 3)
  {
    printf("virial(0,0) %12.4e\n", ((fcs_pepc_internal_t*)(handle->method_context))->virial[0]);

    for(pcnt=0; pcnt<local_particles; pcnt++)
      printf("** e-field dump, particle %" FCS_LMOD_INT "d, (ex,ey,ez): %" FCS_LMOD_FLOAT "f, %" FCS_LMOD_FLOAT "f, %" FCS_LMOD_FLOAT "f\n", pcnt, field[pcnt+0], field[pcnt+1], field[pcnt+2]);
  }

  return FCS_RESULT_SUCCESS;
}