github.com/archlabjp/eeslism-go@v0.0.0-20231109122333-4bb7bfcdf292/eeslism/blpanel.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  /*   bl_panel.c  */
    17  
    18  package eeslism
    19  
    20  import (
    21  	"errors"
    22  	"math"
    23  )
    24  
    25  const WPTOLE = 1.0e-10
    26  
    27  /*  輻射パネル有効熱容量流量  */
    28  
    29  func panelwp(rdpnl *RDPNL) {
    30  	sd := rdpnl.sd[0]
    31  	eo := rdpnl.cmp.Elouts[0]
    32  	wall := sd.mw.wall
    33  
    34  	var Kc, Kcd float64
    35  	if wall.chrRinput {
    36  		Kc = sd.dblKc
    37  		Kcd = sd.dblKcd
    38  	} else {
    39  		Kc = wall.Kc
    40  		Kcd = wall.Kcd
    41  	}
    42  
    43  	if eo.Control != OFF_SW && rdpnl.cmp.Elins[0].Upv != nil {
    44  		rdpnl.cG = eo.G * Spcheat(eo.Fluid)
    45  
    46  		if wall.WallType == WallType_P {
    47  			rdpnl.Wp = rdpnl.cG * rdpnl.effpnl / sd.A
    48  		} else {
    49  			rdpnl.Ec = 1.0 - math.Exp(-Kc*sd.A/rdpnl.cG)
    50  			rdpnl.Wp = Kcd * rdpnl.cG * rdpnl.Ec / (Kc * sd.A)
    51  		}
    52  	} else {
    53  		rdpnl.cG = 0.0
    54  		rdpnl.Ec = 0.0
    55  		rdpnl.Wp = 0.0
    56  	}
    57  
    58  	// 流量が前時刻から変化していれば係数行列を作りなおす
    59  	if math.Abs(rdpnl.Wp-rdpnl.Wpold) >= WPTOLE || sd.PCMflg {
    60  		rdpnl.Wpold = rdpnl.Wp
    61  
    62  		for i := 0; i < rdpnl.MC; i++ {
    63  			rdpnl.sd[i].mrk = '*' // 表面の係数行列再作成
    64  			rdpnl.rm[i].mrk = '*' // 室の係数行列再作成
    65  		}
    66  	}
    67  }
    68  
    69  /* -------------------------------------- */
    70  
    71  /*  輻射パネル計算用係数    */
    72  
    73  func Panelcf(rdpnl *RDPNL) {
    74  	var j, nn, m, mp, M, iup, nrp, n, N int
    75  	var epr, epw *float64
    76  	var ew, kd float64
    77  	var rm *ROOM
    78  	var Sd, Sdd *RMSRF
    79  	var wall *WALL
    80  	var Mw *MWALL
    81  	var C1 float64
    82  
    83  	if rdpnl.Wp > 0.0 {
    84  		for m = 0; m < rdpnl.MC; m++ {
    85  			Sd = rdpnl.sd[m]
    86  			rm = rdpnl.rm[m]
    87  			N = rm.N
    88  			nrp = m
    89  			nn = N * nrp
    90  
    91  			if Sd.mrk == '*' || Sd.PCMflg {
    92  				if m == 0 {
    93  					Mw = Sd.mw
    94  					mp = Mw.mp
    95  					M = Mw.M
    96  
    97  					iup = mp * M
    98  
    99  					rdpnl.FIp[m] = Mw.UX[iup] * Mw.uo
   100  					if Mw.wall.WallType == WallType_P { // 通常の床暖房パネル
   101  						rdpnl.FOp[m] = Mw.UX[iup+M-1] * Mw.um
   102  					} else if Mw.wall.WallType == WallType_C { // 屋根一体型空気集熱器
   103  						rdpnl.FOp[m] = Mw.UX[iup+M-1] * Sd.ColCoeff
   104  					}
   105  					rdpnl.FPp = Mw.UX[iup+mp] * Mw.Pc * rdpnl.Wp
   106  				} else {
   107  					Mw = Sd.mw
   108  					rdpnl.FIp[1] = rdpnl.FOp[0]
   109  					rdpnl.FOp[1] = rdpnl.FIp[0]
   110  				}
   111  
   112  				wall = Mw.wall
   113  				C1 = Sd.alic
   114  				for j = 0; j < N; j++ {
   115  					alr := rm.alr[nn+j]
   116  					Sdd = rm.rsrf[j]
   117  					if j != nrp {
   118  						C1 += alr * Sdd.WSR
   119  					}
   120  				}
   121  				C1 *= rdpnl.FIp[m] / Sd.ali
   122  
   123  				if wall.WallType == WallType_P { // 床暖房パネル
   124  					rdpnl.EPt[m] = C1 * rdpnl.Wp * Sd.A
   125  				} else { // 屋根一体型空気集熱器
   126  					if wall.chrRinput { // 集熱器の特性が熱抵抗で入力されている場合
   127  						kd = Sd.kd
   128  					} else {
   129  						kd = wall.kd
   130  					}
   131  					rdpnl.EPt[m] = C1 * rdpnl.cG * rdpnl.Ec * kd
   132  				}
   133  
   134  				for j = 0; j < rm.Ntr; j++ {
   135  					epr = &rdpnl.EPR[m][j]
   136  
   137  					*epr = 0.0
   138  					for n = 0; n < N; n++ {
   139  						alr := rm.alr[nn+n]
   140  						Sdd := rm.rsrf[n]
   141  
   142  						if n != nrp {
   143  							*epr += alr * Sdd.WSRN[j]
   144  						}
   145  					}
   146  					if wall.WallType == WallType_P {
   147  						*epr *= rdpnl.FIp[m] / Sd.ali * rdpnl.Wp * Sd.A
   148  					} else {
   149  						if wall.chrRinput {
   150  							kd = Sd.kd
   151  						} else {
   152  							kd = wall.kd
   153  						}
   154  
   155  						*epr *= rdpnl.FIp[m] / Sd.ali * rdpnl.cG * rdpnl.Ec * kd
   156  						//*epr *= rdpnl.FIp[m] / Sd.ali * rdpnl.cG * rdpnl.Ec * wall.KdKo ;
   157  					}
   158  
   159  					/*********
   160  					*epr += rdpnl.FOp[m] * Sd.nxsd.alic / Sd.nxsd.ali;
   161  					***********/
   162  				}
   163  				if wall.WallType == WallType_P { // 通常の床暖房パネル
   164  					rdpnl.Epw = rdpnl.Wp * Sd.A * (1.0 - rdpnl.FPp)
   165  				} else { // 屋根一体型空気集熱器
   166  					if wall.chrRinput {
   167  						kd = Sd.kd
   168  					} else {
   169  						kd = wall.kd
   170  					}
   171  
   172  					rdpnl.Epw = rdpnl.cG * (1.0 - rdpnl.Ec*(1.-kd*rdpnl.FPp))
   173  				}
   174  				//}
   175  				//else
   176  				//	rdpnl.Epw = 1. - rdpnl.Ec * ( 1. + wall.KdKo * Sd.FP ) ;
   177  
   178  				for j = 0; j < rm.Nrp; j++ {
   179  					epw = &rdpnl.EPW[m][j]
   180  
   181  					ew = 0.0
   182  					for n = 0; n < N; n++ {
   183  						alr := rm.alr[nn+n]
   184  						Sdd := rm.rsrf[n]
   185  
   186  						if n != nrp {
   187  							ew += alr * Sdd.WSPL[j]
   188  						}
   189  					}
   190  
   191  					if wall.WallType == WallType_P {
   192  						*epw = rdpnl.Wp * Sd.A * rdpnl.FIp[m] * ew / Sd.ali
   193  					} else {
   194  						if wall.chrRinput {
   195  							kd = Sd.kd
   196  						} else {
   197  							kd = wall.kd
   198  						}
   199  
   200  						*epw = rdpnl.cG * rdpnl.FIp[m] * ew / Sd.ali * rdpnl.Ec * kd
   201  					}
   202  				}
   203  			}
   204  		}
   205  	} else {
   206  		rdpnl.Epw = 0.0
   207  		for m = 0; m < rdpnl.MC; m++ {
   208  			rm = rdpnl.rm[m]
   209  			rdpnl.EPt[m] = 0.0
   210  
   211  			for j = 0; j < rm.Ntr; j++ {
   212  				epr = &rdpnl.EPR[m][j]
   213  				*epr = 0.0
   214  			}
   215  
   216  			for j = 0; j < rm.Nrp; j++ {
   217  				epw = &rdpnl.EPW[m][j]
   218  				*epw = 0.0
   219  			}
   220  		}
   221  	}
   222  }
   223  
   224  /* -------------------------------------------- */
   225  
   226  /*  輻射パネルの外乱に関する項の計算     */
   227  
   228  func Panelce(rdpnl *RDPNL) float64 {
   229  	var N int
   230  	var rm *ROOM
   231  	var Sd *RMSRF
   232  	var Mw *MWALL
   233  	var j, nn, m, mp, M, iup, nrp int
   234  	var CFp, C, CC, kd, ku float64
   235  	var wall *WALL
   236  
   237  	Sd = nil
   238  	Mw = nil
   239  	wall = nil
   240  	CC = 0.0
   241  
   242  	if rdpnl.Wp > 0.0 {
   243  		for m = 0; m < rdpnl.MC; m++ {
   244  			Sd = rdpnl.sd[m]
   245  
   246  			if m == 0 {
   247  				Mw = Sd.mw
   248  				mp = Mw.mp
   249  				M = Mw.M
   250  				wall = Mw.wall
   251  
   252  				iup = mp * M
   253  				CFp = 0.0
   254  				for j = 0; j < M; j++ {
   255  					CFp += Mw.UX[iup+j] * Mw.Told[j]
   256  				}
   257  
   258  				CC = CFp
   259  				if Mw.wall.WallType == WallType_C {
   260  					if Mw.wall.chrRinput {
   261  						kd = Sd.kd
   262  					} else {
   263  						kd = Mw.wall.kd
   264  					}
   265  					CC = CFp * kd
   266  				}
   267  				if rdpnl.MC == 1 {
   268  					if Mw.wall.WallType == WallType_P {
   269  						CC += rdpnl.FOp[m] * Sd.Te
   270  					} else {
   271  						if wall.chrRinput {
   272  							kd = Sd.kd
   273  							ku = Sd.ku
   274  						} else {
   275  							kd = Mw.wall.kd
   276  							ku = Mw.wall.ku
   277  						}
   278  						CC += (ku + kd*rdpnl.FOp[m]) * Sd.Tcoleu
   279  					}
   280  				}
   281  			}
   282  
   283  			rm = rdpnl.rm[m]
   284  			N = rm.N
   285  			nrp = m
   286  			nn = N * nrp
   287  
   288  			C = 0.0
   289  			for j = 0; j < N; j++ {
   290  				alr := rm.alr[nn+j]
   291  				Sdd := rm.rsrf[j]
   292  				if j != nrp {
   293  					C += alr * Sdd.WSC
   294  				}
   295  			}
   296  
   297  			if Mw.wall.WallType == WallType_P {
   298  				CC += rdpnl.FIp[m] * (Sd.RS + C) / Sd.ali
   299  			} else {
   300  				if wall.chrRinput {
   301  					kd = Sd.kd
   302  					ku = Sd.ku
   303  				} else {
   304  					kd = Mw.wall.kd
   305  					ku = Mw.wall.ku
   306  				}
   307  				CC += kd * rdpnl.FIp[m] * (Sd.RS + C) / Sd.ali
   308  			}
   309  		}
   310  
   311  		if Mw.wall.WallType == WallType_P {
   312  			return (CC * rdpnl.Wp * Sd.A)
   313  		} else {
   314  			return (CC * rdpnl.cG * rdpnl.Ec)
   315  		}
   316  	} else {
   317  		return (0.0)
   318  	}
   319  }
   320  
   321  /* --------------------------- */
   322  
   323  /* 負荷計算用設定値のポインター */
   324  
   325  func rdpnlldsptr(load *ControlSWType, key []string, Rdpnl *RDPNL, idmrk *byte) (VPTR, error) {
   326  	var err error
   327  	var vptr VPTR
   328  
   329  	if key[1] == "Tout" {
   330  		vptr.Ptr = &Rdpnl.Toset
   331  		vptr.Type = VAL_CTYPE
   332  		Rdpnl.Loadt = load
   333  		*idmrk = 't'
   334  	} else {
   335  		err = errors.New("Tout is expected")
   336  	}
   337  
   338  	return vptr, err
   339  }
   340  
   341  /* ------------------------------------------ */
   342  
   343  /* 負荷計算用設定値のスケジュール設定 */
   344  
   345  func rdpnlldsschd(Rdpnl *RDPNL) {
   346  	Eo := Rdpnl.cmp.Elouts[0]
   347  
   348  	if Rdpnl.Loadt != nil {
   349  		if Eo.Control != OFF_SW {
   350  			if Rdpnl.Toset > TEMPLIMIT {
   351  				Eo.Control = ON_SW
   352  				//Eo.Control = LOAD_SW
   353  				//Eo.Sysv = Rdpnl.Toset
   354  			} else {
   355  				Eo.Control = OFF_SW
   356  			}
   357  		}
   358  	}
   359  }
   360  
   361  /* ------------------------------------- */
   362  
   363  /*  屋根一体型集熱器内部変数のポインター  */
   364  
   365  func rdpnlvptr(key []string, Rdpnl *RDPNL) (VPTR, error) {
   366  	var err error
   367  	var vptr VPTR
   368  
   369  	if Rdpnl.sd[0].mw.wall.WallType == WallType_C && key[1] == "Te" {
   370  		vptr.Ptr = &Rdpnl.sd[0].Tcole
   371  		vptr.Type = VAL_CTYPE
   372  	} else {
   373  		err = errors.New("rdpnlvptr error")
   374  	}
   375  
   376  	return vptr, err
   377  }