This commit is contained in:
h z
2024-06-21 23:50:03 +08:00
commit a9dd3e70e2
11 changed files with 515 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
bin/
obj/
/packages/
riderModule.iml
/_ReSharper.Caches/

17
UnitTest1.cs Normal file
View File

@@ -0,0 +1,17 @@
using NUnit.Framework;
namespace VirtualChemistryTest;
public class Tests
{
[SetUp]
public void Setup()
{
}
[Test]
public void Test1()
{
Assert.Pass();
}
}

View File

@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0"/>
<PackageReference Include="NUnit" Version="3.13.2"/>
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0"/>
<PackageReference Include="coverlet.collector" Version="3.1.0"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\VirtualChemistry\VirtualChemistry.csproj" />
</ItemGroup>
</Project>

22
VirtualChemistryTest.sln Normal file
View File

@@ -0,0 +1,22 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VirtualChemistryTest", "VirtualChemistryTest.csproj", "{D8A30C42-A49B-4096-BF53-32A82B492233}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VirtualChemistry", "..\VirtualChemistry\VirtualChemistry.csproj", "{C1C0E45F-59D4-44C3-A55F-80F44DF2935D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D8A30C42-A49B-4096-BF53-32A82B492233}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D8A30C42-A49B-4096-BF53-32A82B492233}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D8A30C42-A49B-4096-BF53-32A82B492233}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D8A30C42-A49B-4096-BF53-32A82B492233}.Release|Any CPU.Build.0 = Release|Any CPU
{C1C0E45F-59D4-44C3-A55F-80F44DF2935D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C1C0E45F-59D4-44C3-A55F-80F44DF2935D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C1C0E45F-59D4-44C3-A55F-80F44DF2935D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C1C0E45F-59D4-44C3-A55F-80F44DF2935D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

7
global.json Normal file
View File

@@ -0,0 +1,7 @@
{
"sdk": {
"version": "6.0.0",
"rollForward": "latestMinor",
"allowPrerelease": false
}
}

80
tests/AtomSoupTest.cs Normal file
View File

@@ -0,0 +1,80 @@
using System;
using System.Linq;
using VirtualChemistry.Chemistry.Atoms.Implements;
using VirtualChemistry.Chemistry.Atoms.Resolver;
using VirtualChemistry.Chemistry.Compounds.Implements;
using VirtualChemistry.Chemistry.Containers;
using VirtualChemistry.Chemistry.Mixtures.Implements;
using VirtualChemistry.Constants;
namespace VirtualChemistryTest;
public static class AtomSoupTest
{
private static BaseAtom[] AllAtoms() =>
ChemistryConstant.ElementSymbols.Select(AtomResolver.Resolve).ToArray();
private class Container : IChemicalContainer
{
public Container(HeterogeneousMixture h) => Content = h;
public double Volume() => 200;
public HeterogeneousMixture Content { get; set; }
public double EnvironmentPressure { get; set; }
public double EnvironmentTemperature { get; set; }
}
[Test]
public static void AtomSoupTest1()
{
HeterogeneousMixture h = new ();
h.Container = new Container(h);
HomogeneousMixture m = new();
h.AddLayer(m);
foreach (BaseAtom a in AllAtoms())
{
Compound c = a.GrabCompound;
a.Compound = c;
c.Amount = 1;
m.AddCompound(c);
}
m.Volume = m.FreeVolume;
h.Container.EnvironmentTemperature = 4.4;
for (int i = 1; i < 50; i++)
h.OneStep();
Console.WriteLine($"{h.Layers.Count} {h.Layers.Sum(x => x.Volume)} --- {h.FreeVolume}");
foreach (HomogeneousMixture mx in h.Layers)
{
Console.WriteLine($"{mx.Temperature} ====={mx.FreeVolume}==={mx.Density}={mx.Volume}={mx.CompressionStiffness}");
foreach (Compound cx in mx.Compounds)
{
var b = cx.Atoms.First().NextUnconnected("m");
Console.WriteLine($"{cx.Expression}\t\tAMT:{cx.Amount}\t\tRes:{mx.Resolvability(cx)}\t\tE:{b.Energy}");
}
}
m.RPC();
}
[Test]
public static void SoTest1()
{
HeterogeneousMixture h = new ();
h.Container = new Container(h);
HomogeneousMixture m = new();
h.AddLayer(m);
BaseAtom a = new SoAtom();
a.C();
Compound c = a.GrabCompound;
a.Compound = c;
c.Amount = 1;
m.AddCompound(c);
m.Volume = m.FreeVolume;
h.Container.EnvironmentTemperature = 2.4;
h.OneStep();
foreach (HomogeneousMixture mx in h.Layers)
{
Console.WriteLine($"{mx.Temperature} ===================");
foreach (Compound cx in mx.Compounds)
{
var b = cx.Atoms.First().NextUnconnected("m");
Console.WriteLine($"{cx.Expression}\t\tAMT:{cx.Amount}\t\tRes:{mx.Resolvability(cx)}\t\tE:{b.Energy}");
}
}
}
}

159
tests/AtomTests.cs Normal file
View File

@@ -0,0 +1,159 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using VirtualChemistry.Chemistry.Atoms.Implements;
using VirtualChemistry.Chemistry.Atoms.Resolver;
using VirtualChemistry.Chemistry.Bonds.Implements;
using VirtualChemistry.Constants;
namespace VirtualChemistryTest;
public static class AtomTests
{
[DatapointSource]
private static readonly BaseAtom[] DataSource =
ChemistryConstant.ElementSymbols.Select(AtomResolver.Resolve).ToArray();
private static readonly Action<BaseAtom> OnFailReport =
atom => Console.WriteLine($" Fail - {atom.Element} - {atom.AtomicNumber}");
[Test]
public static void AtomQStepByStep()
{
QAtom atom = new QAtom();
atom.C();
MBond b = (atom.Bonds.First() as MBond)!;
Assert.IsNotNull(b);
SU3 s = b.EigenStateMatrix;
LieSU3 tx = atom.LogEigenState.Get;
Console.WriteLine(tx.PythonRepresentation);
Console.WriteLine(atom.StateMatrix.Get.PythonRepresentation);
var evs = tx.EigenValues();
foreach (Complex ev in evs)
{
Console.WriteLine($"ev - {ev}");
}
evs = atom.StateMatrix.Get.EigenValues();
foreach (Complex ev in evs)
{
Console.WriteLine($"ev x - {ev}");
}
Console.WriteLine(s.CSharpRepresentation);
Assert.IsTrue(b.StateMatrix.Get.IsEqualApprox(b.EigenStateMatrix));
Assert.IsTrue(b.LogState.Get.IsEqualApprox(b.StateMatrix.Get.Log()));
Assert.IsTrue(atom.BondInformationMatrix.Get.IsEqualApprox(b.StateMatrix.Get));
Assert.IsTrue(atom.LogEigenState.Get.IsEqualApprox(atom.EigenStateMatrix.Log()));
Assert.IsTrue((atom.LogEigenState.Get - atom.EigenStateMatrix.Log()).IsEqualApprox(C33.Zero));
Assert.IsTrue(atom.LogEigenState.Get.Exp().IsEqualApprox(atom.EigenStateMatrix));
Assert.IsTrue(atom.LogStateMatrix.Get.IsEqualApprox(b.StateMatrix.Get.ConjugateOn(atom.LogEigenState.Get)));
Assert.IsTrue(atom.StateMatrix.Get.IsEqualApprox(b.StateMatrix.Get.ConjugateOn(atom.EigenStateMatrix)));
}
[Theory]
public static void AtomMatrixTest(BaseAtom atom)
{
Assert.IsTrue(atom.LogStateMatrix.Get.Exp().IsEqualApprox(atom.StateMatrix.Get));
}
[Theory]
public static void BondInfoTest(BaseAtom atom)
{
Console.WriteLine(atom.Element);
foreach(var g in atom.Bonds.GroupBy(a => a.BondType))
Console.WriteLine($"\t\t{g.Key}, {g.Count()}");
}
[Test]
public static void AtomTestQ()
{
QAtom a = new QAtom();
a.C();
//LieSU3 x = a.LogStateMatrix.Get;
//SU3 expx = a.StateMatrix.Get;
//Assert.IsTrue(a.LogStateMatrix.Get.Exp().IsEqualApprox(a.StateMatrix.Get));
Assert.That(a.NextUnconnected(ChemistryConstant.BondTypes.M), Is.Not.EqualTo(BaseBond.Null));
Assert.That(a.NextUnconnected(ChemistryConstant.BondTypes.S), Is.EqualTo(BaseBond.Null));
Assert.That(a.NextUnconnected(ChemistryConstant.BondTypes.D), Is.EqualTo(BaseBond.Null));
Assert.That(a.NextUnconnected(ChemistryConstant.BondTypes.Y), Is.EqualTo(BaseBond.Null));
Assert.That(a.NextUnconnected(ChemistryConstant.BondTypes.Q), Is.EqualTo(BaseBond.Null));
Assert.That(a.NextUnconnected(ChemistryConstant.BondTypes.P), Is.EqualTo(BaseBond.Null));
Assert.That(a.NextUnconnected(ChemistryConstant.BondTypes.H), Is.EqualTo(BaseBond.Null));
Dictionary<string, int> bondTypeCount = new();
foreach (BaseBond b in a.Bonds)
{
Assert.IsFalse(b.Connected);
Assert.That(b.Atom, Is.EqualTo(a));
Assert.That(b.Energy, Is.EqualTo(0));
if (bondTypeCount.ContainsKey(b.BondType))
bondTypeCount[b.BondType] += 1;
else
bondTypeCount[b.BondType] = 1;
}
Assert.That(bondTypeCount["m"], Is.EqualTo(1));
}
[Test]
public static void AtomTestR()
{
RAtom a = new RAtom();
a.C();
Assert.IsTrue(a.LogStateMatrix.Get.Exp().IsEqualApprox(a.StateMatrix.Get));
Assert.That(a.NextUnconnected(ChemistryConstant.BondTypes.M), Is.Not.EqualTo(BaseBond.Null));
Assert.That(a.NextUnconnected(ChemistryConstant.BondTypes.S), Is.Not.EqualTo(BaseBond.Null));
Assert.That(a.NextUnconnected(ChemistryConstant.BondTypes.D), Is.EqualTo(BaseBond.Null));
Assert.That(a.NextUnconnected(ChemistryConstant.BondTypes.Y), Is.EqualTo(BaseBond.Null));
Assert.That(a.NextUnconnected(ChemistryConstant.BondTypes.Q), Is.EqualTo(BaseBond.Null));
Assert.That(a.NextUnconnected(ChemistryConstant.BondTypes.P), Is.EqualTo(BaseBond.Null));
Assert.That(a.NextUnconnected(ChemistryConstant.BondTypes.H), Is.EqualTo(BaseBond.Null));
Dictionary<string, int> bondTypeCount = new Dictionary<string, int>();
foreach (BaseBond b in a.Bonds)
{
Assert.IsFalse(b.Connected);
Assert.That(b.Atom, Is.EqualTo(a));
Assert.That(b.Energy, Is.EqualTo(0));
if (bondTypeCount.ContainsKey(b.BondType))
bondTypeCount[b.BondType] += 1;
else
bondTypeCount[b.BondType] = 1;
}
Assert.That(bondTypeCount["m"], Is.EqualTo(1));
Assert.That(bondTypeCount["s"], Is.EqualTo(2));
}
[Test]
public static void AtomTestA()
{
AAtom a = new AAtom();
a.C();
Assert.IsTrue(a.LogStateMatrix.Get.Exp().IsEqualApprox(a.StateMatrix.Get));
Assert.That(a.NextUnconnected(ChemistryConstant.BondTypes.M), Is.Not.EqualTo(BaseBond.Null));
Assert.That(a.NextUnconnected(ChemistryConstant.BondTypes.S), Is.Not.EqualTo(BaseBond.Null));
Assert.That(a.NextUnconnected(ChemistryConstant.BondTypes.D), Is.Not.EqualTo(BaseBond.Null));
Assert.That(a.NextUnconnected(ChemistryConstant.BondTypes.Y), Is.EqualTo(BaseBond.Null));
Assert.That(a.NextUnconnected(ChemistryConstant.BondTypes.Q), Is.EqualTo(BaseBond.Null));
Assert.That(a.NextUnconnected(ChemistryConstant.BondTypes.P), Is.EqualTo(BaseBond.Null));
Assert.That(a.NextUnconnected(ChemistryConstant.BondTypes.H), Is.EqualTo(BaseBond.Null));
Dictionary<string, int> bondTypeCount = new Dictionary<string, int>();
foreach (BaseBond b in a.Bonds)
{
Assert.IsFalse(b.Connected);
Assert.That(b.Atom, Is.EqualTo(a));
Assert.That(b.Energy, Is.EqualTo(0));
if (bondTypeCount.ContainsKey(b.BondType))
bondTypeCount[b.BondType] += 1;
else
bondTypeCount[b.BondType] = 1;
}
Assert.That(bondTypeCount["m"], Is.EqualTo(1));
Assert.That(bondTypeCount["s"], Is.EqualTo(2));
Assert.That(bondTypeCount["d"], Is.EqualTo(1));
}
}

View File

@@ -0,0 +1,96 @@
using System;
using System.Linq;
using Skeleton.Algebra.Extensions;
using VirtualChemistry.Chemistry.Atoms.Implements;
using VirtualChemistry.Chemistry.Atoms.Resolver;
using VirtualChemistry.Chemistry.Bonds.Implements;
using VirtualChemistry.Chemistry.Compounds.Implements;
using VirtualChemistry.Chemistry.Containers;
using VirtualChemistry.Chemistry.Mixtures.Implements;
namespace VirtualChemistryTest;
public static class BondConnectionTest
{
private class Container : IChemicalContainer
{
public Container(HeterogeneousMixture h) => Content = h;
public double Volume() => 200;
public HeterogeneousMixture Content { get; set; }
public double EnvironmentPressure { get; set; }
public double EnvironmentTemperature { get; set; }
}
[Test]
public static void Test()
{
HeterogeneousMixture h = new ();
h.Container = new Container(h);
HomogeneousMixture m = new();
QAtom q1 = new ();
QAtom q2 = new();
q1.C();
q2.C();
BaseBond b1 = q1.NextUnconnected("m");
BaseBond b2 = q2.NextUnconnected("m");
b1.Connect(b2);
Compound c = q1.GrabCompound;
c.Amount = 1;
m.AddCompound(c);
h.AddLayer(m);
Assert.IsTrue(h.Amount.IsEqualApprox(1));
Assert.That(h.Layers.Count, Is.EqualTo(1));
Assert.IsTrue(h.Layers.First().Amount.IsEqualApprox(1));
Assert.IsTrue(h.Layers.First().Ratio.IsEqualApprox(1));
Assert.IsTrue(c.Concentration.IsEqualApprox(1));
Console.WriteLine(c.IsoRepresentation);
QAtom q3 = new();
QAtom q4 = new();
q3.C();
q4.C();
q3.NextUnconnected("m").Connect(q4.NextUnconnected("m"));
Compound cx = q3.GrabCompound;
Console.WriteLine(cx.IsoRepresentation);
Assert.IsTrue(c.IsometricTo(cx));
Console.WriteLine(h.Dump());
Console.WriteLine($"T: {m.Temperature} FD:{m.FreeDensity.Get} FV:{m.FreeVolume}");
h.Container.EnvironmentTemperature = 1;
for(int i = 0;i<10;i++)
{
m.HeatExchange();
Console.WriteLine($"P: {m.Phase} T: {m.Temperature} FD:{m.FreeDensity.Get} FV:{m.FreeVolume}");
//Console.WriteLine($"\t\t{c.CompressionBias.Get} {c.CompressionElasticity.Get} {c.CompressionStiffness}");
Console.WriteLine($"\t{b1.AntiBondingEnergy} - {b1.Energy}");
Console.WriteLine($"\t{b2.AntiBondingEnergy} - {b2.Energy}");
}
}
[Test]
public static void ReactionTest()
{
HeterogeneousMixture h = new ();
h.Container = new Container(h);
HomogeneousMixture m = new();
h.AddLayer(m);
BaseAtom a = AtomResolver.Resolve(1);
Compound c = a.GrabCompound;
a.Compound = c;
c.Amount = 2;
m.AddCompound(c);
h.Container.EnvironmentTemperature = 9;
for(int i = 1; i < 10; i++)
h.OneStep();
foreach (HomogeneousMixture mx in h.Layers)
{
Console.WriteLine(mx.Temperature);
foreach (Compound cx in mx.Compounds)
{
var b = cx.Atoms.First().NextUnconnected("m");
Console.WriteLine($"{cx.Expression} {cx.Amount} {b.BondingEnergy} {b.Energy}");
}
}
}
}

View File

@@ -0,0 +1,39 @@
using Skeleton.Algebra.Extensions;
using VirtualChemistry.Chemistry.Atoms.Implements;
using VirtualChemistry.Chemistry.Atoms.Resolver;
using VirtualChemistry.Chemistry.Compounds.Implements;
using VirtualChemistry.Chemistry.Containers;
using VirtualChemistry.Chemistry.Mixtures.Implements;
namespace VirtualChemistryTest;
public static class MixtureDegenerateTest
{
private class Container : IChemicalContainer
{
public Container(HeterogeneousMixture h) => Content = h;
public double Volume() => 200;
public HeterogeneousMixture Content { get; set; }
public double EnvironmentPressure { get; set; }
public double EnvironmentTemperature { get; set; }
}
[Test]
public static void DegenerateTest()
{
HeterogeneousMixture h = new ();
h.Container = new Container(h);
HomogeneousMixture m = new();
h.AddLayer(m);
BaseAtom a = AtomResolver.Resolve(1);
BaseAtom a2 = AtomResolver.Resolve(1);
Compound c1 = a.GrabCompound;
c1.Amount = 10;
Compound c2 = a2.GrabCompound;
c2.Amount = 5;
m.AddCompound(c1);
m.AddCompound(c2);
Assert.That(m.Compounds.Count, Is.EqualTo(1));
Assert.IsTrue(m.Amount.IsEqualApprox(15));
}
}

View File

@@ -0,0 +1,59 @@
using System;
using System.Numerics;
using VirtualChemistry.Chemistry.Atoms.Implements;
using VirtualChemistry.Chemistry.Atoms.Resolver;
using VirtualChemistry.Chemistry.Compounds.Implements;
using VirtualChemistry.Chemistry.Containers;
using VirtualChemistry.Chemistry.Mixtures.Implements;
namespace VirtualChemistryTest;
public static class ResolvabilityTest
{
private class Container : IChemicalContainer
{
public Container(HeterogeneousMixture h) => Content = h;
public double Volume() => 200;
public HeterogeneousMixture Content { get; set; }
public double EnvironmentPressure { get; set; }
public double EnvironmentTemperature { get; set; }
}
[Test]
public static void SelfResolvabilityTest()
{
HeterogeneousMixture h = new ();
h.Container = new Container(h);
HomogeneousMixture m = new();
h.AddLayer(m);
BaseAtom a = AtomResolver.Resolve(1);
BaseAtom a2 = AtomResolver.Resolve(1);
Compound c1 = a.GrabCompound;
c1.Amount = 1;
Compound c2 = a2.GrabCompound;
c2.Amount = 2;
m.AddCompound(c1);
Console.WriteLine(m.Resolvability(c2));
}
[Test]
public static void InverseResolvabilityTest()
{
HeterogeneousMixture h = new ();
h.Container = new Container(h);
HomogeneousMixture m = new();
h.AddLayer(m);
HomogeneousMixture m2 = new();
BaseAtom a = AtomResolver.Resolve(1);
BaseAtom a2 = AtomResolver.Resolve(2);
Compound c1 = a.GrabCompound;
c1.Amount = 1;
Compound c2 = a2.GrabCompound;
c2.Amount = 2;
m.AddCompound(c1);
m2.AddCompound(c2);
Console.WriteLine(m.Resolvability(c2));
Console.WriteLine(m2.Resolvability(c1));
Complex sa = 0;
Console.WriteLine(sa.Phase);
}
}

10
tests/Usings.cs Normal file
View File

@@ -0,0 +1,10 @@
global using NUnit.Framework;
global using C3 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim3>.OnField<System.Numerics.Complex>.FVector;
global using R3 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim3>.OnField<double>.FVector;
global using C33 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim3>.OnField<System.Numerics.Complex>.FMatrix;
global using R33 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim3>.OnField<double>.FMatrix;
global using U3 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim3>.FUnitaryMatrix;
global using SU3 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim3>.FSpecialUnitaryMatrix;
global using LieU3 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim3>.FLieUnitaryMatrix;
global using LieSU3 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim3>.FSpecialLieUnitaryMatrix;