MixerExampleOnCalculate Method

Calculation method for the MixerExample unit operation.

Definition

Namespace: CapeOpen
Assembly: CapeOpen (in CapeOpen.dll) Version: 1.0.0.0 (1.0.0.0)
public override void OnCalculate()

Remarks

A mixer unit operation combined the material flows from two inlet ports into the flow of a single outlet port. In order to do this calculation, the mixer unit obtains flow information from each inlet port, the adds the flows to obtain the flow of the outlet port. In the case of the mixer below, it is assumed that the components are the same in each material object and that the components are listed in the same order. After the combined flow is calculated at the values set to the outlet port, along with the enthalpy of the stream calculated from an energy balance and the pressure determined from the inlet pressures, the outlet stream can be flahsed to determine equilibrium conditions. The last task is releasing any duplicate material objects obtained.

Example

An example of how to calculate a unit operation. This method obtains material objects from each of ports using the PortCollection class. The ICapeThermoMaterialObject interface is used to obtain the names using the CompIds() method, flows of each of the components present in the material object, overall pressure and overall enthalpy are obtained using the GetProp(String, String, Object, String, String) method. The overall enthalpy of the stram is calculated using CalcProp(Object, Object, String) method. The unit then combines the flows, calculates the output stream enthalpy, and determines output pressure from the lower of the two streams' pressure and pressure drop parameter. Lastly, the results of the calculations are applied to the output material object using the SetProp(String, String, Object, String, String, Object) method. The last method of the calculate method is to call the material's CalcEquilibrium(String, Object) method.

In this case, the inlet materials need to be released. This is accomplished using the ReleaseComObject(Object) method. Using this method to release the outlet material object would result in an null object reference error.

The method also documents use of the throwException(Exception) method to provide CAPE-OPEN compliant error handling.

