Beispiel #1
0
        public void TestBoilingPoints()
        {
            Substance h2o = (Substance)m_brs.MyMaterialCatalog["Water"].CreateMass(1.0, 31);

            double pressure_1Atm = 101325.0;             // pascals.

            Console.WriteLine("BP of water is " + m_brs.MyMaterialCatalog["Water"].GetEstimatedBoilingPoint(pressure_1Atm) + ".");
            Console.WriteLine("BP of ethanol is " + m_brs.MyMaterialCatalog["Ethanol"].GetEstimatedBoilingPoint(pressure_1Atm) + ".");

            m_brs.MyMaterialCatalog.Add(new MaterialType(null, "Rock", Guid.NewGuid(), 4.5, 3.2, MaterialState.Solid, 76, 455));
            //			m_brs.MyMaterialCatalog["Rock"].SetVaporPressureCurveData(new double[]{1.0,2.0,3.0},new double[]{1.0,2.0,3.0});
            //			m_brs.MyMaterialCatalog["Rock"].SetAntoinesCoefficients3(3,6,9);
            //			m_brs.MyMaterialCatalog["Rock"].SetAntoinesCoefficientsExt(3,6);
            //			m_brs.MyMaterialCatalog["Rock"].SetAntoinesCoefficientsExt(3,6,9,12,15,18,21,24,27);
            //			m_brs.MyMaterialCatalog["Rock"].AddEmissionsClassifications(new string[]{"VOC","SARA","HAP","NATA","GHG","ODC"});


            Mixture m = new Mixture("Stone Soup");

            m.AddMaterial((Substance)m_brs.MyMaterialCatalog["Water"].CreateMass(10.0, 37.0));
            m.AddMaterial((Substance)m_brs.MyMaterialCatalog["Rock"].CreateMass(10.0, 37.0));
            m_brs.MyMaterialCatalog["Rock"].STPState = MaterialState.Solid;

            Console.WriteLine("BP of " + m.Name + " is " + m.GetEstimatedBoilingPoint(pressure_1Atm) + ".");

            m = new Mixture("Primordium");
            m.AddMaterial((Substance)m_brs.MyMaterialCatalog["Water"].CreateMass(10.0, 37.0));
            m.AddMaterial((Substance)m_brs.MyMaterialCatalog["Ethanol"].CreateMass(10.0, 37.0));

            Console.WriteLine("BP of " + m.Name + " is " + m.GetEstimatedBoilingPoint(pressure_1Atm) + ".");
        }
Beispiel #2
0
        public void TestRemoval()
        {
            Model model = new Model("Test Model", Guid.NewGuid());
            BasicReactionSupporter brs = new BasicReactionSupporter();

            InitializeForTesting(brs);

            Mixture         mixture = new Mixture(model, "Contents of vat 1", Guid.NewGuid());
            MaterialCatalog cat     = brs.MyMaterialCatalog;

            mixture.AddMaterial(cat["Acetone"].CreateMass(100, 20));
            mixture.AddMaterial(cat["Potassium Sulfate"].CreateMass(100, 20));
            mixture.AddMaterial(cat["Ammonia"].CreateMass(100, 20));
            Debug.WriteLine("Mixture has the following stuff...");
            DiagnosticAids.DumpMaterial(mixture);
            Assert.IsTrue(mixture.Mass.Equals(300D), "Mixture is not 300 kg");

            Debug.WriteLine("Removing 100 kg of Acetone.");
            IMaterial matl = mixture.RemoveMaterial(cat["Acetone"], 100);

            DiagnosticAids.DumpMaterial(matl);
            Assert.IsTrue(mixture.Mass.Equals(200D), "Mixture is not 200 kg");
            Debug.WriteLine("Remaining is the following mixture:");
            DiagnosticAids.DumpMaterial(mixture);
        }
            public TCTestJig(double tSrc, double tMix, double tAmb, double tSet, double rampRatePerMinute, double err, TemperatureControllerMode tcMode, bool tcEnabled)
            {
                BasicReactionSupporter brs = new BasicReactionSupporter();

                Initialize(brs);
                m_mixture = new Mixture(null, "Test Mixture");
                brs.MyReactionProcessor.Watch(m_mixture);
                Container container = new Container(1000, m_mixture);                // Container full volume is 1000 liters.

                m_tempController = new TemperatureController(container);

                m_mixture.AddMaterial(brs.MyMaterialCatalog["Water"].CreateMass(250, tMix));          // Add 250 kg.
                m_mixture.AddMaterial(brs.MyMaterialCatalog["Sodium Nitrite"].CreateMass(100, tMix)); // Add 100 kg NaNO2.

                m_tempController.AmbientTemperature = tAmb;                                           // degreeC

                // Error band functionality has been obsoleted.
                //m_tempController.ErrorBand = err;         // +/- err degreeC dead band.
                m_err = err;                                             // Used for acceptability of non-precise results.

                m_tempController.SetAmbientThermalConductance(.30, .25); // .25 W/degreeC
                m_tempController.SetAmbientThermalConductance(.60, .50); // .50 W/degreeC
                m_tempController.SetAmbientThermalConductance(.90, .75); // .75 W/degreeC
                m_tempController.SetThermalConductance(.30, .40);        // .4 W/degreeC
                m_tempController.SetThermalConductance(.60, .80);        // .8 W/degreeC
                m_tempController.SetThermalConductance(.90, .120);       // 1.2 W/degreeC

                m_tempController.TCEnabled             = tcEnabled;      // Temperature control system is on.
                m_tempController.TCMode                = tcMode;         // Temperature control system maintains a constant deltaT, or a constant tSrc.
                m_tempController.TCSetpoint            = tSet;
                m_tempController.TCSrcTemperature      = tSrc;           // Syltherm (e.g.) temperature.
                m_tempController.TCSrcDelta            = tSrc;           // To be used if/when the system is in constant delta mode.
                m_tempController.TCTemperatureRampRate = new TemperatureRampRate(5.0, TimeSpan.FromMinutes(1));
            }
        public void TestMVTrackerWithNullMixtures()
        {
            Highpoint.Sage.SimCore.Model model = new Highpoint.Sage.SimCore.Model("MVTTracker model");
            BasicReactionSupporter       brs   = new BasicReactionSupporter();

            InitializeForTesting(brs);

            Mixture current = new Mixture(model, "current", Guid.NewGuid());

            current.AddMaterial(brs.MyMaterialCatalog["Water"].CreateMass(150, 30));
            current.AddMaterial(brs.MyMaterialCatalog["Aluminum Hydroxide"].CreateMass(200, 35));

            MassVolumeTracker cmvt = new MassVolumeTracker(brs.MyReactionProcessor);

            cmvt.SetInitialMixture(null);
            cmvt.SetInflowMixture(null);
            cmvt.SetOutflowMixture(null);
            cmvt.SetVesselCapacity(1000);

            cmvt.Process();

            //_Debug.WriteLine("Temperatures: " + cmvt.TemperatureHistory.ToString());
            _Debug.WriteLine("Masses      : " + cmvt.MassHistory.ToString());
            _Debug.WriteLine("Volumes     : " + cmvt.VolumeHistory.ToString());

            _Debug.Assert(cmvt.MassHistory.ToString().Equals("[0/0/0/0]"));
            _Debug.Assert(cmvt.VolumeHistory.ToString().Equals("[0/0/0/0]"));
        }
