Skip to content

Commit

Permalink
Added basic support for Molecules;
Browse files Browse the repository at this point in the history
  • Loading branch information
Sejoslaw committed Jun 20, 2020
1 parent bb04744 commit ef40d30
Show file tree
Hide file tree
Showing 10 changed files with 260 additions and 26 deletions.
48 changes: 48 additions & 0 deletions Chemistry.NET.Tests/ChemicalStackTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/// <summary>
/// Author: Krzysztof Dobrzyński
/// Project: Chemistry.NET
/// Source: https://github.com/Sejoslaw/Chemistry.NET
/// </summary>

using System;
using System.Collections.Generic;
using System.Linq;
using Chemistry.NET.Common;
using Chemistry.NET.Compounds.Collections;
using Chemistry.NET.Compounds.Models;
using Xunit;

namespace Chemistry.NET.Tests
{
public class ChemicalStackTests
{
[Fact]
public void Should_calculate_electrons_neutrons_protons_for_ElementStack()
{
foreach (var element in Container.Elements)
{
var randomElementNumberOnStack = new Random().Next();
var stack = new ElementStack(element, randomElementNumberOnStack);

Assert.Equal(stack.GetTotalElectronsCount(), element.Structure.ElectronsCount * randomElementNumberOnStack);
Assert.Equal(stack.GetTotalNeutronsCount(), element.Structure.NeutronsCount * randomElementNumberOnStack);
Assert.Equal(stack.GetTotalProtonsCount(), element.Structure.ProtonsCount * randomElementNumberOnStack);
Assert.Equal(stack.GetAtoms().Count(), 1);
}
}

[Theory]
[InlineData("H2O", 10, 8, 10, 2)]
[InlineData("H2O2", 18, 16, 18, 2)]
[InlineData("H(CH2)4", 33, 24, 33, 2)]
public void Should_calculate_electrons_neutrons_protons_for_CompoundStack(string compoundSymbol, int electrons, int neutrons, int protons, int atoms)
{
var compound = ChemicalCompound.New(compoundSymbol, "");

Assert.Equal(compound.GetTotalElectronsCount(), electrons);
Assert.Equal(compound.GetTotalNeutronsCount(), neutrons);
Assert.Equal(compound.GetTotalProtonsCount(), protons);
Assert.Equal(compound.GetAtoms().Count(), atoms);
}
}
}
30 changes: 30 additions & 0 deletions Chemistry.NET.Tests/MoleculeTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/// <summary>
/// Author: Krzysztof Dobrzyński
/// Project: Chemistry.NET
/// Source: https://github.com/Sejoslaw/Chemistry.NET
/// </summary>

using Chemistry.NET.Compounds.Models;
using Xunit;

namespace Chemistry.NET.Tests
{
public class MoleculeTests
{
[Theory]
[InlineData("H2", true, false, true)]
[InlineData("H2O", false, true, false)]
[InlineData("CHO", false, true, false)]
[InlineData("CH(CH2)4", false, true, false)]
[InlineData("CH", false, true, true)]
[InlineData("CH(CH2Li3)4", false, true, false)]
public void Check_molecule_properties(string compoundSymbol, bool isHomonuclear, bool isHeteronuclear, bool isDiatomic)
{
var compound = ChemicalCompound.New(compoundSymbol, "");

Assert.Equal(compound.IsHomonuclear, isHomonuclear);
Assert.Equal(compound.IsHeteronuclear, isHeteronuclear);
Assert.Equal(compound.IsDiatomic, isDiatomic);
}
}
}
2 changes: 1 addition & 1 deletion Chemistry.NET/Chemistry.NET.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<PackageId>Chemistry.NET</PackageId>
<Version>1.8.1</Version>
<Version>1.9.0</Version>
<Copyright>https://github.com/Sejoslaw/Chemistry.NET</Copyright>
<PackageProjectUrl>https://github.com/Sejoslaw/Chemistry.NET</PackageProjectUrl>
<RepositoryUrl>https://github.com/Sejoslaw/Chemistry.NET</RepositoryUrl>
Expand Down
71 changes: 71 additions & 0 deletions Chemistry.NET/Compounds/Collections/CompoundStack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
/// Source: https://github.com/Sejoslaw/Chemistry.NET
/// </summary>

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Chemistry.NET.Elements.Models;

