(* Content-type: application/vnd.wolfram.mathematica *)

(*** Wolfram Notebook File ***)
(* http://www.wolfram.com/nb *)

(* CreatedBy='Mathematica 9.0' *)

(*CacheID: 234*)
(* Internal cache information:
NotebookFileLineBreakTest
NotebookFileLineBreakTest
NotebookDataPosition[       157,          7]
NotebookDataLength[    130269,       3390]
NotebookOptionsPosition[    124441,       3271]
NotebookOutlinePosition[    125056,       3294]
CellTagsIndexPosition[    124987,       3289]
WindowFrame->Normal*)

(* Beginning of Notebook Content *)
Notebook[{

Cell[CellGroupData[{
Cell["GeoChem", "Title",ExpressionUUID->"c97a224d-fcf5-4202-83b1-14554b0cdb30"],

Cell[CellGroupData[{

Cell["Begin package", "Section",ExpressionUUID->"26c421db-f3e3-40fa-86e3-0ff6be85e13c"],

Cell[BoxData[
 RowBox[{
  RowBox[{"BeginPackage", "[", 
   RowBox[{"\"\<DataAnalysis`GeoChem`\>\"", ",", 
    RowBox[{"{", "\"\<DataAnalysis`\>\"", "}"}]}], "]"}], ";"}]], "Input",
 InitializationCell->
  True,ExpressionUUID->"69c3d4b3-60ab-45dc-af35-e47599e403d4"],

Cell[BoxData[
 RowBox[{
  RowBox[{"Unprotect", "[", 
   RowBox[{"Evaluate", "[", 
    RowBox[{"$Context", "<>", "\"\<*\>\""}], "]"}], "]"}], ";"}]], "Input",
 InitializationCell->
  True,ExpressionUUID->"65587c63-6581-4070-a83c-9e0fd6dcd451"]
}, Open  ]],

Cell[CellGroupData[{

Cell["Messages", "Section",ExpressionUUID->"7a61416e-3cc7-4b69-80ed-a695703d2114"],

Cell[CellGroupData[{

Cell["Functions", "Subsection",ExpressionUUID->"66216aa4-f3fc-402e-a4b6-1089cb504a43"],

Cell[BoxData[{
 RowBox[{"ConvertComps", ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{"MinFormulaCations", ";"}], "\[IndentingNewLine]", 
  RowBox[{"(*", 
   RowBox[{"CombineFMO", ";"}], "*)"}]}], "\[IndentingNewLine]", 
 RowBox[{"MolarMass", ";"}], "\[IndentingNewLine]", 
 RowBox[{"RegisterComp", ";"}], "\[IndentingNewLine]", 
 RowBox[{"RegisterOxide", ";"}], "\[IndentingNewLine]", 
 RowBox[{"PhaseMolarMass", ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{"ChemElementName", ";"}], 
  "\[IndentingNewLine]"}], "\[IndentingNewLine]", 
 RowBox[{"MassToMoles", ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{"MolesToMass", ";"}], 
  "\[IndentingNewLine]"}], "\[IndentingNewLine]", 
 RowBox[{"MassFractionToMolality", ";"}], "\[IndentingNewLine]", 
 RowBox[{"MassFractionTomMolality", ";"}], "\[IndentingNewLine]", 
 RowBox[{"PpmToMolality", ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{"PpmTomMolality", ";"}], 
  "\[IndentingNewLine]"}], "\[IndentingNewLine]", 
 RowBox[{"MolalityToMassFraction", ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{"MolalityToPpm", ";"}], 
  "\[IndentingNewLine]"}], "\[IndentingNewLine]", 
 RowBox[{"OxideName", ";"}]}], "Input",
 InitializationCell->
  True,ExpressionUUID->"d48abef0-0330-487f-a040-d5e8a4b3c0cc"]
}, Open  ]],

Cell[CellGroupData[{

Cell["Options", "Subsection",ExpressionUUID->"bfa018fa-2dca-4c2b-8dc1-c73b1bbf507b"],

Cell[BoxData[{
 RowBox[{"FromMolarData", ";"}], "\[IndentingNewLine]", 
 RowBox[{"ToMolarData", ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{"ProjectFrom", ";"}], "\[IndentingNewLine]", 
  RowBox[{"(*", 
   RowBox[{"ReduceFe", ";", "\[IndentingNewLine]", "OxidizeFe", ";"}], 
   "*)"}]}], "\[IndentingNewLine]", 
 RowBox[{"ToFractions", ";"}], "\[IndentingNewLine]", 
 RowBox[{"ToPercent", ";"}], "\[IndentingNewLine]", 
 RowBox[{"Synonyms", ";"}]}], "Input",
 InitializationCell->
  True,ExpressionUUID->"8ad1cd10-02dc-46db-b94e-faca512fa9a7"]
}, Open  ]]
}, Open  ]],

Cell[CellGroupData[{

Cell["Begin private context", "Section",ExpressionUUID->"c1b5f50b-8e9b-47f3-8e97-78c734db31a8"],

Cell[BoxData[
 RowBox[{
  RowBox[{"Begin", "[", "\"\<`Private`\>\"", "]"}], ";"}]], "Input",
 InitializationCell->
  True,ExpressionUUID->"48b81d6f-3536-4ff3-ac9a-384f94baf213"]
}, Closed]],

Cell[CellGroupData[{

Cell["Error handling", "Section",ExpressionUUID->"aacfa499-cce1-435f-939e-915e50a77731"],

Cell[BoxData[{
 RowBox[{
  RowBox[{"SetAttributes", "[", 
   RowBox[{"ErrorMessage", ",", "HoldFirst"}], "]"}], 
  ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{
    RowBox[{"ErrorMessage", "[", "Args___", "]"}], ":=", 
    RowBox[{"Module", "[", "\[IndentingNewLine]", 
     RowBox[{
      RowBox[{"{", "}"}], ",", "\[IndentingNewLine]", 
      RowBox[{
       RowBox[{"Message", "[", "Args", "]"}], ";", "\[IndentingNewLine]", 
       RowBox[{"Abort", "[", "]"}], ";"}]}], "\[IndentingNewLine]", "]"}]}], 
   ";"}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{"SetAttributes", "[", 
   RowBox[{"WarningMessage", ",", "HoldFirst"}], "]"}], 
  ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"WarningMessage", "[", "Args___", "]"}], ":=", 
   RowBox[{"Module", "[", "\[IndentingNewLine]", 
    RowBox[{
     RowBox[{"{", "}"}], ",", "\[IndentingNewLine]", 
     RowBox[{
      RowBox[{"Message", "[", "Args", "]"}], ";"}]}], "\[IndentingNewLine]", 
    "]"}]}], ";"}]}], "Input",
 InitializationCell->
  True,ExpressionUUID->"e91e189f-ba8c-44bc-a907-d3b23725056f"],

Cell[BoxData[{
 RowBox[{
  RowBox[{"SetAttributes", "[", 
   RowBox[{"CatchError", ",", "HoldAll"}], "]"}], 
  ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"CatchError", "[", "Body_", "]"}], ":=", 
   RowBox[{"(", 
    RowBox[{
     RowBox[{"Catch", "[", "Body", "]"}], "===", "$ErrorFlag"}], ")"}]}], 
  ";"}]}], "Input",
 InitializationCell->
  True,ExpressionUUID->"8e515af0-a891-42ad-87ac-ca89ed41f648"]
}, Open  ]],

Cell[CellGroupData[{

Cell["Component matrix tools", "Section",
 CellTags->"Null",ExpressionUUID->"40fa656c-1423-4488-a500-27624f3cfb13"],

Cell[BoxData[{
 RowBox[{
  RowBox[{"OxideCoefficients", "=", 
   RowBox[{"{", "}"}]}], ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{"CDefs", "=", 
   RowBox[{"DataTable", "[", 
    RowBox[{"<|", "|>"}], "]"}]}], ";"}]}], "Input",
 InitializationCell->
  True,ExpressionUUID->"d2600751-ce16-49f0-883c-0024cb6204c1"],

Cell[BoxData[{
 RowBox[{
  RowBox[{
   RowBox[{
    RowBox[{"BuildCMatrix", "[", "]"}], ":=", 
    RowBox[{"Module", "[", 
     RowBox[{
      RowBox[{"{", 
       RowBox[{
       "IDM", ",", "OM", ",", "CElements", ",", "Out", ",", "CDefsSyns", ",", 
        "SynRow"}], "}"}], ",", 
      RowBox[{"(", "\[IndentingNewLine]", 
       RowBox[{
        RowBox[{"Out", "=", 
         RowBox[{"CDefs", "//", "ToArray"}]}], ";", "\[IndentingNewLine]", 
        RowBox[{"Out", "=", 
         RowBox[{"Out", "/.", 
          RowBox[{
           RowBox[{"Missing", "[", "___", "]"}], "\[Rule]", "0"}]}]}], ";", 
        "\[IndentingNewLine]", "\[IndentingNewLine]", 
        RowBox[{"CElements", "=", 
         RowBox[{
          RowBox[{"Out", "//", "First"}], "//", "Rest"}]}], ";", 
        "\[IndentingNewLine]", "\[IndentingNewLine]", 
        RowBox[{"IDM", "=", 
         RowBox[{
          RowBox[{"Prepend", "[", 
           RowBox[{
            RowBox[{"IdentityMatrix", "[", 
             RowBox[{"CElements", "//", "Length"}], "]"}], ",", "CElements"}],
            "]"}], "//", "Transpose"}]}], ";", "\[IndentingNewLine]", 
        "\[IndentingNewLine]", 
        RowBox[{
         RowBox[{"(", 
          RowBox[{"Out", "~", "Join", "~", "IDM"}], ")"}], "//", 
         "Transpose"}]}], "\[IndentingNewLine]", "\[IndentingNewLine]", 
       RowBox[{"(*", 
        RowBox[{
         RowBox[{"COxides", "=", 
          RowBox[{"CDefs", "[", 
           RowBox[{"[", 
            RowBox[{"1", ",", 
             RowBox[{"2", ";;"}]}], "]"}], "]"}]}], ";", 
         "\[IndentingNewLine]", "\[IndentingNewLine]", 
         RowBox[{"IDM", "=", 
          RowBox[{
           RowBox[{"Prepend", "[", 
            RowBox[{
             RowBox[{"IdentityMatrix", "[", 
              RowBox[{"COxides", "//", "Length"}], "]"}], ",", "COxides"}], 
            "]"}], "//", "Transpose"}]}], ";", "\[IndentingNewLine]", 
         RowBox[{"OM", "=", 
          RowBox[{"(", 
           RowBox[{
            RowBox[{
             RowBox[{"ReplacePart", "[", 
              RowBox[{
               RowBox[{
                RowBox[{"{", 
                 RowBox[{
                  RowBox[{"#", "[", 
                   RowBox[{"[", "2", "]"}], "]"}], ",", 
                  RowBox[{
                   RowBox[{
                    RowBox[{"-", 
                    RowBox[{"#", "[", 
                    RowBox[{"[", "4", "]"}], "]"}]}], "/", "2"}], "/", 
                   RowBox[{"#", "[", 
                    RowBox[{"[", "3", "]"}], "]"}]}]}], "}"}], "~", "Join", 
                "~", 
                RowBox[{"Table", "[", 
                 RowBox[{"0", ",", 
                  RowBox[{"{", 
                   RowBox[{
                    RowBox[{"Length", "[", "COxides", "]"}], "-", "1"}], 
                   "}"}]}], "]"}]}], ",", 
               RowBox[{
                RowBox[{"(", 
                 RowBox[{
                  RowBox[{"Position", "[", 
                   RowBox[{"COxides", ",", 
                    RowBox[{"#", "[", 
                    RowBox[{"[", "1", "]"}], "]"}]}], "]"}], "+", "1"}], 
                 ")"}], "\[Rule]", 
                RowBox[{"1", "/", 
                 RowBox[{"#", "[", 
                  RowBox[{"[", "3", "]"}], "]"}]}]}]}], "]"}], "&"}], "/@", 
            RowBox[{"(", 
             RowBox[{"OxideCoefficients", "//", "Rest"}], ")"}]}], ")"}]}], 
         ";", "\[IndentingNewLine]", "\[IndentingNewLine]", 
         RowBox[{"CDefsSyns", "=", 
          RowBox[{"{", "}"}]}], ";", "\[IndentingNewLine]", 
         RowBox[{"Scan", "[", 
          RowBox[{
           RowBox[{
            RowBox[{"(", "\[IndentingNewLine]", 
             RowBox[{
              RowBox[{"SynRow", "=", 
               RowBox[{
                RowBox[{"Cases", "[", 
                 RowBox[{"CDefs", ",", 
                  RowBox[{"{", 
                   RowBox[{
                    RowBox[{"#", "//", "First"}], ",", "__"}], "}"}]}], "]"}],
                 "//", "First"}]}], ";", "\[IndentingNewLine]", 
              "\[IndentingNewLine]", 
              RowBox[{"CDefsSyns", "=", 
               RowBox[{"CDefsSyns", "~", "Join", "~", 
                RowBox[{"(", 
                 RowBox[{
                  RowBox[{
                   RowBox[{"(", 
                    RowBox[{"ReplacePart", "[", 
                    RowBox[{"SynRow", ",", 
                    RowBox[{"1", "\[Rule]", "#"}]}], "]"}], ")"}], "&"}], "/@", 
                  RowBox[{"(", 
                   RowBox[{"#", "//", "Rest"}], ")"}]}], ")"}]}]}], ";"}], 
             "\[IndentingNewLine]", ")"}], "&"}], ",", "CSynonyms"}], "]"}], 
         ";", "\[IndentingNewLine]", "\[IndentingNewLine]", 
         RowBox[{"Out", "=", 
          RowBox[{"CDefs", "~", "Join", "~", "CDefsSyns"}]}], ";", 
         "\[IndentingNewLine]", "\[IndentingNewLine]", 
         RowBox[{"Unprotect", "[", "MolarMass", "]"}], ";", 
         "\[IndentingNewLine]", "\[IndentingNewLine]", 
         RowBox[{"Scan", "[", 
          RowBox[{
           RowBox[{
            RowBox[{"(", 
             RowBox[{
              RowBox[{"MolarMass", "[", 
               RowBox[{"#", "[", 
                RowBox[{"[", "1", "]"}], "]"}], "]"}], "=", 
              RowBox[{
               RowBox[{
                RowBox[{"MolarMass", "[", 
                 RowBox[{"#", "[", 
                  RowBox[{"[", "2", "]"}], "]"}], "]"}], "*", 
                RowBox[{"#", "[", 
                 RowBox[{"[", "3", "]"}], "]"}]}], "+", 
               RowBox[{
                RowBox[{"MolarMass", "[", "\"\<O\>\"", "]"}], "*", 
                RowBox[{"#", "[", 
                 RowBox[{"[", "4", "]"}], "]"}]}]}]}], ")"}], "&"}], ",", 
           "OxideCoefficients"}], "]"}], ";", "\[IndentingNewLine]", 
         "\[IndentingNewLine]", 
         RowBox[{"Scan", "[", 
          RowBox[{
           RowBox[{
            RowBox[{"(", 
             RowBox[{
              RowBox[{"MolarMass", "[", 
               RowBox[{"#", "[", 
                RowBox[{"[", "1", "]"}], "]"}], "]"}], "=", 
              RowBox[{"Total", "[", 
               RowBox[{"MapIndexed", "[", 
                RowBox[{
                 RowBox[{
                  RowBox[{
                   RowBox[{"MolarMass", "[", 
                    RowBox[{"(", 
                    RowBox[{
                    RowBox[{"Out", "[", 
                    RowBox[{"[", 
                    RowBox[{"1", ",", 
                    RowBox[{"#2", "+", "1"}]}], "]"}], "]"}], "//", "First"}],
                     ")"}], "]"}], "*", "#1"}], "&"}], ",", 
                 RowBox[{"#", "[", 
                  RowBox[{"[", 
                   RowBox[{"2", ";;"}], "]"}], "]"}]}], "]"}], "]"}]}], ")"}],
             "&"}], ",", 
           RowBox[{"(", 
            RowBox[{"Out", "//", "Rest"}], ")"}]}], "]"}], ";", 
         "\[IndentingNewLine]", "\[IndentingNewLine]", 
         RowBox[{"Protect", "[", "MolarMass", "]"}], ";", 
         "\[IndentingNewLine]", "\[IndentingNewLine]", 
         RowBox[{"(*", 
          RowBox[{"Total", "[", 
           RowBox[{"MapIndexed", "[", 
            RowBox[{
             RowBox[{
              RowBox[{
               RowBox[{"MolarMass", "[", 
                RowBox[{"(", 
                 RowBox[{
                  RowBox[{"Out", "[", 
                   RowBox[{"[", 
                    RowBox[{
                    RowBox[{"#2", "+", "1"}], ",", "1"}], "]"}], "]"}], "//", 
                  "First"}], ")"}], "]"}], "*", "#1"}], "&"}], ",", 
             RowBox[{"#", "[", 
              RowBox[{"[", 
               RowBox[{"2", ";;"}], "]"}], "]"}]}], "]"}], "]"}], "*)"}], 
         "\[IndentingNewLine]", 
         RowBox[{
          RowBox[{"(", 
           RowBox[{"Out", "~", "Join", "~", "IDM", "~", "Join", "~", "OM"}], 
           ")"}], "//", "Transpose"}]}], "*)"}], "\[IndentingNewLine]", 
       ")"}]}], "]"}]}], ";"}], 
  "\[IndentingNewLine]"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{"(*", 
   RowBox[{
    RowBox[{"CMatrix", "=", 
     RowBox[{"BuildCMatrix", "[", "]"}]}], ";"}], "*)"}]}]}], "Input",
 InitializationCell->
  True,ExpressionUUID->"70027a8c-9c77-404b-bfd6-40e77bf16c8f"],

Cell[BoxData[{
 RowBox[{
  RowBox[{
   RowBox[{
    RowBox[{"RegisterOxide", "::", "duplicate"}], "=", 
    "\"\<The oxide `1` is already registered.\>\""}], ";"}], 
  "\[IndentingNewLine]"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"RegisterOxide", "::", "usage"}], "=", 
   "\"\<RegisterOxide[element,c,ox] registers the oxide with the chemical \
formula \!\(\*SubscriptBox[\(element\), \(c\)]\)\!\(\*SubscriptBox[\(O\), \
\(ox\)]\) for later use with other functions.\>\""}], 
  ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"RegisterOxide", "[", 
    RowBox[{"element_", ",", "c_", ",", "o_"}], "]"}], ":=", 
   RowBox[{"Module", "[", 
    RowBox[{
     RowBox[{"{", "name", "}"}], ",", 
     RowBox[{"(", "\[IndentingNewLine]", 
      RowBox[{
       RowBox[{"name", "=", 
        RowBox[{
         RowBox[{"If", "[", 
          RowBox[{
           RowBox[{
            RowBox[{"c", ">", "1"}], "&&", 
            RowBox[{"StringMatchQ", "[", 
             RowBox[{"element", ",", 
              RowBox[{"__", "~~", "\"\<+\>\"", "~~", 
               RowBox[{"DigitCharacter", ".."}]}]}], "]"}]}], ",", 
           RowBox[{"\"\<(\>\"", "<>", "element", "<>", "\"\<)\>\"", "<>", 
            RowBox[{"ToString", "[", "c", "]"}]}], ",", 
           RowBox[{"element", "<>", 
            RowBox[{"If", "[", 
             RowBox[{
              RowBox[{"c", ">", "1"}], ",", 
              RowBox[{"ToString", "[", "c", "]"}], ",", "\"\<\>\""}], 
             "]"}]}]}], "]"}], "<>", "\"\<O\>\"", "<>", 
         RowBox[{"If", "[", 
          RowBox[{
           RowBox[{"o", ">", "1"}], ",", 
           RowBox[{"ToString", "[", "o", "]"}], ",", "\"\<\>\""}], "]"}]}]}], 
       ";", "\[IndentingNewLine]", 
       RowBox[{"If", "[", 
        RowBox[{
         RowBox[{"MemberQ", "[", 
          RowBox[{"OxideCoefficients", ",", 
           RowBox[{"{", 
            RowBox[{"name", ",", "_", ",", "_", ",", "_"}], "}"}]}], "]"}], 
         ",", "\[IndentingNewLine]", 
         RowBox[{
          RowBox[{"ErrorMessage", "[", 
           RowBox[{
            RowBox[{"RegisterOxide", "::", "duplicate"}], ",", "name"}], 
           "]"}], ";"}]}], "\[IndentingNewLine]", "]"}], ";", 
       "\[IndentingNewLine]", 
       RowBox[{"If", "[", 
        RowBox[{
         RowBox[{"StringMatchQ", "[", 
          RowBox[{"element", ",", 
           RowBox[{"__", "~~", "\"\<+\>\"", "~~", 
            RowBox[{"DigitCharacter", ".."}]}]}], "]"}], ",", 
         "\[IndentingNewLine]", 
         RowBox[{"(", "\[IndentingNewLine]", 
          RowBox[{
           RowBox[{"RegisterComp", "[", 
            RowBox[{"name", ",", 
             RowBox[{"Synonyms", "\[Rule]", 
              RowBox[{"{", 
               RowBox[{
                RowBox[{"(", 
                 RowBox[{
                  RowBox[{"StringCases", "[", 
                   RowBox[{"element", ",", 
                    RowBox[{"LetterCharacter", ".."}]}], "]"}], "//", 
                  "First"}], ")"}], "<>", 
                RowBox[{"If", "[", 
                 RowBox[{
                  RowBox[{"c", ">", "1"}], ",", 
                  RowBox[{"ToString", "[", "c", "]"}], ",", "\"\<\>\""}], 
                 "]"}], "<>", "\"\<O\>\"", "<>", 
                RowBox[{"If", "[", 
                 RowBox[{
                  RowBox[{"o", ">", "1"}], ",", 
                  RowBox[{"ToString", "[", "o", "]"}], ",", "\"\<\>\""}], 
                 "]"}]}], "}"}]}]}], "]"}], ";", "\[IndentingNewLine]", 
           RowBox[{"AppendTo", "[", 
            RowBox[{"OxideCoefficients", ",", 
             RowBox[{"{", 
              RowBox[{
               RowBox[{
                RowBox[{"(", 
                 RowBox[{
                  RowBox[{"StringCases", "[", 
                   RowBox[{"element", ",", 
                    RowBox[{"LetterCharacter", ".."}]}], "]"}], "//", 
                  "First"}], ")"}], "<>", 
                RowBox[{"If", "[", 
                 RowBox[{
                  RowBox[{"c", ">", "1"}], ",", 
                  RowBox[{"ToString", "[", "c", "]"}], ",", "\"\<\>\""}], 
                 "]"}], "<>", "\"\<O\>\"", "<>", 
                RowBox[{"If", "[", 
                 RowBox[{
                  RowBox[{"o", ">", "1"}], ",", 
                  RowBox[{"ToString", "[", "o", "]"}], ",", "\"\<\>\""}], 
                 "]"}]}], ",", "element", ",", "c", ",", "o"}], "}"}]}], 
            "]"}], ";", "\[IndentingNewLine]", 
           RowBox[{"AppendTo", "[", 
            RowBox[{"OxideCoefficients", ",", 
             RowBox[{"{", 
              RowBox[{"name", ",", "element", ",", "c", ",", "o"}], "}"}]}], 
            "]"}], ";"}], "\[IndentingNewLine]", ")"}], ",", 
         "\[IndentingNewLine]", 
         RowBox[{"(", "\[IndentingNewLine]", 
          RowBox[{
           RowBox[{"RegisterComp", "[", "name", "]"}], ";", 
           "\[IndentingNewLine]", 
           RowBox[{"AppendTo", "[", 
            RowBox[{"OxideCoefficients", ",", 
             RowBox[{"{", 
              RowBox[{"name", ",", "element", ",", "c", ",", "o"}], "}"}]}], 
            "]"}], ";"}], "\[IndentingNewLine]", ")"}]}], 
        "\[IndentingNewLine]", "]"}], ";", "\[IndentingNewLine]", 
       RowBox[{"(*", 
        RowBox[{
         RowBox[{"CDefs", "=", 
          RowBox[{"JoinT", "[", 
           RowBox[{"CDefs", ",", 
            RowBox[{
             RowBox[{"{", 
              RowBox[{"ReplacePart", "[", 
               RowBox[{
                RowBox[{"Table", "[", 
                 RowBox[{"0", ",", 
                  RowBox[{"{", 
                   RowBox[{"Length", "[", "CDefs", "]"}], "}"}]}], "]"}], ",", 
                RowBox[{"1", "\[Rule]", "name"}]}], "]"}], "}"}], "//", 
             "Transpose"}]}], "]"}]}], ";"}], "*)"}], "\[IndentingNewLine]", 
       "\[IndentingNewLine]", 
       RowBox[{"CMatrix", "=", 
        RowBox[{"BuildCMatrix", "[", "]"}]}], ";"}], "\[IndentingNewLine]", 
      ")"}]}], "]"}]}], ";"}]}], "Input",
 InitializationCell->
  True,ExpressionUUID->"21d7da78-5f51-49c7-b4ca-17b5e2fe4234"],

