/* 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))
FCSResult fcs_mmm1d_tune(FCS handle, fcs_int local_particles, fcs_int local_max_particles, fcs_float *positions, fcs_float *charges) { char* fnc_name = "fcs_mmm1d_tune"; FCSResult result; result = fcs_mmm1d_check(handle, fnc_name); if (result != NULL) return result; /* Check box periodicity */ fcs_int *periodicity = fcs_get_periodicity(handle); if (periodicity[0] != 0 || periodicity[1] != 0 || periodicity[2] != 1) return fcsResult_create(FCS_LOGICAL_ERROR, fnc_name, "mmm1d requires z-axis periodic boundary."); /* Check box shape */ fcs_float *a = fcs_get_box_a(handle); fcs_float *b = fcs_get_box_b(handle); fcs_float *c = fcs_get_box_c(handle); if (!fcs_is_cubic(a, b, c)) return fcsResult_create(FCS_LOGICAL_ERROR, fnc_name, "mmm1d requires a cubic box."); mmm1d_set_box_a(handle->method_context, a[0]); mmm1d_set_box_b(handle->method_context, b[1]); mmm1d_set_box_c(handle->method_context, c[2]); /* Effectively, tune initializes the algorithm */ result = mmm1d_tune(handle->method_context, local_particles, positions, charges); return result; }
/** * 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; }
/* internal p3m-specific tuning function */ FCSResult fcs_mmm2d_tune(FCS handle, fcs_int local_particles, fcs_float *positions, fcs_float *charges) { FCSResult result; MMM2D_CHECK_RETURN_RESULT(handle, __func__); /* Check box periodicity */ const fcs_int *periodicity = fcs_get_periodicity(handle); if (periodicity[0] != 1 || periodicity[1] != 1 || periodicity[2] != 0) return fcs_result_create(FCS_ERROR_WRONG_ARGUMENT, __func__, "mmm2d requires x and y-axis periodic boundaries."); /* Check box shape */ ///@TODO: check for rectangular box geometry (any fcs adequate method?) 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)) return fcs_result_create(FCS_ERROR_WRONG_ARGUMENT, __func__, "p3m requires the box to be orthorhombic."); if (!fcs_uses_principal_axes(a, b, c)) return fcs_result_create(FCS_ERROR_WRONG_ARGUMENT, __func__, "p3m requires the box vectors to be parallel to the principal axes."); */ mmm2d_set_box_a(handle->method_context, a[0]); mmm2d_set_box_b(handle->method_context, b[1]); mmm2d_set_box_c(handle->method_context, c[2]); /* Effectively, tune initializes the algorithm */ result = mmm2d_tune(handle->method_context, local_particles, positions, charges); return result; }
/* 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; }
/* 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; }
FCSResult fcs_fmm_check(FCS handle) { const fcs_float *a,*b,*c; const fcs_int *periodicity; int i,p; 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 deltaE; fcs_fmm_get_deltaE(handle, &deltaE); if (deltaE == -1.0) return fcs_result_create(FCS_ERROR_MISSING_ELEMENT, __func__, "fmm: deltaE not set"); a = fcs_get_box_a(handle); b = fcs_get_box_b(handle); c = fcs_get_box_c(handle); periodicity = fcs_get_periodicity(handle); p = 0; for (i = 0; i < 3; ++i) if (periodicity[i]) p++; switch(p) { case 0: return FCS_RESULT_SUCCESS; case 1: for (i = 0; i < 3; ++i) if (periodicity[i]) break; switch(i) { case 0: if (!( (fcs_norm(a) >= fcs_norm(b)) && (fcs_norm(a) >= fcs_norm(c)) )) return fcs_result_create(FCS_ERROR_INCOMPATIBLE_METHOD, __func__, "fmm: longest box vector not in direction of 1D-periodicity direction"); return FCS_RESULT_SUCCESS; case 1: if (!( (fcs_norm(b) >= fcs_norm(a)) && (fcs_norm(b) >= fcs_norm(a)) )) return fcs_result_create(FCS_ERROR_INCOMPATIBLE_METHOD, __func__, "fmm: longest box vector not in direction of 1D-periodicity direction"); return FCS_RESULT_SUCCESS; case 2: if (!( (fcs_norm(c) >= fcs_norm(a)) && (fcs_norm(c) >= fcs_norm(b)) )) return fcs_result_create(FCS_ERROR_INCOMPATIBLE_METHOD, __func__, "fmm: longest box vector not in direction of 1D-periodicity direction"); return FCS_RESULT_SUCCESS; } case 2: for (i = 0; i < 3; ++i) if (!periodicity[i]) break; switch(i) { case 0: if (!( (fcs_float_is_equal(fcs_norm(b),fcs_norm(c))) && (fcs_norm(b) >= fcs_norm(a)) )) return fcs_result_create(FCS_ERROR_INCOMPATIBLE_METHOD, __func__, "fmm: longest box vector not in direction of 2D-periodicity direction"); return FCS_RESULT_SUCCESS; case 1: if (!( (fcs_float_is_equal(fcs_norm(a),fcs_norm(c))) && (fcs_norm(a) >= fcs_norm(b)) )) return fcs_result_create(FCS_ERROR_INCOMPATIBLE_METHOD, __func__, "fmm: longest box vector not in direction of 2D-periodicity direction"); return FCS_RESULT_SUCCESS; case 2: if (!( (fcs_float_is_equal(fcs_norm(a),fcs_norm(b))) && (fcs_norm(a) >= fcs_norm(c)) )) return fcs_result_create(FCS_ERROR_INCOMPATIBLE_METHOD, __func__, "fmm: longest box vector not in direction of 2D-periodicity direction"); return FCS_RESULT_SUCCESS; } case 3: if (!(fcs_uses_principal_axes(a,b,c))) return fcs_result_create(FCS_ERROR_INCOMPATIBLE_METHOD, __func__, "fmm: cannot use a non-cubic system in 3D-periodicity"); return FCS_RESULT_SUCCESS; } return FCS_RESULT_SUCCESS; }
/* 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; }
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; }
/* 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; }