github.com/archlabjp/eeslism-go@v0.0.0-20231109122333-4bb7bfcdf292/eeslism/blrmdata.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  /*  rmdata.c   */
    17  package eeslism
    18  
    19  import (
    20  	"fmt"
    21  	"math"
    22  	"os"
    23  	"regexp"
    24  	"strconv"
    25  	"strings"
    26  	"unicode"
    27  )
    28  
    29  /* -------------------------------------------- */
    30  
    31  /*  室構成部材の入力  */
    32  
    33  func Roomdata(tokens *EeTokens, Exs []*EXSF, dfwl *DFWL, Rmvls *RMVLS, Schdl *SCHDL, Simc *SIMCONTL) {
    34  	// var Wall, w *WALL
    35  	// var Window, W *WINDOW
    36  	// var Snbk, S *SNBK
    37  	// var Room, room, Rm, Rc, Rmchk *ROOM
    38  	// var rdpnl, Rd *RDPNL
    39  	// var Sd, rsd, nxsd, Sdj *RMSRF
    40  	// var Nroom, Nrdpnl, Nsrf int
    41  	// var N, Nnxrm int
    42  	// var Nwindow, Nwall, Nexs, Nsnbk int
    43  	// var Nairflow int
    44  	// var e *EXSF
    45  	// var Scw, Sch *SCH
    46  	// var Schdl.Val []float64
    47  	// var Ac *ACHIR
    48  	// var ca, roa float64
    49  	// var NSTOP int
    50  	// var i int
    51  
    52  	errkey := "Roomdata"
    53  
    54  	//i := -1
    55  	var j, n, nr, brs, ij, N2, k, l int
    56  	n = -1
    57  	brs = 0
    58  	//var s, ss string
    59  	//var st, ce, stt string
    60  	var dexsname, dnxrname string
    61  	var Er string
    62  	var sfemark bool
    63  	var RmnameEr string
    64  
    65  	//stt := ""
    66  	//sprintf(s, "No. 1") ;
    67  	//HeapCheck(s) ;
    68  
    69  	// 部屋数
    70  	N := Roomcount(tokens)
    71  
    72  	//printf ( "Nroom=%d\n", N ) ;
    73  
    74  	if N > 0 {
    75  		Rmvls.Room = make([]*ROOM, N)
    76  
    77  		Roominit(N, Rmvls.Room)
    78  	}
    79  
    80  	// 部屋を構成する壁、床、天井等の数
    81  	Nnxrm := Rmsrfcount(tokens)
    82  
    83  	//printf ( "Nsrf=%d\n", N ) ;
    84  
    85  	if Nnxrm > 0 {
    86  		Rmvls.Sd = make([]*RMSRF, 0, Nnxrm)
    87  	}
    88  
    89  	//Wall := Rmvls.Wall
    90  	//Window := Rmvls.Window
    91  	//W := &Window[0]
    92  	//Snbk := Rmvls.Snbk
    93  	RmIdx := 0
    94  	//Room := Rmvls.Room
    95  
    96  	SdIdx := 0
    97  	//rdpnl := Rmvls.Rdpnl
    98  
    99  	Er = fmt.Sprintf(ERRFMT, errkey)
   100  	RmIdx--
   101  	SdIdx--
   102  
   103  	var i int = -1
   104  	for tokens.IsEnd() == false {
   105  
   106  		section := tokens.GetSection()
   107  
   108  		// 部屋についての一行目の情報を処理
   109  		s := section.GetToken()
   110  		if s == "*" {
   111  			break
   112  		}
   113  
   114  		/*****************************/
   115  
   116  		if DEBUG {
   117  			fmt.Printf("%s\n", s)
   118  		}
   119  
   120  		//err = Er + s
   121  
   122  		i++
   123  		RmIdx++
   124  		Rm := Rmvls.Room[RmIdx]
   125  
   126  		Rm.Name = s
   127  
   128  		// Check duplication of room names
   129  		for l = 0; l < i-1; l++ {
   130  			Rmchk := Rmvls.Room[l]
   131  			if Rm.Name == Rmchk.Name {
   132  				RmnameEr = fmt.Sprintf("Room=%s is already defined name", Rm.Name)
   133  				Eprint("<Roomdata>", RmnameEr)
   134  			}
   135  		}
   136  
   137  		nr = -1
   138  
   139  		// 室のデータの読み取り
   140  		compnameStart := false
   141  		for section.IsEnd() == false {
   142  			s := section.PeekToken()
   143  			if s == "\n" {
   144  				section.GetToken()
   145  				continue
   146  			}
   147  			if s == "*" {
   148  				break
   149  			}
   150  
   151  			line := section.GetLogicalLine()
   152  
   153  			n++
   154  			nr++
   155  
   156  			SdIdx++
   157  			Sd := Rmsrfinit()
   158  			var err error
   159  
   160  			for _, s := range line {
   161  				if DEBUG {
   162  					fmt.Printf("Roomdata1  s=%s\n", s)
   163  				}
   164  
   165  				var st int
   166  				st = strings.IndexRune(s, '=')
   167  				if st == -1 {
   168  					if DEBUG {
   169  						fmt.Printf("Roomdata2  s=%s\n", s)
   170  					}
   171  					/*******************/
   172  
   173  					if s == "*s" {
   174  						// outfile_sf.es への室内表面温度、
   175  						// outfile_sfq.esへの部位別表面熱流、
   176  						// outfile_sfa.esへの部位別表面熱伝達率の出力指定
   177  						Rm.sfpri = true
   178  					} else if s == "*q" {
   179  						// outfile_rq.es、outfile_dqr.es への日射熱取得、
   180  						// 室内発熱、隙間風熱取得要素の出力指定
   181  						Rm.eqpri = true
   182  					} else if s == "*sfe" {
   183  						// 要素別壁体表面温度出力指定
   184  						if !compnameStart {
   185  							// 部屋の内表面に全体に反映させる
   186  							sfemark = true
   187  						} else {
   188  							// 個別内表面にのみ反映させる
   189  							Sd.sfepri = true
   190  						}
   191  					} else if s == "*p" {
   192  						// 壁体内部温度出力指定
   193  						Sd.wlpri = true
   194  					} else if s == "*shd" {
   195  						// 日よけの影面積出力
   196  						Sd.shdpri = true
   197  					} else if st = strings.Index(s, "*"); st != -1 {
   198  						// 面積の指定 (幅・高さ指定)
   199  						var X, Y float64
   200  						fmt.Sscanf(s, "%f*%f", &X, &Y)
   201  						Sd.A = X * Y
   202  					} else if unicode.IsDigit(rune(s[0])) {
   203  						// 面積の指定 (直接指定)
   204  						_, err = fmt.Sscanf(s, "%f", &Sd.A)
   205  						if err != nil {
   206  							panic(err)
   207  						}
   208  					} else if s == "if" {
   209  						// 動的にカーテンを開閉するロジックを追加  2012/2/25 Satoh
   210  						Sd.Ctlif = new(CTLIF)
   211  
   212  						// Read until the end of the if statement
   213  						var ss string
   214  						ss = strings.Trim(tokens.GetToken(), "()")
   215  						Sd.DynamicCode = ss
   216  
   217  						// IF文の展開
   218  						//ctifdecode(s, Sd->ctlif, Simc, Compnt, Nmpath, Mpath, Wd, Exsf, Schdl);
   219  
   220  						// Read the True case window
   221  						s = tokens.GetToken()
   222  						for j := range Rmvls.Window {
   223  							W := Rmvls.Window[j]
   224  							if W.Name == s {
   225  								Sd.ifwin = W
   226  								Sd.Rwall = W.Rwall
   227  								Sd.CAPwall = 0.0
   228  								break
   229  							}
   230  						}
   231  
   232  						if j == len(Rmvls.Window) {
   233  							err := fmt.Sprintf("Room=%s <window> %s", Rm.Name, s)
   234  							Eprint("<Roomdata>", err)
   235  							os.Exit(1)
   236  						}
   237  					} else if strings.ContainsRune(s, ':') {
   238  						ss := strings.Split(s, ":")
   239  
   240  						regexPattern := `\(([^)]*)\)`
   241  
   242  						// 正規表現をコンパイルします。
   243  						r, err := regexp.Compile(regexPattern)
   244  						if err != nil {
   245  							fmt.Printf("Error compiling regex: %v\n", err)
   246  							return
   247  						}
   248  
   249  						// 文字列からマッチする部分を検索し、結果を取得します。
   250  						match := r.FindStringSubmatch(ss[0])
   251  
   252  						// マッチした内容が存在し、サブマッチ(ここではカッコ内)が存在する場合、それを表示します。
   253  						if len(match) > 1 {
   254  							dnxrname = match[1]
   255  						} else {
   256  							dexsname = ss[0]
   257  						}
   258  						compnameStart = true
   259  					} else if s == "Fij" {
   260  						// 形態係数の入力 (予め計算済みの形態係数を使用する場合)
   261  						Rm.fij = 'F'
   262  
   263  						// 室内の表面数 N
   264  						N2, err = strconv.Atoi(section.GetToken())
   265  						if err != nil {
   266  							panic(err)
   267  						}
   268  						Rm.F = make([]float64, N2*N2)
   269  
   270  						ij = 0
   271  						for {
   272  							var ss string
   273  							ss = section.GetToken()
   274  							if err != nil {
   275  								panic(err)
   276  							}
   277  							if ss == ";" {
   278  								break
   279  							}
   280  							Rm.F[ij], err = readFloat(ss)
   281  							if err != nil {
   282  								panic(err)
   283  							}
   284  							ij++
   285  						}
   286  					} else if s == "rsrnx" {
   287  						Rm.rsrnx = true
   288  					} else if s[0] == '-' {
   289  						c := s[1]
   290  						if c != 'E' && c != 'R' && c != 'F' && c != 'i' && c != 'c' && c != 'f' && c != 'W' {
   291  							panic(fmt.Sprintf("Invalid ble '%s' at \"%s\"", string(c), strings.Join(line, " ")))
   292  						}
   293  						Sd.ble = BLEType(c)
   294  					} else if compnameStart {
   295  						c := Sd.ble
   296  						if DEBUG {
   297  							fmt.Printf("Roomdata3  s=%s  c=%c\n", s, c)
   298  						}
   299  
   300  						if c == 'W' {
   301  							nf := Sd.Nfn
   302  							Sd.Nfn++
   303  
   304  							var stt string
   305  							if sttIndex := strings.IndexByte(s, ':'); sttIndex != -1 {
   306  								stt = s[sttIndex+1:]
   307  								Sd.fnmrk[nf] = rune(s[0])
   308  							} else {
   309  								stt = s
   310  							}
   311  
   312  							for j := range Rmvls.Window {
   313  								W := Rmvls.Window[j]
   314  								if W.Name == stt {
   315  									Sd.window = W
   316  									Sd.fnd[nf] = j
   317  									Sd.Rwall = W.Rwall
   318  									Sd.CAPwall = 0.0
   319  									Sd.RStrans = W.RStrans
   320  									break
   321  								}
   322  							}
   323  
   324  							if j == len(Rmvls.Window) {
   325  								err := fmt.Sprintf("Room=%s <window> %s", Rm.Name, stt)
   326  								Eprint("<Roomdata>", err)
   327  								os.Exit(1)
   328  							}
   329  						} else {
   330  							for j := range Rmvls.Wall {
   331  								w := Rmvls.Wall[j]
   332  
   333  								if DEBUG {
   334  									fmt.Printf("!!!!Wall.name=%s  s=%s!!!!\n", get_string_or_null(w.name), s)
   335  								}
   336  
   337  								if w.name == s && w.ble == Sd.ble {
   338  									if DEBUG {
   339  										fmt.Printf("---- j=%d Wallname=%s n=%d\n", j, get_string_or_null(w.name), n)
   340  									}
   341  
   342  									Sd.wd = j
   343  									Sd.Rwall = w.Rwall
   344  									Sd.CAPwall = w.CAPwall
   345  									Sd.PCMflg = w.PCMflg
   346  									break
   347  								}
   348  							}
   349  
   350  							if j == len(Rmvls.Wall) {
   351  								err := fmt.Sprintf("Room=%s <wall> ble=%c %s Undefined in <WALL>", Rm.Name, Sd.ble, s)
   352  								Eprint("<Roomdata>", err)
   353  								os.Exit(1)
   354  							}
   355  
   356  						}
   357  					}
   358  				} else {
   359  					key, value := s[:st], s[st+1:]
   360  
   361  					if !compnameStart {
   362  						// -- 室への設定 --
   363  
   364  						if key == "Vol" {
   365  							// 室容積
   366  							Rm.VRM, err = readRoomVol(value)
   367  							if err != nil {
   368  								panic(err)
   369  							}
   370  						} else if key == "flrsr" {
   371  							// 床の日射吸収比率
   372  							Rm.flrsr = nil
   373  							k, err = idsch(value, Schdl.Sch, "")
   374  							if err == nil {
   375  								Rm.flrsr = &Schdl.Val[k]
   376  							} else {
   377  								Rm.flrsr = envptr(value, Simc, nil, nil, nil)
   378  							}
   379  						} else if key == "alc" {
   380  							// alc 室内表面熱伝達率[W/m2K]。
   381  							k, err = idsch(value, Schdl.Sch, "")
   382  							if err == nil {
   383  								Rm.alc = &Schdl.Val[k]
   384  							} else {
   385  								Rm.alc = envptr(s[st+1:], Simc, nil, nil, nil)
   386  							}
   387  						} else if key == "Hcap" {
   388  							// 室内空気に付加する熱容量 [J/K]
   389  							Rm.Hcap, err = readFloat(value)
   390  							if err != nil {
   391  								panic(err)
   392  							}
   393  						} else if key == "Mxcap" {
   394  							// 室内空気に付加する湿気容量 [kg/(kg/Kg)]
   395  							Rm.Mxcap, err = readFloat(value)
   396  							if err != nil {
   397  								panic(err)
   398  							}
   399  						} else if key == "MCAP" {
   400  							// 室内に置かれた物体の熱容量 [J/K]
   401  							k, err := idsch(value, Schdl.Sch, "")
   402  							if err == nil {
   403  								Rm.MCAP = &Schdl.Val[k]
   404  							} else {
   405  								Rm.MCAP = envptr(value, Simc, nil, nil, nil)
   406  							}
   407  						} else if key == "CM" {
   408  							// 室内に置かれた物体と室内空気との間の熱コンダクタンス [W/K]
   409  							k, err = idsch(value, Schdl.Sch, "")
   410  							if err == nil {
   411  								Rm.CM = &Schdl.Val[k]
   412  							} else {
   413  								Rm.CM = envptr(value, Simc, nil, nil, nil)
   414  							}
   415  						} else if key == "fsolm" { // 家具への日射吸収割合
   416  							k, err = idsch(value, Schdl.Sch, "")
   417  							if err == nil {
   418  								Rm.fsolm = &Schdl.Val[k]
   419  							} else {
   420  								Rm.fsolm = envptr(value, Simc, nil, nil, nil)
   421  							}
   422  						} else if key == "PCMFurn" {
   423  							// PCM内臓家具の場合 (PCMname,mPCM)
   424  							var PCMname, stbuf string
   425  							s1 := s[:st]
   426  							s2 := s[st+2:]
   427  							PCMname = s2
   428  							stbuf = PCMname
   429  
   430  							st := strings.IndexRune(PCMname, ',')
   431  							s1 = PCMname[:st]
   432  							s2 = PCMname[st+1:]
   433  							Rm.PCMfurnname = s1
   434  
   435  							var err error
   436  							st1 := strings.IndexRune(stbuf, ')')
   437  							st2 := strings.IndexRune(stbuf, ',')
   438  							Rm.mPCM, err = readFloat(s[st2+2 : st1])
   439  							if err != nil {
   440  								panic(err)
   441  							}
   442  
   443  							for _, PCM := range Rmvls.PCM {
   444  								if Rm.PCMfurnname == PCM.Name {
   445  									Rm.PCM = PCM
   446  								}
   447  							}
   448  							if Rm.PCM == nil {
   449  								Er = fmt.Sprintf("Roomname=%s %sが見つかりません", Rm.Name, Rm.PCMfurnname)
   450  								Eprint(Er, "<Roomdata>")
   451  								os.Exit(1)
   452  							}
   453  						} else if key == "OTc" {
   454  							// 作用温度設定時の対流成分重み係数の設定
   455  							if k, err = idsch(value, Schdl.Sch, ""); err == nil {
   456  								Rm.OTsetCwgt = &Schdl.Val[k]
   457  							} else {
   458  								Rm.OTsetCwgt = envptr(value, Simc, nil, nil, nil)
   459  							}
   460  						} else {
   461  							Err := fmt.Sprintf("Room=%s s=%s", Rm.Name, s)
   462  							Eprint("<Roomdata>", Err)
   463  						}
   464  					} else {
   465  						// -- 部位設定 --
   466  						//printf ( "st=%s  Sd.name=%s\n", st, Sd.name ) ;
   467  
   468  						if strings.HasPrefix(s, "A=") {
   469  							Sd.A, err = readFloat(s[2:])
   470  							if err != nil {
   471  								panic(err)
   472  							}
   473  						} else if strings.HasPrefix(s, "e=") {
   474  							// 外表面の検索
   475  							for j, e := range Exs {
   476  								if e.Name == s[st+1:] {
   477  									Sd.exs = j
   478  									break
   479  								}
   480  							}
   481  							// 見つからない場合
   482  							if j == len(Exs) {
   483  								err := fmt.Sprintf("Room=%s <exsrf> %s\n", Rm.Name, s)
   484  								Eprint("<Roomdata>", err)
   485  								os.Exit(1)
   486  							}
   487  						} else if strings.HasPrefix(s, "sb=") {
   488  							// 日よけの検索
   489  							for j := range Rmvls.Snbk {
   490  								S := Rmvls.Snbk[j]
   491  								if S.Name == s[st+1:] {
   492  									Sd.sb = j
   493  									break
   494  								}
   495  							}
   496  							// 見つからない場合
   497  							if j == len(Rmvls.Snbk) {
   498  								err := fmt.Sprintf("Room=%s <Snbrk> %s\n", Rm.Name, s)
   499  								Eprint("<Roomdata>", err)
   500  								os.Exit(1)
   501  							}
   502  						} else if strings.HasPrefix(s, "r=") {
   503  							// 隣室名
   504  							Sd.nxrmname = s[st+1:]
   505  						} else if strings.HasPrefix(s, "c=") {
   506  							// 隣室温度係数
   507  							Sd.c, err = strconv.ParseFloat(s[st+1:], 64)
   508  							if err != nil {
   509  								panic(err)
   510  							}
   511  						} else if strings.HasPrefix(s, "sw=") {
   512  							// 窓変更設定番号
   513  							Sd.fnsw, err = idscw(s[st+1:], Schdl.Scw, "")
   514  							if err != nil {
   515  								panic(err)
   516  							}
   517  						} else if strings.HasPrefix(s, "i=") {
   518  							// 壁体名
   519  							// 放射暖冷房パネル、部位一体型集熱器のときにSYSPTHでの要素名で使用する。
   520  							Sd.Name = s[st+1:]
   521  						} else if strings.HasPrefix(s, "alc=") {
   522  							if k, err := idsch(s[st+1:], Schdl.Sch, ""); err == nil {
   523  								Sd.alicsch = &Schdl.Val[k]
   524  							} else {
   525  								Sd.alicsch = envptr(s[st+1:], Simc, nil, nil, nil)
   526  							}
   527  						} else if strings.HasPrefix(s, "alr=") {
   528  							if k, err := idsch(s[st+1:], Schdl.Sch, ""); err == nil {
   529  								Sd.alirsch = &Schdl.Val[k]
   530  							} else {
   531  								Sd.alirsch = envptr(s[st+1:], Simc, nil, nil, nil)
   532  							}
   533  						} else if strings.HasPrefix(s, "fsol=") {
   534  							Rm.Nfsolfix++
   535  							Sd.ffix_flg = '*'
   536  							if k, err := idsch(s[st+1:], Schdl.Sch, ""); err == nil {
   537  								Sd.fsol = &Schdl.Val[k]
   538  							} else {
   539  								Sd.fsol = envptr(s[st+1:], Simc, nil, nil, nil)
   540  							}
   541  						} else if strings.HasPrefix(s, "rmp=") {
   542  							// RMP名
   543  							Sd.Sname = s[4:]
   544  						} else if strings.HasPrefix(s, "PVcap=") {
   545  							// 空気式集熱器で太陽電池(PV)付のときのアレイの定格発電量[W]
   546  							Sd.PVwall.PVcap, err = readFloat(s[st+1:])
   547  							if err != nil {
   548  								panic(err)
   549  							}
   550  							Sd.PVwallFlg = true
   551  						} else if strings.HasPrefix(s, "Wsu=") {
   552  							// 集熱屋根の通気層上側の幅 [m]
   553  							Sd.dblWsu, err = readFloat(s[st+1:])
   554  							if err != nil {
   555  								panic(err)
   556  							}
   557  						} else if strings.HasPrefix(s, "Wsd=") {
   558  							// 集熱屋根の通気層下側の幅 [m]
   559  							Sd.dblWsd, err = readFloat(s[st+1:])
   560  							if err != nil {
   561  								panic(err)
   562  							}
   563  						} else if strings.HasPrefix(s, "Ndiv=") {
   564  							// 空気式集熱器のときの流れ方向(入口から出口)の分割数
   565  							Sd.Ndiv, err = strconv.Atoi(s[st+1:])
   566  							if err != nil {
   567  								panic(err)
   568  							}
   569  							Sd.Tc = make([]float64, Sd.Ndiv)
   570  						} else if strings.HasPrefix(s, "tnxt=") {
   571  							// 当該部位への入射日射の隣接空間への日射分配(連続空間の隣室への日射分
   572  							Sd.tnxt, err = readFloat(s[st+1:])
   573  							if err != nil {
   574  								panic(err)
   575  							}
   576  						} else {
   577  							err := fmt.Sprintf("Room=%s ble=%c s=%s\n", Rm.Name, Sd.ble, s)
   578  							Eprint("<Roomdata>", err)
   579  							os.Exit(1)
   580  						}
   581  					}
   582  				}
   583  			}
   584  
   585  			Sd.sfepri = sfemark
   586  			Sd.Sname = ""
   587  
   588  			Sd.rm = i
   589  			Sd.room = Rm
   590  			Sd.n = nr
   591  
   592  			switch Sd.ble {
   593  			case 'E', 'R', 'F', 'W':
   594  				// 外壁, 屋根, 床(外部) or 窓の場合
   595  				if Sd.exs == -1 {
   596  					var Nexs int
   597  					if Exs != nil {
   598  						Nexs = len(Exs)
   599  					} else {
   600  						fmt.Println("EXSRFが未定義です。")
   601  						Nexs = 0
   602  						os.Exit(1)
   603  					}
   604  
   605  					for j, e := range Exs {
   606  						if e.Name == dexsname {
   607  							Sd.exs = j
   608  							break
   609  						}
   610  					}
   611  					if j == Nexs {
   612  						err := fmt.Sprintf("Room=%s  (%s)\n", Rm.Name, dexsname)
   613  						Eprint("<Roomdata>", err)
   614  						os.Exit(1)
   615  					}
   616  				}
   617  			case 'i', 'c', 'f':
   618  				// 内壁, 天井(内部) or 床(内部)の場合
   619  				if Sd.nxrm == -1 && Sd.c < 0.0 {
   620  					Sd.nxrmname = dnxrname //隣室名
   621  				}
   622  				if Sd.c < 0.0 {
   623  					// 隣室温度係数 1.0
   624  					Sd.c = 1.0
   625  				}
   626  			}
   627  
   628  			// 窓を除く面積0より大きい壁体で、固有の壁体定義がない場合:
   629  			// 既定の壁体定義番号を割り当てる
   630  			if Sd.ble != BLE_Window && Sd.wd == -1 && Sd.A > 0.0 {
   631  				switch Sd.ble {
   632  				case BLE_ExternalWall:
   633  					Sd.wd = dfwl.E // 外壁(壁体定義番号既定値)
   634  				case BLE_Roof:
   635  					Sd.wd = dfwl.R // 屋根(壁体定義番号既定値)
   636  				case BLE_Floor:
   637  					Sd.wd = dfwl.F // 外部に接する床(壁体定義番号既定値)
   638  				case BLE_InnerWall:
   639  					Sd.wd = dfwl.i // 内壁(壁体定義番号既定値)
   640  				case BLE_Ceil:
   641  					Sd.wd = dfwl.c // 天井(内部)(壁体定義番号既定値)
   642  				case BLE_InnerFloor:
   643  					Sd.wd = dfwl.f // 床(内部)(壁体定義番号既定値)
   644  				}
   645  			}
   646  
   647  			if Sd.ble == BLE_Window {
   648  				// 窓の場合
   649  				Sd.typ = RMSRFType_W
   650  				Sd.wd = -1
   651  				Sd.tnxt = 0.0
   652  			} else {
   653  				// 窓以外の場合
   654  				j := Sd.wd
   655  				var jj int
   656  				if jj = Sd.exs; jj >= 0 && Exs[jj].Typ == 'E' {
   657  					Sd.typ = RMSRFType_E // 地下
   658  				} else if jj = Sd.exs; jj >= 0 && Exs[jj].Typ == 'e' {
   659  					Sd.typ = RMSRFType_e // 地表面
   660  				} else {
   661  					Sd.typ = RMSRFType_H // 壁
   662  				}
   663  
   664  				if j >= 0 {
   665  					w := Rmvls.Wall[j]
   666  					Sd.Eo = w.Eo
   667  					Sd.Ei = w.Ei
   668  					Sd.as = w.as
   669  					Sd.fn = -1
   670  					Sd.Rwall = w.Rwall
   671  					Sd.CAPwall = w.CAPwall
   672  					Sd.PCMflg = w.PCMflg
   673  					if Sd.tnxt < 0.0 {
   674  						Sd.tnxt = w.tnxt
   675  					}
   676  					Sd.tnxt = math.Max(Sd.tnxt, 0.0)
   677  				}
   678  			}
   679  
   680  			Rmvls.Sd = append(Rmvls.Sd, Sd)
   681  		}
   682  
   683  		nr++
   684  		Rm.N = nr
   685  
   686  		N2 = nr * nr
   687  		if Rm.fij != 'F' {
   688  			Rm.F = make([]float64, N2)
   689  		}
   690  		Rm.alr = make([]float64, N2)
   691  		Rm.XA = make([]float64, N2)
   692  		Rm.Wradx = make([]float64, N2)
   693  
   694  		Rm.Brs = brs
   695  		Rm.rsrf = Rmvls.Sd[brs:]
   696  		brs += nr
   697  
   698  		Rm.GRM = Roa*Rm.VRM + Rm.Mxcap
   699  		Rm.MRM = Ca*Roa*Rm.VRM + Rm.Hcap
   700  	}
   701  	i++
   702  	Nroom := i
   703  
   704  	n++
   705  	Nsrf := n
   706  
   707  	//printf ( "Nsrf=%d\n", Nsrf ) ;
   708  	//Room = Rmvls.Room
   709  
   710  	// 全ての壁体のループ
   711  	for _, Sd := range Rmvls.Sd {
   712  		// 隣室名を解決しておく
   713  		if Sd.nxrmname != "" {
   714  			err := fmt.Sprintf("%s%s", Er, Sd.nxrmname)
   715  			var err2 error
   716  			Sd.nxrm, err2 = idroom(Sd.nxrmname, Rmvls.Room, err)
   717  			if err2 != nil {
   718  				panic(err2)
   719  			}
   720  			Sd.nextroom = Rmvls.Room[Sd.nxrm]
   721  		}
   722  	}
   723  
   724  	/******* 個別内壁 *****/
   725  
   726  	// 隣室が設定されているの壁体のループ
   727  	for i, Sd := range Rmvls.Sd {
   728  		if Sd.nxrm < 0 {
   729  			continue
   730  		}
   731  
   732  		Room := Rmvls.Room[Sd.nxrm]
   733  		brs := Room.Brs
   734  		bre := brs + Room.N
   735  
   736  		switch Sd.ble {
   737  		case BLE_InnerWall:
   738  			// 内壁 [i]
   739  			for j := brs; j < bre; j++ {
   740  				Sdj := Rmvls.Sd[j]
   741  				if Sdj.nxrm == Sd.rm && Sdj.ble == BLE_InnerWall {
   742  					Sd.nxn = j
   743  					if i == j {
   744  						panic("")
   745  					}
   746  				}
   747  			}
   748  		case BLE_Ceil:
   749  			// 天井(内部) [f]
   750  			for j := brs; j < bre; j++ {
   751  				Sdj := Rmvls.Sd[j]
   752  				if Sdj.nxrm == Sd.rm && Sdj.ble == BLE_InnerFloor {
   753  					Sd.nxn = j
   754  					if i == j {
   755  						panic("")
   756  					}
   757  				}
   758  			}
   759  		case BLE_InnerFloor:
   760  			// 床(内部) [c]
   761  			for j := brs; j < bre; j++ {
   762  				Sdj := Rmvls.Sd[j]
   763  				if Sdj.nxrm == Sd.rm && Sdj.ble == BLE_Ceil {
   764  					Sd.nxn = j
   765  					if i == j {
   766  						panic("")
   767  					}
   768  				}
   769  			}
   770  		}
   771  	}
   772  
   773  	/***** 共用内壁 ******/
   774  
   775  	// 共用内壁のループ
   776  	for j, rsd := range Rmvls.Sd {
   777  		if !((rsd.ble == BLE_InnerWall || rsd.ble == BLE_Ceil || rsd.ble == BLE_InnerFloor) && rsd.mwtype != RMSRFMwType_C) {
   778  			continue
   779  		}
   780  
   781  		if !(rsd.Name != "" && rsd.wd >= 0 && rsd.A > 0.0) {
   782  			continue
   783  		}
   784  
   785  		// 相手を探す
   786  		flag := false
   787  		for i, nxsd := range Rmvls.Sd {
   788  			if !(nxsd.Name != "" && nxsd.A < 0.0) {
   789  				continue
   790  			}
   791  
   792  			// 同じ名前で別の壁体
   793  			if rsd.Name == nxsd.Name && rsd != nxsd {
   794  				rsd.room.Ntr++
   795  				nxsd.room.Ntr++
   796  
   797  				nxsd.nextroom = rsd.room
   798  				nxsd.nxsd = rsd
   799  				nxsd.A = rsd.A
   800  
   801  				nxsd.Ei = rsd.Eo
   802  				nxsd.Eo = rsd.Ei
   803  				nxsd.as = rsd.as
   804  				nxsd.Rwall = rsd.Rwall
   805  				nxsd.CAPwall = rsd.CAPwall
   806  
   807  				nxsd.wd = rsd.wd
   808  				nxsd.mwside = RMSRFMwSideType_M
   809  				rsd.mwtype = RMSRFMwType_C
   810  				nxsd.mwtype = RMSRFMwType_C
   811  				nxsd.pcmpri = rsd.pcmpri
   812  				nxsd.PCMflg = rsd.PCMflg
   813  
   814  				nxsd.tnxt = rsd.tnxt
   815  
   816  				rsd.nextroom = nxsd.room
   817  				rsd.nxsd = nxsd
   818  
   819  				if rsd.ble == BLE_InnerWall {
   820  					nxsd.ble = BLE_InnerWall
   821  				} else if rsd.ble == BLE_InnerFloor {
   822  					nxsd.ble = BLE_Ceil
   823  				} else if rsd.ble == BLE_Ceil {
   824  					nxsd.ble = BLE_InnerFloor
   825  				}
   826  
   827  				var err error
   828  				rsd.nxrm, err = idroom(rsd.nextroom.Name, Rmvls.Room, "")
   829  				if err != nil {
   830  					panic(err)
   831  				}
   832  				rsd.nxn = i
   833  				nxsd.nxrm, err = idroom(nxsd.nextroom.Name, Rmvls.Room, "")
   834  				if err != nil {
   835  					panic(err)
   836  				}
   837  				nxsd.nxn = j
   838  
   839  				flag = true
   840  				break
   841  			}
   842  		}
   843  
   844  		if !flag {
   845  			fmt.Printf("name=%s 共用内壁が片側しか定義されていません。\n", rsd.Name)
   846  		}
   847  
   848  		if rsd.nxn < 0 && rsd.mwtype == RMSRFMwType_C {
   849  			err := fmt.Sprintf("%s    room=%s  xxx  (%s):  -%c\n", Er, Rmvls.Room[rsd.rm].Name, Rmvls.Room[rsd.nxrm].Name, rsd.ble)
   850  			Eprint("<Roomdata>", err)
   851  			os.Exit(1)
   852  		}
   853  	}
   854  
   855  	// 面積入力のチェック
   856  	for _, rsd := range Rmvls.Sd {
   857  		if rsd.A <= 0.0 {
   858  			fmt.Printf("Room=%s  ble=%c  A=%f\n", rsd.room.Name, rsd.ble, rsd.A)
   859  			os.Exit(1)
   860  		}
   861  	}
   862  
   863  	/***** 放射パネル総数、室ごとのパネル数 *****/
   864  
   865  	var Nairflow, Nrdpnl int
   866  	for _, rsd := range Rmvls.Sd {
   867  		if rsd.ble != BLE_Window {
   868  			w := Rmvls.Wall[rsd.wd]
   869  			if w.Ip >= 0 {
   870  				rsd.room.Nrp++
   871  
   872  				if rsd.mwside == RMSRFMwSideType_i {
   873  					Nrdpnl++
   874  				}
   875  			}
   876  		} else {
   877  			// エアフローウィンドウの総数を数える
   878  			Nairflow++
   879  		}
   880  	}
   881  
   882  	for _, room := range Rmvls.Room {
   883  		N := room.Ntr
   884  		if N > 0 {
   885  			room.trnx = make([]*TRNX, N)
   886  		}
   887  
   888  		if room.trnx != nil {
   889  			for sk := 0; sk < N; sk++ {
   890  				Tn := new(TRNX)
   891  				Tn.nextroom = nil
   892  				Tn.sd = nil
   893  
   894  				room.trnx[sk] = Tn
   895  			}
   896  		}
   897  
   898  		room.ARN = make([]float64, room.Ntr)
   899  
   900  		N = room.Nrp
   901  		if N > 0 {
   902  			room.rmpnl = make([]*RPANEL, N)
   903  		}
   904  
   905  		if room.rmpnl != nil {
   906  			for sk := 0; sk < N; sk++ {
   907  				Rp := new(RPANEL)
   908  				Rp.pnl = nil
   909  				Rp.sd = nil
   910  				Rp.elinpnl = 0
   911  
   912  				room.rmpnl[sk] = Rp
   913  			}
   914  		}
   915  
   916  		room.RMP = make([]float64, room.Nrp)
   917  	}
   918  
   919  	if Nrdpnl > 0 {
   920  		Rmvls.Rdpnl = make([]*RDPNL, Nrdpnl)
   921  	}
   922  
   923  	if Rmvls.Rdpnl != nil {
   924  
   925  		for sk := 0; sk < Nrdpnl; sk++ {
   926  			Rd := new(RDPNL)
   927  			Rd.Name = ""
   928  			Rd.cmp = nil
   929  			Rd.MC = 0
   930  			Rd.eprmnx = 0
   931  			Rd.epwtw = 0
   932  			Rd.Loadt = nil
   933  			Rd.Toset = -999.0
   934  			Rd.cG = 0.0
   935  			Rd.Ec = 0.0
   936  			Rd.OMvav = nil
   937  			MtEdayinit(&Rd.mtPVdy)
   938  
   939  			for si := 0; si < 2; si++ {
   940  				Rd.rm[si] = nil
   941  				Rd.sd[si] = nil
   942  				Rd.Ntrm[si] = 0.0
   943  				Rd.Nrp[si] = 0.0
   944  				Rd.elinpnl[si] = 0
   945  			}
   946  
   947  			Rmvls.Rdpnl[sk] = Rd
   948  		}
   949  	}
   950  
   951  	for i := 0; i < Nsrf; i++ {
   952  		rsd := Rmvls.Sd[i]
   953  		rsd.WSRN = make([]float64, rsd.room.Ntr)
   954  		rsd.WSPL = make([]float64, rsd.room.Nrp)
   955  	}
   956  
   957  	rdpnlIdx := 0
   958  	for i := 0; i < Nroom; i++ {
   959  		room := Rmvls.Room[i]
   960  		room.Nisidermpnl = 0
   961  
   962  		trnxIdx := 0
   963  		rmpnlIdx := 0
   964  		for n := 0; n < room.N; n++ {
   965  			rsd := room.rsrf[n]
   966  
   967  			// 共用壁の場合
   968  			if rsd.mwtype == RMSRFMwType_C {
   969  				trnx := room.trnx[trnxIdx]
   970  				trnx.nextroom = rsd.nextroom
   971  				trnx.sd = rsd
   972  				trnxIdx++
   973  			}
   974  
   975  			if rsd.ble != BLE_Window {
   976  				w := Rmvls.Wall[rsd.wd]
   977  				if w.Ip >= 0 {
   978  					if rsd.mwside == 'i' {
   979  						rdpnl := Rmvls.Rdpnl[rdpnlIdx]
   980  
   981  						if w.tra > 0. {
   982  							rdpnl.Type = 'C'
   983  						} else {
   984  							rdpnl.Type = 'P'
   985  						}
   986  
   987  						rdpnl.Name = rsd.Name
   988  						rdpnl.effpnl = w.effpnl
   989  						rdpnl.MC = 1
   990  
   991  						rdpnl.rm[0] = rsd.room
   992  						rdpnl.sd[0] = rsd
   993  						rdpnl.Ntrm[0] = rsd.room.Ntr
   994  						rdpnl.Nrp[0] = rsd.room.Nrp
   995  
   996  						rmpnl := room.rmpnl[rmpnlIdx]
   997  						rmpnl.pnl = rdpnl
   998  						rmpnl.sd = rsd
   999  
  1000  						rdpnl.elinpnl[0] = 1 + 1 + rdpnl.Ntrm[0]
  1001  						rmpnl.elinpnl = rdpnl.elinpnl[0]
  1002  						rmpnlIdx++
  1003  						room.Nisidermpnl++
  1004  
  1005  						// 共用壁の場合
  1006  						if rsd.mwtype == RMSRFMwType_C {
  1007  							rdpnl.MC = 2
  1008  							nxsd := rsd.nxsd
  1009  
  1010  							rdpnl.rm[1] = nxsd.room
  1011  							rdpnl.sd[1] = nxsd
  1012  							rdpnl.Ntrm[1] = nxsd.room.Ntr
  1013  							rdpnl.Nrp[1] = nxsd.room.Nrp
  1014  							rdpnl.elinpnl[1] = 1 + 1 + rdpnl.Ntrm[0] + rdpnl.Nrp[0] + 1 + rdpnl.Ntrm[1]
  1015  						}
  1016  
  1017  						for j := 0; j < rdpnl.MC; j++ {
  1018  							rdpnl.EPR[j] = make([]float64, rdpnl.Ntrm[j])
  1019  							rdpnl.EPW[j] = make([]float64, rdpnl.Nrp[j])
  1020  						}
  1021  
  1022  						rdpnlIdx++
  1023  					}
  1024  				}
  1025  			}
  1026  		}
  1027  	}
  1028  
  1029  	for i := 0; i < Nroom; i++ {
  1030  		room := Rmvls.Room[i]
  1031  		rmpnlIdx := room.Nisidermpnl
  1032  		for n := 0; n < room.N; n++ {
  1033  			rsd := room.rsrf[n]
  1034  
  1035  			if rsd.ble != BLE_Window {
  1036  				w := Rmvls.Wall[rsd.wd]
  1037  				if w.Ip > 0 && rsd.mwside == 'M' {
  1038  					rsd.rpnl = rsd.nxsd.rpnl
  1039  
  1040  					rmpnl := room.rmpnl[rmpnlIdx]
  1041  					rmpnl.pnl = rsd.rpnl
  1042  					rmpnl.sd = rsd
  1043  					rmpnl.elinpnl = rsd.rpnl.elinpnl[1]
  1044  					rmpnlIdx++
  1045  				}
  1046  			}
  1047  		}
  1048  	}
  1049  
  1050  	for i := 0; i < Nroom; i++ {
  1051  		Rm := Rmvls.Room[i]
  1052  
  1053  		// 室間相互換気
  1054  		Rm.achr = make([]*ACHIR, 0, Nroom)
  1055  		for sk := range Rm.achr {
  1056  			Ac := Rm.achr[sk]
  1057  			Ac.rm = 0
  1058  			Ac.sch = 0
  1059  			Ac.room = nil
  1060  		}
  1061  		Rm.Nachr = len(Rm.achr)
  1062  
  1063  		Rm.Arsp = nil
  1064  		Rm.rmld = nil
  1065  		Area := 0.0
  1066  		Rm.FArea = 0.0
  1067  
  1068  		for j := 0; j < Rm.N; j++ {
  1069  			rsd := Rm.rsrf[j]
  1070  			Area += rsd.A
  1071  			if rsd.ble == BLE_Floor || rsd.ble == BLE_InnerFloor {
  1072  				Rm.Nflr++
  1073  				Rm.FArea += rsd.A
  1074  			}
  1075  		}
  1076  		Rm.Area = Area
  1077  		if Rm.fij != 'F' {
  1078  			Rm.fij = 'A'
  1079  			// 形態係数の近似計算(面積割)
  1080  			formfaprx(Rm.N, Area, Rmvls.Sd[Rm.Brs:], Rm.F)
  1081  		}
  1082  	}
  1083  
  1084  	Rmvls.Trdav = make([]float64, len(Rmvls.Room))
  1085  
  1086  	if len(Rmvls.Room) > 0 {
  1087  		N := len(Rmvls.Room)
  1088  		Rmvls.Qrm = make([]*QRM, N)
  1089  		Rmvls.Qrmd = make([]*QRM, N)
  1090  		Rmvls.Emrk = make([]rune, N)
  1091  
  1092  		for i := 0; i < N; i++ {
  1093  			Rmvls.Qrm[i] = new(QRM)
  1094  			Rmvls.Qrmd[i] = new(QRM)
  1095  		}
  1096  	}
  1097  }
  1098  
  1099  func readFloat(value string) (float64, error) {
  1100  	return strconv.ParseFloat(value, 64)
  1101  }
  1102  
  1103  func readRoomVol(value string) (float64, error) {
  1104  	// 室容積 [m3]入力室が直方体の場合には間口、奥行き、高さを'*'でつなげると、
  1105  	ast := strings.Split(value, "*")
  1106  	if len(ast) == 1 {
  1107  		return readFloat(ast[0])
  1108  	} else {
  1109  		// EESLISM内部で室容積を計算する。
  1110  		// Read Wi
  1111  		Wi, err := readFloat(ast[0])
  1112  		if err != nil {
  1113  			return 0.0, err
  1114  		}
  1115  
  1116  		// Read H
  1117  		H, err := readFloat(ast[1])
  1118  		if err != nil {
  1119  			return 0.0, err
  1120  		}
  1121  
  1122  		// Read D
  1123  		D, err := readFloat(ast[2])
  1124  		if err != nil {
  1125  			return 0.0, err
  1126  		}
  1127  
  1128  		return Wi * H * D, nil
  1129  	}
  1130  }
  1131  
  1132  /* ------------------------------------------------------------- */
  1133  
  1134  /*  重量壁体の計算準備      */
  1135  
  1136  func Balloc(Sd []*RMSRF, Wall []*WALL, Mwall *[]*MWALL) {
  1137  	var mw int
  1138  	for _, ssd := range Sd {
  1139  		if id := ssd.wd; id >= 0 && ssd.mwside == 'i' {
  1140  			mw++
  1141  		}
  1142  	}
  1143  
  1144  	if mw > 0 {
  1145  		*Mwall = make([]*MWALL, mw)
  1146  
  1147  		for n := 0; n < mw; n++ {
  1148  			(*Mwall)[n] = &MWALL{
  1149  				sd:   nil,
  1150  				nxsd: nil,
  1151  				wall: nil,
  1152  				ns:   0,
  1153  				rm:   0,
  1154  				n:    0,
  1155  				nxrm: 0,
  1156  				nxn:  0,
  1157  				M:    0,
  1158  				mp:   0,
  1159  				UX:   nil,
  1160  				res:  nil,
  1161  				cap:  nil,
  1162  				Tw:   nil,
  1163  				Told: nil,
  1164  				uo:   0.0,
  1165  				um:   0.0,
  1166  				Pc:   0.0,
  1167  			}
  1168  		}
  1169  	}
  1170  
  1171  	mw = 0
  1172  	for n, ssd := range Sd {
  1173  
  1174  		if id := ssd.wd; id >= 0 && ssd.mwside == 'i' {
  1175  			ssd.rmw = mw
  1176  			mwl := (*Mwall)[mw]
  1177  			W := Wall[id]
  1178  			ssd.mw = mwl // 壁体構造体のポインタ
  1179  
  1180  			mwl.wall = W
  1181  
  1182  			// 太陽光発電付のチェック
  1183  			sn := 0
  1184  			if ssd.mw.wall.ColType != "" {
  1185  				sn = len(ssd.mw.wall.ColType)
  1186  			}
  1187  			if sn == 2 || sn == 3 && ssd.mw.wall.ColType[2] != 'P' {
  1188  				ssd.PVwallFlg = false
  1189  
  1190  				// 太陽電池の容量が入力されているときにはエラーを表示する
  1191  				if ssd.PVwall.PVcap > 0.0 {
  1192  					fmt.Printf("<%s> name=%s PVcap=%g ですが、WALLで太陽電池付が指定されていません\n",
  1193  						ssd.room.Name, ssd.Name, ssd.PVwall.PVcap)
  1194  					ssd.PVwall.PVcap = -999.0
  1195  					os.Exit(1)
  1196  				}
  1197  			}
  1198  
  1199  			mwl.sd = ssd
  1200  			mwl.nxsd = ssd.nxsd
  1201  			mwl.ns = n
  1202  			mwl.rm = ssd.rm
  1203  			mwl.n = ssd.n
  1204  			mwl.nxrm = ssd.nxrm
  1205  			mwl.nxn = ssd.nxn
  1206  			mwl.M = W.M
  1207  			mwl.mp = W.mp
  1208  
  1209  			M := mwl.M
  1210  
  1211  			if mwl.res == nil {
  1212  				mwl.res = make([]float64, M+2)
  1213  			}
  1214  
  1215  			if mwl.cap == nil {
  1216  				mwl.cap = make([]float64, M+2)
  1217  			}
  1218  
  1219  			wres := W.res
  1220  			wcap := W.cap
  1221  			res := mwl.res
  1222  			cap := mwl.cap
  1223  			for m := 0; m <= M; m++ {
  1224  				res[m] = wres[m]
  1225  				cap[m] = wcap[m]
  1226  			}
  1227  
  1228  			if ssd.typ == 'H' {
  1229  				M++
  1230  				mwl.M = M
  1231  				mwl.res[M] = 0.0
  1232  				mwl.cap[M] = 0.0
  1233  			}
  1234  
  1235  			mwl.UX = make([]float64, M*M)
  1236  
  1237  			// PCM状態値を保持する構造体
  1238  			ssd.pcmstate = make([]*PCMSTATE, M+1)
  1239  			pcmstate := ssd.pcmstate
  1240  			for m := 0; m <= M; m++ {
  1241  				PCM := mwl.wall.PCMLyr[m]
  1242  				pcmstate[m] = &PCMSTATE{
  1243  					Name:         nil,
  1244  					CapmL:        0.0,
  1245  					CapmR:        0.0,
  1246  					LamdaL:       0.0,
  1247  					LamdaR:       0.0,
  1248  					TempPCMave:   0.0,
  1249  					OldCapmL:     0.0,
  1250  					OldCapmR:     0.0,
  1251  					OldLamdaL:    0.0,
  1252  					OldLamdaR:    0.0,
  1253  					TempPCMNodeL: 0.0,
  1254  					TempPCMNodeR: 0.0,
  1255  				}
  1256  				if PCM != nil {
  1257  					pcmstate[m].Name = &PCM.Name
  1258  					ssd.Npcm++
  1259  					if ssd.wlpri {
  1260  						ssd.pcmpri = true
  1261  					}
  1262  				}
  1263  			}
  1264  
  1265  			// prevLayer, startLayer := -999, -999
  1266  			// k := 0
  1267  			mw++
  1268  		} else {
  1269  			ssd.mw = nil
  1270  		}
  1271  	}
  1272  
  1273  	for _, ssd := range Sd {
  1274  		if ssd.mwside == 'M' {
  1275  			ssd.mw = ssd.nxsd.mw
  1276  			M := ssd.mw.M
  1277  			ssd.rmw = ssd.nxsd.rmw
  1278  
  1279  			ssd.PCMflg = ssd.nxsd.PCMflg
  1280  			ssd.pcmpri = ssd.nxsd.pcmpri
  1281  			ssd.Npcm = ssd.nxsd.Npcm
  1282  
  1283  			// PCM状態値を保持する構造体
  1284  			// pcmstate := ssd.pcmstate
  1285  			// nxpcm2 := ssd.nxsd.pcmstate
  1286  			for m := 0; m <= M; m++ {
  1287  				// TODO: ここおかしい?
  1288  				//pcmstate[m] = nxpcm2[M-m]
  1289  			}
  1290  		}
  1291  	}
  1292  
  1293  }
  1294  
  1295  /* ------------------------------------------ */
  1296  
  1297  // 壁体内部温度の初期値設定
  1298  func (Rmvls *RMVLS) Tinit() {
  1299  	Tini := Rmvls.Twallinit
  1300  
  1301  	for _, rm := range Rmvls.Room {
  1302  		rm.Tr = Tini
  1303  		rm.Trold = Tini
  1304  		rm.Tsav = Tini
  1305  		rm.Tot = Tini
  1306  		rm.xrold = FNXtr(rm.Tr, 50.0)
  1307  		rm.xr = rm.xrold
  1308  		rm.hr = FNH(rm.Tr, rm.xr)
  1309  		rm.alrbold = -999.0
  1310  		rm.mrk = '*'
  1311  		rm.oldTM = Tini
  1312  		rm.TM = rm.oldTM
  1313  	}
  1314  
  1315  	for _, Sd := range Rmvls.Sd {
  1316  		Sd.Ts = Tini
  1317  		Sd.mrk = '*'
  1318  	}
  1319  
  1320  	for _, mw := range Rmvls.Mw {
  1321  		mw.Tw = make([]float64, mw.M)
  1322  		mw.Told = make([]float64, mw.M)
  1323  		mw.Toldd = make([]float64, mw.M)
  1324  		mw.Twd = make([]float64, mw.M)
  1325  
  1326  		for m := 0; m < mw.M; m++ {
  1327  			mw.Tw[m] = Tini
  1328  			mw.Told[m] = Tini
  1329  			mw.Toldd[m] = Tini
  1330  			mw.Twd[m] = Tini
  1331  		}
  1332  	}
  1333  
  1334  	for _, Room := range Rmvls.Room {
  1335  		if Room.rmqe == nil {
  1336  			continue
  1337  		}
  1338  		for j := 0; j < Room.N; j++ {
  1339  			rmsb := Room.rmqe.rmsb[j]
  1340  			Sd := Room.rsrf[j]
  1341  			if mw := Sd.mw; mw != nil {
  1342  				for m := 0; m < mw.M; m++ {
  1343  					Told := rmsb.Told[m]
  1344  					Tw := rmsb.Tw[m]
  1345  
  1346  					helmclear(Told)
  1347  					Told.trs = Tini
  1348  					helmcpy(Told, Tw)
  1349  				}
  1350  			}
  1351  		}
  1352  	}
  1353  }
  1354  
  1355  /********************************************************************/
  1356  
  1357  func Roomcount(tokens *EeTokens) int {
  1358  	N := 0
  1359  	pos := tokens.GetPos()
  1360  
  1361  	// Find empty section
  1362  	for tokens.IsEnd() == false {
  1363  		section := tokens.GetSection()
  1364  		s := section.GetToken()
  1365  		if s != "*" {
  1366  			N++
  1367  		} else {
  1368  			break
  1369  		}
  1370  	}
  1371  
  1372  	// restore position
  1373  	tokens.RestorePos(pos)
  1374  
  1375  	return N
  1376  }
  1377  
  1378  /********************************************************************/
  1379  
  1380  func Roominit(N int, Room []*ROOM) {
  1381  	for i := 0; i < N; i++ {
  1382  		B := new(ROOM)
  1383  
  1384  		B.Name = ""
  1385  		B.PCM = nil
  1386  		B.PCMfurnname = ""
  1387  		B.mPCM = -999.
  1388  		B.FunHcap = -999.0
  1389  		B.PCMQl = -999.0
  1390  		B.N = 0
  1391  		B.Brs = 0
  1392  		B.Nachr = 0
  1393  		B.Ntr = 0
  1394  		B.Nrp = 0
  1395  		B.Nflr = 0
  1396  		B.Nfsolfix = 0
  1397  		B.Nisidermpnl = 0
  1398  		B.Nasup = 0
  1399  		B.Brs = 0
  1400  		B.N = 0
  1401  		//B.Nairflow = 0 ;
  1402  		B.rsrf = nil
  1403  		B.achr = nil
  1404  		B.trnx = nil
  1405  		B.rmpnl = nil
  1406  		B.Arsp = nil
  1407  		B.cmp = nil
  1408  		B.elinasup = nil
  1409  		B.elinasupx = nil
  1410  		B.rmld = nil
  1411  		B.rmqe = nil
  1412  		B.F = nil
  1413  		B.alr = nil
  1414  		B.XA = nil
  1415  		B.Wradx = nil
  1416  		B.rsrnx = false
  1417  		B.fij = ' '
  1418  		B.sfpri = false
  1419  		B.eqpri = false
  1420  		B.mrk = ' '
  1421  		B.VRM = 0.0
  1422  		B.GRM = 0.0
  1423  		B.MRM = 0.0
  1424  		B.Area = 0.0
  1425  		B.FArea = 0.0
  1426  		B.flrsr = CreateConstantValuePointer(0.3)
  1427  		B.tfsol = 0.0
  1428  		B.alrbold = 0.0
  1429  		B.Hcap = 0.0
  1430  		B.Mxcap = 0.0
  1431  		B.Ltyp = ' '
  1432  		B.Nhm = 0.0
  1433  		B.Light = 0.0
  1434  		B.Apsc = 0.0
  1435  		B.Apsr = 0.0
  1436  		B.Apl = 0.0
  1437  		B.Gve = 0.0
  1438  		B.Gvi = 0.0
  1439  		B.alc = nil
  1440  		B.Vesc = nil
  1441  		B.Visc = nil
  1442  		//B.vesc = B.visc = 0 ;
  1443  		// B.hmwksc = B.hmnsc = B.lgtsc = B.apssc = B.aplsc = 0 ;
  1444  		//B.metsc = B.closc = B.wvsc = -1 ;
  1445  		B.Hc = 0.0
  1446  		B.Hr = 0.0
  1447  		B.HL = 0.0
  1448  		B.Lc = 0.0
  1449  		B.Lr = 0.0
  1450  		B.Ac = 0.0
  1451  		B.Ar = 0.0
  1452  		B.AL = 0.0
  1453  		B.eqcv = 0.5
  1454  		B.Qeqp = 0.0
  1455  		B.Gvent = 0.0
  1456  		B.RMt = 0.0
  1457  		B.ARN = nil
  1458  		B.RMP = nil
  1459  		B.RMC = 0.0
  1460  		B.RMx = 0.0
  1461  		B.RMXC = 0.0
  1462  		B.Tr = 0.0
  1463  		B.Trold = 0.0
  1464  		B.xr = 0.0
  1465  		B.xrold = 0.0
  1466  		B.RH = 0.0
  1467  		B.Tsav = 0.0
  1468  		B.Tot = 0.0
  1469  		B.PMV = 0.0
  1470  		B.AEsch = nil
  1471  		B.AGsch = nil
  1472  		B.AE = 0.0
  1473  		B.AG = 0.0
  1474  		B.Assch = nil
  1475  		B.Alsch = nil
  1476  		B.Lightsch = nil
  1477  		B.Hmsch = nil
  1478  		B.Metsch = nil
  1479  		B.Closch = nil
  1480  		B.Wvsch = nil
  1481  		B.Hmwksch = nil
  1482  		B.VAVcontrl = nil
  1483  		B.OTsetCwgt = nil // 作用温度設定時の対流成分重み係数
  1484  		//B.rairflow = nil ;
  1485  		B.MCAP = nil
  1486  		B.CM = nil
  1487  		B.QM = 0.0
  1488  		B.HM = 0.0
  1489  		B.fsolm = nil
  1490  		B.Srgm2 = 0.0
  1491  		B.TM = 15.0
  1492  		B.oldTM = 15.0
  1493  		B.SET = -999.
  1494  		B.setpri = false
  1495  
  1496  		Room[i] = B
  1497  	}
  1498  }
  1499  
  1500  /************************************************************************/
  1501  
  1502  func Rmsrfcount(tokens *EeTokens) int {
  1503  	N := 0
  1504  
  1505  	//save current position
  1506  	pos := tokens.GetPos()
  1507  
  1508  	for tokens.IsEnd() == false {
  1509  		s := tokens.GetToken()
  1510  		if strings.HasPrefix(s, "-") {
  1511  			N++
  1512  		}
  1513  	}
  1514  
  1515  	// restore postion
  1516  	tokens.RestorePos(pos)
  1517  
  1518  	return N
  1519  }
  1520  
  1521  /************************************************************************/
  1522  
  1523  func Rmsrfinit() *RMSRF {
  1524  	S := new(RMSRF)
  1525  	S.Ctlif = nil
  1526  	S.ifwin = nil
  1527  	S.Name = ""
  1528  	S.room = nil
  1529  	S.nextroom = nil
  1530  	S.DynamicCode = ""
  1531  	S.nxsd = nil
  1532  	S.mw = nil
  1533  	S.rpnl = nil
  1534  	S.pcmstate = nil
  1535  	S.Npcm = 0
  1536  	S.Nfn = 0
  1537  	S.pcmpri = false
  1538  	S.Rwall = -999.0
  1539  	S.CAPwall = -999.
  1540  	S.A = 0.0
  1541  	S.Eo = 0.0
  1542  	S.as = 0.0
  1543  	S.c = 0.0
  1544  	S.tgtn = 0.0
  1545  	S.Bn = 0.0
  1546  	S.srg = 0.0
  1547  	S.srh = 0.0
  1548  	S.srl = 0.0
  1549  	S.sra = 0.0
  1550  	S.alo = 0.0
  1551  	S.ali = 0.0
  1552  	S.alic = 0.0
  1553  	S.alir = 0.0
  1554  	S.K = 0.0
  1555  	S.FI = 0.0
  1556  	S.FO = 0.0
  1557  	S.FP = 0.0
  1558  	S.CF = 0.0
  1559  	S.WSR = 0.0
  1560  	S.WSC = 0.0
  1561  	S.RS = 0.0
  1562  	S.RSsol = 0.0
  1563  	S.RSin = 0.0
  1564  	S.RSli = 0.0
  1565  	S.Qi = 0.0
  1566  	S.Qga = 0
  1567  	S.Qgt = 0.
  1568  	S.TeEsol = 0.0
  1569  	S.TeErn = 0.0
  1570  	S.Te = 0.0
  1571  	S.Tmrt = 0.0
  1572  	S.Ei = 0.0
  1573  	S.Ts = 0.0
  1574  	S.eqrd = 0.0
  1575  	S.alicsch = nil
  1576  	S.WSRN = nil
  1577  	S.WSPL = nil
  1578  
  1579  	S.exs = -1
  1580  	S.sb = -1
  1581  	S.nxrm = -1
  1582  	S.nxn = -1
  1583  	S.wd = -1
  1584  	S.fn = -1
  1585  	S.c = -1.0
  1586  	S.A = -999.0
  1587  	//		S.Rwall = 0.0 ;
  1588  	S.mwside = RMSRFMwSideType_i
  1589  	S.mwtype = RMSRFMwType_I
  1590  	S.fnmrk = [10]rune{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}
  1591  	S.alirsch = nil
  1592  	S.ffix_flg = '!'
  1593  	S.fsol = nil
  1594  
  1595  	S.ColCoeff = -999.
  1596  	S.oldTx = 20.0
  1597  	S.Iw = 0.0
  1598  	//S.Scol = 0.0 ;
  1599  	S.PVwall.Eff = 0.0
  1600  	S.PVwallFlg = false
  1601  	S.PVwall.PVcap = -999.
  1602  	S.Ndiv = 0
  1603  	S.Tc = nil
  1604  	S.dblWsd = -999.0
  1605  	S.dblWsu = -999.0
  1606  	S.dblTf = 20.0
  1607  	S.dblTsd = 20.0
  1608  	S.dblTsu = 20.0
  1609  	S.ras = -999.
  1610  	S.Tg = 20.
  1611  
  1612  	S.tnxt = -999.
  1613  	S.RStrans = false
  1614  
  1615  	S.wlpri = false
  1616  	S.shdpri = false
  1617  	S.Iwall = 0.0
  1618  	S.fnsw = 0
  1619  
  1620  	for j := 0; j < 10; j++ {
  1621  		f := &S.direct_heat_gain[j]
  1622  		g := &S.fnd[j]
  1623  		*f = 0
  1624  		*g = 0
  1625  	}
  1626  
  1627  	return S
  1628  }