Cell[BoxData[
 RowBox[{
  RowBox[{"ParseChemicalFormula", "[", "str_", "]"}], ":=", 
  RowBox[{"Module", "[", "\[IndentingNewLine]", 
   RowBox[{
    RowBox[{"{", 
     RowBox[{"Groups", ",", "FlatStr", ",", "Elements"}], "}"}], ",", 
    "\[IndentingNewLine]", 
    RowBox[{"(", "\[IndentingNewLine]", 
     RowBox[{
      RowBox[{"Groups", "=", 
       RowBox[{"StringCases", "[", 
        RowBox[{"str", ",", 
         RowBox[{
          RowBox[{"(", 
           RowBox[{"\"\<(\>\"", "~~", "x__", "~~", "\"\<)\>\"", "~~", 
            RowBox[{"f", ":", 
             RowBox[{"(", 
              RowBox[{"NumberString", "..."}], ")"}]}]}], ")"}], 
          "\[RuleDelayed]", 
          RowBox[{"{", 
           RowBox[{"x", ",", 
            RowBox[{"If", "[", 
             RowBox[{
              RowBox[{"f", "\[NotEqual]", "\"\<\>\""}], ",", 
              RowBox[{"ToExpression", "[", "f", "]"}], ",", "1"}], "]"}]}], 
           "}"}]}]}], "]"}]}], ";", "\[IndentingNewLine]", 
      RowBox[{"Groups", "=", 
       RowBox[{
        RowBox[{
         RowBox[{
          RowBox[{"ParseChemicalFormula", "[", 
           RowBox[{"#", "[", 
            RowBox[{"[", "1", "]"}], "]"}], "]"}], "*", 
          RowBox[{"#", "[", 
           RowBox[{"[", "2", "]"}], "]"}]}], "&"}], "/@", "Groups"}]}], ";", 
      "\[IndentingNewLine]", "\[IndentingNewLine]", 
      RowBox[{"FlatStr", "=", 
       RowBox[{"StringReplace", "[", 
        RowBox[{"str", ",", 
         RowBox[{
          RowBox[{"(", 
           RowBox[{"\"\<(\>\"", "~~", "__", "~~", "\"\<)\>\"", "~~", 
            RowBox[{"(", 
             RowBox[{"NumberString", "..."}], ")"}]}], ")"}], "\[Rule]", 
          "\"\<\>\""}]}], "]"}]}], ";", "\[IndentingNewLine]", 
      RowBox[{"Elements", "=", 
       RowBox[{"StringCases", "[", 
        RowBox[{"FlatStr", ",", 
         RowBox[{
          RowBox[{"(", 
           RowBox[{
            RowBox[{"e", ":", 
             RowBox[{"(", 
              RowBox[{
               RowBox[{"CharacterRange", "[", 
                RowBox[{"\"\<A\>\"", ",", "\"\<Z\>\""}], "]"}], "~~", 
               RowBox[{
                RowBox[{"CharacterRange", "[", 
                 RowBox[{"\"\<a\>\"", ",", "\"\<z\>\""}], "]"}], "..."}], "~~", 
               RowBox[{
                RowBox[{"(", 
                 RowBox[{"\"\<+\>\"", "~~", 
                  RowBox[{"NumberString", "..."}]}], ")"}], "..."}]}], 
              ")"}]}], "~~", 
            RowBox[{"(", 
             RowBox[{"f", ":", 
              RowBox[{"NumberString", "..."}]}], ")"}]}], ")"}], 
          "\[RuleDelayed]", 
          RowBox[{"(", 
           RowBox[{"e", "\[Rule]", 
            RowBox[{"If", "[", 
             RowBox[{
              RowBox[{"f", "\[NotEqual]", "\"\<\>\""}], ",", 
              RowBox[{"ToExpression", "[", "f", "]"}], ",", "1"}], "]"}]}], 
           ")"}]}]}], "]"}]}], ";", "\[IndentingNewLine]", 
      RowBox[{"Elements", "=", 
       RowBox[{"Flatten", "@", 
        RowBox[{"Join", "[", 
         RowBox[{"Elements", ",", 
          RowBox[{"Normal", "@", "Groups"}]}], "]"}]}]}], ";", 
      "\[IndentingNewLine]", "\[IndentingNewLine]", 
      RowBox[{"Elements", "=", 
       RowBox[{"GroupBy", "[", 
        RowBox[{"Elements", ",", 
         RowBox[{"First", "\[Rule]", "Last"}]}], "]"}]}], ";", 
      "\[IndentingNewLine]", 
      RowBox[{"Elements", "=", 
       RowBox[{"Total", "/@", "Elements"}]}], ";", "\[IndentingNewLine]", 
      "\[IndentingNewLine]", 
      RowBox[{"KeyMap", "[", 
       RowBox[{
        RowBox[{
         RowBox[{"If", "[", 
          RowBox[{
           RowBox[{"!", 
            RowBox[{"NumericQ", "[", 
             RowBox[{"MolarMass", "[", "#", "]"}], "]"}]}], ",", 
           RowBox[{"ErrorMessage", "[", 
            RowBox[{
             RowBox[{"RegisterComp", "::", "elementudef"}], ",", "#"}], 
            "]"}]}], "]"}], "&"}], ",", "Elements"}], "]"}], ";", 
      "\[IndentingNewLine]", "\[IndentingNewLine]", "Elements"}], 
     "\[IndentingNewLine]", ")"}]}], "\[IndentingNewLine]", "]"}]}]], "Input",
 InitializationCell->
  True,ExpressionUUID->"6c2367ec-40ef-4041-a0bd-cfefbe4445a9"],

Cell[BoxData[{
 RowBox[{
  RowBox[{
   RowBox[{"Options", "[", "RegisterComp", "]"}], "=", 
   RowBox[{"{", 
    RowBox[{"Synonyms", "\[Rule]", 
     RowBox[{"{", "}"}]}], "}"}]}], ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"RegisterComp", "::", "elementudef"}], "=", 
   "\"\<The element `1` is not known.\>\""}], ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{
    RowBox[{"RegisterComp", "::", "duplicate"}], "=", 
    "\"\<The component `1` is already registered.\>\""}], ";"}], 
  "\[IndentingNewLine]"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"RegisterComp", "::", "usage"}], "=", 
   "\"\<RegisterComp[str] registers a chemical component with the chemical \
formula str for later use by other functions.\>\""}], 
  ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{"RegisterComp", "[", 
   RowBox[{"compdef_", ",", 
    RowBox[{"OptionsPattern", "[", "]"}]}], "]"}], ":=", 
  RowBox[{"Module", "[", "\[IndentingNewLine]", 
   RowBox[{
    RowBox[{"{", 
     RowBox[{"ElementList", ",", "MM"}], "}"}], ",", "\[IndentingNewLine]", 
    RowBox[{"(", "\[IndentingNewLine]", 
     RowBox[{
      RowBox[{"If", "[", 
       RowBox[{
        RowBox[{"CDefs", "[", 
         RowBox[{"KeyMemberQ", "[", "compdef", "]"}], "]"}], ",", 
        "\[IndentingNewLine]", 
        RowBox[{"ErrorMessage", "[", 
         RowBox[{
          RowBox[{"RegisterComp", "::", "duplicate"}], ",", "compdef"}], 
         "]"}]}], "\[IndentingNewLine]", "]"}], ";", "\[IndentingNewLine]", 
      "\[IndentingNewLine]", 
      RowBox[{"ElementList", "=", 
       RowBox[{"ParseChemicalFormula", "[", "compdef", "]"}]}], ";", 
      "\[IndentingNewLine]", 
      RowBox[{"MM", "=", 
       RowBox[{"Total", "@", 
        RowBox[{"(", 
         RowBox[{"KeyValueMap", "[", 
          RowBox[{
           RowBox[{
            RowBox[{
             RowBox[{"MolarMass", "[", "#1", "]"}], "*", "#2"}], "&"}], ",", 
           "ElementList"}], "]"}], ")"}]}]}], ";", "\[IndentingNewLine]", 
      "\[IndentingNewLine]", 
      RowBox[{"Unprotect", "[", "MolarMass", "]"}], ";", 
      "\[IndentingNewLine]", "\[IndentingNewLine]", 
      RowBox[{
       RowBox[{
        RowBox[{"(", 
         RowBox[{
          RowBox[{"If", "[", 
           RowBox[{
            RowBox[{"CDefs", "[", 
             RowBox[{"KeyMemberQ", "[", "#", "]"}], "]"}], ",", 
            "\[IndentingNewLine]", 
            RowBox[{"ErrorMessage", "[", 
             RowBox[{
              RowBox[{"RegisterComp", "::", "duplicate"}], ",", "#"}], 
             "]"}]}], "\[IndentingNewLine]", "]"}], ";", 
          "\[IndentingNewLine]", 
          RowBox[{"QueryTo", "[", 
           RowBox[{"CDefs", ",", 
            RowBox[{"Append", "[", 
             RowBox[{"#", "\[Rule]", "ElementList"}], "]"}]}], "]"}], ";", 
          "\[IndentingNewLine]", 
          RowBox[{
           RowBox[{"MolarMass", "[", "#", "]"}], "=", "MM"}], ";"}], 
         "\[IndentingNewLine]", ")"}], "&"}], "/@", 
       RowBox[{"OptionValue", "[", "Synonyms", "]"}]}], ";", 
      "\[IndentingNewLine]", "\[IndentingNewLine]", 
      RowBox[{"QueryTo", "[", 
       RowBox[{"CDefs", ",", 
        RowBox[{"Append", "[", 
         RowBox[{"compdef", "\[Rule]", "ElementList"}], "]"}]}], "]"}], ";", 
      "\[IndentingNewLine]", 
      RowBox[{
       RowBox[{"MolarMass", "[", "compdef", "]"}], "=", "MM"}], ";", 
      "\[IndentingNewLine]", "\[IndentingNewLine]", 
      RowBox[{"Protect", "[", "MolarMass", "]"}], ";", "\[IndentingNewLine]", 
      "\[IndentingNewLine]", 
      RowBox[{"CMatrix", "=", 
       RowBox[{"BuildCMatrix", "[", "]"}]}], ";"}], "\[IndentingNewLine]", 
     ")"}]}], "\[IndentingNewLine]", "]"}]}]}], "Input",
 InitializationCell->
  True,ExpressionUUID->"5cb8150c-f857-43b3-8292-b20c737bf78b"],

