Bridge++  Ver. 1.2.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 const std::string Source_Exponential::class_name = "Source_Exponential";
57 
58 //====================================================================
60 {
61  const string str_vlevel = params.get_string("verbose_level");
62 
63  m_vl = vout.set_verbose_level(str_vlevel);
64 
65  //- fetch and check input parameters
66  valarray<int> source_position;
67  double slope, power;
68 
69  int err = 0;
70  err += params.fetch_int_vector("source_position", source_position);
71  err += params.fetch_double("slope", slope);
72  err += params.fetch_double("power", power);
73 
74  if (err) {
75  vout.crucial(m_vl, "%s: fetch error, input parameter not found.\n", class_name.c_str());
76  abort();
77  }
78 
79  set_parameters(source_position, slope, power);
80 }
81 
82 
83 //====================================================================
84 void Source_Exponential::set_parameters(const valarray<int>& source_position,
85  const double slope, const double power)
86 {
87  // #### parameter setup ####
88  int Ndim = CommonParameters::Ndim();
89 
90  //- global lattice size
91  valarray<int> Lsize(Ndim);
92  Lsize[0] = CommonParameters::Lx();
93  Lsize[1] = CommonParameters::Ly();
94  Lsize[2] = CommonParameters::Lz();
95  Lsize[3] = CommonParameters::Lt();
96 
97  //- local size
98  valarray<int> Nsize(Ndim);
99  Nsize[0] = CommonParameters::Nx();
100  Nsize[1] = CommonParameters::Ny();
101  Nsize[2] = CommonParameters::Nz();
102  Nsize[3] = CommonParameters::Nt();
103 
104  //- print input parameters
105  vout.general(m_vl, "Source for spinor field - exponential smeared:\n");
106  for (int mu = 0; mu < Ndim; ++mu) {
107  vout.general(m_vl, " source_position[%d] = %d\n",
108  mu, source_position[mu]);
109  }
110  vout.general(m_vl, " slope = %12.6f\n", slope);
111  vout.general(m_vl, " power = %12.6f\n", power);
112 
113  //- range check
114  int err = 0;
115  for (int mu = 0; mu < Ndim; ++mu) {
116  // NB. Lsize[mu] > abs(source_position[mu])
117  err += ParameterCheck::non_negative(Lsize[mu] - abs(source_position[mu]));
118  }
119  // NB. slope,power == 0 is allowed.
120 
121  if (err) {
122  vout.crucial(m_vl, "%s: parameter range check failed.\n", class_name.c_str());
123  abort();
124  }
125 
126  assert(source_position.size() == Ndim);
127 
128  //- store values
129  m_source_position.resize(Ndim);
130  for (int mu = 0; mu < Ndim; ++mu) {
131  m_source_position[mu] = (source_position[mu] + Lsize[mu]) % Lsize[mu];
132  }
133 
134  m_slope = slope;
135  m_power = power;
136 
137 
138  //- post-process
139  const int Lvol3 = Lsize[0] * Lsize[1] * Lsize[2];
140  const int Nvol3 = Nsize[0] * Nsize[1] * Nsize[2];
141 
142  m_src_func.reset(1, Nvol3, 1);
143  m_src_func = 0.0;
144 
145  //- PE location in t-direction.
146  int tpe = m_source_position[3] / Nsize[3];
147 
148  m_in_node = false;
149 
150  if (tpe == Communicator::ipe(3)) {
151  m_in_node = true;
152  }
153 
154  //- fill exponential.
155  // center at source_position,
156  // range -L+1 < (x - x0) < L-1,
157  // tail folded.
158  for (int z = -Lsize[2] + 1; z < Lsize[2]; ++z) {
159  for (int y = -Lsize[1] + 1; y < Lsize[1]; ++y) {
160  for (int x = -Lsize[0] + 1; x < Lsize[0]; ++x) {
161  //- global position
162  int z2 = (m_source_position[2] + z + Lsize[2]) % Lsize[2];
163  int y2 = (m_source_position[1] + y + Lsize[1]) % Lsize[1];
164  int x2 = (m_source_position[0] + x + Lsize[0]) % Lsize[0];
165 
166  //- PE location
167  int xpe = x2 / Nsize[0];
168  int ype = y2 / Nsize[1];
169  int zpe = z2 / Nsize[2];
170 
171  //- local position
172  int xl = x2 % Nsize[0];
173  int yl = y2 % Nsize[1];
174  int zl = z2 % Nsize[2];
175 
176  if (
177  (xpe == Communicator::ipe(0)) &&
178  (ype == Communicator::ipe(1)) &&
179  (zpe == Communicator::ipe(2)) &&
180  (tpe == Communicator::ipe(3)))
181  {
182  double r = sqrt((double)(x * x + y * y + z * z));
183  double ex = pow(r, m_power);
184  double expf = exp(-m_slope * ex);
185 
186  int lsite = xl + Nsize[0] * (yl + Nsize[1] * zl);
187 
188  m_src_func.add(0, lsite, 0, expf);
189  }
190  }
191  }
192  }
193 
194  //- normalize
195  double Fnorm = 0.0;
196  for (int i = 0; i < Nvol3; ++i) {
197  Fnorm += m_src_func.cmp(i) * m_src_func.cmp(i);
198  }
199  double Fnorm_global = Communicator::reduce_sum(Fnorm);
200 
201  m_src_func *= 1.0 / sqrt(Fnorm_global);
202 
203  //- check normalization
204  double epsilon_criterion = CommonParameters::epsilon_criterion();
205 
206  Fnorm = 0.0;
207  for (int i = 0; i < Nvol3; i++) {
208  Fnorm += m_src_func.cmp(i) * m_src_func.cmp(i);
209  }
210  Fnorm_global = Communicator::reduce_sum(Fnorm);
211 
212  // assert(abs(sqrt(Fnorm_global) - 1.0) < epsilon_criterion);
213  //- Fluctuation of order of sqrt(NPE) is acceptable. [21 May 2014]
214  double epsilon_criterion2 = epsilon_criterion *
215  sqrt((double)CommonParameters::NPE());
216  // assert(abs(sqrt(Fnorm_global) - 1.0) < epsilon_criterion2);
217  if (abs(sqrt(Fnorm_global) - 1.0) > epsilon_criterion2) {
218  vout.crucial(m_vl, "%s: norm criterion is not satisfied.\n",
219  class_name.c_str());
220  vout.crucial(m_vl, " |sqrt(Fnorm_global) -1| = %e.\n",
221  abs(sqrt(Fnorm_global) - 1.0));
222  vout.crucial(m_vl, " epsilon_criterion2 = %e.\n",
223  epsilon_criterion2);
224  }
225 }
226 
227 
228 //====================================================================
230 {
231  int Ndim = CommonParameters::Ndim();
232 
233  valarray<int> Nsize(Ndim);
234  Nsize[0] = CommonParameters::Nx();
235  Nsize[1] = CommonParameters::Ny();
236  Nsize[2] = CommonParameters::Nz();
237  Nsize[3] = CommonParameters::Nt();
238 
239  //- clear field
240  src = 0.0;
241 
242  if (m_in_node) {
243  int t = m_source_position[3] % Nsize[3];
244 
245  for (int z = 0; z < Nsize[2]; ++z) {
246  for (int y = 0; y < Nsize[1]; ++y) {
247  for (int x = 0; x < Nsize[0]; ++x) {
248  int lsite = x + Nsize[0] * (y + Nsize[1] * z);
249 
250  int isite = m_index.site(x, y, z, t);
251 
252  //XXX field layout: complex as two doubles
253  src.set(2 * j, isite, 0, m_src_func.cmp(0, lsite, 0));
254  }
255  }
256  }
257  }
258 }
259 
260 
261 //====================================================================
262 //============================================================END=====
BridgeIO vout
Definition: bridgeIO.cpp:207
void Register_string(const string &, const string &)
Definition: parameters.cpp:352
static double epsilon_criterion()
void set(const int jin, const int site, const int jex, double v)
Definition: field.h:128
int site(const int &x, const int &y, const int &z, const int &t) const
Definition: index_lex.h:53
void general(const char *format,...)
Definition: bridgeIO.cpp:38
Container of Field-type object.
Definition: field.h:37
double cmp(const int jin, const int site, const int jex) const
Definition: field.h:108
Class for parameters.
Definition: parameters.h:40
static int ipe(const int dir)
logical coordinate of current proc.
int fetch_int_vector(const string &key, std::valarray< int > &val) const
Definition: parameters.cpp:176
void reset(const int Nin, const int Nvol, const int Nex, const element_type cmpl=COMPLEX)
Definition: field.h:82
void crucial(const char *format,...)
Definition: bridgeIO.cpp:26
static const std::string class_name
static bool Register(const std::string &realm, const creator_callback &cb)
valarray< int > m_source_position
void add(const int jin, const int site, const int jex, double v)
Definition: field.h:140
void set(Field &v, int j)
Exponentially smeared source for 4-spinor fermion.
Bridge::VerboseLevel m_vl
Definition: source.h:39
int non_negative(const int v)
Definition: checker.cpp:21
static int reduce_sum(int count, double *recv_buf, double *send_buf, int pattern=0)
make a global sum of an array of double over the communicator. pattern specifies the dimensions to be...
void Register_double(const string &, const double)
Definition: parameters.cpp:324
void Register_int_vector(const string &, const std::valarray< int > &)
Definition: parameters.cpp:345
void set_parameters(const Parameters &params)
int fetch_double(const string &key, double &val) const
Definition: parameters.cpp:124
Base class of sources for a linear solver.
Definition: source.h:36
string get_string(const string &key) const
Definition: parameters.cpp:85
static VerboseLevel set_verbose_level(const std::string &str)
Definition: bridgeIO.cpp:191
static int NPE()