001/*
002 * Units of Measurement Systems
003 * Copyright (c) 2005-2017, Jean-Marie Dautelle, Werner Keil and others.
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-363, Units of Measurement nor the names of their contributors may be used to
017 *    endorse or promote products 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 systems.uom.common;
031
032import static tec.units.indriya.AbstractUnit.ONE;
033import static tec.units.indriya.unit.MetricPrefix.CENTI;
034import static tec.units.indriya.unit.Units.JOULE;
035import static tec.units.indriya.unit.Units.METRE;
036import static tec.units.indriya.unit.Units.NEWTON;
037import static tec.units.indriya.unit.Units.PASCAL;
038
039import javax.measure.Unit;
040import javax.measure.quantity.Acceleration;
041import javax.measure.quantity.Energy;
042import javax.measure.quantity.Force;
043import javax.measure.quantity.Length;
044import javax.measure.quantity.Mass;
045import javax.measure.quantity.Power;
046import javax.measure.quantity.Pressure;
047import javax.measure.quantity.Speed;
048import javax.measure.quantity.Time;
049
050import si.uom.quantity.DynamicViscosity;
051import si.uom.quantity.KinematicViscosity;
052import tec.units.indriya.AbstractSystemOfUnits;
053import tec.units.indriya.AbstractUnit;
054import tec.units.indriya.format.SimpleUnitFormat;
055import tec.units.indriya.unit.ProductUnit;
056import tec.units.indriya.unit.Units;
057
058/**
059 * <p>
060 * This class contains the centimetre–gram–second system of units.
061 * </p>
062 * 
063 * <p>
064 * This class is not intended to be implemented by clients.
065 * </p>
066 * 
067 * @noextend This class is not intended to be extended by clients.
068 * 
069 * @author <a href="mailto:units@catmedia.us">Werner Keil</a>
070 * @version 0.5, $Date: 2017-03-05$
071 * @see <a href=
072 *      "https://en.wikipedia.org/wiki/Centimetre%E2%80%93gram%E2%80%93second_system_of_units">Wikipedia:
073 *      Centimetre–gram–second system of units</a>
074 * @since 0.6
075 */
076public final class CGS extends AbstractSystemOfUnits {
077    private static final String SYSTEM_NAME = "Centimetre–gram–second System of Units";
078
079    /**
080     * Holds the avoirdupois pound: 0.45359237 kg exact
081     */
082    static final int AVOIRDUPOIS_POUND_DIVIDEND = 45359237;
083
084    static final int AVOIRDUPOIS_POUND_DIVISOR = 100000000;
085
086    /**
087     * Default constructor (prevents this class from being instantiated).
088     */
089    private CGS() {
090    }
091
092    /**
093     * Returns the unique instance of this class.
094     * 
095     * @return the NonSI instance.
096     */
097    public static CGS getInstance() {
098        return INSTANCE;
099    }
100
101    private static final CGS INSTANCE = new CGS();
102
103    ////////////
104    // Length //
105    ////////////
106
107    /**
108     * A unit of length equal to <code>1/100 of metre</code> (standard name
109     * <code>cm</code>).
110     */
111    public static final Unit<Length> CENTIMETRE = addUnit(CENTI(METRE));
112
113    //////////
114    // Mass //
115    //////////
116    /**
117     * A unit of mass equal to 1/12 the mass of the carbon-12 atom (standard
118     * name <code>g</code>).
119     */
120    public static final Unit<Mass> GRAM = addUnit(Units.GRAM);
121
122    //////////
123    // Time //
124    //////////
125    /**
126     * The SI base unit for duration quantities (standard name <code>s</code>).
127     * It is defined as the duration of 9,192,631,770 cycles of radiation
128     * corresponding to the transition between two hyperfine levels of the
129     * ground state of cesium (1967 Standard).
130     * 
131     */
132    public static final Unit<Time> SECOND = addUnit(Units.SECOND);
133
134    //////////////
135    // Velocity //
136    //////////////
137    /**
138     * A unit of velocity (cgs unit, standard name <code>cm/s</code>.
139     */
140    public static final Unit<Speed> CENTIMETRE_PER_SECOND = addUnit(CENTIMETRE.divide(SECOND).asType(Speed.class),
141            "centimetre per second", "cm/s");
142
143    //////////////////
144    // Acceleration //
145    //////////////////
146
147    /**
148     * A unit of acceleration (cgs unit, standard name <code>Gal</code>).
149     * 
150     * @see <a href="https://en.wikipedia.org/wiki/Gal_(unit)">Wikipedia:
151     *      Gal</a>
152     */
153    public static final Unit<Acceleration> GAL = addUnit(
154            new ProductUnit<Acceleration>(CENTIMETRE_PER_SECOND.divide(SECOND)).asType(Acceleration.class), "Gal",
155            "Gal");
156
157    ////////////
158    // Energy //
159    ////////////
160    /**
161     * A unit of energy equal to <code>1E-7 J</code> (standard name
162     * <code>erg</code>).
163     */
164    public static final Unit<Energy> ERG = addUnit(JOULE.divide(10000000), "Erg", "erg");
165
166    ///////////
167    // Force //
168    ///////////
169    /**
170     * A unit of force equal to <code>1E-5 N</code> (standard name
171     * <code>dyn</code>).
172     */
173    public static final Unit<Force> DYNE = addUnit(NEWTON.divide(100000), "Dyne", "dyn");
174
175    ///////////
176    // Power //
177    ///////////
178
179    /**
180     * A unit of power (cgs unit, standard name <code>erg/s</code>).
181     */
182    public static final Unit<Power> ERG_PER_SECOND = addUnit(ERG.divide(SECOND).asType(Power.class), "Erg per second",
183            "erg/s");
184
185    //////////////
186    // Pressure //
187    //////////////
188
189    /**
190     * The barye (symbol: <code>Ba</code>), or sometimes barad, barrie, bary,
191     * baryd, baryed, or barie, is the centimetre–gram–second (CGS) unit of
192     * pressure. It is equal to 1 dyne per square centimetre.
193     * <p>
194     * <code>1 Ba = 0.1 Pa = 1×10−6 bar = 1×10−4 pieze = 0.1 N/m2 = 1 g⋅cm−1⋅s−2</code>
195     */
196    public static final Unit<Pressure> BARYE = addUnit(PASCAL.divide(10), "Barye", "Ba");
197
198    ///////////////
199    // Viscosity //
200    ///////////////
201    
202    /**
203     * A unit of dynamic viscosity equal to <code>1 g/(cm·s)</code> (cgs unit
204     * standard name <code>P</code>.
205     * 
206     * @see <a href="https://de.wikipedia.org/wiki/Poise">Wikipedia: Poise</a>
207     */
208    public static final Unit<DynamicViscosity> POISE = addUnit(
209            GRAM.divide(CENTI(METRE).multiply(SECOND)).asType(DynamicViscosity.class), "Poise", "P");
210
211    /**
212     * A unit of kinematic viscosity equal to <code>1 cm²/s</code> (cgs unit,
213     * standard name <code>St</code>).
214     */
215    public static final Unit<KinematicViscosity> STOKES = addUnit(
216            CENTI(METRE).pow(2).divide(SECOND).asType(KinematicViscosity.class), "Stokes", "St");
217
218    ////////////////
219    // Wavenumber //
220    ////////////////
221    
222    /**
223     * A unit of wavenumber equal to <code>1/cm</code> (cgs unit,
224     * standard name <code>cm&#8315;&#185;</code>).
225     */
226    public static final Unit<KinematicViscosity> KAYSER = addUnit(
227            ONE.divide(CENTIMETRE).asType(KinematicViscosity.class), "Kayser", "cm\u207B\u00B9");
228    
229    /////////////////////
230    // Collection View //
231    /////////////////////
232
233    public String getName() {
234        return SYSTEM_NAME;
235    }
236
237    /**
238     * Adds a new unit not mapped to any specified quantity type.
239     *
240     * @param unit
241     *            the unit being added.
242     * @return <code>unit</code>.
243     */
244    private static <U extends Unit<?>> U addUnit(U unit) {
245        INSTANCE.units.add(unit);
246        return unit;
247    }
248
249    /**
250     * Adds a new unit not mapped to any specified quantity type and puts a text
251     * as symbol or label.
252     *
253     * @param unit
254     *            the unit being added.
255     * @param name
256     *            the string to use as name
257     * @param text
258     *            the string to use as label or symbol
259     * @param isLabel
260     *            if the string should be used as a label or not
261     * @return <code>unit</code>.
262     */
263    private static <U extends Unit<?>> U addUnit(U unit, String name, String text, boolean isLabel) {
264        if (isLabel && text != null) {
265            SimpleUnitFormat.getInstance().label(unit, text);
266        }
267        if (name != null && unit instanceof AbstractUnit) {
268            return Helper.addUnit(INSTANCE.units, unit, name);
269        } else {
270            INSTANCE.units.add(unit);
271        }
272        return unit;
273    }
274
275    /**
276     * Adds a new unit not mapped to any specified quantity type and puts a text
277     * as symbol or label.
278     *
279     * @param unit
280     *            the unit being added.
281     * @param name
282     *            the string to use as name
283     * @param text
284     *            the string to use as label
285     * @return <code>unit</code>.
286     */
287    private static <U extends Unit<?>> U addUnit(U unit, String name, String text) {
288        return addUnit(unit, name, text, true);
289    }
290}