Cell[BoxData[{
 RowBox[{
  RowBox[{
   RowBox[{
    RowBox[{"Options", "[", "RegisterComp", "]"}], "=", 
    RowBox[{"{", 
     RowBox[{"Synonyms", "\[Rule]", 
      RowBox[{"{", "}"}]}], "}"}]}], ";"}], 
  "\[IndentingNewLine]"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"RegisterComp", "::", "badoxygencount"}], "=", 
   "\"\<The parser was not able to distribute the given oxygen to the \
cations.\>\""}], ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"RegisterComp", "::", "nooxygen"}], "=", 
   "\"\<At least one oxygen atom must be given in the chemical \
formula.\>\""}], ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"RegisterComp", "::", "oxideudef"}], "=", 
   "\"\<Oxide \\\"`1`\\\" is not defined. Custom oxides must be registered \
using RegisterOxide before they can be used in RegisterComp.\>\""}], 
  ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{
    RowBox[{"RegisterComp", "::", "duplicate"}], "=", 
    "\"\<The component `1` or one of the given synonyms is already \
registered.\>\""}], ";"}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"RegisterComp", "::", "usage"}], "=", 
   "\"\<RegisterComp[str] registers a chemical component with the chemical \
formula str for later use by other functions.\>\""}], 
  ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{
    RowBox[{"RegisterComp", "[", 
     RowBox[{"compdef_", ",", 
      RowBox[{"OptionsPattern", "[", "]"}]}], "]"}], ":=", 
    RowBox[{"Module", "[", "\[IndentingNewLine]", 
     RowBox[{
      RowBox[{"{", 
       RowBox[{
       "Groups", ",", "Lists", ",", "Res", ",", "F", ",", "Oxygens", ",", 
        "CationOxygens", ",", "OxideList", ",", "entry", ",", "pos"}], "}"}], 
      ",", 
      RowBox[{"(", "\[IndentingNewLine]", 
       RowBox[{
        RowBox[{"Groups", "=", 
         RowBox[{"StringCases", "[", 
          RowBox[{"compdef", ",", 
           RowBox[{
            RowBox[{"(", 
             RowBox[{"\"\<(\>\"", "~~", 
              RowBox[{"x", ":", 
               RowBox[{"(", 
                RowBox[{
                 RowBox[{"(", 
                  RowBox[{"WordCharacter", "|", "\"\<.\>\""}], ")"}], ".."}], 
                ")"}]}], "~~", "\"\<)\>\"", "~~", 
              RowBox[{"y", ":", 
               RowBox[{"(", 
                RowBox[{"NumberString", "..."}], ")"}]}]}], ")"}], "\[Rule]", 
            RowBox[{"{", 
             RowBox[{"x", ",", "y"}], "}"}]}]}], "]"}]}], ";", 
        "\[IndentingNewLine]", 
        RowBox[{"AppendTo", "[", 
         RowBox[{"Groups", ",", 
          RowBox[{"{", 
           RowBox[{
            RowBox[{"StringReplace", "[", 
             RowBox[{"compdef", ",", 
              RowBox[{
               RowBox[{"(", 
                RowBox[{"\"\<(\>\"", "~~", 
                 RowBox[{"(", 
                  RowBox[{
                   RowBox[{"(", 
                    RowBox[{"WordCharacter", "|", "\"\<.\>\""}], ")"}], 
                   ".."}], ")"}], "~~", "\"\<)\>\"", "~~", 
                 RowBox[{"NumberString", "..."}]}], ")"}], "\[Rule]", " ", 
               "\"\<\>\""}]}], "]"}], ",", "1"}], "}"}]}], "]"}], ";", 
        "\[IndentingNewLine]", "\[IndentingNewLine]", 
        RowBox[{"Lists", "=", 
         RowBox[{
          RowBox[{
           RowBox[{"(", "\[IndentingNewLine]", 
            RowBox[{
             RowBox[{"Res", "=", 
              RowBox[{"InterpretFormulaGroup", "[", 
               RowBox[{"#", "[", 
                RowBox[{"[", "1", "]"}], "]"}], "]"}]}], ";", 
             "\[IndentingNewLine]", 
             RowBox[{"F", "=", 
              RowBox[{"If", "[", 
               RowBox[{
                RowBox[{
                 RowBox[{"#", "[", 
                  RowBox[{"[", "2", "]"}], "]"}], "\[NotEqual]", "\"\<\>\""}],
                 ",", 
                RowBox[{"ToExpression", "[", 
                 RowBox[{"#", "[", 
                  RowBox[{"[", "2", "]"}], "]"}], "]"}], ",", "1"}], "]"}]}], 
             ";", "\[IndentingNewLine]", 
             RowBox[{"{", 
              RowBox[{
               RowBox[{
                RowBox[{
                 RowBox[{"#", 
                  RowBox[{"{", 
                   RowBox[{"1", ",", "F"}], "}"}]}], "&"}], "/@", 
                RowBox[{"Res", "[", 
                 RowBox[{"[", "1", "]"}], "]"}]}], ",", 
               RowBox[{
                RowBox[{"Res", "[", 
                 RowBox[{"[", "2", "]"}], "]"}], "*", "F"}], ",", 
               RowBox[{
                RowBox[{"Res", "[", 
                 RowBox[{"[", "3", "]"}], "]"}], "*", "F"}]}], "}"}]}], 
            "\[IndentingNewLine]", ")"}], "&"}], "/@", "Groups"}]}], ";", 
        "\[IndentingNewLine]", "\[IndentingNewLine]", 
        RowBox[{"Oxygens", "=", 
         RowBox[{"Total", "@", 
          RowBox[{"Lists", "[", 
           RowBox[{"[", 
            RowBox[{"All", ",", "2"}], "]"}], "]"}]}]}], ";", 
        "\[IndentingNewLine]", 
        RowBox[{"CationOxygens", "=", 
         RowBox[{"Total", "@", 
          RowBox[{"Lists", "[", 
           RowBox[{"[", 
            RowBox[{"All", ",", "3"}], "]"}], "]"}]}]}], ";", 
        "\[IndentingNewLine]", 
        RowBox[{"OxideList", "=", 
         RowBox[{"Flatten", "[", 
          RowBox[{
           RowBox[{"Lists", "[", 
            RowBox[{"[", 
             RowBox[{"All", ",", "1"}], "]"}], "]"}], ",", "1"}], "]"}]}], 
        ";", "\[IndentingNewLine]", "\[IndentingNewLine]", 
        RowBox[{"If", "[", 
         RowBox[{
          RowBox[{"Oxygens", "\[NotEqual]", "CationOxygens"}], ",", 
          "\[IndentingNewLine]", 
          RowBox[{"AppendTo", "[", 
           RowBox[{"OxideList", ",", 
            RowBox[{"{", 
             RowBox[{"\"\<O2\>\"", ",", 
              RowBox[{
               RowBox[{"(", 
                RowBox[{"Oxygens", "-", "CationOxygens"}], ")"}], "/", 
               "2"}]}], "}"}]}], "]"}]}], "\[IndentingNewLine]", "]"}], ";", 
        "\[IndentingNewLine]", 
        RowBox[{"OxideList", "=", 
         RowBox[{"Gather", "[", 
          RowBox[{"OxideList", ",", 
           RowBox[{
            RowBox[{
             RowBox[{"First", "[", "#1", "]"}], "\[Equal]", 
             RowBox[{"First", "[", "#2", "]"}]}], "&"}]}], "]"}]}], ";", 
        "\[IndentingNewLine]", 
        RowBox[{"OxideList", "=", 
         RowBox[{
          RowBox[{
           RowBox[{"{", 
            RowBox[{
             RowBox[{"#", "[", 
              RowBox[{"[", 
               RowBox[{"1", ",", "1"}], "]"}], "]"}], ",", 
             RowBox[{"Total", "[", 
              RowBox[{"#", "[", 
               RowBox[{"[", 
                RowBox[{"All", ",", "2"}], "]"}], "]"}], "]"}]}], "}"}], 
           "&"}], "/@", "OxideList"}]}], ";", "\[IndentingNewLine]", 
        "\[IndentingNewLine]", 
        RowBox[{"If", "[", 
         RowBox[{
          RowBox[{
           RowBox[{"MemberQ", "[", 
            RowBox[{
             RowBox[{"CDefs", "[", 
              RowBox[{"[", 
               RowBox[{"All", ",", "1"}], "]"}], "]"}], ",", "compdef"}], 
            "]"}], "||", 
           RowBox[{"(", 
            RowBox[{"Or", "@@", 
             RowBox[{"(", 
              RowBox[{
               RowBox[{
                RowBox[{"MemberQ", "[", 
                 RowBox[{
                  RowBox[{"CDefs", "[", 
                   RowBox[{"[", 
                    RowBox[{"All", ",", "1"}], "]"}], "]"}], ",", "#"}], 
                 "]"}], "&"}], "/@", 
               RowBox[{"OptionValue", "[", "Synonyms", "]"}]}], ")"}]}], 
            ")"}]}], ",", "\[IndentingNewLine]", 
          RowBox[{"ErrorMessage", "[", 
           RowBox[{
            RowBox[{"RegisterComp", "::", "duplicate"}], ",", "compdef"}], 
           "]"}]}], "\[IndentingNewLine]", "]"}], ";", "\[IndentingNewLine]", 
        "\[IndentingNewLine]", 
        RowBox[{"entry", "=", 
         RowBox[{"Table", "[", 
          RowBox[{"0", ",", 
           RowBox[{"{", 
            RowBox[{"Length", "[", 
             RowBox[{"CDefs", "[", 
              RowBox[{"[", "1", "]"}], "]"}], "]"}], "}"}]}], "]"}]}], ";", 
        "\[IndentingNewLine]", 
        RowBox[{
         RowBox[{"entry", "[", 
          RowBox[{"[", "1", "]"}], "]"}], "=", "compdef"}], ";", 
        "\[IndentingNewLine]", "\[IndentingNewLine]", 
        RowBox[{"Scan", "[", 
         RowBox[{
          RowBox[{
           RowBox[{"(", "\[IndentingNewLine]", 
            RowBox[{
             RowBox[{"pos", "=", 
              RowBox[{"Position", "[", 
               RowBox[{
                RowBox[{"CDefs", "[", 
                 RowBox[{"[", "1", "]"}], "]"}], ",", 
                RowBox[{"#", "[", 
                 RowBox[{"[", "1", "]"}], "]"}]}], "]"}]}], ";", 
             "\[IndentingNewLine]", 
             RowBox[{"If", "[", 
              RowBox[{
               RowBox[{
                RowBox[{
                 RowBox[{"Length", "[", "pos", "]"}], "\[Equal]", "1"}], "&&", 
                RowBox[{
                 RowBox[{"pos", "[", 
                  RowBox[{"[", 
                   RowBox[{"1", ",", "1"}], "]"}], "]"}], ">", "1"}]}], ",", 
               "\[IndentingNewLine]", 
               RowBox[{
                RowBox[{"entry", "[", 
                 RowBox[{"[", 
                  RowBox[{"pos", "[", 
                   RowBox[{"[", 
                    RowBox[{"1", ",", "1"}], "]"}], "]"}], "]"}], "]"}], "=", 
                RowBox[{
                 RowBox[{"#", "[", 
                  RowBox[{"[", "2", "]"}], "]"}], "//", "N"}]}], ",", 
               "\[IndentingNewLine]", 
               RowBox[{"ErrorMessage", "[", 
                RowBox[{
                 RowBox[{"RegisterComp", "::", "oxideudef"}], ",", 
                 RowBox[{"#", "[", 
                  RowBox[{"[", "1", "]"}], "]"}]}], "]"}]}], 
              "\[IndentingNewLine]", "]"}]}], "\[IndentingNewLine]", ")"}], 
           "&"}], ",", "OxideList"}], "]"}], ";", "\[IndentingNewLine]", 
        "\[IndentingNewLine]", 
        RowBox[{"AppendTo", "[", 
         RowBox[{"CDefs", ",", "entry"}], "]"}], ";", "\[IndentingNewLine]", 
        "\[IndentingNewLine]", 
        RowBox[{"If", "[", 
         RowBox[{
          RowBox[{
           RowBox[{"Length", "[", 
            RowBox[{"OptionValue", "[", "Synonyms", "]"}], "]"}], ">", "0"}], 
          ",", 
          RowBox[{
           RowBox[{
            RowBox[{"AppendTo", "[", 
             RowBox[{"CDefs", ",", 
              RowBox[{"ReplacePart", "[", 
               RowBox[{"entry", ",", 
                RowBox[{"1", "\[Rule]", "#"}]}], "]"}]}], "]"}], "&"}], "/@", 
           RowBox[{"OptionValue", "[", "Synonyms", "]"}]}]}], "]"}], ";", 
        "\[IndentingNewLine]", "\[IndentingNewLine]", 
        RowBox[{"CMatrix", "=", 
         RowBox[{"BuildCMatrix", "[", "]"}]}], ";"}], "\[IndentingNewLine]", 
       ")"}]}], "]"}]}], ";"}], 
  "\[IndentingNewLine]"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{"InterpretFormulaGroup", "[", "str_", "]"}], ":=", 
  RowBox[{"Module", "[", "\[IndentingNewLine]", 
   RowBox[{
    RowBox[{"{", 
     RowBox[{
     "Elements", ",", "Oxygens", ",", "CationOxygens", ",", "OxideList", ",", 
      "ElI", ",", "NI", ",", "OxI"}], "}"}], ",", "\[IndentingNewLine]", 
    RowBox[{"(", "\[IndentingNewLine]", 
     RowBox[{"(*", 
      RowBox[{
       RowBox[{"Elements", "=", 
        RowBox[{"StringReplace", "[", 
         RowBox[{"str", ",", 
          RowBox[{
           RowBox[{"(", 
            RowBox[{"\"\<(\>\"", "~~", 
             RowBox[{"WordCharacter", ".."}], "~~", "\"\<)\>\"", "~~", 
             RowBox[{"DigitCharacter", "..."}]}], ")"}], "\[Rule]", " ", 
           "\"\<\>\""}]}], "]"}]}], ";"}], "*)"}], "\[IndentingNewLine]", 
     RowBox[{
      RowBox[{"Elements", "=", 
       RowBox[{"StringCases", "[", 
        RowBox[{"str", ",", 
         RowBox[{
          RowBox[{"CharacterRange", "[", 
           RowBox[{"\"\<A\>\"", ",", "\"\<Z\>\""}], "]"}], "~~", 
          RowBox[{
           RowBox[{"CharacterRange", "[", 
            RowBox[{"\"\<a\>\"", ",", "\"\<z\>\""}], "]"}], "..."}], "~~", 
          RowBox[{"NumberString", "..."}]}]}], "]"}]}], ";", 
      "\[IndentingNewLine]", "\[IndentingNewLine]", 
      RowBox[{"If", "[", 
       RowBox[{
        RowBox[{"Or", "@@", 
         RowBox[{"StringMatchQ", "[", 
          RowBox[{"Elements", ",", 
           RowBox[{"\"\<O\>\"", "~~", 
            RowBox[{"NumberString", "..."}]}]}], "]"}]}], ",", 
        "\[IndentingNewLine]", 
        RowBox[{
         RowBox[{"Oxygens", "=", 
          RowBox[{
           RowBox[{"StringCases", "[", 
            RowBox[{"Elements", ",", 
             RowBox[{"\"\<O\>\"", "~~", 
              RowBox[{"NumberString", "..."}]}]}], "]"}], "//", "Flatten"}]}],
          ";", "\[IndentingNewLine]", 
         RowBox[{"Oxygens", "=", 
          RowBox[{
           RowBox[{
            RowBox[{"(", 
             RowBox[{"If", "[", 
              RowBox[{
               RowBox[{"StringMatchQ", "[", 
                RowBox[{"#", ",", 
                 RowBox[{"\"\<O\>\"", "~~", "NumberString"}]}], "]"}], ",", 
               RowBox[{"ToExpression", "[", 
                RowBox[{
                 RowBox[{"StringCases", "[", 
                  RowBox[{"#", ",", 
                   RowBox[{
                    RowBox[{"\"\<O\>\"", "~~", 
                    RowBox[{"x", ":", 
                    RowBox[{"(", "NumberString", ")"}]}]}], "\[Rule]", " ", 
                    "x"}]}], "]"}], "//", "First"}], "]"}], ",", "1"}], "]"}],
              ")"}], "&"}], "/@", "Oxygens"}]}], ";", "\[IndentingNewLine]", 
         RowBox[{"Oxygens", "=", 
          RowBox[{"Total", "[", "Oxygens", "]"}]}], ";", 
         "\[IndentingNewLine]", 
         RowBox[{"Elements", "=", 
          RowBox[{"Extract", "[", 
           RowBox[{"Elements", ",", 
            RowBox[{"Position", "[", 
             RowBox[{
              RowBox[{"StringMatchQ", "[", 
               RowBox[{"Elements", ",", 
                RowBox[{"\"\<O\>\"", "~~", 
                 RowBox[{"NumberString", "..."}]}]}], "]"}], ",", "False"}], 
             "]"}]}], "]"}]}], ";"}], "\[IndentingNewLine]", ",", 
        "\[IndentingNewLine]", 
        RowBox[{
         RowBox[{"Oxygens", "=", "0"}], ";"}]}], "\[IndentingNewLine]", "]"}],
       ";", "\[IndentingNewLine]", "\[IndentingNewLine]", 
      RowBox[{"CationOxygens", "=", "0"}], ";", "\[IndentingNewLine]", 
      RowBox[{"OxideList", "=", 
       RowBox[{
        RowBox[{
         RowBox[{"(", "\[IndentingNewLine]", 
          RowBox[{
           RowBox[{"ElI", "=", 
            RowBox[{
             RowBox[{"StringCases", "[", 
              RowBox[{"#", ",", 
               RowBox[{"LetterCharacter", ".."}]}], "]"}], "//", "First"}]}], 
           ";", "\[IndentingNewLine]", 
           RowBox[{"If", "[", 
            RowBox[{
             RowBox[{"MemberQ", "[", 
              RowBox[{"OxideCoefficients", ",", 
               RowBox[{"{", 
                RowBox[{"_", ",", "ElI", ",", "_", ",", "_"}], "}"}]}], "]"}],
              ",", 
             RowBox[{"(", "\[IndentingNewLine]", 
              RowBox[{
               RowBox[{"NI", "=", 
                RowBox[{"StringCases", "[", 
                 RowBox[{"#", ",", "NumberString"}], "]"}]}], ";", 
               "\[IndentingNewLine]", 
               RowBox[{"NI", "=", 
                RowBox[{"If", "[", 
                 RowBox[{
                  RowBox[{
                   RowBox[{"Length", "[", "NI", "]"}], "\[Equal]", "1"}], ",", 
                  RowBox[{"ToExpression", "[", 
                   RowBox[{"NI", "//", "First"}], "]"}], ",", "1"}], "]"}]}], 
               ";", "\[IndentingNewLine]", 
               RowBox[{"OxI", "=", 
                RowBox[{"FirstCase", "[", 
                 RowBox[{"OxideCoefficients", ",", 
                  RowBox[{"{", 
                   RowBox[{"_", ",", "ElI", ",", "_", ",", "_"}], "}"}]}], 
                 "]"}]}], ";", "\[IndentingNewLine]", 
               RowBox[{"CationOxygens", "+=", 
                RowBox[{
                 RowBox[{"NI", "/", 
                  RowBox[{"OxI", "[", 
                   RowBox[{"[", "3", "]"}], "]"}]}], "*", 
                 RowBox[{"OxI", "[", 
                  RowBox[{"[", "4", "]"}], "]"}]}]}], ";", 
               "\[IndentingNewLine]", 
               RowBox[{"{", 
                RowBox[{
                 RowBox[{"OxI", "[", 
                  RowBox[{"[", "1", "]"}], "]"}], ",", 
                 RowBox[{"NI", "/", 
                  RowBox[{"OxI", "[", 
                   RowBox[{"[", "3", "]"}], "]"}]}]}], "}"}]}], 
              "\[IndentingNewLine]", ")"}], ",", "\[IndentingNewLine]", 
             RowBox[{"ErrorMessage", "[", 
              RowBox[{
               RowBox[{"RegisterComp", "::", "oxideudef"}], ",", "ElI"}], 
              "]"}]}], "\[IndentingNewLine]", "]"}]}], "\[IndentingNewLine]", 
          ")"}], "&"}], "/@", "Elements"}]}], ";", "\[IndentingNewLine]", 
      "\[IndentingNewLine]", 
      RowBox[{"{", 
       RowBox[{"OxideList", ",", "Oxygens", ",", "CationOxygens"}], "}"}]}], 
     "\[IndentingNewLine]", ")"}]}], "\[IndentingNewLine]", "]"}]}]}], "Input",ExpressionUUID->"51b0293f-8092-4334-8422-867597a7859a"]
}, Open  ]],

