Skip to content

Commit

Permalink
Merge pull request #391 from yangchoo/add-vol-flow-units
Browse files Browse the repository at this point in the history
Add VolumeFlow units (l,nl,ml,µl per s,min,h,d)
  • Loading branch information
cquiroz authored Aug 8, 2020
2 parents 2e3caff + df3e51a commit 38d6501
Show file tree
Hide file tree
Showing 2 changed files with 279 additions and 2 deletions.
169 changes: 167 additions & 2 deletions shared/src/main/scala/squants/motion/VolumeFlow.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
package squants.motion

import squants.{ Seconds, _ }
import squants.space.{ CubicFeet, CubicMeters, UsGallons }
import squants.space.{ CubicFeet, CubicMeters, Litres, Microlitres, Millilitres, Nanolitres, UsGallons }
import squants.time._

/**
Expand All @@ -28,6 +28,23 @@ final class VolumeFlow private (val value: Double, val unit: VolumeFlowRateUnit)
protected[squants] def time = Seconds(1)

def toCubicMetersPerSecond = to(CubicMetersPerSecond)
def toLitresPerDay = to(LitresPerDay)
def toLitresPerHour = to(LitresPerHour)
def toLitresPerMinute = to(LitresPerMinute)
def toLitresPerSecond = to(LitresPerSecond)
def toNanolitresPerDay = to(NanolitresPerDay)
def toNanolitresPerHour = to(NanolitresPerHour)
def toNanolitresPerMinute = to(NanolitresPerMinute)
def toNanolitresPerSecond = to(NanolitresPerSecond)
def toMicrolitresPerDay = to(MicrolitresPerDay)
def toMicrolitresPerHour = to(MicrolitresPerHour)
def toMicrolitresPerMinute = to(MicrolitresPerMinute)
def toMicrolitresPerSecond = to(MicrolitresPerSecond)
def toMillilitresPerDay = to(MillilitresPerDay)
def toMillilitresPerHour = to(MillilitresPerHour)
def toMillilitresPerMinute = to(MillilitresPerMinute)
def toMillilitresPerSecond = to(MillilitresPerSecond)

def toCubicFeetPerHour = to(CubicFeetPerHour)
def toGallonsPerDay = to(GallonsPerDay)
def toGallonsPerHour = to(GallonsPerHour)
Expand All @@ -41,7 +58,11 @@ object VolumeFlow extends Dimension[VolumeFlow] {
def name = "VolumeFlow"
def primaryUnit = CubicMetersPerSecond
def siUnit = CubicMetersPerSecond
def units = Set(CubicMetersPerSecond, CubicFeetPerHour, GallonsPerDay, GallonsPerHour, GallonsPerMinute, GallonsPerSecond)
def units = Set(CubicMetersPerSecond, LitresPerSecond, LitresPerMinute, LitresPerHour, LitresPerDay,
NanolitresPerSecond, NanolitresPerMinute, NanolitresPerHour, NanolitresPerDay,
MicrolitresPerSecond, MicrolitresPerMinute, MicrolitresPerHour, MicrolitresPerDay,
MillilitresPerSecond, MillilitresPerMinute, MillilitresPerHour, MillilitresPerDay,
CubicFeetPerHour, GallonsPerDay, GallonsPerHour, GallonsPerMinute, GallonsPerSecond)
}

trait VolumeFlowRateUnit extends UnitOfMeasure[VolumeFlow] with UnitConverter {
Expand All @@ -52,6 +73,86 @@ object CubicMetersPerSecond extends VolumeFlowRateUnit with PrimaryUnit with SiU
val symbol = "m³/s"
}

object LitresPerSecond extends VolumeFlowRateUnit with SiUnit {
val symbol = "L/s"
val conversionFactor = Litres.conversionFactor / CubicMeters.conversionFactor
}

object LitresPerMinute extends VolumeFlowRateUnit with SiUnit {
val symbol = "L/min"
val conversionFactor = Litres.conversionFactor / CubicMeters.conversionFactor / Time.SecondsPerMinute
}

object LitresPerHour extends VolumeFlowRateUnit with SiUnit {
val symbol = "L/h"
val conversionFactor = Litres.conversionFactor / CubicMeters.conversionFactor / Time.SecondsPerHour
}

object LitresPerDay extends VolumeFlowRateUnit with SiUnit {
val symbol = "L/d"
val conversionFactor = Litres.conversionFactor / CubicMeters.conversionFactor / Time.SecondsPerDay
}

object NanolitresPerSecond extends VolumeFlowRateUnit with SiUnit {
val symbol = "nl/s"
val conversionFactor = Nanolitres.conversionFactor / CubicMeters.conversionFactor
}

object NanolitresPerMinute extends VolumeFlowRateUnit with SiUnit {
val symbol = "nl/min"
val conversionFactor = (Nanolitres.conversionFactor / CubicMeters.conversionFactor) / Time.SecondsPerMinute
}

object NanolitresPerHour extends VolumeFlowRateUnit with SiUnit {
val symbol = "nl/h"
val conversionFactor = Nanolitres.conversionFactor / CubicMeters.conversionFactor / Time.SecondsPerHour
}

object NanolitresPerDay extends VolumeFlowRateUnit with SiUnit {
val symbol = "nl/d"
val conversionFactor = Nanolitres.conversionFactor / CubicMeters.conversionFactor / Time.SecondsPerDay
}

object MicrolitresPerSecond extends VolumeFlowRateUnit with SiUnit {
val symbol = "µl/s"
val conversionFactor = Microlitres.conversionFactor / CubicMeters.conversionFactor
}

object MicrolitresPerMinute extends VolumeFlowRateUnit with SiUnit {
val symbol = "µl/min"
val conversionFactor = (Microlitres.conversionFactor / CubicMeters.conversionFactor) / Time.SecondsPerMinute
}

object MicrolitresPerHour extends VolumeFlowRateUnit with SiUnit {
val symbol = "µl/h"
val conversionFactor = Microlitres.conversionFactor / CubicMeters.conversionFactor / Time.SecondsPerHour
}

object MicrolitresPerDay extends VolumeFlowRateUnit with SiUnit {
val symbol = "µl/d"
val conversionFactor = Microlitres.conversionFactor / CubicMeters.conversionFactor / Time.SecondsPerDay
}

object MillilitresPerSecond extends VolumeFlowRateUnit with SiUnit {
val symbol = "ml/s"
val conversionFactor = Millilitres.conversionFactor / CubicMeters.conversionFactor
}

object MillilitresPerMinute extends VolumeFlowRateUnit with SiUnit {
val symbol = "ml/min"
val conversionFactor = (Millilitres.conversionFactor / CubicMeters.conversionFactor) / Time.SecondsPerMinute
}

object MillilitresPerHour extends VolumeFlowRateUnit with SiUnit {
val symbol = "ml/h"
val conversionFactor = Millilitres.conversionFactor / CubicMeters.conversionFactor / Time.SecondsPerHour
}

object MillilitresPerDay extends VolumeFlowRateUnit with SiUnit {
val symbol = "ml/d"
val conversionFactor = Millilitres.conversionFactor / CubicMeters.conversionFactor / Time.SecondsPerDay
}

object CubicFeetPerHour extends VolumeFlowRateUnit {
val symbol = "ft³/hr"
val conversionFactor = (CubicFeet.conversionFactor / CubicMeters.conversionFactor) / Time.SecondsPerHour
Expand Down Expand Up @@ -79,6 +180,38 @@ object GallonsPerSecond extends VolumeFlowRateUnit {

object VolumeFlowConversions {
lazy val cubicMeterPerSecond = CubicMetersPerSecond(1)
lazy val litresPerSecond = LitresPerSecond(1)
lazy val litersPerSecond = LitresPerSecond(1)
lazy val litersPerMinute = LitresPerMinute(1)
lazy val litresPerMinute = LitresPerMinute(1)
lazy val litersPerHour = LitresPerHour(1)
lazy val litresPerHour = LitresPerHour(1)
lazy val litersPerDay = LitresPerDay(1)
lazy val litresPerDay = LitresPerDay(1)
lazy val nanolitresPerSecond = NanolitresPerSecond(1)
lazy val nanolitersPerSecond = NanolitresPerSecond(1)
lazy val nanolitersPerMinute = NanolitresPerMinute(1)
lazy val nanolitresPerMinute = NanolitresPerMinute(1)
lazy val nanolitersPerHour = NanolitresPerHour(1)
lazy val nanolitresPerHour = NanolitresPerHour(1)
lazy val nanolitersPerDay = NanolitresPerDay(1)
lazy val nanolitresPerDay = NanolitresPerDay(1)
lazy val microlitresPerSecond = MicrolitresPerSecond(1)
lazy val microlitersPerSecond = MicrolitresPerSecond(1)
lazy val microlitersPerMinute = MicrolitresPerMinute(1)
lazy val microlitresPerMinute = MicrolitresPerMinute(1)
lazy val microlitersPerHour = MicrolitresPerHour(1)
lazy val microlitresPerHour = MicrolitresPerHour(1)
lazy val microlitersPerDay = MicrolitresPerDay(1)
lazy val microlitresPerDay = MicrolitresPerDay(1)
lazy val millilitresPerSecond = MillilitresPerSecond(1)
lazy val millilitersPerSecond = MillilitresPerSecond(1)
lazy val millilitersPerMinute = MillilitresPerMinute(1)
lazy val millilitresPerMinute = MillilitresPerMinute(1)
lazy val millilitersPerHour = MillilitresPerHour(1)
lazy val millilitresPerHour = MillilitresPerHour(1)
lazy val millilitersPerDay = MillilitresPerDay(1)
lazy val millilitresPerDay = MillilitresPerDay(1)
lazy val cubicFeetPerHour = CubicFeetPerHour(1)
lazy val gallonPerDay = GallonsPerDay(1)
lazy val gallonPerHour = GallonsPerHour(1)
Expand All @@ -87,6 +220,38 @@ object VolumeFlowConversions {

implicit class VolumeFlowConversions[A](n: A)(implicit num: Numeric[A]) {
def cubicMetersPerSecond = CubicMetersPerSecond(n)
def litresPerSecond = LitresPerSecond(n)
def litersPerSecond = LitresPerSecond(n)
def litersPerMinute = LitresPerMinute(n)
def litresPerMinute = LitresPerMinute(n)
def litersPerHour = LitresPerHour(n)
def litresPerHour = LitresPerHour(n)
def litersPerDay = LitresPerDay(n)
def litresPerDay = LitresPerDay(n)
def nanolitresPerSecond = NanolitresPerSecond(n)
def nanolitersPerSecond = NanolitresPerSecond(n)
def nanolitersPerMinute = NanolitresPerMinute(n)
def nanolitresPerMinute = NanolitresPerMinute(n)
def nanolitersPerHour = NanolitresPerHour(n)
def nanolitresPerHour = NanolitresPerHour(n)
def nanolitersPerDay = NanolitresPerDay(n)
def nanolitresPerDay = NanolitresPerDay(n)
def microlitresPerSecond = MicrolitresPerSecond(n)
def microlitersPerSecond = MicrolitresPerSecond(n)
def microlitersPerMinute = MicrolitresPerMinute(n)
def microlitresPerMinute = MicrolitresPerMinute(n)
def microlitersPerHour = MicrolitresPerHour(n)
def microlitresPerHour = MicrolitresPerHour(n)
def microlitersPerDay = MicrolitresPerDay(n)
def microlitresPerDay = MicrolitresPerDay(n)
def millilitresPerSecond = MillilitresPerSecond(n)
def millilitersPerSecond = MillilitresPerSecond(n)
def millilitersPerMinute = MillilitresPerMinute(n)
def millilitresPerMinute = MillilitresPerMinute(n)
def millilitersPerHour = MillilitresPerHour(n)
def millilitresPerHour = MillilitresPerHour(n)
def millilitersPerDay = MillilitresPerDay(n)
def millilitresPerDay = MillilitresPerDay(n)
def cubicFeetPerHour = CubicFeetPerHour(n)
def gallonsPerDay = GallonsPerDay(n)
def gallonsPerHour = GallonsPerHour(n)
Expand Down
112 changes: 112 additions & 0 deletions shared/src/test/scala/squants/motion/VolumeFlowSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@ class VolumeFlowSpec extends AnyFlatSpec with Matchers with CustomMatchers {

it should "create values using UOM factories" in {
CubicMetersPerSecond(1).toCubicMetersPerSecond should be(1)
LitresPerDay(1).toLitresPerDay should be(1)
LitresPerHour(1).toLitresPerHour should be(1)
LitresPerMinute(1).toLitresPerMinute should be(1)
LitresPerSecond(1).toLitresPerSecond should be(1)
NanolitresPerDay(1).toNanolitresPerDay should be(1)
NanolitresPerHour(1).toNanolitresPerHour should be(1)
NanolitresPerMinute(1).toNanolitresPerMinute should be(1)
NanolitresPerSecond(1).toNanolitresPerSecond should be(1)
MicrolitresPerDay(1).toMicrolitresPerDay should be(1)
MicrolitresPerHour(1).toMicrolitresPerHour should be(1)
MicrolitresPerMinute(1).toMicrolitresPerMinute should be(1)
MicrolitresPerSecond(1).toMicrolitresPerSecond should be(1)
MillilitresPerDay(1).toMillilitresPerDay should be(1)
MillilitresPerHour(1).toMillilitresPerHour should be(1)
MillilitresPerMinute(1).toMillilitresPerMinute should be(1)
MillilitresPerSecond(1).toMillilitresPerSecond should be(1)
CubicFeetPerHour(1).toCubicFeetPerHour should be(1)
GallonsPerDay(1).toGallonsPerDay should be(1)
GallonsPerHour(1).toGallonsPerHour should be(1)
Expand All @@ -34,6 +50,22 @@ class VolumeFlowSpec extends AnyFlatSpec with Matchers with CustomMatchers {

it should "create values from properly formatted Strings" in {
VolumeFlow("10.22 m³/s").get should be(CubicMetersPerSecond(10.22))
VolumeFlow("10.22 L/s").get should be(LitresPerSecond(10.22))
VolumeFlow("10.22 L/min").get should be(LitresPerMinute(10.22))
VolumeFlow("10.22 L/h").get should be(LitresPerHour(10.22))
VolumeFlow("10.22 L/d").get should be(LitresPerDay(10.22))
VolumeFlow("10.22 nl/s").get should be(NanolitresPerSecond(10.22))
VolumeFlow("10.22 nl/min").get should be(NanolitresPerMinute(10.22))
VolumeFlow("10.22 nl/h").get should be(NanolitresPerHour(10.22))
VolumeFlow("10.22 nl/d").get should be(NanolitresPerDay(10.22))
VolumeFlow("10.22 µl/s").get should be(MicrolitresPerSecond(10.22))
VolumeFlow("10.22 µl/min").get should be(MicrolitresPerMinute(10.22))
VolumeFlow("10.22 µl/h").get should be(MicrolitresPerHour(10.22))
VolumeFlow("10.22 µl/d").get should be(MicrolitresPerDay(10.22))
VolumeFlow("10.22 ml/s").get should be(MillilitresPerSecond(10.22))
VolumeFlow("10.22 ml/min").get should be(MillilitresPerMinute(10.22))
VolumeFlow("10.22 ml/h").get should be(MillilitresPerHour(10.22))
VolumeFlow("10.22 ml/d").get should be(MillilitresPerDay(10.22))
VolumeFlow("10.22 ft³/hr").get should be(CubicFeetPerHour(10.22))
VolumeFlow("10.22 GPD").get should be(GallonsPerDay(10.22))
VolumeFlow("10.22 GPH").get should be(GallonsPerHour(10.22))
Expand All @@ -46,6 +78,22 @@ class VolumeFlowSpec extends AnyFlatSpec with Matchers with CustomMatchers {
it should "properly convert to all supported Units of Measure" in {
val x = CubicMetersPerSecond(10.22)
x.toCubicMetersPerSecond should be(10.22)
x.toLitresPerDay should be(CubicMeters(10.22).toLitres / Seconds(1).toDays +- 1E-7)
x.toLitresPerHour should be(CubicMeters(10.22).toLitres / Seconds(1).toHours +- 1E-7)
x.toLitresPerMinute should be(CubicMeters(10.22).toLitres / Seconds(1).toMinutes)
x.toLitresPerSecond should be(CubicMeters(10.22).toLitres / Seconds(1).toSeconds)
x.toNanolitresPerDay should be(CubicMeters(10.22).toNanolitres / Seconds(1).toDays +- 100)
x.toNanolitresPerHour should be(CubicMeters(10.22).toNanolitres / Seconds(1).toHours)
x.toNanolitresPerMinute should be(CubicMeters(10.22).toNanolitres / Seconds(1).toMinutes)
x.toNanolitresPerSecond should be(CubicMeters(10.22).toNanolitres / Seconds(1).toSeconds)
x.toMicrolitresPerDay should be(CubicMeters(10.22).toMicrolitres / Seconds(1).toDays)
x.toMicrolitresPerHour should be(CubicMeters(10.22).toMicrolitres / Seconds(1).toHours)
x.toMicrolitresPerMinute should be(CubicMeters(10.22).toMicrolitres / Seconds(1).toMinutes)
x.toMicrolitresPerSecond should be(CubicMeters(10.22).toMicrolitres / Seconds(1).toSeconds)
x.toMillilitresPerDay should be(CubicMeters(10.22).toMillilitres / Seconds(1).toDays +- 1E-4)
x.toMillilitresPerHour should be(CubicMeters(10.22).toMillilitres / Seconds(1).toHours)
x.toMillilitresPerMinute should be(CubicMeters(10.22).toMillilitres / Seconds(1).toMinutes +- 1E-7)
x.toMillilitresPerSecond should be(CubicMeters(10.22).toMillilitres / Seconds(1).toSeconds)
x.toCubicFeetPerHour should be(CubicMeters(10.22).toCubicFeet / Seconds(1).toHours +- 0.00000001)
x.toGallonsPerDay should be(CubicMeters(10.22).toUsGallons / Seconds(1).toDays +- 0.00000001)
x.toGallonsPerHour should be(CubicMeters(10.22).toUsGallons / Seconds(1).toHours)
Expand All @@ -55,6 +103,22 @@ class VolumeFlowSpec extends AnyFlatSpec with Matchers with CustomMatchers {

it should "return properly formatted strings for all supported Units of Measure" in {
CubicMetersPerSecond(1).toString(CubicMetersPerSecond) should be("1.0 m³/s")
LitresPerDay(1).toString(LitresPerDay) should be("1.0 L/d")
LitresPerHour(1).toString(LitresPerHour) should be("1.0 L/h")
LitresPerMinute(1).toString(LitresPerMinute) should be("1.0 L/min")
LitresPerSecond(1).toString(LitresPerSecond) should be("1.0 L/s")
NanolitresPerDay(1).toString(NanolitresPerDay) should be("1.0 nl/d")
NanolitresPerHour(1).toString(NanolitresPerHour) should be("1.0 nl/h")
NanolitresPerMinute(1).toString(NanolitresPerMinute) should be("1.0 nl/min")
NanolitresPerSecond(1).toString(NanolitresPerSecond) should be("1.0 nl/s")
MicrolitresPerDay(1).toString(MicrolitresPerDay) should be("1.0 µl/d")
MicrolitresPerHour(1).toString(MicrolitresPerHour) should be("1.0 µl/h")
MicrolitresPerMinute(1).toString(MicrolitresPerMinute) should be("1.0 µl/min")
MicrolitresPerSecond(1).toString(MicrolitresPerSecond) should be("1.0 µl/s")
MillilitresPerDay(1).toString(MillilitresPerDay) should be("1.0 ml/d")
MillilitresPerHour(1).toString(MillilitresPerHour) should be("1.0 ml/h")
MillilitresPerMinute(1).toString(MillilitresPerMinute) should be("1.0 ml/min")
MillilitresPerSecond(1).toString(MillilitresPerSecond) should be("1.0 ml/s")
CubicFeetPerHour(1).toString(CubicFeetPerHour) should be("1.0 ft³/hr")
GallonsPerDay(1).toString(GallonsPerDay) should be("1.0 GPD")
GallonsPerHour(1).toString(GallonsPerHour) should be("1.0 GPH")
Expand All @@ -72,6 +136,38 @@ class VolumeFlowSpec extends AnyFlatSpec with Matchers with CustomMatchers {
import VolumeFlowConversions._

cubicMeterPerSecond should be(CubicMetersPerSecond(1))
litresPerDay should be(LitresPerDay(1))
litersPerDay should be(LitresPerDay(1))
litresPerHour should be(LitresPerHour(1))
litersPerHour should be(LitresPerHour(1))
litresPerMinute should be(LitresPerMinute(1))
litersPerMinute should be(LitresPerMinute(1))
litresPerSecond should be(LitresPerSecond(1))
litersPerSecond should be(LitresPerSecond(1))
nanolitresPerDay should be(NanolitresPerDay(1))
nanolitersPerDay should be(NanolitresPerDay(1))
nanolitresPerHour should be(NanolitresPerHour(1))
nanolitersPerHour should be(NanolitresPerHour(1))
nanolitresPerMinute should be(NanolitresPerMinute(1))
nanolitersPerMinute should be(NanolitresPerMinute(1))
nanolitresPerSecond should be(NanolitresPerSecond(1))
nanolitersPerSecond should be(NanolitresPerSecond(1))
microlitresPerDay should be(MicrolitresPerDay(1))
microlitersPerDay should be(MicrolitresPerDay(1))
microlitresPerHour should be(MicrolitresPerHour(1))
microlitersPerHour should be(MicrolitresPerHour(1))
microlitresPerMinute should be(MicrolitresPerMinute(1))
microlitersPerMinute should be(MicrolitresPerMinute(1))
microlitresPerSecond should be(MicrolitresPerSecond(1))
microlitersPerSecond should be(MicrolitresPerSecond(1))
millilitresPerDay should be(MillilitresPerDay(1))
millilitersPerDay should be(MillilitresPerDay(1))
millilitresPerHour should be(MillilitresPerHour(1))
millilitersPerHour should be(MillilitresPerHour(1))
millilitresPerMinute should be(MillilitresPerMinute(1))
millilitersPerMinute should be(MillilitresPerMinute(1))
millilitresPerSecond should be(MillilitresPerSecond(1))
millilitersPerSecond should be(MillilitresPerSecond(1))
cubicFeetPerHour should be(CubicFeetPerHour(1))
gallonPerDay should be(GallonsPerDay(1))
gallonPerHour should be(GallonsPerHour(1))
Expand All @@ -84,6 +180,22 @@ class VolumeFlowSpec extends AnyFlatSpec with Matchers with CustomMatchers {

val d = 10.22d
d.cubicMetersPerSecond should be(CubicMetersPerSecond(d))
d.litresPerDay should be(LitresPerDay(d))
d.litresPerHour should be(LitresPerHour(d))
d.litresPerMinute should be(LitresPerMinute(d))
d.litresPerSecond should be(LitresPerSecond(d))
d.nanolitresPerDay should be(NanolitresPerDay(d))
d.nanolitresPerHour should be(NanolitresPerHour(d))
d.nanolitresPerMinute should be(NanolitresPerMinute(d))
d.nanolitresPerSecond should be(NanolitresPerSecond(d))
d.microlitresPerDay should be(MicrolitresPerDay(d))
d.microlitresPerHour should be(MicrolitresPerHour(d))
d.microlitresPerMinute should be(MicrolitresPerMinute(d))
d.microlitresPerSecond should be(MicrolitresPerSecond(d))
d.millilitresPerDay should be(MillilitresPerDay(d))
d.millilitresPerHour should be(MillilitresPerHour(d))
d.millilitresPerMinute should be(MillilitresPerMinute(d))
d.millilitresPerSecond should be(MillilitresPerSecond(d))
d.cubicFeetPerHour should be(CubicFeetPerHour(d))
d.gallonsPerDay should be(GallonsPerDay(d))
d.gallonsPerHour should be(GallonsPerHour(d))
Expand Down

0 comments on commit 38d6501

Please sign in to comment.