Beispiel #1
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 #2
0
 /// <summary>
 /// Sets the initial mixture in the modeled vessel.
 /// </summary>
 /// <param name="initial">The initial mixture in the modeled vessel.</param>
 public void SetInitialMixture(Mixture initial)
 {
     if (initial != null)
     {
         m_initial = (Mixture)initial.Clone();
     }
     else
     {
         m_initial = new Mixture();
     }
 }
Beispiel #3
0
 /// <summary>
 /// Sets the inflowing mixture in the modeled vessel.
 /// </summary>
 /// <param name="inflow">The inflowing mixture in the modeled vessel.</param>
 public void SetInflowMixture(Mixture inflow)
 {
     if (inflow != null)
     {
         m_inflow = (Mixture)inflow.Clone();
     }
     else
     {
         m_inflow = new Mixture();
     }
 }
Beispiel #4
0
 /// <summary>
 /// Sets the outflowing mixture in the modeled vessel.
 /// </summary>
 /// <param name="outflow">The outflowing mixture in the modeled vessel.</param>
 public void SetOutflowMixture(Mixture outflow)
 {
     if (outflow != null)
     {
         m_outflow = (Mixture)outflow.Clone();
     }
     else
     {
         m_outflow = new Mixture();
     }
 }
Beispiel #5
0
 /// <summary>
 /// Creates a MVTracker with a full complement of parameters.
 /// </summary>
 /// <param name="initial">The initial mixture.</param>
 /// <param name="inflow">The inflowing mixture.</param>
 /// <param name="outflow">The outflowing mixture.</param>
 /// <param name="capacity">The capacity of the vessel.</param>
 /// <param name="rp">The ReactionProcessor that knows of any reactions that will take place. Can be null.</param>
 public MassVolumeTracker(Mixture initial, Mixture inflow, Mixture outflow, double capacity, ReactionProcessor rp)
 {
     m_massHistory   = new DoubleTracker();
     m_volumeHistory = new DoubleTracker();
     SetInitialMixture(initial == null ? new Mixture() : (Mixture)initial.Clone());
     SetInflowMixture(inflow == null ? new Mixture() : (Mixture)inflow.Clone());
     SetOutflowMixture(outflow == null ? new Mixture() : (Mixture)outflow.Clone());
     m_reactionProcessor = rp;
     m_capacity          = capacity;
     m_cyclical          = true;
     m_inflowFirst       = true;
 }
Beispiel #6
0
        public void ProcessEmissions(
            Mixture initial,
            out Mixture final,
            out Mixture emission,
            bool modifyInPlace,
            string emissionModelKey,
            Hashtable parameters)
        {
            final    = null;
            emission = null;

            IEmissionModel em = (IEmissionModel)m_models[emissionModelKey];

            if (em == null)
            {
                if (!m_ignoreUnknownModelTypes)
                {
                    string msg = "Emission Model Key \"" + emissionModelKey
                                 + "\" does not match known emission model keys, which include ";
                    msg += Utility.StringOperations.ToCommasAndAndedList(new ArrayList(m_models.Keys));
                    throw new ApplicationException(msg);
                }
            }
            else
            {
                if (m_enabled)
                {
                    em.Process(initial, out final, out emission, modifyInPlace, parameters);
                }
                else
                {
                    final    = (Mixture)initial.Clone();
                    emission = new Mixture();
                }
            }
        }
Beispiel #7
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 #8
0
        /// <summary>
        /// Causes the reaction to take place, if possible, in (and perform modifications to, the provided target mixture.
        /// </summary>
        /// <param name="target">The target.</param>
        /// <returns></returns>
        public ReactionInstance React(Mixture target)
        {
            // We will handle a reaction's completion percentage/equilibrium
            // calculation by first using the reverse reaction to move all of
            // the already-existent (in proportion) products over to the
            // reactant side, and then move rxnPct % back to the product side.
            double fwdScale = double.MaxValue;
            double revScale = double.MaxValue;

            if (m_reactants.Count != 0)
            {
                foreach (ReactionParticipant rp in m_reactants)
                {
                    double howMuch = target.ContainedMassOf(rp.MaterialType);
                    if (howMuch > 0 && rp.IsCatalyst)
                    {
                        howMuch = double.MaxValue;
                    }
                    fwdScale = Math.Min(fwdScale, howMuch / rp.Mass);
                    if (s_diagnostics)
                    {
                        _Debug.WriteLine("target contains " + howMuch + " of reactant " + rp.MaterialType.Name + " so fwdScale is " + fwdScale);
                    }
                }
                if (fwdScale == double.MaxValue)
                {
                    fwdScale = 0.0;
                }
            }
            else
            {
                fwdScale = 0.0;
            }
            fwdScale *= m_rxPct;

            if (m_products.Count != 0)
            {
                foreach (ReactionParticipant rp in m_products)
                {
                    double howMuch = target.ContainedMassOf(rp.MaterialType);
                    if (howMuch > 0 && rp.IsCatalyst)
                    {
                        howMuch = double.MaxValue;
                    }
                    revScale = Math.Min(revScale, howMuch / rp.Mass);
                    if (s_diagnostics)
                    {
                        _Debug.WriteLine("target contains " + howMuch + " of product " + rp.MaterialType.Name + " so revScale is " + revScale);
                    }
                }

                if (revScale == double.MaxValue)
                {
                    revScale = 0.0;
                }
            }
            else
            {
                revScale = 0.0;
            }
            revScale *= (1 - m_rxPct);

            // If we're going to undo and then redo the same thing, the reaction didn't happen.
            if ((fwdScale == 0.0 && revScale == 0.0) || (Math.Abs(fwdScale - revScale) < 0.000001))
            {
                if (s_diagnostics)
                {
                    _Debug.WriteLine("Reaction " + Name + " won't happen in mixture " + target);
                }
                return(null);
            }

            if (s_diagnostics)
            {
                _Debug.WriteLine("Mixture is " + target);
            }
            if (s_diagnostics)
            {
                _Debug.WriteLine("Reaction " + Name + " is happening. " + ToString());
            }

            ReactionGoingToHappenEvent?.Invoke(this, target);
            target.ReactionGoingToHappen(this);

            Mixture mixtureWas = (Mixture)target.Clone();

            target.SuspendChangeEvents();

            if (s_diagnostics)
            {
                _Debug.WriteLine(revScale > 0.0 ? "Performing reverse reaction..." : "Reverse reaction won't happen.");
            }
            if (revScale > 0.0)
            {
                React(target, m_products, m_reactants, revScale);
            }

            if (s_diagnostics)
            {
                _Debug.WriteLine(fwdScale > 0.0 ? "Performing forward reaction..." : "Forward reaction won't happen.");
            }
            if (fwdScale > 0.0)
            {
                React(target, m_reactants, m_products, fwdScale * m_rxPct);
            }

            // Percent completion is pulled out of the Reaction object.

            ReactionInstance ri = new ReactionInstance(this, fwdScale, revScale, m_nextRiGuid);

            m_nextRiGuid = GuidOps.Increment(m_nextRiGuid);

            ReactionHappenedEvent?.Invoke(ri);
            target.ReactionHappened(ri);

            target.AddEnergy(m_energy * (fwdScale - revScale));

            target.ResumeChangeEvents(!mixtureWas.ToString("F2", "F3").Equals(target.ToString("F2", "F3"))); // Only emit summary events if the mixture has changed.

            return(ri);
        }
Beispiel #9
0
 /// <summary>
 ///   Gets a mixture distribution modeled
 ///   by this Gaussian Mixture Model.
 /// </summary>
 public Mixture <NormalDistribution> GetMixtureDistribution()
 {
     return((Mixture <NormalDistribution>)model.Clone());
 }