Implementing CGS unit system in Mathematica 9
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 [email protected] and they will be considered for future versions.
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]]
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 = { Ε -> (1.*10^12*erg)/cm^3,
KIc -> (1.*10^7*erg)/cm^(5/2),
r0 -> 1.*10^-6*cm, ϵ0 -> 1.*10^-3};
Here Ε
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 ϵ0
and at the distance r0 from the crack tip:
Ε*ϵ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:
Ε*ϵ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μM = {1*cm -> 10^4*μ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, μ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.