Beispiel #5
0
        public void TestBoilingPoints2()
        {
            m_brs.MyMaterialCatalog.Add(new MaterialType(null, "Tula4", Guid.NewGuid(), 1.0, 1.0, MaterialState.Solid, 299, 1.0));
            Substance heptane           = (Substance)m_brs.MyMaterialCatalog["Heptane"].CreateMass(940, 31);
            Substance methyleneChloride = (Substance)m_brs.MyMaterialCatalog["Methylene Chloride"].CreateMass(1036, 31);
            Substance tula4             = (Substance)m_brs.MyMaterialCatalog["Tula4"].CreateMass(217.2, 31);

            double pressure_1Atm = 101325.0;             // pascals.

            Console.WriteLine("BP of Heptane is " + m_brs.MyMaterialCatalog["Heptane"].GetEstimatedBoilingPoint(pressure_1Atm) + ".");
            Console.WriteLine("BP of Methylene Chloride is " + m_brs.MyMaterialCatalog["Methylene Chloride"].GetEstimatedBoilingPoint(pressure_1Atm) + ".");
            Console.WriteLine("BP of Tula4 is " + m_brs.MyMaterialCatalog["Tula4"].GetEstimatedBoilingPoint(pressure_1Atm) + ".");

            Mixture m = new Mixture("Aamir's Soup");

            m.AddMaterial(heptane);
            m.AddMaterial(methyleneChloride);
            m.AddMaterial(tula4);

            Console.WriteLine("BP of " + m.Name + " is " + m.GetEstimatedBoilingPoint(pressure_1Atm) + ".");

            Substance water = (Substance)m_brs.MyMaterialCatalog["Water"].CreateMass(100, 37);

            Console.WriteLine("\r\n...By the way, BP of water is " + water.GetEstimatedBoilingPoint(pressure_1Atm) + ".  ;-)");
        }
            public TSTestJig(double mH2O, double mNANO2)
            {
                m_brs = new BasicReactionSupporter();
                Initialize(m_brs);
                m_mixture = new Mixture(null, "Test Mixture");
                m_brs.MyReactionProcessor.Watch(m_mixture);

                m_mixture.AddMaterial(m_brs.MyMaterialCatalog["Water"].CreateMass(mH2O, 20));            // Add 250 kg.
                m_mixture.AddMaterial(m_brs.MyMaterialCatalog["Sodium Nitrite"].CreateMass(mNANO2, 20)); // Add 100 kg NaNO2.
            }
Beispiel #7
0
        public void TestBoilingPointElevation()
        {
            m_brs.MyMaterialCatalog["Water"].EbullioscopicConstant = 0.512;
            double       pressure_1Atm = 101325.0;       // pascals.
            MaterialType salt          = new MaterialType(null, "Sodium Chloride", Guid.NewGuid(), 1.0 / 2.6, 12.345, MaterialState.Solid, 58.443, 12.345);
            Mixture      mixture       = new Mixture();

            mixture.AddMaterial(m_brs.MyMaterialCatalog["Water"].CreateMass(1.0, 31));
            Console.WriteLine("Boiling point of " + mixture + " is " + mixture.GetEstimatedBoilingPoint(pressure_1Atm));

            for (int i = 0; i < 4; i++)
            {
                mixture.AddMaterial(salt.CreateMass(0.058443, 31));
                Console.WriteLine("Boiling point of " + mixture + " is " + mixture.GetEstimatedBoilingPoint(pressure_1Atm));
            }
        }
Beispiel #8
0
        private void _Update(IExecutive exec, object userData)
        {
            if (!m_inProcess)
            {
                m_inProcess = true;
                double thisFraction     = ((double)(m_model.Executive.Now.Ticks - m_startTicks)) / ((double)m_duration.Ticks);
                double transferFraction = thisFraction - m_lastFraction;
                if (transferFraction > 0)
                {
                    foreach (TypeSpec ts in m_what)
                    {
                        if (ts.Mass > 0)
                        {
                            IMaterial extract = m_from.RemoveMaterial(ts.MaterialType, (ts.Mass * transferFraction));
                            m_to.AddMaterial(extract);
                        }
                    }
                }

                if (m_model.Executive.Now.Ticks >= m_endTicks)
                {
                    m_endWaiters.ForEach(delegate(IDetachableEventController waiter) { waiter.Resume(); });
                    m_endWaiters.Clear();
                }

                m_lastFraction = thisFraction;
                m_inProcess    = false;
            }
        }
        public void TestPressureTransfer()
        {
            Tester tester = new Tester(m_brs, m_lateBound);

            tester.AddGallons("Dimethylsulfide", 10);
            tester.AddGallons("Water", 10);

            // Create a mixture with a 200,000 gallon volume.
            MaterialType mt            = m_brs.MyMaterialCatalog["Unknown"];
            Mixture      addend        = new Mixture("Addend", Guid.NewGuid());
            double       desiredVolume = 200000 * K.litersPerGallon;

            addend.AddMaterial(mt.CreateMass(desiredVolume, 35.0));
            //Console.WriteLine("There are " + (addend.Volume/K.litersPerGallon) + " gallons of " + mt.Name + " being added.");

            double controlTemperature = 35 + K.CELSIUS_TO_KELVIN;

            tester.DoPressureTransfer(addend, controlTemperature);

            Mixture emission  = tester.LastEmission;
            Mixture resultant = tester.CurrentMixture;

            string knownGood = "Mixture (40.00 deg C) of 32.1142 kg of Dimethylsulfide and 24.0567 kg of Water";

            EvaluateResults(knownGood, "Pressure Transfer", emission);
        }
