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