github.com/archlabjp/eeslism-go@v0.0.0-20231109122333-4bb7bfcdf292/eeslism/mcevcooling.go (about)

     1  //This file is part of EESLISM.
     2  //
     3  //Foobar is free software : you can redistribute itand /or modify
     4  //it under the terms of the GNU General Public License as published by
     5  //the Free Software Foundation, either version 3 of the License, or
     6  //(at your option) any later version.
     7  //
     8  //Foobar is distributed in the hope that it will be useful,
     9  //but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
    11  //GNU General Public License for more details.
    12  //
    13  //You should have received a copy of the GNU General Public License
    14  //along with Foobar.If not, see < https://www.gnu.org/licenses/>.
    15  
    16  /* mcevcooling.c */
    17  
    18  package eeslism
    19  
    20  /*  気化冷却器  */
    21  
    22  /*  仕様入力  */
    23  
    24  import (
    25  	"fmt"
    26  	"io"
    27  	"math"
    28  	"strconv"
    29  	"strings"
    30  )
    31  
    32  func Evacdata(s string, Evacca *EVACCA) int {
    33  	st := strings.IndexByte(s, '=')
    34  
    35  	if st == -1 {
    36  		Evacca.Name = s
    37  		Evacca.N = -999
    38  		Evacca.Nlayer = -999
    39  		Evacca.Awet = -999.0
    40  		Evacca.Adry = -999.0
    41  		Evacca.hdry = -999.0
    42  		Evacca.hwet = -999.0
    43  	} else {
    44  		key := s[:st]
    45  		value := s[st+1:]
    46  
    47  		switch key {
    48  		case "Awet":
    49  			if val, err := strconv.ParseFloat(value, 64); err == nil {
    50  				Evacca.Awet = val
    51  			} else {
    52  				panic(err)
    53  			}
    54  		case "Adry":
    55  			if val, err := strconv.ParseFloat(value, 64); err == nil {
    56  				Evacca.Adry = val
    57  			} else {
    58  				panic(err)
    59  			}
    60  		case "hwet":
    61  			if val, err := strconv.ParseFloat(value, 64); err == nil {
    62  				Evacca.hwet = val
    63  			} else {
    64  				panic(err)
    65  			}
    66  		case "hdry":
    67  			if val, err := strconv.ParseFloat(value, 64); err == nil {
    68  				Evacca.hdry = val
    69  			} else {
    70  				panic(err)
    71  			}
    72  		case "N":
    73  			if val, err := strconv.Atoi(value); err == nil {
    74  				Evacca.N = val
    75  			} else {
    76  				panic(err)
    77  			}
    78  		case "Nlayer":
    79  			if val, err := strconv.Atoi(value); err == nil {
    80  				Evacca.Nlayer = val
    81  			} else {
    82  				panic(err)
    83  			}
    84  		default:
    85  			return 1
    86  		}
    87  	}
    88  
    89  	return 0
    90  }
    91  
    92  /* ------------------------------------------------------ */
    93  // 初期設定(入力漏れのチェック、変数用メモリの確保)
    94  func Evacint(Evac []*EVAC) {
    95  	for _, evac := range Evac {
    96  		cat := evac.Cat
    97  
    98  		// 入力漏れのチェック
    99  		if cat.N < 0 {
   100  			msg := fmt.Sprintf("Name=%s catname=%s 分割数が未定義です", evac.Name, cat.Name)
   101  			Eprint("<Evacint>", msg)
   102  		}
   103  		if cat.Adry < 0.0 || cat.Awet < 0.0 || (cat.Nlayer < 0 && (cat.hdry < 0.0 || cat.hwet < 0.0)) {
   104  			msg := fmt.Sprintf("Name=%s catname=%s Adry=%.1g Awet=%.1g hdry=%.1g hwet=%.1g\n",
   105  				evac.Name, cat.Name, cat.Adry, cat.Awet, cat.hdry, cat.hwet)
   106  			Eprint("<Evacint>", msg)
   107  		}
   108  
   109  		// 面積を分割後の面積に変更
   110  		cat.Adry /= float64(cat.N)
   111  		cat.Awet /= float64(cat.N)
   112  
   113  		// 必要なメモリ領域の確保
   114  		if cat.N > 0 {
   115  			Temp := FNXtr(20.0, 50.0)
   116  			evac.M = make([]float64, cat.N)    // 蒸発量のメモリ確保
   117  			evac.Kx = make([]float64, cat.N)   // 物質移動係数のメモリ確保
   118  			evac.Tdry = make([]float64, cat.N) // Dry側温度のメモリ確保
   119  			for i := range evac.Tdry {
   120  				evac.Tdry[i] = 20.0
   121  			}
   122  			evac.Twet = make([]float64, cat.N) // Wet側温度のメモリ確保
   123  			for i := range evac.Twet {
   124  				evac.Twet[i] = 20.0
   125  			}
   126  			evac.Xdry = make([]float64, cat.N) // Dry側絶対湿度のメモリ確保
   127  			for i := range evac.Xdry {
   128  				evac.Xdry[i] = Temp
   129  			}
   130  			evac.Xwet = make([]float64, cat.N) // Wet側絶対湿度のメモリ確保
   131  			for i := range evac.Xwet {
   132  				evac.Xwet[i] = Temp
   133  			}
   134  			evac.Ts = make([]float64, cat.N) // 境界層温度のメモリ確保
   135  			for i := range evac.Ts {
   136  				evac.Ts[i] = 20.0
   137  			}
   138  			evac.Xs = make([]float64, cat.N) // 境界層絶対湿度のメモリ確保
   139  			xs := FNXtr(20.0, 100.0)
   140  			for i := range evac.Xs {
   141  				evac.Xs[i] = xs
   142  			}
   143  			evac.RHdry = make([]float64, cat.N) // Dry側相対湿度のメモリ確保
   144  			for i := range evac.RHdry {
   145  				evac.RHdry[i] = 50.0
   146  			}
   147  			evac.RHwet = make([]float64, cat.N) // Wet側相対湿度のメモリ確保
   148  			for i := range evac.RHwet {
   149  				evac.RHwet[i] = 50.0
   150  			}
   151  
   152  			// 状態値計算用行列
   153  			N := cat.N * 5
   154  			N2 := N * N
   155  			evac.UX = make([]float64, N2)
   156  			evac.UXC = make([]float64, N)
   157  		}
   158  	}
   159  }
   160  
   161  // 飽和絶対湿度の線形近似(Ts℃付近で線形回帰式を作成)
   162  func LinearSatx(Ts float64) (a, b float64) {
   163  	// 線形近似の区間の設定(Tsを中心にEPS区間)
   164  	T1 := Ts - 0.2
   165  	T2 := Ts + 0.2
   166  
   167  	// T1、T2における飽和絶対湿度の計算
   168  	x1 := FNXs(T1)
   169  	x2 := FNXs(T2)
   170  
   171  	// 線形回帰式の傾きの計算
   172  	a = (x2 - x1) / (T2 - T1)
   173  
   174  	// 線形回帰式の切片の計算
   175  	b = x1 - a*T1
   176  
   177  	return a, b
   178  }
   179  
   180  // 湿り空気の飽和絶対湿度の計算
   181  func FNXs(T float64) float64 {
   182  	return 4.2849e-3 * math.Exp(6.0260e-2*T)
   183  }
   184  
   185  /*  気化冷却器出口空気温湿度に関する変数割当  */
   186  func Evacelm(Evac []*EVAC) {
   187  	for _, evac := range Evac {
   188  		EoTdry := evac.Cmp.Elouts[0] // Tdryoutの出口温度計算用
   189  		Eoxdry := evac.Cmp.Elouts[1] // xdryoutの出口温度計算用
   190  		EoTwet := evac.Cmp.Elouts[2] // Twetoutの出口温度計算用
   191  		Eoxwet := evac.Cmp.Elouts[3] // xwetoutの出口温度計算用
   192  
   193  		EoTdry.Elins[1].Upo = Eoxdry.Elins[0].Upo
   194  		EoTdry.Elins[1].Upv = Eoxdry.Elins[0].Upo
   195  		EoTdry.Elins[2].Upo = EoTwet.Elins[0].Upo
   196  		EoTdry.Elins[2].Upv = EoTwet.Elins[0].Upo
   197  		EoTdry.Elins[3].Upo = Eoxwet.Elins[0].Upo
   198  		EoTdry.Elins[3].Upv = Eoxwet.Elins[0].Upo
   199  
   200  		Eoxdry.Elins[1].Upo = EoTdry.Elins[0].Upo
   201  		Eoxdry.Elins[1].Upv = EoTdry.Elins[0].Upo
   202  		Eoxdry.Elins[2].Upo = EoTwet.Elins[0].Upo
   203  		Eoxdry.Elins[2].Upv = EoTwet.Elins[0].Upo
   204  		Eoxdry.Elins[3].Upo = Eoxwet.Elins[0].Upo
   205  		Eoxdry.Elins[3].Upv = Eoxwet.Elins[0].Upo
   206  
   207  		EoTwet.Elins[1].Upo = EoTdry.Elins[0].Upo
   208  		EoTwet.Elins[1].Upv = EoTdry.Elins[0].Upo
   209  		EoTwet.Elins[2].Upo = Eoxdry.Elins[0].Upo
   210  		EoTwet.Elins[2].Upv = Eoxdry.Elins[0].Upo
   211  		EoTwet.Elins[3].Upo = Eoxwet.Elins[0].Upo
   212  		EoTwet.Elins[3].Upv = Eoxwet.Elins[0].Upo
   213  
   214  		Eoxwet.Elins[1].Upo = EoTdry.Elins[0].Upo
   215  		Eoxwet.Elins[1].Upv = EoTdry.Elins[0].Upo
   216  		Eoxwet.Elins[2].Upo = Eoxdry.Elins[0].Upo
   217  		Eoxwet.Elins[2].Upv = Eoxdry.Elins[0].Upo
   218  		Eoxwet.Elins[3].Upo = EoTwet.Elins[0].Upo
   219  		Eoxwet.Elins[3].Upv = EoTwet.Elins[0].Upo
   220  
   221  	}
   222  }
   223  
   224  // 風速の計算
   225  func Evacu(G, T, H, W float64, N int) float64 {
   226  	u := G / FNarow(T) / (float64(N) * H * W)
   227  	return u
   228  }
   229  
   230  // 通気部の対流熱伝達率の計算(プログラムを解読したため詳細は不明)
   231  func Evachcc(de, L, T, H, W float64, N, G, Flg int) float64 {
   232  	// 流路縦横比の計算
   233  	AR := H / (W / 5.0)
   234  
   235  	// 通気部の風速の計算
   236  	u := Evacu(float64(G), T, H, W, N)
   237  
   238  	// レイノルズ数の計算
   239  	Re := u * L / FNanew(T)
   240  
   241  	// ヌセルト数の計算
   242  	Nu := EvacNu(AR, Re)
   243  
   244  	// 裕度の計算
   245  	Mgn := 0.875
   246  	if Flg == 'd' {
   247  		if Re > 1000.0 {
   248  			Mgn *= (0.0000128205*Re + 1.0859)
   249  		} else {
   250  			Mgn *= (0.00083333*Re + 0.18333)
   251  		}
   252  	}
   253  
   254  	// 対流熱伝達率の計算
   255  	hc := Nu / de * FNalam(T) * Mgn
   256  
   257  	return hc
   258  }
   259  
   260  // 通気部のヌセルト数を計算する
   261  func EvacNu(AR, Re float64) float64 {
   262  	var Nu float64
   263  
   264  	if Re <= 1000.0 {
   265  		Nu = -13.042*AR*AR*AR + 27.063*AR*AR - 18.591*AR + 7.54
   266  	} else if Re <= 2000.0 {
   267  		Nu = (-0.023131*AR*AR+0.018229*AR+0.00043299)*Re +
   268  			(46.261*AR*AR - 36.459*AR + 7.0971)
   269  	} else {
   270  		Nu = 0.021 * math.Pow(Re, 0.8) * math.Pow(0.7, 0.4)
   271  	}
   272  
   273  	return Nu
   274  }
   275  
   276  // 要素方程式の係数計算
   277  func Evaccfv(Evac []*EVAC) {
   278  	for _, evac := range Evac {
   279  		EvpFlg := make([]float64, evac.Cat.N)
   280  		if evac.Cmp.Control != OFF_SW {
   281  			EoTdry := evac.Cmp.Elouts[0] // Tdryoutの出口温度計算用
   282  			Eoxdry := evac.Cmp.Elouts[1] // xdryoutの出口温度計算用
   283  			EoTwet := evac.Cmp.Elouts[2] // Twetoutの出口温度計算用
   284  			Eoxwet := evac.Cmp.Elouts[3] // xwetoutの出口温度計算用
   285  
   286  			cat := evac.Cat
   287  			Gdry := EoTdry.G
   288  			Gwet := EoTwet.G
   289  
   290  			if cat.Nlayer > 0 {
   291  				Ts := evac.Ts
   292  				Tsave := 0.0
   293  				for ii := 0; ii < cat.N; ii++ {
   294  					Tsave += Ts[ii] / float64(cat.N)
   295  				}
   296  				cat.hdry = Evachcc(4.3/1000.0, 4.3/1000.0, Tsave, 2.3/1000.0, 173.0/1000.0, cat.Nlayer, int(Gdry), 'd') // Dry側の対流熱伝達率の計算
   297  				cat.hwet = Evachcc(6.4/1000.0, 6.4/1000.0, Tsave, 3.5/1000.0, 173.0/1000.0, cat.Nlayer, int(Gwet), 'w') // Wet側の対流熱伝達率の計算
   298  			}
   299  
   300  			N := cat.N * 5
   301  			N2 := N * N
   302  
   303  			U := make([]float64, N2) // 行列Uの作成
   304  			C := make([]float64, N)  // 行列Cの作成
   305  			a := make([]float64, cat.N)
   306  			b := make([]float64, cat.N)
   307  
   308  			PreFlg := 1.0
   309  			for ii := cat.N - 1; ii >= 0; ii-- {
   310  				Ts := &evac.Ts[ii]
   311  				xwet := &evac.Xwet[ii]
   312  				RHwet := &evac.RHwet[ii]
   313  				//kx := &evac.Kx[ii]
   314  				EF := &EvpFlg[ii]
   315  
   316  				a[ii], b[ii] = LinearSatx(*Ts) // 境界層温度における飽和絶対湿度計算用係数の取得
   317  				*EF = 1.0
   318  				if a[ii]**Ts+b[ii]-*xwet < 0.0 || *RHwet > 99.0 || math.Abs(PreFlg) <= 1e-5 {
   319  					*EF = 0.0
   320  				}
   321  				PreFlg = *EF
   322  			}
   323  
   324  			for ii := 0; ii < cat.N; ii++ {
   325  				Ts := &evac.Ts[ii]
   326  				xs := &evac.Xs[ii]
   327  				// xwet := &evac.Xwet[ii]
   328  				// RHwet := &evac.RHwet[ii]
   329  				kx := &evac.Kx[ii]
   330  				EF := &EvpFlg[ii]
   331  
   332  				*kx = cat.hwet / (Ca + Cv**xs) * *EF // 物質移動係数の計算
   333  				A := *kx * (Ro + Cv**Ts) * *EF       // 係数の計算
   334  
   335  				// C行列の作成
   336  				C[ii*5+0] = 0.0                    // Twetの状態方程式には定数項はない
   337  				C[ii*5+1] = -cat.Awet * *kx * b[0] // xwetの定数項作成
   338  				C[ii*5+2] = A * b[0]               // Tsの定数項作成
   339  				C[ii*5+3] = 0.0                    // Tdryの係数はゼロ
   340  				C[ii*5+4] = 0.0                    // xdryの係数はゼロ
   341  
   342  				// U行列の作成
   343  
   344  				// 対角行列
   345  				U[N*(5*ii+0)+(5*ii+0)] = -(Ca*Gwet + cat.Awet*cat.hwet)   // Twetの項
   346  				U[N*(5*ii+1)+(5*ii+1)] = -(Gwet + cat.Awet**kx)           // xwetの項
   347  				U[N*(5*ii+2)+(5*ii+2)] = -(cat.hwet + A*a[ii] + cat.hdry) // Tsの項
   348  				U[N*(5*ii+2)+(5*ii+3)] = -(Ca*Gdry + cat.Adry*cat.hdry)   // Tdryの項
   349  				U[N*(5*ii+2)+(5*ii+4)] = 1.0                              // xdryの項
   350  
   351  				U[N*(5*ii+0)+(5*ii+2)] = cat.Awet * cat.hwet   // TwetとTsの項
   352  				U[N*(5*ii+1)+(5*ii+2)] = cat.Awet * *kx * a[0] // xwetとTsの項
   353  				U[N*(5*ii+2)+(5*ii+0)] = cat.hwet              // TsとTwetの項
   354  				U[N*(5*ii+2)+(5*ii+1)] = A                     // Tsとxwetの項
   355  				U[N*(5*ii+2)+(5*ii+3)] = cat.hdry              // TsとTdryの項
   356  				U[N*(5*ii+3)+(5*ii+2)] = cat.Adry * cat.hdry   // TdryとTsの項
   357  
   358  				//  Dry側上流
   359  				if ii > 0 {
   360  					U[N*(5*ii+3)+(5*(ii-1)+3)] = Ca * Gdry // Tdryの項
   361  					U[N*(5*ii+4)+(5*(ii-1)+4)] = -1.0      // xdryの項
   362  				}
   363  
   364  				// Wet側の上流
   365  				if ii < cat.N-1 {
   366  					U[N*(5*ii+0)+(5*(ii+1)+0)] = Ca * Gwet // Twetの項
   367  					U[N*(5*ii+1)+(5*(ii+1)+1)] = Gwet      // xwetの項
   368  				}
   369  			}
   370  
   371  			Matinv(U, N, N, "Evaccfv U") // 行列Uの逆行列を計算
   372  			matinit(evac.UX, N2)         // 行列の初期化
   373  			matcpy(U, evac.UX, N2)       // 行列のコピー
   374  
   375  			matinit(evac.UXC, N) // 行列UXCの初期化
   376  			for ii := 0; ii < N; ii++ {
   377  				for jj := 0; jj < N; jj++ {
   378  					evac.UXC[ii] += evac.UX[ii*N+jj] * C[jj] // 行列UXとベクトルCの積の計算
   379  				}
   380  			}
   381  
   382  			Row := N * (5*(cat.N-1) + 3)
   383  
   384  			EoTdry.Coeffo = -1.0                                            // Tdryoutの要素方程式
   385  			EoTdry.Co = -evac.UXC[5*(cat.N-1)+3]                            // 定数の項
   386  			EoTdry.Coeffin[0] = -evac.UX[Row+(5*(cat.N-1)+3)] * (Ca * Gdry) // Tdryinの項
   387  			EoTdry.Coeffin[1] = -evac.UX[Row+(5*(1-1)+4)] * -1.0            // xdryinの項
   388  			EoTdry.Coeffin[2] = -evac.UX[Row+(5*(cat.N-1)+0)] * (Ca * Gwet) // Twetinの項
   389  			EoTdry.Coeffin[3] = -evac.UX[Row+(5*(cat.N-1)+1)] * (Gwet)      // xwetinの項
   390  
   391  			Eoxdry.Coeffo = -1.0                                            // xdryoutの要素方程式
   392  			Eoxdry.Co = -evac.UXC[5*(cat.N-1)+4]                            // 定数の項
   393  			Eoxdry.Coeffin[0] = -evac.UX[Row+(5*(1-1)+4)] * -1.0            // xdryinの項
   394  			Eoxdry.Coeffin[1] = -evac.UX[Row+(5*(1-1)+3)] * (Ca * Gdry)     // Tdryinの項
   395  			Eoxdry.Coeffin[2] = -evac.UX[Row+(5*(cat.N-1)+0)] * (Ca * Gwet) // Twetinの項
   396  			Eoxdry.Coeffin[3] = -evac.UX[Row+(5*(cat.N-1)+1)] * (Gwet)      // xwetinの項
   397  
   398  			Row = N * (5*(1-1) + 0)
   399  			EoTwet.Coeffo = -1.0                                            // Twetoutの要素方程式
   400  			EoTwet.Co = -evac.UXC[5*(1-1)+0]                                // 定数の項
   401  			EoTwet.Coeffin[0] = -evac.UX[Row+(5*(cat.N-1)+0)] * (Ca * Gwet) // Twetinの項
   402  			EoTwet.Coeffin[1] = -evac.UX[Row+(5*(1-1)+3)] * (Ca * Gdry)     // Tdryinの項
   403  			EoTwet.Coeffin[2] = -evac.UX[Row+(5*(1-1)+4)] * -1.0            // xdryinの項
   404  			EoTwet.Coeffin[3] = -evac.UX[Row+(5*(cat.N-1)+1)] * (Gwet)      // xwetinの項
   405  
   406  			Row = N * (5*(1-1) + 1)
   407  			Eoxwet.Coeffo = -1.0                                            // xwetoutの要素方程式
   408  			Eoxwet.Co = -evac.UXC[5*(1-1)+1]                                // 定数の項
   409  			Eoxwet.Coeffin[0] = -evac.UX[Row+(5*(cat.N-1)+1)] * (Gwet)      // xwetinの項
   410  			Eoxwet.Coeffin[1] = -evac.UX[Row+(5*(1-1)+3)] * (Ca * Gdry)     // Tdryinの項
   411  			Eoxwet.Coeffin[2] = -evac.UX[Row+(5*(1-1)+4)] * -1.0            // xdryinの項
   412  			Eoxwet.Coeffin[3] = -evac.UX[Row+(5*(cat.N-1)+0)] * (Ca * Gwet) // Twetinの項
   413  		}
   414  	}
   415  }
   416  
   417  // 内部温度、熱量の計算
   418  func Evacene(Evac []*EVAC, Evacreset *int) {
   419  	for _, evac := range Evac {
   420  		cat := evac.Cat
   421  		if evac.Cmp.Control != OFF_SW {
   422  			var Gdry, Gwet float64
   423  			var Tdry, Twet, xdry, xwet, Ts, xs, RHwet, RHdry, M, kx []float64
   424  			var Sin, Stat, Scmp []float64
   425  			//var elin *ELIN
   426  
   427  			EoTdry := evac.Cmp.Elouts[0] //Tdryoutの出口温度計算用
   428  			Eoxdry := evac.Cmp.Elouts[1] //xdryoutの出口温度計算用
   429  			EoTwet := evac.Cmp.Elouts[2] //Twetoutの出口温度計算用
   430  			Eoxwet := evac.Cmp.Elouts[3] //xwetoutの出口温度計算用
   431  
   432  			// 出入口状態値の取得
   433  			evac.Tdryi = EoTdry.Elins[0].Sysvin
   434  			evac.Xdryi = EoTdry.Elins[1].Sysvin
   435  			evac.Tweti = EoTdry.Elins[2].Sysvin
   436  			evac.Xweti = EoTdry.Elins[3].Sysvin
   437  
   438  			evac.Tdryo = EoTdry.Sysv
   439  			evac.Xdryo = Eoxdry.Sysv
   440  			evac.Tweto = EoTwet.Sysv
   441  			evac.Xweto = Eoxwet.Sysv
   442  
   443  			Gdry = EoTdry.G
   444  			Gwet = EoTwet.G
   445  
   446  			// 相対湿度の計算
   447  			evac.RHdryi = FNRhtx(evac.Tdryi, evac.Xdryi)
   448  			evac.RHdryo = FNRhtx(evac.Tdryo, evac.Xdryo)
   449  			evac.RHweti = FNRhtx(evac.Tweti, evac.Xweti)
   450  			evac.RHweto = FNRhtx(evac.Tweto, evac.Xweto)
   451  
   452  			// 熱量の計算
   453  			evac.Qsdry = Ca * Gdry * (evac.Tdryo - evac.Tdryi)
   454  			evac.Qldry = Ro * Gdry * (evac.Xdryo - evac.Xdryi)
   455  			evac.Qtdry = evac.Qsdry + evac.Qldry
   456  			evac.Qswet = Ca * Gwet * (evac.Tweto - evac.Tweti)
   457  			evac.Qlwet = Ro * Gwet * (evac.Xweto - evac.Xweti)
   458  			evac.Qtwet = evac.Qswet + evac.Qlwet
   459  
   460  			N := cat.N * 5
   461  			//N2 := N * N
   462  
   463  			Sin = make([]float64, N)
   464  			Stat = make([]float64, N)
   465  
   466  			Sin[5*(1-1)+3] = Ca * Gdry * evac.Tdryi
   467  			Sin[5*(1-1)+4] = -evac.Xdryi
   468  			Sin[5*(cat.N-1)+0] = Ca * Gwet * evac.Tweti
   469  			Sin[5*(cat.N-1)+1] = Gwet * evac.Xweti
   470  
   471  			for ii := 0; ii < N; ii++ {
   472  				for jj := 0; jj < N; jj++ {
   473  					// 内部変数の計算
   474  					Stat[ii] += -evac.UX[ii*N+jj] * Sin[jj]
   475  				}
   476  				Stat[ii] += evac.UXC[ii]
   477  			}
   478  
   479  			// 内部変数計算結果の格納
   480  			Tdry = evac.Tdry
   481  			xdry = evac.Xdry
   482  			Twet = evac.Twet
   483  			xwet = evac.Xwet
   484  			Ts = evac.Ts
   485  			xs = evac.Xs
   486  			RHdry = evac.RHdry
   487  			RHwet = evac.RHwet
   488  			M = evac.M
   489  			Scmp = Stat
   490  			kx = evac.Kx
   491  			for ii := 0; ii < cat.N; ii++ {
   492  				Twet[ii] = Scmp[0]
   493  				xwet[ii] = Scmp[1]
   494  				Ts[ii] = Scmp[2]
   495  				Tdry[ii] = Scmp[3]
   496  				xdry[ii] = Scmp[4]
   497  				xs[ii] = FNXtr(Ts[ii], 100.0)
   498  
   499  				// 相対湿度の計算
   500  				RHdry[ii] = FNRhtx(Tdry[ii], xdry[ii])
   501  				RHwet[ii] = FNRhtx(Twet[ii], xwet[ii])
   502  
   503  				// 蒸発量の計算
   504  				M[ii] = kx[ii] * math.Max(xs[ii]-xwet[ii], 0.0) * cat.Awet
   505  
   506  				Scmp = Scmp[5:]
   507  			}
   508  		} else {
   509  			evac.Qsdry = 0.0
   510  			evac.Qldry = 0.0
   511  			evac.Qtdry = 0.0
   512  			evac.Qswet = 0.0
   513  			evac.Qlwet = 0.0
   514  			evac.Qtwet = 0.0
   515  			evac.Tdryi = 0.0
   516  			evac.Tdryo = 0.0
   517  			evac.Tweti = 0.0
   518  			evac.Tweto = 0.0
   519  			evac.Xdryi = 0.0
   520  			evac.Xdryo = 0.0
   521  			evac.Xweti = 0.0
   522  			evac.Xweto = 0.0
   523  			matinit(evac.M, cat.N)
   524  		}
   525  
   526  		evac.Count++
   527  		if evac.Count > 0 {
   528  			*Evacreset = 1
   529  		}
   530  	}
   531  }
   532  
   533  // カウンタのリセット
   534  func (eqsys *EQSYS) Evaccountreset() {
   535  	for _, evac := range eqsys.Evac {
   536  		evac.Count = 0
   537  	}
   538  }
   539  
   540  // 代表日の計算結果出力
   541  func Evacprint(fo io.Writer, id int, Evac []*EVAC) {
   542  	switch id {
   543  	case 0:
   544  		if len(Evac) > 0 {
   545  			fmt.Fprintf(fo, "%s %d\n", EVAC_TYPE, len(Evac))
   546  		}
   547  		for _, evac := range Evac {
   548  			fmt.Fprintf(fo, " %s 1 %d\n", evac.Name, 18+8*evac.Cat.N)
   549  		}
   550  
   551  	case 1:
   552  		for _, evac := range Evac {
   553  			// Wet側出力
   554  			fmt.Fprintf(fo, "%s_cw c c %s_Gw m f %s_Twi t f %s_Two t f %s_xwi x f %s_xwo x f\n",
   555  				evac.Name, evac.Name, evac.Name, evac.Name, evac.Name, evac.Name)
   556  			fmt.Fprintf(fo, "%s_Qws q f %s_Qwl q f %s_Qwt q f\n",
   557  				evac.Name, evac.Name, evac.Name)
   558  			// Dry側出力
   559  			fmt.Fprintf(fo, "%s_cd c c %s_Gd m f %s_Tdi t f %s_Tdo t f %s_xdi x f %s_xdo x f\n",
   560  				evac.Name, evac.Name, evac.Name, evac.Name, evac.Name, evac.Name)
   561  			fmt.Fprintf(fo, "%s_Qds q f %s_Qdl q f %s_Qdt q f\n",
   562  				evac.Name, evac.Name, evac.Name)
   563  			// 内部変数
   564  			for ii := 0; ii < evac.Cat.N; ii++ {
   565  				fmt.Fprintf(fo, "%s_Tw[%d] t f %s_xw[%d] x f %s_RHw[%d] r f %s_Ts[%d] t f %s_Td[%d] t f %s_xd[%d] x f %s_RHd[%d] r f %s_M[%d] m f\n",
   566  					evac.Name, ii, evac.Name, ii, evac.Name, ii, evac.Name, ii, evac.Name, ii, evac.Name, ii, evac.Name, ii, evac.Name, ii)
   567  			}
   568  		}
   569  
   570  	default:
   571  		for _, evac := range Evac {
   572  			// Wet側出力
   573  			elo := evac.Cmp.Elouts[2]
   574  			fmt.Fprintf(fo, "%c %g %.1f %.1f %.3f %.3f %.1f %.1f %.1f\n",
   575  				elo.Control, elo.G, evac.Tweti, evac.Tweto, evac.Xweti, evac.Xweto, evac.Qswet, evac.Qlwet, evac.Qtwet)
   576  			// Dry側出力
   577  			elo = evac.Cmp.Elouts[0]
   578  			fmt.Fprintf(fo, "%c %g %.1f %.1f %.3f %.3f %.1f %.1f %.1f\n",
   579  				elo.Control, elo.G, evac.Tdryi, evac.Tdryo, evac.Xdryi, evac.Xdryo, evac.Qsdry, evac.Qldry, evac.Qtdry)
   580  			// 内部変数
   581  			Tdry := evac.Tdry
   582  			xdry := evac.Xdry
   583  			Twet := evac.Twet
   584  			xwet := evac.Xwet
   585  			Ts := evac.Ts
   586  			RHdry := evac.RHdry
   587  			RHwet := evac.RHwet
   588  			M := evac.M
   589  			for ii := 0; ii < evac.Cat.N; ii++ {
   590  				fmt.Fprintf(fo, "%.1f %.3f %.0f %.1f %.1f %.3f %.0f %.3e\n",
   591  					Twet[ii], xwet[ii], RHwet[ii], Ts[ii], Tdry[ii], xdry[ii], RHdry[ii], M[ii])
   592  			}
   593  		}
   594  	}
   595  }