Beispiel #10
0
        public void TestCombinatorics()
        {
            Model model = new Model("Test Model", Guid.NewGuid());
            BasicReactionSupporter brs = new BasicReactionSupporter();

            InitializeForTesting(brs);

            Mixture mixture = new Mixture(model, "Contents of vat 1", Guid.NewGuid());

            MaterialCatalog cat = brs.MyMaterialCatalog;

            AddSubstance(ref mixture, cat["Nitrous Acid"], 100, 20);
            AddSubstance(ref mixture, cat["Potassium Hydroxide"], 150, 41);
            AddSubstance(ref mixture, cat["Water"], 100, 100);
            Assert.IsTrue(mixture.Mass.Equals(350D), "Mass is not 350 kg");
            Assert.IsTrue(Math.Abs(mixture.Temperature - (18150D / 350D)) < 0.00001, "Temperature is not 51.86724 C.");

            IMaterial matl = mixture.RemoveMaterial(cat["Nitrous Acid"]);

            Debug.WriteLine("Removing all avaliable " + matl.MaterialType.Name);
            DiagnosticAids.DumpMaterial(mixture);
            Assert.IsTrue(mixture.Mass.Equals(250D), "Mass is not 250 kg");

            Debug.WriteLine("Adding " + matl.MaterialType.Name + " back in.");
            mixture.AddMaterial(matl);
            DiagnosticAids.DumpMaterial(mixture);
            Assert.IsTrue(mixture.Mass.Equals(350D), "Mass is not 350 kg");

            Debug.WriteLine("Removing 50 kg of the " + matl.MaterialType.Name);
            matl = mixture.RemoveMaterial(matl.MaterialType, 50.0);
            DiagnosticAids.DumpMaterial(mixture);
            Assert.IsTrue(mixture.Mass.Equals(300D), "Mass is not 300 kg");
        }
Beispiel #11
0
        public void TestReactions3()
        {
            Model model = new Model("Test Model", Guid.NewGuid());
            BasicReactionSupporter brs = new BasicReactionSupporter();

            InitializeForTesting(brs);

            MaterialType potassiumSulfateType = (MaterialType)brs.MyMaterialCatalog["Potassium Sulfate"];
            MaterialType acetoneType          = (MaterialType)brs.MyMaterialCatalog["Acetone"];
            MaterialType hexaneType           = (MaterialType)brs.MyMaterialCatalog["Hexane"];


            Reaction r1 = new Reaction(model, "Reaction 1", Guid.NewGuid());

            r1.AddReactant(potassiumSulfateType, 1.0);
            r1.AddReactant(acetoneType, 2.5);
            r1.AddProduct(hexaneType, 3.0);
            r1.AddProduct(acetoneType, 0.5);
            r1.HeatOfReaction = 0;

            brs.MyReactionProcessor.AddReaction(r1);

            Mixture m       = new Mixture(model, "Mixture");
            string  results = "";

            r1.ReactionGoingToHappenEvent += new ReactionGoingToHappenEvent(delegate(Reaction reaction, Mixture mixture) {
                results += ("\r\nBefore = " + m.ToString("F2", "F4"));
            });
            r1.ReactionHappenedEvent += new ReactionHappenedEvent(delegate(ReactionInstance reactionInstance) {
                results += ("\r\nAfter = " + m.ToString("F2", "F4") + "\r\n");
            });


            brs.MyReactionProcessor.Watch(m);

            Console.WriteLine(r1.ToString());

            m.AddMaterial(potassiumSulfateType.CreateMass(100, 37));
            m.AddMaterial(acetoneType.CreateMass(100, 37));

            Console.WriteLine(results);
            Assert.AreEqual(results, EXPECTED_3);
        }
Beispiel #12
0
        public void AddGallons(string name, double numGallons)
        {
            double       liters = K.litersPerGallon * numGallons;
            MaterialType mt     = m_brs.MyMaterialCatalog[name];
            double       kg     = liters * mt.SpecificGravity;

            m_initialMixture.AddMaterial(mt.CreateMass(kg, m_tempOfTankLiquidInitial));
            m_initialMixture.Temperature = m_initialMixtureTemperature;
            m_currentMixture             = (Mixture)m_initialMixture.Clone();
        }
Beispiel #13
0
        public void TestBoilingPoints3()
        {
            MaterialType mtSodiumChloride = new MaterialType(null, "Potassium Carbonate", Guid.NewGuid(), 2.29, 4.17, MaterialState.Solid, 44.0, 1200);

            for (double d = 1.0; d >= 0.0; d -= .2)
            {
                Substance sodiumChloride = (Substance)mtSodiumChloride.CreateMass(100, 31);
                Substance acetone        = (Substance)m_brs.MyMaterialCatalog["Acetone"].CreateMass(d * 100, 31);

                double pressure_1Atm = 101325.0; // pascals.

                Mixture m = new Mixture("BP Tester");
                m.AddMaterial(sodiumChloride);
                m.AddMaterial(acetone);

                double ebp = m.GetEstimatedBoilingPoint(pressure_1Atm);
                Console.WriteLine("BP of " + m.ToString() + " is " + ebp + ".");
            }
        }
        public void TestMassBalance()
        {
            Tester tester = new Tester(m_brs, m_lateBound);

            tester.AddGallons("Dimethylsulfide", 500);
            tester.AddGallons("Water", 100);

            Mixture desiredEmissions = new Mixture("Mass Balance desired emissions");

            desiredEmissions.AddMaterial(m_brs.MyMaterialCatalog["Water"].CreateMass(1, 37));
            desiredEmissions.AddMaterial(m_brs.MyMaterialCatalog["Dimethylsulfide"].CreateMass(5, 37));
            tester.DoMassBalance(desiredEmissions);

            Mixture emission  = tester.LastEmission;
            Mixture resultant = tester.CurrentMixture;

            string knownGood = "Mixture (37.00 deg C) of 5.0000 kg of Dimethylsulfide and 1.0000 kg of Water";

            EvaluateResults(knownGood, "Mass Balance", emission);
        }
Beispiel #15
0
        private void AddSubstance(ref Mixture mixture, MaterialType matType, double mass, double temp)
        {
            IMaterial matl   = matType.CreateMass(mass, temp);
            double    energy = (temp + Highpoint.Sage.Materials.Chemistry.Constants.CELSIUS_TO_KELVIN) * mass * matType.SpecificHeat;

            Debug.WriteLine(String.Format("Adding {0} - {1} kg, {2} C, and {3} liters. ({4} Joules of thermal energy)", matl.MaterialType.Name, matl.Mass, matl.Temperature, matl.Volume, energy));
            mixture.AddMaterial(matl);

            Debug.WriteLine("Mixture is now:");
            DiagnosticAids.DumpMaterial(mixture);
        }
