Exemple #1
0
        void Init()
        {
            Padding = new Padding(10);

            var su = flowsheet.FlowsheetOptions.SelectedUnitSystem;
            var nf = flowsheet.FlowsheetOptions.NumberFormat;

            assayname = "MyAssay" + new Random().Next(1, 100).ToString("000");

            s.CreateAndAddLabelRow(this, "Assay Information");
            s.CreateAndAddStringEditorRow(this, "Assay Name", assayname, (arg3, arg2) =>
            {
                assayname = arg3.Text;
            });
            s.CreateAndAddDescriptionRow(this, "Enter the name of the assay. It will be used to identify the Material Stream on the flowsheet and the associated compounds as well.");

            s.CreateAndAddDropDownRow(this, "Assay Type", new List <string>()
            {
                "Light", "Average", "Heavy"
            }, 0, (arg3, arg2) =>
            {
                switch (arg3.SelectedIndex)
                {
                case 0:
                    type = SampleType.Light;
                    break;

                case 1:
                    type = SampleType.Average;
                    break;

                case 2:
                    type = SampleType.Heavy;
                    break;
                }
            });
            s.CreateAndAddDescriptionRow(this, "Select the type of the assay. Property calculation methods will be selected according to this setting.");

            s.CreateAndAddLabelRow(this, "Setup Curves");

            string[] curvetypes = { "TBP, ASTM D2892", "ASTM D86", "ASTM D1160", "ASTM D2887" };

            var curvetypeselector = s.CreateAndAddDropDownRow(this, "Boiling Point Curve Type", curvetypes.ToList(), 0, (arg3, arg2) => { });

            var chk_mwcurve = s.CreateAndAddCheckBoxRow(this, "Molar Weight", false, (arg3, arg2) => { });

            var chk_sgcurve = s.CreateAndAddCheckBoxRow(this, "Specific Gravity", false, (arg3, arg2) => { });

            var chk_visc100 = s.CreateAndAddCheckBoxRow(this, "Kinematic Viscosity @ 100 F", false, (arg3, arg2) => { });

            var chk_visc210 = s.CreateAndAddCheckBoxRow(this, "Kinematic Viscosity @ 210 F", false, (arg3, arg2) => { });

            string[] curvebasistypes = { "Liquid Volume (%)", "Molar (%)", "Mass (%)" };

            var curvebasisselector = s.CreateAndAddDropDownRow(this, "Curve Basis", curvebasistypes.ToList(), 0, (arg3, arg2) => { });

            s.CreateAndAddLabelRow(this, "Bulk Sample Data");

            var sgtbox = s.CreateAndAddTextBoxRow(this, nf, "Specific Gravity", 0.0d, (arg3, arg2) => { });

            s.CreateAndAddDescriptionRow(this, "Leave it unchanged if not available.");

            var mwtbox = s.CreateAndAddTextBoxRow(this, nf, "Molar Weight", 0.0d, (arg3, arg2) => { });

            s.CreateAndAddDescriptionRow(this, "Leave it unchanged if not available.");

            s.CreateAndAddLabelRow(this, "Curve Data");

            s.CreateAndAddDescriptionRow(this, "Enter curve data in the field below, separating the column values with spaces. Values should be input without thousands separator. First column is the curve basis data, following columns should contain the data according the the curve selection above.");

            s.CreateAndAddDescriptionRow(this, "Current Temperature units: " + su.temperature);
            s.CreateAndAddDescriptionRow(this, "Current Kinematic Viscosity units: " + su.cinematic_viscosity);

            var decsepsel1 = s.CreateAndAddDropDownRow(this, "Decimal Separator", new[] { "Dot (.)", "Comma (,)" }.ToList(), 0, (arg3, arg2) => { });

            var txtcurvedata = s.CreateAndAddMultilineMonoSpaceTextBoxRow(this, "", 200, false, (arg3, arg2) => { });

            s.CreateAndAddLabelRow(this, "Pseudo Compounds");
            s.CreateAndAddDescriptionRow(this, "Select the method to be used for generation of pseudo compounds (petroleum fractions).");

            string[] pseudotypes = { "Defined Number", "Defined Cut Temperatures" };

            var pseudomodeselector = s.CreateAndAddDropDownRow(this, "Pseudo Cut Type", pseudotypes.ToList(), 0, (arg3, arg2) => { });

            s.CreateAndAddDescriptionRow(this, "Enter the number of pseudo compounds in the field below if you selected the first option in the selector above, or the cut temperatures in the current temperature units, separated by spaces and without thousands separator. Do not include the maximum and minimum temperatures on the list.");

            var decsepsel2 = s.CreateAndAddDropDownRow(this, "Decimal Separator", new[] { "Dot (.)", "Comma (,)" }.ToList(), 0, (arg3, arg2) => { });

            var txtpseudomodedata = s.CreateAndAddFullTextBoxRow(this, "10", (arg3, arg2) => { });

            s.CreateAndAddButtonRow(this, "Characterize Assay and Create Compounds", null, (arg3, arg2) =>
            {
                var comps = new Dictionary <string, Compound>();

                //get data

                tbpcurvetype = curvetypeselector.SelectedIndex;
                hasmwc       = chk_mwcurve.Checked.GetValueOrDefault();
                hassgc       = chk_sgcurve.Checked.GetValueOrDefault();
                hasvisc100c  = chk_visc100.Checked.GetValueOrDefault();
                hasvisc210c  = chk_visc210.Checked.GetValueOrDefault();
                curvebasis   = curvebasisselector.SelectedIndex;
                Double.TryParse(sgtbox.Text, out sgb);
                Double.TryParse(mwtbox.Text, out mwb);
                pseudomode = pseudomodeselector.SelectedIndex;
                decsep1    = decsepsel1.SelectedIndex == 0 ? "." : ",";
                decsep2    = decsepsel2.SelectedIndex == 0 ? "." : ",";

                var datalines = txtcurvedata.Text.Split('\n');
                try
                {
                    ParseCurveData(datalines, su);
                }
                catch (Exception ex)
                {
                    flowsheet.ShowMessage("Error parsing curve data: " + ex.Message, IFlowsheet.MessageType.GeneralError);
                    return;
                }

                try
                {
                    if (pseudomode == 0)
                    {
                        pseudocuts = Int32.Parse(txtpseudomodedata.Text);
                    }
                    else
                    {
                        cuttemps = txtpseudomodedata.Text.Trim().Split(' ').Select(t => t.ToDoubleWithSeparator(decsep2)).ToList();
                    }
                }
                catch (Exception ex)
                {
                    flowsheet.ShowMessage("Error parsing pseudo compound cuts: " + ex.Message, IFlowsheet.MessageType.GeneralError);
                    return;
                }

                var dialog = ProgressDialog.Show(this, "Petroleum Characterization", "Generating compounds, please wait...", true);

                Task.Factory.StartNew(() =>
                {
                    comps = GenerateCompounds(su);

                    foreach (var comp in comps.Values)
                    {
                        if (!flowsheet.AvailableCompounds.ContainsKey(comp.Name))
                        {
                            flowsheet.AvailableCompounds.Add(comp.Name, comp.ConstantProperties);
                        }
                        flowsheet.SelectedCompounds.Add(comp.Name, flowsheet.AvailableCompounds[comp.Name]);
                        foreach (MaterialStream obj in flowsheet.SimulationObjects.Values.Where((x) => x.GraphicObject.ObjectType == ObjectType.MaterialStream))
                        {
                            foreach (var phase in obj.Phases.Values)
                            {
                                phase.Compounds.Add(comp.Name, new Compound(comp.Name, ""));
                                phase.Compounds[comp.Name].ConstantProperties = flowsheet.SelectedCompounds[comp.Name];
                            }
                        }
                    }

                    var ms = (MaterialStream)flowsheet.AddObject(ObjectType.MaterialStream, 100, 100, assayname);

                    double wtotal = comps.Values.Select((x) => x.MoleFraction.GetValueOrDefault() * x.ConstantProperties.Molar_Weight).Sum();

                    foreach (var c in ms.Phases[0].Compounds.Values)
                    {
                        c.MassFraction = 0.0f;
                        c.MoleFraction = 0.0f;
                    }

                    foreach (var c in comps.Values)
                    {
                        c.MassFraction = c.MoleFraction.GetValueOrDefault() * c.ConstantProperties.Molar_Weight / wtotal;
                        ms.Phases[0].Compounds[c.Name].MassFraction = c.MassFraction.GetValueOrDefault();
                        ms.Phases[0].Compounds[c.Name].MoleFraction = c.MoleFraction.GetValueOrDefault();
                    }
                }).ContinueWith((t) =>
                {
                    Application.Instance.Invoke(() =>
                    {
                        dialog.Close();
                    });
                    if (t.Exception == null)
                    {
                        Application.Instance.Invoke(() =>
                        {
                            flowsheet.UpdateInterface();
                            flowsheet.ShowMessage("Material Stream '" + assayname + "' added successfully. " + ncomps.ToString() + " compounds created.", IFlowsheet.MessageType.Information);

                            if (MessageBox.Show("Do you want to export the created compounds to a XML database?", "Petroleum C7+ Characterization", MessageBoxButtons.YesNo, MessageBoxType.Question, MessageBoxDefaultButton.Yes) == DialogResult.Yes)
                            {
                                try
                                {
                                    var compstoexport = comps.Values.Select((x) => x.ConstantProperties).ToArray();
                                    var savedialog    = new SaveFileDialog();
                                    savedialog.Title  = "Save Compounds to XML Database";
                                    savedialog.Filters.Add(new FileFilter("XML File", new[] { ".xml" }));
                                    savedialog.CurrentFilterIndex = 0;
                                    if (savedialog.ShowDialog(this) == DialogResult.Ok)
                                    {
                                        try
                                        {
                                            if (!File.Exists(savedialog.FileName))
                                            {
                                                File.WriteAllText(savedialog.FileName, "");
                                                Thermodynamics.Databases.UserDB.CreateNew(savedialog.FileName, "compounds");
                                            }
                                            Thermodynamics.Databases.UserDB.AddCompounds(compstoexport, savedialog.FileName, true);
                                            flowsheet.ShowMessage("Compounds successfully saved to XML file.", IFlowsheet.MessageType.Information);
                                        }
                                        catch (Exception ex)
                                        {
                                            flowsheet.ShowMessage("Error saving compound to JSON file: " + ex.ToString(), IFlowsheet.MessageType.GeneralError);
                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    flowsheet.ShowMessage("Error saving data: " + ex.ToString(), IFlowsheet.MessageType.GeneralError);
                                }
                            }
                        });
                    }
                    else
                    {
                        Application.Instance.Invoke(() =>
                        {
                            flowsheet.ShowMessage("Error: " + t.Exception.GetBaseException().Message, IFlowsheet.MessageType.GeneralError);
                        });
                    }
                });
            });
        }
Exemple #2
0
        void AddFlashAlgorithmItem(IFlashAlgorithm fa)
        {
            var tr = new TableRow();

            tr = s.CreateAndAddTextBoxAndTwoButtonsRow(facontainer, fa.Tag, "Edit", null, "Remove", null,
                                                       (arg1, arg2) =>
            {
                fa.Tag = arg1.Text;
            },
                                                       (arg1, arg2) =>
            {
                if (Application.Instance.Platform.IsMac)
                {
                    flowsheet.ShowMessage("Sorry, editing a Flash Algorithm is not yet possible on the macOS platform.", IFlowsheet.MessageType.GeneralError);
                    return;
                }
                Application.Instance.Invoke(() =>
                {
                    Thermodynamics.FlashAlgorithmConfig f = new Thermodynamics.FlashAlgorithmConfig
                    {
                        Settings           = fa.FlashSettings,
                        AvailableCompounds = flowsheet.SelectedCompounds.Values.Select(x => x.Name).ToList(),
                        FlashAlgo          = fa
                    };

                    if (fa is DWSIM.Thermodynamics.PropertyPackages.Auxiliary.FlashAlgorithms.CAPEOPEN_Equilibrium_Server)
                    {
                        var coflash = (DWSIM.Thermodynamics.PropertyPackages.Auxiliary.FlashAlgorithms.CAPEOPEN_Equilibrium_Server)fa;

                        f._coes          = coflash._coes;
                        f._coppm         = coflash._coppm;
                        f._selppm        = coflash._selppm;
                        f._esname        = coflash._esname;
                        f._mappings      = coflash._mappings;
                        f._phasemappings = coflash._phasemappings;

                        f.ShowDialog();

                        coflash._coes          = f._coes;
                        coflash._coppm         = f._coppm;
                        coflash._selppm        = f._selppm;
                        coflash._esname        = f._esname;
                        coflash._mappings      = f._mappings;
                        coflash._phasemappings = f._phasemappings;

                        fa.FlashSettings = f.Settings;

                        f.Dispose();
                        f = null;
                    }
                    else
                    {
                        f.ShowDialog();
                        fa.FlashSettings = f.Settings;
                        f.Dispose();
                        f = null;
                    }
                });
            },
                                                       (arg1, arg2) =>
            {
                if (MessageBox.Show("Confirm removal?", "Remove Flash Algorithm", MessageBoxButtons.YesNo, MessageBoxType.Question, MessageBoxDefaultButton.No) == DialogResult.Yes)
                {
                    facontainer.Remove(tr);
                    flowsheet.FlowsheetOptions.FlashAlgorithms.Remove(fa);
                }
            });
        }
Exemple #3
0
        void Init()
        {
            Padding = new Padding(10);

            mw0  = 80.0f;
            sg0  = 0.70f;
            nbp0 = 333.0f;

            t1 = 38 + 273.15;
            t2 = 98.9 + 273.15;

            assayname = "OIL";
            v1        = 0;
            v2        = 0;

            var su = flowsheet.FlowsheetOptions.SelectedUnitSystem;
            var nf = flowsheet.FlowsheetOptions.NumberFormat;

            s.CreateAndAddLabelRow(this, "Assay Identification");
            s.CreateAndAddStringEditorRow(this, "Assay Name", assayname, (arg3, arg2) =>
            {
                assayname = arg3.Text;
            });
            s.CreateAndAddDescriptionRow(this, "Enter the name of the assay. It will be used to identify the Material Stream on the flowsheet and the associated compounds as well.");

            s.CreateAndAddLabelRow(this, "Property Methods");

            s.CreateAndAddDescriptionRow(this, "Select the methods to calculate compound properties.");

            s.CreateAndAddDropDownRow(this, "Molecular Weight", new List <string>()
            {
                "Winn (1956)", "Riazi (1986)", "Lee-Kesler (1974)"
            }, 0, (arg3, arg2) =>
            {
                MWcorr = arg3.SelectedValue.ToString();
            });
            s.CreateAndAddDropDownRow(this, "Critical Temperature", new List <string>()
            {
                "Riazi-Daubert (1985)", "Riazi (2005)", "Lee-Kesler (1976)", "Farah (2006)"
            }, 0, (arg3, arg2) =>
            {
                Tccorr = arg3.SelectedValue.ToString();
            });
            s.CreateAndAddDropDownRow(this, "Critical Pressure", new List <string>()
            {
                "Riazi-Daubert (1985)", "Lee-Kesler (1976)", "Farah (2006)"
            }, 0, (arg3, arg2) =>
            {
                Pccorr = arg3.SelectedValue.ToString();
            });
            s.CreateAndAddDropDownRow(this, "Acentric Factor", new List <string>()
            {
                "Lee-Kesler (1976)", "Korsten (2000)"
            }, 0, (arg3, arg2) =>
            {
                AFcorr = arg3.SelectedValue.ToString();
            });
            s.CreateAndAddCheckBoxRow(this, "Adjust Acentric Factors to match Normal Boiling Temperatures", adjustAf, (arg1, arg2) =>
            {
                adjustAf = arg1.Checked.GetValueOrDefault();
            }, null);
            s.CreateAndAddCheckBoxRow(this, "Adjust Rackett Parameters to match Specific Gravities", adjustZR, (arg1, arg2) =>
            {
                adjustZR = arg1.Checked.GetValueOrDefault();
            }, null);

            s.CreateAndAddLabelRow(this, "Assay Properties");
            s.CreateAndAddDescriptionRow(this, "Define at least one of the following three properties in order to calculate a property distribution.");

            s.CreateAndAddTextBoxRow(this, nf, "Molar Weight", mw.GetValueOrDefault(), (arg3, arg2) =>
            {
                if (s.IsValidDouble(arg3.Text))
                {
                    mw = Double.Parse(arg3.Text);
                }
            });
            s.CreateAndAddDescriptionRow(this, "Leave it unchanged if not available.");
            s.CreateAndAddTextBoxRow(this, nf, "Specific Gravity", sg.GetValueOrDefault(), (arg3, arg2) =>
            {
                if (s.IsValidDouble(arg3.Text))
                {
                    sg = Double.Parse(arg3.Text);
                }
            });
            s.CreateAndAddDescriptionRow(this, "Leave it unchanged if not available.");
            s.CreateAndAddTextBoxRow(this, nf, "Average NBP (" + su.temperature + ")", cv.ConvertFromSI(su.temperature, nbp.GetValueOrDefault()), (arg3, arg2) =>
            {
                if (s.IsValidDouble(arg3.Text))
                {
                    nbp = cv.ConvertToSI(su.temperature, Double.Parse(arg3.Text));
                }
            });
            s.CreateAndAddDescriptionRow(this, "Leave it unchanged if not available.");


            s.CreateAndAddLabelRow(this, "Initial Values for Property Distribution");
            s.CreateAndAddTextBoxRow(this, nf, "Molar Weight", mw0, (arg3, arg2) =>
            {
                if (s.IsValidDouble(arg3.Text))
                {
                    mw0 = Double.Parse(arg3.Text);
                }
            });
            s.CreateAndAddDescriptionRow(this, "This defines the Molar Weight of the lightest compound in the assay.");
            s.CreateAndAddTextBoxRow(this, nf, "Specific Gravity", sg0, (arg3, arg2) =>
            {
                if (s.IsValidDouble(arg3.Text))
                {
                    sg0 = Double.Parse(arg3.Text);
                }
            });
            s.CreateAndAddDescriptionRow(this, "This defines the Specific Gravity of the lightest compound in the assay.");
            s.CreateAndAddTextBoxRow(this, nf, "Normal Boiling Point (" + su.temperature + ")", cv.ConvertFromSI(su.temperature, nbp0), (arg3, arg2) =>
            {
                if (s.IsValidDouble(arg3.Text))
                {
                    nbp0 = cv.ConvertToSI(su.temperature, Double.Parse(arg3.Text));
                }
            });
            s.CreateAndAddDescriptionRow(this, "This defines the Normal Boiling Point of the lightest compound in the assay.");

            s.CreateAndAddLabelRow(this, "Pseudo Compounds");
            s.CreateAndAddTextBoxRow(this, "N0", "Number of Compounds", ncomps, (arg3, arg2) =>
            {
                if (s.IsValidDouble(arg3.Text))
                {
                    ncomps = int.Parse(arg3.Text);
                }
            });
            s.CreateAndAddDescriptionRow(this, "Specify the number of compounds to be generated that, together, will represent the assay. The generated compounds will be added to the simulation and a Material Stream will be created with distribution-defined amounts of these compounds.");

            s.CreateAndAddButtonRow(this, "Characterize Assay and Create Compounds", null, (arg3, arg2) =>
            {
                var dialog = ProgressDialog.Show(this, "Petroleum C7+ Characterization", "Generating compounds, please wait...", false);
                var comps  = new Dictionary <string, ICompound>();
                Task.Factory.StartNew(() =>
                {
                    comps = new GenerateCompounds().GenerateCompounds(assayname, ncomps, Tccorr, Pccorr, AFcorr, MWcorr, adjustAf, adjustZR, mw, sg, nbp, v1, v2, t1, t2, mw0, sg0, nbp0);
                }).ContinueWith((t) =>
                {
                    Application.Instance.Invoke(() => { dialog.Close(); });
                    if (t.Exception == null)
                    {
                        var assay = new DWSIM.SharedClasses.Utilities.PetroleumCharacterization.Assay.Assay(mw.GetValueOrDefault(), sg.GetValueOrDefault(), nbp.GetValueOrDefault(), t1, t2, v1, v2);
                        var ms2   = new MaterialStream("", "");
                        ms2.SetFlowsheet(flowsheet);
                        if (flowsheet.PropertyPackages.Count > 0)
                        {
                            ms2.SetPropertyPackage(flowsheet.PropertyPackages.Values.First());
                        }
                        else
                        {
                            ms2.SetPropertyPackage(new Thermodynamics.PropertyPackages.PengRobinsonPropertyPackage());
                        }
                        foreach (var subst in comps.Values)
                        {
                            ms2.Phases[0].Compounds.Add(subst.Name, subst);
                            ms2.Phases[1].Compounds.Add(subst.Name, new Compound(subst.Name, "")
                            {
                                ConstantProperties = subst.ConstantProperties
                            });
                            ms2.Phases[2].Compounds.Add(subst.Name, new Compound(subst.Name, "")
                            {
                                ConstantProperties = subst.ConstantProperties
                            });
                            ms2.Phases[3].Compounds.Add(subst.Name, new Compound(subst.Name, "")
                            {
                                ConstantProperties = subst.ConstantProperties
                            });
                            ms2.Phases[4].Compounds.Add(subst.Name, new Compound(subst.Name, "")
                            {
                                ConstantProperties = subst.ConstantProperties
                            });
                            ms2.Phases[5].Compounds.Add(subst.Name, new Compound(subst.Name, "")
                            {
                                ConstantProperties = subst.ConstantProperties
                            });
                            ms2.Phases[6].Compounds.Add(subst.Name, new Compound(subst.Name, "")
                            {
                                ConstantProperties = subst.ConstantProperties
                            });
                            ms2.Phases[7].Compounds.Add(subst.Name, new Compound(subst.Name, "")
                            {
                                ConstantProperties = subst.ConstantProperties
                            });
                        }
                        var qc = new Thermodynamics.QualityCheck(assay, ms2);
                        qc.DoQualityCheck();
                        Application.Instance.Invoke(() =>
                        {
                            qc.DisplayForm((c) =>
                            {
                                Application.Instance.Invoke(() =>
                                {
                                    var form = s.GetDefaultEditorForm("Compound Properties: " + c.Name, 800, 600, new CompoundViewer((Flowsheet)flowsheet, c), false);
                                    form.Show();
                                });
                            }, () =>
                            {
                                foreach (var comp in comps.Values)
                                {
                                    if (!flowsheet.AvailableCompounds.ContainsKey(comp.Name))
                                    {
                                        flowsheet.AvailableCompounds.Add(comp.Name, comp.ConstantProperties);
                                    }
                                    flowsheet.SelectedCompounds.Add(comp.Name, flowsheet.AvailableCompounds[comp.Name]);
                                    foreach (MaterialStream obj in flowsheet.SimulationObjects.Values.Where((x) => x.GraphicObject.ObjectType == ObjectType.MaterialStream))
                                    {
                                        foreach (var phase in obj.Phases.Values)
                                        {
                                            phase.Compounds.Add(comp.Name, new Thermodynamics.BaseClasses.Compound(comp.Name, ""));
                                            phase.Compounds[comp.Name].ConstantProperties = flowsheet.SelectedCompounds[comp.Name];
                                        }
                                    }
                                }
                                var ms        = (MaterialStream)flowsheet.AddObject(ObjectType.MaterialStream, 100, 100, assayname);
                                double wtotal = comps.Values.Select((x) => x.MoleFraction.GetValueOrDefault() * x.ConstantProperties.Molar_Weight).Sum();
                                foreach (var c in ms.Phases[0].Compounds.Values)
                                {
                                    c.MassFraction = 0.0f;
                                    c.MoleFraction = 0.0f;
                                }
                                foreach (var c in comps.Values)
                                {
                                    c.MassFraction = c.MoleFraction.GetValueOrDefault() * c.ConstantProperties.Molar_Weight / wtotal;
                                    ms.Phases[0].Compounds[c.Name].MassFraction = c.MassFraction.GetValueOrDefault();
                                    ms.Phases[0].Compounds[c.Name].MoleFraction = c.MoleFraction.GetValueOrDefault();
                                }
                                Application.Instance.Invoke(() =>
                                {
                                    flowsheet.UpdateInterface();
                                    flowsheet.ShowMessage("Material Stream '" + assayname + "' added successfully. " + ncomps.ToString() + " compounds created.", IFlowsheet.MessageType.Information);

                                    if (MessageBox.Show("Do you want to export the created compounds to a XML database?", "Petroleum C7+ Characterization", MessageBoxButtons.YesNo, MessageBoxType.Question, MessageBoxDefaultButton.Yes) == DialogResult.Yes)
                                    {
                                        try
                                        {
                                            var compstoexport = comps.Values.Select((x) => x.ConstantProperties).ToArray();
                                            var savedialog    = new SaveFileDialog();
                                            savedialog.Title  = "Save Compounds to XML Database";
                                            savedialog.Filters.Add(new FileFilter("XML File", new[] { ".xml" }));
                                            savedialog.CurrentFilterIndex = 0;
                                            if (savedialog.ShowDialog(this) == DialogResult.Ok)
                                            {
                                                try
                                                {
                                                    if (!File.Exists(savedialog.FileName))
                                                    {
                                                        File.WriteAllText(savedialog.FileName, "");
                                                        Thermodynamics.Databases.UserDB.CreateNew(savedialog.FileName, "compounds");
                                                    }
                                                    Thermodynamics.Databases.UserDB.AddCompounds(compstoexport, savedialog.FileName, true);
                                                    flowsheet.ShowMessage("Compounds successfully saved to XML file.", IFlowsheet.MessageType.Information);
                                                }
                                                catch (Exception ex)
                                                {
                                                    flowsheet.ShowMessage("Error saving compound to JSON file: " + ex.ToString(), IFlowsheet.MessageType.GeneralError);
                                                }
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            flowsheet.ShowMessage("Error saving data: " + ex.ToString(), IFlowsheet.MessageType.GeneralError);
                                        }
                                    }
                                });
                            });
                        });
                    }
                    else
                    {
                        Application.Instance.Invoke(() =>
                        {
                            flowsheet.ShowMessage("Error saving data: " + t.Exception.GetBaseException().Message, IFlowsheet.MessageType.GeneralError);
                        });
                    }
                });
            });
        }
Exemple #4
0
        void Init()
        {
            Padding = new Padding(10);

            mw0  = 80.0f;
            sg0  = 0.70f;
            nbp0 = 333.0f;

            t1 = 38 + 273.15;
            t2 = 98.9 + 273.15;

            assayname = "OIL";
            v1        = 0;
            v2        = 0;

            var su = flowsheet.FlowsheetOptions.SelectedUnitSystem;
            var nf = flowsheet.FlowsheetOptions.NumberFormat;

            s.CreateAndAddLabelRow(this, "Assay Identification");
            s.CreateAndAddStringEditorRow(this, "Assay Name", assayname, (arg3, arg2) =>
            {
                assayname = arg3.Text;
            });
            s.CreateAndAddDescriptionRow(this, "Enter the name of the assay. It will be used to identify the Material Stream on the flowsheet and the associated compounds as well.");

            s.CreateAndAddLabelRow(this, "Assay Properties");
            s.CreateAndAddDescriptionRow(this, "Select the assay type and define at least one of the following three properties in order to calculate a property distribution.");
            s.CreateAndAddDropDownRow(this, "Assay Type", new List <string>()
            {
                "Light", "Average", "Heavy"
            }, 0, (arg3, arg2) =>
            {
                switch (arg3.SelectedIndex)
                {
                case 0:
                    type = SampleType.Light;
                    break;

                case 1:
                    type = SampleType.Average;
                    break;

                case 2:
                    type = SampleType.Heavy;
                    break;
                }
            });
            s.CreateAndAddDescriptionRow(this, "Select the type of the assay. Property calculation methods will be selected according to this setting.");
            s.CreateAndAddTextBoxRow(this, nf, "Molar Weight", mw.GetValueOrDefault(), (arg3, arg2) =>
            {
                if (s.IsValidDouble(arg3.Text))
                {
                    mw = Double.Parse(arg3.Text);
                }
            });
            s.CreateAndAddDescriptionRow(this, "Leave it unchanged if not available.");
            s.CreateAndAddTextBoxRow(this, nf, "Specific Gravity", sg.GetValueOrDefault(), (arg3, arg2) =>
            {
                if (s.IsValidDouble(arg3.Text))
                {
                    sg = Double.Parse(arg3.Text);
                }
            });
            s.CreateAndAddDescriptionRow(this, "Leave it unchanged if not available.");
            s.CreateAndAddTextBoxRow(this, nf, "Average NBP (" + su.temperature + ")", cv.ConvertFromSI(su.temperature, nbp.GetValueOrDefault()), (arg3, arg2) =>
            {
                if (s.IsValidDouble(arg3.Text))
                {
                    nbp = cv.ConvertToSI(su.temperature, Double.Parse(arg3.Text));
                }
            });
            s.CreateAndAddDescriptionRow(this, "Leave it unchanged if not available.");


            s.CreateAndAddLabelRow(this, "Initial Values for Property Distribution");
            s.CreateAndAddTextBoxRow(this, nf, "Molar Weight", mw0, (arg3, arg2) =>
            {
                if (s.IsValidDouble(arg3.Text))
                {
                    mw0 = Double.Parse(arg3.Text);
                }
            });
            s.CreateAndAddDescriptionRow(this, "This defines the Molar Weight of the lightest compound in the assay.");
            s.CreateAndAddTextBoxRow(this, nf, "Specific Gravity", sg0, (arg3, arg2) =>
            {
                if (s.IsValidDouble(arg3.Text))
                {
                    sg0 = Double.Parse(arg3.Text);
                }
            });
            s.CreateAndAddDescriptionRow(this, "This defines the Specific Gravity of the lightest compound in the assay.");
            s.CreateAndAddTextBoxRow(this, nf, "Normal Boiling Point (" + su.temperature + ")", cv.ConvertFromSI(su.temperature, nbp0), (arg3, arg2) =>
            {
                if (s.IsValidDouble(arg3.Text))
                {
                    nbp0 = cv.ConvertToSI(su.temperature, Double.Parse(arg3.Text));
                }
            });
            s.CreateAndAddDescriptionRow(this, "This defines the Normal Boiling Point of the lightest compound in the assay.");

            s.CreateAndAddLabelRow(this, "Pseudo Compounds");
            s.CreateAndAddTextBoxRow(this, "N0", "Number of Compounds", ncomps, (arg3, arg2) =>
            {
                if (s.IsValidDouble(arg3.Text))
                {
                    ncomps = int.Parse(arg3.Text);
                }
            });
            s.CreateAndAddDescriptionRow(this, "Specify the number of compounds to be generated that, together, will represent the assay. The generated compounds will be added to the simulation and a Material Stream will be created with distribution-defined amounts of these compounds.");

            s.CreateAndAddButtonRow(this, "Characterize Assay and Create Compounds", null, (arg3, arg2) =>
            {
                var dialog = ProgressDialog.Show(this, "Petroleum C7+ Characterization", "Generating compounds, please wait...", false);

                var comps = new Dictionary <string, ICompound>();

                Task.Factory.StartNew(() =>
                {
                    comps = new GenerateCompounds().GenerateCompounds(assayname, ncomps, type, mw, sg, nbp, v1, v2, t1, t2, mw0, sg0, nbp0);
                    foreach (var comp in comps.Values)
                    {
                        if (!flowsheet.AvailableCompounds.ContainsKey(comp.Name))
                        {
                            flowsheet.AvailableCompounds.Add(comp.Name, comp.ConstantProperties);
                        }
                        flowsheet.SelectedCompounds.Add(comp.Name, flowsheet.AvailableCompounds[comp.Name]);
                        foreach (MaterialStream obj in flowsheet.SimulationObjects.Values.Where((x) => x.GraphicObject.ObjectType == ObjectType.MaterialStream))
                        {
                            foreach (var phase in obj.Phases.Values)
                            {
                                phase.Compounds.Add(comp.Name, new Thermodynamics.BaseClasses.Compound(comp.Name, ""));
                                phase.Compounds[comp.Name].ConstantProperties = flowsheet.SelectedCompounds[comp.Name];
                            }
                        }
                    }
                    var ms        = (MaterialStream)flowsheet.AddObject(ObjectType.MaterialStream, 100, 100, assayname);
                    double wtotal = comps.Values.Select((x) => x.MoleFraction.GetValueOrDefault() * x.ConstantProperties.Molar_Weight).Sum();
                    foreach (var c in ms.Phases[0].Compounds.Values)
                    {
                        c.MassFraction = 0.0f;
                        c.MoleFraction = 0.0f;
                    }
                    foreach (var c in comps.Values)
                    {
                        c.MassFraction = c.MoleFraction.GetValueOrDefault() * c.ConstantProperties.Molar_Weight / wtotal;
                        ms.Phases[0].Compounds[c.Name].MassFraction = c.MassFraction.GetValueOrDefault();
                        ms.Phases[0].Compounds[c.Name].MoleFraction = c.MoleFraction.GetValueOrDefault();
                    }
                }).ContinueWith((t) =>
                {
                    Application.Instance.Invoke(() => { dialog.Close(); });
                    if (t.Exception == null)
                    {
                        Application.Instance.Invoke(() =>
                        {
                            flowsheet.UpdateInterface();
                            flowsheet.ShowMessage("Material Stream '" + assayname + "' added successfully. " + ncomps.ToString() + " compounds created.", IFlowsheet.MessageType.Information);

                            if (MessageBox.Show("Do you want to export the created compounds to a XML database?", "Petroleum C7+ Characterization", MessageBoxButtons.YesNo, MessageBoxType.Question, MessageBoxDefaultButton.Yes) == DialogResult.Yes)
                            {
                                try
                                {
                                    var compstoexport = comps.Values.Select((x) => x.ConstantProperties).ToArray();
                                    var savedialog    = new SaveFileDialog();
                                    savedialog.Title  = "Save Compounds to XML Database";
                                    savedialog.Filters.Add(new FileFilter("XML File", new[] { ".xml" }));
                                    savedialog.CurrentFilterIndex = 0;
                                    if (savedialog.ShowDialog(this) == DialogResult.Ok)
                                    {
                                        try
                                        {
                                            if (!File.Exists(savedialog.FileName))
                                            {
                                                File.WriteAllText(savedialog.FileName, "");
                                                Thermodynamics.Databases.UserDB.CreateNew(savedialog.FileName, "compounds");
                                            }
                                            Thermodynamics.Databases.UserDB.AddCompounds(compstoexport, savedialog.FileName, true);
                                            flowsheet.ShowMessage("Compounds successfully saved to XML file.", IFlowsheet.MessageType.Information);
                                        }
                                        catch (Exception ex)
                                        {
                                            flowsheet.ShowMessage("Error saving compound to JSON file: " + ex.ToString(), IFlowsheet.MessageType.GeneralError);
                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    flowsheet.ShowMessage("Error saving data: " + ex.ToString(), IFlowsheet.MessageType.GeneralError);
                                }
                            }
                        });
                    }
                    else
                    {
                        Application.Instance.Invoke(() =>
                        {
                            flowsheet.ShowMessage("Error saving data: " + t.Exception.GetBaseException().Message, IFlowsheet.MessageType.GeneralError);
                        });
                    }
                });
            });
        }
Exemple #5
0
        public void Train(IFlowsheet flowsheet, TextArea ta = null, Eto.OxyPlot.Plot plot = null)
        {
            var nl = Environment.NewLine;

            var g = tf.Graph();

            g.as_default();

            if (session != null)
            {
                session.Dispose(); session = null;
            }

            session = tf.Session(graph: g);

            tf_with(tf.variable_scope("Train"), delegate
            {
                if (flowsheet != null)
                {
                    flowsheet.ShowMessage("Training Started...", IFlowsheet.MessageType.Information);
                }
                else
                {
                    Application.Instance.Invoke(() =>
                    {
                        ta.Append("Training Started..." + nl, true);
                    });
                }

                // tf Graph Input

                var X = tf.placeholder(tf.float32, shape: (-1, n_x), name: "X");
                var Y = tf.placeholder(tf.float32, shape: (-1, n_y), name: "Y");

                Tensor outlayer = null;

                var sigma = 1.0f;
                var weight_initializer = tf.variance_scaling_initializer(mode: "FAN_AVG", uniform: true, factor: sigma);
                var bias_initializer   = tf.zeros_initializer;

                var n_neurons_1 = Parameters.NumberOfNeuronsOnFirstLayer;
                var n_neurons_2 = n_neurons_1 / 2;
                var n_neurons_3 = n_neurons_2 / 2;
                var n_neurons_4 = n_neurons_3 / 2;

                RefVariable W_hidden_1, W_hidden_2, W_hidden_3, W_hidden_4, W_out;
                RefVariable bias_hidden_1, bias_hidden_2, bias_hidden_3, bias_hidden_4, bias_out;
                Tensor hidden_1, hidden_2, hidden_3, hidden_4;

                switch (Parameters.NumberOfLayers)
                {
                case 2:
                    // Hidden weights
                    W_hidden_1    = tf.Variable(weight_initializer.call(new int[] { n_x, n_neurons_1 }, dtype: TF_DataType.TF_FLOAT), name: "W1");
                    bias_hidden_1 = tf.Variable(bias_initializer.call(n_neurons_1, dtype: TF_DataType.TF_FLOAT), name: "b1");
                    W_hidden_2    = tf.Variable(weight_initializer.call(new int[] { n_neurons_1, n_neurons_2 }, dtype: TF_DataType.TF_FLOAT), name: "W2");
                    bias_hidden_2 = tf.Variable(bias_initializer.call(n_neurons_2, dtype: TF_DataType.TF_FLOAT), name: "b2");
                    // Output weights
                    W_out    = tf.Variable(weight_initializer.call(new int[] { n_neurons_2, n_y }, dtype: TF_DataType.TF_FLOAT), name: "Wout");
                    bias_out = tf.Variable(bias_initializer.call(n_y, dtype: TF_DataType.TF_FLOAT), name: "bout");
                    // Hidden layer
                    hidden_1 = tf.nn.relu(tf.add(tf.matmul(X, W_hidden_1), bias_hidden_1), name: "h1");
                    hidden_2 = tf.nn.relu(tf.add(tf.matmul(hidden_1, W_hidden_2), bias_hidden_2), name: "h2");
                    // Output layer
                    outlayer = tf.add(tf.matmul(hidden_2, W_out), bias_out, name: "out");
                    break;

                case 3:
                    // Hidden weights
                    W_hidden_1    = tf.Variable(weight_initializer.call(new int[] { n_x, n_neurons_1 }, dtype: TF_DataType.TF_FLOAT), name: "W1");
                    bias_hidden_1 = tf.Variable(bias_initializer.call(n_neurons_1, dtype: TF_DataType.TF_FLOAT), name: "b1");
                    W_hidden_2    = tf.Variable(weight_initializer.call(new int[] { n_neurons_1, n_neurons_2 }, dtype: TF_DataType.TF_FLOAT), name: "W2");
                    bias_hidden_2 = tf.Variable(bias_initializer.call(n_neurons_2, dtype: TF_DataType.TF_FLOAT), name: "b2");
                    W_hidden_3    = tf.Variable(weight_initializer.call(new int[] { n_neurons_2, n_neurons_3 }, dtype: TF_DataType.TF_FLOAT), name: "W3");
                    bias_hidden_3 = tf.Variable(bias_initializer.call(n_neurons_3, dtype: TF_DataType.TF_FLOAT), name: "b3");
                    // Output weights
                    W_out    = tf.Variable(weight_initializer.call(new int[] { n_neurons_3, n_y }, dtype: TF_DataType.TF_FLOAT), name: "Wout");
                    bias_out = tf.Variable(bias_initializer.call(n_y, dtype: TF_DataType.TF_FLOAT), name: "bout");
                    // Hidden layer
                    hidden_1 = tf.nn.relu(tf.add(tf.matmul(X, W_hidden_1), bias_hidden_1), name: "h1");
                    hidden_2 = tf.nn.relu(tf.add(tf.matmul(hidden_1, W_hidden_2), bias_hidden_2), name: "h2");
                    hidden_3 = tf.nn.relu(tf.add(tf.matmul(hidden_2, W_hidden_3), bias_hidden_3), name: "h3");
                    // Output layer
                    outlayer = tf.add(tf.matmul(hidden_3, W_out), bias_out, name: "out");
                    break;

                case 4:
                    // Hidden weights
                    W_hidden_1    = tf.Variable(weight_initializer.call(new int[] { n_x, n_neurons_1 }, dtype: TF_DataType.TF_FLOAT), name: "W1");
                    bias_hidden_1 = tf.Variable(bias_initializer.call(n_neurons_1, dtype: TF_DataType.TF_FLOAT), name: "b1");
                    W_hidden_2    = tf.Variable(weight_initializer.call(new int[] { n_neurons_1, n_neurons_2 }, dtype: TF_DataType.TF_FLOAT), name: "W2");
                    bias_hidden_2 = tf.Variable(bias_initializer.call(n_neurons_2, dtype: TF_DataType.TF_FLOAT), name: "b2");
                    W_hidden_3    = tf.Variable(weight_initializer.call(new int[] { n_neurons_2, n_neurons_3 }, dtype: TF_DataType.TF_FLOAT), name: "W3");
                    bias_hidden_3 = tf.Variable(bias_initializer.call(n_neurons_3, dtype: TF_DataType.TF_FLOAT), name: "b3");
                    W_hidden_4    = tf.Variable(weight_initializer.call(new int[] { n_neurons_3, n_neurons_4 }, dtype: TF_DataType.TF_FLOAT), name: "W4");
                    bias_hidden_4 = tf.Variable(bias_initializer.call(n_neurons_4, dtype: TF_DataType.TF_FLOAT), name: "b4");
                    // Output weights
                    W_out    = tf.Variable(weight_initializer.call(new int[] { n_neurons_4, n_y }, dtype: TF_DataType.TF_FLOAT), name: "Wout");
                    bias_out = tf.Variable(bias_initializer.call(n_y, dtype: TF_DataType.TF_FLOAT), name: "bout");
                    // Hidden layer
                    hidden_1 = tf.nn.relu(tf.add(tf.matmul(X, W_hidden_1), bias_hidden_1), name: "h1");
                    hidden_2 = tf.nn.relu(tf.add(tf.matmul(hidden_1, W_hidden_2), bias_hidden_2), name: "h2");
                    hidden_3 = tf.nn.relu(tf.add(tf.matmul(hidden_2, W_hidden_3), bias_hidden_3), name: "h3");
                    hidden_4 = tf.nn.relu(tf.add(tf.matmul(hidden_3, W_hidden_4), bias_hidden_4), name: "h4");
                    // Output layer
                    outlayer = tf.add(tf.matmul(hidden_4, W_out), bias_out, name: "out");
                    break;
                }

                // Mean squared error
                var mse = tf.reduce_sum(tf.pow(outlayer - Y, 2.0f), name: "mse");

                var learn_rate = tf.constant(Parameters.LearningRate);

                var opt = tf.train.AdamOptimizer(learn_rate).minimize(mse);

                // Fit neural net

                var batch_size = Parameters.BatchSize;

                var mse_train = new List <float>();
                var mse_test  = new List <float>();

                // Initialize the variables (i.e. assign their default value)

                var init = tf.global_variables_initializer();

                // Run the initializer

                session.run(init);

                // Start training

                var epochs = Parameters.NumberOfEpochs;

                foreach (var e in range(epochs))
                {
                    // Shuffle training data
                    var shuffle_indices = np.random.permutation(np.arange(len(x_train)));

                    var shuffled_x = new NDArray(np.float32, x_train.shape);
                    var shuffled_y = new NDArray(np.float32, y_train.shape);

                    int i0 = 0;
                    foreach (var idx0 in shuffle_indices)
                    {
                        shuffled_x[i0] = x_train[idx0];
                        shuffled_y[i0] = y_train[idx0];
                        i0            += 1;
                    }

                    // Minibatch training
                    foreach (var i in range(0, len(y_train) / batch_size))
                    {
                        var start = i * batch_size;

                        var batch_x = shuffled_x[start.ToString() + ":" + (start + batch_size).ToString(), Slice.All];
                        var batch_y = shuffled_y[start.ToString() + ":" + (start + batch_size).ToString(), Slice.All];

                        // Run optimizer with batch
                        session.run(opt, (X, batch_x), (Y, batch_y));

                        // Show progress
                        var divrem = 0;
                        Math.DivRem(e, 5, out divrem);

                        if (divrem == 0)
                        {
                            // MSE train and test
                            mse_train.Add(session.run(mse, (X, x_train), (Y, y_train)));
                            mse_test.Add(session.run(mse, (X, x_test), (Y, y_test)));
                            if (flowsheet != null)
                            {
                                flowsheet.ShowMessage("Epoch: " + e.ToString(), IFlowsheet.MessageType.Information);
                                flowsheet.ShowMessage("MSE (training): " + mse_train.Last().ToString(), IFlowsheet.MessageType.Information);
                                flowsheet.ShowMessage("MSE (testing): " + mse_test.Last().ToString(), IFlowsheet.MessageType.Information);
                            }
                            else
                            {
                                Application.Instance.Invoke(() =>
                                {
                                    ta.Append("Epoch: " + e.ToString() + nl, true);
                                    ta.Append("MSE (training): " + mse_train.Last().ToString() + nl, true);
                                    ta.Append("MSE (testing): " + mse_test.Last().ToString() + nl, true);
                                    (plot.Model.Series[0] as OxyPlot.Series.LineSeries).Points.Add(new DataPoint(e, mse_train.Last()));
                                    (plot.Model.Series[1] as OxyPlot.Series.LineSeries).Points.Add(new DataPoint(e, mse_test.Last()));
                                    plot.Model.InvalidatePlot(true);
                                });
                            }
                            if (e > 10 &&
                                (Math.Abs(mse_train.Last() - mse_train[mse_train.Count - 2]) / mse_train[mse_train.Count - 2] <
                                 Parameters.RelativeMSETolerance))
                            {
                                break;
                            }
                        }
                    }
                }

                if (flowsheet != null)
                {
                    flowsheet.ShowMessage("Training Finished!", IFlowsheet.MessageType.Information);
                }
                else
                {
                    Application.Instance.Invoke(() =>
                    {
                        ta.Append("Training Finished!" + nl, true);
                    });
                }

                x_test_unscaled  = new NDArray(np.float32, x_test.shape);
                x_train_unscaled = new NDArray(np.float32, x_train.shape);

                for (var i = 0; i < x_test.shape[0]; i++)
                {
                    for (var j = 0; j < x_test.shape[1]; j++)
                    {
                        x_test_unscaled[i][j] = Classes.Utils.UnScale(x_test[i][j],
                                                                      Parameters.MinValues[j],
                                                                      Parameters.MaxValues[j],
                                                                      Parameters.MinScale,
                                                                      Parameters.MaxScale);
                    }
                }

                for (var i = 0; i < x_train.shape[0]; i++)
                {
                    for (var j = 0; j < x_train.shape[1]; j++)
                    {
                        x_train_unscaled[i][j] = Classes.Utils.UnScale(x_train[i][j],
                                                                       Parameters.MinValues[j],
                                                                       Parameters.MaxValues[j],
                                                                       Parameters.MinScale,
                                                                       Parameters.MaxScale);
                    }
                }

                var idx = Parameters.Labels.IndexOf(Parameters.Labels_Outputs.First());

                y_test_unscaled  = new NDArray(np.float32, y_test.shape);
                y_train_unscaled = new NDArray(np.float32, y_train.shape);

                for (var i = 0; i < y_test.shape[0]; i++)
                {
                    for (var j = 0; j < y_test.shape[1]; j++)
                    {
                        y_test_unscaled[i][j] = Classes.Utils.UnScale(y_test[i][j],
                                                                      Parameters.MinValues[idx + j],
                                                                      Parameters.MaxValues[idx + j],
                                                                      Parameters.MinScale,
                                                                      Parameters.MaxScale);
                    }
                }

                for (var i = 0; i < y_train.shape[0]; i++)
                {
                    for (var j = 0; j < y_train.shape[1]; j++)
                    {
                        y_train_unscaled[i][j] = Classes.Utils.UnScale(y_train[i][j],
                                                                       Parameters.MinValues[idx + j],
                                                                       Parameters.MaxValues[idx + j],
                                                                       Parameters.MinScale,
                                                                       Parameters.MaxScale);
                    }
                }

                yp_test  = session.run(outlayer, (X, x_test));
                yp_train = session.run(outlayer, (X, x_train));

                yp_test_unscaled  = new NDArray(np.float32, yp_test.shape);
                yp_train_unscaled = new NDArray(np.float32, yp_train.shape);

                for (var i = 0; i < yp_test.shape[0]; i++)
                {
                    for (var j = 0; j < yp_test.shape[1]; j++)
                    {
                        yp_test_unscaled[i][j] = Classes.Utils.UnScale(yp_test[i][j],
                                                                       Parameters.MinValues[idx + j],
                                                                       Parameters.MaxValues[idx + j],
                                                                       Parameters.MinScale,
                                                                       Parameters.MaxScale);
                    }
                }

                for (var i = 0; i < yp_train.shape[0]; i++)
                {
                    for (var j = 0; j < yp_train.shape[1]; j++)
                    {
                        yp_train_unscaled[i][j] = Classes.Utils.UnScale(yp_train[i][j],
                                                                        Parameters.MinValues[idx + j],
                                                                        Parameters.MaxValues[idx + j],
                                                                        Parameters.MinScale,
                                                                        Parameters.MaxScale);
                    }
                }

                // Testing example

                var training_cost = session.run(mse, (X, x_train), (Y, y_train));
                var testing_cost  = session.run(mse, (X, x_test), (Y, y_test));
                var diff          = Math.Abs((float)training_cost - (float)testing_cost);

                if (flowsheet != null)
                {
                    flowsheet.ShowMessage($"Training Cost = {testing_cost}", IFlowsheet.MessageType.Information);
                    flowsheet.ShowMessage($"Testing Cost = {testing_cost}", IFlowsheet.MessageType.Information);
                    flowsheet.ShowMessage($"Absolute MSE = {diff}", IFlowsheet.MessageType.Information);
                }
                else
                {
                    Application.Instance.Invoke(() =>
                    {
                        ta.Append($"Training Cost = {testing_cost}" + nl, true);
                        ta.Append($"Testing Cost = {testing_cost}" + nl, true);
                        ta.Append($"Absolute MSE = {diff}" + nl, true);
                    });
                }
            });