Message Boards Message Boards

0
|
4615 Views
|
43 Replies
|
12 Total Likes
View groups...
Share
Share this post:

How to set up a simple plot of pH against volume of titrant?

Posted 1 year ago

My very first notebook. I have the following equation Vb = Va * ((Ca/(1 + H/Ka)) - H + Kw/H) / ((Cb/(1 + Kw/(H*Kb))) + H - Kw/H) which I have managed to set up in Mathematica. I have tested it by entering different values of pH one at a time. For given values of Ca, Cb, Ka, Kb, Kw, and Va, I want to plot pH (y-axis) against Vb (x-axis) by specifying a range and increment of pH (e.g., from pH 3.0 to 12.5 in steps of 0.2) I would also like to tabulate the values of pH and Vb.

My longer-term goal is to use manipulate to illustrate the effects of changes to Ca, Cb, Ka, Kb, and Va

Any help with giving me a kickstart will be much appreciated

POSTED BY: Paul Newton
43 Replies
Posted 1 year ago

Quiet nice!

POSTED BY: Paul Newton
Posted 1 year ago

suppress that Solve: message

Wrap it your Solve[...] expression with Quiet. So Quiet[Solve[...]] or Solve[...]//Quiet

why, after making a change to the code, I have to Evaluate the notebook twice for the changes to be reflected?

I'm just guessing, but it probably has to do with all these symbols being global and therefore the sequence of computation is important.

So, for example if at the top of my notebook a evaluate a=7 and then later evaluate b=a, at that point we have "facts" that a is 7 and b is 7. Now if you evaluate a=13, you've only changed one of those facts, i.e. a is now 13 but b is still 7. If instead you had written b := a, then b would "pick up" the value of a each time it is evaluated.

But I haven't gone through your notebook recently, so that's just a guess.

POSTED BY: Eric Rimbey
Posted 1 year ago

Thanks. I had to do this

relationEquation=Vb==Va*((Ca/(1+H/Ka))-H+Kw/H)/((Cb/(1+Kw/(H*Kb)))+H-Kw/H);
    makeRelationEquation[Ka_,Kb_,Ca_,Cb_,Va_]=relationEquation;]

    relationEquation2=Vc==Va*((Ca/(1+H/Ka))-H+Kw/H)/((Cb/(1+Kw/(H*Kb)))+H-Kw/H);
    makeRelationEquation2[Ka_,Kb_,Ca_,Cb_,Va_]=relationEquation2;

because using the first pair of equations and setting Vb = 10 seemed to screw things up further down. Notice I have replaced Vb with Vc and set Vc = 10 to do the calculation.

It would be nice if I could somehow suppress that Solve: message (in red, see picture a couple of posts back)

P.S. Do you know why, after making a change to the code, I have to Evaluate the notebook twice for the changes to be reflected?

POSTED BY: Paul Newton

It would be nice if I could somehow suppress that Solve: message

Use exact numerical values

x = Solve[Rationalize[makeRelationEquation[Ka[pKa1], Kb[pKb], Ca1, Cb1, Va], 0], H];

Use Quiet with caution. It will suppress all messages.

POSTED BY: Rohit Namjoshi
Posted 1 year ago

Thank you, Rohit. Your suggestion looks as if it should be better and I have modified it thus:

x1A = Solve[
   Rationalize[makeRelationEquation2[Ka[pKa1], Kb[pKb], Ca1, Cb1, Va],
     0], H, Assumptions -> H > 0];

However the results of the two approaches are as shown (x1 is the original approach, x1A is your suggestion)

enter image description here

How would I get the numeric value from that last part?

POSTED BY: Paul Newton

With exact input the result is also exact. In this case Root objects. Instead of the complicated nested Part you can do this

sol = H /. x

Which will return a list of the 4 solutions in sol. To get the numerical (inexact values)

sol // N

To get exact representations of the Root objects

sol // ToRadicals
POSTED BY: Rohit Namjoshi
Posted 1 year ago

