001/*
002 * Units of Measurement Reference Implementation
003 * Copyright (c) 2005-2024, Jean-Marie Dautelle, Werner Keil, Otavio Santana.
004 *
005 * All rights reserved.
006 *
007 * Redistribution and use in source and binary forms, with or without modification,
008 * are permitted provided that the following conditions are met:
009 *
010 * 1. Redistributions of source code must retain the above copyright notice,
011 *    this list of conditions and the following disclaimer.
012 *
013 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
014 *    and the following disclaimer in the documentation and/or other materials provided with the distribution.
015 *
016 * 3. Neither the name of JSR-385, Indriya nor the names of their contributors may be used to endorse or promote products
017 *    derived from this software without specific prior written permission.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
021 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
023 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
026 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030package tech.units.indriya.unit;
031
032import static tech.units.indriya.AbstractUnit.ONE;
033
034import java.util.Set;
035
036import javax.measure.Quantity;
037import javax.measure.Unit;
038import javax.measure.quantity.Acceleration;
039import javax.measure.quantity.AmountOfSubstance;
040import javax.measure.quantity.Angle;
041import javax.measure.quantity.Area;
042import javax.measure.quantity.CatalyticActivity;
043import javax.measure.quantity.Dimensionless;
044import javax.measure.quantity.ElectricCapacitance;
045import javax.measure.quantity.ElectricCharge;
046import javax.measure.quantity.ElectricConductance;
047import javax.measure.quantity.ElectricCurrent;
048import javax.measure.quantity.ElectricInductance;
049import javax.measure.quantity.ElectricPotential;
050import javax.measure.quantity.ElectricResistance;
051import javax.measure.quantity.Energy;
052import javax.measure.quantity.Force;
053import javax.measure.quantity.Frequency;
054import javax.measure.quantity.Illuminance;
055import javax.measure.quantity.Length;
056import javax.measure.quantity.LuminousFlux;
057import javax.measure.quantity.LuminousIntensity;
058import javax.measure.quantity.MagneticFlux;
059import javax.measure.quantity.MagneticFluxDensity;
060import javax.measure.quantity.Mass;
061import javax.measure.quantity.Power;
062import javax.measure.quantity.Pressure;
063import javax.measure.quantity.RadiationDoseAbsorbed;
064import javax.measure.quantity.RadiationDoseEffective;
065import javax.measure.quantity.Radioactivity;
066import javax.measure.quantity.SolidAngle;
067import javax.measure.quantity.Speed;
068import javax.measure.quantity.Temperature;
069import javax.measure.quantity.Time;
070import javax.measure.quantity.Volume;
071import tech.units.indriya.AbstractSystemOfUnits;
072import tech.units.indriya.AbstractUnit;
073import tech.units.indriya.function.AddConverter;
074import tech.units.indriya.function.MultiplyConverter;
075import tech.units.indriya.function.RationalNumber;
076
077/**
078 * This class defines common units.<br>
079 * It is a representative subset of the SI system.
080 *
081 * @author <a href="mailto:werner@units.tech">Werner Keil</a>
082 * @author <a href="mailto:thodoris.bais@gmail.com">Teo Bais</a>
083 * @version 3.0 January 17, 2024
084 * @since 1.0
085 * @see <a href="https://usma.org/detailed-list-of-metric-system-units-symbols-and-prefixes">USMA: Detailed list of metric system units, symbols, and prefixes</a>
086 * @see <a href=
087 *      "http://en.wikipedia.org/wiki/International_System_of_Units">Wikipedia:
088 *      International System of Units</a>
089 */
090public class Units extends AbstractSystemOfUnits {
091
092        /** Constructor may only be called by subclasses */
093        protected Units() {
094        }
095
096        /** Singleton instance */
097        private static final Units INSTANCE = new Units();
098
099        /*
100         * (non-Javadoc)
101         * 
102         * @see SystemOfUnits#getName()
103         */
104        @Override
105        public String getName() {
106                return Units.class.getSimpleName();
107        }
108
109        // //////////////
110        // BASE UNITS //
111        // //////////////
112
113        /**
114         * The ampere, symbol A, is the SI unit of electric current. It is defined by
115         * taking the fixed numerical value of the elementary charge e to be 1.602 176
116         * 634 × 10⁻¹⁹ when expressed in the unit C, which is equal to A s, where the
117         * second is defined in terms of ∆νCs.
118         *
119         * This definition implies the exact relation e = 1.602 176 634 × 10⁻¹⁹ A s.
120         * Inverting this relation gives an exact expression for the unit ampere in
121         * terms of the defining constants e and ∆νCs:
122         *
123         * 1 A = (e / 1.602 176 634 × 10⁻¹⁹) s⁻¹
124         *
125     * <dl>
126     * <dt><span class="strong">Implementation Note:</span></dt><dd>SI Base Unit</dd>
127     * </dl>
128         */
129        public static final Unit<ElectricCurrent> AMPERE = addUnit(
130                        new BaseUnit<ElectricCurrent>("A", "Ampere", UnitDimension.ELECTRIC_CURRENT), ElectricCurrent.class);
131
132        /**
133         * The candela, symbol cd, is the SI unit of luminous intensity in a given
134         * direction. It is defined by taking the fixed numerical value of the luminous
135         * efficacy of monochromatic radiation of frequency 540 × 10¹² Hz, Kcd, to be
136         * 683 when expressed in the unit lm W−1, which is equal to cd sr W⁻¹, or cd sr
137         * kg⁻¹ m⁻² s³, where the kilogram, metre and second are defined in terms of h,
138         * c and ∆νCs.
139         *
140         * This definition implies the exact relation Kcd = 683 cd sr kg⁻¹ m⁻² s³ for
141         * monochromatic radiation of frequency ν = 540 × 10¹² Hz. Inverting this
142         * relation gives an exact expression for the candela in terms of the defining
143         * constants Kcd, h and ∆νCs:
144         *
145         * 1 cd = (Kcd / 683) kg m² s⁻³ sr⁻¹
146         *
147     * <dl>
148     * <dt><span class="strong">Implementation Note:</span></dt><dd>SI Base Unit</dd>
149     * </dl>
150     * @see <a href="http://en.wikipedia.org/wiki/Candela"> Wikipedia: Candela</a>
151         */
152        public static final Unit<LuminousIntensity> CANDELA = addUnit(
153                        new BaseUnit<LuminousIntensity>("cd", "Candela", UnitDimension.LUMINOUS_INTENSITY),
154                        LuminousIntensity.class);
155
156        /**
157         * The kelvin, symbol K, is the SI unit of thermodynamic temperature. It is
158         * defined by taking the fixed numerical value of the Boltzmann constant k to be
159         * 1.380 649 × 10−²³ when expressed in the unit J K⁻¹, which is equal to kg m²
160         * s⁻² K⁻¹, where the kilogram, metre and second are defined in terms of h, c
161         * and ∆νCs.
162         *
163         * This definition implies the exact relation k = 1.380 649 × 10⁻²³ kg m² s⁻²
164         * K⁻¹. Inverting this relation gives an exact expression for the kelvin in
165         * terms of the defining constants k, h and ∆νCs:
166         *
167         * 1 K = (1.380 649 / k) × 10⁻²³ kg m² s⁻²
168         *
169         * <dl>
170     * <dt><span class="strong">Implementation Note:</span></dt><dd>SI Base Unit</dd>
171     * </dl>
172         * @see #JOULE
173         */
174        public static final Unit<Temperature> KELVIN = addUnit(
175                        new BaseUnit<Temperature>("K", "Kelvin", UnitDimension.TEMPERATURE), Temperature.class);
176
177        /**
178         * The kilogram, symbol kg, is the SI unit of mass. It is defined by taking the
179         * fixed numerical value of the Planck constant h to be 6.626 070 15 × 10⁻³⁴
180         * when expressed in the unit J s, which is equal to kg m² s−1, where the metre
181         * and the second are defined in terms of c and ∆νCs.
182         *
183         * This definition implies the exact relation h = 6.626 070 15 × 10−34 kg m²
184         * s⁻¹. Inverting this relation gives an exact expression for the kilogram in
185         * terms of the three defining constants h, ∆νCs and c:
186         *
187         * 1 kg = (h / 6.626 070 15 × 10⁻³⁴) m⁻² s
188         *
189         * <dl>
190     * <dt><span class="strong">Implementation Note:</span></dt><dd>SI Base Unit</dd>
191     * </dl>
192         * @see <a href="https://en.wikipedia.org/wiki/Kilogram">Wikipedia: Kilogram</a>
193         * @see #GRAM
194         * @see #METRE
195         * @see #SECOND
196         */
197        public static final Unit<Mass> KILOGRAM = addUnit(new BaseUnit<Mass>("kg", "Kilogram", UnitDimension.MASS), Mass.class);
198
199        /**
200         * The metre, symbol m, is the SI unit of length. It is defined by taking the
201         * fixed numerical value of the speed of light in vacuum c to be 299 792 458
202         * when expressed in the unit m s⁻¹, where the second is defined in terms of the
203         * caesium frequency ∆νCs.
204         *
205         * This definition implies the exact relation c = 299 792 458 m s⁻¹. Inverting
206         * this relation gives an exact expression for the metre in terms of the
207         * defining constants c and ∆νCs:
208         *
209         * 1 m = (c / 299 792 458)s = 9 192 631 770 c / 299 792 458 ∆νCs ≈ 30.663 319 c
210         * / ∆νCs
211         *
212     * <dl>
213     * <dt><span class="strong">Implementation Note:</span></dt><dd>SI Base Unit</dd>
214     * </dl>
215         */
216        public static final Unit<Length> METRE = addUnit(new BaseUnit<>("m", "Metre", UnitDimension.LENGTH), Length.class);
217
218        /**
219         * The mole, symbol mol, is the SI unit of amount of substance. One mole
220         * contains exactly 6.022 140 76 × 10²³ elementary entities. This number is the
221         * fixed numerical value of the Avogadro constant, NA, when expressed in the
222         * unit mol⁻¹ and is called the Avogadro number.
223         *
224         * The amount of substance, symbol n, of a system is a measure of the number of
225         * specified elementary entities. An elementary entity may be an atom, a
226         * molecule, an ion, an electron, any other particle or specified group of
227         * particles. This definition implies the exact relation Nₐ = 6.022 140 76 ×
228         * 10²³ mol⁻¹.
229         *
230         * Inverting this relation gives an exact expression for the mole in terms of
231         * the defining constant NA:
232         *
233         * 1 mol = 6.02214076 × 10²³ / Nₐ
234         *
235     * <dl>
236     * <dt><span class="strong">Implementation Note:</span></dt><dd>SI Base Unit</dd>
237     * </dl>
238         */
239        public static final Unit<AmountOfSubstance> MOLE = addUnit(new BaseUnit<>("mol", "Mole", UnitDimension.AMOUNT_OF_SUBSTANCE),
240                        AmountOfSubstance.class);
241
242        /**
243         * The second, symbol s, is the SI unit of time. It is defined by taking the
244         * fixed numerical value of the caesium frequency ∆νCs, the unperturbed
245         * ground-state hyperfine transition frequency of the caesium 133 atom, to be 9
246         * 192 631 770 when expressed in the unit Hz, which is equal to s⁻¹.
247         *
248         * This definition implies the exact relation ∆νCs = 9 192 631 770 Hz. Inverting
249         * this relation gives an expression for the unit second in terms of the
250         * defining constant ∆νCs:
251         *
252         * 1 Hz = ∆νCs / 9 192 631 770 or 1 s = 9 192 631 770 / ∆νCs
253         *
254     * <dl>
255     * <dt><span class="strong">Implementation Note:</span></dt><dd>SI Base Unit</dd>
256     * </dl>
257         */
258        public static final Unit<Time> SECOND = addUnit(new BaseUnit<>("s", "Second", UnitDimension.TIME), Time.class);
259
260        // //////////////////////////////
261        // SI DERIVED ALTERNATE UNITS //
262        // SI BROCHURE - TABLE 4      //
263        // //////////////////////////////
264
265        /**
266         * The SI derived unit for mass quantities (standard name <code>g</code>). The
267         * base unit for mass quantity is {@link #KILOGRAM}.
268         */
269        public static final Unit<Mass> GRAM = addUnit(INSTANCE.units, KILOGRAM.divide(1000), "Gram");
270
271        /**
272         * The SI unit for plane angle quantities (standard name <code>rad</code>). One
273         * radian is the angle between two radii of a circle such that the length of the
274         * arc between them is equal to the radius.
275         * 
276         * <dl>
277     * <dt><span class="strong">Implementation Note:</span></dt><dd>SI Brochure - Table 4</dd>
278     * </dl>
279         */
280        public static final Unit<Angle> RADIAN = addUnit(AlternateUnit.of(ONE, "rad", "Radian"), Angle.class);
281
282        /**
283         * The SI unit for solid angle quantities (standard name <code>sr</code>). One
284         * steradian is the solid angle subtended at the center of a sphere by an area
285         * on the surface of the sphere that is equal to the radius squared. The total
286         * solid angle of a sphere is 4*Pi steradians.
287         * 
288         * <dl>
289     * <dt><span class="strong">Implementation Note:</span></dt><dd>SI Brochure - Table 4</dd>
290     * </dl>
291         */
292        public static final Unit<SolidAngle> STERADIAN = addUnit(new AlternateUnit<>(ONE, "sr", "Steradian"), SolidAngle.class);
293
294        /**
295         * The SI unit for frequency (standard name <code>Hz</code>). A unit of
296         * frequency equal to one cycle per second. After Heinrich Rudolf Hertz
297         * (1857-1894), German physicist who was the first to produce radio waves
298         * artificially.
299         *
300         * <dl>
301     * <dt><span class="strong">Implementation Note:</span></dt><dd>SI Brochure - Table 4</dd>
302     * </dl>
303         */
304        public static final Unit<Frequency> HERTZ = addUnit(new AlternateUnit<Frequency>(ONE.divide(SECOND), "Hz", "Hertz"),
305                        Frequency.class);
306
307        /**
308         * The SI unit for force (standard name <code>N</code>). One newton is the force
309         * required to give a mass of 1 kilogram an Force of 1 metre per second per
310         * second. It is named after the English mathematician and physicist Sir Isaac
311         * Newton (1642-1727).
312         * 
313         * <dl>
314     * <dt><span class="strong">Implementation Note:</span></dt><dd>SI Brochure - Table 4</dd>
315     * </dl>
316         */
317        public static final Unit<Force> NEWTON = addUnit(
318                        new AlternateUnit<Force>(METRE.multiply(KILOGRAM).divide(SECOND.pow(2)), "N", "Newton"), Force.class);
319
320        /**
321         * The SI unit for pressure, stress (standard name <code>Pa</code>). One pascal
322         * is equal to one newton per square meter. It is named after the French
323         * philosopher and mathematician Blaise Pascal (1623-1662).
324         * 
325         * <dl>
326     * <dt><span class="strong">Implementation Note:</span></dt><dd>SI Brochure - Table 4</dd>
327     * </dl>
328         */
329        @SuppressWarnings({ "unchecked", "rawtypes" })
330        public static final Unit<Pressure> PASCAL = addUnit(new AlternateUnit(NEWTON.divide(METRE.pow(2)), "Pa", "Pascal"),
331                        Pressure.class);
332
333        /**
334         * The SI unit for energy, work, quantity of heat (<code>J</code>). One joule is
335         * the amount of work done when an applied force of 1 newton moves through a
336         * distance of 1 metre in the direction of the force. It is named after the
337         * English physicist James Prescott Joule (1818-1889).
338         * 
339         * <dl>
340     * <dt><span class="strong">Implementation Note:</span></dt><dd>SI Brochure - Table 4</dd>
341     * </dl>
342         */
343        public static final Unit<Energy> JOULE = addUnit(new AlternateUnit<Energy>(NEWTON.multiply(METRE), "J", "Joule"),
344                        Energy.class);
345
346        /**
347         * The SI unit for power, radiant, flux (standard name <code>W</code>). One watt
348         * is equal to one joule per second. It is named after the British scientist
349         * James Watt (1736-1819).
350         * 
351         * <dl>
352     * <dt><span class="strong">Implementation Note:</span></dt><dd>SI Brochure - Table 4</dd>
353     * </dl> 
354         */
355        public static final Unit<Power> WATT = addUnit(new AlternateUnit<Power>(JOULE.divide(SECOND), "W", "Watt"), Power.class);
356
357        /**
358         * The SI unit for electric charge, quantity of electricity (standard name
359         * <code>C</code>). One Coulomb is equal to the quantity of charge transferred
360         * in one second by a steady current of one ampere. It is named after the French
361         * physicist Charles Augustin de Coulomb (1736-1806).
362         * 
363         * <dl>
364     * <dt><span class="strong">Implementation Note:</span></dt><dd>SI Brochure - Table 4</dd>
365     * </dl>
366         */
367        public static final Unit<ElectricCharge> COULOMB = addUnit(
368                        new AlternateUnit<ElectricCharge>(SECOND.multiply(AMPERE), "C", "Coulomb"), ElectricCharge.class);
369
370        /**
371         * The SI unit for electric potential difference, electromotive force (standard
372         * name <code>V</code>). One Volt is equal to the difference of electric
373         * potential between two points on a conducting wire carrying a constant current
374         * of one ampere when the power dissipated between the points is one watt. It is
375         * named after the Italian physicist Count Alessandro Volta (1745-1827).
376         *       
377         * <dl>
378     * <dt><span class="strong">Implementation Note:</span></dt><dd>SI Brochure - Table 4</dd>
379     * </dl>
380         */
381        public static final Unit<ElectricPotential> VOLT = addUnit(
382                        new AlternateUnit<ElectricPotential>(WATT.divide(AMPERE), "V", "Volt"), ElectricPotential.class);
383
384        /**
385         * The SI unit for capacitance (standard name <code>F</code>). One Farad is
386         * equal to the capacitance of a capacitor having an equal and opposite charge
387         * of 1 coulomb on each plate and a potential difference of 1 volt between the
388         * plates. It is named after the British physicist and chemist Michael Faraday
389         * (1791-1867).
390         * 
391         * <dl>
392     * <dt><span class="strong">Implementation Note:</span></dt><dd>SI Brochure - Table 4</dd>
393     * </dl>
394         */
395        public static final Unit<ElectricCapacitance> FARAD = addUnit(
396                        new AlternateUnit<ElectricCapacitance>(COULOMB.divide(VOLT), "F", "Farad"), ElectricCapacitance.class);
397
398        /**
399         * The SI unit for electric resistance (standard name <code>Ohm</code>). One Ohm
400         * is equal to the resistance of a conductor in which a current of one ampere is
401         * produced by a potential of one volt across its terminals. It is named after
402         * the German physicist Georg Simon Ohm (1789-1854).
403         * 
404         * <dl>
405     * <dt><span class="strong">Implementation Note:</span></dt><dd>SI Brochure - Table 4</dd>
406     * </dl>
407         */
408        public static final Unit<ElectricResistance> OHM = addUnit(
409                        new AlternateUnit<ElectricResistance>(VOLT.divide(AMPERE), "Ω", "Ohm"), ElectricResistance.class);
410
411        /**
412         * The SI unit for electric conductance (standard name <code>S</code>). One
413         * Siemens is equal to one ampere per volt. It is named after the German
414         * engineer Ernst Werner von Siemens (1816-1892).
415         */
416        public static final Unit<ElectricConductance> SIEMENS = addUnit(
417                        new AlternateUnit<ElectricConductance>(AMPERE.divide(VOLT), "S", "Siemens"), ElectricConductance.class);
418
419        /**
420         * The SI unit for magnetic flux (standard name <code>Wb</code>). One Weber is
421         * equal to the magnetic flux that in linking a circuit of one turn produces in
422         * it an electromotive force of one volt as it is uniformly reduced to zero
423         * within one second. It is named after the German physicist Wilhelm Eduard
424         * Weber (1804-1891).
425         */
426        public static final Unit<MagneticFlux> WEBER = addUnit(new AlternateUnit<MagneticFlux>(VOLT.multiply(SECOND), "Wb", "Weber"),
427                        MagneticFlux.class);
428
429        /**
430         * The alternate unit for magnetic flux density (standard name <code>T</code>).
431         * One Tesla is equal equal to one weber per square metre. It is named after the
432         * Serbian-born American electrical engineer and physicist Nikola Tesla
433         * (1856-1943).
434         */
435        public static final Unit<MagneticFluxDensity> TESLA = addUnit(
436                        new AlternateUnit<MagneticFluxDensity>(WEBER.divide(METRE.pow(2)), "T", "Tesla"), MagneticFluxDensity.class);
437
438        /**
439         * The alternate unit for inductance (standard name <code>H</code>). One Henry
440         * is equal to the inductance for which an induced electromotive force of one
441         * volt is produced when the current is varied at the rate of one ampere per
442         * second. It is named after the American physicist Joseph Henry (1791-1878).
443         */
444        public static final Unit<ElectricInductance> HENRY = addUnit(
445                        new AlternateUnit<ElectricInductance>(WEBER.divide(AMPERE), "H", "Henry"), ElectricInductance.class);
446
447        /**
448         * The SI unit for Celsius temperature (standard name <code>°C</code>). This is
449         * a unit of temperature such as the freezing point of water (at one atmosphere
450         * of pressure) is 0 °C, while the boiling point is 100 °C.
451         */
452        @SuppressWarnings({ "rawtypes", "unchecked" })
453        public static final Unit<Temperature> CELSIUS = AbstractSystemOfUnits.Helper.addUnit(INSTANCE.units, 
454                        new TransformedUnit(KELVIN, new AddConverter(273.15)), "Celsius", "\u2103");
455        // Not mapping to Temperature since temperature is mapped to Kelvin.
456
457        /**
458         * The SI unit for luminous flux (standard name <code>lm</code>). One Lumen is
459         * equal to the amount of light given out through a solid angle by a source of
460         * one candela intensity radiating equally in all directions.
461         */
462        public static final Unit<LuminousFlux> LUMEN = addUnit(
463                        new AlternateUnit<LuminousFlux>(CANDELA.multiply(STERADIAN), "lm", "Lumen"), LuminousFlux.class);
464
465        /**
466         * The SI unit for illuminance (standard name <code>lx</code>). One Lux is equal
467         * to one lumen per square metre.
468         */
469        public static final Unit<Illuminance> LUX = addUnit(
470                        new AlternateUnit<Illuminance>(LUMEN.divide(METRE.pow(2)), "lx", "Lux"), Illuminance.class);
471
472        /**
473         * The SI unit for activity of a radionuclide (standard name <code>Bq</code> ).
474         * One becquerel is the radiation caused by one disintegration per second. It is
475         * named after the French physicist, Antoine-Henri Becquerel (1852-1908).
476         */
477        public static final Unit<Radioactivity> BECQUEREL = addUnit(
478                        new AlternateUnit<Radioactivity>(ONE.divide(SECOND), "Bq", "Becquerel"), Radioactivity.class);
479
480        /**
481         * The SI unit for absorbed dose, specific energy (imparted), kerma (standard
482         * name <code>Gy</code>). One gray is equal to the dose of one joule of energy
483         * absorbed per one kilogram of matter. It is named after the British physician
484         * L. H. Gray (1905-1965).
485         */
486        public static final Unit<RadiationDoseAbsorbed> GRAY = addUnit(
487                        new AlternateUnit<RadiationDoseAbsorbed>(JOULE.divide(KILOGRAM), "Gy", "Gray"), RadiationDoseAbsorbed.class);
488
489        /**
490         * The SI unit for dose equivalent (standard name <code>Sv</code>). One Sievert
491         * is equal is equal to the actual dose, in grays, multiplied by a "quality
492         * factor" which is larger for more dangerous forms of radiation. It is named
493         * after the Swedish physicist Rolf Sievert (1898-1966).
494         */
495        public static final Unit<RadiationDoseEffective> SIEVERT = addUnit(
496                        new AlternateUnit<RadiationDoseEffective>(JOULE.divide(KILOGRAM), "Sv", "Sievert"), RadiationDoseEffective.class);
497
498        /**
499         * The SI unit for catalytic activity (standard name <code>kat</code>).
500         * 
501         * <dl>
502     * <dt><span class="strong">Implementation Note:</span></dt><dd>SI Brochure - Table 4</dd>
503     * </dl>
504         */
505        public static final Unit<CatalyticActivity> KATAL = addUnit(
506                        new AlternateUnit<CatalyticActivity>(MOLE.divide(SECOND), "kat", "Katal"), CatalyticActivity.class);
507
508        //////////////////////////////
509        // SI DERIVED PRODUCT UNITS //
510        //////////////////////////////
511
512        /**
513         * The SI unit for speed quantities (standard name <code>m/s</code>).
514         */
515        public static final Unit<Speed> METRE_PER_SECOND = addUnit(new ProductUnit<>(METRE.divide(SECOND)), "Metre per Second", Speed.class);
516
517        /**
518         * The SI unit for acceleration quantities (standard name <code>m/s2</code>).
519         * 
520         * @see <a href="https://en.wikipedia.org/wiki/Metre_per_second_squared"> Wikipedia: Metre per second squared</a>
521         */
522        public static final Unit<Acceleration> METRE_PER_SQUARE_SECOND = addUnit(
523                        new ProductUnit<>(METRE_PER_SECOND.divide(SECOND)), "Metre per square second", Acceleration.class);
524
525        /**
526         * The SI unit for area quantities (standard name <code>m2</code>).
527         * 
528         * @see <a href="https://en.wikipedia.org/wiki/Square_metre"> Wikipedia: Square metre</a> 
529         */
530        public static final Unit<Area> SQUARE_METRE = addUnit(new ProductUnit<>(METRE.multiply(METRE)), "Square metre", Area.class);
531
532        /**
533         * The SI unit for volume quantities (standard name <code>m3</code>).
534         */
535        public static final Unit<Volume> CUBIC_METRE = addUnit(new ProductUnit<Volume>(SQUARE_METRE.multiply(METRE)), "Cubic metre",
536                        Volume.class);
537
538        /**
539         * A unit of speed expressing the number of international kilometres per {@link #HOUR hour} 
540         * (abbreviation <code>km/h</code>).
541         * 
542         * @see <a href="https://en.wikipedia.org/wiki/Kilometres_per_hour"> Wikipedia: Kilometres per hour</a>
543         */
544        public static final Unit<Speed> KILOMETRE_PER_HOUR = addUnit(INSTANCE.units, METRE_PER_SECOND.multiply(RationalNumber.of(5, 18)), "Kilometre per hour")
545                        .asType(Speed.class);
546
547        /////////////////////////////////////////////////////////////////
548        // Common Units outside the SI that are accepted for use with the SI. //
549        /////////////////////////////////////////////////////////////////
550
551        /**
552         * A dimensionless unit accepted for use with SI units (standard name
553         * <code>%</code>).
554         */
555        public static final Unit<Dimensionless> PERCENT = addUnit(
556                        new TransformedUnit<>("%", "Percent", ONE, MultiplyConverter.ofRational(1, 100)));
557
558        //////////
559        // Time //
560        //////////
561        /**
562         * A time unit accepted for use with SI units (standard name <code>min</code>).
563         */
564        public static final Unit<Time> MINUTE = addUnit(
565                        new TransformedUnit<>("min", "Minute", SECOND, SECOND, MultiplyConverter.ofRational(60, 1)));
566
567        /**
568         * A time unit accepted for use with SI units (standard name <code>h</code> ).
569         */
570        public static final Unit<Time> HOUR = addUnit(
571                        new TransformedUnit<>("h", "Hour", SECOND, SECOND, MultiplyConverter.ofRational(60 * 60, 1)));
572
573        /**
574         * A time unit accepted for use with SI units (standard name <code>d</code> ).
575         */
576        public static final Unit<Time> DAY = addUnit(
577                        new TransformedUnit<>("d", "Day", SECOND, SECOND, MultiplyConverter.ofRational(24 * 60 * 60, 1)));
578
579        /**
580         * A unit of duration equal to 7 {@link #DAY} (common name <code>wk</code>).
581         */
582        public static final Unit<Time> WEEK = AbstractSystemOfUnits.Helper.addUnit(INSTANCE.units, 
583                        DAY.multiply(7), "Week", "wk");
584
585        /**
586         * A time unit accepted for use with SI units (standard name <code>yr</code> ).
587         */
588        public static final Unit<Time> YEAR = AbstractSystemOfUnits.Helper.addUnit(INSTANCE.units,
589                        Units.DAY.multiply(365.2425), "Year", "yr");
590
591        /**
592         * A unit of duration equal to 1/12 {@link #YEAR} (common name <code>mo</code>).
593         * @since 2.3
594         */
595        public static final Unit<Time> MONTH = AbstractSystemOfUnits.Helper.addUnit(INSTANCE.units, 
596                        YEAR.divide(12), "Month", "mo");
597        
598        /**
599         * A volume unit accepted for use with SI units (standard name <code>l</code>).
600         *
601         * @see <a href="https://en.wikipedia.org/wiki/Litre"> Wikipedia: Litre</a>
602         */
603        public static final Unit<Volume> LITRE = AbstractSystemOfUnits.Helper.addUnit(INSTANCE.units,
604                        new TransformedUnit<Volume>(CUBIC_METRE, MultiplyConverter.ofRational(1, 1000)), "Litre", "l");
605
606        /**
607         * Returns the unique instance of this class.
608         *
609         * @return the Units instance.
610         */
611        public static Units getInstance() {
612                return INSTANCE;
613        }
614        
615        static {
616                // have to add AbstractUnit.ONE as Dimensionless, too
617                addUnit(INSTANCE.units, ONE);
618                Helper.addUnit(INSTANCE.units, ONE, "One");
619                INSTANCE.quantityToUnit.put(Dimensionless.class, ONE);
620        }       
621
622        /**
623     * Adds a new unit not mapped to any specified quantity type to a set with a name and symbol.
624     *
625     * @param units 
626     *            the set to add to.
627     * @param unit
628     *            the unit being added.
629     * @param name
630     *            the string to use as name
631     * @param symbol
632     *            the string to use as symbol
633     * @return <code>unit</code>.
634     */
635        protected static <U extends AbstractUnit<?>> U addUnit(final Set<Unit<?>> units, U unit, String name, String symbol) {
636                return Helper.addUnit(units, unit, name, symbol);
637        }
638        
639        /**
640     * Adds a new unit to a set using a name.
641     *
642     * @param units 
643     *            the set to add to.
644     * @param unit
645     *            the unit being added.
646     * @param name
647     *            the string to use as name
648     * @return <code>unit</code>.
649     */
650        protected static <U extends Unit<?>> U addUnit(final Set<Unit<?>> units, U unit, String name) {
651        if (name != null && unit instanceof AbstractUnit) {
652            return Helper.addUnit(units, unit, name);
653        } else {
654            units.add(unit);
655        }
656        return unit;
657    }
658        
659        /**
660         * Adds a new unit to a set of units.
661         *
662         * @param units the set to add to.
663         * @param unit the unit being added.
664         * @return <code>unit</code>.
665         */
666        protected static <U extends Unit<?>> U addUnit(final Set<Unit<?>> units, U unit) {
667                units.add(unit);
668                return unit;
669        }
670        
671        /**
672         * Adds a new unit not mapped to any specified quantity type.
673         *
674         * @param unit the unit being added.
675         * @return <code>unit</code>.
676         */
677        private static <U extends Unit<?>> U addUnit(U unit) {
678                return addUnit(INSTANCE.units, unit);
679        }
680    
681        /**
682         * Adds a new unit and maps it to the specified quantity type.
683         *
684         * @param unit the unit being added.
685         * @param name the name of the unit being added.
686         * @param type the quantity type.
687         * @return <code>unit</code>.
688         */
689        private static <U extends AbstractUnit<?>> U addUnit(U unit, String name, Class<? extends Quantity<?>> type) {
690                Helper.addUnit(INSTANCE.units, unit, name);
691                INSTANCE.quantityToUnit.put(type, unit);
692                return unit;
693        }
694        
695        /**
696         * Adds a new unit and maps it to the specified quantity type.
697         *
698         * @param unit the unit being added.
699         * @param type the quantity type.
700         * @return <code>unit</code>.
701         */
702        private static <U extends AbstractUnit<?>> U addUnit(U unit, Class<? extends Quantity<?>> type) {
703                INSTANCE.units.add(unit);
704                INSTANCE.quantityToUnit.put(type, unit);
705                return unit;
706        }       
707}