The Wolfram Emerging Leaders Program: High School (WELP:HS) is a remote, semester-long program designed for exceptional graduates from the Wolfram High School Summer Research Program to continue to develop their skills. Students work in a small group over the course of a semester to do either a research-based project or a product development–based project under the guidance of expert mentors. Projects are centered around a topic at the intersection of the group’s interests.
​
This essay was written by:
◼
  • Nicholas Wang
  • ◼
  • Alexander Do
  • ◼
  • Tvesha Ghosh
  • In this project, we investigate Chemical Kinetics: the branch of chemistry dealing with the rates of chemical reactions. Currently, the Wolfram Language lacks significant in-built functions relating to Chemical Kinetics. We specifically explore and develop functions related to the Method of Initial Rates, the Integrated Rate Law, and graphical methods.

    Introduction

    Chemical reactions define the process by which chemicals interact to reformulate new chemicals, or when reactants (before) transform into products (after). In this project, we delve into the world of Chemical Kinetics, investigating the speed at which these reactions occur. We primarily use the rate law formula, given by:
    Generally, the reaction of a chemical reaction can be mapped out according to the following equation:
    rate=
    n
    m
    k[A]
    [B]
    where k is the proportionality/rate constant, A and B are the concentrations of reactants A and B respectively, and m and n are the order rates for reactants A and B respectively, given by integer terms.
    As an important note: if the exponent of any reactant is 1, is it called a first-order reaction with respect to that reactant, and if the exponent is 2, it is called second-order and so on. Adding the exponents up will name the equation as whole first-order, second, etc. In this project, we will explore different methods of visualizing the rate law, including the Method of Initial Rates, Integrated Rate Laws, and Graphical Methods.

    The Method of Initial Rates

    In this section, we develop automatic functions to determine the chemical equation for any set of two-reactant data. Using the Method of Initial Rates, our process begins with method explanation, then moves to coding of individual reactant rate functions and the rate constant functions, and finally puts everything together into the final function.

    Method

    Based on this formula, the Method of Initial Rates finds the values of the reactant orders by experimentally holding one reactant constant at a time under controlled conditions. By observing the change in one reactant while the other is held constant, each order rate can be determined. For our purposes, we will be developing a function that can compute a chemical reaction based on a table of data.
    In[]:=
    dataBF3NH3=Import["https://www.wolframcloud.com/obj/1db33ec5-c1c6-45db-a3d4-2ed401f0af09",{"XLS","Dataset",1,;;6}]
    Out[]=
    Experiment
    [BF3](M)
    [NH3](M)
    Initial Rate (M/s)
    1.0
    0.25
    0.25
    0.213
    2.0
    0.25
    0.125
    0.1065
    3.0
    0.2
    0.1
    0.0682
    4.0
    0.35
    0.1
    0.1193
    5.0
    0.175
    0.1
    0.0596
    The general strategy is to find where a reactant B is held constant and determine the start and end of the “constant chain”. Let’s say A1 is the concentration of reactant A at the start of the constant chain, A2 is the concentration of reactant A at the end of the constant chain, R1 is the rate at the start of the constant chain, and R2 is the rate at the end of the constant chain. The order of A is as follows:
    In[]:=
    Row[{Divide[A2,A1]^rateA,"=",Divide[R2,R1]}]
    Out[]=
    rateA
    A2
    A1
    =
    R2
    R1
    Rate A is thus equal to:
    In[]:=
    Log[Divide[Divide[R2,R1],Divide[A2,A1]]]
    Out[]=
    Log
    A1R2
    A2R1
    

    Individual Reactant Rate Functions

    The following code uses the general strategy explain above to find the order rate of reactant A given the start and end of a reactant B constant chain, and vice versa.
    In[]:=
    order[pos1_List,pos2_List,data_]:=​​Module[{Rratio,Sratio},{Rratio=data[pos2[[1]],4]/data[pos1[[1]],4],Sratio=data[pos2[[1]],pos2[[2]]]/data[pos1[[1]],pos1[[2]]]};​​Round[Log[Rratio]/Log[Sratio]]]
    For example, seeing that Row 4, Column 2 and Row 6, Column 2 is the end, are the start and end of Reactant 2, the order rate of Reactant 1 is:
    In[]:=
    order[{4,2},{6,2},dataBF3NH3]
    Out[]=
    1
    Next, we develop a method to automatically find these constant chains. First, we split a reactant column into a list, gather by the similar term, and find the first and last positions of the same term. With this method actually, the constants don’t actually have to be right next to each in a chain, there just needs to exist at least two constants.
    In[]:=
    check=Normal[dataBF3NH3[[All,3]]]
    Out[]=
    {[NH3](M),0.25,0.125,0.1,0.1,0.1}
    In[]:=
    term=MaximalBy[Gather[check],Length][[1,1]]
    Out[]=
    0.1
    In[]:=
    pos=Flatten[Position[dataBF3NH3[[All,3]],term],1]
    Out[]=
    {4,5,6}
    In[]:=
    First[pos]​​Last[pos]
    Out[]=
    4
    Out[]=
    6
    Next, we put all of this reactant/column rate work into one function. In this function, the specification for column is actually unintuitively swapped; for example, inputting column 2 will find the constants for column 2 and actually spit out the column rate for column 3, and vice versa.
    In[]:=
    columnrateOG[column_,data_]:=​​Module[{list,term,pos},list=Normal[data[[All,column]]];term=MaximalBy[Gather[list],Length][[1,1]];pos=Flatten[Position[data[[All,column]],term],1];​​Which[column==2,order[{First[pos],3},{Last[pos],3},data],column==3,order[{First[pos],2},{Last[pos],2},data]]]
    Thus, finding the column rate of Reactant 3 means plugging in Reactant 2:
    In[]:=
    columnrateOG[2,dataBF3NH3]
    Out[]=
    1
    Finding the column rate of Reactant 2 means plugging in Reactant 3:
    In[]:=
    columnrateOG[3,dataBF3NH3]
    Out[]=
    1

    Rate Constant Functions

    The next step of our equation is to find the rate constant, k, which is defined as:
    In[]:=
    Solve[k*A^a*B^b==r,k]
    Out[]=
    {{k
    -a
    A
    -b
    B
    r}}
    The variables are the same as previously defined in the general equation; r is the rate.
    Given that we have access to real data, we can take the concentrations of any row and use the order rates we have already found to solve the equation for K. However, we first need to define the units. While the k units should in theory be the same between every order 0, order 1, order 2, etc function, this rigorous method also works.
    Extract the unit from the first row:
    In[]:=
    extractunit[pos_List,data_]:=​​StringCases[Normal[data[pos[[1]],pos[[2]]]],"("~~s:RegularExpression["[^()]*"]~~")":>s][[-1]]
    Use the relationship between the reactants, order and K to determine the units for k:
    In[]:=
    unitk[data_]:=ToExpression[extractunit[{1,4},data]]/(ToExpression[extractunit[{1,2},data]]^columnrateOG[3,data]*ToExpression[extractunit[{1,3},data]]^columnrateOG[2,data])
    In[]:=
    unitk[dataBF3NH3]
    Out[]=
    1
    Ms
    This matches the appropriate units for a second order reaction. Next, we implement the units while using the established relationship to find the K value:
    In[]:=
    findkOG[data_]:=​​Module[{k=ScientificForm[data[2,4]/((data[2,2])^columnrateOG[3,data]*data[2,3]^columnrateOG[2,data])]},Row[{k,"*",unitk[data]}]]
    In[]:=
    findkOG[dataBF3NH3]
    Out[]=
    3.408*
    1
    Ms

    Final Function and Testing

    Finally, we can put everything together into one equation:
    In[]:=
    writeequationOG[data_]:=​​RowfindkOG[data],
    columnrateOG[3,data]
    Normal[data[[1,2]]]
    ,
    columnrateOG[2,data]
    Normal[data[[1,3]]]
    
    Testing on different data sets from Physical Chemistry textbooks (cited at the end of the essay):
    In[]:=
    dataCLO2OH=Import["https://www.wolframcloud.com/obj/1db33ec5-c1c6-45db-a3d4-2ed401f0af09",{"XLS","Dataset",2,;;4}]
    Out[]=
    Experiment
    (CL02)(M)
    [OH-](M)
    Initial Rate (M/s)
    1.0
    0.06
    0.03
    0.0248
    2.0
    0.02
    0.03
    0.00276
    3.0
    0.02
    0.09
    0.00828
    In[]:=
    writeequationOG[dataCLO2OH]
    Out[]=
    2.2963×
    2
    10
    *
    1
    2
    M
    s
    2
    (CL02)(M)
    [OH-](M)
    When the constant values are right next to each other:
    In[]:=
    dataOCLI=Import["https://www.wolframcloud.com/obj/1db33ec5-c1c6-45db-a3d4-2ed401f0af09",{"XLS","Dataset",5}]
    Out[]=
    Experiment
    [OCl-](M)
    [I-](M)
    Initial Rate (M/s)
    1.0
    0.0015
    0.0015
    0.000136
    2.0
    0.003
    0.0015
    0.000272
    3.0
    0.0015
    0.003
    0.000272
    In[]:=
    writeequationOG[dataOCLI]
    Out[]=
    6.04444×
    1
    10
    *
    1
    Ms
    [OCl-](M)[I-](M)
    When the constant values are the same for each reactant, it works still:
    In[]:=
    dataH2NO=Import["https://www.wolframcloud.com/obj/1db33ec5-c1c6-45db-a3d4-2ed401f0af09",{"XLS","Dataset",4}]
    Out[]=
    Experiment
    H2(atm)
    NO(atm)
    Initial rate (atm/s)
    1.0
    0.38
    0.526
    0.000211
    2.0
    0.27
    0.526
    0.000145
    3.0
    0.193
    0.526
    0.000104
    4.0
    0.526
    0.472
    0.000197
    5.0
    0.526
    0.395
    0.000136
    6.0
    0.526
    0.2
    0.000033

    Order Functions

    Using our work, we can easily write functions for each and total reactant orders.
    For example, on dataH2NO:

    Simple Algebraic Solving with Integrated Rate Laws

    Integrated Rate Laws are a variation of the rate laws in the form k[A]^a[B]^b. While the rate law we saw before dealt with concentrations and rate, we can integrate the equations with respect to relate the rate and the concentrations of each respective reactants. Furthermore, we can manipulate these integrations to determine the half lives of each order.
    In this section, we develop very simple algebraic functions that will solve zero, first, and second order integrated equations for one variable, supplied with other variables. The capabilities are very elementary but may be helpful for beginners, for instance.The following equations and examples are heavily based off of LibreTexts’ textbook, which is cited at the bottom of the essay.

    Zero Order Solving

    To solve our functions, we create a function that will take a variable to solve for, and a list of associations that will specify the other variables.
    Using a LibreTexts’ question to demonstrate the capabilities of the function:
    Using the integrated form of the rate law, determine the rate constant k of a zero-order reaction if the initial concentration of substance A is 1.5 M and after 120 seconds the concentration of substance A is 0.75 M. Using the substance from the previous problem, what is the half-life of substance A if its original concentration is 1.2 M?
    First, we need to find k, our constant. We supply the function with the information:
    Then, we find the half life.

    First Order Solving

    The Percent H202 that decomposes in the time using k=6.40*10^-5, 450 seconds after:
    If 4.00 g of A are allowed to decompose for 40 min, the mass of A remaining undecomposed is found to be 0.80 g. Calculate the half life.

    Second Order Solving

    Graphical Methods

    In this section, we develop functions related to Graphical Methods that will, based on decomposition data, find the correct order rate.

    Method

    First, we will try to linearize the data according to the following rules: zero order is time vs concentration first order is time vs Log[concentration] and second order is time vs 1/concentration. These relationships are derived from the Integrated Rate Law formulas. We will formulate graphs for each, create linearization equations, and then use RSquared values to determine the best linear fit.

    Creating the Functions

    First, let’s retrieve some data (from OpenStax). Generally, the experimental data involved with graphical methods involve a time component, and a decomposing reactant component.
    Next, we will extract the time values and the reactant values, respectively.
    Next, we will develop our big function. Using the time and concentration values, we can thread the lists to create our zero order: time vs concentration, first order, time vs Log[concentration] and second order, time vs 1/concentration data sets. From here, we fit a linear model on each graph using LinearModelFit, find the RSquared value for each graph to determine accuracy, and finally show the graph itself.
    Using our function on dataC4H6, we obtain sublists of each order, its equation, its R squared value, and its graph.
    Next, we write a function to take the best function based on the highest R squared value:
    Placing the function on dataC4H6 indeed outputs the most visually linear graph:
    From these results, we can determine that C4H6 is second order in this example. Additionally, it is important to note that the rate constant (k value) in this type of work is equivalent to the absolute value of slope of the graph, which would in this case be 0.0131376.
    Testing our functions on another set of OpenStax data:
    The equation is first order with a k value of 4.8E^-4.

    Future Work

    Method of Initial Rates

    Method of Initial Rates function works well for our examples, it only works as the specific, two-reactant structure used in this essay due to the heavy calling of specific cells. The following is a list of all the requirements the function current requires:
    ◼
  • Dataset such that the first column is the experiment number, the second column is reactant 1 values, the third column is reactant 2 values, and the fourth column is the rate values (which means the function only works on two reactants).
  • ◼
  • Dataset such that first row follows the order Experiment, Reactant 1, Reactant 2, and rate.
  • ◼
  • Dataset such that the the units for the reactants and rate, if chosen to be included, are in parenthesis, at the end, when typed.
  • In the future, we aim to develop our kinetics table functions less rigorous, such as including 2+ reactants and flexibility to more data types and formats.

    Simple Algebraic Solving with Integrated Rate Laws

    While there is nothing inherently wrong with the code developed in this section, it is still very simplistic: it is merely algebra. Future work could entail Wolfram Language proofs of these laws (although the proofs are widely known), or greater capacities to calculate more complex questions.

    Graphical Methods

    The functions involved in this section work well, but similar to the work in the Method of Initial Rates, could entail less flexibility in data input options. In the future, we could use the ideas entailed in the Graphical Methods to further expand the approachability of our functions. Currently, the limitations of our Graphical Function data inputs are:
    ◼
  • Dataset such that the first column is the time values, and the second column shows the decomposition of one reactant.
  • ◼
  • Dataset such that the first row indexes the columns; the data starts in the second row.
  • General

    Generally, our functions work well, but a glaring problem is the lack of consideration of significant figures in our functions. For future explorations, we can research the effects of heat, pressure, etc. on chemical kinetics functions.

    Citations

    ◼
  • Libretexts. (2021, September 22). 1: Chemical Kinetics - the method of initial rates (experiment). Chemistry LibreTexts. https://chem.libretexts.org/Ancillary_Materials/Laboratory_Experiments/Wet_Lab_Experiments/General_Chemistry_Labs/Online_Chemistry_Lab_Manual/Chem_12_Experiments/01%3A_Chemical_Kinetics_-_The_Method_of_Initial_Rates_(Experiment)#:~:text=The%20method%20of%20initial%20rates%20allows%20the%20values%20of%20these,the%20concentration%20of%20one%20reactant
  • ◼
  • Libretexts. (2022, October 27). 12.3: Rate laws. Chemistry LibreTexts. https://chem.libretexts.org/Bookshelves/General_Chemistry/Chemistry_1e_(OpenSTAX)/12%3A_Kinetics/12.3%3A_Rate_Laws#:~:text=Rate%20laws%20or%20rate%20equations,%5Dn%5BC%5Dp%E2%80%A6
  • ◼
  • Libretexts. (2022a, September 12). 12.4: Integrated Rate Laws. Chemistry LibreTexts. https://chem.libretexts.org/Bookshelves/General_Chemistry/Chemistry_1e_(OpenSTAX)/12%3A_Kinetics/12.4%3A_Integrated_Rate_Laws#:~:text=Integrated%20rate%20laws%20are%20determined,various%20times%20during%20a%20reaction.
  • ◼
  • Libretexts. (2023, February 13). 2.10: Zero-order reactions. Chemistry LibreTexts. https://chem.libretexts.org/Bookshelves/Physical_and_Theoretical_Chemistry_Textbook_Maps/Supplemental_Modules_(Physical_and_Theoretical_Chemistry)/Kinetics/02%3A_Reaction_Rates/2.10%3A_Zero-Order_Reactions
  • ◼
  • Libretexts. (2023a, February 13). 2.3: First-order reactions. Chemistry LibreTexts. https://chem.libretexts.org/Bookshelves/Physical_and_Theoretical_Chemistry_Textbook_Maps/Supplemental_Modules_(Physical_and_Theoretical_Chemistry)/Kinetics/02%3A_Reaction_Rates/2.03%3A_First-Order_Reactions
  • ◼
  • Libretexts. (2023b, February 13). 2.5: Reaction rate. Chemistry LibreTexts. https://chem.libretexts.org/Bookshelves/Physical_and_Theoretical_Chemistry_Textbook_Maps/Supplemental_Modules_(Physical_and_Theoretical_Chemistry)/Kinetics/02%3A_Reaction_Rates/2.05%3A_Reaction_Rate
  • ◼
  • Libretexts. (2021a, September 7). Chapter 14.4: Using graphs to determine rate laws, rate constants and reaction orders. Chemistry LibreTexts. https://chem.libretexts.org/Courses/Howard_University/General_Chemistry%3A_An_Atoms_First_Approach/Unit_6%3A_Kinetics_and_Equilibria/Chapter_14%3A_Chemical_Kinetics/Chapter_14.4%3A_Using_Graphs_to_Determine_Rate_Laws_Rate_Constants_and_Reaction_Orders
  • ◼
  • Libretexts. (2023a, February 13). 2.1.5: Spectrophotometry. Chemistry LibreTexts. https://chem.libretexts.org/Bookshelves/Physical_and_Theoretical_Chemistry_Textbook_Maps/Supplemental_Modules_%28Physical_and_Theoretical_Chemistry%29/Kinetics/02%3A_Reaction_Rates/2.01%3A_Experimental_Determination_of_Kinetics/2.1.05%3A_Spectrophotometry
  • Acknowledgements

    We would like to thank our mentor, Jason Sonnenberg for helping us with the ideation of our project, providing resources, and the invaluable feedback along the way.
    We would also like to thank Rory Foulger and Eryn Gillam for checking in with us along the way, and for facilitating the WELP program.

    CITE THIS NOTEBOOK

    Implementing Chemical Kinetics Functions to the Wolfram Language​
    by Wolfram Emerging Leaders Program​
    Wolfram Community, STAFF PICKS, January 2, 2024
    ​https://community.wolfram.com/groups/-/m/t/3094750