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.units.ri.AbstractUnit.ONE;
029import static tec.units.ri.unit.MetricPrefix.CENTI;
030import static tec.units.ri.unit.Units.JOULE;
031import static tec.units.ri.unit.Units.METRE;
032import static tec.units.ri.unit.Units.NEWTON;
033import static tec.units.ri.unit.Units.PASCAL;
034
035import javax.measure.Unit;
036import javax.measure.quantity.Acceleration;
037import javax.measure.quantity.Energy;
038import javax.measure.quantity.Force;
039import javax.measure.quantity.Length;
040import javax.measure.quantity.Mass;
041import javax.measure.quantity.Power;
042import javax.measure.quantity.Pressure;
043import javax.measure.quantity.Speed;
044import javax.measure.quantity.Time;
045
046import si.uom.quantity.DynamicViscosity;
047import si.uom.quantity.KinematicViscosity;
048import tec.units.ri.AbstractSystemOfUnits;
049import tec.units.ri.AbstractUnit;
050import tec.units.ri.format.SimpleUnitFormat;
051import tec.units.ri.unit.ProductUnit;
052import tec.units.ri.unit.Units;
053
054/**
055 * <p>
056 * This class contains the centimetre–gram–second system of units.
057 * </p>
058 * 
059 * <p>
060 * This class is not intended to be implemented by clients.
061 * </p>
062 * 
063 * @noextend This class is not intended to be extended by clients.
064 * 
065 * @author <a href="mailto:units@catmedia.us">Werner Keil</a>
066 * @version 0.5, $Date: 2017-03-05$
067 * @see <a href=
068 *      "https://en.wikipedia.org/wiki/Centimetre%E2%80%93gram%E2%80%93second_system_of_units">Wikipedia:
069 *      Centimetre–gram–second system of units</a>
070 * @since 0.6
071 */
072public final class CGS extends AbstractSystemOfUnits {
073    private static final String SYSTEM_NAME = "Centimetre–gram–second System of Units";
074
075    /**
076     * Holds the avoirdupois pound: 0.45359237 kg exact
077     */
078    static final int AVOIRDUPOIS_POUND_DIVIDEND = 45359237;
079
080    static final int AVOIRDUPOIS_POUND_DIVISOR = 100000000;
081
082    /**
083     * Default constructor (prevents this class from being instantiated).
084     */
085    private CGS() {
086    }
087
088    /**
089     * Returns the unique instance of this class.
090     * 
091     * @return the NonSI instance.
092     */
093    public static CGS getInstance() {
094        return INSTANCE;
095    }
096
097    private static final CGS INSTANCE = new CGS();
098
099    ////////////
100    // Length //
101    ////////////
102
103    /**
104     * A unit of length equal to <code>1/100 of metre</code> (standard name
105     * <code>cm</code>).
106     */
107    public static final Unit<Length> CENTIMETRE = addUnit(CENTI(METRE));
108
109    //////////
110    // Mass //
111    //////////
112    /**
113     * A unit of mass equal to 1/12 the mass of the carbon-12 atom (standard
114     * name <code>g</code>).
115     */
116    public static final Unit<Mass> GRAM = addUnit(Units.GRAM);
117
118    //////////
119    // Time //
120    //////////
121    /**
122     * The SI base unit for duration quantities (standard name <code>s</code>).
123     * It is defined as the duration of 9,192,631,770 cycles of radiation
124     * corresponding to the transition between two hyperfine levels of the
125     * ground state of cesium (1967 Standard).
126     * 
127     */
128    public static final Unit<Time> SECOND = addUnit(Units.SECOND);
129
130    //////////////
131    // Velocity //
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<Acceleration>(CENTIMETRE_PER_SECOND.divide(SECOND)).asType(Acceleration.class), "Gal",
151            "Gal");
152
153    ////////////
154    // Energy //
155    ////////////
156    /**
157     * A unit of energy equal to <code>1E-7 J</code> (standard name
158     * <code>erg</code>).
159     */
160    public static final Unit<Energy> ERG = addUnit(JOULE.divide(10000000), "Erg", "erg");
161
162    ///////////
163    // Force //
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    /**
199     * A unit of dynamic viscosity equal to <code>1 g/(cm·s)</code> (cgs unit
200     * standard name <code>P</code>.
201     * 
202     * @see <a href="https://de.wikipedia.org/wiki/Poise">Wikipedia: Poise</a>
203     */
204    public static final Unit<DynamicViscosity> POISE = addUnit(
205            GRAM.divide(CENTI(METRE).multiply(SECOND)).asType(DynamicViscosity.class), "Poise", "P");
206
207    /**
208     * A unit of kinematic viscosity equal to <code>1 cm²/s</code> (cgs unit,
209     * standard name <code>St</code>).
210     */
211    public static final Unit<KinematicViscosity> STOKES = addUnit(
212            CENTI(METRE).pow(2).divide(SECOND).asType(KinematicViscosity.class), "Stokes", "St");
213
214    ////////////////
215    // Wavenumber //
216    ////////////////
217    
218    /**
219     * A unit of wavenumber equal to <code>1/cm</code> (cgs unit,
220     * standard name <code>cm&#8315;&#185;</code>).
221     */
222    public static final Unit<KinematicViscosity> KAYSER = addUnit(
223            ONE.divide(CENTIMETRE).asType(KinematicViscosity.class), "Kayser", "cm\u207B\u00B9");
224    
225    /////////////////////
226    // Collection View //
227    /////////////////////
228
229    public String getName() {
230        return SYSTEM_NAME;
231    }
232
233    /**
234     * Adds a new unit not mapped to any specified quantity type.
235     *
236     * @param unit
237     *            the unit being added.
238     * @return <code>unit</code>.
239     */
240    private static <U extends Unit<?>> U addUnit(U unit) {
241        INSTANCE.units.add(unit);
242        return unit;
243    }
244
245    /**
246     * Adds a new unit not mapped to any specified quantity type and puts a text
247     * as symbol or label.
248     *
249     * @param unit
250     *            the unit being added.
251     * @param name
252     *            the string to use as name
253     * @param text
254     *            the string to use as label or symbol
255     * @param isLabel
256     *            if the string should be used as a label or not
257     * @return <code>unit</code>.
258     */
259    private static <U extends Unit<?>> U addUnit(U unit, String name, String text, boolean isLabel) {
260        if (isLabel && text != null) {
261            SimpleUnitFormat.getInstance().label(unit, text);
262        }
263        if (name != null && unit instanceof AbstractUnit) {
264            return Helper.addUnit(INSTANCE.units, unit, name);
265        } else {
266            INSTANCE.units.add(unit);
267        }
268        return unit;
269    }
270
271    /**
272     * Adds a new unit not mapped to any specified quantity type and puts a text
273     * as symbol or label.
274     *
275     * @param unit
276     *            the unit being added.
277     * @param name
278     *            the string to use as name
279     * @param text
280     *            the string to use as label
281     * @return <code>unit</code>.
282     */
283    private static <U extends Unit<?>> U addUnit(U unit, String name, String text) {
284        return addUnit(unit, name, text, true);
285    }
286}