Defining simple process unit models in Jacaranda

Introduction
The example problem
Process streams
Input stream checking
Heat transfer requests
Design
Variables
Equations
Evaluation equations
References

Published in the Jacaranda blog.

Introduction

Although the Jacaranda system comes with a number of pre-defined process unit models (e.g. Distillation), there are many problems in conceptual design that only require simple models. These simple models may not require complex physical property values and may consist of, for instance, idealised mass and energy balances. For these cases, it may be worthwhile to define ad hoc simple models.

Jacaranda provides a generic model for such cases: units.Unit,1 intended for use with streams supporting vapour liquid equilibria properties (although methods for estimating specific VLE properties won't actually be accessible).

Defining an actual model instance using this generic model consists of a number of steps: specifying the process streams that interact with the unit, definining design variables (to allow for analysis and optimisation), defining the equations that describe the unit operation, and defining the equations that can be used for analysis or evaluation (e.g. values used by the criteria definitions). These are described in detail below through the use of a simple example.

The example problem

The problem we wish to consider is the production of HF, as described in Laing & Fraga, 1997. Potential candidate designs for the process need to consider a wide range of units with varying degrees of detail. The units required include a kiln (essentially a reactor), an acid blender, an absorber, a quench unit and distillation. The distillation unit is modelled through the detailed (albeit short-cut) model available in Jacaranda (units.vle.Distillation) whereas the others can be represented using simpler models.

Process streams

There are three types of streams which interact with process units: input (a.k.a. feed) streams, makeup streams (feed streams whose definition depends on the unit operation) and the outputs of the unit. Although makeup streams are really input streams, they differ from input streams in that they are defined as a result of the unit design. The specific input streams, however, will be specified to the unit before the design is attempted.

The kiln unit has one input stream, the main feed, two output streams, the gas stream which is vapour and is the main product of the unit and the waste stream which is in solid phase, and an air make-up stream, of known composition but with the flow rate to be determined by the design model:

use uk.ac.ucl.che.esf.fish.units
Unit kiln
  input feed
  output gas
  output waste
  makeup air air

The feed stream will be specified by Jacaranda prior to any design being attempted.

Output streams are created by the Unit model itself. The general syntax of the output command is:

  output NAME [TYPE]

where the square brackets indicate that the type of the output stream is optional. If specified, this should be a class which implements the ps.StreamExpressionInterface. If the type is not given, as in the example above, the system will create a stream of the default type, units.vle.Stream

The syntax for the makeup command is

  makeup NAME INSTANCE

where the instance should be an actual stream which describes the composition of the makeup stream to be used. The amount or rate of that stream will be defined by the design model equations.

All streams, whether input, output or makeup, will have variables available for use in the design equations. The actual variables defined will depend on the stream definition. For the default base of units.vle.Stream, the following variables are defined: F, the amount or flow of the stream; x, the molar or mass composition in fractions; P, the pressure in atm.; T, the temperature in Kelvin; and, state, the state of the stream (0 is solid, 1 is liquid and 2 is vapour). For input streams, these variables are defined and set before the design is evaluated; for output streams, the design equations should give values to all of these variables as they will then be used to define the actual output streams. For makeup streams, the composition, x, will have been defined but all others will be undefined and should be set by the design model.

Input stream checking

Before attempting a design, Jacaranda will query the unit model to see if the input streams specified are appropriate or not. In other words, the unit will be given a chance to indicate whether the feed streams assigned to the unit are suitable for that unit. The unit does this by specifying a set of conditions for the feed:

  feedconditions LOGICAL_EXPRESSION

which, for the kiln example, looks like this:

  feedconditions "feed.x[CaF2]>epsilon & feed.x[H2SO4] > epsilon"

This is using the feed input stream defined above and looks to see if the stream contains any significant amounts of latex2png equation and latex2png equation.

Heat transfer requests

Most units will require heating or cooling (or both). Requests for heating or cooling are defined using the heat transfer request (HTR) type in Jacaranda. Such requests are defined using the htr command:

  htr NAME

which creates a set of variables for specifying the necessary information for a heat request, much as stream variables are defined. The components of a heat transfer request are Q, the duty (in kW with negative values indicating that heating is required and positive values indicating that the unit has an excess of heat so cooling is required); T1, the inlet temperature for the process stream to be heated or cooled; T2, the outlet temperature of the process stream; and, U, the heat transfer coefficient latex2png equation for the process stream side of any exchange.

For the kiln unit, we define:

  htr heat

Design

Variables

Design variables are variables which alter the behaviour or design of a unit. These variables are intended for Jacaranda to manipulate, either through the synthesis procedure or through generic optimisation methods within Jacaranda. For the synthesis procedure, it is sufficient to indicate that the variable is of type specification; for the general optimisation use, the variables must also be defined as tunable.

For the kiln unit, we define one such variable:

  new specification "Single pass conversion of CaF2" RealSet conversion 0.95 0.96 0.97 0.98 0.99

The general format for defining a new variable is

  new FUNCTION DESCRIPTION TYPE NAME VALUES

where FUNCTION is either specification or specification+tunable, DESCRIPTION is a string which is purely decorative, TYPE is one of Real, RealSet, Int, IntSet or Component, and VALUES describe the range of values the variable should consider when used in either synthesis or optimisation modes. For a RealSet variable, the values are a list of discrete values. For other types, the values will be specified in different ways. For instance, for the Real type, the definition would look like one of the following:

  new specification "Continuous design variable" Real x1 VALUE
  new specification "Continuous design variable" Real x2 MIN MAX N
  new specification "Continuous design variable" Real x3 VALUE MIN MAX N

In the first case, the variable is given the specified value and the minimum and maximum values this variable can have are also this value. This is not particularly useful for design (either for synthesis or optimisation) but could be useful in debugging. The more common case is the second where the definition says that latex2png equation.

When using the synthesis procedures in Jacaranda, N indicates the number of discrete values for this variable within the interval specified. These discrete values will be uniformly distributed across the interval, including both end-points if latex2png equation. If a log based distribution of the discrete points is required, one can use the LogReal type instead of Real.

The final case is the same as the second except that the variable is initialised to have the specific value given which may or may not correspond to one of the discrete values the system would normally use. This will not affect the synthesis procedures but will be useful for the process optimisation methods in Jacaranda.

Equations

When Jacaranda wishes to generate a design of the unit, it will evaluate the equations given using the designequations command. These equations are evaluated by the uk.ac.ucl.che.esf.util.expr expression evaluator. This is essentially a vector based calculator and does not solve a system of simultaneous equations. If solving a complex system of equations is required, the simple unit model is probably not the approach one should take for defining the model. Alternative approaches are beyond the scope of this short note so readers are encouraged to approach the author for suggestions.

For the kiln model, the following are snippets of the equations we use with some commentary:

  designequations
    # initialize the individual stream flows. we use the feed stream
    # composition vector to create new vectors of the correct size.
    gas.f = 0*feed.x
    waste.f = 0*feed.x
    feed.f = feed.F*feed.x		# feed stream individual component flows

The feed stream will have been defined by Jacaranda and the appropriate variables (F, x, T, ...) defined. These variables are accessed by the stream name (as given in the input, output and makeup commands above) followed by the full stop (.) and then the actual variable name. The expression

    feed.f = feed.F*feed.x

creates a vector of feed component flows based on the total flow, F, and the composition, x, of the feed stream.

    # the air intake is directly related to the feed stream flow rate
    air.F = air.ratio * feed.F
    air.f = air.F * air.x

These equations define the actual amount of the air makeup stream required. Recall that a makeup stream will have the composition already defined.

    # determine extents of reactions
    extent = {0, 0, 0}
    if feed.f[CaCO3] > feed.f[H2SO4]
       extent[0] = 0
       extent[1] = feed.f[H2SO4]
    else
       extent[1] = feed.f[CaCO3]
       if feed.f[CaF2] > (feed.f[H2SO4]-extent[1])
          extent[0] = (feed.f[H2SO4]-extent[1])*conversion
       else
          extent[0] = feed.f[CaF2]*conversion
       endif
    endif
    if feed.f[SiO2] > (4*(extent[0]-feed.f[HF]))
       extent[2] = (feed.f[HF]+extent[0])/4
    else
       extent[2] = feed.f[SiO2]
    endif

These equations determine the extends of reaction. There are three reactions and it is important to note that the expression evaluator in Jacaranda uses a zero-based indexing for vectors.

Given the extents of reaction, the output streams can now be defined based on a simple extents of reaction mass balance procedure:

    # now define the actual output stream compositions
    gas.f[H2SO4] = feed.f[H2SO4] - extent[0] - extent[1]
    gas.f[HF] = feed.f[HF] + 2*extent[0] - 4*extent[2]
    gas.f[H2O] = extent[1]
    gas.f[CO2] = extent[1] + air.f[CO2]
    gas.f[SiF4] = extent[2]
    gas.f[O2] = air.f[O2]
    gas.f[N2] = air.f[N2]
    gas.F = $gas.f				# total gas flow
    gas.x = gas.f/gas.F				# and actual composition
    gas.T = feed.T
    gas.P = feed.P
    gas.state = vapour
    waste.f[CaF2] = feed.f[CaF2] - extent[0]
    waste.f[CaCO3] = feed.f[CaCO3] - extent[1]
    waste.f[SiO2] = feed.f[SiO2] - extent[2]
    waste.f[CaSO4] = extent[0] + extent[1]
    waste.F = $waste.f				# total waste stream flow
    waste.x = waste.f/waste.F			# and composition
    waste.T = feed.T
    waste.P = feed.P
    waste.state = solid

Note the use of the $ operator which means sum of all elements of the vector to calculate the total flow of the gas and waste streams.

Given the specifications on the output streams, we can now design the actual physical unit. This includes a simple quadrature rule for evaluating an integral numerically:

    # finally, design the actual reactor which is based on a numerical
    # integration, as described above.
    nsteps = 100
    N = 2/3
    M = 1/3
    k450 = 0.247
    E = 38363
    k = k450 * exp(-1 * E * (1/feed.T - 1/450)/R)
    Xf = conversion
    Xo = preconversion				# preconversion
    Rc = feed.f[CaF2]/(feed.f[CaF2]+feed.f[CaCO3])	# CaF2:CaCO3 ratio
    Ra = (feed.f[H2SO4]-extent[1])/feed.f[CaF2]		# Acid:CaF2 ratio
    dX = (Xf-Xo)/nsteps
    rio = (1.0 - (1.0-Xo)^M) / ( k*(Rc*Rc*(Ra-Xo)*(Ra-Xo)*(1.0-Xo)^N) )
    X = Xo + dX
    t = 0						# residence time in minutes
    while X <= Xf
      ri = (1.0 - (1.0-X)^M) / ( k*(Rc*Rc*(Ra-X)*(Ra-X)*(1.0-X)^N) )
      t = t + dX*(ri+rio)/2
      rio = ri
      X = X + dX
    endwhile
    volume = feed.F*t*60				# remember to convert to seconds
    diameter = (volume*4/(Pi*htod))^(1/3)
    height = diameter*htod

Finally, given the extents of reaction, we can solve the energy balance equations to tell us the amount of heating or cooling required. The numbers calculated are used to define a heat transfer request (HTR) which was defined above:

    # now calculate the heat balance; recall that Q for a heat
    # transfer request will have a positive value for cooling and a
    # negative value if heating is required so we need to negate the value
    # we get from the heats of reaction directly.
    heat.Q = - extent*{53.7, 91.1, -189.4}		# values are heats of reaction [kJ/kmol]
    heat.T1 = feed.T
    heat.T2 = feed.T
    heat.P = feed.P
    heat.U = 1
  end # of design equations

Evaluation equations

Once the design has been generated, Jacaranda will evaluate the model equations which will typically be used to give values to the variables used to evaluate the criteria for comparing alternative process designs and for optimisation. These variables will be problem dependent. For the kiln model, the only variable we need is the capital cost of the unit:

  model
    capcost = 1917 * diameter^1.066
  end
end # of Unit kiln definition

References

D. M. Laing and E. S. Fraga (1997)
A case study on synthesis in preliminary design, Computers & Chemical Engineering 21(Suppl.):S53-S58.

1. In this blog, class names are typically abbreviated by removing the leading uk.ac.ucl.che.esf.fish. prefix. Unless otherwise noted, all classes should have this prefix to be fully qualified.

free website hit counter