ENKI

PhaseObjC - Solution Phase Example

DEWFluid- number of endmember species is not equivalent to number of endmember components

Required python code to load the PhaseObjC library. The library libphaseobjc.dylib (see build instructions in README.md) must be locatable to teh system in a standard location (by default /usr/local/lib)

from ctypes import cdll
from ctypes import util
from rubicon.objc import ObjCClass, objc_method
cdll.LoadLibrary(util.find_library('phaseobjc'))
<CDLL '/usr/local/lib/libphaseobjc.dylib', handle 7fae8dc4a7f0 at 0x107827208>

Create a python reference to the “DEWFluid” solution phase class and instantiate an instance of that class.

In Objective-C the code has the form:

obj = [[DEWFluid alloc] init]

and in python:

DEWFluid = ObjCClass('DEWFluid')
obj = DEWFluid.alloc().init()

Obtain properties of the phase inherited from the PhaseBase class.

print (obj.phaseName)
DEWFluid

Solution Protocol Functions

Solution component and species number …

–> Retrieves the number of endmember components in the system

(NSUInteger)numberOfSolutionComponents

–> Retrieves the number of species (dependent endmembers with positive mole fractions) in the soluton

(NSUInteger)numberOfSolutionSpecies

Note that the number of components (nc) may be the same as the number of endmember species (ns) if the solution does not involve speciation (complexing) or if the solid solution is not a reciprocal solution.

nc = obj.numberOfSolutionComponents()
print ('Number of components = ', nc)
ns = obj.numberOfSolutionSpecies()
print ('Number of species = ', ns)
Number of components =  17
Number of species =  92

Information about solution components …

Return name, formula and molecular weight of each end-member component in the solution. Note teh use of the PhaseBase class (for further info see the Stoichiometric Phase notebook examples)

–> Retrieves superclass instance of PhaseBase object for component at specified index

(id)componentAtIndex:(NSUInteger)index
PhaseBase = ObjCClass('PhaseBase')
print ('component name, formula, and molecular weight (g/mol)')
for i in range(0, nc):
    component = obj.componentAtIndex_(i)
    print (component.phaseName, component.phaseFormula, component.mw)
component name, formula, and molecular weight (g/mol)
Water H2O 18.0152
CO2,aq CO2 44.0098
O2,aq O2 31.9988
HF,aq HF 20.006303
NaOH,aq NaOH 39.99707
Mg(OH)2,aq Mg(OH)2 58.319599999999994
HAlO2,aq HAlO2 59.98824
SiO2,aq SiO2 60.0843
H3PO4,aq H3PO4 97.99506
SO2,aq SO2 64.0588
HCl,aq HCl 36.4609
KOH,aq KOH 56.1093
Ca(OH)2,aq Ca(OH)2 74.0946
H2CrO4,aq H2CrO4 118.0094
Mn(OH)2,aq Mn(OH)2 88.9526
Fe(OH)2,aq Fe(OH)2 89.8616
Co(OH)2,aq Co(OH)2 92.9478

Create a vector of moles of endmember components …

Allocate a “c”-type pointer to a double precision one-dimensional array, and initialize the array to hold the moles of each component in the solution

import ctypes
m = (ctypes.c_double*nc)()
ctypes.cast(m, ctypes.POINTER(ctypes.c_double))
m[ 0] = 0.998813
m[ 1] = 0.0
m[ 2] = 0.0
m[ 3] = 0.0
m[ 4] = 8.45249e-05
m[ 5] = 0.0
m[ 6] = 3.49734e-10
m[ 7] = 0.00110226
m[ 8] = 0.0
m[ 9] = 0.0
m[10] = 0.0
m[11] = 5.03714e-07
m[12] = 1.51788e-18
m[13] = 0.0
m[14] = 0.0
m[15] = 0.0
m[16] = 0.0
for i in range (0, nc):
    component = obj.componentAtIndex_(i)
    print ('moles of (', component.phaseName, ') = ', m[i])
