using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace vcsFEMondoCH { public partial class Form1 : Form { public Form1() { InitializeComponent(); } //------------------------------------------------------------------------------ private void Form1_Load(object sender, EventArgs e) { label1.Dock = DockStyle.Fill; label1.TextAlign = ContentAlignment.MiddleCenter; label3.Dock = DockStyle.Fill; label3.TextAlign = ContentAlignment.MiddleCenter; label5.Dock = DockStyle.Fill; label5.TextAlign = ContentAlignment.MiddleCenter; label7.Dock = DockStyle.Fill; label7.TextAlign = ContentAlignment.MiddleCenter; label9.Dock = DockStyle.Fill; label9.TextAlign = ContentAlignment.MiddleCenter; label2.Dock = DockStyle.Fill; label2.TextAlign = ContentAlignment.MiddleLeft; label4.Dock = DockStyle.Fill; label4.TextAlign = ContentAlignment.MiddleLeft; label6.Dock = DockStyle.Fill; label6.TextAlign = ContentAlignment.MiddleLeft; label8.Dock = DockStyle.Fill; label8.TextAlign = ContentAlignment.MiddleLeft; label10.Dock = DockStyle.Fill; label10.TextAlign = ContentAlignment.MiddleLeft; label1.Text = "入力ファイル"; label3.Text = "出力ファイル"; label5.Text = "開始時刻"; label7.Text = "完了時刻"; label9.Text = "計算時間"; label2.Text = ""; label4.Text = ""; label6.Text = ""; label8.Text = ""; label10.Text = ""; label11.Text = "nt,mm,ib"; } //------------------------------------------------------------------------------ private void toolStripButton1_Click(object sender, EventArgs e) { main_part(); } //------------------------------------------------------------------------------ private void main_part() { //2次元熱伝導解析 int i,j,k,n,nnn,ia,ja,ne,it; System.IO.StreamReader sr; System.IO.StreamWriter sw; string dat; string[] sbuf; char delim = ','; string fnameR=""; string fnameW=""; string ftinp=""; string strcom; //書出用コメント int NODT; //節点総数 int NELT; //要素総数 int MATEL; //材料種類数 int KOT; //温度指定節点数 int KOC; //熱伝達指定辺数 int nt; //全自由度(総節点数×1[1節点自由度]) int mm; //温度固定点処理後自由度 int ib; //バンド幅 double delta; //時間刻み double ttime; //時刻 double elarea1; //要素半面積 double elarea2; //要素半面積 double fact0 = 1.0E-30; //0判定 DateTime sttime; //計算開始時刻 DateTime entime; //計算終了時刻 TimeSpan tspan; //計算時間 //----------------------------------------------------- //基本データ読み込みファイル・出力ファイル指定 //----------------------------------------------------- openFileDialog1.InitialDirectory = System.IO.Directory.GetCurrentDirectory(); if (openFileDialog1.ShowDialog() == DialogResult.OK) fnameR = openFileDialog1.FileName; if(saveFileDialog1.ShowDialog()==DialogResult.OK)fnameW = saveFileDialog1.FileName; label2.Text = fnameR; label4.Text = fnameW; //----------------------------------------------------- //時間計測開始 //----------------------------------------------------- sttime = DateTime.Now; label6.Text = sttime.ToString(); //***************************************************** //データ入力 //***************************************************** sr = new System.IO.StreamReader(fnameR, System.Text.Encoding.Default); //-------------------------------------------------------------------------------------- //書出用コメント入力 //-------------------------------------------------------------------------------------- dat = sr.ReadLine() ; sbuf = dat.Split(delim) ; strcom = sbuf[0]; //-------------------------------------------------------------------------------------- //時刻歴読み込みファイル指定 //-------------------------------------------------------------------------------------- dat = sr.ReadLine() ; sbuf = dat.Split(delim); ftinp = System.IO.Path.GetDirectoryName(fnameR) + "\\" + sbuf[0]; //------------------------------------------------------------------------------------------ //節点数,要素数,材料種類数,温度固定点数,熱伝達境界辺数,時間刻み //------------------------------------------------------------------------------------------ dat = sr.ReadLine() ; sbuf = dat.Split(delim); NODT = int.Parse(sbuf[0]); NELT = int.Parse(sbuf[1]); MATEL = int.Parse(sbuf[2]); KOT = int.Parse(sbuf[3]); KOC = int.Parse(sbuf[4]); delta = double.Parse(sbuf[5]); //------------------------------------------------------------------------------------------ //配列寸法宣言 //------------------------------------------------------------------------------------------ double alpc; //作業用熱伝達率 double tc; //作業用熱伝達境界温度 int kchen; //作業用熱伝達境界辺番号 double dotq; //作業用発熱率 int[,] kakom=new int[NELT+1, 5]; //要素構成節点番号 double[] Ak=new double[NELT+1]; //要素熱伝導率 double[] Ac=new double[NELT+1]; //要素比熱 double[] Arho=new double[NELT+1]; //要素単位体積重量 double[] Tk=new double[NELT+1]; //要素最終温度上昇量 double[] Al=new double[NELT+1]; //要素発熱速度係数 int[] matno=new int[NELT+1]; //材料種別No double[,] wm=new double[MATEL+1, 6]; //作業用材料物性記憶 double[] x=new double[NODT+1]; //節点x座標 double[] y=new double[NODT+1]; //節点y座標 int[] nokt=new int[KOT+1]; //温度指定節点番号 int[,] nekc=new int[KOC+1, 3]; //熱伝達境界要素・辺番号 double[] alphac=new double[KOC+1]; //指定辺熱伝達率 double[] Tinp=new double[KOT+1]; //指定温度入力 double[] Tcin1=new double[KOC+1]; //指定熱伝達境界温度入力(前回) double[] Tcin2=new double[KOC+1]; //指定熱伝達境界温度入力(現在) nt = NODT * 1; int[] index=new int[nt+1]; //温度固定点処理用 double[,] tck1=new double[nt+1, nt+1]; //全体剛性行列(前回) double[,] tck2=new double[nt+1, nt+1]; //全体剛性行列(現在) double[,] rtck2=new double[nt+1, KOT+1]; //全体剛性行列(現在)拘束節点列保存 double[] tempe0 = new double[nt + 1]; //初期節点温度ベクトル double[] tempe = new double[nt + 1]; //全体節点温度ベクトル double[] reac=new double[nt+1]; //作業用節点温度ベクトル double[] ftvec=new double[nt+1]; //全体熱流束ベクトル int itmax; //時刻歴ステップ数 int nout; //出力節点数 int ntout; //全節点温度出力回数 double[,] ck1=new double[5, 5]; //要素剛性行列(前回) double[,] ck2=new double[5, 5]; //要素剛性行列(現在) double[,] ht=new double[5, 5]; //要素熱伝達行列 double[] fq=new double[5]; //要素発熱率ベクトル double[] fc=new double[5]; //要素熱伝達ベクトル //------------------------------------------------------------------------------------------ //材料特性(Ak,Ac,Arho,Tk,Al) //------------------------------------------------------------------------------------------ for(i=1;i<=MATEL;i++){ dat = sr.ReadLine() ; sbuf = dat.Split(delim); for(j=1;j<=5;j++){ wm[i, j] = double.Parse(sbuf[j - 1]); }} //------------------------------------------------------------------------------------------ //要素構成節点と材料種別(node-1,node-2,node-3,node-4,matno) //------------------------------------------------------------------------------------------ for(ne=1;ne<=NELT;ne++){ dat = sr.ReadLine() ; sbuf = dat.Split(delim); kakom[ne, 1] = int.Parse(sbuf[0]); kakom[ne, 2] = int.Parse(sbuf[1]); kakom[ne, 3] = int.Parse(sbuf[2]); kakom[ne, 4] = int.Parse(sbuf[3]); matno[ne] = int.Parse(sbuf[4]); for(i=1;i<=MATEL;i++){ if(i==matno[ne]){ Ak[ne] = wm[i, 1]; Ac[ne] = wm[i, 2]; Arho[ne] = wm[i, 3]; Tk[ne] = wm[i, 4]; Al[ne] = wm[i, 5]; } }} //------------------------------------------------------------------------------------------ //節点座標(x,y),初期節点温度 //------------------------------------------------------------------------------------------ for(i=1;i<=NODT;i++){ dat = sr.ReadLine() ; sbuf = dat.Split(delim); x[i] = double.Parse(sbuf[0]); y[i] = double.Parse(sbuf[1]); tempe0[i] = double.Parse(sbuf[2]); } //------------------------------------------------------------------------------------------ //温度指定節点番号 //------------------------------------------------------------------------------------------ if(00){ mm = mm + 1 ; index[mm] = i; } } for(i=1;i<=mm;i++){ ia = index[i]; for(j=1;j<=mm;j++){ ja = index[j]; tck2[i, j] = tck2[ia, ja]; }} //----------------------------------------------------- //バンド幅計算とフルマトリックスのバンド化記憶 //----------------------------------------------------- ib=IBAND(mm, tck2, fact0); BAND(mm, ib, tck2); //----------------------------------------------------- //対角項確認と異常終了通知 //----------------------------------------------------- for (i = 1; i <= mm; i++) { if (Math.Abs(tck2[i, 1]) < fact0) IERROR2(fnameW); } //----------------------------------------------------- //コレスキー法(三角行列) //----------------------------------------------------- CHBAND10(mm, ib, tck2); //三角行列 //----------------------------------------------------- //時刻歴出力準備 //----------------------------------------------------- /*初期温度ベクトルセット*/ for (i = 1; i <= nt; i++) { tempe[i] = tempe0[i]; } /*熱伝達境界初期値設定*/ ia = 0; ja = 0; if (0 < KOC) { for (k = 1; k <= KOC; k++) { ne = nekc[k,1]; switch (nekc[k,2]) { case 1: ia = kakom[ne,1]; ja = kakom[ne,2]; break; case 2: ia = kakom[ne,2]; ja = kakom[ne,3]; break; case 3: ia = kakom[ne,3]; ja = kakom[ne,4]; break; case 4: ia = kakom[ne,4]; ja = kakom[ne,1]; break; } Tcin1[k] = 0.5 * (tempe[ia] + tempe[ja]); } } sw = new System.IO.StreamWriter(fnameW, true, System.Text.Encoding.Default); dat = "*temperature records of selected nodes" ; sw.WriteLine(dat); //====================== it = 0; ttime = 0.0; //====================== dat = "it,time"; for(i=1;i<=nout;i++){ dat = dat + ",Node-" + noout[i].ToString(); } sw.WriteLine(dat); dat = it.ToString("0"); dat = dat + "," + ttime.ToString("E"); for(i=1;i<=nout;i++){ dat = dat + "," + tempe[noout[i]].ToString("0.000"); } sw.WriteLine(dat); //----------------------------------------------------- //時刻歴初期値入力 //----------------------------------------------------- sr = new System.IO.StreamReader(ftinp, System.Text.Encoding.Default); dat = sr.ReadLine(); //コメント //***************************************************** //時刻歴計算(時刻歴入力ファイル:ftinpの最終行まで) //***************************************************** it = 0 ; nnn = 0; while(!sr.EndOfStream){ it = it + 1; ttime = delta * (double)it; //----------------------------------------------------- //時刻歴入力(指定温度はその都度入力) //----------------------------------------------------- dat = sr.ReadLine() ; sbuf = dat.Split(delim); //1列目はダミー i = 0; //温度指定節点温度 if(0 m1) { mm = m1; } else { mm = n1 - i + 1; } for (j = 1; j <= mm; j++) { z = array[i, j]; if (j != m1) { if (m1 - j + 1 < i) { mn = m1 - j + 1; } else { mn = i; } for (k = 2; k <= mn; k++) { z = z - array[i - k + 1, k] * array[i - k + 1, j + k - 1]; } if (j > 1) { array[i, j] = z / array[i, 1]; } else { array[i, 1] = Math.Sqrt(z); } } else { array[i, j] = z / array[i, 1]; } } } } //------------------------------------------------------------------------------ private void CHBAND11(int n1, int m1, double[,] array, double[] vector) { //前進消去・後退代入 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]; } } //------------------------------------------------------------------------------ private int IBAND(int mm, double[,] array, double fact0) { int ib, i, j; //----------------------------------------------------- //バンド幅計算 //----------------------------------------------------- ib = 1; for (i = 1; i <= mm - 1; i++) { for (j = mm; j >= i + 1; j--) { if (fact0 <= Math.Abs(array[i, j])) break; } if (ib <= j - i + 1) ib = j - i + 1; } if (mm < ib) ib = mm; return ib; } //------------------------------------------------------------------------------ private void BAND(int mm, int ib, double[,] array) { int i, j, k, mn; double[] work = new double[mm + 1]; //----------------------------------------------------- //フルマトリックスのバンド化記憶 //----------------------------------------------------- for (i = 2; i <= mm; i++) { if (i + ib - 1 < mm) { mn = ib; } else { mn = mm - i + 1; } for (j = 1; j <= ib; j++) { work[j] = 0.0; } for (k = 1; k <= mn; k++) { work[k] = array[i, i + k - 1]; } for (j = 1; j <= ib; j++) { array[i, j] = work[j]; } } } //------------------------------------------------------------------------------ private void IERROR1(string fnameW) { //結果出力(Appendモード) System.IO.StreamWriter sw; string dat; sw = new System.IO.StreamWriter(fnameW, true, System.Text.Encoding.Default); dat = "area of element is less or equal to 0"; sw.WriteLine(dat); sw.Close(); MessageBox.Show("要素面積<=0", "異常終了通知"); this.Close(); } //------------------------------------------------------------------------------ private void IERROR2(string fnameW) { //結果出力(Appendモード) System.IO.StreamWriter sw; string dat; sw = new System.IO.StreamWriter(fnameW, true, System.Text.Encoding.Default); dat = "diagonal value is less or equal to 0"; sw.WriteLine(dat); sw.Close(); MessageBox.Show("対角項<=0", "異常終了通知"); this.Close(); } //------------------------------------------------------------------------------ } }