namespace Chemistry.NET.Compounds.Collections
{
Expand All @@ -31,5 +34,73 @@ IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}

public IEnumerable<ElementStack> GetAtoms()
{
var stacks = new List<ElementStack>();

foreach (var node in Nodes)
{
if (node is ElementStack elementStack)
{
AppendToAppropriateStack(stacks, elementStack);
}
else if (node is CompoundStack compoundStack)
{
var innerStacks = compoundStack.GetAtoms();
innerStacks.ToList().ForEach(innerStack => AppendToAppropriateStack(stacks, innerStack));
}
}

return stacks;
}

public int GetTotalElectronsCount()
{
return GetTotalCount(e => e.Structure.ElectronsCount);
}

public int GetTotalProtonsCount()
{
return GetTotalCount(e => e.Structure.ProtonsCount);
}

public int GetTotalNeutronsCount()
{
return GetTotalCount(e => e.Structure.NeutronsCount);
}

protected int GetTotalCount(Func<Element, int> func)
{
var total = 0;

foreach (var node in Nodes)
{
if (node is ElementStack elementStack)
{
total += func(elementStack.Element) * elementStack.Count;
}
else if (node is CompoundStack compoundStack)
{
total += compoundStack.GetTotalCount(func);
}
}

return total * Count;
}

private void AppendToAppropriateStack(List<ElementStack> stacks, ElementStack elementStack)
{
foreach (var stack in stacks)
{
if (stack.Element == elementStack.Element)
{
stack.IncreaseStackSize(elementStack.Count);
return;
}
}

stacks.Add(elementStack);
}
}
}
21 changes: 21 additions & 0 deletions Chemistry.NET/Compounds/Collections/ElementStack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
/// Source: https://github.com/Sejoslaw/Chemistry.NET
/// </summary>

using System.Collections.Generic;
using Chemistry.NET.Elements.Models;

namespace Chemistry.NET.Compounds.Collections
Expand Down Expand Up @@ -33,5 +34,25 @@ public virtual void IncreaseStackSize(int count = 1)
{
Count += count;
}

public int GetTotalElectronsCount()
{
return Element.Structure.ElectronsCount * Count;
}

public int GetTotalProtonsCount()
{
return Element.Structure.ProtonsCount * Count;
}

public int GetTotalNeutronsCount()
{
return Element.Structure.NeutronsCount * Count;
}

public IEnumerable<ElementStack> GetAtoms()
{
yield return this;
}
}
}
22 changes: 22 additions & 0 deletions Chemistry.NET/Compounds/Collections/IChemicalStack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
/// Source: https://github.com/Sejoslaw/Chemistry.NET
/// </summary>

using System.Collections.Generic;

namespace Chemistry.NET.Compounds.Collections
{
/// <summary>
Expand All @@ -21,5 +23,25 @@ public interface IChemicalStack
/// </summary>
/// <param name="count"></param>
void IncreaseStackSize(int count = 1);
/// <summary>
/// Returns the number of electrons in the stack.
/// </summary>
/// <returns></returns>
int GetTotalElectronsCount();
/// <summary>
/// Returns the number of protons in the stack.
/// </summary>
/// <returns></returns>
int GetTotalProtonsCount();
/// <summary>
/// Returns the number of neutrons in the stack.
/// </summary>
/// <returns></returns>
int GetTotalNeutronsCount();
/// <summary>
/// Returns the total amount of stacks on the current stack.
/// </summary>
/// <returns></returns>
IEnumerable<ElementStack> GetAtoms();
}
}
33 changes: 9 additions & 24 deletions Chemistry.NET/Compounds/ModelsLogics/ChemicalCompound.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@
/// Source: https://github.com/Sejoslaw/Chemistry.NET
/// </summary>