Cell[CellGroupData[{

Cell["Data", "Section",ExpressionUUID->"ff4f298a-2f6e-48d8-8718-5d64e9881cd4"],

Cell[BoxData[{
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "::", "undef"}], "=", 
   "\"\<Molar mass of \\\"`1`\\\" is not defined.\>\""}], 
  ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{
    RowBox[{"MolarMass", "::", "unknownunit"}], "=", 
    "\"\<Unit `1` is not defined.\>\""}], ";"}], 
  "\[IndentingNewLine]"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "::", "usage"}], "=", 
   "\"\<MolarMass[str] represents the molar mass of the element, species or \
compound str.\>\""}], ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Ac\>\"", "]"}], "=", "227"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Ag\>\"", "]"}], "=", "107.8682"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Al\>\"", "]"}], "=", "26.9815386"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Am\>\"", "]"}], "=", "243"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Ar\>\"", "]"}], "=", "39.948"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<As\>\"", "]"}], "=", "74.92160"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<At\>\"", "]"}], "=", "210"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Au\>\"", "]"}], "=", "196.966569"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<B\>\"", "]"}], "=", "10.811"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Ba\>\"", "]"}], "=", "137.327"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Be\>\"", "]"}], "=", "9.012182"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Bh\>\"", "]"}], "=", "272"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Bi\>\"", "]"}], "=", "208.98040"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Bk\>\"", "]"}], "=", "247"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Br\>\"", "]"}], "=", "79.904"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<C\>\"", "]"}], "=", "12.0107"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Ca\>\"", "]"}], "=", "40.078"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Cd\>\"", "]"}], "=", "112.411"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Ce\>\"", "]"}], "=", "140.116"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Cf\>\"", "]"}], "=", "251"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Cl\>\"", "]"}], "=", "35.453"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Cm\>\"", "]"}], "=", "247"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Cn\>\"", "]"}], "=", "285"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Co\>\"", "]"}], "=", "58.933195"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Cr\>\"", "]"}], "=", "51.9961"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Cs\>\"", "]"}], "=", "132.9054519"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Cu\>\"", "]"}], "=", "63.546"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Db\>\"", "]"}], "=", "268"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Ds\>\"", "]"}], "=", "281"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Dy\>\"", "]"}], "=", "162.500"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Er\>\"", "]"}], "=", "167.259"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Es\>\"", "]"}], "=", "252"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Eu\>\"", "]"}], "=", "151.964"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<F\>\"", "]"}], "=", "18.9984032"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Fe\>\"", "]"}], "=", "55.845"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Fe+2\>\"", "]"}], "=", "55.845"}], 
  ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Fe+3\>\"", "]"}], "=", "55.845"}], 
  ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Fm\>\"", "]"}], "=", "257"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Fr\>\"", "]"}], "=", "223"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Ga\>\"", "]"}], "=", "69.723"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Gd\>\"", "]"}], "=", "157.25"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Ge\>\"", "]"}], "=", "72.64"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<H\>\"", "]"}], "=", "1.00794"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<He\>\"", "]"}], "=", "4.002602"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Hf\>\"", "]"}], "=", "178.49"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Hg\>\"", "]"}], "=", "200.59"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Ho\>\"", "]"}], "=", "164.93032"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Hs\>\"", "]"}], "=", "270"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<I\>\"", "]"}], "=", "126.90447"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<In\>\"", "]"}], "=", "114.818"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Ir\>\"", "]"}], "=", "192.217"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<K\>\"", "]"}], "=", "39.0983"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Kr\>\"", "]"}], "=", "83.798"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<La\>\"", "]"}], "=", "138.90547"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Li\>\"", "]"}], "=", "6.941"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Lr\>\"", "]"}], "=", "262"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Lu\>\"", "]"}], "=", "174.9668"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Md\>\"", "]"}], "=", "258"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Mg\>\"", "]"}], "=", "24.3050"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Mn\>\"", "]"}], "=", "54.938045"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Mo\>\"", "]"}], "=", "95.96"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Mt\>\"", "]"}], "=", "276"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<N\>\"", "]"}], "=", "14.0067"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Na\>\"", "]"}], "=", "22.98976928"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Nb\>\"", "]"}], "=", "92.90638"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Nd\>\"", "]"}], "=", "144.242"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Ne\>\"", "]"}], "=", "20.1791"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Ni\>\"", "]"}], "=", "58.6934"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<No\>\"", "]"}], "=", "259"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Np\>\"", "]"}], "=", "237"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<O\>\"", "]"}], "=", "15.9994"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Os\>\"", "]"}], "=", "190.23"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<P\>\"", "]"}], "=", "30.973762"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Pa\>\"", "]"}], "=", "231.03586"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Pb\>\"", "]"}], "=", "207.2"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Pd\>\"", "]"}], "=", "106.42"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Pm\>\"", "]"}], "=", "145"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Po\>\"", "]"}], "=", "209"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Pr\>\"", "]"}], "=", "140.90765"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Pt\>\"", "]"}], "=", "195.084"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Pu\>\"", "]"}], "=", "244"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Ra\>\"", "]"}], "=", "226"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Rb\>\"", "]"}], "=", "85.4678"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Re\>\"", "]"}], "=", "186.207"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Rf\>\"", "]"}], "=", "265"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Rg\>\"", "]"}], "=", "280"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Rh\>\"", "]"}], "=", "102.90550"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Rn\>\"", "]"}], "=", "222"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Ru\>\"", "]"}], "=", "101.07"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<S\>\"", "]"}], "=", "32.065"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Sb\>\"", "]"}], "=", "121.760"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Sc\>\"", "]"}], "=", "44.955912"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Se\>\"", "]"}], "=", "78.96"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Sg\>\"", "]"}], "=", "271"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Si\>\"", "]"}], "=", "28.0855"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Sm\>\"", "]"}], "=", "150.36"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Sn\>\"", "]"}], "=", "118.710"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Sr\>\"", "]"}], "=", "87.62"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Ta\>\"", "]"}], "=", "180.94788"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Tb\>\"", "]"}], "=", "158.92535"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Tc\>\"", "]"}], "=", "98"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Te\>\"", "]"}], "=", "127.60"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Th\>\"", "]"}], "=", "232.03806"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Ti\>\"", "]"}], "=", "47.867"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Tl\>\"", "]"}], "=", "204.3833"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Tm\>\"", "]"}], "=", "168.93421"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<U\>\"", "]"}], "=", "238.02891"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Uuh\>\"", "]"}], "=", "293"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Uuo\>\"", "]"}], "=", "294"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Uup\>\"", "]"}], "=", "288"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Uuq\>\"", "]"}], "=", "289"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Uus\>\"", "]"}], "=", "294"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Uut\>\"", "]"}], "=", "284"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<V\>\"", "]"}], "=", "50.9415"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<W\>\"", "]"}], "=", "183.84"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Xe\>\"", "]"}], "=", "131.293"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Y\>\"", "]"}], "=", "88.90585"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Yb\>\"", "]"}], "=", "173.054"}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Zn\>\"", "]"}], "=", "65.38"}], ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"MolarMass", "[", "\"\<Zr\>\"", "]"}], "=", "91.224"}], 
  ";"}]}], "Input",
 InitializationCell->
  True,ExpressionUUID->"d8aca19b-7c27-4ad7-a9b3-3b44411e282f"],

Cell[BoxData[
 RowBox[{
  RowBox[{
   RowBox[{
    RowBox[{"RegisterOxide", "@@", "#"}], "&"}], "/@", 
   RowBox[{"{", "\[IndentingNewLine]", 
    RowBox[{
     RowBox[{"{", 
      RowBox[{"\"\<Ca\>\"", ",", "1", ",", "1"}], "}"}], ",", 
     "\[IndentingNewLine]", 
     RowBox[{"{", 
      RowBox[{"\"\<Si\>\"", ",", "1", ",", "2"}], "}"}], ",", 
     "\[IndentingNewLine]", 
     RowBox[{"{", 
      RowBox[{"\"\<Mg\>\"", ",", "1", ",", "1"}], "}"}], ",", 
     "\[IndentingNewLine]", 
     RowBox[{"{", 
      RowBox[{"\"\<Al\>\"", ",", "2", ",", "3"}], "}"}], ",", 
     "\[IndentingNewLine]", 
     RowBox[{"{", 
      RowBox[{"\"\<Cr\>\"", ",", "2", ",", "3"}], "}"}], ",", 
     "\[IndentingNewLine]", 
     RowBox[{"{", 
      RowBox[{"\"\<H\>\"", ",", "2", ",", "1"}], "}"}], ",", 
     "\[IndentingNewLine]", 
     RowBox[{"{", 
      RowBox[{"\"\<C\>\"", ",", "1", ",", "2"}], "}"}], ",", 
     "\[IndentingNewLine]", 
     RowBox[{"{", 
      RowBox[{"\"\<K\>\"", ",", "2", ",", "1"}], "}"}], ",", 
     "\[IndentingNewLine]", 
     RowBox[{"{", 
      RowBox[{"\"\<Ti\>\"", ",", "1", ",", "2"}], "}"}], ",", 
     "\[IndentingNewLine]", 
     RowBox[{"{", 
      RowBox[{"\"\<Fe+3\>\"", ",", "2", ",", "3"}], "}"}], ",", 
     "\[IndentingNewLine]", 
     RowBox[{"{", 
      RowBox[{"\"\<Fe+2\>\"", ",", "1", ",", "1"}], "}"}], ",", 
     "\[IndentingNewLine]", 
     RowBox[{"{", 
      RowBox[{"\"\<Na\>\"", ",", "2", ",", "1"}], "}"}], ",", 
     "\[IndentingNewLine]", 
     RowBox[{"{", 
      RowBox[{"\"\<Mn\>\"", ",", "1", ",", "1"}], "}"}], ",", 
     "\[IndentingNewLine]", 
     RowBox[{"{", 
      RowBox[{"\"\<P\>\"", ",", "2", ",", "5"}], "}"}], ",", 
     "\[IndentingNewLine]", 
     RowBox[{"{", 
      RowBox[{"\"\<Li\>\"", ",", "2", ",", "1"}], "}"}], ",", 
     "\[IndentingNewLine]", 
     RowBox[{"{", 
      RowBox[{"\"\<Sr\>\"", ",", "1", ",", "1"}], "}"}], ",", 
     "\[IndentingNewLine]", 
     RowBox[{"{", 
      RowBox[{"\"\<S\>\"", ",", "1", ",", "3"}], "}"}]}], 
    "\[IndentingNewLine]", "}"}]}], ";"}]], "Input",
 InitializationCell->
  True,ExpressionUUID->"c3b4ae23-b847-422d-babc-ff719d6f9e78"],

Cell[BoxData[{
 RowBox[{
  RowBox[{"RegisterComp", "[", 
   RowBox[{"\"\<CO3\>\"", ",", 
    RowBox[{"Synonyms", "\[Rule]", 
     RowBox[{"{", "\"\<Carbonate\>\"", "}"}]}]}], "]"}], 
  ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{"RegisterComp", "[", 
   RowBox[{"\"\<CaCO3\>\"", ",", 
    RowBox[{"Synonyms", "\[Rule]", 
     RowBox[{"{", "\"\<Calcite\>\"", "}"}]}]}], "]"}], 
  ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{"RegisterComp", "[", 
   RowBox[{"\"\<SO4\>\"", ",", 
    RowBox[{"Synonyms", "\[Rule]", 
     RowBox[{"{", "\"\<Sulfate\>\"", "}"}]}]}], "]"}], 
  ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{"RegisterComp", "[", 
   RowBox[{"\"\<CaSO4\>\"", ",", 
    RowBox[{"Synonyms", "\[Rule]", 
     RowBox[{"{", "\"\<Anhydrite\>\"", "}"}]}]}], "]"}], ";"}]}], "Input",
 InitializationCell->
  True,ExpressionUUID->"48d9ff28-db18-4611-a26c-b9f9476dd52f"]
}, Open  ]],

Cell[CellGroupData[{

Cell["Molar-mass conversion", "Section",ExpressionUUID->"183472f6-cae5-4a95-92ef-e33c01366c36"],

Cell[BoxData[{
 RowBox[{
  RowBox[{
   RowBox[{"MassToMoles", "::", "usage"}], "=", 
   "\"\<MassToMoles[comp,mass] converts a mass of a chemical component to a \
molar amount.\nMassToMoles[datatable] convert the data in all columns of a \
DataTable from masses to molar amounts based on the component specified as \
column header.\nMassToMoles[association] convert the data in elements of an \
Association from masses to molar amounts based on the component specified as \
keys.\>\""}], ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"MassToMoles", "[", 
    RowBox[{"comp_String", ",", "mass_"}], "]"}], ":=", 
   RowBox[{"Module", "[", "\[IndentingNewLine]", 
    RowBox[{
     RowBox[{"{", "M", "}"}], ",", "\[IndentingNewLine]", 
     RowBox[{"(", "\[IndentingNewLine]", 
      RowBox[{
       RowBox[{"M", "=", 
        RowBox[{"MolarMass", "[", "comp", "]"}]}], ";", "\[IndentingNewLine]", 
       RowBox[{"If", "[", 
        RowBox[{
         RowBox[{"NumberQ", "[", "M", "]"}], ",", "\[IndentingNewLine]", 
         RowBox[{"Return", "[", 
          RowBox[{"mass", "/", "M"}], "]"}], ",", "\[IndentingNewLine]", 
         RowBox[{"ErrorMessage", "[", 
          RowBox[{
           RowBox[{"MolarMass", "::", "undef"}], ",", "comp"}], "]"}]}], 
        "\[IndentingNewLine]", "]"}], ";"}], "\[IndentingNewLine]", ")"}]}], 
    "\[IndentingNewLine]", "]"}]}], ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"MassToMoles", "[", "dat_DataTable", "]"}], ":=", 
   RowBox[{"dat", "[", 
    RowBox[{"All", ",", 
     RowBox[{
      RowBox[{"Association", "@", 
       RowBox[{"KeyValueMap", "[", 
        RowBox[{
         RowBox[{
          RowBox[{"#1", "\[Rule]", 
           RowBox[{"(", 
            RowBox[{"MassToMoles", "[", 
             RowBox[{"#1", ",", "#2"}], "]"}], ")"}]}], "&"}], ",", "#"}], 
        "]"}]}], "&"}]}], "]"}]}], ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{
    RowBox[{"MassToMoles", "[", "assoc_Association", "]"}], ":=", 
    RowBox[{"Association", "@", 
     RowBox[{"KeyValueMap", "[", 
      RowBox[{
       RowBox[{
        RowBox[{"#1", "\[Rule]", 
         RowBox[{"MassToMoles", "[", 
          RowBox[{"#1", ",", "#2"}], "]"}]}], "&"}], ",", "assoc"}], 
      "]"}]}]}], ";"}], "\[IndentingNewLine]"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"MolesToMass", "::", "usage"}], "=", 
   "\"\<MolesToMass[comp,moles] converts a molar amount of a chemical \
component to a mass.\nMolesToMass[datatable] convert the data in all columns \
of a DataTable from molar amounts to masses based on the component specified \
as column header.\nMolesToMass[association] convert the data in elements of \
an Association from molar amounts to masses based on the component specified \
as keys.\>\""}], ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"MolesToMass", "[", 
    RowBox[{"comp_String", ",", "moles_"}], "]"}], ":=", 
   RowBox[{"Module", "[", "\[IndentingNewLine]", 
    RowBox[{
     RowBox[{"{", "M", "}"}], ",", "\[IndentingNewLine]", 
     RowBox[{"(", "\[IndentingNewLine]", 
      RowBox[{
       RowBox[{"M", "=", 
        RowBox[{"MolarMass", "[", "comp", "]"}]}], ";", "\[IndentingNewLine]", 
       RowBox[{"If", "[", 
        RowBox[{
         RowBox[{"NumberQ", "[", "M", "]"}], ",", "\[IndentingNewLine]", 
         RowBox[{"Return", "[", 
          RowBox[{"moles", "*", "M"}], "]"}], ",", "\[IndentingNewLine]", 
         RowBox[{"ErrorMessage", "[", 
          RowBox[{
           RowBox[{"MolarMass", "::", "undef"}], ",", "comp"}], "]"}]}], 
        "\[IndentingNewLine]", "]"}], ";"}], "\[IndentingNewLine]", ")"}]}], 
    "\[IndentingNewLine]", "]"}]}], ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"MolesToMass", "[", "dat_DataTable", "]"}], ":=", 
   RowBox[{"dat", "[", 
    RowBox[{"All", ",", 
     RowBox[{
      RowBox[{"Association", "@", 
       RowBox[{"KeyValueMap", "[", 
        RowBox[{
         RowBox[{
          RowBox[{"#1", "\[Rule]", 
           RowBox[{"(", 
            RowBox[{"MolesToMass", "[", 
             RowBox[{"#1", ",", "#2"}], "]"}], ")"}]}], "&"}], ",", "#"}], 
        "]"}]}], "&"}]}], "]"}]}], ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"MolesToMass", "[", "assoc_Association", "]"}], ":=", 
   RowBox[{"Association", "@", 
    RowBox[{"KeyValueMap", "[", 
     RowBox[{
      RowBox[{
       RowBox[{"#1", "\[Rule]", 
        RowBox[{"MolesToMass", "[", 
         RowBox[{"#1", ",", "#2"}], "]"}]}], "&"}], ",", "assoc"}], "]"}]}]}],
   ";"}]}], "Input",
 InitializationCell->
  True,ExpressionUUID->"27b6f119-18d2-4c9e-923d-4ae2b299b6ca"],