Beispiel #16
0
        public void TestVaporSpaceMixtureHandling()
        {
            Model model = new Model("Hello, world.", Guid.NewGuid());
            BasicReactionSupporter brs = new BasicReactionSupporter();

            LoadSampleCatalog(brs.MyMaterialCatalog);

            Mixture mixture = new Mixture(model, "VaporTester", Guid.NewGuid());

            mixture.AddMaterial(brs.MyMaterialCatalog["Methanol"].CreateMass(200, 37));
            mixture.AddMaterial(brs.MyMaterialCatalog["Methylene Chloride"].CreateMass(200, 37));
            mixture.AddMaterial(brs.MyMaterialCatalog["Water"].CreateMass(200, 37));

            double T = 315;
            double V = 2.0;

            Console.WriteLine("Starting with " + mixture + " and estimating vapor at " + T + " degrees C in a " + V + " cubic meter space.");
            Mixture vs = mixture.GetVaporFor(V, T);

            Console.WriteLine(vs.ToString());
        }
Beispiel #17
0
        public void TestReactions2()
        {
            Model model = new Model("Test Model", Guid.NewGuid());
            BasicReactionSupporter brs = new BasicReactionSupporter();

            InitializeForTesting(brs);

            MaterialType waterType   = (MaterialType)brs.MyMaterialCatalog["Water"];
            MaterialType ethanolType = (MaterialType)brs.MyMaterialCatalog["Ethanol"];

            Reaction r1 = new Reaction(model, "Reaction 1", Guid.NewGuid());

            r1.AddReactant(brs.MyMaterialCatalog["Water"], 2.0);
            r1.AddProduct(brs.MyMaterialCatalog["Ethanol"], 2.0);
            r1.HeatOfReaction = 0;
            brs.MyReactionProcessor.AddReaction(r1);

            string  actualResults = "";
            Mixture m             = new Mixture(model, "Mixture");

            r1.ReactionGoingToHappenEvent += new ReactionGoingToHappenEvent(delegate(Reaction reaction, Mixture mixture) {
                actualResults += ("\r\nBefore = " + m.ToString("F2", "F4"));
            });
            r1.ReactionHappenedEvent += new ReactionHappenedEvent(delegate(ReactionInstance reactionInstance) {
                actualResults += ("\r\nAfter = " + m.ToString("F2", "F4") + "\r\n");
            });

            brs.MyReactionProcessor.Watch(m);

            m.AddMaterial(waterType.CreateMass(100, 37));

            m.AddMaterial(waterType.CreateMass(10, 37));

            Console.WriteLine(actualResults);
            string expected =
                "\r\nBefore = Mixture (37.00 deg C) of 100.0000 kg of Water\r\nAfter = Mixture (37.00 deg C) of 100.0000 kg of Ethanol\r\n\r\nBefore = Mixture (37.00 deg C) of 100.0000 kg of Ethanol and 10.0000 kg of Water\r\nAfter = Mixture (37.00 deg C) of 110.0000 kg of Ethanol\r\n";

            Assert.AreEqual(expected, actualResults);
        }
Beispiel #18
0
        public void TestMixtureBoilingPointAntoines()
        {
            Model        model    = new Model("Test Model", Guid.NewGuid());
            MaterialType methanol = new MaterialType(null, "Methanol", Guid.NewGuid(), 0.7920, 4.1800, MaterialState.Liquid, 32);
            MaterialType water    = new MaterialType(null, "Water", Guid.NewGuid(), 1.0000, 4.1800, MaterialState.Liquid);

            methanol.SetAntoinesCoefficients3(7.879, 1473.1, 230, PressureUnits.mmHg, TemperatureUnits.Celsius);
            water.SetAntoinesCoefficients3(8.040, 1715.1, 232.4, PressureUnits.mmHg, TemperatureUnits.Celsius);

            Console.WriteLine("Materials are specified as percent-by-mass. Pressure is 1 ATM.");
            Console.WriteLine("Water, Methanol, BoilingPoint");
            for (double d = 0; d <= 100.0; d += 5.0)
            {
                Mixture m = new Mixture();
                m.AddMaterial(water.CreateMass(d, 273));
                m.AddMaterial(methanol.CreateMass(100.0 - d, 273));
                double bp = VaporPressure.VaporPressureCalculator.ComputeBoilingPoint(m, 101325);

                Debug.Assert(bp > 64 && bp < 101);
                Console.WriteLine("{0},{1},{2}", d, 100.0 - d, bp);
            }
        }
        /// <summary>
        /// Exercises an MVTTracker.
        /// </summary>
        [TestMethod] public void TestMVTTracker()
        {
            Highpoint.Sage.SimCore.Model model = new Highpoint.Sage.SimCore.Model("MVTTracker model");
            BasicReactionSupporter       brs   = new BasicReactionSupporter();

            InitializeForTesting(brs);

            Mixture current = new Mixture(model, "current", Guid.NewGuid());

            current.AddMaterial(brs.MyMaterialCatalog["Water"].CreateMass(150, 30));
            current.AddMaterial(brs.MyMaterialCatalog["Aluminum Hydroxide"].CreateMass(200, 35));

            Mixture inflow = new Mixture(model, "inflow", Guid.NewGuid());

            inflow.AddMaterial(brs.MyMaterialCatalog["Acetone"].CreateMass(1500, 70));
            inflow.AddMaterial(brs.MyMaterialCatalog["Hexane"].CreateMass(2000, 90));

            Mixture outflow = new Mixture(model, "inflow", Guid.NewGuid());

            outflow.AddMaterial(brs.MyMaterialCatalog["Acetone"].CreateMass(1400, 17));
            outflow.AddMaterial(brs.MyMaterialCatalog["Hexane"].CreateMass(1900, 17));
            outflow.AddMaterial(brs.MyMaterialCatalog["Aluminum Hydroxide"].CreateMass(200, 17));

            MassVolumeTracker cmvt = new MassVolumeTracker(brs.MyReactionProcessor);

            cmvt.SetInitialMixture(current);
            cmvt.SetInflowMixture(inflow);
            cmvt.SetOutflowMixture(outflow);
            cmvt.SetVesselCapacity(1000);

            cmvt.Process();

            //_Debug.WriteLine("Temperatures: " + cmvt.TemperatureHistory.ToString());
            _Debug.WriteLine("Masses      : " + cmvt.MassHistory.ToString());
            _Debug.WriteLine("Volumes     : " + cmvt.VolumeHistory.ToString());
        }
