Open jlw387 opened 2 months ago
These are really good points! I was just looking at this:
https://chemistry.stackexchange.com/questions/54111/does-solute-add-to-volume-of-solution
Clearly, we need to be more thoughtful here. Can we have an offline discussion about this? ekwan16@gmail.com
Hello!
I believe I've encountered a fairly substantial problem with the logic of the
create_solution()
function. The problem is this: it seems like the function uses the volumes of solutes as contributing factors to the overall volume of the solution. Here is an example of what I mean:Here I have added 20 grams of salt to a solvent of water with the goal of creating a solution that is 100 mL. I have indeed achieved that outcome, but the volumes of the substances added are 20 mL of salt and 80 mL of water. This seemed obviously wrong to me, as adding a solute should, for the most part, leave the volume of the solution unchanged, as it dissolves in the solvent, and so the final volume of a solution formed by adding 20 g of salt to 80 mL of water should be 80 mL, not 100 mL.
I can make this even more extreme, ignoring realistic solubility for a moment, and create an even more farfetched example:
Here, we would create a 100 mL brine solution with only 10 mL of water and 90 g of salt. Again, in reality, most of the salt would likely not dissolve, but it helps make the issue clearer.
Because solubility is not a parameter of the Substance class, it should allow you to create as concentrated of a solution as you'd like. However, if I push the mass too high, I get the following error:
This is because the 150 g of salt is assumed to take up 150 mL, and so it would be impossible to create a solution with only 100 mL. In reality, salt has a density of 2.16 g/mL, so it should be possible to make even if the two substances (salt and water) remained completely separate.
I dug down into this further, and noticed a few discrepancies in the Substance class. The Substance attribute
density
has the following description:density: Density if 'Substance' is a liquid (g/mL)
. This would imply the field is only supposed to be used when the substance is a liquid, and by default it is set to infinity when a substance is initialized. However, when looking through Substance.solid(), the function I used to create the solid substances, I found this line:https://github.com/ekwan/PyPlate/blob/f2047cc44cb9b8e725e524c2483e3cff2e1726b9/pyplate/pyplate.py#L570C9-L570C57
The default value for the solid density in
pyplate.yaml
is 1, which explains why salt was assumed to have a density of 1 g/mL, but the important thing to note here is that the density is being set for solids, not just liquids, in spite of the comment at the top of the class.Looking back at the
create_solution()
logic, the code sets up a linear system of equations and callsnumpy.linalg.solve()
. As far as I can tell, the source of the issue I'm encountering is here:https://github.com/ekwan/PyPlate/blob/f2047cc44cb9b8e725e524c2483e3cff2e1726b9/pyplate/pyplate.py#L1155-L1159
To get the A entries, the function calls the
convert_one()
function with the unit of the 'total_quantity' entry. If a volume quantity is entered, it results in the function computing volumes of one mole of all the other compounds using theUnit.convert_from()
function, which uses density, which is where the 1 g/mL conversion is coming from. This means that the resulting equation is (for the first salt example):0.1 L = [58.55 g/mol (1 g/mL)^(-1) 0.001 L / mL] x_salt + [18.015 g/mol (1 g/mL)^(-1) 0.001 L / mL] x_water
where x_salt is the moles of salt and x_water is the moles of water. In reality, if we assume for simplicity that solutes take up no volume, the equation should be:
0.1 L = 0 x_salt + [18.015 g/mol (1 g/mL)^(-1) 0.001 L / mL] x_water
This would result in the correct amount of water being added. Thus, unless you are currently trying to support instances where solutes take up non-zero volumes, I would recommend adjusting the logic in this function to simply zero out all the solute entries in this final equation if the total quantity unit is a volume.