ScaFaCoS  1.0.1
Scalable Fast Coulomb Solvers
fcs_p3m_p.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2011,2012 Rene Halver, Olaf Lenz
3 
4  This file is part of ScaFaCoS.
5 
6  ScaFaCoS is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Lesser Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  ScaFaCoS is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Lesser Public License for more details.
15 
16  You should have received a copy of the GNU Lesser Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #ifndef _FCS_P3M_P_H
21 #define _FCS_P3M_P_H
22 
23 #include "fcs_definitions.h"
24 #include "fcs_result_p.h"
25 #include "fcs_interface_p.h"
26 #include <math.h>
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
38 /* TODO: test whether to use it or not */
39 #define FCS_P3M_USE_ERFC_APPROXIMATION 1
40  /* #define FCS_P3M_USE_ERFC_APPROXIMATION 0 */
41 
50 /* This struct is defined open so that an MD implementation can use
51  the parameters to perform the near field computation in its own
52  code. */
53 typedef struct {fcs_float alpha; fcs_float potentialOffset;} fcs_p3m_near_parameters_t;
54 
70 FCSResult
72  fcs_p3m_near_parameters_t *near_params);
73 
87 /* This function is defined inline for maximal performance! */
88 static inline fcs_float
89 fcs_p3m_compute_near_potential(fcs_p3m_near_parameters_t params, fcs_float dist) {
90  const fcs_float alpha = params.alpha;
91  const fcs_float potentialOffset = params.potentialOffset;
92  fcs_float adist = alpha * dist;
93 
94 #if FCS_P3M_USE_ERFC_APPROXIMATION
95 
96  /* approximate \f$ \exp(d^2) \mathrm{erfc}(d)\f$ by applying a formula from:
97  Abramowitz/Stegun: Handbook of Mathematical Functions, Dover
98  (9. ed.), chapter 7 */
99  fcs_float t = 1.0 / (1.0 + 0.3275911 * adist);
100  fcs_float erfc_part_ri = exp(-adist*adist) *
101  (t * (0.254829592 +
102  t * (-0.284496736 +
103  t * (1.421413741 +
104  t * (-1.453152027 +
105  t * 1.061405429)))))
106  / dist;
107 
108 #else
109 
110  /* use erf instead of erfc to fix ICC performance problems */
111  fcs_float erfc_part_ri = (1.0 - erf(adist)) / dist;
112 
113 #endif
114 
115  return erfc_part_ri-potentialOffset;
116 
117 }
118 
132 static inline fcs_float
133 fcs_p3m_compute_near_field(fcs_p3m_near_parameters_t params, fcs_float dist) {
134  const fcs_float alpha = params.alpha;
135  fcs_float adist = alpha * dist;
136 
137 #if FCS_P3M_USE_ERFC_APPROXIMATION
138 
139  /* approximate \f$ \exp(d^2) \mathrm{erfc}(d)\f$ by applying a formula from:
140  Abramowitz/Stegun: Handbook of Mathematical Functions, Dover
141  (9. ed.), chapter 7 */
142  fcs_float t = 1.0 / (1.0 + 0.3275911 * adist);
143  fcs_float erfc_part_ri = exp(-adist*adist) *
144  (t * (0.254829592 +
145  t * (-0.284496736 +
146  t * (1.421413741 +
147  t * (-1.453152027 +
148  t * 1.061405429)))))
149  / dist;
150  /* 1/sqrt(PI) = 0.56418958354775627928034964498 */
151  return -(erfc_part_ri + 2.0*alpha*0.56418958354775627928034964498*exp(-adist*adist))
152  / dist;
153 
154 #else
155 
156  fcs_float erfc_part_ri = (1.0 - erf(adist)) / dist; /* use erf instead of erfc to fix ICC performance problems */
157  /* 1/sqrt(PI) = 0.56418958354775627928034964498 */
158  return -(erfc_part_ri + 2.0*alpha*0.56418958354775627928034964498*exp(-adist*adist))
159  / dist;
160 
161 #endif
162 
163 }
164 
165 
182 static inline void
183 fcs_p3m_compute_near(fcs_p3m_near_parameters_t params, fcs_float dist,
184  fcs_float *potential, fcs_float *field) {
185  const fcs_float alpha = params.alpha;
186  const fcs_float potentialOffset = params.potentialOffset;
187  fcs_float adist = alpha * dist;
188 
189 #if FCS_P3M_USE_ERFC_APPROXIMATION
190 
191  /* approximate \f$ \exp(d^2) \mathrm{erfc}(d)\f$ by applying a formula from:
192  Abramowitz/Stegun: Handbook of Mathematical Functions, Dover
193  (9. ed.), chapter 7 */
194  fcs_float t = 1.0 / (1.0 + 0.3275911 * adist);
195  fcs_float erfc_part_ri = exp(-adist*adist) *
196  (t * (0.254829592 +
197  t * (-0.284496736 +
198  t * (1.421413741 +
199  t * (-1.453152027 +
200  t * 1.061405429)))))
201  / dist;
202 
203  *potential = erfc_part_ri-potentialOffset;
204  *field = -(erfc_part_ri + 2.0*alpha*0.56418958354775627928034964498*exp(-adist*adist))
205  / dist;
206 
207 #else
208 
209  fcs_float erfc_part_ri = (1.0 - erf(adist)) / dist; /* use erf instead of erfc to fix ICC performance problems */
210  *potential = erfc_part_ri-potentialOffset;
211  *field = -(erfc_part_ri + 2.0*alpha*0.56418958354775627928034964498*exp(-adist*adist))
212  / dist;
213 
214 #endif
215 
216 }
217 
219 
220 FCSResult fcs_p3m_set_r_cut(FCS handle, fcs_float r_cut);
222 FCSResult fcs_p3m_get_r_cut(FCS handle, fcs_float *r_cut);
223 
224 FCSResult fcs_p3m_set_alpha(FCS handle, fcs_float alpha);
226 FCSResult fcs_p3m_get_alpha(FCS handle, fcs_float *alpha);
227 
228 FCSResult fcs_p3m_set_grid(FCS handle, fcs_int grid);
230 FCSResult fcs_p3m_get_grid(FCS handle, fcs_int *grid);
231 
232 FCSResult fcs_p3m_set_cao(FCS handle, fcs_int cao);
234 FCSResult fcs_p3m_get_cao(FCS handle, fcs_int *cao);
235 
236 FCSResult fcs_p3m_require_total_energy(FCS handle, fcs_int total_energy);
237 FCSResult fcs_p3m_get_total_energy(FCS handle, fcs_float *total_energy);
238 
239 FCSResult fcs_p3m_set_potential_shift(FCS handle, fcs_int flag);
240 fcs_int fcs_p3m_get_potential_shift(FCS handle);
241 
242 FCSResult fcs_p3m_set_tolerance_field(FCS handle, fcs_float tolerance_field);
243 /* FORTRAN wrapper */
244 void fcs_p3m_set_tolerance_field_f(void *handle, fcs_float tolerance_field, fcs_int *return_value);
246 FCSResult fcs_p3m_get_tolerance_field(FCS handle, fcs_float *tolerance_field);
247 
248 
249 
250  /*
251 FCSResult fcs_p3m_set_variant(FCS handle, fcs_int variant);
252 FCSResult fcs_p3m_get_variant(FCS handle, fcs_int *variant);
253  */
254 
255 #ifdef __cplusplus
256 }
257 #endif
258 
259 #endif
FCSResult fcs_p3m_set_grid_tune(FCS handle)
FCSResult fcs_p3m_get_tolerance_field(FCS handle, fcs_float *tolerance_field)
FCSResult fcs_p3m_get_cao(FCS handle, fcs_int *cao)
FCSResult fcs_p3m_set_cao(FCS handle, fcs_int cao)
FCSResult fcs_p3m_get_r_cut(FCS handle, fcs_float *r_cut)
FCSResult fcs_p3m_set_alpha_tune(FCS handle)
FCSResult fcs_p3m_set_r_cut(FCS handle, fcs_float r_cut)
fcs_int fcs_p3m_get_potential_shift(FCS handle)
FCSResult fcs_p3m_distribute_parameters()
FCSResult fcs_p3m_set_tolerance_field(FCS handle, fcs_float tolerance_field)
FCSResult fcs_p3m_set_tolerance_field_tune(FCS handle)
FCSResult fcs_p3m_get_alpha(FCS handle, fcs_float *alpha)
FCSResult fcs_p3m_get_near_parameters(FCS handle, fcs_p3m_near_parameters_t *near_params)
extracts the parameters required to compute the near-field component of p3m from the method handle ...
public interface definitions for the FCSResult-object that is used for handling the return state of t...
FCSResult fcs_p3m_set_alpha(FCS handle, fcs_float alpha)
void fcs_p3m_set_tolerance_field_f(void *handle, fcs_float tolerance_field, fcs_int *return_value)
FCSResult fcs_p3m_set_r_cut_tune(FCS handle)
FCSResult fcs_p3m_set_grid(FCS handle, fcs_int grid)
struct FCSResult_t * FCSResult
FCSResult-object that is used for handling the return state of the ScaFaCoS library functions...
Definition: fcs_result_p.h:42
FCSResult fcs_p3m_get_total_energy(FCS handle, fcs_float *total_energy)
public interface definitions for the main solver-independent functionality of the ScaFaCoS library ...
FCSResult fcs_p3m_set_cao_tune(FCS handle)
The struct that keeps the parameters for the near field component of the method.
Definition: fcs_p3m_p.h:53
FCSResult fcs_p3m_require_total_energy(FCS handle, fcs_int total_energy)
FCSResult fcs_p3m_get_grid(FCS handle, fcs_int *grid)
struct _FCS_t * FCS
FCS-object representing an FCS solver.
FCSResult fcs_p3m_set_potential_shift(FCS handle, fcs_int flag)