Cell[BoxData[{
 RowBox[{
  RowBox[{
   RowBox[{"MassFractionToMolality", "::", "usage"}], "=", 
   "\"\<MassFractionToMolality[<|\!\(\*SubscriptBox[\(comp\), \(1\)]\)\[Rule]\
\!\(\*SubscriptBox[\(mass\), \(1\)]\),\!\(\*SubscriptBox[\(comp\), \(2\)]\)\
\[Rule]\!\(\*SubscriptBox[\(mass\), \(2\)]\),...|>,prefix] converts mass \
fractions in an association where the keys are the component names (which can \
be suffixed by ' / ppm', etc.) and values are the mass fractions to \
molalities with the specified unit prefix (m,\[Mu],n,p), which is optional.\n\
MassFractionToMolality[mass,comp] converts a mass fractions of a component to \
molality assuming that it is the only solute.\>\""}], 
  ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"MassFractionToMolality", "[", 
    RowBox[{"solutes_Association", ",", 
     RowBox[{"prefix_:", "None"}]}], "]"}], ":=", 
   RowBox[{"Module", "[", "\[IndentingNewLine]", 
    RowBox[{
     RowBox[{"{", 
      RowBox[{"Sol", ",", "W0", ",", "M", ",", "El", ",", "F", ",", "Out"}], 
      "}"}], ",", "\[IndentingNewLine]", 
     RowBox[{"(", "\[IndentingNewLine]", 
      RowBox[{
       RowBox[{"Sol", "=", 
        RowBox[{"Association", "@", 
         RowBox[{"KeyValueMap", "[", 
          RowBox[{
           RowBox[{
            RowBox[{"(", "\[IndentingNewLine]", 
             RowBox[{
              RowBox[{"If", "[", 
               RowBox[{
                RowBox[{"StringMatchQ", "[", 
                 RowBox[{"#1", ",", 
                  RowBox[{
                   RowBox[{"WordCharacter", ".."}], "~~", "\"\< / \>\"", "~~", 
                   RowBox[{"WordCharacter", ".."}]}]}], "]"}], ",", 
                "\[IndentingNewLine]", 
                RowBox[{"(", "\[IndentingNewLine]", 
                 RowBox[{
                  RowBox[{"El", "=", 
                   RowBox[{
                    RowBox[{"StringCases", "[", 
                    RowBox[{"#1", ",", 
                    RowBox[{
                    RowBox[{"(", 
                    RowBox[{
                    "StartOfString", "~~", "x__", "~~", "\"\< / \>\"", "~~", 
                    RowBox[{"WordCharacter", ".."}]}], ")"}], "\[Rule]", 
                    "x"}]}], "]"}], "//", "First"}]}], ";", 
                  "\[IndentingNewLine]", "\[IndentingNewLine]", 
                  RowBox[{"F", "=", 
                   RowBox[{"Switch", "[", "\[IndentingNewLine]", 
                    RowBox[{
                    RowBox[{
                    RowBox[{"StringCases", "[", 
                    RowBox[{"#1", ",", 
                    RowBox[{
                    RowBox[{"(", 
                    RowBox[{
                    RowBox[{"WordCharacter", ".."}], "~~", "\"\< / \>\"", "~~",
                     "x__", "~~", "EndOfString"}], ")"}], "\[Rule]", "x"}]}], 
                    "]"}], "//", "First"}], ",", "\[IndentingNewLine]", 
                    "\"\<%\>\"", ",", "100", ",", "\[IndentingNewLine]", 
                    "\"\<ppm\>\"", ",", 
                    RowBox[{"10", "^", "6"}], ",", "\[IndentingNewLine]", 
                    "\"\<ppb\>\"", ",", 
                    RowBox[{"10", "^", "9"}], ",", "\[IndentingNewLine]", 
                    "\"\<ppt\>\"", ",", 
                    RowBox[{"10", "^", "12"}], ",", "\[IndentingNewLine]", 
                    "\"\<ppq\>\"", ",", 
                    RowBox[{"10", "^", "15"}], ",", "\[IndentingNewLine]", 
                    "_", ",", 
                    RowBox[{"ErrorMessage", "[", 
                    RowBox[{
                    RowBox[{"MolarMass", "::", "unknownunit"}], ",", 
                    RowBox[{
                    RowBox[{"StringCases", "[", 
                    RowBox[{"#1", ",", 
                    RowBox[{
                    RowBox[{"(", 
                    RowBox[{
                    RowBox[{"WordCharacter", ".."}], "~~", "\"\< / \>\"", "~~",
                     "x__", "~~", "EndOfString"}], ")"}], "\[Rule]", "x"}]}], 
                    "]"}], "//", "First"}]}], "]"}]}], "\[IndentingNewLine]", 
                    "]"}]}], ";"}], "\[IndentingNewLine]", ")"}], ",", 
                "\[IndentingNewLine]", 
                RowBox[{"(", "\[IndentingNewLine]", 
                 RowBox[{
                  RowBox[{"El", "=", "#1"}], ";", "\[IndentingNewLine]", 
                  RowBox[{"F", "=", "1"}], ";"}], "\[IndentingNewLine]", 
                 ")"}]}], "\[IndentingNewLine]", "]"}], ";", 
              "\[IndentingNewLine]", 
              RowBox[{"El", "\[Rule]", 
               RowBox[{"If", "[", 
                RowBox[{
                 RowBox[{"MissingQ", "[", "#2", "]"}], ",", "#2", ",", 
                 RowBox[{"#2", "/", "F"}]}], "]"}]}]}], "\[IndentingNewLine]",
              ")"}], "&"}], ",", "solutes"}], "\[IndentingNewLine]", 
          "]"}]}]}], ";", "\[IndentingNewLine]", "\[IndentingNewLine]", 
       RowBox[{"W0", "=", 
        RowBox[{"1", "-", 
         RowBox[{"Total", "[", 
          RowBox[{"DeleteMissing", "[", 
           RowBox[{
            RowBox[{"Values", "[", "Sol", "]"}], ",", "1", ",", "2"}], "]"}], 
          "]"}]}]}], ";", "\[IndentingNewLine]", 
       RowBox[{"Out", "=", 
        RowBox[{"Association", "@", 
         RowBox[{"KeyValueMap", "[", 
          RowBox[{
           RowBox[{
            RowBox[{
             RowBox[{"(", 
              RowBox[{"#1", "~~", "\"\< / mol/kg\>\""}], ")"}], "\[Rule]", 
             RowBox[{"(", "\[IndentingNewLine]", 
              RowBox[{
               RowBox[{"M", "=", 
                RowBox[{"MolarMass", "[", "#1", "]"}]}], ";", 
               "\[IndentingNewLine]", 
               RowBox[{"If", "[", 
                RowBox[{
                 RowBox[{"NumericQ", "[", "M", "]"}], ",", 
                 "\[IndentingNewLine]", 
                 RowBox[{"If", "[", 
                  RowBox[{
                   RowBox[{"MissingQ", "[", "#2", "]"}], ",", "#2", ",", 
                   RowBox[{"#2", "*", 
                    RowBox[{
                    RowBox[{"10", "^", "3"}], "/", 
                    RowBox[{"(", 
                    RowBox[{"W0", "*", "M"}], ")"}]}]}]}], "]"}], ",", 
                 "\[IndentingNewLine]", 
                 RowBox[{"ErrorMessage", "[", 
                  RowBox[{
                   RowBox[{"MolarMass", "::", "undef"}], ",", "#1"}], "]"}]}],
                 "\[IndentingNewLine]", "]"}]}], "\[IndentingNewLine]", 
              ")"}]}], "&"}], ",", "Sol"}], "]"}]}]}], ";", 
       "\[IndentingNewLine]", "\[IndentingNewLine]", 
       RowBox[{"Switch", "[", 
        RowBox[{"prefix", ",", "\[IndentingNewLine]", "\"\<m\>\"", ",", 
         RowBox[{"Association", "@", 
          RowBox[{"KeyValueMap", "[", 
           RowBox[{
            RowBox[{
             RowBox[{
              RowBox[{"StringInsert", "[", 
               RowBox[{"#1", ",", "\"\<m\>\"", ",", 
                RowBox[{"-", "7"}]}], "]"}], "\[Rule]", 
              RowBox[{"If", "[", 
               RowBox[{
                RowBox[{"MissingQ", "[", "#2", "]"}], ",", "#2", ",", 
                RowBox[{"#2", "*", 
                 RowBox[{"10", "^", "3"}]}]}], "]"}]}], "&"}], ",", "Out"}], 
           "]"}]}], ",", "\[IndentingNewLine]", "\"\<\[Mu]\>\"", ",", 
         RowBox[{"Association", "@", 
          RowBox[{"KeyValueMap", "[", 
           RowBox[{
            RowBox[{
             RowBox[{
              RowBox[{"StringInsert", "[", 
               RowBox[{"#1", ",", "\"\<\[Mu]\>\"", ",", 
                RowBox[{"-", "7"}]}], "]"}], "\[Rule]", 
              RowBox[{"If", "[", 
               RowBox[{
                RowBox[{"MissingQ", "[", "#2", "]"}], ",", "#2", ",", 
                RowBox[{"#2", "*", 
                 RowBox[{"10", "^", "6"}]}]}], "]"}]}], "&"}], ",", "Out"}], 
           "]"}]}], ",", "\[IndentingNewLine]", "\"\<n\>\"", ",", 
         RowBox[{"Association", "@", 
          RowBox[{"KeyValueMap", "[", 
           RowBox[{
            RowBox[{
             RowBox[{
              RowBox[{"StringInsert", "[", 
               RowBox[{"#1", ",", "\"\<n\>\"", ",", 
                RowBox[{"-", "7"}]}], "]"}], "\[Rule]", 
              RowBox[{"If", "[", 
               RowBox[{
                RowBox[{"MissingQ", "[", "#2", "]"}], ",", "#2", ",", 
                RowBox[{"#2", "*", 
                 RowBox[{"10", "^", "9"}]}]}], "]"}]}], "&"}], ",", "Out"}], 
           "]"}]}], ",", "\[IndentingNewLine]", "\"\<p\>\"", ",", 
         RowBox[{"Association", "@", 
          RowBox[{"KeyValueMap", "[", 
           RowBox[{
            RowBox[{
             RowBox[{
              RowBox[{"StringInsert", "[", 
               RowBox[{"#1", ",", "\"\<p\>\"", ",", 
                RowBox[{"-", "7"}]}], "]"}], "\[Rule]", 
              RowBox[{"If", "[", 
               RowBox[{
                RowBox[{"MissingQ", "[", "#2", "]"}], ",", "#2", ",", 
                RowBox[{"#2", "*", 
                 RowBox[{"10", "^", "12"}]}]}], "]"}]}], "&"}], ",", "Out"}], 
           "]"}]}], ",", "\[IndentingNewLine]", "_", ",", "Out"}], 
        "\[IndentingNewLine]", "]"}]}], "\[IndentingNewLine]", ")"}]}], 
    "\[IndentingNewLine]", "]"}]}], ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{
    RowBox[{"MassFractionToMolality", "[", 
     RowBox[{"val_", ",", "comp_String"}], "]"}], ":=", 
    RowBox[{
     RowBox[{"MassFractionToMolality", "[", 
      RowBox[{"<|", 
       RowBox[{"comp", "\[Rule]", "val"}], "|>"}], "]"}], "[", 
     RowBox[{"[", "1", "]"}], "]"}]}], ";"}], 
  "\[IndentingNewLine]"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"MassFractionTomMolality", "::", "usage"}], "=", 
   "\"\<MassFractionTomMolality[data] is a short version of \
MassFractionToMolality[data,\\\"m\\\"]\>\""}], ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"MassFractionTomMolality", "[", "solutes_Association", "]"}], ":=", 
   RowBox[{"MassFractionToMolality", "[", 
    RowBox[{"solutes", ",", "\"\<m\>\""}], "]"}]}], 
  ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{
    RowBox[{"MassFractionTomMolality", "[", 
     RowBox[{"val_", ",", "comp_String"}], "]"}], ":=", 
    RowBox[{
     RowBox[{"MassFractionTomMolality", "[", 
      RowBox[{"<|", 
       RowBox[{"comp", "\[Rule]", "val"}], "|>"}], "]"}], "[", 
     RowBox[{"[", "1", "]"}], "]"}]}], ";"}], 
  "\[IndentingNewLine]"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"PpmToMolality", "::", "usage"}], "=", 
   "\"\<PpmToMolality[args] evaluates MassFractionToMolality[args] after \
multiplying values by \!\(\*SuperscriptBox[\(10\), \(-6\)]\).\>\""}], 
  ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{
    RowBox[{"PpmToMolality", "[", 
     RowBox[{"solutes_Association", ",", 
      RowBox[{"prefix_:", "None"}]}], "]"}], ":=", 
    RowBox[{"MassFractionToMolality", "[", 
     RowBox[{
      RowBox[{
       RowBox[{
        RowBox[{"If", "[", 
         RowBox[{
          RowBox[{"MissingQ", "[", "#", "]"}], ",", "#", ",", 
          RowBox[{"#", "*", 
           RowBox[{"10", "^", 
            RowBox[{"-", "6"}]}]}]}], "]"}], "&"}], "/@", "solutes"}], ",", 
      "prefix"}], "]"}]}], ";"}], 
  "\[IndentingNewLine]"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"PpmTomMolality", "::", "usage"}], "=", 
   "\"\<PpmTomMolality[data] evaluates MassFractionToMolality[data,\\\"m\\\"] \
after multiplying values by \!\(\*SuperscriptBox[\(10\), \(-6\)]\).\>\""}], 
  ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{
    RowBox[{"PpmTomMolality", "[", "solutes_Association", "]"}], ":=", 
    RowBox[{"PpmToMolality", "[", 
     RowBox[{"solutes", ",", "\"\<m\>\""}], "]"}]}], ";"}], 
  "\[IndentingNewLine]"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"PpmToMolality", "[", 
    RowBox[{"val_", ",", "comp_String"}], "]"}], ":=", 
   RowBox[{"MassFractionToMolality", "[", 
    RowBox[{
     RowBox[{"val", "*", 
      RowBox[{"10", "^", 
       RowBox[{"-", "6"}]}]}], ",", "comp"}], "]"}]}], 
  ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"PpmTomMolality", "[", 
    RowBox[{"val_", ",", "comp_String"}], "]"}], ":=", 
   RowBox[{
    RowBox[{"PpmTomMolality", "[", 
     RowBox[{"<|", 
      RowBox[{"comp", "\[Rule]", "val"}], "|>"}], "]"}], "[", 
    RowBox[{"[", "1", "]"}], "]"}]}], ";"}]}], "Input",
 InitializationCell->
  True,ExpressionUUID->"4904bac8-6ea2-4997-955f-7e7eb7e2b2f2"],

Cell[BoxData[{
 RowBox[{
  RowBox[{
   RowBox[{"MolalityToMassFraction", "::", "usage"}], "=", 
   "\"\<MolalityToMassFraction[<|\!\(\*SubscriptBox[\(comp\), \(1\)]\)\[Rule]\
\!\(\*SubscriptBox[\(amount\), \(1\)]\),\!\(\*SubscriptBox[\(comp\), \(2\)]\)\
\[Rule]\!\(\*SubscriptBox[\(amount\), \(2\)]\),...|>,quantifier] converts \
molalities in an association where the keys are the component names (which \
can have a unit with unit prefix mmol/kg,\[Mu]mol/kg,nmol/kg,pmol/kg) and \
values are the molalities to mass fractions with the specified unit \
quantifier (ppm, etc.), which is optional.\n\
MolalityToMassFraction[amount,comp] converts a molality of a component to a \
mass fraction assuming that it is the only solute.\>\""}], 
  ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{
    RowBox[{"MolalityToMassFraction", "[", 
     RowBox[{"solutes_Association", ",", 
      RowBox[{"quant_:", "None"}]}], "]"}], ":=", 
    RowBox[{"Module", "[", "\[IndentingNewLine]", 
     RowBox[{
      RowBox[{"{", 
       RowBox[{"Sol", ",", "W0", ",", "El", ",", "F", ",", "M", ",", "Out"}], 
       "}"}], ",", "\[IndentingNewLine]", 
      RowBox[{"(", "\[IndentingNewLine]", 
       RowBox[{
        RowBox[{"Sol", "=", 
         RowBox[{"Association", "@", 
          RowBox[{"KeyValueMap", "[", 
           RowBox[{
            RowBox[{
             RowBox[{"(", "\[IndentingNewLine]", 
              RowBox[{
               RowBox[{"If", "[", 
                RowBox[{
                 RowBox[{"StringMatchQ", "[", 
                  RowBox[{"#1", ",", 
                   RowBox[{
                    RowBox[{"WordCharacter", ".."}], "~~", "\"\< / \>\"", "~~", 
                    RowBox[{"WordCharacter", "..."}], "~~", 
                    "\"\<mol/kg\>\""}]}], "]"}], ",", "\[IndentingNewLine]", 
                 RowBox[{"(", "\[IndentingNewLine]", 
                  RowBox[{
                   RowBox[{"El", "=", 
                    RowBox[{
                    RowBox[{"StringCases", "[", 
                    RowBox[{"#1", ",", 
                    RowBox[{
                    RowBox[{"(", 
                    RowBox[{
                    "StartOfString", "~~", "x__", "~~", "\"\< / \>\"", "~~", 
                    RowBox[{"WordCharacter", ".."}]}], ")"}], "\[Rule]", 
                    "x"}]}], "]"}], "//", "First"}]}], ";", 
                   "\[IndentingNewLine]", "\[IndentingNewLine]", 
                   RowBox[{"F", "=", 
                    RowBox[{"Switch", "[", "\[IndentingNewLine]", 
                    RowBox[{
                    RowBox[{
                    RowBox[{"StringCases", "[", 
                    RowBox[{"#1", ",", 
                    RowBox[{
                    RowBox[{"(", 
                    RowBox[{
                    RowBox[{"WordCharacter", ".."}], "~~", "\"\< / \>\"", "~~",
                     "x___", "~~", "\"\<mol/kg\>\"", "~~", "EndOfString"}], 
                    ")"}], "\[Rule]", "x"}]}], "]"}], "//", "First"}], ",", 
                    "\[IndentingNewLine]", "\"\<m\>\"", ",", 
                    RowBox[{"10", "^", "3"}], ",", "\[IndentingNewLine]", 
                    "\"\<\[Mu]\>\"", ",", 
                    RowBox[{"10", "^", "6"}], ",", "\[IndentingNewLine]", 
                    "\"\<n\>\"", ",", 
                    RowBox[{"10", "^", "9"}], ",", "\[IndentingNewLine]", 
                    "\"\<\>\"", ",", "1", ",", "\[IndentingNewLine]", "_", 
                    ",", 
                    RowBox[{"ErrorMessage", "[", 
                    RowBox[{
                    RowBox[{"MolarMass", "::", "unknownunit"}], ",", 
                    RowBox[{
                    RowBox[{"StringCases", "[", 
                    RowBox[{"#1", ",", 
                    RowBox[{
                    RowBox[{"(", 
                    RowBox[{
                    RowBox[{"WordCharacter", ".."}], "~~", "\"\< / \>\"", "~~",
                     "x__", "~~", "\"\</kg\>\"", "~~", "EndOfString"}], ")"}],
                     "\[Rule]", "x"}]}], "]"}], "//", "First"}]}], "]"}]}], 
                    "\[IndentingNewLine]", "]"}]}], ";"}], 
                  "\[IndentingNewLine]", ")"}], ",", "\[IndentingNewLine]", 
                 RowBox[{"(", "\[IndentingNewLine]", 
                  RowBox[{
                   RowBox[{"El", "=", "#1"}], ";", "\[IndentingNewLine]", 
                   RowBox[{"F", "=", "1"}], ";"}], "\[IndentingNewLine]", 
                  ")"}]}], "\[IndentingNewLine]", "]"}], ";", 
               "\[IndentingNewLine]", 
               RowBox[{"El", "\[Rule]", 
                RowBox[{"If", "[", 
                 RowBox[{
                  RowBox[{"MissingQ", "[", "#2", "]"}], ",", "#2", ",", 
                  RowBox[{"#2", "/", "F"}]}], "]"}]}]}], 
              "\[IndentingNewLine]", ")"}], "&"}], ",", "solutes"}], 
           "\[IndentingNewLine]", "]"}]}]}], ";", "\[IndentingNewLine]", 
        "\[IndentingNewLine]", 
        RowBox[{"W0", "=", 
         RowBox[{"Total", "@", 
          RowBox[{"KeyValueMap", "[", 
           RowBox[{
            RowBox[{
             RowBox[{"(", "\[IndentingNewLine]", 
              RowBox[{
               RowBox[{"M", "=", 
                RowBox[{"MolarMass", "[", "#1", "]"}]}], ";", 
               "\[IndentingNewLine]", 
               RowBox[{"If", "[", 
                RowBox[{
                 RowBox[{"NumberQ", "[", "M", "]"}], ",", 
                 "\[IndentingNewLine]", 
                 RowBox[{
                  RowBox[{"#2", "/", 
                   RowBox[{"10", "^", "3"}]}], "*", "M"}], ",", 
                 "\[IndentingNewLine]", 
                 RowBox[{"ErrorMessage", "[", 
                  RowBox[{
                   RowBox[{"MolarMass", "::", "undef"}], ",", "#1"}], "]"}]}],
                 "\[IndentingNewLine]", "]"}]}], "\[IndentingNewLine]", ")"}],
              "&"}], ",", 
            RowBox[{"DeleteMissing", "[", "Sol", "]"}]}], "]"}]}]}], ";", 
        "\[IndentingNewLine]", 
        RowBox[{"W0", "=", 
         RowBox[{"1", "/", 
          RowBox[{"(", 
           RowBox[{"1", "+", "W0"}], ")"}]}]}], ";", "\[IndentingNewLine]", 
        "\[IndentingNewLine]", 
        RowBox[{"Out", "=", 
         RowBox[{"Association", "@", 
          RowBox[{"KeyValueMap", "[", 
           RowBox[{
            RowBox[{
             RowBox[{"#1", "\[Rule]", 
              RowBox[{"(", "\[IndentingNewLine]", 
               RowBox[{
                RowBox[{"M", "=", 
                 RowBox[{"MolarMass", "[", "#1", "]"}]}], ";", 
                "\[IndentingNewLine]", 
                RowBox[{"If", "[", 
                 RowBox[{
                  RowBox[{"MissingQ", "[", "#2", "]"}], ",", "#2", ",", 
                  RowBox[{"W0", "*", 
                   RowBox[{"#2", "/", 
                    RowBox[{"10", "^", "3"}]}], "*", "M"}]}], "]"}]}], 
               "\[IndentingNewLine]", ")"}]}], "&"}], ",", "Sol"}], "]"}]}]}],
         ";", "\[IndentingNewLine]", "\[IndentingNewLine]", 
        RowBox[{"Switch", "[", 
         RowBox[{"quant", ",", "\[IndentingNewLine]", "\"\<%\>\"", ",", 
          RowBox[{"Association", "@", 
           RowBox[{"KeyValueMap", "[", 
            RowBox[{
             RowBox[{
              RowBox[{
               RowBox[{"#1", "<>", "\"\< / %\>\""}], "\[Rule]", 
               RowBox[{"If", "[", 
                RowBox[{
                 RowBox[{"MissingQ", "[", "#2", "]"}], ",", "#2", ",", 
                 RowBox[{"#2", "*", 
                  RowBox[{"10", "^", "2"}]}]}], "]"}]}], "&"}], ",", "Out"}], 
            "]"}]}], ",", "\[IndentingNewLine]", "\"\<ppm\>\"", ",", 
          RowBox[{"Association", "@", 
           RowBox[{"KeyValueMap", "[", 
            RowBox[{
             RowBox[{
              RowBox[{
               RowBox[{"#1", "<>", "\"\< / ppm\>\""}], "\[Rule]", 
               RowBox[{"If", "[", 
                RowBox[{
                 RowBox[{"MissingQ", "[", "#2", "]"}], ",", "#2", ",", 
                 RowBox[{"#2", "*", 
                  RowBox[{"10", "^", "6"}]}]}], "]"}]}], "&"}], ",", "Out"}], 
            "]"}]}], ",", "\[IndentingNewLine]", "\"\<ppb\>\"", ",", 
          RowBox[{"Association", "@", 
           RowBox[{"KeyValueMap", "[", 
            RowBox[{
             RowBox[{
              RowBox[{
               RowBox[{"#1", "<>", "\"\< / ppb\>\""}], "\[Rule]", 
               RowBox[{"If", "[", 
                RowBox[{
                 RowBox[{"MissingQ", "[", "#2", "]"}], ",", "#2", ",", 
                 RowBox[{"#2", "*", 
                  RowBox[{"10", "^", "9"}]}]}], "]"}]}], "&"}], ",", "Out"}], 
            "]"}]}], ",", "\[IndentingNewLine]", "\"\<ppt\>\"", ",", 
          RowBox[{"Association", "@", 
           RowBox[{"KeyValueMap", "[", 
            RowBox[{
             RowBox[{
              RowBox[{
               RowBox[{"#1", "<>", "\"\< / ppt\>\""}], "\[Rule]", 
               RowBox[{"If", "[", 
                RowBox[{
                 RowBox[{"MissingQ", "[", "#2", "]"}], ",", "#2", ",", 
                 RowBox[{"#2", "*", 
                  RowBox[{"10", "^", "12"}]}]}], "]"}]}], "&"}], ",", "Out"}],
             "]"}]}], ",", "\[IndentingNewLine]", "\"\<ppq\>\"", ",", 
          RowBox[{"Association", "@", 
           RowBox[{"KeyValueMap", "[", 
            RowBox[{
             RowBox[{
              RowBox[{
               RowBox[{"#1", "<>", "\"\< / ppq\>\""}], "\[Rule]", 
               RowBox[{"If", "[", 
                RowBox[{
                 RowBox[{"MissingQ", "[", "#2", "]"}], ",", "#2", ",", 
                 RowBox[{"#2", "*", 
                  RowBox[{"10", "^", "15"}]}]}], "]"}]}], "&"}], ",", "Out"}],
             "]"}]}], ",", "\[IndentingNewLine]", "_", ",", "Out"}], 
         "\[IndentingNewLine]", "]"}]}], "\[IndentingNewLine]", ")"}]}], 
     "\[IndentingNewLine]", "]"}]}], ";"}], 
  "\[IndentingNewLine]"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"MolalityToPpm", "::", "usage"}], "=", 
   "\"\<MolalityToPpm[data] is a short version of \
MolalityToMassFraction[data,\\\"ppm\\\"]\>\""}], ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"MolalityToPpm", "[", "solutes_Association", "]"}], ":=", 
   RowBox[{"MolalityToMassFraction", "[", 
    RowBox[{"solutes", ",", "\"\<ppm\>\""}], "]"}]}], 
  ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"MolalityToMassFraction", "[", 
    RowBox[{"val_", ",", "comp_String"}], "]"}], ":=", 
   RowBox[{
    RowBox[{"MolalityToMassFraction", "[", 
     RowBox[{"<|", 
      RowBox[{"comp", "\[Rule]", "val"}], "|>"}], "]"}], "[", 
    RowBox[{"[", "1", "]"}], "]"}]}], ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"MolalityToPpm", "[", 
    RowBox[{"val_", ",", "comp_String"}], "]"}], ":=", 
   RowBox[{
    RowBox[{"MolalityToMassFraction", "[", 
     RowBox[{
      RowBox[{"<|", 
       RowBox[{"comp", "\[Rule]", "val"}], "|>"}], ",", "\"\<ppm\>\""}], 
     "]"}], "[", 
    RowBox[{"[", "1", "]"}], "]"}]}], ";"}]}], "Input",
 InitializationCell->
  True,ExpressionUUID->"77d8577b-a9f7-47e6-aed5-fce8a1a2e809"]
}, Open  ]],

