/*===========================*/ /* gccFRAME_GAL.c */ /*===========================*/ #include #include #include #include #include #define NDmax 500 /*最大節点数*/ #define NEmax 500 /*最大要素数*/ #define MAmax 10 /*最大材料種別数*/ #define NTmax NDmax*3+1 /*最大自由度数*/ int main_part(char fnameR[50],char fnameW[50],int kprog,double coefAB,double deltaS0,double coefS,int maxload); double CAL_LAM01(int nt,double deltaS,double Spara,double dis0[NTmax+1],double df[NTmax+1]); double CAL_LAM02(int nt,double deltaS,double coefAB,double *Spara,double dis0[NTmax+1],double df[NTmax+1]); double CAL_LAMNEW(int nt,double Spara,double dis0[NTmax+1],double disr[NTmax+1],double df[NTmax+1]); void DATAOUT(char fnameW[50],int NODT,int NELT, int iload,int itaration,int nocon,double deltaS,double lam,double dtest,double ftest, double x[NDmax+1],double y[NDmax+1],double dist[NTmax+1], double ff[NTmax+1],double ftvec[NTmax+1],double reforce[NEmax+1][7]); void FRAMESM(int ne,int kakom[NEmax+1][3],double x[NDmax+1],double y[NDmax+1],double dist[NTmax+1], double Em[NEmax+1],double AA[NEmax+1],double AI[NEmax+1],double reforce[NEmax+1][7],double sm[7][7]); void ELMSM(int ne,double xx1,double yy1,double xx2,double yy2, double Em[NEmax+1],double AA[NEmax+1],double AI[NEmax+1],double sme[7][7]); void CALST(int ne, int kakom[NEmax+1][3], double x[NDmax+1],double y[NDmax+1],double dis[NTmax+1], double dist[NTmax+1],double Em[NEmax+1],double AA[NEmax+1],double AI[NEmax+1],double fevec[7],double reforce[NEmax+1][7]); void ROTATE(int ne, int kakom[NEmax+1][3], double x[NDmax+1],double y[NDmax+1], double dis[NTmax+1],double dist[NTmax+1],double *deltai,double *deltaj); void HENMX(int ne,double xx1,double yy1,double xx2,double yy2,double hen[7][7]); void ASMAT(int ne,int nod,int nhen,int kakom[NEmax+1][3],double sm[7][7],double tsm[NTmax+1][NTmax+1]); void ASVEC(int ne,int nod,int nhen,int kakom[NEmax+1][3],double fevec[7],double ftvec[NTmax+1]); int CHBAND10(int n1,int m1,double array[NTmax+1][NTmax+1]); void CHBAND11(int n1,int m1,double array[NTmax+1][NTmax+1],double vector[NTmax+1]); int IBAND(int mm,double array[NTmax+1][NTmax+1],double fact0); void BAND(int mm,int ib,double array[NTmax+1][NTmax+1]); int MATINV(int n,double ary[NTmax+1][NTmax+1]); /*--------------------------------------------------------------------------------*/ int main(int argc, char* argv[]) { char fnameR[50]; /*入力ファイル名*/ char fnameW[50]; /*出力ファイル名*/ int kprog; /*第一中間点設定方法(1:方法1,2:方法2)*/ double coefAB; /*スケーリングパラメータ算定用係数*/ double deltaS0; /*弧長増分法パラメータ(初期弧長)*/ double coefS; /*弧長に乗じる係数*/ int maxload; /*荷重増分数最大値*/ strcpy(fnameR,argv[1]); strcpy(fnameW,argv[2]); kprog =atoi(argv[3]); coefAB =atof(argv[4]); deltaS0 =atof(argv[5]); coefS =atof(argv[6]); maxload =atoi(argv[7]); main_part(fnameR,fnameW,kprog,coefAB,deltaS0,coefS,maxload); /* printf("リターンキーを押してください"); getchar(); */ return 0; } /*--------------------------------------------------------------------------------*/ int main_part(char fnameR[50],char fnameW[50],int kprog,double coefAB,double deltaS0,double coefS,int maxload) { /*微小変形有限変位平面骨組構造解析*/ FILE *fin,*fout; char dat[1000]=""; char sv[50]=""; int i,j,k,l,m,ne,n,ia,ja; char strcom[50]=""; /*コメント*/ int NODT; /*節点総数*/ int NELT; /*要素総数*/ int MATEL; /*材料種別数*/ int KOX; /*x方向変位既知節点数*/ int KOY; /*y方向変位既知節点数*/ int KOZ; /*回転変位既知節点数*/ int NF; /*載荷節点数*/ int nt; /*全自由度*/ int mm; /*変位既知節点処理語の自由度*/ int ib; /*バンド幅*/ double fact0=1.0e-30; /*0判定基準*/ clock_t t_sta,t_end; double cal_time; time_t jikoku; struct tm *lt; char *p; /*--------------------------------------------------------------------------------------*/ /*配列寸法宣言*/ /*--------------------------------------------------------------------------------------*/ int kakom[NEmax+1][3]; /*要素構成節点番号*/ double Em[NEmax+1]; /*要素弾性係数*/ double AA[NEmax+1]; /*要素断面積*/ double AI[NEmax+1]; /*要素断面二次モーメント*/ int matno[NEmax+1]; /*材料種別No*/ double wm[MAmax+1][4]; /*材料種別作業用*/ double x[NDmax+1]; /*初期節点x座標*/ double y[NDmax+1]; /*初期節点y座標*/ int nokx[NDmax+1]; /*x方向変位既知節点番号*/ int noky[NDmax+1]; /*y方向変位既知節点番号*/ int nokz[NDmax+1]; /*回転変位既知節点番号*/ int index[NTmax+1]; /*変位既知節点処理のためのインデックス*/ static double tsm[NTmax+1][NTmax+1]; /*全体剛性マトリックス*/ static double twk[NTmax+1][NTmax+1]; /*全体剛性マトリックス*/ double df[NTmax+1]; /*全体節点外力ベクトル基準増分(入力値)*/ double ff[NTmax+1]; /*全体節点外力ベクトル(荷重)*/ double ftvec[NTmax+1]; /*全体節点力ベクトル*/ double dis[NTmax+1]; /*全体節点変位増分*/ double dist[NTmax+1]; /*全体節点変位*/ double dsav[NTmax+1]; /*全体節点変位記憶(釣合点)*/ double dis0[NTmax+1]; /*全体節点変位増分(基準外力相当増分)*/ double disr[NTmax+1]; /*全体節点変位増分(不平衡力相当増分)*/ double reac[NTmax+1]; /*作業用ベクトル*/ double work[NTmax+1]; /*作業用ベクトル*/ double sm[7][7]; /*要素剛性マトリックス*/ double fevec[7]; /*要素節点荷重ベクトル*/ double hen[7][7]; /*座標変換行列*/ double dtest,dtest0; /*変位収束判定用変数*/ double ftest,ftest0; /*不平衡力収束判定用変数*/ int maxita=50; /*繰返数最大値*/ int itaration; /*収束計算回数インクリメント*/ int iload; /*荷重増分インクリメント*/ int nocon; /*基準回数での収束か否かのフラグ*/ double reforce[NEmax+1][7]; /*要素断面力*/ double refsave[NEmax+1][7]; /*要素断面力記憶(釣合点)*/ double lam,dlam; /*弧長増分法パラメータ*/ double deltaS; /*弧長増分法パラメータ(計算に用いる弧長)*/ double Spara; /*弧長増分法パラメータ(スケーリングパラメータ)*/ double fjdg0,fjdg; /*弧長変更用*/ int jdg,jdginv; /*特異行列判定*/ double fend0,fend1; /*荷重の動きの監視*/ double dend0,dend1; /*変位の動きの監視*/ int jflagc; /*計算終了フラグ*/ /*時間計測開始*/ t_sta=clock(); /*******************************************************/ /*データ入力*/ /*******************************************************/ fin=fopen(fnameR,"r"); /*--------------------------------------------------------------------------------------*/ /*書出用コメント入力*/ /*--------------------------------------------------------------------------------------*/ fgets(dat,sizeof dat,fin);strncpy(strcom,dat,strlen(dat)-1); /*--------------------------------------------------------------------------------------*/ /*節点数,要素数,材料種別数][X方向変位既知節点数,Y方向変位既知節点数,回転変位既知節点数,載荷点数*/ /*--------------------------------------------------------------------------------------*/ fgets(dat,sizeof dat,fin); NODT =atoi(strtok(dat,",")); NELT =atoi(strtok(NULL,",")); MATEL =atoi(strtok(NULL,",")); KOX =atoi(strtok(NULL,",")); KOY =atoi(strtok(NULL,",")); KOZ =atoi(strtok(NULL,",")); NF =atoi(strtok(NULL,",")); nt=NODT*3; /*------------------------------------------------------------------------------------------*/ /*材料特性(Em,AA,AI)*/ /*------------------------------------------------------------------------------------------*/ for(i=1;i<=MATEL;i++){ fgets(dat,sizeof dat,fin); wm[i][1]=atof(strtok(dat,",")); wm[i][2]=atof(strtok(NULL,",")); wm[i][3]=atof(strtok(NULL,",")); } /*------------------------------------------------------------------------------------------*/ /*要素構成節点と材料種別(node-1,node-2,matno)*/ /*------------------------------------------------------------------------------------------*/ for(ne=1;ne<=NELT;ne++){ fgets(dat,sizeof dat,fin); kakom[ne][1]=atoi(strtok(dat,",")); kakom[ne][2]=atoi(strtok(NULL,",")); matno[ne] =atoi(strtok(NULL,",")); for(i=1;i<=MATEL;i++){ if(i==matno[ne]){ Em[ne] =wm[i][1]; AA[ne] =wm[i][2]; AI[ne] =wm[i][3]; } } } /*--------------------------------------------------------------------------------------*/ /*節点座標(x,y)*/ /*--------------------------------------------------------------------------------------*/ for(i=1;i<=NODT;i++){ fgets(dat,sizeof dat,fin); x[i] =atof(strtok(dat,",")); y[i] =atof(strtok(NULL,",")); } /*--------------------------------------------------------------------------------------*/ /*変位既知節点番号,既知節点変位量*/ /*--------------------------------------------------------------------------------------*/ if(00){mm=mm+1;index[mm]=i;}} /*-----------------------------------------------------*/ /*ベクトルクリア*/ /*-----------------------------------------------------*/ for(ne=1;ne<=NELT;ne++){ for(i=1;i<=6;i++){ reforce[ne][i]=0.0; refsave[ne][i]=0.0; }} for(i=1;i<=nt;i++){ ff[i]=0.0; dist[i]=0.0; dsav[i]=0.0; dis0[i]=0.0; disr[i]=0.0; reac[i]=0.0; } /*-----------------------------------------------------*/ /*方法1におけるスケーリングパラメータ設定*/ /*-----------------------------------------------------*/ ftest=0.0; for(i=1;i<=nt;i++){ ftest=ftest+df[i]*df[i]; } Spara=sqrt(coefAB/ftest); ftest=0.0; /*******************************************************/ /*荷重増分過程*/ /*******************************************************/ jflagc=0;/*正常終了フラグ初期設定*/ iload=0; deltaS=deltaS0; do{ iload=iload+1; jdg=0; again: itaration=0; nocon=0; lam=0.0; dtest0=0.0; ftest0=0.0; for(ne=1;ne<=NELT;ne++){for(i=1;i<=6;i++){reforce[ne][i]=refsave[ne][i];}} for(i=1;i<=nt;i++){dist[i]=dsav[i];} /*初期処理 {df}=[KT]{dis0}*/ for(i=1;i<=nt;i++){for(j=1;j<=nt;j++){tsm[i][j]=0.0;}} for(ne=1;ne<=NELT;ne++){ FRAMESM(ne,kakom,x,y,dist,Em,AA,AI,reforce,sm); ASMAT(ne,2,3,kakom,sm,tsm); } for(i=1;i<=nt;i++){reac[i]=0.0;dis0[i]=0.0;work[i]=0.0;} for(i=1;i<=mm;i++){ ia=index[i];work[i]=df[ia];reac[i]=work[i]; for(j=1;j<=mm;j++){ja=index[j];tsm[i][j]=tsm[ia][ja];} } switch(jdg){ case 0: /*Cholesky*/ ib=IBAND(mm,tsm,fact0); BAND(mm,ib,tsm); jdg=CHBAND10(mm,ib,tsm);/*三角行列*/ CHBAND11(mm,ib,tsm,reac);/*前進消去・後退代入*/ break; case 1: /*Gauss-Jordan : [tsm]=inverse matrix */ jdginv=MATINV(mm,tsm); if(jdginv==1)goto epart; for(i=1;i<=mm;i++){ reac[i]=0.0; for(j=1;j<=mm;j++){ reac[i]=reac[i]+tsm[i][j]*work[j]; }} break; } for(i=1;i<=mm;i++){ia=index[i];dis0[ia]=reac[i];} switch(kprog){ case 1:dlam=CAL_LAM01(nt,deltaS,Spara,dis0,df);break; case 2:dlam=CAL_LAM02(nt,deltaS,coefAB,&Spara,dis0,df);break; } for(i=1;i<=nt;i++){dis[i]=dlam*dis0[i];} /*====================================*/ /*収束過程*/ /*====================================*/ do{ itaration=itaration+1; lam=lam+dlam; for(i=1;i<=nt;i++){dist[i]=dist[i]+dis[i];ftvec[i]=0.0;} /*内力計算*/ for(ne=1;ne<=NELT;ne++){ CALST(ne,kakom,x,y,dis,dist,Em,AA,AI,fevec,reforce); ASVEC(ne,2,3,kakom,fevec,ftvec); } /*不平衡力計算*/ for(i=1;i<=nt;i++){reac[i]=ff[i]+lam*df[i]-ftvec[i];ftvec[i]=reac[i];} for(i=1;i<=mm;i++){ia=index[i];reac[i]=reac[ia];dis[i]=dis[ia];} /*収束判定*/ dtest=0.0;ftest=0.0; for(i=1;i<=mm;i++){dtest=dtest+fabs(dis[i]);ftest=ftest+fabs(reac[i]);} dtest0=dtest0+dtest; ftest0=ftest0+ftest; printf("iload=%d itaration=%d dtest=%e ftest=%e lam=%.3e\n",iload,itaration,dtest,ftest,lam); /*=====================================================*/ if(dtest<1e-10)break; if(dtestm1){ mm=m1; }else{ mm=n1-i+1; } for(j=1;j<=mm;j++){ z=array[i][j]; if(j!=m1){ if(m1-j+11){ array[i][j]=z/array[i][1]; }else{ if(z<0)return 1; array[i][1]=sqrt(z); } }else{ array[i][j]=z/array[i][1]; } } } return 0; } /*--------------------------------------------------------------------------------*/ void CHBAND11(int n1,int m1,double array[NTmax+1][NTmax+1],double vector[NTmax+1]) { /*前進消去・後退代入*/ int i,j,mm; double z; vector[1]=vector[1]/array[1][1]; for(i=2;i<=n1;i++){ z=vector[i]; if(i>m1){ mm=m1; }else{ mm=i; } for(j=2;j<=mm;j++){ z=z-array[i-j+1][j]*vector[i-j+1]; } vector[i]=z/array[i][1]; } vector[n1]=vector[n1]/array[n1][1]; for(i=n1-1;i>=1;i--){ z=vector[i]; for(j=2;j<=m1;j++){ if(i+j-1>n1)break; z=z-array[i][j]*vector[i+j-1]; } vector[i]=z/array[i][1]; } } /*--------------------------------------------------------------------------------*/ int IBAND(int mm,double array[NTmax+1][NTmax+1],double fact0) { int ib,i,j; /*-----------------------------------------------------*/ /*バンド幅計算 /*-----------------------------------------------------*/ ib=1; for(i=1;i<=mm-1;i++){ for(j=mm;j>=i+1;j--){ if(fact0