Beispiel #20
0
        public bool CombineMaterials(IMaterial[] materialsToCombine, out IMaterial result, out ArrayList observedReactions, out ArrayList observedReactionInstances)
        {
            Mixture scratch = new Mixture(null, "scratch mixture");

            Watch(scratch);
            ReactionCollector rc = new ReactionCollector(scratch);

            foreach (IMaterial material in materialsToCombine)
            {
                scratch.AddMaterial(material);
            }
            observedReactions         = rc.Reactions;
            observedReactionInstances = rc.ReactionInstances;
            rc.Disconnect();
            result = scratch;
            return(observedReactions != null && observedReactions.Count > 0);
        }
Beispiel #21
0
        /// <summary>
        /// Reacts in the specified mix.
        /// </summary>
        /// <param name="mix">The mixture in which the reaction is to take place.</param>
        /// <param name="from">The <see cref="Highpoint.Sage.Materials.Chemistry.Reaction.ReactionParticipant"/>s that are eliminated.</param>
        /// <param name="to">The <see cref="Highpoint.Sage.Materials.Chemistry.Reaction.ReactionParticipant"/>s that are created.</param>
        /// <param name="scale">The scale of the reaction.</param>
        protected void React(Mixture mix, ArrayList from, ArrayList to, double scale)
        {
            foreach (ReactionParticipant rp in from)
            {
                if (s_diagnostics)
                {
                    _Debug.WriteLine("Eliminating " + (rp.Mass * scale) + " of " + rp.MaterialType.Name + " from mixture.");
                }
                mix.RemoveMaterial(rp.MaterialType, rp.Mass * scale);
            }

            foreach (ReactionParticipant rp in to)
            {
                if (s_diagnostics)
                {
                    _Debug.WriteLine("Adding " + (rp.Mass * scale) + " of " + rp.MaterialType.Name + " to mixture.");
                }
                mix.AddMaterial(rp.MaterialType.CreateMass(rp.Mass * scale, mix.Temperature));
            }
        }
Beispiel #22
0
            public void Run(IExecutive exec, object userData)
            {
                Dump("At start, ", exec);
                IDictionary graphContext = (IDictionary)userData;

                object transferInKey  = m_source.Setup(m_getThis.CreateMass(m_getHowMuch, 17.0), 25.0, Input, true);
                object transferOutKey = m_sink.Setup(m_sendThat.CreateMass(m_sendHowMuch, 17.0), 40.0, Output, true);

                Dump("After setup, ", exec);

                m_source.Execute(graphContext, transferInKey);
                MaterialTransfer mtSrc = (MaterialTransfer)m_source.GetTransferTable(graphContext)[Input.Connector];

                foreach (IMaterial imat in mtSrc.Mixture.Constituents)
                {
                    m_mixture.AddMaterial(imat);
                }

                Dump("After source executes, ", exec);

                Mixture          export = (Mixture)m_mixture.RemoveMaterial(m_sendHowMuch);
                MaterialTransfer mtSnk  = new MaterialTransfer(export, TimeSpan.FromMinutes(m_sendHowMuch / 40.0));

                m_sink.GetTransferTable(graphContext).Add(Output.Connector, mtSnk);
                m_sink.Execute(graphContext, transferOutKey);

                Dump("After sink executes, ", exec);

                exec.CurrentEventController.SuspendFor(
                    TimeSpanOperations.Max(
                        TimeSpanOperations.Max(mtSrc.SourceDuration, mtSrc.DestinationDuration),
                        TimeSpanOperations.Max(mtSnk.SourceDuration, mtSnk.DestinationDuration)
                        ));

                m_source.Teardown(transferInKey, true);
                m_sink.Teardown(transferOutKey, true);

                Dump("After teardown, ", exec);
            }