moles of ( Water ) =  0.998813
moles of ( CO2,aq ) =  0.0
moles of ( O2,aq ) =  0.0
moles of ( HF,aq ) =  0.0
moles of ( NaOH,aq ) =  8.45249e-05
moles of ( Mg(OH)2,aq ) =  0.0
moles of ( HAlO2,aq ) =  3.49734e-10
moles of ( SiO2,aq ) =  0.00110226
moles of ( H3PO4,aq ) =  0.0
moles of ( SO2,aq ) =  0.0
moles of ( HCl,aq ) =  0.0
moles of ( KOH,aq ) =  5.03714e-07
moles of ( Ca(OH)2,aq ) =  1.51788e-18
moles of ( H2CrO4,aq ) =  0.0
moles of ( Mn(OH)2,aq ) =  0.0
moles of ( Fe(OH)2,aq ) =  0.0
moles of ( Co(OH)2,aq ) =  0.0

Note that moles can be assigned from a vector of element abundances using the following functions …

–> Moles of elements (standard order) => Moles of end member components of the phase

(DoubleVector *)convertElementsToMoles:(double *)e

–> Moles of elements (standard order) => Total moles of end member components of the phase

(double)convertElementsToTotalMoles:(double *)e

–> Moles of elements (standard order) => Total mass of the phase (g)

(double)convertElementsToTotalMass:(double *)e
e = (ctypes.c_double*107)()
ctypes.cast(e, ctypes.POINTER(ctypes.c_double))
for i in range (0, 107):
    e[i] = 0.0
e[1]  = 2.0*m[0] + m[4] +     m[6]            + m[11] + 2.0*m[12] # H
e[8]  =     m[0] + m[4] + 2.0*m[6] + 2.0*m[7] + m[11] + 2.0*m[12] # O
e[11] =            m[4]                                           # Na
e[13] =                       m[6]                                # Al
e[14] =                                  m[7]                     # Si
e[19] =                                         m[11]             # K
e[20] =                                                     m[12] # Ca
mCompute = obj.convertElementsToMoles_(e)
for i in range (0, nc):
    component = obj.componentAtIndex_(i)
    print ('assumed moles of', component.phaseName, '= ', m[i], ' computed = ', mCompute.valueAtIndex_(i))
print ('Computed total number of moles = ', obj.convertElementsToTotalMoles_(e))
print ('Computed total mass = ', obj.convertElementsToTotalMass_(e))
assumed moles of Water =  0.998813  computed =  0.998813
assumed moles of CO2,aq =  0.0  computed =  0.0
assumed moles of O2,aq =  0.0  computed =  0.0
assumed moles of HF,aq =  0.0  computed =  0.0
assumed moles of NaOH,aq =  8.45249e-05  computed =  8.45249e-05
assumed moles of Mg(OH)2,aq =  0.0  computed =  0.0
assumed moles of HAlO2,aq =  3.49734e-10  computed =  3.49734e-10
assumed moles of SiO2,aq =  0.00110226  computed =  0.00110226
assumed moles of H3PO4,aq =  0.0  computed =  0.0
assumed moles of SO2,aq =  0.0  computed =  0.0
assumed moles of HCl,aq =  0.0  computed =  0.0
assumed moles of KOH,aq =  5.03714e-07  computed =  5.03714e-07
assumed moles of Ca(OH)2,aq =  1.51788e-18  computed =  1.51788e-18
assumed moles of H2CrO4,aq =  0.0  computed =  0.0
assumed moles of Mn(OH)2,aq =  0.0  computed =  0.0
assumed moles of Fe(OH)2,aq =  0.0  computed =  0.0
assumed moles of Co(OH)2,aq =  0.0  computed =  0.0
Computed total number of moles =  1.000000288963734
Computed total mass =  18.063453510479906

Test the mole vector and output derived quantities …

–> Moles of endmember components => validity of input values

(BOOL)testPermissibleValuesOfComponents:(double *)m

–> Moles of endmember components => Moles of elements (standard order)

(DoubleVector *)convertMolesToElements:(double *)m

–> Moles of endmember components => Molar sum

(double)totalMolesFromMolesOfComponents:(double *)m

–> Moles of endmember components => Mole fractions of endmember components

