m4
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
bin/
|
||||
obj/
|
||||
/packages/
|
||||
riderModule.iml
|
||||
/_ReSharper.Caches/
|
||||
13
VirtualChemistry.csproj
Normal file
13
VirtualChemistry.csproj
Normal file
@@ -0,0 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\RiderProjects\Skeleton\Skeleton.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
27
VirtualChemistry.sln
Normal file
27
VirtualChemistry.sln
Normal file
@@ -0,0 +1,27 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VirtualChemistry", "VirtualChemistry.csproj", "{36979A00-F434-4001-A80E-ECBF92A0AB5E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Skeleton", "..\RiderProjects\Skeleton\Skeleton.csproj", "{CB0ED85F-CAC0-4B53-96A8-16048A928890}"
|
||||
EndProject
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{36979A00-F434-4001-A80E-ECBF92A0AB5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{36979A00-F434-4001-A80E-ECBF92A0AB5E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{36979A00-F434-4001-A80E-ECBF92A0AB5E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{36979A00-F434-4001-A80E-ECBF92A0AB5E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{917762E5-D59D-4724-8F1A-73F739573E99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{917762E5-D59D-4724-8F1A-73F739573E99}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{917762E5-D59D-4724-8F1A-73F739573E99}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{917762E5-D59D-4724-8F1A-73F739573E99}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CB0ED85F-CAC0-4B53-96A8-16048A928890}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CB0ED85F-CAC0-4B53-96A8-16048A928890}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CB0ED85F-CAC0-4B53-96A8-16048A928890}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CB0ED85F-CAC0-4B53-96A8-16048A928890}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
7
global.json
Normal file
7
global.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "6.0.0",
|
||||
"rollForward": "latestMinor",
|
||||
"allowPrerelease": false
|
||||
}
|
||||
}
|
||||
26
src/Chemistry/Atoms/Implements/AAtom.cs
Normal file
26
src/Chemistry/Atoms/Implements/AAtom.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
/// <summary>
|
||||
/// atom 12
|
||||
/// </summary>
|
||||
public class AAtom : BaseAtom
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Element => ChemistryConstant.Elements.A;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int AtomicNumber => 12;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointState => ChemistryConstant.AtomAdjoints.AtomAdjointStateA;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelState => ChemistryConstant.AtomKernels.AtomKernelStateA;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => ChemistryConstant.AtomEigenStates.AtomEigenStateA;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override double AtomicMass => ChemistryConstant.AtomicMasses.AtomicMassA;
|
||||
}
|
||||
386
src/Chemistry/Atoms/Implements/BaseAtom.cs
Normal file
386
src/Chemistry/Atoms/Implements/BaseAtom.cs
Normal file
@@ -0,0 +1,386 @@
|
||||
using System.Text;
|
||||
using Skeleton.Algebra.AdditionalProperties.Extensions;
|
||||
using Skeleton.Algebra.DimensionProviders;
|
||||
using Skeleton.Constants;
|
||||
using Skeleton.DataStructure;
|
||||
using Skeleton.Utils.Helpers;
|
||||
using VirtualChemistry.Chemistry.Bonds.Implements;
|
||||
using VirtualChemistry.Chemistry.Bonds.Resolver;
|
||||
using VirtualChemistry.Chemistry.Compounds.Implements;
|
||||
using VirtualChemistry.Chemistry.Mixtures.Implements;
|
||||
using VirtualChemistry.Constants;
|
||||
using VirtualChemistry.DataStructure.Packs;
|
||||
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
/// <summary>
|
||||
/// meta atom
|
||||
/// </summary>
|
||||
public abstract class BaseAtom
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected BaseAtom()
|
||||
{
|
||||
LogEigenState = new(_ => EigenStateMatrix.Log());
|
||||
BondInformationMatrix = new(
|
||||
x => Bonds
|
||||
.Select(bond => bond.LogState.GetFrom(x))
|
||||
.DefaultIfEmpty(LieSU3.Zero)
|
||||
.SpLieSum()
|
||||
.Exp()
|
||||
);
|
||||
|
||||
LogKernelMatrix = new(_ => KernelState.Log());
|
||||
StateMatrix = new(x => BondInformationMatrix.GetFrom(x).ConjugateOn(EigenStateMatrix));
|
||||
LogStateMatrix = new(x => BondInformationMatrix.GetFrom(x).ConjugateOn(LogEigenState.GetFrom(x)));
|
||||
StructureMatrix = new(x =>
|
||||
{
|
||||
var h = Bonds
|
||||
.Select(b => b.LogConnectionMatrix.GetFrom(x))
|
||||
.DefaultIfEmpty(LieSU3.Zero)
|
||||
.Union(new[] { LogStateMatrix.GetFrom(x), LogKernelMatrix.GetFrom(x) });
|
||||
var s = h.SpLieSum().Exp();
|
||||
return s;
|
||||
}
|
||||
);
|
||||
|
||||
EnergyDistributionFactor = new CacheItem<double>(
|
||||
x =>
|
||||
{
|
||||
C3 v = StructureMatrix.GetFrom(x).Hermitian() * ChemistryConstant.AtomEnergyDistributionVector;
|
||||
return ChemistryConstant.AtomEnergyDistributionSpectrum.Rayleigh<IDim3>(v);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// singleton to represent no atom
|
||||
/// </summary>
|
||||
public static readonly BaseAtom Null = new NullAtom();
|
||||
/// <summary>
|
||||
/// energy holds in the atom
|
||||
/// </summary>
|
||||
public double Energy
|
||||
{
|
||||
get => Bonds.Sum(bond => bond.Energy);
|
||||
set
|
||||
{
|
||||
double energyFactor = Bonds.Sum(bond => bond.EnergyDistributionFactor.Get);
|
||||
foreach (BaseBond bond in Bonds)
|
||||
bond.Energy = value * bond.EnergyDistributionFactor.Get / energyFactor;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// describe how energy in molecular is distributed in this atom
|
||||
/// </summary>
|
||||
|
||||
|
||||
public CacheItem<double> EnergyDistributionFactor { get; }
|
||||
|
||||
/// <summary>
|
||||
/// element name/ atom name
|
||||
/// </summary>
|
||||
public abstract string Element { get; }
|
||||
/// <summary>
|
||||
/// atomic number, redundant information as element
|
||||
/// </summary>
|
||||
public abstract int AtomicNumber { get; }
|
||||
/// <summary>
|
||||
/// atomic mass, wont change as long as atomic number is fixed
|
||||
/// </summary>
|
||||
public abstract double AtomicMass { get; }
|
||||
/// <summary>
|
||||
/// compound of this atom
|
||||
/// </summary>
|
||||
public Compound Compound { get; set; } = Compound.Null;
|
||||
/// <summary>
|
||||
/// homogeneous mixture of its compound
|
||||
/// </summary>
|
||||
public HomogeneousMixture HomogeneousMixture => Compound.HomogeneousMixture;
|
||||
/// <summary>
|
||||
/// bonds
|
||||
/// </summary>
|
||||
public HashSet<BaseBond> Bonds { get; set; } = new HashSet<BaseBond>();
|
||||
/// <summary>
|
||||
/// bonds that already connected with other bond
|
||||
/// </summary>
|
||||
public IEnumerable<BaseBond> ConnectedBonds => Bonds.Where(x => x.Connected);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// bonds that not connected with any other bond yet
|
||||
/// </summary>
|
||||
public IEnumerable<BaseBond> UnconnectedBonds => Bonds.Where(x => !x.Connected);
|
||||
/// <summary>
|
||||
/// atoms that connected to this atom directly
|
||||
/// </summary>
|
||||
public IEnumerable<BaseAtom> ConnectedAtoms => ConnectedBonds
|
||||
.Select(bond => bond.ConnectedBond.Atom);
|
||||
/// <summary>
|
||||
/// mass of all directly connected atoms
|
||||
/// </summary>
|
||||
public double GroupMass => ConnectedAtoms
|
||||
.Select(atom => atom.AtomicMass)
|
||||
.DefaultIfEmpty(0d)
|
||||
.Sum();
|
||||
/// <summary>
|
||||
/// if there is a path to specific atom
|
||||
/// private use only
|
||||
/// </summary>
|
||||
/// <param name="atom"></param>
|
||||
/// <param name="visited"></param>
|
||||
/// <returns></returns>
|
||||
private bool HasPathTo(BaseAtom atom, HashSet<BaseAtom> visited)
|
||||
{
|
||||
if (atom == this)
|
||||
return true;
|
||||
if (ConnectedAtoms.Contains(atom))
|
||||
return true;
|
||||
visited.Add(this);
|
||||
return ConnectedAtoms
|
||||
.Where(connectedAtom => !visited.Contains(connectedAtom))
|
||||
.Any(connectedAtom => connectedAtom.HasPathTo(atom, visited));
|
||||
}
|
||||
/// <summary>
|
||||
/// if there is a path to a specific atom
|
||||
/// </summary>
|
||||
/// <param name="atom"></param>
|
||||
/// <returns></returns>
|
||||
public bool HasPathTo(BaseAtom atom) => HasPathTo(atom, new HashSet<BaseAtom>());
|
||||
/// <summary>
|
||||
/// get the compound by connections
|
||||
/// </summary>
|
||||
public Compound GrabCompound
|
||||
{
|
||||
get
|
||||
{
|
||||
Compound res = new ();
|
||||
res.Atoms.Add(this);
|
||||
int aCount = 0;
|
||||
while (aCount != res.Atoms.Count)
|
||||
{
|
||||
aCount = res.Atoms.Count;
|
||||
foreach (BaseAtom a in res.Atoms
|
||||
.SelectMany(a => a.ConnectedAtoms)
|
||||
.Where(a => !res.Atoms.Contains(a))
|
||||
.ToArray()
|
||||
)
|
||||
res.Atoms.Add(a);
|
||||
}
|
||||
|
||||
res.HomogeneousMixture = HomogeneousMixture.Null;
|
||||
res.Amount = 0d;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// how far is an atom from this one(directly connected atoms has distance 1)
|
||||
/// </summary>
|
||||
/// <param name="atom"></param>
|
||||
/// <param name="visited"></param>
|
||||
/// <returns></returns>
|
||||
private int DistanceTo(BaseAtom atom, HashSet<BaseAtom> visited)
|
||||
{
|
||||
if (Compound != atom.Compound)
|
||||
return -1;
|
||||
if (atom == this)
|
||||
return 0;
|
||||
if(Compound.CachedDistance(this, atom) > 0)
|
||||
return Compound.CachedDistance(this, atom);
|
||||
if (ConnectedAtoms.Contains(atom))
|
||||
return 1;
|
||||
visited.Add(this);
|
||||
int distance = ConnectedAtoms
|
||||
.Where(connectedAtom => !visited.Contains(connectedAtom))
|
||||
.Select(connectedAtom => connectedAtom.DistanceTo(atom, visited))
|
||||
.DefaultIfEmpty(int.MaxValue)
|
||||
.Min();
|
||||
Compound.CacheDistance(this, atom, distance + 1);
|
||||
return distance + 1;
|
||||
}
|
||||
/// <summary>
|
||||
/// how far is an atom from this one(directly connected atoms has distance 1)
|
||||
/// </summary>
|
||||
/// <param name="atom"></param>
|
||||
/// <returns></returns>
|
||||
public int DistanceTo(BaseAtom atom) => DistanceTo(atom, new HashSet<BaseAtom>());
|
||||
|
||||
/// <summary>
|
||||
/// all connections of this atom
|
||||
/// </summary>
|
||||
public IEnumerable<ConnectionInfo> Connections =>
|
||||
Bonds
|
||||
.Where(bond => bond.Connected)
|
||||
.Select(bond => new ConnectionInfo(bond, bond.ConnectedBond, bond.ConnectedBond.Atom));
|
||||
/// <summary>
|
||||
/// distance info as map
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private Dictionary<int, HashSet<BaseAtom>> DistanceMap()
|
||||
{
|
||||
Dictionary<int, HashSet<BaseAtom>> res = new Dictionary<int, HashSet<BaseAtom>>();
|
||||
foreach (BaseAtom atom in Compound.Atoms)
|
||||
{
|
||||
int dist = DistanceTo(atom);
|
||||
if(!res.ContainsKey(dist))
|
||||
res.Add(dist, new HashSet<BaseAtom>());
|
||||
res[dist].Add(atom);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// order bonds by selectors
|
||||
/// </summary>
|
||||
public IOrderedEnumerable<BaseBond> OrderedBonds =>
|
||||
Bonds
|
||||
.OrderBy(bond => bond.Connected)
|
||||
.ThenBy(bond => bond.BondNumber)
|
||||
.ThenBy(bond => bond.Connected ? bond.ConnectedBond.BondNumber : 0)
|
||||
.ThenBy(bond => bond.Connected ? bond.ConnectedBond.Atom.AtomicNumber : 0);
|
||||
/// <summary>
|
||||
/// kernel state matrix of the atom, wont change
|
||||
/// </summary>
|
||||
public abstract SU3 KernelState { get; }
|
||||
/// <summary>
|
||||
/// adj matrix wont change
|
||||
/// </summary>
|
||||
public abstract SU3 AdjointState { get; }
|
||||
/// <summary>
|
||||
/// eig matrix wont change
|
||||
/// </summary>
|
||||
public abstract SU3 EigenStateMatrix { get; }
|
||||
|
||||
/// <summary>
|
||||
/// will never expire
|
||||
/// </summary>
|
||||
public CacheItem<LieSU3> LogKernelMatrix { get; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public CacheItem<SU3> BondInformationMatrix { get; }
|
||||
|
||||
/// <summary>
|
||||
/// will never expire
|
||||
/// </summary>
|
||||
public CacheItem<LieSU3> LogEigenState { get; }
|
||||
|
||||
/// <summary>
|
||||
/// state matrix
|
||||
/// </summary>
|
||||
public CacheItem<SU3> StateMatrix { get; }
|
||||
|
||||
/// <summary>
|
||||
/// log state matrix
|
||||
/// </summary>
|
||||
public CacheItem<LieSU3> LogStateMatrix { get; }
|
||||
|
||||
/// <summary>
|
||||
/// get an unconnected bond of specific type
|
||||
/// </summary>
|
||||
/// <param name="bondType"></param>
|
||||
/// <returns></returns>
|
||||
public BaseBond NextUnconnected(string bondType) =>
|
||||
Bonds
|
||||
.Where(bond => bond.BondType == bondType)
|
||||
.FirstOrDefault(bond => !bond.Connected, BaseBond.Null);
|
||||
/// <summary>
|
||||
/// get an unconnected bond of specific type, except for bonds in exclude set
|
||||
/// </summary>
|
||||
/// <param name="bondType"></param>
|
||||
/// <param name="exclude"></param>
|
||||
/// <returns></returns>
|
||||
public BaseBond NextUnconnected(string bondType, HashSet<BaseBond> exclude) =>
|
||||
Bonds
|
||||
.Where(bond => bond.BondType == bondType)
|
||||
.Where(bond => !exclude.Contains(bond))
|
||||
.FirstOrDefault(bond => !bond.Connected, BaseBond.Null);
|
||||
/// <summary>
|
||||
/// get an unconnected bond of specific type that is not the excluded bond
|
||||
/// </summary>
|
||||
/// <param name="bondType"></param>
|
||||
/// <param name="exclude"></param>
|
||||
/// <returns></returns>
|
||||
public BaseBond NextUnconnected(string bondType, BaseBond exclude) =>
|
||||
Bonds
|
||||
.Where(bond => bond.BondType == bondType)
|
||||
.Where(bond => exclude != bond)
|
||||
.FirstOrDefault(bond => !bond.Connected, BaseBond.Null);
|
||||
|
||||
/// <summary>
|
||||
/// structure matrix
|
||||
/// </summary>
|
||||
public CacheItem<SU3> StructureMatrix { get; }
|
||||
|
||||
/// <summary>
|
||||
/// the representation of the compound relative to a center atom
|
||||
/// </summary>
|
||||
/// <param name="center"></param>
|
||||
/// <param name="visited"></param>
|
||||
/// <returns></returns>
|
||||
public StringBuilder IsoRepresentation(BaseAtom center, HashSet<BaseBond> visited)
|
||||
{
|
||||
HashSet<BaseBond> toVisit = Bonds
|
||||
.Where(b => b.Connected)
|
||||
.Where(b => !visited.Contains(b))
|
||||
.Where(b => !visited.Contains(b.ConnectedBond))
|
||||
.ToHashSet();
|
||||
foreach (BaseBond b in toVisit)
|
||||
{
|
||||
visited.Add(b);
|
||||
visited.Add(b.ConnectedBond);
|
||||
|
||||
}
|
||||
|
||||
Dictionary<BaseBond, StringBuilder> subRepresentations = new ();
|
||||
foreach (BaseBond b in toVisit)
|
||||
subRepresentations[b] =
|
||||
b.ConnectedBond.Atom.IsoRepresentation(center, new HashSet<BaseBond>(visited));
|
||||
|
||||
StringBuilder res = new StringBuilder($"{Element}#{DistanceTo(center)}-[");
|
||||
IEnumerable<BaseBond> visitOrder = toVisit
|
||||
.GroupedOrderBy(bond => bond.BondNumber)
|
||||
.GroupedThenBy(bond => bond.ConnectedBond.BondNumber)
|
||||
.GroupedThenBy(bond => bond.ConnectedBond.Atom.AtomicNumber)
|
||||
.GroupedThenBy(bond => bond.ConnectedBond.Atom.ConnectedAtoms.Count())
|
||||
.GroupedThenBy(bond => subRepresentations[bond].ToString())
|
||||
.SelectMany(g => g);
|
||||
foreach (BaseBond b in visitOrder)
|
||||
{
|
||||
res.Append($"<{b.BondType}={b.ConnectedBond.BondType}*");
|
||||
res.Append(subRepresentations[b]);
|
||||
res.Append(">");
|
||||
}
|
||||
res.Append("]");
|
||||
|
||||
return res;
|
||||
}
|
||||
/// <summary>
|
||||
/// the representation of the compound with this atom as center
|
||||
/// </summary>
|
||||
public string FullRepresentation => IsoRepresentation(this, new HashSet<BaseBond>()).ToString();
|
||||
/// <summary>
|
||||
/// initializer
|
||||
/// </summary>
|
||||
public void C()
|
||||
{
|
||||
Bonds = new HashSet<BaseBond>();
|
||||
for (int bondNumber = 1; bondNumber <= 7; bondNumber++)
|
||||
{
|
||||
int xDiff = AtomicNumber - AlgebraConstant.Ludic(bondNumber);
|
||||
if (AtomicNumber % AlgebraConstant.Ludic(bondNumber) != 0 &&
|
||||
(xDiff < 0 || xDiff % 7 != 0))
|
||||
continue;
|
||||
for (int idx = 0; idx < ChemistryConstant.BondMaxNumbers(bondNumber); idx++)
|
||||
Bonds.Add(BondResolver.Resolve(bondNumber));
|
||||
}
|
||||
|
||||
foreach (BaseBond b in Bonds)
|
||||
b.Atom = this;
|
||||
}
|
||||
|
||||
}
|
||||
27
src/Chemistry/Atoms/Implements/CxAtom.cs
Normal file
27
src/Chemistry/Atoms/Implements/CxAtom.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
|
||||
/// <summary>
|
||||
/// atom # 13
|
||||
/// </summary>
|
||||
public class CxAtom : BaseAtom
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Element => ChemistryConstant.Elements.Cx;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int AtomicNumber => 13;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointState => ChemistryConstant.AtomAdjoints.AtomAdjointStateCx;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelState => ChemistryConstant.AtomKernels.AtomKernelStateCx;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => ChemistryConstant.AtomEigenStates.AtomEigenStateCx;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override double AtomicMass => ChemistryConstant.AtomicMasses.AtomicMassCx;
|
||||
}
|
||||
27
src/Chemistry/Atoms/Implements/DAtom.cs
Normal file
27
src/Chemistry/Atoms/Implements/DAtom.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
|
||||
/// <summary>
|
||||
/// atom # 4
|
||||
/// </summary>
|
||||
public class DAtom : BaseAtom
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Element => ChemistryConstant.Elements.D;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int AtomicNumber => 4;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointState => ChemistryConstant.AtomAdjoints.AtomAdjointStateD;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelState => ChemistryConstant.AtomKernels.AtomKernelStateD;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => ChemistryConstant.AtomEigenStates.AtomEigenStateD;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override double AtomicMass => ChemistryConstant.AtomicMasses.AtomicMassD;
|
||||
}
|
||||
26
src/Chemistry/Atoms/Implements/EAtom.cs
Normal file
26
src/Chemistry/Atoms/Implements/EAtom.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
/// <summary>
|
||||
/// atom # 10
|
||||
/// </summary>
|
||||
public class EAtom : BaseAtom
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Element => ChemistryConstant.Elements.E;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int AtomicNumber => 10;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointState => ChemistryConstant.AtomAdjoints.AtomAdjointStateE;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelState => ChemistryConstant.AtomKernels.AtomKernelStateE;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => ChemistryConstant.AtomEigenStates.AtomEigenStateE;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override double AtomicMass => ChemistryConstant.AtomicMasses.AtomicMassE;
|
||||
}
|
||||
26
src/Chemistry/Atoms/Implements/EsAtom.cs
Normal file
26
src/Chemistry/Atoms/Implements/EsAtom.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
/// <summary>
|
||||
/// atom # 3
|
||||
/// </summary>
|
||||
public class EsAtom : BaseAtom
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Element => ChemistryConstant.Elements.Es;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int AtomicNumber => 3;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointState => ChemistryConstant.AtomAdjoints.AtomAdjointStateEs;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelState => ChemistryConstant.AtomKernels.AtomKernelStateEs;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => ChemistryConstant.AtomEigenStates.AtomEigenStateEs;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override double AtomicMass => ChemistryConstant.AtomicMasses.AtomicMassEs;
|
||||
}
|
||||
27
src/Chemistry/Atoms/Implements/KAtom.cs
Normal file
27
src/Chemistry/Atoms/Implements/KAtom.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
|
||||
/// <summary>
|
||||
/// atom # 7
|
||||
/// </summary>
|
||||
public class KAtom : BaseAtom
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Element => ChemistryConstant.Elements.K;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int AtomicNumber => 7;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointState => ChemistryConstant.AtomAdjoints.AtomAdjointStateK;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelState => ChemistryConstant.AtomKernels.AtomKernelStateK;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => ChemistryConstant.AtomEigenStates.AtomEigenStateK;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override double AtomicMass => ChemistryConstant.AtomicMasses.AtomicMassK;
|
||||
}
|
||||
27
src/Chemistry/Atoms/Implements/MAtom.cs
Normal file
27
src/Chemistry/Atoms/Implements/MAtom.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
|
||||
/// <summary>
|
||||
/// atom # 6
|
||||
/// </summary>
|
||||
public class MAtom : BaseAtom
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Element => ChemistryConstant.Elements.M;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int AtomicNumber => 6;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointState => ChemistryConstant.AtomAdjoints.AtomAdjointStateM;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelState => ChemistryConstant.AtomKernels.AtomKernelStateM;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => ChemistryConstant.AtomEigenStates.AtomEigenStateM;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override double AtomicMass => ChemistryConstant.AtomicMasses.AtomicMassM;
|
||||
}
|
||||
30
src/Chemistry/Atoms/Implements/NullAtom.cs
Normal file
30
src/Chemistry/Atoms/Implements/NullAtom.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
namespace VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
|
||||
/// <summary>
|
||||
/// atom # -1, the atom used to represent no atom
|
||||
/// </summary>
|
||||
public sealed class NullAtom : BaseAtom
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public NullAtom()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Element => "Null";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int AtomicNumber => throw new Exception();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override double AtomicMass => throw new Exception();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelState => throw new Exception();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointState => throw new Exception();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => throw new Exception();
|
||||
}
|
||||
27
src/Chemistry/Atoms/Implements/PAtom.cs
Normal file
27
src/Chemistry/Atoms/Implements/PAtom.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
|
||||
/// <summary>
|
||||
/// atom # 8
|
||||
/// </summary>
|
||||
public class PAtom : BaseAtom
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Element => ChemistryConstant.Elements.P;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int AtomicNumber => 8;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointState => ChemistryConstant.AtomAdjoints.AtomAdjointStateP;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelState => ChemistryConstant.AtomKernels.AtomKernelStateP;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => ChemistryConstant.AtomEigenStates.AtomEigenStateP;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override double AtomicMass => ChemistryConstant.AtomicMasses.AtomicMassP;
|
||||
}
|
||||
26
src/Chemistry/Atoms/Implements/QAtom.cs
Normal file
26
src/Chemistry/Atoms/Implements/QAtom.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
/// <summary>
|
||||
/// atom # 1
|
||||
/// </summary>
|
||||
public class QAtom : BaseAtom
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Element => ChemistryConstant.Elements.Q;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int AtomicNumber => 1;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointState => ChemistryConstant.AtomAdjoints.AtomAdjointStateQ;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelState => ChemistryConstant.AtomKernels.AtomKernelStateQ;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => ChemistryConstant.AtomEigenStates.AtomEigenStateQ;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override double AtomicMass => ChemistryConstant.AtomicMasses.AtomicMassQ;
|
||||
}
|
||||
26
src/Chemistry/Atoms/Implements/RAtom.cs
Normal file
26
src/Chemistry/Atoms/Implements/RAtom.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
/// <summary>
|
||||
/// atom # 2
|
||||
/// </summary>
|
||||
public class RAtom : BaseAtom
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Element => ChemistryConstant.Elements.R;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int AtomicNumber => 2;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointState => ChemistryConstant.AtomAdjoints.AtomAdjointStateR;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelState => ChemistryConstant.AtomKernels.AtomKernelStateR;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => ChemistryConstant.AtomEigenStates.AtomEigenStateR;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override double AtomicMass => ChemistryConstant.AtomicMasses.AtomicMassR;
|
||||
}
|
||||
26
src/Chemistry/Atoms/Implements/SoAtom.cs
Normal file
26
src/Chemistry/Atoms/Implements/SoAtom.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
/// <summary>
|
||||
/// atom # 9
|
||||
/// </summary>
|
||||
public class SoAtom : BaseAtom
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Element => ChemistryConstant.Elements.So;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int AtomicNumber => 9;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointState => ChemistryConstant.AtomAdjoints.AtomAdjointStateSo;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelState => ChemistryConstant.AtomKernels.AtomKernelStateSo;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => ChemistryConstant.AtomEigenStates.AtomEigenStateSo;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override double AtomicMass => ChemistryConstant.AtomicMasses.AtomicMassSo;
|
||||
}
|
||||
27
src/Chemistry/Atoms/Implements/UAtom.cs
Normal file
27
src/Chemistry/Atoms/Implements/UAtom.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
|
||||
/// <summary>
|
||||
/// atom # 11
|
||||
/// </summary>
|
||||
public class UAtom : BaseAtom
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Element => ChemistryConstant.Elements.U;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int AtomicNumber => 11;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointState => ChemistryConstant.AtomAdjoints.AtomAdjointStateU;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelState => ChemistryConstant.AtomKernels.AtomKernelStateU;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => ChemistryConstant.AtomEigenStates.AtomEigenStateU;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override double AtomicMass => ChemistryConstant.AtomicMasses.AtomicMassU;
|
||||
}
|
||||
27
src/Chemistry/Atoms/Implements/UeAtom.cs
Normal file
27
src/Chemistry/Atoms/Implements/UeAtom.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
|
||||
/// <summary>
|
||||
/// atom # 5
|
||||
/// </summary>
|
||||
public class UeAtom : BaseAtom
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Element => ChemistryConstant.Elements.Ue;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int AtomicNumber => 5;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointState => ChemistryConstant.AtomAdjoints.AtomAdjointStateUe;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelState => ChemistryConstant.AtomKernels.AtomKernelStateUe;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => ChemistryConstant.AtomEigenStates.AtomEigenStateUe;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override double AtomicMass => ChemistryConstant.AtomicMasses.AtomicMassUe;
|
||||
}
|
||||
26
src/Chemistry/Atoms/Implements/VAtom.cs
Normal file
26
src/Chemistry/Atoms/Implements/VAtom.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
/// <summary>
|
||||
/// atom # 14
|
||||
/// </summary>
|
||||
public class VAtom : BaseAtom
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Element => ChemistryConstant.Elements.V;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int AtomicNumber => 14;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointState => ChemistryConstant.AtomAdjoints.AtomAdjointStateV;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelState => ChemistryConstant.AtomKernels.AtomKernelStateV;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => ChemistryConstant.AtomEigenStates.AtomEigenStateV;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override double AtomicMass => ChemistryConstant.AtomicMasses.AtomicMassV;
|
||||
}
|
||||
27
src/Chemistry/Atoms/Implements/ViAtom.cs
Normal file
27
src/Chemistry/Atoms/Implements/ViAtom.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
|
||||
/// <summary>
|
||||
/// atom # 15
|
||||
/// </summary>
|
||||
public class ViAtom : BaseAtom
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Element => ChemistryConstant.Elements.Vi;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int AtomicNumber => 15;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointState => ChemistryConstant.AtomAdjoints.AtomAdjointStateVi;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelState => ChemistryConstant.AtomKernels.AtomKernelStateVi;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => ChemistryConstant.AtomEigenStates.AtomEigenStateVi;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override double AtomicMass => ChemistryConstant.AtomicMasses.AtomicMassVi;
|
||||
}
|
||||
72
src/Chemistry/Atoms/Resolver/AtomResolver.cs
Normal file
72
src/Chemistry/Atoms/Resolver/AtomResolver.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Atoms.Resolver;
|
||||
|
||||
/// <summary>
|
||||
/// get an atom instance from descriptions
|
||||
/// </summary>
|
||||
public static class AtomResolver
|
||||
{
|
||||
/// <summary>
|
||||
/// create an atom from string
|
||||
/// </summary>
|
||||
/// <param name="element"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public static BaseAtom Resolve(string element)
|
||||
{
|
||||
BaseAtom res = element switch
|
||||
{
|
||||
ChemistryConstant.Elements.Q => new QAtom(),
|
||||
ChemistryConstant.Elements.R => new RAtom(),
|
||||
ChemistryConstant.Elements.Es => new EsAtom(),
|
||||
ChemistryConstant.Elements.D => new DAtom(),
|
||||
ChemistryConstant.Elements.Ue => new UeAtom(),
|
||||
ChemistryConstant.Elements.M => new MAtom(),
|
||||
ChemistryConstant.Elements.K => new KAtom(),
|
||||
ChemistryConstant.Elements.P => new PAtom(),
|
||||
ChemistryConstant.Elements.So => new SoAtom(),
|
||||
ChemistryConstant.Elements.E => new EAtom(),
|
||||
ChemistryConstant.Elements.U => new UAtom(),
|
||||
ChemistryConstant.Elements.A => new AAtom(),
|
||||
ChemistryConstant.Elements.Cx => new CxAtom(),
|
||||
ChemistryConstant.Elements.V => new VAtom(),
|
||||
ChemistryConstant.Elements.Vi => new ViAtom(),
|
||||
_ => throw new Exception($"TODO-----{element}")
|
||||
};
|
||||
res.C();
|
||||
return res;
|
||||
}
|
||||
/// <summary>
|
||||
/// create an atom by number
|
||||
/// </summary>
|
||||
/// <param name="atomicNumber"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public static BaseAtom Resolve(int atomicNumber)
|
||||
{
|
||||
BaseAtom res = atomicNumber switch
|
||||
{
|
||||
1 => new QAtom(),
|
||||
2 => new RAtom(),
|
||||
3 => new EsAtom(),
|
||||
4 => new DAtom(),
|
||||
5 => new UeAtom(),
|
||||
6 => new MAtom(),
|
||||
7 => new KAtom(),
|
||||
8 => new PAtom(),
|
||||
9 => new SoAtom(),
|
||||
10 => new EAtom(),
|
||||
11 => new UAtom(),
|
||||
12 => new AAtom(),
|
||||
13 => new CxAtom(),
|
||||
14 => new VAtom(),
|
||||
15 => new ViAtom(),
|
||||
_ => throw new Exception("TODO")
|
||||
};
|
||||
res.C();
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
318
src/Chemistry/Bonds/Implements/BaseBond.cs
Normal file
318
src/Chemistry/Bonds/Implements/BaseBond.cs
Normal file
@@ -0,0 +1,318 @@
|
||||
using Skeleton.Algebra.AdditionalProperties.Extensions;
|
||||
using Skeleton.Algebra.DimensionProviders;
|
||||
using Skeleton.Algebra.Extensions;
|
||||
using Skeleton.DataStructure;
|
||||
using VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
using VirtualChemistry.Chemistry.Compounds.Implements;
|
||||
using VirtualChemistry.Chemistry.Mixtures.Implements;
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Bonds.Implements;
|
||||
/// <summary>
|
||||
/// meta bond
|
||||
/// </summary>
|
||||
public abstract class BaseBond
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected BaseBond()
|
||||
{
|
||||
StateMatrix = new (_ =>
|
||||
Connected ? EigenStateMatrix * ConnectedBond.EigenStateMatrix : EigenStateMatrix
|
||||
);
|
||||
LogKernel = new (_ => KernelStateMatrix.Log());
|
||||
HalfBondInformation = new(x =>
|
||||
LogKernel.GetFrom(x) + Atom.StructureMatrix.GetFrom(x).Log()
|
||||
);
|
||||
StructureMatrix = new(x =>
|
||||
(HalfBondInformation.GetFrom(x) + (Connected ? ConnectedBond.HalfBondInformation.GetFrom(x) : LieSU3.Zero))
|
||||
.Exp()
|
||||
);
|
||||
EnergyDistributionFactor = new(x =>
|
||||
{
|
||||
C3 v = StructureMatrix.GetFrom(x).Hermitian() * ChemistryConstant.BondEnergyDistributionVector;
|
||||
return ChemistryConstant.BondEnergyDistributionSpectrum.Rayleigh<IDim3>(v);
|
||||
}
|
||||
);
|
||||
LogConnectionMatrix = new(x => Connected
|
||||
? (AdjointStateMatrix * ConnectedBond.AdjointStateMatrix)
|
||||
.ConjugateOn(Atom.LogKernelMatrix.GetFrom(x))
|
||||
: LieSU3.Zero
|
||||
);
|
||||
LogState = new (x => StateMatrix.GetFrom(x).Log());
|
||||
AntibondingCatalyzeFactor = new(x =>
|
||||
{
|
||||
if (Connected || HomogeneousMixture == HomogeneousMixture.Null)
|
||||
return 0;
|
||||
U3 s = LogState.GetFrom(x).CayleyPositive();
|
||||
LieSU3 f0 = HomogeneousMixture.LogStateMatrix.GetFrom(x).ConjugatedBy<IDim3, LieSU3>(s);
|
||||
LieSU3 f1 = f0 ^ LogState.GetFrom(x);
|
||||
U3 f2 = f1.CayleyNegative();
|
||||
return f2.Det().Imaginary;
|
||||
}
|
||||
);
|
||||
BondingCatalyzeFactor = new(x =>
|
||||
{
|
||||
if (!Connected || HomogeneousMixture == HomogeneousMixture.Null)
|
||||
return 0;
|
||||
U3 s = LogState.GetFrom(x).CayleyNegative();
|
||||
LieSU3 f0 = HomogeneousMixture.LogStateMatrix.GetFrom(x).ConjugatedBy<IDim3, LieSU3>(s);
|
||||
LieSU3 f1 = f0 ^ LogState.GetFrom(x);
|
||||
U3 f2 = f1.CayleyPositive();
|
||||
return f2.Det().Imaginary;
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Compound Compound => Atom.Compound;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public HomogeneousMixture HomogeneousMixture => Compound.HomogeneousMixture;
|
||||
/// <summary>
|
||||
/// null singleton
|
||||
/// </summary>
|
||||
public static readonly BaseBond Null = new NullBond();
|
||||
/// <summary>
|
||||
/// energy hold in this atom
|
||||
/// </summary>
|
||||
public double Energy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// how energy in the molecular is distributed into this atom
|
||||
/// </summary>
|
||||
public CacheItem<double> EnergyDistributionFactor { get; }
|
||||
|
||||
/// <summary>
|
||||
/// the connected bond
|
||||
/// </summary>
|
||||
public BaseBond ConnectedBond { get; set; } = Null;
|
||||
/// <summary>
|
||||
/// atom that holds this bond
|
||||
/// </summary>
|
||||
public BaseAtom Atom { get; set; } = BaseAtom.Null;
|
||||
/// <summary>
|
||||
/// type of the bond
|
||||
/// </summary>
|
||||
public abstract string BondType { get; }
|
||||
/// <summary>
|
||||
/// kernel state matrix of the matrix, won't change as long as bond type is fixed
|
||||
/// </summary>
|
||||
public abstract SU3 KernelStateMatrix { get; }
|
||||
/// <summary>
|
||||
/// adj state matrix of the bond, won't change as long as bond type fixed
|
||||
/// </summary>
|
||||
public abstract SU3 AdjointStateMatrix { get; }
|
||||
/// <summary>
|
||||
/// eigen state matrix of bond, won't change as long as bond type fixed
|
||||
/// </summary>
|
||||
public abstract SU3 EigenStateMatrix { get; }
|
||||
|
||||
/// <summary>
|
||||
/// log of the kernel state matrix
|
||||
/// never expire
|
||||
/// </summary>
|
||||
public CacheItem<LieSU3> LogKernel { get; }
|
||||
|
||||
/// <summary>
|
||||
/// skew hermitian matrix that represent the information of bond and its atom
|
||||
/// </summary>
|
||||
public CacheItem<LieSU3> HalfBondInformation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// special unitary matrix that represent the structure of the bond(its atom, connected bond and atom of connected bond)
|
||||
/// </summary>
|
||||
public CacheItem<SU3> StructureMatrix { get; }
|
||||
|
||||
/// <summary>
|
||||
/// log of connection matrix
|
||||
/// </summary>
|
||||
public CacheItem<LieSU3> LogConnectionMatrix { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// a special unitary matrix that represent the state of the bond
|
||||
/// </summary>
|
||||
|
||||
|
||||
public CacheItem<SU3> StateMatrix { get; }
|
||||
|
||||
/// <summary>
|
||||
/// log of state matrix
|
||||
/// </summary>
|
||||
public CacheItem<LieSU3> LogState { get; }
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// connect with another bond
|
||||
/// </summary>
|
||||
/// <param name="bond"></param>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public void Connect(BaseBond bond)
|
||||
{
|
||||
if(Connected || bond.Connected)
|
||||
return;
|
||||
if(Atom.HomogeneousMixture != HomogeneousMixture.Null)
|
||||
if (!Atom.Compound.Amount.IsEqualApprox(bond.Atom.Compound.Amount))
|
||||
return;
|
||||
if (bond == this)
|
||||
throw new Exception("TODO");
|
||||
ConnectedBond = bond;
|
||||
bond.ConnectedBond = this;
|
||||
StructureChanged();
|
||||
bond.StructureChanged();
|
||||
if (Atom.Compound.Atoms.Contains(bond.Atom))
|
||||
return;
|
||||
bond.Atom.HomogeneousMixture.Compounds.Remove(bond.Atom.Compound);
|
||||
bond.Atom.Compound.Amount = 0d;
|
||||
|
||||
foreach (BaseAtom atom in bond.Atom.Compound.Atoms.ToHashSet())
|
||||
{
|
||||
Atom.Compound.Atoms.Add(atom);
|
||||
atom.Compound = Atom.Compound;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// disconnect with connected bond
|
||||
/// </summary>
|
||||
public void Disconnect()
|
||||
{
|
||||
if (!Connected)
|
||||
return;
|
||||
BaseBond disconnectedBond = ConnectedBond;
|
||||
ConnectedBond = BaseBond.Null;
|
||||
disconnectedBond.ConnectedBond = BaseBond.Null;
|
||||
StructureChanged();
|
||||
disconnectedBond.StructureChanged();
|
||||
if (Atom.HasPathTo(disconnectedBond.Atom))
|
||||
return;
|
||||
Compound newCompound = disconnectedBond.Atom.GrabCompound;
|
||||
newCompound.Amount = Atom.Compound.Amount;
|
||||
|
||||
/*
|
||||
newCompound.HomogeneousMixture = Atom.HomogeneousMixture;*/
|
||||
foreach (BaseAtom atom in newCompound.Atoms)
|
||||
{
|
||||
atom.Compound = newCompound;
|
||||
if (Atom.Compound.Atoms.Contains(atom))
|
||||
Atom.Compound.Atoms.Remove(atom);
|
||||
}
|
||||
Atom.HomogeneousMixture.AddCompound(newCompound);
|
||||
}
|
||||
/// <summary>
|
||||
/// if the bond is connected
|
||||
/// </summary>
|
||||
public bool Connected => ConnectedBond != Null;
|
||||
/// <summary>
|
||||
/// bond number, redundant information of bond type
|
||||
/// </summary>
|
||||
public abstract int BondNumber { get; }
|
||||
private void StructureChanged()
|
||||
{
|
||||
//Atom.Compound.ResetDistanceCache();
|
||||
Atom.Compound.CacheInit();
|
||||
HalfBondInformation.Expire();
|
||||
StateMatrix.Expire();
|
||||
LogConnectionMatrix.Expire();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Conditions for a pair of unconnected bonds tp connect:
|
||||
/// 1. Energy difference of the two bond is less than a threshold
|
||||
/// 2. Energy in both bonds is higher than bonding energy
|
||||
///
|
||||
/// if bond is connected, the antibonding energy is NaN
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public double EigenBondingEnergy()
|
||||
{
|
||||
if (Connected)
|
||||
return double.NaN;
|
||||
SU3 s1 = StructureMatrix.Get * Atom.StructureMatrix.Get;
|
||||
C33 s2 = StructureMatrix.Get + Atom.StructureMatrix.Get;
|
||||
double lowerLimit = -Math.PI;
|
||||
double upperLimit = Math.PI;
|
||||
C3 coVector = s2.Hermitian().ColumnAverage;
|
||||
return s1
|
||||
.ConjugateOn(new DiagR3(lowerLimit, 0d, upperLimit))
|
||||
.Rayleigh(coVector);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Conditions for a connected bond to break:
|
||||
/// 1. energy difference of two connected bond is greater than a threshold
|
||||
/// 2. energy in either bond is higher than antibonding energy
|
||||
///
|
||||
/// if bond is unconnected, the antibonding energy is
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public double EigenAntibondingEnergy()
|
||||
{
|
||||
if(!Connected)
|
||||
return double.NaN;
|
||||
SU3 s1 = Atom.StructureMatrix.Get.Hermitian() * StructureMatrix.Get;
|
||||
SU3 s2 = ConnectedBond.Atom.StructureMatrix.Get.Hermitian() * ConnectedBond.StructureMatrix.Get;
|
||||
C33 sw = s1 + s2;
|
||||
SU3 w = (s1.Log() + s2.Log()).Exp();
|
||||
C3 coVector = sw.ColumnAverageBivariant;
|
||||
double upperLimit = -Math.PI;
|
||||
double lowerLimit = Math.PI;
|
||||
return w
|
||||
.ConjugateOn(new DiagR3(lowerLimit, 0d, upperLimit))
|
||||
.Rayleigh(coVector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// how antibonding energy affected by mixture
|
||||
/// </summary>
|
||||
public CacheItem<double> AntibondingCatalyzeFactor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// hot bonding energy affected by chemical environment
|
||||
/// </summary>
|
||||
public CacheItem<double> BondingCatalyzeFactor { get; set; }
|
||||
|
||||
public double BondingEnergy => EigenBondingEnergy() + BondingCatalyzeFactor.Get;
|
||||
public double AntiBondingEnergy => EigenAntibondingEnergy() + AntibondingCatalyzeFactor.Get;
|
||||
|
||||
/// <summary>
|
||||
/// how to pair bonds
|
||||
/// </summary>
|
||||
public int BondingGroup
|
||||
{
|
||||
get
|
||||
{
|
||||
U3 sP = HalfBondInformation.Get.CayleyPositive();
|
||||
U3 eN = HomogeneousMixture.LogStateMatrix.Get.CayleyNegative();
|
||||
DiagR3 h = new(0, Math.PI, Math.PI * 2);
|
||||
U3 w = sP * eN;
|
||||
double t = w.ConjugateOn(h).Rayleigh(sP.ColumnAverageBivariant);
|
||||
/*
|
||||
//Complex t = (sP * eN).Trace();// + eN.Trace() * eN.Trace();
|
||||
C33 a1 = sP * eN;
|
||||
C33 a2 = eN * sP;
|
||||
C33 w = a1 - a2;
|
||||
Complex t = (w).Det() + a1.Trace() + a2.Trace();// * (eN*sP ).Trace();// * EigenStateMatrix.Trace();*/
|
||||
//Console.WriteLine($"TRACE {t} -");
|
||||
|
||||
return t switch
|
||||
{
|
||||
> 7 * Math.PI / 4 or < Math.PI / 4 => 0,
|
||||
> Math.PI / 4 and < 3 * Math.PI / 4 => 1,
|
||||
> 3 * Math.PI / 4 and < 5 * Math.PI / 4 => 2,
|
||||
_ => 3
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
23
src/Chemistry/Bonds/Implements/DBond.cs
Normal file
23
src/Chemistry/Bonds/Implements/DBond.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Bonds.Implements;
|
||||
/// <summary>
|
||||
/// bond # 3
|
||||
/// </summary>
|
||||
public class DBond : BaseBond
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string BondType => ChemistryConstant.BondTypes.D;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int BondNumber => 3;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelStateMatrix => ChemistryConstant.BondKernels.BondKernelD;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointStateMatrix => ChemistryConstant.BondAdjoints.BondAdjointD;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => ChemistryConstant.BondEigenStates.BondEigenStateD;
|
||||
}
|
||||
24
src/Chemistry/Bonds/Implements/HBond.cs
Normal file
24
src/Chemistry/Bonds/Implements/HBond.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Bonds.Implements;
|
||||
|
||||
/// <summary>
|
||||
/// bond # 7
|
||||
/// </summary>
|
||||
public class HBond : BaseBond
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string BondType => ChemistryConstant.BondTypes.H;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int BondNumber => 7;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelStateMatrix => ChemistryConstant.BondKernels.BondKernelH;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointStateMatrix => ChemistryConstant.BondAdjoints.BondAdjointH;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => ChemistryConstant.BondEigenStates.BondEigenStateH;
|
||||
}
|
||||
25
src/Chemistry/Bonds/Implements/MBond.cs
Normal file
25
src/Chemistry/Bonds/Implements/MBond.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Bonds.Implements;
|
||||
|
||||
/// <summary>
|
||||
/// bond # 1
|
||||
/// </summary>
|
||||
public class MBond : BaseBond
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string BondType => ChemistryConstant.BondTypes.M;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int BondNumber => 1;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelStateMatrix => ChemistryConstant.BondKernels.BondKernelM;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointStateMatrix => ChemistryConstant.BondAdjoints.BondAdjointM;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => ChemistryConstant.BondEigenStates.BondEigenStateM;
|
||||
|
||||
}
|
||||
27
src/Chemistry/Bonds/Implements/NullBond.cs
Normal file
27
src/Chemistry/Bonds/Implements/NullBond.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
namespace VirtualChemistry.Chemistry.Bonds.Implements;
|
||||
|
||||
/// <summary>
|
||||
/// bond singleton that represent no bond
|
||||
/// </summary>
|
||||
public class NullBond : BaseBond
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public NullBond()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string BondType => throw new Exception();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelStateMatrix => throw new Exception();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointStateMatrix => throw new Exception();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => throw new Exception();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int BondNumber => throw new Exception();
|
||||
}
|
||||
24
src/Chemistry/Bonds/Implements/PBond.cs
Normal file
24
src/Chemistry/Bonds/Implements/PBond.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Bonds.Implements;
|
||||
|
||||
/// <summary>
|
||||
/// bond # 6
|
||||
/// </summary>
|
||||
public class PBond : BaseBond
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string BondType => ChemistryConstant.BondTypes.P;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int BondNumber => 6;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelStateMatrix => ChemistryConstant.BondKernels.BondKernelP;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointStateMatrix => ChemistryConstant.BondAdjoints.BondAdjointP;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => ChemistryConstant.BondEigenStates.BondEigenStateP;
|
||||
}
|
||||
25
src/Chemistry/Bonds/Implements/QBond.cs
Normal file
25
src/Chemistry/Bonds/Implements/QBond.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Bonds.Implements;
|
||||
|
||||
/// <summary>
|
||||
/// bond # 5
|
||||
/// </summary>
|
||||
public class QBond : BaseBond
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string BondType => ChemistryConstant.BondTypes.Q;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int BondNumber => 5;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelStateMatrix => ChemistryConstant.BondKernels.BondKernelQ;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointStateMatrix => ChemistryConstant.BondAdjoints.BondAdjointQ;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => ChemistryConstant.BondEigenStates.BondEigenStateQ;
|
||||
|
||||
}
|
||||
24
src/Chemistry/Bonds/Implements/SBond.cs
Normal file
24
src/Chemistry/Bonds/Implements/SBond.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Bonds.Implements;
|
||||
|
||||
/// <summary>
|
||||
/// bond # 2
|
||||
/// </summary>
|
||||
public class SBond : BaseBond
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string BondType => ChemistryConstant.BondTypes.S;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int BondNumber => 2;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelStateMatrix => ChemistryConstant.BondKernels.BondKernelS;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointStateMatrix => ChemistryConstant.BondAdjoints.BondAdjointS;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => ChemistryConstant.BondEigenStates.BondEigenStateS;
|
||||
}
|
||||
24
src/Chemistry/Bonds/Implements/YBond.cs
Normal file
24
src/Chemistry/Bonds/Implements/YBond.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Bonds.Implements;
|
||||
|
||||
/// <summary>
|
||||
/// bond # 4
|
||||
/// </summary>
|
||||
public class YBond : BaseBond
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string BondType => ChemistryConstant.BondTypes.Y;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int BondNumber => 4;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 KernelStateMatrix => ChemistryConstant.BondKernels.BondKernelY;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 AdjointStateMatrix => ChemistryConstant.BondAdjoints.BondAdjointY;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override SU3 EigenStateMatrix => ChemistryConstant.BondEigenStates.BondEigenStateY;
|
||||
}
|
||||
53
src/Chemistry/Bonds/Resolver/BondResolver.cs
Normal file
53
src/Chemistry/Bonds/Resolver/BondResolver.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using VirtualChemistry.Chemistry.Bonds.Implements;
|
||||
using VirtualChemistry.Constants;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Bonds.Resolver;
|
||||
|
||||
/// <summary>
|
||||
/// create a bond instance by descriptions
|
||||
/// </summary>
|
||||
public static class BondResolver
|
||||
{
|
||||
/// <summary>
|
||||
/// create the bond by type
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public static BaseBond Resolve(string type)
|
||||
{
|
||||
BaseBond res = type switch
|
||||
{
|
||||
ChemistryConstant.BondTypes.M => new MBond(),
|
||||
ChemistryConstant.BondTypes.S => new SBond(),
|
||||
ChemistryConstant.BondTypes.D => new DBond(),
|
||||
ChemistryConstant.BondTypes.Y => new YBond(),
|
||||
ChemistryConstant.BondTypes.Q => new QBond(),
|
||||
ChemistryConstant.BondTypes.P => new PBond(),
|
||||
ChemistryConstant.BondTypes.H => new HBond(),
|
||||
_ => throw new Exception("TODO")
|
||||
};
|
||||
return res;
|
||||
}
|
||||
/// <summary>
|
||||
/// create a bond by number
|
||||
/// </summary>
|
||||
/// <param name="number"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public static BaseBond Resolve(int number)
|
||||
{
|
||||
BaseBond res = number switch
|
||||
{
|
||||
1 => new MBond(),
|
||||
2 => new SBond(),
|
||||
3 => new DBond(),
|
||||
4 => new YBond(),
|
||||
5 => new QBond(),
|
||||
6 => new PBond(),
|
||||
7 => new HBond(),
|
||||
_ => throw new Exception("TODO")
|
||||
};
|
||||
return res;
|
||||
}
|
||||
}
|
||||
477
src/Chemistry/Compounds/Implements/Compound.cs
Normal file
477
src/Chemistry/Compounds/Implements/Compound.cs
Normal file
@@ -0,0 +1,477 @@
|
||||
using Skeleton.Algebra.Extensions;
|
||||
using Skeleton.DataStructure;
|
||||
using Skeleton.DataStructure.Packs;
|
||||
using Skeleton.Utils;
|
||||
using Skeleton.Utils.Helpers;
|
||||
using Skeleton.Utils.InverseSampling;
|
||||
using VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
using VirtualChemistry.Chemistry.Bonds.Implements;
|
||||
using VirtualChemistry.Chemistry.Compounds.Resolver;
|
||||
using VirtualChemistry.Chemistry.Mixtures.Implements;
|
||||
using VirtualChemistry.DataStructure.Packs;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Compounds.Implements;
|
||||
|
||||
/// <summary>
|
||||
/// a cluster of molecular of the same kind
|
||||
/// </summary>
|
||||
public class Compound
|
||||
{
|
||||
/// <summary>
|
||||
/// singleton used to represent no compound
|
||||
/// </summary>
|
||||
public static readonly Compound Null = new Compound();
|
||||
private string? IsoRepresentationCache { get; set; }
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public Compound()
|
||||
{
|
||||
CacheInit();
|
||||
LogStateMatrix = new(x => Atoms
|
||||
.Select(atom => atom.LogStateMatrix.GetFrom(x))
|
||||
.DefaultIfEmpty(LieSU3.Zero)
|
||||
.SpLieSum()
|
||||
);
|
||||
StateMatrix = new(x => LogStateMatrix.GetFrom(x).Exp());
|
||||
CompressionElasticity = new (x => (
|
||||
LogStateMatrix.GetFrom(x).CayleyNegative() * StateMatrix.GetFrom(x))
|
||||
.ConjugateOn(new DiagR3(0d, 2d * Math.PI, 4d * Math.PI))
|
||||
.Rayleigh(LogStateMatrix.GetFrom(x).ColumnAverage)
|
||||
);
|
||||
CompressionBias = new (x =>
|
||||
{
|
||||
DiagR3 w1 = new (1d / 11d, 7d / 11d, 10d / 11d);
|
||||
DiagR3 w2 = new (2d / 17d, 8d / 17d, 16d / 17d);
|
||||
double p1 = StateMatrix.GetFrom(x).ConjugateOn(w1).Rayleigh(StateMatrix.GetFrom(x).Hermitian().ColumnAverage);
|
||||
double p2 = StateMatrix.GetFrom(x).Hermitian().ConjugateOn(w2).Rayleigh(StateMatrix.GetFrom(x).ColumnAverageBivariant);
|
||||
double x1 = InverseSampling.StandardNormal(p1) / 4d - 2d * Math.PI;
|
||||
double x2 = InverseSampling.StandardNormal(p2) / 3d + 2d * Math.PI;
|
||||
return Math.Atan(Math.Abs(x1) > Math.Abs(x2) ? x1 : x2) * 2d;
|
||||
}
|
||||
);
|
||||
FreeDensity = new(x =>
|
||||
{
|
||||
double avg = (Math.Exp(-4d * Math.PI) + Math.Exp(Math.PI)) / 2d;
|
||||
DiagR3 spectrum = new DiagR3(Math.Exp(-4d * Math.PI), avg, Math.Exp(Math.PI));
|
||||
double tempMod = Math.Exp(-Phase);
|
||||
return tempMod * LogStateMatrix.GetFrom(x)
|
||||
.CayleyPositive()
|
||||
.ConjugateOn(spectrum)
|
||||
.Rayleigh(StateMatrix.GetFrom(x).ColumnAverageBivariant);
|
||||
});
|
||||
}
|
||||
/// <summary>
|
||||
/// initialize cache
|
||||
/// </summary>
|
||||
public void CacheInit()
|
||||
{
|
||||
HomogeneousMixture.ResetAllCache();
|
||||
ResetDistanceCache();
|
||||
IsoRepresentationCache = null;
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public List<string> TraceLog { get; } = new();
|
||||
/// <summary>
|
||||
/// compression elasticity, refer to the homogeneous mixture version
|
||||
/// </summary>
|
||||
public CacheItem<double> CompressionElasticity { get; }
|
||||
/// <summary>
|
||||
/// compression bias, refer to the homogeneous mixture version
|
||||
/// </summary>
|
||||
public CacheItem<double> CompressionBias { get; }
|
||||
/// <summary>
|
||||
/// all atoms in the molecular
|
||||
/// </summary>
|
||||
public HashSet<BaseAtom> Atoms { get; set; } = new ();
|
||||
/// <summary>
|
||||
/// all connections in this compound
|
||||
/// </summary>
|
||||
public IOrderedEnumerable<FullConnectionInfo> Connections
|
||||
{
|
||||
get
|
||||
{
|
||||
HashSet<BaseBond> visited = new ();
|
||||
List<FullConnectionInfo> res = new ();
|
||||
foreach (BaseBond bond in Bonds.Where(bond => bond.Connected))
|
||||
{
|
||||
if(visited.Contains(bond))
|
||||
continue;
|
||||
if(res.All(con => !con.TryAbsorbBond(bond)))
|
||||
res.Add(new FullConnectionInfo(bond));
|
||||
visited.Add(bond);
|
||||
visited.Add(bond.ConnectedBond);
|
||||
}
|
||||
return res.OrderBy(con => con.Representation);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public IEnumerable<BaseBond> UnconnectedIndex() => Atoms.Count > 15 ?
|
||||
Array.Empty<BaseBond>():
|
||||
Bonds.Where(bond => !bond.Connected && bond.Energy > bond.BondingEnergy);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// string used to save the compound
|
||||
/// </summary>
|
||||
public string ConnectionInfo => String.Join(':', Connections.Select(con => con.Representation));
|
||||
/// <summary>
|
||||
/// all bonds in the compound
|
||||
/// </summary>
|
||||
public IEnumerable<BaseBond> Bonds => Atoms.SelectMany(atom => atom.Bonds);
|
||||
/// <summary>
|
||||
/// the homogeneous mixture of this compound
|
||||
/// </summary>
|
||||
public HomogeneousMixture HomogeneousMixture { get; set; } = HomogeneousMixture.Null;
|
||||
/// <summary>
|
||||
/// state matrix of the compound
|
||||
/// </summary>
|
||||
public CacheItem<SU3> StateMatrix { get; }
|
||||
|
||||
/// <summary>
|
||||
/// log state matrix
|
||||
/// </summary>
|
||||
public CacheItem<LieSU3> LogStateMatrix { get; }
|
||||
|
||||
/// <summary>
|
||||
/// a quantity to compare phase among different materials
|
||||
/// </summary>
|
||||
public double Phase => Math.Tanh(Temperature * CompressionElasticity.Get + CompressionBias.Get);
|
||||
|
||||
/// <summary>
|
||||
/// compression stiffness, refer to the homogeneous mixture version
|
||||
/// </summary>
|
||||
public double CompressionStiffness => Math.Exp(Math.PI / 2d * (5d * Phase - 3d));
|
||||
|
||||
/// <summary>
|
||||
/// temperature of the compound
|
||||
/// </summary>
|
||||
public double Temperature => HomogeneousMixture.Temperature;
|
||||
|
||||
/// <summary>
|
||||
/// unique chemical expression of the compound
|
||||
/// </summary>
|
||||
public string Expression =>
|
||||
Atoms
|
||||
.GroupBy(atom => atom.Element)
|
||||
.OrderBy(group => group.First().AtomicNumber)
|
||||
.Select(group => $"{group.First().Element}"+ (group.Count() > 1 ? group.Count().ToString() : "") )
|
||||
.DefaultIfEmpty("")
|
||||
.Aggregate((a, b) => a + b);
|
||||
/// <summary>
|
||||
/// dump the compound into save string
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public string Dump()
|
||||
{
|
||||
Dictionary<BaseAtom, string> atomMap = new Dictionary<BaseAtom, string>();
|
||||
Dictionary<BaseBond, string> bondMap = new Dictionary<BaseBond, string>();
|
||||
HashSet<string> records = new HashSet<string>();
|
||||
foreach (BaseAtom atom in Atoms)
|
||||
atomMap[atom] = $"({atom.Element}.{atomMap.Count})";
|
||||
foreach (BaseBond bond in Bonds.Where(bond => bond.Connected))
|
||||
bondMap[bond] = $"<{bond.BondType}.{bondMap.Count}>";
|
||||
|
||||
foreach (BaseAtom atom in Atoms)
|
||||
{
|
||||
if (atom.Bonds.All(bond => !bond.Connected))
|
||||
{
|
||||
records.Add($"{atomMap[atom]}-<xxx.0>-<xxx.0>-(xxx.0)");
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (BaseBond bond in atom.Bonds.Where(bond => bond.Connected))
|
||||
{
|
||||
if (bond == bond.ConnectedBond)
|
||||
throw new Exception("TODO");
|
||||
if (bondMap[bond] == bondMap[bond.ConnectedBond])
|
||||
throw new Exception("TODO");
|
||||
string record =
|
||||
$"{atomMap[atom]}-{bondMap[bond]}-{bondMap[bond.ConnectedBond]}-{atomMap[bond.ConnectedBond.Atom]}";
|
||||
string revRecord =
|
||||
$"{atomMap[bond.ConnectedBond.Atom]}-{bondMap[bond.ConnectedBond]}-{bondMap[bond]}-{atomMap[atom]}";
|
||||
if(records.Contains(revRecord))
|
||||
continue;
|
||||
records.Add(record);
|
||||
|
||||
}
|
||||
}
|
||||
return String.Join('|', records) + $"<CompAmtSp>{Amount.ExactDoubleString()}";
|
||||
}
|
||||
/// <summary>
|
||||
/// dump with mapped infomation
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public CompoundDumpMap MappedDump()
|
||||
{
|
||||
Dictionary<BaseAtom, string> atomMap = new();
|
||||
Dictionary<BaseBond, string> bondMap = new();
|
||||
HashSet<string> records = new();
|
||||
foreach (BaseAtom atom in Atoms)
|
||||
atomMap[atom] = $"{atom.Element}.{atomMap.Count}";
|
||||
foreach (BaseBond bond in Bonds.Where(bond => bond.Connected))
|
||||
bondMap[bond] = $"{bond.BondType}.{bondMap.Count}";
|
||||
|
||||
foreach (BaseAtom atom in Atoms)
|
||||
{
|
||||
if (atom.Bonds.All(bond => !bond.Connected))
|
||||
{
|
||||
records.Add($"({atomMap[atom]})-<xxx.0>-<xxx.0>-(xxx.0)");
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (BaseBond bond in atom.Bonds.Where(bond => bond.Connected))
|
||||
{
|
||||
string record =
|
||||
$"({atomMap[atom]})-<{bondMap[bond]}>-<{bondMap[bond.ConnectedBond]}>-({atomMap[bond.ConnectedBond.Atom]})";
|
||||
string revRecord =
|
||||
$"({atomMap[bond.ConnectedBond.Atom]})-<{bondMap[bond.ConnectedBond]}>-<{bondMap[bond]}>-({atomMap[atom]})";
|
||||
if(records.Contains(revRecord))
|
||||
continue;
|
||||
records.Add(record);
|
||||
}
|
||||
}
|
||||
string dumpString = String.Join('|', records);
|
||||
return new CompoundDumpMap(atomMap, bondMap, dumpString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// make a copy of the compound
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Compound Copy() => CompoundResolver.Resolve(Dump());
|
||||
|
||||
/// <summary>
|
||||
/// make a copy with map
|
||||
/// </summary>
|
||||
/// <param name="handle"></param>
|
||||
/// <returns></returns>
|
||||
public PlainPack2<Compound, BaseBond> CopyWithBondMap(BaseBond handle)
|
||||
{
|
||||
CompoundDumpMap dm = MappedDump();
|
||||
CompoundResolveMap rm = CompoundResolver.MappedResolve(dm.DumpString);
|
||||
if (dm.BondMap.ContainsKey(handle))
|
||||
return new PlainPack2<Compound, BaseBond>(rm.ResolvedCompound, rm.BondMap[dm.BondMap[handle]]);
|
||||
return new PlainPack2<Compound, BaseBond>(rm.ResolvedCompound, rm.AtomMap[dm.AtomMap[handle.Atom]].NextUnconnected(handle.BondType));
|
||||
}
|
||||
/// <summary>
|
||||
/// distance between atoms
|
||||
/// </summary>
|
||||
public Dictionary<BaseAtom, Dictionary<BaseAtom, int>> DistanceCache { get; set; } =
|
||||
new Dictionary<BaseAtom, Dictionary<BaseAtom, int>>();
|
||||
/// <summary>
|
||||
/// get the cached distance between two atoms in the compound
|
||||
/// </summary>
|
||||
/// <param name="a1"></param>
|
||||
/// <param name="a2"></param>
|
||||
/// <returns></returns>
|
||||
public int CachedDistance(BaseAtom a1, BaseAtom a2)
|
||||
{
|
||||
if(DistanceCache.Keys.Contains(a1))
|
||||
if (DistanceCache[a1].Keys.Contains(a2))
|
||||
return DistanceCache[a1][a2];
|
||||
if(DistanceCache.Keys.Contains(a2))
|
||||
if (DistanceCache[a2].Keys.Contains(a1))
|
||||
return DistanceCache[a2][a1];
|
||||
return -1;
|
||||
}
|
||||
/// <summary>
|
||||
/// save distance of two atoms in this compound into cache
|
||||
/// </summary>
|
||||
/// <param name="a1"></param>
|
||||
/// <param name="a2"></param>
|
||||
/// <param name="distance"></param>
|
||||
public void CacheDistance(BaseAtom a1, BaseAtom a2, int distance)
|
||||
{
|
||||
if (!DistanceCache.ContainsKey(a1))
|
||||
DistanceCache[a1] = new Dictionary<BaseAtom, int>();
|
||||
DistanceCache[a1][a2] = distance;
|
||||
}
|
||||
/// <summary>
|
||||
/// reset the cache
|
||||
/// </summary>
|
||||
public void ResetDistanceCache() => DistanceCache = new Dictionary<BaseAtom, Dictionary<BaseAtom, int>>();
|
||||
/// <summary>
|
||||
/// if two compound has the same structure
|
||||
/// </summary>
|
||||
/// <param name="compound"></param>
|
||||
/// <returns></returns>
|
||||
public bool IsometricTo(Compound compound)
|
||||
{
|
||||
if (!Expression.Equals(compound.Expression))
|
||||
return false;
|
||||
if(!ConnectionInfo.Equals(compound.ConnectionInfo))
|
||||
return false;
|
||||
if (!StateMatrix.Get.IsEqualApprox(compound.StateMatrix.Get))
|
||||
return false;
|
||||
return IsoRepresentation.Equals(compound.IsoRepresentation, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
/// <summary>
|
||||
/// amount of molecular in this compound
|
||||
/// </summary>
|
||||
public double Amount { get; set; }
|
||||
/// <summary>
|
||||
/// energy per amount
|
||||
/// </summary>
|
||||
public double UnitEnergy
|
||||
{
|
||||
get => Energy / Amount;
|
||||
set => Energy = value * Amount;
|
||||
}
|
||||
/// <summary>
|
||||
/// energy
|
||||
/// </summary>
|
||||
public double Energy
|
||||
{
|
||||
get => Atoms.Sum(atom => atom.Energy) * Amount;
|
||||
set
|
||||
{
|
||||
double energyPerAmount = value / Amount;
|
||||
double energyFactor = Atoms.Sum(atom => atom.EnergyDistributionFactor.Get);
|
||||
foreach (BaseAtom atom in Atoms)
|
||||
atom.Energy = energyPerAmount * atom.EnergyDistributionFactor.Get / energyFactor;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// amount : total mixture amount
|
||||
/// </summary>
|
||||
public double Concentration =>
|
||||
Amount / (HomogeneousMixture == HomogeneousMixture.Null ? Amount : HomogeneousMixture.Amount);
|
||||
/// <summary>
|
||||
/// split into two compounds
|
||||
/// </summary>
|
||||
/// <param name="amount"></param>
|
||||
/// <param name="byRatio"></param>
|
||||
/// <returns></returns>
|
||||
public Compound Split(double amount, bool byRatio = false)
|
||||
{
|
||||
if (amount.IsEqualApprox(0))
|
||||
return Null;
|
||||
if ((!byRatio && amount.IsEqualApprox(Amount)) || (byRatio && amount.IsEqualApprox(1)))
|
||||
{
|
||||
HomogeneousMixture.Compounds.Remove(this);
|
||||
HomogeneousMixture = HomogeneousMixture.Null;
|
||||
return this;
|
||||
}
|
||||
double ebs = Energy;
|
||||
Compound res = Copy();
|
||||
if(!byRatio)
|
||||
{
|
||||
double ratio = amount / Amount;
|
||||
Amount -= amount;
|
||||
res.Amount = amount;
|
||||
res.Energy = ebs * ratio;
|
||||
Energy = ebs * (1d - ratio);
|
||||
}
|
||||
else
|
||||
{
|
||||
res.Amount = Amount * amount;
|
||||
Amount *= (1d - amount);
|
||||
res.Energy = ebs * amount;
|
||||
Energy = ebs * (1d - amount);
|
||||
}
|
||||
res.HomogeneousMixture = HomogeneousMixture.Null;
|
||||
return res;
|
||||
}
|
||||
/// <summary>
|
||||
/// split with bond information
|
||||
/// </summary>
|
||||
/// <param name="amount"></param>
|
||||
/// <param name="handle"></param>
|
||||
/// <param name="byRatio"></param>
|
||||
/// <returns></returns>
|
||||
public PlainPack2<Compound, BaseBond> SplitWithBondMap(double amount, BaseBond handle, bool byRatio = false)
|
||||
{
|
||||
/*if (Amount.IsEqualApprox(0))
|
||||
throw new Exception("DD");
|
||||
if ((Amount * 0.5).IsEqualApprox(0))
|
||||
throw new Exception("FS");*/
|
||||
PlainPack2<Compound, BaseBond> res = CopyWithBondMap(handle);
|
||||
if (!byRatio)
|
||||
{
|
||||
double ratio = amount / Amount;
|
||||
double splitEnergy = Energy * ratio;
|
||||
double energy = Energy - splitEnergy;
|
||||
Amount -= amount;
|
||||
res.Item1.Amount = amount;
|
||||
Energy = energy;
|
||||
res.Item1.Energy = splitEnergy;
|
||||
}
|
||||
else
|
||||
{
|
||||
double splitEnergy = Energy * amount;
|
||||
double energy = Energy * (1 - amount);
|
||||
res.Item1.Amount = Amount * amount;
|
||||
Amount *= 1 - amount;
|
||||
Energy = energy;
|
||||
res.Item1.Energy = splitEnergy;
|
||||
}
|
||||
HomogeneousMixture.AddCompound(res.Item1, true, true);
|
||||
return res;
|
||||
}
|
||||
/// <summary>
|
||||
/// mass per molecular
|
||||
/// </summary>
|
||||
public double MolecularMass => Atoms
|
||||
.Select(atom => atom.AtomicMass)
|
||||
.DefaultIfEmpty(0d)
|
||||
.Sum();
|
||||
/// <summary>
|
||||
/// unique representation of a compound
|
||||
/// </summary>
|
||||
public string IsoRepresentation => IsoRepresentationCache ??= Atoms
|
||||
.GroupedMinBy(a => -a.AtomicNumber)
|
||||
.GroupedMinBy(a => a.ConnectedAtoms.Count())
|
||||
.GroupedApproxMinBy(a => a.GroupMass)
|
||||
.GroupedApproxMinBy(a => a.StateMatrix.Get.Det().Real)
|
||||
.GroupedApproxMinBy(a => a.StateMatrix.Get.Trace().Real)
|
||||
.GroupedApproxMinBy(a => a.StructureMatrix.Get.Det().Real)
|
||||
.Select(a => a.FullRepresentation)
|
||||
.Min() ?? "";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// a real number from 0 to 1
|
||||
/// depend on temperature
|
||||
/// Resolve Level
|
||||
/// when A is next to B(above or below)
|
||||
/// the one with higher resolve level will try to absorb the other one
|
||||
///
|
||||
/// Higher Level => behaviour like solvent
|
||||
/// Lower Level => behaviour like solute
|
||||
/// </summary>
|
||||
public double ResolveLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
double Normalizer(double x) => 2d * (Math.Tanh(-x * 3d) + 1d) / 5d + 1d / 5d;
|
||||
double C(double x) => 1 - Math.Exp(-x);
|
||||
double z = C(C(Phase));
|
||||
C3 divisor = (StateMatrix.Get.ColumnAverage + LogStateMatrix.Get.ColumnAverageBivariant.Conj()) / 2d;
|
||||
double factor = StateMatrix.Get.ConjugateOn(new DiagR3(1d, 1d / 9d, 1d / 3d)).Rayleigh(divisor);
|
||||
return factor * Normalizer(Phase) / Math.Cosh(z);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Phase of compound is determined by compression stiffness
|
||||
* higher stiffness => more like gas
|
||||
* lower stiffness => more like solid
|
||||
*
|
||||
* resolvability of one solute A in solvent B(resolve level of A is less than B)
|
||||
* if both A and B are solid => 0
|
||||
*
|
||||
* otherwise determined by many factors
|
||||
*
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public CacheItem<double> FreeDensity { get; }
|
||||
}
|
||||
111
src/Chemistry/Compounds/Resolver/CompoundResolver.cs
Normal file
111
src/Chemistry/Compounds/Resolver/CompoundResolver.cs
Normal file
@@ -0,0 +1,111 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using Skeleton.Utils;
|
||||
using VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
using VirtualChemistry.Chemistry.Atoms.Resolver;
|
||||
using VirtualChemistry.Chemistry.Bonds.Implements;
|
||||
using VirtualChemistry.Chemistry.Compounds.Implements;
|
||||
using VirtualChemistry.DataStructure.Packs;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Compounds.Resolver;
|
||||
|
||||
/// <summary>
|
||||
/// get compound by save string
|
||||
/// </summary>
|
||||
public static class CompoundResolver
|
||||
{
|
||||
private const string AtomRegex = @"\(([a-zA-Z]+\.[0-9]+)\)";
|
||||
private const string BondRegex = @"<([a-zA-Z]+\.[0-9]+)>";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// resolve into map
|
||||
/// </summary>
|
||||
/// <param name="expression"></param>
|
||||
/// <returns></returns>
|
||||
public static CompoundResolveMap MappedResolve(string expression)
|
||||
{
|
||||
Compound res = new Compound();
|
||||
IEnumerable<string> records = expression.Split('|');
|
||||
Dictionary<string, BaseAtom> atomMap = new();
|
||||
Dictionary<string, BaseBond> bondMap = new();
|
||||
foreach (string record in records)
|
||||
{
|
||||
List<string> connection = record.Split('-').ToList();
|
||||
string atom1 = new Regex(AtomRegex).Match(connection[0]).Result("$1");
|
||||
string bond1 = new Regex(BondRegex).Match(connection[1]).Result("$1");
|
||||
string bond2 = new Regex(BondRegex).Match(connection[2]).Result("$1");
|
||||
string atom2 = new Regex(AtomRegex).Match(connection[3]).Result("$1");
|
||||
if (bond1.Equals("xxx.0", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
BaseAtom single = AtomResolver.Resolve(atom1.Split('.')[0]);
|
||||
atomMap[atom1] = single;
|
||||
single.Compound = res;
|
||||
res.Atoms.Add(single);
|
||||
res.CacheInit();
|
||||
return new CompoundResolveMap(atomMap, bondMap, res);
|
||||
}
|
||||
|
||||
if (!atomMap.Keys.Contains(atom1))
|
||||
atomMap[atom1] = AtomResolver.Resolve(atom1.Split('.')[0]);
|
||||
if (!atomMap.Keys.Contains(atom2))
|
||||
atomMap[atom2] = AtomResolver.Resolve(atom2.Split('.')[0]);
|
||||
atomMap[atom1].Compound = res;
|
||||
atomMap[atom2].Compound = res;
|
||||
res.Atoms.Add(atomMap[atom1]);
|
||||
res.Atoms.Add(atomMap[atom2]);
|
||||
BaseBond ba = atomMap[atom1].NextUnconnected(bond1.Split('.')[0]);
|
||||
BaseBond bb = atomMap[atom2].NextUnconnected(bond2.Split('.')[0], ba);
|
||||
|
||||
ba.Connect(bb);
|
||||
bondMap[bond1] = ba;
|
||||
bondMap[bond2] = bb;
|
||||
}
|
||||
res.CacheInit();
|
||||
return new CompoundResolveMap(atomMap, bondMap, res);
|
||||
}
|
||||
/// <summary>
|
||||
/// get the compound by save string
|
||||
/// </summary>
|
||||
/// <param name="expression"></param>
|
||||
/// <returns></returns>
|
||||
public static Compound Resolve(string expression)
|
||||
{
|
||||
string[] parts = expression.Split("<CompAmtSp>");
|
||||
expression = parts[0];
|
||||
Compound res = new Compound();
|
||||
res.Amount = parts[1].ByteStringToDouble();
|
||||
IEnumerable<string> records = expression.Split('|');
|
||||
Dictionary<string, BaseAtom> atomMap = new Dictionary<string, BaseAtom>();
|
||||
foreach (string record in records)
|
||||
{
|
||||
List<string> connection = record.Split('-').ToList();
|
||||
string atom1 = new Regex(AtomRegex).Match(connection[0]).Result("$1");
|
||||
string bond1 = new Regex(BondRegex).Match(connection[1]).Result("$1");
|
||||
string bond2 = new Regex(BondRegex).Match(connection[2]).Result("$1");
|
||||
string atom2 = new Regex(AtomRegex).Match(connection[3]).Result("$1");
|
||||
if (bond1.Equals("xxx.0", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
BaseAtom single = AtomResolver.Resolve(atom1.Split('.')[0]);
|
||||
single.Compound = res;
|
||||
res.Atoms.Add(single);
|
||||
res.CacheInit();
|
||||
return res;
|
||||
}
|
||||
|
||||
if (!atomMap.Keys.Contains(atom1))
|
||||
atomMap[atom1] = AtomResolver.Resolve(atom1.Split('.')[0]);
|
||||
if (!atomMap.Keys.Contains(atom2))
|
||||
atomMap[atom2] = AtomResolver.Resolve(atom2.Split('.')[0]);
|
||||
atomMap[atom1].Compound = res;
|
||||
atomMap[atom2].Compound = res;
|
||||
res.Atoms.Add(atomMap[atom1]);
|
||||
res.Atoms.Add(atomMap[atom2]);
|
||||
BaseBond b1 = atomMap[atom1].NextUnconnected(bond1.Split('.')[0]);
|
||||
BaseBond b2 = atomMap[atom2].NextUnconnected(bond2.Split('.')[0], b1);
|
||||
b1.Connect(b2);
|
||||
}
|
||||
res.CacheInit();
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
27
src/Chemistry/Containers/IChemicalContainer.cs
Normal file
27
src/Chemistry/Containers/IChemicalContainer.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using VirtualChemistry.Chemistry.Mixtures.Implements;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Containers;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface IChemicalContainer
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
double Volume();
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
HeterogeneousMixture Content { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public double EnvironmentPressure { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public double EnvironmentTemperature { get; set; }
|
||||
}
|
||||
29
src/Chemistry/Containers/NullContainer.cs
Normal file
29
src/Chemistry/Containers/NullContainer.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using VirtualChemistry.Chemistry.Mixtures.Implements;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Containers;
|
||||
/// <summary>
|
||||
/// container singleton used to represent no container
|
||||
/// </summary>
|
||||
public sealed class NullContainer : IChemicalContainer
|
||||
{
|
||||
private NullContainer()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// instance
|
||||
/// </summary>
|
||||
public static readonly NullContainer Null = new();
|
||||
|
||||
/// <inheritdoc />
|
||||
public double Volume() => Double.PositiveInfinity;
|
||||
|
||||
/// <inheritdoc />
|
||||
public HeterogeneousMixture Content { get; set; } = HeterogeneousMixture.Null;
|
||||
|
||||
/// <inheritdoc />
|
||||
public double EnvironmentPressure { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public double EnvironmentTemperature { get; set; }
|
||||
}
|
||||
12
src/Chemistry/Environments/Implements/Environment.cs
Normal file
12
src/Chemistry/Environments/Implements/Environment.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace VirtualChemistry.Chemistry.Environments.Implements;
|
||||
|
||||
/// <summary>
|
||||
/// the environment
|
||||
/// </summary>
|
||||
public class Environment
|
||||
{
|
||||
/// <summary>
|
||||
/// environment temperature
|
||||
/// </summary>
|
||||
public double Temperature { get; set; }
|
||||
}
|
||||
158
src/Chemistry/Mixtures/Implements/HeterogeneousMixture.cs
Normal file
158
src/Chemistry/Mixtures/Implements/HeterogeneousMixture.cs
Normal file
@@ -0,0 +1,158 @@
|
||||
using Skeleton.DataStructure.Link;
|
||||
using VirtualChemistry.Chemistry.Containers;
|
||||
using VirtualChemistry.Chemistry.Mixtures.Resolver;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Mixtures.Implements;
|
||||
|
||||
/// <summary>
|
||||
/// a collection of homogeneous mixtures
|
||||
/// </summary>
|
||||
public class HeterogeneousMixture
|
||||
{
|
||||
public HeterogeneousMixture()
|
||||
{
|
||||
}
|
||||
|
||||
public HeterogeneousMixture(IChemicalContainer c)
|
||||
{
|
||||
Container = c;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// singleton used to represent no mixture
|
||||
/// </summary>
|
||||
public static readonly HeterogeneousMixture Null = new HeterogeneousMixture();
|
||||
/// <summary>
|
||||
/// container of the mixture
|
||||
/// </summary>
|
||||
public IChemicalContainer Container { get; set; } = NullContainer.Null;
|
||||
/// <summary>
|
||||
/// volume of the container
|
||||
/// </summary>
|
||||
public double ContainerVolume => Container.Volume();
|
||||
/// <summary>
|
||||
/// all homogeneous mixtures within
|
||||
/// </summary>
|
||||
public HashSet<HomogeneousMixture> Layers { get; set; } = new();
|
||||
/// <summary>
|
||||
/// homogeneous mixtures in order from bottom to top
|
||||
/// </summary>
|
||||
public Link<HomogeneousMixture> LayerOrder { get; set; } = new();
|
||||
/// <summary>
|
||||
/// add an empty homo mixture to the layers
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public HomogeneousMixture AddLayer()
|
||||
{
|
||||
HomogeneousMixture res = new HomogeneousMixture();
|
||||
AddLayer(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// remove a homo from the layers
|
||||
/// </summary>
|
||||
/// <param name="m"></param>
|
||||
public void RemoveLayer(HomogeneousMixture m)
|
||||
{
|
||||
if (this == Null)
|
||||
return;
|
||||
Layers.Remove(m);
|
||||
LayerOrder.Remove(m.Layer);
|
||||
m.HeterogeneousMixture = Null;
|
||||
m.Layer = LinkNode<HomogeneousMixture>.Null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// add a homo mixture into this as a new layer
|
||||
/// </summary>
|
||||
/// <param name="m"></param>
|
||||
/// <param name="atHead"></param>
|
||||
public void AddLayer(HomogeneousMixture m, bool atHead=true)
|
||||
{
|
||||
m.HeterogeneousMixture.RemoveLayer(m);
|
||||
m.HeterogeneousMixture = this;
|
||||
Layers.Add(m);
|
||||
if (atHead)
|
||||
LayerOrder.AddFirst(m);
|
||||
else
|
||||
LayerOrder.AddLast(m);
|
||||
}
|
||||
/// <summary>
|
||||
/// total amount of molecular
|
||||
/// </summary>
|
||||
public double Amount
|
||||
{
|
||||
get => Layers
|
||||
.Select(l => l.Amount)
|
||||
.DefaultIfEmpty(0d)
|
||||
.Sum();
|
||||
set
|
||||
{
|
||||
Dictionary<HomogeneousMixture, double> res = new Dictionary<HomogeneousMixture, double>();
|
||||
foreach (HomogeneousMixture l in Layers)
|
||||
res[l] = value * l.Ratio;
|
||||
foreach (HomogeneousMixture l in Layers)
|
||||
l.Amount = res[l];
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// if this degenerate into a single homo mixture
|
||||
/// </summary>
|
||||
public bool IsHomogeneous => Layers.Count == 1;
|
||||
|
||||
/// <summary>
|
||||
/// dump the mixture into save string
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string Dump() =>
|
||||
$"`LAYERS{String.Join(HeterogeneousMixtureResolver.LayerSplit, LayerOrder.Select(layer => layer.Dump()))}`%LAYERS";
|
||||
|
||||
/// <summary>
|
||||
/// volume of contents
|
||||
/// </summary>
|
||||
public double Volume => Layers.Sum(layer => layer.Volume);
|
||||
|
||||
/// <summary>
|
||||
/// the total stiffness of all contents
|
||||
/// </summary>
|
||||
public double EquivalentStiffness => 1d / Layers.Sum(h => 1d / h.CompressionStiffness);
|
||||
|
||||
/// <summary>
|
||||
/// volume of contents under 0 pressure
|
||||
/// </summary>
|
||||
public double FreeVolume => Layers.Sum(h => h.FreeVolume);
|
||||
|
||||
private double ContentVolume => Layers.Sum(h => h.Volume);
|
||||
/// <summary>
|
||||
/// the force from container
|
||||
/// </summary>
|
||||
public double ForceFromContainer => (Math.Min(FreeVolume, Volume) - ContentVolume) * EquivalentStiffness;
|
||||
|
||||
/// <summary>
|
||||
/// process one step of all its homogeneous mixture<br/>
|
||||
/// including reaction, resolving/precipitating compounds,<br/>
|
||||
/// heat exchange and volume update
|
||||
/// </summary>
|
||||
public void OneStep()
|
||||
{
|
||||
foreach (HomogeneousMixture h in Layers)
|
||||
{
|
||||
if(h.Layer.Next.IsEnding)
|
||||
continue;
|
||||
if(h.Density > h.Layer.Next.Value.Density)
|
||||
h.Layer.MoveForward();
|
||||
}
|
||||
foreach (HomogeneousMixture h in Layers)
|
||||
h.React();
|
||||
foreach (HomogeneousMixture h in Layers.ToArray())
|
||||
h.PrecipitateAndResolve();
|
||||
foreach (HomogeneousMixture h in Layers)
|
||||
{
|
||||
h.Degenerate();
|
||||
h.VolumeUpdate();
|
||||
h.HeatExchange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
772
src/Chemistry/Mixtures/Implements/HomogeneousMixture.cs
Normal file
772
src/Chemistry/Mixtures/Implements/HomogeneousMixture.cs
Normal file
@@ -0,0 +1,772 @@
|
||||
using System.Numerics;
|
||||
using Skeleton.Algebra.Extensions;
|
||||
using Skeleton.Algebra.ScalarFieldStructure;
|
||||
using Skeleton.DataStructure;
|
||||
using Skeleton.DataStructure.Link;
|
||||
using Skeleton.DataStructure.Packs;
|
||||
using Skeleton.Utils;
|
||||
using Skeleton.Utils.Helpers;
|
||||
using Skeleton.Utils.InverseSampling;
|
||||
using VirtualChemistry.Chemistry.Bonds.Implements;
|
||||
using VirtualChemistry.Chemistry.Compounds.Implements;
|
||||
using VirtualChemistry.Chemistry.Mixtures.Resolver;
|
||||
using VirtualChemistry.Constants;
|
||||
using VirtualChemistry.DataStructure.Packs;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Mixtures.Implements;
|
||||
/// <summary>
|
||||
/// mixture of many well mixed compounds that can not be seperated by psy methods
|
||||
/// </summary>
|
||||
public class HomogeneousMixture
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor by default
|
||||
/// </summary>
|
||||
public HomogeneousMixture()
|
||||
{
|
||||
LogStateMatrix = new CacheItem<LieSU3>(x =>
|
||||
Compounds.Select(compound => compound.LogStateMatrix.GetFrom(x) * compound.Concentration)
|
||||
.DefaultIfEmpty(LieSU3.Zero)
|
||||
.SpLieSum()
|
||||
);
|
||||
StateMatrix = new(x => LogStateMatrix.GetFrom(x).Exp());
|
||||
CompressionElasticity = new(x =>
|
||||
{
|
||||
DiagR3 spectrum = new (0d, 2d * Math.PI, 4d * Math.PI);
|
||||
return (LogStateMatrix.GetFrom(x).CayleyNegative() * StateMatrix.GetFrom(x))
|
||||
.ConjugateOn(spectrum)
|
||||
.Rayleigh(LogStateMatrix.GetFrom(x).ColumnAverage);
|
||||
}
|
||||
);
|
||||
CompressionBias = new(x =>
|
||||
{
|
||||
DiagR3 w1 = new (1d / 11d, 7d / 11d, 10d / 11d);
|
||||
DiagR3 w2 = new (2d / 17d, 8d / 17d, 16d / 17d);
|
||||
double p1 = StateMatrix.GetFrom(x)
|
||||
.ConjugateOn(w1)
|
||||
.Rayleigh(StateMatrix.GetFrom(x).Hermitian().ColumnAverage);
|
||||
double p2 = StateMatrix.GetFrom(x)
|
||||
.Hermitian()
|
||||
.ConjugateOn(w2)
|
||||
.Rayleigh(StateMatrix.GetFrom(x).ColumnAverageBivariant);
|
||||
double x1 = InverseSampling.StandardNormal(p1) / 4d - 2d * Math.PI;
|
||||
double x2 = InverseSampling.StandardNormal(p2) / 3d + 2d * Math.PI;
|
||||
return Math.Atan(Math.Abs(x1) > Math.Abs(x2) ? x1 : x2) * 2d;
|
||||
}
|
||||
);
|
||||
FreeDensity = new(x =>
|
||||
{
|
||||
double avg = (Math.Exp(-4d * Math.PI) + Math.Exp(Math.PI)) / 2d;
|
||||
DiagR3 spectrum = new DiagR3(Math.Exp(-4d * Math.PI), avg, Math.Exp(Math.PI));
|
||||
double tempMod = Math.Exp(-Phase);
|
||||
return tempMod * LogStateMatrix.GetFrom(x)
|
||||
.CayleyPositive()
|
||||
.ConjugateOn(spectrum)
|
||||
.Rayleigh(StateMatrix.GetFrom(x).ColumnAverageBivariant);
|
||||
}
|
||||
);
|
||||
HeatConductivity = new(x =>
|
||||
StateMatrix.GetFrom(x).ConjugateOn(ChemistryConstant.EnergyConductivitySpectrum)
|
||||
.Rayleigh(LogStateMatrix.GetFrom(x) * StateMatrix.GetFrom(x).ColumnAverageBivariant)
|
||||
);
|
||||
ResetAllCache();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// singleton used to represent no mixture
|
||||
/// </summary>
|
||||
public static readonly HomogeneousMixture Null = new();
|
||||
|
||||
private IEnumerable<BaseBond> ConnectedIndex()
|
||||
{
|
||||
HashSet<BaseBond> bs = new();
|
||||
foreach (Compound c in Compounds)
|
||||
{
|
||||
if(c.Amount.IsEqualApprox(0))
|
||||
continue;
|
||||
|
||||
|
||||
foreach (BaseBond b in c.Bonds)
|
||||
{
|
||||
if (b.Compound.Amount.IsEqualApprox(0))
|
||||
throw new Exception("P??");
|
||||
|
||||
if (b.Compound != c)
|
||||
throw new Exception("??!!?");
|
||||
if (
|
||||
b.Connected &&
|
||||
b.Energy > b.AntiBondingEnergy &&
|
||||
b.ConnectedBond.Energy > b.ConnectedBond.AntiBondingEnergy &&
|
||||
!bs.Contains(b.ConnectedBond)
|
||||
)
|
||||
{
|
||||
bs.Add(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bs;
|
||||
//Compounds.Where(c => !(0.5 * c.Amount).IsEqualApprox(0)).SelectMany(x => x.ConnectedIndex());
|
||||
}
|
||||
public void RPC()
|
||||
{
|
||||
|
||||
int s1 = 0;
|
||||
int s2 = 0;
|
||||
int s3 = 0;
|
||||
int s4 = 0;
|
||||
foreach (Compound c in Compounds)
|
||||
{
|
||||
foreach (BaseBond b in c.Bonds)
|
||||
{
|
||||
switch (b.BondingGroup)
|
||||
{
|
||||
case 0:
|
||||
s1++;
|
||||
break;
|
||||
case 1:
|
||||
s2++;
|
||||
break;
|
||||
case 2:
|
||||
s3++;
|
||||
break;
|
||||
default:
|
||||
s4++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Console.WriteLine($"{s1} ---- {s2} ---- {s3} --- {s4}");
|
||||
}
|
||||
|
||||
private BondGroups ReactionGroup()
|
||||
{
|
||||
HashSet<BaseBond> group1 = new();
|
||||
HashSet<BaseBond> group2 = new();
|
||||
HashSet<BaseBond> group3 = new();
|
||||
HashSet<BaseBond> group4 = new();
|
||||
foreach (Compound c in Compounds)
|
||||
{
|
||||
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))
|
||||
continue;
|
||||
switch (b.BondingGroup)
|
||||
{
|
||||
case 0:
|
||||
group1.Add(b);
|
||||
break;
|
||||
case 1:
|
||||
group2.Add(b);
|
||||
break;
|
||||
case 2:
|
||||
group3.Add(b);
|
||||
break;
|
||||
case 3:
|
||||
group4.Add(b);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new(group1, group2, group3, group4);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// elasticity range: 0, 4pi
|
||||
/// elasticity controls the speed k drops from e^pi to e^-4pi
|
||||
/// elasticity -> 0; k -> constant
|
||||
/// b -> 4pi; k -> e^pi
|
||||
/// b -> -4pi; k -> e^-4pi
|
||||
/// </summary>
|
||||
public CacheItem<double> CompressionElasticity { get; }
|
||||
|
||||
/// <summary>
|
||||
/// bias range: -4pi, 4pi
|
||||
/// bias controls the temp of triple point
|
||||
/// higher b -> higher melting point and higher boiling point
|
||||
/// </summary>
|
||||
public CacheItem<double> CompressionBias { get; }
|
||||
|
||||
/// <summary>
|
||||
/// phase -> 1 implies material is more like gas
|
||||
/// phase -> -1 implies material is more like solid
|
||||
///
|
||||
/// </summary>
|
||||
public double Phase => Compounds.Sum(c => c.Concentration * c.Phase);
|
||||
|
||||
/// <summary>
|
||||
/// stiffness range: e^-4pi, e^pi
|
||||
/// higher stiffness -> harder to compress -> solid like
|
||||
/// lower stiffness -> easier to compress -> gas like
|
||||
/// Stiffness K, Density D, Free Density D0, Temperature T
|
||||
/// P = K(1/D - 1/D0)
|
||||
///
|
||||
/// Temperature range: -pi, pi
|
||||
/// </summary>
|
||||
public double CompressionStiffness => Math.Exp(Math.PI / 2d * (5d * Phase - 3d));
|
||||
|
||||
/// <summary>
|
||||
/// e^-4pi ... e^pi
|
||||
/// </summary>
|
||||
public CacheItem<double> FreeDensity { get; }
|
||||
|
||||
/// <summary>
|
||||
/// volume that under 0 compression
|
||||
/// </summary>
|
||||
public double FreeVolume => Amount / FreeDensity.Get;
|
||||
|
||||
/// <summary>
|
||||
/// P = K (1/D - 1/D0)
|
||||
/// </summary>
|
||||
public double Pressure => (Volume - FreeVolume) * CompressionStiffness;
|
||||
|
||||
/// <summary>
|
||||
/// Volume of the mixture
|
||||
/// </summary>
|
||||
public double Volume { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Heat transfer ability
|
||||
/// </summary>
|
||||
public CacheItem<double> HeatConductivity { get; }
|
||||
|
||||
/// <summary>
|
||||
/// energy / amount = temperature
|
||||
/// </summary>
|
||||
public double Temperature
|
||||
{
|
||||
get => Energy / Amount;
|
||||
set => Energy = value * Amount;
|
||||
}
|
||||
/// <summary>
|
||||
/// total Energy the mixture holds
|
||||
/// </summary>
|
||||
public double Energy
|
||||
{
|
||||
get => Compounds.Sum(c => c.Energy);
|
||||
set
|
||||
{
|
||||
foreach (Compound c in Compounds)
|
||||
c.Energy = value * c.Concentration;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// reset all cache
|
||||
/// </summary>
|
||||
public void ResetAllCache()
|
||||
{
|
||||
LayerCache = LinkNode<HomogeneousMixture>.Null;
|
||||
}
|
||||
/// <summary>
|
||||
/// the heterogeneous mixture that holds this homogeneous mixture
|
||||
/// </summary>
|
||||
public HeterogeneousMixture HeterogeneousMixture { get; set; } = HeterogeneousMixture.Null;
|
||||
|
||||
/// <summary>
|
||||
/// Compounds of this mixture
|
||||
/// </summary>
|
||||
public HashSet<Compound> Compounds { get; set; } = new HashSet<Compound>();
|
||||
/// <summary>
|
||||
/// Compounds whose ratio is greater than 1%
|
||||
/// </summary>
|
||||
public IEnumerable<Compound> MainCompounds => Compounds.Where(c => c.Concentration > 0.001d);
|
||||
private LinkNode<HomogeneousMixture> LayerCache { get; set; } = LinkNode<HomogeneousMixture>.Null;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public LinkNode<HomogeneousMixture> Layer
|
||||
{
|
||||
get => LayerCache == LinkNode<HomogeneousMixture>.Null
|
||||
? HeterogeneousMixture.LayerOrder.Find(this)
|
||||
: LayerCache;
|
||||
set => LayerCache = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// State matrix of this mixture
|
||||
/// </summary>
|
||||
public CacheItem<SU3> StateMatrix { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Log of the state matrix
|
||||
/// </summary>
|
||||
public CacheItem<LieSU3> LogStateMatrix { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Split the homogeneous mixture into another heterogeneous mixture by ratio or amount;
|
||||
/// </summary>
|
||||
/// <param name="amount"> The amount or ratio</param>
|
||||
/// <param name="into">another heterogeneous mixture</param>
|
||||
/// <param name="byRatio">determine if the amount variable is ratio or amount</param>
|
||||
/// <returns></returns>
|
||||
public HomogeneousMixture Split(double amount, HeterogeneousMixture into, bool byRatio = false)
|
||||
{
|
||||
double ebs = Energy;
|
||||
double vbs = Volume;
|
||||
double ratio = byRatio ? amount : amount / Amount;
|
||||
HomogeneousMixture res = new HomogeneousMixture();
|
||||
foreach (Compound c in Compounds)
|
||||
{
|
||||
Compound split = c.Split(amount, byRatio);
|
||||
if(split != Compound.Null)
|
||||
res.AddCompound(split);
|
||||
}
|
||||
res.Energy = ebs*ratio;
|
||||
res.Volume = vbs*ratio;
|
||||
Energy = ebs * (1 - ratio);
|
||||
Volume = vbs * (1 - ratio);
|
||||
into.AddLayer(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add compound into the homogeneous mixture
|
||||
/// </summary>
|
||||
/// <param name="compound">compound to add</param>
|
||||
/// <param name="resetCache"></param>
|
||||
/// <param name="skipCombine">add without combine to isomorphic compound</param>
|
||||
public void AddCompound(Compound compound, bool resetCache = true, bool skipCombine=false)
|
||||
{
|
||||
if (compound.HomogeneousMixture == this)
|
||||
return;
|
||||
bool added = false;
|
||||
if(!skipCombine)
|
||||
{
|
||||
foreach (Compound sCompound in Compounds.Where(x => x.Expression == compound.Expression))
|
||||
{
|
||||
if (sCompound.IsometricTo(compound))
|
||||
{
|
||||
sCompound.Amount += compound.Amount;
|
||||
compound.Amount = 0d;
|
||||
sCompound.Energy += compound.Energy;
|
||||
added = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compound.HomogeneousMixture = added ? Null : this;
|
||||
if (!added)
|
||||
Compounds.Add(compound);
|
||||
if(resetCache)
|
||||
ResetAllCache();
|
||||
}
|
||||
/// <summary>
|
||||
/// Amount of this mixture
|
||||
/// </summary>
|
||||
public double Amount
|
||||
{
|
||||
get => Compounds
|
||||
.Select(c => c.Amount)
|
||||
.DefaultIfEmpty(0)
|
||||
.Sum();
|
||||
set
|
||||
{
|
||||
Dictionary<Compound, double> res = new Dictionary<Compound, double>();
|
||||
foreach (Compound c in Compounds)
|
||||
res[c] = value * c.Concentration;
|
||||
foreach (Compound c in Compounds)
|
||||
c.Amount = res[c];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ratio of this mixture in the heterogeneous mixture
|
||||
/// </summary>
|
||||
public double Ratio =>
|
||||
Amount / (HeterogeneousMixture == HeterogeneousMixture.Null ? Amount : HeterogeneousMixture.Amount);
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="homo"></param>
|
||||
public void Resolve(HomogeneousMixture homo)
|
||||
{
|
||||
foreach (Compound c in homo.Compounds)
|
||||
Resolve(c, false);
|
||||
ResetAllCache();
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="compound"></param>
|
||||
/// <param name="resetCache"></param>
|
||||
public void Resolve(Compound compound, bool resetCache = true)
|
||||
{
|
||||
AddCompound(compound, resetCache);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// density of the mixture, amount of molecular per volume
|
||||
/// </summary>
|
||||
public double Density => Amount / Volume;
|
||||
|
||||
/// <summary>
|
||||
/// save mixture into string
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string Dump() =>
|
||||
$"`ENV?ENG{Energy.ExactDoubleString()}?V{Volume.ExactDoubleString()}`%ENV`COMPS{String.Join(HomogeneousMixtureResolver.CompoundsSplit, Compounds.Select(c => c.Dump()))}`%COMPS";
|
||||
|
||||
/// <summary>
|
||||
/// update volume
|
||||
/// </summary>
|
||||
public void VolumeUpdate()
|
||||
{
|
||||
double sVolume = Volume + HeterogeneousMixture.ForceFromContainer / CompressionStiffness;
|
||||
Volume = Math.Max(sVolume, 1E-6);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// exchange energy to neighbor mixtures
|
||||
/// </summary>
|
||||
public void HeatExchange()
|
||||
{
|
||||
if (Layer != Layer.Parent.First)
|
||||
{
|
||||
HomogeneousMixture mPrevious = Layer.Previous.Value;
|
||||
double balanceTemp = (Energy + mPrevious.Energy) / (Amount + mPrevious.Amount);
|
||||
double dTemp = balanceTemp - Temperature;
|
||||
double conductivity = Math.Sqrt(HeatConductivity.Get * mPrevious.HeatConductivity.Get);
|
||||
double transferTemp = dTemp * conductivity;
|
||||
Temperature += transferTemp;
|
||||
mPrevious.Temperature -= transferTemp;
|
||||
}
|
||||
if (Layer != Layer.Parent.Last)
|
||||
{
|
||||
HomogeneousMixture mNext = Layer.Next.Value;
|
||||
double balanceTemp = (Energy + mNext.Energy) / (Amount + mNext.Amount);
|
||||
double dTemp = balanceTemp - Temperature;
|
||||
double conductivity = Math.Sqrt(HeatConductivity.Get * mNext.HeatConductivity.Get);
|
||||
double transferTemp = dTemp * conductivity;
|
||||
Temperature += transferTemp;
|
||||
mNext.Temperature -= transferTemp;
|
||||
}
|
||||
|
||||
double envBalanceTemp = HeterogeneousMixture.Container.EnvironmentTemperature;
|
||||
double envDTemp = envBalanceTemp - Temperature;
|
||||
double envConductivity = HeatConductivity.Get;
|
||||
Temperature += envDTemp * envConductivity;
|
||||
}
|
||||
private void ReactConnecting(HashSet<BaseBond> g1, HashSet<BaseBond> g2)
|
||||
{
|
||||
double maxCd = -1;
|
||||
BaseBond xb1 = BaseBond.Null;
|
||||
BaseBond xb2 = BaseBond.Null;
|
||||
foreach (BaseBond b1 in g1)
|
||||
{
|
||||
foreach (BaseBond b2 in g2)
|
||||
{
|
||||
H3 cd = new(Complex.ImaginaryOne / 2 * (b1.LogState.Get + b2.LogState.Get));
|
||||
double cdX = cd.Rayleigh((b1.LogState.Get + b2.LogState.Get).ColumnAverage);
|
||||
if (cdX > maxCd)
|
||||
{
|
||||
maxCd = cdX;
|
||||
xb1 = b1;
|
||||
xb2 = b2;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (xb1 == BaseBond.Null)
|
||||
return;
|
||||
if (xb1 == xb2)
|
||||
{
|
||||
PlainPack2<Compound, BaseBond> s = xb1.Compound.SplitWithBondMap(0.5, xb2, true);
|
||||
xb2 = s.Item2;
|
||||
}
|
||||
|
||||
if (xb1.Compound.Amount.IsSignificantlyGreaterThen(xb2.Compound.Amount))
|
||||
{
|
||||
double amountDiff = xb1.Compound.Amount - xb2.Compound.Amount;
|
||||
Compound oth = xb1.Compound.Split(amountDiff);
|
||||
xb1.HomogeneousMixture.AddCompound(oth);
|
||||
}
|
||||
|
||||
if (xb1.Compound.Amount.IsSignificantlyLessThen(xb2.Compound.Amount))
|
||||
{
|
||||
double amountDiff = xb2.Compound.Amount - xb1.Compound.Amount;
|
||||
Compound oth = xb2.Compound.Split(amountDiff);
|
||||
xb2.HomogeneousMixture.AddCompound(oth);
|
||||
}
|
||||
|
||||
string log = $"From Composite React of {xb1.Compound.Amount}*{xb1.Compound.Expression} and {xb2.Compound.Amount}*{xb2.Compound.Expression}";
|
||||
|
||||
xb1.Connect(xb2);
|
||||
xb1.Compound.TraceLog.Add(log);
|
||||
}
|
||||
|
||||
private int ReactionType()
|
||||
{
|
||||
Complex d = LogStateMatrix.Get.CayleyPositive().Det();
|
||||
return d.Phase switch
|
||||
{
|
||||
> 7 * Math.PI / 4 or < Math.PI / 4 => 0,
|
||||
> Math.PI / 4 and < 3 * Math.PI / 4 => 1,
|
||||
> 3 * Math.PI / 4 and < 5 * Math.PI / 4 => 2,
|
||||
_ => 3
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// react within the homogeneous mixture
|
||||
/// </summary>
|
||||
public void React()
|
||||
{
|
||||
BaseBond[] connected = ConnectedIndex().ToArray();
|
||||
foreach (BaseBond bond in connected)
|
||||
{
|
||||
if (bond.Compound.Amount.IsEqualApprox(0))
|
||||
continue;
|
||||
if (
|
||||
bond.Energy > bond.AntiBondingEnergy &&
|
||||
bond.ConnectedBond.Energy > bond.ConnectedBond.AntiBondingEnergy
|
||||
)
|
||||
{
|
||||
bond.Disconnect();
|
||||
}
|
||||
|
||||
}
|
||||
for (int i = 1; i <= 3; i++)
|
||||
{
|
||||
BondGroups bg = ReactionGroup();
|
||||
int type = ReactionType();
|
||||
if(type == 0)
|
||||
{
|
||||
ReactConnecting(bg.Group1, bg.Group3);
|
||||
ReactConnecting(bg.Group2, bg.Group4);
|
||||
}
|
||||
else if (type == 1)
|
||||
{
|
||||
ReactConnecting(bg.Group1, bg.Group1);
|
||||
ReactConnecting(bg.Group3, bg.Group3);
|
||||
}
|
||||
else if (type == 2)
|
||||
{
|
||||
ReactConnecting(bg.Group2, bg.Group2);
|
||||
ReactConnecting(bg.Group3, bg.Group3);
|
||||
}
|
||||
else
|
||||
{
|
||||
ReactConnecting(bg.Group1, bg.Group4);
|
||||
ReactConnecting(bg.Group2, bg.Group3);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// higher level mixture can resolve lower level mixture
|
||||
/// </summary>
|
||||
public double ResolveLevel => Compounds.Sum(c => c.Concentration * c.ResolveLevel);
|
||||
/// <summary>
|
||||
/// ability to resolve other compound
|
||||
/// </summary>
|
||||
/// <param name="c"></param>
|
||||
/// <returns></returns>
|
||||
public double Resolvability(Compound c)
|
||||
{
|
||||
LieSU3 s = c.LogStateMatrix.Get ^ LogStateMatrix.Get;
|
||||
C3 a = new(1, 0.5, 1);
|
||||
C3 b = new(0.5, 1, 0.5);
|
||||
Complex w = a * s * b;
|
||||
w = ComplexFieldStructure.Structure.Fix(w);
|
||||
double res = -Math.Tan((Math.Sin(w.Phase) * Math.PI - Math.PI) / 2);
|
||||
if (Math.Abs(res) < 1E-6)
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
/// <summary>
|
||||
/// a tensor of order 3 abstracted from this mixture
|
||||
/// </summary>
|
||||
public C3 Ita => Compounds
|
||||
.Select(c => c.Concentration * c.StateMatrix.Get.ColumnAverageBivariant)
|
||||
.Aggregate((a, b) => a + b);
|
||||
/// <summary>
|
||||
/// Red component
|
||||
/// </summary>
|
||||
public Byte ColorRed => (Byte)
|
||||
(
|
||||
StateMatrix.Get
|
||||
.ConjugateOn(ChemistryConstant.OpticalFilter.RedDefinite)
|
||||
.Rayleigh(Ita) * 255
|
||||
);
|
||||
/// <summary>
|
||||
/// Green component
|
||||
/// </summary>
|
||||
public Byte ColorGreen => (Byte)
|
||||
(
|
||||
StateMatrix.Get
|
||||
.ConjugateOn(ChemistryConstant.OpticalFilter.GreenDefinite)
|
||||
.Rayleigh(Ita) * 255
|
||||
);
|
||||
/// <summary>
|
||||
/// Blue component
|
||||
/// </summary>
|
||||
public Byte ColorBlue => (Byte)
|
||||
(
|
||||
StateMatrix.Get
|
||||
.ConjugateOn(ChemistryConstant.OpticalFilter.BlueDefinite)
|
||||
.Rayleigh(Ita) * 255
|
||||
);
|
||||
/// <summary>
|
||||
/// Transparent component
|
||||
/// </summary>
|
||||
public Byte ColorTransparent => (Byte)
|
||||
(
|
||||
StateMatrix.Get
|
||||
.ConjugateOn(ChemistryConstant.OpticalFilter.OpacityDefinite)
|
||||
.Rayleigh(Ita) * 255
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Should not be used by any methods except ResolveNext and ResolvePrev
|
||||
/// </summary>
|
||||
private void PureResolve(HomogeneousMixture hOther)
|
||||
{
|
||||
HashSet<Compound> toAbsorb = new ();
|
||||
foreach (Compound c in hOther.Compounds)
|
||||
{
|
||||
double maxRes = Resolvability(c);
|
||||
double oRes = hOther.Resolvability(c);
|
||||
if(oRes < 0 || maxRes < 0 || maxRes < oRes)
|
||||
continue;
|
||||
double maxResAmount = Amount;
|
||||
foreach (Compound ct in Compounds)
|
||||
if (ct.IsometricTo(c))
|
||||
maxResAmount -= ct.Amount;
|
||||
maxResAmount *= maxRes;
|
||||
if(maxResAmount < 0)
|
||||
continue;
|
||||
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);
|
||||
}
|
||||
foreach (Compound c in toAbsorb)
|
||||
AddCompound(c);
|
||||
if(hOther.Amount.IsEqualApprox(0))
|
||||
HeterogeneousMixture.RemoveLayer(hOther);
|
||||
}
|
||||
private void ResolveNext()
|
||||
{
|
||||
if (HeterogeneousMixture == HeterogeneousMixture.Null || Layer.Next.IsTail)
|
||||
return;
|
||||
PureResolve(Layer.Next.Value);
|
||||
}
|
||||
private void ResolvePrevious()
|
||||
{
|
||||
if (HeterogeneousMixture == HeterogeneousMixture.Null || Layer.Previous.IsHead)
|
||||
return;
|
||||
PureResolve(Layer.Previous.Value);
|
||||
}
|
||||
|
||||
private bool Resolve()
|
||||
{
|
||||
ResolveNext();
|
||||
ResolvePrevious();
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool Precipitate()
|
||||
{
|
||||
foreach (Compound c in Compounds)
|
||||
{
|
||||
double maxRes = Resolvability(c);
|
||||
if (maxRes < 0)
|
||||
continue;
|
||||
double maxResAmount = maxRes * (Amount - c.Amount);
|
||||
if(maxResAmount.IsEqualApprox(0))
|
||||
continue;
|
||||
|
||||
double aDiff = c.Amount - maxResAmount;
|
||||
if (aDiff.IsSignificantlyGreaterThen(0) )
|
||||
{
|
||||
Compound oth = c.Split(c.Amount - maxResAmount);
|
||||
if (oth.FreeDensity.Get > FreeDensity.Get)
|
||||
{
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns>if any new layer created or deleted</returns>
|
||||
public bool PrecipitateAndResolve()
|
||||
{
|
||||
bool a = Resolve();
|
||||
bool b = Precipitate();
|
||||
return a || b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// combine identical compounds in the miture
|
||||
/// </summary>
|
||||
public void Degenerate()
|
||||
{
|
||||
HashSet<Compound> toRemove = new();
|
||||
foreach (IGrouping<string, Compound> g in Compounds.GroupBy(c => c.Expression))
|
||||
{
|
||||
HashSet<Compound> classified = new();
|
||||
foreach (Compound c in g)
|
||||
{
|
||||
classified.Add(c);
|
||||
foreach (Compound cx in g.Where(x => !classified.Contains(x)))
|
||||
{
|
||||
if (!c.IsometricTo(cx))
|
||||
continue;
|
||||
classified.Add(cx);
|
||||
c.Amount += cx.Amount;
|
||||
cx.Amount = 0;
|
||||
toRemove.Add(cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Compound c in toRemove)
|
||||
{
|
||||
c.HomogeneousMixture = Null;
|
||||
Compounds.Remove(c);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Test()
|
||||
{
|
||||
Func<double, double> a = x => -Math.Tan((Math.PI * x - Math.PI) / 2);
|
||||
Console.WriteLine(a(0));
|
||||
Console.WriteLine(a(-1));
|
||||
Console.WriteLine(a(1));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using VirtualChemistry.Chemistry.Mixtures.Implements;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Mixtures.Resolver;
|
||||
|
||||
/// <summary>
|
||||
/// get heterogeneous mixture from descriptions
|
||||
/// </summary>
|
||||
public static class HeterogeneousMixtureResolver
|
||||
{
|
||||
private const string LayersRegex = @"`LAYERS(.*)`%LAYERS";
|
||||
private static readonly Regex Matcher = new Regex(LayersRegex);
|
||||
/// <summary>
|
||||
/// split different homogeneous mixtures
|
||||
/// </summary>
|
||||
public const string LayerSplit = "<LayerSp>";
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="dumpString"></param>
|
||||
/// <returns></returns>
|
||||
public static HeterogeneousMixture Resolve(string dumpString)
|
||||
{
|
||||
HeterogeneousMixture res = new HeterogeneousMixture();
|
||||
string layers = Matcher.Match(dumpString).Result("$1");
|
||||
foreach (string layerString in layers.Split(LayerSplit))
|
||||
res.AddLayer(HomogeneousMixtureResolver.Resolve(layerString), false);
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using Skeleton.Utils;
|
||||
using VirtualChemistry.Chemistry.Compounds.Resolver;
|
||||
using VirtualChemistry.Chemistry.Mixtures.Implements;
|
||||
|
||||
namespace VirtualChemistry.Chemistry.Mixtures.Resolver;
|
||||
|
||||
/// <summary>
|
||||
/// get homogeneous mixture from description
|
||||
/// </summary>
|
||||
public static class HomogeneousMixtureResolver
|
||||
{
|
||||
private const string EnvironmentRegex = @"`ENV(.*)`%ENV";
|
||||
private const string CompoundsRegex = @"`COMPS(.*)`%COMPS";
|
||||
private const string MatchString = EnvironmentRegex + CompoundsRegex;
|
||||
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 static readonly Regex EnvMatcher = new Regex(EnvMatchString);
|
||||
/// <summary>
|
||||
/// split different compounds
|
||||
/// </summary>
|
||||
public const string CompoundsSplit = "<CompSp>";
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="dumpString"></param>
|
||||
/// <returns></returns>
|
||||
public static HomogeneousMixture Resolve(string dumpString)
|
||||
{
|
||||
Match result = Matcher.Match(dumpString);
|
||||
HomogeneousMixture res = new HomogeneousMixture();
|
||||
string envString = result.Result("$1");
|
||||
Match envRes = EnvMatcher.Match(envString);
|
||||
double volume = envRes.Result("$1").ByteStringToDouble();
|
||||
double energy = envRes.Result("$2").ByteStringToDouble();
|
||||
foreach (string compoundString in result.Result("$2").Split(CompoundsSplit))
|
||||
res.AddCompound(CompoundResolver.Resolve(compoundString));
|
||||
res.Volume = volume;
|
||||
res.Energy = energy;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
103
src/Constants/CachedKeys.cs
Normal file
103
src/Constants/CachedKeys.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
namespace VirtualChemistry.Constants;
|
||||
|
||||
/// <summary>
|
||||
/// keys for tensors
|
||||
/// </summary>
|
||||
public static class CachedKeys
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public const string StateMatrix = $"{TypePrefix.SU3}_StateMatrix";
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public const string LogStateMatrix = $"{TypePrefix.LieSU3}_LogStateMatrix";
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public const string StructureMatrix = $"{TypePrefix.SU3}_StructureMatrix";
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public const string LogConnectionMatrix = $"{TypePrefix.LieSU3}_LogConnectionMatrix";
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public const string EnergyDistributionFactor = $"{TypePrefix.Complex}_EnergyDistributionFactor";
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public const string HeatConductivity = $"{TypePrefix.Double}_HeatConductivity";
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public const string FreeDensity = $"{TypePrefix.Double}_FreeDensity";
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public const string CompressionStiffness = $"{TypePrefix.Double}_CompressionStiffness";
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public const string CompressionElasticity = $"{TypePrefix.Double}_CompressionElasticity";
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public const string CompressionBias = $"{TypePrefix.Double}_CompressionBias";
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public const string BondInformationMatrix = $"{TypePrefix.SU3}_BondInformationMatrix";
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public const string LogEigenStateMatrix = $"{TypePrefix.LieSU3}_LogEigenStateMatrix";
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public const string LogKernelMatrix = $"{TypePrefix.LieSU3}_LogKernelMatrix";
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public const string HalfBondInformation = $"{TypePrefix.LieSU3}_HalfBondInformation";
|
||||
}
|
||||
/// <summary>
|
||||
/// tensor type info
|
||||
/// </summary>
|
||||
public static class TypePrefix
|
||||
{
|
||||
/// <summary>
|
||||
/// real
|
||||
/// </summary>
|
||||
public const string Double = "D";
|
||||
/// <summary>
|
||||
/// complex
|
||||
/// </summary>
|
||||
public const string Complex = "C";
|
||||
/// <summary>
|
||||
/// c3
|
||||
/// </summary>
|
||||
public const string C3 = "C3";
|
||||
/// <summary>
|
||||
/// c33
|
||||
/// </summary>
|
||||
public const string C33 = "C33";
|
||||
/// <summary>
|
||||
/// u3
|
||||
/// </summary>
|
||||
public const string U3 = "U3";
|
||||
/// <summary>
|
||||
/// su3
|
||||
/// </summary>
|
||||
public const string SU3 = "SU3";
|
||||
/// <summary>
|
||||
/// lie u3
|
||||
/// </summary>
|
||||
public const string LieU3 = "LieU3";
|
||||
/// <summary>
|
||||
/// lie su3
|
||||
/// </summary>
|
||||
public const string LieSU3 = "LieSU3";
|
||||
|
||||
}
|
||||
653
src/Constants/ChemistryConstant.cs
Normal file
653
src/Constants/ChemistryConstant.cs
Normal file
@@ -0,0 +1,653 @@
|
||||
using System.Numerics;
|
||||
using Skeleton.Constants;
|
||||
using VirtualChemistry.Utils.Helpers;
|
||||
|
||||
namespace VirtualChemistry.Constants;
|
||||
|
||||
/// <summary>
|
||||
/// chemistry related constants
|
||||
/// </summary>
|
||||
public static class ChemistryConstant
|
||||
{
|
||||
private static readonly Complex I = Complex.ImaginaryOne;
|
||||
/// <summary>
|
||||
/// volume of a single atom
|
||||
/// </summary>
|
||||
public static readonly double AtomVolume = Math.Exp(-2 * Math.PI);
|
||||
|
||||
/// <summary>
|
||||
/// to calculate edv for atom
|
||||
/// </summary>
|
||||
public static readonly C3 AtomEnergyDistributionVector = new C3
|
||||
(
|
||||
Complex.Exp(Math.PI * I / 4d),
|
||||
Complex.Exp(Math.PI * I * 11d / 12d),
|
||||
Complex.Exp(Math.PI * I * 19d / 12d)
|
||||
);
|
||||
/// <summary>
|
||||
/// to calculate edv for bond
|
||||
/// </summary>
|
||||
public static readonly C3 BondEnergyDistributionVector = new C3
|
||||
(
|
||||
Complex.Exp(Math.PI * I * 5d / 4d),
|
||||
Complex.Exp(Math.PI * 23d / 12d),
|
||||
Complex.Exp(Math.PI * I * 7d / 12d)
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// to calculate edv from atom
|
||||
/// </summary>
|
||||
public static readonly DiagR3 AtomEnergyDistributionSpectrum = new DiagR3(1d / 4d, 11d / 12d, 19d / 12d);
|
||||
/// <summary>
|
||||
/// to calculate edv for bond
|
||||
/// </summary>
|
||||
public static readonly DiagR3 BondEnergyDistributionSpectrum = new DiagR3(5d / 4d, 23d / 12d, 7d / 12d);
|
||||
/// <summary>
|
||||
/// to calculate energy conductivity
|
||||
/// </summary>
|
||||
public static readonly DiagR3 EnergyConductivitySpectrum = new DiagR3(2d/15d, 7d/15d, 11d/15d);
|
||||
/// <summary>
|
||||
/// all bond types
|
||||
/// </summary>
|
||||
public static class BondTypes
|
||||
{
|
||||
/// <summary>
|
||||
/// type m
|
||||
/// </summary>
|
||||
public const string M = "m";
|
||||
/// <summary>
|
||||
/// type s
|
||||
/// </summary>
|
||||
public const string S = "s";
|
||||
/// <summary>
|
||||
/// type d
|
||||
/// </summary>
|
||||
public const string D = "d";
|
||||
/// <summary>
|
||||
/// type y
|
||||
/// </summary>
|
||||
public const string Y = "y";
|
||||
/// <summary>
|
||||
/// type q
|
||||
/// </summary>
|
||||
public const string Q = "q";
|
||||
/// <summary>
|
||||
/// type p
|
||||
/// </summary>
|
||||
public const string P = "p";
|
||||
/// <summary>
|
||||
/// type h
|
||||
/// </summary>
|
||||
public const string H = "h";
|
||||
/// <summary>
|
||||
/// all types
|
||||
/// </summary>
|
||||
public static readonly string[] All = new[] { M, S, D, Y, Q, P, H };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// all atom types
|
||||
/// </summary>
|
||||
public static class Elements
|
||||
{
|
||||
/// <summary>
|
||||
/// atom q
|
||||
/// </summary>
|
||||
public const string Q = "Q";
|
||||
/// <summary>
|
||||
/// atom r
|
||||
/// </summary>
|
||||
public const string R = "R";
|
||||
/// <summary>
|
||||
/// atom es
|
||||
/// </summary>
|
||||
public const string Es = "Es";
|
||||
/// <summary>
|
||||
/// atom d
|
||||
/// </summary>
|
||||
public const string D = "D";
|
||||
/// <summary>
|
||||
/// atom ue
|
||||
/// </summary>
|
||||
public const string Ue = "Ue";
|
||||
/// <summary>
|
||||
/// atom m
|
||||
/// </summary>
|
||||
public const string M = "M";
|
||||
/// <summary>
|
||||
/// atom k
|
||||
/// </summary>
|
||||
public const string K = "K";
|
||||
/// <summary>
|
||||
/// atom p
|
||||
/// </summary>
|
||||
public const string P = "P";
|
||||
/// <summary>
|
||||
/// atom so
|
||||
/// </summary>
|
||||
public const string So = "So";
|
||||
/// <summary>
|
||||
/// atom e
|
||||
/// </summary>
|
||||
public const string E = "E";
|
||||
/// <summary>
|
||||
/// atom u
|
||||
/// </summary>
|
||||
public const string U = "U";
|
||||
/// <summary>
|
||||
/// atom a
|
||||
/// </summary>
|
||||
public const string A = "A";
|
||||
/// <summary>
|
||||
/// atom cx
|
||||
/// </summary>
|
||||
public const string Cx = "Cx";
|
||||
/// <summary>
|
||||
/// atom v
|
||||
/// </summary>
|
||||
public const string V = "V";
|
||||
/// <summary>
|
||||
/// atom vi
|
||||
/// </summary>
|
||||
public const string Vi = "Vi";
|
||||
}
|
||||
|
||||
private static double AtomicMass(int atomicNumber) =>
|
||||
Math.Tan(ChemistryHelper.AtomHeightOrder(atomicNumber) * Math.PI / 2d);
|
||||
|
||||
private static SU3 AtomEigenState(int atomicNumber)
|
||||
{
|
||||
SU3 dam = ChemistryHelper.AtomAdjointStateMatrix(atomicNumber);
|
||||
return dam.ConjugateOn(ChemistryHelper.AtomKernel(atomicNumber));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// adjoint matrices for atom
|
||||
/// </summary>
|
||||
public static class AtomAdjoints
|
||||
{
|
||||
/// <summary>
|
||||
/// for q
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomAdjointStateQ = ChemistryHelper.AtomAdjointStateMatrix(1);
|
||||
/// <summary>
|
||||
/// for r
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomAdjointStateR = ChemistryHelper.AtomAdjointStateMatrix(2);
|
||||
/// <summary>
|
||||
/// for es
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomAdjointStateEs = ChemistryHelper.AtomAdjointStateMatrix(3);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomAdjointStateD = ChemistryHelper.AtomAdjointStateMatrix(4);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomAdjointStateUe = ChemistryHelper.AtomAdjointStateMatrix(5);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomAdjointStateM = ChemistryHelper.AtomAdjointStateMatrix(6);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomAdjointStateK = ChemistryHelper.AtomAdjointStateMatrix(7);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomAdjointStateP = ChemistryHelper.AtomAdjointStateMatrix(8);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomAdjointStateSo = ChemistryHelper.AtomAdjointStateMatrix(9);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomAdjointStateE = ChemistryHelper.AtomAdjointStateMatrix(10);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomAdjointStateU = ChemistryHelper.AtomAdjointStateMatrix(11);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomAdjointStateA = ChemistryHelper.AtomAdjointStateMatrix(12);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomAdjointStateCx = ChemistryHelper.AtomAdjointStateMatrix(13);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomAdjointStateV = ChemistryHelper.AtomAdjointStateMatrix(14);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomAdjointStateVi = ChemistryHelper.AtomAdjointStateMatrix(15);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static class AtomKernels
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomKernelStateQ = ChemistryHelper.AtomKernel(1);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomKernelStateR = ChemistryHelper.AtomKernel(2);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomKernelStateEs = ChemistryHelper.AtomKernel(3);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomKernelStateD = ChemistryHelper.AtomKernel(4);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomKernelStateUe = ChemistryHelper.AtomKernel(5);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomKernelStateM = ChemistryHelper.AtomKernel(6);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomKernelStateK = ChemistryHelper.AtomKernel(7);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomKernelStateP = ChemistryHelper.AtomKernel(8);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomKernelStateSo = ChemistryHelper.AtomKernel(9);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomKernelStateE = ChemistryHelper.AtomKernel(10);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomKernelStateU = ChemistryHelper.AtomKernel(11);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomKernelStateA = ChemistryHelper.AtomKernel(12);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomKernelStateCx = ChemistryHelper.AtomKernel(13);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomKernelStateV = ChemistryHelper.AtomKernel(14);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomKernelStateVi = ChemistryHelper.AtomKernel(15);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// atom eigen state matrices
|
||||
/// </summary>
|
||||
public static class AtomEigenStates
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomEigenStateQ = AtomEigenState(1);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomEigenStateR = AtomEigenState(2);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomEigenStateEs = AtomEigenState(3);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomEigenStateD = AtomEigenState(4);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomEigenStateUe = AtomEigenState(5);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomEigenStateM = AtomEigenState(6);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomEigenStateK = AtomEigenState(7);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomEigenStateP = AtomEigenState(8);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomEigenStateSo = AtomEigenState(9);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomEigenStateE = AtomEigenState(10);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomEigenStateU = AtomEigenState(11);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomEigenStateA = AtomEigenState(12);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomEigenStateCx = AtomEigenState(13);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomEigenStateV = AtomEigenState(14);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomEigenStateVi = AtomEigenState(15);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// atomic masses for atoms
|
||||
/// </summary>
|
||||
public static class AtomicMasses
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly double AtomicMassQ = AtomicMass(1);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly double AtomicMassR = AtomicMass(2);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly double AtomicMassEs = AtomicMass(3);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly double AtomicMassD = AtomicMass(4);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly double AtomicMassUe = AtomicMass(5);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly double AtomicMassM = AtomicMass(6);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly double AtomicMassK = AtomicMass(7);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly double AtomicMassP = AtomicMass(8);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly double AtomicMassSo = AtomicMass(9);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly double AtomicMassE = AtomicMass(10);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly double AtomicMassU = AtomicMass(11);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly double AtomicMassA = AtomicMass(12);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly double AtomicMassCx = AtomicMass(13);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly double AtomicMassV = AtomicMass(14);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly double AtomicMassVi = AtomicMass(15);
|
||||
|
||||
}
|
||||
|
||||
private static SU3 BondEigenState(int bondNumber)
|
||||
{
|
||||
SU3 dam = ChemistryHelper.BondAdjointStateMatrix(bondNumber);
|
||||
return dam.ConjugateOn(ChemistryHelper.BondKernel(bondNumber));
|
||||
}
|
||||
/// <summary>
|
||||
/// kernel matrices for bonds
|
||||
/// </summary>
|
||||
public static class BondKernels
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 BondKernelM = ChemistryHelper.BondKernel(1);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 BondKernelS = ChemistryHelper.BondKernel(2);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 BondKernelD = ChemistryHelper.BondKernel(3);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 BondKernelY = ChemistryHelper.BondKernel(4);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 BondKernelQ = ChemistryHelper.BondKernel(5);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 BondKernelP = ChemistryHelper.BondKernel(6);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 BondKernelH = ChemistryHelper.BondKernel(7);
|
||||
}
|
||||
/// <summary>
|
||||
/// adjoint matrices for bond
|
||||
/// </summary>
|
||||
public static class BondAdjoints
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 BondAdjointM = ChemistryHelper.BondAdjointStateMatrix(1);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 BondAdjointS = ChemistryHelper.BondAdjointStateMatrix(2);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 BondAdjointD = ChemistryHelper.BondAdjointStateMatrix(3);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 BondAdjointY = ChemistryHelper.BondAdjointStateMatrix(4);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 BondAdjointQ = ChemistryHelper.BondAdjointStateMatrix(5);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 BondAdjointP = ChemistryHelper.BondAdjointStateMatrix(6);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 BondAdjointH = ChemistryHelper.BondAdjointStateMatrix(7);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// eigen state matrices for bond
|
||||
/// </summary>
|
||||
public static class BondEigenStates
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 BondEigenStateM = BondEigenState(1);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 BondEigenStateS = BondEigenState(2);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 BondEigenStateD = BondEigenState(3);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 BondEigenStateY = BondEigenState(4);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 BondEigenStateQ = BondEigenState(5);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 BondEigenStateP = BondEigenState(6);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 BondEigenStateH = BondEigenState(7);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// max bond numbers for specific bond number
|
||||
/// </summary>
|
||||
/// <param name="bondNumber"></param>
|
||||
/// <returns></returns>
|
||||
public static int BondMaxNumbers(int bondNumber) => bondNumber switch
|
||||
{
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => 1,
|
||||
4 => 2,
|
||||
5 => 2,
|
||||
6 => 1,
|
||||
7 => 2,
|
||||
_ => -1
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// filters to calculate the color of mixtures
|
||||
/// </summary>
|
||||
public static class OpticalFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// to calculate redness
|
||||
/// </summary>
|
||||
public static readonly U3 RedFilter = new LieU3
|
||||
(
|
||||
I,0, -1,
|
||||
0, I, 0,
|
||||
1, 0, -I
|
||||
).Exp();
|
||||
|
||||
/// <summary>
|
||||
/// to calculate greenness
|
||||
/// </summary>
|
||||
public static readonly U3 GreenFilter = new LieU3
|
||||
(
|
||||
0, -I, 0,
|
||||
-I, 0, -1,
|
||||
0, 1, 0
|
||||
).Exp();
|
||||
/// <summary>
|
||||
/// to calculate blueness
|
||||
/// </summary>
|
||||
public static readonly U3 BlueFilter = new LieU3
|
||||
(
|
||||
0, 0, -I,
|
||||
0, 0, -1,
|
||||
-I, 1, 0
|
||||
).Exp();
|
||||
/// <summary>
|
||||
/// to calculate alpha channel
|
||||
/// </summary>
|
||||
public static readonly U3 OpacityFilter = new LieU3(
|
||||
I, -I, -I,
|
||||
-I, I, -1,
|
||||
-I, 1, -I
|
||||
).Exp();
|
||||
|
||||
/// <summary>
|
||||
/// red
|
||||
/// </summary>
|
||||
public static readonly H3 RedDefinite = RedFilter.ConjugateOn(AlgebraConstant.UniformSpectrum3);
|
||||
/// <summary>
|
||||
/// green
|
||||
/// </summary>
|
||||
public static readonly H3 GreenDefinite = GreenFilter.ConjugateOn(AlgebraConstant.UniformSpectrum3);
|
||||
/// <summary>
|
||||
/// blue
|
||||
/// </summary>
|
||||
public static readonly H3 BlueDefinite = BlueFilter.ConjugateOn(AlgebraConstant.UniformSpectrum3);
|
||||
/// <summary>
|
||||
/// alpha
|
||||
/// </summary>
|
||||
public static readonly H3 OpacityDefinite = OpacityFilter.ConjugateOn(new DiagR3(0.05d, 0.74d, 1d));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// all elements
|
||||
/// </summary>
|
||||
public static readonly string[] ElementSymbols =
|
||||
{
|
||||
"Q", "R", "Es", "D", "Ue",
|
||||
"M", "K", "P", "So", "E",
|
||||
"U", "A", "Cx", "V", "Vi"
|
||||
};
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// x
|
||||
/// </summary>
|
||||
public static class CommonResources
|
||||
{
|
||||
/// <summary>
|
||||
/// x
|
||||
/// </summary>
|
||||
public const string Letroline = "res://Data/Chemicals/HighEnergyMixtureLetroline.btx";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to measure Cayley value of homogeneous mixture
|
||||
/// </summary>
|
||||
public static readonly C3 CayleyMeasure = new (1 - I, I, -1 + I);
|
||||
/// <summary>
|
||||
/// Used to measure Euclid value of homogeneous mixture
|
||||
/// </summary>
|
||||
public static readonly C3 EuclidMeasure = new(1, I, -I);
|
||||
|
||||
}
|
||||
54
src/DataStructure/Caches/Cache.cs
Normal file
54
src/DataStructure/Caches/Cache.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using Skeleton.Utils.Helpers;
|
||||
|
||||
namespace VirtualChemistry.DataStructure.Caches;
|
||||
|
||||
/// <summary>
|
||||
/// cache to store a specific type of data
|
||||
/// </summary>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
public class Cache<TValue> : Dictionary<string, TValue>, ICache
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public Cache()
|
||||
{
|
||||
UpdateRequest = new HashSet<string>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// indexer
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="getter">re calculate by getter if key is expired of no value stored in the specified key</param>
|
||||
public TValue this[string key, Func<TValue> getter]
|
||||
{
|
||||
get
|
||||
{
|
||||
if(ValueOutdated(key))
|
||||
{
|
||||
UpdateRequest.Remove(key);
|
||||
return this[key] = getter();
|
||||
}
|
||||
return this[key];
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void DeleteCache()
|
||||
{
|
||||
Keys.ForEach(x => Remove(x));
|
||||
UpdateRequest = new HashSet<string>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void DeleteCache(string key) => Remove(key);
|
||||
private HashSet<string> UpdateRequest { get; set; }
|
||||
private bool ValueOutdated(string key) => !ContainsKey(key) || UpdateRequest.Contains(key);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Expire(string key) => UpdateRequest.Add(key);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Expire(IEnumerable<string> keys) => keys.ForEach(Expire);
|
||||
|
||||
|
||||
}
|
||||
156
src/DataStructure/Caches/GeneralCache.cs
Normal file
156
src/DataStructure/Caches/GeneralCache.cs
Normal file
@@ -0,0 +1,156 @@
|
||||
using System.Numerics;
|
||||
using Skeleton.Utils.Helpers;
|
||||
|
||||
namespace VirtualChemistry.DataStructure.Caches;
|
||||
|
||||
/// <summary>
|
||||
/// a general propose cache to store many type of tensors
|
||||
/// </summary>
|
||||
public class GeneralCache
|
||||
{
|
||||
private Cache<C3> C3Cache { get; set; } = new();
|
||||
private Cache<C33> C33Cache { get; set; } = new();
|
||||
private Cache<Complex> ComplexCache { get; set; } = new();
|
||||
private Cache<double> DoubleCache { get; set; } = new();
|
||||
private Cache<U3> U3Cache { get; set; } = new();
|
||||
private Cache<SU3> SU3Cache { get; set; } = new();
|
||||
private Cache<LieU3> LieU3Cache { get; set; } = new();
|
||||
private Cache<LieSU3> LieSU3Cache { get; set; } = new();
|
||||
|
||||
private static T Identity<T>(T x) => x;
|
||||
private Func<T, T> RegisterOnExpire<T>(string key, Action? e)
|
||||
{
|
||||
|
||||
if (e != null && !OnExpire.ContainsKey(key))
|
||||
OnExpire[key] = e;
|
||||
return Identity<T>;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// C3 tensor getter
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="getter"></param>
|
||||
/// <param name="onExpire">a function to expire other keys if this key is expired</param>
|
||||
public C3 this[string key, Func<C3> getter, Action? onExpire = null] =>
|
||||
RegisterOnExpire<C3>(key, onExpire)(C3Cache[key, getter]);
|
||||
|
||||
/// <summary>
|
||||
/// C33 tensor getter
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="getter"></param>
|
||||
/// <param name="onExpire"></param>
|
||||
public C33 this[string key, Func<C33> getter, Action? onExpire = null] =>
|
||||
RegisterOnExpire<C33>(key, onExpire)(C33Cache[key, getter]);
|
||||
/// <summary>
|
||||
/// complex getter
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="getter"></param>
|
||||
/// <param name="onExpire"></param>
|
||||
public Complex this[string key, Func<Complex> getter, Action? onExpire = null] =>
|
||||
RegisterOnExpire<Complex>(key, onExpire)(ComplexCache[key, getter]);
|
||||
/// <summary>
|
||||
/// real getter
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="getter"></param>
|
||||
/// <param name="onExpire"></param>
|
||||
public double this[string key, Func<double> getter, Action? onExpire = null] =>
|
||||
RegisterOnExpire<double>(key, onExpire)(DoubleCache[key, getter]);
|
||||
|
||||
/// <summary>
|
||||
/// U3 getter
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="getter"></param>
|
||||
/// <param name="onExpire"></param>
|
||||
public U3 this[string key, Func<U3> getter, Action? onExpire = null] =>
|
||||
RegisterOnExpire<U3>(key, onExpire)(U3Cache[key, getter]);
|
||||
|
||||
/// <summary>
|
||||
/// SU3 getter
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="getter"></param>
|
||||
/// <param name="onExpire"></param>
|
||||
public SU3 this[string key, Func<SU3> getter, Action? onExpire = null] =>
|
||||
RegisterOnExpire<SU3>(key, onExpire)(SU3Cache[key, getter]);
|
||||
|
||||
/// <summary>
|
||||
/// LieU3 getter
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="getter"></param>
|
||||
/// <param name="onExpire"></param>
|
||||
public LieU3 this[string key, Func<LieU3> getter, Action? onExpire = null] =>
|
||||
RegisterOnExpire<LieU3>(key, onExpire)(LieU3Cache[key, getter]);
|
||||
|
||||
/// <summary>
|
||||
/// LieSU3 getter
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="getter"></param>
|
||||
/// <param name="onExpire"></param>
|
||||
public LieSU3 this[string key, Func<LieSU3> getter, Action? onExpire = null] =>
|
||||
RegisterOnExpire<LieSU3>(key, onExpire)(LieSU3Cache[key, getter]);
|
||||
|
||||
/// <summary>
|
||||
/// general propose getter
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public ICache this[string key] => key.Split('_')[0] switch
|
||||
{
|
||||
"D" => DoubleCache,
|
||||
"C" => ComplexCache,
|
||||
"C3" => C3Cache,
|
||||
"C33" => C33Cache,
|
||||
"U3" => U3Cache,
|
||||
"SU3" => SU3Cache,
|
||||
"LieU3" => LieU3Cache,
|
||||
"LieSU3" => LieSU3Cache,
|
||||
_ => throw new Exception()
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// general expire
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
public void Expire(string key)
|
||||
{
|
||||
if (OnExpire.ContainsKey(key))
|
||||
OnExpire[key]();
|
||||
this[key].Expire(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// general expire
|
||||
/// </summary>
|
||||
/// <param name="keys"></param>
|
||||
public void Expire(IEnumerable<string> keys) => keys.ForEach(Expire);
|
||||
/// <summary>
|
||||
/// general delete cache
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
public void DeleteCache(string key) => this[key].DeleteCache(key);
|
||||
|
||||
/// <summary>
|
||||
/// trigger the action when key is expired
|
||||
/// </summary>
|
||||
public Dictionary<string, Action> OnExpire { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// get raw real(constant)
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public double GetRaw(string key) => DoubleCache.GetValueOrDefault(key);
|
||||
/// <summary>
|
||||
/// init a constant real
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
public void SetRaw(string key, double value) => DoubleCache[key] = value;
|
||||
}
|
||||
27
src/DataStructure/Caches/ICache.cs
Normal file
27
src/DataStructure/Caches/ICache.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
namespace VirtualChemistry.DataStructure.Caches;
|
||||
|
||||
/// <summary>
|
||||
/// interface for cache
|
||||
/// </summary>
|
||||
public interface ICache
|
||||
{
|
||||
/// <summary>
|
||||
/// delete all cache
|
||||
/// </summary>
|
||||
public void DeleteCache();
|
||||
/// <summary>
|
||||
/// delete for a specific key
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
public void DeleteCache(string key);
|
||||
/// <summary>
|
||||
/// expire a key, the value need to be re calculated from getter
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
public void Expire(string key);
|
||||
/// <summary>
|
||||
/// expire a set of keys
|
||||
/// </summary>
|
||||
/// <param name="keys"></param>
|
||||
public void Expire(IEnumerable<string> keys);
|
||||
}
|
||||
33
src/DataStructure/Packs/BondGroups.cs
Normal file
33
src/DataStructure/Packs/BondGroups.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using Skeleton.DataStructure.Packs;
|
||||
using VirtualChemistry.Chemistry.Bonds.Implements;
|
||||
|
||||
namespace VirtualChemistry.DataStructure.Packs;
|
||||
|
||||
using BondGroup = HashSet<BaseBond>;
|
||||
|
||||
/// <inheritdoc />
|
||||
public class BondGroups : Pack4<BondGroup, BondGroup, BondGroup, BondGroup>
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public BondGroup Group1 => Item1;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public BondGroup Group2 => Item2;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public BondGroup Group3 => Item3;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public BondGroup Group4 => Item4;
|
||||
|
||||
/// <inheritdoc />
|
||||
public BondGroups(BondGroup g1, BondGroup g2, BondGroup g3, BondGroup g4) : base(g1, g2, g3, g4)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
67
src/DataStructure/Packs/CompoundMap.cs
Normal file
67
src/DataStructure/Packs/CompoundMap.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using Skeleton.DataStructure.Packs;
|
||||
using VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
using VirtualChemistry.Chemistry.Bonds.Implements;
|
||||
using VirtualChemistry.Chemistry.Compounds.Implements;
|
||||
|
||||
namespace VirtualChemistry.DataStructure.Packs;
|
||||
|
||||
/// <summary>
|
||||
/// compound dump map
|
||||
/// </summary>
|
||||
public class CompoundDumpMap : Pack3<Dictionary<BaseAtom, string>, Dictionary<BaseBond, string>, string>
|
||||
{
|
||||
/// <summary>
|
||||
/// atom map
|
||||
/// </summary>
|
||||
public Dictionary<BaseAtom, string> AtomMap => Item1;
|
||||
/// <summary>
|
||||
/// bond map
|
||||
/// </summary>
|
||||
public Dictionary<BaseBond, string> BondMap => Item2;
|
||||
/// <summary>
|
||||
/// save string
|
||||
/// </summary>
|
||||
public string DumpString => Item3;
|
||||
|
||||
/// <summary>
|
||||
/// constructor
|
||||
/// </summary>
|
||||
/// <param name="atomMap"></param>
|
||||
/// <param name="bondMap"></param>
|
||||
/// <param name="dumpString"></param>
|
||||
public CompoundDumpMap(Dictionary<BaseAtom, string> atomMap, Dictionary<BaseBond, string> bondMap, string dumpString) :
|
||||
base(atomMap, bondMap, dumpString)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// resolve map for compound
|
||||
/// </summary>
|
||||
public class CompoundResolveMap : Pack3<Dictionary<string, BaseAtom>, Dictionary<string, BaseBond>, Compound>
|
||||
{
|
||||
/// <summary>
|
||||
/// atom map
|
||||
/// </summary>
|
||||
public Dictionary<string, BaseAtom> AtomMap => Item1;
|
||||
/// <summary>
|
||||
/// bond map
|
||||
/// </summary>
|
||||
public Dictionary<string, BaseBond> BondMap => Item2;
|
||||
/// <summary>
|
||||
/// created compound
|
||||
/// </summary>
|
||||
public Compound ResolvedCompound => Item3;
|
||||
|
||||
/// <summary>
|
||||
/// constructor
|
||||
/// </summary>
|
||||
/// <param name="atomMap"></param>
|
||||
/// <param name="bondMap"></param>
|
||||
/// <param name="resolvedCompound"></param>
|
||||
public CompoundResolveMap(Dictionary<string, BaseAtom> atomMap, Dictionary<string, BaseBond> bondMap,
|
||||
Compound resolvedCompound) :
|
||||
base(atomMap, bondMap, resolvedCompound)
|
||||
{
|
||||
}
|
||||
}
|
||||
37
src/DataStructure/Packs/ConnectionInfo.cs
Normal file
37
src/DataStructure/Packs/ConnectionInfo.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using Skeleton.DataStructure.Packs;
|
||||
using VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
using VirtualChemistry.Chemistry.Bonds.Implements;
|
||||
|
||||
namespace VirtualChemistry.DataStructure.Packs;
|
||||
|
||||
/// <summary>
|
||||
/// connection info of an atom and a bond
|
||||
/// </summary>
|
||||
public class ConnectionInfo : Pack3<BaseBond, BaseBond, BaseAtom>
|
||||
{
|
||||
/// <summary>
|
||||
/// constructor
|
||||
/// </summary>
|
||||
/// <param name="bondFrom"></param>
|
||||
/// <param name="bondTo"></param>
|
||||
/// <param name="connectedAtom"></param>
|
||||
public ConnectionInfo(BaseBond bondFrom, BaseBond bondTo, BaseAtom connectedAtom)
|
||||
{
|
||||
Item1 = bondFrom;
|
||||
Item2 = bondTo;
|
||||
Item3 = connectedAtom;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// from bond
|
||||
/// </summary>
|
||||
public BaseBond BondFrom => Item1;
|
||||
/// <summary>
|
||||
/// to bond
|
||||
/// </summary>
|
||||
public BaseBond BondTo => Item2;
|
||||
/// <summary>
|
||||
/// to atom
|
||||
/// </summary>
|
||||
public BaseAtom ConnectedAtom => Item3;
|
||||
}
|
||||
64
src/DataStructure/Packs/FullConnectionInfo.cs
Normal file
64
src/DataStructure/Packs/FullConnectionInfo.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using Skeleton.DataStructure.Packs;
|
||||
using VirtualChemistry.Chemistry.Atoms.Implements;
|
||||
using VirtualChemistry.Chemistry.Bonds.Implements;
|
||||
|
||||
namespace VirtualChemistry.DataStructure.Packs;
|
||||
|
||||
/// <summary>
|
||||
/// all connections from one atom to another
|
||||
/// </summary>
|
||||
public class FullConnectionInfo : Pack3<BaseAtom, HashSet<BaseBond>, BaseAtom>
|
||||
{
|
||||
/// <summary>
|
||||
/// constructor
|
||||
/// </summary>
|
||||
/// <param name="bond"></param>
|
||||
public FullConnectionInfo(BaseBond bond) : base(bond.Atom, new HashSet<BaseBond>() { bond }, bond.ConnectedBond.Atom)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// from atom
|
||||
/// </summary>
|
||||
public BaseAtom Atom1 => Item1;
|
||||
/// <summary>
|
||||
/// connected bonds
|
||||
/// </summary>
|
||||
public HashSet<BaseBond> Bonds => Item2;
|
||||
/// <summary>
|
||||
/// bonds of atom 1
|
||||
/// </summary>
|
||||
public BaseAtom Atom2 => Item3;
|
||||
private string OnwRepresentation => $"{Atom1.Element}-[{String.Join('|', Bonds.Select(bond => $"{bond.BondType}-{bond.ConnectedBond.BondType}"))}]-{Atom2.Element}";
|
||||
private string RevRepresentation => $"{Atom2.Element}-[{String.Join('|', Bonds.Select(bond => $"{bond.ConnectedBond.BondType}-{bond.BondType}"))}]-{Atom1.Element}";
|
||||
|
||||
/// <summary>
|
||||
/// save string
|
||||
/// </summary>
|
||||
public string Representation => Atom1.AtomicNumber + Bonds.Sum(bond => bond.BondNumber) >
|
||||
Atom2.AtomicNumber + Bonds.Sum(bond => bond.ConnectedBond.BondNumber)
|
||||
? OnwRepresentation
|
||||
: RevRepresentation;
|
||||
|
||||
/// <summary>
|
||||
/// try to add a bond to bonds
|
||||
/// </summary>
|
||||
/// <param name="bond"></param>
|
||||
/// <returns></returns>
|
||||
public bool TryAbsorbBond(BaseBond bond)
|
||||
{
|
||||
if(bond.Atom == Atom1 && bond.ConnectedBond.Atom == Atom2)
|
||||
{
|
||||
Bonds.Add(bond);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (bond.Atom == Atom2 && bond.ConnectedBond.Atom == Atom1)
|
||||
{
|
||||
Bonds.Add(bond.ConnectedBond);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
42
src/Using.cs
Normal file
42
src/Using.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
global using C2 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim2>.OnField<System.Numerics.Complex>.FVector;
|
||||
global using C3 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim3>.OnField<System.Numerics.Complex>.FVector;
|
||||
global using C4 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim4>.OnField<System.Numerics.Complex>.FVector;
|
||||
|
||||
global using R2 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim2>.OnField<double>.FVector;
|
||||
global using R3 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim3>.OnField<double>.FVector;
|
||||
global using R4 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim4>.OnField<double>.FVector;
|
||||
|
||||
global using C22 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim2>.OnField<System.Numerics.Complex>.FMatrix;
|
||||
global using C33 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim3>.OnField<System.Numerics.Complex>.FMatrix;
|
||||
global using C44 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim4>.OnField<System.Numerics.Complex>.FMatrix;
|
||||
|
||||
global using R22 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim2>.OnField<double>.FMatrix;
|
||||
global using R33 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim3>.OnField<double>.FMatrix;
|
||||
global using R44 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim4>.OnField<double>.FMatrix;
|
||||
|
||||
global using U2 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim2>.FUnitaryMatrix;
|
||||
global using U3 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim3>.FUnitaryMatrix;
|
||||
global using U4 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim4>.FUnitaryMatrix;
|
||||
|
||||
global using SU2 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim2>.FSpecialUnitaryMatrix;
|
||||
global using SU3 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim3>.FSpecialUnitaryMatrix;
|
||||
global using SU4 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim4>.FSpecialUnitaryMatrix;
|
||||
|
||||
global using LieU2 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim2>.FLieUnitaryMatrix;
|
||||
global using LieU3 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim3>.FLieUnitaryMatrix;
|
||||
global using LieU4 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim4>.FLieUnitaryMatrix;
|
||||
|
||||
global using LieSU2 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim2>.FSpecialLieUnitaryMatrix;
|
||||
global using LieSU3 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim3>.FSpecialLieUnitaryMatrix;
|
||||
global using LieSU4 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim4>.FSpecialLieUnitaryMatrix;
|
||||
|
||||
global using C2Space = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim2>.OnField<System.Numerics.Complex>.FVectorSpace;
|
||||
global using C3Space = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim3>.OnField<System.Numerics.Complex>.FVectorSpace;
|
||||
global using C4Space = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim4>.OnField<System.Numerics.Complex>.FVectorSpace;
|
||||
|
||||
global using R2Space = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim2>.OnField<double>.FVectorSpace;
|
||||
global using R3Space = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim3>.OnField<double>.FVectorSpace;
|
||||
global using R4Space = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim4>.OnField<double>.FVectorSpace;
|
||||
|
||||
global using DiagR3 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim3>.OnField<double>.FDiagonalMatrix;
|
||||
global using H3 = Skeleton.Algebra.CategoryOf<Skeleton.Algebra.DimensionProviders.IDim3>.FHermitianMatrix;
|
||||
282
src/Utils/Helpers/ChemistryHelper.cs
Normal file
282
src/Utils/Helpers/ChemistryHelper.cs
Normal file
@@ -0,0 +1,282 @@
|
||||
using System.Numerics;
|
||||
|
||||
namespace VirtualChemistry.Utils.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// helper functions for chemistry
|
||||
/// </summary>
|
||||
public static class ChemistryHelper
|
||||
{
|
||||
private static readonly Complex I = Complex.ImaginaryOne;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="n"></param>
|
||||
/// <returns></returns>
|
||||
public static double BondHeightOrder(int n) => Math.Pow(4d / 5d, n) - 1;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="n"></param>
|
||||
/// <returns></returns>
|
||||
public static double BondWeightOrder(int n)
|
||||
{
|
||||
double ra = n / 11d;
|
||||
int det = (int)Math.Floor(ra / 0.5d);
|
||||
if (det % 2 == 0)
|
||||
return ra % 0.5d;
|
||||
return 0.5 - (ra % 0.5d);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="n"></param>
|
||||
/// <returns></returns>
|
||||
public static Complex BondHeight(int n) => Complex.Exp(I * Math.PI * BondHeightOrder(n));
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="n"></param>
|
||||
/// <returns></returns>
|
||||
public static Complex BondWeight(int n) => Complex.Exp(I * Math.PI * BondWeightOrder(n));
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="n"></param>
|
||||
/// <returns></returns>
|
||||
public static Complex BondE1(int n) => BondHeight(n);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="n"></param>
|
||||
/// <returns></returns>
|
||||
public static Complex BondE2(int n) => BondWeight(n);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="n"></param>
|
||||
/// <returns></returns>
|
||||
public static Complex BondE3(int n) => 1 / (BondE1(n)*BondE2(n));
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="p"></param>
|
||||
/// <returns></returns>
|
||||
public static SU3 BondKernel(int p) => new
|
||||
(
|
||||
BondE1(p), 0, 0,
|
||||
0, BondE2(p), 0,
|
||||
0, 0, BondE3(p)
|
||||
);
|
||||
|
||||
|
||||
|
||||
private static readonly double Sqrt13 = Math.Sqrt(13d);
|
||||
private static readonly double Sqrt7 = Math.Sqrt(7d);
|
||||
private static readonly double Sqrt3 = Math.Sqrt(3d);
|
||||
private static readonly double Sqrt2 = Math.Sqrt(2d);
|
||||
private static readonly double Sqrt21 = Sqrt3 * Sqrt7;
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly Complex BondAdjointEigen1 = I * Math.Sqrt(0.5d * (5d + Sqrt21));
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly Complex BondAdjointEigen2 = I * Math.Sqrt(0.5d * (5d - Sqrt21));
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly C3 BondAdjointEigenVector1 = new C3
|
||||
(
|
||||
1d/Sqrt2,
|
||||
-I/2d,
|
||||
1/2
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly C3 BondAdjointEigenVector2 = new C3
|
||||
(
|
||||
0,
|
||||
I/Sqrt2,
|
||||
1d/Sqrt2
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly C3 BondAdjointEigenVector3 = new C3
|
||||
(
|
||||
-1d/Sqrt2,
|
||||
I/Sqrt2,
|
||||
1d/2d
|
||||
);
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly C33 BondAdjointCoMatrix =
|
||||
new C33(new[] { BondAdjointEigenVector1, BondAdjointEigenVector2, BondAdjointEigenVector3 }, false);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="bondNumber"></param>
|
||||
/// <returns></returns>
|
||||
public static SU3 BondAdjointStateMatrix(int bondNumber)
|
||||
{
|
||||
double t = Math.Cos(bondNumber * Math.E) + Sqrt3;
|
||||
Complex a1 = Complex.Exp(t * BondAdjointEigen1);
|
||||
Complex a2 = Complex.Exp(t * BondAdjointEigen2);
|
||||
Complex a3 = 1 / (a1 * a2);
|
||||
C33 expBondAdjointEigenDiagonal = new
|
||||
(
|
||||
a1, 0d, 0d,
|
||||
0d, a2, 0d,
|
||||
0d, 0d, a3
|
||||
);
|
||||
return new SU3(BondAdjointCoMatrix * expBondAdjointEigenDiagonal * BondAdjointCoMatrix.Inv());
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="n"></param>
|
||||
/// <returns></returns>
|
||||
public static double AtomHeightOrder(int n) => 1 - Math.Pow(6d / 7d, n);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="n"></param>
|
||||
/// <returns></returns>
|
||||
public static double AtomWeightOrder(int n)
|
||||
{
|
||||
double ra = n / 7d;
|
||||
|
||||
if ((int)Math.Floor(ra / 0.5) % 2 == 0)
|
||||
return ra % 0.5d;
|
||||
return 0.5d - (ra % 0.5d);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="n"></param>
|
||||
/// <returns></returns>
|
||||
public static Complex AtomHeight(int n) => Complex.Exp(I * Math.PI * AtomHeightOrder(n));
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="n"></param>
|
||||
/// <returns></returns>
|
||||
public static Complex AtomWeight(int n) => Complex.Exp(I * Math.PI * AtomWeightOrder(n));
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="n"></param>
|
||||
/// <returns></returns>
|
||||
public static Complex AtomE1(int n) => AtomHeight(n);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="n"></param>
|
||||
/// <returns></returns>
|
||||
public static Complex AtomE2(int n) => AtomWeight(n);
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="n"></param>
|
||||
/// <returns></returns>
|
||||
public static Complex AtomE3(int n) => 1 / (AtomE1(n) * AtomE2(n));
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="atomicNumber"></param>
|
||||
/// <returns></returns>
|
||||
public static SU3 AtomKernel(int atomicNumber) => new
|
||||
(
|
||||
AtomE1(atomicNumber), 0, 0,
|
||||
0, AtomE2(atomicNumber), 0,
|
||||
0, 0, AtomE3(atomicNumber)
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly Complex AtomAdjointEigen1 = I * Complex.Sqrt(0.5 * (5 + Sqrt21));
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly Complex AtomAdjointEigen2 = I * Complex.Sqrt(0.5 * (5 - Sqrt21));
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly C3 AtomAdjointEigenVector1 = new C3
|
||||
(
|
||||
0d,
|
||||
-I * (Sqrt2 - 1d) / (Complex.Sqrt(4d - 2d * Sqrt2)),
|
||||
1d / (Complex.Sqrt(4 - 2 * Sqrt2))
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly C3 AtomAdjointEigenVector2 = new C3
|
||||
(
|
||||
1d,
|
||||
0d,
|
||||
0d
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly C3 AtomAdjointEigenVector3 = new C3
|
||||
(
|
||||
0d,
|
||||
I * (1d + Sqrt2) / Complex.Sqrt(2d * (2d + Sqrt2)),
|
||||
1d / Complex.Sqrt(2d * (2d + Sqrt2))
|
||||
);
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static readonly SU3 AtomAdjointCoMatrix =
|
||||
new ( new []{ AtomAdjointEigenVector1, AtomAdjointEigenVector2, AtomAdjointEigenVector3 }, false);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="atomicNumber"></param>
|
||||
/// <returns></returns>
|
||||
public static SU3 AtomAdjointStateMatrix(int atomicNumber)
|
||||
{
|
||||
double t = Math.Cos(atomicNumber * Math.E) + Sqrt3;
|
||||
Complex a1 = Complex.Exp(t * AtomAdjointEigen1);
|
||||
Complex a2 = Complex.Exp(t * AtomAdjointEigen2);
|
||||
Complex a3 = 1 / (a1 * a2);
|
||||
SU3 expAtomAdjointEigenDiagonal = new SU3
|
||||
(
|
||||
a1, 0, 0,
|
||||
0, a2 , 0,
|
||||
0, 0, a3
|
||||
);
|
||||
return AtomAdjointCoMatrix.ConjugateOn(expAtomAdjointEigenDiagonal);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user