HW 1

Question 1

me`UNITS;

Question 2

me`UNITS;

Question 3

me`UNITS;

Question 4

me`UNITS;

Question 5

me`UNITS;

Question 6

me`UNITS;

Question 7

me`UNITS;

Question 8

me`UNITS;

Initialization & Helpers

(* Limit variable scope to within-question *)
SetOptions[EvaluationNotebook[],CellContext->CellGroup] 

(* Output variable names when printing assignments *)
SetAttributes[saveSet,HoldAll];
saveSet[form:Set[var_,_]]:=(lastSet=HoldForm@var;form);
saveSet[form:___]:=(lastSet=.;form)
$Pre=saveSet;
ShowVariableNames=(If[ValueQ@lastSet,Row[{lastSet," = ",#}],#])&;
$Post=ShowVariableNames;

(* Unit conversion helpers *)
(* This grew like fungus, I'll refactor at some point (lol right) *)
to`upscale[limit_,fromu_,tou_]:={q:Quantity[x_,fromu]/;Abs[x]≥limit->UnitConvert[q,tou],
q:Quantity[x_,fromu^k_]/;Abs[x]≥(limit (10^k)) ->UnitConvert[q,tou^k]}

to`downscale[limit_,fromu_,tou_]:={q:Quantity[x_,fromu]/;0<Abs[x]<limit->UnitConvert[q,tou](*,
q:Quantity[x_,fromu^k_]/;0<Abs[x]<limit  ->UnitConvert[q,tou^k]*)}

use`autoUnitBreak[up_,down_]:={to`downscale[1,up,down],to`upscale[(10^3),down,up]}

to`any[from_,to_]:=#/.q:Quantity[_,from]->UnitConvert[q,to]&;
(* Solve likes to give back A when you gave it mA *)
to`mA = to`any["Amperes","Milliamperes"]@#&;
to`in = to`any["Feet","Inches"]/@to`any["Feet"^k_,"Inches"^k]/@to`any["Miles","Inches"]/@#&;

to`ksi=#/.Quantity[x_,(("KipsForce")/("Inches"^2))]->DisplayForm@RowBox[
{x, unitSym["ksi","kips/(inch^2)","KipsForce"/"Inches"^2]}
]&;
to`kips=#/.to`upscale[(10^3),"PoundsForce","KipsForce"]&;

to`fps:=to`ksi@to`kips@((UnitSimplify[#]/.q_Quantity->UnitConvert[q,"Imperial"])//.Flatten@{
q:Quantity[_,"BritishThermalUnitsIT"]->UnitConvert[q,"ft*lbs"],
to`downscale[(10^(-1)),"Miles","Feet"],
to`downscale[10,"Feet","Inches"],
use`autoUnitBreak["Feet"*"KipsForce","Feet"*"PoundsForce"],
use`autoUnitBreak[(("KipsForce")/(("Inches")^2)),(("PoundsForce")/(("Inches")^2))],
use`autoUnitBreak["PoundsForce"/(("Feet")^2),"PoundsForce"/(("Inches")^2)],
Quantity[x_,(("KipsForce")/("Inches"^2))]->DisplayForm@RowBox[
{x, unitSym["ksi","kips/(inch^2)","KipsForce"/"Inches"^2]}],
Quantity[x_,(("PoundsForce")/("Inches"^2))]->DisplayForm@RowBox[
{x, unitSym["psi","pounds/(inch^2)","PoundsForce"/"Inches"^2]}]
})&;
to`si=((#/.q_Quantity->q(*UnitConvert[q,"SI"]*))//UnitSimplify)//.Flatten@{q:Quantity[_,"Liters"]:>UnitConvert[q,"Meters"^3],
Symbol["Heat"][q_Quantity]:>UnitConvert[q,"Kilojoules"/"Seconds"],
q:Quantity[_,(("Kilograms")/("Seconds"^2))]:>UnitConvert[q,(("Newtons")/("Meters"))],
to`upscale[(10^3),"Pascals","Kilopascals"],
to`upscale[(10^3),"Kilopascals","Megapascals"],
to`upscale[(10^3),"Megapascals","Gigapascals"],
(*need break points ≠ (10^(3 ))
use`autoUnitBreak["Meters","Centimeters"],*)use`autoUnitBreak["Kilowatts","Watts"],
use`autoUnitBreak["Kilojoules","Joules"],
use`autoUnitBreak[(("Kilojoules")/("Kelvins")),(("Joules")/("Kelvins"))],
use`autoUnitBreak["Meters","Millimeters"],
use`autoUnitBreak["Kilonewtons","Newtons"],
use`autoUnitBreak["Kilonewtons"/"Meters","Newtons"/"Meters"]}&;

(* use these to enable unit conversions on all output from a cell group *)
use`si:=$Post=ShowVariableNames@to`si@N@#&;
use`fps:=$Post=ShowVariableNames@to`fps@N@#&;
(* -Unit conversion helpers *)


(* Columnize solution output *)
(* Yeah I know the naming here is terrible, I'll get around to it *)

(* Use this to make results from Solve/NSolve/Reduce more readable *)
Prett`y[sol_]:=Grid[
(#/.(a_->c_):>{a,"->",c}&)/@Flatten@sol,
Alignment->{{Right,Left,Left}}
]
NPrett`y = (# // N // Prett`y)&;
ENPrett`y = (# //NPrett`y//EngineeringForm)&;
SPrett`y = (# //NPrett`y//ScientificForm)&;
(* With simplified units *)
Prett`yu=(#//UnitSimplify//Prett`y)&;
NPrett`yu = (# // N // Prett`yu)&;
ENPrett`yu = (# //NPrett`yu//EngineeringForm)&;
SPrett`yu = (# //NPrett`yu//ScientificForm)&;
(* This is what I end up using 99% of the time *)
EN`Solve[sigfigs_][eqs_,vars_]:=NSolve[eqs,vars]//ENPrett`yu//(NumberForm[#,sigfigs]&);
EN`Solve[eqs_,vars_]:=NSolve[eqs,vars]//ENPrett`yu;
EN`Solve[eqs_,vars_,domain_]:=NSolve[eqs,vars,domain]//ENPrett`yu;
(* There appears to be a bug in FindInstance where it fails to find correct solutions without rationalizing. See https://mathematica.stackexchange.com/a/110705/72415 *)
(* Solving only in the reals gets us a good solution in most cases *)
EN`Instance[a_,b_]:=FindInstance[Rationalize[a],b,Reals]//ENPrett`yu;
(* -Columnize solution output *)


(* Environment templates *)
ee`circuits:=Module[{},
Subject`ElectricalEngineering;
AngleBracket=phasors`operator;
];
me`fps:=Module[{},
use`fps;
Subject`MechanicalEngineering;
];
me`si:=Module[{},
use`si;
Subject`MechanicalEngineering;
];
(* -Environment templates *)


(* Alias rule helpers *)
unitSym[sym_,name_,unit_]:=With[{symBox=ToBoxes@sym},InterpretationBox[TemplateBox[{"",symBox,name},"Quantity"],Quantity[unit],Selectable->False,Editable->False,SyntaxForm->Mod]];

unitValue[sym_,name_,value_,unit_]:=With[{symBox=ToBoxes@sym},InterpretationBox[TemplateBox[{"",symBox,name},"Quantity"],Quantity[value,unit],Selectable->False,Editable->False,SyntaxForm->Mod]];

unitRule[sym_,name_,unit_]:={sym->unitSym[sym,name,unit]};
unitRuleA[sym_,disp_,name_,unit_]:={sym->unitSym[disp,name,unit]};
(* -Alias rule helpers *)


(* Linear interpolator *)
lerp[α_,bmin_,bmax_]:=bmin+α(bmax-bmin);

lerpableQ[_?NumericQ|_Quantity]:=True;
lerpableQ[_]:=False;

(* call lerp on pairs of numbers or quantities *)
lerper[α_]={##}/.{{}:>lerp[α,0,1],{bmin_?lerpableQ,bmax_?lerpableQ}:>lerp[α,bmin,bmax]}&;

(* calculate quality and create a lerper *)
lerper[amin_,a_,amax_]:=lerper[((a-amin)/(amax-amin))/.q_Quantity->QuantityMagnitude[q]];

(* create a quality calculator for an unspecified value in a specified range *)
lerper[amin_,amax_]:=lerper[amin,#,amax]&;

lerpBox:=InterpretationBox[TemplateBox[{"","\"lerp\"","linear interpolate"},"Quantity"],lerper,Selectable->False,Editable->False,SyntaxForm->Mod]
(* -Linear interpolator *)

converterBox[display_,help_,fn_]:=With[{displayBox=ToBoxes[display]},
InterpretationBox[
TemplateBox[{"",displayBox,help},"Quantity"],fn,Selectable->False,Editable->False,SyntaxForm->Mod]
]

Times[T_,to`kelvin]^:=UnitConvert[T,"Kelvin"]
toKelvinBox:=converterBox["⟶ K", "to Kelvin", to`kelvin]

Times[T_,to`celsius]^:=UnitConvert[T,"Celsius"]
toCelsiusBox:=converterBox["⟶ °C", "to °C", to`celsius]

Times[x_,to`specificEnergy]^:=UnitConvert[x,"Kilojoules"/"Kilograms"]
toSpecificEnergyBox:=converterBox["⟶ kJ/kg","to specific energy",to`specificEnergy]

(*SetAttributes[RightTeeArrow,HoldRest];*)
ClearAll[RightTeeArrow];
RightTeeArrow[from_Quantity,to_Quantity]:=UnitConvert[from,QuantityUnit@to]
RightTeeArrow[from:{__Quantity},to_Quantity]:=UnitConvert[#,QuantityUnit@to]&/@from
(*
RightTeeArrow[from_Quantity,to_]:=RightTeeArrow[from,Evaluate[to]]
*)

(* General aliases *)
SetOptions[EvaluationNotebook[],InputAliases->DeleteDuplicates@Join[
{"to"->FromCharacterCode[8614]},
{"'"->FromCharacterCode[700]},
{"''"->FromCharacterCode[700]<>FromCharacterCode[700]},
{"y`"->FromCharacterCode[FromDigits["1EF9",16]]},
{"y-"->FromCharacterCode[FromDigits["0233",16]]},
{"isin"->"∈"},
unitRuleA["sec","s","seconds","Seconds"],
unitRule["min","minutes","Minutes"],
unitRuleA["hr","h","hours","Hours"],
unitRule["yr","years","Years"],
unitRuleA["hz","Hz","hertz","Hertz"],
{"sumof"->InterpretationBox[TemplateBox[{"","\"∑\"","sum of"},"Quantity"],Total,Selectable->False,Editable->False,SyntaxForm->Mod]},
{"lerp"->lerpBox},
{"lp"->lerpBox},
InputAliases/.Quiet[Options[EvaluationNotebook[],InputAliases]]/.InputAliases->{}]];
(* -General aliases *)

(* Maybe a nice fraction form DisplayForm@AdjustmentBox[Style[FractionBox["kg","s",Beveled->True],FontSize->14],BoxMargins->{{.1,0},{0,0}}] *)

SetAttributes[varBoxRule,HoldAllComplete];
varBoxRule[var_,alias_,symbol_,help_]:=(
attr=Attributes[var];
Unprotect[Unevaluated@var];
var/:MakeBoxes[var,StandardForm]:=ToBoxes@symbol;
SetAttributes[Unevaluated@var,attr];
Return[{alias->InterpretationBox[PaneBox[symbol,BaselinePosition->Baseline],var,Selectable->False,Editable->False,SyntaxForm->Mod]}]
)

SetAttributes[varBoxRuleA,HoldAllComplete];
varBoxRuleA[var_,symbol_,help_]:=varBoxRule[var, SymbolName[Unevaluated@var],symbol, help]

Unprotect[tensor,"tensor`*"];
ClearAll[tensor,"tensor`*"];

tensor/:MakeBoxes[tensor[m_List],StandardForm]:=ToBoxes[MatrixForm[m]]

General::timesisntmultiply="Multiply tensors with the . operator";

tensor/:HoldPattern[tensor[m_]tensor[n_]]:=tensor[m n]
tensor/:HoldPattern[tensor[m_]x_]:=tensor[m x]

tensor/:HoldPattern[tensor[m_] . tensor[n_]]:=tensor[m . n]
tensor/:HoldPattern[tensor[m_] . x_]:=tensor[m . x]
tensor/:HoldPattern[x_ . tensor[m_]]:=tensor[x . m]

tensor/:HoldPattern[tensor[m_]+tensor[n_]]:=tensor[m+n]

tensor/:tensor[m_]\[Transpose]:=tensor[m\[Transpose]]

tensor/:BracketingBar[tensor[m_]]:=Norm[m]

(* Allow destructuring into a 1-2D list of symbols *)
tensor/:HoldPattern[Set[l:{(__Symbol|{__Symbol})..},tensor[m_]]]:=tensor[Set[l,m]]

(* Allow chained assignment with a destructuring group in the middle,
e.g. σ =(({{σx}, {σy}}))=(({{1}, {2}})) ⟶ {σx,σy}={1,2} and σ =(({{1}, {2}})) *)
tensor/:HoldPattern[Set[tensor[l:{(__Symbol|{__Symbol})..}],tensor[m_]]]:=tensor[Set[l,m]]

General::tensoroutofrange="Tensor subscript `1` is out of range of `2`x`3`";

(*
indexSubscripts={{"xx",11},{"xy",12},{"xz",13},{"yx",21},{"yy",22},{"yz",23},{"zx",31},{"zy",32},{"zz",33}};
indexSubscriptPatterns=(s_Symbol^_./;StringMatchQ[SymbolName[Unevaluated@s],#[[1]]]->#[[2]])&/@indexSubscripts;

SetAttributes[Subscript,HoldRest];
tensor/:HoldPattern[(Subscript[tensor[m_], k_])]:=
With[{ij=ReleaseHold[Hold[k]/.indexSubscriptPatterns]},
*)

tensor/:HoldPattern[(Subscript[tensor[m_], ij_])]:=
Block[{dims=Dimensions[m,2],digits=IntegerDigits[ij],i,j},
If[Length[digits]<2,(Message[General::tensoroutofrange,ij,dims[[1]],dims[[2]]];Return[])];
i=digits[[1]];j=digits[[2]];
If[
i<1||j<1||i>dims[[1]]||j>dims[[2]],
Message[General::tensoroutofrange,ij,dims[[1]],dims[[2]]],m[[i,j]]
]
]

tensor/:((tensor[m_])^tensor`tolist):=m
tensors=ToBoxes[MatrixForm[#]]&/@\[LeftAssociation]21->(({{\[Placeholder]}, {\[Placeholder]}})),22->(({{\[Placeholder], \[Placeholder]}, {\[Placeholder], \[Placeholder]}})),31->(({{\[Placeholder]}, {\[Placeholder]}, {\[Placeholder]}})),33->(({{\[Placeholder], \[Placeholder], \[Placeholder]}, {\[Placeholder], \[Placeholder], \[Placeholder]}, {\[Placeholder], \[Placeholder], \[Placeholder]}}))\[RightAssociation];
tensor`Identity3=(({{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}));

Protect[tensor,"tensor`*"];

Unprotect[dump];
ClearAll[dump]
SetAttributes[dump,{HoldAll}];
dump[s_]:=SymbolName[Unevaluated@s]->s
dump[s__]:=dump@{s}
dump[s_List]:=dump/@Unevaluated@s//(Grid[
(#/.(a_->c_):>{a,"->",c}),
Alignment->{{Right,Left,Left}}
]&)
Protect[dump];

Subject`MechanicalEngineering:=
Module[{},
SetOptions[EvaluationNotebook[],InputAliases->DeleteDuplicates@Join[
{"dump"->InterpretationBox["(Underscript[dump, column])",dump,Editable->False,Selectable->False]},
varBoxRule[Tensorσ,"[s","[σ]","tensor"],
varBoxRule[Tensorσʼ,"[s'","[σ]^(′)","tensor"],
varBoxRule[TensorT,"[T","[T]","tensor"],
varBoxRule[tensor`Identity3,"[i3","[I]_3","3x3 identity tensor"],

{"[l"->InterpretationBox["L",tensor`tolist,Selectable->False,Editable->False,SyntaxForm->Mod]},
{"[]"->InterpretationBox["[mxn]",tensor,Selectable->False,Editable->False,SyntaxForm->Mod]},

{"3x1"->TagBox[tensors[31],tensor]},
{"3x3"->TagBox[tensors[33],tensor]},
{"2x1"->TagBox[tensors[21],tensor]},
{"2x2"->TagBox[tensors[22],tensor]},

varBoxRuleA[dm,"(OverDot[m])","mass rate"],
varBoxRuleA[dm1,"(Subscript[(OverDot[m]), 1])","mass rate 1"],
varBoxRuleA[dm2,"(Subscript[(OverDot[m]), 2])","mass rate 2"],
varBoxRuleA[dm3,"(Subscript[(OverDot[m]), 3])","mass rate 3"],
varBoxRuleA[dm4,"(Subscript[(OverDot[m]), 4])","mass rate 4"],
varBoxRuleA[dmn,"(Subscript[(OverDot[m]), n])","mass rate n"],
varBoxRuleA[dx1,"(OverDot[x])(Subscript[, 1])","velocity 1"],
varBoxRuleA[dx2,"(OverDot[x])(Subscript[, 2])","velocity 2"],
varBoxRuleA[dx3,"(OverDot[x])(Subscript[, 3])","velocity 3"],
varBoxRuleA[dx4,"(OverDot[x])(Subscript[, 4])","velocity 4"],
varBoxRuleA[dV,"(OverDot[V])","volume rate"],
varBoxRuleA[dV1,"(OverDot[V])(Subscript[, 1])","volume rate 1"],
varBoxRuleA[dV2,"(OverDot[V])(Subscript[, 2])","volume rate 2"],
varBoxRuleA[dV3,"(OverDot[V])(Subscript[, 3])","volume rate 3"],
varBoxRuleA[dV4,"(OverDot[V])(Subscript[, 4])","volume rate 4"],
varBoxRuleA[dQ,"(OverDot[Q])","heat rate"],
varBoxRuleA[dQ1,"(OverDot[Q])(Subscript[, 1])","heat rate 1"],
varBoxRuleA[dQ2,"(OverDot[Q])(Subscript[, 2])","heat rate 2"],
varBoxRuleA[dQ3,"(OverDot[Q])(Subscript[, 3])","heat rate 3"],
varBoxRuleA[dQ4,"(OverDot[Q])(Subscript[, 4])","heat rate 4"],
varBoxRuleA[dQn,"(OverDot[Q])(Subscript[, n])","heat rate n"],
varBoxRuleA[dQh,"(OverDot[Q])(Subscript[, H])","heat rate (high-temp)"],
varBoxRuleA[dQl,"(OverDot[Q])(Subscript[, L])","heat rate (low-temp)"],
varBoxRuleA[dq,"(OverDot[q])","specific heat rate"],
varBoxRuleA[dq1,"(OverDot[q])(Subscript[, 1])","specific heat rate 1"],
varBoxRuleA[dq2,"(OverDot[q])(Subscript[, 2])","specific heat rate 2"],
varBoxRuleA[dq3,"(OverDot[q])(Subscript[, 3])","specific heat rate 3"],
varBoxRuleA[dq4,"(OverDot[q])(Subscript[, 4])","specific heat rate 4"],
varBoxRuleA[dqn,"(OverDot[q])(Subscript[, n])","specific heat rate n"],
varBoxRuleA[dW,"(OverDot[W])","work rate"],
varBoxRuleA[dW1,"(OverDot[W])(Subscript[, 1])","work rate 1"],
varBoxRuleA[dW2,"(OverDot[W])(Subscript[, 2])","work rate 2"],
varBoxRuleA[dW3,"(OverDot[W])(Subscript[, 3])","work rate 3"],
varBoxRuleA[dW4,"(OverDot[W])(Subscript[, 4])","work rate 4"],
varBoxRuleA[dWn,"(OverDot[W])(Subscript[, n])","work rate n"],
varBoxRuleA[dWin,"(OverDot[W])(Subscript[, in])","work rate in"],
varBoxRuleA[dWout,"(OverDot[W])(Subscript[, out])","work rate out"],
varBoxRuleA[dw,"(OverDot[w])","specific work rate"],
varBoxRuleA[dw1,"(OverDot[w])(Subscript[, 1])","specific work rate 1"],
varBoxRuleA[dw2,"(OverDot[w])(Subscript[, 2])","specific work rate 2"],
varBoxRuleA[dw3,"(OverDot[w])(Subscript[, 3])","specific work rate 3"],
varBoxRuleA[dw4,"(OverDot[w])(Subscript[, 4])","specific work rate 4"],
varBoxRuleA[dwn,"(OverDot[w])(Subscript[, n])","specific work rate n"],
{"toC"->toCelsiusBox},
{"tok"->toKelvinBox},
{"tokj/kg"->toSpecificEnergyBox},
{"gsi"->unitValue["g","acceleration due to gravity (SI)",9.81,"Meters"/"Seconds"^2]},
{"stefan"->unitValue["σ","Stefan-Boltzmann constant",5.67 (10^(-8)),(("Watts")/("Meters"^2 "Kelvins"^4))]},
{"d'"->"δʼ"},
{"dia"->"⌀"},
{"sp"->"σp"},
{"sp1"->"σp1"},
{"sp2"->"σp2"},
{"sp3"->"σp3"},
{"sx"->"σx"},
{"sy"->"σy"},
{"sz"->"σz"},
{"sx'"->"σxʼ"},
{"sy'"->"σyʼ"},
{"sz'"->"σzʼ"},
{"tmax"->"τmax"},
{"txy"->"τxy"},
{"tyz"->"τyz"},
{"txz"->"τxz"},
{"txy'"->"τxʼyʼ"},
{"ex"->"ϵx"},
{"ey"->"ϵy"},
{"e1"->"ϵ1"},
{"e2"->"ϵ2"},
{"gxy"->"γxy"},
{"gxy'"->"γxʼyʼ"},
{"gpa"->unitSym["GPa","gigapascals","Gigapascals"]},
{"mpa"->unitSym["MPa","megapascals","Megapascals"]},

unitRule["%","percent","Percent"],
unitRuleA["kpa","kPa","kilopascals","Kilopascals"],
unitRuleA["pa","Pa","pascals","Pascals"],
unitRule["kip","kips-force","KipsForce"],
unitRule["ksi","kips/(inch^2)","KipsForce"/"Inches"^2],
unitRule["bar","bars","Bars"],
unitRule["mbar","millibars","Millibars"],
(* use [esc]ps[esc] for ψ *)
unitRule["psi","pounds-force/(inch^2)","PoundsForce"/"Inches"^2],
unitRuleA["watts","W","watts","Watts"],
unitRuleA["kw","kW","kilowatts","Kilowatts"],
unitRuleA["kn","kN","kilonewtons","Kilonewtons"],
unitRuleA["knm","kN·m","kilonewton-meters","Kilonewtons"*"Meters"],
unitRuleA["N","N","newtons","Newtons"],
unitRuleA["Nm","N·m","newton-meters",
"Newtons"*"Meters"],
unitRule["kg","kilograms","Kilograms"],
unitRule["m/s","meters per second",(("Meters")/("Seconds"))],
unitRuleA["m3/s","(m^3)/s","cubic meters per second","Meters"^3/"Seconds"],
unitRuleA["l/s","L/s","liters per second","Liters"/"Seconds"],
unitRuleA["l/min","L/min","liters per minute","Liters"/"Minutes"],
unitRuleA["l/h","L/h","liters per hour","Liters"/"Hours"],
unitRuleA["m3/min","(m^3)/min","cubic meters per minute","Meters"^3/"Minutes"],
unitRuleA["m3/h","(m^3)/h","cubic meters per hour","Meters"^3/"Hours"],
unitRuleA["kg/s","kg/s","kilograms per second","Kilograms"/"Seconds"],
unitRuleA["kg/min","kg/min","kilograms per minute","Kilograms"/"Minutes"],
unitRuleA["kg/h","kg/h","kilograms per hour","Kilograms"/"Hours"],
unitRuleA["kj/h","kJ/h","kilojoules per hour","Kilojoules"/"Hours"],
unitRuleA["kj/min","kJ/min","kilojoules per minute","Kilojoules"/"Minutes"],
unitRuleA["kj/s","kJ/s","kilojoules per second","Kilojoules"/"Seconds"],
unitRuleA["kj/kg","kJ/kg","kilojoules per kilogram","Kilojoules"/"Kilograms"],
unitRuleA["kj/kgk","kJ/kg·K","Kilojoules per kilogram-Kelvin","Kilojoules"/("Kilograms"*"Kelvins")],
unitRuleA["kj/kgc","kJ/kg·°C","Kilojoules per kilogram-°Celsius","Kilojoules"/("Kilograms"*"Celsius")],
unitRuleA["kj/k","kJ/K","kilojoules per Kelvin","Kilojoules"/"Kelvins"],
unitRuleA["kpam3/kgk","kPa·(m^3)/kg·K","Ideal gas constant",("Kilopascals"*"Meters"^3)/("Kilograms"*"Kelvins")],
unitRuleA["m3/kg","(m^3)/kg","cubic meters per kilogram","Meters"^3/"Kilograms"],
unitRuleA["kg/m3","kg/(m^3)","kilograms per cubic meter","Kilograms"/"Meters"^3],
unitRuleA["gram","g","grams","Grams"],
unitRuleA["g/cm3","g/(cm^3)","grams per cubic centimeter","Grams"/"Centimeters"^3],
unitRule["lb","pounds-force","PoundsForce"],
unitRuleA["lbf","lb","pounds-force","PoundsForce"],
unitRuleA["ftlb","lb·ft","foot-pounds","PoundsForce"*"Feet"],
unitRuleA["lbft","lb·ft","foot-pounds","PoundsForce"*"Feet"],
unitRule["mm","millimeters","Millimeters"],
unitRule["cm","centimeters","Centimeters"],
unitRule["m","meters","Meters"],
unitRuleA["m3","(m^3)","cubic meters","Meters"^3],
unitRuleA["cm2","(cm^2)","square centimeters","Centimeters"^2],
unitRuleA["liter","L","liters","Liters"],
unitRule["in","inches","Inches"],
unitRule["ft","feet","Feet"],
unitRule["mph","miles per hour",(("Miles")/("Hours"))],
unitRule["km/h","kilometers per hour",(("Kilometers")/("Hours"))],
unitRuleA["degf","°F","degrees Fahrenheit","DegreesFahrenheit"],
unitRuleA["degc","°C","degrees Celsius","DegreesCelsius"],
unitRuleA["degr","°R","degrees Rankine","DegreesRankine"],unitRuleA["kelvin","K","kelvin","Kelvins"],
{"in2"->unitSym["(in^2)","square-inches","Inches"^2]},
unitRule["J","joules","Joules"],
unitRuleA["kj","kJ","kilojoules","Kilojoules"],
unitRuleA["btu","BTU","British thermal units","ISOBritishThermalUnits"],
unitRuleA["btu/h","BTU/h","British thermal units per hour",(("ISOBritishThermalUnits")/("Hours"))],
unitRule["hp","horsepower","Horsepower"],
unitRuleA["W/mC","W/m·°C","Watts per meter-degree Celsius","Watts"/("Meters"*"DegreesCelsius")],
unitRuleA["W/m2C","W/(m^2)·°C","Watts per square meter-degree Celsius","Watts"/("Meters"^2*"DegreesCelsius")],
{"||R"->SuperscriptBox[RowBox[{"(",RowBox[{FractionBox["1","\[Placeholder]"],"+",FractionBox["1","\[Placeholder]"]}],")"}],RowBox[{"-","1"}]]},
{"|||R"->SuperscriptBox[RowBox[{"(",RowBox[{FractionBox["1","\[Placeholder]"],"+",FractionBox["1","\[Placeholder]"],"+",FractionBox["1","\[Placeholder]"]}],")"}],RowBox[{"-","1"}]]},
{"||||R"->SuperscriptBox[RowBox[{"(",RowBox[{FractionBox["1","\[Placeholder]"],"+",FractionBox["1","\[Placeholder]"],"+",FractionBox["1","\[Placeholder]"],"+",FractionBox["1","\[Placeholder]"]}],")"}],RowBox[{"-","1"}]]},
{"oh"->InterpretationBox[TemplateBox[{"","\"Ω\"","ohms"},"Quantity"],Quantity["Ohms"],Selectable->False,Editable->False,SyntaxForm->Mod]},
{"koh"->InterpretationBox[TemplateBox[{"","\"kΩ\"","kilohms"},"Quantity"],Quantity["Kiloohms"],Selectable->False,Editable->False,SyntaxForm->Mod]},
{"moh"->InterpretationBox[TemplateBox[{"","\"MΩ\"","megohms"},"Quantity"],Quantity["Megohms"],Selectable->False,Editable->False,SyntaxForm->Mod]},
{"A"->InterpretationBox[TemplateBox[{"","\"A\"","amperes"},"Quantity"],Quantity["Amperes"],Selectable->False,Editable->False,SyntaxForm->Mod]},
{"ma"->InterpretationBox[TemplateBox[{"","\"mA\"","milliamperes"},"Quantity"],Quantity["Milliamperes"],Selectable->False,Editable->False,SyntaxForm->Mod]},
{"ua"->InterpretationBox[TemplateBox[{"","\"μA\"","microamperes"},"Quantity"],Quantity["Microamperes"],Selectable->False,Editable->False,SyntaxForm->Mod]},
{"V"->InterpretationBox[TemplateBox[{"","\"V\"","volts"},"Quantity"],Quantity["Volts"],Selectable->False,Editable->False,SyntaxForm->Mod]},
{"mv"->InterpretationBox[TemplateBox[{"","\"mV\"","millivolts"},"Quantity"],Quantity["Millivolts"],Selectable->False,Editable->False,SyntaxForm->Mod]},
unitRuleA["F","F","farads","Farads"],
unitRuleA["mf","mF","millifarads","Millifarads"],
unitRuleA["uf","μF","microfarads","Microfarads"],
unitRuleA["mh","mH","millihenries","Millihenries"],
unitRule["H","henries","Henries"],
unitRuleA["rads","rad/s","radians/second", "Hertz"],

InputAliases/.Quiet[Options[EvaluationNotebook[],InputAliases]]/.InputAliases->{}]];
];
(* -Subject`MechanicalEngineering *)


is`possible[t_]:=If[t,"Possible","Impossible"]


(* Plotting helpers *)
(* Convert a set of rules {variable -> quantity, ...} to plot axis labels {"variable (unit)", ...} *)
to`AxisLabels = #/.((a_->b_):>Row[{a," ",QuantityForm@QuantityUnit@b}])&;

style`size[pt_]:=#/.(label_:>Style[label,FontSize->pt])&;
(* -Plotting helpers *)