github.com/archlabjp/eeslism-go@v0.0.0-20231109122333-4bb7bfcdf292/eeslism/mcstheat.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  /*  mcstheat.c  */
    17  /*  電気蓄熱式暖房器 */
    18  
    19  package eeslism
    20  
    21  import (
    22  	"errors"
    23  	"fmt"
    24  	"io"
    25  	"os"
    26  	"strconv"
    27  	"strings"
    28  )
    29  
    30  /* ------------------------------------------ */
    31  
    32  /* 機器仕様入力      */
    33  
    34  /*---- Satoh Debug 電気蓄熱式暖房器 2001/1/21 ----*/
    35  func Stheatdata(s string, stheatca *STHEATCA) int {
    36  	var id int
    37  
    38  	if st := strings.IndexRune(s, '='); st == -1 {
    39  		stheatca.Name = s
    40  		stheatca.Eff = -999.0
    41  		stheatca.Q = -999.0
    42  		stheatca.Hcap = -999.0
    43  		stheatca.KA = -999.0
    44  	} else {
    45  		sval := s[st+1:]
    46  
    47  		if s == "PCM" {
    48  			stheatca.PCMName = sval
    49  		} else {
    50  			dt, err := strconv.ParseFloat(sval, 64)
    51  			if err != nil {
    52  				panic(err)
    53  			}
    54  
    55  			if s == "Q" {
    56  				stheatca.Q = dt
    57  			} else if s == "KA" {
    58  				stheatca.KA = dt
    59  			} else if s == "eff" {
    60  				stheatca.Eff = dt
    61  			} else if s == "Hcap" {
    62  				stheatca.Hcap = dt
    63  			} else {
    64  				id = 1
    65  			}
    66  		}
    67  	}
    68  	return id
    69  }
    70  
    71  /* --------------------------- */
    72  
    73  /*  管長・ダクト長、周囲温度設定 */
    74  
    75  func Stheatint(_stheat []*STHEAT, Simc *SIMCONTL, Compnt []*COMPNT, Wd *WDAT, _PCM []*PCM) {
    76  	for i := range _stheat {
    77  		stheat := _stheat[i]
    78  		if stheat.Cmp.Envname != "" {
    79  			stheat.Tenv = envptr(stheat.Cmp.Envname, Simc, Compnt, Wd, nil)
    80  		} else {
    81  			stheat.Room = roomptr(stheat.Cmp.Roomname, Compnt)
    82  		}
    83  
    84  		if stheat.Cat.PCMName != "" {
    85  			for j := range _PCM {
    86  				if stheat.Cat.PCMName == _PCM[j].Name {
    87  					stheat.Pcm = _PCM[j]
    88  				}
    89  			}
    90  			if stheat.Pcm == nil {
    91  				Err := fmt.Sprintf("STHEAT %s のPCM=%sが見つかりません", stheat.Name, stheat.Cat.PCMName)
    92  				Eprint(Err, "<Stheatint>")
    93  				os.Exit(1)
    94  			}
    95  		}
    96  
    97  		st := stheat.Cat
    98  
    99  		if st.Q < 0.0 {
   100  			Err := fmt.Sprintf("Name=%s  Q=%.4g", stheat.Name, st.Q)
   101  			Eprint("Stheatinit", Err)
   102  		}
   103  		if stheat.Pcm == nil && st.Hcap < 0.0 {
   104  			Err := fmt.Sprintf("Name=%s  Hcap=%.4g", stheat.Name, st.Hcap)
   105  			Eprint("Stheatinit", Err)
   106  		}
   107  		if st.KA < 0.0 {
   108  			Err := fmt.Sprintf("Name=%s  KA=%.4g", stheat.Name, st.KA)
   109  			Eprint("Stheatinit", Err)
   110  		}
   111  		if st.Eff < 0.0 {
   112  			Err := fmt.Sprintf("Name=%s  eff=%.4g", stheat.Name, st.Eff)
   113  			Eprint("Stheatinit", Err)
   114  		}
   115  
   116  		var err error
   117  		stheat.Tsold, err = strconv.ParseFloat(stheat.Cmp.Tparm, 64)
   118  		if err != nil {
   119  			panic(err)
   120  		}
   121  
   122  		// 内臓PCMの質量
   123  		stheat.MPCM = stheat.Cmp.MPCM
   124  	}
   125  }
   126  
   127  /* --------------------------- */
   128  
   129  /*  特性式の係数  */
   130  
   131  //
   132  //    +--------+ --> [OUT 1]
   133  //    | STHEAT |
   134  //    +--------+ --> [OUT 2]
   135  //
   136  
   137  func Stheatcfv(_stheat []*STHEAT) {
   138  	for i := range _stheat {
   139  		stheat := _stheat[i]
   140  
   141  		// 作用温度 ?
   142  		var Te float64
   143  		if stheat.Cmp.Envname != "" {
   144  			Te = *(stheat.Tenv)
   145  		} else {
   146  			Te = stheat.Room.Tot
   147  		}
   148  
   149  		Eo1 := stheat.Cmp.Elouts[0]
   150  		eff := stheat.Cat.Eff
   151  		stheat.CG = Spcheat(Eo1.Fluid) * Eo1.G
   152  		KA := stheat.Cat.KA
   153  		Tsold := stheat.Tsold
   154  		pcm := stheat.Pcm
   155  		if pcm != nil {
   156  			//NOTE: FNPCMState のシグネチャがヘッダと一致しない。。。
   157  			// stheat.Hcap = stheat.MPCM *
   158  			// 	FNPCMState(pcm.Cros, pcm.Crol, pcm.Ql, pcm.Ts, pcm.Tl, Tsold, nil)
   159  			panic("Cannot call FNPCMState")
   160  		} else {
   161  			stheat.Hcap = stheat.Cat.Hcap
   162  		}
   163  		cG := stheat.CG
   164  
   165  		d := stheat.Hcap/DTM + eff*cG + KA
   166  		if stheat.Cmp.Control != OFF_SW {
   167  			stheat.E = stheat.Cat.Q
   168  		} else {
   169  			stheat.E = 0.0
   170  		}
   171  
   172  		//  空気が流れていれば出入口温度の関係式係数を作成する
   173  		if Eo1.Control != OFF_SW {
   174  			Eo1.Coeffo = 1.0
   175  			Eo1.Co = eff * (stheat.Hcap/DTM*Tsold + KA*Te + stheat.E) / d
   176  			Eo1.Coeffin[0] = eff - 1.0 - eff*eff*cG/d
   177  
   178  			Eo2 := stheat.Cmp.Elouts[1]
   179  			Eo2.Coeffo = 1.0
   180  			Eo2.Co = 0.0
   181  			Eo2.Coeffin[0] = -1.0
   182  		} else {
   183  			Eo1.Coeffo = 1.0
   184  			Eo1.Co = 0.0
   185  			Eo1.Coeffin[0] = -1.0
   186  
   187  			Eo2 := stheat.Cmp.Elouts[1]
   188  			Eo2.Coeffo = 1.0
   189  			Eo2.Co = 0.0
   190  			Eo2.Coeffin[0] = -1.0
   191  		}
   192  	}
   193  }
   194  
   195  /* --------------------------- */
   196  
   197  /* 取得熱量の計算 */
   198  
   199  func Stheatene(_stheat []*STHEAT) {
   200  	var elo *ELOUT
   201  	var cat *STHEATCA
   202  	var Te float64
   203  
   204  	for i := range _stheat {
   205  		stheat := _stheat[i]
   206  		elo = stheat.Cmp.Elouts[0]
   207  		stheat.Tin = elo.Elins[0].Sysvin
   208  
   209  		cat = stheat.Cat
   210  
   211  		if stheat.Cmp.Envname != "" {
   212  			Te = *(stheat.Tenv)
   213  		} else {
   214  			Te = stheat.Room.Tot
   215  		}
   216  
   217  		stheat.Tout = elo.Sysv
   218  		stheat.Ts = (stheat.Hcap/DTM*stheat.Tsold +
   219  			cat.Eff*stheat.CG*stheat.Tin +
   220  			cat.KA*Te + stheat.E) /
   221  			(stheat.Hcap/DTM + cat.Eff*stheat.CG + cat.KA)
   222  
   223  		stheat.Q = stheat.CG * (stheat.Tout - stheat.Tin)
   224  
   225  		stheat.Qls = stheat.Cat.KA * (Te - stheat.Ts)
   226  
   227  		stheat.Qsto = stheat.Hcap / DTM * (stheat.Ts - stheat.Tsold)
   228  
   229  		stheat.Tsold = stheat.Ts
   230  
   231  		if stheat.Room != nil {
   232  			stheat.Room.Qeqp += (-stheat.Qls)
   233  		}
   234  	}
   235  }
   236  
   237  func stheatvptr(key []string, Stheat *STHEAT) (VPTR, VPTR, error) {
   238  	var err error
   239  	var vptr, vpath VPTR
   240  
   241  	if key[1] == "Ts" {
   242  		vptr = VPTR{
   243  			Ptr:  &Stheat.Tsold,
   244  			Type: VAL_CTYPE,
   245  		}
   246  	} else if key[1] == "control" {
   247  		vpath = VPTR{
   248  			Type: 's',
   249  			Ptr:  Stheat,
   250  		}
   251  		vptr = VPTR{
   252  			Ptr:  &Stheat.Cmp.Control,
   253  			Type: SW_CTYPE,
   254  		}
   255  	} else {
   256  		err = errors.New("'Ts' or 'control' is expected")
   257  	}
   258  
   259  	return vptr, vpath, err
   260  }
   261  
   262  /* ---------------------------*/
   263  
   264  func stheatprint(fo io.Writer, id int, stheat []*STHEAT) {
   265  	switch id {
   266  	case 0:
   267  		if len(stheat) > 0 {
   268  			fmt.Fprintf(fo, "%s %d\n", STHEAT_TYPE, len(stheat))
   269  		}
   270  		for i := range stheat {
   271  			fmt.Fprintf(fo, " %s 1 11\n", stheat[i].Name)
   272  		}
   273  	case 1:
   274  		for i := range stheat {
   275  			fmt.Fprintf(fo, "%s_c c c %s_G m f %s_Ts t f %s_Ti t f %s_To t f %s_Q q f %s_Qsto q f ",
   276  				stheat[i].Name, stheat[i].Name, stheat[i].Name, stheat[i].Name, stheat[i].Name, stheat[i].Name, stheat[i].Name)
   277  			fmt.Fprintf(fo, "%s_Qls q f %s_Ec c c %s_E e f ",
   278  				stheat[i].Name, stheat[i].Name, stheat[i].Name)
   279  			fmt.Fprintf(fo, "%s_Hcap q f\n", stheat[i].Name)
   280  		}
   281  	default:
   282  		for i := range stheat {
   283  			fmt.Fprintf(fo, "%c %6.4g %4.1f %4.1f %4.1f %2.0f %.4g ",
   284  				stheat[i].Cmp.Elouts[0].Control, stheat[i].Cmp.Elouts[0].G,
   285  				stheat[i].Ts,
   286  				stheat[i].Tin, stheat[i].Tout, stheat[i].Q, stheat[i].Qsto)
   287  			fmt.Fprintf(fo, "%.4g %c %2.0f ",
   288  				stheat[i].Qls, stheat[i].Cmp.Control, stheat[i].E)
   289  			fmt.Fprintf(fo, "%.0f\n", stheat[i].Hcap)
   290  		}
   291  	}
   292  }
   293  
   294  /* --------------------------- */
   295  
   296  /* 日積算値に関する処理 */
   297  
   298  /*******************/
   299  func stheatdyint(stheat []*STHEAT) {
   300  	for i := range stheat {
   301  		stheat[i].Qlossdy = 0.0
   302  		stheat[i].Qstody = 0.0
   303  
   304  		svdyint(&stheat[i].Tidy)
   305  		svdyint(&stheat[i].Tsdy)
   306  		svdyint(&stheat[i].Tody)
   307  		qdyint(&stheat[i].Qdy)
   308  		edyint(&stheat[i].Edy)
   309  	}
   310  }
   311  
   312  func stheatmonint(stheat []*STHEAT) {
   313  	for i := range stheat {
   314  		stheat[i].MQlossdy = 0.0
   315  		stheat[i].MQstody = 0.0
   316  
   317  		svdyint(&stheat[i].MTidy)
   318  		svdyint(&stheat[i].MTsdy)
   319  		svdyint(&stheat[i].MTody)
   320  		qdyint(&stheat[i].MQdy)
   321  		edyint(&stheat[i].MEdy)
   322  	}
   323  }
   324  
   325  func stheatday(Mon, Day, ttmm int, stheat []*STHEAT, Nday, SimDayend int) {
   326  	Mo := Mon - 1
   327  	tt := ConvertHour(ttmm)
   328  
   329  	for i := range stheat {
   330  		// 日集計
   331  		stheat[i].Qlossdy += stheat[i].Qls
   332  		stheat[i].Qstody += stheat[i].Qsto
   333  		svdaysum(int64(ttmm), stheat[i].Cmp.Control, stheat[i].Tin, &stheat[i].Tidy)
   334  		svdaysum(int64(ttmm), stheat[i].Cmp.Control, stheat[i].Tout, &stheat[i].Tody)
   335  		svdaysum(int64(ttmm), stheat[i].Cmp.Control, stheat[i].Ts, &stheat[i].Tsdy)
   336  		qdaysum(int64(ttmm), stheat[i].Cmp.Control, stheat[i].Q, &stheat[i].Qdy)
   337  		edaysum(ttmm, stheat[i].Cmp.Control, stheat[i].E, &stheat[i].Edy)
   338  
   339  		// 月集計
   340  		stheat[i].MQlossdy += stheat[i].Qls
   341  		stheat[i].MQstody += stheat[i].Qsto
   342  		svmonsum(Mon, Day, ttmm, stheat[i].Cmp.Control, stheat[i].Tin, &stheat[i].MTidy, Nday, SimDayend)
   343  		svmonsum(Mon, Day, ttmm, stheat[i].Cmp.Control, stheat[i].Tout, &stheat[i].MTody, Nday, SimDayend)
   344  		svmonsum(Mon, Day, ttmm, stheat[i].Cmp.Control, stheat[i].Ts, &stheat[i].MTsdy, Nday, SimDayend)
   345  		qmonsum(Mon, Day, ttmm, stheat[i].Cmp.Control, stheat[i].Q, &stheat[i].MQdy, Nday, SimDayend)
   346  		emonsum(Mon, Day, ttmm, stheat[i].Cmp.Control, stheat[i].E, &stheat[i].MEdy, Nday, SimDayend)
   347  
   348  		// 月・時刻のクロス集計
   349  		emtsum(Mon, Day, ttmm, stheat[i].Cmp.Control, stheat[i].E, &stheat[i].MtEdy[Mo][tt])
   350  	}
   351  }
   352  
   353  func stheatdyprt(fo io.Writer, id int, stheat []*STHEAT) {
   354  	switch id {
   355  	case 0:
   356  		if len(stheat) > 0 {
   357  			fmt.Fprintf(fo, "%s %d\n", STHEAT_TYPE, len(stheat))
   358  		}
   359  		for i := range stheat {
   360  			fmt.Fprintf(fo, " %s 1 32\n", stheat[i].Name)
   361  		}
   362  	case 1:
   363  		for i := range stheat {
   364  			fmt.Fprintf(fo, "%s_Ht H d %s_Ti T f ", stheat[i].Name, stheat[i].Name)
   365  			fmt.Fprintf(fo, "%s_ttn h d %s_Tin t f %s_ttm h d %s_Tim t f\n",
   366  				stheat[i].Name, stheat[i].Name, stheat[i].Name, stheat[i].Name)
   367  			fmt.Fprintf(fo, "%s_Ht H d %s_To T f ", stheat[i].Name, stheat[i].Name)
   368  			fmt.Fprintf(fo, "%s_ttn h d %s_Ton t f %s_ttm h d %s_Tom t f\n",
   369  				stheat[i].Name, stheat[i].Name, stheat[i].Name, stheat[i].Name)
   370  			fmt.Fprintf(fo, "%s_Ht H d %s_Ts T f ", stheat[i].Name, stheat[i].Name)
   371  			fmt.Fprintf(fo, "%s_ttn h d %s_Tsn t f %s_ttm h d %s_Tsm t f\n",
   372  				stheat[i].Name, stheat[i].Name, stheat[i].Name, stheat[i].Name)
   373  			fmt.Fprintf(fo, "%s_Hh H d %s_Qh Q f %s_Hc H d %s_Qc Q f\n",
   374  				stheat[i].Name, stheat[i].Name, stheat[i].Name, stheat[i].Name)
   375  			fmt.Fprintf(fo, "%s_th h d %s_qh q f %s_tc h d %s_qc q f\n",
   376  				stheat[i].Name, stheat[i].Name, stheat[i].Name, stheat[i].Name)
   377  			fmt.Fprintf(fo, "%s_He H d %s_E E f %s_te h d %s_Em e f\n",
   378  				stheat[i].Name, stheat[i].Name, stheat[i].Name, stheat[i].Name)
   379  			fmt.Fprintf(fo, "%s_Qls Q f %s_Qst Q f\n\n",
   380  				stheat[i].Name, stheat[i].Name)
   381  		}
   382  	default:
   383  		for i := range stheat {
   384  			fmt.Fprintf(fo, "%1d %3.1f %1d %3.1f %1d %3.1f ",
   385  				stheat[i].Tidy.Hrs, stheat[i].Tidy.M,
   386  				stheat[i].Tidy.Mntime, stheat[i].Tidy.Mn,
   387  				stheat[i].Tidy.Mxtime, stheat[i].Tidy.Mx)
   388  			fmt.Fprintf(fo, "%1d %3.1f %1d %3.1f %1d %3.1f ",
   389  				stheat[i].Tody.Hrs, stheat[i].Tody.M,
   390  				stheat[i].Tody.Mntime, stheat[i].Tody.Mn,
   391  				stheat[i].Tody.Mxtime, stheat[i].Tody.Mx)
   392  			fmt.Fprintf(fo, "%1d %3.1f %1d %3.1f %1d %3.1f ",
   393  				stheat[i].Tsdy.Hrs, stheat[i].Tsdy.M,
   394  				stheat[i].Tsdy.Mntime, stheat[i].Tsdy.Mn,
   395  				stheat[i].Tsdy.Mxtime, stheat[i].Tsdy.Mx)
   396  			fmt.Fprintf(fo, "%1d %3.1f ", stheat[i].Qdy.Hhr, stheat[i].Qdy.H)
   397  			fmt.Fprintf(fo, "%1d %3.1f ", stheat[i].Qdy.Chr, stheat[i].Qdy.C)
   398  			fmt.Fprintf(fo, "%1d %2.0f ", stheat[i].Qdy.Hmxtime, stheat[i].Qdy.Hmx)
   399  			fmt.Fprintf(fo, "%1d %2.0f ", stheat[i].Qdy.Cmxtime, stheat[i].Qdy.Cmx)
   400  			fmt.Fprintf(fo, "%1d %3.1f ", stheat[i].Edy.Hrs, stheat[i].Edy.D)
   401  			fmt.Fprintf(fo, "%1d %2.0f ", stheat[i].Edy.Mxtime, stheat[i].Edy.Mx)
   402  			fmt.Fprintf(fo, " %3.1f %3.1f\n",
   403  				stheat[i].Qlossdy*Cff_kWh, stheat[i].Qstody*Cff_kWh)
   404  		}
   405  	}
   406  }
   407  
   408  func stheatmonprt(fo io.Writer, id int, stheat []*STHEAT) {
   409  	switch id {
   410  	case 0:
   411  		if len(stheat) > 0 {
   412  			fmt.Fprintf(fo, "%s %d\n", STHEAT_TYPE, len(stheat))
   413  		}
   414  		for i := range stheat {
   415  			fmt.Fprintf(fo, " %s 1 32\n", stheat[i].Name)
   416  		}
   417  	case 1:
   418  		for i := range stheat {
   419  			fmt.Fprintf(fo, "%s_Ht H d %s_Ti T f ", stheat[i].Name, stheat[i].Name)
   420  			fmt.Fprintf(fo, "%s_ttn h d %s_Tin t f %s_ttm h d %s_Tim t f\n",
   421  				stheat[i].Name, stheat[i].Name, stheat[i].Name, stheat[i].Name)
   422  			fmt.Fprintf(fo, "%s_Ht H d %s_To T f ", stheat[i].Name, stheat[i].Name)
   423  			fmt.Fprintf(fo, "%s_ttn h d %s_Ton t f %s_ttm h d %s_Tom t f\n",
   424  				stheat[i].Name, stheat[i].Name, stheat[i].Name, stheat[i].Name)
   425  			fmt.Fprintf(fo, "%s_Ht H d %s_Ts T f ", stheat[i].Name, stheat[i].Name)
   426  			fmt.Fprintf(fo, "%s_ttn h d %s_Tsn t f %s_ttm h d %s_Tsm t f\n",
   427  				stheat[i].Name, stheat[i].Name, stheat[i].Name, stheat[i].Name)
   428  			fmt.Fprintf(fo, "%s_Hh H d %s_Qh Q f %s_Hc H d %s_Qc Q f\n",
   429  				stheat[i].Name, stheat[i].Name, stheat[i].Name, stheat[i].Name)
   430  			fmt.Fprintf(fo, "%s_th h d %s_qh q f %s_tc h d %s_qc q f\n",
   431  				stheat[i].Name, stheat[i].Name, stheat[i].Name, stheat[i].Name)
   432  			fmt.Fprintf(fo, "%s_He H d %s_E E f %s_te h d %s_Em e f\n",
   433  				stheat[i].Name, stheat[i].Name, stheat[i].Name, stheat[i].Name)
   434  			fmt.Fprintf(fo, "%s_Qls Q f %s_Qst Q f\n\n",
   435  				stheat[i].Name, stheat[i].Name)
   436  		}
   437  	default:
   438  		for i := range stheat {
   439  			fmt.Fprintf(fo, "%1d %3.1f %1d %3.1f %1d %3.1f ",
   440  				stheat[i].MTidy.Hrs, stheat[i].MTidy.M,
   441  				stheat[i].MTidy.Mntime, stheat[i].MTidy.Mn,
   442  				stheat[i].MTidy.Mxtime, stheat[i].MTidy.Mx)
   443  			fmt.Fprintf(fo, "%1d %3.1f %1d %3.1f %1d %3.1f ",
   444  				stheat[i].MTody.Hrs, stheat[i].MTody.M,
   445  				stheat[i].MTody.Mntime, stheat[i].MTody.Mn,
   446  				stheat[i].MTody.Mxtime, stheat[i].MTody.Mx)
   447  			fmt.Fprintf(fo, "%1d %3.1f %1d %3.1f %1d %3.1f ",
   448  				stheat[i].MTsdy.Hrs, stheat[i].MTsdy.M,
   449  				stheat[i].MTsdy.Mntime, stheat[i].MTsdy.Mn,
   450  				stheat[i].MTsdy.Mxtime, stheat[i].MTsdy.Mx)
   451  			fmt.Fprintf(fo, "%1d %3.1f ", stheat[i].MQdy.Hhr, stheat[i].MQdy.H)
   452  			fmt.Fprintf(fo, "%1d %3.1f ", stheat[i].MQdy.Chr, stheat[i].MQdy.C)
   453  			fmt.Fprintf(fo, "%1d %2.0f ", stheat[i].MQdy.Hmxtime, stheat[i].MQdy.Hmx)
   454  			fmt.Fprintf(fo, "%1d %2.0f ", stheat[i].MQdy.Cmxtime, stheat[i].MQdy.Cmx)
   455  			fmt.Fprintf(fo, "%1d %3.1f ", stheat[i].MEdy.Hrs, stheat[i].MEdy.D)
   456  			fmt.Fprintf(fo, "%1d %2.0f ", stheat[i].MEdy.Mxtime, stheat[i].MEdy.Mx)
   457  			fmt.Fprintf(fo, " %3.1f %3.1f\n",
   458  				stheat[i].MQlossdy*Cff_kWh, stheat[i].MQstody*Cff_kWh)
   459  		}
   460  	}
   461  }
   462  
   463  func stheatmtprt(fo io.Writer, id int, stheat []*STHEAT, Mo, tt int) {
   464  	switch id {
   465  	case 0:
   466  		if len(stheat) > 0 {
   467  			fmt.Fprintf(fo, "%s %d\n", STHEAT_TYPE, len(stheat))
   468  		}
   469  		for i := range stheat {
   470  			fmt.Fprintf(fo, " %s 1 1\n", stheat[i].Name)
   471  		}
   472  	case 1:
   473  		for i := range stheat {
   474  			fmt.Fprintf(fo, "%s_E E f \n", stheat[i].Name)
   475  		}
   476  	default:
   477  		for i := range stheat {
   478  			fmt.Fprintf(fo, " %.2f\n", stheat[i].MtEdy[Mo-1][tt-1].D*Cff_kWh)
   479  		}
   480  	}
   481  }