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

     1  /* ==================================================================
     2  
     3  PSYLIB
     4  
     5  湿り空気の状態値計算用ライブラリ-
     6  (宇田川、パソコンによる空気調和計算法、プログラム3.1の C 言語版, ANSI C 版)
     7  
     8  --------------------------------------------------------------------- */
     9  
    10  package eeslism
    11  
    12  import (
    13  	"fmt"
    14  	"math"
    15  )
    16  
    17  var _R0, _Ca, _Cv, _Rc, _Cc, _Cw, _Pcnv, _P float64 = 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
    18  
    19  func Psyint() {
    20  	if UNIT == "SI" {
    21  		_P = 101.325
    22  		_R0 = 2501000.0
    23  		_Ca = 1005.0
    24  		_Cv = 1846.0
    25  		_Rc = 333600.0
    26  		_Cc = 2093.0
    27  		_Cw = 4186.0
    28  		_Pcnv = 1.0
    29  	} else {
    30  		_P = 760.0
    31  		_R0 = 597.5
    32  		_Ca = 0.24
    33  		_Cv = 0.441
    34  		_Rc = 79.7
    35  		_Cc = 0.5
    36  		_Cw = 1.0
    37  		_Pcnv = 7.50062
    38  	}
    39  }
    40  
    41  func Poset(Po float64) {
    42  	_P = Po
    43  }
    44  
    45  func FNPo() float64 {
    46  	return _P
    47  }
    48  
    49  // ---- 露点温度 ----
    50  
    51  // 湿り空気を冷却していくと、やがて飽和空気となる。このときの温度を露点温度という。
    52  // 飽和空気にはこれ以上水分を含むことができず、これ以上冷却すると結露が生じる。
    53  // 飽和空気の全圧のうち、水蒸気が占める圧力(水蒸気分圧)である飽和水蒸気圧 Pws [kPa] を求める。
    54  // 計算にはウェククスラー・ハイランド(Wexler-Hyland)による式を用いる。
    55  // See: パソコンによる空気調和計算法 P.27
    56  func FNPws(T float64) float64 {
    57  
    58  	// 絶対温度 Tabs
    59  	Tabs := T + 273.15
    60  	if math.Abs(Tabs) < 1e-5 {
    61  		fmt.Printf("xxxx ゼロ割が発生しています Tabs=%f\n", Tabs)
    62  	}
    63  
    64  	// 飽和水蒸気分圧 Pws
    65  	var Pws float64
    66  	if T > 0.0 {
    67  		// 0から200℃の水と接する場合
    68  		Pws = math.Exp(6.5459673*math.Log(Tabs)-5800.2206/Tabs+1.3914993+Tabs*(-0.048640239+
    69  			Tabs*(4.1764768e-5-1.4452093e-8*Tabs))) / 1000.0
    70  	} else {
    71  		// -100から0℃の氷と接する場合
    72  		Pws = math.Exp(-5674.5359/Tabs+6.3925247+Tabs*(-9.677843e-3+
    73  			Tabs*(6.2215701e-7+Tabs*(2.0747825e-9-9.484024e-13*Tabs)))+4.1635019*math.Log(Tabs)) / 1000.0
    74  	}
    75  
    76  	// 単位変換
    77  	return _Pcnv * Pws
    78  }
    79  
    80  // 水蒸気分圧 Pw [kPa] から露点温度を求める
    81  // NOTE:
    82  // - 611.2 Paは、水の飽和蒸気圧に関連する値であり、これはおおよそ0℃の飽和蒸気圧に相当します。
    83  //
    84  // See: パソコンによる空気調和計算法 P.28
    85  func FNDp(Pw float64) float64 {
    86  	// 水蒸気分圧の単位をPaに変換
    87  	Pwx := Pw * 1000.0 / _Pcnv
    88  
    89  	Y := math.Log(Pwx)
    90  
    91  	// 近似式を用いて水蒸気分圧から露点温度を求める
    92  	if Pwx >= 611.2 {
    93  		// 0から50℃のとき
    94  		// NOTE: 611.2[Pa]はおおよそ0℃の飽和蒸気圧である.
    95  		return -77.199 + Y*(13.198+Y*(-0.63772+0.071098*Y))
    96  	} else {
    97  		// -50から0℃のとき
    98  		return -60.662 + Y*(7.4624+Y*(0.20594+0.016321*Y))
    99  	}
   100  }
   101  
   102  func FNDbxr(X, Rh float64) float64 {
   103  	return FNDbrp(Rh, FNPwx(X))
   104  }
   105  
   106  func FNDbxh(X, H float64) float64 {
   107  	return (H - _R0*X) / (_Ca + _Cv*X)
   108  }
   109  func FNDbxw(X, Twb float64) float64 {
   110  	Hc := FNHc(Twb)
   111  	return ((_Ca*Twb + (_Cv*Twb+_R0-Hc)*FNXp(FNPws(Twb)) - (_R0-Hc)*X) / (_Ca + _Cv*X))
   112  }
   113  
   114  func FNDbrh(Rh, H float64) float64 {
   115  	var T0, F, Fd, Dbrh float64
   116  	T0 = math.Min(FNDbxh(0., H), 30.)
   117  	for I := 1; I <= 10; I++ {
   118  		F = H - FNH(T0, FNXtr(T0, Rh))
   119  		Fd = (H - FNH(T0+.1, FNXtr(T0+.1, Rh)) - F) / .1
   120  		Dbrh = T0 - F/Fd
   121  		if math.Abs(Dbrh-T0) <= .02 {
   122  			return Dbrh
   123  		}
   124  		T0 = Dbrh
   125  	}
   126  	fmt.Printf("XXX FNDbrh  (T-T0)=%f\n", Dbrh-T0)
   127  	return Dbrh
   128  }
   129  
   130  func FNDbrw(Rh, Twb float64) float64 {
   131  	var T0, F, Fd, Dbrw float64
   132  	T0 = Twb
   133  	for I := 1; I <= 10; I++ {
   134  		F = T0 - FNDbxw(FNXtr(T0, Rh), Twb)
   135  		Fd = (T0 + .1 - FNDbxw(FNXtr(T0+.1, Rh), Twb) - F) / .1
   136  		Dbrw = T0 - F/Fd
   137  		if math.Abs(Dbrw-T0) <= .02 {
   138  			return Dbrw
   139  		}
   140  		T0 = Dbrw
   141  	}
   142  	fmt.Printf("XXX FNDbrw  (T-T0)=%f\n", Dbrw-T0)
   143  	return Dbrw
   144  }
   145  
   146  // --- 相対湿度、比較湿度 ---
   147  
   148  // 湿り空気の水蒸気分圧 Pw [kPa] から絶対湿度 x [kg/kg]を求める。
   149  // 絶対湿度とは、湿り空気の水蒸気と乾き空気の質量の比である。
   150  // See: パソコンによる空気調和計算法 P.29
   151  func FNXp(Pw float64) float64 {
   152  	// 標準大気圧 P [kPa]
   153  	P := 101.325
   154  
   155  	if math.Abs(P-Pw) < 1.0e-4 {
   156  		fmt.Printf("xxxxx ゼロ割が発生しています P=%f Pw=%f\n", P, Pw)
   157  	}
   158  
   159  	// 絶対湿度 x [kg/kg]
   160  	x := 0.62198 * Pw / (P - Pw)
   161  
   162  	return x
   163  }
   164  
   165  // 温度 T [C] および 相対湿度 Rh [%] から絶対湿度 x [kg/kg] を求める
   166  func FNXtr(T, Rh float64) float64 {
   167  	return FNXp(FNPwtr(T, Rh))
   168  }
   169  
   170  func FNXtw(T, Twb float64) float64 {
   171  	Hc := FNHc(Twb)
   172  	return ((_R0+_Cv*Twb-Hc)*FNXp(FNPws(Twb)) - _Ca*(T-Twb)) / (_Cv*T + _R0 - Hc)
   173  }
   174  
   175  // 絶対湿度 x [kg/kg] から 水蒸気分圧 Pw [kPa] を求める。
   176  // See: パソコンによる空気調和計算法 P.29
   177  func FNPwx(X float64) float64 {
   178  	// 標準大気圧 P [kPa]
   179  	P := 101.325
   180  
   181  	// 水蒸気分圧 Pw [kPa]
   182  	Pw := (X * P / (X + 0.62198))
   183  
   184  	return Pw
   185  }
   186  
   187  // 温度 T [C] および 湿り空気の水蒸気分圧 Pw [kPa] から 相対湿度 φ [%] を求める。
   188  // 相対湿度は水蒸気分圧を飽和水蒸気圧の百分率である。
   189  // See: パソコンによる空気調和計算法 P.29
   190  func FNRhtp(T, Pw float64) float64 {
   191  	return 100.0 * Pw / FNPws(T)
   192  }
   193  
   194  // 温度 T [C] および 相対湿度 Rh [%] から 湿り空気の水蒸気分圧 Pw [kPa] を求める。
   195  // See: パソコンによる空気調和計算法 P.29
   196  func FNPwtr(T, Rh float64) float64 {
   197  	return (Rh * FNPws(T) / 100.0)
   198  }
   199  
   200  // 相対湿度φ [%]と水蒸気分圧Pwから 乾球温度 Tを求める。
   201  func FNDbrp(Rh, Pw float64) float64 {
   202  	return FNDp(100.0 / Rh * Pw)
   203  }
   204  
   205  // 温度 T [C] および 湿り空気の水蒸気分圧 Pw [kPa] から 相対湿度 φ [%] を求める。
   206  func FNRhtx(T, X float64) float64 {
   207  	return FNRhtp(T, FNPwx(X))
   208  }
   209  
   210  // 乾燥空気の温度 t [C] と絶対湿度 x [kg/kg] から、湿り空気のエンタルピ h [J/kg] を求める。
   211  // ここで、Tは乾燥空気の温度、Xは水蒸気の質量分率(乾燥空気に対する水蒸気の質量比)である。
   212  // エンタルピーは、乾燥空気の比熱を用いた温度の項と、水蒸気の比熱及び蒸発熱を用いた温度と絶対湿度の項の和として計算される。
   213  // See: パソコンによる空気調和計算法 P.29
   214  func FNH(T, X float64) float64 {
   215  	// 定数
   216  	Ca := 1005.0    // 乾き空気の定格比熱, 1005 J/kgK (0.240 kcal/kgC)
   217  	Cv := 1846.0    // 水蒸気の低圧比熱, 1846 J/kgK (0.441 kcal/kgC)
   218  	r0 := 2501000.0 // 0℃の水の蒸発潜熱, 2501x10^3 J/kg (597.5 kcak/kg)
   219  
   220  	// エンタルピー h
   221  	h := Ca*T + (Cv*T+r0)*X
   222  
   223  	return h
   224  }
   225  
   226  // 乾燥空気の温度 t [C]とエンタルピー h [J/kg]から
   227  func FNXth(T, h float64) float64 {
   228  	// 定数
   229  	Ca := 1005.0    // 乾き空気の定格比熱, 1005 J/kgK (0.240 kcal/kgC)
   230  	Cv := 1846.0    // 水蒸気の低圧比熱, 1846 J/kgK (0.441 kcal/kgC)
   231  	r0 := 2501000.0 // 0℃の水の蒸発潜熱, 2501x10^3 J/kg (597.5 kcak/kg)
   232  
   233  	return (h - Ca*T) / (Cv*T + r0)
   234  }
   235  
   236  func FNWbtx(T float64, X float64) float64 {
   237  	var Tw0, H, Xs, Xss, F, Fd, Wbtx float64
   238  	Tw0 = T
   239  	H = FNH(T, X)
   240  	for I := 1; I <= 10; I++ {
   241  		Xs = FNXp(FNPws(Tw0))
   242  		F = FNH(Tw0, Xs) - H - (Xs-X)*FNHc(Tw0)
   243  		Xss = FNXp(FNPws(Tw0 + .1))
   244  		Fd = (FNH(Tw0+.1, Xss) - H - (Xss-X)*FNHc(Tw0+.1) - F) / .1
   245  		Wbtx = Tw0 - F/Fd
   246  		if math.Abs(Wbtx-Tw0) <= .02 {
   247  			return Wbtx
   248  		}
   249  		Tw0 = Wbtx
   250  	}
   251  	fmt.Printf("XXX FNWbtx  (Twb-Tw0)=%f\n", Wbtx-Tw0)
   252  	return Wbtx
   253  }
   254  
   255  func FNHc(Twb float64) float64 {
   256  	var Hc float64 // declare and initialize Hc variable
   257  	if Twb >= 0.0 {
   258  		Hc = _Cw * Twb
   259  	} else {
   260  		Hc = -_Rc + _Cc*Twb
   261  	}
   262  	return Hc
   263  }