Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Solar units of measure #209

Merged
merged 2 commits into from
Mar 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion shared/src/main/scala/squants/energy/Power.scala
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ final class Power private (val value: Double, val unit: PowerUnit)
def toGigawatts = to(Gigawatts)
def toBtusPerHour = to(BtusPerHour)
def toErgsPerSecond = to(ErgsPerSecond)
def toSolarLuminosities = to(SolarLuminosities)
}

/**
Expand All @@ -65,7 +66,7 @@ object Power extends Dimension[Power] {
def name = "Power"
def primaryUnit = Watts
def siUnit = Watts
def units = Set(Watts, Milliwatts, Kilowatts, Megawatts, Gigawatts, BtusPerHour, ErgsPerSecond)
def units = Set(Watts, Milliwatts, Kilowatts, Megawatts, Gigawatts, BtusPerHour, ErgsPerSecond, SolarLuminosities)
}

trait PowerUnit extends UnitOfMeasure[Power] with UnitConverter {
Expand Down Expand Up @@ -106,6 +107,11 @@ object ErgsPerSecond extends PowerUnit {
val symbol = Ergs.symbol + "/" + Seconds.symbol
}

object SolarLuminosities extends PowerUnit {
val conversionFactor = 3.828e26
val symbol = "L☉"
}

object PowerConversions {
lazy val milliwatt = Milliwatts(1)
lazy val mW = milliwatt
Expand All @@ -117,6 +123,7 @@ object PowerConversions {
lazy val MW = megawatt
lazy val gigawatt = Gigawatts(1)
lazy val GW = gigawatt
lazy val solarLuminosity = SolarLuminosities(1)

implicit class PowerConversions[A](n: A)(implicit num: Numeric[A]) {
def mW = Milliwatts(n)
Expand All @@ -131,6 +138,7 @@ object PowerConversions {
def gigawatts = Gigawatts(n)
def BTUph = BtusPerHour(n)
def ergsPerSecond = ErgsPerSecond(n)
def solarLuminosities = SolarLuminosities(n)
}

implicit class PowerStringConversions(s: String) {
Expand Down
10 changes: 9 additions & 1 deletion shared/src/main/scala/squants/mass/Mass.scala
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ final class Mass private (val value: Double, val unit: MassUnit)
def toTroyPounds = to(TroyPounds)
def toTolas = to(Tolas)
def toCarats = to(Carats)
def toSolarMasses = to(SolarMasses)
}

/**
Expand All @@ -67,7 +68,7 @@ object Mass extends Dimension[Mass] with BaseDimension {
def primaryUnit = Grams
def siUnit = Kilograms
def units = Set(Micrograms, Milligrams, Grams, Kilograms, Tonnes, Ounces, Pounds, Kilopounds, Megapounds, Stone,
TroyGrains, Pennyweights, TroyOunces, TroyPounds, Tolas, Carats)
TroyGrains, Pennyweights, TroyOunces, TroyPounds, Tolas, Carats, SolarMasses)
def dimensionSymbol = "M"
}

Expand Down Expand Up @@ -157,6 +158,11 @@ object Carats extends MassUnit {
val symbol = "ct"
}

object SolarMasses extends MassUnit {
val conversionFactor = 1.98855e33
val symbol = "M☉"
}

/**
* Implicit conversions for [[squants.mass.Mass]]
*
Expand All @@ -179,6 +185,7 @@ object MassConversions {
lazy val troyPound = TroyPounds(1)
lazy val tola = Tolas(1)
lazy val carat = Carats(1)
lazy val solarMass = SolarMasses(1)

implicit class MassConversions[A](n: A)(implicit num: Numeric[A]) {
def mcg = Micrograms(n)
Expand All @@ -202,6 +209,7 @@ object MassConversions {
def tolas = Tolas(n)
def ct = Carats(n)
def carats = Carats(n)
def solarMasses = SolarMasses(n)
}

implicit class MassStringConversions(val s: String) {
Expand Down
18 changes: 17 additions & 1 deletion shared/src/main/scala/squants/space/Length.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ final class Length private (val value: Double, val unit: LengthUnit)
def toAstronomicalUnits = to(AstronomicalUnits)
def toLightYears = to(LightYears)
def toParsecs = to(Parsecs)
def toSolarRadii = to(SolarRadii)
def toNominalSolarRadii = to(NominalSolarRadii)
}

/**
Expand All @@ -95,7 +97,7 @@ object Length extends Dimension[Length] with BaseDimension {
def units = Set(Angstroms, Nanometers, Microns, Millimeters, Centimeters,
Decimeters, Meters, Decameters, Hectometers, Kilometers,
Inches, Feet, Yards, UsMiles, InternationalMiles, NauticalMiles,
AstronomicalUnits, LightYears, Parsecs)
AstronomicalUnits, LightYears, Parsecs, SolarRadii, NominalSolarRadii)
def dimensionSymbol = "L"
}

Expand Down Expand Up @@ -202,6 +204,16 @@ object Parsecs extends LengthUnit {
val symbol = "pc"
}

object SolarRadii extends LengthUnit {
val conversionFactor = 6.957e8
val symbol = "R☉"
}

object NominalSolarRadii extends LengthUnit {
val conversionFactor = 6.957e8
val symbol = "RN☉"
}

object LengthConversions {
lazy val angstrom = Angstroms(1)
lazy val nanometer = Nanometers(1)
Expand Down Expand Up @@ -231,6 +243,8 @@ object LengthConversions {
lazy val astronomicalUnit = AstronomicalUnits(1)
lazy val lightYear = LightYears(1)
lazy val parsec = Parsecs(1)
lazy val solarRadius = SolarRadii(1)
lazy val nominalSolarRadius = NominalSolarRadii(1)

implicit class LengthConversions[A](n: A)(implicit num: Numeric[A]) {
def Å = Angstroms(n)
Expand Down Expand Up @@ -268,6 +282,8 @@ object LengthConversions {
def lightYears = LightYears(n)
def parsecs = Parsecs(n)
def pc = Parsecs(n)
def solarRadii = SolarRadii(n)
def nominalSolarRadii = NominalSolarRadii(n)
}

implicit class LengthStringConversions(s: String) {
Expand Down
7 changes: 7 additions & 0 deletions shared/src/test/scala/squants/energy/PowerSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class PowerSpec extends FlatSpec with Matchers {
Gigawatts(1).toGigawatts should be(1)
BtusPerHour(1).toBtusPerHour should be(1)
ErgsPerSecond(1).toErgsPerSecond should be(1)
SolarLuminosities(1).toSolarLuminosities should be(1)
}

it should "create values from properly formatted Strings" in {
Expand All @@ -39,6 +40,7 @@ class PowerSpec extends FlatSpec with Matchers {
Power("10.22 GW").get should be(Gigawatts(10.22))
Power("10.22 Btu/hr").get should be(BtusPerHour(10.22))
Power("10.22 erg/s").get should be(ErgsPerSecond(10.22))
Power("10.22 L☉").get should be(SolarLuminosities(10.22))
Power("10.22 zz").failed.get should be(QuantityParseException("Unable to parse Power", "10.22 zz"))
Power("ZZ W").failed.get should be(QuantityParseException("Unable to parse Power", "ZZ W"))
}
Expand All @@ -53,6 +55,7 @@ class PowerSpec extends FlatSpec with Matchers {
x.toGigawatts should be(1 / MetricSystem.Giga)
x.toBtusPerHour should be(1 / EnergyConversions.btuMultiplier)
x.toErgsPerSecond should be(1 / 1e-7)
x.toSolarLuminosities should be(1 / 3.828e26)
}

it should "return properly formatted strings for all supported Units of Measure" in {
Expand All @@ -63,6 +66,7 @@ class PowerSpec extends FlatSpec with Matchers {
Gigawatts(1).toString(Gigawatts) should be("1.0 GW")
BtusPerHour(1).toString(BtusPerHour) should be("1.0 Btu/hr")
ErgsPerSecond(1).toString(ErgsPerSecond) should be("1.0 erg/s")
SolarLuminosities(1).toString(SolarLuminosities) should be("1.0 L☉")
}

it should "return Energy when multiplied by Time" in {
Expand All @@ -84,6 +88,7 @@ class PowerSpec extends FlatSpec with Matchers {
MW should be(Megawatts(1))
gigawatt should be(Gigawatts(1))
GW should be(Gigawatts(1))
solarLuminosity should be(SolarLuminosities(1))
}

it should "provide implicit conversion from Double" in {
Expand All @@ -102,6 +107,7 @@ class PowerSpec extends FlatSpec with Matchers {
d.gigawatts should be(Gigawatts(d))
d.BTUph should be(BtusPerHour(d))
d.ergsPerSecond should be(ErgsPerSecond(d))
d.solarLuminosities should be(SolarLuminosities(d))
}

it should "provide implicit conversions from String" in {
Expand All @@ -114,6 +120,7 @@ class PowerSpec extends FlatSpec with Matchers {
"10.22 GW".toPower.get should be(Gigawatts(10.22))
"10.22 Btu/hr".toPower.get should be(BtusPerHour(10.22))
"10.22 erg/s".toPower.get should be(ErgsPerSecond(10.22))
"10.22 L☉".toPower.get should be(SolarLuminosities(10.22))
"10.22 zz".toPower.failed.get should be(QuantityParseException("Unable to parse Power", "10.22 zz"))
"ZZ W".toPower.failed.get should be(QuantityParseException("Unable to parse Power", "ZZ W"))
}
Expand Down
8 changes: 8 additions & 0 deletions shared/src/test/scala/squants/mass/MassSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class MassSpec extends FlatSpec with Matchers {
TroyPounds(10.22).toTroyPounds should be(10.22)
Tolas(10.22).toTolas should be(10.22)
Carats(10.22).toCarats should be(10.22)
SolarMasses(10.22).toSolarMasses should be(10.22)
}

it should "create values from properly formatted Strings" in {
Expand All @@ -59,6 +60,7 @@ class MassSpec extends FlatSpec with Matchers {
Mass("10.22 lb t").get should be(TroyPounds(10.22))
Mass("10.22 tola").get should be(Tolas(10.22))
Mass("10.22 ct").get should be(Carats(10.22))
Mass("10.22 M☉").get should be(SolarMasses(10.22))
Mass("10.45 zz").failed.get should be(QuantityParseException("Unable to parse Mass", "10.45 zz"))
Mass("zz g").failed.get should be(QuantityParseException("Unable to parse Mass", "zz g"))
}
Expand All @@ -77,6 +79,7 @@ class MassSpec extends FlatSpec with Matchers {
x.toTroyOunces should be (1 / TroyOunces.conversionFactor)
x.toTroyPounds should be (1 / TroyPounds.conversionFactor)
x.toCarats should be (1 / Carats.conversionFactor)
x.toSolarMasses should be (1 / SolarMasses.conversionFactor)

Grams(1000) should be(Kilograms(1))
Kilograms(0.45359237) should be(Pounds(1))
Expand All @@ -90,6 +93,7 @@ class MassSpec extends FlatSpec with Matchers {
Carats(1) should be(Milligrams(200))
TroyOunces(1).toGrams should be(31.1034768)
Pennyweights(1).toGrams should be(1.55517384 +- 0.000000001)
SolarMasses(1).toKilograms should be(1.98855e30 +- 0.00025)
}

it should "return properly formatted strings for all supported Units of Measure" in {
Expand All @@ -108,6 +112,7 @@ class MassSpec extends FlatSpec with Matchers {
TroyPounds(1).toString(TroyPounds) should be("1.0 lb t")
Tolas(1).toString(Tolas) should be("1.0 tola")
Carats(1).toString(Carats) should be("1.0 ct")
SolarMasses(1).toString(SolarMasses) should be("1.0 M☉")
}

it should "return Momentum when multiplied by Velocity" in {
Expand Down Expand Up @@ -162,6 +167,7 @@ class MassSpec extends FlatSpec with Matchers {
troyPound should be(TroyPounds(1))
tola should be(Tolas(1))
carat should be(Carats(1))
solarMass should be(SolarMasses(1))
}

it should "provide implicit conversion from Double" in {
Expand All @@ -188,6 +194,7 @@ class MassSpec extends FlatSpec with Matchers {
d.tolas should be(Tolas(d))
d.ct should be(Carats(d))
d.carats should be(Carats(d))
d.solarMasses should be(SolarMasses(d))
}

it should "provide implicit conversions from arbitrary Numeric types" in {
Expand Down Expand Up @@ -217,6 +224,7 @@ class MassSpec extends FlatSpec with Matchers {
"10.45 lb t".toMass.get should be(TroyPounds(10.45))
"10.45 tola".toMass.get should be(Tolas(10.45))
"10.45 ct".toMass.get should be(Carats(10.45))
"10.45 M☉".toMass.get should be(SolarMasses(10.45))
"10.45 zz".toMass.failed.get should be(QuantityParseException("Unable to parse Mass", "10.45 zz"))
"zz oz".toMass.failed.get should be(QuantityParseException("Unable to parse Mass", "zz oz"))
}
Expand Down
14 changes: 14 additions & 0 deletions shared/src/test/scala/squants/space/LengthSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ class LengthSpec extends FlatSpec with Matchers {
AstronomicalUnits(1).toAstronomicalUnits should be(1)
LightYears(1).toLightYears should be(1)
Parsecs(1).toParsecs should be(1)
SolarRadii(1).toSolarRadii should be(1)
NominalSolarRadii(1).toNominalSolarRadii should be(1)
}

it should "create values from properly formatted Strings" in {
Expand All @@ -68,6 +70,8 @@ class LengthSpec extends FlatSpec with Matchers {
Length("10.33 au").get should be(AstronomicalUnits(10.33))
Length("10.33 ly").get should be(LightYears(10.33))
Length("10.33 pc").get should be(Parsecs(10.33))
Length("10.33 R☉").get should be(SolarRadii(10.33))
Length("10.33 RN☉").get should be(NominalSolarRadii(10.33))
Length("10.33 zz").failed.get should be(QuantityParseException("Unable to parse Length", "10.33 zz"))
Length("ZZ m").failed.get should be(QuantityParseException("Unable to parse Length", "ZZ m"))
}
Expand Down Expand Up @@ -95,6 +99,8 @@ class LengthSpec extends FlatSpec with Matchers {
x.toAstronomicalUnits should be(1 / 149597870700d)
x.toLightYears should be(1 / 9460730472580800d)
x.toParsecs should be(1 / 3.08567758149137e16)
x.toSolarRadii should be(1 / 6.957e8)
x.toNominalSolarRadii should be(1 / 6.957e8)
}

it should "return properly formatted strings for all supported Units of Measure" in {
Expand All @@ -118,6 +124,8 @@ class LengthSpec extends FlatSpec with Matchers {
AstronomicalUnits(1).toString(AstronomicalUnits) should be("1.0 au")
LightYears(1).toString(LightYears) should be("1.0 ly")
Parsecs(1).toString(Parsecs) should be("1.0 pc")
SolarRadii(1).toString(SolarRadii) should be("1.0 R☉")
NominalSolarRadii(1).toString(NominalSolarRadii) should be("1.0 RN☉")
}

it should "return Area when multiplied by Length" in {
Expand Down Expand Up @@ -189,6 +197,8 @@ class LengthSpec extends FlatSpec with Matchers {
astronomicalUnit should be(AstronomicalUnits(1))
lightYear should be(LightYears(1))
parsec should be(Parsecs(1))
solarRadius should be(SolarRadii(1))
nominalSolarRadius should be(NominalSolarRadii(1))
}

it should "provide implicit conversion from Double" in {
Expand Down Expand Up @@ -228,6 +238,8 @@ class LengthSpec extends FlatSpec with Matchers {
d.lightYears should be(LightYears(d))
d.pc should be(Parsecs(d))
d.parsecs should be(Parsecs(d))
d.solarRadii should be(SolarRadii(d))
d.nominalSolarRadii should be(NominalSolarRadii(d))
}

it should "provide implicit conversion from String" in {
Expand All @@ -252,6 +264,8 @@ class LengthSpec extends FlatSpec with Matchers {
"10.33 au".toLength.get should be(AstronomicalUnits(10.33))
"10.33 ly".toLength.get should be(LightYears(10.33))
"10.33 pc".toLength.get should be(Parsecs(10.33))
"10.33 R☉".toLength.get should be(SolarRadii(10.33))
"10.33 RN☉".toLength.get should be(NominalSolarRadii(10.33))
"10.33 zz".toLength.failed.get should be(QuantityParseException("Unable to parse Length", "10.33 zz"))
"ZZ m".toLength.failed.get should be(QuantityParseException("Unable to parse Length", "ZZ m"))
}
Expand Down