# Implementing CGS unit system in Mathematica 9

So I've just installed the trial version of Mathematica 9. The first noticeable feature for me is the new built-in physical units. I used AutomaticUnits package before, it was almost perfect except that its units aren't usable inside many other functions. But new units can be used everywhere but I can't yet figure out how to implement new units and unit systems or override an old ones. It would be great to have a way to convert units to CGS system.

For reference, that's what I usually do using AutomaticUnits:

Needs["AutomaticUnits"];
UnitSet["cgs"] = {Centimeter,Gram,Second,Statcoulomb,Statcoulomb/Second};
DeclareUnit["statC", Erg^(1/2) Centimeter^(1/2)];
toCGS[x_] :=
Convert[Convert[x, "cgs"] /. {"Statcoulomb" -> statC}, "cgs"]

-
Have you looked at UnitConvert? reference.wolfram.com/mathematica/ref/UnitConvert.html –  David Carraher Nov 28 '12 at 23:46
@DavidCarraher Sure, there is no CGS, only "SIBase", "SI", "Imperial" and "Metric". –  swish Nov 29 '12 at 0:01
The most recent version should be automatically assumed, so the v.9 tag is unnecessary. –  rcollyer Nov 29 '12 at 2:32

The CGS units are available. Out of the need to ensure dimensional consistency, the different things which are all called ESUs must be carefully distinguished.

In[59]:= Quantity[1, "ESU of charge"]
Out[59]= Quantity[1, "ESUsOfCharge"]

In[60]:= Quantity[1, "ESU"]
Out[60]= Quantity[1, "ESUOfDielectricDisplacement"]


Also, when a unit has a special name, Alpha (which is used for interpreting unit names) is more forgiving of misspellings, although are all standard names are accepted.

In[65]:= Quantity[1, "franklin"]
Out[65]= Quantity[1, "Franklins"]

In[66]:= Quantity[1, "StatColumbs"]
During evaluation of In[66]:= Quantity::unkunit: Unable to interpret unit specification StatColumbs. >>
Out[66]= Quantity[1, "StatColumbs"]

In[67]:= Quantity[1, "Fr"] == Quantity[1, "ESUsOfCharge"] == Quantity[1, "StatCoulombs"]
Out[67]= True


You can certainly do a conversion to any of these units or their products.

In[69]:= UnitConvert[Quantity[1, "Coloumbs"], "StatCoulombs"]
Out[69]= Quantity[2997924580, "StatCoulombs"]


There is currently no equivalent of "SIBase", which decomposes any quantity into a product of the 7 SI base units, partly because there isn't a universally accepted definition of what is the CGS base unit of electromagnetism. There is, unfortunately, also no mechanism for defining your own units at this time, other than pure counting units through IndependentUnit. You are welcome to request these features through support@wolfram.com and they will be considered for future versions.

-
Regarding the use of StatCoulombs in MMA, is it equal to $g^{1/2} cm^{3/2}/s$? Some comments below one doubts this. I have the same problem since on paper I would be able to cancel out StatCoulombs. However, in MMA StatCoulombs cannot be cancelled out by a combination of length, mass and seconds...? –  Frank Jun 15 '13 at 14:30

Below is some code I use to work with units. I am aware that the unit system I am calling "CGS" is only semi-CGS, since I am keeping the SI electromagnetic units, but this is the flavor of consistent unit system we sometimes use in our lab. Really, though, this is a recipe for choosing your own set of base units.

The method works by applying UnitDimensions to the quantity in question, then substituting the base units of your choice to each unit dimension. There are also a couple of convenience functions to convert Quantity objects deeper within an expression, or to convert units and strip the units off.

CGSBase[expr_] :=
expr /. HoldPattern[q : _Quantity] :> toCGSFundamental[q]

toCGSFundamental[q_Quantity] :=
UnitConvert[q,
Quantity[Times @@
Apply[Power,
UnitDimensions[q] /. {"LengthUnit" -> "Centimeters",
"MassUnit" -> "Grams", "TimeUnit" -> "Seconds",
"ElectricCurrentUnit" -> "Amperes",
"TemperatureDifferenceUnit" -> "KelvinsDifference",
"AmountUnit" -> "Moles",
"LuminousIntensityUnit" -> "Candelas"}, {1}]]]

CGSValue[expr_] :=
expr /.
HoldPattern[q : _Quantity] :> QuantityMagnitude[toCGSFundamental[q]]

SIBase[expr_] :=
expr /. HoldPattern[q : _Quantity] :> toSIFundamental[q]

toSIFundamental[q_Quantity] := UnitConvert[q, "SIBase"]

SIValue[expr_] :=
expr /.
HoldPattern[q : _Quantity] :> QuantityMagnitude[toSIFundamental[q]]

-

UnitConvert appears to work just fine with CGS.