Beispiel #23
0
        public void TestChangeNotifications()
        {
            Model model = new Model("Test Model", Guid.NewGuid());
            BasicReactionSupporter brs = new BasicReactionSupporter();

            InitializeForTesting(brs);

            MaterialType waterType = (MaterialType)brs.MyMaterialCatalog["Water"];

            string    results = string.Empty;
            Substance w1      = (Substance)waterType.CreateMass(100, 37);

            w1.MaterialChanged += new MaterialChangeListener(delegate(IMaterial material, MaterialChangeType type) {
                results += string.Format("{0} changed in {1}\r\n", material, type);
            });

            w1.Temperature = 85.0;
            w1.Add((Substance)waterType.CreateMass(100, 37));
            Assert.IsTrue(results.Equals(RESULT1));

            results = string.Empty;
            w1.SuspendChangeEvents();
            w1.Temperature = 95.0;
            w1.Add((Substance)waterType.CreateMass(100, 37));
            w1.ResumeChangeEvents(false);
            Assert.IsTrue(results.Equals(string.Empty));

            results = string.Empty;
            w1.SuspendChangeEvents();
            w1.Temperature = 95.0;
            w1.Add((Substance)waterType.CreateMass(100, 37));
            w1.ResumeChangeEvents(true);
            Assert.IsTrue(results.Equals(RESULT2));

            // NOW, SAME TEST, BUT ON A MIXTURE INSTEAD.
            MaterialType acetoneType = (MaterialType)brs.MyMaterialCatalog["Acetone"];

            Mixture m1 = new Mixture("My Goo");

            m1.MaterialChanged += new MaterialChangeListener(delegate(IMaterial material, MaterialChangeType type) {
                results += string.Format("{0} changed in {1}\r\n", material, type);
            });

            results = string.Empty;
            m1.AddMaterial((Substance)waterType.CreateMass(100, 37));
            m1.AddMaterial((Substance)acetoneType.CreateMass(100, 45));
            Assert.IsTrue(results.Equals(RESULT3));

            results = string.Empty;
            m1.SuspendChangeEvents();
            m1.AddMaterial((Substance)waterType.CreateMass(100, 99));
            m1.AddMaterial((Substance)acetoneType.CreateMass(100, 99));
            Assert.IsTrue(results.Equals(string.Empty));
            m1.ResumeChangeEvents(false);
            Assert.IsTrue(results.Equals(string.Empty));

            results = string.Empty;
            m1.SuspendChangeEvents();
            m1.AddMaterial((Substance)waterType.CreateMass(100, 99));
            m1.AddMaterial((Substance)acetoneType.CreateMass(100, 99));
            Assert.IsTrue(results.Equals(string.Empty));
            m1.ResumeChangeEvents(true);
            Assert.IsTrue(results.Equals(RESULT4));
        }
        public void TestMultiMaterialFill()
        {
            Tester tester = new Tester(m_brs, m_lateBound);

            XmlDocument doc = new XmlDocument();

            doc.LoadXml(
                @"<Initial><Material name=""Acetic Acid"" quantity=""0.667469348137951"" />
  <Material name=""Acetone"" quantity=""0.701595088793707"" />
  <Material name=""Acetonitrile"" quantity=""7.74765135149828"" /> 
  <Material name=""Avermectin Oils1"" quantity=""5.11139268759237"" /> 
  <Material name=""Butanol"" quantity=""7.97490558492714"" /> 
  <Material name=""n-Butyl Acetate"" quantity=""8.27308291023275"" /> 
  <Material name=""t-Butyldimethyl Silanol1"" quantity=""1.65958795308116"" /> 
  <Material name=""Cyclohexane"" quantity=""7.36130623489679"" /> 
  <Material name=""Dimethylaminopyridine1"" quantity=""2.6021636475819"" /> 
  <Material name=""Dimethylformamide"" quantity=""5.06004851081411"" />
  <Material name=""Dimethylsulfate"" quantity=""2.30273722312541"" /> 
  <Material name=""Dimethylsulfide"" quantity=""3.87140443263175"" /> 
  <Material name=""Dimethylsulfoxide"" quantity=""2.15980615101746"" /> 
  <Material name=""Dodecylbenzylsulfonic Acid1"" quantity=""0.208108848989061"" /> 
  <Material name=""Ethanol"" quantity=""1.34833602297508"" /> 
  <Material name=""Ethyl Acetate"" quantity=""7.40831733560577"" /> 
  <Material name=""Ethyl Ether"" quantity=""1.95091067904183"" /> 
  <Material name=""n-Ethyl Pyrolidone (NEP)"" quantity=""8.87039565894306"" /> 
  <Material name=""Ethyl-7-Chloro-2-Oxoheptanate1"" quantity=""8.61100613540551"" /> 
  <Material name=""Heptane"" quantity=""3.58865063804605"" /> 
  <Material name=""Hexane"" quantity=""1.03702260229598"" />
  <Material name=""Isoamyl Alcohol"" quantity=""5.29583051581673"" /> 
  <Material name=""Isopropanol"" quantity=""3.58755016866492"" /> 
  <Material name=""Isopropyl Acetate"" quantity=""7.07505481181436"" /> 
  <Material name=""Methane Sulfonic Acid"" quantity=""5.80474831899849"" /> 
  <Material name=""Methanol"" quantity=""6.20548322620126"" /> 
  <Material name=""Methyl Acetate"" quantity=""7.32496631672837"" /> 
  <Material name=""Methyl Ethyl Ketone"" quantity=""7.47882739989032"" /> 
  <Material name=""Methylene Chloride"" quantity=""3.96251060718787"" /> 
  <Material name=""Phenyl Phosphate1"" quantity=""2.45257239902978"" /> 
  <Material name=""n-Propanol"" quantity=""6.86345072317098"" /> 
  <Material name=""Tetrahydrofuran"" quantity=""2.10546193742448"" /> 
  <Material name=""Toluene"" quantity=""5.17537586631969"" /> 
  <Material name=""Triethylamine"" quantity=""4.85390965121515"" /> 
  <Material name=""Hydrazine"" quantity=""2.52805452911558"" /> 
  <Material name=""Chloroform"" quantity=""7.70778849148554"" /> 
  <Material name=""Pyrrolidine"" quantity=""0.0257893931240725"" /> 
  <Material name=""MTBE"" quantity=""4.83912114279304"" /> 
  <Material name=""Water"" quantity=""4.4795790335534"" />
  </Initial>");

            foreach (XmlNode node in doc.SelectNodes("/Initial/Material"))
            {
                tester.AddGallons(node.Attributes["name"].InnerText, double.Parse(node.Attributes["quantity"].InnerText));
            }

            // Create a mixture with a 200,000 gallon volume.
            MaterialType mt            = m_brs.MyMaterialCatalog["Unknown"];
            Mixture      addend        = new Mixture("Addend", Guid.NewGuid());
            double       desiredVolume = 53990 * K.litersPerGallon;

            addend.AddMaterial(mt.CreateMass(desiredVolume, 35.0));
            //Console.WriteLine("There are " + (addend.Volume/K.litersPerGallon) + " gallons of " + mt.Name + " being added.");

            double controlTemperature = 19.7292085 + K.CELSIUS_TO_KELVIN;

            tester.DoFill(addend, controlTemperature);

            Mixture emission  = tester.LastEmission;
            Mixture resultant = tester.CurrentMixture;

            string knownGood = "Mixture (40.00 deg C) of 8.8577 kg of Chloroform, 8.8237 kg of Methylene Chloride, 6.6420 kg of Dimethylsulfide, 5.6593 kg of Methyl Acetate, 2.9698 kg of Ethyl Ether, 2.4233 kg of Ethyl Acetate, 2.3301 kg of Methanol, 2.1779 kg of Cyclohexane, 2.1184 kg of Acetonitrile, 2.0769 kg of Methyl Ethyl Ketone, 1.9382 kg of MTBE, 1.4243 kg of Isopropyl Acetate, 1.3159 kg of Tetrahydrofuran, 0.6678 kg of Triethylamine, 0.5016 kg of Acetone, 0.4785 kg of Toluene, 0.4370 kg of Isopropanol, 0.4052 kg of Hexane, 0.3934 kg of n-Propanol, 0.3838 kg of Water, 0.3808 kg of Heptane, 0.2876 kg of n-Butyl Acetate, 0.2262 kg of Ethanol, 0.1583 kg of Butanol, 0.1309 kg of Hydrazine, 0.0645 kg of Dimethylformamide, 0.0475 kg of Isoamyl Alcohol, 0.0386 kg of Acetic Acid, 0.0087 kg of Ethyl-7-Chloro-2-Oxoheptanate1, 0.0055 kg of Dimethylsulfoxide, 0.0051 kg of Avermectin Oils1, 0.0051 kg of Pyrrolidine, 0.0050 kg of n-Ethyl Pyrolidone (NEP), 0.0047 kg of Dimethylsulfate, 0.0026 kg of Dimethylaminopyridine1, 0.0025 kg of Phenyl Phosphate1, 0.0017 kg of t-Butyldimethyl Silanol1, 0.0002 kg of Dodecylbenzylsulfonic Acid1 and 0.0000 kg of Methane Sulfonic Acid";

            EvaluateResults(knownGood, "Fill", emission);
        }
 public void Reset(double mH2O, double mNANO2)
 {
     m_mixture.Clear();
     m_mixture.AddMaterial(m_brs.MyMaterialCatalog["Water"].CreateMass(mH2O, 20));            // Add 250 kg.
     m_mixture.AddMaterial(m_brs.MyMaterialCatalog["Sodium Nitrite"].CreateMass(mNANO2, 20)); // Add 100 kg NaNO2.
 }
Beispiel #26
0
        /// <summary>
        /// Performs the inflow/outflow cycle analysis. After this runs, consult the Mass, Volume and Temperature history members.
        /// </summary>
        public void Process()
        {
            m_massHistory.Reset();
            m_volumeHistory.Reset();

            Mixture contents = (Mixture)m_initial.Clone();

            if (m_reactionProcessor != null)
            {
                m_reactionProcessor.Watch(contents);
            }

            Mixture inflow  = m_inflow == null?new Mixture():(Mixture)m_inflow.Clone();
            Mixture outflow = m_outflow == null ? new Mixture() : (Mixture)m_outflow.Clone();

            double tiv = inflow.Volume;
            double tim = inflow.Mass;
            double tov = outflow.Volume;
            double tom = outflow.Mass;

            bool useMinidumps = true;

            //bool useMinidumps = false;
            //if ( ( tiv + contents.Volume - tov > m_capacity ) ) useMinidumps = true;

            RecordMvt(contents);
            if (m_cyclical)
            {
                if (m_inflowFirst)
                {
                    if (s_diagnostics)
                    {
                        Console.WriteLine("Initial - total volume = " + contents.Volume + ", mixture is " + contents);
                    }
                    while (inflow.Mass > 0.0 || outflow.Mass > 0.0)
                    {
                        // Perform charge
                        if (inflow.Mass > 0.0)
                        {
                            double chgMass     = Math.Min((m_capacity - contents.Volume) * (tim / tiv), inflow.Mass);
                            double pctOfInFlow = chgMass / inflow.Mass;
                            contents.AddMaterial(inflow.RemoveMaterial(chgMass));
                            if (s_diagnostics)
                            {
                                Console.WriteLine("After charge - total volume = " + contents.Volume + ", mixture is " + contents);
                            }
                            RecordMvt(contents);
                        }

                        // Perform discharge
                        if (outflow.Mass > 0.0)
                        {
                            double  dischgMass = Math.Min((m_capacity - contents.Volume) * (tom / tov), outflow.Mass);
                            Mixture extract    = (Mixture)outflow.RemoveMaterial(dischgMass);
                            foreach (Substance substance in extract.Constituents)
                            {
                                contents.RemoveMaterial(substance.MaterialType, extract.Mass);
                            }
                            if (s_diagnostics)
                            {
                                Console.WriteLine("After discharge - total volume = " + contents.Volume + ", mixture is " + contents);
                            }
                            RecordMvt(contents);
                        }

                        if (useMinidumps)
                        {
                            contents.Clear();
                        }
                    }
                }
                else
                {
                    throw new NotImplementedException("Only able to model inflow-first, cyclical behavior.");
                }
            }
            else
            {
                throw new NotImplementedException("Only able to model inflow-first, cyclical behavior.");
            }
            if (m_reactionProcessor != null)
            {
                m_reactionProcessor.Ignore(contents);
            }
        }
Beispiel #27
0
        public void DoAirDry(Hashtable materialGuidToVolumeFraction, double massOfDriedProductCake, double controlTemperature)
        {
            Console.WriteLine("Air Dry Testing" + (m_lateBound?", late bound.":", early bound."));
            Console.WriteLine("Mixture is      : " + m_currentMixture.ToString());
            if (m_lateBound)
            {
                Hashtable paramTable = new Hashtable();
                string    modelKey   = "Air Dry";
                paramTable.Add(PN.MaterialGuidToVolumeFraction, materialGuidToVolumeFraction);
                paramTable.Add(PN.MassOfDriedProductCake_Kg, massOfDriedProductCake);
                paramTable.Add(PN.ControlTemperature_K, controlTemperature);
                EmissionsService.Instance.ProcessEmissions(m_currentMixture, out m_currentMixture, out m_lastEmission, true, modelKey, paramTable);
            }
            else
            {
                new Highpoint.Sage.Materials.Chemistry.Emissions.AirDryModel().AirDry(m_currentMixture, out m_currentMixture, out m_lastEmission, true, massOfDriedProductCake, controlTemperature, materialGuidToVolumeFraction);
            }
            Console.WriteLine("Mixture becomes : " + m_currentMixture.ToString());
            Console.WriteLine("Emissions are   : " + m_lastEmission.ToString("F1", "F4"));

            m_aggregateEmissions.AddMaterial(m_lastEmission);
        }
Beispiel #28
0
        public void TestReactionBasics()
        {
            BasicReactionSupporter brs = new BasicReactionSupporter();

            Initialize(brs);

            Mixture mixture = new Mixture(null, "test mixture");

            mixture.OnReactionHappened += new ReactionHappenedEvent(mixture_OnReactionHappened);

            brs.MyReactionProcessor.Watch(mixture);
            mixture.AddMaterial(brs.MyMaterialCatalog["Hydrochloric Acid"].CreateMass(10, 20));
            mixture.AddMaterial(brs.MyMaterialCatalog["Caustic Soda"].CreateMass(12, 44));


            foreach (IMaterial constituent in mixture.Constituents)
            {
                _Debug.WriteLine(constituent.ToString());
            }

            /* Calculation mass:
             * 0.5231 + 0.4769 = 0.2356 + 0.7644
             * 100 % Ractions = min(10 kg / 0.4769, 12 kg / 0.5231)	= about  20.97
             * --> Left over Caustic Soda = 12 kg - (20.97 * 0.5231)= about   1.03 kg
             *     Water = 20.97 * 0.2356							= about   4.94 kg
             *     Sodium Cloride = 20.97 * 0.7644					= about  16.03 kg
             *														=		 22.00 kg
             * Calculation temperature:
             * Hydrochloric Acid specific heat = 4.18
             * Caustic Soda specific heat = 2.55
             * Heat of Hydrochloric Acid is 10 kg * 2.55 * 20 dC	= about  510.00 dC
             * Heat of Caustic Soda is 12 kg * 4.18 * 44 dC			= about 2207.04 dC
             * Subtotal												= about 2717.04 dC
             * Divide by 10 * 2.55 + 12 * 4.18						= 75.66
             * Mixture temperature is 2717.04 / 75.66				= about   35.91 dC
             */

            Substance water  = null;
            Substance sodium = null;
            Substance soda   = null;

            foreach (Substance s in mixture.Constituents)
            {
                switch (s.Name)
                {
                case "Water":
                    water = s;
                    break;

                case "Sodium Chloride":
                    sodium = s;
                    break;

                case "Caustic Soda":
                    soda = s;
                    break;
                }
            }

            _Debug.Assert(Math.Abs(soda.Mass - 1.03) < 0.01, "The Caustic Soda part is not 2.88 kg");
            _Debug.Assert(Math.Abs(water.Mass - 4.94) < 0.01, "The Water part is not 4.5 kg");
            _Debug.Assert(Math.Abs(sodium.Mass - 16.03) < 0.01, "The Sodium Cloride part is not 14.61 kg");
            Console.WriteLine(mixture.Temperature);
            _Debug.Assert(Math.Abs(mixture.Temperature - 35.91) < 0.01, "The temperature is not 33.09 degrees C");
        }
Beispiel #29
0
        public void TestCatalyticReactionBasics()
        {
            BasicReactionSupporter brs = new BasicReactionSupporter();

            Initialize(brs);

            int     nReactions = 0;
            Mixture mixture    = new Mixture(null, "test mixture");

            mixture.OnReactionHappened += new ReactionHappenedEvent(mixture_OnReactionHappened);
            mixture.OnReactionHappened += new ReactionHappenedEvent(delegate(ReactionInstance r) { nReactions++; });

            brs.MyReactionProcessor.Watch(mixture);
            mixture.AddMaterial(brs.MyMaterialCatalog["Hydrogen"].CreateMass(10, 20));
            mixture.AddMaterial(brs.MyMaterialCatalog["Oil"].CreateMass(12, 44));


            foreach (IMaterial constituent in mixture.Constituents)
            {
                _Debug.WriteLine(constituent.ToString());
            }

            mixture.AddMaterial(brs.MyMaterialCatalog["Palladium"].CreateMass(1, 44));

            foreach (IMaterial constituent in mixture.Constituents)
            {
                _Debug.WriteLine(constituent.ToString());
            }

            _Debug.Assert(nReactions == 1, String.Format("Reaction occurred {0} times, but should have happened once.", nReactions));
            if (nReactions != 1)
            {
                Console.WriteLine("Test failed. Catalytic reaction happened {0} times, but should only have happened once.", nReactions);
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    System.Diagnostics.Debugger.Break();
                }
            }

            // Now check that a reaction without the catalyst does not happen.
            nReactions = 0;
            mixture    = new Mixture(null, "test mixture");
            mixture.OnReactionHappened += new ReactionHappenedEvent(mixture_OnReactionHappened);
            mixture.OnReactionHappened += new ReactionHappenedEvent(delegate(ReactionInstance r) { nReactions++; });

            brs.MyReactionProcessor.Watch(mixture);
            mixture.AddMaterial(brs.MyMaterialCatalog["Hydrogen"].CreateMass(10, 20));
            mixture.AddMaterial(brs.MyMaterialCatalog["Oil"].CreateMass(12, 44));


            foreach (IMaterial constituent in mixture.Constituents)
            {
                _Debug.WriteLine(constituent.ToString());
            }

            foreach (IMaterial constituent in mixture.Constituents)
            {
                _Debug.WriteLine(constituent.ToString());
            }

            _Debug.Assert(nReactions == 0, String.Format("Reaction occurred {0} times, but should not have happened.", nReactions));
            if (nReactions != 0)
            {
                Console.WriteLine("Test failed. Catalytic reaction happened {0} times, but should not have happened.", nReactions);
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    System.Diagnostics.Debugger.Break();
                }
            }
        }
