Esempio n. 1
0
PETSC_EXTERN void PETSC_STDCALL  epsgetinvariantsubspace_(EPS *eps,Vec *v, int *__ierr ){
*__ierr = EPSGetInvariantSubspace(*eps,v);
}
Esempio n. 2
0
/* Compute cyclicly eigenvalue */
PetscErrorCode Arnoldi(com_lsa * com, Mat * A, Vec  *v){
	EPS eps; /* eigensolver context */
	char  load_path[PETSC_MAX_PATH_LEN],export_path[PETSC_MAX_PATH_LEN];
	PetscInt end,first,validated;
	PetscErrorCode ierr;
	/* eigenvalues number is set to 100, can be changed if needed
	   we choosed to fix it because mallocs weren't working properly */
	PetscScalar eigenvalues[1000], ei, er;
	PetscReal re,im,vnorm;
	PetscInt eigen_nb,j,i,size,one=1, taille;
	Vec initialv,nullv,*vs;
	PetscBool flag,data_load,data_export,continuous_export,load_any;
	int exit_type=0, counter = 0, l;
	int sos_type = 911;
	Vec vecteur_initial;
	PetscViewer viewer;	


	PetscBool need_new_init = PETSC_FALSE, exit = PETSC_FALSE;

	sprintf(load_path,"./arnoldi.bin");
	sprintf(export_path,"./arnoldi.bin");
	
	PetscViewerCreate(PETSC_COMM_WORLD,&viewer);
//	 PetscViewerSetType(viewer,PETSCVIEWERBINARY);
	// if (skippheader) { PetscViewerBinarySetSkipHeader(viewer,PETSC_TRUE); }
//	 PetscViewerFileSetMode(viewer,FILE_MODE_WRITE);
//	 PetscViewerBinarySetUseMPIIO(viewer,PETSC_TRUE); 
// 	 PetscViewerFileSetName(viewer,"arnoldidbg.txt");

	/* create the eigensolver */
	ierr=EPSCreate(PETSC_COMM_WORLD,&eps);CHKERRQ(ierr);
	/* set the matrix operator */
	ierr=EPSSetOperators(eps,*A,PETSC_NULL);
	/* set options */
	ierr=EPSSetType(eps,EPSARNOLDI);
	ierr=EPSSetFromOptions(eps);CHKERRQ(ierr);
	
	/* duplicate vector properties */
	ierr=VecDuplicate(*v,&initialv);CHKERRQ(ierr);
	ierr=VecDuplicate(*v,&nullv);CHKERRQ(ierr);
	ierr=VecSet(nullv,(PetscScalar)0.0);CHKERRQ(ierr);
/*	ierr=VecSet(initialv,(PetscScalar)1.0);CHKERRQ(ierr);*/
	
	ierr=VecSetRandom(initialv,PETSC_NULL);//initialize initial vector to random
	ierr=VecGetSize(initialv,&size);CHKERRQ(ierr);

	ierr=PetscOptionsGetInt(PETSC_NULL,"-ksp_ls_eigen",&eigen_nb,&flag);CHKERRQ(ierr);
	if(!flag) eigen_nb=EIGEN_ALL;
	ierr=PetscOptionsGetString(PETSC_NULL,"-ksp_arnoldi_load",load_path,PETSC_MAX_PATH_LEN,&data_load);CHKERRQ(ierr);
	ierr=PetscOptionsGetString(PETSC_NULL,"-ksp_arnoldi_export",export_path,PETSC_MAX_PATH_LEN,&data_export);CHKERRQ(ierr);

	ierr=PetscOptionsHasName(PETSC_NULL,"-ksp_arnoldi_load_any",&load_any);CHKERRQ(ierr);
	ierr=PetscOptionsHasName(PETSC_NULL,"-ksp_arnoldi_cexport",&continuous_export);CHKERRQ(ierr);

	if(load_any) PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi loading default data file\n");
	PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi path in= %s out= %s\n",load_path,export_path);

	PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi allocating buffer of %d for invariant subspace\n",eigen_nb*2);
	vs=malloc(size*sizeof(Vec));
	for(i=0;i<size;i++){
		ierr=VecDuplicate(*v,&vs[i]);CHKERRQ(ierr);
	}
	ierr=VecDuplicate(initialv,&vecteur_initial);CHKERRQ(ierr);
/*	vecteur_initial = malloc(size * sizeof(PetscScalar));*/

	//	setting_out_vec_sizes( com, v);


	end=0;
	first=1;
	validated=1;
	while(!end){
		/*check if the program need to exit */
		if(exit == PETSC_TRUE)
			break;
		/* check if we received an exit message from Father*/
		if(!mpi_lsa_com_type_recv(com,&exit_type)){
		  if(exit_type==666){
		    end=1;
		    PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi Sending Exit message\n");
		    mpi_lsa_com_type_send(com,&exit_type);
		    break;
		  }
		}
		/* check if we received some data from GMRES		*/
		if(!mpi_lsa_com_vec_recv(com, &initialv)){
				VecGetSize(initialv, &taille);
/*				printf(" =========  %d I RECEIVED %d DATA FROM GMRES ============\n",com->rank_world, taille);*/
/*				ierr = VecCopy(vecteur_initial, initialv);*/
		}
/*		  */
/*		  if(!mpi_lsa_com_array_recv(com, &taille, vecteur_initial)){*/
/*			//	VecGetSize(initialv, &taille);*/
/*					printf(" =========  %d I RECEIVED %d DATA FROM GMRES ============\n",com->rank_world, taille);*/
/*					for (i = 0; i < taille; i++)*/
/*						PetscPrintf(PETSC_COMM_WORLD,"==== > arnoldi %d [%d] = %e\n",com->rank_world, i, vecteur_initial[i]);*/
/*		}  */
		
		for(j=0;j<eigen_nb;j++){
			eigenvalues[j]=(PetscScalar)0.0;
		}

		//FIXME: refactoriser les if suivants + flags file read, c'est très très moche
		if(data_load&&load_any){
		  load_any=PETSC_FALSE;
		  data_load=PETSC_TRUE;
		}
		  ierr = VecAssemblyBegin(initialv);CHKERRQ(ierr);
  		  ierr = VecAssemblyEnd(initialv);CHKERRQ(ierr);
	
		if(!(data_load^=load_any)){
		  ierr=EPSSetInitialSpace(eps,1,&initialv);CHKERRQ(ierr);
		} else {
/*				PetscPrintf(PETSC_COMM_WORLD,"==== > I AM LOADING DATA FROM FILE\n");*/
/*				PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi Reading file %s\n",load_path);*/
				ierr=readBinaryVecArray(load_path,(int*)one,&initialv);CHKERRQ(ierr);
				data_load=PETSC_FALSE;
				load_any=PETSC_FALSE;
				ierr=EPSSetInitialSpace(eps,1,&initialv);CHKERRQ(ierr);
/*				PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi Has Read file %s\n",load_path);*/
		}

		ierr=EPSSolve(eps);CHKERRQ(ierr);
		
				/*construct new initial vector*/
			ierr=EPSGetInvariantSubspace(eps, vs);CHKERRQ(ierr);
		++counter;

		/* get the number of guessed eigenvalues */
		ierr=EPSGetConverged(eps,&eigen_nb);CHKERRQ(ierr);

/* 		#ifdef DEBUG*/
/*		PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi %d converged eigenvalues\n",eigen_nb);*/
/* 		#endif*/

		/* send them */
		for(j=0;j<eigen_nb;j++){
			//EPSGetValue(eps,j,&er,&ei);
			//ierr = EPSGetEigenpair(eps,j,&er,&ei,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
			ierr = EPSGetEigenvalue(eps,j,&er,&ei);CHKERRQ(ierr);
			#ifdef PETSC_USE_COMPLEX
			  re=PetscRealPart(er);
			  im=PetscImaginaryPart(er);
			#else
			  re=er;
			  im=ei;
			#endif

			eigenvalues[j]=(PetscScalar)re+PETSC_i*(PetscScalar)im;


//	 		#ifdef DEBUG
				if(im!=0.0)
				  PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi %d/%d val : %e %e\n",j,eigen_nb,re,im);
				else
				  PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi  %d/%d val : %e\n",j,eigen_nb,er);
//			#endif

		}
		
/*		ierr=VecGetSize(initialv,&taille);CHKERRQ(ierr);*/
/*		PetscPrintf(PETSC_COMM_WORLD,"==== > OUR INITIALV IS OF SIZE %d\n", taille);*/
/*  		vecteur_initial = realloc(vecteur_initial,taille);  			*/
/*  		ierr=VecGetArray(initialv, &vecteur_initial);CHKERRQ(ierr);*/
/*		for (i = 0; i < taille; i++)*/
/*			PetscPrintf(PETSC_COMM_WORLD,"==== > initialv[%d] = %e\n", i, vecteur_initial[i]);*/
/*		ierr= VecRestoreArray(initialv, &vecteur_initial);CHKERRQ(ierr);*/
		
		if( eigen_nb != 0){
/*		#ifdef DEBUG*/
/*		PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi  Sending to LS\n");*/
/*		#endif*/
		/* send the data array */
		mpi_lsa_com_array_send(com, &eigen_nb, eigenvalues);
		
			/*construct new initial vector*/
/*			ierr=EPSGetInvariantSubspace(eps, vs);CHKERRQ(ierr);*/
			ierr=VecCopy(vs[0],initialv);CHKERRQ(ierr);
		
		
			for(j=1;j<eigen_nb;j++){
				ierr=VecAYPX(initialv,(PetscScalar)1.0,vs[j]);
			}
		
			ierr=VecNorm(initialv,NORM_2,&vnorm);CHKERRQ(ierr);
			ierr=VecAYPX(initialv,(PetscScalar)(1.0/vnorm),nullv);CHKERRQ(ierr);
				
	  		if(continuous_export){
/*		  		ierr=writeBinaryVecArray(data_export?export_path:"./arnoldi.bin", 1, &initialv);*/
			}
			if(!mpi_lsa_com_type_recv(com,&exit_type)){
   			if(exit_type==666){
		 			end=1;
		 			PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi Sending Exit message\n");

		 			mpi_lsa_com_type_send(com,&exit_type);
		 			need_new_init = PETSC_FALSE;
		 			exit = PETSC_TRUE;
					 break;
  				}	
			}
  		}else{
  			need_new_init = PETSC_TRUE;
			PetscPrintf(PETSC_COMM_WORLD, "!!! Arnoldi has not converged so we change the initial vector !!!\n"); 
 			while(need_new_init){
				// this was my first try to solve the poblem but it doesn't work better 
				/*ierr=VecSetRandom(initialv,PETSC_NULL);CHKERRQ(ier);*/
				// Now the best to do i think is to develop a kind of help from GMRES 
				// Arnoldi when no convergence observed will send a msg to GMRES like an SOS 
				//and GMRES will send a vector wich will be used to generate a new initial vector that make arnoldi converge **I HOPE **
  				//need_new_init = PETSC_TRUE
				// mpi_lsa_com_type_send(com,&sos_type); // here we send the message 
  				//	 ierr=VecDuplicate(initialv,&vec_tmp_receive);
  				//PetscPrintf(PETSC_COMM_WORLD, "!!! Arnoldi has not converged so we change the initial vector !!!\n");
  				 /* check if there's an incoming message */


				 if(!mpi_lsa_com_vec_recv(com, &initialv)){
/*					if(!mpi_lsa_com_array_recv(com, &taille, vecteur_initial)){*/

/*					printf(" =========   I RECEIVED SOME DATA FROM GMRES ============\n");*/
/*					ierr = VecCopy(vecteur_initial, initialv);*/
					need_new_init = PETSC_FALSE;
		     	 }else{
		     			if(!mpi_lsa_com_type_recv(com,&exit_type)){
			      			if(exit_type==666){
				    			end=1;
/*				    			PetscPrintf(PETSC_COMM_WORLD,"*} Arnoldi Sending Exit message\n");*/

				    			mpi_lsa_com_type_send(com,&exit_type);
				    			need_new_init = PETSC_FALSE;
				    			exit = PETSC_TRUE;
				   			 break;
				  				}
						}
      		 }
			//goto checking;
		     	//return 1;
		     }	
		     if(exit == PETSC_TRUE)
		     		break;		 
  		}
  		
  		// i will check it later 	
		
	}


/*	if(data_export){*/
/*	  ierr=writeBinaryVecArray(export_path, 1, &initialv);*/
/*	}*/


	for(i=0;i<eigen_nb;i++){
		ierr=VecDestroy(&(vs[i]));CHKERRQ(ierr);
	}
	
/*	ierr=PetscFree(vs);CHKERRQ(ierr);*/

	/* and destroy the eps */
	ierr=EPSDestroy(&eps);CHKERRQ(ierr);
	ierr=VecDestroy(&initialv);CHKERRQ(ierr);
	ierr=VecDestroy(&nullv);CHKERRQ(ierr);

	return 0;
}