aboutsummaryrefslogtreecommitdiffstats
path: root/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'main.go')
-rw-r--r--main.go255
1 files changed, 131 insertions, 124 deletions
diff --git a/main.go b/main.go
index aaf4264..656f749 100644
--- a/main.go
+++ b/main.go
@@ -2,157 +2,164 @@ package main
import (
"fmt"
- g "github.com/AllenDang/giu"
"image"
- "image/draw"
- _ "image/jpeg"
"os"
-)
+ "sync"
-const (
- gasConstant = 8.314472
- airMolarMass = 0.0289647 // kg/mol
+ "github.com/faiface/mainthread"
+ "volute/gui"
+ "volute/gui/widget"
+ "volute/gui/win"
)
-var (
- defaultDisplacement = 2 * Litre
- defaultSpeed int32 = 2000
- defaultVE int32 = 80
- defaultTemperature = Temperature{25, Celcius}
-)
-
-var (
- defaultManufacturer = "borgwarner"
- defaultSeries = "efr"
- defaultModel = "6258"
-)
-
-// Number of data points on the compressor map.
-var numPoints = 1
-
-var (
- displacement = defaultDisplacement
- volumeUnitIndex int32
-
- // Angular crankshaft speed in RPM.
- speed = []int32{defaultSpeed}
+const (
+ WIDTH = 800
+ HEIGHT = 600
- volumetricEfficiency = []int32{defaultVE}
+ POINTS = 6
- intakeAirTemperature = []Temperature{defaultTemperature}
- temperatureUnitIndex int32
+ R = 8314.3 // gas constant
+ M = 28.962 // molar mass of air
- manifoldPressure = []Pressure{AtmosphericPressure()}
- pressureUnitIndex int32
+ WIDEST_LABEL = "mass flow (kg/min)"
)
-var pressureRatio []float32
+func run() {
+ wg := new(sync.WaitGroup)
+ defer wg.Wait()
-func pressureRatioAt(point int) float32 {
- u := Pascal
- m := manifoldPressure[point] / u
- a := AtmosphericPressure() / u
- return float32(m / a)
-}
-func init() {
- pressureRatio = append(pressureRatio, pressureRatioAt(0))
-}
-
-var (
- massFlowRateAir []MassFlowRate
- massFlowRateUnitIndex int32
-)
+ focus := widget.NewFocus([]int{1, POINTS, POINTS, POINTS, POINTS})
+ defer focus.Close()
-func massFlowRateAt(point int) MassFlowRate {
- rpm := float32(speed[point])
- disp := float32(displacement / CubicMetre)
- ve := float32(volumetricEfficiency[point]) / 100.0
- cubicMetresPerMin := (rpm / 2.0) * disp * ve
+ displacementChan := make(chan uint)
+ displacementBroadcast := NewBroadcast(displacementChan)
+ defer displacementBroadcast.Wait()
- iat, err := intakeAirTemperature[point].AsUnit(Kelvin)
- Check(err)
- pres := manifoldPressure[point] / Pascal
- molsPerMin := (float32(pres) * cubicMetresPerMin) / (gasConstant * iat)
+ var (
+ rpmChan [POINTS]chan uint
+ veChan [POINTS]chan uint
+ imapChan [POINTS]chan uint
+ actChan [POINTS]chan uint
- kgPerMin := molsPerMin * airMolarMass
+ flowChan [POINTS]chan float64
+ )
+ makeChans(rpmChan[:], veChan[:], imapChan[:], actChan[:])
+ makeChans(flowChan[:])
- mfr := MassFlowRate(kgPerMin/60.0) * KilogramsPerSecond
- return mfr
-}
-func init() {
- massFlowRateAir = append(massFlowRateAir, massFlowRateAt(0))
-}
+ w, err := win.New(win.Title("volute"), win.Size(WIDTH, HEIGHT))
+ if err != nil {
+ fmt.Println("error creating window:", err)
+ os.Exit(1)
+ }
+ mux, env := gui.NewMux(w)
+ defer close(env.Draw())
+
+ spawnWidgets(
+ displacementChan,
+ rpmChan, veChan, imapChan, actChan,
+ flowChan,
+ &focus,
+ mux,
+ wg,
+ )
-var (
- compressorImage *image.RGBA
- compressorTexture *g.Texture
- selectedCompressor Compressor
-)
+ imChan := make(chan image.Image)
+ defer close(imChan)
+ wg.Add(1)
+ go widget.Image(
+ imChan,
+ image.Rect(0, 200, 100, 300),
+ mux.MakeEnv(),
+ wg,
+ )
-func init() {
- manufacturer := defaultManufacturer
- series := defaultSeries
- model := defaultModel
- c, ok := Compressors[manufacturer][series][model]
- if !ok {
- fmt.Printf("compressor.Compressors()[\"%s\"][\"%s\"][\"%s\"] does not exist.\n",
- manufacturer, series, model,
+ for i := 0; i < POINTS; i++ {
+ wg.Add(1)
+ go calculateFlow(
+ flowChan[i],
+ displacementBroadcast.AddDestination(),
+ rpmChan[i], veChan[i], actChan[i], imapChan[i],
+ wg,
)
- os.Exit(1)
}
- setCompressor(c)
+ focus.Focus(true)
+ eventLoop(env, &focus)
}
-func main() {
- wnd := g.NewMasterWindow("volute", 400, 200, 0)
-
- go updateCompImg()
- m := <-updatedCompImg
- g.EnqueueNewTextureFromRgba(m, func(tex *g.Texture) {
- compressorTexture = tex
- })
-
- wnd.Run(loop)
+func eventLoop(env gui.Env, focus *widget.Focus) {
+ for event := range env.Events() {
+ switch event := event.(type) {
+ case win.WiClose:
+ return
+ case win.KbType:
+ switch event.Rune {
+ case 'q':
+ return
+ case 'h':
+ focus.Left()
+ case 'j':
+ focus.Down()
+ case 'k':
+ focus.Up()
+ case 'l':
+ focus.Right()
+ }
+ }
+ }
}
-func setCompressor(c Compressor) {
- f, err := os.Open(c.FileName)
- Check(err)
- defer f.Close()
-
- j, _, err := image.Decode(f)
- Check(err)
+func makeChans[T any](chanss ...[]chan T) {
+ for i := range chanss {
+ for j := range chanss[i] {
+ chanss[i][j] = make(chan T)
+ }
+ }
+}
- b := j.Bounds()
- m := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))
- draw.Draw(m, m.Bounds(), j, b.Min, draw.Src)
+func calculateFlow(
+ flow chan<- float64,
+ displacementChan, rpmChan, veChan, actChan, imapChan <-chan uint,
+ wg *sync.WaitGroup,
+) {
+ defer wg.Done()
+ defer close(flow)
+
+ var (
+ displacement Volume
+ rpm uint
+ ve uint
+ act Temperature
+ imap Pressure
+
+ v uint
+ ok bool
+ )
- selectedCompressor = c
- compressorImage = m
+ for {
+ select {
+ case v, ok = <-displacementChan:
+ displacement = Volume(v) * CubicCentimetre
+ case rpm, ok = <-rpmChan:
+ case ve, ok = <-veChan:
+ case v, ok = <-actChan:
+ act = Temperature{float64(v), Celcius}
+ case v, ok = <-imapChan:
+ imap = Pressure(v) * Millibar
+ }
+ if !ok {
+ return
+ }
+ flow <- massFlow(displacement, rpm, ve, act, imap)
+ }
+}
- go updateCompImg()
+func massFlow(displacement Volume, rpm, ve uint, act Temperature, imap Pressure) float64 {
+ density := (M / R) * float64(imap/Pascal) / act.AsUnit(Kelvin) // kg/m3
+ volumeFlow := float64(displacement/CubicMetre) * float64(rpm/2) * (float64(ve) / 100.0) // m3/min
+ return density * volumeFlow
}
-func loop() {
- g.SingleWindow().Layout(
- displacementRow(),
- g.Table().
- Size(g.Auto, 190).
- Rows(
- speedRow(),
- volumetricEfficiencyRow(),
- intakeAirTemperatureRow(),
- manifoldPressureRow(),
- pressureRatioRow(),
- massFlowRateRow(),
- duplicateDeleteRow(),
- ).
- Columns(
- columns()...,
- ).
- Flags(g.TableFlagsSizingFixedFit),
- selectCompressor(),
- g.Custom(compressorWidget),
- )
+func main() {
+ mainthread.Run(run)
}