double max_eigenvalues_bi(int * nr_of_eigenvalues, const int operator_flag, const int max_iterations, const double precision) { static bispinor * max_evs_ = NULL; static int allocated = 0; bispinor *temp_field, *temp_field_ = NULL, *aux, *aux_ = NULL; bispinor *copy_ev_, *copy_ev; /********************** * For Jacobi-Davidson **********************/ /* OLD VALUES HERE int verbosity = 5; */ int verbosity = g_debug_level, converged = 0, blocksize = 1, blockwise = 0; int solver_it_max = 50, j_max, j_min; /*int it_max = 10000;*/ complex *eigv_ = NULL, *eigv; double decay_min = 1.7, decay_max = 1.5, prec, threshold_min = 1.e-3, threshold_max = 5.e-2; static int v0dim = 0; /********************** * General variables **********************/ int returncode=0; int i, iVol, ix; FILE *conf_bifile=NULL; char * filename = NULL; char conf_bifilename[50]; double ev_time=0.0, av_time=0.0; filename = calloc(200, sizeof(char)); /* strcpy(filename,optarg);*/ if(g_proc_id == g_stdio_proc) printf("\nNumber of highest eigenvalues to compute = %d\n\n",(*nr_of_eigenvalues)); /* eigenvalues_for_cg_computed = 1; */ if(g_proc_id == g_stdio_proc) printf("Using Jacobi-Davidson method! \n"); if((*nr_of_eigenvalues) < 8){ j_max = 15; j_min = 8; } else{ j_max = 2*(*nr_of_eigenvalues); j_min = (*nr_of_eigenvalues); } /* RELAXED ACCURACY if(precision < 1.e-14){ prec = 1.e-14; } else{ */ prec = precision; /* REMEMBER TO CLOSE THE BRACKETS } */ /* g_mu = 0.00343; */ /* prec = 1.e-10; */ if(allocated == 0) { allocated = 1; #if (defined SSE || defined SSE2 || defined SSE3) max_evs_ = calloc((VOLUME)/2*(*nr_of_eigenvalues)+1, sizeof(bispinor)); max_evs = (bispinor *)(((unsigned long int)(max_evs_)+ALIGN_BASE)&~ALIGN_BASE); copy_ev_ = calloc((VOLUME)/2*(*nr_of_eigenvalues)+1, sizeof(bispinor)); copy_ev = (bispinor *)(((unsigned long int)(copy_ev_)+ALIGN_BASE)&~ALIGN_BASE); /* temp_field_ = calloc((VOLUMEPLUSRAND)/2+1, sizeof(spinor)); temp_field = (spinor *)(((unsigned long int)(temp_field_)+ALIGN_BASE)&~ALIGN_BASE); aux_ = calloc((VOLUMEPLUSRAND)/2+1, sizeof(spinor)); aux = (spinor *)(((unsigned long int)(aux_)+ALIGN_BASE)&~ALIGN_BASE); */ temp_field_ = calloc((VOLUME)/2+1, sizeof(bispinor)); temp_field = (bispinor *)(((unsigned long int)(temp_field_)+ALIGN_BASE)&~ALIGN_BASE); aux_ = calloc((VOLUME)/2+1, sizeof(bispinor)); aux = (bispinor *)(((unsigned long int)(aux_)+ALIGN_BASE)&~ALIGN_BASE); #else max_evs_= calloc((VOLUME)/2*(*nr_of_eigenvalues), sizeof(bispinor)); copy_ev_= calloc((VOLUME)/2*(*nr_of_eigenvalues), sizeof(bispinor)); temp_field_ = calloc((VOLUME)/2, sizeof(bispinor)); aux_ = calloc((VOLUME)/2, sizeof(bispinor)); max_evs = max_evs_; copy_ev = copy_ev_; temp_field = temp_field_; aux = aux_; #endif max_evls = (double*)malloc((*nr_of_eigenvalues)*sizeof(double)); } /* compute maximal eigenvalues */ if(g_proc_id==0) { printf(" Values of mu = %e mubar = %e eps = %e precision = %e \n \n", g_mu, g_mubar, g_epsbar, precision); } #ifdef MPI av_time = MPI_Wtime(); #endif DeltaTcd = 0.0; DeltaTtot = 0.0; /* Come secondo argomento, originariamente c`era (VOLUMEPLUSRAND)/2*sizeof(spinor)/sizeof(complex), */ /* THE VALUE IN THE SECOND LINE WAS 0 FOR MINIMAL EW , SET TO 50 FOR MAXIMAL EW */ #ifdef MPI pjdher((VOLUME)/2*sizeof(bispinor)/sizeof(complex), (VOLUME)/2*sizeof(bispinor)/sizeof(complex), 50., prec, (*nr_of_eigenvalues), j_max, j_min, max_iterations, blocksize, blockwise, v0dim, (complex*) max_evs, CG, solver_it_max, threshold_max, decay_max, verbosity, &converged, (complex*) max_evs, max_evls, &returncode, JD_MAXIMAL, 1, &Q_Qdagger_ND_BI); /* IN THE LAST LINE, INSERT: Q_Qdagger_ND_BI; Non-degenerate case - on 1 bispinor Q_Qdagger_ND; Non-degenerate case - on 2 spinors Qtm_pm_psi; Degenerate case - on 1 spinor */ #else jdher((VOLUME)/2*sizeof(bispinor)/sizeof(complex), 50., prec, (*nr_of_eigenvalues), j_max, j_min, max_iterations, blocksize, blockwise, v0dim, (complex*) max_evs, BICGSTAB, solver_it_max, threshold_max, decay_max, verbosity, &converged, (complex*) max_evs, max_evls, &returncode, JD_MAXIMAL, 1, &Q_Qdagger_ND_BI); /* IN THE LAST LINE, INSERT: Q_Qdagger_ND_BI; Non-degenerate case - on 1 bispinor Q_Qdagger_ND; Non-degenerate case - on 2 spinors Qtm_pm_psi; Degenerate case - on 1 spinor */ #endif (*nr_of_eigenvalues) = converged; v0dim = converged; /* printf(" Largest EV = %22.15e \n", max_evls[0]); */ #ifdef MPI ev_time = MPI_Wtime(); #endif DeltaTev = (ev_time - av_time); if(g_proc_id==0) { printf(" \n Now in maximal EW computation \n \n"); printf(" \n Elapsed time for comp-decomp in Q_Qdag_nd_bi = %f \n", DeltaTcd); printf(" \n Total elapsed time in Q_Qdag_nd_bi = %f \n", DeltaTtot); printf(" Number of S Matrix applications = %d \n", counter_Spsi); printf(" \n Total elapsed time in Eigenvalues computation = %f \n", DeltaTev); } free(max_evls); return(max_evls[0]); }
double eigenvalues(int * nr_of_eigenvalues, const int max_iterations, const double precision, const int maxmin, const int readwrite, const int nstore, const int even_odd_flag) { double returnvalue; complex norm2; #ifdef HAVE_LAPACK static spinor * eigenvectors_ = NULL; static int allocated = 0; char filename[200]; FILE * ofs; #ifdef MPI double atime, etime; #endif /********************** * For Jacobi-Davidson **********************/ int verbosity = g_debug_level, converged = 0, blocksize = 1, blockwise = 0; int solver_it_max = 50, j_max, j_min, ii, jj; /*int it_max = 10000;*/ /* complex *eigv_ = NULL, *eigv; */ double decay_min = 1.7, decay_max = 1.5, prec, threshold_min = 1.e-3, threshold_max = 5.e-2; /* static int v0dim = 0; */ int v0dim = 0; matrix_mult f; int N = (VOLUME)/2, N2 = (VOLUMEPLUSRAND)/2; spinor * max_eigenvector_ = NULL, * max_eigenvector; /********************** * General variables **********************/ int returncode=0; int returncode2=0; char eigenvector_prefix[512]; char eigenvalue_prefix[512]; no_eigenvalues = *nr_of_eigenvalues; sprintf(eigenvector_prefix,"eigenvector.%%s.%%.2d.%%.4d"); sprintf(eigenvalue_prefix,"eigenvalues.%%s.%%.4d"); if(!even_odd_flag) { N = (VOLUME); N2 = (VOLUMEPLUSRAND); f = &Q_pm_psi; } else { f = &Qtm_pm_psi; } evlength = N2; if(g_proc_id == g_stdio_proc && g_debug_level >0) { printf("Number of %s eigenvalues to compute = %d\n", maxmin ? "maximal" : "minimal",(*nr_of_eigenvalues)); printf("Using Jacobi-Davidson method! \n"); } if((*nr_of_eigenvalues) < 8){ j_max = 15; j_min = 8; } else{ j_max = 2*(*nr_of_eigenvalues); j_min = (*nr_of_eigenvalues); } if(precision < 1.e-14){ prec = 1.e-14; } else{ prec = precision; } #if (defined SSE || defined SSE2 || defined SSE3) max_eigenvector_ = calloc(N2+1, sizeof(spinor)); max_eigenvector = (spinor *)(((unsigned long int)(max_eigenvector_)+ALIGN_BASE)&~ALIGN_BASE); #else max_eigenvector_= calloc(N2, sizeof(spinor)); max_eigenvector = max_eigenvector_; #endif if(allocated == 0) { allocated = 1; #if (defined SSE || defined SSE2 || defined SSE3) eigenvectors_ = calloc(N2*(*nr_of_eigenvalues)+1, sizeof(spinor)); eigenvectors = (spinor *)(((unsigned long int)(eigenvectors_)+ALIGN_BASE)&~ALIGN_BASE); #else eigenvectors_= calloc(N2*(*nr_of_eigenvalues), sizeof(spinor)); eigenvectors = eigenvectors_; #endif eigenvls = (double*)malloc((*nr_of_eigenvalues)*sizeof(double)); inv_eigenvls = (double*)malloc((*nr_of_eigenvalues)*sizeof(double)); } solver_it_max = 50; /* compute the maximal one first */ jdher(N*sizeof(spinor)/sizeof(complex), N2*sizeof(spinor)/sizeof(complex), 50., 1.e-12, 1, 15, 8, max_iterations, 1, 0, 0, NULL, CG, solver_it_max, threshold_max, decay_max, verbosity, &converged, (complex*) max_eigenvector, (double*) &max_eigenvalue, &returncode2, JD_MAXIMAL, 1, f); if(readwrite) { if(even_odd_flag){ for(v0dim = 0; v0dim < (*nr_of_eigenvalues); v0dim++) { sprintf(filename, eigenvector_prefix , maxmin ? "max" : "min", v0dim, nstore); if((read_eospinor(&eigenvectors[v0dim*N2], filename)) != 0) { break; } } } else { FILE *testfile; spinor *s; double sqnorm; for(v0dim = 0; v0dim < (*nr_of_eigenvalues); v0dim++) { sprintf(filename, eigenvector_prefix, maxmin ? "max" : "min", v0dim, nstore); printf("reading eigenvectors ... "); testfile=fopen(filename,"r"); if( testfile != NULL){ fclose(testfile); s=(spinor*)&eigenvectors[v0dim*N2]; read_spinor(s,NULL, filename,0); sqnorm=square_norm(s,VOLUME,1); printf(" has | |^2 = %e \n",sqnorm); } else { printf(" no more eigenvectors \n"); break; } } } } if(readwrite != 2) { #ifdef MPI atime = MPI_Wtime(); #endif /* (re-) compute minimal eigenvalues */ converged = 0; solver_it_max = 200; if(maxmin) jdher(N*sizeof(spinor)/sizeof(complex), N2*sizeof(spinor)/sizeof(complex), 50., prec, (*nr_of_eigenvalues), j_max, j_min, max_iterations, blocksize, blockwise, v0dim, (complex*) eigenvectors, CG, solver_it_max, threshold_max, decay_max, verbosity, &converged, (complex*) eigenvectors, eigenvls, &returncode, JD_MAXIMAL, 1, f); else jdher(N*sizeof(spinor)/sizeof(complex), N2*sizeof(spinor)/sizeof(complex), 0., prec, (*nr_of_eigenvalues), j_max, j_min, max_iterations, blocksize, blockwise, v0dim, (complex*) eigenvectors, CG, solver_it_max, threshold_min, decay_min, verbosity, &converged, (complex*) eigenvectors, eigenvls, &returncode, JD_MINIMAL, 1, f); #ifdef MPI etime = MPI_Wtime(); if(g_proc_id == 0) { printf("Eigenvalues computed in %e sec. (MPI_Wtime)\n", etime-atime); } #endif } else { sprintf(filename, eigenvalue_prefix, maxmin ? "max" : "min", nstore); if((ofs = fopen(filename, "r")) != (FILE*) NULL) { for(v0dim = 0; v0dim < (*nr_of_eigenvalues); v0dim++) { fscanf(ofs, "%d %lf\n", &v0dim, &eigenvls[v0dim]); if(feof(ofs)) break; converged = v0dim; } } fclose(ofs); } (*nr_of_eigenvalues) = converged; no_eigenvalues = converged; ev_minev = eigenvls[(*nr_of_eigenvalues)-1]; eigenvalues_for_cg_computed = converged; for (ii = 0; ii < (*nr_of_eigenvalues); ii++){ for (jj = 0; jj <= ii; jj++){ norm2 = scalar_prod(&(eigenvectors[ii*N2]),&(eigenvectors[jj*N2]), VOLUME, 1); if(ii==jj){ if((fabs(1.-norm2.re)>1e-12) || (fabs(norm2.im)>1e-12) || 1) { if(g_proc_id == g_stdio_proc){ printf("< %d | %d> =\t %e +i * %e \n", ii+1, jj+1, norm2.re, norm2.im); fflush(stdout); } } } else{ if((fabs(norm2.re)>1e-12) || (fabs(norm2.im)>1e-12) || 1) { if(g_proc_id == g_stdio_proc){ printf("< %d | %d> =\t %e +i * %e \n", ii+1, jj+1, norm2.re, norm2.im); fflush(stdout); } } } } } if(readwrite == 1 ) { if(even_odd_flag) for(v0dim = 0; v0dim < (*nr_of_eigenvalues); v0dim++) { sprintf(filename, eigenvector_prefix, maxmin ? "max" : "min", v0dim, nstore); if((write_eospinor(&eigenvectors[v0dim*N2], filename, eigenvls[v0dim], prec, nstore)) != 0) { break; } } else{ WRITER *writer=NULL; spinor *s; double sqnorm; paramsPropagatorFormat *propagatorFormat = NULL; for(v0dim = 0; v0dim < (*nr_of_eigenvalues); v0dim++) { sprintf(filename, eigenvector_prefix, maxmin ? "max" : "min", v0dim, nstore); construct_writer(&writer, filename, 0); /* todo write propagator format */ propagatorFormat = construct_paramsPropagatorFormat(64, 1); write_propagator_format(writer, propagatorFormat); free(propagatorFormat); s=(spinor*)&eigenvectors[v0dim*N2]; write_spinor(writer, &s,NULL, 1, 64); destruct_writer(writer); writer=NULL; sqnorm=square_norm(s,VOLUME,1); printf(" wrote eigenvector | |^2 = %e \n",sqnorm); } } } if(g_proc_id == 0 && readwrite != 2) { sprintf(filename, eigenvalue_prefix , maxmin ? "max" : "min", nstore); ofs = fopen(filename, "w"); for(v0dim = 0; v0dim < (*nr_of_eigenvalues); v0dim++) { fprintf(ofs, "%d %e\n", v0dim, eigenvls[v0dim]); } fclose(ofs); } for(v0dim = 0; v0dim < converged; v0dim++) { inv_eigenvls[v0dim] = 1./eigenvls[v0dim]; } ev_qnorm=1.0/(sqrt(max_eigenvalue)+0.1); ev_minev*=ev_qnorm*ev_qnorm; /* ov_n_cheby is initialized in Dov_psi.c */ returnvalue=eigenvls[0]; free(max_eigenvector_); #else fprintf(stderr, "lapack not available, so JD method for EV computation not available \n"); #endif return(returnvalue); }
void index_jd(int * nr_of_eigenvalues_ov, const int max_iterations, const double precision_ov, char *conf_filename, const int nstore, const int method){ complex *eval; spinor *eigenvectors_ov, *eigenvectors_ov_; spinor *lowvectors, *lowvectors_; int i=0 , k=0, returncode=0, index = 0, determined = 0, signed_index = 0; char filename[120]; FILE * ifs = NULL; matrix_mult Operator[2]; double absdifference; const int N2 = VOLUMEPLUSRAND; #ifdef MPI double atime, etime; #endif double lowestmodes[20]; int intsign, max_iter, first_blocksize = 1; int * idx = NULL; /********************** * For Jacobi-Davidson **********************/ int verbosity = 3, converged = 0, blocksize = 1, blockwise = 0; int solver_it_max = 50, j_max, j_min, v0dim = 0; double * eigenvalues_ov = NULL; double decay_min = 1.7, threshold_min = 1.e-3, prec; WRITER *writer=NULL; spinor *s; double sqnorm; paramsPropagatorFormat *propagatorFormat = NULL; double ap_eps_sq; int switch_on_adaptive_precision = 0; double ov_s = 0; /********************** * General variables **********************/ eval= calloc((*nr_of_eigenvalues_ov),sizeof(complex)); shift = 0.0; // ov_s = 0.5*(1./g_kappa - 8.) - 1.; ap_eps_sq = precision_ov*precision_ov; #if (defined SSE || defined SSE2 ) eigenvectors_ov_= calloc(VOLUMEPLUSRAND*(*nr_of_eigenvalues_ov)+1, sizeof(spinor)); eigenvectors_ov = (spinor *)(((unsigned long int)(eigenvectors_ov_)+ALIGN_BASE)&~ALIGN_BASE); lowvectors_ = calloc(2*first_blocksize*VOLUMEPLUSRAND+1, sizeof(spinor)); lowvectors = (spinor *)(((unsigned long int)(lowvectors_)+ALIGN_BASE)&~ALIGN_BASE); #else // eigenvectors_ov_ = calloc(VOLUMEPLUSRAND*(*nr_of_eigenvalues_ov), sizeof(spinor)); eigenvectors_ov_ = calloc(VOLUMEPLUSRAND*(*nr_of_eigenvalues_ov), sizeof(spinor)); lowvectors_ = calloc(2*first_blocksize*VOLUMEPLUSRAND, sizeof(spinor)); eigenvectors_ov = eigenvectors_ov_; lowvectors = lowvectors_; #endif // idx = malloc((*nr_of_eigenvalues_ov)*sizeof(int)); idx = malloc((*nr_of_eigenvalues_ov)*sizeof(int)); Operator[0]=&Dov_proj_plus; Operator[1]=&Dov_proj_minus; if(g_proc_id == g_stdio_proc){ printf("Computing first the two lowest modes in the positive and negative chirality sector, respectively\n"); if(switch_on_adaptive_precision == 1) { printf("We have switched on adaptive precision with ap_eps_sq = %e!\n", ap_eps_sq); } printf("We have set the mass to zero within this computation!\n"); fflush(stdout); } prec = precision_ov; j_min = 8; j_max = 16; max_iter = 70; #ifdef MPI atime = MPI_Wtime(); #endif v0dim = first_blocksize; blocksize = v0dim; for(intsign = 0; intsign < 2; intsign++){ converged = 0; if(g_proc_id == g_stdio_proc){ printf("%s chirality sector: \n", intsign ? "negative" : "positive"); fflush(stdout); } if(max_iter == 70){ /******************************************************************** * * We need random start spinor fields, but they must be half zero, * that's why we apply the Projektor once * ********************************************************************/ for(i = 0; i < first_blocksize; i++) { random_spinor_field(&lowvectors[(first_blocksize*intsign+i)*VOLUMEPLUSRAND],N2,0); Proj(&lowvectors[(first_blocksize*intsign+i)*VOLUMEPLUSRAND], &lowvectors[(first_blocksize*intsign+i)*VOLUMEPLUSRAND],N2, intsign); } } jdher(VOLUME*sizeof(spinor)/sizeof(complex), VOLUMEPLUSRAND*sizeof(spinor)/sizeof(complex), shift, prec, blocksize, j_max, j_min, max_iter, blocksize, blockwise, v0dim, (complex*) &lowvectors[first_blocksize*intsign*VOLUMEPLUSRAND], CG, solver_it_max, threshold_min, decay_min, verbosity, &converged, (complex*) &lowvectors[first_blocksize*intsign*VOLUMEPLUSRAND], &lowestmodes[first_blocksize*intsign], &returncode, JD_MINIMAL, 1, Operator[intsign]); if(converged != blocksize && max_iter == 70){ if(g_proc_id == g_stdio_proc){ printf("Restarting %s chirality sector with more iterations!\n", intsign ? "negative" : "positive"); fflush(stdout); } max_iter = 140; intsign-=1; } else { max_iter = 70; /* Save the allready computed eigenvectors_ov */ for(i = 0; i< first_blocksize; i++) { sprintf(filename, "eigenvector_of_D%s.%.2d.%s.%.4d",((intsign==0)?"plus":"minus"),i , conf_filename, nstore); construct_writer(&writer, filename, 0); /* todo write propagator format */ propagatorFormat = construct_paramsPropagatorFormat(64, 1); write_propagator_format(writer, propagatorFormat); free(propagatorFormat); s=(spinor*)&lowvectors[first_blocksize*intsign*VOLUMEPLUSRAND]; write_spinor(writer, &s,NULL, 1, 64); destruct_writer(writer); writer=NULL; sqnorm=square_norm(s,VOLUME,1); printf(" wrote eigenvector of overlap operator !!! | |^2 = %e \n",sqnorm); } } } #ifdef MPI etime = MPI_Wtime(); if(g_proc_id == g_stdio_proc){ printf("It took %f sec to determine the sector with zero modes, if any!\n", etime-atime); } #endif /*Compare the two lowest modes */ absdifference = fabs(lowestmodes[0]-lowestmodes[first_blocksize]); if(absdifference < 0.1*max(lowestmodes[0],lowestmodes[first_blocksize])){ /* They are equal within the errors */ if(g_proc_id == g_stdio_proc){ printf("Index is 0!\n"); fflush(stdout); sprintf(filename, "eigenvalues_of_overlap_proj.%s.%.4d", conf_filename, nstore); ifs = fopen(filename, "w"); printf("\nThe following lowest modes have been computed:\n"); fprintf(ifs, "Index is 0\n\n"); fprintf(ifs, "Sector with positive chirality:\n"); for(i = 0; i < first_blocksize; i++) { lowestmodes[i] = 2.*(1.+ov_s)*lowestmodes[i]; fprintf(ifs, "%d %e positive\n", i, lowestmodes[i]); printf("%d %e positive\n", i, lowestmodes[i]); } fprintf(ifs, "Sector with negative chirality:\n"); for(i = 0; i < first_blocksize; i++) { lowestmodes[i+first_blocksize] = 2.*(1.+ov_s)*lowestmodes[i+first_blocksize]; fprintf(ifs, "%d %e negative\n", i, lowestmodes[i+first_blocksize]); printf("%d %e negative\n", i, lowestmodes[i+first_blocksize]); } fclose(ifs); for(k = 0; k < 2; k++) { sprintf(filename, "eigenvalues_of_D%s.%s.%.4d", k ? "minus" : "plus", conf_filename, nstore); ifs = fopen(filename, "w"); fwrite(&first_blocksize, sizeof(int), 1, ifs); index = 0; fwrite(&index, sizeof(int), 1, ifs); for(i = 0; i < first_blocksize; i++) { fwrite(&lowestmodes[((intsign+1)%2)*first_blocksize+i], sizeof(double), 1, ifs); } fclose(ifs); } } } else{ /* they are not equal */ /* determine the sector with not trivial topology */ if(lowestmodes[0] < lowestmodes[first_blocksize]){ intsign = 0; } else{ intsign = 1; } if(g_proc_id == g_stdio_proc){ printf("Computing now up to %d modes in the sector with %s chirality\n", (*nr_of_eigenvalues_ov), intsign ? "negative" : "positive"); fflush(stdout); } /* Here we set the (absolute) precision to be */ /* such that we can compare to the lowest mode */ /* in the other sector */ prec = (lowestmodes[first_blocksize*((intsign+1)%2)])*1.e-1; eigenvalues_ov = (double*)malloc((*nr_of_eigenvalues_ov)*sizeof(double)); /* Copy the allready computed eigenvectors_ov */ for(i = 0; i < first_blocksize; i++) { assign(&eigenvectors_ov[i], &lowvectors[(first_blocksize*intsign+i)*VOLUMEPLUSRAND],N2); eigenvalues_ov[i] = lowestmodes[first_blocksize*intsign+i]; } #ifdef MPI atime = MPI_Wtime(); #endif blocksize = 3; j_min = 8; j_max = 16; converged = first_blocksize; for(i = first_blocksize; i < (*nr_of_eigenvalues_ov); i+=3) { if((i + blocksize) > (*nr_of_eigenvalues_ov) ) { blocksize = (*nr_of_eigenvalues_ov) - i; } /* Fill up the rest with random spinor fields */ /* and project it to the corresponding sector */ for(v0dim = i; v0dim < i+blocksize; v0dim++){ random_spinor_field(&eigenvectors_ov[v0dim*VOLUMEPLUSRAND],N2,0); Proj(&eigenvectors_ov[v0dim*VOLUMEPLUSRAND], &eigenvectors_ov[v0dim*VOLUMEPLUSRAND],N2, intsign); } v0dim = blocksize; returncode = 0; /* compute minimal eigenvalues */ #ifdef MPI /* pjdher(VOLUME*sizeof(spinor)/sizeof(complex), VOLUMEPLUSRAND*sizeof(spinor)/sizeof(complex), shift, prec, omega, n_omega, ev_tr, i+blocksize, j_max, j_min, max_iterations, blocksize, blockwise, v0dim, (complex*)(&eigenvectors_ov[i*VOLUMEPLUSRAND]), CG, solver_it_max, threshold_min, decay_min, verbosity, &converged, (complex*) eigenvectors_ov, eigenvalues_ov, &returncode, JD_MINIMAL, 1, use_AV, Operator[intsign]);*/ #else jdher(VOLUME*sizeof(spinor)/sizeof(complex), VOLUMEPLUSRAND*sizeof(spinor)/sizeof(complex), shift, prec, blocksize, j_max, j_min, max_iter, blocksize, blockwise, v0dim, (complex*) &eigenvectors_ov[i*VOLUMEPLUSRAND], CG, solver_it_max, threshold_min, decay_min, verbosity, &converged, (complex*) eigenvectors_ov, eigenvalues_ov, &returncode, JD_MINIMAL, 1, Operator[intsign]); #endif /* Save eigenvectors_ov temporary */ /* in order to be able to restart */ for (k=i; k < converged; k++){ if(intsign == 0){ sprintf(filename, "eigenvector_of_Dplus.%.2d.%s.%.4d", k, conf_filename, nstore); } else{ sprintf(filename, "eigenvector_of_Dminus.%.2d.%s.%.4d", k, conf_filename, nstore); } /* write_spinorfield(&eigenvectors_ov[k*VOLUMEPLUSRAND], filename);*/ } /* order the eigenvalues_ov and vectors */ for(k = 0; k < converged; k++) { idx[k] = k; } /* quicksort(converged, eigenvalues_ov, idx);*/ /* Check whether the index is detemined */ index = 0; for(k = 0; k < converged; k++) { absdifference = fabs(lowestmodes[first_blocksize*((intsign+1)%2)] - eigenvalues_ov[k]); if(absdifference < 0.1*lowestmodes[first_blocksize*((intsign+1)%2)]) { /* We have found the first non zero */ if(k < converged-1) { determined = 1; break; } else { blocksize = 1; shift = eigenvalues_ov[converged-1]; } } else { index++; } } /* If we have determined the index or */ /* hit the maximal number of ev */ if(determined == 1 || converged == (*nr_of_eigenvalues_ov)) { break; } else if(g_proc_id == g_stdio_proc) { if(blocksize != 1) { printf("Index %s (or equal) than %s%d, continuing!\n\n", intsign ? "lower" : "bigger", intsign ? "-" : "+", index); fflush( stdout ); } else { printf("Index is %s%d, one non zero is missing, continuing!\n\n", intsign ? "-" : "+", index); fflush( stdout ); } } } #ifdef MPI etime = MPI_Wtime(); #endif /* Save the eigenvectors_ov */ for(i = 0; i < converged; i++){ eval[i].re = 2.*(1.+ov_s)*eigenvalues_ov[i]; eval[i].im = 0.; if(intsign == 0){ sprintf(filename, "eigenvector_of_Dplus.%.2d.%s.%.4d", i, conf_filename, nstore); } else{ sprintf(filename, "eigenvector_of_Dminus.%.2d.%s.%.4d", i, conf_filename, nstore); } /* write_spinorfield(&eigenvectors_ov[idx[i]*VOLUMEPLUSRAND], filename);*/ } /* Some Output */ if(g_proc_id == g_stdio_proc) { printf("Index is %s%d!\n", intsign ? "-" : "+", index); #ifdef MPI printf("Zero modes determined in %f sec!\n", etime-atime); #endif } if(g_proc_id == 0) { sprintf(filename, "eigenvalues_of_overlap_proj.%s.%.4d", conf_filename, nstore); ifs = fopen(filename, "w"); printf("\nThe following lowest modes have been computed:\n"); fprintf(ifs, "Index is %s%d!\n\n", intsign ? "-" : "+", index); for(k = 0; k < 2; k++) { if(k == intsign) { for (i=0; i < converged; i++) { fprintf(ifs, "%d %e %s\n", i, eval[i].re, intsign ? "negative" : "positive"); printf("%d %e %s\n", i, eval[i].re, intsign ? "negative" : "positive"); } } else { for(i = 0; i < first_blocksize; i++) { lowestmodes[((intsign+1)%2)*first_blocksize+i] = 2.*(1.+ov_s)*lowestmodes[((intsign+1)%2)*first_blocksize+i]; fprintf(ifs, "%d %e %s\n", i, lowestmodes[((intsign+1)%2)*first_blocksize+i], intsign ? "positive" : "negative"); printf("%d %e %s\n", i, lowestmodes[((intsign+1)%2)*first_blocksize+i], intsign ? "positive" : "negative"); } } } fclose(ifs); if(intsign != 0) signed_index = -index; else signed_index = index; for(k = 0; k < 2; k++) { sprintf(filename, "eigenvalues_of_D%s.%s.%.4d", k ? "minus" : "plus", conf_filename, nstore); ifs = fopen(filename, "w"); if(k == intsign) { fwrite(&converged, sizeof(int), 1, ifs); fwrite(&signed_index, sizeof(int), 1, ifs); for (i=index; i < converged; i++) { fwrite(&eval[i].re, sizeof(double), 1, ifs); } } else { fwrite(&first_blocksize, sizeof(int), 1, ifs); fwrite(&signed_index, sizeof(int), 1, ifs); for(i = 0; i < first_blocksize; i++) { fwrite(&lowestmodes[((intsign+1)%2)*first_blocksize+i], sizeof(double), 1, ifs); } } fclose(ifs); } } } switch_on_adaptive_precision = 0; /* Free memory */ free(eigenvectors_ov_); free(lowvectors_); free(eval); free(eigenvalues_ov); free(idx); }