github.com/archlabjp/eeslism-go@v0.0.0-20231109122333-4bb7bfcdf292/eeslism/mcvav.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  /*  mcvav.c  */
    17  
    18  /*  VAVコントローラ */
    19  
    20  package eeslism
    21  
    22  import (
    23  	"errors"
    24  	"fmt"
    25  	"io"
    26  	"math"
    27  	"strconv"
    28  	"strings"
    29  )
    30  
    31  /* ------------------------------------------ */
    32  
    33  /* 機器仕様入力      */
    34  
    35  /*---- Satoh Debug VAV  2000/10/30 ----*/
    36  
    37  func VAVdata(cattype EqpType, s string, vavca *VAVCA) int {
    38  	var st string
    39  	var dt float64
    40  	var id int
    41  
    42  	if cattype == VAV_TYPE {
    43  		vavca.Type = VAV_PDT
    44  	} else if cattype == VWV_TYPE {
    45  		vavca.Type = VWV_PDT
    46  	}
    47  
    48  	if st = strings.Split(s, "=")[1]; st == "" {
    49  		vavca.Name = s
    50  		vavca.Gmax = -999.0
    51  		vavca.Gmin = -999.0
    52  		vavca.dTset = -999.0
    53  	} else {
    54  		dt, _ = strconv.ParseFloat(st, 64)
    55  
    56  		switch s {
    57  		case "Gmax":
    58  			vavca.Gmax = dt
    59  		case "Gmin":
    60  			vavca.Gmin = dt
    61  		case "dTset":
    62  			vavca.dTset = dt
    63  		default:
    64  			id = 1
    65  		}
    66  	}
    67  
    68  	return id
    69  }
    70  
    71  func VWVint(VAVs []*VAV, Compn []*COMPNT) {
    72  	for _, vav := range VAVs {
    73  		vav.Hcc = nil
    74  		vav.Hcld = nil
    75  		vav.Mon = '-'
    76  
    77  		if vav.Cat.Type == VWV_PDT {
    78  			if vav.Cmp.Hccname != "" {
    79  				vav.Hcc = hccptr('c', vav.Cmp.Hccname, Compn, &vav.Mon).(*HCC)
    80  			} else if vav.Cmp.Rdpnlname != "" {
    81  				vav.Rdpnl = rdpnlptr(vav.Cmp.Rdpnlname, Compn)
    82  				if vav.Rdpnl != nil {
    83  					vav.Mon = 'f'
    84  				}
    85  			}
    86  
    87  			if vav.Mon == '-' {
    88  				vav.Hcld = hccptr('h', vav.Cmp.Hccname, Compn, &vav.Mon).(*HCLOAD)
    89  			}
    90  
    91  			if vav.Mon == '-' {
    92  				s := fmt.Sprintf("VWV(%s)=%s", vav.Name, vav.Cmp.Hccname)
    93  				fmt.Printf("xxxxxxxxx %s xxxxxxxxxxx\n", s)
    94  			}
    95  		}
    96  	}
    97  }
    98  
    99  /*  特性式の係数  */
   100  /*---- Satoh Debug VAV  2000/11/8 ----*/
   101  /*********************/
   102  
   103  //
   104  //   +-----+ ---> [OUT 1] 空気 or 温水温度
   105  ///  | VAV |
   106  //   +-----+ ---> [OUT 2] 湿度 (VAV_PDTのみ)
   107  //
   108  func VAVcfv(vav []*VAV) {
   109  	for _, v := range vav {
   110  		Eo1 := v.Cmp.Elouts[0]
   111  
   112  		if v.Cmp.Control != OFF_SW && Eo1.Control != OFF_SW {
   113  			if v.Cat.Gmax < 0.0 {
   114  				Err := fmt.Sprintf("Name=%s  Gmax=%.5g", v.Name, v.Cat.Gmax)
   115  				Eprint("VAVcfv", Err)
   116  			}
   117  			if v.Cat.Gmin < 0.0 {
   118  				Err := fmt.Sprintf("Name=%s  Gmin=%.5g", v.Name, v.Cat.Gmin)
   119  				Eprint("VAVcfv", Err)
   120  			}
   121  
   122  			if v.Count == 0 {
   123  				v.G = Eo1.G
   124  				v.CG = Spcheat(Eo1.Fluid) * v.G
   125  
   126  				Eo1.Coeffo = v.CG
   127  				Eo1.Co = 0.0
   128  				Eo1.Coeffin[0] = -v.CG
   129  			} else {
   130  				Eo1.Coeffo = 1.0
   131  				Eo1.Co = 0.0
   132  				Eo1.Coeffin[0] = -1.0
   133  			}
   134  
   135  			if v.Cat.Type == VAV_PDT {
   136  				Eo2 := v.Cmp.Elouts[1]
   137  				Eo2.Coeffo = 1.0
   138  				Eo2.Co = 0.0
   139  				Eo2.Coeffin[0] = -1.0
   140  			}
   141  		}
   142  	}
   143  }
   144  
   145  /************************:/
   146  /* ------------------------------------------ */
   147  
   148  /* VAVコントローラ再熱部分の計算 */
   149  /*---- Satoh Debug VAV  2000/11/27 ----*/
   150  /*******************/
   151  func VAVene(vav []*VAV, VAVrest *int) {
   152  	var rest int
   153  	var elo *ELOUT
   154  	var Tr, Go, dTset float64
   155  
   156  	for _, v := range vav {
   157  		rest = 0
   158  
   159  		elo = v.Cmp.Elouts[0]
   160  		v.Tin = elo.Elins[0].Sysvin
   161  
   162  		if v.Cmp.Control != OFF_SW && elo.Control != OFF_SW {
   163  			Go = v.G
   164  			v.Tout = elo.Sysv
   165  
   166  			if v.Cat.Type == VAV_PDT {
   167  				Tr = v.Cmp.Elouts[0].Emonitr.Sysv
   168  
   169  				v.Q = Spcheat(elo.Fluid) * Go * (v.Tout - Tr)
   170  
   171  				if math.Abs(v.Tin-Tr) > 1.0e-3 {
   172  					v.G = (v.Tout - Tr) / (v.Tin - Tr) * Go
   173  				} else {
   174  					v.G = v.Cat.Gmin
   175  				}
   176  			} else {
   177  				if v.Mon == 'c' && v.Count < VAVCountMAX-1 {
   178  					v.Qrld = -v.Hcc.Qt
   179  				} else if v.Mon == 'f' && v.Count < VAVCountMAX-1 {
   180  					v.Qrld = -v.Rdpnl.Q
   181  				} else if v.Mon == 'h' {
   182  					v.Qrld = v.Hcld.Qt
   183  				}
   184  
   185  				v.Q = v.Qrld
   186  
   187  				dTset = v.Cat.dTset
   188  
   189  				if v.Mon == 'h' && dTset <= 0.0 {
   190  					fmt.Printf("<VAVene> VWV SetDifferencialTemp=%.1f\n", v.Cat.dTset)
   191  				}
   192  
   193  				if v.Chmode == COOLING_SW {
   194  					dTset = -dTset
   195  				}
   196  
   197  				if v.Mon == 'h' || v.Mon == 'f' {
   198  					v.G = v.Q / (Spcheat(elo.Fluid) * dTset)
   199  				} else if v.Mon == 'c' {
   200  					v.G = FNVWVG(v)
   201  				}
   202  			}
   203  
   204  			elo.Control = ON_SW
   205  			elo.Sysld = 'n'
   206  
   207  			if v.Mon != 'h' {
   208  				elo.Emonitr.Control = ON_SW
   209  			}
   210  
   211  			rest = chvavswreset(v.Q, v.Chmode, v)
   212  
   213  			if rest == 1 || math.Abs(v.G-Go) > 1.0e-5 {
   214  				(*VAVrest)++
   215  			}
   216  		} else {
   217  			v.Q = 0.0
   218  			v.G = v.Cat.Gmin
   219  
   220  			if v.Count == 0 {
   221  				(*VAVrest)++
   222  			}
   223  		}
   224  	}
   225  }
   226  
   227  func (eqsys *EQSYS) VAVcountreset() {
   228  	for _, v := range eqsys.Vav {
   229  		v.Count = 0
   230  	}
   231  }
   232  
   233  func (eqsys *EQSYS) VAVcountinc() {
   234  	for _, v := range eqsys.Vav {
   235  		v.Count++
   236  	}
   237  }
   238  
   239  // VAVスイッチのポインターを作成します
   240  func vavswptr(key []string, VAV *VAV) (VPTR, error) {
   241  	if key[1] == "chmode" {
   242  		return VPTR{
   243  			Ptr:  &VAV.Chmode,
   244  			Type: SW_CTYPE,
   245  		}, nil
   246  	} else if key[1] == "control" {
   247  		return VPTR{
   248  			Ptr:  &VAV.Cmp.Elouts[0].Control,
   249  			Type: SW_CTYPE,
   250  		}, nil
   251  
   252  	}
   253  	return VPTR{}, errors.New("vavswptr error")
   254  }
   255  
   256  func chvavswreset(Qload float64, chmode ControlSWType, vav *VAV) int {
   257  	if (chmode == HEATING_SW && Qload < 0.0) ||
   258  		(chmode == COOLING_SW && Qload > 0.0) {
   259  		vav.G = vav.Cat.Gmin
   260  		return 1
   261  	} else {
   262  		if vav.G < vav.Cat.Gmin {
   263  			vav.G = vav.Cat.Gmin
   264  			return 1
   265  		} else if vav.G > vav.Cat.Gmax {
   266  			vav.G = vav.Cat.Gmax
   267  			return 1
   268  		} else {
   269  			return 0
   270  		}
   271  	}
   272  }
   273  
   274  func vavprint(fo io.Writer, id int, VAVs []*VAV) {
   275  	switch id {
   276  	case 0:
   277  		if len(VAVs) > 0 {
   278  			fmt.Fprintf(fo, "%s %d\n", VAV_TYPE, len(VAVs))
   279  		}
   280  		for _, vav := range VAVs {
   281  			fmt.Fprintf(fo, " %s 1 2\n", vav.Name)
   282  		}
   283  	case 1:
   284  		for _, vav := range VAVs {
   285  			fmt.Fprintf(fo, "%s_c c c %s_G m f\n", vav.Name, vav.Name)
   286  		}
   287  	default:
   288  		for _, vav := range VAVs {
   289  			fmt.Fprintf(fo, "%c %6.4g\n", vav.Cmp.Elouts[0].Control, vav.Cmp.Elouts[0].G)
   290  		}
   291  	}
   292  }
   293  
   294  /* VWVシステムの流量計算 */
   295  func FNVWVG(VWV *VAV) float64 {
   296  	var Wa, Wwd, Tain, Twin, Q, KA, et, F, emax, emin, Gwd float64
   297  	var A, B float64
   298  	var h *HCC
   299  	var i int
   300  
   301  	h = VWV.Hcc
   302  	Wa = h.cGa
   303  	Q = VWV.Q
   304  	KA = h.Cat.KA
   305  	Tain = h.Tain
   306  	Twin = VWV.Tin
   307  	A = VWV.Cat.Gmin
   308  	B = VWV.Cat.Gmax
   309  	Gwd = (A + B) / 2.0
   310  	Wwd = Gwd * Cw
   311  
   312  	et = -Q / (Wa * (Tain - Twin))
   313  	emin = FNhccet(Wa, Cw*A, KA)
   314  	emax = FNhccet(Wa, Cw*B, KA)
   315  
   316  	if et > emax {
   317  		return VWV.Cat.Gmax
   318  	} else if et < emin {
   319  		return VWV.Cat.Gmin
   320  	}
   321  
   322  	for i = 0; i < 30; i++ {
   323  		Wwd = Gwd * Cw
   324  		F = FNhccet(Wa, Wwd, KA) - et
   325  		if math.Abs(F) < 1.0e-5 {
   326  			return Gwd
   327  		} else if F > 0.0 {
   328  			B = Gwd
   329  		} else if F < 0.0 {
   330  			A = Gwd
   331  		}
   332  
   333  		Gwd = (A + B) / 2.0
   334  	}
   335  
   336  	fmt.Println("xxxxxx FNVWVG  収束せず")
   337  	fmt.Println(Gwd)
   338  
   339  	return Gwd
   340  }
   341  
   342  func FNFd(Wa, Ww, KA float64) float64 {
   343  	B := (1.0 - Wa/Ww) * KA / Wa
   344  	exB := math.Exp(-B)
   345  	ex2B := math.Exp(-2.0 * B)
   346  	Ww2 := math.Pow(Ww, 2.0)
   347  
   348  	d := Ww * math.Pow(Ww-Wa*exB, 2.0)
   349  	n := (Ww2+Ww+KA)*ex2B - (Ww*(Ww2+Wa)-Wa*KA)*exB
   350  
   351  	return n / d
   352  }