Cell[CellGroupData[{

Cell["Conversion between components", "Section",ExpressionUUID->"315dc0f1-caf9-4773-8e10-c41ff9ede902"],

Cell[BoxData[{
 RowBox[{
  RowBox[{
   RowBox[{
    RowBox[{"Options", "[", "ConvertComps", "]"}], "=", 
    RowBox[{"{", 
     RowBox[{"(*", 
      RowBox[{
       RowBox[{"ReduceFe", "\[Rule]", "Automatic"}], ",", 
       RowBox[{"OxidizeFe", "\[Rule]", "Automatic"}], ","}], "*)"}], 
     RowBox[{
      RowBox[{"FromMolarData", "\[Rule]", "False"}], ",", 
      RowBox[{"ToMolarData", "\[Rule]", "False"}], ",", 
      RowBox[{"ToPercent", "\[Rule]", "False"}], ",", 
      RowBox[{"ToFractions", "\[Rule]", "False"}], ",", 
      RowBox[{"ProjectFrom", "\[Rule]", "None"}]}], "}"}]}], ";"}], 
  "\[IndentingNewLine]", "\[IndentingNewLine]", 
  RowBox[{"(*", 
   RowBox[{
    RowBox[{
     RowBox[{"ReduceFe", "::", "usage"}], "=", 
     "\"\<ReduceFe is an option that specifies whether iron can be reduced in \
ConvertComp[...].\>\""}], ";", "\[IndentingNewLine]", 
    RowBox[{
     RowBox[{"OxidizeFe", "::", "usage"}], "=", 
     "\"\<OxidizeFe is an option that specifies whether iron can be oxidized \
in ConvertComp[...].\>\""}], ";"}], "*)"}]}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"FromMolarData", "::", "usage"}], "=", 
   "\"\<FromMolarData is an option that specifies the input data for \
ConvertComps[...] are molar amounts.\>\""}], ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"ToMolarData", "::", "usage"}], "=", 
   "\"\<ToMolarData is an option that specifies the output data for \
ConvertComps[...] should be molar amounts.\>\""}], 
  ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"ToPercent", "::", "usage"}], "=", 
   "\"\<ToPercent is an option that specifies the output data for \
ConvertComps[...] should be percentages.\>\""}], ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"ToFractions", "::", "usage"}], "=", 
   "\"\<ToFractions is an option that specifies the output data for \
ConvertComps[...] should be fractions.\>\""}], ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"ProjectFrom", "::", "usage"}], "=", 
   "\"\<ProjectFrom is an option that specifies a list of components from \
which the data should be projected in ConvertComps[...].\>\""}], 
  ";"}]}], "Input",
 InitializationCell->
  True,ExpressionUUID->"cf091b1f-dfc5-44e9-9748-79166b0bff6a"],

