/// <summary> /// Calculation method for the CMixerExample110 unit operation. /// </summary> /// <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. /// </remarks> /// <example> /// <para>An example of how to calculate a unit operation. This method obtains material objects /// from each of ports using the <seealso cref = "CapeOpen.CPortCollection"/> class. The <seealso cref = "CapeOpen.ICapeThermoMaterial"/> /// interface is used to obtain the names using the CompIds() method, flows of each of the /// components present in the material object and overall pressure obtained using the /// <seealso cref = "CapeOpen.ICapeThermoMaterial.GetOverallProp"/> method. The enthaply of /// each phase in the inlet materials is calculated using <seealso cref = "CapeOpen.ICapeThermoPropertyRoutine.CalcSinglePhaseProp"/> /// method. The inlet enthalpy was multiplied by the phase flow (phase fraction * overall flow) /// which was summed to determine the outlet stream enthalpy. /// The 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 <seealso cref = "CapeOpen.ICapeThermoMaterial.SetOverallProp"/> /// method. The last method of the calculate method is to call the material's /// <seealso cref = "CapeOpen.ICapeThermoEquilibriumRoutine.CalcEquilibrium"/> method.</para> /// <para> /// A calculation report is generated by this method that is made avalable through the /// <seealso cref = "CapeOpen.ICapeUnitReport.ProduceReport"/> method. /// </para> /// <para> /// In this case, the inlet materials need to be released. This is accomplished using the /// <seealso cref = "System.Runtime.InteropServices.Marshal.ReleaseComObject"/> method. /// Using this method to release the outlet material object would result in an null object reference error. /// </para> /// <para> /// The method also documents use of the <seealso cref = "CapeOpen.CCapeObject.throwException"/> method to provide /// CAPE-OPEN compliant error handling. /// </para> /// <code> /// public override void Calculate() /// { /// this.calcReport = String.Empty; /// // Log a message using the simulation context (pop-up message commented out. /// if (this.SimulationContext != null) /// (this.SimulationContext as CapeOpen.ICapeDiagnostic).LogMessage("Starting Mixer Calculation"); /// this.calcReport = String.Concat(this.calcReport, "Starting Mixer Calculation", System.Environment.NewLine); /// // Get the material Object from Port 0. /// CapeOpen.ICapeThermoMaterial in1 = null; /// CapeOpen.ICapeThermoMaterial in2 = null; /// CapeOpen.ICapeThermoMaterial output = null; /// CapeOpen.ICapeThermoMaterial temp = null; /// Object comps = null; /// Object forms = null; /// Object names = null; /// Object bTemp = null; /// Object molWts = null; /// Object casNos = null; /// string[] compIds1 = null; /// string[] compIds2 = null; /// string[] compIds3 = null; /// try /// { /// temp = (this.Ports[0].connectedObject as CapeOpen.ICapeThermoMaterial); /// in1 = temp.CreateMaterial() as CapeOpen.ICapeThermoMaterial; /// //in1.CopyFromMaterial(temp); /// if (temp.GetType().IsCOMObject) System.Runtime.InteropServices.Marshal.ReleaseComObject(temp); /// (in1 as CapeOpen.ICapeThermoCompounds).GetCompoundList(ref comps, ref forms, ref names, ref bTemp, ref molWts, ref casNos); /// compIds1 = comps as string[]; /// temp = this.Ports[1].connectedObject as CapeOpen.ICapeThermoMaterial; /// in2 = temp.CreateMaterial() as CapeOpen.ICapeThermoMaterial; /// //in2.CopyFromMaterial(temp); /// if (temp.GetType().IsCOMObject) System.Runtime.InteropServices.Marshal.ReleaseComObject(temp); /// (in2 as CapeOpen.ICapeThermoCompounds).GetCompoundList(ref comps, ref forms, ref names, ref bTemp, ref molWts, ref casNos); /// compIds2 = comps as string[]; /// output = this.Ports[2].connectedObject as CapeOpen.ICapeThermoMaterial; /// (output as CapeOpen.ICapeThermoCompounds).GetCompoundList(ref comps, ref forms, ref names, ref bTemp, ref molWts, ref casNos); /// compIds3 = comps as string[]; /// } /// catch (System.Exception p_Ex) /// { /// CapeOpen.CapeInvalidOperationException ex = new CapeOpen.CapeInvalidOperationException("Material object does not support CAPE-OPEN Thermodynamics 1.1.", p_Ex); /// this.calcReport = String.Concat(this.calcReport, "Material object does not support CAPE-OPEN Thermodynamics 1.1.", System.Environment.NewLine); /// this.throwException(ex as CapeOpen.ECapeUser); /// } /// int l1 = 0; /// int l2 = 0; /// int l3 = 0; /// l1 = compIds1.Length; /// l2 = compIds2.Length; /// l3 = compIds3.Length; /// if (l1 != l2) /// { /// this.calcReport = string.Concat(this.calcReport, "Compounds in imlet materials do not match.", System.Environment.NewLine); /// throw new CapeOpen.CapeInvalidOperationException("Compounds in imlet materials do not match."); /// } /// if (l1 != l3) /// { /// this.calcReport = string.Concat(this.calcReport, "Compounds in imlet materials does not match outlet material.", System.Environment.NewLine); /// throw new CapeOpen.CapeInvalidOperationException("Compounds in imlet materials does not match outlet material."); /// } /// for (int i = 0; i < l3; i++) /// { /// if ((String.Compare(compIds1[i], compIds2[i])) != 0) /// { /// this.calcReport = string.Concat(this.calcReport, "Compounds in imlet materials do not match.", System.Environment.NewLine); /// throw new CapeOpen.CapeInvalidOperationException("Compounds in imlet materials do not match."); /// } /// /// if (String.Compare(compIds1[i], compIds3[i]) != 0) /// { /// this.calcReport = string.Concat(this.calcReport, "Compounds in imlet materials does not match outlet material.", System.Environment.NewLine); /// throw new CapeOpen.CapeInvalidOperationException("Compounds in imlet materials does not mAtch outlet material."); /// } /// } /// /// double[] press1 = null; /// double[] press2 = null; /// double[] flow1 = null; /// double[] flow2 = null; /// double[] flow3 = new double[l3]; /// string[] props = { "enthalpy" }; /// string[] overall = { "Overall" }; /// double[] enthalpy = { 0 }; /// Object obj = null; /// Object obj1 = null; /// Object obj2 = null; /// Object obj3 = null; /// string[] phases = null; /// CapeOpen.ICapeThermoEquilibriumRoutine eqRoutine; /// try /// { /// in1.GetOverallProp("flow", "mole", ref obj); /// flow1 = obj as double[]; /// double totalFlow = 0; /// foreach (double flow in flow1) /// { /// totalFlow = totalFlow + flow; /// } /// in1.GetOverallProp("pressure", "", ref obj); /// press1 = obj as double[]; /// CapeOpen.ICapeThermoPropertyRoutine p_Calc = in1 as CapeOpen.ICapeThermoPropertyRoutine; /// CapeOpen.ICapeThermoPhases phaseList = in1 as CapeOpen.ICapeThermoPhases; /// phaseList.GetPhaseList(ref obj1, ref obj2, ref obj3); /// phases = obj1 as string[]; /// foreach (String phase in phases) /// { /// p_Calc.CalcSinglePhaseProp(props, phase); /// in1.GetSinglePhaseProp("enthalpy", phase, "mole", ref obj); /// double[] enth = obj as double[]; /// in1.GetSinglePhaseProp("phaseFraction", phase, "mole", ref obj); /// double[] fract = obj as double[]; /// enthalpy[0] = enthalpy[0] + totalFlow * fract[0] * enth[0]; /// } /// } /// catch (System.Exception p_Ex) /// { /// CapeOpen.ECapeUser user = in1 as CapeOpen.ECapeUser; /// this.calcReport = string.Concat(this.calcReport, user.description, System.Environment.NewLine); /// this.throwException(user); /// } /// try /// { /// in2.GetOverallProp("flow", "mole", ref obj); /// flow2 = obj as double[]; /// double totalFlow = 0; /// foreach (double flow in flow2) /// { /// totalFlow = totalFlow + flow; /// } /// in2.GetOverallProp("pressure", "", ref obj); /// press2 = obj as double[]; /// CapeOpen.ICapeThermoPropertyRoutine p_Calc = in2 as CapeOpen.ICapeThermoPropertyRoutine; /// CapeOpen.ICapeThermoPhases phaseList = in2 as CapeOpen.ICapeThermoPhases; /// phaseList.GetPhaseList(ref obj1, ref obj2, ref obj3); /// foreach (String phase in phases) /// { /// p_Calc.CalcSinglePhaseProp(props, phase); /// in2.GetSinglePhaseProp("enthalpy", phase, "mole", ref obj); /// double[] enth = obj as double[]; /// in2.GetSinglePhaseProp("phaseFraction", phase, "mole", ref obj); /// double[] fract = obj as double[]; /// enthalpy[0] = enthalpy[0] + totalFlow * fract[0] * enth[0]; /// } /// } /// catch (System.Exception p_Ex) /// { /// CapeOpen.ECapeUser user = in2 as CapeOpen.ECapeUser; /// this.calcReport = string.Concat(this.calcReport, user.description, System.Environment.NewLine); /// this.throwException(user); /// } /// for (int i = 0; i < l3; i++) /// { /// flow3[i] = flow1[i] + flow2[i]; /// } /// try /// { /// output.SetOverallProp("flow", "mole", flow3); /// double[] press = new double[1]; /// press[0] = press1[0]; /// if (press1[0] > press2[0]) press[0] = press2[0]; /// double pressdrop = (this.Parameters[0] as CapeOpen.CRealParameter).SIValue; /// press[0] = press[0] - pressdrop; /// output.SetOverallProp("pressure", "", press); /// output.GetOverallProp("totalFlow", "mole", ref obj); /// double[] totalFlow = obj as double[]; /// enthalpy[0] = enthalpy[0] / totalFlow[0]; /// output.SetOverallProp("enthalpy", "mole", enthalpy); /// this.calcReport = string.Concat(this.calcReport, "The outlet pressure is: ", press[0].ToString(), "Pa", System.Environment.NewLine); /// int[] status = { 0, 0 }; /// output.SetPresentPhases(phases, status); /// this.calcReport = string.Concat(this.calcReport, "The outlet ethalpy is: ", enthalpy[0].ToString(), "J/Mole", System.Environment.NewLine); /// eqRoutine = output as CapeOpen.ICapeThermoEquilibriumRoutine; /// string[] spec1 = { "pressure", String.Empty, "Overall" }; /// string[] spec2 = { "enthalpy", String.Empty, "Overall" }; /// eqRoutine.CalcEquilibrium(spec1, spec2, "unspecified"); /// this.calcReport = string.Concat(this.calcReport, "Calculated pressure-enthalpy flash", System.Environment.NewLine); /// } /// catch (System.Exception p_Ex) /// { /// CapeOpen.ECapeUser user = output as CapeOpen.ECapeUser; /// this.calcReport = string.Concat(this.calcReport, user.description, System.Environment.NewLine); /// this.throwException(user); /// } /// /// if (in1.GetType().IsCOMObject) System.Runtime.InteropServices.Marshal.ReleaseComObject(in1); /// if (in2.GetType().IsCOMObject) System.Runtime.InteropServices.Marshal.ReleaseComObject(in2); /// // Log the end of the calculation. /// if (this.SimulationContext != null) /// (this.SimulationContext as CapeOpen.ICapeDiagnostic).LogMessage("Ending Mixer Calculation"); /// this.calcReport = string.Concat(this.calcReport, "Ending Mixer Calculation"); /// //(this.SimulationContext as CapeOpen.ICapeDiagnostic).PopUpMessage("Ending Mixer Calculation"); /// } /// </code> /// </example> /// <seealso cref="CapeOpen.ICapeThermoMaterial"/> /// <seealso cref="CapeOpen.ICapeThermoCompounds"/> /// <seealso cref="CapeOpen.ICapeThermoPhases"/> /// <seealso cref="CapeOpen.ICapeThermoPropertyRoutine"/> /// <seealso cref="CapeOpen.ICapeThermoEquilibriumRoutine"/> /// <seealso cref="CapeOpen.COMExceptionHandler"/> public override void Calculate() { this.calcReport = String.Empty; // Log a message using the simulation context (pop-up message commented out. if (this.SimulationContext != null) { (this.SimulationContext as CapeOpen.ICapeDiagnostic).LogMessage("Starting Mixer Calculation"); } this.calcReport = String.Concat(this.calcReport, "Starting Mixer Calculation", System.Environment.NewLine); // Get the material Object from Port 0. CapeOpen.ICapeThermoMaterial in1 = null; CapeOpen.ICapeThermoMaterial in2 = null; CapeOpen.ICapeThermoMaterial output = null; object temp = null; Object comps = null; Object forms = null; Object names = null; Object bTemp = null; Object molWts = null; Object casNos = null; string[] compIds1 = null; string[] compIds2 = null; string[] compIds3 = null; try { temp = this.Ports[0].connectedObject; in1 = (temp as CapeOpen.ICapeThermoMaterial).CreateMaterial() as CapeOpen.ICapeThermoMaterial; in1.CopyFromMaterial(ref temp); if (temp.GetType().IsCOMObject) { System.Runtime.InteropServices.Marshal.ReleaseComObject(temp); } (in1 as CapeOpen.ICapeThermoCompounds).GetCompoundList(ref comps, ref forms, ref names, ref bTemp, ref molWts, ref casNos); compIds1 = comps as string[]; temp = this.Ports[1].connectedObject as CapeOpen.ICapeThermoMaterial; in2 = (temp as CapeOpen.ICapeThermoMaterial).CreateMaterial() as CapeOpen.ICapeThermoMaterial; in2.CopyFromMaterial(ref temp); if (temp.GetType().IsCOMObject) { System.Runtime.InteropServices.Marshal.ReleaseComObject(temp); } (in2 as CapeOpen.ICapeThermoCompounds).GetCompoundList(ref comps, ref forms, ref names, ref bTemp, ref molWts, ref casNos); compIds2 = comps as string[]; output = this.Ports[2].connectedObject as CapeOpen.ICapeThermoMaterial; (output as CapeOpen.ICapeThermoCompounds).GetCompoundList(ref comps, ref forms, ref names, ref bTemp, ref molWts, ref casNos); compIds3 = comps as string[]; } catch (System.Exception p_Ex) { CapeOpen.CapeInvalidOperationException ex = new CapeOpen.CapeInvalidOperationException("Material object does not support CAPE-OPEN Thermodynamics 1.1.", p_Ex); this.calcReport = String.Concat(this.calcReport, "Material object does not support CAPE-OPEN Thermodynamics 1.1.", System.Environment.NewLine); this.throwException(ex as CapeOpen.ECapeUser); } int l1 = 0; int l2 = 0; int l3 = 0; l1 = compIds1.Length; l2 = compIds2.Length; l3 = compIds3.Length; if (l1 != l2) { this.calcReport = string.Concat(this.calcReport, "Compounds in imlet materials do not match.", System.Environment.NewLine); throw new CapeOpen.CapeInvalidOperationException("Compounds in imlet materials do not match."); } if (l1 != l3) { this.calcReport = string.Concat(this.calcReport, "Compounds in imlet materials does not match outlet material.", System.Environment.NewLine); throw new CapeOpen.CapeInvalidOperationException("Compounds in imlet materials does not match outlet material."); } for (int i = 0; i < l3; i++) { if ((String.Compare(compIds1[i], compIds2[i])) != 0) { this.calcReport = string.Concat(this.calcReport, "Compounds in imlet materials do not match.", System.Environment.NewLine); throw new CapeOpen.CapeInvalidOperationException("Compounds in imlet materials do not match."); } if (String.Compare(compIds1[i], compIds3[i]) != 0) { this.calcReport = string.Concat(this.calcReport, "Compounds in imlet materials does not match outlet material.", System.Environment.NewLine); throw new CapeOpen.CapeInvalidOperationException("Compounds in imlet materials does not mAtch outlet material."); } } double[] press1 = null; double[] press2 = null; double[] flow1 = null; double[] flow2 = null; double[] flow3 = new double[l3]; string[] props = { "enthalpy" }; string[] overall = { "Overall" }; double[] enthalpy = { 0 }; Object obj = null; Object obj1 = null; Object obj2 = null; Object obj3 = null; string[] phases = null; CapeOpen.ICapeThermoEquilibriumRoutine eqRoutine; try { in1.GetOverallProp("flow", "mole", ref obj); flow1 = obj as double[]; double totalFlow = 0; foreach (double flow in flow1) { totalFlow = totalFlow + flow; } in1.GetOverallProp("pressure", "", ref obj); press1 = obj as double[]; CapeOpen.ICapeThermoPropertyRoutine p_Calc = in1 as CapeOpen.ICapeThermoPropertyRoutine; CapeOpen.ICapeThermoPhases phaseList = in1 as CapeOpen.ICapeThermoPhases; phaseList.GetPhaseList(ref obj1, ref obj2, ref obj3); phases = obj1 as string[]; foreach (String phase in phases) { p_Calc.CalcSinglePhaseProp(props, phase); in1.GetSinglePhaseProp("enthalpy", phase, "mole", ref obj); double[] enth = obj as double[]; in1.GetSinglePhaseProp("phaseFraction", phase, "mole", ref obj); double[] fract = obj as double[]; enthalpy[0] = enthalpy[0] + totalFlow * fract[0] * enth[0]; } } catch (System.Exception p_Ex) { CapeOpen.ECapeUser user = in1 as CapeOpen.ECapeUser; this.calcReport = string.Concat(this.calcReport, user.description, System.Environment.NewLine); this.throwException(user); } try { in2.GetOverallProp("flow", "mole", ref obj); flow2 = obj as double[]; double totalFlow = 0; foreach (double flow in flow2) { totalFlow = totalFlow + flow; } in2.GetOverallProp("pressure", "", ref obj); press2 = obj as double[]; CapeOpen.ICapeThermoPropertyRoutine p_Calc = in2 as CapeOpen.ICapeThermoPropertyRoutine; CapeOpen.ICapeThermoPhases phaseList = in2 as CapeOpen.ICapeThermoPhases; phaseList.GetPhaseList(ref obj1, ref obj2, ref obj3); foreach (String phase in phases) { p_Calc.CalcSinglePhaseProp(props, phase); in2.GetSinglePhaseProp("enthalpy", phase, "mole", ref obj); double[] enth = obj as double[]; in2.GetSinglePhaseProp("phaseFraction", phase, "mole", ref obj); double[] fract = obj as double[]; enthalpy[0] = enthalpy[0] + totalFlow * fract[0] * enth[0]; } } catch (System.Exception p_Ex) { CapeOpen.ECapeUser user = in2 as CapeOpen.ECapeUser; this.calcReport = string.Concat(this.calcReport, user.description, System.Environment.NewLine); this.throwException(user); } for (int i = 0; i < l3; i++) { flow3[i] = flow1[i] + flow2[i]; } try { output.SetOverallProp("flow", "mole", flow3); double[] press = new double[1]; press[0] = press1[0]; if (press1[0] > press2[0]) { press[0] = press2[0]; } double pressdrop = (this.Parameters[0] as CapeOpen.CRealParameter).SIValue; press[0] = press[0] - pressdrop; output.SetOverallProp("pressure", "", press); output.GetOverallProp("totalFlow", "mole", ref obj); double[] totalFlow = obj as double[]; enthalpy[0] = enthalpy[0] / totalFlow[0]; output.SetOverallProp("enthalpy", "mole", enthalpy); this.calcReport = string.Concat(this.calcReport, "The outlet pressure is: ", press[0].ToString(), "Pa", System.Environment.NewLine); int[] status = { 0, 0 }; output.SetPresentPhases(phases, status); this.calcReport = string.Concat(this.calcReport, "The outlet ethalpy is: ", enthalpy[0].ToString(), "J/Mole", System.Environment.NewLine); eqRoutine = output as CapeOpen.ICapeThermoEquilibriumRoutine; string[] spec1 = { "pressure", String.Empty, "Overall" }; string[] spec2 = { "enthalpy", String.Empty, "Overall" }; eqRoutine.CalcEquilibrium(spec1, spec2, "unspecified"); this.calcReport = string.Concat(this.calcReport, "Calculated pressure-enthalpy flash", System.Environment.NewLine); } catch (System.Exception p_Ex) { CapeOpen.ECapeUser user = output as CapeOpen.ECapeUser; this.calcReport = string.Concat(this.calcReport, user.description, System.Environment.NewLine); this.throwException(user); } if (in1.GetType().IsCOMObject) { System.Runtime.InteropServices.Marshal.ReleaseComObject(in1); } if (in2.GetType().IsCOMObject) { System.Runtime.InteropServices.Marshal.ReleaseComObject(in2); } // Log the end of the calculation. if (this.SimulationContext != null) { (this.SimulationContext as CapeOpen.ICapeDiagnostic).LogMessage("Ending Mixer Calculation"); } this.calcReport = string.Concat(this.calcReport, "Ending Mixer Calculation"); //(this.SimulationContext as CapeOpen.ICapeDiagnostic).PopUpMessage("Ending Mixer Calculation"); }
/// <summary> /// Calculation method for the MixerExample unit operation. /// </summary> /// <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. /// </remarks> /// <example> /// <para>An example of how to calculate a unit operation. This method obtains material objects /// from each of ports using the <see cref = "PortCollection"/> class. The <see cref = "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 <see cref = "ICapeThermoMaterialObject.GetProp"/> method. The overall enthalpy of the stram is /// calculated using <see cref = "ICapeThermoMaterialObject.CalcProp"/> 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 <see cref = "ICapeThermoMaterialObject.SetProp"/> /// method. The last method of the calculate method is to call the material's /// <see cref = "ICapeThermoMaterialObject.CalcEquilibrium"/> method.</para> /// <para> /// In this case, the inlet materials need to be released. This is accomplished using the /// <see cref = "System.Runtime.InteropServices.Marshal.ReleaseComObject"/> method. /// Using this method to release the outlet material object would result in an null object reference error. /// </para> /// <para> /// The method also documents use of the <see cref = "CapeObjectBase.throwException"/> method to provide /// CAPE-OPEN compliant error handling. /// </para> /// <code> /// protected override void Calculate() /// { /// // 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; /// ICapeThermoMaterialObject tempMO = null; /// try /// { /// tempMO = (ICapeThermoMaterialObject)this.Ports[0].connectedObject; /// } /// catch (System.Exception p_Ex) /// { /// this.OnUnitOperationEndCalculation("Error - Material object does not support CAPE-OPEN Thermodynamics 1.0."); /// 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)tempMO.Duplicate(); /// } /// catch (System.Exception p_Ex) /// { /// this.OnUnitOperationEndCalculation("Error - Object connected to Inlet Port 1 does not support CAPE-OPEN Thermodynamics 1.0."); /// 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); /// } /// IDisposable disp = in1 as IDisposable; /// if (disp != null) /// { /// disp.Dispose(); /// } /// /// /// // Get the material Object from Port 0. /// ICapeThermoMaterialObject in2 = null; /// tempMO = null; /// try /// { /// tempMO = (ICapeThermoMaterialObject)this.Ports[1].connectedObject; /// } /// catch (System.Exception p_Ex) /// { /// this.OnUnitOperationEndCalculation("Error - Material object does not support CAPE-OPEN Thermodynamics 1.0."); /// 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 /// { /// in2 = (ICapeThermoMaterialObject)tempMO.Duplicate(); /// } /// catch (System.Exception p_Ex) /// { /// this.OnUnitOperationEndCalculation("Error - Object connected to Inlet Port 1 does not support CAPE-OPEN Thermodynamics 1.0."); /// 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); /// } /// /// // 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. /// disp = in2 as IDisposable; /// if (disp != null) /// { /// disp.Dispose(); /// } /// /// /// // Get the outlet material object. /// ICapeThermoMaterialObject outPort = (ICapeThermoMaterialObject)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] - (((RealParameter)(this.Parameters[0])).SIValue); /// /// // 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); /// /// // Release the material object if it is a COM object. /// if (outPort.GetType().IsCOMObject) /// { /// System.Runtime.InteropServices.Marshal.FinalReleaseComObject(outPort); /// } /// } /// 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"); /// } /// /// </code> /// </example> /// <see cref="ICapeThermoMaterialObject"/> /// <see cref="COMExceptionHandler"/> protected override void Calculate() { // 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; ICapeThermoMaterialObject tempMO = null; try { tempMO = (ICapeThermoMaterialObject)this.Ports[0].connectedObject; } catch (System.Exception p_Ex) { this.OnUnitOperationEndCalculation("Error - Material object does not support CAPE-OPEN Thermodynamics 1.0."); 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)tempMO.Duplicate(); } catch (System.Exception p_Ex) { this.OnUnitOperationEndCalculation("Error - Object connected to Inlet Port 1 does not support CAPE-OPEN Thermodynamics 1.0."); 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); } IDisposable disp = in1 as IDisposable; if (disp != null) { disp.Dispose(); } // Get the material Object from Port 0. ICapeThermoMaterialObject in2 = null; tempMO = null; try { tempMO = (ICapeThermoMaterialObject)this.Ports[1].connectedObject; } catch (System.Exception p_Ex) { this.OnUnitOperationEndCalculation("Error - Material object does not support CAPE-OPEN Thermodynamics 1.0."); 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 { in2 = (ICapeThermoMaterialObject)tempMO.Duplicate(); } catch (System.Exception p_Ex) { this.OnUnitOperationEndCalculation("Error - Object connected to Inlet Port 1 does not support CAPE-OPEN Thermodynamics 1.0."); 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); } // 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. disp = in2 as IDisposable; if (disp != null) { disp.Dispose(); } // Get the outlet material object. ICapeThermoMaterialObject outPort = (ICapeThermoMaterialObject)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] - (((RealParameter)(this.Parameters[0])).SIValue); // 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); // Release the material object if it is a COM object. if (outPort.GetType().IsCOMObject) { System.Runtime.InteropServices.Marshal.FinalReleaseComObject(outPort); } } 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"); }
/// <summary> /// Calculation method for the CMixerExample110 unit operation. /// </summary> /// <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. /// </remarks> /// <example> /// <para>An example of how to calculate a unit operation. This method obtains material objects /// from each of ports using the <see cref = "PortCollection"/> class. The <see cref = "ICapeThermoMaterial"/> /// interface is used to obtain the names using the CompIds() method, flows of each of the /// components present in the material object and overall pressure obtained using the /// <see cref = "ICapeThermoMaterial.GetOverallProp"/> method. The enthaply of /// each phase in the inlet materials is calculated using <see cref = "ICapeThermoPropertyRoutine.CalcSinglePhaseProp"/> /// method. The inlet enthalpy was multiplied by the phase flow (phase fraction * overall flow) /// which was summed to determine the outlet stream enthalpy. /// The 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 <see cref = "ICapeThermoMaterial.SetOverallProp"/> /// method. The last method of the calculate method is to call the material's /// <see cref = "ICapeThermoEquilibriumRoutine.CalcEquilibrium"/> method.</para> /// <para> /// A calculation report is generated by this method that is made avalable through the /// <see cref = "MixerExample110.ProduceReport"/> method. /// </para> /// <para> /// In this case, the inlet materials need to be released. This is accomplished using the /// <see cref = "System.Runtime.InteropServices.Marshal.ReleaseComObject"/> method. /// Using this method to release the outlet material object would result in an null object reference error. /// </para> /// <para> /// The method also documents use of the <see cref = "CapeObjectBase.throwException"/> method to provide /// CAPE-OPEN compliant error handling. /// </para> /// <code> ///protected override void Calculate() ///{ /// this.calcReport = String.Empty; /// // Log a message using the simulation context (pop-up message commented out. /// if (this.SimulationContext is CapeOpen.ICapeDiagnostic) /// ((CapeOpen.ICapeDiagnostic)this.SimulationContext).LogMessage("Starting Mixer Calculation"); /// this.calcReport = String.Concat(this.calcReport, "Starting Mixer Calculation", System.Environment.NewLine); /// // Get the material Object from Port 0. /// ICapeThermoMaterial in1 = null; /// ICapeThermoMaterial in2 = null; /// ICapeThermoMaterial outlet = null; /// ICapeThermoMaterial temp = null; /// String[] compIds1 = null; /// String[] compIds2 = null; /// String[] compIds3 = null; /// String[] forms = null; /// String[] names = null; /// double[] bTemps = null; /// double[] molWts = null; /// String[] casNos = null; /// try /// { /// temp = (ICapeThermoMaterial)this.Ports[0].connectedObject; /// in1 = (ICapeThermoMaterial)temp.CreateMaterial(); /// in1.CopyFromMaterial(temp); /// if (temp.GetType().IsCOMObject) System.Runtime.InteropServices.Marshal.ReleaseComObject(temp); /// ((CapeOpen.ICapeThermoCompounds)in1).GetCompoundList(ref compIds1, ref forms, ref names, ref bTemps, ref molWts, ref casNos); /// temp = (ICapeThermoMaterial)this.Ports[1].connectedObject; /// in2 = (ICapeThermoMaterial)temp.CreateMaterial(); /// in2.CopyFromMaterial(temp); /// if (temp.GetType().IsCOMObject) System.Runtime.InteropServices.Marshal.FinalReleaseComObject(temp); /// ((CapeOpen.ICapeThermoCompounds)in2).GetCompoundList(ref compIds2, ref forms, ref names, ref bTemps, ref molWts, ref casNos); /// outlet = (ICapeThermoMaterial)this.Ports[2].connectedObject; /// ((CapeOpen.ICapeThermoCompounds)outlet).GetCompoundList(ref compIds3, ref forms, ref names, ref bTemps, ref molWts, ref casNos); /// } /// catch (System.Exception p_Ex) /// { /// CapeOpen.CapeInvalidOperationException ex = new CapeOpen.CapeInvalidOperationException("Material object does not support CAPE-OPEN Thermodynamics 1.1.", p_Ex); /// this.calcReport = String.Concat(this.calcReport, "Material object does not support CAPE-OPEN Thermodynamics 1.1.", System.Environment.NewLine); /// this.throwException(ex); /// } /// int l1 = compIds1.Length; /// int l2 = compIds2.Length; /// int l3 = compIds3.Length; /// if (l1 != l2) /// { /// this.calcReport = String.Concat(this.calcReport, "Compounds in imlet materials do not match.", System.Environment.NewLine); /// throw new CapeOpen.CapeInvalidOperationException("Compounds in imlet materials do not match."); /// } /// if (l1 != l3) /// { /// this.calcReport = String.Concat(this.calcReport, "Compounds in imlet materials does not match outlet material.", System.Environment.NewLine); /// throw new CapeOpen.CapeInvalidOperationException("Compounds in imlet materials does not match outlet material."); /// } /// for (int i = 0; i < l3; i++) /// { /// if ((String.Compare(compIds1[i], compIds2[i])) != 0) /// { /// this.calcReport = String.Concat(this.calcReport, "Compounds in imlet materials do not match.", System.Environment.NewLine); /// throw new CapeOpen.CapeInvalidOperationException("Compounds in imlet materials do not match."); /// } /// /// if (String.Compare(compIds1[i], compIds3[i]) != 0) /// { /// this.calcReport = String.Concat(this.calcReport, "Compounds in imlet materials does not match outlet material.", System.Environment.NewLine); /// throw new CapeOpen.CapeInvalidOperationException("Compounds in imlet materials does not mAtch outlet material."); /// } /// } /// /// double[] flow1 = null; /// double[] flow2 = null; /// double[] press1 = null; /// double[] press2 = null; /// double[] flow3 = new double[l3]; /// String[] props = { "enthalpy" }; /// String[] overall = { "Overall" }; /// double[] enthalpy = { 0 }; /// String[] phases = null; /// CapeOpen.ICapeThermoEquilibriumRoutine eqRoutine; /// string[] strArr1 = null; /// string[] strArr2 = null; /// try /// { /// /// in1.GetOverallProp("flow", "mole", ref flow1); /// double totalFlow = 0; /// foreach (double flow in flow1) /// { /// totalFlow = totalFlow + flow; /// } /// in1.GetOverallProp("pressure", "", ref press1); /// CapeOpen.ICapeThermoPropertyRoutine p_Calc = (CapeOpen.ICapeThermoPropertyRoutine)in1; /// CapeOpen.ICapeThermoPhases phaseList = (CapeOpen.ICapeThermoPhases)in1; /// phaseList.GetPhaseList(ref phases, ref strArr1, ref strArr2); /// foreach (String phase in phases) /// { /// p_Calc.CalcSinglePhaseProp(props, phase); /// double[] enth = null; /// in1.GetSinglePhaseProp("enthalpy", phase, "mole", ref enth); /// double[] fract = null; /// in1.GetSinglePhaseProp("phaseFraction", phase, "mole", ref fract); /// enthalpy[0] = enthalpy[0] + totalFlow * fract[0] * enth[0]; /// } /// IDisposable disp = in1 as IDisposable; /// if (disp != null) /// { /// disp.Dispose(); /// } /// } /// catch (System.Exception p_Ex) /// { /// CapeOpen.ECapeUser user = (CapeOpen.ECapeUser)in1; /// this.calcReport = String.Concat(this.calcReport, user.description, System.Environment.NewLine); /// this.throwException(p_Ex); /// } /// try /// { /// in2.GetOverallProp("flow", "mole", ref flow2); /// double totalFlow = 0; /// foreach (double flow in flow2) /// { /// totalFlow = totalFlow + flow; /// } /// in2.GetOverallProp("pressure", "", ref press2); /// CapeOpen.ICapeThermoPropertyRoutine p_Calc = (CapeOpen.ICapeThermoPropertyRoutine)in2; /// CapeOpen.ICapeThermoPhases phaseList = (CapeOpen.ICapeThermoPhases)in2; /// phaseList.GetPhaseList(ref phases, ref strArr1, ref strArr2); /// foreach (String phase in phases) /// { /// p_Calc.CalcSinglePhaseProp(props, phase); /// double[] enth = null; /// in2.GetSinglePhaseProp("enthalpy", phase, "mole", ref enth); /// double[] fract = null; /// in2.GetSinglePhaseProp("phaseFraction", phase, "mole", ref fract); /// enthalpy[0] = enthalpy[0] + totalFlow * fract[0] * enth[0]; /// } /// IDisposable disp = in2 as IDisposable; /// if (disp != null) /// { /// disp.Dispose(); /// } /// } /// catch (System.Exception p_Ex) /// { /// CapeOpen.ECapeUser user = (CapeOpen.ECapeUser)in2; /// this.calcReport = String.Concat(this.calcReport, user.description, System.Environment.NewLine); /// this.throwException(p_Ex); /// } /// for (int i = 0; i < l3; i++) /// { /// flow3[i] = flow1[i] + flow2[i]; /// } /// try /// { /// outlet.SetOverallProp("flow", "mole", flow3); /// double[] press = new double[1]; /// press[0] = press1[0]; /// if (press1[0] > press2[0]) press[0] = press2[0]; /// double pressdrop = ((CapeOpen.RealParameter)this.Parameters[0]).SIValue; /// press[0] = press[0] - pressdrop; /// outlet.SetOverallProp("pressure", "", press); /// double[] totalFlow = null; /// outlet.GetOverallProp("totalFlow", "mole", ref totalFlow); /// enthalpy[0] = enthalpy[0] / totalFlow[0]; /// outlet.SetOverallProp("enthalpy", "mole", enthalpy); /// this.calcReport = String.Concat(this.calcReport, "The outlet pressure is: ", press[0].ToString(), "Pa", System.Environment.NewLine); /// CapePhaseStatus[] status = { CapePhaseStatus.CAPE_ATEQUILIBRIUM, CapePhaseStatus.CAPE_ATEQUILIBRIUM }; /// outlet.SetPresentPhases(phases, status); /// this.calcReport = String.Concat(this.calcReport, "The outlet ethalpy is: ", enthalpy[0].ToString(), "J/Mole", System.Environment.NewLine); /// eqRoutine = (CapeOpen.ICapeThermoEquilibriumRoutine)outlet; /// String[] spec1 = { "pressure", String.Empty, "Overall" }; /// String[] spec2 = { "enthalpy", String.Empty, "Overall" }; /// eqRoutine.CalcEquilibrium(spec1, spec2, "unspecified"); /// this.calcReport = String.Concat(this.calcReport, "Calculated pressure-enthalpy flash", System.Environment.NewLine); /// } /// catch (System.Exception p_Ex) /// { /// CapeOpen.ECapeUser user = (CapeOpen.ECapeUser)outlet; /// this.calcReport = String.Concat(this.calcReport, user.description, System.Environment.NewLine); /// this.throwException(p_Ex); /// } /// // Log the end of the calculation. /// this.calcReport = String.Concat(this.calcReport, "Ending Mixer Calculation"); /// if (this.SimulationContext is CapeOpen.ICapeDiagnostic) /// ((CapeOpen.ICapeDiagnostic)this.SimulationContext).LogMessage("Ending Mixer Calculation"); ///} /// </code> /// </example> /// <see cref="ICapeThermoMaterial"/> /// <see cref="ICapeThermoCompounds"/> /// <see cref="ICapeThermoPhases"/> /// <see cref="ICapeThermoPropertyRoutine"/> /// <see cref="ICapeThermoEquilibriumRoutine"/> /// <see cref="COMExceptionHandler"/> protected override void Calculate() { this.calcReport = String.Empty; // Log a message using the simulation context (pop-up message commented out. if (this.SimulationContext is CapeOpen.ICapeDiagnostic) { ((CapeOpen.ICapeDiagnostic) this.SimulationContext).LogMessage("Starting Mixer Calculation"); } this.calcReport = String.Concat(this.calcReport, "Starting Mixer Calculation", System.Environment.NewLine); // Get the material Object from Port 0. ICapeThermoMaterial in1 = null; ICapeThermoMaterial in2 = null; ICapeThermoMaterial outlet = null; ICapeThermoMaterial temp = null; String[] compIds1 = null; String[] compIds2 = null; String[] compIds3 = null; String[] forms = null; String[] names = null; double[] bTemps = null; double[] molWts = null; String[] casNos = null; try { temp = (ICapeThermoMaterial)this.Ports[0].connectedObject; in1 = (ICapeThermoMaterial)temp.CreateMaterial(); in1.CopyFromMaterial(temp); if (temp.GetType().IsCOMObject) { System.Runtime.InteropServices.Marshal.ReleaseComObject(temp); } ((CapeOpen.ICapeThermoCompounds)in1).GetCompoundList(ref compIds1, ref forms, ref names, ref bTemps, ref molWts, ref casNos); temp = (ICapeThermoMaterial)this.Ports[1].connectedObject; in2 = (ICapeThermoMaterial)temp.CreateMaterial(); in2.CopyFromMaterial(temp); if (temp.GetType().IsCOMObject) { System.Runtime.InteropServices.Marshal.FinalReleaseComObject(temp); } ((CapeOpen.ICapeThermoCompounds)in2).GetCompoundList(ref compIds2, ref forms, ref names, ref bTemps, ref molWts, ref casNos); outlet = (ICapeThermoMaterial)this.Ports[2].connectedObject; ((CapeOpen.ICapeThermoCompounds)outlet).GetCompoundList(ref compIds3, ref forms, ref names, ref bTemps, ref molWts, ref casNos); } catch (System.Exception p_Ex) { CapeOpen.CapeInvalidOperationException ex = new CapeOpen.CapeInvalidOperationException("Material object does not support CAPE-OPEN Thermodynamics 1.1.", p_Ex); this.calcReport = String.Concat(this.calcReport, "Material object does not support CAPE-OPEN Thermodynamics 1.1.", System.Environment.NewLine); this.throwException(ex); } int l1 = compIds1.Length; int l2 = compIds2.Length; int l3 = compIds3.Length; if (l1 != l2) { this.calcReport = String.Concat(this.calcReport, "Compounds in imlet materials do not match.", System.Environment.NewLine); throw new CapeOpen.CapeInvalidOperationException("Compounds in imlet materials do not match."); } if (l1 != l3) { this.calcReport = String.Concat(this.calcReport, "Compounds in imlet materials does not match outlet material.", System.Environment.NewLine); throw new CapeOpen.CapeInvalidOperationException("Compounds in imlet materials does not match outlet material."); } for (int i = 0; i < l3; i++) { if ((String.Compare(compIds1[i], compIds2[i])) != 0) { this.calcReport = String.Concat(this.calcReport, "Compounds in imlet materials do not match.", System.Environment.NewLine); throw new CapeOpen.CapeInvalidOperationException("Compounds in imlet materials do not match."); } if (String.Compare(compIds1[i], compIds3[i]) != 0) { this.calcReport = String.Concat(this.calcReport, "Compounds in imlet materials does not match outlet material.", System.Environment.NewLine); throw new CapeOpen.CapeInvalidOperationException("Compounds in imlet materials does not mAtch outlet material."); } } double[] flow1 = null; double[] flow2 = null; double[] press1 = null; double[] press2 = null; double[] flow3 = new double[l3]; String[] props = { "enthalpy" }; String[] overall = { "Overall" }; double[] enthalpy = { 0 }; String[] phases = null; CapeOpen.ICapeThermoEquilibriumRoutine eqRoutine; string[] strArr1 = null; string[] strArr2 = null; try { in1.GetOverallProp("flow", "mole", ref flow1); double totalFlow = 0; foreach (double flow in flow1) { totalFlow = totalFlow + flow; } in1.GetOverallProp("pressure", "", ref press1); CapeOpen.ICapeThermoPropertyRoutine p_Calc = (CapeOpen.ICapeThermoPropertyRoutine)in1; CapeOpen.ICapeThermoPhases phaseList = (CapeOpen.ICapeThermoPhases)in1; phaseList.GetPhaseList(ref phases, ref strArr1, ref strArr2); foreach (String phase in phases) { p_Calc.CalcSinglePhaseProp(props, phase); double[] enth = null; in1.GetSinglePhaseProp("enthalpy", phase, "mole", ref enth); double[] fract = null; in1.GetSinglePhaseProp("phaseFraction", phase, "mole", ref fract); enthalpy[0] = enthalpy[0] + totalFlow * fract[0] * enth[0]; } IDisposable disp = in1 as IDisposable; if (disp != null) { disp.Dispose(); } } catch (System.Exception p_Ex) { CapeOpen.ECapeUser user = (CapeOpen.ECapeUser)in1; this.calcReport = String.Concat(this.calcReport, user.description, System.Environment.NewLine); this.throwException(p_Ex); } try { in2.GetOverallProp("flow", "mole", ref flow2); double totalFlow = 0; foreach (double flow in flow2) { totalFlow = totalFlow + flow; } in2.GetOverallProp("pressure", "", ref press2); CapeOpen.ICapeThermoPropertyRoutine p_Calc = (CapeOpen.ICapeThermoPropertyRoutine)in2; CapeOpen.ICapeThermoPhases phaseList = (CapeOpen.ICapeThermoPhases)in2; phaseList.GetPhaseList(ref phases, ref strArr1, ref strArr2); foreach (String phase in phases) { p_Calc.CalcSinglePhaseProp(props, phase); double[] enth = null; in2.GetSinglePhaseProp("enthalpy", phase, "mole", ref enth); double[] fract = null; in2.GetSinglePhaseProp("phaseFraction", phase, "mole", ref fract); enthalpy[0] = enthalpy[0] + totalFlow * fract[0] * enth[0]; } IDisposable disp = in2 as IDisposable; if (disp != null) { disp.Dispose(); } } catch (System.Exception p_Ex) { CapeOpen.ECapeUser user = (CapeOpen.ECapeUser)in2; this.calcReport = String.Concat(this.calcReport, user.description, System.Environment.NewLine); this.throwException(p_Ex); } for (int i = 0; i < l3; i++) { flow3[i] = flow1[i] + flow2[i]; } try { outlet.SetOverallProp("flow", "mole", flow3); double[] press = new double[1]; press[0] = press1[0]; if (press1[0] > press2[0]) { press[0] = press2[0]; } double pressdrop = ((CapeOpen.RealParameter) this.Parameters[0]).SIValue; press[0] = press[0] - pressdrop; outlet.SetOverallProp("pressure", "", press); double[] totalFlow = null; outlet.GetOverallProp("totalFlow", "mole", ref totalFlow); enthalpy[0] = enthalpy[0] / totalFlow[0]; outlet.SetOverallProp("enthalpy", "mole", enthalpy); this.calcReport = String.Concat(this.calcReport, "The outlet pressure is: ", press[0].ToString(), "Pa", System.Environment.NewLine); CapePhaseStatus[] status = { CapePhaseStatus.CAPE_ATEQUILIBRIUM, CapePhaseStatus.CAPE_ATEQUILIBRIUM }; outlet.SetPresentPhases(phases, status); this.calcReport = String.Concat(this.calcReport, "The outlet ethalpy is: ", enthalpy[0].ToString(), "J/Mole", System.Environment.NewLine); eqRoutine = (CapeOpen.ICapeThermoEquilibriumRoutine)outlet; String[] spec1 = { "pressure", String.Empty, "Overall" }; String[] spec2 = { "enthalpy", String.Empty, "Overall" }; eqRoutine.CalcEquilibrium(spec1, spec2, "unspecified"); this.calcReport = String.Concat(this.calcReport, "Calculated pressure-enthalpy flash", System.Environment.NewLine); } catch (System.Exception p_Ex) { CapeOpen.ECapeUser user = (CapeOpen.ECapeUser)outlet; this.calcReport = String.Concat(this.calcReport, user.description, System.Environment.NewLine); this.throwException(p_Ex); } // Log the end of the calculation. this.calcReport = String.Concat(this.calcReport, "Ending Mixer Calculation"); if (this.SimulationContext is CapeOpen.ICapeDiagnostic) { ((CapeOpen.ICapeDiagnostic) this.SimulationContext).LogMessage("Ending Mixer Calculation"); } }