MaterialBalances.mw
Steady State Material Balances on a Separation Train
We begin by creating a list of component identities. We could use numbers, chemical formulae, the component names; here we use the first letter of the component names.
Next, we create a list of units. This problem has three distillation columns which shall be identified as follows:
> |
units :=[Col1,Col2, Col3]; |
The streams will also have to be identified. Again, we could use any indexing method that is convenient. Here we number the streams
> |
Streams:=[seq(i,i=1..7)]; |
The number of streams is
> |
NumStreams := nops(Streams); |
The next step is to set up the material balances. To help us do this in a systematic way we create lists of the input streams to and output streams leaving each process unit. The streams entering and leaving the first distillation column are
> |
Inputs[Col1]:=[1]; Outputs[Col1]:=[2,3]; |
The streams entering and leaving the second column are
> |
Inputs[Col2]:=[2]; Outputs[Col2]:=[4,5]; |
and the streams entering and leaving the third column are
> |
Inputs[Col3]:=[3]; Outputs[Col3]:=[6,7]; |
The component material balances for all units can now be created automatically as follows:
> |
j:='j': i:='i':
for u in units do
lprint(`Material Balances for `,u);
for i in components do
CMB[i,u] := add( F[j] * x[i,j], j = Inputs[u]) = add( F[j] * x[i,j], j = Outputs[u]);
print(CMB[i,u]);
od; od; |
`Material Balances for `, Col1
`Material Balances for `, Col2
`Material Balances for `, Col3
In the above Maple construction we have created the component material balances for each component (the inner loop) and for each process unit (the outer loop).
The total molar flows are given the symbol F and x refers to the mole fraction of some component. The first index of the component mole fraction identifies the component in question, the second associates that quantity with a particular process stream. This double loop will work with all simple material balances regardless of complexity provided we have identified the components, the units and the input and output streams associated with each unit.
The mole fraction summation equations can be created as follows:
> |
SumEqn:='SumEqn': i:='i':
for j in Streams do
SumEqn[j]:=add(x[i,j],i=components)=1;
print(SumEqn[j]);
od: |
The component material balances and the mole fraction summation equations comprise the complete set of independent equations for this kind of problem. Any other balance equation can be created from simple combinations of these equations.
We now create a set independent equations to describe the flowsheet
> |
Eqns:={seq(seq(CMB[i,u],i=components),u=Units),seq(SumEqn[j],j=Streams)}; |
The list of variables appearing in these equations is easily found
> |
Vars := indets(Eqns,name); |
and we can count them using the nops function:
The number of equations is computed in a similar way
The number of degrees of freedom is the difference between these two numbers
This is the number of variables that we must specify before we have a consistent set of equations that can be solved (numerically, at least).
We know the flow and composition of the feed stream (note that only three of the feed mole fractions are specified).
> |
Specs[2]:=x[X,1]=0.15; Specs[3]:=x[S,1]=0.25; Specs[4]:=x[T,1]=0.4; |
We need to specify another 12 variables and must look to the problem statement to find out what other specifications we may make.
In the problem as posed the composition of all final product streams is given. However, in view of the mole fraction summation equations we may only specify 3 from each stream; the choice of which to omit is arbitrary - we leave out the lowest mole fraction in most cases.
> |
Specs[5]:=x[X,4]=0.07; Specs[6]:=x[B,4]=0.35; Specs[7] := x[T,4]=0.54; |
> |
Specs[8]:=x[X,5]=0.18; Specs[9]:=x[B,5]=0.16; Specs[10] := x[T,5]=0.42; |
> |
Specs[11]:=x[X,6]=0.15; Specs[12]:=x[B,6]=0.21; Specs[13] := x[T,6]=0.54; |
> |
Specs[14]:=x[X,7]=0.24; Specs[15]:=x[S,7]=0.65; Specs[16] := x[T,7]=0.10; |
We now have the right number of specification equations which we combine in a set
> |
SpecEqns := {seq(Specs[l],l=1..DegFree)}; |
We augment the set of equations with the specification equations
> |
AllEqns := Eqns union SpecEqns; |
We check to see if the numbers of equations and variables are the same.
> |
nops(AllEqns); nops(Vars); |
Now we can ask Maple to solve the equations.
> |
result:=solve(AllEqns,Vars); |
We check the solution by substituting the result into the equations.
and we see that the result that Maple computed does indeed satisfy the equations.