Cell[BoxData[
 RowBox[{"\[IndentingNewLine]", 
  RowBox[{
   RowBox[{
    RowBox[{
     RowBox[{"ConvertComps", "::", "compcount"}], "=", 
     "\"\<More output components (`1`) are required to solve the conversation \
matrix. Maybe adding oxygen ('O') and projecting from this component using \
the ProjectFrom option helps? Are all custom components registered using \
RegisterComp?\>\""}], ";"}], "\[IndentingNewLine]", 
   RowBox[{
    RowBox[{
     RowBox[{"ConvertComps", "::", "unknowncomp"}], "=", 
     "\"\<The target component \\\"`1`\\\" is not known. Custom compoments \
must be registered using RegisterComp before they can be used with \
ConvertComps.\>\""}], ";"}], "\[IndentingNewLine]", 
   RowBox[{
    RowBox[{
     RowBox[{"ConvertComps", "::", "excesscomp"}], "=", 
     "\"\<The component(s) `1` is/are not necessary for the conversion to the \
target components and will not be used.\>\""}], ";"}], "\[IndentingNewLine]", 
   RowBox[{
    RowBox[{
     RowBox[{"ConvertComps", "::", "noinput"}], "=", 
     "\"\<The input data does not contain any valid composition data.\>\""}], 
    ";"}], "\[IndentingNewLine]", "\[IndentingNewLine]", 
   RowBox[{
    RowBox[{
     RowBox[{"ConvertComps", "::", "usage"}], "=", 
     "\"\<ConvertComps[datatable,{\!\(\*SubscriptBox[\(component\), \(1\)]\),\
\!\(\*SubscriptBox[\(component\), \(2\)]\),...}] converts the compositional \
data in a DataTable to a set of new chemical components using matrix \
transformations.\>\""}], ";"}], "\[IndentingNewLine]", 
   RowBox[{
    RowBox[{
     RowBox[{"ConvertComps", "[", 
      RowBox[{"dat_DataTable", ",", "newComps_", ",", 
       RowBox[{"OptionsPattern", "[", "]"}]}], "]"}], ":=", 
     RowBox[{"Module", "[", "\[IndentingNewLine]", 
      RowBox[{
       RowBox[{"{", 
        RowBox[{
        "FromCols", ",", "ToCols", ",", "IData", ",", "A", ",", "Ox", ",", 
         "OxRows", ",", "B", ",", "OData", ",", "Pos", ",", "IDColumnData"}], 
        "}"}], ",", 
       RowBox[{"(", "\[IndentingNewLine]", 
        RowBox[{
         RowBox[{"IData", "=", "dat"}], ";", "\[IndentingNewLine]", 
         "\[IndentingNewLine]", 
         RowBox[{"If", "[", 
          RowBox[{
           RowBox[{"!", 
            RowBox[{"OptionValue", "[", "FromMolarData", "]"}]}], ",", 
           "\[IndentingNewLine]", 
           RowBox[{
            RowBox[{"IData", "=", 
             RowBox[{"MassToMoles", "[", "IData", "]"}]}], ";"}]}], 
          "\[IndentingNewLine]", "]"}], ";", "\[IndentingNewLine]", 
         "\[IndentingNewLine]", 
         RowBox[{"IData", "=", 
          RowBox[{
           RowBox[{
            RowBox[{"IData", "//", "ToArray"}], "//", "Transpose"}], "//", 
           "Rest"}]}], ";", "\[IndentingNewLine]", "\[IndentingNewLine]", 
         RowBox[{"If", "[", 
          RowBox[{
           RowBox[{
            RowBox[{"Length", "[", 
             RowBox[{"Select", "[", 
              RowBox[{
               RowBox[{"IData", "[", 
                RowBox[{"[", 
                 RowBox[{"All", ",", "1"}], "]"}], "]"}], ",", 
               RowBox[{
                RowBox[{"FreeQ", "[", 
                 RowBox[{
                  RowBox[{"CMatrix", "[", 
                   RowBox[{"[", "1", "]"}], "]"}], ",", "#"}], "]"}], "&"}]}],
               "]"}], "]"}], ">", "0"}], ",", 
           RowBox[{"WarningMessage", "[", 
            RowBox[{
             RowBox[{"ConvertComps", "::", "excesscomp"}], ",", 
             RowBox[{"Select", "[", 
              RowBox[{
               RowBox[{"IData", "[", 
                RowBox[{"[", 
                 RowBox[{"All", ",", "1"}], "]"}], "]"}], ",", 
               RowBox[{
                RowBox[{"FreeQ", "[", 
                 RowBox[{
                  RowBox[{"CMatrix", "[", 
                   RowBox[{"[", "1", "]"}], "]"}], ",", "#"}], "]"}], "&"}]}],
               "]"}]}], "]"}]}], "]"}], ";", "\[IndentingNewLine]", 
         RowBox[{"IData", "=", 
          RowBox[{"Select", "[", 
           RowBox[{"IData", ",", 
            RowBox[{
             RowBox[{"MemberQ", "[", 
              RowBox[{
               RowBox[{"CMatrix", "[", 
                RowBox[{"[", "1", "]"}], "]"}], ",", 
               RowBox[{"#", "[", 
                RowBox[{"[", "1", "]"}], "]"}]}], "]"}], "&"}]}], "]"}]}], 
         ";", "\[IndentingNewLine]", "\[IndentingNewLine]", 
         RowBox[{"FromCols", "=", 
          RowBox[{
           RowBox[{"(", 
            RowBox[{
             RowBox[{
              RowBox[{"(", 
               RowBox[{"Position", "[", 
                RowBox[{
                 RowBox[{"CMatrix", "[", 
                  RowBox[{"[", "1", "]"}], "]"}], ",", "#"}], "]"}], ")"}], 
              "&"}], "/@", 
             RowBox[{"IData", "[", 
              RowBox[{"[", 
               RowBox[{"All", ",", "1"}], "]"}], "]"}]}], ")"}], "//", 
           "Flatten"}]}], ";", "\[IndentingNewLine]", 
         RowBox[{"If", "[", 
          RowBox[{
           RowBox[{
            RowBox[{"Length", "[", "FromCols", "]"}], "\[Equal]", "0"}], ",", 
           RowBox[{
            RowBox[{"ErrorMessage", "[", 
             RowBox[{"ConvertComps", "::", "noinput"}], "]"}], ";"}]}], "]"}],
          ";", "\[IndentingNewLine]", "\[IndentingNewLine]", 
         RowBox[{"ToCols", "=", 
          RowBox[{"(", 
           RowBox[{
            RowBox[{
             RowBox[{"(", 
              RowBox[{"Position", "[", 
               RowBox[{
                RowBox[{"CMatrix", "[", 
                 RowBox[{"[", "1", "]"}], "]"}], ",", "#"}], "]"}], ")"}], 
             "&"}], "/@", "newComps"}], ")"}]}], ";", "\[IndentingNewLine]", 
         RowBox[{"MapIndexed", "[", 
          RowBox[{
           RowBox[{
            RowBox[{"(", "\[IndentingNewLine]", 
             RowBox[{"If", "[", 
              RowBox[{
               RowBox[{
                RowBox[{"Length", "[", "#", "]"}], "\[Equal]", "0"}], ",", 
               RowBox[{"ErrorMessage", "[", 
                RowBox[{
                 RowBox[{"ConvertComps", "::", "unknowncomp"}], ",", 
                 RowBox[{"newComps", "[", 
                  RowBox[{"[", 
                   RowBox[{"#2", "[", 
                    RowBox[{"[", "1", "]"}], "]"}], "]"}], "]"}]}], "]"}]}], 
              "]"}], "\[IndentingNewLine]", ")"}], "&"}], ",", "ToCols"}], 
          "]"}], ";", "\[IndentingNewLine]", 
         RowBox[{"ToCols", "=", 
          RowBox[{"ToCols", "//", "Flatten"}]}], ";", "\[IndentingNewLine]", 
         "\[IndentingNewLine]", 
         RowBox[{"Ox", "=", 
          RowBox[{
           RowBox[{"DeleteCases", "[", 
            RowBox[{
             RowBox[{"(", 
              RowBox[{"CMatrix", "[", 
               RowBox[{"[", 
                RowBox[{"All", ",", 
                 RowBox[{"Prepend", "[", 
                  RowBox[{"ToCols", ",", "1"}], "]"}]}], "]"}], "]"}], ")"}], 
             ",", 
             RowBox[{"{", 
              RowBox[{"_", ",", 
               RowBox[{"0", ".."}]}], "}"}]}], "]"}], "[", 
           RowBox[{"[", 
            RowBox[{
             RowBox[{"2", ";;"}], ",", "1"}], "]"}], "]"}]}], ";", 
         "\[IndentingNewLine]", 
         RowBox[{"OxRows", "=", 
          RowBox[{
           RowBox[{"(", 
            RowBox[{
             RowBox[{
              RowBox[{"(", 
               RowBox[{"Position", "[", 
                RowBox[{
                 RowBox[{"CMatrix", "[", 
                  RowBox[{"[", 
                   RowBox[{"All", ",", "1"}], "]"}], "]"}], ",", "#"}], "]"}],
                ")"}], "&"}], "/@", "Ox"}], ")"}], "//", "Flatten"}]}], ";", 
         "\[IndentingNewLine]", 
         RowBox[{"If", "[", 
          RowBox[{
           RowBox[{
            RowBox[{"(", 
             RowBox[{"OxRows", "//", "Length"}], " ", ")"}], ">", 
            RowBox[{"(", 
             RowBox[{"ToCols", "//", "Length"}], ")"}]}], ",", 
           RowBox[{"ErrorMessage", "[", 
            RowBox[{
             RowBox[{"ConvertComps", "::", "compcount"}], ",", 
             RowBox[{
              RowBox[{"(", 
               RowBox[{"OxRows", "//", "Length"}], " ", ")"}], "-", 
              RowBox[{"(", 
               RowBox[{"ToCols", "//", "Length"}], ")"}]}]}], "]"}]}], "]"}], 
         ";", "\[IndentingNewLine]", "\[IndentingNewLine]", 
         RowBox[{"A", "=", 
          RowBox[{"CMatrix", "[", 
           RowBox[{"[", 
            RowBox[{"OxRows", ",", "FromCols"}], "]"}], "]"}]}], ";", 
         "\[IndentingNewLine]", 
         RowBox[{"(*", 
          RowBox[{
           RowBox[{"If", "[", 
            RowBox[{
             RowBox[{
              RowBox[{"MemberQ", "[", 
               RowBox[{"Ox", ",", "\"\<Fe+2\>\""}], "]"}], "&&", 
              RowBox[{"(", 
               RowBox[{
                RowBox[{"OptionValu", "\[IndentingNewLine]", 
                 RowBox[{"e", "[", "ReduceFe", "]"}]}], "||", 
                RowBox[{"(", 
                 RowBox[{
                  RowBox[{
                   RowBox[{"OptionValue", "[", "ReduceFe", "]"}], "\[Equal]", 
                   "Automatic"}], "&&", 
                  RowBox[{"MatchQ", "[", 
                   RowBox[{
                    RowBox[{"A", "[", 
                    RowBox[{"[", 
                    RowBox[{
                    RowBox[{"Position", "[", 
                    RowBox[{"Ox", ",", "\"\<Fe+2\>\""}], "]"}], "[", 
                    RowBox[{"[", 
                    RowBox[{"1", ",", "1"}], "]"}], "]"}], "]"}], "]"}], ",", 
                    RowBox[{"{", 
                    RowBox[{"0", ".."}], "}"}]}], "]"}]}], ")"}]}], ")"}]}], 
             ",", "\[IndentingNewLine]", 
             RowBox[{
              RowBox[{"Pos", "=", 
               RowBox[{
                RowBox[{"Position", "[", 
                 RowBox[{"Ox", ",", "\"\<Fe+2\>\""}], "]"}], "[", 
                RowBox[{"[", 
                 RowBox[{"1", ",", "1"}], "]"}], "]"}]}], ";", 
              "\[IndentingNewLine]", 
              RowBox[{
               RowBox[{"A", "[", 
                RowBox[{"[", "Pos", "]"}], "]"}], "=", 
               RowBox[{
                RowBox[{
                 RowBox[{"Cases", "[", 
                  RowBox[{"CMatrix", ",", 
                   RowBox[{"{", 
                    RowBox[{"\"\<Fe+3\>\"", ",", "__"}], "}"}]}], "]"}], "[", 
                 RowBox[{"[", 
                  RowBox[{"1", ",", "FromCols"}], "]"}], "]"}], "+", 
                RowBox[{"A", "[", 
                 RowBox[{"[", "Pos", "]"}], "]"}]}]}], ";"}]}], 
            "\[IndentingNewLine]", 
            RowBox[{"(*", 
             RowBox[{
              RowBox[{"If", "[", 
               RowBox[{
                RowBox[{"MemberQ", "[", 
                 RowBox[{"Ox", ",", "\"\<Fe2O3\>\""}], "]"}], ",", 
                "\[IndentingNewLine]", 
                RowBox[{
                 RowBox[{"Pos", "=", 
                  RowBox[{
                   RowBox[{"Position", "[", 
                    RowBox[{"Ox", ",", "\"\<Fe2O3\>\""}], "]"}], "[", 
                   RowBox[{"[", 
                    RowBox[{"1", ",", "1"}], "]"}], "]"}]}], ";", 
                 "\[IndentingNewLine]", 
                 RowBox[{
                  RowBox[{"A", "[", 
                   RowBox[{"[", "Pos", "]"}], "]"}], "=", 
                  RowBox[{"ConstantArray", "[", 
                   RowBox[{"0", ",", 
                    RowBox[{"Length", "[", "OxRows", "]"}]}], "]"}]}], 
                 ";"}]}], "\[IndentingNewLine]", "]"}], ";"}], "*)"}], 
            "\[IndentingNewLine]", "]"}], ";", "\[IndentingNewLine]", 
           RowBox[{"If", "[", 
            RowBox[{
             RowBox[{
              RowBox[{"MemberQ", "[", 
               RowBox[{"Ox", ",", "\"\<Fe+3\>\""}], "]"}], "&&", 
              RowBox[{"(", 
               RowBox[{
                RowBox[{"OptionValue", "[", "OxidizeFe", "]"}], "||", 
                RowBox[{"(", 
                 RowBox[{
                  RowBox[{
                   RowBox[{"OptionValue", "[", "OxidizeFe", "]"}], "\[Equal]",
                    "Automatic"}], "&&", 
                  RowBox[{"MatchQ", "[", 
                   RowBox[{
                    RowBox[{"A", "[", 
                    RowBox[{"[", 
                    RowBox[{
                    RowBox[{"Position", "[", 
                    RowBox[{"Ox", ",", "\"\<Fe+3\>\""}], "]"}], "[", 
                    RowBox[{"[", 
                    RowBox[{"1", ",", "1"}], "]"}], "]"}], "]"}], "]"}], ",", 
                    RowBox[{"{", 
                    RowBox[{"0", ".."}], "}"}]}], "]"}]}], ")"}]}], ")"}]}], 
             ",", "\[IndentingNewLine]", 
             RowBox[{
              RowBox[{"Pos", "=", 
               RowBox[{
                RowBox[{"Position", "[", 
                 RowBox[{"Ox", ",", "\"\<Fe+3\>\""}], "]"}], "[", 
                RowBox[{"[", 
                 RowBox[{"1", ",", "1"}], "]"}], "]"}]}], ";", 
              "\[IndentingNewLine]", 
              RowBox[{
               RowBox[{"A", "[", 
                RowBox[{"[", "Pos", "]"}], "]"}], "=", 
               RowBox[{
                RowBox[{
                 RowBox[{"Cases", "[", 
                  RowBox[{"CMatrix", ",", 
                   RowBox[{"{", 
                    RowBox[{"\"\<Fe+2\>\"", ",", "__"}], "}"}]}], "]"}], "[", 
                 RowBox[{"[", 
                  RowBox[{"1", ",", "FromCols"}], "]"}], "]"}], "+", 
                RowBox[{"A", "[", 
                 RowBox[{"[", "Pos", "]"}], "]"}]}]}], ";"}]}], 
            "\[IndentingNewLine]", "]"}], ";"}], "*)"}], 
         "\[IndentingNewLine]", 
         RowBox[{"MapIndexed", "[", 
          RowBox[{
           RowBox[{
            RowBox[{"(", 
             RowBox[{"If", "[", 
              RowBox[{
               RowBox[{"MatchQ", "[", 
                RowBox[{"#", ",", 
                 RowBox[{"{", 
                  RowBox[{"0", ".."}], "}"}]}], "]"}], ",", 
               "\[IndentingNewLine]", 
               RowBox[{"WarningMessage", "[", 
                RowBox[{
                 RowBox[{"ConvertComps", "::", "excesscomp"}], ",", 
                 RowBox[{"IData", "[", 
                  RowBox[{"[", 
                   RowBox[{
                    RowBox[{"#2", "[", 
                    RowBox[{"[", "1", "]"}], "]"}], ",", "1"}], "]"}], 
                  "]"}]}], "]"}]}], "\[IndentingNewLine]", "]"}], ")"}], 
            "&"}], ",", 
           RowBox[{"A", "//", "Transpose"}]}], "]"}], ";", 
         "\[IndentingNewLine]", "\[IndentingNewLine]", 
         RowBox[{"B", "=", 
          RowBox[{
           RowBox[{"CMatrix", "[", 
            RowBox[{"[", 
             RowBox[{"OxRows", ",", "ToCols"}], "]"}], "]"}], "//", 
           "Inverse"}]}], ";", "\[IndentingNewLine]", "\[IndentingNewLine]", 
         RowBox[{"OData", "=", 
          RowBox[{"ReplacePart", "[", 
           RowBox[{
            RowBox[{
             RowBox[{"(", 
              RowBox[{"B", ".", "A", ".", "IData"}], ")"}], "//", 
             "Transpose"}], ",", 
            RowBox[{"1", "\[Rule]", "newComps"}]}], "]"}]}], ";", 
         "\[IndentingNewLine]", "\[IndentingNewLine]", 
         RowBox[{"If", "[", 
          RowBox[{
           RowBox[{"ListQ", "[", 
            RowBox[{"OptionValue", "[", "ProjectFrom", "]"}], "]"}], ",", 
           "\[IndentingNewLine]", 
           RowBox[{
            RowBox[{"OData", "=", 
             RowBox[{"OData", "[", 
              RowBox[{"[", 
               RowBox[{"All", ",", 
                RowBox[{
                 RowBox[{"(", 
                  RowBox[{
                   RowBox[{
                    RowBox[{"Position", "[", 
                    RowBox[{
                    RowBox[{"OData", "//", "First"}], ",", "#", ",", 
                    RowBox[{"{", "1", "}"}], ",", "1"}], "]"}], "&"}], "/@", 
                   RowBox[{"Select", "[", 
                    RowBox[{
                    RowBox[{"OData", "//", "First"}], ",", 
                    RowBox[{
                    RowBox[{"!", 
                    RowBox[{"MemberQ", "[", 
                    RowBox[{
                    RowBox[{"OptionValue", "[", "ProjectFrom", "]"}], ",", 
                    "#"}], "]"}]}], "&"}]}], "]"}]}], ")"}], "//", 
                 "Flatten"}]}], "]"}], "]"}]}], ";"}]}], 
          "\[IndentingNewLine]", "]"}], ";", "\[IndentingNewLine]", 
         "\[IndentingNewLine]", 
         RowBox[{"If", "[", 
          RowBox[{
           RowBox[{"!", 
            RowBox[{"OptionValue", "[", "ToMolarData", "]"}]}], ",", 
           RowBox[{"OData", "=", 
            RowBox[{
             RowBox[{
              RowBox[{
               RowBox[{
                RowBox[{"MapIndexed", "[", 
                 RowBox[{
                  RowBox[{
                   RowBox[{"MolesToMass", "[", 
                    RowBox[{
                    RowBox[{"OData", "[", 
                    RowBox[{"[", 
                    RowBox[{"1", ",", 
                    RowBox[{"#2", "//", "First"}]}], "]"}], "]"}], ",", 
                    "#1"}], "]"}], "&"}], ",", "#"}], "]"}], "&"}], "/@", 
               "OData"}], "//", "Rest"}], "//", 
             RowBox[{
              RowBox[{"Prepend", "[", 
               RowBox[{"#", ",", 
                RowBox[{"OData", "//", "First"}]}], "]"}], "&"}]}]}]}], "]"}],
          ";", "\[IndentingNewLine]", "\[IndentingNewLine]", 
         RowBox[{"If", "[", 
          RowBox[{
           RowBox[{"OptionValue", "[", "ToFractions", "]"}], ",", 
           RowBox[{
            RowBox[{"OData", "=", 
             RowBox[{
              RowBox[{"(", 
               RowBox[{
                RowBox[{"SumNormalize", "/@", "OData"}], "//", "Rest"}], 
               ")"}], "//", 
              RowBox[{
               RowBox[{"Prepend", "[", 
                RowBox[{"#", ",", 
                 RowBox[{"OData", "//", "First"}]}], "]"}], "&"}]}]}], 
            ";"}]}], "]"}], ";", "\[IndentingNewLine]", "\[IndentingNewLine]", 
         RowBox[{"If", "[", 
          RowBox[{
           RowBox[{"OptionValue", "[", "ToPercent", "]"}], ",", 
           RowBox[{
            RowBox[{"OData", "=", 
             RowBox[{
              RowBox[{"(", 
               RowBox[{
                RowBox[{
                 RowBox[{
                  RowBox[{
                   RowBox[{"SumNormalize", "[", "#", "]"}], "*", "100"}], 
                  "&"}], "/@", "OData"}], "//", "Rest"}], ")"}], "//", 
              RowBox[{
               RowBox[{"Prepend", "[", 
                RowBox[{"#", ",", 
                 RowBox[{"OData", "//", "First"}]}], "]"}], "&"}]}]}], 
            ";"}]}], "]"}], ";", "\[IndentingNewLine]", "\[IndentingNewLine]", 
         RowBox[{"OData", "=", 
          RowBox[{"DataTable", "[", 
           RowBox[{
            RowBox[{"Prepend", "[", 
             RowBox[{
              RowBox[{"OData", "//", "Transpose"}], ",", 
              RowBox[{"Prepend", "[", 
               RowBox[{
                RowBox[{"NK", "[", "dat", "]"}], ",", "\"\<ID\>\""}], "]"}]}],
              "]"}], "//", "Transpose"}], "]"}]}], ";", "\[IndentingNewLine]", 
         RowBox[{"OData", "[", 
          RowBox[{"All", ",", "All", ",", 
           RowBox[{
            RowBox[{"Simplify", "@", 
             RowBox[{"DVE", "@", "#"}]}], "&"}]}], "]"}]}], 
        "\[IndentingNewLine]", ")"}]}], "]"}]}], ";"}], "\[IndentingNewLine]",
    "\[IndentingNewLine]", 
   RowBox[{
    RowBox[{
     RowBox[{"ConvertComps", "[", 
      RowBox[{"assoc_Association", ",", "newComps_", ",", 
       RowBox[{"opts", ":", 
        RowBox[{"OptionsPattern", "[", "]"}]}]}], "]"}], ":=", 
     RowBox[{"If", "[", 
      RowBox[{
       RowBox[{
        RowBox[{"Depth", "@", 
         RowBox[{"DVMeans", "@", "assoc"}]}], "\[Equal]", "2"}], ",", 
       "\[IndentingNewLine]", 
       RowBox[{"First", "@", 
        RowBox[{"Normal", "@", 
         RowBox[{"ConvertComps", "[", 
          RowBox[{
           RowBox[{"DataTable", "[", 
            RowBox[{"<|", 
             RowBox[{"\"\<1\>\"", "\[Rule]", "assoc"}], "|>"}], "]"}], ",", 
           "newComps", ",", "opts"}], "]"}]}]}], ",", "\[IndentingNewLine]", 
       RowBox[{"Normal", "@", 
        RowBox[{"ConvertComps", "[", 
         RowBox[{
          RowBox[{"DataTable", "[", "assoc", "]"}], ",", "newComps", ",", 
          "opts"}], "]"}]}]}], "\[IndentingNewLine]", "]"}]}], 
    ";"}]}]}]], "Input",
 InitializationCell->
  True,ExpressionUUID->"90eedb57-63e5-4051-bbf3-c598ef4091d2"],

Cell[BoxData[
 RowBox[{
  RowBox[{
   RowBox[{"CombineFMO", "[", "data_DataTable", "]"}], ":=", 
   RowBox[{"(", "\[IndentingNewLine]", 
    RowBox[{
     RowBox[{"data", "[", 
      RowBox[{"All", ",", 
       RowBox[{"KeyDrop", "[", 
        RowBox[{"{", 
         RowBox[{"\"\<MgO\>\"", ",", "\"\<FeO\>\""}], "}"}], "]"}]}], "]"}], 
     "~", "Join", "~", 
     RowBox[{"data", "[", 
      RowBox[{"All", ",", 
       RowBox[{
        RowBox[{"<|", 
         RowBox[{"\"\<FMO\>\"", "\[Rule]", 
          RowBox[{"#\"FeO\"", "+", "#\"MgO\""}]}], "|>"}], "&"}]}], "]"}]}], 
    "\[IndentingNewLine]", ")"}]}], ";"}]], "Input",ExpressionUUID->"990fb4aa-\
55e0-46e8-9855-edacfcc08272"],

Cell[BoxData[
 RowBox[{
  RowBox[{
   RowBox[{"SumNormalize", "[", "list_List", "]"}], ":=", 
   RowBox[{"list", "/", 
    RowBox[{"Total", "[", "list", "]"}]}]}], ";"}]], "Input",
 InitializationCell->
  True,ExpressionUUID->"f1ba292c-7715-4963-8f6e-1f2cd2a4450d"]
}, Open  ]],

Cell[CellGroupData[{

Cell["Mineral formula cations", "Section",ExpressionUUID->"2fa78e99-043e-441e-ab23-3378ec6485f5"],

Cell[BoxData[{
 RowBox[{
  RowBox[{
   RowBox[{
    RowBox[{"NumberCations", "[", "oxide_", "]"}], ":=", 
    RowBox[{"If", "[", 
     RowBox[{
      RowBox[{"MemberQ", "[", 
       RowBox[{"OxideCoefficients", ",", 
        RowBox[{"{", 
         RowBox[{"oxide", ",", "__"}], "}"}]}], "]"}], ",", 
      "\[IndentingNewLine]", 
      RowBox[{
       RowBox[{"OxideCoefficients", "[", 
        RowBox[{"[", 
         RowBox[{
          RowBox[{
           RowBox[{"Position", "[", 
            RowBox[{"OxideCoefficients", ",", 
             RowBox[{"{", 
              RowBox[{"oxide", ",", "__"}], "}"}]}], "]"}], "//", "First"}], 
          ",", "3"}], "]"}], "]"}], "//", "First"}], ",", 
      "\[IndentingNewLine]", 
      RowBox[{"ErrorMessage", "[", 
       RowBox[{
        RowBox[{"ChemElementName", "::", "notdefined"}], ",", "oxide"}], 
       "]"}]}], "\[IndentingNewLine]", "]"}]}], ";"}], 
  "\[IndentingNewLine]"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{
    RowBox[{"NumberOxygens", "[", "oxide_", "]"}], ":=", 
    RowBox[{"If", "[", 
     RowBox[{
      RowBox[{"MemberQ", "[", 
       RowBox[{"OxideCoefficients", ",", 
        RowBox[{"{", 
         RowBox[{"oxide", ",", "__"}], "}"}]}], "]"}], ",", 
      "\[IndentingNewLine]", 
      RowBox[{
       RowBox[{"OxideCoefficients", "[", 
        RowBox[{"[", 
         RowBox[{
          RowBox[{
           RowBox[{"Position", "[", 
            RowBox[{"OxideCoefficients", ",", 
             RowBox[{"{", 
              RowBox[{"oxide", ",", "__"}], "}"}]}], "]"}], "//", "First"}], 
          ",", "4"}], "]"}], "]"}], "//", "First"}], ",", 
      "\[IndentingNewLine]", 
      RowBox[{"ErrorMessage", "[", 
       RowBox[{
        RowBox[{"ChemElementName", "::", "notdefined"}], ",", "oxide"}], 
       "]"}]}], "\[IndentingNewLine]", "]"}]}], ";"}], 
  "\[IndentingNewLine]"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{
    RowBox[{"ChemElementName", "::", "notdefined"}], "=", 
    "\"\<The oxide `1` is not defined. Please register it first using the \
RegisterOxide function.\>\""}], ";"}], 
  "\[IndentingNewLine]"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"ChemElementName", "::", "usage"}], "=", 
   "\"\<ChemElementName[oxide] returns the element string for the registered \
chemical oxide compound 'oxide'.\>\""}], ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"ChemElementName", "[", "oxide_", "]"}], ":=", 
   RowBox[{"If", "[", 
    RowBox[{
     RowBox[{"MemberQ", "[", 
      RowBox[{"OxideCoefficients", ",", 
       RowBox[{"{", 
        RowBox[{"oxide", ",", "__"}], "}"}]}], "]"}], ",", 
     "\[IndentingNewLine]", 
     RowBox[{
      RowBox[{"OxideCoefficients", "[", 
       RowBox[{"[", 
        RowBox[{
         RowBox[{
          RowBox[{"Position", "[", 
           RowBox[{"OxideCoefficients", ",", 
            RowBox[{"{", 
             RowBox[{"oxide", ",", "__"}], "}"}]}], "]"}], "//", "First"}], 
         ",", "2"}], "]"}], "]"}], "//", "First"}], ",", 
     "\[IndentingNewLine]", 
     RowBox[{"ErrorMessage", "[", 
      RowBox[{
       RowBox[{"ChemElementName", "::", "notdefined"}], ",", "oxide"}], 
      "]"}]}], "\[IndentingNewLine]", "]"}]}], ";"}]}], "Input",
 InitializationCell->
  True,ExpressionUUID->"f1d4e12e-5a21-48fe-913d-bd3bed8fdb5f"],