Beispiel #30
0
        public void TestMaterialTransferrer()
        {
            #region Create and initialize the model
            Model model = new Model("Test Model", Guid.NewGuid());
            BasicReactionSupporter brs = new BasicReactionSupporter();
            InitializeForTesting(brs);
            #endregion Create and initialize the model

            #region Create handles to material types
            MaterialType potassiumSulfateType = (MaterialType)brs.MyMaterialCatalog["Potassium Sulfate"];
            MaterialType acetoneType          = (MaterialType)brs.MyMaterialCatalog["Acetone"];
            MaterialType hexaneType           = (MaterialType)brs.MyMaterialCatalog["Hexane"];
            MaterialType waterType            = (MaterialType)brs.MyMaterialCatalog["Water"];
            #endregion Create handles to material types

            #region Create the source mixture
            Mixture from = new Mixture("From");
            from.AddMaterial(potassiumSulfateType.CreateMass(100, 37));
            from.AddMaterial(acetoneType.CreateMass(100, 37));
            from.AddMaterial(hexaneType.CreateMass(100, 37));
            #endregion Create the source mixture

            #region Create the destination mixture
            Mixture to = new Mixture("To");
            to.AddMaterial(waterType.CreateMass(55, 50));
            #endregion Create the destination mixture

            #region Create the mixture that will act as the exemplar
            Mixture what = new Mixture("What");
            what.AddMaterial(potassiumSulfateType.CreateMass(25, 37));
            what.AddMaterial(acetoneType.CreateMass(35, 37));
            what.AddMaterial(hexaneType.CreateMass(45, 37));
            #endregion Create the mixture that will act as the exemplar

            TimeSpan            duration = TimeSpan.FromHours(2.0);
            MaterialTransferrer mxfr     = new MaterialTransferrer(model, ref from, ref to, what, duration);

            // Create the start event for the transfer.
            DateTime startAt = new DateTime(2009, 2, 23, 3, 0, 0);
            model.Executive.RequestEvent(delegate(IExecutive exec, object userData) { mxfr.Start(); }, startAt, 0.0, null);

            // Create a pause-til-start event.
            model.Executive.RequestEvent(delegate(IExecutive exec, object userData) {
                Console.WriteLine("Waiting for start.");
                mxfr.BlockTilStart();
                Console.WriteLine("Start has occurred!");
            }, startAt - TimeSpan.FromHours(2.0), 0.0, null, ExecEventType.Detachable);

            // Create a pause-til-done event.
            model.Executive.RequestEvent(delegate(IExecutive exec, object userData) {
                Console.WriteLine("Waiting for finish.");
                mxfr.BlockTilDone();
                Console.WriteLine("Finish has occurred!");
            }, startAt - TimeSpan.FromHours(2.0), 0.0, null, ExecEventType.Detachable);


            // Create a series of (unrelated) events that will force updates during the transfer.
            DateTime update = startAt;
            while (update <= (startAt + duration))
            {
                model.Executive.RequestEvent(delegate(IExecutive exec, object userData) { Console.WriteLine("{2} : From = {0}\r\nTo = {1}", from, to, exec.Now); }, update, 0.0, null);
                update += TimeSpan.FromMinutes(20.0);
            }

            model.Start();
        }