From 68682f38ab31baa8731dee7581456f08b6d100f0 Mon Sep 17 00:00:00 2001 From: hzhang Date: Wed, 26 Jun 2024 14:23:02 +0800 Subject: [PATCH] Bug Fix --- .../Compounds/Implements/Compound.cs | 7 ++ .../Mixtures/Implements/HomogeneousMixture.cs | 91 +++++++++++-------- .../Resolver/HomogeneousMixtureResolver.cs | 4 +- 3 files changed, 64 insertions(+), 38 deletions(-) diff --git a/src/Chemistry/Compounds/Implements/Compound.cs b/src/Chemistry/Compounds/Implements/Compound.cs index 97e2cf5..1d6da47 100644 --- a/src/Chemistry/Compounds/Implements/Compound.cs +++ b/src/Chemistry/Compounds/Implements/Compound.cs @@ -351,14 +351,19 @@ public class Compound return Null; if ((!byRatio && amount.IsEqualApprox(Amount)) || (byRatio && amount.IsEqualApprox(1))) { + + double deltaV = Volume; HomogeneousMixture.Compounds.Remove(this); HomogeneousMixture = HomogeneousMixture.Null; + HomogeneousMixture.Volume -= deltaV; return this; } double ebs = Energy; Compound res = Copy(); if(!byRatio) { + if (amount > Amount) + throw new Exception("????"); double ratio = amount / Amount; Amount -= amount; res.Amount = amount; @@ -373,6 +378,8 @@ public class Compound Energy = ebs * (1d - amount); } res.HomogeneousMixture = HomogeneousMixture.Null; + if (Amount < 0 || res.Amount < 0) + throw new Exception("?"); return res; } /// diff --git a/src/Chemistry/Mixtures/Implements/HomogeneousMixture.cs b/src/Chemistry/Mixtures/Implements/HomogeneousMixture.cs index b8649f2..3bfea10 100644 --- a/src/Chemistry/Mixtures/Implements/HomogeneousMixture.cs +++ b/src/Chemistry/Mixtures/Implements/HomogeneousMixture.cs @@ -149,8 +149,6 @@ public class HomogeneousMixture { if ((c.Amount * 0.125).IsEqualApprox(0) || c.Atoms.Count > 15) continue; - if(c.Expression.Equals("P2So")) - Console.WriteLine("?"); foreach(BaseBond b in c.Bonds) { if(b.Connected || !(b.Energy > b.BondingEnergy)) @@ -322,6 +320,17 @@ public class HomogeneousMixture into.AddLayer(res); return res; } + /// + /// Remove a compound from the homogeneous mixture + /// + /// + public void RemoveCompound(Compound compound) + { + double deltaV = compound.Volume; + Compounds.Remove(compound); + compound.HomogeneousMixture = Null; + Volume -= deltaV; + } /// /// Add compound into the homogeneous mixture @@ -672,12 +681,17 @@ public class HomogeneousMixture .Rayleigh(Ita) * 255 ); + public double OsmoticLevel => StateMatrix.Get + .ConjugateOn(new DiagR3(Phase, Math.PI, -Phase)) + .Rayleigh(LogStateMatrix.Get.ColumnAverage); /// /// Should not be used by any methods except ResolveNext and ResolvePrev /// private void PureResolve(HomogeneousMixture hOther) { - HashSet toAbsorb = new (); + HashSet< (Compound, double)> toAbsorb = new (); + if (hOther.OsmoticLevel > OsmoticLevel) + return; foreach (Compound c in hOther.Compounds) { double eigenRes = EigenResolvability(c); @@ -687,7 +701,7 @@ public class HomogeneousMixture continue; if (eigenRes.IsEqualApprox(0)) { - toAbsorb.Add(c); + toAbsorb.Add((c, c.Amount)); continue; } @@ -701,17 +715,19 @@ public class HomogeneousMixture double splitAmount = Math.Min(maxResAmount, c.Amount); if(splitAmount.IsEqualApprox(0)) continue; - string log = $"{splitAmount} split from {c.Amount} * {c.Expression}"; - Compound cSplit = c.Split(splitAmount); - cSplit.TraceLog.Add(log); - toAbsorb.Add(cSplit); + toAbsorb.Add((c, splitAmount)); + //Compound cSplit = c.Split(splitAmount); + //toAbsorb.Add(cSplit); } - foreach (Compound c in toAbsorb) + foreach ((Compound c, double a) in toAbsorb) { - double v = c.Volume; + Compound sp = c.Split(a); + double v = sp.Volume; hOther.Volume -= v; Volume += v; - AddCompound(c); + /*if (c.Amount.IsEqualApprox(0)) + hOther.RemoveCompound(c);*/ + AddCompound(sp); } if(hOther.Amount.IsEqualApprox(0)) HeterogeneousMixture.RemoveLayer(hOther); @@ -738,43 +754,46 @@ public class HomogeneousMixture private bool Precipitate() { + HashSet<(Compound, double)> toDeposit = new(); foreach (Compound c in Compounds) { double maxRes = Resolvability(c); - if (maxRes < 0) + if (maxRes < 0 || maxRes > c.Concentration) continue; double maxResAmount = maxRes * (Amount - c.Amount); if(maxResAmount.IsEqualApprox(0)) continue; - - double aDiff = c.Amount - maxResAmount; + double aDiff = c.Amount - maxResAmount; if (aDiff.IsSignificantlyGreaterThen(0) ) + toDeposit.Add((c, aDiff)); + } + + foreach ((Compound c, double a) in toDeposit) + { + Compound oth = c.Split(a); + if (oth.FreeDensity.Get > FreeDensity.Get) { - Compound oth = c.Split(c.Amount - maxResAmount); - if (oth.FreeDensity.Get > FreeDensity.Get) + if (Layer.Next.IsEnding) { - if (Layer.Next.IsEnding) - { - HomogeneousMixture m = HeterogeneousMixture.AddLayer(); - m.Layer.MoveAfter(Layer); - m.AddCompound(oth); - m.Volume = m.FreeVolume; - return true; - } - Layer.Next.Value.AddCompound(oth); + HomogeneousMixture m = HeterogeneousMixture.AddLayer(); + m.Layer.MoveAfter(Layer); + m.AddCompound(oth); + m.Volume = m.FreeVolume; + return true; } - else + Layer.Next.Value.AddCompound(oth); + } + else + { + if (Layer.Previous.IsEnding) { - if (Layer.Previous.IsEnding) - { - HomogeneousMixture m = HeterogeneousMixture.AddLayer(); - m.Layer.MoveBefore(Layer); - m.AddCompound(oth); - m.Volume = m.FreeVolume; - return true; - } - Layer.Previous.Value.AddCompound(oth); + HomogeneousMixture m = HeterogeneousMixture.AddLayer(); + m.Layer.MoveBefore(Layer); + m.AddCompound(oth); + m.Volume = m.FreeVolume; + return true; } + Layer.Previous.Value.AddCompound(oth); } } return false; @@ -792,7 +811,7 @@ public class HomogeneousMixture } /// - /// combine identical compounds in the miture + /// combine identical compounds in the mixture /// public void Degenerate() { diff --git a/src/Chemistry/Mixtures/Resolver/HomogeneousMixtureResolver.cs b/src/Chemistry/Mixtures/Resolver/HomogeneousMixtureResolver.cs index 298333c..bd329dc 100644 --- a/src/Chemistry/Mixtures/Resolver/HomogeneousMixtureResolver.cs +++ b/src/Chemistry/Mixtures/Resolver/HomogeneousMixtureResolver.cs @@ -16,8 +16,8 @@ public static class HomogeneousMixtureResolver private static readonly Regex Matcher = new Regex(MatchString); private const string VolumeRegex = @"\?V\(([0-9,]+)\)"; - private const string EnergyRegex = @"\?E\(([0-9,]+)\)"; - private const string EnvMatchString = VolumeRegex + EnergyRegex; + private const string EnergyRegex = @"\?ENG\(([0-9,]+)\)"; + private const string EnvMatchString = EnergyRegex + VolumeRegex; private static readonly Regex EnvMatcher = new Regex(EnvMatchString); /// /// split different compounds