Cell[BoxData[{
 RowBox[{
  RowBox[{
   RowBox[{
    RowBox[{"OxideName", "::", "notdefined"}], "=", 
    "\"\<The element `1` has no defined oxide. Please register it first using \
the RegisterOxide function.\>\""}], ";"}], 
  "\[IndentingNewLine]"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"OxideName", "::", "usage"}], "=", 
   "\"\<OxideName[element] returns the oxide string for the registered \
chemical element 'element'.\>\""}], ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"OxideName", "[", "element_", "]"}], ":=", 
   RowBox[{"If", "[", 
    RowBox[{
     RowBox[{"MemberQ", "[", 
      RowBox[{"OxideCoefficients", ",", 
       RowBox[{"{", 
        RowBox[{"_", ",", "element", ",", "__"}], "}"}]}], "]"}], ",", 
     "\[IndentingNewLine]", 
     RowBox[{
      RowBox[{"OxideCoefficients", "[", 
       RowBox[{"[", 
        RowBox[{
         RowBox[{
          RowBox[{"Position", "[", 
           RowBox[{"OxideCoefficients", ",", 
            RowBox[{"{", 
             RowBox[{"_", ",", "element", ",", "__"}], "}"}]}], "]"}], "//", 
          "First"}], ",", "1"}], "]"}], "]"}], "//", "First"}], ",", 
     "\[IndentingNewLine]", 
     RowBox[{"ErrorMessage", "[", 
      RowBox[{
       RowBox[{"OxideName", "::", "notdefined"}], ",", "element"}], "]"}]}], 
    "\[IndentingNewLine]", "]"}]}], ";"}]}], "Input",
 InitializationCell->
  True,ExpressionUUID->"c0d3cdd3-a017-4bb5-aec7-14772de3c871"],

Cell[BoxData[
 RowBox[{
  RowBox[{
   RowBox[{"Options", "[", "MinFormulaCations", "]"}], "=", 
   RowBox[{"{", 
    RowBox[{"FromMolarData", "\[Rule]", "False"}], "}"}]}], ";"}]], "Input",
 InitializationCell->
  True,ExpressionUUID->"29cfbfd9-c1a1-4f08-8fc7-7985e54db081"],

Cell[BoxData[{
 RowBox[{
  RowBox[{
   RowBox[{"MinFormulaCations", "::", "usage"}], "=", 
   "\"\<MinFormulaCations[datatable,i] converts the compositional data (given \
in terms of oxides) in a DataTable to coefficients for a chemical mineral \
formula based on i oxygen atoms in the formula.\>\""}], 
  ";"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{
    RowBox[{"MinFormulaCations", "[", 
     RowBox[{"dt_DataTable", ",", "oxygens_", ",", 
      RowBox[{"OptionsPattern", "[", "]"}]}], "]"}], ":=", 
    RowBox[{"Module", "[", "\[IndentingNewLine]", 
     RowBox[{
      RowBox[{"{", "\[IndentingNewLine]", 
       RowBox[{"MolarData", ",", "\[IndentingNewLine]", "OxygenData"}], 
       "\[IndentingNewLine]", "}"}], ",", "\[IndentingNewLine]", 
      RowBox[{
       RowBox[{"MolarData", "=", 
        RowBox[{"If", "[", 
         RowBox[{
          RowBox[{"OptionValue", "[", "FromMolarData", "]"}], ",", "dt", ",", 
          RowBox[{"MassToMoles", "[", "dt", "]"}]}], "]"}]}], ";", 
       "\[IndentingNewLine]", 
       RowBox[{"If", "[", 
        RowBox[{
         RowBox[{"FailureQ", "[", "MolarData", "]"}], ",", 
         RowBox[{
          RowBox[{"Print", "[", "MolarData", "]"}], ";", 
          RowBox[{"Abort", "[", "]"}], ";"}]}], "]"}], ";", 
       "\[IndentingNewLine]", "\[IndentingNewLine]", 
       RowBox[{"OxygenData", "=", 
        RowBox[{"MolarData", "[", 
         RowBox[{"All", ",", 
          RowBox[{
           RowBox[{"Association", "@", 
            RowBox[{"KeyValueMap", "[", 
             RowBox[{
              RowBox[{
               RowBox[{"#1", "\[Rule]", 
                RowBox[{"(", 
                 RowBox[{
                  RowBox[{"NumberOxygens", "[", "#1", "]"}], "*", "#2"}], 
                 ")"}]}], "&"}], ",", "#"}], "]"}]}], "&"}]}], "]"}]}], ";", 
       "\[IndentingNewLine]", 
       RowBox[{"If", "[", 
        RowBox[{
         RowBox[{"FailureQ", "[", "OxygenData", "]"}], ",", 
         RowBox[{
          RowBox[{"Print", "[", "OxygenData", "]"}], ";", 
          RowBox[{"Abort", "[", "]"}], ";"}]}], "]"}], ";", 
       "\[IndentingNewLine]", "\[IndentingNewLine]", 
       RowBox[{"OxygenData", "=", 
        RowBox[{"OxygenData", "[", 
         RowBox[{"All", ",", 
          RowBox[{
           RowBox[{"(", 
            RowBox[{
             RowBox[{"#", "/", 
              RowBox[{"Total", "[", "#", "]"}]}], "*", "oxygens"}], ")"}], 
           "&"}]}], "]"}]}], ";", "\[IndentingNewLine]", 
       "\[IndentingNewLine]", 
       RowBox[{"OxygenData", "[", 
        RowBox[{"All", ",", 
         RowBox[{
          RowBox[{"Association", "@", 
           RowBox[{"KeyValueMap", "[", 
            RowBox[{
             RowBox[{
              RowBox[{
               RowBox[{"ChemElementName", "[", "#1", "]"}], "\[Rule]", 
               RowBox[{"(", 
                RowBox[{"#2", "*", 
                 RowBox[{
                  RowBox[{"NumberCations", "[", "#1", "]"}], "/", 
                  RowBox[{"NumberOxygens", "[", "#1", "]"}]}]}], ")"}]}], 
              "&"}], ",", "#"}], "]"}]}], "&"}]}], "]"}]}]}], 
     "\[IndentingNewLine]", "]"}]}], ";"}], 
  "\[IndentingNewLine]"}], "\[IndentingNewLine]", 
 RowBox[{
  RowBox[{
   RowBox[{"MinFormulaCations", "[", 
    RowBox[{"assoc_Association", ",", "oxygens_", ",", 
     RowBox[{"opts", ":", 
      RowBox[{"OptionsPattern", "[", "]"}]}]}], "]"}], ":=", 
   RowBox[{"If", "[", 
    RowBox[{
     RowBox[{
      RowBox[{"Depth", "@", 
       RowBox[{"DVMeans", "@", "assoc"}]}], "\[Equal]", "2"}], ",", 
     "\[IndentingNewLine]", 
     RowBox[{"First", "@", 
      RowBox[{"Normal", "@", 
       RowBox[{"MinFormulaCations", "[", 
        RowBox[{
         RowBox[{"DataTable", "[", 
          RowBox[{"<|", 
           RowBox[{"\"\<1\>\"", "\[Rule]", "assoc"}], "|>"}], "]"}], ",", 
         "oxygens", ",", "opts"}], "]"}]}]}], ",", "\[IndentingNewLine]", 
     RowBox[{"Normal", "@", 
      RowBox[{"MinFormulaCations", "[", 
       RowBox[{
        RowBox[{"DataTable", "[", "assoc", "]"}], ",", "oxygens", ",", 
        "opts"}], "]"}]}]}], "\[IndentingNewLine]", "]"}]}], ";"}]}], "Input",
 InitializationCell->
  True,ExpressionUUID->"e7ad758f-29d5-480d-b808-ccec019e08ee"]
}, Open  ]],

Cell[CellGroupData[{

Cell["End private context", "Section",ExpressionUUID->"a140b911-b019-476e-bcce-66adb1b6f37b"],

Cell[BoxData[
 RowBox[{
  RowBox[{"End", "[", "]"}], ";"}]], "Input",
 InitializationCell->
  True,ExpressionUUID->"4cd65046-4aa4-43a5-a696-c5dbe4826bfb"]
}, Closed]],

Cell[CellGroupData[{

Cell["End package", "Section",ExpressionUUID->"b795fc42-7e04-4a39-8635-acf99783e943"],

Cell[BoxData[{
 RowBox[{
  RowBox[{"Protect", "[", 
   RowBox[{"Evaluate", "[", 
    RowBox[{"$Context", "<>", "\"\<*\>\""}], "]"}], "]"}], ";"}], "\n", 
 RowBox[{
  RowBox[{"EndPackage", "[", "]"}], ";"}]}], "Input",
 InitializationCell->
  True,ExpressionUUID->"33bb095d-3982-4671-a7c0-edca6cc9ecd9"]
}, Closed]]
}, Open  ]]
},
AutoGeneratedPackage->Automatic,
WindowSize->{1920, 1007},
WindowMargins->{{-8, Automatic}, {Automatic, -8}},
DockedCells->FEPrivate`FrontEndResource["FEExpressions", "PackageToolbar"],
FrontEndVersion->"11.2 for Microsoft Windows (64-bit) (September 10, 2017)",
StyleDefinitions->"Default.nb"
]
(* End of Notebook Content *)

(* Internal cache information *)
(*CellTagsOutline
CellTagsIndex->{
 "Null"->{
  Cell[5498, 170, 115, 1, 67, "Section",ExpressionUUID->"40fa656c-1423-4488-a500-27624f3cfb13",
   CellTags->"Null"]}
 }
*)
(*CellTagsIndex
CellTagsIndex->{
 {"Null", 124845, 3283}
 }
*)
(*NotebookFileOutline
Notebook[{
Cell[CellGroupData[{
Cell[579, 22, 79, 0, 96, "Title",ExpressionUUID->"c97a224d-fcf5-4202-83b1-14554b0cdb30"],
Cell[CellGroupData[{
Cell[683, 26, 87, 0, 67, "Section",ExpressionUUID->"26c421db-f3e3-40fa-86e3-0ff6be85e13c"],
Cell[773, 28, 265, 6, 44, "Input",ExpressionUUID->"69c3d4b3-60ab-45dc-af35-e47599e403d4",
 InitializationCell->True],
Cell[1041, 36, 242, 6, 44, "Input",ExpressionUUID->"65587c63-6581-4070-a83c-9e0fd6dcd451",
 InitializationCell->True]
}, Open  ]],
Cell[CellGroupData[{
Cell[1320, 47, 82, 0, 67, "Section",ExpressionUUID->"7a61416e-3cc7-4b69-80ed-a695703d2114"],
Cell[CellGroupData[{
Cell[1427, 51, 86, 0, 53, "Subsection",ExpressionUUID->"66216aa4-f3fc-402e-a4b6-1089cb504a43"],
Cell[1516, 53, 1270, 29, 425, "Input",ExpressionUUID->"d48abef0-0330-487f-a040-d5e8a4b3c0cc",
 InitializationCell->True]
}, Open  ]],
Cell[CellGroupData[{
Cell[2823, 87, 84, 0, 53, "Subsection",ExpressionUUID->"bfa018fa-2dca-4c2b-8dc1-c73b1bbf507b"],
Cell[2910, 89, 550, 12, 178, "Input",ExpressionUUID->"8ad1cd10-02dc-46db-b94e-faca512fa9a7",
 InitializationCell->True]
}, Open  ]]
}, Open  ]],
Cell[CellGroupData[{
Cell[3509, 107, 95, 0, 67, "Section",ExpressionUUID->"c1b5f50b-8e9b-47f3-8e97-78c734db31a8"],
Cell[3607, 109, 177, 4, 31, "Input",ExpressionUUID->"48b81d6f-3536-4ff3-ac9a-384f94baf213",
 InitializationCell->True]
}, Closed]],
Cell[CellGroupData[{
Cell[3821, 118, 88, 0, 53, "Section",ExpressionUUID->"aacfa499-cce1-435f-939e-915e50a77731"],
Cell[3912, 120, 1121, 30, 254, "Input",ExpressionUUID->"e91e189f-ba8c-44bc-a907-d3b23725056f",
 InitializationCell->True],
Cell[5036, 152, 425, 13, 64, "Input",ExpressionUUID->"8e515af0-a891-42ad-87ac-ca89ed41f648",
 InitializationCell->True]
}, Open  ]],
Cell[CellGroupData[{
Cell[5498, 170, 115, 1, 67, "Section",ExpressionUUID->"40fa656c-1423-4488-a500-27624f3cfb13",
 CellTags->"Null"],
Cell[5616, 173, 320, 9, 64, "Input",ExpressionUUID->"d2600751-ce16-49f0-883c-0024cb6204c1",
 InitializationCell->True],
Cell[5939, 184, 8218, 205, 729, "Input",ExpressionUUID->"70027a8c-9c77-404b-bfd6-40e77bf16c8f",
 InitializationCell->True],
Cell[14160, 391, 6090, 147, 463, "Input",ExpressionUUID->"21d7da78-5f51-49c7-b4ca-17b5e2fe4234",
 InitializationCell->True],
Cell[20253, 540, 4165, 105, 368, "Input",ExpressionUUID->"6c2367ec-40ef-4041-a0bd-cfefbe4445a9",
 InitializationCell->True],
Cell[24421, 647, 3814, 96, 634, "Input",ExpressionUUID->"5cb8150c-f857-43b3-8292-b20c737bf78b",
 InitializationCell->True],
Cell[28238, 745, 17374, 428, 1589, "Input",ExpressionUUID->"51b0293f-8092-4334-8422-867597a7859a"]
}, Open  ]],
Cell[CellGroupData[{
Cell[45649, 1178, 78, 0, 67, "Section",ExpressionUUID->"ff4f298a-2f6e-48d8-8718-5d64e9881cd4"],
Cell[45730, 1180, 13151, 454, 2382, "Input",ExpressionUUID->"d8aca19b-7c27-4ad7-a9b3-3b44411e282f",
 InitializationCell->True],
Cell[58884, 1636, 2147, 59, 387, "Input",ExpressionUUID->"c3b4ae23-b847-422d-babc-ff719d6f9e78",
 InitializationCell->True],
Cell[61034, 1697, 887, 25, 102, "Input",ExpressionUUID->"48d9ff28-db18-4611-a26c-b9f9476dd52f",
 InitializationCell->True]
}, Open  ]],
Cell[CellGroupData[{
Cell[61958, 1727, 95, 0, 67, "Section",ExpressionUUID->"183472f6-cae5-4a95-92ef-e33c01366c36"],
Cell[62056, 1729, 4660, 115, 615, "Input",ExpressionUUID->"27b6f119-18d2-4c9e-923d-4ae2b299b6ca",
 InitializationCell->True],
Cell[66719, 1846, 12460, 291, 1224, "Input",ExpressionUUID->"4904bac8-6ea2-4997-955f-7e7eb7e2b2f2",
 InitializationCell->True],
Cell[79182, 2139, 11122, 249, 1148, "Input",ExpressionUUID->"77d8577b-a9f7-47e6-aed5-fce8a1a2e809",
 InitializationCell->True]
}, Open  ]],
Cell[CellGroupData[{
Cell[90341, 2393, 103, 0, 67, "Section",ExpressionUUID->"315dc0f1-caf9-4773-8e10-c41ff9ede902"],
Cell[90447, 2395, 2277, 55, 197, "Input",ExpressionUUID->"cf091b1f-dfc5-44e9-9748-79166b0bff6a",
 InitializationCell->True],
Cell[92727, 2452, 20568, 500, 1452, "Input",ExpressionUUID->"90eedb57-63e5-4051-bbf3-c598ef4091d2",
 InitializationCell->True],
Cell[113298, 2954, 684, 19, 67, "Input",ExpressionUUID->"990fb4aa-55e0-46e8-9855-edacfcc08272"],
Cell[113985, 2975, 265, 7, 44, "Input",ExpressionUUID->"f1ba292c-7715-4963-8f6e-1f2cd2a4450d",
 InitializationCell->True]
}, Open  ]],
Cell[CellGroupData[{
Cell[114287, 2987, 97, 0, 67, "Section",ExpressionUUID->"2fa78e99-043e-441e-ab23-3378ec6485f5"],
Cell[114387, 2989, 3335, 93, 349, "Input",ExpressionUUID->"f1d4e12e-5a21-48fe-913d-bd3bed8fdb5f",
 InitializationCell->True],
Cell[117725, 3084, 1451, 39, 159, "Input",ExpressionUUID->"c0d3cdd3-a017-4bb5-aec7-14772de3c871",
 InitializationCell->True],
Cell[119179, 3125, 274, 7, 44, "Input",ExpressionUUID->"29cfbfd9-c1a1-4f08-8fc7-7985e54db081",
 InitializationCell->True],
Cell[119456, 3134, 4243, 107, 444, "Input",ExpressionUUID->"e7ad758f-29d5-480d-b808-ccec019e08ee",
 InitializationCell->True]
}, Open  ]],
Cell[CellGroupData[{
Cell[123736, 3246, 93, 0, 63, "Section",ExpressionUUID->"a140b911-b019-476e-bcce-66adb1b6f37b"],
Cell[123832, 3248, 154, 4, 31, "Input",ExpressionUUID->"4cd65046-4aa4-43a5-a696-c5dbe4826bfb",
 InitializationCell->True]
}, Closed]],
Cell[CellGroupData[{
Cell[124023, 3257, 85, 0, 49, "Section",ExpressionUUID->"b795fc42-7e04-4a39-8635-acf99783e943"],
Cell[124111, 3259, 302, 8, 52, "Input",ExpressionUUID->"33bb095d-3982-4671-a7c0-edca6cc9ecd9",
 InitializationCell->True]
}, Closed]]
}, Open  ]]
}
]
*)

