HΦ  3.2.0
CalcSpectrumByBiCG.c
Go to the documentation of this file.
1 /* HPhi - Quantum Lattice Model Simulator */
2 /* Copyright (C) 2015 Takahiro Misawa, Kazuyoshi Yoshimi, Mitsuaki Kawamura, Youhei Yamaji, Synge Todo, Naoki Kawashima */
3 
4 /* This program is free software: you can redistribute it and/or modify */
5 /* it under the terms of the GNU General Public License as published by */
6 /* the Free Software Foundation, either version 3 of the License, or */
7 /* (at your option) any later version. */
8 
9 /* This program is distributed in the hope that it will be useful, */
10 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
11 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
12 /* GNU General Public License for more details. */
13 
14 /* You should have received a copy of the GNU General Public License */
15 /* along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 #include "Common.h"
21 #include "CalcSpectrumByLanczos.h"
22 #include "Lanczos_EigenValue.h"
23 #include "FileIO.h"
24 #include "wrapperMPI.h"
25 #include "common/setmemory.h"
26 #include "komega/komega.h"
27 #include "mltply.h"
28 #ifdef MPI
29 #include <mpi.h>
30 #endif
31 
35  struct EDMainCalStruct *X,
36  double complex *v2,
37  double complex *v4,
38  double complex *v12,
39  double complex *v14,
40  int Nomega,
41  double complex *dcSpectrum,
42  double complex *dcomega
43 ) {
44  char sdt[D_FileNameMax];
45  char ctmp[256];
46 
47  int one = 1, status[3], idim_max2int, max_step, iter_old;
48  unsigned long int idx;
49  double complex *alphaCG, *betaCG, *res_save, z_seed;
50  double z_seed_r, z_seed_i, alpha_r, alpha_i, beta_r, beta_i, res_r, res_i;
51  FILE *fp;
52  int comm;
53 
54 #if defined(MPI)
55  comm = MPI_Comm_c2f(MPI_COMM_WORLD);
56 #else
57  comm = 0;
58 #endif
59  idim_max2int = (int)X->Bind.Check.idim_max;
60 
61  if (X->Bind.Def.iFlgCalcSpec == RECALC_FROM_TMComponents ||
62  X->Bind.Def.iFlgCalcSpec == RECALC_FROM_TMComponents_VEC ||
63  X->Bind.Def.iFlgCalcSpec == RECALC_INOUT_TMComponents_VEC) {
65  if (childfopenALL(sdt, "rb", &fp) != 0) {
66  fprintf(stdoutMPI, "INFO: File for the restart is not found.\n");
67  fprintf(stdoutMPI, " Start from SCRATCH.\n");
68  max_step = (int)X->Bind.Def.Lanczos_max;
69  komega_bicg_init(&idim_max2int, &one, &Nomega, dcSpectrum, dcomega, &max_step, &eps_Lanczos, &comm);
70  }
71  else {
72  fgetsMPI(ctmp, sizeof(ctmp) / sizeof(char), fp);
73  sscanf(ctmp, "%d", &iter_old);
74  if (X->Bind.Def.iFlgCalcSpec > RECALC_FROM_TMComponents) {
75  alphaCG = (double complex*)malloc((iter_old + X->Bind.Def.Lanczos_max) * sizeof(double complex));
76  betaCG = (double complex*)malloc((iter_old + X->Bind.Def.Lanczos_max) * sizeof(double complex));
77  res_save = (double complex*)malloc((iter_old + X->Bind.Def.Lanczos_max) * sizeof(double complex));
78  }
79  else {
80  alphaCG = (double complex*)malloc(iter_old * sizeof(double complex));
81  betaCG = (double complex*)malloc(iter_old * sizeof(double complex));
82  res_save = (double complex*)malloc(iter_old * sizeof(double complex));
83  }
84  fgetsMPI(ctmp, sizeof(ctmp) / sizeof(char), fp);
85  sscanf(ctmp, "%lf %lf\n", &z_seed_r, &z_seed_i);
86  z_seed = z_seed_r + I * z_seed_i;
87 
88  idx = 0;
89  while (fgetsMPI(ctmp, sizeof(ctmp) / sizeof(char), fp) != NULL) {
90  sscanf(ctmp, "%lf %lf %lf %lf %lf %lf\n",
91  &alpha_r, &alpha_i, &beta_r, &beta_i, &res_r, &res_i);
92  alphaCG[idx] = alpha_r + I * alpha_i;
93  betaCG[idx] = beta_r + I * beta_i;
94  res_save[idx] = res_r + I * res_i;
95  idx += 1;
96  }
97  fclose(fp);
98 
99  if (X->Bind.Def.iFlgCalcSpec == RECALC_FROM_TMComponents) X->Bind.Def.Lanczos_max = 0;
100  max_step = (int)(iter_old + X->Bind.Def.Lanczos_max);
101 
102  komega_bicg_restart(&idim_max2int, &one, &Nomega, dcSpectrum, dcomega, &max_step, &eps_Lanczos, status,
103  &iter_old, &v2[1], &v12[1], &v4[1], &v14[1], alphaCG, betaCG, &z_seed, res_save, &comm);
104  free(alphaCG);
105  free(betaCG);
106  free(res_save);
107  }/*if (childfopenALL(sdt, "rb", &fp) == 0)*/
108  }/*if (X->Bind.Def.iFlgCalcSpec > RECALC_NOT)*/
109  else {
110  max_step = (int)X->Bind.Def.Lanczos_max;
111  komega_bicg_init(&idim_max2int, &one, &Nomega, dcSpectrum, dcomega, &max_step, &eps_Lanczos, &comm);
112  }
113 
114 }/*int ReadTMComponents_BiCG*/
119  struct EDMainCalStruct *X,
120  int liLanczosStp
121 )
122 {
123  char sdt[D_FileNameMax];
124  unsigned long int stp;
125  FILE *fp;
126  double complex *alphaCG, *betaCG, *res_save, z_seed;
127 
128  alphaCG = (double complex*)malloc(liLanczosStp * sizeof(double complex));
129  betaCG = (double complex*)malloc(liLanczosStp * sizeof(double complex));
130  res_save = (double complex*)malloc(liLanczosStp * sizeof(double complex));
131 
132  komega_bicg_getcoef(alphaCG, betaCG, &z_seed, res_save);
133 
135  childfopenMPI(sdt, "w", &fp);
136  fprintf(fp, "%d \n", liLanczosStp);
137  fprintf(fp, "%.10lf %.10lf\n", creal(z_seed), cimag(z_seed));
138  for (stp = 0; stp < liLanczosStp; stp++) {
139  fprintf(fp, "%25.16le %25.16le %25.16le %25.16le %25.16le %25.16le\n",
140  creal(alphaCG[stp]), cimag(alphaCG[stp]),
141  creal(betaCG[stp]), cimag(betaCG[stp]),
142  creal(res_save[stp]), cimag(res_save[stp]));
143  }
144  fclose(fp);
145  free(alphaCG);
146  free(betaCG);
147  free(res_save);
148 
149  return TRUE;
150 }/*int OutputTMComponents_BiCG*/
155  struct BindStruct *X,
156  double complex *v4
157 )
158 {
159  long int idim, iv;
160  int mythread;
161  double dnorm;
162  /*
163  For DSFMT
164  */
165  long unsigned int u_long_i;
166  dsfmt_t dsfmt;
167 
168  iv = X->Def.initial_iv;
169 #pragma omp parallel default(none) private(idim, u_long_i, mythread, dsfmt) \
170  shared(v4, iv, X, nthreads, myrank)
171  {
172  /*
173  Initialise MT
174  */
175 #ifdef _OPENMP
176  mythread = omp_get_thread_num();
177 #else
178  mythread = 0;
179 #endif
180  u_long_i = 123432 + labs(iv) + mythread + nthreads * myrank;
181  dsfmt_init_gen_rand(&dsfmt, u_long_i);
182 
183 #pragma omp for
184  for (idim = 1; idim <= X->Check.idim_max; idim++)
185  v4[idim] = 2.0*(dsfmt_genrand_close_open(&dsfmt) - 0.5)
186  + 2.0*(dsfmt_genrand_close_open(&dsfmt) - 0.5)*I;
187  }/*#pragma omp parallel*/
188 
189  dnorm = sqrt(creal(VecProdMPI(X->Check.idim_max, v4, v4)));
190 #pragma omp parallel for default(none) shared(X,v4,dnorm) private(idim)
191  for (idim = 1; idim <= X->Check.idim_max; idim++) v4[idim] /= dnorm;
192 
193 }/*void InitShadowRes*/
207  struct EDMainCalStruct *X,
208  double complex *vrhs,
209  double complex *v2,
210  double complex *v4,
211  int Nomega,
212  double complex *dcSpectrum,
213  double complex *dcomega
214 )
215 {
216  char sdt[D_FileNameMax];
217  unsigned long int idim, i_max;
218  FILE *fp;
219  size_t byte_size;
220  int iret, max_step;
221  unsigned long int liLanczosStp_vec = 0;
222  double complex *v12, *v14, res_proj;
223  int stp, one = 1, status[3], iomega;
224  double *resz;
225 
226  fprintf(stdoutMPI, "##### Spectrum calculation with BiCG #####\n\n");
232  v12 = (double complex*)malloc((X->Bind.Check.idim_max + 1) * sizeof(double complex));
233  v14 = (double complex*)malloc((X->Bind.Check.idim_max + 1) * sizeof(double complex));
234  resz = (double*)malloc(Nomega * sizeof(double));
239  if (X->Bind.Def.iFlgCalcSpec == RECALC_FROM_TMComponents_VEC ||
240  X->Bind.Def.iFlgCalcSpec == RECALC_INOUT_TMComponents_VEC) {
241  fprintf(stdoutMPI, " Start: Input vectors for recalculation.\n");
243 
245  if (childfopenALL(sdt, "rb", &fp) != 0) {
246  fprintf(stdoutMPI, "INFO: File for the restart is not found.\n");
247  fprintf(stdoutMPI, " Start from SCRATCH.\n");
248 #pragma omp parallel for default(none) shared(v2,v4,vrhs,X) private(idim)
249  for (idim = 1; idim <= X->Bind.Check.idim_max; idim++) {
250  v2[idim] = vrhs[idim];
251  v4[idim] = vrhs[idim];
252  }
253  //InitShadowRes(&(X->Bind), v4);
254  }
255  else {
256  byte_size = fread(&liLanczosStp_vec, sizeof(int), 1, fp);
257  byte_size = fread(&i_max, sizeof(i_max), 1, fp);
258  if (i_max != X->Bind.Check.idim_max) {
259  fprintf(stderr, "Error: The size of the input vector is incorrect.\n");
260  printf("%s %ld %ld %ld\n", sdt, i_max, X->Bind.Check.idim_max, liLanczosStp_vec);
261  exitMPI(-1);
262  }
263  byte_size = fread(v2, sizeof(complex double), X->Bind.Check.idim_max + 1, fp);
264  byte_size = fread(v12, sizeof(complex double), X->Bind.Check.idim_max + 1, fp);
265  byte_size = fread(v4, sizeof(complex double), X->Bind.Check.idim_max + 1, fp);
266  byte_size = fread(v14, sizeof(complex double), X->Bind.Check.idim_max + 1, fp);
267  fclose(fp);
268  fprintf(stdoutMPI, " End: Input vectors for recalculation.\n");
270  if (byte_size == 0) printf("byte_size : %d\n", (int)byte_size);
271  }/*if (childfopenALL(sdt, "rb", &fp) == 0)*/
272  }/*if (X->Bind.Def.iFlgCalcSpec > RECALC_FROM_TMComponents)*/
273  else {
274 #pragma omp parallel for default(none) shared(v2,v4,vrhs,X) private(idim)
275  for (idim = 1; idim <= X->Bind.Check.idim_max; idim++) {
276  v2[idim] = vrhs[idim];
277  v4[idim] = vrhs[idim];
278  }
279  //InitShadowRes(&(X->Bind), v4);
280  }
284  ReadTMComponents_BiCG(X, v2, v4, v12, v14, Nomega, dcSpectrum, dcomega);
289  fprintf(stdoutMPI, " Start: Calculate tridiagonal matrix components.\n");
291  fprintf(stdoutMPI, "\n Iteration Status Seed Residual-2-Norm\n");
292  childfopenMPI("residual.dat", "w", &fp);
293 
294  for (stp = 1; stp <= X->Bind.Def.Lanczos_max; stp++) {
299 #pragma omp parallel for default(none) shared(X,v12,v14) private(idim)
300  for (idim = 1; idim <= X->Bind.Check.idim_max; idim++) {
301  v12[idim] = 0.0;
302  v14[idim] = 0.0;
303  }
304  iret = mltply(&X->Bind, v12, v2);
305  iret = mltply(&X->Bind, v14, v4);
306 
307  res_proj = VecProdMPI(X->Bind.Check.idim_max, vrhs, v2);
312  komega_bicg_update(&v12[1], &v2[1], &v14[1], &v4[1], dcSpectrum, &res_proj, status);
313 
317  if (stp % 10 == 0) {
318  komega_bicg_getresidual(resz);
319 
320  for (iomega = 0; iomega < Nomega; iomega++) {
321  fprintf(fp, "%7i %20.10e %20.10e %20.10e %20.10e\n",
322  stp, creal(dcomega[iomega]),
323  creal(dcSpectrum[iomega]), cimag(dcSpectrum[iomega]),
324  resz[iomega]);
325  }
326  fprintf(fp, "\n");
327  }
328 
329  fprintf(stdoutMPI, " %9d %9d %8d %25.15e\n", abs(status[0]), status[1], status[2], creal(v12[1]));
330  if (status[0] < 0) break;
331  }/*for (stp = 0; stp <= X->Bind.Def.Lanczos_max; stp++)*/
332  fclose(fp);
337  fprintf(stdoutMPI, " End: Calculate tridiagonal matrix components.\n\n");
342  if (X->Bind.Def.iFlgCalcSpec != RECALC_FROM_TMComponents)
343  OutputTMComponents_BiCG(X, abs(status[0]));
348  if (X->Bind.Def.iFlgCalcSpec == RECALC_OUTPUT_TMComponents_VEC ||
349  X->Bind.Def.iFlgCalcSpec == RECALC_INOUT_TMComponents_VEC) {
350  fprintf(stdoutMPI, " Start: Output vectors for recalculation.\n");
352 
353  komega_bicg_getvec(&v12[1], &v14[1]);
354 
356  if (childfopenALL(sdt, "wb", &fp) != 0) {
357  exitMPI(-1);
358  }
359  byte_size = fwrite(&status[0], sizeof(status[0]), 1, fp);
360  byte_size = fwrite(&X->Bind.Check.idim_max, sizeof(X->Bind.Check.idim_max), 1, fp);
361  byte_size = fwrite(v2, sizeof(complex double), X->Bind.Check.idim_max + 1, fp);
362  byte_size = fwrite(v12, sizeof(complex double), X->Bind.Check.idim_max + 1, fp);
363  byte_size = fwrite(v4, sizeof(complex double), X->Bind.Check.idim_max + 1, fp);
364  byte_size = fwrite(v14, sizeof(complex double), X->Bind.Check.idim_max + 1, fp);
365  fclose(fp);
366 
367  fprintf(stdoutMPI, " End: Output vectors for recalculation.\n");
369  }/*if (X->Bind.Def.iFlgCalcSpec > RECALC_FROM_TMComponents)*/
370 
371  komega_bicg_finalize();
372 
373  free(resz);
374  free(v12);
375  free(v14);
376  return TRUE;
377 }/*int CalcSpectrumByBiCG*/
int childfopenALL(const char *_cPathChild, const char *_cmode, FILE **_fp)
All processes open file in output/ directory.
Definition: FileIO.c:50
void exitMPI(int errorcode)
MPI Abortation wrapper.
Definition: wrapperMPI.c:86
struct DefineList Def
Definision of system (Hamiltonian) etc.
Definition: struct.h:410
int mltply(struct BindStruct *X, double complex *tmp_v0, double complex *tmp_v1)
Parent function of multiplying the wavefunction by the Hamiltonian. . First, the calculation of diago...
Definition: mltply.c:56
int OutputTMComponents_BiCG(struct EDMainCalStruct *X, int liLanczosStp)
write , projected residual for restart
unsigned long int idim_max
The dimension of the Hilbert space of this process.
Definition: struct.h:303
void InitShadowRes(struct BindStruct *X, double complex *v4)
Initialize Shadow Residual as a random vector (Experimental)
#define D_FileNameMax
Definition: global.h:23
double complex * v2
Definition: global.h:36
int childfopenMPI(const char *_cPathChild, const char *_cmode, FILE **_fp)
Only the root process open file in output/ directory.
Definition: FileIO.c:27
const char * cFileNameOutputRestartVec
Definition: global.c:81
#define TRUE
Definition: global.h:26
Bind.
Definition: struct.h:419
int nthreads
Number of Threads, defined in InitializeMPI()
Definition: global.h:164
int CalcSpectrumByBiCG(struct EDMainCalStruct *X, double complex *vrhs, double complex *v2, double complex *v4, int Nomega, double complex *dcSpectrum, double complex *dcomega)
A main function to calculate spectrum by BiCG method In this function, the library is used...
Bind.
Definition: struct.h:409
void ReadTMComponents_BiCG(struct EDMainCalStruct *X, double complex *v2, double complex *v4, double complex *v12, double complex *v14, int Nomega, double complex *dcSpectrum, double complex *dcomega)
Read , projected residual for restart.
const char * c_OutputSpectrumRecalcvecEnd
Definition: LogMessage.c:71
const char * c_InputSpectrumRecalcvecStart
Definition: LogMessage.c:72
const char * cFileNameTridiagonalMatrixComponents
Definition: global.c:52
const char * c_GetTridiagonalStart
Definition: LogMessage.c:66
const char * cFileNameTimeKeep
Definition: global.c:23
const char * c_InputSpectrumRecalcvecEnd
Definition: LogMessage.c:73
double complex VecProdMPI(long unsigned int ndim, double complex *v1, double complex *v2)
Compute conjugate scaler product of process-distributed vector .
Definition: wrapperMPI.c:314
struct EDMainCalStruct X
Definition: struct.h:432
long int initial_iv
Seed of random number for initial guesss of wavefunctions.
Definition: struct.h:76
int myrank
Process ID, defined in InitializeMPI()
Definition: global.h:163
int iFlgCalcSpec
Input parameter CalcSpec in teh CalcMod file.
Definition: struct.h:216
const char * c_GetTridiagonalEnd
Definition: LogMessage.c:67
char * fgetsMPI(char *InputString, int maxcount, FILE *fp)
MPI file I/O (get a line, fgets) wrapper. Only the root node (myrank = 0) reads and broadcast string...
Definition: wrapperMPI.c:122
const char * c_OutputSpectrumRecalcvecStart
Definition: LogMessage.c:70
struct CheckList Check
Size of the Hilbert space.
Definition: struct.h:411
char * CDataFileHead
Read from Calcmod in readdef.h. Header of output file such as Green&#39;s function.
Definition: struct.h:42
double eps_Lanczos
Definition: global.h:155
struct BindStruct Bind
Binded struct.
Definition: struct.h:420
int TimeKeeper(struct BindStruct *X, const char *cFileName, const char *cTimeKeeper_Message, const char *cWriteType)
Functions for writing a time log.
Definition: log.c:42
unsigned int Lanczos_max
Maximum number of iterations.
Definition: struct.h:74
FILE * stdoutMPI
File pointer to the standard output defined in InitializeMPI()
Definition: global.h:165