UnitConvert[Quantity[8.2, "Miles"], "Centimeters"]
UnitConvert[Quantity[3.8, "Pounds"], "Grams"]
UnitConvert[Quantity[2, "Years"], "Seconds"]
UnitConvert[Quantity[3, "Pascals"], Times["Grams", Power["Meters", -1], Power["Seconds", -2]]]


Quantity[1.31966*10^6, "Centimeters"]
Quantity[1723.65, "Grams"]
Quantity[63072000, "Seconds"]
Quantity[3000, ("Grams")/("Meters" ("Seconds")^2)]

-
The point is to be able to write something like UnitConvert[_,"CGS"]. Also it doesn't work with charge: UnitConvert[Quantity[1, "Coulombs"], ("Ergs")^(1/2) ("Centimeters")^(1/2)]. –  swish Nov 29 '12 at 0:42
Ok, but how about UnitConvert[Quantity[1, "Coulombs"], Times["Amperes", "Seconds"]]? –  David Carraher Nov 29 '12 at 1:18
Ampere is a SI unit. CGS = Centimeter Gram Second, it should be able to convert charge into these three unit combination. Basically I need similar workaround to the one with AutomaticUnits. –  swish Nov 29 '12 at 1:26
I see. Well, looks like I should read up on CGS. –  David Carraher Nov 29 '12 at 1:28

This is a kludge, but maybe it can be improved upon.

cgRule = {"Meters"-> Quantity[100, "Centimeters"],
"Kilograms" -> Quantity[1000,"Grams"], "Seconds" -> Quantity[1,"Seconds"]};

cgF = QuantityUnit[#] QuantityMagnitude[#] /. cgRule &;


Then:

UnitConvert[Quantity[1,"erg"] ] // cgF // InputForm

Quantity[1, ("Centimeters"^2*"Grams")/"Seconds"^2]

-

I use a custom approach to operate units. Since I find it to be much too much to type the whole units names many times per day, I do it in such a way as we always did it in the past during our on-paper calculations reserving some letters for units, such as m for meter, cm for centimeter and so on, and using the multiplication sign between the unit and the variable. Five meters will be

5*m


in this case. Calculating is done symbolically, and the transition to the final results with the units is accomplished by application of rules. For example, this is the rule for a solid containing its constants with units in CGS:

    ruleSolid = { \[CapitalEpsilon] -> (1.*10^12*erg)/cm^3,
KIc -> (1.*10^7*erg)/cm^(5/2),
r0 -> 1.*10^-6*cm, \[Epsilon]0 -> 1.*10^-3};


Here \[CapitalEpsilon] is the Young's modulus and KIc is the fracture toughness. Here is the calculation of a stress in a solid under a given strain [Epsilon]0 and at the distance r0 from the crack tip:

  \[CapitalEpsilon]*\[Epsilon]0 /. ruleSolid
KIc/Sqrt[r0] /. ruleSolid


This yields the following:

    (1.*10^9 erg)/cm^3

(1.*10^10 erg)/cm^3


In order to switch between SI and CGS I use a couple of rules:

    ruleSItoCGS = {Coul -> 3*10^9*Sqrt[erg*cm], J -> 10^7*erg,
Pa -> (10^7*erg)/(100*cm)^3, m -> 100*cm};


and back

ruleCGStoSI = {dyne -> 10^-5*Pa*m^2, cm -> 0.01*m,
erg -> 10^-7*Pa*m^3};


For example, the above estimate may be turned into SI as follows:

  \[CapitalEpsilon]*\[Epsilon]0 /. ruleSolid /. ruleCGStoSI
KIc/Sqrt[r0] /. ruleSolid /. ruleCGStoSI


yielding

 1.*10^8 Pa

1.*10^9 Pa


Note that I only keep here rules for those units I deal with during my calculations. Rules for additional units may be included, when needed.

There are few other useful rules:

ruleCMto\[Mu]M = {1*cm -> 10^4*\[Mu]m};
ruleCMtoNm = {1*cm -> 10^7*nm};
rulePaToKbar = Pa -> 10^-8*kbar;
ruleEsuToErg = esu -> Sqrt[erg*cm];


and you may expand expand or decrease them depending upon the area you work in.

Finally, it is handy to make an assumption concerning the positiveness of all these units:

    \$Assumptions = {erg > 0, cm > 0, Pa > 0, m > 0, Coul > 0, dyne > 0,
nm > 0, \[Mu]m > 0, grad > 0};


It may be supplemented by some other assumptions concerning the evident signs of some parameters. For example, the Young's modulus is always positive. Then application of

...//Simplify


in the end of the estimate eliminates possible roots, if any, and delivers the final result.

It may seem to be a bit lengthily, but in reality these rules one makes once-forever. By experience I find it to be much faster then to type each time the full name of each unit. Besides this approach does not require using additional operators (like Quantify) leading to more typing.

-