001/*
002 * Units of Measurement Systems for Java
003 * Copyright (c) 2005-2017, Jean-Marie Dautelle, Werner Keil, V2COM.
004 *
005 * All rights reserved.
006 *
007 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
008 *
009 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
010 *
011 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
012 *
013 * 3. Neither the name of JSR-363, Units of Measurement nor the names of their contributors may be used to endorse or promote products derived from this software without specific prior written permission.
014 *
015 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
016 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
017 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
018 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
019 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
020 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
021 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
022 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
023 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
024 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
025 */
026package systems.uom.common;
027
028import static tec.uom.se.AbstractUnit.ONE;
029import static tec.uom.se.unit.MetricPrefix.CENTI;
030import static tec.uom.se.unit.Units.JOULE;
031import static tec.uom.se.unit.Units.METRE;
032import static tec.uom.se.unit.Units.NEWTON;
033import static tec.uom.se.unit.Units.PASCAL;
034import javax.measure.Unit;
035import javax.measure.quantity.Acceleration;
036import javax.measure.quantity.Energy;
037import javax.measure.quantity.Force;
038import javax.measure.quantity.Length;
039import javax.measure.quantity.Mass;
040import javax.measure.quantity.Power;
041import javax.measure.quantity.Pressure;
042import javax.measure.quantity.Speed;
043import javax.measure.quantity.Time;
044
045import si.uom.quantity.DynamicViscosity;
046import si.uom.quantity.KinematicViscosity;
047import tec.uom.se.AbstractSystemOfUnits;
048import tec.uom.se.AbstractUnit;
049import tec.uom.se.format.SimpleUnitFormat;
050import tec.uom.se.unit.ProductUnit;
051import tec.uom.se.unit.Units;
052
053/**
054 * <p>
055 * This class contains the centimetre–gram–second system of units.
056 * </p>
057 * 
058 * <p>
059 * This class is not intended to be implemented by clients.
060 * </p>
061 * 
062 * @noextend This class is not intended to be extended by clients.
063 * 
064 * @author <a href="mailto:units@catmedia.us">Werner Keil</a>
065 * @version 0.5, $Date: 2017-03-05$
066 * @see <a href=
067 *      "https://en.wikipedia.org/wiki/Centimetre%E2%80%93gram%E2%80%93second_system_of_units">Wikipedia:
068 *      Centimetre–gram–second system of units</a>
069 * @since 0.6
070 */
071public final class CGS extends AbstractSystemOfUnits {
072    private static final String SYSTEM_NAME = "Centimetre–gram–second System of Units";
073
074    /**
075     * Holds the avoirdupois pound: 0.45359237 kg exact
076     */
077    static final int AVOIRDUPOIS_POUND_DIVIDEND = 45359237;
078
079    static final int AVOIRDUPOIS_POUND_DIVISOR = 100000000;
080
081    /**
082     * Default constructor (prevents this class from being instantiated).
083     */
084    private CGS() {
085    }
086
087    /**
088     * Returns the unique instance of this class.
089     * 
090     * @return the NonSI instance.
091     */
092    public static CGS getInstance() {
093        return INSTANCE;
094    }
095
096    private static final CGS INSTANCE = new CGS();
097
098    ////////////
099    // Length //
100    ////////////
101
102    /**
103     * A unit of length equal to <code>1/100 of metre</code> (standard name
104     * <code>cm</code>).
105     */
106    public static final Unit<Length> CENTIMETRE = addUnit(CENTI(METRE));
107
108    //////////
109    // Mass //
110    //////////
111    /**
112     * A unit of mass equal to 1/12 the mass of the carbon-12 atom (standard
113     * name <code>g</code>).
114     */
115    public static final Unit<Mass> GRAM = addUnit(Units.GRAM);
116
117    //////////
118    // Time //
119    //////////
120    /**
121     * The SI base unit for duration quantities (standard name <code>s</code>).
122     * It is defined as the duration of 9,192,631,770 cycles of radiation
123     * corresponding to the transition between two hyperfine levels of the
124     * ground state of cesium (1967 Standard).
125     * 
126     */
127    public static final Unit<Time> SECOND = addUnit(Units.SECOND);
128
129    //////////////
130    // Velocity //
131    //////////////
132
133    /**
134     * A unit of velocity (cgs unit, standard name <code>cm/s</code>).
135     */
136    public static final Unit<Speed> CENTIMETRE_PER_SECOND = addUnit(CENTIMETRE.divide(SECOND).asType(Speed.class),
137            "centimetre per second", "cm/s");
138
139    //////////////////
140    // Acceleration //
141    //////////////////
142
143    /**
144     * A unit of acceleration (cgs unit, standard name <code>Gal</code>).
145     * 
146     * @see <a href="https://en.wikipedia.org/wiki/Gal_(unit)">Wikipedia:
147     *      Gal</a>
148     */
149    public static final Unit<Acceleration> GAL = addUnit(
150            new ProductUnit<>(CENTIMETRE_PER_SECOND.divide(SECOND)).asType(Acceleration.class), "Gal", "Gal");
151
152    ////////////
153    // Energy //
154    ////////////
155    /**
156     * A unit of energy equal to <code>1E-7 J</code> (standard name
157     * <code>erg</code>).
158     */
159    public static final Unit<Energy> ERG = addUnit(JOULE.divide(10000000), "Erg", "erg");
160
161    ///////////
162    // Force //
163    ///////////
164
165    /**
166     * A unit of force equal to <code>1E-5 N</code> (standard name
167     * <code>dyn</code>).
168     */
169    public static final Unit<Force> DYNE = addUnit(NEWTON.divide(100000), "Dyne", "dyn");
170
171    ///////////
172    // Power //
173    ///////////
174
175    /**
176     * A unit of power (cgs unit, standard name <code>erg/s</code>).
177     */
178    public static final Unit<Power> ERG_PER_SECOND = addUnit(ERG.divide(SECOND).asType(Power.class), "Erg per second",
179            "erg/s");
180
181    //////////////
182    // Pressure //
183    //////////////
184
185    /**
186     * The barye (symbol: <code>Ba</code>), or sometimes barad, barrie, bary,
187     * baryd, baryed, or barie, is the centimetre–gram–second (CGS) unit of
188     * pressure. It is equal to 1 dyne per square centimetre.
189     * <p>
190     * <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>
191     */
192    public static final Unit<Pressure> BARYE = addUnit(PASCAL.divide(10), "Barye", "Ba");
193
194    ///////////////
195    // Viscosity //
196    ///////////////
197    /**
198     * A unit of dynamic viscosity equal to <code>1 g/(cm·s)</code> (cgs unit
199     * standard name <code>P</code>.
200     * 
201     * @see <a href="https://de.wikipedia.org/wiki/Poise">Wikipedia: Poise</a>
202     */
203    public static final Unit<DynamicViscosity> POISE = addUnit(
204            GRAM.divide(CENTI(METRE).multiply(SECOND)).asType(DynamicViscosity.class), "Poise", "P");
205
206    /**
207     * A unit of kinematic viscosity equal to <code>1 cm²/s</code> (cgs unit,
208     * standard name <code>St</code>).
209     */
210    public static final Unit<KinematicViscosity> STOKES = addUnit(
211            CENTI(METRE).pow(2).divide(SECOND).asType(KinematicViscosity.class), "Stokes", "St");
212    
213    ////////////////
214    // Wavenumber //
215    ////////////////
216    
217    /**
218     * A unit of wavenumber equal to <code>1/cm</code> (cgs unit,
219     * standard name <code>cm&#8315;&#185;</code>).
220     */
221    public static final Unit<KinematicViscosity> KAYSER = addUnit(
222            ONE.divide(CENTIMETRE).asType(KinematicViscosity.class), "Kayser", "cm\u207B\u00B9");
223    
224    /////////////////////
225    // Collection View //
226    /////////////////////
227    
228    public String getName() {
229        return SYSTEM_NAME;
230    }
231
232    /**
233     * Adds a new unit not mapped to any specified quantity type.
234     *
235     * @param unit
236     *            the unit being added.
237     * @return <code>unit</code>.
238     */
239    private static <U extends Unit<?>> U addUnit(U unit) {
240        INSTANCE.units.add(unit);
241        return unit;
242    }
243
244    /**
245     * Adds a new unit not mapped to any specified quantity type and puts a text
246     * as symbol or label.
247     *
248     * @param unit
249     *            the unit being added.
250     * @param name
251     *            the string to use as name
252     * @param text
253     *            the string to use as label or symbol
254     * @param isLabel
255     *            if the string should be used as a label or not
256     * @return <code>unit</code>.
257     */
258    private static <U extends Unit<?>> U addUnit(U unit, String name, String text, boolean isLabel) {
259        if (isLabel && text != null) {
260            SimpleUnitFormat.getInstance().label(unit, text);
261        }
262        if (name != null && unit instanceof AbstractUnit) {
263            return Helper.addUnit(INSTANCE.units, unit, name);
264        } else {
265            INSTANCE.units.add(unit);
266        }
267        return unit;
268    }
269
270    /**
271     * Adds a new unit not mapped to any specified quantity type and puts a text
272     * as symbol or label.
273     *
274     * @param unit
275     *            the unit being added.
276     * @param name
277     *            the string to use as name
278     * @param text
279     *            the string to use as label
280     * @return <code>unit</code>.
281     */
282    private static <U extends Unit<?>> U addUnit(U unit, String name, String text) {
283        return addUnit(unit, name, text, true);
284    }
285}