예제 #1
0
파일: Substance.cs 프로젝트: sjvannTMU/Sage
        /// <summary>
        /// Applies the material specs.
        /// </summary>
        /// <param name="emitted">The emitted.</param>
        /// <param name="original">The original.</param>
        public static void ApplyMaterialSpecs(Substance emitted, Substance original)
        {
            _Debug.Assert(emitted.MaterialType.Equals(original.MaterialType));

            ArrayList emittedSpecs = new ArrayList();

            foreach (DictionaryEntry de in original.GetMaterialSpecs())
            {
                Guid   specGuid = (Guid)de.Key;
                double specMass = (double)de.Value;
                double origPctg = specMass / original.Mass;

                double emittedMass = emitted.Mass * origPctg;

                emittedSpecs.Add(new DictionaryEntry(specGuid, emittedMass));
            }
            emitted.SetMaterialSpecs(emittedSpecs);
        }
예제 #2
0
파일: Substance.cs 프로젝트: sjvannTMU/Sage
            /// <summary>
            /// Loads the contents of this Memento into the provided object.
            /// </summary>
            /// <param name="ism">The object to receive the contents of the memento.</param>
            public void Load(ISupportsMementos ism)
            {
                Substance substance = (Substance)ism;

                substance.m_mass      = m_mass;
                substance.Temperature = m_temperature;
                substance.m_type      = m_materialType;

                if (m_matlSpecs != null)
                {
                    substance.SetMaterialSpecs(m_matlSpecs);
                }
                else
                {
                    substance.ClearMaterialSpecs();
                }

                OnLoadCompleted?.Invoke(this);
            }
예제 #3
0
파일: Substance.cs 프로젝트: sjvannTMU/Sage
        /// <summary>
        /// Removes the specified substance from this substance. Both substances must be of the same material type, or an exception will fire..
        /// </summary>
        /// <param name="substance">The substance.</param>
        /// <returns>Substance.</returns>
        /// <exception cref="ApplicationException">Fired if the substances are not of the same material type.</exception>
        /// <exception cref="WriteProtectionViolationException">Fired if there is a write lock on the substance.</exception>
        public virtual Substance Remove(Substance substance)
        {
            if (!m_type.Equals(substance.m_type))
            {
                throw new ApplicationException("Substance " + Name + " being removed from substance " + substance.Name + "!");
            }
            if (!m_writeLock.IsWritable)
            {
                throw new WriteProtectionViolationException(this, m_writeLock);
            }
            // Trace.Write("Removing " + substance.Mass + " kg of " + substance.Name + " from an existing " + m_mass + " kg, ");
            // TODO: Assert we are not removing more than is there.
            double    mass = Math.Min(substance.Mass, m_mass);
            Substance s    = Remove(mass);

            // _Debug.WriteLine("leaving " + m_mass + " kg.");
            m_ssh.ReportChange();
            MaterialChanged?.Invoke(this, MaterialChangeType.Contents);
            return(s);
        }
예제 #4
0
파일: Substance.cs 프로젝트: sjvannTMU/Sage
        /// <summary>
        /// Ascertains equality between this one and the other one.
        /// </summary>
        /// <param name="otherOne">The other one.</param>
        /// <returns><c>true</c> if this one and the other one are equal, <c>false</c> otherwise.</returns>
        public bool Equals(ISupportsMementos otherOne)
        {
            Substance otherSubstance = otherOne as Substance;

            if (otherSubstance == null)
            {
                return(false);
            }
            if (m_materialSpecs != null && otherSubstance.m_materialSpecs == null)
            {
                return(false);
            }
            if (m_materialSpecs == null && otherSubstance.m_materialSpecs != null)
            {
                return(false);
            }
            if (m_materialSpecs != null)
            {
                if (otherSubstance.m_materialSpecs != null && m_materialSpecs.Count != otherSubstance.m_materialSpecs.Count)
                {
                    return(false);
                }
                foreach (DictionaryEntry de in m_materialSpecs)
                {
                    if (otherSubstance.m_materialSpecs != null && !otherSubstance.m_materialSpecs.Contains(de.Key))
                    {
                        return(false);
                    }
                    if (otherSubstance.m_materialSpecs != null && !de.Value.Equals(otherSubstance.m_materialSpecs[de.Key]))
                    {
                        return(false);
                    }
                }
            }
            else if (otherSubstance.m_materialSpecs != null)
            {
                return(false);
            }

            return(m_mass.Equals(otherSubstance.m_mass) && Temp.Equals(otherSubstance.Temp) && m_type.Equals(otherSubstance.m_type));
        }
