Skip to content

Commit

Permalink
[.NET] Rethink Species and SpeciesCollection
Browse files Browse the repository at this point in the history
Double arrays that change as part of a simulation or are likely to be calculated on the fly are now returned directly by methods of the SpeciesCollection. This deviates from an ideal OO design, but provides efficient access and calculation across the array.
  • Loading branch information
burkenyo authored and speth committed Aug 17, 2022
1 parent 5e4faa4 commit 49eef19
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 15 deletions.
2 changes: 2 additions & 0 deletions interfaces/dotnet/Cantera.Tests/src/ThermoPhaseTest.cs
Expand Up @@ -13,5 +13,7 @@ public void ThermoPhase_SpeciesRetrieved()

Assert.NotEmpty(thermo.Species);
Assert.NotEmpty(thermo.Species[0].Name);
Assert.Equal(thermo.Species.Count, thermo.Species.MoleFractions.Length);
Assert.Equal(thermo.Species.Count, thermo.Species.MassFractions.Length);
}
}
6 changes: 1 addition & 5 deletions interfaces/dotnet/Cantera/src/Species.cs
Expand Up @@ -4,16 +4,12 @@ public class Species
{
public string Name { get; }
public double MolecularWeight { get; }
public double MoleFraction { get; }
public double MassFraction { get; }
public double Charge { get; }

internal Species(string name, double molecularWeight, double moleFraction, double massFraction, double charge)
internal Species(string name, double molecularWeight, double charge)
{
Name = name;
MolecularWeight = molecularWeight;
MoleFraction = moleFraction;
MassFraction = massFraction;
Charge = charge;
}
}
45 changes: 35 additions & 10 deletions interfaces/dotnet/Cantera/src/SpeciesCollection.cs
@@ -1,38 +1,57 @@
using System.Buffers;
using System.Collections;
using Cantera.Interop;

namespace Cantera;

public class SpeciesCollection : IReadOnlyList<Species>
{
readonly ThermoPhaseHandle _handle;
readonly List<Species> _species;

public Species this[int index] => _species[index];

public int Count => _species.Count;

public unsafe double[] MassFractions
{
get => InteropUtil.GetDoubles(_handle, _species.Count, LibCantera.thermo_getMassFractions);
set => InteropUtil.CheckReturn(
LibCantera.thermo_setMassFractions(_handle, (nuint) _species.Count, value, InteropConsts.True));
}

public unsafe double[] MoleFractions
{
get => InteropUtil.GetDoubles(_handle, _species.Count, LibCantera.thermo_getMoleFractions);
set => InteropUtil.CheckReturn(
LibCantera.thermo_setMoleFractions(_handle, (nuint) _species.Count, value, InteropConsts.True));
}

internal unsafe SpeciesCollection(ThermoPhaseHandle handle)
{
var count = InteropUtil.CheckReturn(LibCantera.thermo_nSpecies(handle));
_handle = handle;

var molecularWeights = InteropUtil.GetDoubles(handle, count, LibCantera.thermo_getMolecularWeights);
var moleFractions = InteropUtil.GetDoubles(handle, count, LibCantera.thermo_getMoleFractions);
var massFractions = InteropUtil.GetDoubles(handle, count, LibCantera.thermo_getMassFractions);
var charges = InteropUtil.GetDoubles(handle, count, LibCantera.thermo_getCharges);
var count = (int) InteropUtil.CheckReturn(LibCantera.thermo_nSpecies(handle));

_species = new((int) count);
var pool = MemoryPool<double>.Shared;

for (var i = (nuint) 0; i < count; i++)
using var __1 = pool.Rent(count, out var molecularWeights);
using var __2 = pool.Rent(count, out var charges);

InteropUtil.GetDoubles(handle, molecularWeights, LibCantera.thermo_getMolecularWeights);
InteropUtil.GetDoubles(handle, charges, LibCantera.thermo_getCharges);

_species = new(count);

for (var i = 0; i < count; i++)
{
var name = InteropUtil.GetString(10, (length, buffer) =>
LibCantera.thermo_getSpeciesName(handle, i, (nuint) length, buffer));
LibCantera.thermo_getSpeciesName(handle, (nuint) i, (nuint) length, buffer));

_species.Add(new
(
name,
molecularWeights[i],
moleFractions[i],
massFractions[i],
charges[i]
));
}
Expand All @@ -43,4 +62,10 @@ internal unsafe SpeciesCollection(ThermoPhaseHandle handle)

IEnumerator IEnumerable.GetEnumerator() =>
_species.GetEnumerator();

public void SetUnormalizedMassFractions(double[] fractions) =>
LibCantera.thermo_setMassFractions(_handle, (nuint) _species.Count, fractions, InteropConsts.False);

public void SetUnormalizedMoleFractions(double[] fractions) =>
LibCantera.thermo_setMoleFractions(_handle, (nuint) _species.Count, fractions, InteropConsts.False);
}

0 comments on commit 49eef19

Please sign in to comment.