github.com/archlabjp/eeslism-go@v0.0.0-20231109122333-4bb7bfcdf292/eeslism/mcsolrcol.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  /*  solrcol.c  */
    17  
    18  package eeslism
    19  
    20  import (
    21  	"errors"
    22  	"fmt"
    23  	"io"
    24  	"math"
    25  	"strconv"
    26  	"strings"
    27  )
    28  
    29  /* 太陽熱集熱器
    30  
    31  機器仕様入力    */
    32  
    33  func Colldata(typeStr EqpType, s string, Collca *COLLCA) int {
    34  	var st string
    35  	id := 0
    36  
    37  	if typeStr == COLLECTOR_TYPE {
    38  		Collca.Type = COLLECTOR_PDT
    39  	} else {
    40  		Collca.Type = ACOLLECTOR_PDT
    41  	}
    42  
    43  	if idx := strings.Index(s, "="); idx == -1 {
    44  		Collca.name = s
    45  		Collca.b0 = -999.0
    46  		Collca.b1 = -999.0
    47  		Collca.Ac = -999.0
    48  		Collca.Ag = -999.0
    49  	} else {
    50  		st = s[idx+1:]
    51  		s = s[:idx]
    52  
    53  		dt, err := strconv.ParseFloat(st, 64)
    54  		if err != nil {
    55  			panic(err)
    56  		}
    57  
    58  		switch s {
    59  		case "b0":
    60  			Collca.b0 = dt
    61  		case "b1":
    62  			Collca.b1 = dt
    63  		case "Fd":
    64  			Collca.Fd = dt
    65  		case "Ac":
    66  			Collca.Ac = dt
    67  		case "Ag":
    68  			Collca.Ag = dt
    69  		default:
    70  			id = 1
    71  		}
    72  	}
    73  
    74  	return id
    75  }
    76  
    77  /* ------------------------------------- */
    78  
    79  /*  初期設定 */
    80  
    81  func Collint(Coll []*COLL, Exs []*EXSF, Wd *WDAT) {
    82  	for _, coll := range Coll {
    83  		coll.Ta = &Wd.T
    84  		coll.sol = nil
    85  		for _, exs := range Exs {
    86  			if coll.Cmp.Exsname == exs.Name {
    87  				coll.sol = exs
    88  			}
    89  		}
    90  		if coll.sol == nil {
    91  			Eprint("Collint", coll.Cmp.Exsname)
    92  		}
    93  
    94  		if coll.Cat.b0 < 0.0 {
    95  			Err := fmt.Sprintf("Name=%s b0=%.4g", coll.Cmp.Name, coll.Cat.b0)
    96  			Eprint("Collint", Err)
    97  		}
    98  		if coll.Cat.b1 < 0.0 {
    99  			Err := fmt.Sprintf("Name=%s b1=%.4g", coll.Cmp.Name, coll.Cat.b1)
   100  			Eprint("Collint", Err)
   101  		}
   102  		if coll.Cat.Ac < 0.0 {
   103  			Err := fmt.Sprintf("Name=%s Ac=%.4g", coll.Cmp.Name, coll.Cat.Ac)
   104  			Eprint("Collint", Err)
   105  		}
   106  		if coll.Cat.Ag < 0.0 {
   107  			Err := fmt.Sprintf("Name=%s Ag=%.4g", coll.Cmp.Name, coll.Cat.Ag)
   108  			Eprint("Collint", Err)
   109  		}
   110  
   111  		// 総合熱損失係数[W/(m2・K)]の計算
   112  		coll.Cat.Ko = coll.Cat.b1 / coll.Cat.Fd
   113  	}
   114  }
   115  
   116  // 集熱器の相当外気温度を計算する(制御用)
   117  func CalcCollTe(Coll []*COLL) {
   118  	for _, coll := range Coll {
   119  		tgaKo := coll.Cat.b0 / coll.Cat.b1
   120  		coll.Te = scolte(tgaKo, coll.sol.Cinc, coll.sol.Idre, coll.sol.Idf, *coll.Ta)
   121  	}
   122  }
   123  
   124  /* ------------------------------------- */
   125  
   126  /*  特性式の係数   */
   127  
   128  //
   129  //   +------+ ---> [OUT 1]
   130  //   | COLL |
   131  //   +------+ ---> [OUT 2] ACOLLECTOR_PDTのみ
   132  //
   133  func Collcfv(Coll []*COLL) {
   134  	for _, coll := range Coll {
   135  		// 制御用の相当外気温度(現在時刻)は計算済みなのでここでは計算しない
   136  		if coll.Cmp.Control != OFF_SW {
   137  			Eo1 := coll.Cmp.Elouts[0]
   138  			Kcw := coll.Cat.b1
   139  			cG := Spcheat(Eo1.Fluid) * Eo1.G
   140  			coll.ec = 1.0 - math.Exp(-Kcw*coll.Cmp.Ac/cG)
   141  			coll.D1 = cG * coll.ec
   142  			coll.Do = coll.D1 * coll.Te
   143  
   144  			Eo1.Coeffo = cG
   145  			Eo1.Co = coll.Do
   146  			Eo1.Coeffin[0] = coll.D1 - cG
   147  
   148  			if coll.Cat.Type == ACOLLECTOR_PDT {
   149  				Eo2 := coll.Cmp.Elouts[1]
   150  				Eo2.Coeffo = 1.0
   151  				Eo2.Co = 0.0
   152  				Eo2.Coeffin[0] = -1.0
   153  			}
   154  		}
   155  	}
   156  }
   157  
   158  /* ------------------------------------- */
   159  
   160  /*  集熱量の計算 */
   161  
   162  func Collene(Coll []*COLL) {
   163  	for _, coll := range Coll {
   164  		coll.Tin = coll.Cmp.Elins[0].Sysvin
   165  
   166  		if coll.Cmp.Control != OFF_SW {
   167  			coll.Q = coll.Do - coll.D1*coll.Tin
   168  		} else {
   169  			coll.Q = 0.0
   170  		}
   171  
   172  		// 集熱板温度の計算
   173  		if coll.Q > 0.0 {
   174  			coll.Tcb = coll.Te - coll.Q/(coll.Ac*coll.Cat.Ko)
   175  		} else {
   176  			// 集熱ポンプ停止時は相当外気温度に等しいとする
   177  			coll.Tcb = coll.Te
   178  		}
   179  
   180  		coll.Sol = coll.sol.Iw * coll.Cmp.Ac
   181  	}
   182  }
   183  
   184  /* ------------------------------------- */
   185  
   186  /*  集熱器到達温度 Te       */
   187  
   188  func scolte(rtgko, cinc, Idre, Idf, Ta float64) float64 {
   189  	Cidf := 0.91
   190  	return rtgko*(Glscid(cinc)*Idre+Cidf*Idf) + Ta
   191  }
   192  
   193  /* ------------------------------------- */
   194  
   195  // 集熱器内部変数のポインターの作成
   196  func collvptr(key []string, Coll *COLL) (VPTR, error) {
   197  	if key[1] == "Te" {
   198  		return VPTR{Ptr: &Coll.Te, Type: VAL_CTYPE}, nil
   199  	} else if key[1] == "Tcb" {
   200  		return VPTR{Ptr: &Coll.Tcb, Type: VAL_CTYPE}, nil
   201  	}
   202  
   203  	return VPTR{}, errors.New("collvptr error")
   204  }
   205  
   206  /* ------------------------------------------------------------- */
   207  
   208  func collprint(fo io.Writer, id int, Coll []*COLL) {
   209  	switch id {
   210  	case 0:
   211  		if len(Coll) > 0 {
   212  			fmt.Fprintf(fo, "%s %d\n", COLLECTOR_TYPE, len(Coll))
   213  		}
   214  		for _, coll := range Coll {
   215  			fmt.Fprintf(fo, " %s 1 7\n", coll.Name)
   216  		}
   217  	case 1:
   218  		for _, coll := range Coll {
   219  			fmt.Fprintf(fo, "%s_c c c %s_Ti t f %s_To t f %s_Te t f %s_Tcb t f %s_Q q f %s_S e f\n",
   220  				coll.Name, coll.Name, coll.Name, coll.Name, coll.Name, coll.Name, coll.Name)
   221  		}
   222  	default:
   223  		for _, coll := range Coll {
   224  			fmt.Fprintf(fo, "%c %4.1f %4.1f %4.1f %4.1f %3.0f %3.0f\n",
   225  				coll.Cmp.Elouts[0].Control,
   226  				coll.Tin, coll.Cmp.Elouts[0].Sysv, coll.Te, coll.Tcb, coll.Q, coll.Sol)
   227  		}
   228  	}
   229  }
   230  
   231  /* --------------------------- */
   232  
   233  /* 日積算値に関する処理 */
   234  
   235  func colldyint(Coll []*COLL) {
   236  	for _, coll := range Coll {
   237  		svdyint(&coll.Tidy) // 温度の日次積分
   238  		qdyint(&coll.Qdy)   // 熱量の日次積分
   239  		edyint(&coll.Soldy) // 経済性指標の日次積分
   240  	}
   241  }
   242  
   243  func collmonint(Coll []*COLL) {
   244  	for _, coll := range Coll {
   245  		svdyint(&coll.mTidy) // 温度の月次積分
   246  		qdyint(&coll.mQdy)   // 熱量の月次積分
   247  		edyint(&coll.mSoldy) // 経済性指標の月次積分
   248  	}
   249  }
   250  
   251  func collday(Mon, Day, ttmm int, Coll []*COLL, Nday, SimDayend int) {
   252  	var sw ControlSWType
   253  
   254  	for _, coll := range Coll {
   255  		// 日次集計
   256  		svdaysum(int64(ttmm), coll.Cmp.Control, coll.Tin, &coll.Tidy) // 温度の日次集計
   257  		qdaysum(int64(ttmm), coll.Cmp.Control, coll.Q, &coll.Qdy)     // 熱量の日次集計
   258  
   259  		if coll.Sol > 0.0 {
   260  			sw = ON_SW
   261  		} else {
   262  			sw = OFF_SW
   263  		}
   264  		edaysum(ttmm, sw, coll.Sol, &coll.Soldy)
   265  
   266  		// 月次集計
   267  		svmonsum(Mon, Day, ttmm, coll.Cmp.Control, coll.Tin, &coll.mTidy, Nday, SimDayend) // 温度の月次集計
   268  		qmonsum(Mon, Day, ttmm, coll.Cmp.Control, coll.Q, &coll.mQdy, Nday, SimDayend)     // 熱量の月次集計
   269  
   270  		if coll.Sol > 0.0 {
   271  			sw = ON_SW
   272  		} else {
   273  			sw = OFF_SW
   274  		}
   275  		emonsum(Mon, Day, ttmm, sw, coll.Sol, &coll.mSoldy, Nday, SimDayend)
   276  	}
   277  }
   278  
   279  func colldyprt(fo io.Writer, id int, Coll []*COLL) {
   280  	switch id {
   281  	case 0:
   282  		if len(Coll) > 0 {
   283  			fmt.Fprintf(fo, "%s %d\n", COLLECTOR_TYPE, len(Coll))
   284  		}
   285  		for _, coll := range Coll {
   286  			fmt.Fprintf(fo, " %s 1 18\n", coll.Name)
   287  		}
   288  	case 1:
   289  		for _, coll := range Coll {
   290  			fmt.Fprintf(fo, "%s_Ht H d %s_T T f ", coll.Name, coll.Name)
   291  			fmt.Fprintf(fo, "%s_ttn h d %s_Tn t f %s_ttm h d %s_Tm t f\n", coll.Name, coll.Name, coll.Name, coll.Name)
   292  			fmt.Fprintf(fo, "%s_Hh H d %s_Qh Q f %s_Hc H d %s_Qc Q f\n", coll.Name, coll.Name, coll.Name, coll.Name)
   293  			fmt.Fprintf(fo, "%s_th h d %s_qh q f %s_tc h d %s_qc q f\n", coll.Name, coll.Name, coll.Name, coll.Name)
   294  			fmt.Fprintf(fo, "%s_He H d %s_S E f %s_te h d %s_Sm e f\n\n", coll.Name, coll.Name, coll.Name, coll.Name)
   295  		}
   296  	default:
   297  		for _, coll := range Coll {
   298  			fmt.Fprintf(fo, "%1d %3.1f %1d %3.1f %1d %3.1f ",
   299  				coll.Tidy.Hrs, coll.Tidy.M, coll.Tidy.Mntime, coll.Tidy.Mn,
   300  				coll.Tidy.Mxtime, coll.Tidy.Mx)
   301  			fmt.Fprintf(fo, "%1d %3.1f ", coll.Qdy.Hhr, coll.Qdy.H)
   302  			fmt.Fprintf(fo, "%1d %3.1f ", coll.Qdy.Chr, coll.Qdy.C)
   303  			fmt.Fprintf(fo, "%1d %2.0f ", coll.Qdy.Hmxtime, coll.Qdy.Hmx)
   304  			fmt.Fprintf(fo, "%1d %2.0f ", coll.Qdy.Cmxtime, coll.Qdy.Cmx)
   305  			fmt.Fprintf(fo, "%1d %3.1f ", coll.Soldy.Hrs, coll.Soldy.D)
   306  			fmt.Fprintf(fo, "%1d %2.0f\n", coll.Soldy.Mxtime, coll.Soldy.Mx)
   307  		}
   308  	}
   309  }
   310  
   311  func collmonprt(fo io.Writer, id int, Coll []*COLL) {
   312  	switch id {
   313  	case 0:
   314  		if len(Coll) > 0 {
   315  			fmt.Fprintf(fo, "%s %d\n", COLLECTOR_TYPE, len(Coll))
   316  		}
   317  		for _, coll := range Coll {
   318  			fmt.Fprintf(fo, " %s 1 18\n", coll.Name)
   319  		}
   320  	case 1:
   321  		for _, coll := range Coll {
   322  			fmt.Fprintf(fo, "%s_Ht H d %s_T T f ", coll.Name, coll.Name)
   323  			fmt.Fprintf(fo, "%s_ttn h d %s_Tn t f %s_ttm h d %s_Tm t f\n", coll.Name, coll.Name, coll.Name, coll.Name)
   324  			fmt.Fprintf(fo, "%s_Hh H d %s_Qh Q f %s_Hc H d %s_Qc Q f\n", coll.Name, coll.Name, coll.Name, coll.Name)
   325  			fmt.Fprintf(fo, "%s_th h d %s_qh q f %s_tc h d %s_qc q f\n", coll.Name, coll.Name, coll.Name, coll.Name)
   326  			fmt.Fprintf(fo, "%s_He H d %s_S E f %s_te h d %s_Sm e f\n\n", coll.Name, coll.Name, coll.Name, coll.Name)
   327  		}
   328  	default:
   329  		for _, coll := range Coll {
   330  			fmt.Fprintf(fo, "%1d %3.1f %1d %3.1f %1d %3.1f ",
   331  				coll.mTidy.Hrs, coll.mTidy.M, coll.mTidy.Mntime,
   332  				coll.mTidy.Mn, coll.mTidy.Mxtime, coll.mTidy.Mx)
   333  			fmt.Fprintf(fo, "%1d %3.1f ", coll.mQdy.Hhr, coll.mQdy.H)
   334  			fmt.Fprintf(fo, "%1d %3.1f ", coll.mQdy.Chr, coll.mQdy.C)
   335  			fmt.Fprintf(fo, "%1d %2.0f ", coll.mQdy.Hmxtime, coll.mQdy.Hmx)
   336  			fmt.Fprintf(fo, "%1d %2.0f ", coll.mQdy.Cmxtime, coll.mQdy.Cmx)
   337  			fmt.Fprintf(fo, "%1d %3.1f ", coll.mSoldy.Hrs, coll.mSoldy.D)
   338  			fmt.Fprintf(fo, "%1d %2.0f\n", coll.mSoldy.Mxtime, coll.mSoldy.Mx)
   339  		}
   340  	}
   341  }