Bridge++  Ver. 1.1.x
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
source_Exponential.cpp
Go to the documentation of this file.
1 
14 #include "source_Exponential.h"
15 
16 #ifdef USE_PARAMETERS_FACTORY
17 #include "parameters_factory.h"
18 #endif
19 
20 using std::valarray;
21 
22 #ifdef USE_FACTORY
23 namespace {
24  Source *create_object()
25  {
26  return new Source_Exponential();
27  }
28 
29 
30  bool init = Source::Factory::Register("Exponential", create_object);
31 }
32 #endif
33 
34 //- parameter entry
35 namespace {
36  void append_entry(Parameters& param)
37  {
38  param.Register_int_vector("source_position", valarray<int>());
39  param.Register_double("slope", 0.0);
40  param.Register_double("power", 0.0);
41 
42  param.Register_string("verbose_level", "NULL");
43  }
44 
45 
46 #ifdef USE_PARAMETERS_FACTORY
47  bool init_param = ParametersFactory::Register("Source.Exponential", append_entry);
48 #endif
49 }
50 //- end
51 
52 //- parameters class
54 //- end
55 
56 //====================================================================
58 {
59  const string str_vlevel = params.get_string("verbose_level");
60 
61  m_vl = vout.set_verbose_level(str_vlevel);
62 
63  //- fetch and check input parameters
64  valarray<int> source_position;
65  double slope, power;
66 
67  int err = 0;
68  err += params.fetch_int_vector("source_position", source_position);
69  err += params.fetch_double("slope", slope);
70  err += params.fetch_double("power", power);
71 
72  if (err) {
73  vout.crucial(m_vl, "Source_Exponential: fetch error, input parameter not found.\n");
74  abort();
75  }
76 
77  set_parameters(source_position, slope, power);
78 }
79 
80 
81 //====================================================================
82 void Source_Exponential::set_parameters(const valarray<int>& source_position,
83  const double slope, const double power)
84 {
85  // #### parameter setup ####
86  int Ndim = CommonParameters::Ndim();
87 
88  //- global lattice size
89  valarray<int> Lsize(Ndim);
90  Lsize[0] = CommonParameters::Lx();
91  Lsize[1] = CommonParameters::Ly();
92  Lsize[2] = CommonParameters::Lz();
93  Lsize[3] = CommonParameters::Lt();
94 
95  //- local size
96  valarray<int> Nsize(Ndim);
97  Nsize[0] = CommonParameters::Nx();
98  Nsize[1] = CommonParameters::Ny();
99  Nsize[2] = CommonParameters::Nz();
100  Nsize[3] = CommonParameters::Nt();
101 
102  //- print input parameters
103  vout.general(m_vl, "Source for spinor field - exponential smeared:\n");
104  for (int mu = 0; mu < Ndim; ++mu) {
105  vout.general(m_vl, " source_position[%d] = %d\n",
106  mu, source_position[mu]);
107  }
108  vout.general(m_vl, " slope = %12.6f\n", slope);
109  vout.general(m_vl, " power = %12.6f\n", power);
110 
111  //- range check
112  int err = 0;
113  for (int mu = 0; mu < Ndim; ++mu) {
114  // NB. Lsize[mu] > abs(source_position[mu])
115  err += ParameterCheck::non_negative(Lsize[mu] - abs(source_position[mu]));
116  }
117  // NB. slope,power == 0 is allowed.
118 
119  if (err) {
120  vout.crucial(m_vl, "Source_Exponential: parameter range check failed.\n");
121  abort();
122  }
123 
124  assert(source_position.size() == Ndim);
125 
126  //- store values
127  m_source_position.resize(Ndim);
128  for (int mu = 0; mu < Ndim; ++mu) {
129  m_source_position[mu] = (source_position[mu] + Lsize[mu]) % Lsize[mu];
130  }
131 
132  m_slope = slope;
133  m_power = power;
134 
135 
136  //- post-process
137  const int Lvol3 = Lsize[0] * Lsize[1] * Lsize[2];
138  const int Nvol3 = Nsize[0] * Nsize[1] * Nsize[2];
139 
140  m_src_func.reset(1, Nvol3, 1);
141  m_src_func = 0.0;
142 
143  //- PE location in t-direction.
144  int tpe = m_source_position[3] / Nsize[3];
145 
146  m_in_node = false;
147 
148  if (tpe == Communicator::ipe(3)) {
149  m_in_node = true;
150  }
151 
152  //- fill exponential.
153  // center at source_position,
154  // range -L+1 < (x - x0) < L-1,
155  // tail folded.
156  for (int z = -Lsize[2] + 1; z < Lsize[2]; ++z) {
157  for (int y = -Lsize[1] + 1; y < Lsize[1]; ++y) {
158  for (int x = -Lsize[0] + 1; x < Lsize[0]; ++x) {
159  //- global position
160  int z2 = (m_source_position[2] + z + Lsize[2]) % Lsize[2];
161  int y2 = (m_source_position[1] + y + Lsize[1]) % Lsize[1];
162  int x2 = (m_source_position[0] + x + Lsize[0]) % Lsize[0];
163 
164  //- PE location
165  int xpe = x2 / Nsize[0];
166  int ype = y2 / Nsize[1];
167  int zpe = z2 / Nsize[2];
168 
169  //- local position
170  int xl = x2 % Nsize[0];
171  int yl = y2 % Nsize[1];
172  int zl = z2 % Nsize[2];
173 
174  if (
175  (xpe == Communicator::ipe(0)) &&
176  (ype == Communicator::ipe(1)) &&
177  (zpe == Communicator::ipe(2)) &&
178  (tpe == Communicator::ipe(3)))
179  {
180  double r = sqrt((double)(x * x + y * y + z * z));
181  double ex = pow(r, m_power);
182  double expf = exp(-m_slope * ex);
183 
184  int lsite = xl + Nsize[0] * (yl + Nsize[1] * zl);
185 
186  m_src_func.add(0, lsite, 0, expf);
187  }
188  }
189  }
190  }
191 
192  //- normalize
193  double Fnorm = 0.0;
194  for (int i = 0; i < Nvol3; ++i) {
195  Fnorm += m_src_func.cmp(i) * m_src_func.cmp(i);
196  }
197  double Fnorm_global = Communicator::reduce_sum(Fnorm);
198 
199  m_src_func *= 1.0 / sqrt(Fnorm_global);
200 
201  //- check normalization
202  double epsilon_criterion = CommonParameters::epsilon_criterion();
203 
204  Fnorm = 0.0;
205  for (int i = 0; i < Nvol3; i++) {
206  Fnorm += m_src_func.cmp(i) * m_src_func.cmp(i);
207  }
208  Fnorm_global = Communicator::reduce_sum(Fnorm);
209 
210  assert(abs(sqrt(Fnorm_global) - 1.0) < epsilon_criterion);
211 }
212 
213 
214 //====================================================================
216 {
217  int Ndim = CommonParameters::Ndim();
218 
219  valarray<int> Nsize(Ndim);
220  Nsize[0] = CommonParameters::Nx();
221  Nsize[1] = CommonParameters::Ny();
222  Nsize[2] = CommonParameters::Nz();
223  Nsize[3] = CommonParameters::Nt();
224 
225  //- clear field
226  src = 0.0;
227 
228  if (m_in_node) {
229  int t = m_source_position[3] % Nsize[3];
230 
231  for (int z = 0; z < Nsize[2]; ++z) {
232  for (int y = 0; y < Nsize[1]; ++y) {
233  for (int x = 0; x < Nsize[0]; ++x) {
234  int lsite = x + Nsize[0] * (y + Nsize[1] * z);
235 
236  int isite = m_index.site(x, y, z, t);
237 
238  //XXX field layout: complex as two doubles
239  src.set(2 * j, isite, 0, m_src_func.cmp(0, lsite, 0));
240  }
241  }
242  }
243  }
244 }
245 
246 
247 //====================================================================
248 //============================================================END=====