using System;
using System.Collections.Generic;
using Chemistry.NET.Compounds.Collections;
using Chemistry.NET.Compounds.Parsers.ChemicalCompounds;
using Chemistry.NET.Elements.Models;

namespace Chemistry.NET.Compounds.Models
{
Expand All @@ -16,38 +15,24 @@ namespace Chemistry.NET.Compounds.Models
/// </summary>
public partial class ChemicalCompound
{
public int GetTotalElectronsCount()
public IEnumerable<ElementStack> GetAtoms()
{
return GetTotalCount(e => e.Structure.ElectronsCount);
return StructureTree.GetAtoms();
}

public int GetTotalProtonsCount()
public int GetTotalElectronsCount()
{
return GetTotalCount(e => e.Structure.ProtonsCount);
return StructureTree.GetTotalElectronsCount();
}

public int GetTotalNeutronsCount()
public int GetTotalProtonsCount()
{
return GetTotalCount(e => e.Structure.NeutronsCount);
return StructureTree.GetTotalProtonsCount();
}

private int GetTotalCount(Func<Element, int> func)
public int GetTotalNeutronsCount()
{
var total = 0;

foreach (var node in StructureTree)
{
if (node is ElementStack elementStack)
{
total += func(elementStack.Element) * elementStack.Count;
}
else if (node is CompoundStack compoundStack)
{
total += GetTotalCount(func) * compoundStack.Count;
}
}

return total;
return StructureTree.GetTotalNeutronsCount();
}

/// <summary>
Expand Down
31 changes: 31 additions & 0 deletions Chemistry.NET/Molecules/IMolecule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/// <summary>
/// Author: Krzysztof Dobrzyński
/// Project: Chemistry.NET
/// Source: https://github.com/Sejoslaw/Chemistry.NET
/// </summary>

namespace Chemistry.NET.Molecules
{
/// <summary>
/// Describes an object to be a Molecule.
/// </summary>
public interface IMolecule
{
/// <summary>
/// Homonuclear molecules are molecules composed of only one type of element.
/// Homonuclear molecules may consist of various numbers of atoms, depending on the element's properties.
/// </summary>
/// <value></value>
bool IsHomonuclear { get; }
/// <summary>
/// A heteronuclear molecule is a molecule composed of atoms of more than one chemical element.
/// </summary>
/// <value></value>
bool IsHeteronuclear { get; }
/// <summary>
/// Diatomic molecules are molecules composed of only two atoms, of the same or different chemical elements.
/// </summary>
/// <value></value>
bool IsDiatomic { get; }
}
}
26 changes: 26 additions & 0 deletions Chemistry.NET/Molecules/ModelsLogics/ChemicalCompound.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/// <summary>
/// Author: Krzysztof Dobrzyński
/// Project: Chemistry.NET
/// Source: https://github.com/Sejoslaw/Chemistry.NET
/// </summary>

using System.Linq;
using Chemistry.NET.Molecules;

namespace Chemistry.NET.Compounds.Models
{
public partial class ChemicalCompound : IMolecule
{
public bool IsHomonuclear => this.GetAtoms().Count() == 1;
public bool IsHeteronuclear => this.GetAtoms().Count() > 1;
public bool IsDiatomic
{
get
{
var atoms = this.GetAtoms();
return (atoms.Count() == 1 && atoms.ElementAt(0).Count == 2) ||
(atoms.Count() == 2 && atoms.ElementAt(0).Count == 1 && atoms.ElementAt(1).Count == 1);
}
}
}
}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Layer | Name | Description
2 | Isotopes | Contains information about known isotopes and their properties. (6500+ isotopes preconfigured)
3 | Compounds | This is a higher-level layer which let's user build advanced compounds from known elements and isotopes. (2400+ compounds preconfigured)
3 | Ions | Describes ionization functionality for each of the elements. (540+ ions preconfigured)
X | Molecules | TBA
4 | Molecules | Contains information which can be used to indicate Molecule-related properties for a Chemical Compound.
X | Lipids | TBA
X | Steroids | TBA
X | Polymers | TBA
Expand Down

0 comments on commit ef40d30

Please sign in to comment.