(DoubleVector *)convertMolesToMoleFractions:(double *)m
if (obj.testPermissibleValuesOfComponents_(m) == 1):
    print ('mole input is feasible')
else:
    print ('mole input is infeasible')

print ('Total moles = ', obj.totalMolesFromMolesOfComponents_(m))

mole_frac_pointer = obj.convertMolesToMoleFractions_(m)
print ('component name, component formula, mole fraction')
for i in range (0, nc):
    print (obj.componentAtIndex_(i).phaseName, obj.componentAtIndex_(i).phaseFormula, mole_frac_pointer.valueAtIndex_(i))

moles_pointer = obj.convertMolesToElements_(m)
ne = moles_pointer.size
formula = ''
for i in range(0, ne):
    value = moles_pointer.valueAtIndex_(i)
    if value != 0.0:
        name = PhaseBase.elementNameFromAtomicNumber_(i)
        formula = formula + name + '(' + str(value) + ')'
print ('Solution formula = ', formula)
mole input is feasible
Total moles =  1.000000288963734
component name, component formula, mole fraction
Water H2O 0.9988127113793492
CO2,aq CO2 0.0
O2,aq O2 0.0
HF,aq HF 0.0
NaOH,aq NaOH 8.452487557537634e-05
Mg(OH)2,aq Mg(OH)2 0.0
HAlO2,aq HAlO2 3.4973389893958666e-10
SiO2,aq SiO2 0.0011022596814869265
H3PO4,aq H3PO4 0.0
SO2,aq SO2 0.0
HCl,aq HCl 0.0
KOH,aq KOH 5.037138544449638e-07
Ca(OH)2,aq Ca(OH)2 1.5178795613878541e-18
H2CrO4,aq H2CrO4 0.0
Mn(OH)2,aq Mn(OH)2 0.0
Fe(OH)2,aq Fe(OH)2 0.0
Co(OH)2,aq Co(OH)2 0.0
Solution formula =  H(1.997711028963734)O(1.001102549313468)Na(8.45249e-05)Al(3.49734e-10)Si(0.00110226)K(5.03714e-07)Ca(1.51788e-18)

Compute activties and chemical potentials of endmember components …

–> Moles of components, T (K), P (bars) => activities of endmember components

(DoubleVector *)getActivityFromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

–> Moles of components, T (K), P (bars) => chemical potentials of endmember components (J)

(DoubleVector *)getChemicalPotentialFromMolesOfComponents:(double *)m andT:(double)t andP:(double)p
t = 1000.0
p = 1000.0
activity = obj.getActivityFromMolesOfComponents_andT_andP_(m, t, p)
potential = obj.getChemicalPotentialFromMolesOfComponents_andT_andP_(m, t, p)
print ('component, activity, chemical potential')
for i in range (0, nc):
    component = obj.componentAtIndex_(i)
    print (component.phaseName, activity.valueAtIndex_(i), potential.valueAtIndex_(i))
component, activity, chemical potential
Water 0.0 -38180804.90310306
CO2,aq inf 37833597730.88722
O2,aq 0.0 -37874126.54848149
HF,aq inf 10351890122.421375
NaOH,aq 0.0 -58641814.91681192
Mg(OH)2,aq inf 3480656539.0185494
HAlO2,aq inf 8533584361.057727
SiO2,aq 0.0 -37874126.54848148
H3PO4,aq inf 58690771225.21861
SO2,aq inf 34583005541.13708
HCl,aq inf 14894427800.685009
KOH,aq inf 3348811201.7649455
Ca(OH)2,aq inf 6603651192.824785
H2CrO4,aq inf 45215221458.0656
Mn(OH)2,aq inf 4805563361.84545
Fe(OH)2,aq inf 4237746152.0624857
Co(OH)2,aq inf 4805563361.84545
component = obj.componentAtIndex_(10)
print ('Does component', component.phaseName, 'implement the CalibrationProtocol?')