예제 #5
0
        public void TestRemovalByPercentageFromSubstance()
        {
            Model model = new Model("Hello, world.", Guid.NewGuid());
            BasicReactionSupporter brs = new BasicReactionSupporter();

            LoadSampleCatalog(brs.MyMaterialCatalog);

            Debug.WriteLine("\r\nWe now work on a substance.");
            MaterialType mt = brs.MyMaterialCatalog["Hydrochloric Acid"];
            Substance    s  = (Substance)mt.CreateMass(100, 20);

            Debug.WriteLine("We have " + s);

            MaterialTransferSpecByPercentage tsbp = new MaterialTransferSpecByPercentage(brs.MyMaterialCatalog["Hydrochloric Acid"], .75, TimeSpan.FromMinutes(5));

            IMaterial removee = tsbp.GetExtract(s);

            Debug.WriteLine("Want to remove " + tsbp);
            Debug.WriteLine("Successful in removing " + removee + ".\r\nWhat remains is ");
            Debug.WriteLine(s);

            Assert.IsTrue(Math.Abs(s.Mass - 25.00) < 0.01, "The Water part is not 25 kg");
            Assert.IsTrue(tsbp.Duration.Hours == 6 && tsbp.Duration.Minutes == 15, "Removing 75% Water part did not take 5 Min");
        }
예제 #6
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));
        }
예제 #7
0
        public void TestRemovalByPercentageFromMixture()
        {
            Model model = new Model("Hello, world.", Guid.NewGuid());
            BasicReactionSupporter brs = new BasicReactionSupporter();

            LoadSampleCatalog(brs.MyMaterialCatalog);

            // Define reactions
            Reaction r = new Reaction(null, "Reaction", Guid.NewGuid());

            r.AddReactant(brs.MyMaterialCatalog["Caustic Soda"], 0.5231);
            r.AddReactant(brs.MyMaterialCatalog["Hydrochloric Acid"], 0.4769);
            r.AddProduct(brs.MyMaterialCatalog["Water"], 0.2356);
            r.AddProduct(brs.MyMaterialCatalog["Sodium Chloride"], 0.7644);
            brs.MyReactionProcessor.AddReaction(r);

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

            brs.MyReactionProcessor.Watch(mixture);

            // Add substances
            AddSubstance(ref mixture, brs.MyMaterialCatalog["Caustic Soda"], 40, 20.0);
            AddSubstance(ref mixture, brs.MyMaterialCatalog["Hydrochloric Acid"], 40, 20.0);
            mixture.Temperature = 100.0;

            // Definitions to retrive substances from mixture
            Substance water            = null;
            Substance hydrochloricAcid = null;
            Substance sodiumCloride    = null;

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

                case "Hydrochloric Acid": hydrochloricAcid = su; break;

                case "Sodium Chloride": sodiumCloride = su; break;
                }
            }

            Assert.IsTrue(Math.Abs(hydrochloricAcid.Mass - 3.53) < 0.01, "The Hydrochloric Acid part is not 3.53 kg");
            Assert.IsTrue(Math.Abs(water.Mass - 18.01) < 0.01, "The Water part is not 18.01 kg");
            Assert.IsTrue(Math.Abs(sodiumCloride.Mass - 58.45) < 0.01, "The Sodium Cloride part is not 58.45 kg");

            // Duration for removing mass given is per 1 kg
            MaterialTransferSpecByPercentage tsbp = new MaterialTransferSpecByPercentage(brs.MyMaterialCatalog["Water"], .5, TimeSpan.FromMinutes(5));

            IMaterial removee = tsbp.GetExtract(mixture);

            Debug.WriteLine("Want to remove " + tsbp);
            Debug.WriteLine("Successful in removing " + removee + ".\r\nWhat remains is ");
            Debug.WriteLine(mixture);

            // Now try to remove by mass from a substance.
            foreach (Substance su in mixture.Constituents)
            {
                switch (su.Name)
                {
                case "Water": water = su; break;

                case "Hydrochloric Acid": hydrochloricAcid = su; break;

                case "Sodium Chloride": sodiumCloride = su; break;
                }
            }

            Assert.IsTrue(Math.Abs(hydrochloricAcid.Mass - 3.53) < 0.01, "The Hydrochloric Acid part is not 3.53 kg");
            Assert.IsTrue(Math.Abs(water.Mass - 9.00) < 0.01, "The Water part is not 9.00 kg");
            Assert.IsTrue(Math.Abs(sodiumCloride.Mass - 58.45) < 0.01, "The Sodium Cloride part is not 58.45 kg");
            Assert.IsTrue(tsbp.Duration.Minutes == 45, "Removing 50% Water part did not take 5 Min"); // there are also a few seconds and miliseconds
        }
