github.com/archlabjp/eeslism-go@v0.0.0-20231109122333-4bb7bfcdf292/eeslism/mcstank.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  /*  mcstank.c */
    17  
    18  /*  95/11/17 rev  */
    19  
    20  package eeslism
    21  
    22  import (
    23  	"errors"
    24  	"fmt"
    25  	"io"
    26  	"math"
    27  	"strconv"
    28  	"strings"
    29  	"unicode"
    30  )
    31  
    32  /* 蓄熱槽仕様入力    */
    33  
    34  func Stankdata(f *EeTokens, s string, Stankca *STANKCA) int {
    35  	id := 0
    36  	st := ""
    37  	Stankca.gxr = 0.0
    38  
    39  	var err error
    40  
    41  	if stIdx := strings.IndexByte(s, '='); stIdx != -1 {
    42  		s = strings.TrimSpace(s)
    43  		st = s[stIdx+1:]
    44  
    45  		switch {
    46  		case strings.HasPrefix(s, "Vol"):
    47  			Stankca.Vol, err = strconv.ParseFloat(st, 64)
    48  		case strings.HasPrefix(s, "KAside"):
    49  			Stankca.KAside, err = strconv.ParseFloat(st, 64)
    50  		case strings.HasPrefix(s, "KAtop"):
    51  			Stankca.KAtop, err = strconv.ParseFloat(st, 64)
    52  		case strings.HasPrefix(s, "KAbtm"):
    53  			Stankca.KAbtm, err = strconv.ParseFloat(st, 64)
    54  		case strings.HasPrefix(s, "gxr"):
    55  			Stankca.gxr, err = strconv.ParseFloat(st, 64)
    56  		default:
    57  			id = 1
    58  		}
    59  
    60  		if err != nil {
    61  			fmt.Println(err)
    62  		}
    63  
    64  	} else if s == "-S" {
    65  		st = ""
    66  		s = f.GetToken()
    67  		s += " *"
    68  		Stankca.tparm = s
    69  	} else {
    70  		Stankca.name = s
    71  		Stankca.Type = 'C'
    72  		Stankca.tparm = ""
    73  		Stankca.Vol = -999.0
    74  		Stankca.KAside = -999.0
    75  		Stankca.KAtop = -999.0
    76  		Stankca.KAbtm = -999.0
    77  		Stankca.gxr = 0.0
    78  	}
    79  
    80  	return id
    81  }
    82  
    83  /* ------------------------------------------------------- */
    84  
    85  /* 蓄熱槽記憶域確保 */
    86  
    87  func Stankmemloc(errkey string, Stank *STANK) {
    88  	var np, Ndiv, Nin int
    89  	var st, stt, ss string
    90  	var parm []string = make([]string, 0)
    91  
    92  	st = Stank.Cat.tparm[:]
    93  
    94  	// 読み飛ばし処理
    95  	np = 0
    96  	for {
    97  		_, err := fmt.Sscanf(st, "%s", &ss)
    98  		if err != nil || ss == "*" {
    99  			break
   100  		}
   101  
   102  		parm = append(parm, st)
   103  		np++
   104  		st = st[len(ss):]
   105  		for st[0] == ' ' || st[0] == '\t' {
   106  			st = st[1:]
   107  		}
   108  	}
   109  
   110  	Stank.Pthcon = make([]ELIOType, np)
   111  	Stank.Batchcon = make([]ControlSWType, np)
   112  	Stank.Ihex = make([]rune, np)
   113  	Stank.Jin = make([]int, np)
   114  	Stank.Jout = make([]int, np)
   115  	Stank.Ihxeff = make([]float64, np)
   116  	Stank.KA = make([]float64, np)
   117  	Stank.KAinput = make([]rune, np)
   118  
   119  	i := 0
   120  
   121  	for j := 0; j < np; j++ {
   122  		_, err := fmt.Sscanf(parm[j], "%s", &ss)
   123  		if err != nil {
   124  			panic(err)
   125  		}
   126  
   127  		if strings.HasPrefix(ss, "N=") {
   128  			Stank.Ndiv, err = strconv.Atoi(ss[2:])
   129  			if err != nil {
   130  				panic(err)
   131  			}
   132  		} else if stIdx := strings.IndexRune(ss, ':'); stIdx != -1 {
   133  			Stank.Pthcon[i] = ELIOType(ss[0])
   134  			tmp, err := strconv.Atoi(ss[stIdx+1:])
   135  			if err != nil {
   136  				panic(err)
   137  			} else {
   138  				Stank.Jin[i] = tmp - 1
   139  			}
   140  
   141  			if sttIdx := strings.IndexRune(ss[stIdx+1:], '-'); sttIdx != -1 {
   142  				stt = ss[stIdx+1:]
   143  				Stank.Ihex[i] = 'n'
   144  				Stank.Ihxeff[i] = 1.0
   145  				tmp, err := strconv.Atoi(stt)
   146  				if err != nil {
   147  					panic(err)
   148  				} else {
   149  					Stank.Jout[i] = tmp - 1
   150  				}
   151  			} else if sttIdx := strings.IndexRune(ss[stIdx+1:], '_'); sttIdx != -1 {
   152  				stt = ss[stIdx+1 : sttIdx]
   153  				Stank.Ihex[i] = 'y'
   154  
   155  				if stt[1] == 'e' { // 温度効率が入力されている場合
   156  					Stank.Ihxeff[i], err = strconv.ParseFloat(stt[5:], 64)
   157  					if err != nil {
   158  						panic(err)
   159  					}
   160  				} else if stt[1] == 'K' { // 内蔵熱交のKAが入力されている場合
   161  					Stank.KAinput[i] = 'Y'
   162  					Stank.KA[i], err = strconv.ParseFloat(stt[4:], 64)
   163  					if err != nil {
   164  						panic(err)
   165  					}
   166  				} else if stt[1] == 'd' {
   167  					Stank.KAinput[i] = 'C' // 内蔵熱交換器の内径と長さが入力されている場合
   168  					stpIdx := strings.IndexRune(stt[4:], '_')
   169  					Stank.Dbld0, err = strconv.ParseFloat(stt[4:], 64)
   170  					if err != nil {
   171  						panic(err)
   172  					}
   173  					Stank.DblL, err = strconv.ParseFloat(stt[stpIdx+1:], 64)
   174  					if err != nil {
   175  						panic(err)
   176  					}
   177  					Stank.Ncalcihex++
   178  				}
   179  
   180  				Stank.Jout[i] = Stank.Jin[i]
   181  
   182  				i++
   183  			}
   184  		}
   185  	}
   186  
   187  	Stank.Nin = i
   188  	Nin = i
   189  
   190  	Ndiv = Stank.Ndiv
   191  	Stank.DtankF = make([]rune, Ndiv)
   192  
   193  	Stank.B = make([]float64, Ndiv*Ndiv)
   194  	Stank.R = make([]float64, Ndiv)
   195  	Stank.D = make([]float64, Ndiv)
   196  	Stank.Fg = make([]float64, Ndiv*Nin)
   197  	Stank.Tss = make([]float64, Ndiv)
   198  
   199  	Stank.Tssold = make([]float64, Ndiv)
   200  	Stank.Dvol = make([]float64, Ndiv)
   201  	Stank.Mdt = make([]float64, Ndiv)
   202  	Stank.KS = make([]float64, Ndiv)
   203  	Stank.CGwin = make([]float64, Nin)
   204  	Stank.EGwin = make([]float64, Nin)
   205  	Stank.Twin = make([]float64, Nin)
   206  	Stank.Q = make([]float64, Nin)
   207  	if Nin > 0 {
   208  		Stank.Stkdy = make([]STKDAY, Nin)
   209  	}
   210  	if Nin > 0 {
   211  		Stank.Mstkdy = make([]STKDAY, Nin)
   212  	}
   213  }
   214  
   215  /* ------------------------------------------------------- */
   216  
   217  /* 蓄熱槽初期設定 */
   218  
   219  func Stankint(Stank []*STANK, Simc *SIMCONTL, Compnt []*COMPNT, Wd *WDAT) {
   220  	var s, ss, Err, E string
   221  	var mrk rune
   222  	var Tso float64
   223  
   224  	E = "Stankint"
   225  
   226  	for _, stank := range Stank {
   227  
   228  		// 内蔵熱交換器の熱伝達率計算用温度の初期化
   229  		stank.DblTa = 20.0
   230  		stank.DblTw = 20.0
   231  
   232  		s = stank.Cmp.Tparm
   233  		if s != "" {
   234  			if s[0] == '(' {
   235  				s = s[1:]
   236  				for j := 0; j < stank.Ndiv; j++ {
   237  					_, err := fmt.Sscanf(s, " %s ", &ss)
   238  					if err != nil {
   239  						panic(err)
   240  					}
   241  
   242  					if ss[0] == TANK_EMPTY {
   243  						stank.DtankF[j] = TANK_EMPTY
   244  						stank.Tssold[j] = TANK_EMPTMP
   245  					} else {
   246  						stank.DtankF[j] = TANK_FULL
   247  						stank.Tssold[j], err = strconv.ParseFloat(ss, 64)
   248  						if err != nil {
   249  							panic(err)
   250  						}
   251  					}
   252  					s = s[len(ss):]
   253  					for s[0] == ' ' {
   254  						s = s[1:]
   255  					}
   256  				}
   257  			} else {
   258  				if s[0] == TANK_EMPTY {
   259  					mrk = TANK_EMPTY
   260  					Tso = TANK_EMPTMP
   261  				} else {
   262  					var err error
   263  					mrk = TANK_FULL
   264  					Tso, err = strconv.ParseFloat(s, 64)
   265  					if err != nil {
   266  						panic(err)
   267  					}
   268  				}
   269  				for j := 0; j < stank.Ndiv; j++ {
   270  					stank.DtankF[j] = mrk
   271  					stank.Tssold[j] = Tso
   272  				}
   273  			}
   274  		}
   275  
   276  		stank.Tenv = envptr(stank.Cmp.Envname, Simc, Compnt, Wd, nil)
   277  		stoint(stank.Ndiv, stank.Cat.Vol, stank.Cat.KAside, stank.Cat.KAtop, stank.Cat.KAbtm,
   278  			stank.Dvol, stank.Mdt, stank.KS, stank.Tss, stank.Tssold, &stank.Jva, &stank.Jvb)
   279  
   280  		if stank.Cat.Vol < 0.0 {
   281  			Err = fmt.Sprintf("Name=%s  Vol=%.4g", stank.Cmp.Name, stank.Cat.Vol)
   282  			Eprint(E, Err)
   283  		}
   284  		if stank.Cat.KAside < 0.0 {
   285  			Err = fmt.Sprintf("Name=%s  KAside=%.4g", stank.Cmp.Name, stank.Cat.KAside)
   286  			Eprint(E, Err)
   287  		}
   288  		if stank.Cat.KAtop < 0.0 {
   289  			Err = fmt.Sprintf("Name=%s  KAtop=%.4g", stank.Cmp.Name, stank.Cat.KAtop)
   290  			Eprint(E, Err)
   291  		}
   292  		if stank.Cat.KAbtm < 0.0 {
   293  			Err = fmt.Sprintf("Name=%s  KAbtm=%.4g", stank.Cmp.Name, stank.Cat.KAbtm)
   294  			Eprint(E, Err)
   295  		}
   296  	}
   297  }
   298  
   299  /* ------------------------------------------------------- */
   300  
   301  /* 蓄熱槽特性式係数 */
   302  
   303  //
   304  //    +-------+  ---> [OUT 1]
   305  //    | STANK |  --->  ....
   306  //    +-------+  ---> [OUT N]
   307  //
   308  func Stankcfv(Stank []*STANK) {
   309  	for _, stank := range Stank {
   310  		for j := 0; j < stank.Nin; j++ {
   311  			elin := stank.Cmp.Elins[j]
   312  			cGwin := &stank.CGwin[j]
   313  			EGwin := &stank.EGwin[j]
   314  			ihxeff := &stank.Ihxeff[j]
   315  			ihex := &stank.Ihex[j]
   316  
   317  			if elin.Lpath.Batch {
   318  				*cGwin = 0.0
   319  			} else {
   320  				*cGwin = Spcheat('W') * elin.Lpath.G
   321  			}
   322  
   323  			// 内蔵熱交のKAが入力されている場合
   324  			if *ihex == 'y' && *cGwin > 0.0 {
   325  				// 内蔵熱交換器の内径、管長が入力されている場合
   326  				if stank.KAinput[j] == 'C' {
   327  					dblT := (stank.DblTa + stank.DblTw) / 2.0
   328  					// 内蔵熱交換器の表面温度は内外流体の平均温度で代用
   329  					ho := FNhoutpipe(stank.Dbld0, dblT, stank.DblTw)
   330  					// 流速の計算
   331  					dblv := elin.Lpath.G / Row / (math.Pi * math.Pow(stank.Dbld0/2.0, 2.0))
   332  					hi := FNhinpipe(stank.Dbld0, stank.DblL, dblv, dblT)
   333  					stank.KA[j] = 1.0 / (1.0/ho + 1.0/hi) * math.Pi * stank.Dbld0 * stank.DblL
   334  				}
   335  				if stank.KAinput[j] == 'Y' || stank.KAinput[j] == 'C' {
   336  					NTU := stank.KA[j] / *cGwin
   337  					*ihxeff = 1.0 - math.Exp(-NTU)
   338  				}
   339  			}
   340  			*EGwin = *cGwin * *ihxeff
   341  		}
   342  
   343  		stofc(stank.Ndiv, stank.Nin, stank.Jin,
   344  			stank.Jout, stank.Ihex, stank.Ihxeff, stank.Jva, stank.Jvb,
   345  			stank.Mdt, stank.KS, stank.Cat.gxr, stank.Tenv,
   346  			stank.Tssold, stank.CGwin, stank.EGwin, stank.B, stank.R, stank.D, stank.Fg)
   347  
   348  		fgIdx := 0
   349  		cfinIdx := 0
   350  		for j := 0; j < stank.Nin; j++ {
   351  			Eo := stank.Cmp.Elouts[j]
   352  			Eo.Coeffo = 1.0
   353  			Eo.Co = stank.D[stank.Jout[j]]
   354  
   355  			for k := 0; k < stank.Nin; k++ {
   356  				Eo.Coeffin[cfinIdx] = -stank.Fg[fgIdx]
   357  				cfinIdx++
   358  				fgIdx++
   359  			}
   360  		}
   361  	}
   362  }
   363  
   364  /* ------------------------------------------------------- */
   365  
   366  // 蓄熱槽内部水温のポインターの作成
   367  func stankvptr(key []string, Stank *STANK) (VPTR, error) {
   368  	var err error
   369  	var vptr VPTR
   370  	var s string
   371  	if key[1] == "Ts" {
   372  		s = key[2]
   373  		if unicode.IsLetter(rune(s[0])) {
   374  			if s[0] == 't' {
   375  				vptr.Ptr = &Stank.Tssold[0]
   376  				vptr.Type = VAL_CTYPE
   377  			} else if s[0] == 'b' {
   378  				vptr.Ptr = &Stank.Tssold[Stank.Ndiv-1]
   379  				vptr.Type = VAL_CTYPE
   380  			} else {
   381  				err = errors.New("'t' or 'b' is expected")
   382  			}
   383  		} else {
   384  			i, _ := strconv.Atoi(s)
   385  			if i >= 0 && i < Stank.Ndiv {
   386  				vptr.Ptr = &Stank.Tssold[i]
   387  				vptr.Type = VAL_CTYPE
   388  			} else {
   389  				err = errors.New("numeric value is expected")
   390  			}
   391  		}
   392  	} else {
   393  		err = errors.New("'Ts' is expected")
   394  	}
   395  
   396  	return vptr, err
   397  }
   398  
   399  /* ------------------------------------------------------- */
   400  
   401  // 槽内水温、水温分布逆転の検討
   402  func Stanktss(Stank []*STANK, TKreset *int) {
   403  	for _, stank := range Stank {
   404  
   405  		for j := 0; j < stank.Nin; j++ {
   406  			eli := stank.Cmp.Elins[j]
   407  			stank.Twin[j] = eli.Sysvin
   408  		}
   409  
   410  		stotss(stank.Ndiv, stank.Nin, stank.Jin, stank.B, stank.R, stank.EGwin, stank.Twin,
   411  			stank.Tss)
   412  
   413  		stotsexm(stank.Ndiv, stank.Tss, &stank.Jva, &stank.Jvb,
   414  			stank.DtankF, &stank.Cfcalc)
   415  
   416  		if stank.Cfcalc == 'y' {
   417  			*TKreset = 1
   418  		}
   419  	}
   420  }
   421  
   422  /* ------------------------------------------------------- */
   423  
   424  /* 供給熱量、損失熱量計算、水温前時間値の置換 */
   425  
   426  func Stankene(Stank []*STANK) {
   427  	for _, stank := range Stank {
   428  		// バッチモードチェック(各層が空かどうかをチェック)
   429  		for k := 0; k < stank.Ndiv; k++ {
   430  			if stank.DtankF[k] == TANK_EMPTY {
   431  				stank.Tss[k] = TANK_EMPTMP
   432  			}
   433  		}
   434  
   435  		// バッチモードの水供給
   436  		if stank.Batchop == BTFILL {
   437  			Tsm := 0.0
   438  			for k := 0; k < stank.Ndiv; k++ {
   439  				if stank.DtankF[k] == TANK_EMPTY {
   440  					stank.DtankF[k] = TANK_FULL
   441  					for j := 0; j < stank.Nin; j++ {
   442  						if stank.Batchcon[j] == BTFILL {
   443  							stank.Tss[k] = stank.Twin[j]
   444  						}
   445  					}
   446  				}
   447  				Tsm += stank.Tss[k]
   448  			}
   449  			Tsm /= float64(stank.Ndiv)
   450  			for k := 0; k < stank.Ndiv; k++ {
   451  				stank.Tss[k] = Tsm
   452  			}
   453  		}
   454  
   455  		for j := 0; j < stank.Nin; j++ {
   456  			Jo := stank.Jout[j]
   457  			Q := &stank.Q[j]
   458  			EGwin := stank.EGwin[j]
   459  			Twin := stank.Twin[j]
   460  			// ihex := stank.Ihex[j]
   461  
   462  			*Q = EGwin * (stank.Tss[Jo] - Twin)
   463  
   464  			// // 内蔵熱交換器の場合
   465  			if stank.KAinput[j] == 'C' {
   466  				stank.DblTa = stank.Tss[Jo]
   467  				if EGwin > 0.0 {
   468  					stank.DblTw = Twin
   469  				}
   470  			}
   471  		}
   472  
   473  		stank.Qloss = 0.0
   474  		stank.Qsto = 0.0
   475  		for j := 0; j < stank.Ndiv; j++ {
   476  			if stank.DtankF[j] == TANK_FULL {
   477  				stank.Qloss += stank.KS[j] * (stank.Tss[j] - *stank.Tenv)
   478  				if stank.Tssold[j] > -273.0 {
   479  					stank.Qsto += stank.Mdt[j] * (stank.Tss[j] - stank.Tssold[j])
   480  				}
   481  			}
   482  			stank.Tssold[j] = stank.Tss[j]
   483  		}
   484  	}
   485  }
   486  
   487  /* ------------------------------------------------------- */
   488  
   489  // 代表日の出力
   490  func stankcmpprt(fo io.Writer, id int, Stank []*STANK) {
   491  	switch id {
   492  	case 0:
   493  		if len(Stank) > 0 {
   494  			fmt.Fprintf(fo, "%s %d\n", STANK_TYPE, len(Stank))
   495  		}
   496  
   497  		for _, stank := range Stank {
   498  			fmt.Fprintf(fo, "%s:%d", stank.Name, stank.Nin)
   499  			for i := 0; i < stank.Nin; i++ {
   500  				fmt.Fprintf(fo, "%c", stank.Cmp.Idi[i])
   501  			}
   502  
   503  			fmt.Fprintf(fo, " 1 %d\n", stank.Nin*5+2+stank.Ndiv+stank.Ncalcihex)
   504  		}
   505  	case 1:
   506  		for _, stank := range Stank {
   507  			for i := 0; i < stank.Nin; i++ {
   508  				c := stank.Cmp.Idi[i]
   509  				fmt.Fprintf(fo, "%s:%c_c c c %s:%c_G m f %s:%c_Ti t f %s:%c_To t f %s:%c_Q q f  ",
   510  					stank.Name, c, stank.Name, c, stank.Name, c, stank.Name, c, stank.Name, c)
   511  				if stank.KAinput[i] == 'C' {
   512  					fmt.Fprintf(fo, "%s:%c_KA q f  ", stank.Name, c)
   513  				}
   514  				fmt.Fprintln(fo)
   515  			}
   516  			fmt.Fprintf(fo, "%s_Qls q f %s_Qst q f\n ", stank.Name, stank.Name)
   517  			for i := 0; i < stank.Ndiv; i++ {
   518  				fmt.Fprintf(fo, "%s_Ts[%d] t f ", stank.Name, i+1)
   519  			}
   520  			fmt.Fprintln(fo)
   521  		}
   522  	default:
   523  		for _, stank := range Stank {
   524  			Tss := &stank.Tss[0]
   525  			for i := 0; i < stank.Nin; i++ {
   526  				Ei := stank.Cmp.Elins[i]
   527  				Twin := &stank.Twin[i]
   528  				Q := &stank.Q[i]
   529  				Eo := stank.Cmp.Elouts[i]
   530  				fmt.Fprintf(fo, "%c %.5g %4.1f %4.1f %3.0f  ", Ei.Lpath.Control,
   531  					Eo.G, *Twin, Eo.Sysv, *Q)
   532  
   533  				if stank.KAinput[i] == 'C' {
   534  					if Eo.G > 0.0 {
   535  						fmt.Fprintf(fo, "%.2f  ", stank.KA[i])
   536  					} else {
   537  						fmt.Fprintf(fo, "%.2f  ", 0.0)
   538  					}
   539  				}
   540  			}
   541  			fmt.Fprintf(fo, "%2.0f %3.0f\n", stank.Qloss, stank.Qsto)
   542  
   543  			for i := 0; i < stank.Ndiv; i++ {
   544  				fmt.Fprintf(fo, " %4.1f", *Tss)
   545  				Tss = &stank.Tss[i+1]
   546  			}
   547  			fmt.Fprintln(fo)
   548  		}
   549  	}
   550  }
   551  
   552  /* ------------------------------------------------------- */
   553  func stankivprt(fo io.Writer, id int, Stank []*STANK) {
   554  	if id == 0 && len(Stank) > 0 {
   555  		for m, stank := range Stank {
   556  			fmt.Fprintf(fo, "m=%d  %s  %d\n", m, stank.Name, stank.Ndiv)
   557  		}
   558  	} else {
   559  		for m, stank := range Stank {
   560  			fmt.Fprintf(fo, "m=%d  ", m)
   561  
   562  			for i := 0; i < stank.Ndiv; i++ {
   563  				fmt.Fprintf(fo, " %5.1f", stank.Tss[i])
   564  			}
   565  			fmt.Fprintln(fo)
   566  		}
   567  	}
   568  }
   569  
   570  /* --------------------------- */
   571  
   572  /* 日積算値に関する処理 */
   573  
   574  func stankdyint(Stank []*STANK) {
   575  	for _, stank := range Stank {
   576  		stank.Qlossdy = 0.0
   577  		stank.Qstody = 0.0
   578  
   579  		for j := 0; j < stank.Nin; j++ {
   580  			s := &stank.Stkdy[j]
   581  			svdyint(&s.Tidy)
   582  			svdyint(&s.Tsdy)
   583  			qdyint(&s.Qdy)
   584  		}
   585  	}
   586  }
   587  
   588  func stankmonint(Stank []*STANK) {
   589  	for _, stank := range Stank {
   590  		stank.MQlossdy = 0.0
   591  		stank.MQstody = 0.0
   592  
   593  		for j := 0; j < stank.Nin; j++ {
   594  			s := &stank.Mstkdy[j]
   595  			svdyint(&s.Tidy)
   596  			svdyint(&s.Tsdy)
   597  			qdyint(&s.Qdy)
   598  		}
   599  	}
   600  }
   601  
   602  // 日集計、月集計
   603  func stankday(Mon, Day, ttmm int, Stank []*STANK, Nday, SimDayend int) {
   604  	for _, stank := range Stank {
   605  
   606  		// 日集計
   607  		Ts := 0.0
   608  
   609  		S := &stank.Stkdy[0]
   610  		for j := 0; j < stank.Ndiv; j++ {
   611  			Ts += stank.Tss[j] / float64(stank.Ndiv)
   612  		}
   613  		svdaysum(int64(ttmm), ON_SW, Ts, &S.Tsdy)
   614  
   615  		stank.Qlossdy += stank.Qloss
   616  		stank.Qstody += stank.Qsto
   617  
   618  		for j := 0; j < stank.Nin; j++ {
   619  			Ei := stank.Cmp.Elins[j]
   620  			S := &stank.Stkdy[j]
   621  			svdaysum(int64(ttmm), Ei.Lpath.Control, stank.Twin[j], &S.Tidy)
   622  			qdaysum(int64(ttmm), Ei.Lpath.Control, stank.Q[j], &S.Qdy)
   623  		}
   624  
   625  		// 月集計
   626  		S = &stank.Mstkdy[0]
   627  		svmonsum(Mon, Day, ttmm, ON_SW, Ts, &S.Tsdy, Nday, SimDayend)
   628  
   629  		stank.MQlossdy += stank.Qloss
   630  		stank.MQstody += stank.Qsto
   631  
   632  		for j := 0; j < stank.Nin; j++ {
   633  			Ei := stank.Cmp.Elins[j]
   634  			S := &stank.Mstkdy[j]
   635  			svmonsum(Mon, Day, ttmm, Ei.Lpath.Control, stank.Twin[j], &S.Tidy, Nday, SimDayend)
   636  			qmonsum(Mon, Day, ttmm, Ei.Lpath.Control, stank.Q[j], &S.Qdy, Nday, SimDayend)
   637  		}
   638  	}
   639  }
   640  
   641  // 日集計の出力
   642  func stankdyprt(fo io.Writer, id int, Stank []*STANK) {
   643  	switch id {
   644  	case 0:
   645  		if len(Stank) > 0 {
   646  			fmt.Fprintf(fo, "%s %d\n", STANK_TYPE, len(Stank))
   647  		}
   648  
   649  		for _, stank := range Stank {
   650  			fmt.Fprintf(fo, "%s:%d", stank.Name, stank.Nin)
   651  
   652  			for i := 0; i < stank.Nin; i++ {
   653  				fmt.Fprintf(fo, "%c", stank.Cmp.Idi[i])
   654  			}
   655  
   656  			fmt.Fprintf(fo, " 1 %d\n", stank.Nin*14+2+1)
   657  		}
   658  
   659  	case 1:
   660  		for _, stank := range Stank {
   661  			fmt.Fprintf(fo, "%s_Ts t f \n", stank.Name)
   662  
   663  			for i := 0; i < stank.Nin; i++ {
   664  				c := stank.Cmp.Idi[i]
   665  				fmt.Fprintf(fo, "%s:%c_Ht H d %s:%c_T T f ", stank.Name, c, stank.Name, c)
   666  				fmt.Fprintf(fo, "%s:%c_ttn h d %s:%c_Tn t f %s:%c_ttm h d %s:%c_Tm t f\n",
   667  					stank.Name, c, stank.Name, c, stank.Name, c, stank.Name, c)
   668  				fmt.Fprintf(fo, "%s:%c_Hh H d %s:%c_Qh Q f %s:%c_Hc H d %s:%c_Qc Q f\n",
   669  					stank.Name, c, stank.Name, c, stank.Name, c, stank.Name, c)
   670  				fmt.Fprintf(fo, "%s:%c_th h d %s:%c_qh q f %s:%c_tc h d %s:%c_qc q f\n",
   671  					stank.Name, c, stank.Name, c, stank.Name, c, stank.Name, c)
   672  			}
   673  			fmt.Fprintf(fo, "%s_Qls Q f %s_Qst Q f\n\n", stank.Name, stank.Name)
   674  		}
   675  
   676  	default:
   677  		for _, stank := range Stank {
   678  			S := &stank.Stkdy[0]
   679  
   680  			fmt.Fprintf(fo, "%.1f\n", S.Tsdy.M)
   681  			for j := 0; j < stank.Nin; j++ {
   682  				S := &stank.Stkdy[j]
   683  
   684  				fmt.Fprintf(fo, "%1d %3.1f %1d %3.1f %1d %3.1f ",
   685  					S.Tidy.Hrs, S.Tidy.M,
   686  					S.Tidy.Mntime, S.Tidy.Mn,
   687  					S.Tidy.Mxtime, S.Tidy.Mx)
   688  
   689  				fmt.Fprintf(fo, "%1d %3.1f ", S.Qdy.Hhr, S.Qdy.H)
   690  				fmt.Fprintf(fo, "%1d %3.1f ", S.Qdy.Chr, S.Qdy.C)
   691  				fmt.Fprintf(fo, "%1d %2.0f ", S.Qdy.Hmxtime, S.Qdy.Hmx)
   692  				fmt.Fprintf(fo, "%1d %2.0f ", S.Qdy.Cmxtime, S.Qdy.Cmx)
   693  			}
   694  			fmt.Fprintf(fo, " %3.1f %3.1f\n",
   695  				stank.Qlossdy*Cff_kWh, stank.Qstody*Cff_kWh)
   696  		}
   697  	}
   698  }
   699  
   700  // 月集計の出力
   701  func stankmonprt(fo io.Writer, id int, Stank []*STANK) {
   702  	switch id {
   703  	case 0:
   704  		if len(Stank) > 0 {
   705  			fmt.Fprintf(fo, "%s %d\n", STANK_TYPE, len(Stank))
   706  		}
   707  
   708  		for _, stank := range Stank {
   709  			fmt.Fprintf(fo, "%s:%d", stank.Name, stank.Nin)
   710  
   711  			for i := 0; i < stank.Nin; i++ {
   712  				fmt.Fprintf(fo, "%c", stank.Cmp.Idi[i])
   713  			}
   714  
   715  			fmt.Fprintf(fo, " 1 %d\n", stank.Nin*14+2+1)
   716  		}
   717  
   718  	case 1:
   719  		for _, stank := range Stank {
   720  			fmt.Fprintf(fo, "%s_Ts t f \n", stank.Name)
   721  
   722  			for i := 0; i < stank.Nin; i++ {
   723  				c := stank.Cmp.Idi[i]
   724  				fmt.Fprintf(fo, "%s:%c_Ht H d %s:%c_T T f ", stank.Name, c, stank.Name, c)
   725  				fmt.Fprintf(fo, "%s:%c_ttn h d %s:%c_Tn t f %s:%c_ttm h d %s:%c_Tm t f\n",
   726  					stank.Name, c, stank.Name, c, stank.Name, c, stank.Name, c)
   727  				fmt.Fprintf(fo, "%s:%c_Hh H d %s:%c_Qh Q f %s:%c_Hc H d %s:%c_Qc Q f\n",
   728  					stank.Name, c, stank.Name, c, stank.Name, c, stank.Name, c)
   729  				fmt.Fprintf(fo, "%s:%c_th h d %s:%c_qh q f %s:%c_tc h d %s:%c_qc q f\n",
   730  					stank.Name, c, stank.Name, c, stank.Name, c, stank.Name, c)
   731  			}
   732  			fmt.Fprintf(fo, "%s_Qls Q f %s_Qst Q f\n\n", stank.Name, stank.Name)
   733  		}
   734  
   735  	default:
   736  		for _, stank := range Stank {
   737  			S := &stank.Mstkdy[0]
   738  
   739  			fmt.Fprintf(fo, "%.1f\n", S.Tsdy.M)
   740  			for j := 0; j < stank.Nin; j++ {
   741  				S := &stank.Mstkdy[j]
   742  
   743  				fmt.Fprintf(fo, "%1d %3.1f %1d %3.1f %1d %3.1f ",
   744  					S.Tidy.Hrs, S.Tidy.M,
   745  					S.Tidy.Mntime, S.Tidy.Mn,
   746  					S.Tidy.Mxtime, S.Tidy.Mx)
   747  
   748  				fmt.Fprintf(fo, "%1d %3.1f ", S.Qdy.Hhr, S.Qdy.H)
   749  				fmt.Fprintf(fo, "%1d %3.1f ", S.Qdy.Chr, S.Qdy.C)
   750  				fmt.Fprintf(fo, "%1d %2.0f ", S.Qdy.Hmxtime, S.Qdy.Hmx)
   751  				fmt.Fprintf(fo, "%1d %2.0f ", S.Qdy.Cmxtime, S.Qdy.Cmx)
   752  			}
   753  			fmt.Fprintf(fo, " %3.1f %3.1f\n",
   754  				stank.MQlossdy*Cff_kWh, stank.MQstody*Cff_kWh)
   755  		}
   756  	}
   757  }