try:
    if component.supportsParameterCalibration() == 1:
        print ('This component supports the Calibration protocol')
    np = component.getNumberOfFreeParameters()
    print ('... there are', np, 'parameters')
    names = component.getArrayOfNamesOfFreeParameters()
    for i in range (0, np):
        name = names.objectAtIndex_(i)
        value = component.getValueForParameterName_(name)
        units = component.getUnitsForParameterName_(name)
        print ('Parameter ', name, 'has value ', value, units)
        dmudw = component.getChemicalPotentialDerivativesForParameter_usingMolesOfComponents_andT_andP_(name, m, t, p)
        print ('   dmu0/dw = ', dmudw.valueAtIndex_(0))
except AttributeError:
    print ('This phase does not implement the parameter calibration protocol')
Does component HCl,aq implement the CalibrationProtocol?
This component supports the Calibration protocol
... there are 12 parameters
Parameter  deltaGibbsFreeEnergyOfFormationInTheReferenceState has value  -127235.44 joules/mol
   dmu0/dw =  0.999999976974281
Parameter  deltaEnthalpyOfFormationInTheReferenceState has value  -175953.93600000002 joules/mol
   dmu0/dw =  -0.0
Parameter  entropyInTheReferenceState has value  13.388800000000002 joules/K/mol
   dmu0/dw =  -701.8497373710411
Parameter  volumeInTheReferenceState has value  1.5 joules/bar/mol
   dmu0/dw =  0.0
Parameter  heatCapacityInTheReferenceState has value  163.17600000000002 joules/K/mol
   dmu0/dw =  0.0
Parameter  a1HKF has value  0.52496648 joules/bar/mol
   dmu0/dw =  998.999798807286
Parameter  a2HKF has value  -1973.88568 joules/mol
   dmu0/dw =  0.3250380185393738
Parameter  a3HKF has value  31.8163912 joules-K/bar/mol
   dmu0/dw =  1.2940460375549456
Parameter  a4HKF has value  -108114.56000000001 joules-K/mol
   dmu0/dw =  0.0004210305386333863
Parameter  c1HKF has value  69.92886560000001 joules/K/mol
   dmu0/dw =  -508.3085673746446
Parameter  c2HKF has value  120193.768 joules-K/mol
   dmu0/dw =  -0.021024693378818047
Parameter  omegaHKF has value  -83680.00000000001 joules/mol
   dmu0/dw =  0.34932168118128587

Execution of the code block following this cell will crash the python kernel

Gibbs free energy and its compositional derivatives …

–> Moles of components, T (K), P (bars) => Gibbs free energy (J)

(double)getGibbsFreeEnergyFromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

–> Moles of components, T (K), P (bars) => d(Gibbs free energy)/d(Moles of components) (J)

(DoubleVector *)getDgDmFromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

–> Moles of components, T (K), P (bars) => d^2(Gibbs free energy)/d(Moles of components)^2 (J)

(DoubleMatrix *)getD2gDm2FromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

–> Moles of components, T (K), P (bars) => d^3(Gibbs free energy)/d(Moles of components)^3 (J)

(DoubleTensor *)getD3gDm3FromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

print (‘Gibbs free energy (J) =’, obj.getGibbsFreeEnergyFromMolesOfComponents_andT_andP_(m, t, p)) dgdm = obj.getDgDmFromMolesOfComponents_andT_andP_(m, t, p) for i in range (0, nc): print (‘dg/dm (’, i, ‘) =’, dgdm.valueAtIndex_(i)) d2gdm2 = obj.getD2gDm2FromMolesOfComponents_andT_andP_(m, t, p) for i in range (0, nc): for j in range (0, nc): print (‘d2g/dm2 (’, i, ‘) (’, j, ‘) =’, d2gdm2.valueAtRowIndex_andColIndex_(i, j)) d3gdm3 = obj.getD3gDm3FromMolesOfComponents_andT_andP_(m, t, p) for i in range (0, nc): for j in range (0, nc): for k in range (0, nc): print (‘d3g/dm3 (’, i, ‘) (’, j, ‘) (’, k, ‘) =’, d3gdm3.valueAtFirstIndex_andSecondIndex_andThirdIndex_(i, j, k))

Execution of the code block following this cell will crash the python kernel

