Beispiel #1
0
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]);
}
Beispiel #2
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);
}
Beispiel #3
0
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);
}