github.com/archlabjp/eeslism-go@v0.0.0-20231109122333-4bb7bfcdf292/eeslism/blhcflib.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  /*    bhcflib.c            */
    17  
    18  package eeslism
    19  
    20  import (
    21  	"fmt"
    22  	"math"
    23  )
    24  
    25  const (
    26  	Alidmy  = 9.3
    27  	ALITOLE = 1.e-5
    28  )
    29  
    30  /* -------------------------------------------------------------- */
    31  
    32  /*    熱伝達率に関する計算  */
    33  
    34  func Htrcf(alc, alo *float64, alotype AloType, Exs []*EXSF, Tr float64, N int, alr []float64, _Sd []*RMSRF, RMmrk *rune, Wd *WDAT) {
    35  	var n int
    36  	var alic float64
    37  	var hc *float64
    38  	//var dT float64
    39  
    40  	if DEBUG {
    41  		fmt.Printf("Htrcf Start\n")
    42  	}
    43  
    44  	for n = 0; n < N; n++ {
    45  		Sd := _Sd[n]
    46  
    47  		if DEBUG {
    48  			fmt.Printf("n=%d name=%s\n", n, get_string_or_null(Sd.Name))
    49  		}
    50  
    51  		// 室内側対流熱伝達率の計算
    52  		alic = -1.0
    53  
    54  		if alc != nil {
    55  			if *alc >= 0.01 {
    56  				alic = *alc
    57  			}
    58  		}
    59  
    60  		if DEBUG {
    61  			fmt.Printf("alic=%f\n", alic)
    62  		}
    63  
    64  		hc = nil
    65  
    66  		if DEBUG {
    67  			fmt.Printf("Sd->alicsch\n")
    68  		}
    69  
    70  		if Sd.alicsch != nil {
    71  			if DEBUG {
    72  				fmt.Printf("test\n")
    73  			}
    74  			hc = Sd.alicsch
    75  			if *hc >= 0.00 {
    76  				alic = *hc
    77  			}
    78  		}
    79  
    80  		if DEBUG {
    81  			fmt.Printf("hc set end\n")
    82  		}
    83  		if alic < 0.0 {
    84  			dT := Sd.Ts - Tr
    85  			switch Sd.ble {
    86  			case 'F', 'f':
    87  				if dT > 0 {
    88  					alic = alcvup(dT)
    89  				} else {
    90  					alic = alcvdn(dT)
    91  				}
    92  			case 'R', 'c':
    93  				if math.Abs(dT) <= 1.0e-3 {
    94  					alic = 0.0
    95  				} else if dT < 0 {
    96  					alic = alcvup(dT)
    97  				} else {
    98  					alic = alcvdn(dT)
    99  				}
   100  			default:
   101  				alic = alcvh(dT)
   102  			}
   103  		}
   104  
   105  		if DEBUG {
   106  			fmt.Printf("----- Htrcf n=%d mrk=%c alic=%f  Sd->alic=%f\n",
   107  				n, Sd.mrk, alic, Sd.alic)
   108  		}
   109  
   110  		if math.Abs(alic-Sd.alic) >= ALITOLE || Sd.mrk == '*' || Sd.PCMflg {
   111  			*RMmrk = '*'
   112  			Sd.mrk = '*'
   113  			Sd.alic = alic
   114  
   115  			switch Sd.ble {
   116  			case BLE_Window, BLE_ExternalWall, BLE_Floor, BLE_Roof:
   117  				Sd.alo = *Exs[Sd.exs].Alo
   118  			default:
   119  				Sd.alo = Alidmy
   120  			}
   121  		}
   122  
   123  		if Sd.mrk == '*' {
   124  			if Sd.alirsch == nil {
   125  				Sd.alir = alr[n*N+n]
   126  			} else if *Sd.alirsch > 0.0 {
   127  				Sd.alir = *Sd.alirsch
   128  			} else {
   129  				Sd.alir = 0.0
   130  			}
   131  
   132  			Sd.ali = alic + Sd.alir
   133  		}
   134  
   135  		if DEBUG {
   136  			fmt.Printf("----- Htrcf n=%2d ble=%c Ts=%.1f Tr=%.1f alic=%.3f alir=%.3f rmname=%s\n",
   137  				n, Sd.ble, Sd.Ts, Tr, Sd.alic, Sd.alir, Sd.room.Name)
   138  		}
   139  
   140  		//if dayprn && Ferr != nil {
   141  		fmt.Fprintf(Ferr, "----- Htrcf n=%2d ble=%c Ts=%f Tr=%f alic=%f alir=%f rmname=%s\n",
   142  			n, Sd.ble, Sd.Ts, Tr, Sd.alic, Sd.alir, Sd.room.Name)
   143  		//}
   144  	}
   145  }
   146  
   147  /*-----------------------------------------------------*/
   148  // 屋外側熱伝達率の計算
   149  func alov(Exs *EXSF, Wd *WDAT) float64 {
   150  	var u float64
   151  
   152  	Wv := Wd.Wv
   153  	Wdre := -180.0 + 360.0/16.0*Wd.Wdre
   154  
   155  	Wadiff := math.Abs(Exs.Wa - Wdre)
   156  	Wadiff = math.Mod(Wadiff, 360.0)
   157  	if Wadiff < 45.0 {
   158  		if Wv <= 2.0 {
   159  			u = 0.5
   160  		} else {
   161  			u = 0.25 * Wv
   162  		}
   163  	} else {
   164  		u = 0.3 + 0.05*Wv
   165  	}
   166  
   167  	return 3.5 + 5.6*u
   168  }
   169  
   170  /* ---------------------------------------- */
   171  
   172  /*  室内表面対流熱伝達率の計算     */
   173  
   174  func alcvup(dT float64) float64 {
   175  	return 2.18 * math.Pow(math.Abs(dT), 0.31)
   176  }
   177  
   178  func alcvdn(dT float64) float64 {
   179  	return 0.138 * math.Pow(math.Abs(dT), 0.25)
   180  }
   181  
   182  func alcvh(dT float64) float64 {
   183  	return 1.78 * math.Pow(math.Abs(dT), 0.32)
   184  }
   185  
   186  /* --------------------------------------- */
   187  
   188  /*  室内表面間放射熱伝達率の計算  */
   189  
   190  func Radcf0(Tsav float64, alrbold *float64, N int, Sd []*RMSRF, W, alr []float64) {
   191  	var n int
   192  	var alir, TA float64
   193  
   194  	TA = Tsav + 273.15
   195  	alir = 4.0 * Sgm * math.Pow(TA, 3.0)
   196  
   197  	/*****/
   198  	if DEBUG {
   199  		fmt.Printf("----- Radcf0   alir=%f  alrbold=%f ALITOLE\n", alir, *alrbold)
   200  	}
   201  	/*****/
   202  
   203  	if math.Abs(alir-*alrbold) >= ALITOLE {
   204  		*alrbold = alir
   205  
   206  		for n = 0; n < N; n++ {
   207  			Sd[n].mrk = '*'
   208  		}
   209  
   210  		for n = 0; n < N*N; n++ {
   211  			alr[n] = alir * math.Abs(W[n])
   212  
   213  			/*****fmt.Printf("----- Radcf0  n=%d alr=%f\n",n, alr[n])
   214  			 *****/
   215  		}
   216  	}
   217  }
   218  
   219  /* ------------------------------------------- */
   220  
   221  /*  放射伝達係数の計算  */
   222  
   223  func radex(N int, Sd []*RMSRF, F, W []float64) {
   224  	wk := make([]float64, N*N)
   225  	Ff := make([]float64, N*N)
   226  
   227  	for l, n := 0, 0; n < N; n++ {
   228  		for j := 0; j < N; j++ {
   229  			wk[l] = -F[l] * (1.0 - Sd[j].Ei) / Sd[j].Ei
   230  
   231  			if DEBUG {
   232  				fmt.Printf("j=%d F=%f Sd=%f wk=%f\n", j, F[l], Sd[j].Ei, wk[l])
   233  			}
   234  
   235  			Ff[l] = -F[l]
   236  			l++
   237  		}
   238  		nn := n*N + n
   239  		wk[nn] += 1.0 / Sd[n].Ei
   240  
   241  		if DEBUG {
   242  			fmt.Printf("nn=%d Sd=%f wk=%f\n", nn, Sd[0].Ei, wk[nn])
   243  		}
   244  
   245  		Ff[nn] += 1.0
   246  	}
   247  
   248  	if DEBUG {
   249  		fmt.Printf("<radex>  wk\n")
   250  		Matprint(" %6.4f", N, wk)
   251  	}
   252  
   253  	Matinv(wk, N, N, "<radex>")
   254  
   255  	if DEBUG {
   256  		fmt.Print("<radex>  wkinv\n")
   257  		Matprint(" %6.4f", N, wk)
   258  	}
   259  
   260  	for i := 0; i < N; i++ {
   261  		for j := 0; j < N; j++ {
   262  			c := 0.0
   263  			for k := 0; k < N; k++ {
   264  				c += wk[N*i+k] * Ff[N*k+j]
   265  			}
   266  			W[N*i+j] = c
   267  		}
   268  	}
   269  
   270  	if DEBUG {
   271  		fmt.Printf("<radex>  W[i,j]\n")
   272  		Matprint(" %6.4f", N, W)
   273  	}
   274  }
   275  
   276  /* ------------------------------------------- */
   277  
   278  /* 形態係数の近似計算  */
   279  
   280  func formfaprx(N int, Aroom float64, Sd []*RMSRF, F []float64) {
   281  	var i, n int
   282  
   283  	for n = 0; n < N; n++ {
   284  		F[n] = Sd[n].A / Aroom
   285  
   286  		for i = 0; i < N; i++ {
   287  			F[i*N+n] = F[n]
   288  		}
   289  	}
   290  }
   291  
   292  /* ------------------------------------------- */
   293  
   294  /*  短波長放射吸収係数 */
   295  
   296  func Radshfc(N int, FArea, Aroom float64, Sd0 []*RMSRF, tfsol, eqcv float64, Rmname string, fsolm *float64) {
   297  	var Sumsrg2, dblTemp, Srgchk float64
   298  	Room := Sd0[0].room
   299  
   300  	Sumsrg2 = 0.0
   301  
   302  	// tfsol:定義済みの部位日射吸収係数の合計値
   303  	for n := 0; n < N; n++ {
   304  		Sd := Sd0[n]
   305  		Sd.eqrd = (1.0 - eqcv) * Sd.A / Aroom
   306  
   307  		dblTemp = math.Max((1.0-tfsol), 0.0) * Sd.A / Aroom
   308  		if Sd.fsol != nil {
   309  			v := *(Sd.fsol) + dblTemp
   310  			Sd.srg = v
   311  			Sd.srh = v
   312  			Sd.srl = v
   313  			Sd.sra = v
   314  		} else {
   315  			Sd.srg = dblTemp
   316  			Sd.srh = dblTemp
   317  			Sd.srl = dblTemp
   318  			Sd.sra = dblTemp
   319  		}
   320  
   321  		Sd.srg2 = Sd.srg
   322  		if Sd.RStrans {
   323  			Sd.srg2 = 0.0
   324  		}
   325  		if Sd.tnxt > 0.0 {
   326  			Sd.srg2 = Sd.srg * (1.0 - Sd.tnxt)
   327  		}
   328  		Sumsrg2 += Sd.srg2
   329  	}
   330  
   331  	Room.Srgm2 = 0.0
   332  	if fsolm != nil {
   333  		Room.Srgm2 = *fsolm
   334  	}
   335  
   336  	//  各種部位の吸収係数のチェック
   337  	Srgchk = 0.0
   338  
   339  	// 家具の日射吸収割合を加算
   340  	if fsolm != nil {
   341  		Srgchk += *fsolm
   342  		Sumsrg2 += *fsolm
   343  	}
   344  
   345  	for n := 0; n < N; n++ {
   346  		Sd := Sd0[n]
   347  		Srgchk += Sd.srg
   348  	}
   349  
   350  	if math.Abs(Srgchk-1.0) > 1.0e-3 {
   351  		fmt.Printf("xxxxx (%s)  室内部位への日射吸収比率の合計が不適 %.3f (本来、1となるべき)\n", Rmname, Srgchk)
   352  	}
   353  
   354  	if tfsol > 1.0 {
   355  		fmt.Printf("xxxxx (%s)  室内部位への日射吸収比率を指定したものだけで合計が不適 %.3f (本来、1未満となるべき)\n", Rmname, tfsol)
   356  	}
   357  
   358  	// 最終日射吸収比率の計算(Sumsrg2で基準化)
   359  	for n := 0; n < N; n++ {
   360  		Sd := Sd0[n]
   361  		Sd.srg2 /= Sumsrg2
   362  	}
   363  
   364  	if fsolm != nil {
   365  		Room.Srgm2 /= Sumsrg2
   366  	}
   367  }