Molar derivatives of activities …

–> Moles of components, T (K), P (bars) => d(activities of endmember components)/d(Moles of components)

(DoubleMatrix *)getDaDmFromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

dadm = obj.getDaDmFromMolesOfComponents_andT_andP_(m, t, p) for i in range (0, nc): for j in range (0, nc): print (‘da/dm (’, i, ‘) (’, j, ‘) =’, dadm.valueAtRowIndex_andColIndex_(i, j))

Execution of the code block following this cell will crash the python kernel

Enthalpy, Entroipy and molar derivatives …

–> Moles of components, T (K), P (bars) => enthalpy (J)

(double)getEnthalpyFromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

–> Moles of components, T (K), P (bars) => entropy (J/K)

(double)getEntropyFromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

–> Moles of components, T (K), P (bars) => d(entropy)/d(Moles of components) (J/K)

(DoubleVector *)getDsDmFromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

–> Moles of components, T (K), P (bars) => d^2(entropy)/d(Moles of components)^2 (J/K)

(DoubleMatrix *)getD2sDm2FromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

print (‘Enthalpy (J) =’, obj.getEnthalpyFromMolesOfComponents_andT_andP_(m, t, p)) print (‘Entropy (J/K) =’, obj.getEntropyFromMolesOfComponents_andT_andP_(m, t, p)) dsdm = obj.getDsDmFromMolesOfComponents_andT_andP_(m, t, p) for i in range (0, nc): print (‘ds/dm (’, i, ‘) =’, dsdm.valueAtIndex_(i)) d2sdm2 = obj.getD2sDm2FromMolesOfComponents_andT_andP_(m, t, p) for i in range (0, nc): for j in range (0, nc): print (‘d2s/dm2 (’, i, ‘) (’, j, ‘) =’, d2sdm2.valueAtRowIndex_andColIndex_(i, j))

Execution of the code block following this cell will crash the python kernel

Heat capcaity and its derivatives …

–> Moles of components, T (K), P (bars) => isobaric heat capacity (J/K)

(double)getHeatCapacityFromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

–> Moles of components, T (K), P (bars) => d(isobaric heat capacity)/dT (J/K^2)

(double)getDcpDtFromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

–> Moles of components, T (K), P (bars) => d(isobaric heat capacity)/d(Moles of components) (J/K)

(DoubleVector *)getDCpDmFromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

print (‘Heat capacity (J/K) =’, obj.getHeatCapacityFromMolesOfComponents_andT_andP_(m, t, p)) print (‘dcpdt (J/K^2) =’, obj.getDcpDtFromMolesOfComponents_andT_andP_(m, t, p)) dcpdm = obj.getDCpDmFromMolesOfComponents_andT_andP_(m, t, p) for i in range (0, nc): print (‘dcp/dm (’, i, ‘) =’, dcpdm.valueAtIndex_(i))

Execution of the code block following this cell will crash the python kernel

Volume and its derivatives …

–> Moles of components, T (K), P (bars) => volume (J/bar)

(double)getVolumeFromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

–> Moles of components, T (K), P (bars) => d(volume)/d(Moles of components) (J/bar)

(DoubleVector *)getDvDmFromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

–> Moles of components, T (K), P (bars) => d^2(volume)/d(Moles of components)^2 (J/bar)

(DoubleMatrix *)getD2vDm2FromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

–> Moles of components, T (K), P (bars) => d(volume)/dT (J/bar-K)

(double)getDvDtFromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

–> Moles of components, T (K), P (bars) => d(volume)/dP (J/bar^2)

(double)getDvDpFromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

–> Moles of components, T (K), P (bars) => d2(volume)/dT^2 (J/bar-K^2)

(double)getD2vDt2FromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

–> Moles of components, T (K), P (bars) => d2(volume)/dTdP (J/bar^2-K)

(double)getD2vDtDpFromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

–> Moles of components, T (K), P (bars) => d2(volume)/dP^2 (J/bar^3)

(double)getD2vDp2FromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

–> Moles of components, T (K), P (bars) => d2(volume)/d(Moles of components)dT (J/bar-K)

