22 #include "wrapperMPI.hpp" 23 #include "common/setmemory.hpp" 25 #include "CalcSpectrum.hpp" 26 #include "mltplyCommon.hpp" 39 std::complex<double> *alpha,
40 std::complex<double> *beta,
41 std::complex<double> *dcomega,
42 std::complex<double> z_seed,
43 std::complex<double> **pBiCG,
44 std::complex<double> **res_proj,
45 std::complex<double> **pi,
46 std::complex<double> **dcSpectrum
48 int iomega, idcSpectrum;
49 std::complex<double> pi_2;
51 for (iomega = 0; iomega < Nomega; iomega++) {
53 if (lz_conv[iomega] == 1)
continue;
58 pi_2 = pi[iter - 2][iomega];
60 pi[iter][iomega] = (1.0 + alpha[iter] * (dcomega[iomega] - z_seed)) * pi[iter - 1][iomega]
61 - alpha[iter] * beta[iter] / alpha[iter - 1] * (pi_2 - pi[iter - 1][iomega]);
62 for (idcSpectrum = 0; idcSpectrum < NdcSpectrum; idcSpectrum++) {
63 pBiCG[iomega][idcSpectrum] = res_proj[iter][idcSpectrum] / pi[iter - 1][iomega]
64 + std::pow(pi_2 / pi[iter - 1][iomega], 2) * beta[iter] * pBiCG[iomega][idcSpectrum];
65 dcSpectrum[iomega][idcSpectrum] +=
66 pi[iter-1][iomega] / pi[iter][iomega] * alpha[iter] * pBiCG[iomega][idcSpectrum];
79 std::complex<double> *z_seed,
80 std::complex<double> *rho,
81 std::complex<double> *dcomega,
83 std::complex<double> **v2,
84 std::complex<double> **v3,
85 std::complex<double> **v4,
86 std::complex<double> **v5,
87 std::complex<double> **pi,
88 std::complex<double> *alpha,
89 std::complex<double> *beta,
90 std::complex<double> **res_proj
93 std::complex<double> pi_seed;
94 int iz_seed0, iomega, jter, idcSpectrum;
97 pi_min = std::abs(pi[iter][0]);
99 for (iomega = 0; iomega < Nomega; iomega++) {
100 if (lz_conv[iomega] == 0)
101 if (std::abs(pi[iter][iomega]) < pi_min) {
103 pi_min = std::abs(pi[iter][iomega]);
107 if (std::abs(pi[iter][iz_seed0]) < 1.0e-50) {
108 printf(
"Error : pi at seed is 0.");
112 if (iz_seed0 != *iz_seed) {
115 *z_seed = dcomega[iz_seed0];
117 *rho /= std::pow(pi[iter-1][iz_seed0], 2);
119 for (idim = 1; idim <= ndim; idim++) {
120 v2[idim][0] /= pi[iter][iz_seed0];
121 v4[idim][0] /= std::conj(pi[iter][iz_seed0]);
122 v3[idim][0] /= pi[iter-1][iz_seed0];
123 v5[idim][0] /= std::conj(pi[iter-1][iz_seed0]);
128 for (jter = 1; jter <= iter; jter++) {
129 alpha[jter] *= pi[jter - 1][iz_seed0] / pi[jter][iz_seed0];
131 beta[jter] *= std::pow(pi[jter - 2][iz_seed0] / pi[jter - 1][iz_seed0], 2);
132 for (idcSpectrum = 0; idcSpectrum < NdcSpectrum; idcSpectrum++) {
133 res_proj[jter][idcSpectrum] /= pi[jter - 1][iz_seed0];
137 for (jter = 1; jter <= iter; jter++) {
138 pi_seed = pi[jter][iz_seed0];
139 for (iomega = 0; iomega < Nomega; iomega++)
140 pi[jter][iomega] /= pi_seed;
158 std::complex<double> **v2,
159 std::complex<double> **v4,
162 std::complex<double> **dcSpectrum,
163 std::complex<double> *dcomega,
164 std::complex<double> **v1Org
167 char sdt[D_FileNameMax];
169 long int idim, i_max;
173 std::complex<double> rho = 1.0, rho_old, z_seed, alpha_denom;
174 int iomega, iter_old;
175 int iter, iz_seed = 0, *lz_conv;
176 double resnorm, dtmp[4];
177 std::complex<double> **vL, **v12, **v14, **v3, **v5,
178 *alpha, *beta, **res_proj, **pi, **pBiCG;
180 z_seed = dcomega[iz_seed];
181 fprintf(
stdoutMPI,
"##### Spectrum calculation with BiCG #####\n\n");
192 lz_conv = i_1d_allocate(Nomega);
199 fprintf(
stdoutMPI,
" Start: Input vectors for recalculation.\n");
200 TimeKeeper(&(X->
Bind),
"%s_TimeKeeper.dat",
"Input vectors for recalculation starts: %s",
"a");
204 fprintf(
stdoutMPI,
"INFO: File for the restart is not found.\n");
205 fprintf(
stdoutMPI,
" Start from SCRATCH.\n");
208 #pragma omp parallel for default(none) shared(v2,v4,v1Org,X) private(idim) 210 v4[idim][0] = v2[idim][0];
213 byte_size = fread(&iter_old,
sizeof(
int), 1, fp);
214 byte_size = fread(&i_max,
sizeof(i_max), 1, fp);
216 fprintf(stderr,
"Error: The size of the input vector is incorrect.\n");
220 byte_size = fread(&v2[0][0],
sizeof(std::complex<double>), X->
Bind.
Check.
idim_max + 1, fp);
221 byte_size = fread(&v3[0][0],
sizeof(std::complex<double>), X->
Bind.
Check.
idim_max + 1, fp);
222 byte_size = fread(&v4[0][0],
sizeof(std::complex<double>), X->
Bind.
Check.
idim_max + 1, fp);
223 byte_size = fread(&v5[0][0],
sizeof(std::complex<double>), X->
Bind.
Check.
idim_max + 1, fp);
225 fprintf(
stdoutMPI,
" End: Input vectors for recalculation.\n");
226 TimeKeeper(&(X->
Bind),
"%s_TimeKeeper.dat",
"Input vectors for recalculation finishes: %s",
"a");
227 if (byte_size == 0) printf(
"byte_size : %d\n", (
int)byte_size);
233 #pragma omp parallel for default(none) shared(v2,v4,v1Org,X) private(idim) 235 v4[idim][0] = v2[idim][0];
247 fprintf(
stdoutMPI,
"INFO: File for the restart is not found.\n");
248 fprintf(
stdoutMPI,
" Start from SCRATCH.\n");
251 fgetsMPI(ctmp,
sizeof(ctmp) /
sizeof(
char), fp);
252 sscanf(ctmp,
"%d", &iter_old);
259 pBiCG = cd_2d_allocate(Nomega, NdcSpectrum);
260 alpha[0] = std::complex<double>(1.0, 0.0);
261 beta[0] = std::complex<double>(0.0, 0.0);
262 for (iomega = 0; iomega < Nomega; iomega++) {
264 for (idcSpectrum = 0; idcSpectrum < NdcSpectrum; idcSpectrum++) {
265 pBiCG[iomega][idcSpectrum] = 0.0;
266 dcSpectrum[iomega][idcSpectrum] = 0.0;
273 fgetsMPI(ctmp,
sizeof(ctmp) /
sizeof(
char), fp);
274 sscanf(ctmp,
"%lf %lf\n", &dtmp[0], &dtmp[1]);
275 z_seed = std::complex<double>(dtmp[0], dtmp[1]);
278 while (
fgetsMPI(ctmp,
sizeof(ctmp) /
sizeof(
char), fp) != NULL) {
279 sscanf(ctmp,
"%lf %lf %lf %lf\n",
280 &dtmp[0], &dtmp[1], &dtmp[2], &dtmp[3]);
281 alpha[iter] = std::complex<double>(dtmp[0], dtmp[1]);
282 beta[iter] = std::complex<double>(dtmp[2], dtmp[3]);
283 for (idcSpectrum = 0; idcSpectrum < NdcSpectrum; idcSpectrum++)
284 sscanf(ctmp,
"%lf %lf\n", &dtmp[0], &dtmp[1]);
285 res_proj[iter][idcSpectrum] = std::complex<double>(dtmp[0], dtmp[1]);
290 for (iter = 1; iter <= iter_old; iter++) {
291 ShiftedEq(iter, Nomega, NdcSpectrum, lz_conv, alpha, beta, dcomega,
292 z_seed, pBiCG, res_proj, pi, dcSpectrum);
297 SeedSwitch(iter, Nomega, NdcSpectrum, lz_conv, &iz_seed,
299 pi, alpha, beta, res_proj);
303 for (iomega = 0; iomega < Nomega; iomega++)
304 if (std::abs(resnorm / pi[iter][iomega]) <
eps_Lanczos)
305 lz_conv[idcSpectrum] = 1;
311 fprintf(
stdoutMPI,
" Start: Calculate tridiagonal matrix components.\n");
312 TimeKeeper(&(X->
Bind),
"%s_TimeKeeper.dat",
"Calculating tridiagonal matrix components starts: %s",
"a");
313 fprintf(
stdoutMPI,
"\n Iteration Seed Residual-2-Norm\n");
326 for (idcSpectrum = 0; idcSpectrum < NdcSpectrum; idcSpectrum++) {
337 beta[iter] = std::complex<double>(0.0, 0.0);
339 beta[iter] = rho / rho_old;
342 v12[idim][0] = z_seed * v2[idim][0] - v12[idim][0];
343 v14[idim][0] = std::conj(z_seed) * v4[idim][0] - v14[idim][0];
346 - beta[iter] * rho / alpha[iter - 1];
348 if (std::abs(alpha_denom) < 1.0e-50) {
349 printf(
"Error : The denominator of alpha is zero.\n");
352 else if (std::abs(rho) < 1.0e-50) {
353 printf(
"Error : rho is zero.\n");
356 alpha[iter] = rho / alpha_denom;
360 ShiftedEq(iter, Nomega, NdcSpectrum, lz_conv, alpha, beta, dcomega,
361 z_seed, pBiCG, res_proj, pi, dcSpectrum);
366 v12[idim][0] = (1.0 + alpha[iter] * beta[iter] / alpha[iter-1]) * v2[idim][0]
367 - alpha[iter] * v12[idim][0]
368 - alpha[iter] * beta[iter] / alpha[iter-1] * v3[idim][0];
369 v3[idim][0] = v2[idim][0];
370 v2[idim][0] = v12[idim][0];
371 v14[idim][0] = (1.0 + std::conj(alpha[iter] * beta[iter] / alpha[iter-1])) * v4[idim][0]
372 - std::conj(alpha[iter]) * v14[idim][0]
373 - std::conj(alpha[iter] * beta[iter] / alpha[iter-1]) * v5[idim][0];
374 v5[idim][0] = v4[idim][0];
375 v4[idim][0] = v14[idim][0];
380 SeedSwitch(iter, Nomega, NdcSpectrum, lz_conv, &iz_seed,
382 pi, alpha, beta, res_proj);
388 for (iomega = 0; iomega < Nomega; iomega++)
389 if (std::abs(resnorm / pi[iter][iomega]) <
eps_Lanczos)
390 lz_conv[idcSpectrum] = 1;
392 fprintf(
stdoutMPI,
" %9d %9d %25.15e\n", iter, iz_seed, resnorm);
397 fprintf(
stdoutMPI,
"Remark : Not converged in iteration %d.", iter);
403 fprintf(
stdoutMPI,
" End: Calculate tridiagonal matrix components.\n\n");
404 TimeKeeper(&(X->
Bind),
"%s_TimeKeeper.dat",
"Calculating tridiagonal matrix components finishes: %s",
"a");
411 fprintf(fp,
"%d \n", iter_old);
412 fprintf(fp,
"%.10lf %.10lf\n", std::real(z_seed), std::imag(z_seed));
413 for (iter = 1; iter <= iter_old; iter++) {
414 fprintf(fp,
"%25.16le %25.16le %25.16le %25.16le\n",
415 std::real(alpha[iter]), std::imag(alpha[iter]),
416 std::real(beta[iter]), std::imag(beta[iter]));
417 for (idcSpectrum = 0; idcSpectrum < NdcSpectrum; idcSpectrum++)
418 fprintf(fp,
"%25.16le %25.16le\n",
419 std::real(res_proj[iter][idcSpectrum]),
420 std::imag(res_proj[iter][idcSpectrum]));
430 fprintf(
stdoutMPI,
" Start: Output vectors for recalculation.\n");
431 TimeKeeper(&(X->
Bind),
"%s_TimeKeeper.dat",
"Output vectors for recalculation starts: %s",
"a");
436 byte_size = fwrite(&iter,
sizeof(iter), 1, fp);
438 byte_size = fwrite(&v2[0][0],
sizeof(std::complex<double>), X->
Bind.
Check.
idim_max + 1, fp);
439 byte_size = fwrite(&v3[0][0],
sizeof(std::complex<double>), X->
Bind.
Check.
idim_max + 1, fp);
440 byte_size = fwrite(&v4[0][0],
sizeof(std::complex<double>), X->
Bind.
Check.
idim_max + 1, fp);
441 byte_size = fwrite(&v5[0][0],
sizeof(std::complex<double>), X->
Bind.
Check.
idim_max + 1, fp);
444 fprintf(
stdoutMPI,
" End: Output vectors for recalculation.\n");
445 TimeKeeper(&(X->
Bind),
"%s_TimeKeeper.dat",
"Output vectors for recalculation finishes: %s",
"a");
448 free_cd_1d_allocate(alpha);
449 free_cd_1d_allocate(beta);
450 free_cd_2d_allocate(res_proj);
451 free_cd_2d_allocate(pi);
452 free_cd_2d_allocate(pBiCG);
453 free_cd_2d_allocate(v3);
454 free_cd_2d_allocate(v5);
455 free_cd_2d_allocate(v12);
456 free_cd_2d_allocate(v14);
457 free_cd_2d_allocate(vL);
void exitMPI(int errorcode)
MPI Abortation wrapper.
struct DefineList Def
Definision of system (Hamiltonian) etc.
int GetExcitedState(struct BindStruct *X, int nstate, std::complex< double > **tmp_v0, std::complex< double > **tmp_v1, int iEx)
Parent function to calculate the excited state.
FILE * stdoutMPI
File pointer to the standard output defined in InitializeMPI()
int childfopenALL(const char *_cPathChild, const char *_cmode, FILE **_fp)
All processes open file in output/ directory.
double NormMPI_dc(long int idim, std::complex< double > *_v1)
Compute norm of process-distributed vector .
int mltply(struct BindStruct *X, int nstate, std::complex< double > **tmp_v0, std::complex< double > **tmp_v1)
Parent function of multiplying the wavefunction by the Hamiltonian. . First, the calculation of diago...
std::complex< double > VecProdMPI(long int ndim, std::complex< double > *v1, std::complex< double > *v2)
Compute conjugate scaler product of process-distributed vector .
void zclear(long int n, std::complex< double > *x)
clear std::complex<double> array.
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...
void ShiftedEq(int iter, int Nomega, int NdcSpectrum, int *lz_conv, std::complex< double > *alpha, std::complex< double > *beta, std::complex< double > *dcomega, std::complex< double > z_seed, std::complex< double > **pBiCG, std::complex< double > **res_proj, std::complex< double > **pi, std::complex< double > **dcSpectrum)
int Lanczos_max
Maximum number of iterations.
int myrank
Process ID, defined in InitializeMPI()
void SeedSwitch(int iter, int Nomega, int NdcSpectrum, int *lz_conv, int *iz_seed, std::complex< double > *z_seed, std::complex< double > *rho, std::complex< double > *dcomega, long int ndim, std::complex< double > **v2, std::complex< double > **v3, std::complex< double > **v4, std::complex< double > **v5, std::complex< double > **pi, std::complex< double > *alpha, std::complex< double > *beta, std::complex< double > **res_proj)
Perform Seed Switch.
int TimeKeeper(struct BindStruct *X, const char *cFileName, const char *cTimeKeeper_Message, const char *cWriteType)
Functions for writing a time log.
int iFlgCalcSpec
Input parameter CalcSpec in teh CalcMod file.
int CalcSpectrumByBiCG(struct EDMainCalStruct *X, std::complex< double > **v2, std::complex< double > **v4, int Nomega, int NdcSpectrum, std::complex< double > **dcSpectrum, std::complex< double > *dcomega, std::complex< double > **v1Org)
A main function to calculate spectrum by BiCG method In this function, the library is used...
struct CheckList Check
Size of the Hilbert space.
char * CDataFileHead
Read from Calcmod in readdef.h. Header of output file such as Green's function.
long int idim_max
The dimension of the Hilbert space of this process.
struct BindStruct Bind
Binded struct.
int childfopenMPI(const char *_cPathChild, const char *_cmode, FILE **_fp)
Only the root process open file in output/ directory.