예제 #8
0
        public void TestSecondaryReactions()
        {
            Model model = new Model("Hello, world.", Guid.NewGuid());
            BasicReactionSupporter brs = new BasicReactionSupporter();

            LoadSampleCatalog(brs.MyMaterialCatalog);

            // Add more substances to catalog
            brs.MyMaterialCatalog.Add(new MaterialType(model, "Tuberus Magnificus", Guid.NewGuid(), 1.02, 4.9, MaterialState.Solid, 22.5));
            brs.MyMaterialCatalog.Add(new MaterialType(model, "French Fried Potatoes", Guid.NewGuid(), 1.02, 5.1, MaterialState.Liquid, 22.8));

            // Define reactions
            Reaction r1 = new Reaction(null, "Reaction 1", Guid.NewGuid());

            r1.AddReactant(brs.MyMaterialCatalog["Caustic Soda"], 0.5231);
            r1.AddReactant(brs.MyMaterialCatalog["Hydrochloric Acid"], 0.4769);
            r1.AddProduct(brs.MyMaterialCatalog["Water"], 0.2356);
            r1.AddProduct(brs.MyMaterialCatalog["Sodium Chloride"], 0.7644);
            brs.MyReactionProcessor.AddReaction(r1);

            Reaction r2 = new Reaction(null, "Make French Fries", Guid.NewGuid());

            r2.AddReactant(brs.MyMaterialCatalog["Sodium Chloride"], 0.1035);
            r2.AddReactant(brs.MyMaterialCatalog["Tuberus Magnificus"], 0.8965);
            r2.AddProduct(brs.MyMaterialCatalog["French Fried Potatoes"], 1.000);
            brs.MyReactionProcessor.AddReaction(r2);

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

            brs.MyReactionProcessor.Watch(mixture);

            AddSubstance(ref mixture, brs.MyMaterialCatalog["Caustic Soda"], 40, 20.0);
            AddSubstance(ref mixture, brs.MyMaterialCatalog["Hydrochloric Acid"], 40, 20.0);
            AddSubstance(ref mixture, brs.MyMaterialCatalog["Tuberus Magnificus"], 40, 20.0);
            mixture.Temperature = 100.0;

            Substance water            = null;
            Substance hydrochloricAcid = null;
            Substance sodiumCloride    = null;
            Substance ff = null;

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

                case "Hydrochloric Acid": hydrochloricAcid = s; break;

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

                case "French Fried Potatoes": ff = s; break;
                }
            }

            Assert.IsTrue(Math.Abs(hydrochloricAcid.Mass - 3.53) < 0.01, "The Hydrochloric Acid part is not 3.53 kg");
            Assert.IsTrue(Math.Abs(water.Mass - 18.01) < 0.01, "The Water part is not 18.01 kg");
            Assert.IsTrue(Math.Abs(sodiumCloride.Mass - 53.83) < 0.01, "The Sodium Cloride part is not 53.83 kg");
            Assert.IsTrue(Math.Abs(ff.Mass - 44.62) < 0.01, "The French Fries part is not 44.62 kg");

            Debug.WriteLine(mixture);
        }
예제 #9
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");
        }