(DoubleVector *)getD2vDmDtFromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

–> Moles of components, T (K), P (bars) => d2(volume)/d(Moles of components)dP (J/bar^2)

(DoubleVector *)getD2vDmDpFromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

print (‘Volume (J/bar) =’, obj.getVolumeFromMolesOfComponents_andT_andP_(m, t, p)) dvdm = obj.getDvDmFromMolesOfComponents_andT_andP_(m, t, p) for i in range (0, nc): print (‘dv/dm (’, i, ‘) =’, dvdm.valueAtIndex_(i)) d2vdm2 = obj.getD2vDm2FromMolesOfComponents_andT_andP_(m, t, p) for i in range (0, nc): for j in range (0, nc): print (‘d2v/dm2 (’, i, ‘) (’, j, ‘) =’, d2vdm2.valueAtRowIndex_andColIndex_(i, j)) print (‘dvdt (J/bar-K) =’, obj.getDvDtFromMolesOfComponents_andT_andP_(m, t, p)) print (‘dvdp (J/bar^2) =’, obj.getDvDpFromMolesOfComponents_andT_andP_(m, t, p)) print (‘d2vdt2 (J/bar-K^2) =’, obj.getD2vDt2FromMolesOfComponents_andT_andP_(m, t, p)) print (‘d2vdtdp (J/bar^2-K) =’, obj.getD2vDtDpFromMolesOfComponents_andT_andP_(m, t, p)) print (‘d2vdp2 (J/bar^3) =’, obj.getD2vDp2FromMolesOfComponents_andT_andP_(m, t, p)) d2vdmdt = obj.getD2vDmDtFromMolesOfComponents_andT_andP_(m, t, p) for i in range (0, nc): print (‘d2vdmdt (’, i, ‘) =’, d2vdmdt.valueAtIndex_(i)) d2vdmdp = obj.getD2vDmDpFromMolesOfComponents_andT_andP_(m, t, p) for i in range (0, nc): print (‘d2vdmdp (’, i, ‘) =’, d2vdmdp.valueAtIndex_(i))

Execution of the code block following this cell will crash the python kernel

Accessing properties of solution species …

–> Moles of components, T (K), P (bars) => formulae as an NSString object

(NSString *)getFormulaFromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

–> Retrieves the name of the solution species at the specified index

(NSString *)nameOfSolutionSpeciesAtIndex:(NSUInteger)index

–> Moles of solution species => moles of endmember components

(DoubleVector *)convertMolesOfSpeciesToMolesOfComponents:(double *)mSpecies

–> Retrieves an elemental stoichiometry vector for the species at the specified index

(DoubleVector *)elementalCompositionOfSpeciesAtIndex:(NSUInteger)index

–> Moles of components, T (K), P (bars) => chemical potentials of solution species (J)

(DoubleVector *)chemicalPotentialsOfSpeciesFromMolesOfComponents:(double *)m andT:(double)t andP:(double)p

Note that the first nc species are identical to the solution components

print (‘formula =’, obj.getFormulaFromMolesOfComponents_andT_andP_(m, t, p)) muSpecies = obj.chemicalPotentialsOfSpeciesFromMolesOfComponents_andT_andP_(m, t, p) for i in range (0, ns): print (‘species =’, obj.nameOfSolutionSpeciesAtIndex_(i)) elm = obj.elementalCompositionOfSpeciesAtIndex_(i) for j in range (0, 107): if elm.valueAtIndex_(j) > 0.0: print (‘element (’, j, ‘) =’, elm.valueAtIndex_(j)) print (‘chemical potential =’, muSpecies.valueAtIndex_(i)) mSpecies = (ctypes.c_double*3)() ctypes.cast(mSpecies, ctypes.POINTER(ctypes.c_double)) mSpecies[0] = 1 mSpecies[1] = 2 mSpecies[2] = 3 mSpToComp = obj.convertMolesOfSpeciesToMolesOfComponents_(mSpecies) for i in range (0, nc): print (‘moles of component (’, i, ‘) =’, mSpToComp.valueAtIndex_(i))