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

     1  package eeslism
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strings"
     7  )
     8  
     9  /* 経路の定義用関数 */
    10  
    11  /* ----------------------------------------------- */
    12  
    13  // システム要素出力端割当
    14  func pelmco(pflow FliudType, Pelm *PELM, errkey string) {
    15  	var Nout int
    16  	err := 0
    17  	var cmp *COMPNT
    18  	var elmo *ELOUT
    19  
    20  	cmp = Pelm.Cmp
    21  	Nout = cmp.Nout
    22  
    23  	elmo_idx := 0
    24  	elmo = cmp.Elouts[elmo_idx]
    25  
    26  	if cmp.Eqptype == DIVERG_TYPE || cmp.Eqptype == DIVGAIR_TYPE {
    27  		for i := 0; i < Nout; i++ {
    28  			elmo = cmp.Elouts[elmo_idx]
    29  			if elmo.Id != '*' {
    30  				Pelm.Co = '*'
    31  				elmo.Id = '*'
    32  				Pelm.Out = elmo
    33  				err = 0
    34  				break
    35  			}
    36  			elmo_idx++
    37  		}
    38  	} else if cmp.Eqptype == STANK_TYPE {
    39  		stank := cmp.Eqp.(*STANK)
    40  		var i, ii int
    41  		for i = 0; i < stank.Nin; i++ {
    42  			if stank.Pthcon[i] == Pelm.Co {
    43  				break
    44  			}
    45  		}
    46  		ii = i
    47  		for i = 0; i < Nout; i++ {
    48  			elmo = cmp.Elouts[elmo_idx]
    49  			if elmo.Id == stank.Pthcon[ii] {
    50  				Pelm.Out = elmo
    51  				err = 0
    52  				break
    53  			}
    54  			elmo_idx++
    55  		}
    56  	} else if Nout == 1 {
    57  		Pelm.Out = elmo
    58  		Pelm.Co = elmo.Id
    59  	} else if cmp.Eqptype == RDPANEL_TYPE {
    60  		if pflow == WATER_FLD || pflow == AIRa_FLD {
    61  			Pelm.Out = elmo
    62  			Pelm.Co = elmo.Id
    63  		} else if pflow == AIRx_FLD {
    64  			elmo_idx++
    65  			Pelm.Out = elmo
    66  			Pelm.Co = elmo.Id
    67  		}
    68  	} else {
    69  		err = 1
    70  		for i := 0; i < Nout; i++ {
    71  			elmo = cmp.Elouts[i]
    72  			if Pelm.Co == elmo.Id {
    73  				Pelm.Out = elmo
    74  				err = 0
    75  				break
    76  			}
    77  		}
    78  	}
    79  
    80  	if err != 0 {
    81  		for i := 0; i < Nout; i++ {
    82  			elmo = cmp.Elouts[i]
    83  
    84  			if (pflow == AIRa_FLD && elmo.Id == 't') ||
    85  				(pflow == AIRx_FLD && elmo.Id == 'x') ||
    86  				(pflow == WATER_FLD && elmo.Id == 'W') {
    87  				Pelm.Out = elmo
    88  				Pelm.Co = elmo.Id
    89  				err = 0
    90  				break
    91  			}
    92  		}
    93  	}
    94  
    95  	// Satoh追加 気化冷却器 2013/10/31
    96  	if err != 0 {
    97  		if cmp.Eqptype == EVAC_TYPE {
    98  			Nout = 4
    99  		}
   100  
   101  		for i := 0; i < Nout; i++ {
   102  			elmo = cmp.Elouts[i]
   103  			if Pelm.Co == elmo.Id ||
   104  				(Pelm.Co == 'W' && elmo.Id == 'V') ||
   105  				(Pelm.Co == 'w' && elmo.Id == 'v') {
   106  				Pelm.Out = elmo
   107  				err = 0
   108  				break
   109  			}
   110  		}
   111  	}
   112  
   113  	Errprint(err, errkey+" <pelmco>", cmp.Name)
   114  }
   115  
   116  /* ----------------------------------------------- */
   117  
   118  // システム要素入力端割当
   119  func pelmci(pflow FliudType, Pelm *PELM, errkey string) {
   120  	err := 0
   121  	cmp := Pelm.Cmp
   122  	elmi := cmp.Elins[0]
   123  	Nin := cmp.Nin
   124  
   125  	// 入口の数が0の場合は処理を行わない
   126  	if Nin <= 0 {
   127  		return
   128  	}
   129  
   130  	if cmp.Eqptype == CONVRG_TYPE || cmp.Eqptype == CVRGAIR_TYPE {
   131  		// 合流要素の場合
   132  		//
   133  		for i := 0; i < Nin; i++ {
   134  			elmi := cmp.Elins[i]
   135  			if elmi.Id != ELIO_ASTER {
   136  				elmi.Id = ELIO_ASTER
   137  				Pelm.Ci = ELIO_ASTER
   138  				Pelm.In = elmi
   139  				break
   140  			}
   141  		}
   142  	} else if SIMUL_BUILDG && cmp.Eqptype == ROOM_TYPE {
   143  		// 室要素の場合
   144  		//
   145  		room := cmp.Eqp.(*ROOM)
   146  
   147  		var elins *[]*ELIN
   148  		if pflow == AIRa_FLD {
   149  			// 流体が空気(温度)の場合:
   150  			elins = &room.elinasup
   151  		} else if pflow == AIRx_FLD {
   152  			// 流体が空気(湿度)の場合:
   153  			elins = &room.elinasupx
   154  		} else {
   155  			panic(pflow)
   156  		}
   157  
   158  		for i := 0; i < room.Nasup; i++ {
   159  			elmi := (*elins)[i]
   160  			if elmi.Id != ELIO_ASTER {
   161  				Pelm.Ci = ELIO_ASTER
   162  				elmi.Id = ELIO_ASTER
   163  				Pelm.In = elmi
   164  				break
   165  			}
   166  		}
   167  	} else if SIMUL_BUILDG && cmp.Eqptype == RDPANEL_TYPE {
   168  		// 放射パネル要素の場合
   169  		//
   170  		if pflow == WATER_FLD || pflow == AIRa_FLD {
   171  			Elout_a := cmp.Elouts[0] // 温水または空気温度
   172  			for i := 0; i < Elout_a.Ni; i++ {
   173  				elmi := cmp.Elins[i]
   174  				if elmi.Id == ELIO_f {
   175  					Pelm.Ci = elmi.Id
   176  					Pelm.In = elmi
   177  					break
   178  				}
   179  			}
   180  		} else if pflow == AIRx_FLD {
   181  			Elout_x := cmp.Elouts[1] // 空気湿度
   182  			elmi := Elout_x.Elins[0]
   183  			Pelm.Ci = elmi.Id
   184  			Pelm.In = elmi
   185  		}
   186  	} else if Nin == 1 {
   187  		// 入口の数が1の場合
   188  		//
   189  		Pelm.In = elmi
   190  		Pelm.Ci = elmi.Id
   191  	} else {
   192  		err = 1
   193  
   194  		for i := 0; i < Nin; i++ {
   195  			elmi := cmp.Elins[i]
   196  
   197  			// ACの絶対湿度はここに入った
   198  			if Pelm.Ci == elmi.Id {
   199  				Pelm.In = elmi
   200  				err = 0
   201  				break
   202  			}
   203  		}
   204  	}
   205  
   206  	if err != 0 {
   207  
   208  		if cmp.Eqptype == HCLOADW_TYPE {
   209  			Hcload := cmp.Eqp.(*HCLOAD)
   210  			if Hcload.Wet {
   211  				Nin = 4
   212  			}
   213  		} else if cmp.Eqptype == DESI_TYPE {
   214  			Nin = 4
   215  		}
   216  
   217  		for i := 0; i < Nin; i++ {
   218  			elmi := cmp.Elins[i]
   219  			if (pflow == AIRa_FLD && elmi.Id == ELIO_t) ||
   220  				(pflow == AIRx_FLD && elmi.Id == ELIO_x) ||
   221  				(pflow == WATER_FLD && elmi.Id == ELIO_W) {
   222  				Pelm.In = elmi
   223  				Pelm.Ci = elmi.Id
   224  				err = 0
   225  				break
   226  			}
   227  		}
   228  
   229  		//printf("\n") ;
   230  	}
   231  
   232  	if err != 0 {
   233  
   234  		if cmp.Eqptype == THEX_TYPE {
   235  			N := 0
   236  			for i := 0; i < cmp.Nout; i++ {
   237  				Eo := cmp.Elouts[i]
   238  				N += Eo.Ni
   239  			}
   240  
   241  			Nin = N
   242  		}
   243  
   244  		for i := 0; i < Nin; i++ {
   245  			elmi := cmp.Elins[i]
   246  			if Pelm.Ci == elmi.Id {
   247  				Pelm.In = elmi
   248  				err = 0
   249  				break
   250  			}
   251  		}
   252  	}
   253  
   254  	if err != 0 {
   255  		if cmp.Eqptype == EVAC_TYPE {
   256  			N := 0
   257  			for i := 0; i < cmp.Nout; i++ {
   258  				Eo := cmp.Elouts[i]
   259  				N += Eo.Ni
   260  			}
   261  
   262  			Nin = N
   263  		}
   264  
   265  		for i := 0; i < Nin; i++ {
   266  			elmi := cmp.Elins[i]
   267  			if Pelm.Ci == elmi.Id ||
   268  				(Pelm.Ci == 'W' && elmi.Id == 'V') ||
   269  				(Pelm.Ci == 'w' && elmi.Id == 'v') {
   270  				Pelm.In = elmi
   271  				err = 0
   272  				break
   273  			}
   274  		}
   275  	}
   276  
   277  	Errprint(err, errkey+" <pelmci>", cmp.Name)
   278  }
   279  
   280  /* ----------------------------------------------- */
   281  
   282  // システム要素接続データのコピー(空気系統湿度経路用
   283  // 空気経路の場合は湿度経路用にpathをコピーする
   284  //
   285  // - 空気温度用のシステム経路 mpath_t の設定を 空湿度用のシステム経路 にコピーする。
   286  // - コピーに際して要素(PELM)を追加する。
   287  // - 要素(PELM)は _Pelm 配列に追加するものとし、 Npelm 番目から詰め込むとする。 Npelmは上書きする。
   288  // ##- _Plist は システム経路 mpath_t に属するすべての 末端経路の配列である。
   289  // - Compntには SYSCMPデータセットで読み込んだすべての機器情報が保持されている。
   290  func plistcpy(mpath_t *MPATH, _Pelm *[]*PELM, _Plist *[]*PLIST, Compnt []*COMPNT) *MPATH {
   291  	// 空気湿度用経路
   292  	var mpath_x *MPATH = NewMPATH()
   293  	mpath_x.Name = mpath_t.Name + ".x" // 湿度用経路の名前 = 温度経路用の名前 + ".x"
   294  	//mpath_x.Plist = _Plist             // 末端経路 (要確認)
   295  	mpath_x.Fluid = AIRx_FLD    // 流体種別 = 空気湿度
   296  	mpath_x.G0 = mpath_t.G0     // 流量比率
   297  	mpath_x.Rate = mpath_t.Rate // 流量比率フラグ
   298  
   299  	// 空気温度用経路
   300  	mpath_t.Fluid = AIRa_FLD // 流体種別を念のため上書き?
   301  	mpath_t.Mpair = mpath_x  // 空気湿度経路への参照(Mpair)を設定
   302  
   303  	// 末端経路についてループ
   304  	for i := range mpath_t.Plist {
   305  		pli := mpath_t.Plist[i]
   306  		Plist := NewPLIST()
   307  
   308  		// ターゲットの末端経路
   309  		//pli := &mpath_t.Plist[i]
   310  
   311  		// 相互参照設定
   312  		pli.Lpair = Plist
   313  		pli.Plistx = Plist
   314  		Plist.Plistt = pli
   315  
   316  		// コピー
   317  		Plist.Pelm = nil
   318  		Plist.Org = false
   319  		Plist.Type = pli.Type
   320  		Plist.Go = pli.Go
   321  		Plist.Nvav = pli.Nvav
   322  		Plist.Nvalv = pli.Nvalv
   323  		Plist.NOMVAV = pli.NOMVAV
   324  		Plist.OMvav = pli.OMvav
   325  		Plist.Valv = pli.Valv
   326  		Plist.Rate = pli.Rate
   327  		Plist.UnknownFlow = pli.UnknownFlow
   328  
   329  		// 名前のコピー: ".x"を付与しながらコピー
   330  		if pli.Name != "" {
   331  			Plist.Name = pli.Name + ".x"
   332  		} else {
   333  			Plist.Name = ".x"
   334  		}
   335  
   336  		// 要素のコピー
   337  		nelm := 0
   338  		Plist.Pelm = make([]*PELM, 0, len(pli.Pelm))
   339  		for _, peli := range pli.Pelm {
   340  
   341  			// コピー対象は空気経路のみ
   342  			if !peli.Cmp.Airpathcpy {
   343  				continue
   344  			}
   345  
   346  			var Pelm *PELM = NewPELM()
   347  
   348  			*_Pelm = append(*_Pelm, Pelm)
   349  			Plist.Pelm = append(Plist.Pelm, Pelm)
   350  
   351  			if peli.Cmp.Eqptype == CVRGAIR_TYPE || peli.Cmp.Eqptype == DIVGAIR_TYPE {
   352  				// ** 合流要素の場合 **
   353  
   354  				// Find index
   355  				k, err := FindComponentRef(peli.Cmp, Compnt)
   356  				if err != nil {
   357  					panic(err)
   358  				}
   359  
   360  				// k+1番目位以降のコンポーネントのみ検索している: 理由??
   361  				var cmp *COMPNT
   362  				for k++; k < len(Compnt); k++ {
   363  					cmp = Compnt[k]
   364  					s := cmp.Name
   365  
   366  					// "name.xxx" のうち name だけで一致する機器を探す。
   367  					if idx := strings.IndexRune(s, '.'); idx >= 0 {
   368  						s = s[:idx]
   369  
   370  						if peli.Cmp.Name == s {
   371  							break
   372  						}
   373  					}
   374  				}
   375  				Pelm.Cmp = cmp // 検索で見つけた機器参照
   376  			} else if peli.Cmp.Eqptype == THEX_TYPE {
   377  				// ** 全熱交換器の場合 **
   378  				Pelm.Cmp = peli.Cmp
   379  				if peli.Ci == ELIO_E {
   380  					Pelm.Ci = ELIO_e
   381  					Pelm.Co = ELIO_e
   382  				} else {
   383  					Pelm.Ci = ELIO_o
   384  					Pelm.Co = ELIO_o
   385  				}
   386  			} else if peli.Cmp.Eqptype == EVAC_TYPE {
   387  				// Satoh追加 気化冷却器 2013/10/31
   388  				Pelm.Cmp = peli.Cmp
   389  				if peli.Ci == ELIO_D {
   390  					Pelm.Ci = ELIO_d
   391  					Pelm.Co = ELIO_d
   392  				} else if peli.Ci == ELIO_W {
   393  					Pelm.Ci = ELIO_w
   394  					Pelm.Co = ELIO_w
   395  				}
   396  			} else {
   397  				Pelm.Cmp = peli.Cmp
   398  				Pelm.Ci = peli.Ci
   399  				Pelm.Co = peli.Co
   400  			}
   401  
   402  			Pelm.Out = peli.Out
   403  			nelm++
   404  		}
   405  
   406  		mpath_x.Plist = append(mpath_x.Plist, Plist)
   407  	}
   408  
   409  	return mpath_x
   410  }
   411  
   412  /* ----------------------------------------------- */
   413  
   414  /*  合流レベルの設定  */
   415  
   416  func plevel(Nmpath int, Mpath []MPATH, Ncnvrg int, Cnvrg []*COMPNT) {
   417  
   418  	var i, j int
   419  	lvc := 0
   420  	var lvcmx, lvcf int
   421  	var Plist *PLIST
   422  	var cmp *COMPNT
   423  	var elin *ELIN
   424  
   425  	for i = 0; i < Ncnvrg; i++ {
   426  		cmp = Cnvrg[i]
   427  		cmp.Elouts[0].Lpath.Lvc = -1
   428  	}
   429  
   430  	lvcf = Ncnvrg
   431  
   432  	for lvcf > 0 {
   433  		for i = 0; i < Ncnvrg; i++ {
   434  			cmp = Cnvrg[i]
   435  			if cmp.Elouts[0].Lpath.Lvc <= 0 {
   436  				for j = 0; j < cmp.Nin; j++ {
   437  					elin = cmp.Elins[j]
   438  					Plist = elin.Lpath
   439  					if Plist.Type != CONVRG_LPTP {
   440  						lvc = 0
   441  					} else {
   442  						if Plist.Lvc > 0 {
   443  							if lvc <= Plist.Lvc {
   444  								lvc = Plist.Lvc
   445  							}
   446  						} else {
   447  							break
   448  						}
   449  					}
   450  				}
   451  
   452  				if j == cmp.Nin {
   453  					lvc++
   454  					cmp.Elouts[0].Lpath.Lvc = lvc
   455  
   456  					lvcf--
   457  				}
   458  			}
   459  		}
   460  	}
   461  
   462  	for i = 0; i < Nmpath; i++ {
   463  		_Mpath := &Mpath[i]
   464  
   465  		lvcmx = 0
   466  
   467  		for _, Plist := range _Mpath.Plist {
   468  			if Plist.Lvc > lvcmx {
   469  				lvcmx = Plist.Lvc
   470  			}
   471  		}
   472  		_Mpath.Lvcmx = lvcmx
   473  	}
   474  }
   475  
   476  /* ----------------------------------------------- */
   477  
   478  func pflowstrct(_Mpath []*MPATH) {
   479  	var j, n, M, MM, k int
   480  	var etype EqpType
   481  	var Elout *ELOUT
   482  	var Elin *ELIN
   483  
   484  	var nplist int = 0
   485  	for _, Mpath := range _Mpath {
   486  		nplist += len(Mpath.Plist)
   487  	}
   488  
   489  	for _, Mpath := range _Mpath {
   490  		Mpath.Pl = make([]*PLIST, nplist)
   491  		Mpath.Cbcmp = make([]*COMPNT, nplist)
   492  	}
   493  
   494  	for _, Mpath := range _Mpath {
   495  		n = 0
   496  
   497  		for _, Plist := range Mpath.Plist {
   498  			// 流量未設定の末端経路を検索
   499  			if Plist.Go == nil && Plist.Nvav == 0 &&
   500  				Plist.Rate == nil && Plist.NOMVAV == 0 &&
   501  				(Plist.Nvalv == 0 || (Plist.Nvalv > 0 && Plist.Valv.MonPlist == nil && Plist.Valv.MGo == nil)) {
   502  				Mpath.Pl[n] = Plist
   503  				Plist.N = n
   504  				// 末端経路未知フラグの変更
   505  				Plist.UnknownFlow = 0
   506  				n++
   507  			}
   508  
   509  			if Mpath.Rate && (Plist.Go != nil || Plist.Nvav > 0 || Plist.Nvalv > 0 || Plist.NOMVAV > 0) {
   510  				Mpath.G0 = &Plist.G // 流量比率設定時の既知流量へのポインタをセット
   511  			}
   512  		}
   513  
   514  		Mpath.NGv = n
   515  		Mpath.NGv2 = n * n
   516  
   517  		n = 0
   518  
   519  		for _, Plist := range Mpath.Plist {
   520  
   521  			// 末端経路の先頭機器
   522  			etype = Plist.Pelm[0].Cmp.Eqptype
   523  
   524  			// 末端経路の先頭が分岐・合流の場合
   525  			if etype == CONVRG_TYPE ||
   526  				etype == CVRGAIR_TYPE ||
   527  				etype == DIVERG_TYPE ||
   528  				etype == DIVGAIR_TYPE {
   529  				MM = 0
   530  
   531  				for k = 0; k < n; k++ {
   532  					if Plist.Pelm[0].Cmp == Mpath.Cbcmp[k] {
   533  						MM++
   534  						break
   535  					}
   536  				}
   537  
   538  				if MM == 0 {
   539  					// 末端経路の先頭機器(分岐・合流)の入口、出口経路の未知流量の数(M)を数える
   540  					M = 0
   541  
   542  					// 末端経路の先頭機器の入口
   543  					for j = 0; j < Plist.Pelm[0].Cmp.Nin; j++ {
   544  						Elin = Plist.Pelm[0].Cmp.Elins[j]
   545  
   546  						Plist.Upplist = Elin.Lpath
   547  						// 末端経路の先頭機器の上流の流量が未定義
   548  						if Elin.Lpath.UnknownFlow == 0 {
   549  							M++
   550  							break
   551  						}
   552  					}
   553  
   554  					if M == 0 {
   555  						// 末端経路の先頭機器の出口
   556  						Elout = Plist.Pelm[0].Cmp.Elouts[0]
   557  
   558  						for j = 0; j < Plist.Pelm[0].Cmp.Nout; j++ {
   559  							Elout = Plist.Pelm[0].Cmp.Elouts[j]
   560  
   561  							Plist.Dnplist = Elout.Lpath
   562  							// 末端経路の先頭機器の出口経路の流量が未知なら
   563  							if Elout.Lpath.UnknownFlow == 0 {
   564  								M++
   565  								break
   566  							}
   567  						}
   568  					}
   569  
   570  					// 末端経路先頭にある分岐・合流の入口もしくは出口経路の未知流量の数(M)
   571  					if M > 0 {
   572  						// 流量連立方程式を解くときに使用する分岐・合流機器と数(n)
   573  						Mpath.Cbcmp[n] = Plist.Pelm[0].Cmp
   574  						n++
   575  					}
   576  				}
   577  			}
   578  		}
   579  
   580  		// 既知末端流量数のチェック
   581  		if n > 0 && (n-1 != Mpath.NGv) {
   582  			fmt.Printf("<%s> 末端流量の与えすぎ、もしくは少なすぎです n=%d NGv=%d\n", Mpath.Name, n, Mpath.NGv)
   583  		}
   584  	}
   585  }
   586  
   587  func FindComponentRef(target *COMPNT, Compnt []*COMPNT) (int, error) {
   588  	for k := range Compnt {
   589  		cmp := Compnt[k]
   590  		if cmp == target {
   591  			return k, nil
   592  		}
   593  	}
   594  	return -1, errors.New("Not Found")
   595  }