LoginSignup
kisara11235
@kisara11235

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

計算がうまくできていない

Q&AClosed

解決したいこと

関数を呼び出しての計算がうまく行かない。
前の質問で変数の初期化をしなければならないという話だったので、そこを変更してみたが求めるような計算結果がえられない。

発生している問題・エラー

4.433201 
19.136448 
4.471029 
18.547600 
4.502804 
18.016253 
4.529414 
17.536604 
0.022275 
-0.009686 
0.023596 
-0.010184 
0.024577 
-0.010568 
0.025294 
-0.010863 
0.025810 
-0.011088 
0.026174 
-0.011258 

エラーとしては求める計算結果よりも大きすぎるものが出てしまう。

該当するソースコード

#define _USE_MATH_DEFINES
#include <stdio.h>
#include <math.h>
#include <complex.h>
#include <stdlib.h>

#define M  2	// 存在するサイト数   //M=24で5nmくらい
#define N  4	//サイト数×2 A+Bの個数
#define P  101	//リボン長 全電子数 P*
#define R  10

void zheev_( char*, char*, int*, double _Complex*,  int*, double*, double _Complex*, int*, double*, int* );
double f(double x, int j, int h, int k);
double g(double kai_ele[N][N]);

double u_up[P+1][N][N], u_dw[P+1][N][N];		//固有ベクトル
double u_up_1[P+1][N][N], u_dw_1[P+1][N][N];
double Energy_dw_1[P+1][N],Energy_up_1[P+1][N];   

int main(int argc, char** argv){
	FILE* fp;	
	FILE* fp_1;
    FILE* fp_2;
	FILE* fp_3;
	FILE* fp_4;

    double b_pi=M_PI;
	double U=1.0;		//相互作用エネルギーの平均(eV) u/t

    if ((fp = fopen("kai.txt", "w")) == NULL)
	{
		printf("Cannot open the file\n");
		exit(1);
	}
	fp_1 = fopen("u_dw.txt", "r");   
    if(fp_1 == NULL) {
        printf("ファイルを開くことが出来ませんでした.¥n");
    }
    for(int l=0; l<=P; l++){
		for(int i=0;i<N;i++){
			for(int j=0;j<N;j++){
				fscanf(fp_1, "%lf", &(u_dw[l][i][j]) );   	
			}
		} 
	}
	fp_2 = fopen("Energydw_1.txt", "r");   
    if(fp_2 == NULL) {
        printf("ファイルを開くことが出来ませんでした.¥n");
    }
    for(int l=0; l<=P; l++){
		for(int i=0;i<N;i++){
			fscanf(fp_2, "%lf", &(Energy_dw_1[l][i]) );   	
		} 
	}
    fp_3 = fopen("Energyup_1.txt", "r");   
    if(fp_3 == NULL) {
        printf("ファイルを開くことが出来ませんでした.¥n");
    }
    for(int l=0; l<=P; l++){
		for(int i=0;i<N;i++){
			fscanf(fp_3, "%lf", &(Energy_up_1[l][i]) );   	
		} 
	}
	fp_4 = fopen("u_up.txt", "r");   
    if(fp_4 == NULL) {
        printf("ファイルを開くことが出来ませんでした.¥n");
    }
    for(int l=0; l<=P; l++){
		for(int i=0;i<N;i++){
			for(int j=0;j<N;j++){
				fscanf(fp_4, "%lf", &(u_up[l][i][j]) );   	
			}
		} 
    }

	//二分法
	double x_start1 = 1.6;
    double x_start2 = 0.0;
    double err = 100.0;
    double a = x_start1;
    double b = x_start2;
    double c;

    for(int i=0;i<R;i++){
        double e=x_start1/R*i;
        for(int j=0;j<=P;j++){
			for(int h=0;h<N;h++){
				for(int k=0;k<N;k++){            
					// double fc=f(e,j);
					double kai_ele[N][N];
					kai_ele[h][k]=f(e,j,h,k);

					double gc=g(kai_ele);
            		fprintf(fp, "%2f %2f %2f\n",e,2*b_pi/P*j,gc/(P+1));
				}				
			}
        }
    }


    fclose(fp);	
 	fclose(fp_1);
    fclose(fp_2);
 	fclose(fp_3);	
	fclose(fp_4);
    return 0;
}

