示例#1
0
/* Tridiagonals solvers */
void solve_tridiag_qr(int n, double *D, double *E, char type){  if (type == 'N'){
    printf("Using PWK variant\n");
    int info = LAPACKE_dsterf(n, D, E);
    assert(!info);
  }
  else {
    double *Q = malloc(n*n*sizeof(double)); assert(Q);
    int info = LAPACKE_dsteqr(LAPACK_COL_MAJOR, type, n, D, E, Q, n);
    assert(!info);
    free(Q);
  }
}
示例#2
0
int main(){

	struct HamData *HD;
	HD = (struct HamData*)malloc(sizeof(struct HamData));
	HD-> num_points = 100.0; //num_points
	HD-> right_endpoint = 10.0; //right_endpoint formerly known as 'a'
	HD-> left_endpoint = -10.0; //left_endpoint formerly known as 'b'

	double integral = 0; 
	int num_points = HD-> num_points;
	int ii; 
	int jj;
	int kk; 
	int ll; 
	//double  elec_field[3] ={-.1,0,.1}; //this array sets the values that the electric field will take on. ex: -1*X(operator). 
	double e_field_max = 1.0; //upper & lower domain of the electric field. 
	double e_field_min = -1.0;
 
	//double p[3] = {0,0,0}; //initializing the polarization vector. 
	//int m = 3;  //this tells the giant for-loop how many times to go through and corresponds to the number of electric field values. 

	int row = 0; //setting the row value for the chebyshev differentiation matrix. 
	int col = 0; //setting the column value for the chebyshev differentiation matrix. 

	//************** INT M(AND THUS THE NUMBER OF VALUES FOR THE ELECTRIC FIELD) AND NUM_CHEBPOINTS MUST BE THE SAME***********
	double sum; 
	double green;
	double BETA = 0;

	//defining the constant alpha(for the laplacian) and num_chebpoints
	int num_chebpoints = 5; 
	double alpha = (pow(HD -> num_points + 1.0, 2.0)) / (pow(HD -> right_endpoint - HD -> left_endpoint,2.0)); 
	double omega = 1.0;
	int flag = 1.0; 
	int tag = 0;



//******************************************************************************************************

	double *main_diag; //main diagonal for the lapack solver
	main_diag = (double*)malloc(num_points*sizeof(double));

	double *sub_diag; //sub diag for the lapack solver(since this matrix is symetric the sub and super diagonals are the same. 
	sub_diag = (double*)malloc(num_points*sizeof(double));

	double *Z; // identity matrix for the lapacke solver 
	Z = (double*)malloc(num_points*num_points*sizeof(double));

	double *psi; //a place to store the first eigenvector.  
	psi = (double*)malloc(num_points*sizeof(double));

	double *cheb_points;//place to store the chebpoints 
	cheb_points = (double*)malloc(num_chebpoints*sizeof(double)); 

	double *elec_field; //place to store the electric field points which correspond to the chebpoints. 
	elec_field = (double*)malloc(num_chebpoints*sizeof(double)); 

	double *diff; //place to store the value of 
	diff = (double*)malloc(sizeof(double));

	double *polarization; //the polarization vector. 
	polarization = (double*)malloc(num_chebpoints*sizeof(double)); 

	//this assigns the electric field array chebpoints on the user defined e_min & e_max so that was it can vary the electric field using the chebyshev points. 
	cheb_array(num_chebpoints, &elec_field[0], e_field_max, e_field_min); 

	//for(ii<0;ii<num_chebpoints;ii++){
	//	printf("these are the chebpoints: %E \n", elec_field[ii]);
	//}



	//creating giant for loop in order to vary the electric field each time. **************
	for(kk=0;kk<num_chebpoints;kk++){

	//*****creating the hamiltonian*****
 
	lap_explicit(HD -> num_points, &main_diag[0], &sub_diag[0], alpha, 0);

	x_squared(HD -> num_points, HD-> left_endpoint, HD-> right_endpoint, &main_diag[0], omega, 1);

	E_field( HD -> num_points, HD -> left_endpoint, HD-> right_endpoint, &main_diag[0], elec_field[kk] , 1);

	//identity matrix(Z) Needed for lapack's eigen-solver(otherwise you won't get the correct values)    
	for(ii=0;ii<num_points;ii++)
	{
		for(jj=0;jj<num_points;jj++){
			if(ii == jj) {
				Z[ii*num_points+jj] = 1.0; 
				//printf("X[%d] = %+1.15e\n",ii,X[ii]);
			}
			else{
				Z[ii*num_points+jj] = 0.0; 
				//printf("X[%d] = %+1.15e\n",jj,X[jj]);
			}
		}
	}



	//Call 1-800-LA-PACKE for a free consulatation of eigenvalues and eigenvectors. 

	LAPACKE_dsteqr(LAPACK_COL_MAJOR,'I', num_points, main_diag, sub_diag, Z, num_points); 


	
	for(ii=0;ii<1;ii++){
	printf("first eigenvalue. %E \n", main_diag[ii]);
	}
	/*
	pick off the first eigenvector e.g. the ground state of the Hamiltonian. 
	for(ii=0;ii<num_points;ii++){
		//psi[ii] = Z[ii]; 




	printf("\nThis is Psi:\n");
	for(ii=0;ii<num_points;ii++){
		printf("Psi[%d] = %+1.15e\n",ii,psi[ii]);
	}
	printf("\n");/*/

	
	normalize_polarize(&Z[0] ,HD -> left_endpoint ,HD-> right_endpoint ,num_points ,&integral);

	polarization[kk] = integral; 

	//printf("The polarization: %1.1e \n", integral);	


}//end of the giant for loop creating the polarization vector.  **************


	for(kk=0;kk<num_chebpoints;kk++){
	printf("The polarization: %E \n", polarization[kk]);
	}


	//creating the array full of cheb_points. 
	//cheb_array(num_chebpoints, &cheb_points[0], e_field_max, e_field_min); 

	/*
	printf("These are the chebpoints: \n");
	for(ii=0;ii<num_chebpoints;ii++){
		printf("cheb_points[ii] = %+1.15e \n", cheb_points[ii]);
	}
	printf("\n");
	/*/
	//creating the first derivative chebyshev differentiation matrix. 
	green = chebdiff(row, col, num_chebpoints, &elec_field[0]); 

 	printf("this is D. %+1.15e \n",green);

	sum = chebdiff2(row, col, num_chebpoints, &elec_field[0]);


 	printf("this is D2 %+1.15e \n",sum);

	BETA = beta(num_chebpoints, &elec_field[0], &polarization[0]); //&elec_field[0] was &cheb_points[0]

	printf("this is beta %1.15e \n", BETA); 
	
	/*
	BETA = 0;

	BETA = beta(row, col, num_chebpoints, &elec_field[0], &polarization[0]);

	printf("This is beta %E \n", BETA); 
	/*/
	free(main_diag);
	free(sub_diag);
	free(cheb_points); 
	free(diff); 

	return 0; 
}