예제 #10
0
        public void TestRemovalByMassFromMixture()
        {
            Model model = new Model("Hello, world.", Guid.NewGuid());
            BasicReactionSupporter brs = new BasicReactionSupporter();

            LoadSampleCatalog(brs.MyMaterialCatalog);

            // Define reactions
            Reaction r = new Reaction(null, "Reaction", Guid.NewGuid());

            r.AddReactant(brs.MyMaterialCatalog["Caustic Soda"], 0.5231);
            r.AddReactant(brs.MyMaterialCatalog["Hydrochloric Acid"], 0.4769);
            r.AddProduct(brs.MyMaterialCatalog["Water"], 0.2356);
            r.AddProduct(brs.MyMaterialCatalog["Sodium Chloride"], 0.7644);
            brs.MyReactionProcessor.AddReaction(r);

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

            brs.MyReactionProcessor.Watch(mixture);

            // Add substances
            AddSubstance(ref mixture, brs.MyMaterialCatalog["Caustic Soda"], 40, 20.0);
            AddSubstance(ref mixture, brs.MyMaterialCatalog["Hydrochloric Acid"], 40, 20.0);
            mixture.Temperature = 100.0;

            // Definitions to retrive substances from mixture
            Substance water            = null;
            Substance hydrochloricAcid = null;
            Substance sodiumCloride    = null;

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

                case "Hydrochloric Acid": hydrochloricAcid = su; break;

                case "Sodium Chloride": sodiumCloride = su; break;
                }
            }

            _Debug.Assert(Math.Abs(hydrochloricAcid.Mass - 3.53) < 0.01, "The Hydrochloric Acid part is not 3.53 kg");
            _Debug.Assert(Math.Abs(water.Mass - 18.01) < 0.01, "The Water part is not 18.01 kg");
            _Debug.Assert(Math.Abs(sodiumCloride.Mass - 58.45) < 0.01, "The Sodium Cloride part is not 58.45 kg");

            // Remove 10 kg of water
            MaterialTransferSpecByMass tsbm = new MaterialTransferSpecByMass(brs.MyMaterialCatalog["Water"], 10, TimeSpan.FromMinutes(5));

            _Debug.WriteLine("Want to remove " + tsbm);
            IMaterial removee = tsbm.GetExtract(mixture);

            _Debug.WriteLine("Successful in removing " + removee + ".\r\nWhat remains is ");
            _Debug.WriteLine(mixture);

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

                case "Hydrochloric Acid": hydrochloricAcid = su; break;

                case "Sodium Chloride": sodiumCloride = su; break;
                }
            }

            _Debug.Assert(Math.Abs(hydrochloricAcid.Mass - 3.53) < 0.01, "The Hydrochloric Acid part is not 3.53 kg");
            _Debug.Assert(Math.Abs(water.Mass - 8.01) < 0.01, "The Water part is not 8.01 kg");
            _Debug.Assert(Math.Abs(sodiumCloride.Mass - 58.45) < 0.01, "The Sodium Chloride part is not 58.45 kg");
            _Debug.Assert(tsbm.Duration.Equals(new TimeSpan(0, 0, 5, 0, 0)), "Removing 10 kg Water part did not take 5 Min");
        }
예제 #11
0
파일: Substance.cs 프로젝트: sjvannTMU/Sage
        /// <summary>
        /// Removes the specified mass from this substance.
        /// </summary>
        /// <param name="mass">The mass.</param>
        /// <returns>Substance.</returns>
        /// <exception cref="WriteProtectionViolationException">Fired if there is a write lock on the substance.</exception>
        public virtual Substance Remove(double mass)
        {
            if (!m_writeLock.IsWritable)
            {
                throw new WriteProtectionViolationException(this, m_writeLock);
            }

            Substance s = (Substance)MaterialType.CreateMass(mass, Temperature);

            if (m_mass == float.MaxValue)
            {
                if (m_materialSpecs != null)
                {
                    // First figure out the total mass...
                    double totalMass = m_materialSpecs.Cast <DictionaryEntry>().Sum(de => (double)de.Value);

                    if (totalMass > 0.0)
                    {
                        foreach (DictionaryEntry de in m_materialSpecs)
                        {
                            if (s.m_materialSpecs == null)
                            {
                                s.m_materialSpecs = new Hashtable();
                            }
                            s.m_materialSpecs.Add(de.Key, mass * ((double)de.Value) / totalMass);
                        }
                    }
                }
                return(s);
            }
            else
            {
                double    pctRemoved = mass / m_mass;
                Hashtable ht         = new Hashtable();
                if (m_materialSpecs != null)
                {
                    foreach (DictionaryEntry de in m_materialSpecs)
                    {
                        if (s.m_materialSpecs == null)
                        {
                            s.m_materialSpecs = new Hashtable();
                        }
                        if (s.m_materialSpecs.ContainsKey(de.Key))
                        {
                            s.m_materialSpecs[de.Key] = pctRemoved * ((double)de.Value);
                        }
                        else
                        {
                            s.m_materialSpecs.Add(de.Key, pctRemoved * ((double)de.Value));
                        }
                        if (pctRemoved < 1.0)
                        {
                            ht.Add(de.Key, (1.0 - pctRemoved) * ((double)de.Value));
                        }
                    }
                }
                m_materialSpecs = ht;
            }

            double have  = Energy;
            double minus = s.Energy;

            m_mass -= s.Mass; // Have to set Mass before setting energy, since energy->temp requires mass.
            Energy  = (have - minus);

            m_ssh.ReportChange();
            MaterialChanged?.Invoke(this, MaterialChangeType.Contents);
            return(s);
        }