double f(double x, int j, int h, int k){  
	
	double kai;
	double kai_1[P+1][M][M],kai_1_dw[P+1][M][M],kai_1_up[P+1][M][M],kai_2[P+1][M],kai_3[P+1];

	for(int v=0;v<=P;v++){	//wavenumber
		for (int t=0;t<M;t++){	//valence
			for(int s=M;s<N;s++){	//conductive
				double Omega_up[P+1][M][M], Omega_dw[P+1][M][M];
				double U_up_plus[P+1][M][M], U_up_minus[P+1][M][M];
				double U_dw_plus[P+1][M][M], U_dw_minus[P+1][M][M];	
				
				Omega_up[v][t][s]=x-Energy_dw_1[v][s]+Energy_up_1[(v+j)%(P+1)][t];
				Omega_dw[v][t][s]=x+Energy_up_1[v][s]-Energy_dw_1[(v+j)%(P+1)][t];

				U_up_plus[v][t][s]=conj(u_up[v][t][k])*u_dw[(v+j)%(P+1)][s][k];
				U_up_minus[v][t][s]=conj(u_dw[(v+j)%(P+1)][s][h])*u_up[v][t][h];
				U_dw_plus[v][t][s]=conj(u_dw[v][t][k])*u_up[(v+j)%(P+1)][s][k];
				U_dw_minus[v][t][s]=conj(u_up[(v+j)%(P+1)][s][h])*u_dw[v][t][h];

				kai_1_up[v][t][s]=U_up_plus[v][t][s]*U_up_minus[v][t][s]/Omega_up[v][t][s];
				kai_1_dw[v][t][s]=U_dw_plus[v][t][s]*U_dw_minus[v][t][s]/Omega_dw[v][t][s];
				kai_1[v][t][s]=-kai_1_up[v][t][s]+kai_1_dw[v][t][s];

				kai_2[v][t]+=kai_1[v][t][s];
			}
			kai_3[v]+=kai_2[v][t];
		}	
		kai+=kai_3[v];
	}										
return kai;
}

double g(double kai_ele[N][N]){		
	double B[N];

    //感受率の対角化
                    // 複素行列(エルミート)の対角化 (入力行列の配列は対角化後にユニタリ行列になる)
                    char   jobz = 'V'           ;// 固有ベクトルを計算する
                    char   uplo = 'U'           ;// Aに上三角行列を格納
                    int    n    = N             ;// 対角化する正方行列のサイズ
                    double _Complex A[N*N]		;// 対角化する行列。対角化後は固有ベクトルが並ぶ

					for(int h=0;h<N;h++){
						for(int k=0;k<N;k++){
		                    A[N*h+k]=kai_ele[h][k];
						}
					}
					// fprintf(fp_1, "%2f %2f \n",A[N*k+h],kai[i][j][k][h]);
					// printf("%2f %2f\n",A[N*h+k],kai[h][k]);

                    double w[N]              	;// 実固有値が小さい順に入る
            
                    int    lda  = N	            ;// 対角化する正方行列のサイズ
                    double _Complex work[6*N]	;// 対角化する際に使用するメモリ
                    int    lwork = 6*N		    ;// workの次元
                    double rwork[3*N-2]      	;// 3*SIZE-2で固定
                    int    info                 ;// 成功すれば0、失敗すれば0以外を返す
  		            
                    zheev_( &jobz, &uplo, &n, A, &lda, w, work, &lwork, rwork, &info );
                        
                    for(int m=0;m<N;m++){
		            	B[m]=w[m];
		            }

                double kai_acc=B[N-1];

  return kai_acc;
}

自分で試したこと

関数fの引数を変えて計算したり、変数の宣言の場所を変えたり下が何がうまく行っていないのかよくわからないです。

環境についてはよくわかりませんが、
Ubuntu 20.04.5 LTS 
でコンパイルには  icc -qmkl -mcmodel=medium -shared-intel
を用いています。

0

2Answer

コンパイルには  icc -qmkl -mcmodel=medium -shared-intel
を用いています。

コンパイルオプションに-Wall -Wextraを追加しコンパイルし、出力される警告にまず対処されるべきでしょう。

2

Comments

  1. デバックしたいのであれば、できる限りprintfで変数の中身を出力してみてはいかがですか。

解決しました。具体的には変数の初期化でした。やはりそこが不十分でした。

@fujitanozomu様、アドバイスありがとうございました。

1

Your answer might help someone💌