Because I am using Assumptions -> H > 0 I am only dealing with one solution not four. However I tried your suggestions and this is what I get (so //N is not in fact giving me a number but a list and I would still need to extract the numeric value)

enter image description here

POSTED BY: Paul Newton

Paul,

Please post complete working code. relationEquation2 refers to symbols Ca and Cb that are not defined anywhere earlier in this thread. Here is what I evaluated

Kw = 1.00*10^-14;
Ka[pKa_] := 10^-pKa;
Kb[pKb_] := 10^-pKb;
pKa1 := 4.757;
pKb := 0.63;
Ca1 := 0.1;
Cb1 := 0.1;
Va := 10;
Vb := 10;
relationEquation = 
  Vb == Va*((Ca/(1 + H/Ka)) - H + Kw/H)/((Cb/(1 + Kw/(H*Kb))) + H - Kw/H);
makeRelationEquation[Ka_, Kb_, Ca_, Cb_, Va_] = relationEquation;
x = Solve[Rationalize[makeRelationEquation[Ka[pKa1], Kb[pKb], Ca1, Cb1, Va], 0], H];

Extract the solutions, select the positive one and convert to a numerical value

H /. x // Select[Positive] // First // N
(* 2.06037*10^-9 *)

Exact value

H /. x // Select[Positive] // First // ToRadicals
(* Long expression *)
POSTED BY: Rohit Namjoshi
Posted 1 year ago

Many thanks, Rohit.

H /. x // Select[Positive] // First // N

was what I needed. It's working perfectly and much better than what I had before.

POSTED BY: Paul Newton

Another option is to use SolveValues, then ReplaceAll is not needed.

x = SolveValues[
  Rationalize[makeRelationEquation[Ka[pKa1], Kb[pKb], Ca1, Cb1, Va], 0], H]
x // Select[Positive] // First // N
POSTED BY: Rohit Namjoshi
Posted 1 year ago

I am not sure what you mean by ReplaceAll is not needed. As far as I can see ReplaceAll never entered the discussion. In any event, I now have a working solution, so thank you.

POSTED BY: Paul Newton

/. is ReplaceAll.

POSTED BY: Rohit Namjoshi
Posted 1 year ago

Ah, that explains it ...

POSTED BY: Paul Newton
Posted 1 year ago

I believe I may have a solution. From a chemistry perspective, the only valid solutions are those where H > 0. I believe that only one solution will meet the criterion H > 0 and although I could be wrong I propose to use that as a working hypothesis. In which case I can do this

x = Solve[makeRelationEquation[Ka[pKa1],Kb[pKb],Ca1,Cb1,Va],H,Assumptions->H>0];
x
pH = -Log10[Part[Part[Part[x,1],1],2]]

Do you have any other ideas? I have tested this with these values:

Kw = 1.00*10^-14;
Ka[pKa_] := 10^-pKa;
Kb[pKb_] := 10^-pKb;
pKb := 0.2;
Ca1 := 0.1;
Cb1 := 0.1;
Va := 10;
Vb := 10;
pKa := 0.63 and pKa := 4.757
POSTED BY: Updating Name
Posted 1 year ago

Oh, sorry, I somehow was looking at a stale page. So, the criteria is simply positive. And you've already figured out how to use Assumptions. I think that's a good solution.

POSTED BY: Eric Rimbey
Posted 1 year ago

Hi Eric, I am trying to adapt some of the code that you have previously provided to give me H (and hence pH) for just one value of Vb and this is what I have so far:

Kw = 1.00*10^-14;
Ka[pKa_] := 10^-pKa;
Kb[pKb_] := 10^-pKb;
pKa1 := 4.757;
pKb := 0.63;
Ca1 := 0.1;
Cb1 := 0.1;
Va := 10;
Vb := 10;
relationEquation=Vb==Va*((Ca/(1+H/Ka))-H+Kw/H)/((Cb/(1+Kw/(H*Kb)))+H-Kw/H);
makeRelationEquation[Ka_,Kb_,Ca_,Cb_,Va_]=relationEquation;
x = Solve[makeRelationEquation[Ka[pKa1],Kb[pKb],Ca1,Cb1,Va],H];
x
pH = -Log10[2.06037 * 10^-9] 

This gives the following: enter image description here

Obviously I had to select which of the four values in x was the sensible one and I wondered if there is a better, more direct way of getting the result. Thanks.

POSTED BY: Paul Newton
Posted 1 year ago

Probably, yes. Can you explain how you determine what a sensible value is? (I haven't gone back through this thread, so sorry if it's obvious.)

POSTED BY: Eric Rimbey
Posted 1 year ago

That looks fantastic. At the moment I am working on getting data from a number of sources in order to compare and check results. This will take some time. Also, tomorrow I am taking delivery of a new computer and I'll need a few days to set it up and transfer stuff from my old computer.

All in all, I probably won't be able to look at this again until towards the end of next week. I hope that is OK with you and I really appreciate all the work you have put in so far.

POSTED BY: Paul Newton
Posted 1 year ago

I just realized that I didn't do anything around the table/columnar view, but I suspect you're pretty close on that part. Feel free to ask if there are still questions there.

POSTED BY: Eric Rimbey
Posted 1 year ago

I don't know if you are still keeping an eye on this discussion, Eric, but if you are I thought you might be interested in what I have finally come up with. If you, or anybody else, is interested I will happily attach my notebook (such as it is).

POSTED BY: Paul Newton
Posted 1 year ago

Sure!

POSTED BY: Eric Rimbey
Posted 1 year ago

It's a first attempt and I am sure that you could pick it to pieces ..anyway you can find it here Trying to add a legend when using CombinePlots I couldn't have got even this far without your considerable help, so thank you once again.

POSTED BY: Paul Newton
Posted 1 year ago

POSTED BY: Eric Rimbey
Posted 1 year ago

If this is all true, - it is the truth, the whole truth and nothing but the truth

Yes, exactly, we can let the user manipulate Ka, Kb, Ca, Cb and Va

we want to show this in either orientation (i.e. for a target pH we want to see what Vb volume we need, or alternatively for a given Vb volume we want to know the pH we achieve

Yes again, but in both cases I would prefer pH on the y-axis

I had already sorted default values in Manipulate and that (and other things) are on the last notebook I attached and I did follow up on all the things you sent and referred to.

POSTED BY: Paul Newton
Posted 1 year ago

So, just as a sanity check, H is really hydrogen ions, and pH is based on that somehow, so solving for H is equivalent to solving for pH. That is, solving for H and scaling appropriately is what we mean by solving for pH.

More sanity checks:

  • Kw is a fixed constant
  • parameters for the experiment are Ka, Kb (i.e. we might let the user specify these, but they represent using completely different acid/base combinations)
  • the free variables, what we want the user to be able to manipulate, are Ca, Cb, and Va (i.e. having pre-determined Ka, Kb, these are the variables that the user "plays" with)
  • we want to show the relationship between pH (or H) and Vb (i.e. having values for all of the aforementioned variables, we just crank out the arithmetic).
  • we want to show this in either orientation (i.e. for a target pH we want to see what Vb volume we need, or alternatively for a given Vb volume we want to know the pH we achieve)

If this is all true, I actually think this is pretty easy (assuming the choices for the variables produce valid numerical answers) and we were almost there. Later today I'll put something together and try to answer your questions. In the meantime, if you look at the things I sent you about number formatting you can probably answer some of them yourself. Also, the default-value-for-manipulate-controls is answered in the documentation for Manipulate. You might be able to finish this before I get back to it.

POSTED BY: Eric Rimbey
Posted 1 year ago

Sorry for the confusion - "we don't need to know anything about Ka or Kb" applies in the laboratory situation when we are dealing with real solutions and glassware. Again, we are only solving for Ca in the laboratory.

So to clarify (and this will make more sense when you look at my latest version of the notebook which I have attached and to which I have added a number of enhancements)

Kw is always a constant 1.0 E-14

Ka, Kb are dependent on the acid and base respectively and will always be known

Ca, Cb are the concentrations of the acid and base respectively - and in the case of our Mathematica approach will be determined by the user

Va is the volume of acid to which we are adding the base - the user sets this value, usually to 5, 10, 20 or 25

What we are trying to achieve is a plot of pH vs Vb. We can do this in one of two ways;

The first way (which we have been working on) is to calculate Vb from pH. The resulting graph has Vb on the y-axis and pH on the x-axis - I don't know if the axes can be transposed, but it would be nice if they could

The second way (which is what we want to do next) is to calculate pH from Vb and then plot pH (y-axis) against Vb (x-axis). You said that you might find a way " I think we might be able to coerce Mathematica into solving the big hairy formula for pH." It might be a good idea to do this in a separate notebook.

I hope all this now makes sense but, if not, please let me know.

Attachments:
POSTED BY: Paul Newton
Posted 1 year ago

That would be brilliant. There is absolutely no hurry -as it is, I'm going to be quite busy trying out your various suggestions. I thought you might like some background, so here goes:

Basically, this is an acid-base titration. We start off with a volume Va of an acid of "strength" Ka and (unknown) concentration Ca in a conical flask. Ka is a property of the acid in question. We can decide on what volume of acid Va we want to use. (typically 10, 20, or 25 cm3)

We then add from a burette incremental volumes Vb of the base of "strength" Kb. Kb is a property of the base, and we can decide on what (known) concentration of base Cb we want to use.

Experimentally, we don't need to know anything about Ka or Kb. For example, we place volume Va of acid of unknown concentration in the flask and then add the base of known concentration from the burette until the "end-point" is reached. Then note the volume of base Vb that was added to reach the end-point. From that, we can calculate the concentration of the acid in the flask.

POSTED BY: Paul Newton
Posted 1 year ago

Okay, I think I understand that. What I'm confused about is what you're trying to find. Previously, it sounded like you were solving for pH, but now it sounds like you're solving for Ca. And when we started, we were solving for Vb. I guess I'm also confused about this: "we don't need to know anything about Ka or Kb". Either we have values for Ka & Kb, or we don't. They seem to be present in the formula you referenced, so I don't know how to set this up for the case where we don't know those values.

Here's what it sounds like to me. We have some acid solution. We must know some of its properties, but I'm confused about which ones. What we don't know but would like to know is its concentration, Ca. We have some base solutions, and we know some of their properties. If we can get to a neutral solution (I assume that's the "endpoint", but maybe it's some other pH) by adding a known amount of the base, we can calculate Ca with this complicated formula. So, we're solving for Ca, and we need a formula where Ca is defined in terms of all of these other independent variables. It sounds like the goal is to solve that complicated formula for Ca. Am I on the right track?

POSTED BY: Eric Rimbey
Posted 1 year ago

Okay, sorry for the back-and-forth...

So, what we have is a relation between acid-volume and base-volume. It's expressed as acid-volume = base-volume * (some big hairy mess based on the other measurements/parameters). Is that correct?

And what you'd like is a formula that outputs pH based on the various acid/base measurements/parameters. Correct?

If my understanding is correct, then I think we might be able to coerce Mathematica into solving the big hairy formula for pH. But I'm heading out, away from my computer, for a bit. So, I can't set this up right now.

POSTED BY: Eric Rimbey
Posted 1 year ago

Sure. Sorry about the units (can't do superscripts here) Ca and Cb are the concentrations in mol dm-3 of an acid and a base Va and Vb are the volumes in cm3 of the acid and base Ka and Kb are the dissociation constants of the acid and base in mol dm-3 Kw is the ionic product of water in mol2 dm-6

The equation comes from an article in the journal School Science Review

Greatorex, D., 'Exact algorithms for acid/base titration curves', S.S.R. 1979, 214, 61, 94

I eventually got hold of a copy (attached) with help of a very kind ladyn at the Association for Science Education (the publishers of S.S.R.)

Attachments:
POSTED BY: Paul Newton
Posted 1 year ago

Can you tell me what each of the symbols is? Or provide a reference to the formula you’re using?

POSTED BY: Eric Rimbey
Posted 1 year ago

Vis-a-vis the divide by zero range error, it's a shame that instead of (for example) {Kb,0,1} which means 0 <= Kb <= 1 there could be way of stating the range as 0 < Kb <= 1

POSTED BY: Paul Newton
Posted 1 year ago

Many thanks, Eric. Best if I reply like you, referring to numbered sections/paragraphs

  1. That's now sorted, and something else I've learned

  2. Rewriting the equation would be a problem (at least for me). In Excel, I was able to use the equation as given (Vb = .....) and use GoalSeek. You have to specify an initial guess value, give it the value sought, and the cell to adjust in order to achieve that value. Might there be a way to do something similar with Mathematica?

3A I followed your instructions, and all is well, BUT when first run, there is a problem (see attached screenshot). This must be because one of the ranges starts at 0. Ideally, can we specify a range (say 0-5) and a default value (say 2.5)?

3B I will study the reference you provided and see whether it helps

4 That's what I wanted, and again will follow up on the reference

5 I'll start following up on your suggestions tomorrow, but I presume Table will now look something like

Table[{x, Vb[x, 0.1, 0.1, 4.76, 0.63, 1.*^-14, 10]}, {x, 3, 12.5, 0.2}]

Attachment

Attachments:
POSTED BY: Paul Newton
Posted 1 year ago

Thanks for that explanation - I had read up about SetDelayed but was not familiar with patterns. A couple of things arising:

  1. I would like to use pKa instead of Ka, where pKa = -logKa (or Ka = 10^-Ka). I have attempted this by trying to follow the example used for pH but cannot get it to work. My attempt (commented out) is in the attached notebook.

  2. I started my approach by calculating Vb for a range of values of pH because this seemed to be the quickest way to get started but what I really want to do is calculate pH for a range of values of Vb (this would more closely what happens in the laboratory). I would then plot pH on the y-axis against Vb on the x-axis. I am not sure whether we can use (some) of what we have already or would have to reformulate things to achieve this.

  3. Manipulate is working nicely (as a newcomer to Mathematica, I am blown away by what can be done with it). I have attached Manipulate.PNG - in this screenshot, I don't really want to see the lower output because the upper input displays the result (11.3973) anyway. Is that possible? Also, can the number of decimal places in the result be specified so in this case, it would display as 11.40?

  4. In manipulate, rather than specify a range that results in a slider control, is it possible (for some items at least) to offer the user a choice of three or four predefined values?

  5. Lastly (for now, at least), is it possible to have the table output arranged as two columns rather than a collection of ordered-pair values?

I do hope I am not asking too much all at once. My revised notebook shows my attempts referred to above.

Attachment

Attachments:
POSTED BY: Paul Newton
Posted 1 year ago

1.

I would like to use pKa instead of Ka...

The expression

Ka[pKa_] := 10^-pKa

was evaluated after

Ka = 1.75 * 10^-5

and you can't set DownValues for a constant number. You can either clear definitions for Ka (e.g. ClearAll[Ka]) before your new definition, or just remove the first expression entirely if you're not going to depend on it as a constant anymore (although you'll still need to clear the symbol or restart the kernel because that definition will still be in Mathematica's "memory" even if you don't see it in the notebook anymore).

POSTED BY: Eric Rimbey
Posted 1 year ago

2.

...what I really want to do is calculate pH for a range of values of Vb...

If you can rewrite the equation in terms of ph = <some complicated expression>, then sure, that's doable. I'm not going to try to do it myself :). Then we'll just write a definition like ph[<arguments go here>]:=<new definition goes here>.

POSTED BY: Eric Rimbey
Posted 1 year ago

3A.

...I don't really want to see the lower output because the upper input displays the result...

You somehow ended up with the output of the Manipulate as an input (or something like that). Just delete all of the output cells and re-evaluate. But before re-evaluating, remove the semi-colon from after the Manipulate expression. That semi-colon is suppressing the output.

POSTED BY: Eric Rimbey
Posted 1 year ago

3B.

...Also can the number of decimal places in the result be specified...

Look at the various *Form methods: http://reference.wolfram.com/language/guide/DisplayOfNumbers.html

Try NumberForm, for example.

POSTED BY: Eric Rimbey
Posted 1 year ago

4.

a choice of three or four pre-defined values

Yes. This is documented for Manipulate: http://reference.wolfram.com/language/ref/Manipulate.html

Specifically, you could use this form for (to take one example) Cb:

{Cb, {0.05, 0.1, 0.15}}

which will give you a setter bar with three choices.

POSTED BY: Eric Rimbey
Posted 1 year ago

5.

is it possible to have the table output arranged as two columns

TableForm[Table[{x, Vb[x]}, {x, 3, 12.5, 0.2}]]

If you're going to want to do further processing on that data, then I suggest you first save the data in a variable:

dataPairs = Table[{x, Vb[x]}, {x, 3, 12.5, 0.2}];
TableForm[dataPairs]

The various *Form functions are just special wrappers that the front end knows how to interpret to give certain visualizations. You rarely want to use form-wrapped expressions in computations. In other words, you probably do NOT want to do this:

dataPairs = TableForm[Table[{x, Vb[x]}, {x, 3, 12.5, 0.2}]]

TableForm has a bunch of options if you want to tweak further.

POSTED BY: Eric Rimbey
Posted 1 year ago

Many thanks Eric, that will definitely get me over the next hurdle. I am curious as to what is the purpose or significance of the underscores as in H[pH_] := 10^-pH; It is getting close to midnight here so I will look at your suggestions tomorrow and takes things from there.

POSTED BY: Paul Newton
Posted 1 year ago
Posted 1 year ago

What I think you want to do is set up a function that takes pH as an argument. Since H also depends on pH, I suggest you turn that into a function as well. So,

(* parameters *)
Ca = 0.1;
Cb = 0.1;
Ka = 1.75*10^-5;
Kb = 0.63;
Kw = 1.*10^-14;
Va = 10;

(* functions *)
H[pH_] := 10^-pH;
Vb[pH_] := Va*((Ca/(1 + H[pH]/Ka)) - H[pH] + Kw/H[pH])/((Cb/(1 + Kw/(H[pH]*Kb))) + H[pH] - Kw/H[pH])

A quick test:

Vb[11.9]
(* 11.8865 *)

Here is how you could generate some data for pH versus Vb:

Table[{x, Vb[x]}, {x, 3, 12.5, 0.2}]

Okay, now things change a bit. You said

My longer term goal is to use manipulate to illustrate the effects of changes to Ca, Cb, Ka, Kb and Va

Okay, so these other symbols aren't actually constants. So, you probably want to define Vb as a function of all of these arguments:

Vb[pH_, Ca_, Cb_, Ka_, Kb_, Kw_, Va_] := 
  Va*((Ca/(1 + H[pH]/Ka)) - H[pH] + Kw/H[pH])/((Cb/(1 + Kw/(H[pH]*Kb))) + H[pH] - Kw/H[pH])

You could replace H[pH] with the explicit expression 10^-pH. Now you can plug in whatever values you want:

Vb[11.9, 0.1, 0.1, 1.75*10^-5, 0.63, 1.*^-14, 10]

This should set you up for an easy Manipulate, but I don't know what ranges you want:

Manipulate[
 Vb[pH, Ca, Cb, Ka, Kb, Kw, Va],
 {pH, 3, 12.5},
 {Ca, < put bounds here >},
 {Cb, < put bounds here >},
 {Ka, < put bounds here >},
 {Kb, < put bounds here >},
 {Kw, < put bounds here >},
 {Va, < put bounds here >}]

Oh, and here's a plot:

Plot[Vb[pH, 0.1, 0.1, 1.75*10^-5, 0.63, 1.*^-14, 10], {pH, 3, 12.5}] 

enter image description here

POSTED BY: Eric Rimbey
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract