public static void MassNeighborEqualize(Matter m1, Matter m2) { List<Matter> ms1 = new List<Matter>(), ms2 = new List<Matter>(); //Create side by side list of applicable matter if (m1._myType.IsStackable) ms1.Add(m1); if (m2._myType.IsStackable) ms2.Add(m2); if (m1._myType.IsPermeable) { for (int i = 0; i < m1._myMixedContents.Count; i++) { if (m1._myMixedContents[i]._myType.IsStackable) ms1.Add(m1._myMixedContents[i]); } } if (m2._myType.IsPermeable) { for (int i = 0; i < m2._myMixedContents.Count; i++) { if (m2._myMixedContents[i]._myType.IsStackable) ms2.Add(m2._myMixedContents[i]); } } //Get Matches for simple equilibrium function and remove from old list List<Matter[]> matches = new List<Matter[]>(); for (int i = 0; i < ms1.Count; i++) { var x = (from Matter tm2 in ms2 where ms1[i].TypeMatches(tm2) select tm2).ToList<Matter>(); if (x.Count == 0) continue; if (x.Count > 1) throw new Exception("Two matches?"); if (ms1[i] == x[0]) throw new Exception("Unknown event by matching objects"); if (Math.Abs(((1.0 * ms1[i].ElementUnits) / x[0].ElementUnits) - 1) > .001) matches.Add(new Matter[] { ms1[i], x[0] }); ms1.RemoveAt(i); i--; ms2.Remove(x[0]); } //FLow what is already matching for (int i = 0; i < matches.Count; i++) { int nmm1 = 0, nmm2 = 0; Chemistry.EquilibriumFunction(matches[i][0].ElementUnits, matches[i][1].ElementUnits, 1, 1, 1, out nmm1, out nmm2); matches[i][0].ElementUnits = nmm1; matches[i][1].ElementUnits = nmm2; } //Go through non matches if (m2._myType.IsPermeable) { for (int i = 0; i < ms1.Count; i++) { int nmm1 = 0, nmm2 = 0; Chemistry.EquilibriumFunction(ms1[i].ElementUnits, 0, 1, 1, 1, out nmm1, out nmm2); if (nmm2 == 0) continue; //ms1[i]._elementMass = nmm1; m2.AbsorbChunk(ms1[i].Split(nmm2)); } } if (m1._myType.IsPermeable) { for (int i = 0; i < ms2.Count; i++) { int nmm1 = 0, nmm2 = 0; Chemistry.EquilibriumFunction(ms2[i].ElementUnits, 0, 1, 1, 1, out nmm1, out nmm2); if (nmm2 == 0) continue; //ms2[i]._elementMass = nmm1; m1.AbsorbChunk(ms2[i].Split(nmm2)); } } }
public virtual bool React(Matter m) { //Make sure matter is reactant, otherwise set reversed var reversed = false; if (this._reversible && m.TypeMatches(this._product)) reversed = true; //If not reversed and m does not equal reactant, throw exception if (!m.TypeMatches(this._reactant) && !reversed) throw new Exception("Matter Object provided does not satisfy given conditions"); //Get Probability of states var temp = 1.0 * m.ElementHeat / m.TotalMass; var parts = m.ElementUnits; if (temp == 0 || parts == 0) return false; //Create Vars var muparts = 0; var muNparts = 0; Matter.ElementType toElement; //Handle Case If reversed for muEnergy if (reversed) { muparts = this._product.Mu; muNparts = this._reactant.Mu; toElement = this._reactant; } else { muparts = this._reactant.Mu; muNparts = this._product.Mu; toElement = this._product; } var reactKR = Math.Exp((muparts - (muNparts + this._activationEnergy)) / temp); if (parts == 0) { int a = 7; int b = 3; int c = a / b; } parts--; var ReactionRate = temp * parts * reactKR; //If State is greater thanequalto one, then create x amount of new state if (ReactionRate > 1)// || StateMuNew >= 1) { if (this._reactant.MyName == "DNA") { int a = 7; int b = 3; int c = a / b; } /////////////////////// //Add DATA if (m.Owner != null) m.Owner.MySimulator.MyData.AddData("ReactionRate", ReactionRate); else m.MySimulator.MyData.AddData("ReactionRate", ReactionRate); ////////////////////// var enDif = muparts - muNparts; var amt = (int)ReactionRate; if (enDif > 0 && enDif * amt > m.ElementHeat) return false; if (amt > parts) amt = parts; //var amt = (int)StateMuNew; var newChunk = new Matter.MatterChunk(m, toElement, amt); //Handle heat if (enDif < 0) m.ReleaseHeat(amt * Math.Abs(enDif)); else if (enDif > 0) m.AbsorbHeat(amt * enDif); else throw new Exception("EnDif is zero or did not interact with environment"); var nm = m.AbsorbChunk(newChunk); if (!m.NeedsRemoval && !m.IsRemoved) Matter.HeatNeighborEqualize(nm, m); if (m.IsElementEmpty()) m.DegenerateExistence(); } return false; }