C#
public override void OnCalculate()
{
    // Log a message using the simulation context (pop-up message commented out.
    if (this.SimulationContext != null)
    {
        ((ICapeDiagnostic)this.SimulationContext).LogMessage("Starting Mixer Calculation");
        ((CapeOpen.ICapeDiagnostic)this.SimulationContext).PopUpMessage("Starting Mixer Calculation");
    }

    // Get the material Object from Port 0.
    ICapeThermoMaterialObject in1 = null;
    try
    {
        in1 = (ICapeThermoMaterialObject)this.Ports[0].connectedObject;
    }
    catch (System.Exception p_Ex)
    {
        CapeOpen.CapeInvalidOperationException ex = new CapeOpen.CapeInvalidOperationException("Material object does not support CAPE-OPEN Thermodynamics 1.0.", p_Ex);
        this.throwException(ex);
    }

    // Duplicate the port, its an input port, always use a duplicate.
    try
    {
        in1 = (ICapeThermoMaterialObject)in1.Duplicate();
    }
    catch (System.Exception p_Ex)
    {
        CapeOpen.CapeInvalidOperationException ex = new CapeOpen.CapeInvalidOperationException("Object connected to Inlet Port 1 does not support CAPE-OPEN Thermodynamics 1.0.", p_Ex);
        this.throwException(ex);
    }

    // Arrays for the GetProps and SetProps call for enthaply.
    String[] phases = { "Overall" };
    String[] props = { "enthalpy" };

    // Declare variables for calculations.
    String[] in1Comps = null;
    double[] in1Flow = null;
    double[] in1Enthalpy = null;
    double[] pressure = null;
    double totalFlow1 = 0;

    // Exception catching code...
    try
    {
        // Get Strings, must cast to string array data type.
        in1Comps = (String[])in1.ComponentIds;

        // Get flow. Arguments are the property; phase, in this case, Overall; compound identifications
        // in this case, the null returns the property for all components; calculation type, in this case,  
        // null, no calculation type; and lastly, the basis, moles. Result is cast to a double array, and will contain one value.
        in1Flow = (double[])in1.GetProp("flow", "Overall", null, null, "mole");

        // Get pressure. Arguments are the property; phase, in this case, Overall; compound identifications
        // in this case, the null returns the property for all components; calculation type, in this case, the 
        // mixture; and lastly, the basis, moles. Result is cast to a double array, and will contain one value.
        pressure = (double[])in1.GetProp("Pressure", "Overall", null, "Mixture", null);

        // The following code adds the individual flows to get the total flow for the stream.
        for (int i = 0; i < in1Flow.Length; i++)
        {
            totalFlow1 = totalFlow1 + in1Flow[i];
        }

        // Calculates the mixture enthalpy of the stream.
        in1.CalcProp(props, phases, "Mixture");

        // Get the enthalpy of the stream. Arguments are the property, enthalpy; the phase, overall;
        // a null pointer, required as the overall enthalpy is desired; the calculation type is
        // mixture; and the basis is moles.
        in1Enthalpy = (double[])in1.GetProp("enthalpy", "Overall", null, "Mixture", "mole");
    }
    catch (System.Exception p_Ex)
    {
        // Exception handling, wraps a COM exception, shows the message, and re-throws the excecption.

        if (p_Ex is System.Runtime.InteropServices.COMException)
        {
            System.Runtime.InteropServices.COMException comException = (System.Runtime.InteropServices.COMException)p_Ex;
            p_Ex = CapeOpen.COMExceptionHandler.ExceptionForHRESULT(in1, p_Ex);
        }
        this.throwException(p_Ex);
    }

    // Release the material object if it is a COM object.
    if (in1.GetType().IsCOMObject) System.Runtime.InteropServices.Marshal.ReleaseComObject(in1);

    // Get the second inlet port material object. In this case, the Material Object wrapper is used.
    MaterialObjectWrapper in2 = new MaterialObjectWrapper(this.Ports[1].connectedObject);

    // Duplicate the material object.
    in2 = in2.Duplicate();

    // Declare variables.
    String[] in2Comps = null;
    double[] in2Flow = null;
    double[] in2Enthalpy = null;
    double totalFlow2 = 0;

    // Try block.
    try
    {
        // Get the component identifications.
        in2Comps = in2.ComponentIds;

        // Get flow. Arguments are the property; phase, in this case, Overall; compound identifications
        // in this case, the null returns the property for all components; calculation type, in this case,  
        // null, no calculation type; and lastly, the basis, moles. Result is cast to a double array, and will contain one value.
        in2Flow = in2.GetProp("flow", "Overall", null, null, "mole");

        // Get pressure. Arguments are the property; phase, in this case, Overall; compound identifications
        // in this case, the null returns the property for all components; calculation type, in this case, the 
        // mixture; and lastly, the basis, moles. Result is cast to a double array, and will contain one value.
        double[] press = in2.GetProp("Pressure", "Overall", null, "Mixture", null);
        if (press[0] < pressure[0]) pressure[0] = press[0];

        // The following code adds the individual flows to get the total flow for the stream.
        for (int i = 0; i < in2Flow.Length; i++)
        {
            totalFlow2 = totalFlow2 + in2Flow[i];
        }

        // Calculates the mixture enthalpy of the stream.
        in2.CalcProp(props, phases, "Mixture");

        // Get the enthalpy of the stream. Arguments are the property, enthalpy; the phase, overall;
        // a null pointer, required as the overall enthalpy is desired; the calculation type is
        // mixture; and the basis is moles.
        in2Enthalpy = in2.GetProp("enthalpy", "Overall", null, "Mixture", "mole");
    }
    catch (System.Exception p_Ex)
    {
        System.Runtime.InteropServices.COMException comException = (System.Runtime.InteropServices.COMException)p_Ex;
        if (comException != null)
        {
            p_Ex = CapeOpen.COMExceptionHandler.ExceptionForHRESULT(in2, p_Ex);
        }
        this.throwException(p_Ex);
    }

    // Release the material object if it is a COM object.
    in2.Dispose();

    // Get the outlet material object.
    MaterialObjectWrapper outPort = new MaterialObjectWrapper(this.Ports[2].connectedObject);

    // An empty, one-member array to set values in the outlet material stream.
    double[] values = new double[1];

    // Use energy balanace to calculate the outlet enthalpy.
    values[0] = (in1Enthalpy[0] * totalFlow1 + in2Enthalpy[0] * totalFlow2) / (totalFlow1 + totalFlow2);
    try
    {
        // Set the outlet enthalpy, for the overall phase, with a mixture calculation type
        // to the value calculated above.
        outPort.SetProp("enthalpy", "Overall", null, "Mixture", "mole", values);

        // Set the outlet pressure to the lower of the to inlet pressures less the value of the 
        // pressure drop parameter.
        pressure[0] = pressure[0] - (double)(this.Parameters[0].value);

        // Set the outlet pressure.
        outPort.SetProp("Pressure", "Overall", null, null, null, pressure);

        // Resize the value array for the number of components.
        values = new double[in1Comps.Length];

        // Calculate the individual flow for each component.
        for (int i = 0; i < in1Comps.Length; i++)
        {
            values[i] = in1Flow[i] + in2Flow[i];
        }
        // Set the outlet flow by component. Note, this is for overall phase and mole flows.
        // The component Identifications are used as a check.
        outPort.SetProp("flow", "Overall", in1Comps, null, "mole", values);

        // Calculate equilibrium using a "pressure-enthalpy" flash type.
        outPort.CalcEquilibrium("PH", null);
    }
    catch (System.Exception p_Ex)
    {
        System.Runtime.InteropServices.COMException comException = (System.Runtime.InteropServices.COMException)p_Ex;
        if (comException != null)
        {
            p_Ex = CapeOpen.COMExceptionHandler.ExceptionForHRESULT(outPort, p_Ex);
        }
        this.throwException(p_Ex);
    }

    // Log the end of the calculation.
    if (this.SimulationContext != null)
    {
        ((CapeOpen.ICapeDiagnostic)this.SimulationContext).LogMessage("Ending Mixer Calculation");
        ((CapeOpen.ICapeDiagnostic)this.SimulationContext).PopUpMessage("Ending Mixer Calculation");
    }
}

See Also