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