From 1e8d3822ffbea866b2b3e0b137bb865f627aa128 Mon Sep 17 00:00:00 2001 From: Dave Goodwin Date: Mon, 14 Apr 2003 17:57:48 +0000 Subject: [PATCH] Initial revision --- .cvsignore | 3 + Cantera/.cvsignore | 1 + Cantera/Makefile.in | 51 + Cantera/clib/src/.cvsignore | 2 + Cantera/clib/src/Cabinet.h | 188 + Cantera/clib/src/Makefile.in | 85 + Cantera/clib/src/Storage.cpp | 115 + Cantera/clib/src/Storage.h | 68 + Cantera/clib/src/clib_defs.h | 19 + Cantera/clib/src/ct.cpp | 863 +++ Cantera/clib/src/ct.h | 132 + Cantera/clib/src/ctbdry.cpp | 92 + Cantera/clib/src/ctbdry.h | 17 + Cantera/clib/src/ctfunc.cpp | 90 + Cantera/clib/src/ctfunc.h | 14 + Cantera/clib/src/ctnum.cpp | 179 + Cantera/clib/src/ctnum.h | 37 + Cantera/clib/src/ctreactor.cpp | 367 + Cantera/clib/src/ctreactor.h | 73 + Cantera/clib/src/ctrpath.cpp | 189 + Cantera/clib/src/ctrpath.h | 37 + Cantera/clib/src/ctstagn.cpp | 452 ++ Cantera/clib/src/ctstagn.h | 71 + Cantera/clib/src/ctsurf.cpp | 86 + Cantera/clib/src/ctsurf.h | 54 + Cantera/clib/src/ctxml.cpp | 235 + Cantera/clib/src/ctxml.h | 30 + Cantera/cxx/README | 3 + Cantera/lib/README | 3 + Cantera/matlab/Makefile.in | 85 + .../matlab/cantera/@FlowDevice/FlowDevice.m | 15 + Cantera/matlab/cantera/@FlowDevice/clear.m | 4 + Cantera/matlab/cantera/@FlowDevice/install.m | 16 + .../matlab/cantera/@FlowDevice/massFlowRate.m | 5 + .../@FlowDevice/private/flowdevicemethods.m | 13 + .../cantera/@FlowDevice/setMassFlowRate.m | 12 + .../cantera/@FlowDevice/setValveCoeff.m | 10 + Cantera/matlab/cantera/@Kinetics/Kinetics.m | 33 + Cantera/matlab/cantera/@Kinetics/clear.m | 5 + .../matlab/cantera/@Kinetics/creationRates.m | 23 + .../cantera/@Kinetics/destructionRates.m | 23 + .../cantera/@Kinetics/destruction_rates.m | 20 + Cantera/matlab/cantera/@Kinetics/equil_Kc.m | 22 + Cantera/matlab/cantera/@Kinetics/hndl.m | 2 + .../matlab/cantera/@Kinetics/isReversible.m | 14 + .../matlab/cantera/@Kinetics/kinetics_hndl.m | 6 + Cantera/matlab/cantera/@Kinetics/multiplier.m | 14 + Cantera/matlab/cantera/@Kinetics/nReactions.m | 5 + .../matlab/cantera/@Kinetics/nTotalSpecies.m | 5 + .../matlab/cantera/@Kinetics/netProdRates.m | 22 + .../cantera/@Kinetics/private/delkinetics.cpp | 22 + .../cantera/@Kinetics/private/isrev.cpp | 19 + .../cantera/@Kinetics/private/kin_get.cpp | 35 + .../cantera/@Kinetics/private/kin_set.cpp | 47 + .../cantera/@Kinetics/private/kinetics_get.m | 14 + .../cantera/@Kinetics/private/kinetics_set.m | 6 + .../cantera/@Kinetics/private/newkinetics.cpp | 33 + .../cantera/@Kinetics/private/production.cpp | 32 + .../cantera/@Kinetics/private/pstoich.cpp | 20 + .../matlab/cantera/@Kinetics/private/rop.cpp | 32 + .../cantera/@Kinetics/private/rstoich.cpp | 20 + .../cantera/@Kinetics/private/rxnstring.cpp | 25 + .../matlab/cantera/@Kinetics/reactionEqn.m | 29 + Cantera/matlab/cantera/@Kinetics/rop.m | 20 + Cantera/matlab/cantera/@Kinetics/rop_f.m | 20 + Cantera/matlab/cantera/@Kinetics/rop_net.m | 20 + Cantera/matlab/cantera/@Kinetics/rop_r.m | 13 + Cantera/matlab/cantera/@Kinetics/rxnEqs.m | 29 + .../matlab/cantera/@Kinetics/setMultiplier.m | 10 + Cantera/matlab/cantera/@Kinetics/stoich_net.m | 30 + Cantera/matlab/cantera/@Kinetics/stoich_p.m | 43 + Cantera/matlab/cantera/@Kinetics/stoich_r.m | 43 + Cantera/matlab/cantera/@Kinetics/ydot.m | 4 + Cantera/matlab/cantera/@Reactor/Reactor.m | 35 + Cantera/matlab/cantera/@Reactor/advance.m | 22 + Cantera/matlab/cantera/@Reactor/clear.m | 5 + Cantera/matlab/cantera/@Reactor/density.m | 4 + .../matlab/cantera/@Reactor/enthalpy_mass.m | 12 + Cantera/matlab/cantera/@Reactor/hndl.m | 2 + Cantera/matlab/cantera/@Reactor/insert.m | 8 + .../matlab/cantera/@Reactor/intEnergy_mass.m | 12 + Cantera/matlab/cantera/@Reactor/mass.m | 5 + .../matlab/cantera/@Reactor/massFraction.m | 5 + .../matlab/cantera/@Reactor/massFractions.m | 11 + Cantera/matlab/cantera/@Reactor/pressure.m | 4 + .../@Reactor/private/reactormethods.cpp | 130 + .../cantera/@Reactor/private/reactormethods.m | 13 + .../matlab/cantera/@Reactor/reactor_hndl.m | 2 + Cantera/matlab/cantera/@Reactor/setEnergy.m | 8 + .../matlab/cantera/@Reactor/setInitialTime.m | 5 + .../cantera/@Reactor/setInitialVolume.m | 5 + .../matlab/cantera/@Reactor/setKineticsMgr.m | 9 + .../matlab/cantera/@Reactor/setThermoMgr.m | 9 + Cantera/matlab/cantera/@Reactor/step.m | 28 + Cantera/matlab/cantera/@Reactor/temperature.m | 5 + Cantera/matlab/cantera/@Reactor/time.m | 4 + Cantera/matlab/cantera/@Reactor/volume.m | 4 + Cantera/matlab/cantera/@Solution/Solution.m | 54 + Cantera/matlab/cantera/@Solution/clear.m | 9 + Cantera/matlab/cantera/@Solution/display.m | 22 + Cantera/matlab/cantera/@Solution/set.m | 125 + Cantera/matlab/cantera/@Solution/soundspeed.m | 18 + .../matlab/cantera/@ThermoPhase/ThermoPhase.m | 23 + .../cantera/@ThermoPhase/atomicMasses.m | 4 + .../cantera/@ThermoPhase/chemPotentials.m | 9 + Cantera/matlab/cantera/@ThermoPhase/clear.m | 5 + Cantera/matlab/cantera/@ThermoPhase/cp_R.m | 8 + Cantera/matlab/cantera/@ThermoPhase/cp_mass.m | 3 + Cantera/matlab/cantera/@ThermoPhase/cp_mole.m | 3 + Cantera/matlab/cantera/@ThermoPhase/cv_mass.m | 3 + Cantera/matlab/cantera/@ThermoPhase/cv_mole.m | 3 + Cantera/matlab/cantera/@ThermoPhase/density.m | 4 + .../cantera/@ThermoPhase/elementIndex.m | 16 + .../matlab/cantera/@ThermoPhase/elementName.m | 17 + .../cantera/@ThermoPhase/enthalpies_RT.m | 12 + .../cantera/@ThermoPhase/enthalpy_mass.m | 4 + .../cantera/@ThermoPhase/enthalpy_mole.m | 4 + .../matlab/cantera/@ThermoPhase/entropies_R.m | 7 + .../cantera/@ThermoPhase/entropy_mass.m | 2 + .../cantera/@ThermoPhase/entropy_mole.m | 2 + Cantera/matlab/cantera/@ThermoPhase/eosType.m | 7 + .../matlab/cantera/@ThermoPhase/equilibrate.m | 51 + .../matlab/cantera/@ThermoPhase/gibbs_RT.m | 8 + .../matlab/cantera/@ThermoPhase/gibbs_mass.m | 3 + .../matlab/cantera/@ThermoPhase/gibbs_mole.m | 3 + Cantera/matlab/cantera/@ThermoPhase/hndl.m | 2 + .../cantera/@ThermoPhase/intEnergy_mass.m | 3 + .../cantera/@ThermoPhase/intEnergy_mole.m | 3 + .../matlab/cantera/@ThermoPhase/isIdealGas.m | 9 + .../cantera/@ThermoPhase/massFractions.m | 17 + Cantera/matlab/cantera/@ThermoPhase/maxTemp.m | 12 + .../cantera/@ThermoPhase/meanMolarMass.m | 8 + .../@ThermoPhase/meanMolecularWeight.m | 9 + Cantera/matlab/cantera/@ThermoPhase/minTemp.m | 12 + .../cantera/@ThermoPhase/molarDensity.m | 4 + .../matlab/cantera/@ThermoPhase/molarMasses.m | 4 + .../cantera/@ThermoPhase/moleFractions.m | 17 + .../cantera/@ThermoPhase/molecularWeights.m | 9 + Cantera/matlab/cantera/@ThermoPhase/nAtoms.m | 7 + .../matlab/cantera/@ThermoPhase/nElements.m | 4 + .../matlab/cantera/@ThermoPhase/nSpecies.m | 4 + Cantera/matlab/cantera/@ThermoPhase/ph.m | 3 + .../matlab/cantera/@ThermoPhase/pressure.m | 4 + .../cantera/@ThermoPhase/private/phase_get.m | 8 + .../cantera/@ThermoPhase/private/phase_set.m | 8 + .../cantera/@ThermoPhase/private/thermo_get.m | 8 + .../cantera/@ThermoPhase/private/thermo_set.m | 8 + .../matlab/cantera/@ThermoPhase/refPressure.m | 6 + Cantera/matlab/cantera/@ThermoPhase/set.m | 16 + .../matlab/cantera/@ThermoPhase/setDensity.m | 10 + .../cantera/@ThermoPhase/setMassFractions.m | 48 + .../cantera/@ThermoPhase/setMoleFractions.m | 47 + .../matlab/cantera/@ThermoPhase/setPressure.m | 11 + .../matlab/cantera/@ThermoPhase/setState.m | 12 + .../matlab/cantera/@ThermoPhase/setState_HP.m | 13 + .../matlab/cantera/@ThermoPhase/setState_SP.m | 15 + .../matlab/cantera/@ThermoPhase/setState_UV.m | 14 + .../cantera/@ThermoPhase/setTemperature.m | 7 + .../cantera/@ThermoPhase/speciesIndex.m | 16 + .../matlab/cantera/@ThermoPhase/speciesName.m | 16 + .../cantera/@ThermoPhase/speciesNames.m | 2 + .../matlab/cantera/@ThermoPhase/temperature.m | 3 + .../matlab/cantera/@ThermoPhase/thermo_hndl.m | 2 + Cantera/matlab/cantera/@Transport/Transport.m | 21 + .../matlab/cantera/@Transport/binDiffCoeffs.m | 10 + Cantera/matlab/cantera/@Transport/hndl.m | 2 + .../matlab/cantera/@Transport/mixDiffCoeffs.m | 20 + .../cantera/@Transport/multiDiffCoeffs.m | 20 + .../@Transport/private/newTransport.cpp | 54 + .../cantera/@Transport/private/trans_get.m | 14 + .../@Transport/private/trans_methods.cpp | 82 + .../cantera/@Transport/thermalConductivity.m | 8 + .../cantera/@Transport/thermalDiffCoeffs.m | 13 + Cantera/matlab/cantera/@Transport/viscosity.m | 8 + Cantera/matlab/cantera/@Wall/Wall.m | 14 + Cantera/matlab/cantera/@Wall/area.m | 5 + Cantera/matlab/cantera/@Wall/install.m | 8 + .../cantera/@Wall/private/wallmethods.cpp | 116 + .../cantera/@Wall/private/wallmethods.m | 13 + Cantera/matlab/cantera/@Wall/ready.m | 5 + Cantera/matlab/cantera/@Wall/setArea.m | 5 + .../cantera/@Wall/setExpansionRateCoeff.m | 5 + .../cantera/@Wall/setHeatTransferCoeff.m | 5 + .../cantera/@Wall/setThermalResistance.m | 5 + Cantera/matlab/cantera/@Wall/wall_hndl.m | 4 + Cantera/matlab/cantera/@XML_Node/XML_Node.m | 24 + Cantera/matlab/cantera/@XML_Node/attrib.m | 9 + Cantera/matlab/cantera/@XML_Node/build.m | 9 + Cantera/matlab/cantera/@XML_Node/child.m | 6 + Cantera/matlab/cantera/@XML_Node/hndl.m | 2 + .../cantera/@XML_Node/private/newxml.cpp | 34 + .../cantera/@XML_Node/private/xmlmethods.cpp | 158 + Cantera/matlab/cantera/@XML_Node/value.m | 13 + Cantera/matlab/cantera/@XML_Node/write.m | 4 + Cantera/matlab/cantera/Contents.m | 40 + Cantera/matlab/cantera/GRI30.m | 27 + Cantera/matlab/cantera/IdealGasMix.m | 60 + Cantera/matlab/cantera/MassFlowController.m | 19 + Cantera/matlab/cantera/Reservoir.m | 21 + Cantera/matlab/cantera/Valve.m | 32 + Cantera/matlab/cantera/adddir.m | 9 + Cantera/matlab/cantera/air.m | 7 + Cantera/matlab/cantera/build.m | 45 + Cantera/matlab/cantera/buildux.m | 9 + Cantera/matlab/cantera/buildwin.m | 59 + Cantera/matlab/cantera/ck2ctml.m | 45 + Cantera/matlab/cantera/conhp.m | 27 + Cantera/matlab/cantera/constants.m | 3 + Cantera/matlab/cantera/conuv.m | 27 + Cantera/matlab/cantera/examples/equil.m | 58 + Cantera/matlab/cantera/examples/ignite.m | 105 + Cantera/matlab/cantera/examples/ignite2.m | 106 + Cantera/matlab/cantera/examples/ignite3.m | 40 + Cantera/matlab/cantera/examples/ignite_hp.m | 38 + Cantera/matlab/cantera/examples/ignite_uv.m | 38 + Cantera/matlab/cantera/examples/isentropic.m | 57 + .../matlab/cantera/examples/periodic_cstr.m | 109 + Cantera/matlab/cantera/examples/prandtl1.m | 72 + Cantera/matlab/cantera/examples/prandtl2.m | 46 + Cantera/matlab/cantera/examples/reactor1.m | 54 + Cantera/matlab/cantera/examples/reactor2.m | 36 + .../matlab/cantera/examples/run_examples.m | 44 + Cantera/matlab/cantera/examples/transport1.m | 44 + Cantera/matlab/cantera/gasconstant.m | 3 + Cantera/matlab/cantera/geterr.m | 6 + Cantera/matlab/cantera/mexopts.sh | 375 + Cantera/matlab/cantera/oneatm.m | 3 + .../matlab/cantera/private/ctfunctions.cpp | 64 + Cantera/matlab/cantera/private/ctmatutils.h | 35 + Cantera/matlab/cantera/private/ctmethods.cpp | 56 + .../cantera/private/flowdevicemethods.cpp | 87 + .../matlab/cantera/private/importFromFile.m | 33 + .../cantera/private/kineticsmethods.cpp | 154 + .../matlab/cantera/private/phasemethods.cpp | 246 + .../matlab/cantera/private/reactormethods.cpp | 118 + .../matlab/cantera/private/thermomethods.cpp | 182 + .../cantera/private/transportmethods.cpp | 89 + .../matlab/cantera/private/wallmethods.cpp | 105 + Cantera/matlab/cantera/private/xmlmethods.cpp | 145 + Cantera/matlab/cantera/reactor_ode.m | 51 + Cantera/matlab/cantera/tutorial/README | 5 + Cantera/matlab/cantera/tutorial/tut1.m | 204 + Cantera/matlab/cantera/tutorial/tut2.m | 95 + Cantera/matlab/cantera/tutorial/tut3.m | 54 + Cantera/matlab/cantera/tutorial/tut4.m | 76 + Cantera/matlab/cantera/tutorial/tut5.m | 105 + Cantera/matlab/cantera/tutorial/tut6.m | 62 + Cantera/matlab/cantera/tutorial/tut7.m | 39 + Cantera/matlab/setup_matlab.py | 25 + Cantera/python/.cvsignore | 2 + Cantera/python/Cantera/Flow.py | 682 ++ Cantera/python/Cantera/FlowBoundary.py | 140 + Cantera/python/Cantera/FlowPlotter.py | 65 + Cantera/python/Cantera/Func.py | 122 + Cantera/python/Cantera/Interface.py | 41 + Cantera/python/Cantera/Kinetics.py | 192 + Cantera/python/Cantera/OneDim.py | 432 ++ Cantera/python/Cantera/Phase.py | 240 + Cantera/python/Cantera/Reactor.py | 378 + Cantera/python/Cantera/SurfWriter.py | 180 + Cantera/python/Cantera/SurfacePhase.py | 38 + Cantera/python/Cantera/Thermo.py | 227 + Cantera/python/Cantera/ThermoPhase.py | 263 + Cantera/python/Cantera/Transport.py | 72 + Cantera/python/Cantera/XML.py | 175 + Cantera/python/Cantera/__init__.py | 55 + Cantera/python/Cantera/boundaries1D.py | 53 + Cantera/python/Cantera/ck2ctml.py | 21 + Cantera/python/Cantera/constants.py | 14 + Cantera/python/Cantera/elements.py | 21 + Cantera/python/Cantera/excel.py | 33 + Cantera/python/Cantera/exceptions.py | 20 + Cantera/python/Cantera/flame.py | 373 + Cantera/python/Cantera/gases.py | 88 + Cantera/python/Cantera/importFromFile.py | 8 + Cantera/python/Cantera/interp.py | 64 + Cantera/python/Cantera/refine.py | 295 + Cantera/python/Cantera/rxnpath.py | 166 + Cantera/python/Cantera/schem.py | 566 ++ Cantera/python/Cantera/set.py | 58 + Cantera/python/Cantera/solids.py | 14 + Cantera/python/Cantera/solution.py | 71 + Cantera/python/Cantera/solve.py | 109 + Cantera/python/Cantera/stoich.py | 46 + Cantera/python/Cantera/tecplot.py | 42 + Cantera/python/Cantera/units.py | 63 + Cantera/python/Makefile.in | 31 + Cantera/python/examples/flame1.py | 79 + Cantera/python/examples/flame2.py | 49 + Cantera/python/examples/isentropic.py | 79 + Cantera/python/examples/reactor1.py | 34 + Cantera/python/examples/reactor2.py | 89 + Cantera/python/examples/rxnpath1.py | 52 + Cantera/python/examples/rxnpath2.py | 67 + Cantera/python/examples/stflame1.py | 88 + Cantera/python/examples/stflame2.py | 84 + Cantera/python/setup.py | 41 + Cantera/python/src/.cvsignore | 2 + Cantera/python/src/Makefile.in | 10 + Cantera/python/src/cantera.def | 2 + Cantera/python/src/canteramodule.cpp | 143 + Cantera/python/src/ct.def | 2 + Cantera/python/src/ctbndry_methods.cpp | 94 + Cantera/python/src/ctflow.cpp | 612 ++ Cantera/python/src/ctflow.def | 2 + Cantera/python/src/ctflow_methods.cpp | 472 ++ Cantera/python/src/ctfunc_methods.cpp | 49 + Cantera/python/src/ctfuncs.cpp | 64 + Cantera/python/src/ctkinetics.cpp | 266 + Cantera/python/src/ctkinetics.def | 2 + Cantera/python/src/ctkinetics_methods.cpp | 194 + Cantera/python/src/ctmodule.cpp | 118 + Cantera/python/src/ctnumerics.cpp | 315 + Cantera/python/src/ctnumerics.def | 2 + Cantera/python/src/ctphase.cpp | 417 ++ Cantera/python/src/ctphase.def | 2 + Cantera/python/src/ctphase_methods.cpp | 298 + Cantera/python/src/ctpy.cpp | 85 + Cantera/python/src/ctpybndry.cpp | 156 + Cantera/python/src/ctpyfunc.cpp | 108 + Cantera/python/src/ctpyreactor.cpp | 685 ++ Cantera/python/src/ctpyrpath.cpp | 359 + Cantera/python/src/ctpysurf.cpp | 404 + Cantera/python/src/ctpyxml.cpp | 283 + Cantera/python/src/ctreactor_methods.cpp | 438 ++ Cantera/python/src/ctrpath_methods.cpp | 284 + Cantera/python/src/ctsurf.cpp | 575 ++ Cantera/python/src/ctsurf.def | 2 + Cantera/python/src/ctsurf_methods.cpp | 84 + Cantera/python/src/ctthermo.cpp | 294 + Cantera/python/src/ctthermo.def | 2 + Cantera/python/src/ctthermo_methods.cpp | 231 + Cantera/python/src/cttransport.cpp | 171 + Cantera/python/src/cttransport.def | 2 + Cantera/python/src/cttransport_methods.cpp | 106 + Cantera/python/src/ctxml_methods.cpp | 214 + Cantera/python/src/methods.h | 211 + Cantera/python/src/pycantera.cpp | 73 + Cantera/python/src/pyutils.h | 137 + Cantera/python/src/reactionpath.cpp | 71 + Cantera/python/tutorial/tut1.py | 172 + Cantera/python/tutorial/tut2.py | 76 + Cantera/python/tutorial/tut4.py | 72 + Cantera/src/.cvsignore | 1 + Cantera/src/Array.h | 215 + Cantera/src/ArrayViewer.h | 144 + Cantera/src/BandMatrix.cpp | 225 + Cantera/src/BandMatrix.h | 150 + Cantera/src/CVode.cpp | 297 + Cantera/src/CVode.h | 98 + Cantera/src/ChemEquil.cpp | 688 ++ Cantera/src/ChemEquil.h | 192 + Cantera/src/ConstDensityThermo.cpp | 102 + Cantera/src/ConstDensityThermo.h | 196 + Cantera/src/Constituents.cpp | 506 ++ Cantera/src/Constituents.h | 264 + Cantera/src/DASPK.cpp | 278 + Cantera/src/DASPK.h | 115 + Cantera/src/DenseMatrix.cpp | 148 + Cantera/src/DenseMatrix.h | 113 + Cantera/src/EOS_TPX.h | 209 + Cantera/src/Elements.cpp | 534 ++ Cantera/src/Elements.h | 218 + Cantera/src/Enhanced3BConc.h | 81 + Cantera/src/FILES | 106 + Cantera/src/FalloffFactory.cpp | 288 + Cantera/src/FalloffFactory.h | 127 + Cantera/src/FalloffMgr.h | 122 + Cantera/src/Flow1D.h | 82 + Cantera/src/FtnODESys.h | 56 + Cantera/src/Func1.h | 199 + Cantera/src/FuncEval.h | 60 + Cantera/src/GRI30.h | 89 + Cantera/src/GRI_30_Kinetics.cpp | 1004 +++ Cantera/src/GRI_30_Kinetics.h | 50 + Cantera/src/GasKinetics.cpp | 471 ++ Cantera/src/GasKinetics.h | 263 + Cantera/src/GasKineticsWriter.cpp | 136 + Cantera/src/GasKineticsWriter.h | 204 + Cantera/src/Group.cpp | 76 + Cantera/src/Group.h | 139 + Cantera/src/IdealGasPhase.cpp | 110 + Cantera/src/IdealGasPhase.h | 311 + Cantera/src/IdealGasThermo.cpp | 110 + Cantera/src/IdealGasThermo.h | 212 + Cantera/src/ImplicitChem.cpp | 88 + Cantera/src/ImplicitChem.h | 118 + Cantera/src/ImplicitSurfChem.cpp | 79 + Cantera/src/ImplicitSurfChem.h | 107 + Cantera/src/IncompressibleThermo.h | 97 + Cantera/src/Integrator.h | 162 + Cantera/src/InterfaceKinetics.cpp | 453 ++ Cantera/src/InterfaceKinetics.h | 213 + Cantera/src/Jac2.h | 198 + Cantera/src/Kinetics.h | 320 + Cantera/src/KineticsFactory.cpp | 106 + Cantera/src/KineticsFactory.h | 80 + Cantera/src/L_matrix.h | 254 + Cantera/src/MMCollisionInt.cpp | 501 ++ Cantera/src/Makefile.in | 134 + Cantera/src/MixTransport.cpp | 445 ++ Cantera/src/MultiDomain.h | 155 + Cantera/src/NasaPoly1.h | 107 + Cantera/src/NasaThermo.h | 202 + Cantera/src/Newton.h | 74 + Cantera/src/Phase.cpp | 237 + Cantera/src/Phase.h | 188 + Cantera/src/PolyThermo.h | 99 + Cantera/src/PolyThermoMgr.h | 96 + Cantera/src/PropertyCalculator.h | 74 + Cantera/src/PropertyUpdater.h | 171 + Cantera/src/RateCoeffMgr.h | 159 + Cantera/src/ReactionData.h | 61 + Cantera/src/ReactionPath.cpp | 953 +++ Cantera/src/ReactionPath.h | 273 + Cantera/src/Resid.h | 141 + Cantera/src/Resid1D.h | 237 + Cantera/src/ResidEval.h | 56 + Cantera/src/RxnRates.h | 118 + Cantera/src/ShomatePoly.h | 108 + Cantera/src/ShomateThermo.h | 149 + Cantera/src/SimpleThermo.h | 95 + Cantera/src/SpeciesThermo.h | 122 + Cantera/src/SpeciesThermoFactory.cpp | 83 + Cantera/src/SpeciesThermoFactory.h | 83 + Cantera/src/SpeciesThermoMgr.h | 215 + Cantera/src/State.h | 352 + Cantera/src/StoichManager.h | 447 ++ Cantera/src/Surf1D.h | 310 + Cantera/src/SurfPhase.h | 83 + Cantera/src/Thermo.h | 444 ++ Cantera/src/ThermoFactory.cpp | 130 + Cantera/src/ThermoFactory.h | 80 + Cantera/src/ThermoPhase.cpp | 101 + Cantera/src/ThermoPhase.h | 601 ++ Cantera/src/ThirdBodyMgr.h | 186 + Cantera/src/TigerPolynomial.h | 116 + Cantera/src/config.h | 59 + Cantera/src/converters/.cvsignore | 2 + Cantera/src/converters/CKParser.cpp | 1309 ++++ Cantera/src/converters/CKParser.h | 89 + Cantera/src/converters/CKReader.cpp | 663 ++ Cantera/src/converters/CKReader.h | 93 + Cantera/src/converters/Constituent.h | 31 + Cantera/src/converters/Element.h | 101 + Cantera/src/converters/Group.h | 64 + Cantera/src/converters/Makefile.in | 53 + Cantera/src/converters/Reaction.cpp | 175 + Cantera/src/converters/Reaction.h | 258 + Cantera/src/converters/RxnSpecies.h | 37 + Cantera/src/converters/Species.h | 117 + Cantera/src/converters/atomicWeightDB.cpp | 126 + Cantera/src/converters/ck2ctml.cpp | 556 ++ Cantera/src/converters/ck2ctml.h | 57 + Cantera/src/converters/ckr_defs.h | 96 + Cantera/src/converters/ckr_utils.cpp | 147 + Cantera/src/converters/ckr_utils.h | 168 + Cantera/src/converters/config.h | 25 + Cantera/src/converters/filter.cpp | 106 + Cantera/src/converters/thermoFunctions.cpp | 92 + Cantera/src/converters/thermoFunctions.h | 30 + Cantera/src/converters/writelog.cpp | 241 + Cantera/src/converters/writelog.h | 31 + Cantera/src/ct_defs.h | 163 + Cantera/src/ctexceptions.h | 47 + Cantera/src/ctlapack.h | 237 + Cantera/src/ctml.cpp | 362 + Cantera/src/ctml.h | 92 + Cantera/src/ctvector.cpp | 191 + Cantera/src/ctvector.h | 115 + Cantera/src/exceptions.h | 80 + Cantera/src/fitPoly.h | 117 + Cantera/src/flowBoundaries.h | 213 + Cantera/src/funcs.cpp | 50 + Cantera/src/gases.h | 29 + Cantera/src/global.h | 62 + Cantera/src/import.h | 41 + Cantera/src/importCTML.cpp | 828 +++ Cantera/src/importCTML.h | 36 + Cantera/src/importSurfChem.cpp | 106 + Cantera/src/importXML.h | 25 + Cantera/src/lapack.h | 62 + Cantera/src/misc.cpp | 293 + Cantera/src/mix_defs.h | 23 + Cantera/src/mix_utils.h | 95 + Cantera/src/newton_utils.cpp | 102 + Cantera/src/oneD/.cvsignore | 2 + Cantera/src/oneD/Inlet1D.h | 471 ++ Cantera/src/oneD/Jac1D.h | 88 + Cantera/src/oneD/Makefile.in | 53 + Cantera/src/oneD/MultiJac.cpp | 114 + Cantera/src/oneD/MultiJac.h | 97 + Cantera/src/oneD/MultiNewton.cpp | 371 + Cantera/src/oneD/MultiNewton.h | 77 + Cantera/src/oneD/Newton1D.h | 73 + Cantera/src/oneD/OneDim.cpp | 377 + Cantera/src/oneD/OneDim.h | 156 + Cantera/src/oneD/Resid1D.h | 237 + Cantera/src/oneD/StFlow.cpp | 1239 +++ Cantera/src/oneD/StFlow.h | 466 ++ Cantera/src/oneD/Surf1D.h | 310 + Cantera/src/oneD/newton_utils.cpp | 100 + Cantera/src/plots.cpp | 103 + Cantera/src/plots.h | 25 + Cantera/src/polyfit.h | 55 + Cantera/src/pureSubstances.h | 138 + Cantera/src/reaction_defs.h | 89 + Cantera/src/recipes.h | 21 + Cantera/src/sort.cpp | 122 + Cantera/src/sort.h | 18 + Cantera/src/speciesThermoTypes.h | 58 + Cantera/src/stringUtils.cpp | 280 + Cantera/src/stringUtils.h | 34 + Cantera/src/surfKinetics.cpp | 390 + Cantera/src/surfKinetics.h | 190 + Cantera/src/surfacePhase.h | 78 + Cantera/src/transport/.cvsignore | 2 + Cantera/src/transport/FtnTransport.h | 158 + Cantera/src/transport/MMCollisionInt.cpp | 501 ++ Cantera/src/transport/MMCollisionInt.h | 101 + Cantera/src/transport/Makefile.in | 53 + Cantera/src/transport/MixTransport.cpp | 445 ++ Cantera/src/transport/MixTransport.h | 171 + Cantera/src/transport/MultiTransport.cpp | 780 ++ Cantera/src/transport/MultiTransport.h | 273 + Cantera/src/transport/TransportBase.h | 359 + Cantera/src/transport/TransportFactory.cpp | 1079 +++ Cantera/src/transport/TransportFactory.h | 192 + Cantera/src/transport/TransportParams.h | 64 + Cantera/src/transportModels.h | 16 + Cantera/src/units.h | 99 + Cantera/src/updaters.h | 113 + Cantera/src/utilities.h | 281 + Cantera/src/vec_functions.h | 114 + Cantera/src/xml.cpp | 543 ++ Cantera/src/xml.h | 239 + Cantera/src/zeroD/.cvsignore | 2 + Cantera/src/zeroD/FlowDevice.cpp | 53 + Cantera/src/zeroD/FlowDevice.h | 163 + Cantera/src/zeroD/Makefile.in | 53 + Cantera/src/zeroD/PID_Controller.h | 151 + Cantera/src/zeroD/Reactor.cpp | 225 + Cantera/src/zeroD/Reactor.h | 297 + Cantera/src/zeroD/ReactorBase.cpp | 98 + Cantera/src/zeroD/ReactorBase.h | 182 + Cantera/src/zeroD/Reservoir.h | 47 + Cantera/src/zeroD/Wall.cpp | 36 + Cantera/src/zeroD/Wall.h | 147 + Cantera/src/zeroD/flowControllers.h | 218 + INSTALLING | 51 + License.rtf | 71 + License.txt | 43 + Makefile.in | 165 + README | 108 + apps/MixMaster/.cvsignore | 1 + apps/MixMaster/CompositionFrame.py | 246 + apps/MixMaster/ControlPanel.py | 212 + apps/MixMaster/DataFrame.py | 363 + apps/MixMaster/DataGraph.py | 231 + apps/MixMaster/Edit.py | 194 + apps/MixMaster/ElementFrame.py | 184 + apps/MixMaster/GraphFrame.py | 130 + apps/MixMaster/ImportFrame.py | 119 + apps/MixMaster/KineticsFrame.py | 356 + apps/MixMaster/MechManager.py | 86 + apps/MixMaster/Mix.py | 132 + apps/MixMaster/NewFlowFrame.py | 116 + apps/MixMaster/SpeciesFrame.py | 176 + apps/MixMaster/SpeciesInfo.py | 245 + apps/MixMaster/ThermoFrame.py | 139 + apps/MixMaster/ThermoProp.py | 44 + apps/MixMaster/TransportFrame.py | 35 + apps/MixMaster/UnitChooser.py | 84 + apps/MixMaster/Units/SI.py | 140 + apps/MixMaster/Units/__init__.py | 27 + apps/MixMaster/Units/area.py | 46 + apps/MixMaster/Units/density.py | 38 + apps/MixMaster/Units/energy.py | 46 + apps/MixMaster/Units/force.py | 35 + apps/MixMaster/Units/length.py | 54 + apps/MixMaster/Units/mass.py | 42 + apps/MixMaster/Units/power.py | 37 + apps/MixMaster/Units/pressure.py | 41 + apps/MixMaster/Units/specificEnergy.py | 41 + apps/MixMaster/Units/specificEntropy.py | 35 + apps/MixMaster/Units/speed.py | 38 + apps/MixMaster/Units/temperature.py | 32 + apps/MixMaster/Units/time.py | 39 + apps/MixMaster/Units/unit.py | 135 + apps/MixMaster/Units/volume.py | 46 + apps/MixMaster/__init__.py | 5 + apps/MixMaster/config.py | 7 + apps/MixMaster/flowpanel.py | 56 + apps/MixMaster/gri30.py | 1186 +++ apps/MixMaster/main.py | 330 + apps/MixMaster/menu.py | 31 + apps/MixMaster/newflow.py | 135 + apps/MixMaster/utilities.py | 44 + apps/README.txt | 8 + bin/.cvsignore | 5 + bin/README | 1 + bin/mixmaster.py | 2 + bin/rm_cvsignore | 40 + config.h | 59 + config.h.in | 58 + config/.cvsignore | 2 + config/Cantera.README | 1 + config/config.guess | 1321 ++++ config/config.h.in | 12 + config/config.sub | 1443 ++++ config/configure | 3741 ++++++++++ config/configure.in | 431 ++ config/install-sh | 251 + configure | 293 + data/README | 5 + data/inputs/.cvsignore | 3 + data/inputs/Makefile.in | 15 + data/inputs/air.inp | 20 + data/inputs/air.xml | 296 + data/inputs/argon.inp | 8 + data/inputs/argon.xml | 55 + data/inputs/elements.xml | 100 + data/inputs/gases.xml | 27 + data/inputs/gri30.inp | 661 ++ data/inputs/gri30.xml | 4877 ++++++++++++ data/inputs/gri30mod.inp | 692 ++ data/inputs/grinc.inp | 228 + data/inputs/h2o2.inp | 88 + data/inputs/h2o2.xml | 558 ++ data/inputs/h2o2_noch.inp | 48 + data/inputs/mkxml | 7 + data/inputs/silane.inp | 108 + data/inputs/silane.xml | 480 ++ data/thermo/nasathermo.dat | 4561 ++++++++++++ data/transport/gri30_tran.dat | 110 + examples/.cvsignore | 1 + examples/Makefile.in | 12 + examples/cxx/.cvsignore | 2 + examples/cxx/Makefile.in | 100 + examples/cxx/equil_example1.cpp | 119 + examples/cxx/example_utils.h | 58 + examples/cxx/examples.cpp | 75 + examples/cxx/examples.dsp | 134 + examples/cxx/kinetics_example1.cpp | 126 + examples/cxx/kinetics_example2.cpp | 114 + examples/cxx/rxnpath_example1.cpp | 161 + examples/cxx/transport_example1.cpp | 110 + examples/cxx/transport_example2.cpp | 112 + ext/.cvsignore | 1 + ext/Makefile.in | 33 + ext/blas/.cvsignore | 1 + ext/blas/Makefile.in | 69 + ext/blas/dasum.f | 43 + ext/blas/daxpy.f | 48 + ext/blas/dcabs1.f | 8 + ext/blas/dcopy.f | 50 + ext/blas/ddot.f | 49 + ext/blas/dgbmv.f | 300 + ext/blas/dgemm.f | 313 + ext/blas/dgemv.f | 261 + ext/blas/dger.f | 157 + ext/blas/dnrm2.f | 60 + ext/blas/drot.f | 37 + ext/blas/drotg.f | 27 + ext/blas/drotm.f | 108 + ext/blas/drotmg.f | 169 + ext/blas/dsbmv.f | 303 + ext/blas/dscal.f | 43 + ext/blas/dsdot.f | 74 + ext/blas/dspmv.f | 262 + ext/blas/dspr.f | 198 + ext/blas/dspr2.f | 229 + ext/blas/dswap.f | 56 + ext/blas/dsymm.f | 294 + ext/blas/dsymv.f | 262 + ext/blas/dsyr.f | 197 + ext/blas/dsyr2.f | 230 + ext/blas/dsyr2k.f | 327 + ext/blas/dsyrk.f | 294 + ext/blas/dtbmv.f | 342 + ext/blas/dtbsv.f | 346 + ext/blas/dtpmv.f | 299 + ext/blas/dtpsv.f | 302 + ext/blas/dtrmm.f | 355 + ext/blas/dtrmv.f | 286 + ext/blas/dtrsm.f | 378 + ext/blas/dtrsv.f | 289 + ext/blas/dzasum.f | 34 + ext/blas/dznrm2.f | 67 + ext/blas/icamax.f | 43 + ext/blas/idamax.f | 39 + ext/blas/isamax.f | 39 + ext/blas/izamax.f | 41 + ext/blas/lsame.f | 87 + ext/blas/xerbla.f | 43 + ext/cvode/.cvsignore | 1 + ext/cvode/Makefile.in | 96 + ext/cvode/include/band.h | 609 ++ ext/cvode/include/cvband.h | 221 + ext/cvode/include/cvbandpre.h | 151 + ext/cvode/include/cvdense.h | 191 + ext/cvode/include/cvdiag.h | 71 + ext/cvode/include/cvode.h | 826 ++ ext/cvode/include/cvspgmr.h | 336 + ext/cvode/include/dense.h | 494 ++ ext/cvode/include/iterativ.h | 243 + ext/cvode/include/llnlmath.h | 121 + ext/cvode/include/llnltyps.h | 131 + ext/cvode/include/nvector.h | 535 ++ ext/cvode/include/spgmr.h | 295 + ext/cvode/source/band.c | 356 + ext/cvode/source/cvband.c | 415 ++ ext/cvode/source/cvbandpre.c | 316 + ext/cvode/source/cvdense.c | 372 + ext/cvode/source/cvdiag.c | 292 + ext/cvode/source/cvode.c | 2631 +++++++ ext/cvode/source/cvspgmr.c | 499 ++ ext/cvode/source/dense.c | 311 + ext/cvode/source/iterativ.c | 258 + ext/cvode/source/llnlmath.c | 67 + ext/cvode/source/nvector.c | 670 ++ ext/cvode/source/spgmr.c | 429 ++ ext/lapack/.cvsignore | 1 + ext/lapack/Makefile.in | 89 + ext/lapack/dbdsqr.f | 807 ++ ext/lapack/dgbsv.f | 144 + ext/lapack/dgbtf2.f | 203 + ext/lapack/dgbtrf.f | 442 ++ ext/lapack/dgbtrs.f | 187 + ext/lapack/dgebd2.f | 238 + ext/lapack/dgebrd.f | 258 + ext/lapack/dgelq2.f | 122 + ext/lapack/dgelqf.f | 186 + ext/lapack/dgelss.f | 604 ++ ext/lapack/dgeqr2.f | 122 + ext/lapack/dgeqrf.f | 187 + ext/lapack/dgetf2.f | 135 + ext/lapack/dgetrf.f | 160 + ext/lapack/dgetri.f | 801 ++ ext/lapack/dgetrs.f | 150 + ext/lapack/dlabad.f | 56 + ext/lapack/dlabrd.f | 291 + ext/lapack/dlacpy.f | 88 + ext/lapack/dlamch.f | 857 +++ ext/lapack/dlange.f | 145 + ext/lapack/dlapy2.f | 54 + ext/lapack/dlarf.f | 116 + ext/lapack/dlarfb.f | 588 ++ ext/lapack/dlarfg.f | 138 + ext/lapack/dlarft.f | 218 + ext/lapack/dlartg.f | 143 + ext/lapack/dlas2.f | 122 + ext/lapack/dlascl.f | 268 + ext/lapack/dlaset.f | 115 + ext/lapack/dlasq1.f | 222 + ext/lapack/dlasq2.f | 268 + ext/lapack/dlasq3.f | 820 ++ ext/lapack/dlasq4.f | 103 + ext/lapack/dlasr.f | 325 + ext/lapack/dlasrt.f | 244 + ext/lapack/dlassq.f | 89 + ext/lapack/dlasv2.f | 250 + ext/lapack/dlaswp.f | 120 + ext/lapack/dorg2r.f | 130 + ext/lapack/dorgbr.f | 223 + ext/lapack/dorgl2.f | 134 + ext/lapack/dorglq.f | 207 + ext/lapack/dorgqr.f | 208 + ext/lapack/dorm2r.f | 198 + ext/lapack/dormbr.f | 250 + ext/lapack/dorml2.f | 198 + ext/lapack/dormlq.f | 254 + ext/lapack/dormqr.f | 247 + ext/lapack/drscl.f | 115 + ext/lapack/ilaenv.f | 506 ++ ext/lapack/lsame.f | 87 + ext/lapack/xerbla.f | 46 + ext/math/.cvsignore | 1 + ext/math/Makefile.in | 58 + ext/math/cblas.h | 646 ++ ext/math/daux.f | 253 + ext/math/ddaspk.f | 6612 +++++++++++++++++ ext/math/dgbefa.f | 174 + ext/math/dgbsl.f | 135 + ext/math/dgefa.f | 104 + ext/math/dgesl.f | 117 + ext/math/dp1vlu.f | 151 + ext/math/dpcoef.f | 78 + ext/math/dpolft.f | 364 + ext/math/fdump.f | 70 + ext/math/gmres.h | 144 + ext/math/idamax.f | 39 + ext/math/j4save.f | 65 + ext/math/mach.cpp | 56 + ext/math/mkl_cblas.h | 644 ++ ext/math/pcoef.f | 712 ++ ext/math/polfit.f | 352 + ext/math/pvalue.f | 148 + ext/math/xercnt.f | 60 + ext/math/xerhlt.f | 40 + ext/math/xermsg.f | 364 + ext/math/xerprn.f | 228 + ext/math/xersve.f | 155 + ext/math/xgetua.f | 51 + ext/recipes/.cvsignore | 2 + ext/recipes/Makefile.in | 33 + ext/recipes/simp1.f | 19 + ext/recipes/simp2.f | 32 + ext/recipes/simp3.f | 22 + ext/recipes/simplx.f | 99 + ext/recipes/splie2.f | 15 + ext/recipes/splin2.f | 16 + ext/recipes/spline.f | 31 + ext/recipes/splint.f | 22 + ext/tpx/.cvsignore | 2 + ext/tpx/.depends | 1 + ext/tpx/CFluid.cpp | 6 + ext/tpx/CFluid.h | 75 + ext/tpx/CGas.cpp | 0 ext/tpx/CLK.cpp | 117 + ext/tpx/CLK.h | 49 + ext/tpx/HFC134a.cpp | 172 + ext/tpx/HFC134a.h | 31 + ext/tpx/Hydrogen.cpp | 258 + ext/tpx/Hydrogen.h | 39 + ext/tpx/Makefile.in | 43 + ext/tpx/Methane.cpp | 212 + ext/tpx/Methane.h | 36 + ext/tpx/Nitrogen.cpp | 221 + ext/tpx/Nitrogen.h | 41 + ext/tpx/Oxygen.cpp | 211 + ext/tpx/Oxygen.h | 38 + ext/tpx/Sub.cpp | 583 ++ ext/tpx/Sub.h | 217 + ext/tpx/Water.cpp | 177 + ext/tpx/Water.h | 38 + ext/tpx/ck_gas.cpp | 26 + ext/tpx/ck_gas.h | 85 + ext/tpx/ideal.cpp | 34 + ext/tpx/lk.cpp | 131 + ext/tpx/lk.h | 44 + ext/tpx/lkw.cpp | 80 + ext/tpx/lkw.h | 49 + ext/tpx/mix.h | 63 + ext/tpx/subs.h | 12 + ext/tpx/utils.cpp | 24 + ext/tpx/utils.h | 8 + include/Cantera.h | 25 + include/IdealGasMix.h | 55 + include/README | 5 + include/config.h | 59 + include/core.h | 9 + include/ctml.h | 92 + include/equilibrium.h | 9 + include/fortran/ctfdevmod.f | 241 + include/fortran/ctkineticsmod.f | 205 + include/fortran/ctmixturemod.f | 1874 +++++ include/fortran/ctmod.f | 582 ++ include/fortran/ctreactormod.f | 468 ++ include/fortran/ctthermomod.f | 12 + include/fortran/cttransportmod.f | 108 + include/fortran/ctutilsmod.f | 57 + include/ftn_defs.h | 20 + include/integrators.h | 6 + include/kinetics.h | 320 + include/numerics.h | 7 + include/onedim.h | 10 + include/surface.h | 7 + include/transport.h | 5 + lib/README | 1 + test_problems/.cvsignore | 1 + test_problems/Makefile.in | 19 + test_problems/cxx_ex/.cvsignore | 26 + test_problems/cxx_ex/Makefile.in | 14 + test_problems/cxx_ex/eq1_blessed.csv | 52 + test_problems/cxx_ex/eq1_blessed.dat | 71 + test_problems/cxx_ex/gri30.inp | 661 ++ test_problems/cxx_ex/gri30.xml | 4877 ++++++++++++ test_problems/cxx_ex/gri30_tran.dat | 110 + test_problems/cxx_ex/gri30mod.inp | 692 ++ test_problems/cxx_ex/kin1_blessed.csv | 103 + test_problems/cxx_ex/kin2_blessed.csv | 103 + test_problems/cxx_ex/runtest | 121 + test_problems/cxx_ex/silane.inp | 108 + test_problems/cxx_ex/silane.xml | 480 ++ test_problems/cxx_ex/tr1_blessed.csv | 22 + test_problems/cxx_ex/tr2_blessed.csv | 22 + test_problems/silane_equil/.cvsignore | 4 + test_problems/silane_equil/Makefile.in | 82 + test_problems/silane_equil/output_blessed.txt | 32 + test_problems/silane_equil/runtest | 32 + test_problems/silane_equil/silane.xml | 480 ++ test_problems/silane_equil/silane_equil.cpp | 28 + tools/.cvsignore | 2 + tools/Makefile.in | 22 + tools/bin/ctupdate.py | 758 ++ tools/bin/finish_install.py | 48 + tools/export | 17 + tools/src/.cvsignore | 2 + tools/src/Makefile.in | 40 + tools/src/ck2ctml.cpp | 77 + tools/src/ck2ctml.dsp | 108 + tools/src/ctlibsample.mak.in | 82 + tools/src/ctsetup.cpp | 228 + tools/src/ctsetup.in | 38 + tools/src/ctwin | 80 + tools/src/makedsp.cpp | 81 + tools/src/newdsp.cpp | 140 + tools/src/proto.dsp | 103 + tools/src/protocvf.dsp | 103 + tools/src/protocxx.cpp | 13 + tools/src/protocxx.dsp | 108 + tools/src/sample.mak.in | 96 + tools/src/sample_f90.mak.in | 90 + tools/src/validate.cpp | 45 + tools/templates/f77/demo.f | 24 + tools/templates/f77/demo_ftnlib.cpp | 190 + tools/templates/f77/sample.mak.in | 99 + tools/testtools/.cvsignore | 4 + tools/testtools/Makefile.in | 42 + tools/testtools/csvdiff.cpp | 723 ++ tools/testtools/mdp_allo.cpp | 1454 ++++ tools/testtools/mdp_allo.h | 101 + tools/testtools/tok_input_util.cpp | 1570 ++++ tools/testtools/tok_input_util.h | 113 + 925 files changed, 158956 insertions(+) create mode 100644 .cvsignore create mode 100644 Cantera/.cvsignore create mode 100755 Cantera/Makefile.in create mode 100644 Cantera/clib/src/.cvsignore create mode 100755 Cantera/clib/src/Cabinet.h create mode 100755 Cantera/clib/src/Makefile.in create mode 100755 Cantera/clib/src/Storage.cpp create mode 100755 Cantera/clib/src/Storage.h create mode 100755 Cantera/clib/src/clib_defs.h create mode 100755 Cantera/clib/src/ct.cpp create mode 100755 Cantera/clib/src/ct.h create mode 100755 Cantera/clib/src/ctbdry.cpp create mode 100755 Cantera/clib/src/ctbdry.h create mode 100755 Cantera/clib/src/ctfunc.cpp create mode 100755 Cantera/clib/src/ctfunc.h create mode 100755 Cantera/clib/src/ctnum.cpp create mode 100755 Cantera/clib/src/ctnum.h create mode 100755 Cantera/clib/src/ctreactor.cpp create mode 100755 Cantera/clib/src/ctreactor.h create mode 100755 Cantera/clib/src/ctrpath.cpp create mode 100755 Cantera/clib/src/ctrpath.h create mode 100755 Cantera/clib/src/ctstagn.cpp create mode 100755 Cantera/clib/src/ctstagn.h create mode 100755 Cantera/clib/src/ctsurf.cpp create mode 100755 Cantera/clib/src/ctsurf.h create mode 100644 Cantera/clib/src/ctxml.cpp create mode 100644 Cantera/clib/src/ctxml.h create mode 100644 Cantera/cxx/README create mode 100755 Cantera/lib/README create mode 100644 Cantera/matlab/Makefile.in create mode 100644 Cantera/matlab/cantera/@FlowDevice/FlowDevice.m create mode 100644 Cantera/matlab/cantera/@FlowDevice/clear.m create mode 100644 Cantera/matlab/cantera/@FlowDevice/install.m create mode 100644 Cantera/matlab/cantera/@FlowDevice/massFlowRate.m create mode 100644 Cantera/matlab/cantera/@FlowDevice/private/flowdevicemethods.m create mode 100644 Cantera/matlab/cantera/@FlowDevice/setMassFlowRate.m create mode 100644 Cantera/matlab/cantera/@FlowDevice/setValveCoeff.m create mode 100755 Cantera/matlab/cantera/@Kinetics/Kinetics.m create mode 100644 Cantera/matlab/cantera/@Kinetics/clear.m create mode 100755 Cantera/matlab/cantera/@Kinetics/creationRates.m create mode 100755 Cantera/matlab/cantera/@Kinetics/destructionRates.m create mode 100755 Cantera/matlab/cantera/@Kinetics/destruction_rates.m create mode 100755 Cantera/matlab/cantera/@Kinetics/equil_Kc.m create mode 100755 Cantera/matlab/cantera/@Kinetics/hndl.m create mode 100755 Cantera/matlab/cantera/@Kinetics/isReversible.m create mode 100644 Cantera/matlab/cantera/@Kinetics/kinetics_hndl.m create mode 100755 Cantera/matlab/cantera/@Kinetics/multiplier.m create mode 100755 Cantera/matlab/cantera/@Kinetics/nReactions.m create mode 100644 Cantera/matlab/cantera/@Kinetics/nTotalSpecies.m create mode 100755 Cantera/matlab/cantera/@Kinetics/netProdRates.m create mode 100644 Cantera/matlab/cantera/@Kinetics/private/delkinetics.cpp create mode 100755 Cantera/matlab/cantera/@Kinetics/private/isrev.cpp create mode 100755 Cantera/matlab/cantera/@Kinetics/private/kin_get.cpp create mode 100755 Cantera/matlab/cantera/@Kinetics/private/kin_set.cpp create mode 100644 Cantera/matlab/cantera/@Kinetics/private/kinetics_get.m create mode 100644 Cantera/matlab/cantera/@Kinetics/private/kinetics_set.m create mode 100755 Cantera/matlab/cantera/@Kinetics/private/newkinetics.cpp create mode 100755 Cantera/matlab/cantera/@Kinetics/private/production.cpp create mode 100755 Cantera/matlab/cantera/@Kinetics/private/pstoich.cpp create mode 100755 Cantera/matlab/cantera/@Kinetics/private/rop.cpp create mode 100755 Cantera/matlab/cantera/@Kinetics/private/rstoich.cpp create mode 100755 Cantera/matlab/cantera/@Kinetics/private/rxnstring.cpp create mode 100755 Cantera/matlab/cantera/@Kinetics/reactionEqn.m create mode 100644 Cantera/matlab/cantera/@Kinetics/rop.m create mode 100755 Cantera/matlab/cantera/@Kinetics/rop_f.m create mode 100755 Cantera/matlab/cantera/@Kinetics/rop_net.m create mode 100755 Cantera/matlab/cantera/@Kinetics/rop_r.m create mode 100755 Cantera/matlab/cantera/@Kinetics/rxnEqs.m create mode 100755 Cantera/matlab/cantera/@Kinetics/setMultiplier.m create mode 100755 Cantera/matlab/cantera/@Kinetics/stoich_net.m create mode 100755 Cantera/matlab/cantera/@Kinetics/stoich_p.m create mode 100755 Cantera/matlab/cantera/@Kinetics/stoich_r.m create mode 100755 Cantera/matlab/cantera/@Kinetics/ydot.m create mode 100644 Cantera/matlab/cantera/@Reactor/Reactor.m create mode 100644 Cantera/matlab/cantera/@Reactor/advance.m create mode 100644 Cantera/matlab/cantera/@Reactor/clear.m create mode 100644 Cantera/matlab/cantera/@Reactor/density.m create mode 100644 Cantera/matlab/cantera/@Reactor/enthalpy_mass.m create mode 100644 Cantera/matlab/cantera/@Reactor/hndl.m create mode 100644 Cantera/matlab/cantera/@Reactor/insert.m create mode 100644 Cantera/matlab/cantera/@Reactor/intEnergy_mass.m create mode 100644 Cantera/matlab/cantera/@Reactor/mass.m create mode 100644 Cantera/matlab/cantera/@Reactor/massFraction.m create mode 100644 Cantera/matlab/cantera/@Reactor/massFractions.m create mode 100644 Cantera/matlab/cantera/@Reactor/pressure.m create mode 100644 Cantera/matlab/cantera/@Reactor/private/reactormethods.cpp create mode 100644 Cantera/matlab/cantera/@Reactor/private/reactormethods.m create mode 100644 Cantera/matlab/cantera/@Reactor/reactor_hndl.m create mode 100644 Cantera/matlab/cantera/@Reactor/setEnergy.m create mode 100644 Cantera/matlab/cantera/@Reactor/setInitialTime.m create mode 100644 Cantera/matlab/cantera/@Reactor/setInitialVolume.m create mode 100644 Cantera/matlab/cantera/@Reactor/setKineticsMgr.m create mode 100644 Cantera/matlab/cantera/@Reactor/setThermoMgr.m create mode 100644 Cantera/matlab/cantera/@Reactor/step.m create mode 100644 Cantera/matlab/cantera/@Reactor/temperature.m create mode 100644 Cantera/matlab/cantera/@Reactor/time.m create mode 100644 Cantera/matlab/cantera/@Reactor/volume.m create mode 100755 Cantera/matlab/cantera/@Solution/Solution.m create mode 100644 Cantera/matlab/cantera/@Solution/clear.m create mode 100755 Cantera/matlab/cantera/@Solution/display.m create mode 100755 Cantera/matlab/cantera/@Solution/set.m create mode 100755 Cantera/matlab/cantera/@Solution/soundspeed.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/ThermoPhase.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/atomicMasses.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/chemPotentials.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/clear.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/cp_R.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/cp_mass.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/cp_mole.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/cv_mass.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/cv_mole.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/density.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/elementIndex.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/elementName.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/enthalpies_RT.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/enthalpy_mass.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/enthalpy_mole.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/entropies_R.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/entropy_mass.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/entropy_mole.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/eosType.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/equilibrate.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/gibbs_RT.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/gibbs_mass.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/gibbs_mole.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/hndl.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/intEnergy_mass.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/intEnergy_mole.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/isIdealGas.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/massFractions.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/maxTemp.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/meanMolarMass.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/meanMolecularWeight.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/minTemp.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/molarDensity.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/molarMasses.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/moleFractions.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/molecularWeights.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/nAtoms.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/nElements.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/nSpecies.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/ph.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/pressure.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/private/phase_get.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/private/phase_set.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/private/thermo_get.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/private/thermo_set.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/refPressure.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/set.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/setDensity.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/setMassFractions.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/setMoleFractions.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/setPressure.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/setState.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/setState_HP.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/setState_SP.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/setState_UV.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/setTemperature.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/speciesIndex.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/speciesName.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/speciesNames.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/temperature.m create mode 100644 Cantera/matlab/cantera/@ThermoPhase/thermo_hndl.m create mode 100755 Cantera/matlab/cantera/@Transport/Transport.m create mode 100755 Cantera/matlab/cantera/@Transport/binDiffCoeffs.m create mode 100755 Cantera/matlab/cantera/@Transport/hndl.m create mode 100755 Cantera/matlab/cantera/@Transport/mixDiffCoeffs.m create mode 100755 Cantera/matlab/cantera/@Transport/multiDiffCoeffs.m create mode 100755 Cantera/matlab/cantera/@Transport/private/newTransport.cpp create mode 100644 Cantera/matlab/cantera/@Transport/private/trans_get.m create mode 100755 Cantera/matlab/cantera/@Transport/private/trans_methods.cpp create mode 100755 Cantera/matlab/cantera/@Transport/thermalConductivity.m create mode 100755 Cantera/matlab/cantera/@Transport/thermalDiffCoeffs.m create mode 100755 Cantera/matlab/cantera/@Transport/viscosity.m create mode 100644 Cantera/matlab/cantera/@Wall/Wall.m create mode 100644 Cantera/matlab/cantera/@Wall/area.m create mode 100644 Cantera/matlab/cantera/@Wall/install.m create mode 100644 Cantera/matlab/cantera/@Wall/private/wallmethods.cpp create mode 100644 Cantera/matlab/cantera/@Wall/private/wallmethods.m create mode 100644 Cantera/matlab/cantera/@Wall/ready.m create mode 100644 Cantera/matlab/cantera/@Wall/setArea.m create mode 100644 Cantera/matlab/cantera/@Wall/setExpansionRateCoeff.m create mode 100644 Cantera/matlab/cantera/@Wall/setHeatTransferCoeff.m create mode 100644 Cantera/matlab/cantera/@Wall/setThermalResistance.m create mode 100644 Cantera/matlab/cantera/@Wall/wall_hndl.m create mode 100644 Cantera/matlab/cantera/@XML_Node/XML_Node.m create mode 100644 Cantera/matlab/cantera/@XML_Node/attrib.m create mode 100644 Cantera/matlab/cantera/@XML_Node/build.m create mode 100644 Cantera/matlab/cantera/@XML_Node/child.m create mode 100644 Cantera/matlab/cantera/@XML_Node/hndl.m create mode 100644 Cantera/matlab/cantera/@XML_Node/private/newxml.cpp create mode 100644 Cantera/matlab/cantera/@XML_Node/private/xmlmethods.cpp create mode 100644 Cantera/matlab/cantera/@XML_Node/value.m create mode 100644 Cantera/matlab/cantera/@XML_Node/write.m create mode 100755 Cantera/matlab/cantera/Contents.m create mode 100755 Cantera/matlab/cantera/GRI30.m create mode 100755 Cantera/matlab/cantera/IdealGasMix.m create mode 100644 Cantera/matlab/cantera/MassFlowController.m create mode 100644 Cantera/matlab/cantera/Reservoir.m create mode 100644 Cantera/matlab/cantera/Valve.m create mode 100755 Cantera/matlab/cantera/adddir.m create mode 100755 Cantera/matlab/cantera/air.m create mode 100755 Cantera/matlab/cantera/build.m create mode 100755 Cantera/matlab/cantera/buildux.m create mode 100755 Cantera/matlab/cantera/buildwin.m create mode 100644 Cantera/matlab/cantera/ck2ctml.m create mode 100755 Cantera/matlab/cantera/conhp.m create mode 100755 Cantera/matlab/cantera/constants.m create mode 100755 Cantera/matlab/cantera/conuv.m create mode 100755 Cantera/matlab/cantera/examples/equil.m create mode 100755 Cantera/matlab/cantera/examples/ignite.m create mode 100755 Cantera/matlab/cantera/examples/ignite2.m create mode 100755 Cantera/matlab/cantera/examples/ignite3.m create mode 100755 Cantera/matlab/cantera/examples/ignite_hp.m create mode 100755 Cantera/matlab/cantera/examples/ignite_uv.m create mode 100755 Cantera/matlab/cantera/examples/isentropic.m create mode 100644 Cantera/matlab/cantera/examples/periodic_cstr.m create mode 100755 Cantera/matlab/cantera/examples/prandtl1.m create mode 100755 Cantera/matlab/cantera/examples/prandtl2.m create mode 100644 Cantera/matlab/cantera/examples/reactor1.m create mode 100644 Cantera/matlab/cantera/examples/reactor2.m create mode 100755 Cantera/matlab/cantera/examples/run_examples.m create mode 100755 Cantera/matlab/cantera/examples/transport1.m create mode 100755 Cantera/matlab/cantera/gasconstant.m create mode 100755 Cantera/matlab/cantera/geterr.m create mode 100644 Cantera/matlab/cantera/mexopts.sh create mode 100755 Cantera/matlab/cantera/oneatm.m create mode 100644 Cantera/matlab/cantera/private/ctfunctions.cpp create mode 100755 Cantera/matlab/cantera/private/ctmatutils.h create mode 100644 Cantera/matlab/cantera/private/ctmethods.cpp create mode 100644 Cantera/matlab/cantera/private/flowdevicemethods.cpp create mode 100755 Cantera/matlab/cantera/private/importFromFile.m create mode 100644 Cantera/matlab/cantera/private/kineticsmethods.cpp create mode 100644 Cantera/matlab/cantera/private/phasemethods.cpp create mode 100644 Cantera/matlab/cantera/private/reactormethods.cpp create mode 100644 Cantera/matlab/cantera/private/thermomethods.cpp create mode 100644 Cantera/matlab/cantera/private/transportmethods.cpp create mode 100644 Cantera/matlab/cantera/private/wallmethods.cpp create mode 100644 Cantera/matlab/cantera/private/xmlmethods.cpp create mode 100644 Cantera/matlab/cantera/reactor_ode.m create mode 100755 Cantera/matlab/cantera/tutorial/README create mode 100755 Cantera/matlab/cantera/tutorial/tut1.m create mode 100755 Cantera/matlab/cantera/tutorial/tut2.m create mode 100755 Cantera/matlab/cantera/tutorial/tut3.m create mode 100755 Cantera/matlab/cantera/tutorial/tut4.m create mode 100755 Cantera/matlab/cantera/tutorial/tut5.m create mode 100755 Cantera/matlab/cantera/tutorial/tut6.m create mode 100755 Cantera/matlab/cantera/tutorial/tut7.m create mode 100644 Cantera/matlab/setup_matlab.py create mode 100644 Cantera/python/.cvsignore create mode 100755 Cantera/python/Cantera/Flow.py create mode 100755 Cantera/python/Cantera/FlowBoundary.py create mode 100755 Cantera/python/Cantera/FlowPlotter.py create mode 100644 Cantera/python/Cantera/Func.py create mode 100644 Cantera/python/Cantera/Interface.py create mode 100755 Cantera/python/Cantera/Kinetics.py create mode 100755 Cantera/python/Cantera/OneDim.py create mode 100755 Cantera/python/Cantera/Phase.py create mode 100644 Cantera/python/Cantera/Reactor.py create mode 100755 Cantera/python/Cantera/SurfWriter.py create mode 100644 Cantera/python/Cantera/SurfacePhase.py create mode 100755 Cantera/python/Cantera/Thermo.py create mode 100644 Cantera/python/Cantera/ThermoPhase.py create mode 100755 Cantera/python/Cantera/Transport.py create mode 100644 Cantera/python/Cantera/XML.py create mode 100755 Cantera/python/Cantera/__init__.py create mode 100755 Cantera/python/Cantera/boundaries1D.py create mode 100644 Cantera/python/Cantera/ck2ctml.py create mode 100755 Cantera/python/Cantera/constants.py create mode 100755 Cantera/python/Cantera/elements.py create mode 100755 Cantera/python/Cantera/excel.py create mode 100755 Cantera/python/Cantera/exceptions.py create mode 100755 Cantera/python/Cantera/flame.py create mode 100755 Cantera/python/Cantera/gases.py create mode 100755 Cantera/python/Cantera/importFromFile.py create mode 100755 Cantera/python/Cantera/interp.py create mode 100755 Cantera/python/Cantera/refine.py create mode 100755 Cantera/python/Cantera/rxnpath.py create mode 100755 Cantera/python/Cantera/schem.py create mode 100755 Cantera/python/Cantera/set.py create mode 100755 Cantera/python/Cantera/solids.py create mode 100755 Cantera/python/Cantera/solution.py create mode 100755 Cantera/python/Cantera/solve.py create mode 100755 Cantera/python/Cantera/stoich.py create mode 100755 Cantera/python/Cantera/tecplot.py create mode 100755 Cantera/python/Cantera/units.py create mode 100755 Cantera/python/Makefile.in create mode 100755 Cantera/python/examples/flame1.py create mode 100755 Cantera/python/examples/flame2.py create mode 100755 Cantera/python/examples/isentropic.py create mode 100644 Cantera/python/examples/reactor1.py create mode 100644 Cantera/python/examples/reactor2.py create mode 100755 Cantera/python/examples/rxnpath1.py create mode 100755 Cantera/python/examples/rxnpath2.py create mode 100644 Cantera/python/examples/stflame1.py create mode 100644 Cantera/python/examples/stflame2.py create mode 100755 Cantera/python/setup.py create mode 100644 Cantera/python/src/.cvsignore create mode 100755 Cantera/python/src/Makefile.in create mode 100755 Cantera/python/src/cantera.def create mode 100755 Cantera/python/src/canteramodule.cpp create mode 100755 Cantera/python/src/ct.def create mode 100644 Cantera/python/src/ctbndry_methods.cpp create mode 100755 Cantera/python/src/ctflow.cpp create mode 100755 Cantera/python/src/ctflow.def create mode 100644 Cantera/python/src/ctflow_methods.cpp create mode 100644 Cantera/python/src/ctfunc_methods.cpp create mode 100644 Cantera/python/src/ctfuncs.cpp create mode 100755 Cantera/python/src/ctkinetics.cpp create mode 100755 Cantera/python/src/ctkinetics.def create mode 100644 Cantera/python/src/ctkinetics_methods.cpp create mode 100755 Cantera/python/src/ctmodule.cpp create mode 100755 Cantera/python/src/ctnumerics.cpp create mode 100755 Cantera/python/src/ctnumerics.def create mode 100755 Cantera/python/src/ctphase.cpp create mode 100755 Cantera/python/src/ctphase.def create mode 100644 Cantera/python/src/ctphase_methods.cpp create mode 100755 Cantera/python/src/ctpy.cpp create mode 100755 Cantera/python/src/ctpybndry.cpp create mode 100644 Cantera/python/src/ctpyfunc.cpp create mode 100755 Cantera/python/src/ctpyreactor.cpp create mode 100755 Cantera/python/src/ctpyrpath.cpp create mode 100755 Cantera/python/src/ctpysurf.cpp create mode 100644 Cantera/python/src/ctpyxml.cpp create mode 100644 Cantera/python/src/ctreactor_methods.cpp create mode 100644 Cantera/python/src/ctrpath_methods.cpp create mode 100755 Cantera/python/src/ctsurf.cpp create mode 100755 Cantera/python/src/ctsurf.def create mode 100644 Cantera/python/src/ctsurf_methods.cpp create mode 100755 Cantera/python/src/ctthermo.cpp create mode 100755 Cantera/python/src/ctthermo.def create mode 100644 Cantera/python/src/ctthermo_methods.cpp create mode 100755 Cantera/python/src/cttransport.cpp create mode 100755 Cantera/python/src/cttransport.def create mode 100644 Cantera/python/src/cttransport_methods.cpp create mode 100644 Cantera/python/src/ctxml_methods.cpp create mode 100644 Cantera/python/src/methods.h create mode 100644 Cantera/python/src/pycantera.cpp create mode 100755 Cantera/python/src/pyutils.h create mode 100755 Cantera/python/src/reactionpath.cpp create mode 100755 Cantera/python/tutorial/tut1.py create mode 100755 Cantera/python/tutorial/tut2.py create mode 100755 Cantera/python/tutorial/tut4.py create mode 100644 Cantera/src/.cvsignore create mode 100755 Cantera/src/Array.h create mode 100755 Cantera/src/ArrayViewer.h create mode 100755 Cantera/src/BandMatrix.cpp create mode 100755 Cantera/src/BandMatrix.h create mode 100755 Cantera/src/CVode.cpp create mode 100755 Cantera/src/CVode.h create mode 100755 Cantera/src/ChemEquil.cpp create mode 100755 Cantera/src/ChemEquil.h create mode 100755 Cantera/src/ConstDensityThermo.cpp create mode 100755 Cantera/src/ConstDensityThermo.h create mode 100755 Cantera/src/Constituents.cpp create mode 100755 Cantera/src/Constituents.h create mode 100755 Cantera/src/DASPK.cpp create mode 100755 Cantera/src/DASPK.h create mode 100755 Cantera/src/DenseMatrix.cpp create mode 100755 Cantera/src/DenseMatrix.h create mode 100755 Cantera/src/EOS_TPX.h create mode 100644 Cantera/src/Elements.cpp create mode 100644 Cantera/src/Elements.h create mode 100755 Cantera/src/Enhanced3BConc.h create mode 100755 Cantera/src/FILES create mode 100755 Cantera/src/FalloffFactory.cpp create mode 100755 Cantera/src/FalloffFactory.h create mode 100755 Cantera/src/FalloffMgr.h create mode 100755 Cantera/src/Flow1D.h create mode 100755 Cantera/src/FtnODESys.h create mode 100644 Cantera/src/Func1.h create mode 100755 Cantera/src/FuncEval.h create mode 100755 Cantera/src/GRI30.h create mode 100755 Cantera/src/GRI_30_Kinetics.cpp create mode 100755 Cantera/src/GRI_30_Kinetics.h create mode 100755 Cantera/src/GasKinetics.cpp create mode 100755 Cantera/src/GasKinetics.h create mode 100755 Cantera/src/GasKineticsWriter.cpp create mode 100755 Cantera/src/GasKineticsWriter.h create mode 100755 Cantera/src/Group.cpp create mode 100755 Cantera/src/Group.h create mode 100644 Cantera/src/IdealGasPhase.cpp create mode 100644 Cantera/src/IdealGasPhase.h create mode 100755 Cantera/src/IdealGasThermo.cpp create mode 100755 Cantera/src/IdealGasThermo.h create mode 100755 Cantera/src/ImplicitChem.cpp create mode 100755 Cantera/src/ImplicitChem.h create mode 100755 Cantera/src/ImplicitSurfChem.cpp create mode 100755 Cantera/src/ImplicitSurfChem.h create mode 100755 Cantera/src/IncompressibleThermo.h create mode 100755 Cantera/src/Integrator.h create mode 100644 Cantera/src/InterfaceKinetics.cpp create mode 100644 Cantera/src/InterfaceKinetics.h create mode 100755 Cantera/src/Jac2.h create mode 100755 Cantera/src/Kinetics.h create mode 100644 Cantera/src/KineticsFactory.cpp create mode 100644 Cantera/src/KineticsFactory.h create mode 100755 Cantera/src/L_matrix.h create mode 100755 Cantera/src/MMCollisionInt.cpp create mode 100755 Cantera/src/Makefile.in create mode 100755 Cantera/src/MixTransport.cpp create mode 100755 Cantera/src/MultiDomain.h create mode 100755 Cantera/src/NasaPoly1.h create mode 100755 Cantera/src/NasaThermo.h create mode 100755 Cantera/src/Newton.h create mode 100755 Cantera/src/Phase.cpp create mode 100755 Cantera/src/Phase.h create mode 100755 Cantera/src/PolyThermo.h create mode 100755 Cantera/src/PolyThermoMgr.h create mode 100755 Cantera/src/PropertyCalculator.h create mode 100755 Cantera/src/PropertyUpdater.h create mode 100755 Cantera/src/RateCoeffMgr.h create mode 100755 Cantera/src/ReactionData.h create mode 100755 Cantera/src/ReactionPath.cpp create mode 100755 Cantera/src/ReactionPath.h create mode 100755 Cantera/src/Resid.h create mode 100755 Cantera/src/Resid1D.h create mode 100755 Cantera/src/ResidEval.h create mode 100755 Cantera/src/RxnRates.h create mode 100755 Cantera/src/ShomatePoly.h create mode 100755 Cantera/src/ShomateThermo.h create mode 100644 Cantera/src/SimpleThermo.h create mode 100755 Cantera/src/SpeciesThermo.h create mode 100755 Cantera/src/SpeciesThermoFactory.cpp create mode 100755 Cantera/src/SpeciesThermoFactory.h create mode 100755 Cantera/src/SpeciesThermoMgr.h create mode 100755 Cantera/src/State.h create mode 100755 Cantera/src/StoichManager.h create mode 100755 Cantera/src/Surf1D.h create mode 100644 Cantera/src/SurfPhase.h create mode 100755 Cantera/src/Thermo.h create mode 100644 Cantera/src/ThermoFactory.cpp create mode 100644 Cantera/src/ThermoFactory.h create mode 100644 Cantera/src/ThermoPhase.cpp create mode 100755 Cantera/src/ThermoPhase.h create mode 100755 Cantera/src/ThirdBodyMgr.h create mode 100755 Cantera/src/TigerPolynomial.h create mode 100755 Cantera/src/config.h create mode 100644 Cantera/src/converters/.cvsignore create mode 100755 Cantera/src/converters/CKParser.cpp create mode 100755 Cantera/src/converters/CKParser.h create mode 100755 Cantera/src/converters/CKReader.cpp create mode 100755 Cantera/src/converters/CKReader.h create mode 100755 Cantera/src/converters/Constituent.h create mode 100755 Cantera/src/converters/Element.h create mode 100755 Cantera/src/converters/Group.h create mode 100644 Cantera/src/converters/Makefile.in create mode 100755 Cantera/src/converters/Reaction.cpp create mode 100755 Cantera/src/converters/Reaction.h create mode 100755 Cantera/src/converters/RxnSpecies.h create mode 100755 Cantera/src/converters/Species.h create mode 100755 Cantera/src/converters/atomicWeightDB.cpp create mode 100755 Cantera/src/converters/ck2ctml.cpp create mode 100755 Cantera/src/converters/ck2ctml.h create mode 100755 Cantera/src/converters/ckr_defs.h create mode 100755 Cantera/src/converters/ckr_utils.cpp create mode 100755 Cantera/src/converters/ckr_utils.h create mode 100755 Cantera/src/converters/config.h create mode 100755 Cantera/src/converters/filter.cpp create mode 100755 Cantera/src/converters/thermoFunctions.cpp create mode 100755 Cantera/src/converters/thermoFunctions.h create mode 100755 Cantera/src/converters/writelog.cpp create mode 100755 Cantera/src/converters/writelog.h create mode 100755 Cantera/src/ct_defs.h create mode 100755 Cantera/src/ctexceptions.h create mode 100755 Cantera/src/ctlapack.h create mode 100755 Cantera/src/ctml.cpp create mode 100755 Cantera/src/ctml.h create mode 100755 Cantera/src/ctvector.cpp create mode 100755 Cantera/src/ctvector.h create mode 100755 Cantera/src/exceptions.h create mode 100755 Cantera/src/fitPoly.h create mode 100755 Cantera/src/flowBoundaries.h create mode 100755 Cantera/src/funcs.cpp create mode 100755 Cantera/src/gases.h create mode 100755 Cantera/src/global.h create mode 100755 Cantera/src/import.h create mode 100755 Cantera/src/importCTML.cpp create mode 100755 Cantera/src/importCTML.h create mode 100755 Cantera/src/importSurfChem.cpp create mode 100755 Cantera/src/importXML.h create mode 100755 Cantera/src/lapack.h create mode 100755 Cantera/src/misc.cpp create mode 100755 Cantera/src/mix_defs.h create mode 100755 Cantera/src/mix_utils.h create mode 100755 Cantera/src/newton_utils.cpp create mode 100644 Cantera/src/oneD/.cvsignore create mode 100644 Cantera/src/oneD/Inlet1D.h create mode 100644 Cantera/src/oneD/Jac1D.h create mode 100644 Cantera/src/oneD/Makefile.in create mode 100644 Cantera/src/oneD/MultiJac.cpp create mode 100644 Cantera/src/oneD/MultiJac.h create mode 100644 Cantera/src/oneD/MultiNewton.cpp create mode 100644 Cantera/src/oneD/MultiNewton.h create mode 100644 Cantera/src/oneD/Newton1D.h create mode 100644 Cantera/src/oneD/OneDim.cpp create mode 100644 Cantera/src/oneD/OneDim.h create mode 100644 Cantera/src/oneD/Resid1D.h create mode 100644 Cantera/src/oneD/StFlow.cpp create mode 100644 Cantera/src/oneD/StFlow.h create mode 100644 Cantera/src/oneD/Surf1D.h create mode 100644 Cantera/src/oneD/newton_utils.cpp create mode 100755 Cantera/src/plots.cpp create mode 100755 Cantera/src/plots.h create mode 100755 Cantera/src/polyfit.h create mode 100755 Cantera/src/pureSubstances.h create mode 100755 Cantera/src/reaction_defs.h create mode 100755 Cantera/src/recipes.h create mode 100755 Cantera/src/sort.cpp create mode 100755 Cantera/src/sort.h create mode 100755 Cantera/src/speciesThermoTypes.h create mode 100755 Cantera/src/stringUtils.cpp create mode 100755 Cantera/src/stringUtils.h create mode 100755 Cantera/src/surfKinetics.cpp create mode 100755 Cantera/src/surfKinetics.h create mode 100755 Cantera/src/surfacePhase.h create mode 100644 Cantera/src/transport/.cvsignore create mode 100755 Cantera/src/transport/FtnTransport.h create mode 100755 Cantera/src/transport/MMCollisionInt.cpp create mode 100755 Cantera/src/transport/MMCollisionInt.h create mode 100644 Cantera/src/transport/Makefile.in create mode 100755 Cantera/src/transport/MixTransport.cpp create mode 100755 Cantera/src/transport/MixTransport.h create mode 100755 Cantera/src/transport/MultiTransport.cpp create mode 100755 Cantera/src/transport/MultiTransport.h create mode 100755 Cantera/src/transport/TransportBase.h create mode 100755 Cantera/src/transport/TransportFactory.cpp create mode 100755 Cantera/src/transport/TransportFactory.h create mode 100755 Cantera/src/transport/TransportParams.h create mode 100755 Cantera/src/transportModels.h create mode 100644 Cantera/src/units.h create mode 100755 Cantera/src/updaters.h create mode 100755 Cantera/src/utilities.h create mode 100755 Cantera/src/vec_functions.h create mode 100755 Cantera/src/xml.cpp create mode 100755 Cantera/src/xml.h create mode 100644 Cantera/src/zeroD/.cvsignore create mode 100644 Cantera/src/zeroD/FlowDevice.cpp create mode 100644 Cantera/src/zeroD/FlowDevice.h create mode 100644 Cantera/src/zeroD/Makefile.in create mode 100644 Cantera/src/zeroD/PID_Controller.h create mode 100644 Cantera/src/zeroD/Reactor.cpp create mode 100644 Cantera/src/zeroD/Reactor.h create mode 100644 Cantera/src/zeroD/ReactorBase.cpp create mode 100644 Cantera/src/zeroD/ReactorBase.h create mode 100644 Cantera/src/zeroD/Reservoir.h create mode 100644 Cantera/src/zeroD/Wall.cpp create mode 100644 Cantera/src/zeroD/Wall.h create mode 100644 Cantera/src/zeroD/flowControllers.h create mode 100644 INSTALLING create mode 100755 License.rtf create mode 100755 License.txt create mode 100755 Makefile.in create mode 100755 README create mode 100644 apps/MixMaster/.cvsignore create mode 100644 apps/MixMaster/CompositionFrame.py create mode 100644 apps/MixMaster/ControlPanel.py create mode 100644 apps/MixMaster/DataFrame.py create mode 100644 apps/MixMaster/DataGraph.py create mode 100644 apps/MixMaster/Edit.py create mode 100644 apps/MixMaster/ElementFrame.py create mode 100644 apps/MixMaster/GraphFrame.py create mode 100644 apps/MixMaster/ImportFrame.py create mode 100644 apps/MixMaster/KineticsFrame.py create mode 100644 apps/MixMaster/MechManager.py create mode 100644 apps/MixMaster/Mix.py create mode 100644 apps/MixMaster/NewFlowFrame.py create mode 100644 apps/MixMaster/SpeciesFrame.py create mode 100644 apps/MixMaster/SpeciesInfo.py create mode 100644 apps/MixMaster/ThermoFrame.py create mode 100644 apps/MixMaster/ThermoProp.py create mode 100644 apps/MixMaster/TransportFrame.py create mode 100644 apps/MixMaster/UnitChooser.py create mode 100755 apps/MixMaster/Units/SI.py create mode 100755 apps/MixMaster/Units/__init__.py create mode 100755 apps/MixMaster/Units/area.py create mode 100755 apps/MixMaster/Units/density.py create mode 100755 apps/MixMaster/Units/energy.py create mode 100755 apps/MixMaster/Units/force.py create mode 100755 apps/MixMaster/Units/length.py create mode 100755 apps/MixMaster/Units/mass.py create mode 100755 apps/MixMaster/Units/power.py create mode 100755 apps/MixMaster/Units/pressure.py create mode 100755 apps/MixMaster/Units/specificEnergy.py create mode 100755 apps/MixMaster/Units/specificEntropy.py create mode 100755 apps/MixMaster/Units/speed.py create mode 100755 apps/MixMaster/Units/temperature.py create mode 100755 apps/MixMaster/Units/time.py create mode 100755 apps/MixMaster/Units/unit.py create mode 100755 apps/MixMaster/Units/volume.py create mode 100644 apps/MixMaster/__init__.py create mode 100644 apps/MixMaster/config.py create mode 100644 apps/MixMaster/flowpanel.py create mode 100644 apps/MixMaster/gri30.py create mode 100644 apps/MixMaster/main.py create mode 100644 apps/MixMaster/menu.py create mode 100644 apps/MixMaster/newflow.py create mode 100644 apps/MixMaster/utilities.py create mode 100644 apps/README.txt create mode 100644 bin/.cvsignore create mode 100755 bin/README create mode 100755 bin/mixmaster.py create mode 100755 bin/rm_cvsignore create mode 100755 config.h create mode 100755 config.h.in create mode 100644 config/.cvsignore create mode 100755 config/Cantera.README create mode 100755 config/config.guess create mode 100755 config/config.h.in create mode 100755 config/config.sub create mode 100755 config/configure create mode 100755 config/configure.in create mode 100755 config/install-sh create mode 100755 configure create mode 100755 data/README create mode 100644 data/inputs/.cvsignore create mode 100755 data/inputs/Makefile.in create mode 100755 data/inputs/air.inp create mode 100644 data/inputs/air.xml create mode 100644 data/inputs/argon.inp create mode 100644 data/inputs/argon.xml create mode 100644 data/inputs/elements.xml create mode 100644 data/inputs/gases.xml create mode 100755 data/inputs/gri30.inp create mode 100755 data/inputs/gri30.xml create mode 100755 data/inputs/gri30mod.inp create mode 100755 data/inputs/grinc.inp create mode 100755 data/inputs/h2o2.inp create mode 100644 data/inputs/h2o2.xml create mode 100755 data/inputs/h2o2_noch.inp create mode 100755 data/inputs/mkxml create mode 100755 data/inputs/silane.inp create mode 100644 data/inputs/silane.xml create mode 100755 data/thermo/nasathermo.dat create mode 100755 data/transport/gri30_tran.dat create mode 100644 examples/.cvsignore create mode 100755 examples/Makefile.in create mode 100644 examples/cxx/.cvsignore create mode 100755 examples/cxx/Makefile.in create mode 100755 examples/cxx/equil_example1.cpp create mode 100755 examples/cxx/example_utils.h create mode 100755 examples/cxx/examples.cpp create mode 100755 examples/cxx/examples.dsp create mode 100755 examples/cxx/kinetics_example1.cpp create mode 100755 examples/cxx/kinetics_example2.cpp create mode 100755 examples/cxx/rxnpath_example1.cpp create mode 100755 examples/cxx/transport_example1.cpp create mode 100755 examples/cxx/transport_example2.cpp create mode 100644 ext/.cvsignore create mode 100755 ext/Makefile.in create mode 100644 ext/blas/.cvsignore create mode 100755 ext/blas/Makefile.in create mode 100755 ext/blas/dasum.f create mode 100755 ext/blas/daxpy.f create mode 100755 ext/blas/dcabs1.f create mode 100755 ext/blas/dcopy.f create mode 100755 ext/blas/ddot.f create mode 100755 ext/blas/dgbmv.f create mode 100755 ext/blas/dgemm.f create mode 100755 ext/blas/dgemv.f create mode 100755 ext/blas/dger.f create mode 100755 ext/blas/dnrm2.f create mode 100755 ext/blas/drot.f create mode 100755 ext/blas/drotg.f create mode 100755 ext/blas/drotm.f create mode 100755 ext/blas/drotmg.f create mode 100755 ext/blas/dsbmv.f create mode 100755 ext/blas/dscal.f create mode 100755 ext/blas/dsdot.f create mode 100755 ext/blas/dspmv.f create mode 100755 ext/blas/dspr.f create mode 100755 ext/blas/dspr2.f create mode 100755 ext/blas/dswap.f create mode 100755 ext/blas/dsymm.f create mode 100755 ext/blas/dsymv.f create mode 100755 ext/blas/dsyr.f create mode 100755 ext/blas/dsyr2.f create mode 100755 ext/blas/dsyr2k.f create mode 100755 ext/blas/dsyrk.f create mode 100755 ext/blas/dtbmv.f create mode 100755 ext/blas/dtbsv.f create mode 100755 ext/blas/dtpmv.f create mode 100755 ext/blas/dtpsv.f create mode 100755 ext/blas/dtrmm.f create mode 100755 ext/blas/dtrmv.f create mode 100755 ext/blas/dtrsm.f create mode 100755 ext/blas/dtrsv.f create mode 100755 ext/blas/dzasum.f create mode 100755 ext/blas/dznrm2.f create mode 100755 ext/blas/icamax.f create mode 100755 ext/blas/idamax.f create mode 100755 ext/blas/isamax.f create mode 100755 ext/blas/izamax.f create mode 100755 ext/blas/lsame.f create mode 100755 ext/blas/xerbla.f create mode 100644 ext/cvode/.cvsignore create mode 100755 ext/cvode/Makefile.in create mode 100755 ext/cvode/include/band.h create mode 100755 ext/cvode/include/cvband.h create mode 100755 ext/cvode/include/cvbandpre.h create mode 100755 ext/cvode/include/cvdense.h create mode 100755 ext/cvode/include/cvdiag.h create mode 100755 ext/cvode/include/cvode.h create mode 100755 ext/cvode/include/cvspgmr.h create mode 100755 ext/cvode/include/dense.h create mode 100755 ext/cvode/include/iterativ.h create mode 100755 ext/cvode/include/llnlmath.h create mode 100755 ext/cvode/include/llnltyps.h create mode 100755 ext/cvode/include/nvector.h create mode 100755 ext/cvode/include/spgmr.h create mode 100755 ext/cvode/source/band.c create mode 100755 ext/cvode/source/cvband.c create mode 100755 ext/cvode/source/cvbandpre.c create mode 100755 ext/cvode/source/cvdense.c create mode 100755 ext/cvode/source/cvdiag.c create mode 100755 ext/cvode/source/cvode.c create mode 100755 ext/cvode/source/cvspgmr.c create mode 100755 ext/cvode/source/dense.c create mode 100755 ext/cvode/source/iterativ.c create mode 100755 ext/cvode/source/llnlmath.c create mode 100755 ext/cvode/source/nvector.c create mode 100755 ext/cvode/source/spgmr.c create mode 100644 ext/lapack/.cvsignore create mode 100755 ext/lapack/Makefile.in create mode 100755 ext/lapack/dbdsqr.f create mode 100755 ext/lapack/dgbsv.f create mode 100755 ext/lapack/dgbtf2.f create mode 100755 ext/lapack/dgbtrf.f create mode 100755 ext/lapack/dgbtrs.f create mode 100755 ext/lapack/dgebd2.f create mode 100755 ext/lapack/dgebrd.f create mode 100755 ext/lapack/dgelq2.f create mode 100755 ext/lapack/dgelqf.f create mode 100755 ext/lapack/dgelss.f create mode 100755 ext/lapack/dgeqr2.f create mode 100755 ext/lapack/dgeqrf.f create mode 100755 ext/lapack/dgetf2.f create mode 100755 ext/lapack/dgetrf.f create mode 100755 ext/lapack/dgetri.f create mode 100755 ext/lapack/dgetrs.f create mode 100755 ext/lapack/dlabad.f create mode 100755 ext/lapack/dlabrd.f create mode 100755 ext/lapack/dlacpy.f create mode 100755 ext/lapack/dlamch.f create mode 100755 ext/lapack/dlange.f create mode 100755 ext/lapack/dlapy2.f create mode 100755 ext/lapack/dlarf.f create mode 100755 ext/lapack/dlarfb.f create mode 100755 ext/lapack/dlarfg.f create mode 100755 ext/lapack/dlarft.f create mode 100755 ext/lapack/dlartg.f create mode 100755 ext/lapack/dlas2.f create mode 100755 ext/lapack/dlascl.f create mode 100755 ext/lapack/dlaset.f create mode 100755 ext/lapack/dlasq1.f create mode 100755 ext/lapack/dlasq2.f create mode 100755 ext/lapack/dlasq3.f create mode 100755 ext/lapack/dlasq4.f create mode 100755 ext/lapack/dlasr.f create mode 100755 ext/lapack/dlasrt.f create mode 100755 ext/lapack/dlassq.f create mode 100755 ext/lapack/dlasv2.f create mode 100755 ext/lapack/dlaswp.f create mode 100755 ext/lapack/dorg2r.f create mode 100755 ext/lapack/dorgbr.f create mode 100755 ext/lapack/dorgl2.f create mode 100755 ext/lapack/dorglq.f create mode 100755 ext/lapack/dorgqr.f create mode 100755 ext/lapack/dorm2r.f create mode 100755 ext/lapack/dormbr.f create mode 100755 ext/lapack/dorml2.f create mode 100755 ext/lapack/dormlq.f create mode 100755 ext/lapack/dormqr.f create mode 100755 ext/lapack/drscl.f create mode 100755 ext/lapack/ilaenv.f create mode 100755 ext/lapack/lsame.f create mode 100755 ext/lapack/xerbla.f create mode 100644 ext/math/.cvsignore create mode 100755 ext/math/Makefile.in create mode 100755 ext/math/cblas.h create mode 100755 ext/math/daux.f create mode 100755 ext/math/ddaspk.f create mode 100644 ext/math/dgbefa.f create mode 100644 ext/math/dgbsl.f create mode 100644 ext/math/dgefa.f create mode 100644 ext/math/dgesl.f create mode 100644 ext/math/dp1vlu.f create mode 100644 ext/math/dpcoef.f create mode 100644 ext/math/dpolft.f create mode 100644 ext/math/fdump.f create mode 100755 ext/math/gmres.h create mode 100755 ext/math/idamax.f create mode 100644 ext/math/j4save.f create mode 100755 ext/math/mach.cpp create mode 100755 ext/math/mkl_cblas.h create mode 100644 ext/math/pcoef.f create mode 100644 ext/math/polfit.f create mode 100644 ext/math/pvalue.f create mode 100644 ext/math/xercnt.f create mode 100644 ext/math/xerhlt.f create mode 100755 ext/math/xermsg.f create mode 100644 ext/math/xerprn.f create mode 100644 ext/math/xersve.f create mode 100644 ext/math/xgetua.f create mode 100644 ext/recipes/.cvsignore create mode 100755 ext/recipes/Makefile.in create mode 100755 ext/recipes/simp1.f create mode 100755 ext/recipes/simp2.f create mode 100755 ext/recipes/simp3.f create mode 100755 ext/recipes/simplx.f create mode 100755 ext/recipes/splie2.f create mode 100755 ext/recipes/splin2.f create mode 100755 ext/recipes/spline.f create mode 100755 ext/recipes/splint.f create mode 100644 ext/tpx/.cvsignore create mode 100755 ext/tpx/.depends create mode 100755 ext/tpx/CFluid.cpp create mode 100755 ext/tpx/CFluid.h create mode 100755 ext/tpx/CGas.cpp create mode 100755 ext/tpx/CLK.cpp create mode 100755 ext/tpx/CLK.h create mode 100755 ext/tpx/HFC134a.cpp create mode 100755 ext/tpx/HFC134a.h create mode 100755 ext/tpx/Hydrogen.cpp create mode 100755 ext/tpx/Hydrogen.h create mode 100755 ext/tpx/Makefile.in create mode 100755 ext/tpx/Methane.cpp create mode 100755 ext/tpx/Methane.h create mode 100755 ext/tpx/Nitrogen.cpp create mode 100755 ext/tpx/Nitrogen.h create mode 100755 ext/tpx/Oxygen.cpp create mode 100755 ext/tpx/Oxygen.h create mode 100755 ext/tpx/Sub.cpp create mode 100755 ext/tpx/Sub.h create mode 100755 ext/tpx/Water.cpp create mode 100755 ext/tpx/Water.h create mode 100755 ext/tpx/ck_gas.cpp create mode 100755 ext/tpx/ck_gas.h create mode 100755 ext/tpx/ideal.cpp create mode 100755 ext/tpx/lk.cpp create mode 100755 ext/tpx/lk.h create mode 100755 ext/tpx/lkw.cpp create mode 100755 ext/tpx/lkw.h create mode 100755 ext/tpx/mix.h create mode 100755 ext/tpx/subs.h create mode 100755 ext/tpx/utils.cpp create mode 100755 ext/tpx/utils.h create mode 100755 include/Cantera.h create mode 100644 include/IdealGasMix.h create mode 100644 include/README create mode 100755 include/config.h create mode 100644 include/core.h create mode 100755 include/ctml.h create mode 100755 include/equilibrium.h create mode 100755 include/fortran/ctfdevmod.f create mode 100755 include/fortran/ctkineticsmod.f create mode 100755 include/fortran/ctmixturemod.f create mode 100755 include/fortran/ctmod.f create mode 100755 include/fortran/ctreactormod.f create mode 100755 include/fortran/ctthermomod.f create mode 100755 include/fortran/cttransportmod.f create mode 100755 include/fortran/ctutilsmod.f create mode 100755 include/ftn_defs.h create mode 100755 include/integrators.h create mode 100644 include/kinetics.h create mode 100755 include/numerics.h create mode 100755 include/onedim.h create mode 100755 include/surface.h create mode 100755 include/transport.h create mode 100755 lib/README create mode 100644 test_problems/.cvsignore create mode 100644 test_problems/Makefile.in create mode 100644 test_problems/cxx_ex/.cvsignore create mode 100644 test_problems/cxx_ex/Makefile.in create mode 100644 test_problems/cxx_ex/eq1_blessed.csv create mode 100644 test_problems/cxx_ex/eq1_blessed.dat create mode 100644 test_problems/cxx_ex/gri30.inp create mode 100644 test_problems/cxx_ex/gri30.xml create mode 100644 test_problems/cxx_ex/gri30_tran.dat create mode 100644 test_problems/cxx_ex/gri30mod.inp create mode 100644 test_problems/cxx_ex/kin1_blessed.csv create mode 100644 test_problems/cxx_ex/kin2_blessed.csv create mode 100755 test_problems/cxx_ex/runtest create mode 100644 test_problems/cxx_ex/silane.inp create mode 100644 test_problems/cxx_ex/silane.xml create mode 100644 test_problems/cxx_ex/tr1_blessed.csv create mode 100644 test_problems/cxx_ex/tr2_blessed.csv create mode 100644 test_problems/silane_equil/.cvsignore create mode 100644 test_problems/silane_equil/Makefile.in create mode 100644 test_problems/silane_equil/output_blessed.txt create mode 100755 test_problems/silane_equil/runtest create mode 100644 test_problems/silane_equil/silane.xml create mode 100644 test_problems/silane_equil/silane_equil.cpp create mode 100644 tools/.cvsignore create mode 100644 tools/Makefile.in create mode 100644 tools/bin/ctupdate.py create mode 100644 tools/bin/finish_install.py create mode 100755 tools/export create mode 100644 tools/src/.cvsignore create mode 100755 tools/src/Makefile.in create mode 100755 tools/src/ck2ctml.cpp create mode 100755 tools/src/ck2ctml.dsp create mode 100755 tools/src/ctlibsample.mak.in create mode 100755 tools/src/ctsetup.cpp create mode 100755 tools/src/ctsetup.in create mode 100755 tools/src/ctwin create mode 100755 tools/src/makedsp.cpp create mode 100755 tools/src/newdsp.cpp create mode 100755 tools/src/proto.dsp create mode 100755 tools/src/protocvf.dsp create mode 100755 tools/src/protocxx.cpp create mode 100755 tools/src/protocxx.dsp create mode 100755 tools/src/sample.mak.in create mode 100755 tools/src/sample_f90.mak.in create mode 100755 tools/src/validate.cpp create mode 100644 tools/templates/f77/demo.f create mode 100644 tools/templates/f77/demo_ftnlib.cpp create mode 100644 tools/templates/f77/sample.mak.in create mode 100644 tools/testtools/.cvsignore create mode 100644 tools/testtools/Makefile.in create mode 100644 tools/testtools/csvdiff.cpp create mode 100644 tools/testtools/mdp_allo.cpp create mode 100644 tools/testtools/mdp_allo.h create mode 100644 tools/testtools/tok_input_util.cpp create mode 100644 tools/testtools/tok_input_util.h diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 000000000..9c54b9a08 --- /dev/null +++ b/.cvsignore @@ -0,0 +1,3 @@ +Makefile +configure.sol +configure.linux diff --git a/Cantera/.cvsignore b/Cantera/.cvsignore new file mode 100644 index 000000000..f3c7a7c5d --- /dev/null +++ b/Cantera/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/Cantera/Makefile.in b/Cantera/Makefile.in new file mode 100755 index 000000000..3c4ca6eb7 --- /dev/null +++ b/Cantera/Makefile.in @@ -0,0 +1,51 @@ +#/bin/sh +############################################################### +# $Author$ +# $Date$ +# $Revision$ +# +# Copyright 2001 California Institute of Technology +# See file License.txt for licensing information +# +# $Log$ +# Revision 1.1 2003-04-14 17:57:49 dggoodwin +# Initial revision +# +# Revision 1.6 2002/12/16 13:25:57 dgg +# *** empty log message *** +# +# Revision 1.5 2002/08/24 23:25:06 dgg +# *** empty log message *** +# +# Revision 1.4 2002/08/14 07:37:42 dgg +# *** empty log message *** +# +# Revision 1.3 2002/01/12 06:43:42 dgg +# *** empty log message *** +# +############################################################### + +build_f90=@BUILD_F90@ +build_python=@BUILD_PYTHON@ + +all: + cd src; @MAKE@ +ifeq ($(build_f90),1) + cd fortran; @MAKE@ +endif + + +clean: + $(RM) ../lib/libcantera.a + cd src; @MAKE@ clean + cd clib/src; @MAKE@ clean + cd python; @MAKE@ clean + +depends: + cd src; @MAKE@ depends + cd clib/src; @MAKE@ depends + +# end of file + + + diff --git a/Cantera/clib/src/.cvsignore b/Cantera/clib/src/.cvsignore new file mode 100644 index 000000000..57751bad9 --- /dev/null +++ b/Cantera/clib/src/.cvsignore @@ -0,0 +1,2 @@ +Makefile +.depends diff --git a/Cantera/clib/src/Cabinet.h b/Cantera/clib/src/Cabinet.h new file mode 100755 index 000000000..39940ac3f --- /dev/null +++ b/Cantera/clib/src/Cabinet.h @@ -0,0 +1,188 @@ +/** + * @file Cabinet.h + */ + +#ifndef CT_CABINET_H +#define CT_CABINET_H + +#include + +/** + * Template for classes to hold pointers to objects. The Cabinet + * class maintains a list of pointers to objects of class M (or of + * subclasses of M). These classes are used by the 'clib' interface + * library functions that provide access to Cantera C++ objects from + * outside C++. To refer to an existing object, the library functions + * take an integer argument that specifies the location in the pointer + * list maintained by the appropriate Cabinet instance. The pointer + * is retrieved from the list by the interface function, the desired + * method is invoked, and the result returned to the non-C++ calling + * procedure. By storing the pointers in a 'cabinet', there is no need + * to encode them in a string or integer and pass them out to the + * non-C++ calling routine, as some other interfacing schemes do. + * + * The Cabinet class can be used to store pointers to any class + * that is default-constructible (i.e., has a constructor that takes + * no arguments). The requirement that the class be + * default-constructible arises since the Cabinet constructor always + * creates an instance of M by invoking 'new M', and stores a pointer + * to it as the first entry in the list. In most cases, class M is a + * base class with virtual methods, and the base class versions of the + * methods throw CanteraError exceptions. The subclasses overload + * these methods to implement the desired functionality. Class + * Cabinet stores only the base-class pointers, but since the + * methods are virtual, the method of the appropriate subclass will be + * invoked. + * + * The Cabinet class is set up to allow deleting objects in a safe + * manner, *provided* that method 'delete' is used, and the destructor + * for the object is not called directly. Method 'delete' does the + * following. If called with n = 0, it does nothing, since the first + * object in the list (the default-constructed base class instance) is + * never destroyed. If called with n > 0, it deletes the object, and + * replaces the pointer to where the object had been (but is no more) + * with a pointer to the first object. In this way, if it is deleted + * again inadvertently nothing happens, and if an attempt is made to + * reference the object by its index number, the base-class object + * will be referenced instead, which will throw an exception. If + * instead the pointer were stored in the refering code, there would + * always be the chance that + * + * The Cabinet class is implemented as a singlet. The constructor + * is never explicitly called; instead, static function + * Cabinet::cabinet() is called to obtain a pointer to the + * instance. This function calls the constructor on the first call and + * stores the pointer to this instance. Subsequent calls simply return + * the already-created pointer. + */ + +template +class Cabinet { +public: + + /** + * Destructor. Delete all objects in the list. + */ + virtual ~Cabinet() {clear();} + + /** + * Static function that returns a pointer to the one Cabinet + * instance. All access to the Cabinet instance should go + * through this function. + */ + static Cabinet* cabinet() { + if (__storage == 0) { + __storage = new Cabinet; + } + return __storage; + } + + + /** + * Add a new object. The index of the object is returned. + */ + int add(M* ptr) { + //try { + __table.push_back(ptr); + return __table.size() - 1; + //} + //catch (CanteraError) {return -1;} + //catch (...) {return -999;} + } + + + /** + * Make a new copy of an existing object. The index of the new + * object is returned. + */ + int newCopy(int i) { + try { + M* old = __table[i]; + __table.push_back(new M(*old)); + return __table.size() - 1; + } + catch (CanteraError) {return -1;} + catch (...) {return -999;} + } + + + /** + * Assign one object (index j) to another (index i). This method + * is not used currently, and may be removed from the class in the + * future. + */ + int assign(int i, int j) { + try { + M* src = __table[j]; + M* dest = __table[i]; + *dest = *src; + return 0; + } + catch (CanteraError) {return -1;} + catch (...) {return -999;} + } + + + /** + * Delete all objects. + */ + int clear() { + int i, n; + n = __table.size(); + for (i = 1; i < n; i++) {del(i);} + delete __table[0]; + __table = vector(); + return 0; + } + + + /** + * Delete the nth object. After the object is deleted, the pointer + * to it in the list is replaced by a pointer to the first element + * in the list. + */ + void del(int n) { + if (n == 0) return; + if (__table[n] != __table[0]) { + delete __table[n]; + __table[n] = __table[0]; + } + else { + throw CanteraError("Cabinet::del", + "Attempt made to delete an already-deleted object."); + } + } + + + /** + * Return a pointer to object n. + */ + M* item(int n) { + if (n >= 0 && n < int(__table.size())) + return __table[n]; + else { + throw CanteraError("item","index out of range"+int2str(n)); + return __table[0]; + } + } + +private: + + /** + * Constructor. + */ + Cabinet() { add(new M); } + + + /** + * Pointer to the single instance of this class. + */ + static Cabinet* __storage; + + /** + * Vector to hold pointers to objects. + */ + std::vector __table; +}; + +#endif diff --git a/Cantera/clib/src/Makefile.in b/Cantera/clib/src/Makefile.in new file mode 100755 index 000000000..4a8757612 --- /dev/null +++ b/Cantera/clib/src/Makefile.in @@ -0,0 +1,85 @@ +#/bin/sh +############################################################### +# $Author$ +# $Date$ +# $Revision$ +# +# Copyright 2001 California Institute of Technology +# +############################################################### + + +SUFFIXES= +SUFFIXES= .cpp .d .o + +CXX_FLAGS = @CXXFLAGS@ $(CXX_OPT) + +OBJS = ct.o Storage.o ctstagn.o ctsurf.o ctrpath.o ctbdry.o ctreactor.o ctfunc.o ctxml.o + +DEPENDS = $(OBJS:.o=.d) + + +# Fortran libraries +FORT_LIBS = @FLIBS@ + +shared_ctlib = @SHARED_CTLIB@ + +# the C++ compiler +CXX = @CXX@ + +# external libraries +EXT_LIBS = -lzeroD -loneD @LOCAL_LIBS@ + +# the directory where the Cantera libraries are located +CANTERA_LIBDIR=../../../lib +LIB_DEPS = $(CANTERA_LIBDIR)/libcantera.a $(CANTERA_LIBDIR)/libzeroD.a \ + $(CANTERA_LIBDIR)/liboneD.a $(CANTERA_LIBDIR)/libconverters.a + +# the directory where Cantera include files may be found. +CANTERA_INCDIR=../../src + +CXX_INCLUDES = -I$(CANTERA_INCDIR) + +# flags passed to the C++ compiler/linker for the linking step +LCXX_FLAGS = -L$(CANTERA_LIBDIR) @CXXFLAGS@ + +# how to compile C++ source files to object files +.@CXX_EXT@.@OBJ_EXT@: + $(CXX) -c $< $(CXX_INCLUDES) $(CXX_FLAGS) @PIC@ + +LIB_NAME=lib@CT_SHARED_LIB@ + +ifeq ($(shared_ctlib),1) +CTLIB = ./$(LIB_NAME)@SO@ +else +CTLIB = ./$(LIB_NAME).a +endif + +lib: $(OBJS) $(LIB_DEPS) + $(RM) $(CTLIB) +ifeq ($(shared_ctlib),1) + $(CXX) -o $(CTLIB) $(OBJS) $(LCXX_FLAGS) @SHARED@ $(LINK_OPTIONS) $(EXT_LIBS) @LIBS@ $(FORT_LIBS) + cp $(CTLIB) ../../../lib +else + @ARCHIVE@ $(CTLIB) $(OBJS) + cp $(CTLIB) ../../../lib + ranlib ../../../lib/$(CTLIB) +endif + +clean: + $(RM) $(OBJS) $(CTLIB) + +install: + @INSTALL@ $(CTLIB) @prefix@/lib/cantera + + +%.d: + g++ -MM $(CXX_INCLUDES) $*.cpp > $*.d + +depends: $(DEPENDS) + cat *.d > .depends + $(RM) $(DEPENDS) + +ifeq ($(wildcard .depends), .depends) +include .depends +endif diff --git a/Cantera/clib/src/Storage.cpp b/Cantera/clib/src/Storage.cpp new file mode 100755 index 000000000..d026cc810 --- /dev/null +++ b/Cantera/clib/src/Storage.cpp @@ -0,0 +1,115 @@ + +// Build as a DLL under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#else +#define DLL_EXPORT +#endif + + +// Cantera includes +#include "Kinetics.h" +#include "transport/TransportFactory.h" + +#include "clib_defs.h" +#include "Storage.h" + + +Storage::Storage() { + addThermo(new ThermoPhase); + addKinetics(new Kinetics); + addTransport(newTransportMgr()); +} + +Storage::~Storage() { clear(); } + +int Storage::addThermo(thermo_t* th) { + if (th->index() >= 0) + return th->index(); + __thtable.push_back(th); + int n = __thtable.size() - 1; + th->setIndex(n); + __thmap[th->id()] = n; + return n; +} + +int Storage::nThermo() { return __thtable.size(); } + +int Storage::addKinetics(Kinetics* kin) { + if (kin->index() >= 0) + return kin->index(); + __ktable.push_back(kin); + int n = __ktable.size() - 1; + kin->setIndex(n); + return n; +} + +int Storage::addTransport(Transport* tr) { + if (tr->index() >= 0) + return tr->index(); + __trtable.push_back(tr); + int n = __trtable.size() - 1; + tr->setIndex(n); + return n; +} + +// int Storage::addNewTransport(int model, char* dbase, int th, +// int loglevel) { +// try { +// ThermoPhase* thrm = __thtable[th]; +// Transport* tr = newTransportMgr(model, +// string(dbase), thrm, loglevel); +// __trtable.push_back(tr); +// return __trtable.size() - 1; +// } +// catch (CanteraError) {return -1;} +// catch (...) {return ERR;} +// } + +int Storage::clear() { + int i, n; + n = __thtable.size(); + for (i = 1; i < n; i++) { + if (__thtable[i] != __thtable[0]) + delete __thtable[i]; + __thtable[i] = __thtable[0]; + } + n = __ktable.size(); + for (i = 1; i < n; i++) { + if (__ktable[i] != __ktable[0]) + delete __ktable[i]; + __ktable[i] = __ktable[0]; + } + n = __trtable.size(); + for (i = 1; i < n; i++) { + if (__trtable[i] != __trtable[0]) + delete __trtable[i]; + __trtable[i] = __trtable[0]; + } + return 0; +} + +void Storage::deleteKinetics(int n) { + if (n == 0) return; + if (__ktable[n] != __ktable[0]) + delete __ktable[n]; + __ktable[n] = __ktable[0]; +} + +void Storage::deleteThermo(int n) { + if (n == 0) return; + if (n < 0 || n >= (int) __thtable.size()) + throw CanteraError("deleteThermo","illegal index"); + __thtable[n] = __thtable[0]; +} + +void Storage::deleteTransport(int n) { + if (n == 0) return; + if (__trtable[n] != __trtable[0]) + delete __trtable[n]; + __trtable[n] = __trtable[0]; +} + +Storage* Storage::__storage = 0; + diff --git a/Cantera/clib/src/Storage.h b/Cantera/clib/src/Storage.h new file mode 100755 index 000000000..1fe554e5b --- /dev/null +++ b/Cantera/clib/src/Storage.h @@ -0,0 +1,68 @@ +#ifndef CTC_STORAGE_H +#define CTC_STORAGE_H + +// Cantera includes +#include "Kinetics.h" +#include "transport/TransportBase.h" + +#include "Cabinet.h" +#include "clib_defs.h" + + +/** + * Class to hold pointers to Cantera objects. Only one instance of + * this class is needed. + */ +class Storage { +public: + Storage(); + virtual ~Storage(); + + // vectors to hold pointers to objects + vector __ktable; + vector __thtable; + vector __trtable; + + map __thmap; + + static Storage* storage() { + if (__storage == 0) { + __storage = new Storage; + } + return __storage; + } + + + int addThermo(ThermoPhase* th); + int addKinetics(Kinetics* kin); + int addTransport(Transport* tr); + // int addNewTransport(int model, char* dbase, int th, int loglevel); + int clear(); + void deleteKinetics(int n); + void deleteThermo(int n); + void deleteTransport(int n); + int nThermo(); + static Storage* __storage; +}; + +inline ThermoPhase* ph(int n) { + return Storage::__storage->__thtable[n]; +} + +inline Kinetics* kin(int n) { + return Storage::__storage->__ktable[n]; +} + +inline ThermoPhase* th(int n) { + return Storage::__storage->__thtable[n]; +} + +inline int thermo_index(string id) { + return Storage::__storage->__thmap[id]; +} + +inline Transport* trans(int n) { + return Storage::__storage->__trtable[n]; +} + +#endif diff --git a/Cantera/clib/src/clib_defs.h b/Cantera/clib/src/clib_defs.h new file mode 100755 index 000000000..7d050cf99 --- /dev/null +++ b/Cantera/clib/src/clib_defs.h @@ -0,0 +1,19 @@ +#ifndef CTC_DEFS_H +#define CTC_DEFS_H + +// Build as a DLL under Windows +#ifdef WIN32 +#define DLL_IMPORT __declspec(dllimport) +#define DLL_EXPORT __declspec(dllexport) +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#else +#define DLL_EXPORT +#define DLL_IMPORT +#endif + +// Values returned for error conditions +#define ERR -999 +#define DERR -999.999 + +#endif diff --git a/Cantera/clib/src/ct.cpp b/Cantera/clib/src/ct.cpp new file mode 100755 index 000000000..28fbd5041 --- /dev/null +++ b/Cantera/clib/src/ct.cpp @@ -0,0 +1,863 @@ +/** + * Cantera interface library. This library of functions is designed + * to encapsulate Cantera functionality and make it available for + * use in languages and applications other than C++. A set of + * library functions is provided that are declared "extern C". All + * Cantera objects are stored and referenced by integers - no + * pointers are passed to or from the calling application. + */ + +// turn off warnings under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +// Cantera includes +#include "ChemEquil.h" +#include "KineticsFactory.h" +#include "transport/TransportFactory.h" +#include "ctml.h" +#include "importCTML.h" +#include "converters/ck2ctml.h" +#include "Storage.h" +#include "Cabinet.h" + +#include "clib_defs.h" + +inline XML_Node* _xml(int i) { + return Cabinet::cabinet()->item(i); +} + +inline int nThermo() { + return Storage::storage()->nThermo(); +} + +/** + * Exported functions. + */ +extern "C" { + + //--------------- Phase ---------------------// + + int DLL_EXPORT phase_nElements(int n) { + return ph(n)->nElements(); + } + + int DLL_EXPORT phase_nSpecies(int n) { + return ph(n)->nSpecies(); + } + + doublereal DLL_EXPORT phase_temperature(int n) { + return ph(n)->temperature(); + } + + int DLL_EXPORT phase_setTemperature(int n, double t) { + ph(n)->setTemperature(t); + return 0; + } + + doublereal DLL_EXPORT phase_density(int n) { + return ph(n)->density(); + } + + int DLL_EXPORT phase_setDensity(int n, double rho) { + if (rho < 0.0) throw CanteraError("phase_setDensity", + "density cannot be negative"); + ph(n)->setDensity(rho); + return 0; + } + + doublereal DLL_EXPORT phase_molarDensity(int n) { + return ph(n)->molarDensity(); + } + + doublereal DLL_EXPORT phase_meanMolecularWeight(int n) { + return ph(n)->meanMolecularWeight(); + } + + int DLL_EXPORT phase_elementIndex(int n, char* nm) { + string elnm = string(nm); + return ph(n)->elementIndex(elnm); + } + + int DLL_EXPORT phase_speciesIndex(int n, char* nm) { + string spnm = string(nm); + return ph(n)->speciesIndex(spnm); + } + + int DLL_EXPORT phase_getMoleFractions(int n, int lenx, double* x) { + ThermoPhase* p = ph(n); + if (lenx >= p->nSpecies()) { + p->getMoleFractions(x); + return 0; + } + else + return -1; + } + + doublereal DLL_EXPORT phase_moleFraction(int n, int k) { + ThermoPhase* p = ph(n); + return p->moleFraction(k); + } + + int DLL_EXPORT phase_getMassFractions(int n, int leny, double* y) { + ThermoPhase* p = ph(n); + if (leny >= p->nSpecies()) { + p->getMassFractions(leny, y); + return 0; + } + else + return -1; + } + + doublereal DLL_EXPORT phase_massFraction(int n, int k) { + ThermoPhase* p = ph(n); + return p->massFraction(k); + } + + int DLL_EXPORT phase_setMoleFractions(int n, int lenx, double* x, int norm) { + ThermoPhase* p = ph(n); + if (lenx >= p->nSpecies()) { + if (norm) p->setMoleFractions(x); + else p->setMoleFractions_NoNorm(x); + return 0; + } + else + return -1; + } + + int DLL_EXPORT phase_setMoleFractionsByName(int n, char* x) { + try { + ThermoPhase* p = ph(n); + compositionMap xx; + int nsp = p->nSpecies(); + for (int n = 0; n < nsp; n++) { + xx[p->speciesName(n)] = -1; + } + parseCompString(string(x), xx); + p->setMoleFractionsByName(xx); + return 0; + } + catch (CanteraError) {return -1;} + //catch (...) {return ERR;} + } + + int DLL_EXPORT phase_setMassFractions(int n, int leny, + double* y, int norm) { + ThermoPhase* p = ph(n); + if (leny >= p->nSpecies()) { + if (norm) p->setMassFractions(y); + else p->setMassFractions_NoNorm(y); + return 0; + } + else + return -10; + } + + int DLL_EXPORT phase_setMassFractionsByName(int n, char* y) { + try { + ThermoPhase* p = ph(n); + compositionMap yy; + int nsp = p->nSpecies(); + for (int n = 0; n < nsp; n++) { + yy[p->speciesName(n)] = -1; + } + parseCompString(string(y), yy); + p->setMassFractionsByName(yy); + return 0; + } + catch (CanteraError) {return -1;} + } + + int DLL_EXPORT phase_getAtomicWeights(int n, + int lenm, double* atw) { + ThermoPhase* p = ph(n); + if (lenm >= p->nElements()) { + const vector_fp& wt = p->atomicWeights(); + copy(wt.begin(), wt.end(), atw); + return 0; + } + else + return -10; + } + + int DLL_EXPORT phase_getMolecularWeights(int n, + int lenm, double* mw) { + ThermoPhase* p = ph(n); + if (lenm >= p->nSpecies()) { + const vector_fp& wt = p->molecularWeights(); + copy(wt.begin(), wt.end(), mw); + return 0; + } + else + return -10; + } + + int DLL_EXPORT phase_getSpeciesName(int n, int k, int lennm, char* nm) { + try { + string spnm = ph(n)->speciesName(k); + int lout = min(lennm,spnm.size()); + copy(spnm.c_str(), spnm.c_str() + lout, nm); + nm[lout] = '\0'; + return 0; + } + catch (CanteraError) { return -1; } + //catch (...) {return ERR;} + } + + int DLL_EXPORT phase_getElementName(int n, int m, int lennm, char* nm) { + try { + string elnm = ph(n)->elementName(m); + int lout = min(lennm,elnm.size()); + copy(elnm.c_str(), elnm.c_str() + lout, nm); + nm[lout] = '\0'; + return 0; + } + catch (CanteraError) { return -1; } + } + + + doublereal DLL_EXPORT phase_nAtoms(int n, int k, int m) { + try { + return ph(n)->nAtoms(k,m); + } + catch (CanteraError) { return -1; } + } + + int DLL_EXPORT phase_addElement(int n, char* name, doublereal weight) { + try { + ph(n)->addElement(string(name),weight); + return 0; + } + catch (CanteraError) { return -1; } + } + +// int DLL_EXPORT phase_addSpecies(int n, char* name, int phase, +// int ncomp, doublereal* comp, int thermoType, int ncoeffs, +// double* coeffs, double minTemp, double maxTemp, double refPressure, +// doublereal charge, doublereal weight) { +// try { +// vector_fp cmp(ncomp); +// copy(comp, comp + ncomp, cmp.begin()); +// vector_fp c(ncoeffs); +// copy(coeffs, coeffs + ncoeffs, c.begin()); +// ph(n)->addSpecies(string(name), phase, cmp, +// thermoType, c, minTemp, maxTemp, refPressure, +// charge, weight); +// return 0; +// } +// catch (CanteraError) { return -1; } +// catch (...) {return ERR;} +// } + + + + //-------------- Thermo --------------------// + + // int DLL_EXPORT newThermo(int eos, int ph, int sptherm) { + // return Storage::storage()->addNewThermo(eos, ph, sptherm); + // } + + int DLL_EXPORT th_thermoIndex(char* id) { + return thermo_index(id); + } + +// int DLL_EXPORT newThermo(char* model) { +// try { +// string m = string(model); +// thermo_t* th = newThermoPhase(m); +// return Storage::storage()->addThermo(th); +// } +// catch (CanteraError) { return -1; } +// } + + int DLL_EXPORT newThermoFromXML(int mxml) { + try { + XML_Node* x = _xml(mxml); + thermo_t* th = newPhase(*x); + return Storage::storage()->addThermo(th); + } + catch (CanteraError) { return -1; } + } + + //int DLL_EXPORT th_phase(int n) { + // return th(n)->phase().index(); + // } + + int DLL_EXPORT th_nSpecies(int n) { + return th(n)->nSpecies(); + } + + int DLL_EXPORT th_eosType(int n) { + return th(n)->eosType(); + } + + double DLL_EXPORT th_enthalpy_mole(int n) { + try {return th(n)->enthalpy_mole();} + catch (CanteraError) {return DERR;} + } + + double DLL_EXPORT th_intEnergy_mole(int n) { + try {return th(n)->intEnergy_mole();} + catch (CanteraError) {return DERR;} + } + + double DLL_EXPORT th_entropy_mole(int n) { + try {return th(n)->entropy_mole();} + catch (CanteraError) {return DERR;} + } + + double DLL_EXPORT th_gibbs_mole(int n) { + try {return th(n)->gibbs_mole();} + catch (CanteraError) {return DERR;} + } + + double DLL_EXPORT th_cp_mole(int n) { + try {return th(n)->cp_mole();} + catch (CanteraError) {return DERR;} + } + + double DLL_EXPORT th_cv_mole(int n) { + try {return th(n)->cv_mole();} + catch (CanteraError) {return DERR;} + } + + double DLL_EXPORT th_pressure(int n) { + try {return th(n)->pressure();} + catch (CanteraError) {return DERR;} + } + + double DLL_EXPORT th_enthalpy_mass(int n) { + try {return th(n)->enthalpy_mass();} + catch (CanteraError) {return DERR;} + } + + double DLL_EXPORT th_intEnergy_mass(int n) { + try {return th(n)->intEnergy_mass();} + catch (CanteraError) {return DERR;} + } + + double DLL_EXPORT th_entropy_mass(int n) { + try {return th(n)->entropy_mass();} + catch (CanteraError) {return DERR;} + } + + double DLL_EXPORT th_gibbs_mass(int n) { + try {return th(n)->gibbs_mass();} + catch (CanteraError) {return DERR;} + } + + double DLL_EXPORT th_cp_mass(int n) { + try {return th(n)->cp_mass();} + catch (CanteraError) {return DERR;} + } + + double DLL_EXPORT th_cv_mass(int n) { + try {return th(n)->cv_mass();} + catch (CanteraError) {return DERR;} + } + + int DLL_EXPORT th_chemPotentials(int n, int lenm, double* murt) { + thermo_t* thrm = th(n); + int nsp = thrm->nSpecies(); + if (lenm >= nsp) { + thrm->getChemPotentials(murt); + return 0; + } + else + return -10; + } + + int DLL_EXPORT th_setPressure(int n, double p) { + try { + if (p < 0.0) throw CanteraError("th_setPressure", + "pressure cannot be negative"); + th(n)->setPressure(p); + return 0; + } + catch (CanteraError) {return -1;} + } + + int DLL_EXPORT th_set_HP(int n, double* vals) { + try { + if (vals[1] < 0.0) + throw CanteraError("th_set_HP", + "pressure cannot be negative"); + th(n)->setState_HP(vals[0],vals[1]); + if (th(n)->temperature() < 0.0) + throw CanteraError("th_set_HP", + "temperature cannot be negative"); + return 0; + } + catch (CanteraError) {return -1;} + } + + int DLL_EXPORT th_set_UV(int n, double* vals) { + try { + if (vals[1] < 0.0) + throw CanteraError("th_set_UV", + "specific volume cannot be negative"); + th(n)->setState_UV(vals[0],vals[1]); + if (th(n)->temperature() < 0.0) + throw CanteraError("th_set_UV", + "temperature cannot be negative"); + return 0; + } + catch (CanteraError) {return -1;} + } + + int DLL_EXPORT th_set_SV(int n, double* vals) { + try { th(n)->setState_SV(vals[0],vals[1]); + return 0; } + catch (CanteraError) {return -1;} + catch (...) {return ERR;} + } + + int DLL_EXPORT th_set_SP(int n, double* vals) { + try { + th(n)->setState_SP(vals[0],vals[1]); + return 0; + } + catch (CanteraError) {return -1;} + } + + int DLL_EXPORT th_equil(int n, int XY) { + try { + equilibrate(*th(n), XY); return 0; + } + catch (CanteraError) {return -1;} + } + + doublereal DLL_EXPORT th_refPressure(int n) { + return th(n)->refPressure(); + } + + doublereal DLL_EXPORT th_minTemp(int n, int k) { + return th(n)->minTemp(k); + } + + doublereal DLL_EXPORT th_maxTemp(int n, int k) { + return th(n)->maxTemp(k); + } + + + int DLL_EXPORT th_getEnthalpies_RT(int n, int lenm, double* h_rt) { + thermo_t* thrm = th(n); + int nsp = thrm->nSpecies(); + if (lenm >= nsp) { + thrm->getEnthalpy_RT(h_rt); + return 0; + } + else + return -10; + } + + int DLL_EXPORT th_getEntropies_R(int n, int lenm, double* s_r) { + thermo_t* thrm = th(n); + int nsp = thrm->nSpecies(); + if (lenm >= nsp) { + thrm->getEntropy_R(s_r); + return 0; + } + else + return -10; + } + + int DLL_EXPORT th_getCp_R(int n, int lenm, double* cp_r) { + thermo_t* thrm = th(n); + int nsp = thrm->nSpecies(); + if (lenm >= nsp) { + thrm->getCp_R(cp_r); + return 0; + } + else + return -10; + } + + //-------------- Kinetics ------------------// + + int DLL_EXPORT newKineticsFromXML(int mxml, int iphase, + int neighbor1, int neighbor2) { + try { + XML_Node* x = _xml(mxml); + vector phases; + phases.push_back(th(iphase)); + if (neighbor1 >= 0) { + phases.push_back(th(neighbor1)); + if (neighbor2 >= 0) { + phases.push_back(th(neighbor2)); + } + } + Kinetics* kin = newKineticsMgr(*x, phases); + return Storage::storage()->addKinetics(kin); + } + catch (CanteraError) { return -1; } + } + + int DLL_EXPORT installRxnArrays(int pxml, int ikin, + char* default_phase) { + try { + XML_Node* p = _xml(pxml); + kinetics_t* k = kin(ikin); + string defphase = string(default_phase); + installReactionArrays(*p, *k, defphase); + return 0; + } + catch (CanteraError) { return -1; } + } + + //------------------------------------- + int DLL_EXPORT kin_type(int n) { + return kin(n)->type(); + } + + int DLL_EXPORT kin_start(int n, int p) { + return kin(n)->start(p); + } + + int DLL_EXPORT kin_speciesIndex(int n, const char* nm, const char* ph) { + return kin(n)->kineticsSpeciesIndex(string(nm), string(ph)); + } + + //--------------------------------------- + + int DLL_EXPORT kin_nSpecies(int n) { + return kin(n)->nTotalSpecies(); + } + + int DLL_EXPORT kin_nReactions(int n) { + return kin(n)->nReactions(); + } + + double DLL_EXPORT kin_reactantStoichCoeff(int n, int k, int i) { + return kin(n)->reactantStoichCoeff(k,i); + } + + double DLL_EXPORT kin_productStoichCoeff(int n, int k, int i) { + return kin(n)->productStoichCoeff(k,i); + } + + int DLL_EXPORT kin_reactionType(int n, int i) { + return kin(n)->reactionType(i); + } + + int DLL_EXPORT kin_getFwdRatesOfProgress(int n, int len, double* fwdROP) { + Kinetics* k = kin(n); + try { + if (len >= k->nReactions()) { + k->getFwdRatesOfProgress(fwdROP); + return 0; + } + else + return ERR; + } + catch (CanteraError) {return -1;} + } + + int DLL_EXPORT kin_getRevRatesOfProgress(int n, int len, double* revROP) { + Kinetics* k = kin(n); + try { + if (len >= k->nReactions()) { + k->getRevRatesOfProgress(revROP); + return 0; + } + else + return ERR; + } + catch (CanteraError) {return -1;} + } + + int DLL_EXPORT kin_isReversible(int n, int i) { + return (int)kin(n)->isReversible(i); + } + + int DLL_EXPORT kin_getNetRatesOfProgress(int n, int len, double* netROP) { + try { + Kinetics* k = kin(n); + if (len >= k->nReactions()) { + k->getNetRatesOfProgress(netROP); + return 0; + } + else + return ERR; + } + catch (CanteraError) {return -1;} + } + + int DLL_EXPORT kin_getCreationRates(int n, int len, double* cdot) { + try { + Kinetics* k = kin(n); + if (len >= k->nTotalSpecies()) { + k->getCreationRates(cdot); + return 0; + } + else + return ERR; + } + catch (CanteraError) {return -1;} + } + + int DLL_EXPORT kin_getDestructionRates(int n, int len, double* ddot) { + try { + Kinetics* k = kin(n); + if (len >= k->nTotalSpecies()) { + k->getDestructionRates(ddot); + return 0; + } + else + return ERR; + } + catch (CanteraError) {return -1;} + //catch (...) {return ERR;} + } + + int DLL_EXPORT kin_getNetProductionRates(int n, int len, double* wdot) { + try { + Kinetics* k = kin(n); + if (len >= k->nTotalSpecies()) { + k->getNetProductionRates(wdot); + return 0; + } + else + return ERR; + } + catch (CanteraError) {return -1;} + } + + int DLL_EXPORT kin_getSourceTerms(int n, int len, double* ydot) { + try { + Kinetics* k = kin(n); + ThermoPhase* p = &k->thermo(); + const vector_fp& mw = p->molecularWeights(); + int nsp = mw.size(); + double rrho = 1.0/p->density(); + if (len >= nsp) { + k->getNetProductionRates(ydot); + multiply_each(ydot, ydot + nsp, mw.begin()); + scale(ydot, ydot + nsp, ydot, rrho); + return 0; + } + else + return ERR; + } + catch (CanteraError) {return -1;} + } + + double DLL_EXPORT kin_multiplier(int n, int i) { + return kin(n)->multiplier(i); + } + + int DLL_EXPORT kin_getEquilibriumConstants(int n, int len, double* kc) { + try { + Kinetics* k = kin(n); + if (len >= k->nReactions()) { + k->getEquilibriumConstants(kc); + return 0; + } + else + return ERR; + } + catch (CanteraError) {return -1;} + } + + int DLL_EXPORT kin_getReactionString(int n, int i, int len, char* buf) { + try { + Kinetics* k = kin(n); + string r = k->reactionString(i); + int lout = min(len,r.size()); + copy(r.c_str(), r.c_str() + lout, buf); + buf[lout] = '\0'; + return 0; + } + catch (CanteraError) {return -1;} + } + + int DLL_EXPORT kin_setMultiplier(int n, int i, double v) { + try { + if (v >= 0.0) { + kin(n)->setMultiplier(i,v); + return 0; + } + else return ERR; + } + catch (CanteraError) {return -1;} + } + + + //------------------- Transport --------------------------- + + int DLL_EXPORT newTransport(char* model, + int ith, int loglevel) { + string mstr = string(model); + thermo_t* t = th(ith); + try { + Transport* tr = newTransportMgr(mstr,t, loglevel); + return Storage::storage()->addTransport(tr); + } + catch (CanteraError) { return -1; } + } + + double DLL_EXPORT trans_viscosity(int n) { + try {return trans(n)->viscosity();} + catch (CanteraError) { return -1.0; } + } + + double DLL_EXPORT trans_thermalConductivity(int n) { + try {return trans(n)->thermalConductivity();} + catch (CanteraError) { return -1.0; } + } + + int DLL_EXPORT trans_getThermalDiffCoeffs(int n, int ldt, double* dt) { + try { trans(n)->getThermalDiffCoeffs(dt); return 0; } + catch (CanteraError) { return -1; } + } + + int DLL_EXPORT trans_getMixDiffCoeffs(int n, int ld, double* d) { + try { trans(n)->getMixDiffCoeffs(d); return 0;} + catch (CanteraError) { return -1; } + } + + int DLL_EXPORT trans_getBinDiffCoeffs(int n, int ld, double* d) { + try { trans(n)->getBinaryDiffCoeffs(ld,d); return 0;} + catch (CanteraError) { return -1; } + } + + int DLL_EXPORT trans_getMultiDiffCoeffs(int n, int ld, double* d) { + try { trans(n)->getMultiDiffCoeffs(ld,d); return 0;} + catch (CanteraError) { return -1; } + } + + + //-------------------- Functions --------------------------- + + int DLL_EXPORT import_phase(int nth, int nxml, char* id) { + thermo_t* thrm = th(nth); + XML_Node* node = _xml(nxml); + string idstr = string(id); + try { + importPhase(*node, thrm); + return 0; + } + catch (CanteraError) { return -1; } + } + + int DLL_EXPORT import_kinetics(int nxml, char* id, + int nphases, integer* ith, int nkin) { + vector phases; + for (int i = 0; i < nphases; i++) { + phases.push_back(th(ith[i])); + } + XML_Node* node = _xml(nxml); + Kinetics* k = kin(nkin); + string idstr = string(id); + try { + importKinetics(*node, phases, k); + return 0; + } + catch (CanteraError) { return -1; } + } + + + int DLL_EXPORT phase_report(int nth, + int ibuf, char* buf, int show_thermo) { + try { + bool stherm = (show_thermo != 0); + string s = report(*th(nth), stherm); + if (int(s.size()) > ibuf - 1) { + return -(s.size() + 1); + } + copy(s.begin(), s.end(), buf); + buf[s.size() - 1] = '\0'; + return 0; + + } + catch (CanteraError) { return -1; } + } + + int DLL_EXPORT getCanteraError(int buflen, char* buf) { + string e; // = ""; + //if (nErrors() > 0) + e = lastErrorMessage(); + int n = min(e.size(), buflen-1); + copy(e.begin(), e.begin() + n, buf); + buf[min(n, buflen-1)] = '\0'; + return 0; + } + + int DLL_EXPORT addCanteraDirectory(int buflen, char* buf) { + addDirectory(string(buf)); + return 0; + } + + int DLL_EXPORT readlog(int n, char* buf) { + string s; + getlog(s); + int nlog = s.size(); + if (n < 0) return nlog; + int nn = min(n-1, nlog); + copy(s.begin(), s.begin() + nn, + buf); + buf[min(nlog, n-1)] = '\0'; + clearlog(); + return 0; + + } + int DLL_EXPORT clearStorage() { + Storage::__storage->clear(); + return 0; + } + + int DLL_EXPORT delThermo(int n) { + try { + Storage::__storage->deleteThermo(n); + return 0; + } + catch (CanteraError) { + return -1; + } + } + + int DLL_EXPORT delKinetics(int n) { + Storage::__storage->deleteKinetics(n); + return 0; + } + + int DLL_EXPORT delTransport(int n) { + Storage::__storage->deleteTransport(n); + return 0; + } + + int DLL_EXPORT buildSolutionFromXML(char* src, int ixml, char* id, + int ith, int ikin) { + + XML_Node* root = 0; + if (ixml > 0) root = _xml(ixml); + + thermo_t* t = th(ith); + kinetics_t* k = kin(ikin); + + Kinetics& kin = *k; + XML_Node *x, *r=0; + if (root) r = &root->root(); + x = find_XML(string(src), r, string(id), "", "phase"); + if (!x) return false; + importPhase(*x, t); + kin.addPhase(*t); + kin.init(); + installReactionArrays(*x, kin, x->id()); + t->setState_TP(300.0, OneAtm); + if (r) { + if (&x->root() != &r->root()) delete &x->root(); + } + else delete &x->root(); + return 0; + } + + + int DLL_EXPORT ck_to_ctml(char* in_file, char* db_file, + char* tr_file, char* out_file, char* id_tag) { + return convert_ck(in_file, db_file, tr_file, out_file, id_tag); + } + +} diff --git a/Cantera/clib/src/ct.h b/Cantera/clib/src/ct.h new file mode 100755 index 000000000..7b6b5ce8b --- /dev/null +++ b/Cantera/clib/src/ct.h @@ -0,0 +1,132 @@ +#ifndef CTC_CT_H +#define CTC_CT_H + +#include "clib_defs.h" + +extern "C" { + + int DLL_IMPORT phase_nElements(int n); + int DLL_IMPORT phase_nSpecies(int n); + double DLL_IMPORT phase_temperature(int n); + int DLL_IMPORT phase_setTemperature(int n, double t); + double DLL_IMPORT phase_density(int n); + int DLL_IMPORT phase_setDensity(int n, double rho); + double DLL_IMPORT phase_molarDensity(int n); + double DLL_IMPORT phase_meanMolecularWeight(int n); + double DLL_IMPORT phase_moleFraction(int n, int k); + double DLL_IMPORT phase_massFraction(int n, int k); + int DLL_IMPORT phase_getMoleFractions(int n, int lenx, double* x); + int DLL_IMPORT phase_getMassFractions(int n, int leny, double* y); + int DLL_IMPORT phase_setMoleFractions(int n, int lenx, + double* x, int norm); + int DLL_IMPORT phase_setMassFractions(int n, int leny, + double* y, int norm); + int DLL_IMPORT phase_setMoleFractionsByName(int n, char* x); + int DLL_IMPORT phase_setMassFractionsByName(int n, char* y); + int DLL_IMPORT phase_getAtomicWeights(int n, int lenm, double* atw); + int DLL_IMPORT phase_getMolecularWeights(int n, int lenm, double* mw); + int DLL_IMPORT phase_getElementName(int n, int k, int lennm, char* nm); + int DLL_IMPORT phase_getSpeciesName(int n, int m, int lennm, char* nm); + int DLL_IMPORT phase_elementIndex(int n, char* nm); + int DLL_IMPORT phase_speciesIndex(int n, char* nm); + int DLL_IMPORT phase_report(int nth, + int ibuf, char* buf, int show_thermo); + double DLL_IMPORT phase_nAtoms(int n, int k, int m); + + int DLL_IMPORT phase_addElement(int n, char* name, double weight); + int DLL_IMPORT phase_addSpecies(int n, char* name, int phase, + int ncomp, double* comp, int thermoType, int ncoeffs, + double* coeffs, double minTemp, double maxTemp, double refPressure, + double charge, double weight); + + //int DLL_IMPORT newThermo(char* model); + int DLL_IMPORT newThermoFromXML(int mxml); + int DLL_IMPORT th_thermoIndex(char* id); + int DLL_IMPORT th_phase(int n); + int DLL_IMPORT th_nSpecies(int n); + int DLL_IMPORT th_eosType(int n); + double DLL_IMPORT th_refPressure(int n); + double DLL_IMPORT th_minTemp(int n, int k=-1); + double DLL_IMPORT th_maxTemp(int n, int k=-1); + double DLL_IMPORT th_enthalpy_mole(int n); + double DLL_IMPORT th_intEnergy_mole(int n); + double DLL_IMPORT th_entropy_mole(int n); + double DLL_IMPORT th_gibbs_mole(int n); + double DLL_IMPORT th_cp_mole(int n); + double DLL_IMPORT th_cv_mole(int n); + double DLL_IMPORT th_pressure(int n); + int DLL_IMPORT th_setPressure(int n, double p); + double DLL_IMPORT th_enthalpy_mass(int n); + double DLL_IMPORT th_intEnergy_mass(int n); + double DLL_IMPORT th_entropy_mass(int n); + double DLL_IMPORT th_gibbs_mass(int n); + double DLL_IMPORT th_cp_mass(int n); + double DLL_IMPORT th_cv_mass(int n); + int DLL_IMPORT th_chemPotentials(int n, int lenm, double* murt); + int DLL_IMPORT th_getEnthalpies_RT(int n, int lenm, double* h_rt); + int DLL_IMPORT th_getEntropies_R(int n, int lenm, double* s_r); + int DLL_IMPORT th_getCp_R(int n, int lenm, double* cp_r); + int DLL_IMPORT get_eos(char* fname, char* phase_id); + + int DLL_IMPORT th_set_HP(int n, double* vals); + int DLL_IMPORT th_set_UV(int n, double* vals); + int DLL_IMPORT th_set_SV(int n, double* vals); + int DLL_IMPORT th_set_SP(int n, double* vals); + int DLL_IMPORT th_equil(int n, int XY); + + int DLL_IMPORT newKineticsFromXML(int mxml, int iphase, + int neighbor1=-1, int neighbor2=-1); + int DLL_IMPORT installRxnArrays(int pxml, int ikin, + char* default_phase); + int DLL_IMPORT kin_nSpecies(int n); + int DLL_IMPORT kin_nReactions(int n); + double DLL_IMPORT kin_reactantStoichCoeff(int n, int i, int k); + double DLL_IMPORT kin_productStoichCoeff(int n, int i, int k); + int DLL_IMPORT kin_reactionType(int n, int i); + int DLL_IMPORT kin_getFwdRatesOfProgress(int n, int len, double* fwdROP); + int DLL_IMPORT kin_getRevRatesOfProgress(int n, int len, double* revROP); + int DLL_IMPORT kin_getNetRatesOfProgress(int n, int len, double* netROP); + int DLL_IMPORT kin_getEquilibriumConstants(int n, int len, double* kc); + int DLL_IMPORT kin_getCreationRates(int n, int len, double* cdot); + int DLL_IMPORT kin_getDestructionRates(int n, int len, double* ddot); + int DLL_IMPORT kin_getNetProductionRates(int n, int len, double* wdot); + int DLL_IMPORT kin_getSourceTerms(int n, int len, double* ydot); + double DLL_IMPORT kin_multiplier(int n, int i); + int DLL_IMPORT kin_getReactionString(int n, int i, int len, char* buf); + int DLL_IMPORT kin_setMultiplier(int n, int i, double v); + + int DLL_IMPORT kin_isReversible(int n, int i); + int DLL_IMPORT kin_type(int n); + int DLL_IMPORT kin_start(int n, int p); + int DLL_IMPORT kin_speciesIndex(int n, const char* nm, const char* ph); + + int DLL_IMPORT newTransport(char* model, + int th, int loglevel); + double DLL_IMPORT trans_viscosity(int n); + double DLL_IMPORT trans_thermalConductivity(int n); + int DLL_IMPORT trans_getThermalDiffCoeffs(int n, int ldt, double* dt); + int DLL_IMPORT trans_getMixDiffCoeffs(int n, int ld, double* d); + int DLL_IMPORT trans_getBinDiffCoeffs(int n, int ld, double* d); + int DLL_IMPORT trans_getMultiDiffCoeffs(int n, int ld, double* d); + + int DLL_IMPORT import_phase(int nth, int nxml, char* id); + int DLL_IMPORT import_kinetics(int nxml, char* id, + int nphases, int* ith, int nkin); + int DLL_IMPORT import_from_file(int nth, int nkin, char* fname, char* db, + char* id, int validate, double threshold); + int DLL_IMPORT getCanteraError(int buflen, char* buf); + int DLL_IMPORT addCanteraDirectory(int buflen, char* buf); + int DLL_IMPORT clearStorage(); + int DLL_IMPORT delPhase(int n); + int DLL_IMPORT delThermo(int n); + int DLL_IMPORT delKinetics(int n); + int DLL_IMPORT delTransport(int n); + int DLL_IMPORT readlog(int n, char* buf); + int DLL_IMPORT buildSolutionFromXML(char* src, int ixml, char* id, + int ith, int ikin); + + int DLL_IMPORT ck_to_ctml(char* in_file, char* db_file, + char* tr_file, char* out_file, char* id_tag); +} + +#endif diff --git a/Cantera/clib/src/ctbdry.cpp b/Cantera/clib/src/ctbdry.cpp new file mode 100755 index 000000000..5f46e57c2 --- /dev/null +++ b/Cantera/clib/src/ctbdry.cpp @@ -0,0 +1,92 @@ + +// Build as a DLL under Windows +#ifdef WIN32 +#define DLL_EXPORT __declspec(dllexport) +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#else +#define DLL_EXPORT +#endif + + +// Cantera includes +#include "oneD/OneDim.h" +#include "oneD/Inlet1D.h" + +#include "Cabinet.h" +#include "Storage.h" + +// Values returned for error conditions +#define ERR -999 +#define DERR -999.999 + +Cabinet* Cabinet::__storage = 0; + +inline Bdry1D* _bndry(int i) { + return Cabinet::cabinet()->item(i); +} + +//inline Phase* _phase(int n) { +// return Storage::__storage->__phasetable[n]; +//} + +inline ThermoPhase* _thermo(int n) { + return Storage::__storage->__thtable[n]; +} + +extern "C" { + + int DLL_EXPORT bndry_new(int itype) { + Bdry1D* s; + switch (itype) { + case 1: + s = new Inlet1D(); break; + case 2: + s = new Symm1D(); break; + case 3: + s = new Surf1D(); break; + default: + return -2; + } + int i = Cabinet::cabinet()->add(s); + return i; + } + + int DLL_EXPORT bndry_del(int i) { + Cabinet::cabinet()->del(i); + return 0; + } + + double DLL_EXPORT bndry_temperature(int i) { + return _bndry(i)->temperature(); + } + + int DLL_EXPORT bndry_settemperature(int i, double t) { + _bndry(i)->setTemperature(t); + return 0; + } + + int DLL_EXPORT bndry_setmdot(int i, double mdot) { + try { + _bndry(i)->setMdot(mdot); + } + catch (CanteraError) {return -1;} + return 0; + } + + + double DLL_EXPORT bndry_mdot(int i) { + return _bndry(i)->mdot(); + return 0; + } + + int DLL_EXPORT bndry_setxin(int i, double* xin) { + _bndry(i)->setMoleFractions(xin); + return 0; + } + + int DLL_EXPORT bndry_setxinbyname(int i, char* xin) { + _bndry(i)->setMoleFractions(string(xin)); + return 0; + } +} diff --git a/Cantera/clib/src/ctbdry.h b/Cantera/clib/src/ctbdry.h new file mode 100755 index 000000000..e6aea2036 --- /dev/null +++ b/Cantera/clib/src/ctbdry.h @@ -0,0 +1,17 @@ +#ifndef CTC_BDRY_H +#define CTC_BDRY_H + +#include "clib_defs.h" + +extern "C" { + + int DLL_IMPORT bndry_new(int itype); + int DLL_IMPORT bndry_del(int i); + double DLL_IMPORT bndry_temperature(int i); + int DLL_IMPORT bndry_settemperature(int i, double t); + int DLL_IMPORT bndry_setmdot(int i, double mdot); + double DLL_IMPORT bndry_mdot(int i); + int DLL_IMPORT bndry_setxin(int i, double* xin); + int DLL_IMPORT bndry_setxinbyname(int i, char* xin); +} +#endif diff --git a/Cantera/clib/src/ctfunc.cpp b/Cantera/clib/src/ctfunc.cpp new file mode 100755 index 000000000..9c39f34ef --- /dev/null +++ b/Cantera/clib/src/ctfunc.cpp @@ -0,0 +1,90 @@ + +#include "Func1.h" +#include "ctexceptions.h" +using namespace Cantera; + +#include "Cabinet.h" + +// Build as a DLL under Windows +#ifdef WIN32 +#define DLL_EXPORT __declspec(dllexport) +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#else +#define DLL_EXPORT +#endif + +// Values returned for error conditions +#define ERR -999 +#define DERR -999.999 + +typedef Func1 func_t; + +Cabinet* Cabinet::__storage = 0; + +inline func_t* _func(int i) { + return Cabinet::cabinet()->item(i); +} + +extern "C" { + + // functions + + int DLL_EXPORT func_new(int type, int n, int lenp, double* params) { + func_t* r=0; + int m = lenp; + try { + if (type == FourierFuncType) { + if (lenp < 2*n + 2) + throw CanteraError("func_new", + "not enough Fourier coefficients"); + r = new Fourier1(n, params[n+1], params[0], params + 1, + params + n + 2); + } + else if (type == PolyFuncType) { + if (lenp < n + 1) + throw CanteraError("func_new", + "not enough polynomial coefficients"); + r = new Poly1(n, params); + } + else if (type == ArrheniusFuncType) { + if (lenp < 3*n) + throw CanteraError("func_new", + "not enough Arrhenius coefficients"); + r = new Arrhenius1(n, params); + } + else if (type == SumFuncType) { + r = new Func1Sum(*_func(n), *_func(m)); + } + else if (type == ProdFuncType) { + r = new Func1Product(*_func(n), *_func(m)); + } + else if (type == RatioFuncType) { + r = new Func1Ratio(*_func(n), *_func(m)); + } + else + r = new Func1(); + return Cabinet::cabinet()->add(r); + } + catch (CanteraError) {return -1;} + } + + + int DLL_EXPORT func_del(int i) { + Cabinet::cabinet()->del(i); + return 0; + } + + int DLL_EXPORT func_copy(int i) { + return Cabinet::cabinet()->newCopy(i); + } + + int DLL_EXPORT func_assign(int i, int j) { + return Cabinet::cabinet()->assign(i,j); + } + + double DLL_EXPORT func_value(int i, double t) { + return _func(i)->eval(t); + } + +} diff --git a/Cantera/clib/src/ctfunc.h b/Cantera/clib/src/ctfunc.h new file mode 100755 index 000000000..fba972550 --- /dev/null +++ b/Cantera/clib/src/ctfunc.h @@ -0,0 +1,14 @@ +#ifndef CTC_FUNC1_H +#define CTC_FUNC1_H + +#include "clib_defs.h" + +extern "C" { + int DLL_IMPORT func_new(int type, int n, int lenp, double* p); + int DLL_IMPORT func_del(int i); + int DLL_IMPORT func_copy(int i); + int DLL_IMPORT func_assign(int i, int j); + double DLL_IMPORT func_value(int i, double t); +} + +#endif diff --git a/Cantera/clib/src/ctnum.cpp b/Cantera/clib/src/ctnum.cpp new file mode 100755 index 000000000..1dbc7f301 --- /dev/null +++ b/Cantera/clib/src/ctnum.cpp @@ -0,0 +1,179 @@ + +// Cantera includes +#include "numerics.h" +#include "Cabinet.h" +inline DenseMatrix* _matrix(int i) { + return Cabinet::cabinet()->item(i); +} + +inline BandMatrix* _bmatrix(int i) { + return Cabinet::cabinet()->item(i); +} + +// Build as a DLL under Windows +#ifdef WIN32 +#define DLL_EXPORT __declspec(dllexport) +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#else +#define DLL_EXPORT +#endif + +// Values returned for error conditions +#define ERR -999 +#define DERR -999.999 + +Cabinet* Cabinet::__storage = 0; +Cabinet* Cabinet::__storage = 0; + +extern "C" { + + + ///// Matrix ////// + + int DLL_EXPORT newMatrix(int m, int n) { + DenseMatrix* x = new DenseMatrix(m,n); + return Cabinet::cabinet()->add(x); + } + + int DLL_EXPORT delMatrix(int i) { + Cabinet::cabinet()->del(i); + return 0; + } + + int DLL_EXPORT matrix_copy(int i) { + return Cabinet::cabinet()->newCopy(i); + } + + int DLL_EXPORT matrix_assign(int i, int j) { + return Cabinet::cabinet()->assign(i,j); + } + + int DLL_EXPORT matrix_nRows(int i) { + return _matrix(i)->nRows(); + } + + int DLL_EXPORT matrix_nColumns(int i) { + return _matrix(i)->nColumns(); + } + + int DLL_EXPORT matrix_resize(int i, int m, int n, double v) { + _matrix(i)->resize(m,n,v); + return 0; + } + + int DLL_EXPORT matrix_appendColumn(int i, double* c) { + _matrix(i)->appendColumn(c); + return 0; + } + + double DLL_EXPORT matrix_value(int i, int m, int n) { + return _matrix(i)->value(m,n); + } + + double DLL_EXPORT matrix_setvalue(int i, int m, int n, double v) { + _matrix(i)->value(m,n) = v; + return v; + } + + int DLL_EXPORT matrix_solve(int i1, int i2) { + try { + int info = solve(*_matrix(i1), *_matrix(i2)); + return info; + } + catch (CanteraError) { return -1; } + catch (...) { return ERR; } + } + + int DLL_EXPORT matrix_multiply(int ma, int mb, int mp) { + try { + DenseMatrix* a = _matrix(ma); + DenseMatrix* b = _matrix(mb); + DenseMatrix* p = _matrix(mp); + multiply(*a, b->begin(), p->begin()); + return 0; + } + catch (CanteraError) { return -1; } + catch (...) { return ERR; } + } + + int DLL_EXPORT matrix_invert(int ma) { + try { + invert(*_matrix(ma)); + return 0; + } + catch (CanteraError) { return -1; } + catch (...) { return ERR; } + } + + + ///////////////// BandMatrix ////////////////////// + + + int DLL_EXPORT bmatrix_new(int n, int kl, int ku) { + BandMatrix* x = new BandMatrix(n, kl, ku); + return Cabinet::cabinet()->add(x); + } + + int DLL_EXPORT bmatrix_del(int i) { + Cabinet::cabinet()->del(i); + return 0; + } + + int DLL_EXPORT bmatrix_copy(int i) { + return Cabinet::cabinet()->newCopy(i); + } + + int DLL_EXPORT bmatrix_assign(int i, int j) { + return Cabinet::cabinet()->assign(i,j); + } + + int DLL_EXPORT bmatrix_nRows(int i) { + return _bmatrix(i)->rows(); + } + + int DLL_EXPORT bmatrix_nColumns(int i) { + return _bmatrix(i)->columns(); + } + + int DLL_EXPORT bmatrix_resize(int i, int m, int n, double v) { + _bmatrix(i)->resize(m,n,v); + return 0; + } + + double DLL_EXPORT bmatrix_value(int i, int m, int n) { + return _bmatrix(i)->value(m,n); + } + + double DLL_EXPORT bmatrix_setvalue(int i, int m, int n, double v) { + try { + _bmatrix(i)->value(m,n) = v; + return v; + } + catch (...) { return ERR; } + } + + int DLL_EXPORT bmatrix_solve(int ma, int mb) { + try { + int n = _bmatrix(ma)->nColumns(); + _bmatrix(ma)->solve(n, + _matrix(mb)->begin()); + return 0; + } + catch (CanteraError) { return -1; } + catch (...) { return ERR; } + } + + int DLL_EXPORT bmatrix_multiply(int ma, int mb, int mp) { + try { + BandMatrix* a = _bmatrix(ma); + DenseMatrix* b = _matrix(mb); + DenseMatrix* p = _matrix(mp); + a->mult(b->begin(), p->begin()); + return 0; + } + catch (CanteraError) { return -1; } + catch (...) { return ERR; } + } + +} diff --git a/Cantera/clib/src/ctnum.h b/Cantera/clib/src/ctnum.h new file mode 100755 index 000000000..8d58bfb0d --- /dev/null +++ b/Cantera/clib/src/ctnum.h @@ -0,0 +1,37 @@ +#ifndef CTC_CTNUM_H +#define CTC_CTNUM_H + +#include "clib_defs.h" + +extern "C" { + + int DLL_IMPORT newMatrix(int m, int n); + int DLL_IMPORT delMatrix(int i); + int DLL_IMPORT matrix_copy(int i); + int DLL_IMPORT matrix_assign(int i, int j); + int DLL_IMPORT matrix_nRows(int i); + int DLL_IMPORT matrix_nColumns(int i); + int DLL_IMPORT matrix_resize(int i, int m, int n, double v); + int DLL_IMPORT matrix_appendColumn(int i, double* c); + double DLL_IMPORT matrix_value(int i, int m, int n); + double DLL_IMPORT matrix_setvalue(int i, int m, int n, double v); + int DLL_IMPORT matrix_solve(int i1, int i2); + int DLL_IMPORT matrix_multiply(int ma, int mb, int mp); + int DLL_IMPORT matrix_invert(int ma); + + int DLL_IMPORT bmatrix_new(int n, int kl, int ku); + int DLL_IMPORT bmatrix_del(int i); + int DLL_IMPORT bmatrix_copy(int i); + int DLL_IMPORT bmatrix_assign(int i, int j); + int DLL_IMPORT bmatrix_nRows(int i); + int DLL_IMPORT bmatrix_nColumns(int i); + int DLL_IMPORT bmatrix_resize(int i, int m, int n, double v); + double DLL_IMPORT bmatrix_value(int i, int m, int n); + double DLL_IMPORT bmatrix_setvalue(int i, int m, int n, double v); + int DLL_IMPORT bmatrix_solve(int ma, int mb); + int DLL_IMPORT bmatrix_multiply(int ma, int mb, int mp); + + +} + +#endif diff --git a/Cantera/clib/src/ctreactor.cpp b/Cantera/clib/src/ctreactor.cpp new file mode 100755 index 000000000..26b9e6612 --- /dev/null +++ b/Cantera/clib/src/ctreactor.cpp @@ -0,0 +1,367 @@ + +// Cantera includes +#include "zeroD/Reactor.h" +#include "zeroD/Reservoir.h" +#include "zeroD/Wall.h" +#include "zeroD/flowControllers.h" + +#include "Cabinet.h" +#include "Storage.h" + +// Build as a DLL under Windows +#ifdef WIN32 +#define DLL_EXPORT __declspec(dllexport) +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#else +#define DLL_EXPORT +#endif + +// Values returned for error conditions +#define ERR -999 +#define DERR -999.999 + +typedef ReactorBase reactor_t; +typedef FlowDevice flowdev_t; +typedef Wall wall_t; + +Cabinet* Cabinet::__storage = 0; +Cabinet* Cabinet::__storage = 0; +Cabinet* Cabinet::__storage = 0; + +inline reactor_t* _reactor(int i) { + return Cabinet::cabinet()->item(i); +} + +inline flowdev_t* _flowdev(int i) { + return Cabinet::cabinet()->item(i); +} + +inline wall_t* _wall(int i) { + return Cabinet::cabinet()->item(i); +} + +inline Kinetics* _kin(int n) { + return Storage::__storage->__ktable[n]; +} + +inline ThermoPhase* _th(int n) { + return Storage::__storage->__thtable[n]; +} + +inline Func1* _func(int i) { + return Cabinet::cabinet()->item(i); +} + +extern "C" { + + + // reactor + + int DLL_EXPORT reactor_new(int type) { + reactor_t* r=0; + if (type == ReactorType) + r = new Reactor(); + else if (type == ReservoirType) + r = new Reservoir(); + else + r = new ReactorBase(); + return Cabinet::cabinet()->add(r); + } + + int DLL_EXPORT reactor_del(int i) { + Cabinet::cabinet()->del(i); + return 0; + } + + int DLL_EXPORT reactor_copy(int i) { + return Cabinet::cabinet()->newCopy(i); + } + + int DLL_EXPORT reactor_assign(int i, int j) { + return Cabinet::cabinet()->assign(i,j); + } + + int DLL_EXPORT reactor_setInitialVolume(int i, double v) { + _reactor(i)->setInitialVolume(v); + return 0; + } + + int DLL_EXPORT reactor_setInitialTime(int i, double t) { + _reactor(i)->setInitialTime(t); + return 0; + } + + int DLL_EXPORT reactor_setThermoMgr(int i, int n) { + _reactor(i)->setThermoMgr(*_th(n)); + return 0; + } + + int DLL_EXPORT reactor_setKineticsMgr(int i, int n) { + reactor_t* r = _reactor(i); + if (r->type() == ReactorType) + ((Reactor*)r)->setKineticsMgr(*_kin(n)); + return 0; + } + + int DLL_EXPORT reactor_advance(int i, double t) { + try { + _reactor(i)->advance(t); + return 0; + } + catch (CanteraError) {return -1;} + } + + double DLL_EXPORT reactor_step(int i, double t) { + return _reactor(i)->step(t); + } + + double DLL_EXPORT reactor_time(int i) { + return _reactor(i)->time(); + } + + double DLL_EXPORT reactor_mass(int i) { + return _reactor(i)->mass(); + } + + double DLL_EXPORT reactor_volume(int i) { + return _reactor(i)->volume(); + } + + double DLL_EXPORT reactor_density(int i) { + return _reactor(i)->density(); + } + + double DLL_EXPORT reactor_temperature(int i) { + return _reactor(i)->temperature(); + } + + double DLL_EXPORT reactor_enthalpy_mass(int i) { + return _reactor(i)->enthalpy_mass(); + } + + double DLL_EXPORT reactor_intEnergy_mass(int i) { + return _reactor(i)->intEnergy_mass(); + } + + double DLL_EXPORT reactor_pressure(int i) { + return _reactor(i)->pressure(); + } + + double DLL_EXPORT reactor_massFraction(int i, int k) { + return _reactor(i)->massFraction(k); + } + + int DLL_EXPORT reactor_setEnergy(int i, int eflag) { + reactor_t* r = _reactor(i); + if (r->type() == ReactorType) ((Reactor*)r)->setEnergy(eflag); + return 0; + } + + int DLL_EXPORT reactor_setArea(int i, double a) { + reactor_t* r = _reactor(i); + if (r->type() == ReactorType) ((Reactor*)r)->setArea(a); + return 0; + } + + int DLL_EXPORT reactor_setExtTemp(int i, double t) { + reactor_t* r = _reactor(i); + if (r->type() == ReactorType) ((Reactor*)r)->setExtTemp(t); + return 0; + } + + int DLL_EXPORT reactor_setExtRadTemp(int i, double t) { + reactor_t* r = _reactor(i); + if (r->type() == ReactorType) ((Reactor*)r)->setExtRadTemp(t); + return 0; + } + + int DLL_EXPORT reactor_setVDotCoeff(int i, double v) { + reactor_t* r = _reactor(i); + if (r->type() == ReactorType) ((Reactor*)r)->setVDotCoeff(v); + return 0; + } + + int DLL_EXPORT reactor_setHeatTransferCoeff(int i, double h) { + reactor_t* r = _reactor(i); + if (r->type() == ReactorType) ((Reactor*)r)->setHeatTransferCoeff(h); + return 0; + } + + int DLL_EXPORT reactor_setEmissivity(int i, double eps) { + reactor_t* r = _reactor(i); + if (r->type() == ReactorType) ((Reactor*)r)->setEmissivity(eps); + return 0; + } + + int DLL_EXPORT reactor_setExtPressure(int i, double p) { + reactor_t* r = _reactor(i); + if (r->type() == ReactorType) ((Reactor*)r)->setExtPressure(p); + return 0; + } + + + // flow devices + + int DLL_EXPORT flowdev_new(int type) { + flowdev_t* r; + switch (type) { + case MFC_Type: + r = new MassFlowController(); break; + case PressureReg_Type: + r = new PressureRegulator(); break; + case Valve_Type: + r = new Valve(); break; + default: + r = new FlowDevice(); + } + return Cabinet::cabinet()->add(r); + } + + int DLL_EXPORT flowdev_del(int i) { + Cabinet::cabinet()->del(i); + return 0; + } + + int DLL_EXPORT flowdev_copy(int i) { + return Cabinet::cabinet()->newCopy(i); + } + + int DLL_EXPORT flowdev_assign(int i, int j) { + return Cabinet::cabinet()->assign(i,j); + } + + int DLL_EXPORT flowdev_install(int i, int n, int m) { + _flowdev(i)->install(*_reactor(n), *_reactor(m) ); + return 0; + } + + double DLL_EXPORT flowdev_massFlowRate(int i) { + return _flowdev(i)->massFlowRate(); + } + + double DLL_EXPORT flowdev_setpoint(int i) { + return _flowdev(i)->setpoint(); + } + + int DLL_EXPORT flowdev_setSetpoint(int i, double v) { + _flowdev(i)->setSetpoint(v); + return 0; + } + + int DLL_EXPORT flowdev_setGains(int i, int n, double* gains) { + _flowdev(i)->setGains(n, gains); + return 0; + } + + int DLL_EXPORT flowdev_getGains(int i, int n, double* gains) { + _flowdev(i)->getGains(n, gains); + return 0; + } + + int DLL_EXPORT flowdev_setParameters(int i, int n, double* v) { + _flowdev(i)->setParameters(n, v); + return 0; + } + + int DLL_EXPORT flowdev_setFunction(int i, int n) { + _flowdev(i)->setFunction(_func(n)); + return 0; + } + + int DLL_EXPORT flowdev_reset(int i) { + _flowdev(i)->reset(); + return 0; + } + + int DLL_EXPORT flowdev_update(int i) { + _flowdev(i)->update(); + return 0; + } + + double DLL_EXPORT flowdev_maxError(int i) { + return _flowdev(i)->maxError(); + } + + int DLL_EXPORT flowdev_ready(int i) { + bool ok = _flowdev(i)->ready(); + if (ok) return 1; + return 0; + } + + + ///////////// Walls /////////////////////// + + + int DLL_EXPORT wall_new(int type) { + wall_t* r; + r = new Wall(); + return Cabinet::cabinet()->add(r); + } + + int DLL_EXPORT wall_del(int i) { + Cabinet::cabinet()->del(i); + return 0; + } + + int DLL_EXPORT wall_copy(int i) { + return Cabinet::cabinet()->newCopy(i); + } + + int DLL_EXPORT wall_assign(int i, int j) { + return Cabinet::cabinet()->assign(i,j); + } + + int DLL_EXPORT wall_install(int i, int n, int m) { + _wall(i)->install(*_reactor(n), *_reactor(m) ); + return 0; + } + + double DLL_EXPORT wall_vdot(int i, double t) { + return _wall(i)->vdot(t); + } + + double DLL_EXPORT wall_Q(int i, double t) { + return _wall(i)->Q(t); + } + + double DLL_EXPORT wall_area(int i) { + return _wall(i)->area(); + } + + int DLL_EXPORT wall_setArea(int i, double v) { + _wall(i)->setArea(v); + return 0; + } + + int DLL_EXPORT wall_setThermalResistance(int i, double rth) { + _wall(i)->setThermalResistance(rth); + return 0; + } + + int DLL_EXPORT wall_setHeatTransferCoeff(int i, double u) { + _wall(i)->setHeatTransferCoeff(u); + return 0; + } + + int DLL_EXPORT wall_setHeatFlux(int i, int n) { + _wall(i)->setHeatFlux(_func(n)); + return 0; + } + + int DLL_EXPORT wall_setExpansionRateCoeff(int i, double k) { + _wall(i)->setExpansionRateCoeff(k); + return 0; + } + + int DLL_EXPORT wall_setExpansionRate(int i, int n) { + _wall(i)->setExpansionRate(_func(n)); + return 0; + } + + int DLL_EXPORT wall_ready(int i) { + if (_wall(i)->ready()) return 1; + else return 0; + } + +} diff --git a/Cantera/clib/src/ctreactor.h b/Cantera/clib/src/ctreactor.h new file mode 100755 index 000000000..79b71d310 --- /dev/null +++ b/Cantera/clib/src/ctreactor.h @@ -0,0 +1,73 @@ +#ifndef CTC_REACTOR_H +#define CTC_REACTOR_H + +#include "clib_defs.h" + +extern "C" { + + int DLL_IMPORT reactor_new(int type); + int DLL_IMPORT reactor_del(int i); + int DLL_IMPORT reactor_copy(int i); + int DLL_IMPORT reactor_assign(int i, int j); + int DLL_IMPORT reactor_setInitialVolume(int i, double v); + int DLL_IMPORT reactor_setInitialTime(int i, double t); + int DLL_IMPORT reactor_setEnergy(int i, int eflag); + int DLL_IMPORT reactor_setThermoMgr(int i, int n); + int DLL_IMPORT reactor_setKineticsMgr(int i, int n); + int DLL_IMPORT reactor_advance(int i, double t); + double DLL_IMPORT reactor_step(int i, double t); + double DLL_IMPORT reactor_time(int i); + double DLL_IMPORT reactor_mass(int i); + double DLL_IMPORT reactor_volume(int i); + double DLL_IMPORT reactor_density(int i); + double DLL_IMPORT reactor_temperature(int i); + double DLL_IMPORT reactor_enthalpy_mass(int i); + double DLL_IMPORT reactor_intEnergy_mass(int i); + double DLL_IMPORT reactor_pressure(int i); + double DLL_IMPORT reactor_massFraction(int i, int k); + + //int DLL_IMPORT reactor_setArea(int i, double a); + //int DLL_IMPORT reactor_setExtTemp(int i, double t); + //int DLL_IMPORT reactor_setExtRadTemp(int i, double t); + //int DLL_IMPORT reactor_setVDotCoeff(int i, double v); + //int DLL_IMPORT reactor_setHeatTransferCoeff(int i, double h); + //int DLL_IMPORT reactor_setEmissivity(int i, double eps); + //int DLL_IMPORT reactor_setExtPressure(int i, double p); + //int DLL_IMPORT reactor_setEnergy(int i, int eflag); + + int DLL_IMPORT flowdev_new(int type); + int DLL_IMPORT flowdev_del(int i); + //int DLL_IMPORT flowdev_copy(int i); + //int DLL_IMPORT flowdev_assign(int i, int j); + int DLL_IMPORT flowdev_install(int i, int n, int m); + double DLL_IMPORT flowdev_massFlowRate(int i); + double DLL_IMPORT flowdev_setpoint(int i); + int DLL_IMPORT flowdev_setSetpoint(int i, double v); + //int DLL_IMPORT flowdev_setGains(int i, int n, double* gains); + //int DLL_IMPORT flowdev_getGains(int i, int n, double* gains); + int DLL_IMPORT flowdev_setParameters(int i, int n, double* v); + int DLL_IMPORT flowdev_setFunction(int i, int n); + //int DLL_IMPORT flowdev_reset(int i); + //int DLL_IMPORT flowdev_update(int i); + //double DLL_IMPORT flowdev_maxError(int i); + int DLL_IMPORT flowdev_ready(int i); + + int DLL_IMPORT wall_new(int type); + int DLL_IMPORT wall_del(int i); + int DLL_IMPORT wall_copy(int i); + int DLL_IMPORT wall_assign(int i, int j); + int DLL_IMPORT wall_install(int i, int n, int m); + double DLL_IMPORT wall_vdot(int i, double t); + double DLL_IMPORT wall_Q(int i, double t); + double DLL_IMPORT wall_area(int i); + int DLL_IMPORT wall_setArea(int i, double v); + int DLL_IMPORT wall_setThermalResistance(int i, double rth); + int DLL_IMPORT wall_setHeatTransferCoeff(int i, double u); + int DLL_IMPORT wall_setHeatFlux(int i, int n); + int DLL_IMPORT wall_setExpansionRateCoeff(int i, double k); + int DLL_IMPORT wall_setExpansionRate(int i, int n); + int DLL_IMPORT wall_ready(int i); + +} + +#endif diff --git a/Cantera/clib/src/ctrpath.cpp b/Cantera/clib/src/ctrpath.cpp new file mode 100755 index 000000000..3373fff3b --- /dev/null +++ b/Cantera/clib/src/ctrpath.cpp @@ -0,0 +1,189 @@ + +// Build as a DLL under Windows +#ifdef WIN32 +#define DLL_EXPORT __declspec(dllexport) +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#else +#define DLL_EXPORT +#endif + + +// Cantera includes +#include "ReactionPath.h" + +#include "Cabinet.h" +#include "Storage.h" + +// Values returned for error conditions +#define ERR -999 +#define DERR -999.999 + +typedef ReactionPathDiagram diag_t; +typedef ReactionPathBuilder builder_t; + +Cabinet* Cabinet::__storage = 0; +Cabinet* Cabinet::__storage = 0; + +inline ReactionPathDiagram* _diag(int i) { + return Cabinet::cabinet()->item(i); +} + +inline builder_t* _builder(int i) { + return Cabinet::cabinet()->item(i); +} + +inline Kinetics* _kin(int n) { + return Storage::__storage->__ktable[n]; +} + +extern "C" { + + int DLL_EXPORT rdiag_new() { + diag_t* d = new ReactionPathDiagram(); + return Cabinet::cabinet()->add(d); + } + + int DLL_EXPORT rdiag_del(int i) { + Cabinet::cabinet()->del(i); + return 0; + } + + int DLL_EXPORT rdiag_copy(int i) { + return Cabinet::cabinet()->newCopy(i); + } + + int DLL_EXPORT rdiag_assign(int i, int j) { + return Cabinet::cabinet()->assign(i,j); + } + + int DLL_EXPORT rdiag_detailed(int i) { + _diag(i)->show_details = true; + return 0; + } + + int DLL_EXPORT rdiag_brief(int i) { + _diag(i)->show_details = false; + return 0; + } + + int DLL_EXPORT rdiag_setThreshold(int i, double v) { + _diag(i)->threshold = v; + return 0; + } + + int DLL_EXPORT rdiag_setBoldColor(int i, char* color) { + _diag(i)->bold_color = string(color); + return 0; + } + + int DLL_EXPORT rdiag_setNormalColor(int i, char* color) { + _diag(i)->normal_color = string(color); + return 0; + } + + int DLL_EXPORT rdiag_setDashedColor(int i, char* color) { + _diag(i)->dashed_color = string(color); + return 0; + } + + int DLL_EXPORT rdiag_setDotOptions(int i, char* opt) { + _diag(i)->dot_options = string(opt); + return 0; + } + + int DLL_EXPORT rdiag_setFont(int i, char* font) { + _diag(i)->setFont(string(font)); + return 0; + } + + int DLL_EXPORT rdiag_setBoldThreshold(int i, double v) { + _diag(i)->bold_min = v; + return 0; + } + + int DLL_EXPORT rdiag_setNormalThreshold(int i, double v) { + _diag(i)->dashed_max = v; + return 0; + } + + int DLL_EXPORT rdiag_setLabelThreshold(int i, double v) { + _diag(i)->label_min = v; + return 0; + } + + int DLL_EXPORT rdiag_setScale(int i, double v) { + _diag(i)->scale = v; + return 0; + } + + int DLL_EXPORT rdiag_setFlowType(int i, int iflow) { + if (iflow == 0) + _diag(i)->flow_type = OneWayFlow; + else + _diag(i)->flow_type = NetFlow; + return 0; + } + + int DLL_EXPORT rdiag_setArrowWidth(int i, double v) { + _diag(i)->arrow_width = v; + return 0; + } + + int DLL_EXPORT rdiag_setTitle(int i, char* title) { + _diag(i)->title = string(title); + return 0; + } + + int DLL_EXPORT rdiag_add(int i, int n) { + _diag(i)->add(*_diag(n)); + return 0; + } + + int DLL_EXPORT rdiag_findMajor(int i, double threshold, + int lda, double* a) { + _diag(i)->findMajorPaths(threshold, lda, a); + return 0; + } + + int DLL_EXPORT rdiag_write(int i, int fmt, char* fname) { + ofstream f(fname); + if (fmt == 0) + _diag(i)->exportToDot(f); + else + _diag(i)->writeData(f); + f.close(); + return 0; + } + + int DLL_EXPORT rdiag_displayOnly(int i, int k) { + _diag(i)->displayOnly(k); + return 0; + } + + int DLL_EXPORT rbuild_new() { + builder_t* d = new ReactionPathBuilder(); + return Cabinet::cabinet()->add(d); + } + + int DLL_EXPORT rbuild_del(int i) { + Cabinet::cabinet()->del(i); + return 0; + } + + int DLL_EXPORT rbuild_init(int i, char* logfile, int k) { + ofstream flog(logfile); + _builder(i)->init(flog, *_kin(k)); + return 0; + } + + int DLL_EXPORT rbuild_build(int i, int k, char* el, char* dotfile, + int idiag, int iquiet) { + ofstream fdot(dotfile); + bool quiet = false; + if (iquiet > 0) quiet = true; + _builder(i)->build(*_kin(k), string(el), fdot, *_diag(idiag), quiet); + return 0; + } + +} diff --git a/Cantera/clib/src/ctrpath.h b/Cantera/clib/src/ctrpath.h new file mode 100755 index 000000000..f0397fe10 --- /dev/null +++ b/Cantera/clib/src/ctrpath.h @@ -0,0 +1,37 @@ +#ifndef CTC_RXNPATH_H +#define CTC_RXNPATH_H + +#include "clib_defs.h" + +extern "C" { + + int DLL_IMPORT rdiag_new(); + int DLL_IMPORT rdiag_del(int i); + int DLL_IMPORT rdiag_detailed(int i); + int DLL_IMPORT rdiag_brief(int i); + int DLL_IMPORT rdiag_setThreshold(int i, double v); + int DLL_IMPORT rdiag_setBoldColor(int i, char* color); + int DLL_IMPORT rdiag_setNormalColor(int i, char* color); + int DLL_IMPORT rdiag_setDashedColor(int i, char* color); + int DLL_IMPORT rdiag_setDotOptions(int i, char* opt); + int DLL_IMPORT rdiag_setBoldThreshold(int i, double v); + int DLL_IMPORT rdiag_setNormalThreshold(int i, double v); + int DLL_IMPORT rdiag_setLabelThreshold(int i, double v); + int DLL_IMPORT rdiag_setScale(int i, double v); + int DLL_IMPORT rdiag_setFlowType(int i, int iflow); + int DLL_IMPORT rdiag_setArrowWidth(int i, double v); + int DLL_IMPORT rdiag_setTitle(int i, char* title); + int DLL_IMPORT rdiag_write(int i, int fmt, char* fname); + int DLL_IMPORT rdiag_add(int i, int n); + int DLL_IMPORT rdiag_findMajor(int i, double threshold, int lda, double* a); + int DLL_IMPORT rdiag_setFont(int i, char* font); + int DLL_IMPORT rdiag_displayOnly(int i, int k); + + int DLL_IMPORT rbuild_new(); + int DLL_IMPORT rbuild_del(int i); + int DLL_IMPORT rbuild_init(int i, char* logfile, int k); + int DLL_IMPORT rbuild_build(int i, int k, char* el, char* dotfile, + int idiag, int iquiet); +} + +#endif diff --git a/Cantera/clib/src/ctstagn.cpp b/Cantera/clib/src/ctstagn.cpp new file mode 100755 index 000000000..68bc7d0d0 --- /dev/null +++ b/Cantera/clib/src/ctstagn.cpp @@ -0,0 +1,452 @@ + +// Cantera includes +#include "oneD/OneDim.h" +#include "oneD/StFlow.h" +#include "oneD/Inlet1D.h" +#include "oneD/MultiNewton.h" +#include "DenseMatrix.h" +#include "Cabinet.h" +#include "Storage.h" + +// Build as a DLL under Windows +#ifdef WIN32 +#define DLL_EXPORT __declspec(dllexport) +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#else +#define DLL_EXPORT +#endif + +// Values returned for error conditions +#define ERR -999 +#define DERR -999.999 + +using namespace FlowBdry; + +Cabinet* Cabinet::__storage = 0; +Cabinet* Cabinet::__storage = 0; +Cabinet* Cabinet::__storage = 0; +//Cabinet* Cabinet::__storage = 0; + +inline OneDim* _onedim(int i) { + return Cabinet::cabinet()->item(i); +} + +inline StFlow* _flow(int i) { + return Cabinet::cabinet()->item(i); +} + +inline Boundary* _boundary(int i) { + return Cabinet::cabinet()->item(i); +} + +inline Bdry1D* _bndry(int i) { + return Cabinet::cabinet()->item(i); +} + +//inline SurfKinetics* _surfkin(int i) { +// return Cabinet::cabinet()->item(i); +//} + +//inline Surf1D* _surface(int i) { +// return Cabinet::cabinet()->item(i); +//} + +inline DenseMatrix* _matrix(int i) { + return Cabinet::cabinet()->item(i); +} + +inline ThermoPhase* _phase(int n) { + return Storage::__storage->__thtable[n]; +} + +inline Kinetics* _kinetics(int n) { + return Storage::__storage->__ktable[n]; +} + +inline ThermoPhase* _thermo(int n) { + return Storage::__storage->__thtable[n]; +} + +inline Transport* _transport(int n) { + return Storage::__storage->__trtable[n]; +} + + +extern "C" { + + int DLL_EXPORT flow_new(int type, int iph, int np) { + IdealGasPhase* ph = (IdealGasPhase*)_thermo(iph); + StFlow* x; + try { + switch (type) { + case 0: + x = new AxiStagnFlow(ph, ph->nSpecies(), np); break; + case 1: + x = new OneDFlow(ph, ph->nSpecies(), np); break; + default: + return -2; + } + return Cabinet::cabinet()->add(x); + } + catch (CanteraError) { return -1; } + } + + + int DLL_EXPORT flow_del(int i) { + Cabinet::cabinet()->del(i); + return 0; + } + + int DLL_EXPORT flow_copy(int i) { + return Cabinet::cabinet()->newCopy(i); + } + + int DLL_EXPORT flow_assign(int i, int j) { + return Cabinet::cabinet()->assign(i,j); + } + +// int DLL_EXPORT flow_readinputs(int i, char* infile) { +// try { +// ifstream f(infile); +// if (!f) throw CanteraError("flow_readinputs", +// "error opening input file"); +// // _flow(i)->readInputs(f); +// f.close(); +// return 0; +// } +// catch (CanteraError) { return -1; } +// catch (...) { return ERR; } +// } + + int DLL_EXPORT flow_setupgrid(int i, int npts, double* grid) { + try { + _flow(i)->setupGrid(npts, grid); + return 0; + } + catch (CanteraError) { return -1; } + //catch (...) { return ERR; } + } + + int DLL_EXPORT flow_setthermo(int i, int k) { + IdealGasPhase* th = (IdealGasPhase*)_thermo(k); + _flow(i)->setThermo(*th); + return 0; + } + + int DLL_EXPORT flow_setkinetics(int i, int k) { + Kinetics* kin = _kinetics(k); + _flow(i)->setKinetics(*kin); + return 0; + } + + int DLL_EXPORT flow_settransport(int i, int k, int soret) { + try { + Transport* tr = _transport(k); + bool withSoret = (soret == 1); + _flow(i)->setTransport(*tr, withSoret); + return 0; + } + catch (CanteraError) { return -1; } + } + + int DLL_EXPORT flow_settemperature(int i, int j, double t) { + _flow(i)->setTemperature(j, t); + return 0; + } + + int DLL_EXPORT flow_setmassfraction(int i, int j, int k, double t) { + _flow(i)->setMassFraction(j, k, t); + return 0; + } + + int DLL_EXPORT flow_setpressure(int i, double p) { + _flow(i)->setPressure(p); + return 0; + } + + int DLL_EXPORT flow_showsolution(int i, char* fname, double* soln) { + string fn = string(fname); + if (fn == "-") + _flow(i)->showSolution(cout, soln); + else { + ofstream fout(fname); + _flow(i)->showSolution(fout, soln); + fout.close(); + } + return 0; + } + + int DLL_EXPORT flow_outputtec(int i, doublereal* x, + char* fname, char* title, int zone) { + ofstream f(fname); + //DenseMatrix* mat = _matrix(m); + _flow(i)->outputTEC(f, x, string(title), zone); + return 0; + } + + + // solve / fix + + int DLL_EXPORT flow_solveenergyeqn(int i, int j) { + _flow(i)->solveEnergyEqn(j); + return 0; + } + + int DLL_EXPORT flow_fixtemperature(int i, int j) { + _flow(i)->fixTemperature(j); + return 0; + } + + int DLL_EXPORT flow_setenergyfactor(int i, double e) { + _flow(i)->setEnergyFactor(e); + return 0; + } + + int DLL_EXPORT flow_fixspecies(int i, int j) { + _flow(i)->fixSpecies(j); + return 0; + } + + int DLL_EXPORT flow_solvespecies(int i, int j) { + _flow(i)->solveSpecies(j); + return 0; + } + + int DLL_EXPORT flow_resize(int i, int points) { + _flow(i)->resize(points); + return 0; + } + +// int DLL_EXPORT flow_integratechem(int i, doublereal* x, double dt) { +// try{ +// _flow(i)->integrateChem(x, dt); +// return 0; +// } +// catch (CanteraError) { return -1; } +// } + + int DLL_EXPORT flow_settolerances(int i, int nr, + doublereal* rtol, int na, doublereal* atol) { + try { + _flow(i)->setTolerances(nr, rtol, na, atol); + return 0; + } + catch (CanteraError) { return -1; } + //catch (...) { return ERR; } + } + + int DLL_EXPORT flow_eval(int i, int j, doublereal* x, doublereal* r, integer* m) { + try { + _flow(i)->eval(j, x, r, m); + return 0; + } + catch (CanteraError) { return -1; } + } + + int DLL_EXPORT flow_restore(int i, int job, char* fname, char* id, + int& size_z, doublereal* z, int& size_soln, doublereal* soln) { + try { + _flow(i)->restore(job, fname, string(id), size_z, z, + size_soln, soln); + return 0; + } + catch (CanteraError) { return -1; } + catch (...) { return ERR; } + } + + int DLL_EXPORT flow_setfixedpoint(int i, int j0, doublereal t0) { + _flow(i)->setFixedPoint(j0, t0); + return 0; + } + + + int DLL_EXPORT flow_setboundaries(int i, int nleft, int nright) { + Boundary *left=0, *right=0; + if (nleft > 0) left = _boundary(nleft); + if (nright > 0) right = _boundary(nright); + _flow(i)->setBoundaries(left, right); + return 0; + } + + + //========================================================== + + int DLL_EXPORT bdry_new(int type, int iph, int kin) { + Boundary* x=0; + //const doublereal* wt = _phase(iph)->molecularWeights().begin(); + int nsp = _phase(iph)->nSpecies(); + switch (type) { + case 0: + x = new Inlet(nsp); break; + case 1: + x = new Outlet(nsp); break; + //case 2: + //if (kin > 0) + // x = new Surface(nsp, _surfkin(kin)); + //else + // x = new Surface(nsp, 0); + //break; + case 3: + x = new SymmPlane(nsp); break; + default: + return -2; + } + return Cabinet::cabinet()->add(x); + } + + + int DLL_EXPORT bdry_del(int i) { + Cabinet::cabinet()->del(i); + return 0; + } + + int DLL_EXPORT bdry_copy(int i) { + return Cabinet::cabinet()->newCopy(i); + } + + int DLL_EXPORT bdry_assign(int i, int j) { + return Cabinet::cabinet()->assign(i,j); + } + + int DLL_EXPORT bdry_set(int i, int n, doublereal* v) { + switch (n) { + case 1: + _boundary(i)->set_mdot(*v); break; + case 2: + _boundary(i)->set_V(*v); break; + case 3: + _boundary(i)->set_T(*v); break; + case 4: + _boundary(i)->set_Y(v); break; + default: + throw CanteraError("bdry_set","unknown option"); + } + return 0; + } + + //========================================================= + + + int DLL_EXPORT onedim_new(int nd, int* domains, int* types) { + int i; + vector doms; + for (i = 0; i < nd; i++) { + switch (types[i]) { + case 0: + doms.push_back(_flow(domains[i])); break; + //case 1: + //doms.push_back(_surface(domains[i])); break; + case 2: + doms.push_back(_bndry(domains[i])); break; + default: + throw CanteraError("onedim_new", "unknown domain type"); + } + } + try { + OneDim* x = new OneDim(doms); + return Cabinet::cabinet()->add(x); + } + catch (CanteraError) { return -1; } + } + + + int DLL_EXPORT onedim_del(int i) { + Cabinet::cabinet()->del(i); + return 0; + } + + int DLL_EXPORT onedim_addFlow(int i, int n) { + try { + _onedim(i)->addDomain(_flow(n)); + return 0; + } + catch (CanteraError) { return -1; } + // catch (...) { return ERR; } + } + +// int DLL_EXPORT onedim_addSurf(int i, int n) { +// try { +// _onedim(i)->addDomain(_surface(n)); +// return 0; +// } +// catch (CanteraError) { return -1; } +// } + + int DLL_EXPORT onedim_eval(int i, doublereal* x0, doublereal* r) { + try { + _onedim(i)->eval(-1, x0, r, 0.0); + return 0; + } + catch (CanteraError) { return -1; } + // catch (...) { return ERR; } + } + + int DLL_EXPORT onedim_solve(int i, doublereal* x0, doublereal* x1, + int loglevel) { + try { + int m = _onedim(i)->solve(x0, x1, loglevel); + return m; + } + catch (CanteraError) { return -1; } + //catch (...) { return ERR; } + } + + double DLL_EXPORT onedim_ssnorm(int i, doublereal* x0, doublereal* x1) { + return _onedim(i)->ssnorm(x0, x1); + } + + int DLL_EXPORT onedim_setsteadymode(int i) { + if (_onedim(i)->transient()) { + _onedim(i)->setSteadyMode(); + //_onedim(i)->jacobian().setAge(10000); + return 1; + } + return 0; + } + + int DLL_EXPORT onedim_settransientmode(int i, doublereal dt, doublereal* x) { + _onedim(i)->initTimeInteg(dt, x); + double rr = fabs(_onedim(i)->rdt()*dt - 1.0); + if ((rr > 1.e-5) || _onedim(i)->steady()) { + //_onedim(i)->jacobian().setAge(10000); + return 1; + } + return 0; + } + + int DLL_EXPORT onedim_setnewtonoptions(int i, int maxage) { + _onedim(i)->newton().setOptions(maxage); + return 0; + } + + int DLL_EXPORT onedim_resize(int i) { + _onedim(i)->resize(); + return 0; + } + + int DLL_EXPORT onedim_writeStats(int i) { + _onedim(i)->writeStats(); + return 0; + } + + double DLL_EXPORT onedim_timestep(int i, int nsteps, doublereal dt, + doublereal* x, doublereal* xnew, int loglevel) { + try { + return _onedim(i)->timeStep(nsteps, dt, x, xnew, loglevel); + } + catch (CanteraError) { return -1.0; } + } + + int DLL_EXPORT onedim_save(int i, char* fname, char* id, + char* desc, doublereal* soln) { + try { + _onedim(i)->save(string(fname), string(id), string(desc), soln); + return 0; + } + catch (CanteraError) { return -1; } + //catch (...) { return ERR; } + } + + +} diff --git a/Cantera/clib/src/ctstagn.h b/Cantera/clib/src/ctstagn.h new file mode 100755 index 000000000..5a8ca2625 --- /dev/null +++ b/Cantera/clib/src/ctstagn.h @@ -0,0 +1,71 @@ +#ifndef CTC_STAGN_H +#define CTC_STAGN_H + +// Cantera includes +//#include "stagn.h" + +//#include "Cabinet.h" +//#include "Storage.h" +#include "clib_defs.h" + +//inline StFlow* _flow(int i) { +// return Cabinet::cabinet()->item(i); +//} + +extern "C" { + + int DLL_IMPORT flow_new(int type, int iph, int np); + int DLL_IMPORT flow_del(int i); + int DLL_IMPORT flow_copy(int i); + int DLL_IMPORT flow_assign(int i, int j); + int DLL_IMPORT flow_setupgrid(int i, int npts, double* grid); + int DLL_EXPORT flow_setthermo(int i, int k); + int DLL_IMPORT flow_setkinetics(int i, int k); + int DLL_IMPORT flow_settransport(int i, int k, int soret); + int DLL_IMPORT flow_solveenergyeqn(int i, int j); + int DLL_IMPORT flow_fixtemperature(int i, int j); + int DLL_IMPORT flow_setenergyfactor(int i, double e); + int DLL_IMPORT flow_fixspecies(int i, int j); + int DLL_IMPORT flow_solvespecies(int i, int j); + // int DLL_IMPORT flow_integratechem(int i, double* x, double dt); + int DLL_IMPORT flow_settemperature(int i, int j, double t); + int DLL_IMPORT flow_setpressure(int i, double p); + int DLL_IMPORT flow_setmassfraction(int i, int j, int k, double t); + int DLL_IMPORT flow_outputtec(int i, double* x, char* fname, + char* title, int zone); + int DLL_IMPORT flow_showsolution(int i, char* fname, double* x); + int DLL_IMPORT flow_settolerances(int i, int nr, + double* rtol, int na, double* atol); + int DLL_IMPORT flow_resize(int i, int points); + int DLL_IMPORT flow_setsteadymode(int i); + int DLL_IMPORT flow_settransientmode(int i, double dt, double* x); + + int DLL_IMPORT flow_restore(int i, int job, char* fname, char* id, + int& size_z, double* z, int& size_soln, double* soln); + int DLL_IMPORT flow_setfixedpoint(int i, int j0, double t0); + int DLL_IMPORT flow_setboundaries(int i, int nleft, int nright); + int DLL_IMPORT bdry_new(int type, int iph, int kin); + int DLL_IMPORT bdry_del(int i); + int DLL_IMPORT bdry_copy(int i); + int DLL_IMPORT bdry_assign(int i, int j); + int DLL_IMPORT bdry_set(int i, int n, double* v); + + int DLL_IMPORT onedim_new(int nd, int* domains, int* types); + int DLL_IMPORT onedim_del(int i); + int DLL_IMPORT onedim_addFlow(int i, int n); + //int DLL_IMPORT onedim_addSurf(int i, int n); + int DLL_EXPORT onedim_eval(int i, double* x0, double* r); + int DLL_IMPORT onedim_solve(int i, double* x0, double* x1, int loglevel); + double DLL_IMPORT onedim_ssnorm(int i, double* x0, double* x1); + int DLL_IMPORT onedim_setsteadymode(int i); + int DLL_IMPORT onedim_settransientmode(int i, double dt, double* x); + int DLL_IMPORT onedim_setnewtonoptions(int i, int maxage); + int DLL_IMPORT onedim_resize(int i); + int DLL_IMPORT onedim_writeStats(int i); + double DLL_IMPORT onedim_timestep(int i, int nsteps, double dt, + double* x, double* xnew, int loglevel); + int DLL_IMPORT onedim_save(int i, char* fname, char* id, char* desc, double* soln); + +} + +#endif diff --git a/Cantera/clib/src/ctsurf.cpp b/Cantera/clib/src/ctsurf.cpp new file mode 100755 index 000000000..46e329b3b --- /dev/null +++ b/Cantera/clib/src/ctsurf.cpp @@ -0,0 +1,86 @@ + +// Cantera includes +#include "SurfPhase.h" +#include "InterfaceKinetics.h" + +#include "Cabinet.h" +#include "Storage.h" + +// Build as a DLL under Windows +#ifdef WIN32 +#define DLL_EXPORT __declspec(dllexport) +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#else +#define DLL_EXPORT +#endif + +// Values returned for error conditions +#define ERR -999 +#define DERR -999.999 + + +//Cabinet* Cabinet::__storage = 0; + +//inline Surf1D* _surface(int i) { +// return Cabinet::cabinet()->item(i); +//} + +inline SurfPhase* _surfphase(int n) { + return (SurfPhase*)Storage::__storage->__thtable[n]; +} + +inline InterfaceKinetics* _surfkin(int n) { + return (InterfaceKinetics*)Storage::__storage->__ktable[n]; +} + + +extern "C" { + +// int DLL_EXPORT surface_new(int ikin) { +// InterfaceKinetics* sk = 0; +// if (ikin > 0) sk = _surfkin(ikin); +// Surf1D* s = new Surf1D(sk); +// return Cabinet::cabinet()->add(s); +// } + +// int DLL_EXPORT surface_del(int i) { +// Cabinet::cabinet()->del(i); +// return 0; +// } + + + int DLL_EXPORT surf_setsitedensity(int i, double s0) { + _surfphase(i)->setSiteDensity(s0); + return 0; + } + + double DLL_EXPORT surf_sitedensity(int i) { + return _surfphase(i)->siteDensity(); + } + + int DLL_EXPORT surf_setcoverages(int i, double* c) { + _surfphase(i)->setCoverages(c); + return 0; + } + + int DLL_EXPORT surf_getcoverages(int i, double* c) { + _surfphase(i)->getCoverages(c); + return 0; + } + + int DLL_EXPORT surf_setconcentrations(int i, double* c) { + _surfphase(i)->setConcentrations(c); + return 0; + } + + int DLL_EXPORT surf_getconcentrations(int i, double* c) { + _surfphase(i)->getConcentrations(c); + return 0; + } + +// int DLL_EXPORT surface_setcoverages(int i, double* c) { +// _surface(i)->setCoverages(c); +// return 0; +// } +} diff --git a/Cantera/clib/src/ctsurf.h b/Cantera/clib/src/ctsurf.h new file mode 100755 index 000000000..03123173a --- /dev/null +++ b/Cantera/clib/src/ctsurf.h @@ -0,0 +1,54 @@ +#ifndef CTC_SURF_H +#define CTC_SURF_H + +// Cantera includes +//#include "surface.h" + +//#include "Cabinet.h" +//#include "Storage.h" +#include "clib_defs.h" + +extern "C" { + + int DLL_IMPORT surface_new(int ikin); + int DLL_IMPORT surface_del(int i); + + int DLL_IMPORT surfphase_new(); + int DLL_IMPORT surf_del(int i); + int DLL_IMPORT surf_copy(int i); + int DLL_IMPORT surf_assign(int i, int j); + int DLL_IMPORT surf_addspecies(int i, char* nm, double sz); + int DLL_IMPORT surf_nspecies(int i); + int DLL_IMPORT surf_freezespecies(int i); + int DLL_IMPORT surf_setcoverages(int i, double* c); + int DLL_IMPORT surf_getcoverages(int i, double* c); + int DLL_IMPORT surf_setconcentrations(int i, double* c); + int DLL_IMPORT surf_getconcentrations(int i, double* c); + int DLL_IMPORT surf_setsitedensity(int i, double s0); + double DLL_IMPORT surf_sitedensity(int i); + int DLL_IMPORT surf_doc(int i, char* key, char* value); + + int DLL_IMPORT surfkin_new(int iph, int ith1, int ith2); + int DLL_IMPORT surfkin_del(int i); + int DLL_IMPORT surfkin_addreaction(int i, int nr, int* r, + int* rst, int* ro, int np, int* p, int* pst, + int nrate, double* rateParams); + int DLL_IMPORT surfkin_nreactions(int i); + int DLL_IMPORT surfkin_getratesofprogress(int i, double* rop); + int DLL_IMPORT surfkin_getnetproductionrates(int i, double* sdot); + int DLL_IMPORT surfkin_integrate(int i, double dt); + int DLL_IMPORT surfkin_save(int i, char* fname, char* id, char* comment); + + int DLL_IMPORT surface_settolerances(int i, int nr, + double* rtol, int na, double* atol); + int DLL_IMPORT surface_fixspecies(int i, int k, double c=-1.0); + int DLL_IMPORT surface_solvespecies(int i, int k); + int DLL_IMPORT surface_setmultiplier(int i, int k, double f); + double DLL_IMPORT surface_multiplier(int i, int k); + double DLL_IMPORT surface_temperature(int i); + int DLL_IMPORT surface_settemperature(int i, double t); + int DLL_IMPORT surface_setcoverages(int i, double* c); + +} + +#endif diff --git a/Cantera/clib/src/ctxml.cpp b/Cantera/clib/src/ctxml.cpp new file mode 100644 index 000000000..198e8c92d --- /dev/null +++ b/Cantera/clib/src/ctxml.cpp @@ -0,0 +1,235 @@ + +// Cantera includes +#include "ctml.h" + +#include "Cabinet.h" +#include "Storage.h" + +// Build as a DLL under Windows +#ifdef WIN32 +#define DLL_EXPORT __declspec(dllexport) +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#else +#define DLL_EXPORT +#endif + +// Values returned for error conditions +#define ERR -999 +#define DERR -999.999 + +Cabinet* Cabinet::__storage = 0; + +inline XML_Node* _xml(int i) { + return Cabinet::cabinet()->item(i); +} + +extern "C" { + + int DLL_EXPORT xml_new(const char* name = 0) { + XML_Node* x; + if (!name) x = new XML_Node; + else x = new XML_Node(string(name)); + return Cabinet::cabinet()->add(x); + } + + int DLL_EXPORT xml_del(int i) { + Cabinet::cabinet()->del(i); + return 0; + } + + int DLL_EXPORT xml_removeChild(int i, int j) { + _xml(i)->removeChild(_xml(j)); + return 0; + } + + int DLL_EXPORT xml_copy(int i) { + return Cabinet::cabinet()->newCopy(i); + } + + int DLL_EXPORT xml_assign(int i, int j) { + return Cabinet::cabinet()->assign(i,j); + } + + int DLL_EXPORT xml_build(int i, const char* file) { + try { + string path = findInputFile(string(file)); + ifstream f(path.c_str()); + if (!f) { + throw CanteraError("xml_build", + "file "+string(file)+" not found."); + } + _xml(i)->build(f); + f.close(); + return 0; + } + catch (CanteraError) { return -1; } + } + + int DLL_EXPORT xml_attrib(int i, const char* key, char* value) { + try { + string ky = string(key); + XML_Node& node = *_xml(i); + if (node.hasAttrib(ky)) { + string v = node[ky]; + strncpy(value, v.c_str(), 80); + } + else + throw CanteraError("xml_attrib","node " + " has no attribute '"+ky+"'"); + } + catch (CanteraError) { return -1; } + return 0; + } + + int DLL_EXPORT xml_addAttrib(int i, const char* key, const char* value) { + try { + string ky = string(key); + string val = string(value); + XML_Node& node = *_xml(i); + node.addAttribute(ky, val); + } + catch (CanteraError) { return -1; } + return 0; + } + + int DLL_EXPORT xml_tag(int i, char* tag) { + try { + XML_Node& node = *_xml(i); + const string v = node.name(); + strncpy(tag, v.c_str(), 80); + } + catch (CanteraError) { return -1; } + return 0; + } + + int DLL_EXPORT xml_value(int i, char* value) { + try { + XML_Node& node = *_xml(i); + const string v = node.value(); + strncpy(value, v.c_str(), 80); + } + catch (CanteraError) { return -1; } + return 0; + } + + int DLL_EXPORT xml_child(int i, const char* loc) { + try { + XML_Node& node = *_xml(i); + XML_Node& c = node.child(string(loc)); + return Cabinet::cabinet()->add(&c); + } + catch (CanteraError) { return -1; } + return 0; + } + + int DLL_EXPORT xml_child_bynumber(int i, int m) { + try { + XML_Node& node = *_xml(i); + XML_Node& c = node.child(m); + return Cabinet::cabinet()->add(&c); + } + catch (CanteraError) { return -1; } + return 0; + } + + int DLL_EXPORT xml_findID(int i, const char* id) { + try { + XML_Node& node = *_xml(i); + XML_Node* c = node.findID(string(id)); + if (c) { + return Cabinet::cabinet()->add(c); + } + else + throw CanteraError("xml_find_id","id not found: "+string(id)); + } + catch (CanteraError) { return -1; } + return 0; + } + + int DLL_EXPORT xml_findByName(int i, const char* nm) { + try { + XML_Node& node = *_xml(i); + XML_Node* c = node.findByName(string(nm)); + if (c) { + return Cabinet::cabinet()->add(c); + } + else + throw CanteraError("xml_findByName","name "+string(nm) + +" not found"); + } + catch (CanteraError) { return -1; } + return 0; + } + + int DLL_EXPORT xml_nChildren(int i) { + try { + XML_Node& node = *_xml(i); + return node.nChildren(); + } + catch (CanteraError) { return -1; } + } + + int DLL_EXPORT xml_addChild(int i, const char* name, const char* value) { + try { + XML_Node& node = *_xml(i); + XML_Node& c = node.addChild(string(name),string(value)); + return Cabinet::cabinet()->add(&c); + } + catch (CanteraError) { showErrors(cout); return -1; } + return 0; + } + + int DLL_EXPORT xml_addChildNode(int i, int j) { + try { + XML_Node& node = *_xml(i); + XML_Node& chld = *_xml(j); + XML_Node& c = node.addChild(chld); + return Cabinet::cabinet()->add(&c); + } + catch (CanteraError) { return -1; } + return 0; + } + + int DLL_EXPORT xml_write(int i, const char* file) { + try { + ofstream f(file); + if (f) { + XML_Node& node = *_xml(i); + node.write(f); + } + else { + throw CanteraError("xml_write", + "file "+string(file)+" not found."); + } + return 0; + } + catch (CanteraError) { return -1; } + return 0; + } + + int DLL_EXPORT ctml_getFloatArray(int i, int n, doublereal* data, int iconvert) { + try { + XML_Node& node = *_xml(i); + vector_fp v; + bool conv = false; + if (iconvert > 0) conv = true; + getFloatArray(node, v, conv); + int nv = v.size(); + + // array not big enough + if (n < nv) { + throw CanteraError("ctml_getFloatArray", + "array must be dimensioned at least "+int2str(nv)); + } + + for (int i = 0; i < nv; i++) { + data[i] = v[i]; + } + n = nv; + } + catch (CanteraError) { return -1; } + return 0; + } + +} diff --git a/Cantera/clib/src/ctxml.h b/Cantera/clib/src/ctxml.h new file mode 100644 index 000000000..4efbe02a9 --- /dev/null +++ b/Cantera/clib/src/ctxml.h @@ -0,0 +1,30 @@ +#ifndef CTC_XML_H +#define CTC_XML_H + +#include "clib_defs.h" + +extern "C" { + + int DLL_IMPORT xml_new(const char* name); + int DLL_IMPORT xml_del(int i); + int DLL_IMPORT xml_copy(int i); + int DLL_IMPORT xml_assign(int i, int j); + int DLL_IMPORT xml_build(int i, const char* file); + int DLL_IMPORT xml_attrib(int i, const char* key, char* value); + int DLL_IMPORT xml_addAttrib(int i, const char* key, const char* value); + int DLL_IMPORT xml_value(int i, char* value); + int DLL_IMPORT xml_tag(int i, char* tag); + int DLL_IMPORT xml_child(int i, const char* loc); + int DLL_IMPORT xml_child_bynumber(int i, int m); + int DLL_IMPORT xml_findID(int i, const char* id); + int DLL_IMPORT xml_findByName(int i, const char* nm); + int DLL_IMPORT xml_nChildren(int i); + int DLL_IMPORT xml_addChild(int i, const char* name, const char* value); + int DLL_IMPORT xml_addChildNode(int i, int j); + int DLL_IMPORT xml_write(int i, const char* file); + int DLL_IMPORT xml_removeChild(int i, int j); + int DLL_IMPORT ctml_getFloatArray(int i, int n, double* data, int iconvert=0); +} + +#endif + diff --git a/Cantera/cxx/README b/Cantera/cxx/README new file mode 100644 index 000000000..258a20e55 --- /dev/null +++ b/Cantera/cxx/README @@ -0,0 +1,3 @@ +This directory contains files that are part of the C++ user +interface. For the kernel C++ files, see directory ../src. + diff --git a/Cantera/lib/README b/Cantera/lib/README new file mode 100755 index 000000000..433f3a24e --- /dev/null +++ b/Cantera/lib/README @@ -0,0 +1,3 @@ + +Library files. + diff --git a/Cantera/matlab/Makefile.in b/Cantera/matlab/Makefile.in new file mode 100644 index 000000000..99e6052f8 --- /dev/null +++ b/Cantera/matlab/Makefile.in @@ -0,0 +1,85 @@ +#/bin/sh +############################################################### +# $Author$ +# $Date$ +# $Revision$ +# +# Copyright 2001 California Institute of Technology +# See file License.txt for licensing information +# +############################################################### + +LIBS = @LOCAL_LIBS@ @LIBS@ @FLIBS@ +SRCS = cantera/private/ctmethods.cpp \ + cantera/private/ctfunctions.cpp \ + cantera/private/xmlmethods.cpp \ + cantera/private/phasemethods.cpp \ + cantera/private/thermomethods.cpp \ + cantera/private/kineticsmethods.cpp \ + cantera/private/transportmethods.cpp \ + cantera/private/reactormethods.cpp \ + cantera/private/wallmethods.cpp \ + cantera/private/flowdevicemethods.cpp + +all: ctmethods.mexmac + +ctmethods.mexmac: $(SRCS) + @PYTHON_CMD@ setup_matlab.py @ctroot@/lib @CT_SHARED_LIB@ '$(LIBS)' + (@MATLAB_CMD@ -nodesktop -nojvm -nosplash -r setup) + rm -f setup.m + +install: + @INSTALL@ -d @prefix@/matlab/toolbox/cantera/cantera + @INSTALL@ -d @prefix@/matlab/toolbox/cantera/cantera-demos + @INSTALL@ -d @prefix@/matlab/toolbox/cantera/cantera/private + @INSTALL@ -d @prefix@/matlab/toolbox/cantera/cantera/@ThermoPhase/private + @INSTALL@ -d @prefix@/matlab/toolbox/cantera/cantera/@Kinetics/private + @INSTALL@ -d @prefix@/matlab/toolbox/cantera/cantera/@Transport/private + @INSTALL@ -d @prefix@/matlab/toolbox/cantera/cantera/@Solution + @INSTALL@ -d @prefix@/matlab/toolbox/cantera/cantera/@XML_Node/private + @INSTALL@ -d @prefix@/matlab/toolbox/cantera/cantera/@Reactor/private + @INSTALL@ -d @prefix@/matlab/toolbox/cantera/cantera/@Wall/private + @INSTALL@ -d @prefix@/matlab/toolbox/cantera/cantera/@FlowDevice/private + cd cantera; @INSTALL@ *.m *.@mex_ext@ @prefix@/matlab/toolbox/cantera/cantera + cd cantera/private; @INSTALL@ *.m \ + @prefix@/matlab/toolbox/cantera/cantera/private + cd cantera/examples; @INSTALL@ *.m @prefix@/matlab/toolbox/cantera/cantera-demos + cd cantera/@ThermoPhase; @INSTALL@ \ + *.m @prefix@/matlab/toolbox/cantera/cantera/@ThermoPhase + cd cantera/@ThermoPhase/private; @INSTALL@ *.m \ + @prefix@/matlab/toolbox/cantera/cantera/@ThermoPhase/private + cd cantera/@Kinetics; @INSTALL@ *.m \ + @prefix@/matlab/toolbox/cantera/cantera/@Kinetics + cd cantera/@Kinetics/private; @INSTALL@ *.m \ + @prefix@/matlab/toolbox/cantera/cantera/@Kinetics/private + cd cantera/@Solution; @INSTALL@ *.m \ + @prefix@/matlab/toolbox/cantera/cantera/@Solution + cd cantera/@Transport; @INSTALL@ *.m \ + @prefix@/matlab/toolbox/cantera/cantera/@Transport + cd cantera/@Transport/private; @INSTALL@ *.m \ + @prefix@/matlab/toolbox/cantera/cantera/@Transport/private + cd cantera/@XML_Node; @INSTALL@ *.m \ + @prefix@/matlab/toolbox/cantera/cantera/@XML_Node + cd cantera/@Reactor; @INSTALL@ *.m \ + @prefix@/matlab/toolbox/cantera/cantera/@Reactor + cd cantera/@Reactor/private; @INSTALL@ *.m \ + @prefix@/matlab/toolbox/cantera/cantera/@Reactor/private + cd cantera/@Wall; @INSTALL@ *.m \ + @prefix@/matlab/toolbox/cantera/cantera/@Wall + cd cantera/@Wall/private; @INSTALL@ *.m \ + @prefix@/matlab/toolbox/cantera/cantera/@Wall/private + cd cantera/@FlowDevice; @INSTALL@ *.m \ + @prefix@/matlab/toolbox/cantera/cantera/@FlowDevice + cd cantera/@FlowDevice/private; @INSTALL@ *.m \ + @prefix@/matlab/toolbox/cantera/cantera/@FlowDevice/private + +clean: + echo '-' + +depends: + echo '-' + +# end of file + + + diff --git a/Cantera/matlab/cantera/@FlowDevice/FlowDevice.m b/Cantera/matlab/cantera/@FlowDevice/FlowDevice.m new file mode 100644 index 000000000..fdb8d8618 --- /dev/null +++ b/Cantera/matlab/cantera/@FlowDevice/FlowDevice.m @@ -0,0 +1,15 @@ +function x = FlowDevice(typ) +% +if nargin == 0 + typ = 1; +end +x.index = flowdevicemethods(0,typ); +if x.index < 0 + error(geterr); +end +x.type = typ; +x.upstream = -1; +x.downstream = -1; +x = class(x,'FlowDevice'); + + diff --git a/Cantera/matlab/cantera/@FlowDevice/clear.m b/Cantera/matlab/cantera/@FlowDevice/clear.m new file mode 100644 index 000000000..7a2fc11e2 --- /dev/null +++ b/Cantera/matlab/cantera/@FlowDevice/clear.m @@ -0,0 +1,4 @@ +function clear(f) +% CLEAR - +% +flowdevicemethods(1, f.index) diff --git a/Cantera/matlab/cantera/@FlowDevice/install.m b/Cantera/matlab/cantera/@FlowDevice/install.m new file mode 100644 index 000000000..f7349f0a2 --- /dev/null +++ b/Cantera/matlab/cantera/@FlowDevice/install.m @@ -0,0 +1,16 @@ +function install(f, upstream, downstream) + +if nargin == 3 + if ~isa(upstream,'Reactor') | ~isa(downstream,'Reactor') + error(['Flow devices can only be installed between reactors or' ... + ' reservoirs']) + end + i = hndl(upstream); + j = hndl(downstream); + ok = flowdevicemethods(2, f.index, i, j); + if ok < 0 + error(geterr) + end +else + error('install requires 3 arguments') +end \ No newline at end of file diff --git a/Cantera/matlab/cantera/@FlowDevice/massFlowRate.m b/Cantera/matlab/cantera/@FlowDevice/massFlowRate.m new file mode 100644 index 000000000..d8e998203 --- /dev/null +++ b/Cantera/matlab/cantera/@FlowDevice/massFlowRate.m @@ -0,0 +1,5 @@ +function mdot = massFlowRate(f) +% MASSFLOWRATE - mass flow rate in kg/s +% +mdot = flowdevicemethods(21, f.index) + diff --git a/Cantera/matlab/cantera/@FlowDevice/private/flowdevicemethods.m b/Cantera/matlab/cantera/@FlowDevice/private/flowdevicemethods.m new file mode 100644 index 000000000..b537c9290 --- /dev/null +++ b/Cantera/matlab/cantera/@FlowDevice/private/flowdevicemethods.m @@ -0,0 +1,13 @@ +function v = flowdevicemethods(n, job, a, b, c, d) +% +if nargin == 2 + v = ctmethods(80, n, job); +elseif nargin == 3 + v = ctmethods(80, n, job, a); +elseif nargin == 4 + v = ctmethods(80, n, job, a, b); +elseif nargin == 5 + v = ctmethods(80, n, job, a, b, c); +elseif nargin == 6 + v = ctmethods(80, n, job, a, b, c, d); +end \ No newline at end of file diff --git a/Cantera/matlab/cantera/@FlowDevice/setMassFlowRate.m b/Cantera/matlab/cantera/@FlowDevice/setMassFlowRate.m new file mode 100644 index 000000000..f4e69ce7b --- /dev/null +++ b/Cantera/matlab/cantera/@FlowDevice/setMassFlowRate.m @@ -0,0 +1,12 @@ +function setMassFlowRate(f, mdot) +% SETMASSFLOWRATE - +% +if f.type == 1 + k = flowdevicemethods(3, f.index, mdot); + if k < 0 + error(geterr); + end +else + error('Mass flow rate can only be set for mass flow controllers') +end + diff --git a/Cantera/matlab/cantera/@FlowDevice/setValveCoeff.m b/Cantera/matlab/cantera/@FlowDevice/setValveCoeff.m new file mode 100644 index 000000000..18381cc42 --- /dev/null +++ b/Cantera/matlab/cantera/@FlowDevice/setValveCoeff.m @@ -0,0 +1,10 @@ +function setValveCoeff(f, k) +% SETVALVECOEFF - set valve coefficient +% +if f.type ~= 3 + error('Valve coefficient can only be set for valves') +end +ok = flowdevicemethods(4, f.index, k); +if ok < 0 + error(geterr); +end \ No newline at end of file diff --git a/Cantera/matlab/cantera/@Kinetics/Kinetics.m b/Cantera/matlab/cantera/@Kinetics/Kinetics.m new file mode 100755 index 000000000..7b73ee38d --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/Kinetics.m @@ -0,0 +1,33 @@ +function k = Kinetics(r, ph, neighbor1, neighbor2) +% KINETICS - Kinetics class constructor. +% +% Class Kinetics represents kinetics managers, which are classes +% that manage reaction mechanisms. The reaction mechanism +% attributes are specified in a CTML file. +% +% +if nargin == 1 + if isa(r,'Kinetics') + % create a copy + k = r; + return + end +elseif nargin == 2 + if isa(r,'XML_Node') + k.owner = 1; + i = hndl(r); + iph = hndl(ph); + ineighbor1 = -1; + ineighbor2 = -1; + k.id = kinetics_get(i,0,iph,ineighbor1,ineighbor2); + if k.id < 0 + error(geterr); + end + else + k.owner = 0; + k.id = r; + end + k = class(k,'Kinetics'); +else + error('wrong number of arguments'); +end diff --git a/Cantera/matlab/cantera/@Kinetics/clear.m b/Cantera/matlab/cantera/@Kinetics/clear.m new file mode 100644 index 000000000..539837d29 --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/clear.m @@ -0,0 +1,5 @@ +function clear(k) +% CLEAR - delete the Kinetics instance. +% +kinetics_set(k.id,3); + diff --git a/Cantera/matlab/cantera/@Kinetics/creationRates.m b/Cantera/matlab/cantera/@Kinetics/creationRates.m new file mode 100755 index 000000000..1336f86f2 --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/creationRates.m @@ -0,0 +1,23 @@ +function cdot = creationRates(a) +% CREATIONRATES Chemical creation rates (kmol/m^3/s). +% +% cdot = creationRates(K) +% +% Returns a column vector of the creation rates of all +% species. If the output is not assigned to a variable, a +% bar graph is produced. +% +% See also: destructionRates, netProdRates. +% +cdot = kinetics_get(a.id,21,0); +if nargout == 0 + figure + set(gcf,'Name','Creation Rates') + bar(cdot) + xlabel('Species Number') + ylabel('Creation Rate (kmol/m^3-s)') + title('Species Chemical Creation Rates') +end + + + diff --git a/Cantera/matlab/cantera/@Kinetics/destructionRates.m b/Cantera/matlab/cantera/@Kinetics/destructionRates.m new file mode 100755 index 000000000..45d35331a --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/destructionRates.m @@ -0,0 +1,23 @@ +function ddot = destructionRates(a) +% destructionRates Chemical destruction rates (kmol/m^3/s). +% +% cdot = destructionRates(a) +% +% Returns a column vector of the destruction rates of all +% species. If the output is not assigned to a variable, a +% bar graph is produced. +% +% See also: creationRates, netProdRates. +% +ddot = kinetics_get(a.id,22,0); +if nargout == 0 + figure + set(gcf,'Name','Destruction Rates') + bar(ddot) + xlabel('Species Number') + ylabel('Destruction Rate (kmol/m^3/s)') + title('Species Chemical Destruction Rates') +end + + + diff --git a/Cantera/matlab/cantera/@Kinetics/destruction_rates.m b/Cantera/matlab/cantera/@Kinetics/destruction_rates.m new file mode 100755 index 000000000..f6913e0d4 --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/destruction_rates.m @@ -0,0 +1,20 @@ +function q = destruction_rates(a) +% destruction_rates Chemical destruction rates for all species. +% +% q = destruction_rates(a) +% +% Returns a column vector of the destruction rates of all species. +% +% See also: creation_rates, net_production_rates. +% +q = production(a.id,nSpecies(a.ph),1); +if nargout == 0 + figure + set(gcf,'Name','Destruction Rates') + bar(q) + xlabel('Species Number') + ylabel('Destruction Rate (kmol/m^3/s)') + title('Species Chemical Destruction Rates') +end + + diff --git a/Cantera/matlab/cantera/@Kinetics/equil_Kc.m b/Cantera/matlab/cantera/@Kinetics/equil_Kc.m new file mode 100755 index 000000000..e6df2a544 --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/equil_Kc.m @@ -0,0 +1,22 @@ +function kc = equil_Kc(a) +% equil_Kc(a) equilibrium constants for all reactions +% +% q = equil_Kc(a) +% +% Returns a column vector of the equilibrium constants +% for all reactions. The vector has an entry for every +% reaction, whether reversible or not, but non-zero values +% occur only for the reversible reactions. +% +% +kc = kinetics_get(a.id,14,0); +if nargout == 0 + figure + set(gcf,'Name','Equilibrium Constants') + bar(log10(kc)) + xlabel('Reaction Number') + ylabel('log_1_0 Kc [kmol, m, s]') + title('Equilibrium Constants Kc') +end + + diff --git a/Cantera/matlab/cantera/@Kinetics/hndl.m b/Cantera/matlab/cantera/@Kinetics/hndl.m new file mode 100755 index 000000000..c031576c8 --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/hndl.m @@ -0,0 +1,2 @@ +function i = hndl(k) +i = k.id; diff --git a/Cantera/matlab/cantera/@Kinetics/isReversible.m b/Cantera/matlab/cantera/@Kinetics/isReversible.m new file mode 100755 index 000000000..41d37f285 --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/isReversible.m @@ -0,0 +1,14 @@ +function yn = isReversible(a, i) +% ISREVERSIBLE - Reversible reaction flag. +% +% A reversible reaction is one that runs in both the forward +% direction (reactants -> products) and in the reverse direction +% (products -> reactants). The reverse rate for reversible +% reactions is computed from thermochemistry, so that the +% reaction satisfies detailed balance, and the net rate of +% progress is zero in states of chemical equilibrium. +% +% ISREVERSIBLE(K, IRXN) returns 1 if reaction number IRXN is +% reversible, and 0 if it is irreversible. +% +yn = kinetics_get(a.id,4,i); diff --git a/Cantera/matlab/cantera/@Kinetics/kinetics_hndl.m b/Cantera/matlab/cantera/@Kinetics/kinetics_hndl.m new file mode 100644 index 000000000..84735db8e --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/kinetics_hndl.m @@ -0,0 +1,6 @@ +function i = kinetics_hndl(k) +% KINETICS_HNDL - integer used to access kernel object +% +i = k.id; + + diff --git a/Cantera/matlab/cantera/@Kinetics/multiplier.m b/Cantera/matlab/cantera/@Kinetics/multiplier.m new file mode 100755 index 000000000..966f23421 --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/multiplier.m @@ -0,0 +1,14 @@ +function n = multiplier(a,irxn) +% MULTIPLIER Multiplier for reaction rate of progress. +% +% The multiplier multiplies the reaction rate of progress. It may +% be used to implement sensitivity analysis, or to selectively +% disable reactions. For reversible reactions, it multiplies both +% the forward and reverse rates. By default, the multiplier value +% is 1.0, but it may be set to any other value by calling method +% setMultiplier. +% +% MULTIPLIER(K, IRXN) Multiplier for reaction number IRXN +% +n = kinetics_get(a.id,2,irxn); + diff --git a/Cantera/matlab/cantera/@Kinetics/nReactions.m b/Cantera/matlab/cantera/@Kinetics/nReactions.m new file mode 100755 index 000000000..63529214a --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/nReactions.m @@ -0,0 +1,5 @@ +function n = nReactions(a) +% NREACTIONS - Number of reactions. +% +n = kinetics_get(a.id,1,0); + diff --git a/Cantera/matlab/cantera/@Kinetics/nTotalSpecies.m b/Cantera/matlab/cantera/@Kinetics/nTotalSpecies.m new file mode 100644 index 000000000..29cde000b --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/nTotalSpecies.m @@ -0,0 +1,5 @@ +function nsp = nTotalSpecies(a) +% NTOTALSPECIES - The total number of species, summed over all +% participating phases. +% +nsp = kinetics_get(a.id, 3, 0); diff --git a/Cantera/matlab/cantera/@Kinetics/netProdRates.m b/Cantera/matlab/cantera/@Kinetics/netProdRates.m new file mode 100755 index 000000000..8d6b4e032 --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/netProdRates.m @@ -0,0 +1,22 @@ +function wdot = netProdRates(a) +% NETPRODRATES Net chemical production rates for all species. +% +% wdot = netProdRates(a) +% +% Returns a column vector of the net production (creation - +% destruction) rates of all species. If the output is not +% assigned to a variable, a bar plot is produced. +% +% See also: creationRates, destructionRates +% +wdot = kinetics_get(a.id,23,0); +if nargout == 0 + figure + set(gcf,'Name','Production Rates') + bar(wdot) + xlabel('Species Number') + ylabel('Net Production Rate (kmol/m^3/s)') + title('Species Net Chemical Production Rates') +end + + diff --git a/Cantera/matlab/cantera/@Kinetics/private/delkinetics.cpp b/Cantera/matlab/cantera/@Kinetics/private/delkinetics.cpp new file mode 100644 index 000000000..be6c3427c --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/private/delkinetics.cpp @@ -0,0 +1,22 @@ + +#include "mex.h" +#include "../../../../clib/src/ct.h" +#include "../../private/ctmatutils.h" + +extern "C" { + + /* + * Create a Cantera 'Kinetics' object + */ + void mexFunction( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) + { + int k = getInt(prhs[0]); + int ok = delKinetics(k); + + // Create matrix for the return argument. + plhs[0] = mxCreateDoubleMatrix(1,1, mxREAL); + double* x = mxGetPr(plhs[0]); + *x = ok; + } +} diff --git a/Cantera/matlab/cantera/@Kinetics/private/isrev.cpp b/Cantera/matlab/cantera/@Kinetics/private/isrev.cpp new file mode 100755 index 000000000..374964eda --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/private/isrev.cpp @@ -0,0 +1,19 @@ + +#include "mex.h" +#include "../../../../clib/src/ct.h" +#include "../../private/ctmatutils.h" + +extern "C" { + + void mexFunction( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) + { + double vv; + int kin = getInt(prhs[0]); + int irxn = getInt(prhs[1]); + vv = kin_isReversible(kin,irxn-1); + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = vv; + } +} diff --git a/Cantera/matlab/cantera/@Kinetics/private/kin_get.cpp b/Cantera/matlab/cantera/@Kinetics/private/kin_get.cpp new file mode 100755 index 000000000..97e79a496 --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/private/kin_get.cpp @@ -0,0 +1,35 @@ + +#include "mex.h" +#include "../../../../clib/src/ct.h" +#include "../../private/ctmatutils.h" + +extern "C" { + + void mexFunction( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) + { + double vv; + int kin = getInt(prhs[0]); + int job = getInt(prhs[1]); + int irxn = getInt(prhs[2]); + + bool ok = true; + switch (job) { + + case 1: + vv = kin_nReactions(kin); break; + case 2: + vv = kin_multiplier(kin, irxn-1); break; + case 3: + vv = kin_nSpecies(kin); break; + default: + ok = false; + } + if (ok) { + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = vv; + return; + } + } +} diff --git a/Cantera/matlab/cantera/@Kinetics/private/kin_set.cpp b/Cantera/matlab/cantera/@Kinetics/private/kin_set.cpp new file mode 100755 index 000000000..d61f6feb5 --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/private/kin_set.cpp @@ -0,0 +1,47 @@ + +#include "mex.h" +#include "../../private/ctmatutils.h" +#include "../../../../clib/src/ct.h" + +extern "C" { + + void reportError() { + int buflen = 300; + char* output_buf = (char*)mxCalloc(buflen, sizeof(char)); + getCanteraError(buflen, output_buf); + mexErrMsgTxt(output_buf); + } + + void mexFunction( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) { + // try { + double vv; + int kin = getInt(prhs[0]); + int job = getInt(prhs[1]); + int irxn = getInt(prhs[2]); + double* ptr = mxGetPr(prhs[3]); + int m = mxGetM(prhs[3]); + int n = mxGetN(prhs[3]); + + // set scalar attributes + int iok = -1; + if (job < 10) { + if (m != 1 || n != 1) + mexErrMsgTxt("value must be scalar."); + + switch (job) { + case 1: + iok = kin_setMultiplier(kin,irxn-1,*ptr); break; + default: + iok = -1; + } + } + if (iok < 0) mexErrMsgTxt("error in kin_set."); + // } + //catch (...) { + // reportError(); + // mexErrMsgTxt("exception in kin_set."); + // return; + // } + } +} diff --git a/Cantera/matlab/cantera/@Kinetics/private/kinetics_get.m b/Cantera/matlab/cantera/@Kinetics/private/kinetics_get.m new file mode 100644 index 000000000..933dce0f0 --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/private/kinetics_get.m @@ -0,0 +1,14 @@ +function v = kinetics_get(n, job, a, b, c, d) +% KINETICS_GET - get kinetics attributes +% +if nargin == 2 + v = ctmethods(40, n, job); +elseif nargin == 3 + v = ctmethods(40, n, job, a); +elseif nargin == 4 + v = ctmethods(40, n, job, a, b); +elseif nargin == 5 + v = ctmethods(40, n, job, a, b, c); +elseif nargin == 6 + v = ctmethods(40, n, job, a, b, c, d); +end \ No newline at end of file diff --git a/Cantera/matlab/cantera/@Kinetics/private/kinetics_set.m b/Cantera/matlab/cantera/@Kinetics/private/kinetics_set.m new file mode 100644 index 000000000..1ac0019f1 --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/private/kinetics_set.m @@ -0,0 +1,6 @@ +function kinetics_set(n, job, a, b) +% KINETICS_SET - get kinetics attributes +% +ctmethods(40, n, -job, a, b) + + diff --git a/Cantera/matlab/cantera/@Kinetics/private/newkinetics.cpp b/Cantera/matlab/cantera/@Kinetics/private/newkinetics.cpp new file mode 100755 index 000000000..24fe22188 --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/private/newkinetics.cpp @@ -0,0 +1,33 @@ + +#include "mex.h" +#include "../../../../clib/src/ct.h" +#include "../../private/ctmatutils.h" + +extern "C" { + + /* + * Create a Cantera 'Kinetics' object + */ + void mexFunction( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) + { + // Check for proper number of arguments + if(nrhs != 4) { + mexErrMsgTxt("Four inputs required."); + } + else if(nlhs > 1) { + mexErrMsgTxt("Too many output arguments"); + } + + int root = getInt(prhs[0]); + int iph = getInt(prhs[1]); + int in1 = getInt(prhs[2]); + int in2 = getInt(prhs[3]); + int n = newKineticsFromXML(root, iph, in1, in2); + + // Create matrix for the return argument. + plhs[0] = mxCreateDoubleMatrix(1,1, mxREAL); + double* x = mxGetPr(plhs[0]); + *x = n; + } +} diff --git a/Cantera/matlab/cantera/@Kinetics/private/production.cpp b/Cantera/matlab/cantera/@Kinetics/private/production.cpp new file mode 100755 index 000000000..be471ebee --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/private/production.cpp @@ -0,0 +1,32 @@ + +#include "mex.h" +#include "../../../../clib/src/ct.h" +#include "../../private/ctmatutils.h" + +extern "C" { + + void mexFunction( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) + { + int kin = getInt(prhs[0]); + int nsp = getInt(prhs[1]); + int job = getInt(prhs[2]); + plhs[0] = mxCreateNumericMatrix(nsp,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + int ok = -10; + switch (job) { + case 0: + ok = kin_getCreationRates(kin,nsp,h); break; + case 1: + ok = kin_getDestructionRates(kin,nsp,h); break; + case 2: + ok = kin_getNetProductionRates(kin,nsp,h); break; + case 3: + ok = kin_getSourceTerms(kin, nsp, h); break; + default: + ; + } + if (ok < 0) + mexErrMsgTxt("error computing production rates"); + } +} diff --git a/Cantera/matlab/cantera/@Kinetics/private/pstoich.cpp b/Cantera/matlab/cantera/@Kinetics/private/pstoich.cpp new file mode 100755 index 000000000..0e618421a --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/private/pstoich.cpp @@ -0,0 +1,20 @@ + +#include "mex.h" +#include "../../../../clib/src/ct.h" +#include "../../private/ctmatutils.h" + +extern "C" { + + void mexFunction( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) + { + double vv; + int kin = getInt(prhs[0]); + int isp = getInt(prhs[1]); + int irxn = getInt(prhs[2]); + vv = kin_productStoichCoeff(kin,irxn-1,isp-1); + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = vv; + } +} diff --git a/Cantera/matlab/cantera/@Kinetics/private/rop.cpp b/Cantera/matlab/cantera/@Kinetics/private/rop.cpp new file mode 100755 index 000000000..eaa2380f6 --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/private/rop.cpp @@ -0,0 +1,32 @@ + +#include "mex.h" +#include "../../../../clib/src/ct.h" +#include "../../private/ctmatutils.h" + +extern "C" { + + void mexFunction( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) + { + int kin = getInt(prhs[0]); + int job = getInt(prhs[1]); + int nr = kin_nReactions(kin); + plhs[0] = mxCreateNumericMatrix(nr,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + int ok = -10; + switch (job) { + case 0: + ok = kin_getFwdRatesOfProgress(kin,nr,h); break; + case 1: + ok = kin_getRevRatesOfProgress(kin,nr,h); break; + case 2: + ok = kin_getNetRatesOfProgress(kin,nr,h); break; + case 3: + ok = kin_getEquilibriumConstants(kin,nr,h); break; + default: + ; + } + if (ok < 0) + mexErrMsgTxt("error computing rates of progress"); + } +} diff --git a/Cantera/matlab/cantera/@Kinetics/private/rstoich.cpp b/Cantera/matlab/cantera/@Kinetics/private/rstoich.cpp new file mode 100755 index 000000000..3ba3efec2 --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/private/rstoich.cpp @@ -0,0 +1,20 @@ + +#include "mex.h" +#include "../../../../clib/src/ct.h" +#include "../../private/ctmatutils.h" + +extern "C" { + + void mexFunction( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) + { + double vv; + int kin = getInt(prhs[0]); + int isp = getInt(prhs[1]); + int irxn = getInt(prhs[2]); + vv = kin_reactantStoichCoeff(kin,irxn-1,isp-1); + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = vv; + } +} diff --git a/Cantera/matlab/cantera/@Kinetics/private/rxnstring.cpp b/Cantera/matlab/cantera/@Kinetics/private/rxnstring.cpp new file mode 100755 index 000000000..db5b5cbef --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/private/rxnstring.cpp @@ -0,0 +1,25 @@ + +#include "mex.h" +#include "../../../../clib/src/ct.h" +#include "../../private/ctmatutils.h" + +extern "C" { + + void mexFunction( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) + { + int kin = getInt(prhs[0]); + int irxn = getInt(prhs[1]); + char* buf; + int buflen = 80; + buf = (char*)mxCalloc(buflen, sizeof(char)); + int iok = kin_getReactionString(kin, irxn-1, buflen, buf); + if (iok >= 0) { + plhs[0] = mxCreateString(buf); + return; + } + else { + mexErrMsgTxt("error getting reaction string"); + } + } +} diff --git a/Cantera/matlab/cantera/@Kinetics/reactionEqn.m b/Cantera/matlab/cantera/@Kinetics/reactionEqn.m new file mode 100755 index 000000000..331631be1 --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/reactionEqn.m @@ -0,0 +1,29 @@ +function e = reactionEqn(a, irxn) +% reactionEqn Reaction equation of reaction irxn. +% +if nargin == 1 + m = nReactions(a); + n = 1; + irxn = [1:m]'; +elseif nargin == 2 + if isa(irxn,'double') + [m, n] = size(irxn); + else + error('reaction number(s) must be numeric'); + end +end + +if m == 1 & n == 1 + e = kinetics_get(a.id, 31, irxn); % rxnstring(a.id, irxn); +else + e = {}; + for i = 1:m + for j = 1:n + e{i,j} = kinetics_get(a.id, 31, irxn(i,j)); % rxnstring(a.id, irxn(i,j)); + end + end +end + + + + diff --git a/Cantera/matlab/cantera/@Kinetics/rop.m b/Cantera/matlab/cantera/@Kinetics/rop.m new file mode 100644 index 000000000..fa1c33bbf --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/rop.m @@ -0,0 +1,20 @@ +function rop = rop(k) +% ROP - Forward and reverse rates of progress. +% +% ROP(K) returns an M x 2 array of reaction rates of +% progress. The first column contains the forward rates of progress, +% and the second column the reverse rates. If this function +% is called with no output argument, a bar graph is produced. +% +f = rop_f(k) +r = rop_r(k) +rop = [f r] +if nargout == 0 + figure + set(gcf,'Name','Rates of Progress'); + bar(rop); + xlabel('Reaction Number'); + ylabel('Rate of Progress [kmol/m^3-s]'); + title('Rates of Progress'); + legend('Forward', 'Reverse'); +end diff --git a/Cantera/matlab/cantera/@Kinetics/rop_f.m b/Cantera/matlab/cantera/@Kinetics/rop_f.m new file mode 100755 index 000000000..1a578f1a8 --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/rop_f.m @@ -0,0 +1,20 @@ +function q = rop_f(a) +% ROP_F Forward rates of progress for all reactions. +% +% Q = ROP_F(K) +% +% Returns a column vector of the forward rates of progress +% for all reactions. +% +% See also: rop_r, rop_net. +% +q = kinetics_get(a.id,11,0); +if nargout == 0 + figure + set(gcf,'Name','Rates of Progress') + bar(q) + xlabel('Reaction Number') + ylabel('Forward Rate of Progress [kmol/m^3]') + title('Forward Rates of Progress') +end + diff --git a/Cantera/matlab/cantera/@Kinetics/rop_net.m b/Cantera/matlab/cantera/@Kinetics/rop_net.m new file mode 100755 index 000000000..ac9a42029 --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/rop_net.m @@ -0,0 +1,20 @@ +function q = rop_net(a) +% ROP_F Forward rates of progress for all reactions. +% +% Q = ROP_F(K) +% +% Returns a column vector of the forward rates of progress +% for all reactions. +% +% See also: rop_r, rop_net. +% +q = kinetics_get(a.id,13,0); +if nargout == 0 + figure + set(gcf,'Name','Rates of Progress') + bar(q) + xlabel('Reaction Number') + ylabel('Net Rate of Progress [kmol/m^3]') + title('Net Rates of Progress') +end + diff --git a/Cantera/matlab/cantera/@Kinetics/rop_r.m b/Cantera/matlab/cantera/@Kinetics/rop_r.m new file mode 100755 index 000000000..7cc3fb907 --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/rop_r.m @@ -0,0 +1,13 @@ +function q = rop_r(a) +% ROP_R Reverse rates of progress for all reactions. +% +% Q = ROP_R(K) +% +% Returns a column vector of the reverse rates of progress +% for all reactions. The value is zero for irreversible +% reactions. +% +% See also: rop_r, rop_net. +% +q = kinetics_get(a.id,12,0); + diff --git a/Cantera/matlab/cantera/@Kinetics/rxnEqs.m b/Cantera/matlab/cantera/@Kinetics/rxnEqs.m new file mode 100755 index 000000000..76697557b --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/rxnEqs.m @@ -0,0 +1,29 @@ +function e = rxnEqs(a, irxn) +% rxnEqs +% +if nargin == 1 + m = nReactions(a); + n = 1; + irxn = [1:m]' +elseif nargin == 2 + if isa(irxn,'double') + [m, n] = size(irxn); + else + error('reaction number(s) must be numeric'); + end +end + +if m == 1 & n == 1 + e = rxnstring(a.id, irxn); +else + e = {}; + for i = 1:m + for j = 1:n + e{i,j} = rxnstring(a.id, irxn(i,j)); + end + end +end + + + + diff --git a/Cantera/matlab/cantera/@Kinetics/setMultiplier.m b/Cantera/matlab/cantera/@Kinetics/setMultiplier.m new file mode 100755 index 000000000..cb5d441eb --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/setMultiplier.m @@ -0,0 +1,10 @@ +function setMultiplier(a,i,v) +% SETMULTIPLIER Set the rate of progress multiplier. +% +% SETMULTIPLIER(K, IRXN, V) sets the multipler for reaction IRXN +% to value V. +% +% see also: MULTIPLIER +% +kinetics_set(a.id,1,i,v); + diff --git a/Cantera/matlab/cantera/@Kinetics/stoich_net.m b/Cantera/matlab/cantera/@Kinetics/stoich_net.m new file mode 100755 index 000000000..39631d4e3 --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/stoich_net.m @@ -0,0 +1,30 @@ +function nu = stoich_net(a,species,rxns) +% stoich_net Net stoichiometric coefficients. +% +% nu = stoich_net(a) +% +% Returns a sparse matrix of all net (product - reactant) +% stoichiometric coefficients. The matrix element nu(k,i) is the +% net stoichiometric coefficient of species k in reaction i. +% +% nu = stoich_net(a, species, rxns) +% +% Returns a sparse matrix the same size as above, but +% containing only entries for the specified species and +% reactions. For example, stoich_net(a,3,[1 3 5 7]) returns a +% sparse matrix containing only the coefficients for species 3 +% in reactions 1, 3, 5, and 7. +% +% Note that the net stoichiometric coefficients may be negative, +% unlike the reactant or product stoichiometric coefficients. +% +% See also: stoich_r, stoich_p. +% +if nargin == 1 + nu = stoich_p(a) - stoich_r(a) +elseif nargin == 3 + nu = stoich_p(a,species,rxns) - stoich_r(a,species,rxns); +else + error(['syntax error. Type ''help stoich_net'' for more' ... + ' information.']) +end diff --git a/Cantera/matlab/cantera/@Kinetics/stoich_p.m b/Cantera/matlab/cantera/@Kinetics/stoich_p.m new file mode 100755 index 000000000..3909df001 --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/stoich_p.m @@ -0,0 +1,43 @@ +function nu_p = stoich_p(a,species,rxns) +% stoich_p Product stoichiometric coefficients. +% +% nu = stoich_p(a) +% +% Returns a sparse matrix of all product stoichiometric +% coefficients. The matrix element nu(k,i) is the +% stoichiometric coefficient of species k as a product in +% reaction i. +% +% nu = stoich_p(a, species, rxns) +% +% Returns a sparse matrix the same size as above, but +% containing only entries for the specified species and +% reactions. For example, stoich_p(a,3,[1 3 5 7]) returns a +% sparse matrix containing only the coefficients for species 3 +% in reactions 1, 3, 5, and 7. +% +% See also: stoich_r, stoich_net. +% +nsp = nTotalSpecies(a); +nr =nReactions(a); +b = sparse(nsp,nr); +f = @kinetics_get; +if nargin == 1 + kvals = 1:nsp; + ivals = 1:nr; +elseif nargin == 3 + kvals = species; + ivals = rxns; +else + error('Syntax error. type ''help stoich_r'' for more information.') +end + +for k = kvals + for i = ivals + nu = feval(f,a.id,6,i,k); + if nu ~= 0.0 + b(k,i) = nu; + end + end +end +nu_p = b; \ No newline at end of file diff --git a/Cantera/matlab/cantera/@Kinetics/stoich_r.m b/Cantera/matlab/cantera/@Kinetics/stoich_r.m new file mode 100755 index 000000000..ee5ebd39f --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/stoich_r.m @@ -0,0 +1,43 @@ +function nu_r = stoich_r(a,species,rxns) +% stoich_r Reactant stoichiometric coefficients. +% +% nu = stoich_r(a) +% +% Returns a sparse matrix of all reactant stoichiometric +% coefficients. The matrix element nu(k,i) is the +% stoichiometric coefficient of species k as a reactant in +% reaction i. +% +% nu = stoich_r(a, species, rxns) +% +% Returns a sparse matrix the same size as above, but +% containing only entries for the specified species and +% reactions. For example, stoich_r(a,3,[1 3 5 7]) returns a +% sparse matrix containing only the coefficients for species 3 +% in reactions 1, 3, 5, and 7. +% +% See also: stoich_p, stoich_net. +% +nsp = nTotalSpecies(a); +nr =nReactions(a); +b = sparse(nsp,nr); +f = @kinetics_get; +if nargin == 1 + kvals = 1:nsp; + ivals = 1:nr; +elseif nargin == 3 + kvals = species; + ivals = rxns; +else + error('Syntax error. type ''help stoich_r'' for more information.') +end + +for k = kvals + for i = ivals + nu = feval(f,a.id,5,i,k); + if nu ~= 0.0 + b(k,i) = nu; + end + end +end +nu_r = b; \ No newline at end of file diff --git a/Cantera/matlab/cantera/@Kinetics/ydot.m b/Cantera/matlab/cantera/@Kinetics/ydot.m new file mode 100755 index 000000000..d90c5571b --- /dev/null +++ b/Cantera/matlab/cantera/@Kinetics/ydot.m @@ -0,0 +1,4 @@ +function v = ydot(a) +% YDOT - Evaluates wdot_k M_k / (density) +% +v = kinetics_get(a.id,24,0); \ No newline at end of file diff --git a/Cantera/matlab/cantera/@Reactor/Reactor.m b/Cantera/matlab/cantera/@Reactor/Reactor.m new file mode 100644 index 000000000..4909e1cab --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/Reactor.m @@ -0,0 +1,35 @@ +function x = Reactor(contents, typ) +% REACTOR - Create a Reactor object. +% +% A Reactor object simulates a perfectly-stirred reactor. It has +% a time-dependent state, and may be coupled to other reactors +% through flow lines or through walls that may expand or +% contract and/or conduct heat. +% +% r1 = Reactor % an empty reactor +% r2 = Reactor(gas) % a reactor containing a gas +% +% See also: Reservoir +% +if nargin == 0 + contents = 0; + typ = 1; +elseif nargin == 1 + typ = 1; +elseif nargin > 2 + error('too many arguments'); +end + +x.index = reactormethods(0,typ); +if x.index < 0 + error(geterr); +end +x.contents = contents; +x = class(x,'Reactor'); + +if isa(contents,'Solution') + insert(x, contents); +end + + + diff --git a/Cantera/matlab/cantera/@Reactor/advance.m b/Cantera/matlab/cantera/@Reactor/advance.m new file mode 100644 index 000000000..2a4310949 --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/advance.m @@ -0,0 +1,22 @@ +function advance(r, tout) +% ADVANCE - Advance the state of the reactor in time. +% +% Method advance integrates the system of ordinary differential +% equations that determine the rate of change of the reactor +% volume, the mass of each species, and the total energy. The +% integration is carried out from the current reactor time to time +% 'tout.' (Note 'tout' is an absolute time, not a time interval.) The +% integrator may take many internal time steps before reaching +% tout. +% +% for i in 1:10 +% tout = 0.1*i +% advance(r, tout) +% ... +% +% ... +% end +% +% See also: Reactor/step +% +reactormethods(8, reactor_hndl(r), tout); diff --git a/Cantera/matlab/cantera/@Reactor/clear.m b/Cantera/matlab/cantera/@Reactor/clear.m new file mode 100644 index 000000000..921177729 --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/clear.m @@ -0,0 +1,5 @@ +function clear(r) +% CLEAR - +% +reactormethods(2, reactor_hndl(r)); + diff --git a/Cantera/matlab/cantera/@Reactor/density.m b/Cantera/matlab/cantera/@Reactor/density.m new file mode 100644 index 000000000..9ae85dee2 --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/density.m @@ -0,0 +1,4 @@ +function rho = density(r) +% DENSITY - density +% +rho = reactormethods(25, reactor_hndl(r)); diff --git a/Cantera/matlab/cantera/@Reactor/enthalpy_mass.m b/Cantera/matlab/cantera/@Reactor/enthalpy_mass.m new file mode 100644 index 000000000..945cc72d4 --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/enthalpy_mass.m @@ -0,0 +1,12 @@ +function h = enthalpy_mass(r) +% ENTHALPY_MASS - the specific enthalpy [J/kg]. +% +% h = enthalpy_mass(r) +% +% returns the specific enthalpy of the reactor contents at the +% end of the last call to 'advance' or 'step.' +% +% See also: Reactor/intEnergy_mass, Reactor/entropy_mass, +% Reactor/enthalpy_mole +% +h = reactormethods(27, reactor_hndl(r)); diff --git a/Cantera/matlab/cantera/@Reactor/hndl.m b/Cantera/matlab/cantera/@Reactor/hndl.m new file mode 100644 index 000000000..77715a715 --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/hndl.m @@ -0,0 +1,2 @@ +function i = hndl(r) +i = r.index; diff --git a/Cantera/matlab/cantera/@Reactor/insert.m b/Cantera/matlab/cantera/@Reactor/insert.m new file mode 100644 index 000000000..f4e7277b5 --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/insert.m @@ -0,0 +1,8 @@ +function insert(r, gas) +% INSERT - insert a mixture into the reactor +% +r.contents = gas; +setThermoMgr(r, gas); +setKineticsMgr(r, gas); + + diff --git a/Cantera/matlab/cantera/@Reactor/intEnergy_mass.m b/Cantera/matlab/cantera/@Reactor/intEnergy_mass.m new file mode 100644 index 000000000..1ec99b75e --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/intEnergy_mass.m @@ -0,0 +1,12 @@ +function u = intEnergy_mass(r) +% INTENERGY_MASS - the specific internal energy [J/kg]. +% +% u = intEnergy_mass(r) +% +% returns the specific internal energy of the reactor contents at +% the end of the last call to 'advance' or 'step.' +% +% See also: Reactor/enthalpy_mass, Reactor/entropy_mass, +% Reactor/enthalpy_mole +% +u = reactormethods(28, reactor_hndl(r)); diff --git a/Cantera/matlab/cantera/@Reactor/mass.m b/Cantera/matlab/cantera/@Reactor/mass.m new file mode 100644 index 000000000..213273225 --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/mass.m @@ -0,0 +1,5 @@ +function m = mass(r) +% MASS - +% +reactormethods(23, reactor_hndl(r)); + diff --git a/Cantera/matlab/cantera/@Reactor/massFraction.m b/Cantera/matlab/cantera/@Reactor/massFraction.m new file mode 100644 index 000000000..ad6ecc93c --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/massFraction.m @@ -0,0 +1,5 @@ +function y = massFraction(r, species) +% MASSFRACTION - Mass fraction of species with name 'species'. +% +k = speciesIndex(r.contents, species) - 1; +y = reactormethods(30, reactor_hndl(r), k); diff --git a/Cantera/matlab/cantera/@Reactor/massFractions.m b/Cantera/matlab/cantera/@Reactor/massFractions.m new file mode 100644 index 000000000..44763e93d --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/massFractions.m @@ -0,0 +1,11 @@ +function y = massFractions(r) +% MASSFRACTION - Mass fractions of reactor contents after last call +% to 'advance' or 'step'. +% +nsp = nSpecies(r.contents) +ir = reactor_hndl(r) +for k = 1:nsp + yy(k) = reactormethods(30, ir, k-1); +end +y = yy + diff --git a/Cantera/matlab/cantera/@Reactor/pressure.m b/Cantera/matlab/cantera/@Reactor/pressure.m new file mode 100644 index 000000000..a97dc663f --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/pressure.m @@ -0,0 +1,4 @@ +function p = pressure(r) +% PRESSURE - pressure +% +p = reactormethods(29, reactor_hndl(r)); diff --git a/Cantera/matlab/cantera/@Reactor/private/reactormethods.cpp b/Cantera/matlab/cantera/@Reactor/private/reactormethods.cpp new file mode 100644 index 000000000..4761c116c --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/private/reactormethods.cpp @@ -0,0 +1,130 @@ + +#include "mex.h" +#include "../../../../clib/src/ctreactor.h" +#include "../../../../clib/src/ct.h" +#include "../../private/ctmatutils.h" + +const double Undef = -999.123; + +extern "C" { + + + void reportError() { + int buflen = 300; + char* output_buf = (char*)mxCalloc(buflen, sizeof(char)); + getCanteraError(buflen, output_buf); + mexErrMsgTxt(output_buf); + } + + + void mexFunction( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) + { + int j, m, iok, n; + char *file, *key, *val; + + int job = getInt(prhs[0]); + int i = getInt(prhs[1]); + + double r = Undef; + double v = Undef; + if (nrhs > 2) v = getDouble(prhs[2]); + + // constructor + if (job == 0) { + n = reactor_new(i); + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = double(n); + if (n < 0) reportError(); + return; + } + + // options that do not return a value + + if (job < 20) { + switch (job) { + + case 1: + iok = reactor_del(i); + break; + case 2: + iok = reactor_copy(i); + break; + case 3: + iok = reactor_assign(i,int(v)); + break; + case 4: + iok = reactor_setInitialVolume(i, v); + break; + case 5: + iok = reactor_setInitialTime(i, v); + break; + case 6: + iok = reactor_setThermoMgr(i, int(v)); + break; + case 7: + iok = reactor_setKineticsMgr(i, int(v)); + break; + case 8: + iok = reactor_advance(i, v); + break; + case 9: + iok = reactor_setEnergy(i, int(v)); + break; + default: + mexErrMsgTxt("unknown job parameter"); + } + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = double(iok); + if (iok < 0) reportError(); + return; + } + + + // options that return a value of type 'double' + + else if (job < 40) { + switch (job) { + case 21: + r = reactor_step(i, v); + break; + case 22: + r = reactor_time(i); + break; + case 23: + r = reactor_mass(i); + break; + case 24: + r = reactor_volume(i); + break; + case 25: + r = reactor_density(i); + break; + case 26: + r = reactor_temperature(i); + break; + case 27: + r = reactor_enthalpy_mass(i); + break; + case 28: + r = reactor_intEnergy_mass(i); + break; + case 29: + r = reactor_pressure(i); + break; + case 30: + r = reactor_massFraction(i, int(v)); + break; + default: + mexErrMsgTxt("unknown job parameter"); + } + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = r; + if (r == Undef) reportError(); + return; + } + } +} diff --git a/Cantera/matlab/cantera/@Reactor/private/reactormethods.m b/Cantera/matlab/cantera/@Reactor/private/reactormethods.m new file mode 100644 index 000000000..5c4b9b7f6 --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/private/reactormethods.m @@ -0,0 +1,13 @@ +function v = reactormethods(n, job, a, b, c, d) +% +if nargin == 2 + v = ctmethods(60, n, job); +elseif nargin == 3 + v = ctmethods(60, n, job, a); +elseif nargin == 4 + v = ctmethods(60, n, job, a, b); +elseif nargin == 5 + v = ctmethods(60, n, job, a, b, c); +elseif nargin == 6 + v = ctmethods(60, n, job, a, b, c, d); +end \ No newline at end of file diff --git a/Cantera/matlab/cantera/@Reactor/reactor_hndl.m b/Cantera/matlab/cantera/@Reactor/reactor_hndl.m new file mode 100644 index 000000000..aa39d5350 --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/reactor_hndl.m @@ -0,0 +1,2 @@ +function i = reactor_hndl(r) +i = r.index; diff --git a/Cantera/matlab/cantera/@Reactor/setEnergy.m b/Cantera/matlab/cantera/@Reactor/setEnergy.m new file mode 100644 index 000000000..194ae5288 --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/setEnergy.m @@ -0,0 +1,8 @@ +function setEnergy(f, flag) +% SETENERGY - +% +iflag = 0 +if flag = 'on' + iflag = 1 +end +reactormethods(9, f.index, iflag) diff --git a/Cantera/matlab/cantera/@Reactor/setInitialTime.m b/Cantera/matlab/cantera/@Reactor/setInitialTime.m new file mode 100644 index 000000000..abe5a7b82 --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/setInitialTime.m @@ -0,0 +1,5 @@ +function setInitialTime(r, t0) +% SETINITIALTIME - +% +reactormethods(5, reactor_hndl(r), t0); + diff --git a/Cantera/matlab/cantera/@Reactor/setInitialVolume.m b/Cantera/matlab/cantera/@Reactor/setInitialVolume.m new file mode 100644 index 000000000..ee0b3fe3c --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/setInitialVolume.m @@ -0,0 +1,5 @@ +function setInitialVolume(r, t0) +% SETINITIALVOLUME - +% +reactormethods(4, reactor_hndl(r), t0); + diff --git a/Cantera/matlab/cantera/@Reactor/setKineticsMgr.m b/Cantera/matlab/cantera/@Reactor/setKineticsMgr.m new file mode 100644 index 000000000..32e72bac1 --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/setKineticsMgr.m @@ -0,0 +1,9 @@ +function setKineticsMgr(r, k) +% SETKINETICSMGR - set the kinetics manager +% +if ~isa(k,'Kinetics') + error('wrong object type'); +end + +reactormethods(7, reactor_hndl(r), kinetics_hndl(k)); + diff --git a/Cantera/matlab/cantera/@Reactor/setThermoMgr.m b/Cantera/matlab/cantera/@Reactor/setThermoMgr.m new file mode 100644 index 000000000..f2d8ecfad --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/setThermoMgr.m @@ -0,0 +1,9 @@ +function setThermoMgr(r, t) +% SETTHERMOMGR - set the thermo manager +% +if ~isa(t,'ThermoPhase') + error('wrong object type'); +end + +reactormethods(6, reactor_hndl(r), thermo_hndl(t)); + diff --git a/Cantera/matlab/cantera/@Reactor/step.m b/Cantera/matlab/cantera/@Reactor/step.m new file mode 100644 index 000000000..83b267873 --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/step.m @@ -0,0 +1,28 @@ +function t = step(r, tout) +% STEP - Take one internal time step toward tout. +% +% The integrator used to integrate the ODEs (CVODE) takes +% variable-size steps, chosen so that a specified error +% tolerance is maintained. At times when the solution is rapidly +% changing, the time step becomes smaller to resolve the +% solution. +% +% Method 'step' takes one internal time step and returns. This +% can be useful when it is desired to resolve a rapidly-changing +% solution in the output file. +% +% This method can be used as follows: +% +% t = 0.0 +% tout = 0.1 +% while t < tout +% t = step(r, tout) +% ,,, +% +% ... +% end +% +% See also: Reactor/advance +% +t = reactormethods(21, reactor_hndl(r), tend); + diff --git a/Cantera/matlab/cantera/@Reactor/temperature.m b/Cantera/matlab/cantera/@Reactor/temperature.m new file mode 100644 index 000000000..07e1b0053 --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/temperature.m @@ -0,0 +1,5 @@ +function t = temperature(r) +% TEMPERATURE - temperature +% +t = reactormethods(26, reactor_hndl(r)); + diff --git a/Cantera/matlab/cantera/@Reactor/time.m b/Cantera/matlab/cantera/@Reactor/time.m new file mode 100644 index 000000000..d6943d4f6 --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/time.m @@ -0,0 +1,4 @@ +function t = time(r) +% TIME - time +% +t = reactormethods(22, reactor_hndl(r)); diff --git a/Cantera/matlab/cantera/@Reactor/volume.m b/Cantera/matlab/cantera/@Reactor/volume.m new file mode 100644 index 000000000..2febc87ae --- /dev/null +++ b/Cantera/matlab/cantera/@Reactor/volume.m @@ -0,0 +1,4 @@ +function v = volume(r) +% VOLUME - volume +% +v = reactormethods(24, reactor_hndl(r)); diff --git a/Cantera/matlab/cantera/@Solution/Solution.m b/Cantera/matlab/cantera/@Solution/Solution.m new file mode 100755 index 000000000..95feb8885 --- /dev/null +++ b/Cantera/matlab/cantera/@Solution/Solution.m @@ -0,0 +1,54 @@ +function s = Solution(x, r) +% SOLUTION - class Solution constructor. +% +% Class Solution represents solutions of multiple species. A +% solution is defined as a mixture of two or more constituents +% (species) that are completely mixed on molecular length +% scales. The macroscopic intensive thermodynamic state of a +% solution is specified by two thermodynamic properties (for +% example, the temperature and pressure), and the relative amounts +% of each species, which may be given as mole fractions or mass +% fractions. + +% s = Solution('input.xml', ) +% +% constructs a Solution object from a specification contained in +% file input.xml, and using a specified transport property +% model. If the transport model is omitted, it defaults to +% 'None', which disables transport property evaluation. + +% Class Solution derives from three more basic classes, and most of +% its methods are inherited from these classes. These are: +% +% class ThermoPhase - composition information and +% thermodynamic properties +% class Kinetics - homogeneous kinetics +% class Transport - transport properties +% +% See also: ThermoPhase, Kinetics, Transport +% +if nargin == 1 + trmodel = 'None'; +elseif nargin == 2 + trmodel = r; +else + error('wrong number of arguments'); +end + +if isa(x,'Solution') + s = x; + return +elseif isa(x,'XML_Node') + xp = x; +else + doc = XML_Node('doc', x); + xp = child(doc,'ctml/phase'); +end +t = ThermoPhase(xp); +k = Kinetics(xp,t); +s.kin = k; +s.th = t; +tr = Transport(trmodel,t,4); +s.tr = tr; +s = class(s,'Solution',t,k,tr); + diff --git a/Cantera/matlab/cantera/@Solution/clear.m b/Cantera/matlab/cantera/@Solution/clear.m new file mode 100644 index 000000000..27723ae8c --- /dev/null +++ b/Cantera/matlab/cantera/@Solution/clear.m @@ -0,0 +1,9 @@ +function clear(s) +% CLEAR - Delete the kernel object. +% +clear(s.th); +clear(s.kin); +disp('Solution.clear: skipping clearing the transport object... check this!') +%clear(s.tr); + + diff --git a/Cantera/matlab/cantera/@Solution/display.m b/Cantera/matlab/cantera/@Solution/display.m new file mode 100755 index 000000000..77bfc2732 --- /dev/null +++ b/Cantera/matlab/cantera/@Solution/display.m @@ -0,0 +1,22 @@ +function display(a) + +s = [sprintf('\n temperature %12.6g K\n', temperature(a)) ... + sprintf(' pressure %12.6g Pa\n', pressure(a)) ... + sprintf(' density %12.6g kg/m^3\n', density(a)) ... + sprintf(' mean mol. weight %12.6g amu', ... + meanMolecularWeight(a))]; +disp(s); + +nsp = nSpecies(a); +x = moleFractions(a); +y = massFractions(a); + +s = [... + sprintf('\n X Y \n') ... + sprintf(' ------------- ------------ ')]; + disp(s); + + for k = 1:nsp + disp(sprintf('%18s %12.6e %12.6e', char(speciesName(a,k)), x(k), y(k))); + end +disp(' '); \ No newline at end of file diff --git a/Cantera/matlab/cantera/@Solution/set.m b/Cantera/matlab/cantera/@Solution/set.m new file mode 100755 index 000000000..76664d12e --- /dev/null +++ b/Cantera/matlab/cantera/@Solution/set.m @@ -0,0 +1,125 @@ +function a = set(a,varargin) +% SET - Set properties. +% +% The properties that may be set are +% +% Temperature (T) +% Density (Rho) +% Volume (V) +% Pressure (P) +% Enthalpy (H) +% Entropy (S) +% MoleFractions (X) +% MassFractions (Y) +% +% Either the full property name or the symbol may be +% specified. For the extensive properties (V,H,U,S), the values +% must be given per unit mass. H, U, and S must be set in +% conjunction with pressure (for H,S) or volume (for U,S). Either +% (specific) volume or density may be specified. Mole and mass +% fractions must be input as vectors (either row or column) with +% length equal to the number of species. +% +% Examples: +% +% set(gas,'Temperature',600.0); +% set(gas,'T',600.0); +% set(gas,'T',600.0,'P',2*oneatm,'Y',massfracs); +% set(gas,'H',0.5*enthalpy_mass(gas),'P',pressure(gas)); +% set(gas,'S',entropy_mass(gas),'P',0.5*pressure(gas)); +% set(gas,'X',ones(nSpecies(gas),1)); +% +% Alternatively, individual methods to set properties may be +% called (setTemperature, setMoleFractions, etc.) +% + +property_argin = varargin; +pval = -999; +hval = -999; +uval = -999; +sval = -999; +vval = -999; +np = 0; +while length(property_argin) >= 2, + prop = property_argin{1}; + val = property_argin{2}; + property_argin = property_argin(3:end); + switch prop + case 'Temperature' + setTemperature(a,val); + case 'T' + setTemperature(a,val); + case 'Density' + setDensity(a,val); + vval = 1.0/val; + case 'Rho' + setDensity(a,val); + vval = 1.0/val; + case 'V' + setDensity(a,1.0/val); + vval = val; + case 'MoleFractions' + setMoleFractions(a,val); + case 'X' + setMoleFractions(a,val); + case 'MassFractions' + setMassFractions(a,val); + case 'Y' + setMassFractions(a,val); + case 'Pressure' + pval = val; + np = np + 1; + case 'P' + pval = val; + np = np + 1; + case 'Enthalpy' + hval = val; + np = np + 1; + case 'H' + hval = val; + np = np + 1; + case 'IntEnergy' + uval = val; + np = np + 1; + case 'U' + uval = val; + np = np + 1; + case 'Entropy' + sval = val; + np = np + 1; + case 'S' + sval = val; + np = np + 1; + otherwise + error(['unknown property ' char(prop)]) + end +end + +if np == 1 + if notnull(pval) + setPressure(a,pval); + end +end + +if (np >= 2) + if notnull(pval) & notnull(hval) + setState_HP(a,[hval,pval]); + elseif notnull(uval) & notnull(vval) + setState_UV(a,[uval,vval]); + elseif notnull(sval) & notnull(pval) + setState_SP(a,[sval,pval]); + elseif notnull(sval) & notnull(vval) + setState_SV(a,[sval,vval]); + else + error('unimplemented property pair'); + end +end + + +function b = notnull(v) +if v == -999 + b = 0; +else + b = 1; +end + diff --git a/Cantera/matlab/cantera/@Solution/soundspeed.m b/Cantera/matlab/cantera/@Solution/soundspeed.m new file mode 100755 index 000000000..2648c3481 --- /dev/null +++ b/Cantera/matlab/cantera/@Solution/soundspeed.m @@ -0,0 +1,18 @@ +function b = soundspeed(a) +% SOUNDSPEED - Speed of sound (m/s). + +if isIdealGas(a) + gamma = cp_mass(a)/cv_mass(a); + wtm = meanMolecularWeight(a); + r = gasconstant/wtm; + b = sqrt(gamma * r * temperature(a)); +else + rho0 = density(a); + p0 = pressure(a); + s0 = entropy_mass(a); + rho1 = 1.001*rho0; + set(gas,'Density',rho1,'Entropy',s0); + p1 = pressure(a); + dpdrho_s = (p1 - p0)/(rho1 - rho0); + b = sqrt(dpdrho_s); +end diff --git a/Cantera/matlab/cantera/@ThermoPhase/ThermoPhase.m b/Cantera/matlab/cantera/@ThermoPhase/ThermoPhase.m new file mode 100644 index 000000000..7bb775a9d --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/ThermoPhase.m @@ -0,0 +1,23 @@ +function t = ThermoPhase(r) +%THERMOPHASE Cantera ThermoPhase class constructor +% +if nargin == 1 + if isa(r,'ThermoPhase') + % create a copy + t = r; + return + elseif isa(r,'XML_Node') + t.owner = 1; + hr = hndl(r); + t.tp_id = thermo_get(hr,0); + if t.tp_id < 0 + error(geterr); + end + else + t.owner = 0; + t.tp_id = r; + end + t = class(t,'ThermoPhase'); +else + error('wrong number of arguments'); +end diff --git a/Cantera/matlab/cantera/@ThermoPhase/atomicMasses.m b/Cantera/matlab/cantera/@ThermoPhase/atomicMasses.m new file mode 100644 index 000000000..ebbbcec96 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/atomicMasses.m @@ -0,0 +1,4 @@ +function x = atomicMasses(a) +% ATOMICMASSES - Array of element atomic masses [kg/kmol]. +% + x = phase_get(a.tp_id,30); diff --git a/Cantera/matlab/cantera/@ThermoPhase/chemPotentials.m b/Cantera/matlab/cantera/@ThermoPhase/chemPotentials.m new file mode 100644 index 000000000..d7b4a14d9 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/chemPotentials.m @@ -0,0 +1,9 @@ +function mu = chemPotentials(p) +% CHEMPOTENTIALS - Species chemical potentials. +% +% This method returns an array containing the species +% chemical potentials [J/kmol]. The expressions used to +% compute these depend on the model implemented by the +% underlying kernel thermo manager.""" + mu = thermo_get(p.tp_id,34); + diff --git a/Cantera/matlab/cantera/@ThermoPhase/clear.m b/Cantera/matlab/cantera/@ThermoPhase/clear.m new file mode 100644 index 000000000..e69ad8729 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/clear.m @@ -0,0 +1,5 @@ +function clear(t) +% CLEAR - Delete the kernel object. +% +thermo_set(t.tp_id,0,10); + diff --git a/Cantera/matlab/cantera/@ThermoPhase/cp_R.m b/Cantera/matlab/cantera/@ThermoPhase/cp_R.m new file mode 100644 index 000000000..5dca044c8 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/cp_R.m @@ -0,0 +1,8 @@ +function v = cp_R(p) +% CP_R - Species non-dimensional heat capacities. +% +% This method returns an array containing the pure species +% standard-state heat capacities at constant pressure. +% + v = thermo_get(p.tp_id,38); + diff --git a/Cantera/matlab/cantera/@ThermoPhase/cp_mass.m b/Cantera/matlab/cantera/@ThermoPhase/cp_mass.m new file mode 100644 index 000000000..e03ed2957 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/cp_mass.m @@ -0,0 +1,3 @@ +function v = cp_mass(a) +% CP_MASS - Specific heat at constant pressure [J/kg-K]. + v = thermo_get(a.tp_id,13); diff --git a/Cantera/matlab/cantera/@ThermoPhase/cp_mole.m b/Cantera/matlab/cantera/@ThermoPhase/cp_mole.m new file mode 100644 index 000000000..4acbd378e --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/cp_mole.m @@ -0,0 +1,3 @@ +function v = cp_mole(a) +% CP_MOLE - Molar heat capacity at constant pressure [J/kmol-K]. + v = thermo_get(a.tp_id,6); diff --git a/Cantera/matlab/cantera/@ThermoPhase/cv_mass.m b/Cantera/matlab/cantera/@ThermoPhase/cv_mass.m new file mode 100644 index 000000000..f9e12826a --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/cv_mass.m @@ -0,0 +1,3 @@ +function v = cv_mass(a) +% CV_MASS - Specific heat at constant volume [J/kg-K]. + v = thermo_get(a.tp_id,14); diff --git a/Cantera/matlab/cantera/@ThermoPhase/cv_mole.m b/Cantera/matlab/cantera/@ThermoPhase/cv_mole.m new file mode 100644 index 000000000..092594b83 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/cv_mole.m @@ -0,0 +1,3 @@ +function v = cv_mole(a) +% CV_MOLE - Molar heat capacity at constant volume [J/kmol-K]. + v = thermo_get(a.tp_id,7); diff --git a/Cantera/matlab/cantera/@ThermoPhase/density.m b/Cantera/matlab/cantera/@ThermoPhase/density.m new file mode 100644 index 000000000..efab882bc --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/density.m @@ -0,0 +1,4 @@ +function rho = density(p) +% DENSITY - Mass density [kg/m^3]. +% + rho = phase_get(p.tp_id,2); diff --git a/Cantera/matlab/cantera/@ThermoPhase/elementIndex.m b/Cantera/matlab/cantera/@ThermoPhase/elementIndex.m new file mode 100644 index 000000000..943ed078a --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/elementIndex.m @@ -0,0 +1,16 @@ +function n = elementIndex(a,name) +% ELEMENTINDEX - The element index of the element with name +% 'name'. +% +% The index is an integer assigned to each element in sequence as it +% is read in from the input file. +% +% NOTE: In keeping with the conventions used by Matlab, this method +% returns 1 for the first element. In contrast, the corresponding +% method elementIndex in the Cantera C++ and Python interfaces +% returns 0 for the first element, 1 for the second one, etc. +% +% ic = elementIndex(gas, 'C'); +% ih = elementIndex(gas, 'H'); +% + n = phase_get(a.tp_id,13,name); \ No newline at end of file diff --git a/Cantera/matlab/cantera/@ThermoPhase/elementName.m b/Cantera/matlab/cantera/@ThermoPhase/elementName.m new file mode 100644 index 000000000..40d6f29e0 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/elementName.m @@ -0,0 +1,17 @@ +function nm = elementName(a, m) +% ELEMENTNAME - Name of element with index m. +% +% If m is a scalar integer, the return value will be a string +% containing the name of the m^th species. If it is an array of +% integers, the output will be a cell array of +% the same shape containing the name strings. +% +[m, n] = size(k); +nm = {}; +for i = 1:m + for j = 1:n + nm{i,j} = phase_get(a.tp_id, 41, k(i,j)); + end +end + + diff --git a/Cantera/matlab/cantera/@ThermoPhase/enthalpies_RT.m b/Cantera/matlab/cantera/@ThermoPhase/enthalpies_RT.m new file mode 100644 index 000000000..72c7234f3 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/enthalpies_RT.m @@ -0,0 +1,12 @@ +function v = enthalpies_RT(p) +% ENTHALPIES_RT - Pure species non-dimensional enthalpies. +% +% h_rt = enthalpies_RT(phase) +% +% sets array h_rt to the array of standard-state species enthalpies +% for phase 'phase' divided by RT, where R is the universal gas +% constant and T is the temperature. For gaseous species, these +% values are ideal gas enthalpies. +% +% + v = thermo_get(p.tp_id,32); diff --git a/Cantera/matlab/cantera/@ThermoPhase/enthalpy_mass.m b/Cantera/matlab/cantera/@ThermoPhase/enthalpy_mass.m new file mode 100644 index 000000000..5c7849471 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/enthalpy_mass.m @@ -0,0 +1,4 @@ +function v = enthalpy_mass(a) +% ENTHALPY_MASS - Specific enthalpy [J/kg]. +% + v = thermo_get(a.tp_id,9); diff --git a/Cantera/matlab/cantera/@ThermoPhase/enthalpy_mole.m b/Cantera/matlab/cantera/@ThermoPhase/enthalpy_mole.m new file mode 100644 index 000000000..22cca043d --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/enthalpy_mole.m @@ -0,0 +1,4 @@ +function v = enthalpy_mole(a) +% ENTHALPY_MOLE - Molar enthalpy [J/kmol]. +% + v = thermo_get(a.tp_id,2); diff --git a/Cantera/matlab/cantera/@ThermoPhase/entropies_R.m b/Cantera/matlab/cantera/@ThermoPhase/entropies_R.m new file mode 100644 index 000000000..b041fe480 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/entropies_R.m @@ -0,0 +1,7 @@ +function v = entropies_R(p) +% ENTROPIES_R - Species non-dimensional entropies. +% +% This method returns an array containing the pure species +% standard-state entropies. +% + v = thermo_get(p.tp_id,36); diff --git a/Cantera/matlab/cantera/@ThermoPhase/entropy_mass.m b/Cantera/matlab/cantera/@ThermoPhase/entropy_mass.m new file mode 100644 index 000000000..a080ca479 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/entropy_mass.m @@ -0,0 +1,2 @@ +function v = entropy_mass(a) +v = thermo_get(a.tp_id,11); diff --git a/Cantera/matlab/cantera/@ThermoPhase/entropy_mole.m b/Cantera/matlab/cantera/@ThermoPhase/entropy_mole.m new file mode 100644 index 000000000..31f8e3974 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/entropy_mole.m @@ -0,0 +1,2 @@ +function v = entropy_mole(a) +v = thermo_get(a.tp_id,4); diff --git a/Cantera/matlab/cantera/@ThermoPhase/eosType.m b/Cantera/matlab/cantera/@ThermoPhase/eosType.m new file mode 100644 index 000000000..8747a9c60 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/eosType.m @@ -0,0 +1,7 @@ +function e = eosType(a) +% EOSTYPE - Equation of state type. +% +% This method returns an integer flag identifying the type of +% equation of state. +% +e = thermo_get(a.tp_id, 18); diff --git a/Cantera/matlab/cantera/@ThermoPhase/equilibrate.m b/Cantera/matlab/cantera/@ThermoPhase/equilibrate.m new file mode 100644 index 000000000..21510dd9a --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/equilibrate.m @@ -0,0 +1,51 @@ +function a = equilibrate(a, xy) +% EQUILIBRATE Set the phase to a state of chemical equilibrium. +% +% The second argument must be one of the strings 'TP', 'TV', +% 'HP', 'SP', 'SV', 'UV', 'PT', 'VT', 'PH', 'PS', 'VS', or 'VU', +% and specifies the two thermodynamic properties held fixed at +% the values in the initial state. Note that if U, H, V, or S is +% specified, it is the specific value (per unit mass), not the +% molar value, that is held fixed. +% +if nargin ~= 2 + error('two arguments required') +end + +iok = 0; +switch xy + case 'TP' + iok = thermo_set(a.tp_id, 50, 104); + case 'TV' + iok = thermo_set(a.tp_id, 50, 100); + case 'HP' + iok = thermo_set(a.tp_id, 50, 101); + case 'SP' + iok = thermo_set(a.tp_id, 50, 102); + case 'SV' + iok = thermo_set(a.tp_id, 50, 107); + case 'UV' + iok = thermo_set(a.tp_id, 50, 105); + case 'PT' + iok = thermo_set(a.tp_id, 50, 104); + case 'VT' + iok = thermo_set(a.tp_id, 50, 100); + case 'PH' + iok = thermo_set(a.tp_id, 50, 101); + case 'PS' + iok = thermo_set(a.tp_id, 50, 102); + case 'VS' + iok = thermo_set(a.tp_id, 50, 107); + case 'VU' + iok = thermo_set(a.tp_id, 50, 105); + otherwise + error('unsupported option') +end +if iok < 0 + e = geterr; + if e == 0 + e = 'unknown error'; + end + error(e); +end + diff --git a/Cantera/matlab/cantera/@ThermoPhase/gibbs_RT.m b/Cantera/matlab/cantera/@ThermoPhase/gibbs_RT.m new file mode 100644 index 000000000..b6ac1b187 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/gibbs_RT.m @@ -0,0 +1,8 @@ +function g_RT = gibbs_RT(p) +% GIBBS_RT - Species non-dimensional Gibbs free energies. +% +% This method returns an array containing the pure species +% standard-state Gibbs free energies. +% +g_RT = enthalpies_RT(g) - entropies_R(g); + diff --git a/Cantera/matlab/cantera/@ThermoPhase/gibbs_mass.m b/Cantera/matlab/cantera/@ThermoPhase/gibbs_mass.m new file mode 100644 index 000000000..0e268fda7 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/gibbs_mass.m @@ -0,0 +1,3 @@ +function v = gibbs_mass(a) +% GIBBS_MASS - Specific Gibbs function [J/kg]. + v = thermo_get(a.tp_id,12); diff --git a/Cantera/matlab/cantera/@ThermoPhase/gibbs_mole.m b/Cantera/matlab/cantera/@ThermoPhase/gibbs_mole.m new file mode 100644 index 000000000..604d260e2 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/gibbs_mole.m @@ -0,0 +1,3 @@ +function v = gibbs_mole(a) +% GIBBS_MOLE - Molar Gibbs function [J/kmol]. + v = thermo_get(a.tp_id,5); diff --git a/Cantera/matlab/cantera/@ThermoPhase/hndl.m b/Cantera/matlab/cantera/@ThermoPhase/hndl.m new file mode 100644 index 000000000..4b6c8c94f --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/hndl.m @@ -0,0 +1,2 @@ +function i = hndl(p) +i = p.tp_id; diff --git a/Cantera/matlab/cantera/@ThermoPhase/intEnergy_mass.m b/Cantera/matlab/cantera/@ThermoPhase/intEnergy_mass.m new file mode 100644 index 000000000..93697d3ee --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/intEnergy_mass.m @@ -0,0 +1,3 @@ +function v = intEnergy_mass(a) +% INTENERGY_MASS - Specific internal energy [J/kg]. + v = thermo_get(a.tp_id,10); diff --git a/Cantera/matlab/cantera/@ThermoPhase/intEnergy_mole.m b/Cantera/matlab/cantera/@ThermoPhase/intEnergy_mole.m new file mode 100644 index 000000000..568558c7a --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/intEnergy_mole.m @@ -0,0 +1,3 @@ +function v = intEnergy_mole(a) +% INTENERGY_MOLE - Molar internal energy [J/kmol]. + v = thermo_get(a.tp_id,3); diff --git a/Cantera/matlab/cantera/@ThermoPhase/isIdealGas.m b/Cantera/matlab/cantera/@ThermoPhase/isIdealGas.m new file mode 100644 index 000000000..516bcff4d --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/isIdealGas.m @@ -0,0 +1,9 @@ +function v = isIdealGas(a) +% ISIDEALGAS - True if the phase is an ideal gas or ideal gas +% mixture, and false otherwise. +% + if eosType(a) == 1 + v = 1; +else + v = 0; +end diff --git a/Cantera/matlab/cantera/@ThermoPhase/massFractions.m b/Cantera/matlab/cantera/@ThermoPhase/massFractions.m new file mode 100644 index 000000000..7887e4697 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/massFractions.m @@ -0,0 +1,17 @@ +function x = massFractions(a) +% MASSFRACTIONS - Mass fractions. +% +% massFractions(phase); +% +% returns the array of species mass fractions for phase 'phase'. If +% no output argument is specified, a bar plot is produced. +% + x = phase_get(a.tp_id,21); + if nargout == 0 + figure + set(gcf,'Name','Mass Fractions') + bar(x) + xlabel('Species Number') + ylabel('Mass Fraction') + title('Species Mass Fractions') + end \ No newline at end of file diff --git a/Cantera/matlab/cantera/@ThermoPhase/maxTemp.m b/Cantera/matlab/cantera/@ThermoPhase/maxTemp.m new file mode 100644 index 000000000..2380cecae --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/maxTemp.m @@ -0,0 +1,12 @@ +function v = maxTemp(p) +% MAXTEMP - Maximum temperature. +% +% The parameterizations used to represent the temperature-dependent +% species thermodynamic properties are generally only valid in some +% finite temperature range, which may be different for each species +% in the phase. This method returns the highest temperature at which +% the parameterizations are valid for all species in the phase. +% +% See also: minTemp +% + v = thermo_get(p.tp_id,17); diff --git a/Cantera/matlab/cantera/@ThermoPhase/meanMolarMass.m b/Cantera/matlab/cantera/@ThermoPhase/meanMolarMass.m new file mode 100644 index 000000000..a9a6392de --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/meanMolarMass.m @@ -0,0 +1,8 @@ +function wtm = meanMolarMass(p) +% MEANMOLARMASS - Mean molar mass [kg/kmol]. +% +% The mean molar mass is the mole-fraction-weighted sum of the +% molar masses of the individual species in the phase. +% +wtm = phase_get(p.tp_id,4); + \ No newline at end of file diff --git a/Cantera/matlab/cantera/@ThermoPhase/meanMolecularWeight.m b/Cantera/matlab/cantera/@ThermoPhase/meanMolecularWeight.m new file mode 100644 index 000000000..faee89b0d --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/meanMolecularWeight.m @@ -0,0 +1,9 @@ +function wtm = meanMolecularWeight(p) +% MEANMOLECULARWEIGHT - Mean molecular weight. +% +% This method is a synonym for method meanMolarMass and is +% provided for backward compatibility. +% +% See also; meanMolarMass +% + wtm = meanMolarMass(p); \ No newline at end of file diff --git a/Cantera/matlab/cantera/@ThermoPhase/minTemp.m b/Cantera/matlab/cantera/@ThermoPhase/minTemp.m new file mode 100644 index 000000000..6b6db8f2a --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/minTemp.m @@ -0,0 +1,12 @@ +function v = minTemp(p) +% MINTEMP - Minimum temperature. +% +% The parameterizations used to represent the temperature-dependent +% species thermodynamic properties are generally only valid in some +% finite temperature range, which may be different for each species +% in the phase. This method returns the lowest temperature at which +% the parameterizations are valid for all species in the phase. +% +% See also: maxTemp +% + v = thermo_get(p.tp_id,16); diff --git a/Cantera/matlab/cantera/@ThermoPhase/molarDensity.m b/Cantera/matlab/cantera/@ThermoPhase/molarDensity.m new file mode 100644 index 000000000..8ab6664d0 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/molarDensity.m @@ -0,0 +1,4 @@ +function n = molarDensity(p) +% MOLARDENSITY - Molar density [kmol/m^3]. +% + n = phase_get(p.tp_id,3); diff --git a/Cantera/matlab/cantera/@ThermoPhase/molarMasses.m b/Cantera/matlab/cantera/@ThermoPhase/molarMasses.m new file mode 100644 index 000000000..390c0281c --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/molarMasses.m @@ -0,0 +1,4 @@ +function x = molarMasses(a) +% MOLARMASSES - Array of species molar masses [kg/kmol]. +% + x = phase_get(a.tp_id,22); diff --git a/Cantera/matlab/cantera/@ThermoPhase/moleFractions.m b/Cantera/matlab/cantera/@ThermoPhase/moleFractions.m new file mode 100644 index 000000000..8dbaa0169 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/moleFractions.m @@ -0,0 +1,17 @@ +function x = moleFractions(a) +% MOLEFRACTIONS - Mole fractions. +% +% moleFractions(phase) +% +% returns the array of species mole fractions for phase 'phase'. If +% no output argument is specified, a bar plot is produced. +% + x = phase_get(a.tp_id,20); + if nargout == 0 + figure + set(gcf,'Name','Mole Fractions') + bar(x) + xlabel('Species Number') + ylabel('Mole Fraction') + title('Species Mole Fractions') + end diff --git a/Cantera/matlab/cantera/@ThermoPhase/molecularWeights.m b/Cantera/matlab/cantera/@ThermoPhase/molecularWeights.m new file mode 100644 index 000000000..f073220c6 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/molecularWeights.m @@ -0,0 +1,9 @@ +function x = molecularWeights(a) +% MOLECULARWEIGHTS - Array of species molar masses [kg/kmol]. +% +% This method is deprecated - use molarMasses instead. +% +% See also: molarMasses +% + x = molarMasses(a); + diff --git a/Cantera/matlab/cantera/@ThermoPhase/nAtoms.m b/Cantera/matlab/cantera/@ThermoPhase/nAtoms.m new file mode 100644 index 000000000..30e1e2e51 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/nAtoms.m @@ -0,0 +1,7 @@ +function n = nAtoms(a,k,m) +% NATOMS - Number of atoms of element m in species k. +if nargin == 3 + n = phase_get(a.tp_id,14,k,m); +else + error('usage: nAtoms(phase, k, m)') +end \ No newline at end of file diff --git a/Cantera/matlab/cantera/@ThermoPhase/nElements.m b/Cantera/matlab/cantera/@ThermoPhase/nElements.m new file mode 100644 index 000000000..4ec6b7991 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/nElements.m @@ -0,0 +1,4 @@ +function n = nElements(a) +% NELEMENTS - Number of elements in the phase. +% +n = phase_get(a.tp_id,10); \ No newline at end of file diff --git a/Cantera/matlab/cantera/@ThermoPhase/nSpecies.m b/Cantera/matlab/cantera/@ThermoPhase/nSpecies.m new file mode 100644 index 000000000..cec4fb0b4 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/nSpecies.m @@ -0,0 +1,4 @@ +function n = nSpecies(a) +% NSPECIES - Number of species in the phase. +% +n = phase_get(a.tp_id,11); \ No newline at end of file diff --git a/Cantera/matlab/cantera/@ThermoPhase/ph.m b/Cantera/matlab/cantera/@ThermoPhase/ph.m new file mode 100644 index 000000000..4fe7bcc78 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/ph.m @@ -0,0 +1,3 @@ +function i = ph(t) +disp('method ph is deprecated.'); +i = t.ph; diff --git a/Cantera/matlab/cantera/@ThermoPhase/pressure.m b/Cantera/matlab/cantera/@ThermoPhase/pressure.m new file mode 100644 index 000000000..fe5d64424 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/pressure.m @@ -0,0 +1,4 @@ +function v = pressure(a) +% PRESSURE - Pressure [Pa]. +% +v = thermo_get(a.tp_id,8); diff --git a/Cantera/matlab/cantera/@ThermoPhase/private/phase_get.m b/Cantera/matlab/cantera/@ThermoPhase/private/phase_get.m new file mode 100644 index 000000000..5dc316adb --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/private/phase_get.m @@ -0,0 +1,8 @@ +function i = phase_get(n, job, a, b) +if nargin == 2 + i = ctmethods(30,n,job); +elseif nargin == 3 + i = ctmethods(30,n,job,a); +else + i = ctmethods(30, n, job, a, b); +end \ No newline at end of file diff --git a/Cantera/matlab/cantera/@ThermoPhase/private/phase_set.m b/Cantera/matlab/cantera/@ThermoPhase/private/phase_set.m new file mode 100644 index 000000000..2cbc21eff --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/private/phase_set.m @@ -0,0 +1,8 @@ +function phase_set(n, job, a, b) +if nargin == 2 + ctmethods(30,n,-job); +elseif nargin == 3 + ctmethods(30,n,-job,a); +else + ctmethods(30, n,-job, a, b); +end \ No newline at end of file diff --git a/Cantera/matlab/cantera/@ThermoPhase/private/thermo_get.m b/Cantera/matlab/cantera/@ThermoPhase/private/thermo_get.m new file mode 100644 index 000000000..984282169 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/private/thermo_get.m @@ -0,0 +1,8 @@ +function i = thermo_get(n, job, a, b) +if nargin == 2 + i = ctmethods(20,n, job); +elseif nargin == 3 + i = ctmethods(20,n, job,a); +else + i = ctmethods(20, n, job, a, b); +end \ No newline at end of file diff --git a/Cantera/matlab/cantera/@ThermoPhase/private/thermo_set.m b/Cantera/matlab/cantera/@ThermoPhase/private/thermo_set.m new file mode 100644 index 000000000..3ffd94c30 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/private/thermo_set.m @@ -0,0 +1,8 @@ +function i = thermo_set(n, job, a, b) +if nargin == 2 + i = ctmethods(20,n,-job); +elseif nargin == 3 + i = ctmethods(20,n,-job,a); +else + i = ctmethods(20, n,-job, a, b); +end \ No newline at end of file diff --git a/Cantera/matlab/cantera/@ThermoPhase/refPressure.m b/Cantera/matlab/cantera/@ThermoPhase/refPressure.m new file mode 100644 index 000000000..4283d6fab --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/refPressure.m @@ -0,0 +1,6 @@ +function v = refPressure(p) +% REFPRESSURE - Reference pressure [Pa]. +% +% All standard-state thermodynamic properties are for this pressure. +% +v = thermo_get(p.tp_id,15); diff --git a/Cantera/matlab/cantera/@ThermoPhase/set.m b/Cantera/matlab/cantera/@ThermoPhase/set.m new file mode 100644 index 000000000..9a2deaca4 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/set.m @@ -0,0 +1,16 @@ +function a = set(a,varargin) +% SET Set phase properties and return the updated object +property_argin = varargin; +while length(property_argin) >= 2, + prop = property_argin{1}; + val = property_argin{2}; + property_argin = property_argin(3:end); + switch prop + case 'Temperature' + phase_set(a.tp_id,1,val); + case 'Density' + phase_set(a.tp_id,2,val); + otherwise + error('Phase properties: Temperature, Density') + end +end \ No newline at end of file diff --git a/Cantera/matlab/cantera/@ThermoPhase/setDensity.m b/Cantera/matlab/cantera/@ThermoPhase/setDensity.m new file mode 100644 index 000000000..9a902187a --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/setDensity.m @@ -0,0 +1,10 @@ +function a = setDensity(a,rho) +% SETDENSITY - Set the density [kg/m^3]. +% +% setDensity(phase, 0.01); +% +if rho <= 0.0 + error('the density must be positive'); +end + +phase_set(a.tp_id,2,rho); diff --git a/Cantera/matlab/cantera/@ThermoPhase/setMassFractions.m b/Cantera/matlab/cantera/@ThermoPhase/setMassFractions.m new file mode 100644 index 000000000..47001616c --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/setMassFractions.m @@ -0,0 +1,48 @@ +function a = setMassFractions(a, y, norm) +% SETMASSFRACTIONS Set the species mass fractions. +% +% setMassFractions(a,y) +% +% If y is a vector of doubles, this call sets the species mass +% fractions to the values in y and then scales them so that they +% sum to 1.0. The length of y must equal the number of species. +% +% If y is a string, then the mass fractions of the listed +% species are set to the specified values, and all others are +% set to zero. The syntax for the string is as shown in these +% examples: +% 'CH4:4, O2:2, AR:3' +% 'SIH2:0.9,H2:0.1' +% +% setMassFractions(a, y, 'nonorm') +% +% As above, but the normalization step is skipped. This only +% works if y is an array, not a string. Since unnormalized mass +% fractions can lead to unphysical results, 'nonorm' should be +% used only in rare cases, such as computing partial +% derivatives with respect to a species mass fraction. +% +% Note that calling setMassFractions leaves the temperature and +% density unchanged, and therefore the pressure changes if the new +% composition has a molar mass that is different than the old +% composition. If it is desired to change the composition and hold +% the pressure fixed, use method 'set' (defined in class Solution) +% instead, or call setPressure after calling setMassFractions. +% +if isa(y,'double') + if nargin == 3 + if strcmp(norm,'nonorm') + phase_set(a.tp_id,23,y); + else + phase_set(a.tp_id,21,y); + end + else + phase_set(a.tp_id,21,y); + end +% +% string input +% +elseif isa(y,'char') + phase_set(a.tp_id,31,y); +end + diff --git a/Cantera/matlab/cantera/@ThermoPhase/setMoleFractions.m b/Cantera/matlab/cantera/@ThermoPhase/setMoleFractions.m new file mode 100644 index 000000000..7f332942d --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/setMoleFractions.m @@ -0,0 +1,47 @@ +function a = setMoleFractions(a,x,norm) +% SETMOLEFRACTIONS Set the species mole fractions. +% +% setMoleFractions(a,x) +% +% If x is a vector of doubles, this call sets the species mole +% fractions to the values in x and then scales them so that they +% sum to 1.0. The length of x must equal the number of species. +% +% If x is a string, then the mole fractions of the listed +% species are set to the specified values, and all others are +% set to zero. The syntax for the string is as shown in these +% examples: +% 'CH4:4, O2:2, AR:3' +% 'SIH2:0.9,H2:0.1' +% +% setMoleFractions(a, x, 'nonorm') +% +% As above, but the normalization step is skipped. This only +% works if x is an array, not a string. Since unnormalized mole +% fractions can lead to unphysical results, 'nonorm' should be +% used only in rare cases, such as computing partial +% derivatives with respect to a species mole fraction. +% +% Note that calling setMoleFractions leaves the temperature and +% density unchanged, and therefore the pressure changes if the new +% composition has a molar mass that is different than the old +% composition. If it is desired to change the composition and hold +% the pressure fixed, use method 'set' (defined in class Solution) +% instead, or call setPressure after calling setMoleFractions. + +if isa(x,'double') + if nargin == 3 + if strcmp(norm,'nonorm') + phase_set(a.tp_id,22,x); + else + phase_set(a.tp_id,20,x); + end + else + phase_set(a.tp_id,20,x); + end +% +% string input +% +elseif isa(x,'char') + phase_set(a.tp_id,30,x); +end diff --git a/Cantera/matlab/cantera/@ThermoPhase/setPressure.m b/Cantera/matlab/cantera/@ThermoPhase/setPressure.m new file mode 100644 index 000000000..cf6e41887 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/setPressure.m @@ -0,0 +1,11 @@ +function a = setPressure(a,p) +% SETPRESSURE Set the pressure [Pa]. +% +% The pressure is set by changing the density holding the +% temperature and chemical composition fixed. +% +if p <= 0.0 + error('the pressure must be positive') +end + +thermo_set(a.tp_id,1,p); \ No newline at end of file diff --git a/Cantera/matlab/cantera/@ThermoPhase/setState.m b/Cantera/matlab/cantera/@ThermoPhase/setState.m new file mode 100644 index 000000000..83b3d2961 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/setState.m @@ -0,0 +1,12 @@ +function a = setState(a,job,values) +disp('deprecated') +if nargin ~= 3 | ~isa(job,'char') + error('Syntax error. Type "help setState" for more information.') +end + +switch job + case 'T' + setTemperature(a,values) + otherwise + error(['unknown flag: ' job]) +end diff --git a/Cantera/matlab/cantera/@ThermoPhase/setState_HP.m b/Cantera/matlab/cantera/@ThermoPhase/setState_HP.m new file mode 100644 index 000000000..257645959 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/setState_HP.m @@ -0,0 +1,13 @@ +function a = setState_HP(a,hp) +% SETSTATE_HP - Set the specific enthalpy [J/kg] and pressure [Pa]. +% +% setState_HP(a, hp) sets the specific enthalpy and pressure +% of object a, holding its composition fixed. Argument 'hp' must +% be a vector of length 2 containing the desired values for the specific +% enthalpy (J/kg) and pressure (Pa). +% +if hp(2) <= 0.0 + error('the pressure must be positive'); +end + +thermo_set(a.tp_id,20,hp); diff --git a/Cantera/matlab/cantera/@ThermoPhase/setState_SP.m b/Cantera/matlab/cantera/@ThermoPhase/setState_SP.m new file mode 100644 index 000000000..fa8899aed --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/setState_SP.m @@ -0,0 +1,15 @@ +function a = setState_SP(a,sp) +% SETSTATE_SP Set the specific entropy [J/kg/K] and pressure [Pa]. +% +% setState_SP(a, sp) sets the specific entropy and pressure +% of object a, holding its composition fixed. Argument 'sp' must +% be a vector of length 2 containing the desired values for the specific +% entropy (J/kg/K) and pressure (Pa). +% +if sp(1) <= 0.0 + error('the pressure must be positive'); +end +if sp(2) <= 0.0 + error('the specific entropy must be positive'); +end +thermo_set(a.tp_id,23,sp); diff --git a/Cantera/matlab/cantera/@ThermoPhase/setState_UV.m b/Cantera/matlab/cantera/@ThermoPhase/setState_UV.m new file mode 100644 index 000000000..3f425a7a0 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/setState_UV.m @@ -0,0 +1,14 @@ +function a = setState_UV(a,uv) +% SETSTATE_UV Set the specific internal energy [J/kg] and +% specific volume [m^3/kg]. +% +% setState_UV(a, uv) sets the specific internal energy and +% specific volume of object a, holding its composition +% fixed. Argument 'uv' must be a vector of length 2 containing +% the desired values for the specific internal energy (J/kg) and +% specific volume (m^3/kg). +% +if uv(2) <= 0.0 + error('the specific volume must be positive'); +end +thermo_set(a.tp_id,21,uv); diff --git a/Cantera/matlab/cantera/@ThermoPhase/setTemperature.m b/Cantera/matlab/cantera/@ThermoPhase/setTemperature.m new file mode 100644 index 000000000..e2cdec900 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/setTemperature.m @@ -0,0 +1,7 @@ +function a = setTemperature(a,t) +% SETTEMPERATURE Set the temperature [K]. +% +if (t <= 0) + error('the temperature must be positive'); +end +phase_set(a.tp_id,1,t); diff --git a/Cantera/matlab/cantera/@ThermoPhase/speciesIndex.m b/Cantera/matlab/cantera/@ThermoPhase/speciesIndex.m new file mode 100644 index 000000000..016618fb2 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/speciesIndex.m @@ -0,0 +1,16 @@ +function n = speciesIndex(a,name) +% SPECIESINDEX - The species index of species with name 'name'. +% +% The index is an integer assigned to each species in sequence as it +% is read in from the input file. +% +% NOTE: In keeping with the conventions used by Matlab, this method +% returns 1 for the first species, 2 for the second, etc. In +% contrast, the corresponding method speciesIndex in the Cantera C++ +% and Python interfaces returns 0 for the first species, 1 for the +% second one, etc. +% +% ich4 = speciesIndex(gas, 'CH4'); +% iho2 = speciesIndex(gas, 'HO2'); +% +n = phase_get(a.tp_id,12,name); \ No newline at end of file diff --git a/Cantera/matlab/cantera/@ThermoPhase/speciesName.m b/Cantera/matlab/cantera/@ThermoPhase/speciesName.m new file mode 100644 index 000000000..9d057c6e1 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/speciesName.m @@ -0,0 +1,16 @@ +function nm = speciesName(a, k) +% SPECIESNAME - Name of species k. +% If k is a scalar integer, the return value will be a string +% containing the name of the kth species. If it is an array of +% integers, the output will be a cell array of +% the same shape containing the name strings. +% +[m, n] = size(k); +nm = {}; +for i = 1:m + for j = 1:n + nm{i,j} = phase_get(a.tp_id, 40, k(i,j)); + end +end + + diff --git a/Cantera/matlab/cantera/@ThermoPhase/speciesNames.m b/Cantera/matlab/cantera/@ThermoPhase/speciesNames.m new file mode 100644 index 000000000..4c932066d --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/speciesNames.m @@ -0,0 +1,2 @@ +function n = speciesNames(a) +n = speciesName(a,1:nSpecies(a)); diff --git a/Cantera/matlab/cantera/@ThermoPhase/temperature.m b/Cantera/matlab/cantera/@ThermoPhase/temperature.m new file mode 100644 index 000000000..74343625b --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/temperature.m @@ -0,0 +1,3 @@ +function t = temperature(p) +% TEMPERATURE - temperature [K]. +t = phase_get(p.tp_id,1); diff --git a/Cantera/matlab/cantera/@ThermoPhase/thermo_hndl.m b/Cantera/matlab/cantera/@ThermoPhase/thermo_hndl.m new file mode 100644 index 000000000..f26dc3308 --- /dev/null +++ b/Cantera/matlab/cantera/@ThermoPhase/thermo_hndl.m @@ -0,0 +1,2 @@ +function i = thermo_hndl(p) +i = p.tp_id; diff --git a/Cantera/matlab/cantera/@Transport/Transport.m b/Cantera/matlab/cantera/@Transport/Transport.m new file mode 100755 index 000000000..fd97a95d1 --- /dev/null +++ b/Cantera/matlab/cantera/@Transport/Transport.m @@ -0,0 +1,21 @@ +function tr = Transport(model, th, loglevel) +%TRANSPORT Transport class constructor. +% +% k = TRANSPORT(model, p, loglevel) creates a transport +% manager for phase object p. +% +% The 'model' parameter is a string that specifies the transport +% model. The phase object must have already been created. +% +tr.id = 0; +if nargin == 3 + tr.th = th; + tr.model = model; + tr.id = trans_get(hndl(th), -1, model, loglevel) ; + tr = class(tr,'Transport'); +elseif isa(model,'Transport') + tr = model; +else + error('syntax error') +end + diff --git a/Cantera/matlab/cantera/@Transport/binDiffCoeffs.m b/Cantera/matlab/cantera/@Transport/binDiffCoeffs.m new file mode 100755 index 000000000..2eceb18ed --- /dev/null +++ b/Cantera/matlab/cantera/@Transport/binDiffCoeffs.m @@ -0,0 +1,10 @@ +function v = binDiffCoeffs(a) +%BINDIFFCOEFFS Binary diffusion coefficients (m^2/s). +% +% d = binDiffCoeffs(gas) +% +% returns the matrix of binary diffusion coefficients in array +% d. The matrix is symmetric: d(i,j) = d(j,i). +% +v = trans_get(a.id, 21, nSpecies(a.th)); + diff --git a/Cantera/matlab/cantera/@Transport/hndl.m b/Cantera/matlab/cantera/@Transport/hndl.m new file mode 100755 index 000000000..d8ce4d46f --- /dev/null +++ b/Cantera/matlab/cantera/@Transport/hndl.m @@ -0,0 +1,2 @@ +function n = hndl(a) +n = a.id; diff --git a/Cantera/matlab/cantera/@Transport/mixDiffCoeffs.m b/Cantera/matlab/cantera/@Transport/mixDiffCoeffs.m new file mode 100755 index 000000000..8ca7074f4 --- /dev/null +++ b/Cantera/matlab/cantera/@Transport/mixDiffCoeffs.m @@ -0,0 +1,20 @@ +function v = mixDiffCoeffs(a) +%MIXDIFFCOEFFS Mixture-averaged diffusion coefficients (m^2/s). +% +% d = mixDiffCoeffs(gas) +% +% returns in column vector d the mixture-averaged diffusion +% coefficients. Object 'gas' must belong to a class derived from +% Transport, and that was constructed by specifying the 'Mix' +% option. If 'Mix' was not specified, you will get the error message +% +% **** Method getMixDiffCoeffs not implemented. **** +% +% In this case, try method 'multiDiffCoeffs', or create a new gas +% mixture model that uses a mixture-averaged transport manager, +% for example: +% +% gas = GRI30('Mix') +% +v = trans_get(a.id, 11, nSpecies(a.th)); + diff --git a/Cantera/matlab/cantera/@Transport/multiDiffCoeffs.m b/Cantera/matlab/cantera/@Transport/multiDiffCoeffs.m new file mode 100755 index 000000000..4f6cf3cd3 --- /dev/null +++ b/Cantera/matlab/cantera/@Transport/multiDiffCoeffs.m @@ -0,0 +1,20 @@ +function v = multiDiffCoeffs(a) +%MULTIDIFFCOEFFS Multicomponent diffusion coefficients (m^2/s). +% +% d = multiDiffCoeffs(gas) +% +% returns in d the array of multicomponent diffusion +% coefficients. Object 'gas' must belong to a class derived from +% Transport, and that was constructed by specifying the 'Multi' +% option. If 'Multi' was not specified, you will get the error message +% +% **** Method getMultiDiffCoeffs not implemented. **** +% +% In this case, try method 'mixDiffCoeffs', or create a new gas +% mixture model that uses a multicomponent transport manager, +% for example: +% +% gas = GRI30('Multi') +% +v = trans_get(a.id, 22, nSpecies(a.th)); + diff --git a/Cantera/matlab/cantera/@Transport/private/newTransport.cpp b/Cantera/matlab/cantera/@Transport/private/newTransport.cpp new file mode 100755 index 000000000..7d25cbec0 --- /dev/null +++ b/Cantera/matlab/cantera/@Transport/private/newTransport.cpp @@ -0,0 +1,54 @@ + +#include "mex.h" +#include "../../../../clib/src/ct.h" +#include "../../private/ctmatutils.h" + +extern "C" { + + static void reportError() { + int buflen = 300; + char* output_buf = (char*)mxCalloc(buflen, sizeof(char)); + getCanteraError(buflen, output_buf); + mexErrMsgTxt(output_buf); + } + + /* + * Create a Cantera 'Transport' object + */ + void mexFunction( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) + { + try { + + // Check for proper number of arguments + if(nrhs != 3) { + mexErrMsgTxt("Three inputs required."); + } + else if(nlhs > 1) { + mexErrMsgTxt("Too many output arguments"); + } + + //int model = getInt(prhs[0]); + int ph = getInt(prhs[1]); + int loglevel = getInt(prhs[2]); + + int buflen = (mxGetM(prhs[0]) * mxGetN(prhs[0])) + 1; + char* model = (char*)mxCalloc(buflen, sizeof(char)); + int status = mxGetString(prhs[0],model,buflen); + if (status != 0) + mexErrMsgTxt("error reading model."); + + int n = newTransport(model, ph, loglevel); + if (n < 0) mexErrMsgTxt("Unknown transport model"); + + // Create matrix for the return argument. + plhs[0] = mxCreateDoubleMatrix(1,1, mxREAL); + double* x = mxGetPr(plhs[0]); + *x = n; + } + catch (...) { + reportError(); + //mexErrMsgTxt("exception raised in newTransport."); + } + } +} diff --git a/Cantera/matlab/cantera/@Transport/private/trans_get.m b/Cantera/matlab/cantera/@Transport/private/trans_get.m new file mode 100644 index 000000000..f3848e593 --- /dev/null +++ b/Cantera/matlab/cantera/@Transport/private/trans_get.m @@ -0,0 +1,14 @@ +function v = trans_get(n, job, a, b, c, d) +% TRANS_GET - get transport attributes +% +if nargin == 2 + v = ctmethods(50, n, job); +elseif nargin == 3 + v = ctmethods(50, n, job, a); +elseif nargin == 4 + v = ctmethods(50, n, job, a, b); +elseif nargin == 5 + v = ctmethods(50, n, job, a, b, c); +elseif nargin == 6 + v = ctmethods(50, n, job, a, b, c, d); +end diff --git a/Cantera/matlab/cantera/@Transport/private/trans_methods.cpp b/Cantera/matlab/cantera/@Transport/private/trans_methods.cpp new file mode 100755 index 000000000..0faaad75a --- /dev/null +++ b/Cantera/matlab/cantera/@Transport/private/trans_methods.cpp @@ -0,0 +1,82 @@ + +#include "mex.h" +#include "../../../../clib/src/ct.h" +#include "../../private/ctmatutils.h" +#include + +extern "C" { + + void mexFunction( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) + { + double vv; + int n = getInt(prhs[0]); + int job = getInt(prhs[1]); + double* h; + int iok = 0; + int nsp; + + if (job < 10) { + + bool ok = true; + switch (job) { + case 0: + delTransport(n); + vv = 0.0; + break; + case 1: + vv = trans_viscosity(n); + break; + case 2: + vv = trans_thermalConductivity(n); break; + default: + mexErrMsgTxt("unknown Transport method"); + } + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + h = mxGetPr(plhs[0]); + *h = vv; + return; + } + else if (job < 20) { + nsp = getInt(prhs[2]); + plhs[0] = mxCreateNumericMatrix(nsp,1,mxDOUBLE_CLASS,mxREAL); + h = mxGetPr(plhs[0]); + + switch (job) { + case 11: + iok = trans_getMixDiffCoeffs(n, nsp, h); break; + case 12: + iok = trans_getThermalDiffCoeffs(n, nsp, h); break; + default: + mexErrMsgTxt("unknown Transport method"); + } + } + else if (job < 30) { + nsp = getInt(prhs[2]); + plhs[0] = mxCreateNumericMatrix(nsp,nsp,mxDOUBLE_CLASS,mxREAL); + h = mxGetPr(plhs[0]); + switch (job) { + case 21: + iok = trans_getBinDiffCoeffs(n, nsp, h); break; + case 22: + iok = trans_getMultiDiffCoeffs(n, nsp, h); break; + default: + mexErrMsgTxt("unknown Transport method"); + } + } + else { + mexErrMsgTxt("unknown Transport method"); + } + if (iok < 0) { + if (iok == -1) { + int buflen = 80; + char* buf = (char*)mxCalloc(buflen, sizeof(char)); + getCanteraError(buflen, buf); + mexErrMsgTxt(buf); + } + else { + mexErrMsgTxt("exception thrown."); + } + } + } +} diff --git a/Cantera/matlab/cantera/@Transport/thermalConductivity.m b/Cantera/matlab/cantera/@Transport/thermalConductivity.m new file mode 100755 index 000000000..4dddfe2ac --- /dev/null +++ b/Cantera/matlab/cantera/@Transport/thermalConductivity.m @@ -0,0 +1,8 @@ +function v = thermalConductivity(a) +% THERMALCONDUCTIVITY Thermal conductivity in W/m^2/K. +v = trans_get(a.id, 2); +if v == -1.0 + error(geterr); +elseif v < 0.0 + error('exception raised'); +end \ No newline at end of file diff --git a/Cantera/matlab/cantera/@Transport/thermalDiffCoeffs.m b/Cantera/matlab/cantera/@Transport/thermalDiffCoeffs.m new file mode 100755 index 000000000..0d591433f --- /dev/null +++ b/Cantera/matlab/cantera/@Transport/thermalDiffCoeffs.m @@ -0,0 +1,13 @@ +function v = thermalDiffCoeffs(a) +%THERMALDIFFCOEFFS Thermal diffusion coefficients. +% +% dt = thermalDiffCoeffs(gas) +% +% returns in column vector dt the thermal diffusion +% coefficients. Object 'gas' must belong to a class derived from +% Transport, and that was constructed by specifying the 'Multi' +% option. If 'Multi' was not specified, the returned values will +% all be zero. +% +v = trans_get(a.id, 12, nSpecies(a.th)); + diff --git a/Cantera/matlab/cantera/@Transport/viscosity.m b/Cantera/matlab/cantera/@Transport/viscosity.m new file mode 100755 index 000000000..87a4bd509 --- /dev/null +++ b/Cantera/matlab/cantera/@Transport/viscosity.m @@ -0,0 +1,8 @@ +function v = viscosity(a) +v = trans_get(a.id, 1); +if v == -1.0 + error(geterr); +elseif v < 0.0 + error('exception raised'); +end + diff --git a/Cantera/matlab/cantera/@Wall/Wall.m b/Cantera/matlab/cantera/@Wall/Wall.m new file mode 100644 index 000000000..d4c6fc054 --- /dev/null +++ b/Cantera/matlab/cantera/@Wall/Wall.m @@ -0,0 +1,14 @@ +function x = Wall(typ) +% +if nargin == 0 + typ = 1; +end +x.index = wallmethods(0,typ); +if x.index < 0 + error(geterr); +end +x.left = -1; +x.right = -1; +x = class(x,'Wall'); + + diff --git a/Cantera/matlab/cantera/@Wall/area.m b/Cantera/matlab/cantera/@Wall/area.m new file mode 100644 index 000000000..d9263e1d4 --- /dev/null +++ b/Cantera/matlab/cantera/@Wall/area.m @@ -0,0 +1,5 @@ +function a = area(w) +% AREA - +% +a = wallmethods(23, wall_hndl(w)) + diff --git a/Cantera/matlab/cantera/@Wall/install.m b/Cantera/matlab/cantera/@Wall/install.m new file mode 100644 index 000000000..b34ad5590 --- /dev/null +++ b/Cantera/matlab/cantera/@Wall/install.m @@ -0,0 +1,8 @@ +function install(w, left, right) +% INSTALL - +% +w.left = left; +w.right = right; +wallmethods(4, wall_hndl(w), reactor_hndl(left), ... + reactor_hndl(right)); + diff --git a/Cantera/matlab/cantera/@Wall/private/wallmethods.cpp b/Cantera/matlab/cantera/@Wall/private/wallmethods.cpp new file mode 100644 index 000000000..9129070db --- /dev/null +++ b/Cantera/matlab/cantera/@Wall/private/wallmethods.cpp @@ -0,0 +1,116 @@ + +#include "mex.h" +#include "../../../../clib/src/ctreactor.h" +#include "../../../../clib/src/ct.h" +#include "../../private/ctmatutils.h" + +const double Undef = -999.123; + +extern "C" { + + + void reportError() { + int buflen = 300; + char* output_buf = (char*)mxCalloc(buflen, sizeof(char)); + getCanteraError(buflen, output_buf); + mexErrMsgTxt(output_buf); + } + + + void mexFunction( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) + { + int j, m, iok, n; + char *file, *key, *val; + + int job = getInt(prhs[0]); + int i = getInt(prhs[1]); + + double r = Undef; + double v = Undef; + if (nrhs > 2) v = getDouble(prhs[2]); + + // constructor + if (job == 0) { + n = wall_new(i); + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = double(n); + if (n < 0) reportError(); + return; + } + + // options that do not return a value + + if (job < 20) { + switch (job) { + + case 1: + iok = wall_del(i); + break; + case 2: + iok = wall_copy(i); + break; + case 3: + iok = wall_assign(i,int(v)); + break; + case 4: + m = getInt(prhs[3]); + iok = wall_install(i, int(v), m); + break; + case 5: + iok = wall_setArea(i, v); + break; + case 6: + iok = wall_setThermalResistance(i, v); + break; + case 7: + iok = wall_setHeatTransferCoeff(i, v); + break; + case 8: + iok = wall_setHeatFlux(i, int(v)); + break; + case 9: + iok = wall_setExpansionRateCoeff(i, v); + break; + case 10: + iok = wall_setExpansionRate(i, int(v)); + break; + case 11: + iok = wall_ready(i); + break; + default: + mexErrMsgTxt("unknown job parameter"); + } + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = double(iok); + if (iok < 0) reportError(); + return; + } + + + // options that return a value of type 'double' + + else if (job < 40) { + switch (job) { + case 21: + r = wall_vdot(i, v); + break; + case 22: + r = wall_Q(i, v); + break; + case 23: + r = wall_area(i); + break; + default: + mexErrMsgTxt("unknown job parameter"); + } + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = r; + if (r == Undef) reportError(); + return; + } + } +} diff --git a/Cantera/matlab/cantera/@Wall/private/wallmethods.m b/Cantera/matlab/cantera/@Wall/private/wallmethods.m new file mode 100644 index 000000000..188f50e9a --- /dev/null +++ b/Cantera/matlab/cantera/@Wall/private/wallmethods.m @@ -0,0 +1,13 @@ +function v = wallmethods(n, job, a, b, c, d) +% +if nargin == 2 + v = ctmethods(70, n, job); +elseif nargin == 3 + v = ctmethods(70, n, job, a); +elseif nargin == 4 + v = ctmethods(70, n, job, a, b); +elseif nargin == 5 + v = ctmethods(70, n, job, a, b, c); +elseif nargin == 6 + v = ctmethods(70, n, job, a, b, c, d); +end \ No newline at end of file diff --git a/Cantera/matlab/cantera/@Wall/ready.m b/Cantera/matlab/cantera/@Wall/ready.m new file mode 100644 index 000000000..25ab582e4 --- /dev/null +++ b/Cantera/matlab/cantera/@Wall/ready.m @@ -0,0 +1,5 @@ +function ok = ready(w) +% READY - +% +ok = wallmethods(11, wall_hndl(w)); + diff --git a/Cantera/matlab/cantera/@Wall/setArea.m b/Cantera/matlab/cantera/@Wall/setArea.m new file mode 100644 index 000000000..ede46e58c --- /dev/null +++ b/Cantera/matlab/cantera/@Wall/setArea.m @@ -0,0 +1,5 @@ +function setArea(w, a) +% SETAREA - +% +wallmethods(5, wall_hndl(w), a); + diff --git a/Cantera/matlab/cantera/@Wall/setExpansionRateCoeff.m b/Cantera/matlab/cantera/@Wall/setExpansionRateCoeff.m new file mode 100644 index 000000000..66e6bc300 --- /dev/null +++ b/Cantera/matlab/cantera/@Wall/setExpansionRateCoeff.m @@ -0,0 +1,5 @@ +function setExpansionRateCoeff(w, k) +% SETEXPANSIONRATECOEFF - +% +wallmethods(9, wall_hndl(w), k); + diff --git a/Cantera/matlab/cantera/@Wall/setHeatTransferCoeff.m b/Cantera/matlab/cantera/@Wall/setHeatTransferCoeff.m new file mode 100644 index 000000000..eed158c2e --- /dev/null +++ b/Cantera/matlab/cantera/@Wall/setHeatTransferCoeff.m @@ -0,0 +1,5 @@ +function setHeatTransferCoeff(w, u) +% SETHEATTRANSFERCOEFF - +% +wallmethods(7, wall_hndl(w), u); + diff --git a/Cantera/matlab/cantera/@Wall/setThermalResistance.m b/Cantera/matlab/cantera/@Wall/setThermalResistance.m new file mode 100644 index 000000000..1b9aed568 --- /dev/null +++ b/Cantera/matlab/cantera/@Wall/setThermalResistance.m @@ -0,0 +1,5 @@ +function setThermalResistance(w, r) +% SETTHERMALRESISTANCE - +% +wallmethods(6, wall_hndl(w), r) + diff --git a/Cantera/matlab/cantera/@Wall/wall_hndl.m b/Cantera/matlab/cantera/@Wall/wall_hndl.m new file mode 100644 index 000000000..6d1ed3d96 --- /dev/null +++ b/Cantera/matlab/cantera/@Wall/wall_hndl.m @@ -0,0 +1,4 @@ +function i = wall_hndl(w) +% WALL_HNDL - +% +i = w.index; \ No newline at end of file diff --git a/Cantera/matlab/cantera/@XML_Node/XML_Node.m b/Cantera/matlab/cantera/@XML_Node/XML_Node.m new file mode 100644 index 000000000..6fd9228fd --- /dev/null +++ b/Cantera/matlab/cantera/@XML_Node/XML_Node.m @@ -0,0 +1,24 @@ +function x = XML_Node(name, src, root, wrap) +%XML_Node Cantera XML_Node class constructor +% +x.id = 0; +x.root = 0; +if nargin == 4 + x.id = wrap; + x.root = root; +elseif nargin > 0 + % create an empty node with name 'name' + x.id = ctmethods(10,0,0,name); % newxml(name) + if x.id < 0 + error(geterr); + end +end +if nargin > 2 + x.root = root; +end + +x = class(x,'XML_Node'); + +if nargin > 1 & nargin < 4 + build(x, src); +end diff --git a/Cantera/matlab/cantera/@XML_Node/attrib.m b/Cantera/matlab/cantera/@XML_Node/attrib.m new file mode 100644 index 000000000..30ed919f0 --- /dev/null +++ b/Cantera/matlab/cantera/@XML_Node/attrib.m @@ -0,0 +1,9 @@ +function x = attrib(x, key) + +if nargin ~= 2 | ~isa(key,'char') + error('Syntax error. Type "help attrib" for more information.') +end + +iok = ctmethods(10, 20, x.id, key); + + diff --git a/Cantera/matlab/cantera/@XML_Node/build.m b/Cantera/matlab/cantera/@XML_Node/build.m new file mode 100644 index 000000000..a7c46d51f --- /dev/null +++ b/Cantera/matlab/cantera/@XML_Node/build.m @@ -0,0 +1,9 @@ +function x = build(x, file) + +if nargin ~= 2 | ~isa(file,'char') + error('Syntax error. Type "help build" for more information.') +end + +iok = ctmethods(10, 4, x.id, file); + + diff --git a/Cantera/matlab/cantera/@XML_Node/child.m b/Cantera/matlab/cantera/@XML_Node/child.m new file mode 100644 index 000000000..410398af1 --- /dev/null +++ b/Cantera/matlab/cantera/@XML_Node/child.m @@ -0,0 +1,6 @@ +function v = child(x, loc) + +id = ctmethods(10, 6, x.id, loc); +v = XML_Node('', '', x.root, id); + + diff --git a/Cantera/matlab/cantera/@XML_Node/hndl.m b/Cantera/matlab/cantera/@XML_Node/hndl.m new file mode 100644 index 000000000..4061904d7 --- /dev/null +++ b/Cantera/matlab/cantera/@XML_Node/hndl.m @@ -0,0 +1,2 @@ +function i = hndl(x) +i = x.id; diff --git a/Cantera/matlab/cantera/@XML_Node/private/newxml.cpp b/Cantera/matlab/cantera/@XML_Node/private/newxml.cpp new file mode 100644 index 000000000..6c4e4ec4d --- /dev/null +++ b/Cantera/matlab/cantera/@XML_Node/private/newxml.cpp @@ -0,0 +1,34 @@ + +#include "mex.h" +#include "../../../../clib/src/ctxml.h" +#include "../../private/ctmatutils.h" + + +extern "C" { + + /* + * Create a Cantera 'XML_Node' object + */ + void mexFunction( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) + { + // Check for proper number of arguments + if(nrhs != 1) { + mexErrMsgTxt("One input required."); + } + else if(nlhs > 1) { + mexErrMsgTxt("Too many output arguments"); + } + char* input_buf = getString(prhs[0]); + int id = 0; + //try { + id = xml_new(input_buf); + //} + //catch (...) { + //mexErrMsgTxt("exception occurred"); + //} + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = double(id); + } +} diff --git a/Cantera/matlab/cantera/@XML_Node/private/xmlmethods.cpp b/Cantera/matlab/cantera/@XML_Node/private/xmlmethods.cpp new file mode 100644 index 000000000..da2d4b725 --- /dev/null +++ b/Cantera/matlab/cantera/@XML_Node/private/xmlmethods.cpp @@ -0,0 +1,158 @@ + +#include "mex.h" +#include "../../../../clib/src/ctxml.h" +#include "../../../../clib/src/ct.h" +#include "../../private/ctmatutils.h" + + +extern "C" { + + static bool nargs_ok(int job, int n) { + switch (n) { + case 1: case 2: case 10: case 21: case 22: + return (n == 2); + case 3: case 4: case 6: case 7: case 8: case 9: + case 13: case 14: case 20: + return (n == 3); + case 5: case 11: case 12: + return (n == 4); + default: + return true; + } + } + + static void reportError() { + int buflen = 300; + char* output_buf = (char*)mxCalloc(buflen, sizeof(char)); + getCanteraError(buflen, output_buf); + mexErrMsgTxt(output_buf); + } + + + /* + * Create a Cantera 'XML_Node' object + */ + void mexFunction( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) + { + int j, m, iok, id; + char *file, *key, *val, *nm; + + int job = getInt(prhs[0]); + int i = getInt(prhs[1]); + + // Check for proper number of arguments + if (!nargs_ok(job,nrhs)) { + mexErrMsgTxt("Wrong number of inputs."); + return; + } + else if(nlhs > 1) { + mexErrMsgTxt("Too many output arguments"); + } + + + // options that do not return a value + + if (job < 20) { + switch (job) { + case 0: + nm = getString(prhs[2]); + iok = xml_new(nm); + break; + case 1: + iok = xml_del(i); + break; + case 2: + iok = xml_copy(i); + break; + case 3: + j = getInt(prhs[2]); + iok = xml_assign(i,j); + break; + case 4: + file = getString(prhs[2]); + iok = xml_build(i, file); + break; + case 5: + key = getString(prhs[2]); + val = getString(prhs[3]); + iok = xml_addAttrib(i, key, val); + break; + case 6: + key = getString(prhs[2]); + iok = xml_child(i, key); + break; + case 7: + m = getInt(prhs[2]); + iok = xml_child_bynumber(i, m); + break; + case 8: + key = getString(prhs[2]); + iok = xml_findID(i, key); + break; + case 9: + key = getString(prhs[2]); + iok = xml_findByName(i, key); + break; + case 10: + iok = xml_nChildren(i); + break; + case 11: + key = getString(prhs[2]); + val = getString(prhs[3]); + iok = xml_addChild(i, key, val); + break; + case 12: + key = getString(prhs[2]); + j = getInt(prhs[3]); + iok = xml_addChildNode(i, j); + break; + case 13: + file = getString(prhs[2]); + iok = xml_write(i, file); + break; + case 14: + j = getInt(prhs[2]); + iok = xml_removeChild(i, j); + break; + + default: + mexErrMsgTxt("unknown job parameter"); + } + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = double(iok); + if (iok < 0) reportError(); + return; + } + + // options that return strings + + char* v = (char*)mxCalloc(80, sizeof(char)); + switch (job) { + case 20: + // return an attribute + key = getString(prhs[2]); + iok = xml_attrib(i, key, v); + break; + case 21: + // return the value of the node + iok = xml_value(i, v); + break; + case 22: + iok = xml_tag(i, v); + break; + default: + mexErrMsgTxt("unknown job parameter"); + } + if (iok < 0) { + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = double(iok); + if (iok < 0) reportError(); + } + else { + plhs[0] = mxCreateString(v); + } + } +} diff --git a/Cantera/matlab/cantera/@XML_Node/value.m b/Cantera/matlab/cantera/@XML_Node/value.m new file mode 100644 index 000000000..d943dc1a9 --- /dev/null +++ b/Cantera/matlab/cantera/@XML_Node/value.m @@ -0,0 +1,13 @@ +function v = value(x,loc) +% VALUE - value(x) returns the value of the XML element. +% value(x, loc) is shorthand for value(child(x,loc)) +% +if nargin == 2 + c = child(x, loc); + id = c.id; +else + id = x.id; +end + +v = ctmethods(10, 21, id); + diff --git a/Cantera/matlab/cantera/@XML_Node/write.m b/Cantera/matlab/cantera/@XML_Node/write.m new file mode 100644 index 000000000..5acb3a71f --- /dev/null +++ b/Cantera/matlab/cantera/@XML_Node/write.m @@ -0,0 +1,4 @@ +function write(x, file) + +ctmethods(10, 13, x.id, file); + diff --git a/Cantera/matlab/cantera/Contents.m b/Cantera/matlab/cantera/Contents.m new file mode 100755 index 000000000..5a4f155ec --- /dev/null +++ b/Cantera/matlab/cantera/Contents.m @@ -0,0 +1,40 @@ +% Cantera Toolbox. +% Version 1.0 17-April-2002 +% +% Cantera is an open-source, object-oriented software package to aid +% the analysis and simulation of chemically-reacting flows. It +% consists of a computational kernel written largely in C++, along +% with interface libraries for several programming languages, +% including Fortran 90, Python, and MATLAB. More information about +% Cantera is available at http://www.cantera.org. +% +% This toolbox is the Cantera MATLAB interface. +% +% Cantera object construction. +% Solution - construct a Solution object. +% +% Constants. +% oneatm - One atmosphere. +% gasconstant - Universal gas constant. +% +% Gas mixture models. +% IdealGasMix - Ideal gas mixtures. +% GRI30 - GRI-Mech 3.0. +% air - air. +% +% Zero-dimensional reactor models. +% reactor - A general, customizable reactor. +% conhp - An adiabatic, constant pressure reactor. +% conuv - An adiabatic, constant volume reactor. +% +% Utilities. +% geterr - Get Cantera error message. +% adddir - Add a directory to Cantera's search path +% ctclear - Clear all objects from memory. +% +% Copyright 2002 California Institute of Technology +% $Revision$ $Date$ + + + + diff --git a/Cantera/matlab/cantera/GRI30.m b/Cantera/matlab/cantera/GRI30.m new file mode 100755 index 000000000..9ec68b7e8 --- /dev/null +++ b/Cantera/matlab/cantera/GRI30.m @@ -0,0 +1,27 @@ +function s = GRI30(tr) +% GRI30 - Create a Solution instance representing +% reaction mechanism GRI-Mech 3.0. +% +% GRI-Mech 3.0 is a widely-used reaction mechanism for natural gas +% combustion. It contains 53 species composed of the elements H, +% C, O, N, and/or Ar, and contains 325 reactions, most of which +% are reversible. GRI-Mech 3.0, like most combustion mechanisms, +% is designed for use at pressures where the ideal gas law holds. +% +% Function GRI30 creates the solution according to the +% specifications in file gri30.xml. The ideal gas equation of +% state is used. Transport property evaluation is disabled by +% default. To enable transport properties, supply the name of +% the transport model to use. +% +% g1 = GRI30 % no transport properties +% g2 = GRI30('Mix') % mixture-averaged transport properties +% g3 = GRI30('Multi') % miulticomponent transport properties +% +if nargin == 0 + s = Solution('gri30.xml'); +elseif nargin == 1 + s = Solution('gri30.xml',tr); +else + error('wrong number of arguments') +end diff --git a/Cantera/matlab/cantera/IdealGasMix.m b/Cantera/matlab/cantera/IdealGasMix.m new file mode 100755 index 000000000..47720dc58 --- /dev/null +++ b/Cantera/matlab/cantera/IdealGasMix.m @@ -0,0 +1,60 @@ +function s = IdealGasMix(a,b,c,d) +% IDEALGASMIX - Create a Solution instance representing an ideal gas mixture. +% +% gas1 = IdealGasMix('ctml_file'[,'transport_model']) +% gas2 = IdealGasMix('ck_file'[,'thermo_db'[,'tran_db'[,'transport_model']]]) +% +% creates an object that represents an ideal gas mixture. The +% species in the mixture, their properties, and the reactions among +% the species, if any, are specified in file 'input_file'. Two +% input file formats are supported - CTML and CK +% (Chemkin-compatible). Examples: +% +% g1a = IdealGasMix('mech.xml') +% g1b = IdealGasMix('mech.xml','Multi') +% g2 = IdealGasMix('mech2.inp') +% g3 = IdealGasMix('mech3.inp','therm.dat') +% g4 = IdealGasMix('mech4.inp','therm.dat','tran.dat','Mix') +% +% Objects g1a and g1b are created from a CTML file. CTML files +% contain all data required to build the object, and do not require +% any additional database files. Objects g2 - g4 are created from +% CK-format input files. For g2, 'mech2.inp' contains all required +% species thermo data. File 'mech3.inp' is missing some or all +% species thermo data, and requires database file 'therm.dat.' +% Object g4 is created including transport data. +% +% Note that calling IdealGasMix with a CK-format input file +% also creates an equivalent CTML file that may be used in future +% calls. If the initial call includes a transport database, then +% the CTML file will contain transport data. +% +% See also: ck2ctml, Solution +% +dotloc = findstr(a,'.'); +if dotloc > 1 + ext = a(dotloc:end); + if ext == '.xml'; + if nargin == 1 + s = Solution(a); + elseif nargin == 2 + s = Solution(a, b); + end + set(s,'P',oneatm); + return + end +end + +if nargin == 1 + b = '-'; + c = '-'; + d = 'None'; +elseif nargin == 2 + c = '-'; + d = 'None'; +elseif nargin == 3 + d = 'None'; +end +xml = ck2ctml(a,b,c); +s = Solution(xml,d); +set(s,'P',oneatm); diff --git a/Cantera/matlab/cantera/MassFlowController.m b/Cantera/matlab/cantera/MassFlowController.m new file mode 100644 index 000000000..831d01e06 --- /dev/null +++ b/Cantera/matlab/cantera/MassFlowController.m @@ -0,0 +1,19 @@ +function m = MassFlowController(upstream, downstream) +% +% MASSFLOWCONTROLLER - Create a mass flow controller connecting two +% reactors / reservoirs. +% +% m = MassFlowController(upstream, downstream) +% +% creates an instance of class FlowDevice configured to simulate a +% mass flow controller that maintains a constant mass flow rate +% independent of upstream or downstream conditions. If two reactor +% objects are supplied as arguments, the controller is installed +% between the two reactors. +% +% see also: FlowDevice +% +m = FlowDevice(1); +if nargin == 2 + install(m, upstream, downstream) +end \ No newline at end of file diff --git a/Cantera/matlab/cantera/Reservoir.m b/Cantera/matlab/cantera/Reservoir.m new file mode 100644 index 000000000..8a71022ce --- /dev/null +++ b/Cantera/matlab/cantera/Reservoir.m @@ -0,0 +1,21 @@ +function r = Reservoir(contents) +% RESERVOIR - Create a Reservoir object. +% +% A Reservoir is an instance of class Reactor configured so that +% its intensive state is constant in time. A reservoir may be +% thought of as infinite in extent, perfectly mixed, and +% non-reacting, so that fluid may be extracted or added without +% changing the composition or thermodynamic state. Note that even +% if the reaction mechanism associated with the fluid in the +% reactor defines reactions, they are disabled within +% reservoirs. +% +% r1 = Reservoir % an empty reservoir +% r2 = Reservoir(gas) % a reservoir containing a gas +% +% See also: Reactor +% +if nargin == 0 + contents = 0 +end +r = Reactor(contents, 2); diff --git a/Cantera/matlab/cantera/Valve.m b/Cantera/matlab/cantera/Valve.m new file mode 100644 index 000000000..08bcc2e44 --- /dev/null +++ b/Cantera/matlab/cantera/Valve.m @@ -0,0 +1,32 @@ +function m = Valve(upstream, downstream) +% +% VALVE - Create a valve connecting two reactors / reservoirs. +% +% m = Valve(upstream, downstream) +% +% creates an instance of class FlowDevice configured to simulate a +% valve that produces a flow rate proportional to the pressure +% difference between the uupstream and downstream reactors. If two reactor +% objects are supplied as arguments, the valve is installed +% between the two reactors. +% +% The mass flow rate [kg/s] is computed from the expression +% +% mdot = K ( P_upstream - P_downstream ) +% +% as long as this produces a positive value. If this expression is +% negative, zero is returned. Therefore, the Valve object acts as a +% check valve - flow is always from the upstream reactor to the +% downstream one. Note: as currently implemented, the Valve object +% does not model real valve characteristics - in particular, it +% does not model choked flow. The mass flow rate is always assumed +% to be linearly proportional to the mass flow rate, no matter how +% large the pressure difference. THIS MAY CHANGE IN A FUTURE +% RELEASE. +% +% see also: FlowDevice, MassFlowController +% +m = FlowDevice(3); +if nargin == 2 + install(m, upstream, downstream) +end \ No newline at end of file diff --git a/Cantera/matlab/cantera/adddir.m b/Cantera/matlab/cantera/adddir.m new file mode 100755 index 000000000..1ddf4a9bb --- /dev/null +++ b/Cantera/matlab/cantera/adddir.m @@ -0,0 +1,9 @@ +function adddir(d) +% ADDDIR Add a directory to the Cantera search path. +% +% adddir('directory') +% +% adds 'directory' to the set of directories where Cantera looks for +% input and data files. +% +ctmethods(0,3,d) diff --git a/Cantera/matlab/cantera/air.m b/Cantera/matlab/cantera/air.m new file mode 100755 index 000000000..1b87008fc --- /dev/null +++ b/Cantera/matlab/cantera/air.m @@ -0,0 +1,7 @@ +function gas = air +% AIR - create an object representing air. +% +% Air is modeled as an ideal gas mixture, and several reactions +% are defined. The specification is taked from file air.xml. +% +gas = IdealGasMix('air.xml'); diff --git a/Cantera/matlab/cantera/build.m b/Cantera/matlab/cantera/build.m new file mode 100755 index 000000000..ad8dc04c9 --- /dev/null +++ b/Cantera/matlab/cantera/build.m @@ -0,0 +1,45 @@ +disp('building Phase...'); +%buildphase +cd @Phase/private +mex newphase.cpp -lct +mex phase_get.cpp -lct +mex phase_set.cpp -lct +cd ../.. + +disp('building Thermo...'); +%buildthermo +cd @Thermo/private +mex newthermo.cpp -lct +mex thermo_get.cpp -lct +mex thermo_set.cpp -lct +cd ../.. + +disp('building Kinetics...'); +%buildkinetics +cd @Kinetics/private +mex newkinetics.cpp -lct +mex kin_get.cpp -lct +mex kin_set.cpp -lct +mex rstoich.cpp -lct +mex pstoich.cpp -lct +mex rop.cpp -lct +mex production.cpp -lct +mex isrev.cpp -lct +mex rxnstring.cpp -lct +cd ../.. + +disp('building Transport...'); +%buildtransport +cd @Transport/private +mex newTransport.cpp -lct +mex trans_methods.cpp -lct +cd ../.. + +% +disp('building Functions...'); +cd private +mex addCanteraDirectory.cpp -lct +mex clearStorage.cpp -lct +mex import_from_file.cpp -lct +mex getCanteraError.cpp -lct +cd .. diff --git a/Cantera/matlab/cantera/buildux.m b/Cantera/matlab/cantera/buildux.m new file mode 100755 index 000000000..a7079d0b7 --- /dev/null +++ b/Cantera/matlab/cantera/buildux.m @@ -0,0 +1,9 @@ + +disp('building Cantera..'); +mex private/ctmethods.cpp private/ctfunctions.cpp ... + private/xmlmethods.cpp private/phasemethods.cpp ... + private/thermomethods.cpp private/kineticsmethods.cpp ... + private/transportmethods.cpp private/reactormethods.cpp ... + private/wallmethods.cpp private/flowdevicemethods.cpp ... + -L/home/goodwin/dv/cantera-1.4/lib -lct14 -loneD -lzeroD -ltransport -lconverters -lcantera -lrecipes -lcvode -lctlapack -lctmath -lctblas -L/usr/lib/gcc-lib/i386-redhat-linux/2.96 -L/usr/lib/gcc-lib/i386-redhat-linux/2.96/../../.. -lg2c -lm +disp('done.'); diff --git a/Cantera/matlab/cantera/buildwin.m b/Cantera/matlab/cantera/buildwin.m new file mode 100755 index 000000000..fc6094697 --- /dev/null +++ b/Cantera/matlab/cantera/buildwin.m @@ -0,0 +1,59 @@ +disp('thermodynamic properties...'); +%buildthermo +cd @ThermoPhase/private +mex newthermo.cpp ../../../../../lib/ct13r5.lib +mex phase_get.cpp ../../../../../lib/ct13r5.lib +mex phase_set.cpp ../../../../../lib/ct13r5.lib +mex thermo_get.cpp ../../../../../lib/ct13r5.lib +mex thermo_set.cpp ../../../../../lib/ct13r5.lib +cd ../.. + +disp('chemical kinetics...'); +%buildkinetics +cd @Kinetics/private +mex newkinetics.cpp ../../../../../lib/ct13r5.lib +mex delkinetics.cpp ../../../../../lib/ct13r5.lib +mex kin_get.cpp ../../../../../lib/ct13r5.lib +mex kin_set.cpp ../../../../../lib/ct13r5.lib +mex rstoich.cpp ../../../../../lib/ct13r5.lib +mex pstoich.cpp ../../../../../lib/ct13r5.lib +mex rop.cpp ../../../../../lib/ct13r5.lib +mex production.cpp ../../../../../lib/ct13r5.lib +mex isrev.cpp ../../../../../lib/ct13r5.lib +mex rxnstring.cpp ../../../../../lib/ct13r5.lib +cd ../.. + +disp('transport properties...'); +%buildtransport +cd @Transport/private +mex newTransport.cpp ../../../../../lib/ct13r5.lib +mex trans_methods.cpp ../../../../../lib/ct13r5.lib +cd ../.. + +% +disp('XML support...'); +cd @XML_Node/private +mex newxml.cpp ../../../../../lib/ct13r5.lib +mex xmlmethods.cpp ../../../../../lib/ct13r5.lib +cd ../.. + +% +disp('utility functions...'); +cd private +mex addCanteraDirectory.cpp ../../../../lib/ct13r5.lib +mex clearStorage.cpp ../../../../lib/ct13r5.lib +%mex import_from_file.cpp ../../../../lib/ct13r5.lib +mex getCanteraError.cpp ../../../../lib/ct13r5.lib +mex ck_to_ctml.cpp ../../../../lib/ct13r5.lib +cd .. + +disp('Zero-dimensional reactors...'); +cd @Reactor/private +mex reactormethods.cpp ../../../../../lib/ct13r5.lib +cd ../.. +cd @Wall/private +mex wallmethods.cpp ../../../../../lib/ct13r5.lib +cd ../.. +cd @FlowDevice/private +mex flowdevicemethods.cpp ../../../../../lib/ct13r5.lib +cd ../.. diff --git a/Cantera/matlab/cantera/ck2ctml.m b/Cantera/matlab/cantera/ck2ctml.m new file mode 100644 index 000000000..c91abefb9 --- /dev/null +++ b/Cantera/matlab/cantera/ck2ctml.m @@ -0,0 +1,45 @@ +function f = ck2ctml(infile, thermo, transport) +% CK2CTML - Convert a Chemkin-compatible reaction mechanism file to +% CTML. +% +% Cantera uses an XML-based file format (CTML) for specifying input +% parameters of any type, including specifying reaction mechanism +% attributes. This function reads a reaction mechanism file in "CK +% format" - the file format used by the Chemkin software package - +% and writes an equivalent description in CTML. +% +% f = ck2ctml('chem.inp') +% f = ck2ctml('chem.inp', 'therm.dat') +% f = ck2ctml('chem.inp', 'therm.dat', 'tran.dat') +% +% These 3 statements all create a CTML file 'chem.xml.' In the +% first case, the CK-format file contains all required species +% thermo data, while in the second case some or all thermo data is +% read from file 'therm.dat.' In the third form, the CTML file +% created will also contain transport property parameters. The +% function return value is a string containing the output file +% name. +% +if nargin == 0 + error('input file name must be supplied') +elseif nargin == 1 + thermo = '-'; + transport = '-'; +elseif nargin == 2 + transport = '-'; +end + +dotloc = findstr(infile,'.'); +if dotloc > 1 + idtag = infile(1:dotloc-1); + outfile = [idtag '.xml']; +else + idtag = infile; + outfile = [infile '.xml']; +end + +iok = ctmethods(0, 1, infile, thermo, transport, outfile, idtag); +if iok + error(geterr); +end +f = outfile; diff --git a/Cantera/matlab/cantera/conhp.m b/Cantera/matlab/cantera/conhp.m new file mode 100755 index 000000000..e68a1ef3e --- /dev/null +++ b/Cantera/matlab/cantera/conhp.m @@ -0,0 +1,27 @@ +function dydt = conhp(t,y,gas,mw) +% CONHP ODE system for a constant-pressure, adiabatic reactor. +% +% Function CONHP evaluates the system of ordinary differential +% equations for an adiabatic, constant-pressure, +% zero-dimensional reactor. It assumes that the 'gas' object +% represents a reacting ideal gas mixture. + + +% Set the state of the gas, based on the current solution vector. +set(gas, 'T', y(1), 'P', pressure(gas), 'Y', y(2:end)); + +% energy equation +wdot = netProdRates(gas); +tdot = - temperature(gas) * gasconstant * enthalpies_RT(gas)' ... + * wdot / (density(gas)*cp_mass(gas)); + +% set up column vector for dydt +dydt = [ tdot + zeros(53,1) ]; + +% species equations +rrho = 1.0/density(gas); +nsp = nSpecies(gas); +for i = 1:nsp + dydt(i+1) = rrho*mw(i)*wdot(i); +end diff --git a/Cantera/matlab/cantera/constants.m b/Cantera/matlab/cantera/constants.m new file mode 100755 index 000000000..ecf8aeb02 --- /dev/null +++ b/Cantera/matlab/cantera/constants.m @@ -0,0 +1,3 @@ +function [atm,r] = constants +atm = 101325.0; +r = 8314.0; diff --git a/Cantera/matlab/cantera/conuv.m b/Cantera/matlab/cantera/conuv.m new file mode 100755 index 000000000..7f35b569d --- /dev/null +++ b/Cantera/matlab/cantera/conuv.m @@ -0,0 +1,27 @@ +function dydt = conuv(t,y,gas,mw) +% CONUV ODE system for a constant-volume, adiabatic reactor. +% +% Function CONUV evaluates the system of ordinary differential +% equations for an adiabatic, constant-volume, +% zero-dimensional reactor. It assumes that the 'gas' object +% represents a reacting ideal gas mixture. + + +% Set the state of the gas, based on the current solution vector. +set(gas, 'T', y(1), 'Rho', density(gas), 'Y', y(2:end)); +nsp = nSpecies(gas); + +% energy equation +wdot = netProdRates(gas); +tdot = - temperature(gas) * gasconstant * (enthalpies_RT(gas) - ones(nsp,1))' ... + * wdot / (density(gas)*cv_mass(gas)); + +% set up column vector for dydt +dydt = [ tdot + zeros(53,1) ]; + +% species equations +rrho = 1.0/density(gas); +for i = 1:nsp + dydt(i+1) = rrho*mw(i)*wdot(i); +end diff --git a/Cantera/matlab/cantera/examples/equil.m b/Cantera/matlab/cantera/examples/equil.m new file mode 100755 index 000000000..b3d8e2197 --- /dev/null +++ b/Cantera/matlab/cantera/examples/equil.m @@ -0,0 +1,58 @@ +function equil(g) +% EQUIL a chemical equilibrium example. +% +% This example computes the adiabatic flame temperature and +% equilibrium composition for a methane/air mixture as a function of +% equivalence ratio. +help equil; + +if nargin == 1 & isa(g,'GasMix') + gas = g; +else + gas = IdealGasMix('gri30.xml'); +end + +nsp = nSpecies(gas); +phi = []; + +% find methane, nitrogen, and oxygen indices +ich4 = speciesIndex(gas,'CH4'); +io2 = speciesIndex(gas,'O2'); +in2 = speciesIndex(gas,'N2'); + +for i = 1:50 + phi(i) = 0.2 + 0.05*i; + x = zeros(nsp,1); + x(ich4,1) = phi(i); + x(io2,1) = 2.0; + x(in2,1) = 7.52; + set(gas,'Temperature',300.0,'Pressure',101325.0,'MoleFractions', ... + x); + equilibrate(gas,'HP'); + tad(i) = temperature(gas); + xeq(:,i) = moleFractions(gas); +end + +% make plots + +figure(1); +plot(phi,tad); +xlabel('Equivalence Ratio'); +ylabel('Temperature (K)'); +title('Adiabatic Flame Temperature'); + +figure(2); +semilogy(phi,xeq); +axis([phi(1) phi(50) 1.0e-14 1]); +%legend(speciesName(gas,1:nsp),1); +j = 10; +for k = 1:nsp + text(phi(j),1.5*xeq(k,j),speciesName(gas,k)) + j = j + 2; + if j > 46 + j = 10; + end +end +xlabel('Equivalence Ratio'); +ylabel('Mole Fraction'); +title('Equilibrium Composition'); diff --git a/Cantera/matlab/cantera/examples/ignite.m b/Cantera/matlab/cantera/examples/ignite.m new file mode 100755 index 000000000..a510e617e --- /dev/null +++ b/Cantera/matlab/cantera/examples/ignite.m @@ -0,0 +1,105 @@ +function plotdata = ignite(g) +% IGNITE Zero-dimensional kinetics: adiabatic, constant pressure. +% +% This example solves the same problem as 'reactor1,' but does +% it using on of MATLAB's ODE integrators, rather than using the +% Cantera Reactor class. +% + +help ignite + +if nargin == 1 & isa(g,'solution') + gas = g; +else + gas = IdealGasMix('gri30.xml'); +end + +nsp = nSpecies(gas); + +% set the initial conditions + +set(gas,'T',1001.0,'P',oneatm,'X','H2:2,O2:1,N2:4'); + +y0 = [intEnergy_mass(gas) + 1.0/density(gas) + massFractions(gas)]; + +time_interval = [0 0.001]; +options = odeset('RelTol',1.e-5,'AbsTol',1.e-12,'Stats','on'); + +t0 = cputime; +out = ode15s(@reactor_ode,time_interval,y0,options,gas,@vdot,@area,@heatflux); +disp(['CPU time = ' num2str(cputime - t0)]); + +plotdata = output(out,gas); + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% the functions below may be defined arbitrarily to set the reactor +% boundary conditions - the rate of change of volume, the heat +% flux, and the area. + + +% Rate of change of volume. Any arbirtrary function may be implemented. +% Input arguments: +% t time +% vol volume +% gas ideal gas object + +function v = vdot(t, vol, gas) +%v = 0.0; %uncomment for constant volume +v = 1.e11 * (pressure(gas) - 101325.0); % holds pressure very + % close to 1 atm + +% heat flux (W/m^2). +function q = heatflux(t, gas) +q = 0.0; % adiabatic + + +% surface area (m^2). Used only to compute heat transfer. +function a = area(t,vol) +a = 1.0; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Since the solution variables used by the 'reactor' function are +% not necessarily those desired for output, this function is called +% after the integration is complete to generate the desired +% outputs. + +function pv = output(s, gas) +times = s.x; +soln = s.y; +[m n] = size(times); +pv = zeros(nSpecies(gas) + 4, n); + +set(gas,'T',1001.0,'P',oneatm); + +for j = 1:n + ss = soln(:,j); + y = ss(3:end); + mass = sum(y); + u_mass = ss(1)/mass; + v_mass = ss(2)/mass; + setMassFractions(gas, y); + setState_UV(gas, [u_mass v_mass]); + + pv(1,j) = times(j); + pv(2,j) = temperature(gas); + pv(3,j) = density(gas); + pv(4,j) = pressure(gas); + pv(5:end,j) = y; +end + +% plot the temperature and OH mole fractions. +figure(1); +plot(pv(1,:),pv(2,:)); +xlabel('time'); +ylabel('Temperature'); +title(['Final T = ' num2str(pv(2,end)) ' K']); + +figure(2); +ioh = speciesIndex(gas,'OH'); +plot(pv(1,:),pv(4+ioh,:)); +xlabel('time'); +ylabel('Mole Fraction'); +title('OH Mole Fraction'); diff --git a/Cantera/matlab/cantera/examples/ignite2.m b/Cantera/matlab/cantera/examples/ignite2.m new file mode 100755 index 000000000..02f260b5c --- /dev/null +++ b/Cantera/matlab/cantera/examples/ignite2.m @@ -0,0 +1,106 @@ +function ignite2(g) +% IGNITE2 Zero-dimensional kinetics: adiabatic, constant volume. +% +% This example illustrates how to use function 'reactor' for +% zero-dimensional kinetics simulations with arbitrary heat flux +% and volume vs. time. Here a constant-volume, adiabatic simulation +% is conducted by setting vdot and q to zero. +% + +help ignite2 + +if nargin == 1 & isa(g,'GasMix') + gas = g; +else + gas = IdealGasMix('gri30.xml'); +end + +nsp = nSpecies(gas); + +% set the initial conditions + +set(gas,'T',1001.0,'P',oneatm,'X','H2:2,O2:1,N2:4'); + +y0 = [intEnergy_mass(gas) + 1.0/density(gas) + massFractions(gas)]; + +time_interval = [0 0.001]; +options = odeset('RelTol',1.e-5,'AbsTol',1.e-12,'Stats','on'); + +t0 = cputime; +out = ode15s(@reactor_ode,time_interval,y0,options,gas,@vdot,@area,@heatflux); +disp(['CPU time = ' num2str(cputime - t0)]); + +plotdata = output(out,gas); + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% the functions below may be defined arbitrarily to set the reactor +% boundary conditions - the rate of change of volume, the heat +% flux, and the area. + + +% Rate of change of volume. Any arbirtrary function may be implemented. +% Input arguments: +% t time +% vol volume +% gas ideal gas object + +function v = vdot(t, vol, gas) +v = 0.0; %constant volume +%v = 1.e11 * (pressure(gas) - 101325.0); % holds pressure very + % close to 1 atm + +% heat flux (W/m^2). +function q = heatflux(t, gas) +q = 0.0; % adiabatic + + +% surface area. Used only to compute heat transfer. +function a = area(t,vol) +a = 1.0; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Since the solution variables used by the 'reactor' function are +% not necessarily those desired for output, this function is called +% after the integration is complete to generate the desired +% outputs. + +function pv = output(s, gas) +times = s.x; +soln = s.y; +[m n] = size(times); +pv = zeros(nSpecies(gas) + 4, n); + +set(gas,'T',1001.0,'P',oneatm); + +for j = 1:n + ss = soln(:,j); + y = ss(3:end); + mass = sum(y); + u_mass = ss(1)/mass; + v_mass = ss(2)/mass; + setMassFractions(gas, y); + setState_UV(gas, [u_mass v_mass]); + + pv(1,j) = times(j); + pv(2,j) = temperature(gas); + pv(3,j) = density(gas); + pv(4,j) = pressure(gas); + pv(5:end,j) = y; +end + +% plot the temperature and OH mole fractions. +figure(1); +plot(pv(1,:),pv(2,:)); +xlabel('time'); +ylabel('Temperature'); +title(['Final T = ' num2str(pv(2,end)) ' K']); + +figure(2); +ioh = speciesIndex(gas,'OH'); +plot(pv(1,:),pv(4+ioh,:)); +xlabel('time'); +ylabel('Mole Fraction'); +title('OH Mole Fraction'); diff --git a/Cantera/matlab/cantera/examples/ignite3.m b/Cantera/matlab/cantera/examples/ignite3.m new file mode 100755 index 000000000..da4f7e0fb --- /dev/null +++ b/Cantera/matlab/cantera/examples/ignite3.m @@ -0,0 +1,40 @@ +function ignite3(gas) +% IGNITE3 Solves the same ignition problem as 'ignite', except +% that the volume is held fixed, and function conuv is used +% instead of reactor. +% + +help ignite3 + +if nargin == 0 | ~isa(gas,'GasMix') + gas = idealgasmix('gri30.xml'); +end + +mw = molecularWeights(gas); +nsp = nSpecies(gas); +set(gas,'T',1001.0,'P',oneatm,'X','H2:2,O2:1,N2:4'); + +y0 = [temperature(gas) + massFractions(gas)]; +tel = [0 0.001]; +options = odeset('RelTol',1.e-5,'AbsTol',1.e-12,'Stats','on'); +t0 = cputime; +out = ode15s(@conuv,tel,y0,options,gas,mw); +disp(['CPU time = ' num2str(cputime - t0)]); + +if nargout == 0 + % plot the temperature and OH mole fractions. + figure(1); + plot(out.x,out.y(1,:)); + xlabel('time'); + ylabel('Temperature'); + title(['Final T = ' num2str(out.y(1,end)) ' K']); + + figure(2); + ioh = speciesIndex(gas,'OH'); + plot(out.x,out.y(1+ioh,:)); + xlabel('time'); + ylabel('Mole Fraction'); + title('OH Mole Fraction'); + +end diff --git a/Cantera/matlab/cantera/examples/ignite_hp.m b/Cantera/matlab/cantera/examples/ignite_hp.m new file mode 100755 index 000000000..dabf2e8cf --- /dev/null +++ b/Cantera/matlab/cantera/examples/ignite_hp.m @@ -0,0 +1,38 @@ +function ignite_hp(gas) +% IGNITE_HP Solves the same ignition problem as 'ignite', but uses function +% conhp instead of reactor. +% + +help ignite_hp + +if nargin == 0 | ~isa(gas,'GasMix') + gas = IdealGasMix('gri30.xml'); +end + +mw = molecularWeights(gas); +nsp = nSpecies(gas); +set(gas,'T',1001.0,'P',oneatm,'X','H2:2,O2:1,N2:4'); + +y0 = [temperature(gas) + massFractions(gas)]; +tel = [0 0.001]; +options = odeset('RelTol',1.e-5,'AbsTol',1.e-12,'Stats','on'); +t0 = cputime; +out = ode15s(@conhp,tel,y0,options,gas,mw); +disp(['CPU time = ' num2str(cputime - t0)]); + +if nargout == 0 + % plot the temperature and OH mole fractions. + figure(1); + plot(out.x,out.y(1,:)); + xlabel('time'); + ylabel('Temperature'); + title(['Final T = ' num2str(out.y(1,end)) ' K']); + + figure(2); + ioh = speciesIndex(gas,'OH'); + plot(out.x,out.y(1+ioh,:)); + xlabel('time'); + ylabel('Mole Fraction'); + title('OH Mole Fraction'); +end diff --git a/Cantera/matlab/cantera/examples/ignite_uv.m b/Cantera/matlab/cantera/examples/ignite_uv.m new file mode 100755 index 000000000..6843368e6 --- /dev/null +++ b/Cantera/matlab/cantera/examples/ignite_uv.m @@ -0,0 +1,38 @@ +function ignite_uv(gas) +% IGNITE_UV Solves the same ignition problem as 'ignite2', except +% that function conuv is used instead of reactor. +% +help ignite_uv + +if nargin == 0 | ~isa(gas,'GasMix') + gas = IdealGasMix('gri30.xml'); +end + +mw = molecularWeights(gas); +nsp = nSpecies(gas); +set(gas,'T',1001.0,'P',oneatm,'X','H2:2,O2:1,N2:4'); + +y0 = [temperature(gas) + massFractions(gas)]; +tel = [0 0.001]; +options = odeset('RelTol',1.e-5,'AbsTol',1.e-12,'Stats','on'); +t0 = cputime; +out = ode15s(@conuv,tel,y0,options,gas,mw); +disp(['CPU time = ' num2str(cputime - t0)]); + +if nargout == 0 + % plot the temperature and OH mole fractions. + figure(1); + plot(out.x,out.y(1,:)); + xlabel('time'); + ylabel('Temperature'); + title(['Final T = ' num2str(out.y(1,end)) ' K']); + + figure(2); + ioh = speciesIndex(gas,'OH'); + plot(out.x,out.y(1+ioh,:)); + xlabel('time'); + ylabel('Mole Fraction'); + title('OH Mole Fraction'); + +end diff --git a/Cantera/matlab/cantera/examples/isentropic.m b/Cantera/matlab/cantera/examples/isentropic.m new file mode 100755 index 000000000..ccf1f5e23 --- /dev/null +++ b/Cantera/matlab/cantera/examples/isentropic.m @@ -0,0 +1,57 @@ +function isentropic(g) +% ISENTROPIC isentropic, adiabatic flow example +% +% In this example, the area ratio vs. Mach number curve is +% computed for a hydrogen/nitrogen gas mixture. +% +help isentropic + +if nargin == 1 & isa(g,'solution') + gas = g; +else + gas = IdealGasMix('gri30.xml'); +end + +% set the stagnation state +set(gas,'T',1200.0,'P',10.0*oneatm,'X','H2:1,N2:0.1'); +s0 = entropy_mass(gas); +h0 = enthalpy_mass(gas); +p0 = pressure(gas); + +mdot = 1; % arbitrary + +mach = []; +a = []; +i = 1; +amin = 1.e14; + +% compute values for a range of pressure ratios +for r = 0.005:0.0025:0.995 + p = p0*r; + + % set the state using (p,s0) + set(gas,'P',p,'S',s0); + + h = enthalpy_mass(gas); + rho = density(gas); + + v2 = 2.0*(h0 - h); % h + V^2/2 = h0 + v = sqrt(v2); + a(i) = mdot/(rho*v); % rho*v*A = constant + + if a(i) < amin + amin = a(i); + end + mach(i) = v/soundspeed(gas); + i = i + 1; +end + +a = a/amin; + +% plot results + +figure(1); +plot(mach,a); +ylabel('Area Ratio'); +xlabel('Mach Number'); +title('Isentropic Flow: Area Ratio vs. Mach Number'); diff --git a/Cantera/matlab/cantera/examples/periodic_cstr.m b/Cantera/matlab/cantera/examples/periodic_cstr.m new file mode 100644 index 000000000..1843d3fe6 --- /dev/null +++ b/Cantera/matlab/cantera/examples/periodic_cstr.m @@ -0,0 +1,109 @@ +function periodic_cstr +% +% Periodic CSTR +% +% This example illustrates a CSTR with steady inputs but periodic interior state. +% A stoichiometric hydrogen/oxygen mixture is introduced and reacts to produce water. +% But since water has a large efficiency as a third body in the chain termination reaction +% +% H + O2 + M = HO2 + M +% +% as soon as a significant amount of water is produced the reaction stops. After enough time has +% passed that the water is exhausted from the reactor, the mixture explodes again and the +% process repeats. This explanation can be verified by decreasing the rate for reaction 7 in +% file 'h2o2.xml' and re-running the example. +% +% Acknowledgments: The idea for this example and an estimate of the conditions needed to +% see the oscillations came from Bob Kee, Colorado School of Mines +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +help periodic_cstr + +% create the gas mixture +gas = IdealGasMix('h2o2.xml'); + +% pressure = 60 Torr, T = 770 K +p = 60.0*133.3; +t = 770.0; + +OneAtm = 1.01325e5; + +set(gas,'T', 300.0, 'P', p, 'X', 'H2:2, O2:1'); + + +% create an upstream reservoir that will supply the reactor. The +% temperature, pressure, and composition of the upstream reservoir are +% set to those of the 'gas' object at the time the reservoir is +% created. +upstream = Reservoir(gas); + + +% Now set the gas to the initial temperature of the reactor, and create +% the reactor object. +set(gas, 'T', t, 'P', p); +cstr = Reactor(gas); + +% Set its volume to 10 cm^3. In this problem, the reactor volume is +% fixed, so the initial volume is the volume at all later times. +setInitialVolume(cstr, 10.0*1.0e-6); + + +% We need to have heat loss to see the oscillations. Create a +% reservoir to represent the environment, and initialize its +% temperature to the reactor temperature. +env = Reservoir(gas); + + +% Create a heat-conducting wall between the reactor and the +% environment. Set its area, and its overall heat transfer +% coefficient. Larger U causes the reactor to be closer to isothermal. +% If U is too small, the gas ignites, and the temperature spikes and +% stays high. +w = Wall; +install(w, cstr, env); +setArea(w, 1.0); +setHeatTransferCoeff(w, 0.02); + + +% Connect the upstream reservoir to the reactor with a mass flow +% controller (constant mdot). Set the mass flow rate to 1.25 sccm. +sccm = 1.25; +vdot = sccm * 1.0e-6/60.0 * ((OneAtm / pressure(gas)) * ( temperature(gas) / 273.15)); % m^3/s +mdot = density(gas) * vdot; % kg/s +mfc = MassFlowController; +install(mfc, upstream, cstr); +setMassFlowRate(mfc, mdot); + + +% now create a downstream reservoir to exhaust into. +downstream = Reservoir(gas); + + +% connect the reactor to the downstream reservoir with a valve, and +% set the coefficient sufficiently large to keep the reactor pressure +% close to the downstream pressure of 60 Torr. +v = Valve; +install(v, cstr, downstream); +setValveCoeff(v, 1.0e-9); +% mdot (kg/s) = coeff * (delta P, Pascals) + + +% now integrate in time +tme = 0.0; +dt = 0.1; + +n = 0; +while tme < 300.0 + n = n + 1; + tme = tme + dt; + advance(cstr, tme); + tm(n) = tme; + y(1,n) = massFraction(cstr,'H2'); + y(2,n) = massFraction(cstr,'O2'); + y(3,n) = massFraction(cstr,'H2O'); +end +figure(1) +plot(tm,y) +legend('H2','O2','H2O') +title('Mass Fractions') diff --git a/Cantera/matlab/cantera/examples/prandtl1.m b/Cantera/matlab/cantera/examples/prandtl1.m new file mode 100755 index 000000000..e71d7bfdb --- /dev/null +++ b/Cantera/matlab/cantera/examples/prandtl1.m @@ -0,0 +1,72 @@ +function prandtl1(g) +% PRANDTL1 Prandlt number for an equilibrium H/O gas mixture. +% +% This example computes and plots the Prandtl number for a +% hydrogen / oxygen mixture in chemical equilibrium for P = 1 +% atm and a range of temperatures and elemental O/(O+H) ratios. +% +help prandtl1 + +if nargin == 1 & isa(g,'solution') + gas = g; +else + gas = GRI30('Mix'); +end + +pr = zeros(31,31); +xh2 = zeros(31,31); +visc = zeros(31,31); +lambda = zeros(31,31); +t = []; +xo2 = []; +io2 = speciesIndex(gas,'O2'); +ih2 = speciesIndex(gas,'H2'); +ih = speciesIndex(gas,'H'); +ih2o = speciesIndex(gas,'H2O'); + +atm = oneatm; +t0 = cputime; +for i = 1:31 + t(i) = 300.0 + 100.0*i; + for j = 1:31 + xo2(j) = 0.99*(j-1)/30.0; + x = zeros(nSpecies(gas),1); + x(io2) = xo2(j); + x(ih2) = 1.0 - xo2(j); + set(gas,'T',t(i),'P',oneatm,'X',x); + equilibrate(gas,'TP'); + visc(i,j) = viscosity(gas); + lambda(i,j) = thermalConductivity(gas); + pr(i,j) = visc(i,j)*cp_mass(gas)/lambda(i,j); + x = moleFractions(gas); + xh2(i,j) = x(ih2); + end +end +disp(['CPU time = ' num2str(cputime - t0)]); + +% plot results + +figure(1); +subplot(2,2,1); +surf(xo2,t,pr); +xlabel('Elemental O/(O+H)'); +ylabel('Temperature (K)'); +zlabel('Prandtl Number'); + +subplot(2,2,2); +surf(xo2,t,xh2); +xlabel('Elemental O/(O+H)'); +ylabel('Temperature (K)'); +zlabel('H_2 Mole Fraction'); + +subplot(2,2,3); +surf(xo2,t,visc); +xlabel('Elemental O/(O+H)'); +ylabel('Temperature (K)'); +zlabel('Viscosity'); + +subplot(2,2,4); +surf(xo2,t,lambda); +xlabel('Elemental O/(O+H)'); +ylabel('Temperature (K)'); +zlabel('Thermal Conductivity'); diff --git a/Cantera/matlab/cantera/examples/prandtl2.m b/Cantera/matlab/cantera/examples/prandtl2.m new file mode 100755 index 000000000..ad51febb8 --- /dev/null +++ b/Cantera/matlab/cantera/examples/prandtl2.m @@ -0,0 +1,46 @@ +function prandtl2(g) +% PRANDTL2 Prandlt number for an equilibrium H/O gas mixture. +% +% This example does the same thing as prandtl1, but using +% the multicomponent expression for the thermal conductivity. +% +help prandtl2 + +if nargin == 1 & isa(g,'solution') + gas = g; +else + gas = GRI30('Multi'); +end + +pr = zeros(31,31); +t = []; +xo2 = []; +io2 = speciesIndex(gas,'O2'); +ih2 = speciesIndex(gas,'H2'); + +atm = oneatm; +t0 = cputime; +for i = 1:31 + t(i) = 300.0 + 100.0*i; + for j = 1:31 + xo2(j) = 0.99*(j-1)/30.0; + x = zeros(nSpecies(gas),1); + x(io2) = xo2(j); + x(ih2) = 1.0 - xo2(j); + set(gas,'T',t(i),'P',oneatm,'X',x); + equilibrate(gas,'TP'); + pr(i,j) = viscosity(gas)*cp_mass(gas)/ ... + thermalConductivity(gas); + + end +end +disp(['CPU time = ' num2str(cputime - t0)]); + +% plot results + +figure(1); +surf(xo2,t,pr); +xlabel('Elemental O/(O+H)'); +ylabel('Temperature (K)'); +zlabel('Prandtl Number'); + diff --git a/Cantera/matlab/cantera/examples/reactor1.m b/Cantera/matlab/cantera/examples/reactor1.m new file mode 100644 index 000000000..9533beade --- /dev/null +++ b/Cantera/matlab/cantera/examples/reactor1.m @@ -0,0 +1,54 @@ +function reactor1(g) +% REACTOR1 Zero-dimensional kinetics: adiabatic, constant pressure. +% +% This example illustrates how to use class 'Reactor' for +% zero-dimensional kinetics simulations. Here the parameters are +% set so that the reactor is adiabatic and very close to constant +% pressure. +% + +help reactor1 + +if nargin == 1 & isa(g,'solution') + gas = g; +else + gas = GRI30; +end + +nsp = nSpecies(gas); + +% set the initial conditions +set(gas,'T',1001.0,'P',oneatm,'X','H2:2,O2:1,N2:4'); + +% create a reactor, and insert the gas +r = Reactor; +insert(r, gas); + +% create a reservoir to represent the environment +env = Reservoir; +a = IdealGasMix('air.xml'); +insert(env, a); + +% Define a wall between the reactor and the environment, and +% make it flexible, so that the pressure in the reactor is held +% at the environment pressure. +w = Wall; +install(w,r,env); + +% set expansion parameter. dV/dt = K(P_1 - P_2) +setExpansionRateCoeff(w, 1.0e6); + +% set wall area +setArea(w, 1.0); + +t = 0; +dt = 1.0e-5; +t0 = cputime; +for n = 1:100 + t = t + dt; + advance(r, t); + disp([time(r) temperature(r)]); +end +disp(['CPU time = ' num2str(cputime - t0)]); + +clear all diff --git a/Cantera/matlab/cantera/examples/reactor2.m b/Cantera/matlab/cantera/examples/reactor2.m new file mode 100644 index 000000000..a917caca2 --- /dev/null +++ b/Cantera/matlab/cantera/examples/reactor2.m @@ -0,0 +1,36 @@ +function reactor2(g) +% REACTOR2 Zero-dimensional kinetics: adiabatic, constant volume. +% +% This example illustrates how to use class 'Reactor' for +% zero-dimensional kinetics simulations. Here the parameters are +% set so that the reactor is adiabatic and constant volume. +% + +help reactor2 + +if nargin == 1 & isa(g,'solution') + gas = g; +else + gas = GRI30; +end + +nsp = nSpecies(gas); + +% set the initial conditions +set(gas,'T',1001.0,'P',oneatm,'X','H2:2,O2:1,N2:4'); + +% create a reactor, and insert the gas +r = Reactor; +insert(r, gas); + +t = 0; +dt = 1.0e-5; +t0 = cputime; +for n = 1:100 + t = t + dt; + advance(r, t); + disp([time(r) temperature(r)]); +end +disp(['CPU time = ' num2str(cputime - t0)]); + +clear all diff --git a/Cantera/matlab/cantera/examples/run_examples.m b/Cantera/matlab/cantera/examples/run_examples.m new file mode 100755 index 000000000..cdcc9f34a --- /dev/null +++ b/Cantera/matlab/cantera/examples/run_examples.m @@ -0,0 +1,44 @@ +function run_examples(g) +if nargin == 0 | ~isa(g,'solution') + gas = 0; +end + +% runs all examples +%adddir([pwd '/../data']); +equil(gas); +disp('press any key to continue'); +pause +set(1:2,'Visible','off'); +isentropic(gas); +disp('press any key to continue'); +pause +set(1:2,'Visible','off'); +reactor1(gas); +disp('press any key to continue'); +pause +set(1:2,'Visible','off'); +reactor2(gas); +disp('press any key to continue'); +pause +set(1:2,'Visible','off'); +ignite(gas); +disp('press any key to continue'); +pause +set(1:2,'Visible','off'); +ignite_hp(gas); +disp('press any key to continue'); +pause +set(1:2,'Visible','off'); +ignite2(gas); +disp('press any key to continue'); +pause +set(1:2,'Visible','off'); +ignite_uv(gas); +pause +set(1:2,'Visible','off'); +prandtl1(gas); +pause +set(1:2,'Visible','off'); +prandtl2(gas); +pause +set(1:2,'Visible','off'); diff --git a/Cantera/matlab/cantera/examples/transport1.m b/Cantera/matlab/cantera/examples/transport1.m new file mode 100755 index 000000000..d186cfc15 --- /dev/null +++ b/Cantera/matlab/cantera/examples/transport1.m @@ -0,0 +1,44 @@ +function transport1(g) +% TRANSPORT1 mixture-averaged transport properties +% +help transport1 + +if nargin == 1 & isa(g,'GasMix') + gas = g; +else + gas = GRI30('Mix'); +end + +% set the state +%set(gas,'T',2300.0,'P',oneatm,'X','AR:1'); + +% = zeros(31,31); +pr = zeros(31,31); + +t = []; +xo2 = []; +io2 = speciesIndex(gas,'O2'); +ih2 = speciesIndex(gas,'H2'); + +atm = oneatm; +for i = 1:31 + t(i) = 300.0 + 100.0*i; + for j = 1:31 + xo2(j) = (j-1)/30.0; + x = zeros(nSpecies(gas),1); + x(io2) = xo2(j); + x(ih2) = 1.0 - xo2(j); + set(gas,'T',t(i),'P',oneatm,'X',x); + equilibrate(gas,'TP'); + pr(i,j) = viscosity(gas)*cp_mass(gas)/thermalConductivity(gas); + end +end + +% plot results + +figure(1); +surf(xo2,t,pr); +xlabel('Elemental oxygen mole fraction'); +ylabel('Temperature (K)'); +zlabel('Prandtl Number'); + diff --git a/Cantera/matlab/cantera/gasconstant.m b/Cantera/matlab/cantera/gasconstant.m new file mode 100755 index 000000000..909e9aeb3 --- /dev/null +++ b/Cantera/matlab/cantera/gasconstant.m @@ -0,0 +1,3 @@ +function r = gasconstant +% GASCONSTANT The universal gas constant in J/kmol-K. +r = 8314.0; diff --git a/Cantera/matlab/cantera/geterr.m b/Cantera/matlab/cantera/geterr.m new file mode 100755 index 000000000..e06985f3a --- /dev/null +++ b/Cantera/matlab/cantera/geterr.m @@ -0,0 +1,6 @@ +function e = geterr +try + e = ctmethods(0,2); % getCanteraError; +catch + e = ' '; +end \ No newline at end of file diff --git a/Cantera/matlab/cantera/mexopts.sh b/Cantera/matlab/cantera/mexopts.sh new file mode 100644 index 000000000..ff0d862be --- /dev/null +++ b/Cantera/matlab/cantera/mexopts.sh @@ -0,0 +1,375 @@ +# +# mexopts.sh Shell script for configuring MEX-file creation script, +# mex. These options were tested with the specified compiler. +# +# usage: Do not call this file directly; it is sourced by the +# mex shell script. Modify only if you don't like the +# defaults after running mex. No spaces are allowed +# around the '=' in the variable assignment. +# +# SELECTION_TAGs occur in template option files and are used by MATLAB +# tools, such as mex and mbuild, to determine the purpose of the contents +# of an option file. These tags are only interpreted when preceded by '#' +# and followed by ':'. +# +#SELECTION_TAG_MEX_OPT: Template Options file for building MEX-files via the system ANSI compiler +# +# Copyright 1984-2000 The MathWorks, Inc. +# $Revision$ $Date$ +#---------------------------------------------------------------------------- +# + TMW_ROOT="$MATLAB" + MFLAGS='' + if [ "$ENTRYPOINT" = "mexLibrary" ]; then + MLIBS="-L$TMW_ROOT/bin/$Arch -lmx -lmex -lmatlb -lmat -lmwservices -lut -lm" + else + MLIBS="-L$TMW_ROOT/bin/$Arch -lmx -lmex -lmat -lm" + fi + case "$Arch" in + Undetermined) +#---------------------------------------------------------------------------- +# Change this line if you need to specify the location of the MATLAB +# root directory. The script needs to know where to find utility +# routines so that it can determine the architecture; therefore, this +# assignment needs to be done while the architecture is still +# undetermined. +#---------------------------------------------------------------------------- + MATLAB="$MATLAB" + ;; + alpha) +#---------------------------------------------------------------------------- +# cc -V | grep UNIX +# DEC C V5.9-008 on Digital UNIX V4.0 (Rev. 1229) +# Digital UNIX Compiler Driver 3.11 + CC='cc' + CFLAGS='-shared -ieee -pthread -std1' + CLIBS="$MLIBS -lm" + COPTIMFLAGS='-O -DNDEBUG' + CDEBUGFLAGS='-g' +# +# cxx -V +# Compaq C++ V6.2-024 for Digital UNIX V4.0F (Rev. 1229) + CXX='cxx' + CXXFLAGS='-shared -ieee -pthread' + CXXLIBS="$MLIBS -lm" + CXXOPTIMFLAGS='-O -DNDEBUG' + CXXDEBUGFLAGS='-g' +# +# f77 -what +# Compaq Fortran 77 Driver V5.3-11 +# Compaq Fortran 77 V5.3-189-449BB + FC='f77' + FFLAGS='-shared -fpe3 -pthread' + FLIBS="$MLIBS -lm" + FOPTIMFLAGS='-O' + FDEBUGFLAGS='-g' +# + LD="$COMPILER" + LDFLAGS="-pthread -shared -Wl,-expect_unresolved,'*',-hidden,-exported_symbol,$ENTRYPOINT,-exported_symbol,mexVersion,-exported_symbol,'__*'" + LDOPTIMFLAGS='-O' + LDDEBUGFLAGS='-g' +# + POSTLINK_CMDS=':' +#---------------------------------------------------------------------------- + ;; + hpux) +#---------------------------------------------------------------------------- +# what `which cc` +# HP92453-01 B.11.11.02 HP C Compiler +# $ Sep 8 2000 23:13:51 $ + CC='cc' + CFLAGS='+Z +DA2.0 -D_POSIX_C_SOURCE=199506L -Wp,-H65535 -Ae' + CLIBS="$MLIBS -lm -lc" + COPTIMFLAGS='-O -DNDEBUG' + CDEBUGFLAGS='-g' +# +# what `which aCC` +# HP aC++ B3910B A.03.30 +# HP aC++ B3910B X.03.27 Language Support Library + CXX='aCC' + CXXFLAGS='-AA +Z +DA2.0 -D_POSIX_C_SOURCE=199506L -D_HPUX_SOURCE' + CXXLIBS="$MLIBS -lm -lstd_v2 -lCsup_v2" + CXXOPTIMFLAGS='-O -DNDEBUG +Oconservative' + CXXDEBUGFLAGS='-g' +# +# what `which f90` +# HP-UX f90 20001114 (140952) B3907DB/B3909DB B.11.01.27 +# HP F90 v2.4.10 +# $ PATCH/11.00:PHCO_95167 Oct 1 1998 13:46:32 $ + F90LIBDIR='/opt/fortran90/lib/pa2.0' + FC='f90' + FFLAGS='+Z +DA2.0' + FLIBS="$MLIBS -lm -L$F90LIBDIR -lF90 -lcl -lc -lisamstub" + FOPTIMFLAGS='-O +Oconservative' + FDEBUGFLAGS='-g' +# + LDCXX="$COMPILER" + LDCXXFLAGS="-b -Wl,+e,$ENTRYPOINT,+e,mexVersion,+e,_shlInit" + LDCXXOPTIMFLAGS='-O' + LDCXXDEBUGFLAGS='-g' +# + LD='ld' + LDFLAGS="-b +e $ENTRYPOINT +e mexVersion" + LDOPTIMFLAGS='' + LDDEBUGFLAGS='' +# + POSTLINK_CMDS=':' +#---------------------------------------------------------------------------- + ;; + hp700) +#---------------------------------------------------------------------------- +# what `which cc` +# HP92453-01 A.10.32.30 HP C Compiler + CC='cc' +# Remove +DAportable from CFLAGS if you wish to optimize +# for target machine + CFLAGS='+Z -Ae +DAportable -Wp,-H65535' + CLIBS="$MLIBS -lc" + COPTIMFLAGS='-O -DNDEBUG' + CDEBUGFLAGS='-g' +# +# what `which aCC` +# HP aC++ B3910B A.01.27 +# HP aC++ B3910B A.01.19.02 Language Support Library + CXX='aCC' +# Remove +DAportable from CXXFLAGS if you wish to optimize +# for target machine + CXXFLAGS='-AA +Z -D_HPUX_SOURCE +DAportable' + CXXLIBS="$MLIBS -lstd_v2 -lCsup_v2" + CXXOPTIMFLAGS='-O -DNDEBUG' + CXXDEBUGFLAGS='-g' +# +# what `which f90` +# HP-UX f90 20010618 (003353) B3907DB/B3909DB PHSS_23952 also B.10.20.40 +# HP F90 v2.5.1 + F90LIBDIR='/opt/fortran90/lib' + FC='f90' + FFLAGS='+Z +DAportable' + FLIBS="$MLIBS -L$F90LIBDIR -lF90 -lcl -lc -lisamstub" + FOPTIMFLAGS='-O' + FDEBUGFLAGS='-g' +# + LDCXX="$COMPILER" + LDCXXFLAGS="-b -Wl,+e,$ENTRYPOINT,+e,mexVersion,+e,_shlInit,+e,errno" + LDCXXOPTIMFLAGS='-O' + LDCXXDEBUGFLAGS='-g' +# + LD='ld' + LDFLAGS="-b +e $ENTRYPOINT +e mexVersion +e errno" + LDOPTIMFLAGS='' + LDDEBUGFLAGS='' +# + POSTLINK_CMDS=':' +#---------------------------------------------------------------------------- + ;; + ibm_rs) +#---------------------------------------------------------------------------- +# lslpp -l | vacpp.cmp.core +# 5.0.0.0 COMMITTED IBM C and C++ Compilers + CC='cc' + CFLAGS='-D_THREAD_SAFE -D_ALL_SOURCE -qchars=signed -qlanglvl=ansi' + CLIBS="$MLIBS -lm " + COPTIMFLAGS='-O -DNDEBUG' + CDEBUGFLAGS='-g' +# lslpp -l vacpp.cmp.core +# 5.0.0.0 COMMITTED IBM C and C++ Compilers + CXX='/usr/vacpp/bin/xlC' + CXXFLAGS='-D_THREAD_SAFE -D_ALL_SOURCE -qrtti=all' + CXXLIBS="$MLIBS -lm" + CXXOPTIMFLAGS='-O -DNDEBUG' + CXXDEBUGFLAGS='-g' +# +# lslpp -l xlfcmp +# 7.1.0.0 COMMITTED I XL Fortran Compiler + FC='f77' + FFLAGS='' + FLIBS="$MLIBS -lmat -lm" + FOPTIMFLAGS='-O' + FDEBUGFLAGS='-g' +# + LDCXX='/usr/vacpp/bin/makeC++SharedLib' + LDCXXFLAGS='-p 0' + LDCXXOPTIMFLAGS='' + LDCXXDEBUGFLAGS='' +# + LD="$COMPILER" + LDFLAGS="-bE:$TMW_ROOT/extern/lib/$Arch/$MAPFILE -bM:SRE -bnoentry" + LDOPTIMFLAGS='-O -Wl,-s' + LDDEBUGFLAGS='-g' +# + POSTLINK_CMDS=':' +#---------------------------------------------------------------------------- + ;; + glnx86) +#---------------------------------------------------------------------------- + RPATH="-Wl,--rpath-link,$TMW_ROOT/extern/lib/$Arch,--rpath-link,$TMW_ROOT/bin/$Arch" +# gcc -v +# gcc version 2.95.2 19991024 (release) + CC='gcc' + CFLAGS='-fPIC -ansi -D_GNU_SOURCE -pthread' + CLIBS="$RPATH $MLIBS -lm" + COPTIMFLAGS='-O -DNDEBUG' + CDEBUGFLAGS='-g' +# +# g++ -v +# gcc version 2.95.2 19991024 (release) + CXX='g++' +# Add -fhandle-exceptions to CXXFLAGS to support exception handling + CXXFLAGS='-fPIC -ansi -D_GNU_SOURCE -pthread' + CXXLIBS="$RPATH $MLIBS -lm" + CXXOPTIMFLAGS='-O -DNDEBUG' + CXXDEBUGFLAGS='-g' +# +# g77 -v -xf77-version +# g77 version 2.95.2 19991024 (release) +# (from FSF-g77 version 0.5.25 19991024 (release)) +# NOTE: g77 is not thread safe + FC='g77' + FFLAGS='-fPIC' + FLIBS="$RPATH $MLIBS -lm" + FOPTIMFLAGS='-O' + FDEBUGFLAGS='-g' +# + LD="$COMPILER" + LDFLAGS="-pthread -shared -Wl,--version-script,$TMW_ROOT/extern/lib/$Arch/$MAPFILE" + LDOPTIMFLAGS='-O' + LDDEBUGFLAGS='-g' +# + POSTLINK_CMDS=':' +#---------------------------------------------------------------------------- + ;; + sgi) +#---------------------------------------------------------------------------- +# cc -version +# MIPSpro Compilers: Version 7.3.1.2m + CC='cc' + CFLAGS='-n32 -signed -OPT:IEEE_NaN_inf=ON -D_POSIX_C_SOURCE=199506L -D__EXTENSIONS__ -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED' + CLIBS="-dont_warn_unused $MLIBS -lm -lc" + COPTIMFLAGS='-O -DNDEBUG' + CDEBUGFLAGS='-g' +# +# CC -version +# MIPSpro Compilers: Version 7.3.1.2m + CXX='CC' +# Add -exceptions to CXXFLAGS to support exception handling + CXXFLAGS='-n32 -OPT:IEEE_NaN_inf=ON -D_POSIX_C_SOURCE=199506L -D__EXTENSIONS__ -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED -LANG:STD -ptused' + CXXLIBS="-dont_warn_unused $MLIBS -lm -lC -lCio" + CXXOPTIMFLAGS='-O -DNDEBUG' + CXXDEBUGFLAGS='-g' +# +# f77 -version +# MIPSpro Compilers: Version 7.3.1.2m + FC='f77' + FFLAGS='-n32 -OPT:IEEE_NaN_inf=ON' + FLIBS="-dont_warn_unused $MLIBS -lm" + FOPTIMFLAGS='-O' + FDEBUGFLAGS='-g' +# + LD="$COMPILER" + LDFLAGS="-n32 -shared -exported_symbol $ENTRYPOINT -exported_symbol mexVersion" + LDOPTIMFLAGS='-O' + LDDEBUGFLAGS='-g' +# + POSTLINK_CMDS=':' +#---------------------------------------------------------------------------- + ;; + sol2) +#---------------------------------------------------------------------------- +# cc -V +# WorkShop Compilers 5.0 98/12/15 C 5.0 + CC='cc' + CFLAGS='-KPIC -dalign -xlibmieee -D__EXTENSIONS__ -D_POSIX_C_SOURCE=199506L -mt' + CLIBS="$MLIBS -lm -lc" + COPTIMFLAGS='-xO3 -xlibmil -DNDEBUG' + CDEBUGFLAGS='-g' +# +# CC -V +# WorkShop Compilers 5.0 98/12/15 C++ 5.0 + CXX='CC -compat=5' + CCV=`CC -V 2>&1` + version=`expr "$CCV" : '.*\([0-9][0-9]*\)\.'` + if [ "$version" = "4" ]; then + echo "SC5.0 or later C++ compiler is required" + fi + CXXFLAGS='-KPIC -dalign -xlibmieee -D__EXTENSIONS__ -D_POSIX_C_SOURCE=199506L -mt' + CXXLIBS="$MLIBS -lm -lCstd -lCrun" + CXXOPTIMFLAGS='-xO3 -xlibmil -DNDEBUG' + CXXDEBUGFLAGS='-g' +# +# f77 -V +# WorkShop Compilers 5.0 99/09/16 FORTRAN 77 5.0 patch 107596-03 + FC='f77' + FFLAGS='-KPIC -dalign -mt' + FLIBS="$MLIBS -lF77 -lM77 -lsunmath -lm -lcx -lc" + FOPTIMFLAGS='-O' + FDEBUGFLAGS='-g' +# + LD="$COMPILER" + LDFLAGS="-G -mt -M$TMW_ROOT/extern/lib/$Arch/$MAPFILE" + LDOPTIMFLAGS='-O' + LDDEBUGFLAGS='-g' +# + POSTLINK_CMDS=':' +#---------------------------------------------------------------------------- + ;; + mac) +#---------------------------------------------------------------------------- + CC='g++3' + CFLAGS='-fno-common -traditional-cpp' + + CLIBS="$MLIBS" + + COPTIMFLAGS='-O3 -DNDEBUG' + CDEBUGFLAGS='-g' + + if [ -f /usr/bin/g++3 ]; then + CXX=g++3 + else + CXX=c++ + fi + CXXFLAGS='-fno-common -traditional-cpp' + CXXLIBS="$MLIBS -lstdc++" + CXXOPTIMFLAGS='-O3 -DNDEBUG' + CXXDEBUGFLAGS='-g' +# + FC='f77' + FFLAGS='-f -N15 -N11 -s -Q51 -W' + ABSOFTLIBDIR=`which $FC | sed -n -e '1s|bin/'$FC'|lib|p'` + FLIBS="-L$ABSOFTLIBDIR -lfio -lf77math" + FOPTIMFLAGS='-O' + FDEBUGFLAGS='-g' +# + LD="$CC" + LDFLAGS="-bundle -Wl,-flat_namespace -undefined suppress -yui" + LDOPTIMFLAGS='-O' + LDDEBUGFLAGS='-g' +# + POSTLINK_CMDS='nmedit -s $TMW_ROOT/extern/lib/$Arch/$MAPFILE $mex_file' +#---------------------------------------------------------------------------- + ;; + esac +############################################################################# +# +# Architecture independent lines: +# +# Set and uncomment any lines which will apply to all architectures. +# +#---------------------------------------------------------------------------- +# CC="$CC" +# CFLAGS="$CFLAGS" +# COPTIMFLAGS="$COPTIMFLAGS" +# CDEBUGFLAGS="$CDEBUGFLAGS" +# CLIBS="$CLIBS" +# +# FC="$FC" +# FFLAGS="$FFLAGS" +# FOPTIMFLAGS="$FOPTIMFLAGS" +# FDEBUGFLAGS="$FDEBUGFLAGS" +# FLIBS="$FLIBS" +# +# LD="$LD" +# LDFLAGS="$LDFLAGS" +# LDOPTIMFLAGS="$LDOPTIMFLAGS" +# LDDEBUGFLAGS="$LDDEBUGFLAGS" +#---------------------------------------------------------------------------- +############################################################################# diff --git a/Cantera/matlab/cantera/oneatm.m b/Cantera/matlab/cantera/oneatm.m new file mode 100755 index 000000000..548b4db34 --- /dev/null +++ b/Cantera/matlab/cantera/oneatm.m @@ -0,0 +1,3 @@ +function p = oneatm +% ONEATM One atmosphere in Pascals. +p = 101325.0; diff --git a/Cantera/matlab/cantera/private/ctfunctions.cpp b/Cantera/matlab/cantera/private/ctfunctions.cpp new file mode 100644 index 000000000..db96919f0 --- /dev/null +++ b/Cantera/matlab/cantera/private/ctfunctions.cpp @@ -0,0 +1,64 @@ + +#include "mex.h" +#include "../../../clib/src/ct.h" +#include "ctmatutils.h" +#include + +void reportError() { + int buflen = 300; + char* output_buf = (char*)mxCalloc(buflen, sizeof(char)); + getCanteraError(buflen, output_buf); + mexErrMsgTxt(output_buf); +} + +void ctfunctions( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) +{ + int job = getInt(prhs[1]); + + int j, m, iok, id; + char *file, *key, *val; + + char *infile, *dbfile, *trfile, *outfile, *idtag; + int buflen; + char* output_buf; + + switch (job) { + + // convert CK file to CTML + case 1: + if (nrhs < 7) { + mexErrMsgTxt("Wrong number of inputs."); + return; + } + infile = getString(prhs[2]); + dbfile = getString(prhs[3]); + trfile = getString(prhs[4]); + outfile = getString(prhs[5]); + idtag = getString(prhs[6]); + + iok = ck_to_ctml(infile, dbfile, trfile, outfile, idtag); + break; + + // get Cantera error + case 2: + buflen = 300; + output_buf = (char*)mxCalloc(buflen, sizeof(char)); + iok = getCanteraError(buflen, output_buf); + plhs[0] = mxCreateString(output_buf); + return; + + // add directory + case 3: + infile = getString(prhs[2]); + iok = addCanteraDirectory(strlen(infile), infile); + break; + + default: + mexErrMsgTxt("ctfunctions: unknown job"); + } + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = double(iok); + if (iok < 0) reportError(); +} diff --git a/Cantera/matlab/cantera/private/ctmatutils.h b/Cantera/matlab/cantera/private/ctmatutils.h new file mode 100755 index 000000000..54acbdd47 --- /dev/null +++ b/Cantera/matlab/cantera/private/ctmatutils.h @@ -0,0 +1,35 @@ +void reportError(); + +void checkNArgs(const int n, const int nrhs); + +template +inline int getInt(A* mxhndl) { + return int(mxGetScalar(mxhndl)); +} + +template +inline double getDouble(A* mxhndl) { + return double(mxGetScalar(mxhndl)); +} + +inline char* getString(const mxArray* p) { + char* input_buf = 0; + int status; + int m = mxGetM(p); + int n = mxGetN(p); + int buflen = m*n + 1; + + if (m == 1) { + input_buf = (char*)mxCalloc(buflen, sizeof(char)); + status = mxGetString(p, input_buf, buflen); + if(status != 0) + mexWarnMsgTxt("Not enough space. String is truncated."); + } + else { + mexErrMsgTxt("string must be a row vector"); + } + return input_buf; +} + + + diff --git a/Cantera/matlab/cantera/private/ctmethods.cpp b/Cantera/matlab/cantera/private/ctmethods.cpp new file mode 100644 index 000000000..99392c3d6 --- /dev/null +++ b/Cantera/matlab/cantera/private/ctmethods.cpp @@ -0,0 +1,56 @@ + +#include "mex.h" +#include "../../../clib/src/ct.h" +#include "ctmatutils.h" + +const int NO_CLASS = 0; +const int XML_CLASS = 10; +const int THERMO_CLASS = 20; +const int PHASE_CLASS = 30; +const int KINETICS_CLASS = 40; +const int TRANSPORT_CLASS = 50; +const int REACTOR_CLASS = 60; +const int WALL_CLASS = 70; +const int FLOWDEVICE_CLASS = 80; + +void ctfunctions( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ); +void xmlmethods( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ); +void thermomethods( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ); +void phasemethods( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ); +void kineticsmethods( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ); +void transportmethods( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ); +void reactormethods( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ); +void wallmethods( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ); +void flowdevicemethods( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ); + +extern "C" { + + void mexFunction( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) + { + int iclass = getInt(prhs[0]); + + switch (iclass) { + case NO_CLASS: + ctfunctions(nlhs, plhs, nrhs, prhs); break; + case XML_CLASS: + xmlmethods(nlhs, plhs, nrhs, prhs); break; + case THERMO_CLASS: + thermomethods(nlhs, plhs, nrhs, prhs); break; + case PHASE_CLASS: + phasemethods(nlhs, plhs, nrhs, prhs); break; + case KINETICS_CLASS: + kineticsmethods(nlhs, plhs, nrhs, prhs); break; + case TRANSPORT_CLASS: + transportmethods(nlhs, plhs, nrhs, prhs); break; + case REACTOR_CLASS: + reactormethods(nlhs, plhs, nrhs, prhs); break; + case WALL_CLASS: + wallmethods(nlhs, plhs, nrhs, prhs); break; + case FLOWDEVICE_CLASS: + flowdevicemethods(nlhs, plhs, nrhs, prhs); break; + default: + mexErrMsgTxt("unknown class"); + } + } +} diff --git a/Cantera/matlab/cantera/private/flowdevicemethods.cpp b/Cantera/matlab/cantera/private/flowdevicemethods.cpp new file mode 100644 index 000000000..89e3ddc06 --- /dev/null +++ b/Cantera/matlab/cantera/private/flowdevicemethods.cpp @@ -0,0 +1,87 @@ + +#include "mex.h" +#include "ctmatutils.h" +#include "../../../clib/src/ctreactor.h" +#include "../../../clib/src/ct.h" + + +const double Undef = -999.123; + + void flowdevicemethods( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) + { + int j, m, iok, n; + char *file, *key, *val; + + int job = getInt(prhs[1]); + int i = getInt(prhs[2]); + + double r = Undef; + double v = Undef; + if (nrhs > 3) v = getDouble(prhs[3]); + + // constructor + if (job == 0) { + n = flowdev_new(i); + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = double(n); + if (n < 0) reportError(); + return; + } + + // options that do not return a value + + if (job < 20) { + switch (job) { + + case 1: + iok = flowdev_del(i); + break; + case 2: + m = getInt(prhs[4]); + iok = flowdev_install(i, int(v), m); + break; + case 3: + iok = flowdev_setSetpoint(i, v); + break; + case 4: + iok = flowdev_setParameters(i, 1, &v); + break; + case 5: + iok = flowdev_setFunction(i, int(v)); + break; + case 6: + iok = flowdev_ready(i); + break; + default: + mexErrMsgTxt("unknown job parameter"); + } + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = double(iok); + if (iok < 0) reportError(); + return; + } + + + // options that return a value of type 'double' + + else if (job < 40) { + switch (job) { + case 21: + r = flowdev_massFlowRate(i); + break; + case 22: + r = flowdev_setpoint(i); + break; + default: + mexErrMsgTxt("unknown job parameter"); + } + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = r; + if (r == Undef) reportError(); + return; + } + } diff --git a/Cantera/matlab/cantera/private/importFromFile.m b/Cantera/matlab/cantera/private/importFromFile.m new file mode 100755 index 000000000..3312fa09e --- /dev/null +++ b/Cantera/matlab/cantera/private/importFromFile.m @@ -0,0 +1,33 @@ +function b = importFromFile(th, k, infile, therm_db) +%importFromFile import a definition of a phase from a file. +% +% function importFromFile reads element, species, and reaction +% definitions from a file. The elements and species are added to +% thermo object 'th', and the reactions are added to 'k', which must be a +% kinetics manager for object th. + +if nargin > 3 + therm = therm_db; +elseif nargin == 3 + therm = ' '; +elseif nargin < 3 + error('syntax error: not enough arguments'); +end + +lasterr(''); + +if isa(th,'Thermo') & isa(k,'Kinetics') & isa(infile,'char') & isa(therm,'char') + ok = import_from_file(hndl(th), hndl(k), infile, therm, ' ', 1); + if ok == -1 + error(geterr); + elseif ok == -999 + disp('exception'); + error(lasterr); + elseif ok < 0 + error('Error importing file'); + end + +else + error('syntax error'); +end +b = {th, k}; diff --git a/Cantera/matlab/cantera/private/kineticsmethods.cpp b/Cantera/matlab/cantera/private/kineticsmethods.cpp new file mode 100644 index 000000000..28760d6b1 --- /dev/null +++ b/Cantera/matlab/cantera/private/kineticsmethods.cpp @@ -0,0 +1,154 @@ + +#include "mex.h" +#include "ctmatutils.h" +#include "../../../clib/src/ct.h" + +void checkNArgs(const int n, const int nrhs) { + if (n != nrhs) { + mexErrMsgTxt("Wrong number of arguments."); + } +} + +void kineticsmethods( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) { + double vv; + int job = getInt(prhs[2]); + int kin, irxn; + + // construct a new instance + if (job == 0) { + checkNArgs(6, nrhs); + int root = getInt(prhs[1]); + int iph = getInt(prhs[3]); + int in1 = getInt(prhs[4]); + int in2 = getInt(prhs[5]); + vv = newKineticsFromXML(root, iph, in1, in2); + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = vv; + return; + } + + // methods + else if (job > 0) { + int isp = 1; + if (job < 5 || job > 6) checkNArgs(4,nrhs); + else { + checkNArgs(5,nrhs); + isp = getInt(prhs[4]); + } + kin = getInt(prhs[1]); + irxn = getInt(prhs[3]); + + // get scalar attributes + if (job < 10) { + + switch (job) { + + case 1: + vv = kin_nReactions(kin); break; + case 2: + vv = kin_multiplier(kin, irxn-1); break; + case 3: + vv = kin_nSpecies(kin); break; + case 4: + vv = kin_isReversible(kin,irxn-1); break; + case 5: + vv = kin_reactantStoichCoeff(kin, isp - 1, irxn-1); + break; + case 6: + vv = kin_productStoichCoeff(kin, isp - 1, irxn-1); + break; + default: + mexErrMsgTxt("unknown job"); + } + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = vv; + return; + } + else if (job < 20) { + + // get reaction array attributes + int nr = kin_nReactions(kin); + plhs[0] = mxCreateNumericMatrix(nr,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + int ok = -10; + switch (job) { + case 11: + ok = kin_getFwdRatesOfProgress(kin,nr,h); break; + case 12: + ok = kin_getRevRatesOfProgress(kin,nr,h); break; + case 13: + ok = kin_getNetRatesOfProgress(kin,nr,h); break; + case 14: + ok = kin_getEquilibriumConstants(kin,nr,h); break; + default: + ; + } + if (ok < 0) + mexErrMsgTxt("error computing rates of progress"); + } + else if (job < 30) { + int nsp = kin_nSpecies(kin); + plhs[0] = mxCreateNumericMatrix(nsp,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + int ok = -10; + switch (job) { + case 21: + ok = kin_getCreationRates(kin,nsp,h); break; + case 22: + ok = kin_getDestructionRates(kin,nsp,h); break; + case 23: + ok = kin_getNetProductionRates(kin,nsp,h); break; + case 24: + ok = kin_getSourceTerms(kin, nsp, h); break; + default: + ; + } + if (ok < 0) + mexErrMsgTxt("error computing production rates"); + } + else if (job < 40) { + char* buf; + int iok = -1, buflen = 80; + switch (job) { + case 31: + buf = (char*)mxCalloc(buflen, sizeof(char)); + iok = kin_getReactionString(kin, irxn-1, buflen, buf); + break; + default: + ; + } + if (iok >= 0) { + plhs[0] = mxCreateString(buf); + return; + } + else reportError(); + } + } + + else { + + // set attributes + int iok = -1; + job = -job; + kin = getInt(prhs[1]); + irxn = getInt(prhs[3]); + + if (job < 10) { + checkNArgs(5,nrhs); + double v = getDouble(prhs[4]); + switch (job) { + case 1: + iok = kin_setMultiplier(kin,irxn-1,v); break; + case 3: + iok = delKinetics(kin); break; + default: + iok = -1; + } + } + + if (iok < 0) mexErrMsgTxt("error in kineticsmethods."); + } +} diff --git a/Cantera/matlab/cantera/private/phasemethods.cpp b/Cantera/matlab/cantera/private/phasemethods.cpp new file mode 100644 index 000000000..89af0110e --- /dev/null +++ b/Cantera/matlab/cantera/private/phasemethods.cpp @@ -0,0 +1,246 @@ + +#include "mex.h" +#include "ctmatutils.h" +#include "../../../clib/src/ct.h" + + void phasemethods( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) + { + double vv; + int iok, k, m; + int ph = getInt(prhs[1]); + int job = getInt(prhs[2]); + + bool ok = true; + int status, buflen; + char* input_buf; + double* ptr; + int n, nsp, mjob; + + // methods to set attributes + if (job < 0) { + mjob = -job; + ptr = mxGetPr(prhs[3]); + m = mxGetM(prhs[3]); + n = mxGetN(prhs[3]); + + nsp = phase_nSpecies(ph); + + // set scalar attributes + bool ok = true; + if (mjob < 10) { + if (m != 1 || n != 1) + mexErrMsgTxt("value must be scalar."); + + switch (mjob) { + case 1: + phase_setTemperature(ph,*ptr); break; + case 2: + phase_setDensity(ph,*ptr); break; + default: + ok = false; + } + } + + // set array attributes + else if (mjob < 30) { + if ((m == nsp && n == 1) || (m == 1 && n == nsp)) { + int norm = 1; + switch (mjob) { + case 20: + phase_setMoleFractions(ph, nsp, ptr, norm); + break; + case 21: + phase_setMassFractions(ph, nsp, ptr, norm); + break; + case 22: + norm = 0; + phase_setMoleFractions(ph, nsp, ptr, norm); + break; + case 23: + norm = 0; + phase_setMassFractions(ph, nsp, ptr, norm); + break; + default: + ok = false; + } + } + else { + mexErrMsgTxt("wrong array size"); + } + } + + // set attributes from a string + else { + int buflen, status; + char* input_buf; + if (mxIsChar(prhs[3]) == 1) { + + if(mxGetM(prhs[3]) != 1) + mexErrMsgTxt("Input must be a row vector."); + + buflen = (mxGetM(prhs[3]) * mxGetN(prhs[3])) + 1; + input_buf = (char*)mxCalloc(buflen, sizeof(char)); + status = mxGetString(prhs[3], input_buf, buflen); + if (status != 0) + mexWarnMsgTxt("Not enough space. " + "String is truncated."); + + switch (mjob) { + case 30: + phase_setMoleFractionsByName(ph, input_buf); + break; + case 31: + phase_setMassFractionsByName(ph, input_buf); + break; + default: + mexErrMsgTxt("what?"); + } + } + else { + mexErrMsgTxt("expected a string."); + } + } + } + + else if (job < 20) { + + switch (job) { + case 0: + vv = newThermoFromXML(ph); break; + // floating-point attributes + case 1: + vv = phase_temperature(ph); break; + case 2: + vv = phase_density(ph); break; + case 3: + vv = phase_molarDensity(ph); break; + case 4: + vv = phase_meanMolecularWeight(ph); break; + case 8: + vv = 1.0/phase_density(ph); break; + case 10: + vv = phase_nElements(ph); break; + case 11: + vv = phase_nSpecies(ph); break; + case 12: + input_buf = getString(prhs[3]); + vv = phase_speciesIndex(ph, input_buf) + 1; + break; + case 13: + input_buf = getString(prhs[3]); + vv = phase_elementIndex(ph, input_buf) + 1; + break; + case 14: + k = getInt(prhs[3]); + m = getInt(prhs[4]); + vv = phase_nAtoms(ph,k-1,m-1); break; + default: + ok = false; + } + if (ok) { + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = vv; + return; + } + } + //ok = true; + + else if (job < 30) { + + iok = 0; + int nsp = phase_nSpecies(ph); + double* x = new double[nsp]; + switch (job) { + case 20: + iok = phase_getMoleFractions(ph,nsp,x); + break; + case 21: + iok = phase_getMassFractions(ph,nsp,x); + break; + case 22: + iok = phase_getMolecularWeights(ph,nsp,x); + break; + default: + ; + } + plhs[0] = mxCreateNumericMatrix(nsp,1, + mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + if (iok >= 0) { + for (int i = 0; i < nsp; i++) h[i] = x[i]; + delete x; + return; + } + else { + for (int i = 0; i < nsp; i++) h[i] = -999.99; + delete x; + mexErrMsgTxt("unknown attribute"); + return; + } + } + + else if (job < 40) { + + iok = 0; + int nel = phase_nElements(ph); + double* x = new double[nel]; + switch (job) { + case 30: + iok = phase_getAtomicWeights(ph,nel,x); + break; + default: + ; + } + plhs[0] = mxCreateNumericMatrix(nel,1, + mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + if (iok >= 0) { + for (int i = 0; i < nel; i++) h[i] = x[i]; + delete x; + return; + } + else { + for (int i = 0; i < nel; i++) h[i] = -999.99; + delete x; + mexErrMsgTxt("unknown attribute"); + return; + } + } + + else if (job < 50) { + iok = -1; + int ksp, mel; + int buflen; + char* output_buf; + switch (job) { + case 40: + ksp = getInt(prhs[3]); + buflen = 40; + output_buf = (char*)mxCalloc(buflen, sizeof(char)); + iok = phase_getSpeciesName(ph, ksp-1, buflen, output_buf); + break; + case 41: + mel = getInt(prhs[3]); + buflen = 40; + output_buf = (char*)mxCalloc(buflen, sizeof(char)); + iok = phase_getElementName(ph, mel-1, buflen, output_buf); + break; + default: + iok = -1; + } + if (iok >= 0) { + plhs[0] = mxCreateString(output_buf); + return; + } + else { + mexErrMsgTxt("error or unknown method."); + return; + } + } + else { + mexErrMsgTxt("unimplemented method."); + return; + } + } diff --git a/Cantera/matlab/cantera/private/reactormethods.cpp b/Cantera/matlab/cantera/private/reactormethods.cpp new file mode 100644 index 000000000..3c4b09c7a --- /dev/null +++ b/Cantera/matlab/cantera/private/reactormethods.cpp @@ -0,0 +1,118 @@ + +#include "mex.h" +#include "../../../clib/src/ctreactor.h" +#include "../../../clib/src/ct.h" +#include "ctmatutils.h" + +const double Undef = -999.123; + + void reactormethods( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) + { + int j, m, iok, n; + char *file, *key, *val; + + int job = getInt(prhs[1]); + int i = getInt(prhs[2]); + + double r = Undef; + double v = Undef; + if (nrhs > 3) v = getDouble(prhs[3]); + + // constructor + if (job == 0) { + n = reactor_new(i); + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = double(n); + if (n < 0) reportError(); + return; + } + + // options that do not return a value + + if (job < 20) { + switch (job) { + + case 1: + iok = reactor_del(i); + break; + case 2: + iok = reactor_copy(i); + break; + case 3: + iok = reactor_assign(i,int(v)); + break; + case 4: + iok = reactor_setInitialVolume(i, v); + break; + case 5: + iok = reactor_setInitialTime(i, v); + break; + case 6: + iok = reactor_setThermoMgr(i, int(v)); + break; + case 7: + iok = reactor_setKineticsMgr(i, int(v)); + break; + case 8: + iok = reactor_advance(i, v); + break; + case 9: + iok = reactor_setEnergy(i, int(v)); + break; + default: + mexErrMsgTxt("unknown job parameter"); + } + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = double(iok); + if (iok < 0) reportError(); + return; + } + + + // options that return a value of type 'double' + + else if (job < 40) { + switch (job) { + case 21: + r = reactor_step(i, v); + break; + case 22: + r = reactor_time(i); + break; + case 23: + r = reactor_mass(i); + break; + case 24: + r = reactor_volume(i); + break; + case 25: + r = reactor_density(i); + break; + case 26: + r = reactor_temperature(i); + break; + case 27: + r = reactor_enthalpy_mass(i); + break; + case 28: + r = reactor_intEnergy_mass(i); + break; + case 29: + r = reactor_pressure(i); + break; + case 30: + r = reactor_massFraction(i, int(v)); + break; + default: + mexErrMsgTxt("unknown job parameter"); + } + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = r; + if (r == Undef) reportError(); + return; + } + } diff --git a/Cantera/matlab/cantera/private/thermomethods.cpp b/Cantera/matlab/cantera/private/thermomethods.cpp new file mode 100644 index 000000000..3ae08db1c --- /dev/null +++ b/Cantera/matlab/cantera/private/thermomethods.cpp @@ -0,0 +1,182 @@ + +#include "mex.h" +#include "../../../clib/src/ct.h" +#include "ctmatutils.h" + +static void thermoset( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) { + + if (nrhs != 4) { + mexErrMsgTxt("wrong number of input parameters."); + } + int ierr = 0; + double vv; + int th = getInt(prhs[1]); + int job = -getInt(prhs[2]); + double* ptr = mxGetPr(prhs[3]); + int m = mxGetM(prhs[3]); + int n = mxGetN(prhs[3]); + + bool ok = true; + + // scalar attributes + if (job < 20) { + if (m != 1 || n != 1) + mexErrMsgTxt("value must be scalar."); + switch (job) { + case 10: + ierr = delThermo(th); break; + case 1: + ierr = th_setPressure(th,*ptr); break; + default: + mexErrMsgTxt("unknown attribute."); + } + } + + // property pairs + else if (job < 40) { + if ((m == 2 && n == 1) || (m == 1 && n == 2)) { + switch (job) { + case 20: + ierr = th_set_HP(th,ptr); break; + case 21: + ierr = th_set_UV(th,ptr); break; + case 22: + ierr = th_set_SV(th,ptr); break; + case 23: + ierr = th_set_SP(th,ptr); break; + default: + mexErrMsgTxt("unknown pair attribute."); + } + } + else { + mexErrMsgTxt("wrong size"); + } + } + + // equilibrate + else if (job == 50) { + int xy = int(*ptr); + ierr = th_equil(th, xy); + } + + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = 1.0*ierr; + return; +} + +static void thermoget( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) + { + double vv; + int n = getInt(prhs[1]); + int job = getInt(prhs[2]); + + if (job < 30) { + + bool ok = true; + switch (job) { + case 0: + vv = newThermoFromXML(n); break; + case 2: + vv = th_enthalpy_mole(n); + break; + case 3: + vv = th_intEnergy_mole(n); break; + case 4: + vv = th_entropy_mole(n); + break; + case 5: + vv = th_gibbs_mole(n); break; + case 6: + vv = th_cp_mole(n); break; + case 7: + vv = th_cv_mole(n); break; + case 8: + vv = th_pressure(n); break; + case 9: + vv = th_enthalpy_mass(n); break; + case 10: + vv = th_intEnergy_mass(n); break; + case 11: + vv = th_entropy_mass(n); break; + case 12: + vv = th_gibbs_mass(n); break; + case 13: + vv = th_cp_mass(n); break; + case 14: + vv = th_cv_mass(n); break; + case 15: + vv = th_refPressure(n); break; + case 16: + vv = th_minTemp(n); break; + case 17: + vv = th_maxTemp(n); break; + case 18: + vv = double(th_eosType(n)); break; + + default: + ok = false; + } + if (ok) { + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = vv; + return; + } + } + else if (job < 50) { + + int iok = 0; + int nsp = th_nSpecies(n); + double* x = new double[nsp]; + switch (job) { + case 32: + iok = th_getEnthalpies_RT(n,nsp,x); + break; + case 34: + iok = th_chemPotentials(n,nsp,x); + break; + case 36: + iok = th_getEntropies_R(n,nsp,x); + break; + case 38: + iok = th_getCp_R(n,nsp,x); + break; + default: + ; + } + plhs[0] = mxCreateNumericMatrix(nsp,1, + mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + if (iok >= 0) { + for (int i = 0; i < nsp; i++) h[i] = x[i]; + delete x; + return; + } + else { + for (int i = 0; i < nsp; i++) h[i] = -999.99; + delete x; + mexErrMsgTxt("unknown attribute"); + return; + } + } + + else { + mexErrMsgTxt("unknown attribute"); + } + } + + +void thermomethods( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) { + + int job = getInt(prhs[2]); + if (job < 0) { + thermoset(nlhs, plhs, nrhs, prhs); + } + else { + thermoget(nlhs, plhs, nrhs, prhs); + } +} diff --git a/Cantera/matlab/cantera/private/transportmethods.cpp b/Cantera/matlab/cantera/private/transportmethods.cpp new file mode 100644 index 000000000..0bc92e891 --- /dev/null +++ b/Cantera/matlab/cantera/private/transportmethods.cpp @@ -0,0 +1,89 @@ + +#include "mex.h" +#include "../../../clib/src/ct.h" +#include "ctmatutils.h" +#include + +void reportError(); + + void transportmethods( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) + { + double vv; + int n = getInt(prhs[1]); + int job = getInt(prhs[2]); + double* h; + int iok = 0; + int nsp; + + if (job == -1) { + char* model = getString(prhs[3]); + int loglevel = getInt(prhs[4]); + int m = -2; + m = newTransport(model, n, loglevel); + if (m < 0) reportError(); + + // Create matrix for the return argument. + plhs[0] = mxCreateDoubleMatrix(1,1, mxREAL); + double* x = mxGetPr(plhs[0]); + *x = m; + return; + } + + + if (job < 10) { + + bool ok = true; + switch (job) { + case 0: + delTransport(n); + vv = 0.0; + break; + case 1: + vv = trans_viscosity(n); + break; + case 2: + vv = trans_thermalConductivity(n); break; + default: + mexErrMsgTxt("unknown Transport method"); + } + if (vv < 0.0) reportError(); + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + h = mxGetPr(plhs[0]); + *h = vv; + return; + } + else if (job < 20) { + nsp = getInt(prhs[3]); + plhs[0] = mxCreateNumericMatrix(nsp,1,mxDOUBLE_CLASS,mxREAL); + h = mxGetPr(plhs[0]); + + switch (job) { + case 11: + iok = trans_getMixDiffCoeffs(n, nsp, h); break; + case 12: + iok = trans_getThermalDiffCoeffs(n, nsp, h); break; + default: + mexErrMsgTxt("unknown Transport method"); + } + } + else if (job < 30) { + nsp = getInt(prhs[3]); + plhs[0] = mxCreateNumericMatrix(nsp,nsp,mxDOUBLE_CLASS,mxREAL); + h = mxGetPr(plhs[0]); + switch (job) { + case 21: + iok = trans_getBinDiffCoeffs(n, nsp, h); break; + case 22: + iok = trans_getMultiDiffCoeffs(n, nsp, h); break; + default: + mexErrMsgTxt("unknown Transport method"); + } + } + else { + mexErrMsgTxt("unknown Transport method"); + } + if (iok < 0) { + reportError(); + } + } diff --git a/Cantera/matlab/cantera/private/wallmethods.cpp b/Cantera/matlab/cantera/private/wallmethods.cpp new file mode 100644 index 000000000..9aeb1635d --- /dev/null +++ b/Cantera/matlab/cantera/private/wallmethods.cpp @@ -0,0 +1,105 @@ + +#include "mex.h" +#include "../../../clib/src/ctreactor.h" +#include "../../../clib/src/ct.h" +#include "ctmatutils.h" + +const double Undef = -999.123; + + void wallmethods( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) + { + int j, m, iok, n; + char *file, *key, *val; + + int job = getInt(prhs[1]); + int i = getInt(prhs[2]); + + double r = Undef; + double v = Undef; + if (nrhs > 3) v = getDouble(prhs[3]); + + // constructor + if (job == 0) { + n = wall_new(i); + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = double(n); + if (n < 0) reportError(); + return; + } + + // options that do not return a value + + if (job < 20) { + switch (job) { + + case 1: + iok = wall_del(i); + break; + case 2: + iok = wall_copy(i); + break; + case 3: + iok = wall_assign(i,int(v)); + break; + case 4: + m = getInt(prhs[4]); + iok = wall_install(i, int(v), m); + break; + case 5: + iok = wall_setArea(i, v); + break; + case 6: + iok = wall_setThermalResistance(i, v); + break; + case 7: + iok = wall_setHeatTransferCoeff(i, v); + break; + case 8: + iok = wall_setHeatFlux(i, int(v)); + break; + case 9: + iok = wall_setExpansionRateCoeff(i, v); + break; + case 10: + iok = wall_setExpansionRate(i, int(v)); + break; + case 11: + iok = wall_ready(i); + break; + default: + mexErrMsgTxt("unknown job parameter"); + } + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = double(iok); + if (iok < 0) reportError(); + return; + } + + + // options that return a value of type 'double' + + else if (job < 40) { + switch (job) { + case 21: + r = wall_vdot(i, v); + break; + case 22: + r = wall_Q(i, v); + break; + case 23: + r = wall_area(i); + break; + default: + mexErrMsgTxt("unknown job parameter"); + } + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = r; + if (r == Undef) reportError(); + return; + } + } + diff --git a/Cantera/matlab/cantera/private/xmlmethods.cpp b/Cantera/matlab/cantera/private/xmlmethods.cpp new file mode 100644 index 000000000..a4c1b46ca --- /dev/null +++ b/Cantera/matlab/cantera/private/xmlmethods.cpp @@ -0,0 +1,145 @@ + +#include "mex.h" +#include "../../../clib/src/ctxml.h" +#include "../../../clib/src/ct.h" +#include "ctmatutils.h" + +void reportError(); + +static bool nargs_ok(int job, int n) { + switch (n) { + case 1: case 2: case 10: case 21: case 22: + return (n == 2); + case 3: case 4: case 6: case 7: case 8: case 9: + case 13: case 14: case 20: + return (n == 3); + case 5: case 11: case 12: + return (n == 4); + default: + return true; + } +} + +void xmlmethods( int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[] ) +{ + int j, m, iok, id; + char *file, *key, *val, *nm; + + int job = getInt(prhs[1]); + int i = getInt(prhs[2]); + + // Check for proper number of arguments + if (!nargs_ok(job,nrhs-1)) { + mexErrMsgTxt("Wrong number of inputs."); + return; + } + else if(nlhs > 1) { + mexErrMsgTxt("Too many output arguments"); + } + + + // options that do not return a value + + if (job < 20) { + switch (job) { + case 0: + nm = getString(prhs[3]); + iok = xml_new(nm); + break; + case 1: + iok = xml_del(i); + break; + case 2: + iok = xml_copy(i); + break; + case 3: + j = getInt(prhs[3]); + iok = xml_assign(i,j); + break; + case 4: + file = getString(prhs[3]); + iok = xml_build(i, file); + break; + case 5: + key = getString(prhs[3]); + val = getString(prhs[4]); + iok = xml_addAttrib(i, key, val); + break; + case 6: + key = getString(prhs[3]); + iok = xml_child(i, key); + break; + case 7: + m = getInt(prhs[3]); + iok = xml_child_bynumber(i, m); + break; + case 8: + key = getString(prhs[3]); + iok = xml_findID(i, key); + break; + case 9: + key = getString(prhs[3]); + iok = xml_findByName(i, key); + break; + case 10: + iok = xml_nChildren(i); + break; + case 11: + key = getString(prhs[3]); + val = getString(prhs[4]); + iok = xml_addChild(i, key, val); + break; + case 12: + key = getString(prhs[3]); + j = getInt(prhs[4]); + iok = xml_addChildNode(i, j); + break; + case 13: + file = getString(prhs[3]); + iok = xml_write(i, file); + break; + case 14: + j = getInt(prhs[3]); + iok = xml_removeChild(i, j); + break; + + default: + mexErrMsgTxt("unknown job parameter"); + } + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = double(iok); + if (iok < 0) reportError(); + return; + } + + // options that return strings + + char* v = (char*)mxCalloc(80, sizeof(char)); + switch (job) { + case 20: + // return an attribute + key = getString(prhs[3]); + iok = xml_attrib(i, key, v); + break; + case 21: + // return the value of the node + iok = xml_value(i, v); + break; + case 22: + iok = xml_tag(i, v); + break; + default: + mexErrMsgTxt("unknown job parameter"); + } + if (iok < 0) { + plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); + double *h = mxGetPr(plhs[0]); + *h = double(iok); + if (iok < 0) reportError(); + } + else { + plhs[0] = mxCreateString(v); + } +} diff --git a/Cantera/matlab/cantera/reactor_ode.m b/Cantera/matlab/cantera/reactor_ode.m new file mode 100644 index 000000000..718d31079 --- /dev/null +++ b/Cantera/matlab/cantera/reactor_ode.m @@ -0,0 +1,51 @@ +function dydt = reactor_ode(t,y,gas,vdot,area,heatflux) +% REACTOR ODE system for a generic zero-dimensional reactor. +% +% Function REACTOR evaluates the system of ordinary differential +% equations for a zero-dimensional reactor with arbitrary heat +% transfer and volume change. +% +% Solution vector components: +% y(1) Total internal energy U +% y(2) Volume V +% y(3) Mass of species 1 +% .... +% y(2+nsp) Mass of last species +% + +[m,n] = size(y); +dydt = zeros(m,n); + +for j = 1:n + + this_y = y(:,j); + int_energy = this_y(1); + vol = this_y(2); + masses = this_y(3:end); + + % evaluate the total mass, and the specific internal energy and volume. + total_mass = sum(masses); + u_mass = int_energy/total_mass; + v_mass = vol/total_mass; + + % set the state of the gas by specifying (u,v,{Y_k}) + setMassFractions(gas,masses); + setState_UV(gas, [u_mass v_mass]); + p = pressure(gas); + + % volume equation + vdt = feval(vdot, t, vol, gas); + + % energy equation + a = feval(area, t, vol); + q = feval(heatflux, t, gas); + udt = -p * vdt + a * q; + + % species equations + ydt = total_mass * ydot(gas); + + % set up column vector for dydt + dydt(:,j) = [ udt + vdt + ydt ]; +end diff --git a/Cantera/matlab/cantera/tutorial/README b/Cantera/matlab/cantera/tutorial/README new file mode 100755 index 000000000..d627461bc --- /dev/null +++ b/Cantera/matlab/cantera/tutorial/README @@ -0,0 +1,5 @@ + +This directory contains several short tutorials. Each one is a MATLAB +script that you should first read and then execute. + + diff --git a/Cantera/matlab/cantera/tutorial/tut1.m b/Cantera/matlab/cantera/tutorial/tut1.m new file mode 100755 index 000000000..e15127745 --- /dev/null +++ b/Cantera/matlab/cantera/tutorial/tut1.m @@ -0,0 +1,204 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Getting started +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +% Start MATLAB, and at the prompt type: + +gas1 = GRI30 + +% If you have successfully installed the Cantera toolbox, +% you should see something like this: +% +% +% temperature 300 K +% pressure 101325 Pa +% density 0.081896 kg/m^3 +% mean mol. weight 2.01594 amu +% +% X Y +% ------------- ------------ +% H2 1.000000e+000 1.000000e+000 +% H 0.000000e+000 0.000000e+000 +% O 0.000000e+000 0.000000e+000 +% O2 0.000000e+000 0.000000e+000 +% OH 0.000000e+000 0.000000e+000 +% H2O 0.000000e+000 0.000000e+000 +% HO2 0.000000e+000 0.000000e+000 +% H2O2 0.000000e+000 0.000000e+000 +% C 0.000000e+000 0.000000e+000 +% CH 0.000000e+000 0.000000e+000 +% CH2 0.000000e+000 0.000000e+000 +% CH2(S) 0.000000e+000 0.000000e+000 +% CH3 0.000000e+000 0.000000e+000 +% CH4 0.000000e+000 0.000000e+000 +% CO 0.000000e+000 0.000000e+000 +% CO2 0.000000e+000 0.000000e+000 +% HCO 0.000000e+000 0.000000e+000 +% CH2O 0.000000e+000 0.000000e+000 +% CH2OH 0.000000e+000 0.000000e+000 +% CH3O 0.000000e+000 0.000000e+000 +% CH3OH 0.000000e+000 0.000000e+000 +% C2H 0.000000e+000 0.000000e+000 +% C2H2 0.000000e+000 0.000000e+000 +% C2H3 0.000000e+000 0.000000e+000 +% C2H4 0.000000e+000 0.000000e+000 +% C2H5 0.000000e+000 0.000000e+000 +% C2H6 0.000000e+000 0.000000e+000 +% HCCO 0.000000e+000 0.000000e+000 +% CH2CO 0.000000e+000 0.000000e+000 +% HCCOH 0.000000e+000 0.000000e+000 +% N 0.000000e+000 0.000000e+000 +% NH 0.000000e+000 0.000000e+000 +% NH2 0.000000e+000 0.000000e+000 +% NH3 0.000000e+000 0.000000e+000 +% NNH 0.000000e+000 0.000000e+000 +% NO 0.000000e+000 0.000000e+000 +% NO2 0.000000e+000 0.000000e+000 +% N2O 0.000000e+000 0.000000e+000 +% HNO 0.000000e+000 0.000000e+000 +% CN 0.000000e+000 0.000000e+000 +% HCN 0.000000e+000 0.000000e+000 +% H2CN 0.000000e+000 0.000000e+000 +% HCNN 0.000000e+000 0.000000e+000 +% HCNO 0.000000e+000 0.000000e+000 +% HOCN 0.000000e+000 0.000000e+000 +% HNCO 0.000000e+000 0.000000e+000 +% NCO 0.000000e+000 0.000000e+000 +% N2 0.000000e+000 0.000000e+000 +% AR 0.000000e+000 0.000000e+000 +% C3H7 0.000000e+000 0.000000e+000 +% C3H8 0.000000e+000 0.000000e+000 +% CH2CHO 0.000000e+000 0.000000e+000 +% CH3CHO 0.000000e+000 0.000000e+000 +% +% What you have just done is to create an object ("gas1") that +% implements GRI-Mech 3.0, the 53-species, 325-reaction natural gas +% combustion mechanism developed by Gregory P. Smith, David M. Golden, +% Michael Frenklach, Nigel W. Moriarty, Boris Eiteneer, Mikhail +% Goldenberg, C. Thomas Bowman, Ronald K. Hanson, Soonho Song, William +% C. Gardiner, Jr., Vitali V. Lissianski, and Zhiwei Qin. (See +% http://www.me.berkeley.edu/gri_mech/ for more information about +% GRI-Mech 3.0.) +% +% The object created by GI30 has properties you would expect for a gas +% mixture - it has a temperature, a pressure, species mole and mass +% fractions, etc. As we'll soon see, it has many other properties too. +% +% The summary of the state of 'gas1' printed above shows that new +% objects created by function GRI30 start out with a temperature of +% 300 K, a pressure of 1 atm, and have a composition that consists of +% only one species, in this case hydrogen. There is nothing special +% about H2 - it just happens to be the first species listed in the +% input file defining GRI-Mech 3.0 that the 'GRI30' function reads. In +% general, the species listed first will initially have a mole +% fraction of 1.0, and all of the others will be zero. + +% Setting the state +% ----------------- + +% The state of the object can easily be changed. For example, + +setTemperature(gas1, 1200) + +% sets the temperature to 1200 K. (Cantera always uses SI units.) + +% Notice in the summary of properties that MATLAB prints after this +% command is executed that the temperature has been changed as +% requested, but the pressure has changed too. The density and +% composition have not. +% +% When setting properties individually, some convention needs to be +% adopted to specify which other properties are held constant. This is +% because thermodynamics requires that *two* properties (not one) in +% addition to composition information be specified to fix the +% intensive state of a substance (or mixture). +% +% Cantera adopts the following convention: only one of the set +% (temperature, density, mass fractions) is altered by setting any +% single property. In particular: +% +% a) Setting the temperature is done holding density and +% composition fixed. (The pressure changes.) + +% b) Setting the pressure is done holding temperature and +% composition fixed. (The density changes.) +% +% c) Setting the composition is done holding temperature +% and density fixed. (The pressure changes). +% + + +% Setting multiple properties: the 'set' method +% --------------------------------------------- + +% If you want to set multiple properties at once, use the 'set' +% method. (Note: a 'method' is just the term for a function that acts +% on an object. In MATLAB, methods take the object as the first +% argument.) + +set(gas1, 'Temperature', 900.0, 'Pressure', 1.e5) + +% This statement sets both temperature and pressure at the same +% time. Any number of property/value pairs can be specified in a +% call to 'set'. For example, the following sets the mole fractions +% too: +set(gas1, 'Temperature', 900.0, 'Pressure', 1.e5, 'MoleFractions', ... + 'CH4:1,O2:2,N2:7.52') + +% The 'set' method also accepts abbreviated property names: + +set(gas1,'T',900.0,'P',1.e5,'X','CH4:1,O2:2,N2:7.52') + +% Either version results in +% +% temperature 900 K +% pressure 100000 Pa +% density 0.3693 kg/m^3 +% mean mol. weight 27.6332 amu +% +% X Y +% ------------- ------------ +% O2 1.901141e-001 2.201489e-001 +% CH4 9.505703e-002 5.518732e-002 +% N2 7.148289e-001 7.246638e-001 +% + +% Other properties may also be set using 'set', including some that +% can't be set individually. The following property pairs may be +% set: (Enthalpy, Pressure), (IntEnergy, Volume), (Entropy, +% Volume), (Entropy, Pressure). In each case, the values of the +% extensive properties must be entered *per unit mass*. + +% Setting the enthalpy and pressure: +set(gas1, 'Enthalpy', 2*enthalpy_mass(gas1), 2*oneatm); + + +% The composition above was specified using a string. The format is a +% comma-separated list of : +% pairs. The mole numbers will be normalized to produce the mole +% fractions, and therefore they are 'relative' mole numbers. Mass +% fractions can be set in this way too by changing 'X' to 'Y' in the +% above statement. + +% The composition can also be set using an array, which can be +% either a column vector or a row vector but must have the same +% size as the number of species. For example, to set all 53 mole +% fractions to the same value, do this: + +x = ones(53,1); % a column vector of 53 ones +set(gas1, 'X', x) + +% To set the mass fractions to equal values: +set(gas1, 'Y', x) + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% end of tutorial 1 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + + diff --git a/Cantera/matlab/cantera/tutorial/tut2.m b/Cantera/matlab/cantera/tutorial/tut2.m new file mode 100755 index 000000000..ecdbb0d19 --- /dev/null +++ b/Cantera/matlab/cantera/tutorial/tut2.m @@ -0,0 +1,95 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Tutorial 2: Using your own reaction mechanism files +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +% Function 'IdealGasMix' +% ---------------------- + +% In the last tutorial, we used function GRI30 to create an object +% that models an ideal gas mixture with the species and reactions of +% GRI-Mech 3.0. Another way to do this is shown here: + +gas = IdealGasMix('gri30.xml') + +% Function 'IdealGasMix' constructs an object representing an ideal +% gas mixture by reading in attributes of the mixture from a file, +% which in this case is 'gri30.xml'. This file contains a complete +% specification of the GRI-Mech 3.0 reaction mechanism, including +% element data (name, atomic weight), species data (name, elemental +% composition, coefficients to compute thermodynamic and transport +% properties), and reaction data (stoichiometry, rate coefficient +% parameters). The file is written in an XML dialect understood by +% Cantera (CTML, or "Cantera Markup Language"). +% +% Several reaction mechanism files in CTML format are included in the +% Cantera distribution, including ones that model high-temperature air +% and a hydrogen/oxygen reaction mechanism. Under Windows, the +% installation program puts these files in 'C:\Program +% File\Common Files\Cantera.' On a unix/linux machine, they are +% kept in the 'data/inputs' subdirectory within the Cantera +% installation directory. +% +% +% CK-format files +% --------------- +% +% Cantera also can use reaction mechanism files written in the format +% used in the Chemkin-II software package [1], which we will refer to +% as 'CK format'. Many gas-phase reaction mechanisms are available in +% this format. (See, for example, +% http://www.galcit.caltech.edu/EDL/mechanisms/library/library.html) + +% To use a CK-format reaction mechanism file, call IdealGasMix with +% the file name, followed by the name of the thermodynamic property +% database (optional), followed by the name of the transport +% database (optional): +% +% gas1 = IdealGasMix('mech1.inp') +% gas2 = IdealGasMix('mech2.inp','therm.dat') +% gas3 = IdealGasMix('mech2.inp','therm.dat','tran.dat') +% +% If no transport database is specified, then transport property +% evaluation is disabled. +% +% When function IdealGasMix is called with a CK file as an +% argument, an equivalent file in CTML format is written, and then +% the mixture attributes are read in from the CTML file. The next +% time you use the mechanism, you can simply specify the CTML file: +% +% gas2 = IdealGasMix('mech2.xml') +% +% Note that CTML files contain all required thermodynamic and +% transport data, and so no external databases need be specified. + + +% The Search Path +% --------------- +% +% Cantera looks in several standard directories for input files. As +% long as you have set CANTERA_ROOT correctly, you can use file +% 'gri30.xml' and the others that come with Cantera from any +% directory. But note that Cantera always looks in the local directory +% first. So if you have a modified file of the same name in the local +% directory, it will be used instead. +% +% If you have a directory where you keep files you want to use with +% Cantera, you can add it to the Cantera search path. For example, to +% add directory '/usr/local/lib/inputs' to the search path, call the +% MATLAB function 'addDirectory': +% +% addDirectory('/usr/local/lib/inputs') + + +%---------------------------------------------------------------- +% [1] R. J. Kee, F. M. Rupley, and J. A. Miller, Sandia National +% Laboratories Report SAND89-8009 (1989). + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% end of tutorial 2 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + diff --git a/Cantera/matlab/cantera/tutorial/tut3.m b/Cantera/matlab/cantera/tutorial/tut3.m new file mode 100755 index 000000000..5680cd829 --- /dev/null +++ b/Cantera/matlab/cantera/tutorial/tut3.m @@ -0,0 +1,54 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Tutorial 3: Getting Help +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Suppose you have created a Cantera object and want to know what +% methods are available for it, and get help on using the methods. + +g = GRI30 + +% The first thing you need to know is the MATLAB class object g +% belongs to. Type: + +class(g) + +% This tells you that g belongs to a class called 'solution'. To find +% the methods for this class, type + +methods solution + +% This command returns only a few method names. These are the ones +% directly defined in this class. But solution inherits many other +% methods from base classes. To see all of its methods, type + +methods solution -full + +% Now a long list is printed, along with a specification of the class +% the method is inherited from. For example, 'setPressure' is +% inherited from a class 'thermophase'. Don't be concerned at this +% point about what these base classes are - we'll come back to them +% later. + +% Now that you see what methods are available, you can type 'help +% ' to print help text for any method. For example, + +help setTemperature +help setMassFractions +help rop_net + +% For help on how to construct objects of a given class, type 'help +% ' + +help Solution + +% Now that you know how to get help when you need it, you can +% explore using the Cantera Toolbox on your own. But there are a +% few more useful things to know, which are described in the next +% few tutorials. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% end of tutorial 3 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/Cantera/matlab/cantera/tutorial/tut4.m b/Cantera/matlab/cantera/tutorial/tut4.m new file mode 100755 index 000000000..cf31f839a --- /dev/null +++ b/Cantera/matlab/cantera/tutorial/tut4.m @@ -0,0 +1,76 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Tutorial 4: Chemical Equilibrium +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% To set a gas mixture to a state of chemical equilibrium, use the +% 'equilibrate' method. +% +g = GRI30; +set(g,'T',300.0,'P',oneatm,'X','CH4:0.95,O2:2,N2:7.52') +equilibrate(g,'TP') + +% The above statement sets the state of object 'g' to the state of +% chemical equilibrium holding temperature and pressure +% fixed. Alternatively, the specific enthalpy and pressure can be held +% fixed: + +set(g,'T',300.0,'P',oneatm,'X','CH4:0.95,O2:2.0,N2:7.52'); +equilibrate(g,'HP') + +% Other options are +% 'UV' fixed specific internal energy and specific volume +% 'SV' fixed specific entropy and specific volume +% 'SP' fixed specific entropy and pressure + +set(g,'T',300.0,'P',oneatm,'X','CH4:0.95,O2:2,N2:7.52'); +equilibrate(g,'UV') + +set(g,'T',300.0,'P',oneatm,'X','CH4:0.95,O2:2,N2:7.52'); +equilibrate(g,'SV') + +set(g,'T',300.0,'P',oneatm,'X','CH4:0.95,O2:2,N2:7.52'); +equilibrate(g,'SP') + +% How can you tell if 'equilibrate' has correctly found the +% chemical equilibrium state? One way is verify that the net rates of +% progress of all reversible reactions are zero. + +% Here is the code to do this: +set(g,'T',2000.0,'P',oneatm,'X','CH4:0.95,O2:2,N2:7.52'); +equilibrate(g,'TP') +rf = rop_f(g); +rr = rop_r(g); +format short e; +for i = 1:nReactions(g) + if isReversible(g,i) + disp([i, rf(i), rr(i), (rf(i) - rr(i))/rf(i)]); + end +end + + +% You might be wondering how 'equilibrate' works. (Then again, you might +% not, in which case you can go on to the next tutorial now.) Method +% 'equilibrate' invokes Cantera's chemical equilibrium solver, which +% uses an element potential method. The element potential method is +% one of a class of equivalent 'nonstoichiometric' methods that all +% have the characteristic that the problem reduces to solving a set of +% M nonlinear algebraic equations, where M is the number of elements +% (not species). The so-called 'stoichiometric' methods, on the other +% hand, (including Gibbs minimization), require solving K nonlinear +% equations, where K is the number of species (usually K >> M). See +% Smith and Missen, "Chemical Reaction Equilibrium Analysis" for more +% information on the various algorithms and their characteristics. +% +% Cantera uses a damped Newton method to solve these equations, and +% does a few other things to generate a good starting guess and to +% produce a reasonably robust algorithm. If you want to know more +% about the details, look at the on-line documented source code of +% Cantera C++ class 'ChemEquil' at http://www.cantera.org. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% end of tutorial 4 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \ No newline at end of file diff --git a/Cantera/matlab/cantera/tutorial/tut5.m b/Cantera/matlab/cantera/tutorial/tut5.m new file mode 100755 index 000000000..59f136a48 --- /dev/null +++ b/Cantera/matlab/cantera/tutorial/tut5.m @@ -0,0 +1,105 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Tutorial 5: Reaction information and rates +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +g = GRI30; +set(g,'T',1500,'P',oneatm,'X',ones(nSpecies(g),1)); + +% Methods are provided that compute many quantities of interest for +% kinetics. Some of these are: + + +% 1) Stoichiometric coefficients + +nu_r = stoich_r(g) % reactant stoichiometric coefficient mstix +nu_p = stoich_p(g) % product stoichiometric coefficient mstix +nu_net = stoich_net(g) % net (product - reactant) stoichiometric + % coefficient mstix + +% For any of these, the (k,i) matrix element is the stoichiometric +% coefficient of species k in reaction i. Since these coefficient +% matrices are very sparse, they are implemented as MATLAB sparse +% matrices. + + +% 2) Reaction rates of progress + +% Methods rop_f, rop_r, and rop_net return column vectors containing +% the forward, reverse, and net (forward - reverse) rates of +% progress, respectively, for all reactions. + +qf = rop_f(g); +qr = rop_r(g); +qn = rop_net(g); +rop = [qf, qr, qn] + +% This plots the rates of progress +figure(1); +bar(rop); +legend('forward','reverse','net'); + +% 3) Species production rates + +% Methods creationRates, destructionRates, and netProdRates return +% column vectors containing the creation, destruction, and net +% production (creation - destruction) rates, respectively, for all species. + +cdot = creationRates(g); +ddot = destructionRates(g); +wdot = netProdRates(g); +rates = [cdot, ddot, wdot] + +% This plots the production rates +figure(2); +bar(rates); +legend('creation','destruction','net'); + +% For comparison, the production rates may also be computed +% directly from the rates of progress and stoichiometric +% coefficients. + +cdot2 = nu_p*qf + nu_r*qr; +creation = [cdot, cdot2, cdot - cdot2] + +ddot2 = nu_r*qf + nu_p*qr; +destruction = [ddot, ddot2, ddot - ddot2] + +wdot2 = nu_net * qn; +net = [wdot, wdot2, wdot - wdot2] + + +% 4) Reaction equations + +e8 = reactionEqn(g,8) % equation for reaction 8 +e1_10 = reactionEqn(g,1:10) % equation for rxns 1 - 10 +eqs = reactionEqn(g) % all equations + + + +% 5) Equilibrium constants + +% The equilibrium constants are computed in concentration units, +% with concentrations in kmol/m^3. + +kc = equil_Kc(g); +for i = 1:nReactions(g) + disp(sprintf('%50s %13.5g', eqs{i}, kc(i))) +end + + + +% 6) Multipliers + +% For each reaction, a multiplier may be specified that is applied +% to the forward rate coefficient. By default, the multiplier is +% 1.0 for all reactions. + +for i = 1:nReactions(g) + setMultiplier(g, i, 2*i); + m = multiplier(g, i); +end + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/Cantera/matlab/cantera/tutorial/tut6.m b/Cantera/matlab/cantera/tutorial/tut6.m new file mode 100755 index 000000000..63f78e6ff --- /dev/null +++ b/Cantera/matlab/cantera/tutorial/tut6.m @@ -0,0 +1,62 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Tutorial 5: Transport properties +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Methods are provided to compute transport properties. By +% default, calculation of transport properties is not enabled. If +% transport properties are required, the transport model must be +% specified when the gas mixture object is constructed. + +% Currently, two models are implemented. Both are based on kinetic +% theory expressions, and follow the approach described in Dixon-Lewis +% (1968) and Kee, Coltrin, and Glarborg (2002). The first is a full +% multicomponent formulation, and the second is a simplification that +% uses expressions derived for mixtures with a small number of species +% (1 to 3), using approximate mixture rules to average over +% composition. + +% To use the multicomponent model with GRI-Mech 3.0, call function +% GRI30 as follows: + +g1 = GRI30('Multi') + +% To use the mixture-averaged model: + +g2 = GRI30('Mix') + + +% Both models use a mixture-averaged formulation for the viscosity. +visc = [viscosity(g1), viscosity(g2)] + +% The thermal conductivity differs, however. +lambda = [thermalConductivity(g1), thermalConductivity(g2)] + +% Binary diffusion coefficients +bdiff1 = binDiffCoeffs(g1) +bdiff2 = binDiffCoeffs(g2) + +% Mixture-averaged diffusion coefficients. These are only +% implemented if the mixture-averaged model is used. +dmix = mixDiffCoeffs(g2) + +% Multicomponent diffusion coefficients. These are only implemented +% if the multicomponent model is used. +dmulti = multiDiffCoeffs(g1) + +% Thermal diffusion coefficients. These are only implemented with the +% multicomponent model. These will be very close to zero, since +% the composition is pure H2. +dt = thermalDiffCoeffs(g1) + +% Now change the composition and re-evaluate +set(g1,'X',ones(nSpecies(g1),1)); +dt = thermalDiffCoeffs(g1) + +% Note that there are no singularities for pure gases. This is +% because a very small positive value is added to all mole +% fractions for the purpose of computing transport properties. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + diff --git a/Cantera/matlab/cantera/tutorial/tut7.m b/Cantera/matlab/cantera/tutorial/tut7.m new file mode 100755 index 000000000..f0d44dfa4 --- /dev/null +++ b/Cantera/matlab/cantera/tutorial/tut7.m @@ -0,0 +1,39 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Tutorial 7: Thermodynamic Properties +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% A variety of thermodynamic property methods are provided. + +gas = air +set(gas,'T',800,'P',oneatm) + + +% temperature, pressure, density +T = temperature(gas) +P = pressure(gas) +rho = density(gas) +n = molarDensity(gas) + + +% species non-dimensional properties +hrt = enthalpies_RT(gas) % vector of h_k/RT + + +% mixture properties per mole +hmole = enthalpy_mole(gas) +umole = intEnergy_mole(gas) +smole = entropy_mole(gas) +gmole = gibbs_mole(gas) + + +% mixture properties per unit mass +hmass = enthalpy_mass(gas) +umass = intEnergy_mass(gas) +smass = entropy_mass(gas) +gmass = gibbs_mass(gas) + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + diff --git a/Cantera/matlab/setup_matlab.py b/Cantera/matlab/setup_matlab.py new file mode 100644 index 000000000..7852ed652 --- /dev/null +++ b/Cantera/matlab/setup_matlab.py @@ -0,0 +1,25 @@ + +import sys + +if len(sys.argv) >= 3: + libdir = sys.argv[1] + libs = '-l'+sys.argv[2]+' '+sys.argv[3] +else: + print 'usage: python setup_matlab.py ' + sys.exit(0) + +f = open('setup.m','w') +f.write('cd cantera\nbuildux\nexit\n') +f.close() + +fb = open('cantera/buildux.m','w') +fb.write(""" +disp('building Cantera..'); +mex private/ctmethods.cpp private/ctfunctions.cpp ... + private/xmlmethods.cpp private/phasemethods.cpp ... + private/thermomethods.cpp private/kineticsmethods.cpp ... + private/transportmethods.cpp private/reactormethods.cpp ... + private/wallmethods.cpp private/flowdevicemethods.cpp ... +"""+' -L'+libdir+' '+libs+'\n'+"""disp('done.'); +""") +fb.close() diff --git a/Cantera/python/.cvsignore b/Cantera/python/.cvsignore new file mode 100644 index 000000000..3c6ff92ae --- /dev/null +++ b/Cantera/python/.cvsignore @@ -0,0 +1,2 @@ +Makefile +build diff --git a/Cantera/python/Cantera/Flow.py b/Cantera/python/Cantera/Flow.py new file mode 100755 index 000000000..c9d7ae63c --- /dev/null +++ b/Cantera/python/Cantera/Flow.py @@ -0,0 +1,682 @@ +""" +One-dimensional reacting flows. +""" + +from Cantera import getCanteraError +from FlowPlotter import FlowPlotter + +from exceptions import * +import refine +import sys, types, copy, tempfile +import _cantera +import interp +import math + +from Numeric import array, zeros, ones, transpose, size, sort, shape, asarray + +_flows = {'Stagnation':0, 'Stag':0, + 'OneDimensional':1, '1D':1, 'OneD':1, 'OneDim':1, + 'Free':2} + +_geom = {'Axisymmetric':0, 'Axi':0, 'Planar':1} + + + +class Flow1D: + """ One-dimensional reacting flows. + + Class Flow1D models several types of steady 'one dimensional' + reacting flows. The flows are one-dimensional in the sense that + the governing equations for the steady-state solution can be cast + in the form of a set of ordinary differential equations in one + axial coordinate (z). For the case of stagnation flows, this + results from a similarity transformation that reduces the + physically two-dimensional problem to one that is mathematically + one-dimensional. + + The types of flows that may be simulated are: + + - One-dimensional reacting flows, such as burner-stabilized + premixed flames; + - Axisymmetric stagnation-point flows + - Planar stagnation-point flows + + """ + + + # Allowed option keywords are defined here so that only these + # keywords may be added to the _opt dictionary. + + _timeint_options = ['ftime', 'min_timestep', 'max_timestep', + 'nsteps', 'timestep'] + _newton_options = ['max_jac_age', 'rtol', 'atol'] + _output_options = ['loglevel', 'plotfile'] + + _options = _newton_options + _timeint_options + _output_options + + + + def __init__(self, + flow_type = 'Stagnation', + flow_geom = 'Axisymmetric', + gas = None, + grid = None, + pressure = 1.01325e5): + """Flow1D Constructor. + """ + + self.__flow_id = -1 + self.domainType = 0 + self.loglevel = 1 + self.initial = {} + if not grid: + raise CanteraError('Grid not specified!') + + if not gas: + raise CanteraError('Gas mixture object not specified!') + self.gas = gas + self.nsp = self.gas.nSpecies() + self.nv = self.nsp + 4 + + if _flows.has_key(flow_type): + self.type = _flows[flow_type] + else: + raise CanteraError('unsupported flow type: '+flow_type) + + if self.type == 0: + if flow_geom == 'Planar': self.type = 3 + + + # Create the kernel object. This is an instance of a subclass of + # C++ Cantera class 'StFlow'. + self.__flow_id = _cantera.Flow(self.type, self.gas.phase_id(), len(grid)) + + + # Set the grid. Must be done _after_ creating the kernel + # object, since it sets the grid there too. + self.setGrid(asarray(grid)) + + + # Set the pressure. Note that the pressure is constant + # throughout the flowfield, due to the assumption of low Mach + # number. + self.setPressure(pressure) + + + # set the thermo, kinetics, and transport managers to those of + # object self.gas. + self.setThermo(self.gas) + self.setKinetics(self.gas) + self.setTransport(self.gas) + + + # create a NumPy array to hold the solution. Since NumPy + # arrays are stored by row, while Cantera expects arrays + # stored by column, this array is defined with the grid point + # number as the first index. In this way, all solution + # variables for one grid point will be stored in contiguous + # locations. + self.x = zeros((self.npts, self.nsp + 4), 'd') + self.xnew = zeros((self.npts, self.nsp + 4), 'd') + + + # Default error tolerances + self.setTolerances( + u = (1.e-8, 1.e-15), + V = (1.e-8, 1.e-15), + T = (1.e-8, 1.e-15), + L = (1.e-8, 1.e-15), + Y = (1.e-8, 1.e-15)) + + self.energy = 0 + self.names = ['u','V','T','L']+ list(self.gas.speciesNames()) + + # finish setting default parameter values + self.restoreDefaults() + + self.time = 0.0 + + # For refiner, only refine the grid based on species mass + # fraction and velocity profiles until the energy equation is + # enabled. + self.refine_components = range(4,4+self.nsp) + if self.type == 0: self.refine_components.append([0,1]) + self.refiner = refine.Refiner(components = self.refine_components, + names = self.names) + + + # Create an object to handle plotting results. + self.plotter = FlowPlotter(self) + + #================> end of method '__init__' <=================== + + + + def __del__(self): + """Delete the Flow1D instance.""" + if self.__flow_id >= 0: + _cantera.flow_delete(self.__flow_id) + + def shape(self): + """Return (rows, columns) of solution matrix.""" + return (len(self.z), self.gas.nSpecies() + 4) + + def nPoints(self): + """Number of grid points.""" + return self.npts + + def flow_id(self): + """ID used to accesss the kernel object.""" + return self.__flow_id + + def option(self, key): + """Return the value of an option.""" + return self._opt[key] + + def setGrid(self, z): + """Set the grid to the values in sequence z. + + The values will be sorted, and so the input sequence + does not need to be monotonic. + """ + self.z = array(z) + sort(self.z) + self.npts = len(z) + return _cantera.flow_setupgrid(self.flow_id(), z) + + + def setThermo(self, th): + """Set the thermodynamic property manager.""" + id = _cantera.flow_setthermo(self.flow_id(), th.phase_id()) + return id + + def setKinetics(self, kin): + """Set the kinetics manager.""" + id = _cantera.flow_setkinetics(self.__flow_id, kin.ckin) + return id + + def setTransport(self, tr, soret=0): + """Set the transport manager.""" + id = _cantera.flow_settransport(self.__flow_id, + tr.transport_id(), soret) + return id + + def setPressure(self, p): + """Set the pressure [Pa]. + + Since the flow has very nearly the same pressure everywhere, + this pressure value is used in all computations involving the + equation of state. + """ + self.p = p + _cantera.flow_setpressure(self.__flow_id, p) + + + def holdTemperature(self, points, t0): + """Hold the temperature at grid points 'points' to t0, + and disable the energy equation. + """ + self.x[points,2] = t0 + _cantera.flow_settemperature(self.__flow_id, points, t0) + self.setEnergyEqn('off') + + + def holdMassFraction(self, j, k, y0): + self.x[j,4+k] = y0 + _cantera.flow_setmassfraction(self.__flow_id, j, k, y0) + + + def setInitialProfiles(self, datatable=None): + + """Set initial velocity, temperature, and/or species profiles. + + datatable -- Dictionary mapping variable names to sequences of + (position, value) pairs. The position is specified in + relative terms, as a number in the range [0,1], where the + value zero corresponds to the smallest grid value, and the + value one to the largest. + + The keys of datatable must be 'u', 'V', 'T', or a species + name. Velocity and temperature values are entered in SI units, + and species values are entered in arbitrary molar units, and + will be normalized to produce mole fractions. + + The profile will be linearly interpolated onto the grid from + the data provided. Each variable may be specified at different + locations. + + Example: + + data = {} + data['T'] = [(0, 500), (0.3, 2000), (0.8, 2200), (1, 1500)] + data['u'] = [(0, 0.0), (1, 2)] + data['H2'] = [(0, 0.2), (1, 0.3)] + data['O2'] = [(0, 0.8), (1, 0.7)] + flow.setInitialProfiles(data) + + """ + + if datatable: + self.datatable = datatable + else: + datatable = self.datatable + + vars = datatable.keys() + x = zeros((self.npts, self.nsp),'d') + equil = 0 + + for var in vars: + data = datatable[var] + if not var == 'equil': + data.sort() + zz = [] + v = [] + for item in data: + zz.append(self.z[0] + item[0]*(self.z[-1] - self.z[0])) + v.append(item[1]) + self.initial[var] = (zz, v) + + if (var == 'u'): + for j in range(self.npts): + self.x[j,0] = interp.interp(self.z[j],zz,v) + + elif (var == 'V'): + for j in range(self.npts): + self.x[j,1] = interp.interp(self.z[j],zz,v) + elif (var == 'T'): + for j in range(self.npts): + self.holdTemperature(j,interp.interp(self.z[j],zz,v)) + else: + k = self.gas.speciesIndex(var) + if k < 0: + raise CanteraError('Unknown species name: '+var) + for j in range(self.npts): + x[j,k] = interp.interp(self.z[j],zz,v) + else: + equil = 1 + + if equil == 1: + xin = self.left.X + x[0,:] = xin + for j in range(1,self.npts): + self.gas.setState_TPX(self.x[j,2],self.p,xin) + try: + self.gas.equilibrate('TP') + except: + pass + x[j,:] = self.gas.moleFractions() + + # convert input mole fractions to mass fractions, + # and set the mass fraction profiles + + for j in range(self.npts): + self.gas.setMoleFractions(x[j,:]) + y = self.gas.massFractions() + for k in range(self.nsp): + self.x[j, k+4] = y[k] + self.holdMassFraction(j,k,y[k]) + self.enableSpecies() + + + def regrid(self, grid): + oldx = self.x + oldgrid = self.z + np, nv = shape(oldx) + v = range(nv) + self.setGrid(grid) + for j in range(self.npts): + for n in v: + self.x[j,n] = interp.interp(self.z[j], oldgrid, oldx) + + def __repr__(self): + return self.show() + + def show(self): + fname = tempfile.mktemp('.dat') + x = self.x + _cantera.flow_showsolution(self.__flow_id, fname, x) + f = open(fname,'r') + y = f.readlines() + print + for line in y: + print line, + print + f.close() + + def showResid(self): + """Print the current residual values""" + print transpose(self.resid()) + + def T(self,j): + """Temperature at grid point j [K].""" + return self.x[j,2] + + def u(self,j): + """Axial velocity at grid point j [m/s].""" + return self.x[j, 0] + + + def V(self,j): + """Radial velocity divided by radius at grid point j [1/s].""" + return self.x[j, 1] + + def lamb(self,j): + """(1/r)(dP/dr) at grid point j. + + If the solution has converged, this will be the same at all + grid points. + """ + return self.x[j, 3] + + def massFraction(self,sp,j): + """Mass fraction of species 'sp', which may be referenced by + name or by index number.""" + k = self.gas.speciesIndex(sp) + return self.x[j, k + 4] + + def density(self, j): + """Density [kg/m^3].""" + self.setGas(j) + return self.gas.density() + + def molWt(self, j): + """Mean molecular weight [kg/kmol].""" + self.setGas(j) + return self.gas.meanMolecularWeight() + + def setGas(self, j): + """Set the state of the internal gas mixture object to be + consistent with the solution at grid point j.""" + self.gas.setTemperature(self.T(j)) + y = self.x[j,4:] + self.gas.setMassFractions(y) + self.gas.setPressure(self.p) + + + def setTolerances(self, u = None, V = None, T = None, + L = None, Y = None): + """Set error tolerances. + + The inputs are tuples of (relative, absolute) tolerances for + each of u, V, T, L, and Y. + """ + default = (1.e-7, 1.e-15) + if u == None: u = default + if V == None: V = default + if T == None: T = default + if L == None: L = default + if Y == None: Y = default + + rtol = zeros(self.nsp+4,'d') + atol = zeros(self.nsp+4,'d') + + rtol[0] = u[0] + rtol[1] = V[0] + rtol[2] = T[0] + rtol[3] = L[0] + for k in range(self.nsp): + rtol[4+k] = Y[0] + + atol[0] = u[1] + atol[1] = V[1] + atol[2] = T[1] + atol[3] = L[1] + for k in range(self.nsp): + atol[4+k] = Y[1] + + _cantera.flow_settolerances(self.__flow_id, len(rtol), rtol, + len(atol), atol) + + def disableSpecies(self): + off = zeros(self.nsp,'d') + _cantera.flow_solvespecies(self.__flow_id, self.nsp, off) + + def enableSpecies(self): + o = ones(self.nsp,'d') + _cantera.flow_solvespecies(self.__flow_id, self.nsp, o) + + + def setEnergyEqn(self, o, loglevel = 0, pt = -1): + """Enable or disable the energy equation.""" + if o == 'on': + self.energy = 1 + _cantera.flow_energy(self.__flow_id, pt, 1) + if loglevel > 0: print '\n%%%%%%%%%%%% Enabling energy equation %%%%%%%%%%%%\n' + elif o == 'off': + self.energy = 0 + _cantera.flow_energy(self.__flow_id, pt, 0) + if loglevel > 0: print '\n%%%%%%%%%%%% Disabling energy equation %%%%%%%%%%%%\n' + + def setEnergyFactor(self, e): + _cantera.flow_setenergyfactor(self.__flow_id, e) + +## def resid(self, point = -1): +## """Return the residual vector. + +## If 'point' is specified, the residual is only evaluated at +## this point and those adjacent to it. Otherwise, it is +## evaluated at all grid points. +## """ + +## r = zeros(shape(self.x),'d') +## if point >= 0 and point < self.npts: +## j = point +## else: +## j = -1 +## _cantera.flow_eval(self.__flow_id, j, self.x, r) +## return r + + + def ssnorm(self): + """Absolute maximum value of the steady-state residual for any + component at any point.""" + a = self.container.ssnorm(self.x,self.xnew) + return a + + def integrateChem(self, dt, loglevel=1): + """Condition the species profiles by integrating the + constant-pressure kinetics rate equations + \[ + \dot Y_k = \dot\omega_k M_k / \rho. + \] + at each grid point for time 'dt'. + """ + if loglevel > 0: + print '\nIntegrating the chemical ource terms for %10.4g s...' % dt, + _cantera.flow_integratechem(self.__flow_id, self.x, dt) + print _cantera.readlog() + + + def restoreDefaults(self): + """Restore default options.""" + self._opt = {} + self.setOptions( + + max_jac_age = 5, + timestep = 1.e-6, + min_timestep = 1.e-12, + max_timestep = 0.1, + nsteps = 20, + ftime = 3.0, + + plotfile = "" + ) + + def setOptions(self, **options): + """Set options.""" + for kw in options.keys(): + if kw in Flow1D._options: + self._opt[kw] = options[kw] + else: + raise OptionError(kw) + + + def refine(self, loglevel = 2): + """Refine the grid. + + """ + r = self.refiner + r.components = range(4,self.nsp+4) + if self.energy: + r.components.append(2) + + + #dsave = r.delta + #while 1 > 0: + # try: + znew, zadded, xn, ok = r.refine(grid = self.z, solution = self.x) + nin = len(znew) - len(self.z) + # break + # except: + # r.delta = (0.9*r.delta[0], 0.9*r.delta[1]) + #r.delta = dsave + + if not ok: + self.setGrid(znew) + self.x = array(xn,'d') + self.xnew = zeros(shape(xn),'d') + + # update the fixed temperature values if the energy + # equation is not being solved + + if self.energy == 0: + for j in range(self.npts): + zz, tt = self.initial['T'] + t = interp.interp(self.z[j],zz,tt) + self.holdTemperature(j,t) + else: + for j in range(self.npts): + self.holdTemperature(j,self.x[j,2]) + self.setEnergyEqn('on') + + if loglevel > 0: + print 'Refine: ', + print 'added',nin,'points.' + print 'Grid size = ',len(self.z) + + return nin + + + def save(self, filename, id, desc="", append=0): + """Save a solution to a file. + + filename -- file name. If the file, does not exist, it will + be created. The save files are xml files, and the + filename should have the extension '.xml'. If it + does not, this extension will be appended to the + name. + + id -- the ID tag of the solution. Multiple solutions may + be saved to the same file. Specifying a unique ID + tag allows this solution to selected later by + method 'restore'. + + append -- If append > 0, the solution will be appended to the + file. Otherwise, the file will be overwritten if it + exists. + """ + appnd = append + fn = filename + extn = filename[-4:] + if extn <> '.xml' and extn <> '.XML': + fn = filename + '.xml' + + #if self.loglevel > 0: + #print 'Solution saved to file',filename,'as solution',`id` + + #_cantera.flow_save(self.__flow_id, fn, id, appnd, self.x) + _cantera.flow_save(self.__flow_id, fn, id, desc, self.x) + print _cantera.readlog() + + np, nv = shape(self.x) + f = open('ctsoln.dat','w') + for j in range(np): + f.write('%14.6e %14.6e ' % (100.0*self.z[j], self.x[j,2])) + for k in range(4,nv): + f.write('%14.6e ' % (self.x[j,k],)) + f.write('\n') + f.close() + + + def restore(self, filename, id): + """Restore a previously-saved solution. + + filename -- name of a file containing a solution previously + saved by a call to 'save' + id -- the ID tag of the solution + """ + + #try: + (z, s) = _cantera.flow_restore(self.__flow_id, 0, filename, id) + #except: + # raise CanteraError() + + self.setGrid(z) + self.x = array(s,'d') + self.xnew = array(self.x,'d') + + for j in range(self.npts): + self.holdTemperature(j,self.x[j,2]) + self.initial['T'] = (self.z, self.x[:,2]) + + self.setEnergyEqn('off') + if self.loglevel > 0: + print 'Solution ',`id`,'read from file',filename + print _cantera.readlog() + + + def outputTEC(self, plotfile="", title="", zone="c0", append=0): + """Write the current solution to a file in TECPLOT format. + + plotfile -- file name (required) + title -- plot title + zone -- zone name + append -- if append > 0, the output is appended to the file + + """ + self.plotter.plot(fname = plotfile, title = title, + zone = zone, append=append) + + + def outputCSV(self, plotfile="", append=0): + """Write the current solution to a file in CSV format. + + plotfile -- file name (required) + append -- if append > 0, the output is appended to the file + + """ + self.plotter.plot(fname = plotfile, fmt = 'EXCEL', + append=append) + + + + def plot(self, i): + """Plot solution component i. Requires the scipy package.""" + from scipy import gplt + return gplt.plot(self.z, self.x[:,i]) + + + + def setBoundaries(self, left = None, right = None): + """Install the boundary objects. + + The type of boundary object determines the boundary conditions. + """ + nleft = 0 + nright = 0 + if left: + self.left = left + nleft = left.bdry_id() + if right: + self.right = right + nright = right.bdry_id() + _cantera.flow_setboundaries(self.__flow_id, nleft, nright) + +""" + $Author$ + $Revision$ + $Date$ + + Copyright 2001 California Institute of Technology +""" + diff --git a/Cantera/python/Cantera/FlowBoundary.py b/Cantera/python/Cantera/FlowBoundary.py new file mode 100755 index 000000000..27199d932 --- /dev/null +++ b/Cantera/python/Cantera/FlowBoundary.py @@ -0,0 +1,140 @@ +from Cantera import CanteraError +import _cantera +from Numeric import * + +class FlowBoundary: + def __init__(self, type, phase, kin=None): + self.phase = phase + self.kin = kin + if kin: + self.__bdry_id = _cantera.bdry_new(type, phase.phase_id(), kin.kin_id()) + else: + self.__bdry_id = _cantera.bdry_new(type, phase.phase_id(), 0) + + FlowBoundary.set(self, mdot = 0.0, V = 0.0, T = phase.temperature(), + X = phase.moleFractions()) + + def __del__(self): + _cantera.bdry_del(self.__bdry_id) + def bdry_id(self): + return self.__bdry_id + def set(self, mdot = -999.0, V = -999.0, T = -999.0, X = None, Y = None): + if mdot > 0.0: + self.mdot = mdot + _cantera.bdry_set(self.__bdry_id, 1, mdot, None) + if V > 0.0: + self.V = V + _cantera.bdry_set(self.__bdry_id, 2, V, None) + if T > 0.0: + self.T = T + _cantera.bdry_set(self.__bdry_id, 3, T, None) + if X: + self.phase.setMoleFractions(X) + yy = self.phase.massFractions() + self.X = self.phase.moleFractions() + _cantera.bdry_set(self.__bdry_id, 4, 0.0, yy) + if Y: + self.phase.setMassFractions(Y) + yy = self.phase.massFractions() + self.X = self.phase.moleFractions() + _cantera.bdry_set(self.__bdry_id, 4, 0.0, yy) + + +class Inlet(FlowBoundary): + def __init__(self, phase): + FlowBoundary.__init__(self, 0, phase) + + +class Outlet(FlowBoundary): + def __init__(self, phase): + FlowBoundary.__init__(self, 1, phase) + def set(self, mdot = -999.0, V = -999.0, T = -999.0, X = None, Y = None): + raise CanteraError("outlet properties cannot be set.") + + +class Surface(FlowBoundary): + def __init__(self, phase, surf): + self._surf = surf + self.domainType = 1 + FlowBoundary.__init__(self, 2, phase, surf) + self.__surf1d_id = _cantera.surf1d_new(self.kin.kin_id()) + self.x = zeros((1,self.kin.nSpecies()),'d') + self.x[0,:] = self.kin.coverages() + self.species_on = [] + self.species_off = [] + def surf_id(self): + return self.__surf1d_id + def setCoverages(self, theta): + self.kin.setCoverages(theta) + self.x[0,:] = self.kin.coverages() + def coverages(self): + return self.x[0] # kin.coverages() + def show(self): + self.kin.setCoverages(self.x) + self.kin.show() + def shape(self): + return (1, self.kin.nSpecies()) + def integrate(self, dt): + self.kin.setCoverages(self.x) + self.kin.integrate(dt) + c = self.kin.coverages() + self.x[0,:] = c + for k in range(len(c)): + #print k, c[k] + self.fixSpecies(k,c[k]) + self.setSpeciesEqn(on = self.species_on, off = self.species_off) + def fixSpecies(self, k, c): + _cantera.surf1d_fixspecies(self.__surf1d_id, k, c) + def setTemperature(self, t): + _cantera.surf1d_settemperature(self.__surf1d_id, t) + def temperature(self): + return _cantera.surf1d_temperature(self.__surf1d_id) + def setMultiplier(self,f): + for k in range(self.kin.nSpecies()): + _cantera.surf1d_setmultiplier(self.__surf1d_id,k,f) + + def setSpeciesEqn(self, on=None, off=None, loglevel=0): + """Enable or disable surface species equations.""" + + self.species_on = on + self.species_off = off + + on_msg = `on` + off_msg = `off` + if on == 'all': + on = self.kin.speciesNames() + on_msg = 'all species' + if off == 'all': + off = self.kin.speciesNames() + off_msg = 'all species' + + a = zeros(self.kin.nSpecies(),'d') + + if loglevel > 0: + if on: + print '\n\n--------------------------------------------------\n' + print 'Enabling species equation for',on_msg + print '\n--------------------------------------------------\n\n' + if off: + print '\n\n--------------------------------------------------\n' + print 'Disabling species equation for',off_msg + print '\n--------------------------------------------------\n\n' + if on: + for sp in on: + k = self.kin.speciesIndex(sp) + a[k] = 1.0 + if off: + for sp in off: + k = self.kin.speciesIndex(sp) + a[k] = 0.0 + + _cantera.surf1d_solvespecies(self.__surf1d_id, len(a), a) + + + +class SymmPlane(FlowBoundary): + def __init__(self, phase): + FlowBoundary.__init__(self, 3, phase) + def set(self, mdot = -999.0, V = -999.0, T = -999.0, X = None, Y = None): + raise CanteraError("outlet properties cannot be set.") + diff --git a/Cantera/python/Cantera/FlowPlotter.py b/Cantera/python/Cantera/FlowPlotter.py new file mode 100755 index 000000000..673b36a3f --- /dev/null +++ b/Cantera/python/Cantera/FlowPlotter.py @@ -0,0 +1,65 @@ +""" +Plotting of Flow1D solutions. +""" + +from Numeric import shape, zeros, ones, array + +class FlowPlotter: + """FlowPlotter objects handle generating plots of Flow1D solutions. + + This class is primarily designed for internal use by class Flow1D. + """ + + def __init__(self, flow): + self.flow = flow + self.np = 0 + self.nv = 0 + self.names = ['z [m]', 'u [m/s]', 'V [1/s]', + 'T [K]', 'lambda', 'P [Pa]'] + list(flow.gas.speciesNames()) + + def value(self, j, n): + if n == 0: + return self.flow.z[j] + elif n < 5: + return self.flow.x[j,n-1] + elif n == 5: + return self.flow.gas.pressure() + else: + return self.mf[j,n-6] + + + def plot(self, fmt = 'TECPLOT', + fname = 'plot.dat', title = 'plot', + zone = 'zone1', + moles = 1, + append = 0): + + self.np, self.nv = shape(self.flow.x) + self.mf = zeros((self.np, self.nv - 4), 'd') + if moles: + for j in range(self.np): + self.flow.setGas(j) + self.mf[j,:] = self.flow.gas.moleFractions() + else: + for j in range(self.np): + self.flow.setGas(j) + self.mf[j,:] = self.flow.gas.massFractions() + + if fmt == 'TECPLOT': + from tecplot import write_TECPLOT_zone + data = zeros((self.np,self.flow.gas.nSpecies()+6),'d') + data[:,0] = self.flow.z + data[:,1:5] = self.flow.x[:,0:4] + data[:,5] = ones(self.np)*self.flow.gas.pressure() + data[:,6:] = self.mf + + write_TECPLOT_zone(fname, title, zone, self.names, + self.np, self.nv+2, append, data) + + elif fmt == 'EXCEL': + from excel import write_CSV_data + write_CSV_data(fname, self.names, + self.np, self.nv+2, append, self) + else: + raise 'unknown format'+fmt + diff --git a/Cantera/python/Cantera/Func.py b/Cantera/python/Cantera/Func.py new file mode 100644 index 000000000..f7dc54720 --- /dev/null +++ b/Cantera/python/Cantera/Func.py @@ -0,0 +1,122 @@ +""" + +The classes in this module are designed to allow constructing +user-defined functions of one variable in Python that can be used with the +Cantera C++ kernel. These classes are mostly shadow classes for +corresponding classes in the C++ kernel. + +""" + +from Numeric import array, asarray, ravel, shape, transpose +import _cantera +import types + + +class Func1: + """Base class for functions of one variable.""" + def __init__(self, typ, n, coeffs=[]): + self.n = n + self.coeffs = asarray(coeffs,'d') + self._func_id = ctfunc.func_new(typ, n, self.coeffs) + + def __del__(self): + ctfunc.func_del(self._func_id) + + def __call__(self, t): + return ctfunc.func_value(self._func_id, t) + + def __add__(self, other): + if type(other) == types.FloatType: + return SumFunction(self, Const(other)) + return SumFunction(self, other) + + def __radd__(self, other): + if type(other) == types.FloatType: + return SumFunction(Const(other),self) + return SumFunction(other, self) + + def __mul__(self, other): + return ProdFunction(self, other) + + def __rmul__(self, other): + return ProdFunction(other, self) + + def __div__(self, other): + return RatioFunction(self, other) + + def __rdiv__(self, other): + return RatioFunction(other, self) + + def func_id(self): + return self._func_id + + +class Polynomial(Func1): + """A polynomial. The degree is determined by the number of coefficients + supplied. Example: + + p = Polynomial([1.0, -2.0, 3.0]) # 3t^2 - 2t + 1 + """ + def __init__(self, coeffs=[]): + Func1.__init__(self, 2, len(coeffs)-1, coeffs) + + + +class Fourier(Func1): + """ + Fourier series. + + f(t) = a[0]/2 + sum_{i=1}^n [a[i]*cos(n*omega*t) + b[i]*sin(n*omega*t)] + + Note that b[0] must be specified for symmetry with 'a', but is not + used. + """ + + def __init__(self, omega, c): + cc = asarray(c,'d') + n, m = cc.shape + if m <> 2: + raise CanteraError('provide (a, b) for each term') + cc[0,1] = omega + Func1.__init__(self, 1, n-1, ravel(transpose(cc))) + + +class Arrhenius(Func1): + def __init__(self, c): + cc = asarray(c,'d') + n, m = cc.shape + if m <> 3: + raise CanteraError('Three Arrhenius parameters (A, b, E) required.') + Func1.__init__(self, 3, n, ravel(cc)) + + + +def Const(value): + return Polynomial([value]) + + + +# functions that combine two functions + +class SumFunction(Func1): + def __init__(self, f1, f2): + self.f1 = f1 + self.f2 = f2 + self.n = -1 + self._func_id = ctfunc.func_newcombo(20, f1.func_id(), f2.func_id()) + +class ProdFunction(Func1): + def __init__(self, f1, f2): + self.f1 = f1 + self.f2 = f2 + self.n = -1 + self._func_id = ctfunc.func_newcombo(30, f1.func_id(), f2.func_id()) + +class RatioFunction(Func1): + def __init__(self, f1, f2): + self.f1 = f1 + self.f2 = f2 + self.n = -1 + self._func_id = ctfunc.func_newcombo(40, f1.func_id(), f2.func_id()) + + diff --git a/Cantera/python/Cantera/Interface.py b/Cantera/python/Cantera/Interface.py new file mode 100644 index 000000000..d8dab6c85 --- /dev/null +++ b/Cantera/python/Cantera/Interface.py @@ -0,0 +1,41 @@ +""" +""" + +import string +import os + +from constants import * +from SurfacePhase import SurfacePhase +from Kinetics import Kinetics +import XML + +class Interface(SurfacePhase, Kinetics): + """ + ... + """ + + def __init__(self, src="", root=None, phases=[]): + + self.ckin = 0 + self._owner = 0 + self.verbose = 1 + + fn = string.split(src,'#') + fn = fn[0] + fname = os.path.basename(fn) + ff = os.path.splitext(fname) + + # get the 'phase' element + s = XML.find_XML(src=src, root=root, name="phase") + + # get the equation of state model + SurfacePhase.__init__(self, xml_phase=s) + + # get the kinetics model + Kinetics.__init__(self, xml_phase=s, phases=[self]+phases) + + + def __del__(self): + Kinetics.__del__(self) + SurfacePhase.__del__(self) + diff --git a/Cantera/python/Cantera/Kinetics.py b/Cantera/python/Cantera/Kinetics.py new file mode 100755 index 000000000..76cc5af26 --- /dev/null +++ b/Cantera/python/Cantera/Kinetics.py @@ -0,0 +1,192 @@ + +from Cantera.exceptions import CanteraError +from Cantera.ThermoPhase import ThermoPhase +from Cantera.XML import XML_Node +import Numeric +import _cantera + + +def buildKineticsPhases(root=None, id=None): + """Return a list of ThermoPhase objects representing the phases + involved in a reaction mechanism. + + root -- XML node contaning a 'kinetics' child + id -- id attribute of the desired 'kinetics' node + """ + kin = root.child(id = id) + phase_refs = kin.children("phaseRef") + th = None + phases = [] + for p in phase_refs: + phase_id = p["id"] + try: + th = ThermoPhase(root=root, id=phase_id) + except: + if p["src"]: + pnode = XML_Node(name="root",src=src) + th = ThermoPhase(pnode, phase_id) + else: + raise CanteraError("phase "+phase_id+" not found.") + phases.append(th) + return phases + + +class Kinetics: + """ + Kinetics managers. Instances of class Kinetics are responsible for + evaluating reaction rates of progress, species production rates, + and other quantities pertaining to a reaction mechanism. + """ + + def __init__(self, kintype=-1, thrm=0, xml_phase=None, id=None, phases=[]): + """Build a kinetics manager from an XML specification. + + root -- root of a CTML tree + + id -- id of the 'kinetics' node within the tree that contains + the specification of the parameters. + """ + np = len(phases) + self._ph = {} + self._end = [0] + p0 = phases[0].thermophase() + self._ph[phases[0]] = 0 + self._end.append(phases[0].nSpecies()) + p1 = -1 + p2 = -1 + if np >= 2: + p1 = phases[1].thermophase() + self._ph[phases[1]] = 1 + self._end.append(self._end[-1] + phases[1].nSpecies()) + if np >= 3: + p2 = phases[2].thermophase() + self._ph[phases[2]] = 2 + self._end.append(self._end[-1] + phases[2].nSpecies()) + self.ckin = _cantera.KineticsFromXML(xml_phase, + p0, p1, p2) + self.phases = phases + + + + def __del__(self): + """Delete the kinetics manager.""" + if self.ckin > 0: + _cantera.kin_delete(self.ckin) + + def kin_index(self): + return self.ckin + + def kineticsType(self): + """Kinetics manager type.""" + return _cantera.kin_type(self.ckin) + + def kineticsSpeciesIndex(self, name, phase): + return _cantera.kin_speciesIndex(self.ckin, name, phase) + + def kineticsStart(self, n): + return _cantera.kin_start(self.ckin, n) + + def nReactions(self): + """Number of reactions.""" + return _cantera.kin_nreactions(self.ckin) + + def isReversible(self,i): + """ + True (1) if reaction number 'i' is reversible, + and false (0) otherwise. + """ + return _cantera.kin_isreversible(self.ckin,i) + + def reactionType(self,i): + """Type of reaction 'i'""" + return _cantera.kin_rxntype(self.ckin,i) + + def reactionString(self,i): + return _cantera.kin_getstring(self.ckin,1,i) + + def reactionEqn(self,i): + try: + eqs = [] + for rxn in i: + eqs.append(_cantera.kin_getstring(self.ckin,1,rxn)) + return eqs + except: + return _cantera.kin_getstring(self.ckin,1,i) + + def reactantStoichCoeff(self,k,i): + return _cantera.kin_rstoichcoeff(self.ckin,k,i) + + def reactantStoichCoeffs(self): + nsp = _cantera.kin_nspecies(self.ckin) + nr = _cantera.kin_nreactions(self.ckin) + nu = Numeric.zeros((nsp,nr),'d') + for i in range(nr): + for k in range(nsp): + nu[k,i] = _cantera.kin_rstoichcoeff(self.ckin,k,i) + return nu + + def productStoichCoeff(self,k,i): + return _cantera.kin_pstoichcoeff(self.ckin,k,i) + + def productStoichCoeffs(self): + nsp = _cantera.kin_nspecies(self.ckin) + nr = _cantera.kin_nreactions(self.ckin) + nu = Numeric.zeros((nsp,nr),'d') + for i in range(nr): + for k in range(nsp): + nu[k,i] = _cantera.kin_pstoichcoeff(self.ckin,k,i) + return nu + + def fwdRatesOfProgress(self): + return _cantera.kin_getarray(self.ckin,10) + + def revRatesOfProgress(self): + return _cantera.kin_getarray(self.ckin,20) + + def netRatesOfProgress(self): + return _cantera.kin_getarray(self.ckin,30) + + def equilibriumConstants(self): + return _cantera.kin_getarray(self.ckin,40) + + def creationRates(self, phase = None): + c = _cantera.kin_getarray(self.ckin,50) + if phase: + if self._ph.has_key(phase): + n = self._ph[phase] + return c[self._end[n]:self._end[n+1]] + else: + raise CanteraError('unknown phase') + else: + return c + + + + def destructionRates(self): + return _cantera.kin_getarray(self.ckin,60) + + def netProductionRates(self): + return _cantera.kin_getarray(self.ckin,70) + + def sourceTerms(self): + return _cantera.kin_getarray(self.ckin,80) + + def multiplier(self,i): + return _cantera.kin_multiplier(self.ckin,i) + + def setMultiplier(self,i,v): + return _cantera.kin_setMultiplier(self.ckin,i,v) + + + + + + + + + + + + + + diff --git a/Cantera/python/Cantera/OneDim.py b/Cantera/python/Cantera/OneDim.py new file mode 100755 index 000000000..489ad7c97 --- /dev/null +++ b/Cantera/python/Cantera/OneDim.py @@ -0,0 +1,432 @@ + +from exceptions import * +import refine +import sys, types, copy, tempfile +import interp +import math + +import _cantera + +from Numeric import * + +def print_heading(msg): + print '\n\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n' + print msg + print '\n' + + + +class OneDim: + """ + One-dimensional, multi-domain problems. + + Class OneDim allows solving multi-domain, one-dimensional, + steady-state problems implicitly. Each domain has a set of one or + more grid points, and each may have a different number of solution + components. + + At ... N(I) algebraic residual + equations are defined for the N(I) solution components. Each + domain may have a different number of components. + + The domains are linked in a linear chain, and are of two + types. Standard domains know nothing of their neighbors, and + evaluate their residual functions using only information in their + own domain. 'Connector' domains can also modify the residual + equations of their immediate neighbors, but only at the nearest + grid point. Every standard domain must be attached to a connector + at both ends. Connectors also serve to terminate the ends of the + chain. + + """ + + _timeint_options = ['ftime', 'min_timestep', 'max_timestep', + 'nsteps', 'timestep', 'ts_jac_age'] + _newton_options = ['max_jac_age', 'rtol', 'atol'] + _output_options = ['loglevel', 'plotfile'] + + _options = _newton_options + _timeint_options + _output_options + + + def __init__(self, domains): + self._size = [] + self._start = [] + self._end = [] + self._domain = [] + self._flow = [] + self._shape = [] + self._loc = 0 + self._opt = {} + self.time = 0.0 + self.x = array([0.0,],'d') + self._surf = [] + dtype = [] + dlist = [] + self.npts = [] + for d in domains: + if d.domainType == 0: + self.addFlow(d) + dtype.append(0) + dlist.append(d.flow_id()) + self.npts.append(d.nPoints()) + elif d.domainType == 1: + self.addSurface(d) + dtype.append(1) + dlist.append(d.surf_id()) + self.npts.append(1) + elif d.domainType == 2: + self.addBoundary(d) + dtype.append(2) + dlist.append(d.bndry_id()) + self.npts.append(1) + else: + raise 'unknown domain type' + self.__onedim_id = _cantera.onedim_new(len(dlist), + array(dlist,'i'), + array(dtype,'i')) + self.collect() + self.restoreDefaults(); + self.ienergy = 0 + self.ts_jac_age = 50 + + def __del__(self): + _cantera.onedim_del(self.__onedim_id) + + def addFlow(self, flow): + + self._domain.append(flow) + self._flow.append(flow) + flow.index = len(self._domain) - 1 + + np, nv = flow.shape() + self._shape.append((np,nv)) + self._size.append(np*nv) + self._start.append(self._loc) + self._loc += np*nv + self._end.append(self._loc) + + + def index(self, n, j, i): + np, nv = self._shape[i] + return self._start[n] + nv*j + i + + +## def resetEnergy(self): +## i = 0 +## ilast = self.ienergy +## for f in self._flow: +## i += f.resetEnergy() +## self.ienergy = 0 +## return 0# ilast + + + def finish(self): + """ + Update the solution in each domain based on the global solution. + + This method is called by function 'solve' when a converged + solution has been found, just prior to grid refinement. + """ + for i in range(len(self._domain)): + self._domain[i].x = self.solution(i) + + def solution(self, i): + """ Return the solution array for domain i. + + The returned array has the shape (points, + components) appropriate for domain i. """ + + x = self.x[self._start[i]:self._end[i]] + dx = reshape(x, self._domain[i].shape()) + return dx + + + def resid(self, i): + """ + The residual matrix for domain i. + + The returned array has the shape + (points, components) appropriate for domain i. + """ + self.ssnorm() + x = self.xnew[self._start[i]:self._end[i]] + dx = reshape(x, self._domain[i].shape()) + return dx + + + def addSurface(self, surf): + """Add a surface domain.""" + self._surf.append(surf) + self._domain.append(surf) + surf.index = len(self._domain) - 1 + nv = surf.kin.nSpecies() + np = 1 + self._shape.append((np,nv)) + self._size.append(np*nv) + self._start.append(self._loc) + self._loc += np*nv + self._end.append(self._loc) + + def addBoundary(self, b): + """Add a boundary domain.""" + #self._surf.append(surf) + self._domain.append(b) + b.index = len(self._domain) - 1 + nv = 2 # surf.kin.nSpecies() + np = 1 + self._shape.append((np,nv)) + self._size.append(np*nv) + self._start.append(self._loc) + self._loc += np*nv + self._end.append(self._loc) + + + def setNewtonOptions(self, max_jac_age = 5): + _cantera.onedim_setnewtonoptions(self.__onedim_id, max_jac_age) + + + def newton_solve(self, loglevel = 0): + """Damped Newton iteration. + + This method invokes C++ method 'solve' of kernel class + 'OneDim' on the current solution. The solution is only + modified if the damped Newton process leads to a fully + converged solution. Otherwise, an exception is raised. + """ + + iok = _cantera.onedim_solve(self.__onedim_id, self.x, + self.xnew, loglevel) + if loglevel > 0: print _cantera.readlog() + if iok >= 0: + _cantera.copy(size(self.x),self.xnew,self.x) + elif iok > -10: + raise CanteraError() + else: + raise 'iok = '+`iok` + return iok + + + + def collect(self): + """Collect the state information from each domain to + construct the global solution vector.""" + n = 0 + strt = [] # list of start locations for each domain + self.npts = [] + nd = len(self._domain) + for d in self._domain: + strt.append(n) + n += size(d.x) + self.npts.append(d.shape()[0]) + strt.append(n) + + self.x = zeros(n,'d') + self.xnew = zeros(n,'d') + + # set the portion of the global solution vector corresponding + # to each domain to the flattened solution matrix for that + # domain + for i in range(nd): + self.x[strt[i]:strt[i+1]] = reshape(self._domain[i].x,(-1,)) + + + def ssnorm(self): + """Max norm of the steady-state residual.""" + n = _cantera.onedim_ssnorm(self.__onedim_id, self.x, self.xnew) + return n + + + def setSteadyMode(self): + """Prepare to solve the steady-state problem.""" + return _cantera.onedim_setsteadymode(self.__onedim_id) + + + def setTransientMode(self, dt): + """Prepare for time-stepping with timestep dt. + + Must be called before each step.""" + return _cantera.onedim_settransientmode(self.__onedim_id, dt, self.x) + + + def option(self, key): + """Return the value of an option.""" + return self._opt[key] + + + def restoreDefaults(self): + """Restore default options.""" + self._opt = {} + self.setOptions( + max_jac_age = 20, + timestep = 1.e-6, + min_timestep = 1.e-12, + max_timestep = 0.1, + nsteps = [1,2,4,8,20], + ftime = 3.0, + plotfile = "" + ) + + + def setOptions(self, **options): + """ + Set options. + + Time stepping: + nsteps -- number of steps. + min_timestep -- minimum timestep + max_timestep -- maximum timestep + ftime -- factor by which to increase the timestep for next + set of 'nsteps' timesteps + + Newton solver: + max_jac_age -- maximum number of times Jacobian will be used + before re-evaluating + rtol -- relative error tolerance + atol -- absolute error tolerance + + Output: + loglevel -- controls amount of diagnostic output + plotfile -- file to write plot data for intermediate solutions + + """ + for kw in options.keys(): + if kw in OneDim._options: + self._opt[kw] = options[kw] + else: + raise OptionError(kw) + if kw in OneDim._newton_options: + self.setNewtonOptions(max_jac_age = + self._opt['max_jac_age']) + + + def refine(self, loglevel = 2): + """Refine the grid of every flow domain.""" + new_points = 0 + for f in self._flow: + new_points += f.refine(loglevel) + if new_points > 0: + self.collect() + _cantera.onedim_resize(self.__onedim_id) + self._shape = [] + self._size = [] + self._start = [] + self._end = [] + self._loc = 0 + for d in self._domain: + np, nv = d.shape() + self._shape.append((np, nv)) + self._size.append(np*nv) + self._start.append(self._loc) + self._loc += np*nv + self._end.append(self._loc) + return new_points + + def setEnergyFactor(self, e): + for f in self._flow: + f.setEnergyFactor(e) + + def restore(self, n, file, soln, loglevel = 2): + """Read the solution for domain n from a file.""" + self._domain[n].restore(file, soln) + self.collect() + _cantera.onedim_resize(self.__onedim_id) + self._shape = [] + self._size = [] + self._start = [] + self._end = [] + self._loc = 0 + for d in self._domain: + np, nv = d.shape() + self._shape.append((np, nv)) + self._size.append(np*nv) + self._start.append(self._loc) + self._loc += np*nv + self._end.append(self._loc) + + + def c_timeStep(self, nsteps, dt, loglevel = 0): + dtnew = _cantera.onedim_timestep(self.__onedim_id, nsteps, dt, + self.x, self.xnew, loglevel) + print _cantera.readlog() + return dtnew + + + def py_timeStep(self, nsteps, dt, loglevel = 0): + """Take time steps using Backward Euler. + + nsteps -- number of steps + dt -- initial step size + loglevel -- controls amount of printed diagnostics + """ + + self.setNewtonOptions(max_jac_age = self.ts_jac_age) + + if loglevel > 0: + print_heading('Begin time integration.\n\n') + print(' step size (s) log10(ss) ') + print('===============================') + + n = 0 + maxdt = self._opt['max_timestep'] + while n < nsteps: + if loglevel > 0: + ss = self.ssnorm() + str = ' %4d %10.4g %10.4g' % (n,dt,math.log10(ss)) + print str, + try: + self.setTransientMode(dt) + m = self.newton_solve(loglevel-1) + self.time += dt + n += 1 + if m == 100: dt *= 1.5 + #if m > 0: dt *= 1.5 + if dt > maxdt: dt = maxdt + if loglevel > 0: print + + except CanteraError: + #print self.resid(1)[:,0] + if loglevel > 0: print '...failure.' + dt *= 0.5 + if dt < 1.e-16: + self._domain[0].show() + raise CanteraError('Time integration failed.') + + self.setSteadyMode() + self.setNewtonOptions(max_jac_age = + self._opt['max_jac_age']) + return dt + + def show(self): + for d in self._domain: + d.show() + + + def showStatistics(self): + _cantera.onedim_writestats(self.__onedim_id) + print _cantera.readlog() + + + def save(self, filename, id, desc=""): + """Save a solution to a file. + + filename -- file name. If the file, does not exist, it will + be created. The save files are xml files, and the + filename should have the extension '.xml'. If it + does not, this extension will be appended to the + name. + + id -- the ID tag of the solution. Multiple solutions may + be saved to the same file. Specifying a unique ID + tag allows this solution to selected later by + method 'restore'. + + """ + fn = filename + extn = filename[-4:] + if extn <> '.xml' and extn <> '.XML': + fn = filename + '.xml' + + _cantera.onedim_save(self.__onedim_id, fn, id, desc, self.x) + print _cantera.readlog() + + diff --git a/Cantera/python/Cantera/Phase.py b/Cantera/python/Cantera/Phase.py new file mode 100755 index 000000000..63e23efd3 --- /dev/null +++ b/Cantera/python/Cantera/Phase.py @@ -0,0 +1,240 @@ +"""Cantera.Phase + +This module provides class Phase. + +""" + +import _cantera + +import types +import Numeric +from exceptions import CanteraError + +__revision__ = "$Id$" + +class Phase: + + """Class Phase manages basic state and constituent property + information for a homogeneous phase of matter. It does not contain + information on the equation of state, homogeneous kinetics, or + transport properties -- these attributes of the phase are the + responsibility of other classes (see the ThermoPhase, Kinetics, and + Transport classes). + + In the C++ kernel, class Phase is only a base class for + ThermoPhase. This structure is maintained in the Python wrapper + class. Class Phase implements methods of the C++ Phase class, but + the instance is actually a 'ThermoPhase' object. Also, in C++ + class Phase is itself derived from more elementary classes (State + and Constituents), but these are not exposed in Python. + + """ + + def __init__(self, index = -1): + pass + + def phase_id(self): + return self._phase_id + +## def addElement(self, symbol, atomicWeight): +## """Add an element.""" +## _cantera.phase_addelement(self._phase_id,symbol,atomicWeight) + +## def addSpecies(self, name, atoms = [], +## thermoType = 'poly', +## thermoCoeffs = []): +## _cantera.phase_addSpecies(self._phase_id, name, array(atoms,'d'), +## thermoType, array(thermoCoeffs,'d'), +## minTemp, maxTemp, refPressure) + + def nElements(self): + """Number of elements.""" + return _cantera.phase_nelements(self._phase_id) + + def atomicWeights(self): + """Array of element molar masses [kg/kmol].""" + return _cantera.phase_getarray(self._phase_id,1) + + def nSpecies(self): + """Number of species.""" + return _cantera.phase_nspecies(self._phase_id) + + def nAtoms(self, species = -1, element = -1): + """Number of atoms of element 'element' in species 'species'. + + The element and species may be specified by name or by number.""" + try: + m = self.elementIndex(element) + k = self.speciesIndex(species) + na = _cantera.phase_natoms(self._phase_id, k, m) + if na < 0: return 0 + return na + except CanteraError: + return 0 + + def temperature(self): + """Temperature [K].""" + return _cantera.phase_temperature(self._phase_id) + + def density(self): + """Mass density [kg/m^3].""" + return _cantera.phase_density(self._phase_id) + + def volume_mass(self): + """Specific volume [m^3/kg].""" + return 1.0/_cantera.phase_density(self._phase_id) + + def molarDensity(self): + """Molar density [kmol/m^3].""" + return _cantera.phase_molardensity(self._phase_id) + + def meanMolecularWeight(self): + """Mean molar mass [kg/kmol]. + DEPRECATED: use meanMolarMass""" + return _cantera.phase_meanmolwt(self._phase_id) + + def meanMolarMass(self): + """Mean molar mass [kg/kmol].""" + return _cantera.phase_meanmolwt(self._phase_id) + + def molecularWeights(self): + """Array of species molar masses [kg/kmol]. + DEPRECATED: use molarMasses""" + return _cantera.phase_getarray(self._phase_id,22) + + def molarMasses(self): + """Array of species molar masses [kg/kmol].""" + return _cantera.phase_getarray(self._phase_id,22) + + def moleFractions(self): + """Species mole fraction array.""" + return _cantera.phase_getarray(self._phase_id,20) + + def moleFraction(self, species=-1): + """Mole fraction of a species, referenced by name or + index number. + >>> ph.moleFraction(4) + >>> ph.moleFraction('CH4') + """ + k = self.speciesIndex(species) + return _cantera.phase_molefraction(self._phase_id,k) + + def massFractions(self): + """Species mass fraction array.""" + return _cantera.phase_getarray(self._phase_id,21) + + def massFraction(self, species=-1): + """Mass fraction of one or more species, referenced by name or + index number. + >>> ph.massFraction(4) + >>> ph.massFraction('CH4') + """ + k = self.speciesIndex(species) + return _cantera.phase_massfraction(self._phase_id,k) + + + def elementName(self,m): + """Name of element m.""" + return _cantera.phase_getstring(self._phase_id,1,m) + + def elementNames(self): + """Return a tuple of all element names.""" + nel = self.nElements() + return map(self.elementName,range(nel)) + + def elementIndex(self, element=-1): + """The index of element 'element', which may be specified as + a string or an integer index. In the latter case, the index is + checked for validity and returned. If no such element is + present, an exception is thrown.""" + + nel = self.nElements() + if type(element) == types.IntType: + m = element + else: + m = _cantera.phase_elementindex(self._phase_id, element) + if m < 0 or m >= nel: + raise CanteraError("""Element """+element+""" not in set """ + +`self.elementNames()`) + return m + + + + def speciesName(self,k): + """Name of the species with index k.""" + return _cantera.phase_getstring(self._phase_id,2,k) + + + def speciesNames(self): + """Return a tuple of all species names.""" + nsp = self.nSpecies() + return map(self.speciesName,range(nsp)) + + + def speciesIndex(self, species=-1): + """The index of species 'species', which may be specified as + a string or an integer index. In the latter case, the index is + checked for validity and returned. If no such species is + present, an exception is thrown.""" + nsp = self.nSpecies() + if type(species) == types.IntType or type(species) == types.FloatType: + k = species + else: + k = _cantera.phase_speciesindex(self._phase_id,species) + if k < 0 or k >= nsp: + raise CanteraError("""Species """+`species`+""" not in set """ + +`self.speciesNames()`) + return k + + + def setTemperature(self, t): + """Set the temperature [K].""" + _cantera.phase_setfp(self._phase_id,1,t) + + def setDensity(self, rho): + """Set the density [kg/m3].""" + _cantera.phase_setfp(self._phase_id,2,rho) + + def setMoleFractions(self, x, norm = 1): + """Set the mole fractions. The values may be input either + in a string or a sequence. + >>> ph.setMoleFractions('CO:1, H2:7, H2O:7.8') + >>> x = [1.0]*ph.nSpecies() + >>> ph.setMoleFractions(x) + By default, the input values will be scaled to sum to 1.0. + If this is not desired, supply a third parameter 'norm' set to zero + >>> ph.setMoleFractions(x, norm = 0) + (Note that this only works if an array is input.) + """ + if type(x) == types.StringType: + _cantera.phase_setstring(self._phase_id,1,x) + else: + _cantera.phase_setarray(self._phase_id,1,norm,Numeric.asarray(x)) + + + def setMassFractions(self, x, norm = 1): + """Set the mass fractions. + See also: setMoleFractions + """ + if type(x) == types.StringType: + _cantera.phase_setstring(self._phase_id,2,x) + else: + _cantera.phase_setarray(self._phase_id,2,norm,x) + + def setState_TRX(self, t, rho, x): + """Set the temperature, density, and mole fractions.""" + self.setTemperature(t) + self.setMoleFractions(x) + self.setDensity(rho) + + def setState_TRY(self, t, rho, y): + """Set the temperature, density, and mass fractions.""" + self.setTemperature(t) + self.setMassFractions(x) + self.setDensity(rho) + + def setState_TR(self, t, rho): + """Set the temperature and density.""" + self.setTemperature(t) + self.setDensity(rho) + diff --git a/Cantera/python/Cantera/Reactor.py b/Cantera/python/Cantera/Reactor.py new file mode 100644 index 000000000..7f6871151 --- /dev/null +++ b/Cantera/python/Cantera/Reactor.py @@ -0,0 +1,378 @@ +""" +Zero-dimensional reactors. More text. + +""" + +import _cantera +from Numeric import array, zeros +import types + +class ReactorBase: + """Base class for reactors.""" + + + def __init__(self, contents = None, type = -1): + """ + Create a new ReactorBase instance. If 'contents' is specified, + method 'insert' is invoked. The 'type' parameter determines + the type of C++ Reactor object that is instantiated (1 = Reactor, + 2 = Reservoir). + """ + self.__reactor_id = _cantera.reactor_new(type) + if contents: + self.insert(contents) + + + def __del__(self): + """Delete the reactor instance.""" + _cantera.reactor_del(self.__reactor_id) + + + def reactor_id(self): + """ + The integer index used to access the kernel reactor object. + """ + return self.__reactor_id + + + def insert(self, contents): + """ + Insert 'contents' into the reactor. Sets the objects used to compute + thermodynamic properties and kinetic rates. + """ + self.contents = contents + self.setThermoMgr(contents) + self.setKineticsMgr(contents) + + def setInitialTime(self, t0): + """Set the initial time. Restarts integration from this time + using the current state as the initial condition. Default: 0.0 s""" + _cantera.reactor_setInitialTime(self.__reactor_id, t0) + + def setInitialVolume(self, t0): + """Set the initial reactor volume. Default: 1.0 m^3.""" + _cantera.reactor_setInitialVolume(self.__reactor_id, t0) + + def setEnergy(self, e): + ie = 1 + if e == 'off': + ie = 0 + _cantera.reactor_setEnergy(self.__reactor_id, ie) + + def temperature(self): + """Temperature [K].""" + return _cantera.reactor_temperature(self.__reactor_id) + + def density(self): + """Density [kg/m^3].""" + return _cantera.reactor_density(self.__reactor_id) + + def volume(self): + """Reactor volume [m^3].""" + return _cantera.reactor_volume(self.__reactor_id) + + def time(self): + """Time [s]. The reactor time is set by method advance.""" + return _cantera.reactor_time(self.__reactor_id) + + def mass(self): + """The total mass of the reactor contents [kg].""" + return _cantera.reactor_mass(self.__reactor_id) + + def enthalpy_mass(self): + """The specific enthalpy [J/kg].""" + return _cantera.reactor_enthalpy_mass(self.__reactor_id) + + def intEnergy_mass(self): + """The specific interhal energy [J/kg].""" + return _cantera.reactor_intEnergy_mass(self.__reactor_id) + + def pressure(self): + """The pressure [Pa].""" + return _cantera.reactor_pressure(self.__reactor_id) + + def advance(self, time): + """Advance the state of the reactor in time from the current + time to time 'time'.""" + return _cantera.reactor_advance(self.__reactor_id, time) + + def step(self, time): + """Advance the state of the reactor in time from the current + time to time 'time'.""" + return _cantera.reactor_step(self.__reactor_id, time) + + def setThermoMgr(self, th): + _cantera.reactor_setThermoMgr(self.__reactor_id, th._phase_id) + + def setKineticsMgr(self, kin): + _cantera.reactor_setKineticsMgr(self.__reactor_id, kin.ckin) + #self.setThermoMgr(kin.thrm) + + def massFraction(self, k): + """Mass fraction of species k.""" + if type(k) == types.StringType: + kk = self.contents.speciesIndex(k) + else: + kk = k + return _cantera.reactor_massFraction(self.__reactor_id, kk) + + def massFractions(self): + nsp = self.contents.nSpecies() + y = zeros(nsp,'d') + for k in range(nsp): + y[k] = self.massFraction(k) + return y + + def moleFractions(self): + y = self.massFractions() + self.contents.setMassFractions(y) + return self.contents.moleFractions() + + + +class Reactor(ReactorBase): + """ + A reactor. + """ + def __init__(self, contents = None): + """ + Create a Reactor instance, and if 'contents' is specified, + insert it. + """ + ReactorBase.__init__(self, contents = contents, type = 1) + + +class Reservoir(ReactorBase): + """ + A reservoir is a reactor with a constant state. Class Reservoir + derives from class ReactorBase, and overloads method advance to do + nothing. + """ + def __init__(self, contents = None): + ReactorBase.__init__(self, contents = contents, type = 2) + + def advance(self, time): + """Do nothing.""" + pass + + + +#------------------ FlowDevice --------------------------------- + +class FlowDevice: + """ + Base class for devices that regulate the flow rate in a fluid line. + """ + def __init__(self, type): + """ + Create a new instance of type 'type' + """ + self.__fdev_id = _cantera.flowdev_new(type) + + def __del__(self): + """ + Delete the instance. + """ + _cantera.flowdev_del(self.__fdev_id) + + def ready(self): + """ + Returns true if the device is ready to use. + """ + return _cantera.flowdev_ready(self.__fdev_id) + + def massFlowRate(self): + """ + Mass flow rate (kg/s). + """ + return _cantera.flowdev_massFlowRate(self.__fdev_id) + + def setSetpoint(self, v): + """ + Set the set point. + """ + _cantera.flowdev_setSetpoint(self.__fdev_id, v) + + def setpoint(self): + """ + The setpoint value. + """ + return _cantera.flowdev_setpoint(self.__fdev_id) + +## def reset(self): +## """ +## Reset the flow controller. Only necessary for pressure regulators. +## """ +## _cantera.flowdev_reset(self.__fdev_id) + + def install(self, upstream, downstream): + """ + Install the device between the upstream and downstream + reactors. + """ + _cantera.flowdev_install(self.__fdev_id, upstream.reactor_id(), + downstream.reactor_id()) +## self.reset() + +## def setGains(self, gains): +## g = array(gains,'d') +## n = len(g) +## _cantera.flowdev_setGains(self.__fdev_id, n, g) + +## def getGains(self): +## n = 4 +## return _cantera.flowdev_getGains(self.__fdev_id, n) + + def setParameters(self, c): + params = array(c,'d') + n = len(params) + return _cantera.flowdev_setParameters(self.__fdev_id, n, params) + +## def maxError(self): +## return _cantera.flowdev_maxError(self.__fdev_id) + +## def update(self): +## _cantera.flowdev_update(self.__fdev_id) + + +class MassFlowController(FlowDevice): + def __init__(self, upstream=None, downstream=None): + FlowDevice.__init__(self,1) + if upstream and downstream: + self.install(upstream, downstream) + + def setMassFlowRate(self, mdot): + self.setSetpoint(mdot) + + +## class PressureRegulator(FlowDevice): +## def __init__(self, upstream=None, downstream=None): +## FlowDevice.__init__(self,2) +## if upstream and downstream: +## self.install(upstream, downstream) + +## def setPressure(self, p): +## self.setSetpoint(p) + + +class Valve(FlowDevice): + def __init__(self, upstream=None, downstream=None): + FlowDevice.__init__(self,3) + if upstream and downstream: + self.install(upstream, downstream) + + def setValveCoeff(self, v): + vv = zeros(1,'d') + vv[0] = v + self.setParameters(vv) + + +#------------- Wall --------------------------- + +class Wall: + """ + A Wall separates two reactors. Any number of walls may be created + between any pair of reactors. + """ + def __init__(self, left=None, right=None, area=1.0): + typ = 0 + self.__wall_id = _cantera.wall_new(typ) + if left and right: + self.install(left, right) + self.setArea(area) + self.setExpansionRateCoeff(0.0) + self.setExpansionRate() + self.setHeatFlux() + + def __del__(self): + """ + Delete the Wall instance. + """ + _cantera.wall_del(self.__wall_id) + + def ready(self): + """ + Return 1 if the wall instance is ready for use, 0 otherwise. + """ + return _cantera.wall_ready(self.__wall_id) + + def area(self): + """ + The wall area (m^2). + """ + return _cantera.wall_area(self.__wall_id) + + def setArea(self, a): + """ + Set the area (m^2). + """ + _cantera.wall_setArea(self.__wall_id, a) + + def setThermalResistance(self, rth): + """Deprecated.""" + return _cantera.wall_setThermalResistance(self.__wall_id, rth) + + def setHeatTransferCoeff(self, u): + """ + Set the overall heat transfer coefficient [W/m^2/K] + """ + return _cantera.wall_setHeatTransferCoeff(self.__wall_id, u) + + def setHeatFlux(self, qfunc=None): + """ + Specify the time-dependent heat flux function [W/m2]. + 'qfunc' must be a functor. + """ + n = 0 + if qfunc: n = qfunc.func_id() + return _cantera.wall_setHeatFlux(self.__wall_id, n) + + def setExpansionRateCoeff(self, k): + _cantera.wall_setExpansionRateCoeff(self.__wall_id, k) + + def setExpansionRate(self, vfunc=None): + """ + Specify the volumetric expansion rate function [m^3/s]. + """ + n = 0 + if vfunc: n = vfunc.func_id() + _cantera.wall_setExpansionRate(self.__wall_id, n) + + def install(self, left, right): + self.left = left + self.right = right + _cantera.wall_install(self.__wall_id, left.reactor_id(), + right.reactor_id()) + + def set(self, **p): + for item in p.keys(): + if item == 'A' or item == 'area': + self.setArea(p[item]) + elif item == 'R': + self.setThermalResistance(p[item]) + elif item == 'U': + self.setHeatTransferCoeff(p[item]) + elif item == 'K': + self.setExpansionRateCoeff(p[item]) + elif item == 'Q': + self.setHeatFlux(p[item]) + elif item == 'Vdot': + self.setExpansionRate(p[item]) + else: + raise 'unknown parameter: ',item + + + + + + + + + + + + + + + + diff --git a/Cantera/python/Cantera/SurfWriter.py b/Cantera/python/Cantera/SurfWriter.py new file mode 100755 index 000000000..f6f458d29 --- /dev/null +++ b/Cantera/python/Cantera/SurfWriter.py @@ -0,0 +1,180 @@ +""" +Write C functions implementing a surface reaction mechanism. +NOT CURRENTLY FUNCTIONAL +""" + +from Cantera import CanteraError +from Cantera import units +from Numeric import array +from Cantera import constants +import math +import types + +hdr = """ +/* + +The identity of the species in each phase is as listed below. +""" + +ropheader = """ + + /* + Get the reaction rates of progress given the concentrations. + + conc --- concentrations in kmol/m^3 or kmol/m^2. Array c + must be dimensioned at least KB1 + KB2 + KS. The first + KB1 entries are the concentrations of species in bulk phase 1, + the next KB2 entries are the concentrations of species in bulk + phase 2, and the final KS entries are the concentrations of the + surface species. + + ropf --- rates of progress of the surface reactions in kmol/m^2/s. + Must be dimensioned at least NSR, the number of surface reactions. + + */ + + void get_rop(double* c, double* kf, double* ropf) { +""" + +sdotheader = """ + + void get_sdot(double* r, double* sdot) { +""" + +rateheader = """ + + /* get the forward reaction rates */ + void get_kf(double T, double* kf) { + double logT = log(T); + double rt = 1.0/T; +""" + +finaltxt = """ + } + """ + +class SurfWriter: + + def __init__(self, iface, mechname): + self.bulk1 = iface.p1 + self.bulk2 = iface.p2 + self.surf = iface + self.sp = {} + self.f = open(mechname+'.c', 'w') + self.write_top() + self.f.write('\n#ifdef __cplusplus\nextern "C" {\n#endif') + self.rop = ropheader + self.rate = rateheader + self.nrxns = 0 + self.sdot = {} + + def write(self): + self.f.write(self.rop) + self.f.write(' }\n\n') + self.f.write(sdotheader) + for k in self.sdot.keys(): + self.f.write('\n /* '+self.sp[k]+' */\n') + self.f.write(' sdot['+`k`+'] = '+self.sdot[k]+';\n') + self.f.write(' }\n\n') + self.f.write(self.rate) + self.f.write(' }\n') + self.f.write('#ifdef __cplusplus\n}\n#endif\n') + self.f.close() + + def write_top(self): + self.f.write(hdr) + n1 = self.bulk1.nSpecies() + self.f.write('Bulk phase 1 species: '+`n1`+' total.\n') + + sp = self.bulk1.speciesNames() + i = 0 + k = 0 + for s in sp: + self.f.write('%3d %s\n' % (i, s)) + i += 1 + self.sp[k] = s + k += 1 + self.f.write('\n\n') + + if self.bulk2: + n2 = self.bulk2.nSpecies() + self.f.write('Bulk phase 2 species: '+`n2`+' total.\n') + + sp = self.bulk2.speciesNames() + i = 0 + for s in sp: + self.f.write('%3d %s\n' % (i, s)) + i += 1 + self.sp[k] = s + k += 1 + self.f.write('\n\n') + + else: + self.f.write('No second bulk phase.\n\n') + + ns = self.surf.nSpecies() + self.f.write('Surface species: '+`ns`+' total.\n') + sp = self.surf.speciesNames() + i = 0 + for s in sp: + self.f.write('%3d %s\n' % (i, s)) + i += 1 + self.sp[k] = s + k += 1 + self.f.write('\n\n*/') + + self.f.write('\n\n') + + + def write_update_rate(self, rate): + i = self.nrxns + self.rate += ' kf['+`i`+'] = '+'%17.10e' % (rate[0],) + if rate[1] == 0.0 and rate[2] == 0.0: + self.rate += ';\n' + return + self.rate += ' * exp(' + if rate[1] <> 0.0: + self.rate += '%f * logT' % (rate[1],) + if rate[2] <> 0.0: + self.rate += '- %f * rt' % (rate[2],) + self.rate += ');\n' + + + def write_ROP(self, rindex, rstoich, rorder, + pindex, pstoich, rate): + f = '' + i = self.nrxns + f += ' ropf['+`i`+'] = kf['+`i`+']*' + nr = len(rindex) + for n in range(nr): + k = rindex[n] + if rorder[n] == rstoich[n]: + for j in range(rstoich[n]): + f +='c['+`k`+']*' + else: + f += 'pow(c['+`k`+'], '+`rorder[n]`+')*' + f = f[:-1]+';\n' + self.rop += f + + def write_sdot(self, rindex, rstoich, pindex, pstoich): + i = self.nrxns + nr = len(rindex) + for n in range(nr): + k = rindex[n] + if rstoich[n] == 1: st = '' + else: st = `rstoich[n]`+'*' + if not self.sdot.has_key(k): + self.sdot[k] = ' -'+st+'r['+`i`+']' + else: + self.sdot[k] += ' - '+st+'r['+`i`+']' + + np = len(pindex) + for n in range(np): + k = pindex[n] + if pstoich[n] == 1: st = '' + else: st = `pstoich[n]`+'*' + if not self.sdot.has_key(k): + self.sdot[k] = st+'r['+`i`+']' + else: + self.sdot[k] += ' + '+st+'r['+`i`+']' + diff --git a/Cantera/python/Cantera/SurfacePhase.py b/Cantera/python/Cantera/SurfacePhase.py new file mode 100644 index 000000000..aed3669e7 --- /dev/null +++ b/Cantera/python/Cantera/SurfacePhase.py @@ -0,0 +1,38 @@ + +from ThermoPhase import ThermoPhase +from exceptions import CanteraError +import Numeric +import _cantera + +class SurfacePhase(ThermoPhase): + """A class for surface phases.""" + + def __init__(self, xml_phase=None, index=-1): + ThermoPhase.__init__(self, xml_phase=xml_phase, index=index) + + def setSiteDensity(self, n0): + _cantera.surf_setsitedensity(self._phase_id, n0) + + def siteDensity(self): + return _cantera.surf_sitedensity(self._phase_id) + + def setCoverages(self, theta): + nt = len(theta) + if nt == self.nSpecies(): + _cantera.surf_setcoverages(self._phase_id, + Numeric.asarray(theta,'d')) + else: + raise CanteraError('expected '+`self.nSpecies()`+ + ' coverage values, but got '+`nt`) + + def coverages(self): + return _cantera.surf_getcoverages(self._phase_id) + + def setConcentrations(self, theta): + _cantera.surf_setconcentrations(self._phase_id, theta) + + def concentrations(self): + return _cantera.surf_getconcentrations(self._phase_id) + + + diff --git a/Cantera/python/Cantera/Thermo.py b/Cantera/python/Cantera/Thermo.py new file mode 100755 index 000000000..3859ddd84 --- /dev/null +++ b/Cantera/python/Cantera/Thermo.py @@ -0,0 +1,227 @@ +""" +Module Thermo +""" + +DEPRECATED + + +from Cantera.Phase import Phase + +import ctthermo +import ctphase +import types + +def thermoIndex(id): + return ctthermo.thermoIndex(id) + +class Thermo: + + _equilmap = {'TP':104,'TV':100,'HP':101,'SP':102,'SV':107,'UV':105, + 'PT':104,'VT':100,'PH':101,'PS':102,'VS':107,'VU':105} + + def __init__(self, eostype=1, phase=None, sptherm=0, + root=None, id=None, index=-1): + self.__phase = None + self.cthermo = None + self._owner = 1 + self.idtag = "" + + #if thermoIndex(id) > 0: + # index = thermoIndex(id) + + if index >= 0: + # create a Python wrapper for an existing kernel + # Thermo instance + self.cthermo = index + self.__phase = Phase(index = ctthermo.phase(index)) + self._owner = 0 + + elif root: + # create a new kernel instance from an XML specification + self.cthermo, ph = ctthermo.ThermoFromXML(root._xml_id, id) + self.__phase = Phase(ph) + self.idtag = id + + else: + # create a new kernel instance with specified parameters + self.cthermo = ctthermo.Thermo(eostype, phase.phase_id(), sptherm) + self.__phase = phase + + def __del__(self): + if self._owner: + ctthermo.delete(self.cthermo) + + def importFromXML(self, xml_root, id): + ctthermo.import_xml(self.cthermo, xml_root._xml_id, id) + + def thermophase(self): + return self.__phase + + def refPressure(self): + """Reference pressure [Pa]. + All standard-state thermodynamic properties are for this pressure. + """ + return ctthermo.refpressure(self.cthermo) + + def minTemp(self, sp=-1): + """ Minimum temperature for which the parameterization of + standard-state thermodynamic properties vs. T for species 'sp' + is valid. If no species is specified, the value returned is + the maximum value of minTemp for any one species, and + therefore is the minimum temperature at which mixture + thermodynamic properties are valid.""" + return ctthermo.mintemp(self.cthermo, self.speciesIndex(sp)) + + def maxTemp(self, sp=-1): + """ Maximum temperature for which the parameterization of + standard-state thermodynamic properties vs. T for species 'sp' + is valid. If no species is specified, the value returned is + the minimum value of maxTemp for any one species, and + therefore is the maximum temperature at which mixture + thermodynamic properties are valid.""" + return ctthermo.maxtemp(self.cthermo, self.speciesIndex(sp)) + + def enthalpy_mole(self): + """ The molar enthalpy [J/kmol].""" + return ctthermo.getfp(self.cthermo,1) + + def intEnergy_mole(self): + """ The molar internal energy [J/kmol].""" + return ctthermo.getfp(self.cthermo,2) + + def entropy_mole(self): + """ The molar entropy [J/kmol/K].""" + return ctthermo.getfp(self.cthermo,3) + + def gibbs_mole(self): + """ The molar Gibbs function [J/kmol].""" + return ctthermo.getfp(self.cthermo,4) + + def cp_mole(self): + """ The molar heat capacity at constant pressure [J/kmol/K].""" + return ctthermo.getfp(self.cthermo,5) + + def cv_mole(self): + """ The molar heat capacity at constant volume [J/kmol/K].""" + return ctthermo.getfp(self.cthermo,6) + + def pressure(self): + """ The pressure [Pa].""" + return ctthermo.getfp(self.cthermo,7) + + def chemPotentials(self): + """Species chemical potentials. + + This method returns an array containing the species + chemical potentials [J/kmol]. The expressions used to + compute these depend on the model implemented by the + underlying kernel thermo manager.""" + return ctthermo.getarray(self.cthermo,20) + + def enthalpies_RT(self): + """Pure species non-dimensional enthalpies. + + This method returns an array containing the pure-species + standard-state enthalpies divided by RT. For gaseous species, + these values are ideal gas enthalpies.""" + return ctthermo.getarray(self.cthermo,23) + + def entropies_R(self): + """Pure species non-dimensional entropies. + + This method returns an array containing the pure-species + standard-state entropies divided by R. For gaseous species, + these values are ideal gas entropies.""" + return ctthermo.getarray(self.cthermo,24) + + def gibbs_RT(self): + """Pure species non-dimensional Gibbs free energies. + + This method returns an array containing the pure-species + standard-state Gibbs free energies divided by R. + For gaseous species, these are ideal gas values.""" + return (ctthermo.getarray(self.cthermo,23) + - ctthermo.getarray(self.cthermo,24)) + + def cp_R(self): + """Pure species non-dimensional heat capacities + at constant pressure. + + This method returns an array containing the pure-species + standard-state heat capacities divided by R. For gaseous + species, these values are ideal gas heat capacities.""" + return ctthermo.getarray(self.cthermo,25) + + + def setPressure(self, p): + """Set the pressure [Pa].""" + ctthermo.setfp(self.cthermo,1,p,0.0) + + def enthalpy_mass(self): + """Specific enthalpy [J/kg].""" + return ctthermo.getfp(self.cthermo,8) + + def intEnergy_mass(self): + """Specific internal energy [J/kg].""" + return ctthermo.getfp(self.cthermo,9) + + def entropy_mass(self): + """Specific entropy [J/kg/K].""" + return ctthermo.getfp(self.cthermo,10) + + def gibbs_mass(self): + """Specific Gibbs free energy [J/kg].""" + return ctthermo.getfp(self.cthermo,11) + + def cp_mass(self): + """Specific heat at constant pressure [J/kg/K].""" + return ctthermo.getfp(self.cthermo,12) + + def cv_mass(self): + """Specific heat at constant volume [J/kg/K].""" + return ctthermo.getfp(self.cthermo,13) + + def setState_HP(self, h, p): + """Set the state by specifying the specific enthalpy and + the pressure.""" + ctthermo.setfp(self.cthermo, 2, h, p) + + def setState_UV(self, u, v): + """Set the state by specifying the specific internal + energy and the specific volume.""" + ctthermo.setfp(self.cthermo, 3, u, v) + + def setState_SV(self, s, v): + """Set the state by specifying the specific entropy + and the specific volume.""" + ctthermo.setfp(self.cthermo, 4, s, v) + + def setState_SP(self, s, p): + """Set the state by specifying the specific entropy + energy and the pressure.""" + ctthermo.setfp(self.cthermo, 5, s, p) + + def equilibrate(self, XY): + """Set to a state of chemical equilibrium holding property pair + 'XY' constant. The pair is specified by a two-letter string, + which must be one of the set + ['TP','TV','HP','SP','SV','UV','PT','VT','PH','PS','VS','VU']. + If H, U, S, or V is specified, the value must be the specific + value (per unit mass). + """ + ixy = Thermo._equilmap[XY] + if ixy > 0: + ctthermo.equil(self.cthermo, ixy) + else: + raise 'invalid equilibrium option: '+XY + + + + + + + + + + + diff --git a/Cantera/python/Cantera/ThermoPhase.py b/Cantera/python/Cantera/ThermoPhase.py new file mode 100644 index 000000000..614d0079c --- /dev/null +++ b/Cantera/python/Cantera/ThermoPhase.py @@ -0,0 +1,263 @@ +""" This module implements class ThermoPhase, a class representing +thermodynamic phases. """ + +from Cantera.Phase import Phase + +import _cantera +import types + +def thermoIndex(id): + return _cantera.thermo_thermoIndex(id) + +class ThermoPhase(Phase): + + """ Class ThermoPhase may be used to represent the intensive state + of a homogeneous phase of matter, which might be a gas, liquid, or solid. + """ + + #used in the 'equilibrate' method + _equilmap = {'TP':104,'TV':100,'HP':101,'SP':102,'SV':107,'UV':105, + 'PT':104,'VT':100,'PH':101,'PS':102,'VS':107,'VU':105} + + + def __init__(self, xml_phase=None, index=-1): + """Create a new object representing a phase of matter, or wrap + an existing kernel instance.""" + + Phase.__init__(self) + self._phase_id = 0 + self._owner = 0 + self.idtag = "" + + if index >= 0: + # create a Python wrapper for an existing kernel + # ThermoPhase instance + self._phase_id = index + + elif xml_phase: + # create a new kernel instance from an XML specification + self._phase_id = _cantera.ThermoFromXML(xml_phase._xml_id) + self.idtag = xml_phase["id"] + self._owner = 1 + + else: + raise CanteraError('either xml_phase or index must be specified') + + + def __del__(self): + """Delete the object. If it is the owner of the kernel object, + this is also deleted.""" + if self._owner: + _cantera.thermo_delete(self._phase_id) + + #def importFromXML(self, xml_root, id): + # _cantera.thermo_import_xml(self._phase_id, xml_root._xml_id, id) + + def thermophase(self): + """Return the integer index that is used to + reference the kernel object.""" + return self._phase_id + + def refPressure(self): + """Reference pressure [Pa]. + All standard-state thermodynamic properties are for this pressure. + """ + return _cantera.thermo_refpressure(self._phase_id) + + def minTemp(self, sp=None): + """ Minimum temperature for which thermodynamic property fits + are valid. If a species is specified (by name or number), + then the minimum temperature is for only this + species. Otherwise it is the lowest temperature for which the + properties are valid for all species. """ + if not sp: + return _cantera.thermo_mintemp(self._phase_id, -1) + else: + return _cantera.thermo_mintemp(self._phase_id, + self.speciesIndex(sp)) + + def maxTemp(self, sp=None): + """ Maximum temperature for which thermodynamic property fits + are valid. If a species is specified (by name or number), + then the maximum temperature is for only this + species. Otherwise it is the highest temperature for which the + properties are valid for all species. """ + if not sp: + return _cantera.thermo_maxtemp(self._phase_id, -1) + else: + return _cantera.thermo_maxtemp(self._phase_id, + self.speciesIndex(sp)) + + def enthalpy_mole(self): + """ The molar enthalpy [J/kmol].""" + return _cantera.thermo_getfp(self._phase_id,1) + + def intEnergy_mole(self): + """ The molar internal energy [J/kmol].""" + return _cantera.thermo_getfp(self._phase_id,2) + + def entropy_mole(self): + """ The molar entropy [J/kmol/K].""" + return _cantera.thermo_getfp(self._phase_id,3) + + def gibbs_mole(self): + """ The molar Gibbs function [J/kmol].""" + return _cantera.thermo_getfp(self._phase_id,4) + + def cp_mole(self): + """ The molar heat capacity at constant pressure [J/kmol/K].""" + return _cantera.thermo_getfp(self._phase_id,5) + + def cv_mole(self): + """ The molar heat capacity at constant volume [J/kmol/K].""" + return _cantera.thermo_getfp(self._phase_id,6) + + def pressure(self): + """ The pressure [Pa].""" + return _cantera.thermo_getfp(self._phase_id,7) + + def chemPotentials(self): + """Species chemical potentials. + + This method returns an array containing the species + chemical potentials [J/kmol]. The expressions used to + compute these depend on the model implemented by the + underlying kernel thermo manager.""" + return _cantera.thermo_getarray(self._phase_id,20) + + def enthalpies_RT(self): + """Pure species non-dimensional enthalpies. + + This method returns an array containing the pure-species + standard-state enthalpies divided by RT. For gaseous species, + these values are ideal gas enthalpies.""" + return _cantera.thermo_getarray(self._phase_id,23) + + def entropies_R(self): + """Pure species non-dimensional entropies. + + This method returns an array containing the pure-species + standard-state entropies divided by R. For gaseous species, + these values are ideal gas entropies.""" + return _cantera.thermo_getarray(self._phase_id,24) + + def gibbs_RT(self): + """Pure species non-dimensional Gibbs free energies. + + This method returns an array containing the pure-species + standard-state Gibbs free energies divided by R. + For gaseous species, these are ideal gas values.""" + return (_cantera.thermo_getarray(self._phase_id,23) + - _cantera.thermo_getarray(self._phase_id,24)) + + def cp_R(self): + """Pure species non-dimensional heat capacities + at constant pressure. + + This method returns an array containing the pure-species + standard-state heat capacities divided by R. For gaseous + species, these values are ideal gas heat capacities.""" + return _cantera.thermo_getarray(self._phase_id,25) + + + def setPressure(self, p): + """Set the pressure [Pa].""" + _cantera.thermo_setfp(self._phase_id,1,p,0.0) + + def enthalpy_mass(self): + """Specific enthalpy [J/kg].""" + return _cantera.thermo_getfp(self._phase_id,8) + + def intEnergy_mass(self): + """Specific internal energy [J/kg].""" + return _cantera.thermo_getfp(self._phase_id,9) + + def entropy_mass(self): + """Specific entropy [J/kg/K].""" + return _cantera.thermo_getfp(self._phase_id,10) + + def gibbs_mass(self): + """Specific Gibbs free energy [J/kg].""" + return _cantera.thermo_getfp(self._phase_id,11) + + def cp_mass(self): + """Specific heat at constant pressure [J/kg/K].""" + return _cantera.thermo_getfp(self._phase_id,12) + + def cv_mass(self): + """Specific heat at constant volume [J/kg/K].""" + return _cantera.thermo_getfp(self._phase_id,13) + + def setState_TPX(self, t, p, x): + """Set the temperature [K], pressure [Pa], and + mole fractions.""" + self.setTemperature(t) + self.setMoleFractions(x) + self.setPressure(p) + + def setState_TPY(self, t, p, y): + """Set the temperature [K], pressure [Pa], and + mass fractions.""" + self.setTemperature(t) + self.setMassFractions(y) + self.setPressure(p) + + def setState_TP(self, t, p): + """Set the temperature [K] and pressure [Pa].""" + self.setTemperature(t) + self.setPressure(p) + + def setState_PX(self, p, x): + """Set the pressure [Pa], and mole fractions.""" + self.setMoleFractions(x) + self.setPressure(p) + + def setState_PY(self, p, y): + """Set the pressure [Pa], and mass fractions.""" + self.setMassFractions(y) + self.setPressure(p) + + def setState_HP(self, h, p): + """Set the state by specifying the specific enthalpy and + the pressure.""" + _cantera.thermo_setfp(self._phase_id, 2, h, p) + + def setState_UV(self, u, v): + """Set the state by specifying the specific internal + energy and the specific volume.""" + _cantera.thermo_setfp(self._phase_id, 3, u, v) + + def setState_SV(self, s, v): + """Set the state by specifying the specific entropy + and the specific volume.""" + _cantera.thermo_setfp(self._phase_id, 4, s, v) + + def setState_SP(self, s, p): + """Set the state by specifying the specific entropy + energy and the pressure.""" + _cantera.thermo_setfp(self._phase_id, 5, s, p) + + def equilibrate(self, XY): + """Set to a state of chemical equilibrium holding property pair + 'XY' constant. The pair is specified by a two-letter string, + which must be one of the set + ['TP','TV','HP','SP','SV','UV','PT','VT','PH','PS','VS','VU']. + If H, U, S, or V is specified, the value must be the specific + value (per unit mass). + """ + ixy = ThermoPhase._equilmap[XY] + if ixy > 0: + _cantera.thermo_equil(self._phase_id, ixy) + else: + raise 'invalid equilibrium option: '+XY + + + + + + + + + + + diff --git a/Cantera/python/Cantera/Transport.py b/Cantera/python/Cantera/Transport.py new file mode 100755 index 000000000..de4ab356b --- /dev/null +++ b/Cantera/python/Cantera/Transport.py @@ -0,0 +1,72 @@ +import _cantera + +class Transport: + """Transport property manager. + + A transport property manager is responsible for computing transport + properties. + """ + def __init__(self, xml_phase=None, + phase=None, model = "", loglevel=0): + self._phase = phase + if model == "" or model == "Default": + try: + self.model = xml_phase.child('transport')['model'] + except: + self.model = "" + else: + self.model = model + self.__tr_id = 0 + self.__tr_id = _cantera.Transport(self.model, + phase._phase_id, loglevel) + self.trnsp = phase.nSpecies() + self._models = {} + self._models[self.model] = self.__tr_id + + def __del__(self): + try: + _cantera.tran_delete(self.__tr_id) + except: + pass + + def setTransportModel(self, model): + if self._models.has_key(model): + self.__tr_id = self._models[model] + else: + self.__tr_id = _cantera.Transport(model, + self._phase._phase_id, 0) + self.model = model + + def desc(self): + if self.model == 'Multi': + return 'Multicomponent' + elif self.model == 'Mix': + return 'Mixture-averaged' + else: + return 'Unknown' + + def transport_id(self): + return self.__tr_id + + def viscosity(self): + return _cantera.tran_viscosity(self.__tr_id) + + def thermalConductivity(self): + return _cantera.tran_thermalConductivity(self.__tr_id) + + def thermalDiffCoeffs(self): + return _cantera.tran_thermalDiffCoeffs(self.__tr_id, + self.trnsp) + + def binaryDiffCoeffs(self): + return _cantera.tran_binaryDiffCoeffs(self.__tr_id, + self.trnsp) + + def mixDiffCoeffs(self): + return _cantera.tran_mixDiffCoeffs(self.__tr_id, + self.trnsp) + + def multiDiffCoeffs(self): + return _cantera.tran_multiDiffCoeffs(self.__tr_id, + self.trnsp) + diff --git a/Cantera/python/Cantera/XML.py b/Cantera/python/Cantera/XML.py new file mode 100644 index 000000000..81efed5d0 --- /dev/null +++ b/Cantera/python/Cantera/XML.py @@ -0,0 +1,175 @@ +""" +This module provides the Python interface to C++ class XML_Node. +""" + +import _cantera +import types +import tempfile +import string +import exceptions + +class XML_Node: + """A node in an XML tree.""" + def __init__(self, name="--", src="", wrap=0, root=None): + """ + Return an instance representing a node in an XML tree. + If 'src' is specified, then the XML tree found in file 'src' is + constructed, and this node forms the root of the tree. + Construct a new XML tree, with this node as the root. + If 'wrap' is greater than zero, then a + """ + self.wrap = wrap + if wrap > 0: + self._xml_id = wrap + self._root = root + else: + self._xml_id = _cantera.xml_new(name) + if src: + _cantera.xml_build(self._xml_id, src) + self._root = self + + def __del__(self): + """Delete the node. Does nothing if this node is only a wrapper.""" + if not self.wrap: + _cantera.xml_del(self._xml_id) + + def tag(self): + return _cantera.xml_tag(self._xml_id) + + def id(self): + try: + return self['id'] + except: + return '' + + def root(self): + return self._root + + def nChildren(self): + return _cantera.xml_nChildren(self._xml_id) + + def children(self,tag=""): + nch = self.nChildren() + children = [] + for n in range(nch): + m = _cantera.xml_childbynumber(self._xml_id, n) + ch = XML_Node(src="", wrap=m, root=self._root) + if (tag == "" or ch.tag() == tag): + children.append(ch) + return children + + def removeChild(self, child): + _cantera.xml_removeChild(self._xml_id, child._xml_id) + + def addChild(self, name, value=""): + if type(value) <> types.StringType: + v = `value` + else: + v = value + m = _cantera.xml_addChild(self._xml_id, name, v) + return XML_Node(src="", wrap=m, root=self._root) + + def hasAttrib(self, key): + x = self.attrib(key) + if x: return 1 + else: return 0 + + def attrib(self, key): + try: + return _cantera.xml_attrib(self._xml_id, key) + except: + return '' + + def addAttrib(self, key, value): + _cantera.xml_addAttrib(self._xml_id, key, value) + + def value(self, loc=""): + if loc: + node = self.child(loc) + return node.value() + else: + return _cantera.xml_value(self._xml_id) + + def child(self, loc="", id="", name=""): + if loc: + m = _cantera.xml_child(self._xml_id, loc) + elif id: + m = _cantera.xml_findID(self._xml_id, id) + elif name: + m = _cantera.xml_findByName(self._xml_id, name) + + ch = XML_Node(src="", wrap=m, root=self._root) + return ch + + def __getitem__(self, key): + return self.attrib(key) + + def __setitem__(self, key, value): + return self.addAttrib(key, value) + + def __int__(self): + return self._xml_id + + def __call__(self, loc): + return self.value(loc) + + def write(self, file): + _cantera.xml_write(self._xml_id, file) + + def __repr__(self): + tmp = tempfile.mktemp('.xml') + self.write(tmp) + f = open(tmp) + lines = f.readlines() + f.close() + s = '' + for line in lines: + s += line + return s + + def getRef(self): + if not self["idRef"]: return self + return find_XML(src = self["src"], root = self.root(), + id = self["idRef"]) + + +def find_XML(src = "", root = None, id = "", loc = "", name=""): + doc = None + r = None + if src: + ihash = string.find(src,'#') + if ihash < 0: + fname = src + else: + fname, idnew = string.split(src,'#') + if idnew: id = idnew + if fname: + doc = XML_Node(name="doc", src=fname) + root = None + elif root: + doc = root + elif root: + doc = root + else: + raise exceptions.CanteraError("either root or src must be specified.") + +## try: + if loc or id or name: + r = doc.child(loc=loc, id=id, name=name) + else: + r = doc + return r + + +def getFloatArray(node, convert_units=0): + sz = int(node['size']) + return _cantera.ctml_getFloatArray(node._xml_id, convert_units, sz) + + + + + + + + + diff --git a/Cantera/python/Cantera/__init__.py b/Cantera/python/Cantera/__init__.py new file mode 100755 index 000000000..00afd499d --- /dev/null +++ b/Cantera/python/Cantera/__init__.py @@ -0,0 +1,55 @@ +# +# Cantera +# + +import types +from constants import * +from gases import * +from exceptions import * +from set import set +#from _version import __createdate__ + +try: + from Numeric import array, asarray, zeros, ones +except: + print """ + + ERROR: NumPy not found! + + Cantera uses the NumPy set of numerical extensions to + Python. These do not appear to be present on your system, or else + the 'Numeric' package is not on your Python path. You can get + NumPy from http://sourceforge.net/projects/numpy, or see + http://www.python.org/topics/scicomp/numpy.html for more + information. If you are working on a Windows PC, an installer + program is available from the sourceforge site that will install + NumPy for you. The whole process takes less than a minute. + + """ + raise "could not import Numeric" + +# +# utilities +# +# write list items in comma-separated-value format +def writeCSV(f, list): + for item in list: + if type(item) == types.StringType: + f.write(item+', ') + else: + f.write(`item`+', ') + f.write('\n') + + +def table(keys, values): + x = {} + pairs = map(None, keys, values) + for p in pairs: + k, v = p + x[k] = v + return x + +def getCanteraError(): + import _cantera + return _cantera.get_Cantera_Error() + diff --git a/Cantera/python/Cantera/boundaries1D.py b/Cantera/python/Cantera/boundaries1D.py new file mode 100755 index 000000000..3b82d78ff --- /dev/null +++ b/Cantera/python/Cantera/boundaries1D.py @@ -0,0 +1,53 @@ +from Cantera import CanteraError +import _cantera +from Numeric import * +import types + +class Boundary1D: + def __init__(self, type): + self.domainType = 2 + self.__bndry_id = _cantera.bndry_new(type) + self.x = zeros((1,2),'d') + self.x[0,1] = 300.0 + + def __del__(self): + _cantera.bndry_del(self.__bndry_id) + + def shape(self): + return (1,2) + + def show(self): + pass + + def restore(self, file='', solution=''): + pass + + def bndry_id(self): + return self.__bndry_id + + def set(self, mdot = -999.0, V = -999.0, T = -999.0, X = None, Y = None): + if mdot > 0.0: + self.mdot = mdot + self.x[0,0] = mdot + _cantera.bndry_setmdot(self.__bndry_id, mdot) + if T > 0.0: + self.T = T + self.x[0,1] = T + _cantera.bndry_settemperature(self.__bndry_id, T) + if X: + self.X = X + if type(X) == types.StringType: + _cantera.bndry_setxinbyname(self.__bndry_id, X) + else: + _cantera.bndry_setxin(self.__bndry_id, X) + +def Inlet1D(): + return Boundary1D(1) + +def Symm1D(): + return Boundary1D(2) + +def Surf1D(): + return Boundary1D(3) + + diff --git a/Cantera/python/Cantera/ck2ctml.py b/Cantera/python/Cantera/ck2ctml.py new file mode 100644 index 000000000..17cb88c8d --- /dev/null +++ b/Cantera/python/Cantera/ck2ctml.py @@ -0,0 +1,21 @@ +import _cantera +from exceptions import * +import os + +def ck2ctml(infile = '', thermo = '-', transport = '-', outfile = '', id = ''): + if not infile: + raise CanteraError('No input file specified') + fname = os.path.basename(infile) + ff = os.path.splitext(fname) + if len(ff) == 2: + mechname = ff[0] + else: + mechname = ff + if not outfile: + outfile = mechname + '.xml' + if not id: + id = mechname + _cantera.ck2ctml(infile, thermo, transport, outfile, id) + + + diff --git a/Cantera/python/Cantera/constants.py b/Cantera/python/Cantera/constants.py new file mode 100755 index 000000000..762fe6bc8 --- /dev/null +++ b/Cantera/python/Cantera/constants.py @@ -0,0 +1,14 @@ +# +# constants +# + +OneAtm = 101325.0 +GasConstant = 8314.0 +Avogadro = 6.022136736e26 + +GasConst_cal_mol_K = 1.987 +Boltzmann = GasConstant / Avogadro +StefanBoltz = 5.67e-8 +ElectronCharge = 1.602e-19 +Pi = 3.1415926 +Faraday = ElectronCharge * Avogadro diff --git a/Cantera/python/Cantera/elements.py b/Cantera/python/Cantera/elements.py new file mode 100755 index 000000000..1da566aa7 --- /dev/null +++ b/Cantera/python/Cantera/elements.py @@ -0,0 +1,21 @@ + +def elementMoles(mix, element): + """Number of moles of an element in one mole of a mixture. + + mix -- a mixture object. + element -- the symbol for an element in 'mix'. + """ + + nsp = mix.nSpecies() + try: + m = mix.elementIndex(element) + if m < 0.0: return 0.0 + except: + return 0.0 + x = mix.moleFractions() + moles = 0.0 + for k in range(nsp): + moles += x[k]*mix.nAtoms(k,m) + return moles + + diff --git a/Cantera/python/Cantera/excel.py b/Cantera/python/Cantera/excel.py new file mode 100755 index 000000000..08a1f7232 --- /dev/null +++ b/Cantera/python/Cantera/excel.py @@ -0,0 +1,33 @@ +"""EXCEL CSV file utilities.""" + +def write_CSV_data(fname, names, npts, nvar, append, data): + """ + Write CSV data that can be imported into Excel + + fname -- file name + names -- sequence of variable names + npts -- number of data points + nvar -- number of variables + append -- if > 0, append to plot file, otherwise overwrite + data -- object to generate plot data. This object must have a + method 'value', defined so that data.value(j,n) returns + the value of variable n at point j. + """ + + from Numeric import array, shape + + if append > 0: + f = open(fname,'a') + else: + f = open(fname,'w') + for nm in names: + f.write(nm+',') + f.write('\n') + for j in range(npts): + for n in range(nvar): + f.write('%10.4e, ' % data.value(j,n)) + f.write('\n') + f.close() + + + diff --git a/Cantera/python/Cantera/exceptions.py b/Cantera/python/Cantera/exceptions.py new file mode 100755 index 000000000..d97b130cd --- /dev/null +++ b/Cantera/python/Cantera/exceptions.py @@ -0,0 +1,20 @@ +import _cantera + +def getCanteraError(): + return _cantera.get_Cantera_Error() + +class CanteraError(Exception): + def __init__(self, msg = ""): + if msg == "": + msg = _cantera.get_Cantera_Error() + self.msg = msg + def __str__(self): + print '\n\n\n############# CANTERA ERROR ############\n' + print ' ',self.msg + print '\n##########################################\n' + + +class OptionError(CanteraError): + def __init__(self, msg): + self.msg = 'Unknown option: '+msg + diff --git a/Cantera/python/Cantera/flame.py b/Cantera/python/Cantera/flame.py new file mode 100755 index 000000000..80c614db5 --- /dev/null +++ b/Cantera/python/Cantera/flame.py @@ -0,0 +1,373 @@ + +from Cantera import OneAtm +from Cantera.Flow import Flow1D +from Cantera.boundaries1D import Inlet1D, Surf1D, Symm1D +from Numeric import array, zeros, arrayrange + +from Cantera.gases import IdealGasMix, GRI30 +from Cantera.solve import solve +#from Cantera.esolve import esolve +from Cantera.OneDim import OneDim +from Cantera.FlowBoundary import Inlet, Outlet, SymmPlane +from Cantera import stoich +import math + +class BurnerFlame: + """One-dimensional flat, premixed flames. + + flame = BurnerFlame(gas, domain, fuel, oxidizer, inert, grid, pressure) + + example: + flame = BurnerFlame(gas = GRI30(), + domain = [0.0, 10.0*units.cm], + fuel = 'CH4:1', + oxidizer = 'O2:1,N2:3.76', + grid = [0.0, 0.01, 0.03, 0.06, 0.1], + pressure = OneAtm) + + """ + + def __init__(self, gas = None, domain = None, + fuel = '', oxidizer = '', inert = '', + grid = None, pressure = -1.0): + + if not gas or not domain or not fuel or not oxidizer or not pressure: + raise self.__doc__ + + self.gas = gas + self.p = pressure + + dx = (domain[1] - domain[0]) + if grid == None: + grid = dx * array([0.0, 0.01, 0.03, 0.1, 0.3, 0.6, 1.0]) + + self.__flow = Flow1D(flow_type = 'OneDim', gas = gas, + grid = grid, pressure = self.p) + + + self.inlet = Inlet(gas) + self.outlet = Outlet(gas) + + self.__flow.setBoundaries(left = self.inlet, right = self.outlet) + + self.__container = OneDim([self.__flow]) + self.start = 0 + + + # get the compositions of the fuel and oxidizer streams, and + # calculate the fuel/oxidizer ratio for stoichiometric + # combustion + + gas.setMoleFractions(fuel) + self._xfuel = gas.moleFractions() + + gas.setMoleFractions(oxidizer) + self._xox = gas.moleFractions() + + if inert: + gas.setMoleFractions(inert) + self._xinert = gas.moleFractions() + else: + self._xinert = zeros(gas.nSpecies(),'d') + + self._stoich_FO = stoich.stoich_fuel_to_oxidizer(gas, fuel, oxidizer) + + + + def setEquivRatio(self, phi): + """Set the equivalence ratio.""" + f_flow = self._stoich_FO * phi + comp = f_flow * self._xfuel + self._xox + self.gas.setState_PX(self.p, comp) + self.inlet.set(X = self.gas.moleFractions()) + + def setEquilProducts(self): + """Set the flame state to chemical equilibrium. + + This is useful to generate a starting estimate. + """ + x0 = self.inlet.X + self.gas.setState_TPX(self.inlet.T, self.p, x0) + rho0 = self.gas.density() + mdot = self.inlet.mdot + self.gas.equilibrate('HP') + xp = self.gas.moleFractions() + xinit = {} + z0 = 0.2 + teq = self.gas.temperature() + rhoeq = self.gas.density() + xinit['T'] = [(0.0, self.inlet.T), (z0, teq), (1.0, teq)] + xinit['u'] = [(0.0, mdot/rho0), (z0, mdot/rhoeq), (1.0, mdot/rhoeq)] + for k in range(self.gas.nSpecies()): + nm = self.gas.speciesName(k) + x = [(0.0, x0[k]), (z0, xp[k]), (1.0, xp[k])] + xinit[nm] = x + self.__flow.setInitialProfiles(xinit) + + def plot(self, plotfile = '', title = '', fmt = 'TECPLOT', + zone = 'c0', append = 0): + self.__flow.plotter.plot(fname = plotfile, title = title, + fmt = fmt, zone = zone, append=append) + + def setInitialProfiles(self, **init): + self.__flow.setInitialProfiles(init) + self.start = 1 + + def restore(self, src = '', solution = ''): + self.__container.restore(0, src, solution) + self.start = 1 + + def setTolerances(self, V = None, T = None, Y = None): + self.__flow.setTolerances( V, V, T, Y) + + def show(self): + self.__flow.show() + + def stretch(self, factor): + self.__flow.setGrid(factor*self.__flow.z) + + def set(self, **opt): + + if self.__container == None: + self.__container = OneDim([self.__flow,]) + + for o in opt.keys(): + v = opt[o] + if o == 'energy': + self.__flow.setEnergyEqn(v,loglevel=1) + elif o == 'pressure': + self.p = v + self.__flow.setPressure(v) + elif o == 'mdot': + self.inlet.set(mdot = v) + elif o == 'equiv_ratio': + self.setEquivRatio(v) + elif o == 'T_burner': + self.inlet.set(T = v) + elif o == 'refine': + self.__flow.refiner.delta = v + elif o == 'tol': + self.__flow.setTolerances(u = v, V = v, T = v, Y = v) + elif o == 'max_jac_age': + self.__container.setOptions(max_jac_age = v) + elif o == 'timesteps': + self.__container.setOptions(nsteps = v[0], timestep = v[1]) + + def solve(self, loglevel = 0): + if not self.start: + self.setEquilProducts() + self.start = 1 + solve(self.__container, loglevel = loglevel, refine_grid = 1) + + def esolve(self, loglevel = 0, efactor = 1.0e4): + if not self.start: + self.setEquilProducts() + self.start = 1 + esolve(self.__container, efactor = efactor, loglevel = loglevel, refine_grid = 1) + + + def save(self, soln, desc, file = 'flame.xml'): + self.__container.save(file, soln, desc) + + def showStatistics(self): + self.__container.showStatistics() + + + + + +class StagnationFlame: + """Axisymmetric premixed stagnation-point flames. + + flame = StagnationFlame(gas, domain, fuel, oxidizer, inert, grid, pressure) + + example: + flame = BurnerFlame(gas = GRI30(), + domain = [0.0, 10.0*units.cm], + fuel = 'CH4:1', + oxidizer = 'O2:1,N2:3.76', + grid = [0.0, 0.01, 0.03, 0.06, 0.1], + pressure = OneAtm) + + """ + + def __init__(self, gas = None, domain = None, + fuel = '', oxidizer = '', inert = '', + grid = None, pressure = -1.0): + + if not gas or not domain or not fuel or not oxidizer or not pressure: + raise self.__doc__ + + self.gas = gas + self.p = pressure + + dx = (domain[1] - domain[0]) + self.dx = dx + + if grid == None: + grid = dx * array([0.0, 0.01, 0.03, 0.1, 0.3, 0.6, 1.0]) + + self.__flow = Flow1D(flow_type = 'Stag', gas = gas, + grid = grid, pressure = self.p) + + self.__left = Inlet1D() + self.__right = Surf1D() + self.__container = OneDim([self.__left, self.__flow, self.__right]) + self.start = 0 + + + # get the compositions of the fuel and oxidizer streams, and + # calculate the fuel/oxidizer ratio for stoichiometric + # combustion + + gas.setMoleFractions(fuel) + self._xfuel = gas.moleFractions() + + gas.setMoleFractions(oxidizer) + self._xox = gas.moleFractions() + + if inert: + gas.setMoleFractions(inert) + self._xinert = gas.moleFractions() + else: + self._xinert = zeros(gas.nSpecies(),'d') + + self._stoich_FO = stoich.stoich_fuel_to_oxidizer(gas, fuel, oxidizer) + + + def nPoints(self): + return len(self.__flow.z) + + def setEquivRatio(self, phi): + """Set the equivalence ratio.""" + f_flow = self._stoich_FO * phi + comp = f_flow * self._xfuel + self._xox + self.gas.setState_PX(self.p, comp) + self.__left.set(X = self.gas.moleFractions()) + + + def setEquilProducts(self): + """Set the flame state to chemical equilibrium. + + This is useful to generate a starting estimate. + """ + + x0 = self.__left.X + self.gas.setState_TPX(self.__left.T, self.p, x0) + rho0 = self.gas.density() + + mdot = self.__left.mdot + self.gas.equilibrate('HP') + xp = self.gas.moleFractions() + + xinit = {} + z0 = 0.2 + teq = self.gas.temperature() + rhoeq = self.gas.density() + + re = self.dx * mdot / self.gas.viscosity() + z1 = 1.0 - 1.0/math.sqrt(re) + + tw = self.__right.T + self.gas.setState_TPX(tw, self.p, x0) + self.gas.equilibrate('TP') + x1 = self.gas.moleFractions() + rho1 = self.gas.density() + + xinit['T'] = [(0.0, self.__left.T), (z0, teq), (z1, teq), + (1.0, tw)] + xinit['u'] = [(0.0, mdot/rho0), (1.0, 0.0)] + xinit['V'] = [(0.0, 0.0), (z1, mdot/(rhoeq*z1*self.dx)), (1.0, 0.0)] + for k in range(self.gas.nSpecies()): + nm = self.gas.speciesName(k) + x = [(0.0, x0[k]), (z0, xp[k]), (z1, xp[k]), (1.0, x1[k])] + xinit[nm] = x + self.__flow.setInitialProfiles(xinit) + + + def plot(self, plotfile = '', title = '', fmt = 'TECPLOT', + zone = 'c0', append = 0): + self.__flow.plotter.plot(fname = plotfile, title = title, + fmt = fmt, zone = zone, append=append) + + def setInitialProfiles(self, **init): + self.__flow.setInitialProfiles(init) + self.start = 1 + + def resid(self): + return self.__container.resid(1) + + def restore(self, src = '', solution = ''): + self.__container.restore(1,src, solution) + self.start = 1 + + def setTolerances(self, V = None, T = None, Y = None): + self.__flow.setTolerances( V, V, T, Y) + + def show(self): + self.__flow.show() + + def stretch(self, factor): + self.__flow.setGrid(factor*self.__flow.z) + + def enableEnergy(self, pt): + self.__flow.setEnergyEqn('on',loglevel=1,pt=pt) + + def set(self, **opt): + + if self.__container == None: + self.__container = OneDim([self.__flow,]) + + for o in opt.keys(): + v = opt[o] + if o == 'energy': + self.__flow.setEnergyEqn(v,loglevel=1) + elif o == 'pressure': + self.p = v + self.__flow.setPressure(v) + elif o == 'mdot': + self.__left.set(mdot = v) + elif o == 'equiv_ratio': + self.setEquivRatio(v) + elif o == 'T_burner': + self.__left.set(T = v) + elif o == 'T_surface': + self.__right.set(T = v) + elif o == 'refine': + self.__flow.refiner.delta = v + elif o == 'efactor': + self.__flow.setEnergyFactor(v) + elif o == 'tol': + self.__flow.setTolerances(u = v, V = v, T = v, Y = v) + elif o == 'max_jac_age': + self.__container.setOptions(max_jac_age = v) + elif o == 'timesteps': + self.__container.setOptions(nsteps = v[0], timestep = v[1]) + + def solve(self, loglevel = 0): + if not self.start: + self.setEquilProducts() + self.start = 1 + solve(self.__container, loglevel = loglevel, refine_grid = 1) + +## def esolve(self, loglevel = 0, efactor = 1.0e4): +## if not self.start: +## self.setEquilProducts() +## self.start = 1 +## esolve(self.__container, efactor = efactor, loglevel = loglevel, refine_grid = 1) + + def save(self, soln, desc, file = 'flame.xml'): + self.__container.save(file, soln, desc) + + def showStatistics(self): + self.__container.showStatistics() + + + + + + + + + + diff --git a/Cantera/python/Cantera/gases.py b/Cantera/python/Cantera/gases.py new file mode 100755 index 000000000..bc7473219 --- /dev/null +++ b/Cantera/python/Cantera/gases.py @@ -0,0 +1,88 @@ +"""This module defines classes and functions used to model gas mixtures.""" + +from constants import * +from solution import Solution +from ck2ctml import ck2ctml +#import _cantera +import os + +def IdealGasMix(src="", root=None, transport='None', + thermo = "", trandb = ""): + p = os.path.normpath(os.path.dirname(src)) + fname = os.path.basename(src) + ff = os.path.splitext(fname) + nm = "" + if len(ff) > 1: + nm = ff[0] + ext = ff[1] + else: + nm = ff + ext = '' + if ext <> '.xml' and ext <> '.XML' and ext <> '.ctml' and ext <> '.CTML': + outfile = p+os.sep+nm+'.xml' + ck2ctml(infile = src, outfile = outfile, thermo = thermo, + transport = trandb, id = nm) + return Solution(src=outfile, root=None, transport=transport) + else: + return Solution(src=src, root=root, transport=transport) + +def GRI30(transport='None'): + return Solution(src="gri30.xml#gri30_hw", transport=transport) + +def Air(): + return Solution(src="air.xml#air") + +def Argon(): + return Solution(src="argon.xml#argon") + +## def H_O_AR(transport=None, chem = 1): +## """ +## The hydrogen/oxygen/argon portion of GRI-Mech 3.0. + +## Parameters: +## transport --- transport model (None, 'Mix,' or 'Multi'). Default: None +## chem --- chemistry disabled if chem = 0. Default: enabled. +## """ +## if chem == 1: +## return Solution(import_file='h2o2.inp', thermo_db="", +## eos=1, kmodel=1, trmodel=transport, +## transport_db='gri30_tran.dat', +## validate=0) +## else: +## return Solution(import_file='h2o2_noch.inp', thermo_db="", +## eos=1, kmodel=1, trmodel=transport, +## transport_db='gri30_tran.dat', +## validate=0) + + +## def GRI30(transport=None): +## """ +## GRI-Mech 3.0. + +## Parameters: +## transport --- transport model (None, 'Mix,' or 'Multi'). Default: None +## """ +## return Solution(import_file='gri30.xml', thermo_db="", +## eos=1, kmodel=2, trmodel=transport, id="gri30", +## transport_db='gri30_tran.dat', +## validate=0) + + +## def Air(transport=None, T=300.0, P=OneAtm): +## """ +## Edited version of GRI-Mech 3.0 containing only O/N/AR species. Initial +## composition is set to 21% O2, 78% N2, 1% Ar. + +## Parameters: +## transport --- transport model (None, 'Mix,' or 'Multi'). Default: None +## T --- temperature +## P --- pressure +## """ +## gas = Solution(import_file='air.inp', thermo_db="nasathermo.dat", +## eos=1, kmodel=1, trmodel=transport, id="air", +## transport_db='gri30_tran.dat', +## validate=0) +## gas.setState_TPX(T, P, 'O2:0.21, N2:0.78, Ar:0.01') +## return gas + + diff --git a/Cantera/python/Cantera/importFromFile.py b/Cantera/python/Cantera/importFromFile.py new file mode 100755 index 000000000..5bfda3c4f --- /dev/null +++ b/Cantera/python/Cantera/importFromFile.py @@ -0,0 +1,8 @@ + +import _cantera +from Thermo import Thermo +from Kinetics import Kinetics + +def importFromFile(t, k, params): + return _cantera.importFromFile(t.cthermo, k.ckin, params['import_file'],'',1) + diff --git a/Cantera/python/Cantera/interp.py b/Cantera/python/Cantera/interp.py new file mode 100755 index 000000000..7d2ad4854 --- /dev/null +++ b/Cantera/python/Cantera/interp.py @@ -0,0 +1,64 @@ + +def interp(z0, z, f): + """ + Linear interpolation. + + Sequences z and f must be of the same length, + and the entries in z must be monotonically increasing. + + Example: + >>> z = [0.0, 0.2, 0.5, 1.2, 2.1] + >>> f = [3.0, 2.0, 1.0, 0.0, -1.0] + >>>print interp(-2, z, f), interp(0.5, z, f), interp(6, z, f) + 3.0 7.0 -9.0 + """ + + n = len(z) + + # if z0 is outside the range of z, then return the endpoint value, + # instead of extrapolating. + if z0 <= z[0]: + return f[0] + elif z0 > z[-1]: + return f[-1] + + for i in range(1,n): + if z0 <= z[i]: + return f[i-1] + (f[i] - f[i-1])*(z0 - z[i-1])/(z[i] - z[i-1]) + + # if this statement is reached, then there is an error. + raise 'interpolation error!' + + +def quadInterp(z0, z, f): + + n = len(z) + + # if z0 is outside the range of z, then return the endpoint value, + # instead of extrapolating. + if z0 <= z[0]: + return f[0] + elif z0 > z[-1]: + return f[-1] + + for i in range(1,n): + if z0 <= z[i]: + j = max(2,i) + dx21 = z[j-1] - z[j-2] + dx32 = z[j] - z[j-1] + dx31 = dx21 + dx32 + dy32 = f[j] - f[j-1] + dy21 = f[j-1] - f[j-2] + a = (dx21*dy32 - dy21*dx32)/(dx21*dx31*dx32) + return a*(z0 - z[j-2])*(z0 - z[j-1]) + ( + (dy21/dx21)*(z0 - z[j-1]) + f[j-1]) + + # if this statement is reached, then there is an error. + raise 'interpolation error!' + +## if __name__ == '__main__': +## z = [0.0, 0.2, 0.5, 1.2, 2.1] +## f = [3.0, 5.0, 11.0, 0.0, -9.0] + +## print interp(-2, z, f), interp(0.3, z, f), interp(6, z, f) +## print quadInterp(-2, z, f), quadInterp(0.3, z, f), quadInterp(6, z, f) diff --git a/Cantera/python/Cantera/refine.py b/Cantera/python/Cantera/refine.py new file mode 100755 index 000000000..39c265e7c --- /dev/null +++ b/Cantera/python/Cantera/refine.py @@ -0,0 +1,295 @@ +"""Grid refinement. + +Suppose you have a monotonic NumPy array of grid points 'z', and a +solution array soln[j,n] that contains 3 three solution components +denoted 'a', 'b', and 'c', evaluated at the grid points. To refine the +grid based on components 'a' and 'b' but not 'c', do the following. + +>>> from refine import Refiner +>>> r = Refiner([(0, 'a'), (1, 'b')]) +>>> new_grid, new_soln = r.refine(grid, soln) + +""" + + +import Numeric +import math +from Cantera import CanteraError +from Cantera import interp + +def eps(): + """Return the square root of machine precision.""" + e = 1.0 + while 1.0 + e <> 1.0: e = 0.5*e + return math.sqrt(e) + + +def delta(f): + """Given an array f, return an array of the difference in + adjacent values.""" + n = len(f) + d = Numeric.zeros(n-1,'d') + for j in range(n-1): + d[j] = f[j+1] - f[j] + return d + + +def slope(z, f): + """Given arrays z and f, return an array of the slopes df/dz in + each interval.""" + n = len(z) + s = Numeric.zeros(n-1,'d') + for j in range(n-1): + s[j] = ((f[j+1] - f[j])/(z[j+1] - z[j])) + return Numeric.array(s,'d') + + +class RefineError(CanteraError): + def __init__(self, msg): + self.msg = 'Grid refinement error!\n'+msg + + +class Refiner: + """Grid refiner. + + Attributes: + + components -- sequence of (number, name) pairs specifying the + components of the solution to use for grid refinement. The number + is used to access the component in the solution array, and the + name is used only for diagnostic messages. + + max_delta -- Maximum tolerated difference in solution values + between neighboring grid points, expressed as a fraction between 0 + and 1 of the total range of the component over all grid + points. Default: 0.8 (minimal refinement). + + max_delta_slope -- Maximum tolerated difference in solution slopes + between neighboring grid intervals, expressed as a fraction between 0 + and 1 of the total range of the component over all grid + points. Default: 0.8 (minimal refinement). + + """ + + def __init__(self, components = [], delta = (2.0, 0.1, 0.2), names = []): + self.components = components + self.delta = delta + self.names = names + self.loglevel = 2 + self.eps = eps() + self.min_range = 0.01 + self.direction = 1 + self.fctr = 1.0 + self.ok = 0 + + + def prune(self, grid = None, solution = None, threshold = None): + + n0 = len(grid) + g = grid + sol = solution + self.fctr = 1.0 + savedir = self.direction + + ll = self.loglevel + #self.loglevel = 0 + j = 1 + while j < len(g)-1: + g0 = g + s0 = sol + pt = g[j] + nn = len(g) + + # remove point j + g = Numeric.take(g,range(0,j)+range(j+1,nn)) + + # remove row j + sol = Numeric.take(sol, range(0,j)+range(j+1,nn)) + np = len(g) + + self.direction = 1 + gnew, snew = self.refine(g, sol, threshold) + if (len(gnew) > np): + g = g0 + sol = s0 + j += 1 + if ll > 0: + print 'cannot remove point at ',pt + else: + if ll > 0: + print 'removed point at ',pt + self.loglevel = ll + self.fctr = 0.2 + self.direction = savedir + return (g, sol) + + + def refine(self, grid = None, solution = None, threshold = None): + + self.ok = 0 + # grid parameters + n0 = len(grid) + dz0 = grid[-1] - grid[0] + + maxpts = self.fctr*n0 + 1 + + ncomp = Numeric.shape(solution)[1] + + if threshold: + self.threshold = threshold + else: + self.threshold = self.eps * Numeric.ones(ncomp, 'd') + + if Numeric.shape(solution)[0] <> n0: + raise RefineError('Number of solution points differs from '+ + 'number of grid points.') + + # if the solution components to examine for refinement have + # not been specified, use all components. + nc = Numeric.shape(solution)[1] + if not self.components: self.components = range(nc) + + c = {} + p = {} + + dz = delta(grid) + for j in range(1,n0-1): + if dz[j] > self.delta[0]*dz[j-1]: + p[j] = 1 + c['point '+`j`] = 1 + if dz[j] < dz[j-1]/self.delta[0]: + p[j-1] = 1 + c['point '+`j-1`] = 1 + + for i in self.components: + try: + name = self.names[i] + except: + name = 'component '+`i` + + # get component i at all points, and compute its slope + v = solution[:,i] + s = slope(grid, v) + + # compute the change in value and slope + dv = delta(v) + ds = delta(s) + + # find the range of values and slopes + vmin = min(v) + vmax = max(v) + smin = min(s) + smax = max(s) + + # max absolute values of v and s + aa = max((abs(vmax), abs(vmin))) + ss = max((abs(smax), abs(smin))) + + + # refine based on component i only if the range of v is + # greater than a fraction 'min_range' of max |v|. This + # eliminates components that consist of small fluctuations + # on a constant background. + + if (vmax - vmin) > self.min_range*aa: + + # maximum allowable difference in value between + # adjacent points. + + dmax = self.delta[1]*(vmax - vmin) + self.threshold[i] + for j in range(len(dv)): + r = abs(dv[j])/dmax + if r > 1.0: + p[j] = 1 + c[name] = 1 + + + # refine based on the slope of component i only if the + # range of s is greater than a fraction 'min_range' of max + # |s|. This eliminates components that consist of small + # fluctuations on a constant slope background. + + if (smax - smin) > self.min_range*ss: + + # maximum allowable difference in slope between + # adjacent points. + dmax = self.delta[2]*(smax - smin) + + for j in range(len(ds)): + r = abs(ds[j]) / (dmax + self.threshold[i]/dz[j]) + if r > 1: + c[name] = 1 + p[j] = 1 + p[j+1] = 1 + + if len(p) == 0: self.ok = 1 + + znew = [] + nnew = len(p) + nadded = nnew + + if self.loglevel > 0: + if nnew > 0: + print '\nRefining grid.' + print 'New points inserted after grid points', + + for j in range(n0 - 1): + znew.append(grid[j]) + if p.has_key(j): + if self.loglevel > 0: print j, + znew.append(0.5*(grid[j] + grid[j+1])) + if self.loglevel > 0: print + znew.append(grid[-1]) + if self.loglevel > 0 and nnew > 0: + print 'to resolve ', + ck = c.keys() + for s in ck: + if s <> ck[-1]: + print s+',', + else: + print s, + print + + npts = len(znew) + + newsoln = Numeric.zeros((npts, ncomp),'d') + for i in range(ncomp): + for j in range(npts): + newsoln[j,i] = interp.interp(znew[j],grid,solution[:,i]) + + return (Numeric.array(znew), Numeric.array(znew), newsoln, self.ok) + + + +def refine(grid = None, solution = None, components = [], delta = (0.8, 1.0), threshold = None): + """Refine a grid and interpolate the solution onto the new grid.""" + r = Refiner(components = components, delta = delta) + return r.refine(grid, solution, threshold) + + +def prune(grid = None, solution = None, components = [], delta = (0.8, 1.0), threshold = None): + """Remove unneeded points from a grid and solution array.""" + r = Refiner(components = components, delta = delta) + return r.prune(grid, solution, threshold) + + + +# test it +if __name__ == '__main__': + + grid = Numeric.array([0.0, 0.2, 0.3, 1.0, 4.0]) + soln = Numeric.array([[100.0, 0.4, -9.0], + [500.0, 0.0, -89.0], + [700.0, 0.9, 99.0], + [-99.0, 8.0, 77.0], + [567.0, 8.0, 0.0]]) + grid_new, soln_new = refine(grid, soln, + components = [0,2], + delta = (0.5, 0.8)) + + print 'new grid = ',grid_new + print 'new solution = ',soln_new + + + + diff --git a/Cantera/python/Cantera/rxnpath.py b/Cantera/python/Cantera/rxnpath.py new file mode 100755 index 000000000..8b281963b --- /dev/null +++ b/Cantera/python/Cantera/rxnpath.py @@ -0,0 +1,166 @@ +""" +Reaction path diagrams. + +To create a simple reaction path diagram: + +>>> import rxnpath +>>> element = 'C' +>>> rxnpath.write(gas, element, file) + +Object 'gas' must an instance of a class derived from class 'Kinetics' +(for example class IdealGasMix). The diagram layout is written to +'file'. The output must be postprocessed with program 'dot', which is +part of the GraphViz package. To create a Postscript plot: + +dot -Tps rp.dot > rp.ps + +Other output formats are also supported by dot, including gif, pcl, +jpg, png, and svg + +For more control over the graph properties, create a PathDiagam object +and pass it to the 'write' procedure. + +PathDiagram keyword options: + + diagram type: + -- detailed 'true' or 'false' + -- type 'both' or 'net' (forward and reverse arrows, + or net arrow) + -- dot_options options passed through to 'dot' + + colors: + -- normal_color color for normal-weight lines + -- bold_color color for bold-weight lines + -- dashed_color color for dashed lines + + thresholds: + -- threshold min relative strength for a path to be shown + -- normal_threshold min relative strength for normal-weight path + Below this value, paths are dashed. + -- bold_threshold min relative strength for bold-weight path + +""" + +import _cantera + +class PathDiagram: + def __init__(self, **options): + self.__rdiag_id = _cantera.rdiag_new() + self.setOptions({"detailed":"true", + "dashed_color":"gray", + "bold_color":"red", + "normal_color":"steelblue", + "scale":-1, + "dot_options":'center=1;margin=0;size="5,6";page="5,6";ratio=compress;fontname=Arial;', + "title":"-", + "arrow_width":-5, + "threshold":0.001, + "bold_threshold":0.2, + "normal_threshold":0.01, + "label_threshold":0.001, + "flow_type":"net"} + ) + self.setOptions(options) + + def __del__(self): + _cantera.rdiag_del(self.__rdiag_id) + + def id(self): + return self.__rdiag_id + + def write(self, fmt, file): + _cantera.rdiag_write(self.__rdiag_id, fmt, file) + + def add(self, other): + _cantera.rdiag_add(self.__rdiag_id, other.id()) + + def findMajorPaths(self, a, threshold = 0.0): + _cantera.rdiag_findMajor(self.__rdiag_id, threshold, a) + + def displayOnly(self, node=-1): + _cantera.rdiag_displayOnly(self.__rdiag_id, node) + + def setOptions(self, options): + for o in options.keys(): + v = options[o] + if o == "detailed": + if v == "true": + _cantera.rdiag_detailed(self.__rdiag_id) + elif v == "false": + _cantera.rdiag_brief(self.__rdiag_id) + elif o == "dashed_color": + _cantera.rdiag_setDashedColor(self.__rdiag_id, v) + elif o == "bold_color": + _cantera.rdiag_setBoldColor(self.__rdiag_id, v) + elif o == "normal_color": + _cantera.rdiag_setNormalColor(self.__rdiag_id, v) + elif o == "scale": + _cantera.rdiag_setScale(self.__rdiag_id, v) + elif o == "dot_options": + _cantera.rdiag_setDotOptions(self.__rdiag_id, v) + elif o == "title": + _cantera.rdiag_setTitle(self.__rdiag_id, v) + elif o == "arrow_width": + _cantera.rdiag_setArrowWidth(self.__rdiag_id, v) + elif o == "threshold": + _cantera.rdiag_setThreshold(self.__rdiag_id, v) + elif o == "bold_threshold": + _cantera.rdiag_setBoldThreshold(self.__rdiag_id, v) + elif o == "normal_threshold": + _cantera.rdiag_setNormalThreshold(self.__rdiag_id, v) + elif o == "label_threshold": + _cantera.rdiag_setLabelThreshold(self.__rdiag_id, v) + elif o == "flow_type": + if v == "one_way": + _cantera.rdiag_setFlowType(self.__rdiag_id, 0) + else: + _cantera.rdiag_setFlowType(self.__rdiag_id, 1) + else: + raise("unknown attribute "+o) + +class PathBuilder: + + def __init__(self, kin, logfile=""): + if logfile == "": + logfile = "rxnpath.log" + self.__rbuild_id = _cantera.rbuild_new() + self.kin = kin + _cantera.rbuild_init(self.__rbuild_id, logfile, kin.ckin) + + def __del__(self): + _cantera.rbuild_del(self.__rbuild_id) + + def build(self, diagram = None, element = "C", + dotfile = "rxnpaths.dot", format="dot"): + if diagram == None: + diagram = PathDiagram() + _cantera.rbuild_build(self.__rbuild_id, self.kin.ckin, element, + "buildlog", diagram.id(), 1) + if format == "dot": + diagram.write(0, dotfile) + elif format == "plain": + diagram.write(1, dotfile) + + +def write(g, el, file, d=None, format="dot"): + b = PathBuilder(g) + b.build(element = el, diagram = d, dotfile = file, format = format) + + +def view(url, ext = 'png'): + if not ext in ['pdf', 'png', 'gif', 'jpg', 'svg']: + raise 'fmt must be svg, pdf, png, gif, or jpg' + import webbrowser + dot_server = 'http://webdot.graphviz.org/cgi-bin/webdot/' + webbrowser.open(dot_server+url+'.dot.'+ext) + + +if __name__ == "__main__": + from Cantera.gases import GRI30 + gas = GRI30() + x = [1.0] * gas.nSpecies() + gas.setState_TPX(1800.0, 1.01325e5, x) + write(gas, 'C', 'c:/users/dgg/test.dot') + + + diff --git a/Cantera/python/Cantera/schem.py b/Cantera/python/Cantera/schem.py new file mode 100755 index 000000000..537496437 --- /dev/null +++ b/Cantera/python/Cantera/schem.py @@ -0,0 +1,566 @@ +deprecated + +""" +Surface chemistry. + +Classes: + +BulkSpecies -- bulk species +SurfSpecies -- surface species +SurfReaction -- surface reactions +Interface -- interfaces + +""" + + +from Cantera import CanteraError +from Cantera import units +from Numeric import array +from Cantera import ctsurf, constants, SurfWriter +import math +import types + +_rtypes = {'conc':0, 'cov':1, 'bar':2, 'site':3} + + +class SurfSpecies: + """ + Surface species. + + A SurfSpecies object is required for every surface species. + """ + + def __init__(self, phase, symbol = '', elements = {}, size = 1): + """ + Constructor arguments: + + phase -- the surface phase the species belongs to. + symbol -- the symbol used in writing the reaction equation. + elements -- a dictionary mapping element symbols to atom numbers. + size -- number of surface sites occuppied by this species. + + Example: + h_surf = SurfSpecies(phase = surf, symbol = 'H_s', + elements = {'H':1}, size = 1.0) + + """ + + self.symbol = symbol + self._nAtoms = {} + for e in elements.keys(): + self._nAtoms[e] = elements[e] + self.elements = elements.keys() # list of element symbols + self.size = size + self.phase = phase + self.index = len(self.phase.species) + self.phase.addSpecies(self) # add it to the surface phase + + + def nAtoms(self, el): + """ + Number of atoms of element with symbol 'el'. + """ + try: + return self._nAtoms[el] + except: + return 0.0 # symbol not in the dictionary + + + +class BulkSpecies: + """ + Instances of class BulkSpecies represent the bulk-phase species in + surface reactions. A 'bulk-phase' species is any species in a 3D + phase, whether a gas, solid, or liquid. The species parameters are + taken from the bulk-phase object. + """ + + def __init__(self, phase = None, symbol = ''): + self.phase = phase + self.symbol = symbol + self.index = phase.speciesIndex(symbol) + self._nAtoms = {} + el = phase.elementNames() + for m in range(len(el)): + na = self.phase.nAtoms(self.index, m) + if na <> 0: + self._nAtoms[el[m]] = na + self.weight = self.phase.molecularWeights()[self.index] + self.elements = self._nAtoms.keys() # list of element symbols + + # number of atoms + def nAtoms(self, el): + try: + return self._nAtoms[el] + except: + return 0.0 + + +class RateParam: + """ + + Reaction rate parameterizations appear in many different forms. + Instances of this class are used to collect together a set of + parameters for a particular parameterization type. + + The rate is computed using a generalized law of mass action, where + the bulk (3D) species may be specified either by concentration or + partial pressure, and empirical reaction orders may be assigned + for each species. The surface species may be specified using + either surface concentration, or coverage. Finally, the computed + rate may be specified to be either a rate per unit area, or per + site. + + Arguments: + + bulk -- one of ['conc', 'bar']. Specifies how bulk-phase + reactant abundances appear in the rate expression. Default: + 'conc'. If 'bar' is specified, the ideal gas law is used to + convert from partial pressure to concentration units when the + reaction is added to the surface mechanism. + + surf -- one of ['conc', 'cov']. Specifies how surface reactant + abundances appear in the rate expression. Default: 'conc'. + + rate -- one of ['per_area', 'per_site']. Specifies whether the + rate expression computes the rate per unit area (default), or + per site. These differ only by a factor of the total site + density. + + Note that these values are used to convert the reaction + parameterization into concentration form at the time the + reaction is added to the surface mechanism. + +""" + def __init__(self, bulk = 'conc', surf = 'conc', result = 'per_area'): + self.bulk = bulk + self.surf = surf + self.result = result + if not self.bulk in ['conc', 'bar']: + raise CanteraError('unknown bulk phase quantity type: '+self.bulk) + if not self.surf in ['conc', 'cov']: + raise CanteraError('unknown surface phase quantity type: ' + +self.surf) + if not self.result in ['per_area', 'per_site']: + raise CanteraError('unknown rate type: '+self.result) + + + + +# A class for surface reactions. + +class SurfReaction: + """ + rate_type --- a triplet of strings specifying how the reaction rate is + expressed. + """ + + def __init__(self, phase = None, reactants = [], order = {}, products = [], + rate = None, stick = None, + type = None): + + self.reactants = reactants + self.products = products + self.order = order + + self.stick = stick + self.rate = rate + self.phase = phase + if type: + self.type = type + else: + self.type = RateParam(bulk = 'conc', + surf = 'conc', + result = 'per_area') + + self.phase.addReaction(self) + + + + def __repr__(self): + rstr = '' + for r in self.reactants: + rstr += r.symbol + ' + ' + rstr = rstr[:-3] + ' => ' + for p in self.products: + rstr += p.symbol + ' + ' + rstr = rstr[:-3] + return rstr + + + +class Interface: + def __init__(self, phases = (None, None), + site_density = 0.0): + + self.rxns = [] + self.indexmap = {} + + # bulk phase 1 parameters + self.p1 = phases[0] + self.p1_nsp = 0 + self.p1id = 0 + self.p1sp = None + if self.p1: + self.p1id = self.p1.cthermo + self.p1_nsp = self.p1.nSpecies() + self.p1sp = self.p1.speciesNames() + + # bulk phase 2 parameters + self.p2_nsp = 0 + self.p2id = 0 + self.p2 = phases[1] + self.p2sp = None + if self.p2: + self.p2id = self.p2.cthermo + self.p2_nsp = self.p2.nSpecies() + self.p2sp = self.p2.speciesNames() + + self.s0 = site_density + self.species = [] + self._spsymbols = [] + self._elements = {} + self._freeze_species = 0 + self.rindex = [] + self.pindex = [] + + # unit conversion factors to SI + self._umol = 1.0 + self._ulength = 1.0 + self._utime = 1.0 + self._uconc2 = 1.0 + self._uconc3 = 1.0 + self._ue = 1.0 + + # create instances of kernel classes SurfacePhase and + # SurfKinetics + self.__surf_id = ctsurf.surf_new(self.s0) + self.__surfkin_id = ctsurf.surfkin_new(self.__surf_id, + self.p1id, self.p2id) + + + self.rxndata = [] + + + def __del__(self): + ctsurf.surf_delete(self.__surf_id) + ctsurf.surfkin_delete(self.__surfkin_id) + ctsurf.surf1d_delete(self.__surf1d_id) + + + def kin_id(self): + return self.__surfkin_id + + def surf_id(self): + return self.__surf1d_id + +## def parse_equation(self, eqn): +## toks = string.split(eqn) +## digits = ['2', '3', '4', '5', '6', '7', '8', '9'] +## for t in toks: +## if t in digits: +## nu = int(t) +## elif t == '+' + +## if t in self.p1sp: +## k = self.p1sp.index(t) +## elif t in self.p2sp: +## k = self.p1nsp + self.p2sp.index(t) +## elif t in self._spsymbols: +## k = self.p1nsp + self.p2nsp + self._spsymbols.index(t) +## else: +## raise CanteraError('unknown species '+t) + + + def addDoc(self, key, value): + ctsurf.surf_doc(self.__surf_id, key, value) + + def save(self, filename, idtag, comment): + ctsurf.surfkin_save(self.__surfkin_id, filename, idtag, comment) + + def setUnits(self, + length = '', moles = '', time = '', E = ''): + + """ + Set the unit system for surface reactions. On each call, + only the specified unit conversion factors are set; the rest + are left unchanged. + + length -- units for lengths ('m', 'cm', 'mm') + moles -- units for amount ('mol', 'kmol', 'molecule') + time -- units for time ('s') + E -- units for activation energy ('kcal_per_mol', + 'cal_per_mol', 'eV', 'K') + """ + if moles: self._umol = units.mole(moles) + if length: self._ulength = units.length(length) + if time: self._utime = 1.0 + if E: self._ue = units.actEnergy(E) + self._uconc2 = self._umol/(self._ulength * self._ulength) + self._uconc3 = self._uconc2/self._ulength + + + def addSpecies(self, s): + """Add a species.""" + if self._freeze_species > 0: + raise CanteraError("Species must be added to a phase "+ + "before reactions are added") + self.species.append(s) + self._spsymbols.append(s.symbol) + self.indexmap[s.symbol] = s.index + for e in s.elements: + self._elements[e] = 1 + self.elements = self._elements.keys() + ctsurf.surf_addspecies(self.__surf_id, s.symbol, s.size) + + def nSpecies(self): + return ctsurf.surf_nspecies(self.__surf_id) + + def speciesIndex(self, sym): + return self.indexmap[sym] + + def speciesNames(self): + return self._spsymbols + + def setSiteDensity(self, s0): + self.s0 = s0 + print 'setting site density to ',s0 + ctsurf.surf_setsitedensity(self.__surf_id, self.s0) + + def show(self): + cv = self.coverages() + c = map(None,self._spsymbols,cv) + for s in c: + print ' %16s %10.4g ' % (s[0],s[1]) + + def coverage(self, sp): + clist = ctsurf.surf_getcoverages(self.__surf_id) + c = [] + for s in sp: + c.append(clist[self.indexmap[s]]) + return c + + def coverages(self): + return ctsurf.surf_getcoverages(self.__surf_id) + + def setCoverages(self, cov): + if type(cov) == types.DictType: + cv = [0.0]*len(self.species) + for c in cov.keys(): + cv[self.indexmap[c]] = cov[c] + else: + cv = cov + ctsurf.surf_setcoverages(self.__surf_id, array(cv, 'd')) + + def ratesOfProgress(self): + """Rates of progress for all surface reactions [kmol/m^2-s].""" + return ctsurf.surfkin_getratesofprogress(self.__surf_id) + + def netProductionRates(self): + """Net production rates for all bulk and surface species. + + The results are returned as a tuple of 3 arrays for the species in + bulk phase 1, bulk phase 2, and the surface phase, respectively. + """ + n1 = self.p1_nsp + n2 = self.p2_nsp + ns = self.nSpecies() + ntot = n1 + n2 + ns + sdot = ctsurf.surfkin_getsdot(self.__surf_id, ntot) + return (sdot[:n1], sdot[n1:n1+n2], sdot[n1+n2:]) + + def integrate(self, dt): + """Integrate the surface site-balance equations for time dt + with fixed bulk compositions.""" + ctsurf.surfkin_integrate(self.__surf_id, dt) + + def _index(self, sp): + """Location of species object 'sp' in the solution array.""" + if sp.phase == self.p1: + return sp.index + elif sp.phase == self.p2: + return sp.index + self.p1_nsp + elif sp.phase == self: + return sp.index + self.p1_nsp + self.p2_nsp + + def _uconc(self, n): + """Return the concentration conversion factor to SI for the + species with index n.""" + if n < self.p1_nsp + self.p2_nsp: + return self._uconc3 + else: + return self._uconc2 + + def isBulkSpecies(self, n): + """Return 1 if species n is a bulk species, and 0 if it is a + surface species.""" + if n < self.p1_nsp + self.p2_nsp: + return 1 + else: + return 0 + + def _bulkReactants(self, reactants): + """Given a list of reactant objects, return a list of those that + are bulk species.""" + rb = [] + for r in reactants: + if hasattr(r,'weight'): + rb.append(r) + return rb + + def _surfReactants(self, reactants): + """Given a list of reactant objects, return a list of those that + are surface species.""" + rs = [] + for r in reactants: + if not hasattr(r,'weight'): + rs.append(r) + return rs + + + def write_C(self, mech): + + writer = SurfWriter.SurfWriter(self, mech) + for d in self.rxndata: + rindex, rstoich, rorder, pindex, pstoich, rate = d + writer.write_ROP(rindex, rstoich, rorder, + pindex, pstoich, rate) + writer.write_sdot(rindex, rstoich, pindex, pstoich) + writer.write_update_rate(rate) + writer.nrxns += 1 + writer.write() + + + def addReaction(self, r): + """Add a reaction to the surface mechanism.""" + self._freeze_species = 1 + + self.rxns.append(r) + + + # check balance + for e in self.elements: + n = 0 + for rr in r.reactants: + n += rr.nAtoms(e) + for pp in r.products: + n -= pp.nAtoms(e) + if n <> 0: + raise CanteraError('Reaction does not balance. \nElement '+ + e+' out of balance by '+`n`+' atoms.') + + rmap = {} + rindex2object = {} + for rr in r.reactants: + if rmap.has_key(rr): + rmap[rr][1] += 1 + rmap[rr][2] += 1 + else: + rmap[rr] = [self._index(rr),1,1] + rindex2object[self._index(rr)] = rr + + pmap = {} + for pp in r.products: + if pmap.has_key(pp): + pmap[pp][1] += 1 + pmap[pp][2] += 1 + else: + pmap[pp] = [self._index(pp),1,1] + + rinfo = array(rmap.values(),'i') + pinfo = array(pmap.values(),'i') + + rindex = rinfo[:,0] + for rr in r.order.keys(): + loc = self._index(rr) + for n in range(len(rindex)): + if loc == rindex[n]: + rinfo[n,2] = r.order[rr] + + rstoich = rinfo[:,1] + rorder = rinfo[:,2] + pindex = pinfo[:,0] + pstoich = pinfo[:,1] + + funit = 1.0 + fb = 0.0 + + + # sticking probabilities are dimensionless, and are limited to + # reactions with one bulk reactant. The reaction rate is + # computed as the sticking probability multiplied by the + # incident flux, times the coverages of all surface species + # reactants. + + if r.stick: + rb = self._bulkReactants(r.reactants) + if len(rb) <> 1: + raise CanteraError( + 'A sticking probability can only be specified if there'+ + ' is exactly one bulk-phase reactant') + wt = rb[0].weight + + # mean speed / sqrt(T) + cfactor = math.sqrt(8.0*constants.GasConstant/(constants.Pi * wt)) + + for n in range(len(rindex)): + if not self.isBulkSpecies(rindex[n]): + sz = rindex2object[rindex[n]].size + funit /= math.pow(self.s0/sz, rorder[n]) + preExp = funit*r.stick[0]*cfactor/4.0 + b = r.stick[1] + 0.5 + e = r.stick[2] + r.rate = [preExp, b, e] + + + # Reaction rates are specified using several different + # conventions. Here the various possibilities are converted + # into rates per unit area, with reactant amounts specified in + # concentrations. + + else: + for n in range(len(rindex)): + if self.isBulkSpecies(rindex[n]): + if r.type.bulk == 'conc': + funit /= (math.pow(self._uconc3,rorder[n])) + elif r.type.bulk == 'bar': + funit *= math.pow(1.e-5 + * constants.GasConstant,rorder[n]) + fb += rorder[n] + else: + if r.type.surf == 'conc': + funit /= (math.pow(self._uconc2,rorder[n])) + elif r.type.surf == 'cov': + sz = rindex2object[rindex[n]].size + funit /= math.pow(self.s0/sz, rorder[n]) + + if r.type.result == 'per_area': + funit *= self._uconc2 + elif r.type.result == 'per_site': + print 'multiplying A by ',self.s0 + funit *= self.s0 + + # modify the pre-exponential term, and the temperature + # exponent + r.rate[0] *= funit + print 'A = ',r.rate[0] + r.rate[1] += fb + + + rate = array(r.rate,'d') + + # convert the activation energy to K + rate[2] *= self._ue + + self.rxndata.append((rindex, rstoich, rorder, pindex, pstoich, rate)) + + ctsurf.surfkin_addreaction(self.__surf_id, + len(rindex), + array(rindex,'i'), + array(rstoich,'i'), + array(rorder,'i'), + len(pindex), + array(pindex,'i'), + array(pstoich,'i'), + len(r.rate), rate) + diff --git a/Cantera/python/Cantera/set.py b/Cantera/python/Cantera/set.py new file mode 100755 index 000000000..aacdc682e --- /dev/null +++ b/Cantera/python/Cantera/set.py @@ -0,0 +1,58 @@ +from exceptions import CanteraError + +def set(a, **options): + + pval = None + hval = None + uval = None + sval = None + vval = None + np = 0 + + for o in options.keys(): + val = options[o] + if o == 'Temperature' or o == 'T': + a.setTemperature(val) + elif o == 'Density' or o == 'Rho': + a.setDensity(val) + vval = 1.0/val + elif o == 'V': + a.setDensity(1.0/val) + vval = val + elif o == 'MoleFractions' or o == 'X': + a.setMoleFractions(val) + elif o == 'MassFractions' or o == 'Y': + a.setMassFractions(val) + elif o == 'Pressure' or o == 'P': + pval = val + np = np + 1 + elif o == 'Enthalpy' or o == 'H': + hval = val + np = np + 1 + elif o == 'IntEnergy' or o == 'U': + uval = val + np = np + 1 + elif o == 'Entropy' or o == 'S': + sval = val + np = np + 1 + else: + raise CanteraError('unknown property: '+o) + + if np == 1: + if pval: + a.setPressure(pval) + + if np >= 2: + if pval and hval: + a.setState_HP(hval,pval) + elif uval and vval: + a.setState_UV(uval,vval) + elif sval and pval: + a.setState_SP(sval,pval) + elif sval and vval: + a.setState_SV(sval,vval) + else: + raise CanteraError('unimplemented property pair') + + + diff --git a/Cantera/python/Cantera/solids.py b/Cantera/python/Cantera/solids.py new file mode 100755 index 000000000..9123e57b5 --- /dev/null +++ b/Cantera/python/Cantera/solids.py @@ -0,0 +1,14 @@ +"""This module defines classes and functions used to model gas mixtures.""" + +from solution import Solution + +def Solid(import_file="", id="", + kmodel=1, transport=None): + return Solution(import_file=import_file, + thermo_db="", + eos=0, + id=id, + kmodel=kmodel, + trmodel=transport, + validate=0) + diff --git a/Cantera/python/Cantera/solution.py b/Cantera/python/Cantera/solution.py new file mode 100755 index 000000000..9bf059619 --- /dev/null +++ b/Cantera/python/Cantera/solution.py @@ -0,0 +1,71 @@ +""" +""" + +import string +import os + +from constants import * +from ThermoPhase import ThermoPhase +from Kinetics import Kinetics +from Transport import Transport +import XML +import _cantera + +class Solution(ThermoPhase, Kinetics, Transport): + """ + A class for chemically-reacting solutions. + + Instances can be created to represent any type of solution -- a + mixture of gases, a liquid solution, or a solid solution, for + example. + + Class Solution derives from classes ThermoPhase, Kinetics, and + Transport. It defines very few methods of its own, and is + provided largely for convenience, so that a single object can be + used to compute thermodynamic, kinetic, and transport properties + of a solution. Functions like IdealGasMix and others defined in + module gases return objects of class Solution. + + """ + + def __init__(self, src="", root=None, + transport = "None", thermo_db = "", + transport_db = ""): + + self.ckin = 0 + self._owner = 0 + self.verbose = 1 + + fn = string.split(src,'#') + fn = fn[0] + fname = os.path.basename(fn) + ff = os.path.splitext(fname) + if ff[1] <> '.xml' and ff[1] <> '.ctml': + ctmodule.ck2ctml(src, thermo_db, transport_db, ff[0]+'.xml', + ff[0]) + src = ff[0]+'.xml' + + # get the 'phase' element + s = XML.find_XML(src=src, root=root, name="phase") + + # get the equation of state model + ThermoPhase.__init__(self, xml_phase=s) + + # get the kinetics model + Kinetics.__init__(self, xml_phase=s, phases=[self]) + + Transport.__init__(self, xml_phase=s, phase=self, + model = transport, loglevel=4) + + #self.setState_TP(300.0, OneAtm) + + + def __repr__(self): + return _cantera.phase_report(self._phase_id, self.verbose) + + + def __del__(self): + Transport.__del__(self) + Kinetics.__del__(self) + ThermoPhase.__del__(self) + diff --git a/Cantera/python/Cantera/solve.py b/Cantera/python/Cantera/solve.py new file mode 100755 index 000000000..d9012e583 --- /dev/null +++ b/Cantera/python/Cantera/solve.py @@ -0,0 +1,109 @@ +# +# Solve a steady-state problem by combined damped Newton +# iteration and time integration. +# + +from Cantera import CanteraError +from Numeric import array +import math, types + +def solve(sim, loglevel = 0, refine_grid = 1, plotfile = '', savefile = ''): + """ + Solve a steady-state problem by combined damped Newton iteration + and time integration. + """ + + new_points = 1 + + # get options + dt = sim.option('timestep') + ft = sim.option('ftime') + + # sequence of timesteps + _steps = sim.option('nsteps') + if type(_steps) == types.IntType: _steps = [_steps] + + len_nsteps = len(_steps) + dt = sim.option('timestep') + + ll = loglevel + soln_number = -1 + max_timestep = sim.option('max_timestep') + + sim.collect() + + # loop until refine adds no more points + while new_points > 0: + + istep = 0 + nsteps = _steps[istep] + + # loop until Newton iteration succeeds + ok = 0 + while ok == 0: + + # Try to solve the steady-state problem by damped + # Newton iteration. + try: + if loglevel > 0: + print 'Attempt Newton solution of ',\ + 'steady-state problem...', + sim.newton_solve(loglevel-1) + + if loglevel > 0: + print 'success.\n\n' + print '%'*79+'\n' + print 'Problem solved on ',sim.npts,' point grid(s).\n' + print '%'*79+'\n' + ok = 1 + soln_number += 1 + sim.finish() + + + except CanteraError: + + # Newton iteration failed. + if loglevel > 0: print '\n' + + # Take nsteps time steps, starting with step size + # dt. The final dt may be smaller than the initial + # value if one or more steps fail. + + if loglevel == 1: + print 'Take',nsteps,' timesteps', + + dt = sim.py_timeStep(nsteps,dt,loglevel=ll-1) + if loglevel == 1: print dt, math.log10(sim.ssnorm()) + istep += 1 + if istep >= len_nsteps: + nsteps = _steps[-1] + dt *= 2.0 + else: + nsteps = _steps[istep] + if dt > max_timestep: dt = max_timestep + + + + # A converged solution was found. Save and/or plot it, then + # check whether the grid should be refined. + + # Add the solution to the plot file + if plotfile: + sim.outputTEC(plotfile,"flame","p"+`sim.npts`,append=soln_number) + + # If a filename has been specified for a save file, add + # the solution to this file + if savefile: + sim.save(savefile, soln_name+'_'+`sim.npts`+'_points') + + if loglevel > 2: sim.show() + + if refine_grid: + + # Call refine to add new points, if needed + new_points = sim.refine(loglevel = loglevel - 1) + + else: + new_points = 0 + + diff --git a/Cantera/python/Cantera/stoich.py b/Cantera/python/Cantera/stoich.py new file mode 100755 index 000000000..8fdf4b98d --- /dev/null +++ b/Cantera/python/Cantera/stoich.py @@ -0,0 +1,46 @@ +from Cantera import exceptions +from Numeric import array +from Cantera.elements import elementMoles + +def det3(A): + """Determinant of a 3x3 matrix.""" + return (A[0,0]*(A[1,1]*A[2,2] - A[1,2]*A[2,1]) + - A[0,1]*(A[1,0]*A[2,2] - A[1,2]*A[2,0]) + + A[0,2]*(A[1,0]*A[2,1] - A[2,0]*A[1,1])) + +def stoich_fuel_to_oxidizer(mix, fuel, oxidizer): + """Fuel to oxidizer ratio for stoichiometric combustion. + + This function only works for fuels composed of carbon, hydrogen, + and/or oxygen. The fuel to oxidizer ratio is returned that results in + + """ + + # fuel + mix.setMoleFractions(fuel) + f_carbon = elementMoles(mix, 'C') + f_oxygen = elementMoles(mix, 'O') + f_hydrogen = elementMoles(mix, 'H') + + #oxidizer + mix.setMoleFractions(oxidizer) + o_carbon = elementMoles(mix, 'C') + o_oxygen = elementMoles(mix, 'O') + o_hydrogen = elementMoles(mix, 'H') + + B = array([f_carbon, f_hydrogen, f_oxygen],'d') + A = array([[1.0, 0.0, -o_carbon], + [0.0, 2.0, -o_hydrogen], + [2.0, 1.0, -o_oxygen]], 'd') + + num = array(A,'d') + num[:,2] = B + r = det3(num)/det3(A) + if r <= 0.0: + raise CanteraError('negative or zero computed stoichiometric fuel/oxidizer ratio!') + return 1.0/r + +if __name__ == "__main__": + g = GRI30() + print stoich_fuel_to_oxidizer(g, 'CH4:1', 'O2:1') + diff --git a/Cantera/python/Cantera/tecplot.py b/Cantera/python/Cantera/tecplot.py new file mode 100755 index 000000000..f430c96f1 --- /dev/null +++ b/Cantera/python/Cantera/tecplot.py @@ -0,0 +1,42 @@ +"""TECPLOT utilities.""" + +def write_TECPLOT_zone(fname, title, zone, names, npts, nvar, append, data): + """ + Write a TECPLOT zone specification to generate line plots of multiple + variables. + fname -- file name + title -- plot title + zone -- zone name + names -- sequence of variable names + npts -- number of data points + nvar -- number of variables + append -- if > 0, append to plot file, otherwise overwrite + data -- object to generate plot data. This object must have a + method 'value', defined so that data.value(j,n) returns + the value of variable n at point j. + """ + + from Numeric import array, shape + + if append > 0: + f = open(fname,'a') + else: + f = open(fname,'w') + f.write('TITLE = "' + title + '"\n') + f.write('VARIABLES = \n') + for nm in names: + f.write('"'+nm+'"\n') + f.write('ZONE T="'+zone+'"\n') + f.write(' I='+`npts`+',J=1,K=1,F=POINT\n') + f.write('DT=(') + for n in range(nvar): + f.write('SINGLE ') + f.write(')\n') + for j in range(npts): + for n in range(nvar): + f.write('%10.4e ' % data[j,n]) + f.write('\n') + f.close() + + + diff --git a/Cantera/python/Cantera/units.py b/Cantera/python/Cantera/units.py new file mode 100755 index 000000000..307ac2360 --- /dev/null +++ b/Cantera/python/Cantera/units.py @@ -0,0 +1,63 @@ +from constants import Avogadro, GasConstant + +kmol = 1.0 +mol = 1.e-3 +molecule = kmol/Avogadro + +m = 1.0 +cm = 0.01 +mm = 0.001 + +m2 = 1.0 +cm2 = 1.e-4 +mm2 = 1.e-6 +A2 = 1.e-20 + +m3 = 1.0 +cm3 = 1.e-6 +mm3 = 1.e-9 + +J = 1.0 +kJ = 1000.0 +cal = 4.184 +kcal = 4184.0 + +K = 1.0 + +kJ_per_mol = kJ/mol +cal_per_mol = cal/mol +kcal_per_mol = kcal/mol + +mol_per_cm2 = mol/cm/cm +molecule_per_cm2 = molecule/cm/cm + +# pressure +Pa = 1.0 +kPa = 1000.0 +atm = 1.01325e5 +bar = 1.0e5 +torr = atm/760.0 + +# mass +kg = 1.0 +gm = 1000.0 + +# mass flux +kg_per_m2_per_s = 1.0 +g_per_cm2_per_s = gm/(cm*cm) + +_lengthdict = {'m':m, 'cm':cm, 'mm':mm} +def length(u): + return _lengthdict[u] + +_moldict = {'kmol':kmol, 'mol':mol, 'molecule':molecule} +def mole(u): + return _moldict[u] + +_eadict = {'kJ_per_mol':kJ_per_mol, + 'kcal_per_mol':kcal_per_mol, + 'cal_per_mol':cal_per_mol, + 'K':GasConstant} + +def actEnergy(u): + return _eadict[u]/GasConstant diff --git a/Cantera/python/Makefile.in b/Cantera/python/Makefile.in new file mode 100755 index 000000000..1f03fc5c1 --- /dev/null +++ b/Cantera/python/Makefile.in @@ -0,0 +1,31 @@ +#/bin/sh +############################################################### +# $Author$ +# $Date$ +# $Revision$ +# +# Copyright 2001 California Institute of Technology +# See file License.txt for licensing information +# +############################################################### + +all: refresh + @PYTHON_CMD@ setup.py build + +refresh: $(LIB_DEPS) + touch src/pycantera.cpp + +install: + @PYTHON_CMD@ setup.py install + +clean: + @PYTHON_CMD@ setup.py clean + cd src; rm -f *.o + +depends: + echo '-' + +# end of file + + + diff --git a/Cantera/python/examples/flame1.py b/Cantera/python/examples/flame1.py new file mode 100755 index 000000000..98c0f0151 --- /dev/null +++ b/Cantera/python/examples/flame1.py @@ -0,0 +1,79 @@ +######################################################## +# +# A burner-stabilized hydrogen/oxygen flame +# +######################################################## + +# note that SI units (m, kg, J, kmol) are used, not cgs units. +import os +from Cantera import units +from Cantera.flame import * + +gas = IdealGasMix(src = 'h2o2.xml', transport='Mix') + +# create a burner-stabilized flame in the domain z = 0 to z = 20 cm, +# define the fuel to be pure hydrogen, and the oxidizer to be +# oxygen diluted in argon. + +flame = BurnerFlame( + domain = (0, 0.4), + fuel = 'H2:1', + oxidizer = 'O2:1, AR:7', + gas = gas, + grid = [0, 0.02, 0.04, 0.06, 0.08, 0.1, 0.15, 0.2, 0.49, 0.5] + ) + +# Set some parameters. +# mdot -- mass flow rate in kg/m^2/s +# T0 -- burner temperature +# pressure -- P in pascals +# tol -- (relative, absolute) +# timesteps -- ( [sequence of number of steps], initial step size ) +# refine -- (max size ratio between adj cells, slope parameter, +# curvature parameter) +# jac_age -- (steady age, transient age) + +flame.set(mdot = 0.04, + equiv_ratio = 0.9, + T_burner = 373.0, + pressure = 0.05 * units.atm, + tol = (1.e-5, 1.e-12), + timesteps = ([1,2,5,10,20], 1.e-5), + refine = (2.0, 0.8, 0.9), + jac_age = (20, 10), + ) + + +# if you want to start from a previously saved solution, uncomment +# this line and modify as necessary +#flame.restore(src = 'h2o2_flame1.xml', solution = 'energy_1') + + +# turn the energy equation off (default) +flame.set(energy = 'off') + +# solve the flame, with output level 1 +flame.solve(1) + +# save the solution +flame.save('no_energy','solution with the energy equation disabled', + 'h2o2_flame1.xml') + +# turn the energy equation on, and change the grid refinement parameters +flame.set(energy = 'on', refine = (2.0, 0.05, 0.1)) + +# solve it again +flame.solve(1) + +# save it to the same file, but with a different solution id. +flame.save('energy','solution with the energy equation enabled', + 'h2o2_flame1.xml') + +# write plot files +flame.plot(plotfile = 'flame1.dat', title = 'H2/O2 flame', fmt = 'TECPLOT') +flame.plot(plotfile = 'flame1.csv', title = 'H2/O2 flame', fmt = 'EXCEL') +print ' TECPLOT file flame1.dat and Excel CSV file flame1.csv written' +print ' Directory: '+os.getcwd() + +# show statistics -- number of Jacobians, etc. +flame.showStatistics() diff --git a/Cantera/python/examples/flame2.py b/Cantera/python/examples/flame2.py new file mode 100755 index 000000000..ec962cbcb --- /dev/null +++ b/Cantera/python/examples/flame2.py @@ -0,0 +1,49 @@ +# +# rich methane/air flame +# +import os +from Cantera.flame import * +from Cantera import units +#from Cantera.gases import H_O_AR + + +gas = GRI30(transport = 'Default') + +flame = BurnerFlame( + domain = (0, 0.01), + fuel = 'CH4:1', + oxidizer = 'O2:1, N2:3.76', + gas = gas, + grid = [0.0, 0.0025, 0.005, 0.0075, 0.0099, 0.01] + ) + +flame.set(mdot = 0.04, + equiv_ratio = 1.3, + T_burner = 373.7, + pressure = 1.0 * units.atm, + tol = (1.e-4, 1.e-9), + rtol = (1.e-5, 1.e-5), + timesteps = ([1,2,5,10,20], 1.e-5), + refine = (10.0, 1, 1), + jac_age = (50, 50), + nsteps = [1,2,5,10,20] + ) + +flame.set(energy = 'off') +flame.solve(1) +flame.save('no_energy','solution with the energy equation disabled', + 'ch4_flame1.xml') + +flame.set(energy = 'on', refine = (3.0, 0.1, 0.2)) +flame.solve(1) + +flame.save('energy','solution with the energy equation enabled', + 'ch4_flame1.xml') + +# write plot files +flame.plot(plotfile = 'flame2.dat', title = 'methane/air flame', + fmt = 'TECPLOT') +flame.plot(plotfile = 'flame2.csv', fmt = 'EXCEL') +print ' Solution written to TECPLOT file flame2.dat and Excel CSV file flame2.csv' +print ' Directory: '+os.getcwd() +flame.showStatistics() diff --git a/Cantera/python/examples/isentropic.py b/Cantera/python/examples/isentropic.py new file mode 100755 index 000000000..976e7a060 --- /dev/null +++ b/Cantera/python/examples/isentropic.py @@ -0,0 +1,79 @@ +from Cantera import * +from Numeric import zeros +import math + + +def soundspeed(gas): + """The speed of sound. Assumes an ideal gas.""" + + # if gas.isIdealGas(): + gamma = gas.cp_mass()/gas.cv_mass() + return math.sqrt(gamma * GasConstant + * gas.temperature() / gas.meanMolecularWeight() ) + #else: + # raise "non-ideal not implemented." + + + +def isentropic(g = None): + """ + ISENTROPIC isentropic, adiabatic flow example + + In this example, the area ratio vs. Mach number curve is + computed. If a gas object is supplied, it will be used for the + calculations, with the stagnation state given by the input gas + state. Otherwise, the calculations will be done for a 10:1 + hydrogen/nitrogen mixture with stagnation T0 = 1200 K, P0 = 10 + atm. + + """ + + if g == None: + gas = IdealGasMix('gri30.xml') + gas.setState_TPX(1200.0,10.0*OneAtm,'H2:1,N2:0.1') + else: + gas = g + + + # get the stagnation state parameters + s0 = gas.entropy_mass() + h0 = gas.enthalpy_mass() + p0 = gas.pressure() + + mdot = 1 # arbitrary + amin = 1.e14 + + data = zeros((200,4),'d') + + # compute values for a range of pressure ratios + for r in range(200): + p = p0*(r+1)/201.0 + + # set the state using (p,s0) + gas.setState_SP(s0,p) + + h = gas.enthalpy_mass() + rho = gas.density() + + v2 = 2.0*(h0 - h) # h + V^2/2 = h0 + v = math.sqrt(v2) + area = mdot/(rho*v); # rho*v*A = constant + if area < amin: amin = area + data[r,:] = [area, v/soundspeed(gas), gas.temperature(), p/p0] + + data[:,0] /= amin + return data + + + +if __name__ == "__main__": + print isentropic.__doc__ + data = isentropic() + print 'area ratio, Mach number, temperature, pressure ratio' + print data + + + + + + diff --git a/Cantera/python/examples/reactor1.py b/Cantera/python/examples/reactor1.py new file mode 100644 index 000000000..53de392a3 --- /dev/null +++ b/Cantera/python/examples/reactor1.py @@ -0,0 +1,34 @@ +""" + + Constant-pressure, adiabatic kinetics simulation. + +""" +from Cantera import * +from Cantera.Reactor import * +from Cantera.Func import * +from Cantera import rxnpath + +gri3 = GRI30() + +gri3.setState_TPX(1001.0, OneAtm, 'H2:2,O2:1,N2:4') +r = Reactor(gri3) + +env = Reservoir(Air()) + +# Define a wall between the reactor and the environment, and +# make it flexible, so that the pressure in the reactor is held +# at the environment pressure. +w = Wall(r,env) +w.set(K = 1.0e6) # set expansion parameter. dV/dt = K(P_1 - P_2) +w.set(A = 1.0) + +time = 0.0 +for n in range(100): + time += 1.e-5 + r.advance(time) + env.advance(time) + print '%10.3e %10.3f %10.3f %14.6e' % (r.time(), r.temperature(), + r.pressure(), r.intEnergy_mass()) + +#print gri3 + diff --git a/Cantera/python/examples/reactor2.py b/Cantera/python/examples/reactor2.py new file mode 100644 index 000000000..8e856f5b6 --- /dev/null +++ b/Cantera/python/examples/reactor2.py @@ -0,0 +1,89 @@ +""" + +This script simulates the following situation. A closed cylinder with +volume 2 m^3 is divided into two equal parts by a massless piston that +moves with speed proportional to the pressure difference between the +two sides. It is initially held in place in the middle. One side is +filled with 1000 K argon at 20 atm, and the other with a combustible +500 K methane/air mixture at 0.1 atm (phi = 1.1). At t = 0 the piston +is released and begins to move due to the large pressure difference, +compressing and heating the methane/air mixture, which eventually +explodes. At the same time, the argon cools as it expands. The piston +is adiabatic, but some heat is lost through the outer cylinder walls +to the environment. + +Note that this simulation, being zero-dimensional, takes no account of +shock wave propagation. It is somewhat artifical, but nevertheless +instructive. + +""" + + +from Cantera import * +from Cantera.Reactor import * +from Cantera.Func import * + +#----------------------------------------------------------------------- +# First create each gas needed, and a reactor or reservoir for each one. +#----------------------------------------------------------------------- + +# create an argon gas object and set its state. This function is +# defined in module Cantera.gases, as are functions 'Air()', and +# 'GRI30()' + +ar = Argon() +ar.setState_TPX(1000.0, 20.0*OneAtm, 'AR:1') + +# create a reactor to represent the side of the cylinder filled with argon +r1 = Reactor(ar) + + +# create a reservoir for the environment, and fill it with air. +env = Reservoir(Air()) + + +# use GRI-Mech 3.0 for the methane/air mixture, and set its initial state +gri3 = GRI30() + +gri3.setState_TPX(500.0, 0.1*OneAtm, 'CH4:1.1, O2:2, N2:7.52') + +# create a reactor for the methane/air side +r2 = Reactor(gri3) + + +#--------------------------------------------------------------------- +# Now couple the reactors by defining common walls that may move (a piston) +# or conduct heat +#---------------------------------------------------------------------- + +# add a flexible wall (a piston) between r2 and r1 +w = Wall(r2, r1) +w.set(area = 2.0, K=1.1e-4) + + +# heat loss to the environment. Heat loss always occur through walls, +# so we create a wall separating r1 from the environment, give it a +# non-zero area, and specify the overall heat transfer coefficient +# through the wall. +w2 = Wall(r1, env) +w2.set(area = 0.5, U=100.0) + +# Now the problem is set up, and we're ready to solve it. +print 'finished setup, begin solution...' + +time = 0.0 +f = open('piston.csv','w') +writeCSV(f,['time (s)','T2 (K)','P2 (Pa)','V2 (m3)', + 'T1 (K)','P1 (Pa)','V1 (m3)']) +for n in range(300): + time += 4.e-5 + print time, r2.temperature(),n + r1.advance(time) + r2.advance(time) + writeCSV(f, [r2.time(), r2.temperature(), r2.pressure(), r2.volume(), + r1.temperature(), r1.pressure(), r1.volume()]) +f.close() +import os +print 'Output written to file piston.csv' +print 'Directory: '+os.getcwd() + diff --git a/Cantera/python/examples/rxnpath1.py b/Cantera/python/examples/rxnpath1.py new file mode 100755 index 000000000..121e60533 --- /dev/null +++ b/Cantera/python/examples/rxnpath1.py @@ -0,0 +1,52 @@ +""" + +Viewing a reaction path diagram in a web browser. + +This script uses the public webdot server at webdot.graphviz.org to +perform the rendering of the graph. You don't need to get the 'dot' +program to use this script, but you do need to be able to put your +output file where it can be served by your web server. You can either +run a local server, or mount the remote directory where your web files +are located. You could also modify this script to write the file +locally, and then upload it to your web server. + +""" + +from os.path import join +from Cantera import * +from Cantera import rxnpath + +#------------ site-specific configuration ----------------------------- + +# to view the diagram in a browser, set 'output_dir' to a directory that +# is within the document tree of your web server, and set output_url to +# the URL that accesses this directory. + +output_dir = 'd:/www/docs' +output_urldir = 'http://your.http.server/' + +#----------------------------------------------------------------------- +# these lines can be replaced by any commands that generate +# an object of a class derived from class Kinetics (such as IdealGasMix) +# in some state. +gas = GRI30() +gas.setState_TPX(2500.0, OneAtm, 'CH4:0.4, O2:1, N2:3.76') +gas.equilibrate('TP') +gas.setTemperature(500.0) + +#------------------------------------------------------------------------ + +d = rxnpath.PathDiagram(title = 'reaction path diagram following N', + bold_color = 'green') + +element = 'N' +output_file = 'rxnpath2.dot' +url = output_urldir+'/'+output_file + +# graphics format. Must be one of png, svg, gif, or jpg +fmt = 'svg' + +rxnpath.write(gas, element, join(output_dir, output_file), d) +rxnpath.view(url, fmt) + + diff --git a/Cantera/python/examples/rxnpath2.py b/Cantera/python/examples/rxnpath2.py new file mode 100755 index 000000000..419c738cd --- /dev/null +++ b/Cantera/python/examples/rxnpath2.py @@ -0,0 +1,67 @@ +""" + +Viewing a reaction path diagram in a web browser. + +This script uses the public webdot server at webdot.graphviz.org to +perform the rendering of the graph. You don't need to get the 'dot' +program to use this script, but you do need to be able to put your +output file where it can be served by your web server. You can either +run a local server, or mount the remote directory where your web files +are located. You could also modify this script to write the file +locally, and then upload it to your web server. + +""" + +from os.path import join +from Cantera import * +from Cantera import rxnpath +import os + +#------------ site-specific configuration ----------------------------- + +# Set 'output_dir' to a directory that is within the document tree of +# your web server, and set output_url to the URL that accesses this +# directory. + +# output_dir = /var/www/html # linux/apache default + +output_dir = 'c:/cygwin/var/www/htdocs' +output_urldir = 'http://blue.caltech.edu' + +#----------------------------------------------------------------------- +# these lines can be replaced by any commands that generate +# an object of a class derived from class Kinetics (such as IdealGasMix) +# in some state. +gas = GRI30() +gas.setState_TPX(2500.0, OneAtm, 'CH4:2, O2:1, N2:3.76') +gas.equilibrate('TP') +x = gas.moleFractions() +gas.setMassFractions(x) + +#------------------------------------------------------------------------ + +# To control diagram attributes, create an instance of +# class rxnpath.PathDiagram and set the properties as desired. +# Then pass it as the last argument to rxnpath.write + +d = rxnpath.PathDiagram(title = 'reaction path diagram following N', + bold_color = 'orange', + threshold = 0.001) + +# element to follow +element = 'N' + +output_file = 'rxnpath2.dot' +url = output_urldir+'/'+output_file + +# graphics format. Must be one of png, svg, gif, or jpg +fmt = 'svg' + +print 'writing dot file',output_file+'...' +#rxnpath.write(gas, element, join(output_dir, output_file), d) +rxnpath.write(gas, element, output_file, d) +os.system('scp '+output_file+' blue:/var/www/html') +print 'generating browser view...' +rxnpath.view(url, fmt) + + diff --git a/Cantera/python/examples/stflame1.py b/Cantera/python/examples/stflame1.py new file mode 100644 index 000000000..b79501a69 --- /dev/null +++ b/Cantera/python/examples/stflame1.py @@ -0,0 +1,88 @@ +""" + +A hydrogen/oxygen flame stabilized in an axisymmetric stagnation +flow. + +""" + +from Cantera import units +from Cantera.flame import * + +# Import the hydrogen/oxygen reaction mechanism +# The input file is in directory 'data/inputs'. + +gas = IdealGasMix(src = 'h2o2.xml', transport='Mix') + + +# Create a stagnation-point flame in the domain z = 0 (the inlet) to z +# = 20 cm (the surface). The fuel stream will be pure hydrogen, +# and the oxidizer stream oxygen diluted in argon. + +flame = StagnationFlame( + domain = (0, 0.2), + fuel = 'H2:1', + oxidizer = 'O2:1, AR:7', + gas = gas, + grid = [0, 0.02, 0.04, 0.06, 0.08, 0.1, 0.15, 0.2] # initial grid + ) + + +# Set some parameters. +# mdot -- mass flow rate in kg/m^2/s +# T_burner -- burner temperature +# T_surface -- surface temperature +# pressure -- P in pascals +# tol -- (relative, absolute) +# timesteps -- ( [sequence of number of steps], initial step size ) +# refine -- (max size ratio between adj cells, slope parameter, +# curvature parameter) +# jac_age -- (steady age, transient age) + +flame.set(mdot = 0.1, + equiv_ratio = 1.2, + T_burner = 373.0, + T_surface = 600.0, + pressure = 0.05 * units.atm, + tol = (1.e-7, 1.e-9), + timesteps = ([1,2,5,10], 1.e-5), + refine = (2.0, 0.5, 0.5), + jac_age = (20, 10), + ) + + +# if you want to start from a previously saved solution, uncomment +# this line and modify as necessary +# flame.restore(src = 'h2o2_flame1.xml', solution = 'energy_1') + +# turn the energy equation off (default) +flame.set(energy = 'off') + +# solve the flame, with output level 1 +flame.solve(1) +flame.show() + +# save the solution +flame.save('no_energy','solution with the energy equation disabled', + 'h2o2_stflame1.xml') + +# turn the energy equation on, and change the grid refinement parameters +flame.set(energy = 'on', refine = (2.0, 0.1, 0.2)) + +# solve it again +flame.solve(1) + +# save it to the same file, but with a different solution id. +flame.save('energy','solution with the energy equation enabled', + 'h2o2_stflame1.xml') + +# write a TECPLOT plot file +flame.plot(plotfile = 'stflame1.dat', title = 'H2/O2 flame', fmt = 'TECPLOT') + +# write an Excel CSV file +flame.plot(plotfile = 'stflame1.csv', title = 'H2/O2 flame', fmt = 'EXCEL') + +print 'TECPLOT file stflame1.dat and Excel CSV file stflame1.csv written' + +# show statistics -- number of Jacobians, etc. +flame.showStatistics() + diff --git a/Cantera/python/examples/stflame2.py b/Cantera/python/examples/stflame2.py new file mode 100644 index 000000000..bb7cc903e --- /dev/null +++ b/Cantera/python/examples/stflame2.py @@ -0,0 +1,84 @@ +""" + A stagnation-point flame using GRI-Mech 3.0. + + In this script, a hydrogen / oxygen / argon flame is first solved, + and then used as the starting estimate for a methane / oxygen / argon + flame. + +""" + +from Cantera.flame import * +from Cantera import units + +# start with only a hydrogen/oxygen mechanism +gas = IdealGasMix('h2o2.xml', transport='Mix') + +flame = StagnationFlame( + domain = (0, 0.02), + fuel = 'H2:1', + oxidizer = 'O2:1, AR:4', + gas = gas, + grid = [0.0, 0.0025, 0.005, 0.0075, 0.01, 0.016, 0.02] + ) + +flame.set(mdot = 0.4, + equiv_ratio = 0.9, + T_burner = 373.7, + T_surface = 600.0, + pressure = 1.0 * units.atm, + tol = (1.e-7, 1.e-11), + timesteps = ([1,2,5,10,20], 1.e-5), + refine = (10.0, 1.0, 1.0), + jac_age = (50, 50), + ) + +# first solve the fixed-temperature problem +flame.set(energy = 'off') +flame.solve(1) + +# now enable the energy equation, and specify that rough +# grid refinement should be done +flame.set(energy = 'on', refine = (3.0, 0.9, 0.9)) +flame.solve(1) + +flame.save('energy','h2/o2 soln with energy equation', 'h2.xml') + + +#----------------------------------------------------------- + +# Now construct the methane flame using GRI-Mech 3.0 +gas2 = GRI30(transport = 'Mix') + +flame2 = StagnationFlame( + domain = (0, 0.02), + fuel = 'CH4:1', + oxidizer = 'O2:1, AR:4', + gas = gas2, + grid = [0.0, 0.0025, 0.005, 0.0075, 0.01, 0.016, 0.02] + ) + +flame2.set(mdot = 0.8, + equiv_ratio = 0.9, + T_burner = 373.7, + T_surface = 600.0, + pressure = 1.0 * units.atm, + tol = (1.e-7, 1.e-11), + timesteps = ([1,2,5], 1.e-5), + refine = (2.0, 0.1, 0.2), + jac_age = (50, 50), + ) + +# Use the hydrogen results as the starting guess. +flame2.restore(src = 'h2.xml', solution = 'energy') + +flame2.set(energy = 'on') +flame2.solve(1) +flame2.show() + +# write plot files +flame2.plot(plotfile = 'stflame2.dat', title = 'methane/air flame', + fmt = 'TECPLOT') +flame2.plot(plotfile = 'stflame2.csv', fmt = 'EXCEL') +print 'Solution written to TECPLOT file stflame2.dat and Excel CSV file stflame2.csv' +flame2.showStatistics() + diff --git a/Cantera/python/setup.py b/Cantera/python/setup.py new file mode 100755 index 000000000..e1c5f35ef --- /dev/null +++ b/Cantera/python/setup.py @@ -0,0 +1,41 @@ +#!/usr/bin/python2 + +from distutils.core import setup, Extension + +libs = [] +import sys +platform = sys.platform + +if platform == "win32": + libs = ["cantera14"] +else: + libs = ["ct14", "zeroD","oneD","converters", "transport", + "cantera","recipes","ctlapack", + "ctblas", "ctmath", "cvode", "stdc++", "g2c", "m"] + + +#if sys.argv[1] == 'install': +# import time +# f = open('_pydate.py','w') +# f.write('date = '+`time.time()`) +# f.close() + +setup(name="Cantera", + version="1.4", + description="The Cantera Python Interface", + long_description=""" + """, + author="Prof. D. G. Goodwin, Caltech", + author_email="dgoodwin@caltech.edu", + url="http://www.cantera.org", + package_dir = {'MixMaster':'../../apps/MixMaster'}, + packages = ["","Cantera","MixMaster","MixMaster.Units"], + ext_modules=[ + Extension("Cantera._cantera", + ["src/pycantera.cpp"], + include_dirs=["../../include", + "src", "../clib/src"], + library_dirs = ["../../lib"], libraries = libs) + ], + ) + diff --git a/Cantera/python/src/.cvsignore b/Cantera/python/src/.cvsignore new file mode 100644 index 000000000..57751bad9 --- /dev/null +++ b/Cantera/python/src/.cvsignore @@ -0,0 +1,2 @@ +Makefile +.depends diff --git a/Cantera/python/src/Makefile.in b/Cantera/python/src/Makefile.in new file mode 100755 index 000000000..2a68ff12f --- /dev/null +++ b/Cantera/python/src/Makefile.in @@ -0,0 +1,10 @@ +#/bin/sh +############################################################### +# $Author$ +# $Date$ +# $Revision$ +# +# Copyright 2001 California Institute of Technology +# +############################################################### + diff --git a/Cantera/python/src/cantera.def b/Cantera/python/src/cantera.def new file mode 100755 index 000000000..436c790fe --- /dev/null +++ b/Cantera/python/src/cantera.def @@ -0,0 +1,2 @@ +EXPORTS + initcantera diff --git a/Cantera/python/src/canteramodule.cpp b/Cantera/python/src/canteramodule.cpp new file mode 100755 index 000000000..5427ac409 --- /dev/null +++ b/Cantera/python/src/canteramodule.cpp @@ -0,0 +1,143 @@ +/** + * @file canteramodule.cpp + * Cantera Python Interface + * + */ + +// copyright 2001 David G. Goodwin + + +// turn off warnings about long names under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "Python.h" +#include "Cantera.h" +#include +using namespace std; + +// constants defined in the module +static PyObject *ErrorObject; +static PyObject *OneAtmos; +static PyObject *GasCon; + + +local includes +#include "pyutils.h" +#include "CtSubstance.h" +#include "CtRxnPath.h" +#include "CtReactor.h" + + +/* Function of no arguments returning new CtSubstance object */ + +static PyObject * +ct_newSubstance(PyObject *self, PyObject *args) +{ + CtSubstance *rv=0; + char* subtype; + PyObject* params; + if (!PyArg_ParseTuple(args, "sO:newSubstance", &subtype, ¶ms)) + return NULL; + if (!PySequence_Check(params)) { + PyErr_SetString(ErrorObject, + "usage: Substance('', [])"); + return NULL; + } + string stype(subtype); + if (stype == "chemkin") { + rv = newChemkinSubstance(params); + } + if ( rv == NULL ) return NULL; + return (PyObject *)rv; +} + + +static PyObject * +ct_newRxnPath(PyObject *self, PyObject *args) +{ + CtRxnPath *rv; + if (!PyArg_ParseTuple(args, ":newCtRxnPath")) + return NULL; + rv = newCtRxnPath(); + if ( rv == NULL ) return NULL; + return (PyObject *)rv; +} + +static PyObject * +ct_newReactor(PyObject *self, PyObject *args) +{ + CtReactor *rv; + char* s; + if (!PyArg_ParseTuple(args, "s:newCtReactor", &s)) + return NULL; + rv = newCtReactor(s); + if ( rv == NULL ) return NULL; + return (PyObject *)rv; +} + + + +/* List of functions defined in the module */ + +static PyMethodDef ct_methods[] = { + {"Substance", ct_newSubstance, METH_VARARGS}, + {"ReactionPath", ct_newRxnPath, METH_VARARGS}, + {"Reactor", ct_newReactor, METH_VARARGS}, + {"ChemEquil", ct_newChemEquil, METH_VARARGS}, + //{"Integrator", ct_newIntegrator, METH_VARARGS}, + {NULL, NULL} /* sentinel */ +}; + + +extern "C" { + + /* Initialization function for the module (*must* be called initcantera) */ + + DL_EXPORT(void) + initct(void) + { + PyObject *m, *d; + + CtSubstance::init(); + CtRxnPath::init(); + CtReactor::init(); + + /* Initialize the type of the new type object here; doing it here + * is required for portability to Windows without requiring C++. */ + + CtSubstance_Type.ob_type = &PyType_Type; + CtSubstance_Type.tp_dealloc = (destructor)CtSubstance_dealloc; + CtSubstance_Type.tp_getattr = (getattrfunc)CtSubstance_getattr; + CtSubstance_Type.tp_setattr = (setattrfunc)CtSubstance_setattr; + CtSubstance_Type.tp_print = (printfunc)CtSubstance_print; + + CtRxnPath_Type.ob_type = &PyType_Type; + CtRxnPath_Type.tp_dealloc = (destructor)CtRxnPath_dealloc; + CtRxnPath_Type.tp_getattr = (getattrfunc)CtRxnPath_getattr; + CtRxnPath_Type.tp_setattr = (setattrfunc)CtRxnPath_setattr; + + CtReactor_Type.ob_type = &PyType_Type; + CtReactor_Type.tp_dealloc = (destructor)CtReactor_dealloc; + CtReactor_Type.tp_getattr = (getattrfunc)CtReactor_getattr; + CtReactor_Type.tp_setattr = (setattrfunc)CtReactor_setattr; + + /* Create the module and add the functions */ + m = Py_InitModule("cantera", ct_methods); + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + ErrorObject = PyErr_NewException("cantera.error", NULL, NULL); + PyDict_SetItemString(d, "error", ErrorObject); + + // one atmosphere + OneAtmos = PyFloat_FromDouble(OneAtm); + PyDict_SetItemString(d, "OneAtm", OneAtmos); + + // gas constant + GasCon = PyFloat_FromDouble(GasConstant); + PyDict_SetItemString(d, "GasConstant", GasCon); + } +} diff --git a/Cantera/python/src/ct.def b/Cantera/python/src/ct.def new file mode 100755 index 000000000..27caa82f2 --- /dev/null +++ b/Cantera/python/src/ct.def @@ -0,0 +1,2 @@ +EXPORTS + initctphase diff --git a/Cantera/python/src/ctbndry_methods.cpp b/Cantera/python/src/ctbndry_methods.cpp new file mode 100644 index 000000000..8c6923484 --- /dev/null +++ b/Cantera/python/src/ctbndry_methods.cpp @@ -0,0 +1,94 @@ + +static PyObject* +py_bndry_new(PyObject *self, PyObject *args) +{ + int itype; + if (!PyArg_ParseTuple(args, "i:bndry_new", &itype)) + return NULL; + int iok = bndry_new(itype); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_bndry_del(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:bndry_del", &n)) + return NULL; + bndry_del(n); + return Py_BuildValue("i",0); +} + +static PyObject* +py_bndry_temperature(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:bndry_temperature", &n)) + return NULL; + double t = bndry_temperature(n); + return Py_BuildValue("d",t); +} + +static PyObject* +py_bndry_settemperature(PyObject *self, PyObject *args) +{ + int n; + double t; + if (!PyArg_ParseTuple(args, "id:bndry_settemperature", &n, &t)) + return NULL; + int iok = bndry_settemperature(n, t); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_bndry_mdot(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:bndry_mdot", &n)) + return NULL; + double mdot = bndry_mdot(n); + return Py_BuildValue("d",mdot); +} + +static PyObject* +py_bndry_setmdot(PyObject *self, PyObject *args) +{ + int n; + double mdot; + if (!PyArg_ParseTuple(args, "id:bndry_setmdot", &n, &mdot)) + return NULL; + int iok = bndry_setmdot(n, mdot); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_bndry_setxinbyname(PyObject *self, PyObject *args) +{ + int n; + char* xin; + //PyObject* o; + if (!PyArg_ParseTuple(args, "is:bndry_setxin", &n, &xin)) + return NULL; + //double* x = (double*)((PyArrayObject*)o)->data; + int iok = bndry_setxinbyname(n, xin); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + + +static PyObject* +py_bndry_setxin(PyObject *self, PyObject *args) +{ + int n; + PyObject* xin; + if (!PyArg_ParseTuple(args, "iO:bndry_setxin", &n, &xin)) + return NULL; + double* x = (double*)((PyArrayObject*)xin)->data; + int iok = bndry_setxin(n, x); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + diff --git a/Cantera/python/src/ctflow.cpp b/Cantera/python/src/ctflow.cpp new file mode 100755 index 000000000..582852aa4 --- /dev/null +++ b/Cantera/python/src/ctflow.cpp @@ -0,0 +1,612 @@ +/** + * @file ctkinetics.cpp + * + */ + +// turn off warnings about long names under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + + +#include "Python.h" +#include "Numeric/arrayobject.h" + +#include "ct.h" +#include "ctstagn.h" +#include +#include +#include + +using namespace std; + +// constants defined in the module +static PyObject *ErrorObject; + +// local includes +#include "pyutils.h" + +static PyObject * +py_flow_new(PyObject *self, PyObject *args) +{ + int itype, iph, np; + if (!PyArg_ParseTuple(args, "iii:flow_new", + &itype, &iph, &np)) + return NULL; + int nn = flow_new(itype,iph,np); + if (nn < 0) return reportError(nn); + return Py_BuildValue("i",nn); +} + +static PyObject* +py_flow_delete(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:flow_delete", &n)) return NULL; + flow_del(n); + return Py_BuildValue("i",0); +} + +static PyObject* +py_flow_setupgrid(PyObject *self, PyObject *args) +{ + int n; + PyObject* grid; + if (!PyArg_ParseTuple(args, "iO:flow_setupgrid", &n, &grid)) + return NULL; + + //vector z; + //int iok = pyNumericSequence_ToVector(grid, z); + PyArrayObject* g = (PyArrayObject*)grid; + double* xd = (double*)g->data; + int glen = g->dimensions[0]; + int + // if (iok == -1) { + // PyErr_SetString(ErrorObject, "Third argument must be a sequence"); + // return NULL; + //} + //if (iok == -2) { + // PyErr_SetString(ErrorObject, + // "Sequence must contain only numeric values"); + // return NULL; + //} + + iok = flow_setupgrid(n, glen, xd); + if (iok == -1) return reportCanteraError(); + else if (iok < 0) return NULL; + return Py_BuildValue("i",0); +} + +static PyObject* +py_flow_setkinetics(PyObject *self, PyObject *args) +{ + int nn,k; + if (!PyArg_ParseTuple(args, "ii:flow_setkinetics", &nn, &k)) return NULL; + return Py_BuildValue("i",flow_setkinetics(nn,k)); +} + +static PyObject* +py_flow_settransport(PyObject *self, PyObject *args) +{ + int nn,k,soret; + if (!PyArg_ParseTuple(args, "iii:flow_settransport", + &nn, &k, &soret)) return NULL; + return Py_BuildValue("i",flow_settransport(nn,k,soret)); +} + +static PyObject* +py_flow_setthermo(PyObject *self, PyObject *args) +{ + int nn,k; + if (!PyArg_ParseTuple(args, "ii:flow_setthermo", &nn, &k)) return NULL; + return Py_BuildValue("i",flow_setthermo(nn,k)); +} + +static PyObject* +py_flow_setpressure(PyObject *self, PyObject *args) +{ + int nn; + double p; + if (!PyArg_ParseTuple(args, "id:flow_setpressure", &nn, &p)) + return NULL; + return Py_BuildValue("i",flow_setpressure(nn,p)); +} + +static PyObject* +py_flow_settemperature(PyObject *self, PyObject *args) +{ + int n, j; + double t; + if (!PyArg_ParseTuple(args, "iid:flow_settemperature", &n, &j, &t)) + return NULL; + return Py_BuildValue("i",flow_settemperature(n,j,t)); +} + +static PyObject* +py_flow_setenergyfactor(PyObject *self, PyObject *args) +{ + int n; + double e; + if (!PyArg_ParseTuple(args, "id:flow_setenergyfactor", &n, &e)) + return NULL; + return Py_BuildValue("i",flow_setenergyfactor(n,e)); +} + +static PyObject* +py_flow_setmassfraction(PyObject *self, PyObject *args) +{ + int n, j, k; + double y; + if (!PyArg_ParseTuple(args, "iiid:flow_setinlet_v", &n, &j, &k, &y)) + return NULL; + return Py_BuildValue("i",flow_setmassfraction(n,j,k,y)); +} + +static PyObject* +py_flow_showsolution(PyObject *self, PyObject *args) +{ + int n; + char* fname; + PyObject* soln; + if (!PyArg_ParseTuple(args, "isO:flow_showsolution", &n, &fname, &soln)) + return NULL; + double* x = (double*)((PyArrayObject*)soln)->data; + return Py_BuildValue("i",flow_showsolution(n,fname,x)); +} + +static PyObject* +py_flow_solvespecies(PyObject *self, PyObject *args) +{ + int n, slen; + PyObject* s; + if (!PyArg_ParseTuple(args, "iiO:flow_solvespecies", &n, &slen, &s)) + return NULL; + double* x = (double*)((PyArrayObject*)s)->data; + for (int i = 0; i < slen; i++) { + if (x[i] <= 0.0) + flow_fixspecies(n, i); + else + flow_solvespecies(n, i); + } + return Py_BuildValue("i",0); +} + +static PyObject* +py_copy(PyObject *self, PyObject *args) +{ + int n; + PyObject *s, *snew; + if (!PyArg_ParseTuple(args, "iOO:copy", &n, &s, &snew)) + return NULL; + double* x = (double*)((PyArrayObject*)s)->data; + double* xnew = (double*)((PyArrayObject*)snew)->data; + for (int i = 0; i < n; i++) xnew[i] = x[i]; + return Py_BuildValue("i",0); +} + + +static PyObject* +py_flow_settolerances(PyObject *self, PyObject *args) +{ + int n, nr, na; + PyObject *prtol, *patol; + if (!PyArg_ParseTuple(args, "iiOiO:flow_solve", &n, &nr, &prtol, + &na, &patol)) + return NULL; + double* rtol = (double*)((PyArrayObject*)prtol)->data; + double* atol = (double*)((PyArrayObject*)patol)->data; + int iok = flow_settolerances(n, nr, rtol, na, atol); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +// static PyObject* +// py_flow_integratechem(PyObject *self, PyObject *args) +// { +// int n; +// PyObject *px; +// double dt; +// if (!PyArg_ParseTuple(args, "iOd:flow_solve", &n, &px, &dt)) +// return NULL; +// double* x = (double*)((PyArrayObject*)px)->data; +// int iok = flow_integratechem(n, x, dt); +// if (iok < 0) return reportError(iok); +// return Py_BuildValue("i",iok); +// } + +static PyObject* +py_flow_outputtec(PyObject *self, PyObject *args) +{ + int n; + PyObject *px; + char *fname, *title; + int zone; + if (!PyArg_ParseTuple(args, "iOssi:flow_outputtec", &n, &px, + &fname, &title, &zone)) + return NULL; + double* x = (double*)((PyArrayObject*)px)->data; + int iok = flow_outputtec(n, x, fname, title, zone); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_flow_resize(PyObject *self, PyObject *args) +{ + int n, points; + if (!PyArg_ParseTuple(args, "ii:flow_resize", &n, &points)) + return NULL; + int iok = flow_resize(n, points); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_flow_energy(PyObject *self, PyObject *args) +{ + int n, j, flag, iok; + if (!PyArg_ParseTuple(args, "iii:flow_energy", &n, &j, &flag)) + return NULL; + if (flag == 1) + iok = flow_solveenergyeqn(n, j); + else + iok = flow_fixtemperature(n, j); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_flow_setfixedpoint(PyObject *self, PyObject *args) +{ + int n, j0; + double t0; + if (!PyArg_ParseTuple(args, "iid:flow_setfixedpoint", &n, &j0, &t0)) + return NULL; + int iok = flow_setfixedpoint(n, j0, t0); + return Py_BuildValue("i",iok); +} + +// static PyObject* +// py_flow_eval(PyObject *self, PyObject *args) +// { +// int n, j; +// PyObject *px, *pr; +// if (!PyArg_ParseTuple(args, "iiOO:flow_eval", &n, &j, &px, &pr)) +// return NULL; +// double* x = (double*)((PyArrayObject*)px)->data; +// double* r = (double*)((PyArrayObject*)pr)->data; +// int iok = flow_eval(n, j, x, r); +// if (iok < 0) return reportError(iok); +// return Py_BuildValue("i",iok); +// } + +static PyObject* +py_flow_restore(PyObject *self, PyObject *args) +{ + int n, job, iz, isoln; + char *fname, *id; + PyArrayObject *pz, *psoln; + if (!PyArg_ParseTuple(args, "iiss:flow_restore", + &n, &job, &fname, &id)) + return NULL; + int iok; + double *z=0, *soln=0; + iok = flow_restore(n, -1, fname, id, iz, z, isoln, soln); + if (iok < 0) return reportError(iok); + if (job < 0) { + return Py_BuildValue("(ii)",iz,isoln); + } + pz = (PyArrayObject*)PyArray_FromDims(1, &iz, PyArray_DOUBLE); + int sdim[2]; + sdim[0] = iz; + sdim[1] = isoln/iz; + psoln = (PyArrayObject*)PyArray_FromDims(2, sdim, PyArray_DOUBLE); + z = (double*)((PyArrayObject*)pz)->data; + soln = (double*)((PyArrayObject*)psoln)->data; + iok = flow_restore(n, 0, fname, id, iz, z, isoln, soln); + if (iok < 0) return reportError(iok); + return Py_BuildValue("(OO)",pz,psoln); +} + +static PyObject* +py_flow_setboundaries(PyObject *self, PyObject *args) +{ + int n, nleft, nright; + if (!PyArg_ParseTuple(args, "iii:flow_setboundaries", &n, &nleft, + &nright)) + return NULL; + int iok = flow_setboundaries(n, nleft, nright); + return Py_BuildValue("i",iok); +} + + +/* flow boundary objects */ + + +static PyObject * +py_bdry_new(PyObject *self, PyObject *args) +{ + int itype, ip, kin; + if (!PyArg_ParseTuple(args, "iii:bdry_new", &itype, &ip, &kin)) + return NULL; + int nn = bdry_new(itype,ip,kin); + if (nn < 0) return reportError(nn); + return Py_BuildValue("i",nn); +} + +static PyObject* +py_bdry_delete(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:bdry_delete", &n)) return NULL; + bdry_del(n); + return Py_BuildValue("i",0); +} + +static PyObject* +py_bdry_set(PyObject *self, PyObject *args) +{ + int n, i; + double v; + PyObject* px; + double* x; + if (!PyArg_ParseTuple(args, "iidO:bdry_set", &n, &i, &v, &px)) + return NULL; + if (i < 4) + bdry_set(n, i, &v); + else { + x = (double*)((PyArrayObject*)px)->data; + bdry_set(n, i, x); + } + return Py_BuildValue("i",0); +} + +static PyObject * +py_onedim_new(PyObject *self, PyObject *args) +{ + int n; + PyObject *pydom, *pytype; + if (!PyArg_ParseTuple(args, "iOO:onedim_new", &n, &pydom, &pytype)) + return NULL; + int* dom = (int*)((PyArrayObject*)pydom)->data; + int* typ = (int*)((PyArrayObject*)pytype)->data; + int nn = onedim_new(n, dom, typ); + if (nn == -1) return reportCanteraError(); + return Py_BuildValue("i",nn); +} + +static PyObject* +py_onedim_delete(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:onedim_delete", &n)) return NULL; + onedim_del(n); + return Py_BuildValue("i",0); +} + +static PyObject* +py_onedim_solve(PyObject *self, PyObject *args) +{ + int n, loglevel; + PyObject *s, *snew; + if (!PyArg_ParseTuple(args, "iOOi:onedim_solve", &n, &s, &snew, &loglevel)) + return NULL; + double* x = (double*)((PyArrayObject*)s)->data; + double* xnew = (double*)((PyArrayObject*)snew)->data; + int iok = onedim_solve(n,x,xnew,loglevel); + if (iok == -1) return reportCanteraError(); + return Py_BuildValue("i",iok); +} + + +static PyObject* +py_onedim_ssnorm(PyObject *self, PyObject *args) +{ + int n; + PyObject *ps, *pr; + if (!PyArg_ParseTuple(args, "iOO:flow_solve", &n, &ps, &pr)) + return NULL; + double* x = (double*)((PyArrayObject*)ps)->data; + double* r = (double*)((PyArrayObject*)pr)->data; + double ss = onedim_ssnorm(n,x,r); + return Py_BuildValue("d",ss); +} + +static PyObject* +py_onedim_setnewtonoptions(PyObject *self, PyObject *args) +{ + int n, age; + if (!PyArg_ParseTuple(args, "ii:onedim_setnewtonoptions", &n, &age)) + return NULL; + int iok = onedim_setnewtonoptions(n, age); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_onedim_setsteadymode(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:onedim_setsteadymode", &n)) + return NULL; + int iok = onedim_setsteadymode(n); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_onedim_settransientmode(PyObject *self, PyObject *args) +{ + int n; + double dt; + PyArrayObject* px; + if (!PyArg_ParseTuple(args, "idO:onedim_settransientmode", &n, &dt, &px)) + return NULL; + double* x = (double*)((PyArrayObject*)px)->data; + int iok = onedim_settransientmode(n, dt, x); + return Py_BuildValue("i",iok); +} + + +static PyObject* +py_onedim_eval(PyObject *self, PyObject *args) +{ + int n; + PyObject *px, *pr; + if (!PyArg_ParseTuple(args, "iOO:onedim_eval", &n, &px, &pr)) + return NULL; + double* x = (double*)((PyArrayObject*)px)->data; + double* r = (double*)((PyArrayObject*)pr)->data; + int iok = onedim_eval(n, x, r); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_onedim_addflow(PyObject *self, PyObject *args) +{ + int n, m; + if (!PyArg_ParseTuple(args, "ii:onedim_addflow", &n, &m)) + return NULL; + int iok = onedim_addFlow(n, m); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +// static PyObject* +// py_onedim_addsurf(PyObject *self, PyObject *args) +// { +// int n, m; +// if (!PyArg_ParseTuple(args, "ii:onedim_addflow", &n, &m)) +// return NULL; +// int iok = onedim_addSurf(n, m); +// if (iok < 0) return reportError(iok); +// return Py_BuildValue("i",iok); +// } + + +static PyObject* +py_onedim_resize(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:onedim_resize", &n)) + return NULL; + int iok = onedim_resize(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_onedim_writestats(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:onedim_writeStats", &n)) + return NULL; + int iok = onedim_writeStats(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_onedim_timestep(PyObject *self, PyObject *args) +{ + int n, nsteps, loglevel; + double dt; + PyObject *px, *pr; + if (!PyArg_ParseTuple(args, "iidOOi:onedim_timestep", &n, &nsteps, + &dt, &px, &pr, &loglevel)) + return NULL; + double* x = (double*)((PyArrayObject*)px)->data; + double* r = (double*)((PyArrayObject*)pr)->data; + double newdt = onedim_timestep(n, nsteps, dt, x, r, loglevel); + if (newdt < 0.0) return reportError(-1); + return Py_BuildValue("d",newdt); +} + +static PyObject* +py_onedim_save(PyObject *self, PyObject *args) +{ + int n; + char *fname, *id, *desc; + PyArrayObject* px; + if (!PyArg_ParseTuple(args, "isssO:onedim_save", &n, &fname, &id, &desc, &px)) + return NULL; + double* x = (double*)((PyArrayObject*)px)->data; + int iok = onedim_save(n, fname, id, desc, x); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + + +/* List of functions defined in the module */ + +static PyMethodDef ct_methods[] = { + {"Flow", py_flow_new, METH_VARARGS}, + {"flow_delete", py_flow_delete, METH_VARARGS}, + {"flow_setupgrid", py_flow_setupgrid, METH_VARARGS}, + {"flow_setthermo", py_flow_setthermo, METH_VARARGS}, + {"flow_setkinetics", py_flow_setkinetics, METH_VARARGS}, + {"flow_settransport", py_flow_settransport, METH_VARARGS}, + {"flow_setpressure", py_flow_setpressure, METH_VARARGS}, + //{"flow_setinletstate", py_flow_setinletstate, METH_VARARGS}, + // {"flow_setinlet_u", py_flow_setinlet_u, METH_VARARGS}, + //{"flow_setinlet_v", py_flow_setinlet_v, METH_VARARGS}, + //{"flow_setsurface_t", py_flow_setsurface_t, METH_VARARGS}, + {"flow_solvespecies", py_flow_solvespecies, METH_VARARGS}, + {"flow_settemperature", py_flow_settemperature, METH_VARARGS}, + {"flow_setenergyfactor", py_flow_setenergyfactor, METH_VARARGS}, + {"flow_setmassfraction", py_flow_setmassfraction, METH_VARARGS}, + {"flow_settolerances", py_flow_settolerances, METH_VARARGS}, + {"flow_energy", py_flow_energy, METH_VARARGS}, + {"flow_showsolution", py_flow_showsolution, METH_VARARGS}, + // {"flow_integratechem", py_flow_integratechem, METH_VARARGS}, + {"flow_resize", py_flow_resize, METH_VARARGS}, + {"flow_outputtec", py_flow_outputtec, METH_VARARGS}, + // {"flow_eval", py_flow_eval, METH_VARARGS}, + {"flow_restore", py_flow_restore, METH_VARARGS}, + {"flow_setfixedpoint", py_flow_setfixedpoint, METH_VARARGS}, + {"flow_setboundaries", py_flow_setboundaries, METH_VARARGS}, + {"copy", py_copy, METH_VARARGS}, + {"bdry_new", py_bdry_new, METH_VARARGS}, + {"bdry_del", py_bdry_delete, METH_VARARGS}, + {"bdry_set", py_bdry_set, METH_VARARGS}, + {"onedim_solve", py_onedim_solve, METH_VARARGS}, + {"onedim_new", py_onedim_new, METH_VARARGS}, + {"onedim_del", py_onedim_delete, METH_VARARGS}, + {"onedim_setnewtonoptions", py_onedim_setnewtonoptions, METH_VARARGS}, + {"onedim_ssnorm", py_onedim_ssnorm, METH_VARARGS}, + {"onedim_setsteadymode", py_onedim_setsteadymode, METH_VARARGS}, + {"onedim_settransientmode", py_onedim_settransientmode, METH_VARARGS}, + {"onedim_eval", py_onedim_eval, METH_VARARGS}, + {"onedim_addflow", py_onedim_addflow, METH_VARARGS}, + //{"onedim_addsurf", py_onedim_addsurf, METH_VARARGS}, + {"onedim_resize", py_onedim_resize, METH_VARARGS}, + {"onedim_writestats", py_onedim_writestats, METH_VARARGS}, + {"onedim_timestep", py_onedim_timestep, METH_VARARGS}, + {"onedim_save", py_onedim_save, METH_VARARGS}, + {NULL, NULL} /* sentinel */ +}; + + +extern "C" { + + /* Initialization function for the module (*must* be called initctflow) */ + + DL_EXPORT(void) initctflow(void) + { + PyObject *m, *d; + + /* Initialize the type of the new type object here; doing it here + * is required for portability to Windows without requiring C++. */ + + /* Create the module and add the functions */ + m = Py_InitModule("ctflow", ct_methods); + import_array(); + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + ErrorObject = PyErr_NewException("cantera.error", NULL, NULL); + PyDict_SetItemString(d, "error", ErrorObject); + } + +} diff --git a/Cantera/python/src/ctflow.def b/Cantera/python/src/ctflow.def new file mode 100755 index 000000000..9d4937774 --- /dev/null +++ b/Cantera/python/src/ctflow.def @@ -0,0 +1,2 @@ +EXPORTS + initctflow \ No newline at end of file diff --git a/Cantera/python/src/ctflow_methods.cpp b/Cantera/python/src/ctflow_methods.cpp new file mode 100644 index 000000000..973ca25da --- /dev/null +++ b/Cantera/python/src/ctflow_methods.cpp @@ -0,0 +1,472 @@ + +static PyObject * +py_flow_new(PyObject *self, PyObject *args) +{ + int itype, iph, np; + if (!PyArg_ParseTuple(args, "iii:flow_new", + &itype, &iph, &np)) + return NULL; + int nn = flow_new(itype,iph,np); + if (nn < 0) return reportError(nn); + return Py_BuildValue("i",nn); +} + +static PyObject* +py_flow_delete(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:flow_delete", &n)) return NULL; + flow_del(n); + return Py_BuildValue("i",0); +} + +static PyObject* +py_flow_setupgrid(PyObject *self, PyObject *args) +{ + int n; + PyObject* grid; + if (!PyArg_ParseTuple(args, "iO:flow_setupgrid", &n, &grid)) + return NULL; + + PyArrayObject* g = (PyArrayObject*)grid; + double* xd = (double*)g->data; + int glen = g->dimensions[0]; + + int iok = flow_setupgrid(n, glen, xd); + if (iok == -1) return reportCanteraError(); + else if (iok < 0) return NULL; + return Py_BuildValue("i",0); +} + +static PyObject* +py_flow_setkinetics(PyObject *self, PyObject *args) +{ + int nn,k; + if (!PyArg_ParseTuple(args, "ii:flow_setkinetics", &nn, &k)) return NULL; + return Py_BuildValue("i",flow_setkinetics(nn,k)); +} + +static PyObject* +py_flow_settransport(PyObject *self, PyObject *args) +{ + int nn,k,soret; + if (!PyArg_ParseTuple(args, "iii:flow_settransport", + &nn, &k, &soret)) return NULL; + return Py_BuildValue("i",flow_settransport(nn,k,soret)); +} + +static PyObject* +py_flow_setthermo(PyObject *self, PyObject *args) +{ + int nn,k; + if (!PyArg_ParseTuple(args, "ii:flow_setthermo", &nn, &k)) return NULL; + return Py_BuildValue("i",flow_setthermo(nn,k)); +} + +static PyObject* +py_flow_setpressure(PyObject *self, PyObject *args) +{ + int nn; + double p; + if (!PyArg_ParseTuple(args, "id:flow_setpressure", &nn, &p)) + return NULL; + return Py_BuildValue("i",flow_setpressure(nn,p)); +} + +static PyObject* +py_flow_settemperature(PyObject *self, PyObject *args) +{ + int n, j; + double t; + if (!PyArg_ParseTuple(args, "iid:flow_settemperature", &n, &j, &t)) + return NULL; + return Py_BuildValue("i",flow_settemperature(n,j,t)); +} + +static PyObject* +py_flow_setenergyfactor(PyObject *self, PyObject *args) +{ + int n; + double e; + if (!PyArg_ParseTuple(args, "id:flow_setenergyfactor", &n, &e)) + return NULL; + return Py_BuildValue("i",flow_setenergyfactor(n,e)); +} + +static PyObject* +py_flow_setmassfraction(PyObject *self, PyObject *args) +{ + int n, j, k; + double y; + if (!PyArg_ParseTuple(args, "iiid:flow_setinlet_v", &n, &j, &k, &y)) + return NULL; + return Py_BuildValue("i",flow_setmassfraction(n,j,k,y)); +} + +static PyObject* +py_flow_showsolution(PyObject *self, PyObject *args) +{ + int n; + char* fname; + PyObject* soln; + if (!PyArg_ParseTuple(args, "isO:flow_showsolution", &n, &fname, &soln)) + return NULL; + double* x = (double*)((PyArrayObject*)soln)->data; + return Py_BuildValue("i",flow_showsolution(n,fname,x)); +} + +static PyObject* +py_flow_solvespecies(PyObject *self, PyObject *args) +{ + int n, slen; + PyObject* s; + if (!PyArg_ParseTuple(args, "iiO:flow_solvespecies", &n, &slen, &s)) + return NULL; + double* x = (double*)((PyArrayObject*)s)->data; + for (int i = 0; i < slen; i++) { + if (x[i] <= 0.0) + flow_fixspecies(n, i); + else + flow_solvespecies(n, i); + } + return Py_BuildValue("i",0); +} + +static PyObject* +py_copy(PyObject *self, PyObject *args) +{ + int n; + PyObject *s, *snew; + if (!PyArg_ParseTuple(args, "iOO:copy", &n, &s, &snew)) + return NULL; + double* x = (double*)((PyArrayObject*)s)->data; + double* xnew = (double*)((PyArrayObject*)snew)->data; + for (int i = 0; i < n; i++) xnew[i] = x[i]; + return Py_BuildValue("i",0); +} + + +static PyObject* +py_flow_settolerances(PyObject *self, PyObject *args) +{ + int n, nr, na; + PyObject *prtol, *patol; + if (!PyArg_ParseTuple(args, "iiOiO:flow_solve", &n, &nr, &prtol, + &na, &patol)) + return NULL; + double* rtol = (double*)((PyArrayObject*)prtol)->data; + double* atol = (double*)((PyArrayObject*)patol)->data; + int iok = flow_settolerances(n, nr, rtol, na, atol); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_flow_outputtec(PyObject *self, PyObject *args) +{ + int n; + PyObject *px; + char *fname, *title; + int zone; + if (!PyArg_ParseTuple(args, "iOssi:flow_outputtec", &n, &px, + &fname, &title, &zone)) + return NULL; + double* x = (double*)((PyArrayObject*)px)->data; + int iok = flow_outputtec(n, x, fname, title, zone); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_flow_resize(PyObject *self, PyObject *args) +{ + int n, points; + if (!PyArg_ParseTuple(args, "ii:flow_resize", &n, &points)) + return NULL; + int iok = flow_resize(n, points); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_flow_energy(PyObject *self, PyObject *args) +{ + int n, j, flag, iok; + if (!PyArg_ParseTuple(args, "iii:flow_energy", &n, &j, &flag)) + return NULL; + if (flag == 1) + iok = flow_solveenergyeqn(n, j); + else + iok = flow_fixtemperature(n, j); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_flow_setfixedpoint(PyObject *self, PyObject *args) +{ + int n, j0; + double t0; + if (!PyArg_ParseTuple(args, "iid:flow_setfixedpoint", &n, &j0, &t0)) + return NULL; + int iok = flow_setfixedpoint(n, j0, t0); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_flow_restore(PyObject *self, PyObject *args) +{ + int n, job, iz, isoln; + char *fname, *id; + PyArrayObject *pz, *psoln; + if (!PyArg_ParseTuple(args, "iiss:flow_restore", + &n, &job, &fname, &id)) + return NULL; + int iok; + double *z=0, *soln=0; + iok = flow_restore(n, -1, fname, id, iz, z, isoln, soln); + if (iok < 0) return reportError(iok); + if (job < 0) { + return Py_BuildValue("(ii)",iz,isoln); + } + pz = (PyArrayObject*)PyArray_FromDims(1, &iz, PyArray_DOUBLE); + int sdim[2]; + sdim[0] = iz; + sdim[1] = isoln/iz; + psoln = (PyArrayObject*)PyArray_FromDims(2, sdim, PyArray_DOUBLE); + z = (double*)((PyArrayObject*)pz)->data; + soln = (double*)((PyArrayObject*)psoln)->data; + iok = flow_restore(n, 0, fname, id, iz, z, isoln, soln); + if (iok < 0) return reportError(iok); + return Py_BuildValue("(OO)",pz,psoln); +} + +static PyObject* +py_flow_setboundaries(PyObject *self, PyObject *args) +{ + int n, nleft, nright; + if (!PyArg_ParseTuple(args, "iii:flow_setboundaries", &n, &nleft, + &nright)) + return NULL; + int iok = flow_setboundaries(n, nleft, nright); + return Py_BuildValue("i",iok); +} + + +/* flow boundary objects */ + + +static PyObject * +py_bdry_new(PyObject *self, PyObject *args) +{ + int itype, ip, kin; + if (!PyArg_ParseTuple(args, "iii:bdry_new", &itype, &ip, &kin)) + return NULL; + int nn = bdry_new(itype,ip,kin); + if (nn < 0) return reportError(nn); + return Py_BuildValue("i",nn); +} + +static PyObject* +py_bdry_delete(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:bdry_delete", &n)) return NULL; + bdry_del(n); + return Py_BuildValue("i",0); +} + +static PyObject* +py_bdry_set(PyObject *self, PyObject *args) +{ + int n, i; + double v; + PyObject* px; + double* x; + if (!PyArg_ParseTuple(args, "iidO:bdry_set", &n, &i, &v, &px)) + return NULL; + if (i < 4) + bdry_set(n, i, &v); + else { + x = (double*)((PyArrayObject*)px)->data; + bdry_set(n, i, x); + } + return Py_BuildValue("i",0); +} + +static PyObject * +py_onedim_new(PyObject *self, PyObject *args) +{ + int n; + PyObject *pydom, *pytype; + if (!PyArg_ParseTuple(args, "iOO:onedim_new", &n, &pydom, &pytype)) + return NULL; + int* dom = (int*)((PyArrayObject*)pydom)->data; + int* typ = (int*)((PyArrayObject*)pytype)->data; + int nn = onedim_new(n, dom, typ); + if (nn == -1) return reportCanteraError(); + return Py_BuildValue("i",nn); +} + +static PyObject* +py_onedim_delete(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:onedim_delete", &n)) return NULL; + onedim_del(n); + return Py_BuildValue("i",0); +} + +static PyObject* +py_onedim_solve(PyObject *self, PyObject *args) +{ + int n, loglevel; + PyObject *s, *snew; + if (!PyArg_ParseTuple(args, "iOOi:onedim_solve", &n, &s, &snew, &loglevel)) + return NULL; + double* x = (double*)((PyArrayObject*)s)->data; + double* xnew = (double*)((PyArrayObject*)snew)->data; + int iok = onedim_solve(n,x,xnew,loglevel); + if (iok == -1) return reportCanteraError(); + return Py_BuildValue("i",iok); +} + + +static PyObject* +py_onedim_ssnorm(PyObject *self, PyObject *args) +{ + int n; + PyObject *ps, *pr; + if (!PyArg_ParseTuple(args, "iOO:flow_solve", &n, &ps, &pr)) + return NULL; + double* x = (double*)((PyArrayObject*)ps)->data; + double* r = (double*)((PyArrayObject*)pr)->data; + double ss = onedim_ssnorm(n,x,r); + return Py_BuildValue("d",ss); +} + +static PyObject* +py_onedim_setnewtonoptions(PyObject *self, PyObject *args) +{ + int n, age; + if (!PyArg_ParseTuple(args, "ii:onedim_setnewtonoptions", &n, &age)) + return NULL; + int iok = onedim_setnewtonoptions(n, age); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_onedim_setsteadymode(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:onedim_setsteadymode", &n)) + return NULL; + int iok = onedim_setsteadymode(n); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_onedim_settransientmode(PyObject *self, PyObject *args) +{ + int n; + double dt; + PyArrayObject* px; + if (!PyArg_ParseTuple(args, "idO:onedim_settransientmode", &n, &dt, &px)) + return NULL; + double* x = (double*)((PyArrayObject*)px)->data; + int iok = onedim_settransientmode(n, dt, x); + return Py_BuildValue("i",iok); +} + + +static PyObject* +py_onedim_eval(PyObject *self, PyObject *args) +{ + int n; + PyObject *px, *pr; + if (!PyArg_ParseTuple(args, "iOO:onedim_eval", &n, &px, &pr)) + return NULL; + double* x = (double*)((PyArrayObject*)px)->data; + double* r = (double*)((PyArrayObject*)pr)->data; + int iok = onedim_eval(n, x, r); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_onedim_addflow(PyObject *self, PyObject *args) +{ + int n, m; + if (!PyArg_ParseTuple(args, "ii:onedim_addflow", &n, &m)) + return NULL; + int iok = onedim_addFlow(n, m); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +// static PyObject* +// py_onedim_addsurf(PyObject *self, PyObject *args) +// { +// int n, m; +// if (!PyArg_ParseTuple(args, "ii:onedim_addflow", &n, &m)) +// return NULL; +// int iok = onedim_addSurf(n, m); +// if (iok < 0) return reportError(iok); +// return Py_BuildValue("i",iok); +// } + + +static PyObject* +py_onedim_resize(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:onedim_resize", &n)) + return NULL; + int iok = onedim_resize(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_onedim_writestats(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:onedim_writeStats", &n)) + return NULL; + int iok = onedim_writeStats(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_onedim_timestep(PyObject *self, PyObject *args) +{ + int n, nsteps, loglevel; + double dt; + PyObject *px, *pr; + if (!PyArg_ParseTuple(args, "iidOOi:onedim_timestep", &n, &nsteps, + &dt, &px, &pr, &loglevel)) + return NULL; + double* x = (double*)((PyArrayObject*)px)->data; + double* r = (double*)((PyArrayObject*)pr)->data; + double newdt = onedim_timestep(n, nsteps, dt, x, r, loglevel); + if (newdt < 0.0) return reportError(-1); + return Py_BuildValue("d",newdt); +} + +static PyObject* +py_onedim_save(PyObject *self, PyObject *args) +{ + int n; + char *fname, *id, *desc; + PyArrayObject* px; + if (!PyArg_ParseTuple(args, "isssO:onedim_save", &n, &fname, &id, &desc, &px)) + return NULL; + double* x = (double*)((PyArrayObject*)px)->data; + int iok = onedim_save(n, fname, id, desc, x); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + + diff --git a/Cantera/python/src/ctfunc_methods.cpp b/Cantera/python/src/ctfunc_methods.cpp new file mode 100644 index 000000000..1d2186f81 --- /dev/null +++ b/Cantera/python/src/ctfunc_methods.cpp @@ -0,0 +1,49 @@ + +static PyObject* +py_func_new(PyObject *self, PyObject *args) +{ + int type, n; + PyObject* c; + if (!PyArg_ParseTuple(args, "iiO:func_new", &type, &n, &c)) + return NULL; + PyArrayObject* coeffs = (PyArrayObject*)c; + double* xd = (double*)coeffs->data; + int lenc = coeffs->dimensions[0]; + int nn = func_new(type, n, lenc, xd); + if (nn < 0) return reportError(nn); + return Py_BuildValue("i",nn); +} + +static PyObject* +py_func_newcombo(PyObject *self, PyObject *args) +{ + int type, n, m; + if (!PyArg_ParseTuple(args, "iii:func_newcombo", &type, &n, &m)) + return NULL; + int nn = func_new(type, n, m, 0); + if (nn < 0) return reportError(nn); + return Py_BuildValue("i",nn); +} + +static PyObject* +py_func_del(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:func_del", &n)) + return NULL; + int iok = func_del(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_func_value(PyObject *self, PyObject *args) +{ + int n; + double t; + if (!PyArg_ParseTuple(args, "id:func_value", &n, &t)) + return NULL; + double r = func_value(n, t); + return Py_BuildValue("d",r); +} + diff --git a/Cantera/python/src/ctfuncs.cpp b/Cantera/python/src/ctfuncs.cpp new file mode 100644 index 000000000..766bd7a30 --- /dev/null +++ b/Cantera/python/src/ctfuncs.cpp @@ -0,0 +1,64 @@ + +static PyObject * +ct_buildSolutionFromXML(PyObject *self, PyObject *args) +{ + int ixml, ith, ikin; + char *src=0, *id=0; + if (!PyArg_ParseTuple(args, "sisii:buildSolutionFromXML", &src, &ixml, + &id, &ith, &ikin)) + return NULL; + int ok = buildSolutionFromXML(src, ixml, id, ith, ikin); + if (ok == -1) { return reportCanteraError();} + return Py_BuildValue("i",ok); +} + +static PyObject * +ct_get_cantera_error(PyObject *self, PyObject *args) +{ + char* buf = new char[400]; + getCanteraError(400, buf); + PyObject* msg = Py_BuildValue("s",buf); + delete buf; + return msg; +} + +static PyObject * +ct_print(PyObject *self, PyObject *args) +{ + char* msg; + if (!PyArg_ParseTuple(args, "s:print", &msg)) + return NULL; + printf(msg); + return Py_BuildValue("i",0); +} + +static PyObject * +ct_readlog(PyObject *self, PyObject *args) +{ + char* msg = 0; + int n = readlog(-1, msg); + if (n > 0) { + msg = new char[n+1]; + readlog(n, msg); + PyObject* r = Py_BuildValue("s",msg); + return r; + } + else + return Py_BuildValue("s",""); +} + +static PyObject * +ct_ck2ctml(PyObject *self, PyObject *args) +{ + int iok; + char *infile, *thermo, *tran, *outfile, *idtag; + if (!PyArg_ParseTuple(args, "sssss:ck2ctml", &infile, + &thermo, &tran, &outfile, &idtag)) + return NULL; + iok = ck_to_ctml(infile, thermo, tran, outfile, idtag); + if (iok == -1) { return reportCanteraError();} + return Py_BuildValue("i",iok); +} + + + diff --git a/Cantera/python/src/ctkinetics.cpp b/Cantera/python/src/ctkinetics.cpp new file mode 100755 index 000000000..7be51d62d --- /dev/null +++ b/Cantera/python/src/ctkinetics.cpp @@ -0,0 +1,266 @@ +/** + * @file ctkinetics.cpp + * + */ + +// turn off warnings about long names under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + + +#include "Python.h" +#include "Numeric/arrayobject.h" +#include "ct.h" +#include +#include +#include +using namespace std; + + +// constants defined in the module +static PyObject *ErrorObject; + +// local includes +#include "pyutils.h" + +static PyObject* +kin_newFromXML(PyObject *self, PyObject *args) { + int mxml, iphase, neighbor1, neighbor2; + if (!PyArg_ParseTuple(args, "iiii:newFromXML", &mxml, + &iphase, &neighbor1, &neighbor2)) + return NULL; + int n = newKineticsFromXML(mxml, iphase, neighbor1, neighbor2); + if (n < 0) return reportError(n); + return Py_BuildValue("i",n); +} + +static PyObject* +kin_delete(PyObject *self, PyObject *args) +{ + int kin; + if (!PyArg_ParseTuple(args, "i:kin_delete", &kin)) return NULL; + delKinetics(kin); + return Py_BuildValue("i",0); +} + +static PyObject* +kin_nspecies(PyObject *self, PyObject *args) { + int kin; + if (!PyArg_ParseTuple(args, "i:kin_nspecies", &kin)) return NULL; + return Py_BuildValue("i",kin_nSpecies(kin)); +} + +static PyObject* +kin_rstoichcoeff(PyObject *self, PyObject *args) { + int kin, i, k; + if (!PyArg_ParseTuple(args, "iii:kin_rstoichcoeff", &kin, &k, &i)) + return NULL; + return Py_BuildValue("d",kin_reactantStoichCoeff(kin, k, i)); +} + +static PyObject* +kin_pstoichcoeff(PyObject *self, PyObject *args) { + int kin, i, k; + if (!PyArg_ParseTuple(args, "iii:kin_pstoichcoeff", &kin, &k, &i)) + return NULL; + return Py_BuildValue("d",kin_productStoichCoeff(kin, k, i)); +} + +static PyObject* +kin_nrxns(PyObject *self, PyObject *args) { + int kin; + if (!PyArg_ParseTuple(args, "i:kin_nreactions", &kin)) return NULL; + return Py_BuildValue("i",kin_nReactions(kin)); +} + +static PyObject* +kin_isrev(PyObject *self, PyObject *args) { + int kin, i; + if (!PyArg_ParseTuple(args, "ii:kin_isrev", &kin, &i)) return NULL; + return Py_BuildValue("i",kin_isReversible(kin,i)); +} + +static PyObject* +kin_rxntype(PyObject *self, PyObject *args) { + int kin, i; + if (!PyArg_ParseTuple(args, "ii:kin_rxntype", &kin, &i)) return NULL; + return Py_BuildValue("i",kin_reactionType(kin,i)); +} + +static PyObject* +kin_multiplier(PyObject *self, PyObject *args) { + int kin, i; + if (!PyArg_ParseTuple(args, "ii:kin_multiplier", &kin, &i)) return NULL; + return Py_BuildValue("d",kin_multiplier(kin,i)); +} + +static PyObject* +kin_setMultiplier(PyObject *self, PyObject *args) { + int kin, i; + double v; + if (!PyArg_ParseTuple(args, "iid:kin_setMultiplier", &kin, &i, &v)) return NULL; + return Py_BuildValue("i",kin_setMultiplier(kin,i,v)); +} + + +static PyObject* +kin_type(PyObject *self, PyObject *args) { + int kin, i; + if (!PyArg_ParseTuple(args, "i:kin_type", &kin)) return NULL; + return Py_BuildValue("i",kin_type(kin)); +} + +static PyObject* +kin_start(PyObject *self, PyObject *args) { + int kin, p; + if (!PyArg_ParseTuple(args, "ii:kin_start", &kin, &p)) return NULL; + return Py_BuildValue("i",kin_start(kin,p)); +} + +static PyObject* +kin_speciesIndex(PyObject *self, PyObject *args) { + int kin; + char *nm, *ph; + if (!PyArg_ParseTuple(args, "iss:kin_speciesIndex", &kin, &nm, &ph)) + return NULL; + return Py_BuildValue("i",kin_speciesIndex(kin,nm,ph)); +} + +static PyObject* +kin_getarray(PyObject *self, PyObject *args) +{ + int kin; + int job; + + if (!PyArg_ParseTuple(args, "ii:kin_getarray", &kin, &job)) + return NULL; + + // array attributes + int iok = -22; + int nrxns = kin_nReactions(kin); + int nsp = kin_nSpecies(kin); + int ix; + if (job < 45) ix = nrxns; else ix = nsp; + + PyArrayObject* x = + (PyArrayObject*)PyArray_FromDims(1, &ix, PyArray_DOUBLE); + double* xd = (double*)x->data; + + switch (job) { + case 10: + iok = kin_getFwdRatesOfProgress(kin, nrxns, xd); + break; + case 20: + iok = kin_getRevRatesOfProgress(kin, nrxns, xd); + break; + case 30: + iok = kin_getNetRatesOfProgress(kin, nrxns, xd); + break; + case 40: + iok = kin_getEquilibriumConstants(kin, nrxns, xd); + break; + case 50: + iok = kin_getCreationRates(kin, nsp, xd); + break; + case 60: + iok = kin_getDestructionRates(kin, nsp, xd); + break; + case 70: + iok = kin_getNetProductionRates(kin, nsp, xd); + break; + case 80: + iok = kin_getSourceTerms(kin, nsp, xd); + break; + + break; + default: + ; + } + if (iok >= 0) { + return PyArray_Return(x); + } + else + return reportError(iok); +} + + + +// string attributes +static PyObject* +kin_getstring(PyObject *self, PyObject *args) +{ + int kin, job, i, iok = -3; + int buflen; + char* output_buf = 0; + if (!PyArg_ParseTuple(args, "iii:kin_getstring", &kin, &job, &i)) + return NULL; + switch (job) { + case 1: + buflen = 80; + output_buf = new char[buflen]; + iok = kin_getReactionString(kin, i, buflen, output_buf); + break; + default: + iok = -10; + } + if (iok >= 0) { + PyObject* str = Py_BuildValue("s",output_buf); + delete output_buf; + return str; + } + delete output_buf; + if (iok == -1) + return reportCanteraError(); + else { + PyErr_SetString(ErrorObject,"Unknown string attribute"); + return NULL; + } +} + + +/* List of functions defined in the module */ + +static PyMethodDef ct_methods[] = { + {"KineticsFromXML", kin_newFromXML, METH_VARARGS}, + {"delete", kin_delete, METH_VARARGS}, + {"nspecies", kin_nspecies, METH_VARARGS}, + {"nreactions", kin_nrxns, METH_VARARGS}, + {"isreversible", kin_isrev, METH_VARARGS}, + {"rstoichcoeff", kin_rstoichcoeff, METH_VARARGS}, + {"pstoichcoeff", kin_pstoichcoeff, METH_VARARGS}, + {"rxntype", kin_rxntype, METH_VARARGS}, + {"type", kin_type, METH_VARARGS}, + {"start", kin_start, METH_VARARGS}, + {"multiplier", kin_multiplier, METH_VARARGS}, + {"setMultiplier", kin_setMultiplier, METH_VARARGS}, + {"speciesIndex", kin_speciesIndex, METH_VARARGS}, + {"getarray", kin_getarray, METH_VARARGS}, + {"getstring", kin_getstring, METH_VARARGS}, + {NULL, NULL} /* sentinel */ +}; + + +extern "C" { + + /* Initialization function for the module (*must* be called initctkinetics) */ + + DL_EXPORT(void) initctkinetics(void) + { + PyObject *m, *d; + + /* Initialize the type of the new type object here; doing it here + * is required for portability to Windows without requiring C++. */ + + /* Create the module and add the functions */ + m = Py_InitModule("ctkinetics", ct_methods); + import_array(); + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + ErrorObject = PyErr_NewException("cantera.error", NULL, NULL); + PyDict_SetItemString(d, "error", ErrorObject); + } + +} diff --git a/Cantera/python/src/ctkinetics.def b/Cantera/python/src/ctkinetics.def new file mode 100755 index 000000000..273bc855c --- /dev/null +++ b/Cantera/python/src/ctkinetics.def @@ -0,0 +1,2 @@ +EXPORTS + initctkinetics \ No newline at end of file diff --git a/Cantera/python/src/ctkinetics_methods.cpp b/Cantera/python/src/ctkinetics_methods.cpp new file mode 100644 index 000000000..6f037e45b --- /dev/null +++ b/Cantera/python/src/ctkinetics_methods.cpp @@ -0,0 +1,194 @@ + +static PyObject* +kin_newFromXML(PyObject *self, PyObject *args) { + int mxml, iphase, neighbor1, neighbor2; + if (!PyArg_ParseTuple(args, "iiii:newFromXML", &mxml, + &iphase, &neighbor1, &neighbor2)) + return NULL; + int n = newKineticsFromXML(mxml, iphase, neighbor1, neighbor2); + if (n < 0) return reportError(n); + return Py_BuildValue("i",n); +} + +static PyObject* +kin_delete(PyObject *self, PyObject *args) +{ + int kin; + if (!PyArg_ParseTuple(args, "i:kin_delete", &kin)) return NULL; + delKinetics(kin); + return Py_BuildValue("i",0); +} + +static PyObject* +kin_nspecies(PyObject *self, PyObject *args) { + int kin; + if (!PyArg_ParseTuple(args, "i:kin_nspecies", &kin)) return NULL; + return Py_BuildValue("i",kin_nSpecies(kin)); +} + +static PyObject* +kin_rstoichcoeff(PyObject *self, PyObject *args) { + int kin, i, k; + if (!PyArg_ParseTuple(args, "iii:kin_rstoichcoeff", &kin, &k, &i)) + return NULL; + return Py_BuildValue("d",kin_reactantStoichCoeff(kin, k, i)); +} + +static PyObject* +kin_pstoichcoeff(PyObject *self, PyObject *args) { + int kin, i, k; + if (!PyArg_ParseTuple(args, "iii:kin_pstoichcoeff", &kin, &k, &i)) + return NULL; + return Py_BuildValue("d",kin_productStoichCoeff(kin, k, i)); +} + +static PyObject* +kin_nrxns(PyObject *self, PyObject *args) { + int kin; + if (!PyArg_ParseTuple(args, "i:kin_nreactions", &kin)) return NULL; + return Py_BuildValue("i",kin_nReactions(kin)); +} + +static PyObject* +kin_isrev(PyObject *self, PyObject *args) { + int kin, i; + if (!PyArg_ParseTuple(args, "ii:kin_isrev", &kin, &i)) return NULL; + return Py_BuildValue("i",kin_isReversible(kin,i)); +} + +static PyObject* +kin_rxntype(PyObject *self, PyObject *args) { + int kin, i; + if (!PyArg_ParseTuple(args, "ii:kin_rxntype", &kin, &i)) return NULL; + return Py_BuildValue("i",kin_reactionType(kin,i)); +} + +static PyObject* +kin_multiplier(PyObject *self, PyObject *args) { + int kin, i; + if (!PyArg_ParseTuple(args, "ii:kin_multiplier", &kin, &i)) return NULL; + return Py_BuildValue("d",kin_multiplier(kin,i)); +} + +static PyObject* +kin_setMultiplier(PyObject *self, PyObject *args) { + int kin, i; + double v; + if (!PyArg_ParseTuple(args, "iid:kin_setMultiplier", &kin, &i, &v)) return NULL; + return Py_BuildValue("i",kin_setMultiplier(kin,i,v)); +} + + +static PyObject* +kin_type(PyObject *self, PyObject *args) { + int kin; + if (!PyArg_ParseTuple(args, "i:kin_type", &kin)) return NULL; + return Py_BuildValue("i",kin_type(kin)); +} + +static PyObject* +kin_start(PyObject *self, PyObject *args) { + int kin, p; + if (!PyArg_ParseTuple(args, "ii:kin_start", &kin, &p)) return NULL; + return Py_BuildValue("i",kin_start(kin,p)); +} + +static PyObject* +kin_speciesIndex(PyObject *self, PyObject *args) { + int kin; + char *nm, *ph; + if (!PyArg_ParseTuple(args, "iss:kin_speciesIndex", &kin, &nm, &ph)) + return NULL; + return Py_BuildValue("i",kin_speciesIndex(kin,nm,ph)); +} + +static PyObject* +kin_getarray(PyObject *self, PyObject *args) +{ + int kin; + int job; + + if (!PyArg_ParseTuple(args, "ii:kin_getarray", &kin, &job)) + return NULL; + + // array attributes + int iok = -22; + int nrxns = kin_nReactions(kin); + int nsp = kin_nSpecies(kin); + int ix; + if (job < 45) ix = nrxns; else ix = nsp; + + PyArrayObject* x = + (PyArrayObject*)PyArray_FromDims(1, &ix, PyArray_DOUBLE); + double* xd = (double*)x->data; + + switch (job) { + case 10: + iok = kin_getFwdRatesOfProgress(kin, nrxns, xd); + break; + case 20: + iok = kin_getRevRatesOfProgress(kin, nrxns, xd); + break; + case 30: + iok = kin_getNetRatesOfProgress(kin, nrxns, xd); + break; + case 40: + iok = kin_getEquilibriumConstants(kin, nrxns, xd); + break; + case 50: + iok = kin_getCreationRates(kin, nsp, xd); + break; + case 60: + iok = kin_getDestructionRates(kin, nsp, xd); + break; + case 70: + iok = kin_getNetProductionRates(kin, nsp, xd); + break; + case 80: + iok = kin_getSourceTerms(kin, nsp, xd); + break; + + break; + default: + ; + } + if (iok >= 0) { + return PyArray_Return(x); + } + else + return reportError(iok); +} + + + +// string attributes +static PyObject* +kin_getstring(PyObject *self, PyObject *args) +{ + int kin, job, i, iok = -3; + int buflen; + char* output_buf = 0; + if (!PyArg_ParseTuple(args, "iii:kin_getstring", &kin, &job, &i)) + return NULL; + switch (job) { + case 1: + buflen = 80; + output_buf = new char[buflen]; + iok = kin_getReactionString(kin, i, buflen, output_buf); + break; + default: + iok = -10; + } + if (iok >= 0) { + PyObject* str = Py_BuildValue("s",output_buf); + delete output_buf; + return str; + } + delete output_buf; + if (iok == -1) + return reportCanteraError(); + else { + PyErr_SetString(ErrorObject,"Unknown string attribute"); + return NULL; + } +} diff --git a/Cantera/python/src/ctmodule.cpp b/Cantera/python/src/ctmodule.cpp new file mode 100755 index 000000000..258616751 --- /dev/null +++ b/Cantera/python/src/ctmodule.cpp @@ -0,0 +1,118 @@ +/** + * @file ctmodule.cpp + * Cantera Python Interface + * + */ + + +// turn off warnings about long names under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +// #define USE_DL_EXPORT + +#include "Python.h" +#include "ct.h" + +// constants defined in the module +static PyObject *ErrorObject; + +#include +#include +using namespace std; + +// local includes +#include "pyutils.h" + +static PyObject * +ct_buildSolutionFromXML(PyObject *self, PyObject *args) +{ + int ixml, ith, ikin; + char *src=0, *id=0; + if (!PyArg_ParseTuple(args, "sisii:buildSolutionFromXML", &src, &ixml, + &id, &ith, &ikin)) + return NULL; + int ok = buildSolutionFromXML(src, ixml, id, ith, ikin); + if (ok == -1) { return reportCanteraError();} + return Py_BuildValue("i",ok); +} + +static PyObject * +ct_get_cantera_error(PyObject *self, PyObject *args) +{ + char* buf = new char[400]; + getCanteraError(400, buf); + PyObject* msg = Py_BuildValue("s",buf); + delete buf; + return msg; +} + +static PyObject * +ct_print(PyObject *self, PyObject *args) +{ + char* msg; + if (!PyArg_ParseTuple(args, "s:print", &msg)) + return NULL; + printf(msg); + return Py_BuildValue("i",0); +} + +static PyObject * +ct_readlog(PyObject *self, PyObject *args) +{ + char* msg = 0; + int n = readlog(-1, msg); + if (n > 0) { + msg = new char[n+1]; + int ok = readlog(n, msg); + PyObject* r = Py_BuildValue("s",msg); + return r; + } + else + return Py_BuildValue("s",""); +} + +static PyObject * +ct_ck2ctml(PyObject *self, PyObject *args) +{ + int iok; + char *infile, *thermo, *tran, *outfile, *idtag; + if (!PyArg_ParseTuple(args, "sssss:ck2ctml", &infile, + &thermo, &tran, &outfile, &idtag)) + return NULL; + iok = ck_to_ctml(infile, thermo, tran, outfile, idtag); + if (iok == -1) { return reportCanteraError();} + return Py_BuildValue("i",iok); +} + +/* List of functions defined in the module */ + +static PyMethodDef ct_methods[] = { + {"get_Cantera_Error", ct_get_cantera_error, METH_VARARGS}, + {"ct_print", ct_print, METH_VARARGS}, + {"readlog", ct_readlog, METH_VARARGS}, + {"ck2ctml", ct_ck2ctml, METH_VARARGS}, + {"buildSolutionFromXML", ct_buildSolutionFromXML, METH_VARARGS}, + {NULL, NULL} /* sentinel */ +}; + + +extern "C" { + + /* Initialization function for the module (*must* be called initctmodule) */ + + DL_EXPORT(void) initctmodule(void) + { + PyObject *m, *d; + + /* Create the module and add the functions */ + m = Py_InitModule("ctmodule", ct_methods); + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + ErrorObject = PyErr_NewException("cantera.error", NULL, NULL); + PyDict_SetItemString(d, "error", ErrorObject); + } +} diff --git a/Cantera/python/src/ctnumerics.cpp b/Cantera/python/src/ctnumerics.cpp new file mode 100755 index 000000000..94a7ff304 --- /dev/null +++ b/Cantera/python/src/ctnumerics.cpp @@ -0,0 +1,315 @@ +/** + * @file ctkinetics.cpp + * + */ + +// turn off warnings about long names under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + + +#include "Python.h" +#include "ct.h" +#include "ctnum.h" +#include +#include +#include +using namespace std; + + +// constants defined in the module +static PyObject *ErrorObject; + +// local includes +#include "pyutils.h" + +static PyObject * +py_new_matrix(PyObject *self, PyObject *args) +{ + int n, m; + if (!PyArg_ParseTuple(args, "ii:ct_newMatrix", &n, &m)) + return NULL; + int nn = newMatrix(n,m); + if (nn < 0) return reportCanteraError(); + return Py_BuildValue("i",nn); +} + +static PyObject* +py_matrix_delete(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:matrix_delete", &n)) return NULL; + delMatrix(n); + return Py_BuildValue("i",0); +} + +static PyObject* +py_matrix_newcopy(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:matrix_newcopy", &n)) return NULL; + return Py_BuildValue("i",matrix_copy(n)); +} + +static PyObject* +py_matrix_assign(PyObject *self, PyObject *args) +{ + int n, m; + if (!PyArg_ParseTuple(args, "ii:matrix_assign", &n, &m)) return NULL; + return Py_BuildValue("i",matrix_assign(n, m)); +} + +static PyObject* +py_matrix_nrows(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:matrix_nrows", &n)) return NULL; + return Py_BuildValue("i",matrix_nRows(n)); +} + +static PyObject* +py_matrix_ncols(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:matrix_ncols", &n)) return NULL; + return Py_BuildValue("i",matrix_nColumns(n)); +} + +static PyObject* +py_matrix_value(PyObject *self, PyObject *args) +{ + int nn,m,n; + if (!PyArg_ParseTuple(args, "iii:matrix_value", &nn, &m, &n)) return NULL; + return Py_BuildValue("d",matrix_value(nn,m,n)); +} + +static PyObject* +py_matrix_setvalue(PyObject *self, PyObject *args) +{ + int nn,m,n; + double v; + if (!PyArg_ParseTuple(args, "iiid:matrix_setvalue", &nn, &m, &n, &v)) return NULL; + return Py_BuildValue("d",matrix_setvalue(nn,m,n,v)); +} + +static PyObject* +py_matrix_solve(PyObject *self, PyObject *args) +{ + int na, nb; + if (!PyArg_ParseTuple(args, "ii:matrix_solve", &na, &nb)) return NULL; + int i = matrix_solve(na, nb); + if (i == -1) return reportCanteraError(); + return Py_BuildValue("i",i); +} + +static PyObject* +py_matrix_mult(PyObject *self, PyObject *args) +{ + int na, nb, np; + if (!PyArg_ParseTuple(args, "iii:matrix_mult", &na, &nb, &np)) return NULL; + int i = matrix_multiply(na, nb, np); + if (i == -1) return reportCanteraError(); + return Py_BuildValue("i",i); +} + +static PyObject* +py_matrix_invert(PyObject *self, PyObject *args) +{ + int na; + if (!PyArg_ParseTuple(args, "i:matrix_invert", &na)) return NULL; + int i = matrix_invert(na); + if (i == -1) return reportCanteraError(); + return Py_BuildValue("i",i); +} + + +static PyObject * +py_bandmatrix_new(PyObject *self, PyObject *args) +{ + int n, kl, ku; + if (!PyArg_ParseTuple(args, "iii:bandmatrix_new", &n, &kl, &ku)) + return NULL; + int nn = bmatrix_new(n,kl,ku); + if (nn < 0) return reportCanteraError(); + return Py_BuildValue("i",nn); +} + +static PyObject* +py_bandmatrix_delete(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:bandmatrix_delete", &n)) return NULL; + bmatrix_del(n); + return Py_BuildValue("i",0); +} + +static PyObject* +py_bandmatrix_newcopy(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:bandmatrix_newcopy", &n)) return NULL; + return Py_BuildValue("i",bmatrix_copy(n)); +} + +static PyObject* +py_bandmatrix_assign(PyObject *self, PyObject *args) +{ + int n, m; + if (!PyArg_ParseTuple(args, "ii:bandmatrix_assign", &n, &m)) return NULL; + return Py_BuildValue("i",bmatrix_assign(n, m)); +} + +static PyObject* +py_bandmatrix_nrows(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:bandmatrix_nrows", &n)) return NULL; + return Py_BuildValue("i",bmatrix_nRows(n)); +} + +static PyObject* +py_bandmatrix_ncols(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:bandmatrix_ncols", &n)) return NULL; + return Py_BuildValue("i",bmatrix_nColumns(n)); +} + +static PyObject* +py_bandmatrix_value(PyObject *self, PyObject *args) +{ + int nn,m,n; + if (!PyArg_ParseTuple(args, "iii:bandmatrix_value", &nn, &m, &n)) return NULL; + return Py_BuildValue("d",bmatrix_value(nn,m,n)); +} + +static PyObject* +py_bandmatrix_setvalue(PyObject *self, PyObject *args) +{ + int nn,m,n; + double v; + if (!PyArg_ParseTuple(args, "iiid:bandmatrix_setvalue", &nn, &m, &n, &v)) + return NULL; + return Py_BuildValue("d",bmatrix_setvalue(nn,m,n,v)); +} + +static PyObject* +py_bandmatrix_solve(PyObject *self, PyObject *args) +{ + int na, nb; + if (!PyArg_ParseTuple(args, "ii:bandmatrix_solve", &na, &nb)) + + return NULL; + int i = bmatrix_solve(na, nb); + if (i == -1) return reportCanteraError(); + return Py_BuildValue("i",i); +} + +static PyObject* +py_bandmatrix_mult(PyObject *self, PyObject *args) +{ + int na, nb, np; + if (!PyArg_ParseTuple(args, "iii:bandmatrix_mult", &na, &nb, &np)) + return NULL; + int i = bmatrix_multiply(na, nb, np); + if (i == -1) return reportCanteraError(); + return Py_BuildValue("i",i); +} + + +// static PyObject* +// num_getarray(PyObject *self, PyObject *args) +// { +// int n; +// int job; + +// if (!PyArg_ParseTuple(args, "ii:num_getarray", &n, &job)) +// return NULL; + +// // array attributes +// int iok = -22; +// int nrxns = kin_nReactions(kin); +// int nsp = phase_nSpecies(kin); +// vector x; +// switch (job) { +// case 1: +// x.resize(nrxns); +// iok = kin_getFwdRatesOfProgress(kin, nrxns, x.begin()); +// break; +// case 2: +// x.resize(nrxns); +// iok = kin_getRevRatesOfProgress(kin, nrxns, x.begin()); +// break; +// case 3: +// x.resize(nrxns); +// iok = kin_getEquilibriumConstants(kin, nrxns, x.begin()); +// break; +// default: +// ; +// } +// if (iok >= 0) { +// return pyNumericTuple_FromVector(x); +// } +// else if (iok == -1) { +// return reportCanteraError(); +// } +// else { +// PyErr_SetString(ErrorObject,"Unknown array attribute"); +// return NULL; +// } +// } + + +/* List of functions defined in the module */ + +static PyMethodDef ct_methods[] = { + {"Matrix", py_new_matrix, METH_VARARGS}, + {"matrix_delete", py_matrix_delete, METH_VARARGS}, + {"matrix_newcopy", py_matrix_newcopy, METH_VARARGS}, + {"matrix_assign", py_matrix_assign, METH_VARARGS}, + {"matrix_nrows", py_matrix_nrows, METH_VARARGS}, + {"matrix_ncols", py_matrix_ncols, METH_VARARGS}, + {"matrix_value", py_matrix_value, METH_VARARGS}, + {"matrix_setvalue", py_matrix_setvalue, METH_VARARGS}, + {"matrix_solve", py_matrix_solve, METH_VARARGS}, + {"matrix_mult", py_matrix_mult, METH_VARARGS}, + {"matrix_invert", py_matrix_invert, METH_VARARGS}, + {"BandMatrix", py_bandmatrix_new, METH_VARARGS}, + {"bandmatrix_delete", py_bandmatrix_delete, METH_VARARGS}, + {"bandmatrix_newcopy", py_bandmatrix_newcopy, METH_VARARGS}, + {"bandmatrix_assign", py_bandmatrix_assign, METH_VARARGS}, + {"bandmatrix_nrows", py_bandmatrix_nrows, METH_VARARGS}, + {"bandmatrix_ncols", py_bandmatrix_ncols, METH_VARARGS}, + {"bandmatrix_value", py_bandmatrix_value, METH_VARARGS}, + {"bandmatrix_setvalue", py_bandmatrix_setvalue, METH_VARARGS}, + {"bandmatrix_solve", py_bandmatrix_solve, METH_VARARGS}, + {"bandmatrix_mult", py_bandmatrix_mult, METH_VARARGS}, + //{"setfp", thermo_setfp, METH_VARARGS}, + //{"equil", thermo_equil, METH_VARARGS}, + {NULL, NULL} /* sentinel */ +}; + + +extern "C" { + + /* Initialization function for the module (*must* be called initctnumerics) */ + + DL_EXPORT(void) initctnumerics(void) + { + PyObject *m, *d; + + /* Initialize the type of the new type object here; doing it here + * is required for portability to Windows without requiring C++. */ + + /* Create the module and add the functions */ + m = Py_InitModule("ctnumerics", ct_methods); + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + ErrorObject = PyErr_NewException("cantera.error", NULL, NULL); + PyDict_SetItemString(d, "error", ErrorObject); + } + +} diff --git a/Cantera/python/src/ctnumerics.def b/Cantera/python/src/ctnumerics.def new file mode 100755 index 000000000..a83831e99 --- /dev/null +++ b/Cantera/python/src/ctnumerics.def @@ -0,0 +1,2 @@ +EXPORTS + initctnumerics \ No newline at end of file diff --git a/Cantera/python/src/ctphase.cpp b/Cantera/python/src/ctphase.cpp new file mode 100755 index 000000000..d36645d0e --- /dev/null +++ b/Cantera/python/src/ctphase.cpp @@ -0,0 +1,417 @@ +/** + * @file ctphase.cpp + * Cantera Python Interface + * + */ + +// turn off warnings about long names under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "Python.h" +#include "Numeric/arrayobject.h" +#include "ct.h" +#include +//#include +#include +using namespace std; + +//#include "Cantera.h" + +// constants defined in the module +static PyObject *ErrorObject; +static PyObject *OneAtmos; +static PyObject *GasCon; + +// local includes +#include "pyutils.h" + + + +// /** +// * Create a new Phase object. +// */ +// static PyObject * +// ct_newPhase(PyObject *self, PyObject *args) { +// int n = newPhase(); +// return Py_BuildValue("i",n); +// } + + +// /** +// * Delete the Phase object. +// */ +// static PyObject* +// phase_delete(PyObject *self, PyObject *args) +// { +// int ph; +// if (!PyArg_ParseTuple(args, "i:phase_delete", &ph)) +// return NULL; +// delPhase(ph); +// return Py_BuildValue("i",0); +// } + + +static PyObject* +py_temperature(PyObject *self, PyObject *args) { + int ph; + if (!PyArg_ParseTuple(args, "i:py_temperature", &ph)) return NULL; + return Py_BuildValue("d",phase_temperature(ph)); +} + +static PyObject* +py_density(PyObject *self, PyObject *args) { + int ph; + if (!PyArg_ParseTuple(args, "i:py_density", &ph)) return NULL; + return Py_BuildValue("d",phase_density(ph)); +} + +static PyObject* +py_molardensity(PyObject *self, PyObject *args) { + int ph; + if (!PyArg_ParseTuple(args, "i:py_molardensity", &ph)) return NULL; + return Py_BuildValue("d",phase_molarDensity(ph)); +} + +static PyObject* +py_meanmolwt(PyObject *self, PyObject *args) { + int ph; + if (!PyArg_ParseTuple(args, "i:py_meanmolwt", &ph)) return NULL; + return Py_BuildValue("d",phase_meanMolecularWeight(ph)); +} + +static PyObject* +py_molefraction(PyObject *self, PyObject *args) { + int ph, k; + if (!PyArg_ParseTuple(args, "ii:py_molefraction", &ph, &k)) return NULL; + return Py_BuildValue("d",phase_moleFraction(ph, k)); +} + +static PyObject* +py_massfraction(PyObject *self, PyObject *args) { + int ph, k; + if (!PyArg_ParseTuple(args, "ii:py_massfraction", &ph, &k)) return NULL; + return Py_BuildValue("d",phase_massFraction(ph, k)); +} + +static PyObject* +py_nelements(PyObject *self, PyObject *args) { + int ph; + if (!PyArg_ParseTuple(args, "i:py_nelements", &ph)) return NULL; + return Py_BuildValue("i",phase_nElements(ph)); +} + +static PyObject* +py_nspecies(PyObject *self, PyObject *args) { + int ph; + if (!PyArg_ParseTuple(args, "i:py_nspecies", &ph)) return NULL; + return Py_BuildValue("i",phase_nSpecies(ph)); +} + +static PyObject* +py_natoms(PyObject *self, PyObject *args) { + int ph, k, m; + if (!PyArg_ParseTuple(args, "iii:py_natoms", &ph, &k, &m)) return NULL; + return Py_BuildValue("d",phase_nAtoms(ph, k, m)); +} + +static PyObject* +py_addelement(PyObject *self, PyObject *args) { + int ph; + char* name; + double wt; + if (!PyArg_ParseTuple(args, "isd:py_addelement", &ph, &name, &wt)) + return NULL; + int ok = phase_addElement(ph, name, wt); + if (ok < 0) return reportError(ok); + else return Py_BuildValue("i",0); +} + +static PyObject* +py_elementindex(PyObject *self, PyObject *args) { + int ph; + char* nm; + if (!PyArg_ParseTuple(args, "is:py_elementindex", &ph, &nm)) return NULL; + int k = phase_elementIndex(ph,nm); + if (k >= 0) + return Py_BuildValue("i",k); + else { + PyErr_SetString(ErrorObject,( + "Unknown element ("+string(nm)+")").c_str()); + return NULL; + } +} + +static PyObject* +py_speciesindex(PyObject *self, PyObject *args) { + int ph; + char* nm; + if (!PyArg_ParseTuple(args, "is:py_speciesindex", &ph, &nm)) return NULL; + int k = phase_speciesIndex(ph,nm); + if (k >= 0) + return Py_BuildValue("i",k); + else { + PyErr_SetString(ErrorObject,( + "Unknown species ("+string(nm)+")").c_str()); + return NULL; + } +} + +static PyObject* +py_report(PyObject *self, PyObject *args) { + int th, show_thermo; + int buflen = 400; + char* output_buf = new char[buflen]; + if (!PyArg_ParseTuple(args, "ii:py_report", &th, &show_thermo)) + return NULL; + int iok = phase_report(th, buflen, output_buf, show_thermo); + if (iok < -1 && iok != -999) { + delete output_buf; + output_buf = new char[-iok]; + iok = phase_report(th, -iok, output_buf, show_thermo); + } + if (iok < 0) return reportError(iok); + PyObject* s = Py_BuildValue("s",output_buf); + delete output_buf; + return s; +} + + +static PyObject* +phase_getarray(PyObject *self, PyObject *args) +{ + int ph; + int job; + + if (!PyArg_ParseTuple(args, "ii:phase_getarray", &ph, &job)) + return NULL; + + // array attributes + int iok = -22; + PyArrayObject* x = 0; + double* xd = 0; + if (job > 10) { + + int nsp = phase_nSpecies(ph); + x = (PyArrayObject*)PyArray_FromDims(1, &nsp, PyArray_DOUBLE); + xd = (double*)x->data; + switch (job) { + case 20: + iok = phase_getMoleFractions(ph,nsp,xd); + break; + case 21: + iok = phase_getMassFractions(ph,nsp,xd); + break; + case 22: + iok = phase_getMolecularWeights(ph,nsp,xd); + break; + default: + ; + } + } + else { + + int nel = phase_nElements(ph); + x = (PyArrayObject*)PyArray_FromDims(1, &nel, PyArray_DOUBLE); + xd = (double*)x->data; + switch (job) { + case 1: + iok = phase_getAtomicWeights(ph,nel,xd); + break; + default: + ; + } + } + + if (iok >= 0) { + return PyArray_Return(x); + } + else { + PyErr_SetString(ErrorObject,"Unknown array attribute"); + return NULL; + } +} + +// string attributes +static PyObject* +phase_getstring(PyObject *self, PyObject *args) +{ + int ph, job, iok = -1; + int k; + int buflen; + char* output_buf = 0; + if (!PyArg_ParseTuple(args, "iii:phase_getstring", &ph, &job, &k)) + return NULL; + switch (job) { + case 1: + buflen = 20; + output_buf = new char[buflen]; + iok = phase_getElementName(ph, k, buflen, output_buf); + break; + case 2: + buflen = 40; + output_buf = new char[buflen]; + iok = phase_getSpeciesName(ph, k, buflen, output_buf); + break; + default: + iok = -10; + } + if (iok >= 0) { + PyObject* str = Py_BuildValue("s",output_buf); + delete output_buf; + return str; + } + delete output_buf; + if (iok == -1) + return reportCanteraError(); + else { + PyErr_SetString(ErrorObject,"Unknown string attribute"); + return NULL; + } +} + +static PyObject* +phase_setfp(PyObject *self, PyObject *args) +{ + double vv; + int iok = -2; + int ph; + int job; + + if (!PyArg_ParseTuple(args, "iid:phase_getfp", &ph, &job, &vv)) + return NULL; + + // set floating-point attributes + switch (job) { + case 1: + iok = phase_setTemperature(ph, vv); break; + case 2: + iok = phase_setDensity(ph, vv); break; + default: + iok = -10; + } + if (iok >= 0) + return Py_BuildValue("i",iok); + else { + PyErr_SetString(ErrorObject,"Unknown floating-point attribute"); + return NULL; + } +} + + +static PyObject* +phase_setarray(PyObject *self, PyObject *args) +{ + int ph; + int job; + int norm; + int iok; + PyObject* seq; + if (!PyArg_ParseTuple(args, "iiiO:phase_setarray", &ph, &job, &norm, &seq)) + return NULL; + //vector_fp v; + PyArrayObject* a = (PyArrayObject*)seq; + //iok = pyNumericSequence_ToVector(seq, v); + double* xd = (double*)a->data; + int len = a->dimensions[0]; + //if (iok == -1) { + // PyErr_SetString(ErrorObject, "Fourth argument must be a sequence"); + // return NULL; + //} + switch (job) { + case 1: + iok = phase_setMoleFractions(ph, len, xd, norm); + break; + case 2: + iok = phase_setMassFractions(ph, len, xd, norm); + break; + default: + iok = -10; + } + if (iok >= 0) + return Py_BuildValue("i",iok); + if (iok == -1) + return reportCanteraError(); + else { + PyErr_SetString(ErrorObject, "Error in phase_setarray"); + return NULL; + } +} + +static PyObject* +phase_setstring(PyObject *self, PyObject *args) +{ + int ph; + int job; + int iok; + char* str; + if (!PyArg_ParseTuple(args, "iis:phase_setstring", &ph, &job, &str)) + return NULL; + switch (job) { + case 1: + iok = phase_setMoleFractionsByName(ph, str); + break; + case 2: + iok = phase_setMassFractionsByName(ph, str); + break; + default: + iok = -10; + } + if (iok >= 0) + return Py_BuildValue("i",iok); + if (iok == -1) + return reportCanteraError(); + else { + PyErr_SetString(ErrorObject, "Error in phase_setstring"); + return NULL; + } +} + +/* List of functions defined in the module */ + +static PyMethodDef ct_methods[] = { + {"temperature", py_temperature, METH_VARARGS}, + {"density", py_density, METH_VARARGS}, + {"molardensity", py_molardensity, METH_VARARGS}, + {"meanmolwt", py_meanmolwt, METH_VARARGS}, + {"molefraction", py_molefraction, METH_VARARGS}, + {"massfraction", py_massfraction, METH_VARARGS}, + {"nelements", py_nelements, METH_VARARGS}, + {"nspecies", py_nspecies, METH_VARARGS}, + {"natoms", py_natoms, METH_VARARGS}, + {"addelement", py_addelement, METH_VARARGS}, + {"elementindex", py_elementindex, METH_VARARGS}, + {"speciesindex", py_speciesindex, METH_VARARGS}, + {"getarray", phase_getarray, METH_VARARGS}, + {"getstring", phase_getstring, METH_VARARGS}, + {"setfp", phase_setfp, METH_VARARGS}, + {"setarray", phase_setarray, METH_VARARGS}, + {"setstring", phase_setstring, METH_VARARGS}, + {"report", py_report, METH_VARARGS}, + {NULL, NULL} /* sentinel */ +}; + + +extern "C" { + + /* Initialization function for the module (*must* be called initctphase) */ + + DL_EXPORT(void) initctphase(void) + { + PyObject *m, *d; + + /* Initialize the type of the new type object here; doing it here + * is required for portability to Windows without requiring C++. */ + + /* Create the module and add the functions */ + m = Py_InitModule("ctphase", ct_methods); + import_array(); + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + ErrorObject = PyErr_NewException("cantera.error", NULL, NULL); + PyDict_SetItemString(d, "error", ErrorObject); + } +} diff --git a/Cantera/python/src/ctphase.def b/Cantera/python/src/ctphase.def new file mode 100755 index 000000000..59852c9fc --- /dev/null +++ b/Cantera/python/src/ctphase.def @@ -0,0 +1,2 @@ +EXPORTS + initctphase \ No newline at end of file diff --git a/Cantera/python/src/ctphase_methods.cpp b/Cantera/python/src/ctphase_methods.cpp new file mode 100644 index 000000000..c808e6e50 --- /dev/null +++ b/Cantera/python/src/ctphase_methods.cpp @@ -0,0 +1,298 @@ + +static PyObject* +py_temperature(PyObject *self, PyObject *args) { + int ph; + if (!PyArg_ParseTuple(args, "i:py_temperature", &ph)) return NULL; + return Py_BuildValue("d",phase_temperature(ph)); +} + +static PyObject* +py_density(PyObject *self, PyObject *args) { + int ph; + if (!PyArg_ParseTuple(args, "i:py_density", &ph)) return NULL; + return Py_BuildValue("d",phase_density(ph)); +} + +static PyObject* +py_molardensity(PyObject *self, PyObject *args) { + int ph; + if (!PyArg_ParseTuple(args, "i:py_molardensity", &ph)) return NULL; + return Py_BuildValue("d",phase_molarDensity(ph)); +} + +static PyObject* +py_meanmolwt(PyObject *self, PyObject *args) { + int ph; + if (!PyArg_ParseTuple(args, "i:py_meanmolwt", &ph)) return NULL; + return Py_BuildValue("d",phase_meanMolecularWeight(ph)); +} + +static PyObject* +py_molefraction(PyObject *self, PyObject *args) { + int ph, k; + if (!PyArg_ParseTuple(args, "ii:py_molefraction", &ph, &k)) return NULL; + return Py_BuildValue("d",phase_moleFraction(ph, k)); +} + +static PyObject* +py_massfraction(PyObject *self, PyObject *args) { + int ph, k; + if (!PyArg_ParseTuple(args, "ii:py_massfraction", &ph, &k)) return NULL; + return Py_BuildValue("d",phase_massFraction(ph, k)); +} + +static PyObject* +py_nelements(PyObject *self, PyObject *args) { + int ph; + if (!PyArg_ParseTuple(args, "i:py_nelements", &ph)) return NULL; + return Py_BuildValue("i",phase_nElements(ph)); +} + +static PyObject* +py_nspecies(PyObject *self, PyObject *args) { + int ph; + if (!PyArg_ParseTuple(args, "i:py_nspecies", &ph)) return NULL; + return Py_BuildValue("i",phase_nSpecies(ph)); +} + +static PyObject* +py_natoms(PyObject *self, PyObject *args) { + int ph, k, m; + if (!PyArg_ParseTuple(args, "iii:py_natoms", &ph, &k, &m)) return NULL; + return Py_BuildValue("d",phase_nAtoms(ph, k, m)); +} + +static PyObject* +py_addelement(PyObject *self, PyObject *args) { + int ph; + char* name; + double wt; + if (!PyArg_ParseTuple(args, "isd:py_addelement", &ph, &name, &wt)) + return NULL; + int ok = phase_addElement(ph, name, wt); + if (ok < 0) return reportError(ok); + else return Py_BuildValue("i",0); +} + +static PyObject* +py_elementindex(PyObject *self, PyObject *args) { + int ph; + char* nm; + if (!PyArg_ParseTuple(args, "is:py_elementindex", &ph, &nm)) return NULL; + int k = phase_elementIndex(ph,nm); + return Py_BuildValue("i",k); +} + +static PyObject* +py_speciesindex(PyObject *self, PyObject *args) { + int ph; + char* nm; + if (!PyArg_ParseTuple(args, "is:py_speciesindex", &ph, &nm)) return NULL; + int k = phase_speciesIndex(ph,nm); + return Py_BuildValue("i",k); +} + +static PyObject* +py_report(PyObject *self, PyObject *args) { + int th, show_thermo; + int buflen = 400; + char* output_buf = new char[buflen]; + if (!PyArg_ParseTuple(args, "ii:py_report", &th, &show_thermo)) + return NULL; + int iok = phase_report(th, buflen, output_buf, show_thermo); + if (iok < -1 && iok != -999) { + delete output_buf; + output_buf = new char[-iok]; + iok = phase_report(th, -iok, output_buf, show_thermo); + } + if (iok < 0) return reportError(iok); + PyObject* s = Py_BuildValue("s",output_buf); + delete output_buf; + return s; +} + + +static PyObject* +phase_getarray(PyObject *self, PyObject *args) +{ + int ph; + int job; + + if (!PyArg_ParseTuple(args, "ii:phase_getarray", &ph, &job)) + return NULL; + + // array attributes + int iok = -22; + PyArrayObject* x = 0; + double* xd = 0; + if (job > 10) { + + int nsp = phase_nSpecies(ph); + x = (PyArrayObject*)PyArray_FromDims(1, &nsp, PyArray_DOUBLE); + xd = (double*)x->data; + switch (job) { + case 20: + iok = phase_getMoleFractions(ph,nsp,xd); + break; + case 21: + iok = phase_getMassFractions(ph,nsp,xd); + break; + case 22: + iok = phase_getMolecularWeights(ph,nsp,xd); + break; + default: + ; + } + } + else { + + int nel = phase_nElements(ph); + x = (PyArrayObject*)PyArray_FromDims(1, &nel, PyArray_DOUBLE); + xd = (double*)x->data; + switch (job) { + case 1: + iok = phase_getAtomicWeights(ph,nel,xd); + break; + default: + ; + } + } + + if (iok >= 0) { + return PyArray_Return(x); + } + else { + PyErr_SetString(ErrorObject,"Unknown array attribute"); + return NULL; + } +} + +// string attributes +static PyObject* +phase_getstring(PyObject *self, PyObject *args) +{ + int ph, job, iok = -1; + int k; + int buflen; + char* output_buf = 0; + if (!PyArg_ParseTuple(args, "iii:phase_getstring", &ph, &job, &k)) + return NULL; + switch (job) { + case 1: + buflen = 20; + output_buf = new char[buflen]; + iok = phase_getElementName(ph, k, buflen, output_buf); + break; + case 2: + buflen = 40; + output_buf = new char[buflen]; + iok = phase_getSpeciesName(ph, k, buflen, output_buf); + break; + default: + iok = -10; + } + if (iok >= 0) { + PyObject* str = Py_BuildValue("s",output_buf); + delete output_buf; + return str; + } + delete output_buf; + if (iok == -1) + return reportCanteraError(); + else { + PyErr_SetString(ErrorObject,"Unknown string attribute"); + return NULL; + } +} + +static PyObject* +phase_setfp(PyObject *self, PyObject *args) +{ + double vv; + int iok = -2; + int ph; + int job; + + if (!PyArg_ParseTuple(args, "iid:phase_getfp", &ph, &job, &vv)) + return NULL; + + // set floating-point attributes + switch (job) { + case 1: + iok = phase_setTemperature(ph, vv); break; + case 2: + iok = phase_setDensity(ph, vv); break; + default: + iok = -10; + } + if (iok >= 0) + return Py_BuildValue("i",iok); + else { + PyErr_SetString(ErrorObject,"Unknown floating-point attribute"); + return NULL; + } +} + + +static PyObject* +phase_setarray(PyObject *self, PyObject *args) +{ + int ph; + int job; + int norm; + int iok; + PyObject* seq; + if (!PyArg_ParseTuple(args, "iiiO:phase_setarray", &ph, &job, &norm, &seq)) + return NULL; + PyArrayObject* a = (PyArrayObject*)seq; + double* xd = (double*)a->data; + int len = a->dimensions[0]; + switch (job) { + case 1: + iok = phase_setMoleFractions(ph, len, xd, norm); + break; + case 2: + iok = phase_setMassFractions(ph, len, xd, norm); + break; + default: + iok = -10; + } + if (iok >= 0) + return Py_BuildValue("i",iok); + if (iok == -1) + return reportCanteraError(); + else { + PyErr_SetString(ErrorObject, "Error in phase_setarray"); + return NULL; + } +} + +static PyObject* +phase_setstring(PyObject *self, PyObject *args) +{ + int ph; + int job; + int iok; + char* str; + if (!PyArg_ParseTuple(args, "iis:phase_setstring", &ph, &job, &str)) + return NULL; + switch (job) { + case 1: + iok = phase_setMoleFractionsByName(ph, str); + break; + case 2: + iok = phase_setMassFractionsByName(ph, str); + break; + default: + iok = -10; + } + if (iok >= 0) + return Py_BuildValue("i",iok); + if (iok == -1) + return reportCanteraError(); + else { + PyErr_SetString(ErrorObject, "Error in phase_setstring"); + return NULL; + } +} + diff --git a/Cantera/python/src/ctpy.cpp b/Cantera/python/src/ctpy.cpp new file mode 100755 index 000000000..8e86d4045 --- /dev/null +++ b/Cantera/python/src/ctpy.cpp @@ -0,0 +1,85 @@ +/** + * @file ctpy.cpp + * Cantera Python Interface + * + */ + +// turn off warnings about long names under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "Python.h" +#include "ct.h" +#include +using namespace std; + +// constants defined in the module +static PyObject *ErrorObject; +static PyObject *OneAtmos; +static PyObject *GasCon; + +// local includes +#include "pyutils.h" + + +static reportCanteraError() { + PyErr_SetString(ErrorObject, + Cantera::Application::errorMessage.back().c_str()); + return NULL; +} + + +static PyObject * +ct_newPhase(PyObject *self, PyObject *args) +{ + CtPhase *rv=0; + int job; + if (!PyArg_ParseTuple(args, "i:ct_newPhase", &job)) + return NULL; + int n = newPhase(job); + if (n < 0) { + PyErr_SetString(ErrorObject,"Unknown species thermo manager"); + return NULL; + } + return Py_BuildValue("i",n); +} + + +/* List of functions defined in the module */ + +static PyMethodDef ct_methods[] = { + {"Phase", ct_newPhase, METH_VARARGS}, + {NULL, NULL} /* sentinel */ +}; + + +extern "C" { + + /* Initialization function for the module (*must* be called initct) */ + + DL_EXPORT(void) initct(void) + { + PyObject *m, *d; + + /* Initialize the type of the new type object here; doing it here + * is required for portability to Windows without requiring C++. */ + + /* Create the module and add the functions */ + m = Py_InitModule("ct", ct_methods); + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + ErrorObject = PyErr_NewException("cantera.error", NULL, NULL); + PyDict_SetItemString(d, "error", ErrorObject); + + // one atmosphere + OneAtmos = PyFloat_FromDouble(OneAtm); + PyDict_SetItemString(d, "OneAtm", OneAtmos); + + // gas constant + GasCon = PyFloat_FromDouble(GasConstant); + PyDict_SetItemString(d, "GasConstant", GasCon); + } +} diff --git a/Cantera/python/src/ctpybndry.cpp b/Cantera/python/src/ctpybndry.cpp new file mode 100755 index 000000000..bde3d63a4 --- /dev/null +++ b/Cantera/python/src/ctpybndry.cpp @@ -0,0 +1,156 @@ + +/** + * @file ctpybndry.cpp + * + */ + +// turn off warnings about long names under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + + +#include "Python.h" +#include "Numeric/arrayobject.h" + +#include "ct.h" +#include "ctbdry.h" + +// constants defined in the module +static PyObject *ErrorObject; + +// local includes +#include "pyutils.h" +#include +using namespace std; + +static PyObject* +py_bndry_new(PyObject *self, PyObject *args) +{ + int itype; + if (!PyArg_ParseTuple(args, "i:bndry_new", &itype)) + return NULL; + int iok = bndry_new(itype); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_bndry_del(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:bndry_del", &n)) + return NULL; + bndry_del(n); + return Py_BuildValue("i",0); +} + +static PyObject* +py_bndry_temperature(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:bndry_temperature", &n)) + return NULL; + double t = bndry_temperature(n); + return Py_BuildValue("d",t); +} + +static PyObject* +py_bndry_settemperature(PyObject *self, PyObject *args) +{ + int n; + double t; + if (!PyArg_ParseTuple(args, "id:bndry_settemperature", &n, &t)) + return NULL; + int iok = bndry_settemperature(n, t); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_bndry_mdot(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:bndry_mdot", &n)) + return NULL; + double mdot = bndry_mdot(n); + return Py_BuildValue("d",mdot); +} + +static PyObject* +py_bndry_setmdot(PyObject *self, PyObject *args) +{ + int n; + double mdot; + if (!PyArg_ParseTuple(args, "id:bndry_setmdot", &n, &mdot)) + return NULL; + int iok = bndry_setmdot(n, mdot); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_bndry_setxinbyname(PyObject *self, PyObject *args) +{ + int n; + char* xin; + //PyObject* o; + if (!PyArg_ParseTuple(args, "is:bndry_setxin", &n, &xin)) + return NULL; + //double* x = (double*)((PyArrayObject*)o)->data; + int iok = bndry_setxinbyname(n, xin); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + + +static PyObject* +py_bndry_setxin(PyObject *self, PyObject *args) +{ + int n; + PyObject* xin; + if (!PyArg_ParseTuple(args, "iO:bndry_setxin", &n, &xin)) + return NULL; + double* x = (double*)((PyArrayObject*)xin)->data; + int iok = bndry_setxin(n, x); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + + +static PyMethodDef ct_methods[] = { + {"bndry_temperature", py_bndry_temperature, METH_VARARGS}, + {"bndry_setxin", py_bndry_setxin, METH_VARARGS}, + {"bndry_setxinbyname", py_bndry_setxinbyname, METH_VARARGS}, + {"bndry_settemperature", py_bndry_settemperature, METH_VARARGS}, + {"bndry_new", py_bndry_new, METH_VARARGS}, + {"bndry_del", py_bndry_del, METH_VARARGS}, + {"bndry_mdot", py_bndry_mdot, METH_VARARGS}, + {"bndry_setmdot", py_bndry_setmdot, METH_VARARGS}, + {NULL, NULL} +}; + +extern "C" { + + /* Initialization function for the module */ + + DL_EXPORT(void) initctbndry(void) + { + PyObject *m, *d; + + /* Initialize the type of the new type object here; doing it here + * is required for portability to Windows without requiring C++. */ + + /* Create the module and add the functions */ + m = Py_InitModule("ctbndry", ct_methods); + import_array(); + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + ErrorObject = PyErr_NewException("cantera.error", NULL, NULL); + PyDict_SetItemString(d, "error", ErrorObject); + } + +} + diff --git a/Cantera/python/src/ctpyfunc.cpp b/Cantera/python/src/ctpyfunc.cpp new file mode 100644 index 000000000..43b86eb61 --- /dev/null +++ b/Cantera/python/src/ctpyfunc.cpp @@ -0,0 +1,108 @@ + +/** + * @file ctpyfunc1.cpp + * + */ + +// turn off warnings about long names under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include +using namespace std; + +#include "Python.h" +#include "Numeric/arrayobject.h" + +#include "ct.h" +#include "ctfunc.h" + +// constants defined in the module +static PyObject *ErrorObject; + +// local includes +#include "pyutils.h" + + +static PyObject* +py_func_new(PyObject *self, PyObject *args) +{ + int type, n; + PyObject* c; + if (!PyArg_ParseTuple(args, "iiO:func_new", &type, &n, &c)) + return NULL; + PyArrayObject* coeffs = (PyArrayObject*)c; + double* xd = (double*)coeffs->data; + int lenc = coeffs->dimensions[0]; + int nn = func_new(type, n, lenc, xd); + if (nn < 0) return reportError(nn); + return Py_BuildValue("i",nn); +} + +static PyObject* +py_func_newcombo(PyObject *self, PyObject *args) +{ + int type, n, m; + if (!PyArg_ParseTuple(args, "iii:func_newcombo", &type, &n, &m)) + return NULL; + int nn = func_new(type, n, m, 0); + if (nn < 0) return reportError(nn); + return Py_BuildValue("i",nn); +} + +static PyObject* +py_func_del(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:func_del", &n)) + return NULL; + int iok = func_del(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_func_value(PyObject *self, PyObject *args) +{ + int n; + double t; + if (!PyArg_ParseTuple(args, "id:func_value", &n, &t)) + return NULL; + double r = func_value(n, t); + return Py_BuildValue("d",r); +} + + +static PyMethodDef ct_methods[] = { + {"func_new", py_func_new, METH_VARARGS}, + {"func_newcombo", py_func_newcombo, METH_VARARGS}, + {"func_del", py_func_del, METH_VARARGS}, + {"func_value", py_func_value, METH_VARARGS}, + {NULL, NULL} +}; + +extern "C" { + + /* Initialization function for the module */ + + DL_EXPORT(void) initctfunc(void) + { + PyObject *m, *d; + + /* Initialize the type of the new type object here; doing it here + * is required for portability to Windows without requiring C++. */ + + /* Create the module and add the functions */ + m = Py_InitModule("ctfunc", ct_methods); + import_array(); + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + ErrorObject = PyErr_NewException("cantera.error", NULL, NULL); + PyDict_SetItemString(d, "error", ErrorObject); + } + +} + diff --git a/Cantera/python/src/ctpyreactor.cpp b/Cantera/python/src/ctpyreactor.cpp new file mode 100755 index 000000000..680cc65ab --- /dev/null +++ b/Cantera/python/src/ctpyreactor.cpp @@ -0,0 +1,685 @@ + +/** + * @file ctpyreactor.cpp + * + */ + +// turn off warnings about long names under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + + +#include "Python.h" +#include "Numeric/arrayobject.h" + +#include "ct.h" +#include "ctreactor.h" + +// constants defined in the module +static PyObject *ErrorObject; + +// local includes +#include "pyutils.h" + + +static PyObject* +py_reactor_new(PyObject *self, PyObject *args) +{ + int type; + if (!PyArg_ParseTuple(args, "i:reactor_new", &type)) + return NULL; + int n = reactor_new(type); + return Py_BuildValue("i",n); +} + +static PyObject* +py_reactor_del(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:reactor_del", &n)) + return NULL; + int iok = reactor_del(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_reactor_setInitialVolume(PyObject *self, PyObject *args) +{ + int n; + double v; + if (!PyArg_ParseTuple(args, "id:reactor_setInitialVolume", &n, &v)) + return NULL; + int iok = reactor_setInitialVolume(n,v); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_reactor_setInitialTime(PyObject *self, PyObject *args) +{ + int n; + double t; + if (!PyArg_ParseTuple(args, "id:reactor_setInitialTime", &n, &t)) + return NULL; + int iok = reactor_setInitialTime(n, t); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_reactor_setEnergy(PyObject *self, PyObject *args) +{ + int n, eflag; + if (!PyArg_ParseTuple(args, "ii:reactor_setEnergy", &n, &eflag)) + return NULL; + int iok = reactor_setEnergy(n, eflag); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_reactor_setThermoMgr(PyObject *self, PyObject *args) +{ + int n; + int th; + if (!PyArg_ParseTuple(args, "ii:reactor_setThermoMgr", &n, &th)) + return NULL; + int iok = reactor_setThermoMgr(n, th); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_reactor_setKineticsMgr(PyObject *self, PyObject *args) +{ + int n; + int kin; + if (!PyArg_ParseTuple(args, "ii:reactor_setKineticsMgr", &n, &kin)) + return NULL; + int iok = reactor_setKineticsMgr(n, kin); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_reactor_advance(PyObject *self, PyObject *args) +{ + int n; + double t; + if (!PyArg_ParseTuple(args, "id:reactor_advance", &n, &t)) + return NULL; + int iok = reactor_advance(n, t); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_reactor_step(PyObject *self, PyObject *args) +{ + int n; + double t; + if (!PyArg_ParseTuple(args, "id:reactor_step", &n, &t)) + return NULL; + return Py_BuildValue("d",reactor_step(n, t)); +} + +static PyObject* +py_reactor_time(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:reactor_time", &n)) + return NULL; + double t = reactor_time(n); + return Py_BuildValue("d",t); +} + +static PyObject* +py_reactor_mass(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:reactor_mass", &n)) + return NULL; + double m = reactor_mass(n); + return Py_BuildValue("d",m); +} + +static PyObject* +py_reactor_volume(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:reactor_volume", &n)) + return NULL; + double v = reactor_volume(n); + return Py_BuildValue("d",v); +} + +static PyObject* +py_reactor_density(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:reactor_density", &n)) + return NULL; + double rho = reactor_density(n); + return Py_BuildValue("d",rho); +} + +static PyObject* +py_reactor_temperature(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:reactor_temperature", &n)) + return NULL; + double t = reactor_temperature(n); + return Py_BuildValue("d",t); +} + +static PyObject* +py_reactor_enthalpy_mass(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:reactor_enthalpy_mass", &n)) + return NULL; + double h = reactor_enthalpy_mass(n); + return Py_BuildValue("d",h); +} + +static PyObject* +py_reactor_intEnergy_mass(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:reactor_intEnergy_mass", &n)) + return NULL; + double u = reactor_intEnergy_mass(n); + return Py_BuildValue("d",u); +} + +static PyObject* +py_reactor_pressure(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:reactor_pressure", &n)) + return NULL; + double p = reactor_pressure(n); + return Py_BuildValue("d",p); +} + +static PyObject* +py_reactor_massFraction(PyObject *self, PyObject *args) +{ + int n; + int k; + if (!PyArg_ParseTuple(args, "ii:reactor_massFraction", &n, &k)) + return NULL; + double y = reactor_massFraction(n, k); + return Py_BuildValue("d",y); +} + +// static PyObject* +// py_reactor_setArea(PyObject *self, PyObject *args) +// { +// int n; +// double a; +// if (!PyArg_ParseTuple(args, "id:reactor_setArea", &n, &a)) +// return NULL; +// int iok = reactor_setArea(n,a); +// if (iok < 0) return reportError(iok); +// return Py_BuildValue("i",0); +// } + +// static PyObject* +// py_reactor_setExtTemp(PyObject *self, PyObject *args) +// { +// int n; +// double t; +// if (!PyArg_ParseTuple(args, "id:reactor_setExtTemp", &n, &t)) +// return NULL; +// int iok = reactor_setExtTemp(n, t); +// if (iok < 0) return reportError(iok); +// return Py_BuildValue("i",0); +// } + +// static PyObject* +// py_reactor_setExtRadTemp(PyObject *self, PyObject *args) +// { +// int n; +// double t; +// if (!PyArg_ParseTuple(args, "id:reactor_setExtRadTemp", &n, &t)) +// return NULL; +// int iok = reactor_setExtRadTemp(n, t); +// if (iok < 0) return reportError(iok); +// return Py_BuildValue("i",0); +// } + +// static PyObject* +// py_reactor_setVDotCoeff(PyObject *self, PyObject *args) +// { +// int n; +// double vdt; +// if (!PyArg_ParseTuple(args, "id:reactor_setVDotCoeff", &n, &vdt)) +// return NULL; +// int iok = reactor_setVDotCoeff(n, vdt); +// if (iok < 0) return reportError(iok); +// return Py_BuildValue("i",0); +// } + +// static PyObject* +// py_reactor_setHeatTransferCoeff(PyObject *self, PyObject *args) +// { +// int n; +// double h; +// if (!PyArg_ParseTuple(args, "id:reactor_setHeatTransferCoeff", &n, &h)) +// return NULL; +// int iok = reactor_setHeatTransferCoeff(n, h); +// if (iok < 0) return reportError(iok); +// return Py_BuildValue("i",0); +// } + +// static PyObject* +// py_reactor_setEmissivity(PyObject *self, PyObject *args) +// { +// int n; +// double e; +// if (!PyArg_ParseTuple(args, "id:reactor_setEmissivity", &n, &e)) +// return NULL; +// int iok = reactor_setEmissivity(n, e); +// if (iok < 0) return reportError(iok); +// return Py_BuildValue("i",0); +// } + +// static PyObject* +// py_reactor_setExtPressure(PyObject *self, PyObject *args) +// { +// int n; +// double p; +// if (!PyArg_ParseTuple(args, "id:reactor_setExtPressure", &n, &p)) +// return NULL; +// int iok = reactor_setExtPressure(n,p); +// if (iok < 0) return reportError(iok); +// return Py_BuildValue("i",0); +// } + +static PyObject* +py_flowdev_new(PyObject *self, PyObject *args) +{ + int type; + if (!PyArg_ParseTuple(args, "i:flowdev_new", &type)) + return NULL; + int n = flowdev_new(type); + return Py_BuildValue("i",n); +} + +static PyObject* +py_flowdev_del(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:flowdev_del", &n)) + return NULL; + int iok = flowdev_del(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_flowdev_install(PyObject *self, PyObject *args) +{ + int n, r1, r2; + if (!PyArg_ParseTuple(args, "iii:flowdev_install", &n, &r1, &r2)) + return NULL; + int iok = flowdev_install(n, r1, r2); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_flowdev_massFlowRate(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:flowdev_massFlowRate", &n)) + return NULL; + double mdot = flowdev_massFlowRate(n); + return Py_BuildValue("d",mdot); +} + +static PyObject* +py_flowdev_setpoint(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:flowdev_setpoint", &n)) + return NULL; + double v = flowdev_setpoint(n); + return Py_BuildValue("d",v); +} + +static PyObject* +py_flowdev_setSetpoint(PyObject *self, PyObject *args) +{ + int n; + double v; + if (!PyArg_ParseTuple(args, "id:flowdev_setSetpoint", &n, &v)) + return NULL; + int iok = flowdev_setSetpoint(n, v); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +// static PyObject* +// py_flowdev_setGains(PyObject *self, PyObject *args) +// { +// int n, sz; +// PyObject* gains; +// if (!PyArg_ParseTuple(args, "iiO:flowdev_setGains", &n, &sz, &gains)) +// return NULL; +// double* x = (double*)((PyArrayObject*)gains)->data; +// int iok = flowdev_setGains(n, sz, x); +// if (iok < 0) return reportError(iok); +// return Py_BuildValue("i",0); +// } + +static PyObject* +py_flowdev_setParameters(PyObject *self, PyObject *args) +{ + int n, sz; + PyObject* c; + if (!PyArg_ParseTuple(args, "iiO:flowdev_setParameters", &n, &sz, &c)) + return NULL; + double* x = (double*)((PyArrayObject*)c)->data; + int iok = flowdev_setParameters(n, sz, x); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_flowdev_setFunction(PyObject *self, PyObject *args) +{ + int n, m; + if (!PyArg_ParseTuple(args, "ii:flowdev_setFunction", &n, &m)) + return NULL; + int iok = flowdev_setFunction(n, m); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +// static PyObject* +// py_flowdev_getGains(PyObject *self, PyObject *args) +// { +// int n, sz; +// if (!PyArg_ParseTuple(args, "ii:flowdev_getGains", &n, &sz)) +// return NULL; +// PyArrayObject* x = +// (PyArrayObject*)PyArray_FromDims(1, &sz, PyArray_DOUBLE); +// double* xd = (double*)x->data; +// int iok = flowdev_getGains(n, sz, xd); +// if (iok < 0) return reportError(iok); +// return PyArray_Return(x); +// } + +// static PyObject* +// py_flowdev_reset(PyObject *self, PyObject *args) +// { +// int n; +// if (!PyArg_ParseTuple(args, "i:flowdev_reset", &n)) +// return NULL; +// int iok = flowdev_reset(n); +// if (iok < 0) return reportError(iok); +// return Py_BuildValue("i",0); +// } + +// static PyObject* +// py_flowdev_update(PyObject *self, PyObject *args) +// { +// int n; +// if (!PyArg_ParseTuple(args, "i:flowdev_update", &n)) +// return NULL; +// int iok = flowdev_update(n); +// if (iok < 0) return reportError(iok); +// return Py_BuildValue("i",0); +// } + +// static PyObject* +// py_flowdev_maxError(PyObject *self, PyObject *args) +// { +// int n; +// if (!PyArg_ParseTuple(args, "i:flowdev_maxError", &n)) +// return NULL; +// double e = flowdev_maxError(n); +// return Py_BuildValue("d",e); +// } + +static PyObject* +py_flowdev_ready(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:flowdev_ready", &n)) + return NULL; + int iok = flowdev_ready(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + + +static PyObject* +py_wall_new(PyObject *self, PyObject *args) +{ + int type; + if (!PyArg_ParseTuple(args, "i:wall_new", &type)) + return NULL; + int n = wall_new(type); + return Py_BuildValue("i",n); +} + +static PyObject* +py_wall_del(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:wall_del", &n)) + return NULL; + int iok = wall_del(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_wall_install(PyObject *self, PyObject *args) +{ + int n, r1, r2; + if (!PyArg_ParseTuple(args, "iii:wall_install", &n, &r1, &r2)) + return NULL; + int iok = wall_install(n, r1, r2); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_wall_vdot(PyObject *self, PyObject *args) +{ + int n; + double t; + if (!PyArg_ParseTuple(args, "id:wall_vdot", &n, &t)) + return NULL; + double vdt = wall_vdot(n,t); + return Py_BuildValue("d",vdt); +} + +static PyObject* +py_wall_Q(PyObject *self, PyObject *args) +{ + int n; + double t; + if (!PyArg_ParseTuple(args, "id:wall_Q", &n, &t)) + return NULL; + return Py_BuildValue("d",wall_Q(n, t)); +} + +static PyObject* +py_wall_area(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:wall_area", &n)) + return NULL; + return Py_BuildValue("d",wall_area(n)); +} + +static PyObject* +py_wall_setArea(PyObject *self, PyObject *args) +{ + int n; + double area; + if (!PyArg_ParseTuple(args, "id:wall_setArea", &n, &area)) + return NULL; + int iok = wall_setArea(n, area); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_wall_setThermalResistance(PyObject *self, PyObject *args) +{ + int n; + double rth; + if (!PyArg_ParseTuple(args, "id:wall_setThermalResistance", &n, &rth)) + return NULL; + int iok = wall_setThermalResistance(n,rth); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_wall_setHeatTransferCoeff(PyObject *self, PyObject *args) +{ + int n; + double u; + if (!PyArg_ParseTuple(args, "id:wall_setHeatTransferCoeff", &n, &u)) + return NULL; + int iok = wall_setHeatTransferCoeff(n,u); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_wall_setExpansionRateCoeff(PyObject *self, PyObject *args) +{ + int n; + double k; + if (!PyArg_ParseTuple(args, "id:wall_setExpansionRateCoeff", &n, &k)) + return NULL; + int iok = wall_setExpansionRateCoeff(n,k); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_wall_setExpansionRate(PyObject *self, PyObject *args) +{ + int n, m; + if (!PyArg_ParseTuple(args, "ii:wall_setExpansionRate", &n, &m)) + return NULL; + int iok = wall_setExpansionRate(n,m); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_wall_setHeatFlux(PyObject *self, PyObject *args) +{ + int n, m; + if (!PyArg_ParseTuple(args, "ii:wall_setHeatFlux", &n, &m)) + return NULL; + int iok = wall_setHeatFlux(n,m); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_wall_ready(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:wall_ready", &n)) + return NULL; + int iok = wall_ready(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + + +static PyMethodDef ct_methods[] = { + // {"reactor_setExtTemp", py_reactor_setExtTemp, METH_VARARGS}, + {"flowdev_ready", py_flowdev_ready, METH_VARARGS}, + //{"reactor_setEmissivity", py_reactor_setEmissivity, METH_VARARGS}, + {"reactor_setInitialTime", py_reactor_setInitialTime, METH_VARARGS}, + {"flowdev_new", py_flowdev_new, METH_VARARGS}, + {"flowdev_massFlowRate", py_flowdev_massFlowRate, METH_VARARGS}, + {"flowdev_del", py_flowdev_del, METH_VARARGS}, + {"flowdev_setpoint", py_flowdev_setpoint, METH_VARARGS}, + {"reactor_temperature", py_reactor_temperature, METH_VARARGS}, + {"flowdev_setSetpoint", py_flowdev_setSetpoint, METH_VARARGS}, + //{"flowdev_reset", py_flowdev_reset, METH_VARARGS}, + //{"reactor_setExtRadTemp", py_reactor_setExtRadTemp, METH_VARARGS}, + {"flowdev_install", py_flowdev_install, METH_VARARGS}, + {"reactor_setThermoMgr", py_reactor_setThermoMgr, METH_VARARGS}, + {"reactor_setEnergy", py_reactor_setEnergy, METH_VARARGS}, + {"reactor_volume", py_reactor_volume, METH_VARARGS}, + {"reactor_time", py_reactor_time, METH_VARARGS}, + {"reactor_advance", py_reactor_advance, METH_VARARGS}, + {"reactor_step", py_reactor_step, METH_VARARGS}, + //{"reactor_setExtPressure", py_reactor_setExtPressure, METH_VARARGS}, + //{"flowdev_setGains", py_flowdev_setGains, METH_VARARGS}, + {"flowdev_setParameters", py_flowdev_setParameters, METH_VARARGS}, + {"flowdev_setFunction", py_flowdev_setFunction, METH_VARARGS}, + {"reactor_mass", py_reactor_mass, METH_VARARGS}, + {"reactor_new", py_reactor_new, METH_VARARGS}, + //{"reactor_setVDotCoeff", py_reactor_setVDotCoeff, METH_VARARGS}, + //{"reactor_setHeatTransferCoeff", py_reactor_setHeatTransferCoeff, METH_VARARGS}, + {"reactor_enthalpy_mass", py_reactor_enthalpy_mass, METH_VARARGS}, + //{"flowdev_maxError", py_flowdev_maxError, METH_VARARGS}, + //{"flowdev_getGains", py_flowdev_getGains, METH_VARARGS}, + //{"flowdev_update", py_flowdev_update, METH_VARARGS}, + //{"reactor_setArea", py_reactor_setArea, METH_VARARGS}, + {"reactor_pressure", py_reactor_pressure, METH_VARARGS}, + {"reactor_setInitialVolume", py_reactor_setInitialVolume, METH_VARARGS}, + {"reactor_density", py_reactor_density, METH_VARARGS}, + {"reactor_setKineticsMgr", py_reactor_setKineticsMgr, METH_VARARGS}, + {"reactor_del", py_reactor_del, METH_VARARGS}, + {"reactor_intEnergy_mass", py_reactor_intEnergy_mass, METH_VARARGS}, + {"reactor_massFraction", py_reactor_massFraction, METH_VARARGS}, + {"wall_install", py_wall_install, METH_VARARGS}, + {"wall_area", py_wall_area, METH_VARARGS}, + {"wall_setArea", py_wall_setArea, METH_VARARGS}, + {"wall_setThermalResistance", py_wall_setThermalResistance, METH_VARARGS}, + {"wall_setHeatTransferCoeff", py_wall_setHeatTransferCoeff, METH_VARARGS}, + {"wall_setHeatFlux", py_wall_setHeatFlux, METH_VARARGS}, + {"wall_Q", py_wall_Q, METH_VARARGS}, + {"wall_new", py_wall_new, METH_VARARGS}, + {"wall_vdot", py_wall_vdot, METH_VARARGS}, + {"wall_del", py_wall_del, METH_VARARGS}, + {"wall_setExpansionRate", py_wall_setExpansionRate, METH_VARARGS}, + {"wall_setExpansionRateCoeff", py_wall_setExpansionRateCoeff, METH_VARARGS}, + {"wall_ready", py_wall_ready, METH_VARARGS}, + {NULL, NULL} +}; + +extern "C" { + + /* Initialization function for the module */ + + DL_EXPORT(void) initctreactor(void) + { + PyObject *m, *d; + + /* Initialize the type of the new type object here; doing it here + * is required for portability to Windows without requiring C++. */ + + /* Create the module and add the functions */ + m = Py_InitModule("ctreactor", ct_methods); + import_array(); + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + ErrorObject = PyErr_NewException("cantera.error", NULL, NULL); + PyDict_SetItemString(d, "error", ErrorObject); + } + +} + diff --git a/Cantera/python/src/ctpyrpath.cpp b/Cantera/python/src/ctpyrpath.cpp new file mode 100755 index 000000000..ed525b184 --- /dev/null +++ b/Cantera/python/src/ctpyrpath.cpp @@ -0,0 +1,359 @@ + +/** + * @file ctpyrpath.cpp + * + */ + +// turn off warnings about long names under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + + +#include "Python.h" +#include "Numeric/arrayobject.h" + +#include "ct.h" +#include "ctrpath.h" + +// constants defined in the module +static PyObject *ErrorObject; + +// local includes +#include "pyutils.h" + + +static PyObject* +py_rdiag_new(PyObject *self, PyObject *args) +{ + int iok = rdiag_new(); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_rdiag_del(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:rdiag_del", &n)) + return NULL; + int iok = rdiag_del(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_detailed(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:rdiag_detailed", &n)) + return NULL; + int iok = rdiag_detailed(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_brief(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:rdiag_brief", &n)) + return NULL; + int iok = rdiag_brief(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setThreshold(PyObject *self, PyObject *args) +{ + int n; + double v; + if (!PyArg_ParseTuple(args, "id:rdiag_setThreshold", &n, &v)) + return NULL; + int iok = rdiag_setThreshold(n,v); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setBoldColor(PyObject *self, PyObject *args) +{ + int n; + char* color; + if (!PyArg_ParseTuple(args, "is:rdiag_setBoldColor", &n, &color)) + return NULL; + int iok = rdiag_setBoldColor(n, color); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setNormalColor(PyObject *self, PyObject *args) +{ + int n; + char* color; + if (!PyArg_ParseTuple(args, "is:rdiag_setNormalColor", &n, &color)) + return NULL; + int iok = rdiag_setNormalColor(n, color); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setDashedColor(PyObject *self, PyObject *args) +{ + int n; + char* color; + if (!PyArg_ParseTuple(args, "is:rdiag_setDashedColor", &n, &color)) + return NULL; + int iok = rdiag_setDashedColor(n,color); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setDotOptions(PyObject *self, PyObject *args) +{ + int n; + char* opt; + if (!PyArg_ParseTuple(args, "is:rdiag_setDotOptions", &n, &opt)) + return NULL; + int iok = rdiag_setDotOptions(n,opt); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setBoldThreshold(PyObject *self, PyObject *args) +{ + int n; + double v; + if (!PyArg_ParseTuple(args, "id:rdiag_setBoldThreshold", &n, &v)) + return NULL; + int iok = rdiag_setBoldThreshold(n,v); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setNormalThreshold(PyObject *self, PyObject *args) +{ + int n; + double v; + if (!PyArg_ParseTuple(args, "id:rdiag_setNormalThreshold", &n, &v)) + return NULL; + int iok = rdiag_setNormalThreshold(n,v); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setLabelThreshold(PyObject *self, PyObject *args) +{ + int n; + double v; + if (!PyArg_ParseTuple(args, "id:rdiag_setLabelThreshold", &n, &v)) + return NULL; + int iok = rdiag_setLabelThreshold(n,v); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setScale(PyObject *self, PyObject *args) +{ + int n; + double v; + if (!PyArg_ParseTuple(args, "id:rdiag_setScale", &n, &v)) + return NULL; + int iok = rdiag_setScale(n,v); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setFlowType(PyObject *self, PyObject *args) +{ + int n; + int iflow; + if (!PyArg_ParseTuple(args, "ii:rdiag_setFlowType", &n, &iflow)) + return NULL; + int iok = rdiag_setFlowType(n, iflow); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setArrowWidth(PyObject *self, PyObject *args) +{ + int n; + double v; + if (!PyArg_ParseTuple(args, "id:rdiag_setArrowWidth", &n, &v)) + return NULL; + int iok = rdiag_setArrowWidth(n,v); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + + +static PyObject* +py_rdiag_displayOnly(PyObject *self, PyObject *args) +{ + int n, k; + if (!PyArg_ParseTuple(args, "ii:rdiag_displayOnly", &n, &k)) + return NULL; + int iok = rdiag_displayOnly(n,k); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setTitle(PyObject *self, PyObject *args) +{ + int n; + char* t; + if (!PyArg_ParseTuple(args, "is:rdiag_setTitle", &n, &t)) + return NULL; + int iok = rdiag_setTitle(n,t); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_add(PyObject *self, PyObject *args) +{ + int n, m; + if (!PyArg_ParseTuple(args, "ii:rdiag_add", &n, &m)) + return NULL; + int iok = rdiag_add(n,m); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_findMajor(PyObject *self, PyObject *args) +{ + int n, m; + double thresh; + PyObject* a; + if (!PyArg_ParseTuple(args, "idO:rdiag_findMajor", &n, &thresh, &a)) + return NULL; + PyArrayObject* aa = (PyArrayObject*)a; + int lda = aa->dimensions[0]; + double* x = (double*)aa->data; + int iok = rdiag_findMajor(n, thresh, lda, x); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_write(PyObject *self, PyObject *args) +{ + int n, fmt; + char* nm; + if (!PyArg_ParseTuple(args, "iis:rdiag_write", &n, &fmt, &nm)) + return NULL; + int iok = rdiag_write(n, fmt, nm); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rbuild_new(PyObject *self, PyObject *args) +{ + int iok = rbuild_new(); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_rbuild_del(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:rbuild_del", &n)) + return NULL; + int iok = rbuild_del(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rbuild_init(PyObject *self, PyObject *args) +{ + int n; + char* log; + int k; + if (!PyArg_ParseTuple(args, "isi:rbuild_init", &n, &log, &k)) + return NULL; + int iok = rbuild_init(n,log,k); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rbuild_build(PyObject *self, PyObject *args) +{ + int n; + int k, idiag, iquiet; + char *el, *dotfile; + if (!PyArg_ParseTuple(args, "iissii:rbuild_build", &n, &k, + &el, &dotfile, &idiag, &iquiet)) + return NULL; + int iok = rbuild_build(n,k,el,dotfile,idiag,iquiet); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyMethodDef ct_methods[] = { + {"rdiag_setDashedColor", py_rdiag_setDashedColor, METH_VARARGS}, + {"rbuild_new", py_rbuild_new, METH_VARARGS}, + {"rdiag_write", py_rdiag_write, METH_VARARGS}, + {"rdiag_setDotOptions", py_rdiag_setDotOptions, METH_VARARGS}, + {"rdiag_setScale", py_rdiag_setScale, METH_VARARGS}, + {"rdiag_setTitle", py_rdiag_setTitle, METH_VARARGS}, + {"rdiag_setArrowWidth", py_rdiag_setArrowWidth, METH_VARARGS}, + {"rdiag_displayOnly", py_rdiag_displayOnly, METH_VARARGS}, + {"rdiag_setThreshold", py_rdiag_setThreshold, METH_VARARGS}, + {"rdiag_setBoldThreshold", py_rdiag_setBoldThreshold, METH_VARARGS}, + {"rdiag_new", py_rdiag_new, METH_VARARGS}, + {"rdiag_del", py_rdiag_del, METH_VARARGS}, + {"rdiag_detailed", py_rdiag_detailed, METH_VARARGS}, + {"rdiag_add", py_rdiag_add, METH_VARARGS}, + {"rdiag_findMajor", py_rdiag_findMajor, METH_VARARGS}, + {"rbuild_build", py_rbuild_build, METH_VARARGS}, + {"rdiag_setNormalThreshold", py_rdiag_setNormalThreshold, METH_VARARGS}, + {"rdiag_brief", py_rdiag_brief, METH_VARARGS}, + {"rbuild_del", py_rbuild_del, METH_VARARGS}, + {"rdiag_setNormalColor", py_rdiag_setNormalColor, METH_VARARGS}, + {"rbuild_init", py_rbuild_init, METH_VARARGS}, + {"rdiag_setBoldColor", py_rdiag_setBoldColor, METH_VARARGS}, + {"rdiag_setFlowType", py_rdiag_setFlowType, METH_VARARGS}, + {"rdiag_setLabelThreshold", py_rdiag_setLabelThreshold, METH_VARARGS}, + {NULL, NULL} +}; + +extern "C" { + + /* Initialization function for the module */ + + DL_EXPORT(void) initctrpath(void) + { + PyObject *m, *d; + + /* Initialize the type of the new type object here; doing it here + * is required for portability to Windows without requiring C++. */ + + /* Create the module and add the functions */ + m = Py_InitModule("ctrpath", ct_methods); + import_array(); + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + ErrorObject = PyErr_NewException("cantera.error", NULL, NULL); + PyDict_SetItemString(d, "error", ErrorObject); + } + +} + diff --git a/Cantera/python/src/ctpysurf.cpp b/Cantera/python/src/ctpysurf.cpp new file mode 100755 index 000000000..cc2528dbc --- /dev/null +++ b/Cantera/python/src/ctpysurf.cpp @@ -0,0 +1,404 @@ +/** + * @file ctsurf.cpp + * + */ + +// turn off warnings about long names under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + + +#include "Python.h" +#include "Numeric/arrayobject.h" + +#include "ct.h" +#include "ctsurf.h" +#include +#include +#include + +using namespace std; + +// constants defined in the module +static PyObject *ErrorObject; + +// local includes +#include "pyutils.h" + +static PyObject* +py_surf_setsitedensity(PyObject *self, PyObject *args) +{ + int n; + double s0; + if (!PyArg_ParseTuple(args, "id:surf_setsitedensity", &n, &s0)) + return NULL; + + int iok = surf_setsitedensity(n, s0); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_surf_sitedensity(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:surf_sitedensity", &n)) + return NULL; + + double s0 = surf_sitedensity(n); + return Py_BuildValue("d",s0); +} + + +static PyObject* +py_surf_setcoverages(PyObject *self, PyObject *args) +{ + int n; + PyObject* cov; + if (!PyArg_ParseTuple(args, "iO:surf_setcoverages", &n, &cov)) + return NULL; + double* x = (double*)((PyArrayObject*)cov)->data; + int iok = surf_setcoverages(n, x); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_surf_setconcentrations(PyObject *self, PyObject *args) +{ + int n; + PyObject* c; + if (!PyArg_ParseTuple(args, "iO:surf_setconcentrations", &n, &c)) + return NULL; + double* x = (double*)((PyArrayObject*)c)->data; + int iok = surf_setconcentrations(n, x); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_surf_getcoverages(PyObject *self, PyObject *args) +{ + int n; + PyArrayObject* cov; + if (!PyArg_ParseTuple(args, "i:surf_getcoverages", &n)) + return NULL; + int nsp = th_nSpecies(n); + cov = (PyArrayObject*)PyArray_FromDims(1, &nsp, PyArray_DOUBLE); + double* x = (double*)((PyArrayObject*)cov)->data; + int iok = surf_getcoverages(n, x); + if (iok < 0) return reportError(iok); + return Py_BuildValue("O",cov); +} + +static PyObject* +py_surf_getconcentrations(PyObject *self, PyObject *args) +{ + int n; + PyArrayObject* c; + if (!PyArg_ParseTuple(args, "i:surf_getconcentrations", &n)) + return NULL; + int nsp = th_nSpecies(n); + c = (PyArrayObject*)PyArray_FromDims(1, &nsp, PyArray_DOUBLE); + double* x = (double*)((PyArrayObject*)c)->data; + int iok = surf_getconcentrations(n, x); + if (iok < 0) return reportError(iok); + return Py_BuildValue("O",c); +} + +// static PyObject* +// py_surf_doc(PyObject *self, PyObject *args) +// { +// int n; +// char *k, *v; +// if (!PyArg_ParseTuple(args, "iss:surf_doc", &n, &k, &v)) +// return NULL; +// surf_doc(n, k, v); +// return Py_BuildValue("i",0); +// } + +// static PyObject * +// py_surfkin_new(PyObject *self, PyObject *args) +// { +// int isurf, ib1, ib2; +// if (!PyArg_ParseTuple(args, "iii:surfkin_new", &isurf, &ib1, &ib2)) +// return NULL; +// int nn = surfkin_new(isurf, ib1, ib2); +// if (nn < 0) return reportError(nn); +// return Py_BuildValue("i",nn); +// } + +// static PyObject* +// py_surfkin_delete(PyObject *self, PyObject *args) +// { +// int n; +// if (!PyArg_ParseTuple(args, "i:surfkin_delete", &n)) return NULL; +// surf_del(n); +// return Py_BuildValue("i",0); +// } + + +// static PyObject * +// py_surfkin_addreaction(PyObject *self, PyObject *args) +// { +// int isurf, nr, np, nrate; +// PyObject *pyr, *pyrst, *pyro, *pyp, *pypst, *pyrate; +// if (!PyArg_ParseTuple(args, "iiOOOiOOiO:surfkin_addreaction", +// &isurf, &nr, &pyr, &pyrst, &pyro, &np, &pyp, &pypst, +// &nrate, &pyrate)) +// return NULL; +// int* r = (int*)((PyArrayObject*)pyr)->data; +// int* rst = (int*)((PyArrayObject*)pyrst)->data; +// int* ro = (int*)((PyArrayObject*)pyro)->data; +// int* p = (int*)((PyArrayObject*)pyp)->data; +// int* pst = (int*)((PyArrayObject*)pypst)->data; +// double* rate = (double*)((PyArrayObject*)pyrate)->data; +// int nn = surfkin_addreaction(isurf, nr, r, rst, ro, np, p, pst, +// nrate, rate); +// if (nn < 0) return reportError(nn); +// return Py_BuildValue("i",nn); +// } + +// static PyObject * +// py_surfkin_nreactions(PyObject *self, PyObject *args) +// { +// int isurf; +// if (!PyArg_ParseTuple(args, "i:surfkin_nreactions", &isurf)) +// return NULL; +// int nn = surfkin_nreactions(isurf); +// return Py_BuildValue("i",nn); +// } + +// static PyObject* +// py_surfkin_getratesofprogress(PyObject *self, PyObject *args) +// { +// int n; +// PyArrayObject* rop; +// if (!PyArg_ParseTuple(args, "i:surfkin_getratesofprogress", &n)) +// return NULL; +// int nrxn = surfkin_nreactions(n); +// rop = (PyArrayObject*)PyArray_FromDims(1, &nrxn, PyArray_DOUBLE); +// double* x = (double*)((PyArrayObject*)rop)->data; +// int iok = surfkin_getratesofprogress(n, x); +// if (iok < 0) return reportError(iok); +// return Py_BuildValue("O",rop); +// } + +// static PyObject* +// py_surfkin_getnetproductionrates(PyObject *self, PyObject *args) +// { +// int n, nsp; +// PyArrayObject* sdot; +// if (!PyArg_ParseTuple(args, "ii:surfkin_getnetproductionrates", &n, &nsp)) +// return NULL; +// sdot = (PyArrayObject*)PyArray_FromDims(1, &nsp, PyArray_DOUBLE); +// double* x = (double*)((PyArrayObject*)sdot)->data; +// int iok = surfkin_getnetproductionrates(n, x); +// if (iok < 0) return reportError(iok); +// return Py_BuildValue("O",sdot); +// } + +// static PyObject * +// py_surfkin_integrate(PyObject *self, PyObject *args) +// { +// int isurf; +// double dt; +// if (!PyArg_ParseTuple(args, "id:surfkin_integrate", &isurf, &dt)) +// return NULL; +// int nn = surfkin_integrate(isurf, dt); +// if (nn < 0) return reportError(nn); +// return Py_BuildValue("i",0); +// } + +// static PyObject * +// py_surfkin_save(PyObject *self, PyObject *args) +// { +// int isurf; +// char *fname, *id, *comment; +// if (!PyArg_ParseTuple(args, "isss:surfkin_save", &isurf, &fname, &id, &comment)) +// return NULL; +// int nn = surfkin_save(isurf, fname, id, comment); +// if (nn < 0) return reportError(nn); +// return Py_BuildValue("i",0); +// } + +// static PyObject * +// py_surf1d_new(PyObject *self, PyObject *args) +// { +// int ikin; +// if (!PyArg_ParseTuple(args, "i:surf1d_new", &ikin)) +// return NULL; +// int nn = surface_new(ikin); +// if (nn < 0) return reportError(nn); +// return Py_BuildValue("i",nn); +// } + +// static PyObject* +// py_surf1d_delete(PyObject *self, PyObject *args) +// { +// int n; +// if (!PyArg_ParseTuple(args, "i:surf1d_delete", &n)) return NULL; +// surface_del(n); +// return Py_BuildValue("i",0); +// } + +// static PyObject* +// py_surf1d_settolerances(PyObject *self, PyObject *args) +// { +// int n, nr, na; +// PyObject *prtol, *patol; +// if (!PyArg_ParseTuple(args, "iiOiO:surf1d_settolerances", &n, &nr, &prtol, +// &na, &patol)) +// return NULL; +// double* rtol = (double*)((PyArrayObject*)prtol)->data; +// double* atol = (double*)((PyArrayObject*)patol)->data; +// int iok = surface_settolerances(n, nr, rtol, na, atol); +// if (iok < 0) return reportError(iok); +// return Py_BuildValue("i",iok); +// } + +// static PyObject* +// py_surf1d_settemperature(PyObject *self, PyObject *args) +// { +// int n; +// double t; +// if (!PyArg_ParseTuple(args, "id:surf1d_settemperature", &n, &t)) +// return NULL; +// int iok = surface_settemperature(n, t); +// if (iok < 0) return reportError(iok); +// return Py_BuildValue("i",iok); +// } + +// static PyObject* +// py_surf1d_temperature(PyObject *self, PyObject *args) +// { +// int n; +// if (!PyArg_ParseTuple(args, "i:surf1d_temperature", &n)) +// return NULL; +// return Py_BuildValue("d",surface_temperature(n)); +// } + +// static PyObject* +// py_surf1d_setcoverages(PyObject *self, PyObject *args) +// { +// int n; +// PyObject* cov; +// if (!PyArg_ParseTuple(args, "iO:surf1d_setcoverages", &n, &cov)) +// return NULL; +// double* x = (double*)((PyArrayObject*)cov)->data; +// int iok = surface_setcoverages(n, x); +// if (iok < 0) return reportError(iok); +// return Py_BuildValue("i",0); +// } + +// static PyObject* +// py_surf1d_setmultiplier(PyObject *self, PyObject *args) +// { +// int n, k; +// double f; +// if (!PyArg_ParseTuple(args, "iid:surf1d_setmultiplier", &n, &k, &f)) +// return NULL; +// int iok = surface_setmultiplier(n, k, f); +// if (iok < 0) return reportError(iok); +// return Py_BuildValue("i",iok); +// } + +// static PyObject* +// py_surf1d_multiplier(PyObject *self, PyObject *args) +// { +// int n, k; +// if (!PyArg_ParseTuple(args, "ii:surf1d_multiplier", &n, &k)) +// return NULL; +// return Py_BuildValue("d",surface_multiplier(n, k)); +// } + +// static PyObject* +// py_surf1d_fixspecies(PyObject *self, PyObject *args) +// { +// int n, k; +// double c; +// if (!PyArg_ParseTuple(args, "iid:surf1d_fixspecies", &n, &k, &c)) +// return NULL; +// int iok = surface_fixspecies(n, k, c); +// if (iok < 0) return reportError(iok); +// return Py_BuildValue("i",iok); +// } + +// static PyObject* +// py_surf1d_solvespecies(PyObject *self, PyObject *args) +// { +// int n, slen; +// PyObject* s; +// if (!PyArg_ParseTuple(args, "iiO:surf1d_solvespecies", &n, &slen, &s)) +// return NULL; +// double* x = (double*)((PyArrayObject*)s)->data; +// for (int i = 0; i < slen; i++) { +// if (x[i] <= 0.0) +// surface_fixspecies(n, i); +// else +// surface_solvespecies(n, i); +// } +// return Py_BuildValue("i",0); +// } + + +/* List of functions defined in the module */ + +static PyMethodDef ct_methods[] = { + // {"surf_new", py_surf_new, METH_VARARGS}, + //{"surf_delete", py_surf_delete, METH_VARARGS}, + //{"surf_addspecies", py_surf_addspecies, METH_VARARGS}, + {"surf_setsitedensity", py_surf_setsitedensity, METH_VARARGS}, + {"surf_sitedensity", py_surf_sitedensity, METH_VARARGS}, + //{"surf_nspecies", py_surf_nspecies, METH_VARARGS}, + {"surf_setcoverages", py_surf_setcoverages, METH_VARARGS}, + {"surf_getcoverages", py_surf_getcoverages, METH_VARARGS}, + {"surf_setconcentrations", py_surf_setconcentrations, METH_VARARGS}, + {"surf_getconcentrations", py_surf_getconcentrations, METH_VARARGS}, + //{"surf_doc", py_surf_doc, METH_VARARGS}, +// {"surfkin_new", py_surfkin_new, METH_VARARGS}, +// {"surfkin_delete", py_surfkin_delete, METH_VARARGS}, +// {"surfkin_addreaction", py_surfkin_addreaction, METH_VARARGS}, +// {"surfkin_nreactions", py_surfkin_nreactions, METH_VARARGS}, +// {"surfkin_getratesofprogress", py_surfkin_getratesofprogress, METH_VARARGS}, +// {"surfkin_getsdot", py_surfkin_getnetproductionrates, METH_VARARGS}, +// {"surfkin_integrate", py_surfkin_integrate, METH_VARARGS}, +// {"surfkin_save", py_surfkin_save, METH_VARARGS}, +// {"surf1d_new", py_surf1d_new, METH_VARARGS}, +// {"surf1d_delete", py_surf1d_delete, METH_VARARGS}, +// {"surf1d_settolerances", py_surf1d_settolerances, METH_VARARGS}, +// {"surf1d_settemperature", py_surf1d_settemperature, METH_VARARGS}, +// {"surf1d_temperature", py_surf1d_temperature, METH_VARARGS}, +// {"surf1d_setcoverages", py_surf1d_setcoverages, METH_VARARGS}, +// {"surf1d_setmultiplier", py_surf1d_setmultiplier, METH_VARARGS}, +// {"surf1d_multiplier", py_surf1d_multiplier, METH_VARARGS}, +// {"surf1d_fixspecies", py_surf1d_fixspecies, METH_VARARGS}, +// {"surf1d_solvespecies", py_surf1d_solvespecies, METH_VARARGS}, + {NULL, NULL} /* sentinel */ +}; + + +extern "C" { + + /* Initialization function for the module (*must* be called initctsurf) */ + + DL_EXPORT(void) initctsurf(void) + { + PyObject *m, *d; + + /* Initialize the type of the new type object here; doing it here + * is required for portability to Windows without requiring C++. */ + + /* Create the module and add the functions */ + m = Py_InitModule("ctsurf", ct_methods); + import_array(); + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + ErrorObject = PyErr_NewException("cantera.error", NULL, NULL); + PyDict_SetItemString(d, "error", ErrorObject); + } + +} diff --git a/Cantera/python/src/ctpyxml.cpp b/Cantera/python/src/ctpyxml.cpp new file mode 100644 index 000000000..37c0e846a --- /dev/null +++ b/Cantera/python/src/ctpyxml.cpp @@ -0,0 +1,283 @@ + +/** + * @file ctpyxml.cpp + * + */ + +// turn off warnings about long names under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + + +#include "Python.h" +#include "Numeric/arrayobject.h" + +#include "ct.h" +#include "ctxml.h" +#include +using namespace std; + +// constants defined in the module +static PyObject *ErrorObject; + +// local includes +#include "pyutils.h" + + +static PyObject* +py_xml_new(PyObject *self, PyObject *args) +{ + char* nm; + if (!PyArg_ParseTuple(args, "s:xml_new", &nm)) + return NULL; + int n = xml_new(nm); + return Py_BuildValue("i",n); +} + +static PyObject* +py_xml_del(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:xml_del", &n)) + return NULL; + int iok = xml_del(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_xml_build(PyObject *self, PyObject *args) +{ + int n; + char* file; + if (!PyArg_ParseTuple(args, "is:xml_build", &n, &file)) + return NULL; + int iok = xml_build(n, file); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_xml_attrib(PyObject *self, PyObject *args) +{ + int n; + char *key; + if (!PyArg_ParseTuple(args, "is:xml_attrib", &n, &key)) + return NULL; + char* val = new char[81]; + int iok = xml_attrib(n, key, val); + if (iok < 0) return reportError(iok); + PyObject* r = Py_BuildValue("s",val); + delete val; + return r; +} + +static PyObject* +py_xml_tag(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:xml_tag", &n)) + return NULL; + char* val = new char[81]; + int iok = xml_tag(n, val); + if (iok < 0) return reportError(iok); + PyObject* r = Py_BuildValue("s",val); + delete val; + return r; +} + +static PyObject* +py_xml_value(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:xml_value", &n)) + return NULL; + char* val = new char[81]; + int iok = xml_value(n, val); + if (iok < 0) return reportError(iok); + PyObject* r = Py_BuildValue("s",val); + delete val; + return r; +} + +static PyObject* +py_xml_child(PyObject *self, PyObject *args) +{ + int n; + char* loc; + if (!PyArg_ParseTuple(args, "is:xml_child", &n, &loc)) + return NULL; + int m = xml_child(n, loc); + if (m < 0) return reportError(m); + return Py_BuildValue("i",m); +} + +static PyObject* +py_xml_childbynumber(PyObject *self, PyObject *args) +{ + int n, k; + if (!PyArg_ParseTuple(args, "ii:xml_childbynumber", &n, &k)) + return NULL; + int m = xml_child_bynumber(n, k); + if (m < 0) return reportError(m); + return Py_BuildValue("i",m); +} + +static PyObject* +py_xml_findID(PyObject *self, PyObject *args) +{ + int n; + char* id; + if (!PyArg_ParseTuple(args, "is:xml_findID", &n, &id)) + return NULL; + int m = xml_findID(n, id); + if (m < 0) return reportError(m); + return Py_BuildValue("i",m); +} + +static PyObject* +py_xml_findByName(PyObject *self, PyObject *args) +{ + int n; + char* nm; + if (!PyArg_ParseTuple(args, "is:xml_findID", &n, &nm)) + return NULL; + int m = xml_findByName(n, nm); + if (m < 0) return reportError(m); + return Py_BuildValue("i",m); +} + +static PyObject* +py_xml_nChildren(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:xml_nChildren", &n)) + return NULL; + int m = xml_nChildren(n); + if (m < 0) return reportError(m); + return Py_BuildValue("i",m); +} + +static PyObject* +py_xml_addChild(PyObject *self, PyObject *args) +{ + int n; + char *name, *value; + if (!PyArg_ParseTuple(args, "iss:xml_addChild", &n, &name, &value)) + return NULL; + int m = xml_addChild(n, name, value); + if (m < 0) return reportError(m); + return Py_BuildValue("i",m); +} + + +static PyObject* +py_xml_addChildNode(PyObject *self, PyObject *args) +{ + int n, j; + if (!PyArg_ParseTuple(args, "ii:xml_addChildNode", &n, &j)) + return NULL; + int m = xml_addChildNode(n, j); + if (m < 0) return reportError(m); + return Py_BuildValue("i",m); +} + + +static PyObject* +py_xml_addAttrib(PyObject *self, PyObject *args) +{ + int n; + char *name, *value; + if (!PyArg_ParseTuple(args, "iss:xml_addAttrib", &n, &name, &value)) + return NULL; + int m = xml_addAttrib(n, name, value); + if (m < 0) return reportError(m); + return Py_BuildValue("i",m); +} + +static PyObject* +py_xml_removeChild(PyObject *self, PyObject *args) +{ + int n, m; + if (!PyArg_ParseTuple(args, "ii:xml_removeChild", &n, &m)) + return NULL; + int iok = xml_removeChild(n, m); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + + +static PyObject* +py_xml_write(PyObject *self, PyObject *args) +{ + int n; + char *file; + if (!PyArg_ParseTuple(args, "is:xml_write", &n, &file)) + return NULL; + int iok = xml_write(n, file); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_ctml_getFloatArray(PyObject *self, PyObject *args) +{ + int n; + int iconv, ia; + if (!PyArg_ParseTuple(args, "iii", &n, &iconv, &ia)) + return NULL; + + PyArrayObject* a = + (PyArrayObject*)PyArray_FromDims(1, &ia, PyArray_DOUBLE); + double* x = (double*)a->data; + int iok = ctml_getFloatArray(n, ia, x, iconv); + if (iok < 0) return reportError(iok); + return PyArray_Return(a); +} + +static PyMethodDef ct_methods[] = { + {"xml_attrib", py_xml_attrib, METH_VARARGS}, + {"xml_addAttrib", py_xml_addAttrib, METH_VARARGS}, + {"xml_tag", py_xml_tag, METH_VARARGS}, + {"xml_value", py_xml_value, METH_VARARGS}, + {"xml_new", py_xml_new, METH_VARARGS}, + {"xml_del", py_xml_del, METH_VARARGS}, + {"xml_build", py_xml_build, METH_VARARGS}, + {"xml_child", py_xml_child, METH_VARARGS}, + {"xml_childbynumber", py_xml_childbynumber, METH_VARARGS}, + {"xml_findID", py_xml_findID, METH_VARARGS}, + {"xml_findByName", py_xml_findByName, METH_VARARGS}, + {"xml_nChildren", py_xml_nChildren, METH_VARARGS}, + {"xml_addChild", py_xml_addChild, METH_VARARGS}, + {"xml_addChildNode", py_xml_addChildNode, METH_VARARGS}, + {"xml_removeChild", py_xml_removeChild, METH_VARARGS}, + {"xml_write", py_xml_write, METH_VARARGS}, + {"ctml_getFloatArray", py_ctml_getFloatArray, METH_VARARGS}, + {NULL, NULL} +}; + +extern "C" { + + /* Initialization function for the module */ + + DL_EXPORT(void) initctxml(void) + { + PyObject *m, *d; + + /* Initialize the type of the new type object here; doing it here + * is required for portability to Windows without requiring C++. */ + + /* Create the module and add the functions */ + m = Py_InitModule("ctxml", ct_methods); + import_array(); + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + ErrorObject = PyErr_NewException("cantera.error", NULL, NULL); + PyDict_SetItemString(d, "error", ErrorObject); + } + +} + diff --git a/Cantera/python/src/ctreactor_methods.cpp b/Cantera/python/src/ctreactor_methods.cpp new file mode 100644 index 000000000..2de470a09 --- /dev/null +++ b/Cantera/python/src/ctreactor_methods.cpp @@ -0,0 +1,438 @@ + +static PyObject* +py_reactor_new(PyObject *self, PyObject *args) +{ + int type; + if (!PyArg_ParseTuple(args, "i:reactor_new", &type)) + return NULL; + int n = reactor_new(type); + return Py_BuildValue("i",n); +} + +static PyObject* +py_reactor_del(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:reactor_del", &n)) + return NULL; + int iok = reactor_del(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_reactor_setInitialVolume(PyObject *self, PyObject *args) +{ + int n; + double v; + if (!PyArg_ParseTuple(args, "id:reactor_setInitialVolume", &n, &v)) + return NULL; + int iok = reactor_setInitialVolume(n,v); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_reactor_setInitialTime(PyObject *self, PyObject *args) +{ + int n; + double t; + if (!PyArg_ParseTuple(args, "id:reactor_setInitialTime", &n, &t)) + return NULL; + int iok = reactor_setInitialTime(n, t); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_reactor_setEnergy(PyObject *self, PyObject *args) +{ + int n, eflag; + if (!PyArg_ParseTuple(args, "ii:reactor_setEnergy", &n, &eflag)) + return NULL; + int iok = reactor_setEnergy(n, eflag); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_reactor_setThermoMgr(PyObject *self, PyObject *args) +{ + int n; + int th; + if (!PyArg_ParseTuple(args, "ii:reactor_setThermoMgr", &n, &th)) + return NULL; + int iok = reactor_setThermoMgr(n, th); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_reactor_setKineticsMgr(PyObject *self, PyObject *args) +{ + int n; + int kin; + if (!PyArg_ParseTuple(args, "ii:reactor_setKineticsMgr", &n, &kin)) + return NULL; + int iok = reactor_setKineticsMgr(n, kin); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_reactor_advance(PyObject *self, PyObject *args) +{ + int n; + double t; + if (!PyArg_ParseTuple(args, "id:reactor_advance", &n, &t)) + return NULL; + int iok = reactor_advance(n, t); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_reactor_step(PyObject *self, PyObject *args) +{ + int n; + double t; + if (!PyArg_ParseTuple(args, "id:reactor_step", &n, &t)) + return NULL; + return Py_BuildValue("d",reactor_step(n, t)); +} + +static PyObject* +py_reactor_time(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:reactor_time", &n)) + return NULL; + double t = reactor_time(n); + return Py_BuildValue("d",t); +} + +static PyObject* +py_reactor_mass(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:reactor_mass", &n)) + return NULL; + double m = reactor_mass(n); + return Py_BuildValue("d",m); +} + +static PyObject* +py_reactor_volume(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:reactor_volume", &n)) + return NULL; + double v = reactor_volume(n); + return Py_BuildValue("d",v); +} + +static PyObject* +py_reactor_density(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:reactor_density", &n)) + return NULL; + double rho = reactor_density(n); + return Py_BuildValue("d",rho); +} + +static PyObject* +py_reactor_temperature(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:reactor_temperature", &n)) + return NULL; + double t = reactor_temperature(n); + return Py_BuildValue("d",t); +} + +static PyObject* +py_reactor_enthalpy_mass(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:reactor_enthalpy_mass", &n)) + return NULL; + double h = reactor_enthalpy_mass(n); + return Py_BuildValue("d",h); +} + +static PyObject* +py_reactor_intEnergy_mass(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:reactor_intEnergy_mass", &n)) + return NULL; + double u = reactor_intEnergy_mass(n); + return Py_BuildValue("d",u); +} + +static PyObject* +py_reactor_pressure(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:reactor_pressure", &n)) + return NULL; + double p = reactor_pressure(n); + return Py_BuildValue("d",p); +} + +static PyObject* +py_reactor_massFraction(PyObject *self, PyObject *args) +{ + int n; + int k; + if (!PyArg_ParseTuple(args, "ii:reactor_massFraction", &n, &k)) + return NULL; + double y = reactor_massFraction(n, k); + return Py_BuildValue("d",y); +} + +static PyObject* +py_flowdev_new(PyObject *self, PyObject *args) +{ + int type; + if (!PyArg_ParseTuple(args, "i:flowdev_new", &type)) + return NULL; + int n = flowdev_new(type); + return Py_BuildValue("i",n); +} + +static PyObject* +py_flowdev_del(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:flowdev_del", &n)) + return NULL; + int iok = flowdev_del(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_flowdev_install(PyObject *self, PyObject *args) +{ + int n, r1, r2; + if (!PyArg_ParseTuple(args, "iii:flowdev_install", &n, &r1, &r2)) + return NULL; + int iok = flowdev_install(n, r1, r2); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_flowdev_massFlowRate(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:flowdev_massFlowRate", &n)) + return NULL; + double mdot = flowdev_massFlowRate(n); + return Py_BuildValue("d",mdot); +} + +static PyObject* +py_flowdev_setpoint(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:flowdev_setpoint", &n)) + return NULL; + double v = flowdev_setpoint(n); + return Py_BuildValue("d",v); +} + +static PyObject* +py_flowdev_setSetpoint(PyObject *self, PyObject *args) +{ + int n; + double v; + if (!PyArg_ParseTuple(args, "id:flowdev_setSetpoint", &n, &v)) + return NULL; + int iok = flowdev_setSetpoint(n, v); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_flowdev_setParameters(PyObject *self, PyObject *args) +{ + int n, sz; + PyObject* c; + if (!PyArg_ParseTuple(args, "iiO:flowdev_setParameters", &n, &sz, &c)) + return NULL; + double* x = (double*)((PyArrayObject*)c)->data; + int iok = flowdev_setParameters(n, sz, x); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_flowdev_setFunction(PyObject *self, PyObject *args) +{ + int n, m; + if (!PyArg_ParseTuple(args, "ii:flowdev_setFunction", &n, &m)) + return NULL; + int iok = flowdev_setFunction(n, m); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_flowdev_ready(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:flowdev_ready", &n)) + return NULL; + int iok = flowdev_ready(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + + +static PyObject* +py_wall_new(PyObject *self, PyObject *args) +{ + int type; + if (!PyArg_ParseTuple(args, "i:wall_new", &type)) + return NULL; + int n = wall_new(type); + return Py_BuildValue("i",n); +} + +static PyObject* +py_wall_del(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:wall_del", &n)) + return NULL; + int iok = wall_del(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_wall_install(PyObject *self, PyObject *args) +{ + int n, r1, r2; + if (!PyArg_ParseTuple(args, "iii:wall_install", &n, &r1, &r2)) + return NULL; + int iok = wall_install(n, r1, r2); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_wall_vdot(PyObject *self, PyObject *args) +{ + int n; + double t; + if (!PyArg_ParseTuple(args, "id:wall_vdot", &n, &t)) + return NULL; + double vdt = wall_vdot(n,t); + return Py_BuildValue("d",vdt); +} + +static PyObject* +py_wall_Q(PyObject *self, PyObject *args) +{ + int n; + double t; + if (!PyArg_ParseTuple(args, "id:wall_Q", &n, &t)) + return NULL; + return Py_BuildValue("d",wall_Q(n, t)); +} + +static PyObject* +py_wall_area(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:wall_area", &n)) + return NULL; + return Py_BuildValue("d",wall_area(n)); +} + +static PyObject* +py_wall_setArea(PyObject *self, PyObject *args) +{ + int n; + double area; + if (!PyArg_ParseTuple(args, "id:wall_setArea", &n, &area)) + return NULL; + int iok = wall_setArea(n, area); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_wall_setThermalResistance(PyObject *self, PyObject *args) +{ + int n; + double rth; + if (!PyArg_ParseTuple(args, "id:wall_setThermalResistance", &n, &rth)) + return NULL; + int iok = wall_setThermalResistance(n,rth); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_wall_setHeatTransferCoeff(PyObject *self, PyObject *args) +{ + int n; + double u; + if (!PyArg_ParseTuple(args, "id:wall_setHeatTransferCoeff", &n, &u)) + return NULL; + int iok = wall_setHeatTransferCoeff(n,u); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_wall_setExpansionRateCoeff(PyObject *self, PyObject *args) +{ + int n; + double k; + if (!PyArg_ParseTuple(args, "id:wall_setExpansionRateCoeff", &n, &k)) + return NULL; + int iok = wall_setExpansionRateCoeff(n,k); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_wall_setExpansionRate(PyObject *self, PyObject *args) +{ + int n, m; + if (!PyArg_ParseTuple(args, "ii:wall_setExpansionRate", &n, &m)) + return NULL; + int iok = wall_setExpansionRate(n,m); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_wall_setHeatFlux(PyObject *self, PyObject *args) +{ + int n, m; + if (!PyArg_ParseTuple(args, "ii:wall_setHeatFlux", &n, &m)) + return NULL; + int iok = wall_setHeatFlux(n,m); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_wall_ready(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:wall_ready", &n)) + return NULL; + int iok = wall_ready(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + + diff --git a/Cantera/python/src/ctrpath_methods.cpp b/Cantera/python/src/ctrpath_methods.cpp new file mode 100644 index 000000000..86099af92 --- /dev/null +++ b/Cantera/python/src/ctrpath_methods.cpp @@ -0,0 +1,284 @@ + +static PyObject* +py_rdiag_new(PyObject *self, PyObject *args) +{ + int iok = rdiag_new(); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_rdiag_del(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:rdiag_del", &n)) + return NULL; + int iok = rdiag_del(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_detailed(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:rdiag_detailed", &n)) + return NULL; + int iok = rdiag_detailed(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_brief(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:rdiag_brief", &n)) + return NULL; + int iok = rdiag_brief(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setThreshold(PyObject *self, PyObject *args) +{ + int n; + double v; + if (!PyArg_ParseTuple(args, "id:rdiag_setThreshold", &n, &v)) + return NULL; + int iok = rdiag_setThreshold(n,v); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setBoldColor(PyObject *self, PyObject *args) +{ + int n; + char* color; + if (!PyArg_ParseTuple(args, "is:rdiag_setBoldColor", &n, &color)) + return NULL; + int iok = rdiag_setBoldColor(n, color); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setNormalColor(PyObject *self, PyObject *args) +{ + int n; + char* color; + if (!PyArg_ParseTuple(args, "is:rdiag_setNormalColor", &n, &color)) + return NULL; + int iok = rdiag_setNormalColor(n, color); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setDashedColor(PyObject *self, PyObject *args) +{ + int n; + char* color; + if (!PyArg_ParseTuple(args, "is:rdiag_setDashedColor", &n, &color)) + return NULL; + int iok = rdiag_setDashedColor(n,color); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setDotOptions(PyObject *self, PyObject *args) +{ + int n; + char* opt; + if (!PyArg_ParseTuple(args, "is:rdiag_setDotOptions", &n, &opt)) + return NULL; + int iok = rdiag_setDotOptions(n,opt); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setBoldThreshold(PyObject *self, PyObject *args) +{ + int n; + double v; + if (!PyArg_ParseTuple(args, "id:rdiag_setBoldThreshold", &n, &v)) + return NULL; + int iok = rdiag_setBoldThreshold(n,v); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setNormalThreshold(PyObject *self, PyObject *args) +{ + int n; + double v; + if (!PyArg_ParseTuple(args, "id:rdiag_setNormalThreshold", &n, &v)) + return NULL; + int iok = rdiag_setNormalThreshold(n,v); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setLabelThreshold(PyObject *self, PyObject *args) +{ + int n; + double v; + if (!PyArg_ParseTuple(args, "id:rdiag_setLabelThreshold", &n, &v)) + return NULL; + int iok = rdiag_setLabelThreshold(n,v); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setScale(PyObject *self, PyObject *args) +{ + int n; + double v; + if (!PyArg_ParseTuple(args, "id:rdiag_setScale", &n, &v)) + return NULL; + int iok = rdiag_setScale(n,v); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setFlowType(PyObject *self, PyObject *args) +{ + int n; + int iflow; + if (!PyArg_ParseTuple(args, "ii:rdiag_setFlowType", &n, &iflow)) + return NULL; + int iok = rdiag_setFlowType(n, iflow); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setArrowWidth(PyObject *self, PyObject *args) +{ + int n; + double v; + if (!PyArg_ParseTuple(args, "id:rdiag_setArrowWidth", &n, &v)) + return NULL; + int iok = rdiag_setArrowWidth(n,v); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + + +static PyObject* +py_rdiag_displayOnly(PyObject *self, PyObject *args) +{ + int n, k; + if (!PyArg_ParseTuple(args, "ii:rdiag_displayOnly", &n, &k)) + return NULL; + int iok = rdiag_displayOnly(n,k); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_setTitle(PyObject *self, PyObject *args) +{ + int n; + char* t; + if (!PyArg_ParseTuple(args, "is:rdiag_setTitle", &n, &t)) + return NULL; + int iok = rdiag_setTitle(n,t); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_add(PyObject *self, PyObject *args) +{ + int n, m; + if (!PyArg_ParseTuple(args, "ii:rdiag_add", &n, &m)) + return NULL; + int iok = rdiag_add(n,m); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_findMajor(PyObject *self, PyObject *args) +{ + int n; + double thresh; + PyObject* a; + if (!PyArg_ParseTuple(args, "idO:rdiag_findMajor", &n, &thresh, &a)) + return NULL; + PyArrayObject* aa = (PyArrayObject*)a; + int lda = aa->dimensions[0]; + double* x = (double*)aa->data; + int iok = rdiag_findMajor(n, thresh, lda, x); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rdiag_write(PyObject *self, PyObject *args) +{ + int n, fmt; + char* nm; + if (!PyArg_ParseTuple(args, "iis:rdiag_write", &n, &fmt, &nm)) + return NULL; + int iok = rdiag_write(n, fmt, nm); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rbuild_new(PyObject *self, PyObject *args) +{ + int iok = rbuild_new(); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_rbuild_del(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:rbuild_del", &n)) + return NULL; + int iok = rbuild_del(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rbuild_init(PyObject *self, PyObject *args) +{ + int n; + char* log; + int k; + if (!PyArg_ParseTuple(args, "isi:rbuild_init", &n, &log, &k)) + return NULL; + int iok = rbuild_init(n,log,k); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_rbuild_build(PyObject *self, PyObject *args) +{ + int n; + int k, idiag, iquiet; + char *el, *dotfile; + if (!PyArg_ParseTuple(args, "iissii:rbuild_build", &n, &k, + &el, &dotfile, &idiag, &iquiet)) + return NULL; + int iok = rbuild_build(n,k,el,dotfile,idiag,iquiet); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + + diff --git a/Cantera/python/src/ctsurf.cpp b/Cantera/python/src/ctsurf.cpp new file mode 100755 index 000000000..46f2ff7a0 --- /dev/null +++ b/Cantera/python/src/ctsurf.cpp @@ -0,0 +1,575 @@ +/** + * @file ctkinetics.cpp + * + */ + +// turn off warnings about long names under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + + +#include "Python.h" +#include "Numeric/arrayobject.h" + +#include "ct.h" +#include "ctstagn.h" +#include +#include +#include + +using namespace std; + +// constants defined in the module +static PyObject *ErrorObject; + +// local includes +#include "pyutils.h" + +static PyObject * +py_flow_new(PyObject *self, PyObject *args) +{ + int itype, iph, np; + if (!PyArg_ParseTuple(args, "iii:flow_new", + &itype, &iph, &np)) + return NULL; + int nn = flow_new(itype,iph,np); + if (nn < 0) return reportError(nn); + return Py_BuildValue("i",nn); +} + +static PyObject* +py_flow_delete(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:flow_delete", &n)) return NULL; + flow_del(n); + return Py_BuildValue("i",0); +} + +// static PyObject* +// py_flow_newcopy(PyObject *self, PyObject *args) +// { +// int n; +// if (!PyArg_ParseTuple(args, "i:flow_newcopy", &n)) return NULL; +// return Py_BuildValue("i",flow_copy(n)); +// } + +// static PyObject* +// py_flow_assign(PyObject *self, PyObject *args) +// { +// int n, m; +// if (!PyArg_ParseTuple(args, "ii:flow_assign", &n, &m)) return NULL; +// return Py_BuildValue("i",flow_assign(n, m)); +// } + +// static PyObject* +// py_flow_readinputs(PyObject *self, PyObject *args) +// { +// int n; +// char* infile; +// if (!PyArg_ParseTuple(args, "is:flow_readinputs", &n, &infile)) +// return NULL; +// return Py_BuildValue("i",flow_readinputs(n,infile)); +// } + +static PyObject* +py_flow_setupgrid(PyObject *self, PyObject *args) +{ + int n; + PyObject* grid; + if (!PyArg_ParseTuple(args, "iO:flow_setupgrid", &n, &grid)) + return NULL; + + vector z; + int iok = pyNumericSequence_ToVector(grid, z); + if (iok == -1) { + PyErr_SetString(ErrorObject, "Third argument must be a sequence"); + return NULL; + } + if (iok == -2) { + PyErr_SetString(ErrorObject, + "Sequence must contain only numeric values"); + return NULL; + } + iok = flow_setupgrid(n, z.size(), z.begin()); + if (iok == -1) return reportCanteraError(); + else if (iok < 0) return NULL; + return Py_BuildValue("i",0); +} + +static PyObject* +py_flow_setkinetics(PyObject *self, PyObject *args) +{ + int nn,k; + if (!PyArg_ParseTuple(args, "ii:flow_setkinetics", &nn, &k)) return NULL; + return Py_BuildValue("i",flow_setkinetics(nn,k)); +} + +static PyObject* +py_flow_settransport(PyObject *self, PyObject *args) +{ + int nn,k,soret; + if (!PyArg_ParseTuple(args, "iii:flow_settransport", + &nn, &k, &soret)) return NULL; + return Py_BuildValue("i",flow_settransport(nn,k,soret)); +} + +static PyObject* +py_flow_setthermo(PyObject *self, PyObject *args) +{ + int nn,k; + if (!PyArg_ParseTuple(args, "ii:flow_setthermo", &nn, &k)) return NULL; + return Py_BuildValue("i",flow_setthermo(nn,k)); +} + +static PyObject* +py_flow_setpressure(PyObject *self, PyObject *args) +{ + int nn; + double p; + if (!PyArg_ParseTuple(args, "id:flow_setpressure", &nn, &p)) + return NULL; + return Py_BuildValue("i",flow_setpressure(nn,p)); +} + +static PyObject* +py_flow_setinletstate(PyObject *self, PyObject *args) +{ + int nn,gas; + if (!PyArg_ParseTuple(args, "ii:flow_setinletstate", &nn, &gas)) + return NULL; + return Py_BuildValue("i",flow_setinletstate(nn,gas)); +} + +static PyObject* +py_flow_setinlet_u(PyObject *self, PyObject *args) +{ + int nn; + double u; + if (!PyArg_ParseTuple(args, "id:flow_setinlet_u", &nn, &u)) + return NULL; + return Py_BuildValue("i",flow_setinlet_u(nn,u)); +} + +static PyObject* +py_flow_setinlet_v(PyObject *self, PyObject *args) +{ + int nn; + double v; + if (!PyArg_ParseTuple(args, "id:flow_setinlet_v", &nn, &v)) + return NULL; + return Py_BuildValue("i",flow_setinlet_v(nn,v)); +} + +static PyObject* +py_flow_setsurface_t(PyObject *self, PyObject *args) +{ + int nn; + double t; + if (!PyArg_ParseTuple(args, "id:flow_setsurface_t", &nn, &t)) + return NULL; + return Py_BuildValue("i",flow_setsurface_t(nn,t)); +} + +static PyObject* +py_flow_settemperature(PyObject *self, PyObject *args) +{ + int n, j; + double t; + if (!PyArg_ParseTuple(args, "iid:flow_settemperature", &n, &j, &t)) + return NULL; + return Py_BuildValue("i",flow_settemperature(n,j,t)); +} + +static PyObject* +py_flow_setmassfraction(PyObject *self, PyObject *args) +{ + int n, j, k; + double y; + if (!PyArg_ParseTuple(args, "iiid:flow_setinlet_v", &n, &j, &k, &y)) + return NULL; + return Py_BuildValue("i",flow_setmassfraction(n,j,k,y)); +} + +static PyObject* +py_flow_showsolution(PyObject *self, PyObject *args) +{ + int n; + char* fname; + PyObject* soln; + if (!PyArg_ParseTuple(args, "isO:flow_showsolution", &n, &fname, &soln)) + return NULL; + double* x = (double*)((PyArrayObject*)soln)->data; + return Py_BuildValue("i",flow_showsolution(n,fname,x)); +} + +static PyObject* +py_flow_solvespecies(PyObject *self, PyObject *args) +{ + int n, j, slen; + PyObject* s; + if (!PyArg_ParseTuple(args, "iiO:flow_solvespecies", &n, &slen, &s)) + return NULL; + double* x = (double*)((PyArrayObject*)s)->data; + for (int i = 0; i < slen; i++) { + if (x[i] <= 0.0) + flow_fixspecies(n, i); + else + flow_solvespecies(n, i); + } + return Py_BuildValue("i",0); +} + + +static PyObject* +py_flow_solve(PyObject *self, PyObject *args) +{ + int n, loglevel; + PyObject *s, *snew; + if (!PyArg_ParseTuple(args, "iOOi:flow_solve", &n, &s, &snew, &loglevel)) + return NULL; + double* x = (double*)((PyArrayObject*)s)->data; + double* xnew = (double*)((PyArrayObject*)snew)->data; + int iok = flow_solve(n,x,xnew,loglevel); + if (iok == -1) return reportCanteraError(); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_flow_ssnorm(PyObject *self, PyObject *args) +{ + int n, loglevel; + PyObject *ps, *pr; + if (!PyArg_ParseTuple(args, "iOO:flow_solve", &n, &ps, &pr)) + return NULL; + double* x = (double*)((PyArrayObject*)ps)->data; + double* r = (double*)((PyArrayObject*)pr)->data; + double ss = flow_ssnorm(n,x,r); + return Py_BuildValue("d",ss); +} + + +static PyObject* +py_flow_timeinteg(PyObject *self, PyObject *args) +{ + int n, nsteps, loglevel; + double dt; + PyObject *s, *snew; + if (!PyArg_ParseTuple(args, "iidOOi:flow_solve", &n, &nsteps, &dt, + &s, &snew, &loglevel)) + return NULL; + double* x = (double*)((PyArrayObject*)s)->data; + double* xnew = (double*)((PyArrayObject*)snew)->data; + int iok = flow_timeinteg(n,nsteps,dt,x,xnew,loglevel); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + + +static PyObject* +py_copy(PyObject *self, PyObject *args) +{ + int n; + PyObject *s, *snew; + if (!PyArg_ParseTuple(args, "iOO:copy", &n, &s, &snew)) + return NULL; + double* x = (double*)((PyArrayObject*)s)->data; + double* xnew = (double*)((PyArrayObject*)snew)->data; + for (int i = 0; i < n; i++) xnew[i] = x[i]; + return Py_BuildValue("i",0); +} + + +static PyObject* +py_flow_settolerances(PyObject *self, PyObject *args) +{ + int n, nr, na; + PyObject *prtol, *patol; + if (!PyArg_ParseTuple(args, "iiOiO:flow_solve", &n, &nr, &prtol, + &na, &patol)) + return NULL; + double* rtol = (double*)((PyArrayObject*)prtol)->data; + double* atol = (double*)((PyArrayObject*)patol)->data; + int iok = flow_settolerances(n, nr, rtol, na, atol); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + + +static PyObject* +py_flow_eval(PyObject *self, PyObject *args) +{ + int n, j; + PyObject *px, *pr; + if (!PyArg_ParseTuple(args, "iiOO:flow_solve", &n, &j, &px, &pr)) + return NULL; + double* x = (double*)((PyArrayObject*)px)->data; + double* r = (double*)((PyArrayObject*)pr)->data; + int iok = flow_eval(n, j, x, r); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + + +static PyObject* +py_flow_integratechem(PyObject *self, PyObject *args) +{ + int n, j; + PyObject *px; + double dt; + if (!PyArg_ParseTuple(args, "iOd:flow_solve", &n, &px, &dt)) + return NULL; + double* x = (double*)((PyArrayObject*)px)->data; + int iok = flow_integratechem(n, x, dt); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_flow_outputtec(PyObject *self, PyObject *args) +{ + int n; + PyObject *px; + char *fname, *title; + int zone; + if (!PyArg_ParseTuple(args, "iOssi:flow_outputtec", &n, &px, + &fname, &title, &zone)) + return NULL; + double* x = (double*)((PyArrayObject*)px)->data; + int iok = flow_outputtec(n, x, fname, title, zone); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_flow_resize(PyObject *self, PyObject *args) +{ + int n, points; + PyObject *px; + if (!PyArg_ParseTuple(args, "ii:flow_resize", &n, &points)) + return NULL; + int iok = flow_resize(n, points); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_flow_energy(PyObject *self, PyObject *args) +{ + int n, j, flag, iok; + if (!PyArg_ParseTuple(args, "iii:flow_energy", &n, &j, &flag)) + return NULL; + if (flag == 1) + iok = flow_solveenergyeqn(n, j); + else + iok = flow_fixtemperature(n, j); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_flow_setnewtonoptions(PyObject *self, PyObject *args) +{ + int n, age; + double ratio; + if (!PyArg_ParseTuple(args, "iid:flow_setnewtonoptions", &n, &age, &ratio)) + return NULL; + int iok = flow_setnewtonoptions(n, age, ratio); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_flow_setsteadymode(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:flow_setsteadymode", &n)) + return NULL; + int iok = flow_setsteadymode(n); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_flow_settransientmode(PyObject *self, PyObject *args) +{ + int n; + double dt; + PyArrayObject* px; + if (!PyArg_ParseTuple(args, "idO:flow_settransientmode", &n, &dt, &px)) + return NULL; + double* x = (double*)((PyArrayObject*)px)->data; + int iok = flow_settransientmode(n, dt, x); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_flow_setfixedpoint(PyObject *self, PyObject *args) +{ + int n, j0; + double t0; + if (!PyArg_ParseTuple(args, "iid:flow_setfixedpoint", &n, &j0, &t0)) + return NULL; + int iok = flow_setfixedpoint(n, j0, t0); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_flow_save(PyObject *self, PyObject *args) +{ + int n; + char *fname, *id; + PyArrayObject* px; + if (!PyArg_ParseTuple(args, "issO:flow_solve", &n, &fname, &id, &px)) + return NULL; + double* x = (double*)((PyArrayObject*)px)->data; + int iok = flow_save(n, fname, id, x); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_flow_restore(PyObject *self, PyObject *args) +{ + int n, job, iz, isoln; + char *fname, *id; + PyArrayObject *pz, *psoln; + if (!PyArg_ParseTuple(args, "iiss:flow_solve", + &n, &job, &fname, &id)) + return NULL; + int iok; + double *z=0, *soln=0; + + iok = flow_restore(n, -1, fname, id, iz, z, isoln, soln); + if (job < 0) { + return Py_BuildValue("(ii)",iz,isoln); + } + pz = (PyArrayObject*)PyArray_FromDims(1, &iz, PyArray_DOUBLE); + vector sdim(2); + sdim[0] = iz; + sdim[1] = isoln/iz; + psoln = (PyArrayObject*)PyArray_FromDims(2, sdim.begin(), PyArray_DOUBLE); + z = (double*)((PyArrayObject*)pz)->data; + soln = (double*)((PyArrayObject*)psoln)->data; + iok = flow_restore(n, 0, fname, id, iz, z, isoln, soln); + + return Py_BuildValue("(OO)",pz,psoln); +} + +static PyObject* +py_flow_setboundaries(PyObject *self, PyObject *args) +{ + int n, nleft, nright; + if (!PyArg_ParseTuple(args, "iii:flow_setboundaries", &n, &nleft, + &nright)) + return NULL; + int iok = flow_setboundaries(n, nleft, nright); + return Py_BuildValue("i",iok); +} + + +/* flow boundary objects */ + + +static PyObject * +py_bdry_new(PyObject *self, PyObject *args) +{ + int itype, ip; + if (!PyArg_ParseTuple(args, "ii:bdry_new", &itype, &ip)) + return NULL; + int nn = bdry_new(itype,ip); + if (nn < 0) return reportError(nn); + return Py_BuildValue("i",nn); +} + +static PyObject* +py_bdry_delete(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:bdry_delete", &n)) return NULL; + bdry_del(n); + return Py_BuildValue("i",0); +} + +static PyObject* +py_bdry_set(PyObject *self, PyObject *args) +{ + int n, i; + double v; + PyObject* px; + double* x; + if (!PyArg_ParseTuple(args, "iidO:bdry_set", &n, &i, &v, &px)) + return NULL; + if (i < 4) + bdry_set(n, i, &v); + else { + x = (double*)((PyArrayObject*)px)->data; + bdry_set(n, i, x); + } + return Py_BuildValue("i",0); +} + + +/* List of functions defined in the module */ + +static PyMethodDef ct_methods[] = { + {"Flow", py_flow_new, METH_VARARGS}, + {"flow_delete", py_flow_delete, METH_VARARGS}, + {"flow_setupgrid", py_flow_setupgrid, METH_VARARGS}, + {"flow_setthermo", py_flow_setthermo, METH_VARARGS}, + {"flow_setkinetics", py_flow_setkinetics, METH_VARARGS}, + {"flow_settransport", py_flow_settransport, METH_VARARGS}, + {"flow_setpressure", py_flow_setpressure, METH_VARARGS}, + {"flow_setinletstate", py_flow_setinletstate, METH_VARARGS}, + {"flow_setinlet_u", py_flow_setinlet_u, METH_VARARGS}, + {"flow_setinlet_v", py_flow_setinlet_v, METH_VARARGS}, + {"flow_setsurface_t", py_flow_setsurface_t, METH_VARARGS}, + {"flow_solvespecies", py_flow_solvespecies, METH_VARARGS}, + {"flow_settemperature", py_flow_settemperature, METH_VARARGS}, + {"flow_setmassfraction", py_flow_setmassfraction, METH_VARARGS}, + {"flow_settolerances", py_flow_settolerances, METH_VARARGS}, + {"flow_energy", py_flow_energy, METH_VARARGS}, + {"flow_showsolution", py_flow_showsolution, METH_VARARGS}, + {"flow_eval", py_flow_eval, METH_VARARGS}, + {"flow_solve", py_flow_solve, METH_VARARGS}, + {"flow_timeinteg", py_flow_timeinteg, METH_VARARGS}, + {"flow_integratechem", py_flow_integratechem, METH_VARARGS}, + {"flow_setnewtonoptions", py_flow_setnewtonoptions, METH_VARARGS}, + {"flow_resize", py_flow_resize, METH_VARARGS}, + {"flow_outputtec", py_flow_outputtec, METH_VARARGS}, + {"flow_setsteadymode", py_flow_setsteadymode, METH_VARARGS}, + {"flow_settransientmode", py_flow_settransientmode, METH_VARARGS}, + {"flow_save", py_flow_save, METH_VARARGS}, + {"flow_restore", py_flow_restore, METH_VARARGS}, + {"flow_setfixedpoint", py_flow_setfixedpoint, METH_VARARGS}, + {"flow_setboundaries", py_flow_setboundaries, METH_VARARGS}, + {"flow_ssnorm", py_flow_ssnorm, METH_VARARGS}, + {"copy", py_copy, METH_VARARGS}, + {"bdry_new", py_bdry_new, METH_VARARGS}, + {"bdry_del", py_bdry_delete, METH_VARARGS}, + {"bdry_set", py_bdry_set, METH_VARARGS}, + {NULL, NULL} /* sentinel */ +}; + + +extern "C" { + + /* Initialization function for the module (*must* be called initctflow) */ + + DL_EXPORT(void) initctflow(void) + { + PyObject *m, *d; + + /* Initialize the type of the new type object here; doing it here + * is required for portability to Windows without requiring C++. */ + + /* Create the module and add the functions */ + m = Py_InitModule("ctflow", ct_methods); + import_array(); + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + ErrorObject = PyErr_NewException("cantera.error", NULL, NULL); + PyDict_SetItemString(d, "error", ErrorObject); + } + +} diff --git a/Cantera/python/src/ctsurf.def b/Cantera/python/src/ctsurf.def new file mode 100755 index 000000000..6d0fa5368 --- /dev/null +++ b/Cantera/python/src/ctsurf.def @@ -0,0 +1,2 @@ +EXPORTS + initctsurf \ No newline at end of file diff --git a/Cantera/python/src/ctsurf_methods.cpp b/Cantera/python/src/ctsurf_methods.cpp new file mode 100644 index 000000000..3d4ad201c --- /dev/null +++ b/Cantera/python/src/ctsurf_methods.cpp @@ -0,0 +1,84 @@ + +static PyObject* +py_surf_setsitedensity(PyObject *self, PyObject *args) +{ + int n; + double s0; + if (!PyArg_ParseTuple(args, "id:surf_setsitedensity", &n, &s0)) + return NULL; + + int iok = surf_setsitedensity(n, s0); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_surf_sitedensity(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:surf_sitedensity", &n)) + return NULL; + + double s0 = surf_sitedensity(n); + return Py_BuildValue("d",s0); +} + + +static PyObject* +py_surf_setcoverages(PyObject *self, PyObject *args) +{ + int n; + PyObject* cov; + if (!PyArg_ParseTuple(args, "iO:surf_setcoverages", &n, &cov)) + return NULL; + double* x = (double*)((PyArrayObject*)cov)->data; + int iok = surf_setcoverages(n, x); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_surf_setconcentrations(PyObject *self, PyObject *args) +{ + int n; + PyObject* c; + if (!PyArg_ParseTuple(args, "iO:surf_setconcentrations", &n, &c)) + return NULL; + double* x = (double*)((PyArrayObject*)c)->data; + int iok = surf_setconcentrations(n, x); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_surf_getcoverages(PyObject *self, PyObject *args) +{ + int n; + PyArrayObject* cov; + if (!PyArg_ParseTuple(args, "i:surf_getcoverages", &n)) + return NULL; + int nsp = th_nSpecies(n); + cov = (PyArrayObject*)PyArray_FromDims(1, &nsp, PyArray_DOUBLE); + double* x = (double*)((PyArrayObject*)cov)->data; + int iok = surf_getcoverages(n, x); + if (iok < 0) return reportError(iok); + return Py_BuildValue("O",cov); +} + +static PyObject* +py_surf_getconcentrations(PyObject *self, PyObject *args) +{ + int n; + PyArrayObject* c; + if (!PyArg_ParseTuple(args, "i:surf_getconcentrations", &n)) + return NULL; + int nsp = th_nSpecies(n); + c = (PyArrayObject*)PyArray_FromDims(1, &nsp, PyArray_DOUBLE); + double* x = (double*)((PyArrayObject*)c)->data; + int iok = surf_getconcentrations(n, x); + if (iok < 0) return reportError(iok); + return Py_BuildValue("O",c); +} + + + diff --git a/Cantera/python/src/ctthermo.cpp b/Cantera/python/src/ctthermo.cpp new file mode 100755 index 000000000..6cad25512 --- /dev/null +++ b/Cantera/python/src/ctthermo.cpp @@ -0,0 +1,294 @@ +/** + * @file ctthermo.cpp + * Cantera Python Interface + * + */ + +// turn off warnings about long names under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "Python.h" +#include "Numeric/arrayobject.h" +#include "ct.h" +#include +//#include +#include +using namespace std; + + +// constants defined in the module +static PyObject *ErrorObject; + +// local includes +#include "pyutils.h" + +static PyObject * +ct_newThermoFromXML(PyObject *self, PyObject *args) +{ + int mxml; + //char* id; + if (!PyArg_ParseTuple(args, "i:ct_newThermoFromXML", &mxml)) + return NULL; + int n = newThermoFromXML(mxml); + if (n < 0) return reportCanteraError(); + //int p = th_phase(n); + return Py_BuildValue("i",n); +} + +static PyObject* +thermo_delete(PyObject *self, PyObject *args) +{ + int th; + if (!PyArg_ParseTuple(args, "i:thermo_delete", &th)) + return NULL; + delThermo(th); + return Py_BuildValue("i",0); +} + +static PyObject* +thermo_index(PyObject *self, PyObject *args) { + char* id; + if (!PyArg_ParseTuple(args, "s:index", &id)) return NULL; + return Py_BuildValue("i",th_thermoIndex(id)); +} + +static PyObject* +thermo_refpressure(PyObject *self, PyObject *args) { + int th; + if (!PyArg_ParseTuple(args, "i:refpressure", &th)) return NULL; + return Py_BuildValue("d",th_refPressure(th)); +} + +static PyObject* +thermo_mintemp(PyObject *self, PyObject *args) { + int th, k; + if (!PyArg_ParseTuple(args, "ii:mintemp", &th, &k)) return NULL; + return Py_BuildValue("d",th_minTemp(th,k)); +} + +static PyObject* +thermo_maxtemp(PyObject *self, PyObject *args) { + int th, k; + if (!PyArg_ParseTuple(args, "ii:maxtemp", &th, &k)) return NULL; + return Py_BuildValue("d",th_maxTemp(th,k)); +} + +// static PyObject* +// thermo_geteos(PyObject *self, PyObject *args) { +// char *fname, *id; +// if (!PyArg_ParseTuple(args, "ss:geteos", &fname, &id)) return NULL; +// return Py_BuildValue("i",get_eos(fname, id)); +// } + +static PyObject* +thermo_import(PyObject *self, PyObject *args) { + int n, mxml; + char* id; + if (!PyArg_ParseTuple(args, "iis:import", &n, &mxml, &id)) return NULL; + int iok = import_phase(n, mxml, id); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + + +static PyObject* +thermo_getfp(PyObject *self, PyObject *args) +{ + double vv; + bool ok = true; + int th; + int job; + + if (!PyArg_ParseTuple(args, "ii:thermo_getfp", &th, &job)) + return NULL; + + // floating-point attributes + switch (job) { + case 1: + vv = th_enthalpy_mole(th); break; + case 2: + vv = th_intEnergy_mole(th); break; + case 3: + vv = th_entropy_mole(th); break; + case 4: + vv = th_gibbs_mole(th); break; + case 5: + vv = th_cp_mole(th); break; + case 6: + vv = th_cv_mole(th); break; + case 7: + vv = th_pressure(th); break; + case 8: + vv = th_enthalpy_mass(th); break; + case 9: + vv = th_intEnergy_mass(th); break; + case 10: + vv = th_entropy_mass(th); break; + case 11: + vv = th_gibbs_mass(th); break; + case 12: + vv = th_cp_mass(th); break; + case 13: + vv = th_cv_mass(th); break; + default: + ok = false; + } + if (ok) { + if (vv == -999.999) { + return reportCanteraError(); + } + return Py_BuildValue("d",vv); + } + else { + PyErr_SetString(ErrorObject,"Unknown floating-point attribute"); + return NULL; + } +} + +static PyObject* +thermo_setfp(PyObject *self, PyObject *args) +{ + double v1, v2; + int iok = -2; + int th; + int job; + + if (!PyArg_ParseTuple(args, "iidd:thermo_setfp", &th, &job, &v1, &v2)) + return NULL; + + //vector_fp v(2); + double* v = new double[2]; + v[0] = v1; v[1] = v2; + + // set floating-point attributes + switch (job) { + case 1: + iok = th_setPressure(th, v1); break; + case 2: + iok = th_set_HP(th, v); break; + case 3: + iok = th_set_UV(th, v); break; + case 4: + iok = th_set_SV(th, v); break; + case 5: + iok = th_set_SP(th, v); break; + default: + iok = -10; + } + delete v; + if (iok >= 0) + return Py_BuildValue("i",iok); + if (iok == -1) return reportCanteraError(); + else { + PyErr_SetString(ErrorObject,"Error in thermo_setfp"); + return NULL; + } +} + + +static PyObject* +thermo_getarray(PyObject *self, PyObject *args) +{ + int th; + int job; + + if (!PyArg_ParseTuple(args, "ii:thermo_getarray", &th, &job)) + return NULL; + + int nsp = th_nSpecies(th); + + // array attributes + int iok = -22; + PyArrayObject* x = + (PyArrayObject*)PyArray_FromDims(1, &nsp, PyArray_DOUBLE); + double* xd = (double*)x->data; + switch (job) { + case 20: + iok = th_chemPotentials(th,nsp,xd); + break; + case 23: + iok = th_getEnthalpies_RT(th,nsp,xd); + break; + case 24: + iok = th_getEntropies_R(th,nsp,xd); + break; + case 25: + iok = th_getCp_R(th,nsp,xd); + break; + + default: + ; + } + if (iok >= 0) { + return PyArray_Return(x); + } + else { + PyErr_SetString(ErrorObject,"Unknown array attribute"); + return NULL; + } +} + + +static PyObject* +thermo_equil(PyObject *self, PyObject *args) +{ + int iok = -2; + int th; + int XY; + + if (!PyArg_ParseTuple(args, "ii:thermo_equil", &th, &XY)) + return NULL; + + iok = th_equil(th, XY); + if (iok >= 0) + return Py_BuildValue("i",iok); + if (iok == -1) return reportCanteraError(); + else { + PyErr_SetString(ErrorObject,"Error in thermo_equil"); + return NULL; + } +} + +/* List of functions defined in the module */ + +static PyMethodDef ct_methods[] = { + {"ThermoFromXML", ct_newThermoFromXML, METH_VARARGS}, + {"delete", thermo_delete, METH_VARARGS}, + {"mintemp", thermo_mintemp, METH_VARARGS}, + {"maxtemp", thermo_maxtemp, METH_VARARGS}, + {"thermoIndex", thermo_index, METH_VARARGS}, + {"refpressure", thermo_refpressure, METH_VARARGS}, + {"getfp", thermo_getfp, METH_VARARGS}, + {"setfp", thermo_setfp, METH_VARARGS}, + {"getarray", thermo_getarray, METH_VARARGS}, + {"equil", thermo_equil, METH_VARARGS}, + {"import_xml", thermo_import, METH_VARARGS}, + {NULL, NULL} /* sentinel */ +}; + + +extern "C" { + + /* Initialization function for the module (*must* be called initctthermo) */ + + DL_EXPORT(void) initctthermo(void) + { + PyObject *m, *d; + + /* Initialize the type of the new type object here; doing it here + * is required for portability to Windows without requiring C++. */ + + /* Create the module and add the functions */ + m = Py_InitModule("ctthermo", ct_methods); + import_array(); + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + ErrorObject = PyErr_NewException("cantera.error", NULL, NULL); + PyDict_SetItemString(d, "error", ErrorObject); + } + +} diff --git a/Cantera/python/src/ctthermo.def b/Cantera/python/src/ctthermo.def new file mode 100755 index 000000000..3a996256a --- /dev/null +++ b/Cantera/python/src/ctthermo.def @@ -0,0 +1,2 @@ +EXPORTS + initctthermo \ No newline at end of file diff --git a/Cantera/python/src/ctthermo_methods.cpp b/Cantera/python/src/ctthermo_methods.cpp new file mode 100644 index 000000000..b1d628494 --- /dev/null +++ b/Cantera/python/src/ctthermo_methods.cpp @@ -0,0 +1,231 @@ + +static PyObject * +ct_newThermoFromXML(PyObject *self, PyObject *args) +{ + int mxml; + //char* id; + if (!PyArg_ParseTuple(args, "i:ct_newThermoFromXML", &mxml)) + return NULL; + int n = newThermoFromXML(mxml); + if (n < 0) return reportCanteraError(); + //int p = th_phase(n); + return Py_BuildValue("i",n); +} + +static PyObject* +thermo_delete(PyObject *self, PyObject *args) +{ + int th; + if (!PyArg_ParseTuple(args, "i:thermo_delete", &th)) + return NULL; + delThermo(th); + return Py_BuildValue("i",0); +} + +static PyObject* +thermo_index(PyObject *self, PyObject *args) { + char* id; + if (!PyArg_ParseTuple(args, "s:index", &id)) return NULL; + return Py_BuildValue("i",th_thermoIndex(id)); +} + +static PyObject* +thermo_refpressure(PyObject *self, PyObject *args) { + int th; + if (!PyArg_ParseTuple(args, "i:refpressure", &th)) return NULL; + return Py_BuildValue("d",th_refPressure(th)); +} + +static PyObject* +thermo_mintemp(PyObject *self, PyObject *args) { + int th, k; + if (!PyArg_ParseTuple(args, "ii:mintemp", &th, &k)) return NULL; + return Py_BuildValue("d",th_minTemp(th,k)); +} + +static PyObject* +thermo_maxtemp(PyObject *self, PyObject *args) { + int th, k; + if (!PyArg_ParseTuple(args, "ii:maxtemp", &th, &k)) return NULL; + return Py_BuildValue("d",th_maxTemp(th,k)); +} + +// static PyObject* +// thermo_geteos(PyObject *self, PyObject *args) { +// char *fname, *id; +// if (!PyArg_ParseTuple(args, "ss:geteos", &fname, &id)) return NULL; +// return Py_BuildValue("i",get_eos(fname, id)); +// } + +static PyObject* +thermo_import(PyObject *self, PyObject *args) { + int n, mxml; + char* id; + if (!PyArg_ParseTuple(args, "iis:import", &n, &mxml, &id)) return NULL; + int iok = import_phase(n, mxml, id); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + + +static PyObject* +thermo_getfp(PyObject *self, PyObject *args) +{ + double vv = -999.999; + bool ok = true; + int th; + int job; + + if (!PyArg_ParseTuple(args, "ii:thermo_getfp", &th, &job)) + return NULL; + + // floating-point attributes + switch (job) { + case 1: + vv = th_enthalpy_mole(th); break; + case 2: + vv = th_intEnergy_mole(th); break; + case 3: + vv = th_entropy_mole(th); break; + case 4: + vv = th_gibbs_mole(th); break; + case 5: + vv = th_cp_mole(th); break; + case 6: + vv = th_cv_mole(th); break; + case 7: + vv = th_pressure(th); break; + case 8: + vv = th_enthalpy_mass(th); break; + case 9: + vv = th_intEnergy_mass(th); break; + case 10: + vv = th_entropy_mass(th); break; + case 11: + vv = th_gibbs_mass(th); break; + case 12: + vv = th_cp_mass(th); break; + case 13: + vv = th_cv_mass(th); break; + default: + ok = false; + } + if (ok) { + if (vv == -999.999) { + return reportCanteraError(); + } + return Py_BuildValue("d",vv); + } + else { + PyErr_SetString(ErrorObject,"Unknown floating-point attribute"); + return NULL; + } +} + +static PyObject* +thermo_setfp(PyObject *self, PyObject *args) +{ + double v1, v2; + int iok = -2; + int th; + int job; + + if (!PyArg_ParseTuple(args, "iidd:thermo_setfp", &th, &job, &v1, &v2)) + return NULL; + + //vector_fp v(2); + double* v = new double[2]; + v[0] = v1; v[1] = v2; + + // set floating-point attributes + switch (job) { + case 1: + iok = th_setPressure(th, v1); break; + case 2: + iok = th_set_HP(th, v); break; + case 3: + iok = th_set_UV(th, v); break; + case 4: + iok = th_set_SV(th, v); break; + case 5: + iok = th_set_SP(th, v); break; + default: + iok = -10; + } + delete v; + if (iok >= 0) + return Py_BuildValue("i",iok); + if (iok == -1) return reportCanteraError(); + else { + PyErr_SetString(ErrorObject,"Error in thermo_setfp"); + return NULL; + } +} + + +static PyObject* +thermo_getarray(PyObject *self, PyObject *args) +{ + int th; + int job; + + if (!PyArg_ParseTuple(args, "ii:thermo_getarray", &th, &job)) + return NULL; + + int nsp = th_nSpecies(th); + + // array attributes + int iok = -22; + PyArrayObject* x = + (PyArrayObject*)PyArray_FromDims(1, &nsp, PyArray_DOUBLE); + double* xd = (double*)x->data; + switch (job) { + case 20: + iok = th_chemPotentials(th,nsp,xd); + break; + case 23: + iok = th_getEnthalpies_RT(th,nsp,xd); + break; + case 24: + iok = th_getEntropies_R(th,nsp,xd); + break; + case 25: + iok = th_getCp_R(th,nsp,xd); + break; + + default: + ; + } + if (iok >= 0) { + return PyArray_Return(x); + } + else { + PyErr_SetString(ErrorObject,"Unknown array attribute"); + return NULL; + } +} + + +static PyObject* +thermo_equil(PyObject *self, PyObject *args) +{ + int iok = -2; + int th; + int XY; + + if (!PyArg_ParseTuple(args, "ii:thermo_equil", &th, &XY)) + return NULL; + + iok = th_equil(th, XY); + if (iok >= 0) + return Py_BuildValue("i",iok); + if (iok == -1) return reportCanteraError(); + else { + PyErr_SetString(ErrorObject,"Error in thermo_equil"); + return NULL; + } +} + + + + diff --git a/Cantera/python/src/cttransport.cpp b/Cantera/python/src/cttransport.cpp new file mode 100755 index 000000000..fa9df831e --- /dev/null +++ b/Cantera/python/src/cttransport.cpp @@ -0,0 +1,171 @@ +/** + * @file cttransport.cpp + * Cantera Python Interface + * + */ + +// turn off warnings about long names under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "Python.h" +#include "Numeric/arrayobject.h" +#include "ct.h" +#include +//#include +#include +using namespace std; + +//#include "Cantera.h" + +// constants defined in the module +static PyObject *ErrorObject; + +// local includes +#include "pyutils.h" + + + +/** + * Create a new Transport object. + */ +static PyObject * +py_transport_new(PyObject *self, PyObject *args) { + char* model; + int ph; + int loglevel; + if (!PyArg_ParseTuple(args, "sii:transport_new", &model, + &ph, &loglevel)) + return NULL; + int n = newTransport(model, ph, loglevel); + if (n < 0) return reportError(n); + return Py_BuildValue("i",n); +} + + +/** + * Delete the Phase object. + */ +static PyObject* +py_transport_delete(PyObject *self, PyObject *args) +{ + int tr; + if (!PyArg_ParseTuple(args, "i:transport_delete", &tr)) + return NULL; + delTransport(tr); + return Py_BuildValue("i",0); +} + + +static PyObject* +py_viscosity(PyObject *self, PyObject *args) { + int n; + if (!PyArg_ParseTuple(args, "i:py_viscosity", &n)) return NULL; + double mu = trans_viscosity(n); + if (mu < 0.0) return reportError(int(mu)); + return Py_BuildValue("d",mu); +} + +static PyObject* +py_thermalConductivity(PyObject *self, PyObject *args) { + int n; + if (!PyArg_ParseTuple(args, "i:py_thermalConductivity", &n)) return NULL; + double lambda = trans_thermalConductivity(n); + if (lambda < 0.0) return reportError(int(lambda)); + return Py_BuildValue("d",lambda); +} + +static PyObject* +py_thermalDiffCoeffs(PyObject *self, PyObject *args) { + int n, idt; + if (!PyArg_ParseTuple(args, "ii:py_thermalDiffCoeffs", &n, &idt)) + return NULL; + PyArrayObject* dt = + (PyArrayObject*)PyArray_FromDims(1, &idt, PyArray_DOUBLE); + int iok = trans_getThermalDiffCoeffs(n, idt, (double*)dt->data); + if (iok < 0) return reportError(iok); + return PyArray_Return(dt); +} + +static PyObject* +py_binaryDiffCoeffs(PyObject *self, PyObject *args) { + int n, id; + if (!PyArg_ParseTuple(args, "ii:py_binaryDiffCoeffs", &n, &id)) + return NULL; + int idim[2]; + idim[0] = id; + idim[1] = id; + PyArrayObject* d = + (PyArrayObject*)PyArray_FromDims(2, idim, PyArray_DOUBLE); + int iok = trans_getBinDiffCoeffs(n, id, (double*)d->data); + if (iok < 0) return reportError(iok); + return PyArray_Return(d); +} + +static PyObject* +py_mixDiffCoeffs(PyObject *self, PyObject *args) { + int n, id; + if (!PyArg_ParseTuple(args, "ii:py_mixDiffCoeffs", &n, &id)) + return NULL; + PyArrayObject* d = + (PyArrayObject*)PyArray_FromDims(1, &id, PyArray_DOUBLE); + int iok = trans_getMixDiffCoeffs(n, id, (double*)d->data); + if (iok < 0) return reportError(iok); + return PyArray_Return(d); +} + +static PyObject* +py_multiDiffCoeffs(PyObject *self, PyObject *args) { + int n, id; + if (!PyArg_ParseTuple(args, "ii:py_multiDiffCoeffs", &n, &id)) + return NULL; + //vector_int idim(2,id); + int idim[2]; + idim[0] = id; + idim[1] = id; + PyArrayObject* d = + (PyArrayObject*)PyArray_FromDims(2, idim, PyArray_DOUBLE); + int iok = trans_getMultiDiffCoeffs(n, id, (double*)d->data); + if (iok < 0) return reportError(iok); + return PyArray_Return(d); +} + + +/* List of functions defined in the module */ + +static PyMethodDef ct_methods[] = { + {"Transport", py_transport_new, METH_VARARGS}, + {"delete", py_transport_delete, METH_VARARGS}, + {"viscosity", py_viscosity, METH_VARARGS}, + {"thermalConductivity", py_thermalConductivity, METH_VARARGS}, + {"thermalDiffCoeffs", py_thermalDiffCoeffs, METH_VARARGS}, + {"binaryDiffCoeffs", py_binaryDiffCoeffs, METH_VARARGS}, + {"mixDiffCoeffs", py_mixDiffCoeffs, METH_VARARGS}, + {"multiDiffCoeffs", py_multiDiffCoeffs, METH_VARARGS}, + {NULL, NULL} /* sentinel */ +}; + + +extern "C" { + + /* Initialization function for the module (*must* be called initcttransport) */ + + DL_EXPORT(void) initcttransport(void) + { + PyObject *m, *d; + + /* Initialize the type of the new type object here; doing it here + * is required for portability to Windows without requiring C++. */ + + /* Create the module and add the functions */ + m = Py_InitModule("cttransport", ct_methods); + import_array(); + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + ErrorObject = PyErr_NewException("cantera.error", NULL, NULL); + PyDict_SetItemString(d, "error", ErrorObject); + } +} diff --git a/Cantera/python/src/cttransport.def b/Cantera/python/src/cttransport.def new file mode 100755 index 000000000..e2f1f45e5 --- /dev/null +++ b/Cantera/python/src/cttransport.def @@ -0,0 +1,2 @@ +EXPORTS + initcttransport diff --git a/Cantera/python/src/cttransport_methods.cpp b/Cantera/python/src/cttransport_methods.cpp new file mode 100644 index 000000000..00953e9c0 --- /dev/null +++ b/Cantera/python/src/cttransport_methods.cpp @@ -0,0 +1,106 @@ + +/** + * Create a new Transport object. + */ +static PyObject * +py_transport_new(PyObject *self, PyObject *args) { + char* model; + int ph; + int loglevel; + if (!PyArg_ParseTuple(args, "sii:transport_new", &model, + &ph, &loglevel)) + return NULL; + int n = newTransport(model, ph, loglevel); + if (n < 0) return reportError(n); + return Py_BuildValue("i",n); +} + + +/** + * Delete the Phase object. + */ +static PyObject* +py_transport_delete(PyObject *self, PyObject *args) +{ + int tr; + if (!PyArg_ParseTuple(args, "i:transport_delete", &tr)) + return NULL; + delTransport(tr); + return Py_BuildValue("i",0); +} + + +static PyObject* +py_viscosity(PyObject *self, PyObject *args) { + int n; + if (!PyArg_ParseTuple(args, "i:py_viscosity", &n)) return NULL; + double mu = trans_viscosity(n); + if (mu < 0.0) return reportError(int(mu)); + return Py_BuildValue("d",mu); +} + +static PyObject* +py_thermalConductivity(PyObject *self, PyObject *args) { + int n; + if (!PyArg_ParseTuple(args, "i:py_thermalConductivity", &n)) return NULL; + double lambda = trans_thermalConductivity(n); + if (lambda < 0.0) return reportError(int(lambda)); + return Py_BuildValue("d",lambda); +} + +static PyObject* +py_thermalDiffCoeffs(PyObject *self, PyObject *args) { + int n, idt; + if (!PyArg_ParseTuple(args, "ii:py_thermalDiffCoeffs", &n, &idt)) + return NULL; + PyArrayObject* dt = + (PyArrayObject*)PyArray_FromDims(1, &idt, PyArray_DOUBLE); + int iok = trans_getThermalDiffCoeffs(n, idt, (double*)dt->data); + if (iok < 0) return reportError(iok); + return PyArray_Return(dt); +} + +static PyObject* +py_binaryDiffCoeffs(PyObject *self, PyObject *args) { + int n, id; + if (!PyArg_ParseTuple(args, "ii:py_binaryDiffCoeffs", &n, &id)) + return NULL; + int idim[2]; + idim[0] = id; + idim[1] = id; + PyArrayObject* d = + (PyArrayObject*)PyArray_FromDims(2, idim, PyArray_DOUBLE); + int iok = trans_getBinDiffCoeffs(n, id, (double*)d->data); + if (iok < 0) return reportError(iok); + return PyArray_Return(d); +} + +static PyObject* +py_mixDiffCoeffs(PyObject *self, PyObject *args) { + int n, id; + if (!PyArg_ParseTuple(args, "ii:py_mixDiffCoeffs", &n, &id)) + return NULL; + PyArrayObject* d = + (PyArrayObject*)PyArray_FromDims(1, &id, PyArray_DOUBLE); + int iok = trans_getMixDiffCoeffs(n, id, (double*)d->data); + if (iok < 0) return reportError(iok); + return PyArray_Return(d); +} + +static PyObject* +py_multiDiffCoeffs(PyObject *self, PyObject *args) { + int n, id; + if (!PyArg_ParseTuple(args, "ii:py_multiDiffCoeffs", &n, &id)) + return NULL; + //vector_int idim(2,id); + int idim[2]; + idim[0] = id; + idim[1] = id; + PyArrayObject* d = + (PyArrayObject*)PyArray_FromDims(2, idim, PyArray_DOUBLE); + int iok = trans_getMultiDiffCoeffs(n, id, (double*)d->data); + if (iok < 0) return reportError(iok); + return PyArray_Return(d); +} + + diff --git a/Cantera/python/src/ctxml_methods.cpp b/Cantera/python/src/ctxml_methods.cpp new file mode 100644 index 000000000..6e8426b07 --- /dev/null +++ b/Cantera/python/src/ctxml_methods.cpp @@ -0,0 +1,214 @@ + +static PyObject* +py_xml_new(PyObject *self, PyObject *args) +{ + char* nm; + if (!PyArg_ParseTuple(args, "s:xml_new", &nm)) + return NULL; + int n = xml_new(nm); + return Py_BuildValue("i",n); +} + +static PyObject* +py_xml_del(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:xml_del", &n)) + return NULL; + int iok = xml_del(n); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_xml_build(PyObject *self, PyObject *args) +{ + int n; + char* file; + if (!PyArg_ParseTuple(args, "is:xml_build", &n, &file)) + return NULL; + int iok = xml_build(n, file); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",0); +} + +static PyObject* +py_xml_attrib(PyObject *self, PyObject *args) +{ + int n; + char *key; + if (!PyArg_ParseTuple(args, "is:xml_attrib", &n, &key)) + return NULL; + char* val = new char[81]; + int iok = xml_attrib(n, key, val); + if (iok < 0) return reportError(iok); + PyObject* r = Py_BuildValue("s",val); + delete val; + return r; +} + +static PyObject* +py_xml_tag(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:xml_tag", &n)) + return NULL; + char* val = new char[81]; + int iok = xml_tag(n, val); + if (iok < 0) return reportError(iok); + PyObject* r = Py_BuildValue("s",val); + delete val; + return r; +} + +static PyObject* +py_xml_value(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:xml_value", &n)) + return NULL; + char* val = new char[81]; + int iok = xml_value(n, val); + if (iok < 0) return reportError(iok); + PyObject* r = Py_BuildValue("s",val); + delete val; + return r; +} + +static PyObject* +py_xml_child(PyObject *self, PyObject *args) +{ + int n; + char* loc; + if (!PyArg_ParseTuple(args, "is:xml_child", &n, &loc)) + return NULL; + int m = xml_child(n, loc); + if (m < 0) return reportError(m); + return Py_BuildValue("i",m); +} + +static PyObject* +py_xml_childbynumber(PyObject *self, PyObject *args) +{ + int n, k; + if (!PyArg_ParseTuple(args, "ii:xml_childbynumber", &n, &k)) + return NULL; + int m = xml_child_bynumber(n, k); + if (m < 0) return reportError(m); + return Py_BuildValue("i",m); +} + +static PyObject* +py_xml_findID(PyObject *self, PyObject *args) +{ + int n; + char* id; + if (!PyArg_ParseTuple(args, "is:xml_findID", &n, &id)) + return NULL; + int m = xml_findID(n, id); + if (m < 0) return reportError(m); + return Py_BuildValue("i",m); +} + +static PyObject* +py_xml_findByName(PyObject *self, PyObject *args) +{ + int n; + char* nm; + if (!PyArg_ParseTuple(args, "is:xml_findID", &n, &nm)) + return NULL; + int m = xml_findByName(n, nm); + if (m < 0) return reportError(m); + return Py_BuildValue("i",m); +} + +static PyObject* +py_xml_nChildren(PyObject *self, PyObject *args) +{ + int n; + if (!PyArg_ParseTuple(args, "i:xml_nChildren", &n)) + return NULL; + int m = xml_nChildren(n); + if (m < 0) return reportError(m); + return Py_BuildValue("i",m); +} + +static PyObject* +py_xml_addChild(PyObject *self, PyObject *args) +{ + int n; + char *name, *value; + if (!PyArg_ParseTuple(args, "iss:xml_addChild", &n, &name, &value)) + return NULL; + int m = xml_addChild(n, name, value); + if (m < 0) return reportError(m); + return Py_BuildValue("i",m); +} + + +static PyObject* +py_xml_addChildNode(PyObject *self, PyObject *args) +{ + int n, j; + if (!PyArg_ParseTuple(args, "ii:xml_addChildNode", &n, &j)) + return NULL; + int m = xml_addChildNode(n, j); + if (m < 0) return reportError(m); + return Py_BuildValue("i",m); +} + + +static PyObject* +py_xml_addAttrib(PyObject *self, PyObject *args) +{ + int n; + char *name, *value; + if (!PyArg_ParseTuple(args, "iss:xml_addAttrib", &n, &name, &value)) + return NULL; + int m = xml_addAttrib(n, name, value); + if (m < 0) return reportError(m); + return Py_BuildValue("i",m); +} + +static PyObject* +py_xml_removeChild(PyObject *self, PyObject *args) +{ + int n, m; + if (!PyArg_ParseTuple(args, "ii:xml_removeChild", &n, &m)) + return NULL; + int iok = xml_removeChild(n, m); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + + +static PyObject* +py_xml_write(PyObject *self, PyObject *args) +{ + int n; + char *file; + if (!PyArg_ParseTuple(args, "is:xml_write", &n, &file)) + return NULL; + int iok = xml_write(n, file); + if (iok < 0) return reportError(iok); + return Py_BuildValue("i",iok); +} + +static PyObject* +py_ctml_getFloatArray(PyObject *self, PyObject *args) +{ + int n; + int iconv, ia; + if (!PyArg_ParseTuple(args, "iii", &n, &iconv, &ia)) + return NULL; + + PyArrayObject* a = + (PyArrayObject*)PyArray_FromDims(1, &ia, PyArray_DOUBLE); + double* x = (double*)a->data; + int iok = ctml_getFloatArray(n, ia, x, iconv); + if (iok < 0) return reportError(iok); + return PyArray_Return(a); +} + + + diff --git a/Cantera/python/src/methods.h b/Cantera/python/src/methods.h new file mode 100644 index 000000000..2597488a7 --- /dev/null +++ b/Cantera/python/src/methods.h @@ -0,0 +1,211 @@ +/* List of functions defined in the module */ + +static PyMethodDef ct_methods[] = { + + {"phase_temperature", py_temperature, METH_VARARGS}, + {"phase_density", py_density, METH_VARARGS}, + {"phase_molardensity", py_molardensity, METH_VARARGS}, + {"phase_meanmolwt", py_meanmolwt, METH_VARARGS}, + {"phase_molefraction", py_molefraction, METH_VARARGS}, + {"phase_massfraction", py_massfraction, METH_VARARGS}, + {"phase_nelements", py_nelements, METH_VARARGS}, + {"phase_nspecies", py_nspecies, METH_VARARGS}, + {"phase_natoms", py_natoms, METH_VARARGS}, + {"phase_addelement", py_addelement, METH_VARARGS}, + {"phase_elementindex", py_elementindex, METH_VARARGS}, + {"phase_speciesindex", py_speciesindex, METH_VARARGS}, + {"phase_getarray", phase_getarray, METH_VARARGS}, + {"phase_getstring", phase_getstring, METH_VARARGS}, + {"phase_setfp", phase_setfp, METH_VARARGS}, + {"phase_setarray", phase_setarray, METH_VARARGS}, + {"phase_setstring", phase_setstring, METH_VARARGS}, + {"phase_report", py_report, METH_VARARGS}, + + {"ThermoFromXML", ct_newThermoFromXML, METH_VARARGS}, + {"thermo_delete", thermo_delete, METH_VARARGS}, + {"thermo_mintemp", thermo_mintemp, METH_VARARGS}, + {"thermo_maxtemp", thermo_maxtemp, METH_VARARGS}, + {"thermo_thermoIndex", thermo_index, METH_VARARGS}, + {"thermo_refpressure", thermo_refpressure, METH_VARARGS}, + {"thermo_getfp", thermo_getfp, METH_VARARGS}, + {"thermo_setfp", thermo_setfp, METH_VARARGS}, + {"thermo_getarray", thermo_getarray, METH_VARARGS}, + {"thermo_equil", thermo_equil, METH_VARARGS}, + {"thermo_import_xml", thermo_import, METH_VARARGS}, + + {"xml_attrib", py_xml_attrib, METH_VARARGS}, + {"xml_addAttrib", py_xml_addAttrib, METH_VARARGS}, + {"xml_tag", py_xml_tag, METH_VARARGS}, + {"xml_value", py_xml_value, METH_VARARGS}, + {"xml_new", py_xml_new, METH_VARARGS}, + {"xml_del", py_xml_del, METH_VARARGS}, + {"xml_build", py_xml_build, METH_VARARGS}, + {"xml_child", py_xml_child, METH_VARARGS}, + {"xml_childbynumber", py_xml_childbynumber, METH_VARARGS}, + {"xml_findID", py_xml_findID, METH_VARARGS}, + {"xml_findByName", py_xml_findByName, METH_VARARGS}, + {"xml_nChildren", py_xml_nChildren, METH_VARARGS}, + {"xml_addChild", py_xml_addChild, METH_VARARGS}, + {"xml_addChildNode", py_xml_addChildNode, METH_VARARGS}, + {"xml_removeChild", py_xml_removeChild, METH_VARARGS}, + {"xml_write", py_xml_write, METH_VARARGS}, + {"ctml_getFloatArray", py_ctml_getFloatArray, METH_VARARGS}, + + {"KineticsFromXML", kin_newFromXML, METH_VARARGS}, + {"kin_delete", kin_delete, METH_VARARGS}, + {"kin_nspecies", kin_nspecies, METH_VARARGS}, + {"kin_nreactions", kin_nrxns, METH_VARARGS}, + {"kin_isreversible", kin_isrev, METH_VARARGS}, + {"kin_rstoichcoeff", kin_rstoichcoeff, METH_VARARGS}, + {"kin_pstoichcoeff", kin_pstoichcoeff, METH_VARARGS}, + {"kin_rxntype", kin_rxntype, METH_VARARGS}, + {"kin_type", kin_type, METH_VARARGS}, + {"kin_start", kin_start, METH_VARARGS}, + {"kin_multiplier", kin_multiplier, METH_VARARGS}, + {"kin_setMultiplier", kin_setMultiplier, METH_VARARGS}, + {"kin_speciesIndex", kin_speciesIndex, METH_VARARGS}, + {"kin_getarray", kin_getarray, METH_VARARGS}, + {"kin_getstring", kin_getstring, METH_VARARGS}, + + {"Transport", py_transport_new, METH_VARARGS}, + {"tran_delete", py_transport_delete, METH_VARARGS}, + {"tran_viscosity", py_viscosity, METH_VARARGS}, + {"tran_thermalConductivity", py_thermalConductivity, METH_VARARGS}, + {"tran_thermalDiffCoeffs", py_thermalDiffCoeffs, METH_VARARGS}, + {"tran_binaryDiffCoeffs", py_binaryDiffCoeffs, METH_VARARGS}, + {"tran_mixDiffCoeffs", py_mixDiffCoeffs, METH_VARARGS}, + {"tran_multiDiffCoeffs", py_multiDiffCoeffs, METH_VARARGS}, + + {"get_Cantera_Error", ct_get_cantera_error, METH_VARARGS}, + {"ct_print", ct_print, METH_VARARGS}, + {"readlog", ct_readlog, METH_VARARGS}, + {"ck2ctml", ct_ck2ctml, METH_VARARGS}, + {"buildSolutionFromXML", ct_buildSolutionFromXML, METH_VARARGS}, + + {"Flow", py_flow_new, METH_VARARGS}, + {"flow_delete", py_flow_delete, METH_VARARGS}, + {"flow_setupgrid", py_flow_setupgrid, METH_VARARGS}, + {"flow_setthermo", py_flow_setthermo, METH_VARARGS}, + {"flow_setkinetics", py_flow_setkinetics, METH_VARARGS}, + {"flow_settransport", py_flow_settransport, METH_VARARGS}, + {"flow_setpressure", py_flow_setpressure, METH_VARARGS}, + {"flow_solvespecies", py_flow_solvespecies, METH_VARARGS}, + {"flow_settemperature", py_flow_settemperature, METH_VARARGS}, + {"flow_setenergyfactor", py_flow_setenergyfactor, METH_VARARGS}, + {"flow_setmassfraction", py_flow_setmassfraction, METH_VARARGS}, + {"flow_settolerances", py_flow_settolerances, METH_VARARGS}, + {"flow_energy", py_flow_energy, METH_VARARGS}, + {"flow_showsolution", py_flow_showsolution, METH_VARARGS}, + {"flow_resize", py_flow_resize, METH_VARARGS}, + {"flow_outputtec", py_flow_outputtec, METH_VARARGS}, + {"flow_restore", py_flow_restore, METH_VARARGS}, + {"flow_setfixedpoint", py_flow_setfixedpoint, METH_VARARGS}, + {"flow_setboundaries", py_flow_setboundaries, METH_VARARGS}, + {"copy", py_copy, METH_VARARGS}, + {"bdry_new", py_bdry_new, METH_VARARGS}, + {"bdry_del", py_bdry_delete, METH_VARARGS}, + {"bdry_set", py_bdry_set, METH_VARARGS}, + {"onedim_solve", py_onedim_solve, METH_VARARGS}, + {"onedim_new", py_onedim_new, METH_VARARGS}, + {"onedim_del", py_onedim_delete, METH_VARARGS}, + {"onedim_setnewtonoptions", py_onedim_setnewtonoptions, METH_VARARGS}, + {"onedim_ssnorm", py_onedim_ssnorm, METH_VARARGS}, + {"onedim_setsteadymode", py_onedim_setsteadymode, METH_VARARGS}, + {"onedim_settransientmode", py_onedim_settransientmode, METH_VARARGS}, + {"onedim_eval", py_onedim_eval, METH_VARARGS}, + {"onedim_addflow", py_onedim_addflow, METH_VARARGS}, + {"onedim_resize", py_onedim_resize, METH_VARARGS}, + {"onedim_writestats", py_onedim_writestats, METH_VARARGS}, + {"onedim_timestep", py_onedim_timestep, METH_VARARGS}, + {"onedim_save", py_onedim_save, METH_VARARGS}, + + {"surf_setsitedensity", py_surf_setsitedensity, METH_VARARGS}, + {"surf_sitedensity", py_surf_sitedensity, METH_VARARGS}, + {"surf_setcoverages", py_surf_setcoverages, METH_VARARGS}, + {"surf_getcoverages", py_surf_getcoverages, METH_VARARGS}, + {"surf_setconcentrations", py_surf_setconcentrations, METH_VARARGS}, + {"surf_getconcentrations", py_surf_getconcentrations, METH_VARARGS}, + + {"rdiag_setDashedColor", py_rdiag_setDashedColor, METH_VARARGS}, + {"rbuild_new", py_rbuild_new, METH_VARARGS}, + {"rdiag_write", py_rdiag_write, METH_VARARGS}, + {"rdiag_setDotOptions", py_rdiag_setDotOptions, METH_VARARGS}, + {"rdiag_setScale", py_rdiag_setScale, METH_VARARGS}, + {"rdiag_setTitle", py_rdiag_setTitle, METH_VARARGS}, + {"rdiag_setArrowWidth", py_rdiag_setArrowWidth, METH_VARARGS}, + {"rdiag_displayOnly", py_rdiag_displayOnly, METH_VARARGS}, + {"rdiag_setThreshold", py_rdiag_setThreshold, METH_VARARGS}, + {"rdiag_setBoldThreshold", py_rdiag_setBoldThreshold, METH_VARARGS}, + {"rdiag_new", py_rdiag_new, METH_VARARGS}, + {"rdiag_del", py_rdiag_del, METH_VARARGS}, + {"rdiag_detailed", py_rdiag_detailed, METH_VARARGS}, + {"rdiag_add", py_rdiag_add, METH_VARARGS}, + {"rdiag_findMajor", py_rdiag_findMajor, METH_VARARGS}, + {"rbuild_build", py_rbuild_build, METH_VARARGS}, + {"rdiag_setNormalThreshold", py_rdiag_setNormalThreshold, METH_VARARGS}, + {"rdiag_brief", py_rdiag_brief, METH_VARARGS}, + {"rbuild_del", py_rbuild_del, METH_VARARGS}, + {"rdiag_setNormalColor", py_rdiag_setNormalColor, METH_VARARGS}, + {"rbuild_init", py_rbuild_init, METH_VARARGS}, + {"rdiag_setBoldColor", py_rdiag_setBoldColor, METH_VARARGS}, + {"rdiag_setFlowType", py_rdiag_setFlowType, METH_VARARGS}, + {"rdiag_setLabelThreshold", py_rdiag_setLabelThreshold, METH_VARARGS}, + + {"bndry_temperature", py_bndry_temperature, METH_VARARGS}, + {"bndry_setxin", py_bndry_setxin, METH_VARARGS}, + {"bndry_setxinbyname", py_bndry_setxinbyname, METH_VARARGS}, + {"bndry_settemperature", py_bndry_settemperature, METH_VARARGS}, + {"bndry_new", py_bndry_new, METH_VARARGS}, + {"bndry_del", py_bndry_del, METH_VARARGS}, + {"bndry_mdot", py_bndry_mdot, METH_VARARGS}, + {"bndry_setmdot", py_bndry_setmdot, METH_VARARGS}, + + {"flowdev_ready", py_flowdev_ready, METH_VARARGS}, + {"reactor_setInitialTime", py_reactor_setInitialTime, METH_VARARGS}, + {"flowdev_new", py_flowdev_new, METH_VARARGS}, + {"flowdev_massFlowRate", py_flowdev_massFlowRate, METH_VARARGS}, + {"flowdev_del", py_flowdev_del, METH_VARARGS}, + {"flowdev_setpoint", py_flowdev_setpoint, METH_VARARGS}, + {"reactor_temperature", py_reactor_temperature, METH_VARARGS}, + {"flowdev_setSetpoint", py_flowdev_setSetpoint, METH_VARARGS}, + {"flowdev_install", py_flowdev_install, METH_VARARGS}, + {"reactor_setThermoMgr", py_reactor_setThermoMgr, METH_VARARGS}, + {"reactor_setEnergy", py_reactor_setEnergy, METH_VARARGS}, + {"reactor_volume", py_reactor_volume, METH_VARARGS}, + {"reactor_time", py_reactor_time, METH_VARARGS}, + {"reactor_advance", py_reactor_advance, METH_VARARGS}, + {"reactor_step", py_reactor_step, METH_VARARGS}, + {"flowdev_setParameters", py_flowdev_setParameters, METH_VARARGS}, + {"flowdev_setFunction", py_flowdev_setFunction, METH_VARARGS}, + {"reactor_mass", py_reactor_mass, METH_VARARGS}, + {"reactor_new", py_reactor_new, METH_VARARGS}, + {"reactor_enthalpy_mass", py_reactor_enthalpy_mass, METH_VARARGS}, + {"reactor_pressure", py_reactor_pressure, METH_VARARGS}, + {"reactor_setInitialVolume", py_reactor_setInitialVolume, METH_VARARGS}, + {"reactor_density", py_reactor_density, METH_VARARGS}, + {"reactor_setKineticsMgr", py_reactor_setKineticsMgr, METH_VARARGS}, + {"reactor_del", py_reactor_del, METH_VARARGS}, + {"reactor_intEnergy_mass", py_reactor_intEnergy_mass, METH_VARARGS}, + {"reactor_massFraction", py_reactor_massFraction, METH_VARARGS}, + {"wall_install", py_wall_install, METH_VARARGS}, + {"wall_area", py_wall_area, METH_VARARGS}, + {"wall_setArea", py_wall_setArea, METH_VARARGS}, + {"wall_setThermalResistance", py_wall_setThermalResistance, METH_VARARGS}, + {"wall_setHeatTransferCoeff", py_wall_setHeatTransferCoeff, METH_VARARGS}, + {"wall_setHeatFlux", py_wall_setHeatFlux, METH_VARARGS}, + {"wall_Q", py_wall_Q, METH_VARARGS}, + {"wall_new", py_wall_new, METH_VARARGS}, + {"wall_vdot", py_wall_vdot, METH_VARARGS}, + {"wall_del", py_wall_del, METH_VARARGS}, + {"wall_setExpansionRate", py_wall_setExpansionRate, METH_VARARGS}, + {"wall_setExpansionRateCoeff", py_wall_setExpansionRateCoeff, METH_VARARGS}, + {"wall_ready", py_wall_ready, METH_VARARGS}, + + {"func_new", py_func_new, METH_VARARGS}, + {"func_newcombo", py_func_newcombo, METH_VARARGS}, + {"func_del", py_func_del, METH_VARARGS}, + {"func_value", py_func_value, METH_VARARGS}, + + {NULL, NULL} /* sentinel */ +}; + diff --git a/Cantera/python/src/pycantera.cpp b/Cantera/python/src/pycantera.cpp new file mode 100644 index 000000000..26c5b3fd4 --- /dev/null +++ b/Cantera/python/src/pycantera.cpp @@ -0,0 +1,73 @@ +/** + * @file pycantera.cpp + * + * This is the main file for the Python interface module. + * + */ + +// turn off warnings about long names under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + + +#include "Python.h" +#include "Numeric/arrayobject.h" + +#include "ct.h" +#include "ctxml.h" +#include "ctstagn.h" +#include "ctsurf.h" +#include "ctbdry.h" +#include "ctrpath.h" +#include "ctreactor.h" +#include "ctfunc.h" + +#include +using namespace std; + +// constants defined in the module +static PyObject *ErrorObject; + +// local includes +#include "pyutils.h" + +#include "ctphase_methods.cpp" +#include "ctthermo_methods.cpp" +#include "ctkinetics_methods.cpp" +#include "cttransport_methods.cpp" +#include "ctxml_methods.cpp" +#include "ctflow_methods.cpp" +#include "ctfuncs.cpp" +#include "ctsurf_methods.cpp" +#include "ctbndry_methods.cpp" +#include "ctrpath_methods.cpp" +#include "ctreactor_methods.cpp" +#include "ctfunc_methods.cpp" + +#include "methods.h" + +extern "C" { + + /* Initialization function for the module */ + + DL_EXPORT(void) init_cantera(void) + { + PyObject *m, *d; + + /* Initialize the type of the new type object here; doing it here + * is required for portability to Windows without requiring C++. */ + + /* Create the module and add the functions */ + m = Py_InitModule("_cantera", ct_methods); + import_array(); + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + ErrorObject = PyErr_NewException("cantera.error", NULL, NULL); + PyDict_SetItemString(d, "error", ErrorObject); + } + +} + diff --git a/Cantera/python/src/pyutils.h b/Cantera/python/src/pyutils.h new file mode 100755 index 000000000..e60dd520f --- /dev/null +++ b/Cantera/python/src/pyutils.h @@ -0,0 +1,137 @@ +#ifndef CTPY_UTILS +#define CTPY_UTILS + +#include "Python.h" + +static PyObject* reportCanteraError() { + char* buf = new char[400]; + getCanteraError(400, buf); + PyErr_SetString(ErrorObject,buf); + delete buf; + return NULL; +} + +static PyObject* reportError(int n) { + if (n == -1) return reportCanteraError(); + else if (n < 0) { + PyErr_SetString(ErrorObject,"Exception occurred."); + } + return NULL; +} + +// template +// int pyNumericSequence_ToVector(PyObject* seq, V& vec) +// { +// if (!PySequence_Check(seq)) return -1; +// int n = PySequence_Size(seq); +// vec.resize(n); +// PyObject* item; +// double x; +// for (int i = 0; i < n; i++) { +// item = PySequence_GetItem(seq, i); +// if (PyFloat_Check(item)) +// x = PyFloat_AsDouble(item); +// else if (PyInt_Check(item)) +// x = 1.0*PyInt_AsLong(item); +// else +// return -2; +// vec[i] = x; +// } +// return 1; +// } + + +// template +// PyObject* pyNumericTuple_FromVector(const V& vec) +// { +// int n = vec.size(); +// PyObject* seq = PyTuple_New(n); +// PyObject* item; +// for (int i = 0; i < n; i++) { +// item = PyFloat_FromDouble(1.0*vec[i]); +// if (PyTuple_SetItem(seq, i, item) < 0) return NULL; +// } +// return seq; +// } + + +// template +// PyObject* pyNumericList_FromVector(const V& vec) +// { +// int n = vec.size(); +// PyObject* seq = PyList_New(n); +// PyObject* item; +// for (int i = 0; i < n; i++) { +// item = PyFloat_FromDouble(1.0*vec[i]); +// if (PyList_SetItem(seq, i, item) < 0) return NULL; +// } +// return seq; +// } + +// template +// PyObject* pyStringTuple_FromVector(const V& vec) +// { +// int n = vec.size(); +// PyObject* seq = PyTuple_New(n); +// PyObject* item; +// for (int i = 0; i < n; i++) { +// item = PyString_FromString(vec[i].c_str()); +// if (PyTuple_SetItem(seq, i, item) < 0) return NULL; +// } +// return seq; +// } + + +// template +// int pyStrNumMapping_ToMap(PyObject* d, M& m) +// { +// if (!PyMapping_Check(d)) return -1; +// int n = PyMapping_Length(d); +// PyObject *keys, *values, *ky, *v; +// double x; +// string key; +// keys = PyMapping_Keys(d); +// values = PyMapping_Values(d); +// for (int i = 0; i < n; i++) { +// ky = PySequence_GetItem(keys, i); +// v = PySequence_GetItem(values, i); +// key = string(PyString_AsString(ky)); +// if (PyFloat_Check(v)) +// x = PyFloat_AsDouble(v); +// else if (PyInt_Check(v)) +// x = 1.0*PyInt_AsLong(v); +// else +// return -2; +// m[key] = x; +// } +// return 1; +// } + + +// template +// PyObject* pyStrNumMapping_FromMap(M& m) +// { +// if (!PyMapping_Check(d)) return -1; +// int n = m.size(); +// double value; +// char* key; +// PyObject* x; +// TYPENAME_KEYWORD M::const_iter ptr; +// PyObject* map = PyDict_New(); +// for (int i = 0; i < n; i++) { +// key = ptr->first.c_str(); +// value = ptr->second; +// x = PyFloat_FromDouble(value); +// PyMapping_SetItemString(map, key, x); +// } +// return map; +// } + + +// static int lengthError() { +// PyErr_SetString(PyExc_AttributeError, +// "wrong length for sequence"); +// return -1; +// } + +#endif diff --git a/Cantera/python/src/reactionpath.cpp b/Cantera/python/src/reactionpath.cpp new file mode 100755 index 000000000..3e6facb4a --- /dev/null +++ b/Cantera/python/src/reactionpath.cpp @@ -0,0 +1,71 @@ + +/* Cantera objects */ + +#ifdef WIN32 +#pragma warning(disable:4786) +#endif + +#include "Python.h" +#include "Cantera.h" +#include +using namespace std; + +static PyObject *ErrorObject; + +#include "pyutils.h" + +static PyObject * +ct_newCtRxnPath(PyObject *self, PyObject *args) +{ + CtRxnPath *rv; + PyObject* s; + if (!PyArg_ParseTuple(args, "O:newCtRxnPath", &s)) + return NULL; + if (!CtSubstance_check(s)) { + PyErr_SetString(ErrorObject, "argument must be of type CtSubstance"); + } + ReactingSubstance* g = s->g; + rv = newCtRxnPath(g); + if ( rv == NULL ) return NULL; + return (PyObject *)rv; +} + + +/* List of functions defined in the module */ + +static PyMethodDef ct_methods[] = { + {"Substance", ct_newSubstance, METH_VARARGS}, + {"CKGas", ct_newSubstance, METH_VARARGS}, + {"Substance", ct_newSubstance, METH_VARARGS}, + {NULL, NULL} /* sentinel */ +}; + + +extern "C" { + + /* Initialization function for the module (*must* be called initcantera) */ + + DL_EXPORT(void) + initcantera(void) + { + PyObject *m, *d; + + CtSubstance::init(); + + /* Initialize the type of the new type object here; doing it here + * is required for portability to Windows without requiring C++. */ + CtSubstance_Type.ob_type = &PyType_Type; + CtSubstance_Type.tp_dealloc = (destructor)CtSubstance_dealloc; + CtSubstance_Type.tp_getattr = (getattrfunc)CtSubstance_getattr; + CtSubstance_Type.tp_setattr = (setattrfunc)CtSubstance_setattr; + + /* Create the module and add the functions */ + m = Py_InitModule("cantera", ct_methods); + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + ErrorObject = PyErr_NewException("cantera.error", NULL, NULL); + PyDict_SetItemString(d, "error", ErrorObject); + } + +} diff --git a/Cantera/python/tutorial/tut1.py b/Cantera/python/tutorial/tut1.py new file mode 100755 index 000000000..939292f6d --- /dev/null +++ b/Cantera/python/tutorial/tut1.py @@ -0,0 +1,172 @@ +################################################################# +# +# Getting started +# +################################################################### + + +# Start Python, and at the prompt type: +from Cantera import * + +# This statement imports the most commonly-used components of Cantera. + +# Now type +gas1 = GRI30() +print gas1 + +# If you have successfully installed the Cantera package, +# you should see something like this: +# +# +# temperature 300 K +# pressure 101325 Pa +# density 0.081896 kg/m^3 +# mean mol. weight 2.01594 amu +# +# X Y +# ------------- ------------ +# H2 1.000000e+000 1.000000e+000 +# +# +# What you have just done is to create an object ("gas1") that +# implements GRI-Mech 3.0, the 53-species, 325-reaction natural gas +# combustion mechanism developed by Gregory P. Smith, David M. Golden, +# Michael Frenklach, Nigel W. Moriarty, Boris Eiteneer, Mikhail +# Goldenberg, C. Thomas Bowman, Ronald K. Hanson, Soonho Song, William +# C. Gardiner, Jr., Vitali V. Lissianski, and Zhiwei Qin. See +# http://www.me.berkeley.edu/gri_mech/ for more information. +# +# The object created by GI30() has properties you would expect for a gas +# mixture - it has a temperature, a pressure, species mole and mass +# fractions, etc. As we'll soon see, it has many more properties. +# +# The summary of the state of 'gas1' printed above shows that new +# objects created by function GRI30() start out with a temperature of +# 300 K, a pressure of 1 atm, and have a composition that consists of +# only one species, in this case hydrogen. There is nothing special +# about H2 - it just happens to be the first species listed in the +# input file defining GRI-Mech 3.0 that the 'GRI30' function reads. In +# general, whichever species is listed first will initially have a +# mole fraction of 1.0, and all of the others will be zero. + +# The printed summary only shows those species with non-zero mole +# fractions, so only H2 is shown, and the 52 other species are not +# listed. (More precisely, only species with mole fractions above a +# threshold value of 1.E-20 are shown.) + + +# Setting the state +# ----------------- + +# The state of the object can easily be changed. For example, + +gas1.setTemperature(1200) + +# sets the temperature to 1200 K. (Cantera always uses SI units.) +# After this statement, + +print gas1 + +# results in: +# +# temperature 1200 K +# pressure 405300 Pa +# density 0.081896 kg/m^3 +# mean mol. weight 2.01594 amu +# +# X Y +# ------------- ------------ +# H2 1.000000e+000 1.000000e+000 +# +# Notice that the temperature has been changed as requested, but the +# pressure has changed too. The density and composition have +# not. +# +# When setting properties individually, some convention needs to be +# adopted to specify which other properties are held constant. This is +# because thermodynamics requires that *two* properties (not one) in +# addition to composition information be specified to fix the +# intensive state of a substance (or mixture). +# +# Cantera adopts the following convention: only one of the set +# (temperature, density, mass fractions) is altered by setting any +# single property. In particular: +# +# a) Setting the temperature is done holding density and +# composition fixed. (The pressure changes.) + +# b) Setting the pressure is done holding temperature and +# composition fixed. (The density changes.) +# +# c) Setting the composition is done holding temperature +# and density fixed. (The pressure changes). +# + + +# Setting multiple properties +# --------------------------------------------------- + +# If you want to set multiple properties at once, use the 'set' function: + +set(gas1, Temperature = 900.0, Pressure = 1.e5) + +# This statement sets both temperature and pressure at the same +# time. Any number of property/value pairs can be specified in a +# call to 'set'. For example, the following sets the mole fractions +# too: + +set(gas1, Temperature = 900.0, Pressure = 1.e5, + MoleFractions = 'CH4:1,O2:2,N2:7.52') + +# The 'set' function also accepts abbreviated property names: + +set(gas1,T = 900.0, P = 1.e5, X = 'CH4:1,O2:2,N2:7.52') + +# Either version results in +# +# temperature 900 K +# pressure 100000 Pa +# density 0.3693 kg/m^3 +# mean mol. weight 27.6332 amu +# +# X Y +# ------------- ------------ +# O2 1.901141e-001 2.201489e-001 +# CH4 9.505703e-002 5.518732e-002 +# N2 7.148289e-001 7.246638e-001 +# + +# Other properties may also be set using 'set', including some that +# can't be set individually. The following property pairs may be +# set: (Enthalpy, Pressure), (IntEnergy, Volume), (Entropy, +# Volume), (Entropy, Pressure). In each case, the values of the +# extensive properties must be entered *per unit mass*. + +# Setting the enthalpy and pressure: +set(gas1, Enthalpy = 2*gas1.enthalpy_mass(), Pressure = 2*OneAtm) + + +# The composition above was specified using a string. The format is a +# comma-separated list of : +# pairs. The mole numbers will be normalized to produce the mole +# fractions, and therefore they are 'relative' mole numbers. Mass +# fractions can be set in this way too by changing 'X' to 'Y' in the +# above statement. + +# The composition can also be set using an array, which must have the +# same size as the number of species. For example, to set all 53 mole +# fractions to the same value, do this: + +x = ones(53,'d'); # NumPy array of 53 ones +set(gas1, X = x) +print gas1 + +# To set the mass fractions to equal values: +set(gas1, Y = x) +print gas1 + + + + + + diff --git a/Cantera/python/tutorial/tut2.py b/Cantera/python/tutorial/tut2.py new file mode 100755 index 000000000..e237fef6e --- /dev/null +++ b/Cantera/python/tutorial/tut2.py @@ -0,0 +1,76 @@ +#################################################################### +# +# Tutorial 2: Using your own reaction mechanism files +# +#################################################################### + +# You can build a gas mixture object by importing element, species, +# and reaction definitions from input files in supported +# formats. Currently, two formats are supported. + +# Importing CK-format files +# ------------------------- + +# By 'CK format', we mean the input file format developed for use +# with the Chemkin-II software package. [See R. J. Kee, +# F. M. Rupley, and J. A. Miller, Sandia National Laboratories +# Report SAND89-8009 (1989).] + +# These files contain no equation of state information, since an +# ideal gas mixture is implicitly assumed. (Chemkin-II does not +# handle non-ideal gases.) Therefore, it is appropriate in Cantera +# to build from them objects that represent ideal gas +# mixtures. This is done using function IdealGasMix: + +from Cantera import * +gas1 = IdealGasMix('mech.inp') + +# This statement creates a mixture that implements GRI-Mech 3.0, +# much like function GRI30 does. File 'gri30.inp' is in the 'data' +# directory. Under Windows, this directory +# +# Cantera always looks in the local directory first, however. So if +# you have a file of the same name in the local directory, +# it will be used instead. + + +# The CK file format specification does not require that all +# species data be contained in the file. Missing species +# definitions (usually called 'thermo' data but in fact defining +# all properties of the species, including name, phase, and +# elemental composition) are to be looked up in a second +# 'thermodynamic database' file. To create the object from an +# incomplete input file, give both file names as arguments: + +gas2 = IdealGasMix('air.inp','nasathermo.dat') + +# The CK file specification does not include transport data for the +# species. These too are taken from an external database. If you +# need transport properties, include the transport file name and +# transport model to implement as follows: + +gas3 = IdealGasMix(src = 'gri30.inp', + transport_db = 'gri30_tran.dat', + transport = 'Multi') + +# Allowable values for the transport model are 'Multi' and +# 'Mix'. If the model is omitted, 'Mix' is assumed. + + +# Importing CTML files +# ------------------- + +# Cantera can also read input files in an XML-based format called +# 'CTML' (Cantera Markup Language). These input files are complete, +# and do not require auxiliary database files for either thermodynamic +# or transport properties. To import a CTML file, simply give the file +# name in the call to IdealGasMix: + +gxml = IdealGasMix('gri30.xml') + +# Cantera determines the file format by examining its contents. A +# conversion utility is available that converts CK-format files into +# CTML. + + + diff --git a/Cantera/python/tutorial/tut4.py b/Cantera/python/tutorial/tut4.py new file mode 100755 index 000000000..6af70cf7a --- /dev/null +++ b/Cantera/python/tutorial/tut4.py @@ -0,0 +1,72 @@ +################################################################# +# +# Tutorial 4: Chemical Equilibrium +# +################################################################# + +# To set a gas mixture to a state of chemical equilibrium, use the +# equilibrate method. +# +from Cantera import * +g = GRI30() +set(g,T=300.0,P=OneAtm,X='CH4:0.95,O2:2,N2:7.52') +g.equilibrate('TP') + +# The above statement sets the state of object 'g' to the state of +# chemical equilibrium holding temperature and pressure +# fixed. Alternatively, the specific enthalpy and pressure can be +# held fixed: + +set(g,T=300.0,P=OneAtm,X='CH4:0.95,O2:2,N2:7.52') +g.equilibrate('HP') + +# Other options are +# 'UV' fixed specific internal energy and specific volume +# 'SV' fixed specific entropy and specific volume +# 'SP' fixed specific entropy and pressure + +set(g,T=300.0,P=OneAtm,X='CH4:0.95,O2:2,N2:7.52') +g.equilibrate('UV') +print g + +set(g,T=300.0,P=OneAtm,X='CH4:0.95,O2:2,N2:7.52') +g.equilibrate('SV') +print g + +set(g,T=300.0,P=OneAtm,X='CH4:0.95,O2:2,N2:7.52') +g.equilibrate('SP') +print g + +# How can you tell if 'equilibrate' has correctly found the +# chemical equilibrium state? One way is verify that the net rates of +# progress of all reversible reactions are zero. + +# Here is the code to do this: +set(g,T=300.0,P=OneAtm,X='CH4:0.95,O2:2,N2:7.52') +g.equilibrate('HP') + +rf = g.fwdRatesOfProgress() +rr = g.revRatesOfProgress() +for i in range(g.nReactions()): + if g.isReversible(i) and rf[i] <> 0.0: + print ' %4i %10.4g %10.4g %10.4g ' % (i, rf[i], rr[i], (rf[i] - rr[i])/rf[i]) + + +# You might be wondering how 'equilibrate' works. (Then again, you might +# not, in which case you can go on to the next tutorial now.) Method +# 'equilibrate' invokes Cantera's chemical equilibrium solver, which +# uses an element potential method. The element potential method is +# one of a class of equivalent 'nonstoichiometric' methods that all +# have the characteristic that the problem reduces to solving a set of +# M nonlinear algebraic equations, where M is the number of elements +# (not species). The so-called 'stoichiometric' methods, on the other +# hand, (including Gibbs minimization), require solving K nonlinear +# equations, where K is the number of species (usually K >> M). See +# Smith and Missen, "Chemical Reaction Equilibrium Analysis" for more +# information on the various algorithms and their characteristics. +# +# Cantera uses a damped Newton method to solve these equations, and +# does a few other things to generate a good starting guess and to +# produce a reasonably robust algorithm. If you want to know more +# about the details, look at the on-line documented source code of +# Cantera C++ class 'ChemEquil.h' at http://www.cantera.org. diff --git a/Cantera/src/.cvsignore b/Cantera/src/.cvsignore new file mode 100644 index 000000000..f3c7a7c5d --- /dev/null +++ b/Cantera/src/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/Cantera/src/Array.h b/Cantera/src/Array.h new file mode 100755 index 000000000..1fbdfd8ea --- /dev/null +++ b/Cantera/src/Array.h @@ -0,0 +1,215 @@ +/** + * @file Array.h + * + * Header file for class Array2D + */ + +/* + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_ARRAY_H +#define CT_ARRAY_H + +#include +#include +using namespace std; + +#include "ct_defs.h" +#include "ctexceptions.h" +#include "stringUtils.h" +#include "utilities.h" + +namespace Cantera { + + + /** + * A class for 2D arrays stored in column-major + * (Fortran-compatible) form. + */ + class Array2D { + + public: + + typedef vector_fp::iterator iterator; + typedef vector_fp::const_iterator const_iterator; + + /** + * Default constructor. Create an empty array. + */ + Array2D() : m_nrows(0), m_ncols(0) { m_data.clear(); } + + + /** + * Constructor. Create an \c m by \c n array, and initialize + * all elements to \c v. + */ + Array2D(int m, int n, doublereal v = 0.0) + : m_nrows(m), m_ncols(n) { + m_data.resize(n*m); + fill(m_data.begin(), m_data.end(), v); + } + + /// copy constructor + Array2D(const Array2D& y) { + m_nrows = y.m_nrows; + m_ncols = y.m_ncols; + m_data.resize(m_nrows*m_ncols); + m_data = y.m_data; + } + + /// assignment operator + Array2D& operator=(const Array2D& y) { + if (&y == this) return *this; + m_nrows = y.m_nrows; + m_ncols = y.m_ncols; + m_data.resize(m_nrows*m_ncols); + m_data = y.m_data; + return *this; + } + + /// resize the array, and fill the new entries with 'v' + void resize(int n, int m, doublereal v = 0.0) { + m_nrows = n; + m_ncols = m; + m_data.resize(n*m, v); + } + + /// append a column + void appendColumn(const vector_fp& c) { + m_ncols++; + m_data.resize(m_nrows*m_ncols); + int m; + for (m = 0; m < m_nrows; m++) value(m_ncols, m) = c[m]; + } + + /// append a column + void appendColumn(doublereal* c) { + m_ncols++; + m_data.resize(m_nrows*m_ncols); + int m; + for (m = 0; m < m_nrows; m++) value(m_ncols, m) = c[m]; + } + + /// set the nth row to array rw + void setRow(int n, doublereal* rw) { + for (int j = 0; j < m_ncols; j++) { + m_data[m_nrows*j + n] = rw[j]; + } + } + + /// get the nth row + void getRow(int n, doublereal* rw) { + for (int j = 0; j < m_ncols; j++) { + rw[j] = m_data[m_nrows*j + n]; + } + } + + /// set the values in column m to those in array col + void setColumn(int m, doublereal* col) { + for (int i = 0; i < m_nrows; i++) { + m_data[m_nrows*m + i] = col[i]; + } + } + + /// get the values in column m + void getColumn(int m, doublereal* col) { + for (int i = 0; i < m_nrows; i++) { + col[i] = m_data[m_nrows*m + i]; + } + } + + /** + * Destructor. Does nothing, since no memory allocated on the + * heap. + */ + virtual ~Array2D(){} + + + /** + * Evaluate a*x + y. + */ + void axpy(doublereal a, const Array2D& x, const Array2D& y) { + const doublereal* xb = x.begin(); + const doublereal* yb = y.begin(); + doublereal* b = begin(); + for (; b != end(); ++b, ++xb, ++yb) *b = a*(*xb) + *yb; + } + + /** + * Allows setting elements using the syntax A(i,j) = x. + */ + doublereal& operator()( int i, int j) { return value(i,j); } + + /** + * Allows retrieving elements using the syntax x = A(i,j). + */ + doublereal operator() ( int i, int j) const {return value(i,j);} + + doublereal& value( int i, int j) {return m_data[m_nrows*j + i];} + doublereal value( int i, int j) const {return m_data[m_nrows*j + i];} + + /// Number of rows + size_t nRows() const { return m_nrows; } + + /// Number of columns + size_t nColumns() const { return m_ncols; } + + /// Return an iterator pointing to the first element + iterator begin() { return m_data.begin(); } + + /// Return an iterator pointing past the last element + iterator end() { return m_data.end(); } + + /// Return a const iterator pointing to the first element + const_iterator begin() const { return m_data.begin(); } + + /// Return a const iterator pointing to past the last element + const_iterator end() const { return m_data.end(); } + + /// Return a reference to the data vector + vector_fp& data() { return m_data; } + + /// Return a const reference to the data vector + const vector_fp& data() const { return m_data; } + + + protected: + + vector_fp m_data; + int m_nrows, m_ncols; + }; + + /// output the array + inline ostream& operator<<(ostream& s, const Array2D& m) { + int nr = m.nRows(); + int nc = m.nColumns(); + int i,j; + for (i = 0; i < nr; i++) { + for (j = 0; j < nc; j++) { + s << m(i,j) << ", "; + } + s << endl; + } + return s; + } + + inline void operator*=(Array2D& m, doublereal a) { + scale(m.begin(), m.end(), m.begin(), a); + } + + inline void operator+=(Array2D& x, const Array2D& y) { + sum_each(x.begin(), x.end(), y.begin()); + } + +} + +#endif + + + diff --git a/Cantera/src/ArrayViewer.h b/Cantera/src/ArrayViewer.h new file mode 100755 index 000000000..906e5a990 --- /dev/null +++ b/Cantera/src/ArrayViewer.h @@ -0,0 +1,144 @@ +/** + * @file Array.h + * + * Header file for class Array2D + * + * $Author$ + * $Revision$ + * $Date$ + * + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_ARRAYVIEWER_H +#define CT_ARRAYVIEWER_H + +#include +#include +using namespace std; + +#include "ct_defs.h" +#include "ctexceptions.h" +#include "stringUtils.h" +#include "utilities.h" + +namespace Cantera { + + + /** + * A class for 2D arrays stored in column-major + * (Fortran-compatible) form. + */ + class ArrayViewer { + + public: + + typedef doublereal* iterator; + typedef const doublereal* const_iterator; + + + /** + * Default constructor. Create an empty array. + */ + ArrayViewer() : m_nrows(0), m_ncols(0) { data = 0; } + + + /** + * Constructor. Create an \c m by \c n array viewer for array v. + */ + ArrayViewer(int m, int n, doublereal* v) + : m_nrows(m), m_ncols(n) { + data = v; + } + + /// resize the array + void resize(int n, int m) { + m_nrows = n; + m_ncols = m; + } + + /// set the nth row to array rw + void setRow(int n, doublereal* rw) { + for (int j = 0; j < m_ncols; j++) { + data[m_nrows*j + n] = rw[j]; + } + } + + /// get the nth row + void getRow(int n, doublereal* rw) { + for (int j = 0; j < m_ncols; j++) { + rw[j] = data[m_nrows*j + n]; + } + } + + /// set the values in column m to those in array col + void setColumn(int m, doublereal* col) { + for (int i = 0; i < m_nrows; i++) { + data[m_nrows*m + i] = col[i]; + } + } + + /// get the values in column m + void getColumn(int m, doublereal* col) { + for (int i = 0; i < m_nrows; i++) { + col[i] = data[m_nrows*m + i]; + } + } + + /// Destructor. Does nothing. + virtual ~ArrayViewer(){} + + doublereal& operator()( int i, int j) {return value(i,j);} + doublereal operator() ( int i, int j) const {return value(i,j);} + + doublereal& value( int i, int j) {return data[m_nrows*j + i];} + doublereal value( int i, int j) const {return data[m_nrows*j + i];} + + /// Number of rows + size_t nRows() const { return m_nrows; } + + /// Number of columns + size_t nColumns() const { return m_ncols; } + + iterator begin() { return data; } + iterator end() { return data + m_nrows*m_ncols; } + const_iterator begin() const { return data; } + const_iterator end() const { return data + m_nrows*m_ncols; } + + doublereal* data; + + protected: + + int m_nrows, m_ncols; + }; + + /// output the array + inline ostream& operator<<(ostream& s, const ArrayViewer& m) { + int nr = m.nRows(); + int nc = m.nColumns(); + int i,j; + for (i = 0; i < nr; i++) { + for (j = 0; j < nc; j++) { + s << m(i,j) << ", "; + } + s << endl; + } + return s; + } + + inline void operator*=(ArrayViewer& m, doublereal a) { + scale(m.begin(), m.end(), m.begin(), a); + } + + inline void operator+=(ArrayViewer& x, const ArrayViewer& y) { + sum_each(x.begin(), x.end(), y.begin()); + } + +} + +#endif + + + diff --git a/Cantera/src/BandMatrix.cpp b/Cantera/src/BandMatrix.cpp new file mode 100755 index 000000000..c6c7b6c30 --- /dev/null +++ b/Cantera/src/BandMatrix.cpp @@ -0,0 +1,225 @@ +/** + * @file BandMatrix.cpp + * + * Banded matrices. + */ + +// Copyright 2001 California Institute of Technology + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + + +#include +#include +using namespace std; + +#include "BandMatrix.h" +#include "ctlapack.h" +#include "utilities.h" +#include "ctexceptions.h" + + +namespace Cantera { + + + /// Default constructor. + BandMatrix::BandMatrix() : m_factored(false), m_n(0), + m_kl(0), m_ku(0), m_zero(0.0) { + data.clear(); ludata.clear(); + } + + + /** + * Constructor. Create an n by n banded matrix. + * @param n number of rows and columns + * @param kl number of subdiagonals + * @param ku number of superdiagonals + * @param v initial value (default = 0.0) + */ + BandMatrix::BandMatrix(int n, int kl, int ku, doublereal v) + : m_factored(false), m_n(n), m_kl(kl), m_ku(ku) { + data.resize(n*(2*kl + ku + 1)); + ludata.resize(n*(2*kl + ku + 1)); + fill(data.begin(), data.end(), v); + fill(ludata.begin(), ludata.end(), 0.0); + m_ipiv.resize(m_n); + } + + /// copy constructor + BandMatrix::BandMatrix(const BandMatrix& y) { + m_n = y.m_n; + m_kl = y.m_kl; + m_ku = y.m_ku; + data = y.data; + ludata = y.ludata; + m_factored = y.m_factored; + m_ipiv = y.m_ipiv; + } + + BandMatrix& BandMatrix::operator=(const BandMatrix& y) { + if (&y == this) return *this; + m_n = y.m_n; + m_kl = y.m_kl; + m_ku = y.m_ku; + m_ipiv = y.m_ipiv; + data = y.data; + ludata = y.ludata; + m_factored = y.m_factored; + return *this; + } + + void BandMatrix::resize(int n, int kl, int ku, doublereal v) { + m_n = n; + m_kl = kl; + m_ku = ku; + data.resize(n*(2*kl + ku + 1)); + ludata.resize(n*(2*kl + ku + 1)); + m_ipiv.resize(m_n); + fill(data.begin(), data.end(), v); + fill(data.begin(), data.end(), 0.0); + m_factored = false; + } + + + /** + * Multiply A*b and write result to \c prod. + */ + void BandMatrix::mult(const double* b, double* prod) const { + int nr = rows(); + int m, j; + double sum = 0.0; + for (m = 0; m < nr; m++) { + sum = 0.0; + for (j = m - m_kl; j <= m + m_ku; j++) { + if (j >= 0 && j < m_n) + sum += _value(m,j)*b[j]; + } + prod[m] = sum; + } + } + + + /** + * Multiply b*A and write result to \c prod. + */ + void BandMatrix::leftMult(const double* b, double* prod) const { + int nc = columns(); + int n, i; + double sum = 0.0; + for (n = 0; n < nc; n++) { + sum = 0.0; + for (i = n - m_ku; i <= n + m_kl; i++) { + if (i >= 0 && i < m_n) + sum += _value(i,n)*b[i]; + } + prod[n] = sum; + } + } + + + /** + * Perform an LU decomposition. LAPACK routine DGBTRF is used. + * The factorization is saved in ludata. + */ + void BandMatrix::factor() { + int info=0; + copy(data.begin(), data.end(), ludata.begin()); + ct_dgbtrf(rows(), columns(), nSubDiagonals(), nSuperDiagonals(), + ludata.begin(), ldim(), ipiv().begin(), info); + + // if info = 0, LU decomp succeeded. + if (info == 0) { + m_factored = true; + } + else { + ofstream fout("bandmatrix.csv"); + fout << *this << endl; + fout.close(); + throw CanteraError("BandMatrix::factor", + "DGBTRF returned info = "+int2str(info)+".\n" + +"Matrix written to file bandmatrix.csv\n"); + } + } + + + /** + * Solve the linear system Ax = b, where A is this matrix. + * Calls LAPACK subroutine DGBTRS. + */ +// void BandMatrix::solve(const vector_fp& b, vector_fp& x) { +// int info = 0; +// copy(b.begin(), b.end(), x.begin()); // b -> x + +// // If the matrix has been modified since the last LU decomposition, +// // then do it now. +// if (!m_factored) factor(); + +// ct_dgbtrs(ctlapack::NoTranspose, columns(), nSubDiagonals(), +// nSuperDiagonals(), 1, ludata.begin(), ldim(), ipiv().begin(), +// x.begin(), columns(), info); + +// // error handling +// if (info != 0) { +// ofstream fout("bandmatrix.csv"); +// fout << *this << endl; +// fout.close(); +// throw CanteraError("BandMatrix::solve", +// "DGBTRS returned info = "+int2str(info)+".\n" +// +"Matrix written to file bandmatrix.csv\n"); +// } +// } + + void BandMatrix::solve(int n, const doublereal* b, doublereal* x) { + copy(b, b+n, x); + solve(n, x); + } + + void BandMatrix::solve(int n, doublereal* b) { + int info = 0; + if (!m_factored) factor(); + ct_dgbtrs(ctlapack::NoTranspose, columns(), nSubDiagonals(), + nSuperDiagonals(), 1, ludata.begin(), ldim(), ipiv().begin(), + b, columns(), info); + + // error handling + if (info != 0) { + ofstream fout("bandmatrix.csv"); + fout << *this << endl; + fout.close(); + throw CanteraError("BandMatrix::solve", + "DGBTRS returned info = "+int2str(info)+".\n" + +"Matrix written to file bandmatrix.csv\n"); + } + } + + ostream& operator<<(ostream& s, const BandMatrix& m) { + int nr = m.rows(); + int nc = m.columns(); + int i,j; + for (i = 0; i < nr; i++) { + s << "Row " << i+1 << ": "; + for (j = 0; j < nc; j++) { + s << m(i,j) << ", "; + } + s << endl << endl; + } + return s; + } + + /** + * Solve Ax = b. Array b is overwritten on exit with x. + */ +// int bsolve(BandMatrix& A, double* b) { +// int info=0; +// A.ludata = A.data; +// ct_dgbsv(A.columns(), A.nSubDiagonals(), A.nSuperDiagonals(), +// 1, A.ludata.begin(), A.ldim(), A.ipiv().begin(), b, +// A.columns(), info); +// A.m_factored = true; +// return info; +// } +} + diff --git a/Cantera/src/BandMatrix.h b/Cantera/src/BandMatrix.h new file mode 100755 index 000000000..dcae05862 --- /dev/null +++ b/Cantera/src/BandMatrix.h @@ -0,0 +1,150 @@ +/** + * @file BandMatrix.h + * + * Banded matrices. + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_BANDMATRIX_H +#define CT_BANDMATRIX_H + +#include +#include +using namespace std; + +#include "ct_defs.h" +#include "ctlapack.h" +#include "utilities.h" +#include "ctexceptions.h" + +namespace Cantera { + + /** + * A class for banded matrices. + */ + class BandMatrix { + + public: + + BandMatrix(); + BandMatrix(int n, int kl, int ku, doublereal v = 0.0); + + /// copy constructor + BandMatrix(const BandMatrix& y); + + /// Destructor. Does nothing. + virtual ~BandMatrix(){} + + /// assignment. + BandMatrix& operator=(const BandMatrix& y); + + void resize(int n, int kl, int ku, doublereal v = 0.0); + + void bfill(doublereal v) { + fill(data.begin(), data.end(), v); + m_factored = false; + } + + doublereal& operator()( int i, int j) { + return value(i,j); + } + + doublereal operator() ( int i, int j) const { + return value(i,j); + } + + doublereal& value( int i, int j) { + m_factored = false; + if (i < j - m_ku || i > j + m_kl) { + m_zero = 0.0; + return m_zero; + } + return data[index(i,j)]; + } + + doublereal value( int i, int j) const { + if (i < j - m_ku || i > j + m_kl) return 0.0; + return data[index(i,j)]; + } + + int index(int i, int j) const { + int rw = m_kl + m_ku + i - j; + return (2*m_kl + m_ku + 1)*j + rw; + } + + doublereal _value(int i, int j) const { + return data[index(i,j)]; + } + + /// Number of rows + int nRows() const { return m_n; } + int rows() const { return m_n; } + + /// Number of columns + int nColumns() const { return m_n; } + int columns() const { return m_n; } + + /// Number of subdiagonals + int nSubDiagonals() const { return m_kl; } + + /// Number of superdiagonals + int nSuperDiagonals() const { return m_ku; } + + int ldim() const { return 2*m_kl + m_ku + 1; } + vector_int& ipiv() { return m_ipiv; } + + /// Multiply A*b and write result to prod. + void mult(const double* b, double* prod) const; + + /// Multiply b*A and write result to prod. + void leftMult(const double* b, double* prod) const; + + void factor(); + + //void solve(const vector_fp& b, vector_fp& x); + + void solve(int n, const doublereal* b, doublereal* x); + void solve(int n, doublereal* b); + + vector_fp::iterator begin() { + m_factored = false; + return data.begin(); + } + vector_fp::iterator end() { + m_factored = false; + return data.end(); + } + vector_fp::const_iterator begin() const { return data.begin(); } + vector_fp::const_iterator end() const { return data.end(); } + + vector_fp data; + vector_fp ludata; + bool m_factored; + + protected: + + int m_n, m_kl, m_ku; + doublereal m_zero; + vector_int m_ipiv; + + }; + + ostream& operator<<(ostream& s, const BandMatrix& m); + + /** + * Solve Ax = b. Array b is overwritten on exit with x. + */ + // int bsolve(BandMatrix& A, double* b); + +} + +#endif + + + diff --git a/Cantera/src/CVode.cpp b/Cantera/src/CVode.cpp new file mode 100755 index 000000000..1911fc2dc --- /dev/null +++ b/Cantera/src/CVode.cpp @@ -0,0 +1,297 @@ +/** + * @file CVode.cpp + * + */ + +// Copyright 2001 California Institute of Technology + +#include "CVode.h" +#include +using namespace std; + + +// cvode includes +#include "../../ext/cvode/include/llnltyps.h" +#include "../../ext/cvode/include/llnlmath.h" +#include "../../ext/cvode/include/cvode.h" +#include "../../ext/cvode/include/cvdense.h" +#include "../../ext/cvode/include/cvdiag.h" +#include "../../ext/cvode/include/cvspgmr.h" +#include "../../ext/cvode/include/nvector.h" +#include "../../ext/cvode/include/cvode.h" + +inline static N_Vector nv(void* x) { + return reinterpret_cast(x); +} + +extern "C" { + + /** + * Function called by cvode to evaluate ydot given y. The cvode + * integrator allows passing in a void* pointer to access + * external data. This pointer is cast to a pointer to a instance + * of class FuncEval. The equations to be integrated should be + * specified by deriving a class from FuncEval that evaluates the + * desired equations. + * @ingroup odeGroup + */ + static void cvode_rhs(integer N, real t, N_Vector y, N_Vector ydot, + void *f_data) { + double* ydata = N_VDATA(y); + double* ydotdata = N_VDATA(ydot); + Cantera::FuncEval* f = (Cantera::FuncEval*)f_data; + f->eval(t, ydata, ydotdata); + } + + + /** + * Function called by cvode to evaluate the Jacobian matrix. + * (temporary) + * @ingroup odeGroup + */ + static void cvode_jac(integer N, DenseMat J, RhsFn f, void *f_data, + real t, N_Vector y, N_Vector fy, N_Vector ewt, real h, real uround, + void *jac_data, long int *nfePtr, N_Vector vtemp1, N_Vector vtemp2, + N_Vector vtemp3) + { + // get pointers to start of data + double* ydata = N_VDATA(y); + double* fydata = N_VDATA(fy); + double* ewtdata = N_VDATA(ewt); + double* ydot = N_VDATA(vtemp1); + + Cantera::FuncEval* func = (Cantera::FuncEval*)f_data; + + int i,j; + double* col_j; + double ysave, dy; + for (j=0; j < N; j++) { + col_j = (J->data)[j]; + ysave = ydata[j]; + dy = 1.0/ewtdata[j]; + ydata[j] = ysave + dy; + dy = ydata[j] - ysave; + func->eval(t, ydata, ydot); + for (i=0; i < N; i++) { + col_j[i] = (ydot[i] - fydata[i])/dy; + } + ydata[j] = ysave; + } + } +} + +namespace Cantera { + + + /** + * Constructor. Default settings: dense jacobian, no user-supplied + * Jacobian function, Newton iteration. + */ + CVodeInt::CVodeInt() : m_neq(0), + m_cvode_mem(0), + m_t0(0.0), + m_y(0), + m_abstol(0), + m_type(DENSE+NOJAC), + m_itol(0), + m_method(BDF), + m_iter(NEWTON), + m_maxord(0), + m_reltol(1.e-9), + m_abstols(1.e-15), + m_nabs(0), + m_hmax(0.0) + { + m_ropt.resize(OPT_SIZE,0.0); + m_iopt = new long[OPT_SIZE]; + fill(m_iopt, m_iopt+OPT_SIZE,0); + } + + + /// Destructor. + CVodeInt::~CVodeInt() + { + if (m_cvode_mem) CVodeFree(m_cvode_mem); + if (m_y) N_VFree(nv(m_y)); + if (m_abstol) N_VFree(nv(m_abstol)); + } + + double& CVodeInt::solution(int k){ return N_VIth(nv(m_y),k); } + double* CVodeInt::solution(){ return N_VDATA(nv(m_y)); } + + void CVodeInt::setTolerances(double reltol, int n, double* abstol) { + m_itol = 1; + m_nabs = n; + if (n != m_neq) { + if (m_abstol) N_VFree(nv(m_abstol)); + m_abstol = reinterpret_cast(N_VNew(n, 0)); + } + for (int i=0; i(N_VNew(m_neq, 0)); // allocate solution vector + + // check abs tolerance array size + if (m_itol == 1 && m_nabs < m_neq) + throw CVodeErr("not enough absolute tolerance values specified."); + + func.getInitialConditions(m_t0, m_neq, N_VDATA(nv(m_y))); + + // set options + m_iopt[MXSTEP] = 20000; + m_iopt[MAXORD] = m_maxord; + m_ropt[HMAX] = m_hmax; + + if (m_cvode_mem) CVodeFree(m_cvode_mem); + + // pass a pointer to func in m_data + m_data = (void*)&func; + + if (m_itol) { + m_cvode_mem = CVodeMalloc(m_neq, cvode_rhs, m_t0, nv(m_y), m_method, + m_iter, m_itol, &m_reltol, + nv(m_abstol), m_data, NULL, TRUE, m_iopt, + m_ropt.begin(), NULL); + } + else { + m_cvode_mem = CVodeMalloc(m_neq, cvode_rhs, m_t0, nv(m_y), m_method, + m_iter, m_itol, &m_reltol, + &m_abstols, m_data, NULL, TRUE, m_iopt, + m_ropt.begin(), NULL); + } + + if (!m_cvode_mem) throw CVodeErr("CVodeMalloc failed."); + + if (m_type == DENSE + NOJAC) { + CVDense(m_cvode_mem, NULL, NULL); + } + else if (m_type == DENSE + JAC) { + CVDense(m_cvode_mem, cvode_jac, NULL); + } + else if (m_type == DIAG) { + CVDiag(m_cvode_mem); + } + else if (m_type == GMRES) { + CVSpgmr(m_cvode_mem, NONE, MODIFIED_GS, 0, 0.0, + NULL, NULL, NULL); + } + else { + throw CVodeErr("unsupported option"); + } + } + + + void CVodeInt::reinitialize(double t0, FuncEval& func) + { + m_t0 = t0; + func.getInitialConditions(m_t0, m_neq, N_VDATA(nv(m_y))); + + // set options + m_iopt[MXSTEP] = 20000; + m_iopt[MAXORD] = m_maxord; + m_ropt[HMAX] = m_hmax; + + //if (m_cvode_mem) CVodeFree(m_cvode_mem); + + // pass a pointer to func in m_data + m_data = (void*)&func; + int result; + if (m_itol) { + result = CVReInit(m_cvode_mem, cvode_rhs, m_t0, nv(m_y), m_method, + m_iter, m_itol, &m_reltol, + nv(m_abstol), m_data, NULL, TRUE, m_iopt, + m_ropt.begin(), NULL); + } + else { + result = CVReInit(m_cvode_mem, cvode_rhs, m_t0, nv(m_y), m_method, + m_iter, m_itol, &m_reltol, + &m_abstols, m_data, NULL, TRUE, m_iopt, + m_ropt.begin(), NULL); + } + + if (result != 0) throw CVodeErr("CVReInit failed."); + + if (m_type == DENSE + NOJAC) { + CVDense(m_cvode_mem, NULL, NULL); + } + else if (m_type == DENSE + JAC) { + CVDense(m_cvode_mem, cvode_jac, NULL); + } + else if (m_type == DIAG) { + CVDiag(m_cvode_mem); + } + else if (m_type == GMRES) { + CVSpgmr(m_cvode_mem, NONE, MODIFIED_GS, 0, 0.0, + NULL, NULL, NULL); + } + else { + throw CVodeErr("unsupported option"); + } + } + + void CVodeInt::integrate(double tout) + { + double t; + int flag; + flag = CVode(m_cvode_mem, tout, nv(m_y), &t, NORMAL); + if (flag != SUCCESS) + throw CVodeErr(" CVode error encountered."); + } + + double CVodeInt::step(double tout) + { + double t; + int flag; + flag = CVode(m_cvode_mem, tout, nv(m_y), &t, ONE_STEP); + if (flag != SUCCESS) + throw CVodeErr(" CVode error encountered."); + return t; + } + + int CVodeInt::nEvals() const { return m_iopt[NFE]; } +} + + + diff --git a/Cantera/src/CVode.h b/Cantera/src/CVode.h new file mode 100755 index 000000000..65cf59465 --- /dev/null +++ b/Cantera/src/CVode.h @@ -0,0 +1,98 @@ +/** + * @file CVode.h + */ + +/* $Author$ + * $Date$ + * $Revision$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_CVODE_H +#define CT_CVODE_H + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "Integrator.h" +#include "FuncEval.h" +#include "ctexceptions.h" +#include "ct_defs.h" + +// cvode includes +//#include "cvode/nvector.h" +//#include "cvode/cvode.h" + + +namespace Cantera { + + /** + * Exception thrown when a CVODE error is encountered. + */ + class CVodeErr : public CanteraError { + public: + CVodeErr(string msg) : CanteraError("CVodeInt", msg){} + }; + + + /** + * Wrapper class for 'cvode' integrator from LLNL. + * The unmodified cvode code is in directory ext/cvode. + * + * @see FuncEval.h. Classes that use CVodeInt: + * ImplicitChem, ImplicitSurfChem, Reactor + * + */ + class CVodeInt : public Integrator { + + public: + + CVodeInt(); + virtual ~CVodeInt(); + virtual void setTolerances(double reltol, int n, double* abstol); + virtual void setTolerances(double reltol, double abstol); + virtual void setProblemType(int probtype); + virtual void initialize(double t0, FuncEval& func); + virtual void reinitialize(double t0, FuncEval& func); + virtual void integrate(double tout); + virtual doublereal step(double tout); + virtual double& solution(int k); + virtual double* solution(); + virtual int nEquations() const { return m_neq;} + virtual int nEvals() const; + virtual void setMaxOrder(int n) { m_maxord = n; } + virtual void setMethod(MethodType t); + virtual void setIterator(IterType t); + virtual void setMaxStep(double hmax); + + private: + + int m_neq; + void* m_cvode_mem; + double m_t0; + void *m_y, *m_abstol; //N_Vector m_y; + //N_Vector m_abstol; + int m_type; + int m_itol; + int m_method; + int m_iter; + int m_maxord; + double m_reltol; + double m_abstols; + int m_nabs; + double m_hmax; + + vector_fp m_ropt; + //vector_int m_iopt; + long int* m_iopt; //[OPT_SIZE]; + //N_Vector m_yprime; + void* m_data; + }; + +} // namespace + +#endif // CT_CVODE diff --git a/Cantera/src/ChemEquil.cpp b/Cantera/src/ChemEquil.cpp new file mode 100755 index 000000000..090edc875 --- /dev/null +++ b/Cantera/src/ChemEquil.cpp @@ -0,0 +1,688 @@ +/** + * + * @file ChemEquil.cpp + * + * Chemical equilibrium. + * Implementation file for class ChemEquil + * + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2001 California Institute of Technology + * + */ + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include +using namespace std; + +#include "ChemEquil.h" +#include "DenseMatrix.h" +#include "recipes.h" +#include "sort.h" +#include "PropertyCalculator.h" +#include "ctexceptions.h" +#include "vec_functions.h" +#include "stringUtils.h" + + +namespace Cantera { + + //----------------------------------------------------------- + // construction / destruction + //----------------------------------------------------------- + + + /// Default Constructor. + ChemEquil::ChemEquil() : m_skip(-1), m_p1(0), m_p2(0), m_p0(OneAtm) + {} + + + /// Destructor + ChemEquil::~ChemEquil(){ + delete m_p1; + delete m_p2; + } + + + /** + * Prepare for equilibrium calculations with a specified + * mixture. + * @param s mixture + */ + void ChemEquil::initialize(thermo_t& s) + { + // store a pointer to s and some of its properties locally + m_thermo = &s; + m_phase = &s; + + m_p0 = s.refPressure(); + m_kk = m_phase->nSpecies(); + m_mm = m_phase->nElements(); + if (m_kk < m_mm) { + throw CanteraError("ChemEquil::initialize", + "number of species cannot be less than the number of elements."); + } + + // allocate space in internal work arrays + m_molefractions.resize(m_kk); + m_lambda.resize(m_mm, -10.0); + m_elementmolefracs.resize(m_mm); + m_comp.resize(m_mm * m_kk); + m_jwork1.resize(m_mm+2); + m_jwork2.resize(m_mm+2); + m_startSoln.resize(m_mm+1); + m_grt.resize(m_kk); + + // set up elemental composition matrix + for (int k = 0; k < m_kk; k++) + for (int m = 0; m < m_mm; m++) + m_comp[k*m_mm + m] = m_phase->nAtoms(k,m); + } + + + /** + * Set mixture to an equilibrium state consistent with specified + * element potentials and temperature. + * + * @param lambda_RT vector of non-dimensional element potentials + * \f[ \lambda_m/RT \f]. + * @param t temperature in K. + * + */ + void ChemEquil::setToEquilState(thermo_t& s, + const vector_fp& lambda_RT, doublereal t) + { + // set the temperature + m_phase->setTemperature(t); + s.setToEquilState(lambda_RT.begin()); + update(s); + } + + + /** + * update internally stored state information. + */ + void ChemEquil::update(const thermo_t& s) { + m_phase->getMoleFractions(m_molefractions.begin()); + m_temp = m_phase->temperature(); + m_dens = m_phase->density(); + + // elemental mole fractions + doublereal sum = 0.0; + int m; + for (m = 0; m < m_mm; m++) { + m_elementmolefracs[m] = 0.0; + for (int k = 0; k < m_kk; k++) { + m_elementmolefracs[m] += nAtoms(k,m) * m_molefractions[k]; + if (nAtoms(k,m) < 0.0) { + throw CanteraError("update","negative nAtoms"); + } + if (m_molefractions[k] < 0.0) { + throw CanteraError("update", + "negative mole fraction for "+m_phase->speciesName(k)+ + ": "+fp2str(m_molefractions[k])); + } + } + sum += m_elementmolefracs[m]; + } + // normalize the element mole fractions + for (m = 0; m < m_mm; m++) m_elementmolefracs[m] /= sum; + } + + + /** + * Estimate the initial mole fractions. Uses the Simplex method + * to estimate the initial number of moles of each species. The + * linear Gibbs minimization problem is solved, neglecting the + * free energy of mixing terms. This procedure produces a good + * estimate of the low-temperature equilibrium composition. + * + * @param s phase object + * @param elementMoles vector of elemental moles + */ + int ChemEquil::setInitialMoles(thermo_t& s, + vector_fp& elementMoles) + { + int m, n; + double pres = s.pressure(); + double lp = log(pres/m_p0); + integer mm = m_phase->nElements(); + integer kksp = m_phase->nSpecies(); + + DenseMatrix aa(mm+2, kksp+1, 0.0); + + // first column contains fixed element moles + for (m = 0; m < mm; m++) { + aa(m+1,0) = elementMoles[m]; + if (elementMoles[m] < 0.0) { + throw CanteraError("setInitialMoles", + "negative element moles for " + +m_phase->elementName(m)+": "+fp2str(elementMoles[m])); + } + } + + + // get the array of non-dimensional Gibbs functions + s.getGibbs_RT(m_grt.begin()); + + int kpp = 0; + for (int k = 0; k < kksp; k++) { + kpp++; + aa(0, kpp) = -m_grt[k]; + aa(0, kpp) -= lp; // ideal gas + for (int q = 0; q < mm; q++) + aa(q+1, kpp) = -nAtoms(k, q); + } + + integer mp = mm+2; // parameters for SIMPLX + integer np = kksp+1; + integer m1 = 0; + integer m2 = 0; + integer m3 = mm; + integer icase=0; + + vector_int iposv(mm); + vector_int izrov(kksp); + + // solve the linear programming problem + + simplx_(&aa(0,0), &mm, &kksp, &mp, &np, &m1, &m2, &m3, + &icase, izrov.begin(), iposv.begin()); + + fill(m_molefractions.begin(), m_molefractions.end(), 0.0); + for (n = 0; n < mm; n++) { + int ksp = 0; + int ip = iposv[n] - 1; + for (int k = 0; k < kksp; k++) { + if (ip == ksp) { + m_molefractions[k] = aa(n+1, 0); + } + ksp++; + } + } + s.setState_PX(pres, m_molefractions.begin()); + update(s); + return icase; + } + + + /** + * Generate a starting estimate for the element potentials. + */ + int ChemEquil::estimateElementPotentials(thermo_t& s, vector_fp& lambda) + { + int k, ksp, m, n; + for (k = 0; k < m_kk; k++) { + if (m_molefractions[k] > 0.0) + m_molefractions[k] = fmaxx(m_molefractions[k], 0.05); + } + s.setState_PX(s.pressure(), m_molefractions.begin()); + + // sort mole fractions + vector_fp mol(m_kk, 0.0); + vector_int index(m_kk, 0); + for (k = 0; k < m_kk; k++) { + mol[k] = m_molefractions[k]; + index[k] = k; + } + heapsort(mol, index); + + DenseMatrix aa(m_mm, m_mm, 0.0); + vector_fp b(m_mm, -999.0); + vector_fp ipvt(m_mm, 0); + + // find a set of constituents + vector_int kc(m_mm, 0); + vector_fp tmp(m_mm, 0.0); + vector_fp mu_RT(m_kk, 0.0); + + s.getChemPotentials(mu_RT.begin()); + doublereal rrt = 1.0/(GasConstant*m_phase->temperature()); + scale(mu_RT.begin(), mu_RT.end(), mu_RT.begin(), rrt); + int j = 0; + for (k = m_kk - 1; k >= 0; k--) { + ksp = index[k]; + if ( mol[k] > 0.0 ) { + kc[j] = ksp; + j++; + if (j == m_mm) break; + } + } + if (j < m_mm) + throw CanteraError("estimateElementPotentials", + "too few species."); + + for (m = 0; m < m_mm; m++) { + for (n = 0; n < m_mm; n++) { + aa(m,n) = nAtoms(kc[m], n); + } + b[m] = mu_RT[kc[m]]; + } + + int info; + try { + info = solve(aa, b.begin()); + } + catch (CanteraError) { + throw CanteraError("estimateElementPotentials","singular matrix."); + } + + if (info == 0) { + for (m = 0; m < m_mm; m++) + lambda[m] = b[m]; + } + return info; + } + + int ChemEquil::equilibrate(thermo_t& s, int XY) { + vector_fp emol(s.nElements()); + initialize(s); + update(s); + copy(m_elementmolefracs.begin(), m_elementmolefracs.end(), + emol.begin()); + return equilibrate(s, XY, emol); + } + + + /** + * compute the equilibrium composition for 2 specified + * properties and specified element moles. + */ + int ChemEquil::equilibrate(thermo_t& s, int XY, vector_fp& elMoles) + { + doublereal xval, yval; + int fail = 0; + + delete m_p1; + delete m_p2; + bool tempFixed = true; + initialize(s); + + switch (XY) { + case TP: case PT: + m_p1 = new TemperatureCalculator; + m_p2 = new PressureCalculator; break; + case HP: case PH: + tempFixed = false; + m_p1 = new EnthalpyCalculator; + m_p2 = new PressureCalculator; break; + case SP: case PS: + tempFixed = false; + m_p1 = new EntropyCalculator; + m_p2 = new PressureCalculator; break; + case SV: case VS: + tempFixed = false; + m_p1 = new EntropyCalculator; + m_p2 = new DensityCalculator; break; + case TV: case VT: + m_p1 = new TemperatureCalculator; + m_p2 = new DensityCalculator; break; + case UV: case VU: + tempFixed = false; + m_p1 = new IntEnergyCalculator; + m_p2 = new DensityCalculator; break; + default: + throw CanteraError("equilibrate","illegal property pair."); // IllegalPropertyPair(XY); + } + + xval = m_p1->value(s); + yval = m_p2->value(s); + + int mm = m_mm; + + int m; + int nvar = mm + 1; + + DenseMatrix jac(nvar, nvar); // jacobian + vector_fp x(nvar, -10.0); // solution vector + + vector_fp res_trial(nvar); + vector_fp elementMol(mm, 0.0); + + double perturb; + for (m = 0; m < mm; m++) { + perturb = Cutoff*(1.0 + rand()); + elementMol[m] = elMoles[m] + perturb; + if (m_skip < 0 && elMoles[m] > 0.0 ) m_skip = m; + } + + update(s); + + // loop to estimate T + if (!tempFixed) { + + doublereal tmax = m_thermo->maxTemp(); + doublereal tmin = m_thermo->minTemp(); + doublereal slope, phigh, plow, pval, dt; + + + // first get the property values at the upper and lower + // temperature limits. Since p1 (h, s, or u) is monotonic + // in T, these values determine the upper and lower + // bounnds (phigh, plow) for p1. + + m_phase->setTemperature(tmax); + setInitialMoles(s, elementMol); + phigh = m_p1->value(s); + + m_phase->setTemperature(tmin); + setInitialMoles(s, elementMol); + plow = m_p1->value(s); + + // start with T at the midpoint of the range + doublereal t0 = 0.5*(tmin + tmax); + m_phase->setTemperature(t0); + + // loop up to 5 times + for (int it = 0; it < 5; it++) { + + // set the composition and get p1 + setInitialMoles(s, elementMol); + pval = m_p1->value(s); + + + // If this value of p1 is greater than the specified + // property value, then the current temperature is too + // high. Use it as the new upper bound. Otherwise, it + // is too low, so use it as the new lower bound. + if (pval > xval) { + tmax = t0; + phigh = pval; + } + else { + tmin = t0; + plow = pval; + } + + // Determine the new T estimate by linearly intepolation + // between the upper and lower bounds + slope = (phigh - plow)/(tmax - tmin); + dt = (xval - plow)/slope; + + // If within 100 K, terminate the search + if (fabs(dt) < 100.0) break; + + // update the T estimate + t0 = tmin + dt; + m_phase->setTemperature(t0); + } + } + + + setInitialMoles(s, elementMol); + + for (int ii = 0; ii < m_mm; ii++) x[ii] = -10.0; + try { + estimateElementPotentials(s, x); + } + catch (CanteraError) { ; } + + x[m_mm] = log(m_phase->temperature()); + + vector_fp above(nvar); + vector_fp below(nvar); + + for (m = 0; m < mm; m++) { + above[m] = 200.0; + below[m] = -2000.0; + if (elMoles[m] < Cutoff) x[m] = -1000.0; + } + above[mm] = log(1.e4); + below[mm] = log(10.0); + + vector_fp grad(nvar, 0.0); // gradient of f = F*F/2 + vector_fp oldx(nvar, 0.0); // old solution + vector_fp prevx(nvar, 0.0); // old solution + vector_fp oldresid(nvar, 0.0); + doublereal f, oldf; + + int iter = 0; + int info=0; + doublereal fctr = 1.0, newval; + + next: + + iter++; + equilResidual(s, x, elMoles, res_trial, XY, xval, yval); + f = 0.5*dot(res_trial.begin(), res_trial.end(), res_trial.begin()); + equilJacobian(s, x, elMoles, jac, XY, xval, yval); + + jac.leftMult(res_trial.begin(), grad.begin()); + copy(x.begin(), x.end(), oldx.begin()); + copy(oldx.begin(), oldx.end(), prevx.begin()); + oldf = f; + scale(res_trial.begin(), res_trial.end(), res_trial.begin(), -1.0); + try { + info = solve(jac, res_trial.begin()); + } + catch (CanteraError) { + throw CanteraError("equilibrate", + "Jacobian is singular. \nTry adding more species, " + "changing the elemental composition slightly, \nor removing " + "unused elements."); + return -3; + } + + fctr = 1.0; + for (m = 0; m < nvar; m++) { + newval = x[m] + res_trial[m]; + if (newval > above[m]) { + fctr = fmaxx( 0.0, fminn( fctr, + 0.8*(above[m] - x[m])/(newval - x[m]))); + } + else if (newval < below[m]) { + fctr = fminn(fctr, 0.8*(x[m] - below[m])/(x[m] - newval)); + } + } + + scale(res_trial.begin(), res_trial.end(), res_trial.begin(), fctr); + + if (!dampStep(s, oldx, oldf, grad, res_trial, + x, f, elMoles , XY, xval, yval)) + { + fail++; + if (fail > 3) { + throw CanteraError("equilibrate", + "Cannot find an acceptable Newton damping coefficient."); + return -4; + } + } + else fail = 0; + + + // check for convergence. + + equilResidual(s, x, elMoles, res_trial, XY, xval, yval); + f = 0.5*dot(res_trial.begin(), res_trial.end(), res_trial.begin()); + doublereal xx, yy, deltax, deltay; + xx = m_p1->value(s); + yy = m_p2->value(s); + deltax = (xx - xval)/xval; + deltay = (yy - yval)/yval; + if (absmax(res_trial.begin(), res_trial.end()) < options.relTolerance + && fabs(deltax) < options.relTolerance + && fabs(deltay) < options.relTolerance) { + options.iterations = iter; + return 0; + } + + // no convergence + + if (iter > options.maxIterations) { + throw CanteraError("equilibrate", + "no convergence in "+int2str(options.maxIterations) + +"iterations."); + return -1; + } + goto next; + } + + + int ChemEquil::dampStep(thermo_t& mix, vector_fp& oldx, + double oldf, vector_fp& grad, vector_fp& step, vector_fp& x, + double& f, vector_fp& elmols, int XY, double xval, double yval ) + { + int nvar = x.size(); + + double slope; + double f2 = 0.0; + double oldf2 = 0.0; + double alpha = 1.e-4; + double tmpdamp = 0.0; + double rhs1; + double rhs2; + double damp = 1.0; + double damp2=0.0; + double a; + double bb; + double disc; + double minDamp = 0.0; + double xTol = 1.e-7; + + vector_fp res_new(nvar); // fix + + //slope = grad * step; + slope = dot(grad.begin(), grad.end(), step.begin()); + double temp, test = 0.0; + + for (int i=0; i test) test = temp; + } + minDamp = xTol/test; + + retry: + + x = step; + scale(x, damp); + add_each(x, oldx); + + + equilResidual(mix, x, elmols, res_new, XY, xval, yval); + //f = 0.5*(res_new*res_new); + f = 0.5*dot(res_new.begin(), res_new.end(), res_new.begin()); + if (damp < minDamp && damp < 1.0) + { + return 0; // check that this is not a spurious min of f + } + else if (f <= oldf + alpha * damp * slope) + { + return 1; // good damping coefficient + } + else + { + if (damp == 1.0) // first time + { + tmpdamp = -slope/(2.0*(f - oldf - slope)); + } + else + { + rhs1 = f - oldf - damp*slope; + rhs2 = f2 - oldf2 - damp2*slope; + a = (rhs1/(damp*damp) - rhs2/(damp2*damp2))/(damp - damp2); + bb = (-damp2*rhs1/(damp*damp) + damp*rhs2/(damp2*damp2)) + /(damp - damp2); + + if (a == 0.0) + tmpdamp = -slope/(2.0*bb); + else + { + disc = bb*bb - 3.0*a*slope; + if (disc < 0.0) + tmpdamp = -slope/(2.0*bb); + else + tmpdamp = (-bb +sqrt(disc))/(3.0*a); + } + if (tmpdamp > 0.5*damp) tmpdamp = 0.5*damp; + } + + damp2 = damp; + f2 = f; + oldf2 = oldf; + damp = fmaxx(tmpdamp, 0.1*damp); + goto retry; + } + } + + + /** + * evaluates the residual vector F, of length mm + */ + void ChemEquil::equilResidual(thermo_t& mix, const vector_fp& x, + const vector_fp& elmtotal, vector_fp& resid, + int XY, doublereal xval, doublereal yval) + { + int n; + doublereal xx, yy; + doublereal temp = exp(x[m_mm]); + setToEquilState(mix, x, temp); + + // residuals are the total element moles + vector_fp& elm = m_elementmolefracs; + for (n=0; n < m_mm; n++) + { + // drive element potential for absent elements to -1000 + if (elmtotal[n] < Cutoff) + resid[n] = x[n] + 1000.0; + else + resid[n] = log( (1.0 + elmtotal[n]) / (1.0 + elm[n]) ); + } + xx = m_p1->value(mix); + yy = m_p2->value(mix); + resid[m_mm] = xx/xval - 1.0; + resid[m_skip] = yy/yval - 1.0; + } + + + //-------------------- Jacobian evaluation --------------------------- + + void ChemEquil::equilJacobian(thermo_t& mix, vector_fp& x, + const vector_fp& elmols, DenseMatrix& jac, + int XY, doublereal xval, doublereal yval) + { + int len = x.size(); + vector_fp& r0 = m_jwork1; + vector_fp& r1 = m_jwork2; + r0.resize(len); + r1.resize(len); + + int n, m; + doublereal rdx, dx, xsave; + doublereal atol = 1.e-7; + + equilResidual(mix, x, elmols, r0, XY, xval, yval); + + for (n = 0; n < len; n++) + { + // perturb x(n) + + xsave = x[n]; + dx = atol; + x[n] = xsave + dx; + dx = x[n] - xsave; + rdx = 1.0/dx; + + // calculate perturbed residual + + equilResidual(mix, x, elmols, r1, XY, xval, yval); + + // compute nth column of Jacobian + + for (m = 0; m < len; m++) { + jac(m, n) = (r1[m] - r0[m])*rdx; + } + x[n] = xsave; + } + } + +} // namespace + + +// $Log: ChemEquil.cpp,v diff --git a/Cantera/src/ChemEquil.h b/Cantera/src/ChemEquil.h new file mode 100755 index 000000000..c55e24b82 --- /dev/null +++ b/Cantera/src/ChemEquil.h @@ -0,0 +1,192 @@ +/** + * @file ChemEquil.h + * + * Chemical equilibrium. + * + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2001 California Institute of Technology + * + */ + + +#ifndef CT_CHEM_EQUIL_H +#define CT_CHEM_EQUIL_H + + +// STL includes +#include +#include +using namespace std; + + +// Cantera includes +#include "ct_defs.h" +#include "vec_functions.h" +#include "ctexceptions.h" +#include "Thermo.h" +#include "PropertyCalculator.h" +#include "DenseMatrix.h" + +namespace Cantera { + + /** + * Chemical equilibrium options. Used internally by class ChemEquil. + */ + class EquilOpt { + public: + EquilOpt() : relTolerance(1.e-9), maxIterations(1000), iterations(0), + maxStepSize(10.0), propertyPair(TP), contin(false) {} + + doublereal relTolerance; ///< Relative tolerance + int maxIterations; ///< Maximum number of iterations + int iterations; ///< Iteration counter + + /** + * Maximum step size. Largest change in any element potential or + * in log(T) allowed in one Newton step. Default: 10.0 + */ + doublereal maxStepSize; + + /** + * Property pair flag. Determines which two thermodynamic properties + * are fixed. + */ + int propertyPair; + + /** + * Continuation flag. Set true if the calculation should be + * initialized from the last calculation. Otherwise, the + * calculation will be started from scratch and the initial + * composition and element potentials estimated. (Not Implemented.) + */ + bool contin; + }; + + + + /** + * Chemical equilibrium processor. Sets a mixture to a state of + * chemical equilibrium. + */ + class ChemEquil { + + public: + ChemEquil(); + virtual ~ChemEquil(); + + int equilibrate(thermo_t& s, int XY = 0); + int equilibrate(thermo_t& s, int XY, vector_fp& elMoles); + + /** + * Options controlling how the calculation is carried out. + * @see EquilOptions + */ + EquilOpt options; + + + protected: + + thermo_t* m_phase; + thermo_t* m_thermo; + + /// number of atoms of element m in species k. + doublereal nAtoms(int k, int m) const { return m_comp[k*m_mm + m]; } + + void initialize(thermo_t& s); + + void setToEquilState(thermo_t& s, + const vector_fp& x, doublereal t); + + int setInitialMoles(thermo_t& s, vector_fp& elementMoles); + + int estimateElementPotentials(thermo_t& s, + vector_fp& lambda); + + int dampStep(thermo_t& s, vector_fp& oldx, + double oldf, vector_fp& grad, vector_fp& step, vector_fp& x, + double& f, vector_fp& elmols, int XY, double xval, double yval ); + + void equilResidual(thermo_t& s, const vector_fp& x, + const vector_fp& elmtotal, vector_fp& resid, + int XY, double xval, double yval); + + void equilJacobian(thermo_t& s, vector_fp& x, + const vector_fp& elmols, DenseMatrix& jac, + int XY, double xval, double yval); + + void update(const thermo_t& s); + + int m_mm; + int m_kk; + int m_skip; + + PropertyCalculator *m_p1, *m_p2; + + vector_fp m_molefractions; + vector_fp m_lambda; + vector_fp m_elementmolefracs; + vector_fp m_reswork; + vector_fp m_jwork1; + vector_fp m_jwork2; + vector_fp m_comp; + doublereal m_temp, m_dens; + doublereal m_p0; + + doublereal m_startTemp, m_startDens; + vector_fp m_startSoln; + + vector_fp m_grt; + }; + + + //----------------------------------------------------------- + // exceptions + //----------------------------------------------------------- + +// class ChemEquilError : public CanteraError { +// public: +// ChemEquilError(string msg = "") { +// if (msg == "") +// m_msg += "Exception thrown in class ChemEquil.\n"; +// else +// m_msg += msg; +// } +// }; + + +// class IllegalPropertyPair : public ChemEquilError { +// public: +// IllegalPropertyPair(int XY) { +// m_msg += "Illegal property pair flag: " + int2str(XY) + "\n"; +// } +// }; + + + //----------------------------------------------------------- + // convenience functions + //----------------------------------------------------------- + + /** + * Set a mixture to a state of chemical equilibrium. The flag 'XY' + * determines the two properties that will be held fixed in the + * calculation. + */ + inline void equilibrate(thermo_t& s, int XY) { + ChemEquil e; + //try { + int istatus = e.equilibrate(s,XY); + //} + //catch (CanteraError) { + //throw CanteraError("equilibrate", + // "equilibrium error "); + //} + } + +} + + +#endif + diff --git a/Cantera/src/ConstDensityThermo.cpp b/Cantera/src/ConstDensityThermo.cpp new file mode 100755 index 000000000..6d0e3e547 --- /dev/null +++ b/Cantera/src/ConstDensityThermo.cpp @@ -0,0 +1,102 @@ +/** + * + * @file ConstDensityThermo.cpp + * + */ + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "ct_defs.h" +#include "mix_defs.h" +#include "ConstDensityThermo.h" +#include "SpeciesThermo.h" + +namespace Cantera { + + void ConstDensityThermo::getChemPotentials(doublereal* mu) const { + doublereal vdp = (pressure() - m_spthermo->refPressure())/ + molarDensity(); + doublereal xx; + doublereal rt = temperature() * GasConstant; + const array_fp& g_RT = gibbs_RT(); + for (int k = 0; k < m_kk; k++) { + xx = fmaxx(SmallNumber, moleFraction(k)); + mu[k] = rt*(g_RT[k] + log(xx)) + vdp; + } + } + + void ConstDensityThermo::initThermo() { + m_kk = nSpecies(); + m_mm = nElements(); + doublereal tmin = m_spthermo->minTemp(); + doublereal tmax = m_spthermo->maxTemp(); + if (tmin > 0.0) m_tmin = tmin; + if (tmax > 0.0) m_tmax = tmax; + m_p0 = refPressure(); + + int leng = m_kk; + m_h0_RT.resize(leng); + m_g0_RT.resize(leng); + m_expg0_RT.resize(leng); + m_cp0_R.resize(leng); + m_s0_R.resize(leng); + m_pe.resize(leng, 0.0); + m_pp.resize(leng); + } + + + /** + * Set mixture to an equilibrium state consistent with specified + * element potentials and temperature. + * + * @param lambda_RT vector of non-dimensional element potentials + * \f[ \lambda_m/RT \f]. + * @param t temperature in K. + * @param work. Temporary work space. Must be dimensioned at least + * as large as the number of species. + * + */ + void ConstDensityThermo::setToEquilState(const doublereal* lambda_RT) + { + throw CanteraError("setToEquilState","not yet impl."); + //const array_fp& grt = gibbs_RT(); + + // set the pressure and composition to be consistent with + // the temperature, + // doublereal pres = 0.0; +// for (int k = 0; k < m_kk; k++) { +// m_pp[k] = -grt[k]; +// for (int m = 0; m < m_mm; m++) +// m_pp[k] += phase().nAtoms(k,m)*lambda_RT[m]; +// m_pp[k] = m_p0 * exp(m_pp[k]); +// pres += m_pp[k]; +// } +// // set state +// setState_PX(pres, m_pp.begin()); + } + + void ConstDensityThermo::_updateThermo() const { + doublereal tnow = temperature(); + if (m_tlast != tnow) { + m_spthermo->update(tnow, m_cp0_R.begin(), m_h0_RT.begin(), + m_s0_R.begin()); + m_tlast = tnow; + doublereal rrt = 1.0 / (GasConstant * tnow); + int k; + doublereal deltaE; + for (k = 0; k < m_kk; k++) { + deltaE = rrt * m_pe[k]; + m_h0_RT[k] += deltaE; + m_g0_RT[k] = m_h0_RT[k] - m_s0_R[k]; + } + m_tlast = tnow; + } + } +} + + + + diff --git a/Cantera/src/ConstDensityThermo.h b/Cantera/src/ConstDensityThermo.h new file mode 100755 index 000000000..4aa0a0ac7 --- /dev/null +++ b/Cantera/src/ConstDensityThermo.h @@ -0,0 +1,196 @@ +/** + * + * @file ConstDensityThermo.h + * + * Thermo manager for incompressible substances. + + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2002 California Institute of Technology + * + */ + +#ifndef CT_CONSTRHOTHERMO_H +#define CT_CONSTRHOTHERMO_H + +#include "ct_defs.h" +#include "mix_defs.h" +#include "Thermo.h" +#include "SpeciesThermo.h" + +namespace Cantera { + + /** + * Overloads the virtual methods of class Thermo to implement the + * incompressible equation of state. + */ + class ConstDensityThermo : public ThermoPhase { + + public: + + ConstDensityThermo() : m_tlast(0.0) {} + + virtual ~ConstDensityThermo() {} + + virtual int eosType() const { return cIncompressible; } + + virtual doublereal enthalpy_mole() const { + doublereal p0 = m_spthermo->refPressure(); + return GasConstant * temperature() * + mean_X(enthalpy_RT().begin()) + + (pressure() - p0)/molarDensity(); + } + + virtual doublereal intEnergy_mole() const { + doublereal p0 = m_spthermo->refPressure(); + return GasConstant * temperature() * + mean_X(enthalpy_RT().begin()) + - p0/molarDensity(); + } + + virtual doublereal entropy_mole() const { + return GasConstant * (mean_X(entropy_R().begin()) - + sum_xlogx()); + } + + virtual doublereal gibbs_mole() const { + return enthalpy_mole() - temperature() * entropy_mole(); + } + + virtual doublereal cp_mole() const { + return GasConstant * mean_X(cp_R().begin()); + } + + virtual doublereal cv_mole() const { + return cp_mole(); + } + + virtual doublereal pressure() const { + return m_press; + } + + virtual void setPressure(doublereal p) { + m_press = p; + } + + virtual void getChemPotentials(doublereal* mu) const; + +// virtual void getPartialMolarEnthalpies(doublereal* hbar) const { +// const array_fp& _h = enthalpy_RT(); +// doublereal rt = GasConstant * _temp(); +// scale(_h.begin(), _h.end(), hbar, rt); +// } + + //virtual void getPartialMolarEntropies(doublereal* sbar) const { + // err("getPartialMolarEntropies"); + //} + + //virtual void getPartialMolarVolumes(doublereal* vbar) const { + // err("getPartialMolarVolumes"); + //} + + virtual void getPureGibbs(doublereal* gpure) const { + const array_fp& gibbsrt = gibbs_RT(); + scale(gibbsrt.begin(), gibbsrt.end(), gpure, _RT()); + } + + void getEnthalpy_RT(doublereal* hrt) const { + const array_fp& _h = enthalpy_RT(); + copy(_h.begin(), _h.end(), hrt); + } + + void getEntropy_R(doublereal* sr) const { + const array_fp& _s = entropy_R(); + copy(_s.begin(), _s.end(), sr); + } + + virtual void getGibbs_RT(doublereal* grt) const { + const array_fp& gibbsrt = gibbs_RT(); + copy(gibbsrt.begin(), gibbsrt.end(), grt); + } + + void getCp_R(doublereal* cpr) const { + const array_fp& _cpr = cp_R(); + copy(_cpr.begin(), _cpr.end(), cpr); + } + + + // new methods defined here + + const array_fp& enthalpy_RT() const { + _updateThermo(); + return m_h0_RT; + } + + const array_fp& gibbs_RT() const { + _updateThermo(); + return m_g0_RT; + } + + const array_fp& expGibbs_RT() const { + _updateThermo(); + int k; + for (k = 0; k != m_kk; k++) m_expg0_RT[k] = exp(m_g0_RT[k]); + return m_expg0_RT; + } + + const array_fp& entropy_R() const { + _updateThermo(); + return m_s0_R; + } + + const array_fp& cp_R() const { + _updateThermo(); + return m_cp0_R; + } + + virtual void setPotentialEnergy(int k, doublereal pe) { + m_pe[k] = pe; + } + + virtual doublereal potentialEnergy(int k) const { + return m_pe[k]; + } + + virtual void initThermo(); + + + virtual void setToEquilState(const doublereal* lambda_RT); + + // set the density + virtual void setParameters(int n, doublereal* c) { + setDensity(c[0]); + } + + + protected: + + int m_kk, m_mm; + doublereal m_tmin, m_tmax, m_p0; + + mutable doublereal m_tlast; + mutable array_fp m_h0_RT; + mutable array_fp m_cp0_R; + mutable array_fp m_g0_RT; + mutable array_fp m_s0_R; + mutable array_fp m_expg0_RT; + mutable array_fp m_pe; + mutable array_fp m_pp; + + doublereal m_press; + + + private: + + void _updateThermo() const; + }; +} + +#endif + + + + + diff --git a/Cantera/src/Constituents.cpp b/Cantera/src/Constituents.cpp new file mode 100755 index 000000000..e5bbe3040 --- /dev/null +++ b/Cantera/src/Constituents.cpp @@ -0,0 +1,506 @@ +/** + * @file Constituents.cpp. + * Implementation file for class Constituents + */ + +/* $Author$ + * $Date$ + * $Revision$ + * + * $Log$ + * Revision 1.1 2003-04-14 17:57:51 dggoodwin + * Initial revision + * + * Revision 1.21 2002/12/19 15:21:54 dgg + * Changed sense of ptr_Element in constructor. Now default is to create + * independent element set. See comments below. + * + * + */ + +// Copyright 2001 California Institute of Technology + + +#ifdef WIN32 +#pragma warning(disable:4786) +#endif + +#include "Constituents.h" +#include "Elements.h" +#include +using namespace std; + +namespace Cantera { + + class ElementsFrozen : public CanteraError { + public: + ElementsFrozen(string func) + : CanteraError(func, + "elements cannot be added after species.") {} + }; + + /******************************************************************** + * + * Constituents(): + * + * Constructor sets all base variable types to zero. Also, it + * sets the pointer to the Elements object for this object to the + * default value of BaseElements. If the BaseElements Elements + * object doesn't exist, it creates it. + * + * Input + * -------- + * ptr_Elements: If the Constituents object requires a different + * Elements object than the default one, input + * address here. This argument defaults to null, + * in which case the default Elements Object is + * chosen. + */ + + /* + * DGG: I have reversed the role of ptr_Elements. In this version, + * the default is that a new Elements object is created, so this + * Constituents object is independent of any other object. But if + * ptr_Elements is supplied, it will be used. This way, a class + * implementing a multi-phase mixture is responsible for + * maintaining the global elements list for the mixture, and no + * static global element list is required. + */ + Constituents::Constituents(Elements* ptr_Elements) : + m_kk(0), + m_speciesFrozen(false) , + m_Elements(ptr_Elements) + { + /* + * Check to see that m_Elements is non-null. + */ + if (!m_Elements) { + m_Elements = new Elements(); + } + +// /* +// * Check to see if the default Elements Object has been +// * created. If it hasn't, create it. +// */ +// if (Elements::Global_Elements_List.size() == 0) { +// Elements::Global_Elements_List.push_back(new Elements()); +// } +// /* +// * Assign the default Elements object as the +// * Constituents's Elements object +// */ +// m_Elements = Elements::Global_Elements_List[0]; +// } + + /* + * Register subscription to Elements object whether or not we + * created it here. + */ + m_Elements->subscribe(); + } + + /******************************************************************** + * + * ~Constituents(): + * + * Destructor For Constituents class. + * + * When the Elements subscription list hits zero, we delete the + * Elements object from here. + */ + Constituents::~Constituents() + { + int ileft = m_Elements->unsubscribe(); + /* + * Here we may delete Elements Objects or not. Right now, we + * will delete them. We also delete the global pointer entry + * to keep everything consistent. + */ + if (ileft <= 0) { + vector::iterator it; + for (it = Elements::Global_Elements_List.begin(); + it != Elements::Global_Elements_List.end(); ++it) { + if (*it == m_Elements) { + Elements::Global_Elements_List.erase(it); + break; + } + } + delete m_Elements; + } + } + + int Constituents::nElements() const { return m_Elements->nElements(); } + + + /******************************************************************** + * + * atomicWeight + * + * Return the Atomic weight of element m. + * units = Kg / Kmol + */ + doublereal Constituents::atomicWeight(int m) const { + return m_Elements->atomicWeight(m); + } + + /******************************************************************* + * + * atomicWeights() + * + * returns a reference to the vector of atomic weights pertinent + * to this constituents object + * units = kg / Kmol + */ + const vector_fp& Constituents::atomicWeights() const { + return m_Elements->atomicWeights(); + } + +#ifdef INCL_DEPRECATED_METHODS + /******************************************************************** + * element(): + * + * Returns an ElementData struct that contains the parameters for + * element m. + * + * -> Passthrough to the Element lvl. + */ + ElementData Constituents::element(int m) const { + return (m_Elements->element(m)); + } +#endif + + /******************************************************************* + * + * addElement(): + * + * Add an element to the set. + * @param symbol symbol string + * Optional: + * @param weight atomic weight in kg/mol. + * + * + * If weight is not given, then a lookup is performed in the + * element object + * + * -> Passthrough to the Element lvl. + */ + void Constituents:: + addElement(const string& symbol, doublereal weight) + { + m_Elements->addElement(symbol, weight); + } + + void Constituents:: + addElement(const XML_Node& e) + { + m_Elements->addElement(e); + } + + /******************************************************************* + * + * addUniqueElement(): + * + * Add a unique element to the set. A check on the symbol is made + * If the symbol is already an element, then a new element is + * not created. + * + * @param symbol symbol string + * Optional: + * @param weight atomic weight in kg/mol. + * + * If weight is not given, then a lookup is performed in the + * element object + * + * -> Passthrough to the Element lvl. + */ + void Constituents:: + addUniqueElement(const string& symbol, doublereal weight) + { + m_Elements->addUniqueElement(symbol, weight); + } + + void Constituents:: + addUniqueElement(const XML_Node& e) + { + m_Elements->addUniqueElement(e); + } + + /******************************************************************* + * + * freezeElements() + * + * -> Passthrough to the Element lvl. + */ + void Constituents::freezeElements() { + m_Elements->freezeElements(); + } + + /******************************************************************* + * + * elementsFrozen() + * + * -> Passthrough to the Element lvl. + */ + bool Constituents::elementsFrozen() { + return m_Elements->elementsFrozen(); + } + + /******************************************************************* + * + * elementIndex(): + * + * Index of element named \c name. The index is an integer + * assigned to each element in the order it was added, + * beginning with 0 for the first element. If \c name is not + * the name of an element in the set, then the value -1 is + * returned. + * + * + * -> Passthrough to the Element class. + */ + int Constituents::elementIndex(string name) const { + return (m_Elements->elementIndex(name)); + } + + /******************************************************************* + * + * elementName(): + * + * Name of the element with index \c m. @param m Element + * index. If m < 0 or m >= nElements() an exception is thrown. + * + * + * -> Passthrough to the Element lvl. + */ + string Constituents::elementName(int m) const { + return (m_Elements->elementName(m)); + } + + /******************************************************************* + * + * elementNames(): + * + * Returns a read-only reference to the vector of element names. + * @code + * Constituents c; + * ... + * const vector& enames = c.elementNames(); + * int n = enames.size(); + * for (int i = 0; i < n; i++) cout << enames[i] << endl; + * @endcode + * + * + * -> Passthrough to the Element lvl. + */ + const vector& Constituents::elementNames() const { + return m_Elements->elementNames(); + } + + /********************************************************************** + * + * molecularWeight() + * + * Returns the molecular weight of a species given the species index + * + * units = kg / kmol. + */ + doublereal Constituents::molecularWeight(int k) const { + if (k < 0 || k >= nSpecies()) { + throw SpeciesRangeError("Constituents::molecularWeight", + k, nSpecies()); + } + return m_weight[k]; + } + + /********************************************************************** + * + * molecularWeights() + * + * Returns a const reference to the vector of molecular weights + * for all of the species defined in the object. + * + * units = kg / kmol. + */ + const array_fp& Constituents::molecularWeights() const { + return m_weight; + } + + /********************************************************************** + * + * charge(): + * + * Electrical charge of one species k molecule, divided by + * \f$ e = 1.602 \times 10^{-19}\f$ Coulombs. + */ + doublereal Constituents::charge(int k) { + if (k < 0 || k >= nSpecies()) + throw SpeciesRangeError("Constituents::charge", + k, nSpecies()); + return m_speciesCharge[k]; + } + + /********************************************************************** + * + * addSpecies() + * + * Add a species to a Constituents object. Note, no check is made + * as to whether the species has a unique name. + * + * Input + * --------- + * name = string containing the name + * comp[] + * charge = + * weight = weight of the species. Default = 0.0. + * Note, the weight is a bit redundent and potentially + * harmful. If weight is less than or equal to zero, + * the weight is calculated from the element composition + * and it need not be supplied on the command line. + */ + void Constituents:: + addSpecies(const string& name, const doublereal* comp, + doublereal charge, doublereal size) { + m_Elements->freezeElements(); + m_speciesNames.push_back(name); + m_speciesCharge.push_back(charge); + m_speciesSize.push_back(size); + double wt = 0.0; + int m_mm = m_Elements->nElements(); + const vector_fp &aw = m_Elements->atomicWeights(); + for (int m = 0; m < m_mm; m++) { + m_speciesComp.push_back(comp[m]); + wt += comp[m] * aw[m]; + } + m_weight.push_back(wt); + m_kk++; + } + + /********************************************************************** + * + * addUniqueSpecies(): + * + * Add a species to a Constituents object. This routine will + * first check to see if the species is already part of the + * phase. It does this via a string comparison with the + * existing species in the phase. + */ + void Constituents:: + addUniqueSpecies(const string& name, const doublereal* comp, + doublereal charge, doublereal size) { + vector::const_iterator it = m_speciesNames.begin(); + for (int k = 0; k < m_kk; k++) { + if (*it == name) { + /* + * We have found a match. At this point we could do some + * compatibility checks. However, let's just return for the + * moment without specifying any error. + */ + int m_mm = m_Elements->nElements(); + for (int i = 0; i < m_mm; i++) { + if (comp[i] != m_speciesComp[m_kk * m_mm + i]) { + throw CanteraError("addUniqueSpecies", + "Duplicate species have different " + "compositions: " + *it); + } + } + if (charge != m_speciesCharge[m_kk]) { + throw CanteraError("addUniqueSpecies", + "Duplicate species have different " + "charges: " + *it); + } + if (size != m_speciesSize[m_kk]) { + throw CanteraError("addUniqueSpecies", + "Duplicate species have different " + "sizes: " + *it); + } + return; + } + ++it; + } + addSpecies(name, comp, charge, size); + } + + /******************************************************************* + * + * freezeSpecies() + * Set the boolean indicating that we are no longer allowing + * species to be added to the Constituents class object. + */ + void Constituents::freezeSpecies() { + m_speciesFrozen = true; + } + + /********************************************************************** + * + * speciesIndex() + * + * Index of species named \c name. The first species added + * will have index 0, and the last one index nSpecies() - 1. + * + * Note, the [] operator shouldn't be used for map's because it + * creates new entries. Here, we use find() to look up entries. + * + * If name isn't in the list, then a -1 is returned. + */ + int Constituents::speciesIndex(string name) const { + vector::const_iterator it = m_speciesNames.begin(); + for (int k = 0; k < m_kk; k++) { + if (*it == name) { + /* + * We have found a match. + */ + return k; + } + ++it; + } + return -1; + } + + /********************************************************************** + * + * speciesName() + * + * Name of the species with index k + */ + string Constituents::speciesName(int k) const { + if (k < 0 || k >= nSpecies()) + throw SpeciesRangeError("Constituents::speciesName", + k, nSpecies()); + return m_speciesNames[k]; + } + /********************************************************************** + * + * speciesNames() + * + * Return a const reference to the vector of species names + */ + const vector& Constituents::speciesNames() const { + return m_speciesNames; + } + + /********************************************************************** + * + * ready(): + * True if both elements and species have been frozen + */ + bool Constituents::ready() const { + return (m_Elements->elementsFrozen() && m_speciesFrozen); + } + + /********************************************************************** + * + * nAtoms() + * + * Returns the number of atoms of element \c m in species \c k. + */ + doublereal Constituents::nAtoms(int k, int m) const + { + const int m_mm = m_Elements->nElements(); + if (m < 0 || m >=m_mm) + throw ElementRangeError("Constituents::nAtoms",m,nElements()); + if (k < 0 || k >= nSpecies()) + throw SpeciesRangeError("Constituents::nAtoms",k,nSpecies()); + return m_speciesComp[m_mm * k + m]; + } + +} diff --git a/Cantera/src/Constituents.h b/Cantera/src/Constituents.h new file mode 100755 index 000000000..b55ad99f3 --- /dev/null +++ b/Cantera/src/Constituents.h @@ -0,0 +1,264 @@ +/** + * @file Constituents.h + * Header file for class Constituents + * + * $Author$ + * $Date$ + * $Revision$ + * + * $Log$ + * Revision 1.1 2003-04-14 17:57:51 dggoodwin + * Initial revision + * + * Revision 1.24 2002/12/19 15:19:32 dgg + * added log block, replaced include statement for Elements.h with + * forward reference for Elements class + * + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_CONSTIT_H +#define CT_CONSTIT_H + + +#include "ct_defs.h" +using namespace std; + +//#include "Elements.h" +#include "SpeciesThermo.h" +#include "ctexceptions.h" +#include "stringUtils.h" +#include "xml.h" + +namespace Cantera { + + class Elements; + +#ifdef INCL_DEPRECATED_METHODS + + /** + * Structure returned by method species() + * @param name species name + * @param atoms vector of element atom numbers + * @param phase flag specifying phase + * @param charge electric charge + * @param molecularWeight molecular weight + */ + struct SpeciesData { + string name; + vector_fp atoms; + int phase; + doublereal charge; + doublereal molecularWeight; + }; +#endif + + /************** DEFINITIONS OF ERRORS *****************************/ + + class SpeciesRangeError : public CanteraError { + public: + SpeciesRangeError(string func, int k, int kmax) : + CanteraError(func, "Species index " + int2str(k) + + " outside valid range of 0 to " + int2str(kmax-1)) {} + }; + + + /** + * Class Constituents manages a set of elements and species. The + * set of elements must include all those that compose the + * species, but may include additional elements. The species all + * must belong to the same phase. + */ + class Constituents { + + public: + + Constituents(Elements* ptr_Elements = 0); + ~Constituents(); + + /// Atomic weight of element m. + doublereal atomicWeight(int m) const; + /// vector of atomic weights + const array_fp& atomicWeights() const; + /// Number of elements. + int nElements() const; + +#ifdef INCL_DEPRECATED_METHODS + /** + * Returns an ElementData struct that contains the + * parameters for element number m. + */ + ElementData element(int m) const { + return m_Elements->element(m); + } +#endif + /** + * @name Adding Elements and Species + * These methods are used to add new elements or species. + * They are not usually called by user programs. + */ + void addElement(const string& symbol, doublereal weight); + void addElement(const XML_Node& e); + void addUniqueElement(const string& symbol, doublereal weight); + void addUniqueElement(const XML_Node& e); + /** + * Prohibit addition of more elements, and prepare to add + * species. + */ + void freezeElements(); + /// True if freezeElements has been called. + bool elementsFrozen(); + /** + * Index of element named 'name'. The index is an integer + * assigned to each element in the order it was added, + * beginning with 0 for the first element. If 'name' is not + * the name of an element in the set, then the value -1 is + * returned. + */ + int elementIndex(string name) const; + /** + * Name of the element with index m. @param m Element + * index. If m < 0 or m >= nElements() an exception is thrown. + */ + string elementName(int m) const; + /** + * Returns a read-only reference to the vector of element names. + */ + const vector& elementNames() const; + + /** + * Returns the Number of species in the phase + */ + int nSpecies() const { return m_kk; } + /// Molecular weight of species k. + doublereal molecularWeight(int k) const; + /** + * Return a const reference to the vector of molecular weights + * of the species + */ + const array_fp& molecularWeights() const; + + /** + * Electrical charge of one species k molecule, divided by + * \f$ e = 1.602 \times 10^{-19}\f$ Coulombs. + */ + doublereal charge(int k); + /** + * @name Adding Species + * These methods are used to add new species. + * They are not usually called by user programs. + */ + //@{ + /** + * @name Adding Species + * These methods are used to add new species. + * They are not usually called by user programs. + */ + //@{ + void addSpecies(const string& name, const doublereal* comp, + doublereal charge = 0.0, doublereal size = 1.0); + + void addUniqueSpecies(const string& name, const doublereal* comp, + doublereal charge = 0.0, + doublereal size = 1.0); + /** + * Index of species named 'name'. The first species added + * will have index 0, and the last one index nSpecies() - 1. + */ + int speciesIndex(string name) const; + /// Name of the species with index k + string speciesName(int k) const; + /// Return a const referernce to the vector of species names + const vector& speciesNames() const; + /** + * size(): + * This routine returns the size of species k + */ + doublereal size(int k) const { return m_speciesSize[k]; } + +#ifdef INCL_DEPRECATED_METHODS + /** + * Return a SpeciesData structure containing species data. + */ + SpeciesData species(int k) const { + if (k < 0 || k >= nSpecies()) + throw SpeciesRangeError("Constituents::charge",k,nSpecies()); + SpeciesData s; + s.name = m_speciesNames[k]; + s.phase = m_speciesPhase[k]; + int offset = m_mm * k; + s.atoms.resize(m_mm); + for (int m = 0; m < m_mm; m++) { + s.atoms[m] = m_speciesComp[offset + m]; + } + s.charge = m_speciesCharge[k]; + s.molecularWeight = m_weight[k]; + return s; + } +#endif + + /** + * Prohibit addition of more species, and prepare for + * calculations with this set of elements and species. + */ + void freezeSpecies(); + + /// True if freezeSpecies has been called. + bool speciesFrozen() { return m_speciesFrozen; } + + /// Remove all elements and species + void clear(); + + //@} + + /// True if both elements and species have been frozen + bool ready() const; + + /// Number of atoms of element m in species k. + doublereal nAtoms(int k, int m) const; + + /// Copy constructor and assignment operator + Constituents::Constituents(const Constituents& right); + Constituents& operator=(const Constituents& right); + + protected: + + int m_kk; + vector_fp m_weight; + + bool m_speciesFrozen; + + /* + * Pointer to the element object corresponding to this + * phase. Normally, this will be the default Element object + * common to all phases. + */ + Elements * m_Elements; + + vector m_speciesNames; + vector_fp m_speciesComp; + /** + * m_speciesCharge: Vector of species charges + * length = m_kk + */ + vector_fp m_speciesCharge; + /** + * m_speciesSize(): Vector of species sizes. + * length m_kk + * This is used in some equations of state + * which employ the constant partial molar + * volume approximation. It's so fundamental + * we've put it at the Constituents class level + */ + vector_fp m_speciesSize; + + private: + + }; + + +} // namespace + +#endif diff --git a/Cantera/src/DASPK.cpp b/Cantera/src/DASPK.cpp new file mode 100755 index 000000000..9f39a545a --- /dev/null +++ b/Cantera/src/DASPK.cpp @@ -0,0 +1,278 @@ +/** + * @file DASPK.cpp + * + */ + +// Copyright 2001 California Institute of Technology + +// turn off warnings under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "DASPK.h" +#include "ctexceptions.h" +#include "stringUtils.h" + +#include +using namespace std; + +extern "C" { + + typedef void (*ResidFunc)(const doublereal* t, + const doublereal* y, const doublereal* yprime, + const doublereal* cj, doublereal* delta, + integer* ires, doublereal* rpar, integer* ipar); + + typedef void (*JacFunc)(); + typedef void (*PsolFunc)(); + + extern void ddaspk_(ResidFunc res, integer* neq, doublereal* t, + doublereal* y, doublereal* yprime, doublereal* tout, integer* info, + doublereal* rtol, doublereal* atol, integer* idid, doublereal* rwork, + integer* lrw, integer* iwork, integer* liw, doublereal* rpar, + integer* ipar, JacFunc jac, PsolFunc psol); + + + /** + * Function called by DASPK to evaluate the residual. + */ + static void ddaspk_res(const doublereal* t, + const doublereal* y, const doublereal* yprime, + const doublereal* cj, doublereal* delta, + integer* ires, doublereal* rpar, integer* ipar) { + void* hndl = (void*)ipar[0]; + Cantera::ResidEval* f = (Cantera::ResidEval*)hndl; + f->evalResid(*t, y, yprime, delta); + } + + static void ddaspk_jac() {} + static void ddaspk_psol() {} + +} + + +namespace Cantera { + + class DASPKErr : public CanteraError { + public: + DASPKErr(string proc, string msg) + : CanteraError("DASPK::"+proc,msg) {} + virtual ~DASPKErr(){} + }; + + /** + * Constructor. Default settings: dense jacobian, no user-supplied + * Jacobian function, Newton iteration. + */ + DASPK::DASPK(ResidEval& f) : + m_resid(f), + m_idid(0), + m_lrw(0), + m_liw(0), + m_ml(0), + m_mu(0), + m_lenwp(0), + m_ok(false), + m_init(false), + m_time(0.0) + { + m_info.resize(20); + m_neq = f.neq(); + m_rwork.resize(20); // will be reset later + m_iwork.resize(20); // " + m_ipar.resize(2); + m_rpar.resize(2); + m_ipar[0] = integer((void*)(&m_resid)); + setTolerances(1.e-7, 1.e-15); + } + + + /// Destructor. + DASPK::~DASPK(){} + + void DASPK::setTolerances(int nr, double* reltol, int na, double* abstol) { + // scalar tolerances + if (nr == 1 && na == 1) { + setInfo(2,0); + m_rtol.resize(1); + m_rtol[0] = reltol[0]; + m_atol.resize(1); + m_atol[0] = abstol[0]; + } + // vector tolerances + else { + setInfo(2,1); + m_rtol.resize(neq()); + m_atol.resize(neq()); + copy(reltol, reltol + nr, m_rtol.begin()); + copy(abstol, abstol + na, m_atol.begin()); + } + } + + void DASPK::setTolerances(double reltol, double abstol) { + doublereal rtol = reltol; + doublereal atol = abstol; + setTolerances(1, &rtol, 1, &atol); + } + + void DASPK::setJacobian(Jacobian& jac) { + + // No Jacobian evaluation function is supplied, so let DASPK + // compute the Jacobian by numerical finite-difference + if (!jac.supplied()) setInfo(5,0); + else { + setInfo(5,1); + } + + if (jac.isBanded()) { + setInfo(6,1); + setIwork(1, jac.lowerBandWidth()); + setIwork(2, jac.upperBandWidth()); + } + else setInfo(6,0); + } + + void DASPK::setMethod(int methodType) { + if (methodType == cDirect) + setInfo(12,0); + else if (methodType == cKrylov) + setInfo(12,1); + else + throw DASPKErr("setMethod", + "method must be either cDirect " + "or cKrylov"); + } + + void DASPK::setMaxTime(doublereal tmax) { + setInfo(4,1); + setRwork(1,tmax); + } + + void DASPK::setMaxStepSize(doublereal dtmax) { + setInfo(7,1); + setRwork(2,dtmax); + } + + void DASPK::setInitialIntStepSize(doublereal h0) { + setInfo(8,1); + setRwork(3,h0); + } + + void DASPK::setMaxOrder(int n) { + setInfo(9,1); + setIwork(3,n); + } + + void DASPK::estimateInitial_Y_given_Yp() { + setInfo(11,2); + } + + void DASPK::estimateInitial_YaYp_given_Yd( + const vector& vartypes) { + setInfo(11,2); + int m, n = neq(); + int lid = ((info(10) == 0 || info(10) == 2) ? + 41 : 41 + neq()); + if (int(m_iwork.size()) < lid + neq()) + m_iwork.resize(lid + neq()); + for (m = 0; m < n; m++) { + setIwork(lid + m, vartypes[m]); + } + } + + void DASPK::sizeRwork() { + int base; + if (info(12) == 0) { + base = 50 + 9*neq(); + if (info(6) == 0) + base += neq()*neq(); + else { + base += (2*m_ml + m_mu + 1)*neq(); + if (info(5) == 0) + base += 2*(neq()/(m_ml + m_mu + 1) + 1); + } + } + else { + base = 91 + 18*neq() + m_lenwp; + } + if (info(16) == 1) base += neq(); + + /// @todo fix this! + base = 2000000; // tmp + + m_rwork.resize(base, 0.0); + m_lrw = base; + } + + void DASPK::sizeIwork() { + int base; + if (info(12) == 0) { + base = 40 + neq(); + } + else { + base = 40 + m_lenwp; + } + if (info(10) == 1 || info(10) == 3) base += neq(); + if (info(11) == 1 || info(16) == 1) base += neq(); + m_iwork.resize(base); + m_liw = base; + } + + + void DASPK::init(doublereal t0) + { + m_init = true; + m_time = t0; + setInfo(1,0); // tells DASPK to initialize + sizeRwork(); + sizeIwork(); + //m_resid.init(t0); + } + + int DASPK::integrate(doublereal tout) { + if (!m_init) init(0.0); + + doublereal tfinal = tout; + setInfo(3,0); // don't want intermediate output + + ddaspk_(ddaspk_res, &m_neq, &m_time, m_resid.solution(), + m_resid.solution_dot(), &tfinal, m_info.begin(), + m_rtol.begin(), m_atol.begin(), &m_idid, + m_rwork.begin(), &m_lrw, m_iwork.begin(), &m_liw, + m_rpar.begin(), m_ipar.begin(), ddaspk_jac, ddaspk_psol); + + return m_idid; + } + + void DASPK::step(double tout) + { + setInfo(3,1); // do want intermediate output + doublereal tfinal = tout; + // setInfo(3,0); // don't want intermediate output + + ddaspk_(ddaspk_res, &m_neq, &m_time, m_resid.solution(), + m_resid.solution_dot(), &tfinal, m_info.begin(), + m_rtol.begin(), m_atol.begin(), &m_idid, + m_rwork.begin(), &m_lrw, m_iwork.begin(), &m_liw, + m_rpar.begin(), m_ipar.begin(), ddaspk_jac, ddaspk_psol); + if (m_idid < 0) { + throw DASPKErr("step", + "DASPK returned IDID = "+int2str(m_idid)); + m_ok = false; + } + else if (m_idid == 1 || m_idid == 2 || m_idid == 3) { + m_ok = true; + } + else { + m_ok = false; + } + return; + } + + int DASPK::nEvals() const { return iwork(12); } +} + + + diff --git a/Cantera/src/DASPK.h b/Cantera/src/DASPK.h new file mode 100755 index 000000000..b3d31cc73 --- /dev/null +++ b/Cantera/src/DASPK.h @@ -0,0 +1,115 @@ +/** + * + * @file DASPK.h + * + * Header file for class DASPK + * + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2001 California Institute of Technology + * + */ + +#ifndef CT_DASPK_H +#define CT_DASPK_H + +#include + +#include "ct_defs.h" +#include "ResidEval.h" + +namespace Cantera { + + class Jacobian { + public: + Jacobian(){} + virtual ~Jacobian(){} + virtual bool supplied() { return false; } + virtual bool isBanded() { return false; } + virtual int lowerBandWidth() { return 0; } + virtual int upperBandWidth() { return 0; } + }; + + class BandedJac : public Jacobian { + public: + BandedJac(int ml, int mu) { + m_ml = ml; m_mu = mu; + } + virtual bool supplied() { return false; } + virtual bool isBanded() { return true; } + virtual int lowerBandWidth() { return m_ml; } + virtual int upperBandWidth() { return m_mu; } + protected: + int m_ml, m_mu; + }; + + class ResidEval; + + const int cDirect = 0; + const int cKrylov = 1; + + /** + * Wrapper for DASPK 2.0 DAE solver of Petzold et al. + */ + class DASPK { + public: + + DASPK(ResidEval& f); + virtual ~DASPK(); + + integer iwork(int n) const { return m_iwork[n-1];} + doublereal rwork(int n) const { return m_rwork[n-1];} + void setIwork(int n, integer m) { m_iwork[n-1] = m; } + void setRwork(int n, doublereal v) { m_rwork[n-1] = v; } + integer info(int n) { return m_info[n-1]; } + void setInfo(int n, integer m) { m_info[n-1] = m; } + + void setTolerances(int nr, double* reltol, int na, double* abstol); + void setTolerances(double reltol, double abstol); + void setJacobian(Jacobian& jac); + void setMethod(int methodType); + void setMaxTime(doublereal tmax); + void setMaxStepSize(doublereal dtmax); + void setMaxOrder(int n); + void setInitialIntStepSize(doublereal h0); + void estimateInitial_Y_given_Yp(); + void estimateInitial_YaYp_given_Yd(const vector& vartypes); + void sizeRwork(); + void sizeIwork(); + int integrate(doublereal tout); + void step(doublereal tout); + int nEvals() const; + int neq() { return m_resid.neq(); } + void init(doublereal t0); + + protected: + + ResidEval& m_resid; + vector_int m_info; + vector_int m_iwork; + vector_int m_ipar; + + vector_fp m_rwork; + vector_fp m_atol; + vector_fp m_rtol; + vector_fp m_rpar; + + integer m_idid; + integer m_neq; + integer m_lrw; + integer m_liw; + integer m_ml; + integer m_mu; + integer m_lenwp; + + bool m_ok; + bool m_init; + doublereal m_time; + }; + +} + +#endif + diff --git a/Cantera/src/DenseMatrix.cpp b/Cantera/src/DenseMatrix.cpp new file mode 100755 index 000000000..114c33e5d --- /dev/null +++ b/Cantera/src/DenseMatrix.cpp @@ -0,0 +1,148 @@ +/** + * @file DenseMatrix.cpp + */ + +// Copyright 2001 California Institute of Technology + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include +#include +using namespace std; + +#include "ct_defs.h" +#include "ctlapack.h" +#include "utilities.h" +#include "DenseMatrix.h" + +namespace Cantera { + + /// assignment. + DenseMatrix& DenseMatrix::operator=(const DenseMatrix& y) { + if (&y == this) return *this; + Array2D::operator=(y); + m_ipiv = y.ipiv(); + return *this; + } + + void DenseMatrix::resize(int n, int m, doublereal v) { + Array2D::resize(n,m,v); + m_ipiv.resize( max(n,m) ); + } + + void DenseMatrix::mult(const double* b, double* prod) const { + ct_dgemv(ctlapack::ColMajor, ctlapack::NoTranspose, nRows(), + nRows(), 1.0, begin(), nRows(), b, 1, 0.0, prod, 1); + } + + void DenseMatrix::leftMult(const double* b, double* prod) const { + int nc = nColumns(); + int nr = nRows(); + int n, i; + double sum = 0.0; + for (n = 0; n < nc; n++) { + sum = 0.0; + for (i = 0; i < nr; i++) { + sum += value(i,n)*b[i]; + } + prod[n] = sum; + } + } + + /** + * Solve Ax = b. Array b is overwritten on exit with x. + */ + int solve(DenseMatrix& A, double* b) { + int info=0; + ct_dgetrf(A.nRows(), A.nColumns(), A.begin(), A.nRows(), + A.ipiv().begin(), info); + if (info != 0) + throw CanteraError("DenseMatrix::solve", + "DGETRF returned INFO = "+int2str(info)); + ct_dgetrs(ctlapack::NoTranspose, A.nRows(), 1, A.begin(), A.nRows(), + A.ipiv().begin(), b, A.nColumns(), info); + if (info != 0) + throw CanteraError("DenseMatrix::solve", + "DGETRS returned INFO = "+int2str(info)); + return 0; + } + + /** Solve Ax = b for multiple right-hand-side vectors. */ + int solve(DenseMatrix& A, DenseMatrix& b) { + int info=0; + ct_dgetrf(A.nRows(), A.nColumns(), A.begin(), A.nRows(), + A.ipiv().begin(), info); + if (info != 0) + throw CanteraError("DenseMatrix::solve", + "DGETRF returned INFO = "+int2str(info)); + ct_dgetrs(ctlapack::NoTranspose, A.nRows(), b.nColumns(), + A.begin(), A.nRows(), + A.ipiv().begin(), b.begin(), b.nRows(), info); + if (info != 0) + throw CanteraError("DenseMatrix::solve", + "DGETRS returned INFO = "+int2str(info)); + return 0; + } + + + /** @todo fix lwork */ + int leastSquares(DenseMatrix& A, double* b) { + int info = 0; + int rank = 0; + double rcond = -1.0; + // fix this! + int lwork = 6000; // 2*(3*min(m,n) + max(2*min(m,n), max(m,n))); + vector_fp work(lwork); + vector_fp s(min(A.nRows(),A.nColumns())); + ct_dgelss(A.nRows(), A.nColumns(), 1, A.begin(), + A.nRows(), b, A.nColumns(), s.begin(), + rcond, rank, work.begin(), work.size(), info); + if (info != 0) + throw CanteraError("DenseMatrix::leaseSquares", + "DGELSS returned INFO = "+int2str(info)); + return 0; + } + + /** + * Multiply \c A*b and return the result in \c prod. Uses BLAS + * routine DGEMV. + */ + void multiply(const DenseMatrix& A, const double* b, double* prod) { + ct_dgemv(ctlapack::ColMajor, ctlapack::NoTranspose, + A.nRows(), A.nRows(), 1.0, + A.begin(), A.nRows(), b, 1, 0.0, prod, 1); + } + + void increment(const DenseMatrix& A, + const double* b, double* prod) { + ct_dgemv(ctlapack::ColMajor, ctlapack::NoTranspose, + A.nRows(), A.nRows(), 1.0, + A.begin(), A.nRows(), b, 1, 1.0, prod, 1); + } + + + /** + * invert A. A is overwritten with A^-1. + */ + int invert(DenseMatrix& A, int nn) { + integer n = (nn > 0 ? nn : A.nRows()); + int info=0; + ct_dgetrf(n, n, A.begin(), A.nRows(), A.ipiv().begin(), info); + if (info != 0) + throw CanteraError("invert", + "DGETRF returned INFO="+int2str(info)); + + vector_fp work(n); + integer lwork = n; + ct_dgetri(n, A.begin(), A.nRows(), A.ipiv().begin(), + work.begin(), lwork, info); + if (info != 0) + throw CanteraError("invert", + "DGETRI returned INFO="+int2str(info)); + return 0; + } +} + diff --git a/Cantera/src/DenseMatrix.h b/Cantera/src/DenseMatrix.h new file mode 100755 index 000000000..10c4615ce --- /dev/null +++ b/Cantera/src/DenseMatrix.h @@ -0,0 +1,113 @@ +/** + * @file DenseMatrix.h + * + * Dense (not sparse) matrices. + */ + +/* + * $Author$ + * $Date$ + * $Revision$ + * + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_DENSEMATRIX_H +#define CT_DENSEMATRIX_H + +#include +#include +using namespace std; + +#include "ct_defs.h" +//#include "ctlapack.h" +//#include "utilities.h" +#include "Array.h" + +namespace Cantera { + + /** + * A class for full (non-sparse) matrices with Fortran-compatible + * data storage. Adds matrix operations to class Array2D. + */ + class DenseMatrix : public Array2D { + + public: + + DenseMatrix(){} + + /** + * Constructor. Create an \c n by \c m matrix, and initialize + * all elements to \c v. + */ + DenseMatrix(int n, int m, doublereal v = 0.0) : Array2D(n,m,v) { + m_ipiv.resize( max(n, m) ); + } + + /// copy constructor + DenseMatrix(const DenseMatrix& y) : Array2D(y) { + m_ipiv = y.ipiv(); + } + + /// assignment. + DenseMatrix& operator=(const DenseMatrix& y); + + void resize(int n, int m, doublereal v = 0.0); + + /// Destructor. Does nothing. + virtual ~DenseMatrix(){} + + + /** + * Multiply A*b and write result to \c prod. + */ + virtual void mult(const double* b, double* prod) const; + + /** + * Left-multiply the matrix by transpose(b), and write the + * result to prod. + */ + virtual void leftMult(const double* b, double* prod) const; + + vector_int& ipiv() { return m_ipiv; } + const vector_int& ipiv() const { return m_ipiv; } + + protected: + + vector_int m_ipiv; + }; + + + /** + * Solve Ax = b. Array b is overwritten on exit with x. + */ + int solve(DenseMatrix& A, double* b); + + /** Solve Ax = b for multiple right-hand-side vectors. */ + int solve(DenseMatrix& A, DenseMatrix& b); + + /** @todo fix lwork */ + int leastSquares(DenseMatrix& A, double* b); + + /** + * Multiply \c A*b and return the result in \c prod. Uses BLAS + * routine DGEMV. + */ + void multiply(const DenseMatrix& A, const double* b, double* prod); + + void increment(const DenseMatrix& A, + const double* b, double* prod); + + /** + * invert A. A is overwritten with A^-1. + */ + int invert(DenseMatrix& A, int nn=-1); + +} + +#endif + + + diff --git a/Cantera/src/EOS_TPX.h b/Cantera/src/EOS_TPX.h new file mode 100755 index 000000000..3f63b0a27 --- /dev/null +++ b/Cantera/src/EOS_TPX.h @@ -0,0 +1,209 @@ +/** + * @file EOS.h + * + * Declares virtual base class EOS + */ + +// Copyright 2001 California Institute of Technology + +#ifndef CT_EOS_TPX_H +#define CT_EOS_TPX_H + +#include "EOS.h" +#include "../ext/tpx/Sub.h" +#include "../ext/tpx/utils.h" + +namespace Cantera { + + class TPX_Error { + public: + TPX_Error(string proc, int err, int fatal = 1) { + cerr << "Error in EOS_TPX::" << proc << ": " + << tpx::errorMsg(err) << endl; + if (fatal) exit(-1); + } + }; + + + class EOS_TPX : public EOS { + + public: + + EOS_TPX(int subflag, double h0 = 0.0, double s0 = 0.0) { + m_sub = tpx::GetSub(subflag); + m_mw = m_sub->MolWt(); + m_sub->setStdState(h0/m_mw, s0/m_mw); + } + + virtual ~EOS_TPX() { delete m_sub; } + + + /** + * Mixture molar enthalpy. Units: J/mol. + */ + virtual doublereal enthalpy_mole(const State& s, + const vector_fp& h0_RT) const { + m_sub->Set(tpx::TV, s.temperature(), 1.0/s.density()); + return m_sub->h() * m_mw; + } + /** + * Mixture molar internal energy. Units: J/mol. + */ + virtual doublereal intEnergy_mole(const State& s, + const vector_fp& h0_RT) const { + m_sub->Set(tpx::TV, s.temperature(), 1.0/s.density()); + return m_sub->u() * m_mw; + } + + /** + * Mixture molar entropy. Units: J/mol/K. + */ + virtual doublereal entropy_mole(const State& s, + const vector_fp& s0_RT, + doublereal log_Pp_bar = -999.0 ) const { + m_sub->Set(tpx::TV, s.temperature(), 1.0/s.density()); + return m_sub->s() * m_mw; + } + + /** + * Mixture molar Gibbs function. Units: J/mol. + */ + virtual doublereal gibbs_mole(const State& s, + const vector_fp& g0_RT, + doublereal log_Pp_bar = -999.0 ) const { + m_sub->Set(tpx::TV, s.temperature(), 1.0/s.density()); + return m_sub->g() * m_mw; + } + + /** + * Mixture molar heat capacity at constant pressure. + * Units: J/mol/K. + */ + virtual doublereal cp_mole(const State& s, + const vector_fp& cp0_R ) const { + m_sub->Set(tpx::TV, s.temperature(), 1.0/s.density()); + return m_sub->cp() * m_mw; + } + + /** + * Mixture molar heat capacity at constant volume. + * Units: J/mol/K. + */ + virtual doublereal cv_mole(const State& s, + const vector_fp& cp0_R ) const { + m_sub->Set(tpx::TV, s.temperature(), 1.0/s.density()); + return m_sub->cv() * m_mw; + } + + /** + * Mixture molar isothermal compressibility + * \f$ -(1/V)(\partial V/\partial P)_T\f$. Units: 1/Pa. + */ + virtual doublereal compressibility_T(const State& s, + const vector_fp& cp0_R ) const { + m_sub->Set(tpx::TV, s.temperature(), 1.0/s.density()); + return -999.0; + } + + /** + * Mixture molar volumetric thermal expansion coefficient + * \f$ (1/V)(\partial V/\partial T)_P\f$. Units: 1/K. + */ + virtual doublereal thermalExpansionCoeff(const State& s, + const vector_fp& cp0_R ) const { + m_sub->Set(tpx::TV, s.temperature(), 1.0/s.density()); + doublereal beta = m_sub->thermExpCoeff(); + if (m_sub->Error()) + throw TPX_Error("thermalExpansionCoeff", m_sub->Error()); + return beta; + } + + + /** + * Pressure. Units: Pa + */ + virtual doublereal pressure(const State& s) const { + m_sub->Set(tpx::TV, s.temperature(), 1.0/s.density()); + doublereal pp = m_sub->P(); + if (m_sub->Error()) + throw TPX_Error("pressure", m_sub->Error()); + return pp; + } + + + /** + * Set the pressure, holding temperature and composition + * fixed. + * + * @param s State instance defining the thermodynamic state. + * The density attribute of s will be set to a value such that + * the value of pressure() equals p. + * + * @param p Pressure in Pa. + */ + virtual void setPressure(State& s, doublereal p) const { + m_sub->Set(tpx::TP, s.temperature(), p); + s.setDensity(1.0/m_sub->v()); + if (m_sub->Error()) + throw TPX_Error("setPressure", m_sub->Error()); + } + + virtual void getChemPotentials_RT(const State& s, + const vector_fp& g0_RT, const vector_fp& x, + doublereal* mu) const { + m_sub->Set(tpx::TV, s.temperature(), 1.0/s.density()); + mu[0] = gibbs_mole(s, g0_RT); + if (m_sub->Error()) + throw TPX_Error("getChemPotentials_RT", m_sub->Error()); + } + + tpx::Substance& TPX_Substance() { return *m_sub; } + doublereal Tmin() { return m_sub->Tmin(); } + doublereal Tmax() { return m_sub->Tmax(); } + + /// critical state properties + virtual doublereal critTemperature() { return m_sub->Tcrit(); } + virtual doublereal critPressure() { return m_sub->Pcrit(); } + virtual doublereal critDensity() { return 1.0/m_sub->Vcrit(); } + + /// saturation properties + virtual doublereal satTemperature(doublereal p) { + doublereal ts = m_sub->Tsat(p); + if (ts == tpx::Undef) throw TPX_Error("satTemperature",m_sub->Error()); + return ts; + } + virtual doublereal satPressure(doublereal t) { + doublereal tsv = m_sub->Temp(); + doublereal vsv = m_sub->v(); + m_sub->Set(tpx::TP, t, 0.5*m_sub->Pcrit()); + doublereal ps = m_sub->Ps(); + if (ps == tpx::Undef) throw TPX_Error("satPressure",m_sub->Error()); + m_sub->Set(tpx::TV,tsv,vsv); + return ps; + } + + virtual int phase() { + doublereal xx = m_sub->x(); + if (xx > 0.99999) + return Vapor_Phase; + else if (xx < 1.e-5) + return Liquid_Phase; + else + return Liquid_Phase + Vapor_Phase; + } + + + protected: + + tpx::Substance* m_sub; + doublereal m_mw; + }; + +} + +#endif + + + + + diff --git a/Cantera/src/Elements.cpp b/Cantera/src/Elements.cpp new file mode 100644 index 000000000..df509710c --- /dev/null +++ b/Cantera/src/Elements.cpp @@ -0,0 +1,534 @@ +/**************************************************************************** + * $RCSfile$ + * $Author$ + * $Date$ + * $Revision$ + * + * + ****************************************************************************/ +// Copyright 2003 California Institute of Technology + +/** + * @file Elements.cpp + * Implementation file for the class Elements + * + * This file contains the definitions for functions in the class Elements. + * It also contains a database of atomic weights. + */ + +#ifdef WIN32 +#pragma warning(disable:4786) +#endif + +#include "Elements.h" +#include "xml.h" + +#ifdef USE_DGG_CODE +#include +#endif + +namespace Cantera { + + /* awData structure */ + /** + * Database for atomic molecular weights + * + * Values are taken from the 1989 Standard Atomic Weights, CRC + * + * awTable[] is a static function with scope limited to this file. + * It can only be referenced via the static Elements class function, + * LookupWtElements(). + * + * units = kg / kg-mol (or equivalently gm / gm-mol) + * + * (note: this structure was picked because it's simple, compact, + * and extensible). + * + */ + struct awData { + char name[4]; ///< Null Terminated name, First letter capitalized + double atomicWeight; ///< atomic weight in kg / kg-mol + }; + + /*! + * @var static struct awData aWTable[] + * \brief aWTable is a vector containing the atomic weights database. + * + * The size of the table is given by the initial instantiation. + */ + static struct awData aWTable[] = { + {"H", 1.00794}, + {"D", 2.0 }, + {"Tr", 3.0 }, + {"He", 4.002602}, + {"Li", 6.941 }, + {"Be", 9.012182}, + {"B", 10.811 }, + {"C", 12.011 }, + {"N", 14.00674}, + {"O", 15.9994 }, + {"F", 18.9984032}, + {"Ne", 20.1797 }, + {"Na", 22.98977}, + {"Mg", 24.3050 }, + {"Al", 26.98154}, + {"Si", 28.0855 }, + {"P", 30.97376}, + {"S", 32.066 }, + {"Cl", 35.4527 }, + {"Ar", 39.948 }, + {"K", 39.0983 }, + {"Ca", 40.078 }, + {"Sc", 44.95591}, + {"Ti", 47.88 }, + {"V", 50.9415 }, + {"Cr", 51.9961 }, + {"Mn", 54.9381 }, + {"Fe", 55.847 }, + {"Co", 58.9332 }, + {"Ni", 58.69 }, + {"Cu", 63.546 }, + {"Zn", 65.39 }, + {"Ga", 69.723 }, + {"Ge", 72.61 }, + {"As", 74.92159}, + {"Se", 78.96 }, + {"Br", 79.904 }, + {"Kr", 83.80 }, + {"Rb", 85.4678 }, + {"Sr", 87.62 }, + {"Y", 88.90585}, + {"Zr", 91.224 }, + {"Nb", 92.90638}, + {"Mo", 95.94 }, + {"Tc", 97.9072 }, + {"Ru", 101.07 }, + {"Rh", 102.9055 }, + {"Pd", 106.42 }, + {"Ag", 107.8682 }, + {"Cd", 112.411 }, + {"In", 114.82 }, + {"Sn", 118.710 }, + {"Sb", 121.75 }, + {"Te", 127.6 }, + {"I", 126.90447}, + {"Xe", 131.29 }, + {"Cs", 132.90543}, + {"Ba", 137.327 }, + {"La", 138.9055 }, + {"Ce", 140.115 }, + {"Pr", 140.90765}, + {"Nd", 144.24 }, + {"Pm", 144.9127 }, + {"Sm", 150.36 }, + {"Eu", 151.965 }, + {"Gd", 157.25 }, + {"Tb", 158.92534}, + {"Dy", 162.50 }, + {"Ho", 164.93032}, + {"Er", 167.26 }, + {"Tm", 168.93421}, + {"Yb", 173.04 }, + {"Lu", 174.967 }, + {"Hf", 178.49 }, + {"Ta", 180.9479 }, + {"W", 183.85 }, + {"Re", 186.207 }, + {"Os", 190.2 }, + {"Ir", 192.22 }, + {"Pt", 195.08 }, + {"Au", 196.96654}, + {"Hg", 200.59 }, + {"Ti", 204.3833 }, + {"Pb", 207.2 }, + {"Bi", 208.98037}, + {"Po", 208.9824 }, + {"At", 209.9871 }, + {"Rn", 222.0176 }, + {"Fr", 223.0197 }, + {"Ra", 226.0254 }, + {"Ac", 227.0279 }, + {"Th", 232.0381 }, + {"Pa", 231.03588}, + {"U", 238.0508 }, + {"Np", 237.0482 }, + {"Pu", 244.0482 } + }; + + /* LookupWtElements(): */ + /** Static function to look up an atomic weight + * + * This static function looks up the argument string in the + * database above and returns the associated molecular weight. + * The data are from the periodic table. + * + * Note: The idea behind this function is to provide a unified + * source for the element atomic weights. This helps to + * ensure that mass is conserved. + * + * @param + * ElemName String. Only the first 3 characters are significant + * + * @return + * Return value contains the atomic weight of the element + * If a match for the string is not found, a value of -1.0 is + * returned. + * + * @exception CanteraError + * If a match is not found, a CanteraError is thrown as well + */ + double Elements::LookupWtElements(const string& s) { + int num = sizeof(aWTable) / sizeof(struct awData); + string s3 = s.substr(0,3); + for (int i = 0; i < num; i++) { + //if (!std::strncmp(s.c_str(), aWTable[i].name, 3)) { + if (s3 == aWTable[i].name) { + return (aWTable[i].atomicWeight); + } + } + throw CanteraError("LookupWtElements", "element not found"); + return -1.0; + } + + /*! + * Exception class to indicate a fixed set of elements. + * + * This class is used to warn the user when the number of elements + * are changed after at least one species is defined. + */ + class ElementsFrozen : public CanteraError { + public: + ElementsFrozen(string func) + : CanteraError(func, + "elements cannot be added after species.") {} + }; + + /*! + * Elements Class Constructor + * We initialize all internal variables to zero here. + */ + Elements::Elements() : + m_mm(0), + m_elementsFrozen(false), + numSubscribers(0) + { + } + + /*! + * Elements Class Destructor + * If the number of subscribers is not zero, through an error. + * A logic problem has occurred. + * + * @exception CanteraError + */ + Elements::~Elements() + { + if (numSubscribers != 0) { + throw CanteraError("~Elements", "numSubscribers not zero"); + } + } + + /*! + * freezeElements(): + * + * Set the freeze flag. This is a prerequesite to other + * activivities, i.e., this is done before species are defined. + */ + void Elements::freezeElements() { + m_elementsFrozen = true; + } + +#ifdef INCL_DEPRECATED_METHODS + /*! + * + * Returns an ElementData struct that contains the parameters + * for element index m. + */ + ElementData Elements::element(int m) const { + ElementData e; + e.name = m_elementNames[m]; + e.atomicWeight = m_atomicWeights[m]; + return e; + } +#endif + /*********************************************************************** + * elementIndex(): + * + * Index of element named \c name. The index is an integer + * assigned to each element in the order it was added, + * beginning with 0 for the first element. If \c name is not + * the name of an element in the set, then the value -1 is + * returned. + * + */ +#ifdef USE_DGG_CODE + int Elements::elementIndex(string name) const{ + map::const_iterator it; + it = m_definedElements.find(name); + if (it != m_definedElements.end()) { + return it->second; + } + return -1; + } +#else + int Elements::elementIndex(string name) const { + for (int i = 0; i < m_mm; i++) { + if (m_elementNames[i] == name) return i; + } + return -1; + } +#endif + + /*! + * + * Name of the element with index \c m. @param m Element + * index. If m < 0 or m >= nElements() an exception is thrown. + */ + string Elements::elementName(int m) const { + if (m >= 0 && m < nElements()) + return m_elementNames[m]; + else + throw ElementRangeError("Elements::elementName",m,nElements()); + } + + /*! + * + * Add an element to the current set of elements in the current object. + * @param symbol symbol string + * @param weight atomic weight in kg/kmol. + * + * The default weight is a special value, which will cause the + * routine to look up the actual weight via a string lookup. + * + * There are two interfaces to this routine. The XML interface + * looks up the required parameters for the regular interface + * and then calls the base routine. + */ + void Elements:: + addElement(const string& symbol, doublereal weight) + { + if (weight == -12345.0) { + weight = LookupWtElements(symbol); + if (weight < 0.0) { + throw ElementsFrozen("addElement"); + } + } + if (m_elementsFrozen) { + throw ElementsFrozen("addElement"); + return; + } + m_atomicWeights.push_back(weight); + m_elementNames.push_back(symbol); +#ifdef USE_DGG_CODE + m_definedElements[symbol] = nElements() + 1; +#endif + m_mm++; + } + + void Elements:: + addElement(const XML_Node& e) { + doublereal weight = atof(e["atomicWt"].c_str()); + string symbol = e["name"]; + addElement(symbol, weight); + } + + /*********************************************************************** + * addUniqueElement(): + * + * Add a unique element to the set. This routine will not allow + * duplicate elements to be input. + * + * @param symbol symbol string + * @param weight atomic weight in kg/kmol. + * + * + * The default weight is a special value, which will cause the + * routine to look up the actual weight via a string lookup. + */ +#ifdef USE_DGG_CODE + void Elements:: + addUniqueElement(const string& symbol, doublereal weight) + { + if (m_elementsFrozen) + throw ElementsFrozen("addElement"); + + if (weight == -12345.0) { + weight = LookupWtElements(symbol); + } + + /* + * First decide if this element has been previously added. + * If it unique, add it to the list. + */ + + int i = m_definedElements[symbol] - 1; + if (i < 0) { + m_atomicWeights.push_back(weight); + m_elementNames.push_back(symbol); + m_mm++; + } + else { + if (m_atomicWeights[i] != weight) { + throw CanteraError("AddUniqueElement", + "Duplicate Elements (" + symbol + + ") have different weights"); + } + } + } + +#else + void Elements:: + addUniqueElement(const string& symbol, doublereal weight) + { + if (weight == -12345.0) { + weight = LookupWtElements(symbol); + if (weight < 0.0) { + throw ElementsFrozen("addElement"); + } + } + /* + * First decide if this element has been previously added + * by conducting a string search. If it unique, add it to + * the list. + */ + int ifound = 0; + int i = 0; + for (vector::const_iterator it = m_elementNames.begin(); + it < m_elementNames.end(); ++it, ++i) { + if (*it == symbol) { + ifound = 1; + break; + } + } + if (!ifound) { + if (m_elementsFrozen) { + throw ElementsFrozen("addElement"); + return; + } + m_atomicWeights.push_back(weight); + m_elementNames.push_back(symbol); + m_mm++; + } else { + if (m_atomicWeights[i] != weight) { + throw CanteraError("AddUniqueElement", + "Duplicate Elements (" + symbol + + ") have different weights"); + } + } + } +#endif + + + /** + * @todo call addUniqueElement(symbol, weight) instead of + * addElement. + */ + void Elements:: + addUniqueElement(const XML_Node& e) { + doublereal weight = 0.0; + if (e.hasAttrib("atomicWt")) + weight = atof(stripws(e["atomicWt"]).c_str()); + string symbol = e["name"]; + if (weight) + addUniqueElement(symbol, weight); + else + addUniqueElement(symbol); + } + + /*********************************************************************** + * clear() + * + * Remove all elements from the structure. + */ + void Elements::clear() { + m_mm = 0; + m_atomicWeights.resize(0); + m_elementNames.resize(0); + m_elementsFrozen = false; + } + + /*********************************************************************** + * ready(): + * + * True if the elements have been frozen + */ + bool Elements::ready() const { + return (m_elementsFrozen); + } + + /*********************************************************************** + * Elements(const Elements&) - copy constructor: + * + * This copy constructor just calls the assignment operator for this + * class. + */ + Elements::Elements(const Elements& right) + { + *this = right; + /* + * Set the number of subscribers to zero during a copy constructor + */ + numSubscribers = 0; + } + + /*********************************************************************** + * Elements& Elements::operator=(const Elements& right): + * + * (assignment operator) + * + * This is the assignment operator for the Elements class. + * Right now we pretty much do a straight uncomplicated + * assignment. However, subscribers are not mucked with, as they + * have to do with the address of the object to be subscribed to + */ + Elements& Elements::operator=(const Elements& right) + { + /* + * Check for self assignment. + */ + if (this == &right) return *this; + /* + * We do a straight assignment operator on all of the + * data. The vectors are copied. + */ + m_mm = right.m_mm; + m_elementsFrozen = right.m_elementsFrozen; + m_atomicWeights = right.m_atomicWeights; + m_elementNames = right.m_elementNames; + /* + * We must not muck with the number of subscribers to this object + * during a straight assignment. This number was set in the + * constructor operation. + */ + /* + * Return the reference to the current object + */ + return *this; + } + + /*********************************************************************** + * subscribe(), unsubscribe(), and reportSubscriptions(): + * + * Handles setting and reporting the number of subscriptions to this + * object. + */ + void Elements::subscribe() { + ++numSubscribers; + } + int Elements::unsubscribe() { + --numSubscribers; + return numSubscribers; + } + int Elements::reportSubscriptions() const { + return numSubscribers; + } + + /********************* GLOBAL STATIC SECTION **************************/ + /* + * We keep track of a vector of pointers to element objects. + * Initially there are no Elements objects. Whenever one is created, + * the pointer to that object is added onto this list. + */ + vector Elements::Global_Elements_List; + /***********************************************************************/ +} diff --git a/Cantera/src/Elements.h b/Cantera/src/Elements.h new file mode 100644 index 000000000..a40be50db --- /dev/null +++ b/Cantera/src/Elements.h @@ -0,0 +1,218 @@ +/*********************************************************************** + * $RCSfile$ + * $Author$ + * $Date$ + * $Revision$ + ***********************************************************************/ +// Copyright 2001 California Institute of Technology + +/** @file Elements.h + * Header file for class, Elements. + * + * This file contains the declarations for the elements class. + */ + +#ifndef CT_ELEMENTS_H +#define CT_ELEMENTS_H + +#undef USE_DGG_CODE + +#include "ct_defs.h" +#include "ctexceptions.h" + +/*! + * @namespace Cantera + * @brief All of Cantera's global variables exist in this namespace + * + * + */ +namespace Cantera { + + class XML_Node; + +#ifdef INCL_DEPRECATED_METHODS + /** + * Holds element name and atomic weight. Used for output of + * element properties and initial initialization only. + */ + struct ElementData { + string name; + doublereal atomicWeight; + }; +#endif + + class ElementRangeError : public CanteraError { + public: + ElementRangeError(string func, int m, int mmax) : + CanteraError(func, "Element index " + int2str(m) + + " outside valid range of 0 to " + int2str(mmax-1)) {} + }; + + + /** Elements Class: Object contains the elements that make up species. + * + * Class Elements manages the elements that are part of a + * chemistry specification. This class may support calculations + * employing Multiple phases. In this case, a single Elements object may + * be shared by more than one Constituents class. Reactions between + * the phases may then be described using stoichiometry base on the + * same Elements class object. + * + * The member functions return information about the elements described + * in a particular instantiation of the class. + */ + class Elements { + + public: + /// Default constructor for the elements class + Elements(); + ~Elements(); + + static double LookupWtElements(const string &); + + /// Atomic weight of element m. + doublereal atomicWeight(int m) const { return m_atomicWeights[m]; } + + /// vector of element atomic weights + const vector_fp& atomicWeights() const { return m_atomicWeights; } + + /** + * Inline function that returns the number of elements in the object. + * + * @return + * \c int: The number of elements in the object. + */ + int nElements() const { return m_mm; } + +#ifdef INCL_DEPRECATED_METHODS + /// Returns an ElementData struct that contains the parameters + /// for element m. + ElementData element(int m) const; +#endif + /** Function that returns the index of an element. + * + * Index of element named \c name. The index is an integer + * assigned to each element in the order it was added, + * beginning with 0 for the first element. If \c name is not + * the name of an element in the set, then the value -1 is + * returned. + * + * @param name String containing the index. + */ + int elementIndex(string name) const; + + /* + * Name of the element with index \c m. @param m Element 11111 + * index. If m < 0 or m >= nElements() an exception is thrown. + */ + string elementName(int m) const; + + /* elementNames() */ + /** Returns a string vector containing the element names + * + * Returns a read-only reference to the vector of element names. + * @return const vector& : The vector contains + * the element names in their indexed order. + */ + const vector& elementNames() const { + return m_elementNames; + } + + /// Add an element. + void addElement(const string& symbol, + doublereal weight = -12345.0); + void addElement(const XML_Node& e); + + /* + * Add an element only if the element hasn't been added before. + * This is accomplished via a string match on symbol. + */ + void addUniqueElement(const string& symbol, + doublereal weight = -12345.0); + void addUniqueElement(const XML_Node& e); + + /** + * Prohibit addition of more elements, and prepare to add + * species. + */ + void freezeElements(); + + /// True if freezeElements has been called. + bool elementsFrozen() { return m_elementsFrozen; } + + /// Remove all elements + void clear(); + + /// True if both elements and species have been frozen + bool ready() const; + + Elements(const Elements& right); + Elements& operator=(const Elements& right); + + + void subscribe(); + int unsubscribe(); + int reportSubscriptions() const; + + protected: + + /******************************************************************/ + /* Description of DATA in the Object */ + /******************************************************************/ + /* n_mm: */ + /** Number of elements. + * + */ + int m_mm; + + /* m_elementsFrozen: */ + /** boolean indicating completion of object + * + * If this is true, then no elements may be added to the + * object. + */ + bool m_elementsFrozen; + + /** + * Vector of element atomic weights: + * + * units = kg / kmol + */ + vector_fp m_atomicWeights; + + /** Vector of strings containing the names of the elements + * + * Note, a string search is the primary way to identify elements. + */ + vector m_elementNames; +#ifdef USE_DGG_CODE + /** + * Map of elements to indecises + * + * NOTE: this is redundent + */ + map m_definedElements; +#endif + /** + * Number of Constituents Objects that use this object + * + * Number of Constituents Objects that require this Elements object + * to complete its definition. + * The destructor checks to see that this is equal to zero. + * when the element object is released. + */ + int numSubscribers; + + /********* GLOBAL STATIC SECTION *************/ + + public: + /** Vector of pointers to Elements Objects + * + */ + static vector Global_Elements_List; + + }; + +} // namespace + +#endif diff --git a/Cantera/src/Enhanced3BConc.h b/Cantera/src/Enhanced3BConc.h new file mode 100755 index 000000000..82064cb54 --- /dev/null +++ b/Cantera/src/Enhanced3BConc.h @@ -0,0 +1,81 @@ +/** + * @file Enhanced3BConc.h + */ + +/* $Author$ + * $Date$ + * $Revision$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_ENH_CONC_H +#define CT_ENH_CONC_H + +#include + +namespace Cantera { + + /** + * Computes enhanced third-body concentrations. + * @see GasKinetics + */ + class Enhanced3BConc { + + public: + + Enhanced3BConc() : m_n (0), m_deflt (1.0) {} + + Enhanced3BConc(int n, const map& enhanced, + doublereal deflt = 1.0) { + map::const_iterator iter; + for (iter = enhanced.begin(); iter != enhanced.end(); ++iter) { + m_index.push_back( iter->first ); + m_eff.push_back( iter->second - deflt); + } + m_deflt = deflt; + m_n = n; + } + + Enhanced3BConc(int n, const vector_int& e_index, + const vector_fp& efficiencies, doublereal deflt = 1.0) + : m_index (e_index), m_eff (efficiencies) { + int i; + m_n = n; + m_deflt = deflt; + for (i = 0; i < m_n; i++) { + m_eff[i] -= m_deflt; + } + } + + doublereal update(const vector_fp& c, doublereal ctot) const { + int i; + doublereal sum = 0.0; + for (i = 0; i < m_n; i++) { + sum += m_eff[i] * c[m_index[i]]; + } + return m_deflt * ctot + sum; + } + + void getEfficiencies(vector_fp& eff) const { + int i; + for (i = 0; i < m_n; i++) { + eff[m_index[i]] = m_eff[i] + m_deflt; + } + } + + private: + int m_n; + vector_int m_index; + vector_fp m_eff; + doublereal m_deflt; + }; + +} + +#endif + + + + diff --git a/Cantera/src/FILES b/Cantera/src/FILES new file mode 100755 index 000000000..3e5da5c10 --- /dev/null +++ b/Cantera/src/FILES @@ -0,0 +1,106 @@ + +Core Components +--------------- +State.h T, density, mole/mass conversion +Constituents.cpp Element and species properties +Phase.cpp a basic class for phases of matter +stringUtils.cpp string utilities +misc.cpp application-wide settings +plots.cpp plotting to TECPLOT and Excel +ctvector.cpp a simple vector class + + +XML/CTML +-------- +importCTML.cpp read CTML files +xml.cpp XML input/output +ctml.cpp CTML input/output + + +Numerics +-------- +DenseMatrix.cpp dense matrices +BandMatrix.cpp band matrices +funcs.cpp polynomial fitting +sort.cpp sorting + + +Thermodynamic Properties +------------------------ +IdealGasThermo.cpp ideal gas thermodynamic properties +ConstDensityThermo.cpp incompressible thermodynamic properties +SpeciesThermoFactory.cpp factory to build thermo managers + + +Homogeneous Kinetics +-------------------- +Kinetics.h base class definition +GRI_30_Kinetics.cpp hard-wired GRI-Mech 3.0 +GasKinetics.cpp gas-phase homogeneous kinetics +FalloffFactory.cpp build falloff parameterizations +GasKineticsWriter.cpp writes hard-coded versions of reaction mechanisms + + +Heterogeneous kinetics +---------------------- +SurfacePhase.h a surface phase +surfKinetics.cpp surface kinetics +ImplicitSurfChem.cpp integrate site density rate equations + +Support for Chemkin-format Files +-------------------------------- +importCK.cpp import a Chemkin-format reaction mechanism +ck2ctml.cpp translate Chemkin format to CTML + + +Chemical Equilibrium +-------------------- +ChemEquil.cpp chemical equilibrium solver (element potential) + + +Transport Properties +-------------------- +TransportFactory.cpp build transport managers +MultiTransport.cpp multicomponent transport properties +MixTransport.cpp mixture-averaged transport properties +MMCollisionInt.cpp Monchick & Mason collision integrals + + +Zero-Dimensional Reactors +------------------------- +ReactorBase.cpp base class +Reactor.cpp general-purpose reactor +ImplicitChem.cpp integrate rate equations +FlowDevice.cpp devices to connect reactors in a network + + +Reaction Path Analysis +---------------------- +Group.cpp represents atomic groups in a molecule +ReactionPath.cpp generates reaction path diagrams + + +ODE Integrators +--------------- +Integrator.h base class +CVode.cpp wrapper for CVODE + + +Solvers for 1D, Multi-Domain Problems +------------------------------------- +MultiJac.cpp Jacobian matrix evaluator +MultiNewton.cpp Newton solver +newton_utils.cpp utilities used by MultiNewton + + +1D Flows +-------- +StFlow.cpp one-dimensional reacting flows +OneDim.cpp one-dimensional, multidomain simulations + + + + + + + diff --git a/Cantera/src/FalloffFactory.cpp b/Cantera/src/FalloffFactory.cpp new file mode 100755 index 000000000..fc65db57a --- /dev/null +++ b/Cantera/src/FalloffFactory.cpp @@ -0,0 +1,288 @@ +/** + * @file FalloffFactory.cpp + */ + +/* $Author$ + * $Date$ + * $Revision$ + */ + +// Copyright 2001 California Institute of Technology + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include + +#include "FalloffFactory.h" + +namespace Cantera { + + FalloffFactory* FalloffFactory::__factory = 0; + + /** + * The 3-parameter Troe falloff parameterization. + * This parameterization is + * defined by + * \f[ F = F_{cent}^{1/(1 + f_1^2)} \f] + * where + * \f[ F_{cent} = (1 - A)\exp(-T/T_3) + A \exp(-T/T_1) \f] + * \f[ f_1 = (\log_{10} P_r + C) / \left(N - 0.14 + * (\log_{10} P_r + C)\right) \f] + * \f[ C = -0.4 - 0.67 \log_{10} F_{cent} \f] + * \f[ N = 0.75 - 1.27 \log_{10} F_{cent} \f] + */ + class Troe3 : public Falloff { + public: + + /// Default constructor. + Troe3() : m_a (0.0), m_rt3 (0.0), m_rt1 (0.0) {} + + // Destructor. Does nothing. + virtual ~Troe3() {} + + /** + * Initialize. + * @param c Coefficient vector of length 3, + * with entries \f$ (A, T_3, T_1) \f$ + */ + virtual void init(const vector_fp& c) { + m_a = c[0]; + m_rt3 = 1.0/c[1]; + m_rt1 = 1.0/c[2]; + } + + virtual void updateTemp(doublereal T, workPtr work) const { + doublereal Fcent = (1.0 - m_a) * exp(- T * m_rt3 ) + + m_a * exp(- T * m_rt1 ); + *work = log10( fmaxx( Fcent, SmallNumber ) ); + } + + virtual doublereal F(doublereal pr, const_workPtr work) const { + doublereal lpr,f1,lgf, cc, nn; + lpr = log10( fmaxx(pr,SmallNumber) ); + cc = -0.4 - 0.67 * (*work); + nn = 0.75 - 1.27 * (*work); + f1 = ( lpr + cc )/ ( nn - 0.14 * ( lpr + cc ) ); + lgf = (*work) / ( 1.0 + f1 * f1 ); + return pow(10.0, lgf ); + } + + virtual size_t workSize() { return 1; } + + protected: + + doublereal m_a, m_rt3, m_rt1; + + private: + + }; + + + + /** + * The 4-parameter Troe falloff parameterization. This parameterization is + * defined by + * + * \f[ F = F_{cent}^{1/(1 + f_1^2)} \f] + * where + * \f[ F_{cent} = (1 - A)\exp(-T/T_3) + A \exp(-T/T_1) + \exp(-T_2/T) \f] + * \f[ f_1 = (\log_{10} P_r + C) / \left(N - 0.14 + * (\log_{10} P_r + C)\right) \f] + * \f[ C = -0.4 - 0.67 \log_{10} F_{cent} \f] + * \f[ N = 0.75 - 1.27 \log_{10} F_{cent} \f] + * + */ + + class Troe4 : public Falloff { + public: + + Troe4() : m_a (0.0), m_rt3 (0.0), m_rt1 (0.0), + m_t2 (0.0) {} + virtual ~Troe4() {} + + virtual void init(const vector_fp& c) { + m_a = c[0]; + m_rt3 = 1.0/c[1]; + m_rt1 = 1.0/c[2]; + m_t2 = c[3]; + } + + virtual void updateTemp(doublereal T, workPtr work) const { + doublereal Fcent = (1.0 - m_a) * exp(- T * m_rt3 ) + + m_a * exp(- T * m_rt1 ) + + exp(- m_t2 / T ); + *work = log10( fmaxx( Fcent, SmallNumber ) ); + } + + virtual doublereal F(doublereal pr, const_workPtr work) const { + doublereal lpr,f1,lgf, cc, nn; + lpr = log10( fmaxx(pr,SmallNumber) ); + cc = -0.4 - 0.67 * (*work); + nn = 0.75 - 1.27 * (*work); + f1 = ( lpr + cc )/ ( nn - 0.14 * ( lpr + cc ) ); + lgf = (*work) / ( 1.0 + f1 * f1 ); + return pow(10.0, lgf ); + } + + virtual size_t workSize() { return 1; } + + protected: + + doublereal m_a, m_rt3, m_rt1; + doublereal m_t2; + + private: + }; + + /** + * The 3-parameter SRI falloff function. + */ + class SRI3 : public Falloff { + + public: + + SRI3() {} + virtual ~SRI3() {} + + virtual void init(const vector_fp& c) { + m_a = c[0]; + m_b = c[1]; + m_c = c[2]; + } + + virtual void updateTemp(doublereal T, workPtr work) const { + *work = m_a * exp( - m_b / T); + if (m_c != 0.0) *work += exp( - T/m_c ); + } + + virtual doublereal F(doublereal pr, const_workPtr work) const { + doublereal lpr = log10( fmaxx(pr,SmallNumber) ); + doublereal xx = 1.0/(1.0 + lpr*lpr); + doublereal ff = pow( *work , xx); + return ff; + } + + virtual size_t workSize() { return 1; } + + protected: + doublereal m_a, m_b, m_c; + + private: + + }; + + + /** + * The 5-parameter SRI falloff function. + */ + class SRI5 : public Falloff { + + public: + SRI5() {} + virtual ~SRI5() {} + virtual void init(const vector_fp& c) { + m_a = c[0]; + m_b = c[1]; + m_c = c[2]; + m_d = c[3]; + m_e = c[4]; + } + + virtual void updateTemp(doublereal T, workPtr work) const { + *work = m_a * exp( - m_b / T); + if (m_c != 0.0) *work += exp( - T/m_c ); + work[1] = m_d * pow(T,m_e); + } + + virtual doublereal F(doublereal pr, const_workPtr work) const { + doublereal lpr = log10( fmaxx(pr,SmallNumber) ); + doublereal xx = 1.0/(1.0 + lpr*lpr); + return pow( *work, xx) * work[1]; + } + + virtual size_t workSize() { return 2; } + + protected: + + doublereal m_a, m_b, m_c; + doublereal m_d, m_e; + + private: + + }; + + + /** + * Wang-Frenklach falloff function. Reference: Wang, H., and + * Frenklach, M., Chem. Phys. Lett. vol. 205, 271 (1993). + */ + class WF93 : public Falloff { + + public: + WF93() {} + virtual ~WF93() {} + + virtual void init(const vector_fp& c) { + m_a = c[0]; + m_rt1 = 1.0/c[1]; + m_t2 = c[2]; + m_rt3 = 1.0/c[3]; + m_alpha0 = c[4]; + m_alpha1 = c[5]; + m_alpha2 = c[6]; + m_sigma0 = c[7]; + m_sigma1 = c[8]; + m_sigma2 = c[9]; + } + + virtual void updateTemp(doublereal T, workPtr work) const { + work[0] = m_alpha0 + (m_alpha1 + m_alpha2*T)*T; // alpha + work[1] = m_sigma0 + (m_sigma1 + m_sigma2*T)*T; // sigma + doublereal Fcent = (1.0 - m_a) * exp(- T * m_rt3 ) + + m_a * exp(- T * m_rt1 ) + exp(-m_t2/T); + work[2] = log10(Fcent); + } + + virtual doublereal F(doublereal pr, const_workPtr work) const { + doublereal lpr = log10( fmaxx(pr, SmallNumber) ); + doublereal x = (lpr - work[0])/work[1]; + doublereal flog = work[2]/exp(x*x); + return pow( 10.0, flog); + } + + virtual size_t workSize() { return 3; } + + protected: + + doublereal m_alpha0, m_alpha1, m_alpha2; + doublereal m_sigma0, m_sigma1, m_sigma2; + doublereal m_a, m_rt1, m_t2, m_rt3; + + private: + + }; + + + Falloff* FalloffFactory::newFalloff(int type, const vector_fp& c) { + Falloff* f; + switch(type) { + case TROE3_FALLOFF: + f = new Troe3(); break; + case TROE4_FALLOFF: + f = new Troe4(); break; + case SRI3_FALLOFF: + f = new SRI3(); break; + case SRI5_FALLOFF: + f = new SRI5(); break; + case WF_FALLOFF: + f = new WF93(); break; + default: return 0; + } + f->init(c); + return f; + } + +} diff --git a/Cantera/src/FalloffFactory.h b/Cantera/src/FalloffFactory.h new file mode 100755 index 000000000..8a7d14aa4 --- /dev/null +++ b/Cantera/src/FalloffFactory.h @@ -0,0 +1,127 @@ +/** + * @file FalloffFactory.h + * + * Parameterizations for reaction falloff functions. Used by classes + * that implement gas-phase kinetics (GasKinetics, GRI_30_Kinetics). + */ + + +/* + * $Author$ + * $Date$ + * $Revision$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_NEWFALLOFF_H +#define CT_NEWFALLOFF_H + +#include "ct_defs.h" +#include "reaction_defs.h" + +namespace Cantera { + + /** + * Base class for falloff function calculators. Each instance of a + * subclass of Falloff computes one falloff function. + */ + class Falloff { + public: + + Falloff(){} + virtual ~Falloff(){} + + /** + * Initialize. Must be called before any other method is + * invoked. + * + * @param c Vector of coefficients of the parameterization. + * The number and meaning of these coefficients is + * subclass-dependent. + */ + virtual void init(const vector_fp& c) =0; + + /** + * Update the temperature-dependent portions of the falloff + * function, if any. This method evaluates temperature-dependent + * intermediate results and stores them in the 'work' array. + * If not overloaded, the default behavior is to do nothing. + * @param T Temperature [K]. + * @param work storage space for intermediate results. + */ + virtual void updateTemp (doublereal T, workPtr work) const {} + + /** + * The falloff function. This is defined so that the + * rate coefficient is + * \f[ k = F(Pr)\frac{Pr}{1 + Pr}. \f] + * Here \f$ Pr \f$ is the reduced pressure, defined by + * \f[ + * Pr = \frac{k_0 [M]}{k_\infty}. + * \f] + * @param pr reduced pressure (dimensionless). + * @param work array of size workSize() containing cached + * temperature-dependent intermediate results from a prior call + * to updateTemp. + */ + virtual doublereal F(doublereal pr, const_workPtr work) const =0; + + /** + * The size of the work array required. + */ + virtual size_t workSize() =0; + + protected: + private: + }; + + + + /** + * Factory class to construct falloff function calculators. + * The falloff factory is accessed through static method factory: + * @code + * Falloff* f = FalloffFactory::factory()->newFalloff(type, c) + * @endcode + * @ingroup falloffGroup + */ + class FalloffFactory { + public: + + /** + * Return a pointer to the factory. On the first call, a new + * instance is created. Since there is no need to instantiate + * more than one factory, on all subsequent calls, a pointer + * to the existing factory is returned. + */ + static FalloffFactory* factory() { + if (!__factory) __factory = new FalloffFactory; + return __factory; + } + + /** + * Delete the factory, and set the pointer to zero. + */ + virtual ~FalloffFactory() { + delete __factory; + __factory = 0; + } + + /** + * Return a pointer to a new falloff function calculator. + * @param type Integer flag specifying the type of falloff function. + * The standard types are defined in file reaction_defs.h. A factory + * class derived from FalloffFactory may define other types as well. + */ + virtual Falloff* newFalloff(int type, const vector_fp& c); + + private: + static FalloffFactory* __factory; + FalloffFactory(){} + }; + +} +#endif + diff --git a/Cantera/src/FalloffMgr.h b/Cantera/src/FalloffMgr.h new file mode 100755 index 000000000..0ccb808cc --- /dev/null +++ b/Cantera/src/FalloffMgr.h @@ -0,0 +1,122 @@ +/** + * @file FalloffMgr.h + * + * $Author$ + * $Date$ + * $Revision$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_FALLOFFMGR_H +#define CT_FALLOFFMGR_H + +#include "reaction_defs.h" +#include "FalloffFactory.h" + +namespace Cantera { + + /** + * A falloff manager that implements any set of falloff functions. + * @ingroup falloffGroup + */ + class FalloffMgr { + public: + + /** + * Constructor. + * @param f If supplied, this factory will be used to construct + * falloff function calculators. If omitted, the standard factory + * will be used. + */ + FalloffMgr(FalloffFactory* f = 0) : m_n(0), m_n0(0), m_worksize(0) { + if (f == 0) m_factory = FalloffFactory::factory(); + else m_factory = f; + } + + /** + * Destructor. Deletes all installed falloff function + * calculators. + */ + virtual ~FalloffMgr(){ + int i; + for (i = 0; i < m_n; i++) delete m_falloff[i]; + } + + /** + * Install a new falloff function calculator. @param rxn + * Index of the falloff reaction. This will be used to determine + * which array entry is modified in method pr_to_falloff. + * + * @param type of falloff function to install. + * @param c vector of coefficients for the falloff function. + */ + void install(int rxn, int type, + const vector_fp& c) { + if (type != SIMPLE_FALLOFF) { + m_rxn.push_back(rxn); + Falloff* f = m_factory->newFalloff(type,c); + m_offset.push_back(m_worksize); + m_worksize += f->workSize(); + m_falloff.push_back(f); + m_n++; + } + else { + m_rxn0.push_back(rxn); + m_n0++; + } + } + + /** + * Size of the work array required to store intermediate results. + */ + size_t workSize() { return m_worksize; } + + /** + * Update the cached temperature-dependent intermediate + * results for all installed falloff functions. + * @param t Temperature [K]. + * @param work Work array. Must be dimensioned at least workSize(). + */ + void updateTemp(doublereal t, workPtr work) { + int i; + for (i = 0; i < m_n; i++) m_falloff[i]->updateTemp(t, + work + m_offset[i]); + } + + /** + * Given a vector of reduced pressures for each falloff reaction, + * replace each entry by the value of the falloff function. + */ + void pr_to_falloff(doublereal* values, const_workPtr work) { + doublereal pr; + int i; + for (i = 0; i < m_n0; i++) { + values[m_rxn0[i]] /= (1.0 + values[m_rxn0[i]]); + } + for (i = 0; i < m_n; i++) { + pr = values[m_rxn[i]]; + values[m_rxn[i]] *= + m_falloff[i]->F(pr, work + m_offset[i]) /(1.0 + pr); + } + } + + protected: + vector_int m_rxn, m_rxn0; + vector m_falloff; + FalloffFactory* m_factory; + vector_int m_loc; + int m_n, m_n0; + vector m_offset; + size_t m_worksize; + }; +} + +#endif + + + + + + diff --git a/Cantera/src/Flow1D.h b/Cantera/src/Flow1D.h new file mode 100755 index 000000000..5ac26e174 --- /dev/null +++ b/Cantera/src/Flow1D.h @@ -0,0 +1,82 @@ + +deprecated + + +#ifndef CT_FLOW1D_H +#define CT_FLOW1D_H + +#include "MultiDomain.h" +#include "MultiJac.h" +#include "MultiNewton.h" + +#include "Jac1D.h" +#include "Newton1D.h" + +#include "Surf1D.h" + +namespace Cantera { + + /** + * Container class for multiple-domain 1D problems. + */ + class OneDim : public MultiDomain { + public: + OneDim() : m_jac(0), m_newt(0) { + m_newt = new MultiNewton(1); + } + + virtual void addDomain(Resid1D* d) { + MultiDomain::addDomain(d); + m_newt->resize(size()); + delete m_jac; + m_jac = 0; + m_jac = new MultiJac(*this); + m_jac_ok = false; + int nd = m_dom.size(); + for (int i = 0; i < nd; i++) + m_dom[i]->setJac(m_jac); + } + + virtual ~OneDim() { + delete m_jac; + delete m_newt; + } + + MultiJac& jacobian() { return *m_jac; } + MultiNewton& newton() { return *m_newt; } + + + virtual int solve(doublereal* x, doublereal* xnew, int loglevel) { + if (!m_jac) { + cout << "creating new jac.." << endl; + m_jac = new MultiJac(*this); + m_jac_ok = false; + int nd = m_dom.size(); + for (int i = 0; i < nd; i++) + m_dom[i]->setJac(m_jac); + cout << "done" << endl; + } + + if (!m_jac_ok) { + cout << "eval jac" << endl; + eval(-1, x, xnew, m_rdt); + m_jac->eval(x, xnew, m_rdt); + m_jac_ok = true; + } + return m_newt->solve(x, xnew, *this, *m_jac, loglevel); + } + + + + protected: + MultiJac* m_jac; + MultiNewton* m_newt; + Jac1D* m_jac1; + Newton1D* m_newt1; + }; + +} + +#endif + + diff --git a/Cantera/src/FtnODESys.h b/Cantera/src/FtnODESys.h new file mode 100755 index 000000000..d9a82c05c --- /dev/null +++ b/Cantera/src/FtnODESys.h @@ -0,0 +1,56 @@ + +#ifndef CT_FTNODESYS_H +#define CT_FTNODESYS_H + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +namespace Cantera { + + + typedef void (*Ftn_RHS_Func) (integer* n, doublereal* t, doublereal* y, + doublereal* ydot); + + /** + * A class to integrate a system of ODE's defined by a Fortran function. + * Not currently used. + */ + class FtnODESys : public FuncEval { + + public: + + FtnODESys(int n, doublereal* y0, Ftn_RHS_Func f) { + m_func = f; + m_n = n; + m_y0.resize(n); + int i; + for (i = 0; i < n; i++) m_y0[i] = y0[i]; + } + + virtual ~FtnODESys(){} + + virtual void eval(double t, double* y, double* ydot) { + m_func(&m_n, &t, y, ydot); + } + + virtual void getInitialConditions(double t0, double* y) { + int i; + for (i = 0; i < m_n; i++) y[i] = m_y0[i]; + } + + virtual int neq() { return m_n; } + + protected: + int m_n; + vector_fp m_y0; + Ftn_RHS_Func m_func; + + private: + + }; + +} + +#endif diff --git a/Cantera/src/Func1.h b/Cantera/src/Func1.h new file mode 100644 index 000000000..ee59ffbb4 --- /dev/null +++ b/Cantera/src/Func1.h @@ -0,0 +1,199 @@ +/** + * @file Func1.h + * + * $Author$ + * $Date$ + * $Revision$ + */ + +// Copyright 2001 California Institute of Technology + +#ifndef CT_FUNC1_H +#define CT_FUNC1_H + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "ct_defs.h" + +namespace Cantera { + + const int FourierFuncType = 1; + const int PolyFuncType = 2; + const int ArrheniusFuncType = 3; + const int SumFuncType = 20; + const int ProdFuncType = 30; + const int RatioFuncType = 40; + + /** + * Base class for 'functor' classes that evaluate a function of + * one variable. + */ + class Func1 { + public: + Func1() {} + virtual ~Func1() {cout << "Func1 destructor" << endl;} + doublereal operator()(doublereal t) { return eval(t); } + virtual doublereal eval(doublereal t) { return 0.0; } + protected: + int m_n; + private: + }; + + + /** + * Polynomial of degree n. + */ + class Poly1 : public Func1 { + public: + Poly1(int n, doublereal* c) { + m_n = n+1; + m_c.resize(n+1); + copy(c, c+m_n, m_c.begin()); + } + virtual ~Poly1() {} + + virtual doublereal eval(doublereal t) { + int n; + doublereal r = m_c[m_n-1]; + for (n = 1; n < m_n; n++) { + r *= t; + r += m_c[m_n - n - 1]; + } + return r; + } + + protected: + int m_n; + vector_fp m_c; + }; + + + /** + * Fourier cosine/sin series. + */ + class Fourier1 : public Func1 { + public: + Fourier1(int n, doublereal omega, doublereal a0, + doublereal* a, doublereal* b) { + m_n = n; + m_omega = omega; + m_a0_2 = 0.5*a0; + m_ccos.resize(n); + m_csin.resize(n); + copy(a, a+n, m_ccos.begin()); + copy(b, b+n, m_csin.begin()); + } + virtual ~Fourier1() {} + + virtual doublereal eval(doublereal t) { + int n, nn; + doublereal sum = m_a0_2; + for (n = 0; n < m_n; n++) { + nn = n + 1; + sum += m_ccos[n]*cos(m_omega*nn*t) + + m_csin[n]*sin(m_omega*nn*t); + } + return sum; + } + + protected: + int m_n; + doublereal m_omega, m_a0_2; + vector_fp m_ccos, m_csin; + }; + + + /** + * Sum of Arrhenius terms. + */ + class Arrhenius1 : public Func1 { + public: + Arrhenius1(int n, doublereal* c) { + m_n = n; + m_A.resize(n); + m_b.resize(n); + m_E.resize(n); + int loc; + for (int i = 0; i < n; i++) { + loc = 3*i; + m_A[i] = c[loc]; + m_b[i] = c[loc+1]; + m_E[i] = c[loc+2]; + } + } + virtual ~Arrhenius1() {} + + virtual doublereal eval(doublereal t) { + int n; + doublereal sum = 0.0; + for (n = 0; n < m_n; n++) { + sum += m_A[n]*pow(t,m_b[n])*exp(-m_E[n]/t); + } + return sum; + } + + protected: + int m_n; + vector_fp m_A, m_b, m_E; + }; + + + /** + * Sum of two functions. + */ + class Func1Sum : public Func1 { + public: + Func1Sum(Func1& f1, Func1& f2) { + m_f1 = &f1; + m_f2 = &f2; + } + virtual ~Func1Sum() {} + virtual doublereal eval(doublereal t) { + return m_f1->eval(t) + m_f2->eval(t); + } + protected: + Func1 *m_f1, *m_f2; + private: + }; + + /** + * Product of two functions. + */ + class Func1Product : public Func1 { + public: + Func1Product(Func1& f1, Func1& f2) { + m_f1 = &f1; + m_f2 = &f2; + } + virtual ~Func1Product() {} + virtual doublereal eval(doublereal t) { + return m_f1->eval(t) * m_f2->eval(t); + } + protected: + Func1 *m_f1, *m_f2; + private: + }; + + /** + * Ratio of two functions. + */ + class Func1Ratio : public Func1 { + public: + Func1Ratio(Func1& f1, Func1& f2) { + m_f1 = &f1; + m_f2 = &f2; + } + virtual ~Func1Ratio() {} + virtual doublereal eval(doublereal t) { + return m_f1->eval(t) / m_f2->eval(t); + } + protected: + Func1 *m_f1, *m_f2; + private: + }; +} + +#endif diff --git a/Cantera/src/FuncEval.h b/Cantera/src/FuncEval.h new file mode 100755 index 000000000..f64c48ad9 --- /dev/null +++ b/Cantera/src/FuncEval.h @@ -0,0 +1,60 @@ +/** + * @file FuncEval.h + * + */ + +// Copyright 2001 California Institute of Technology + +#ifndef CT_FUNCEVAL_H +#define CT_FUNCEVAL_H + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "ct_defs.h" + +namespace Cantera { + + + /** + * Virtual base class for ODE right-hand-side function evaluators. + * Classes derived from FuncEval evaluate the right-hand-side function + * \f$ \vec{F}(t,\vec{y})\f$ in + * \f[ + * \dot\vec{y} = \vec{F}(t,\vec{y}). + * \f] + * @ingroup odeGroup + */ + class FuncEval { + + public: + + /** + * Evaluate the right-hand-side function. Called by the + * integrator. + * @param t time. (input) + * @param y solution vector. (input) + * @param ydot rate of change of solution vector. (output) + */ + virtual void eval(double t, double* y, double* ydot)=0; + + /** + * Fill the solution vector with the initial conditions + * at initial time t0. + */ + virtual void getInitialConditions(double t0, size_t leny, double* y)=0; + + /** Number of equations. */ + virtual int neq()=0; + + protected: + + private: + + }; + +} + +#endif diff --git a/Cantera/src/GRI30.h b/Cantera/src/GRI30.h new file mode 100755 index 000000000..14b7edfbd --- /dev/null +++ b/Cantera/src/GRI30.h @@ -0,0 +1,89 @@ + +DEPRECATED + +/** + * @file GRI30.h + * + * GRI-Mech 3.0 + * + */ + +// Copyright 2001 California Institute of Technology + +#ifndef CT_GRI30_H +#define CT_GRI30_H + +#include + +#include "Phase.h" +#include "IdealGasThermo.h" +#include "GRI_30_Kinetics.h" + +#include "global.h" +#include "import.h" +#include "SpeciesThermoFactory.h" + +#include "speciesThermoTypes.h" + + +namespace Cantera { + + /** + * Implements reaction mechanism GRI-Mech 3.0 + */ + class GRI30 : + public Phase, public IdealGasThermo, public GRI_30_Kinetics + { + public: + +// GRI30(map& params) { +// setSpThermo(NASA); +// initThermo(*this); +// GRI_30_Kinetics::setThermo(*this); +// m_ok = importFromFile(this, this, params); +// } + + GRI30() { + setSpThermo(NASA); + initThermo(*this); + GRI_30_Kinetics::setThermo(*this); + map params; + params["input"] = "gri30.xml"; + params["ID"] = "gri30"; + //if (validate) params["validate"] = "yes"; + m_ok = importFromFile(this, this, params); + //m_ok = import("gri30.xml", "", false); + } + + /** + * Destructor. Does nothing. + */ + virtual ~GRI30() {} + + bool valid() const { return m_ok; } + + bool operator!() const {return !m_ok;} + + protected: + +// bool import(string infile, string dbfile="", bool validate=false) { +// map params; +// params["input"] = infile; +// params["database"] = dbfile; +// if (validate) params["validate"] = "yes"; +// m_ok = importFromFile(this, this, params); +// return m_ok; +// } + + void setSpThermo(int paramType, SpeciesThermoFactory* fsp = 0) { + if (fsp == 0) fsp = SpeciesThermoFactory::factory(); + setSpeciesThermo(fsp->newSpeciesThermo(paramType)); + } + + bool m_ok; + + private: + }; +} + +#endif diff --git a/Cantera/src/GRI_30_Kinetics.cpp b/Cantera/src/GRI_30_Kinetics.cpp new file mode 100755 index 000000000..3651058c7 --- /dev/null +++ b/Cantera/src/GRI_30_Kinetics.cpp @@ -0,0 +1,1004 @@ +/** + * @file GRI_30_Kinetics.cpp + * + */ + +// Copyright 2001 California Institute of Technology + + +// turn off warnings under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "GRI_30_Kinetics.h" + +#include "ReactionData.h" +#include "StoichManager.h" +#include "Enhanced3BConc.h" +#include "ThirdBodyMgr.h" +#include "RateCoeffMgr.h" +#include "IdealGasPhase.h" + +#include +using namespace std; + + +#ifdef HAVE_INTEL_MKL +#include "mkl_vml.h" +#endif + +namespace Cantera { + + /** + * Construct an empty reaction mechanism. + */ + GRI_30_Kinetics:: + GRI_30_Kinetics(thermo_t* th) : GasKinetics(th) {} + + void GRI_30_Kinetics:: + gri30_update_rates_T() { + doublereal T = thermo().temperature(); + if (fabs(T - m_kdata->m_temp) > m_dt_threshold) { + doublereal logT = log(T); + m_kdata->m_logc0 = m_kdata->m_logp0 - logT; + update_rates(T, logT, m_kdata->m_rfn.begin()); + + m_falloff_low_rates.update(T, logT, m_kdata->m_rfn_low.begin()); + m_falloff_high_rates.update(T, logT, m_kdata->m_rfn_high.begin()); + m_falloffn.updateTemp(T, m_kdata->falloff_work.begin()); + + m_kdata->m_temp = T; + gri30_updateKc(); + m_kdata->m_ROP_ok = false; + } + }; + + + /** + * Update the equilibrium constants in molar units. + * @todo This formulation assumes an ideal gas. + */ + void GRI_30_Kinetics::gri30_updateKc() { + doublereal* rkc = m_kdata->m_rkcn.begin(); + const doublereal* a = ((IdealGasPhase*)m_thermo[0])->expGibbs_RT().begin(); + doublereal exp_c0 = exp(m_kdata->m_logc0); + update_kc(a, exp_c0, rkc); + } + + + void GRI_30_Kinetics::gri30_updateROP() { + + gri30_update_rates_T(); + _update_rates_C(); + + if (m_kdata->m_ROP_ok) return; + + const vector_fp& rf = m_kdata->m_rfn; + const vector_fp& rkc = m_kdata->m_rkcn; + array_fp& ropf = m_kdata->m_ropf; + array_fp& ropnet = m_kdata->m_ropnet; + + copy(rf.begin(), rf.end(), ropf.begin()); + m_3b_concm.multiply( ropf.begin(), m_kdata->concm_3b_values.begin() ); + processFalloffReactions(); + multiply_each(ropf.begin(), ropf.end(), m_perturb.begin()); + eval_ropnet(m_conc.begin(), ropf.begin(), rkc.begin(), ropnet.begin()); + m_kdata->m_ROP_ok = true; + } + + + void GRI_30_Kinetics::update_rates(double t, double tlog, double* rf) { + double rt = 1.0/t; + rf[0] = exp(25.5108 + -1 * tlog); + rf[1] = exp(26.9379 + -1 * tlog); + rf[2] = exp(3.65584 + 2.7 * tlog - 3150.48 * rt); + rf[4] = exp(9.17264 + 2 * tlog - 2013.09 * rt); + rf[10] = exp(13.8353 + 1.5 * tlog - 4328.13 * rt); + rf[14] = exp(24.3868 - 1781.58 * rt); + rf[17] = exp(5.96101 + 2.5 * tlog - 1560.14 * rt); + rf[18] = exp(4.86753 + 2.5 * tlog - 2516.36 * rt); + rf[20] = exp(9.51044 + 2 * tlog - 956.215 * rt); + rf[21] = exp(38.3674 + -1.41 * tlog - 14569.7 * rt); + rf[22] = exp(8.84506 + 2 * tlog - 956.215 * rt); + rf[24] = exp(9.43348 + 1.83 * tlog - 110.72 * rt); + rf[26] = exp(11.4053 + 1.92 * tlog - 2863.61 * rt); + rf[28] = exp(23.0259 - 4026.17 * rt); + rf[29] = exp(21.2829 - 679.416 * rt); + rf[30] = exp(21.6396 - 24056.4 * rt); + rf[31] = exp(25.3284 - 20130.9 * rt); + rf[32] = exp(28.6606 + -0.86 * tlog); + rf[33] = exp(30.666 + -1.24 * tlog); + rf[34] = exp(30.0523 + -0.76 * tlog); + rf[35] = exp(30.8891 + -1.24 * tlog); + rf[36] = exp(27.2743 + -0.8 * tlog); + rf[37] = exp(30.9082 + -0.6707 * tlog - 8576.25 * rt); + rf[38] = exp(27.631 + -1 * tlog); + rf[39] = exp(25.2231 + -0.6 * tlog); + rf[40] = exp(31.7254 + -1.25 * tlog); + rf[41] = exp(33.9409 + -2 * tlog); + rf[42] = exp(37.6298 + -2 * tlog); + rf[43] = exp(22.102 - 337.695 * rt); + rf[44] = exp(24.5255 - 537.494 * rt); + rf[45] = exp(25.1541 - 319.577 * rt); + rf[46] = exp(9.40096 + 2 * tlog - 2617.01 * rt); + rf[47] = exp(23.0259 - 1811.78 * rt); + rf[52] = exp(13.4 + 1.62 * tlog - 5455.46 * rt); + rf[57] = exp(10.9578 + 1.9 * tlog - 1379.97 * rt); + rf[60] = exp(18.9215 + 0.65 * tlog - -142.929 * rt); + rf[61] = exp(24.2137 + -0.09 * tlog - 306.995 * rt); + rf[63] = exp(10.6334 + 1.63 * tlog - 968.294 * rt); + rf[65] = exp(21.1287 + 0.5 * tlog - -55.3598 * rt); + rf[66] = exp(26.2916 + -0.23 * tlog - 538.5 * rt); + rf[67] = exp(9.74097 + 2.1 * tlog - 2450.93 * rt); + rf[68] = exp(8.34284 + 2.1 * tlog - 2450.93 * rt); + rf[74] = exp(7.18917 + 2.53 * tlog - 6160.04 * rt); + rf[77] = exp(11.6527 + 1.9 * tlog - 3789.63 * rt); + rf[79] = exp(24.6353 - 4026.17 * rt); + rf[80] = exp(23.1481 - 1725.21 * rt); + rf[83] = exp(12.283 + 1.51 * tlog - 1726.22 * rt); + rf[85] = exp(3.57515 + 2.4 * tlog - -1061.9 * rt); + rf[86] = exp(23.3974 - -251.636 * rt); + rf[87] = exp(21.4164 - 214.897 * rt); + rf[88] = exp(35.0694 - 14801.2 * rt); + rf[92] = exp(9.33256 + 2 * tlog - 1509.81 * rt); + rf[95] = exp(10.9331 + 1.6 * tlog - 2727.73 * rt); + rf[96] = exp(34.0987 + -1.34 * tlog - 713.135 * rt); + rf[97] = exp(11.5129 + 1.6 * tlog - 1570.21 * rt); + rf[98] = exp(10.7706 + 1.228 * tlog - 35.229 * rt); + rf[100] = exp(15.0481 + 1.18 * tlog - -224.962 * rt); + rf[103] = exp(7.2724 + 2 * tlog - -422.748 * rt); + rf[104] = exp(8.7483 + 2 * tlog - 754.907 * rt); + rf[106] = exp(-15.3388 + 4.5 * tlog - -503.271 * rt); + rf[107] = exp(6.22258 + 2.3 * tlog - 6794.16 * rt); + rf[108] = exp(10.4253 + 2 * tlog - 7045.8 * rt); + rf[109] = exp(-14.5432 + 4 * tlog - -1006.54 * rt); + rf[111] = exp(8.18869 + 2 * tlog - 1258.18 * rt); + rf[112] = exp(8.17188 + 2.12 * tlog - 437.846 * rt); + rf[113] = exp(22.7382 - 1006.54 * rt); + rf[114] = exp(18.683 - -820.332 * rt); + rf[115] = exp(26.7635 - 6039.26 * rt); + rf[119] = exp(25.7339 - 11877.2 * rt); + rf[120] = exp(8.63052 + 2 * tlog - 6039.26 * rt); + rf[121] = exp(24.7837 - 289.884 * rt); + rf[125] = exp(25.4054 - 1565.17 * rt); + rf[126] = exp(22.4655 - -379.97 * rt); + rf[131] = exp(25.9703 - 7947.66 * rt); + rf[132] = exp(25.2729 - -259.185 * rt); + rf[134] = exp(22.3327 - 754.907 * rt); + rf[135] = exp(6.21461 + 2 * tlog - 3638.65 * rt); + rf[136] = exp(28.101 - 6011.07 * rt); + rf[138] = exp(7.80792 + 2 * tlog - 4162.05 * rt); + rf[141] = exp(23.4313 - 301.963 * rt); + rf[142] = exp(22.9205 - 301.963 * rt); + rf[148] = exp(23.2082 - -286.865 * rt); + rf[149] = exp(23.4959 - -286.865 * rt); + rf[153] = exp(24.4121 - -276.799 * rt); + rf[154] = exp(24.2956 - 15339.7 * rt); + rf[155] = exp(21.5605 - 10224 * rt); + rf[156] = exp(3.19867 + 2.47 * tlog - 2606.95 * rt); + rf[158] = exp(22.6461 + 0.1 * tlog - 5334.68 * rt); + rf[160] = exp(1.19996 + 2.81 * tlog - 2949.17 * rt); + rf[161] = exp(10.309 + 1.5 * tlog - 5002.52 * rt); + rf[162] = exp(9.21034 + 1.5 * tlog - 5002.52 * rt); + rf[163] = exp(5.42495 + 2 * tlog - 4630.1 * rt); + rf[164] = exp(8.72258 + 1.74 * tlog - 5259.18 * rt); + rf[165] = exp(34.9442 + -1 * tlog - 8555.61 * rt); + rf[166] = exp(32.8621 + -1 * tlog - 8555.61 * rt); + rf[167] = exp(23.3222 - 201.309 * rt); + rf[168] = exp(23.6136 - 452.944 * rt); + rf[169] = exp(-35.3874 + 7.6 * tlog - -1776.55 * rt); + rf[170] = exp(23.0259 - -379.97 * rt); + rf[171] = exp(17.855 + 0.9 * tlog - 1003.02 * rt); + rf[172] = exp(31.4553 + -1.39 * tlog - 510.82 * rt); + rf[174] = exp(20.5489 - 1950.18 * rt); + rf[175] = exp(21.8864 - 429.794 * rt); + rf[177] = exp(24.0191 - 178.661 * rt); + rf[178] = exp(16.0127 + 1 * tlog - 3271.26 * rt); + rf[179] = exp(24.2378 - 193.759 * rt); + rf[180] = exp(21.0597 - 5440.36 * rt); + rf[181] = exp(24.0906 - 11650.7 * rt); + rf[182] = exp(26.6817 - 9501.76 * rt); + rf[183] = exp(21.4164 - 10598.9 * rt); + rf[185] = exp(21.47 - -241.57 * rt); + rf[186] = exp(32.2945 + -1.41 * tlog); + rf[187] = exp(22.0842 - -120.785 * rt); + rf[188] = exp(25.6061 - 181.178 * rt); + rf[190] = exp(24.189 - 166.08 * rt); + rf[192] = exp(14.5087 + 1.2 * tlog); + rf[193] = exp(6.1334 + 2 * tlog - 3271.26 * rt); + rf[194] = exp(7.15462 + 1.5 * tlog - 50.3271 * rt); + rf[196] = exp(23.719 - 6970.31 * rt); + rf[197] = exp(23.796 + -0.23 * tlog); + rf[198] = exp(26.6232 + -0.45 * tlog); + rf[201] = exp(24.4121 - 1836.94 * rt); + rf[202] = exp(11.4076 + 1.5 * tlog - -231.505 * rt); + rf[204] = exp(25.5908 + -0.11 * tlog - 2506.29 * rt); + rf[211] = exp(31.4332 + -1.32 * tlog - 372.421 * rt); + rf[213] = exp(20.6179 + 0.72 * tlog - 332.159 * rt); + rf[214] = exp(9.4727 + 1.9 * tlog - -478.108 * rt); + rf[215] = exp(23.0259 - 6542.53 * rt); + rf[218] = exp(22.8027 - 3754.4 * rt); + rf[219] = exp(22.5381 - -221.439 * rt); + rf[220] = exp(5.68698 + 2.45 * tlog - 1127.33 * rt); + rf[225] = exp(21.4164 - 10065.4 * rt); + rf[226] = exp(26.4598 - 27201.8 * rt); + rf[227] = exp(32.878 + -1.52 * tlog - 372.421 * rt); + rf[228] = exp(35.8738 + -2 * tlog - 402.617 * rt); + rf[229] = exp(59.9064 + -3.3 * tlog - 63714.1 * rt); + rf[230] = exp(3.01062 + 2.64 * tlog - 2506.29 * rt); + rf[231] = exp(1.62334 + 2.64 * tlog - 2506.29 * rt); + rf[232] = exp(15.179 + 1.58 * tlog - 13387 * rt); + rf[233] = exp(7.00307 + 2.03 * tlog - 6728.74 * rt); + rf[234] = exp(1.4816 + 2.26 * tlog - 3220.94 * rt); + rf[235] = exp(-1.83258 + 2.56 * tlog - 4529.44 * rt); + rf[237] = exp(24.8176 - 201.309 * rt); + rf[238] = exp(24.8664 - 23160.5 * rt); + rf[239] = exp(14.9533 + 0.88 * tlog - 10130.9 * rt); + rf[241] = exp(23.0259 - 37242.1 * rt); + rf[242] = exp(18.4207 - 32712.6 * rt); + rf[248] = exp(33.3676 + -1.38 * tlog - 639.155 * rt); + rf[249] = exp(26.3931 + -0.69 * tlog - 382.486 * rt); + rf[250] = exp(24.3609 + -0.36 * tlog - 291.897 * rt); + rf[251] = exp(33.3676 + -1.38 * tlog - 639.155 * rt); + rf[252] = exp(26.3931 + -0.69 * tlog - 382.486 * rt); + rf[253] = exp(24.3609 + -0.36 * tlog - 291.897 * rt); + rf[254] = exp(25.2876 - 14494.2 * rt); + rf[255] = exp(20.7233 - 10946.1 * rt); + rf[261] = exp(11.4927 + 1.41 * tlog - 4277.81 * rt); + rf[262] = exp(11.9184 + 1.57 * tlog - 22143.9 * rt); + rf[263] = exp(7.69621 + 2.11 * tlog - 5737.29 * rt); + rf[264] = exp(10.0213 + 1.7 * tlog - 1912.43 * rt); + rf[265] = exp(4.65396 + 2.5 * tlog - 6693.51 * rt); + rf[266] = exp(10.4043 + 1.5 * tlog - 1811.78 * rt); + rf[267] = exp(8.10168 + 1.5 * tlog - 1811.78 * rt); + rf[268] = exp(30.0991 - 42637.1 * rt); + rf[269] = exp(28.373 + -0.69 * tlog - 1434.32 * rt); + rf[270] = exp(19.4139 + 0.18 * tlog - 1066.94 * rt); + rf[271] = exp(25.8591 + -0.75 * tlog - 1454.45 * rt); + rf[272] = exp(9.90349 + 2 * tlog - 1006.54 * rt); + rf[274] = exp(27.1367 + -0.31 * tlog - 145.949 * rt); + rf[275] = exp(22.0316 + 0.15 * tlog - -45.2944 * rt); + rf[276] = exp(6.29157 + 2.4 * tlog - 4989.93 * rt); + rf[277] = exp(10.8198 + 1.6 * tlog - 480.624 * rt); + rf[278] = exp(9.14846 + 1.94 * tlog - 3251.13 * rt); + rf[279] = exp(23.0259 - 7221.94 * rt); + rf[280] = exp(29.4491 + -0.752 * tlog - 173.629 * rt); + rf[281] = exp(21.9019 - -354.806 * rt); + rf[282] = exp(21.8219 - 5686.97 * rt); + rf[284] = exp(8.80986 + 1.83 * tlog - 110.72 * rt); + rf[286] = exp(29.2405 - 8721.69 * rt); + rf[287] = exp(15.895 + 0.5 * tlog - -883.241 * rt); + rf[289] = exp(22.4811 - 754.907 * rt); + rf[290] = exp(21.5987 - 754.907 * rt); + rf[291] = exp(26.0216 - 5530.45 * rt); + rf[292] = exp(18.038 + 0.25 * tlog - -470.559 * rt); + rf[293] = exp(19.5292 + 0.29 * tlog - 5.53598 * rt); + rf[294] = exp(7.19818 + 1.61 * tlog - -193.256 * rt); + rf[295] = exp(22.488 - 909.914 * rt); + rf[296] = exp(22.488 - 909.914 * rt); + rf[297] = exp(24.1278 - 19703.1 * rt); + rf[298] = exp(14.5334 + 1.16 * tlog - 1210.37 * rt); + rf[299] = exp(14.5334 + 1.16 * tlog - 1210.37 * rt); + rf[300] = exp(16.9695 + 0.73 * tlog - -560.141 * rt); + rf[301] = exp(21.8252 - 6000.5 * rt); + rf[302] = exp(7.90839 + 1.77 * tlog - 2979.37 * rt); + rf[312] = exp(5.26269 + 2.68 * tlog - 1870.16 * rt); + rf[313] = exp(7.18539 + 2.54 * tlog - 3400.1 * rt); + rf[314] = exp(10.3609 + 1.8 * tlog - 470.055 * rt); + rf[315] = exp(-0.972861 + 2.72 * tlog - 754.907 * rt); + rf[316] = exp(-7.00979 + 3.65 * tlog - 3600.4 * rt); + rf[320] = exp(8.30894 + 2.19 * tlog - 447.911 * rt); + rf[322] = exp(17.0542 + 0.255 * tlog - -474.585 * rt); + rf[324] = exp(23.6818 + -0.32 * tlog); + } + + + void GRI_30_Kinetics::update_kc(const double* a, double exp_c0, double* rkc) { + rkc[0] = a[3]*exp_c0/(a[2]*a[2]); + rkc[1] = a[4]*exp_c0/(a[1]*a[2]); + rkc[2] = a[1]*a[4]/(a[0]*a[2]); + rkc[3] = a[3]*a[4]/(a[2]*a[6]); + rkc[4] = a[4]*a[6]/(a[2]*a[7]); + rkc[5] = a[1]*a[14]/(a[2]*a[9]); + rkc[6] = a[1]*a[16]/(a[2]*a[10]); + rkc[7] = a[0]*a[14]/(a[2]*a[11]); + rkc[8] = a[1]*a[16]/(a[2]*a[11]); + rkc[9] = a[1]*a[17]/(a[2]*a[12]); + rkc[10] = a[4]*a[12]/(a[2]*a[13]); + rkc[11] = a[15]*exp_c0/(a[2]*a[14]); + rkc[12] = a[4]*a[14]/(a[2]*a[16]); + rkc[13] = a[1]*a[15]/(a[2]*a[16]); + rkc[14] = a[4]*a[16]/(a[2]*a[17]); + rkc[15] = a[4]*a[17]/(a[2]*a[18]); + rkc[16] = a[4]*a[17]/(a[2]*a[19]); + rkc[17] = a[4]*a[18]/(a[2]*a[20]); + rkc[18] = a[4]*a[19]/(a[2]*a[20]); + rkc[19] = a[9]*a[14]/(a[2]*a[21]); + rkc[20] = a[1]*a[27]/(a[2]*a[22]); + rkc[21] = a[4]*a[21]/(a[2]*a[22]); + rkc[22] = a[10]*a[14]/(a[2]*a[22]); + rkc[23] = a[1]*a[28]/(a[2]*a[23]); + rkc[24] = a[12]*a[16]/(a[2]*a[24]); + rkc[25] = a[12]*a[17]/(a[2]*a[25]); + rkc[26] = a[4]*a[25]/(a[2]*a[26]); + rkc[27] = a[1]*a[14]*a[14]/(a[2]*a[27]*exp_c0); + rkc[28] = a[4]*a[27]/(a[2]*a[28]); + rkc[29] = a[10]*a[15]/(a[2]*a[28]); + rkc[30] = a[2]*a[15]/(a[3]*a[14]); + rkc[31] = a[6]*a[16]/(a[3]*a[17]); + rkc[32] = a[6]*exp_c0/(a[1]*a[3]); + rkc[33] = a[3]*a[6]*exp_c0/(a[1]*a[3]*a[3]); + rkc[34] = a[5]*a[6]*exp_c0/(a[1]*a[3]*a[5]); + rkc[35] = a[6]*a[47]*exp_c0/(a[1]*a[3]*a[47]); + rkc[36] = a[6]*a[48]*exp_c0/(a[1]*a[3]*a[48]); + rkc[37] = a[2]*a[4]/(a[1]*a[3]); + rkc[38] = a[0]*exp_c0/(a[1]*a[1]); + rkc[39] = a[0]*a[0]*exp_c0/(a[0]*a[1]*a[1]); + rkc[40] = a[0]*a[5]*exp_c0/(a[1]*a[1]*a[5]); + rkc[41] = a[0]*a[15]*exp_c0/(a[1]*a[1]*a[15]); + rkc[42] = a[5]*exp_c0/(a[1]*a[4]); + rkc[43] = a[2]*a[5]/(a[1]*a[6]); + rkc[44] = a[0]*a[3]/(a[1]*a[6]); + rkc[45] = a[4]*a[4]/(a[1]*a[6]); + rkc[46] = a[0]*a[6]/(a[1]*a[7]); + rkc[47] = a[4]*a[5]/(a[1]*a[7]); + rkc[48] = a[0]*a[8]/(a[1]*a[9]); + rkc[49] = a[12]*exp_c0/(a[1]*a[10]); + rkc[50] = a[0]*a[9]/(a[1]*a[11]); + rkc[51] = a[13]*exp_c0/(a[1]*a[12]); + rkc[52] = a[0]*a[12]/(a[1]*a[13]); + rkc[53] = a[17]*exp_c0/(a[1]*a[16]); + rkc[54] = a[0]*a[14]/(a[1]*a[16]); + rkc[55] = a[18]*exp_c0/(a[1]*a[17]); + rkc[56] = a[19]*exp_c0/(a[1]*a[17]); + rkc[57] = a[0]*a[16]/(a[1]*a[17]); + rkc[58] = a[20]*exp_c0/(a[1]*a[18]); + rkc[59] = a[0]*a[17]/(a[1]*a[18]); + rkc[60] = a[4]*a[12]/(a[1]*a[18]); + rkc[61] = a[5]*a[11]/(a[1]*a[18]); + rkc[62] = a[20]*exp_c0/(a[1]*a[19]); + rkc[63] = a[1]*a[18]/(a[1]*a[19]); + rkc[64] = a[0]*a[17]/(a[1]*a[19]); + rkc[65] = a[4]*a[12]/(a[1]*a[19]); + rkc[66] = a[5]*a[11]/(a[1]*a[19]); + rkc[67] = a[0]*a[18]/(a[1]*a[20]); + rkc[68] = a[0]*a[19]/(a[1]*a[20]); + rkc[69] = a[22]*exp_c0/(a[1]*a[21]); + rkc[70] = a[23]*exp_c0/(a[1]*a[22]); + rkc[71] = a[24]*exp_c0/(a[1]*a[23]); + rkc[72] = a[0]*a[22]/(a[1]*a[23]); + rkc[73] = a[25]*exp_c0/(a[1]*a[24]); + rkc[74] = a[0]*a[23]/(a[1]*a[24]); + rkc[75] = a[26]*exp_c0/(a[1]*a[25]); + rkc[76] = a[0]*a[24]/(a[1]*a[25]); + rkc[77] = a[0]*a[25]/(a[1]*a[26]); + rkc[78] = a[11]*a[14]/(a[1]*a[27]); + rkc[79] = a[0]*a[27]/(a[1]*a[28]); + rkc[80] = a[12]*a[14]/(a[1]*a[28]); + rkc[81] = a[1]*a[28]/(a[1]*a[29]); + rkc[82] = a[17]*exp_c0/(a[0]*a[14]); + rkc[83] = a[1]*a[5]/(a[0]*a[4]); + rkc[84] = a[7]*exp_c0/(a[4]*a[4]); + rkc[85] = a[2]*a[5]/(a[4]*a[4]); + rkc[86] = a[3]*a[5]/(a[4]*a[6]); + rkc[87] = a[5]*a[6]/(a[4]*a[7]); + rkc[88] = a[5]*a[6]/(a[4]*a[7]); + rkc[89] = a[1]*a[14]/(a[4]*a[8]); + rkc[90] = a[1]*a[16]/(a[4]*a[9]); + rkc[91] = a[1]*a[17]/(a[4]*a[10]); + rkc[92] = a[5]*a[9]/(a[4]*a[10]); + rkc[93] = a[1]*a[17]/(a[4]*a[11]); + rkc[94] = a[20]*exp_c0/(a[4]*a[12]); + rkc[95] = a[5]*a[10]/(a[4]*a[12]); + rkc[96] = a[5]*a[11]/(a[4]*a[12]); + rkc[97] = a[5]*a[12]/(a[4]*a[13]); + rkc[98] = a[1]*a[15]/(a[4]*a[14]); + rkc[99] = a[5]*a[14]/(a[4]*a[16]); + rkc[100] = a[5]*a[16]/(a[4]*a[17]); + rkc[101] = a[5]*a[17]/(a[4]*a[18]); + rkc[102] = a[5]*a[17]/(a[4]*a[19]); + rkc[103] = a[5]*a[18]/(a[4]*a[20]); + rkc[104] = a[5]*a[19]/(a[4]*a[20]); + rkc[105] = a[1]*a[27]/(a[4]*a[21]); + rkc[106] = a[1]*a[28]/(a[4]*a[22]); + rkc[107] = a[1]*a[29]/(a[4]*a[22]); + rkc[108] = a[5]*a[21]/(a[4]*a[22]); + rkc[109] = a[12]*a[14]/(a[4]*a[22]); + rkc[110] = a[5]*a[22]/(a[4]*a[23]); + rkc[111] = a[5]*a[23]/(a[4]*a[24]); + rkc[112] = a[5]*a[25]/(a[4]*a[26]); + rkc[113] = a[5]*a[27]/(a[4]*a[28]); + rkc[114] = a[3]*a[7]/(a[6]*a[6]); + rkc[115] = a[3]*a[7]/(a[6]*a[6]); + rkc[116] = a[4]*a[17]/(a[6]*a[10]); + rkc[117] = a[3]*a[13]/(a[6]*a[12]); + rkc[118] = a[4]*a[19]/(a[6]*a[12]); + rkc[119] = a[4]*a[15]/(a[6]*a[14]); + rkc[120] = a[7]*a[16]/(a[6]*a[17]); + rkc[121] = a[2]*a[14]/(a[3]*a[8]); + rkc[122] = a[1]*a[21]/(a[8]*a[10]); + rkc[123] = a[1]*a[22]/(a[8]*a[12]); + rkc[124] = a[2]*a[16]/(a[3]*a[9]); + rkc[125] = a[1]*a[10]/(a[0]*a[9]); + rkc[126] = a[1]*a[17]/(a[5]*a[9]); + rkc[127] = a[1]*a[22]/(a[9]*a[10]); + rkc[128] = a[1]*a[23]/(a[9]*a[12]); + rkc[129] = a[1]*a[24]/(a[9]*a[13]); + rkc[130] = a[27]*exp_c0/(a[9]*a[14]); + rkc[131] = a[14]*a[16]/(a[9]*a[15]); + rkc[132] = a[1]*a[28]/(a[9]*a[17]); + rkc[133] = a[14]*a[22]/(a[9]*a[27]); + rkc[135] = a[1]*a[12]/(a[0]*a[10]); + rkc[136] = a[0]*a[22]/(a[10]*a[10]); + rkc[137] = a[1]*a[24]/(a[10]*a[12]); + rkc[138] = a[12]*a[12]/(a[10]*a[13]); + rkc[139] = a[28]*exp_c0/(a[10]*a[14]); + rkc[140] = a[14]*a[23]/(a[10]*a[27]); + rkc[141] = a[10]*a[47]/(a[11]*a[47]); + rkc[142] = a[10]*a[48]/(a[11]*a[48]); + rkc[143] = a[1]*a[4]*a[14]/(a[3]*a[11]*exp_c0); + rkc[144] = a[5]*a[14]/(a[3]*a[11]); + rkc[145] = a[1]*a[12]/(a[0]*a[11]); + rkc[146] = a[20]*exp_c0/(a[5]*a[11]); + rkc[147] = a[5]*a[10]/(a[5]*a[11]); + rkc[148] = a[1]*a[24]/(a[11]*a[12]); + rkc[149] = a[12]*a[12]/(a[11]*a[13]); + rkc[150] = a[10]*a[14]/(a[11]*a[14]); + rkc[151] = a[10]*a[15]/(a[11]*a[15]); + rkc[152] = a[14]*a[17]/(a[11]*a[15]); + rkc[153] = a[12]*a[25]/(a[11]*a[26]); + rkc[154] = a[2]*a[19]/(a[3]*a[12]); + rkc[155] = a[4]*a[17]/(a[3]*a[12]); + rkc[156] = a[6]*a[13]/(a[7]*a[12]); + rkc[157] = a[26]*exp_c0/(a[12]*a[12]); + rkc[158] = a[1]*a[25]/(a[12]*a[12]); + rkc[159] = a[13]*a[14]/(a[12]*a[16]); + rkc[160] = a[13]*a[16]/(a[12]*a[17]); + rkc[161] = a[13]*a[18]/(a[12]*a[20]); + rkc[162] = a[13]*a[19]/(a[12]*a[20]); + rkc[163] = a[13]*a[23]/(a[12]*a[24]); + rkc[164] = a[13]*a[25]/(a[12]*a[26]); + rkc[165] = a[1]*a[5]*a[14]/(a[5]*a[16]*exp_c0); + rkc[166] = a[1]*a[14]/(a[16]*exp_c0); + rkc[167] = a[6]*a[14]/(a[3]*a[16]); + rkc[168] = a[6]*a[17]/(a[3]*a[18]); + rkc[169] = a[6]*a[17]/(a[3]*a[19]); + rkc[170] = a[14]*a[16]/(a[3]*a[21]); + rkc[171] = a[1]*a[22]/(a[0]*a[21]); + rkc[172] = a[16]*a[17]/(a[3]*a[23]); + rkc[173] = a[0]*a[22]/(a[24]*exp_c0); + rkc[174] = a[6]*a[24]/(a[3]*a[25]); + rkc[175] = a[4]*a[14]*a[14]/(a[3]*a[27]*exp_c0); + rkc[176] = a[14]*a[14]*a[22]/(a[27]*a[27]*exp_c0); + rkc[177] = a[2]*a[47]/(a[30]*a[35]); + rkc[178] = a[2]*a[35]/(a[3]*a[30]); + rkc[179] = a[1]*a[35]/(a[4]*a[30]); + rkc[180] = a[3]*a[47]/(a[2]*a[37]); + rkc[181] = a[35]*a[35]/(a[2]*a[37]); + rkc[182] = a[4]*a[47]/(a[1]*a[37]); + rkc[183] = a[6]*a[47]/(a[4]*a[37]); + rkc[184] = a[2]*a[47]/(a[37]*exp_c0); + rkc[185] = a[4]*a[36]/(a[6]*a[35]); + rkc[186] = a[36]*exp_c0/(a[2]*a[35]); + rkc[187] = a[3]*a[35]/(a[2]*a[36]); + rkc[188] = a[4]*a[35]/(a[1]*a[36]); + rkc[189] = a[1]*a[35]/(a[2]*a[31]); + rkc[190] = a[0]*a[30]/(a[1]*a[31]); + rkc[191] = a[1]*a[38]/(a[4]*a[31]); + rkc[192] = a[5]*a[30]/(a[4]*a[31]); + rkc[193] = a[2]*a[38]/(a[3]*a[31]); + rkc[194] = a[4]*a[35]/(a[3]*a[31]); + rkc[195] = a[1]*a[47]/(a[30]*a[31]); + rkc[196] = a[0]*a[38]/(a[5]*a[31]); + rkc[197] = a[4]*a[47]/(a[31]*a[35]); + rkc[198] = a[1]*a[37]/(a[31]*a[35]); + rkc[199] = a[4]*a[31]/(a[2]*a[32]); + rkc[200] = a[1]*a[38]/(a[2]*a[32]); + rkc[201] = a[0]*a[31]/(a[1]*a[32]); + rkc[202] = a[5]*a[31]/(a[4]*a[32]); + rkc[203] = a[1]*a[47]/(a[34]*exp_c0); + rkc[204] = a[1]*a[47]/(a[34]*exp_c0); + rkc[205] = a[6]*a[47]/(a[3]*a[34]); + rkc[206] = a[4]*a[47]/(a[2]*a[34]); + rkc[207] = a[31]*a[35]/(a[2]*a[34]); + rkc[208] = a[0]*a[47]/(a[1]*a[34]); + rkc[209] = a[5]*a[47]/(a[4]*a[34]); + rkc[210] = a[13]*a[47]/(a[12]*a[34]); + rkc[211] = a[38]*exp_c0/(a[1]*a[35]); + rkc[212] = a[4]*a[35]/(a[2]*a[38]); + rkc[213] = a[0]*a[35]/(a[1]*a[38]); + rkc[214] = a[5]*a[35]/(a[4]*a[38]); + rkc[215] = a[6]*a[35]/(a[3]*a[38]); + rkc[216] = a[14]*a[30]/(a[2]*a[39]); + rkc[217] = a[1]*a[46]/(a[4]*a[39]); + rkc[218] = a[4]*a[40]/(a[5]*a[39]); + rkc[219] = a[2]*a[46]/(a[3]*a[39]); + rkc[220] = a[1]*a[40]/(a[0]*a[39]); + rkc[221] = a[14]*a[35]/(a[2]*a[46]); + rkc[222] = a[14]*a[31]/(a[1]*a[46]); + rkc[223] = a[1]*a[14]*a[35]/(a[4]*a[46]*exp_c0); + rkc[224] = a[14]*a[47]/(a[30]*a[46]); + rkc[225] = a[15]*a[35]/(a[3]*a[46]); + rkc[226] = a[14]*a[30]/(a[46]*exp_c0); + rkc[227] = a[14]*a[37]/(a[35]*a[46]); + rkc[228] = a[15]*a[47]/(a[35]*a[46]); + rkc[229] = a[1]*a[39]/(a[40]*exp_c0); + rkc[230] = a[1]*a[46]/(a[2]*a[40]); + rkc[231] = a[14]*a[31]/(a[2]*a[40]); + rkc[232] = a[4]*a[39]/(a[2]*a[40]); + rkc[233] = a[1]*a[44]/(a[4]*a[40]); + rkc[234] = a[1]*a[45]/(a[4]*a[40]); + rkc[235] = a[14]*a[32]/(a[4]*a[40]); + rkc[236] = a[41]*exp_c0/(a[1]*a[40]); + rkc[237] = a[10]*a[47]/(a[30]*a[41]); + rkc[238] = a[30]*a[39]/(a[8]*a[47]); + rkc[239] = a[30]*a[40]/(a[9]*a[47]); + rkc[240] = a[42]*exp_c0/(a[9]*a[47]); + rkc[241] = a[31]*a[40]/(a[10]*a[47]); + rkc[242] = a[31]*a[40]/(a[11]*a[47]); + rkc[243] = a[2]*a[39]/(a[8]*a[35]); + rkc[244] = a[14]*a[30]/(a[8]*a[35]); + rkc[245] = a[2]*a[40]/(a[9]*a[35]); + rkc[246] = a[1]*a[46]/(a[9]*a[35]); + rkc[247] = a[16]*a[30]/(a[9]*a[35]); + rkc[248] = a[1]*a[45]/(a[10]*a[35]); + rkc[249] = a[4]*a[40]/(a[10]*a[35]); + rkc[250] = a[1]*a[43]/(a[10]*a[35]); + rkc[251] = a[1]*a[45]/(a[11]*a[35]); + rkc[252] = a[4]*a[40]/(a[11]*a[35]); + rkc[253] = a[1]*a[43]/(a[11]*a[35]); + rkc[254] = a[5]*a[40]/(a[12]*a[35]); + rkc[255] = a[4]*a[41]/(a[12]*a[35]); + rkc[256] = a[1]*a[14]*a[47]/(a[2]*a[42]*exp_c0); + rkc[257] = a[35]*a[40]/(a[2]*a[42]); + rkc[258] = a[2]*a[16]*a[47]/(a[3]*a[42]*exp_c0); + rkc[259] = a[1]*a[16]*a[47]/(a[4]*a[42]*exp_c0); + rkc[260] = a[10]*a[47]/(a[1]*a[42]); + rkc[261] = a[15]*a[31]/(a[2]*a[45]); + rkc[262] = a[14]*a[38]/(a[2]*a[45]); + rkc[263] = a[4]*a[46]/(a[2]*a[45]); + rkc[264] = a[14]*a[32]/(a[1]*a[45]); + rkc[265] = a[0]*a[46]/(a[1]*a[45]); + rkc[266] = a[5]*a[46]/(a[4]*a[45]); + rkc[267] = a[15]*a[32]/(a[4]*a[45]); + rkc[268] = a[14]*a[31]/(a[45]*exp_c0); + rkc[269] = a[1]*a[45]/(a[1]*a[43]); + rkc[270] = a[4]*a[40]/(a[1]*a[43]); + rkc[271] = a[14]*a[32]/(a[1]*a[43]); + rkc[272] = a[1]*a[45]/(a[1]*a[44]); + rkc[273] = a[14]*a[43]/(a[27]*a[35]); + rkc[274] = a[1]*a[41]/(a[12]*a[30]); + rkc[275] = a[0]*a[40]/(a[12]*a[30]); + rkc[276] = a[0]*a[32]/(a[1]*a[33]); + rkc[277] = a[5]*a[32]/(a[4]*a[33]); + rkc[278] = a[4]*a[32]/(a[2]*a[33]); + rkc[279] = a[14]*a[38]/(a[15]*a[31]); + rkc[280] = a[35]*a[46]/(a[36]*a[39]); + rkc[281] = a[15]*a[37]/(a[36]*a[46]); + rkc[282] = a[14]*a[35]/(a[15]*a[30]); + rkc[284] = a[1]*a[51]/(a[2]*a[24]); + rkc[285] = a[1]*a[52]/(a[2]*a[25]); + rkc[286] = a[3]*a[5]/(a[4]*a[6]); + rkc[288] = a[12]*exp_c0/(a[0]*a[9]); + rkc[290] = a[2]*a[17]/(a[3]*a[10]); + rkc[293] = a[2]*a[51]/(a[3]*a[23]); + rkc[294] = a[6]*a[22]/(a[3]*a[23]); + rkc[295] = a[4]*a[51]/(a[2]*a[52]); + rkc[298] = a[0]*a[51]/(a[1]*a[52]); + rkc[303] = a[51]*exp_c0/(a[1]*a[28]); + rkc[307] = a[12]*a[16]/(a[1]*a[51]); + rkc[308] = a[0]*a[28]/(a[1]*a[51]); + rkc[309] = a[5]*a[28]/(a[4]*a[51]); + rkc[310] = a[16]*a[18]/(a[4]*a[51]); + rkc[311] = a[50]*exp_c0/(a[12]*a[25]); + rkc[312] = a[4]*a[49]/(a[2]*a[50]); + rkc[313] = a[0]*a[49]/(a[1]*a[50]); + rkc[314] = a[5]*a[49]/(a[4]*a[50]); + rkc[315] = a[6]*a[50]/(a[7]*a[49]); + rkc[316] = a[13]*a[49]/(a[12]*a[50]); + rkc[317] = a[49]*exp_c0/(a[12]*a[24]); + rkc[318] = a[17]*a[25]/(a[2]*a[49]); + rkc[319] = a[50]*exp_c0/(a[1]*a[49]); + rkc[320] = a[12]*a[25]/(a[1]*a[49]); + rkc[321] = a[18]*a[25]/(a[4]*a[49]); + rkc[322] = a[3]*a[50]/(a[6]*a[49]); + rkc[324] = a[25]*a[25]/(a[12]*a[49]); + } + + + void GRI_30_Kinetics::get_wdot(const double* rop, double* wdot) { + wdot[0] = - rop[2] + rop[7] + rop[38] + rop[39] + rop[40] + rop[41] + rop[44] + rop[46] + rop[48] + rop[50] + rop[52] + rop[54] + rop[57] + rop[59] + rop[64] + rop[67] + rop[68] + rop[72] + rop[74] + rop[76] + rop[77] + rop[79] - rop[82] - rop[83] - rop[125] - rop[135] + rop[136] - rop[145] - rop[171] + rop[173] + rop[190] + rop[196] + rop[201] + rop[208] + rop[213] - rop[220] + rop[265] + rop[275] + rop[276] + rop[283] + rop[287] - rop[288] + rop[292] + rop[298] + rop[299] + rop[308] + rop[313]; + wdot[1] = - rop[1] + rop[2] + rop[5] + rop[6] + rop[8] + rop[9] + rop[13] + rop[20] + rop[23] + rop[27] - rop[32] - rop[33] - rop[34] - rop[35] - rop[36] - rop[37] - 2*rop[38] - 2*rop[39] - 2*rop[40] - 2*rop[41] - rop[42] - rop[43] - rop[44] - rop[45] - rop[46] - rop[47] - rop[48] - rop[49] - rop[50] - rop[51] - rop[52] - rop[53] - rop[54] - rop[55] - rop[56] - rop[57] - rop[58] - rop[59] - rop[60] - rop[61] - rop[62] - rop[64] - rop[65] - rop[66] - rop[67] - rop[68] - rop[69] - rop[70] - rop[71] - rop[72] - rop[73] - rop[74] - rop[75] - rop[76] - rop[77] - rop[78] - rop[79] - rop[80] + rop[83] + rop[89] + rop[90] + rop[91] + rop[93] + rop[98] + rop[105] + rop[106] + rop[107] + rop[122] + rop[123] + rop[125] + rop[126] + rop[127] + rop[128] + rop[129] + rop[132] + rop[134] + rop[135] + rop[137] + rop[143] + rop[145] + rop[148] + rop[158] + rop[165] + rop[166] + rop[171] + rop[179] - rop[182] - rop[188] + rop[189] - rop[190] + rop[191] + rop[195] + rop[198] + rop[200] - rop[201] + rop[203] + rop[204] - rop[208] - rop[211] - rop[213] + rop[217] + rop[220] - rop[222] + rop[223] + rop[229] + rop[230] + rop[233] + rop[234] - rop[236] + rop[246] + rop[248] + rop[250] + rop[251] + rop[253] + rop[256] + rop[259] - rop[260] - rop[264] - rop[265] - rop[270] - rop[271] + rop[274] - rop[276] + rop[283] + rop[284] + rop[285] + 2*rop[289] + 2*rop[291] - rop[298] - rop[299] - rop[303] + rop[304] - rop[307] - rop[308] - rop[313] - rop[319] - rop[320]; + wdot[2] = - 2*rop[0] - rop[1] - rop[2] - rop[3] - rop[4] - rop[5] - rop[6] - rop[7] - rop[8] - rop[9] - rop[10] - rop[11] - rop[12] - rop[13] - rop[14] - rop[15] - rop[16] - rop[17] - rop[18] - rop[19] - rop[20] - rop[21] - rop[22] - rop[23] - rop[24] - rop[25] - rop[26] - rop[27] - rop[28] - rop[29] + rop[30] + rop[37] + rop[43] + rop[85] + rop[121] + rop[124] + rop[154] + rop[177] + rop[178] - rop[180] - rop[181] + rop[184] - rop[186] - rop[187] - rop[189] + rop[193] - rop[199] - rop[200] - rop[206] - rop[207] - rop[212] - rop[216] + rop[219] - rop[221] - rop[230] - rop[231] - rop[232] + rop[243] + rop[245] - rop[256] - rop[257] + rop[258] - rop[261] - rop[262] - rop[263] - rop[278] - rop[283] - rop[284] - rop[285] + rop[290] + rop[293] - rop[295] - rop[296] - rop[304] - rop[312] - rop[318]; + wdot[3] = + rop[0] + rop[3] - rop[30] - rop[31] - rop[32] - rop[33] - rop[34] - rop[35] - rop[36] - rop[37] + rop[44] + rop[86] + rop[114] + rop[115] + rop[117] - rop[121] - rop[124] - rop[134] - rop[143] - rop[144] - rop[154] - rop[155] - rop[167] - rop[168] - rop[169] - rop[170] - rop[172] - rop[174] - rop[175] - rop[178] + rop[180] + rop[187] - rop[193] - rop[194] - rop[205] - rop[215] - rop[219] - rop[225] - rop[258] + rop[286] - rop[289] - rop[290] - rop[293] - rop[294] - rop[297] - rop[305] - rop[306] + rop[322]; + wdot[4] = + rop[1] + rop[2] + rop[3] + rop[4] + rop[10] + rop[12] + rop[14] + rop[15] + rop[16] + rop[17] + rop[18] + rop[21] + rop[26] + rop[28] + rop[37] - rop[42] + 2*rop[45] + rop[47] + rop[60] + rop[65] - rop[83] - 2*rop[84] - 2*rop[85] - rop[86] - rop[87] - rop[88] - rop[89] - rop[90] - rop[91] - rop[92] - rop[93] - rop[94] - rop[95] - rop[96] - rop[97] - rop[98] - rop[99] - rop[100] - rop[101] - rop[102] - rop[103] - rop[104] - rop[105] - rop[106] - rop[107] - rop[108] - rop[109] - rop[110] - rop[111] - rop[112] - rop[113] + rop[116] + rop[118] + rop[119] + rop[134] + rop[143] + rop[155] + rop[175] - rop[179] + rop[182] - rop[183] + rop[185] + rop[188] - rop[191] - rop[192] + rop[194] + rop[197] + rop[199] - rop[202] + rop[206] - rop[209] + rop[212] - rop[214] - rop[217] + rop[218] - rop[223] + rop[232] - rop[233] - rop[234] - rop[235] + rop[249] + rop[252] + rop[255] - rop[259] + rop[263] - rop[266] - rop[267] + rop[270] - rop[277] + rop[278] - rop[286] - rop[287] + rop[295] + rop[296] - rop[300] + rop[305] + rop[306] - rop[309] - rop[310] + rop[312] - rop[314] - rop[321] + rop[323]; + wdot[5] = + rop[42] + rop[43] + rop[47] + rop[61] + rop[66] + rop[83] + rop[85] + rop[86] + rop[87] + rop[88] + rop[92] + rop[95] + rop[96] + rop[97] + rop[99] + rop[100] + rop[101] + rop[102] + rop[103] + rop[104] + rop[108] + rop[110] + rop[111] + rop[112] + rop[113] - rop[126] + rop[144] - rop[146] + rop[192] - rop[196] + rop[202] + rop[209] + rop[214] - rop[218] + rop[254] + rop[266] + rop[277] + rop[286] - rop[292] + rop[300] + rop[309] + rop[314]; + wdot[6] = - rop[3] + rop[4] + rop[31] + rop[32] + rop[33] + rop[34] + rop[35] + rop[36] - rop[43] - rop[44] - rop[45] + rop[46] - rop[86] + rop[87] + rop[88] - 2*rop[114] - 2*rop[115] - rop[116] - rop[117] - rop[118] - rop[119] - rop[120] + rop[156] + rop[167] + rop[168] + rop[169] + rop[174] + rop[183] - rop[185] + rop[205] + rop[215] - rop[286] + rop[294] + rop[297] - rop[301] + rop[315] - rop[322] - rop[323]; + wdot[7] = - rop[4] - rop[46] - rop[47] + rop[84] - rop[87] - rop[88] + rop[114] + rop[115] + rop[120] - rop[156] + rop[301] - rop[315]; + wdot[8] = + rop[48] - rop[89] - rop[121] - rop[122] - rop[123] - rop[238] - rop[243] - rop[244]; + wdot[9] = - rop[5] + rop[19] - rop[48] + rop[50] - rop[90] + rop[92] - rop[124] - rop[125] - rop[126] - rop[127] - rop[128] - rop[129] - rop[130] - rop[131] - rop[132] - rop[133] - rop[239] - rop[240] - rop[245] - rop[246] - rop[247] - rop[288]; + wdot[10] = - rop[6] + rop[22] + rop[29] - rop[49] - rop[91] - rop[92] + rop[95] - rop[116] - rop[122] + rop[125] - rop[127] - rop[134] - rop[135] - 2*rop[136] - rop[137] - rop[138] - rop[139] - rop[140] + rop[141] + rop[142] + rop[147] + rop[150] + rop[151] + rop[237] - rop[241] - rop[248] - rop[249] - rop[250] + rop[260] - rop[289] - rop[290] - 2*rop[291] + rop[304]; + wdot[11] = - rop[7] - rop[8] - rop[50] + rop[61] + rop[66] + rop[78] - rop[93] + rop[96] - rop[141] - rop[142] - rop[143] - rop[144] - rop[145] - rop[146] - rop[147] - rop[148] - rop[149] - rop[150] - rop[151] - rop[152] - rop[153] - rop[242] - rop[251] - rop[252] - rop[253] - rop[292]; + wdot[12] = - rop[9] + rop[10] + rop[24] + rop[25] + rop[49] - rop[51] + rop[52] + rop[60] + rop[65] + rop[80] - rop[94] - rop[95] - rop[96] + rop[97] + rop[109] - rop[117] - rop[118] - rop[123] - rop[128] + rop[135] - rop[137] + 2*rop[138] + rop[145] - rop[148] + 2*rop[149] + rop[153] - rop[154] - rop[155] - rop[156] - 2*rop[157] - 2*rop[158] - rop[159] - rop[160] - rop[161] - rop[162] - rop[163] - rop[164] - rop[210] - rop[254] - rop[255] - rop[274] - rop[275] - rop[283] - rop[287] + rop[288] + rop[296] + rop[297] + rop[299] + rop[300] + rop[301] + rop[307] - rop[311] - rop[316] - rop[317] + rop[320] - rop[324]; + wdot[13] = - rop[10] + rop[51] - rop[52] - rop[97] + rop[117] - rop[129] - rop[138] - rop[149] + rop[156] + rop[159] + rop[160] + rop[161] + rop[162] + rop[163] + rop[164] + rop[210] + rop[302] + rop[316]; + wdot[14] = + rop[5] + rop[7] - rop[11] + rop[12] + rop[19] + rop[22] + 2*rop[27] - rop[30] + rop[54] + rop[78] + rop[80] - rop[82] + rop[89] - rop[98] + rop[99] + rop[109] - rop[119] + rop[121] - rop[130] + rop[131] + rop[133] + rop[134] - rop[139] + rop[140] + rop[143] + rop[144] + rop[152] + rop[159] + rop[165] + rop[166] + rop[167] + rop[170] + 2*rop[175] + 2*rop[176] + rop[216] + rop[221] + rop[222] + rop[223] + rop[224] + rop[226] + rop[227] + rop[231] + rop[235] + rop[244] + rop[256] + rop[262] + rop[264] + rop[268] + rop[271] + rop[273] + rop[279] + rop[282] + rop[283] + rop[296] + rop[297] + rop[299] + rop[300] + rop[301] + rop[302] + rop[305]; + wdot[15] = + rop[11] + rop[13] + rop[29] + rop[30] + rop[98] + rop[119] - rop[131] - rop[152] + rop[225] + rop[228] + rop[261] + rop[267] - rop[279] + rop[281] - rop[282] + rop[289] + rop[304]; + wdot[16] = + rop[6] + rop[8] - rop[12] - rop[13] + rop[14] + rop[24] + rop[31] - rop[53] - rop[54] + rop[57] + rop[90] - rop[99] + rop[100] + rop[120] + rop[124] + rop[131] - rop[159] + rop[160] - rop[165] - rop[166] - rop[167] + rop[170] + rop[172] + rop[247] + rop[258] + rop[259] + 2*rop[306] + rop[307] + rop[310]; + wdot[17] = + rop[9] - rop[14] + rop[15] + rop[16] + rop[25] - rop[31] + rop[53] - rop[55] - rop[56] - rop[57] + rop[59] + rop[64] + rop[82] + rop[91] + rop[93] - rop[100] + rop[101] + rop[102] + rop[116] - rop[120] + rop[126] - rop[132] + rop[152] + rop[155] - rop[160] + rop[168] + rop[169] + rop[172] + rop[287] + rop[290] + rop[292] + rop[305] + rop[318] + rop[323]; + wdot[18] = - rop[15] + rop[17] + rop[55] - rop[58] - rop[59] - rop[60] - rop[61] + rop[63] + rop[67] - rop[101] + rop[103] + rop[161] - rop[168] + rop[310] + rop[321]; + wdot[19] = - rop[16] + rop[18] + rop[56] - rop[62] - rop[63] - rop[64] - rop[65] - rop[66] + rop[68] - rop[102] + rop[104] + rop[118] + rop[154] + rop[162] - rop[169]; + wdot[20] = - rop[17] - rop[18] + rop[58] + rop[62] - rop[67] - rop[68] + rop[94] - rop[103] - rop[104] + rop[146] - rop[161] - rop[162]; + wdot[21] = - rop[19] + rop[21] - rop[69] - rop[105] + rop[108] + rop[122] - rop[170] - rop[171]; + wdot[22] = - rop[20] - rop[21] - rop[22] + rop[69] - rop[70] + rop[72] - rop[106] - rop[107] - rop[108] - rop[109] + rop[110] + rop[123] + rop[127] + rop[133] + rop[136] + rop[171] + rop[173] + rop[176] + rop[291] + rop[294]; + wdot[23] = - rop[23] + rop[70] - rop[71] - rop[72] + rop[74] - rop[110] + rop[111] + rop[128] + rop[140] + rop[163] - rop[172] - rop[293] - rop[294]; + wdot[24] = - rop[24] + rop[71] - rop[73] - rop[74] + rop[76] - rop[111] + rop[129] + rop[137] + rop[148] - rop[163] - rop[173] + rop[174] - rop[284] - rop[317]; + wdot[25] = - rop[25] + rop[26] + rop[73] - rop[75] - rop[76] + rop[77] + rop[112] + rop[153] + rop[158] + rop[164] - rop[174] - rop[285] - rop[311] + rop[318] + rop[320] + rop[321] + rop[323] + 2*rop[324]; + wdot[26] = - rop[26] + rop[75] - rop[77] - rop[112] - rop[153] + rop[157] - rop[164]; + wdot[27] = + rop[20] - rop[27] + rop[28] - rop[78] + rop[79] + rop[105] + rop[113] + rop[130] - rop[133] - rop[140] - rop[175] - 2*rop[176] - rop[273]; + wdot[28] = + rop[23] - rop[28] - rop[29] - rop[79] - rop[80] + rop[81] + rop[106] - rop[113] + rop[132] + rop[139] - rop[303] + rop[308] + rop[309]; + wdot[29] = - rop[81] + rop[107]; + wdot[30] = - rop[177] - rop[178] - rop[179] + rop[190] + rop[192] - rop[195] + rop[216] - rop[224] + rop[226] - rop[237] + rop[238] + rop[239] + rop[244] + rop[247] - rop[274] - rop[275] - rop[282]; + wdot[31] = - rop[189] - rop[190] - rop[191] - rop[192] - rop[193] - rop[194] - rop[195] - rop[196] - rop[197] - rop[198] + rop[199] + rop[201] + rop[202] + rop[207] + rop[222] + rop[231] + rop[241] + rop[242] + rop[261] + rop[268] - rop[279]; + wdot[32] = - rop[199] - rop[200] - rop[201] - rop[202] + rop[235] + rop[264] + rop[267] + rop[271] + rop[276] + rop[277] + rop[278]; + wdot[33] = - rop[276] - rop[277] - rop[278]; + wdot[34] = - rop[203] - rop[204] - rop[205] - rop[206] - rop[207] - rop[208] - rop[209] - rop[210]; + wdot[35] = - rop[177] + rop[178] + rop[179] + 2*rop[181] - rop[185] - rop[186] + rop[187] + rop[188] + rop[189] + rop[194] - rop[197] - rop[198] + rop[207] - rop[211] + rop[212] + rop[213] + rop[214] + rop[215] + rop[221] + rop[223] + rop[225] - rop[227] - rop[228] - rop[243] - rop[244] - rop[245] - rop[246] - rop[247] - rop[248] - rop[249] - rop[250] - rop[251] - rop[252] - rop[253] - rop[254] - rop[255] + rop[257] - rop[273] + rop[280] + rop[282]; + wdot[36] = + rop[185] + rop[186] - rop[187] - rop[188] - rop[280] - rop[281]; + wdot[37] = - rop[180] - rop[181] - rop[182] - rop[183] - rop[184] + rop[198] + rop[227] + rop[281]; + wdot[38] = + rop[191] + rop[193] + rop[196] + rop[200] + rop[211] - rop[212] - rop[213] - rop[214] - rop[215] + rop[262] + rop[279]; + wdot[39] = - rop[216] - rop[217] - rop[218] - rop[219] - rop[220] + rop[229] + rop[232] + rop[238] + rop[243] - rop[280]; + wdot[40] = + rop[218] + rop[220] - rop[229] - rop[230] - rop[231] - rop[232] - rop[233] - rop[234] - rop[235] - rop[236] + rop[239] + rop[241] + rop[242] + rop[245] + rop[249] + rop[252] + rop[254] + rop[257] + rop[270] + rop[275]; + wdot[41] = + rop[236] - rop[237] + rop[255] + rop[274]; + wdot[42] = + rop[240] - rop[256] - rop[257] - rop[258] - rop[259] - rop[260]; + wdot[43] = + rop[250] + rop[253] - rop[269] - rop[270] - rop[271] + rop[273]; + wdot[44] = + rop[233] - rop[272]; + wdot[45] = + rop[234] + rop[248] + rop[251] - rop[261] - rop[262] - rop[263] - rop[264] - rop[265] - rop[266] - rop[267] - rop[268] + rop[269] + rop[272]; + wdot[46] = + rop[217] + rop[219] - rop[221] - rop[222] - rop[223] - rop[224] - rop[225] - rop[226] - rop[227] - rop[228] + rop[230] + rop[246] + rop[263] + rop[265] + rop[266] + rop[280] - rop[281]; + wdot[47] = + rop[177] + rop[180] + rop[182] + rop[183] + rop[184] + rop[195] + rop[197] + rop[203] + rop[204] + rop[205] + rop[206] + rop[208] + rop[209] + rop[210] + rop[224] + rop[228] + rop[237] - rop[238] - rop[239] - rop[240] - rop[241] - rop[242] + rop[256] + rop[258] + rop[259] + rop[260]; + wdot[48] = 0.0; + wdot[49] = + rop[312] + rop[313] + rop[314] - rop[315] + rop[316] + rop[317] - rop[318] - rop[319] - rop[320] - rop[321] - rop[322] - rop[323] - rop[324]; + wdot[50] = + rop[311] - rop[312] - rop[313] - rop[314] + rop[315] - rop[316] + rop[319] + rop[322]; + wdot[51] = + rop[284] + rop[293] + rop[295] + rop[298] + rop[303] - rop[304] - rop[305] - rop[306] - rop[307] - rop[308] - rop[309] - rop[310]; + wdot[52] = + rop[285] - rop[295] - rop[296] - rop[297] - rop[298] - rop[299] - rop[300] - rop[301] - rop[302]; + } + + + void GRI_30_Kinetics::eval_ropnet(const double* c, const double* rf, const double* rkc, double* r) { + r[0] = rf[0] * (c[2] * c[2] - rkc[0] * c[3]); + r[1] = rf[1] * (c[2] * c[1] - rkc[1] * c[4]); + r[2] = rf[2] * (c[2] * c[0] - rkc[2] * c[1] * c[4]); + r[3] = rf[3] * (c[2] * c[6] - rkc[3] * c[4] * c[3]); + r[4] = rf[4] * (c[2] * c[7] - rkc[4] * c[4] * c[6]); + r[5] = rf[5] * (c[2] * c[9] - rkc[5] * c[1] * c[14]); + r[6] = rf[6] * (c[2] * c[10] - rkc[6] * c[1] * c[16]); + r[7] = rf[7] * (c[2] * c[11] - rkc[7] * c[0] * c[14]); + r[8] = rf[8] * (c[2] * c[11] - rkc[8] * c[1] * c[16]); + r[9] = rf[9] * (c[2] * c[12] - rkc[9] * c[1] * c[17]); + r[10] = rf[10] * (c[2] * c[13] - rkc[10] * c[4] * c[12]); + r[11] = rf[11] * (c[2] * c[14] - rkc[11] * c[15]); + r[12] = rf[12] * (c[2] * c[16] - rkc[12] * c[4] * c[14]); + r[13] = rf[13] * (c[2] * c[16] - rkc[13] * c[1] * c[15]); + r[14] = rf[14] * (c[2] * c[17] - rkc[14] * c[4] * c[16]); + r[15] = rf[15] * (c[2] * c[18] - rkc[15] * c[4] * c[17]); + r[16] = rf[16] * (c[2] * c[19] - rkc[16] * c[4] * c[17]); + r[17] = rf[17] * (c[2] * c[20] - rkc[17] * c[4] * c[18]); + r[18] = rf[18] * (c[2] * c[20] - rkc[18] * c[4] * c[19]); + r[19] = rf[19] * (c[2] * c[21] - rkc[19] * c[9] * c[14]); + r[20] = rf[20] * (c[2] * c[22] - rkc[20] * c[1] * c[27]); + r[21] = rf[21] * (c[2] * c[22] - rkc[21] * c[4] * c[21]); + r[22] = rf[22] * (c[2] * c[22] - rkc[22] * c[14] * c[10]); + r[23] = rf[23] * (c[2] * c[23] - rkc[23] * c[1] * c[28]); + r[24] = rf[24] * (c[2] * c[24] - rkc[24] * c[12] * c[16]); + r[25] = rf[25] * (c[2] * c[25] - rkc[25] * c[12] * c[17]); + r[26] = rf[26] * (c[2] * c[26] - rkc[26] * c[4] * c[25]); + r[27] = rf[27] * (c[2] * c[27] - rkc[27] * c[1] * c[14] * c[14]); + r[28] = rf[28] * (c[2] * c[28] - rkc[28] * c[4] * c[27]); + r[29] = rf[29] * (c[2] * c[28] - rkc[29] * c[10] * c[15]); + r[30] = rf[30] * (c[3] * c[14] - rkc[30] * c[2] * c[15]); + r[31] = rf[31] * (c[3] * c[17] - rkc[31] * c[6] * c[16]); + r[32] = rf[32] * (c[1] * c[3] - rkc[32] * c[6]); + r[33] = rf[33] * (c[1] * c[3] * c[3] - rkc[33] * c[6] * c[3]); + r[34] = rf[34] * (c[1] * c[3] * c[5] - rkc[34] * c[6] * c[5]); + r[35] = rf[35] * (c[1] * c[3] * c[47] - rkc[35] * c[6] * c[47]); + r[36] = rf[36] * (c[1] * c[3] * c[48] - rkc[36] * c[6] * c[48]); + r[37] = rf[37] * (c[1] * c[3] - rkc[37] * c[2] * c[4]); + r[38] = rf[38] * (c[1] * c[1] - rkc[38] * c[0]); + r[39] = rf[39] * (c[1] * c[1] * c[0] - rkc[39] * c[0] * c[0]); + r[40] = rf[40] * (c[1] * c[1] * c[5] - rkc[40] * c[0] * c[5]); + r[41] = rf[41] * (c[1] * c[1] * c[15] - rkc[41] * c[0] * c[15]); + r[42] = rf[42] * (c[1] * c[4] - rkc[42] * c[5]); + r[43] = rf[43] * (c[1] * c[6] - rkc[43] * c[2] * c[5]); + r[44] = rf[44] * (c[1] * c[6] - rkc[44] * c[3] * c[0]); + r[45] = rf[45] * (c[1] * c[6] - rkc[45] * c[4] * c[4]); + r[46] = rf[46] * (c[1] * c[7] - rkc[46] * c[6] * c[0]); + r[47] = rf[47] * (c[1] * c[7] - rkc[47] * c[4] * c[5]); + r[48] = rf[48] * (c[1] * c[9] - rkc[48] * c[8] * c[0]); + r[49] = rf[49] * (c[1] * c[10] - rkc[49] * c[12]); + r[50] = rf[50] * (c[1] * c[11] - rkc[50] * c[9] * c[0]); + r[51] = rf[51] * (c[1] * c[12] - rkc[51] * c[13]); + r[52] = rf[52] * (c[1] * c[13] - rkc[52] * c[12] * c[0]); + r[53] = rf[53] * (c[1] * c[16] - rkc[53] * c[17]); + r[54] = rf[54] * (c[1] * c[16] - rkc[54] * c[0] * c[14]); + r[55] = rf[55] * (c[1] * c[17] - rkc[55] * c[18]); + r[56] = rf[56] * (c[1] * c[17] - rkc[56] * c[19]); + r[57] = rf[57] * (c[1] * c[17] - rkc[57] * c[16] * c[0]); + r[58] = rf[58] * (c[1] * c[18] - rkc[58] * c[20]); + r[59] = rf[59] * (c[1] * c[18] - rkc[59] * c[0] * c[17]); + r[60] = rf[60] * (c[1] * c[18] - rkc[60] * c[4] * c[12]); + r[61] = rf[61] * (c[1] * c[18] - rkc[61] * c[11] * c[5]); + r[62] = rf[62] * (c[1] * c[19] - rkc[62] * c[20]); + r[63] = rf[63] * (c[1] * c[19] - rkc[63] * c[1] * c[18]); + r[64] = rf[64] * (c[1] * c[19] - rkc[64] * c[0] * c[17]); + r[65] = rf[65] * (c[1] * c[19] - rkc[65] * c[4] * c[12]); + r[66] = rf[66] * (c[1] * c[19] - rkc[66] * c[11] * c[5]); + r[67] = rf[67] * (c[1] * c[20] - rkc[67] * c[18] * c[0]); + r[68] = rf[68] * (c[1] * c[20] - rkc[68] * c[19] * c[0]); + r[69] = rf[69] * (c[1] * c[21] - rkc[69] * c[22]); + r[70] = rf[70] * (c[1] * c[22] - rkc[70] * c[23]); + r[71] = rf[71] * (c[1] * c[23] - rkc[71] * c[24]); + r[72] = rf[72] * (c[1] * c[23] - rkc[72] * c[0] * c[22]); + r[73] = rf[73] * (c[1] * c[24] - rkc[73] * c[25]); + r[74] = rf[74] * (c[1] * c[24] - rkc[74] * c[23] * c[0]); + r[75] = rf[75] * (c[1] * c[25] - rkc[75] * c[26]); + r[76] = rf[76] * (c[1] * c[25] - rkc[76] * c[0] * c[24]); + r[77] = rf[77] * (c[1] * c[26] - rkc[77] * c[25] * c[0]); + r[78] = rf[78] * (c[1] * c[27] - rkc[78] * c[11] * c[14]); + r[79] = rf[79] * (c[1] * c[28] - rkc[79] * c[27] * c[0]); + r[80] = rf[80] * (c[1] * c[28] - rkc[80] * c[12] * c[14]); + r[81] = rf[81] * (c[1] * c[29] - rkc[81] * c[1] * c[28]); + r[82] = rf[82] * (c[0] * c[14] - rkc[82] * c[17]); + r[83] = rf[83] * (c[4] * c[0] - rkc[83] * c[1] * c[5]); + r[84] = rf[84] * (c[4] * c[4] - rkc[84] * c[7]); + r[85] = rf[85] * (c[4] * c[4] - rkc[85] * c[2] * c[5]); + r[86] = rf[86] * (c[4] * c[6] - rkc[86] * c[3] * c[5]); + r[87] = rf[87] * (c[4] * c[7] - rkc[87] * c[6] * c[5]); + r[88] = rf[88] * (c[4] * c[7] - rkc[88] * c[6] * c[5]); + r[89] = rf[89] * (c[4] * c[8] - rkc[89] * c[1] * c[14]); + r[90] = rf[90] * (c[4] * c[9] - rkc[90] * c[1] * c[16]); + r[91] = rf[91] * (c[4] * c[10] - rkc[91] * c[1] * c[17]); + r[92] = rf[92] * (c[4] * c[10] - rkc[92] * c[9] * c[5]); + r[93] = rf[93] * (c[4] * c[11] - rkc[93] * c[1] * c[17]); + r[94] = rf[94] * (c[4] * c[12] - rkc[94] * c[20]); + r[95] = rf[95] * (c[4] * c[12] - rkc[95] * c[10] * c[5]); + r[96] = rf[96] * (c[4] * c[12] - rkc[96] * c[11] * c[5]); + r[97] = rf[97] * (c[4] * c[13] - rkc[97] * c[12] * c[5]); + r[98] = rf[98] * (c[4] * c[14] - rkc[98] * c[1] * c[15]); + r[99] = rf[99] * (c[4] * c[16] - rkc[99] * c[5] * c[14]); + r[100] = rf[100] * (c[4] * c[17] - rkc[100] * c[16] * c[5]); + r[101] = rf[101] * (c[4] * c[18] - rkc[101] * c[5] * c[17]); + r[102] = rf[102] * (c[4] * c[19] - rkc[102] * c[5] * c[17]); + r[103] = rf[103] * (c[4] * c[20] - rkc[103] * c[18] * c[5]); + r[104] = rf[104] * (c[4] * c[20] - rkc[104] * c[19] * c[5]); + r[105] = rf[105] * (c[4] * c[21] - rkc[105] * c[1] * c[27]); + r[106] = rf[106] * (c[4] * c[22] - rkc[106] * c[1] * c[28]); + r[107] = rf[107] * (c[4] * c[22] - rkc[107] * c[1] * c[29]); + r[108] = rf[108] * (c[4] * c[22] - rkc[108] * c[21] * c[5]); + r[109] = rf[109] * (c[4] * c[22] - rkc[109] * c[12] * c[14]); + r[110] = rf[110] * (c[4] * c[23] - rkc[110] * c[5] * c[22]); + r[111] = rf[111] * (c[4] * c[24] - rkc[111] * c[23] * c[5]); + r[112] = rf[112] * (c[4] * c[26] - rkc[112] * c[25] * c[5]); + r[113] = rf[113] * (c[4] * c[28] - rkc[113] * c[27] * c[5]); + r[114] = rf[114] * (c[6] * c[6] - rkc[114] * c[3] * c[7]); + r[115] = rf[115] * (c[6] * c[6] - rkc[115] * c[3] * c[7]); + r[116] = rf[116] * (c[6] * c[10] - rkc[116] * c[4] * c[17]); + r[117] = rf[117] * (c[6] * c[12] - rkc[117] * c[3] * c[13]); + r[118] = rf[118] * (c[6] * c[12] - rkc[118] * c[4] * c[19]); + r[119] = rf[119] * (c[6] * c[14] - rkc[119] * c[4] * c[15]); + r[120] = rf[120] * (c[6] * c[17] - rkc[120] * c[16] * c[7]); + r[121] = rf[121] * (c[8] * c[3] - rkc[121] * c[2] * c[14]); + r[122] = rf[122] * (c[8] * c[10] - rkc[122] * c[1] * c[21]); + r[123] = rf[123] * (c[8] * c[12] - rkc[123] * c[1] * c[22]); + r[124] = rf[124] * (c[9] * c[3] - rkc[124] * c[2] * c[16]); + r[125] = rf[125] * (c[9] * c[0] - rkc[125] * c[1] * c[10]); + r[126] = rf[126] * (c[9] * c[5] - rkc[126] * c[1] * c[17]); + r[127] = rf[127] * (c[9] * c[10] - rkc[127] * c[1] * c[22]); + r[128] = rf[128] * (c[9] * c[12] - rkc[128] * c[1] * c[23]); + r[129] = rf[129] * (c[9] * c[13] - rkc[129] * c[1] * c[24]); + r[130] = rf[130] * (c[9] * c[14] - rkc[130] * c[27]); + r[131] = rf[131] * (c[9] * c[15] - rkc[131] * c[16] * c[14]); + r[132] = rf[132] * (c[9] * c[17] - rkc[132] * c[1] * c[28]); + r[133] = rf[133] * (c[9] * c[27] - rkc[133] * c[14] * c[22]); + r[134] = rf[134] * (c[10] * c[3]); + r[135] = rf[135] * (c[10] * c[0] - rkc[135] * c[1] * c[12]); + r[136] = rf[136] * (c[10] * c[10] - rkc[136] * c[0] * c[22]); + r[137] = rf[137] * (c[10] * c[12] - rkc[137] * c[1] * c[24]); + r[138] = rf[138] * (c[10] * c[13] - rkc[138] * c[12] * c[12]); + r[139] = rf[139] * (c[10] * c[14] - rkc[139] * c[28]); + r[140] = rf[140] * (c[10] * c[27] - rkc[140] * c[23] * c[14]); + r[141] = rf[141] * (c[11] * c[47] - rkc[141] * c[10] * c[47]); + r[142] = rf[142] * (c[11] * c[48] - rkc[142] * c[10] * c[48]); + r[143] = rf[143] * (c[11] * c[3] - rkc[143] * c[1] * c[4] * c[14]); + r[144] = rf[144] * (c[11] * c[3] - rkc[144] * c[14] * c[5]); + r[145] = rf[145] * (c[11] * c[0] - rkc[145] * c[12] * c[1]); + r[146] = rf[146] * (c[11] * c[5] - rkc[146] * c[20]); + r[147] = rf[147] * (c[11] * c[5] - rkc[147] * c[10] * c[5]); + r[148] = rf[148] * (c[11] * c[12] - rkc[148] * c[1] * c[24]); + r[149] = rf[149] * (c[11] * c[13] - rkc[149] * c[12] * c[12]); + r[150] = rf[150] * (c[11] * c[14] - rkc[150] * c[10] * c[14]); + r[151] = rf[151] * (c[11] * c[15] - rkc[151] * c[10] * c[15]); + r[152] = rf[152] * (c[11] * c[15] - rkc[152] * c[14] * c[17]); + r[153] = rf[153] * (c[11] * c[26] - rkc[153] * c[12] * c[25]); + r[154] = rf[154] * (c[12] * c[3] - rkc[154] * c[2] * c[19]); + r[155] = rf[155] * (c[12] * c[3] - rkc[155] * c[4] * c[17]); + r[156] = rf[156] * (c[12] * c[7] - rkc[156] * c[6] * c[13]); + r[157] = rf[157] * (c[12] * c[12] - rkc[157] * c[26]); + r[158] = rf[158] * (c[12] * c[12] - rkc[158] * c[1] * c[25]); + r[159] = rf[159] * (c[12] * c[16] - rkc[159] * c[13] * c[14]); + r[160] = rf[160] * (c[12] * c[17] - rkc[160] * c[16] * c[13]); + r[161] = rf[161] * (c[12] * c[20] - rkc[161] * c[18] * c[13]); + r[162] = rf[162] * (c[12] * c[20] - rkc[162] * c[19] * c[13]); + r[163] = rf[163] * (c[12] * c[24] - rkc[163] * c[23] * c[13]); + r[164] = rf[164] * (c[12] * c[26] - rkc[164] * c[25] * c[13]); + r[165] = rf[165] * (c[16] * c[5] - rkc[165] * c[1] * c[14] * c[5]); + r[166] = rf[166] * (c[16] - rkc[166] * c[1] * c[14]); + r[167] = rf[167] * (c[16] * c[3] - rkc[167] * c[6] * c[14]); + r[168] = rf[168] * (c[18] * c[3] - rkc[168] * c[6] * c[17]); + r[169] = rf[169] * (c[19] * c[3] - rkc[169] * c[6] * c[17]); + r[170] = rf[170] * (c[21] * c[3] - rkc[170] * c[16] * c[14]); + r[171] = rf[171] * (c[21] * c[0] - rkc[171] * c[1] * c[22]); + r[172] = rf[172] * (c[23] * c[3] - rkc[172] * c[16] * c[17]); + r[173] = rf[173] * (c[24] - rkc[173] * c[0] * c[22]); + r[174] = rf[174] * (c[25] * c[3] - rkc[174] * c[6] * c[24]); + r[175] = rf[175] * (c[27] * c[3] - rkc[175] * c[4] * c[14] * c[14]); + r[176] = rf[176] * (c[27] * c[27] - rkc[176] * c[14] * c[14] * c[22]); + r[177] = rf[177] * (c[30] * c[35] - rkc[177] * c[47] * c[2]); + r[178] = rf[178] * (c[30] * c[3] - rkc[178] * c[35] * c[2]); + r[179] = rf[179] * (c[30] * c[4] - rkc[179] * c[35] * c[1]); + r[180] = rf[180] * (c[37] * c[2] - rkc[180] * c[47] * c[3]); + r[181] = rf[181] * (c[37] * c[2] - rkc[181] * c[35] * c[35]); + r[182] = rf[182] * (c[37] * c[1] - rkc[182] * c[47] * c[4]); + r[183] = rf[183] * (c[37] * c[4] - rkc[183] * c[47] * c[6]); + r[184] = rf[184] * (c[37] - rkc[184] * c[47] * c[2]); + r[185] = rf[185] * (c[6] * c[35] - rkc[185] * c[36] * c[4]); + r[186] = rf[186] * (c[35] * c[2] - rkc[186] * c[36]); + r[187] = rf[187] * (c[36] * c[2] - rkc[187] * c[35] * c[3]); + r[188] = rf[188] * (c[36] * c[1] - rkc[188] * c[35] * c[4]); + r[189] = rf[189] * (c[31] * c[2] - rkc[189] * c[35] * c[1]); + r[190] = rf[190] * (c[31] * c[1] - rkc[190] * c[30] * c[0]); + r[191] = rf[191] * (c[31] * c[4] - rkc[191] * c[38] * c[1]); + r[192] = rf[192] * (c[31] * c[4] - rkc[192] * c[30] * c[5]); + r[193] = rf[193] * (c[31] * c[3] - rkc[193] * c[38] * c[2]); + r[194] = rf[194] * (c[31] * c[3] - rkc[194] * c[35] * c[4]); + r[195] = rf[195] * (c[31] * c[30] - rkc[195] * c[47] * c[1]); + r[196] = rf[196] * (c[31] * c[5] - rkc[196] * c[38] * c[0]); + r[197] = rf[197] * (c[31] * c[35] - rkc[197] * c[47] * c[4]); + r[198] = rf[198] * (c[31] * c[35] - rkc[198] * c[37] * c[1]); + r[199] = rf[199] * (c[32] * c[2] - rkc[199] * c[4] * c[31]); + r[200] = rf[200] * (c[32] * c[2] - rkc[200] * c[1] * c[38]); + r[201] = rf[201] * (c[32] * c[1] - rkc[201] * c[31] * c[0]); + r[202] = rf[202] * (c[32] * c[4] - rkc[202] * c[31] * c[5]); + r[203] = rf[203] * (c[34] - rkc[203] * c[47] * c[1]); + r[204] = rf[204] * (c[34] - rkc[204] * c[47] * c[1]); + r[205] = rf[205] * (c[34] * c[3] - rkc[205] * c[6] * c[47]); + r[206] = rf[206] * (c[34] * c[2] - rkc[206] * c[4] * c[47]); + r[207] = rf[207] * (c[34] * c[2] - rkc[207] * c[31] * c[35]); + r[208] = rf[208] * (c[34] * c[1] - rkc[208] * c[0] * c[47]); + r[209] = rf[209] * (c[34] * c[4] - rkc[209] * c[5] * c[47]); + r[210] = rf[210] * (c[34] * c[12] - rkc[210] * c[13] * c[47]); + r[211] = rf[211] * (c[1] * c[35] - rkc[211] * c[38]); + r[212] = rf[212] * (c[38] * c[2] - rkc[212] * c[35] * c[4]); + r[213] = rf[213] * (c[38] * c[1] - rkc[213] * c[0] * c[35]); + r[214] = rf[214] * (c[38] * c[4] - rkc[214] * c[35] * c[5]); + r[215] = rf[215] * (c[38] * c[3] - rkc[215] * c[6] * c[35]); + r[216] = rf[216] * (c[39] * c[2] - rkc[216] * c[14] * c[30]); + r[217] = rf[217] * (c[39] * c[4] - rkc[217] * c[46] * c[1]); + r[218] = rf[218] * (c[39] * c[5] - rkc[218] * c[40] * c[4]); + r[219] = rf[219] * (c[39] * c[3] - rkc[219] * c[46] * c[2]); + r[220] = rf[220] * (c[39] * c[0] - rkc[220] * c[40] * c[1]); + r[221] = rf[221] * (c[46] * c[2] - rkc[221] * c[35] * c[14]); + r[222] = rf[222] * (c[46] * c[1] - rkc[222] * c[31] * c[14]); + r[223] = rf[223] * (c[46] * c[4] - rkc[223] * c[35] * c[1] * c[14]); + r[224] = rf[224] * (c[46] * c[30] - rkc[224] * c[47] * c[14]); + r[225] = rf[225] * (c[46] * c[3] - rkc[225] * c[35] * c[15]); + r[226] = rf[226] * (c[46] - rkc[226] * c[30] * c[14]); + r[227] = rf[227] * (c[46] * c[35] - rkc[227] * c[37] * c[14]); + r[228] = rf[228] * (c[46] * c[35] - rkc[228] * c[47] * c[15]); + r[229] = rf[229] * (c[40] - rkc[229] * c[1] * c[39]); + r[230] = rf[230] * (c[40] * c[2] - rkc[230] * c[46] * c[1]); + r[231] = rf[231] * (c[40] * c[2] - rkc[231] * c[31] * c[14]); + r[232] = rf[232] * (c[40] * c[2] - rkc[232] * c[39] * c[4]); + r[233] = rf[233] * (c[40] * c[4] - rkc[233] * c[44] * c[1]); + r[234] = rf[234] * (c[40] * c[4] - rkc[234] * c[45] * c[1]); + r[235] = rf[235] * (c[40] * c[4] - rkc[235] * c[32] * c[14]); + r[236] = rf[236] * (c[1] * c[40] - rkc[236] * c[41]); + r[237] = rf[237] * (c[41] * c[30] - rkc[237] * c[47] * c[10]); + r[238] = rf[238] * (c[8] * c[47] - rkc[238] * c[39] * c[30]); + r[239] = rf[239] * (c[9] * c[47] - rkc[239] * c[40] * c[30]); + r[240] = rf[240] * (c[9] * c[47] - rkc[240] * c[42]); + r[241] = rf[241] * (c[10] * c[47] - rkc[241] * c[40] * c[31]); + r[242] = rf[242] * (c[11] * c[47] - rkc[242] * c[31] * c[40]); + r[243] = rf[243] * (c[8] * c[35] - rkc[243] * c[39] * c[2]); + r[244] = rf[244] * (c[8] * c[35] - rkc[244] * c[14] * c[30]); + r[245] = rf[245] * (c[9] * c[35] - rkc[245] * c[40] * c[2]); + r[246] = rf[246] * (c[9] * c[35] - rkc[246] * c[1] * c[46]); + r[247] = rf[247] * (c[9] * c[35] - rkc[247] * c[30] * c[16]); + r[248] = rf[248] * (c[10] * c[35] - rkc[248] * c[1] * c[45]); + r[249] = rf[249] * (c[10] * c[35] - rkc[249] * c[4] * c[40]); + r[250] = rf[250] * (c[10] * c[35] - rkc[250] * c[1] * c[43]); + r[251] = rf[251] * (c[11] * c[35] - rkc[251] * c[1] * c[45]); + r[252] = rf[252] * (c[11] * c[35] - rkc[252] * c[4] * c[40]); + r[253] = rf[253] * (c[11] * c[35] - rkc[253] * c[1] * c[43]); + r[254] = rf[254] * (c[12] * c[35] - rkc[254] * c[40] * c[5]); + r[255] = rf[255] * (c[12] * c[35] - rkc[255] * c[41] * c[4]); + r[256] = rf[256] * (c[42] * c[2] - rkc[256] * c[14] * c[1] * c[47]); + r[257] = rf[257] * (c[42] * c[2] - rkc[257] * c[40] * c[35]); + r[258] = rf[258] * (c[42] * c[3] - rkc[258] * c[2] * c[16] * c[47]); + r[259] = rf[259] * (c[42] * c[4] - rkc[259] * c[1] * c[16] * c[47]); + r[260] = rf[260] * (c[42] * c[1] - rkc[260] * c[10] * c[47]); + r[261] = rf[261] * (c[45] * c[2] - rkc[261] * c[31] * c[15]); + r[262] = rf[262] * (c[45] * c[2] - rkc[262] * c[38] * c[14]); + r[263] = rf[263] * (c[45] * c[2] - rkc[263] * c[46] * c[4]); + r[264] = rf[264] * (c[45] * c[1] - rkc[264] * c[32] * c[14]); + r[265] = rf[265] * (c[45] * c[1] - rkc[265] * c[0] * c[46]); + r[266] = rf[266] * (c[45] * c[4] - rkc[266] * c[46] * c[5]); + r[267] = rf[267] * (c[45] * c[4] - rkc[267] * c[32] * c[15]); + r[268] = rf[268] * (c[45] - rkc[268] * c[31] * c[14]); + r[269] = rf[269] * (c[43] * c[1] - rkc[269] * c[1] * c[45]); + r[270] = rf[270] * (c[43] * c[1] - rkc[270] * c[4] * c[40]); + r[271] = rf[271] * (c[43] * c[1] - rkc[271] * c[32] * c[14]); + r[272] = rf[272] * (c[44] * c[1] - rkc[272] * c[1] * c[45]); + r[273] = rf[273] * (c[27] * c[35] - rkc[273] * c[43] * c[14]); + r[274] = rf[274] * (c[12] * c[30] - rkc[274] * c[41] * c[1]); + r[275] = rf[275] * (c[12] * c[30] - rkc[275] * c[40] * c[0]); + r[276] = rf[276] * (c[33] * c[1] - rkc[276] * c[32] * c[0]); + r[277] = rf[277] * (c[33] * c[4] - rkc[277] * c[32] * c[5]); + r[278] = rf[278] * (c[33] * c[2] - rkc[278] * c[32] * c[4]); + r[279] = rf[279] * (c[31] * c[15] - rkc[279] * c[38] * c[14]); + r[280] = rf[280] * (c[39] * c[36] - rkc[280] * c[46] * c[35]); + r[281] = rf[281] * (c[46] * c[36] - rkc[281] * c[37] * c[15]); + r[282] = rf[282] * (c[30] * c[15] - rkc[282] * c[35] * c[14]); + r[283] = rf[283] * (c[2] * c[12]); + r[284] = rf[284] * (c[2] * c[24] - rkc[284] * c[1] * c[51]); + r[285] = rf[285] * (c[2] * c[25] - rkc[285] * c[1] * c[52]); + r[286] = rf[286] * (c[4] * c[6] - rkc[286] * c[3] * c[5]); + r[287] = rf[287] * (c[4] * c[12]); + r[288] = rf[288] * (c[9] * c[0] - rkc[288] * c[12]); + r[289] = rf[289] * (c[10] * c[3]); + r[290] = rf[290] * (c[10] * c[3] - rkc[290] * c[2] * c[17]); + r[291] = rf[291] * (c[10] * c[10]); + r[292] = rf[292] * (c[11] * c[5]); + r[293] = rf[293] * (c[23] * c[3] - rkc[293] * c[2] * c[51]); + r[294] = rf[294] * (c[23] * c[3] - rkc[294] * c[6] * c[22]); + r[295] = rf[295] * (c[2] * c[52] - rkc[295] * c[4] * c[51]); + r[296] = rf[296] * (c[2] * c[52]); + r[297] = rf[297] * (c[3] * c[52]); + r[298] = rf[298] * (c[1] * c[52] - rkc[298] * c[51] * c[0]); + r[299] = rf[299] * (c[1] * c[52]); + r[300] = rf[300] * (c[4] * c[52]); + r[301] = rf[301] * (c[6] * c[52]); + r[302] = rf[302] * (c[12] * c[52]); + r[303] = rf[303] * (c[1] * c[28] - rkc[303] * c[51]); + r[304] = rf[304] * (c[2] * c[51]); + r[305] = rf[305] * (c[3] * c[51]); + r[306] = rf[306] * (c[3] * c[51]); + r[307] = rf[307] * (c[1] * c[51] - rkc[307] * c[12] * c[16]); + r[308] = rf[308] * (c[1] * c[51] - rkc[308] * c[28] * c[0]); + r[309] = rf[309] * (c[4] * c[51] - rkc[309] * c[5] * c[28]); + r[310] = rf[310] * (c[4] * c[51] - rkc[310] * c[16] * c[18]); + r[311] = rf[311] * (c[12] * c[25] - rkc[311] * c[50]); + r[312] = rf[312] * (c[2] * c[50] - rkc[312] * c[4] * c[49]); + r[313] = rf[313] * (c[1] * c[50] - rkc[313] * c[49] * c[0]); + r[314] = rf[314] * (c[4] * c[50] - rkc[314] * c[49] * c[5]); + r[315] = rf[315] * (c[49] * c[7] - rkc[315] * c[6] * c[50]); + r[316] = rf[316] * (c[12] * c[50] - rkc[316] * c[49] * c[13]); + r[317] = rf[317] * (c[12] * c[24] - rkc[317] * c[49]); + r[318] = rf[318] * (c[2] * c[49] - rkc[318] * c[25] * c[17]); + r[319] = rf[319] * (c[1] * c[49] - rkc[319] * c[50]); + r[320] = rf[320] * (c[1] * c[49] - rkc[320] * c[12] * c[25]); + r[321] = rf[321] * (c[4] * c[49] - rkc[321] * c[25] * c[18]); + r[322] = rf[322] * (c[6] * c[49] - rkc[322] * c[3] * c[50]); + r[323] = rf[323] * (c[6] * c[49]); + r[324] = rf[324] * (c[12] * c[49] - rkc[324] * c[25] * c[25]); + } + +} + + + + + + + + diff --git a/Cantera/src/GRI_30_Kinetics.h b/Cantera/src/GRI_30_Kinetics.h new file mode 100755 index 000000000..8822c4d13 --- /dev/null +++ b/Cantera/src/GRI_30_Kinetics.h @@ -0,0 +1,50 @@ +/** + * + * @file GasKinetics.h + * + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_GRI30_KINETICS_H +#define CT_GRI30_KINETICS_H + +#include "GasKinetics.h" + +namespace Cantera { + + const int cGRI_30_Kinetics = cGasKinetics + 1; + + /** + * Kinetics manager implementing reaction mechanism GRI-Mech 3.0 + */ + class GRI_30_Kinetics : public GasKinetics { + + public: + + /// Default constructor. + GRI_30_Kinetics(thermo_t* th=0); + + /// Destructor. + virtual ~GRI_30_Kinetics(){} + + virtual int ID() { return cGRI_30_Kinetics; } + + virtual void getNetProductionRates(doublereal* net) { + gri30_updateROP(); + get_wdot(m_kdata->m_ropnet.begin(), net); + } + + private: + void gri30_update_rates_T(); + void gri30_updateROP(); + void gri30_updateKc(); + void get_wdot(const doublereal* rop, doublereal* wdot); + void update_kc(const double* grt, double c0, double* rkc); + void update_rates(double t, double tlog, double* rf); + void eval_ropnet(const double* c, const double* rf, const double* rkc, double* r); + }; +} + +#endif diff --git a/Cantera/src/GasKinetics.cpp b/Cantera/src/GasKinetics.cpp new file mode 100755 index 000000000..e20736156 --- /dev/null +++ b/Cantera/src/GasKinetics.cpp @@ -0,0 +1,471 @@ +/** + * @file GasKinetics.cpp + * + * Homogeneous kinetics in ideal gases + * + */ + +// Copyright 2001 California Institute of Technology + + +// turn off warnings under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "GasKinetics.h" + +#include "ReactionData.h" +#include "StoichManager.h" +#include "Enhanced3BConc.h" +#include "ThirdBodyMgr.h" +#include "RateCoeffMgr.h" + +#include +using namespace std; + +#ifdef HAVE_INTEL_MKL +#include "mkl_vml.h" +#endif + +void update_kc(const double* grt, double c0, double* rkc); +void update_rates(double t, double tlog, double* rf); +void mult_by_conc(const double* c, double* ropf, double* ropr); +void eval_ropnet(const double* c, const double* rf, const double* rkc, double* r); + +namespace Cantera { + + + /** + * Construct an empty reaction mechanism. + */ + GasKinetics:: + GasKinetics(thermo_t* thermo) : + Kinetics(thermo), + m_kk(0), + m_nfall(0), + m_dt_threshold(0.0), // 1.e-6), + m_nirrev(0), + m_nrev(0), + m_finalized(false) + { + m_kdata = new GasKineticsData; + m_kdata->m_temp = 0.0; + } + + /** + * Update temperature-dependent portions of reaction rates and + * falloff functions. + */ + void GasKinetics:: + update_T() {} + + void GasKinetics:: + update_C() {} + + void GasKinetics:: + _update_rates_T() { + doublereal T = thermo().temperature(); + m_kdata->m_logc0 = log(thermo().standardConcentration()); + if (fabs(T - m_kdata->m_temp) > m_dt_threshold) { + doublereal logT = log(T); + //m_kdata->m_logp0 - logT; + m_rates.update(T, logT, m_kdata->m_rfn.begin()); + m_falloff_low_rates.update(T, logT, m_kdata->m_rfn_low.begin()); + m_falloff_high_rates.update(T, logT, m_kdata->m_rfn_high.begin()); + m_falloffn.updateTemp(T, m_kdata->falloff_work.begin()); + m_kdata->m_temp = T; + updateKc(); + m_kdata->m_ROP_ok = false; + } + else { + doublereal logT = log(T); + doublereal dT = T - m_kdata->m_temp; + //m_kdata->m_logc0 = m_kdata->m_logp0 - logT; + m_rates.update_dT(T, logT, dT, m_kdata->m_rfn.begin()); + m_falloff_low_rates.update_dT(T, logT, dT, + m_kdata->m_rfn_low.begin()); + m_falloff_high_rates.update_dT(T, logT, dT, + m_kdata->m_rfn_high.begin()); + m_falloffn.updateTemp(T, m_kdata->falloff_work.begin()); + m_kdata->m_temp = T; + updateKc(); + m_kdata->m_ROP_ok = false; + } + }; + + + /** + * Update properties that depend on concentrations. Currently only + * the enhanced collision partner concentrations are updated here. + */ + void GasKinetics:: + _update_rates_C() { + thermo().getActivityConcentrations(m_conc.begin()); + doublereal ctot = thermo().molarDensity(); + m_3b_concm.update(m_conc, ctot, m_kdata->concm_3b_values.begin()); + m_falloff_concm.update(m_conc, ctot, + m_kdata->concm_falloff_values.begin()); + m_kdata->m_ROP_ok = false; + } + + /** + * Update the equilibrium constants in molar units. + */ + void GasKinetics::updateKc() { + int i, irxn; + vector_fp& m_rkc = m_kdata->m_rkcn; + +#ifdef HWMECH + const vector_fp& expg0_RT = thermo().expGibbs_RT(); + doublereal exp_c0 = exp(m_kdata->m_logc0); + update_kc(expg0_RT.begin(), exp_c0, m_rkc.begin()); +#else + + //thermo().getGibbs_RT(m_grt.begin()); + thermo().getStandardChemPotentials(m_grt.begin()); + fill(m_rkc.begin(), m_rkc.end(), 0.0); + + // compute Delta G^0 for all reversible reactions + m_reactantStoich.decrementReactions(m_grt.begin(), m_rkc.begin()); + m_revProductStoich.incrementReactions(m_grt.begin(), m_rkc.begin()); + + doublereal logc0 = m_kdata->m_logc0; + doublereal rrt = 1.0/(GasConstant * thermo().temperature()); + for (i = 0; i < m_nrev; i++) { + irxn = m_revindex[i]; + m_rkc[irxn] = exp(m_rkc[irxn]*rrt - m_dn[irxn]*logc0); + } + + for(i = 0; i != m_nirrev; ++i) { + m_rkc[ m_irrev[i] ] = 0.0; + } +#endif + } + + /** + * Get the equilibrium constants of all reactions, whether + * reversible or not. + */ + void GasKinetics::getEquilibriumConstants(doublereal* kc) { + int i; + _update_rates_T(); + vector_fp& rkc = m_kdata->m_rkcn; + //thermo().getGibbs_RT(m_grt.begin()); + thermo().getStandardChemPotentials(m_grt.begin()); + fill(rkc.begin(), rkc.end(), 0.0); + + // compute Delta G^0 for all reactions + m_reactantStoich.decrementReactions(m_grt.begin(), rkc.begin()); + m_revProductStoich.incrementReactions(m_grt.begin(), + rkc.begin()); + m_irrevProductStoich.incrementReactions(m_grt.begin(), + rkc.begin()); + + doublereal logc0 = m_kdata->m_logc0; + doublereal rrt = 1.0/(GasConstant * thermo().temperature()); + for (i = 0; i < m_ii; i++) { + kc[i] = exp(-rkc[i]*rrt + m_dn[i]*logc0); + } + } + + + void GasKinetics::processFalloffReactions() { + + int i; + const vector_fp& fc = m_kdata->concm_falloff_values; + const array_fp& m_rf_low = m_kdata->m_rfn_low; + const array_fp& m_rf_high = m_kdata->m_rfn_high; + + // use m_ropr for temporary storage of reduced pressure + array_fp& pr = m_kdata->m_ropr; + + array_fp& ropf = m_kdata->m_ropf; + + for (i = 0; i < m_nfall; i++) { + pr[i] = fc[i] * m_rf_low[i] / m_rf_high[i]; + } + + m_falloffn.pr_to_falloff( pr.begin(), m_kdata->falloff_work.begin() ); + + for (i = 0; i < m_nfall; i++) { + pr[i] *= m_rf_high[i]; + } + + _scatter_copy(pr.begin(), pr.begin() + m_nfall, + ropf.begin(), m_fallindx.begin()); + } + + + void GasKinetics::updateROP() { + + _update_rates_T(); + _update_rates_C(); + + if (m_kdata->m_ROP_ok) return; + + const vector_fp& rf = m_kdata->m_rfn; + const vector_fp& m_rkc = m_kdata->m_rkcn; + array_fp& ropf = m_kdata->m_ropf; + array_fp& ropr = m_kdata->m_ropr; + array_fp& ropnet = m_kdata->m_ropnet; + +#ifdef HWMECH + copy(rf.begin(), rf.end(), ropf.begin()); + m_3b_concm.multiply( ropf, m_kdata->concm_3b_values.begin() ); + processFalloffReactions(); + multiply_each(ropf.begin(), ropf.end(), m_perturb.begin()); + eval_ropnet(m_conc.begin(), ropf.begin(), m_rkc.begin(), ropnet.begin()); +#else + + // copy rate coefficients into ropf + copy(rf.begin(), rf.end(), ropf.begin()); + + // multiply ropf by enhanced 3b conc for all 3b rxns + m_3b_concm.multiply( ropf.begin(), m_kdata->concm_3b_values.begin() ); + + processFalloffReactions(); + + // multiply by perturbation factor + multiply_each(ropf.begin(), ropf.end(), m_perturb.begin()); + + // copy the forward rates to the reverse rates + copy(ropf.begin(), ropf.end(), ropr.begin()); + + // for reverse rates computed from thermochemistry, multiply + // the forward rates copied into m_ropr by the reciprocals of + // the equilibrium constants + multiply_each(ropr.begin(), ropr.end(), m_rkc.begin()); + + // multiply ropf by concentration products + m_reactantStoich.multiply(m_conc.begin(), ropf.begin()); + + // for reversible reactions, multiply ropr by concentration + // products + m_revProductStoich.multiply(m_conc.begin(), ropr.begin()); + + for (int j = 0; j != m_ii; ++j) { + ropnet[j] = ropf[j] - ropr[j]; + } + +#endif + m_kdata->m_ROP_ok = true; + } + + + void GasKinetics:: + addReaction(const ReactionData& r) { + + if (r.reactionType == ELEMENTARY_RXN) addElementaryReaction(r); + else if (r.reactionType == THREE_BODY_RXN) addThreeBodyReaction(r); + else if (r.reactionType == FALLOFF_RXN) addFalloffReaction(r); + + // operations common to all reaction types + //installReagents( r.reactants, r.products, r.reversible ); + installReagents( r ); + installGroups(reactionNumber(), r.rgroups, r.pgroups); + incrementRxnCount(); + m_rxneqn.push_back(r.equation); + } + + + void GasKinetics:: + addFalloffReaction(const ReactionData& r) { + + // install high and low rate coeff calculators + + int iloc = m_falloff_high_rates.install( m_nfall, + r.rateCoeffType, r.rateCoeffParameters.size(), + r.rateCoeffParameters.begin() ); + + m_falloff_low_rates.install( m_nfall, + r.rateCoeffType, r.auxRateCoeffParameters.size(), + r.auxRateCoeffParameters.begin() ); + + // add constant terms to high and low rate + // coeff value vectors + m_kdata->m_rfn_high.push_back(r.rateCoeffParameters[0]); + m_kdata->m_rfn_low.push_back(r.auxRateCoeffParameters[0]); + + // add a dummy entry in m_rf, where computed falloff + // rate coeff will be put + m_kdata->m_rfn.push_back(0.0); + + // add this reaction number to the list of + // falloff reactions + m_fallindx.push_back( reactionNumber() ); + + // install the enhanced third-body concentration + // calculator for this reaction + m_falloff_concm.install( m_nfall, r.thirdBodyEfficiencies, + r.default_3b_eff); + + // install the falloff function calculator for + // this reaction + m_falloffn.install( m_nfall, r.falloffType, r.falloffParameters ); + + // forward rxn order equals number of reactants, since rate + // coeff is defined in terms of the high-pressure limit + m_fwdOrder.push_back(r.reactants.size()); + + // increment the falloff reaction counter + ++m_nfall; + registerReaction( reactionNumber(), FALLOFF_RXN, iloc); + } + + + void GasKinetics:: + addElementaryReaction(const ReactionData& r) { + int iloc; + + // install rate coeff calculator + iloc = m_rates.install( reactionNumber(), + r.rateCoeffType, r.rateCoeffParameters.size(), + r.rateCoeffParameters.begin() ); + + // add constant term to rate coeff value vector + m_kdata->m_rfn.push_back(r.rateCoeffParameters[0]); + + // forward rxn order equals number of reactants + m_fwdOrder.push_back(r.reactants.size()); + registerReaction( reactionNumber(), ELEMENTARY_RXN, iloc); + } + + + void GasKinetics:: + addThreeBodyReaction(const ReactionData& r) { + + int iloc; + // install rate coeff calculator + iloc = m_rates.install( reactionNumber(), + r.rateCoeffType, r.rateCoeffParameters.size(), + r.rateCoeffParameters.begin() ); + + // add constant term to rate coeff value vector + m_kdata->m_rfn.push_back(r.rateCoeffParameters[0]); + + // forward rxn order equals number of reactants + 1 + m_fwdOrder.push_back(r.reactants.size() + 1); + + m_3b_concm.install( reactionNumber(), r.thirdBodyEfficiencies, + r.default_3b_eff ); + registerReaction( reactionNumber(), THREE_BODY_RXN, iloc); + } + + + void GasKinetics::installReagents(const ReactionData& r) { + //const vector_int& r, + //const vector_int& p, bool reversible) { + + m_kdata->m_ropf.push_back(0.0); // extend by one for new rxn + m_kdata->m_ropr.push_back(0.0); + m_kdata->m_ropnet.push_back(0.0); + int n, ns, m; + + int rnum = reactionNumber(); + + vector_int rk; + int nr = r.reactants.size(); + for (n = 0; n < nr; n++) { + ns = r.rstoich[n]; + if (ns != 0) m_rrxn[r.reactants[n]][rnum] += ns; + for (m = 0; m < ns; m++) { + rk.push_back(r.reactants[n]); + } + } + m_reactants.push_back(rk); + + vector_int pk; + int np = r.products.size(); + for (n = 0; n < np; n++) { + ns = r.pstoich[n]; + if (ns != 0) m_prxn[r.products[n]][rnum] += ns; + for (m = 0; m < ns; m++) { + pk.push_back(r.products[n]); + } + } + m_products.push_back(pk); + + m_kdata->m_rkcn.push_back(0.0); + // int nr = r.size(); + + //int i; + //for (i = 0; i < nr; i++) { + // m_rrxn[r[i]][rnum] += 1.0; + //} + m_reactantStoich.add( reactionNumber(), rk); + + //int np = p.size(); + // + //for (i = 0; i < np; i++) { + // m_prxn[p[i]][rnum] += 1.0; + // } + + if (r.reversible) { + m_revProductStoich.add(reactionNumber(), pk); + m_dn.push_back(pk.size() - rk.size()); + m_revindex.push_back(reactionNumber()); + m_nrev++; + } + else { + m_irrevProductStoich.add(reactionNumber(), pk); + m_dn.push_back(pk.size() - rk.size()); + m_irrev.push_back( reactionNumber() ); + m_nirrev++; + } + } + + + void GasKinetics::installGroups(int irxn, + const vector& r, const vector& p) { + if (!r.empty()) { + m_rgroups[reactionNumber()] = r; + m_pgroups[reactionNumber()] = p; + } + } + + + void GasKinetics::init() { + m_kk = thermo().nSpecies(); + m_rrxn.resize(m_kk); + m_prxn.resize(m_kk); + m_conc.resize(m_kk); + m_grt.resize(m_kk); + m_kdata->m_logp0 = log(thermo().refPressure()) - log(GasConstant); + } + + void GasKinetics::finalize() { + if (!m_finalized) { + int i, j, nr, np; + m_kdata->falloff_work.resize(m_falloffn.workSize()); + m_kdata->concm_3b_values.resize(m_3b_concm.workSize()); + m_kdata->concm_falloff_values.resize(m_falloff_concm.workSize()); + + for (i = 0; i < m_ii; i++) { + nr = m_reactants[i].size(); + for (j = 0; j < nr; j++) { + m_rstoich[i][m_reactants[i][j]]++; + } + np = m_products[i].size(); + for (j = 0; j < np; j++) { + m_pstoich[i][m_products[i][j]]++; + } + } + m_finalized = true; + } + } + + bool GasKinetics::ready() const { + return (m_finalized); + } + +} + + + + + + + + diff --git a/Cantera/src/GasKinetics.h b/Cantera/src/GasKinetics.h new file mode 100755 index 000000000..7214d56b4 --- /dev/null +++ b/Cantera/src/GasKinetics.h @@ -0,0 +1,263 @@ +/** + * @file GasKinetics.h + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_GASKINETICS_H +#define CT_GASKINETICS_H + +#include +#include +#include +#include + +#include "mix_defs.h" +#include "Kinetics.h" + +#include "utilities.h" +#include "StoichManager.h" +#include "ThirdBodyMgr.h" +#include "FalloffMgr.h" +#include "RateCoeffMgr.h" + +void get_wdot(const doublereal* rop, doublereal* wdot); + +namespace Cantera { + + // forward references + + class Enhanced3BConc; + class ReactionData; + class GasKineticsData; + class Thermo; + + /** + * Holds mechanism-specific data. + */ + class GasKineticsData { + public: + GasKineticsData() : + m_ROP_ok(false), + m_temp(0.0) + {} + virtual ~GasKineticsData(){} + + doublereal m_logp0, m_logc0; + array_fp m_ropf, m_ropr, m_ropnet; + array_fp m_rfn_low, m_rfn_high; + bool m_ROP_ok; + + doublereal m_temp; + vector_fp m_rfn; + vector_fp falloff_work; + vector_fp concm_3b_values; + vector_fp concm_falloff_values; + vector_fp m_rkcn; + }; + + + /** + * Kinetics manager for elementary gas-phase chemistry. This + * kinetics manager implements standard mass-action reaction rate + * expressions for low-density gases. It assumes that all + * stoichiometric coefficients are integers. + */ + + class GasKinetics : public Kinetics { + + public: + + /// Constructor. + GasKinetics(thermo_t* thermo = 0); + + /// Destructor. + virtual ~GasKinetics(){delete m_kdata;} + + virtual int ID() { return cGasKinetics; } + + virtual doublereal reactantStoichCoeff(int k, int i) const { + return m_rrxn[k][i]; + } + + virtual doublereal productStoichCoeff(int k, int i) const { + return m_prxn[k][i]; + } + + virtual void getFwdRatesOfProgress(doublereal* fwdROP) { + updateROP(); + copy(m_kdata->m_ropf.begin(), m_kdata->m_ropf.end(), fwdROP); + } + + virtual void getRevRatesOfProgress(doublereal* revROP) { + updateROP(); + copy(m_kdata->m_ropr.begin(), m_kdata->m_ropr.end(), revROP); + } + + virtual void getNetRatesOfProgress(doublereal* netROP) { + updateROP(); + copy(m_kdata->m_ropnet.begin(), m_kdata->m_ropnet.end(), netROP); + } + + virtual void getNetProductionRates(doublereal* net) { + updateROP(); +#ifdef HWMECH + get_wdot(m_kdata->m_ropnet.begin(), net); +#else + fill(net, net + m_kk, 0.0); + m_revProductStoich.incrementSpecies( + m_kdata->m_ropnet.begin(), net); + m_irrevProductStoich.incrementSpecies( + m_kdata->m_ropnet.begin(), net); + m_reactantStoich.decrementSpecies( + m_kdata->m_ropnet.begin(), net); +#endif + } + + virtual void getCreationRates(doublereal* cdot) { + updateROP(); + fill(cdot, cdot + m_kk, 0.0); + m_revProductStoich.incrementSpecies( + m_kdata->m_ropf.begin(), cdot); + m_irrevProductStoich.incrementSpecies( + m_kdata->m_ropf.begin(), cdot); + m_reactantStoich.incrementSpecies( + m_kdata->m_ropr.begin(), cdot); + } + + virtual void getDestructionRates(doublereal* ddot) { + updateROP(); + fill(ddot, ddot + m_kk, 0.0); + m_revProductStoich.incrementSpecies( + m_kdata->m_ropr.begin(), ddot); + m_reactantStoich.incrementSpecies( + m_kdata->m_ropf.begin(), ddot); + } + + virtual void getEquilibriumConstants(doublereal* kc); + + /** + * Set delta T threshold for updating temperature-dependent + * rates. + */ + void setRateUpdateThreshold(doublereal dt) { + m_dt_threshold = dt; + } + + virtual void init(); + + /// Add a reaction to the mechanism. + void addReaction(const ReactionData& r); + + virtual void finalize(); + virtual bool ready() const; + + virtual void update_T(); + virtual void update_C(); + + void updateROP(); + + virtual int reactionType(int i) const { + return m_index[i].first; + } + + virtual string reactionString(int i) const { + return m_rxneqn[i]; + } + + const vector& reactantGroups(int i) + { return m_rgroups[i]; } + const vector& productGroups(int i) + { return m_pgroups[i]; } + + virtual bool isReversible(int i) { + if (find(m_revindex.begin(), m_revindex.end(), i) + < m_revindex.end()) return true; + else return false; + } + + void _update_rates_T(); + void _update_rates_C(); + + protected: + + int m_kk, m_nfall; + + vector_int m_fallindx; + doublereal m_dt_threshold; + + Rate1 m_falloff_low_rates; + Rate1 m_falloff_high_rates; + Rate1 m_rates; + + mutable map > m_index; + + FalloffMgr m_falloffn; + + ThirdBodyMgr m_3b_concm; + ThirdBodyMgr m_falloff_concm; + + vector m_irrev; + + StoichManagerN m_reactantStoich; + StoichManagerN m_revProductStoich; + StoichManagerN m_irrevProductStoich; + + vector m_fwdOrder; + + int m_nirrev; + int m_nrev; + + map > m_rgroups; + map > m_pgroups; + + vector m_rxntype; + + mutable vector > m_rrxn; + mutable vector > m_prxn; + + vector_int m_dn; + vector_int m_revindex; + + map > m_rstoich; + map > m_pstoich; + + vector m_rxneqn; + + GasKineticsData* m_kdata; + + vector_fp m_conc; + void processFalloffReactions(); + vector_fp m_grt; + + + private: + + int reactionNumber(){ return m_ii;} + vector > m_stoich; + + void addElementaryReaction(const ReactionData& r); + void addThreeBodyReaction(const ReactionData& r); + void addFalloffReaction(const ReactionData& r); + + void installReagents(const ReactionData& r); + //const vector_int& r, + // const vector_int& p, bool reversible); + + void installGroups(int irxn, const vector& r, + const vector& p); + void updateKc(); + + void registerReaction(int rxnNumber, int type, int loc) { + m_index[rxnNumber] = pair(type, loc); + } + bool m_finalized; + }; +} + +#endif diff --git a/Cantera/src/GasKineticsWriter.cpp b/Cantera/src/GasKineticsWriter.cpp new file mode 100755 index 000000000..113849d75 --- /dev/null +++ b/Cantera/src/GasKineticsWriter.cpp @@ -0,0 +1,136 @@ +/** + * @file GasKineticsWriter.cpp + * + */ + +// Copyright 2001 California Institute of Technology + + +// turn off warnings under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "ReactionData.h" +#include "GasKineticsWriter.h" + +#include "StoichManager.h" +#include "Enhanced3BConc.h" +#include "ThirdBodyMgr.h" +#include "RateCoeffMgr.h" + +//#include "ThermoPhase.h" + +#include +using namespace std; + +namespace Cantera { + + /** + * Construct an empty reaction mechanism. + */ + GasKineticsWriter:: + GasKineticsWriter() : m_kk(0), m_ii(0), m_nfall(0), m_nrev(0), m_nirrev(0), + m_finalized(false) {} + + void GasKineticsWriter:: + addReaction(const ReactionData& r) { + + if (r.reactionType == ELEMENTARY_RXN) addElementaryReaction(r); + else if (r.reactionType == THREE_BODY_RXN) addThreeBodyReaction(r); + else if (r.reactionType == FALLOFF_RXN) addFalloffReaction(r); + + // operations common to all reaction types + installReagents( r.reactants, r.products, r.reversible ); + m_ii++; + } + + + void GasKineticsWriter:: + addFalloffReaction(const ReactionData& r) { + + // install high and low rate coeff calculators + m_falloff_high_rates.install( m_nfall, + r.rateCoeffType, r.rateCoeffParameters.size(), + r.rateCoeffParameters.begin() ); + m_falloff_low_rates.install( m_nfall, + r.rateCoeffType, r.auxRateCoeffParameters.size(), + r.auxRateCoeffParameters.begin() ); + + // add this reaction number to the list of + // falloff reactions + m_fallindx.push_back( reactionNumber() ); + + // increment the falloff reaction counter + ++m_nfall; + } + + + void GasKineticsWriter:: + addElementaryReaction(const ReactionData& r) { + + int iloc; + // install rate coeff calculator + iloc = m_rates.install( reactionNumber(), + r.rateCoeffType, r.rateCoeffParameters.size(), + r.rateCoeffParameters.begin() ); + } + + + void GasKineticsWriter:: + addThreeBodyReaction(const ReactionData& r) { + + int iloc; + // install rate coeff calculator + iloc = m_rates.install( reactionNumber(), + r.rateCoeffType, r.rateCoeffParameters.size(), + r.rateCoeffParameters.begin() ); + } + + + void GasKineticsWriter::installReagents(const vector_int& r, + const vector_int& p, bool reversible) { + + int nr = r.size(); + int rnum = reactionNumber(); + int i; + for (i = 0; i < nr; i++) { + m_rrxn[r[i]][rnum] += 1.0; + } + + m_reactantWriter.add( reactionNumber(), r); + + int np = p.size(); + + for (i = 0; i < np; i++) { + m_prxn[p[i]][rnum] += 1.0; + } + + if (reversible) { + m_revProductWriter.add(reactionNumber(), p); + m_dn.push_back(np - nr); + m_revindex.push_back(reactionNumber()); + m_nrev++; + } + else { + m_irrevProductWriter.add(reactionNumber(), p); + m_irrev.push_back( reactionNumber() ); + m_nirrev++; + } + } + + void GasKineticsWriter::init(int nsp) { + m_rrxn.resize(nsp); + m_prxn.resize(nsp); + } + +} + + + + + + + + diff --git a/Cantera/src/GasKineticsWriter.h b/Cantera/src/GasKineticsWriter.h new file mode 100755 index 000000000..015475114 --- /dev/null +++ b/Cantera/src/GasKineticsWriter.h @@ -0,0 +1,204 @@ +/** + * + * @file GasKinetics.h + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_GASKINETICSWRITER_H +#define CT_GASKINETICSWRITER_H + +#define WRITE_UPDATE + +#include +#include +#include +#include + +#include "mix_defs.h" +#include "Kinetics.h" + +#include "utilities.h" +#include "StoichManager.h" +#include "ThirdBodyMgr.h" +#include "FalloffMgr.h" +#include "RateCoeffMgr.h" +#include "Phase.h" + +namespace Cantera { + + // forward references + class Enhanced3BConc; + class ReactionData; + + /** + * Class to write a hard-coded version of a mechanism. + * @ingroup kineticsGroup + */ + + class GasKineticsWriter { + + public: + + /// Default constructor. + GasKineticsWriter(); + + /// Destructor. + virtual ~GasKineticsWriter(){} + + void init(int nsp); + doublereal reactantStoichCoeff(int k, int i) const { + return m_rrxn[k][i]; + } + + doublereal productStoichCoeff(int k, int i) const { + return m_prxn[k][i]; + } + void writeUpdateROP(){} + + void writeGetNetProductionRates(ostream& s, int nsp, int nrxns) { + int i, k; + s << "void get_wdot(const double* rop, double* wdot) {" << endl; + for (k = 0; k < nsp; k++) { + s << " wdot[" << k << "] = "; + doublereal net; + bool empty = true; + for (i = 0; i < nrxns; i++) { + net = productStoichCoeff(k,i) - reactantStoichCoeff(k,i); + if (net > 0.0) { + empty = false; + if (net == 1.0) + s << " + rop[" << i << "]"; + else + s << " + " << net << "*rop[" << i << "]"; + } + else if (net < 0.0) { + empty = false; + if (net == -1.0) + s << " - rop[" << i << "]"; + else + s << " - " << -net << "*rop[" << i << "]"; + } + } + if (empty) s << "0.0"; + s << ";" << endl; + } + s << "}" << endl; + } + + + void writeUpdateKc(ostream& s, int nsp, int nrxns) { + int i, k, n, nn, ir; + s << "void update_kc(const double* a, " + "double exp_c0, double* rkc) {" << endl; + for (i = 0; i != m_nrev; i++) { + //if (isReversible(i)) { + ir = m_revindex[i]; + s << " rkc[" << ir << "] = "; + bool empty = true; + for (k = 0; k < nsp; k++) { + n = int(productStoichCoeff(k,ir)); + for (nn = 0; nn != n; nn++) { + if (!empty) s << "*"; + s << "a[" << k << "]"; + empty = false; + } + } + if (m_dn[i] < 0.0) { + n = -m_dn[i]; + for (nn = 0; nn < n; nn++) s << "*exp_c0"; + } + s << "/("; + empty = true; + for (k = 0; k < nsp; k++) { + n = int(reactantStoichCoeff(k,ir)); + for (nn = 0; nn < n; nn++) { + if (!empty) s << "*"; + s << "a[" << k << "]"; + empty = false; + } + } + if (m_dn[i] > 0.0) { + n = m_dn[i]; + for (nn = 0; nn != n; nn++) s << "*exp_c0"; + } + s << ");" << endl; + } + s << "}" << endl; + } + + void writeEvalRopnet(ostream& s) { + int i; + s << "void eval_ropnet(const double* c, " + "const double* rf, const double* rkc, double* r) {" << endl; + for (i = 0; i < m_ii; i++) { + s << " r[" << i << "] = rf[" << i << "] * (" + << m_reactantWriter.mult(i); + if (isReversible(i)) { + s << " - rkc[" << i << "] * " + << m_revProductWriter.mult(i); + } + s << ");" << endl; + } + s << "}" << endl; + } + + + + void writeUpdateRates(ostream& s) { + s << "void update_rates(double t, double tlog, double* rf) {" << endl; + s << " double rt = 1.0/t;" << endl; + m_rates.writeUpdate(s, "rf"); + s << "}" << endl; + } + + /// Add a reaction to the mechanism. + void addReaction(const ReactionData& r); + + protected: + + int m_kk, m_ii, m_nfall, m_nrev, m_nirrev; + + vector_int m_fallindx; + + Rate1 m_falloff_low_rates; + Rate1 m_falloff_high_rates; + Rate1 m_rates; + + vector m_irrev; + + StoichWriter m_reactantWriter; + StoichWriter m_revProductWriter; + StoichWriter m_irrevProductWriter; + + mutable vector > m_rrxn; + mutable vector > m_prxn; + + vector_int m_dn; + vector_int m_revindex; + + private: + + int reactionNumber(){ return m_ii;} + void addElementaryReaction(const ReactionData& r); + void addThreeBodyReaction(const ReactionData& r); + void addFalloffReaction(const ReactionData& r); + + void installReagents(const vector_int& r, + const vector_int& p, bool reversible); + + virtual bool isReversible(int i) { + if (find(m_revindex.begin(), m_revindex.end(), i) + < m_revindex.end()) return true; + else return false; + } + bool m_finalized; + }; +} + +#endif diff --git a/Cantera/src/Group.cpp b/Cantera/src/Group.cpp new file mode 100755 index 000000000..34b43c64d --- /dev/null +++ b/Cantera/src/Group.cpp @@ -0,0 +1,76 @@ +/** + * @file Group.cpp + * + * Implementation file for the Group class used in reaction path analysis. + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +// reaction path analysis support + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include +#include "Group.h" + +#include "Group.h" + +namespace Cantera { + + /** + * A group is 'valid' if all of its nonzero atom numbers have + * the same sign, either positive or negative. This method + * checks for this, and if the group is not valid it sets + * m_sign to -999, and sets all atom numbers to zero. + */ + void Group::validate() { + + int n = m_comp.size(); + + // if already checked and not valid, return + if (m_sign == -999) return; + + m_sign = 0; + bool ok = true; + for (int m = 0; m < n; m++) + { + if (m_comp[m] != 0) + { + if (m_sign == 0) { + m_sign = m_comp[m]/abs(m_comp[m]); + } + else if (m_sign * m_comp[m] < 0) { + ok = false; break; + } + } + } + if (!ok) { m_sign = -999; m_comp.resize(n,0); } + } + + ostream& Group::fmt(ostream& s, const vector& esymbols) const { + s << "("; + int nm; + bool first = true; + int n = m_comp.size(); + for (int m = 0; m < n; m++) { + nm = m_comp[m]; + if (nm != 0) { + if (!first) s << "-"; + s << esymbols[m]; + if (nm != 1) s << nm; + first = false; + } + } + s << ")"; + return s; + } + +} diff --git a/Cantera/src/Group.h b/Cantera/src/Group.h new file mode 100755 index 000000000..f094fe3c6 --- /dev/null +++ b/Cantera/src/Group.h @@ -0,0 +1,139 @@ +/** + * @file Group.h + * + * $Author$ + * $Revision$ + * $Date$ + */ + + +// Copyright 2001 California Institute of Technology + +#ifndef CT_RXNPATH_GROUP +#define CT_RXNPATH_GROUP + +#include +using namespace std; + +#include "ct_defs.h" + +namespace Cantera { + + /** + * Class Group is an internal class used by class ReactionPath. It + * represents some subset of the atoms of a molecule. + */ + class Group { + public: + Group() : m_sign(-999) { } + Group(int n) : m_sign(0) { m_comp.resize(n,0);} + Group(const vector_int& elnumbers) : + m_comp(elnumbers), m_sign(0) { + validate(); + } + Group(const Group& g) : + m_comp(g.m_comp), m_sign(g.m_sign) { } + Group& operator=(const Group& g) { + if (&g != this) { + m_comp = g.m_comp; + m_sign = g.m_sign; + } + return *this; + } + virtual ~Group(){} + + /** + * Decrement the atom numbers by those in group 'other'. + */ + void operator-=(const Group& other) { + verifyInputs(*this, other); + int n = m_comp.size(); + for (int m = 0; m < n; m++) + m_comp[m] -= other.m_comp[m]; + validate(); + } + void operator+=(const Group& other) { + verifyInputs(*this, other); + int n = m_comp.size(); + for (int m = 0; m < n; m++) + m_comp[m] += other.m_comp[m]; + validate(); + } + void operator*=(int a) { + int n = m_comp.size(); + for (int m = 0; m < n; m++) + m_comp[m] *= a; + validate(); + } + bool operator==(const Group& other) const { + verifyInputs(*this, other); + int n = m_comp.size(); + for (int m = 0; m < n; m++) { + if (m_comp[m] != other.m_comp[m]) return false; + } + return true; + } + friend Group operator-(const Group& g1, const Group& g2) { + verifyInputs(g1, g2); + Group diff(g1); + diff -= g2; + return diff; + } + friend Group operator+(const Group& g1, const Group& g2) { + verifyInputs(g1, g2); + Group sum(g1); + sum += g2; + return sum; + } + friend void verifyInputs(const Group& g1, const Group& g2) { +// if (Debug::on) { +// if (g1.size() != g2.size()) { +// cerr << "Group: size mismatch!" << endl; +// cerr << " group 1 = " << g1 << endl; +// cerr << " group 2 = " << g2 << endl; +// } +// } + } + + void validate(); + + /** + * True if all non-zero atom numbers have the same sign. + */ + bool valid() const { return (m_sign != -999); } + bool operator!() const { return (m_sign == -999); } + int sign() const { return m_sign; } + int size() const { return m_comp.size(); } + + /// Number of atoms in the group (>= 0) + int nAtoms() const { + int n = m_comp.size(); + int sum = 0; + for (int m = 0; m < n; m++) sum += abs(m_comp[m]); + return sum; + } + /// Number of atoms of element m (positive or negative) + int nAtoms(int m) const { + if (m_comp.empty()) return 0; + return m_comp[m]; + } + + ostream& fmt(ostream& s, const vector& esymbols) const; + + friend ostream& operator<<(ostream& s, const Group& g) { + if (g.valid()) + s << g.m_comp; + else + s << ""; + return s; + } + + private: + vector_int m_comp; + int m_sign; + }; + +} + +#endif + diff --git a/Cantera/src/IdealGasPhase.cpp b/Cantera/src/IdealGasPhase.cpp new file mode 100644 index 000000000..b586a0175 --- /dev/null +++ b/Cantera/src/IdealGasPhase.cpp @@ -0,0 +1,110 @@ +/** + * + * @file IdealGasPhase.cpp + * + */ + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "ct_defs.h" +#include "mix_defs.h" +#include "IdealGasPhase.h" +#include "SpeciesThermo.h" + +namespace Cantera { + + void IdealGasPhase::getChemPotentials(doublereal* mu) const { + doublereal logp = log(pressure()/m_spthermo->refPressure()); + doublereal xx; + doublereal rt = temperature() * GasConstant; + const array_fp& g_RT = gibbs_RT(); + for (int k = 0; k < m_kk; k++) { + xx = fmaxx(SmallNumber, moleFraction(k)); + mu[k] = rt*(g_RT[k] + log(xx) + logp); + } + } + + // new methods defined here + + + void IdealGasPhase::initThermo() { + m_kk = nSpecies(); + m_mm = nElements(); + doublereal tmin = m_spthermo->minTemp(); + doublereal tmax = m_spthermo->maxTemp(); + if (tmin > 0.0) m_tmin = tmin; + if (tmax > 0.0) m_tmax = tmax; + m_p0 = refPressure(); + + int leng = m_kk; + m_h0_RT.resize(leng); + m_g0_RT.resize(leng); + m_expg0_RT.resize(leng); + m_cp0_R.resize(leng); + m_s0_R.resize(leng); + m_pe.resize(leng, 0.0); + m_pp.resize(leng); + } + + + /** + * Set mixture to an equilibrium state consistent with specified + * element potentials and temperature. + * + * @param lambda_RT vector of non-dimensional element potentials + * \f[ \lambda_m/RT \f]. + * @param t temperature in K. + * @param work. Temporary work space. Must be dimensioned at least + * as large as the number of species. + * + */ + void IdealGasPhase::setToEquilState(const doublereal* lambda_RT) + { + const array_fp& grt = gibbs_RT(); + + // set the pressure and composition to be consistent with + // the temperature, + doublereal pres = 0.0; + for (int k = 0; k < m_kk; k++) { + m_pp[k] = -grt[k]; + for (int m = 0; m < m_mm; m++) { + m_pp[k] += nAtoms(k,m)*lambda_RT[m]; + //cout << "m = " << m << " k = " << k << " " << + // nAtoms(k,m) << " " << lambda_RT[m] << endl; + } + //cout << "m_pp = " << m_pp[k] << endl; + m_pp[k] = m_p0 * exp(m_pp[k]); + //cout << "after exp, m_pp[k] = " << m_pp[k] << endl; + pres += m_pp[k]; + } + //cout << "pres = " << pres << endl; + // set state + setState_PX(pres, m_pp.begin()); + } + + void IdealGasPhase::_updateThermo() const { + doublereal tnow = temperature(); + if (m_tlast != tnow) { + m_spthermo->update(tnow, m_cp0_R.begin(), m_h0_RT.begin(), + m_s0_R.begin()); + m_tlast = tnow; + doublereal rrt = 1.0 / (GasConstant * tnow); + int k; + doublereal deltaE; + for (k = 0; k < m_kk; k++) { + deltaE = rrt * m_pe[k]; + m_h0_RT[k] += deltaE; + m_g0_RT[k] = m_h0_RT[k] - m_s0_R[k]; + } + m_logc0 = log(m_p0/(GasConstant * tnow)); + m_tlast = tnow; + } + } +} + + + + diff --git a/Cantera/src/IdealGasPhase.h b/Cantera/src/IdealGasPhase.h new file mode 100644 index 000000000..e0b23d741 --- /dev/null +++ b/Cantera/src/IdealGasPhase.h @@ -0,0 +1,311 @@ +/** + * + * @file IdealGasPhase.h + * + */ + +/* $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2001 California Institute of Technology + * + */ + + +#ifndef CT_IDEALGASPHASE_H +#define CT_IDEALGASPHASE_H + +//#include "ct_defs.h" +#include "mix_defs.h" +#include "ThermoPhase.h" +#include "SpeciesThermo.h" + +namespace Cantera { + + /** + * @ingroup thermoprops + * + * Class IdealGasPhase represents low-density gases that obey the + * ideal gas equation of state. It derives from class ThermoPhase, + * and overloads the virtual methods defined there with ones that + * use expressions appropriate for ideal gas mixtures. + * + */ + class IdealGasPhase : public ThermoPhase { + + public: + + IdealGasPhase(): m_tlast(0.0) {} + + virtual ~IdealGasPhase() {} + + /** + * Equation of state flag. Returns the value cIdealGas, defined + * in mix_defs.h. + */ + virtual int eosType() const { return cIdealGas; } + + + /** + * @name Molar Thermodynamic Properties + * @{ + */ + + /** + * Molar enthalpy. Units: J/kmol. + * For an ideal gas mixture, + * \f[ + * \hat h(T) = \sum_k X_k \hat h^0_k(T), + * \f] + * and is a function only of temperature. + * The standard-state pure-species enthalpies + * \f$ \hat h^0_k(T) \f$ are computed by the species thermodynamic + * property manager. + * @see SpeciesThermo + */ + virtual doublereal enthalpy_mole() const { + return GasConstant * temperature() * + mean_X(enthalpy_RT().begin()); + } + + /** + * Molar internal energy. J/kmol. For an ideal gas mixture, + * \f[ + * \hat u(T) = \sum_k X_k \hat h^0_k(T) - \hat R T, + * \f] + * and is a function only of temperature. + * The standard-state pure-species enthalpies + * \f$ \hat h^0_k(T) \f$ are computed by the species thermodynamic + * property manager. + * @see SpeciesThermo + */ + virtual doublereal intEnergy_mole() const { + return GasConstant * temperature() + * ( mean_X(enthalpy_RT().begin()) - 1.0); + } + + + /** + * Molar entropy. Units: J/kmol/K. + * For an ideal gas mixture, + * \f[ + * \hat s(T, P) = \sum_k X_k \hat s^0_k(T) - \hat R \log (P/P^0). + * \f] + * The standard-state pure-species entropies + * \f$ \hat s^0_k(T) \f$ are computed by the species thermodynamic + * property manager. + * @see SpeciesThermo + */ + virtual doublereal entropy_mole() const { + return GasConstant * (mean_X(entropy_R().begin()) - + sum_xlogx() - log(pressure()/m_spthermo->refPressure())); + } + + + virtual doublereal gibbs_mole() const { + return enthalpy_mole() - temperature() * entropy_mole(); + } + + + /** + * Molar heat capacity at constant pressure. Units: J/kmol/K. + * For an ideal gas mixture, + * \f[ + * \hat c_p(t) = \sum_k \hat c^0_{p,k}(T). + * \f] + * The standard-state pure-species heat capacities + * \f$ \hat c^0_{p,k}(T) \f$ are computed by the species thermodynamic + * property manager. + * @see SpeciesThermo + */ + virtual doublereal cp_mole() const { + return GasConstant * mean_X(cp_R().begin()); + } + + /** + * Molar heat capacity at constant volume. Units: J/kmol/K. + * For an ideal gas mixture, + * \f[ \hat c_v = \hat c_p - \hat R. \f] + */ + virtual doublereal cv_mole() const { + return cp_mole() - GasConstant; + } + + //@} + + + /** + * @name Mechanical Equation of State + * @{ + */ + + /** + * Pressure. Units: Pa. + * For an ideal gas mixture, + * \f[ P = n \hat R T. \f] + */ + virtual doublereal pressure() const { + return GasConstant * molarDensity() * temperature(); + } + + /** + * Set the pressure at constant temperature. Units: Pa. + * This method is implemented by setting the mass density to + * \f[ + * \rho = \frac{P \overline W}{\hat R T }. + * \f] + */ + virtual void setPressure(doublereal p) { + setDensity(p * meanMolecularWeight() + /(GasConstant * temperature())); + } + + //@} + + + virtual void getChemPotentials(doublereal* mu) const; + + virtual void getStandardChemPotentials(doublereal* mu0) const { + getPureGibbs(mu0); + } + + /** + * This method returns the array of generalized + * concentrations. For an ideal gas mixture, these are simply + * the actual concentrations. + */ + virtual void getActivityConcentrations(doublereal* c) const { + getConcentrations(c); + } + + /** + * The standard concentration. This is defined as the concentration + * by which the generalized concentration is normalized to produce + * the activity. Since the activity for an ideal gas mixture is + * simply the mole fraction, the standard concentration is + * \f$ P^0/\hat R T \f$. + */ + virtual doublereal standardConcentration(int k=0) const { + return m_p0/(GasConstant * temperature()); + } + + virtual doublereal logStandardConc(int k=0) const { + _updateThermo(); + return m_logc0; + } + + virtual void getPartialMolarEnthalpies(doublereal* hbar) const { + const array_fp& _h = enthalpy_RT(); + doublereal rt = GasConstant * temperature(); + scale(_h.begin(), _h.end(), hbar, rt); + } + + virtual void getPureGibbs(doublereal* gpure) const { + const array_fp& gibbsrt = gibbs_RT(); + scale(gibbsrt.begin(), gibbsrt.end(), gpure, _RT()); + } + + void getEnthalpy_RT(doublereal* hrt) const { + const array_fp& _h = enthalpy_RT(); + copy(_h.begin(), _h.end(), hrt); + } + + void getEntropy_R(doublereal* sr) const { + const array_fp& _s = entropy_R(); + copy(_s.begin(), _s.end(), sr); + } + + virtual void getGibbs_RT(doublereal* grt) const { + const array_fp& gibbsrt = gibbs_RT(); + copy(gibbsrt.begin(), gibbsrt.end(), grt); + } + + void getCp_R(doublereal* cpr) const { + const array_fp& _cpr = cp_R(); + copy(_cpr.begin(), _cpr.end(), cpr); + } + + + // new methods defined here + + const array_fp& enthalpy_RT() const { + _updateThermo(); + return m_h0_RT; + } + + const array_fp& gibbs_RT() const { + _updateThermo(); + return m_g0_RT; + } + + const array_fp& expGibbs_RT() const { + _updateThermo(); + int k; + for (k = 0; k != m_kk; k++) m_expg0_RT[k] = exp(m_g0_RT[k]); + return m_expg0_RT; + } + + const array_fp& entropy_R() const { + _updateThermo(); + return m_s0_R; + } + + const array_fp& cp_R() const { + _updateThermo(); + return m_cp0_R; + } + + virtual void setPotentialEnergy(int k, doublereal pe) { + m_pe[k] = pe; + _updateThermo(); + } + + virtual doublereal potentialEnergy(int k) const { + return m_pe[k]; + } + + virtual void initThermo(); + + + /** + * Set mixture to an equilibrium state consistent with specified + * element potentials and temperature. + * + * @param lambda_RT vector of non-dimensional element potentials + * \f[ \lambda_m/RT \f]. + * @param t temperature in K. + * @param work. Temporary work space. Must be dimensioned at least + * as large as the number of species. + * + */ + virtual void setToEquilState(const doublereal* lambda_RT); + + + + protected: + + int m_kk, m_mm; + doublereal m_tmin, m_tmax, m_p0; + + mutable doublereal m_tlast, m_logc0; + mutable array_fp m_h0_RT; + mutable array_fp m_cp0_R; + mutable array_fp m_g0_RT; + mutable array_fp m_s0_R; + mutable array_fp m_expg0_RT; + mutable array_fp m_pe; + mutable array_fp m_pp; + + private: + + void _updateThermo() const; + }; +} + +#endif + + + + + diff --git a/Cantera/src/IdealGasThermo.cpp b/Cantera/src/IdealGasThermo.cpp new file mode 100755 index 000000000..594bb4e54 --- /dev/null +++ b/Cantera/src/IdealGasThermo.cpp @@ -0,0 +1,110 @@ +/** + * + * @file IdealGasThermo.cpp + * + */ + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "ct_defs.h" +#include "mix_defs.h" +#include "IdealGasThermo.h" +#include "SpeciesThermo.h" + +namespace Cantera { + + void IdealGasThermo::getChemPotentials(doublereal* mu) const { + doublereal logp = log(pressure()/m_spthermo->refPressure()); + doublereal xx; + doublereal rt = m_s->temperature() * GasConstant; + const array_fp& g_RT = gibbs_RT(); + for (int k = 0; k < m_kk; k++) { + xx = fmaxx(SmallNumber, m_s->moleFraction(k)); + mu[k] = rt*(g_RT[k] + log(xx) + logp); + } + } + + // new methods defined here + + + void IdealGasThermo::initThermo(Phase& s) { + Thermo::initThermo(s); + m_kk = s.nSpecies(); + m_mm = s.nElements(); + doublereal tmin = m_spthermo->minTemp(); + doublereal tmax = m_spthermo->maxTemp(); + if (tmin > 0.0) m_tmin = tmin; + if (tmax > 0.0) m_tmax = tmax; + m_p0 = refPressure(); + + // allocate space to cache species thermo properties + m_kk = m_s->nSpecies(); + + int leng = m_kk; + m_h0_RT.resize(leng); + m_g0_RT.resize(leng); + m_expg0_RT.resize(leng); + m_cp0_R.resize(leng); + m_s0_R.resize(leng); + m_pe.resize(leng, 0.0); + m_pp.resize(leng); + } + + + /** + * Set mixture to an equilibrium state consistent with specified + * element potentials and temperature. + * + * @param lambda_RT vector of non-dimensional element potentials + * \f[ \lambda_m/RT \f]. + * @param t temperature in K. + * @param work. Temporary work space. Must be dimensioned at least + * as large as the number of species. + * + */ + void IdealGasThermo::setToEquilState(const doublereal* lambda_RT) + { + const array_fp& grt = gibbs_RT(); + + // set the pressure and composition to be consistent with + // the temperature, + doublereal pres = 0.0; + for (int k = 0; k < m_kk; k++) { + m_pp[k] = -grt[k]; + for (int m = 0; m < m_mm; m++) { + m_pp[k] += phase().nAtoms(k,m)*lambda_RT[m]; + cout << "m = " << m << " k = " << k << " " << + phase().nAtoms(k,m) << " " << lambda_RT[m] << endl; + } + m_pp[k] = m_p0 * exp(m_pp[k]); + pres += m_pp[k]; + } + // set state + setState_PX(pres, m_pp.begin()); + } + + void IdealGasThermo::_updateThermo() const { + doublereal tnow = m_s->temperature(); + if (m_tlast != tnow) { + m_spthermo->update(tnow, m_cp0_R.begin(), m_h0_RT.begin(), + m_s0_R.begin()); + m_tlast = tnow; + doublereal rrt = 1.0 / (GasConstant * tnow); + int k; + doublereal deltaE; + for (k = 0; k < m_kk; k++) { + deltaE = rrt * m_pe[k]; + m_h0_RT[k] += deltaE; + m_g0_RT[k] = m_h0_RT[k] - m_s0_R[k]; + } + m_tlast = tnow; + } + } +} + + + + diff --git a/Cantera/src/IdealGasThermo.h b/Cantera/src/IdealGasThermo.h new file mode 100755 index 000000000..e59728e84 --- /dev/null +++ b/Cantera/src/IdealGasThermo.h @@ -0,0 +1,212 @@ +/** + * + * @file IdealGasThermo.h + * + * Template for an equation of state class that implements the ideal + * gas equation. + */ + +/* $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2001 California Institute of Technology + * + */ + + +#ifndef CT_IDEALGASTHERMO_H +#define CT_IDEALGASTHERMO_H + +#include "ct_defs.h" +#include "mix_defs.h" +#include "Thermo.h" +#include "SpeciesThermo.h" + +namespace Cantera { + + /** + * Overloads the virtual methods of class Thermo to implement the + * ideal gas equation of state. + */ + class IdealGasThermo : public Thermo { + + public: + + IdealGasThermo(phase_t* phase=0, SpeciesThermo* sptherm = 0) + : Thermo(phase, sptherm), m_tlast(0.0) {} + + virtual ~IdealGasThermo() {} + + virtual int eosType() const { return cIdealGas; } + + virtual doublereal enthalpy_mole() const { + return GasConstant * m_s->temperature() * + m_s->mean_X(enthalpy_RT().begin()); + } + + virtual doublereal intEnergy_mole() const { + return GasConstant * m_s->temperature() + * ( m_s->mean_X(enthalpy_RT().begin()) - 1.0); + } + + virtual doublereal entropy_mole() const { + return GasConstant * (m_s->mean_X(entropy_R().begin()) - + m_s->sum_xlogx() - log(pressure()/m_spthermo->refPressure())); + } + + virtual doublereal gibbs_mole() const { + return enthalpy_mole() - m_s->temperature() * entropy_mole(); + } + + virtual doublereal cp_mole() const { + return GasConstant * m_s->mean_X(cp_R().begin()); + } + + virtual doublereal cv_mole() const { + return cp_mole() - GasConstant; + } + + virtual doublereal pressure() const { + return GasConstant * m_s->molarDensity() * m_s->temperature(); + } + + virtual void setPressure(doublereal p) { + m_s->setDensity(p * m_s->meanMolecularWeight() + /(GasConstant * m_s->temperature())); + } + + virtual void getChemPotentials(doublereal* mu) const; + + virtual void getPartialMolarEnthalpies(doublereal* hbar) const { + const array_fp& _h = enthalpy_RT(); + doublereal rt = GasConstant * _temp(); + scale(_h.begin(), _h.end(), hbar, rt); + } + + //virtual void getPartialMolarEntropies(doublereal* sbar) const { + // err("getPartialMolarEntropies"); + //} + + //virtual void getPartialMolarVolumes(doublereal* vbar) const { + // err("getPartialMolarVolumes"); + //} + + virtual void getPureGibbs(doublereal* gpure) const { + const array_fp& gibbsrt = gibbs_RT(); + scale(gibbsrt.begin(), gibbsrt.end(), gpure, _RT()); + } + + void getEnthalpy_RT(doublereal* hrt) const { + const array_fp& _h = enthalpy_RT(); + copy(_h.begin(), _h.end(), hrt); + } + + void getEntropy_R(doublereal* sr) const { + const array_fp& _s = entropy_R(); + copy(_s.begin(), _s.end(), sr); + } + + virtual void getGibbs_RT(doublereal* grt) const { + const array_fp& gibbsrt = gibbs_RT(); + copy(gibbsrt.begin(), gibbsrt.end(), grt); + } + + void getCp_R(doublereal* cpr) const { + const array_fp& _cpr = cp_R(); + copy(_cpr.begin(), _cpr.end(), cpr); + } + + virtual doublereal minTemp(int k = -1) { + return m_spthermo->minTemp(k); + } + + virtual doublereal maxTemp(int k = -1) { + return m_spthermo->maxTemp(k); + } + + // new methods defined here + + const array_fp& enthalpy_RT() const { + _updateThermo(); + return m_h0_RT; + } + + const array_fp& gibbs_RT() const { + _updateThermo(); + return m_g0_RT; + } + + const array_fp& expGibbs_RT() const { + _updateThermo(); + int k; + for (k = 0; k != m_kk; k++) m_expg0_RT[k] = exp(m_g0_RT[k]); + return m_expg0_RT; + } + + const array_fp& entropy_R() const { + _updateThermo(); + return m_s0_R; + } + + const array_fp& cp_R() const { + _updateThermo(); + return m_cp0_R; + } + + void setPotentialEnergy(int k, doublereal pe) { + m_pe[k] = pe; + } + + doublereal potentialEnergy(int k) { + return m_pe[k]; + } + + virtual doublereal refPressure() const { + return m_spthermo->refPressure(); + } + + void initThermo(Phase& s); + + + /** + * Set mixture to an equilibrium state consistent with specified + * element potentials and temperature. + * + * @param lambda_RT vector of non-dimensional element potentials + * \f[ \lambda_m/RT \f]. + * @param t temperature in K. + * @param work. Temporary work space. Must be dimensioned at least + * as large as the number of species. + * + */ + virtual void setToEquilState(const doublereal* lambda_RT); + + + + protected: + + int m_kk, m_mm; + doublereal m_tmin, m_tmax, m_p0; + + mutable doublereal m_tlast; + mutable array_fp m_h0_RT; + mutable array_fp m_cp0_R; + mutable array_fp m_g0_RT; + mutable array_fp m_s0_R; + mutable array_fp m_expg0_RT; + mutable array_fp m_pe; + mutable array_fp m_pp; + + private: + + void _updateThermo() const; + }; +} + +#endif + + + + + diff --git a/Cantera/src/ImplicitChem.cpp b/Cantera/src/ImplicitChem.cpp new file mode 100755 index 000000000..c31921da0 --- /dev/null +++ b/Cantera/src/ImplicitChem.cpp @@ -0,0 +1,88 @@ +/** + * @file Reactor.cpp + */ + +/* $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "ImplicitChem.h" +#include "CVode.h" + +namespace Cantera { + + ImplicitChem::ImplicitChem(Kinetics& kin, ThermoPhase& therm) + : FuncEval(), m_kin(&kin), m_thermo(&therm), m_integ(0), + m_atol(1.e-15), m_rtol(1.e-7), m_maxstep(0.0), m_energy(false) + { + m_integ = new CVodeInt; + //m_mix = &kin.phase(); + m_wt = m_thermo->molecularWeights(); + + // use backward differencing, with a full Jacobian computed + // numerically, and use a Newton linear iterator + m_integ->setMethod(BDF_Method); + m_integ->setProblemType(DENSE + NOJAC); + m_integ->setIterator(Newton_Iter); + m_nsp = m_thermo->nSpecies(); + } + + // overloaded method of FuncEval. Called by the integrator to + // get the initial conditions. + void ImplicitChem::getInitialConditions(double t0, size_t leny, double* y) + { + m_thermo->getMassFractions(leny, y); + m_h0 = m_thermo->enthalpy_mass(); + m_rho = m_thermo->density(); + m_press = m_thermo->pressure(); + } + + + /** + * Must be called before calling method 'advance' + */ + void ImplicitChem::initialize(doublereal t0) { + m_integ->setTolerances(m_rtol, m_atol); + // m_integ->setMaxStep(m_maxstep); + m_integ->initialize(t0, *this); + } + + + void ImplicitChem::updateState(doublereal* y) { + m_thermo->setMassFractions(y); + if (m_energy) { + doublereal delta, temp = m_thermo->temperature(); + do { + delta = -(m_thermo->enthalpy_mass() - m_h0)/m_thermo->cp_mass(); + temp += delta; + m_thermo->setTemperature(temp); + } + while (fabs(delta) > 1.e-7); + } + m_thermo->setPressure(m_press); + } + + /** + * Called by the integrator to evaluate ydot given y at time 'time'. + */ + void ImplicitChem::eval(doublereal time, doublereal* y, doublereal* ydot) + { + updateState(y); // synchronize the mixture state with y + m_thermo->setPressure(m_press); + m_kin->getNetProductionRates(ydot); // "omega dot" + int k; + for (k = 0; k < m_nsp; k++) { + ydot[k] *= m_wt[k]/m_rho; + } + } + +} diff --git a/Cantera/src/ImplicitChem.h b/Cantera/src/ImplicitChem.h new file mode 100755 index 000000000..0ae77c985 --- /dev/null +++ b/Cantera/src/ImplicitChem.h @@ -0,0 +1,118 @@ +/** + * @file ImplicitChem.h + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + +#ifndef CT_IMPCHEM_H +#define CT_IMPCHEM_H + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "FuncEval.h" +#include "CVode.h" +#include "Kinetics.h" +#include "ThermoPhase.h" + +namespace Cantera { + + /** + * Advances the composition of an associated phase object in time + * by implicitly integrating + * \f[ + * \dot Y_k = \frac{\omega_k}{\rho} + * \f] + */ + class ImplicitChem : public FuncEval { + + public: + + /** + * Constructor. + */ + ImplicitChem(Kinetics& kin, ThermoPhase& therm); + + + /** + * Destructor. Deletes the integrator. + */ + virtual ~ImplicitChem(){ delete m_integ; } + + + /** + * Overloads the virtual function + * declared in FuncEval. + */ + virtual void initialize(doublereal t0 = 0.0); + + void adiabatic() { + m_energy = true; + } + + void isothermal() { + m_energy = false; + } + + /** + * Integrate from t0 to t1. The integrator is reinitialized + * first. + */ + void integrate(doublereal t0, doublereal t1) { + m_integ->reinitialize(t0, *this); + m_integ->setMaxStep(t1 - t0); + m_rho = m_thermo->density(); + m_integ->integrate(t1); + updateState(m_integ->solution()); + } + + /** + * Integrate from t0 to t1 without reinitializing the + * integrator. + */ + void integrate0(doublereal t0, doublereal t1) { + m_integ->integrate(t1); + updateState(m_integ->solution()); + } + + // overloaded methods of class FuncEval + virtual int neq() { return m_nsp; } + virtual void eval(doublereal t, doublereal* y, doublereal* ydot); + virtual void getInitialConditions(doublereal t0, size_t leny, + doublereal* y); + + + protected: + + /** + * Set the mixture to a state consistent with solution + * vector y. + */ + void updateState(doublereal* y); + + //Kinetics::phase_t* m_mix; + Kinetics* m_kin; + ThermoPhase* m_thermo; + int m_nsp; + Integrator* m_integ; // pointer to integrator + doublereal m_atol, m_rtol; // tolerances + doublereal m_maxstep; // max step size + array_fp m_wt; + doublereal m_rho; + bool m_energy; + doublereal m_h0; + doublereal m_press; + + private: + + }; +} + +#endif + diff --git a/Cantera/src/ImplicitSurfChem.cpp b/Cantera/src/ImplicitSurfChem.cpp new file mode 100755 index 000000000..567d32253 --- /dev/null +++ b/Cantera/src/ImplicitSurfChem.cpp @@ -0,0 +1,79 @@ +/** + * @file ImplicitSurfChem.cpp + * + * Implicit integration of surface site density equations + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "ImplicitSurfChem.h" +#include "CVode.h" + +namespace Cantera { + + ImplicitSurfChem::ImplicitSurfChem(SurfKinetics& kin) + : FuncEval(), m_kin(&kin), m_integ(0), + m_atol(1.e-15), m_rtol(1.e-7), m_maxstep(0.0) + { + m_integ = new CVodeInt; + m_surf = &kin.sphase(); + + // use backward differencing, with a full Jacobian computed + // numerically, and use a Newton linear iterator + + m_integ->setMethod(BDF_Method); + m_integ->setProblemType(DENSE + NOJAC); + m_integ->setIterator(Newton_Iter); + m_nsp = m_surf->nSpecies(); + m_work.resize(m_kin->nTotal()); + } + + // overloaded method of FuncEval. Called by the integrator to + // get the initial conditions. + void ImplicitSurfChem::getInitialConditions(double t0, size_t lenc, + double* c) + { + m_surf->getCoverages(c); + } + + + /** + * Must be called before calling method 'advance' + */ + void ImplicitSurfChem::initialize(doublereal t0) { + m_integ->setTolerances(m_rtol, m_atol); + m_integ->initialize(t0, *this); + } + + void ImplicitSurfChem::updateState(doublereal* c) { + m_surf->setCoverages(c); + } + + /** + * Called by the integrator to evaluate ydot given y at time 'time'. + */ + void ImplicitSurfChem::eval(doublereal time, doublereal* y, + doublereal* ydot) + { + updateState(y); // synchronize the surface state with y + doublereal rs0 = 1.0/m_surf->siteDensity(); + m_kin->getNetProductionRates(m_work.begin()); + int k; + int kbulk = m_kin->nTotal() - m_nsp; + doublereal sum = 0.0; + for (k = 0; k < m_nsp; k++) { + ydot[k] = m_work[kbulk + k] * rs0 * m_surf->size(k); + } + } + +} diff --git a/Cantera/src/ImplicitSurfChem.h b/Cantera/src/ImplicitSurfChem.h new file mode 100755 index 000000000..d80f976b6 --- /dev/null +++ b/Cantera/src/ImplicitSurfChem.h @@ -0,0 +1,107 @@ +/** + * @file ImplicitSurfChem.h + * + * Implicit integration of surface site density equations. + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_IMPSURFCHEM_H +#define CT_IMPSURFCHEM_H + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "FuncEval.h" +#include "CVode.h" +#include "surfKinetics.h" + +namespace Cantera { + + /** + * Advances the surface coverages of an associated SurfacePhase + * object in time by implicitly integrating \f[ \dot \theta_k = + * \dot s_k (\sigma_k / s_0)\f] + */ + class ImplicitSurfChem : public FuncEval { + + public: + + /** + * Constructor. + */ + ImplicitSurfChem(SurfKinetics& kin); + + + /** + * Destructor. Deletes the integrator. + */ + virtual ~ImplicitSurfChem(){ delete m_integ; } + + + /** + * Overloads the virtual function + * declared in FuncEval. + */ + virtual void initialize(doublereal t0 = 0.0); + + + /** + * Integrate from t0 to t1. The integrator is reinitialized + * first. + */ + void integrate(doublereal t0, doublereal t1) { + m_integ->reinitialize(t0, *this); + m_integ->setMaxStep(t1 - t0); + m_integ->integrate(t1); + updateState(m_integ->solution()); + } + + /** + * Integrate from t0 to t1 without reinitializing the + * integrator. Use when the coverages have not changed from + * their values on return from the last call to integrate or + * integrate0. + */ + void integrate0(doublereal t0, doublereal t1) { + m_integ->integrate(t1); + updateState(m_integ->solution()); + } + + // overloaded methods of class FuncEval + virtual int neq() { return m_nsp; } + virtual void eval(doublereal t, doublereal* y, doublereal* ydot); + virtual void getInitialConditions(doublereal t0, + size_t leny, doublereal* y); + + + protected: + + /** + * Set the mixture to a state consistent with solution + * vector y. + */ + void updateState(doublereal* y); + + SurfacePhase* m_surf; + SurfKinetics* m_kin; + int m_nsp; + Integrator* m_integ; // pointer to integrator + doublereal m_atol, m_rtol; // tolerances + doublereal m_maxstep; // max step size + vector_fp m_work; + + private: + + }; +} + +#endif + diff --git a/Cantera/src/IncompressibleThermo.h b/Cantera/src/IncompressibleThermo.h new file mode 100755 index 000000000..5a3bac1d4 --- /dev/null +++ b/Cantera/src/IncompressibleThermo.h @@ -0,0 +1,97 @@ +/** + * + * @file IncompressibleThermo.h + * + * + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2001 California Institute of Technology + * + */ + + +#ifndef CT_INCOMPTHERMO_H +#define CT_INCOMPTHERMO_H + +#include "ct_defs.h" +#include "mix_defs.h" +#include "Thermo.h" + +namespace Cantera { + + /** + * Overloads the virtual methods of class Thermo to implement the + * ideal gas equation of state. + */ + class IncompressibleThermo : public Thermo { + + public: + + IncompressibleThermo(phase_t* phase=0) + : Thermo(phase), m_press(-1.0) {} + virtual ~IncompressibleThermo() {} + + virtual bool eosType() const { return cIncompressible; } + + virtual doublereal enthalpy_mole() const { + return GasConstant * m_s->temperature() * + m_s->mean_X(m_s->enthalpy_RT()) + + (pressure() - m_s->refPressure())/m_s->molarDensity(); + } + + virtual doublereal intEnergy_mole() const { + return enthalpy_mole() - pressure()/m_s->molarDensity(); + } + + virtual doublereal entropy_mole() const { + return GasConstant * (m_s->mean_X(m_s->entropy_R()) - + m_s->sum_xlogx()); + } + + virtual doublereal gibbs_mole() const { + return enthalpy_mole() - m_s->temperature() * entropy_mole(); + } + + virtual doublereal cp_mole() const { + return GasConstant * m_s->mean_X(m_s->cp_R()); + } + + virtual doublereal cv_mole() const { + return cp_mole(); + } + + virtual doublereal pressure() const { + return m_press; + } + + virtual void setPressure(doublereal p) { + m_press = p; + } + + virtual void getChemPotentials_RT(doublereal* mu) const { + int kk = m_s->nSpecies(); + doublereal xx; + const vector_fp& g_RT = m_s->gibbs_RT(); + doublereal vhat_dp = (pressure() - m_s->refPressure())/ + m_s->molarDensity(); + for (int k = 0; k < kk; k++) { + xx = fmax(Tiny,m_s->moleFraction(k)); + mu[k] = g_RT[k] + log(xx); + } + } + + protected: + doublereal m_press; + private: + + }; +} + +#endif + + + + + diff --git a/Cantera/src/Integrator.h b/Cantera/src/Integrator.h new file mode 100755 index 000000000..c02597013 --- /dev/null +++ b/Cantera/src/Integrator.h @@ -0,0 +1,162 @@ +/** + * @file Integrator.h + * + * $Author$ + * $Date$ + * $Revision$ + * + */ + +/** + * @defgroup odeGroup ODE Integrators + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_INTEGRATOR_H +#define CT_INTEGRATOR_H + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "FuncEval.h" + +#include "ct_defs.h" + +#define DIAG 1 +#define DENSE 2 +#define NOJAC 4 +#define JAC 8 +#define GMRES 16 + + +namespace Cantera { + + /** + * Specifies the method used to integrate the system of equations. + * Not all methods are supported by all integrators. + */ + enum MethodType { + BDF_Method, /**< Backward Differentiation */ + Adams_Method /**< Adams */ + }; + + /** + * Specifies the method used for iteration. + * Not all methods are supported by all integrators. + */ + enum IterType { + Newton_Iter, /**< Newton iteration */ + Functional_Iter /**< Functional iteration */ + }; + + + /** + * Abstract base class for ODE system integrators. + * @ingroup odeGroup + */ + class Integrator { + + public: + + /** Set or reset the number of equations. */ + //virtual void resize(int n)=0; + + /** + * Set error tolerances. + * @param reltol scalar relative tolerance + * @param number of equations + * @param abstol array of N absolute tolerance values + */ + virtual void setTolerances(doublereal reltol, int n, + doublereal* abstol) { warn("setTolerances"); } + + /** + * Set error tolerances. + * @param reltol scalar relative tolerance + * @param abstol scalar absolute tolerance + */ + virtual void setTolerances(doublereal reltol, doublereal abstol) + { warn("setTolerances"); } + + /** + * Set problem type. + */ + virtual void setProblemType(int probtype) { warn("setProblemType"); } + + /** + * Initialize the integrator for a new problem. Call after + * all options have been set. + * @param t0 initial time + * @param func RHS evaluator object for system of equations. + */ + virtual void initialize(doublereal t0, FuncEval& func) + { warn("initialize"); } + + virtual void reinitialize(doublereal t0, FuncEval& func) + { warn("reinitialize"); } + + /** + * Integrate the system of equations. + * @param tout integrate to this time. Note that this is the + * absolute time value, not a time interval. + */ + virtual void integrate(doublereal tout) + { warn("integrate"); } + + /** + * Integrate the system of equations. + * @param tout integrate to this time. Note that this is the + * absolute time value, not a time interval. + */ + virtual doublereal step(doublereal tout) + { warn("step"); return 0.0; } + + /** The current value of the solution of equation k. */ + virtual doublereal& solution(int k) + { warn("solution"); return m_dummy; } + + /** The current value of the solution of the system of equations. */ + virtual doublereal* solution() + { warn("solution"); return 0; } + + /** The number of equations. */ + virtual int nEquations() const + { warn("nEquations"); return 0; } + + /** The number of function evaluations. */ + virtual int nEvals() const + { warn("nEvals"); return 0; } + + /** Set the maximum integration order that will be used. **/ + virtual void setMaxOrder(int n) + { warn("setMaxorder"); } + + /** Set the solution method */ + virtual void setMethod(MethodType t) + { warn("setMethodType"); } + + /** Set the linear iterator. */ + virtual void setIterator(IterType t) + { warn("setInterator"); } + + /** Set the maximum step size */ + virtual void setMaxStep(double hmax) + { warn("setMaxStep"); } + + private: + + doublereal m_dummy; + void warn(string msg) const { + cerr << ">>>> Warning: method " << msg << " of base class " + << "Integrator called. Nothing done." << endl; + } + + }; + +} // namespace + +#endif diff --git a/Cantera/src/InterfaceKinetics.cpp b/Cantera/src/InterfaceKinetics.cpp new file mode 100644 index 000000000..f45dea5c8 --- /dev/null +++ b/Cantera/src/InterfaceKinetics.cpp @@ -0,0 +1,453 @@ +/** + * @file InterfaceKinetics.cpp + * + */ + +// Copyright 2002 California Institute of Technology + + +// turn off warnings under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "InterfaceKinetics.h" +#include "SurfPhase.h" + +#include "ReactionData.h" +#include "StoichManager.h" +#include "RateCoeffMgr.h" + +#include +using namespace std; + + +namespace Cantera { + + + /////////////////////////////////////////////////////////// + // + // class SurfPhase methods + // + /////////////////////////////////////////////////////////// + + SurfPhase:: + SurfPhase(doublereal n0): m_n0(n0), m_tlast(0.0) { + setNDim(2); + } + + doublereal SurfPhase:: + enthalpy_mole() const { + _updateThermo(); + return mean_X(m_h0.begin()); + } + + /** + * For a surface phase, the pressure is not a relevant + * thermodynamic variable, and so the enthalpy is equal to the + * internal energy. + */ + doublereal SurfPhase:: + intEnergy_mole() const { return enthalpy_mole(); } + + void SurfPhase:: + getStandardChemPotentials(doublereal* mu0) const { + _updateThermo(); + copy(m_mu0.begin(), m_mu0.end(), mu0); + } + + void SurfPhase:: + getActivityConcentrations(doublereal* c) const { getConcentrations(c); } + + doublereal SurfPhase:: + standardConcentration(int k) const { return m_n0/size(k); } + + doublereal SurfPhase:: + logStandardConc(int k) const { + return m_logn0 - m_logsize[k]; + } + + void SurfPhase:: + setParameters(int n, doublereal* c) { + m_n0 = c[0]; + m_logn0 = log(m_n0); + } + + void SurfPhase:: + initThermo() { + m_h0.resize(m_kk); + m_s0.resize(m_kk); + m_cp0.resize(m_kk); + m_mu0.resize(m_kk); + m_work.resize(m_kk); + m_pe.resize(m_kk, 0.0); + vector_fp cov(m_kk, 0.0); + cov[0] = 1.0; + setCoverages(cov.begin()); + m_logsize.resize(m_kk); + for (int k = 0; k < m_kk; k++) + m_logsize[k] = log(size(k)); + } + + void SurfPhase:: + setPotentialEnergy(int k, doublereal pe) { + m_pe[k] = pe; + _updateThermo(true); + } + + + void SurfPhase:: + setSiteDensity(doublereal n0) { + doublereal x = n0; + setParameters(1, &x); + } + + void SurfPhase:: + setElectricPotential(doublereal V) { + for (int k = 0; k < m_kk; k++) { + m_pe[k] = charge(k)*Faraday; + } + _updateThermo(true); + } + + void SurfPhase:: + setCoverages(const doublereal* theta) { + for (int k = 0; k < m_kk; k++) { + m_work[k] = m_n0*theta[k]/size(k); + } + setConcentrations(m_work.begin()); + } + + void SurfPhase:: + getCoverages(doublereal* theta) { + getConcentrations(theta); + for (int k = 0; k < m_kk; k++) { + theta[k] *= size(k)/m_n0; + } + } + + void SurfPhase:: + _updateThermo(bool force) const { + doublereal tnow = temperature(); + if (m_tlast != tnow || force) { + m_spthermo->update(tnow, m_cp0.begin(), m_h0.begin(), + m_s0.begin()); + m_tlast = tnow; + doublereal rt = GasConstant * tnow; + int k; + doublereal deltaE; + for (k = 0; k < m_kk; k++) { + m_h0[k] *= rt; + m_s0[k] *= GasConstant; + m_cp0[k] *= GasConstant; + deltaE = m_pe[k]; + m_h0[k] += deltaE; + m_mu0[k] = m_h0[k] - tnow*m_s0[k]; + } + m_tlast = tnow; + } + } + + + ////////////////////////////////////////////////////////////////// + + + + /** + * Construct an empty reaction mechanism. + */ + InterfaceKinetics:: + InterfaceKinetics(thermo_t* thermo) : + Kinetics(thermo), + m_kk(0), + m_nirrev(0), + m_nrev(0), + m_finalized(false) + { + m_kdata = new InterfaceKineticsData; + m_kdata->m_temp = 0.0; + } + + void InterfaceKinetics:: + _update_rates_T() { + doublereal T = thermo().temperature(); + if (T != m_kdata->m_temp) { + doublereal logT = log(T); + m_rates.update(T, logT, m_kdata->m_rfn.begin()); + m_kdata->m_temp = T; + updateKc(); + m_kdata->m_ROP_ok = false; + } + }; + + + /** + * Update properties that depend on concentrations. + */ + void InterfaceKinetics:: + _update_rates_C() { + int n; + int np = nPhases(); + for (n = 0; n < np; n++) { + thermo(n).getActivityConcentrations(m_conc.begin() + m_start[n]); + } + m_kdata->m_ROP_ok = false; + } + + /** + * Update the equilibrium constants in molar units. + */ + void InterfaceKinetics::updateKc() { + int i, irxn; + vector_fp& m_rkc = m_kdata->m_rkcn; + + int n, nsp, k, ik=0; + doublereal rt = GasConstant*thermo(0).temperature(); + doublereal rrt = 1.0/rt; + int np = nPhases(); + for (n = 0; n < np; n++) { + thermo(n).getStandardChemPotentials(m_mu0.begin() + m_start[n]); + nsp = thermo(n).nSpecies(); + for (k = 0; k < nsp; k++) { + m_mu0[ik] -= rt*thermo(n).logStandardConc(k); + ik++; + } + } + + fill(m_rkc.begin(), m_rkc.end(), 0.0); + + // compute Delta mu^0 for all reversible reactions + m_reactantStoich.decrementReactions(m_mu0.begin(), m_rkc.begin()); + m_revProductStoich.incrementReactions(m_mu0.begin(), m_rkc.begin()); + + for (i = 0; i < m_nrev; i++) { + irxn = m_revindex[i]; + m_rkc[irxn] = exp(m_rkc[irxn]*rrt); + } + + for(i = 0; i != m_nirrev; ++i) { + m_rkc[ m_irrev[i] ] = 0.0; + } + } + + /** + * Get the equilibrium constants of all reactions, whether + * reversible or not. + */ + void InterfaceKinetics::getEquilibriumConstants(doublereal* kc) { + int i; + + int n, nsp, k, ik=0; + doublereal rt = GasConstant*thermo(0).temperature(); + doublereal rrt = 1.0/rt; + int np = nPhases(); + for (n = 0; n < np; n++) { + thermo(n).getStandardChemPotentials(m_mu0.begin() + m_start[n]); + nsp = thermo(n).nSpecies(); + for (k = 0; k < nsp; k++) { + m_mu0[ik] -= rt*thermo(n).logStandardConc(k); + ik++; + } + } + + fill(kc, kc + m_ii, 0.0); + + m_reactantStoich.decrementReactions(m_mu0.begin(), kc); + m_revProductStoich.incrementReactions(m_mu0.begin(), kc); + m_irrevProductStoich.incrementReactions(m_mu0.begin(), kc); + + for (i = 0; i < m_ii; i++) { + kc[i] = exp(-kc[i]*rrt); + } + } + + + void InterfaceKinetics::updateROP() { + + _update_rates_T(); + _update_rates_C(); + + if (m_kdata->m_ROP_ok) return; + + const vector_fp& rf = m_kdata->m_rfn; + const vector_fp& m_rkc = m_kdata->m_rkcn; + array_fp& ropf = m_kdata->m_ropf; + array_fp& ropr = m_kdata->m_ropr; + array_fp& ropnet = m_kdata->m_ropnet; + + // copy rate coefficients into ropf + copy(rf.begin(), rf.end(), ropf.begin()); + + // multiply by perturbation factor + multiply_each(ropf.begin(), ropf.end(), m_perturb.begin()); + + // copy the forward rates to the reverse rates + copy(ropf.begin(), ropf.end(), ropr.begin()); + + // for reverse rates computed from thermochemistry, multiply + // the forward rates copied into m_ropr by the reciprocals of + // the equilibrium constants + multiply_each(ropr.begin(), ropr.end(), m_rkc.begin()); + + // multiply ropf by concentration products + m_reactantStoich.multiply(m_conc.begin(), ropf.begin()); + + // for reversible reactions, multiply ropr by concentration + // products + m_revProductStoich.multiply(m_conc.begin(), ropr.begin()); + + // do global reactions + m_globalReactantStoich.power(m_conc.begin(), ropf.begin()); + + for (int j = 0; j != m_ii; ++j) { + ropnet[j] = ropf[j] - ropr[j]; + } + + m_kdata->m_ROP_ok = true; + } + + + void InterfaceKinetics:: + addReaction(const ReactionData& r) { + + if (r.reactionType == ELEMENTARY_RXN) + addElementaryReaction(r); + else if (r.reactionType == GLOBAL_RXN) + addGlobalReaction(r); + + // operations common to all reaction types + installReagents( r ); + installGroups(reactionNumber(), r.rgroups, r.pgroups); + incrementRxnCount(); + m_rxneqn.push_back(r.equation); + } + + + void InterfaceKinetics:: + addElementaryReaction(const ReactionData& r) { + int iloc; + // install rate coeff calculator + iloc = m_rates.install( reactionNumber(), + r.rateCoeffType, r.rateCoeffParameters.size(), + r.rateCoeffParameters.begin() ); + // add constant term to rate coeff value vector + m_kdata->m_rfn.push_back(r.rateCoeffParameters[0]); + registerReaction( reactionNumber(), ELEMENTARY_RXN, iloc); + } + + + void InterfaceKinetics:: + addGlobalReaction(const ReactionData& r) { + + int iloc; + // install rate coeff calculator + iloc = m_rates.install( reactionNumber(), + r.rateCoeffType, r.rateCoeffParameters.size(), + r.rateCoeffParameters.begin() ); + + // add constant term to rate coeff value vector + m_kdata->m_rfn.push_back(r.rateCoeffParameters[0]); + + int nr = r.order.size(); + vector_fp ordr(nr); + for (int n = 0; n < nr; n++) { + ordr[n] = r.order[n] - r.rstoich[n]; + } + m_globalReactantStoich.add( reactionNumber(), + r.reactants, ordr); + + registerReaction( reactionNumber(), GLOBAL_RXN, iloc); + } + + + void InterfaceKinetics::installReagents(const ReactionData& r) { + + m_kdata->m_ropf.push_back(0.0); // extend by one for new rxn + m_kdata->m_ropr.push_back(0.0); + m_kdata->m_ropnet.push_back(0.0); + int n, ns, m; + + int rnum = reactionNumber(); + + vector_int rk; + int nr = r.reactants.size(); + for (n = 0; n < nr; n++) { + ns = r.rstoich[n]; + m_rrxn[r.reactants[n]][rnum] = ns; + for (m = 0; m < ns; m++) { + rk.push_back(r.reactants[n]); + } + } + m_reactants.push_back(rk); + + vector_int pk; + int np = r.products.size(); + for (n = 0; n < np; n++) { + ns = r.pstoich[n]; + m_prxn[r.products[n]][rnum] = ns; + for (m = 0; m < ns; m++) { + pk.push_back(r.products[n]); + } + } + m_products.push_back(pk); + + m_kdata->m_rkcn.push_back(0.0); + + m_reactantStoich.add( reactionNumber(), rk); + + if (r.reversible) { + m_revProductStoich.add(reactionNumber(), pk); + //m_dn.push_back(pk.size() - rk.size()); + m_revindex.push_back(reactionNumber()); + m_nrev++; + } + else { + m_irrevProductStoich.add(reactionNumber(), pk); + //m_dn.push_back(pk.size() - rk.size()); + m_irrev.push_back( reactionNumber() ); + m_nirrev++; + } + } + + + void InterfaceKinetics::installGroups(int irxn, + const vector& r, const vector& p) { + if (!r.empty()) { + m_rgroups[reactionNumber()] = r; + m_pgroups[reactionNumber()] = p; + } + } + + + void InterfaceKinetics::init() { + int n; + m_kk = 0; + int np = nPhases(); + for (n = 0; n < np; n++) { + m_kk += thermo(n).nSpecies(); + } + m_rrxn.resize(m_kk); + m_prxn.resize(m_kk); + m_conc.resize(m_kk); + m_mu0.resize(m_kk); + } + + void InterfaceKinetics::finalize() { + m_finalized = true; + } + + + bool InterfaceKinetics::ready() const { + return (m_finalized); + } + +} + + + + + + + + diff --git a/Cantera/src/InterfaceKinetics.h b/Cantera/src/InterfaceKinetics.h new file mode 100644 index 000000000..b6bccb617 --- /dev/null +++ b/Cantera/src/InterfaceKinetics.h @@ -0,0 +1,213 @@ +/** + * @file InterfaceKinetics.h + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_IFACEKINETICS_H +#define CT_IFACEKINETICS_H + +#include +#include +#include +#include + +#include "mix_defs.h" +#include "Kinetics.h" + +#include "utilities.h" +#include "RateCoeffMgr.h" +#include "StoichManager.h" + +namespace Cantera { + + // forward references + + class ReactionData; + class InterfaceKineticsData; + class ThermoPhase; + + /** + * Holds mechanism-specific data. + */ + class InterfaceKineticsData { + public: + InterfaceKineticsData() : + m_ROP_ok(false), + m_temp(0.0) + {} + virtual ~InterfaceKineticsData(){} + + doublereal m_logp0, m_logc0; + array_fp m_ropf, m_ropr, m_ropnet; + array_fp m_rfn_low, m_rfn_high; + bool m_ROP_ok; + + doublereal m_temp; + vector_fp m_rfn; + vector_fp m_rkcn; + }; + + + class InterfaceKinetics : public Kinetics { + + public: + + /// Constructor. + InterfaceKinetics(thermo_t* thermo = 0); + + /// Destructor. + virtual ~InterfaceKinetics(){delete m_kdata;} + + virtual int ID() { return cInterfaceKinetics; } + + virtual doublereal reactantStoichCoeff(int k, int i) const { + return m_rrxn[k][i]; + } + + virtual doublereal productStoichCoeff(int k, int i) const { + return m_prxn[k][i]; + } + + virtual void getFwdRatesOfProgress(doublereal* fwdROP) { + updateROP(); + copy(m_kdata->m_ropf.begin(), m_kdata->m_ropf.end(), fwdROP); + } + + virtual void getRevRatesOfProgress(doublereal* revROP) { + updateROP(); + copy(m_kdata->m_ropr.begin(), m_kdata->m_ropr.end(), revROP); + } + + virtual void getNetRatesOfProgress(doublereal* netROP) { + updateROP(); + copy(m_kdata->m_ropnet.begin(), m_kdata->m_ropnet.end(), netROP); + } + + virtual void getNetProductionRates(doublereal* net) { + updateROP(); + fill(net, net + m_kk, 0.0); + m_revProductStoich.incrementSpecies( + m_kdata->m_ropnet.begin(), net); + m_irrevProductStoich.incrementSpecies( + m_kdata->m_ropnet.begin(), net); + m_reactantStoich.decrementSpecies( + m_kdata->m_ropnet.begin(), net); + } + + virtual void getCreationRates(doublereal* cdot) { + updateROP(); + fill(cdot, cdot + m_kk, 0.0); + m_revProductStoich.incrementSpecies( + m_kdata->m_ropf.begin(), cdot); + m_irrevProductStoich.incrementSpecies( + m_kdata->m_ropf.begin(), cdot); + m_reactantStoich.incrementSpecies( + m_kdata->m_ropr.begin(), cdot); + } + + virtual void getDestructionRates(doublereal* ddot) { + updateROP(); + fill(ddot, ddot + m_kk, 0.0); + m_revProductStoich.incrementSpecies( + m_kdata->m_ropr.begin(), ddot); + m_reactantStoich.incrementSpecies( + m_kdata->m_ropf.begin(), ddot); + } + + virtual void getEquilibriumConstants(doublereal* kc); + + virtual void init(); + + /// Add a reaction to the mechanism. + virtual void addReaction(const ReactionData& r); + + virtual void finalize(); + virtual bool ready() const; + + //virtual void update_T(); + //virtual void update_C(); + + void updateROP(); + + virtual int reactionType(int i) const { + return m_index[i].first; + } + + virtual string reactionString(int i) const { + return m_rxneqn[i]; + } + + const vector& reactantGroups(int i) + { return m_rgroups[i]; } + const vector& productGroups(int i) + { return m_pgroups[i]; } + + virtual bool isReversible(int i) { + if (find(m_revindex.begin(), m_revindex.end(), i) + < m_revindex.end()) return true; + else return false; + } + + void _update_rates_T(); + void _update_rates_C(); + + protected: + + int m_kk; + + Rate1 m_rates; + + mutable map > m_index; + + vector m_irrev; + + StoichManagerN m_reactantStoich; + StoichManagerN m_revProductStoich; + StoichManagerN m_irrevProductStoich; + + StoichManagerN m_globalReactantStoich; + + int m_nirrev; + int m_nrev; + + map > m_rgroups; + map > m_pgroups; + + vector m_rxntype; + + mutable vector > m_rrxn; + mutable vector > m_prxn; + + vector_int m_revindex; + vector m_rxneqn; + + InterfaceKineticsData* m_kdata; + + vector_fp m_conc; + vector_fp m_mu0; + + private: + + int reactionNumber(){ return m_ii;} + void addElementaryReaction(const ReactionData& r); + void addGlobalReaction(const ReactionData& r); + void installReagents(const ReactionData& r); + + void installGroups(int irxn, const vector& r, + const vector& p); + void updateKc(); + + void registerReaction(int rxnNumber, int type, int loc) { + m_index[rxnNumber] = pair(type, loc); + } + bool m_finalized; + }; +} + +#endif diff --git a/Cantera/src/Jac2.h b/Cantera/src/Jac2.h new file mode 100755 index 000000000..65bedf19f --- /dev/null +++ b/Cantera/src/Jac2.h @@ -0,0 +1,198 @@ +/** + * + * @file Jac2.h + * + * >>>>> Under construction! <<<<< + * + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2002 California Institute of Technology + * + */ + +#ifndef CT_JAC2_H +#define CT_JAC2_H + + +#include "BandMatrix.h" +#include "ctlapack.h" +#include "../ext/math/gmres.h" +#include "stringUtils.h" +#include "Array.h" +#include "time.h" + +namespace Cantera { + + + /** + * Residual function evaluator for a one-dimensional problem. + */ + class ResidFunc2 { + public: + + /** + * Constructor. + * @param nv Number of variables at each grid point. + * @param points Number of grid points. + */ + ResidFunc2(int nv, int points) { + m_nv = nv; + m_points = points; + m_max.resize(m_nv, 0.0); + m_min.resize(m_nv, 0.0); + m_rtol.resize(m_nv, 0.0); + m_atol.resize(m_nv, 0.0); + m_slast.resize(m_nv, m_points); + m_rdt = 0.0; + + // m_soln.resize(m_nv, m_points, 0.0); + //m_resid.resize(m_nv, m_points, 0.0); + } + + /// Destructor. + virtual ~ResidFunc2(){} + + /// Number of components at each grid point. + int nComponents() const { return m_nv; } + + /// Number of grid points. + int nPoints() const { return m_points; } + + /// Name of the nth component. + virtual string componentName(int n) const { + return "component " + int2str(n); } + + void setBounds(const vector_fp& lower, const vector_fp& upper) { + if (lower.size() != m_nv || upper.size() != m_nv) + throw CanteraError("ResidFunc2::setBounds", + "wrong array size for solution bounds"); + m_max = upper; + m_min = lower; + } + + void setTolerances(vector_fp& rtol, vector_fp& atol) { + m_rtol = rtol; + m_atol = atol; + } + + doublereal rtol(int n) { return m_rtol[n]; } + doublereal atol(int n) { return m_atol[n]; } + + doublereal upperBound(int n) const { + return m_max[n]; + } + + doublereal lowerBound(int n) const { + return m_min[n]; + } + + + void initTimeInteg(doublereal dt, const Array2D& x0) { + m_slast = x0; + m_rdt = 1.0/dt; + } + + void setSteadyMode() { + m_rdt = 0.0; + } + + bool steady() { return (m_rdt == 0.0); } + bool transient() { return (m_rdt != 0.0); } + + /// Evaluate the residual function at point j. + virtual void eval(int j, Array2D& x, Array2D& r) { + throw CanteraError("ResidFunc2::eval", + "residual function not defined."); + } + + void evalss(Array2D& x, Array2D& r) { + doublereal rdt_save = m_rdt; + m_rdt = 0.0; + eval(-1, x, r); + m_rdt = rdt_save; + } + + protected: + int m_nv; + int m_points; + // Array2D m_soln; + //Array2D m_resid; + Array2D m_slast; + doublereal m_rdt; + vector_fp m_max; + vector_fp m_min; + vector_fp m_rtol; + vector_fp m_atol; + + private: + + }; + + + /////////////////////////////////////////////////////////////// + + + /** + * Class Jac2 evaluates the Jacobian of a system of equations + * defined by a residual function of class ResidFunc2. It is + * assumed that the Jacobian is banded. + */ + class Jac2 : public BandMatrix { + + public: + + /** + * Constructor. The residual function defining the system of + * equations must be supplied. + */ + Jac2(ResidFunc2& r); + + /// Destructor. Does nothing. + virtual ~Jac2(){} + + /** + * Evaluate the Jacobian. + */ + void eval(Array2D& x0, Array2D& resid0); + + /** + * Returns the matrix element describing the influence of the + * nth component at point j on the mth equation at point + * i. Due to the assumption of a banded Jacobian, this will be + * zero unless |i - j| <= 1. + */ + doublereal& v(int m, int i, int n, int j) { + return value(i*m_nv + m, j*m_nv + n); + } + + doublereal elapsedTime() const { + return m_elapsed; + } + + int nEvals() const { return m_nevals; } + + int age() const { return m_age; } + + void incrementAge() { m_age++; } + void setAge(int age) { m_age = age; } + + protected: + + ResidFunc2* m_resid; + Array2D m_r1; + int m_nv, m_points; + doublereal m_atol; + doublereal m_elapsed; + int m_nevals; + int m_age; + + private: + + }; +} + +#endif + + diff --git a/Cantera/src/Kinetics.h b/Cantera/src/Kinetics.h new file mode 100755 index 000000000..14650ebe2 --- /dev/null +++ b/Cantera/src/Kinetics.h @@ -0,0 +1,320 @@ +/** + * @file Kinetics.h + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + +/** + * @defgroup kineticsGroup Kinetics + */ + +#ifndef CT_KINETICS_H +#define CT_KINETICS_H + +#include "ctexceptions.h" +//#include "Phase.h" +#include "ThermoPhase.h" + +namespace Cantera { + + class ReactionData; + + /** + * Public interface for kinetics managers. This class serves as a + * base class to derive 'kinetics managers', which are classes + * that manage homogeneous chemistry within one phase. + */ + class Kinetics { + + public: + + // typedefs + typedef ThermoPhase thermo_t; + + /// Constructor. + Kinetics() : m_ii(0), m_thermo(0), m_index(-1) {} + Kinetics(thermo_t* thermo) + : m_ii(0), m_index(-1) { + if (thermo) { + m_start.push_back(0); + m_thermo.push_back(thermo); + } + } + + /// Destructor. Does nothing. + virtual ~Kinetics() {} // delete m_xml; } + + int index(){ return m_index; } + void setIndex(int index) { m_index = index; } + + //XML_Node& xml() { return *m_xml; } + + /// Identifies subclass. + virtual int type() { return 0; } + + int start(int n) { return m_start[n]; } + + /// Number of reactions + int nReactions() const {return m_ii;} + + /// Number of species + int nTotalSpecies() const { + int n=0, np; + np = nPhases(); + for (int p = 0; p < np; p++) n += thermo(p).nSpecies(); + return n; + } + + /** + * Stoichiometric coefficient of species k as a reactant in + * reaction i. + */ + virtual doublereal reactantStoichCoeff(int k, int i) const { + err("reactantStoichCoeff"); + return -1.0; + } + + /** + * Stoichiometric coefficient of species k as a product in + * reaction i. + */ + virtual doublereal productStoichCoeff(int k, int i) const { + err("productStoichCoeff"); + return -1.0; + } + + + /** + * Returns a read-only reference to the vector of reactant + * index numbers for reaction i. + */ + virtual const vector_int& reactants(int i) const { + return m_reactants[i]; + } + virtual const vector_int& products(int i) const { + return m_products[i]; + } + + /** + * Flag specifying the type of reaction. The legal values and + * their meaning are specific to the particular kinetics + * manager. + */ + virtual int reactionType(int i) const { + err("reactionType"); + return -1; + } + + /** + * @name Reaction Rates Of Progress + */ + //@{ + + /** + * Forward rates of progress. + * Return the forward rates of progress in array fwdROP, which + * must be dimensioned at least as large as the total number + * of reactions. + */ + virtual void getFwdRatesOfProgress(doublereal* fwdROP) { + err("getFwdRatesOfProgress"); + } + + /** + * Reverse rates of progress. + * Return the reverse rates of progress in array revROP, which + * must be dimensioned at least as large as the total number + * of reactions. + */ + virtual void getRevRatesOfProgress(doublereal* revROP) { + err("getRevRatesOfProgress"); + } + + /** + * Net rates of progress. Return the net (forward - reverse) + * rates of progress in array netROP, which must be + * dimensioned at least as large as the total number of + * reactions. + */ + virtual void getNetRatesOfProgress(doublereal* netROP) { + err("getNetRatesOfProgress"); + } + + /** + * True if reaction i has been declared to be reversible. If + * isReversible(i) is false, then the reverse rate of progress + * for reaction i is always zero. + */ + virtual bool isReversible(int i){return false;} + + /** + * Species creation rates [kmol/m^3]. Return the species + * creation rates in array cdot, which must be + * dimensioned at least as large as the total number of + * species. + * + */ + virtual void getCreationRates(doublereal* cdot) { + err("getCreationRates"); + } + + /** + * Species destruction rates [kmol/m^3]. Return the species + * destruction rates in array ddot, which must be + * dimensioned at least as large as the total number of + * species. + * + */ + virtual void getDestructionRates(doublereal* ddot) { + err("getDestructionRates"); + } + + /** + * Species net production rates [kmol/m^3]. Return the species + * net production rates (creation - destruction) in array + * wdot, which must be dimensioned at least as large as the + * total number of species. + */ + virtual void getNetProductionRates(doublereal* wdot) { + err("getNetProductionRates"); + } + + /** + * Equilibrium constants. Return the equilibrium constants of + * the reactions in concentration units in array kc, which + * must be dimensioned at least as large as the total number + * of reactions. + */ + virtual void getEquilibriumConstants(doublereal* kc) { + err("getEquilibriumConstants"); + } + //@} + + + /** + * @name Reaction Mechanism Construction + */ + //@{ + + + /** + * Get the nth Phase object. + */ + //phase_t& phase(int n=0) { return *m_phase[n]; } + //const phase_t& phase(int n=0) const { return *m_phase[n]; } + int nPhases() const { return m_thermo.size(); } + int phaseIndex(string ph) { return m_phaseindex[ph] - 1; } + + /** + * Add a phase. + */ + void addPhase(thermo_t& thermo) { + if (m_thermo.size() > 0) { + m_start.push_back(m_start.back() + + m_thermo.back()->nSpecies()); + } + else { + m_start.push_back(0); + } + m_thermo.push_back(&thermo); + m_phaseindex[m_thermo.back()->id()] = nPhases(); + } + thermo_t& thermo(int n=0) { return *m_thermo[n]; } + const thermo_t& thermo(int n=0) const { return *m_thermo[n]; } + thermo_t& phase(int n=0) { return *m_thermo[n]; } + const thermo_t& phase(int n=0) const { return *m_thermo[n]; } + + int kineticsSpeciesIndex(int k, int n) { + return m_start[n] + k; + } + + int kineticsSpeciesIndex(string nm, string ph = "") { + int np = m_thermo.size(); + int k; + string id; + for (int n = 0; n < np; n++) { + id = thermo(n).id(); + if (ph == id) { + k = thermo(n).speciesIndex(nm); + if (k < 0) return -1; + return k + m_start[n]; + } + else if (ph == "") { + k = thermo(n).speciesIndex(nm); + if (k >= 0) return k + m_start[n]; + } + } + return -2; + } + + /** + * Prepare to add reactions. + */ + virtual void init() {err("init");} + + /// Finished adding reactions. Prepare for use. + virtual void finalize() {err("finalize");} + + virtual void addReaction(const ReactionData& r) {err("addReaction");} + + virtual string reactionString(int i) const { + err("reactionString"); return ""; + } + + + virtual const vector& reactantGroups(int i) + { err("reactantGroups"); return m_dummygroups; } + + virtual const vector& productGroups(int i) + { err("productGroups"); return m_dummygroups; } + + /** + * @name Altering Reaction Rates + * + * These methods alter reaction rates. They are designed + * primarily for carrying out sensitivity analysis. + */ + //@{ + + /// The current value of the multiplier for reaction i. + doublereal multiplier(int i) const {return m_perturb[i];} + + /// Set the multiplier for reaction i to f. + void setMultiplier(int i, doublereal f) {m_perturb[i] = f;} + + //@} + + void incrementRxnCount() { m_ii++; m_perturb.push_back(1.0); } + + virtual bool ready() const {return false;} + + protected: + + int m_ii; + vector_fp m_perturb; + vector m_reactants; + vector m_products; + vector m_thermo; + vector_int m_start; + // XML_Node* m_xml; + map m_phaseindex; + int m_index; + + private: + + vector m_dummygroups; + void err(string m) const { + throw CanteraError("Kinetics::"+m,"Base class method called."); + } + }; + + typedef Kinetics kinetics_t; +} + + + +#endif diff --git a/Cantera/src/KineticsFactory.cpp b/Cantera/src/KineticsFactory.cpp new file mode 100644 index 000000000..0c77ae7f6 --- /dev/null +++ b/Cantera/src/KineticsFactory.cpp @@ -0,0 +1,106 @@ +/** + * @file KineticsFactory.cpp + */ + +/* + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifdef WIN32 +#pragma warning(disable:4786) +#endif + +#include "KineticsFactory.h" + +#include "GasKinetics.h" +#include "GRI_30_Kinetics.h" +#include "InterfaceKinetics.h" + +#include "importCTML.h" + +namespace Cantera { + + KineticsFactory* KineticsFactory::__factory = 0; + + static int ntypes = 3; + static string _types[] = {"GasKinetics", "GRI30", "Interface"}; + static int _itypes[] = {cGasKinetics, cGRI30, cInterfaceKinetics}; + + + /** + * Return a new kinetics manager that implements a reaction + * mechanism specified in a CTML file. + */ + Kinetics* KineticsFactory::newKinetics(XML_Node& phase, + vector th) { + + string kintype = phase.child("kinetics")["model"]; + int ikin=-1; + int n; + for (n = 0; n < ntypes; n++) { + if (kintype == _types[n]) ikin = _itypes[n]; + } + Kinetics* k=0; + switch (ikin) { + + case cGasKinetics: + k = new GasKinetics; + break; + + case cGRI30: + k = new GRI_30_Kinetics; + break; + + case cInterfaceKinetics: + k = new InterfaceKinetics; + break; + + default: + throw CanteraError("newKinetics", + "unknown kinetics manager: "+kintype); + } + + // import the reaction mechanism + importKinetics(phase, th, k); + return k; + } + + + /** + * Return a new, empty kinetics manager. + */ + Kinetics* KineticsFactory::newKinetics(string model) { + + int ikin = -1; + int n; + for (n = 0; n < ntypes; n++) { + if (model == _types[n]) ikin = _itypes[n]; + } + Kinetics* k=0; + switch (ikin) { + + case cGasKinetics: + k = new GasKinetics; + break; + + case cGRI30: + k = new GRI_30_Kinetics; + break; + + case cInterfaceKinetics: + k = new InterfaceKinetics; + break; + + default: + throw CanteraError("newKinetics", + "unknown kinetics manager: "+model); + } + return k; + } + +} diff --git a/Cantera/src/KineticsFactory.h b/Cantera/src/KineticsFactory.h new file mode 100644 index 000000000..b3da2e2f6 --- /dev/null +++ b/Cantera/src/KineticsFactory.h @@ -0,0 +1,80 @@ +/** + * @file KineticsFactory.h + */ + +/* + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef KINETICS_FACTORY_H +#define KINETICS_FACTORY_H + +#include "Kinetics.h" +#include "xml.h" + +namespace Cantera { + + /** + * Factory for kinetics managers. + */ + class KineticsFactory { + + public: + + static KineticsFactory* factory() { + if (!__factory) __factory = new KineticsFactory; + return __factory; + } + + virtual ~KineticsFactory() { + delete __factory; + __factory = 0; + } + + /** + * Create a new kinetics manager. + */ + virtual Kinetics* newKinetics(XML_Node& phase, + vector th); + + virtual Kinetics* newKinetics(string model); + + private: + + static KineticsFactory* __factory; + KineticsFactory(){} + }; + + + /** + * Create a new thermo manager instance. + */ + inline Kinetics* newKineticsMgr(XML_Node& phase, + vector th, KineticsFactory* f=0) { + if (f == 0) { + f = KineticsFactory::factory(); + } + Kinetics* kin = f->newKinetics(phase, th); + return kin; + } + + /** + * Create a new thermo manager instance. + */ + inline Kinetics* newKineticsMgr(string model, KineticsFactory* f=0) { + if (f == 0) { + f = KineticsFactory::factory(); + } + Kinetics* kin = f->newKinetics(model); + return kin; + } +} + +#endif + + diff --git a/Cantera/src/L_matrix.h b/Cantera/src/L_matrix.h new file mode 100755 index 000000000..9f2fec8b2 --- /dev/null +++ b/Cantera/src/L_matrix.h @@ -0,0 +1,254 @@ +/** + * @file L_matrix.h + * + * functions to evaluate portions of the L matrix needed for + * multicomponent transport properties. + */ + +#ifndef CT_LMATRIX_H +#define CT_LMATRIX_H + +// turn off warnings under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "DenseMatrix.h" +#include "ct_defs.h" + +#include +using namespace std; +using namespace Cantera; + + +///////////////////////////////////////////////////////////////////// + +namespace Cantera { + + // #define CHEMKIN_COMPATIBILITY_MODE + + const doublereal Min_C_Internal = 0.001; + + bool MultiTransport::hasInternalModes(int j) { +#ifdef CHEMKIN_COMPATIBILITY_MODE + return (m_crot[j] > Min_C_Internal); +#else + return (m_cinternal[j] > Min_C_Internal); +#endif + } + + + /** + * Evaluate the upper-left block of the L matrix. + */ + void MultiTransport::eval_L0000(const doublereal* x) { + + doublereal prefactor = 16.0*m_temp/25.0; + doublereal sum; + int i, j, k; + for (i = 0; i < m_nsp; i++) + { + // subtract-off the k=i term to account for the first delta + // function in Eq. (12.121) + + sum = -x[i]/m_bdiff(i,i); + for (k = 0; k < m_nsp; k++) sum += x[k]/m_bdiff(i,k); + + sum /= m_mw[i]; + for (j = 0; j != m_nsp; ++j) { + m_Lmatrix(i,j) = prefactor * x[j] + * ( m_mw[j] * sum + x[i]/m_bdiff(i,j) ); + } + // diagonal term is zero + m_Lmatrix(i,i) = 0.0; + } + } + + + //////////////////////////////////////////////////////////////////////////// + + + void MultiTransport::eval_L0010(const doublereal* x) { + + doublereal prefactor = 1.6*m_temp; + + doublereal sum, wj, xj; + int i, j; + for (j = 0; j < m_nsp; j++) { + //constant = prefactor * x[j]; + xj = x[j]; + wj = m_mw[j]; + sum = 0.0; + for (i = 0; i < m_nsp; i++) { + m_Lmatrix(i,j + m_nsp) = - prefactor * x[i] * xj * m_mw[i] * + (1.2 * m_cstar(j,i) - 1.0) / + ( (wj + m_mw[i]) * m_bdiff(j,i) ); + + // the next term is independent of "j"; + // need to do it for the "j,j" term + sum -= m_Lmatrix(i,j+m_nsp); + } + m_Lmatrix(j,j+m_nsp) += sum; + } + } + + + + //////////////////////////////////////////////////////////////////////// + + void MultiTransport::eval_L1000() { + int i, j; + for (j = 0; j < m_nsp; j++) + for (i = 0; i < m_nsp; i++) + m_Lmatrix(i+m_nsp,j) = m_Lmatrix(j,i+m_nsp); + } + + + ////////////////////////////////////////////////////////////////////// + + void MultiTransport::eval_L1010(const doublereal* x) { + + const doublereal fiveover3pi = 5.0/(3.0*Pi); + doublereal prefactor = (16.0*m_temp)/25.0; + + int i, j; + doublereal constant1, wjsq, constant2, constant3, constant4, + fourmj, threemjsq, sum, sumwij;; + doublereal term1, term2; + + for (j = 0; j < m_nsp; j++) { + + // get constant terms that depend on just species "j" + + constant1 = prefactor*x[j]; + wjsq = m_mw[j]*m_mw[j]; + constant2 = 13.75*wjsq; + constant3 = m_crot[j]/m_rotrelax[j]; + constant4 = 7.5*wjsq; + fourmj = 4.0*m_mw[j]; + threemjsq = 3.0*m_mw[j]*m_mw[j]; + sum = 0.0; + for (i = 0; i < m_nsp; i++) { + + sumwij = m_mw[i] + m_mw[j]; + term1 = m_bdiff(i,j) * sumwij*sumwij; + term2 = fourmj*m_astar(i,j)*(1.0 + fiveover3pi* + (constant3 + + (m_crot[i]/m_rotrelax[i]))); // see Eq. (12.125) + + m_Lmatrix(i+m_nsp,j+m_nsp) = constant1*x[i]*m_mw[i] /(m_mw[j]*term1) * + (constant2 - threemjsq*m_bstar(i,j) + - term2*m_mw[j]); + + sum += x[i] /(term1) * + (constant4 + m_mw[i]*m_mw[i]* + (6.25 - 3.0*m_bstar(i,j)) + term2*m_mw[i]); + } + + m_Lmatrix(j+m_nsp,j+m_nsp) -= sum*constant1; + } + } + + + ////////////////////////////////////////////////////////////////////////////////// + + void MultiTransport::eval_L1001(const doublereal* x) { + + doublereal prefactor = 32.00*m_temp/(5.00*Pi); + int i,j; + doublereal constant, sum; + int n2 = 2*m_nsp; + int npoly = 0; + for (j = 0; j < m_nsp; j++) { + // collect terms that depend only on "j" + if (hasInternalModes(j)) { + constant = prefactor*m_mw[j]*x[j]*m_crot[j]/(m_cinternal[j]*m_rotrelax[j]); + sum = 0.0; + for (i = 0; i < m_nsp; i++) { + // see Eq. (12.127) + m_Lmatrix(i+m_nsp,j+n2) = constant * m_astar(j,i) * x[i] / + ( (m_mw[j] + m_mw[i] ) * m_bdiff(j,i)); + sum += m_Lmatrix(i+m_nsp,j+n2); + } + npoly++; + m_Lmatrix(j+m_nsp,j+n2) += sum; + } + else { + for (i = 0; i < m_nsp; i++) m_Lmatrix(i+m_nsp,j+n2) = 0.0; + } + } + } + + //////////////////////////////////////////////////////////////////////// + + void MultiTransport::eval_L0001() { + int i, j; + int n2 = 2*m_nsp; + for (j = 0; j < m_nsp; j++) + for (i = 0; i < m_nsp; i++) + m_Lmatrix(i,j+n2) = 0.0; + } + + //////////////////////////////////////////////////////////////////////// + + void MultiTransport::eval_L0100() { + int i, j; + int n2 = 2*m_nsp; + for (j = 0; j < m_nsp; j++) + for (i = 0; i < m_nsp; i++) + m_Lmatrix(i+n2,j) = 0.0; // see Eq. (12.123) + } + + //////////////////////////////////////////////////////////////////////// + + void MultiTransport::eval_L0110() { + int i, j; + int n2 = 2*m_nsp; + for (j = 0; j < m_nsp; j++) + for (i = 0; i < m_nsp; i++) + m_Lmatrix(i+n2,j+m_nsp) = m_Lmatrix(j+m_nsp,i+n2); // see Eq. (12.123) + } + + //////////////////////////////////////////////////////////////////////// + + + void MultiTransport::eval_L0101(const doublereal* x) { + + const doublereal fivepi = 5.00*Pi; + const doublereal eightoverpi = 8.0 / Pi; + + doublereal prefactor = 4.00*m_temp; + int n2 = 2*m_nsp; + int i,k; + doublereal constant1, constant2, diff_int, sum; + for (i = 0; i < m_nsp; i++) { + if (hasInternalModes(i)) { + // collect terms that depend only on "i" + constant1 = prefactor*x[i]/m_cinternal[i]; + constant2 = 12.00*m_mw[i]*m_crot[i] / + (fivepi*m_cinternal[i]*m_rotrelax[i]); + sum = 0.0; + for (k = 0; k < m_nsp; k++) { + // see Eq. (12.131) + diff_int = m_bdiff(i,k); + m_Lmatrix(k+n2,i+n2) = 0.0; + sum += x[k]/diff_int; + if (k != i) sum += x[k]*m_astar(i,k)*constant2 / + (m_mw[k]*diff_int); + } + // see Eq. (12.130) + m_Lmatrix(i+n2,i+n2) = + - eightoverpi*m_mw[i]*x[i]*x[i]*m_crot[i] / + (m_cinternal[i]*m_cinternal[i]*GasConstant*m_visc[i]*m_rotrelax[i]) + - constant1*sum; + } + else { + for (k = 0; k < m_nsp; k++) + m_Lmatrix(i+n2,i+n2) = 1.0; + } + } + } +} + +#endif diff --git a/Cantera/src/MMCollisionInt.cpp b/Cantera/src/MMCollisionInt.cpp new file mode 100755 index 000000000..63fb4e3b8 --- /dev/null +++ b/Cantera/src/MMCollisionInt.cpp @@ -0,0 +1,501 @@ +/** + * @file MMCollisionInt.cpp + */ + +/* + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology */ + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "MMCollisionInt.h" +#include "polyfit.h" +#include "xml.h" +#include + +namespace Cantera { + + const int DeltaDegree = 6; + + double MMCollisionInt::delta[8] = {0.0, 0.25, 0.50, 0.75, 1.0, + 1.5, 2.0, 2.5}; + + doublereal quadInterp(doublereal x0, doublereal* x, doublereal* y) { + doublereal dx21, dx32, dx31, dy32, dy21, a; + dx21 = x[1] - x[0]; + dx32 = x[2] - x[1]; + dx31 = dx21 + dx32; + dy32 = y[2] - y[1]; + dy21 = y[1] - y[0]; + a = (dx21*dy32 - dy21*dx32)/(dx21*dx31*dx32); + return a*(x0 - x[0])*(x0 - x[1]) + (dy21/dx21)*(x0 - x[1]) + y[1]; + } + + + double MMCollisionInt::tstar22[37] = + {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, + 1.2, 1.4, 1.6, 1.8, 2.0, 2.5, 3.0, 3.5, 4.0, + 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 12.0, 14.0, 16.0, + 18.0, 20.0, 25.0, 30.0, 35.0, 40.0, 50.0, 75.0, 100.0}; + + + double MMCollisionInt::omega22_table[37*8] = { + 4.1005, 4.266, 4.833, 5.742, 6.729, 8.624, 10.34, 11.89, + 3.2626, 3.305, 3.516, 3.914, 4.433, 5.57, 6.637, 7.618, + 2.8399, 2.836, 2.936, 3.168, 3.511, 4.329, 5.126, 5.874, + 2.531, 2.522, 2.586, 2.749, 3.004, 3.64, 4.282, 4.895, + 2.2837, 2.277, 2.329, 2.46, 2.665, 3.187, 3.727, 4.249, + 2.0838, 2.081, 2.13, 2.243, 2.417, 2.862, 3.329, 3.786, + 1.922, 1.924, 1.97, 2.072, 2.225, 2.614, 3.028, 3.435, + 1.7902, 1.795, 1.84, 1.934, 2.07, 2.417, 2.788, 3.156, + 1.6823, 1.689, 1.733, 1.82, 1.944, 2.258, 2.596, 2.933, + 1.5929, 1.601, 1.644, 1.725, 1.838, 2.124, 2.435, 2.746, + 1.4551, 1.465, 1.504, 1.574, 1.67, 1.913, 2.181, 2.451, + 1.3551, 1.365, 1.4, 1.461, 1.544, 1.754, 1.989, 2.228, + 1.28, 1.289, 1.321, 1.374, 1.447, 1.63, 1.838, 2.053, + 1.2219, 1.231, 1.259, 1.306, 1.37, 1.532, 1.718, 1.912, + 1.1757, 1.184, 1.209, 1.251, 1.307, 1.451, 1.618, 1.795, + 1.0933, 1.1, 1.119, 1.15, 1.193, 1.304, 1.435, 1.578, + 1.0388, 1.044, 1.059, 1.083, 1.117, 1.204, 1.31, 1.428, + 0.99963, 1.004, 1.016, 1.035, 1.062, 1.133, 1.22, 1.319, + 0.96988, 0.9732, 0.983, 0.9991, 1.021, 1.079, 1.153, 1.236, + 0.92676, 0.9291, 0.936, 0.9473, 0.9628, 1.005, 1.058, 1.121, + 0.89616, 0.8979, 0.903, 0.9114, 0.923, 0.9545, 0.9955, 1.044, + 0.87272, 0.8741, 0.878, 0.8845, 0.8935, 0.9181, 0.9505, 0.9893, + 0.85379, 0.8549, 0.858, 0.8632, 0.8703, 0.8901, 0.9164, 0.9482, + 0.83795, 0.8388, 0.8414, 0.8456, 0.8515, 0.8678, 0.8895, 0.916, + 0.82435, 0.8251, 0.8273, 0.8308, 0.8356, 0.8493, 0.8676, 0.8901, + 0.80184, 0.8024, 0.8039, 0.8065, 0.8101, 0.8201, 0.8337, 0.8504, + 0.78363, 0.784, 0.7852, 0.7872, 0.7899, 0.7976, 0.8081, 0.8212, + 0.76834, 0.7687, 0.7696, 0.7712, 0.7733, 0.7794, 0.7878, 0.7983, + 0.75518, 0.7554, 0.7562, 0.7575, 0.7592, 0.7642, 0.7711, 0.7797, + 0.74364, 0.7438, 0.7445, 0.7455, 0.747, 0.7512, 0.7569, 0.7642, + 0.71982, 0.72, 0.7204, 0.7211, 0.7221, 0.725, 0.7289, 0.7339, + 0.70097, 0.7011, 0.7014, 0.7019, 0.7026, 0.7047, 0.7076, 0.7112, + 0.68545, 0.6855, 0.6858, 0.6861, 0.6867, 0.6883, 0.6905, 0.6932, + 0.67232, 0.6724, 0.6726, 0.6728, 0.6733, 0.6743, 0.6762, 0.6784, + 0.65099, 0.651, 0.6512, 0.6513, 0.6516, 0.6524, 0.6534, 0.6546, + 0.61397, 0.6141, 0.6143, 0.6145, 0.6147, 0.6148, 0.6148, 0.6147, + 0.5887, 0.5889, 0.5894, 0.59, 0.5903, 0.5901, 0.5895, 0.5885 + }; + + //----------------------------- + + double MMCollisionInt::tstar[39] = { + 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, + 1.2, 1.4, 1.6, 1.8, 2.0, 2.5, 3.0, 3.5, 4.0, + 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 12.0, 14.0, 16.0, + 18.0, 20.0, 25.0, 30.0, 35.0, 40.0, 50.0, 75.0, 100.0, 1.e10}; + + double MMCollisionInt::astar_table[39*8] = { + 1.0065, 1.0840, 1.0840, 1.0840, 1.0840, 1.0840, 1.0840, 1.0840, + 1.0231, 1.0660, 1.0380, 1.0400, 1.0430, 1.0500, 1.0520, 1.0510, + 1.0424, 1.0450, 1.0480, 1.0520, 1.0560, 1.0650, 1.0660, 1.0640, + 1.0719, 1.0670, 1.0600, 1.0550, 1.0580, 1.0680, 1.0710, 1.0710, + 1.0936, 1.0870, 1.0770, 1.0690, 1.0680, 1.0750, 1.0780, 1.0780, + 1.1053, 1.0980, 1.0880, 1.0800, 1.0780, 1.0820, 1.0840, 1.0840, + 1.1104, 1.1040, 1.0960, 1.0890, 1.0860, 1.0890, 1.0900, 1.0900, + 1.1114, 1.1070, 1.1000, 1.0950, 1.0930, 1.0950, 1.0960, 1.0950, + 1.1104, 1.1070, 1.1020, 1.0990, 1.0980, 1.1000, 1.1000, 1.0990, + 1.1086, 1.1060, 1.1020, 1.1010, 1.1010, 1.1050, 1.1050, 1.1040, + 1.1063, 1.1040, 1.1030, 1.1030, 1.1040, 1.1080, 1.1090, 1.1080, + 1.1020, 1.1020, 1.1030, 1.1050, 1.1070, 1.1120, 1.1150, 1.1150, + 1.0985, 1.0990, 1.1010, 1.1040, 1.1080, 1.1150, 1.1190, 1.1200, + 1.0960, 1.0960, 1.0990, 1.1030, 1.1080, 1.1160, 1.1210, 1.1240, + 1.0943, 1.0950, 1.0990, 1.1020, 1.1080, 1.1170, 1.1230, 1.1260, + 1.0934, 1.0940, 1.0970, 1.1020, 1.1070, 1.1160, 1.1230, 1.1280, + 1.0926, 1.0940, 1.0970, 1.0990, 1.1050, 1.1150, 1.1230, 1.1300, + 1.0934, 1.0950, 1.0970, 1.0990, 1.1040, 1.1130, 1.1220, 1.1290, + 1.0948, 1.0960, 1.0980, 1.1000, 1.1030, 1.1120, 1.1190, 1.1270, + 1.0965, 1.0970, 1.0990, 1.1010, 1.1040, 1.1100, 1.1180, 1.1260, + 1.0997, 1.1000, 1.1010, 1.1020, 1.1050, 1.1100, 1.1160, 1.1230, + 1.1025, 1.1030, 1.1040, 1.1050, 1.1060, 1.1100, 1.1150, 1.1210, + 1.1050, 1.1050, 1.1060, 1.1070, 1.1080, 1.1110, 1.1150, 1.1200, + 1.1072, 1.1070, 1.1080, 1.1080, 1.1090, 1.1120, 1.1150, 1.1190, + 1.1091, 1.1090, 1.1090, 1.1100, 1.1110, 1.1130, 1.1150, 1.1190, + 1.1107, 1.1110, 1.1110, 1.1110, 1.1120, 1.1140, 1.1160, 1.1190, + 1.1133, 1.1140, 1.1130, 1.1140, 1.1140, 1.1150, 1.1170, 1.1190, + 1.1154, 1.1150, 1.1160, 1.1160, 1.1160, 1.1170, 1.1180, 1.1200, + 1.1172, 1.1170, 1.1170, 1.1180, 1.1180, 1.1180, 1.1190, 1.1200, + 1.1186, 1.1190, 1.1190, 1.1190, 1.1190, 1.1190, 1.1200, 1.1210, + 1.1199, 1.1200, 1.1200, 1.1200, 1.1200, 1.1210, 1.1210, 1.1220, + 1.1223, 1.1220, 1.1220, 1.1220, 1.1220, 1.1230, 1.1230, 1.1240, + 1.1243, 1.1240, 1.1240, 1.1240, 1.1240, 1.1240, 1.1250, 1.1250, + 1.1259, 1.1260, 1.1260, 1.1260, 1.1260, 1.1260, 1.1260, 1.1260, + 1.1273, 1.1270, 1.1270, 1.1270, 1.1270, 1.1270, 1.1270, 1.1280, + 1.1297, 1.1300, 1.1300, 1.1300, 1.1300, 1.1300, 1.1300, 1.1290, + 1.1339, 1.1340, 1.1340, 1.1350, 1.1350, 1.1340, 1.1340, 1.1320, + 1.1364, 1.1370, 1.1370, 1.1380, 1.1390, 1.1380, 1.1370, 1.1350, + 1.14187, 1.14187, 1.14187, 1.14187, 1.14187, 1.14187, 1.14187, + 1.14187 }; + + double MMCollisionInt::bstar_table[39*8] = { + 1.1852, 1.2963, 1.2963, 1.2963, 1.2963, 1.2963,1.2963, 1.2963, + 1.1960, 1.216, 1.237, 1.269, 1.285, 1.290, 1.297, 1.294, + 1.2451, 1.257, 1.340, 1.389, 1.366, 1.327, 1.314, 1.278, + 1.2900, 1.294, 1.272, 1.258, 1.262, 1.282, 1.290, 1.299, + 1.2986, 1.291, 1.284, 1.278, 1.277, 1.288, 1.294, 1.297, + 1.2865, 1.281, 1.276, 1.272, 1.277, 1.286, 1.292, 1.298, + 1.2665, 1.264, 1.261, 1.263, 1.269, 1.284, 1.292, 1.298, + 1.2455, 1.244, 1.248, 1.255, 1.262, 1.278, 1.289, 1.296, + 1.2253, 1.225, 1.234, 1.240, 1.252, 1.271, 1.284, 1.295, + 1.2078, 1.210, 1.216, 1.227, 1.242, 1.264, 1.281, 1.292, + 1.1919, 1.192, 1.205, 1.216, 1.230, 1.256, 1.273, 1.287, + 1.1678, 1.172, 1.181, 1.195, 1.209, 1.237, 1.261, 1.277, + 1.1496, 1.155, 1.161, 1.174, 1.189, 1.221, 1.246, 1.266, + 1.1366, 1.141, 1.147, 1.159, 1.174, 1.202, 1.231, 1.256, + 1.1270, 1.130, 1.138, 1.148, 1.162, 1.191, 1.218, 1.242, + 1.1197, 1.122, 1.129, 1.140, 1.149, 1.178, 1.205, 1.231, + 1.1080, 1.110, 1.116, 1.122, 1.132, 1.154, 1.180, 1.205, + 1.1016, 1.103, 1.107, 1.112, 1.120, 1.138, 1.160, 1.183, + 1.0980, 1.099, 1.102, 1.106, 1.112, 1.127, 1.145, 1.165, + 1.0958, 1.097, 1.099, 1.102, 1.107, 1.119, 1.135, 1.153, + 1.0935, 1.094, 1.095, 1.097, 1.100, 1.109, 1.120, 1.134, + 1.0925, 1.092, 1.094, 1.095, 1.098, 1.104, 1.112, 1.122, + 1.0922, 1.092, 1.093, 1.094, 1.096, 1.100, 1.106, 1.115, + 1.0922, 1.092, 1.093, 1.093, 1.095, 1.098, 1.103, 1.110, + 1.0923, 1.092, 1.093, 1.093, 1.094, 1.097, 1.101, 1.106, + 1.0923, 1.092, 1.092, 1.093, 1.094, 1.096, 1.099, 1.103, + 1.0927, 1.093, 1.093, 1.093, 1.094, 1.095, 1.098, 1.101, + 1.0930, 1.093, 1.093, 1.093, 1.094, 1.094, 1.096, 1.099, + 1.0933, 1.094, 1.093, 1.094, 1.094, 1.095, 1.096, 1.098, + 1.0937, 1.093, 1.094, 1.094, 1.094, 1.094, 1.096, 1.097, + 1.0939, 1.094, 1.094, 1.094, 1.094, 1.095, 1.095, 1.097, + 1.0943, 1.094, 1.094, 1.094, 1.095, 1.095, 1.096, 1.096, + 1.0944, 1.095, 1.094, 1.094, 1.094, 1.095, 1.095, 1.096, + 1.0944, 1.094, 1.095, 1.094, 1.094, 1.095, 1.096, 1.096, + 1.0943, 1.095, 1.094, 1.094, 1.095, 1.095, 1.095, 1.095, + 1.0941, 1.094, 1.094, 1.094, 1.094, 1.094, 1.094, 1.096, + 1.0947, 1.095, 1.094, 1.094, 1.093, 1.093, 1.094, 1.095, + 1.0957, 1.095, 1.094, 1.093, 1.092, 1.093, 1.093, 1.094, + 1.10185, 1.10185, 1.10185, 1.10185, 1.10185, 1.10185, 1.10185, + 1.10185}; + + + double MMCollisionInt::cstar_table[39*8] = { + 0.8889, 0.77778, 0.77778,0.77778,0.77778,0.77778,0.77778,0.77778, + 0.88575, 0.8988, 0.8378, 0.8029, 0.7876, 0.7805, 0.7799, 0.7801, + 0.87268, 0.8692,0.8647,0.8479,0.8237,0.7975,0.7881,0.7784, + 0.85182, 0.8525,0.8366,0.8198,0.8054,0.7903,0.7839,0.782, + 0.83542, 0.8362,0.8306,0.8196,0.8076,0.7918,0.7842,0.7806, + 0.82629, 0.8278,0.8252,0.8169,0.8074,0.7916,0.7838,0.7802, + 0.82299, 0.8249,0.823,0.8165,0.8072,0.7922,0.7839,0.7798, + 0.82357, 0.8257,0.8241,0.8178,0.8084,0.7927,0.7839,0.7794, + 0.82657, 0.828,0.8264,0.8199,0.8107,0.7939,0.7842,0.7796, + 0.8311, 0.8234,0.8295,0.8228,0.8136,0.796,0.7854,0.7798, + 0.8363, 0.8366,0.8342,0.8267,0.8168,0.7986,0.7864,0.7805, + 0.84762, 0.8474,0.8438,0.8358,0.825,0.8041,0.7904,0.7822, + 0.85846, 0.8583,0.853,0.8444,0.8336,0.8118,0.7957,0.7854, + 0.8684, 0.8674,0.8619,0.8531,0.8423,0.8186,0.8011,0.7898, + 0.87713, 0.8755,0.8709,0.8616,0.8504,0.8265,0.8072,0.7939, + 0.88479, 0.8831,0.8779,0.8695,0.8578,0.8338,0.8133,0.799, + 0.89972, 0.8986,0.8936,0.8846,0.8742,0.8504,0.8294,0.8125, + 0.91028, 0.9089,0.9043,0.8967,0.8869,0.8649,0.8438,0.8253, + 0.91793, 0.9166,0.9125,0.9058,0.897,0.8768,0.8557,0.8372, + 0.92371, 0.9226,0.9189,0.9128,0.905,0.8861,0.8664,0.8484, + 0.93135, 0.9304,0.9274,0.9226,0.9164,0.9006,0.8833,0.8662, + 0.93607, 0.9353,0.9329,0.9291,0.924,0.9109,0.8958,0.8802, + 0.93927, 0.9387,0.9366,0.9334,0.9292,0.9162,0.905,0.8911, + 0.94149, 0.9409,0.9393,0.9366,0.9331,0.9236,0.9122,0.8997, + 0.94306, 0.9426,0.9412,0.9388,0.9357,0.9276,0.9175,0.9065, + 0.94419, 0.9437,0.9425,0.9406,0.938,0.9308,0.9219,0.9119, + 0.94571, 0.9455,0.9445,0.943,0.9409,0.9353,0.9283,0.9201, + 0.94662, 0.9464,0.9456,0.9444,0.9428,0.9382,0.9325,0.9258, + 0.94723, 0.9471,0.9464,0.9455,0.9442,0.9405,0.9355,0.9298, + 0.94764, 0.9474,0.9469,0.9462,0.945,0.9418,0.9378,0.9328, + 0.9479, 0.9478,0.9474,0.9465,0.9457,0.943,0.9394,0.9352, + 0.94827, 0.9481,0.948,0.9472,0.9467,0.9447,0.9422,0.9391, + 0.94842, 0.9484,0.9481,0.9478,0.9472,0.9458,0.9437,0.9415, + 0.94852, 0.9484,0.9483,0.948,0.9475,0.9465,0.9449,0.943, + 0.94861, 0.9487,0.9484,0.9481,0.9479,0.9468,0.9455,0.943, + 0.94872, 0.9486,0.9486,0.9483,0.9482,0.9475,0.9464,0.9452, + 0.94881, 0.9488,0.9489,0.949,0.9487,0.9482,0.9476,0.9468, + 0.94863, 0.9487,0.9489,0.9491,0.9493,0.9491,0.9483,0.9476, + 0.94444, 0.94444,0.94444,0.94444,0.94444,0.94444,0.94444,0.94444}; + + + void MMCollisionInt::init(XML_Writer* xml, + doublereal tsmin, doublereal tsmax, int log_level) { + ostream& logfile = xml->output(); + m_xml = xml; + m_loglevel = log_level; + m_xml->XML_comment(logfile, "Collision Integral Polynomial Fits"); + m_nmin = -1; + m_nmax = -1; + char p[200]; + for (int n = 0; n < 37; n++) { + if (tsmin > tstar[n+1]) m_nmin = n; + if (tsmax > tstar[n+1]) m_nmax = n+1; + } + if (m_nmin < 0 || m_nmin >= 36 || m_nmax < 0 || m_nmax > 36) { + m_nmin = 0; + } + m_xml->XML_item(logfile, "Tstar_min", tstar[m_nmin + 1]); + m_xml->XML_item(logfile, "Tstar_max", tstar[m_nmax + 1]); + m_logTemp.resize(37); + doublereal rmserr, e22 = 0.0, ea = 0.0, eb = 0.0, ec = 0.0; + + m_xml->XML_open(logfile, "dstar_fits"); + m_xml->XML_comment(logfile, "Collision integral fits at each " + "tabulated T* vs. delta*.\n" + "These polynomial fits are used to interpolate between " + "columns (delta*)\n in the Monchick and Mason tables." + " They are only used for nonzero delta*."); + if (log_level < 4) { + m_xml->XML_comment(logfile, + "polynomial coefficients not printed (log_level < 4)"); + } + + string indent = " "; + for (int i = 0; i < 37; i++) + { + m_logTemp[i] = log(tstar[i+1]); + vector_fp c(DeltaDegree+1); + + rmserr = fitDelta(0, i, DeltaDegree, c.begin()); + if (log_level > 3) { + sprintf(p, " Tstar=\"%12.6g\"", tstar[i+1]); + m_xml->XML_open(logfile, "dstar_fit", p); + m_xml->XML_item(logfile, "Tstar", tstar[i+1]); + m_xml->XML_writeVector(logfile, indent, "omega22", + c.size(), c.begin()); + } + m_o22poly.push_back(c); + if (rmserr > e22) e22 = rmserr; + + rmserr = fitDelta(1, i, DeltaDegree, c.begin()); + m_apoly.push_back(c); + if (log_level > 3) + m_xml->XML_writeVector(logfile, indent, "astar", + c.size(), c.begin()); + if (rmserr > ea) ea = rmserr; + + rmserr = fitDelta(2, i, DeltaDegree, c.begin()); + m_bpoly.push_back(c); + if (log_level > 3) + m_xml->XML_writeVector(logfile, indent, "bstar", + c.size(), c.begin()); + if (rmserr > eb) eb = rmserr; + + rmserr = fitDelta(3, i, DeltaDegree, c.begin()); + m_cpoly.push_back(c); + if (log_level > 3) + m_xml->XML_writeVector(logfile, indent, "cstar", + c.size(), c.begin()); + if (rmserr > ec) ec = rmserr; + + if (log_level > 3) + m_xml->XML_close(logfile, "dstar_fit"); + } + sprintf(p, + "max RMS errors in fits vs. delta*:\n" + " omega_22 = %12.6g \n" + " A* = %12.6g \n" + " B* = %12.6g \n" + " C* = %12.6g \n", e22, ea, eb, ec); + m_xml->XML_comment(logfile, p); + m_xml->XML_close(logfile, "dstar_fits"); + } + + MMCollisionInt::~MMCollisionInt() {} + + + + doublereal MMCollisionInt::fitDelta(int table, int ntstar, + int degree, doublereal* c) { + vector_fp w(8); + doublereal* begin = 0; + int ndeg=0; + switch (table) { + case 0: + begin = omega22_table + 8*ntstar; break; + case 1: + begin = astar_table + 8*(ntstar + 1); break; + case 2: + begin = bstar_table + 8*(ntstar + 1); break; + case 3: + begin = cstar_table + 8*(ntstar + 1); break; + default: + return 0.0; + } + w[0] = -1.0; + return polyfit(8, delta, begin, w.begin(), degree, ndeg, 0.0, c); + } + + doublereal MMCollisionInt::omega22(double ts, double deltastar) { + int i; + for (i = 0; i < 37; i++) if (ts < tstar22[i]) break; + int i1, i2; + i1 = i - 1; + if (i1 < 0) i1 = 0; + i2 = i1+3; + if (i2 > 36) { + i2 = 36; + i1 = i2 - 3; + } + vector_fp values(3); + for (i = i1; i < i2; i++) { + if (deltastar == 0.0) values[i-i1] = omega22_table[8*i]; + else values[i-i1] = poly5(deltastar, m_o22poly[i].begin()); + } + return quadInterp(log(ts), m_logTemp.begin() + i1, values.begin()); + } + + doublereal MMCollisionInt::astar(double ts, double deltastar) { + int i; + for (i = 0; i < 37; i++) if (ts < tstar22[i]) break; + int i1, i2; + i1 = i - 1; + if (i1 < 0) i1 = 0; + i2 = i1+3; + if (i2 > 36) { + i2 = 36; + i1 = i2 - 3; + } + vector_fp values(3); + for (i = i1; i < i2; i++) { + if (deltastar == 0.0) values[i-i1] = astar_table[8*(i + 1)]; + else values[i-i1] = poly5(deltastar, m_apoly[i].begin()); + } + return quadInterp(log(ts), m_logTemp.begin() + i1, values.begin()); + } + + + doublereal MMCollisionInt::bstar(double ts, double deltastar) { + int i; + for (i = 0; i < 37; i++) if (ts < tstar22[i]) break; + int i1, i2; + i1 = i - 1; + if (i1 < 0) i1 = 0; + i2 = i1+3; + if (i2 > 36) { + i2 = 36; + i1 = i2 - 3; + } + vector_fp values(3); + for (i = i1; i < i2; i++) { + if (deltastar == 0.0) values[i-i1] = bstar_table[8*(i + 1)]; + else values[i-i1] = poly5(deltastar, m_bpoly[i].begin()); + } + return quadInterp(log(ts), m_logTemp.begin() + i1, values.begin()); + } + + + doublereal MMCollisionInt::cstar(double ts, double deltastar) { + int i; + for (i = 0; i < 37; i++) if (ts < tstar22[i]) break; + int i1, i2; + i1 = i - 1; + if (i1 < 0) i1 = 0; + i2 = i1+3; + if (i2 > 36) { + i2 = 36; + i1 = i2 - 3; + } + vector_fp values(3); + for (i = i1; i < i2; i++) { + if (deltastar == 0.0) values[i-i1] = cstar_table[8*(i + 1)]; + else values[i-i1] = poly5(deltastar, m_cpoly[i].begin()); + } + return quadInterp(log(ts), m_logTemp.begin() + i1, + values.begin()); } + + + void MMCollisionInt::fit_omega22(int degree, + doublereal deltastar, doublereal* o22) + { + + int i, n = m_nmax - m_nmin + 1; + int ndeg=0; + string indent = " "; + vector_fp values(n); + doublereal rmserr; + vector_fp w(n); + doublereal* logT = m_logTemp.begin() + m_nmin; + for (i = 0; i < n; i++) { + if (deltastar == 0.0) values[i] = omega22_table[8*(i + m_nmin)]; + else values[i] = poly5(deltastar, m_o22poly[i+m_nmin].begin()); + } + w[0]= -1.0; + rmserr = polyfit(n, logT, values.begin(), + w.begin(), degree, ndeg, 0.0, o22); + if (rmserr > 0.01) { + cerr << "Warning: RMS error = " << rmserr << " for omega_22 fit " + << "with delta* = " << deltastar << endl; + } + } + + void MMCollisionInt::fit(ostream& logfile, int degree, + doublereal deltastar, doublereal* a, doublereal* b, doublereal* c) + { + int i, n = m_nmax - m_nmin + 1; + int ndeg=0; + char s[100]; + string indent = " "; + vector_fp values(n); + doublereal rmserr; + vector_fp w(n); + doublereal* logT = m_logTemp.begin() + m_nmin; + for (i = 0; i < n; i++) { + if (deltastar == 0.0) values[i] = astar_table[8*(i + m_nmin + 1)]; + else values[i] = poly5(deltastar, m_apoly[i+m_nmin].begin()); + } + w[0]= -1.0; + rmserr = polyfit(n, logT, values.begin(), + w.begin(), degree, ndeg, 0.0, a); + + for (i = 0; i < n; i++) { + if (deltastar == 0.0) values[i] = bstar_table[8*(i + m_nmin + 1)]; + else values[i] = poly5(deltastar, m_bpoly[i+m_nmin].begin()); + } + w[0]= -1.0; + rmserr = polyfit(n, logT, values.begin(), + w.begin(), degree, ndeg, 0.0, b); + + for (i = 0; i < n; i++) { + if (deltastar == 0.0) values[i] = cstar_table[8*(i + m_nmin + 1)]; + else values[i] = poly5(deltastar, m_cpoly[i+m_nmin].begin()); + } + w[0]= -1.0; + rmserr = polyfit(n, logT, values.begin(), + w.begin(), degree, ndeg, 0.0, c); + + if (m_loglevel > 2) { + char p[100]; + sprintf(p, " dstar=\"%12.6g\"", deltastar); + m_xml->XML_open(logfile, "tstar_fit", p); + + m_xml->XML_writeVector(logfile, indent, "astar", degree+1, a); + if (rmserr > 0.01) { + sprintf(p, "Warning: RMS error = %12.6g for A* fit", rmserr); + m_xml->XML_comment(logfile, s); + } + + m_xml->XML_writeVector(logfile, indent, "bstar", degree+1, b); + if (rmserr > 0.01) { + sprintf(p, "Warning: RMS error = %12.6g for B* fit", rmserr); + m_xml->XML_comment(logfile, s); + } + + m_xml->XML_writeVector(logfile, indent, "cstar", degree+1, c); + + if (rmserr > 0.01) { + sprintf(p, "Warning: RMS error = %12.6g for C* fit", rmserr); + m_xml->XML_comment(logfile, s); + } + m_xml->XML_close(logfile, "tstar_fit"); + } + } + +} // namespace + + + + diff --git a/Cantera/src/Makefile.in b/Cantera/src/Makefile.in new file mode 100755 index 000000000..2c20884ab --- /dev/null +++ b/Cantera/src/Makefile.in @@ -0,0 +1,134 @@ +#/bin/sh +############################################################### +# $Author$ +# $Date$ +# $Revision$ +# +# Copyright 2001 California Institute of Technology +# +############################################################### + +SUFFIXES= +SUFFIXES= .cpp .d .o + +OBJDIR = . + +CXX_FLAGS = @CXXFLAGS@ $(CXX_OPT) + +EXT = ../../ext + +#---------------------- +# kernel components +#---------------------- + +# basic components always needed +BASE = Elements.o Constituents.o stringUtils.o misc.o importCTML.o plots.o \ + xml.o Phase.o DenseMatrix.o ctml.o funcs.o ctvector.o + +# thermodynamic properties +THERMO = $(BASE) ThermoPhase.o IdealGasPhase.o ConstDensityThermo.o SpeciesThermoFactory.o ThermoFactory.o + +# homogeneous kinetics +KINETICS = GRI_30_Kinetics.o KineticsFactory.o GasKinetics.o FalloffFactory.o GasKineticsWriter.o $(THERMO) + +# heterogeneous kinetics +HETEROKIN = InterfaceKinetics.o $(THERMO) + +# support for importing from Chemkin-compatible reaction mechanisms +CK = $(KINETICS) + +# chemical equilibrium +EQUIL = ChemEquil.o sort.o $(THERMO) + +# reaction path analysis +RPATH = Group.o ReactionPath.o + +# solvers +SOLVERS = CVode.o BandMatrix.o + +# 1D flow models +FLOW1D = $(KINETICS) $(SOLVERS) + +EVERYTHING = $(KINETICS) $(HETEROKIN) $(CK) $(TRANSPORT) $(REACTOR) $(RPATH) $(SOLVERS) $(FLOW1D) + +all: @KERNEL@ lib + +base: $(BASE) + +thermo: $(THERMO) + +kinetics: $(KINETICS) $(HETEROKIN) + +ck: + cd converters; @MAKE@ + +equil: $(EQUIL) + +flow1d: $(FLOW1D) + +trprops: + cd transport; @MAKE@ + +reactor: + cd zeroD; @MAKE@ + +rpath: $(RPATH) + +solvers: $(SOLVERS) + +#tpx: +# cd $(EXT)/tpx; @MAKE@ + +flow1D: + cd oneD; @MAKE@ + + + +CXX_LIBS = @LIBS@ +CXX_INCLUDES = -I. +CANTERA_LIB = ./libcantera.a + +DEPENDS = $(EVERYTHING:.o=.d) + +%.d: + g++ -MM $*.cpp > $*.d + +.cpp.o: + @CXX@ -c $< $(CXX_FLAGS) +#$(CXX_INCLUDES) + +misc.o: misc.cpp + echo '#define CANTERA_ROOT "@prefix@/cantera"' > ctdir.h + @CXX@ -c misc.cpp $(CXX_FLAGS) + +.f.o: + @F77@ -c $< $(F77_FLAGS) + +# +# HKM note: The lib function below removes the library first. +# I was having trouble linking applications on linux +# without removing the cantera library first. +# +lib: + $(RM) $(CANTERA_LIB) + @ARCHIVE@ $(CANTERA_LIB) *.o > /dev/null + +clean: + $(RM) *.o *~ $(CANTERA_LIB) + cd zeroD; @MAKE@ clean + cd oneD; @MAKE@ clean + +depends: $(DEPENDS) + cat *.d > .depends + $(RM) $(DEPENDS) + cd oneD; @MAKE@ depends + cd zeroD; @MAKE@ depends + cd converters; @MAKE@ depends + cd transport; @MAKE@ depends + +TAGS: + etags *.h *.cpp + +ifeq ($(wildcard .depends), .depends) +include .depends +endif diff --git a/Cantera/src/MixTransport.cpp b/Cantera/src/MixTransport.cpp new file mode 100755 index 000000000..12852049e --- /dev/null +++ b/Cantera/src/MixTransport.cpp @@ -0,0 +1,445 @@ +/** + * + * @file MixTransport.cpp + * Mixture-averaged transport properties for ideal gas mixtures. + */ + +/* $Author$ + * $Revision$ + * $Date$ + */ + +// copyright 2001 California Institute of Technology + + +// turn off warnings under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "MixTransport.h" + +#include "utilities.h" +#include "TransportParams.h" + +#include + +/** + * Mole fractions below MIN_X will be set to MIN_X when computing + * transport properties. + */ +#define MIN_X 1.e-20 + + +namespace Cantera { + + //////////////////// class MixTransport methods ////////////// + + + MixTransport::MixTransport() {} + + bool MixTransport::init(TransportParams& tr) { + + // constant substance attributes + //m_phase = tr.mix; + m_thermo = tr.thermo; + m_nsp = m_thermo->nSpecies(); + m_tmin = m_thermo->minTemp(); + m_tmax = m_thermo->maxTemp(); + + // make a local copy of the molecular weights + m_mw.resize(m_nsp); + copy(m_thermo->molecularWeights().begin(), + m_thermo->molecularWeights().end(), m_mw.begin()); + + // copy polynomials and parameters into local storage + m_poly = tr.poly; + m_visccoeffs = tr.visccoeffs; + m_condcoeffs = tr.condcoeffs; + m_diffcoeffs = tr.diffcoeffs; + m_mode = tr.mode; + + m_phi.resize(m_nsp, m_nsp, 0.0); + + m_polytempvec.resize(5); + m_visc.resize(m_nsp); + m_cond.resize(m_nsp); + m_bdiff.resize(m_nsp, m_nsp); + + m_molefracs.resize(m_nsp); + m_spwork.resize(m_nsp); + + // set flags all false + m_viscmix_ok = false; + m_viscwt_ok = false; + m_spvisc_ok = false; + m_spcond_ok = false; + m_condmix_ok = false; + m_spcond_ok = false; + m_diffmix_ok = false; + m_abc_ok = false; + + return true; + } + + + /********************************************************* + * + * Public methods + * + *********************************************************/ + + + /****************** viscosity ******************************/ + + /** + * The viscosity is computed using the Wilke mixture rule. + * \f[ + * \mu = \sum_k \frac{\mu_k X_k}{\sum_j \Phi_{k,j} X_j}. + * \f] + * Here \f$ \mu_k \f$ is the viscosity of pure species \e k, + * and + * \f[ + * \Phi_{k,j} = \frac{\left[1 + * + \sqrt\left(\frac{\mu_k}{\mu_j}\sqrt{\frac{M_j}{M_k}\right)}\right]^2} + * {\sqrt{8}\sqrt{1 + M_k/M_j}} + * \f] + * @see updateViscosity_T(); + */ + doublereal MixTransport::viscosity() { + + update_T(); + update_C(); + + if (m_viscmix_ok) return m_viscmix; + + doublereal vismix = 0.0, denom; + int k, j; + + // update m_visc and m_phi if necessary + if (!m_viscwt_ok) updateViscosity_T(); + + for (k = 0; k < m_nsp; k++) { + denom = 0.0; + for (j = 0; j < m_nsp; j++) { + denom += m_phi(k,j) * m_molefracs[j]; + } + vismix += m_molefracs[k] * m_visc[k]/denom; + } + m_viscmix = vismix; + return vismix; + } + + + /******************* binary diffusion coefficients **************/ + + + void MixTransport::getBinaryDiffCoeffs(int ld, doublereal* d) { + int i,j; + + update_T(); + + // if necessary, evaluate the binary diffusion coefficents + // from the polynomial fits + if (!m_bindiff_ok) updateDiff_T(); + + doublereal rp = 1.0/pressure_ig(); + for (i = 0; i < m_nsp; i++) + for (j = 0; j < m_nsp; j++) { + d[ld*j + i] = rp * m_bdiff(i,j); + } + } + + + void MixTransport::getMobilities(doublereal* mobil) { + int k; + getMixDiffCoeffs(m_spwork.begin()); + doublereal c1 = ElectronCharge / (Boltzmann * m_temp); + for (k = 0; k < m_nsp; k++) { + mobil[k] = c1 * m_spwork[k] * m_thermo->charge(k); + } + } + + + /****************** thermal conductivity **********************/ + + /** + * The thermal conductivity is computed from the following mixture rule: + * \[ + * \lambda = 0.5 \left( \sum_k X_k \lambda_k + * + \frac{1}{\sum_k X_k/\lambda_k}\right) + * \] + */ + doublereal MixTransport::thermalConductivity() { + int k; + + update_T(); + update_C(); + + if (!m_spcond_ok) updateCond_T(); + if (!m_condmix_ok) { + doublereal sum1 = 0.0, sum2 = 0.0; + for (k = 0; k < m_nsp; k++) { + sum1 += m_molefracs[k] * m_cond[k]; + sum2 += m_molefracs[k] / m_cond[k]; + } + m_lambda = 0.5*(sum1 + 1.0/sum2); + } + return m_lambda; + } + + + /****************** thermal diffusion coefficients ************/ + + /** + * Thermal diffusion is not considered in this mixture-averaged + * model. To include thermal diffusion, use transport manager + * MultiTransport instead. This methods fills out array dt with + * zeros. + */ + void MixTransport::getThermalDiffCoeffs(doublereal* dt) { + int k; + for (k = 0; k < m_nsp; k++) { + dt[k] = 0.0; + } + } + + /** + * @param ndim The number of spatial dimensions (1, 2, or 3). + * @param grad_T The temperature gradient (ignored in this model). + * @param ldx Leading dimension of the grad_X array. + * The diffusive mass flux of species \e k is computed from + * \f[ + * \vec{j}_k = -n M_k D_k \nabla X_k. + * \f] + */ + void MixTransport::getSpeciesFluxes(int ndim, + doublereal* grad_T, int ldx, const doublereal* grad_X, + int ldf, doublereal* fluxes) { + int n, k; + + update_T(); + update_C(); + + getMixDiffCoeffs(m_spwork.begin()); + + const array_fp& mw = m_thermo->molecularWeights(); + const doublereal* y = m_thermo->massFractions(); + doublereal rhon = m_thermo->molarDensity(); + + vector_fp sum(ndim,0.0); + for (n = 0; n < ndim; n++) { + for (k = 0; k < m_nsp; k++) { + fluxes[n*ldf + k] = -rhon * mw[k] * m_spwork[k] * grad_X[n*ldx + k]; + sum[n] += fluxes[n*ldf + k]; + } + } + // add correction flux to enforce sum to zero + for (n = 0; n < ndim; n++) { + for (k = 0; k < m_nsp; k++) { + fluxes[n*ldf + k] -= y[k]*sum[n]; + } + } + } + + + void MixTransport::getMixDiffCoeffs(doublereal* d) { + + update_T(); + update_C(); + + // update the binary diffusion coefficients if necessary + if (!m_bindiff_ok) updateDiff_T(); + + int k, j; + doublereal mmw = m_thermo->meanMolecularWeight(); + doublereal sumxw = 0.0, sum2; + doublereal p = pressure_ig(); + for (k = 0; k < m_nsp; k++) sumxw += m_molefracs[k] * m_mw[k]; + for (k = 0; k < m_nsp; k++) { + sum2 = 0.0; + for (j = 0; j < m_nsp; j++) { + if (j != k) { + sum2 += m_molefracs[j] / m_bdiff(j,k); + } + } + d[k] = (sumxw - m_molefracs[k] * m_mw[k])/(p * mmw * sum2); + } + } + + + /** + * @internal This is called whenever a transport property is + * requested from ThermoSubstance if the temperature has changed + * since the last call to update_T. + */ + void MixTransport::update_T() + { + doublereal t = m_thermo->temperature(); + if (t == m_temp) return; + if (t < 0.0) { + throw CanteraError("MixTransport::update_T", + "negative temperature "+fp2str(t)); + } + m_temp = t; + m_logt = log(m_temp); + m_kbt = Boltzmann * m_temp; + m_sqrt_t = sqrt(m_temp); + m_t32 = m_temp * m_sqrt_t; + m_sqrt_kbt = sqrt(Boltzmann*m_temp); + + // compute powers of log(T) + m_polytempvec[0] = 1.0; + m_polytempvec[1] = m_logt; + m_polytempvec[2] = m_logt*m_logt; + m_polytempvec[3] = m_logt*m_logt*m_logt; + m_polytempvec[4] = m_logt*m_logt*m_logt*m_logt; + + // temperature has changed, so polynomial fits will need to be + // redone. + m_viscmix_ok = false; + m_spvisc_ok = false; + m_viscwt_ok = false; + m_spcond_ok = false; + m_diffmix_ok = false; + m_bindiff_ok = false; + m_abc_ok = false; + m_condmix_ok = false; + } + + /** + * @internal This is called the first time any transport property + * is requested from Mixture after the concentrations + * have changed. + */ + void MixTransport::update_C() + { + // signal that concentration-dependent quantities will need to + // be recomputed before use, and update the local mole + // fractions. + + m_viscmix_ok = false; + m_diffmix_ok = false; + m_condmix_ok = false; + + m_thermo->getMoleFractions(m_molefracs.begin()); + + // add an offset to avoid a pure species condition + int k; + for (k = 0; k < m_nsp; k++) { + m_molefracs[k] = fmaxx(MIN_X, m_molefracs[k]); + } + } + + + /************************************************************************* + * + * methods to update temperature-dependent properties + * + *************************************************************************/ + + /** + * Update the temperature-dependent parts of the mixture-averaged + * thermal conductivity. + */ + void MixTransport::updateCond_T() { + + int k; + if (m_mode == CK_Mode) { + for (k = 0; k < m_nsp; k++) { + m_cond[k] = exp(dot4(m_polytempvec, m_condcoeffs[k])); + } + } + else { + for (k = 0; k < m_nsp; k++) { + m_cond[k] = m_sqrt_t*dot5(m_polytempvec, m_condcoeffs[k]); + } + } + m_spcond_ok = true; + m_condmix_ok = false; + } + + + /** + * Update the binary diffusion coefficients. These are evaluated + * from the polynomial fits at unit pressure (1 Pa). + */ + void MixTransport::updateDiff_T() { + + // evaluate binary diffusion coefficients at unit pressure + int i,j; + int ic = 0; + if (m_mode == CK_Mode) { + for (i = 0; i < m_nsp; i++) { + for (j = i; j < m_nsp; j++) { + m_bdiff(i,j) = exp(dot4(m_polytempvec, m_diffcoeffs[ic])); + m_bdiff(j,i) = m_bdiff(i,j); + ic++; + } + } + } + else { + for (i = 0; i < m_nsp; i++) { + for (j = i; j < m_nsp; j++) { + m_bdiff(i,j) = m_temp * m_sqrt_t*dot5(m_polytempvec, + m_diffcoeffs[ic]); + m_bdiff(j,i) = m_bdiff(i,j); + ic++; + } + } + } + + m_bindiff_ok = true; + m_diffmix_ok = false; + } + + + /** + * Update the pure-species viscosities. + */ + void MixTransport::updateSpeciesViscosities() { + + int k; + if (m_mode == CK_Mode) { + for (k = 0; k < m_nsp; k++) { + m_visc[k] = exp(dot4(m_polytempvec, m_visccoeffs[k])); + } + } + else { + for (k = 0; k < m_nsp; k++) { + m_visc[k] = m_sqrt_t*dot5(m_polytempvec, m_visccoeffs[k]); + } + } + m_spvisc_ok = true; + } + + + /** + * Update the temperature-dependent viscosity terms. + * Updates the array of pure species viscosities, and the + * weighting functions in the viscosity mixture rule. + * The flag m_visc_ok is set to true. + */ + void MixTransport::updateViscosity_T() { + doublereal vratiokj, wratiojk, rootwjk, factor1; + + if (!m_spvisc_ok) updateSpeciesViscosities(); + + // see Eq. (9-5.15) of Reid, Prausnitz, and Poling + int j, k; + for (j = 0; j < m_nsp; j++) { + for (k = j; k < m_nsp; k++) { + vratiokj = m_visc[k]/m_visc[j]; + wratiojk = m_mw[j]/m_mw[k]; + rootwjk = sqrt(wratiojk); + factor1 = 1.0 + sqrt(vratiokj * rootwjk); + m_phi(k,j) = factor1*factor1 / + (SqrtEight * sqrt(1.0 + m_mw[k]/m_mw[j])); + m_phi(j,k) = m_phi(k,j)/(vratiokj * wratiojk); + } + } + m_viscwt_ok = true; + } + +} diff --git a/Cantera/src/MultiDomain.h b/Cantera/src/MultiDomain.h new file mode 100755 index 000000000..ec52eea39 --- /dev/null +++ b/Cantera/src/MultiDomain.h @@ -0,0 +1,155 @@ +/** + * + * @file Resid1D.h + * + * >>>>> Under construction! <<<<< + * + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2002 California Institute of Technology + * + */ + +#ifndef CT_MULTIDOM_H +#define CT_MULTIDOM_H + + +#include "stringUtils.h" +//#include "Array.h" +#include "Resid1D.h" + +namespace Cantera { + + + /** + * Residual function evaluator for a one-dimensional problem. + */ + class MultiDomain { + public: + + /** + * Constructor. + * @param nv Number of variables at each grid point. + * @param points Number of grid points. + */ + MultiDomain() : m_bw(0), m_nd(0), m_rdt(0.0), m_jac_ok(false) {} + + /// Destructor. + virtual ~MultiDomain(){} + + int nDomains() const { return m_nd; } + + Resid1D& domain(int i) const { return *m_dom[i]; } + int start(int i) const { return m_start[i]; } + int size() const { return m_size; } + int bandwidth() const { return m_bw; } + + virtual void addDomain(Resid1D* d) { + m_dom.push_back(d); + int sz = d->nPoints() + * d->nComponents(); + if (m_nd > 0) { + m_start.push_back(m_start.back() + m_states.back()); + } + else + m_start.push_back(0); + m_states.push_back(sz); + m_comp.push_back(d->nComponents()); + m_points.push_back(d->nPoints()); + int bw1, bw2 = 0; + bw1 = 2*d->nComponents() - 1; + if (m_nd > 0) { + bw2 = d->nComponents() + m_dom[m_nd-1]->nComponents() - 1; + } + if (bw1 > m_bw) m_bw = bw1; + if (bw2 > m_bw) m_bw = bw2; + m_nd = m_states.size(); + m_size = m_start.back() + m_states.back(); + } + + void evalDomain(int i, int j, doublereal* x, doublereal* r, + doublereal rdt) { + int jpt; + if (j < 0) + jpt = j; + else + jpt = (j - m_start[i])/m_comp[i]; + //cout << "calling Resid1D::eval. jpt, start = " << jpt << " " << m_start[i] << endl; + m_dom[i]->eval(jpt, x + m_start[i], r + m_start[i], rdt); + } + + + doublereal ssnorm(doublereal* x, doublereal* r) { + //cout << " calling eval to get ss norm " << endl; + eval(-1, x, r, 0.0); + doublereal ss = 0.0; + for (int i = 0; i < m_size; i++) + ss = fmax(fabs(r[i]),ss); + return ss; + } + + doublereal rdt() const { return m_rdt; } + + void initTimeInteg(doublereal dt, doublereal* x) { + doublereal rdt_old = m_rdt; + m_rdt = 1.0/dt; + if (fabs(rdt_old - m_rdt) > Tiny) { + m_jac_ok = false; + } + int i; + for (i = 0; i < m_nd; i++) + m_dom[i]->initTimeInteg(dt, x + m_start[i]); + } + + bool transient() const { return (m_rdt != 0.0);} + bool steady() const { return (m_rdt == 0.0); } + + void setSteadyMode() { + if (m_rdt > 0) + m_jac_ok = false; + m_rdt = 0.0; + } + + void eval(int j, double* x, double* r, doublereal rdt=-1.0) { + int i, jpt; + if (rdt < 0.0) rdt = m_rdt; + if (j < 0) { + for (i = 0; i < m_nd; i++) { + evalDomain(i, j, x, r, rdt); + } + } + else { + for (i = 0; i < m_nd; i++) { + if (j >= m_start[i]) { + //cout << "calling evalDomain with j = " << j << endl; + evalDomain(i, j, x, r, rdt); + jpt = j - m_start[i]; + if (jpt == 0 && i > 0) + evalDomain(i-1, j-1, x, r, rdt); + else if (jpt == m_states[i] - 1 && i < m_nd - 1) + evalDomain(i+1, j+1, x, r, rdt); + break; + } + } + } + } + + protected: + doublereal m_rdt; + bool m_jac_ok; + int m_nd, m_bw, m_size; + vector_int m_states; + vector_int m_start; + vector_int m_comp, m_points; + vector m_dom; + + private: + + }; +} + +#endif + + diff --git a/Cantera/src/NasaPoly1.h b/Cantera/src/NasaPoly1.h new file mode 100755 index 000000000..9cc9ff0e7 --- /dev/null +++ b/Cantera/src/NasaPoly1.h @@ -0,0 +1,107 @@ +/** + * @file NasaPoly1.h + */ + +/* $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_NASAPOLY1_H +#define CT_NASAPOLY1_H + +namespace Cantera { + + /** + * The NASA polynomial parameterization for one temperature range. + * This parameterization expresses the heat capacity as a + * fourth-order polynomial. Note that this is the form used in the + * 1971 NASA equilibrium program and by the Chemkin software + * package, but differs from the form used in the more recent NASA + * equilibrium program. + * + * Seven coefficients \f$(a_0,\dots,a_6)\f$ are used to represent + * \f$ c_p^0(T)\f$, \f$ h^0(T)\f$, and \f$ s^0(T) \f$ as + * polynomials in \f$ T \f$ : + * \f[ + * \frac{c_p(T)}{R} = a_0 + a_1 T + a_2 T^2 + a_3 T^3 + a_4 T^4 + * \f] + * \f[ + * \frac{h^0(T)}{RT} = a_0 + \frac{a_1}{2} T + \frac{a_2}{3} T^2 + + \frac{a_3}{4} T^3 + \frac{a_4}{5} T^4 + a_5. + * \f] + * \f[ + * \frac{s^0(T)}{R} = a_0\ln T + a_1 T + \frac{a_2}{2} T^2 + + \frac{a_3}{3} T^3 + \frac{a_4}{4} T^4 + a_6. + * \f] + * + * This class is designed specifically for use by class NasaThermo. + * @ingroup spthermo + */ + class NasaPoly1 { + + public: + + NasaPoly1() + : m_lowT(0.0), m_highT (0.0), + m_Pref(0.0), m_index (0), m_coeff(array_fp(7)) {} + + NasaPoly1(int n, doublereal tlow, doublereal thigh, doublereal pref, + const doublereal* coeffs) : + m_lowT (tlow), + m_highT (thigh), + m_Pref (pref), + m_index (n), + m_coeff (array_fp(7)) { + copy(coeffs, coeffs + 7, m_coeff.begin()); + } + + virtual ~NasaPoly1(){} + + doublereal minTemp() const { return m_lowT;} + doublereal maxTemp() const { return m_highT;} + doublereal refPressure() const { return m_Pref; } + + void updateProperties(const doublereal* tt, + doublereal* cp_R, doublereal* h_RT, doublereal* s_R) const { + + doublereal ct0 = m_coeff[2]; + doublereal ct1 = m_coeff[3]*tt[0]; + doublereal ct2 = m_coeff[4]*tt[1]; + doublereal ct3 = m_coeff[5]*tt[2]; + doublereal ct4 = m_coeff[6]*tt[3]; + + doublereal cp, h, s; + cp = ct0 + ct1 + ct2 + ct3 + ct4; + h = ct0 + 0.5*ct1 + OneThird*ct2 + 0.25*ct3 + 0.2*ct4 + + m_coeff[0]*tt[4]; + s = ct0*tt[5] + ct1 + 0.5*ct2 + OneThird*ct3 + +0.25*ct4 + m_coeff[1]; + + cp_R[m_index] = cp; + h_RT[m_index] = h; + s_R[m_index] = s; + } + + protected: + + doublereal m_lowT, m_highT, m_Pref; + int m_index; + array_fp m_coeff; + + private: + + }; + +} + +#endif + + + + + + diff --git a/Cantera/src/NasaThermo.h b/Cantera/src/NasaThermo.h new file mode 100755 index 000000000..63c4cae13 --- /dev/null +++ b/Cantera/src/NasaThermo.h @@ -0,0 +1,202 @@ +/** + * @file NasaThermo.h + */ + +/* + * $author$ + * $revision$ + * $date$ + */ + + +#ifndef CT_NASATHERMO_H +#define CT_NASATHERMO_H + +#include "SpeciesThermoMgr.h" +#include "NasaPoly1.h" +#include "speciesThermoTypes.h" +#include "polyfit.h" + +namespace Cantera { + + /** + * A species thermodynamic property manager for the NASA + * polynomial parameterization with two temperature ranges. + * + * The original NASA polynomial parameterization expressed the + * heat capacity as a fourth-order polynomial in temperature, with + * separate coefficients for each of two temperature ranges. (The + * newer NASA format adds coefficients for 1/T and 1/T^2, and + * allows multiple temperature ranges.) This class is designed for + * use with the original parameterization, which is used, for + * example, by the Chemkin software package. + * + * In many cases, the midpoint temperature is the same for many + * species. To take advantage of this, class NasaThermo groups + * species with a common midpoint temperature, so that checking + * which range the desired temperature is in need be done only + * once for each group. + * + * @note There is a special CTML element for entering the + * coefficients of this parameterization. + * @see importCTML + */ + class NasaThermo : public SpeciesThermo { + + public: + + const int ID; + + NasaThermo() : + ID(NASA), + m_tlow_max(0.0), + m_thigh_min(1.e30), + m_ngroups(0) { m_t.resize(6); } + + virtual ~NasaThermo() {} + + /** + * Install parameterization for a species. + * @param index Species index + * @param type ignored, since only NASA type is supported + * @param c coefficients. These are + * - c[0] midpoint temperature + * - c[1] - c[7] coefficients for low T range + * - c[8] - c[14] coefficients for high T range + */ + virtual void install(int index, int type, const doublereal* c, + doublereal minTemp, doublereal maxTemp, doublereal refPressure) { + + int imid = int(c[0]); // midpoint temp converted to integer + int igrp = m_index[imid]; // has this value been seen before? + if (igrp == 0) { // if not, prepare new group + vector v; + m_high.push_back(v); + m_low.push_back(v); + m_tmid.push_back(c[0]); + m_index[imid] = igrp = m_high.size(); + m_ngroups++; + } + doublereal tlow = minTemp; + doublereal tmid = c[0]; + doublereal thigh = maxTemp; + doublereal pref = refPressure; + const doublereal* clow = c + 1; + + vector_fp chigh(7); + copy(c + 8, c + 15, chigh.begin()); + + // Make cp exactly continuous at tmid by offsetting the + // high temp fit. + doublereal cplow = poly4(tmid, clow+2); + doublereal cphigh = poly4(tmid, chigh.begin()+2); + chigh[0] += (cplow - cphigh); + + m_high[igrp-1].push_back(NasaPoly1(index, tmid, thigh, + pref, chigh.begin())); + m_low[igrp-1].push_back(NasaPoly1(index, tlow, tmid, + pref, clow)); + if (tlow > m_tlow_max) m_tlow_max = tlow; + if (thigh < m_thigh_min) m_thigh_min = thigh; + m_tlow.push_back(tlow); + m_thigh.push_back(thigh); + m_p0 = pref; + m_high_map[index] = &m_high[igrp-1].back(); + m_low_map[index] = &m_low[igrp-1].back(); + } + + virtual void update_one(int k, doublereal t, doublereal* cp_R, + doublereal* h_RT, doublereal* s_R) const { + + m_t[0] = t; + m_t[1] = t*t; + m_t[2] = m_t[1]*t; + m_t[3] = m_t[2]*t; + m_t[4] = 1.0/t; + m_t[5] = log(t); + + doublereal tmid = m_low_map[k]->maxTemp(); + if (t < tmid) + m_low_map[k]->updateProperties(m_t.begin(), cp_R, h_RT, s_R); + else + m_high_map[k]->updateProperties(m_t.begin(), cp_R, h_RT, s_R); + } + + + virtual void update(doublereal t, doublereal* cp_R, + doublereal* h_RT, doublereal* s_R) const { + int i; + + m_t[0] = t; + m_t[1] = t*t; + m_t[2] = m_t[1]*t; + m_t[3] = m_t[2]*t; + m_t[4] = 1.0/t; + m_t[5] = log(t); + + vector::const_iterator _begin, _end; + for (i = 0; i != m_ngroups; i++) { + if (t > m_tmid[i]) { + _begin = m_high[i].begin(); + _end = m_high[i].end(); + } + else { + _begin = m_low[i].begin(); + _end = m_low[i].end(); + } + for (; _begin != _end; ++_begin) + _begin->updateProperties(m_t.begin(), cp_R, h_RT, s_R); + } + } + + virtual doublereal minTemp(int k=-1) const { + if (k < 0) + return m_tlow_max; + else + return m_tlow[k]; + } + + virtual doublereal maxTemp(int k=-1) const { + if (k < 0) + return m_thigh_min; + else + return m_thigh[k]; + } + + virtual doublereal refPressure() const {return m_p0;} + + protected: + + mutable map m_low_map; + mutable map m_high_map; + vector > m_high; + vector > m_low; + map m_index; + vector_fp m_tmid; + doublereal m_tlow_max; + doublereal m_thigh_min; + vector_fp m_tlow; + vector_fp m_thigh; + doublereal m_p0; + int m_ngroups; + mutable vector_fp m_t; + }; + +} + +#endif + +// $Log$ +// Revision 1.1 2003-04-14 17:57:51 dggoodwin +// Initial revision +// +// Revision 1.16 2003/01/13 10:14:32 dgg +// *** empty log message *** +// +// +// Revision 1.3 2001/12/19 03:14:27 dgg +// Added an offset to the high temperature cp constant coefficient so +// that the high and low cp fits agree precisely at Tmid. This is +// necessary to avoid spurious errors that can occur when integrators +// begin at an initial temperature precisely equal to Tmid. +// diff --git a/Cantera/src/Newton.h b/Cantera/src/Newton.h new file mode 100755 index 000000000..951980860 --- /dev/null +++ b/Cantera/src/Newton.h @@ -0,0 +1,74 @@ +/** + * + * @file Newton.h + * + * Newton solver >>> under construction! <<<< + * + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2002 California Institute of Technology + * + */ + +#ifndef CT_NEWTON_H +#define CT_NEWTON_H + +#include "Resid.h" +#include "Jac.h" + +namespace Cantera { + + class Newton { + + public: + + Newton(int nv); + virtual ~Newton(); + + doublereal norm(const doublereal* step); + void step(doublereal* x, doublereal* step, + Resid& r, Jac& jac, int loglevel, int update=1); + doublereal boundStep(const doublereal* x0, const doublereal* step0, + const Resid& r, int loglevel); + int dampStep(const doublereal* x0, const doublereal* step0, + doublereal* x1, doublereal* step1, doublereal& s1, + Resid& r, Jac& jac, int loglevel, bool writetitle); + void getErrorWeights(const doublereal* x, doublereal* ewt, Resid& r); + doublereal norm2(const doublereal* step, doublereal* ewt); + doublereal norm_infty(const doublereal* step, doublereal* ewt); + int nsolve(doublereal* x0, doublereal* x1, Resid& r, Jac& jac, + int loglevel); + int timeIntegrate(int n, doublereal dt, + doublereal* x0, doublereal* x1, + Resid& r, Jac& jac, int loglevel); + doublereal ssnorm(doublereal* x, doublereal* resid, Resid& r); + + void setOptions(int maxJacAge = 5, doublereal maxNormRatio = 0.001) { + m_maxAge = maxJacAge; + m_maxRatio = maxNormRatio; + } + void resize(int points); + + protected: + + doublereal* getWorkArray(); + void releaseWorkArray(doublereal* work); + vector m_workarrays; + vector_fp m_ewt; + int m_maxAge; + int m_maxRatio; + int m_nv, m_n; + + private: + + size_t index(int n, int j) { + return m_nv * j + n; + } + }; +} + +#endif + + diff --git a/Cantera/src/Phase.cpp b/Cantera/src/Phase.cpp new file mode 100755 index 000000000..2b4a17cf0 --- /dev/null +++ b/Cantera/src/Phase.cpp @@ -0,0 +1,237 @@ +/** + * @file Phase.cpp + */ + +// Copyright 2001 California Institute of Technology + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "ct_defs.h" +#include "Phase.h" +#include "vec_functions.h" +#include "ctexceptions.h" + +namespace Cantera { + + void Phase::saveState(vector_fp& state) const { + state.resize(nSpecies() + 2); + saveState(state.size(),state.begin()); + } + void Phase::saveState(int lenstate, doublereal* state) const { + state[0] = temperature(); + state[1] = density(); + getMassFractions(lenstate - 2, state + 2); + } + + void Phase::restoreState(vector_fp& state) { + restoreState(state.size(),state.begin()); + } + + void Phase::restoreState(int lenstate, doublereal* state) { + if (int(lenstate) >= nSpecies() + 2) { + setMassFractions_NoNorm(state + 2); + setTemperature(state[0]); + setDensity(state[1]); + } + else { + throw ArraySizeError("Phase::restoreState", + lenstate,nSpecies()+2); + } + } + + void Phase::setMoleFractionsByName(compositionMap& xMap) { + int kk = nSpecies(); + doublereal x; + vector_fp mf(kk, 0.0); + for (int k = 0; k < kk; k++) { + x = xMap[speciesName(k)]; + if (x > 0.0) mf[k] = x; + } + setMoleFractions(mf.begin()); + } + + void Phase::setMoleFractionsByName(const string& x) { + compositionMap xx; + int kk = nSpecies(); + for (int k = 0; k < kk; k++) { + xx[speciesName(k)] = -1.0; + } + parseCompString(x, xx); + setMoleFractionsByName(xx); + //int kk = nSpecies(); + //vector_fp mf(kk); + //for (int k = 0; k < kk; k++) { + // mf[k] = xx[speciesName(k)]; + //} + //setMoleFractions(mf.begin()); + } + + void Phase::setMassFractionsByName(compositionMap& yMap) { + int kk = nSpecies(); + doublereal y; + vector_fp mf(kk); + for (int k = 0; k < kk; k++) { + y = yMap[speciesName(k)]; + if (y > 0.0) mf[k] = y; + } + setMassFractions(mf.begin()); + } + + void Phase::setMassFractionsByName(const string& y) { + compositionMap yy; + int kk = nSpecies(); + for (int k = 0; k < kk; k++) { + yy[speciesName(k)] = -1.0; + } + parseCompString(y, yy); + setMassFractionsByName(yy); + } + + /** Set the temperature (K), density (kg/m^3), and mole fractions. */ + void Phase::setState_TRX(doublereal t, doublereal dens, + const doublereal* x) { + setMoleFractions(x); setTemperature(t); setDensity(dens); + } + + /** Set the temperature (K), density (kg/m^3), and mole fractions. */ + void Phase::setState_TRX(doublereal t, doublereal dens, + compositionMap& x) { + setMoleFractionsByName(x); setTemperature(t); setDensity(dens); + } + + /** Set the temperature (K), density (kg/m^3), and mass fractions. */ + void Phase::setState_TRY(doublereal t, doublereal dens, + const doublereal* y) { + setMassFractions(y); setTemperature(t); setDensity(dens); + } + + /** Set the temperature (K), density (kg/m^3), and mass fractions. */ + void Phase::setState_TRY(doublereal t, doublereal dens, + compositionMap& y) { + setMassFractionsByName(y); setTemperature(t); setDensity(dens); + } + + /** Set the temperature (K) and density (kg/m^3) */ + void Phase::setState_TR(doublereal t, doublereal rho) { + setTemperature(t); setDensity(rho); + } + + /** Set the temperature (K) and mole fractions. */ + void Phase::setState_TX(doublereal t, doublereal* x) { + setTemperature(t); setMoleFractions(x); + } + + /** Set the temperature (K) and mass fractions. */ + void Phase::setState_TY(doublereal t, doublereal* y) { + setTemperature(t); setMassFractions(y); + } + + /** Set the density (kg/m^3) and mole fractions. */ + void Phase::setState_RX(doublereal rho, doublereal* x) { + setMoleFractions(x); setDensity(rho); + } + + /** Set the density (kg/m^3) and mass fractions. */ + void Phase::setState_RY(doublereal rho, doublereal* y) { + setMassFractions(y); setDensity(rho); + } + + /** + * Copy the vector of molecular weights into vector weights. + */ + void Phase::getMolecularWeights(vector_fp& weights) { + const array_fp& mw = Constituents::molecularWeights(); + if (weights.size() < mw.size()) weights.resize(mw.size()); + copy(mw.begin(), mw.end(), weights.begin()); + } + + /** + * Copy the vector of molecular weights into array weights. + */ + void Phase::getMolecularWeights(int iwt, doublereal* weights) { + const array_fp& mw = Constituents::molecularWeights(); + copy(mw.begin(), mw.end(), weights); + } + + /** + * Return a const reference to the internal vector of + * molecular weights. + */ + const array_fp& Phase::molecularWeights() { + return Constituents::molecularWeights(); + } + + + /** + * Get the mole fractions by name. + */ + void Phase::getMoleFractionsByName(compositionMap& x) { + x.clear(); + int kk = nSpecies(); + for (int k = 0; k < kk; k++) { + x[speciesName(k)] = State::moleFraction(k); + } + } + + doublereal Phase::moleFraction(int k) const { + return State::moleFraction(k); + } + + doublereal Phase::moleFraction(string name) const { + int iloc = speciesIndex(name); + if (iloc >= 0) return State::moleFraction(iloc); + else return 0.0; + } + + doublereal Phase::massFraction(int k) const { + return State::massFraction(k); + } + + doublereal Phase::massFraction(string name) const { + int iloc = speciesIndex(name); + if (iloc >= 0) return massFractions()[iloc]; + else return 0.0; + } + + void Phase::update_T(int n) const { + m_T_updater.update(n); + } + + void Phase::update_C(int n) const { + m_C_updater.update(n); + } + + /** + * Finished adding species, prepare to use them for calculation + * of mixture properties. + */ + void Phase::freezeSpecies() { + Constituents::freezeSpecies(); + init(Constituents::molecularWeights()); + int kk = nSpecies(); + int nv = kk + 2; + m_data.resize(nv,0.0); + m_data[0] = 300.0; + m_data[1] = 0.001; + m_data[2] = 1.0; + + setState_TRY(300.0, density(), m_data.begin() + 2); + + m_kk = nSpecies(); + } + + bool Phase::ready() const { + return (m_kk > 0 && Constituents::ready() && State::ready()); + } + + int Phase::installUpdater_T(Updater* u) { + return m_T_updater.install(u); + } + + int Phase::installUpdater_C(Updater* u) { + return m_C_updater.install(u); + } +} diff --git a/Cantera/src/Phase.h b/Cantera/src/Phase.h new file mode 100755 index 000000000..85040fa65 --- /dev/null +++ b/Cantera/src/Phase.h @@ -0,0 +1,188 @@ +/** + * @file Phase.h + */ + +/* + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + +#ifndef CT_PHASE_H +#define CT_PHASE_H + +//#include "ct_defs.h" +#include "State.h" +#include "Constituents.h" +#include "vec_functions.h" +//#include "ctexceptions.h" + +#include "ctml.h" +using namespace ctml; + +namespace Cantera { + + + /** + * @defgroup phases Phases of Matter + * + * These classes are used to represent phases of matter. + */ + + /** + * Base class for phases of matter. Class Phase derives from both + * Constituents and State. In addition to the methods of those two + * classes, it implements methods that allow referencing a species + * by name. + * @ingroup phases + */ + class Phase : public Constituents, public State { + + public: + + /// Default constructor. + Phase() : m_kk(-1), m_ndim(3), m_index(-1), + m_xml(new XML_Node("phase")), m_id("") {} + + /// Destructor. + virtual ~Phase(){ delete m_xml; } + + XML_Node& xml() { return *m_xml; } + string id() { return m_id; } + void setID(string id) {m_id = id;} + int index() { return m_index; } + void setIndex(int m) { m_index = m; } + + /** + * Write to vector 'state' the current internal state. + * @param state output vector. Will be resized to nSpecies() + 2 on + * return. + */ + void saveState(vector_fp& state) const; + + /** + * Write to array 'state' the current internal state. + * @param lenstate length of the state array. Must be >= nSpecies() + 2 + */ + void saveState(int lenstate, doublereal* state) const; + + /** + * Restore a state saved on a previous call to saveState. + */ + void restoreState(vector_fp& state); + + void restoreState(int lenstate, doublereal* state); + + /** + * Set the species mole fractions by name. + * @param xMap map from species names to mole fraction values. + * Species not listed by name in \c xMap are set to zero. + */ + void setMoleFractionsByName(compositionMap& xMap); + + void setMoleFractionsByName(const string& x); + + /** + * Set the species mass fractions by name. + * @param yMap map from species names to mass fraction values. + * Species not listed by name in \c yMap are set to zero. + */ + void setMassFractionsByName(compositionMap& yMap); + + void setMassFractionsByName(const string& x); + + /** Set the temperature (K), density (kg/m^3), and mole fractions. */ + void setState_TRX(doublereal t, doublereal dens, const doublereal* x); + + /** Set the temperature (K), density (kg/m^3), and mole fractions. */ + void setState_TRX(doublereal t, doublereal dens, compositionMap& x); + + /** Set the temperature (K), density (kg/m^3), and mass fractions. */ + void setState_TRY(doublereal t, doublereal dens, const doublereal* y); + + /** Set the temperature (K), density (kg/m^3), and mass fractions. */ + void setState_TRY(doublereal t, doublereal dens, compositionMap& y); + + /** Set the temperature (K) and density (kg/m^3) */ + void setState_TR(doublereal t, doublereal rho); + + /** Set the temperature (K) and mole fractions. */ + void setState_TX(doublereal t, doublereal* x); + + /** Set the temperature (K) and mass fractions. */ + void setState_TY(doublereal t, doublereal* y); + + /** Set the density (kg/m^3) and mole fractions. */ + void setState_RX(doublereal rho, doublereal* x); + + /** Set the density (kg/m^3) and mass fractions. */ + void setState_RY(doublereal rho, doublereal* y); + + /** + * Copy the vector of molecular weights into vector weights. + */ + void getMolecularWeights(vector_fp& weights); + + /** + * Copy the vector of molecular weights into array weights. + */ + void getMolecularWeights(int iwt, doublereal* weights); + + /** + * Return a const reference to the internal vector of + * molecular weights. + */ + const array_fp& molecularWeights(); + + /** + * Get the mole fractions by name. + */ + void getMoleFractionsByName(compositionMap& x); + + doublereal moleFraction(int k) const; + + doublereal moleFraction(string name) const; + + doublereal massFraction(int k) const; + + doublereal massFraction(string name) const; + + void update_T(int n) const; + + void update_C(int n) const; + + /// Number of spatial dimensions (1, 2, or 3) + int nDim() {return m_ndim;} + void setNDim(int ndim) {m_ndim = ndim;} + + /** + * Finished adding species, prepare to use them for calculation + * of mixture properties. + */ + virtual void freezeSpecies(); + + virtual bool ready() const; + + int installUpdater_T(Updater* u); + + int installUpdater_C(Updater* u); + + protected: + + int m_kk; + int m_ndim; + int m_index; + + private: + + vector_fp m_data; + XML_Node* m_xml; + string m_id; + }; + + typedef Phase phase_t; +} + +#endif diff --git a/Cantera/src/PolyThermo.h b/Cantera/src/PolyThermo.h new file mode 100755 index 000000000..517f58037 --- /dev/null +++ b/Cantera/src/PolyThermo.h @@ -0,0 +1,99 @@ +/** + * @file PolyThermo.h + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#include "utilities.h" + +#ifndef CT_POLYTHERMO_H +#define CT_POLYTHERMO_H + +namespace Cantera { + + /** + * A polynomial parameterization for one temperature range. + * Seven coefficients \f$(a_0,\dots,a_6)\f$ are used to represent + * \f$ c_p^0(T)\f$, \f$ h^0(T)\f$, and \f$ s^0(T) \f$ as + * polynomials in \f$ T \f$ : + * \f[ + * \frac{c_p(T)}{R} = a_0 + a_1 T + a_2 T^2 + a_3 T^3 + a_4 T^4 + * \f] + * \f[ + * \frac{h^0(T)}{RT} = a_0 + \frac{a_1}{2} T + \frac{a_2}{3} T^2 + + \frac{a_3}{4} T^3 + \frac{a_4}{5} T^4 + a_5. + * \f] + * \f[ + * \frac{s^0(T)}{R} = a_0\ln T + a_1 T + \frac{a_2}{2} T^2 + + \frac{a_3}{3} T^3 + \frac{a_4}{4} T^4 + a_6. + * \f] + * + * This class is designed specifically for use by class NasaThermo. + */ + + template + class PolyThermo { + + public: + + PolyThermo() {} + + void setCoefficients(const vector_fp& coeffs) { + m_c.resize(N + 1); + m_h.resize(N + 1); + m_s.resize(N + 1); + //copy(coeffs.begin(), coeffs.begin() + N + 3, m_c.begin()); + m_c[0] = coeffs[2]; + m_h[0] = m_c[0]; + m_s[0] = coeffs[1]; + for (int i = 1; i <= N; i++) { + m_c[i] = coeffs[i+2]; + m_h[i] = m_c[i]/(i+1); + m_s[i] = m_c[i]/i; + } + m_h0 = coeffs[0]; + m_s0 = coeffs[2]; + } + + virtual ~PolyThermo(){} + + // these inline functions are defined only for readability + static doublereal tlog(const doublereal* tt) { return tt[0]; } + static doublereal trecip(const doublereal* tt) { return tt[1]; } + + doublereal h0_RT(const doublereal* tt) const { + return m_c[0] * trecip(tt) + m_c[2]; } + doublereal s0_R(const doublereal* tt) const { + return m_c[2] * tlog(tt) + m_c[1]; } + + void updateProperties(const doublereal* tt, + doublereal* cp_R, doublereal* h_RT, doublereal* s_R) const { + doublereal cpt, ht, st; + cpt = m_c[0] + dot4(tt+2,m_c.begin()+1); + ht = m_h0*tt[1] + m_h[0] + dot4(tt+2,m_h.begin()+1); + st = m_s0*tt[0] + m_s[0] + dot4(tt+2,m_s.begin()+1); //s0_R(tt); + *cp_R = cpt; + *h_RT = ht; + *s_R = st; + } + + protected: + + doublereal m_h0, m_s0; + vector_fp m_c, m_h, m_s; + }; + +} + +#endif + + + + + + diff --git a/Cantera/src/PolyThermoMgr.h b/Cantera/src/PolyThermoMgr.h new file mode 100755 index 000000000..66c96e285 --- /dev/null +++ b/Cantera/src/PolyThermoMgr.h @@ -0,0 +1,96 @@ + +#ifndef CT_POLYTHERMMGR_H +#define CT_POLYTHERMOMGR_H + +#include "PolyThermo.h" +#include "ctexceptions.h" +#include "polyfit.h" +#include "SpeciesThermo.h" + +namespace Cantera { + + /** + * A species thermodynamic property manager for polynomial + * parameterizations. + */ + template + class PolyThermoMgr : public SpeciesThermo { + + public: + + PolyThermoMgr() : + m_nsp(0), + m_minTemp(0.0), + m_maxTemp(1.e30), + m_p0(-1.0) + { m_t.resize(N + 1); } + + virtual ~PolyThermoMgr() {} + + virtual void install(int index, int type, const vector_fp& coeffs, + doublereal minTemp = 0.0, + doublereal maxTemp = 1.e30, + doublereal refPressure = OneAtm) { + m_thermo.push_back(PolyThermo()); + PolyThermo& th = m_thermo.back(); + if (coeffs.size() != N + 3) + throw CanteraError("PolyThermoMgr::install", + string("wrong number of coefficients ") + +int2str(coeffs.size())); + th.setCoefficients(coeffs); + if (m_nsp > 0 && refPressure != m_p0) { + cout << refPressure << " " << m_p0 << endl; + throw CanteraError("PolyThermoMgr::install", + "reference pressure mismatch"); + } + else if (m_nsp == 0) + m_p0 = refPressure; + + m_index.push_back(index); + m_nsp++; + + if (minTemp > m_minTemp) m_minTemp = minTemp; + if (maxTemp < m_maxTemp) m_maxTemp = maxTemp; + } + + virtual void update(doublereal t, vector_fp& cp_R, + vector_fp& h_RT, vector_fp& s_R) const { + int i; + + m_t[0] = log(t); + m_t[1] = 1.0/t; + m_t[2] = t; + // int i; + const int nmax = N + 1; + for (i = 2; i < nmax; i++) m_t[i+1] = m_t[i]*t; + + doublereal* bcp = cp_R.begin(); + doublereal* bh = h_RT.begin(); + doublereal* bs = s_R.begin(); + doublereal* tt = m_t.begin(); + size_t k; + for (k = 0; k < m_nsp; k++, bcp++, bh++, bs++) { + m_thermo[k].updateProperties(tt, bcp, bh, bs); + } + } + + virtual doublereal minTemp(int k=-1) const {return m_minTemp;} + virtual doublereal maxTemp(int k=-1) const {return m_maxTemp;} + virtual doublereal refPressure() const {return m_p0;} + + protected: + + size_t m_nsp; + vector > m_thermo; + vector m_index; + doublereal m_minTemp; + doublereal m_maxTemp; + doublereal m_p0; + mutable vector_fp m_t; + }; + +} + +#endif + + diff --git a/Cantera/src/PropertyCalculator.h b/Cantera/src/PropertyCalculator.h new file mode 100755 index 000000000..669205b28 --- /dev/null +++ b/Cantera/src/PropertyCalculator.h @@ -0,0 +1,74 @@ +/** + * @file PropertyCalculator.h + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + +#ifndef CT_PROP_CALC_H +#define CT_PROP_CALC_H + +#include "ct_defs.h" + +namespace Cantera { + + template + class PropertyCalculator { + public: + virtual doublereal value(const M& s) =0; + }; + + template + class EnthalpyCalculator : public PropertyCalculator { + public: + virtual doublereal value(const M& s) { + return s.enthalpy_mass(); + } + }; + + template + class EntropyCalculator : public PropertyCalculator { + public: + virtual doublereal value(const M& s) { + return s.entropy_mass(); + } + }; + + template + class TemperatureCalculator : public PropertyCalculator { + public: + virtual doublereal value(const M& s) { + return s.temperature(); + } + }; + + template + class PressureCalculator : public PropertyCalculator { + public: + virtual doublereal value(const M& s) { + return s.pressure(); + } + }; + + template + class DensityCalculator : public PropertyCalculator { + public: + virtual doublereal value(const M& s) { + return s.density(); + } + }; + + template + class IntEnergyCalculator : public PropertyCalculator { + public: + virtual doublereal value(const M& s) { + return s.intEnergy_mass(); + } + }; +} + +#endif + diff --git a/Cantera/src/PropertyUpdater.h b/Cantera/src/PropertyUpdater.h new file mode 100755 index 000000000..3ea359ab1 --- /dev/null +++ b/Cantera/src/PropertyUpdater.h @@ -0,0 +1,171 @@ +/** + * @file PropertyUpdater.h + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_PROPUPDATER_H +#define CT_PROPUPDATER_H + +#include "ct_defs.h" + +/* + * Reacting flow simulations require the evaluation of many quantities + * that are expensive to compute, such as reaction rates of progress, + * equilibrium constants, and multicomponent transport properties. In + * many cases, these quantities in turn require evaluating properties + * that may depend only on temperature, composition, or other + * something else. For example, reaction rate coefficients depend only + * on temperature (or may be decomposed into parts that + * do). Re-evaluating the reaction rate coefficients each time the + * rates of progress of the reactions are computed is inefficient, + * since the temperature may not have changed since the last + * call. This occurs commonly when using implicit methods that require + * evaluating a Jacobian, and the Jacobian is evaluated numerically. + * + * Cantera implements a technique to manage property updating that + * results in properties being re-evaluated only when the quantities + * they depend on have changed, and only when the properties are + * needed. + * + * The basic idea is as follows. For every property that needs + * updating, a class is derived from class Updater, and its method + * 'update()' is overloaded to update the property in question. A + * instance of container class PropertyUpdater is created to hold + * pointers to a set of updaters (instances of subclasses of + * Updater). The conditions under which the properties must be updated + * must be the same for all updaters pointed to by the PropertyUpdater + * instance. For example, one instance of PropertyUpdater might handle + * all properties that depent only on temperature, and another + * properties that depend on composition. + * + * When updaters are added to a PropertyUpdater instance, an integer + * is returned that can be used to refer to that updater. The first + * updater (number 0) is always a null updater that does nothing. + * + * PropertyUpdater acts as a 'switch'. When its method 'update(n)' is + * called, the updater pointed to by the nth pointer in its internal + * pointer array is invoked. The method 'need_update()' sets all + * pointers in this array to point to the appropriate installed + * updaters. When 'update(n)' is called, it invokes whatever updater + * is pointed to, then sets the pointer to the null + * updater. Subsequent calls to 'update(n)' will do nothing, until + * 'need_update()' is called again. Note that 'update(n)' only sets + * the nth pointer to the null updater; the rest continue to function + * until 'update' is called with their index number. 'need_update', + * however, resets all pointers to the non-null updaters. + */ + +namespace Cantera { + + /** + * Base class for updaters. This also serves as the null + * updater. Specific updaters should be derived from this + * class. Here's an example of a template for an updater that + * calls method 'recompute()' of whatever object it is + * initialized with: + * @code + * template + * class UpdateMyProperty : public Updater { + * public: + * UpdateMyProperty(S& s) : m_s(s) {} + * virtual void update() { m_s.recompute(); } + * private: + * S& m_s; + * }; + * @code + * + * @ingroup updategroup + */ + struct Updater { + Updater() : count (0) {} + virtual void update() {} + long count; + }; + + + /** + * Property updater. + * @ingroup updategroup + */ + class PropertyUpdater { + + public: + + /** + * Construct a new instance and install a null updater. + */ + PropertyUpdater() { + m_updaters.push_back( new Updater() ); + m_switch.push_back(0); + m_number = 1; + } + + + /// Destructor. Does nothing. + virtual ~PropertyUpdater() {} + + + /** + * Install an updater. + * @param u pointer to an instance of a class derived from Updater. + */ + int install(Updater* u) { + m_updaters.push_back(u); + m_switch.push_back(m_number); + m_number++; + need_update(); + return m_number - 1; + } + + + /** + * Signal that an update is needed. + */ + void need_update() { + // reset all switches to the installed updaters + for(int i=1; i < m_number; i++) m_switch[i] = i; + } + + + /** + * Invoke the updater at position n. Depending on whether + * need_update() or update(n) was called last, this will be + * either the nth installed updater, or the null updater. + */ + void update(int n) { + m_updaters[m_switch[n]]->update(); + m_switch[n] = 0; // switch to the null updater + } + + + /** + * Force an update of all properties, whether needed or not. + */ + void force_update() { + for (int n=1; nupdate(); + } + } + + private: + + vector m_updaters; + vector_int m_switch; + int m_number; + }; + +} + +#endif + + + + + + diff --git a/Cantera/src/RateCoeffMgr.h b/Cantera/src/RateCoeffMgr.h new file mode 100755 index 000000000..333de48da --- /dev/null +++ b/Cantera/src/RateCoeffMgr.h @@ -0,0 +1,159 @@ +/** + * @file RateCoeffMgr.h + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_RATECOEFF_MGR_H +#define CT_RATECOEFF_MGR_H + +#include "utilities.h" +#include "RxnRates.h" + +#ifdef HAVE_INTEL_MKL +#include "mkl_vml.h" +#endif + +#include "ct_defs.h" +#include "ctexceptions.h" + +namespace Cantera { + + // exception class + class UnknownRateCoefficient : public CanteraError { + public: + UnknownRateCoefficient() { + m_msg += "Unknown rate coefficient type."; + } + }; + + /** + * Virtual base class for rate coefficient managers. + */ +// class RateCoeffMgr { +// public: +// virtual int install( int rxnNumber, int rateType, +// const vector_fp& c )=0; +// virtual void update(doublereal T, doublereal logT, vector_fp& values)=0; +// virtual void writeUpdate(ostream& s, string name) {} +// }; + + + + /** + * This rate coefficient manager supports one parameterization of + * any type. + */ + template + class Rate1 { + + public: + + Rate1(){} + virtual ~Rate1(){} + + int install( int rxnNumber, int rateType, int m, + const doublereal* c ) { + if (rateType != R::type()) + throw UnknownRateCoefficient(); + + //int m = c.size(); + + // if any coefficient other than the first is non-zero, + // install a rate calculator and return the index of the + // calculator. + + for (int i = 1; i < m; i++) { + if (c[i] != 0.0) { + m_rxn.push_back(rxnNumber); + m_rates.push_back(R(c)); + return m_rates.size() - 1; + } + } + return -1; + } + + void update_C(const doublereal* c) { + TYPENAME_KEYWORD vector::iterator b = m_rates.begin(); + TYPENAME_KEYWORD vector::iterator e = m_rates.end(); + int i = 0; + for (; b != e; ++b, ++i) { + b->update_C(c); + } + } + + void update(doublereal T, doublereal logT, doublereal* values) { + TYPENAME_KEYWORD vector::const_iterator b = m_rates.begin(); + TYPENAME_KEYWORD vector::const_iterator e = m_rates.end(); + doublereal recipT = 1.0/T; + int i = 0; + for (; b != e; ++b, ++i) { + values[m_rxn[i]] = exp(b->update(logT, recipT)); + } + } + + void update_dT(doublereal T, doublereal logT, doublereal dT, + doublereal* values) { + TYPENAME_KEYWORD vector::const_iterator b = m_rates.begin(); + TYPENAME_KEYWORD vector::const_iterator e = m_rates.end(); + doublereal recipT = 1.0/T; + int i = 0; + for (; b != e; ++b, ++i) { + values[m_rxn[i]] *= (1.0 + dT*b->update_dT(logT, recipT)); + } + } + + virtual void writeUpdate(ostream& s, string name) { + int nrates = m_rates.size(); + for (int i = 0; i < nrates; i++) { + s << " " << name << "[" << m_rxn[i] << "] = "; + m_rates[i].writeUpdateRHS(s); + } + } + + protected: + vector m_rates; + vector m_rxn; + array_fp m_const; + }; + + + + /** + * This rate coefficient manager supports two parameterizations of + * any type. + */ +// template +// class Rate2 : public RateCoeffMgr { +// public: + +// Rate2(){} +// virtual ~Rate2(){} + +// virtual int install( int rxnNumber, int rateType, const vector_fp& c ) { +// if (rateType == R1::type()) +// return m_r1.install(rxnNumber, rateType, c); +// else if (rateType == R2::type()) +// return m_r2.install(rxnNumber, rateType, c); +// else +// throw UnknownRateCoefficient(); +// return -1; +// } + +// virtual void update(doublereal T, doublereal logT, vector_fp& values) { +// m_r1.update(T, logT, values); +// m_r2.update(T, logT, values); +// } +// protected: +// Rate1 m_r1; +// Rate1 m_r2; +// }; + +} + +#endif diff --git a/Cantera/src/ReactionData.h b/Cantera/src/ReactionData.h new file mode 100755 index 000000000..0b4bb5944 --- /dev/null +++ b/Cantera/src/ReactionData.h @@ -0,0 +1,61 @@ +/** + * @file ReactionData.h + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_REACTION_DATA_H +#define CT_REACTION_DATA_H + +#include +#include +#include +using namespace std; + +#include "reaction_defs.h" + +namespace Cantera { + + class ReactionData { + public: + ReactionData() { + reactionType = ELEMENTARY_RXN; + number = 0; + rxn_number = 0; + reversible = true; + rateCoeffType = ARRHENIUS; + falloffType = NONE; + error = 0; + equation = ""; + default_3b_eff = 1.0; + } + ~ReactionData(){} + + int reactionType; + int number, rxn_number; + vector_int reactants; + vector_int products; + vector_fp order; + vector_int rstoich; + vector_int pstoich; + vector rgroups; + vector pgroups; + map thirdBodyEfficiencies; + bool reversible; + int rateCoeffType; + vector_fp rateCoeffParameters; + vector_fp auxRateCoeffParameters; + int falloffType; + vector_fp falloffParameters; + int error; + string equation; + doublereal default_3b_eff; + }; +} + +#endif diff --git a/Cantera/src/ReactionPath.cpp b/Cantera/src/ReactionPath.cpp new file mode 100755 index 000000000..8c5aa3b53 --- /dev/null +++ b/Cantera/src/ReactionPath.cpp @@ -0,0 +1,953 @@ +/** + * @file ReactionPath.cpp + * Implementation file for classes used in reaction path analysis. + */ + +/* + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +// STL includes +#include +#include + +#include "ReactionPath.h" +#include "Kinetics.h" +#include "reaction_defs.h" +#include "Group.h" + + +namespace Cantera { + + + /** + * Construct a path connecting two species nodes. + */ + Path::Path(SpeciesNode* begin, SpeciesNode* end) + : m_a(begin), m_b(end), m_total(0.0) + { + begin->addPath(this); + end->addPath(this); + } + + + /** + * add a reaction to the path. Increment the flow from this + * reaction, the total flow, and the flow associated with this + * label. + */ + void Path::addReaction(int rxnNumber, doublereal value, + string label) { + m_rxn[rxnNumber] += value; + m_total += value; + if (label != "") m_label[label] += value; + } + + + /** + * Write the label for a path connecting two species, indicating + * the percent of the total flow due to each reaction. + */ + void Path::writeLabel(ostream& s, doublereal threshold) + { + int nn = m_label.size(); + if (nn == 0) return; + doublereal v; + map::const_iterator i = m_label.begin(); + for (; i != m_label.end(); ++i) { + v = i->second/m_total; + if (nn == 1) s << i->first << "\\l"; + else if (v > threshold) { + s << i->first; + int percent = int(100*v + 0.5); + if (percent < 100) + s << " (" << percent << "%)\\l"; + else + s << "\\l"; + } + } + } + + + /** + * Default constructor. + */ + ReactionPathDiagram::ReactionPathDiagram() { + name = "reaction_paths"; + m_flxmax = 0.0; + bold_color = "blue"; + normal_color = "steelblue"; + dashed_color = "gray"; + dot_options = "center=1;"; + m_font = "Helvetica"; + bold_min = 0.2; + dashed_max = 0.0; + label_min = 0.0; + threshold = 0.005; + flow_type = NetFlow; + scale = -1; + x_size = -1.0; + y_size = -1.0; + arrow_width = -5.0; + show_details = false; + arrow_hue = 0.6666; + title = ""; + m_local = -1; + } + + + /** + * Destructor. Deletes all nodes and paths in the diagram. + */ + ReactionPathDiagram::~ReactionPathDiagram() + { + // delete the nodes + map::const_iterator i = m_nodes.begin(); + for (; i != m_nodes.end(); ++i) delete i->second; + + // delete the paths + int nn = nPaths(); + int n; + for (n = 0; n < nn; n++) delete m_pathlist[n]; + } + + + vector_int ReactionPathDiagram::reactions() { + int i, npaths = nPaths(); + double flmax = 0.0, flxratio; + Path* p; + for (i = 0; i < npaths; i++) + { + p = path(i); + if (p->flow() > flmax) flmax = p->flow(); + } + m_rxns.clear(); + for (i = 0; i < npaths; i++) + { + p = path(i); + const Path::rxn_path_map& rxns = p->reactionMap(); + Path::rxn_path_map::const_iterator m = rxns.begin(); + for (; m != rxns.end(); ++m) { + flxratio = m->second/flmax; + if (flxratio > threshold) { + m_rxns[m->first] = 1; + } + } + } + vector_int r; + map::const_iterator begin = m_rxns.begin(); + for (; begin != m_rxns.end(); ++begin) r.push_back(abs(begin->first)); + return r; + } + + void ReactionPathDiagram::add(ReactionPathDiagram& d) { +// double f1, f2; +// int nnodes = nNodes(); +// if (nnodes != d.nNodes()) { +// throw CanteraError("ReactionPathDiagram::add", +// "number of nodes must be the same"); +// } + int np = nPaths(); + int n, k1, k2; + Path* p = 0; + for (n = 0; n < np; n++) { + p = path(n); + k1 = p->begin()->number; + k2 = p->end()->number; + p->setFlow(p->flow() + d.flow(k1,k2)); + } + } + + void ReactionPathDiagram::findMajorPaths(doublereal threshold, int lda, + doublereal* a) { + int nn = nNodes(); + int n, m, k1, k2; + doublereal fl, netmax = 0.0; + for (n = 0; n < nn; n++) { + for (m = n+1; m < nn; m++) { + k1 = m_speciesNumber[n]; + k2 = m_speciesNumber[m]; + fl = fabs(netFlow(k1,k2)); + if (fl > netmax) netmax = fl; + } + } + for (n = 0; n < nn; n++) { + for (m = n+1; m < nn; m++) { + k1 = m_speciesNumber[n]; + k2 = m_speciesNumber[m]; + fl = fabs(netFlow(k1,k2)); + if (fl > threshold*netmax) + a[lda*k1 + k2] = 1; + } + } + } + + void ReactionPathDiagram::writeData(ostream& s) { + double f1, f2; + int nnodes = nNodes(); + int i1, i2, k1, k2; + s << title << endl; + for (i1 = 0; i1 < nnodes; i1++) + { + k1 = m_speciesNumber[i1]; + s << m_nodes[k1]->name << " "; + } + s << endl; + for (i1 = 0; i1 < nnodes; i1++) + { + k1 = m_speciesNumber[i1]; + for (i2 = i1+1; i2 < nnodes; i2++) + { + k2 = m_speciesNumber[i2]; + f1 = flow(k1, k2); + f2 = flow(k2, k1); + //if (f1 > 0.001 || f2 > 0.001) { + s << m_nodes[k1]->name << " " << m_nodes[k2]->name + << " " << f1 << " " << -f2 << endl; + //} + } + } + } + + + /** + * Export the reaction path diagram. This method writes to stream + * \c s the commands for the 'dot' program in the \c GraphViz + * package from AT&T. (GraphViz may be downloaded from + * www.graphviz.org.) + * + * To generate a postscript reaction path diagram from the + * output of this method saved in file paths.dot, for example, give + * the command: + * \code + * dot -Tps paths.dot > paths.ps + * \endcode + * To generate a GIF image, replace -Tps with -Tgif + */ + void ReactionPathDiagram::exportToDot(ostream& s) + { + int i; + doublereal flxratio, flmax = 0.0, lwidth; + //s.flags(std::ios_base::showpoint+std::ios_base::fixed); + s.precision(3); + + // a directed graph + s << "digraph " << name << " {" << endl; + + // the graph will be no larger than x_size, y_size + if (x_size > 0.0) + { + if (y_size < 0.0) y_size = x_size; + s << "size = \"" + << x_size << "," + << y_size << "\";" + << endl; + } + + //s << "color = white;" << endl; + if (dot_options != "") + s << dot_options << endl; + + int npaths = nPaths(); + Path* p; + + int nnodes = nNodes(); + int kbegin, kend, i1, i2, k1, k2; + double flx; + + // draw paths representing net flows + if (flow_type == NetFlow) + { + + // if no scale was specified, normalize + // net flows by the maximum net flow + if (scale <= 0.0) + { + for (i1 = 0; i1 < nnodes; i1++) + { + k1 = m_speciesNumber[i1]; + node(k1)->visible = false; + for (i2 = i1+1; i2 < nnodes; i2++) + { + k2 = m_speciesNumber[i2]; + flx = netFlow(k1, k2); + if (flx < 0.0) flx = -flx; + if (flx > flmax) flmax = flx; + } + } + } + else + flmax = scale; + + if (flmax < 1.e-10) flmax = 1.e-10; + + // loop over all unique pairs of nodes + + for (i1 = 0; i1 < nnodes; i1++) + { + k1 = m_speciesNumber[i1]; + for (i2 = i1+1; i2 < nnodes; i2++) + { + k2 = m_speciesNumber[i2]; + flx = netFlow(k1, k2); + if (m_local >= 0) { + if (k1 != m_local && k2 != m_local) flx = 0.0; + } + if (flx != 0.0) + { + // set beginning and end of the path based on the + // sign of the net flow + + if (flx > 0.0) + { + kbegin = k1; + kend = k2; + flxratio = flx/flmax; + } + else + { + kbegin = k2; + kend = k1; + flxratio = -flx/flmax; + } + + // write out path specification if the net flow + // is greater than the threshold + + if (flxratio >= threshold) + { + // make nodes visible + node(kbegin)->visible = true; + node(kend)->visible = true; + + s << "s" << kbegin << " -> s" << kend; + + if (arrow_width < 0) { + lwidth = 1.0 - 4.0 + * log10(flxratio/threshold)/log10(threshold) + 1.0; + s << "[fontname=\""+m_font+"\", style=\"setlinewidth(" + << lwidth << ")\""; + s << ", arrowsize=" + << min(6.0, 0.5*lwidth); + } + else + { + s << ", style=\"setlinewidth(" + << arrow_width << ")\""; + s << ", arrowsize=" << flxratio + 1; + } + + doublereal hue = 0.7; + doublereal bright = 0.9; + s << ", color=" << "\"" << hue << ", " + << flxratio + 0.5 + << ", " << bright << "\"" << endl; + + if (flxratio > label_min) + { + s << ", label=\" " << flxratio; + if (show_details) { + if (flow(kbegin, kend) > 0.0) { + s << "\\l fwd: " + << flow(kbegin, kend)/flmax << "\\l"; + path(kbegin, kend)->writeLabel(s); + } + if (flow(kend, kbegin) > 0.0) { + s << " \\l rev: " + << flow(kend,kbegin)/flmax << "\\l"; + path(kend, kbegin)->writeLabel(s); + } + } + s << "\""; + } + s << "];" << endl; + } + } + } + } + } + + else { + for (i = 0; i < npaths; i++) + { + p = path(i); + if (p->flow() > flmax) flmax = p->flow(); + } + + for (i = 0; i < npaths; i++) { + p = path(i); + flxratio = p->flow()/flmax; + if (m_local >= 0) { + if (p->begin()->number != m_local + && p->end()->number != m_local) flxratio = 0.0; + } + if (flxratio > threshold) { + p->begin()->visible = true; + p->end()->visible = true; + s << "s" << p->begin()->number + << " -> s" << p->end()->number; + + if (arrow_width < 0) { + lwidth = 1.0 - 4.0 * log10(flxratio/threshold)/log10(threshold) + + 1.0; + s << "[fontname=\""+m_font+"\", style=\"setlinewidth(" + //<< 1.0 - arrow_width*flxratio + << lwidth + << ")\""; + s << ", arrowsize=" + << min(6.0, 0.5*lwidth); // 1 - arrow_width*flxratio; + } + else + { + s << ", style=\"setlinewidth(" + << arrow_width << ")\""; + s << ", arrowsize=" << flxratio + 1; + } + doublereal hue = 0.7; //2.0/(1.0 + pow(log10(flxratio),2)) ; + doublereal bright = 0.9; + s << ", color=" << "\"" << hue << ", " << flxratio + 0.5 + << ", " << bright << "\"" << endl; + + if (flxratio > label_min) { + s << ", label = \" " << flxratio; + if (show_details) { + s << "\\l"; p->writeLabel(s); + } + s << "\""; + } + s << "];" << endl; + } + } + } + s.precision(2); + map::const_iterator b = m_nodes.begin(); + for (; b != m_nodes.end(); ++b) { + if (b->second->visible) { + s << "s" << b->first << " [ fontname=\""+m_font+"\", label=\"" << b->second->name + //<< " \\n " << b->second->value + << "\"];" << endl; + } + } + s << " label = " << "\"" << "Scale = " + << flmax << "\";" << endl; //\\l\\l created with Cantera (www.cantera.org)\\l\";" + s << " fontname = \""+m_font+"\";" << endl << "}" << endl; + } + + + void ReactionPathDiagram::addNode(int k, string nm, doublereal x) { + if (!m_nodes[k]) { + m_nodes[k] = new SpeciesNode; + m_nodes[k]->number = k; + m_nodes[k]->name = nm; + m_nodes[k]->value = x; + m_speciesNumber.push_back(k); + } + } + + void ReactionPathDiagram::linkNodes(int k1, int k2, int rxn, + doublereal value, string legend) { + SpeciesNode* begin = m_nodes[k1]; + SpeciesNode* end = m_nodes[k2]; + Path* ff = m_paths[k1][k2]; + if (!ff) { + ff= new Path(begin, end); + m_paths[k1][k2] = ff; + m_pathlist.push_back(ff); + } + ff->addReaction(rxn, value, legend); + m_rxns[rxn] = 1; + if (ff->flow() > m_flxmax) m_flxmax = ff->flow(); + } + + vector_int ReactionPathDiagram::species(){ + return m_speciesNumber; + } + + + /** + * analyze a reaction to determine which reactants lead to which products. + */ + int ReactionPathBuilder::findGroups(ostream& logfile, Kinetics& s) + { + m_groups.resize(m_nr); + map net; + + for (int i = 0; i < m_nr; i++) // loop over reactions + { + logfile << endl << "Reaction " << i+1 << ": " + << s.reactionString(i); + + int nrnet = m_reac[i].size(); + int npnet = m_prod[i].size(); + const vector_int& r = s.reactants(i); + const vector_int& p = s.products(i); + + int nr = s.reactants(i).size(); + int np = s.products(i).size(); + + Group b0, b1, bb; + + vector& e = m_elementSymbols; + + const vector& rgroups = s.reactantGroups(i); + const vector& pgroups = s.productGroups(i); + + + if (m_determinate[i]) { + logfile << " ... OK." << endl; + } + + else if (rgroups.size() > 0) { + logfile << " ... specified groups." << endl; + int nrg = rgroups.size(); + int npg = pgroups.size(); + int kr, kp, ngrpr, ngrpp; + Group gr, gp; + + if (nrg != nr || npg != np) return -1; + + // loop over reactants + for (int igr = 0; igr < nrg; igr++) { + kr = r[igr]; + ngrpr = rgroups[igr].size(); + + // loop over products + for (int igp = 0; igp < npg; igp++) { + kp = p[igp]; + ngrpp = pgroups[igp].size(); + + // loop over pairs of reactant and product groups + for (int kgr = 0; kgr < ngrpr; kgr++) { + gr = Group(rgroups[igr][kgr]); + for (int kgp = 0; kgp < ngrpp; kgp++) { + gp = Group(pgroups[igp][kgp]); + if (gr == gp) { + m_transfer[i][kr][kp] = gr; + } + } + } + } + } + } + + else if (nrnet == 2 && npnet == 2) + { + // indices for the two reactants + int kr0 = m_reac[i][0]; + int kr1 = m_reac[i][1]; + + // indices for the two products + int kp0 = m_prod[i][0]; + int kp1 = m_prod[i][1]; + + // references to the Group objects representing the + // reactants + const Group& r0 = m_sgroup[kr0]; + const Group& r1 = m_sgroup[kr1]; + const Group& p0 = m_sgroup[kp0]; + const Group& p1 = m_sgroup[kp1]; + + const Group *group_a0=0, *group_b0=0, *group_c0=0, + *group_a1=0, *group_b1=0, *group_c1=0; + b0 = p0 - r0; + b1 = p1 - r0; + if (b0.valid() && b1.valid()) { + logfile << " ... ambiguous." << endl; + } + else if (!b0.valid() && !b1.valid()) { + logfile << " ... cannot express as A + BC = AB + C" << endl; + } + else logfile << endl; + + if (b0.valid()) { + if (b0.sign() > 0) { + group_a0 = &r0; + group_b0 = &b0; + group_c0 = &p1; + m_transfer[i][kr0][kp0] = r0; + m_transfer[i][kr1][kp0] = b0; + m_transfer[i][kr1][kp1] = p1; + } + else { + group_a0 = &r1; + group_c0 = &p0; + b0 *= -1; + group_b0 = &b0; + m_transfer[i][kr1][kp1] = r1; + m_transfer[i][kr0][kp1] = b0; + m_transfer[i][kr0][kp0] = p0; + } + logfile << " "; + group_a0->fmt(logfile,e); + logfile << " + "; + group_b0->fmt(logfile,e); + group_c0->fmt(logfile,e); + logfile << " = "; + group_a0->fmt(logfile,e); + group_b0->fmt(logfile,e); + logfile << " + "; + group_c0->fmt(logfile,e); + if (b1.valid()) + logfile << " [<= default] " << endl; + else + logfile << endl; + } + + + if (b1.valid()) { + if (b1.sign() > 0) { + group_a1 = &r0; + group_b1 = &b1; + group_c1 = &p0; + if (!b0.valid()) { + m_transfer[i][kr0][kp1] = r0; + m_transfer[i][kr1][kp1] = b0; + m_transfer[i][kr1][kp0] = p0; + } + } + else { + group_a1 = &r1; + group_c1 = &p1; + b1 *= -1; + group_b1 = &b1; + if (!b0.valid()) { + m_transfer[i][kr1][kp0] = r1; + m_transfer[i][kr0][kp0] = b0; + m_transfer[i][kr0][kp1] = p1; + } + } + logfile << " "; + group_a1->fmt(logfile,e); logfile << " + "; + group_b1->fmt(logfile,e); + group_c1->fmt(logfile,e); logfile << " = "; + group_a1->fmt(logfile,e); group_b1->fmt(logfile,e); + logfile << " + "; group_c1->fmt(logfile,e); + logfile << endl; + } + } + else { + logfile << "... cannot parse. [ignored]" << endl; + } + } + return 1; + } + + void ReactionPathBuilder::writeGroup(ostream& out, const Group& g) + { + g.fmt(out, m_elementSymbols); + } + + int ReactionPathBuilder::init(ostream& logfile, Kinetics& kin) { + //m_warn.clear(); + m_transfer.clear(); + + const Kinetics::thermo_t& ph = kin.thermo(); + + m_nel = ph.nElements(); + m_ns = ph.nSpecies(); + m_nr = kin.nReactions(); + + m_elementSymbols.clear(); + int m, i; + for (m = 0; m < m_nel; m++) { + m_elementSymbols.push_back(ph.elementName(m)); + } + + // all reactants / products, even ones appearing on both sides + // of the reaction + // mod 8/18/01 dgg + vector allProducts; + vector allReactants; + for (i = 0; i < m_nr; i++) { + allReactants.push_back(kin.reactants(i)); + allProducts.push_back(kin.products(i)); + } + + // m_reac and m_prod exclude indices for species that appear on + // both sides of the reaction, so that the diagram contains no loops. + + m_reac.resize(m_nr); + m_prod.resize(m_nr); + + m_ropf.resize(m_nr); + m_ropr.resize(m_nr); + m_determinate.resize(m_nr); + + m_x.resize(m_ns); // not currently used ? + m_elatoms.resize(m_nel, m_nr); + + int nr, np, n, k; + int nmol; + map net; + + for (i = 0; i < m_nr; i++) { + + // construct the lists of reactant and product indices, not + // including molecules that appear on both sides. + + m_reac[i].clear(); + m_prod[i].clear(); + net.clear(); + nr = allReactants[i].size(); + np = allProducts[i].size(); + for (int ir = 0; ir < nr; ir++) net[allReactants[i][ir]]--; + for (int ip = 0; ip < np; ip++) net[allProducts[i][ip]]++; + + for (k = 0; k < m_ns; k++) { + if (net[k] < 0) { + nmol = -net[k]; + for (int jr = 0; jr < nmol; jr++) m_reac[i].push_back(k); + } + else if (net[k] > 0) { + nmol = net[k]; + for (int jp = 0; jp < nmol; jp++) m_prod[i].push_back(k); + } + } + + int nrnet = m_reac[i].size(); + // int npnet = m_prod[i].size(); + + // compute number of atoms of each element in each reaction, + // excluding molecules that appear on both sides of the + // reaction. We only need to compute this for the reactants, + // since the elements are conserved. + + for (n = 0; n < nrnet; n++) { + k = m_reac[i][n]; + for (int m = 0; m < m_nel; m++) { + m_elatoms(m,i) += ph.nAtoms(k,m); + } + } + } + + // build species groups + vector_int comp(m_nel); + m_sgroup.resize(m_ns); + int j; + for (j = 0; j < m_ns; j++) { + for (int m = 0; m < m_nel; m++) comp[m] = int(ph.nAtoms(j,m)); + m_sgroup[j] = Group(comp); + } + + + // determine whether or not the reaction is "determinate", meaning + // that there is no ambiguity about which reactant is the source for + // any element in any product. This is false if more than one + // reactant contains a given element, *and* more than one product + // contains the element. In this case, additional information is + // needed to determine the partitioning of the reactant atoms of + // that element among the products. + + int nar, nap; + for (i = 0; i < m_nr; i++) { + nr = m_reac[i].size(); + np = m_prod[i].size(); + m_determinate[i] = true; + for (m = 0; m < m_nel; m++) { + nar = 0; + nap = 0; + for (j = 0; j < nr; j++) { + if (ph.nAtoms(m_reac[i][j],m) > 0) nar++; + } + for (j = 0; j < np; j++) { + if (ph.nAtoms(m_prod[i][j],m) > 0) nap++; + } + if (nar > 1 && nap > 1) { + m_determinate[i] = false; break; + } + } + } + + findGroups(logfile, kin); + return 1; + } + + string reactionLabel(int i, int kr, int nr, const vector_int& slist, + const Kinetics& s) { + + const Kinetics::thermo_t& ph = s.thermo(); + + string label = ""; + int l; + for (l = 0; l < nr; l++) { + if (l != kr) + label += " + "+ ph.speciesName(slist[l]); + } + if (s.reactionType(i) == THREE_BODY_RXN) + label += " + M "; + else if (s.reactionType(i) == FALLOFF_RXN) + label += " (+ M)"; + return label; + } + + + int ReactionPathBuilder::build(Kinetics& s, + string element, ostream& output, ReactionPathDiagram& r, bool quiet) + { + int i, nr, np, kr, kp, kkr, kkp; + doublereal f, ropf, ropr, fwd, rev; + string fwdlabel, revlabel; + map warn; + + doublereal threshold = 0.0; + bool fwd_incl, rev_incl, force_incl; + + const Kinetics::thermo_t& ph = s.thermo(); + int m = ph.elementIndex(element); + + r.element = element; + if (m < 0) return -1; + + int k; + int kk = ph.nSpecies(); + + s.getFwdRatesOfProgress(m_ropf.begin()); + s.getRevRatesOfProgress(m_ropr.begin()); + + ph.getMoleFractions(m_x.begin()); + + doublereal sum = 0.0; + for (k = 0; k < kk; k++) { + sum += m_x[k] * ph.nAtoms(k,m); + } + sum *= ph.molarDensity(); + + // species explicitly included or excluded + vector& in_nodes = r.included(); + vector& out_nodes = r.excluded(); + int nin = in_nodes.size(); + int nout = out_nodes.size(); + + vector_int status; + status.resize(kk,0); + for (int ni = 0; ni < nin; ni++) + status[ph.speciesIndex(in_nodes[ni])] = 1; + for (int ne = 0; ne < nout; ne++) + status[ph.speciesIndex(out_nodes[ne])] = -1; + + for (i = 0; i < m_nr; i++) + { + ropf = m_ropf[i]; + ropr = m_ropr[i]; + + // loop over reactions involving element m + if (m_elatoms(m, i) > 0) + { + nr = m_reac[i].size(); + np = m_prod[i].size(); + + for (kr = 0; kr < nr; kr++) + { + kkr = m_reac[i][kr]; + int l; + + fwdlabel = reactionLabel(i, kr, nr, m_reac[i], s); + + for (kp = 0; kp < np; kp++) + { + kkp = m_prod[i][kp]; + revlabel = ""; + for (l = 0; l < np; l++) { + if (l != kp) + revlabel += " + "+ ph.speciesName(m_prod[i][l]); + } + if (s.reactionType(i) == THREE_BODY_RXN) + revlabel += " + M "; + else if (s.reactionType(i) == FALLOFF_RXN) + revlabel += " (+ M)"; + + + // calculate the flow only for pairs that are + // not the same species, both contain atoms of + // element m, and both are allowed to appear in + // the diagram + + if ((kkr != kkp) && (ph.nAtoms(kkr,m) > 0 + && ph.nAtoms(kkp,m) > 0) + && status[kkr] >= 0 && status[kkp] >= 0) + { + + // if neither species contains the full + // number of atoms of element m in the + // reaction, then we must consider the + // type of reaction to determine which + // reactant species was the source of a + // given m-atom in the product + + if ( (ph.nAtoms(kkp,m) < m_elatoms(m, i)) && + (ph.nAtoms(kkr,m) < m_elatoms(m, i)) ) + { + map >& g = m_transfer[i]; + if (g.empty()) { + if (!warn[i]) { + if (!quiet) { + output << endl; + output << "*************** REACTION IGNORED ***************" << endl; + output << "Warning: no rule to determine partitioning of " << element + << endl << " in reaction " << s.reactionString(i) << "." << endl + << "*************** REACTION IGNORED **************" << endl; + output << endl; + warn[i] = 1; + } + } + f = 0.0; + } + else { + if (!g[kkr][kkp]) f = 0.0; + else f = g[kkr][kkp].nAtoms(m); + } + } + + // no ambiguity about where the m-atoms come + // from or go to. Either all reactant m atoms + // end up in one product, or only one reactant + // contains all the m-atoms. In either case, + // the number of atoms transferred is given by + // the same expression. + + else { + f = ph.nAtoms(kkp,m) * ph.nAtoms(kkr,m) / m_elatoms(m, i); + } + + fwd = ropf*f; + rev = ropr*f; + force_incl = ((status[kkr] == 1) || (status[kkp] == 1)); + + fwd_incl = ((fwd > threshold) || + (fwd > 0.0 && force_incl)); + rev_incl = ((rev > threshold) || + (rev > 0.0 && force_incl)); + if (fwd_incl || rev_incl) + { + if (!r.hasNode(kkr)) { + r.addNode(kkr, ph.speciesName(kkr), m_x[kkr]); + } + if (!r.hasNode(kkp)) { + r.addNode(kkp, ph.speciesName(kkp), m_x[kkp]); + } + } + if (fwd_incl) { + r.linkNodes(kkr, kkp, i, fwd, fwdlabel); + } + if (rev_incl) { + r.linkNodes(kkp, kkr, -i, rev, revlabel); + } + } + } + } + } + } + return 1; + } + + +} diff --git a/Cantera/src/ReactionPath.h b/Cantera/src/ReactionPath.h new file mode 100755 index 000000000..2602144e3 --- /dev/null +++ b/Cantera/src/ReactionPath.h @@ -0,0 +1,273 @@ +/** + * @file ReactionPath.h + * + * Classes for reaction path analysis. + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_RXNPATH_H +#define CT_RXNPATH_H + +// STL includes +#include +#include +#include +#include +using namespace std; + +// Cantera includes +#include "ct_defs.h" +#include "DenseMatrix.h" +#include "Group.h" +#include "Kinetics.h" + +namespace Cantera { + + enum flow_t { NetFlow, OneWayFlow }; + + Group parseGroupString(string str, vector& esyms); + + // forward references + class Path; + + /** + * Nodes in reaction path graphs. + */ + class SpeciesNode { + public: + + typedef vector path_list; + + /// Default constructor + SpeciesNode() : number(-1), name(""), value(0.0), + visible(false) {} + + /// Destructor + virtual ~SpeciesNode() {} + + // public attributes + int number; ///< Species number + string name; ///< Label on graph + doublereal value; ///< May be used to set node appearance + bool visible; ///< Visible on graph; + + + // public methods + + /** + * @name References. + * Return a reference to a path object connecting this node + * to another node. + */ + //@{ + Path* path(int n) { return m_paths[n]; } + const Path* path(int n) const { return m_paths[n]; } + //@} + + + /// Total number of paths to or from this node + int nPaths() const { return m_paths.size(); } + + /// add a path to or from this node + void addPath(Path* path) { m_paths.push_back(path); } + + protected: + + path_list m_paths; + }; + + + + class Path { + + public: + + typedef map rxn_path_map; + + /** + * Constructor. Construct a one-way path from + * \c begin to \c end. + */ + Path(SpeciesNode* begin, SpeciesNode* end); + + /// Destructor + virtual ~Path() {} + + void addReaction(int rxnNumber, doublereal value, string label = ""); + + /// Upstream node. + const SpeciesNode* begin() const { return m_a; } + SpeciesNode* begin() { return m_a; } + + /// Downstream node. + const SpeciesNode* end() const { return m_b; } + SpeciesNode* end() { return m_b; } + + /** + * If \c n is one of the nodes this path connects, then + * the other node is returned. Otherwise zero is returned. + */ + SpeciesNode* otherNode(SpeciesNode* n) { + return (n == m_a ? m_b : (n == m_b ? m_a : 0)); + } + + /// The total flow in this path + doublereal flow() { return m_total; } + void setFlow(doublereal v) { m_total = v; } + + /// Number of reactions contributing to this path + int nReactions() { return m_rxn.size(); } + + /// Map from reaction number to flow from that reaction in this path. + const rxn_path_map& reactionMap() { return m_rxn; } + + void writeLabel(ostream& s, doublereal threshold = 0.005); + + protected: + + map m_label; + SpeciesNode *m_a, *m_b; + rxn_path_map m_rxn; + doublereal m_total; + }; + + + /** + * Reaction path diagrams (graphs). + */ + class ReactionPathDiagram { + + public: + + ReactionPathDiagram(); + + virtual ~ReactionPathDiagram(); + + /// The largest one-way flow value in any path + doublereal maxFlow() { return m_flxmax; } + + /// The net flow from node \c k1 to node \c k2 + doublereal netFlow(int k1, int k2) { + return flow(k1, k2) - flow(k2, k1); + } + + /// The one-way flow from node \c k1 to node \c k2 + doublereal flow(int k1, int k2) { + return (m_paths[k1][k2] ? m_paths[k1][k2]->flow() : 0.0); + } + + /// True if a node for species k exists + bool hasNode(int k) { + return (m_nodes[k] != 0); + } + + void writeData(ostream& s); + void exportToDot(ostream& s); + void add(ReactionPathDiagram& d); + SpeciesNode* node(int k) { return m_nodes[k]; } + Path* path(int k1, int k2) { return m_paths[k1][k2]; } + Path* path(int n) { return m_pathlist[n]; } + int nPaths() { return m_pathlist.size(); } + int nNodes() { return m_nodes.size(); } + + void addNode(int k, string nm, doublereal x = 0.0); + + void displayOnly(int k=-1) { m_local = k; } + + void linkNodes(int k1, int k2, int rxn, doublereal value, + string legend = ""); + + void include(string name) { m_include.push_back(name); } + void exclude(string name) { m_exclude.push_back(name); } + void include(vector& names) { + int n = names.size(); + for (int i = 0; i < n; i++) m_include.push_back(names[i]); + } + void exclude(vector& names) { + int n = names.size(); + for (int i = 0; i < n; i++) m_exclude.push_back(names[i]); + } + vector& included() { return m_include; } + vector& excluded() { return m_exclude; } + vector_int species(); + vector_int reactions(); + void findMajorPaths(doublereal threshold, int lda, doublereal* a); + void setFont(string font) { + m_font = font; + } + // public attributes + + string title; + string bold_color; + string normal_color; + string dashed_color; + string element; + string m_font; + doublereal threshold, + bold_min, dashed_max, label_min; + doublereal x_size, y_size; + string name, dot_options; + flow_t flow_type; + double scale; + double arrow_width; + bool show_details; + double arrow_hue; + + protected: + + doublereal m_flxmax; + map > m_paths; + map m_nodes; + vector m_pathlist; + vector m_include; + vector m_exclude; + vector_int m_speciesNumber; + map m_rxns; + int m_local; + }; + + + + class ReactionPathBuilder { + + public: + ReactionPathBuilder() {} + virtual ~ReactionPathBuilder() {} + + int init(ostream& logfile, Kinetics& s); + + int build(Kinetics& s, string element, ostream& output, + ReactionPathDiagram& r, bool quiet=false); + + int findGroups(ostream& logfile, Kinetics& s); + + void writeGroup(ostream& out, const Group& g); + + protected: + + int m_nr; + int m_ns; + int m_nel; + vector_fp m_ropf; + vector_fp m_ropr; + array_fp m_x; + vector m_reac; + vector m_prod; + DenseMatrix m_elatoms; + vector > m_groups; + vector m_sgroup; + vector m_elementSymbols; + // map m_warn; + map > > m_transfer; + vector m_determinate; + }; + +} + +#endif diff --git a/Cantera/src/Resid.h b/Cantera/src/Resid.h new file mode 100755 index 000000000..ff8492ed9 --- /dev/null +++ b/Cantera/src/Resid.h @@ -0,0 +1,141 @@ +/** + * + * @file Resid.h + * + * >>>>> Under construction! <<<<< + * + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2002 California Institute of Technology + * + */ + +#ifndef CT_RESID_H +#define CT_RESID_H + +#include +#include "ctexceptions.h" +#include "stringUtils.h" + +namespace Cantera { + + + /** + * Residual function evaluator for a zero-dimensional problem. + */ + class Resid { + public: + + /** + * Constructor. + * @param nv Number of variables at each grid point. + * @param points Number of grid points. + */ + Resid(int nv=1, doublereal time = 0.0) { + m_nv = nv; + m_max.resize(m_nv, 0.0); + m_min.resize(m_nv, 0.0); + m_rtol.resize(m_nv, 0.0); + m_atol.resize(m_nv, 0.0); + m_time = time; + m_slast.resize(m_nv); + setSteadyMode(); + } + + void resize(int nv) { + m_nv = nv; + m_max.resize(m_nv, 0.0); + m_min.resize(m_nv, 0.0); + m_rtol.resize(m_nv, 0.0); + m_atol.resize(m_nv, 0.0); + m_slast.resize(m_nv); + setSteadyMode(); + } + + /// Destructor. + virtual ~Resid(){} + + /// Number of components + int nComponents() const { return m_nv; } + + /// Name of the nth component. + virtual string componentName(int n) const { + return "component " + int2str(n); } + + void setBounds(int nl, const doublereal* lower, + int nu, const doublereal* upper) { + if (nl != m_nv || nu != m_nv) + throw CanteraError("Resid::setBounds", + "wrong array size for solution bounds"); + copy(upper, upper + m_nv, m_max.begin()); + copy(lower, lower + m_nv, m_min.begin()); + } + + void setTolerances(int nr, const doublereal* rtol, + int na, const doublereal* atol) { + if (nr != m_nv || na != m_nv) + throw CanteraError("Resid::setTolerances", + "wrong array size for solution error tolerances"); + copy(rtol, rtol + m_nv, m_rtol.begin()); + copy(atol, atol + m_nv, m_atol.begin()); + } + + doublereal rtol(int n) { return m_rtol[n]; } + doublereal atol(int n) { return m_atol[n]; } + + doublereal upperBound(int n) const { return m_max[n]; } + doublereal lowerBound(int n) const { return m_min[n]; } + + void initTimeInteg(doublereal dt, const doublereal* x0) { + copy(x0, x0 + m_nv, m_slast.begin()); + m_rdt = 1.0/dt; + } + + void setSteadyMode() { m_rdt = 0.0; } + + bool steady() { return (m_rdt == 0.0); } + bool transient() { return (m_rdt != 0.0); } + + + /** + * Evaluate the residual function. + */ + virtual void eval(doublereal* x, doublereal* r) { + throw CanteraError("Resid::eval", + "residual function not defined."); + } + + virtual void update(doublereal* x) {} + + void evalss(doublereal* x, doublereal* r) { + doublereal rdt_save = m_rdt; + m_rdt = 0.0; + eval(x, r); + m_rdt = rdt_save; + } + + doublereal time() { return m_time;} + doublereal rdt() { return m_rdt; } + void incrementTime(doublereal dt) { m_time += dt; } + + protected: + int m_nv; + int m_points; + vector_fp m_slast; + doublereal m_rdt; + doublereal m_time; + vector_fp m_max; + vector_fp m_min; + vector_fp m_rtol; + vector_fp m_atol; + + private: + + }; +} + +#endif + + diff --git a/Cantera/src/Resid1D.h b/Cantera/src/Resid1D.h new file mode 100755 index 000000000..676a9babc --- /dev/null +++ b/Cantera/src/Resid1D.h @@ -0,0 +1,237 @@ +/** + * @file Resid1D.h + * + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2002 California Institute of Technology + * + */ + +#ifndef CT_RESID1D_H +#define CT_RESID1D_H + + +//#include "stringUtils.h" +#include "ctexceptions.h" +#include "xml.h" + +namespace Cantera { + + // domain types + const int cFlowType = 101; + const int cSurfType = 102; + const int cConnectorType = 103; + const int cInletType = 104; + const int cSymmType = 105; + const int cOutletType = 106; + + class MultiJac; + class OneDim; + + + /** + * Base class for single-domain, one-dimensional residual function + * evaluators. + */ + class Resid1D { + public: + + /** + * Constructor. + * @param nv Number of variables at each grid point. + * @param points Number of grid points. + */ + Resid1D(int nv=1, int points=1, + doublereal time = 0.0) : + m_time(time), + m_container(0), + m_index(-1), + m_type(0), + m_iloc(0), + m_jstart(0), + m_left(0), + m_right(0) { + resize(nv, points); + } + + /// Destructor. + virtual ~Resid1D(){} + + /// Domain type flag. + const int domainType() { return m_type; } + + const OneDim& container() const{ return *m_container; } + + /** + * Specify the container object for this domain, and the + * position of this domain in the list. + */ + void setContainer(OneDim* c, int index){ + m_container = c; + m_index = index; + } + + /** Initialize. Base class method does nothing, but may be + * overloaded. + */ + virtual void init(){} + + /** + * Resize the domain to have nv components and np grid points. + */ + virtual void resize(int nv, int np) { + m_nv = nv; + m_max.resize(m_nv, 0.0); + m_min.resize(m_nv, 0.0); + m_rtol.resize(m_nv, 0.0); + m_atol.resize(m_nv, 0.0); + m_points = np; + m_slast.resize(m_nv * m_points, 0.0); + locate(); + } + + /// Number of components at each grid point. + int nComponents() const { return m_nv; } + + /// Number of grid points in this domain. + int nPoints() const { return m_points; } + + /// Name of the nth component. May be overloaded. + virtual string componentName(int n) const { + return "component " + int2str(n); } + + /** + * Set the lower and upper bounds for each solution component. + */ + void setBounds(int nl, const doublereal* lower, + int nu, const doublereal* upper) { + if (nl != m_nv || nu != m_nv) + throw CanteraError("Resid1D::setBounds", + "wrong array size for solution bounds"); + copy(upper, upper + m_nv, m_max.begin()); + copy(lower, lower + m_nv, m_min.begin()); + } + + void setTolerances(int nr, const doublereal* rtol, + int na, const doublereal* atol) { + if (nr != m_nv || na != m_nv) + throw CanteraError("Resid1D::setTolerances", + "wrong array size for solution error tolerances. Size should be "+int2str(m_nv)); + copy(rtol, rtol + m_nv, m_rtol.begin()); + copy(atol, atol + m_nv, m_atol.begin()); + } + + doublereal rtol(int n) { return m_rtol[n]; } + doublereal atol(int n) { return m_atol[n]; } + + doublereal upperBound(int n) const { return m_max[n]; } + doublereal lowerBound(int n) const { return m_min[n]; } + + void initTimeInteg(doublereal dt, const doublereal* x0) { + copy(x0 + loc(), x0 + loc() + size(), m_slast.begin()); + m_rdt = 1.0/dt; + } + + void setSteadyMode() { m_rdt = 0.0; } + + bool steady() { return (m_rdt == 0.0); } + bool transient() { return (m_rdt != 0.0); } + + void needJacUpdate(); + + void evalss(doublereal* x, doublereal* r, integer* mask) { + eval(-1,x,r,mask,0.0); + } + + /** + * Evaluate the residual function at point j. If j < 0, + * evaluate the residual function at all points. + */ + virtual void eval(int j, doublereal* x, doublereal* r, + integer* mask, doublereal rdt=0.0) { + throw CanteraError("Resid1D::eval", + "residual function not defined."); + } + + virtual void update(doublereal* x) {} + + doublereal time() { return m_time;} + void incrementTime(doublereal dt) { m_time += dt; } + size_t index(int n, int j) const { return m_nv*j + n; } + + virtual void setJac(MultiJac* jac){} + virtual void save(XML_Node& o, doublereal* sol) { + throw CanteraError("Resid1D::save","base class method called"); + } + + int size() { return m_nv*m_points; } + + void locate() { + if (m_left) { + m_jstart = m_left->lastPoint() + 1; + m_iloc = m_left->loc() + m_left->size(); + } + else { + m_jstart = 0; + m_iloc = 0; + } + if (m_right) m_right->locate(); + } + + virtual int loc(int j = 0) { return m_iloc; } + + int firstPoint() { return m_jstart; } + int lastPoint() { return m_jstart + m_points - 1; } + + void append(Resid1D* right) { + linkRight(right); + right->linkLeft(this); + } + + void linkLeft(Resid1D* left) { + m_left = left; + locate(); + } + void linkRight(Resid1D* right) { m_right = right; } + + Resid1D* left() { return m_left; } + Resid1D* right() { return m_right; } + + double prevSoln(int n, int j) const{ + return m_slast[m_nv*j + n]; + } + + void setID(const string& s) {m_id = s;} + void setDesc(const string& s) {m_desc = s;} + + virtual void getTransientMask(integer* mask){} + + protected: + + doublereal m_rdt; + int m_nv; + int m_points; + vector_fp m_slast; + doublereal m_time; + vector_fp m_max; + vector_fp m_min; + vector_fp m_rtol; + vector_fp m_atol; + OneDim* m_container; + int m_index; + int m_type; + int m_iloc; + int m_jstart; + Resid1D *m_left, *m_right; + string m_id, m_desc; + + private: + + }; +} + +#endif + + diff --git a/Cantera/src/ResidEval.h b/Cantera/src/ResidEval.h new file mode 100755 index 000000000..1cc04af15 --- /dev/null +++ b/Cantera/src/ResidEval.h @@ -0,0 +1,56 @@ +/** + * @file FuncEval.h + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + +#ifndef CT_RESIDEVAL_H +#define CT_RESIDEVAL_H + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +namespace Cantera { + + + /** + * + * Virtual base class for DAE residual function evaluators. + * + */ + class ResidEval { + + public: + + /** + * Evaluate the residual function. + * @param t time (input, do not modify) + * @param y solution vector (input, do not modify) + * @param ydot rate of change of solution vector. (input, do + * not modify) + */ + virtual void evalResid(double t, const double* y, + const double* ydot, double* resid)=0; + + /** Number of equations. */ + virtual int neq()=0; + + // virtual bool init(double t0)=0; + virtual double* solution()=0; + virtual double* solution_dot()=0; + + protected: + + private: + + }; + +} + +#endif diff --git a/Cantera/src/RxnRates.h b/Cantera/src/RxnRates.h new file mode 100755 index 000000000..2d837d6b5 --- /dev/null +++ b/Cantera/src/RxnRates.h @@ -0,0 +1,118 @@ +/** + * @file RxnRates.h + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_RXNRATES_H +#define CT_RXNRATES_H + +#include "reaction_defs.h" + +namespace Cantera { + + + class Arrhenius { + + public: + static int type(){ return ARRHENIUS; } + Arrhenius() : m_b (0.0), m_E (0.0) {} + Arrhenius( const doublereal* c ) + : m_b (c[1]), m_E (c[2]) { m_logA = log(c[0]);} + + void update_C(const doublereal* c) {} + + doublereal update(doublereal logT, doublereal recipT) const { + return m_logA + m_b*logT - m_E*recipT; + } + + doublereal update_dT(doublereal logT, doublereal recipT) const { + return recipT*(m_b + m_E*recipT); + } + + void writeUpdateRHS(ostream& s) const { + s << " exp(" << m_logA; + if (m_b != 0.0) s << " + " << m_b << " * tlog"; + if (m_E != 0.0) s << " - " << m_E << " * rt"; + s << ");" << endl; + } + + protected: + doublereal m_logA, m_b, m_E; + }; + +#ifdef INCL_TST + + class TST { + + public: + static int type(){ return TSTRATE; } + TST() {} + TST( const vector_fp& c ) { + m_b.resize(10); + copy(c.begin(), c.begin() + 10, m_b.begin()); + m_k = int(c[10]); + } + + void update_C(const vector_fp& c) { + doublereal ck = c[m_k]; + delta_s0 = m_b[0] + m_b[1]*ck + m_b[2]*ck*ck; + delta_e0 = m_b[5] + m_b[6]*ck + m_b[7]*ck*ck; + } + + doublereal update(doublereal logT, doublereal recipT) const { + doublereal delta_s = delta_s0*(1.0 + m_b[3]*logT + m_b[4]*recipT); + doublereal delta_E = delta_e0*(1.0 + m_b[8]*logT + m_b[9]*recipT); + return logBoltz_Planck + logT + delta_s - delta_E*recipT; + } + + void writeUpdateRHS(ostream& s) const {} + + protected: + doublereal delta_s0, delta_e0; + int m_k; + vector_fp m_b; + }; + +#endif + +} + + +// class LandauTeller { + +// public: +// static int type(){ return LANDAUTELLER; } +// LandauTeller(){} +// LandauTeller( const vector_fp& c ) : m_c(c) { m_c[0] = log(c[0]); } + +// doublereal update(doublereal logT, doublereal recipT) const { +// return m_c[0] + m_c[1]*tt[1] - m_c[2]*tt[2] +// + m_c[3]*tt[3] + m_c[4]*tt[4]; +// } + +// //void writeUpdateRHS(ostream& s) const { +// // s << exp(m_logA); +// // s << " * exp("; +// // if (m_b != 0.0) s << m_b << " * tlog"; +// // if (m_E != 0.0) s << " - " << m_E << " * rt"; +// // if (m_E != 0.0) s << " - " << m_E << " * rt"; +// // s << ");" << endl; +// // } +// //} + +// protected: +// doublereal m_logA, m_b, m_E; +// }; + +//} + + +#endif + + diff --git a/Cantera/src/ShomatePoly.h b/Cantera/src/ShomatePoly.h new file mode 100755 index 000000000..190157c2c --- /dev/null +++ b/Cantera/src/ShomatePoly.h @@ -0,0 +1,108 @@ +/** + * @file ShomatePoly.h + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_SHOMATEPOLY1_H +#define CT_SHOMATEPOLY1_H + +namespace Cantera { + + /** + * The Shomate polynomial parameterization for one temperature range. + * Seven coefficients \f$(a_0,\dots,a_6)\f$ are used to represent + * \f$ c_p^0(T)\f$, \f$ h^0(T)\f$, and \f$ s^0(T) \f$ as + * polynomials in \f$ T \f$ : + * \f[ + * \hat c_p(T) = A + B t + C t^2 + D t^3 + \frac{E}{t^2} + * \f] + * \f[ + * \hat h^0(T)} = A t + \frac{B t^2}{2} + \frac{C t^3}{3} + + \frac{D t^4}{4} - \frac{E}{t} + F. + * \f] + * \f[ + * s^0(T) = A\ln t + B t + \frac{C t^2}{2} + + \frac{D t^3}{3} - \frac{E}{2t^2} + G. + * \f] + */ + + class ShomatePoly { + + public: + + ShomatePoly() + : m_lowT(0.0), m_highT (0.0), + m_Pref(0.0), m_index (0) {m_coeff.resize(7);} + + ShomatePoly(int n, doublereal tlow, doublereal thigh, doublereal pref, + const doublereal* coeffs) : + m_lowT (tlow), + m_highT (thigh), + m_Pref (pref), + m_index (n) { + m_coeff.resize(7); + copy(coeffs, coeffs + 7, m_coeff.begin()); + } + + virtual ~ShomatePoly(){} + + doublereal minTemp() const { return m_lowT;} + doublereal maxTemp() const { return m_highT;} + doublereal refPressure() const { return m_Pref; } + + /** + * t is T/1000. + * + * tt[0] t + * tt[1] t*t + * tt[2] t*t*t + * tt[3] t^4 + * tt[4] ln t + */ + void updateProperties(const doublereal* tt, + doublereal* cp_R, doublereal* h_RT, doublereal* s_R) const { + + doublereal A = m_coeff[0]; + doublereal Bt = m_coeff[1]*tt[0]; + doublereal Ct2 = m_coeff[2]*tt[1]; + doublereal Dt3 = m_coeff[3]*tt[2]; + doublereal Etm2 = m_coeff[4]*tt[3]; + doublereal F = m_coeff[5]; + doublereal G = m_coeff[6]; + + doublereal cp, h, s; + cp = A + Bt + Ct2 + Dt3 + Etm2; + h = tt[0]*(A + 0.5*Bt + OneThird*Ct2 + 0.25*Dt3 - Etm2) + F; + s = A*tt[4] + Bt + 0.5*Ct2 + OneThird*Dt3 - 0.5*Etm2 + G; + h *= 1.e6; + + cp_R[m_index] = 1.e3 * cp * tt[5]; + h_RT[m_index] = h * tt[6]; + s_R[m_index] = 1.e3 * s * tt[5]; + } + + protected: + + doublereal m_lowT, m_highT, m_Pref; + array_fp m_coeff; + int m_index; + + private: + + }; + +} + +#endif + + + + + + diff --git a/Cantera/src/ShomateThermo.h b/Cantera/src/ShomateThermo.h new file mode 100755 index 000000000..fa438de9a --- /dev/null +++ b/Cantera/src/ShomateThermo.h @@ -0,0 +1,149 @@ +/** + * @file ShomateThermo.h + * + * This parameterization requires 7 coefficients A - G: + * + * Cp° = A + B*t + C*t2 + D*t3 + E/t^2 + * + * H° - H°298.15= A*t + B*t^2/2 + C*t^3/3 + D*t^4/4 - E/t + F + * - \Delta_f H°f,298 + * + * S° = A*ln(t) + B*t + C*t^2/2 + D*t^3/3 - E/(2*t^2) + G + * + * Cp = heat capacity (J/mol*K) + * H° = standard enthalpy (kJ/mol) + * \Delta_f H°298.15 = enthalpy of formation at 298.15 K (kJ/mol) + * S° = standard entropy (J/mol*K) + * t = temperature (K) / 1000. + * + */ + +#ifndef CT_SHOMATETHERMO_H +#define CT_SHOMATETHERMO_H + +#include "SpeciesThermoMgr.h" +#include "ShomatePoly.h" +#include "speciesThermoTypes.h" + +namespace Cantera { + + /** + * A species thermodynamic property manager for the Shomate + * polynomial parameterization. This is the parameterization used + * in the NIST Chemistry WebBook (http://webbook.nist.gov/chemistry) + */ + class ShomateThermo : public SpeciesThermo { + + public: + + const int ID; + + ShomateThermo() : + ID(SHOMATE), + m_tlow_max(0.0), + m_thigh_min(1.e30), + m_ngroups(0) { m_t.resize(7); } + + virtual ~ShomateThermo() {} + + /** + * Install values for a new species. + * @param index Species index + * @param type ignored, since only Shomate type is supported + * @param c coefficients. These are parameters A through G + * in the same units as used in the NIST Chemistry WebBook. + * + */ + virtual void install(int index, int type, const doublereal* c, + doublereal minTemp, doublereal maxTemp, doublereal refPressure) { + int imid = int(c[0]); // midpoint temp converted to integer + int igrp = m_index[imid]; // has this value been seen before? + if (igrp == 0) { // if not, prepare new group + vector v; + m_high.push_back(v); + m_low.push_back(v); + m_tmid.push_back(c[0]); + m_index[imid] = igrp = m_high.size(); + m_ngroups++; + } + doublereal tlow = minTemp; + doublereal tmid = c[0]; + doublereal thigh = maxTemp; + doublereal pref = refPressure; + const doublereal* clow = c + 1; + const doublereal* chigh = c + 8; + m_high[igrp-1].push_back(ShomatePoly(index, tmid, thigh, + pref, chigh)); + m_low[igrp-1].push_back(ShomatePoly(index, tlow, tmid, + pref, clow)); + if (tlow > m_tlow_max) m_tlow_max = tlow; + if (thigh < m_thigh_min) m_thigh_min = thigh; + m_tlow.push_back(tlow); + m_thigh.push_back(thigh); + m_p0 = pref; + } + + + virtual void update(doublereal t, doublereal* cp_R, + doublereal* h_RT, doublereal* s_R) const { + int i; + + doublereal tt = 1.e-3*t; + m_t[0] = tt; + m_t[1] = tt*tt; + m_t[2] = m_t[1]*tt; + m_t[3] = 1.0/m_t[1]; + m_t[4] = log(tt); + m_t[5] = 1.0/GasConstant; + m_t[6] = 1.0/(GasConstant * t); + + vector::const_iterator _begin, _end; + for (i = 0; i != m_ngroups; i++) { + if (t > m_tmid[i]) { + _begin = m_high[i].begin(); + _end = m_high[i].end(); + } + else { + _begin = m_low[i].begin(); + _end = m_low[i].end(); + } + for (; _begin != _end; ++_begin) { + _begin->updateProperties(m_t.begin(), cp_R, h_RT, s_R); + } + } + } + + virtual doublereal minTemp(int k=-1) const { + if (k < 0) + return m_tlow_max; + else + return m_tlow[k]; + } + + virtual doublereal maxTemp(int k=-1) const { + if (k < 0) + return m_thigh_min; + else + return m_thigh[k]; + } + + virtual doublereal refPressure() const {return m_p0;} + + protected: + + vector > m_high; + vector > m_low; + map m_index; + vector_fp m_tmid; + doublereal m_tlow_max; + doublereal m_thigh_min; + vector_fp m_tlow; + vector_fp m_thigh; + doublereal m_p0; + int m_ngroups; + mutable vector_fp m_t; + }; + +} + +#endif diff --git a/Cantera/src/SimpleThermo.h b/Cantera/src/SimpleThermo.h new file mode 100644 index 000000000..06487613b --- /dev/null +++ b/Cantera/src/SimpleThermo.h @@ -0,0 +1,95 @@ +/** + * + */ + +#ifndef CT_SIMPLETHERMO_H +#define CT_SIMPLETHERMO_H + +#include "SpeciesThermoMgr.h" + +namespace Cantera { + + /** + * A simple species thermodynamic property manager. + */ + class SimpleThermo : public SpeciesThermo { + + public: + + const int ID; + + SimpleThermo() : + ID(SIMPLE), + m_tlow_max(0.0), + m_thigh_min(1.e30), + m_p0(-1.0), m_nsp(0) {} + + + virtual ~SimpleThermo() {} + + virtual void install(int index, int type, const doublereal* c, + doublereal minTemp, doublereal maxTemp, doublereal refPressure) { + m_logt0.push_back(log(c[0])); + m_t0.push_back(c[0]); + m_h0_R.push_back(c[1]/GasConstant); + m_s0_R.push_back(c[2]/GasConstant); + m_cp0_R.push_back(c[3]/GasConstant); + m_nsp++; + doublereal tlow = minTemp; + doublereal thigh = maxTemp; + m_p0 = refPressure; + if (tlow > m_tlow_max) m_tlow_max = tlow; + if (thigh < m_thigh_min) m_thigh_min = thigh; + m_tlow.push_back(tlow); + m_thigh.push_back(thigh); + } + + + virtual void update(doublereal t, doublereal* cp_R, + doublereal* h_RT, doublereal* s_R) const { + int k; + doublereal logt = log(t); + doublereal rt = 1.0/t; + for (k = 0; k < m_nsp; k++) { + cp_R[k] = m_cp0_R[k]; + h_RT[k] = rt*(m_h0_R[k] + (t - m_t0[k]) * m_cp0_R[k]); + s_R[k] = m_s0_R[k] + m_cp0_R[k] * (logt - m_logt0[k]); + } + } + + virtual doublereal minTemp(int k=-1) const { + if (k < 0) + return m_tlow_max; + else + return m_tlow[k]; + } + + virtual doublereal maxTemp(int k=-1) const { + if (k < 0) + return m_thigh_min; + else + return m_thigh[k]; + } + + virtual doublereal refPressure() const {return m_p0;} + + protected: + + map m_index; + doublereal m_tlow_max; + doublereal m_thigh_min; + vector_fp m_tlow; + vector_fp m_thigh; + vector_fp m_t0; + vector_fp m_logt0; + vector_fp m_h0_R; + vector_fp m_s0_R; + vector_fp m_cp0_R; + doublereal m_p0; + int m_nsp; + + }; + +} + +#endif diff --git a/Cantera/src/SpeciesThermo.h b/Cantera/src/SpeciesThermo.h new file mode 100755 index 000000000..2753da0cb --- /dev/null +++ b/Cantera/src/SpeciesThermo.h @@ -0,0 +1,122 @@ +/** + * @file SpeciesThermo.h + * + * Species thermodynamic property managers. + */ + +/* + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_SPECIESTHERMO_H +#define CT_SPECIESTHERMO_H + +#include "ct_defs.h" + +namespace Cantera { + + /** + * @defgroup spthermo Species Standard-State Thermodynamic Properties + * + * Species thermodynamic property managers compute the + * standard-state properties of pure species. They are designed + * for use by thermodynamic property managers (subclasses of + * ThermoPhase) to compute the thermodynamic properties of + * solutions. + */ + + + //////////////////////// class SpeciesThermo //////////////////// + + /** + * Virtual base class for the species thermo + * manager classes. This class defines the interface which all + * subclasses must implement. + * @ingroup spthermo + */ + + class SpeciesThermo { + + public: + + SpeciesThermo() {} + virtual ~SpeciesThermo() {} + + /** + * install a new species thermodynamic property + * parameterization for one species. + * @param index The 'update' method will update the property + * values at position \i index in the property arrays. + * @param type int flag specifying the type of parameterization to be + * installed. + * @param c vector of coefficients for the parameterization. + * This vector is simply passed through to the parameterization + * constructor. + * @param minTemp minimum temperature for which this parameterization + * is valid. + * @param maxTemp maximum temperature for which this parameterization + * is valid. + * @param refPressure standard-state pressure for this + * parameterization. + * @see speciesThermoTypes.h + */ + virtual void install(int index, int type, const doublereal* c, + doublereal minTemp, doublereal maxTemp, doublereal refPressure)=0; + + /** + * Compute the standard-state properties for all species. + * Given temperature T in K, this method updates the values of + * the non-dimensional heat capacity at constant pressure, + * enthalpy, and entropy. + */ + virtual void update(doublereal T, + doublereal* cp_R, + doublereal* h_RT, + doublereal* s_R) const=0; + + /** + * Like update, but only updates position k. + */ + virtual void update_one(int k, doublereal T, + doublereal* cp_R, + doublereal* h_RT, + doublereal* s_R) const {} + + /** + * Minimum temperature. If no argument is supplied, this + * method returns the minimum temperature for which \e all + * parameterizations are valid. If an integer index k is + * supplied, then the value returned is the minimum + * temperature for parameterization k. + */ + virtual doublereal minTemp(int k=-1) const =0; + + /** + * Maximum temperature. If no argument is supplied, this + * method returns the maximum temperature for which \e all + * parameterizations are valid. If an integer index k is + * supplied, then the value returned is the maximum + * temperature for parameterization k. + */ + virtual doublereal maxTemp(int k=-1) const =0; + + /** + * The standard-state pressure. All parameterizations must be + * for the same standard-state pressure. + */ + virtual doublereal refPressure() const =0; + }; +} + +#endif + + + + + + diff --git a/Cantera/src/SpeciesThermoFactory.cpp b/Cantera/src/SpeciesThermoFactory.cpp new file mode 100755 index 000000000..1665055ad --- /dev/null +++ b/Cantera/src/SpeciesThermoFactory.cpp @@ -0,0 +1,83 @@ +/** + * @file SpeciesThermoFactory.cpp + */ + +/* + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifdef WIN32 +#pragma warning(disable:4786) +#endif + +#include "SpeciesThermoFactory.h" + +#include "SpeciesThermo.h" +#include "NasaThermo.h" +#include "ShomateThermo.h" +#include "PolyThermoMgr.h" +#include "SimpleThermo.h" + +#include "SpeciesThermoMgr.h" +#include "speciesThermoTypes.h" + +#include "xml.h" + +namespace Cantera { + + SpeciesThermoFactory* SpeciesThermoFactory::__factory = 0; + + /** + * Return a species thermo manager to handle the parameterizations + * specified in a CTML phase specification. + */ + SpeciesThermo* SpeciesThermoFactory::newSpeciesThermo(XML_Node* node) { + XML_Node& sparray = *node; //node->child("speciesData"); + vector sp; + sparray.getChildren("species",sp); + int ns = sp.size(); + int inasa = 0; + int ishomate = 0; + int isimple = 0; + for (int n = 0; n < ns; n++) { + XML_Node& th = sp[n]->child("thermo"); + if (th.hasChild("NASA")) inasa = 1; + if (th.hasChild("Shomate")) ishomate = 1; + if (th.hasChild("const_cp")) isimple = 1; + if (th.hasChild("poly")) { + if (th.child("poly")["order"] == "1") isimple = 1; + else throw CanteraError("newSpeciesThermo", + "poly with order > 1 not yet supported"); + } + } + return newSpeciesThermo(NASA*inasa + + SHOMATE*ishomate + SIMPLE*isimple); + } + + SpeciesThermo* SpeciesThermoFactory::newSpeciesThermo(int type) { + + switch (type) { + + case NASA: + return new NasaThermo; + case SHOMATE: + return new ShomateThermo; + case SIMPLE: + return new SimpleThermo; + case NASA + SHOMATE: + return new SpeciesThermoDuo; + case NASA + SIMPLE: + return new SpeciesThermoDuo; + default: + throw UnknownSpeciesThermo( + "SpeciesThermoFactory::newSpeciesThermo",type); + return 0; + } + } + +} diff --git a/Cantera/src/SpeciesThermoFactory.h b/Cantera/src/SpeciesThermoFactory.h new file mode 100755 index 000000000..a3e2b68db --- /dev/null +++ b/Cantera/src/SpeciesThermoFactory.h @@ -0,0 +1,83 @@ +/** + * @file SpeciesThermoFactory.h + */ + +/* + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef SPECIESTHERMO_FACTORY_H +#define SPECIESTHERMO_FACTORY_H + +#include "SpeciesThermo.h" +//#include "xml.h" + +namespace Cantera { + + class XML_Node; + + /** + * Factory to build instances of classes that manage the + * standard-state thermodynamic properties of a set of species. + */ + class SpeciesThermoFactory { + + public: + + static SpeciesThermoFactory* factory() { + if (!__factory) __factory = new SpeciesThermoFactory; + return __factory; + } + + virtual ~SpeciesThermoFactory() { + delete __factory; + __factory = 0; + } + + /** + * Create a new species property manager. + * @param type the type to be created. + */ + virtual SpeciesThermo* newSpeciesThermo(int type); + virtual SpeciesThermo* newSpeciesThermo(XML_Node* node); + + private: + static SpeciesThermoFactory* __factory; + SpeciesThermoFactory(){} + }; + + + /** + * Create a new species thermo manager instance. + */ + inline SpeciesThermo* newSpeciesThermoMgr(int type, + SpeciesThermoFactory* f=0) { + if (f == 0) { + f = SpeciesThermoFactory::factory(); + } + SpeciesThermo* sptherm = f->newSpeciesThermo(type); + return sptherm; + } + + /** + * Create a new species thermo manager instance. + */ + inline SpeciesThermo* newSpeciesThermoMgr(XML_Node* node, + SpeciesThermoFactory* f=0) { + if (f == 0) { + f = SpeciesThermoFactory::factory(); + } + SpeciesThermo* sptherm = f->newSpeciesThermo(node); + return sptherm; + } + +} + +#endif + + diff --git a/Cantera/src/SpeciesThermoMgr.h b/Cantera/src/SpeciesThermoMgr.h new file mode 100755 index 000000000..8529baa5d --- /dev/null +++ b/Cantera/src/SpeciesThermoMgr.h @@ -0,0 +1,215 @@ +/** + * @file SpeciesThermoMgr.h + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_SPECIESTHERMO_MGR_H +#define CT_SPECIESTHERMO_MGR_H + +#include "ct_defs.h" +#include "ctexceptions.h" +#include "stringUtils.h" +#include "SpeciesThermo.h" + +namespace Cantera { + + /////////////////////////////////////////////////////////////// + // + // Helper Template Functions + // + /////////////////////////////////////////////////////////////// + + /** + * Invokes the 'updateProperties' method of all objects in the + * list. + */ + template + inline void _updateAll( + InputIter begin, + InputIter end, + doublereal t, + vector_fp& cp_R, + vector_fp& h_RT, + vector_fp& s_R) { + for (; begin != end; ++begin) + begin->updateProperties(t, cp_R, h_RT, s_R); + } + + + /** + * Iterates through a list of objects which implement a method + * 'minTemp()', and returns the largest 'minTemp' value. + */ + template + doublereal _minTemp(InputIter begin, InputIter end) { + doublereal _minT = 0.0; + for (; begin != end; ++begin) + _minT = fmaxx(_minT, begin->minTemp()); + return _minT; + } + + + /** + * Iterates through a list of objects that implement a method + * 'maxTemp()', and returns the smallest 'maxTemp' value. + */ + template + doublereal _maxTemp(_InputIter __begin, _InputIter __end) { + doublereal _maxT = 1.e10; + for (; __begin != __end; ++__begin) + _maxT = fminn(_maxT, __begin->maxTemp()); + return _maxT; + } + + + /////////////////////// Exceptions ////////////////////////////// + + + /** + * Exception thrown if species reference pressures don't match. + * @ingroup spthermo + */ + class RefPressureMismatch : public CanteraError { + public: + RefPressureMismatch(string proc, doublereal prnew, + doublereal prold) : CanteraError(proc, + "Species reference pressure (" + + fp2str(prnew) + ") does not match previously-defined " + + "reference pressure (" + fp2str(prold) + ")") {} + virtual ~RefPressureMismatch() {} + }; + + class UnknownSpeciesThermo + : public CanteraError { + public: + UnknownSpeciesThermo(string proc, int type) : + CanteraError(proc, "Specified species " + "parameterization type (" + int2str(type) + + ") does not match any known type.") {} + virtual ~UnknownSpeciesThermo() {} + }; + + + + /** + * This species thermo manager requires that all species have one + * of two parameterizations. + */ + template + class SpeciesThermoDuo : public SpeciesThermo { + + public: + + SpeciesThermoDuo() {} + virtual ~SpeciesThermoDuo(){} + + virtual void install(int sp, int type, const doublereal* c, + doublereal minTemp, doublereal maxTemp, doublereal refPressure) { + if (type == m_thermo1.ID) + m_thermo1.install(sp, 0, c, minTemp, maxTemp, refPressure); + else if (type == m_thermo2.ID) + m_thermo2.install(sp, 0, c, minTemp, maxTemp, refPressure); + else + throw UnknownSpeciesThermo("SpeciesThermoDuo:install",type); + } + + virtual void update(doublereal t, doublereal* cp_R, + doublereal* h_RT, doublereal* s_R) const { + m_thermo1.update(t, cp_R, h_RT, s_R); + m_thermo2.update(t, cp_R, h_RT, s_R); + } + + virtual doublereal minTemp(int k = -1) const { + doublereal tm1 = m_thermo1.minTemp(); + doublereal tm2 = m_thermo2.minTemp(); + return (tm1 < tm2 ? tm2 : tm1); + } + + virtual doublereal maxTemp(int k = -1) const { + doublereal tm1 = m_thermo1.maxTemp(); + doublereal tm2 = m_thermo2.maxTemp(); + return (tm1 < tm2 ? tm1 : tm2); + } + + virtual doublereal refPressure() const { + return m_thermo1.refPressure(); + } + + private: + + T1 m_thermo1; + T2 m_thermo2; + }; + + + /** + * This species thermo manager requires that all species have the + * same parameterization. + */ + template + class SpeciesThermo1 : public SpeciesThermo { + + public: + + SpeciesThermo1() : m_pref(0.0) {} + virtual ~SpeciesThermo1(){} + + virtual void install(int sp, int type, const vector_fp& c) { + m_thermo.push_back(T(sp, c)); + if (m_pref) { + if (m_thermo.begin()->refPressure() != m_pref) { + throw RefPressureMismatch("SpeciesThermo1:install", + refPressure(), m_pref); + } + } + else m_pref = m_thermo.begin()->refPressure(); + } + + virtual void update(doublereal t, vector_fp& cp_R, + vector_fp& h_RT, vector_fp& s_R) const { + _updateAll(m_thermo.begin(),m_thermo.end(), + t, cp_R, h_RT, s_R); + } + + virtual void update_one(int k, doublereal t, vector_fp& cp_R, + vector_fp& h_RT, vector_fp& s_R) const { + m_thermo[k]->update(t, cp_R, h_RT, s_R); + } + + virtual doublereal minTemp(int k = -1) const { + if (k < 0) + return _minTemp(m_thermo.begin(), m_thermo.end()); + else + return m_thermo[k].minTemp(); + } + + virtual doublereal maxTemp(int k = -1) const { + if (k < 0) + return _maxTemp(m_thermo.begin(), m_thermo.end()); + else + return m_thermo[k].maxTemp(); + } + + virtual doublereal refPressure() const { + return m_pref; + } + + private: + vector m_thermo; + doublereal m_pref; + }; +} + +#endif + + + + + + diff --git a/Cantera/src/State.h b/Cantera/src/State.h new file mode 100755 index 000000000..9238c719b --- /dev/null +++ b/Cantera/src/State.h @@ -0,0 +1,352 @@ +/** + * + * @file State.h + * + * This file implements class State. + */ + +/* + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2001 California Institute of Technology + * See file License.txt for licensing information + * + */ + + +#ifndef CT_STATE2_H +#define CT_STATE2_H + +//#include "config.h" +//#include "ct_defs.h" +#include "utilities.h" +#include "updaters.h" +#include "ctexceptions.h" + +namespace Cantera { + + /** + * Manages the thermodynamic state. Class State manages the + * thermodynamic state of a multi-species solution. It + * holds values for the temperature, mass density, and mean + * molecular weight, and a vector of species mass + * fractions. For efficiency in mass/mole conversion, the vector + * of mass fractions divided by molecular weight \f$ Y_k/M_k \f$ + * is also stored. + * + * Class State is not usually used directly in application + * programs. Its primary use is as a base class for class Phase. + */ + + class State { + + public: + + /** + * Constructor. + */ + State() : m_kk(0), m_temp(0.0), m_dens(0.001), m_mmw(0.0) { + } + + /** + * Destructor. Since no memory is allocated by methods of this + * class, the destructor does nothing. + */ + virtual ~State() {} + + + /** + * Return a read-only reference to the vector of molecular + * weights. + */ + const array_fp& molecularWeights() const { return m_molwts; } + + /** + * Get the species mole fractions. + * @param x On return, x contains the mole fractions. Must have a + * length greater than or equal to the number of species. + */ + void getMoleFractions(doublereal* x) const { + scale(m_ym.begin(), m_ym.end(), x, m_mmw); + } + + /// The mole fraction of species k. + doublereal moleFraction(int k) const { + if (k >= 0 && k < m_kk) { + return m_ym[k] * m_mmw; + } + else { + throw CanteraError("State:moleFraction", + "illegal species index number"); + } + } + + /** + * Set the mole fractions to the specified values, and then + * normalize them so that they sum to 1.0. + * @param x Array of unnormalized mole fraction values (input). + * Must have a length greater than or equal to the number of + * species. + */ + void setMoleFractions(const doublereal* x) { + int k; + doublereal sum = 0.0, norm = 0.0; + sum = dot(x, x + m_kk, m_molwts.begin()); + for (k = 0; k != m_kk; ++k) { + m_ym[k] = x[k] / sum; + m_y[k] = m_molwts[k]*m_ym[k]; + norm += x[k]; + } + m_mmw = sum/norm; + m_C_updater.need_update(); + } + + /** + * Set the mole fractions to the specified values without + * normalizing. + */ + void setMoleFractions_NoNorm(const doublereal* x) { + int k; + m_mmw = dot(x, x + m_kk, m_molwts.begin()); + doublereal rmmw = 1.0/m_mmw; + for (k = 0; k != m_kk; ++k) { + m_ym[k] = x[k]*rmmw; + m_y[k] = m_ym[k] * m_molwts[k]; + } + m_C_updater.need_update(); + } + + void getMassFractions(size_t leny, doublereal* y) const { + copy(m_y.begin(), m_y.end(), y); + } + + /** + * Get the species mass fractions. @param y On return, y + * contains the mass fractions. Array \i y must have a length + * greater than or equal to the number of species. + */ + void getMassFractions(doublereal* y) const { + copy(m_y.begin(), m_y.end(), y); + } + + /// Mass fraction of species k. + doublereal massFraction(int k) const { + if (k >= 0 && k < m_kk) { + return m_y[k]; + } + else { + throw CanteraError("State:massFraction", + "illegal species index number"); + } + } + + /** + * Set the mole fractions to the specified values, and then + * normalize them so that they sum to 1.0. + * @param x Array of unnormalized mole fraction values (input). + * Must have a length greater than or equal to the number of + * species. + */ + void setMassFractions(const doublereal* y) { + doublereal norm = 0.0, sum = 0.0; + int k; + for (k = 0; k != m_kk; ++k) { + norm += y[k]; + } + scale(y, y + m_kk, m_y.begin(), 1.0/norm); + for (k = 0; k != m_kk; ++k) { + m_ym[k] = m_y[k] * m_rmolwts[k]; + sum += m_ym[k]; + } + m_mmw = 1.0/sum; + m_C_updater.need_update(); + } + + /** + * Set the mass fractions to the specified values without + * normalizing. + */ + void setMassFractions_NoNorm(const doublereal* y) { + int k; + doublereal sum = 0.0; + for (k = 0; k != m_kk; ++k) { + m_y[k] = y[k]; + m_ym[k] = m_y[k] * m_rmolwts[k]; + sum += m_ym[k]; + } + m_mmw = 1.0/sum; + //copy(y, y + m_kk, m_y.begin()); + m_C_updater.need_update(); + } + + /** + * Get the species concentrations (kmol/m^3). @param c On return, c + * contains the concentrations. Array \i c must have a length + * greater than or equal to the number of species. + */ + void getConcentrations(doublereal* c) const { + doublereal f = m_dens; + scale(m_ym.begin(), m_ym.end(), c, f); + } + + /** + * Evaluate the mole-fraction-weighted mean of Q: + * \f[ \sum_k X_k Q_k. \f] + * Array Q should contain pure-species molar property + * values. + */ + doublereal mean_X(const doublereal* Q) const { + return m_mmw*dot(m_ym.begin(), m_ym.end(), Q); + } + + + /** + * Evaluate the mass-fraction-weighted mean of Q: + * \f[ \sum_k Y_k Q_k \f] + * Array Q should contain pure-species property + * values in mass units. + */ + doublereal mean_Y(const doublereal* Q) const { + return dot(m_y.begin(), m_y.end(), Q); + } + + /** + * The mean molecular weight. Units: (kg/kmol) + */ + doublereal meanMolecularWeight() const { + return m_mmw; + } + + /// Evaluate \f$ \sum_k X_k \log X_k \f$. + doublereal sum_xlogx() const { + return m_mmw*_sum_xlogx(m_ym.begin(), m_ym.end()) + log(m_mmw); + } + + /// Evaluate \f$ \sum_k X_k \log Q_k \f$. + doublereal sum_xlogQ(doublereal* Q) const { + return m_mmw * _sum_xlogQ(m_ym.begin(), m_ym.end(), Q); + } + + /// Temperature. Units: K. + doublereal temperature() const { return m_temp; } + + /// Density. Units: kg/m^3. + doublereal density() const { return m_dens; } + + /// Molar density. Units: kmol/m^3. + doublereal molarDensity() const { + return m_dens/meanMolecularWeight(); + } + + /// Set the density to value rho (kg/m^3). + void setDensity(doublereal rho) { + if (rho != m_dens) { + m_dens = rho; + m_C_updater.need_update(); + } + } + + /// Set the molar density to value n (kmol/m^3). + void setMolarDensity(doublereal n) { + m_dens = n*meanMolecularWeight(); + m_C_updater.need_update(); + } + + /// Set the temperature to value temp (K). + void setTemperature(doublereal temp) { + if (temp != m_temp) { + m_temp = temp; + m_T_updater.need_update(); + } + } + + /// set the concentrations to the specified values + void setConcentrations(const doublereal* c) { + int k; + doublereal sum = 0.0, norm = 0.0; + for (k = 0; k != m_kk; ++k) { + sum += c[k]*m_molwts[k]; + norm += c[k]; + } + m_mmw = sum/norm; + setDensity(sum); + doublereal rsum = 1.0/sum; + for (k = 0; k != m_kk; ++k) { + m_ym[k] = c[k] * rsum; + m_y[k] = m_ym[k] * m_molwts[k]; + } + m_C_updater.need_update(); + } + + const doublereal* massFractions() const { return m_y.begin(); } + + bool ready() const { return (m_kk > 0); } + + + protected: + + PropertyUpdater& updater_T() { return m_T_updater; } + PropertyUpdater& updater_C() { return m_C_updater; } + + /** + * @internal + * Initialize. Make a local copy of the vector of + * molecular weights, and resize the composition arrays to + * the appropriate size. The only information an instance of + * State has about the species is their molecular weights. + * + */ + void init(const array_fp& mw) { + m_kk = mw.size(); + m_molwts.resize(m_kk); + m_rmolwts.resize(m_kk); + m_y.resize(m_kk, 0.0); + m_ym.resize(m_kk, 0.0); + copy(mw.begin(), mw.end(), m_molwts.begin()); + for (int k = 0; k < m_kk; k++) + m_rmolwts[k] = 1.0/m_molwts[k]; + } + + int m_kk; + doublereal m_temp, m_dens; + doublereal m_mmw; + mutable array_fp m_ym, m_y; + array_fp m_molwts, m_rmolwts; + + // property updaters + mutable PropertyUpdater m_T_updater; + mutable PropertyUpdater m_C_updater; + + + private: + + }; + +} + +#endif + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Cantera/src/StoichManager.h b/Cantera/src/StoichManager.h new file mode 100755 index 000000000..8371f0d20 --- /dev/null +++ b/Cantera/src/StoichManager.h @@ -0,0 +1,447 @@ +/** + * @file StoichManager.h + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_STOICH_MGR_H +#define CT_STOICH_MGR_H + +#include +#include +using namespace std; + +#include "stringUtils.h" + +namespace Cantera { + + /** + * @defgroup Stoichiometry Stoichiometry + * Operations on reactions that require knowing the reaction + * stoichiometry. This module consists of class StoichManager, and + * classes C1, C2, and C3. Classes C1, C2, and C3 handle operations + * involving one, two, or three species, respectively, in a + * reaction. Instances are instantiated with a reaction number, and n + * species numbers (n = 1 for C1, etc.). All three classes have the + * same interface. + * + * These classes are designed for use by StoichManager, and the + * operations implemented are those needed to efficiently compute + * quantities such as rates of progress, species production rates, + * reaction thermochemistry, etc. The compiler will inline these + * methods into the body of the corresponding StoichManager method, + * and so there is no performance penalty (unless inlining is turned + * off). + * + * To describe the methods, consider class C3 and suppose an instance + * is created with reaction number irxn and species numbers k0, k1, + * and k2. + * + * - multiply(in, out) : out[irxn] is multiplied by + * in[k0] * in[k1] * in[k2] + * + * - incrementReaction(in, out) : out[irxn] is incremented by + * in[k0] + in[k1] + in[k2] + * + * - decrementReaction(in, out) : out[irxn] is decremented by + * in[k0] + in[k1] + in[k2] + * + * - incrementSpecies(in, out) : out[k0], out[k1], and out[k2] + * are all incremented by in[irxn] + * + * - decrementSpecies(in, out) : out[k0], out[k1], and out[k2] + * are all decremented by in[irxn] + * + * + */ + + + /** + * Handles one molecule in a reaction. + * @ingroup Stoichiometry + * @internal + */ + class C1 { + + public: + + C1( int rxn = 0, int ic0 = 0, doublereal order = 1.0 ) + : m_rxn (rxn), m_ic0 (ic0), m_order(order) {} + + int data(vector& ic) { + ic.resize(3); + ic[0] = m_ic0; + return m_rxn; + } + + void multiply(const doublereal* input, doublereal* output) const { + *(output + m_rxn) *= *(input + m_ic0); + } + void power(const doublereal* input, doublereal* output) const { + output[m_rxn] *= pow(input[m_ic0], m_order); + } + void incrementSpecies(const doublereal* input, + doublereal* output) const { + *(output + m_ic0) += *(input + m_rxn); + } + void decrementSpecies(const doublereal* input, + doublereal* output) const { + *(output + m_ic0) -= *(input + m_rxn); + } + void incrementReaction(const doublereal* input, + doublereal* output) const { + *(output + m_rxn) += *(input + m_ic0); + } + void decrementReaction(const doublereal* input, + doublereal* output) const { + *(output + m_rxn) -= *(input + m_ic0); + } + private: + int m_rxn, m_ic0; + doublereal m_order; + }; + + + + /** + * Handles two species in a reaction. + * @ingroup Stoichiometry + */ + class C2 { + public: + C2( int rxn = 0, int ic0 = 0, int ic1 = 0, + doublereal order0 = 1.0, doublereal order1 = 1.0 ) + : m_rxn (rxn), m_ic0 (ic0), m_ic1 (ic1), + m_order0(order0), m_order1(order1) {} + + int data(vector& ic) { + ic.resize(2); + ic[0] = m_ic0; + ic[1] = m_ic1; + return m_rxn; + } + + void multiply(const doublereal* input, doublereal* output) const { + output[m_rxn] *= input[m_ic0] * input[m_ic1]; + } + void power(const doublereal* input, doublereal* output) const { + output[m_rxn] *= pow(input[m_ic0],m_order0) * + pow(input[m_ic1],m_order1); + } + void incrementSpecies(const doublereal* input, + doublereal* output) const { + doublereal x = input[m_rxn]; + output[m_ic0] += x; + output[m_ic1] += x; + } + void decrementSpecies(const doublereal* input, + doublereal* output) const { + doublereal x = input[m_rxn]; + output[m_ic0] -= x; + output[m_ic1] -= x; + } + void incrementReaction(const doublereal* input, + doublereal* output) const { + *(output + m_rxn) += *(input + m_ic0) + *(input + m_ic1); + } + void decrementReaction(const doublereal* input, + doublereal* output) const { + *(output + m_rxn) -= (*(input + m_ic0) + *(input + m_ic1)); + } + private: + int m_rxn, m_ic0, m_ic1; + doublereal m_order0, m_order1; + }; + + + /** + * Handles three species in a reaction. + * @ingroup Stoichiometry + */ + class C3 { + public: + C3( int rxn = 0, int ic0 = 0, int ic1 = 0, int ic2 = 0, + doublereal order0 = 1.0, doublereal order1 = 1.0, + doublereal order2 = 1.0) + : m_rxn (rxn), m_ic0 (ic0), m_ic1 (ic1), m_ic2 (ic2), + m_order0(order0), m_order1(order1), m_order2(order2) {} + + int data(vector& ic) { + ic.resize(3); + ic[0] = m_ic0; + ic[1] = m_ic1; + ic[2] = m_ic2; + return m_rxn; + } + + void multiply(const doublereal* input, doublereal* output) const { + *(output + m_rxn) *= (*(input + m_ic0)) * (*(input + m_ic1)) + * (*(input + m_ic2)); + } + void power(const doublereal* input, doublereal* output) const { + output[m_rxn] *= pow(input[m_ic0],m_order0) * + pow(input[m_ic1],m_order1) * + pow(input[m_ic2],m_order2); + } + void incrementSpecies(const doublereal* input, + doublereal* output) const { + doublereal x = *(input + m_rxn); + *(output + m_ic0) += x; + *(output + m_ic1) += x; + *(output + m_ic2) += x; + } + void decrementSpecies(const doublereal* input, + doublereal* output) const { + doublereal x = *(input + m_rxn); + *(output + m_ic0) -= x; + *(output + m_ic1) -= x; + *(output + m_ic2) -= x; + } + void incrementReaction(const doublereal* input, + doublereal* output) const { + *(output + m_rxn) += *(input + m_ic0) + *(input + m_ic1) + + *(input + m_ic2); + } + void decrementReaction(const doublereal* input, + doublereal* output) const { + *(output + m_rxn) -= (*(input + m_ic0) + *(input + m_ic1) + + *(input + m_ic2)); + } + private: + int m_rxn, m_ic0, m_ic1, m_ic2; + doublereal m_order0, m_order1, m_order2; + }; + + /** + * Handles any number of species in a reaction. + * @ingroup Stoichiometry + */ + class C_AnyN { + public: + C_AnyN() : m_rxn (-1) {} + + C_AnyN( int rxn, const vector_int& ic, const vector_fp& order) + : m_rxn (rxn) { + m_n = ic.size(); + m_ic.resize(m_n); + m_order.resize(m_n); + for (int n = 0; n < m_n; n++) { + m_ic[n] = ic[n]; + m_order[n] = order[n]; + } + } + + int data(vector& ic) { + ic.resize(m_n); + int n; + for (n = 0; n < m_n; n++) ic[n] = m_ic[n]; + return m_rxn; + } + + void power(const doublereal* input, doublereal* output) const { + for (int n = 0; n < m_n; n++) output[m_rxn] + *= pow(input[m_ic[n]],m_order[n]); + } + + void multiply(const doublereal* input, doublereal* output) const { + for (int n = 0; n < m_n; n++) output[m_rxn] *= input[m_ic[n]]; + } + + void incrementSpecies(const doublereal* input, + doublereal* output) const { + doublereal x = input[m_rxn]; + for (int n = 0; n < m_n; n++) output[m_ic[n]] += x; + } + void decrementSpecies(const doublereal* input, + doublereal* output) const { + doublereal x = input[m_rxn]; + for (int n = 0; n < m_n; n++) output[m_ic[n]] -= x; + } + void incrementReaction(const doublereal* input, + doublereal* output) const { + for (int n = 0; n < m_n; n++) output[m_rxn] += input[m_ic[n]]; + } + void decrementReaction(const doublereal* input, + doublereal* output) const { + for (int n = 0; n < m_n; n++) output[m_rxn] -= input[m_ic[n]]; + } + private: + int m_n, m_rxn, m_ic0, m_ic1, m_ic2; + vector_int m_ic; + vector_fp m_order; + }; + + + template + inline static void _multiply(_InputIter __begin, _InputIter __end, + const Vec1& input, Vec2& output) { + for (; __begin != __end; ++__begin) + __begin->multiply(input, output); + } + template + inline static void _power(_InputIter __begin, _InputIter __end, + const Vec1& input, Vec2& output) { + for (; __begin != __end; ++__begin) + __begin->power(input, output); + } + template + inline static void _incrementSpecies(_InputIter __begin, + _InputIter __end, const Vec1& input, Vec2& output) { + for (; __begin != __end; ++__begin) + __begin->incrementSpecies(input, output); + } + template + inline static void _decrementSpecies(_InputIter __begin, + _InputIter __end, const Vec1& input, Vec2& output) { + for (; __begin != __end; ++__begin) + __begin->decrementSpecies(input, output); + } + template + inline static void _incrementReactions(_InputIter __begin, + _InputIter __end, const Vec1& input, Vec2& output) { + for (; __begin != __end; ++__begin) + __begin->incrementReaction(input, output); + } + template + inline static void _decrementReactions(_InputIter __begin, + _InputIter __end, const Vec1& input, Vec2& output) { + for (; __begin != __end; ++__begin) + __begin->decrementReaction(input, output); + } + + + class StoichManagerN { + public: + + StoichManagerN() {} + + void add(int rxn, const vector_int& k) { + vector_fp order(k.size(), 1.0); + add(rxn, k, order); + } + + void add(int rxn, const vector_int& k, const vector_fp& order) { + m_n[rxn] = k.size(); + switch (k.size()) { + case 1: + m_loc[rxn] = m_c1_list.size(); + m_c1_list.push_back(C1(rxn, k[0], order[0])); + break; + case 2: + m_loc[rxn] = m_c2_list.size(); + m_c2_list.push_back(C2(rxn, k[0], k[1], order[0], order[1])); + break; + case 3: + m_loc[rxn] = m_c3_list.size(); + m_c3_list.push_back(C3(rxn, k[0], k[1], k[2], + order[0], order[1], order[2])); + break; + default: + m_loc[rxn] = m_cn_list.size(); + m_cn_list.push_back(C_AnyN(rxn, k, order)); + } + } + + void multiply(const doublereal* input, doublereal* output) const { + _multiply(m_c1_list.begin(), m_c1_list.end(), input, output); + _multiply(m_c2_list.begin(), m_c2_list.end(), input, output); + _multiply(m_c3_list.begin(), m_c3_list.end(), input, output); + _multiply(m_cn_list.begin(), m_cn_list.end(), input, output); + } + + void power(const doublereal* input, doublereal* output) const { + _power(m_c1_list.begin(), m_c1_list.end(), input, output); + _power(m_c2_list.begin(), m_c2_list.end(), input, output); + _power(m_c3_list.begin(), m_c3_list.end(), input, output); + _power(m_cn_list.begin(), m_cn_list.end(), input, output); + } + + void incrementSpecies(const doublereal* input, doublereal* output) const { + _incrementSpecies(m_c1_list.begin(), m_c1_list.end(), input, output); + _incrementSpecies(m_c2_list.begin(), m_c2_list.end(), input, output); + _incrementSpecies(m_c3_list.begin(), m_c3_list.end(), input, output); + _incrementSpecies(m_cn_list.begin(), m_cn_list.end(), input, output); + } + + void decrementSpecies(const doublereal* input, doublereal* output) const { + _decrementSpecies(m_c1_list.begin(), m_c1_list.end(), input, output); + _decrementSpecies(m_c2_list.begin(), m_c2_list.end(), input, output); + _decrementSpecies(m_c3_list.begin(), m_c3_list.end(), input, output); + _decrementSpecies(m_cn_list.begin(), m_cn_list.end(), input, output); + } + + void incrementReactions(const doublereal* input, doublereal* output) const { + _incrementReactions(m_c1_list.begin(), m_c1_list.end(), input, output); + _incrementReactions(m_c2_list.begin(), m_c2_list.end(), input, output); + _incrementReactions(m_c3_list.begin(), m_c3_list.end(), input, output); + _incrementReactions(m_cn_list.begin(), m_cn_list.end(), input, output); + } + + void decrementReactions(const doublereal* input, doublereal* output) const { + _decrementReactions(m_c1_list.begin(), m_c1_list.end(), input, output); + _decrementReactions(m_c2_list.begin(), m_c2_list.end(), input, output); + _decrementReactions(m_c3_list.begin(), m_c3_list.end(), input, output); + _decrementReactions(m_cn_list.begin(), m_cn_list.end(), input, output); + } + + private: + + vector m_c1_list; + vector m_c2_list; + vector m_c3_list; + vector m_cn_list; + map m_n; + map m_loc; + }; + + + + + class StoichWriter { + public: + + StoichWriter() {} + + void add(int rxn, const vector_int& k) { + int n, nn = k.size(); + for (n = 0; n < nn; n++) { + if (m_mult[rxn] != "") m_mult[rxn] += " * "; + m_mult[rxn] += "c[" + int2str(k[n]) + "]"; + m_is[k[n]] += " + rop[" + int2str(rxn) + "]"; + m_ds[k[n]] += " - rop[" + int2str(rxn) + "]"; + m_ir[rxn] += " + grt[" + int2str(k[n]) + "]"; + m_dr[rxn] += " - grt[" + int2str(k[n]) + "]"; + } + } + + void writeIncSpec(ostream& s, int nsp) { + int k; + for (k = 0; k < nsp; k++) { + s << "out[" << k << "] = " << m_is[k] << ";" << endl; + } + } + + string mult(int rxn) { return m_mult[rxn]; } + string incrSpec(int k) { return m_is[k]; } + string decrSpec(int k) { return m_ds[k]; } + string incrRxn(int rxn) { return m_ir[rxn]; } + string decrRxn(int rxn) { return m_dr[rxn]; } + + private: + map m_mult, m_ir, m_dr, m_is, m_ds; + }; + } + +#endif + + + + + + + diff --git a/Cantera/src/Surf1D.h b/Cantera/src/Surf1D.h new file mode 100755 index 000000000..a2feb1400 --- /dev/null +++ b/Cantera/src/Surf1D.h @@ -0,0 +1,310 @@ +dep + +#ifndef CT_SURF1D_H +#define CT_SURF1D_H + +#include "Resid1D.h" +#include "SurfPhase.h" +#include "InterfaceKinetics.h" +#include "StFlow.h" +#include "OneDim.h" +#include "ctml.h" + +namespace Cantera { + + // A class for surface domains in one-dimensional simulations, The + // surface is zero-dimensional, and defined by a set of surface + // species coverages. + + class Surf1D : public Resid1D { + + public: + + Surf1D(InterfaceKinetics* skin = 0) : Resid1D(1, 1, 0.0) { + m_type = cSurfType; + m_flow_left = 0; + m_flow_right = 0; + m_kin = 0; + m_sphase = 0; + if (skin) setKinetics(skin); + } + virtual ~Surf1D(){} + + // Set the kinetics manager for the surface. + void setKinetics(InterfaceKinetics* kin) { + m_kin = kin; + int np = kin->nPhases(); + m_sphase = 0; + for (int n = 0; n < np; n++) { + if (kin->phase(n).eosType() == cSurf) { + m_sphase = (SurfPhase*)&m_kin->phase(n); + m_nsurf = n; + } + else { + m_bulk.push_back(&kin->phase(n)); + m_nbulk.push_back(n); + } + } + if (!m_sphase) + throw CanteraError("setKinetics","no surface phase defined"); + + m_nsp = m_sphase->nSpecies(); + resize(m_nsp,1); + if (m_bulk.size() == 1) { + m_bulk.push_back(0); + } + } + + void fixSpecies(int k, doublereal c) { + if (c >= 0.0) m_fixed_cov[k] = c; + m_do_surf_species[k] = false; + needJacUpdate(); + } + + void solveSpecies(int k) { + m_do_surf_species[k] = true; + needJacUpdate(); + } + + /// Set the surface temperature + void setTemperature(doublereal t) { + m_sphase->setTemperature(t); + needJacUpdate(); + } + + /// Temperature [K]. + doublereal temperature() { + return m_sphase->temperature(); + } + + void setCoverages(doublereal* c) { + m_sphase->setCoverages(c); + copy(c, c + m_nsp, m_fixed_cov.begin()); + } + + void setMultiplier(int k, doublereal f) { + m_mult[k] = f; + needJacUpdate(); + } + + doublereal multiplier(int k) { return m_mult[k]; } + + virtual string componentName(int n) const { + return m_sphase->speciesName(n); + } + + virtual void init() { + if (m_index < 0) { + throw CanteraError("Surf1D", + "install in container before calling init."); + } + m_nsp = m_sphase->nSpecies(); + resize(m_nsp,1); + m_mult.resize(m_nsp, 1.0); + m_do_surf_species.resize(m_nsp, true); + m_fixed_cov.resize(m_nsp, 1.0/m_nsp); + + // set bounds + vector_fp lower(m_nsp, -1.e-3); + vector_fp upper(m_nsp, 1.0); + setBounds(m_nsp, lower.begin(), m_nsp, upper.begin()); + + // set tolerances + vector_fp rtol(m_nsp, 1e-4); + vector_fp atol(m_nsp, 1.e-10); + setTolerances(m_nsp, rtol.begin(), m_nsp, atol.begin()); + + m_left_nsp = 0; + m_right_nsp = 0; + + // check for left and right flow objects + if (m_index > 0) { + Resid1D& r = container().domain(m_index-1); + if (r.domainType() == cFlowType) { + m_flow_left = (StFlow*)&r; + m_left_nv = m_flow_left->nComponents(); + m_left_points = m_flow_left->nPoints(); + m_left_loc = container().start(m_index-1); + m_left_nsp = m_left_nv - 4; + m_phase_left = &m_flow_left->phase(); + m_molwt_left = m_phase_left->molecularWeights().begin(); + if (m_phase_left == m_bulk[0]) + m_start_left = m_kin->start(m_nbulk[0]); + else if (m_phase_left == m_bulk[1]) + m_start_left = m_kin->start(m_nbulk[1]); + else + throw CanteraError("Surf1D::init", + "left gas does not match one in surface mechanism"); + } + else + throw CanteraError("Surf1D::init", + "Surface domains can only be " + "connected to flow domains."); + } + + if (m_index < container().nDomains() - 1) { + Resid1D& r = container().domain(m_index+1); + if (r.domainType() == cFlowType) { + m_flow_right = (StFlow*)&r; + m_right_nv = m_flow_right->nComponents(); + m_right_loc = container().start(m_index+1); + m_right_nsp = m_right_nv - 4; + m_phase_right = &m_flow_right->phase(); + m_molwt_right = m_phase_right->molecularWeights().begin(); + if (m_phase_right == m_bulk[0]) + m_start_right = m_kin->start(m_nbulk[0]); + else if (m_phase_right == m_bulk[1]) + m_start_right = m_kin->start(m_nbulk[1]); + else + throw CanteraError("Surf1D::init", + "right gas does not match one in surface mechanism"); + } + else + throw CanteraError("Surf1D::init", + "Surface domains can only be " + "connected to flow domains."); + } + m_work.resize(m_kin->nSpecies()); + } + + + virtual void eval(int jg, doublereal* xg, doublereal* rg, + integer* diagg, doublereal rdt) { + int k; + + if (jg >= 0 && (jg < firstPoint() - 2 + || jg > lastPoint() + 2)) return; + + // start of local part of global arrays + doublereal* x = xg + loc(); + doublereal* r = rg + loc(); + integer* diag = diagg + loc(); + + // set the coverages + doublereal sum = 0.0; + for (k = 0; k < m_nsp; k++) { + m_work[k] = x[k]; + sum += x[k]; + } + m_sphase->setCoverages(m_work.begin()); + + // set the left gas state to the adjacent point + + int leftloc = 0, rightloc = 0; + int pnt = 0; + + if (m_flow_left) { + leftloc = m_flow_left->loc(); + pnt = m_flow_left->nPoints() - 1; + m_flow_left->setGas(xg + leftloc, pnt); + } + + if (m_flow_right) { + rightloc = m_flow_right->loc(); + m_flow_right->setGas(xg + rightloc, 0); + } + + m_kin->getNetProductionRates(m_work.begin()); + doublereal rs0 = 1.0/m_sphase->siteDensity(); + + scale(m_work.begin(), m_work.end(), m_work.begin(), m_mult[0]); + + bool enabled = true; + int ioffset = m_kin->start(m_nsurf); // m_left_nsp + m_right_nsp; + doublereal maxx = -1.0; + int imx = -1; + for (k = 0; k < m_nsp; k++) { + r[k] = m_work[k + ioffset] * m_sphase->size(k) * rs0; + r[k] -= rdt*(x[k] - prevSoln(k,0)); + diag[k] = 1; + if (x[k] > maxx) { + maxx = x[k]; + imx = k; + } + if (!m_do_surf_species[k]) { + r[k] = x[k] - m_fixed_cov[k]; + diag[k] = 0; + enabled = false; + } + } + if (enabled) { + r[imx] = 1.0 - sum; + diag[imx] = 0; + } + + // gas-phase residuals + doublereal rho; + if (m_flow_left) { + rho = m_phase_left->density(); + doublereal rdz = 2.0/ + (m_flow_left->z(m_left_points-1) - + m_flow_left->z(m_left_points - 2)); + + for (k = 0; k < m_left_nsp; k++) + m_work[k + m_start_left] *= m_molwt_left[k]; + + int ileft = loc() - m_left_nv; + + // if the energy equation is enabled at this point, + // set the gas temperature to the surface temperature + if (m_flow_left->doEnergy(pnt)) { + rg[ileft + 2] = xg[ileft + 2] - m_sphase->temperature(); + } + + for (k = 1; k < m_left_nsp; k++) { + if (enabled && m_flow_left->doSpecies(k)) { + rg[ileft + 4 + k] += m_work[k + m_start_left]; +//+= rdz*m_work[k + m_sp_left]/rho; + + } + } + } + + if (m_flow_right) { + for (k = 0; k < m_right_nsp; k++) + m_work[k + m_start_right] *= m_molwt_right[k]; + + int iright = loc() + m_nsp; + rg[iright + 2] -= m_sphase->temperature(); + //r[iright + 3] = x[iright]; + for (k = 0; k < m_right_nsp; k++) { + rg[iright + 4 + k] -= m_work[k + m_start_right]; + } + } + } + + virtual void save(XML_Node& o, doublereal* soln) { + doublereal* s = soln + loc(); + XML_Node& surf = o.addChild("surface"); + for (int k = 0; k < m_nsp; k++) { + ctml::addFloat(surf, componentName(k), s[k], "", "coverage", + 0.0, 1.0); + } + } + + + protected: + + InterfaceKinetics* m_kin; + SurfPhase* m_sphase; + StFlow *m_flow_left, *m_flow_right; + int m_left_nv, m_right_nv; + int m_left_loc, m_right_loc; + int m_left_points; + int m_nsp, m_left_nsp, m_right_nsp; + vector_fp m_work; + const doublereal *m_molwt_right, *m_molwt_left; + int m_sp_left, m_sp_right; + int m_start_left, m_start_right, m_start_surf; + ThermoPhase *m_phase_left, *m_phase_right; + vector m_bulk; + vector m_nbulk; + int m_nsurf; + vector_fp m_mult; + vector m_do_surf_species; + vector_fp m_fixed_cov; + }; + +} + +#endif diff --git a/Cantera/src/SurfPhase.h b/Cantera/src/SurfPhase.h new file mode 100644 index 000000000..fd29a7681 --- /dev/null +++ b/Cantera/src/SurfPhase.h @@ -0,0 +1,83 @@ +/** + * + * @file SurfPhase.h + * + */ + +/* $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2002 California Institute of Technology + * + */ + + +#ifndef CT_SURFPHASE_H +#define CT_SURFPHASE_H + +#include "ct_defs.h" +#include "mix_defs.h" +#include "ThermoPhase.h" +#include "ctvector.h" +#include + +namespace Cantera { + + + /** + * A simple model for a surface phase. The surface consists of a + * grid of equivalent sites. Surface species may be defined that + * occupy one or more sites. The surface species are assumed to be + * independent, and thus the species form an ideal solution. + */ + class SurfPhase : public ThermoPhase { + + public: + + SurfPhase(doublereal n0 = 0.0); + virtual ~SurfPhase() {} + virtual int eosType() const { return cSurf; } + virtual doublereal enthalpy_mole() const; + virtual doublereal intEnergy_mole() const; + virtual void getStandardChemPotentials(doublereal* mu0) const; + virtual void getActivityConcentrations(doublereal* c) const; + virtual doublereal standardConcentration(int k = 0) const; + virtual doublereal logStandardConc(int k=0) const; + virtual void setParameters(int n, doublereal* c); + virtual void initThermo(); + doublereal siteDensity(){ return m_n0; } + void setPotentialEnergy(int k, doublereal pe); + doublereal potentialEnergy(int k) {return m_pe[k];} + void setSiteDensity(doublereal n0); + void setElectricPotential(doublereal V); + void setCoverages(const doublereal* theta); + void getCoverages(doublereal* theta); + + protected: + + doublereal m_n0, m_logn0; + doublereal m_tmin, m_tmax; + + mutable doublereal m_tlast; + mutable array_fp m_h0; + mutable array_fp m_s0; + mutable array_fp m_cp0; + mutable array_fp m_mu0; + mutable array_fp m_work; + mutable array_fp m_pe; + mutable array_fp m_logsize; + + private: + + void _updateThermo(bool force=false) const; + + }; +} + +#endif + + + + + diff --git a/Cantera/src/Thermo.h b/Cantera/src/Thermo.h new file mode 100755 index 000000000..d72a3a939 --- /dev/null +++ b/Cantera/src/Thermo.h @@ -0,0 +1,444 @@ + + +/** + * + * @file Thermo.h + */ + +/* + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2001 California Institute of Technology + * + */ + +#ifndef CT_THERMO_H +#define CT_THERMO_H + +#include "ThermoPhase.h" + +// #include "ct_defs.h" +// #include "mix_defs.h" +// #include "Phase.h" + +// #include "ctml.h" +// using namespace ctml; + + +// namespace Cantera { + +// /** +// * Exception thrown if a method of class Thermo is called. The +// * methods of Thermo should be overloaded to implement a +// * particular thermo manager. But a given manager may not overload +// * every method. If an unimplemented virtual method is called, the +// * base class method will throw an exception. +// */ +// class ThermoNotImplemented : public CanteraError { +// public: +// ThermoNotImplemented(string method) : CanteraError("Thermo", +// "**** Method "+method+" not implemented. ****\n") {} +// }; + + +// /** +// * Base class for thermodynamic property managers. +// */ +// class Thermo { + +// public: + +// Thermo(phase_t* phase=0, SpeciesThermo* sptherm = 0) { +// if (phase == 0) m_s = new Phase(); +// m_s = phase; +// m_spthermo = sptherm; +// m_xml = new XML_Node("thermo"); +// m_index = -1; +// } + +// virtual ~Thermo() {} + +// int index() { return m_index; } +// void setIndex(int m) { m_index = m; } + +// XML_Node& xml() { return *m_xml; } + +// /** +// * Initialize. @param s Object defining the composition and +// * species properties of the phase that thermodynamic +// * properties will be computed for. +// */ +// virtual void initThermo(Phase& s) { +// m_s = &s; +// } + + +// /** Return a reference to the phase object. */ +// phase_t& phase() { return *m_s; } + + +// /** Return a read-only reference to the phase object. */ +// const phase_t& phase() const { return *m_s; } + + +// /** +// * Equation of state type. The base class returns +// * zero. Subclasses should define this to return a non-zero +// * value. +// */ +// virtual int eosType() const { return 0; } + +// /** +// * @name Virtual Methods +// * +// * The methods in this section should be overloaded by subclasses. +// * The base class methods throw an exception. +// */ + +// //@{ + +// /** +// * Molar enthalpy. Units: J/kmol. +// */ +// virtual doublereal enthalpy_mole() const { +// return err("enthalpy_mole"); +// } + +// /** +// * Molar internal energy. Units: J/kmol. +// */ +// virtual doublereal intEnergy_mole() const { +// return err("intEnergy_mole"); +// } + +// /** +// * Molar entropy. Units: J/kmol/K. +// */ +// virtual doublereal entropy_mole() const { +// return err("entropy_mole"); +// } + +// /** +// * Molar Gibbs function. Units: J/kmol. +// */ +// virtual doublereal gibbs_mole() const { +// return err("gibbs_mole"); +// } + +// /** +// * Molar heat capacity at constant pressure. Units: J/kmol/K. +// */ +// virtual doublereal cp_mole() const { +// return err("cp_mole"); +// } + +// /** +// * Molar heat capacity at constant volume. Units: J/kmol/K. +// */ +// virtual doublereal cv_mole() const { +// return err("cv_mole"); +// } + +// /** +// * Pressure. Units: Pa. +// */ +// virtual doublereal pressure() const { +// return err("pressure"); +// } + +// /** +// * Set the pressure. Units: Pa. +// */ +// virtual void setPressure(doublereal p) { +// err("setPressure"); +// } + + +// /** +// * Get the species chemical potentials. Units: J/kmol. +// */ +// virtual void getChemPotentials(doublereal* mu) const { +// err("getChemPotentials_RT"); +// } + +// virtual void getChemPotentials_RT(doublereal* mu) const { +// err("getChemPotentials_RT"); +// } + +// /** +// * Get the species partial molar enthalpies. Units: J/kmol. +// */ +// virtual void getPartialMolarEnthalpies(doublereal* hbar) const { +// err("getPartialMolarEnthalpies"); +// } + +// /** +// * Get the species partial molar entropies. Units: J/kmol. +// */ +// virtual void getPartialMolarEntropies(doublereal* sbar) const { +// err("getPartialMolarEntropies"); +// } + +// /** +// * Get the species partial molar enthalpies. Units: J/kmol. +// */ +// virtual void getPartialMolarVolumes(doublereal* vbar) const { +// err("getPartialMolarVolumes"); +// } + +// /** +// * Get the nondimensional Gibbs functions for the pure species +// * at the current T and P. +// */ +// virtual void getEnthalpy_RT(doublereal* hrt) const { +// err("getEnthalpy_RT"); +// } + + +// /** +// * Get the nondimensional Gibbs functions for the pure species +// * at the current T and P. +// */ +// virtual void getEntropy_R(doublereal* sr) const { +// err("getEntropy_R"); +// } + +// /** +// * Get the nondimensional Gibbs functions for the pure species +// * at the current T and P. +// */ +// virtual void getGibbs_RT(doublereal* grt) const { +// err("getGibbs_RT"); +// } + +// virtual void getPureGibbs(doublereal* gpure) const { +// err("getPureGibbs"); +// } + +// /** +// * Get the nondimensional Gibbs functions for the pure species +// * at the current T and P. +// */ +// virtual void getCp_R(doublereal* cpr) const { +// err("getCp_RT"); +// } + +// //@} + +// virtual doublereal refPressure() const { +// err("refPressure"); +// return 0.0; +// } + +// virtual doublereal minTemp(int k = -1) { +// err("minTemp"); +// return 0.0; +// } + +// virtual doublereal maxTemp(int k = -1) { +// err("maxTemp"); +// return 0.0; +// } + +// /** +// * Specific enthalpy. Units: J/kg. +// */ +// doublereal enthalpy_mass() const { +// return enthalpy_mole()/m_s->meanMolecularWeight(); +// } + +// /** +// * Specific internal energy. Units: J/kg. +// */ +// doublereal intEnergy_mass() const { +// return intEnergy_mole()/m_s->meanMolecularWeight(); +// } + +// /** +// * Specific entropy. Units: J/kg/K. +// */ +// doublereal entropy_mass() const { +// return entropy_mole()/m_s->meanMolecularWeight(); +// } + +// /** +// * Specific Gibbs function. Units: J/kg. +// */ +// doublereal gibbs_mass() const { +// return gibbs_mole()/m_s->meanMolecularWeight(); +// } + +// /** +// * Specific heat at constant pressure. Units: J/kg/K. +// */ +// doublereal cp_mass() const { +// return cp_mole()/m_s->meanMolecularWeight(); +// } + +// /** +// * Specific heat at constant volume. Units: J/kg/K. +// */ +// doublereal cv_mass() const { +// return cv_mole()/m_s->meanMolecularWeight(); +// } + +// doublereal _temp() const { +// return m_s->temperature(); +// } + +// doublereal _dens() const { +// return m_s->density(); +// } + +// doublereal _RT() const { +// return m_s->temperature() * GasConstant; +// } + +// /** Set the temperature (K), pressure (Pa), and mole fractions. */ +// void setState_TPX(doublereal t, doublereal p, const doublereal* x) { +// m_s->setMoleFractions(x); m_s->setTemperature(t); setPressure(p); +// } + +// /** Set the temperature (K), pressure (Pa), and mole fractions. */ +// void setState_TPX(doublereal t, doublereal p, compositionMap& x) { +// m_s->setMoleFractionsByName(x); m_s->setTemperature(t); setPressure(p); +// } + +// /** Set the temperature (K), pressure (Pa), and mole fractions. */ +// void setState_TPX(doublereal t, doublereal p, const string& x) { +// compositionMap xx; +// parseCompString(x, xx); +// m_s->setMoleFractionsByName(xx); m_s->setTemperature(t); setPressure(p); +// } + +// /** Set the temperature (K), pressure (Pa), and mass fractions. */ +// void setState_TPY(doublereal t, doublereal p, const doublereal* y) { +// m_s->setMassFractions(y); m_s->setTemperature(t); setPressure(p); +// } + +// /** Set the temperature (K), pressure (Pa), and mass fractions. */ +// void setState_TPY(doublereal t, doublereal p, compositionMap& y) { +// m_s->setMassFractionsByName(y); m_s->setTemperature(t); setPressure(p); +// } + +// /** Set the temperature (K), pressure (Pa), and mass fractions. */ +// void setState_TPY(doublereal t, doublereal p, const string& y) { +// compositionMap yy; +// parseCompString(y, yy); +// m_s->setMassFractionsByName(yy); m_s->setTemperature(t); setPressure(p); +// } + +// /** Set the temperature (K) and pressure (Pa) */ +// void setState_TP(doublereal t, doublereal p) { +// m_s->setTemperature(t); setPressure(p); +// } + +// /** Set the pressure (Pa) and mole fractions. */ +// void setState_PX(doublereal p, doublereal* x) { +// m_s->setMoleFractions(x); setPressure(p); +// } + +// /** Set the pressure (Pa) and mass fractions. */ +// void setState_PY(doublereal p, doublereal* y) { +// m_s->setMassFractions(y); setPressure(p); +// } + +// void setState_HP(doublereal h, doublereal p, doublereal tol = 1.e-8) { +// doublereal dt; +// setPressure(p); +// for (int n = 0; n < 20; n++) { +// dt = (h - enthalpy_mass())/cp_mass(); +// if (dt > 100.0) dt = 100.0; +// else if (dt < -100.0) dt = -100.0; +// setState_TP(_temp() + dt, p); +// if (fabs(dt) < tol) { +// return; +// } +// } +// throw CanteraError("setState_HP","no convergence. dt = " + fp2str(dt)); +// } + +// void setState_UV(doublereal u, doublereal v, doublereal tol = 1.e-8) { +// doublereal dt; +// m_s->setDensity(1.0/v); +// for (int n = 0; n < 20; n++) { +// dt = (u - intEnergy_mass())/cv_mass(); +// if (dt > 100.0) dt = 100.0; +// else if (dt < -100.0) dt = -100.0; +// m_s->setTemperature(_temp() + dt); +// if (fabs(dt) < tol) { +// return; +// } +// } +// throw CanteraError("setState_UV","no convergence. dt = " + fp2str(dt)); +// } + +// void setState_SP(doublereal s, doublereal p, doublereal tol = 1.e-8) { +// doublereal dt; +// setPressure(p); +// for (int n = 0; n < 20; n++) { +// dt = (s - entropy_mass())*_temp()/cp_mass(); +// if (dt > 100.0) dt = 100.0; +// else if (dt < -100.0) dt = -100.0; +// setState_TP(_temp() + dt, p); +// if (fabs(dt) < tol) { +// return; +// } +// } +// throw CanteraError("setState_SP","no convergence. dt = " + fp2str(dt)); +// } + +// void setState_SV(doublereal s, doublereal v, doublereal tol = 1.e-8) { +// doublereal dt; +// m_s->setDensity(1.0/v); +// for (int n = 0; n < 20; n++) { +// dt = (s - entropy_mass())*_temp()/cv_mass(); +// if (dt > 100.0) dt = 100.0; +// else if (dt < -100.0) dt = -100.0; +// m_s->setTemperature(_temp() + dt); +// if (fabs(dt) < tol) { +// return; +// } +// } +// throw CanteraError("setState_SV","no convergence. dt = " + fp2str(dt)); +// } + +// virtual void setToEquilState(const doublereal* lambda_RT) { +// err("setToEquilState"); +// } + +// /// Install a standard-state species thermodynamic property +// /// manager +// void setSpeciesThermo(SpeciesThermo* spthermo) +// { m_spthermo = spthermo; } + +// SpeciesThermo& speciesThermo() { return *m_spthermo; } + +// virtual void setParameters(int n, doublereal* c) {} + +// protected: + +// Phase* m_s; +// XML_Node* m_xml; +// SpeciesThermo* m_spthermo; +// int m_index; + +// private: + +// doublereal err(string msg) const { +// throw ThermoNotImplemented(msg); +// return 0; +// } +// }; + +// typedef Thermo thermo_t; +// } + +#endif + + + + + diff --git a/Cantera/src/ThermoFactory.cpp b/Cantera/src/ThermoFactory.cpp new file mode 100644 index 000000000..d13ce1bcc --- /dev/null +++ b/Cantera/src/ThermoFactory.cpp @@ -0,0 +1,130 @@ +/** + * @file ThermoFactory.cpp + */ + +/* + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifdef WIN32 +#pragma warning(disable:4786) +#endif + +#include "ThermoFactory.h" + +#include "SpeciesThermoFactory.h" +#include "IdealGasPhase.h" +#include "ConstDensityThermo.h" +#include "SurfPhase.h" +#include "importCTML.h" + +namespace Cantera { + + ThermoFactory* ThermoFactory::__factory = 0; + + static int ntypes = 3; + static string _types[] = {"IdealGas", "Incompressible", "Surface"}; + static int _itypes[] = {cIdealGas, cIncompressible, cSurf}; + + + ThermoPhase* ThermoFactory::newThermoPhase(string model) { + + int ieos=-1; + for (int n = 0; n < ntypes; n++) { + if (model == _types[n]) ieos = _itypes[n]; + } + + ThermoPhase* th=0; + map d; + switch (ieos) { + + case cIdealGas: + th = new IdealGasPhase; + break; + + case cIncompressible: + th = new ConstDensityThermo; + break; + + case cSurf: + th = new SurfPhase; + break; + + default: + throw CanteraError("newThermo", + "newThermo: unknown equation of state: "+model); + } + return th; + } + + /** + * Return a thermo manager to handle the parameterizations + * specified in a CTML phase specification. + */ + ThermoPhase* ThermoFactory::newThermo(XML_Node& root, string id) { + + // Find the node with the specified id, check that it is + // a 'phase' node, and set the phase id to 'id'. + XML_Node* ph; + ph = root.findID(id); + if (ph == 0) return 0; // false; // id not found + XML_Node& node = *ph; + + if (node.name() != "phase") + throw CanteraError("newThermo","node with id = "+id + +" is not a phase object."); + + //Phase* p = new Phase; + //p->setID(id); // set the phase id + + // get equaton of state type + XML_Node& eos = node.child("thermo"); + string eostype = eos["model"]; + int ieos=-1; + for (int n = 0; n < ntypes; n++) { + if (eostype == _types[n]) ieos = _itypes[n]; + } + + // build species thermo manager + SpeciesThermo* spthermo = newSpeciesThermoMgr(&node); + + ThermoPhase* th=0; + // doublereal dens; + map d; + switch (ieos) { + + case cIdealGas: + // Ideal gas + th = new IdealGasPhase; + break; + + case cIncompressible: + // getFloats(eos,d); + //dens = d["density"]; + th = new ConstDensityThermo; + //th->setParameters(1, &dens); + break; + + case cSurf: + //getFloats(eos,d); + //dens = d["site_density"]; + th = new SurfPhase; + //th->setParameters(1, &dens); + break; + + default: + throw CanteraError("newThermo", + "newThermo: unknown equation of state: "+eostype); + } + th->setSpeciesThermo(spthermo); + // import the phase specification + importPhase(node, th); + return th; + } + +} diff --git a/Cantera/src/ThermoFactory.h b/Cantera/src/ThermoFactory.h new file mode 100644 index 000000000..a27502d36 --- /dev/null +++ b/Cantera/src/ThermoFactory.h @@ -0,0 +1,80 @@ +/** + * @file ThermoFactory.h + */ + +/* + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef THERMO_FACTORY_H +#define THERMO_FACTORY_H + +#include "ThermoPhase.h" +#include "xml.h" + +namespace Cantera { + + /** + * Factory for thermodynamic property managers. + */ + class ThermoFactory { + + public: + + static ThermoFactory* factory() { + if (!__factory) __factory = new ThermoFactory; + return __factory; + } + + virtual ~ThermoFactory() { + delete __factory; + __factory = 0; + } + + /** + * Create a new thermodynamic property manager. + * @param type the type to be created. + */ + virtual ThermoPhase* newThermo(XML_Node& node, string id); + virtual ThermoPhase* newThermoPhase(string model); + + private: + + static ThermoFactory* __factory; + ThermoFactory(){} + }; + + + /** + * Create a new thermo manager instance. + */ + inline ThermoPhase* newThermoMgr(XML_Node& root, string id, + ThermoFactory* f=0) { + if (f == 0) { + f = ThermoFactory::factory(); + } + ThermoPhase* therm = f->newThermo(root, id); + return therm; + } + + /** + * Create a new thermo manager instance. + */ + inline ThermoPhase* newThermoPhase(string model, + ThermoFactory* f=0) { + if (f == 0) { + f = ThermoFactory::factory(); + } + return f->newThermoPhase(model); + } + +} + +#endif + + diff --git a/Cantera/src/ThermoPhase.cpp b/Cantera/src/ThermoPhase.cpp new file mode 100644 index 000000000..9191f7204 --- /dev/null +++ b/Cantera/src/ThermoPhase.cpp @@ -0,0 +1,101 @@ +/** + * + * @file ThermoPhase.cpp + */ + +/* + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2002 California Institute of Technology + * + */ + +// turn off warnings under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "ThermoPhase.h" + + +namespace Cantera { + + + void ThermoPhase::setState_HP(doublereal h, doublereal p, + doublereal tol) { + doublereal dt; + setPressure(p); + for (int n = 0; n < 20; n++) { + dt = (h - enthalpy_mass())/cp_mass(); + if (dt > 100.0) dt = 100.0; + else if (dt < -100.0) dt = -100.0; + setState_TP(temperature() + dt, p); + if (fabs(dt) < tol) { + return; + } + } + throw CanteraError("setState_HP","no convergence. dt = " + fp2str(dt)); + } + + void ThermoPhase::setState_UV(doublereal u, doublereal v, + doublereal tol) { + doublereal dt; + setDensity(1.0/v); + for (int n = 0; n < 20; n++) { + dt = (u - intEnergy_mass())/cv_mass(); + if (dt > 100.0) dt = 100.0; + else if (dt < -100.0) dt = -100.0; + setTemperature(temperature() + dt); + if (fabs(dt) < tol) { + return; + } + } + throw CanteraError("setState_UV","no convergence. dt = " + fp2str(dt)); + } + + void ThermoPhase::setState_SP(doublereal s, doublereal p, + doublereal tol) { + doublereal dt; + setPressure(p); + for (int n = 0; n < 20; n++) { + dt = (s - entropy_mass())*temperature()/cp_mass(); + if (dt > 100.0) dt = 100.0; + else if (dt < -100.0) dt = -100.0; + setState_TP(temperature() + dt, p); + if (fabs(dt) < tol) { + return; + } + } + throw CanteraError("setState_SP","no convergence. dt = " + fp2str(dt)); + } + + void ThermoPhase::setState_SV(doublereal s, doublereal v, + doublereal tol) { + doublereal dt; + setDensity(1.0/v); + for (int n = 0; n < 20; n++) { + dt = (s - entropy_mass())*temperature()/cv_mass(); + if (dt > 100.0) dt = 100.0; + else if (dt < -100.0) dt = -100.0; + setTemperature(temperature() + dt); + if (fabs(dt) < tol) { + return; + } + } + throw CanteraError("setState_SV","no convergence. dt = " + fp2str(dt)); + } + + doublereal ThermoPhase::err(string msg) const { + throw CanteraError("ThermoPhase","Base class method " + +msg+" called."); + return 0; + } + +} + + + + diff --git a/Cantera/src/ThermoPhase.h b/Cantera/src/ThermoPhase.h new file mode 100755 index 000000000..46751be79 --- /dev/null +++ b/Cantera/src/ThermoPhase.h @@ -0,0 +1,601 @@ +/** + * + * @file ThermoPhase.h + * + */ + +/* + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2002 California Institute of Technology + * + */ + +#ifndef CT_THERMOPHASE_H +#define CT_THERMOPHASE_H + +#include "Phase.h" + + +namespace Cantera { + + class XML_Node; + + /** + * @defgroup thermoprops Thermodynamic Properties + * + * These classes are used to compute thermodynamic properties. + */ + + /** + * A phase with thermodynamic properties. + * Extends class Phase by adding methods that compute + * thermodynamic properties. + * + * Class ThermoPhase is the base class for the family of classes + * that represent phases of matter with particular equations of + * state. Instances of subclasses of ThermoPhase should be created + * using the factory class ThermoFactory, not by calling the + * constructor directly. + * + * To implement a new equation of state, derive a class from + * ThermoPhase and overload the virtual methods in + * ThermoPhase. Methods that are not needed can be left + * unimplimented, which will cause an exception to be thrown if it + * is called. + * @ingroup thermoprops + * @ingroup phases + */ + class ThermoPhase : public Phase { + + public: + + virtual ~ThermoPhase() { + delete m_spthermo; + delete m_speciesData; + m_spthermo = 0; + m_speciesData = 0; + } + + + /** + * + * @name Utilities + * @{ + */ + + + /** + * @internal + * Index number. This method can be used to identify the + * location of a phase object in a list, and is used by the + * interface library (clib) routines for this purpose. + */ + int index() { return m_index; } + + + /** + * @internal Set the index number. The Cantera interface + * library uses this method to set the index number to the + * location of the pointer to this object in the pointer array + * it maintains. Using this method for any other purpose will + * lead to unpredictable results if used in conjunction with + * the interface library. + */ + void setIndex(int m) { m_index = m; } + + + void saveSpeciesData(XML_Node* data) { + m_speciesData = data; + } + + XML_Node* speciesData() { return m_speciesData; } + + + /** + * @internal Initialize. This method is provided to allow + * subclasses to perform any initialization required after all + * species have been added. For example, it might be used to + * resize internal work arrays that must have an entry for + * each species. The base class implementation does nothing, + * and subclasses that do not require initialization do not + * need to overload this method. When importing a CTML phase + * description, this method is called just prior to returning + * from function importPhase. + * + * @see importCTML.cpp + */ + virtual void initThermo() {} + + + /** + * Equation of state type flag. The base class returns + * zero. Subclasses should define this to return a unique + * non-zero value. Constants defined for this purpose are + * listed in mix_defs.h. + */ + virtual int eosType() const { return 0; } + + + + /** + * @} + * @name Molar Thermodynamic Properties + * @{ + */ + + + /** + * Molar enthalpy. Units: J/kmol. + */ + virtual doublereal enthalpy_mole() const { + return err("enthalpy_mole"); + } + + + /** + * Molar internal energy. Units: J/kmol. + */ + virtual doublereal intEnergy_mole() const { + return err("intEnergy_mole"); + } + + + /** + * Molar entropy. Units: J/kmol/K. + */ + virtual doublereal entropy_mole() const { + return err("entropy_mole"); + } + + + /** + * Molar Gibbs function. Units: J/kmol. + */ + virtual doublereal gibbs_mole() const { + return err("gibbs_mole"); + } + + + /** + * Molar heat capacity at constant pressure. Units: J/kmol/K. + */ + virtual doublereal cp_mole() const { + return err("cp_mole"); + } + + + /** + * Molar heat capacity at constant volume. Units: J/kmol/K. + */ + virtual doublereal cv_mole() const { + return err("cv_mole"); + } + + /** + * @} + * @name Mechanical Properties + * @{ + */ + + /** + * Pressure. Units: Pa. + */ + virtual doublereal pressure() const { + return err("pressure"); + } + + + /** + * Set the pressure. Units: Pa. + */ + virtual void setPressure(doublereal p) { + err("setPressure"); + } + + /** + * @} + * @name Potential Energy + * + * Species may have an additional potential energy due to the + * presence of external gravitation or electric fields. These + * methods allow specifying a potential energy for individual + * species. + */ + + /** + * Set the potential energy of species k to pe. + * Units: J/kmol. + */ + virtual void setPotentialEnergy(int k, doublereal pe) { + err("setPotentialEnergy"); + } + + /** + * Get the potential energy of species k. + * Units: J/kmol. + */ + virtual doublereal potentialEnergy(int k) const { + return err("potentialEnergy"); + } + + void setElectricPotential(doublereal v) { + int nsp = nSpecies(); + for (int k = 0; k < nsp; k++) { + setPotentialEnergy(k, v*charge(k)*Faraday); + } + } + + /** + * @} + * @name Chemical Potentials and Activities + * + * The activity \f$ a_k \f$ of a species in solution is + * related to the chemical potential by \f[ \mu_k = \mu_k^0(T) + * + \hat R T \log a_k. \f] The quantity \f$\mu_k^0(T)\f$ is + * the chemical potential at unit activity, which depends only + * on temperature. @{ + */ + + /** + * This method returns an array of generalized concentrations + * \f$ C_k \f$ that are defined such that \f$ a_k = C_k / + * C^0_k, \f$ where \f$ C^0_k \f$ is a standard concentration + * defined below. These generalized concentrations are used + * by kinetics manager classes to compute the forward and + * reverse rates of elementary reactions. + */ + virtual void getActivityConcentrations(doublereal* c) const { + err("getActivityConcentrations"); + } + + /** + * The standard concentration \f$ C^0_k \f$ used to normalize + * the generalized concentration. In many cases, this quantity + * will be the same for all species in a phase - for example, + * for an ideal gas \f$ C^0_k = P^0/\hat R T \f$. For this + * reason, this method returns a single value, instead of an + * array. However, for phases in which the standard + * concentration is species-specific (e.g. surface species of + * different sizes), this method may be called with an + * optional parameter indicating the species. + */ + virtual doublereal standardConcentration(int k=0) const { + err("standardConcentration"); + return -1.0; + } + + /** The natural logarithm of the standard concentration. */ + virtual doublereal logStandardConc(int k=0) const { + err("logStandardConc"); + return -1.0; + } + + + /** Get the array of chemical potentials at unit activity \f$ + * \mu^0_k \f$. + */ + virtual void getStandardChemPotentials(doublereal* mu) const { + err("getStandardChemPotentials"); + } + + + /** + * Get the array of non-dimensional chemical potentials \f$ + * \mu_k / \hat R T \f$. + */ + virtual void getChemPotentials_RT(doublereal* mu) const { + err("getChemPotentials_RT"); + } + + /** + * Get the species chemical potentials. Units: J/kmol. + */ + virtual void getChemPotentials(doublereal* mu) const { + err("getChemPotentials_RT"); + } + + //@} + /// @name Partial Molar Properties + //@{ + + /** + * Get the species partial molar enthalpies. Units: J/kmol. + */ + virtual void getPartialMolarEnthalpies(doublereal* hbar) const { + err("getPartialMolarEnthalpies"); + } + + + /** + * Get the species partial molar entropies. Units: J/kmol. + */ + virtual void getPartialMolarEntropies(doublereal* sbar) const { + err("getPartialMolarEntropies"); + } + + + /** + * Get the species partial molar volumes. Units: m^3/kmol. + */ + virtual void getPartialMolarVolumes(doublereal* vbar) const { + err("getPartialMolarVolumes"); + } + //@} + + /** + * Get the nondimensional Gibbs functions for the pure species + * at the current T and P. + */ + virtual void getEnthalpy_RT(doublereal* hrt) const { + err("getEnthalpy_RT"); + } + + + /** + * Get the nondimensional Gibbs functions for the pure species + * at the current T and P. + */ + virtual void getEntropy_R(doublereal* sr) const { + err("getEntropy_R"); + } + + + /** + * Get the nondimensional Gibbs functions for the pure species + * at the current T and P. + */ + virtual void getGibbs_RT(doublereal* grt) const { + err("getGibbs_RT"); + } + + + virtual void getPureGibbs(doublereal* gpure) const { + err("getPureGibbs"); + } + + + /** + * Get the nondimensional Gibbs functions for the pure species + * at the current T and P. @deprecated + */ + virtual void getCp_R(doublereal* cpr) const { + err("getCp_RT"); + } + + + /////////////////////////////////////////////////////// + // + // The methods below are not virtual, and should not + // be overloaded. + // + ////////////////////////////////////////////////////// + + /** + * @name Specific Properties + * @{ + */ + + /** + * Specific enthalpy. Units: J/kg. + */ + doublereal enthalpy_mass() const { + return enthalpy_mole()/meanMolecularWeight(); + } + + /** + * Specific internal energy. Units: J/kg. + */ + doublereal intEnergy_mass() const { + return intEnergy_mole()/meanMolecularWeight(); + } + + /** + * Specific entropy. Units: J/kg/K. + */ + doublereal entropy_mass() const { + return entropy_mole()/meanMolecularWeight(); + } + + /** + * Specific Gibbs function. Units: J/kg. + */ + doublereal gibbs_mass() const { + return gibbs_mole()/meanMolecularWeight(); + } + + /** + * Specific heat at constant pressure. Units: J/kg/K. + */ + doublereal cp_mass() const { + return cp_mole()/meanMolecularWeight(); + } + + /** + * Specific heat at constant volume. Units: J/kg/K. + */ + doublereal cv_mass() const { + return cv_mole()/meanMolecularWeight(); + } + //@} + + /// @internal + doublereal _RT() const { + return temperature() * GasConstant; + } + + /** + * @name Setting the State + * + * These methods set all or part of the thermodynamic + * state. + * @{ + */ + /** Set the temperature (K), pressure (Pa), and mole fractions. */ + void setState_TPX(doublereal t, doublereal p, const doublereal* x) { + setMoleFractions(x); setTemperature(t); setPressure(p); + } + + /** Set the temperature (K), pressure (Pa), and mole fractions. */ + void setState_TPX(doublereal t, doublereal p, compositionMap& x) { + setMoleFractionsByName(x); setTemperature(t); setPressure(p); + } + + /** Set the temperature (K), pressure (Pa), and mole fractions. */ + void setState_TPX(doublereal t, doublereal p, const string& x) { + compositionMap xx; + int kk = nSpecies(); + for (int k = 0; k < kk; k++) xx[speciesName(k)] = -1.0; + parseCompString(x, xx); + setMoleFractionsByName(xx); setTemperature(t); setPressure(p); + } + + /** Set the temperature (K), pressure (Pa), and mass fractions. */ + void setState_TPY(doublereal t, doublereal p, const doublereal* y) { + setMassFractions(y); setTemperature(t); setPressure(p); + } + + /** Set the temperature (K), pressure (Pa), and mass fractions. */ + void setState_TPY(doublereal t, doublereal p, compositionMap& y) { + setMassFractionsByName(y); setTemperature(t); setPressure(p); + } + + /** Set the temperature (K), pressure (Pa), and mass fractions. */ + void setState_TPY(doublereal t, doublereal p, const string& y) { + compositionMap yy; + int kk = nSpecies(); + for (int k = 0; k < kk; k++) yy[speciesName(k)] = -1.0; + parseCompString(y, yy); + setMassFractionsByName(yy); setTemperature(t); setPressure(p); + } + + /** Set the temperature (K) and pressure (Pa) */ + void setState_TP(doublereal t, doublereal p) { + setTemperature(t); setPressure(p); + } + + /** Set the pressure (Pa) and mole fractions. */ + void setState_PX(doublereal p, doublereal* x) { + setMoleFractions(x); setPressure(p); + } + + /** Set the pressure (Pa) and mass fractions. */ + void setState_PY(doublereal p, doublereal* y) { + setMassFractions(y); setPressure(p); + } + + /** Set the specific enthalpy (J/kg) and pressure (Pa). */ + void setState_HP(doublereal h, doublereal p, doublereal tol = 1.e-8); + + /** Set the specific enthalpy (J/kg) and specific volume (m^3/kg). */ + void setState_UV(doublereal u, doublereal v, doublereal tol = 1.e-8); + + /** Set the specific entropy (J/kg/K) and pressure (Pa). */ + void setState_SP(doublereal s, doublereal p, doublereal tol = 1.e-8); + + /** Set the specific entropy (J/kg/K) and specific volume (m^3/kg). */ + void setState_SV(doublereal s, doublereal v, doublereal tol = 1.e-8); + + //@} + + /** + * @internal + * @name Chemical Equilibrium + * @{ + * + * This method is used by the ChemEquil equilibrium solver. + * It sets the state such that the chemical potentials satisfy + * \f[ \frac{\mu_k}{\hat R T} = \sum_m A_{k,m} + * \left(\frac{\lambda_m} {\hat R T}\right) \f] where \f$ + * \lambda_m \f$ is the element potential of element m. The + * temperature is unchanged. Any phase (ideal or not) that + * implements this method can be equilibrated by ChemEquil. + */ + virtual void setToEquilState(const doublereal* lambda_RT) { + err("setToEquilState"); + } + //@} + + void getActivities(doublereal* a) { + getActivityConcentrations(a); + int nsp = nSpecies(); + doublereal rc = standardConcentration(); + scale(a, a + nsp, a, rc); + } + + + /** + * @internal + * Set equation of state parameters. The number and meaning of + * these depends on the subclass. + * @param n number of parameters + * @param c array of \i n coefficients + */ + virtual void setParameters(int n, doublereal* c) {} + + + /** + * @internal Install a species thermodynamic property + * manager. The species thermodynamic property manager + * computes properties of the pure species for use in + * constructing solution properties. It is meant for internal + * use, and some classes derived from ThermoPhase may not use + * any species thermodynamic property manager. + */ + void setSpeciesThermo(SpeciesThermo* spthermo) + { m_spthermo = spthermo; } + + /** + * Return a reference to the species thermodynamic property + * manager. @todo This method will fail if no species thermo + * manager has been installed. + */ + SpeciesThermo& speciesThermo() { return *m_spthermo; } + + + doublereal refPressure() const { + return m_spthermo->refPressure(); + } + + doublereal minTemp(int k = -1) { + return m_spthermo->minTemp(); + } + + doublereal maxTemp(int k = -1) { + return m_spthermo->maxTemp(); + } + + ThermoPhase() { + m_spthermo = 0; + m_index = -1; + m_speciesData = 0; + } + + protected: + + /// Pointer to the species thermodynamic property manager + SpeciesThermo* m_spthermo; + + XML_Node* m_speciesData; + + /// Index number + int m_index; + + private: + + doublereal err(string msg) const; + + }; + + typedef ThermoPhase thermophase_t; + typedef ThermoPhase thermo_t; +} + +#endif + + + + + diff --git a/Cantera/src/ThirdBodyMgr.h b/Cantera/src/ThirdBodyMgr.h new file mode 100755 index 000000000..59748f9a6 --- /dev/null +++ b/Cantera/src/ThirdBodyMgr.h @@ -0,0 +1,186 @@ +/** + * @file ThirdBodyMgr.h + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_THIRDBODY_MGR_H +#define CT_THIRDBODY_MGR_H + +#include + +#include "ct_defs.h" +#include "utilities.h" +#include "Enhanced3BConc.h" + + +namespace Cantera { + + template + class ThirdBodyMgr{ + + public: + + ThirdBodyMgr<_E>() : m_n(0) {} + + void install( int rxnNumber, const map& enhanced, + doublereal dflt=1.0) { + m_n++; + m_reaction_index.push_back( rxnNumber ); + m_concm.push_back( _E( enhanced.size(), enhanced, dflt ) ); + } + + void update(const vector_fp& conc, doublereal ctot, workPtr work) { + TYPENAME_KEYWORD vector<_E>::const_iterator b = m_concm.begin(); + //doublereal* v = m_values.begin(); + for (; b != m_concm.end(); ++b, ++work) + *work = b->update(conc, ctot); + } + + void multiply(doublereal* output, const_workPtr work) { + _scatter_mult(work, work + m_n, + output, m_reaction_index.begin()); + } + + size_t workSize() { return m_concm.size(); } + bool contains(int rxnNumber) { + return (find(m_reaction_index.begin(), + m_reaction_index.end(), rxnNumber) + != m_reaction_index.end()); + } + + protected: + + int m_n; + vector_int m_reaction_index; + vector<_E> m_concm; + }; + +} + +#endif + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Cantera/src/TigerPolynomial.h b/Cantera/src/TigerPolynomial.h new file mode 100755 index 000000000..814349b05 --- /dev/null +++ b/Cantera/src/TigerPolynomial.h @@ -0,0 +1,116 @@ +/** + * @file TigerPolynomial.h + * + * $Author$ + * $Revision$ + * $Date$ + */ + +WARNING: May be out of date. Test before using! + + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_TigerPOLY_H +#define CT_TigerPOLY_H + +#include "TempFuncMgr.h" + +namespace Cantera { + + /** + * The Tiger polynomial parameterization. + */ + + + class TigerPolynomial { + + public: + + TigerPolynomial() : m_lowT(0.0), m_highT(0.0), m_Pref(0.0), + m_coeff(vector_fp(11)) {} + + /** + * construct a Tiger polynomial parameterization from the + * values in vector coeffs. + * @param coeffs(0) minimum temperature (K) + * @param coeffs(1) maximum temperature (K) + * @param coeffs(2) standard-state pressure (Pa) + * @param coeffs(3)-coeffs(11) polynomial coefficients + */ + + TigerPolynomial(int n, const vector_fp& coeffs) : + + m_lowT (coeffs[0]), + m_highT (coeffs[1]), + m_Pref (coeffs[2]), + m_coeff (vector_fp(8)) { + + m_coeff[0] = coeffs[3]; + m_coeff[1] = 1.e-3 * coeffs[4]; + m_coeff[2] = 1.e-6 * coeffs[5]; + m_coeff[3] = 1.e-9 * coeffs[6]; + m_coeff[4] = 1.e3 * coeffs[7]; + m_coeff[5] = 1.e6 * coeffs[8]; + m_coeff[6] = 1.e9 * coeffs[9]; + m_coeff[7] = 1.e9 * coeffs[10] / + (GasConst_cal_mol_K * 298.15); + + if (Debug::on) { + Debug::require(coeffs.size(), 11, Debug::NotLessThan); + } + } + + doublereal minTemp() const { return m_lowT; } + doublereal maxTemp() const { return m_highT; } + doublereal refPressure() const { return m_Pref; } + + void updateProperties(const TempFuncMgr& tt, + vector_fp& cp_R, vector_fp& h_RT, vector_fp& s_R, + vector_fp& g_RT) const { + + doublereal ct0 = m_coeff[0]; + doublereal ct1 = m_coeff[1]*tt.value(0); + doublereal ct2 = m_coeff[2]*tt.value(T2_INDEX); + doublereal ct3 = m_coeff[3]*tt.value(T3_INDEX); + doublereal ctm1 = m_coeff[4]*tt.value(TRECIP_INDEX); + doublereal ctm2 = m_coeff[5]/tt.value(T2_INDEX); + doublereal ctm3 = m_coeff[6]/tt.value(T3_INDEX); + + cp_R[m_index] = ct0 + ct1 + ct2 + ct3 + + ctm1 + ctm2 + ctm3; + + h_RT[m_index] = ct0 + 0.5 * ct1 + ct2/3.0 + + 0.25 * ct3 + + m_coeff[4] * tt.value(TLOG_INDEX) / tt.value(0) + - ctm2 - 0.5 * ctm3 + + m_coeff[7]*tt.value(TRECIP_INDEX); + + s_R[m_index] = m_coeff[0] * tt.value(TLOG_INDEX) + ct1 + + 0.5 * ct2 + ct3/3.0 + - ctm1 - 0.5 * ctm2 - ctm3/3.0 + + m_coeff[8] / GasConst_cal_mol_K ; + + g_RT[m_index] = h_RT[m_index] - s_R[m_index]; + } + + protected: + + doublereal m_lowT, m_highT, m_Pref; + vector_fp m_coeff; + int m_index; + + private: + + }; + +} + +#endif + + + + + + diff --git a/Cantera/src/config.h b/Cantera/src/config.h new file mode 100755 index 000000000..b891e9df9 --- /dev/null +++ b/Cantera/src/config.h @@ -0,0 +1,59 @@ +/* ../config.h. Generated automatically by configure. */ +// +// Run the 'configure' script to generate 'config.h' from this input file. +// +#ifndef CT_CONFIG_H +#define CT_CONFIG_H + + +//------------------------ Fortran settings -------------------// + + +// define types doublereal, integer, and ftnlen to match the +// corresponding Fortran data types on your system. The defaults +// are OK for most systems + +typedef double doublereal; // Fortran double precision +typedef int integer; // Fortran integer +typedef int ftnlen; // Fortran hidden string length type + + +// Fortran compilers pass character strings in argument lists by +// adding a hidden argement with the length of the string. Some +// compilers add the hidden length argument immediately after the +// CHARACTER variable being passed, while others put all of the hidden +// length arguments at the end of the argument list. Define this if +// the lengths are at the end of the argument list. This is usually the +// case for most unix Fortran compilers, but is (by default) false for +// Visual Fortran under Windows. +#define STRING_LEN_AT_END + + +// Define this if Fortran adds a trailing underscore to names in object files. +// For linux and most unix systems, this is the case. +#define FTN_TRAILING_UNDERSCORE + + +//-------- LAPACK / BLAS --------- + +// Define if you are using LAPACK and BLAS from the Intel Math Kernel +// Library +/* #undef HAVE_INTEL_MKL */ + +#define LAPACK_FTN_STRING_LEN_AT_END 1 +#define LAPACK_NAMES_LOWERCASE 1 +#define LAPACK_FTN_TRAILING_UNDERSCORE 1 + + +//--------- Cantera -------------- + + +//--------- CKReader ------------- + + + +//--------- CtLib ---------------- + + + +#endif diff --git a/Cantera/src/converters/.cvsignore b/Cantera/src/converters/.cvsignore new file mode 100644 index 000000000..57751bad9 --- /dev/null +++ b/Cantera/src/converters/.cvsignore @@ -0,0 +1,2 @@ +Makefile +.depends diff --git a/Cantera/src/converters/CKParser.cpp b/Cantera/src/converters/CKParser.cpp new file mode 100755 index 000000000..2cd925291 --- /dev/null +++ b/Cantera/src/converters/CKParser.cpp @@ -0,0 +1,1309 @@ +/** + * @file CKParser.cpp + * + */ + +// Copyright 2001 California Institute of Technology +// +// $Log$ +// Revision 1.1 2003-04-14 17:57:52 dggoodwin +// Initial revision +// +// Revision 1.1 2003/03/05 00:28:16 dgg +// *** empty log message *** +// +// Revision 1.21 2003/03/02 02:15:50 dgg +// *** empty log message *** +// +// Revision 1.20 2003/02/19 14:36:31 dgg +// *** empty log message *** +// +// Revision 1.19 2003/02/13 19:07:19 dgg +// *** empty log message *** +// + +// turn off warnings about truncating long names under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#endif + +#include +#include +#include +#include +#include + +#include "CKParser.h" +#include "ckr_utils.h" +#include "writelog.h" +#include + +//#include "../Cantera/src/ctmap.h" + + +using namespace std; + +namespace ckr { + + + static string int2s(int n, string fmt="%d") { + char buf[30]; + sprintf(buf, fmt.c_str(), n); + return string(buf); + } + + /// Exception class for syntax errors. + class CK_SyntaxError : public CK_Exception { + public: + CK_SyntaxError(ostream& f, const string& s, int linenum = -1) + : m_out(f) { + m_msg += "Syntax error: " + s; + if (linenum > 0) m_msg += " (line " + int2s(linenum) + ")\n"; + } + ostream& m_out; + }; + + + static int parseGroupString(string str, vector& esyms, + vector_int& result); + + /// @internal + //static string dummy_string; + + /** + * Throw an exception if one of the four lines that must have + * 1, 2, 3, or 4 in column 80 do not. + */ + static void illegalThermoLine(ostream& f, + char n, int linenum = -1) + { + throw CK_SyntaxError(f, "column 80 must " + "contain an integer", linenum); + }; + + + /** + * Throw an exception if number string is bad + */ + static void illegalNumber(ostream& f, + string s, int linenum = -1) + { + string msg = "illegal number: "+s; + throw CK_SyntaxError(f, msg, linenum); + }; + + + extern void getDefaultAtomicWeights(map& weights); + //extern void getDefaultAtomicWeights(ct::ctmap_sd& weights); + + static double getNumberFromString(string s) { + bool inexp = false; + removeWhiteSpace(s); + int sz = s.size(); + + char ch; + for (int n = 0; n < sz; n++) { + ch = s[n]; + if (!inexp && (ch == 'E' || ch == 'e' || ch == 'd')) + inexp = true; + else if (ch == '+' || ch == '-') { + if (n > 0 && (s[n-1] != 'E' && s[n-1] + != 'e' && s[n-1] != 'd')) { + return UNDEF; + } + } + else if (ch != '.' && (ch < '0' || ch > '9')) { + return UNDEF; + } + //else if (!inexp && isdigit(ch) && ch != '0') return UNDEF; + //else if (!inexp && ) return UNDEF; + } + return atof(s.c_str()); + } + + /** + * Add an element to a species. + * @param symbol element symbol + * @param atoms number of atoms of this element in the + * species (may be non-integral) + * @param sp Species object to add element to + * @param log log file output stream + */ + static void addElement(string symbol, double atoms, + Species& sp, ostream& log) { + + if (atoms != 0.0) { + Constituent e; + e.name = symbol; + e.number = atoms; + sp.elements.push_back(e); + sp.comp[symbol] = atoms; + } + } + + + /** + * Check validity of the three temperatures defining the two + * temperature ranges for the NASA polynomial species thermodynamic + * property fits. + * @param log log file output stream + * @param tmin minimum temperature + * @param tmid intermediate temperature + * @param tmax maximum temperature + */ + static void checkTemps(ostream& log, double tmin, + double tmid, double tmax) + { + if (tmin == 0.0 || tmid == 0.0 || tmax == 0.0) { + throw CK_SyntaxError(log, + "error reading Tmin, Tmid, or Tmax"); + } + if (tmin > tmid || tmid > tmax) { + throw CK_SyntaxError(log, + "condition Tmin <= Tmid <= Tmax violated"); + } + } + + + /** + * given a string specifying either the reactant or product side of a + * reaction equation, construct a list of RxnSpecies objects + * containing the species symbols and stoichiometric coefficients. + * @todo allow non-integral stoichiometric coefficients + */ + static void getSpecies(string s, + int n, vector& species) + { + char* begin = new char[n+1]; + copy(s.begin(), s.end(), begin); + begin[n] = '\0'; + char* end = begin + n; + char* p = begin; + bool inplus = true; + double m; + species.clear(); + vector syms; + vector_fp coeffs; + for (; p != end; p++) { + if (*p != '+' && inplus) { + if (p > begin) *(p - 1) = ' '; + if (m = atof(p), m > 0) { + *p = ' '; + coeffs.push_back(m); + } + else + coeffs.push_back(1.0); + inplus = false; + } + else if (*p == '+') + inplus = true; + } + string str = string(begin); + getTokens(str, n, syms); + RxnSpecies ss; + unsigned int j; + for (j = 0; j < syms.size(); j++) { + ss.name = syms[j]; + ss.number = coeffs[j]; + species.push_back(ss); + } + } + + + + /** + * given a string specifying either the reactant or product side of a + * reaction equation, construct a list of Constituent objects + * containing the species symbols and stoichiometric coefficients. + * @todo allow non-integral stoichiometric coefficients + */ + int getGroups(string::const_iterator begin, string::const_iterator end, vector& esyms, + vector& rxngroups) + { + bool ingroup = false; + rxngroups.clear(); + string g = ""; + group_t igrp; + grouplist_t groups; + + for (; begin != end; ++begin) { + if (*begin == '(') { + ingroup = true; + g = ""; + } + else if (*begin == ')') { + ingroup = false; + igrp.clear(); + if (parseGroupString(g, esyms, igrp) >= 0) + groups.push_back(igrp); + else return -1; + } + else if (*begin == '+') { + rxngroups.push_back(groups); + groups.clear(); + } + else if (ingroup && *begin != ' ') { + g += *begin; + } + } + rxngroups.push_back(groups); + return 1; + } + + + /** + * Constructor. Construct a parser for the specified input file. + */ + CKParser::CKParser(istream* infile, const string& fname, ostream* log) + : verbose(true), m_line (0) { + m_ckfile = infile; + m_ckfilename = fname; + m_log = log; + m_nasafmt = false; + } + + + /** + * + * Get a line from the input file, and return it in string s. If the + * line contains a comment character (!), then return only the + * portion preceding it. Non-printing characters are replaced by + * spaces. + * @param s On return, s contains the line read from the + * input file. + * @param comment On return, comment contains the text following the + * comment character on the line, if any. + * + */ + void CKParser::getCKLine(string& s, string& comment) { + + // Chemkin comment character + const char commentChar = '!'; + + // Cantera anti-comment character + const char undoCommentChar = '%'; + + // unix end of line + const char char13 = char(13); + + istream& f = *m_ckfile; + + // if putCKLine was called to 'put back' a line, then return this + // line, instead of reading a new one + + if (!m_buf.empty()) { + s = m_buf; + m_buf = ""; + comment = m_comment; + m_comment = ""; + return; + } + + // read a line, convert non-printing characters to ' ', + // and remove comments + + comment = ""; + string line; + //getline(f, line, dm); + line = ""; + char ch; + while (1 > 0) { + f.get(ch); + if (!f || f.eof()) break; + if (ch == '\n' || ch == char13) break; + line += ch; + } + int icom = line.find(commentChar); + + // lines that begin with !% are not comments for Cantera + if (icom == 0 && line[1] == undoCommentChar) { + line[0] = '%'; + line[1] = ' '; + icom = line.find(commentChar); + } + int len = line.size(); + + for (int i = 0; i < len; i++) if (!isprint(line[i])) line[i] = ' '; + if (icom >= 0) { + s = line.substr(0, icom); + comment = line.substr(icom+1,len-icom-1); + } + else { + s = line; + } + + if (!f || f.eof()) { + s = ""; + comment = ""; + return; + } + m_line++; + } + + + /** + * + * Put back a line read from the input file. The next call to + * getCKLine will return this line. + * + */ + + void CKParser::putCKLine(string& s, string& comment) { + m_buf = s; + m_comment = comment; + } + + + bool CKParser::advanceToKeyword(const string& kw, const string& stop) { + string s, c; + do { + getCKLine(s,c); + if (match(s,"")) return false; + if (match(s,kw)) { + putCKLine(s,c); + return true; + } + } + while (!match(s,stop)); + putCKLine(s,c); + return false; + } + + + + /** + * + * Read the element section of the input file, and return + * a list of the elements found. + * + */ + + bool CKParser::readElementSection(elementList& elements) { + string s, comment; + int firsttok; + vector toks; + + map defaultWeights; + //ct::ctmap_sd defaultWeights; + getDefaultAtomicWeights(defaultWeights); + + //istream& f = m_ckfile; + int ntok; + + elements.clear(); + while (1 > 0) { + +next: + if (advanceToKeyword("ELEM", "SPEC")) { + firsttok = 1; + while (1 > 0) { + do { + getCKLine(s, comment); + getTokens(s, s.size(), toks); + ntok = toks.size(); + } while (ntok == 0); + + if (firsttok == 0 && isKeyword(toks[0])) { + putCKLine(s,comment); + goto next; + } + for (int i = firsttok; i < ntok; i++) { + if (match(toks[i],"END")) goto next; + else { + Element el; + string wtstr; + el.comment = comment; + el.index = elements.size(); + if (extractSlashData(toks[i], el.name, wtstr)) { + el.atomicWeight = atof(wtstr.c_str()); + el.weightFromDB = false; + } + else { + el.atomicWeight = defaultWeights[capitalize(el.name)]; + el.weightFromDB = true; + } + if (el.atomicWeight > 0.0) el.valid = 1; + else el.valid = 0; + if (find(elements.begin(), + elements.end(), el) < elements.end()) { + if (m_log) + *m_log << "warning... duplicate element " + << el.name << " (ignored)." << endl; + } + else + elements.push_back(el); + } + } + firsttok = 0; + } + } + else { + if (elements.size() == 0) { + *m_log << "no elements found." << endl; + return false; + } + else return valid(elements); + } + } + return false; + } + + + + /** + * + * Read the SPECIES section of the input file, and return + * a list of species names. + * + */ + bool CKParser::readSpeciesSection(speciesList& species) { + string s, comment; + int firsttok; + vector toks; + + int ntok; + int nsp = 0; + + while (1 > 0) { + + next: + if (advanceToKeyword("SPEC", "THER")) { + firsttok = 1; + while (1 > 0) { + do { + getCKLine(s, comment); + getTokens(s, s.size(), toks); + ntok = toks.size(); + } while (ntok == 0); + + if (firsttok == 0 && isKeyword(toks[0])) { + putCKLine(s,comment); + goto next; + } + for (int i = firsttok; i < ntok; i++) { + if (match(toks[i],"END")) goto next; + else { + Species sp; + sp.name = toks[i]; + if (find(species.begin(), species.end(), sp) + < species.end()) { + if (m_log) + *m_log << "warning... duplicate species " + << sp.name << " (ignored)." << endl; + } + else { + nsp++; + sp.index = nsp; + species.push_back(sp); + } + } + } + firsttok = 0; + } + } + else { + if (species.size() == 0) return false; + else return true; + } + } + return false; + } + + + + /** + * + * Read species data from THERMO section records. + * + * @param names List of species names (input). + * @param species Table of species objects holding data from records + * in THERMO section (output). + * @param allowExtThermoData True if 'THERMO' specified, false if + * 'THERMO ALL' specified. + * + */ + + bool CKParser::readThermoSection(const vector& names, + speciesTable& species, vector_fp& temp, + int& optionFlag, ostream& log) { + string s; + vector toks; + + double tmin = -1.0, tmid = -1.0, tmax = -1.0; + if (temp.size() == 3) { + tmin = temp[0]; + tmid = temp[1]; + tmax = temp[2]; + } + + int nsp = names.size(); + + string comment; + + // read lines until THERMO section is found. But if EOF reached or + // start of REACTIONS section, then there is no THERMO section. + do { + getCKLine(s,comment); + if (match(s,"")) return false; + if (match(s,"REAC")) { + putCKLine(s,comment); + return false; + } + } + while (!match(s,"THER")); + + // read the tokens on the THERMO line + getTokens(s, s.size(), toks); + m_nasafmt = false; + if (toks.size() >= 2) + { + unsigned int itt; + for (itt = 1; itt < toks.size(); itt++) { + if (match(toks[itt],"ALL")) { + optionFlag = NoThermoDatabase; + } + else if (match(toks[itt],"NO_TMID")) { + m_nasafmt = true; + log << "\nOption 'NO_TMID' specified. Default midpoint temperature\n"; + log << "will be used for all species.\n\n"; + } + else throw CK_SyntaxError(log, + "unrecognized THERMO option.", m_line); + } + } + + // if "THERMO ALL" specified, or if optionFlag is set to HasTempRange, + // then the next line must be the 3 default temperatures for the database. + + if (optionFlag == NoThermoDatabase || optionFlag == HasTempRange) { + getCKLine(s, comment); + getTokens(s, s.size(), toks); + if (toks.size() >= 3) { + tmin = atof(toks[0].c_str()); + tmid = atof(toks[1].c_str()); + tmax = atof(toks[2].c_str()); + } + + if (verbose) { + log.flags(ios::showpoint | ios::fixed); + log.precision(2); + log << endl << " default Tlow, Tmid, Thigh: " << tmin << " " + << tmid << " " << tmax << endl; + } + checkTemps(log, tmin, tmid, tmax); + temp.clear(); + temp.push_back(tmin); + temp.push_back(tmid); + temp.push_back(tmax); + } + + // now read in all species records that have names in list 'names' + + bool getAllSpecies = (nsp > 0 && match(names[0],"")); + + map dup; // used to check for duplicate THERMO records + bool already_read; + + while (1 > 0) { + if (nsp == 0) break; + already_read = false; + + Species spec; + readThermoRecord(spec); + + if (spec.name == "") { + break; + } + + // check for duplicate thermo data + if (dup[spec.name] == 2) { + log << "Warning: more than one THERMO record for " + << "species " << spec.name << endl; + log << "Record at line " << m_line + << " of " << m_ckfilename << " ignored." << endl; + already_read = true; + } + dup[spec.name] = 2; + + if (!already_read && (getAllSpecies + || (find(names.begin(), names.end(), spec.name) + < names.end()))) + { + + if (spec.tmid == 0.0) { + spec.tmid = tmid; + log << "Warning: default Tmid used for species " + << spec.name << endl; + if (spec.tmid < 0.0) { + log << "Error: no default Tmid has been entered!" + << endl; + } + } + species[spec.name] = spec; + + if (verbose) { + log << endl << "found species " << spec.name; + log << " at line " << m_line + << " of " << m_ckfilename; + writeSpeciesData(log, spec); + } + checkTemps(log, spec.tlow, spec.tmid, spec.thigh); + nsp--; + } + } + return true; + } + + + /** + * + * Read one 4-line species definition record in NASA format. + * + */ + + void CKParser::readThermoRecord(Species& sp) { + string s; + string numstr; + double cf; + + // look for line 1, but if a keyword is found first or the end of + // the file is reached, return "" as the species name + string comment; + do { + getCKLine(s, comment); + if (isKeyword(s) || match(s, "")) { + sp.name = ""; + putCKLine(s, comment); + return; + } + } + while ((s.size() < 80) || (s[79] != '1')); + + // next 4 lines must be the NASA-format lines without intervening + // comments. + + //------------- line 1 --------------------------- + + if (s[79] != '1') illegalThermoLine(*m_log, s[79], m_line); + + // extract the species name and the id string (date) + string nameid = s.substr(0,24); + vector toks; + getTokens(nameid, nameid.size(), toks); + sp.name = toks[0]; + sp.id = ""; + unsigned int j; + for (j = 1; j < toks.size(); j++) { + if (j > 1) sp.id += ' '; + sp.id += toks[j]; + } + int iloc; + string elementSym; + double atoms; + int i; + + // elemental composition (first 4 elements) + for (i = 0; i < 4; i++) { + elementSym = ""; + iloc = 24 + 5*i; + if (s[iloc] != ' ') { + if (s[iloc+1] != ' ') elementSym = s.substr(iloc,2); + else elementSym = s.substr(iloc,1); + } + else if (s[iloc+1] != ' ') elementSym = s.substr(iloc+1,1); + atoms = atof(s.substr(iloc+2,3).c_str()); + addElement(elementSym, atoms, sp, *m_log); + } + + // single-character phase descriptor + sp.phase = s[44]; + + // low, high, and mid temperatures + sp.tlow = atof(s.substr(45,10).c_str()); + sp.thigh = atof(s.substr(55,10).c_str()); + + if (!m_nasafmt) { + sp.tmid = atof(s.substr(65,8).c_str()); + + // fifth element, if any + elementSym = ""; + if (s[73] != ' ') elementSym += s[73]; + if (s[74] != ' ') elementSym += s[74]; + atoms = atof(s.substr(75,3).c_str()); + addElement(elementSym, atoms, sp, *m_log); + } + + //-------------- line 2 ---------------------------- + + getCKLine(s, comment); + if (s[79] != '2') illegalThermoLine(*m_log, s[79], m_line); + for (i = 0; i < 5; i++) { + numstr = s.substr(i*15, 15); + cf = getNumberFromString(numstr); + if (cf == UNDEF) illegalNumber(*m_log, numstr, m_line); + sp.highCoeffs.push_back(cf); + } + + //-------------- line 3 ---------------------------- + + getCKLine(s, comment); + if (s[79] != '3') illegalThermoLine(*m_log, s[79], m_line); + for (i = 0; i < 2; i++) { + numstr = s.substr(i*15, 15); + cf = getNumberFromString(numstr); + if (cf == UNDEF) illegalNumber(*m_log, numstr, m_line); + sp.highCoeffs.push_back(cf); + } + for (i = 2; i < 5; i++) { + numstr = s.substr(i*15, 15); + cf = getNumberFromString(numstr); + if (cf == UNDEF) illegalNumber(*m_log, numstr, m_line); + sp.lowCoeffs.push_back(cf); + } + + //--------------- line 4 ---------------------------- + + getCKLine(s, comment); + if (s[79] != '4') illegalThermoLine(*m_log, s[79], m_line); + for (i = 0; i < 4; i++) { + numstr = s.substr(i*15, 15); + cf = getNumberFromString(numstr); + if (cf == UNDEF) illegalNumber(*m_log, numstr, m_line); + sp.lowCoeffs.push_back(cf); + } + sp.valid = 1; + } + + + + void CKParser::missingAuxData(const string& kw) { + throw CK_SyntaxError(*m_log, kw + + " keyword must be followed by slash-delimited data.", m_line); + } + + + /** + * Parse the REACTION section of the input file, and return + * a list of Reaction objects and the units. + */ + bool CKParser::readReactionSection(const vector& speciesNames, + vector& elementNames, reactionList& reactions, + ReactionUnits& units) + { + string s, comment; + vector toks; + int nRxns = 0; + + vector rc, pr; + vector_int c; + + // advance to the beginning of the REACTION section + do { + getCKLine(s, comment); + if (match(s, "")) return false; + } + while (!match(s,"REAC")); + + + // look for units specifications + + getTokens(s, s.size(), toks); + string tok; + units.ActEnergy = Cal_per_Mole; + units.Quantity = Moles; + unsigned int ir; + for (ir = 1; ir < toks.size(); ir++) { + tok = toks[ir]; + if (match(tok,"CAL/MOLE")) + units.ActEnergy = Cal_per_Mole; + else if (match(tok,"KCAL/MOLE")) + units.ActEnergy = Kcal_per_Mole; + else if (match(tok,"JOULES/MOLE")) + units.ActEnergy = Joules_per_Mole; + else if (match(tok,"KJOULES/MOLE")) + units.ActEnergy = Kjoules_per_Mole; + else if (match(tok,"KELVINS")) + units.ActEnergy = Kelvin; + else if (match(tok,"EVOLTS")) + units.ActEnergy = Electron_Volts; + else if (match(tok,"MOLES")) + units.Quantity = Moles; + else if (match(tok,"MOLECULES")) + units.Quantity = Molecules; + } + + Reaction rxn; + bool ok = true; + + while (1 > 0) { + + // skip blank or comment lines + do { + getCKLine(s, comment); + } + while (s == "" && comment[0] != '%'); + + // end of REACTION section or EOF + /// @todo does this handle case of 1 reaction correctly? + if (isKeyword(s) || s == "") { + if (nRxns > 0) { + rxn.number = nRxns; + reactions.push_back(rxn); + } + if (nRxns > 0) return ok; + return false; + } + + // rxn line + int eqloc; + string sleft, sright; + bool auxDataLine, metaDataLine; + + + // if the line contains an '=', it is the start of a new reaction. + // In this case, add the previous reaction to the output list, + // increment the number of reactions, and start processing the + // new reaction. + + eqloc = s.find_first_of("="); + metaDataLine = false; + auxDataLine = false; + + // look for a metadata line + if (s[0] == '%') { + metaDataLine = true; + if (eqloc > 0 && eqloc < int(s.size())) { + int ierr, ierp; + vector rg, pg; + s[eqloc] = ' '; + ierr = getGroups(s.begin(), s.begin() + eqloc, + elementNames, rg); + ierp = getGroups(s.begin() + eqloc, s.end(), + elementNames, pg); + unsigned int nr = rxn.reactants.size(); + unsigned int nratoms = 0; + for (unsigned int ij = 0; ij < nr; ij++) + nratoms += int(rxn.reactants[ij].number); + if (rg.size() != nratoms) + throw CK_SyntaxError(*m_log, + " groups not specified for all reactants", m_line); + else if (ierr < 0) + throw CK_SyntaxError(*m_log, + " error in reactant group specification", m_line); + for (unsigned int ir = 0; ir < nr; ir++) { + rxn.reactants[ir].groups = rg[ir]; + } + unsigned int np = rxn.products.size(); + unsigned int npatoms = 0; + for (unsigned int ik = 0; ik < np; ik++) + npatoms += int(rxn.products[ik].number); + if (pg.size() != npatoms) + throw CK_SyntaxError(*m_log, + " groups not specified for all products", m_line); + else if (ierp < 0) + throw CK_SyntaxError(*m_log, + " error in product group specification", m_line); + for (unsigned int ip = 0; ip < np; ip++) { + rxn.products[ip].groups = pg[ip]; + } + } + } + + else if (eqloc >= 0 && eqloc < int(s.size())) { + if (nRxns > 0) { + rxn.number = nRxns; + reactions.push_back(rxn); + } + nRxns++; + rxn = Reaction(); + } + else auxDataLine = true; + if (comment != "") rxn.lines.push_back(s+'!'+comment); + else rxn.lines.push_back(s); + + if (!auxDataLine && !metaDataLine) { + + // depending on the form of the 'equals' symbol, + // determine whether the reaction is reversible or + // irreversible, and separate it into strings for + // each side. + + if (eqloc = int(s.find("<=>")), eqloc >= 0) { + rxn.isReversible = true; + sleft = s.substr(0, eqloc); + sright = s.substr(eqloc+3,1000); + } + else if (eqloc = int(s.find("=>")), eqloc >= 0) { + rxn.isReversible = false; + sleft = s.substr(0, eqloc); + sright = s.substr(eqloc+2,1000); + } + else if (eqloc = int(s.find("=")), eqloc >= 0) { + rxn.isReversible = true; + sleft = s.substr(0, eqloc); + sright = s.substr(eqloc+1,1000); + } + else throw CK_SyntaxError(*m_log, + "expected <=>, =>, or =", m_line); + + int mloc, mloc2; + + // process reactants + removeWhiteSpace(sleft); + rxn.isFalloffRxn = false; + + string sm, mspecies; + + mloc = sleft.find("(+"); + if (mloc >= 0) { + sm = sleft.substr(mloc+2, 1000); + mloc2 = sm.find(")"); + if (mloc2 >= 0) { + mspecies = sm.substr(0,mloc2); + rxn.isFalloffRxn = true; + rxn.type = Falloff; + sleft = sleft.substr(0, mloc); + if (mspecies == "M" || mspecies == "m") { + rxn.thirdBody = "M"; + } + else { + rxn.thirdBody = mspecies; + } + } + else throw CK_SyntaxError(*m_log, + "missing )", m_line); + } + + else if ((mloc = sleft.find("+M"), mloc >= 0) || + (mloc = sleft.find("+m"), mloc >= 0)) { + rxn.isThreeBodyRxn = true; + rxn.type = ThreeBody; + sleft = sleft.substr(0, mloc); + rxn.thirdBody = "M"; + } + + getSpecies(sleft.c_str(),sleft.size(),rxn.reactants); + int ir = rxn.reactants.size(); + for (int iir = 0; iir < ir; iir++) { + if (find(speciesNames.begin(), speciesNames.end(), + rxn.reactants[iir].name) >= speciesNames.end()) + throw CK_SyntaxError(*m_log, + "undeclared reactant species " + +rxn.reactants[iir].name, m_line); + } + + + // process Arrhenius coefficients + getTokens(sright, sright.size(), toks); + int ntoks = toks.size(); + if (ntoks < 3) { + throw CK_SyntaxError(*m_log, + "expected 3 Arrhenius parameters", m_line); + } + rxn.kf.A = atof(toks[ntoks - 3].c_str()); + rxn.kf.n = atof(toks[ntoks - 2].c_str()); + rxn.kf.E = atof(toks[ntoks - 1].c_str()); + + // 2/10/03: allow negative prefactor but print a warning + if (rxn.kf.A < 0.0) + *m_log << "Warning: negative prefactor at line " + << m_line << endl; + //throw CK_SyntaxError(*m_log, "negative prefactor", m_line); + + sright = sright.substr(0, sright.find(toks[ntoks - 3]) - 1 ); + + removeWhiteSpace(sright); + + mloc = sright.find("(+"); + if (mloc >= 0) { + sm = sright.substr(mloc+2, 1000); + mloc2 = sm.find(")"); + if (mloc2 >= 0) { + mspecies = sm.substr(0,mloc2); + + if (rxn.type == ThreeBody) + throw CK_SyntaxError(*m_log, + "mismatched +M or (+M)", m_line); + + rxn.isFalloffRxn = true; + rxn.type = Falloff; + } + else throw CK_SyntaxError(*m_log, + "missing )", m_line); + + sright = sright.substr(0, mloc); + + if (mspecies == "M" || mspecies == "m") { + rxn.thirdBody = "M"; + } + else { + if (rxn.thirdBody != mspecies) + throw CK_SyntaxError(*m_log, + "mismatched third body", m_line); + rxn.thirdBody = mspecies; + } + } + + else if ((mloc = sright.find("+M"), mloc >= 0) || + (mloc = sright.find("+m"), mloc >= 0)) { + if (rxn.type == Falloff) + throw CK_SyntaxError(*m_log, + "mismatched +M or (+M)", m_line); + rxn.isThreeBodyRxn = true; + rxn.thirdBody = "M"; + sright = sright.substr(0, mloc); + } + getSpecies(sright.c_str(),sright.size(),rxn.products); + int ip = rxn.products.size(); + for (int iip = 0; iip < ip; iip++) { + if (find(speciesNames.begin(), speciesNames.end(), + rxn.products[iip].name) >= speciesNames.end()) + throw CK_SyntaxError(*m_log, + "undeclared product species "+rxn.products[iip].name, m_line); + } + } + + // auxiliary data line + else if (auxDataLine) { + + bool hasAuxData; + string name, data; + map kwindex; + while (1 > 0) { + + hasAuxData = extractSlashData(s, name, data); + if (!hasAuxData && name == "") break; + + // check for duplicate keyword + if (kwindex[name]) { + throw CK_SyntaxError(*m_log, + "duplicate auxiliary data keyword " + name, m_line); + } + else + kwindex[name] = 1; + + + // low-pressure rate coefficient for falloff rxn + + if (match(name,"LOW")) { + vector klow; + rxn.type = Falloff; + if (hasAuxData) { + getTokens(data, data.size(), klow); + if (klow.size() != 3) { + throw CK_SyntaxError(*m_log, + "expected 3 low-pressure Arrhenius parameters", m_line); + } + rxn.kf_aux.A = atof(klow[0].c_str()); + rxn.kf_aux.n = atof(klow[1].c_str()); + rxn.kf_aux.E = atof(klow[2].c_str()); + } + else + missingAuxData("LOW"); + } + + + // falloff parameters + + else if (match(name,"TROE")) { + vector falloff; + if (kwindex["SRI"] > 0) + { + throw CK_SyntaxError(*m_log, + "cannot specify both SRI and TROE", m_line); + } + + if (hasAuxData) { + getTokens(data, data.size(), falloff); + int nf = falloff.size(); + double ff; + rxn.falloffType = Troe; + for (int jf = 0; jf < nf; jf++) { + ff = atof(falloff[jf].c_str()); + rxn.falloffParameters.push_back(ff); + } + } + else + missingAuxData("TROE"); + } + + else if (match(name,"SRI")) { + vector falloff; + if (kwindex["TROE"] > 0) { + throw CK_SyntaxError(*m_log, + "cannot specify both SRI and TROE", m_line); + } + if (hasAuxData) { + getTokens(data, data.size(), falloff); + int nf = falloff.size(); + rxn.falloffType = SRI; + double ff; + for (int jf = 0; jf < nf; jf++) { + ff = atof(falloff[jf].c_str()); + rxn.falloffParameters.push_back(ff); + } + } + else missingAuxData("SRI"); + } + + + + // reverse rate coefficient + + else if (match(name,"REV")) { + vector krev; + if (!rxn.isReversible) { + throw CK_SyntaxError(*m_log, + "reverse rate parameters can only be " + "specified for reversible reactions", m_line); + } + if (hasAuxData) { + getTokens(data, data.size(), krev); + if (krev.size() != 3) { + throw CK_SyntaxError(*m_log, + "expected 3 Arrhenius parameters", m_line); + } + rxn.krev.A = atof(krev[0].c_str()); + rxn.krev.n = atof(krev[1].c_str()); + rxn.krev.E = atof(krev[2].c_str()); + } + else + missingAuxData("REV"); + } + + + else if (match(name,"DUP")) + rxn.isDuplicate = true; + + else if (match(name,"END")) { + string c = ""; + putCKLine(name,c); + break; + } + + + // Landau-Teller reaction rate parameters + + else if (match(name,"LT")) { + vector bc; + rxn.kf.type = LandauTeller; + if (hasAuxData) { + getTokens(data, data.size(), bc); + rxn.kf.B = atof(bc[0].c_str()); + rxn.kf.C = atof(bc[1].c_str()); + } + else + missingAuxData("LT"); + } + + else if (match(name,"RLT")) { + vector bc; + rxn.krev.type = LandauTeller; + if (hasAuxData) { + getTokens(data, data.size(), bc); + rxn.krev.B = atof(bc[0].c_str()); + rxn.krev.C = atof(bc[1].c_str()); + } + else + missingAuxData("RLT"); + } + + + // chem activation reactions + else if (match(name,"HIGH")) { + vector khigh; + rxn.type = ChemAct; + if (hasAuxData) { + getTokens(data, data.size(), khigh); + rxn.kf_aux.A = atof(khigh[0].c_str()); + rxn.kf_aux.n = atof(khigh[1].c_str()); + rxn.kf_aux.E = atof(khigh[2].c_str()); + } + else + missingAuxData("HIGH"); + } + + else if (find(speciesNames.begin(), speciesNames.end(), name) + < speciesNames.end()) { + if (hasAuxData) { + if (rxn.thirdBody == name || rxn.thirdBody == "M") + rxn.e3b[name] = atof(data.c_str()); + else if (rxn.thirdBody == "") { + *m_log << "Error in reaction " << nRxns + << ": third-body collision efficiencies cannot be specified" + << " for this reaction type." << endl; + throw CK_SyntaxError(*m_log, + "third-body efficiency error", m_line); + } + else { + *m_log << "Reaction " << nRxns << ": illegal species in enhanced " + << "efficiency specification. Species = " + << name << " rxn.thirdBody = " + << rxn.thirdBody << endl; + throw CK_SyntaxError(*m_log, + "third-body efficiency error", m_line); + } + } + else missingAuxData(name); + } + else { + Reaction::auxdata vals; + vector toks; + getTokens(data, data.size(), toks); + int ntoks = toks.size(); + for (int itok = 0; itok < ntoks; itok++) { + vals.push_back(atof(toks[itok].c_str())); + } + rxn.otherAuxData[name] = vals; + } + } + } + } + return false; + } + + + + int parseGroupString(string str, vector& esyms, group_t& result) { + bool inSymbol=true; + string s = str + '-'; + int i; + string num, sym; + int eindx; + string::const_iterator begin = s.begin(); + string::const_iterator end = s.end(); + vector::iterator e; + result.resize(esyms.size(),0); + for (; begin != end; ++begin) { + + // new element + if (*begin == '-') { + e = find(esyms.begin(), esyms.end(), sym); + if (e == esyms.end()) return -1; + eindx = e - esyms.begin(); + if (num != "") + i = atoi(num.c_str()); + else + i = 1; + result[eindx] = i; + sym = ""; + num = ""; + inSymbol = true; + } + else if (isdigit(*begin)) { + inSymbol = false; + num += *begin; + } + else if (isalpha(*begin) && inSymbol) { + sym += *begin; + } + } + return 1; + } + +} // ckr namespace + + + + + diff --git a/Cantera/src/converters/CKParser.h b/Cantera/src/converters/CKParser.h new file mode 100755 index 000000000..4705c8f00 --- /dev/null +++ b/Cantera/src/converters/CKParser.h @@ -0,0 +1,89 @@ +/** + * @file CKParser.h + * + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CKR_CKPARSER_H +#define CKR_CKPARSER_H + +#ifdef WIN32 +#pragma warning(disable:4786) +#endif + +#include +#include +#include +using namespace std; + +#include "ckr_defs.h" +#include "Element.h" +#include "Species.h" +#include "Reaction.h" +#include "Group.h" + +namespace ckr { + + + // typedefs + + /// readability constants + //@{ + const int NoThermoDatabase = 10; + const int HasTempRange = 11; + //@} + + + + + /** + * Chemkin mechanism file parser. For internal use by class CKReader. + */ + class CKParser { + + public: + + CKParser(string ckfile, ostream* log); + CKParser(istream* infile, const string& fname, ostream* log); + + /// Destructor. + ~CKParser(){} + + bool readElementSection(elementList& elements); + bool readSpeciesSection(speciesList& species); + bool readThermoSection(const vector& names, + speciesTable& speciesData, vector_fp& temp, + int& optionFlag, ostream& log); + bool readReactionSection(const vector& speciesNames, + vector& elementNames, + reactionList& reactions, ReactionUnits& units); + bool advanceToKeyword(const string& kw, const string& stop); + bool verbose; + + private: + + int m_line; + string m_buf; + string m_comment; + istream* m_ckfile; + string m_ckfilename; + ostream* m_log; + bool m_nasafmt; + void readThermoRecord(Species& sp); + void getCKLine(string& s, string& comment); + void putCKLine(string& s, string& comment); + void missingAuxData(const string& kw); + }; +} + + +#endif + + + + + + + diff --git a/Cantera/src/converters/CKReader.cpp b/Cantera/src/converters/CKReader.cpp new file mode 100755 index 000000000..a314f7072 --- /dev/null +++ b/Cantera/src/converters/CKReader.cpp @@ -0,0 +1,663 @@ +/** + * @file CKReader.cpp + * + */ + +// Copyright 2001 California Institute of Technology + + +// disable warning about long names in Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#endif + +#include +#include +using namespace std; + +#include "CKParser.h" +#include "CKReader.h" +#include "thermoFunctions.h" + +#include +#include +#include +#include + +#include "writelog.h" +#include +#include "ckr_defs.h" + +//#include "global.h" +//#define APP Cantera::Application + +namespace ckr { + + +/** + * read and optionally validate an input file in Chemkin format. + * @param inputFile path to the input file + * @param thermoDatabase path to the species database file + * @param log path to the file where log messages should be written + * @return true if no errors were encountered, false otherwise + */ + +bool CKReader::read(const string& inputFile, const string& thermoDatabase, + const string& logfile) { + + clock_t t0, t1; + + t0 = clock(); + + ifstream ckinfile(inputFile.c_str()); + ofstream log(logfile.c_str()); + try { + // construct a parser for the input file + CKParser parser(&ckinfile, inputFile, &log); + parser.verbose = verbose; + + // write header information to the log file + struct tm *newtime; + time_t aclock; + time( &aclock ); /* Get time in seconds */ + newtime = localtime( &aclock ); /* Convert time to struct tm form */ + + + log << "CKReader version 1.0" << endl + << "http://www.cantera.org" << endl << endl + << asctime(newtime) << endl + << setw(20) << "input file: " + << setw(30) << inputFile << endl; + + if (thermoDatabase != "") + log << setw(20) << "species database: " + << setw(30) << thermoDatabase << endl; + + if (!validate) + log << endl << "*************** Warning ***************" << endl + << " mechanism validation disabled" << endl + << "*****************************************" << endl; + + //----------- process ELEMENT section ---------------------- + + bool elok = parser.readElementSection(elements); + int nel = elements.size(); + vector elementSymbols; + for (int j = 0; j < nel; j++) elementSymbols.push_back(elements[j].name); + + if (verbose) { + log.flags(ios::showpoint); + log.precision(6); + log.width(0); + + log << endl << newTask("reading elements") << endl; + + // write summary to log file + for (int i = 0; i < nel; i++) { + log << i+1 << ". " << pad(elements[i].name,2) << " "; + double wt = elements[i].atomicWeight; + if (wt == 0.0) log << ""; + else log << wt; + if (!elements[i].weightFromDB) log << " (specified)"; + if (elements[i].comment != "") + log << " ! " << elements[i].comment; + log << endl; + } + } + log << "\nread " << nel << " elements." << endl; + + if (!elok) { + log << "\nerrors were encountered." << endl; + return false; + } + if (nel == 0) { + return false; + } + + + //------------ process SPECIES section ------------------------ + + vector speciesSymbols; + bool spok = parser.readSpeciesSection(species); + int nsp = species.size(); + + if (verbose) log << newTask("reading species") << endl; + + for (int i = 0; i < nsp; i++) { + Species& s = species[i]; + if (verbose) log << i+1 << ". " << s.name << endl; + speciesSymbols.push_back(s.name); + } + log << "\nread " << nsp << " species." << endl; + + if (!spok) { + log << "\nerrors were encountered." << endl; + return false; + } + if (nsp == 0) return false; + + + //------------- process THERMO section ------------------------- + + if (verbose) log << newTask("looking up species definitions") << endl; + + // if a thermo database is specified, get the default Tmin, Tmid, Tmax + vector_fp temp; + + if (thermoDatabase != "") { + + if (verbose) log << "reading default temperature ranges from " + << thermoDatabase << endl; + + ifstream thermofile(thermoDatabase.c_str()); + CKParser thermReader(&thermofile, thermoDatabase, &log); + thermReader.verbose = verbose; + int dbflag = HasTempRange; + vector dummy; + thermReader.readThermoSection(dummy, speciesData, temp, dbflag, log); + } + + + bool hasthermo = parser.advanceToKeyword("THERM","REAC"); + + int optionFlag = 0; + int undefined = species.size(); + string nm; + vector undef; + + if (hasthermo && parser.readThermoSection(speciesSymbols, + speciesData, temp, optionFlag, log)) { + + undefined = 0; + for (int k = 0; k < nsp; k++) { + nm = species[k].name; + species[k] = speciesData[species[k].name]; + if (species[k].name == "") { + undefined++; + undef.push_back(nm); + species[k].name = nm; + } + } + int localdefs = nsp - undefined; + if (localdefs > 0 && verbose) log << "found definitions for " + << localdefs + << " of " + << nsp + << " species in the input file. " + << endl; + } + else { + undef = speciesSymbols; + if (verbose) log << "no THERMO section in input file." << endl; + } + + if (undefined > 0 && thermoDatabase != "" + && optionFlag != NoThermoDatabase) { + + if (verbose) log << "searching external database " + << thermoDatabase << " for species definitions..." + << endl; + + ifstream thermofile(thermoDatabase.c_str()); + CKParser thermoReader(&thermofile, thermoDatabase, &log); + thermoReader.verbose = verbose; + int dbflag = HasTempRange; + thermoReader.readThermoSection(undef, speciesData, temp, dbflag, log); + undefined = 0; + for (int k = 0; k < nsp; k++) { + if (species[k].valid == 0) { + nm = species[k].name; + species[k] = speciesData[species[k].name]; + if (species[k].name == "") { + undefined++; + species[k].name = nm; + } + } + } + } + + if (!validateSpecies(log)) { + //Cantera::setError("read","error in species"); + return false; + } + + + //------------- process REACTIONS section ------------------------- + + if (verbose) log << newTask("reading reactions") << endl; + + ckinfile.close(); + ifstream ckinfile2(inputFile.c_str()); + + // construct a new parser for the input file + CKParser parser2(&ckinfile2, inputFile, &log); + parser2.verbose = verbose; + + parser2.readReactionSection(speciesSymbols, elementSymbols, reactions, units); + log << "\nread " << reactions.size() << " reactions." << endl; + + bool rxnok = true; + if (validate) rxnok = rxnok && validateReactions(log); + bool writeok = true; + if (verbose || validate) writeok = writeReactions(log); + rxnok = rxnok && writeok; + if (!rxnok) return false; + + log << "\nSuccess... "; + t1 = clock(); + log << "elapsed CPU time = " + << double(t1 - t0)/CLOCKS_PER_SEC + << " s" << endl; + if (!validate) log << "*** no validation performed ***" << endl; + } + + catch (CK_Exception e) { + log << e.errorMessage() << endl; + //Cantera::setError("CKReader::read",e.errorMessage()); + return false; + } + catch (...) { + log << "an exception was raised in CKReader."; + return false; + } + + return true; +} + + +/// print a summary of all reactions to the log file +bool CKReader::writeReactions(ostream& log) { + + bool ok = true; + // int ns = species.size(); + int nrxns = reactions.size(); + log.flags(ios::unitbuf); + log.precision(6); + + log << endl; + for (int n = 0; n < nrxns; n++) { + Reaction& r = reactions[n]; + + log << "reaction " << r.number << endl; + log << " "; + printReactionEquation(log, r); + log << endl; + + // rate coefficient + if (r.isFalloffRxn) { + + log << " high P rate coeff: "; + ok = ok && writeRateCoeff(r.kf, log) ; + + log << " low P rate coeff: "; + ok = ok && writeRateCoeff(r.kf_aux, log); + + ok = ok && writeFalloff(r.falloffType, r.falloffParameters, log); + + } + else { + log << " rate coeff: "; + ok = ok && writeRateCoeff(r.kf, log); + } + if (r.isReversible && r.krev.A > 0) { + log << " reverse rate coeff: "; + ok = ok && writeRateCoeff(r.krev, log); + } + int ne = r.e3b.size(); + + if (ne > 0) { + vector enhSpecies; + getMapKeys(r.e3b, enhSpecies); + log << " enhanced collision efficiencies:" << endl; + log << " "; + for (int nn = 0; nn < ne; nn++) { + log << enhSpecies[nn] << " " + << r.e3b[enhSpecies[nn]]; + if (nn < ne-1) log << ", "; + } + log << endl; + } + if (r.isDuplicate) log + << " declared duplicate reaction. See reaction " + << r.duplicate << "." << endl; + log << endl; + } + return ok; +} + + + +/// validate the species +bool CKReader::validateSpecies(ostream& log) { + int nel = elements.size(); + int nsp = species.size(); + double nm, tol; + int j, k, m; + + log << newTask("validating species"); + + // check for undeclared elements + vector esyms; + + log << " checking that all species have been defined... "; + for (k = 0; k < nsp; k++) { + Species& s = species[k]; + if (s.valid == 0) { + log << endl << " species " << s.name << " undefined "; + s.valid = -1; + } + } + if (valid(species)) log << "OK" << endl; + else { + log << endl; + return false; + } + + log << " checking that all species elements have been declared... "; + for (k = 0; k < nsp; k++) { + + Species& s = species[k]; + + getMapKeys(s.comp, esyms); + nm = esyms.size(); + + for (m = 0; m < nm; m++) { + for (j = 0; j < nel; j++) { + if (esyms[m] == elements[j].name) break; + } + if (j == nel) { + log << endl << " species " + << s.name << ": undeclared element " + << esyms[m]; + s.valid = -1; + } + } + } + if (valid(species)) log << "OK" << endl; + else { + log << endl; + return false; + } + + log << " checking consistency of species thermo data... "; + tol = 0.01; + if (checkThermo(log, species, tol)) log << "OK" << endl; + else { + log << endl; + return false; + } + return true; + +} + + +/// validate the reactions +bool CKReader::validateReactions(ostream& log) { + + bool ok = true; + // int ns = species.size(); + int nrxns = reactions.size(); + + vector unbal; + log << "checking that all reactions balance..."; + if (checkBalance(log, speciesData, reactions, unbal)) { + log << " OK" << endl; + } + else { + int nu = unbal.size(); + for (int iu = 0; iu < nu; iu++) { + log << " error... reaction " << unbal[iu] + << " does not balance" << endl; + } + ok = false; + } + + log << "checking for duplicate reactions..."; + + for (int nn = 0; nn < nrxns; nn++) { + Reaction& r1 = reactions[nn]; + for (int mm = nn + 1; mm < nrxns; mm++) { + Reaction& r2 = reactions[mm]; + if (r1 == r2) { + r1.duplicate = mm + 1; + r2.duplicate = nn + 1; + if (!r1.isDuplicate || !r2.isDuplicate) { + log << endl << " error... undeclared duplicate reactions: " + << nn + 1 << " and " << mm + 1; + ok = false; + } + else { + log << endl << " declared duplicate reactions: " + << nn + 1 + << " and " << mm + 1; + } + } + } + } + if (ok) log << "...OK" << endl; + + return ok; +} + + +/** + * Check the thermodynamic property parameterizations for all species. + * The following are verified: + * - The heat capacity is positive throughout the full temperature range; + * - The entropy at Tmin is positive; + * - The heat capacity, entropy, and enthalpy evaluated at Tmid using + * both the high and low polynomial coefficients are the same to within + * relative error tol + * - The heat capacity at Tmax is not greater than the equipartition limit + * for the number of atoms in the molecule + */ +bool checkThermo(ostream& log, speciesList& sp, double tol) { + const double dt = 0.0001; + double t, cp0, h0, s0, cp1, h1, s1; + int nsp = sp.size(); + const int n_points = 20; + + int k; + bool ok = true; + for (k = 0; k < nsp; k++) { + Species& s = sp[k]; + + if (s.valid <= 0) { + ok = false; + log << endl << "species " << s.name + << " contains an error." << endl; + } + if (!ok) return false; + } + + log << endl << " Checking that cp/R is positive... "; + + for (k = 0; k < nsp; k++) { + Species& s = sp[k]; + + // check that cp is positive + + cp0 = 0.0; + for (int j = 0; j < n_points; j++) { + t = j*(s.thigh - s.tlow)/(n_points - 1) + s.tlow; + + cp0 = cp(t, s); + if (cp0 < 0.0) { + log << endl << " error... Cp/R < 0 at T = " << t + << " for species " << s.name << endl; + s.valid = -1; + ok = false; + } + } + } + if (ok) log << "ok" << endl; + else return ok; + + + // check that S(tlow) > 0 + + log << " Checking that the species entropies are positive... "; + for (k = 0; k < nsp; k++) { + Species& s = sp[k]; + if (entropy(s.tlow, s) <= 0.0) { + log << endl << " error... negative entropy for species " + << s.name << endl; + s.valid = -1; + ok = false; + } + } + if (ok) log << "ok" << endl; + else return ok; + + log << " Checking that properties are continuous at the midpoint temperature... "; + for (k = 0; k < nsp; k++) { + Species& s = sp[k]; + + // check continuity at Tmid + t = s.tmid - dt; + cp0 = cp(t, s); + h0 = enthalpy(t, s) + cp0*dt; + s0 = entropy(t, s) + dt*cp0/t; + + t = s.tmid + dt; + cp1 = cp(t, s); + h1 = enthalpy(t, s) - cp1*dt; + s1 = entropy(t, s) - cp1*dt/t; + + if (absval((cp0 - cp1)/cp0) > tol) { + log << endl << "Warning... species " << s.name + << ": discontinuity in Cp at Tmid = " + << s.tmid << endl; + log << "Cp/R (low, high) = " << cp0 + << ", " << cp1 << endl; + ok = false; + } + + if (absval((h0 - h1)/h0) > tol) { + log << endl << "Warning... species " << s.name + << ": discontinuity in enthalpy at Tmid = " + << s.tmid << endl; + log << "h/R (low, high) = " + << h0 << ", " << h1 << endl; + ok = false; + } + + if (absval((s0 - s1)/s0) > tol) { + log << endl << "Warning... species " << s.name + << ": discontinuity in entropy at Tmid = " + << s.tmid << endl; + log << "s/R (low, high) = " + << s0 << ", " << s1 << endl; + ok = false; + } + } + if (ok) log << "ok \n\n\n"; + else log << "\n\n\n"; + + log << " Checking that cp is less that the high-temperature\n" + << " limiting value predicted by equipartition of energy.\n"; + log << " Note that this limit does not account for the electronic\n" + << " contribution to cp, and so may be violated in some cases." + << endl << endl; + + + for (k = 0; k < nsp; k++) { + Species& s = sp[k]; + + // check that cp at Tmax is less than the equipartion value + // This does not include any possible electronic contribution + + cp0 = cp(s.thigh, s); + int nel = s.elements.size(); + int i; + double na = 0.0; + for (i = 0; i < nel; i++) + if (s.elements[i].name != "E") na += s.elements[i].number; + int natoms = int(floor(na)); + double cpmax; + switch (natoms) { + case 1: cpmax = 2.5; break; + case 2: cpmax = 4.5; break; + default: cpmax = 3.0*natoms - 3.0; + } + + if (cp0 > cpmax) { + double over = 100.0*(cp0 - cpmax)/cpmax; + log << endl << "Warning... species " << s.name + << ": cp(Tmax) greater than equipartition value \nby " + << over << " percent."; + if ((natoms > 2) && (cp0 - cpmax < 0.5)) + log << endl << " (if molecule is linear, cp is ok)" + << endl; + } + } + + return valid(sp); +} + + + + /** + * Check that all reactions balance. + * @param speciesData species property dataset used to look up + * elemental compositions. + * @param r list of reactions to check + * @param unbalanced list of integers specifying reaction numbers of + * unbalanced reactions. + * @return true if all reactions balance + * @todo use reaction number stored in reaction object + */ + bool checkBalance(ostream& f, speciesTable& speciesData, + reactionList& r, vector& unbalanced) + { + int nrxn = r.size(); + string rname, pname; + vector elementSyms; + unsigned int m; + + unbalanced.clear(); + map atoms; + + for (int i = 0; i < nrxn; i++) + { + atoms.clear(); + int nr = r[i].reactants.size(); + int np = r[i].products.size(); + int j; + double stoichCoeff; + for (j = 0; j < nr; j++) + { + rname = r[i].reactants[j].name; + stoichCoeff = r[i].reactants[j].number; + vector& elements = speciesData[rname].elements; + for (m = 0; m < elements.size(); m++) + { + atoms[elements[m].name] -= stoichCoeff * elements[m].number; + } + } + for (j = 0; j < np; j++) + { + pname = r[i].products[j].name; + stoichCoeff = r[i].products[j].number; + vector& elements = speciesData[pname].elements; + for (m = 0; m < elements.size(); m++) + { + atoms[elements[m].name] += stoichCoeff * elements[m].number; + } + } + getMapKeys(atoms, elementSyms); + for (m = 0; m < elementSyms.size(); m++) { + if (atoms[elementSyms[m]] != 0.0) { + //cout << "unbalanced element: " + // << elementSyms[m] << " " + // << atoms[elementSyms[m]] << endl; + unbalanced.push_back(i+1); break; + } + } + } + return (unbalanced.empty()); + } + +} + + diff --git a/Cantera/src/converters/CKReader.h b/Cantera/src/converters/CKReader.h new file mode 100755 index 000000000..38a56eacb --- /dev/null +++ b/Cantera/src/converters/CKReader.h @@ -0,0 +1,93 @@ +/** + * @file CKReader.h + * + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CKR_CKRREADER_H +#define CKR_CKRREADER_H + +#ifdef WIN32 +#pragma warning(disable:4786) +#endif + +#include +#include +#include +#include +#include + +#include "CKParser.h" + +using namespace std; + +namespace ckr { + + +/** + * Chemkin file reader class. Class CKReader parses and validates a file + * containing a description of a chemical reaction mechanism in Chemkin + * format. See the Examples section for examples of how CKReader is + * used in user programs. + */ + +class CKReader { +public: + + /** + * Constructor. Construct a new CKReader instance. By default, + * validation is enabled, as well as verbose output to the log file. + */ + CKReader() : verbose(true), validate(true) {} + + /// Destructor. Does nothing. + ~CKReader() {} + + elementList elements; ///< a list of Element objects + speciesList species; ///< a list of Species objects + reactionList reactions; ///< a list of Reaction objects + groupList groups; ///< a list of Groups + speciesTable speciesData; ///< a map from species names to Species objects + ReactionUnits units; ///< reaction units + + /** + * Read and optionally validate a Chemkin input file. + * @param inputFile path to the input file. + * @param thermoDatabase path to the species thermodynamic property database. + * If no database is required, enter a null string. + * @param logFile file to write logging and error messages to. + * @return true if no errors encountered, false otherwise. + */ + bool read(const string& inputFile, + const string& thermoDatabase, const string& logFile); + + void write(string outputFile); ///< not implemented. + + bool verbose; ///< print detailed messages to log file + bool validate; ///< validate elements, species, and reaction + +private: + + // void validateElements(ostream& log); + bool validateSpecies(ostream& log); ///< validate the species. + bool validateReactions(ostream& log); ///< validate the reactions. + bool writeReactions(ostream& log); +}; + + +bool checkBalance(ostream& f, speciesTable& speciesData, reactionList& r, + vector& unbalanced); +bool checkThermo(ostream& f, speciesList& species, double tol); + +bool filter(const string& infile, const string& database, + const string& outfile, const vector& species, const vector& reactions); + +} + + +#endif + + + diff --git a/Cantera/src/converters/Constituent.h b/Cantera/src/converters/Constituent.h new file mode 100755 index 000000000..d8daf5d06 --- /dev/null +++ b/Cantera/src/converters/Constituent.h @@ -0,0 +1,31 @@ +/** + * @file Constituent.h + * + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CKR_CONSTITUENT_H +#define CKR_CONSTITUENT_H + +#include +#include +using namespace std; + +namespace ckr { + +/** + * A class for components of a composite object. The only members are + * a string identifying the component, and a double specifying the + * amount. + */ +class Constituent { +public: + string name; //!< The name of the object. + double number; //!< The number of units (molecules, etc.). +}; + +} + +#endif diff --git a/Cantera/src/converters/Element.h b/Cantera/src/converters/Element.h new file mode 100755 index 000000000..5ba352502 --- /dev/null +++ b/Cantera/src/converters/Element.h @@ -0,0 +1,101 @@ +/** + * @file Element.h + * + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CKR_ELEMENT_H +#define CKR_ELEMENT_H + +#include +#include + +using namespace std; + +namespace ckr { + +/** + * A class for elements. + * Example usage: + * @code + * Element e; + * e.name = "He"; + * e.atomicWeight = 4.0026; + * e.comment = "helium"; + * @endcode + */ +class Element { +public: + + /// Construct a new empty Element object + Element() : + name(""), + atomicWeight(0.0), + valid(0), + index(-1), + weightFromDB(false), + comment("") + {} + + + /// Construct a new empty Element object + Element(const string& nm, double wt) : + name(nm), + atomicWeight(wt), + valid(0), + index(-1), + weightFromDB(false), + comment("") + {} + + + /// Destructor + ~Element() {} + + string name; //!< Element name + double atomicWeight; //!< Atomic weight in amu + int valid; //!< flag returned by validation routines + int index; //!< index number + bool weightFromDB; //!< true if atomic weight is not specified + string comment; //!< comment in input file + + + /** + * Compare two Element instances for equality based on name. + * Primarily for internal use. + */ + bool operator==(const Element& e) const { + return (name == e.name); + } + bool operator!=(const Element& e) const { + return !(*this == e); + } + friend ostream& operator<<(ostream& s, const Element& e) { + s << e.name; + if (!e.weightFromDB) s << "/" << e.atomicWeight << "/"; + if (e.comment != "") + s << " !" << e.comment << endl; + else + s << " "; + return s; + } +}; + +/// a list (vector) of Elements +typedef vector elementList; + +} + + +#endif + + + + + + + + + diff --git a/Cantera/src/converters/Group.h b/Cantera/src/converters/Group.h new file mode 100755 index 000000000..6cb1ff504 --- /dev/null +++ b/Cantera/src/converters/Group.h @@ -0,0 +1,64 @@ +/** + * @file Element.h + * + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CKR_GROUP_H +#define CKR_GROUP_H + +#include +#include + +using namespace std; + +namespace ckr { + +/** + * A class for groups. + */ +class Group { +public: + + /// Construct a new empty Group object + Group() : name(""), index(-1) {} + + Group(const string& nm) : name(nm), index(-1) {} + + /// Destructor + ~Group() {} + + string name; //!< name + int index; //!< index number + map comp; //!< elemental composition + + /** + * Compare two Group instances for equality based on name. + * Primarily for internal use. + */ + bool operator==(const Group& g) const { + return (name == g.name); + } + bool operator!=(const Group& g) const { + return !(*this == g); + } +}; + +/// a list (vector) of Groups +typedef vector groupList; + +} + + +#endif + + + + + + + + + diff --git a/Cantera/src/converters/Makefile.in b/Cantera/src/converters/Makefile.in new file mode 100644 index 000000000..afb64ddbf --- /dev/null +++ b/Cantera/src/converters/Makefile.in @@ -0,0 +1,53 @@ +#/bin/sh +############################################################### +# $Author$ +# $Date$ +# $Revision$ +# +# Copyright 2002 California Institute of Technology +# +############################################################### + +SUFFIXES= +SUFFIXES= .cpp .d .o + +OBJDIR = . + +CXX_FLAGS = @CXXFLAGS@ $(CXX_OPT) + +# Temporarily removed 'filter.o', since it was causing a compile error on Mac OS X. +OBJS = ck2ctml.o atomicWeightDB.o CKParser.o CKReader.o Reaction.o ckr_utils.o thermoFunctions.o writelog.o + +CXX_INCLUDES = -I. -I.. +CONV_LIB = ./libconverters.a + +DEPENDS = $(OBJS:.o=.d) + +%.d: + g++ -MM $(CXX_INCLUDES) $*.cpp > $*.d + +.cpp.o: + @CXX@ -c $< $(CXX_FLAGS) $(CXX_INCLUDES) + +all: $(CONV_LIB) + +$(CONV_LIB): $(OBJS) + @ARCHIVE@ $(CONV_LIB) $(OBJS) + +clean: + $(RM) *.o *~ $(CONV_LIB) + +CKParser.o: CKParser.cpp + @CXX@ -c CKParser.cpp $(CXX_FLAGS) $(CXX_INCLUDES) -O0 + +depends: $(DEPENDS) + cat *.d > .depends + $(RM) $(DEPENDS) + +TAGS: + etags *.h *.cpp + +ifeq ($(wildcard .depends), .depends) +include .depends +endif + diff --git a/Cantera/src/converters/Reaction.cpp b/Cantera/src/converters/Reaction.cpp new file mode 100755 index 000000000..73a2dcd3c --- /dev/null +++ b/Cantera/src/converters/Reaction.cpp @@ -0,0 +1,175 @@ +/** + * @file Reaction.cpp + * + */ + +// Copyright 2001 California Institute of Technology + +// turn off warnings about truncating long names under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#endif + +#include "Reaction.h" +#include +#include + +namespace ckr { + + Reaction forwardReaction(const Reaction& rxn) { + Reaction r(rxn); + r.isReversible = false; + r.krev = RateCoeff(); + return r; + } + + Reaction reverseReaction(const Reaction& rxn) { + Reaction r(rxn); + if (rxn.isReversible && (r.krev.A > 0.0) ) { + r.isReversible = false; + r.products = rxn.reactants; + r.reactants = rxn.products; + r.kf = rxn.krev; + r.krev = RateCoeff(); + } + else { + r.reactants.clear(); + r.products.clear(); + } + return r; + } + + Reaction& Reaction::operator=(const Reaction& b) { + if (this == &b) return *this; + type = b.type; + reactants = b.reactants; + products = b.products; + thirdBody = b.thirdBody; + e3b = b.e3b; + kf = b.kf; + kf_aux = b.kf_aux; + krev = b.krev; + duplicate = b.duplicate; + falloffType = b.falloffType; + falloffParameters = b.falloffParameters; + otherAuxData = b.otherAuxData; + isFalloffRxn = b.isFalloffRxn; + isChemActRxn = b.isChemActRxn; + isThreeBodyRxn = b.isThreeBodyRxn; + isDuplicate = b.isDuplicate; + lines = b.lines; + number = b.number; + return *this; + } + + void Reaction::write(ostream& s) const { + int nl = lines.size(); + for (int nn = 0; nn < nl; nn++) { + s << lines[nn] << endl; + } +// int nr = reactants.size(); +// int np = products.size(); +// int n; +// double nu; +// for (n = 0; n < nr; n++) { +// nu = reactants[n].number; +// if (nu > 1) s << nu; +// s << reactants[n].name; +// if (n < nr - 1) +// s << " + "; +// else if (isThreeBodyRxn) +// s << " + " << thirdBody; +// else if (isFalloffRxn || isChemActRxn) +// s << " (+ " << thirdBody << ")"; +// } + +// if (isReversible) s << " = "; +// else s << "=>"; +// for (n = 0; n < np; n++) { +// nu = products[n].number; +// if (nu > 1) s << nu; +// s << products[n].name; +// if (n < np - 1) +// s << " + "; +// else if (isThreeBodyRxn) +// s << " + " << thirdBody; +// else if (isFalloffRxn || isChemActRxn) +// s << " (+ " << thirdBody << ")"; +// } +// char kfstr[100]; +// sprintf(kfstr, " %14.5g %4.2g %f", kf.A, kf.n, kf.E); +// s << kfstr << endl; + } + + +/** + * stoichiometric coefficient of species s in the reaction. Negative + * for reactants, positive for products, and zero if the species does + * not participate in the reaction. + */ + +double Reaction::stoichCoefficient(const string& s) const { + int k; + int nr = reactants.size(); + for (k = 0; k < nr; k++) + if (reactants[k].name == s) return -reactants[k].number; + int np = products.size(); + for (k = 0; k < np; k++) + if (products[k].name == s) return products[k].number; + return 0.0; +} + +/** + * used to find undeclared duplicate reactions. + * @todo could be made faster + */ +bool Reaction::operator==(const Reaction& r) const { + int nr = reactants.size(); + int np = products.size(); + if (int(r.reactants.size()) != nr || + int(r.products.size()) != np || r.thirdBody != thirdBody) return false; + + string nm; + map coeffs; + for (int ir = 0; ir < nr; ir++) { + coeffs[reactants[ir].name] = -reactants[ir].number; + } + for (int ip = 0; ip < np; ip++) { + coeffs[products[ip].name] = products[ip].number; + } + for (int jr = 0; jr < nr; jr++) { + nm = r.reactants[jr].name; + if (coeffs[nm] == 0.0) return false; + coeffs[nm] /= -r.reactants[jr].number; + } + for (int jp = 0; jp < np; jp++) { + nm = r.products[jp].name; + if (coeffs[nm] == 0.0) return false; + coeffs[nm] /= products[jp].number; + } + int nc = coeffs.size(); + vector ratios; + getMapValues(coeffs, ratios); + + if (!isReversible && ratios[0] < 0.0) return false; + + for (int ic = 0; ic < nc; ic++) { + if (ratios[ic] != ratios[0]) return false; + } + return true; +} + +} + + + + + + + + + + + + + diff --git a/Cantera/src/converters/Reaction.h b/Cantera/src/converters/Reaction.h new file mode 100755 index 000000000..ec2cf564c --- /dev/null +++ b/Cantera/src/converters/Reaction.h @@ -0,0 +1,258 @@ +/** + * @file Reaction.h + * + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CKR_REACTION_H +#define CKR_REACTION_H + +#include +#include +#include +using namespace std; + +#include "ckr_defs.h" +#include "ckr_utils.h" +#include "RxnSpecies.h" + + +namespace ckr { + + + /** @name Reaction Types + */ + + //@{ + const int Elementary = 2000; ///< elementary, pressure-independent reaction + const int ThreeBody = 2001; ///< three-body reaction + const int Falloff = 2002; ///< falloff reaction + const int ChemAct = 2003; ///< chemical activation reaction + +#ifdef ENABLE_PLASMA_REACTIONS + const int CrossSection = 2004; ///< momentum transfer cross section + const int CollisionFreq = 2005; ///< momentum transfer collision frequency +#endif + //@} + + /** + * Reaction rate coefficient class. For simplicity, the RateCoeff + * class has public members representing the parameters of all rate + * coefficient types supported by Chemkin. The 'type' attribute + * specifies the rate coefficient type. + */ + class RateCoeff { + public: + + /** + * Constructor. Construct a default rate coefficient object. The + * type is set to Arrhenius, and all parameter values are set to + * zero. + */ + RateCoeff() : A(0.0), n(0.0), E(0.0), + B(0.0), C(0.0), type(Arrhenius) {} + + /** + * Copy constructor + */ + RateCoeff(const RateCoeff& k) : A(k.A), n(k.n), E(k.E), + B(k.B), C(k.C), type(k.type), b(k.b) {} + + /// Destructor. Does nothing. + ~RateCoeff() {} + + RateCoeff& operator=(const RateCoeff& k) { + if (this == &k) return *this; + A = k.A; + n = k.n; + E = k.E; + B = k.B; + C = k.C; + type = k.type; + b = k.b; + return *this; + } + + // Modified Arrhenius parameters, common to all types. + double A; ///< pre-exponential factor (all types) + double n; ///< temperature exponent (all types) + double E; ///< activation energy (all types) + + // Landau-Teller parameters + double B; ///< Landau-Teller B parameter + double C; ///< Landau-Teller C parameter + + int type; ///< rate coefficient type + + // Coefficients for the special forms allowed by Chemkin-III + vector_fp b; ///< coefficients for JAN or FIT1 form + + }; + + + ////////////////////////////////////////////////////////////////////////// + + /** + * Specifies the units for all reactions. + */ + + class ReactionUnits { + public: + int ActEnergy; ///< Activation energy unit flag + int Quantity; ///< Moles or molecules unit flag + }; + + + ////////////////////////////////////////////////////////////////////////// + + + /// A class for reactions. + + class Reaction { + public: + + /// a list of auxiliary data values + typedef vector_fp auxdata; + + /// Construct an empty Reaction object + Reaction() : type(Elementary), + isFalloffRxn(false), + isChemActRxn(false), + isThreeBodyRxn(false), + isReversible(false), + isDuplicate(false), + duplicate(0), + thirdBody(""), + number(0), + falloffType(Lindemann) {} + + /// Copy constructor + Reaction(const Reaction& r) : type(r.type), + isFalloffRxn(r.isFalloffRxn), + isChemActRxn(r.isChemActRxn), + isThreeBodyRxn(r.isThreeBodyRxn), + isReversible(r.isReversible), + isDuplicate(r.isDuplicate), + duplicate(r.duplicate), + thirdBody(r.thirdBody), + number(r.number), + reactants(r.reactants), + products(r.products), + e3b(r.e3b), + kf(r.kf), + kf_aux(r.kf_aux), + krev(r.krev), + falloffType(r.falloffType), + falloffParameters(r.falloffParameters), + otherAuxData(r.otherAuxData), + lines(r.lines) {} + + /// Destructor + virtual ~Reaction() {} + + Reaction& operator=(const Reaction& r); + + int type; ///< Reaction type. + + bool isFalloffRxn; ///< True if reaction is a falloff reaction. + bool isChemActRxn; ///< True if reaction is a chemical activation reaction. + bool isThreeBodyRxn; ///< True if reaction is a three-body reaction. + bool isReversible; ///< True if reaction is reversible. + bool isDuplicate; ///< True if reaction is declared to be a duplicate; + + /** + * reaction number this one is a duplicate to (declared or not). + * If the reaction is not a duplicate, the value is zero. + */ + int duplicate; + + /** + * For pressure-dependent reactions (including three-body ones) + * this string contains either "M" if all species may act as + * third body collision partners, or a species name if only + * one species does. + */ + string thirdBody; + + /// Reaction number. + int number; + + + /** + * list of species that participate as reactants, + * and their stoichiometric coefficients + */ + vector reactants; + + /** + * list of species that participate as products, + * and their stoichiometric coefficients + */ + vector products; + + + /** + * map from species names to enhanced third-body collision efficiencies + */ + mutable map e3b; + + /** + * Forward rate coefficient. For falloff reactions, this is the + * high-pressure rate coefficient, and for chemical activation + * reactions it is the low-pressure one. + */ + RateCoeff kf; + + /** + * For pressure-dependent reactions, the rate coefficient for the + * opposite pressure limit as kf ( + */ + RateCoeff kf_aux; + + /// Reverse rate coefficient. Empty unless REV auxiliary data given. + RateCoeff krev; + + + int falloffType; + vector_fp falloffParameters; + + /** + * auxiliary data not handled elsewhere. + */ + mutable map otherAuxData; + + /** + * input file lines + */ + vector lines; + + // methods + + double stoichCoefficient(const string& s) const; + bool operator==(const Reaction& r) const; + void write(ostream& s) const; + + }; + + /// a list of Reaction objects + typedef vector reactionList; + + Reaction forwardReaction(const Reaction& rxn); + Reaction reverseReaction(const Reaction& rxn); +} +/** + * @file Reaction.h + * Definitions of reaction-related classes. + * @author California Institute of Technology, Caltech + */ + + + +#endif + + + + + diff --git a/Cantera/src/converters/RxnSpecies.h b/Cantera/src/converters/RxnSpecies.h new file mode 100755 index 000000000..1725ebc33 --- /dev/null +++ b/Cantera/src/converters/RxnSpecies.h @@ -0,0 +1,37 @@ +/** + * @file RxnSpecies.h + * + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CKR_RXNSPECIES_H +#define CKR_RXNSPECIES_H + +#include +#include +//#include "Cantera.h" + +using namespace std; + +namespace ckr { + + typedef vector_int group_t; + typedef vector grouplist_t; + + +/** + * A class for species in a reaction. + * + */ +class RxnSpecies { +public: + string name; //!< The name of the object. + double number; //!< The number of units (molecules, etc.). + grouplist_t groups; +}; + +} + +#endif diff --git a/Cantera/src/converters/Species.h b/Cantera/src/converters/Species.h new file mode 100755 index 000000000..da2facbc8 --- /dev/null +++ b/Cantera/src/converters/Species.h @@ -0,0 +1,117 @@ +/** + * @file Species.h + * + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CKR_SPECIES_H +#define CKR_SPECIES_H + +#include "ckr_defs.h" +#include "Constituent.h" +#include +#include + +//#include "Cantera.h" + +using namespace std; + +namespace ckr { + +/** + * Holds species data read in from entries in the THERMO section of + * the input file. + */ +class Species { +public: + + /// Construct an empty Species object + Species() : + name (""), + id (""), + phase (""), + tlow(0.0), + tmid(0.0), + thigh(0.0), + valid(0), + index(-1) + {} + + /// Destructor + ~Species() {} + + /// Assignment operator + Species& operator=(const Species& s) { + if (&s == this) return *this; + name = s.name; + id = s.id; + phase = s.phase; + tlow = s.tlow; + tmid = s.tmid; + thigh = s.thigh; + elements = s.elements; + comp = s.comp; + lowCoeffs = s.lowCoeffs; + highCoeffs = s.highCoeffs; + valid = s.valid; + index = s.index; + return *this; + } + + /// Test for equality based on name only. + bool operator==(const Species& s) const { + return (s.name == name); + } + + bool operator!=(const Species& s) const { + return !(*this == s); + } + + /// Used to sort lists of species by index number. + bool operator<(const Species& s) const { + return (index < s.index); + } + + + string name; //!< Species name + string id; //!< ID tag from 'date' field in input + string phase; //!< Phase string. Usually "G", "L", or "S". + double tlow; //!< Min temperature for thermo data fit + double tmid; //!< Mid temperature for thermo data fit + double thigh; //!< Max temperature for thermo data fit + + /// list of Constituent objects defining elemental composition + vector elements; + + /// map from element symbols to atom numbers + mutable map comp; + + /// polynomial coefficients for the lower temperature range + vector_fp lowCoeffs; + + /// polynomial coefficients for the upper temperature range + vector_fp highCoeffs; + + /// flag set by the validation routines + int valid; + + /// position in the list of species in the input file + int index; +}; + +/// A list of Species +typedef vector speciesList; + +/// A map from species names to Species objects +typedef map speciesTable; + +} + +#endif + + + + + diff --git a/Cantera/src/converters/atomicWeightDB.cpp b/Cantera/src/converters/atomicWeightDB.cpp new file mode 100755 index 000000000..33980d7fe --- /dev/null +++ b/Cantera/src/converters/atomicWeightDB.cpp @@ -0,0 +1,126 @@ +/** + * @file atomicWeightsDB.cpp + * + * internal database of default atomic weights + * + */ + +// Copyright 2001 California Institute of Technology + + +// turn off warnings about truncating long names under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#endif + +//#include "../../config.h" +#include +//#include "../Cantera/src/ctmap.h" +#include +#include +using namespace std; + +namespace ckr { + + static double _weights[] = { + 1.00797, 4.0026, 6.939, 9.01220, 10.811, // H - B + 12.01115, 14.0067, 15.9994, 18.9984, 20.183, 22.9898, // C - Na + 24.312, 26.9815, 28.086, 30.9738, 32.064, // Mg - S + 35.453, 39.948, 39.102, 40.08, 44.956, // Cl - Sc + 47.9, 50.942, 51.996, 54.938, 55.847, // Ti - Fe + 58.9332, 58.71, 63.54, 65.37, 69.72, // Co - Ga + 72.59, 74.9216, 78.96, 79.9009, 83.8, // Ge - Kr + 85.47, 87.62, 88.905, 91.22, 92.9064, // Rb - Nb + 95.94, 98, 101.07, 102.906, 106.42, // Mo - Pd + 107.868, 112.41, 114.82, 118.71, 121.75, // Ag - Sb + 127.6, 126.905, 131.29, 132.905, 137.33, // Te - Ba + 138.906, 140.12, 140.908, 144.24, 145, // La - Pm + 150.36, 151.96, 157.25, 158.925, 162.5, // Sm - Dy + 164.93, 167.26, 168.934, 173.04, 174.967, // Ho - Lu + 178.49, 180.948, 183.85, 186.207, 190.2, // Hf - Os + 192.22, 195.08, 196.967, 200.59, 204.383, // Ir - Tl + 207.2, 208.98, 209, 210, 222, // Pb - Rn + 223, 226.025, 227.028, 232.038, 231.036, // Fr - Pa + 238.029, 237.048, 244, 243, 247, // U - Cm + 247, 251, 252, 257, 258, // Bk - Md + 259, 269, 2.0141, 5.45e-4, -1.0 // No - E + }; + + + + static char _symbols[][3] = { + "H", "He", "Li", "Be", "B", + "C", "N", "O", "F", "Ne", "Na", + "Mg", "Al", "Si", "P", "S", + "Cl", "Ar", "K", "Ca", "Sc", + "Ti", "V", "Cr", "Mn", "Fe", + "Co", "Ni", "Cu", "Zn", "Ga", + "Ge", "As", "Se", "Br", "Kr", + "Rb", "Sr", "Y", "Zr", "Nb", + "Mo", "Tc", "Ru", "Rh", "Pd", + "Ag", "Cd", "In", "Sn", "Sb", + "Te", "I", "Xe", "Cs", "Ba", + "La", "Ce", "Pr", "Nd", "Pm", + "Sm", "Eu", "Gd", "Tb", "Dy", + "Ho", "Er", "Tm", "Yb", "Lu", + "Hf", "Ta", "W", "Re", "Os", + "Ir", "Pt", "Au", "Hg", "Tl", + "Pb", "Bi", "Po", "At", "Rn", + "Fr", "Ra", "Ac", "Th", "Pa", + "U", "Np", "Pu", "Am", "Cm", + "Bk", "Cf", "Ei", "Fm", "Md", + "No", "Lw", "D", "E", "!" }; + + + + /** + * Get table of atomic weights from the internal database. + * @param weights atomic symbol -> atomic weight map + * + * Example usage: + * @code + * #include "atomicWeightDB.h" + * ... + * map atw; + * getDefaultAtomicWeights(atw); + * double copperAtomicWeight = atw["Cu"]; + * ... + * @endcode + * Note that if the atomic weight is requested for an unknown + * element symbol, the value zero will be returned. + */ + //void getDefaultAtomicWeights(ct::ctmap_sd& weights) { + void getDefaultAtomicWeights(map& weights) { + + // erase existing entries, if any + //weights.clear(); + const int MAX_NUM = 200; + int n; + for (n = 0; n < MAX_NUM; n++) { + if (_symbols[n][0] == '!') break; + weights[_symbols[n]] = _weights[n]; + } + } + + void writeKnownElements(ostream& s, string fmt) { + + const int MAX_NUM = 200; + int n; + if (fmt == "CK") { + for (n = 0; n < MAX_NUM; n++) { + if (_symbols[n][0] == '!') break; + s << " " << string(_symbols[n]) << "/" << _weights[n] << "/" << endl; + } + } + else if (fmt == "XML") { + s << "" << endl; + for (n = 0; n < MAX_NUM; n++) { + if (_symbols[n][0] == '!') break; + s << " " << _symbols[n] << "" + << _weights[n] << "" << endl; + } + s << "" << endl; + } + } +} + diff --git a/Cantera/src/converters/ck2ctml.cpp b/Cantera/src/converters/ck2ctml.cpp new file mode 100755 index 000000000..9b2df24c9 --- /dev/null +++ b/Cantera/src/converters/ck2ctml.cpp @@ -0,0 +1,556 @@ +/** + * @file ck2ctml.cpp + * + * Convert CK-format reaction mechanism files to CTML format. + * + */ +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include +#include +//#include +using namespace std; + +#include "CKReader.h" +#include "Reaction.h" +#include "writelog.h" + + +#include "xml.h" +#include "ck2ctml.h" + +//using namespace Cantera; + +namespace ctml { + + struct trdata { + trdata() {name = "-";} + string name; + int geom; + doublereal welldepth, diam, dipole, polar, rot; + }; + + // add a NASA polynomial parameterization + static void addNASA(XML_Node& node, + const vector_fp& low, const vector_fp& high, + doublereal minx, doublereal midx, + doublereal maxx) { + XML_Node& f = node.addChild("NASA"); + if (minx != -999.0) f.addAttribute("Tmin",minx); + if (maxx != -999.0) f.addAttribute("Tmid",midx); + if (maxx != -999.0) f.addAttribute("Tmax",maxx); + addFloatArray(f,"low",low.size(),low.begin()); + addFloatArray(f,"high",high.size(),high.begin()); + } + + static void addShomate(XML_Node& node, + const vector_fp& low, const vector_fp& high, + doublereal minx, doublereal midx, + doublereal maxx) { + XML_Node& f = node.addChild("Shomate"); + if (minx != -999.0) f.addAttribute("Tmin",minx); + if (maxx != -999.0) f.addAttribute("Tmid",midx); + if (maxx != -999.0) f.addAttribute("Tmax",maxx); + addFloatArray(f,"low",low.size(),low.begin()); + addFloatArray(f,"high",high.size(),high.begin()); + } + + + static void addArrhenius(XML_Node& node, + doublereal A, doublereal b, doublereal E, int order, + string unitsys, string E_units) { + string abe = fp2str(A)+" "+fp2str(b)+" "+fp2str(E); + XML_Node& r = node.addChild("Arrhenius",abe); + r.addAttribute("order",order); + } + + static void addRateCoeff(XML_Node& node, string title, string type, + string direction, int order, doublereal A, doublereal b, doublereal E, + string unitsys, string E_units) { + XML_Node& r = node.addChild("rateCoeff"); + + r.addAttribute("id",title); + if (type == "Arrhenius") + addArrhenius(r, A, b, E, order, unitsys, E_units); + r.addAttribute("direction",direction); + } + + static void addFalloff(XML_Node& node, string type, + const vector_fp& params) { + int np = params.size(); + string p; + for (int n = 0; n < np; n++) p += " "+fp2str(params[n])+" "; + XML_Node& f = node.addChild("falloff",p); + f.addAttribute("type",type); + } + + static void addTroeFalloff(XML_Node& node, const vector_fp& params) { + XML_Node& f = node.addChild("falloff"); + f.addAttribute("type","Troe"); + addFloat(f,"A",params[0]); + addFloat(f,"T***",params[1]); + addFloat(f,"T*",params[2]); + if (params.size() == 4) + addFloat(f,"T**",params[3]); + } + + static void addSRIFalloff(XML_Node& node, const vector_fp& params) { + XML_Node& f = node.addChild("falloff"); + f.addAttribute("type","SRI"); + addFloat(f,"A",params[0]); + addFloat(f,"B",params[1]); + addFloat(f,"C",params[2]); + if (params.size() == 5) { + addFloat(f,"D",params[3]); + addFloat(f,"E",params[4]); + } + } + + static void addElement(XML_Node& node, string idtag, const ckr::Element& el) { + XML_Node& elx = node.addChild("element"); + elx.addAttribute("id",idtag+"_e_"+el.name); + string elnm = el.name; + elnm[0] = toupper(elnm[0]); + if (el.name.size() == 2) elnm[1] = tolower(elnm[1]); + elx.addAttribute("name",elnm); + elx.addAttribute("atomicWt",el.atomicWeight); + //addFloat(elx, "mass", el.atomicWeight, "amu"); + //addString(elx, "elementSymbol", el.name); + } + + /** + * addSpecies(): + * + * Add a species element to an XML description of a mechanism + * + * Input + * -------- + * node : Reference to the current parent node, where the + * species description is going to be placed. + */ + static void addSpecies(XML_Node& node, string idtag, const ckr::Species& sp) { + string spname = sp.name; + node.addComment(spname); + XML_Node& spx = node.addChild("species"); + spx.addAttribute("id",idtag+"_s_"+sp.name); + spx.addAttribute("name",sp.name); + //spx.addAttribute("phaseType",sp.phase); + if (stripws(sp.id) != "") spx.addChild("note",sp.id); + //addString(spx,"comment","ideal gas"); + int nel = sp.elements.size(); + int m, num; + string nm, str=""; + for (m = 0; m < nel; m++) { + /* + * Copy the element name into the string, nm. Lower case the + * second letter, if needed. + */ + nm = sp.elements[m].name; + nm[0] = toupper(nm[0]); + if (nm.size() == 2) nm[1] = tolower(nm[1]); + /* + * Obtain the current number of atoms in the species. + * Linearize the number (HKM question? can we employ real values here + * instead?) + */ + num = int(sp.elements[m].number); + /* + * Add the name and number to end of the string, str + */ + str += " "+nm+":"+int2str(num)+" "; + } + /* + * Add the child element, atomArray, to the species xml node. + */ + spx.addChild("atomArray", str); + + XML_Node& cp1 = spx.addChild("thermo"); + addNASA(cp1, sp.lowCoeffs, sp.highCoeffs, + sp.tlow, sp.tmid, sp.thigh); + } + + static void addReaction(XML_Node& node, string idtag, int i, + const ckr::Reaction& rxn, + const ckr::ReactionUnits& runits, doublereal version) { + + node.addComment(idtag+" reaction "+int2str(i+1)); + string eqn = ckr::reactionEquation(rxn); + int eqlen = eqn.size(); + for (int nn = 0; nn < eqlen; nn++) { + if (eqn[nn] == '<') eqn[nn] = '['; + if (eqn[nn] == '>') eqn[nn] = ']'; + } + // node.addComment(eqn); + XML_Node& r = node.addChild("reaction"); + r.addAttribute("id",idtag+"_rxn_"+int2str(i+1)); + r.addChild("equation", eqn); + + string e_unit; + int eunit = runits.ActEnergy; + if (eunit == ckr::Cal_per_Mole) + e_unit = "cal/mol"; + else if (eunit == ckr::Kcal_per_Mole) + e_unit = "kcal/mol"; + else if (eunit == ckr::Joules_per_Mole) + e_unit = "J/mol"; + else if (eunit == ckr::Kjoules_per_Mole) + e_unit = "kJ/mol"; + else if (eunit == ckr::Kelvin) + e_unit = "K"; + else if (eunit == ckr::Electron_Volts) + e_unit = "eV"; + + int nr = rxn.reactants.size(); + int np = rxn.products.size(); + + int n; + doublereal order = 0.0; + + string rct="", prd=""; + for (n = 0; n < nr; n++) { + //XML_Node& reac = r.addChild("reactant"); + //reac.addAttribute("name",rxn.reactants[n].name); + rct += (" " + rxn.reactants[n].name + ":" + + int2str((int) rxn.reactants[n].number) + " "); + //reac.addAttribute("phase",idtag); + doublereal nn = rxn.reactants[n].number; + order += nn; + } + r.addChild("reactants",rct); + //if (nn != 1) addInteger(reac, "number", int(nn)); + + // reac.addAttribute("phase",idtag); + for (n = 0; n < np; n++) { + prd += (" " + rxn.products[n].name + ":" + + int2str((int) rxn.products[n].number) + " "); + //doublereal nn = rxn.products[n].number; + //prod.addAttribute("name",rxn.products[n].name); + //if (nn != 1) addInteger(prod, "number", int(nn)); + } + r.addChild("products",prd); + + if (rxn.isChemActRxn || rxn.isThreeBodyRxn) order += 1.0; + + + XML_Node& kf = r.addChild("rateCoeff"); + kf.addAttribute("units","mol,cm,s"); + kf.addAttribute("Eunits",e_unit); + + //kf.addAttribute("id",r["id"]+"_kf"); + if (rxn.kf.type == ckr::Arrhenius) + addArrhenius(kf, rxn.kf.A, rxn.kf.n, rxn.kf.E, + int(order), "mol,cm,s", e_unit); + + if (rxn.isFalloffRxn) { + addArrhenius(kf, rxn.kf_aux.A, rxn.kf_aux.n, rxn.kf_aux.E, + int(order+1), "mol,cm,s", e_unit); + + if (rxn.falloffType == ckr::Lindemann) + addFalloff(kf,"Lindemann",rxn.falloffParameters); + else if (rxn.falloffType == ckr::Troe) + addFalloff(kf,"Troe",rxn.falloffParameters); + else if (rxn.falloffType == ckr::SRI) + addFalloff(kf,"SRI",rxn.falloffParameters); + else + throw CanteraError("addReaction","unknown falloff type"); + } + + int ne = rxn.e3b.size(); + if (rxn.thirdBody != "") { + if (rxn.thirdBody != "M") { + XML_Node& e3b = kf.addChild("efficiencies",rxn.thirdBody+":1.0"); + e3b.addAttribute("default",0.0); + //addFloat(e3b, rxn.thirdBody, 1.0); + } + else if (ne > 0.0) { + map::const_iterator b = rxn.e3b.begin(), + e = rxn.e3b.end(); + string estr = ""; + for (; b != e; ++b) { + estr += " "+b->first+":"+fp2str(b->second)+" "; + //addFloat(e3b,b->first,b->second); + } + estr += "\n"; + XML_Node& e3b = kf.addChild("efficiencies",estr); + e3b.addAttribute("default",1.0); + } + } + + if (rxn.isReversible) + r.addAttribute("reversible","yes"); + else + r.addAttribute("reversible","no"); + //addBool(r,"reversible",rxn.isReversible); + + if (rxn.duplicate != 0) + r.addChild("duplicate","idtag_rxn_"+int2str(rxn.duplicate)); + // addString(r, "duplicate","reaction_"+int2str(rxn.duplicate)); + + if (rxn.isFalloffRxn) + r.addAttribute("type","falloff"); + if (rxn.isChemActRxn) + r.addAttribute("type","chemAct"); + if (rxn.isThreeBodyRxn) + r.addAttribute("type","threeBody"); + } + + static void addState(XML_Node& phase, string x) { + XML_Node& state = phase.addChild("state"); + XML_Node& temp = state.addChild("temperature",300.0); + temp.addAttribute("units","K"); + XML_Node& pres = state.addChild("pressure",1.0); + pres.addAttribute("units","atm"); + state.addChild("moleFractions",x+":1.0"); + } + + /*! + * addTransport() searches a transport database, pointed to by + * the istream, s, + * for the species names listed in node. It then adds the + * pertinent transport properties to the XML_Node database + * pointed to by node. + */ + static void addTransport(istream& s, XML_Node& node) { + /* + * The first thing we will do is to read the entire transport + * database and place its contents into a map structure, + * indexed by the name of the species. + */ + map indx; + string rest; + while (! s.eof()) { +#ifdef USE_STRINGSTREAM + /* + * Read a line from the file + */ + getline(s, rest); + /* + * In the transport database, we allow comment lines that + * consist of '#' and '!' as the first character in the + * in the line. We also don't bother to parse short lines that + * can't possibly have enough data in them to comprise a + * properly formatted record. + */ + if (rest[0] != '#' && rest[0] != '!' && rest.size() > 5) { + /* + * copy the string into a stringstream and parse the line + * into the trdata object + */ + std::istringstream ioline(rest); + trdata t; + ioline >> t.name >> t.geom >> t.welldepth >> t.diam + >> t.dipole >> t.polar >> t.rot; + /* + * Add the trdata object into the map database by making a + * copy of it, and index it by the species name. + */ + if (t.name != "") { + indx[t.name] = t; + } + } +#else + trdata t; + s >> t.name >> t.geom >> t.welldepth >> t.diam + >> t.dipole >> t.polar >> t.rot; + if (t.name != "") { + indx[t.name] = t; + } +#endif + } + + vector sp; + node.getChildren("species",sp); + int ns = sp.size(); + for (int n = 0; n < ns; n++) { + XML_Node& spx = *sp[n]; + string nm = spx["name"]; + trdata t = indx[nm]; + if (t.name == "-") { + throw CanteraError("addTransport", + "no transport data for species "+nm); + } + XML_Node& tr = spx.addChild("transport"); + + switch (t.geom) { + case 0: + addString(tr,"geometry","atom"); break; + case 1: + addString(tr,"geometry","linear"); break; + case 2: + addString(tr,"geometry","nonlinear"); break; + default: ; + } + if (t.welldepth != 0.0) + addFloat(tr,"LJ_welldepth",t.welldepth,"Kelvin"); + if (t.diam != 0.0) + addFloat(tr,"LJ_diameter",t.diam,"A"); + if (t.dipole != 0.0) + addFloat(tr,"dipoleMoment",t.dipole,"Debye"); + if (t.polar != 0.0) + addFloat(tr,"polarizability",t.polar,"A^3"); + if (t.rot != 0.0) + addFloat(tr,"rotRelax",t.rot); + } + } + + + /*! + * This routine is the main routine. It + * + * @param r reference to a ckreader object that has already read a chemkin formatted + * mechanism. This is the input to the routine. + * @param root Reference to the root node of an XML description of the + * mechanism. The node will be filled up with the description + * of the mechanism. This is the output to the routine. + */ + void ck2ctml(string idtag, ckr::CKReader& r, XML_Node& root) { + + popError(); + doublereal version = 1.3; + + XML_Node& ph = root.addChild("phase"); + ph.addAttribute("id",idtag); + + addState(ph, r.species[0].name); + + XML_Node& eos = ph.addChild("thermo"); + eos.addAttribute("model","IdealGas"); + + string enames; + int nel = r.elements.size(); + int i; + map emap; + string elnm; + for (i = 0; i < nel; i++) { + elnm = r.elements[i].name; + elnm[0] = toupper(elnm[0]); + if (elnm.size() == 2) elnm[1] = tolower(elnm[1]); + emap[r.elements[i].name] = elnm; + enames += " "+elnm+" "; + //addElement(earray, idtag, r.elements[i]); + } + XML_Node& earray = ph.addChild("elementArray",enames); + earray.addAttribute("datasrc","elements.xml"); + + string spnames = ""; + root.addComment("species data"); + XML_Node& spdata = root.addChild("speciesData"); + spdata.addAttribute("id",idtag+"_species_data"); + int nsp = r.species.size(); + for (i = 0; i < nsp; i++) { + spnames += " "+r.species[i].name+" "; + if ((i+1) % 10 == 0) spnames += "\n"; + addSpecies(spdata, idtag, r.species[i]); + } + XML_Node& sparray = ph.addChild("speciesArray",spnames+"\n"); + sparray.addAttribute("datasrc","#"+idtag+"_species_data"); + //sparray.addAttribute("database",idtag+"_species_data"); + + XML_Node& rxns = ph.addChild("reactionArray"); + rxns.addAttribute("datasrc","#"+idtag+"_rxn_data"); + //rxns.addAttribute("datasrc",idtag+"_rxn_data"); + XML_Node& incl = rxns.addChild("include"); + XML_Node& ktype = ph.addChild("kinetics"); + ktype.addAttribute("model","GasKinetics"); + + root.addComment("reaction data"); + XML_Node& kin = root.addChild("reactionData"); + kin.addAttribute("id",idtag+"_rxn_data"); + + int nrxns = r.reactions.size(); + incl.addAttribute("prefix",idtag+"_rxn_"); + + int irxn = 0; + string idktag = idtag; + for (i = 0; i < nrxns; i++) { + + // if krev.A is non-zero, then the reverse rate coefficient is + // being explicitly specified rather than being computed from + // thermochemistry. In this case, convert the reaction into + // two irreversible reactions. + + if (r.reactions[i].krev.A != 0.0) { + addReaction(kin, idktag, irxn, + ckr::forwardReaction(r.reactions[i]), r.units, version); + irxn++; + addReaction(kin, idktag, irxn, + ckr::reverseReaction(r.reactions[i]), r.units, version); + irxn++; + } + + // Otherwise, just add the whole reaction, which may or may + // not be reversible. + else { + addReaction(kin, idktag, irxn, r.reactions[i], + r.units, version); + irxn++; + } + } + incl.addAttribute("min",1); + incl.addAttribute("max", irxn); + } + + + int convert_ck(const char* in_file, const char* db_file, + const char* tr_file, const char* out_file, const char* id_tag) { + ckr::CKReader r; + r.validate = true; + int i=1; + + string infile = string(in_file); + string dbfile = string(db_file); + string trfile = string(tr_file); + string outfile = string(out_file); + string idtag = string(id_tag); + string logfile; + if (dbfile == "-") dbfile = ""; + if (trfile == "-") trfile = ""; + + try { + + logfile = "ck2ctml.log"; + if (!r.read(infile, dbfile, logfile)) { + throw CanteraError("convert_ck", + "error encountered in input file " + string(infile) + + "\nsee file ck2ctml.log for more information.\n"); + } + + XML_Node root("ctml"); + root.addComment("generated from "+infile+" by ck2ctml."); + if (trfile != "") + root.addComment("transport data from "+trfile+"."); + + ck2ctml(idtag, r, root); + + if (trfile != "") { + ifstream ftr(trfile.c_str()); + XML_Node& sparray = *root.findByName("speciesData"); + addTransport(ftr, sparray); + ftr.close(); + } + + if (outfile == "") { + root.writeHeader(cout); + root.write(cout); + } + else { + ofstream ff(outfile.c_str()); + root.writeHeader(ff); + root.write(ff); + ff.close(); + cout << "CTML file " << outfile << " written." << endl; + } + } + catch (CanteraError) { + return -1; + } + + return 0; + } + +} + + diff --git a/Cantera/src/converters/ck2ctml.h b/Cantera/src/converters/ck2ctml.h new file mode 100755 index 000000000..86668b1f0 --- /dev/null +++ b/Cantera/src/converters/ck2ctml.h @@ -0,0 +1,57 @@ +#ifndef CT_CK2CTML_H +#define CT_CK2CTML_H + +#include +#include + +#include "ctml.h" + +namespace ckr{ + class CKReader; +} + +namespace ctml { + + +// void addNASA(XML_Node& node, +// const vector_fp& low, const vector_fp& high, +// doublereal minx=-999.0, doublereal midx=-999.0, +// doublereal maxx=-999.0); + +// void addShomate(XML_Node& node, +// const vector_fp& low, const vector_fp& high, +// doublereal minx=-999.0, doublereal midx=-999.0, +// doublereal maxx=-999.0); + +// void addArrhenius(XML_Node& node, +// doublereal A, doublereal b, doublereal E, int order, +// string unitsys, string E_units); + +// void addRateCoeff(XML_Node& node, string title, string type, +// string direction, int order, doublereal A, doublereal b, +// doublereal E, string unitsys, string E_units); + +// void addTroeFalloff(XML_Node& node, const vector_fp& params); + +// void addSRIFalloff(XML_Node& node, const vector_fp& params); + +// void addElement(XML_Node& node, string idtag, const ckr::Element& el); + +// void addSpecies(XML_Node& node, string idtag, const ckr::Species& sp); + +// void addReaction(XML_Node& node, string idtag, int i, +// const ckr::Reaction& rxn, const ckr::ReactionUnits& runits, +// doublereal version); + + // void addTransport(istream& s, XML_Node& node); + + void ck2ctml(string idtag, ckr::CKReader& r, + XML_Node& root); + + int convert_ck(const char* in_file, const char* db_file, + const char* tr_file, const char* out_file, const char* id_tag); + +} + +#endif + diff --git a/Cantera/src/converters/ckr_defs.h b/Cantera/src/converters/ckr_defs.h new file mode 100755 index 000000000..faae6864d --- /dev/null +++ b/Cantera/src/converters/ckr_defs.h @@ -0,0 +1,96 @@ +/** + * @file ckr_defs.h + * + */ + +// Copyright 2001 California Institute of Technology + + + +#ifndef CKR_DEFS_H +#define CKR_DEFS_H + +//#include "config.h" +#include +#include +#include +using namespace std; + +#include "ctvector.h" + +/// the namespace for the CKReader packaage +namespace ckr { + + typedef ct::ctvector_fp vector_fp; + typedef ct::ctvector_int vector_int; + //typedef vector vector_fp; + + // exceptions + class CK_Exception { + public: + CK_Exception() { + m_msg = ""; + } + virtual ~CK_Exception() {} + string errorMessage() { + return m_msg; + } + protected: + string m_msg; + }; + + const double UNDEF = -9999.1234; + + /** + * @name Falloff Parameterizations + * These constants are used to specify which falloff parameterization + * to use for a pressure-dependent reaction. + * @see Reaction.h + */ + + //@{ + const int Lindemann = 0; + const int Troe = 1; + const int SRI = 2; + //@} + + + + /** @name Reaction Rate Types + * These constant are used to specify the type of rate coefficient + */ + //@{ + const int Arrhenius = 0, LandauTeller = 1, Jan = 2, Fit1 = 3; + //@} + + + /** @name Activation Energy Units + * These constants specify the supported units for the activation energy of + * a reaction + */ + //@{ + const int Cal_per_Mole = 1, + Kcal_per_Mole = 2, + Joules_per_Mole = 3, + Kelvin= 4, + Electron_Volts = 5, + Kjoules_per_Mole = 6; + //@} + + /** + * @name Quantity Units + * These constants define the supported units for number of molecules. + */ + //@{ + const int Moles = 100; ///< specify number of moles (6.023e23 molecules / mole) + const int Molecules = 101; ///< specify number of molecules + //@} + +} // namespace + + +#endif + + + + diff --git a/Cantera/src/converters/ckr_utils.cpp b/Cantera/src/converters/ckr_utils.cpp new file mode 100755 index 000000000..d89bb508c --- /dev/null +++ b/Cantera/src/converters/ckr_utils.cpp @@ -0,0 +1,147 @@ +/** + * @file ckr_utils.cpp + * + */ + +// Copyright 2001 California Institute of Technology + + +// turn off warnings about truncating long names under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#endif + +#include + +#include +#include "ckr_utils.h" + +namespace ckr { + + +bool match(const string& s1, const string& s2) +{ + size_t n = s2.size(); + if (s1.size() < n) return false; + for (size_t i = 0; i < n; i++) + if (s2[i] != '*' && (toupper(s1[i]) != toupper(s2[i]))) return false; + return true; +} + + +/// remove all white space from string s. +void removeWhiteSpace(string& s) { + string r; + int ssize = s.size(); + for (int n = 0; n < ssize; n++) if (s[n] != ' ' + && s[n] != '\t' && s[n] != '\n') r += s[n]; + s = r; +} + +/** + * Get tokens from char array of length n beginning at 'begin'. Tokens are + * delimited by character 'delim' (space by default), with the exception of + * text contained within forward slashes ('/'), which is treated literally. + * + * code + * vector tokens; + * char line[] = "a b/3.0 txt/ c /4.0 6/ d"; + * int n = strlen(line); + * getTokens(line, n, tokens); + * for (int i = 0; i < tokens.size(); i++) cout << tokens[i] << endl; + * endcode + * + */ + +void getTokens(string& s, int n, vector& toks, char delim) { + string::iterator q, p = s.begin(), end = p + n; + vector tokk; + int inslash = -1; + + //p = begin; + while (1 > 0) { + for (; p < end; p++) { + if (*p != delim) break; + } + q = p; + for (; q < end; q++) { + if (*q == '/') inslash *= -1; + if (inslash < 0 && *q == delim) break; + } + if (p != q) { + tokk.push_back(s.substr(p - s.begin(), q - p)); + } + p = q; + if (p == end) break; + } + + toks.clear(); + int nt = tokk.size(); + string t = ""; + for (int i = 0; i < nt; i++) { + if (tokk[i][0] == '/') t += tokk[i]; + else { + if (t != "") toks.push_back(t); + t = tokk[i]; + } + } + if (t != "") toks.push_back(t); +} + + +/** + * Look for a slash-delimited number in string s, + * and if found set v to the numerical value, and + * set s to the portion of the string before the + * first slash. Return true if slash data found, + * false otherwise. + */ +bool extractSlashData(string& s, string& name, string& data) { + int slen = s.size(); + int n = s.find_first_of("/"); + if (n >= 0 && n < slen) { + int m; + for (m = n+1; m < slen; m++) if (s[m] == '/') break; + if (m < slen) { + data = s.substr(n+1,m-n-1); + name = s.substr(0,n); + removeWhiteSpace(name); + s = s.substr(m+1,1000); + return true; + } + else { + name = s; + removeWhiteSpace(name); + data = ""; + s = ""; + return false; + } + } + else { + name = s; + removeWhiteSpace(name); + data = ""; + s = ""; + return false; + } +} + +/** + * Return a modified version of string word, in which + * the first letter is upper case, and the rest are + * lower case. + */ +string capitalize(const string& word) { + string cap = word; + int n = word.size(); + if (n > 0) { + cap[0] = toupper(word[0]); + for (int m = 1; m < n; m++) { + cap[m] = tolower(word[m]); + } + } + return cap; +} + +} + diff --git a/Cantera/src/converters/ckr_utils.h b/Cantera/src/converters/ckr_utils.h new file mode 100755 index 000000000..02b4feeb3 --- /dev/null +++ b/Cantera/src/converters/ckr_utils.h @@ -0,0 +1,168 @@ +/** + * @file ckr_utils.h + * + */ + +// Copyright 2001 California Institute of Technology + +#ifndef CKR_UTILS_H +#define CKR_UTILS_H + +#ifdef WIN32 +#pragma warning(disable:4786) +#endif + +#include +#include +#include +#include + +using namespace std; + +#ifdef WIN32 +#define TYPENAME_KEYWORD +#else +#define TYPENAME_KEYWORD typename +#endif + + +namespace ckr { + +/** + * + * Fill vector 'keys' with the keys of map 'mp' + * + */ + +template +void getMapKeys(const map& mp, vector& keys) { + keys.clear(); + TYPENAME_KEYWORD map::const_iterator i = mp.begin(); + for (; i != mp.end(); ++i) keys.push_back(i->first); +} + + +/** + * + * Fill vector 'values' with the values of map 'mp' + * + */ + +template +void getMapValues(const map& mp, vector& values) { + values.clear(); + TYPENAME_KEYWORD map::const_iterator i = mp.begin(); + for (; i != mp.end(); ++i) values.push_back(i->second); +} + + + +/** + * + * Template to compare two objects a and b, possibly of different + * types, and return the greater of the two, converted to the type of + * a. The '<' operator is used for the comparison, and must be + * defined for the two types in question. + * + */ + +template +inline T max(T a, S b) { return (a < b ? b : a); } + + + +/** + * + * Template to compare two objects a and b, possibly of different + * types, and * return the lesser of the two, converted to the type + * of a. The '<' operator is used for the comparison, and must be + * defined for the two types in question. + * + */ + +template +inline T min(T a, S b) { return (a < b ? a : b); } + + +/** + * Template to return a string equal to s, but padded with spaces on + * the right as necessary to make the length n. + */ +template +inline S pad(const S& s, size_t n) { + S output; + output.resize(max(n,s.size()),' '); + copy(s.begin(), s.end(), output.begin()); + return output; +} + +/// Absolute value. +template +inline T absval(T x) { + if (x < 0) return -x; + return x; +} + +/** + * + * Iterate through a list of objects that have a numeric member named + * 'valid', and return false if for any object this attribute is not + * greater than 0. Otherwise return true. + * + */ + +template +inline bool valid(L& list) { + size_t i; + for (i=0; i < list.size(); i++) if (list[i].valid <= 0) return false; + return true; +} + + +/// Remove all white space from string s. +void removeWhiteSpace(string& s); + +void getTokens(string& begin, + int n, vector& toks, char delim=' '); + + +/** + * Perform a case-insensitive comparison of the first n2 characters + * of strings s1 and s2, where n2 is the length of s2. Typically, s1 + * is an unknown string and s2 is the significant portion of a + * keyword. Returns true if a match is found, false otherwise. An asterisk + * in string s2 matches any character at that position. + * + * Example: if s1 = "elements", then match(s1, "ELEM") would return true. + * + */ + +bool match(const string& s1, const string& s2); + +/** + * + * Check whether string 'word' begins with a Chemkin keyword. + * + */ + +inline bool isKeyword(string word) +{ + return (match(word, "ELEM") || + match(word, "SPEC") || + match(word, "THERM") || + match(word, "REAC") || + match(word, "END")); +} + + +bool extractSlashData(string& s, string& name, string& data); +string capitalize(const string& word); + +} + +#endif + + + + + diff --git a/Cantera/src/converters/config.h b/Cantera/src/converters/config.h new file mode 100755 index 000000000..054804c33 --- /dev/null +++ b/Cantera/src/converters/config.h @@ -0,0 +1,25 @@ + +#ifndef CKR_CONFIG_H +#define CKR_CONFIG_H + +namespace ckr { + +/** + * define to enable parsing Chemkin-III plasma reactions. Not yet fully + * implemented, so best to leave it undefined for now. + */ +#undef ENABLE_PLASMA_REACTIONS + +} + + +/** + * @file config.h + * Header file generated by configure script. To change options, + * edit config.h.in and re-run configure. + * @author David G. Goodwin, Caltech + */ + +#endif + + diff --git a/Cantera/src/converters/filter.cpp b/Cantera/src/converters/filter.cpp new file mode 100755 index 000000000..346db5922 --- /dev/null +++ b/Cantera/src/converters/filter.cpp @@ -0,0 +1,106 @@ +/** + * @file importCK.cpp + * + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CKR_FILTER_H +#define CKR_FILTER_H + +#ifdef WIN32 +#pragma warning(disable:4786) +#endif + +// +// STL includes +// +#include +#include +#include +#include + +using namespace std; +#include + +// +// CKReader includes. +// +#include "CKReader.h" +namespace ckr { + + /** + * Edit a mechanism. + */ + + bool filter(const string& infile, const string& database, + const string& outfile, const vector& species, const vector& reactions) { + + bool ok = true; + + // + // read the input file + // + ckr::CKReader ck; + ck.validate = false; + string logfile = "filter"; + try { + if (!ck.read(infile, database, logfile)) { + cerr << "error encountered while parsing " << infile << endl; + cerr << "see log file " << logfile << " for details." + << endl << endl; + return false; + } + } + catch (ckr::CK_SyntaxError) { + cerr << "syntax error encountered while parsing " << infile << endl; + cerr << "see log file " << logfile << " for details." + << endl << endl; + return false; + } + + ofstream fout(outfile.c_str()); + if (!fout) { + cerr << "could not open " << outfile << endl; + return false; + } + int nel = ck.elements.size(); + int n; + + // write header information + struct tm *newtime; + time_t aclock; + time( &aclock ); /* Get time in seconds */ + newtime = localtime( &aclock ); /* Convert time to struct tm form */ + + fout << "!\n! reduced mechanism generated from " << infile << endl + << "! " << asctime(newtime) << endl; + + fout << "ELEMENTS " << endl; + for (n = 0; n < nel; n++) fout << ck.elements[n]; + fout << "END" << endl; + + int nsp = species.size(); + fout << "SPECIES" << endl; + for (n = 0; n < nsp; n++) { + fout << ck.species[ species[n] ].name << " "; + if (5*((n+1)/5) == n+1) fout << endl; + } + fout << "END" << endl; + fout << "REACTIONS" << endl; + int nrxns = reactions.size(); + for (n = 0; n < nrxns; n++) { + vector& lines = ck.reactions[reactions[n]].lines; + int nl = lines.size(); + for (int j = 0; j < nl; j++) fout << lines[j] << endl; + } + fout.close(); + return ok; + } +} + + +#endif + + diff --git a/Cantera/src/converters/thermoFunctions.cpp b/Cantera/src/converters/thermoFunctions.cpp new file mode 100755 index 000000000..e066e20ba --- /dev/null +++ b/Cantera/src/converters/thermoFunctions.cpp @@ -0,0 +1,92 @@ +/** + * @file thermoFunctions.cpp + * + */ + +// Copyright 2001 California Institute of Technology + + +// turn off warnings about truncating long names under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#endif + +/** + * @file thermoFunctions.cpp + * Species thermodynamic properties implementation. + * @author California Institute of Technology, Caltech + * @date @today + */ + +#include +#include "thermoFunctions.h" +#include +using namespace std; + +//#include "Cantera.h" + +namespace ckr { + + +/** + * non-dimensional heat capacity (\f$ C_p/R \f$) at constant P for + * one species @param t temperature @param s species object + */ +double cp(double t, const Species& s) { + const vector_fp* cpc; + if (t > s.tmid) cpc = &s.highCoeffs; + else cpc = &s.lowCoeffs; + const vector_fp& c = *cpc; + double cp0r = c[0] + c[1]*t + c[2]*t*t + c[3]*t*t*t + c[4]*t*t*t*t; + return cp0r; +} + + + +/** + * enthalpy in Kelvin (\f$ H/R \f$) for + * one species. @param t temperature @param s species object + */ +double enthalpy(double t, const Species& s) { + const vector_fp* cp; + if (t > s.tmid) cp = &s.highCoeffs; + else cp = &s.lowCoeffs; + const vector_fp& c = *cp; + double h0rt = c[0] + 0.5*c[1]*t + c[2]*t*t/3.0 + 0.25*c[3]*t*t*t + + 0.2*c[4]*t*t*t*t + c[5]/t; + return t*h0rt; +} + + +/** + * non-dimensional entropy (\f$ S/R \f$) for + * one species @param t temperature @param s species object + */ +double entropy(double t, const Species& s) { + const vector_fp* cp; + if (t > s.tmid) cp = &s.highCoeffs; + else cp = &s.lowCoeffs; + const vector_fp& c = *cp; + double s0r = c[0]*log(t) + c[1]*t + 0.5*c[2]*t*t + c[3]*t*t*t/3.0 + + 0.25*c[4]*t*t*t*t + c[6]; + return t*s0r; +} + +/** + * Gibbs function in Kelvin (\f$ G/R \f$) for + * one species. @param t temperature @param s species object + */ +double gibbs(double t, const Species& s) { + const vector_fp* cp; + if (t > s.tmid) cp = &s.highCoeffs; + else cp = &s.lowCoeffs; + const vector_fp& c = *cp; + double h0rt = c[0] + 0.5*c[1]*t + c[2]*t*t/3.0 + 0.25*c[3]*t*t*t + + 0.2*c[4]*t*t*t*t + c[5]/t; + double s0r = c[0]*log(t) + c[1]*t + 0.5*c[2]*t*t + c[3]*t*t*t/3.0 + + 0.25*c[4]*t*t*t*t + c[6]; + return t*(h0rt - s0r); +} + +} + diff --git a/Cantera/src/converters/thermoFunctions.h b/Cantera/src/converters/thermoFunctions.h new file mode 100755 index 000000000..6b12b9285 --- /dev/null +++ b/Cantera/src/converters/thermoFunctions.h @@ -0,0 +1,30 @@ +/** + * @file thermoFunctions.h + * + * Thermodynamic properties. Note that these functions are used only + * for validation purposes by CKReader. They are not used by Cantera. + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CKR_THERMOFUNCTIONS_H +#define CKR_THERMOFUNCTIONS_H + +#ifdef WIN32 +#pragma warning(disable:4786) +#endif + +#include "Species.h" + +namespace ckr { + +double enthalpy(double t, const Species& s); +double cp(double t, const Species& s); +double entropy(double t, const Species& s); +double gibbs(double t, const Species& s); + +} + +#endif + diff --git a/Cantera/src/converters/writelog.cpp b/Cantera/src/converters/writelog.cpp new file mode 100755 index 000000000..73064523b --- /dev/null +++ b/Cantera/src/converters/writelog.cpp @@ -0,0 +1,241 @@ +/** + * @file writelog.cpp + * + */ + +// Copyright 2001 California Institute of Technology + + +// turn off warnings about truncating long names under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#endif + +#include +#include "writelog.h" + +namespace ckr { + + + /// format a string for the log file message printed when starting a new task + string newTask(string msg) { + string s = "\n"; + s += msg + "...\n"; + return s; + } + + + /// print the falloff parameters for a pressure-dependent reaction + bool writeFalloff(int type, const vector_fp& c, ostream& log) { + + log.precision(6); + log.width(0); + log.flags(ios::uppercase); + + // bool ok = true; + switch (type) { + + case Lindemann: + log << " Lindemann falloff function" << endl; + return true; + + case Troe: + log << " Troe falloff function: " << endl; + if (c.size() == 3) { + log << " alpha, T***, T* = (" << c[0] << ", " << c[1] + << ", " << c[2] << ")" << endl; + } + else if (c.size() == 4) { + log << " alpha, T***, T*, T** = (" << c[0] << ", " << c[1] + << ", " << c[2] << ", " << c[3] << ")" << endl; + } + else { + for (size_t n = 0; n < c.size(); n++) log << c[n] << ", "; log << endl; + log << "###### ERROR ##### incorrect number of parameters" << endl; + return false; + } + return true; + + case SRI: + log << " SRI falloff function: " << endl; + if (c.size() == 3) { + log << " a, b, c = (" << c[0] << ", " << c[1] + << ", " << c[2] << ")" << endl; + } + else if (c.size() == 5) { + log << " a, b, c, d, e = (" << c[0] << ", " << c[1] + << ", " << c[2] << ", " << c[3] << ", " << c[4] + << ")" << endl; + } + else { + for (size_t n = 0; n < c.size(); n++) log << c[n] << ", "; log << endl; + log << "##### ERROR ##### incorrect number of parameters" << endl; + return false; + } + return true; + + default: + log << "unknown falloff type: " << type << endl; + return false; + } + } + + + /// print the rate coefficient parameters + bool writeRateCoeff(const RateCoeff& k, ostream& log) { + + log.precision(10); + log.width(0); + log.flags(ios::uppercase); + int n; + + bool ok = true; + int nb; + + switch (k.type) { + + case Arrhenius: + log <<" A, n, E = (" << k.A << ", " << k.n + << ", " << k.E << ")" << endl; + break; + + case LandauTeller: + log << "A, n, E, B, C = (" << k.A << ", " << k.n + << ", " << k.E << ", " << k.B << ", " << k.C + << ") *** Landau-Teller ***" << endl; + break; + + case Jan: + log <<" A, n, E = (" << k.A << ", " << k.n + << ", " << k.E << ") *** JAN *** " << endl; + nb = k.b.size(); + for (n = 0; n < nb; n++) { + log << " b" << n+1 << ": " << k.b[n] << endl; + } + if (nb != 9) log + << "warning: number of b coefficients should be 9." + << endl; + break; + + case Fit1: + log <<" A, n, E = (" << k.A << ", " << k.n + << ", " << k.E << ") *** FIT1 *** " << endl; + nb = k.b.size(); + for (n = 0; n < nb; n++) { + log << " b" << n+1 << ": " << k.b[n] << endl; + } + if (nb != 9) log + << "warning: number of b coefficients should be 4." + << endl; + break; + + default: + log << "unknown rate coefficient type: " << k.type << endl; + ok = false; + } + return ok; + } + + /** + * Write onto an output stream the chemical equation for a reaction. + */ + void printReactionEquation(ostream& f, const Reaction& r) { + // r.write(f); + f << reactionEquation(r); + } + + + /** + * Write to a string the chemical equation for a reaction. + */ + string reactionEquation(const Reaction& r) { + string s = ""; + int nr = r.reactants.size(); + int np = r.products.size(); + int k; + double m; + char buf[20]; + + for (k = 0; k < nr; k++) { + m = r.reactants[k].number; + if (m != 1.0) { + sprintf(buf,"%g",m); + s += string(buf); + s += " "; + } + s += r.reactants[k].name; + if (k < nr - 1) s += " + "; + } + + if (r.isFalloffRxn) s += " (+ " + r.thirdBody + ")"; + else if (r.isThreeBodyRxn) s += " + " + r.thirdBody; + if (r.isReversible) s += " <=> "; + else s += " => "; + + for (k = 0; k < np; k++) { + m = r.products[k].number; + if (m != 1.0) { + sprintf(buf,"%g",m); + s += string(buf); + s += " "; + } + s += r.products[k].name; + if (k < np - 1) s += " + "; + } + if (r.isFalloffRxn) s += " (+ " + r.thirdBody + ")"; + else if (r.isThreeBodyRxn) s += " + " + r.thirdBody; + return s; + } + + + + /** + * + * Write a summary of the properties of one species to the log file. + * @param log log file output stream + * @param spec instance of Species class + */ + + void writeSpeciesData(ostream& log, const Species& spec) { + + if (!spec.id.empty()) + log << endl << " id/date: " << spec.id << endl; + else + log << " ... " << endl; + + log << " phase: " + << spec.phase << endl + << " composition: ("; + + for (size_t ie = 0; ie < spec.elements.size(); ie++) { + if (!spec.elements[ie].name.empty()) { + log.flags(ios::fixed); + log.precision(0); + if (ie > 0) log << ", "; + log << spec.elements[ie].number << " " + << spec.elements[ie].name; + } + } + log << ")"; + + log.flags(ios::showpoint | ios::fixed); + log.precision(2); + log << endl << " Tlow, Tmid, Thigh: (" << spec.tlow << ", " << + spec.tmid << ", " << spec.thigh << ")" << endl << endl; + log << " coefficients (low, high):" << endl; + log.flags(ios::scientific | ios::uppercase | ios::internal); + log.precision(8); + for (int j = 0; j < 7; j++) { + log << " a" << j + 1; + log.setf(ios::showpos); + log << " \t" << spec.lowCoeffs[j] + << " \t" << spec.highCoeffs[j] << endl; + log.unsetf(ios::showpos); + } + log << endl; + } + + +} + + diff --git a/Cantera/src/converters/writelog.h b/Cantera/src/converters/writelog.h new file mode 100755 index 000000000..2b64c6c69 --- /dev/null +++ b/Cantera/src/converters/writelog.h @@ -0,0 +1,31 @@ +/** + * @file writelog.h + * + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CKR_WRITELOG_H +#define CKR_WRITELOG_H + +#include +#include +#include +using namespace std; + +#include "Species.h" +#include "Reaction.h" + +//#include "Cantera.h" + +namespace ckr { + string newTask(string msg); + bool writeFalloff(int type, const vector_fp& c, ostream& log); + bool writeRateCoeff(const RateCoeff& k, ostream& log); + void printReactionEquation(ostream& f, const Reaction& r); + void writeSpeciesData(ostream& log, const Species& spec); + string reactionEquation(const Reaction& r); +} + +#endif diff --git a/Cantera/src/ct_defs.h b/Cantera/src/ct_defs.h new file mode 100755 index 000000000..a71186dfd --- /dev/null +++ b/Cantera/src/ct_defs.h @@ -0,0 +1,163 @@ +/** + * + * @file ct_defs.h + * + * This file contains definitions of terms that are used in internal + * routines and are unlikely to need modifying + */ + +/* $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_DEFS_H +#define CT_DEFS_H + +#include +#include "config.h" + +// STL includes +//#include +#include +#include +#include +#include +#include + +using namespace std; + +#include "ctvector.h" +using namespace ct; + +#ifdef WIN32 +#define TYPENAME_KEYWORD +#else +#define TYPENAME_KEYWORD typename +#endif + +#undef CHEMKIN_COMPATIBILITY_MODE + +/** + * Namespace for the Cantera kernel. + */ +namespace Cantera { + +#define CANTERA_VERSION 1.3 + + // use kg-moles, rather than g-moles. +#define USE_KMOL + +#ifdef USE_KMOL + const doublereal CtMoles_per_mole = 1.e-3; // kmol + /// Avogadro's Number + const doublereal Avogadro = 6.022136736e26; + /// Universal Gas Constant + const doublereal GasConstant = 8314.0; + const doublereal logGasConstant = 9.02569612; +#else + const doublereal CtMoles_per_mole = 1.0; // mol + const doublereal Avogadro = 6.022136736e23; + const doublereal GasConstant = 8.3140; + const doublereal logGasConstant = 2.117940841; +#endif + + /// One atmosphere + const doublereal OneAtm = 1.01325e5; // Pa + /// Universal gas constant in cal/mol/K + const doublereal GasConst_cal_mol_K = 1.987; + /// Boltzmann's constant + const doublereal Boltzmann = GasConstant / Avogadro; + /// Planck's constant + const doublereal Planck = 6.6262e-34; // J-s + /// log(k/h) + const doublereal logBoltz_Planck = 23.7599032; // ln(k_B/h) + /// Stefan-Boltzmann constant + const doublereal StefanBoltz = 5.67e-8; + const doublereal ElectronCharge = 1.602e-19; + const doublereal Faraday = ElectronCharge * Avogadro; + const doublereal Pi = 3.1415926; + const doublereal SqrtPi = sqrt(Pi); + + const doublereal OneThird = 1.0/3.0; + const doublereal FiveSixteenths = 5.0/16.0; + const doublereal SqrtTen = sqrt(10.0); + const doublereal SqrtEight = sqrt(8.0); + + const doublereal SmallNumber = 1.e-300; + const doublereal BigNumber = 1.e300; + + /// largest x such that exp(x) is valid + const doublereal MaxExp = 690.775527898; + + const int Undefined = -999; + const doublereal Undef = -999.1234; + const doublereal Cutoff = 1.e-12; + const doublereal Tiny = 1.e-20; + + + const int TV = 100, HP = 101, SP = 102, PV = 103, TP = 104, UV = 105, + ST = 106, SV = 107, UP = 108, VH = 109, TH = 110, SH = 111, + PX = 112, TX = 113; + const int VT = -100, PH = -101, PS = -102, VP = -103, PT = -104, + VU = -105, TS = -106, VS = -107, PU = -108, HV = -109, + HT = -110, HS = -111, XP = -112, XT = -113; + + inline doublereal fmaxx(doublereal x, doublereal y) + { return (x > y) ? x : y; } + inline doublereal fminn(doublereal x, doublereal y) + { return (x < y) ? x : y; } + + const int GAS = 0; + const int LIQUID = 1; + const int SOLID = 2; + const int PURE_FLUID = 3; + + // enum Phase {GAS, LIQUID, SOLID, PURE_FLUID}; + + const int Solid_Phase = 0, + Liquid_Phase = 1, + Vapor_Phase = 2, + Gas_Phase = 2; + + const int None = 0; + + // typedefs + typedef std::map compositionMap; + typedef ct::ctvector_fp array_fp; + typedef ct::ctvector_fp vector_fp; + typedef ct::ctvector_int array_int; + typedef ct::ctvector_int vector_int; + typedef vector_int group_t; + typedef std::vector grouplist_t; + + typedef vector_fp::iterator workPtr; + typedef vector_fp::const_iterator const_workPtr; + + + template + inline doublereal operator*(const vector& u, const vector& v) { + return inner_product(u.begin(), u.end(), v.begin(), 0.0); + } + + template + inline ostream& operator<<(ostream& s, const vector& v) { + int n = v.size(); + s << "<"; + for (int i = 0; i < n; i++) { + s << v[i]; + if (i < n-1) s << ", "; + } + s << ">"; + return s; + } + +} // namespace + +#endif + + + diff --git a/Cantera/src/ctexceptions.h b/Cantera/src/ctexceptions.h new file mode 100755 index 000000000..d0331b6be --- /dev/null +++ b/Cantera/src/ctexceptions.h @@ -0,0 +1,47 @@ +/** + * @file ctexceptions.h + */ + +// $Author$ +// $Revision$ +// $Date$ + +// Copyright 2001 California Institute of Technology + +#ifndef CT_CTEXCEPTIONS_H +#define CT_CTEXCEPTIONS_H + +#include "global.h" +#include "stringUtils.h" + +namespace Cantera { + + /** + * Base class for exceptions thrown by Cantera classes + */ + class CanteraError { + public: + CanteraError() {} + CanteraError(string proc, string msg) { + setError(proc, msg); + m_msg = msg; + } + virtual ~CanteraError(){} + string errorMessage() { return m_msg; } + void append(string msg) { m_msg += msg; } + void saveError(string procedure) { + setError(procedure, m_msg); + m_msg = ""; + } + protected: + string m_msg; + }; + + class ArraySizeError : public CanteraError { + public: + ArraySizeError(string proc, int sz, int reqd) : + CanteraError(proc, "Array size ("+int2str(sz)+") too small. Must be at least "+int2str(reqd)) {} + }; +} + +#endif diff --git a/Cantera/src/ctlapack.h b/Cantera/src/ctlapack.h new file mode 100755 index 000000000..61dc7a9f9 --- /dev/null +++ b/Cantera/src/ctlapack.h @@ -0,0 +1,237 @@ +/** + * @file ctlapack.h + */ + +/* $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology. + +#ifndef CT_CTLAPACK_H +#define CT_CTLAPACK_H + +#include "ct_defs.h" + +// map BLAS names to names with or without a trailing underscore. +#ifndef LAPACK_FTN_TRAILING_UNDERSCORE + +#define _DGEMV_ dgemv +#define _DGETRF_ dgetrf +#define _DGETRS_ dgetrs +#define _DGETRI_ dgetri +#define _DGELSS_ dgelss +#define _DGBSV_ dgbsv +#define _DGBTRF_ dgbtrf +#define _DGBTRS_ dgbtrs + +#else + +#define _DGEMV_ dgemv_ +#define _DGETRF_ dgetrf_ +#define _DGETRS_ dgetrs_ +#define _DGETRI_ dgetri_ +#define _DGELSS_ dgelss_ +#define _DGBSV_ dgbsv_ +#define _DGBTRF_ dgbtrf_ +#define _DGBTRS_ dgbtrs_ + +#endif + + +namespace ctlapack { + + typedef enum {Transpose = 1, NoTranspose = 0} transpose_t; + typedef enum {ColMajor = 1, RowMajor = 0} storage_t; +} +const char no_yes[2] = {'N', 'T'}; + +// #ifdef HAVE_INTEL_MKL +// #include "../../ext/math/mkl_cblas.h" +// const CBLAS_ORDER cblasOrder[2] = { CblasRowMajor, CblasColMajor }; +// const CBLAS_TRANSPOSE cblasTrans[2] = { CblasNoTrans, CblasTrans }; +// #endif + + +// C interfaces for Fortran Lapack routines +extern "C" { + +#ifdef LAPACK_FTN_STRING_LEN_AT_END + + int _DGEMV_(const char* transpose, + const integer* m, const integer* n, const doublereal* alpha, + const doublereal* a, const integer* lda, const doublereal* x, + const integer* incX, const doublereal* beta, doublereal* y, + const integer* incY, ftnlen trsize); +#else + + int _DGEMV_(const char* transpose, ftnlen trsize, + const integer* m, const integer* n, const doublereal* alpha, + const doublereal* a, const integer* lda, const doublereal* x, + const integer* incX, const doublereal* beta, doublereal* y, + const integer* incY); +#endif + + int _DGETRF_(const integer* m, const integer* n, + doublereal* a, integer* lda, integer* ipiv, + integer* info); + +#ifdef LAPACK_FTN_STRING_LEN_AT_END + + int _DGETRS_(const char* transpose, const integer* n, + const integer* nrhs, doublereal* a, const integer* lda, + integer* ipiv, doublereal* b, const integer* ldb, + integer* info, ftnlen trsize); + +#else + + int _DGETRS_(const char* transpose, ftnlen trsize, const integer* n, + const integer* nrhs, const doublereal* a, const integer* lda, + integer* ipiv, doublereal* b, const integer* ldb, integer* info); + +#endif + + int _DGETRI_(const integer* n, doublereal* a, const integer* lda, + integer* ipiv, doublereal* work, integer* lwork, integer* info); + + int _DGELSS_(integer *m, integer *n, integer *nrhs, + doublereal *a, integer *lda, doublereal *b, integer *ldb, doublereal * + s, doublereal *rcond, integer *rank, doublereal *work, integer *lwork, + integer *info); + + + int _DGBSV_(integer *n, integer *kl, integer *ku, integer *nrhs, + doublereal *a, integer *lda, integer *ipiv, doublereal *b, + integer *ldb, integer *info); + + int _DGBTRF_(integer* m, integer *n, integer *kl, integer *ku, + doublereal *a, integer *lda, integer *ipiv, integer *info); + +#ifdef LAPACK_FTN_STRING_LEN_AT_END + int _DGBTRS_(const char* trans, integer *n, integer *kl, integer *ku, + integer *nrhs, doublereal *a, integer *lda, integer *ipiv, + doublereal *b, integer *ldb, integer *info, ftnlen trsize); +#else + int _DGBTRS_(const char* trans, ftnlen trsize, + integer *n, integer *kl, integer *ku, + integer *nrhs, doublereal *a, integer *lda, integer *ipiv, + doublereal *b, integer *ldb, integer *info); +#endif + +} + +namespace Cantera { + + inline void ct_dgemv(ctlapack::storage_t storage, + ctlapack::transpose_t trans, + int m, int n, doublereal alpha, const doublereal* a, int lda, + const doublereal* x, int incX, doublereal beta, + doublereal* y, int incY) + { + //#ifdef HAVE_INTEL_MKL + //cblas_dgemv(cblasOrder[storage], cblasTrans[trans], m, n, alpha, + // a, lda, x, incX, beta, y, incY); + //#else + integer f_m = m, f_n = n, f_lda = lda, f_incX = incX, f_incY = incY; + doublereal f_alpha = alpha, f_beta = beta; + ftnlen trsize = 1; +#ifdef LAPACK_FTN_STRING_LEN_AT_END + _DGEMV_(&no_yes[trans], &f_m, &f_n, &f_alpha, a, + &f_lda, x, &f_incX, &f_beta, y, &f_incY, trsize); +#else + _DGEMV_(&no_yes[trans], trsize, &f_m, &f_n, &f_alpha, a, + &f_lda, x, &f_incX, &f_beta, y, &f_incY); +#endif + //#endif + } + + + inline void ct_dgbsv(int n, int kl, int ku, int nrhs, + doublereal* a, int lda, integer* ipiv, doublereal* b, int ldb, + int& info) { + integer f_n = n, f_kl = kl, f_ku = ku, f_nrhs = nrhs, f_lda = lda, + f_ldb = ldb, f_info = info; + _DGBSV_(&f_n, &f_kl, &f_ku, &f_nrhs, a, &f_lda, ipiv, + b, &f_ldb, &f_info); + info = f_info; + } + + inline void ct_dgbtrf(int m, int n, int kl, int ku, + doublereal* a, int lda, integer* ipiv, int& info) { + integer f_m = m, f_n = n, f_kl = kl, f_ku = ku, + f_lda = lda, f_info = info; + _DGBTRF_(&f_m, &f_n, &f_kl, &f_ku, a, &f_lda, ipiv, &f_info); + info = f_info; + } + + inline void ct_dgbtrs(ctlapack::transpose_t trans, int n, + int kl, int ku, int nrhs, doublereal* a, int lda, + integer* ipiv, doublereal* b, int ldb, int& info) { + integer f_n = n, f_kl = kl, f_ku = ku, f_nrhs = nrhs, f_lda = lda, + f_ldb = ldb, f_info = info; + char tr = no_yes[trans]; + ftnlen trsize = 1; +#ifdef LAPACK_FTN_STRING_LEN_AT_END + _DGBTRS_(&tr, &f_n, &f_kl, &f_ku, &f_nrhs, a, &f_lda, ipiv, + b, &f_ldb, &f_info, trsize); +#else + _DGBTRS_(&tr, trsize, &f_n, &f_kl, &f_ku, &f_nrhs, a, &f_lda, ipiv, + b, &f_ldb, &f_info); +#endif + info = f_info; + } + + inline void ct_dgetrf(int m, int n, + doublereal* a, int lda, integer* ipiv, int& info) { + integer mm = m; + integer nn = n; + integer ldaa = lda; + integer infoo = info; + _DGETRF_(&mm, &nn, a, &ldaa, ipiv, &infoo); + info = infoo; + } + + inline void ct_dgetrs(ctlapack::transpose_t trans, int n, + int nrhs, doublereal* a, int lda, + integer* ipiv, doublereal* b, int ldb, int& info) + { + integer f_n = n, f_lda = lda, f_nrhs = nrhs, f_ldb = ldb, + f_info = info; + char tr = no_yes[trans]; + + ftnlen trsize = 1; +#ifdef LAPACK_FTN_STRING_LEN_AT_END + _DGETRS_(&tr, &f_n, &f_nrhs, a, &f_lda, ipiv, b, &f_ldb, + &f_info, trsize); +#else + _DGETRS_(&tr, trsize, &f_n, &f_nrhs, a, &f_lda, ipiv, b, &f_ldb, + &f_info); +#endif + info = f_info; + } + + inline void ct_dgetri(int n, doublereal* a, int lda, integer* ipiv, + doublereal* work, int lwork, int& info) { + integer f_n = n, f_lda = lda, f_lwork = lwork, f_info = info; + _DGETRI_(&f_n, a, &f_lda, ipiv, work, &f_lwork, &f_info); + } + + inline void ct_dgelss(int m, int n, int nrhs, doublereal* a, + int lda, doublereal* b, int ldb, doublereal* s, + doublereal rcond, int& rank, doublereal* work, int lwork, + int& info) { + doublereal f_rcond = rcond; + integer f_m = m, f_n = n, f_nrhs = nrhs, f_lda = lda, f_ldb = ldb, + f_rank = rank, f_info = info, f_lwork = lwork; + //f_lwork = 2*(3*min(m,n) + max(2*min(m,n), max(m,n))); + _DGELSS_(&f_m, &f_n, &f_nrhs, a, &f_lda, b, &f_ldb, s, &f_rcond, + &f_rank, work, &f_lwork, &f_info); + info = f_info; + rank = f_rank; + } + + +} + +#endif diff --git a/Cantera/src/ctml.cpp b/Cantera/src/ctml.cpp new file mode 100755 index 000000000..6cf988e37 --- /dev/null +++ b/Cantera/src/ctml.cpp @@ -0,0 +1,362 @@ +/** + * @file ctml.cpp + * + * Functions to read and write CTML. + * + */ + +/* $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2002 California Institute of Technology + + +// turn off warnings under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "ctml.h" + +namespace ctml { + + static doublereal fpValue(string val) { + return atof(stripws(val).c_str()); + } + + void addBool(XML_Node& node, string title, bool val) { + string v = (val ? "true" : "false"); + XML_Node& f = node.addChild("bool",v); + f.addAttribute("title",title); + } + + void addInteger(XML_Node& node, string title, int val, + string units, string type) { + XML_Node& f = node.addChild("integer",val); + f.addAttribute("title",title); + if (type != "") f.addAttribute("type",type); + if (units != "") f.addAttribute("units",units); + } + + void addIntegerArray(XML_Node& node, string title, int n, + const int* vals, string units, string type, + doublereal minval, doublereal maxval) { + string fmt = "%8d"; + int i; + string v = ""; + for (i = 0; i < n; i++) { + v += int2str(vals[i],fmt); + if (i == n-1) v += "\n"; + else if (i > 0 && (i+1) % 3 == 0) v += ",\n"; + else v += ", "; + } + XML_Node& f = node.addChild("intArray",v); + f.addAttribute("title",title); + if (type != "") f.addAttribute("type",type); + f.addAttribute("size",n); + if (units != "") f.addAttribute("units",units); + if (minval != Undef) f.addAttribute("min",minval); + if (maxval != Undef) f.addAttribute("max",maxval); + } + + void addFloat(XML_Node& node, + string title, + doublereal val, + string units, + string type, + doublereal minval, + doublereal maxval) { + + string fmt = "%17.9E"; + XML_Node& f = node.addChild("float",val,fmt); + f.addAttribute("title",title); + if (type != "") f.addAttribute("type",type); + if (units != "") f.addAttribute("units",units); + if (minval != Undef) f.addAttribute("min",minval); + if (maxval != Undef) f.addAttribute("max",maxval); + } + + + void addFloatArray(XML_Node& node, string title, int n, + const double* vals, string units, string type, + doublereal minval, doublereal maxval) { + string fmt = "%17.9E"; + int i; + string v = ""; + for (i = 0; i < n; i++) { + v += fp2str(vals[i],fmt); + if (i == n-1) v += "\n"; + else if (i > 0 && (i+1) % 3 == 0) v += ",\n"; + else v += ", "; + } + XML_Node& f = node.addChild("floatArray",v); + f.addAttribute("title",title); + if (type != "") f.addAttribute("type",type); + f.addAttribute("size",n); + if (units != "") f.addAttribute("units",units); + if (minval != Undef) f.addAttribute("min",minval); + if (maxval != Undef) f.addAttribute("max",maxval); + } + + void addString(XML_Node& node, string title, string val, + string type) { + XML_Node& f = node.addChild("string",val); + f.addAttribute("title",title); + if (type != "") f.addAttribute("type",type); + } + + XML_Node* getByTitle(XML_Node& node, string title) { + XML_Node* s = node.findByAttr("title",title); + if (s->parent() == &node) return s; + else return 0; + } + + string getString(XML_Node& parent, string name) { + if (!parent.hasChild(name)) return ""; + return parent(name); + } + + void getString(XML_Node& node, string title, string& val, + string& type) { + val = ""; + type = ""; + XML_Node* s = getByTitle(node, title); + if (s) + if (s->name() == "string") { + val = (*s).value(); + type = (*s)["type"]; + return; + } + } + + void getIntegers(XML_Node& node, map& v) { + vector f; + node.getChildren("integer",f); + int n = f.size(); + integer x, x0, x1; + string typ, title, vmin, vmax; + for (int i = 0; i < n; i++) { + XML_Node& fi = *(f[i]); + x = atoi(fi().c_str()); + title = fi["title"]; + vmin = fi["min"]; + vmax = fi["max"]; + if (vmin != "") + x0 = atoi(vmin.c_str()); + if (fi["max"] != "") + x1 = atoi(vmax.c_str()); + v[title] = x; + } + } + + + void getStrings(XML_Node& node, map& v) { + vector f; + node.getChildren("string",f); + int n = f.size(); + string typ, title; + for (int i = 0; i < n; i++) { + XML_Node& fi = *(f[i]); + title = fi["title"]; + v[title] = fi(); + } + } + + + void getFloats(XML_Node& node, map& v, bool convert) { + vector f; + node.getChildren("float",f); + int n = f.size(); + doublereal x, x0, x1, fctr; + string typ, title, units, vmin, vmax; + for (int i = 0; i < n; i++) { + XML_Node& fi = *(f[i]); + x = atof(fi().c_str()); + x0 = Undef; + x1 = Undef; + typ = fi["type"]; + title = fi["title"]; + units = fi["units"]; + vmin = fi["min"]; + vmax = fi["max"]; + if (vmin != "") { + x0 = atof(vmin.c_str()); + if (x < x0 - Tiny) { + write("\nWarning: value "+fi()+" is below lower limit of " + +vmin+".\n"); + } + } + if (fi["max"] != "") { + x1 = atof(vmax.c_str()); + if (x > x1 + Tiny) { + write("\nWarning: value "+fi()+" is above upper limit of " + +vmax+".\n"); + } + } + fctr = (convert ? toSI(units) : 1.0); // toSI(typ,units); + v[title] = fctr*x; + } + } + + + /** + * Get a floating-point value from a child element. Returns a + * double value for the child named 'name' of element 'parent'. If + * 'type' is supplied and matches a known unit type, unit + * conversion will be done if the child element has an attribute + * 'units'. + */ + doublereal getFloat(XML_Node& parent, string name, string type) { + if (!parent.hasChild(name)) return Undef; + XML_Node& node = parent.child(name); + doublereal x, x0, x1, fctr = 1.0; + string units, vmin, vmax; + x = atof(node().c_str()); + x0 = Undef; + x1 = Undef; + units = node["units"]; + vmin = node["min"]; + vmax = node["max"]; + if (vmin != "") { + x0 = atof(vmin.c_str()); + if (x < x0 - Tiny) { + write("\nWarning: value "+node()+" is below lower limit of " + +vmin+".\n"); + } + } + if (node["max"] != "") { + x1 = atof(vmax.c_str()); + if (x > x1 + Tiny) { + write("\nWarning: value "+node()+" is above upper limit of " + +vmax+".\n"); + } + } + if (type != "" && units != "") + fctr = toSI(units); + return fctr*x; + } + + + void getFloatArray(XML_Node& node, vector_fp& v, bool convert) { + int icom; + string numstr; + if (node.name() != "floatArray") + throw CanteraError("getFloatArray","wrong element type: " + +node.name()); + + v.clear(); + doublereal vmin = Undef, vmax = Undef; + + doublereal funit = 1.0; + if (node["units"] != "" && convert) { + funit = toSI(node["units"]); + } + + if (node["min"] != "") + vmin = atof(node["min"].c_str()); + if (node["max"] != "") + vmax = atof(node["max"].c_str()); + + doublereal vv; + string val = node.value(); + while (1 > 0) { + icom = val.find(','); + if (icom >= 0) { + numstr = val.substr(0,icom); + val = val.substr(icom+1,val.size()); + v.push_back(atof(numstr.c_str())); + } + else { + v.push_back(atof(val.c_str())); + break; + } + vv = v.back(); + if (vmin != Undef && vv < vmin - Tiny) { + write("\nWarning: value "+fp2str(vv)+ + " is below lower limit of " +fp2str(vmin)+".\n"); + } + if (vmax != Undef && vv > vmax + Tiny) { + write("\nWarning: value "+fp2str(vv)+ + " is above upper limit of " +fp2str(vmin)+".\n"); + } + } + int nv = v.size(); + for (int n = 0; n < nv; n++) { + v[n] *= funit; + } + } + + void getMap(XML_Node& node, map& m) { + vector v; + getStringArray(node, v); + string key, val; + int n = v.size(); + int icolon; + for (int i = 0; i < n; i++) { + icolon = v[i].find(":"); + if (icolon < 0) { + throw CanteraError("getMap","missing colon in map entry (" + +v[i]+")"); + } + key = v[i].substr(0,icolon); + val = v[i].substr(icolon+1, v.size()); + m[key] = val; + } + } + + void getPairs(XML_Node& node, vector& key, vector& val) { + vector v; + getStringArray(node, v); + int n = v.size(); + int icolon; + for (int i = 0; i < n; i++) { + icolon = v[i].find(":"); + if (icolon < 0) { + throw CanteraError("getMap","missing colon in map entry (" + +v[i]+")"); + } + key.push_back(v[i].substr(0,icolon)); + val.push_back(v[i].substr(icolon+1, v.size())); + } + } + + void getStringArray(XML_Node& node, vector& v) { + int ibegin, iend; + + v.clear(); + + string val = node.value(); + while (1 > 0) { + ibegin = val.find_first_not_of(" \n\t"); + if (ibegin >= 0) { + val = val.substr(ibegin,val.size()); + iend = val.find_first_of(" \n\t"); + if (iend > 0) { + v.push_back(val.substr(0,iend)); + val = val.substr(iend+1,val.size()); + } + else { + v.push_back(val.substr(0,iend)); + break; + } + } + else + break; + } + } + + void getFunction(XML_Node& node, string& type, doublereal& xmin, + doublereal& xmax, vector_fp& coeffs) { + XML_Node& c = node.child("floatArray"); + coeffs.clear(); + getFloatArray(c,coeffs); + xmin = Undef; + if (node["min"] != "") xmin = fpValue(node["min"]); + if (node["max"] != "") xmax = fpValue(node["max"]); + type = node["type"]; + } + +} diff --git a/Cantera/src/ctml.h b/Cantera/src/ctml.h new file mode 100755 index 000000000..75d861098 --- /dev/null +++ b/Cantera/src/ctml.h @@ -0,0 +1,92 @@ +/** + * @file ctml.h + * + * CTML ("Cantera Markup Language") is the variant of XML that Cantera uses + * to store data. These functions read and write it. + * + * see also: importCTML, ck2ctml. + */ + + +/* $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2002 California Institute of Technology + + + +#ifndef CT_CTML_H +#define CT_CTML_H + +#include "ct_defs.h" +#include "xml.h" +using namespace Cantera; + +namespace ctml { + + bool isBuiltin(string nm); + + void addBool(XML_Node& node, + string title, + bool val); + + void addInteger(XML_Node& node, + string title, + int val, + string units="", + string type=""); + + void addFloat(XML_Node& node, + string title, + doublereal val, + string units="", + string type="", + doublereal minval = Undef, + doublereal maxval = Undef); + + void addIntegerArray(XML_Node& node, + string title, + int n, + const int* vals, + string units="", + string type="", + doublereal minval=Undef, + doublereal maxval=Undef); + + void addFloatArray(XML_Node& node, + string title, + int n, + const double* vals, + string units="", + string type="", + doublereal minval = Undef, + doublereal maxval = Undef); + + void addString(XML_Node& node, + string title, + string val, + string type=""); + + void getFloatArray(XML_Node& node, + vector_fp& v, bool convert=true); + + void getStringArray(XML_Node& node, vector& v); + void getMap(XML_Node& node, map& m); + void getPairs(XML_Node& node, vector& key, vector& val); + + void getIntegers(XML_Node& node, map& v); + void getFloats(XML_Node& node, map& v, bool convert=true); + doublereal getFloat(XML_Node& parent, string name, string type=""); + void getStrings(XML_Node& node, map& v); + void getFunction(XML_Node& node, string& type, doublereal& xmin, + doublereal& xmax, vector_fp& coeffs); + XML_Node* getByTitle(XML_Node& node, string title); + void getString(XML_Node& node, string title, string& val, + string& type); + + string getString(XML_Node& parent, string name); +} + +#endif diff --git a/Cantera/src/ctvector.cpp b/Cantera/src/ctvector.cpp new file mode 100755 index 000000000..d27f7f11b --- /dev/null +++ b/Cantera/src/ctvector.cpp @@ -0,0 +1,191 @@ +/** + * @file ctvector.cpp + * + * Simple vector classes. Classes ctvector_fp and ctvector_int are + * designed to be wrappers around double* and int* arrays, + * respectively. They provide a few convenient methods that function + * like those of std::vector, but unlike the STL classes explicitly + * allow accessing a pointer to the underlying data array. + */ + +#include +#include "ctvector.h" +#include +using namespace std; +using namespace ct; + + ostream& operator<<(ostream& s, const ctvector_int& v) { + int n = v.size(); + s << "<"; + for (int i = 0; i < n; i++) { + s << v[i]; + if (i < n-1) s << ", "; + } + s << ">"; + return s; + } + + ostream& operator<<(ostream& s, const ctvector_fp& v) { + int n = v.size(); + s << "<"; + for (int i = 0; i < n; i++) { + s << v[i]; + if (i < n-1) s << ", "; + } + s << ">"; + return s; + } + +namespace ct { + + ctvector_fp::ctvector_fp(size_t n) : _size(0), _alloc(0), _data(0) { + if (n > 0) resize(n); + } + + ctvector_fp::ctvector_fp(size_t n, value_type v0) + : _size(0), _alloc(0), _data(0) { + if (n > 0) resize(n, v0); + } + + ctvector_fp::ctvector_fp(const ctvector_fp& x) { + if (x._alloc > 0) { + _data = new value_type[x._alloc]; + copy(x._data, x._data + x._alloc, _data); + } + else { + _data = 0; + } + _size = x._size; + _alloc = x._alloc; + } + + ctvector_fp ctvector_fp::operator=(const ctvector_fp& x) { + if (this == &x) return *this; + delete[] _data; + if (x._alloc > 0) { + _data = new value_type[x._alloc]; + copy(x._data, x._data + x._alloc, _data); + } + else { + _data = 0; + } + _size = x._size; + _alloc = x._alloc; + return *this; + } + + ctvector_fp::~ctvector_fp() { + delete[] _data; + _data = 0; + } + + void ctvector_fp::resize(size_t n) { + size_t new_alloc = n+1; + value_type* newdata = new value_type[new_alloc]; + size_t datalen = (n > _size ? _size : n); + copy(_data, _data + datalen, newdata); + delete[] _data; + _data = newdata; + _alloc = new_alloc; + _size = n; + } + + void ctvector_fp::resize(size_t n, value_type v0) { + size_t new_alloc = n+1; + value_type* newdata = new value_type[new_alloc]; + fill(newdata, newdata + new_alloc, v0); + size_t datalen = (n > _size ? _size : n); + copy(_data, _data + datalen, newdata); + delete[] _data; + _data = newdata; + _alloc = new_alloc; + _size = n; + } + + void ctvector_fp::push_back(value_type x) { + size_t loc = _size; + if (_size == _alloc) { + resize(2*_alloc); + } + _data[loc] = x; + _size = loc + 1; + } + + void ctvector_fp::clear() { fill(_data, _data + _size, 0.0); resize(0); } + + + + //-------------------------------------// + // ctvector_int // + //-------------------------------------// + + + ctvector_int::ctvector_int(size_t n) : _size(0), _alloc(0), _data(0) { + if (n > 0) resize(n); + } + + ctvector_int::ctvector_int(size_t n, value_type v0) + : _size(0), _alloc(0), _data(0) { + if (n > 0) resize(n, v0); + } + + ctvector_int::ctvector_int(const ctvector_int& x) { + if (x._alloc > 0) { + _data = new value_type[x._alloc]; + copy(x._data, x._data + x._alloc, _data); + } + _size = x._size; + _alloc = x._alloc; + } + + ctvector_int ctvector_int::operator=(const ctvector_int& x) { + if (this == &x) return *this; + if (x._alloc > 0) { + _data = new value_type[x._alloc]; + copy(x._data, x._data + x._alloc, _data); + } + _size = x._size; + _alloc = x._alloc; + return *this; + } + + ctvector_int::~ctvector_int() { + if (_alloc > 0) delete[] _data; + _data = 0; + } + + void ctvector_int::resize(size_t n) { + size_t new_alloc = n+1; + value_type* newdata = new value_type[new_alloc]; + size_t datalen = (n > _size ? _size : n); + copy(_data, _data + datalen, newdata); + if (_alloc > 0) delete[] _data; + _data = newdata; + _alloc = new_alloc; + _size = n; + } + + void ctvector_int::resize(size_t n, value_type v0) { + size_t new_alloc = n+1; + value_type* newdata = new value_type[new_alloc]; + fill(newdata, newdata + new_alloc, v0); + size_t datalen = (n > _size ? _size : n); + copy(_data, _data + datalen, newdata); + if (_alloc > 0) delete[] _data; + _data = newdata; + _alloc = new_alloc; + _size = n; + } + + void ctvector_int::push_back(value_type x) { + size_t loc = _size; + if (_size == _alloc) { + resize(2*_alloc); + } + _data[loc] = x; + _size = loc + 1; + } + + void ctvector_int::clear() { fill(_data, _data + _size, 0); resize(0); } +} + diff --git a/Cantera/src/ctvector.h b/Cantera/src/ctvector.h new file mode 100755 index 000000000..beb779df3 --- /dev/null +++ b/Cantera/src/ctvector.h @@ -0,0 +1,115 @@ +/** + * @file ctvector.h + * + * These classes are defined to represent floating-point and integer + * arrays. They act as simplified replacements for std::vector + * and std::vector, respectively. These classes are designed for + * use where it is necessary to access the array of data values + * directly, which not all implementations of std::vector allow. This + * is required, for example, to pass the arrays to Fortran or C + * routines. + * + * They are not implemented as templates since only two data types are + * usually needed, and to allow for different implementations for + * floating-point and integer arrays (i.e., using BLAS). Note that + * the allocated memory is doubled each time new memory is required, + * as is done also in vector. + */ + +#ifndef CT_CTVECTOR_H +#define CT_CTVECTOR_H + +#include + +namespace ct { + + /** + * A class for floating-point arrays + */ + class ctvector_fp { + public: + + typedef unsigned int size_t; + typedef double doublereal; + typedef doublereal* iterator; + typedef const doublereal* const_iterator; + typedef doublereal* pointer; + typedef size_t difference_type; + typedef doublereal value_type; + + ctvector_fp(size_t n=0); + ctvector_fp(size_t n, value_type v0); + ctvector_fp(const ctvector_fp& x); + ctvector_fp operator=(const ctvector_fp& x); + virtual ~ctvector_fp(); + + value_type operator[](size_t n) const { return _data[n]; } + value_type& operator[](size_t n) { return _data[n]; } + + void resize(size_t n); + void resize(size_t n, value_type v0); + + value_type back() const { return _data[_size-1]; } + const_iterator begin() const { return _data; } + iterator begin() { return _data; } + const_iterator end() const { return _data + _size; } + iterator end() { return _data + _size; } + void push_back(value_type x); + size_t size() const { return _size; } + void clear(); + bool empty() const { return (_size == 0); } + + protected: + size_t _size, _alloc; + iterator _data; + private: + }; + + + // integer arrays + class ctvector_int { + public: + + typedef unsigned int size_t; + typedef int integer; + typedef integer* iterator; + typedef const integer* const_iterator; + typedef integer* pointer; + typedef size_t difference_type; + typedef integer value_type; + + ctvector_int(size_t n=0); + ctvector_int(size_t n, value_type v0); + ctvector_int(const ctvector_int& x); + ctvector_int operator=(const ctvector_int& x); + virtual ~ctvector_int(); + + value_type operator[](size_t n) const { return _data[n]; } + value_type& operator[](size_t n) { return _data[n]; } + + void resize(size_t n); + void resize(size_t n, value_type v0); + + value_type back() const { return _data[_size-1]; } + const_iterator begin() const { return _data; } + iterator begin() { return _data; } + const_iterator end() const { return _data + _size; } + iterator end() { return _data + _size; } + void push_back(value_type x); + size_t size() const { return _size; } + void clear(); + bool empty() const { return (_size == 0); } + protected: + size_t _size, _alloc; + iterator _data; + private: + }; + +} + +std::ostream& operator<<(std::ostream& s, const ct::ctvector_fp& v); +std::ostream& operator<<(std::ostream& s, ct::ctvector_fp& v); +std::ostream& operator<<(std::ostream& s, const ct::ctvector_int& v); + + +#endif diff --git a/Cantera/src/exceptions.h b/Cantera/src/exceptions.h new file mode 100755 index 000000000..3e7fa7f43 --- /dev/null +++ b/Cantera/src/exceptions.h @@ -0,0 +1,80 @@ +/** + * @file exceptions.h + * + * @deprecated + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_DEBUG_EXC_H +#define CT_DEBUG_EXC_H + +#include + +#ifdef WIN32 +#define _TYPENAME_ +#else +#define _TYPENAME_ typename +#endif + +__BEGIN_DEBUG_NAMESPACE + +template +void show_values(const T& x, size_t max_show = 20) { + + cerr << "values: <"; + if (x.size() < max_show) { + copy(x.begin(), x.begin() + x.size(), + ostream_iterator<_TYPENAME_ T::value_type>(cerr, " ")); + } + else { + size_t m2 = max_show/2; + copy(x.begin(), x.begin() + m2, + ostream_iterator<_TYPENAME_ T::value_type>(cerr, " ")); + cerr << "...(skipping " << x.size() - max_show << ")... "; + copy(x.end() - max_show + m2, x.end(), + ostream_iterator<_TYPENAME_ T::value_type>(cerr, " ")); + } + cerr << ">" << endl << endl; +} + + +template +class RangeError { + +public: + + RangeError(const T& vec, typename T::size_type n) { + + cerr << "\n###RANGE ERROR###\n" + << "attempt to access element " + << n << " outside valid range [0," + << vec.size()-1 << "]" << endl; + cerr << "object at " << &vec << endl; + show_values(vec); + } +}; + + +template +class SizeError { + +public: + + SizeError(const T& vec, typename T::size_type n) { + + cerr << "\n###SIZE ERROR###\n" + << "size = " << vec.size() << ", but should be " << n < + void fitPolynomial(int n, M& mix, int fittype, vector& coeffs, + doublereal tmin = -1.0, doublereal tmax = -1.0) { + int i, k; + doublereal temp; + if (tmin < 0.0) tmin = mix.minTemp(); + if (tmax < 0.0) tmax = mix.maxTemp(); + + // generate data + int np = int((tmax - tmin)/20.0 + 1); + if (np < 2*n+2) np = 2*n+2; + doublereal dt = (tmax - tmin)/(np - 1); + + int nsp = mix.nSpecies(); + + coeffs.resize(nsp); + + vector cp(nsp); + vector_fp x(np), w(np); + for (k = 0; k < nsp; k++) { + cp[k].resize(np); + } + + mix.setTemperature(298.15); + vector_fp h0 = mix.enthalpy_RT(); + vector_fp s0 = mix.entropy_R(); + + for (i = 0; i < np; i++) { + temp = tmin + i*dt; + mix.setTemperature(temp); + const vector_fp& cpr = mix.cp_R(); + switch (fittype) { + case 0: x[i] = temp; break; + case 1: x[i] = 1.0/temp; break; + case 2: x[i] = log(temp); break; + default: + cout << " unknown fit type (" << fittype << ")" << endl; + return; + } + w[i] = -1.0; + for (k = 0; k < nsp; k++) { + cp[k][i] = cpr[k]; + } + } + doublereal err; + for (k = 0; k < nsp; k++) { + coeffs[k].resize(n + 3); + err = polyfit(np, x.begin(), cp[k].begin(), w.begin(), + n, n, 0.0, coeffs[k].begin()+2); + coeffs[k][0] = 298.15 * (h0[k] - + poly_enthalpy_RT(298.15, n, coeffs[k].begin()+2, 0.0)); + coeffs[k][1] = (s0[k] + - poly_entropy_R(298.15, n, coeffs[k].begin()+2, 0.0)); + } + } +} + +#undef TESTIT +#ifdef TESTIT + +#include "Cantera.h" +#include "../Cantera/src/IdealGasMix.h" + +main() { + IdealGasMix mix("gri30.inp"); + int fittype = 0; + int n; + cout << " enter n: "; + cin >> n; + fitPolynomial(n, mix, fittype); +} + +#endif + +#endif diff --git a/Cantera/src/flowBoundaries.h b/Cantera/src/flowBoundaries.h new file mode 100755 index 000000000..da59dc5d0 --- /dev/null +++ b/Cantera/src/flowBoundaries.h @@ -0,0 +1,213 @@ +/** + * + */ + +#ifndef CT_FLOW_BOUNDS +#define CT_FLOW_BOUNDS + +#include +#include "ct_defs.h" +//#include "surfKinetics.h" + +using namespace Cantera; + +namespace FlowBdry { + + class Boundary { + + public: + Boundary(int nsp = 0) + : rtau(1.e5), m_lr(1), m_nsp(nsp), m_nv(nsp+4), + m_bv(0), m_bp(0), m_temp(0.0), m_mdot(0.0), m_V(0.0) { + m_y.resize(nsp, 0.1); + } + virtual ~Boundary(){} + + doublereal rtau; + doublereal T() { return m_temp; } + doublereal mdot() { return m_mdot; } + doublereal V() { return m_V; } + doublereal* Y() { return m_y.begin(); } + + int orient() { return m_lr; } + int faceLeft() { m_lr = -1; return m_lr; } + int faceRight() { m_lr = 1; return m_lr; } + + void setNSpecies(int n) { m_nsp = n; } + void set_mdot(doublereal mdot) { m_mdot = mdot; } + void set_V(doublereal V) { m_V = V; } + void set_T(doublereal T) { m_temp = T; } + void set_Y(const doublereal* y) { + copy(y, y+m_nsp, m_y.begin()); + } + + virtual void evalInt(int j, doublereal* x, doublereal* r) { + int i; + for (i = 0; i < m_bv; i++) { + r[i] = x[i]; + } + } + virtual void eval(doublereal* x0, doublereal density, + doublereal* data, doublereal* r) { + throw CanteraError("Boundary::eval", + " ERROR!! Base class eval called!"); + } + + virtual int nIntVars() { return m_bv; } + virtual int nIntPoints() { return m_bp; } + + protected: + + int offset(int n) { return m_lr*n*m_nv; } + + int m_lr, m_nsp, m_nv; + int m_bv, m_bp; + doublereal m_temp, m_mdot, m_V; + vector_fp m_y; + }; + + + /** + * zero axial velocity, zero gradients for everything else. + */ + class SymmPlane : public Boundary { + + public: + SymmPlane(int nsp) : Boundary(nsp) {} + virtual ~SymmPlane() {} + + virtual void eval(doublereal* x0, doublereal density, + doublereal* data, doublereal* r) { + for (int n = 0; n < m_nv; n++) { + r[n] = x0[n] - x0[offset(1) + n]; + } + r[0] = x0[0]; + } + + protected: + int m_iloc; + }; + + + + /** + * Zero gradients for all components, except V, which is zero. + */ + class Outlet : public Boundary { + + public: + + Outlet(int nsp) : Boundary(nsp) {} + virtual ~Outlet() {} + + virtual void eval(doublereal* x0, doublereal density, + doublereal* data, doublereal* r) { + for (int n = 0; n < m_nv; n++) { + r[n] = -rtau*(x0[n] - x0[offset(1) + n]); + } + r[1] = -rtau*x0[1]; + } + }; + + +#ifdef INCL_SURF + + class Surface : public Boundary { + + public: + + Surface(int nsp, SurfKinetics* kin=0) + : Boundary(nsp), m_kin(kin), m_dt(1.e3) { + if (m_kin) + m_sdot.resize(m_kin->nTotal()); + else + m_sdot.resize(nsp); + } + virtual ~Surface(){} + + + virtual void eval(doublereal* x0, doublereal density, + doublereal* data, doublereal* r) { + + doublereal sum = 0.0, mdot = 0.0; + // updateSurfaceRates(x0[2], density, x0+4); + + for (int k = 0; k < m_nsp; k++) { + // r[4+k] = m_sdot[k] - m_lr*data[k]; + //mdot += m_sdot[k]; + //sum += x0[4+k]; + r[4+k] = - m_lr*data[k]; + sum += x0[4+k]; + } + r[4] = 1.0 - sum; + + // match the Stefan velocity at the surface + r[0] = density*x0[0] - m_lr*mdot; + r[1] = x0[1]; // no slip + r[2] = x0[2] - m_temp; // specified T + r[3] = x0[3]; + } + + /** + * Update the mass species production rates, given + * the species mass fractions at the surface. + * @param y + */ + virtual void updateSurfaceRates(doublereal t, + doublereal rho, doublereal* y) { + int k; + if (m_kin) { + for (k = 0; k < m_nsp; k++) { + m_sdot[k] = fmaxx(Tiny, y[k]); + } + m_kin->bulkPhase(0)->setState_TR(t, rho); + m_kin->bulkPhase(0)->setMassFractions_NoNorm(m_sdot.begin()); + //m_kin->integrate(m_dt); + m_kin->getNetProductionRates(m_sdot.begin()); + } + else + for (k = 0; k < m_nsp; k++) m_sdot[k] = 0.0; + + } + + + + protected: + + const doublereal* m_wt; + vector_fp m_sdot; + SurfKinetics* m_kin; + doublereal m_dt; + }; + +#endif + + class Inlet : public Boundary { + + public: + Inlet(int nsp, doublereal* wt=0) + : Boundary(nsp) {} + virtual ~Inlet(){} + + virtual void eval(doublereal* x0, + doublereal density, doublereal* flux, doublereal* r) { + int k; + for (k = 0; k < m_nsp; k++) { + r[4+k] = rtau*(m_y[k] - x0[k+4] - flux[k]/m_mdot); + // cout << k << " " << m_y[k] << " " << flux[k] + // << " " << density << " " << x0[0] << " " + // << x0[k+4] << " " << m_mdot << endl; + } + r[0] = -rtau*(density*x0[0] - m_lr*m_mdot); + r[1] = -rtau*(x0[1] - V()); + r[2] = -rtau*(x0[2] - T()); // specified T + r[3] = -rtau*x0[3]; + //cout << "inlet: r[2], x0[2] = " << r[2] << " " << x0[2] << endl; + } + }; + +} + + + +#endif diff --git a/Cantera/src/funcs.cpp b/Cantera/src/funcs.cpp new file mode 100755 index 000000000..9456df6f7 --- /dev/null +++ b/Cantera/src/funcs.cpp @@ -0,0 +1,50 @@ + +// miscellaneous functions + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include +using namespace std; + +#include "ct_defs.h" +#include "ctexceptions.h" + +extern "C" { + + int dpolft_(integer* n, doublereal* x, doublereal* y, doublereal* w, + integer* maxdeg, integer* ndeg, doublereal* eps, doublereal* r, + integer* ierr, doublereal* a); + + int dpcoef_(integer* l, doublereal* c, doublereal* tc, doublereal* a); +} + +namespace Cantera { + + doublereal polyfit(int n, doublereal* x, doublereal* y, doublereal* w, + int maxdeg, int& ndeg, doublereal eps, doublereal* r) { + integer nn = n; + integer mdeg = maxdeg; + integer ndg = ndeg; + doublereal epss = eps; + integer ierr; + int worksize = 3*n + 3*maxdeg + 3; + vector_fp awork(worksize,0.0); + vector_fp coeffs(n+1, 0.0); + doublereal zer = 0.0; + + dpolft_(&nn, x, y, w, &mdeg, &ndg, &epss, coeffs.begin(), + &ierr, awork.begin()); + if (ierr != 1) throw CanteraError("polyfit", + "DPOLFT returned error code IERR = " + int2str(ierr) + + "while attempting to fit " + int2str(n) + " data points " + + "to a polynomial of degree " + int2str(maxdeg)); + ndeg = ndg; + dpcoef_(&ndg, &zer, r, awork.begin()); + return epss; + } + + +} diff --git a/Cantera/src/gases.h b/Cantera/src/gases.h new file mode 100755 index 000000000..e452a991f --- /dev/null +++ b/Cantera/src/gases.h @@ -0,0 +1,29 @@ +/** + * @file gases.h + * + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_GASES_H +#define CT_GASES_H + +#include "IdealGasMix.h" +#include "TransportFactory.h" + +namespace Cantera { + + template + class GasWithTransport : public IdealGasMix, public T { + public: + GasWithTransport(map& params, + TransportFactory* f = 0) { + if (f == 0) + f = TransportFactory::factory(); + f->initTransport(*self, dbase); + } + }; +} + +#endif diff --git a/Cantera/src/global.h b/Cantera/src/global.h new file mode 100755 index 000000000..8dcf909e0 --- /dev/null +++ b/Cantera/src/global.h @@ -0,0 +1,62 @@ +/** + * @file global.h + */ + +/* $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + +#ifndef CT_GLOBAL_H +#define CT_GLOBAL_H + +#include +#include "ct_defs.h" + +namespace Cantera { + + /// Number of errors that have been encountered + int nErrors(); + + /// The last error message + string lastErrorMessage(); + + /// Add an error message + void setError(string r, string msg); + + /// Print the error messages to f + void showErrors(ostream& f); + + /// Discard the last error message + void popError(); + + /// Find a file on a search path + string findInputFile(string name); + + /// Add a directory to the search path + void addDirectory(string dir); + + /// Write a message + void write(const string& msg); + + /// Write a message + void write(const char* msg); + + string canteraRoot(); + + /** + * Write a diagnostic message to an internal buffer. + */ + void writelog(const string& msg); + void writelog(const char* msg); + + + void getlog(string& s); + void clearlog(); + doublereal toSI(string unit); + // +} + +#endif diff --git a/Cantera/src/import.h b/Cantera/src/import.h new file mode 100755 index 000000000..08a07ed02 --- /dev/null +++ b/Cantera/src/import.h @@ -0,0 +1,41 @@ +/** + * @file import.h + * + * functions to import objects from files. + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_IMPORTERS_H +#define CT_IMPORTERS_H + +#include "importCK.h" +//#include "importXML.h" +#include "importCTML.h" + +namespace Cantera { + + /** + * import the specifications for a phase from a file, including + * elements, species, and reactions. The file formats currently + * supported are + * + * - CKML "Chemical Kinetics Markup Language." This XML-based + * markup language has been developed by M. Aivazis and R. Muller + * at Caltech and is used in their Fuego software package. + * + * - CK This is the name we give to the widely-used format + * developed by Kee, Miller, and Rupley for the Chemkin-II + * software package. + * + */ + bool importFromFile(Thermo* th, Kinetics* k, map& params); + +} + +#endif diff --git a/Cantera/src/importCTML.cpp b/Cantera/src/importCTML.cpp new file mode 100755 index 000000000..9b87a3e6c --- /dev/null +++ b/Cantera/src/importCTML.cpp @@ -0,0 +1,828 @@ +/* + * @file importCTML.cpp + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2002 California Institute of Technology + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "importCTML.h" +#include "mix_defs.h" +#include + +// STL includes +#include +#include +#include +using namespace std; + +// Cantera includes +#include "speciesThermoTypes.h" +#include "ThermoPhase.h" +#include "ThermoFactory.h" +#include "SpeciesThermoFactory.h" +#include "KineticsFactory.h" +#include "reaction_defs.h" +#include "ReactionData.h" +#include "global.h" +#include "stringUtils.h" + +#include "xml.h" +#include "ctml.h" +using namespace ctml; + +#include + +namespace Cantera { + + typedef vector nodeset_t; + typedef XML_Node node_t; + + static int intValue(string val) { + return atoi(stripws(val).c_str()); + } + + static doublereal fpValue(string val) { + return atof(stripws(val).c_str()); + } + + /// Number of reactant molecules + static int nReacMolecules(ReactionData& r) { + return accumulate(r.rstoich.begin(), r.rstoich.end(), 0); + } + + const doublereal DefaultPref = 1.01325e5; // one atm + + /** + * Get an XML tree from a file. If successful, a pointer to the + * document root is returned. If not, a null pointer is returned. + */ + XML_Node* get_XML(string file) { + string inname = findInputFile(file); + if (inname == "") return 0; + ifstream fin(inname.c_str()); + + XML_Node* rootPtr = new XML_Node; + try { + rootPtr->build(fin); + } + catch (...) { + return 0; + } + fin.close(); + return rootPtr; + } + + + /** + * Install a NASA polynomial thermodynamic property + * parameterization for species k. + */ + void installNasaThermo(SpeciesThermo& sp, int k, XML_Node& f) { + doublereal tmin, tmid, tmax; + tmin = fpValue(f["Tmin"]); + tmid = fpValue(f["Tmid"]); + tmax = fpValue(f["Tmax"]); + + vector fa; + f.getChildren("floatArray",fa); + vector_fp c0, c1; + getFloatArray(*fa[0], c0, false); + getFloatArray(*fa[1], c1, false); + array_fp c(15); + c[0] = tmid; + doublereal p0 = OneAtm; + if ((*fa[0])["title"] == "low") { + c[1] = c0[5]; + c[2] = c0[6]; + copy(c0.begin(), c0.begin()+5, c.begin() + 3); + c[8] = c1[5]; + c[9] = c1[6]; + copy(c1.begin(), c1.begin()+5, c.begin() + 10); + } + else { + c[1] = c1[5]; + c[2] = c1[6]; + copy(c1.begin(), c1.begin()+5, c.begin() + 3); + c[8] = c0[5]; + c[9] = c0[6]; + copy(c0.begin(), c0.begin()+5, c.begin() + 10); + } + sp.install(k, NASA, c.begin(), tmin, tmax, p0); + } + + /** + * Install a Shomate polynomial thermodynamic property + * parameterization for species k. + */ + void installShomateThermo(SpeciesThermo& sp, int k, XML_Node& f) { + doublereal tmin, tmid, tmax; + tmin = fpValue(f["Tmin"]); + tmid = fpValue(f["Tmid"]); + tmax = fpValue(f["Tmax"]); + + vector fa; + f.getChildren("floatArray",fa); + vector_fp c0, c1; + getFloatArray(*fa[0], c0, false); + getFloatArray(*fa[1], c1, false); + array_fp c(15); + c[0] = tmid; + doublereal p0 = OneAtm; + if ((*fa[0])["title"] == "low") { + copy(c0.begin(), c0.end(), c.begin() + 1); + copy(c1.begin(), c1.end(), c.begin() + 8); + } + else { + copy(c1.begin(), c1.end(), c.begin() + 1); + copy(c0.begin(), c0.end(), c.begin() + 8); + } + sp.install(k, SHOMATE, c.begin(), tmin, tmax, p0); + } + + /** + * Install a Shomate polynomial thermodynamic property + * parameterization for species k. + */ + void installSimpleThermo(SpeciesThermo& sp, int k, XML_Node& f) { + doublereal tmin, tmax; + tmin = fpValue(f["Tmin"]); + tmax = fpValue(f["Tmax"]); + if (tmax == 0.0) tmax = 1.0e30; + + //map fp; + //getFloats(f, fp); + vector_fp c(4); + c[0] = getFloat(f, "t0", "-"); + c[1] = getFloat(f, "h0", "-"); + c[2] = getFloat(f, "s0", "-"); + c[3] = getFloat(f, "cp0", "-"); + doublereal p0 = OneAtm; + sp.install(k, SIMPLE, c.begin(), tmin, tmax, p0); + } + + bool installSpecies(int k, XML_Node& s, thermo_t& p, SpeciesThermo& spthermo, int rule) { + + // get the composition of the species + XML_Node& a = s.child("atomArray"); + map comp; + getMap(a, comp); + + // check that all elements in the species + // exist in 'p' + map::const_iterator _b = comp.begin(); + for (; _b != comp.end(); ++_b) { + if (p.elementIndex(_b->first) < 0) { + if (rule == 0) + throw CanteraError("installSpecies", + "species " + s["name"] + + " contains undeclared element " + _b->first); + else + return false; + } + } + + int m, nel = p.nElements(); + vector_fp ecomp(nel, 0.0); + for (m = 0; m < nel; m++) { + ecomp[m] = atoi(comp[p.elementName(m)].c_str()); + } + + /* + * Define a map and get all of the floats in the + * current XML species block + */ + map fd; + getFloats(s, fd); + + /* + * Set a default for the size parameter to one + */ + if (fd["size"] == 0.0) fd["size"] = 1.0; + p.addUniqueSpecies(s["name"], ecomp.begin(), + fd["charge"], fd["size"]); + + // get thermo + XML_Node& thermo = s.child("thermo"); + vector tp = thermo.children(); + int nc = tp.size(); + if (nc == 1) { + XML_Node& f = *tp[0]; + if (f.name() == "NASA") { + installNasaThermo(spthermo, k, f); + } + else if (f.name() == "Shomate") { + installShomateThermo(spthermo, k, f); + } + else if (f.name() == "const_cp") { + installSimpleThermo(spthermo, k, f); + } + else + throw CanteraError("importCTML", + "Unsupported species thermo parameterization" + " for species "+s["name"]); + } + else + throw CanteraError("importCTML", + "Multiple thermo parameterizations given for " + "species "+s["name"]); + + return true; + } + + + /** + * Get the reactants or products of a reaction. + */ + bool getReagents(XML_Node& rxn, kinetics_t& kin, int rp, + string default_phase, + vector_int& spnum, vector_int& stoich, vector_fp& order, + int rule) { + + string rptype; + if (rp == 1) rptype = "reactants"; + else rptype = "products"; + XML_Node& rg = rxn.child(rptype); + vector key, val; + getPairs(rg, key, val); + + int ns = key.size(); + int stch, isp; + doublereal ord; + string ph, sp; + for (int n = 0; n < ns; n++) { + sp = key[n]; + ph = ""; //snode["phase"]; + //if (ph == "") ph = default_phase; + isp = kin.kineticsSpeciesIndex(sp,""); + if (isp < 0) { + if (rule == 1) + return false; + else { + throw CanteraError("getReagents", + "undeclared reactant or product species "+sp); + return false; + } + } + spnum.push_back(isp); + stch = atoi(val[n].c_str()); + stoich.push_back(stch); + ord = doublereal(stch); + order.push_back(ord); + } + return true; + } + + + void getArrhenius(XML_Node& node, int& order, doublereal& A, doublereal& b, + doublereal& E) { + + // get rxn order to do unit conversion for pre-exponential + order = intValue(node["order"]); + + //nodeset_t c = node.children(); + + vector abe; + getStringArray(node, abe); + A = fpValue(abe[0]); + b = fpValue(abe[1]); + E = fpValue(abe[2]); + + string u = (*node.parent())["units"]; + string eu = (*node.parent())["Eunits"]; + + doublereal cmult = 1.0; + if (u != "") { + if (u == "mol,cm,s") + cmult = 1.0e-6 / CtMoles_per_mole; + else if (u == "molec,cm,s") + cmult = 1.0e-6*Avogadro; + else + throw CanteraError("getArrhenius","unknown units for A"); + } + A *= pow(cmult, order - 1); + + doublereal gasConstant = 1.0; + if (eu != "") { + if (eu == "cal/mol") + gasConstant = 1.987; + else if (eu == "kcal/mol") + gasConstant = 1.987e-3; + else if (eu == "J/mol") + gasConstant = 8.314; + else if (eu == "kJ/mol") + gasConstant = 8.314e-3; + else if (eu == "K") + gasConstant = 1.0; + else if (eu == "eV") + gasConstant = 1.0/11600.0; + else + throw CanteraError("getArrhenius", + "unknown units for activation energy: "+eu); + } + E /= gasConstant; + } + + + /** + * Get falloff parameters for a reaction. + */ + void getFalloff(node_t& f, ReactionData& rdata) { + string type = f["type"]; + vector p; + getStringArray(f,p); + vector_fp c; + int np = p.size(); + for (int n = 0; n < np; n++) { + c.push_back(fpValue(p[n])); + } + if (type == "Troe") { + if (np == 4) rdata.falloffType = TROE4_FALLOFF; + else rdata.falloffType = TROE3_FALLOFF; + } + else if (type == "SRI") { + if (np == 5) rdata.falloffType = SRI5_FALLOFF; + else rdata.falloffType = SRI3_FALLOFF; + } + rdata.falloffParameters = c; + } + + /** + * Get the enhanced collision efficiencies. It is assumed that the + * reaction mechanism is homogeneous, so that all species belong + * to phase(0) of 'kin'. + */ + void getEfficiencies(node_t& eff, kinetics_t& kin, ReactionData& rdata) { + + // set the default collision efficiency + rdata.default_3b_eff = fpValue(eff["default"]); + + vector key, val; + getPairs(eff, key, val); + int ne = key.size(); + //map e; + //getFloats(eff, e, false); + //map::const_iterator bb = e.begin(), ee = e.end(); + string nm; + string phse = kin.thermo(0).id(); + int n, k; + for (n = 0; n < ne; n++) { // ; bb != ee; ++bb) { + nm = key[n];// bb->first; + k = kin.kineticsSpeciesIndex(nm, phse); + rdata.thirdBodyEfficiencies[k] = fpValue(val[n]); // bb->second; + } + } + + /** + * Get the rate coefficient for a reaction. + */ + void getRateCoefficient(node_t& kf, kinetics_t& kin, ReactionData& rdata) { + + int nc = kf.nChildren(); + const nodeset_t& kf_children = kf.children(); + vector_fp clow(3,0.0), chigh(3,0.0); + int nr = nReacMolecules(rdata); + for (int m = 0; m < nc; m++) { + node_t& c = *kf_children[m]; + string nm = c.name(); + int order=0; + + if (nm == "Arrhenius") { + vector_fp coeff(3); + getArrhenius(c, order, coeff[0], coeff[1], coeff[2]); + if (order == 0) order = nr; + if (order == nr || rdata.reactionType == THREE_BODY_RXN) + chigh = coeff; + else if (order == nr + 1) clow = coeff; + else { + cerr << "\n\n\n" << endl; + kf.write(cerr); + throw CanteraError("importCTML", + "wrong Arrhenius coeff order"); + } + } + else if (nm == "falloff") { + getFalloff(c, rdata); + } + else if (nm == "efficiencies") { + getEfficiencies(c, kin, rdata); + } + } + + if (rdata.reactionType == CHEMACT_RXN) + rdata.rateCoeffParameters = clow; + else + rdata.rateCoeffParameters = chigh; + + if (rdata.reactionType == FALLOFF_RXN) + rdata.auxRateCoeffParameters = clow; + else if (rdata.reactionType == CHEMACT_RXN) + rdata.auxRateCoeffParameters = chigh; + + } + + + /** + * Create a new ThermoPhase object. + */ + ThermoPhase* newPhase(XML_Node& xmlphase) { + XML_Node& th = xmlphase.child("thermo"); + string model = th["model"]; + ThermoPhase* t = newThermoPhase(model); + importPhase(xmlphase, t); + return t; + } + + + /** + * Set the thermodynamic state. + */ + static void setState(XML_Node& phase, ThermoPhase* th) { + if (!phase.hasChild("state")) return; + XML_Node state = phase.child("state"); + doublereal t, p, rho; + string comp = getString(state,"moleFractions"); + if (comp != "") + th->setMoleFractionsByName(comp); + else { + comp = getString(state,"massFractions"); + if (comp != "") + th->setMassFractionsByName(comp); + } + t = getFloat(state, "temperature", "temperature"); + if (t > 0.0) th->setTemperature(t); + p = getFloat(state, "pressure", "pressure"); + if (p > 0.0) th->setPressure(p); + rho = getFloat(state, "density", "density"); + if (rho > 0.0) th->setDensity(rho); + } + + /** + * Import a phase specification. + */ + bool importPhase(XML_Node& phase, ThermoPhase* th) { + + if (phase.name() != "phase") + throw CanteraError("importPhase", + "Current XML_Node is not a phase element."); + + th->setID(phase.id()); // set the phase id + + // Number of spatial dimensions. Defaults to 3 (bulk phase) + if (phase.hasAttrib("dim")) { + int idim = intValue(phase["dim"]); + if (idim < 1 || idim > 3) + throw CanteraError("importPhase", + "unphysical number of dimensions: "+phase["dim"]); + th->setNDim(idim); + } + else + th->setNDim(3); // default + + + // equation of state + if (phase.hasChild("thermo")) { + XML_Node& eos = phase.child("thermo"); + if (eos["model"] == "Incompressible") { + if (th->eosType() == cIncompressible) { + map d; + getFloats(eos, d); + doublereal rho = d["density"]; + th->setParameters(1, &rho); + } + else { + throw CanteraError("importCTML", + "wrong equation of state type"); + } + } + else if (eos["model"] == "Surface") { + if (th->eosType() == cSurf) { + map d; + //getFloats(eos, d); + doublereal n = fpValue(eos("site_density")); + th->setParameters(1, &n); + } + else { + throw CanteraError("importCTML", + "wrong equation of state type"); + } + } + } + + + /************************************************* + * Add the elements. + ************************************************/ + + + // get the declared element names + XML_Node& elements = phase.child("elementArray"); + vector enames; + getStringArray(elements, enames); + + // // element database defaults to elements.xml + string element_database; // = "elements.xml"; + if (elements.hasAttrib("datasrc")) + element_database = elements["datasrc"]; + XML_Node* db = find_XML(element_database,&phase.root(),"","", + "elementData"); + + int nel = enames.size(); + int i; + string enm; + for (i = 0; i < nel; i++) { + XML_Node* e = db->findByAttr("name",enames[i]); + if (e) { + th->addUniqueElement(*e); + } + else { + throw CanteraError("importPhase","no data for element " + +enames[i]); + } + } + delete db; + db = 0; + + + /*************************************************************** + * Add the species. First get the speciesArray element, then + * the species database. + ***************************************************************/ + + XML_Node& species = phase.child("speciesArray"); + + int sprule = 0; + if (species.hasChild("skip")) { + XML_Node& sk = species.child("skip"); + string eskip = sk["element"]; + if (eskip == "undeclared") { + sprule = 1; + } + } + + db = find_XML(species["datasrc"], &phase.root(), species["idRef"], + "","speciesData"); + + + /******************************************************* + * Set the species thermo manager. + * Function 'newSpeciesThermoMgr' looks at the species + * in the database to see what thermodynamic property + * parameterizations are used, and selects a class + * that can handle the parameterizations found. + ******************************************************/ + + delete &th->speciesThermo(); + SpeciesThermo* spth = newSpeciesThermoMgr(db); + th->setSpeciesThermo(spth); + SpeciesThermo& spthermo = th->speciesThermo(); + + + /* + * Get the array of species name strings. + */ + vector spnames; + getStringArray(species, spnames); + int nsp = spnames.size(); + + map declared; + string name; + int k = 0; + for (i = 0; i < nsp; i++) { + name = spnames[i]; + + // Check that every species is only declared once + if (declared[name]) { + throw CanteraError("importPhase", + "duplicate species: "+name); + } + declared[name] = true; + + /* + * Find the species in the database by name. + */ + XML_Node* s = db->findByAttr("name",spnames[i]); + if (s) { + if (installSpecies(k, *s, *th, spthermo, sprule)) + ++k; + } + else { + throw CanteraError("importPhase","no data for species " + +name); + } + } + th->freezeSpecies(); + th->initThermo(); + setState(phase, th); + + th->saveSpeciesData(db); + return true; + } + + + + bool installReaction(int i, XML_Node& r, Kinetics* k, + string default_phase, int rule) { + + Kinetics& kin = *k; + ReactionData rdata; + rdata.reactionType = ELEMENTARY_RXN; + vector_int reac, prod; + string eqn, type; + int nn, eqlen; + vector_fp dummy; + + eqn = r("equation"); + eqlen = eqn.size(); + for (nn = 0; nn < eqlen; nn++) { + if (eqn[nn] == '[') eqn[nn] = '<'; + if (eqn[nn] == ']') eqn[nn] = '>'; + } + + bool ok; + // get the reactants + ok = getReagents(r, kin, 1, default_phase, rdata.reactants, + rdata.rstoich, rdata.order, rule); + + // get the products + ok = ok && getReagents(r, kin, -1, default_phase, rdata.products, + rdata.pstoich, dummy, rule); + if (!ok) { + cout << "skipping " << eqn << endl; + return false; + } + + rdata.equation = eqn; + rdata.reversible = false; + rdata.number = i; + rdata.rxn_number = i; + + string typ = r["type"]; + if (typ == "falloff") { + rdata.reactionType = FALLOFF_RXN; + rdata.falloffType = SIMPLE_FALLOFF; + } + else if (typ == "chemAct") { + rdata.reactionType = CHEMACT_RXN; + rdata.falloffType = SIMPLE_FALLOFF; + } + else if (typ == "threeBody") { + rdata.reactionType = THREE_BODY_RXN; + } + else if (typ != "") + throw CanteraError("installReaction", + "Unknown reaction type: " + typ); + + string isrev = r["reversible"]; + if (isrev == "yes" || isrev == "true") + rdata.reversible = true; + + getRateCoefficient(r.child("rateCoeff"), kin, rdata); + kin.addReaction(rdata); + return true; + } + + + bool installReactionArrays(XML_Node& p, Kinetics& kin, + string default_phase) { + vector rarrays; + int itot = 0; + p.getChildren("reactionArray",rarrays); + int na = rarrays.size(); + if (na == 0) return false; + for (int n = 0; n < na; n++) { + XML_Node& rxns = *rarrays[n]; + XML_Node* rdata = find_XML(rxns["datasrc"],&rxns.root(), + "","","reactionData"); + + int rxnrule = 0; + if (rxns.hasChild("skip")) { + XML_Node& sk = rxns.child("skip"); + string sskip = sk["species"]; + if (sskip == "undeclared") { + rxnrule = 1; + } + } + + vector incl; + rxns.getChildren("include",incl); + int ninc = incl.size(); + for (int nii = 0; nii < ninc; nii++) { + int nrxns = 0; + XML_Node& ii = *incl[nii]; + vector rxn_ids; + string pref = ii["prefix"]; + int imin = atoi(ii["min"].c_str()); + int imax = atoi(ii["max"].c_str()); + if (imin != 0 && imax != 0) { + nrxns = imax - imin + 1; + for (int nn=0; nnfindID(rxn_ids[i],1); + if (r) { + if (installReaction(itot, *r, &kin, + default_phase, rxnrule)) ++itot; + } + } + } + } + kin.finalize(); + return true; + } + + + /** + * Import a reaction mechanism for a phase or an interface. + */ + bool importKinetics(XML_Node& phase, vector th, + Kinetics* k) { + + Kinetics& kin = *k; + + // This phase will be the default one + string default_phase = phase["id"]; + + // if other phases are involved in the reaction mechanism, + // they must be listed in a 'phaseArray' child + // element. Homogeneous mechanisms do not need to include a + // phaseArray element. + + vector phase_ids; + if (phase.hasChild("phaseArray")) { + XML_Node& pa = phase.child("phaseArray"); + getStringArray(pa, phase_ids); + } + phase_ids.push_back(default_phase); + + int np = phase_ids.size(); + + int nt = th.size(); + + // for each referenced phase, attempt to find its id among those + // phases that have already been built. + bool phase_ok; + + string phase_id; + for (int n = 0; n < np; n++) { + phase_id = phase_ids[n]; + phase_ok = false; + + // loop over the supplied 'ThermoPhase' objects representing + // phases, to find an object with the same id. + for (int m = 0; m < nt; m++) { + if (th[m]->id() == phase_id) { + phase_ok = true; + + // if no phase with this id has been added to + //the kinetics manager yet, then add this one + if (kin.phaseIndex(phase_id) < 0) { + kin.addPhase(*th[m]); + } + } + } + if (!phase_ok) { + throw CanteraError("importKinetics", + "phase "+phase_id+" not found."); + } + } + + // allocates arrays, etc. Must be called after the phases have + // been added to 'kin', so that the number of species in each + // phase is known. + kin.init(); + + // Install the reactions. + return installReactionArrays(phase, kin, default_phase); + } + + /** + * Build a single-phase solution. + */ + bool buildSolutionFromXML(XML_Node& root, string id, string nm, + ThermoPhase* th, Kinetics* k) { + XML_Node* x; + x = find_XML("", &root, id, "", nm); + if (!x) return false; + + importPhase(*x, th); + + vector phases(1); + phases[0] = th; + importKinetics(*x, phases, k); + + return true; + } +} + diff --git a/Cantera/src/importCTML.h b/Cantera/src/importCTML.h new file mode 100755 index 000000000..f8208f49c --- /dev/null +++ b/Cantera/src/importCTML.h @@ -0,0 +1,36 @@ +/** + * @file importCTML.h + * + * $Author$ + * $Revision$ + * $Date$ + * + */ + +// Copyright 2002 California Institute of Technology + + +#ifndef CT_IMPORTCTML_H +#define CT_IMPORTCTML_H + +#include + +#include "Kinetics.h" +#include "transport/TransportBase.h" + +namespace Cantera { + + bool isCTMLFile(string infile); + bool importPhase(XML_Node& phase, thermophase_t* th); + bool importKinetics(XML_Node& phase, vector th, + Kinetics* kin); + bool installReactionArrays(XML_Node& parent, Kinetics& kin, + string default_phase); + ThermoPhase* newPhase(XML_Node& phase); + bool buildSolutionFromXML(XML_Node& root, string id, string nm, + ThermoPhase* th, Kinetics* k); + +} + +#endif + diff --git a/Cantera/src/importSurfChem.cpp b/Cantera/src/importSurfChem.cpp new file mode 100755 index 000000000..b2be5b8a4 --- /dev/null +++ b/Cantera/src/importSurfChem.cpp @@ -0,0 +1,106 @@ + +#include "surfKinetics.h" +#include "ctml.h" +using namespace ctml; + +namespace Cantera { + + + /** + * Import a surface reaction mechanism + */ + void importInterfaceData(SurfacePhase* ph, SurfKinetics* kin, + string fname, string id) { + + ifstream f(fname.c_str()); + XML_Node root; + root.build(f); + + XML_Node* srxns = root.findID(id); + map fmap; + getFloats(*srxns, fmap); + ph->setSiteDensity(fmap["site_density"]); + XML_Node& spset = srxns->child("SpeciesArray"); + vector sp; + spset.getChildren("species",sp); + int nsp = sp.size(); + int k; + for (k = 0; k < nsp; k++) { + XML_Node& s = *sp[k]; + ph->addSpecies(s["name"], atof(s["size"].c_str())); + } + + vector rxns; + srxns->child("ReactionArray").getChildren("reaction",rxns); + int nrxns = rxns.size(); + int i, n; + string phase; + vector_int rindex, order, rstoich, pindex, pstoich; + + // get bulk phase data + int kk1 = kin->bulkPhase(0)->nSpecies(); + int kk2 = 0; + if (kin->bulkPhase(1)) kk2 = kin->bulkPhase(1)->nSpecies(); + vector bphase; + srxns->getChildren("phase", bphase); + int nbulk = bphase.size(); + string s, t; + vector phase_id(2,""); + for (int nb = 0; nb < nbulk; nb++) { + phase_id[nb] = (*bphase[nb])["id"]; + } + for (i = 0; i < nrxns; i++) { + XML_Node& rxn = *rxns[i]; + vector reac; + rxn.getChildren("reactant",reac); + int nr = reac.size(); + int k; + for (n = 0; n < nr; n++) { + XML_Node& r = *reac[n]; + rstoich.push_back(atoi(r["stoich"].c_str())); + order.push_back(atoi(r["order"].c_str())); + phase = r["phase"]; + if (phase == phase_id[0]) { + k = kin->bulkPhase(0)->speciesIndex(r["name"]); + } + else if (phase == phase_id[1]) { + k = kin->bulkPhase(1)->speciesIndex(r["name"]) + kk1; + } + else { + k = ph->speciesIndex(r["name"]) + kk1 + kk2; + } + rindex.push_back(k); + } + + vector prod; + rxn.getChildren("product",prod); + int np = prod.size(); + for (n = 0; n < np; n++) { + XML_Node& p = *prod[n]; + pstoich.push_back(atoi(p["stoich"].c_str())); + phase = p["phase"]; + if (phase == phase_id[0]) { + k = kin->bulkPhase(0)->speciesIndex(p["name"]); + } + else if (phase == phase_id[1]) { + k = kin->bulkPhase(1)->speciesIndex(p["name"]) + kk1; + } + else { + k = ph->speciesIndex(p["name"]) + kk1 + kk2; + } + pindex.push_back(k); + } + + XML_Node& rate = rxn.child("rate"); + map rp; + getFloats(rate, rp); + vector_fp kf(3); + kf[0] = rp["A"]; + kf[1] = rp["n"]; + kf[2] = rp["E"]; + + kin->addReaction(rindex, rstoich, order, pindex, pstoich, kf); + } + } + +} diff --git a/Cantera/src/importXML.h b/Cantera/src/importXML.h new file mode 100755 index 000000000..c13c0603b --- /dev/null +++ b/Cantera/src/importXML.h @@ -0,0 +1,25 @@ +/** + * @file importXML.h + * + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_IMPORTXML_H +#define CT_IMPORTXML_H + +#include + +#include "GasKinetics.h" + +namespace Cantera { + + bool isXMLFile(string infile); + + bool importXML(const string& infile, phase_t& gas, Kinetics& kin); + +} + +#endif + diff --git a/Cantera/src/lapack.h b/Cantera/src/lapack.h new file mode 100755 index 000000000..f4ad15a4c --- /dev/null +++ b/Cantera/src/lapack.h @@ -0,0 +1,62 @@ + +// Copyright 2001 California Institute of Technology. +// All rights reserved. + +#include "ct_defs.h" + +#ifndef LAPACK_H +#define LAPACK_H + +#if defined(NEEDS_F77_TRANSLATION) + +#if defined(F77EXTERNS_UPPERCASE_NOTRAILINGBAR) +#define dgelss_ DGELSS +#define dgetrs_ DGETRS +#define dgetrf_ DGETRF +#define dgetri_ DGETRI +#define dvode_ DVODE +#define ddassl_ DDASSL +#define simplx_ SIMPLX +#define splin2_ SPLIN2 +#define splie2_ SPLIE2 +#define dgelss_ DGELSS +#endif + +#endif + +extern "C" +{ + + // /* Subroutine */ int dgelss_(integer *m, integer *n, integer *nrhs, + // doublereal *a, integer *lda, doublereal *b, integer *ldb, doublereal * + // s, doublereal *rcond, integer *rank, doublereal *work, integer *lwork, + // integer *info); + + ///* Subroutine */ int dgetrs_(char *trans, integer *n, integer *nrhs, +// doublereal *a, integer *lda, integer *ipiv, doublereal *b, integer * +// ldb, integer *info, int len); + +///* Subroutine */ int dgetrf_(integer *m, integer *n, doublereal *a, integer * +// lda, integer *ipiv, integer *info); + +///* Subroutine */ int dgetri_(integer *n, doublereal *a, integer * +// lda, integer *ipiv, doublereal *work, integer *lwork, integer *info); + +// /* Subroutine */ int dgemv_(char *trans, integer *m, integer *n, doublereal * +// alpha, doublereal *a, integer *lda, doublereal *x, integer *incx, +// doublereal *beta, doublereal *y, integer *incy, int len); + +void dcopy_(const integer *n, const doublereal *dx, const integer *incx, doublereal *dy, const integer *incy); + //doublereal ddot_(integer *n, doublereal *dx, integer *incx, doublereal *dy, integer *incy); + +doublereal ddot_(integer *n, doublereal *dx, integer *incx, doublereal *dy, integer *incy); + +void daxpy_(integer* n, doublereal* a, doublereal* x, integer* incx, + doublereal* y, integer* incy); +void dscal_(integer *n, doublereal *da, doublereal *dx, integer *incx); +integer idamax_(integer* n, doublereal* a, integer* incx); + +} + + +#endif diff --git a/Cantera/src/misc.cpp b/Cantera/src/misc.cpp new file mode 100755 index 000000000..1d76e5ca4 --- /dev/null +++ b/Cantera/src/misc.cpp @@ -0,0 +1,293 @@ + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) + +//#include "ctwin.h" +#endif + +#include "global.h" +#include "ctexceptions.h" +#include "stringUtils.h" +#include "units.h" + +#ifndef WIN32 +#include "ctdir.h" +#endif + +#include +using namespace std; + +namespace Cantera { + + /** + * Class to hold global data. Class Application is the top-level + * class that stores data that should persist for the duration of + * the process. The class should not be instantiated directly; + * instead, it is instantiated as needed by the functions declared + * here. At most one instance is created, and it is not destroyed + * until the process terminates. + */ + class Application { + public: + Application() : linelen(0) {} + virtual ~Application(){} + vector inputDirs; + vector errorMessage; + vector warning; + vector errorRoutine; + string msglog; + bool stop_on_error; + size_t linelen; + map options; + }; + + + /// Returns a pointer to the one and only instance of Application + Application* app(); + + + void setDefaultDirectories(); + + static Application* __app = 0; + Unit* Unit::__u = 0; + + static void appinit() { + if (__app == 0) __app = new Application; + } + + Application* app() { + if (__app == 0) { + __app = new Application; + setDefaultDirectories(); + } + return __app; + } + + int nErrors() {return __app->errorMessage.size();} + + void popError() { + appinit(); + if (nErrors() > 0) { + __app->errorMessage.pop_back(); + __app->errorRoutine.pop_back(); + } + } + + string lastErrorMessage() { + appinit(); + if (nErrors() > 0) + return __app->errorMessage.back(); + else + return ""; + } + + void showErrors(ostream& f) { + appinit(); + int i = __app->errorMessage.size(); + if (i == 0) return; + f << endl << endl; + f << "**********************" << endl; + f << " Cantera Error! " << endl; + f << "**********************" << endl << endl; + int j; + for (j = 0; j < i; j++) { + f << endl; + f << "Procedure: " << __app->errorRoutine[j] << endl; + f << "Error: " << __app->errorMessage[j] << endl; + } + f << endl << endl; + __app->errorMessage.clear(); + __app->errorRoutine.clear(); + //if (__app->stop_on_error) exit(-1); + } + + void setError(string r, string msg) { + appinit(); + __app->errorMessage.push_back(msg); + __app->errorRoutine.push_back(r); + } + + + /** + * Set the default directories for input files. Four directories are + * added to the search path used by findInputFile. These are + * 'data', 'data/inputs', 'data/thermo', and + * 'data/transport'. These names are for convenience only - + * findInputFile searches all of them, independent of the type of + * file. The location of the 'data' directory depends on how + * environment variables are set. If CANTERA_DATA_DIR is set, then + * this will be used instead of 'data'. In addition, if + * WIN_CANTERA_ROOT or CANTERA_ROOT are set, then 'data' is + * assumed to be a top-level subdirectory. WIN_CANTERA_ROOT should + * only be set on PCs, and should be in 'DOS' format, for example + * 'C:\CANTERA'. CANTERA_ROOT, on the other hand, should be in + * unix-like format ('/home/usr/cantera'). This allows Cantera to + * be built on PCs using a unix-like environment (Cygwin) and + * compiler (g++), as well as using Win32 compilers. + */ + void setDefaultDirectories() { + appinit(); + vector& dirs = __app->inputDirs; + + // always look in the local directory first + dirs.push_back("."); + +#ifdef WIN32 + /* + * Under Windows, the Cantera setup utility puts data files in + * a directory 'Cantera\data' below the one the environment + * variable COMMONPROGRAMFILES points to. (This is usually + * C:\Program Files\Common Files.) If this environment + * variable is defined, then this directory is assumed to + * exist and is added to the search path. + */ + const char* comfiles = getenv("COMMONPROGRAMFILES"); + if (comfiles != 0) { + string cfiles = string(comfiles); + + // remove quotes if necessary + if (cfiles[0] == '\'') + cfiles = cfiles.substr(1,1000); + if (cfiles[cfiles.size()-1] == '\'') cfiles[cfiles.size()-1] = '\n'; + + string datadir = string(comfiles) + "/Cantera/data"; + string tmpldir = string(comfiles) + "/Cantera/templates"; + dirs.push_back(datadir); + dirs.push_back(tmpldir); + } +#endif + if (getenv("CANTERA_DATA") != 0) { + string datadir = string(getenv("CANTERA_DATA")); + dirs.push_back(datadir); + } + + // CANTERA_ROOT is defined in file ctdir.h. This file is written + // during the build process (unix), and points to the directory + // specified by the 'prefix' option to 'configure', or else to + // /usr/local.cantera. This will generally not be defined under + // Windows. +#ifdef CANTERA_ROOT + string datadir = string(CANTERA_ROOT) + "/data"; + dirs.push_back(datadir); +#endif + } + + + + + void addDirectory(string dir) { + appinit(); + if (__app->inputDirs.size() == 0) setDefaultDirectories(); + __app->inputDirs.push_back(stripnonprint(dir)); + } + + /** + * findInputFile(): + * + * This routine will search for a file in the default + * locations specified for the application. + * See the routine setDefaultDirectories() listed above. + * + * The default set of directories specified for the application + * will be searched if a '/' or an '\\' is not found in + * name. If either is found then a relative path name is + * presumed and the default directories are not searched. + * + * The presence of the file is determined by whether the file + * can be opened for reading by the current user. + * + * Return + * ------- + * The absolute path name of the first matching + * file is returned. If a relative path name + * is indicated, the relative path name is returned. + * + * If the file is not found, a message is written to + * stdout and a CanteraError exception is thrown. + */ + string findInputFile(string name) { + appinit(); + int islash = name.find('/'); + int ibslash = name.find('\\'); + string inname; + vector& dirs = __app->inputDirs; + if (dirs.size() == 0) setDefaultDirectories(); + + int nd; + if (islash < 0 && ibslash < 0) { + nd = dirs.size(); + int i; + inname = ""; + for (i = 0; i < nd; i++) { + inname = dirs[i] + "/" + name; + ifstream fin(inname.c_str()); + if (fin) { + fin.close(); + return inname; + } + } + string msg; + msg = "\nInput file " + name + + " not found in director"; + msg += (nd == 1 ? "y " : "ies "); + for (i = 0; i < nd; i++) { + msg += "\n'" + dirs[i] + "'"; + if (i < nd-1) msg += ", "; + } + msg += "\n\n"; + msg += "To fix this problem, either:\n"; + msg += " a) move the missing files into the local directory;\n"; + msg += " b) define environment variable CANTERA_DATA to\n"; + msg += " point to the directory containing the file."; + throw CanteraError("findInputFile", msg); + return ""; + } + else { + return name; + } + } + + void write(const string& msg) {cout << msg;} + void write(const char* msg) {cout << msg;} + void writelog(const string& msg) { + appinit(); + __app->msglog += msg; + __app->linelen += msg.size(); + if (msg[msg.size()-1] == '\n') __app->linelen = 0; + if (__app->linelen > 70) { + __app->msglog += "\n"; + __app->linelen = 0; + } + } + void writelog(const char* msg) {writelog(string(msg));} + void getlog(string& s) { + appinit(); + s = __app->msglog; + //__app->msglog = ""; + } + void clearlog() { + __app->msglog = ""; + } + doublereal toSI(string unit) { + doublereal f = Unit::units()->toSI(unit); + if (f) return f; + else return 1.0; + } + + + string canteraRoot() { + char* ctroot = 0; + ctroot = getenv("CANTERA_ROOT"); + if (ctroot != 0) { return string(ctroot); } + else { +#ifdef CANTERA_ROOT + return string(CANTERA_ROOT); +#else + return ""; +#endif + } + } +} + + diff --git a/Cantera/src/mix_defs.h b/Cantera/src/mix_defs.h new file mode 100755 index 000000000..335b49424 --- /dev/null +++ b/Cantera/src/mix_defs.h @@ -0,0 +1,23 @@ +#ifndef CT_MIX_DEFS_H +#define CT_MIX_DEFS_H + +namespace Cantera { + + const int cNone = 0; + + // species thermo types + const int cNASA = 1; + const int cShomate = 2; + + // equation of state types + const int cIdealGas = 1; + const int cIncompressible = 2; + const int cSurf = 3; + + // kinetic manager types + const int cGasKinetics = 2; + const int cGRI30 = 3; + const int cInterfaceKinetics = 4; +} + +#endif diff --git a/Cantera/src/mix_utils.h b/Cantera/src/mix_utils.h new file mode 100755 index 000000000..16c9c2ad1 --- /dev/null +++ b/Cantera/src/mix_utils.h @@ -0,0 +1,95 @@ +#ifndef CT_MIX_UTILS_H +#define CT_MIX_UTILS_H + +#include "ctexceptions.h" + +namespace Cantera { + + doublereal quadInterp(doublereal x0, doublereal* x, doublereal* y); + +// /** Set the temperature (K), pressure (Pa), and mole fractions. */ +// template +// void set_TPX(S& s, doublereal t, doublereal p, doublereal* x) { +// s.setMoleFractions(x); s.setTemperature(t); s.setPressure(p); +// } + +// template +// void set_HP(S& s, doublereal h, doublereal p, doublereal tol) { +// doublereal dt; +// s.setPressure(p); +// for (int n = 0; n < 20; n++) { +// dt = (h - s.enthalpy_mass())/s.cp_mass(); +// if (dt > 100.0) dt = 100.0; +// else if (dt < -100.0) dt = -100.0; +// s.setState_TP(s._temp() + dt, p); +// if (fabs(dt) < tol) { +// return; +// } +// } +// throw CanteraError("set_HP","no convergence. dt = " + fp2str(dt)); +// } + +// template +// void set_UV(S& s, doublereal u, doublereal v, +// doublereal tol) { +// doublereal dt; +// s.setDensity(1.0/v); +// for (int n = 0; n < 20; n++) { +// dt = (u - s.intEnergy_mass())/s.cv_mass(); +// if (dt > 100.0) dt = 100.0; +// else if (dt < -100.0) dt = -100.0; +// s.setTemperature(s._temp() + dt); +// if (fabs(dt) < tol) return; +// } +// throw CanteraError("set_UV","no convergence. dt = " + fp2str(dt)); +// } + +// template +// void set_SP(S& s, doublereal entropy, doublereal p, +// doublereal tol) { +// doublereal dt; +// s.setPressure(p); +// for (int n = 0; n < 20; n++) { +// dt = (entropy - s.entropy_mass())*s.temperature()/s.cp_mass(); +// if (dt > 100.0) dt = 100.0; +// else if (dt < -100.0) dt = -100.0; +// s.setState_TP(s._temp() + dt, p); +// if (fabs(dt) < tol) return; +// } +// throw CanteraError("set_SP","no convergence. dt = " + fp2str(dt)); +// } + +// template +// void set_SV(S& s, doublereal entropy, doublereal v, +// doublereal tol) { +// doublereal dt; +// s.setDensity(1.0/v); +// for (int n = 0; n < 20; n++) { +// dt = (entropy - s.entropy_mass())*s.temperature()/s.cv_mass(); +// if (dt > 100.0) dt = 100.0; +// else if (dt < -100.0) dt = -100.0; +// s.setTemperature(s._temp() + dt); +// if (fabs(dt) < tol) return; +// } +// throw CanteraError("set_SV","no convergence. dt = " + fp2str(dt)); +// } + + template + void mapSpeciesData(const S1& s1, const S2& s2, const doublereal* data1, + doublereal* data2) { + int n1 = s1.nSpecies(); + int n2 = s2.nSpecies(); + int n, m2; + + // zero out the destination array + for (n = 0; n < n2; n++) data2[n] = 0.0; + + // copy + for (n = 0; n < n1; n++) { + m2 = s2.speciesIndex(s1.speciesName(n)); + if (m2 >= 0) data2[m2] = data1[n]; + } + } +} + +#endif diff --git a/Cantera/src/newton_utils.cpp b/Cantera/src/newton_utils.cpp new file mode 100755 index 000000000..8a1f4e9df --- /dev/null +++ b/Cantera/src/newton_utils.cpp @@ -0,0 +1,102 @@ +/** + * @file newton_utils.cpp + */ + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "ct_defs.h" +#include "Resid1D.h" + +namespace Cantera { + + class Indx { + public: + Indx(int nv, int np) : m_nv(nv), m_np(np) {} + int m_nv, m_np; + int operator()(int m, int j) { return j*m_nv + m; } + }; + + + doublereal bound_step(const doublereal* x, const doublereal* step, + Resid1D& r, int loglevel=0) { + + char buf[100]; + int np = r.nPoints(); + int nv = r.nComponents(); + Indx index(nv, np); + doublereal above, below, val, newval; + int m, j; + doublereal fbound = 1.0; + bool wroteTitle = false; + for (m = 0; m < nv; m++) { + above = r.upperBound(m); + below = r.lowerBound(m); + + for (j = 0; j < np; j++) { + val = x[index(m,j)]; + if (loglevel > 0) { + if (val > above + Tiny || val < below - Tiny) + cout << "ERROR: solution out of bounds. " + << r.componentName(m) << "(" << j << ") = " << val + << " (" << below << ", " << above << ")" << endl; + } + + newval = val + step[index(m,j)]; + + if (newval > above) { + fbound = fmaxx( 0.0, fminn( fbound, + (above - val)/(newval - val))); + } + else if (newval < below) { + fbound = fminn(fbound, (val - below)/(val - newval)); + } + + if (loglevel > 1 && (newval > above || newval < below)) { + if (!wroteTitle) { + writelog("\nNewton step takes solution out of bounds.\n\n"); + sprintf(buf," %12s %4s %10s %10s %10s %10s\n", + "component","pt","value","step","min","max"); + wroteTitle = true; + writelog(buf); + } + sprintf(buf, " %12s %4i %10.3e %10.3e %10.3e %10.3e\n", + r.componentName(m).c_str(), j, val, + step[index(m,j)], below, above); + writelog(buf); + } + } + } + return fbound; + } + + + doublereal norm_square(const doublereal* x, + const doublereal* step, Resid1D& r) { + doublereal f, ewt, esum, sum = 0.0; + int n, j; + + int nv = r.nComponents(); + int np = r.nPoints(); + //int jmx = 0, nmx = 0; + //doublereal fmx = -1.0; + + for (n = 0; n < nv; n++) { + esum = 0.0; + for (j = 0; j < np; j++) esum += fabs(x[nv*j + n]); + ewt = r.rtol(n)*esum/np + r.atol(n); + for (j = 0; j < np; j++) { + f = step[nv*j + n]/ewt; + sum += f*f; +// if (fabs(f) > fmx) { +// fmx = fabs(f); +// jmx = j; +// nmx = n; +// } + } + } + return sum; + } +} diff --git a/Cantera/src/oneD/.cvsignore b/Cantera/src/oneD/.cvsignore new file mode 100644 index 000000000..e825c6550 --- /dev/null +++ b/Cantera/src/oneD/.cvsignore @@ -0,0 +1,2 @@ +.depends +Makefile diff --git a/Cantera/src/oneD/Inlet1D.h b/Cantera/src/oneD/Inlet1D.h new file mode 100644 index 000000000..5e962435b --- /dev/null +++ b/Cantera/src/oneD/Inlet1D.h @@ -0,0 +1,471 @@ + +#ifndef CT_BDRY1D_H +#define CT_BDRY1D_H + +#include "Resid1D.h" +//#include "surfacePhase.h" +//#include "surfKinetics.h" +#include "StFlow.h" +#include "OneDim.h" +#include "ctml.h" + +namespace Cantera { + + const int LeftInlet = 1; + const int RightInlet = -1; + + + // A class for surface domains in one-dimensional simulations, The + // surface is zero-dimensional, and defined by a set of surface + // species coverages. + + class Bdry1D : public Resid1D { + public: + Bdry1D() : Resid1D(1, 1, 0.0) {} + virtual ~Bdry1D() {} + virtual void init(){err("init");} + virtual void setTemperature(doublereal t){err("setTemperature");} + virtual doublereal temperature() {err("temperature"); return 0.0;} + virtual void setMoleFractions(string xin){err("setMoleFractions");} + virtual void setMoleFractions(doublereal* xin){err("setMoleFractions");} + virtual doublereal massFraction(int k) {err("massFraction"); return 0.0;} + virtual void setMdot(doublereal mdot){err("setMdot");} + virtual doublereal mdot() {err("mdot"); return 0.0;} + protected: + private: + void err(string method) { + throw CanteraError("Bdry1D::"+method, "attempt to call base class method "+method); + } + }; + + + class Inlet1D : public Bdry1D { + + public: + + Inlet1D(int ilr = 1) { + m_type = cInletType; + m_flow = 0; + m_ilr = ilr; + } + virtual ~Inlet1D(){} + + /// Set the inlet temperature + virtual void setTemperature(doublereal t) { + m_temp = t; + needJacUpdate(); + } + + /// Temperature [K]. + doublereal temperature() {return m_temp;} + + virtual void setMoleFractions(string xin) { + m_xstr = xin; + if (m_flow) { + m_flow->phase().setMoleFractionsByName(xin); + m_flow->phase().getMassFractions(m_yin.begin()); + needJacUpdate(); + } + } + + virtual void setMoleFractions(doublereal* xin) { + if (m_flow) { + m_flow->phase().setMoleFractions(xin); + m_flow->phase().getMassFractions(m_yin.begin()); + needJacUpdate(); + } + } + + virtual doublereal massFraction(int k) {return m_yin[k];} + + virtual void setMdot(doublereal mdot) { m_mdot = mdot; } + + virtual string componentName(int n) const { + switch (n) { + case 0: return "mdot"; break; + case 1: return "temperature"; break; + default: return "unknown"; + } + } + + virtual void init() { + if (m_index < 0) { + throw CanteraError("Inlet1D", + "install in container before calling init."); + } + resize(2,1); + + // set bounds + const doublereal lower[2] = {-1.0e5, 200.0}; + const doublereal upper[2] = {1.0e5, 1.e5}; + setBounds(2, lower, 2, upper); + + // set tolerances + vector_fp rtol(2, 1e-4); + vector_fp atol(2, 1.e-5); + setTolerances(2, rtol.begin(), 2, atol.begin()); + + if (m_index > 0) { + Resid1D& r = container().domain(m_index-1); + if (r.domainType() == cFlowType) { + m_ilr = RightInlet; + m_flow = (StFlow*)&r; + } + else + throw CanteraError("Inlet1D::init", + "Inlet domains can only be connected to a flow domain."); + } + else { + if (container().nDomains() > 1) { + Resid1D& r = container().domain(1); + if (r.domainType() == cFlowType) { + m_ilr = LeftInlet; + m_flow = (StFlow*)&r; + } + else + throw CanteraError("Inlet1D::init", + "An inlet domain can only be connected to a flow domain."); + } + else + throw CanteraError("Inlet1D::init", + "An inlet domain must be connected to a flow domain."); + } + m_nsp = m_flow->nComponents() - 4; + m_yin.resize(m_nsp, 0.0); + if (m_xstr != "") + setMoleFractions(m_xstr); + else + m_yin[0] = 1.0; + } + + + virtual void eval(int jg, doublereal* xg, doublereal* rg, + integer* diagg, doublereal rdt) { + int k; + if (jg >= 0 && (jg < firstPoint() - 2 || jg > lastPoint() + 2)) return; + + // start of local part of global arrays + doublereal* x = xg + loc(); + doublereal* r = rg + loc(); + integer* diag = diagg + loc(); + doublereal *xb, *rb; + //integer *db = diag + loc(); + + r[0] = m_mdot - x[0]; + r[1] = m_temp - x[1]; + diag[0] = 0; + diag[1] = 0; + + if (m_ilr == LeftInlet) { + xb = x + 2; + rb = r + 2; + if (m_flow->doEnergy(0)) { + rb[2] -= x[1]; // T + //db[2] = 1; + } + rb[3] += x[0]; // lambda + for (k = 0; k < m_nsp; k++) { + rb[4+k] += x[0]*m_yin[k]; + //db[4+k] = 1; + } + //cout << x[1] << " " << xb[2] << " " << rb[2] << endl; + } + else { + int boffset = m_flow->nComponents(); + xb = x - boffset; + rb = r - boffset; + rb[2] -= x[1]; // T + xb[0] += x[0]; // u + for (k = 0; k < m_nsp; k++) + rb[4+k] += x[0]*m_yin[k]; + } + } + + virtual void save(XML_Node& o, doublereal* soln) { + doublereal* s = soln + loc(); + XML_Node& inlt = o.addChild("inlet"); + for (int k = 0; k < 2; k++) { + ctml::addFloat(inlt, componentName(k), s[k], "", "",0.0, 1.0); + } + } + + protected: + + int m_ilr; + doublereal m_mdot, m_temp; + StFlow *m_flow; + int m_nsp; + vector_fp m_yin; + string m_xstr; + }; + + + class Symm1D : public Bdry1D { + + public: + + Symm1D(int ilr = 1) { + m_type = cSymmType; + m_flow = 0; + m_ilr = ilr; + } + virtual ~Symm1D(){} + + virtual string componentName(int n) const { + switch (n) { + case 0: return "dummy"; break; + default: return ""; + } + } + + virtual void init() { + if (m_index < 0) { + throw CanteraError("Symm1D", + "install in container before calling init."); + } + resize(1,1); + + // set bounds + const doublereal lower = -1.0e5; + const doublereal upper = 1.0e5; + setBounds(1, &lower, 1, &upper); + + // set tolerances + doublereal rtol = 1e-4; + doublereal atol = 1.e-5; + setTolerances(1, &rtol, 1, &atol); + + if (m_index > 0) { + Resid1D& r = container().domain(m_index-1); + if (r.domainType() == cFlowType) { + m_ilr = -1; + m_flow = (StFlow*)&r; + } + else + throw CanteraError("Symm1D::init", + "Symmetry planes can only be connected to flow domains."); + } + else { + if (container().nDomains() > 1) { + Resid1D& r = container().domain(1); + if (r.domainType() == cFlowType) { + m_ilr = 1; + m_flow = (StFlow*)&r; + } + else + throw CanteraError("Symm1D::init", + "Symmetry planes can only be connected to flow domains."); + } + else + throw CanteraError("Symm1D::init", + "A symmetry plane must be connected to a flow domain."); + } + m_nsp = m_flow->nComponents() - 4; + } + + + virtual void eval(int jg, doublereal* xg, doublereal* rg, + integer* diagg, doublereal rdt) { + int k; + if (jg >= 0 && (jg < firstPoint() - 2 || jg > lastPoint() + 2)) return; + + // start of local part of global arrays + doublereal* x = xg + loc(); + doublereal* r = rg + loc(); + integer* diag = diagg + loc(); + doublereal *xb, *rb; + // integer *db = diag + loc(); + + r[0] = x[0]; + diag[0] = 0; + int nc = m_flow->nComponents(); + + if (m_ilr == 1) { + xb = x + 1; + rb = r + 1; + rb[0] = xb[0]; + rb[1] = xb[1] - xb[1 + nc]; + if (m_flow->doEnergy(0)) { + rb[2] = xb[2] - xb[2 + nc]; + } + rb[3] = xb[3] - xb[3 + nc]; + for (k = 0; k < m_nsp; k++) { + rb[4+k] = xb[4+k] - xb[4+k+nc]; + } + } + else { + xb = x - nc; + rb = r - nc; + rb[0] = xb[0]; + rb[1] = xb[1] - xb[1 - nc]; + // if (m_flow->doEnergy(0)) { + rb[2] = xb[2] - xb[2 - nc]; + // } + rb[3] = xb[3] - xb[3 - nc]; + for (k = 0; k < m_nsp; k++) { + rb[4+k] = xb[4+k] - xb[4+k-nc]; + } + } + } + + virtual void save(XML_Node& o, doublereal* soln) { + // doublereal* s = soln + loc(); + // XML_Node& symm = o.addChild("symmetry_plane"); + (void) o.addChild("symmetry_plane"); + } + + protected: + + int m_ilr; + StFlow *m_flow; + int m_nsp; + }; + + + + ///////////////////////////////////////////////////////////// + // + // surf1D + // + //////////////////////////////////////////////////////////// + + class Surf1D : public Bdry1D { + + public: + + Surf1D(int ilr = 1) { + m_type = cSurfType; + m_flow = 0; + m_ilr = ilr; + } + virtual ~Surf1D(){} + + /// Set the surface temperature + virtual void setTemperature(doublereal t) { + m_temp = t; + needJacUpdate(); + } + + /// Temperature [K]. + doublereal temperature() {return m_temp;} + + virtual string componentName(int n) const { + switch (n) { + case 0: return "dummy"; break; + case 1: return "temperature"; break; + default: return ""; + } + } + + virtual void init() { + if (m_index < 0) { + throw CanteraError("Surf1D", + "install in container before calling init."); + } + resize(2,1); + + // set bounds + const doublereal lower[2] = {-1.0e5, 200.0}; + const doublereal upper[2] = {1.0e5, 1.e5}; + setBounds(2, lower, 2, upper); + + // set tolerances + vector_fp rtol(2, 1e-4); + vector_fp atol(2, 1.e-5); + setTolerances(2, rtol.begin(), 2, atol.begin()); + + if (m_index > 0) { + Resid1D& r = container().domain(m_index-1); + if (r.domainType() == cFlowType) { + m_ilr = -1; + m_flow = (StFlow*)&r; + } + else + throw CanteraError("Surf1D::init", + "Surface domains can only be connected to a flow domain."); + } + else { + if (container().nDomains() > 1) { + Resid1D& r = container().domain(1); + if (r.domainType() == cFlowType) { + m_ilr = 1; + m_flow = (StFlow*)&r; + } + else + throw CanteraError("Surf1D::init", + "A surface domain can only be connected to a flow domain."); + } + else + throw CanteraError("Surf1D::init", + "A surface domain must be connected to a flow domain."); + } + m_nsp = m_flow->nComponents() - 4; + } + + + virtual void eval(int jg, doublereal* xg, doublereal* rg, + integer* diagg, doublereal rdt) { + int k; + if (jg >= 0 && (jg < firstPoint() - 2 || jg > lastPoint() + 2)) return; + + // start of local part of global arrays + doublereal* x = xg + loc(); + doublereal* r = rg + loc(); + integer* diag = diagg + loc(); + doublereal *xb, *rb; + //integer *db = diag + loc(); + + r[0] = x[0]; + r[1] = m_temp - x[1]; + diag[0] = 0; + diag[1] = 0; + int nc = m_flow->nComponents(); + + if (m_ilr == 1) { + xb = x + 2; + rb = r + 2; + rb[0] = xb[0]; + rb[1] = xb[1]; // T + // if (m_flow->doEnergy(0)) { + rb[2] = xb[2] - x[1]; // T + //} + rb[3] = xb[3] - xb[3 + nc]; // lambda + for (k = 0; k < m_nsp; k++) { + rb[4+k] += xb[4+k] - xb[4+k+nc]; + } + } + else { + xb = x - nc; + rb = r - nc; + rb[0] = xb[0]; + rb[1] = xb[1]; // T + // if (m_flow->doEnergy(0)) { + rb[2] = xb[2] - x[1]; // T + //} + rb[3] = xb[3] - xb[3 - nc]; // lambda + for (k = 0; k < m_nsp; k++) { + rb[4+k] += xb[4+k] - xb[4+k-nc]; + } + } + } + + virtual void save(XML_Node& o, doublereal* soln) { + doublereal* s = soln + loc(); + XML_Node& srf = o.addChild("surface"); + for (int k = 1; k < 2; k++) { + ctml::addFloat(srf, componentName(k), s[k], "", "",0.0, 1.0); + } + } + + protected: + + int m_ilr; + doublereal m_temp; + StFlow *m_flow; + int m_nsp; + }; + + +} + +#endif diff --git a/Cantera/src/oneD/Jac1D.h b/Cantera/src/oneD/Jac1D.h new file mode 100644 index 000000000..03dbb88a6 --- /dev/null +++ b/Cantera/src/oneD/Jac1D.h @@ -0,0 +1,88 @@ +/** + * + * @file Jac1D.h + * + * >>>>> Under construction! <<<<< + * + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2002 California Institute of Technology + * + */ + +#ifndef CT_JAC1D_H +#define CT_JAC1D_H + +#include "Resid1D.h" +#include "BandMatrix.h" +//#include "ArrayViewer.h" +#include "Array.h" +#include "time.h" + +namespace Cantera { + + /** + * Class Jac1D evaluates the Jacobian of a system of equations + * defined by a residual function of class Resid1D. It is + * assumed that the Jacobian is banded. + */ + class Jac1D : public BandMatrix { + + public: + + /** + * Constructor. The residual function defining the system of + * equations must be supplied. + */ + Jac1D(Resid1D& r); + + /// Destructor. Does nothing. + virtual ~Jac1D(){} + + /** + * Evaluate the Jacobian. + */ + void eval(doublereal* x0, doublereal* resid0); + + /** + * Returns the matrix element describing the influence of the + * nth component at point j on the mth equation at point + * i. Due to the assumption of a banded Jacobian, this will be + * zero unless |i - j| <= 1. + */ + doublereal& v(int m, int i, int n, int j) { + return value(i*m_nv + m, j*m_nv + n); + } + + doublereal elapsedTime() const { + return m_elapsed; + } + + int nEvals() const { return m_nevals; } + + int age() const { return m_age; } + + void incrementAge() { m_age++; } + void setAge(int age) { m_age = age; } + + protected: + + Resid1D* m_resid; + Array2D m_r1; + // ArrayViewer m_x0, m_r0; + int m_nv, m_points; + doublereal m_atol; + doublereal m_elapsed; + int m_nevals; + int m_age; + + private: + size_t index(int m, int j) { return m_nv*j + m; } + }; +} + +#endif + + diff --git a/Cantera/src/oneD/Makefile.in b/Cantera/src/oneD/Makefile.in new file mode 100644 index 000000000..a5bb9de18 --- /dev/null +++ b/Cantera/src/oneD/Makefile.in @@ -0,0 +1,53 @@ +#/bin/sh +############################################################### +# $Author$ +# $Date$ +# $Revision$ +# +# Copyright 2002 California Institute of Technology +# +############################################################### + +SUFFIXES= +SUFFIXES= .cpp .d .o + +OBJDIR = . + +CXX_FLAGS = @CXXFLAGS@ $(CXX_OPT) + +# stirred reactors +OBJS = MultiJac.o MultiNewton.o newton_utils.o OneDim.o StFlow.o + +CXX_INCLUDES = -I.. +ONED_LIB = ./liboneD.a + +DEPENDS = $(OBJS:.o=.d) + +%.d: + g++ -MM $(CXX_INCLUDES) $*.cpp > $*.d + +.cpp.o: + @CXX@ -c $< @DEFS@ $(CXX_FLAGS) $(CXX_INCLUDES) + +.f.o: + @F77@ -c $< $(F77_FLAGS) + +all: $(ONED_LIB) + +$(ONED_LIB): $(OBJS) + @ARCHIVE@ $(ONED_LIB) $(OBJS) > /dev/null + +clean: + $(RM) *.o *~ $(ONED_LIB) + +depends: $(DEPENDS) + cat *.d > .depends + $(RM) $(DEPENDS) + +TAGS: + etags *.h *.cpp + +ifeq ($(wildcard .depends), .depends) +include .depends +endif + diff --git a/Cantera/src/oneD/MultiJac.cpp b/Cantera/src/oneD/MultiJac.cpp new file mode 100644 index 000000000..2687b3838 --- /dev/null +++ b/Cantera/src/oneD/MultiJac.cpp @@ -0,0 +1,114 @@ +/** + * + * @file MultiJac.cpp + * + * Implementation file for class MultiJac + */ + +/* + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2002 California Institute of Technology + * + */ + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include +using namespace std; + +#include "MultiJac.h" + +namespace Cantera { + + MultiJac::MultiJac(OneDim& r) + : BandMatrix(r.size(),r.bandwidth(),r.bandwidth()) + { + m_size = r.size(); + m_points = r.points(); + m_resid = &r; + m_r1.resize(m_size); + m_ssdiag.resize(m_size); + m_mask.resize(m_size); + m_elapsed = 0.0; + m_nevals = 0; + m_age = 100000; + doublereal ff = 1.0; + while (1.0 + ff != 1.0) { + ff *= 0.5; + } + m_atol = sqrt(ff); + } + + void MultiJac::updateTransient(doublereal rdt, integer* mask) { + int n; + for (n = 0; n < m_size; n++) { + value(n,n) = m_ssdiag[n] - mask[n]*rdt; + } + } + + void MultiJac::incrementDiagonal(int j, doublereal d) { + m_ssdiag[j] += d; + value(j,j) = m_ssdiag[j]; + } + + /** + * Evaluate the Jacobian at x0. The array of residual values at x0 + * is supplied as an input. + */ + void MultiJac::eval(doublereal* x0, doublereal* resid0, doublereal rdt) + { + m_nevals++; + clock_t t0 = clock(); + bfill(0.0); + + int n, m, ipt=0, i, j, nv, mv, iloc; + doublereal rdx, dx, xsave; + + for (j = 0; j < m_points; j++) { + nv = m_resid->nVars(j); + for (n = 0; n < nv; n++) { + + // perturb x(n) + xsave = x0[ipt]; + dx = m_atol; + x0[ipt] = xsave + dx; + dx = x0[ipt] - xsave; + rdx = 1.0/dx; + + // calculate perturbed residual + m_resid->eval(j, x0, m_r1.begin(), rdt, 0); + + // compute nth column of Jacobian + for (i = j - 1; i <= j+1; i++) { + if (i >= 0 && i < m_points) { + mv = m_resid->nVars(i); + iloc = m_resid->loc(i); + for (m = 0; m < mv; m++) { + value(m+iloc,ipt) = (m_r1[m+iloc] + - resid0[m+iloc])*rdx; + } + } + } + x0[ipt] = xsave; + ipt++; + } + + } + + for (n = 0; n < m_size; n++) { + m_ssdiag[n] = value(n,n); + } + + m_elapsed += double(clock() - t0)/CLOCKS_PER_SEC; + m_age = 0; + } + +} // namespace + +// $Log: MultiJac.cpp,v diff --git a/Cantera/src/oneD/MultiJac.h b/Cantera/src/oneD/MultiJac.h new file mode 100644 index 000000000..caf228722 --- /dev/null +++ b/Cantera/src/oneD/MultiJac.h @@ -0,0 +1,97 @@ +/** + * + * @file MultiJac.h + */ + +/* + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2002 California Institute of Technology + * + */ + +#ifndef CT_MULTIJAC_H +#define CT_MULTIJAC_H + +#include "../BandMatrix.h" +#include "OneDim.h" +#include "time.h" + +namespace Cantera { + + /** + * Class MultiJac evaluates the Jacobian of a system of equations + * defined by a residual function supplied by an instance of class + * 'OneDim.' The residual function may consist of several linked + * 1D domains, with different variables in each domain. + */ + class MultiJac : public BandMatrix { + + public: + + /** + * Constructor. + */ + MultiJac(OneDim& r); + + /// Destructor. Does nothing. + virtual ~MultiJac(){} + + /** + * Evaluate the Jacobian at x0. The unperturbed residual + * function is resid0, which must be supplied on input. The + * third parameter 'rdt' is the reciprocal of the time + * step. If zero, the steady-state Jacobian is evaluated. + */ + void eval(doublereal* x0, doublereal* resid0, double rdt); + + /** + * Elapsed CPU time spent computing the Jacobian. + */ + doublereal elapsedTime() const { + return m_elapsed; + } + + /// Number of Jacobian evaluations. + int nEvals() const { return m_nevals; } + + /** + * Number of times 'incrementAge' has been called since the + * last evaluation + */ + int age() const { return m_age; } + + /** + * Increment the Jacobian age. + */ + void incrementAge() { m_age++; } + + void updateTransient(doublereal rdt, integer* mask); + + /// Set the age. + void setAge(int age) { m_age = age; } + + vector_int& transientMask() { return m_mask; } + + void incrementDiagonal(int j, doublereal d); + + protected: + + OneDim* m_resid; + vector_fp m_r1; + doublereal m_atol; + doublereal m_elapsed; + vector_fp m_ssdiag; + vector_int m_mask; + int m_nevals; + int m_age; + int m_size; + int m_points; + }; +} + +#endif + + diff --git a/Cantera/src/oneD/MultiNewton.cpp b/Cantera/src/oneD/MultiNewton.cpp new file mode 100644 index 000000000..8cbf7106b --- /dev/null +++ b/Cantera/src/oneD/MultiNewton.cpp @@ -0,0 +1,371 @@ +/** + * + * @file MultiNewton.cpp + * + * Damped Newton solver for 1D multi-domain problems + */ + +/* + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2001 California Institute of Technology + * + */ + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include +using namespace std; + +#include "MultiNewton.h" +#include +#include + +#include "../ctexceptions.h" +#include "../vec_functions.h" +#include "../stringUtils.h" +#include + +namespace Cantera { + + //---------------------------------------------------------- + // function declarations + //---------------------------------------------------------- + + // declarations for functions in newton_utils.h + doublereal bound_step(const doublereal* x, + const doublereal* step, Resid1D& r, int loglevel=0); + doublereal norm_square(const doublereal* x, + const doublereal* step, Resid1D& r); + + + + //----------------------------------------------------------- + // constants + //----------------------------------------------------------- + + const string dashedline = + "-----------------------------------------------------------------"; + + const doublereal DampFactor = sqrt(2.0); + const int NDAMP = 7; + + + + //----------------------------------------------------------- + // MultiNewton methods + //----------------------------------------------------------- + + + MultiNewton::MultiNewton(int sz) + : m_maxAge(5) { + m_n = sz; + m_elapsed = 0.0; + } + + MultiNewton::~MultiNewton() { + int n = m_workarrays.size(); + int i; + for (i = 0; i < n; i++) { + delete m_workarrays[i]; + } + } + + /** + * Prepare for a new solution vector length. + */ + void MultiNewton::resize(int sz) { + m_n = sz; + int n = m_workarrays.size(); + int i; + for (i = 0; i < n; i++) { + delete m_workarrays[i]; + } + m_workarrays.clear(); + } + + + /** + * Compute the weighted 2-norm of 'step'. + */ + doublereal MultiNewton::norm2(const doublereal* x, + const doublereal* step, OneDim& r) const { + doublereal f, sum = 0.0;//, fmx = 0.0; + int n; + int nd = r.nDomains(); + for (n = 0; n < nd; n++) { + f = norm_square(x + r.start(n), step + r.start(n), + r.domain(n)); + sum += f; + // if (f > fmx) fmx = f; + } + sum /= r.size(); + return sqrt(sum); + } + + + /** + * Compute the undamped Newton step. The residual function is + * evaluated at x, but the Jacobian is not recomputed. + */ + void MultiNewton::step(doublereal* x, doublereal* step, + OneDim& r, MultiJac& jac, int loglevel) { + int n; + int sz = r.size(); + r.eval(-1, x, step); + for (n = 0; n < sz; n++) { + step[n] = -step[n]; + } +#ifdef DEBUG_STEP + Resid1D* d; + if (!ok) { + for (n = 0; n < sz; n++) { + d = r.pointDomain(n); + int nvd = d->nComponents(); + int pt = (n - d->loc())/nvd; + cout << pt << " " << + r.pointDomain(n)->componentName(n - d->loc() - nvd*pt) + << " " << x[n] << " " << step[n] << endl; + } + if (!ok) throw "not ok"; + } +#endif + jac.solve(sz, step, step); + } + + + /** + * Return the factor by which the undamped Newton step 'step0' + * must be multiplied in order to keep all solution components in + * all domains between their specified lower and upper bounds. + */ + doublereal MultiNewton::boundStep(const doublereal* x0, + const doublereal* step0, const OneDim& r, int loglevel) { + + int i; + doublereal fbound = 1.0; + int nd = r.nDomains(); + for (i = 0; i < nd; i++) { + fbound = fminn(fbound, + bound_step(x0 + r.start(i), step0 + r.start(i), + r.domain(i), loglevel)); + } + return fbound; + } + + + /** + * On entry, step0 must contain an undamped Newton step for the + * solution x0. This method attempts to find a damping coefficient + * such that the next undamped step would have a norm smaller than + * that of step0. If successful, the new solution after taking the + * damped step is returned in x1, and the undamped step at x1 is + * returned in step1. + */ + int MultiNewton::dampStep(const doublereal* x0, const doublereal* step0, + doublereal* x1, doublereal* step1, doublereal& s1, + OneDim& r, MultiJac& jac, int loglevel, bool writetitle) { + + // write header + if (loglevel > 0 && writetitle) { + writelog("\n\nDamped Newton iteration:\n"); + writelog(dashedline); + + sprintf(m_buf,"\n%s %8s %8s %8s %8s %8s %5s\n", + "m","F_damp","F_bound","log10(ss)", + "log10(s0)","log10(s1)","N_jac"); + writelog(m_buf); + writelog(dashedline+"\n"); + } + + // compute the weighted norm of the undamped step size step0 + doublereal s0 = norm2(x0, step0, r); + + // compute the multiplier to keep all components in bounds + doublereal fbound = boundStep(x0, step0, r, loglevel-1); + + // if fbound is very small, then x0 is already close to the + // boundary and step0 points out of the allowed domain. In + // this case, the Newton algorithm fails, so return an error + // condition. + if (fbound < 1.e-10) { + if (loglevel > 0) writelog("\nAt limits.\n"); + return -3; + } + + + //-------------------------------------------- + // Attempt damped step + //-------------------------------------------- + + // damping coefficient starts at 1.0 + doublereal damp = 1.0; + + int j, m; + doublereal ff; + + for (m = 0; m < NDAMP; m++) { + + ff = fbound*damp; + + // step the solution by the damped step size + for (j = 0; j < m_n; j++) x1[j] = ff*step0[j] + x0[j]; + + // compute the next undamped step that would result if x1 + // is accepted + step(x1, step1, r, jac, loglevel-1); + + // compute the weighted norm of step1 + s1 = norm2(x1, step1, r); + + // write log information + if (loglevel > 0) { + doublereal ss = r.ssnorm(x1,step1); + sprintf(m_buf,"\n%d %8.4f %8.4f %8.4f %8.4f %8.4f %5d ", + m,damp,fbound,log10(ss+SmallNumber), + log10(s0+SmallNumber), + log10(s1+SmallNumber), + jac.nEvals()); + writelog(m_buf); + } + + // if the norm of s1 is less than the norm of s0, then + // accept this damping coefficient. Also accept it if this + // step would result in a converged solution. Otherwise, + // decrease the damping coefficient and try again. + + if (s1 < 1.0 || s1 < s0) break; + damp /= DampFactor; + } + + // If a damping coefficient was found, return 1 if the + // solution after stepping by the damped step would represent + // a converged solution, and return 0 otherwise. If no damping + // coefficient could be found, return -2. + if (m < NDAMP) { + if (s1 > 1.0) return 0; + else return 1; + } + else { + return -2; + } + } + + + /** + * Find the solution to F(X) = 0 by damped Newton iteration. On + * entry, x0 contains an initial estimate of the solution. On + * successful return, x1 contains the converged solution. + */ + int MultiNewton::solve(doublereal* x0, doublereal* x1, + OneDim& r, MultiJac& jac, int loglevel) { + clock_t t0 = clock(); + + int m = 0; + bool forceNewJac = false; + doublereal s1=1.e30; + + doublereal* x = getWorkArray(); + doublereal* stp = getWorkArray(); + doublereal* stp1 = getWorkArray(); + + copy(x0, x0 + m_n, x); + + bool frst = true; + doublereal rdt = r.rdt(); + int j0 = jac.nEvals(); + + while (1 > 0) { + + // Check whether the Jacobian should be re-evaluated. + if (jac.age() > m_maxAge) { + forceNewJac = true; + } + + if (forceNewJac) { + r.eval(-1, x, stp, 0.0, 0); + jac.eval(x, stp, 0.0); + jac.updateTransient(rdt, r.transientMask().begin()); + forceNewJac = false; + } + + // compute the undamped Newton step + step(x, stp, r, jac, loglevel-1); + + // increment the Jacobian age + jac.incrementAge(); + + // damp the Newton step + m = dampStep(x, stp, x1, stp1, s1, r, jac, loglevel-1, frst); + frst = false; + if (loglevel == 1 && m >= 0) { + doublereal ss = r.ssnorm(x, stp); + sprintf(m_buf,"\n %10.4f %10.4f %d ", + log10(ss),log10(s1),jac.nEvals()); + writelog(m_buf); + } + + // Successful step, but not converged yet. Take the damped + // step, and try again. + if (m == 0) { + copy(x1, x1 + m_n, x); + } + + // convergence + else if (m == 1) goto done; + + // If dampStep fails, first try a new Jacobian if an old + // one was being used. If it was a new Jacobian, then + // return -1 to signify failure. + else if (m < 0) { + if (jac.age() > 1) forceNewJac = true; + else goto done; + } + } + + done: + if (m < 0) { + copy(x, x + m_n, x1); + } + if (m > 0 && jac.nEvals() == j0) m = 100; + releaseWorkArray(x); + releaseWorkArray(stp); + releaseWorkArray(stp1); + m_elapsed += (clock() - t0)/(1.0*CLOCKS_PER_SEC); + return m; + } + + + /** + * Get a pointer to an array of length m_n for temporary work + * space. + */ + doublereal* MultiNewton::getWorkArray() { + doublereal* w = 0; + + if (!m_workarrays.empty()) { + w = m_workarrays.back(); + m_workarrays.pop_back(); + } + else { + w = new doublereal[m_n]; + } + return w; + } + + /** + * Release a work array by pushing its pointer onto the stack of + * available arrays. + */ + void MultiNewton::releaseWorkArray(doublereal* work) { + m_workarrays.push_back(work); + } +} + + +// $Log: Newton.cpp,v diff --git a/Cantera/src/oneD/MultiNewton.h b/Cantera/src/oneD/MultiNewton.h new file mode 100644 index 000000000..203458097 --- /dev/null +++ b/Cantera/src/oneD/MultiNewton.h @@ -0,0 +1,77 @@ +/** + * + * @file MultiNewton.h + */ + +/* + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2002 California Institute of Technology + * + */ + +#ifndef CT_MULTINEWTON_H +#define CT_MULTINEWTON_H + +#include "MultiJac.h" + +namespace Cantera { + + /** + * Newton iterator for multi-domain, one-dimensional problems. + * Used by class OneDim. + */ + class MultiNewton { + + public: + + MultiNewton(int sz); + virtual ~MultiNewton(); + + int size() { return m_n; } + + /// Compute undamped step + void step(doublereal* x, doublereal* step, + OneDim& r, MultiJac& jac, int loglevel); + + /// Compute factor to keep all components in bounds. + doublereal boundStep(const doublereal* x0, const doublereal* step0, + const OneDim& r, int loglevel); + + int dampStep(const doublereal* x0, const doublereal* step0, + doublereal* x1, doublereal* step1, doublereal& s1, + OneDim& r, MultiJac& jac, int loglevel, bool writetitle); + + doublereal norm2(const doublereal* x, const doublereal* step, + OneDim& r) const; + + int solve(doublereal* x0, doublereal* x1, OneDim& r, MultiJac& jac, + int loglevel); + + /// Set options. + void setOptions(int maxJacAge = 5) {m_maxAge = maxJacAge;} + + /// Change the problem size. + void resize(int points); + + + protected: + + doublereal* getWorkArray(); + void releaseWorkArray(doublereal* work); + vector m_workarrays; + int m_maxAge; + int m_nv, m_np, m_n; + doublereal m_elapsed; + + private: + + char m_buf[100]; + }; +} + +#endif + + diff --git a/Cantera/src/oneD/Newton1D.h b/Cantera/src/oneD/Newton1D.h new file mode 100644 index 000000000..2756a900c --- /dev/null +++ b/Cantera/src/oneD/Newton1D.h @@ -0,0 +1,73 @@ +/** + * + * @file Newton1D.h + * + * Newton solver >>> under construction! <<<< + * + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2002 California Institute of Technology + * + */ + +#ifndef CT_NEWTON1D_H +#define CT_NEWTON1D_H + +#include "Jac1D.h" + +namespace Cantera { + + class Newton1D { + + public: + + Newton1D(int nv, int np); + virtual ~Newton1D(); + + doublereal norm(const doublereal* step); + void step(doublereal* x, doublereal* step, + Resid1D& r, Jac1D& jac, int loglevel, int update=1); + doublereal boundStep(const doublereal* x0, const doublereal* step0, + const Resid1D& r, int loglevel); + int dampStep(const doublereal* x0, const doublereal* step0, + doublereal* x1, doublereal* step1, doublereal& s1, + Resid1D& r, Jac1D& jac, int loglevel, bool writetitle); + void getErrorWeights(const doublereal* x, doublereal* ewt, Resid1D& r); + doublereal norm2(const doublereal* step, doublereal* ewt); + doublereal norm_infty(const doublereal* step, doublereal* ewt); + int solve(doublereal* x0, doublereal* x1, Resid1D& r, Jac1D& jac, + int loglevel); + int timeIntegrate(int n, doublereal dt, + doublereal* x0, doublereal* x1, + Resid1D& r, Jac1D& jac, int loglevel); + doublereal ssnorm(doublereal* x, doublereal* resid, Resid1D& r); + + void setOptions(int maxJacAge = 5, doublereal maxNormRatio = 0.001) { + m_maxAge = maxJacAge; + m_maxRatio = maxNormRatio; + } + void resize(int points); + + protected: + + doublereal* getWorkArray(); + void releaseWorkArray(doublereal* work); + vector m_workarrays; + vector_fp m_ewt; + int m_maxAge; + int m_maxRatio; + int m_nv, m_np, m_n; + + private: + + size_t index(int n, int j) { + return m_nv * j + n; + } + }; +} + +#endif + + diff --git a/Cantera/src/oneD/OneDim.cpp b/Cantera/src/oneD/OneDim.cpp new file mode 100644 index 000000000..918c9d80a --- /dev/null +++ b/Cantera/src/oneD/OneDim.cpp @@ -0,0 +1,377 @@ + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "MultiJac.h" +#include "MultiNewton.h" +#include "OneDim.h" + +#include "ctml.h" +using namespace ctml; + +namespace Cantera { + + /** + * Default constructor. Create an empty object. + */ + OneDim::OneDim() + : m_jac(0), m_newt(0), + m_rdt(0.0), m_jac_ok(false), + m_nd(0), m_bw(0), m_size(0), + m_nflow(0), m_nbdry(0), m_init(false), + m_ss_jac_age(10), m_ts_jac_age(20), + m_nevals(0), m_evaltime(0.0) + { + m_newt = new MultiNewton(1); + m_solve_time = 0.0; + } + + + /** + * Construct a OneDim container for the domains pointed at by the + * input vector of pointers. + */ + OneDim::OneDim(vector domains) : + m_jac(0), m_newt(0), + m_rdt(0.0), m_jac_ok(false), + m_nd(0), m_bw(0), m_size(0), + m_nflow(0), m_nbdry(0), m_init(false), + m_ss_jac_age(10), m_ts_jac_age(20), + m_nevals(0), m_evaltime(0.0) + { + + // create a Newton iterator, and add each domain. + m_newt = new MultiNewton(1); + int nd = domains.size(); + int i; + for (i = 0; i < nd; i++) addDomain(domains[i]); + init(); + resize(); + } + + void OneDim::addDomain(Resid1D* d) { + + // if not the first domain, link it to the last (rightmost) + // current domain + int n = m_dom.size(); + if (m_dom.size() > 0) m_dom.back()->append(d); + if (2*(n/2) == n) + m_connect.push_back(d); + else + m_bulk.push_back(d); + + // add it also to the global domain list, and set its + // container and position + m_dom.push_back(d); + d->setContainer(this, m_nd); + m_nd++; + resize(); + } + + + OneDim::~OneDim() { + delete m_jac; + delete m_newt; + } + + MultiJac& OneDim::jacobian() { return *m_jac; } + MultiNewton& OneDim::newton() { return *m_newt; } + + void OneDim::writeStats() { + saveStats(); + char buf[100]; + sprintf(buf,"\nStatistics:\n\n Grid Functions Time Jacobians Time \n"); + writelog(buf); + int n = m_gridpts.size(); + for (int i = 0; i < n; i++) { + sprintf(buf,"%5i %5i %9.4f %5i %9.4f \n", + m_gridpts[i], m_funcEvals[i], m_funcElapsed[i], + m_jacEvals[i], m_jacElapsed[i]); + writelog(buf); + } + } + + void OneDim::saveStats() { + if (m_jac) { + int nev = m_jac->nEvals(); + if (nev > 0) { + m_gridpts.push_back(m_pts); + m_jacEvals.push_back(m_jac->nEvals()); + m_jacElapsed.push_back(m_jac->elapsedTime()); + m_funcEvals.push_back(m_nevals); + m_nevals = 0; + m_funcElapsed.push_back(m_evaltime); + m_evaltime = 0.0; + } + } + } + + void OneDim::resize() { + int i; + m_bw = 0; + m_nvars.clear(); + m_loc.clear(); + + int lc = 0; + + saveStats(); + + m_pts = 0; + for (i = 0; i < m_nd; i++) { + Resid1D* d = m_dom[i]; + + int np = d->nPoints(); + int nv = d->nComponents(); + for (int n = 0; n < np; n++) { + m_nvars.push_back(nv); + m_loc.push_back(lc); + lc += nv; + m_pts++; + } + + // update the Jacobian bandwidth + int bw1, bw2 = 0; + + // bandwidth of the local block + bw1 = 2*d->nComponents() - 1; + + // bandwidth of the block coupling the first point of this + // domain to the last point of the previous domain + if (i > 0) { + bw2 = d->nComponents() + m_dom[i-1]->nComponents() - 1; + } + if (bw1 > m_bw) m_bw = bw1; + if (bw2 > m_bw) m_bw = bw2; + + m_size = d->loc() + d->size(); + } + m_newt->resize(size()); + m_mask.resize(size()); + + delete m_jac; + m_jac = new MultiJac(*this); + m_jac_ok = false; + + for (i = 0; i < m_nd; i++) + m_dom[i]->setJac(m_jac); + } + + + int OneDim::solve(doublereal* x, doublereal* xnew, int loglevel) { + clock_t t0 = clock(); + static int iok = 0, inotok = 0; + if (!m_jac_ok) { + eval(-1, x, xnew, 0.0, 0); // m_rdt); + m_jac->eval(x, xnew, 0.0); // m_rdt); + m_jac->updateTransient(m_rdt, m_mask.begin()); + m_jac_ok = true; + inotok++; + } + else + iok++; + int m = m_newt->solve(x, xnew, *this, *m_jac, loglevel); + clock_t t1 = clock(); + m_solve_time += (t1 - t0)/(1.0*CLOCKS_PER_SEC); + return m; + } + + /** + * Return a pointer to the domain that contains component i of the + * global solution vector. The domains are scanned right-to-left, + * and the first one with starting location less or equal to i is + * returned. + * + * 8/26/02 changed '<' to '<=' DGG + * + */ + Resid1D* OneDim::pointDomain(int i) { + Resid1D* d = right(); + while (d) { + if (d->loc() <= i) return d; + d = d->left(); + } + return 0; + } + + + /** + * Evaluate the multi-domain residual function, and return the + * result in array r. + */ + void OneDim::eval(int j, double* x, double* r, doublereal rdt, int count) { + clock_t t0 = clock(); + fill(r, r+m_size, 0.0); + fill(m_mask.begin(), m_mask.end(), 0); + if (rdt < 0.0) rdt = m_rdt; + + vector::iterator d; + for (d = m_bulk.begin(); d != m_bulk.end(); ++d) + (*d)->eval(j, x, r, m_mask.begin(), rdt); + for (d = m_connect.begin(); d != m_connect.end(); ++d) + (*d)->eval(j, x, r, m_mask.begin(), rdt); + + if (count) { + clock_t t1 = clock(); + m_evaltime += double(t1 - t0)/CLOCKS_PER_SEC; + m_nevals++; + } + } + + + /** + * The 'infinity' (maximum magnitude) norm of the steady-state + * residual. Used only for diagnostic output. + */ + doublereal OneDim::ssnorm(doublereal* x, doublereal* r) { + eval(-1, x, r, 0.0); + doublereal ss = 0.0; + for (int i = 0; i < m_size; i++) { + ss = fmaxx(fabs(r[i]),ss); + } + return ss; + } + + + /** + * Prepare for time stepping with timestep dt. + */ + void OneDim::initTimeInteg(doublereal dt, doublereal* x) { + doublereal rdt_old = m_rdt; + m_rdt = 1.0/dt; + if (fabs(rdt_old - m_rdt) > Tiny) { + m_jac->updateTransient(m_rdt, m_mask.begin()); + } + Resid1D* d = left(); + while (d) { + d->initTimeInteg(dt, x); + d = d->right(); + } + } + + /** + * Prepare to solve the steady-state problem. Set the reciprocal + * of the time step to zero, and, if it was previously non-zero, + * signal that a new Jacobian will be needed. + */ + void OneDim::setSteadyMode() { + m_rdt = 0.0; + m_jac->updateTransient(m_rdt, m_mask.begin()); + } + + /** + * Initialize all domains. On the first call, this methods calls + * the init method of each domain, proceeding from left to right. + * Subsequent calls do nothing. + */ + void OneDim::init() { + if (!m_init) { + Resid1D* d = left(); + while (d) { + d->init(); + d = d->right(); + } + } + m_init = true; + } + + /** + * Signal that the current Jacobian is no longer valid. + */ + void Resid1D::needJacUpdate() { + if (m_container) + m_container->jacobian().setAge(10000); + } + + /** + * Take time steps using Backward Euler. + * + * nsteps -- number of steps + * dt -- initial step size + * loglevel -- controls amount of printed diagnostics + */ + doublereal OneDim::timeStep(int nsteps, doublereal dt, doublereal* x, + doublereal* r, int loglevel) { + + newton().setOptions(m_ts_jac_age); + + if (loglevel > 0) { + writelog("Begin time integration.\n\n"); + writelog(" step size (s) log10(ss) "); + writelog("==============================="); + } + int n = 0, m; + doublereal ss; + char str[80]; + while (n < nsteps) { + if (loglevel > 0) { + ss = ssnorm(x, r); + sprintf(str, " %4d %10.4g %10.4g" , n,dt,log10(ss)); + writelog(str); + } + initTimeInteg(dt,x); + m = solve(x, r, loglevel-1); + if (m >= 0) { + n += 1; + if (loglevel > 0) writelog("\n"); + copy(r, r + m_size, x); + } + else { + if (loglevel > 0) writelog("...failure."); + dt *= 0.5; + if (dt < 1.e-14) + throw CanteraError("OneDim::timeStep", + "Time integration failed."); + } + } + setSteadyMode(); + newton().setOptions(m_ss_jac_age); + return dt; + } + + void OneDim::save(string fname, string id, string desc, doublereal* sol) { + + struct tm *newtime; + time_t aclock; + ::time( &aclock ); /* Get time in seconds */ + newtime = localtime( &aclock ); /* Convert time to struct tm form */ + + XML_Node root("doc"); + ifstream fin(fname.c_str()); + XML_Node* ct; + if (fin) { + root.build(fin); + XML_Node* same_ID = root.findID(id); + int jid = 1; + string idnew = id; + while (same_ID != 0) { + idnew = id + "_" + int2str(jid); + jid++; + same_ID = root.findID(idnew); + } + id = idnew; + fin.close(); + ct = &root.child("ctml"); + } + else { + ct = &root.addChild("ctml"); + } + XML_Node& sim = (XML_Node&)ct->addChild("simulation"); + sim.addAttribute("id",id); + addString(sim,"timestamp",asctime(newtime)); + if (desc != "") addString(sim,"description",desc); + + Resid1D* d = left(); + while (d) { + d->save(sim, sol); + d = d->right(); + } + ofstream s(fname.c_str()); + if (!s) + throw CanteraError("save","could not open file "+fname); + ct->write(s); + s.close(); + writelog("Solution saved to file "+fname+" as solution '"+id+"'.\n"); + } +} diff --git a/Cantera/src/oneD/OneDim.h b/Cantera/src/oneD/OneDim.h new file mode 100644 index 000000000..9685ed573 --- /dev/null +++ b/Cantera/src/oneD/OneDim.h @@ -0,0 +1,156 @@ +/** + * @file OneDim.h + */ + +#ifndef CT_ONEDIM_H +#define CT_ONEDIM_H + +#include "Resid1D.h" + +namespace Cantera { + + class MultiJac; + class MultiNewton; + + /** + * Container class for multiple-domain 1D problems. Each domain is + * represented by an instance of Resid1D. + */ + class OneDim { + public: + + // Default constructor. + OneDim(); + + // Constructor. + OneDim(vector domains); + + /// Destructor. + virtual ~OneDim(); + + /// Add a domain. + void addDomain(Resid1D* d); + + /// Return a reference to the Jacobian. + MultiJac& jacobian(); + + /// Return a reference to the Newton iterator. + MultiNewton& newton(); + + /// Solve F(x) = 0, where F(x) is the multi-domain residual. + int solve(doublereal* x, doublereal* xnew, int loglevel); + + /// Number of domains. + int nDomains() const { return m_nd; } + + /// Return a reference to domain i. + Resid1D& domain(int i) const { return *m_dom[i]; } + + /// The index of the start of domain i in the solution vector. + int start(int i) const { return m_dom[i]->loc(); } + + /// Total solution vector length; + int size() const { return m_size; } + + /// Pointer to left-most domain (first added). + Resid1D* left() { return m_dom[0]; } + + /// Pointer to right-most domain (last added). + Resid1D* right() { return m_dom.back(); } + + /// Number of solution components at global point jg. + int nVars(int jg) { return m_nvars[jg]; } + + /** Location in the solution vector of the first component of + global point jg. */ + int loc(int jg) { return m_loc[jg]; } + + /// Jacobian bandwidth. + int bandwidth() const { return m_bw; } + + /// Initialize. + void init(); + + /// Total number of points. + int points() { return m_pts; } + + /// Staedy-state max norm of the residual. + doublereal ssnorm(doublereal* x, doublereal* r); + + /// Reciprocal of the time step. + doublereal rdt() const { return m_rdt; } + + /// Prepare for time stepping. + void initTimeInteg(doublereal dt, doublereal* x); + + /// True if transient mode. + bool transient() const { return (m_rdt != 0.0);} + + /// True if steady mode. + bool steady() const { return (m_rdt == 0.0); } + + /// Set steady mode + void setSteadyMode(); + + /// Evaluate the multi-domain residual function + void eval(int j, double* x, double* r, doublereal rdt=-1.0, + int count = 1); + + /// Pointer to the domain global point i belongs to. + Resid1D* pointDomain(int i); + + void resize(); + doublereal solveTime() { return m_solve_time; } + + //void setTransientMask(); + vector_int& transientMask() { return m_mask; } + + double timeStep(int nsteps, double dt, double* x, + double* r, int loglevel); + + void writeStats(); + void saveStats(); + + void save(string fname, string id, string desc, doublereal* sol); + + protected: + + MultiJac* m_jac; + MultiNewton* m_newt; + doublereal m_rdt; + bool m_jac_ok; + int m_nd; + int m_bw; + int m_size; + vector_int m_states; + vector_int m_start; + vector_int m_comp, m_points; + vector m_dom, m_connect, m_bulk; + vector_int m_flow, m_bdry; + int m_nflow, m_nbdry; + bool m_init; + vector_int m_nvars; + vector_int m_loc; + vector_int m_mask; + int m_pts; + doublereal m_solve_time; + + int m_ss_jac_age, m_ts_jac_age; + + // stats + int m_nevals; + doublereal m_evaltime; + vector_int m_gridpts; + vector_int m_jacEvals; + vector_fp m_jacElapsed; + vector_int m_funcEvals; + vector_fp m_funcElapsed; + + private: + }; + +} + +#endif + + diff --git a/Cantera/src/oneD/Resid1D.h b/Cantera/src/oneD/Resid1D.h new file mode 100644 index 000000000..c9d9b0b24 --- /dev/null +++ b/Cantera/src/oneD/Resid1D.h @@ -0,0 +1,237 @@ +/** + * @file Resid1D.h + * + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2002 California Institute of Technology + * + */ + +#ifndef CT_RESID1D_H +#define CT_RESID1D_H + + +//#include "stringUtils.h" +#include "../ctexceptions.h" +#include "../xml.h" + +namespace Cantera { + + // domain types + const int cFlowType = 101; + const int cSurfType = 102; + const int cConnectorType = 103; + const int cInletType = 104; + const int cSymmType = 105; + const int cOutletType = 106; + + class MultiJac; + class OneDim; + + + /** + * Base class for single-domain, one-dimensional residual function + * evaluators. + */ + class Resid1D { + public: + + /** + * Constructor. + * @param nv Number of variables at each grid point. + * @param points Number of grid points. + */ + Resid1D(int nv=1, int points=1, + doublereal time = 0.0) : + m_time(time), + m_container(0), + m_index(-1), + m_type(0), + m_iloc(0), + m_jstart(0), + m_left(0), + m_right(0) { + resize(nv, points); + } + + /// Destructor. + virtual ~Resid1D(){} + + /// Domain type flag. + const int domainType() { return m_type; } + + const OneDim& container() const{ return *m_container; } + + /** + * Specify the container object for this domain, and the + * position of this domain in the list. + */ + void setContainer(OneDim* c, int index){ + m_container = c; + m_index = index; + } + + /** Initialize. Base class method does nothing, but may be + * overloaded. + */ + virtual void init(){} + + /** + * Resize the domain to have nv components and np grid points. + */ + virtual void resize(int nv, int np) { + m_nv = nv; + m_max.resize(m_nv, 0.0); + m_min.resize(m_nv, 0.0); + m_rtol.resize(m_nv, 0.0); + m_atol.resize(m_nv, 0.0); + m_points = np; + m_slast.resize(m_nv * m_points, 0.0); + locate(); + } + + /// Number of components at each grid point. + int nComponents() const { return m_nv; } + + /// Number of grid points in this domain. + int nPoints() const { return m_points; } + + /// Name of the nth component. May be overloaded. + virtual string componentName(int n) const { + return "component " + int2str(n); } + + /** + * Set the lower and upper bounds for each solution component. + */ + void setBounds(int nl, const doublereal* lower, + int nu, const doublereal* upper) { + if (nl != m_nv || nu != m_nv) + throw CanteraError("Resid1D::setBounds", + "wrong array size for solution bounds"); + copy(upper, upper + m_nv, m_max.begin()); + copy(lower, lower + m_nv, m_min.begin()); + } + + void setTolerances(int nr, const doublereal* rtol, + int na, const doublereal* atol) { + if (nr != m_nv || na != m_nv) + throw CanteraError("Resid1D::setTolerances", + "wrong array size for solution error tolerances. Size should be "+int2str(m_nv)); + copy(rtol, rtol + m_nv, m_rtol.begin()); + copy(atol, atol + m_nv, m_atol.begin()); + } + + doublereal rtol(int n) { return m_rtol[n]; } + doublereal atol(int n) { return m_atol[n]; } + + doublereal upperBound(int n) const { return m_max[n]; } + doublereal lowerBound(int n) const { return m_min[n]; } + + void initTimeInteg(doublereal dt, const doublereal* x0) { + copy(x0 + loc(), x0 + loc() + size(), m_slast.begin()); + m_rdt = 1.0/dt; + } + + void setSteadyMode() { m_rdt = 0.0; } + + bool steady() { return (m_rdt == 0.0); } + bool transient() { return (m_rdt != 0.0); } + + void needJacUpdate(); + + void evalss(doublereal* x, doublereal* r, integer* mask) { + eval(-1,x,r,mask,0.0); + } + + /** + * Evaluate the residual function at point j. If j < 0, + * evaluate the residual function at all points. + */ + virtual void eval(int j, doublereal* x, doublereal* r, + integer* mask, doublereal rdt=0.0) { + throw CanteraError("Resid1D::eval", + "residual function not defined."); + } + + virtual void update(doublereal* x) {} + + doublereal time() { return m_time;} + void incrementTime(doublereal dt) { m_time += dt; } + size_t index(int n, int j) const { return m_nv*j + n; } + + virtual void setJac(MultiJac* jac){} + virtual void save(XML_Node& o, doublereal* sol) { + throw CanteraError("Resid1D::save","base class method called"); + } + + int size() { return m_nv*m_points; } + + void locate() { + if (m_left) { + m_jstart = m_left->lastPoint() + 1; + m_iloc = m_left->loc() + m_left->size(); + } + else { + m_jstart = 0; + m_iloc = 0; + } + if (m_right) m_right->locate(); + } + + virtual int loc(int j = 0) { return m_iloc; } + + int firstPoint() { return m_jstart; } + int lastPoint() { return m_jstart + m_points - 1; } + + void append(Resid1D* right) { + linkRight(right); + right->linkLeft(this); + } + + void linkLeft(Resid1D* left) { + m_left = left; + locate(); + } + void linkRight(Resid1D* right) { m_right = right; } + + Resid1D* left() { return m_left; } + Resid1D* right() { return m_right; } + + double prevSoln(int n, int j) const{ + return m_slast[m_nv*j + n]; + } + + void setID(const string& s) {m_id = s;} + void setDesc(const string& s) {m_desc = s;} + + virtual void getTransientMask(integer* mask){} + + protected: + + doublereal m_rdt; + int m_nv; + int m_points; + vector_fp m_slast; + doublereal m_time; + vector_fp m_max; + vector_fp m_min; + vector_fp m_rtol; + vector_fp m_atol; + OneDim* m_container; + int m_index; + int m_type; + int m_iloc; + int m_jstart; + Resid1D *m_left, *m_right; + string m_id, m_desc; + + private: + + }; +} + +#endif + + diff --git a/Cantera/src/oneD/StFlow.cpp b/Cantera/src/oneD/StFlow.cpp new file mode 100644 index 000000000..d75f46945 --- /dev/null +++ b/Cantera/src/oneD/StFlow.cpp @@ -0,0 +1,1239 @@ +/** + * @file StFlow.cpp + */ + +/* + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2002 California Institute of Technology + + +// turn off warnings under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include +#include + +#include "StFlow.h" +#include "../ArrayViewer.h" +#include "ctml.h" +#include "MultiJac.h" + +using namespace ctml; + +namespace Cantera { + + + //------------------- importSolution ------------------------ + + /** + * Import a previous solution to use as an initial estimate. The + * previous solution may have been computed using a different + * reaction mechanism. Species in the old and new mechanisms are + * matched by name, and any species in the new mechanism that were + * not in the old one are set to zero. The new solution is created + * with the same number of grid points as in the old solution. + */ + void importSolution(int points, + doublereal* oldSoln, igthermo_t& oldmech, + int size_new, doublereal* newSoln, igthermo_t& newmech) { + + // Number of components in old and new solutions + int nv_old = oldmech.nSpecies() + 4; + int nv_new = newmech.nSpecies() + 4; + + if (size_new < nv_new*points) { + throw CanteraError("importSolution", + "new solution array must have length "+ + int2str(nv_new*points)); + } + + int n, j, knew; + string nm; + + // copy u,V,T,lambda + for (j = 0; j < points; j++) + for (n = 0; n < 4; n++) + newSoln[nv_new*j + n] = oldSoln[nv_old*j + n]; + + // copy mass fractions + int nsp0 = oldmech.nSpecies(); + int nsp1 = newmech.nSpecies(); + + // loop over the species in the old mechanism + for (int k = 0; k < nsp0; k++) { + nm = oldmech.speciesName(k); // name + + // location of this species in the new mechanism. + // If < 0, then the species is not in the new mechanism. + knew = newmech.speciesIndex(nm); + + // copy this species from the old to the new solution vectors + if (knew >= 0) { + for (j = 0; j < points; j++) { + newSoln[nv_new*j + 4 + knew] = oldSoln[nv_old*j + 4 + k]; + } + } + } + + + // normalize mass fractions + for (j = 0; j < points; j++) { + newmech.setMassFractions(&newSoln[nv_new*j + 4]); + newmech.getMassFractions(nsp1,&newSoln[nv_new*j + 4]); + } + } + + + //---------------------- drawline ---------------------------------- + + inline void drawline(ostream& s) { + s << "\n-------------------------------------" + << "------------------------------------------"; + } + + + //--------------------- linear interp ------------------------------ + + /** + * Linearly interpolate a function defined on a discrete grid. + * vector xpts contains a monotonic sequence of grid points, and + * vector fpts contains function values defined at these points. + * The value returned is the linear interpolate at point x. + * If x is outside the range of xpts, the value of fpts at the + * nearest end is returned. + */ + + doublereal linearInterp(doublereal x, vector_fp& xpts, vector_fp& fpts) { + if (x <= xpts[0]) return fpts[0]; + if (x >= xpts.back()) return fpts.back(); + doublereal* loc = lower_bound(xpts.begin(), xpts.end(), x); + int iloc = int(loc - xpts.begin()) - 1; + doublereal ff = fpts[iloc] + + (x - xpts[iloc])*(fpts[iloc + 1] + - fpts[iloc])/(xpts[iloc + 1] - xpts[iloc]); + return ff; + } + + + + StFlow::StFlow(igthermo_t* ph, int nsp, int points) : + Resid1D(nsp+4, points), + m_inlet_u(0.0), + m_inlet_V(0.0), + m_inlet_T(-1.0), + m_surface_T(-1.0), + m_press(-1.0), + m_nsp(nsp), + m_thermo(0), + m_kin(0), + m_trans(0), + m_jac(0), + m_ok(false), + m_do_soret(false), + m_transport_option(-1), + m_efctr(0.0) + { + m_type = cFlowType; + + m_boundary.resize(2,0); + + m_points = points; + m_thermo = ph; + m_nv = m_nsp + 4; + + if (ph == 0) return; // used to create a dummy object + + // make a local copy of the species molecular weight vector + m_wt = m_thermo->molecularWeights(); + + // the species mass fractions are the last components in the solution + // vector, so the total number of components is the number of species + // plus the offset of the first mass fraction. + m_nv = c_offset_Y + m_nsp; + + // enable all species equations by default + m_do_species.resize(m_nsp, true); + + // but turn off the energy equation at all points + m_do_energy.resize(m_points,false); + + m_diff.resize(m_nsp,m_points); + m_flux.resize(m_nsp,m_points); + m_wdot.resize(m_nsp,m_points, 0.0); + m_surfdot.resize(m_nsp, 0.0); + m_ybar.resize(m_nsp); + + // default solution bounds + vector_fp vmin(m_nv), vmax(m_nv); + + // no bounds on u + vmin[0] = -1.e20; + vmax[0] = 1.e20; + + // no negative V + vmin[1] = -0.01; + vmax[1] = 1.e20; + + // temperature bounds + vmin[2] = 200.0; + vmax[2]= 1.e9; + + // lamda should be negative + vmin[3] = -1.e20; + vmax[3] = 0.001; + + // mass fraction bounds + int k; + for (k = 0; k < m_nsp; k++) { + vmin[4+k] = -1.e-5; + vmax[4+k] = 1.1; + } + setBounds(vmin.size(), vmin.begin(), vmax.size(), vmax.begin()); + } + + /** + * Change the grid size. Called after grid refinement. + */ + void StFlow::resize(int points) { + Resid1D::resize(m_nv, points); + + m_rho.resize(m_points, 0.0); + m_wtm.resize(m_points, 0.0); + m_cp.resize(m_points, 0.0); + m_enth.resize(m_points, 0.0); + m_visc.resize(m_points, 0.0); + m_tcon.resize(m_points, 0.0); + + m_diff.resize(m_nsp,m_points); + m_flux.resize(m_nsp,m_points); + m_wdot.resize(m_nsp,m_points, 0.0); + m_do_energy.resize(m_points,false); + + m_fixedy.resize(m_nsp, m_points); + m_fixedtemp.resize(m_points); + + m_dz.resize(m_points-1); + m_z.resize(m_points); + } + + + + void StFlow::setupGrid(int n, const doublereal* z) { + resize(n); + int j; + + m_z[0] = z[0]; + for (j = 1; j < m_points; j++) { + m_z[j] = z[j]; + m_dz[j-1] = m_z[j] - m_z[j-1]; + } + } + + + /** + * Install a transport manager. + */ + void StFlow::setTransport(Transport& trans, bool withSoret) { + m_trans = &trans; + m_do_soret = withSoret; + + if (m_trans->model() == cMulticomponent) { + m_transport_option = c_Multi_Transport; + } + else if (m_trans->model() == cMixtureAveraged) { + m_transport_option = c_Mixav_Transport; + if (withSoret) + throw CanteraError("setTransport", + "Thermal diffusion (the Soret effect) " + "requires using a multicomponent transport model."); + } + else + throw CanteraError("setTransport","unknown transport model."); + } + + /** + * Set the gas object state to be consistent with the solution at + * point j. + */ + void StFlow::setGas(const doublereal* x,int j) { + m_thermo->setTemperature(T(x,j)); + const doublereal* yy = x + m_nv*j + c_offset_Y; + m_thermo->setMassFractions_NoNorm(yy); + m_thermo->setPressure(m_press); + } + + void StFlow::setGasAtMidpoint(const doublereal* x,int j) { + m_thermo->setTemperature(0.5*(T(x,j)+T(x,j+1))); + const doublereal* yyj = x + m_nv*j + c_offset_Y; + const doublereal* yyjp = x + m_nv*(j+1) + c_offset_Y; + for (int k = 0; k < m_nsp; k++) + m_ybar[k] = 0.5*(yyj[k] + yyjp[k]); + m_thermo->setMassFractions_NoNorm(m_ybar.begin()); + m_thermo->setPressure(m_press); + } + + +// /** +// * Integrate the species mass fractions at each point separately, +// * without the transport terms. This method is provided to +// * condition a poor estimate of the solution to produce a better +// * starting estimate for Newton iteration. It is not used by any +// * other method, but is available for use in user codes, if +// * desired. +// */ +// void StFlow::integrateChem(doublereal* x,doublereal dt) { +// int j; +// if (!ready()) return; +// if (m_integrator == 0) { +// m_integrator = new ImplicitChem(*m_kin, *m_thermo); +// m_integrator->initialize(0.0); +// } +// for (j = 0; j < m_points; j++) { +// setGas(x,j); +// m_integrator->integrate(0.0, dt); +// m_thermo->getMassFractions(m_nsp, &x[index(c_offset_Y,j)]); +// T(x,j) = m_thermo->temperature(); +// } +// } + + + + /** + * Evaluate the residual function for stagnation flow. If jpt is + * less than zero, the residual function is evaluated at all grid + * points. If jpt >= 0, then the residual function is only + * evaluated at grid points jpt-1), jpt, and jpt+1. This option + * is used to efficiently evaluate the Jacobian numerically. + */ + + void AxiStagnFlow::eval(int jg, doublereal* xg, + doublereal* rg, integer* diagg, doublereal rdt) { + + if (jg >=0 && (jg < firstPoint() - 1 || jg > lastPoint() + 1)) return; + + if (jg >= 0) rdt = 0.0; + + // start of local part of global arrays + doublereal* x = xg + loc(); + doublereal* rsd = rg + loc(); + integer* diag = diagg + loc(); + + int jmin, jmax, jpt; + jpt = jg - firstPoint(); + + if (jg < 0) { + jmin = 0; + jmax = m_points - 1; + } + else { + jmin = max(jpt-1, 0); + jmax = min(jpt+1,m_points-1); + } + + // properties are computed for grid points from j0 to j1 + int j0 = max(jmin-1,0); + int j1 = min(jmax+1,m_points-1); + + + int j, k; + + + //----------------------------------------------------- + // update properties + //----------------------------------------------------- + + // thermodynamic properties + if (jpt < 0) updateThermo(x, j0, j1); + + // update transport properties only if a Jacobian is + // not being evaluated + if (jpt < 0) updateTransport(x, j0, j1); + + // update the species diffusive mass fluxes + updateDiffFluxes(x, j0, j1); + + + //---------------------------------------------------- + // evaluate the residual equations at all required + // grid points + //---------------------------------------------------- + + doublereal sum, sum2, dtdzj; + + for (j = jmin; j <= jmax; j++) { + + + //---------------------------------------------- + // left boundary + //---------------------------------------------- + + if (j == 0) { + + // these may be modified by a boundary object + +#define NEW_INLET +#ifdef NEW_INLET + // continuity + rsd[index(c_offset_U,0)] = + -(rho_u(x,1) - rho_u(x,0))/m_dz[0] + -(density(1)*V(x,1) + density(0)*V(x,0)); + + rsd[index(c_offset_V,0)] = V(x,0); + rsd[index(c_offset_T,0)] = T(x,0); + rsd[index(c_offset_L,0)] = -rho_u(x,0); + //cout << "rsd: " << rsd[0] << " " << rsd[1] << " " << rsd[2] << endl; + + // zero flux + for (k = 0; k < m_nsp; k++) { + rsd[index(c_offset_Y + k, 0)] = + -(m_flux(k,0) + rho_u(x,0)* Y(x,k,0)); + } +#else + // first, call the left boundary object to evaluate + // the residual + + m_boundary[0]->eval(x + index(0,0), m_rho[0], m_flux.begin(), + rsd + index(0,0)); + + + // Now modify the left boundary conditions to allow + // specifying the mass flux at both boundaries. The + // right mass flux is specified directly as a boundary + // condition on the continuity equation; the left mass + // flux is matched by adjusting lambda. + + // Shift the left continuity boundary condition to lambda, + rsd[index(c_offset_L, 0)] = rsd[index(c_offset_U, 0)]; + + // and replace it with the continuity equation. + rsd[index(c_offset_U,0)] = + -(rho_u(x,1) - rho_u(x,0))/m_dz[0] + -(density(1)*V(x,1) + density(0)*V(x,0)); +#endif + } + + + //---------------------------------------------- + // right boundary + // + // The right boundary residuals are for a nonreacting, + // impermeable wall. Since domains are evaluated left to + // right, the surface object may add terms to these + // residual equations. + // + //---------------------------------------------- + + else if (j == m_points - 1) { + + //m_boundary[1]->eval(x + index(0, j), m_rho[j], + // m_flux.begin() + m_nsp*(j-1), + // rsd + index(0, j)); + + rsd[index(0,j)] = rho_u(x,j); + rsd[index(1,j)] = V(x,j); + rsd[index(2,j)] = T(x,j); + + doublereal sum = 0.0; + for (k = 0; k < m_nsp; k++) { + sum += Y(x,k,j); + rsd[index(k+4,j)] = rho_u(x,j)*Y(x,k,j) + m_flux(k,j-1); + } + rsd[index(4,j)] = 1.0 - sum; + diag[index(4,j)] = 0; + } + + //------------------------------------------ + // interior points + //------------------------------------------ + + else { + + //---------------------------------------------- + // Continuity equation + // + // Note that this propagates the mass flow rate + // information to the left (j+1 -> j) from the + // value specified at the right boundary. The + // lambda information propagates in the opposite + // direction. + // + // d(\rho u)/dz + 2\rho V = 0 + // + //------------------------------------------------ + rsd[index(c_offset_U,j)] = + -(rho_u(x,j+1) - rho_u(x,j))/m_dz[j] + -(density(j+1)*V(x,j+1) + density(j)*V(x,j)); + + + //------------------------------------------------ + // Radial momentum equation + // + // \rho u dV/dz + \rho V^2 = d(\mu dV/dz)/dz - lambda + // + //------------------------------------------------- + rsd[index(c_offset_V,j)] + = (shear(x,j) - lambda(x,j) - rho_u(x,j)*dVdz(x,j) + - m_rho[j]*V(x,j)*V(x,j))/m_rho[j]; + + + //------------------------------------------------- + // Species equations + // + // \rho u dY_k/dz + dJ_k/dz + M_k\omega_k + // + //------------------------------------------------- + getWdot(x,j); + + doublereal convec, diffus; + for (k = 0; k < m_nsp; k++) { + if (m_do_species[k]) { + convec = rho_u(x,j)*dYdz(x,k,j); + diffus = 2.0*(m_flux(k,j) - m_flux(k,j-1)) + /(z(j+1) - z(j-1)); + rsd[index(c_offset_Y + k, j)] + = (m_wt[k]*(wdot(k,j) ) + - convec - diffus)/m_rho[j] + - rdt*(Y(x,k,j) - Y_prev(k,j)); + diag[index(c_offset_Y + k, j)] = 1; + } + } + + + //----------------------------------------------- + // energy equation + //----------------------------------------------- + + if (m_do_energy[j]) { + + setGas(x,j); + + // heat release term + const vector_fp& h_RT = m_thermo->enthalpy_RT(); + const vector_fp& cp_R = m_thermo->cp_R(); + sum = 0.0; + sum2 = 0.0; + doublereal flxk; + for (k = 0; k < m_nsp; k++) { + flxk = 0.5*(m_flux(k,j-1) + m_flux(k,j)); + sum += wdot(k,j)*h_RT[k]; + sum2 += flxk*cp_R[k]/m_wt[k]; + } + sum *= GasConstant * T(x,j); + dtdzj = dTdz(x,j); + sum2 *= GasConstant * dtdzj; + + rsd[index(c_offset_T, j)] = + - m_cp[j]*rho_u(x,j)*dtdzj + - divHeatFlux(x,j) - sum - sum2; + rsd[index(c_offset_T, j)] /= (m_rho[j]*m_cp[j]); + + rsd[index(c_offset_T, j)] = + rsd[index(c_offset_T, j)] + m_efctr*(T_fixed(j) - T(x,j)); + + rsd[index(c_offset_T, j)] -= rdt*(T(x,j) - T_prev(j)); + diag[index(c_offset_T, j)] = 1; + + + } + } + + // residual equations if the energy or species equations + // are disabled + + for (k = 0; k < m_nsp; k++) { + if (!m_do_species[k]) { + rsd[index(c_offset_Y+k,j)] = Y(x,k,j) - Y_fixed(k,j); + diag[index(c_offset_Y+k, j)] = 0; + } + } + if (!m_do_energy[j]) { + rsd[index(c_offset_T, j)] = T(x,j) - T_fixed(j); + diag[index(c_offset_T, j)] = 0; + } + + // lambda + if (j > 0) { + rsd[index(c_offset_L, j)] = lambda(x,j) - lambda(x,j-1); + diag[index(c_offset_L, j)] = 0; + } + } + } + + + + /** + * Update the transport properties at grid points in the range + * from j0 to j1, based on solution x. + */ + void AxiStagnFlow::updateTransport(doublereal* x,int j0, int j1) { + int j; + //for (j = j0; j <= j1; j++) { + for (j = j0; j < j1; j++) { + setGasAtMidpoint(x,j); + m_visc[j] = m_trans->viscosity(); + m_trans->getMixDiffCoeffs(&m_diff(0,j)); + m_tcon[j] = m_trans->thermalConductivity(); + } + } + + + void OneDFlow::eval(int jg, doublereal* xg, doublereal* rg, integer* diagg, + doublereal rdt) { + + static double elapsed; + // doublereal rtau = 1.e5; + + clock_t t0 = clock(); + + // doublereal rdt_save = rdt; + if (jg >= 0) rdt = 0.0; + + if (jg >= 0 && (jg < firstPoint() || jg > lastPoint())) return; + + // start of local part of global arrays + doublereal* x = xg + loc(); + doublereal* rsd = rg + loc(); + integer* diag = diagg + loc(); + + int jmin, jmax, jpt; + jpt = jg - firstPoint(); + + for (int jj = 0; jj < m_points*m_nv; jj++) { + if (x[jj] < -1.e20 || x[jj] > 1.e20) { + showSolution(cout, x); + throw CanteraError("tlt","tlt"); + } + } + + // the residual function is evaluated for jmin <= j <= jmax, and + // properties and evaluated for j0 <= j <= j1. + + if (jg < 0) { + jmin = 0; + jmax = m_points - 1; + } + else { + jmin = max(jpt-1,0); + jmax = min(jpt+1,m_points-1); + } + int j0 = max(jmin-1,0); + int j1 = min(jmax+1,m_points-1); + + int j, k; + + //----------------------------------------------------- + // compute properties needed in the residual equations + //----------------------------------------------------- + + // for each point, synchronize the state of the fluid object + // with the current solution values, and then use this object + // to compute the density, mean molecular weight, and mean + // specific heat at constant pressure. + if (jpt < 0) updateThermo(x, j0, j1); + + // skip updating transport properties if a Jacobian is + // being evaluated + if (jpt < 0) updateTransport(x, j0, j1); + + // update the species diffusive mass fluxes + updateDiffFluxes(x, j0, j1); + + + //---------------------------------------------------- + // evaluate the residual equations at all required + // grid points + //---------------------------------------------------- + + doublereal sum, sum2, deltaz, dtdzj; + + + for (j = jmin; j <= jmax; j++) { + + + //---------------------------------------------- + // boundaries + //---------------------------------------------- + + if (j == 0) { + setGas(x,0); + m_boundary[0]->eval(x, m_rho[0], m_flux.begin(), + rsd); + } + + else if (j == m_points - 1) { + m_boundary[1]->eval(x + index(0, j), m_rho[j], + m_flux.begin() + m_nsp*(j-1), + rsd + index(0, j)); + } + + + //------------------------------------------ + // interior points + //------------------------------------------ + + else { + + // continuity + rsd[index(c_offset_U,j)] = (rho_u(x,j-1) - rho_u(x,j)); + + // radial velocity = 0 + rsd[index(c_offset_V,j)] = V(x,j); + + // species equations + getWdot(x,j); + + doublereal convec, diffus; + for (k = 0; k < m_nsp; k++) { + if (m_do_species[k]) { + + convec = rho_u(x,j) * dYdz(x,k,j); + diffus = 2.0*(m_flux(k,j) - m_flux(k,j-1))/(z(j+1) - z(j-1)); + rsd[index(c_offset_Y + k, j)] = + (m_wt[k]*wdot(k,j) - convec - diffus)/m_rho[j] + - rdt*(Y(x,k,j) - Y_prev(k,j)); + diag[index(c_offset_Y + k, j)] = 1; + } + else + rsd[index(c_offset_Y+k,j)] = (Y(x,k,j) - Y_fixed(k,j)); + } + + + // energy equation + + if (m_do_energy[j]) { + setGas(x,j); + + // heat release term + const vector_fp& h_RT = m_thermo->enthalpy_RT(); + const vector_fp& cp_R = m_thermo->cp_R(); + sum = 0.0; + sum2 = 0.0; + deltaz = (z(j+1) - z(j-1)); + doublereal flxk; + for (k = 0; k < m_nsp; k++) { + flxk = 0.5*(m_flux(k,j-1) + m_flux(k,j)); + + sum += wdot(k,j)*h_RT[k]; + sum2 += flxk*cp_R[k]/m_wt[k]; + } + sum *= GasConstant * T(x,j); + dtdzj = (T(x,j+1) - T(x,j-1))/deltaz; // dTdz(x,j) + (m_dz[j-1]/deltaz)*(dTdz(x,j+1) - dTdz(x,j)); + sum2 *= GasConstant * dtdzj; + rsd[index(c_offset_T, j)] = - m_cp[j]*rho_u(x,j)*dtdzj + - divHeatFlux(x,j) - sum - sum2; + rsd[index(c_offset_T, j)] /= (m_rho[j]*m_cp[j]); + rsd[index(c_offset_T, j)] -= rdt*(T(x,j) - T_prev(j)); + diag[index(c_offset_T, j)] = 1; + } + + // lambda = 0 + rsd[index(c_offset_L, j)] = lambda(x,j); + + } + for (k = 0; k < m_nsp; k++) { + if (!m_do_species[k]) { + rsd[index(c_offset_Y+k,j)] = + (Y(x,k,j) - Y_fixed(k,j)); + diag[index(c_offset_Y+k, j)] = 0; + } + } + if (!m_do_energy[j]) { + rsd[index(c_offset_T, j)] = (T(x,j) - T_fixed(j)); + diag[index(c_offset_T, j)] = 0; + } + + } + clock_t t1 = clock(); + elapsed += double(t1 - t0)/CLOCKS_PER_SEC; + } + + + /** + * Update the transport properties at grid points in the range + * from j0 to j1, based on solution x. + */ + void OneDFlow::updateTransport(doublereal* x,int j0, int j1) { + int j; + for (j = j0; j < j1; j++) { + setGasAtMidpoint(x,j); + m_trans->getMixDiffCoeffs(&m_diff(0,j)); + m_tcon[j] = m_trans->thermalConductivity(); + } + } + + + /** + * Print the solution. + */ + void StFlow::showSolution(ostream& s, const doublereal* x) { + int nn = m_nv/5; + int i, j, n; + char* buf = new char[100]; + + // The mean molecular weight is needed to convert + updateThermo(x, 0, m_points-1); + + for (i = 0; i < nn; i++) { + drawline(s); + sprintf(buf, "\n z "); + s << buf; + for (n = 0; n < 5; n++) { + sprintf(buf, " %10s ",componentName(i*5 + n).c_str()); + s << buf; + } + drawline(s); + for (j = 0; j < m_points; j++) { + sprintf(buf, "\n %10.4g ",m_z[j]); + s << buf; + for (n = 0; n < 5; n++) { + sprintf(buf, " %10.4g ",component(x, i*5+n,j)); + s << buf; + } + } + s << endl; + } + int nrem = m_nv - 5*nn; + drawline(s); + sprintf(buf, "\n z "); + s << buf; + for (n = 0; n < nrem; n++) { + sprintf(buf, " %10s ", componentName(nn*5 + n).c_str()); + s << buf; + } + drawline(s); + for (j = 0; j < m_points; j++) { + sprintf(buf, "\n %10.4g ",m_z[j]); + s << buf; + for (n = 0; n < nrem; n++) { + sprintf(buf, " %10.4g ",component(x, nn*5+n,j)); + s << buf; + } + } + s << endl; + } + + + /** + * Update the diffusive mass fluxes. + */ + void StFlow::updateDiffFluxes(const doublereal* x, int j0, int j1) { + int j, k; + double sum, wtm, rho, dz; + switch (m_transport_option) { + + case c_Mixav_Transport: + for (j = j0; j < j1; j++) { + sum = 0.0; + wtm = m_wtm[j]; + rho = density(j); + dz = z(j+1) - z(j); + + for (k = 0; k < m_nsp; k++) { + m_flux(k,j) = m_wt[k]*(rho*m_diff(k,j)/wtm); + m_flux(k,j) *= (X(x,k,j) - X(x,k,j+1))/dz; + sum -= m_flux(k,j); + } + // correction flux to insure that \sum_k Y_k j_k = 0. + for (k = 0; k < m_nsp; k++) m_flux(k,j) += sum*Y(x,k,j); + } + break; + + case c_Multi_Transport: + cout << " not yet implemented... " << endl; + } + if (m_do_soret) { + cout << " net yet implemented... " << endl; + } + } + + + + void StFlow::outputTEC(ostream &s, const doublereal* x, string title, int zone) { + int j,k; + s << "TITLE = \"" + title + "\"" << endl; + s << "VARIABLES = \"Z (m)\"" << endl; + s << "\"u (m/s)\"" << endl; + s << "\"V (1/s)\"" << endl; + s << "\"T (K)\"" << endl; + s << "\"lambda\"" << endl; + + for (k = 0; k < m_nsp; k++) { + s << "\"" << m_thermo->speciesName(k) << "\"" << endl; + } + s << "ZONE T=\"c" << zone << "\"" << endl; + s << " I=" << m_points << ",J=1,K=1,F=POINT" << endl; + s << "DT=(SINGLE SINGLE SINGLE SINGLE"; + for (k = 0; k < m_nsp; k++) s << " SINGLE"; + s << " )" << endl; + for (j = 0; j < m_points; j++) { + s << z(j) << " "; + for (k = 0; k < m_nv; k++) { + s << component(x, k, j) << " "; + } + s << endl; + } + } + + + string StFlow::componentName(int n) const { + switch(n) { + case 0: return "u [m/s]"; + case 1: return "V [1/s]"; + case 2: return "T [K]"; + case 3: return "lambda"; + default: + if (n >= (int) c_offset_Y && n < (int) (c_offset_Y + m_nsp)) { + if (m_do_species[n - c_offset_Y]) + return m_thermo->speciesName(n - c_offset_Y)+" "; + else + return m_thermo->speciesName(n - c_offset_Y)+" *"; + } + else + return ""; + } + } + + + /** + * Returns true if all necessary parameters have been set; otherwise it + * throws an exception. + */ + bool StFlow::ready() { + if (m_press < 0.0) { + throw CanteraError("StFlow::ready", + "pressure not specified - call setPressure"); + return false; + } + if (m_points == 0) { + throw CanteraError("StFlow::ready", + "grid not specified - call setupGrid"); + return false; + } + if (m_nsp < 0) { + throw CanteraError("StFlow::ready", + "fluid not specified - call specifyFluid"); + return false; + } + if (m_boundary[0] == 0 || m_boundary[1] == 0) { + throw CanteraError("StFlow::ready", + "boundaries not specified - call setBoundary"); + return false; + } + m_ok = true; + return m_ok; + } + + + void StFlow::restore(int job, + string fname, string id, int& size_z, doublereal* z, + int& size_soln, doublereal* soln) { + + vector ignored; + int nsp = m_thermo->nSpecies(); + vector_int did_species(nsp, 0); + + ifstream s(fname.c_str()); + if (!s) + throw CanteraError("StFlow::restore", + "could not open input file "+fname); + + XML_Node root; + root.build(s); + s.close(); + int k; + + XML_Node* f = root.findID(id); + if (!f) { + throw CanteraError("StFlow::restore","No solution with id = "+id); + } + + XML_Node& flow = f->child("flowfield"); + f = &flow; + + //if (f->name() != "flowfield") { + // throw CanteraError("StFlow::restore","The element with id " + // +id+" does not contain flowfield data."); + //} + + vector str; + f->getChildren("string",str); + int nstr = str.size(); + for (int istr = 0; istr < nstr; istr++) { + XML_Node& nd = *str[istr]; + writelog(nd["title"]+": "+nd.value()+"\n"); + } + + vector d; + f->child("grid_data").getChildren("floatArray",d); + int nd = d.size(); + + vector_fp x; + int n, np, j, ks; + string nm; + bool readgrid = false, wrote_header = false; + for (n = 0; n < nd; n++) { + XML_Node& fa = *d[n]; + nm = fa["title"]; + if (nm == "z") { + getFloatArray(fa,x,false); + np = x.size(); + if (job == -1) { + size_z = np; + //size_soln = (nd - 1)*np; + size_soln = (m_nsp + 4)*np; + return; + } + writelog("Grid contains "+int2str(np)+ + " points.\n"); + if (size_z < np) { + throw CanteraError("restore", + "grid array must be have length at least " + +int2str(np)); + } +// if (size_soln < (m_nsp + 4)*np) { +// throw CanteraError("restore", +// "solution array must have length at least " +// +int2str((m_nsp + 4)*np)); +// } + copy(x.begin(), x.end(), z); + readgrid = true; + } + } + if (!readgrid) { + throw CanteraError("StFlow::restore", + "solution contains no grid points."); + } + + cout << "importing...." << endl; + writelog("Importing datasets:\n"); + for (n = 0; n < nd; n++) { + XML_Node& fa = *d[n]; + nm = fa["title"]; + cout << "nm = " << nm << endl; + getFloatArray(fa,x,false); + if (nm == "u") { + writelog("axial velocity "); + if ((int) x.size() == np) { + for (j = 0; j < np; j++) { + cout << j << " " << x[j] << " " << np << endl; + cout << index(0,j) << " " << size_soln << endl; + soln[index(0,j)] = x[j]; + } + } + else { + cout << "error..." << endl; + goto error; + } + } + else if (nm == "z") { + ; + } + else if (nm == "V") { + writelog("radial velocity "); + if ((int) x.size() == np) { + for (j = 0; j < np; j++) + soln[index(1,j)] = x[j]; + } + else goto error; + } + else if (nm == "T") { + writelog("temperature "); + if ((int) x.size() == np) { + for (j = 0; j < np; j++) + soln[index(2,j)] = x[j]; + } + else goto error; + } + else if (nm == "L") { + writelog("lambda "); + if ((int) x.size() == np) { + for (j = 0; j < np; j++) + soln[index(3,j)] = x[j]; + } + else goto error; + } + else if (m_thermo->speciesIndex(nm) >= 0) { + writelog(nm+" "); + if ((int) x.size() == np) { + k = m_thermo->speciesIndex(nm); + did_species[k] = 1; + for (j = 0; j < np; j++) + soln[index(k+4,j)] = x[j]; + } + } + else + ignored.push_back(nm); + } + + if (ignored.size() != 0) { + writelog("\n\n"); + writelog("Ignoring datasets:\n"); + int nn = ignored.size(); + for (int n = 0; n < nn; n++) { + writelog(ignored[n]+" "); + } + } + + for (ks = 0; ks < nsp; ks++) { + if (did_species[ks] == 0) { + if (!wrote_header) { + writelog("Missing data for species:\n"); + wrote_header = true; + } + writelog(m_thermo->speciesName(ks)+" "); + } + } + + writelog("\n\nFinished importing solution.\n\n"); + return; + error: + throw CanteraError("StFlow::restore","Data size error"); + } + + + void StFlow::save(string fname, string id, string desc, doublereal* sol) { + int k; + + struct tm *newtime; + time_t aclock; + ::time( &aclock ); /* Get time in seconds */ + newtime = localtime( &aclock ); /* Convert time to struct tm form */ + + ArrayViewer soln(m_nv, m_points, sol); + + XML_Node root("doc"); + ifstream fin(fname.c_str()); + XML_Node* ct; + if (fin) { + root.build(fin); + XML_Node* same_ID = root.findID(id); + int jid = 1; + string idnew = id; + while (same_ID != 0) { + idnew = id + "_" + int2str(jid); + jid++; + same_ID = root.findID(idnew); + } + id = idnew; + fin.close(); + ct = &root.child("ctml"); + } + else { + ct = &root.addChild("ctml"); + } + + XML_Node& flow = (XML_Node&)ct->addChild("flowfield"); + flow.addAttribute("type",flowType()); + flow.addAttribute("id",id); + addString(flow,"timestamp",asctime(newtime)); + addFloat(flow, "pressure", m_press, "Pa", "pressure"); + addString(flow,"solve_time",fp2str(m_container->solveTime())); + if (desc != "") addString(flow,"description",desc); + XML_Node& gv = flow.addChild("grid_data"); + addFloatArray(gv,"z",m_z.size(),m_z.begin(), + "m","length"); + vector_fp x(soln.nColumns()); + + soln.getRow(0,x.begin()); + addFloatArray(gv,"u",x.size(),x.begin(),"m/s","velocity"); + + soln.getRow(1,x.begin()); + addFloatArray(gv,"V", + x.size(),x.begin(),"1/s","strainrate"); + + soln.getRow(2,x.begin()); + addFloatArray(gv,"T",x.size(),x.begin(),"K","temperature",0.0); + + soln.getRow(3,x.begin()); + addFloatArray(gv,"L",x.size(),x.begin(),"N/m^4"); + + for (k = 0; k < m_nsp; k++) { + soln.getRow(4+k,x.begin()); + addFloatArray(gv,m_thermo->speciesName(k), + x.size(),x.begin(),"","massFraction",0.0,1.0); + } + +// XML_Node& inlt = flow.addChild("inlet"); +// addFloat(inlt,"T",m_inlet_T,"K","temperature",0.0); +// addFloat(inlt,"P",m_press,"Pa","pressure",0.0); +// for (k = 0; k < m_nsp; k++) { +// if (m_yin[k] != 0.0) +// addFloat(inlt, m_thermo->speciesName(k), m_yin[k], +// "", "massFraction",0.0,1.0); +// } + + ofstream s(fname.c_str()); + if (!s) + throw CanteraError("save","could not open file "+fname); + ct->writeHeader(s); + ct->write(s); + s.close(); + writelog("Solution saved to file "+fname+" as solution '"+id+"'.\n"); + m_container->writeStats(); + } + + + void StFlow::save(XML_Node& o, doublereal* sol) { + int k; + + ArrayViewer soln(m_nv, m_points, sol + loc()); + + XML_Node& flow = (XML_Node&)o.addChild("flowfield"); + flow.addAttribute("type",flowType()); + flow.addAttribute("id",m_id); + if (m_desc != "") addString(flow,"description",m_desc); + XML_Node& gv = flow.addChild("grid_data"); + addFloat(flow, "pressure", m_press, "Pa", "pressure"); + addFloatArray(gv,"z",m_z.size(),m_z.begin(), + "m","length"); + vector_fp x(soln.nColumns()); + + soln.getRow(0,x.begin()); + addFloatArray(gv,"u",x.size(),x.begin(),"m/s","velocity"); + + soln.getRow(1,x.begin()); + addFloatArray(gv,"V", + x.size(),x.begin(),"1/s","rate"); + + soln.getRow(2,x.begin()); + addFloatArray(gv,"T",x.size(),x.begin(),"K","temperature",0.0); + + soln.getRow(3,x.begin()); + addFloatArray(gv,"L",x.size(),x.begin(),"N/m^4"); + + for (k = 0; k < m_nsp; k++) { + soln.getRow(4+k,x.begin()); + addFloatArray(gv,m_thermo->speciesName(k), + x.size(),x.begin(),"","massFraction",0.0,1.0); + } + } + + + void StFlow::setJac(MultiJac* jac) { + m_jac = jac; + } + + void StFlow::requestJacUpdate() { + if (m_jac) m_jac->setAge(10000); + } + + void StFlow::setEnergyFactor(doublereal efctr) { + doublereal de = efctr - m_efctr; + m_efctr = efctr; + int strt = loc(); + int jg; + for (int j = 1; j < m_points - 1; j++) { + jg = strt + index(c_offset_T, j); + m_jac->incrementDiagonal(jg, -de); + } + } + + +} diff --git a/Cantera/src/oneD/StFlow.h b/Cantera/src/oneD/StFlow.h new file mode 100644 index 000000000..a1204a1b9 --- /dev/null +++ b/Cantera/src/oneD/StFlow.h @@ -0,0 +1,466 @@ +/** + * @file StFlow.h + * + */ + +/* + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + +#ifndef CT_STFLOW_H +#define CT_STFLOW_H + +#include "../transport/TransportBase.h" +//#include "IdealGasMix.h" +#include "Resid1D.h" +//#include "../ChemEquil.h" +#include "../Array.h" +#include "../sort.h" +//#include "ImplicitChem.h" +#include "../IdealGasPhase.h" +#include "../Kinetics.h" + +#include "../flowBoundaries.h" + +namespace Cantera { + + typedef IdealGasPhase igthermo_t; + + class MultiJac; + + //------------------------------------------ + // constants + //------------------------------------------ + + /** + * Offsets of solution components in the solution array. + */ + const unsigned int c_offset_U = 0; // axial velocity + const unsigned int c_offset_V = 1; // strain rate + const unsigned int c_offset_T = 2; // temperature + const unsigned int c_offset_L = 3; // (1/r)dP/dr + const unsigned int c_offset_Y = 4; // mass fractions + + // Transport option flags + const int c_Mixav_Transport = 0; + const int c_Multi_Transport = 1; + const int c_Soret = 2; + + + + //----------------------------------------------------------- + // Class StFlow + //----------------------------------------------------------- + + + /** + * A class for one-dimensional reacting stagnation-point + * flows. This class implements the one-dimensional similarity + * solution for a chemically-reacting, axisymmetric, + * stagnation-point flow. + */ + class StFlow : public Resid1D { + + public: + + //-------------------------------- + // construction and destruction + //-------------------------------- + + // Constructor. + StFlow(igthermo_t* ph = 0, int nsp = 1, int points = 1); + + /// Destructor. + virtual ~StFlow(){} + + /** + * @name Problem Specification + */ + //@{ + + void setupGrid(int n, const doublereal* z); + + //thermo_t& phase() { return *m_phase; } + thermo_t& phase() { return *m_thermo; } + kinetics_t& kinetics() { return *m_kin; } + + /** + * Set the thermo manager. Note that the flow equations + * assume the ideal gas equation. + */ + void setThermo(igthermo_t& th) { + m_thermo = &th; + //m_phase = &th.phase(); + } + + /// set the kinetics manager + void setKinetics(kinetics_t& kin) { m_kin = &kin; } + + /// set the transport manager + void setTransport(Transport& trans, bool withSoret = false); + + /// set the pressure + void setPressure(doublereal p) { + m_press = p; + } + + /// Check that all required parameters have been set. + bool ready(); + + /** + * Set the temperature fixed point at grid point j, and + * disable the energy equation so that the solution will be + * held to this value. + */ + void setTemperature(int j, doublereal t) { + m_fixedtemp[j] = t; + m_do_energy[j] = false; + } + + /** + * Set the mass fraction fixed point for species k at grid + * point j, and disable the species equation so that the + * solution will be held to this value. + */ + void setMassFraction(int j, int k, doublereal y) { + m_fixedy(k,j) = y; + m_do_species[k] = false; + } + + doublereal T_fixed(int j) const {return m_fixedtemp[j];} + doublereal Y_fixed(int k, int j) const {return m_fixedy(k,j);} + + virtual string componentName(int n) const; + + /** + * Write a Tecplot zone corresponding to the current solution. + * May be called multiple times to generate animation. + */ + void outputTEC(ostream &s, const doublereal* x, + string title, int zone); + + void showSolution(ostream& s, const doublereal* x); + + void save(string fname, string id, string desc, doublereal* soln); + virtual void save(XML_Node& o, doublereal* sol); + + void restore(int job, string fname, string id, int& size_z, + doublereal* z, int& size_soln, doublereal* soln); + + + // overloaded in subclasses + virtual string flowType() { return ""; } + + void solveEnergyEqn(int j=-1) { + if (j < 0) + for (int i = 0; i < m_points; i++) + m_do_energy[i] = true; + else + m_do_energy[j] = true; + requestJacUpdate(); + } + + void fixTemperature(int j=-1) { + if (j < 0) + for (int i = 0; i < m_points; i++) { + m_do_energy[i] = false; + } + else m_do_energy[j] = false; + requestJacUpdate(); + } + + bool doSpecies(int k) { return m_do_species[k]; } + bool doEnergy(int j) { return m_do_energy[j]; } + + void solveSpecies(int k=-1) { + if (k == -1) { + for (int i = 0; i < m_nsp; i++) + m_do_species[i] = true; + } + else m_do_species[k] = true; + requestJacUpdate(); + } + + void setEnergyFactor(doublereal efctr); + + void fixSpecies(int k=-1) { + if (k == -1) { + for (int i = 0; i < m_nsp; i++) + m_do_species[i] = false; + } + else m_do_species[k] = false; + requestJacUpdate(); + //m_jac->setAge(10000); + } + + void integrateChem(doublereal* x,doublereal dt); + + doublereal z(int j) const {return m_z[j];} + doublereal zmin() const { return m_z[0]; } + doublereal zmax() const { return m_z[m_points - 1]; } + + void resize(int points); + virtual void setFixedPoint(int j0, doublereal t0){} + + + virtual void setBoundaries(FlowBdry::Boundary* left, + FlowBdry::Boundary* right) { + if (left) { + m_boundary[0] = left; + left->faceRight(); + } + if (right) { + m_boundary[1] = right; + right->faceLeft(); + } + } + + void setJac(MultiJac* jac); + void setGas(const doublereal* x,int j); + void setGasAtMidpoint(const doublereal* x,int j); + + + protected: + + // used to write mole fractions to plot files. + + doublereal component(const doublereal* x, int i, int j) const { + doublereal xx = x[index(i,j)]; + //if (i >= 4) { + // return xx*m_wtm[j]/m_wt[i-4]; + //} + //else return xx; + return xx; + } + + doublereal conc(const doublereal* x,int k,int j) const { + return Y(x,k,j)*density(j)/m_wt[k]; + } + + doublereal cbar(const doublereal* x,int k, int j) const { + return sqrt(8.0*GasConstant * T(x,j) / (Pi * m_wt[k])); + } + + doublereal wdot(int k, int j) const {return m_wdot(k,j);} + + void getWdot(doublereal* x,int j) { + setGas(x,j); + m_kin->getNetProductionRates(&m_wdot(0,j)); + } + + void updateThermo(const doublereal* x, int j0, int j1) { + int j; + for (j = j0; j <= j1; j++) { + setGas(x,j); + m_rho[j] = m_thermo->density(); + m_wtm[j] = m_thermo->meanMolecularWeight(); + m_cp[j] = m_thermo->cp_mass(); + } + } + + //-------------------------------- + // central-differenced derivatives + //-------------------------------- + + doublereal cdif2(const doublereal* x, int n, int j, + const doublereal* f) const { + doublereal c1 = (f[j] + f[j-1])*(x[index(n,j)] - x[index(n,j-1)]); + doublereal c2 = (f[j+1] + f[j])*(x[index(n,j+1)] - x[index(n,j)]); + return (c2/(z(j+1) - z(j)) - c1/(z(j) - z(j-1)))/(z(j+1) - z(j-1)); + } + + + //-------------------------------- + // solution components + //-------------------------------- + + + doublereal T(const doublereal* x,int j) const { + return x[index(c_offset_T, j)]; + } + doublereal& T(doublereal* x,int j) {return x[index(c_offset_T, j)];} + doublereal T_prev(int j) const {return prevSoln(c_offset_T, j);} + + doublereal rho_u(const doublereal* x,int j) const { + return m_rho[j]*x[index(c_offset_U, j)];} + + doublereal u(const doublereal* x,int j) const { + return x[index(c_offset_U, j)];} + + doublereal V(const doublereal* x,int j) const { + return x[index(c_offset_V, j)];} + doublereal V_prev(int j) const { + return prevSoln(c_offset_V, j);} + + doublereal lambda(const doublereal* x,int j) const { + return x[index(c_offset_L, j)]; + } + + doublereal Y(const doublereal* x,int k, int j) const { + return x[index(c_offset_Y + k, j)]; + } + + doublereal& Y(doublereal* x,int k, int j) { + return x[index(c_offset_Y + k, j)]; + } + + doublereal Y_prev(int k, int j) const { + return prevSoln(c_offset_Y + k, j); + } + + doublereal X(const doublereal* x,int k, int j) const { + return m_wtm[j]*Y(x,k,j)/m_wt[k]; + } + + doublereal density(int j) const { + return m_rho[j]; + } + + doublereal flux(int k, int j) const { + return m_flux(k, j); + } + + + // convective spatial derivatives. These use upwind + // differencing, assuming u(z) is negative + + doublereal dVdz(const doublereal* x,int j) const { + //return (V(x,j+1) - V(x,j-1))/(m_dz[j] + m_dz[j-1]); + return (V(x,j) - V(x,j-1))/m_dz[j-1]; + } + + doublereal dYdz(const doublereal* x,int k, int j) const { + //return (Y(x,k,j+1) - Y(x,k,j))/m_dz[j]; + return (Y(x,k,j) - Y(x,k,j-1))/m_dz[j-1]; + } + + doublereal dTdz(const doublereal* x,int j) const { + // return (T(x,j+1) - T(x,j))/m_dz[j]; + return (T(x,j) - T(x,j-1))/m_dz[j-1]; + } + + doublereal shear(const doublereal* x,int j) const { + doublereal c1 = m_visc[j-1]*(V(x,j) - V(x,j-1)); + doublereal c2 = m_visc[j]*(V(x,j+1) - V(x,j)); + return 2.0*(c2/(z(j+1) - z(j)) - c1/(z(j) - z(j-1)))/(z(j+1) - z(j-1)); + } + + doublereal divHeatFlux(const doublereal* x, int j) const { + doublereal c1 = m_tcon[j-1]*(T(x,j) - T(x,j-1)); + doublereal c2 = m_tcon[j]*(T(x,j+1) - T(x,j)); + return -2.0*(c2/(z(j+1) - z(j)) - c1/(z(j) - z(j-1)))/(z(j+1) - z(j-1)); + } + + void updateDiffFluxes(const doublereal* x, int j0, int j1); + + // inlet + doublereal m_inlet_u; + doublereal m_inlet_V; + doublereal m_inlet_T; + doublereal m_rho_inlet; + vector_fp m_yin; + + // surface + doublereal m_surface_T; + + doublereal m_press; // pressure + + vector_fp m_dz; + vector_fp m_z; + + // mixture thermo properties + vector_fp m_rho; + vector_fp m_wtm; + + // species thermo properties + vector_fp m_wt; + vector_fp m_cp; + vector_fp m_enth; + + // transport properties + vector_fp m_visc; + vector_fp m_tcon; + Array2D m_diff; + Array2D m_flux; + + // production rates + Array2D m_wdot; + vector_fp m_surfdot; + + int m_nsp; + + //IdealGasMix* m_fluid; + //thermo_t* m_phase; + igthermo_t* m_thermo; + kinetics_t* m_kin; + Transport* m_trans; + //ImplicitChem* m_integrator; + + MultiJac* m_jac; + + bool m_ok; + + // flags + vector m_do_energy; + bool m_do_soret; + vector m_do_species; + int m_transport_option; + + vector_fp m_zest; + Array2D m_yest; + Array2D m_fixedy; + vector_fp m_fixedtemp; + vector_fp m_zfix; + vector_fp m_tfix; + + vector m_boundary; + doublereal m_efctr; + + private: + + void requestJacUpdate(); + vector_fp m_ybar; + }; + + + class AxiStagnFlow : public StFlow { + public: + AxiStagnFlow(igthermo_t* ph = 0, int nsp = 1, int points = 1) : + StFlow(ph, nsp, points) { + } + virtual ~AxiStagnFlow() {} + virtual void eval(int j, doublereal* x, doublereal* r, + integer* mask, doublereal rdt); + virtual string flowType() { return "Axisymmetric Stagnation"; } + private: + void updateTransport(doublereal* x,int j0, int j1); + }; + + + class OneDFlow : public StFlow { + public: + OneDFlow(igthermo_t* ph = 0, int nsp = 1, int points = 1) : + StFlow(ph, nsp, points) { + } + virtual ~OneDFlow() {} + virtual void eval(int j, doublereal* x, doublereal* r, + integer* mask, doublereal rdt); + virtual string flowType() { return "OneDFlow"; } + doublereal mdot(doublereal* x, int j) { + return x[index(c_offset_L,j)]; + } + + private: + void updateTransport(doublereal* x,int j0, int j1); + }; + + void importSolution(doublereal* oldSoln, igthermo_t& oldmech, + doublereal* newSoln, igthermo_t& newmech); + +} + +#endif diff --git a/Cantera/src/oneD/Surf1D.h b/Cantera/src/oneD/Surf1D.h new file mode 100644 index 000000000..a2feb1400 --- /dev/null +++ b/Cantera/src/oneD/Surf1D.h @@ -0,0 +1,310 @@ +dep + +#ifndef CT_SURF1D_H +#define CT_SURF1D_H + +#include "Resid1D.h" +#include "SurfPhase.h" +#include "InterfaceKinetics.h" +#include "StFlow.h" +#include "OneDim.h" +#include "ctml.h" + +namespace Cantera { + + // A class for surface domains in one-dimensional simulations, The + // surface is zero-dimensional, and defined by a set of surface + // species coverages. + + class Surf1D : public Resid1D { + + public: + + Surf1D(InterfaceKinetics* skin = 0) : Resid1D(1, 1, 0.0) { + m_type = cSurfType; + m_flow_left = 0; + m_flow_right = 0; + m_kin = 0; + m_sphase = 0; + if (skin) setKinetics(skin); + } + virtual ~Surf1D(){} + + // Set the kinetics manager for the surface. + void setKinetics(InterfaceKinetics* kin) { + m_kin = kin; + int np = kin->nPhases(); + m_sphase = 0; + for (int n = 0; n < np; n++) { + if (kin->phase(n).eosType() == cSurf) { + m_sphase = (SurfPhase*)&m_kin->phase(n); + m_nsurf = n; + } + else { + m_bulk.push_back(&kin->phase(n)); + m_nbulk.push_back(n); + } + } + if (!m_sphase) + throw CanteraError("setKinetics","no surface phase defined"); + + m_nsp = m_sphase->nSpecies(); + resize(m_nsp,1); + if (m_bulk.size() == 1) { + m_bulk.push_back(0); + } + } + + void fixSpecies(int k, doublereal c) { + if (c >= 0.0) m_fixed_cov[k] = c; + m_do_surf_species[k] = false; + needJacUpdate(); + } + + void solveSpecies(int k) { + m_do_surf_species[k] = true; + needJacUpdate(); + } + + /// Set the surface temperature + void setTemperature(doublereal t) { + m_sphase->setTemperature(t); + needJacUpdate(); + } + + /// Temperature [K]. + doublereal temperature() { + return m_sphase->temperature(); + } + + void setCoverages(doublereal* c) { + m_sphase->setCoverages(c); + copy(c, c + m_nsp, m_fixed_cov.begin()); + } + + void setMultiplier(int k, doublereal f) { + m_mult[k] = f; + needJacUpdate(); + } + + doublereal multiplier(int k) { return m_mult[k]; } + + virtual string componentName(int n) const { + return m_sphase->speciesName(n); + } + + virtual void init() { + if (m_index < 0) { + throw CanteraError("Surf1D", + "install in container before calling init."); + } + m_nsp = m_sphase->nSpecies(); + resize(m_nsp,1); + m_mult.resize(m_nsp, 1.0); + m_do_surf_species.resize(m_nsp, true); + m_fixed_cov.resize(m_nsp, 1.0/m_nsp); + + // set bounds + vector_fp lower(m_nsp, -1.e-3); + vector_fp upper(m_nsp, 1.0); + setBounds(m_nsp, lower.begin(), m_nsp, upper.begin()); + + // set tolerances + vector_fp rtol(m_nsp, 1e-4); + vector_fp atol(m_nsp, 1.e-10); + setTolerances(m_nsp, rtol.begin(), m_nsp, atol.begin()); + + m_left_nsp = 0; + m_right_nsp = 0; + + // check for left and right flow objects + if (m_index > 0) { + Resid1D& r = container().domain(m_index-1); + if (r.domainType() == cFlowType) { + m_flow_left = (StFlow*)&r; + m_left_nv = m_flow_left->nComponents(); + m_left_points = m_flow_left->nPoints(); + m_left_loc = container().start(m_index-1); + m_left_nsp = m_left_nv - 4; + m_phase_left = &m_flow_left->phase(); + m_molwt_left = m_phase_left->molecularWeights().begin(); + if (m_phase_left == m_bulk[0]) + m_start_left = m_kin->start(m_nbulk[0]); + else if (m_phase_left == m_bulk[1]) + m_start_left = m_kin->start(m_nbulk[1]); + else + throw CanteraError("Surf1D::init", + "left gas does not match one in surface mechanism"); + } + else + throw CanteraError("Surf1D::init", + "Surface domains can only be " + "connected to flow domains."); + } + + if (m_index < container().nDomains() - 1) { + Resid1D& r = container().domain(m_index+1); + if (r.domainType() == cFlowType) { + m_flow_right = (StFlow*)&r; + m_right_nv = m_flow_right->nComponents(); + m_right_loc = container().start(m_index+1); + m_right_nsp = m_right_nv - 4; + m_phase_right = &m_flow_right->phase(); + m_molwt_right = m_phase_right->molecularWeights().begin(); + if (m_phase_right == m_bulk[0]) + m_start_right = m_kin->start(m_nbulk[0]); + else if (m_phase_right == m_bulk[1]) + m_start_right = m_kin->start(m_nbulk[1]); + else + throw CanteraError("Surf1D::init", + "right gas does not match one in surface mechanism"); + } + else + throw CanteraError("Surf1D::init", + "Surface domains can only be " + "connected to flow domains."); + } + m_work.resize(m_kin->nSpecies()); + } + + + virtual void eval(int jg, doublereal* xg, doublereal* rg, + integer* diagg, doublereal rdt) { + int k; + + if (jg >= 0 && (jg < firstPoint() - 2 + || jg > lastPoint() + 2)) return; + + // start of local part of global arrays + doublereal* x = xg + loc(); + doublereal* r = rg + loc(); + integer* diag = diagg + loc(); + + // set the coverages + doublereal sum = 0.0; + for (k = 0; k < m_nsp; k++) { + m_work[k] = x[k]; + sum += x[k]; + } + m_sphase->setCoverages(m_work.begin()); + + // set the left gas state to the adjacent point + + int leftloc = 0, rightloc = 0; + int pnt = 0; + + if (m_flow_left) { + leftloc = m_flow_left->loc(); + pnt = m_flow_left->nPoints() - 1; + m_flow_left->setGas(xg + leftloc, pnt); + } + + if (m_flow_right) { + rightloc = m_flow_right->loc(); + m_flow_right->setGas(xg + rightloc, 0); + } + + m_kin->getNetProductionRates(m_work.begin()); + doublereal rs0 = 1.0/m_sphase->siteDensity(); + + scale(m_work.begin(), m_work.end(), m_work.begin(), m_mult[0]); + + bool enabled = true; + int ioffset = m_kin->start(m_nsurf); // m_left_nsp + m_right_nsp; + doublereal maxx = -1.0; + int imx = -1; + for (k = 0; k < m_nsp; k++) { + r[k] = m_work[k + ioffset] * m_sphase->size(k) * rs0; + r[k] -= rdt*(x[k] - prevSoln(k,0)); + diag[k] = 1; + if (x[k] > maxx) { + maxx = x[k]; + imx = k; + } + if (!m_do_surf_species[k]) { + r[k] = x[k] - m_fixed_cov[k]; + diag[k] = 0; + enabled = false; + } + } + if (enabled) { + r[imx] = 1.0 - sum; + diag[imx] = 0; + } + + // gas-phase residuals + doublereal rho; + if (m_flow_left) { + rho = m_phase_left->density(); + doublereal rdz = 2.0/ + (m_flow_left->z(m_left_points-1) - + m_flow_left->z(m_left_points - 2)); + + for (k = 0; k < m_left_nsp; k++) + m_work[k + m_start_left] *= m_molwt_left[k]; + + int ileft = loc() - m_left_nv; + + // if the energy equation is enabled at this point, + // set the gas temperature to the surface temperature + if (m_flow_left->doEnergy(pnt)) { + rg[ileft + 2] = xg[ileft + 2] - m_sphase->temperature(); + } + + for (k = 1; k < m_left_nsp; k++) { + if (enabled && m_flow_left->doSpecies(k)) { + rg[ileft + 4 + k] += m_work[k + m_start_left]; +//+= rdz*m_work[k + m_sp_left]/rho; + + } + } + } + + if (m_flow_right) { + for (k = 0; k < m_right_nsp; k++) + m_work[k + m_start_right] *= m_molwt_right[k]; + + int iright = loc() + m_nsp; + rg[iright + 2] -= m_sphase->temperature(); + //r[iright + 3] = x[iright]; + for (k = 0; k < m_right_nsp; k++) { + rg[iright + 4 + k] -= m_work[k + m_start_right]; + } + } + } + + virtual void save(XML_Node& o, doublereal* soln) { + doublereal* s = soln + loc(); + XML_Node& surf = o.addChild("surface"); + for (int k = 0; k < m_nsp; k++) { + ctml::addFloat(surf, componentName(k), s[k], "", "coverage", + 0.0, 1.0); + } + } + + + protected: + + InterfaceKinetics* m_kin; + SurfPhase* m_sphase; + StFlow *m_flow_left, *m_flow_right; + int m_left_nv, m_right_nv; + int m_left_loc, m_right_loc; + int m_left_points; + int m_nsp, m_left_nsp, m_right_nsp; + vector_fp m_work; + const doublereal *m_molwt_right, *m_molwt_left; + int m_sp_left, m_sp_right; + int m_start_left, m_start_right, m_start_surf; + ThermoPhase *m_phase_left, *m_phase_right; + vector m_bulk; + vector m_nbulk; + int m_nsurf; + vector_fp m_mult; + vector m_do_surf_species; + vector_fp m_fixed_cov; + }; + +} + +#endif diff --git a/Cantera/src/oneD/newton_utils.cpp b/Cantera/src/oneD/newton_utils.cpp new file mode 100644 index 000000000..775e65637 --- /dev/null +++ b/Cantera/src/oneD/newton_utils.cpp @@ -0,0 +1,100 @@ +/** + * @file newton_utils.cpp + */ + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "../ct_defs.h" +#include "Resid1D.h" + +namespace Cantera { + + class Indx { + public: + Indx(int nv, int np) : m_nv(nv), m_np(np) {} + int m_nv, m_np; + int operator()(int m, int j) { return j*m_nv + m; } + }; + + + doublereal bound_step(const doublereal* x, const doublereal* step, + Resid1D& r, int loglevel=0) { + + char buf[100]; + int np = r.nPoints(); + int nv = r.nComponents(); + Indx index(nv, np); + doublereal above, below, val, newval; + int m, j; + doublereal fbound = 1.0; + bool wroteTitle = false; + for (m = 0; m < nv; m++) { + above = r.upperBound(m); + below = r.lowerBound(m); + + for (j = 0; j < np; j++) { + val = x[index(m,j)]; + if (loglevel > 0) { + if (val > above + Tiny || val < below - Tiny) + cout << "ERROR: solution out of bounds. " + << r.componentName(m) << "(" << j << ") = " << val + << " (" << below << ", " << above << ")" << endl; + } + + newval = val + step[index(m,j)]; + + if (newval > above) { + fbound = fmaxx( 0.0, fminn( fbound, + (above - val)/(newval - val))); + } + else if (newval < below) { + fbound = fminn(fbound, (val - below)/(val - newval)); + } + + if (loglevel > 1 && (newval > above || newval < below)) { + if (!wroteTitle) { + writelog("\nNewton step takes solution out of bounds.\n\n"); + sprintf(buf," %12s %4s %10s %10s %10s %10s\n", + "component","pt","value","step","min","max"); + wroteTitle = true; + writelog(buf); + } + sprintf(buf, " %12s %4i %10.3e %10.3e %10.3e %10.3e\n", + r.componentName(m).c_str(), j, val, + step[index(m,j)], below, above); + writelog(buf); + } + } + } + return fbound; + } + + + doublereal norm_square(const doublereal* x, + const doublereal* step, Resid1D& r) { + doublereal f, ewt, esum, sum = 0.0; + int n, j; + + int nv = r.nComponents(); + int np = r.nPoints(); + + for (n = 0; n < nv; n++) { + esum = 0.0; + for (j = 0; j < np; j++) esum += fabs(x[nv*j + n]); + ewt = r.rtol(n)*esum/np + r.atol(n); + for (j = 0; j < np; j++) { + f = step[nv*j + n]/ewt; + sum += f*f; +// if (fabs(f) > fmx) { +// fmx = fabs(f); +// jmx = j; +// nmx = n; +// } + } + } + return sum; + } +} diff --git a/Cantera/src/plots.cpp b/Cantera/src/plots.cpp new file mode 100755 index 000000000..cb30e81b3 --- /dev/null +++ b/Cantera/src/plots.cpp @@ -0,0 +1,103 @@ +/** + * @file plots.cpp + */ + +/* + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2002 California Institute of Technology + + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "plots.h" + +namespace Cantera { + + void writePlotFile(string fname, string fmt, + string plotTitle, const vector names, const Array2D& data) { + ofstream f(fname.c_str()); + if (!f) { + throw CanteraError("writePlotFile","could not open file "+fname+ + " for writing."); + } + if (fmt == "TEC") { + outputTEC(f, plotTitle, names, data); + f.close(); + } + else if (fmt == "XL") { + outputExcel(f, plotTitle, names, data); + f.close(); + } + else { + throw CanteraError("writePlotFile", + "unsupported plot type:" + fmt); + } + } + + + /** + * Write a Tecplot data file. + * @param s output stream + * @param title plot title + * @param names vector of variable names + * @param data N x M data array. + * data(n,m) is the m^th value of the n^th variable. + */ + void outputTEC(ostream &s, string title, const vector& names, + const Array2D& data) { + int i,j; + int npts = data.nColumns(); + int nv = data.nRows(); + s << "TITLE = \"" + title + "\"" << endl; + s << "VARIABLES = " << endl; + for (i = 0; i < nv; i++) { + s << "\"" << names[i] << "\"" << endl; + } + s << "ZONE T=\"zone1\"" << endl; + s << " I=" << npts << ",J=1,K=1,F=POINT" << endl; + s << "DT=( "; + for (i = 0; i < nv; i++) s << " SINGLE"; + s << " )" << endl; + for (i = 0; i < npts; i++) { + for (j = 0; j < nv; j++) { + s << data(j,i) << " "; + } + s << endl; + } + } + + + /** + * Write an Excel spreadsheet in 'csv' form. + * @param s output stream + * @param title plot title + * @param names vector of variable names @param data N + * x M data array. data(n,m) is the m^th value of the n^th variable. + */ + void outputExcel(ostream &s, string title, const vector& names, + const Array2D& data) { + int i,j; + int npts = data.nColumns(); + int nv = data.nRows(); + s << title + "," << endl; + for (i = 0; i < nv; i++) { + s << names[i] << ","; + } + s << endl; + for (i = 0; i < npts; i++) { + for (j = 0; j < nv; j++) { + s << data(j,i) << ","; + } + s << endl; + } + } + + +} diff --git a/Cantera/src/plots.h b/Cantera/src/plots.h new file mode 100755 index 000000000..abe01cdca --- /dev/null +++ b/Cantera/src/plots.h @@ -0,0 +1,25 @@ + +#ifndef CT_PLOTS_H +#define CT_PLOTS_H + +#include +#include +#include +using namespace std; + +#include "Array.h" +#include "ctexceptions.h" + +namespace Cantera { + + void writePlotFile(string fname, string fmt, + string plotTitle, const vector names, const Array2D& data); + + void outputTEC(ostream &s, string title, const vector& names, + const Array2D& data); + + void outputExcel(ostream &s, string title, const vector& names, + const Array2D& data); +} + +#endif diff --git a/Cantera/src/polyfit.h b/Cantera/src/polyfit.h new file mode 100755 index 000000000..225ec8a33 --- /dev/null +++ b/Cantera/src/polyfit.h @@ -0,0 +1,55 @@ + +/* C interface for Fortran DPOLFT subroutine */ + +#ifndef CT_POLYFIT_H +#define CT_POLYFIT_H + +#include +using namespace std; + +#include "ct_defs.h" + +namespace Cantera { + + doublereal polyfit(int n, doublereal* x, doublereal* y, doublereal* w, + int maxdeg, int& ndeg, doublereal eps, doublereal* r); + + template + R poly6(D x, R* c) { + return ((((((c[6]*x + c[5])*x + c[4])*x + c[3])*x + + c[2])*x + c[1])*x + c[0]); + } + + template + R poly8(D x, R* c) { + return ((((((((c[8]*x + c[7])*x + c[6])*x + c[5])*x + c[4])*x + c[3])*x + + c[2])*x + c[1])*x + c[0]); + } + + template + R poly10(D x, R* c) { + return ((((((((((c[10]*x + c[9])*x + c[8])*x + c[7])*x + + c[6])*x + c[5])*x + c[4])*x + c[3])*x + + c[2])*x + c[1])*x + c[0]); + } + + template + R poly5(D x, R* c) { + return (((((c[5]*x + c[4])*x + c[3])*x + + c[2])*x + c[1])*x + c[0]); + } + + template + R poly4(D x, R* c) { + return ((((c[4]*x + c[3])*x + + c[2])*x + c[1])*x + c[0]); + } + + template + R poly3(D x, R* c) { + return (((c[3]*x + c[2])*x + c[1])*x + c[0]); + } +} +#endif + + diff --git a/Cantera/src/pureSubstances.h b/Cantera/src/pureSubstances.h new file mode 100755 index 000000000..509bed469 --- /dev/null +++ b/Cantera/src/pureSubstances.h @@ -0,0 +1,138 @@ + +#ifndef CT_PURESUBS_H +#define CT_PURESUBS_H + +#include "ct_defs.h" +#include "Phase.h" +#include "EOS_TPX.h" +#include "SpeciesThermoMgr.h" + +namespace Cantera { + + static double h0[5] = { + -2.8583e8, + 0.0, + -7.4850e7, + 0.0, + 0.0 + }; + + static double s0[5] = { + 6.995e4, + 1.915e5, + 1.8616e5, + 1.3057e5, + 2.0503e5 +}; + + const int Pure_Water = 0, + Pure_Nitrogen = 1, + Pure_Methane = 2, + Pure_Hydrogen = 3, + Pure_Oxygen = 4; + + class PureSubError { + public: + PureSubError(int i) { + cerr << "**** ERROR: unknown pure substance flag (" + << i << ")" << endl; + } + }; + + + /** + * Pure substances based on TPX substance models. + */ + class PureSubstance : public Mixture { + public: + PureSubstance(int sub) { + EOS_TPX* eos = new EOS_TPX(sub, h0[sub], s0[sub]); + setEquationOfState(eos); + setSpeciesThermo(new NoSpeciesThermo()); + m_tmin = eos->Tmin(); + m_tmax = eos->Tmax(); + } + protected: + }; + + + static PureSubstance* newNitrogen() { + PureSubstance* n2 = new PureSubstance(Pure_Nitrogen); + n2->addUniqueElement("N"); + vector_fp comp; + comp.push_back(2.0); + vector_fp coeff; + n2->addSpecies("N2", PURE_FLUID, comp, 0, coeff); + n2->freezeSpecies(); + n2->setState_TP(298.15, 1.01325e5); + return n2; + } + + + static PureSubstance* newWater() { + PureSubstance* sub = new PureSubstance(Pure_Water); + sub->addUniqueElement("H"); + sub->addUniqueElement("O"); + vector_fp comp; + comp.push_back(2.0); + comp.push_back(1.0); + vector_fp coeff; + sub->addSpecies("H2O", PURE_FLUID, comp, 0, coeff); + sub->freezeSpecies(); + sub->setState_TP(298.15, 1.01325e5); + return sub; + } + + + static PureSubstance* newMethane() { + PureSubstance* sub = new PureSubstance(Pure_Methane); + sub->addUniqueElement("C"); + sub->addUniqueElement("H"); + vector_fp comp; + comp.push_back(1.0); + comp.push_back(4.0); + vector_fp coeff; + sub->addSpecies("CH4", PURE_FLUID, comp, 0, coeff); + sub->freezeSpecies(); + sub->setState_TP(298.15, 1.01325e5); + return sub; + } + + static PureSubstance* newHydrogen() { + PureSubstance* sub = new PureSubstance(Pure_Hydrogen); + sub->addUniqueElement("H"); + vector_fp comp; + comp.push_back(2.0); + vector_fp coeff; + sub->addSpecies("H2", PURE_FLUID, comp, 0, coeff); + sub->freezeSpecies(); + sub->setState_TP(298.15, 1.01325e5); + return sub; + } + + static PureSubstance* newOxygen() { + PureSubstance* sub = new PureSubstance(Pure_Oxygen); + sub->addUniqueElement("O"); + vector_fp comp; + comp.push_back(2.0); + vector_fp coeff; + sub->addSpecies("O2", PURE_FLUID, comp, 0, coeff); + sub->freezeSpecies(); + sub->setState_TP(298.15, 1.01325e5); + return sub; + } + + inline PureSubstance* newSubstance(int isub) { + switch(isub) { + case (Pure_Water): return newWater(); + case (Pure_Nitrogen): return newNitrogen(); + case (Pure_Methane): return newMethane(); + case (Pure_Hydrogen): return newHydrogen(); + case (Pure_Oxygen): return newOxygen(); + default: throw PureSubError(isub); + } + } +} + +#endif + diff --git a/Cantera/src/reaction_defs.h b/Cantera/src/reaction_defs.h new file mode 100755 index 000000000..0e99dc0f8 --- /dev/null +++ b/Cantera/src/reaction_defs.h @@ -0,0 +1,89 @@ +/** + * @file reaction_defs.h + * + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_RXN_DEFS_H +#define CT_RXN_DEFS_H + +#include "ct_defs.h" + +namespace Cantera { + + const int NONE = 0; + + /// @name Reaction Types + + //@{ + + /** + * A reaction with a rate coefficient that depends only on + * temperature. Example: O + OH <-> O2 + H + */ + const int ELEMENTARY_RXN = 1; + + /** + * A reaction that requires a third-body collision partner. Example: + * O2 + M <-> O + O + M + */ + const int THREE_BODY_RXN = 2; + + /** + * The general form for an association or dissociation reaction, with a + * pressure-dependent rate. Example: CH3 + H (+M) <-> CH4 (+M) + */ + const int FALLOFF_RXN = 4; + + /** + * A chemical activation reaction. For these reactions, the rate falls + * off as the pressure increases, due to collisional stabilization of + * a reaction intermediate. Example: Si + SiH4 (+M) <-> Si2H2 + H2 + * (+M), which competes with Si + SiH4 (+M) <-> Si2H4 (+M). + */ + const int CHEMACT_RXN = 8; + + /** + * A reaction occurring on a surface. + */ + const int SURFACE_RXN = 20; + + const int GLOBAL_RXN = 30; + + //@} + + /** @name Rate Coefficient Types + * These types define the supported rate coefficient types for + * elementary reactions. Any of these may also be used as the high and + * low-pressure limits of falloff and chemical activation reactions. + */ + //@{ + + const int ARRHENIUS = 1; + const int LANDAUTELLER = 2; + const int TSTRATE = 3; + + //@} + + /** @name Falloff Function Types + */ + //@{ + const int SIMPLE_FALLOFF = 100; + const int TROE3_FALLOFF = 110; + const int TROE4_FALLOFF = 111; + const int SRI3_FALLOFF = 112; + const int SRI5_FALLOFF = 113; + const int WF_FALLOFF = 114; + //@} + + // error flags + const int NO_ERROR = 0; + const int UNKNOWN_REACTION_TYPE = -100; + const int UNKNOWN_RATE_COEFF_TYPE = -200; + const int NOT_YET_IMPLEMENTED = -300; + +} + +#endif diff --git a/Cantera/src/recipes.h b/Cantera/src/recipes.h new file mode 100755 index 000000000..55ddff414 --- /dev/null +++ b/Cantera/src/recipes.h @@ -0,0 +1,21 @@ +// declarations for Fortran simplex routines from Numerical Recipes. + +#ifndef NUM_RECIPES_H +#define NUM_RECIPES_H + +extern "C" { + +integer simplx_(doublereal *a, integer *m, integer *n, integer * + mp, integer *np, integer *m1, integer *m2, integer *m3, integer * + icase, integer *izrov, integer *iposv); + +integer splin2_(doublereal *x1a, doublereal *x2a, doublereal *ya, + doublereal *y2a, integer *m, integer *n, + doublereal *x1, doublereal *x2, doublereal *y); + +integer splie2_(doublereal *x1a, doublereal *x2a, doublereal *ya, + integer *m, integer *n, doublereal *y2a); +} + + +#endif diff --git a/Cantera/src/sort.cpp b/Cantera/src/sort.cpp new file mode 100755 index 000000000..ffd4703ba --- /dev/null +++ b/Cantera/src/sort.cpp @@ -0,0 +1,122 @@ +/** + * @file sort.cpp + * + */ + + +#ifdef WIN32 +#pragma warning(disable:4786) +#endif + + +#include "sort.h" + +namespace Cantera { + + // sort (x,y) pairs by x + + void heapsort(vector_fp& x, vector_int& y) { + int n = x.size(); + doublereal rra; + integer rrb; + int ll = n/2; + int iret = n-1; + + while (1 > 0) { + if (ll > 0) { + ll--; + rra = x[ll]; + rrb = y[ll]; + } + else { + rra = x[iret]; + rrb = y[iret]; + x[iret] = x[0]; + y[iret] = y[0]; + iret--; + if (iret == 0) { + x[0] = rra; + y[0] = rrb; + return; + } + } + + int i = ll; + int j = ll + ll + 1; + + while (j <= iret) { + if (j < iret) { + if (x[j] < x[j+1]) + j++; + } + if (rra < x[j]) { + x[i] = x[j]; + y[i] = y[j]; + i = j; + j = j + j + 1; + } + else { + j = iret + 1; + } + } + x[i] = rra; + y[i] = rrb; + } + } + + void heapsort(vector_fp& x, vector_fp& y) { + int n = x.size(); + doublereal rra; + doublereal rrb; + int ll = n/2; + int iret = n-1; + + while (1 > 0) { + if (ll > 0) { + ll--; + rra = x[ll]; + rrb = y[ll]; + } + else { + rra = x[iret]; + rrb = y[iret]; + x[iret] = x[0]; + y[iret] = y[0]; + iret--; + if (iret == 0) { + x[0] = rra; + y[0] = rrb; + return; + } + } + + int i = ll; + int j = ll + ll + 1; + + while (j <= iret) { + if (j < iret) { + if (x[j] < x[j+1]) + j++; + } + if (rra < x[j]) { + x[i] = x[j]; + y[i] = y[j]; + i = j; + j = j + j + 1; + } + else { + j = iret + 1; + } + } + x[i] = rra; + y[i] = rrb; + } + } + +} + + + + + + diff --git a/Cantera/src/sort.h b/Cantera/src/sort.h new file mode 100755 index 000000000..868023460 --- /dev/null +++ b/Cantera/src/sort.h @@ -0,0 +1,18 @@ +/** + * @file sort.h + */ + +#ifndef CT_SORT_H +#define CT_SORT_H + +#include "ct_defs.h" + +namespace Cantera { + + // sort (x,y) pairs by x + + void heapsort(vector_fp& x, vector_int& y); + void heapsort(vector_fp& x, vector_fp& y); +} + +#endif diff --git a/Cantera/src/speciesThermoTypes.h b/Cantera/src/speciesThermoTypes.h new file mode 100755 index 000000000..47166cbbc --- /dev/null +++ b/Cantera/src/speciesThermoTypes.h @@ -0,0 +1,58 @@ +/** + * @file speciesThermoTypes.h + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef SPECIES_THERMO_TYPES_H +#define SPECIES_THERMO_TYPES_H + +// Constant Cp +#define CONSTANT_CP 1 + +// Polynomial +#define POLYNOMIAL_4 2 + +// NASA Polynomials +#define NASA 4 + +// Shomate Polynomials used in NIST database +#define SHOMATE 8 + +// Tiger Polynomials +#define TIGER 16 + +#define SIMPLE 32 + +#include "ct_defs.h" + +namespace Cantera { + + struct UnknownThermoParam { + UnknownThermoParam(int thermotype) { + cerr << endl << "### ERROR ###" << endl; + cerr << "Unknown species thermo parameterization (" + << thermotype << ")" << endl << endl; + } + }; + + + /// holds parameterization-dependent index information + struct ThermoIndexData { + int param; + int nCoefficients; + int Tmin_coeff; + int Tmax_coeff; + int Pref_coeff; + }; + +} + +#endif + + diff --git a/Cantera/src/stringUtils.cpp b/Cantera/src/stringUtils.cpp new file mode 100755 index 000000000..8e872ad13 --- /dev/null +++ b/Cantera/src/stringUtils.cpp @@ -0,0 +1,280 @@ +/** + * @file stringUtils.cpp + * + */ + +// Copyright 2001 California Institute of Technology + + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "ct_defs.h" +//#include "Phase.h" +#include "ThermoPhase.h" + +//#include "IdealGasMix.h" + +#include + +namespace Cantera { + + + /** + * Convert a floating point number to a string using sprintf. + */ + string fp2str(double x, string fmt) { + char buf[30]; + sprintf(buf, fmt.c_str(), x); + return string(buf); + } + + /** + * Convert an integer number to a string using sprintf. + */ + string int2str(int n, string fmt) { + char buf[30]; + sprintf(buf, fmt.c_str(), n); + return string(buf); + } + + string lowercase(string s) { + int n = s.size(); + string lc(s); + for (int i = 0; i < n; i++) lc[i] = tolower(s[i]); + return lc; + } + + /** + * Strip white space. + */ + string stripws(string s) { + int i; + bool sempty = true; + int n = s.size(); + string ss = ""; + for (i = 0; i < n; i++) { + if (s[i] != ' ' && isprint(s[i])) { + ss += s[i]; + sempty = false; + } + else if (!sempty) break; + } + return ss; + } + + /** + * Strip non-printing characters. + */ + string stripnonprint(string s) { + int i; + int n = s.size(); + string ss = ""; + for (i = 0; i < n; i++) { + if (isprint(s[i])) { + ss += s[i]; + } + } + return ss; + } + + + /** + * Parse a composition string. + */ + void parseCompString(const string ss, compositionMap& x) { + string s = ss; + int icolon, ibegin, iend; + string name, num, nm; + do { + ibegin = s.find_first_not_of(", ;\n\t"); + if (ibegin >= 0) { + s = s.substr(ibegin,s.size()); + icolon = s.find(':'); + iend = s.find_first_of(", ;\n\t"); + //icomma = s.find(','); + if (icolon > 0) { + name = s.substr(0, icolon); + if (iend > 0) { + num = s.substr(icolon+1, iend-icolon); + s = s.substr(iend+1, s.size()); + } + else { + num = s.substr(icolon+1, s.size()); + s = ""; + } + nm = stripws(name); + if (x[nm] == 0.0) throw CanteraError("parseCompString", + "unknown species "+nm); + x[nm] = atof(num.c_str()); + } + else s = ""; + } + } + while (s != ""); + } + + int fillArrayFromString(const string& str, doublereal* a, char delim) { + int iloc; + int count = 0; + string num, s; + s = str; + while (s.size() > 0) { + iloc = s.find(delim); + if (iloc > 0) { + num = s.substr(0, iloc); + s = s.substr(iloc+1,s.size()); + } + else { + num = s; + s = ""; + } + a[count] = atof(num.c_str()); + count++; + } + return count; + } + + /** + * Format a summary of the mixture state for output. + */ + string report(const ThermoPhase& th, bool show_thermo) { + + char p[200]; + string s = ""; + + sprintf(p, "\n temperature %12.6g K\n", th.temperature()); + s += p; + sprintf(p, " pressure %12.6g Pa\n", th.pressure()); + s += p; + sprintf(p, " density %12.6g kg/m^3\n", th.density()); + s += p; + sprintf(p, " mean mol. weight %12.6g amu\n", th.meanMolecularWeight()); + s += p; + + if (show_thermo) { + sprintf(p, "\n"); + s += p; + sprintf(p, " 1 kg 1 kmol\n"); + s += p; + sprintf(p, " ----------- ------------\n"); + s += p; + sprintf(p, " enthalpy %12.6g %12.4g J\n", + th.enthalpy_mass(), th.enthalpy_mole()); + s += p; + sprintf(p, " internal energy %12.6g %12.4g J\n", + th.intEnergy_mass(), th.intEnergy_mole()); + s += p; + sprintf(p, " entropy %12.6g %12.4g J/K\n", + th.entropy_mass(), th.entropy_mole()); + s += p; + sprintf(p, " Gibbs function %12.6g %12.4g J\n", + th.gibbs_mass(), th.gibbs_mole()); + s += p; + sprintf(p, " heat capacity c_p %12.6g %12.4g J/K\n", + th.cp_mass(), th.cp_mole()); + s += p; + sprintf(p, " heat capacity c_v %12.6g %12.4g J/K\n", + th.cv_mass(), th.cv_mole()); + s += p; + } + + int kk = th.nSpecies(); + array_fp x(kk); + array_fp y(kk); + th.getMoleFractions(x.begin()); + th.getMassFractions(y.begin()); + + int k; + + sprintf(p, "\n X Y \n"); + s += p; + sprintf(p, " ------------- ------------\n"); + s += p; + for (k = 0; k < kk; k++) { + sprintf(p, "%18s %12.6e %12.6e\n", + th.speciesName(k).c_str(), x[k], y[k]); + s += p; + } + return s; + } + + /** + * Format a composition list for output. + */ + string formatCompList(const Phase& mix, int xyc) { + + const doublereal Threshold = 1.e-20; + + char p[200]; + string s = ""; + int kk = mix.nSpecies(); + array_fp zz(kk); + switch (xyc) { + case 0: mix.getMoleFractions(zz.begin()); break; + case 1: mix.getMassFractions(zz.begin()); break; + case 2: mix.getConcentrations(zz.begin()); break; + default: return "error: xyc must be 0, 1, or 2"; + } + + doublereal z; + int k; + for (k = 0; k < kk; k++) { + z = fabs(zz[k]); + if (z < Threshold) zz[k] = 0.0; + } + + for (k = 0; k < kk; k++) { + sprintf(p, "%18s\t %12.6e\n", mix.speciesName(k).c_str(), + zz[k]); + s += p; + } + return s; + } + + + /** + * Get the file name without the path or extension + */ + string getFileName(const string& path) { + string file; + size_t idot = path.find_last_of('.'); + size_t islash = path.find_last_of('/'); + if (idot > 0 && idot < path.size()) { + if (islash > 0 && islash < idot) { + file = path.substr(islash+1, idot-islash-1); + } + else { + file = path.substr(0,idot); + } + } + else { + file = path; + } + return file; + } + + + /** + * Generate a logfile name based on an input file name + */ + string logfileName(const string& infile) { + string logfile; + size_t idot = infile.find_last_of('.'); + size_t islash = infile.find_last_of('/'); + if (idot > 0 && idot < infile.size()) { + if (islash > 0 && islash < idot) { + logfile = infile.substr(islash+1, idot-islash-1) + ".log"; + } + else { + logfile = infile.substr(0,idot) + ".log"; + } + } + else { + logfile = infile + ".log"; + } + return logfile; + } +} diff --git a/Cantera/src/stringUtils.h b/Cantera/src/stringUtils.h new file mode 100755 index 000000000..3725c0545 --- /dev/null +++ b/Cantera/src/stringUtils.h @@ -0,0 +1,34 @@ +/** + * @file stringUtils.h + * + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_STRINGUTILS_H +#define CT_STRINGUTILS_H + +#include "ct_defs.h" +#include + +namespace Cantera { + + class Phase; + class ThermoPhase; + + string fp2str(double x, string fmt = "%g"); + string int2str(int n, string fmt = "%d"); + string stripws(string s); + string stripnonprint(string s); + string lowercase(string s); + void parseCompString(const string ss, compositionMap& x); + int fillArrayFromString(const string& str, doublereal* a, char delim = ' '); + string report(const ThermoPhase& th, bool show_thermo = true); + //void printSummary(IdealGasMix& mix, ostream& s); + string formatCompList(const Phase& mix, int xyc); + string logfileName(const string& infile); + string getFileName(const string& path); +} + +#endif diff --git a/Cantera/src/surfKinetics.cpp b/Cantera/src/surfKinetics.cpp new file mode 100755 index 000000000..25a309e7d --- /dev/null +++ b/Cantera/src/surfKinetics.cpp @@ -0,0 +1,390 @@ +/** + * @file SurfKinetics.cpp + * + */ + +// Copyright 2002 California Institute of Technology + + +// turn off warnings under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + + +#include "surfKinetics.h" +#include "ReactionData.h" +#include "RateCoeffMgr.h" +#include "ImplicitSurfChem.h" +#include +using namespace std; + +#include "ctml.h" +using namespace ctml; + +#include + +namespace Cantera { + + void importInterfaceData(SurfacePhase* ph, SurfKinetics* kin, string fname, string id); + + /** + * Construct an empty surface reaction mechanism. + */ + SurfKinetics:: + SurfKinetics(SurfacePhase* surfphase, + thermo_t* th1, + thermo_t* th2, string fname, string id) : + Kinetics(), + m_surfphase(surfphase), + m_kk(0), + m_kk1(0), + m_kk2(0), + m_ktot(0), + m_nirrev(0), + m_integrator(0), + m_finalized(false), + m_twobulk(false), + m_xml(new XML_Node("interface_reactions")) + { + + // add the two bulk phases + addPhase(*th1); + if (th2) { + m_twobulk = true; + addPhase(*th2); + } + + m_kk1 = phase(0).nSpecies(); + + if (th2) { + m_kk2 = phase(1).nSpecies(); + } + m_kk = m_surfphase->nSpecies(); + m_kdata = new SurfKineticsData; + m_kdata->m_temp = 0.0; + + if (fname != "") importInterfaceData(surfphase, this, fname, id); + } + + void SurfKinetics:: + _update_rates_T() { + doublereal T = m_surfphase->temperature(); + if (T != m_kdata->m_temp) { + doublereal logT = log(T); + m_rates.update(T, logT, m_kdata->m_rfn.begin()); + m_kdata->m_temp = T; + m_kdata->m_ROP_ok = false; + } + }; + + void SurfKinetics:: + _update_rates_C() { + phase(0).getConcentrations(m_conc.begin()); + if (m_twobulk) { + phase(1).getConcentrations(m_conc.begin() + m_kk1); + } + m_surfphase->getConcentrations(m_conc.begin() + m_kk1 + m_kk2); + m_rates.update_C(m_conc.begin()); + m_kdata->m_ROP_ok = false; + } + + void SurfKinetics::updateROP() { + + _update_rates_C(); + _update_rates_T(); + + if (m_kdata->m_ROP_ok) return; + + const vector_fp& rf = m_kdata->m_rfn; + vector_fp& ropf = m_kdata->m_ropf; + + // copy rate coefficients into ropf + copy(rf.begin(), rf.end(), ropf.begin()); + + // multiply by perturbation factor + multiply_each(ropf.begin(), ropf.end(), m_perturb.begin()); + + // multiply ropf by concentration products + int i, j, k, o; + for (i = 0; i < m_ii; i++) { + for (j = 0; j < m_nr[i]; j++) { + k = m_reactants[i][j]; + o = m_order[i][j]; + ropf[i] *= pow(m_conc[k],m_order[i][j]); + } + } + m_kdata->m_ROP_ok = true; + } + + + void SurfKinetics:: + getNetProductionRates(doublereal* net) { + updateROP(); + int i, n, k; + doublereal q; + for (k = 0; k < m_ktot; k++) net[k] = 0.0; + + for (i = 0; i < m_ii; i++) { + q = m_kdata->m_ropf[i]; + for (n = 0; n < m_nr[i]; n++) { + k = m_reactants[i][n]; + net[k] -= q*m_rst[i][n]; + } + for (n = 0; n < m_np[i]; n++) { + k = m_products[i][n]; + net[k] += q*m_pst[i][n]; + } + } + } + + void SurfKinetics:: + getCreationRates(doublereal* cdot) { + updateROP(); + int i, n, k; + doublereal q; + fill(cdot, cdot + m_ktot, 0.0); + for (i = 0; i < m_ii; i++) { + q = m_kdata->m_ropf[i]; + for (n = 0; n < m_np[i]; n++) { + k = m_products[i][n]; + cdot[k] += q*m_pst[i][n]; + } + } + } + + void SurfKinetics:: + getDestructionRates(doublereal* ddot) { + updateROP(); + int i, n, k; + doublereal q; + fill(ddot, ddot + m_ktot, 0.0); + for (i = 0; i < m_ii; i++) { + q = m_kdata->m_ropf[i]; + for (n = 0; n < m_nr[i]; n++) { + k = m_reactants[i][n]; + ddot[k] += q*m_rst[i][n]; + } + } + } + + void SurfKinetics:: + getChemRates(doublereal* rtau) { + updateROP(); + int i, n, k; + doublereal q; + fill(rtau, rtau + m_ktot, 0.0); + for (i = 0; i < m_ii; i++) { + q = m_kdata->m_ropf[i]; + for (n = 0; n < m_nr[i]; n++) { + k = m_reactants[i][n]; + rtau[k] += q*m_rst[i][n]; + } + } + for (k = 0;k < m_ktot; k++) { + if (m_conc[k] != 0.0) + rtau[k] = fabs(rtau[k]/m_conc[k]); + else + rtau[k] = 0.0; + } + } + + void SurfKinetics:: + saveReactionData( + const vector_int& r, + const vector_int& rstoich, + const vector_int& order, + const vector_int& p, + const vector_int& pstoich, + const vector_fp& rateParams) { + + if (nReactions() == 0) + m_xml->addChild("ReactionArray"); + + XML_Node& rxndata = *new XML_Node("reaction"); + int n, k; + string nm, ph, ustr, comment; + for (n = 0; n < r.size(); n++) { + XML_Node& reac = rxndata.addChild("reactant"); + if (r[n] < m_kk1) { + k = r[n]; + nm = phase(0).speciesName(k); + ph = phase(0).id(); + ustr = "kmol/m^3"; + m_bsp1[nm] = 1; + } + else if (r[n] < m_kk1 + m_kk2) { + k = r[n] - m_kk1; + nm = phase(1).speciesName(k); + ph = phase(1).id(); + ustr = "kmol/m^3"; + m_bsp2[nm] = 1; + } + else { + k = r[n] - m_kk1 - m_kk2; nm = m_surfphase->speciesName(k); + ph = ""; // m_surfphase->id(); + ustr = "kmol/m^2"; + } + if (ph != "") reac.addAttribute("phase",ph); + reac.addAttribute("name",nm); + reac.addAttribute("stoich",rstoich[n]); + reac.addAttribute("order",order[n]); + // reac.addAttribute("units",ustr); + comment += nm+" + "; + } + comment = comment.substr(0, comment.size() - 2) + " => "; + + for (n = 0; n < p.size(); n++) { + XML_Node& prod = rxndata.addChild("product"); + if (p[n] < m_kk1) { + k = p[n]; nm = phase(0).speciesName(k); + ph = phase(0).id(); + ustr = "kmol/m^3"; + } + else if (p[n] < m_kk1 + m_kk2) { + k = p[n] - m_kk1; + nm = phase(1).speciesName(k); + ph = phase(1).id(); + ustr = "kmol/m^3"; + } + else { + k = p[n] - m_kk1 - m_kk2; + nm = m_surfphase->speciesName(k); + ph = ""; + ustr = "kmol/m^2"; + } + if (ph != "") prod.addAttribute("phase",ph); + prod.addAttribute("name",nm); + prod.addAttribute("stoich",pstoich[n]); + comment += nm+" + "; + } + comment = " "+comment.substr(0, comment.size() - 2)+" "; + + XML_Node& rate = rxndata.addChild("rate"); + rate.addAttribute("type","Arrhenius"); + rate.addAttribute("units","kmol/m^2/s"); + addFloat(rate, "A", rateParams[0]); + addFloat(rate, "n", rateParams[1]); + addFloat(rate, "E", rateParams[2], "K"); + + XML_Node& rxns = m_xml->child("ReactionArray"); + rxns.addComment(comment); + rxns.addChild(rxndata); + }; + + + void SurfKinetics:: + addReaction(const vector_int& r, + const vector_int& rstoich, + const vector_int& order, + const vector_int& p, + const vector_int& pstoich, + const vector_fp& rateParams) { + + // record reaction parameters + saveReactionData(r, rstoich, order, p, pstoich, rateParams); + + // prohibit adding more species + if (!m_surfphase->speciesFrozen()) + m_surfphase->freezeSpecies(); + + // if init() hasn't been called yet, call it + if (m_kk == 0) init(); + + int iloc; + // install rate coeff calculator + iloc = m_rates.install( m_ii, + ARRHENIUS, rateParams.size(), rateParams.begin()); + + // add constant term to rate coeff value vector + m_kdata->m_rfn.push_back(rateParams[0]); + + // forward rxn order + m_order.push_back(order); + + m_kdata->m_ropf.push_back(0.0); // extend by one for new rxn + + m_reactants.push_back(r); + m_rst.push_back(rstoich); + m_products.push_back(p); + m_pst.push_back(pstoich); + + m_nr.push_back(r.size()); + m_np.push_back(p.size()); + + incrementRxnCount(); + } + + + void SurfKinetics::init() { + m_kk = m_surfphase->nSpecies(); + m_ktot = m_kk + m_kk1 + m_kk2; + m_conc.resize(m_ktot); + } + + void SurfKinetics::save(string fname, string idtag, string comment) { + struct tm *newtime; + time_t aclock; + ::time( &aclock ); /* Get time in seconds */ + newtime = localtime( &aclock ); /* Convert time to struct tm form */ + + ofstream fout(fname.c_str()); + XML_Node root("doc"); + XML_Node& ct = root.addChild("ctml"); + ct.addComment(comment); + + XML_Node& iface = ct.addChild("interface"); + addString(iface,"timestamp",asctime(newtime)); + iface.addAttribute("id",idtag); + addFloat(iface, "site_density", m_surfphase->siteDensity()); + XML_Node& bp1 = iface.addChild("phase"); + bp1.addAttribute("id",phase(0).id()); + map::const_iterator b = m_bsp1.begin(), e = m_bsp1.end(); + for (; b != e; ++b) { + bp1.addChild("species").addAttribute("name",b->first); + } + bp1.addChild(thermo(0).xml()); + if (m_twobulk) { + XML_Node& bp2 = iface.addChild("phase"); + bp2.addAttribute("id",phase(1).id()); + map::const_iterator b = m_bsp2.begin(), e = m_bsp2.end(); + for (; b != e; ++b) { + bp2.addChild("species").addAttribute("name",b->first); + } + bp2.addChild(thermo(1).xml()); + } + iface.addChild(m_surfphase->xml().child("SpeciesArray")); + iface.addChild(m_xml->child("ReactionArray")); + ct.writeHeader(fout); + ct.write(fout); + fout.close(); + } + + void SurfKinetics::finalize() { + if (!m_finalized) { + m_finalized = true; + } + } + + bool SurfKinetics::ready() const { + return (m_finalized); + } + + void SurfKinetics::integrate(doublereal dt) { + finalize(); + if (m_integrator == 0) { + m_integrator = new ImplicitSurfChem(*this); + m_integrator->initialize(0.0); + } + m_integrator->integrate(0.0, dt); + } +} + + + + + + + + diff --git a/Cantera/src/surfKinetics.h b/Cantera/src/surfKinetics.h new file mode 100755 index 000000000..2a79eeb23 --- /dev/null +++ b/Cantera/src/surfKinetics.h @@ -0,0 +1,190 @@ +/** + * @file SurfKinetics.h + */ + + +/* + * $Author$ + * $Revision$ + * $Date$ + * + * Copyright 2001 California Institute of Technology + */ + +#ifndef CT_SURFKINETICS_H +#define CT_SURFKINETICS_H + +#include +#include +#include +#include + +#include "mix_defs.h" +#include "Kinetics.h" + +#include "utilities.h" +#include "RateCoeffMgr.h" +#include "surfacePhase.h" + +namespace Cantera { + + // forward references + class ImplicitSurfChem; + class ReactionData; + + /** + * Holds mechanism-specific data. + * @ingroup kineticsGroup + */ + class SurfKineticsData { + public: + SurfKineticsData() : + m_ROP_ok(false), + m_temp(0.0) + {} + virtual ~SurfKineticsData(){} + + vector_fp m_ropf; + bool m_ROP_ok; + + doublereal m_temp; + vector_fp m_rfn; + doublereal m_s0; + }; + + + /** + * A kinetics manager for elementary surface chemistry. + */ + class SurfKinetics : public Kinetics { + + public: + + /// Constructor. + SurfKinetics() : Kinetics() {} + SurfKinetics(SurfacePhase* surfphase, thermo_t* th1, + thermo_t* th2, string fname="", string id=""); + + /// Destructor. + virtual ~SurfKinetics(){delete m_kdata; delete m_xml;} + + virtual int ID() { return 10; } + void import(string fname, string id); + + /** + * The surface phase for which this is a kinetics manager. + */ + SurfacePhase& sphase() { return *m_surfphase; } + + /** + * Total number of species on the surface and in both phases. + */ + int nTotal() { return m_ktot; } + + /** + * Return a reference to one of the bulk phases. + */ + Phase* bulkPhase(int n) { + return m_phase[n]; + } + + /** + * Get the forward rates of progress for all surface reactions. + */ + virtual void getFwdRatesOfProgress(doublereal* fwdROP) { + updateROP(); + copy(m_kdata->m_ropf.begin(), m_kdata->m_ropf.end(), fwdROP); + } + + /** + * Get the reverse rates of progress for all surface reactions. + * All reactions are currently modeled as irreversible, so this + * returns all zeros. + */ + virtual void getRevRatesOfProgress(doublereal* revROP) { + int i; + for (i = 0; i < m_ii; i++) + revROP[i] = 0.0; + } + + virtual void getNetRatesOfProgress(doublereal* netROP) { + getFwdRatesOfProgress(netROP); + } + + virtual void getNetProductionRates(doublereal* net); + virtual void getCreationRates(doublereal* cdot); + virtual void getDestructionRates(doublereal* ddot); + virtual void getChemRates(doublereal* rtau); + + virtual void init(); + + virtual void integrate(doublereal dt); + + /// Add a reaction to the mechanism. + void addReaction(const vector_int& r, const vector_int& rstoich, + const vector_int& order, const vector_int& p, + const vector_int& pstoich, + const vector_fp& rateParams); + + void saveReactionData(const vector_int& r, const vector_int& rstoich, + const vector_int& order, const vector_int& p, + const vector_int& pstoich, + const vector_fp& rateParams); + + virtual void finalize(); + virtual bool ready() const; + + void updateROP(); + + virtual int reactionType(int i) const {return SURFACE_RXN;} + virtual bool isReversible(int i) {return false;} + void save(string fname, string idtag, string comment); + + protected: + + SurfacePhase* m_surfphase; + SurfKineticsData* m_kdata; + + // objects for bulk phase 2. Those for bulk phase 1 + // are declared in Kinetics + phase_t* m_phase2; + thermo_t* m_thermo2; + + int m_kk; // number of surface species + int m_kk1; // number of bulk phase 1 species + int m_kk2; // number of bulk phase 2 species + int m_ktot; // total number of species + + Rate1 m_rates; + + vector_int m_irrev; + int m_nirrev; + + //mutable vector > m_rrxn; + //mutable vector > m_prxn; + + //map > m_rstoich; + //map > m_pstoich; + + vector m_order; + vector m_rst; + vector m_pst; + vector_int m_nr, m_np; + + vector_fp m_conc; + + ImplicitSurfChem* m_integrator; + map m_bsp1, m_bsp2; + + private: + + void _update_rates_T(); + void _update_rates_C(); + XML_Node* m_xml; + bool m_twobulk; + + bool m_finalized; + }; +} + +#endif diff --git a/Cantera/src/surfacePhase.h b/Cantera/src/surfacePhase.h new file mode 100755 index 000000000..bf16d1a80 --- /dev/null +++ b/Cantera/src/surfacePhase.h @@ -0,0 +1,78 @@ +#ifndef CT_SURFACE_PHASE +#define CT_SURFACE_PHASE + +#include +using namespace std; + +#include "ctml.h" +using namespace ctml; +#include "Phase.h" + +namespace Cantera { + + /** + * Surface phases. This class is analogous to class 'Phase' for 3D phases. + * + * @todo Should SurfacePhase and Phase be integrated? + */ + class SurfacePhase : public Phase { + public: + SurfacePhase() : Phase(), m_s0(-1.0) {} + + virtual ~SurfacePhase() {} + virtual void freezeSpecies() { + Phase::freezeSpecies(); + m_work.resize(nSpecies()); + } + + /** + * Return the total coverage, summed over all species. + * Normally, this should equal 1.0, and in SurfKinetics + * this method is used to formulate the residual equation to + * enforce this condition. + */ + doublereal totalCoverage() { + int k; + doublereal sum = 0.0; + getConcentrations(m_work.begin()); + for (k = 0; k < m_kk; k++) + sum += m_work[k]*m_size[k]; + sum /= m_s0; + return sum; + } + + virtual bool ready() const { + return (Phase::ready() && m_s0 > 0.0); + } + + // Number of surface sites per unit area. + doublereal siteDensity() { return m_s0; } + + // Set the site density. + void setSiteDensity(doublereal s0) { m_s0 = s0; } + + void setCoverages(const doublereal* cov) { + int k; + for (k = 0; k < m_kk; k++) { + m_work[k] = cov[k]*m_s0/m_size[k]; + } + setConcentrations(m_work.begin()); + } + + void getCoverages(doublereal* cov) const { + int k; + getConcentrations(m_work.begin()); + for (k = 0; k < m_kk; k++) + cov[k] = m_work[k]*m_size[k]/m_s0; + } + + protected: + + doublereal m_s0; + vector_fp m_size; + mutable vector_fp m_work; + }; + +} + +#endif diff --git a/Cantera/src/transport/.cvsignore b/Cantera/src/transport/.cvsignore new file mode 100644 index 000000000..57751bad9 --- /dev/null +++ b/Cantera/src/transport/.cvsignore @@ -0,0 +1,2 @@ +Makefile +.depends diff --git a/Cantera/src/transport/FtnTransport.h b/Cantera/src/transport/FtnTransport.h new file mode 100755 index 000000000..706fd051f --- /dev/null +++ b/Cantera/src/transport/FtnTransport.h @@ -0,0 +1,158 @@ +/** + * @file FtnTransport.h + * + * Customizable Fortran transport manager. This manager calls + * external Fortran functions to evaluate the transport + * properties. This is designed to be used to build custom transport + * managers in Fortran. + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_FTNTRANSPORT_H +#define CT_FTNTRANSPORT_H + +#include "ct_defs.h" +#include "DenseMatrix.h" + + +/** + * Change these definitions to change the names of the Fortran + * procedures. If you want to define more than one custom Fortran + * transport manager, copy this file, rename the class, and change + * these definitions. + * + * The Fortran procedure names must follow the conventions of the Fortran + * compiler. On most unix systems, this means the names must be lowercase, + * and must include a trailing underscore. + * + */ +#define __VISC__ visc_ +#define __BULKVISC__ bvisc_ +#define __TCON__ tcon_ +#define __SPVISC__ spvisc_ +#define __SPCOND__ spcond_ +#define __SPFLUXES__ spfluxes_ +#define __TDIFF__ tdiff_ +#define __MULTIDIFF__ multidiff_ +#define __MIXDIFF__ mixdiff_ +#define __UPT__ updatet_ +#define __UPC__ updatec_ +#define __INIT__ init_ + +extern "C" { + doublereal __VISC__(doublereal* t, doublereal* p, doublereal* x); + doublereal __BULKVISC__(doublereal* t, doublereal* p, doublereal* x); + doublereal __TCON__(doublereal* t, doublereal* p, doublereal* x); + + void __SPVISC__(doublereal* t, doublereal* p, doublereal* x, doublereal* visc); + void __SPCOND__(doublereal* t, doublereal* p, doublereal* x, doublereal* cond); + void __SPFLUXES__(doublereal* t, doublereal* p, doublereal* x, + integer* ndim, doublereal* gradt, integer* ldx, doublereal* gradx, + integer* ldf, doublereal* fluxes); + void __TDIFF__(doublereal* t, doublereal* p, doublereal* x, doublereal* dt); + void __MULTIDIFF__(doublereal* t, doublereal* p, doublereal* x, + integer* ld, doublereal* d); + void __MIXDIFF__(doublereal* t, doublereal* p, doublereal* x, doublereal* d); + void __BINDIFF__(doublereal* t, doublereal* p, doublereal* x, doublereal* d); + void __UPT__(doublereal* t); + void __UPC__(doublereal* p, doublereal* x); + void __INIT__(); +} + +namespace Cantera { + + /** + * A class that calls external Fortran functions to evaluate + * transport properties. Not currently used - may need updating. + */ + class FtnTransport : public Transport { + + public: + + FtnTransport(int model) { m_model = model; } + + virtual int model() { return m_model; } + + virtual doublereal viscosity() { + return __VISC__(&m_temp, &m_pres, m_x.begin()); + } + + virtual void getSpeciesViscosities(doublereal* visc) { + __SPVISC__(&m_temp, &m_pres, m_x.begin(), visc); + } + + virtual void getSpeciesConductivities(doublereal* cond) { + __SPCOND__(&m_temp, &m_pres, m_x.begin(), cond); + } + + virtual doublereal bulkViscosity() + { return __BULKVISC__(&m_temp, &m_pres, m_x.begin()); } + + virtual doublereal thermalConductivity() + { return __TCON__(&m_temp, &m_pres, m_x.begin()); } + + virtual void getSpeciesFluxes(doublereal p, int ndim, + doublereal* grad_T, int ldx, doublereal* grad_X, + int ldf, doublereal* fluxes) { + doublereal pp = p; + integer ldxx = ldx, ndimm = ndim, ldff = ldf; + __SPFLUXES__(&m_temp, &pp, &m_x, &ndimm, grad_T, &ldxx, grad_X, + &ldff, fluxes); + } + + virtual void getThermalDiffCoeffs(doublereal* dt) + { __TDIFF__(&m_temp, &m_pres, m_x.begin(), dt); } + + virtual void getBinaryDiffCoeffs(doublereal p, int ld, doublereal* d) + { m_pres = p; + integer ldd = ld; + __BINDIFF__(&m_temp, &m_pres, m_x.begin(), &ldd, d); + } + + virtual void getMultiDiffCoeffs(doublereal p, int ld, doublereal* d) + { m_pres = p; + integer ldd = ld; + __MULTIDIFF__(&m_temp, &m_pres, m_x.begin(), &ldd, d); + } + + virtual void getMixDiffCoeffs(doublereal p, doublereal* d) + { m_pres = p; + integer ldd = ld; + __MIXDIFF__(&m_temp, &m_pres, m_x.begin(), d); + } + + virtual void update_T() + { m_temp = m_mix->temperature(); + __UPT__(m_temp); + } + + virtual void update_C() + { m_mix->getMoleFractions(m_x.begin()); + m_pres = m_mix->pressure(); + __UPC__(m_pres, m_x); + } + + virtual bool init(TransportParams& tr) { + m_mix = tr.mix; + __INIT__(); + } + + private: + + doublereal m_temp; + doublereal m_pres; + vector_fp m_x; + int m_model; + + }; + +} +#endif + + + + + + diff --git a/Cantera/src/transport/MMCollisionInt.cpp b/Cantera/src/transport/MMCollisionInt.cpp new file mode 100755 index 000000000..854992743 --- /dev/null +++ b/Cantera/src/transport/MMCollisionInt.cpp @@ -0,0 +1,501 @@ +/** + * @file MMCollisionInt.cpp + */ + +/* + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology */ + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "MMCollisionInt.h" +#include "../polyfit.h" +#include "../xml.h" +#include + +namespace Cantera { + + const int DeltaDegree = 6; + + double MMCollisionInt::delta[8] = {0.0, 0.25, 0.50, 0.75, 1.0, + 1.5, 2.0, 2.5}; + + doublereal quadInterp(doublereal x0, doublereal* x, doublereal* y) { + doublereal dx21, dx32, dx31, dy32, dy21, a; + dx21 = x[1] - x[0]; + dx32 = x[2] - x[1]; + dx31 = dx21 + dx32; + dy32 = y[2] - y[1]; + dy21 = y[1] - y[0]; + a = (dx21*dy32 - dy21*dx32)/(dx21*dx31*dx32); + return a*(x0 - x[0])*(x0 - x[1]) + (dy21/dx21)*(x0 - x[1]) + y[1]; + } + + + double MMCollisionInt::tstar22[37] = + {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, + 1.2, 1.4, 1.6, 1.8, 2.0, 2.5, 3.0, 3.5, 4.0, + 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 12.0, 14.0, 16.0, + 18.0, 20.0, 25.0, 30.0, 35.0, 40.0, 50.0, 75.0, 100.0}; + + + double MMCollisionInt::omega22_table[37*8] = { + 4.1005, 4.266, 4.833, 5.742, 6.729, 8.624, 10.34, 11.89, + 3.2626, 3.305, 3.516, 3.914, 4.433, 5.57, 6.637, 7.618, + 2.8399, 2.836, 2.936, 3.168, 3.511, 4.329, 5.126, 5.874, + 2.531, 2.522, 2.586, 2.749, 3.004, 3.64, 4.282, 4.895, + 2.2837, 2.277, 2.329, 2.46, 2.665, 3.187, 3.727, 4.249, + 2.0838, 2.081, 2.13, 2.243, 2.417, 2.862, 3.329, 3.786, + 1.922, 1.924, 1.97, 2.072, 2.225, 2.614, 3.028, 3.435, + 1.7902, 1.795, 1.84, 1.934, 2.07, 2.417, 2.788, 3.156, + 1.6823, 1.689, 1.733, 1.82, 1.944, 2.258, 2.596, 2.933, + 1.5929, 1.601, 1.644, 1.725, 1.838, 2.124, 2.435, 2.746, + 1.4551, 1.465, 1.504, 1.574, 1.67, 1.913, 2.181, 2.451, + 1.3551, 1.365, 1.4, 1.461, 1.544, 1.754, 1.989, 2.228, + 1.28, 1.289, 1.321, 1.374, 1.447, 1.63, 1.838, 2.053, + 1.2219, 1.231, 1.259, 1.306, 1.37, 1.532, 1.718, 1.912, + 1.1757, 1.184, 1.209, 1.251, 1.307, 1.451, 1.618, 1.795, + 1.0933, 1.1, 1.119, 1.15, 1.193, 1.304, 1.435, 1.578, + 1.0388, 1.044, 1.059, 1.083, 1.117, 1.204, 1.31, 1.428, + 0.99963, 1.004, 1.016, 1.035, 1.062, 1.133, 1.22, 1.319, + 0.96988, 0.9732, 0.983, 0.9991, 1.021, 1.079, 1.153, 1.236, + 0.92676, 0.9291, 0.936, 0.9473, 0.9628, 1.005, 1.058, 1.121, + 0.89616, 0.8979, 0.903, 0.9114, 0.923, 0.9545, 0.9955, 1.044, + 0.87272, 0.8741, 0.878, 0.8845, 0.8935, 0.9181, 0.9505, 0.9893, + 0.85379, 0.8549, 0.858, 0.8632, 0.8703, 0.8901, 0.9164, 0.9482, + 0.83795, 0.8388, 0.8414, 0.8456, 0.8515, 0.8678, 0.8895, 0.916, + 0.82435, 0.8251, 0.8273, 0.8308, 0.8356, 0.8493, 0.8676, 0.8901, + 0.80184, 0.8024, 0.8039, 0.8065, 0.8101, 0.8201, 0.8337, 0.8504, + 0.78363, 0.784, 0.7852, 0.7872, 0.7899, 0.7976, 0.8081, 0.8212, + 0.76834, 0.7687, 0.7696, 0.7712, 0.7733, 0.7794, 0.7878, 0.7983, + 0.75518, 0.7554, 0.7562, 0.7575, 0.7592, 0.7642, 0.7711, 0.7797, + 0.74364, 0.7438, 0.7445, 0.7455, 0.747, 0.7512, 0.7569, 0.7642, + 0.71982, 0.72, 0.7204, 0.7211, 0.7221, 0.725, 0.7289, 0.7339, + 0.70097, 0.7011, 0.7014, 0.7019, 0.7026, 0.7047, 0.7076, 0.7112, + 0.68545, 0.6855, 0.6858, 0.6861, 0.6867, 0.6883, 0.6905, 0.6932, + 0.67232, 0.6724, 0.6726, 0.6728, 0.6733, 0.6743, 0.6762, 0.6784, + 0.65099, 0.651, 0.6512, 0.6513, 0.6516, 0.6524, 0.6534, 0.6546, + 0.61397, 0.6141, 0.6143, 0.6145, 0.6147, 0.6148, 0.6148, 0.6147, + 0.5887, 0.5889, 0.5894, 0.59, 0.5903, 0.5901, 0.5895, 0.5885 + }; + + //----------------------------- + + double MMCollisionInt::tstar[39] = { + 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, + 1.2, 1.4, 1.6, 1.8, 2.0, 2.5, 3.0, 3.5, 4.0, + 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 12.0, 14.0, 16.0, + 18.0, 20.0, 25.0, 30.0, 35.0, 40.0, 50.0, 75.0, 100.0, 1.e10}; + + double MMCollisionInt::astar_table[39*8] = { + 1.0065, 1.0840, 1.0840, 1.0840, 1.0840, 1.0840, 1.0840, 1.0840, + 1.0231, 1.0660, 1.0380, 1.0400, 1.0430, 1.0500, 1.0520, 1.0510, + 1.0424, 1.0450, 1.0480, 1.0520, 1.0560, 1.0650, 1.0660, 1.0640, + 1.0719, 1.0670, 1.0600, 1.0550, 1.0580, 1.0680, 1.0710, 1.0710, + 1.0936, 1.0870, 1.0770, 1.0690, 1.0680, 1.0750, 1.0780, 1.0780, + 1.1053, 1.0980, 1.0880, 1.0800, 1.0780, 1.0820, 1.0840, 1.0840, + 1.1104, 1.1040, 1.0960, 1.0890, 1.0860, 1.0890, 1.0900, 1.0900, + 1.1114, 1.1070, 1.1000, 1.0950, 1.0930, 1.0950, 1.0960, 1.0950, + 1.1104, 1.1070, 1.1020, 1.0990, 1.0980, 1.1000, 1.1000, 1.0990, + 1.1086, 1.1060, 1.1020, 1.1010, 1.1010, 1.1050, 1.1050, 1.1040, + 1.1063, 1.1040, 1.1030, 1.1030, 1.1040, 1.1080, 1.1090, 1.1080, + 1.1020, 1.1020, 1.1030, 1.1050, 1.1070, 1.1120, 1.1150, 1.1150, + 1.0985, 1.0990, 1.1010, 1.1040, 1.1080, 1.1150, 1.1190, 1.1200, + 1.0960, 1.0960, 1.0990, 1.1030, 1.1080, 1.1160, 1.1210, 1.1240, + 1.0943, 1.0950, 1.0990, 1.1020, 1.1080, 1.1170, 1.1230, 1.1260, + 1.0934, 1.0940, 1.0970, 1.1020, 1.1070, 1.1160, 1.1230, 1.1280, + 1.0926, 1.0940, 1.0970, 1.0990, 1.1050, 1.1150, 1.1230, 1.1300, + 1.0934, 1.0950, 1.0970, 1.0990, 1.1040, 1.1130, 1.1220, 1.1290, + 1.0948, 1.0960, 1.0980, 1.1000, 1.1030, 1.1120, 1.1190, 1.1270, + 1.0965, 1.0970, 1.0990, 1.1010, 1.1040, 1.1100, 1.1180, 1.1260, + 1.0997, 1.1000, 1.1010, 1.1020, 1.1050, 1.1100, 1.1160, 1.1230, + 1.1025, 1.1030, 1.1040, 1.1050, 1.1060, 1.1100, 1.1150, 1.1210, + 1.1050, 1.1050, 1.1060, 1.1070, 1.1080, 1.1110, 1.1150, 1.1200, + 1.1072, 1.1070, 1.1080, 1.1080, 1.1090, 1.1120, 1.1150, 1.1190, + 1.1091, 1.1090, 1.1090, 1.1100, 1.1110, 1.1130, 1.1150, 1.1190, + 1.1107, 1.1110, 1.1110, 1.1110, 1.1120, 1.1140, 1.1160, 1.1190, + 1.1133, 1.1140, 1.1130, 1.1140, 1.1140, 1.1150, 1.1170, 1.1190, + 1.1154, 1.1150, 1.1160, 1.1160, 1.1160, 1.1170, 1.1180, 1.1200, + 1.1172, 1.1170, 1.1170, 1.1180, 1.1180, 1.1180, 1.1190, 1.1200, + 1.1186, 1.1190, 1.1190, 1.1190, 1.1190, 1.1190, 1.1200, 1.1210, + 1.1199, 1.1200, 1.1200, 1.1200, 1.1200, 1.1210, 1.1210, 1.1220, + 1.1223, 1.1220, 1.1220, 1.1220, 1.1220, 1.1230, 1.1230, 1.1240, + 1.1243, 1.1240, 1.1240, 1.1240, 1.1240, 1.1240, 1.1250, 1.1250, + 1.1259, 1.1260, 1.1260, 1.1260, 1.1260, 1.1260, 1.1260, 1.1260, + 1.1273, 1.1270, 1.1270, 1.1270, 1.1270, 1.1270, 1.1270, 1.1280, + 1.1297, 1.1300, 1.1300, 1.1300, 1.1300, 1.1300, 1.1300, 1.1290, + 1.1339, 1.1340, 1.1340, 1.1350, 1.1350, 1.1340, 1.1340, 1.1320, + 1.1364, 1.1370, 1.1370, 1.1380, 1.1390, 1.1380, 1.1370, 1.1350, + 1.14187, 1.14187, 1.14187, 1.14187, 1.14187, 1.14187, 1.14187, + 1.14187 }; + + double MMCollisionInt::bstar_table[39*8] = { + 1.1852, 1.2963, 1.2963, 1.2963, 1.2963, 1.2963,1.2963, 1.2963, + 1.1960, 1.216, 1.237, 1.269, 1.285, 1.290, 1.297, 1.294, + 1.2451, 1.257, 1.340, 1.389, 1.366, 1.327, 1.314, 1.278, + 1.2900, 1.294, 1.272, 1.258, 1.262, 1.282, 1.290, 1.299, + 1.2986, 1.291, 1.284, 1.278, 1.277, 1.288, 1.294, 1.297, + 1.2865, 1.281, 1.276, 1.272, 1.277, 1.286, 1.292, 1.298, + 1.2665, 1.264, 1.261, 1.263, 1.269, 1.284, 1.292, 1.298, + 1.2455, 1.244, 1.248, 1.255, 1.262, 1.278, 1.289, 1.296, + 1.2253, 1.225, 1.234, 1.240, 1.252, 1.271, 1.284, 1.295, + 1.2078, 1.210, 1.216, 1.227, 1.242, 1.264, 1.281, 1.292, + 1.1919, 1.192, 1.205, 1.216, 1.230, 1.256, 1.273, 1.287, + 1.1678, 1.172, 1.181, 1.195, 1.209, 1.237, 1.261, 1.277, + 1.1496, 1.155, 1.161, 1.174, 1.189, 1.221, 1.246, 1.266, + 1.1366, 1.141, 1.147, 1.159, 1.174, 1.202, 1.231, 1.256, + 1.1270, 1.130, 1.138, 1.148, 1.162, 1.191, 1.218, 1.242, + 1.1197, 1.122, 1.129, 1.140, 1.149, 1.178, 1.205, 1.231, + 1.1080, 1.110, 1.116, 1.122, 1.132, 1.154, 1.180, 1.205, + 1.1016, 1.103, 1.107, 1.112, 1.120, 1.138, 1.160, 1.183, + 1.0980, 1.099, 1.102, 1.106, 1.112, 1.127, 1.145, 1.165, + 1.0958, 1.097, 1.099, 1.102, 1.107, 1.119, 1.135, 1.153, + 1.0935, 1.094, 1.095, 1.097, 1.100, 1.109, 1.120, 1.134, + 1.0925, 1.092, 1.094, 1.095, 1.098, 1.104, 1.112, 1.122, + 1.0922, 1.092, 1.093, 1.094, 1.096, 1.100, 1.106, 1.115, + 1.0922, 1.092, 1.093, 1.093, 1.095, 1.098, 1.103, 1.110, + 1.0923, 1.092, 1.093, 1.093, 1.094, 1.097, 1.101, 1.106, + 1.0923, 1.092, 1.092, 1.093, 1.094, 1.096, 1.099, 1.103, + 1.0927, 1.093, 1.093, 1.093, 1.094, 1.095, 1.098, 1.101, + 1.0930, 1.093, 1.093, 1.093, 1.094, 1.094, 1.096, 1.099, + 1.0933, 1.094, 1.093, 1.094, 1.094, 1.095, 1.096, 1.098, + 1.0937, 1.093, 1.094, 1.094, 1.094, 1.094, 1.096, 1.097, + 1.0939, 1.094, 1.094, 1.094, 1.094, 1.095, 1.095, 1.097, + 1.0943, 1.094, 1.094, 1.094, 1.095, 1.095, 1.096, 1.096, + 1.0944, 1.095, 1.094, 1.094, 1.094, 1.095, 1.095, 1.096, + 1.0944, 1.094, 1.095, 1.094, 1.094, 1.095, 1.096, 1.096, + 1.0943, 1.095, 1.094, 1.094, 1.095, 1.095, 1.095, 1.095, + 1.0941, 1.094, 1.094, 1.094, 1.094, 1.094, 1.094, 1.096, + 1.0947, 1.095, 1.094, 1.094, 1.093, 1.093, 1.094, 1.095, + 1.0957, 1.095, 1.094, 1.093, 1.092, 1.093, 1.093, 1.094, + 1.10185, 1.10185, 1.10185, 1.10185, 1.10185, 1.10185, 1.10185, + 1.10185}; + + + double MMCollisionInt::cstar_table[39*8] = { + 0.8889, 0.77778, 0.77778,0.77778,0.77778,0.77778,0.77778,0.77778, + 0.88575, 0.8988, 0.8378, 0.8029, 0.7876, 0.7805, 0.7799, 0.7801, + 0.87268, 0.8692,0.8647,0.8479,0.8237,0.7975,0.7881,0.7784, + 0.85182, 0.8525,0.8366,0.8198,0.8054,0.7903,0.7839,0.782, + 0.83542, 0.8362,0.8306,0.8196,0.8076,0.7918,0.7842,0.7806, + 0.82629, 0.8278,0.8252,0.8169,0.8074,0.7916,0.7838,0.7802, + 0.82299, 0.8249,0.823,0.8165,0.8072,0.7922,0.7839,0.7798, + 0.82357, 0.8257,0.8241,0.8178,0.8084,0.7927,0.7839,0.7794, + 0.82657, 0.828,0.8264,0.8199,0.8107,0.7939,0.7842,0.7796, + 0.8311, 0.8234,0.8295,0.8228,0.8136,0.796,0.7854,0.7798, + 0.8363, 0.8366,0.8342,0.8267,0.8168,0.7986,0.7864,0.7805, + 0.84762, 0.8474,0.8438,0.8358,0.825,0.8041,0.7904,0.7822, + 0.85846, 0.8583,0.853,0.8444,0.8336,0.8118,0.7957,0.7854, + 0.8684, 0.8674,0.8619,0.8531,0.8423,0.8186,0.8011,0.7898, + 0.87713, 0.8755,0.8709,0.8616,0.8504,0.8265,0.8072,0.7939, + 0.88479, 0.8831,0.8779,0.8695,0.8578,0.8338,0.8133,0.799, + 0.89972, 0.8986,0.8936,0.8846,0.8742,0.8504,0.8294,0.8125, + 0.91028, 0.9089,0.9043,0.8967,0.8869,0.8649,0.8438,0.8253, + 0.91793, 0.9166,0.9125,0.9058,0.897,0.8768,0.8557,0.8372, + 0.92371, 0.9226,0.9189,0.9128,0.905,0.8861,0.8664,0.8484, + 0.93135, 0.9304,0.9274,0.9226,0.9164,0.9006,0.8833,0.8662, + 0.93607, 0.9353,0.9329,0.9291,0.924,0.9109,0.8958,0.8802, + 0.93927, 0.9387,0.9366,0.9334,0.9292,0.9162,0.905,0.8911, + 0.94149, 0.9409,0.9393,0.9366,0.9331,0.9236,0.9122,0.8997, + 0.94306, 0.9426,0.9412,0.9388,0.9357,0.9276,0.9175,0.9065, + 0.94419, 0.9437,0.9425,0.9406,0.938,0.9308,0.9219,0.9119, + 0.94571, 0.9455,0.9445,0.943,0.9409,0.9353,0.9283,0.9201, + 0.94662, 0.9464,0.9456,0.9444,0.9428,0.9382,0.9325,0.9258, + 0.94723, 0.9471,0.9464,0.9455,0.9442,0.9405,0.9355,0.9298, + 0.94764, 0.9474,0.9469,0.9462,0.945,0.9418,0.9378,0.9328, + 0.9479, 0.9478,0.9474,0.9465,0.9457,0.943,0.9394,0.9352, + 0.94827, 0.9481,0.948,0.9472,0.9467,0.9447,0.9422,0.9391, + 0.94842, 0.9484,0.9481,0.9478,0.9472,0.9458,0.9437,0.9415, + 0.94852, 0.9484,0.9483,0.948,0.9475,0.9465,0.9449,0.943, + 0.94861, 0.9487,0.9484,0.9481,0.9479,0.9468,0.9455,0.943, + 0.94872, 0.9486,0.9486,0.9483,0.9482,0.9475,0.9464,0.9452, + 0.94881, 0.9488,0.9489,0.949,0.9487,0.9482,0.9476,0.9468, + 0.94863, 0.9487,0.9489,0.9491,0.9493,0.9491,0.9483,0.9476, + 0.94444, 0.94444,0.94444,0.94444,0.94444,0.94444,0.94444,0.94444}; + + + void MMCollisionInt::init(XML_Writer* xml, + doublereal tsmin, doublereal tsmax, int log_level) { + ostream& logfile = xml->output(); + m_xml = xml; + m_loglevel = log_level; + m_xml->XML_comment(logfile, "Collision Integral Polynomial Fits"); + m_nmin = -1; + m_nmax = -1; + char p[200]; + for (int n = 0; n < 37; n++) { + if (tsmin > tstar[n+1]) m_nmin = n; + if (tsmax > tstar[n+1]) m_nmax = n+1; + } + if (m_nmin < 0 || m_nmin >= 36 || m_nmax < 0 || m_nmax > 36) { + m_nmin = 0; + } + m_xml->XML_item(logfile, "Tstar_min", tstar[m_nmin + 1]); + m_xml->XML_item(logfile, "Tstar_max", tstar[m_nmax + 1]); + m_logTemp.resize(37); + doublereal rmserr, e22 = 0.0, ea = 0.0, eb = 0.0, ec = 0.0; + + m_xml->XML_open(logfile, "dstar_fits"); + m_xml->XML_comment(logfile, "Collision integral fits at each " + "tabulated T* vs. delta*.\n" + "These polynomial fits are used to interpolate between " + "columns (delta*)\n in the Monchick and Mason tables." + " They are only used for nonzero delta*."); + if (log_level < 4) { + m_xml->XML_comment(logfile, + "polynomial coefficients not printed (log_level < 4)"); + } + + string indent = " "; + for (int i = 0; i < 37; i++) + { + m_logTemp[i] = log(tstar[i+1]); + vector_fp c(DeltaDegree+1); + + rmserr = fitDelta(0, i, DeltaDegree, c.begin()); + if (log_level > 3) { + sprintf(p, " Tstar=\"%12.6g\"", tstar[i+1]); + m_xml->XML_open(logfile, "dstar_fit", p); + m_xml->XML_item(logfile, "Tstar", tstar[i+1]); + m_xml->XML_writeVector(logfile, indent, "omega22", + c.size(), c.begin()); + } + m_o22poly.push_back(c); + if (rmserr > e22) e22 = rmserr; + + rmserr = fitDelta(1, i, DeltaDegree, c.begin()); + m_apoly.push_back(c); + if (log_level > 3) + m_xml->XML_writeVector(logfile, indent, "astar", + c.size(), c.begin()); + if (rmserr > ea) ea = rmserr; + + rmserr = fitDelta(2, i, DeltaDegree, c.begin()); + m_bpoly.push_back(c); + if (log_level > 3) + m_xml->XML_writeVector(logfile, indent, "bstar", + c.size(), c.begin()); + if (rmserr > eb) eb = rmserr; + + rmserr = fitDelta(3, i, DeltaDegree, c.begin()); + m_cpoly.push_back(c); + if (log_level > 3) + m_xml->XML_writeVector(logfile, indent, "cstar", + c.size(), c.begin()); + if (rmserr > ec) ec = rmserr; + + if (log_level > 3) + m_xml->XML_close(logfile, "dstar_fit"); + } + sprintf(p, + "max RMS errors in fits vs. delta*:\n" + " omega_22 = %12.6g \n" + " A* = %12.6g \n" + " B* = %12.6g \n" + " C* = %12.6g \n", e22, ea, eb, ec); + m_xml->XML_comment(logfile, p); + m_xml->XML_close(logfile, "dstar_fits"); + } + + MMCollisionInt::~MMCollisionInt() {} + + + + doublereal MMCollisionInt::fitDelta(int table, int ntstar, + int degree, doublereal* c) { + vector_fp w(8); + doublereal* begin = 0; + int ndeg=0; + switch (table) { + case 0: + begin = omega22_table + 8*ntstar; break; + case 1: + begin = astar_table + 8*(ntstar + 1); break; + case 2: + begin = bstar_table + 8*(ntstar + 1); break; + case 3: + begin = cstar_table + 8*(ntstar + 1); break; + default: + return 0.0; + } + w[0] = -1.0; + return polyfit(8, delta, begin, w.begin(), degree, ndeg, 0.0, c); + } + + doublereal MMCollisionInt::omega22(double ts, double deltastar) { + int i; + for (i = 0; i < 37; i++) if (ts < tstar22[i]) break; + int i1, i2; + i1 = i - 1; + if (i1 < 0) i1 = 0; + i2 = i1+3; + if (i2 > 36) { + i2 = 36; + i1 = i2 - 3; + } + vector_fp values(3); + for (i = i1; i < i2; i++) { + if (deltastar == 0.0) values[i-i1] = omega22_table[8*i]; + else values[i-i1] = poly5(deltastar, m_o22poly[i].begin()); + } + return quadInterp(log(ts), m_logTemp.begin() + i1, values.begin()); + } + + doublereal MMCollisionInt::astar(double ts, double deltastar) { + int i; + for (i = 0; i < 37; i++) if (ts < tstar22[i]) break; + int i1, i2; + i1 = i - 1; + if (i1 < 0) i1 = 0; + i2 = i1+3; + if (i2 > 36) { + i2 = 36; + i1 = i2 - 3; + } + vector_fp values(3); + for (i = i1; i < i2; i++) { + if (deltastar == 0.0) values[i-i1] = astar_table[8*(i + 1)]; + else values[i-i1] = poly5(deltastar, m_apoly[i].begin()); + } + return quadInterp(log(ts), m_logTemp.begin() + i1, values.begin()); + } + + + doublereal MMCollisionInt::bstar(double ts, double deltastar) { + int i; + for (i = 0; i < 37; i++) if (ts < tstar22[i]) break; + int i1, i2; + i1 = i - 1; + if (i1 < 0) i1 = 0; + i2 = i1+3; + if (i2 > 36) { + i2 = 36; + i1 = i2 - 3; + } + vector_fp values(3); + for (i = i1; i < i2; i++) { + if (deltastar == 0.0) values[i-i1] = bstar_table[8*(i + 1)]; + else values[i-i1] = poly5(deltastar, m_bpoly[i].begin()); + } + return quadInterp(log(ts), m_logTemp.begin() + i1, values.begin()); + } + + + doublereal MMCollisionInt::cstar(double ts, double deltastar) { + int i; + for (i = 0; i < 37; i++) if (ts < tstar22[i]) break; + int i1, i2; + i1 = i - 1; + if (i1 < 0) i1 = 0; + i2 = i1+3; + if (i2 > 36) { + i2 = 36; + i1 = i2 - 3; + } + vector_fp values(3); + for (i = i1; i < i2; i++) { + if (deltastar == 0.0) values[i-i1] = cstar_table[8*(i + 1)]; + else values[i-i1] = poly5(deltastar, m_cpoly[i].begin()); + } + return quadInterp(log(ts), m_logTemp.begin() + i1, + values.begin()); } + + + void MMCollisionInt::fit_omega22(int degree, + doublereal deltastar, doublereal* o22) + { + + int i, n = m_nmax - m_nmin + 1; + int ndeg=0; + string indent = " "; + vector_fp values(n); + doublereal rmserr; + vector_fp w(n); + doublereal* logT = m_logTemp.begin() + m_nmin; + for (i = 0; i < n; i++) { + if (deltastar == 0.0) values[i] = omega22_table[8*(i + m_nmin)]; + else values[i] = poly5(deltastar, m_o22poly[i+m_nmin].begin()); + } + w[0]= -1.0; + rmserr = polyfit(n, logT, values.begin(), + w.begin(), degree, ndeg, 0.0, o22); + if (rmserr > 0.01) { + cerr << "Warning: RMS error = " << rmserr << " for omega_22 fit " + << "with delta* = " << deltastar << endl; + } + } + + void MMCollisionInt::fit(ostream& logfile, int degree, + doublereal deltastar, doublereal* a, doublereal* b, doublereal* c) + { + int i, n = m_nmax - m_nmin + 1; + int ndeg=0; + char s[100]; + string indent = " "; + vector_fp values(n); + doublereal rmserr; + vector_fp w(n); + doublereal* logT = m_logTemp.begin() + m_nmin; + for (i = 0; i < n; i++) { + if (deltastar == 0.0) values[i] = astar_table[8*(i + m_nmin + 1)]; + else values[i] = poly5(deltastar, m_apoly[i+m_nmin].begin()); + } + w[0]= -1.0; + rmserr = polyfit(n, logT, values.begin(), + w.begin(), degree, ndeg, 0.0, a); + + for (i = 0; i < n; i++) { + if (deltastar == 0.0) values[i] = bstar_table[8*(i + m_nmin + 1)]; + else values[i] = poly5(deltastar, m_bpoly[i+m_nmin].begin()); + } + w[0]= -1.0; + rmserr = polyfit(n, logT, values.begin(), + w.begin(), degree, ndeg, 0.0, b); + + for (i = 0; i < n; i++) { + if (deltastar == 0.0) values[i] = cstar_table[8*(i + m_nmin + 1)]; + else values[i] = poly5(deltastar, m_cpoly[i+m_nmin].begin()); + } + w[0]= -1.0; + rmserr = polyfit(n, logT, values.begin(), + w.begin(), degree, ndeg, 0.0, c); + + if (m_loglevel > 2) { + char p[100]; + sprintf(p, " dstar=\"%12.6g\"", deltastar); + m_xml->XML_open(logfile, "tstar_fit", p); + + m_xml->XML_writeVector(logfile, indent, "astar", degree+1, a); + if (rmserr > 0.01) { + sprintf(p, "Warning: RMS error = %12.6g for A* fit", rmserr); + m_xml->XML_comment(logfile, s); + } + + m_xml->XML_writeVector(logfile, indent, "bstar", degree+1, b); + if (rmserr > 0.01) { + sprintf(p, "Warning: RMS error = %12.6g for B* fit", rmserr); + m_xml->XML_comment(logfile, s); + } + + m_xml->XML_writeVector(logfile, indent, "cstar", degree+1, c); + + if (rmserr > 0.01) { + sprintf(p, "Warning: RMS error = %12.6g for C* fit", rmserr); + m_xml->XML_comment(logfile, s); + } + m_xml->XML_close(logfile, "tstar_fit"); + } + } + +} // namespace + + + + diff --git a/Cantera/src/transport/MMCollisionInt.h b/Cantera/src/transport/MMCollisionInt.h new file mode 100755 index 000000000..d0b8b4c8e --- /dev/null +++ b/Cantera/src/transport/MMCollisionInt.h @@ -0,0 +1,101 @@ +/** + * @file MMCollisionInt.h + * + * Monk and Monchick collision integrals + */ + +/* + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_MMCOLLISIONINT_H +#define CT_MMCOLLISIONINT_H + +#include +using namespace std; + +#include "../ct_defs.h" + +// turn off warnings under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +namespace Cantera { + + class XML_Writer; + + class MMCollisionIntError { + public: + MMCollisionIntError(ostream& logfile, string msg) { + logfile << "#### ERROR ####" << endl; + logfile << "MMCollisionInt: " << msg << endl; + cerr << "Error in fitting collision integrals. " + << "Execution terminated." << endl + << "See transport log file for more information." << endl; + } + }; + + + /** + * Collision integrals. This class provides functions that + * interpolate the tabulated collision integrals in Monchick and + * Mason, "Transport Properties of Polar Gases," J. Chem. Phys. (1961) + * + * @ingroup transportgroup + */ + class MMCollisionInt { + + public: + + MMCollisionInt(){} + virtual ~MMCollisionInt(); + void init(XML_Writer* xml, doublereal tsmin, + doublereal tsmax, int loglevel = 0); + + doublereal omega22(double ts, double deltastar); + doublereal astar(double tstar, double deltastar); + doublereal bstar(double tstar, double deltastar); + doublereal cstar(double tstar, double deltastar); + + void fit(ostream& logfile, int degree, doublereal deltastar, + doublereal* astar, doublereal* bstar, doublereal* cstar); + + void fit_omega22(int degree, doublereal deltastar, doublereal* om22); + doublereal omega11(double tstar, double deltastar) { + return omega22(tstar, deltastar)/astar(tstar, deltastar); + } + + private: + + doublereal fitDelta(int table, int ntstar, + int degree, doublereal* c); + + vector m_o22poly; + vector m_apoly; + vector m_bpoly; + vector m_cpoly; + + static doublereal delta[8]; + static doublereal tstar22[37]; + static doublereal omega22_table[37*8]; + static doublereal tstar[39]; + static doublereal astar_table[39*8]; + static doublereal bstar_table[39*8]; + static doublereal cstar_table[39*8]; + + vector_fp m_logTemp; + int m_nmin, m_nmax; + XML_Writer* m_xml; + int m_loglevel; + }; +} +#endif + + diff --git a/Cantera/src/transport/Makefile.in b/Cantera/src/transport/Makefile.in new file mode 100644 index 000000000..7f90fc16b --- /dev/null +++ b/Cantera/src/transport/Makefile.in @@ -0,0 +1,53 @@ +#/bin/sh +############################################################### +# $Author$ +# $Date$ +# $Revision$ +# +# Copyright 2002 California Institute of Technology +# +############################################################### + +SUFFIXES= +SUFFIXES= .cpp .d .o + +OBJDIR = . + +CXX_FLAGS = @CXXFLAGS@ $(CXX_OPT) + +# stirred reactors +OBJS = TransportFactory.o MultiTransport.o MixTransport.o MMCollisionInt.o + +CXX_INCLUDES = -I.. +LIB = ./libtransport.a + +DEPENDS = $(OBJS:.o=.d) + +%.d: + g++ -MM $(CXX_INCLUDES) $*.cpp > $*.d + +.cpp.o: + @CXX@ -c $< $(CXX_FLAGS) $(CXX_INCLUDES) + +.f.o: + @F77@ -c $< $(F77_FLAGS) + +all lib: $(LIB) + +$(LIB): $(OBJS) + @ARCHIVE@ $(LIB) $(OBJS) > /dev/null + +clean: + $(RM) *.o *~ $(LIB) + +depends: $(DEPENDS) + cat *.d > .depends + $(RM) $(DEPENDS) + +TAGS: + etags *.h *.cpp + +ifeq ($(wildcard .depends), .depends) +include .depends +endif + diff --git a/Cantera/src/transport/MixTransport.cpp b/Cantera/src/transport/MixTransport.cpp new file mode 100755 index 000000000..12852049e --- /dev/null +++ b/Cantera/src/transport/MixTransport.cpp @@ -0,0 +1,445 @@ +/** + * + * @file MixTransport.cpp + * Mixture-averaged transport properties for ideal gas mixtures. + */ + +/* $Author$ + * $Revision$ + * $Date$ + */ + +// copyright 2001 California Institute of Technology + + +// turn off warnings under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "MixTransport.h" + +#include "utilities.h" +#include "TransportParams.h" + +#include + +/** + * Mole fractions below MIN_X will be set to MIN_X when computing + * transport properties. + */ +#define MIN_X 1.e-20 + + +namespace Cantera { + + //////////////////// class MixTransport methods ////////////// + + + MixTransport::MixTransport() {} + + bool MixTransport::init(TransportParams& tr) { + + // constant substance attributes + //m_phase = tr.mix; + m_thermo = tr.thermo; + m_nsp = m_thermo->nSpecies(); + m_tmin = m_thermo->minTemp(); + m_tmax = m_thermo->maxTemp(); + + // make a local copy of the molecular weights + m_mw.resize(m_nsp); + copy(m_thermo->molecularWeights().begin(), + m_thermo->molecularWeights().end(), m_mw.begin()); + + // copy polynomials and parameters into local storage + m_poly = tr.poly; + m_visccoeffs = tr.visccoeffs; + m_condcoeffs = tr.condcoeffs; + m_diffcoeffs = tr.diffcoeffs; + m_mode = tr.mode; + + m_phi.resize(m_nsp, m_nsp, 0.0); + + m_polytempvec.resize(5); + m_visc.resize(m_nsp); + m_cond.resize(m_nsp); + m_bdiff.resize(m_nsp, m_nsp); + + m_molefracs.resize(m_nsp); + m_spwork.resize(m_nsp); + + // set flags all false + m_viscmix_ok = false; + m_viscwt_ok = false; + m_spvisc_ok = false; + m_spcond_ok = false; + m_condmix_ok = false; + m_spcond_ok = false; + m_diffmix_ok = false; + m_abc_ok = false; + + return true; + } + + + /********************************************************* + * + * Public methods + * + *********************************************************/ + + + /****************** viscosity ******************************/ + + /** + * The viscosity is computed using the Wilke mixture rule. + * \f[ + * \mu = \sum_k \frac{\mu_k X_k}{\sum_j \Phi_{k,j} X_j}. + * \f] + * Here \f$ \mu_k \f$ is the viscosity of pure species \e k, + * and + * \f[ + * \Phi_{k,j} = \frac{\left[1 + * + \sqrt\left(\frac{\mu_k}{\mu_j}\sqrt{\frac{M_j}{M_k}\right)}\right]^2} + * {\sqrt{8}\sqrt{1 + M_k/M_j}} + * \f] + * @see updateViscosity_T(); + */ + doublereal MixTransport::viscosity() { + + update_T(); + update_C(); + + if (m_viscmix_ok) return m_viscmix; + + doublereal vismix = 0.0, denom; + int k, j; + + // update m_visc and m_phi if necessary + if (!m_viscwt_ok) updateViscosity_T(); + + for (k = 0; k < m_nsp; k++) { + denom = 0.0; + for (j = 0; j < m_nsp; j++) { + denom += m_phi(k,j) * m_molefracs[j]; + } + vismix += m_molefracs[k] * m_visc[k]/denom; + } + m_viscmix = vismix; + return vismix; + } + + + /******************* binary diffusion coefficients **************/ + + + void MixTransport::getBinaryDiffCoeffs(int ld, doublereal* d) { + int i,j; + + update_T(); + + // if necessary, evaluate the binary diffusion coefficents + // from the polynomial fits + if (!m_bindiff_ok) updateDiff_T(); + + doublereal rp = 1.0/pressure_ig(); + for (i = 0; i < m_nsp; i++) + for (j = 0; j < m_nsp; j++) { + d[ld*j + i] = rp * m_bdiff(i,j); + } + } + + + void MixTransport::getMobilities(doublereal* mobil) { + int k; + getMixDiffCoeffs(m_spwork.begin()); + doublereal c1 = ElectronCharge / (Boltzmann * m_temp); + for (k = 0; k < m_nsp; k++) { + mobil[k] = c1 * m_spwork[k] * m_thermo->charge(k); + } + } + + + /****************** thermal conductivity **********************/ + + /** + * The thermal conductivity is computed from the following mixture rule: + * \[ + * \lambda = 0.5 \left( \sum_k X_k \lambda_k + * + \frac{1}{\sum_k X_k/\lambda_k}\right) + * \] + */ + doublereal MixTransport::thermalConductivity() { + int k; + + update_T(); + update_C(); + + if (!m_spcond_ok) updateCond_T(); + if (!m_condmix_ok) { + doublereal sum1 = 0.0, sum2 = 0.0; + for (k = 0; k < m_nsp; k++) { + sum1 += m_molefracs[k] * m_cond[k]; + sum2 += m_molefracs[k] / m_cond[k]; + } + m_lambda = 0.5*(sum1 + 1.0/sum2); + } + return m_lambda; + } + + + /****************** thermal diffusion coefficients ************/ + + /** + * Thermal diffusion is not considered in this mixture-averaged + * model. To include thermal diffusion, use transport manager + * MultiTransport instead. This methods fills out array dt with + * zeros. + */ + void MixTransport::getThermalDiffCoeffs(doublereal* dt) { + int k; + for (k = 0; k < m_nsp; k++) { + dt[k] = 0.0; + } + } + + /** + * @param ndim The number of spatial dimensions (1, 2, or 3). + * @param grad_T The temperature gradient (ignored in this model). + * @param ldx Leading dimension of the grad_X array. + * The diffusive mass flux of species \e k is computed from + * \f[ + * \vec{j}_k = -n M_k D_k \nabla X_k. + * \f] + */ + void MixTransport::getSpeciesFluxes(int ndim, + doublereal* grad_T, int ldx, const doublereal* grad_X, + int ldf, doublereal* fluxes) { + int n, k; + + update_T(); + update_C(); + + getMixDiffCoeffs(m_spwork.begin()); + + const array_fp& mw = m_thermo->molecularWeights(); + const doublereal* y = m_thermo->massFractions(); + doublereal rhon = m_thermo->molarDensity(); + + vector_fp sum(ndim,0.0); + for (n = 0; n < ndim; n++) { + for (k = 0; k < m_nsp; k++) { + fluxes[n*ldf + k] = -rhon * mw[k] * m_spwork[k] * grad_X[n*ldx + k]; + sum[n] += fluxes[n*ldf + k]; + } + } + // add correction flux to enforce sum to zero + for (n = 0; n < ndim; n++) { + for (k = 0; k < m_nsp; k++) { + fluxes[n*ldf + k] -= y[k]*sum[n]; + } + } + } + + + void MixTransport::getMixDiffCoeffs(doublereal* d) { + + update_T(); + update_C(); + + // update the binary diffusion coefficients if necessary + if (!m_bindiff_ok) updateDiff_T(); + + int k, j; + doublereal mmw = m_thermo->meanMolecularWeight(); + doublereal sumxw = 0.0, sum2; + doublereal p = pressure_ig(); + for (k = 0; k < m_nsp; k++) sumxw += m_molefracs[k] * m_mw[k]; + for (k = 0; k < m_nsp; k++) { + sum2 = 0.0; + for (j = 0; j < m_nsp; j++) { + if (j != k) { + sum2 += m_molefracs[j] / m_bdiff(j,k); + } + } + d[k] = (sumxw - m_molefracs[k] * m_mw[k])/(p * mmw * sum2); + } + } + + + /** + * @internal This is called whenever a transport property is + * requested from ThermoSubstance if the temperature has changed + * since the last call to update_T. + */ + void MixTransport::update_T() + { + doublereal t = m_thermo->temperature(); + if (t == m_temp) return; + if (t < 0.0) { + throw CanteraError("MixTransport::update_T", + "negative temperature "+fp2str(t)); + } + m_temp = t; + m_logt = log(m_temp); + m_kbt = Boltzmann * m_temp; + m_sqrt_t = sqrt(m_temp); + m_t32 = m_temp * m_sqrt_t; + m_sqrt_kbt = sqrt(Boltzmann*m_temp); + + // compute powers of log(T) + m_polytempvec[0] = 1.0; + m_polytempvec[1] = m_logt; + m_polytempvec[2] = m_logt*m_logt; + m_polytempvec[3] = m_logt*m_logt*m_logt; + m_polytempvec[4] = m_logt*m_logt*m_logt*m_logt; + + // temperature has changed, so polynomial fits will need to be + // redone. + m_viscmix_ok = false; + m_spvisc_ok = false; + m_viscwt_ok = false; + m_spcond_ok = false; + m_diffmix_ok = false; + m_bindiff_ok = false; + m_abc_ok = false; + m_condmix_ok = false; + } + + /** + * @internal This is called the first time any transport property + * is requested from Mixture after the concentrations + * have changed. + */ + void MixTransport::update_C() + { + // signal that concentration-dependent quantities will need to + // be recomputed before use, and update the local mole + // fractions. + + m_viscmix_ok = false; + m_diffmix_ok = false; + m_condmix_ok = false; + + m_thermo->getMoleFractions(m_molefracs.begin()); + + // add an offset to avoid a pure species condition + int k; + for (k = 0; k < m_nsp; k++) { + m_molefracs[k] = fmaxx(MIN_X, m_molefracs[k]); + } + } + + + /************************************************************************* + * + * methods to update temperature-dependent properties + * + *************************************************************************/ + + /** + * Update the temperature-dependent parts of the mixture-averaged + * thermal conductivity. + */ + void MixTransport::updateCond_T() { + + int k; + if (m_mode == CK_Mode) { + for (k = 0; k < m_nsp; k++) { + m_cond[k] = exp(dot4(m_polytempvec, m_condcoeffs[k])); + } + } + else { + for (k = 0; k < m_nsp; k++) { + m_cond[k] = m_sqrt_t*dot5(m_polytempvec, m_condcoeffs[k]); + } + } + m_spcond_ok = true; + m_condmix_ok = false; + } + + + /** + * Update the binary diffusion coefficients. These are evaluated + * from the polynomial fits at unit pressure (1 Pa). + */ + void MixTransport::updateDiff_T() { + + // evaluate binary diffusion coefficients at unit pressure + int i,j; + int ic = 0; + if (m_mode == CK_Mode) { + for (i = 0; i < m_nsp; i++) { + for (j = i; j < m_nsp; j++) { + m_bdiff(i,j) = exp(dot4(m_polytempvec, m_diffcoeffs[ic])); + m_bdiff(j,i) = m_bdiff(i,j); + ic++; + } + } + } + else { + for (i = 0; i < m_nsp; i++) { + for (j = i; j < m_nsp; j++) { + m_bdiff(i,j) = m_temp * m_sqrt_t*dot5(m_polytempvec, + m_diffcoeffs[ic]); + m_bdiff(j,i) = m_bdiff(i,j); + ic++; + } + } + } + + m_bindiff_ok = true; + m_diffmix_ok = false; + } + + + /** + * Update the pure-species viscosities. + */ + void MixTransport::updateSpeciesViscosities() { + + int k; + if (m_mode == CK_Mode) { + for (k = 0; k < m_nsp; k++) { + m_visc[k] = exp(dot4(m_polytempvec, m_visccoeffs[k])); + } + } + else { + for (k = 0; k < m_nsp; k++) { + m_visc[k] = m_sqrt_t*dot5(m_polytempvec, m_visccoeffs[k]); + } + } + m_spvisc_ok = true; + } + + + /** + * Update the temperature-dependent viscosity terms. + * Updates the array of pure species viscosities, and the + * weighting functions in the viscosity mixture rule. + * The flag m_visc_ok is set to true. + */ + void MixTransport::updateViscosity_T() { + doublereal vratiokj, wratiojk, rootwjk, factor1; + + if (!m_spvisc_ok) updateSpeciesViscosities(); + + // see Eq. (9-5.15) of Reid, Prausnitz, and Poling + int j, k; + for (j = 0; j < m_nsp; j++) { + for (k = j; k < m_nsp; k++) { + vratiokj = m_visc[k]/m_visc[j]; + wratiojk = m_mw[j]/m_mw[k]; + rootwjk = sqrt(wratiojk); + factor1 = 1.0 + sqrt(vratiokj * rootwjk); + m_phi(k,j) = factor1*factor1 / + (SqrtEight * sqrt(1.0 + m_mw[k]/m_mw[j])); + m_phi(j,k) = m_phi(k,j)/(vratiokj * wratiojk); + } + } + m_viscwt_ok = true; + } + +} diff --git a/Cantera/src/transport/MixTransport.h b/Cantera/src/transport/MixTransport.h new file mode 100755 index 000000000..f3c752288 --- /dev/null +++ b/Cantera/src/transport/MixTransport.h @@ -0,0 +1,171 @@ +/** + * + * @file MixTransport.h + * Header file defining class MixTransport + */ + +/* $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_MIXTRAN_H +#define CT_MIXTRAN_H + + +// turn off warnings under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +// STL includes +#include +#include +#include +#include +#include + +using namespace std; + +// Cantera includes +#include "TransportBase.h" +#include "../DenseMatrix.h" + +namespace Cantera { + + + class TransportParams; + + /** + * Class MixTransport implements mixture-averaged transport + * properties for ideal gas mixtures. The model is based on that + * described by Kee, Coltrin, and Glarborg, "Theoretical and + * Practical Aspects of Chemically Reacting Flow Modeling." + */ + class MixTransport : public Transport { + + public: + + virtual ~MixTransport() {} + + virtual int model() { return cMixtureAveraged; } + + // overloaded base class methods + virtual doublereal viscosity(); + + + virtual void getSpeciesViscosities(doublereal* visc) + { updateViscosity_T(); copy(m_visc.begin(), m_visc.end(), visc); } + + virtual void getThermalDiffCoeffs(doublereal* dt); + virtual doublereal thermalConductivity(); + + virtual void getBinaryDiffCoeffs(int ld, doublereal* d); + virtual void getMixDiffCoeffs(doublereal* d); + virtual void getMobilities(doublereal* mobil); + virtual void update_T(); + virtual void update_C(); + + virtual void getSpeciesFluxes(int ndim, + doublereal* grad_T, int ldx, const doublereal* grad_X, + int ldf, doublereal* fluxes); + + virtual bool init(TransportParams& tr); + + friend class TransportFactory; + + protected: + + /// default constructor + MixTransport(); + + private: + + + doublereal pressure_ig() { + return m_thermo->molarDensity() * GasConstant * m_thermo->temperature(); + } + + // mixture attributes + int m_nsp; + doublereal m_tmin, m_tmax; + vector_fp m_mw; + + // polynomial fits + vector m_visccoeffs; + vector m_condcoeffs; + vector m_diffcoeffs; + vector_fp m_polytempvec; + + // property values + DenseMatrix m_bdiff; + vector_fp m_visc; + vector_fp m_cond; + + array_fp m_molefracs; + + vector > m_poly; + vector m_astar_poly; + vector m_bstar_poly; + vector m_cstar_poly; + vector m_om22_poly; + DenseMatrix m_astar; + DenseMatrix m_bstar; + DenseMatrix m_cstar; + DenseMatrix m_om22; + + DenseMatrix m_phi; // viscosity weighting functions + + vector_fp m_zrot; + vector_fp m_crot; + vector_fp m_cinternal; + vector_fp m_eps; + + doublereal m_temp, m_logt, m_kbt, m_t32; + doublereal m_sqrt_kbt, m_sqrt_t; + + vector_fp m_sqrt_eps_k; + DenseMatrix m_log_eps_k; + vector_fp m_frot_298; + vector_fp m_rotrelax; + + doublereal m_lambda; + doublereal m_viscmix; + + // work space + vector_fp m_spwork; + + void updateThermal_T(); + void updateViscosity_T(); + void updateCond_T(); + void updateSpeciesViscosities(); + void updateDiff_T(); + void correctBinDiffCoeffs(); + bool m_viscmix_ok; + bool m_viscwt_ok; + bool m_spvisc_ok; + bool m_diffmix_ok; + bool m_bindiff_ok; + bool m_abc_ok; + bool m_spcond_ok; + bool m_condmix_ok; + + int m_mode; + + DenseMatrix m_epsilon; + DenseMatrix m_diam; + DenseMatrix incl; + bool m_debug; + }; +} +#endif + + + + + + diff --git a/Cantera/src/transport/MultiTransport.cpp b/Cantera/src/transport/MultiTransport.cpp new file mode 100755 index 000000000..b408d2540 --- /dev/null +++ b/Cantera/src/transport/MultiTransport.cpp @@ -0,0 +1,780 @@ +/** + * + * @file MultiTransport.cpp + * Implementation file for class MultiTransport + * + * @ingroup transportProps + * + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2001 California Institute of Technology + * See file License.txt for licensing information + * + */ + + +// turn off warnings under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "MultiTransport.h" +#include "ctlapack.h" +#include "../../ext/math/gmres.h" + +#include "DenseMatrix.h" +#include "polyfit.h" +#include "utilities.h" +#include "L_matrix.h" +#include "TransportParams.h" +#include "IdealGasPhase.h" + +#include + +/** + * Mole fractions below MIN_X will be set to MIN_X when computing + * transport properties. + */ + +#define MIN_X 1.e-20 + + +namespace Cantera { + + + template + struct UpdateSpeciesVisc : public Updater { + UpdateSpeciesVisc(S& s) : Updater(), m_s(s) {} + void update() { m_s._update_species_visc_T(); } + S& m_s; + }; + + template + struct UpdateVisc_T : public Updater { + UpdateVisc_T(S& s) : Updater(), m_s(s) {} + void update() { m_s._update_visc_T(); } + S& m_s; + }; + + template + struct UpdateDiff_T : public Updater { + UpdateDiff_T(S& s) : Updater(), m_s(s) {} + void update() { m_s._update_diff_T(); } + S& m_s; + }; + + template + struct UpdateThermal_T : public Updater { + UpdateThermal_T(S& s) : Updater(), m_s(s) {} + void update() { m_s._update_thermal_T(); } + S& m_s; + }; + + + /////////////////////////// constants ////////////////////////// + + const doublereal ThreeSixteenths = 3.0/16.0; + + + + ///////////////////// helper functions ///////////////////////// + + + /** + * @internal + * + * The Parker temperature correction to the rotational collision + * number. + * + * @param tr Reduced temperature \f$ \epsilon/kT \f$ + * @param sqtr square root of tr. + */ + inline doublereal Frot(doublereal tr, doublereal sqtr) { + const doublereal c1 = 0.5*SqrtPi*Pi; + const doublereal c2 = 0.25*Pi*Pi + 2.0; + const doublereal c3 = SqrtPi*Pi; + return 1.0 + c1*sqtr + c2*tr + c3*sqtr*tr; + } + + + /** + * This method is used by GMRES to multiply the L matrix by a + * vector b. The L matrix has a 3x3 block structure, where each + * block is a K x K matrix. The elements of the upper-right and + * lower-left blocks are all zero. This method is defined so + * that the multiplication only involves the seven non-zero + * blocks. + */ + void L_Matrix::mult(const doublereal* b, doublereal* prod) const { + integer n = nRows()/3; + integer n2 = 2*n; + integer n3 = 3*n; + ct_dgemv(ctlapack::ColMajor, ctlapack::NoTranspose, n, n2, 1.0, + data().begin(), nRows(), b, 1, 0.0, prod, 1); + ct_dgemv(ctlapack::ColMajor, ctlapack::NoTranspose, n, n3, 1.0, + data().begin() + n, nRows(), b, 1, 0.0, prod+n, 1); + ct_dgemv(ctlapack::ColMajor, ctlapack::NoTranspose, n, n, 1.0, + data().begin() + n*n3 + n2, nRows(), b + n, 1, 0.0, prod+n2, 1); + for (int i = 0; i < n; i++) + prod[i + n2] += b[i + n2] * value(i + n2, i + n2); + } + + //////////////////// class MultiTransport methods ////////////// + + + MultiTransport::MultiTransport(thermo_t* thermo) + : Transport(thermo) {} + + bool MultiTransport::init(TransportParams& tr) { + + // constant mixture attributes + //m_phase = tr.mix; + m_thermo = tr.thermo; + m_nsp = m_thermo->nSpecies(); + m_tmin = m_thermo->minTemp(); + m_tmax = m_thermo->maxTemp(); + + // make a local copy of the molecular weights + m_mw.resize(m_nsp); + copy(m_thermo->molecularWeights().begin(), + m_thermo->molecularWeights().end(), m_mw.begin()); + + // copy polynomials and parameters into local storage + m_poly = tr.poly; + m_visccoeffs = tr.visccoeffs; + m_diffcoeffs = tr.diffcoeffs; + m_astar_poly = tr.astar_poly; + m_bstar_poly = tr.bstar_poly; + m_cstar_poly = tr.cstar_poly; + m_om22_poly = tr.omega22_poly; + m_zrot = tr.zrot; + m_crot = tr.crot; + m_epsilon = tr.epsilon; + m_mode = tr.mode; + m_diam = tr.diam; + m_eps = tr.eps; + + // the L matrix + m_Lmatrix.resize(3*m_nsp, 3*m_nsp); + m_a.resize(3*m_nsp, 1.0); + m_b.resize(3*m_nsp, 0.0); + m_aa.resize(m_nsp, m_nsp, 0.0); + + m_frot_298.resize(m_nsp); + m_rotrelax.resize(m_nsp); + + m_phi.resize(m_nsp, m_nsp, 0.0); + m_cinternal.resize(m_nsp); + + m_polytempvec.resize(5); + m_visc.resize(m_nsp); + m_bdiff.resize(m_nsp, m_nsp); + + //m_poly.resize(m_nsp); + m_om22.resize(m_nsp, m_nsp); + m_astar.resize(m_nsp, m_nsp); + m_bstar.resize(m_nsp, m_nsp); + m_cstar.resize(m_nsp, m_nsp); + + m_molefracs.resize(m_nsp); + + // set flags all false + m_visc_ok = false; + m_spvisc_ok = false; + m_diff_ok = false; + m_abc_ok = false; + m_l0000_ok = false; + m_lmatrix_soln_ok = false; + + // use LU decomposition by default + m_gmres = false; + + // default GMRES parameters + m_mgmres = 100; + m_eps_gmres = 1.e-4; + + // some work space + m_spwork.resize(m_nsp); + + + // precompute and store log(epsilon_ij/k_B) + m_log_eps_k.resize(m_nsp, m_nsp); + int i, j; + for (i = 0; i < m_nsp; i++) { + for (j = i; j < m_nsp; j++) { + m_log_eps_k(i,j) = log(tr.epsilon(i,j)/Boltzmann); + m_log_eps_k(j,i) = m_log_eps_k(i,j); + } + } + + + // precompute and store constant parts of the Parker rotational + // collision number temperature correction + const doublereal sq298 = sqrt(298.0); + const doublereal kb298 = Boltzmann * 298.0; + m_sqrt_eps_k.resize(m_nsp); + int k; + for (k = 0; k < m_nsp; k++) { + m_sqrt_eps_k[k] = sqrt(tr.eps[k]/Boltzmann); + m_frot_298[k] = Frot( tr.eps[k]/kb298, + m_sqrt_eps_k[k]/sq298); + } + + // install updaters + m_update_transport_T = m_thermo->installUpdater_T( + new UpdateTransport_T(*this)); + m_update_transport_C = m_thermo->installUpdater_C( + new UpdateTransport_C(*this)); + m_update_spvisc_T = m_thermo->installUpdater_T( + new UpdateSpeciesVisc(*this)); + m_update_visc_T = m_thermo->installUpdater_T( + new UpdateVisc_T(*this)); + m_update_diff_T = m_thermo->installUpdater_T( + new UpdateDiff_T(*this)); + m_update_thermal_T = m_thermo->installUpdater_T( + new UpdateThermal_T(*this)); + + return true; + } + + + /****************** viscosity ******************************/ + + doublereal MultiTransport::viscosity() { + doublereal vismix = 0.0, denom; + int k, j; + + // update m_visc if necessary + updateViscosity_T(); + + // update the mole fractions + updateTransport_C(); + + for (k = 0; k < m_nsp; k++) { + denom = 0.0; + for (j = 0; j < m_nsp; j++) { + denom += m_phi(k,j) * m_molefracs[j]; + } + vismix += m_molefracs[k] * m_visc[k]/denom; + } + return vismix; + } + + + + /******************* binary diffusion coefficients **************/ + + void MultiTransport::getBinaryDiffCoeffs(int ld, doublereal* d) { + int i,j; + + // if necessary, evaluate the binary diffusion coefficents + // from the polynomial fits + updateDiff_T(); + + doublereal p = pressure_ig(); + doublereal rp = 1.0/p; + for (i = 0; i < m_nsp; i++) + for (j = 0; j < m_nsp; j++) { + d[ld*j + i] = rp * m_bdiff(i,j); + } + } + + + + /****************** thermal conductivity **********************/ + + /** + * @internal + */ + doublereal MultiTransport::thermalConductivity() { + + solveLMatrixEquation(); + doublereal sum = 0.0; + int k; + for (k = 0; k < 2*m_nsp; k++) { + sum += m_b[k + m_nsp] * m_a[k + m_nsp]; + } + return -4.0*sum; + } + + + /****************** thermal diffusion coefficients ************/ + + /** + * @internal + */ + void MultiTransport::getThermalDiffCoeffs(doublereal* dt) { + + solveLMatrixEquation(); + const doublereal c = 1.6/GasConstant; + int k; + for (k = 0; k < m_nsp; k++) { + dt[k] = c * m_mw[k] * m_molefracs[k] * m_a[k]; + } + } + + + /** + * @internal + */ + void MultiTransport::solveLMatrixEquation() { + + // if T has changed, update the temperature-dependent + // properties. + + updateThermal_T(); + updateTransport_C(); + + // Copy the mole fractions twice into the last two blocks of + // the right-hand-side vector m_b. The first block of m_b was + // set to zero when it was created, and is not modified so + // doesn't need to be reset to zero. + int k; + for (k = 0; k < m_nsp; k++) { + m_b[k] = 0.0; + m_b[k + m_nsp] = m_molefracs[k]; + m_b[k + 2*m_nsp] = m_molefracs[k]; + } + + // Set the right-hand side vector to zero in the 3rd block for + // all species with no internal energy modes. The + // corresponding third-block rows and columns will be set to + // zero, except on the diagonal of L01,01, where they are set + // to 1.0. This has the effect of eliminating these equations + // from the system, since the equation becomes: m_a[2*m_nsp + + // k] = 0.0. + + // Note that this differs from the Chemkin procedure, where + // all *monatomic* species are excluded. Since monatomic + // radicals can have non-zero internal heat capacities due to + // electronic excitation, they should be retained. + // + // But if CHEMKIN_COMPATIBILITY_MODE is defined, then all + // monatomic species are excluded. + + for (k = 0; k < m_nsp; k++) { + if (!hasInternalModes(k)) m_b[2*m_nsp + k] = 0.0; + } + + // evaluate the submatrices of the L matrix + + m_Lmatrix.resize(3*m_nsp, 3*m_nsp, 0.0); + + eval_L0000(m_molefracs.begin()); + eval_L0010(m_molefracs.begin()); + eval_L0001(); + eval_L1000(); + eval_L1010(m_molefracs.begin()); + eval_L1001(m_molefracs.begin()); + eval_L0100(); + eval_L0110(); + eval_L0101(m_molefracs.begin()); + + + // Solve it using GMRES or LU decomposition. The last solution + // in m_a should provide a good starting guess, so convergence + // should be fast. + + if (m_gmres) { + gmres(m_mgmres, 3*m_nsp, m_Lmatrix, m_b.begin(), + m_a.begin(), m_eps_gmres); + m_lmatrix_soln_ok = true; + m_l0000_ok = true; // L matrix not modified by GMRES + } + else { + copy(m_b.begin(), m_b.end(), m_a.begin()); + int info = solve(m_Lmatrix, m_a.begin()); + if (info != 0) { + throw CanteraError("MultiTransport::solveLMatrixEquation", + "error in solving L matrix."); + } + m_lmatrix_soln_ok = true; + m_l0000_ok = false; + // L matrix is overwritten with LU decomposition + } + m_lmatrix_soln_ok = true; + } + + + /** + * + */ + void MultiTransport::getSpeciesFluxes(int ndim, + doublereal* grad_T, int ldx, const doublereal* grad_X, + int ldf, doublereal* fluxes) { + + // update the binary diffusion coefficients if necessary + updateDiff_T(); + + doublereal sum; + int i, j; + + // If any component of grad_T is non-zero, then get the + // thermal diffusion coefficients + + bool addThermalDiffusion = false; + for (i = 0; i < ndim; i++) { + if (grad_T[i] != 0.0) addThermalDiffusion = true; + } + if (addThermalDiffusion) getThermalDiffCoeffs(m_spwork.begin()); + + const doublereal* y = m_thermo->massFractions(); + doublereal rho = m_thermo->density(); + + for (i = 0; i < m_nsp; i++) { + sum = 0.0; + for (j = 0; j < m_nsp; j++) { + m_aa(i,j) = m_molefracs[j]*m_molefracs[i]/m_bdiff(i,j); + sum += m_aa(i,j); + } + m_aa(i,i) -= sum; + } + + // enforce the condition \sum Y_k V_k = 0. This is done by replacing + // the flux equation with the largest gradx component in the first + // coordinate direction with the flux balance condition. + int jmax = 0; + doublereal gradmax = -1.0; + for (j = 0; j < m_nsp; j++) { + if (fabs(grad_X[j]) > gradmax) { + gradmax = fabs(grad_X[j]); + jmax = j; + } + } + + // set the matrix elements in this row to the mass fractions, + // and set the entry in gradx to zero + + for (j = 0; j < m_nsp; j++) { + m_aa(jmax,j) = y[j]; + } + vector_fp gsave(ndim), grx(ldx*m_nsp); + int n; + for (n = 0; n < ldx*ndim; n++) { + grx[n] = grad_X[n]; + } + //for (n = 0; n < ndim; n++) { + // gsave[n] = grad_X[jmax + n*ldx]; // save the input mole frac gradient + //grad_X[jmax + n*ldx] = 0.0; + // grx[jmax + n*ldx] = 0.0; + // } + + // copy grad_X to fluxes + const doublereal* gx; + for (n = 0; n < ndim; n++) { + gx = grad_X + ldx*n; + copy(gx, gx + m_nsp, fluxes + ldf*n); + fluxes[jmax + n*ldf] = 0.0; + } + + // use LAPACK to solve the equations + int info=0; + ct_dgetrf(m_aa.nRows(), m_aa.nColumns(), m_aa.begin(), m_aa.nRows(), + m_aa.ipiv().begin(), info); + if (info == 0) { + ct_dgetrs(ctlapack::NoTranspose, m_aa.nRows(), ndim, + m_aa.begin(), m_aa.nRows(), + m_aa.ipiv().begin(), fluxes, ldf, info); + if (info != 0) info += 100; + } + else + throw CanteraError("MultiTransport::getSpeciesFluxes", + "Error in DGETRF"); + if (info > 50) + throw CanteraError("MultiTransport::getSpeciesFluxes", + "Error in DGETRS"); + + + int offset; + doublereal pp = pressure_ig(); + + // multiply diffusion velocities by rho * V to create + // mass fluxes, and restore the gradx elements that were + // modified + for (n = 0; n < ndim; n++) { + offset = n*ldf; + for (i = 0; i < m_nsp; i++) { + fluxes[i + offset] *= rho * y[i] / pp; + } + //grad_X[jmax + n*ldx] = gsave[n]; + } + + // thermal diffusion + if (addThermalDiffusion) { + for (n = 0; n < ndim; n++) { + offset = n*ldf; + doublereal grad_logt = grad_T[n]/m_temp; + for (i = 0; i < m_nsp; i++) + fluxes[i + offset] -= m_spwork[i]*grad_logt; + } + } + } + + + void MultiTransport::getMultiDiffCoeffs(int ld, doublereal* d) { + int i,j; + + doublereal p = pressure_ig(); + + // update the mole fractions + updateTransport_C(); + + // update the binary diffusion coefficients + updateDiff_T(); + + // evaluate L0000 if the temperature or concentrations have + // changed since it was last evaluated. + if (!m_l0000_ok) eval_L0000(m_molefracs.begin()); + + // invert L00,00 + int ierr = invert(m_Lmatrix, m_nsp); + if (ierr != 0) { + cout << " invert returned ierr = " << ierr << endl; + exit(1); + } + m_l0000_ok = false; // matrix is overwritten by inverse + + //doublereal pres = m_thermo->pressure(); + doublereal prefactor = 16.0 * m_temp + * m_thermo->meanMolecularWeight()/(25.0 * p); + doublereal c; + + for (i = 0; i < m_nsp; i++) { + for (j = 0; j < m_nsp; j++) { + c = prefactor/m_mw[j]; + d[ld*j + i] = c*m_molefracs[i]* + (m_Lmatrix(i,j) - m_Lmatrix(i,i)); + } + } + } + + + /** + * Update temperature-dependent quantities. This method is called + * by the temperature property updater. + */ + void MultiTransport::_update_transport_T() + { + //if (m_temp == m_thermo->temperature()) return; + + m_temp = m_thermo->temperature(); + m_logt = log(m_temp); + m_kbt = Boltzmann * m_temp; + m_sqrt_t = sqrt(m_temp); + m_t32 = m_temp * m_sqrt_t; + m_sqrt_kbt = sqrt(Boltzmann*m_temp); + + // compute powers of log(T) + m_polytempvec[0] = 1.0; + m_polytempvec[1] = m_logt; + m_polytempvec[2] = m_logt*m_logt; + m_polytempvec[3] = m_logt*m_logt*m_logt; + m_polytempvec[4] = m_logt*m_logt*m_logt*m_logt; + + // temperature has changed, so polynomial fits will need to be + // redone, and the L matrix reevaluated. + m_visc_ok = false; + m_spvisc_ok = false; + m_diff_ok = false; + m_abc_ok = false; + m_lmatrix_soln_ok = false; + m_l0000_ok = false; + } + + /** + * This is called the first time any transport property + * is requested from ThermoSubstance after the concentrations + * have changed. + */ + void MultiTransport::_update_transport_C() + { + // signal that concentration-dependent quantities will need to + // be recomputed before use, and update the local mole + // fraction array. + m_l0000_ok = false; + m_lmatrix_soln_ok = false; + m_thermo->getMoleFractions(m_molefracs.begin()); + + + // add an offset to avoid a pure species condition + // (check - this may be unnecessary) + int k; + for (k = 0; k < m_nsp; k++) { + m_molefracs[k] = fmaxx(MIN_X, m_molefracs[k]); + } + } + + + /************************************************************************* + * + * methods to update temperature-dependent properties + * + *************************************************************************/ + + /** + * @internal + * Update the binary diffusion coefficients. These are evaluated + * from the polynomial fits at unit pressure (1 Pa). + */ + void MultiTransport::updateDiff_T() { + m_thermo->update_T(m_update_diff_T); + } + + void MultiTransport::_update_diff_T() { + + updateTransport_T(); + + // evaluate binary diffusion coefficients at unit pressure + int i,j; + int ic = 0; + if (m_mode == CK_Mode) { + for (i = 0; i < m_nsp; i++) { + for (j = i; j < m_nsp; j++) { + m_bdiff(i,j) = exp(dot4(m_polytempvec, m_diffcoeffs[ic])); + m_bdiff(j,i) = m_bdiff(i,j); + ic++; + } + } + } + else { + for (i = 0; i < m_nsp; i++) { + for (j = i; j < m_nsp; j++) { + m_bdiff(i,j) = m_temp * m_sqrt_t*dot5(m_polytempvec, + m_diffcoeffs[ic]); + m_bdiff(j,i) = m_bdiff(i,j); + ic++; + } + } + } + m_diff_ok = true; + } + + + /** + * @internal + * Update the temperature-dependent viscosity terms. + * Updates the array of pure species viscosities, and the + * weighting functions in the viscosity mixture rule. + * The flag m_visc_ok is set to true. + */ + void MultiTransport::updateSpeciesViscosities_T() { + m_thermo->update_T(m_update_spvisc_T); + } + + + void MultiTransport::_update_species_visc_T() { + + updateTransport_T(); + + int k; + if (m_mode == CK_Mode) { + for (k = 0; k < m_nsp; k++) { + m_visc[k] = exp(dot4(m_polytempvec, m_visccoeffs[k])); + } + } + else { + for (k = 0; k < m_nsp; k++) { + m_visc[k] = m_sqrt_t*dot5(m_polytempvec, m_visccoeffs[k]); + } + } + m_spvisc_ok = true; + } + + /** + * @internal + */ + void MultiTransport::updateViscosity_T() { + m_thermo->update_T(m_update_visc_T); + } + + void MultiTransport::_update_visc_T() { + doublereal vratiokj, wratiojk, rootwjk, factor1; + + updateSpeciesViscosities_T(); + + // see Eq. (9-5.15) of Reid, Prausnitz, and Poling + int j, k; + for (j = 0; j < m_nsp; j++) { + for (k = j; k < m_nsp; k++) { + vratiokj = m_visc[k]/m_visc[j]; + wratiojk = m_mw[j]/m_mw[k]; + rootwjk = sqrt(wratiojk); + factor1 = 1.0 + sqrt(vratiokj * rootwjk); + m_phi(k,j) = factor1*factor1 / + (SqrtEight * sqrt(1.0 + m_mw[k]/m_mw[j])); + m_phi(j,k) = m_phi(k,j)/(vratiokj * wratiojk); + } + } + m_visc_ok = true; + } + + + /** + * @internal + * Update the temperature-dependent terms needed to compute the + * thermal conductivity and thermal diffusion coefficients. + */ + void MultiTransport::updateThermal_T() { + m_thermo->update_T(m_update_thermal_T); + } + + void MultiTransport::_update_thermal_T() { + // we need species viscosities and binary diffusion + // coefficients + updateSpeciesViscosities_T(); + updateDiff_T(); + + // evaluate polynomial fits for A*, B*, C* + doublereal z; + int ipoly; + int i, j; + for (i = 0; i < m_nsp; i++) { + for (j = i; j < m_nsp; j++) { + z = m_logt - m_log_eps_k(i,j); + ipoly = m_poly[i][j]; + if (m_mode == CK_Mode) { + m_om22(i,j) = poly6(z, m_om22_poly[ipoly].begin()); + m_astar(i,j) = poly6(z, m_astar_poly[ipoly].begin()); + m_bstar(i,j) = poly6(z, m_bstar_poly[ipoly].begin()); + m_cstar(i,j) = poly6(z, m_cstar_poly[ipoly].begin()); + } + else { + m_om22(i,j) = poly8(z, m_om22_poly[ipoly].begin()); + m_astar(i,j) = poly8(z, m_astar_poly[ipoly].begin()); + m_bstar(i,j) = poly8(z, m_bstar_poly[ipoly].begin()); + m_cstar(i,j) = poly8(z, m_cstar_poly[ipoly].begin()); + } + m_om22(j,i) = m_om22(i,j); + m_astar(j,i) = m_astar(i,j); + m_bstar(j,i) = m_bstar(i,j); + m_cstar(j,i) = m_cstar(i,j); + } + } + m_abc_ok = true; + + // evaluate the temperature-dependent rotational relaxation + // rate + + int k; + doublereal tr, sqtr; + for (k = 0; k < m_nsp; k++) { + tr = m_eps[k]/ m_kbt; + sqtr = m_sqrt_eps_k[k] / m_sqrt_t; + m_rotrelax[k] = fmaxx(1.0,m_zrot[k]) * m_frot_298[k]/Frot(tr, sqtr); + } + + doublereal d; + doublereal c = 1.2*GasConstant*m_temp; + for (k = 0; k < m_nsp; k++) { + d = c * m_visc[k] * m_astar(k,k)/m_mw[k]; + m_bdiff(k,k) = d; + } + + // internal heat capacities + const array_fp& cp = ((IdealGasPhase*)m_thermo)->cp_R(); + for (k = 0; k < m_nsp; k++) m_cinternal[k] = cp[k] - 2.5; + } +} diff --git a/Cantera/src/transport/MultiTransport.h b/Cantera/src/transport/MultiTransport.h new file mode 100755 index 000000000..2e95b74e3 --- /dev/null +++ b/Cantera/src/transport/MultiTransport.h @@ -0,0 +1,273 @@ +/** + * + * @file MultiTransport.h + * Interface for class MultiTransport + * + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_MULTITRAN_H +#define CT_MULTITRAN_H + + +// Define this for better agreement with Chemkin TRANLIB results, even +// if the results are less correct. +//#undef CHEMKIN_COMPATIBILITY_MODE + + +// turn off warnings under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + + +// STL includes +#include +#include +#include +#include +#include + +using namespace std; + +// Cantera includes +#include "TransportBase.h" +#include "../DenseMatrix.h" + + +namespace Cantera { + + + class TransportParams; + + ///////////////////////////////////////////////////////////// + + /** + * Class L_Matrix is used to represent the "L" matrix. This class + * is used instead of DenseMatrix so that a version of mult can be + * used that knows about the structure of the L matrix, + * specifically that the upper-right and lower-left blocks are + * zero. + * @ingroup transportProps + */ + class L_Matrix : public DenseMatrix { + public: + L_Matrix() {} + virtual ~L_Matrix(){} + + /** + * This method is used by GMRES to multiply the L matrix by a + * vector b. The L matrix has a 3x3 block structure, where each + * block is a K x K matrix. The elements of the upper-right and + * lower-left blocks are all zero. This method is defined so + * that the multiplication only involves the seven non-zero + * blocks. + */ + virtual void mult(const doublereal* b, doublereal* prod) const; + }; + + + const int GMRES = 1, LU = 2; + + /** + * Class MultiTransport implements multicomponent transport + * properties for ideal gas mixtures. The implementation generally + * follows the procedure outlined in Kee, Coltrin, and Glarborg, + * "Theoretical and Practical Aspects of Chemically Reacting Flow + * Modeling," Wiley Interscience. + * @ingroup transportProps + */ + class MultiTransport : public Transport { + + public: + + + virtual ~MultiTransport() {} + + // overloaded base class methods + virtual int model() { + if (m_mode == CK_Mode) + return CK_Multicomponent; + else + return cMulticomponent; + } + + virtual doublereal viscosity(); + + virtual void getSpeciesViscosities(doublereal* visc) + { updateViscosity_T(); copy(m_visc.begin(), m_visc.end(), visc); } + + virtual void getThermalDiffCoeffs(doublereal* dt); + virtual doublereal thermalConductivity(); + + virtual void getBinaryDiffCoeffs(int ld, doublereal* d); + virtual void getMultiDiffCoeffs(int ld, doublereal* d); + + + virtual void getSpeciesFluxes(int ndim, + doublereal* grad_T, int ldx, const doublereal* grad_X, + int ldf, doublereal* fluxes); + + virtual void setSolutionMethod(int method) { + if (method == GMRES) m_gmres = true; + else m_gmres = false; + } + + virtual void setOptions_GMRES(int m, doublereal eps) { + if (m > 0) m_mgmres = m; + if (eps > 0.0) m_eps_gmres = eps; + } + + void save(string outfile); + + /** + * @internal + */ + //bool init(const string& transportDatabase, phase_t& mix); + virtual bool init(TransportParams& tr); + + + /** + * @name Property Updating This methods are used to update + * temperature- or concentration-dependent quantities. The + * methods of the first group (with names that do not begin + * with an underscore) invoke the 'update' method of the + * relevant property updater. These methods are the ones that + * are called by other methods of the class to update + * properties. The methods that actually perform the updates + * are the ones with names beginning with an underscore. These + * are only called by the property updaters. + */ + + void updateTransport_T() {m_thermo->update_T(m_update_transport_T);} + void updateTransport_C() {m_thermo->update_C(m_update_transport_C);} + + void updateThermal_T(); + void updateViscosity_T(); + void updateSpeciesViscosities_T(); + void updateDiff_T(); + + + void _update_transport_T(); + void _update_transport_C(); + void _update_species_visc_T(); + void _update_visc_T(); + void _update_diff_T(); + void _update_thermal_T(); + + friend class TransportFactory; + + protected: + + /// default constructor + MultiTransport(thermo_t* thermo=0); + + private: + + int m_update_transport_T; + int m_update_transport_C; + int m_update_spvisc_T; + int m_update_visc_T; + int m_update_diff_T; + int m_update_thermal_T; + + + // mixture attributes + int m_nsp; + doublereal m_tmin, m_tmax; + vector_fp m_mw; + + // polynomial fits + vector m_visccoeffs; + vector m_diffcoeffs; + vector_fp m_polytempvec; + + // property values + DenseMatrix m_bdiff; + vector_fp m_visc; + + array_fp m_molefracs; + + + vector > m_poly; + vector m_astar_poly; + vector m_bstar_poly; + vector m_cstar_poly; + vector m_om22_poly; + DenseMatrix m_astar; + DenseMatrix m_bstar; + DenseMatrix m_cstar; + DenseMatrix m_om22; + + DenseMatrix m_phi; // viscosity weighting functions + + vector_fp m_zrot; + vector_fp m_crot; + vector_fp m_cinternal; + vector_fp m_eps; + + doublereal m_temp, m_logt, m_kbt, m_t32; + doublereal m_sqrt_kbt, m_sqrt_t; + + vector_fp m_sqrt_eps_k; + DenseMatrix m_log_eps_k; + vector_fp m_frot_298; + vector_fp m_rotrelax; + + doublereal m_lambda; + + // L matrix quantities + L_Matrix m_Lmatrix; + DenseMatrix m_aa; + //DenseMatrix m_Lmatrix; + vector_fp m_a; + vector_fp m_b; + + bool m_gmres; + int m_mgmres; + doublereal m_eps_gmres; + + // work space + vector_fp m_spwork; + + void correctBinDiffCoeffs(); + bool m_visc_ok; + bool m_spvisc_ok; + bool m_diff_ok; + bool m_abc_ok; + bool m_l0000_ok; + bool m_lmatrix_soln_ok; + int m_mode; + + void eval_L0000(const doublereal* x); + void eval_L0010(const doublereal* x); + void eval_L1000(); + void eval_L0100(); + void eval_L0001(); + void eval_L1010(const doublereal* x); + void eval_L1001(const doublereal* x); + void eval_L0110(); + void eval_L0101(const doublereal* x); + bool hasInternalModes(int j); + + doublereal pressure_ig() { + return m_thermo->molarDensity() * GasConstant * m_thermo->temperature(); + } + + void solveLMatrixEquation(); + DenseMatrix m_epsilon; + DenseMatrix m_diam; + DenseMatrix incl; + bool m_debug; + }; +} +#endif + + + + + + diff --git a/Cantera/src/transport/TransportBase.h b/Cantera/src/transport/TransportBase.h new file mode 100755 index 000000000..5a48613bc --- /dev/null +++ b/Cantera/src/transport/TransportBase.h @@ -0,0 +1,359 @@ +/** + * @file TransportBase.h + * @brief Provides class Transport. + */ + +/* + * $Author$ + * $Revision$ + * $Date$ + */ + +/** + * @example transport_example.cpp + * An example that illustrates use of all methods of class Transport. + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_TRANSPORTBASE_H +#define CT_TRANSPORTBASE_H + +#include "../ct_defs.h" +#include "../ctexceptions.h" +#include "../Array.h" +#include "../stringUtils.h" +//#include "Phase.h" +#include "../ThermoPhase.h" + +namespace Cantera { + + class NotImplemented : public CanteraError { + public: + NotImplemented(string method) : CanteraError("Transport", + "\n\n\n**** Method "+method+" not implemented. ****\n" + "(Did you forget to specify a transport model?)\n\n\n") {} + }; + + + class TransportParams; + + const int CK_Mode = 10; + + // types of transport models that can be constructed + const int cMulticomponent = 200; + const int CK_Multicomponent = 202; + const int cMixtureAveraged = 210; + const int CK_MixtureAveraged = 211; + + class XML_Writer; + + + /** + * Base class for transport property managers. + * All classes that compute transport properties derive from this + * class. Class Transport is meant to be used as a base class + * only. It is possible to instantiate it, but its methods throw + * exceptions if called. + * @see MultiTransport + * @see MixTransport + */ + class Transport { + + public: + + /** + * Transport model. Each transport manager may implement a + * different transport model, defined as the set of equations + * used to compute the transport properties. This virtual + * method returns an integer flag that identifies the + * transport model implemented. + */ + virtual int model() {return 0;} + + /** + * Phase object. Every transport manager is designed to + * compute properties for a specific phase of a mixture, which + * might be a liquid solution, a gas mixture, etc. This method + * returns a reference to the object representing the phase + * itself. + */ + //phase_t& phase() { return *m_phase; } + thermo_t& thermo() { return *m_thermo; } + + + /** + * Returns true if the transport manager is ready for use. + * When first created, ready() returns false, since + */ + bool ready() { return m_ready; } + + + /** + * Returns an integer index number. + */ + int index() { return m_index; } + + void setIndex(int i) { m_index = i; } + + + + /** + * @name Transport Properties + */ + //@{ + + + /** + * The mixture viscosity in Pa-s. + * @see \ref viscositySection + */ + virtual doublereal viscosity() + { return err("viscosity"); } + + + //virtual void getSpeciesViscosities(doublereal* visc) + // { err("getSpeciesViscosities"); } + + //virtual void getSpeciesConductivities(doublereal* cond) + // { err("getSpeciesConductivities"); } + + + /** + * The bulk viscosity in Pa-s. The contribution of the bulk + * viscosity to the stress tensor is usually negligible, since + * it multiplies \f$ \nabla\cdot{\bf v}.\f$ Therefore, it does + * not contribute to the stress in incompressible fluids; + * furthermore, kinetic theory shows that it is zero for ideal + * gas mixtures under typical conditions. It does influence + * certain aspects of sound propagation in liquids, and so it + * is included here. Most transport managers are likely to not + * implement this method (in which case an exception is thrown + * if it is invoked), or else return zero. Nevertheless, for + * applications where bulk viscosity is important, it is + * possible to create a transport manager that computes it by + * overloading this method. + * @see bulkViscositySection + */ + virtual doublereal bulkViscosity() + { return err("bulkViscosity"); } + + + /** + * The thermal conductivity in W/m/K. + * @see thermalConductivitySection + */ + virtual doublereal thermalConductivity() + { return err("thermalConductivity"); } + + /** + * The electrical conductivity (mho/m). + */ + virtual doublereal electricalConductivity() + { return err("electricalConductivity"); } + + /** + * Electrical mobilities. Units: [m^2/V/s]. + */ + void getMobilities(vector_fp& mobil) { + if (mobil.size() < m_nmin) sizeError(mobil.size(), m_nmin); + getMobilities(mobil.begin()); + } + + virtual void getMobilities(doublereal* mobil) + { err("getMobilities"); } + + //@} + + + /** + * Get the species mass fluxes, given the gradients. + */ + virtual void getSpeciesFluxes(int ndim, + doublereal* grad_T, int ldx, const doublereal* grad_X, + int ldf, doublereal* fluxes) { err("getSpeciesFluxes"); } + + /** + * Get the species mass fluxes, given the gradients. + */ + void getSpeciesFluxes(int ndim, vector_fp& grad_T, const Array2D& grad_X, + Array2D& fluxes) { + getSpeciesFluxes(ndim, grad_T.begin(), grad_X.nRows(), grad_X.begin(), + fluxes.nRows(), fluxes.begin()); + } + + + + /** + * Thermal diffusion coefficients. Units: [kg/m/sec]. + * The thermal diffusion coefficient \f$ D^T_k \f$ is defined + * so that the diffusive mass flux of species k induced by the + * local temperature gradient is \f[ M_k J_k = -D^T_k \nabla + * \ln T. \f]. The thermal diffusion coefficient can be either + * positive or negative. + * + * @param dt on return, dt will contain the species thermal + * diffusion coefficients. Dimension dt at least as large as + * the number of species. + */ + void getThermalDiffCoeffs(vector_fp& dt) { + if (dt.size() < m_nmin) sizeError(dt.size(),m_nmin); + getThermalDiffCoeffs(dt.begin()); + } + virtual void getThermalDiffCoeffs(doublereal* dt) + { err("getThermalDiffCoeffs"); } + + + /** + * Binary diffusion coefficients. Units: [m^2/s]. + */ + void getBinaryDiffCoeffs(Array2D& d) { + if (d.nRows() < m_nmin || d.nColumns() < m_nmin) + sizeError(d.nRows(), m_nmin, d.nColumns(), m_nmin); + getBinaryDiffCoeffs(d.nRows(), d.begin()); + } + virtual void getBinaryDiffCoeffs(int ld, doublereal* d) + { err("getBinaryDiffCoeffs"); } + + + /** + * Multicomponent diffusion coefficients. Units: [m^2/s]. If + * the transport manager implements a multicomponent diffusion + * model, then this method returns the array of multicomponent + * diffusion coefficients. + */ + void getMultiDiffCoeffs(Array2D& d) { + if (d.nRows() < m_nmin || d.nColumns() < m_nmin) + sizeError(d.nRows(), m_nmin, d.nColumns(), m_nmin); + getMultiDiffCoeffs(d.nRows(), d.begin()); + } + virtual void getMultiDiffCoeffs(int ld, doublereal* d) + { err("getMultiDiffCoeffs"); } + + + /** + * Mixture-averaged diffusion coefficients. Units: [m^2/s]. + * If the transport manager implements a mixture-averaged + * diffusion model, then this method returns the array of + * mixture-averaged diffusion coefficients. + */ + void getMixDiffCoeffs(vector_fp& d) { + if (d.size() < m_nmin) + sizeError(d.size(), m_nmin); + getMixDiffCoeffs(d.begin()); + } + virtual void getMixDiffCoeffs(doublereal* d) + { err("getMixDiffCoeffs"); } + + doublereal meanThermalSpeed(int k) const { + doublereal t = m_thermo->temperature(); + doublereal mw = m_thermo->molecularWeight(k); + return sqrt(8.0 * GasConstant * t /(Pi * mw)); + } + + virtual ~Transport(){} ///< Destructor. + + friend class TransportFactory; + + protected: + + /** + * Constructor. New transport managers should be created using + * TransportFactory, not by calling the constructor directly. + * @see TransportFactory + */ + Transport(thermo_t* thermo=0) + : m_thermo(thermo), m_ready(false), m_nmin(0), m_index(-1) {} + + /** + * @name Transport manager construction + * These methods are used internally during construction. + * @{ + */ + + /** + * called by TransportFactory to set parameters. + */ + virtual bool init(TransportParams& tr) + { err("init"); return false; } + + + /** + * Set the phase object. + */ + void setThermo(thermo_t& thermo) { + if (!ready()) { + m_thermo = &thermo; + //m_phase = &m_thermo->phase(); + m_nmin = m_thermo->nSpecies(); + } + else + throw CanteraError("Transport::setPhase", + "the phase object cannot be changed after " + "the transport manager has been constructed."); + } + + /** + * Enable for use. Once finalize() has been called, the + * transport manager should be ready to compute any supported + * transport property, and no further modifications to the + * model parameters should be made. + */ + void finalize() { + if (!ready()) + m_ready = true; + else + throw CanteraError("Transport::finalize", + "finalize has already been called."); + } + //@} + + + //phase_t* m_phase; ///< pointer to the object representing the phase + thermo_t* m_thermo; ///< pointer to the object representing the phase + bool m_ready; ///< false initially, true if ready to use + size_t m_nmin; ///< number of species + int m_index; + + private: + + /** + * Throw an exception if a method of this class is + * invoked. This probably indicates that a transport manager + * is being used that does not implement all virtual methods, + * and one of those methods was called by the application + * program. For example, a transport manager that computes the + * thermal conductivity of a solid may not overload the + * viscosity() method, since the viscosity is meaningless. If the + * application invokes the viscosity() method, the base class + * method will be called, resulting in an exception being + * thrown. + */ + doublereal err(string msg) const { + throw NotImplemented(msg); + return 0.0; + } + + void sizeError(int nr, int nrmin, int nc=-1, int ncmin=-1) { + string msg; + msg = "Array size (" + int2str(nr); + if (nc > 0) msg += "," + int2str(nc); + msg += ") is too small. Dimension at least (" + int2str(nrmin); + if (nc > 0) msg += "," + int2str(ncmin); + msg += ")."; + throw CanteraError("Transport", msg); + } + + }; + + typedef Transport transport_t; + +} +#endif + + + + + + diff --git a/Cantera/src/transport/TransportFactory.cpp b/Cantera/src/transport/TransportFactory.cpp new file mode 100755 index 000000000..9ee6d8141 --- /dev/null +++ b/Cantera/src/transport/TransportFactory.cpp @@ -0,0 +1,1079 @@ +/** + * + * @file TransportFactory.cpp + * + * Implementation file for class TransportFactory. + * + * + */ + +// turn off warnings under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + + +// known transport models +#include "MultiTransport.h" + +#include "MixTransport.h" +#include "TransportFactory.h" + +#include "polyfit.h" +#include "MMCollisionInt.h" +#include +#include "xml.h" +#include "TransportParams.h" +#include "global.h" +#include "IdealGasPhase.h" +#include "ctml.h" + +#include + + +/** + * polynomial degree used for fitting collision integrals + * except in CK mode, where the degree is 6. + */ +#define COLL_INT_POLY_DEGREE 8 + + +namespace Cantera { + + TransportFactory* TransportFactory::__factory = 0; + + + ////////////////////////// exceptions ///////////////////////// + + /** + * Exception thrown if an error is encountered while reading the + * transport database. + */ + class TransportDBError : public CanteraError { + public: + TransportDBError(int linenum, string msg) + : CanteraError("getTransportData", + "error reading transport data: " + + msg + "\n") {} + }; + + + + /////////////////////////// constants ////////////////////////// + + const doublereal ThreeSixteenths = 3.0/16.0; + const doublereal TwoOverPi = 2.0/Pi; + const doublereal FiveThirds = 5.0/3.0; + + + + //////////////////// class TransportFactory methods ////////////// + + + /** + * Calculate second-order corrections to binary diffusion + * coefficient pair (dkj, djk). At first order, the binary + * diffusion coefficients are independent of composition, and + * d(k,j) = d(j,k). But at second order, there is a weak + * dependence on composition, with the result that d(k,j) != + * d(j,k). This method computes the multiplier by which the + * first-order binary diffusion coefficient should be multiplied + * to produce the value correct to second order. The expressions + * here are taken from Marerro and Mason, + * J. Phys. Chem. Ref. Data, vol. 1, p. 3 (1972). + * + * @param t Temperature (K) + * @param tr Transport parameters + * @param k index of first species + * @param j index of second species + * @param xmk mole fraction of species k + * @param xmj mole fraction of species j + * @param fkj multiplier for d(k,j) + * @param fjk multiplier for d(j,k) + */ + void TransportFactory::getBinDiffCorrection(doublereal t, + const TransportParams& tr, int k, int j, doublereal xk, doublereal xj, + doublereal& fkj, doublereal& fjk) { + + doublereal w1, w2, wsum, sig1, sig2, sig12, sigratio, sigratio2, + sigratio3, tstar1, tstar2, tstar12, + om22_1, om22_2, om22_12, om11_12, astar_12, bstar_12, cstar_12, + cnst, wmwp, sqw12, p1, p2, p12, q1, q2, q12; + + w1 = tr.mw[k]; + w2 = tr.mw[j]; + wsum = w1 + w2; + wmwp = (w1 - w2)/wsum; + sqw12 = sqrt(w1*w2); + + sig1 = tr.sigma[k]; + sig2 = tr.sigma[j]; + sig12 = 0.5*(tr.sigma[k] + tr.sigma[j]); + sigratio = sig1*sig1/(sig2*sig2); + sigratio2 = sig1*sig1/(sig12*sig12); + sigratio3 = sig2*sig2/(sig12*sig12); + + tstar1 = Boltzmann * t / tr.eps[k]; + tstar2 = Boltzmann * t / tr.eps[j]; + tstar12 = Boltzmann * t / sqrt(tr.eps[k] * tr.eps[j]); + + om22_1 = m_integrals->omega22(tstar1, tr.delta(k,k)); + om22_2 = m_integrals->omega22(tstar2, tr.delta(j,j)); + om22_12 = m_integrals->omega22(tstar12, tr.delta(k,j)); + om11_12 = m_integrals->omega11(tstar12, tr.delta(k,j)); + astar_12 = m_integrals->astar(tstar12, tr.delta(k,j)); + bstar_12 = m_integrals->bstar(tstar12, tr.delta(k,j)); + cstar_12 = m_integrals->cstar(tstar12, tr.delta(k,j)); + + cnst = sigratio * sqrt(2.0*w2/wsum) * 2.0 * + w1*w1/(wsum * w2); + p1 = cnst * om22_1 / om11_12; + + cnst = (1.0/sigratio) * sqrt(2.0*w1/wsum) * 2.0*w2*w2/(wsum*w1); + p2 = cnst * om22_2 / om11_12; + + p12 = 15.0 * wmwp*wmwp + 8.0*w1*w2*astar_12/(wsum*wsum); + + cnst = (2.0/(w2*wsum))*sqrt(2.0*w2/wsum)*sigratio2; + q1 = cnst*((2.5 - 1.2*bstar_12)*w1*w1 + 3.0*w2*w2 + + 1.6*w1*w2*astar_12); + + cnst = (2.0/(w1*wsum))*sqrt(2.0*w1/wsum)*sigratio3; + q2 = cnst*((2.5 - 1.2*bstar_12)*w2*w2 + 3.0*w1*w1 + + 1.6*w1*w2*astar_12); + + q12 = wmwp*wmwp*15.0*(2.5 - 1.2*bstar_12) + + 4.0*w1*w2*astar_12*(11.0 - 2.4*bstar_12)/(wsum*wsum) + + 1.6*wsum*om22_1*om22_2/(om11_12*om11_12*sqw12) + * sigratio2 * sigratio3; + + cnst = 6.0*cstar_12 - 5.0; + fkj = 1.0 + 0.1*cnst*cnst * + (p1*xk*xk + p2*xj*xj + p12*xk*xj)/ + (q1*xk*xk + q2*xj*xj + q12*xk*xj); + fjk = 1.0 + 0.1*cnst*cnst * + (p2*xk*xk + p1*xj*xj + p12*xk*xj)/ + (q2*xk*xk + q1*xj*xj + q12*xk*xj); + } + + + /** + * Calculate corrections to the well depth parameter and the + * diamter for use in computing the binary diffusion coefficient + * of polar-nonpolar pairs. For more information about this + * correction, see Dixon-Lewis, Proc. Royal Society (1968). + */ + void TransportFactory::makePolarCorrections(int i, int j, + const TransportParams& tr, doublereal& f_eps, doublereal& f_sigma) { + + if (tr.polar[i] == tr.polar[j]) { + f_eps = 1.0; f_sigma = 1.0; return; + } + + // corrections to the effective diameter and well depth + // if one is polar and one is non-polar + + int kp = (tr.polar[i] ? i : j); // the polar one + int knp = (i == kp ? j : i); // the nonpolar one + + doublereal d3np, d3p, alpha_star, mu_p_star, xi; + d3np = pow(tr.sigma[knp],3); + d3p = pow(tr.sigma[kp],3); + alpha_star = tr.alpha[knp]/d3np; + mu_p_star = tr.dipole(kp,kp)/sqrt(d3p + * tr.eps[kp]); + xi = 1.0 + 0.25 * alpha_star * mu_p_star * mu_p_star * + sqrt(tr.eps[kp]/tr.eps[knp]); + f_sigma = pow(xi, -1.0/6.0); + f_eps = xi*xi; + } + + + // Constructor does nothing + TransportFactory::TransportFactory() : m_integrals(0) { + m_models["Mix"] = cMixtureAveraged; + m_models["Multi"] = cMulticomponent; + m_models["None"] = 0; + } + + TransportFactory::~TransportFactory() { + delete __factory; + __factory = 0; + delete m_integrals; + m_integrals = 0; + } + + /** + * make one of several transport models, and return a base class + * pointer to it. + */ + Transport* TransportFactory::newTransport(string transportModel, + thermo_t* phase, int log_level) { + + if (transportModel == "") return new Transport; + + vector_fp state; + Transport* tr = 0; + phase->saveState(state); + + switch(m_models[transportModel]) { + case None: + tr = new Transport; break; + case cMulticomponent: + tr = new MultiTransport; + initTransport(tr, phase, 0, log_level); + break; + case CK_Multicomponent: + tr = new MultiTransport; + initTransport(tr, phase, CK_Mode, log_level); + break; + case cMixtureAveraged: + tr = new MixTransport; + initTransport(tr, phase, 0, log_level); + break; + case CK_MixtureAveraged: + tr = new MixTransport; + initTransport(tr, phase, CK_Mode, log_level); + break; + default: + throw CanteraError("newTransport","unknown transport model"); + } + phase->restoreState(state); + return tr; + } + +// Transport* TransportFactory:: +// newPowerTransport(const string& transport_database, +// Transport::phase_t* mix) { +// doublereal tref, viscref, lambdaref, viscexp, lambdaexp, +// diffexp; +// ifstream f(transport_database.c_str()); +// if (!f) { +// throw TransportDBError("newPowerTransport: file" + +// transport_database + " not found."); +// } +// f >> tref +// >> viscref >> viscexp +// >> lambdaref >> lambdaexp +// >> diffexp; +// int nsp = mix->nSpecies(); +// int k; +// vector_fp dref(nsp); +// for (k = 0; k < nsp; k++) { +// f >> dref[k]; +// } +// PowerTransport* t = new PowerTransport(); +// t->init(mix); +// t->setExponents(viscexp, lambdaexp, diffexp); +// t->setRefValues(tref, viscref, lambdaref, nsp, dref.begin()); +// f.close(); +// return t; +// } + + + + /** + * Prepare to build a new kinetic-theory-based transport manager + * for low-density gases. Uses polynomial fits to Monchick & Mason + * collision integrals. + */ + void TransportFactory::setupMM(ostream& flog, + XML_Node* transport_database, + thermo_t* thermo, int mode, int log_level, TransportParams& tr) { + + // constant mixture attributes + //tr.mix = thermo; + tr.thermo = thermo; + tr.nsp = tr.thermo->nSpecies(); + int nsp = tr.nsp; + + tr.tmin = thermo->minTemp(); + tr.tmax = thermo->maxTemp(); + tr.mw.resize(nsp); + tr.log_level = log_level; + + copy(tr.thermo->molecularWeights().begin(), + tr.thermo->molecularWeights().end(), tr.mw.begin()); + + tr.mode = mode; + tr.epsilon.resize(nsp, nsp, 0.0); + tr.delta.resize(nsp, nsp, 0.0); + tr.reducedMass.resize(nsp, nsp, 0.0); + tr.dipole.resize(nsp, nsp, 0.0); + tr.diam.resize(nsp, nsp, 0.0); + tr.crot.resize(nsp); + tr.zrot.resize(nsp); + tr.polar.resize(nsp, false); + tr.alpha.resize(nsp, 0.0); + tr.poly.resize(nsp); + tr.sigma.resize(nsp); + tr.eps.resize(nsp); + + + //readTransportDatabase(flog, transport_database, + // tr.thermo->speciesNames(), tr); + + XML_Node root, log; + //string infile = findInputFile(transport_database); + //ifstream fin(infile.c_str()); + //root.build(fin); + getTransportData(transport_database, log, + tr.thermo->speciesNames(), tr); + + int i, j; + for (i = 0; i < nsp; i++) tr.poly[i].resize(nsp); + + doublereal ts1, ts2, tstar_min = 1.e8, tstar_max = 0.0; + doublereal f_eps, f_sigma; + + DenseMatrix& diam = tr.diam; + DenseMatrix& epsilon = tr.epsilon; + + for (i = 0; i < nsp; i++) + { + for (j = i; j < nsp; j++) + { + // the reduced mass + tr.reducedMass(i,j) = + tr.mw[i] * tr.mw[j] / (Avogadro * (tr.mw[i] + tr.mw[j])); + + // hard-sphere diameter for (i,j) collisions + diam(i,j) = 0.5*(tr.sigma[i] + tr.sigma[j]); + + // the effective well depth for (i,j) collisions + epsilon(i,j) = sqrt(tr.eps[i]*tr.eps[j]); + + // The polynomial fits of collision integrals vs. T* + // will be done for the T* from tstar_min to tstar_max + ts1 = Boltzmann * tr.tmin/epsilon(i,j); + ts2 = Boltzmann * tr.tmax/epsilon(i,j); + if (ts1 < tstar_min) tstar_min = ts1; + if (ts2 > tstar_max) tstar_max = ts2; + + // the effective dipole moment for (i,j) collisions + tr.dipole(i,j) = sqrt(tr.dipole(i,i)*tr.dipole(j,j)); + + // reduced dipole moment delta* (nondimensional) + doublereal d = diam(i,j); + tr.delta(i,j) = 0.5 * tr.dipole(i,j)*tr.dipole(i,j) + / (epsilon(i,j) * d * d * d); + + makePolarCorrections(i, j, tr, f_eps, f_sigma); + tr.diam(i,j) *= f_sigma; + epsilon(i,j) *= f_eps; + + // properties are symmetric + tr.reducedMass(j,i) = tr.reducedMass(i,j); + diam(j,i) = diam(i,j); + epsilon(j,i) = epsilon(i,j); + tr.dipole(j,i) = tr.dipole(i,j); + tr.delta(j,i) = tr.delta(i,j); + } + } + + + // Chemkin fits the entire T* range in the Monchick and Mason tables, + // so modify tstar_min and tstar_max if in Chemkin compatibility mode + //if (mode == CK_Mode) { + tstar_min = 0.101; + tstar_max = 99.9; + //} + + // initialize the collision integral calculator for the desired + // T* range + tr.xml->XML_open(flog, "collision_integrals"); + m_integrals = new MMCollisionInt; + m_integrals->init(tr.xml, tstar_min, tstar_max); + fitCollisionIntegrals(flog, tr); + tr.xml->XML_close(flog, "collision_integrals"); + + // make polynomial fits + tr.xml->XML_open(flog, "property fits"); + fitProperties(tr,flog); + tr.xml->XML_close(flog, "property fits"); + } + + + void TransportFactory::initTransport(Transport* tran, + thermo_t* thermo, int mode, int log_level) { + + XML_Node* transport_database = thermo->speciesData(); + + TransportParams tr; + ofstream flog("transport_log.xml"); + tr.xml = new XML_Writer(flog); + tr.xml->XML_open(flog, "transport"); + + // set up Monchick and Mason collision integrals + setupMM(flog, transport_database, thermo, mode, log_level, tr); + + // do model-specific initialization + tran->init(tr); + + tr.xml->XML_close(flog, "transport"); + flog.close(); + + // finished with log file + flog.close(); + + return; + } + + + + + + /******************************************************** + * + * Collision Integral Fits + * + ********************************************************/ + + + void TransportFactory::fitCollisionIntegrals(ostream& logfile, + TransportParams& tr) { + + doublereal* dptr; + doublereal dstar; + int nsp = tr.nsp; + int mode = tr.mode; + int i, j; + + // Chemkin fits to sixth order polynomials + int degree = (mode == CK_Mode ? 6 : COLL_INT_POLY_DEGREE); + + tr.xml->XML_open(logfile, "tstar_fits"); + tr.xml->XML_comment(logfile, "fits to A*, B*, and C* vs. log(T*).\n" + "These are done only for the required dstar(j,k) values."); + if (tr.log_level < 3) + tr.xml->XML_comment(logfile, "*** polynomial coefficients not printed (log_level < 3) ***"); + + for (i = 0; i < nsp; i++) + { + for (j = i; j < nsp; j++) + { + // Chemkin fits only delta* = 0 + if (mode != CK_Mode) + dstar = tr.delta(i,j); + else + dstar = 0.0; + + // if a fit has already been generated for + // delta* = tr.delta(i,j), then use it. Otherwise, + // make a new fit, and add tr.delta(i,j) to the list + // of delta* values for which fits have been done. + + // 'find' returns a pointer to end() if not found + if (dptr = find(tr.fitlist.begin(), tr.fitlist.end(), + dstar), dptr == tr.fitlist.end()) + { + vector_fp ca(degree+1), cb(degree+1), cc(degree+1); + vector_fp co22(degree+1); + m_integrals->fit(logfile, degree, dstar, + ca.begin(), cb.begin(), cc.begin()); + m_integrals->fit_omega22(degree, dstar, + co22.begin()); + tr.omega22_poly.push_back(co22); + tr.astar_poly.push_back(ca); + tr.bstar_poly.push_back(cb); + tr.cstar_poly.push_back(cc); + tr.poly[i][j] = tr.astar_poly.size() - 1; + tr.fitlist.push_back(dstar); + } + + // delta* found in fitlist, so just point to this + // polynomial + else { + tr.poly[i][j] = (dptr - tr.fitlist.begin()); + } + tr.poly[j][i] = tr.poly[i][j]; + } + } + tr.xml->XML_close(logfile, "tstar_fits"); + } + + + + + /********************************************************* + * + * Read Transport Database + * + *********************************************************/ + + + /** + * Read transport property data from a file for a list of species. + * Given the name of a file containing transport property + * parameters and a list of species names, this method returns an + * instance of TransportParams containing the transport data for + * these species read from the file. + */ +// void TransportFactory::readTransportDatabase( +// ostream& logfile, +// const string& database_file, +// const vector& names, +// TransportParams& tr) +// { + +// string dbase_file = findInputFile(database_file); +// ifstream dbase(dbase_file.c_str()); + +// if (!dbase) throw CanteraError("readTransportDatabase", +// "cannot open file " + database_file); + +// string name, rest; +// int geom, linenum = 0; +// map datatable; +// doublereal welldepth, diam, dipole, polar, rot; + + + +// // read all entries in database into 'datatable' and check for +// // errors. Note that this procedure validates all entries, not +// // only those for the species listed in 'names'. + +// while (!dbase.eof()) { +// dbase >> name; +// linenum++; +// if (name[0] != '!' && !dbase.eof()) { +// dbase >> geom >> welldepth >> diam +// >> dipole >> polar >> rot; + +// // get the rest of the line, in case there are comments +// getline(dbase, rest); + +// TransportData data; +// data.speciesName = name; +// data.geometry = geom; +// data.wellDepth = welldepth; +// data.diameter = diam; +// data.dipoleMoment = dipole; +// data.polarizability = polar; +// data.rotRelaxNumber = rot; + +// datatable[name] = data; + +// if (welldepth >= 0.0) data.wellDepth = welldepth; +// else throw TransportDBError(linenum, +// "negative well depth"); + +// if (diam > 0.0) data.diameter = diam; +// else throw TransportDBError(linenum, +// "negative or zero diameter"); + +// if (dipole >= 0.0) data.dipoleMoment = dipole; +// else throw TransportDBError(linenum, +// "negative dipole moment"); + +// if (polar >= 0.0) data.polarizability = polar; +// else throw TransportDBError(linenum, +// "negative polarizability"); + +// if (rot >= 0.0) data.rotRelaxNumber = rot; +// else throw TransportDBError(linenum, +// "negative rotation relaxation number"); + +// datatable[name] = data; +// } +// } +// dbase.close(); + +// // look up the entries for the species listed in 'names'. +// tr.xml->XML_open(logfile,"database_parameters"); +// tr.xml->XML_item(logfile,"file_name",database_file); +// for (int i = 0; i < tr.nsp; i++) { + +// TransportData& trdat = datatable[names[i]]; + +// // 'datatable' returns a default TransportData object if +// // the species name is not one in the transport database. +// // This can be detected by examining 'geometry'. +// if (trdat.geometry < 0) { +// throw TransportDBError(0,"no transport data found for species " +// + names[i]); +// } + +// // parameters are converted to SI units before storing + +// // rotational heat capacity / R +// switch (trdat.geometry) { +// case 0: +// tr.crot[i] = 0.0; // monatomic +// break; +// case 1: +// tr.crot[i] = 1.0; // linear +// break; +// default: +// tr.crot[i] = 1.5; // nonlinear +// } + + +// tr.dipole(i,i) = 1.e-25 * SqrtTen * trdat.dipoleMoment; + +// if (trdat.dipoleMoment > 0.0) +// tr.polar[i] = true; +// else +// tr.polar[i] = false; + +// // A^3 -> m^3 +// tr.alpha[i] = 1.e-30 * trdat.polarizability; + +// tr.sigma[i] = 1.e-10 * trdat.diameter; + +// tr.eps[i] = Boltzmann * trdat.wellDepth; +// tr.zrot[i] = fmaxx(1.0, trdat.rotRelaxNumber); + +// // write database parameters to log file +// tr.xml->XML_open(logfile, names[i]); +// tr.xml->XML_item(logfile, "geom", trdat.geometry); +// tr.xml->XML_item(logfile, "epsilon", trdat.wellDepth); +// tr.xml->XML_item(logfile, "sigma", trdat.diameter); +// tr.xml->XML_item(logfile, "dipole", trdat.dipoleMoment); +// tr.xml->XML_item(logfile, "alpha", trdat.polarizability); +// tr.xml->XML_item(logfile, "zrot", trdat.rotRelaxNumber); +// tr.xml->XML_close(logfile, names[i]); +// } +// tr.xml->XML_close(logfile,"database_parameters"); + // } + + + + /********************************************************* + * + * Read Transport Database + * + *********************************************************/ + + + /** + * Read transport property data from a file for a list of species. + * Given the name of a file containing transport property + * parameters and a list of species names, this method returns an + * instance of TransportParams containing the transport data for + * these species read from the file. + */ + void TransportFactory::getTransportData(XML_Node* transport_database, + XML_Node& log, const vector& names, TransportParams& tr) + { + string name; + int geom; + map datatable; + doublereal welldepth, diam, dipole, polar, rot; + + //XML_Node* sparray = find_XML("", &root, "", "", "speciesData"); + vector xspecies; + transport_database->getChildren("species",xspecies); + int nsp = xspecies.size(); + + // read all entries in database into 'datatable' and check for + // errors. Note that this procedure validates all entries, not + // only those for the species listed in 'names'. + + string val, type; + map gindx; + gindx["atom"] = 100; + gindx["linear"] = 101; + gindx["nonlinear"] = 102; + int linenum = 0; + int i; + for (i = 0; i < nsp; i++) { + XML_Node& sp = *xspecies[i]; + name = sp["name"]; + XML_Node& tr = sp.child("transport"); + getString(tr, "geometry", val, type); + geom = gindx[val] - 100; + map fv; + getFloats(tr, fv, false); + welldepth = fv["LJ_welldepth"]; + diam = fv["LJ_diameter"]; + dipole = fv["dipoleMoment"]; + polar = fv["polarizability"]; + rot = fv["rotRelax"]; + + TransportData data; + data.speciesName = name; + data.geometry = geom; + if (welldepth >= 0.0) data.wellDepth = welldepth; + else throw TransportDBError(linenum, + "negative well depth"); + + if (diam > 0.0) data.diameter = diam; + else throw TransportDBError(linenum, + "negative or zero diameter"); + + if (dipole >= 0.0) data.dipoleMoment = dipole; + else throw TransportDBError(linenum, + "negative dipole moment"); + + if (polar >= 0.0) data.polarizability = polar; + else throw TransportDBError(linenum, + "negative polarizability"); + + if (rot >= 0.0) data.rotRelaxNumber = rot; + else throw TransportDBError(linenum, + "negative rotation relaxation number"); + + datatable[name] = data; + } + + // look up the entries for the species listed in 'names'. + //tr.xml->XML_open(logfile,"database_parameters"); + //tr.xml->XML_item(logfile,"file_name",database_file); + + for (i = 0; i < tr.nsp; i++) { + + TransportData& trdat = datatable[names[i]]; + + // 'datatable' returns a default TransportData object if + // the species name is not one in the transport database. + // This can be detected by examining 'geometry'. + if (trdat.geometry < 0) { + throw TransportDBError(0,"no transport data found for species " + + names[i]); + } + + // parameters are converted to SI units before storing + + // rotational heat capacity / R + switch (trdat.geometry) { + case 0: + tr.crot[i] = 0.0; // monatomic + break; + case 1: + tr.crot[i] = 1.0; // linear + break; + default: + tr.crot[i] = 1.5; // nonlinear + } + + + tr.dipole(i,i) = 1.e-25 * SqrtTen * trdat.dipoleMoment; + + if (trdat.dipoleMoment > 0.0) + tr.polar[i] = true; + else + tr.polar[i] = false; + + // A^3 -> m^3 + tr.alpha[i] = 1.e-30 * trdat.polarizability; + + tr.sigma[i] = 1.e-10 * trdat.diameter; + + tr.eps[i] = Boltzmann * trdat.wellDepth; + tr.zrot[i] = fmaxx(1.0, trdat.rotRelaxNumber); + + // write database parameters to log file + //tr.xml->XML_open(logfile, names[i]); + //tr.xml->XML_item(logfile, "geom", trdat.geometry); + //tr.xml->XML_item(logfile, "epsilon", trdat.wellDepth); + //tr.xml->XML_item(logfile, "sigma", trdat.diameter); + //tr.xml->XML_item(logfile, "dipole", trdat.dipoleMoment); + //tr.xml->XML_item(logfile, "alpha", trdat.polarizability); + //tr.xml->XML_item(logfile, "zrot", trdat.rotRelaxNumber); + //tr.xml->XML_close(logfile, names[i]); + } + //tr.xml->XML_close(logfile,"database_parameters"); + } + + + /********************************************************* + * + * Polynomial fitting + * + *********************************************************/ + + + + /***************** fitProperties ***************/ + + /** + * Generate polynomial fits for the pure-species viscosities and + * for the binary diffusion coefficients. If + * CK_mode, then the fits are of the + * form \f[ + * \log(\eta(i)) = \sum_{n = 0}^3 a_n(i) (\log T)^n + * \f] + * and \f[ + * \log(D(i,j)) = \sum_{n = 0}^3 a_n(i,j) (\log T)^n + * \f] + * Otherwise the fits are of the form + * \f[ + * \eta(i)/sqrt(k_BT) = \sum_{n = 0}^4 a_n(i) (\log T)^n + * \f] + * and \f[ + * D(i,j)/sqrt(k_BT)) = \sum_{n = 0}^4 a_n(i,j) (\log T)^n + * \f] + */ + void TransportFactory::fitProperties(TransportParams& tr, + ostream& logfile) { + doublereal tstar; + int k, j, n, ndeg = 0; + char s[100]; + + // number of points to use in generating fit data + const int np = 50; + + int mode = tr.mode; + int degree = (mode == CK_Mode ? 3 : 4); + + doublereal t, om22; + doublereal dt = (tr.tmax - tr.tmin)/(np-1); + vector_fp tlog(np), spvisc(np), spcond(np); + doublereal val, fit; + + vector_fp w(np), w2(np); + + // generate array of log(t) values + for (n = 0; n < np; n++) { + t = tr.tmin + dt*n; + tlog[n] = log(t); + } + + // vector of polynomial coefficients + vector_fp c(degree + 1), c2(degree + 1); + + + // fit the pure-species viscosity and thermal conductivity for + // each species + + if (tr.log_level < 2) + tr.xml->XML_comment(logfile, + "*** polynomial coefficients not printed (log_level < 3) ***"); + + int ipoly; + doublereal sqrt_T, visc, err, relerr, + mxerr = 0.0, mxrelerr = 0.0, mxerr_cond = 0.0, mxrelerr_cond = 0.0; + tr.xml->XML_open(logfile, "viscosity"); + tr.xml->XML_comment(logfile,"Polynomial fits for viscosity"); + if (mode == CK_Mode) { + tr.xml->XML_comment(logfile,"log(viscosity) fit to cubic " + "polynomial in log(T)"); + } + else { + sprintf(s, "viscosity/sqrt(T) fit to " + "polynomial of degree %d in log(T)",degree); + tr.xml->XML_comment(logfile,s); + } + + // const vector_fp& cp_R = tr.mix->cp_R(); + + doublereal cp_R, cond, w_RT, f_int, A_factor, B_factor, + c1, cv_rot, cv_int, f_rot, f_trans, om11; + doublereal diffcoeff; + + for (k = 0; k < tr.nsp; k++) + { + for (n = 0; n < np; n++) { + t = tr.tmin + dt*n; + + tr.thermo->setTemperature(t); + cp_R = ((IdealGasPhase*)tr.thermo)->cp_R()[k]; + + tstar = Boltzmann * t/ tr.eps[k]; + sqrt_T = sqrt(t); + om22 = m_integrals->omega22(tstar, tr.delta(k,k)); + om11 = m_integrals->omega11(tstar, tr.delta(k,k)); + + // self-diffusion coefficient, without polar + // corrections + diffcoeff = ThreeSixteenths * + sqrt( 2.0 * Pi/tr.reducedMass(k,k) ) * + pow((Boltzmann * t), 1.5)/ + (Pi * tr.sigma[k] * tr.sigma[k] * om11); + + // viscosity + visc = FiveSixteenths + * sqrt(Pi * tr.mw[k] * Boltzmann * t / Avogadro) / + (om22 * Pi * tr.sigma[k]*tr.sigma[k]); + + // thermal conductivity + w_RT = tr.mw[k]/(GasConstant * t); + f_int = w_RT * diffcoeff/visc; + cv_rot = tr.crot[k]; + + A_factor = 2.5 - f_int; + B_factor = tr.zrot[k] + TwoOverPi + *(FiveThirds * cv_rot + f_int); + c1 = TwoOverPi * A_factor/B_factor; + cv_int = cp_R - 2.5 - cv_rot; + + f_rot = f_int * (1.0 + c1); + f_trans = 2.5 * (1.0 - c1 * cv_rot/1.5); + + cond = (visc/tr.mw[k])*GasConstant*(f_trans * 1.5 + + f_rot * cv_rot + f_int * cv_int); + + if (mode == CK_Mode) { + spvisc[n] = log(visc); + spcond[n] = log(cond); + w[n] = -1.0; + w2[n] = -1.0; + } + else { + spvisc[n] = visc/sqrt_T; + spcond[n] = cond/sqrt_T; + w[n] = 1.0/(spvisc[n]*spvisc[n]); + w2[n] = 1.0/(spcond[n]*spcond[n]); + } + } + polyfit(np, tlog.begin(), spvisc.begin(), + w.begin(), degree, ndeg, 0.0, c.begin()); + polyfit(np, tlog.begin(), spcond.begin(), + w.begin(), degree, ndeg, 0.0, c2.begin()); + + // evaluate max fit errors for viscosity + for (n = 0; n < np; n++) { + if (mode == CK_Mode) { + val = exp(spvisc[n]); + fit = exp(poly3(tlog[n], c.begin())); + } + else { + sqrt_T = exp(0.5*tlog[n]); + val = sqrt_T * spvisc[n]; + fit = sqrt_T * poly4(tlog[n], c.begin()); + } + err = fit - val; + relerr = err/val; + if (fabs(err) > mxerr) mxerr = fabs(err); + if (fabs(relerr) > mxrelerr) mxrelerr = fabs(relerr); + } + + // evaluate max fit errors for conductivity + for (n = 0; n < np; n++) { + if (mode == CK_Mode) { + val = exp(spcond[n]); + fit = exp(poly3(tlog[n], c2.begin())); + } + else { + sqrt_T = exp(0.5*tlog[n]); + val = sqrt_T * spcond[n]; + fit = sqrt_T * poly4(tlog[n], c2.begin()); + } + err = fit - val; + relerr = err/val; + if (fabs(err) > mxerr_cond) mxerr_cond = fabs(err); + if (fabs(relerr) > mxrelerr_cond) mxrelerr_cond = fabs(relerr); + } + tr.visccoeffs.push_back(c); + tr.condcoeffs.push_back(c2); + + if (tr.log_level >= 2) { + tr.xml->XML_writeVector(logfile, " ", tr.thermo->speciesName(k), + c.size(), c.begin()); + } + } + + sprintf(s, "Maximum viscosity absolute error: %12.6g", mxerr); + tr.xml->XML_comment(logfile,s); + sprintf(s, "Maximum viscosity relative error: %12.6g", mxrelerr); + tr.xml->XML_comment(logfile,s); + tr.xml->XML_close(logfile, "viscosity"); + + + tr.xml->XML_open(logfile, "conductivity"); + tr.xml->XML_comment(logfile,"Polynomial fits for conductivity"); + if (mode == CK_Mode) + tr.xml->XML_comment(logfile,"log(conductivity) fit to cubic " + "polynomial in log(T)"); + else { + sprintf(s, "conductivity/sqrt(T) fit to " + "polynomial of degree %d in log(T)",degree); + tr.xml->XML_comment(logfile,s); + } + if (tr.log_level >= 2) + for (k = 0; k < tr.nsp; k++) { + tr.xml->XML_writeVector(logfile, " ", tr.thermo->speciesName(k), + degree+1, tr.condcoeffs[k].begin()); + } + sprintf(s, "Maximum conductivity absolute error: %12.6g", mxerr_cond); + tr.xml->XML_comment(logfile,s); + sprintf(s, "Maximum conductivity relative error: %12.6g", mxrelerr_cond); + tr.xml->XML_comment(logfile,s); + tr.xml->XML_close(logfile, "conductivity"); + + // fit the binary diffusion coefficients for each species pair + + tr.xml->XML_open(logfile, "binary_diffusion_coefficients"); + tr.xml->XML_comment(logfile, "binary diffusion coefficients"); + if (mode == CK_Mode) + tr.xml->XML_comment(logfile,"log(D) fit to cubic " + "polynomial in log(T)"); + else { + sprintf(s, "D/T**(3/2) fit to " + "polynomial of degree %d in log(T)",degree); + tr.xml->XML_comment(logfile,s); + } + mxerr = 0.0, mxrelerr = 0.0; + vector_fp diff(np + 1); + doublereal eps, sigma; + for (k = 0; k < tr.nsp; k++) + { + for (j = k; j < tr.nsp; j++) { + + ipoly = tr.poly[k][j]; + for (n = 0; n < np; n++) { + + t = tr.tmin + dt*n; + + eps = tr.epsilon(j,k); + tstar = Boltzmann * t/eps; + sigma = tr.diam(j,k); + om11 = m_integrals->omega11(tstar, tr.delta(j,k)); + + diffcoeff = ThreeSixteenths * + sqrt( 2.0 * Pi/tr.reducedMass(k,j) ) * + pow((Boltzmann * t), 1.5)/ + (Pi * sigma * sigma * om11); + + // 2nd order correction + doublereal fkj, fjk; + getBinDiffCorrection(t, tr, k, j, 1.0, 1.0, fkj, fjk); + //diffcoeff *= fkj; + + if (mode == CK_Mode) { + + diff[n] = log(diffcoeff); + w[n] = -1.0; + } + else { + diff[n] = diffcoeff/pow(t, 1.5); + w[n] = 1.0/(diff[n]*diff[n]); + } + } + polyfit(np, tlog.begin(), diff.begin(), + w.begin(), degree, ndeg, 0.0, c.begin()); + + doublereal pre; + for (n = 0; n < np; n++) { + if (mode == CK_Mode) { + val = exp(diff[n]); + fit = exp(poly3(tlog[n], c.begin())); + } + else { + t = exp(tlog[n]); + pre = pow(t, 1.5); + val = pre * diff[n]; + fit = pre * poly4(tlog[n], c.begin()); + } + err = fit - val; + relerr = err/val; + if (fabs(err) > mxerr) mxerr = fabs(err); + if (fabs(relerr) > mxrelerr) mxrelerr = fabs(relerr); + } + tr.diffcoeffs.push_back(c); + if (tr.log_level >= 2) + tr.xml->XML_writeVector(logfile, " ", tr.thermo->speciesName(k) + + "__"+tr.thermo->speciesName(j), c.size(), c.begin()); + } + } + sprintf(s,"Maximum binary diffusion coefficient absolute error:" + " %12.6g", mxerr); + tr.xml->XML_comment(logfile,s); + sprintf(s, "Maximum binary diffusion coefficient relative error:" + "%12.6g", mxrelerr); + tr.xml->XML_comment(logfile,s); + tr.xml->XML_close(logfile, "binary_diffusion_coefficients"); + } +} diff --git a/Cantera/src/transport/TransportFactory.h b/Cantera/src/transport/TransportFactory.h new file mode 100755 index 000000000..86b4a1374 --- /dev/null +++ b/Cantera/src/transport/TransportFactory.h @@ -0,0 +1,192 @@ +/** + * + * @file TransportFactory.h + * + * Header file defining class TransportFactory + */ + +/* + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2001 California Institute of Technology + * + */ + +#ifndef CT_TRANFACTORY_H +#define CT_TRANFACTORY_H + + +// turn off warnings under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +// STL includes +#include +#include +#include + +using namespace std; + +// Cantera includes +#include "../ct_defs.h" +#include "TransportBase.h" + +namespace Cantera { + + /** + * Struct to hold data read from a transport property database file. + */ + struct TransportData { + TransportData() : speciesName("-"), + geometry(-1), wellDepth(-1.0), + diameter(-1.0), + dipoleMoment(-1.0), + polarizability(-1.0), + rotRelaxNumber(-1.0) {} + + string speciesName; + int geometry; + doublereal wellDepth; + doublereal diameter; + doublereal dipoleMoment; + doublereal polarizability; + doublereal rotRelaxNumber; + }; + + // forward references + class MMCollisionInt; + class TransportParams; + class XML_Node; + + /** + * The purpose of TransportFactory is to create new instances of + * 'transport managers', which are classes that provide transport + * properties and are derived from base class + * Transport. TransportFactory handles all initialization + * required, including evaluation of collision integrals and + * generating polynomial fits. Transport managers can also be + * created in other ways. @ingroup transportgroup + * @ingroup transportProps + */ + class TransportFactory { + + public: + + /** + * Return a pointer to a TransportFactory + * instance. TransportFactory is implemented as a 'singleton', + * which means that at most one instance may be created. The + * constructor is private. When a TransportFactory instance is + * required, call static method factory() to return a pointer + * to the TransportFactory instance. + * + * @code + * TransportFactory* f; + * f = TransportFactory::factory(); + * @endcode + */ + static TransportFactory* factory() { + if (!__factory) { + __factory = new TransportFactory(); + } + return __factory; + } + + /** + * Destructor. Deletes the TransportFactory instance pointed + * to by __factory, and sets __factory to NULL. + */ + virtual ~TransportFactory(); + + /// Build a new transport manager + virtual Transport* + newTransport(string model="", thermo_t* thermo=0, int log_level=0); + + /// Initialize an existing transport manager + virtual void initTransport(Transport* tr, + thermo_t* thermo=0, int mode=0, int log_level=0); + + + private: + + static TransportFactory* __factory; + + // The constructor is private; use static method factory() to + // get a pointer to a factory instance + TransportFactory(); + + /// Read in transport parameters from a database + //void readTransportDatabase(ostream& logfile, + // XML_Node* db, + // const vector& names, + // TransportParams& tr); + + void getTransportData(XML_Node* db, + XML_Node& log, const vector& names, + TransportParams& tr); + + /** Generate polynomial fits to viscosity, conductivity, and + * binary diffusion coefficients */ + void fitProperties(TransportParams& tr, ostream& logfile=cout); + + /// Generate polynomial fits to collision integrals + void fitCollisionIntegrals(ostream& logfile, + TransportParams& tr); + + MMCollisionInt* m_integrals; + + void setupMM(ostream& flog, XML_Node* transport_database, + thermo_t* thermo, int mode, int log_level, + TransportParams& tr); + + /// construct a new power-law transport manager + //Transport* newPowerTransport(const string& transport_database, + // phase_t* mix); + + /// construct a new multicomponent transport manager + // Transport* newMultiTransport(const string& fname, + // thermo_t* thermo, int mode = 0, int log_level = 0); + + /// construct a new mixture-averaged transport server + //Transport* newMixTransport(const string& fname, + // thermo_t* thermo, int mode = 0, int log_level = 0); + + + /// Second-order correction to the binary diffusion coefficients + void getBinDiffCorrection(doublereal t, + const TransportParams& tr, int k, int j, doublereal xk, doublereal xj, + doublereal& fkj, doublereal& fjk); + + /// Corrections for polar-nonpolar binary diffusion coefficients + void makePolarCorrections(int i, int j, + const TransportParams& tr, doublereal& f_eps, doublereal& f_sigma); + + map m_models; + }; + + + /** + * Create a new transport manager instance. + * @ingroup transportProps + */ + inline Transport* newTransportMgr(string transportModel="", + thermo_t* thermo=0, int loglevel=0, TransportFactory* f=0) { + if (f == 0) { + f = TransportFactory::factory(); + } + return f->newTransport(transportModel, thermo, loglevel); + } + + +} +#endif + + + + + + diff --git a/Cantera/src/transport/TransportParams.h b/Cantera/src/transport/TransportParams.h new file mode 100755 index 000000000..4a58bfc2d --- /dev/null +++ b/Cantera/src/transport/TransportParams.h @@ -0,0 +1,64 @@ +#ifndef CT_TRANSPORTPARAMS_H +#define CT_TRANSPORTPARAMS_H + +#include +using namespace std; + +#include "ct_defs.h" +#include "TransportBase.h" +#include "xml.h" + +namespace Cantera { + + /** + * + * Holds transport data. Used by TransportFactory. + * + */ + class TransportParams { + + public: + + TransportParams() : thermo(0), xml(0) {} + virtual ~TransportParams(){ + delete xml; + } + int nsp; + + // phase_t* mix; + thermo_t* thermo; + vector_fp mw; + + // polynomial fits + vector visccoeffs; + vector condcoeffs; + vector diffcoeffs; + vector_fp polytempvec; + + vector > poly; + vector omega22_poly; + vector astar_poly; + vector bstar_poly; + vector cstar_poly; + + vector_fp zrot; + vector_fp crot; + + vector polar; + vector_fp alpha; + vector_fp fitlist; + vector_fp eps; + vector_fp sigma; + DenseMatrix reducedMass; + DenseMatrix diam; + DenseMatrix epsilon; + DenseMatrix dipole; + DenseMatrix delta; + doublereal tmax, tmin; + int mode; + XML_Writer* xml; + int log_level; + }; +} + +#endif diff --git a/Cantera/src/transportModels.h b/Cantera/src/transportModels.h new file mode 100755 index 000000000..aedb15ba7 --- /dev/null +++ b/Cantera/src/transportModels.h @@ -0,0 +1,16 @@ +#ifndef CT_TRANSPORT_MODELS_H +#define CT_TRANSPORT_MODELS_H + + +#include "TransportFactory.h" + +namespace Cantera { + + inline Transport* MultiTransport(mixture_t& mix, string file, + int loglevel=0) { + TransportFactory* f = TransportFactory::factory(); + Transport* t = f->newTransport(Multicomponent, file, mix, loglevel); + mix->setTransport(t); + } + +} diff --git a/Cantera/src/units.h b/Cantera/src/units.h new file mode 100644 index 000000000..1e70f1e9d --- /dev/null +++ b/Cantera/src/units.h @@ -0,0 +1,99 @@ +#ifndef CT_UNITS_H +#define CT_UNITS_H + +#include "ct_defs.h" + +namespace Cantera { + + class Unit { + public: + + static Unit* units() { + if (!__u) __u = new Unit; + return __u; + } + + virtual ~Unit() { + delete __u; + __u = 0; + } + + doublereal toSI(string units) { + if (units == "") return 1.0; + doublereal f = 1.0, fctr; + int tsize; + string u = units, tok; + int k; + char action = '-'; + while (1 > 0) { + k = u.find_first_of("/-"); + if (k >= 0) + tok = u.substr(0,k); + else + tok = u; + tsize = tok.size(); + if (tok[tsize - 1] == '2') { + fctr = m_u[tok.substr(0,tsize-2)]; + fctr *= fctr; + } + else if (tok[tsize - 1] == '3') { + fctr = m_u[tok.substr(0,tsize-2)]; + fctr *= fctr*fctr; + } + else + fctr = m_u[tok]; + + if (fctr == 0) + throw CanteraError("toSI","unknown unit: "+tok); + if (action == '-') f *= fctr; + else if (action == '/') f /= fctr; + if (k < 0) break; + action = u[k]; + u = u.substr(k+1,u.size()); + } + return f; + } + + private: + + static Unit* __u; + map m_u; + Unit(){ + + // length + m_u["m"] = 1.0; + m_u["cm"] = 0.01; + m_u["km"] = 1.0e3; + m_u["mm"] = 1.0e-3; + m_u["micron"] = 1.0e-6; + m_u["A"] = 1.0e-10; + + // energy + m_u["J"] = 1.0; + m_u["kJ"] = 1.0e3; + m_u["cal"] = 4.184; + m_u["kcal"] = 4184.0; + + // quantity + m_u["mol"] = 1.0e-3; + m_u["mole"] = 1.0e-3; + m_u["kmol"] = 1.0; + m_u["molec"] = 1.0/Avogadro; + + // temperature + m_u["K"] = 1.0; + m_u["C"] = 1.0; + + // mass + m_u["g"] = 1.0e-3; + m_u["kg"] = 1.0; + + // pressure + m_u["atm"] = 1.01325e5; + m_u["bar"] = 1.0e5; + m_u["Pa"] = 1.0; + } + }; +} + +#endif diff --git a/Cantera/src/updaters.h b/Cantera/src/updaters.h new file mode 100755 index 000000000..7985645e7 --- /dev/null +++ b/Cantera/src/updaters.h @@ -0,0 +1,113 @@ +#ifndef CT_UPDATERS_H +#define CT_UPDATERS_H + +#include "PropertyUpdater.h" + +namespace Cantera { + + //-------------------------------------------------------- + // Property Updaters + //-------------------------------------------------------- + + /** + * Invokes method 'update_T' of the object it is initialized with. + */ + template + struct T_Updater : public Updater { + T_Updater(S& s) : m_s(s) {} + void update() { m_s.update_T(); } + S& m_s; + }; + + + /** + * Invokes method 'updateMoleFractions' of the object it is + * initialized with. + */ + template + struct UpdateMoleFractions : public Updater { + UpdateMoleFractions(S& s) : Updater(), m_s(s) {} + void update() { m_s.updateMoleFractions(); } + S& m_s; + }; + + /** + * Invokes method 'updateMW' of the object it is + * initialized with. + */ + template + struct UpdateMolWt : public Updater { + UpdateMolWt(S& s) : Updater(), m_s(s) {} + void update() { m_s.updateMW(); } + S& m_s; + }; + + /** + * Updater responsible for updating the species standard-state + * thermodynamic properties. + * @ingroup updategroup + */ + template + struct UpdateThermo : public Updater { + UpdateThermo(S& s) : Updater(), m_s(s) {} + void update() { m_s._updateThermo(); } + + S& m_s; + }; + + /** + * Updater responsible for updating the temperature-dependent + * parts of the transport properties. + * @ingroup updategroup + */ + template + struct UpdateTransport_T : public Updater { + UpdateTransport_T(S& s) : Updater(), m_s(s) {} + void update() { m_s._update_transport_T(); } + S& m_s; + }; + + + /** + * Updater responsible for updating the concentration-dependent + * parts of the transport properties. + * @ingroup updategroup + */ + template + struct UpdateTransport_C : public Updater { + UpdateTransport_C(S& s) : Updater(), m_s(s) {} + void update() { m_s._update_transport_C(); } + S& m_s; + }; + + + /** + * Template for an updater subclass that calls method _updateRates_T() + * of the object it is initialized with. + * @ingroup updategroup + */ + template + struct UpdateRates_T : public Updater { + UpdateRates_T(S& s) : Updater(), m_s(s) {} + void update() { m_s._update_rates_T(); } + S& m_s; + }; + + /** + * Template for an updater subclass that calls method _updateRates_C() + * of the object it is initialized with. + * @ingroup updategroup + */ + template + struct UpdateRates_C : public Updater { + UpdateRates_C(S& s) : Updater(), m_s(s) {} + void update() { m_s._update_rates_C(); } + S& m_s; + }; + + +} + +#endif + + diff --git a/Cantera/src/utilities.h b/Cantera/src/utilities.h new file mode 100755 index 000000000..42dd6a099 --- /dev/null +++ b/Cantera/src/utilities.h @@ -0,0 +1,281 @@ +/** + * @file utilities.h + * + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_UTILITIES_H +#define CT_UTILITIES_H + +#include "ct_defs.h" +//#include + +extern "C" { + +#ifdef HAVE_INTEL_MKL +#include "mkl_vml.h" +#endif + +} + +namespace Cantera { + + /** + * Maximum of i and j. + */ + template + inline T max(T i, S j) { + return (i > T(j) ? i : T(j)); + } + + /** + * Minimum of i and j. + */ + template + inline T min(T i, S j) { + return (i < T(j) ? i : T(j)); + } + + /** + * Inner product of two vectors of length 4. + * If either \i x + * or \i y has length greater than 4, only the first 4 elements + * will be used. + */ + template + inline doublereal dot4(const V& x, const V& y) { + return x[0]*y[0] + x[1]*y[1] + x[2]*y[2] + x[3]*y[3]; + } + + /** + * Inner product of two vectors of length 5. + * If either \i x + * or \i y has length greater than 5, only the first 5 elements + * will be used. + */ + template + inline doublereal dot5(const V& x, const V& y) { + return x[0]*y[0] + x[1]*y[1] + x[2]*y[2] + x[3]*y[3] + + x[4]*y[4]; + } + + /** + * Inner product of two vectors of length 6. + * If either \i x + * or \i y has length greater than 6, only the first 6 elements + * will be used. + */ + template + inline doublereal dot6(const V& x, const V& y) { + return x[0]*y[0] + x[1]*y[1] + x[2]*y[2] + x[3]*y[3] + + x[4]*y[4] + x[5]*y[5]; + } + + /** + * Inner product. + */ + template + inline doublereal dot(_InputIter x_begin, _InputIter x_end, + _InputIter2 y_begin) { + doublereal sum = 0.0; + for(; x_begin != x_end; ++x_begin, ++y_begin) + sum += *x_begin * *y_begin; + return sum; + } + + /** + * Multiply elements of an array by a scale factor. + * \code + * vector_fp in(8, 1.0), out(8); + * scale(in.begin(), in.end(), out.begin(), factor); + * \endcode + */ + template + inline void scale(_InputIter __begin, _InputIter __end, + _OutputIter __out, S scale_factor) { + for (; __begin != __end; ++__begin, ++__out) + *__out = scale_factor * *__begin; + } + + /** + * Multiply each entry in x by the corresponding entry in y. + */ + template + inline void multiply_each(_OutputIter x_begin, _OutputIter x_end, + _InputIter y_begin) { + for(; x_begin != x_end; ++x_begin, ++y_begin) *x_begin *= *y_begin; + } + + + /** + * Invoke method 'resize' with argument \i m for a sequence of objects. + */ + template + inline void _resize_each(int m, _InputIter __begin, _InputIter __end) { + for(; __begin != __end; ++__begin) __begin->resize(m); + } + + /** + * The maximum absolute value. + */ + template + inline doublereal absmax(_InputIter __begin, _InputIter __end) { + doublereal amax = 0.0; + for(; __begin != __end; ++__begin) + if (fabs(*__begin) > amax) amax = fabs(*__begin); + return amax; + } + + /** + * Normalize the values in a sequence, such that they sum to 1.0. + */ + template + inline void normalize(_InputIter __begin, _InputIter __end, + _OutputIter __out) { + doublereal sum = accumulate(__begin, __end, 0.0); + for (; __begin != __end; ++__begin, ++__out) *__out = *__begin/sum; + } + + /** + * Divide each element of \i x by the corresponding element of \i y. + */ + template + inline void divide_each(_OutputIter x_begin, _OutputIter x_end, + _InputIter y_begin) { +#ifdef HAVE_INTEL_MKL + vdDiv(int(x_end - x_begin), x_begin, y_begin, x_begin); +#else + for(; x_begin != x_end; ++x_begin, ++y_begin) *x_begin /= *y_begin; +#endif + } + + /** + * Increment each entry in \i x by the corresponding entry in \i y. + */ + template + inline void sum_each(_OutputIter x_begin, _OutputIter x_end, + _InputIter y_begin) { + for(; x_begin != x_end; ++x_begin, ++y_begin) *x_begin += *y_begin; + } + + /** Copies a contiguous range in a sequence to indexed + * positions in another sequence. Example: + * + * \code + * vector x(3), y(20), ; + * vector index(3); + * index[0] = 9; + * index[1] = 2; + * index[3] = 16; + * _scatter_copy(x.begin(), x.end(), y.begin(), index.begin()); + * \endcode + */ + template + inline void _scatter_copy(_InputIter __begin, _InputIter __end, + _OutputIter __result, _IndexIter __index) { + for (; __begin != __end; ++__begin, ++__index) { + *(__result + *__index) = *__begin; + } + } + + /** + * Multiply selected values in a sequence by . x[indx[i]] *= m[i] + * \code + * vector multipliers(3), data(20); + * vector index(3); + * ... + * _scatter_mult(multipliers.begin(), multipliers.end(), data.begin(), + * index.begin()); + * \endcode + */ + + template + inline void _scatter_mult(_InputIter __begin, _InputIter __end, + _RandAccessIter __result, _IndexIter __index) { + for (; __begin != __end; ++__begin, ++__index) { + *(__result + *__index) *= *__begin; + } + } + + + template + inline void _scatter_divide(_InputIter __begin, _InputIter __end, + _OutputIter __result, _IndexIter __index) { + for (; __begin != __end; ++__begin, ++__index) { + *(__result + *__index) /= *__begin; + } + } + + template + inline doublereal _sum_xlogx(_InputIter __begin, _InputIter __end) { + doublereal sum = 0.0; + for (; __begin != __end; ++__begin) { + sum += (*__begin) * log(*__begin + Tiny); + } + return sum; + } + + template + inline doublereal _sum_xlogQ(_InputIter1 __begin, _InputIter1 __end, + _InputIter2 _Q_begin) { + doublereal sum = 0.0; + for (; __begin != __end; ++__begin, ++_Q_begin) { + sum += (*__begin) * log(*_Q_begin + Tiny); + } + return sum; + } + + + /** calls method 'update' for each object in a range, and writes the + * result into indexed positions in sequence 'output'. + * + * \code + * vector x(3); + * vector index(3); + * index[0] = 9; + * index[1] = 2; + * index[3] = 16; + * vector output(20); + * _scatter_update(x.begin(), x.end(), output.begin(), index.begin()); + * \endcode + */ + template + inline void _scatter_update(_InputIter __begin, _InputIter __end, + _OutputIter __result, _IndexIter __index, const _Params& __params) { + for (; __begin != __end; ++__begin, ++__index) { + *(__result + *__index) = (*__begin).update(__params); + } + } + + template + inline void _update(_InputIter __begin, _InputIter __end, + _OutputIter __result, const _Params& __params) { + for (; __begin != __end; ++__begin, ++__result) { + *__result = (*__begin).update(__params); + } + } + +} + + +#endif + + + + + + + + + + + + + + + + + diff --git a/Cantera/src/vec_functions.h b/Cantera/src/vec_functions.h new file mode 100755 index 000000000..de5e9e133 --- /dev/null +++ b/Cantera/src/vec_functions.h @@ -0,0 +1,114 @@ +/** + * + * @file vec_functions.h + * + * Templates for operations on vector-like objects. + * + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2001 California Institute of Technology + * + */ + +#ifndef CT_VEC_FUNCTIONS_H +#define CT_VEC_FUNCTIONS_H + +#include "ct_defs.h" +#include +#include +#include + +namespace Cantera { + + /** + * Copy the first n entries from x to y. Both x and y must have + * size greater than or equal to n. + */ + template + inline void copyn(size_t n, const T& x, T& y) { + copy(x.begin(), x.begin() + n, y.begin()); + } + + /** + * Divide each element of x by the corresponding element of y. + * This function replaces x[n] by x[n]/y[n], for 0 <= n < x.size() + */ + template + inline void divide_each(T& x, const T& y) { + transform(x.begin(), x.end(), y.begin(), + x.begin(), divides()); + } + + /** + * multiply each element of x by the corresponding element of y. + * This function replaces x[n] by x[n]*y[n], for 0 <= n < x.size() + */ + template + inline void multiply_each(T& x, const T& y) { + transform(x.begin(), x.end(), y.begin(), + x.begin(), multiplies()); + } + + /** + * Multiply each element of x by scale_factor. + */ + template + inline void scale(T& x, S scale_factor) { + scale(x.begin(), x.end(), x.begin(), scale_factor); + } + + /** + * Returns the sum of x[n]*y[n], for 0 <= n < x.size(). + */ + template + inline doublereal dot_product(const T& x, const T& y) { + return inner_product(x.begin(), x.end(), y.begin(), 0.0); + } + + /** + * Returns the sum of x[n]/y[n], for 0 <= n < x.size(). + */ + template + inline doublereal dot_ratio(const T& x, const T& y) { + return __dot_ratio(x.begin(), x.end(), y.begin(), 0.0); + } + + /** + * Replaces x[n] by x[n] + y[n] for 0 <= n < x.size() + */ + template + inline void add_each(T& x, const T& y) { + transform(x.begin(), x.end(), y.begin(), + x.begin(), plus()); + } + + template + inline doublereal __dot_ratio(_InputIter __x_begin, _InputIter __x_end, + _InputIter __y_begin, S start_value) { + for (; __x_begin != __x_end; ++__x_begin, ++__y_begin) + start_value += *__x_begin / *__y_begin; + return start_value; + } + + /** + * Finds the entry in a vector with maximum absolute + * value, and return this value. + */ + template + inline T absmax(const vector& v) { + int n = v.size(); + T val; + T maxval = 0.0; + for (int i = 0; i < n; i++) { + val = v[i]; + if (val < 0) val = -val; + if (val > maxval) maxval = val; + } + return maxval; + } + +} + +#endif diff --git a/Cantera/src/xml.cpp b/Cantera/src/xml.cpp new file mode 100755 index 000000000..9c0baecba --- /dev/null +++ b/Cantera/src/xml.cpp @@ -0,0 +1,543 @@ + +// simple xml functions + +// turn off warnings under Windows +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include +using namespace std; + +#include "xml.h" + +#define XML_INDENT 4 + +namespace Cantera { + + + static void split(const string& src, string& file, string& id) { + int ipound = src.find('#'); + + if (ipound >= 0) { + id = src.substr(ipound+1,src.size()); + file = src.substr(0,ipound); + } + else { + id = ""; + file = src; + } + } + + + ////////////////////// exceptions //////////////////////////// + + + class XML_Error : public CanteraError { + public: + XML_Error(int line=0) : m_line(line) { + m_msg = "Error in XML file"; + if (line > 0) { + m_msg += " at line " + line; + } + m_msg += ".\n"; + } + virtual ~XML_Error() {} + protected: + int m_line; + string m_msg; + }; + + class XML_TagMismatch : public XML_Error { + public: + XML_TagMismatch(string opentag, string closetag, + int line=0) : XML_Error(line) { + m_msg += "<" + opentag + "> paired with .\n"; + setError("XML_TagMismatch",m_msg); + } + virtual ~XML_TagMismatch() {} + }; + + class XML_NoChild : public XML_Error { + public: + XML_NoChild(string parent, string child) { + m_msg += "Node " + parent + " has no child named " + + child + ".\n"; + setError("XML_NoChild",m_msg); + } + virtual ~XML_NoChild() {} + }; + + class XML_IllegalUnits : public XML_Error { + public: + XML_IllegalUnits(string name, string units) { + m_msg += "Illegal units (" + units + + ") specified for node " + name + ".\n"; + setError("XML_IllegalUnits",m_msg); + } + virtual ~XML_IllegalUnits() {} + }; + + + + //////////////////// XML_Reader methods /////////////////////// + + + + void XML_Reader::getchr(char& ch) { + m_s.get(ch); + if (ch == '\n') m_line++; + } + + string XML_Reader::strip(const string& aline) { + int len = aline.size(); + int i, j; + for (i = len-1; i >= 0; i--) + if (aline[i] != ' ' && aline[i] != '\n') break; + for (j = 0; j < i; j++) + if (aline[j] != ' ' && aline[j] != '\n') break; + return aline.substr(j, i - j + 1); + } + + string XML_Reader::inquotes(const string& aline) { + int len = aline.size(); + int i, j; + for (i = len-1; i >= 0; i--) + if (aline[i] == '"') break; + for (j = 0; j < i; j++) + if (aline[j] == '"') break; + if (j == i) return ""; + else return aline.substr(j+1, i - j - 1); + } + + + void XML_Reader::parseTag(string line, string& name, + map& attribs) { + int iloc; + string attr, val; + string s = strip(line); + iloc = s.find(' '); + if (iloc > 0) { + name = s.substr(0, iloc); + s = strip(s.substr(iloc+1,s.size())); + if (s[s.size()-1] == '/') name += "/"; + // get attributes + while (1) { + iloc = s.find('='); + if (iloc < 0) break; + attr = strip(s.substr(0,iloc)); + if (attr == "") break; + s = strip(s.substr(iloc+1,s.size())); + iloc = s.find(' '); + if (iloc < 0) iloc = s.size(); + val = inquotes(s.substr(0,iloc)); + attribs[attr] = val; + if (iloc < int(s.size())) + s = strip(s.substr(iloc+1,s.size())); + else + break; + } + } + else { + name = s; + } + } + + string XML_Reader::readTag(map& attribs) { + string name, tag = ""; + bool incomment = false; + char ch = '-'; + while (1) { + if (m_s.eof() || (getchr(ch), ch == '<')) break; + } + char ch1 = ' ', ch2 = ' '; + while (1) { + if (m_s.eof()) { tag = "EOF"; break;} + ch2 = ch1; + ch1 = ch; + getchr(ch); + if (ch == '-') { + if (ch1 == '-' && ch2 == '!') { + incomment = true; + tag = "-"; + } + } + else if (ch == '>') { + if (incomment) { + if (ch1 == '-' && ch2 == '-') break; + } + else + break; + } + if (isprint(ch)) tag += ch; + } + if (incomment) { + attribs.clear(); + return tag; + } + else { + parseTag(tag, name, attribs); + return name; + } + } + + string XML_Reader::readValue() { + string tag = ""; + char ch, lastch; + ch = '\n'; + bool front = true; + while (1) { + if (m_s.eof()) break; + lastch = ch; + getchr(ch); + if (ch == '\n') + front = true; + else if (ch != ' ') + front = false; + if (ch == '<') { + m_s.putback(ch); + break; + } + if (front && lastch == ' ' && ch == ' ') ; + else tag += ch; + } + return strip(tag); + } + + + ////////////////////////// XML_Node ///////////////////////////////// + + + XML_Node::XML_Node(string nm, XML_Node* p, int n) + : m_name(nm), m_level(0), m_parent(p), m_nchildren(0), + m_n(n), m_iscomment(false) { + if (!p) m_root = this; + else m_root = &p->root(); + } + + + XML_Node::~XML_Node() { + int n = m_children.size(); + for (int i = 0; i < n; i++) { + if (m_children[i]) { + if (m_children[i]->parent() == this) { + delete m_children[i]; + m_children[i] = 0; + } + } + } + } + + void XML_Node::addComment(string comment) { + addChild("comment",comment); + } + + XML_Node& XML_Node::addChild(XML_Node& node) { + m_children.push_back(&node); + m_nchildren = m_children.size(); + m_childindex[node.name()] = m_children.back(); + node.setRoot(root()); + return *m_children.back(); + } + + XML_Node& XML_Node::addChild(string name) { + int n = m_children.size(); + m_children.push_back(new XML_Node(name, this, n)); + m_nchildren = m_children.size(); + m_childindex[name] = m_children.back(); + m_children.back()->setParent(this); + return *m_children.back(); + } + + void XML_Node::removeChild(XML_Node* node) { + vector::iterator i; + i = find(m_children.begin(), m_children.end(), node); + m_children.erase(i); + m_nchildren = m_children.size(); + m_childindex.erase(node->name()); + } + + XML_Node* XML_Node::findID(const string& id, int depth) { + if (hasAttrib("id")) { + if (attrib("id") == id) { + return this; + } + } + if (depth > 0) { + XML_Node* r = 0; + int n = nChildren(); + for (int i = 0; i < n; i++) { + r = m_children[i]->findID(id, depth-1); + if (r != 0) return r; + } + } + return 0; + } + + XML_Node* XML_Node::findByAttr(const string& attr, const string& val) { + if (hasAttrib(attr)) { + if (attrib(attr) == val) { + return this; + } + } + XML_Node* r = 0; + int n = nChildren(); + for (int i = 0; i < n; i++) { + r = m_children[i]->findByAttr(attr, val); + if (r != 0) return r; + } + return 0; + } + + XML_Node* XML_Node::findByName(const string& nm) { + if (name() == nm) { + return this; + } + XML_Node* r = 0; + int n = nChildren(); + for (int i = 0; i < n; i++) { + r = m_children[i]->findByName(nm); + if (r != 0) return r; + } + return 0; + } + + /** + * addChild(string name, string value): + * + * Add a child node to the current xml node, and at the + * same time add a value to the child + * + * Resulting XML string: + * value + * + * Return + * ------- + * Returns a reference to the created child XML_Node object + */ + XML_Node& XML_Node::addChild(string name, string value) { + XML_Node& c = addChild(name); + c.addValue(value); + return c; + } + + XML_Node& XML_Node::addChild(string name, double value, string fmt) { + XML_Node& c = addChild(name); + c.addValue(value,fmt); + return c; + } + + void XML_Node::addValue(string val) { + m_value = val; + if (m_name == "comment") m_iscomment = true; + } + void XML_Node::addValue(doublereal val, string fmt) { + char buf[30]; + sprintf(buf,fmt.c_str(),val); + m_value = stripws(buf); + } + + void XML_Node::addAttribute(string attrib, string value) { + m_attribs[attrib] = value; + } + void XML_Node::addAttribute(string attrib, double value, string fmt) { + m_attribs[attrib] = fp2str(value, fmt); + } + + void XML_Node::writeHeader(ostream& s) { + s << "" << endl; + } + + void XML_Node::build(istream& f) { + XML_Reader r(f); + string nm, nm2, val; + XML_Node* node = this; + map attribs; + while (!f.eof()) { + attribs.clear(); + nm = r.readTag(attribs); + if (nm == "EOF") break; + int lnum = r.m_line; + if (nm[nm.size() - 1] == '/') { + nm2 = nm.substr(0,nm.size()-1); + node = &node->addChild(nm2); + node->addValue(""); + node->attribs() = attribs; + node = node->parent(); + } + else if (nm[0] != '/') { + if (nm[0] != '!' && nm[0] != '-' && nm[0] != '?') { + node = &node->addChild(nm); + val = r.readValue(); + node->addValue(val); + node->attribs() = attribs; + } + else if (nm.substr(0,2) == "--") { + if (nm.substr(nm.size()-2,2) == "--") { + node->addComment(nm.substr(2,nm.size()-4)); + } + } + } + else { + if (node->name() != nm.substr(1,nm.size()-1)) + throw XML_TagMismatch(node->name(), + nm.substr(1,nm.size()-1), lnum); + node = node->parent(); + } + } + } + + + void XML_Node::getChildren(string nm, + vector& children) const { + int i, n = nChildren(); + for (i = 0; i < n; i++) { + if (child(i).name() == nm) { + children.push_back(&child(i)); + } + } + } + + XML_Node& XML_Node::child(string loc) const { + int iloc; + string cname; + map::const_iterator i; + while (1) { + iloc = loc.find('/'); + if (iloc >= 0) { + cname = loc.substr(0,iloc); + loc = loc.substr(iloc+1, loc.size()); + i = m_childindex.find(cname); + //XML_Node* chld = m_childindex[cname]; + if (i != m_childindex.end()) return i->second->child(loc); + else throw XML_NoChild(m_name, cname); + } + else { + i = m_childindex.find(loc); + if (i != m_childindex.end()) return *(i->second); + //XML_Node* chld = m_childindex[loc]; + //if (chld) return *chld; + else throw XML_NoChild(m_name, loc); + } + } + } + + void XML_Node::write(ostream& s, int level) { + + if (m_name == "") return; + + m_level = level; + string indent(level,' '); + if (m_iscomment) { + s << endl << indent << ""; + return; + } + + s << indent << "<" << m_name; + map::const_iterator b = m_attribs.begin(); + for (; b != m_attribs.end(); ++b) { + s << " " << b->first << "=\"" << b->second << "\""; + } + if (m_value == "" && m_nchildren == 0) { + s << "/>"; + } + else { + s << ">"; + + if (m_value != "") { + string vv = m_value; + int ieol = vv.find('\n'); + if (ieol >= 0) { + while (1 > 0) { + ieol = vv.find('\n'); + if (ieol >= 0) { + s << endl << indent << vv.substr(0,ieol); + vv = vv.substr(ieol+1,vv.size()); + } + else { + s << endl << indent << vv; + break; + } + } + } + else + s << m_value; + } + int i; + for (i = 0; i < m_nchildren; i++) { + s << endl; + m_children[i]->write(s,level + 2); + } + if (m_nchildren > 0) s << endl << indent; + s << ""; + } + } + + XML_Node* XML_Node::getRef() { + if (!hasAttrib("idRef")) return this; + XML_Node& node = *this; + return find_XML(node["src"], &root(), node["idRef"]); + } + + XML_Node* find_XML(string src, XML_Node* root, string id, string loc, + string name) { + + string file, id2; + split(src, file, id2); + src = file; + if (id2 != "") id = id2; + + XML_Node *doc = 0, *r = 0; + if (src != "") { + doc = new XML_Node("doc"); + string spath = findInputFile(src); + ifstream fin(spath.c_str()); + if (!fin) + throw CanteraError("find_XML","could not open file "+src+ + " for input."); + doc->build(fin); + root = 0; + } + else if (root) { + doc = root; + } + else { + throw CanteraError("find_XML", + "either root or src must be specified."); + } + + try { + if (id != "") + r = doc->findID(id); + else if (loc != "") + r = &doc->child(loc); + else if (name != "") + r = doc->findByName(name); + if (!r) { + string opt = " src="+src+", loc="+loc+", id=" + +id+", name="+name; + throw CanteraError("find_XML", "XML element with "+opt+ + " not found."); + } + return r; + } + catch (CanteraError) { + + // root was used, but element was not found. Try src. + if (root && src != "") { + return find_XML(src, 0, id, loc, name); + } + else { + string opt = " src="+src+", loc="+loc+", id=" + +id+", name="+name; + throw CanteraError("find_XML", "XML element with "+opt+ + " not found."); + return 0; + } + } + } + +} + + diff --git a/Cantera/src/xml.h b/Cantera/src/xml.h new file mode 100755 index 000000000..cbbaf1b56 --- /dev/null +++ b/Cantera/src/xml.h @@ -0,0 +1,239 @@ +/** + * Classes providing support for XML data files. These classes + * implement only those aspects of XML required to read, write, and + * manipulate CTML data files. + */ + +#ifndef CT_XML +#define CT_XML + +#include +#include +#include +using namespace std; + +#include "ctexceptions.h" +#include "ct_defs.h" +#include "stringUtils.h" +#include +#include "global.h" + +#define XML_INDENT 4 + + +namespace Cantera { + + + /** + * Class XML_Reader is designed for internal use. + */ + class XML_Reader { + public: + XML_Reader(istream& input) : m_s(input), m_line(0) {} + + istream& m_s; + int m_line; + + void getchr(char& ch); + string strip(const string& aline); + string inquotes(const string& aline); + void parseTag(string line, string& name, map& attribs); + string readTag(map& attribs); + string readValue(); + }; + + + ////////////////////////// XML_Node ///////////////////////////////// + + class XML_Node { + public: + + XML_Node(string nm = "--", XML_Node* p = 0, int n = 0); + virtual ~XML_Node(); + void addComment(string comment); + XML_Node& addChild(XML_Node& node); + XML_Node& addChild(string name); + XML_Node& addChild(string name, string value); + XML_Node& addChild(string name, double value, string fmt="%g"); + void removeChild(XML_Node* node); + void addValue(string val); + void addValue(doublereal val, string fmt="%g"); + void addAttribute(string attrib, string value); + void addAttribute(string attrib, double value, string fmt="%g"); + void writeHeader(ostream& s); + string value() const { return m_value; } + string value(string loc) const { return child(loc).value(); } + doublereal fp_value() const { + return atof(m_value.c_str()); + } + integer int_value() const { + return atoi(m_value.c_str()); + } + string operator()() const { return m_value; } + string operator()(string loc) const { return value(loc); } + string operator[](string attr) const { + return attrib(attr); + //if (hasAttrib(attr)) {return m_attribs[attr]; } + } + string attrib(string attr) const { + map::const_iterator i = m_attribs.find(attr); + if (i != m_attribs.end()) return i->second; + else return ""; + } + map& attribs() { return m_attribs; } + XML_Node* parent() { return m_parent; } + XML_Node* setParent(XML_Node* p) { m_parent = p; return p; } + + bool hasChild(string ch) { + return (m_childindex.find(ch) != m_childindex.end()); + //return (m_childindex[ch] != 0); + } + bool hasAttrib(string a) const { + return (m_attribs.find(a) != m_attribs.end()); + //if (m_attribs[a] != "") return true; + //else { + // m_attribs.erase(a); + // return false; + //} + } + + string name() { return m_name; } + string id() { + if (hasAttrib("id")) return attrib("id"); + else return ""; + } + int number() { return m_n; } + + XML_Node& child(int n) const { return *m_children[n]; } + vector children() { return m_children; } + int nChildren() const { return m_nchildren; } + + void build(istream& f); + + XML_Node* findID(const string& id, int depth=100); + XML_Node* findByAttr(const string& attr, const string& val); + XML_Node* findByName(const string& nm); + void getChildren(string name, vector& children) const; + XML_Node& child(string loc) const; + void write(ostream& s, int level = 0); + XML_Node* getRef(); + XML_Node& root() { return *m_root; } + void setRoot(XML_Node& root) { m_root = &root; } + + protected: + + vector m_tags; + string m_name; + string m_value; + int m_level; + map m_childindex; + map m_attribs; + XML_Node* m_parent; + XML_Node* m_root; + vector m_children; + int m_nchildren; + int m_n; + bool m_iscomment; + }; + + + ////////////////////// XML_Writer ////////////////////////// + + class XML_Writer { + public: + XML_Writer(ostream& output) : + m_s(output), _indent(" "), _level(0) {} + virtual ~XML_Writer() {} + ostream& m_s; + + string _indent; + int _level; + + ostream& output() { return m_s; } + + inline string XML_filter(string name) { + int ns = name.size(); + string nm(name); + for (int m = 0; m < ns; m++) + if (name[m] == ' ' + || name[m] == '(' + || name[m] == ')') + nm[m] = '_'; + return nm; + } + + /** + * XML_comment() + * + * Add a comment element to the current XML output file + * Comment elements start with + * Comments are indented according to the current lvl, + * _level + * + * input + * --------- + * s : Output stream containing the XML file + * comment : Reference to a string containing the comment + */ + inline void XML_comment(ostream& s, const string& comment) { + for (int n = 0; n < _level; n++) s << _indent; + s << "" << endl; + } + + inline void XML_open(ostream& s, const string& tag, const string p = "") { + for (int n = 0; n < _level; n++) s << _indent; + _level++; + s << "<" << XML_filter(tag) << p << ">" << endl; + } + + inline void XML_close(ostream& s, const string& tag) { + _level--; + for (int n = 0; n < _level; n++) s << _indent; + s << "" << endl; + } + + template + void XML_item(ostream& s, const string& tag, T value) { + for (int n = 0; n < _level; n++) s << _indent; + s << "<" << XML_filter(tag) << ">" + << value << "" << endl; + } + + template + void XML_writeVector(ostream& s, const string& indent, + const string& name, int vsize, iter v) { + int ni; + for (ni = 0; ni < _level; ni++) s << _indent; + s << "<" << XML_filter(name) << "> "; + + int n = vsize; + int n5 = n/5; + int i, j, k = 0; + for (j = 0; j < n5; j++) { + for (i = 0; i < 5; i++) { + s << v[k] << (k < n - 1 ? ", " : ""); + k++; + } + if (j < n5-1) { + s << endl; + for (ni = 0; ni < _level; ni++) s << _indent; + } + } + for (i = k; i < n; i++) { + s << v[k] << (k < n - 1 ? ", " : ""); + k++; + } + + s << "" << endl; + } + }; + + //inline XML_getByID(string file, string id) { + + XML_Node* find_XML(string src, XML_Node* root=0, + string id="", string loc="", string name=""); + +} + +#endif + diff --git a/Cantera/src/zeroD/.cvsignore b/Cantera/src/zeroD/.cvsignore new file mode 100644 index 000000000..57751bad9 --- /dev/null +++ b/Cantera/src/zeroD/.cvsignore @@ -0,0 +1,2 @@ +Makefile +.depends diff --git a/Cantera/src/zeroD/FlowDevice.cpp b/Cantera/src/zeroD/FlowDevice.cpp new file mode 100644 index 000000000..1a6eaafba --- /dev/null +++ b/Cantera/src/zeroD/FlowDevice.cpp @@ -0,0 +1,53 @@ + +#include "FlowDevice.h" +#include "ReactorBase.h" +#include "Func1.h" + +namespace Cantera { + + bool FlowDevice::install(ReactorBase& in, ReactorBase& out) { + if (m_in || m_out) return false; + m_in = ∈ + m_out = &out; + m_in->addOutlet(*this); + m_out->addInlet(*this); + + // construct adapters between inlet and outlet species + phase_t* mixin = &m_in->contents(); + phase_t* mixout = &m_out->contents(); + if (mixin == 0 || mixout == 0) return false; + + m_nspin = mixin->nSpecies(); + m_nspout = mixout->nSpecies(); + string nm; + int ki, ko; + for (ki = 0; ki < m_nspin; ki++) { + nm = mixin->speciesName(ki); + ko = mixout->speciesIndex(nm); + m_in2out.push_back(ko); + } + for (ko = 0; ko < m_nspout; ko++) { + nm = mixout->speciesName(ko); + ki = mixin->speciesIndex(nm); + m_out2in.push_back(ki); + } + return true; + } + + void FlowDevice::setFunction(Func1* f) {} + + + /** + * Mass flow rate of outlet species k. Returns zero if this + * species is not present in the upstream mixture. + */ + doublereal FlowDevice::massFlowRate(int k) { + if (k < 0 || k >= m_nspout) return 0.0; + int ki = m_out2in[k]; + if (ki < 0) return 0.0; + return m_mdot * m_in->massFraction(ki); + } + + doublereal FlowDevice::enthalpy_mass() { return m_in->enthalpy_mass(); } + +} diff --git a/Cantera/src/zeroD/FlowDevice.h b/Cantera/src/zeroD/FlowDevice.h new file mode 100644 index 000000000..a0ff54bd5 --- /dev/null +++ b/Cantera/src/zeroD/FlowDevice.h @@ -0,0 +1,163 @@ +/** + * @file FlowDevice.h + * + * $Author$ + * $Date$ + * $Revision$ + */ + +// Copyright 2001 California Institute of Technology + +#ifndef CT_FLOWDEVICE_H +#define CT_FLOWDEVICE_H + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "../ct_defs.h" + +namespace Cantera { + + class ReactorBase; // forward reference + class Func1; + + const int MFC_Type = 1; + const int PressureReg_Type = 2; + const int Valve_Type = 3; + + /** + * Base class for 'flow devices' (valves, pressure regulators, + * etc.) connecting reactors. Allowance is made for devices that + * are closed-loop controllers. Several methods for these are + * defined here that do nothing but may be overloaded to set or + * get the setpoint, gains, etc. The behavior of overloaded + * methods should be consistent with the behavior described + * here. The base-class versions of these methods print a warning + * if called. + * @ingroup reactor0 + */ + class FlowDevice { + + public: + + /// Constructor + FlowDevice() : m_mdot(0.0), + m_nspin(0), m_nspout(0), + m_in(0), m_out(0) {} + + /// Destructor (does nothing) + virtual ~FlowDevice(){} + + /// Copy constructor. + FlowDevice(const FlowDevice& a) : m_in(a.m_in), m_out(a.m_out) {} + + /// Assignment operator + FlowDevice& operator=(const FlowDevice& a) { + if (this == &a) return *this; + m_in = a.m_in; + m_out = a.m_out; + return *this; + } + + /** + * Mass flow rate (kg/s). May be overloaded in derived + * classes. + */ + virtual doublereal massFlowRate() {return m_mdot;} + + doublereal massFlowRate(int k); + virtual doublereal enthalpy_mass(); + + /** + * Setpoint. Default = 0.0. + */ + virtual doublereal setpoint() { warn("setpoint"); return 0.0; } + + /* Update the internal state, if necessary. By default this method + * does nothing, but may be overloaded for devices that have a + * state. + */ + virtual void update() {warn("update");} + + /* Reset the device. By default this method does nothing, but + * may be overloaded for devices that have a state that depends on + * past history. + */ + virtual void reset() {warn("reset");} + + /** + * Set the setpoint. May be changed at any time. By default, + * this does nothing. + */ + virtual void setSetpoint(doublereal value) {warn("setSetpoint");} + + /** + * Set the controller gains. Returns false if the number of + * gains is too small, or if an illegal value is specified. + */ + virtual bool setGains(int n, const doublereal* gains) { + warn("setGains"); + return true; + } + + /** + * Get the controller gains. Returns false if the 'gains' + * array is too small. + */ + virtual bool getGains(int n, doublereal* gains) { + warn("getGains"); + return true; + } + + /** + * Maximum difference between input and setpoint since + * last call to 'reset'. + */ + virtual doublereal maxError() {warn("maxError"); return 0.0;} + + /** + * Install a flow device between two reactors. + * @param in Upstream reactor. + * @param out Downstream reactor. + */ + bool install(ReactorBase& in, ReactorBase& out); + + virtual bool ready() { return (m_in != 0 && m_out != 0); } + doublereal m_mdot; + + /// Return a reference to the upstream reactor. + ReactorBase& in() const { return *m_in; } + + /// Return a const reference to the downstream reactor. + const ReactorBase& out() const { return *m_out; } + + /// set parameters + virtual void setParameters(int n, doublereal* coeffs) { + m_coeffs.resize(n); + copy(coeffs, coeffs + n, m_coeffs.begin()); + } + + virtual void setFunction(Func1* f); + + protected: + + vector_fp m_coeffs; + + private: + + int m_nspin, m_nspout; + ReactorBase* m_in; + ReactorBase* m_out; + vector_int m_in2out, m_out2in; + + void warn(string meth) { + cerr << "Warning: method " << meth << " of base class " + << " FlowDevice called. Nothing done."; + } + }; + +} + +#endif diff --git a/Cantera/src/zeroD/Makefile.in b/Cantera/src/zeroD/Makefile.in new file mode 100644 index 000000000..376426422 --- /dev/null +++ b/Cantera/src/zeroD/Makefile.in @@ -0,0 +1,53 @@ +#/bin/sh +############################################################### +# $Author$ +# $Date$ +# $Revision$ +# +# Copyright 2002 California Institute of Technology +# +############################################################### + +SUFFIXES= +SUFFIXES= .cpp .d .o + +OBJDIR = . + +CXX_FLAGS = @CXXFLAGS@ $(CXX_OPT) + +# stirred reactors +OBJS = Reactor.o ReactorBase.o FlowDevice.o Wall.o + +CXX_INCLUDES = -I.. +ZEROD_LIB = ./libzeroD.a + +DEPENDS = $(OBJS:.o=.d) + +%.d: + g++ -MM $(CXX_INCLUDES) $*.cpp > $*.d + +.cpp.o: + @CXX@ -c $< @DEFS@ $(CXX_FLAGS) $(CXX_INCLUDES) + +.f.o: + @F77@ -c $< $(F77_FLAGS) + +all lib: $(ZEROD_LIB) + +$(ZEROD_LIB): $(OBJS) + @ARCHIVE@ $(ZEROD_LIB) $(OBJS) > /dev/null + +clean: + $(RM) *.o *~ $(ZEROD_LIB) + +depends: $(DEPENDS) + cat *.d > .depends + $(RM) $(DEPENDS) + +TAGS: + etags *.h *.cpp + +ifeq ($(wildcard .depends), .depends) +include .depends +endif + diff --git a/Cantera/src/zeroD/PID_Controller.h b/Cantera/src/zeroD/PID_Controller.h new file mode 100644 index 000000000..ff597499a --- /dev/null +++ b/Cantera/src/zeroD/PID_Controller.h @@ -0,0 +1,151 @@ +/** + * @file PID_Controller.h + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + +#ifndef CT_PID_H +#define CT_PID_H + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +namespace Cantera { + + + class PID_Controller { + + public: + + /// Default constructor. + PID_Controller() : m_v0(Undef), m_p(Undef), m_i(Undef), m_d(Undef), + m_setpoint(Undef), m_last(Undef), m_time(Undef), + m_xint(Undef), m_out(Undef), m_dt(Undef) {} + + /** + * Copy constructor. Gains and setpoint are copied, but not + * the internal parameters defining the state of the + * controller. Method 'reset' must be called for the copy + * before using it. + */ + PID_Controller(const PID_Controller& pid) + : m_v0(pid.m_v0), m_p(pid.m_p), m_i(pid.m_i), m_d(pid.m_d), + m_setpoint(pid.m_setpoint), + m_last(Undef), m_time(Undef), m_xint(Undef) {} + + /** + * Assignment operator. @see Copy constructor. + */ + PID_Controller& operator=(const PID_Controller& pid) { + if (this == &pid) return *this; + m_v0 = pid.m_v0; + m_p = pid.m_p; + m_i = pid.m_i; + m_d = pid.m_d; + m_setpoint = pid.m_setpoint; + m_last = Undef; + m_time = Undef; + m_xint = Undef; + return *this; + } + + /** + * Reset the start time to time, and the current value of + * the input to input. Sets the integrated error signal to zero. + */ + void reset(doublereal time = 0.0, doublereal input = 0.0) { + m_time = time; + m_last = input; + m_xint = 0.0; + m_out = m_v0; + m_dt = 1.0; + m_maxerr = 0.0; + } + + doublereal setpoint(doublereal y = Undef) { + if (y != Undef) { + m_setpoint = y; + } + return m_setpoint; + } + + bool getGains(vector_fp& gains) { + gains.resize(4); + return getGains(4, gains.begin()); + } + + bool getGains(int n, doublereal* gains) { + if (n < 4) return false; + gains[0] = m_v0; + gains[1] = m_p; + gains[2] = m_i; + gains[3] = m_d; + return true; + } + + bool setGains(const vector_fp& gains) { + return setGains(int(gains.size()), gains.begin()); + } + + bool setGains(int n, const doublereal* gains) { + if (n < 4) return false; + m_v0 = gains[0]; + m_p = gains[1]; + m_i = gains[2]; + m_d = gains[3]; + if (m_p < 0.0 || m_i < 0.0 || m_d < 0.0) { + return false; + } + return true; + } + + void update(doublereal time, doublereal input) { + if (time <= m_time) return; + doublereal err = input - m_setpoint; + if (fabs(err) > m_maxerr) m_maxerr = fabs(err); + m_dt = time - m_time; + m_xint += (0.5*(input + m_last) - m_setpoint) * m_dt; + m_last = input; + m_time = time; + doublereal xdot = (input - m_last)/m_dt; + m_out = m_v0 - m_p*(input - m_setpoint) - m_i*m_xint + - m_d*xdot; + } + + doublereal output(doublereal input) { + return fmaxx(0.0, + m_out - (m_p + m_d/m_dt + 0.5*m_i*m_dt)*(input - m_last)); + } + + doublereal maxError() { return m_maxerr; } + + bool ready() {return (m_time != Undef + && m_setpoint != Undef + && m_v0 != Undef); } + + protected: + + doublereal + m_v0, + m_p, + m_i, + m_d, + m_setpoint, + m_maxerr, + m_last, + m_time, + m_xint, + m_out, + m_dt; + }; + +} + +#endif + diff --git a/Cantera/src/zeroD/Reactor.cpp b/Cantera/src/zeroD/Reactor.cpp new file mode 100644 index 000000000..b04ecbb98 --- /dev/null +++ b/Cantera/src/zeroD/Reactor.cpp @@ -0,0 +1,225 @@ +/** + * @file Reactor.cpp + * + * A zero-dimensional reactor + */ + +// Copyright 2001 California Institute of Technology + + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "Reactor.h" +#include "../CVode.h" +#include "FlowDevice.h" +#include "Wall.h" + +namespace Cantera { + + doublereal quadInterp(doublereal x0, doublereal* x, doublereal* y); + + Reactor::Reactor() : ReactorBase(), + FuncEval(), + m_kin(0), + m_integ(0), + m_temp_atol(1.e-11), + m_maxstep(0.0), + m_vdot(0.0), + m_Q(0.0), + m_emis(0.0), + m_h(0.0), + m_area(1.0), + m_ext_temp(0.0), + m_ext_temp4(0.0), + m_kv(0.0), + m_p0(OneAtm), + m_rtol(1.e-9), + m_trad_set(false), + m_chem(true), + m_energy(true) + { + m_integ = new CVodeInt; + + // use backward differencing, with a full Jacobian computed + // numerically, and use a Newton linear iterator + m_integ->setMethod(BDF_Method); + m_integ->setProblemType(DENSE + NOJAC); + m_integ->setIterator(Newton_Iter); + } + + + // overloaded method of FuncEval. Called by the integrator to + // get the initial conditions. + void Reactor::getInitialConditions(double t0, size_t leny, double* y) + { + m_init = true; + if (m_mix == 0) { + cout << "Error: reactor is empty." << endl; + return; + } + m_time = t0; + + // total mass + doublereal mass = m_mix->density() * m_vol; + + // set components y + 2 ... y + K + 1 to the + // mass M_k of each species + m_mix->getMassFractions(leny-2, y+2); + scale(y + 2, y + m_nsp + 2, y + 2, mass); + + // set the first component to the total internal + // energy + y[0] = m_thermo->intEnergy_mass() * mass; + + // set the second component to the total volume + y[1] = m_vol; + } + + + /** + * Must be called before calling method 'advance' + */ + void Reactor::initialize(doublereal t0) { + m_mix->restoreState(m_state); + m_sdot.resize(m_nsp, 0.0); + m_atol.resize(m_nsp + 2); + fill(m_atol.begin(), m_atol.end(), 1.e-15); + m_integ->setTolerances(m_rtol, neq(), m_atol.begin()); + m_integ->setMaxStep(m_maxstep); + m_integ->initialize(t0, *this); + + m_enthalpy = m_thermo->enthalpy_mass(); + m_pressure = m_thermo->pressure(); + m_intEnergy = m_thermo->intEnergy_mass(); + + m_init = true; + } + + void Reactor::updateState(doublereal* y) { + + phase_t& mix = *m_mix; // define for readability + + // The components of y are the total internal energy, + // the total volume, and the mass of each species. + // Set the mass fractions and density of the mixture. + + doublereal u = y[0]; + m_vol = y[1]; + doublereal* mss = y + 2; + doublereal mass = accumulate(y+2, y+2+m_nsp, 0.0); + m_mix->setMassFractions(mss); + m_mix->setDensity(mass/m_vol); + + doublereal temp = temperature(); + mix.setTemperature(temp); + + if (m_energy) { + doublereal u_mass = u/mass; // specific int. energy + doublereal delta; + + do { + delta = -(m_thermo->intEnergy_mass() + - u_mass)/m_thermo->cv_mass(); + temp += delta; + mix.setTemperature(temp); + } + while (fabs(delta) > m_temp_atol); + } + mix.setTemperature(temp); + m_state[0] = temp; + + // save parameters needed by other connected reactors + m_enthalpy = m_thermo->enthalpy_mass(); + m_pressure = m_thermo->pressure(); + m_intEnergy = m_thermo->intEnergy_mass(); + } + + + + /** + * Called by the integrator to evaluate ydot given y at time 'time'. + */ + void Reactor::eval(doublereal time, doublereal* y, doublereal* ydot) + { + int i; + m_time = time; + updateState(y); // synchronize the reactor state with y + + m_vdot = 0.0; + m_Q = 0.0; + + // compute wall terms + doublereal vdot; + for (i = 0; i < m_nwalls; i++) { + vdot = m_lr[i]*m_wall[i]->vdot(time); + m_vdot += vdot; + m_Q += m_lr[i]*m_wall[i]->Q(time); + } + + // volume equation + ydot[1] = m_vdot; + + /* species equations + * Equation is: + * \dot M_k = \hat W_k \dot\omega_k + \dot m_{in} Y_{k,in} + * - \dot m_{out} Y_{k} + A \dot s_k. + */ + const doublereal* mw = m_mix->molecularWeights().begin(); + + int n; + + m_kin->getNetProductionRates(ydot+2); // "omega dot" + for (n = 0; n < m_nsp; n++) { + ydot[n+2] *= m_vol; // moles/s/m^3 -> moles/s + // ydot[n+2] += m_sdot[n]; + ydot[n+2] *= mw[n]; + } + + + /** + * Energy equation. + * \dot U = -P\dot V + A \dot q + \dot m_{in} h_{in} + * - \dot m_{out} h. + */ + if (m_energy) { + ydot[0] = - m_thermo->pressure() * m_vdot - m_Q; + } + else { + ydot[0] = 0.0; + } + + // add terms for open system + if (m_open) { + + const doublereal* mf = m_mix->massFractions(); + doublereal enthalpy = m_thermo->enthalpy_mass(); + + // outlets + + int n; + doublereal mdot_out; + for (i = 0; i < m_nOutlets; i++) { + mdot_out = m_outlet[i]->massFlowRate(); + for (n = 0; n < m_nsp; n++) { + ydot[2+n] -= mdot_out * mf[n]; + } + ydot[0] -= mdot_out * enthalpy; + } + + + // inlets + + doublereal mdot_in; + for (i = 0; i < m_nInlets; i++) { + mdot_in = m_inlet[i]->massFlowRate(); + for (n = 0; n < m_nsp; n++) { + ydot[2+n] += m_inlet[i]->massFlowRate(n); + } + ydot[0] += mdot_in * m_inlet[i]->enthalpy_mass(); + } + } + } +} diff --git a/Cantera/src/zeroD/Reactor.h b/Cantera/src/zeroD/Reactor.h new file mode 100644 index 000000000..9d5edd79b --- /dev/null +++ b/Cantera/src/zeroD/Reactor.h @@ -0,0 +1,297 @@ +/** + * @file Reactor.h + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + +#ifndef CT_REACTOR_H +#define CT_REACTOR_H + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "ReactorBase.h" +#include "../FuncEval.h" +#include "../CVode.h" +#include "../Kinetics.h" + +namespace Cantera { + + /** + * Class Reactor is a general-purpose class for stirred + * reactors. The reactor may have an arbitrary number of inlets + * and outlets, each of which may be connected to a "flow device" + * such as a mass flow controller, a pressure regulator, + * etc. Additional reactors may be connected to the other end of + * the flow device, allowing construction of arbitrary reactor + * networks. + * + * The reactor class integrates the same governing equations no + * mattter what type of reactor is simulated. The differences + * among reactor types are completely specified by the attached + * flow devices and the time-dependent user-specified boundary + * conditions. + * + * If an instance of class Reactor is used directly, it will + * simulate an adiabatic, constant volume reactor with gas-phase + * chemistry but no surface chemistry. Other reactor types may be + * simulated by deriving a class from Reactor and overloading + * method getParams. This method allows specifying the following + * in terms of the instantaneous reactor state: + * + * - rate of change of the total volume (m^3/s) + * - surface heat loss rate (W) + * - species surface production rates (kmol/s) + * + * class Reactor inherits from both ReactorBase and + * FuncEval. ReactorBase provides the basic reactor-like methods + * that FlowDevice instances can access to determine their mass + * flow rate. Class FuncEval is the class used to define a system + * of ODE's to be integrated. + */ + + class Reactor : public ReactorBase, public FuncEval { + + public: + + /** + * Default constructor. + */ + Reactor(); + + + /** + * Destructor. Deletes the integrator. + */ + virtual ~Reactor(){ delete m_integ; } + + virtual int type() const { return ReactorType; } + + /** + * Advance the state of the reactor in time. On the first + * call, internal method 'initialize' is called, and the maximum + * integrator step size is set. By default, this is set to + * 'time'. To specify a different maximum step size, precede the + * call to advance with a call to setMaxStep. Note that this + * cannot be reset after advance has been called. + * + * @param time Final time (s). + */ + virtual void advance(doublereal time) { + if (!m_init) { + setMaxStep(time); + initialize(); + } + m_integ->integrate(time); + m_time = time; + updateState(m_integ->solution()); + m_mix->saveState(m_state); + } + + virtual double step(doublereal time) { + if (!m_init) { + setMaxStep(time); + initialize(); + } + m_time = m_integ->step(time); + updateState(m_integ->solution()); + m_mix->saveState(m_state); + return m_time; + } + + /** + * Insert something into the reactor. The 'something' must + * belong to a class that is a subclass of both ThermoPhase + * and Kinetics. + */ + template + void insert(G& contents) { + setThermoMgr(contents); + setKineticsMgr(contents); + } + + void setKineticsMgr(Kinetics& kin) { + m_kin = &kin; + } + + /** + * Set the maximum step size for integration. + */ + void setMaxStep(doublereal maxstep) { + m_maxstep = maxstep; + } + + /** + * Set the reactor surface area [m$^2$]. Can be changed at any time. + */ + void setArea(doublereal area) { + m_area = area; + } + + /** + * Set the external temperature \f$ T_0 \f$ + * used for heat loss calculations. + * The heat loss rate is calculated from + * \f[ + * \dot Q_{out} = h A (T - T_0) + \epsilon A (T^4 - T_{0,R}^4). + * \f] + * @see setArea, setEmissivity, setExtRadTemp + */ + void setExtTemp(doublereal ts) { + m_ext_temp = ts; + if (!m_trad_set) m_ext_temp4 = ts*ts*ts*ts; + } + + /** + * Set the external temperature for radiation. By default, this + * is the same as the temperature set by setExtTemp. But if + * setExtRadTemp is called, then subsequent of calls to + * setExtTemp do not modify the value set here. + */ + void setExtRadTemp(doublereal tr) { + m_ext_temp4 = tr*tr*tr*tr; + } + + void setHeatTransferCoeff(doublereal h) { + m_h = h; + } + + void setVDotCoeff(doublereal k) { + m_kv = k; + } + + void setEmissivity(doublereal emis) { + m_emis = emis; + } + + void setExtPressure(doublereal p0) { + m_p0 = p0; + } + + void disableChemistry() { m_chem = false; } + void enableChemistry() { m_chem = true; } + + /// Set the energy equation on or off. + void setEnergy(int eflag = 1) { + if (eflag > 0) m_energy = true; + else m_energy = false; + } + + //----------------------------------------------------- + + /** @name References to internal objects */ + //@{ + + /// Return a reference to the integrator. + Integrator& integrator() { return *m_integ; } + + //@} + + + //----------------------------------------------------- + + // overloaded methods of class FuncEval + virtual int neq() { return m_nsp + 2; } + virtual void eval(doublereal t, doublereal* y, doublereal* ydot); + virtual void getInitialConditions(doublereal t0, size_t leny, + doublereal* y); + virtual void initialize(doublereal t0 = 0.0); + + + + //----------------------------------------------------- + + /** + * @name Methods to specify simulation options. + * These virtual methods may be overloaded in + * derived classes to implement models for heat gain/loss, + * surface chemistry, and compression/expansion. + */ + //@{ + + /** + * Initialize the boundary conditions, if necessary. This + * method does nothing, but may be overloaded in derived classes if + * initialization is needed. + */ + // virtual void initBC() {} + + /** + * Evaluate the reactor boundary conditions. This procedure is + * called during integration to evaluate the rate of volume + * change \f$ dV/dt \f$ [m^3/s], the heat loss rate [W], and + * the species production rates due to surface chemistry. + * + * It may be overloaded in derived classes to implement other + * boundary conditions. If not overloaded, this routine + * implements the following boundary conditions. + * + * The rate of volume change is + * \f[ + * dV/dt = K ( P - P_{ext}) + * \f] + * where K is set in procedure setVDotCoeff. + * + * + * The heat loss rate is calculated from + * \f[ + * \dot Q_{out} = h A (T - T_0) + \epsilon A (T^4 - T_{0,R}^4). + * \f] + * @see setArea, setEmissivity, setExtRadTemp + */ + +// virtual void evalBC(doublereal& vdot, +// doublereal& heatLossRate, doublereal* sdot) { +// doublereal t = m_mix->temperature(); + +// //m_p0 = m_env->pressure(); +// vdot = m_kv * (m_thermo->pressure()/m_p0 - 1.0)*m_vol0; +// heatLossRate = m_area * ( +// m_h * (t - m_ext_temp) +// + m_emis * StefanBoltz * (t*t*t*t - m_ext_temp4) +// ); +// } + + //@} + + //----------------------------------------------------- + + /** + * Set the mixture to a state consistent with solution + * vector y. + */ + + protected: + + virtual void updateState(doublereal* y); + + Kinetics* m_kin; + // ReactorBase* m_env; + // Thermo* m_thermo; + + Integrator* m_integ; // pointer to integrator + doublereal m_temp_atol; // tolerance on T + doublereal m_maxstep; // max step size + doublereal m_vdot, m_Q; + doublereal m_emis, m_h, m_area; + doublereal m_ext_temp, m_ext_temp4; + doublereal m_kv, m_p0; + vector_fp m_atol; + doublereal m_rtol; + vector_fp m_sdot; // surface production rates + bool m_trad_set; + bool m_chem; + bool m_energy; + + private: + }; +} + +#endif + diff --git a/Cantera/src/zeroD/ReactorBase.cpp b/Cantera/src/zeroD/ReactorBase.cpp new file mode 100644 index 000000000..1115c9737 --- /dev/null +++ b/Cantera/src/zeroD/ReactorBase.cpp @@ -0,0 +1,98 @@ +/** + * @file ReactorBase.cpp + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "ReactorBase.h" +#include "FlowDevice.h" +#include "Wall.h" + +namespace Cantera { + + ReactorBase::ReactorBase() : m_nsp(0), + m_mix(0), + m_time(0.0), + m_vol(1.0), + m_vol0(1.0), + m_init(false), + m_nInlets(0), + m_nOutlets(0), + m_open(false), + m_enthalpy(0.0), + m_intEnergy(0.0), + m_pressure(0.0), + m_nwalls(0) + {} + +// void ReactorBase::setMixture(phase_t& mix, thermo_t& thermo){ +// m_mix = &mix; +// m_thermo = &thermo; +// m_nsp = m_mix->nSpecies(); +// m_mix->saveState(m_state); +// m_enthalpy = m_thermo->enthalpy_mass(); +// m_intEnergy = m_thermo->intEnergy_mass(); +// m_pressure = m_thermo->pressure(); +// } + +// void ReactorBase::setPhase(phase_t& ph){ +// m_mix = &ph; +// m_nsp = m_mix->nSpecies(); +// m_mix->saveState(m_state); +// } + + void ReactorBase::setThermoMgr(thermo_t& thermo){ + m_mix = &thermo; + m_thermo = &thermo; + m_nsp = m_mix->nSpecies(); + m_mix->saveState(m_state); + m_enthalpy = m_thermo->enthalpy_mass(); + m_intEnergy = m_thermo->intEnergy_mass(); + m_pressure = m_thermo->pressure(); + } + + void ReactorBase::addInlet(FlowDevice& inlet) { + m_inlet.push_back(&inlet); + m_open = true; + m_nInlets++; + } + + void ReactorBase::addOutlet(FlowDevice& outlet) { + m_outlet.push_back(&outlet); + m_open = true; + m_nOutlets++; + } + + void ReactorBase::addWall(Wall& w, int lr) { + m_wall.push_back(&w); + if (lr > 0) m_lr.push_back(1); + else m_lr.push_back(-1); + m_nwalls++; + } + + Wall& ReactorBase::wall(int n) { + return *m_wall[n]; + } + + doublereal ReactorBase::residenceTime() { + int nout = m_outlet.size(); + doublereal mout = 0.0; + for (int i = 0; i < nout; i++) + mout += m_outlet[i]->massFlowRate(); + return volume()/mout; + } + + FlowDevice& ReactorBase::inlet(int n) { return *m_inlet[n]; } + FlowDevice& ReactorBase::outlet(int n) { return *m_outlet[n]; } + +} diff --git a/Cantera/src/zeroD/ReactorBase.h b/Cantera/src/zeroD/ReactorBase.h new file mode 100644 index 000000000..43da1e3d9 --- /dev/null +++ b/Cantera/src/zeroD/ReactorBase.h @@ -0,0 +1,182 @@ +/** + * @file ReactorBase.h + */ + +/* + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + +#ifndef CT_REACTORBASE_H +#define CT_REACTORBASE_H + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "../ThermoPhase.h" + +namespace Cantera { + +// typedef Thermo thermo_t; + + class FlowDevice; + class Wall; + + const int ReactorType = 1; + const int ReservoirType = 2; + + /** + * Base class for stirred reactors. + * Allows using any substance model, with arbitrary + * inflow, outflow, heat loss/gain, surface chemistry, and + * volume change. + */ + class ReactorBase { + + public: + + ReactorBase(); + virtual ~ReactorBase(){} + + //----------------------------------------------------- + + virtual int type() const { return 0; } + + /** @name Methods to set up a simulation. */ + //@{ + + + /** + * Set the initial reactor volume. By default, the volume is + * 1.0 m^3. + */ + void setInitialVolume(doublereal vol) { + m_vol = vol; + m_vol0 = vol; + } + + /** + * Set initial time. Default = 0.0 s. Restarts integration + * from this time using the current mixture state as the + * initial condition. + */ + void setInitialTime(doublereal time) { + m_time = time; + m_init = false; + } + + /** + * Specify the mixture contained in the reactor. Note that + * a pointer to this substance is stored, and as the integration + * proceeds, the state of the substance is modified. + */ + //void setMixture(phase_t& mix, thermo_t& thermo); + //void setPhase(phase_t& phase); + void setThermoMgr(thermo_t& thermo); + + void addInlet(FlowDevice& inlet); + void addOutlet(FlowDevice& outlet); + FlowDevice& inlet(int n = 0); + FlowDevice& outlet(int n = 0); + + void addWall(Wall& w, int lr); + Wall& wall(int n); + + /** + * Initialize the reactor. Must be called after specifying the + * (and if necessary the inlet mixture) and before + * calling advance. + */ + virtual void initialize(doublereal t0 = 0.0) { tilt(); } + + /** + * Advance the state of the reactor in time. + * @param time Time to advance to (s). + * Note that this method + * changes the state of the mixture object. + */ + virtual void advance(doublereal time) { tilt(); } + virtual double step(doublereal time) { tilt(); return 0.0; } + virtual void start() {} + + //@} + + /// return a reference to the mixture. + thermo_t& contents() { + return *m_mix; + } + + const thermo_t& contents() const { + return *m_mix; + } + + doublereal residenceTime(); + + + //------------------------------------------------------ + + + /** @name Solution components. */ + //@{ + + /// the current time (s). + doublereal time() const { return m_time; } + + // property values after the last call to advance. + doublereal volume() const { return m_vol; } + doublereal density() const { return m_state[1]; } + doublereal temperature() const { return m_state[0]; } + doublereal enthalpy_mass() const { return m_enthalpy; } + doublereal intEnergy_mass() const { return m_intEnergy; } + doublereal pressure() const { return m_pressure; } + doublereal mass() const { return m_vol * density(); } + const doublereal* massFractions() const { return m_state.begin() + 2; } + doublereal massFraction(int k) const { return m_state[k+2]; } + //@} + + //----------------------------------------------------- + + + int error(string msg) const { + cout << "Error: " << msg << endl; + return 1; + } + + //----------------------------------------------------- + + + protected: + + int m_nsp; + thermo_t* m_mix; + thermo_t* m_thermo; +// kinetics_t* m_kin; + doublereal m_time; + doublereal m_vol, m_vol0; + bool m_init; + int m_nInlets, m_nOutlets; + bool m_open; + doublereal m_enthalpy; + doublereal m_intEnergy; + doublereal m_pressure; + vector_fp m_state; + vector m_inlet, m_outlet; + vector m_wall; + vector_int m_lr; + int m_nwalls; + + + private: + + void tilt() const { throw error("ReactorBase method called!"); } + + }; +} + +#endif + diff --git a/Cantera/src/zeroD/Reservoir.h b/Cantera/src/zeroD/Reservoir.h new file mode 100644 index 000000000..3d43ec53e --- /dev/null +++ b/Cantera/src/zeroD/Reservoir.h @@ -0,0 +1,47 @@ +/** + * @file Reqservoir.h + */ + +/* + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + +#ifndef CT_RESERVOIR_H +#define CT_RESERVOIR_H + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include +#include "ReactorBase.h" + +namespace Cantera { + + class Reservoir : public ReactorBase { + + public: + + Reservoir() {} + virtual ~Reservoir() {} + virtual int type() const { return ReservoirType; } + virtual void initialize(doublereal t0 = 0.0) {} + virtual void advance(doublereal time) {m_time = time;} + + void insert(ThermoPhase& contents) { + setThermoMgr(contents); + } + + private: + + }; + +} + +#endif + diff --git a/Cantera/src/zeroD/Wall.cpp b/Cantera/src/zeroD/Wall.cpp new file mode 100644 index 000000000..4abb635e8 --- /dev/null +++ b/Cantera/src/zeroD/Wall.cpp @@ -0,0 +1,36 @@ + +#include "Wall.h" +#include "ReactorBase.h" +#include "Func1.h" + +namespace Cantera { + + + Wall::Wall() : m_left(0), m_right(0), m_area(0.0), m_k(0.0), m_rrth(0.0), + m_vf(0), m_qf(0) {} + + bool Wall::install(ReactorBase& rleft, ReactorBase& rright) { + // check if wall is already installed + if (m_left || m_right) return false; + m_left = &rleft; + m_right = &rright; + m_left->addWall(*this, 1); + m_right->addWall(*this, -1); + return true; + } + + doublereal Wall::vdot(doublereal t) { + double rate1 = m_k * m_area * + (m_left->pressure() - m_right->pressure()); + if (m_vf) rate1 += m_vf->eval(t); + return rate1; + } + + doublereal Wall::Q(doublereal t) { + double q1 = (m_area * m_rrth) * + (m_left->temperature() - m_right->temperature()); + if (m_qf) q1 += m_area * m_qf->eval(t); + return q1; + } + +} diff --git a/Cantera/src/zeroD/Wall.h b/Cantera/src/zeroD/Wall.h new file mode 100644 index 000000000..db0bf22af --- /dev/null +++ b/Cantera/src/zeroD/Wall.h @@ -0,0 +1,147 @@ +/** + * @file FlowDevice.h + * + * $Author$ + * $Date$ + * $Revision$ + */ + +// Copyright 2001 California Institute of Technology + +#ifndef CT_WALL_H +#define CT_WALL_H + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "../ct_defs.h" +#include "../Func1.h" + +namespace Cantera { + + class ReactorBase; // forward reference + class Func1; + + const int Rigid_Type = 1; + const int Flexible_Type = 2; + + class Wall { + + public: + + /// Constructor + Wall(); + + /// Destructor + virtual ~Wall() {} + + /** + * Rate of volume change (kg/s). Positive value increases volume + * Of reactor on left, and decreases volume on right. + */ + virtual doublereal vdot(doublereal t); + virtual doublereal Q(doublereal t); + + /// Area in m^2. + doublereal area() { return m_area; } + + /// Set the area [m^2]. + void setArea(doublereal a) { m_area = a; } + + void setThermalResistance(doublereal Rth) { m_rrth = 1.0/Rth; } + + /// Set the overall heat transfer coefficient [W/m^2/K]. + void setHeatTransferCoeff(doublereal U) { m_rrth = U; } + + void setExpansionRate(Func1* f=0) {if (f) m_vf = f;} + + void setExpansionRateCoeff(doublereal k) {m_k = k;} + + /** + * Specify the heat flux q(t). + */ + void setHeatFlux(Func1* q) { m_qf = q;} + + bool install(ReactorBase& in, ReactorBase& out); + virtual bool ready() { return (m_left != 0 && m_right != 0); } + + int type() { return 0; } + + /// Return a reference to the left reactor. + ReactorBase& left() const { return *m_left; } + + /// Return a reference to the right-hand reactor. + const ReactorBase& right() { return *m_right; } + + /// set parameters + virtual void setParameters(int n, doublereal* coeffs) { + m_coeffs.resize(n); + copy(coeffs, coeffs + n, m_coeffs.begin()); + } + + protected: + + vector_fp m_coeffs; + + ReactorBase* m_left; + ReactorBase* m_right; + doublereal m_area, m_k, m_rrth; + Func1 *m_vf; + Func1 *m_qf; + + private: + + }; + + +// class Piston : public Wall { +// public: +// Piston() +// : m_omega(2.0*3.1415926*freq), Wall() { +// //m_vdisp = stroke * Pi * bore * bore / 4.0; +// //m_vclear = tdc * bore; +// //m_ra = 1.0/crankradius; +// } +// ~Piston() {} +// virtual doublereal vdot(double t) { +// doublereal theta = m_omega * t; +// doublereal sinth = sin(theta); +// return 0.0; +// //return m_vclear + 0.5*m_vdist*(1.0 + m_ra - m_omega*sin(theta) +// // - sqrt(m_ra * m_ra - sinth*sinth)); +// } +// protected: +// doublereal m_tdc, m_bdc, m_stroke, m_bore, m_rodlen, +// m_radius, m_omega; +// }; + + + class Piston : public Wall { + public: + Piston(doublereal freq, + doublereal tdc, doublereal bdc, + doublereal stroke, doublereal bore, + doublereal rodlen, doublereal crankradius) + : Wall(), m_omega(2.0*3.1415926*freq) { + //m_vdisp = stroke * Pi * bore * bore / 4.0; + //m_vclear = tdc * bore; + //m_ra = 1.0/crankradius; + } + virtual ~Piston() {} + virtual doublereal vdot(double t) { + // doublereal theta = m_omega * t; + //doublereal sinth = sin(theta); + return 0.0; + //return m_vclear + 0.5*m_vdist*(1.0 + m_ra - m_omega*sin(theta) + // - sqrt(m_ra * m_ra - sinth*sinth)); + } + protected: + doublereal m_tdc, m_bdc, m_stroke, m_bore, m_rodlen, + m_radius, m_omega; + }; + +} + +#endif diff --git a/Cantera/src/zeroD/flowControllers.h b/Cantera/src/zeroD/flowControllers.h new file mode 100644 index 000000000..91ee4c1d8 --- /dev/null +++ b/Cantera/src/zeroD/flowControllers.h @@ -0,0 +1,218 @@ +/** + * @file FlowDevice.h + * + * Some flow devices derived from class FlowDevice. + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + + +#ifndef CT_FLOWCONTR_H +#define CT_FLOWCONTR_H + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include "FlowDevice.h" +#include "ReactorBase.h" +#include "PID_Controller.h" +#include "../Func1.h" + +namespace Cantera { + + + /////////////////////////////////////////////////////////////// + + + /** + * A base class for devices that do not use closed-loop control. + * This is defined only for convenience, in order to overload + * virtual methods of FlowDevice that print warnings with ones + * that do nothing. + */ + class NoController : public FlowDevice { + public: + + NoController() {} + virtual ~NoController() {} + + NoController(const NoController& a) + : FlowDevice(a) {} + + NoController& operator=(const NoController& a) { + return *this; + } + + // unneeded methods + virtual void update() {} + virtual void reset() {} + virtual bool setGains(int n, const doublereal* gains) {return true;} + virtual bool getGains(int n, doublereal* gains) {return true;} + virtual doublereal maxError() { return 0.0; } + virtual doublereal setpoint() { return 0.0; } + virtual void setSetpoint(doublereal mdot) { } + virtual bool ready() { + return FlowDevice::ready(); + } + + protected: + private: + }; + + + ////////////////////////////////////////////////////////// + + + /** + * A class for mass flow controllers. The mass flow rate is constant, + * independent of any other parameters. + */ + class MassFlowController : public NoController { + public: + + MassFlowController() {} + virtual ~MassFlowController() {} + + MassFlowController(const MassFlowController& a) + : NoController(a) {} + + MassFlowController& operator=(const MassFlowController& a) { + if (this == &a) return *this; + m_mdot = a.m_mdot; + return *this; + } + + virtual doublereal setpoint() { return m_mdot; } + virtual void setSetpoint(doublereal mdot) { m_mdot = mdot; } + virtual bool ready() { + return FlowDevice::ready() && m_mdot >= 0.0; + } + + protected: + private: + }; + + + class UserValve : public NoController { + public: + + UserValve() : m_func(0) {} + virtual ~UserValve() {} + + UserValve(const UserValve& a) : NoController(a) {} + + UserValve& operator=(const UserValve& a) { + if (this == &a) return *this; + m_func = a.m_func; + return *this; + } + + virtual bool ready() { + return FlowDevice::ready() && m_func != 0; + } + + virtual void setFunction(Func1* f) { m_func = f; } + + virtual doublereal massFlowRate() { + return m_func->eval(in().pressure() - out().pressure()); + } + + protected: + Func1* m_func; + + private: + }; + + + /** + * A class for mass flow controllers. The mass flow rate is constant, + * independent of any other parameters. + */ + class Valve : public NoController { + public: + + Valve() {} + virtual ~Valve() {} + + Valve(const Valve& a) : NoController(a) {} + + Valve& operator=(const Valve& a) { + if (this == &a) return *this; + m_mdot = a.m_mdot; + return *this; + } + + virtual bool ready() { + return FlowDevice::ready() && m_coeffs.size() >= 1; + } + + virtual doublereal massFlowRate() { + m_mdot = m_coeffs[0]* (in().pressure() - out().pressure()); + return (m_mdot > 0.0 ? m_mdot : 0.0); + } + + protected: + + private: + }; + + + + /** + * A PressureRegulator is a device that controls the pressure + * of the upstream reactor by regulating the mass flow rate. + */ + class PressureRegulator : public FlowDevice { + + public: + + PressureRegulator() {} + virtual ~PressureRegulator() {} + PressureRegulator(const PressureRegulator& p) : m_pid(p.m_pid) {} + PressureRegulator& operator=(const PressureRegulator& p) { + if (this == &p) return *this; + m_pid = p.m_pid; + return *this; + } + + // overloaded virtual methods + virtual void setSetpoint(doublereal p0) { m_pid.setpoint(-p0); } + virtual doublereal setpoint() { return -m_pid.setpoint(); } + virtual bool ready() { + return FlowDevice::ready() && m_pid.ready(); } + virtual void reset() { + m_pid.reset(in().time()-1.e-12, -in().pressure()); + } + virtual void update() { + m_pid.update(in().time(), -in().pressure()); + } + + virtual bool setGains(int n, const doublereal* gains) { + return m_pid.setGains(n, gains); + } + + virtual bool getGains(int n, doublereal* gains) { + return m_pid.getGains(n, gains); + } + + virtual doublereal maxError() { return m_pid.maxError(); } + + virtual doublereal massFlowRate() { + m_mdot = m_pid.output(-in().pressure()); + return m_mdot; + } + + protected: + + private: + PID_Controller m_pid; + }; +} +#endif + diff --git a/INSTALLING b/INSTALLING new file mode 100644 index 000000000..096647371 --- /dev/null +++ b/INSTALLING @@ -0,0 +1,51 @@ + +Cantera should build 'out of the box' on linux, cygwin, and Mac OS +10.2. It should build on most other variants of unix with some +tweaking. The build process runs a few Python scripts, so you need to +have Python present whether or not you plan to install the Cantera +python interface. Linux and Mac OS 10.2 have python pre-installed. + + +Build Instructions +================== + +To build and install Cantera in /usr/local: + +./configure +make +make install + + +To build and install Cantera in a different directory: + +./configure --prefix=/installation/dir +make +make install + +To do 'make install', you may need to be super-user. On a Mac running +OS X, type 'sudo make install' + + + +Customizing +----------- + +Before running configure, the following environment variables may be set: + +CXX C++ compiler + +F77 Fortran 77 compiler + +BUILD_PYTHON_MODULE build the Cantera Python interface ('y' or 'n') + +BUILD_MATLAB_TOOLBOX build the Matlab toolbox ('y' or 'n') + +PYTHON_CMD Python interpreter to use with Cantera (default: 'python') + You must have write access to the + 'site-packages' directory of this Python + interpreter if you are installing the Cantera + Python interface, and it must have the + 'Numeric' package installed. + +Additional customization can be done by editing the configure script. + diff --git a/License.rtf b/License.rtf new file mode 100755 index 000000000..162ecc1cb --- /dev/null +++ b/License.rtf @@ -0,0 +1,71 @@ +{\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f2\fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;} +{\f23\froman\fcharset128\fprq1{\*\panose 00000000000000000000}MS Mincho{\*\falt MS ??};}{\f28\froman\fcharset128\fprq1{\*\panose 00000000000000000000}@MS Mincho;}{\f33\froman\fcharset238\fprq2 Times New Roman CE;} +{\f34\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f36\froman\fcharset161\fprq2 Times New Roman Greek;}{\f37\froman\fcharset162\fprq2 Times New Roman Tur;}{\f38\froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\f39\froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f40\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f49\fmodern\fcharset238\fprq1 Courier New CE;}{\f50\fmodern\fcharset204\fprq1 Courier New Cyr;} +{\f52\fmodern\fcharset161\fprq1 Courier New Greek;}{\f53\fmodern\fcharset162\fprq1 Courier New Tur;}{\f54\fmodern\fcharset177\fprq1 Courier New (Hebrew);}{\f55\fmodern\fcharset178\fprq1 Courier New (Arabic);} +{\f56\fmodern\fcharset186\fprq1 Courier New Baltic;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255; +\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{ +\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 Normal;}{\*\cs10 \additive Default Paragraph Font;}{ +\s15\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f2\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext15 Plain Text;}{\s16\ql \li0\ri0\widctlpar +\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1033\langfe1033\loch\f2\hich\af2\dbch\af2\cgrid\langnp1033\langfenp1033 +\sbasedon0 \snext16 HTML Preformatted;}}{\*\listtable{\list\listtemplateid1037336554\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\leveltemplateid67698703 +\'02\'00.;}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1\fbias0 \fi-360\li360\jclisttab\tx360 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext +\leveltemplateid67698713\'02\'01.;}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-360\li1080\jclisttab\tx1080 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext +\leveltemplateid67698715\'02\'02.;}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-180\li1800\jclisttab\tx1800 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext +\leveltemplateid67698703\'02\'03.;}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-360\li2520\jclisttab\tx2520 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext +\leveltemplateid67698713\'02\'04.;}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-360\li3240\jclisttab\tx3240 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext +\leveltemplateid67698715\'02\'05.;}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-180\li3960\jclisttab\tx3960 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext +\leveltemplateid67698703\'02\'06.;}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-360\li4680\jclisttab\tx4680 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext +\leveltemplateid67698713\'02\'07.;}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-360\li5400\jclisttab\tx5400 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext +\leveltemplateid67698715\'02\'08.;}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-180\li6120\jclisttab\tx6120 }{\listname ;}\listid308100129}{\list\listtemplateid-1268982884\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0 +\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67698703\'02\'00.;}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-360\li360\jclisttab\tx360 }{\listlevel\levelnfc4\levelnfcn4\leveljc0 +\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67698713\'02\'01.;}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-360\li1080\jclisttab\tx1080 }{\listlevel\levelnfc2\levelnfcn2 +\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67698715\'02\'02.;}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-180\li1800\jclisttab\tx1800 }{\listlevel\levelnfc0 +\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67698703\'02\'03.;}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-360\li2520\jclisttab\tx2520 }{\listlevel +\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67698713\'02\'04.;}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-360\li3240\jclisttab\tx3240 } +{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67698715\'02\'05.;}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-180\li3960 +\jclisttab\tx3960 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67698703\'02\'06.;}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 +\fi-360\li4680\jclisttab\tx4680 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67698713\'02\'07.;}{\levelnumbers\'01;}\chbrdr\brdrnone\brdrcf1 +\chshdng0\chcfpat1\chcbpat1 \fi-360\li5400\jclisttab\tx5400 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67698715\'02\'08.;}{\levelnumbers\'01;}\chbrdr +\brdrnone\brdrcf1 \chshdng0\chcfpat1\chcbpat1 \fi-180\li6120\jclisttab\tx6120 }{\listname ;}\listid1692761455}}{\*\listoverridetable{\listoverride\listid308100129\listoverridecount0\ls1}{\listoverride\listid1692761455\listoverridecount0\ls2}}{\info +{\author Dave Goodwin}{\operator Dave Goodwin}{\creatim\yr2001\mo5\dy15\hr2\min36}{\revtim\yr2002\mo1\dy3\hr11\min7}{\version5}{\edmins9}{\nofpages1}{\nofwords0}{\nofchars0}{\*\company Caltech}{\nofcharsws0}{\vern8247}}\margl1319\margr1319 +\widowctrl\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\hyphcaps0\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1319\dgvorigin1440\dghshow1\dgvshow1 +\jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule \fet0\sectd \linex0\endnhere\sectlinegrid360\sectdefaultcl {\*\pnseclvl1 +\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5 +\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s15\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f2\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\dbch\af23 + +\par \hich\af2\dbch\af23\loch\f2 Copyright \hich\af2\dbch\af23\loch\f2 2001 Cali\hich\af2\dbch\af23\loch\f2 fornia Institute of Technology\hich\af2\dbch\af23\loch\f2 +\par \hich\af2\dbch\af23\loch\f2 All rights reserved +\par +\par +\par \hich\af2\dbch\af23\loch\f2 LICENSE AGREEMENT +\par \hich\af2\dbch\af23\loch\f2 ----------------- +\par +\par \hich\af2\dbch\af23\loch\f2 Use in source and binary forms, with or without modification, is \hich\af2\dbch\af23\loch\f2 permitted provided that the following conditions are met: +\par }\pard\plain \s16\ql \li0\ri0\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 +\fs20\lang1033\langfe1033\loch\af2\hich\af2\dbch\af2\cgrid\langnp1033\langfenp1033 {\dbch\af23 +\par }\pard \s16\ql \li0\ri0\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\dbch\af23 +\par {\listtext\pard\plain\s16 \fs20\loch\af2\hich\af2\dbch\af2 \hich\af2\dbch\af2\loch\f2 1.\tab}}\pard \s16\ql \fi-360\li360\ri0\widctlpar +\jclisttab\tx360\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\aspalpha\aspnum\faauto\ls2\adjustright\rin0\lin360\itap0 {\hich\af2\dbch\af2\loch\f2 +No portion of the software may be sold or incorporated into commercial soft\hich\af2\dbch\af2\loch\f2 ware packages or other products\hich\af2\dbch\af2\loch\f2 , or used for any}{\hich\af2\dbch\af2\loch\f2 other commercial purpose, }{ +\hich\af2\dbch\af2\loch\f2 without prior written consent and execution of a separate license agreement.}{\dbch\af23 +\par {\listtext\pard\plain\s16 \fs20\loch\af2\hich\af2\dbch\af2 \hich\af2\dbch\af2\loch\f2 2.\tab}}{\hich\af2\dbch\af2\loch\f2 Redistr\hich\af2\dbch\af2\loch\f2 +ibutions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. +\par {\listtext\pard\plain\s16 \fs20\loch\af2\hich\af2\dbch\af2 \hich\af2\dbch\af2\loch\f2 3.\tab}\hich\af2\dbch\af2\loch\f2 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the +\hich\af2\dbch\af2\loch\f2 documentation and/or other materials provided with the distribution.}{\dbch\af23 +\par {\listtext\pard\plain\s16 \fs20\loch\af2\hich\af2\dbch\af23 \hich\af2\dbch\af23\loch\f2 4.\tab}}\pard \s16\ql \fi-360\li360\ri0\widctlpar +\jclisttab\tx360\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\aspalpha\aspnum\faauto\ls2\adjustright\rin0\lin360\itap0 {\dbch\af23 \hich\af2\dbch\af23\loch\f2 +Software derived from or incorpoating this software may not be called "Cantera", nor may "Cantera" appear in the name, without prior written permission. +\par }\pard\plain \s15\ql \li360\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin360\itap0 \f2\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\dbch\af23 +\par }\pard \s15\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\dbch\af23 \hich\af2\dbch\af23\loch\f2 DISCLAIMER +\par \hich\af2\dbch\af23\loch\f2 ---------- +\par +\par \hich\af2\dbch\af23\loch\f2 THIS SO\hich\af2\dbch\af23\loch\f2 +FTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EITHER THE DEVELOPERS OF THE SOFTWARE OR +\hich\af2\dbch\af23\loch\f2 \hich\af2\dbch\af23\loch\f2 +THE CALIFORNIA INSTITUTE OF TECHNOLOGY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INT +\hich\af2\dbch\af23\loch\f2 E\hich\af2\dbch\af23\loch\f2 +RRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\par +\par }} \ No newline at end of file diff --git a/License.txt b/License.txt new file mode 100755 index 000000000..1cb726ca9 --- /dev/null +++ b/License.txt @@ -0,0 +1,43 @@ + + Copyright 2001 California Institute of Technology. + All rights reserved. + + + LICENSE AGREEMENT + ----------------- + + Use in source and binary forms, with or without modification, is + permitted provided that the following conditions are met: + + 1. No portion of the software may be sold or incorporated into + commercial software packages or other products, or used for any + other commercial purpose, without prior written consent and + execution of a separate license agreement. + + 2. Redistributions of source code must retain the above copyright + notice, this list of conditions, and the following disclaimer. + + 3. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 4. Software derived from or incorporting this software may not be + called "Cantera", nor may "Cantera" appear in the name, without + prior written permission. + + + DISCLAIMER + ---------- + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL EITHER THE DEVELOPERS OF THE SOFTWARE OR THE + CALIFORNIA INSTITUTE OF TECHNOLOGY BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. diff --git a/Makefile.in b/Makefile.in new file mode 100755 index 000000000..1bb77f683 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,165 @@ +# +# $RCSfile$ +# $Author$ +# $Date$ +# $Revision$ +# +######################################################################## + +export_dir = $(HOME)/export +version = 1.3 +ct = $(export_dir)/cantera-$(version) +build_ck = @BUILD_CK@ +build_clib = @BUILD_CLIB@ +build_python = @BUILD_PYTHON@ +build_matlab = @BUILD_MATLAB@ + +LIBDIR=@LIB_DIR@ + +# removed utils temporarily +all: kernel movelibs clib python matlab + +install: hdr-install kernel-install data-install python-install matlab-install finish-install + +demos: example_codes + +kernel: info + rm -f lib/*.a + cd ext; @MAKE@ + cd Cantera/src; @MAKE@ + +clib: + cd Cantera/clib/src; @MAKE@ + + +movelibs: + mv -f Cantera/src/*.a lib + mv -f Cantera/src/*/*.a lib + mv -f ext/*/*.a lib + ranlib lib/*.a + +utils: + cd tools; @MAKE@ + +kernel-install: + @INSTALL@ -d @prefix@/lib/cantera + @INSTALL@ -m 644 lib/*.a @prefix@/lib/cantera + cd Cantera/clib/src; make install + ranlib @prefix@/lib/cantera/*.a + +data-install: + @INSTALL@ -d @prefix@/cantera/data + @INSTALL@ -d @prefix@/cantera/templates + @INSTALL@ -m 644 data/inputs/*.xml @prefix@/cantera/data + @INSTALL@ -m 644 tools/src/*.mak @prefix@/cantera/templates + #@INSTALL@ -m 644 tools/templates/gaslib.cpp @prefix@/cantera/templates + +hdr-install: + @INSTALL@ -d @prefix@/include/cantera + @INSTALL@ -d @prefix@/include/kernel + @INSTALL@ -d @prefix@/include/cantera/kernel/oneD + @INSTALL@ -d @prefix@/include/cantera/kernel/zeroD + @INSTALL@ -d @prefix@/include/cantera/kernel/converters + @INSTALL@ -d @prefix@/include/cantera/kernel/transport + rm -r -f @prefix@/include/cantera/*.h + @INSTALL@ include/*.h @prefix@/include/cantera + @INSTALL@ config.h @prefix@/include/cantera + @INSTALL@ Cantera/src/*.h @prefix@/include/cantera/kernel + @INSTALL@ Cantera/src/oneD/*.h @prefix@/include/cantera/kernel/oneD + @INSTALL@ Cantera/src/zeroD/*.h @prefix@/include/cantera/kernel/zeroD + @INSTALL@ Cantera/src/converters/*.h @prefix@/include/cantera/kernel/converters + @INSTALL@ Cantera/src/transport/*.h @prefix@/include/cantera/kernel/transport + + + +python: +ifeq ($(build_python),1) + cd Cantera/python; @MAKE@ +endif + +python-install: +ifeq ($(build_python),1) + cd Cantera/python; @MAKE@ install + @INSTALL@ -d @prefix@/cantera/demos/python + @INSTALL@ Cantera/python/examples/*.py @prefix@/cantera/demos/python + @INSTALL@ -d @prefix@/cantera/tutorials/python + @INSTALL@ Cantera/python/tutorial/*.py \ + @prefix@/cantera/tutorials/python +endif + +matlab: +ifeq ($(build_matlab),1) + cd Cantera/matlab; @MAKE@ +endif + +matlab-install: +ifeq ($(build_matlab),1) + cd Cantera/matlab; @MAKE@ install + @INSTALL@ -d @prefix@/cantera/demos/matlab + @INSTALL@ Cantera/matlab/cantera/examples/*.m @prefix@/cantera/demos/matlab + @INSTALL@ -d @prefix@/cantera/tutorials/matlab + @INSTALL@ Cantera/matlab/cantera/tutorial/*.m @prefix@/cantera/tutorials/matlab +endif + +finish-install: + @INSTALL@ -d @prefix@/bin + @INSTALL@ -d @prefix@/cantera/demos/c++ + @INSTALL@ examples/cxx/*.cpp @prefix@/cantera/demos/c++ + @PYTHON_CMD@ tools/bin/finish_install.py @prefix@ @PYTHON_CMD@ +#@INSTALL@ bin/ctmkmf @prefix@/bin/ctnew +#@INSTALL@ bin/cxx_examples @prefix@/cantera/demos/c++ + + + +example_codes: + cd examples; @MAKE@ all + +test: example_codes + cd test_problems; @MAKE@ all + cd test_problems; @MAKE@ test + +uninstall: + rm -r -f @prefix@/include/cantera + rm -r -f @prefix@/cantera + rm -f @prefix@/lib/lib@CT_SHARED_LIB@.a + +clean: + $(RM) *.*~ lib/Cantera.a lib/libckreader.a lib/*.a lib/*.so bin/ck2ctml bin/ctsetup bin/cxx_examples + cd Cantera; @MAKE@ clean + cd CKReader; @MAKE@ clean + cd tools; @MAKE@ clean + cd ext; @MAKE@ clean + cd test_problems; @MAKE@ clean + cd examples; @MAKE@ clean + +docs: + cd tools/doxygen/Cantera; doxygen Cantera.cfg + +depends: + cd CKReader; @MAKE@ depends + cd Cantera; @MAKE@ depends + cd tools; @MAKE@ depends + +export: + @INSTALL@ -d $(export_dir) + if (test -d $(ct)); then rm -r -f $(ct); fi + cd $(export_dir); cvs export -D 1/01/2010 cantera-export-$(version) + cd $(ct); rm -r -f Cantera/matlab/cantera/@Thermo + +pack: export + (cd $(export_dir); \ + rm -f cantera-$(version).tar.gz; \ + tar cvf cantera-$(version).tar cantera-$(version)/*; \ + gzip cantera-$(version).tar) + +post: pack + (cd $(export_dir); \ + $(HOME)/ctpost cantera-$(version).tar.gz 1.3.5/src) + + +info: + echo '#define CANTERA_ROOT "@prefix@/cantera"' > include/ctdir.h + + + + diff --git a/README b/README new file mode 100755 index 000000000..fc7775a0f --- /dev/null +++ b/README @@ -0,0 +1,108 @@ + + C A N T E R A + + release 1.3.5 + 2/03 + + Copyright (c) 2001, 2002 California Institute of Technology + + +License information +=================== + +See the file "License.txt" for information on the terms & conditions +for usage, and a DISCLAIMER OF ALL WARRANTIES. + +All trademarks referenced herein are property of their respective +holders. + + + +Installing Cantera +================== + +To download and install Cantera, run Python script 'ctupdate.py.' +It will perform a binary install on Windows, and build everything from +the source on any other platform. + +Alternatively, to manually build Cantera, follow the procedure below. + + + + +Building Cantera from the source code +===================================== + + +1) Unix/linux/cygwin build procedure +------------------------------------ + +Run the 'configure' script to build the Makefiles. By default, 'make install' +will install under '/usr/local.' If you want to install Cantera somewhere else, +run 'configure' with the 'prefix' option: + +configure --prefix=$HOME/my_cantera_dir + +If necessary, edit 'configure' to set options appropriate for your +system. As shipped, the configure script is set up to build Cantera on +a linux system. + +After running 'configure', type: + +make +make install + +The last one may need to be run as super-user. + +By default, this procedure also builds the Python and MATLAB interfaces. +Edit 'configure' to disable building these if desired. + +To use either the Python or Matlab interfaces, the shared library file +installed in '/usr/local/lib' (or wherever you installed it) must be on the +library search path. Set LD_LIBRARY_PATH if necessary: + +export LD_LIBRARY_PATH=$HOME/my_cantera_dir/lib + + + +2) Windows Build Procedure +-------------------------- + +Cantera can be built under Windows using Visual C++ and Compaq Visual +Fortran. In the 'win32' directory, open workspace 'cantera.dsw'. Set +the active project to 'examples', and the active configuration to +'Win32 - Release'. Build the project, and execute 'examples.exe' from +the Build menu to verify that it works. + +If you plan to build the Python or MATLAB interfaces, you also need to +build project 'ct'. This creates a DLL file which by default +is placed in C:\WINDOWS\SYSTEM32. Edit the project settings if you want +to put it somewhere else. + +Finally, build project 'ctsetup'. This creates a simple utility that +writes a Visual Studio project file or a unix Makefile and a prototype +C++ main program that you can use as the starting point to develop +your own C++ application. + + + +Configuring Matlab +--------------------- + +Before you can build the Matlab toolbox from the source, Matlab needs +to be configured for your compiler. In Matlab type: + +mex -setup + +and enter the number for the compiler you wish to use. + + +Configuring Python +--------------------- + +Before you can build the Python interface from the source, you need to +have Python 2.0 or greater, you need to be able to write into its +'Lib/site-packages' directory, and the 'Numeric' package must be +installed. If any of these are not the case, run the Python script +'ctupdate.py' found in the 'tools/bin' directory to download and +install Python and Numeric. diff --git a/apps/MixMaster/.cvsignore b/apps/MixMaster/.cvsignore new file mode 100644 index 000000000..5d0bfe229 --- /dev/null +++ b/apps/MixMaster/.cvsignore @@ -0,0 +1 @@ +error.txt diff --git a/apps/MixMaster/CompositionFrame.py b/apps/MixMaster/CompositionFrame.py new file mode 100644 index 000000000..2fc698634 --- /dev/null +++ b/apps/MixMaster/CompositionFrame.py @@ -0,0 +1,246 @@ +from Tkinter import * +from Cantera import * + +from SpeciesInfo import SpeciesInfo +#from KineticsFrame import KineticsFrame + +_CUTOFF = 1.e-15 +_ATOL = 1.e-15 +_RTOL = 1.e-7 + +class CompFrame(Frame): + def __init__(self,master): + Frame.__init__(self,master) + self.config(relief=FLAT, bd=4) + self.top = self.master.top + self.controls=Frame(self) + self.hide = IntVar() + self.hide.set(0) + self.comp = IntVar() + self.comp.set(0) + self.controls.grid(column=1,row=0,sticky=W+E+N) + self.makeControls() + mf = self.master + + def makeControls(self): + Radiobutton(self.controls,text='Moles', + variable=self.comp,value=0, + command=self.show).grid(column=0,row=0,sticky=W) + Radiobutton(self.controls,text='Mass', + variable=self.comp,value=1, + command=self.show).grid(column=0,row=1,sticky=W) + Radiobutton(self.controls,text='Concentration', + variable=self.comp,value=2, + command=self.show).grid(column=0,row=2,sticky=W) + Button(self.controls,text='Clear', + command=self.zero).grid(column=0,row=4,sticky=W+E) + Button(self.controls,text='Normalize', + command=self.norm).grid(column=0,row=5,sticky=W+E) + Checkbutton(self.controls,text='Hide Missing\nSpecies', + variable=self.hide,onvalue=1, + offvalue=0,command=self.master.redo).grid(column=0, + row=3, + sticky=W) + + def norm(self): + mf = self.master + mf.update() + + data = mf.comp + sum = 0.0 + for sp in data: + sum += sp + for i in range(len(mf.comp)): + mf.comp[i] /= sum + self.show() + + def set(self): + c = self.comp.get() + mix = self.top.mix + mf = self.master + g = mix.g + if c == 0: + mix.setMoles(mf.comp) + + elif c == 1: + mix.setMass(mf.comp) + + elif c == 2: + pass + self.top.thermo.setState() + self.top.kinetics.show() + + def show(self): + mf = self.master + mf.active = self + c = self.comp.get() + mix = self.top.mix + g = mix.g + if c == 0: + mf.var.set("Moles") + #mf.data = spdict(mix.g, mix.moles()) + mf.comp = mix.moles() + + elif c == 1: + mf.var.set("Mass") + #mf.data = spdict(mix.g,mix.mass()) + mf.comp = mix.mass() + + elif c == 2: + mf.var.set("Concentration") + mf.comp = mix.concentrations() + #mf.data = spdict(mix,mix,mf.comp) + + for s in mf.variable.keys(): + try: + k = g.speciesIndex(s) + if mf.comp[k] > _CUTOFF: + mf.variable[s].set(mf.comp[k]) + else: + mf.variable[s].set(0.0) + except: + pass + + + + def zero(self): + mf = self.master + mf.comp *= 0.0 + self.show() + + + +class MixtureFrame(Frame): + def __init__(self,master,top): + Frame.__init__(self,master) + self.config(relief=GROOVE, bd=4) + self.top = top + self.top.mixframe = self + self.g = self.top.mix.g + #self.scroll = Scrollbar(self) + self.entries=Frame(self) + #self.scroll.config(command=self.entries.xview) + #self.scroll.grid(column=0,row=1) + self.var = StringVar() + self.var.set("Moles") + self.comp = array(self.top.mix.moles()) + self.names = self.top.mix.speciesNames() + self.nsp = len(self.names) + #self.data = self.top.mix.moleDict() + self.makeControls() + self.makeEntries() + self.entries.bind('',self.minimize) + self.ctype = 0 + self.newcomp = 0 + + def makeControls(self): + self.c = CompFrame(self) + #self.k = KineticsFrame(self) + self.active = self.c + self.c.grid(column=1,row=0,sticky=E+W+N+S) + #self.k.grid(column=2,row=0,sticky=E+W+N+S) + + def update(self): + self.newcomp = 0 + for s in self.variable.keys(): + k = self.g.speciesIndex(s) + current = self.comp[k] + val = self.variable[s].get() + dv = abs(val - current) + if dv > _RTOL*abs(current) + _ATOL: + self.comp[k] = val + self.newcomp = 1 + + def show(self): + self.active.show() +## for k in range(self.nsp): +## sp = self.names[k] +## if self.comp[k] > _CUTOFF: +## self.variable[sp].set(self.comp[k]) +## else: +## self.variable[sp].set(0.0) + + def redo(self): + self.update() + self.entries.destroy() + self.entries=Frame(self) + self.makeEntries() + + def minimize(self,Event=None): + self.c.hide.set(1) + self.redo() + self.c.grid_forget() + self.entries.bind("",self.maximize) + + def maximize(self,Event=None): + self.c.hide.set(0) + self.redo() + self.c.grid(column=1,row=0,sticky=E+W+N+S) + self.entries.bind("",self.minimize) + + def up(self, x): + self.update() + if self.newcomp: + self.c.set() + self.c.show() + self.top.update() + #thermo.showState() + #self.top.kinetics.show() + + def makeEntries(self): + self.entries.grid(row=0,column=0,sticky=W+N+S+E) + self.entries.config(relief=FLAT,bd=4) + DATAKEYS = self.top.species + self.variable = {} + + n=0 + ncol = 3 + col = 0 + row = 60 + + equil = 0 + if self.top.thermo: + equil = self.top.thermo.equil.get() + + for sp in DATAKEYS: + s = sp # self.top.species[sp] + k = s.index + if row > 25: + row = 0 + col = col + 2 + l = Label(self.entries,text='Species') + l.grid(column=col,row=row,sticky=E+W) + e1 = Entry(self.entries) + e1.grid(column=col+1,row=row,sticky=E+W) + e1['textvariable'] = self.var + e1.config(state=DISABLED) + e1.config(bg='lightyellow',relief=RIDGE) + row = row + 1 + + spname = s.name + val = self.comp[k] + if not self.c.hide.get() or val: showit = 1 + else: showit = 0 + + l=SpeciesInfo(self.entries,species=s, + text=spname,relief=FLAT,justify=RIGHT, + fg='darkblue') + entry1 = Entry(self.entries) + self.variable[spname] = DoubleVar() + self.variable[spname].set(self.comp[k]) + entry1['textvariable']=self.variable[spname] + entry1.bind('',self.up) + if showit: + l.grid(column= col ,row=row,sticky=E) + entry1.grid(column=col+1,row=row) + n=n+1 + row = row + 1 + if equil == 1: + entry1.config(state=DISABLED,bg='lightgray') +## if self.c.hide.get(): +## b=Button(self.entries,height=1,command=self.maximize) +## else: +## b=Button(self.entries,command=self.minimize) +## b.grid(column=col,columnspan=2, row=row+1) + + diff --git a/apps/MixMaster/ControlPanel.py b/apps/MixMaster/ControlPanel.py new file mode 100644 index 000000000..826bb3f68 --- /dev/null +++ b/apps/MixMaster/ControlPanel.py @@ -0,0 +1,212 @@ +from types import * +from Tkinter import * +from ScrolledText import ScrolledText +#import datawindow +#import filewindow + +def ff(): + print ' hi ' + +class ControlWindow(Frame): + fncs = [ff]*10 + + def __init__(self, title, master=None): + self.app = master + Frame.__init__(self,master) + self.grid(row=0,column=0,sticky=E+W+N+S) + self.master.title(title) + + + def addButtons(self, label, funcs): + self.buttonholder = Frame(self, relief=FLAT, bd=2) + self.buttonholder.pack(side=TOP,anchor=W) + b = Label(self.buttonholder,text=label) + b.pack(side=LEFT,fill=X) + for f in funcs: + b=Button(self.buttonholder, + text=f[0],command=f[1], padx=1,pady=1) + b.pack(side=LEFT,fill=X) + + def disableButtons(self, *buttons): + for button in self.buttonholder.slaves(): + if (button.cget('text') in buttons): + try: + button.config(state=DISABLED) + except: + pass + + def enableButtons(self, *buttons): + for button in self.buttonholder.slaves(): + if (button.cget('text') in buttons): + try: + button.config(state=NORMAL) + except: + pass + + + + def newFrame(self, label, var): + fr = Frame(self, relief = RIDGE, bd = 2) + fr.pack(side=TOP,fill=X) + c = Checkbutton(fr, variable=var) + c.pack(side = LEFT, fill = X) + b = Label(fr,text=label,foreground="NavyBlue") + b.pack(side=LEFT,fill=X) + return fr + + ##creates a new Toplevel object + ##options: transient=, + ## placement=(, ) + def newWindow(self, master, title, **options): + new = Toplevel(master) + new.title(title) + #new.config(takefocus=0) + if 'transient' in options.keys(): + new.transient(master) + if options['transient']: + new.protocol('WM_DELETE_WINDOW', options['transient']) + if 'placement' in options.keys(): + new.geometry("+%d+%d" % tuple(options['placement'])) + return new + + ##routes mouse and keyboard events to the window and + ##waits for it to close before returning + def makemodal(self, window): + window.focus_set() + window.grab_set() + window.wait_window() + return + + + def PlotMenu(self, fr, label, funcs): + filebutton = Menubutton(fr,text=label, padx=3,pady=1) + filebutton.pack(side=LEFT) + filemenu = Menu(filebutton,tearoff=TRUE) + i = 0 + for f in funcs: + filemenu.add_command(label=f[0], command=f[1]) + i = i + 1 + filebutton['menu']=filemenu + return filemenu + +def testevent(event): + print 'event ',event.value + +def make_menu(name, menubar, list): + button=Menubutton(menubar, text=name, padx=3,pady=1) + button.pack(side=LEFT, anchor=W) + menu = Menu(button,tearoff=FALSE) + m = menu + i = 0 + for entry in list: + i += 1 + if entry == 'separator': + menu.add_separator({}) + elif type(entry)==ListType: + for num in entry: + menu.entryconfig(num,state=DISABLED) + elif type(entry[1]) != ListType: + if i == 20: + i = 0 + submenu = Menu(button,tearoff=FALSE) + m.add_cascade(label='More...', + menu=submenu) + m = submenu + if len(entry) == 2 or entry[2] == 'command': + m.add_command(label=entry[0], + command=entry[1]) + elif entry[2] == 'check': + entry[3].set(0) + if len(entry) >= 5: val = entry[4] + else: val = 1 + m.add_checkbutton(label=entry[0], + command=entry[1], + variable = entry[3], + onvalue=val) + else: + submenu=make_menu(entry[0], menu, entry[1]) + m.add_cascade(label=entry[0], + menu=submenu) + button['menu']=menu + return button + +def menuitem_state(button, *statelist): + for menu in button.children.keys(): + if isinstance(button.children[menu], Menu): + for (commandnum, onoff) in statelist: + if onoff==0: + button.children[menu].entryconfig(commandnum,state=DISABLED) + if onoff==1: + button.children[menu].entryconfig(commandnum,state=NORMAL) + else: + pass + +class ArgumentWindow(Toplevel): + import tkMessageBox + def __init__(self, sim, **options): + Toplevel.__init__(self, sim.cwin) + self.resizable(FALSE,FALSE) + self.protocol("WM_DELETE_WINDOW", lambda:0) #self.cancelled) + self.transient(sim.cwin) + if 'placement' in options.keys(): + self.geometry("+%d+%d" % tuple(options['placement'])) + self.title('Thermal Model Initialization') + self.sim = sim + + self.make_options() + + buttonframe = Frame(self) + buttonframe.pack(side=BOTTOM) + b1=Button(buttonframe, text='OK', command=self.callback) + b1.pack(side=LEFT) + #b2=Button(buttonframe, text='Cancel', command=self.cancelled) + #b2.pack(side=LEFT) + self.bind("", self.callback) + #self.bind("", self.cancelled) + + self.initial_focus = self + self.initial_focus.focus_set() + #self.wait_window(self) + + def make_options(self): + pass + + ### must override this function ### + ### with the entry forms ### + ### be sure to use pack or a ### + ### frame that is packed into self ### + + def getArguments(self): + pass + + ### must override this function ### + ### with the validation checking ### + ### must return None if error, ### + ### and non_null if ok ### + + + def callback(self, event=None): + g=self.getArguments() + if not g: + self.initial_focus.focus_set() + return + self.withdraw() + self.update_idletasks() + + self.assign(g) + self.cancelled() + + def assign(self, obj): + pass + + ### must override this function ### + ### to do the assignment in sim ### + + def cancelled(self,event=None): + self.sim.cwin.focus_set() + self.destroy() + + +if __name__=='__main__': + t = Tk() + ControlWindow(t).mainloop() diff --git a/apps/MixMaster/DataFrame.py b/apps/MixMaster/DataFrame.py new file mode 100644 index 000000000..9a3254ad6 --- /dev/null +++ b/apps/MixMaster/DataFrame.py @@ -0,0 +1,363 @@ +import os, math, string +from Tkinter import * +from Cantera import * +from Numeric import * +import Numeric +from tkFileDialog import askopenfilename +from GraphFrame import Graph +from DataGraph import DataGraph, plotLimits +from ControlPanel import make_menu + + +U_LOC = 1 +V_LOC = 2 +T_LOC = 3 +P_LOC = 4 +Y_LOC = 5 + +def testit(e = None): + pass + +class DataFrame(Frame): + + def __init__(self,master,top): +# if master==None: + self.master = Toplevel() + self.master.protocol("WM_DELETE_WINDOW",self.hide) + #else: + # self.master = master + + #self.vis = vis + Frame.__init__(self,self.master) + self.config(relief=GROOVE, bd=4) + self.top = top + self.mix = self.top.mix + self.g = self.top.mix.g + self.data = None + self.zdata = None + self.ydata = None + self.plt = None + #self.pltwhat = None + self.datasets = [] + self.vars = [] + self.whichsoln = IntVar() + self.loc = IntVar() +# self.loc.set(1) + self.lastloc = T_LOC # self.loc.get() + self.datafile = StringVar() + self.solnid = StringVar() + self.gr = Frame(self) + self.n = IntVar() + + self.scframe = Frame(self) + self.sc = Scale(self.scframe, variable = self.n, + orient='horizontal',digits=0, + length=300,resolution=1,command=self.updateplot) + self.sc.config(cnf={'from':0,'to':1}) + Label(self.scframe,text='Grid Point').grid(column=0,row=0) + self.sc.grid(row=0,column=1) + self.sc.bind('',self.updateState) + self.gr.grid(row=4,column=0,columnspan=10) + + self.grid(column=0,row=10) + self.makeMenu() + self.hide() + + + def makeMenu(self): + self.menubar = Frame(self, relief=GROOVE,bd=2) + self.menubar.grid(row=0,column=0,sticky=N+W+E,columnspan=10) + f = [('Open...',self.browseForDatafile)] + #make_menu('File',self.menubar,items) + make_menu('File',self.menubar,f) + make_menu('Dataset',self.menubar,self.datasets) + make_menu('Plot',self.menubar,self.vars) + + + def browseForDatafile(self, e=None): + pathname = askopenfilename( + filetypes=[("Data Files", ("*.xml","*.csv","*.dat")), + ("All Files", "*.*")]) + if pathname: + self.datafile.set(pathname) + self.show() + self.getSoln() + + def getSoln(self): + fname = os.path.basename(self.datafile.get()) + ff = os.path.splitext(fname) + self.datasets = [] + if len(ff) == 2 and (ff[1] == '.xml' or ff[1] == '.ctml'): + + x = XML.XML_Node('root',src=self.datafile.get()) + c = x.child('ctml') + self.solns = c.children('simulation') + if len(self.solns) > 1: + i = 0 + for soln in self.solns: + self.datasets.append((soln['id'],self.pickSoln, + 'check',self.whichsoln,i)) + i += 1 + self.solnid.set(self.solns[-1]['id']) + self.soln = self.solns[-1] + + self.importData() + + elif len(ff) == 2 and (ff[1] == '.csv' or ff[1] == '.CSV'): + self.importCSV() + + self.makeMenu() + if self.loc.get() <= 0: + self.loc.set(self.lastloc) + + + def importCSV(self): + self.lastloc = self.loc.get() + if self.lastloc <= 0: self.lastloc = T_LOC + self.vars = [] + self.zdata = None + self.ydata = None + if self.plt: + self.plt.destroy() + + f = open(self.datafile.get(),'r') + lines = f.readlines() + vars = string.split(lines[0],',') + nlines = len(lines) + self.np = nlines - 1 + nv = len(vars) + vv = [] + for n in range(nv): + if n < nv - 1 or vars[n].strip().isalnum(): + vv.append(vars[n].strip()) + else: + break + nv = len(vv) + vars = vv + fdata = zeros((nv, self.np),'d') + for n in range(self.np): + v = string.split(lines[n+1],',') + for j in range(nv): + try: + fdata[j,n] = float(v[j]) + except: + fdata[j,n] = 0.0 + + self.nsp = self.g.nSpecies() + self.y = zeros(self.nsp,'d') + self.data = zeros((self.nsp+6,self.np),'d') + self.data[0,:] = fdata[0,:] + self.label = ['-']*(self.nsp+6) + self.label[0] = vars[0] + w = [] + for n in range(1,nv-1): + try: + k = self.g.speciesIndex(vars[n]) + except: + k = -1 + v2 = vars[n] + if v2 == 'T': + self.data[T_LOC,:] = fdata[n,:] + self.label[T_LOC] = vars[n] + w.append(('T', self.newplot, 'check', self.loc, T_LOC)) + elif v2 == 'P': + self.data[P_LOC,:] = fdata[n,:] + self.label[P_LOC] = vars[n] + w.append((vars[n], self.newplot, 'check', self.loc, P_LOC)) + elif v2 == 'u': + self.data[U_LOC,:] = fdata[n,:] + self.label[U_LOC] = vars[n] + w.append((vars[n], self.newplot, 'check', self.loc, U_LOC)) + elif v2 == 'V': + self.data[V_LOC,:] = fdata[n,:] + self.label[V_LOC] = vars[n] + w.append((vars[n], self.newplot, 'check', self.loc, V_LOC)) + elif k >= 0: + self.data[k+Y_LOC,:] = fdata[n,:] + self.label[k+Y_LOC] = vars[n] + w.append((vars[n], self.newplot, 'check', self.loc, k + Y_LOC)) + + if self.data[P_LOC,0] == 0.0: + self.data[P_LOC,:] = ones(self.np,'d')*OneAtm + print 'Warning: no pressure data. P set to 1 atm.' + + self.sc.config(cnf={'from':0,'to':self.np-1}) + if self.loc.get() <= 0: + self.loc.set(self.lastloc) + self.updateplot() + + self.vars = w + #self.makeMenu() + self.scframe.grid(row=5,column=0,columnspan=10) + + + def pickSoln(self): + self.solnid.set(self.solns[self.whichsoln.get()]['id']) + self.soln = self.solns[self.whichsoln.get()] +# self.t.destroy() + self.importData() + + + def importData(self): + + self.lastloc = self.loc.get() + if self.lastloc <= 0: self.lastloc = T_LOC + self.vars = [] + self.zdata = None + self.ydata = None + if self.plt: + self.plt.destroy() + + self.nsp = self.g.nSpecies() + self.label = ['-']*(self.nsp + 6) + + self.y = zeros(self.nsp,'d') + gdata = self.soln.child('flowfield/grid_data') + xp = self.soln.child('flowfield').children('float') + p = 0.0 + for x in xp: + if x['title'] == 'pressure': + p = float(x.value()) + fa = gdata.children('floatArray') + self.np = int(fa[0]['size']) + + self.data = zeros((self.nsp+6,self.np),'d') + w = [] + for f in fa: + t = f['title'] + try: + k = self.g.speciesIndex(t) + except: + k = -1 + v = XML.getFloatArray(f) + if t == 'z' or t == 't': + self.data[0,:] = v + self.label[0] = t + elif k >= 0: + self.data[k + Y_LOC] = v + self.label[k + Y_LOC] = t + w.append((t, self.newplot, 'check', self.loc, k + Y_LOC)) + elif t == 'T': + self.data[T_LOC,:] = v + self.label[T_LOC] = t + w.append((t, self.newplot, 'check', self.loc, T_LOC)) + elif t == 'u': + self.data[U_LOC,:] = v + self.label[U_LOC] = t + w.append((t, self.newplot, 'check', self.loc, U_LOC)) + elif t == 'V': + self.data[V_LOC,:] = v + self.label[V_LOC] = t + w.append((t, self.newplot, 'check', self.loc, V_LOC)) + + self.data[P_LOC,:] = ones(self.np,'d')*p + self.label[P_LOC] = 'P (Pa)' + self.sc.config(cnf={'from':0,'to':self.np-1}) + if self.loc.get() <= 0: + self.loc.set(self.lastloc) + self.updateplot() + + self.vars = w + self.scframe.grid(row=5,column=0,columnspan=10) + + + def hide(self): + #self.vis.set(0) + self.master.withdraw() + #if self.pltwhat: self.pltwhat.withdraw() + + def show(self, e=None): + self.master.deiconify() + + def updateState(self, e=None): + n = self.n.get() + if self.plt: self.plt.update() + + for k in range(self.nsp): + self.y[k] = self.data[k+Y_LOC,n] + + self.top.thermo.checkTPBoxes() + self.mix.setMass(self.y) + self.mix.set(temperature = self.data[T_LOC,n], + pressure = self.data[P_LOC,n]) + + self.top.update() + + def newplot(self,e=0): + loc = self.loc.get() + self.zdata = self.data[0,:] + self.ydata = self.data[loc,:] + npts = len(self.zdata) + + ylog = 0 + if loc >= Y_LOC: + for n in range(npts): + if self.ydata[n] <= 0.0: + #print n, self.ydata[n] + self.ydata[n] = 1.0e-20 + self.ydata = Numeric.log10(self.ydata) + ylog = 1 + + self.gdata = [] + zmin = self.zdata[0] + zmax = self.zdata[-1] + for n in range(npts): + self.gdata.append((self.zdata[n],self.ydata[n])) + + ymin, ymax, dtick = plotLimits(self.ydata) + if loc > 0: + self.plt = DataGraph(self.gr,self.data, 0, loc, + title='', + label=(self.label[0],self.label[loc]), + logscale=(0,ylog), + pixelX=500,pixelY=400) + self.plt.canvas.config(bg='white') + self.plt.grid(row=1,column=0,columnspan=2,sticky=W+E) + n = self.n.get() + self.gdot = self.plt.plot(n,'red') + + def updateplot(self,event=None): + if not self.data: return + + if not self.zdata: + self.newplot() + + n = self.n.get() + self.pnt = self.zdata[n], self.ydata[n] + if hasattr(self, 'gdot'): + self.plt.delete(self.gdot) + self.gdot = self.plt.plot(n,'red') + + + def plotLimits(self, xy): + ymax = -1.e10 + ymin = 1.e10 + for x, y in xy: + if y > ymax: ymax = y + if y < ymin: ymin = y + + dy = abs(ymax - ymin) + if dy < 0.2*ymin: + ymin = ymin*.9 + ymax = ymax*1.1 + dy = abs(ymax - ymin) + else: + ymin = ymin - 0.1*dy + ymax = ymax + 0.1*dy + dy = abs(ymax - ymin) + + p10 = math.floor(math.log10(0.1*dy)) + fctr = math.pow(10.0, p10) + mm = [2.0, 2.5, 2.0] + i = 0 + while dy/fctr > 5: + fctr = mm[i % 3]*fctr + i = i + 1 + ymin = fctr*math.floor(ymin/fctr) + ymax = fctr*(math.floor(ymax/fctr + 1)) + return (ymin, ymax, fctr) + + + + + diff --git a/apps/MixMaster/DataGraph.py b/apps/MixMaster/DataGraph.py new file mode 100644 index 000000000..37223263d --- /dev/null +++ b/apps/MixMaster/DataGraph.py @@ -0,0 +1,231 @@ + +from Tkinter import * +import math +from Numeric import * + +def plotLimits(ypts, f=0.0, ndiv=5, logscale=0): + """Return plot limits that""" + if logscale: + threshold = 1.0e-19 + else: + threshold = -1.0e20 + ymax = -1.e20 + ymin = 1.e20 + for y in ypts: + if y > ymax: ymax = y + if y < ymin and y > threshold: ymin = y + + dy = abs(ymax - ymin) + + if logscale: + ymin = math.floor(math.log10(ymin)) + ymax = math.floor(math.log10(ymax))+1 + fctr = 1.0 + +## if dy < 0.2*ymin: +## ymin = ymin*.9 +## ymax = ymax*1.1 +## dy = abs(ymax - ymin) +## else: + else: + ymin = ymin - f*dy + ymax = ymax + f*dy + dy = abs(ymax - ymin) + + try: + p10 = math.floor(math.log10(0.1*dy)) + fctr = math.pow(10.0, p10) + except: + return (ymin -1.0, ymax + 1.0, 1.0) + mm = [2.0, 2.5, 2.0] + i = 0 + while dy/fctr > ndiv: + fctr = mm[i % 3]*fctr + i = i + 1 + ymin = fctr*math.floor(ymin/fctr) + ymax = fctr*(math.floor(ymax/fctr+0.999)) + + return (ymin, ymax, fctr) + + +class DataGraph(Frame): + def __init__(self,master, + data, ix=0, iy=0, + title='', + label = ('x-axis','y-axis'), + logscale = (0,0), + pixelX=500, + pixelY=500): + self.logscale = logscale + self.data = data + self.ix = ix + self.iy = iy + self.minX, self.maxX, self.dx = plotLimits(data[ix,:], + logscale=self.logscale[0]) + self.minY, self.maxY, self.dy = plotLimits(data[iy,:], + logscale=self.logscale[1]) + + Frame.__init__(self,master, relief=RIDGE, bd=2) + self.title = Label(self,text=' ') + self.title.grid(row=0,column=1,sticky=W+E) + self.graph_w, self.graph_h = pixelX - 120, pixelY - 70 + self.origin = (100, 20) + self.canvas = Canvas(self, + width=pixelX, + height=pixelY, + relief=SUNKEN,bd=1) + id = self.canvas.create_rectangle(self.origin[0],self.origin[1], + pixelX-20,pixelY-50) + self.canvas.grid(row=1,column=1,rowspan=2,sticky=N+S+E+W) + self.last_points=[] + self.ticks(self.minX, self.maxX, self.dx, + self.minY, self.maxY, self.dy, 10) + self.screendata() + self.draw() + self.canvas.create_text(self.origin[0] + self.graph_w/2, + self.origin[1] + self.graph_h + 30, + text=label[0],anchor=N) + self.canvas.create_text(self.origin[0] - 50, + self.origin[1] + self.graph_h/2, + text=label[1],anchor=E) + + + def writeValue(self, y): + yval = '%15.4f' % (y) + self.title.config(text = yval) + + def delete(self, ids): + for id in ids: + self.canvas.delete(id) + + def screendata(self): + self.xdata = array(self.data[self.ix,:]) + self.ydata = array(self.data[self.iy,:]) + npts = len(self.ydata) + if self.logscale[0] > 0: + self.xdata = log10(max(1.e-20,self.xdata)) + if self.logscale[1] > 0: + self.ydata = log10(max(1.e-20,self.ydata)) + f = float(self.graph_w)/(self.maxX-self.minX) + self.xdata = (self.xdata - self.minX)*f + self.origin[0] + f = float(self.graph_h)/(self.maxY-self.minY) + self.ydata = (self.maxY - self.ydata)*f + self.origin[1] + + def toscreen(self,x,y): + if self.logscale[0] > 0: + x = log10(max(1.e-20,x)) + if self.logscale[1] > 0: + y = log10(max(1.e-20,y)) + f = float(self.graph_w)/(self.maxX-self.minX) + xx = (x - self.minX)*f + self.origin[0] + f = float(self.graph_h)/(self.maxY-self.minY) + yy = (self.maxY - y)*f + self.origin[1] + return (xx, yy) + + def move(self, id, newpos, oldpos): + dxpt = (newpos[0] - oldpos[0])/(self.maxX-self.minX)*self.graph_w + dypt = -(newpos[1] - oldpos[1])/(self.maxY-self.minY)*self.graph_h + self.canvas.move(id, dxpt, dypt) + self.writeValue(newpos[1]) + + def plot(self,n,color='black'): + xpt, ypt = self.toscreen(self.data[self.ix,n], + self.data[self.iy,n]) + #xpt = (x-self.minX)/(self.maxX-self.minX)*float(self.graph_w) + self.origin[0] + #ypt = (self.maxY-y)/(self.maxY-self.minY)*float(self.graph_h) + self.origin[1] + id_ycross = self.canvas.create_line(xpt,self.graph_h+self.origin[1],xpt,self.origin[1],fill = 'gray') + id_xcross = self.canvas.create_line(self.origin[0],ypt,self.graph_w+self.origin[0],ypt,fill = 'gray') + id = self.canvas.create_oval(xpt-2,ypt-2,xpt+2,ypt+2,fill=color) + #self.writeValue(y) + s = '(%g, %g)' % (self.data[self.ix,n],self.data[self.iy,n]) + if n > 0 and self.data[self.iy,n] > self.data[self.iy,n-1]: + idt = self.canvas.create_text(xpt+5,ypt+5,text=s,anchor=NW) + else: + idt = self.canvas.create_text(xpt+5,ypt-5,text=s,anchor=SW) + + return [id,id_xcross,id_ycross, idt] + + def draw(self,color='red'): + npts = len(self.xdata) + for n in range(1,npts): + self.canvas.create_line(self.xdata[n-1],self.ydata[n-1], + self.xdata[n],self.ydata[n],fill=color) + + def addLabel(self, y, orient=0): + if orient==0: + xpt, ypt = self.toscreen(y, 1.0) + ypt = self.origin[1] + self.graph_h + 5 + self.canvas.create_text(xpt,ypt,text=y,anchor=N) + else: + xpt, ypt = self.toscreen(self.minX, y) + xpt = self.origin[0] - 5 + self.canvas.create_text(xpt,ypt,text=y,anchor=E) + def addLegend(self,text,color=None): + m=Message(self,text=text,width=self.graph_w-10) + m.pack(side=BOTTOM) + if color: + m.config(fg=color) + + def pauseWhenFinished(self): + self.wait_window() + + def minorTicks(self, x0, x1, y, n, size, orient=0): + xtick = x0 + dx = (x1 - x0)/float(n) + if orient == 0: + while xtick <= x1: + xx, yy = self.toscreen(xtick, y) + self.canvas.create_line(xx,yy, + xx,yy-size) + xtick += dx + else: + while xtick <= x1: + xx, yy = self.toscreen(y, xtick) + self.canvas.create_line(xx,yy, + xx+size,yy) + xtick += dx + + + def ticks(self, xmin, xmax, dx, ymin, ymax, dy, size): + + if self.logscale[0]: + xmin = math.pow(10.0,xmin) + xmax = math.pow(10.0,xmax) + if self.logscale[1]: + ymin = math.pow(10.0,ymin) + ymax = math.pow(10.0,ymax) + + n = 5 + ytick = ymin + while ytick <= ymax: + xx, yy = self.toscreen(xmin, ytick) + self.canvas.create_line(xx, yy, xx + size,yy) + self.addLabel(ytick,1) + xx, yy = self.toscreen(xmax, ytick) + self.canvas.create_line(xx, yy, xx - size,yy) + ytick0 = ytick + if self.logscale[1]: + ytick *= 10.0 + n = 10 + else: ytick = ytick + dy + if ytick <= ymax: + self.minorTicks(ytick0, ytick, xmin, n, 5, 1) + self.minorTicks(ytick0, ytick, xmax, n, -5, 1) + + n = 5 + xtick = xmin + while xtick <= xmax: + xx, yy = self.toscreen(xtick, ymin) + self.canvas.create_line(xx, yy, xx, yy - size) + self.addLabel(xtick,0) + xx, yy = self.toscreen(xtick, ymax) + self.canvas.create_line(xx, yy, xx, yy + size) + if self.logscale[0]: + xtick *= 10.0 + n = 10 + else: xtick = xtick + dx + if xtick <= xmax: + self.minorTicks(xtick - dx, xtick, ymin, n, 5, 0) + self.minorTicks(xtick - dx, xtick, ymax, n, -5, 0) + + diff --git a/apps/MixMaster/Edit.py b/apps/MixMaster/Edit.py new file mode 100644 index 000000000..2e09cb217 --- /dev/null +++ b/apps/MixMaster/Edit.py @@ -0,0 +1,194 @@ +from Tkinter import * + +from ElementFrame import getElements +from utilities import handleError +from Cantera import * +from config import * +from SpeciesFrame import getSpecies + +def testit(): + pass + +class EditFrame(Frame): + + def redraw(self): + try: + self.eframe.destroy() + self.sframe.destroy() + self.rframe.destroy() + except: + pass + self.addElementFrame() + self.addSpeciesFrame() + self.addReactionFrame() + + def __init__(self, master, app): + Frame.__init__(self, master) + self.mix = app.mix + print self.mix, dir(self.mix) + self.app = app + self.master = master + self.master.title("Cantera Mechanism Editor") + self.redraw() + + def addReactionFrame(self): + self.rframe = Frame(self) + self.rframe.config(relief=GROOVE,bd=4) + self.rframe.grid(row=2,column=0,columnspan=10,sticky=E+W) + b=Button(self.rframe,text='Reactions',command=testit) + b.grid(column=5, row=0) + + def addElementFrame(self): + self.eframe = Frame(self) + self.eframe.config(relief=GROOVE,bd=4) + self.eframe.grid(row=0,column=0,columnspan=10,sticky=E+W) + self.element_labels = [] + n = 0 + for el in self.mix._mech.elementNames(): + x = Label(self.eframe,text=el,fg='darkblue') + x.grid(column = n, row=0) + self.element_labels.append(x) + n = n + 1 + b=Button(self.eframe,text='Element',command=self.chooseElements, default=ACTIVE) + b.grid(column=0, row=1, columnspan=10) + + + def addSpeciesFrame(self): + self.sframe = Frame(self) + self.sframe.config(relief=GROOVE,bd=4) + self.sframe.grid(row=1,column=0,columnspan=10,sticky=E+W) + r = 0 + c = 0 + splist = self.app.species + self.spcheck = [] + self.spec = [] + for i in range(self.app.mech.nSpecies()): + self.spec.append(IntVar()) + self.spec[i].set(1) + self.spcheck.append( Checkbutton(self.sframe, + text=splist[i].name, + variable=self.spec[i], + onvalue = 1, offvalue = 0) ) + self.spcheck[i].grid(row = r, column = c, sticky = N+W) + self.spcheck[i].bind("", self.editSpecies) + c = c + 1 + if c > 4: + c, r = 0, r + 1 + + def getspecies(self): + print getSpecies(self.mix.speciesNames(), + self.mix.speciesNames()) + + def editSpecies(self, event=None): + e = Toplevel(event.widget.master) + w = event.widget + txt = w.cget('text') + sp = self.app.mix.species[txt] + + # name, etc. + e1 = Frame(e, relief=FLAT) + self.addEntry(e1,'Name',0,0,sp.name) + self.addEntry(e1,'ID Tag',1,0,sp.id) + self.addEntry(e1,'Phase',2,0,sp.phase) + e1.grid(row=0,column=0) + + # elements + elframe = Frame(e) + elframe.grid(row=1,column=0) + Label(elframe,text='Elemental Composition').grid(row=0,column=0,columnspan=2,sticky=E+W) + + i = 0 + for el in self.app.mech.elementNames(): + self.addEntry(elframe,el,i,0,self.mech.nAtoms(sp, el)) + i = i + 1 + + # thermo + thframe = Frame(e) + thframe.grid(row=0,rowspan=2,column=1) + thframe.config(relief=GROOVE,bd=4) + i = 0 + Label(thframe,text='Thermodynamic Properties').grid(row=0, + column=0, columnspan=4, sticky=E+W) + if isinstance(sp.thermoParam(),NasaPolynomial): + Label(thframe,text='Parametrization:').grid(row=1,column=1) + self.addEntry(thframe,'',2,0,'NasaPolynomial') + Label(thframe,text='Temperatures (min, mid, max):').grid(row=3,column=1) + self.addEntry(thframe,'',4,0,`sp.minTemp`) + self.addEntry(thframe,'',5,0,`sp.midTemp`) + self.addEntry(thframe,'',6,0,`sp.maxTemp`) + low = Frame(thframe) + low.config(relief=GROOVE,bd=4) + low.grid(row=1,rowspan=6,column=3,columnspan=2) + Label(low,text='Coefficients for the Low\n Temperature Range').grid(row=0,column=0,columnspan=2,sticky=E+W) + c = sp.thermoParam().coefficients(sp.minTemp) + for j in range(7): + self.addEntry(low,'a'+`j`,j+3,0,`c[j]`) + high = Frame(thframe) + high.config(relief=GROOVE,bd=4) + high.grid(row=1,rowspan=6,column=5,columnspan=2) + Label(high,text='Coefficients for the High\n Temperature Range').grid(row=0,column=0,columnspan=2,sticky=E+W) + c = sp.thermoParam().coefficients(sp.maxTemp) + for j in range(7): + self.addEntry(high,'a'+`j`,j+3,0,`c[j]`) + + com = Frame(e) + com.grid(row=10,column=0,columnspan=5) + ok = Button(com,text='OK',default=ACTIVE) + ok.grid(row=0,column=0) + ok.bind('<1>',self.modifySpecies) + Button(com,text='Cancel',command=e.destroy).grid(row=0,column=1) + self.especies = e + + def modifySpecies(self,event=None): + button = event.widget + e = self.especies + for fr in e.children.values(): + for item in fr.children.values(): + try: + print item.cget('selection') + except: + pass + e.destroy() + + def addEntry(self,master,name,row,column,text): + if name: + Label(master, text=name).grid(row=row, column=column) + nm = Entry(master) + nm.grid(row=row, column=column+1) + nm.insert(END,text) + + def chooseElements(self): + oldel = self.mix.g.elementNames() + newel = getElements(self.mix.g.elementNames()) + removeList = [] + for el in oldel: + if not el in newel: + removeList.append(el) + #self.app.mech.removeElements(removeList) + addList = [] + for el in newel: + if not el in oldel: + addList.append(el) + #self.app.mech.addElements(addList) + try: + self.redraw() + self.app.makeWindows() + except: + handleError('Edit err') + + self.app.mix = IdealGasMixture(self.app.mech) + self.mix = self.app.mix + nn = self.mix.speciesList[0].name + self.mix.set(temperature = 300.0, pressure = 101325.0, moles = {nn:1.0}) + for label in self.element_labels: + label.destroy() + self.element_labels = [] + n = 0 + for el in self.mix._mech.elementList(): + x = Label(self.eframe,text=el.symbol(),fg='darkblue') + x.grid(column = n, row=0) + self.element_labels.append(x) + n = n + 1 + + self.app.makeWindows() + diff --git a/apps/MixMaster/ElementFrame.py b/apps/MixMaster/ElementFrame.py new file mode 100644 index 000000000..8ee42e1fa --- /dev/null +++ b/apps/MixMaster/ElementFrame.py @@ -0,0 +1,184 @@ +# +# function getElements displays a periodic table, and returns a list of +# the selected elements +# + +from Tkinter import * +from types import * +import tkMessageBox +import string + +from Cantera import * + +# (row,column) positions in the periodic table +_pos = {'H':(1,1), 'He':(1,18), + 'Li':(2,1), 'Be':(2,2), + 'B':(2,13), 'C':(2,14), 'N':(2,15), 'O':(2,16), 'F':(2,17), 'Ne':(2,18), + 'Na':(3,1), 'Mg':(3,2), + 'Al':(3,13), 'Si':(3,14), 'P':(3,15), 'S':(3,16), 'Cl':(3,17), 'Ar':(3,18), + 'K':(4,1), 'Ca':(4,2), + 'Sc':(4,3), 'Ti':(4,4), 'V':(4,5), 'Cr':(4,6), 'Mn':(4,7), 'Fe':(4,8), + 'Co':(4,9), 'Ni':(4,10), 'Cu':(4,11), 'Zn':(4,12), + 'Ga':(4,13), 'Ge':(4,14), 'As':(4,15), 'Se':(4,16), 'Br':(4,17), 'Kr':(4,18), + 'Rb':(5,1), 'Sr':(5,2), + 'Y':(5,3), 'Zr':(5,4), 'Nb':(5,5), 'Mo':(5,6), 'Tc':(5,7), 'Ru':(5,8), + 'Rh':(5,9), 'Pd':(5,10), 'Ag':(5,11), 'Cd':(5,12), + 'In':(5,13), 'Sn':(5,14), 'Sb':(5,15), 'Te':(5,16), 'I':(5,17), 'Xe':(5,18) + } + +class PeriodicTable(Frame): + + def __init__(self, master, selected=[]): + Frame.__init__(self,master) + self.master = master + self.control = Frame(self) + self.control.config(relief=GROOVE,bd=4) + Button(self.control, text = 'Display',command=self.show).pack(fill=X,pady=3, padx=10) + Button(self.control, text = 'Clear',command=self.clear).pack(fill=X,pady=3, padx=10) + Button(self.control, text = ' OK ',command=self.get).pack(side=BOTTOM, + fill=X,pady=3, padx=10) + Button(self.control, text = 'Cancel',command=self.master.quit).pack(side=BOTTOM, + fill=X,pady=3, padx=10) + self.entries = Frame(self) + self.entries.pack(side=LEFT) + self.control.pack(side=RIGHT,fill=Y) + self.c = {} + self.element = {} + self.selected = selected + n=0 + ncol = 8 + for el in _pos.keys(): + self.element[el] = Frame(self.entries) + self.element[el].config(relief=GROOVE, bd=4, bg=self.color(el)) + self.c[el] = Button(self.element[el],text=el,bg=self.color(el),width=3,relief=FLAT) + self.c[el].pack() + self.c[el].bind("",self.setColors) + self.element[el].grid(row=_pos[el][0]-1, column = _pos[el][1]-1,sticky=W+N+E+S) + n = n + 1 + Label(self.entries,text='select the elements to be included, and then press OK.\nTo view the properties of the selected elements, press Display ').grid(row=0, column=2, columnspan=10, sticky=W) + + + def select(self, el): + e = string.capitalize(el) + self.c[e]['relief'] = RAISED + self.c[e]['bg'] = self.color(e, sel=1) + + def deselect(self, el): + e = string.capitalize(el) + self.c[e]['relief'] = FLAT + self.c[e]['bg'] = self.color(e, sel=0) + + def selectElements(self,ellist): + for el in ellist: + ename = el + self.select(ename) + + def setColors(self,event): + el = event.widget['text'] + if event.widget['relief'] == RAISED: + event.widget['relief'] = FLAT + back = self.color(el, sel=0) + elif event.widget['relief'] == FLAT: + event.widget['relief'] = RAISED + back = self.color(el, sel=1) + event.widget['bg'] = back + + def color(self, el, sel=0): + _normal = ['#88dddd','#dddd88','#dd8888'] + _selected = ['#aaffff','#ffffaa','#ffaaaa'] + row, column = _pos[el] + if sel: list = _selected + else: list = _normal + if column < 3: + return list[0] + elif column > 12: + return list[1] + else: + return list[2] + + def show(self): + elnames = _pos.keys() + elnames.sort() + selected = [] + for el in elnames: + if self.c[el]['relief'] == RAISED: + selected.append(periodicTable[el]) + showElementProperties(selected) + + def get(self): + self.selected = [] + names = _pos.keys() + names.sort() + for el in names: + if self.c[el]['relief'] == RAISED: + self.selected.append(periodicTable[el]) + #self.master.quit()' + self.master.destroy() + + def clear(self): + for el in _pos.keys(): + self.c[el]['bg'] = self.color(el, sel=0) + self.c[el]['relief'] = FLAT + +class ElementPropertyFrame(Frame): + def __init__(self,master,ellist): + Frame.__init__(self,master) + n = 1 + ellist.sort() + Label(self,text='Name').grid(column=0,row=0,sticky=W+S,padx=10,pady=10) + Label(self,text='Atomic \nNumber').grid(column=1,row=0,sticky=W+S,padx=10,pady=10) + Label(self, + text='Atomic \nWeight').grid(column=2, + row=0, + sticky=W+S, + padx=10, + pady=10) + for el in ellist: + Label(self, + text=el.name).grid(column=0, + row=n, + sticky=W, + padx=10) + Label(self, + text=`el.atomicNumber`).grid(column=1, + row=n, + sticky=W, + padx=10) + Label(self, + text=`el.atomicWeight`).grid(column=2, + row=n, + sticky=W, + padx=10) + n = n + 1 + + +# utility functions + +def getElements(ellist=None): + master = Toplevel() + master.title('Periodic Table of the Elements') + t = PeriodicTable(master) + if ellist: t.selectElements(ellist) + t.pack() + t.focus_set() + t.grab_set() + t.wait_window() + try: + master.destroy() + except TclError: + pass + return t.selected + + +# display table of selected element properties in a window +def showElementProperties(ellist): + m = Tk() + m.title('Element Properties') + elem = [] + ElementPropertyFrame(m, ellist).pack() + + +if __name__ == "__main__": + print getElements() + + diff --git a/apps/MixMaster/GraphFrame.py b/apps/MixMaster/GraphFrame.py new file mode 100644 index 000000000..7acdf4181 --- /dev/null +++ b/apps/MixMaster/GraphFrame.py @@ -0,0 +1,130 @@ + +from Tkinter import * +import math + +class Graph(Frame): + def __init__(self,master,title,minX,maxX,minY,maxY,pixelX=250,pixelY=250): + Frame.__init__(self,master, relief=RIDGE, bd=2) + # self.pack() + self.title = Label(self,text=' ') + self.title.grid(row=0,column=1,sticky=W+E) + self.graph_w, self.graph_h = pixelX, pixelY + self.maxX, self.maxY = maxX, maxY #float(math.floor(maxX + 1)), \ + #float(math.floor(maxY + 1)) + self.minX, self.minY = minX, minY # float(math.floor(minX)), float(math.floor(minY)) + self.canvas = Canvas(self, + width=self.graph_w, + height=self.graph_h, + relief=SUNKEN,bd=1) + ymintext = "%8.1f" % (self.minY) + ymaxtext = "%8.1f" % (self.maxY) + self.ml=Label(self, text=ymintext) + self.mr=Label(self, text=ymaxtext) + self.ml.grid(row=2,column=0,sticky=S+E) + self.mr.grid(row=1,column=0,sticky=N+E) + self.canvas.grid(row=1,column=1,rowspan=2,sticky=N+S+E+W) + self.last_points=[] + + + def writeValue(self, y): + yval = '%15.4f' % (y) + self.title.config(text = yval) + + def delete(self, ids): + for id in ids: + self.canvas.delete(id) + + def move(self, id, newpos, oldpos): + dxpt = (newpos[0] - oldpos[0])/(self.maxX-self.minX)*self.graph_w + dypt = -(newpos[1] - oldpos[1])/(self.maxY-self.minY)*self.graph_h + self.canvas.move(id, dxpt, dypt) + self.writeValue(newpos[1]) + + def plot(self,x,y,color='black'): + xpt = (x-self.minX)/(self.maxX-self.minX)*float(self.graph_w) + 1.5 + ypt = (self.maxY-y)/(self.maxY-self.minY)*float(self.graph_h) - 1.5 + id_ycross = self.canvas.create_line(xpt,self.graph_h,xpt,0,fill = 'gray') + id_xcross = self.canvas.create_line(0,ypt,self.graph_w,ypt,fill = 'gray') + id = self.canvas.create_oval(xpt-2,ypt-2,xpt+2,ypt+2,fill=color) + self.writeValue(y) + return [id,id_xcross,id_ycross] + + def reset(self,minX,maxX,minY,maxY): + self.maxX, self.maxY = maxX, maxY + self.minX, self.minY = minX, minY + self.canvas.destroy() + self.canvas = Canvas(self, + width=self.graph_w, + height=self.graph_h, + relief=SUNKEN,bd=1) + self.canvas.create_text(4,2,text=self.maxY,anchor=NW) + self.canvas.create_text(4,self.graph_h,text=self.minY,anchor=SW) + self.ml["text"] = `minX` + self.mr["text"] = `maxX` + self.canvas.pack() + self.last_points = [] + + def join(self,point_list): + i = 0 + for pt in point_list: + x, y, color = pt + if self.last_points == []: + last_x, last_y, last_color = pt + else: + last_x, last_y, last_color = self.last_points[i] + i = i + 1 + xpt = (x - self.minX)/(float(self.maxX - self.minX)/self.graph_w) + 1.5 + ypt = (self.maxY-y)/(float(self.maxY - self.minY)/self.graph_h) - 1.5 + last_xpt = (last_x - self.minX)/(float(self.maxX - self.minX)/self.graph_w) + 1.5 + last_ypt = (self.maxY-last_y)/(float(self.maxY - self.minY)/self.graph_h) - 1.5 + self.canvas.create_line(last_xpt,last_ypt, + xpt,ypt,fill=color) + self.last_points = point_list + self.canvas.update() + return + + + def addLegend(self,text,color=None): + m=Message(self,text=text,width=self.graph_w-10) + m.pack(side=BOTTOM) + if color: + m.config(fg=color) + + def pauseWhenFinished(self): + self.wait_window() + + +if __name__=='__main__': + root= Tk() + g = Graph(root,'graph1',0,10,0.01,120) + h = Graph(root,'graph2',0,15,0,20000) + g.pack(side=LEFT) + h.pack(side=RIGHT) + + #root.protocol("WM_DELETE_WINDOW", root.destroy()) + j = Graph(root,'Graph',0,1000,0,2000) + j.pack() + + j.plot(0, 0, color='red') + j.last_points = [ (0, 0, 'red') ] + for i in range(100): + j.join( [ ( (i*10),(i*10+500), 'red' ) ] ) + + + g.addLegend('An example of the GraphFrame') + h.addLegend('This is where the legend goes') + for i in range(100): + if root: + x,y = float(i)/10, i + g.plot(x,y,color='red') + h.plot(i,i**2)#(0,0) + #h.join([(i,i**2,'black')]) + else: + break + + #print("finished") + g.pauseWhenFinished() + h.pauseWhenFinished() + print g + + diff --git a/apps/MixMaster/ImportFrame.py b/apps/MixMaster/ImportFrame.py new file mode 100644 index 000000000..d5b2fcae5 --- /dev/null +++ b/apps/MixMaster/ImportFrame.py @@ -0,0 +1,119 @@ +import os, math +from Tkinter import * +from Cantera import * +from Cantera.ck2ctml import ck2ctml +from tkFileDialog import askopenfilename + +class ImportFrame(Frame): + def __init__(self,top): + self.master = Toplevel() + self.master.title('Convert and Import CK File') + self.master.protocol("WM_DELETE_WINDOW",self.hide) + + Frame.__init__(self,self.master) + self.config(relief=GROOVE, bd=4) + self.top = top + self.infile = StringVar() + + Label(self,text="Input File").grid(row=0,column=0) + Entry(self, width=40, + textvariable=self.infile).grid(column=1,row=0) + Button(self, text='Browse', + command=self.browseForInput).grid(row=0,column=2) + + self.thermo = StringVar() + Label(self,text="Thermodynamic Database").grid(row=1,column=0) + Entry(self, width=40, + textvariable=self.thermo).grid(column=1,row=1) + Button(self, text='Browse', + command=self.browseForThermo).grid(row=1,column=2) + + + self.transport = StringVar() + Label(self,text="Transport Database").grid(row=2,column=0) + Entry(self, width=40, + textvariable=self.transport).grid(column=1,row=2) + Button(self, text='Browse', + command=self.browseForTransport).grid(row=2,column=2) + + bframe = Frame(self) + bframe.config(relief=GROOVE, bd=1) + bframe.grid(row=100,column=0) + Button(bframe, text='OK', width=8, command=self.importfile).grid(row=0,column=0) + self.grid(column=0,row=0) + Button(bframe, text='Cancel', width=8, command=self.hide).grid(row=0,column=1) + self.grid(column=0,row=0) + self.hide() + + def browseForInput(self, e=None): + pathname = askopenfilename( + filetypes=[("Reaction Mechanism Files", + ("*.inp","*.mech","*.ck2")), + ("All Files", "*.*")]) + if pathname: + self.infile.set(pathname) + self.show() + + def browseForThermo(self, e=None): + pathname = askopenfilename( + filetypes=[("Thermodynamic Databases", + ("*.dat","*.inp","*.therm")), + ("All Files", "*.*")]) + if pathname: + self.thermo.set(pathname) + self.show() + + def browseForTransport(self, e=None): + pathname = askopenfilename( + filetypes=[("Transport Databases", "*.dat"), + ("All Files", "*.*")]) + if pathname: + self.transport.set(pathname) + self.show() + + + def importfile(self): + ckfile = self.infile.get() + thermdb = self.thermo.get() + trandb = self.transport.get() + p = os.path.normpath(os.path.dirname(ckfile)) + fname = os.path.basename(ckfile) + ff = os.path.splitext(fname) + nm = "" + if len(ff) > 1: nm = ff[0] + else: nm = ff + outfile = p+os.sep+nm+'.xml' + try: + ck2ctml(infile = ckfile, thermo = thermdb, + transport = trandb, outfile = outfile, + id = nm) + except: + print 'Errors were encountered. See log file ck2ctml.log' + self.hide() + return + + self.top.loadmech(nm,outfile,1) + self.hide() + +## cmd = 'ck2ctml -i '+ckfile+' -o '+outfile +## if thermdb <> "": +## cmd += ' -t '+thermdb +## if trandb <> "": +## cmd += ' -tr '+trandb +## cmd += ' -id '+nm +## ok = os.system(cmd) +## if ok == 0: +## self.top.loadmech(nm,outfile,1) + + + def hide(self): + #self.vis.set(0) + self.master.withdraw() + + def show(self): + #v = self.vis.get() + #if v == 0: + # self.hide() + # return + + self.master.deiconify() diff --git a/apps/MixMaster/KineticsFrame.py b/apps/MixMaster/KineticsFrame.py new file mode 100644 index 000000000..09b1068d8 --- /dev/null +++ b/apps/MixMaster/KineticsFrame.py @@ -0,0 +1,356 @@ +import os, math +from Tkinter import * +from Cantera import * + +from SpeciesInfo import SpeciesInfo +from Cantera import rxnpath +import webbrowser + +_CUTOFF = 1.e-15 +_ATOL = 1.e-15 +_RTOL = 1.e-7 + +class KineticsFrame(Frame): + def __init__(self,master): + Frame.__init__(self,master) + self.config(relief=FLAT, bd=4) + self.top = self.master.top + self.controls=Frame(self) + self.hide = IntVar() + self.hide.set(0) + self.comp = IntVar() + self.comp.set(2) + self.controls.grid(column=1,row=0,sticky=W+E+N) + self.makeControls() + mf = self.master + + def makeControls(self): + Radiobutton(self.controls,text='Creation Rates', + variable=self.comp,value=0, + command=self.show).grid(column=0,row=0,sticky=W) + Radiobutton(self.controls,text='Destruction Rates', + variable=self.comp,value=1, + command=self.show).grid(column=0,row=1,sticky=W) + Radiobutton(self.controls,text='Net Production Rates', + variable=self.comp,value=2, + command=self.show).grid(column=0,row=2,sticky=W) + + def show(self): + mf = self.master + mf.active = self + c = self.comp.get() + mix = self.top.mix + g = mix.g + if c == 0: + mf.var.set("Creation Rates") + #mf.data = spdict(mix.g, mix.moles()) + mf.comp = g.creationRates() + + elif c == 1: + mf.var.set("Destruction Rates") + #mf.data = spdict(mix.g,mix.mass()) + mf.comp = g.destructionRates() + + elif c == 2: + mf.var.set("Net Production Rates") + mf.comp = g.netProductionRates() + #mf.data = spdict(mix,mix,mf.comp) + + for s in mf.variable.keys(): + try: + k = g.speciesIndex(s) + if mf.comp[k] > _CUTOFF or -mf.comp[k] > _CUTOFF: + mf.variable[s].set(mf.comp[k]) + else: + mf.variable[s].set(0.0) + except: + pass + +class SpeciesKineticsFrame(Frame): + def __init__(self,master,top): + Frame.__init__(self,master) + self.config(relief=GROOVE, bd=4) + self.top = top + self.top.kinetics = self + self.g = self.top.mix.g + self.entries=Frame(self) + self.var = StringVar() + self.var.set("Net Production Rates") + self.names = self.top.mix.speciesNames() + self.nsp = len(self.names) + self.comp = [0.0]*self.nsp + self.makeControls() + self.makeEntries() + self.entries.bind('',self.minimize) + self.ctype = 0 + + def makeControls(self): + self.c = KineticsFrame(self) + #self.rr = ReactionKineticsFrame(self, self.top) + self.c.grid(column=1,row=0,sticky=E+W+N+S) + #self.rr.grid(column=0,row=1,sticky=E+W+N+S) + + def show(self): + self.c.show() + + def redo(self): + self.update() + self.entries.destroy() + self.entries=Frame(self) + self.makeEntries() + + def minimize(self,Event=None): + self.c.hide.set(1) + self.redo() + self.c.grid_forget() + self.entries.bind("",self.maximize) + + def maximize(self,Event=None): + self.c.hide.set(0) + self.redo() + self.c.grid(column=1,row=0,sticky=E+W+N+S) + self.entries.bind("",self.minimize) + + def up(self, x): + self.update() + + def makeEntries(self): + self.entries.grid(row=0,column=0,sticky=W+N+S+E) + self.entries.config(relief=FLAT,bd=4) + DATAKEYS = self.top.species + self.variable = {} + + n=0 + ncol = 3 + col = 0 + row = 60 + + for sp in DATAKEYS: + s = sp + k = s.index + if row > 15: + row = 0 + col = col + 2 + l = Label(self.entries,text='Species') + l.grid(column=col,row=row,sticky=E+W) + e1 = Entry(self.entries) + e1.grid(column=col+1,row=row,sticky=E+W) + e1['textvariable'] = self.var + e1.config(state=DISABLED) + e1.config(bg='lightyellow',relief=RIDGE) + row = row + 1 + + spname = s.name + val = self.comp[k] + if not self.c.hide.get() or val: showit = 1 + else: showit = 0 + + l=SpeciesInfo(self.entries,species=s, + text=spname,relief=FLAT,justify=RIGHT, + fg='darkblue') + entry1 = Entry(self.entries) + self.variable[spname] = DoubleVar() + self.variable[spname].set(self.comp[k]) + entry1['textvariable']=self.variable[spname] + entry1.bind('',self.up) + if showit: + l.grid(column= col ,row=row,sticky=E) + entry1.grid(column=col+1,row=row) + n=n+1 + row = row + 1 + entry1.config(state=DISABLED,bg='lightgray') + + +class ReactionKineticsFrame(Frame): + def __init__(self,vis,top): + self.master = Toplevel() + self.master.protocol("WM_DELETE_WINDOW",self.hide) + self.vis = vis + Frame.__init__(self,self.master) + self.config(relief=GROOVE, bd=4) + self.top = top + self.g = self.top.mix.g + nr = self.g.nReactions() + self.eqs=Text(self,width=40,height=nr) + self.data = [] + for i in range(4): + self.data.append(Text(self,width=15,height=nr)) + + for n in range(nr): + s = self.g.reactionEqn(n) + self.eqs.insert(END,s+'\n') + self.eqs.grid(column=0,row=1,sticky=W+E+N) + for i in range(4): + self.data[i].grid(column=i+1,row=1,sticky=W+E+N) + Label(self, text='Reaction').grid(column=0,row=0,sticky=W+E+N) + Label(self, text='Fwd ROP').grid(column=1,row=0,sticky=W+E+N) + Label(self, text='Rev ROP').grid(column=2,row=0,sticky=W+E+N) + Label(self, text='Net ROP').grid(column=3,row=0,sticky=W+E+N) + Label(self, text='Kp').grid(column=4,row=0,sticky=W+E+N) +# Button(self, text='View Reaction Paths', command=self.viewRxnPaths).grid(column=0,row=2,sticky=W+E+N) + self.grid(column=0,row=0) + self.hide() + + def hide(self): +# self.vis.set(0) + self.master.withdraw() + + def show(self): + v = self.vis.get() + #if v == 0: + # self.hide() + # return + + self.master.deiconify() + nr = self.g.nReactions() + frop = self.g.fwdRatesOfProgress() + rrop = self.g.revRatesOfProgress() + kp = self.g.equilibriumConstants() + self.data[0].delete(1.0,END) + self.data[1].delete(1.0,END) + self.data[2].delete(1.0,END) + self.data[3].delete(1.0,END) + for n in range(nr): + s = '%12.5e \n' % (frop[n],) + self.data[0].insert(END,s) + s = '%12.5e \n' % (rrop[n],) + self.data[1].insert(END,s) + s = '%12.5e \n' % (frop[n] - rrop[n],) + self.data[2].insert(END,s) + s = '%12.5e \n' % (kp[n],) + self.data[3].insert(END,s) + + +class ReactionPathFrame(Frame): + + def __init__(self,top): + self.master = Toplevel() + self.master.protocol("WM_DELETE_WINDOW",self.hide) + #self.vis = vis + Frame.__init__(self,self.master) + self.config(relief=GROOVE, bd=4) + self.grid(column=0,row=0) + self.top = top + self.g = self.top.mix.g + self.el = IntVar() + self.el.set(0) + self.thresh = DoubleVar() + + scframe = Frame(self) + self.sc = Scale(scframe,variable = self.thresh, + orient='horizontal',digits=3,length=300,resolution=0.01) + self.sc.config(cnf={'from':-6,'to':0}) + Label(scframe,text='log10 Threshold').grid(column=0,row=0) + self.sc.grid(row=0,column=1,columnspan=10) + self.sc.bind('',self.show) + scframe.grid(row=3,column=0,columnspan=10) + + enames = self.g.elementNames() + self.nel = len(enames) + + i = 1 + eframe = Frame(self) + Label(eframe,text='Element').grid(column=0,row=0,sticky=W) + for e in enames: + Radiobutton(eframe,text=e, + variable=self.el,value=i-1, + command=self.show).grid(column=i,row=0,sticky=W) + i += 1 + eframe.grid(row=0,column=0) + + self.detailed = IntVar() + Checkbutton(self, text = 'Show details', variable=self.detailed, + command=self.show).grid(column=1,row=0) + self.net = IntVar() + Checkbutton(self, text = 'Show net flux', + variable=self.net, + command=self.show).grid(column=2,row=0) + self.local = StringVar() + Label(self,text='Species').grid(column=1,row=1,sticky=E) + sp = Entry(self, textvariable=self.local, + width=15) + sp.grid(column=2,row=1) + sp.bind('',self.show) + + self.b = rxnpath.PathBuilder(self.g) + + self.fmt = StringVar() + self.fmt.set('svg') + i = 1 + fmtframe = Frame(self) + fmtframe.config(relief=GROOVE, bd=4) + self.browser = IntVar() + Checkbutton(fmtframe, text = 'Display in Web Browser', + variable=self.browser, + command=self.show).grid(column=0,columnspan=6,row=0) + Label(fmtframe,text='Format').grid(column=0,row=1,sticky=W) + for e in ['svg', 'png', 'gif', 'jpg']: + Radiobutton(fmtframe,text=e, + variable=self.fmt,value=e, + command=self.show).grid(column=i,row=1,sticky=W) + i += 1 + fmtframe.grid(row=5,column=0,columnspan=10,sticky=E+W) + + self.cv = Canvas(self,relief=SUNKEN,bd=1) + self.cv.grid(column=0,row=4,sticky=W+E+N,columnspan=10) + + pframe = Frame(self) + pframe.config(relief=GROOVE, bd=4) + self.dot = StringVar() + self.dot.set('dot -Tgif rxnpath.dot > rxnpath.gif') + Label(pframe,text='DOT command:').grid(column=0,row=0,sticky=W) + Entry(pframe,width=60,textvariable=self.dot).grid(column=0, + row=1,sticky=W) + pframe.grid(row=6,column=0,columnspan=10,sticky=E+W) + + self.thresh.set(-2.0) + self.hide() + + def hide(self): + #self.vis.set(0) + self.master.withdraw() + + def show(self,e=None): + + self.master.deiconify() + el = self.g.elementName(self.el.get()) + det = 'false' + if self.detailed.get() == 1: det = 'true' + flow = 'one_way' + if self.net.get() == 1: flow = 'net' + self.d = rxnpath.PathDiagram(arrow_width=-2, + flow_type=flow, + detailed = det, + threshold=math.pow(10.0, + self.thresh.get())) + node = self.local.get() + try: + k = self.g.speciesIndex(node) + self.d.displayOnly(k) + except: + self.d.displayOnly() + + self.b.build(element = el, diagram = self.d, + dotfile = 'rxnpath.dot', format = 'dot') + + if self.browser.get() == 1: + fmt = self.fmt.get() + os.system('dot -T'+fmt+' rxnpath.dot > rxnpath.'+fmt) + webbrowser.open('rxnpath.'+fmt) + try: + self.cv.delete(self.image) + except: + pass + else: + os.system(self.dot.get()) + self.rp = PhotoImage(file='rxnpath.gif') + try: + self.cv.delete(self.image) + except: + pass + self.cv.configure(width=self.rp.width(), + height=self.rp.height()) + + self.image = self.cv.create_image(0,0,anchor=NW, + image=self.rp) + diff --git a/apps/MixMaster/MechManager.py b/apps/MixMaster/MechManager.py new file mode 100644 index 000000000..38e427fad --- /dev/null +++ b/apps/MixMaster/MechManager.py @@ -0,0 +1,86 @@ +from Cantera import * +from Tkinter import * +from ControlPanel import ControlWindow +from ControlPanel import make_menu, menuitem_state +#from Cantera.Examples.Tk import _mechdir +import os + +# automatically-loaded mechanisms +_autoload = [ + (' GRI-Mech 3.0', 'gri30.xml'), + (' Air', 'air.xml'), + (' H/O/Ar', 'h2o2.xml') + ] + +def testit(): + pass + +class MechManager(Frame): + + def __init__(self,master,app): + Frame.__init__(self,master) + #self.config(relief=GROOVE, bd=4) + self.app = app + self.master = master + self.mechindx = IntVar() + self.mechindx.set(1) + + #m = Label(self, text = 'Loaded Mechanisms') + #m.grid(column=0,row=0) +# m.bind('',self.show) +# self.mechindx.set(0) + self.mechanisms = [] + self.mlist = [ [] ] + i = 1 + #for m in self.mechanisms: + # self.mlist.append((m[0], self.setMechanism, 'check', self.mechindx, i)) + # i = i + 1 + #self.mlist.append([]) + + self.mechmenu = make_menu('Mixtures', self, self.mlist) + self.mechmenu.grid(row=0,column=0,sticky=W) + + self.mfr = None + + def addMechanism(self, name, mech): + self.mechanisms.append((name, mech)) + il = len(self.mechanisms) + self.mlist[-1] = (name, self.setMechanism, 'check', self.mechindx, il) + self.mlist.append([]) + + self.mechmenu = make_menu('Mixtures', self, self.mlist) + self.mechindx.set(il) + self.mechmenu.grid(row=0,column=0,sticky=W) + + + def delMechanism(self, mech): + self.mechanisms.remove(mech) + self.show() + +## def show(self,event=None): +## print 'show' +## if self.mfr: +## self.mfr.destroy() +## self.mfr = Frame(self) +## self.mfr.grid(row=1,column=0) +## self.mfr.config(relief=GROOVE, bd=4) +## Label(self.mfr,text='jkl').grid(row=0,column=0) +## i = 0 +## for name, mech in self.mechanisms: +## Radiobutton(self.mfr, text=name, variable=self.mechindx, +## value = i, +## command=self.setMechanism).grid(row=i,column=0) +## i = i + 1 +## print 'end' + + + def setMechanism(self, event=None): + i = self.mechindx.get() + self.app.mech = self.mechanisms[i-1][1] + self.app.makeMix() + self.app.makeWindows() + + + + + diff --git a/apps/MixMaster/Mix.py b/apps/MixMaster/Mix.py new file mode 100644 index 000000000..ccaa5d8e1 --- /dev/null +++ b/apps/MixMaster/Mix.py @@ -0,0 +1,132 @@ +from Cantera import GasConstant, OneAtm +from Numeric import zeros + +def spdict(phase, x): + nm = phase.speciesNames() + data = {} + for k in range(len(nm)): + data[nm[k]] = x[k] + return data + +class Species: + def __init__(self,g,name): + self.g = g + t = g.temperature() + p = g.pressure() + x = g.moleFractions() + self.name = name + self.symbol = name + self.index = g.speciesIndex(name) + self.minTemp = g.minTemp(self.index) + self.maxTemp = g.maxTemp(self.index) + self.molecularWeight = g.molecularWeights()[self.index] + self.c = [] + self.e = g.elementNames() + self.hf0 = self.enthalpy_RT(298.15)*GasConstant*298.15 + g.setState_TPX(t,p,x) + for n in range(len(self.e)): + na = g.nAtoms(self.index, n) + if na > 0: + self.c.append((self.e[n],na)) + + def composition(self): + return self.c + + def enthalpy_RT(self,t): + self.g.setTemperature(t) + return self.g.enthalpies_RT()[self.index] + + def cp_R(self,t): + self.g.setTemperature(t) + return self.g.cp_R()[self.index] + + def entropy_R(self,t): + self.g.setTemperature(t) + return self.g.entropies_R()[self.index] + +class Mix: + def __init__(self,g): + self.g = g + self._mech = g + self.nsp = g.nSpecies() + self._moles = zeros(self.nsp,'d') + self.wt = g.molecularWeights() + + def setMoles(self, m): + self._moles = m + self.g.setMoleFractions(self._moles) + + def moles(self): + return self._moles + + def totalMoles(self): + sum = 0.0 + for k in range(self.nsp): + sum += self._moles[k] + return sum + + def totalMass(self): + sum = 0.0 + for k in range(self.nsp): + sum += self._moles[k]*self.wt[k] + return sum + + def moleDict(self): + d = {} + nm = self.g.speciesNames() + for e in range(self.nsp): + d[nm[e]] = self._moles[e] + return d + + def setMass(self, m): + self.setMoles( m/self.wt) + + def mass(self): + return self.wt*self._moles + + def speciesNames(self): + return self.g.speciesNames() + + def massDict(self): + d = {} + nm = self.g.speciesNames() + for e in range(self.nsp): + d[nm[e]] = self._moles[e]*self.wt[e] + return d + + def set(self, temperature = None, pressure = None, + density = None, enthalpy = None, + entropy = None, equil = 0): + total_mass = self.totalMass() + + if temperature and pressure: + self.g.setState_TP(temperature, pressure) + if equil: + self.g.equilibrate('TP') + + elif temperature and density: + self.g.setState_TR(temperature, density) + if equil: + self.g.equilibrate('TV') + + elif pressure and enthalpy: + self.g.setState_HP(enthalpy, pressure) + if equil: + self.g.equilibrate('HP') + + elif pressure and entropy: + self.g.setState_SP(entropy, pressure) + if equil: + self.g.equilibrate('SP') + + elif density and entropy: + self.g.setState_SV(entropy, 1.0/density) + if equil: + self.g.equilibrate('SV') + + + total_moles = total_mass/self.g.meanMolecularWeight() + self._moles = self.g.moleFractions()*total_moles + + + diff --git a/apps/MixMaster/NewFlowFrame.py b/apps/MixMaster/NewFlowFrame.py new file mode 100644 index 000000000..b0335ce0e --- /dev/null +++ b/apps/MixMaster/NewFlowFrame.py @@ -0,0 +1,116 @@ +from Tkinter import * +from Cantera import * + +from SpeciesInfo import SpeciesInfo + +_CUTOFF = 1.e-15 +_ATOL = 1.e-15 +_RTOL = 1.e-7 + +class NewFlowFrame(Frame): + def __init__(self,master): + Frame.__init__(self,master) + self.config(relief=GROOVE, bd=4) + self.app = self.master.app + self.controls=Frame(self) + self.hide = IntVar() + self.hide.set(0) + self.p = DoubleVar() + #self.comp.set(1.0) + self.controls.grid(column=1,row=0,sticky=W+E+N) + #self.makeControls() + mf = self.master + + e1 = Entry(self) + e1.grid(column=0,row=0,sticky=E+W) + e1['textvariable'] = self.p + #e1.config(state=ENABLED) + e1.config(relief=RIDGE) + +## def makeControls(self): +## Radiobutton(self.controls,text='Moles', +## variable=self.comp,value=0,command=self.show).grid(column=0,row=0,sticky=W) +## Radiobutton(self.controls,text='Mass',variable=self.comp,value=1,command=self.show).grid(column=0,row=1,sticky=W) +## Radiobutton(self.controls,text='Concentration',variable=self.comp,value=2,command=self.show).grid(column=0,row=2,sticky=W) +## Button(self.controls,text='Clear',command=self.zero).grid(column=0,row=4,sticky=W+E) +## Button(self.controls,text='Normalize',command=self.norm).grid(column=0,row=5,sticky=W+E) +## Checkbutton(self.controls,text='Hide Missing\nSpecies', +## variable=self.hide,onvalue=1,offvalue=0,command=self.master.redo).grid(column=0,row=3,sticky=W) + + +## def makeControls(self): +## self.c = CompFrame(self) +## self.c.grid(column=1,row=0,sticky=E+W+N+S) + +## def redo(self): +## self.update() +## self.entries.destroy() +## self.entries=Frame(self) +## self.makeEntries() + +## def minimize(self,Event=None): +## self.c.hide.set(1) +## self.redo() +## self.c.grid_forget() +## self.entries.bind("",self.maximize) + +## def maximize(self,Event=None): +## self.c.hide.set(0) +## self.redo() +## self.c.grid(column=1,row=0,sticky=E+W+N+S) +## self.entries.bind("",self.minimize) + + +## def makeEntries(self): +## self.entries.grid(row=0,column=0,sticky=W+N+S+E) +## self.entries.config(relief=GROOVE,bd=4) +## DATAKEYS = self.top.species +## self.variable = {} + +## n=0 +## ncol = 3 +## col = 0 +## row = 60 + +## presbox = + +## for sp in DATAKEYS: +## s = sp # self.top.species[sp] +## k = s.index +## if row > 15: +## row = 0 +## col = col + 2 +## l = Label(self.entries,text='Species') +## l.grid(column=col,row=row,sticky=E+W) +## e1 = Entry(self.entries) +## e1.grid(column=col+1,row=row,sticky=E+W) +## e1['textvariable'] = self.var +## e1.config(state=DISABLED) +## e1.config(bg='lightyellow',relief=RIDGE) +## row = row + 1 + +## spname = s.name +## val = self.comp[k] +## if not self.c.hide.get() or val: showit = 1 +## else: showit = 0 + +## l=SpeciesInfo(self.entries,species=s, +## text=spname,relief=FLAT,justify=RIGHT, +## fg='darkblue') +## entry1 = Entry(self.entries) +## self.variable[spname] = DoubleVar() +## self.variable[spname].set(self.comp[k]) +## entry1['textvariable']=self.variable[spname] +## entry1.bind('',self.up) +## if showit: +## l.grid(column= col ,row=row,sticky=E) +## entry1.grid(column=col+1,row=row) +## n=n+1 +## row = row + 1 +## if self.c.hide.get(): +## b=Button(self.entries,height=1,command=self.maximize) +## else: +## b=Button(self.entries,command=self.minimize) +## b.grid(column=col,columnspan=2, row=row+1) + + diff --git a/apps/MixMaster/SpeciesFrame.py b/apps/MixMaster/SpeciesFrame.py new file mode 100644 index 000000000..5f92d96fd --- /dev/null +++ b/apps/MixMaster/SpeciesFrame.py @@ -0,0 +1,176 @@ +# +# function getElements displays a periodic table, and returns a list of +# the selected elements +# + +from Tkinter import * +from types import * +import tkMessageBox + +from Cantera import * + +class SpeciesFrame(Frame): + + def __init__(self, master, speciesList = [], selected=[]): + Frame.__init__(self,master) + self.master = master + self.control = Frame(self) + self.species = {} + for sp in speciesList: + self.species[sp.name] = sp + + self.control.config(relief=GROOVE,bd=4) + Button(self.control, text = 'Display',command=self.show).pack(fill=X,pady=3, padx=10) + Button(self.control, text = 'Clear',command=self.clear).pack(fill=X,pady=3, padx=10) + Button(self.control, text = ' OK ',command=self.get).pack(side=BOTTOM, + fill=X,pady=3, padx=10) + Button(self.control, text = 'Cancel',command=self.master.quit).pack(side=BOTTOM, + fill=X,pady=3, padx=10) + self.entries = Frame(self) + self.entries.pack(side=LEFT) + self.control.pack(side=RIGHT,fill=Y) + self.c = {} + self.selected = selected + n=0 + ncol = 8 + rw = 1 + col = 0 + list = self.species.values() + list.sort() + for sp in list: + el = sp.name + self.species[el] = Frame(self.entries) + self.species[el].config(relief=GROOVE, bd=4, bg=self.color(el)) + self.c[el] = Button(self.species[el],text=el,bg=self.color(el),width=6,relief=FLAT) + self.c[el].pack() + self.c[el].bind("",self.setColors) + self.species[el].grid(row= rw, column = col,sticky=W+N+E+S) + col = col + 1 + if col > ncol: + rw = rw + 1 + col = 0 + Label(self.entries,text='select the species to be included, and then press OK.\nTo view the properties of the selected species, press Display ').grid(row=0, column=2, columnspan=10, sticky=W) + + + def select(self, el): + self.c[el]['relief'] = RAISED + self.c[el]['bg'] = self.color(el, sel=1) + + def deselect(self, el): + self.c[el]['relief'] = FLAT + self.c[el]['bg'] = self.color(el, sel=0) + + def selectSpecies(self,splist): + for sp in splist: + spname = sp.name + self.select(spname) + + def setColors(self,event): + el = event.widget['text'] + if event.widget['relief'] == RAISED: + event.widget['relief'] = FLAT + back = self.color(el, sel=0) + fore = '#ffffff' + elif event.widget['relief'] == FLAT: + event.widget['relief'] = RAISED + fore = '#000000' + back = self.color(el, sel=1) + event.widget['bg'] = back + event.widget['fg'] = fore + + def color(self, el, sel=0): + _normal = ['#88dddd','#005500','#dd8888'] + _selected = ['#aaffff','#88dd88','#ffaaaa'] + #row, column = _pos[el] + if sel: list = _selected + else: list = _normal + return list[1] + #if column < 3: + # return list[0] + #elif column > 12: + # return list[1] + #else: + # return list[2] + + def show(self): + selected = [] + for sp in self.species.values(): + if self.c[sp.name]['relief'] == RAISED: + selected.append(sp) + #showElementProperties(selected) + + def get(self): + self.selected = [] + for sp in self.species.values(): + if self.c[sp.name]['relief'] == RAISED: + self.selected.append(sp) + #self.master.quit()' + self.master.destroy() + + def clear(self): + for sp in self.species.values(): + self.c[sp]['bg'] = self.color(sp, sel=0) + self.c[sp]['relief'] = FLAT + +## class ElementPropertyFrame(Frame): +## def __init__(self,master,ellist): +## Frame.__init__(self,master) +## n = 1 +## ellist.sort() +## Label(self,text='Name').grid(column=0,row=0,sticky=W+S,padx=10,pady=10) +## Label(self,text='Atomic \nNumber').grid(column=1,row=0,sticky=W+S,padx=10,pady=10) +## Label(self, +## text='Atomic \nWeight').grid(column=2, +## row=0, +## sticky=W+S, +## padx=10, +## pady=10) +## for el in ellist: +## Label(self, +## text=el.name).grid(column=0, +## row=n, +## sticky=W, +## padx=10) +## Label(self, +## text=`el.atomicNumber`).grid(column=1, +## row=n, +## sticky=W, +## padx=10) +## Label(self, +## text=`el.atomicWeight`).grid(column=2, +## row=n, +## sticky=W, +## padx=10) +## n = n + 1 + + +# utility functions + +def getSpecies(splist=[],selected=[]): + master = Toplevel() + master.title('Species') + t = SpeciesFrame(master,splist,selected) + if splist: t.selectSpecies(splist) + t.pack() + t.focus_set() + t.grab_set() + t.wait_window() + try: + master.destroy() + except TclError: + pass + return t.selected + + +# display table of selected element properties in a window +def showElementProperties(ellist): + m = Tk() + m.title('Element Properties') + elem = [] + ElementPropertyFrame(m, ellist).pack() + + +if __name__ == "__main__": + print getSpecies() + + diff --git a/apps/MixMaster/SpeciesInfo.py b/apps/MixMaster/SpeciesInfo.py new file mode 100644 index 000000000..6ef899447 --- /dev/null +++ b/apps/MixMaster/SpeciesInfo.py @@ -0,0 +1,245 @@ +from Tkinter import * +import re, math +from Cantera import * +from Units import temperature, specificEnergy, specificEntropy +from UnitChooser import UnitVar +from GraphFrame import Graph + +def testit(): + pass + +class SpeciesInfo(Label): + def __init__(self,master,phase=None,species=None,**opt): + Label.__init__(self,master,opt) + self.sp = species + self.phase = phase + self.bind('', self.show) + self.bind('', self.show) + self.bind('', self.highlight) + self.bind('', self.nohighlight) + + + def highlight(self, event=None): + self.config(fg='yellow') + + def nohighlight(self, event=None): + self.config(fg='darkblue') + + def show(self, event): + self.new=Toplevel() + self.new.title(self.sp.symbol) + #self.new.transient(self.master) + self.new.bind("", self.update,"+") + self.cpr = 0.0 + self.t = 0.0 + self.cpl = 0.0 + self.tl = 0.0 + self.cpp = [[(0.0, 0.0, 'red')]] + + # elemental composition + self.eframe = Frame(self.new) + self.eframe.config(relief=GROOVE,bd=4) + self.eframe.grid(row=0,column=0,columnspan=10,sticky=E+W) + r = 1 + Label(self.eframe,text='Atoms:')\ + .grid(row=0,column=0,sticky=N+W) + for el, c in self.sp.composition(): + Label(self.eframe,text=`int(c)`+' '+el).grid(row=0,column=r) + r = r + 1 + + + # thermodynamic properties + self.thermo = Frame(self.new) + self.thermo.config(relief=GROOVE,bd=4) + self.thermo.grid(row=1,column=0,columnspan=10,sticky=N+E+W) + Label(self.thermo,text = 'Standard Heat of Formation at 298 K: ').grid(row=0, column=0, sticky=W) + Label(self.thermo,text = '%8.2f kJ/mol' % (self.sp.hf0*1.0e-6)).grid(row=0, column=1, sticky=W) + Label(self.thermo,text = 'Molar Mass: ').grid(row=1, column=0, sticky=W) + Label(self.thermo,text = self.sp.molecularWeight).grid(row=1, column=1, sticky=W) + labels = ['Temperature', 'c_p', 'Enthalpy', 'Entropy'] + units = [temperature, specificEntropy, specificEnergy, specificEntropy] + whichone = [0, 1, 1, 1] + + r = 2 + self.prop = [] + for prop in labels: + Label(self.thermo,text=prop).grid(row=r,column=0,sticky=W) + p = UnitVar(self.thermo,units[r-2],whichone[r-2]) + p.grid(row=r,column=1,sticky=W) + p.v.config(state=DISABLED,bg='lightgray') + self.prop.append(p) + r = r + 1 + + tmin = self.sp.minTemp + tmax = self.sp.maxTemp + cp = self.sp.cp_R(tmin) + hh = self.sp.enthalpy_RT(tmin) + ss = self.sp.entropy_R(tmin) + + self.prop[0].bind("", self.decouple) + self.prop[0].bind("", self.update) + self.prop[0].bind("", self.update) + self.prop[0].v.config(state=NORMAL,bg='white') + self.prop[0].set(300.0) + + self.graphs = Frame(self.new) + self.graphs.config(relief=GROOVE,bd=4) + self.graphs.grid(row=2,column=0,columnspan=10,sticky=E+W) + + self.cpdata = [] + self.hdata = [] + self.sdata = [] + t = tmin + n = int((tmax - tmin)/100.0) + while t <= tmax: + self.cpdata.append((t,self.sp.cp_R(t))) + self.hdata.append((t,self.sp.enthalpy_RT(t))) + self.sdata.append((t,self.sp.entropy_R(t))) + t = t + n + + # specific heat + + Label(self.graphs,text='c_p/R').grid(row=0,column=0,sticky=W+E) + ymin, ymax, dtick = self.plotLimits(self.cpdata) + self.cpg = Graph(self.graphs,'',tmin,tmax,ymin,ymax, + pixelX=150,pixelY=150) + self.cpg.canvas.config(bg='white') + self.cpg.grid(row=1,column=0,columnspan=2,sticky=W+E) + self.ticks(ymin, ymax, dtick, tmin, tmax, self.cpg) + + # enthalpy + Label(self.graphs,text='enthalpy/RT').grid(row=0,column=3,sticky=W+E) + ymin, ymax, dtick = self.plotLimits(self.hdata) + self.hg = Graph(self.graphs,'',tmin,tmax,ymin,ymax, + pixelX=150,pixelY=150) + self.hg.canvas.config(bg='white') + self.hg.grid(row=1,column=3,columnspan=2,sticky=W+E) + self.ticks(ymin, ymax, dtick, tmin, tmax, self.hg) + + # entropy + Label(self.graphs,text='entropy/R').grid(row=0,column=5,sticky=W+E) + ymin, ymax, dtick = self.plotLimits(self.sdata) + self.sg = Graph(self.graphs,'',tmin,tmax,ymin,ymax, + pixelX=150,pixelY=150) + self.sg.canvas.config(bg='white') + self.sg.grid(row=1,column=5,columnspan=2,sticky=W+E) + self.ticks(ymin, ymax, dtick, tmin, tmax, self.sg) + + n = int((tmax - tmin)/100.0) + t = tmin + self.cpp = [] + + for t, cp in self.cpdata: + self.cpg.join([(t,cp,'red')]) + for t, h in self.hdata: + self.hg.join([(t,h,'green')]) + for t, s in self.sdata: + self.sg.join([(t,s,'blue')]) + + self.cpdot = self.cpg.plot(tmin,cp,'red') + self.hdot = self.hg.plot(tmin,hh,'green') + self.sdot = self.sg.plot(tmin,ss,'blue') + + b=Button(self.new,text=' OK ',command=self.finished, default=ACTIVE) + #ed=Button(self.new,text='Edit',command=testit) + b.grid(column=0, row=4,sticky=W) + #ed.grid(column=1,row=4,sticky=W) + + self.scfr = Frame(self.new) + self.scfr.config(relief=GROOVE,bd=4) + self.scfr.grid(row=3,column=0,columnspan=10,sticky=N+E+W) + self.sc = Scale(self.scfr,command=self.update,variable = self.prop[0].x, + orient='horizontal',digits=7,length=400) + self.sc.config(cnf={'from':tmin,'to':tmax}) + self.sc.bind('',self.couple) + self.scfr.bind('',self.decouple) + self.sc.grid(row=0,column=0,columnspan=10) + + def decouple(self,event=None): + d = DoubleVar() + xx = self.prop[0].get() + d.set(xx) + self.sc.config(variable = d) + + def couple(self,event=None): + self.sc.config(variable = self.prop[0].x) + #self.update() + + def update(self,event=None): + try: + tmp = self.prop[0].get() + cnd = self.sp.cp_R(tmp) + cc = cnd*GasConstant + self.prop[1].set(cc) + hnd = self.sp.enthalpy_RT(tmp) + hh = hnd*tmp*GasConstant + self.prop[2].set(hh) + snd = self.sp.entropy_R(tmp) + ss = snd*tmp*GasConstant + self.prop[3].set(ss) + + + self.cppoint = tmp, cnd + self.hpoint = tmp, hnd + self.spoint = tmp, snd + if hasattr(self, 'cpdot'): + self.cpg.delete(self.cpdot) + self.cpdot = self.cpg.plot(self.cppoint[0], self.cppoint[1],'red') + self.hg.delete(self.hdot) + self.hdot = self.hg.plot(self.hpoint[0], self.hpoint[1],'green') + self.sg.delete(self.sdot) + self.sdot = self.sg.plot(self.spoint[0], self.spoint[1],'blue') + except: + pass + + def plotLimits(self, xy): + ymax = -1.e10 + ymin = 1.e10 + for x, y in xy: + if y > ymax: ymax = y + if y < ymin: ymin = y + + dy = abs(ymax - ymin) + if dy < 0.2*ymin: + ymin = ymin*.9 + ymax = ymax*1.1 + dy = abs(ymax - ymin) + else: + ymin = ymin - 0.1*dy + ymax = ymax + 0.1*dy + dy = abs(ymax - ymin) + + p10 = math.floor(math.log10(0.1*dy)) + fctr = math.pow(10.0, p10) + mm = [2.0, 2.5, 2.0] + i = 0 + while dy/fctr > 5: + fctr = mm[i % 3]*fctr + i = i + 1 + ymin = fctr*math.floor(ymin/fctr) + ymax = fctr*(math.floor(ymax/fctr + 1)) + return (ymin, ymax, fctr) + + def ticks(self, ymin, ymax, dtick, tmin, tmax, plot): + ytick = ymin + eps = 1.e-3 + while ytick <= ymax: + if abs(ytick) < eps: + plot.join([(tmin, ytick, 'gray')]) + plot.join([(tmax, ytick, 'gray')]) + plot.last_points = [] + else: + plot.join([(tmin, ytick, 'gray')]) + plot.join([(tmin + 0.05*(tmax - tmin), ytick, 'gray')]) + plot.last_points = [] + plot.join([(2.0*tmax, ytick, 'gray')]) + plot.join([(tmax - 0.05*(tmax - tmin), ytick, 'gray')]) + plot.last_points = [] + + ytick = ytick + dtick + + def finished(self,event=None): + self.new.destroy() + + + diff --git a/apps/MixMaster/ThermoFrame.py b/apps/MixMaster/ThermoFrame.py new file mode 100644 index 000000000..11f9ff1a9 --- /dev/null +++ b/apps/MixMaster/ThermoFrame.py @@ -0,0 +1,139 @@ + + +from Cantera import * +from Tkinter import * + +from Units import temperature, pressure, density, specificEnergy, specificEntropy +from UnitChooser import UnitVar +from ThermoProp import ThermoProp +from utilities import handleError + +_PRESSURE = 1 +_TEMPERATURE = 0 +_DENSITY = 2 +_INTENERGY = 3 +_ENTHALPY = 4 +_ENTROPY = 5 + +class ThermoFrame(Frame): + def __init__(self,master,top): + Frame.__init__(self,master) + self.config(relief=GROOVE, bd=4) + self.top = top + self.mix = self.top.mix + self.internal = Frame(self) + self.internal.pack(side=LEFT,anchor=N+W,padx=2,pady=2) + self.controls=Frame(self.internal) + self.controls.pack(side=LEFT,anchor=N+W,padx=4,pady=5) + + self.entries=Frame(self.internal) + self.entries.pack(side=LEFT,anchor=N,padx=4,pady=2) + self.makeEntries() + self.makeControls() + self.showState() + + def makeControls(self): + Button(self.controls,text='Set State', width=15, + command=self.setState).grid(column=0,row=0) + self.equil = IntVar() + self.equil.set(0) + Button(self.controls,text='Equilibrate', width=15, + command=self.eqset).grid(column=0,row=1) +## Radiobutton(self.controls,text='Frozen',variable = self.equil, +## command=self.freeze,value=0).grid(column=0,row=2,sticky='W') +## Radiobutton(self.controls,text='Equilibrium', +## variable=self.equil, +## command=self.eqset,value=1).grid(column=0,row=3,sticky='W') + + def eqset(self): + self.equil.set(1) + self.setState() + self.equil.set(0) + #if self.top.mixframe: + # self.top.mixframe.redo() + + def freeze(self): + self.equil.set(0) + if self.top.mixframe: + self.top.mixframe.redo() + + def makeEntries(self): + self.entries.pack() + self.variable = {} + self.prop = [] + props = ['Temperature', 'Pressure', 'Density', + 'Internal Energy', 'Enthalpy', 'Entropy'] + units = [temperature, pressure, density, specificEnergy, + specificEnergy, specificEntropy] + defaultunit = [0, 2, 0, 1, 1, 1] + for i in range(len(props)): + self.prop.append(ThermoProp(self.entries, self, i, props[i], + 0.0, units[i], defaultunit[i])) + self.prop[-1].entry.bind("",self.setState) + self.last2 = self.prop[2] + self.last1 = self.prop[3] + self.prop[0].checked.set(1) + self.prop[0].check() + self.prop[1].checked.set(1) + self.prop[1].check() + self.showState() + + def checkTPBoxes(self): + if not self.prop[0].isChecked(): + self.prop[0].checked.set(1) + self.prop[0].check() + if not self.prop[1].isChecked(): + self.prop[1].checked.set(1) + self.prop[1].check() + + def showState(self): + self.prop[_TEMPERATURE].set(self.mix.g.temperature()) + self.prop[_PRESSURE].set(self.mix.g.pressure()) + self.prop[_DENSITY].set(self.mix.g.density()) + self.prop[_INTENERGY].set(self.mix.g.intEnergy_mass()) + self.prop[_ENTHALPY].set(self.mix.g.enthalpy_mass()) + self.prop[_ENTROPY].set(self.mix.g.entropy_mass()) + + def setState(self,event=None): + self.top.mixfr.update() + i = self.equil.get() + optlist = ['frozen','equilibrium'] + opt = [optlist[i]] + + if self.prop[_PRESSURE].isChecked() \ + and self.prop[_TEMPERATURE].isChecked(): + self.mix.set( + temperature = self.prop[_TEMPERATURE].get(), + pressure = self.prop[_PRESSURE].get(), + equil=i) + + elif self.prop[_DENSITY].isChecked() \ + and self.prop[_TEMPERATURE].isChecked(): + self.mix.set( + temperature = self.prop[_TEMPERATURE].get(), + density = self.prop[_DENSITY].get(), + equil=i) + + elif self.prop[_ENTROPY].isChecked() \ + and self.prop[_PRESSURE].isChecked(): + self.mix.set(pressure = self.prop[_PRESSURE].get(), + entropy = self.prop[_ENTROPY].get(), + equil=i) + + elif self.prop[_ENTHALPY].isChecked() \ + and self.prop[_PRESSURE].isChecked(): + self.mix.set(pressure = self.prop[_PRESSURE].get(), + enthalpy = self.prop[_ENTHALPY].get(), + equil=i) + + elif self.prop[_INTENERGY].isChecked() \ + and self.prop[_DENSITY].isChecked(): + self.mix.set(density = self.prop[_DENSITY].get(), + intEnergy = self.prop[_INTENERGY].get()) + else: + handleError("unsupported property pair") + + self.top.update() + + + diff --git a/apps/MixMaster/ThermoProp.py b/apps/MixMaster/ThermoProp.py new file mode 100644 index 000000000..8c81beab1 --- /dev/null +++ b/apps/MixMaster/ThermoProp.py @@ -0,0 +1,44 @@ +from Tkinter import * +from UnitChooser import UnitVar + +class ThermoProp: + def __init__(self, master, thermoframe, row, name, value, units, defaultunit=0): + self.value = DoubleVar() + self.thermoframe = thermoframe + self.entry = UnitVar(master,units,defaultunit) + self.entry.grid(column=1,row=row,sticky=W) + self.entry.v.config(state=DISABLED,bg='lightgray') + self.checked=IntVar() + self.checked.set(0) + self.c=Checkbutton(master, + text=name, + variable=self.checked, + onvalue=1, + offvalue=0, + command=self.check + ) + self.c.grid(column=0,row=row, sticky=W+N) + + def check(self): + self._check() + self.thermoframe.last2.checked.set(0) + self.thermoframe.last2._check() + self.thermoframe.last2 = self.thermoframe.last1 + self.thermoframe.last1 = self + + def _check(self): + if self.isChecked(): + self.entry.v.config(state=NORMAL,bg='white') + else: + self.entry.v.config(state=DISABLED,bg='lightgray') + + def isChecked(self): + return self.checked.get() + + def set(self, value): + self.entry.set(value) + + def get(self): + return self.entry.get() + + diff --git a/apps/MixMaster/TransportFrame.py b/apps/MixMaster/TransportFrame.py new file mode 100644 index 000000000..e3ecdb0b8 --- /dev/null +++ b/apps/MixMaster/TransportFrame.py @@ -0,0 +1,35 @@ +from Tkinter import * + +class TransportFrame(Frame): + def show(self, i, frame, row, col): + if self.checked[i].get(): + frame.grid(row=row,column=col,sticky=N+E+S+W) + else: + frame.grid_forget() + + def showcomp(self): + self.show(0, self.top.mixfr, 8, 0) + + def showthermo(self): + self.show(1, self.top.thermo, 7, 0) + + def __init__(self,master,top): + self.top = top + self.c = [] + self.checked = [] + Frame.__init__(self,master) + self.config(relief=GROOVE, bd=4) + lbl = ['multicomponent', 'mixture-averaged'] + cmds = [self.showcomp, self.showthermo] + for i in range(2): + self.checked.append(IntVar()) + self.checked[i].set(0) + self.c.append(Checkbutton(self, + text=lbl[i], + variable=self.checked[i], + onvalue=1, + offvalue=0, + command=cmds[i] + )) + self.c[i].grid(column=i,row=0, sticky=W+N) + diff --git a/apps/MixMaster/UnitChooser.py b/apps/MixMaster/UnitChooser.py new file mode 100644 index 000000000..290787393 --- /dev/null +++ b/apps/MixMaster/UnitChooser.py @@ -0,0 +1,84 @@ +from Tkinter import * +import re + +class UnitVar(Frame): + def __init__(self,master,unitmod,defaultunit=0): + Frame.__init__(self,master) + self.x = DoubleVar() + self.xsi = 0.0 + self.x.set(0.0) + self.unitmod = unitmod + try: + self.unitlist = self.unitmod.units + except: + self.unitlist = [] + unitlist=dir(self.unitmod) + for it in unitlist: + if it[0] != '_': + self.unitlist.append(it) + self.v = Entry(self,textvariable=self.x) + self.s = StringVar() + tmp = re.sub('__',' / ',self.unitlist[defaultunit]) + self.s.set(tmp) + self.conv = eval('self.unitmod.'+re.sub(' / ','__',self.s.get())).value + self.u = Label(self) + self.u.config(textvariable=self.s,fg='darkblue') + self.u.bind('', self.select) + self.u.bind('',self.highlight) + self.u.bind('',self.nohighlight) + self.v.grid(row=0,column=0) + self.u.grid(row=0,column=1) + + def highlight(self, event=None): + self.u.config(fg='yellow') + + def nohighlight(self, event=None): + self.u.config(fg='darkblue') + + def select(self, event): + self.new=Toplevel() + self.new.title("Units") + self.new.transient(self.master) + self.new.bind("", self.finished,"+") + + r=0 + c=0 + for each in self.unitlist: + if each[0] != '_' and each[:1] != '__' and each != 'SI': + each = re.sub('__',' / ',each) + Radiobutton(self.new, + text=each, + variable=self.u['textvariable'], + value=each, + command=self.update, + ).grid(column=c, row=r, sticky=W) + r=r+1 + if (r>10): + r=0 + c=c+1 + r=r+1 + + b=Button(self.new,text='OK',command=self.finished, default=ACTIVE) + b.grid(column=c, row=r) + + self.new.grab_set() + self.new.focus_set() + self.new.wait_window() + + def finished(self,event=None): + self.new.destroy() + + def update(self): + self.xsi = self.x.get() * self.conv + self.conv = eval('self.unitmod.'+re.sub(' / ','__',self.s.get())).value + self.x.set(self.xsi/self.conv) + + def get(self): + self.xsi = self.x.get() * self.conv + return self.xsi + + def set(self,value): + self.xsi = value + self.x.set(value/self.conv) + + diff --git a/apps/MixMaster/Units/SI.py b/apps/MixMaster/Units/SI.py new file mode 100755 index 000000000..a1eb21ac6 --- /dev/null +++ b/apps/MixMaster/Units/SI.py @@ -0,0 +1,140 @@ +#!/bin/env python +# +#-------------------------------------------------------------------------- +# +# $License$ +# +#-------------------------------------------------------------------------- + +# $Log$ +# Revision 1.1 2003-04-14 17:57:49 dggoodwin +# Initial revision +# +# Revision 1.1 2002/12/20 13:23:41 dgg +# first commit +# +# Revision 1.1.1.1 2000/01/21 22:59:51 dgg +# dgg Cantera +# +# Revision 1.1 1999/11/27 17:27:35 dgg +# initial import to Cantera repository +# +# Revision 1.1 1999/11/25 19:50:58 aivazis +# Original source +# + +from unit import unit, dimensionless + +# +# The basic SI units +# +meter = unit(1.0, (1, 0, 0, 0, 0, 0, 0)) +kilogram = unit(1.0, (0, 1, 0, 0, 0, 0, 0)) +second = unit(1.0, (0, 0, 1, 0, 0, 0, 0)) +ampere = unit(1.0, (0, 0, 0, 1, 0, 0, 0)) +kelvin = unit(1.0, (0, 0, 0, 0, 1, 0, 0)) +mole = unit(1.0, (0, 0, 0, 0, 0, 1, 0)) +candela = unit(1.0, (0, 0, 0, 0, 0, 0, 1)) + +# +# The 21 derived SI units with special names +# +radian = dimensionless # plane angle +steradian = dimensionless # solid angle + +hertz = 1/second # frequency + +newton = meter*kilogram/second**2 # force +pascal = newton/meter**2 # pressure +joule = newton*meter # work, heat +watt = joule/second # power, radiant flux + +coulomb = ampere*second # electric charge +volt = watt/ampere # electric potential difference +farad = coulomb/volt # capacitance +ohm = volt/ampere # electric resistance +siemens = ampere/volt # electric conductance +weber = volt*second # magnetic flux +tesla = weber/meter**2 # magnetic flux density +henry = weber/ampere # inductance + +celsius = kelvin # Celsius temperature + +lumen = candela*steradian # luminous flux +lux = lumen/meter**2 # illuminance + +becquerel = 1/second # radioactivity +gray = joule/kilogram # absorbed dose +sievert = joule/kilogram # dose equivalent + +# +# The prefixes +# + +yotta = 1e24 +zetta = 1e21 +exa = 1e18 +peta = 1e15 +tera = 1e12 +giga = 1e9 +mega = 1e6 +kilo = 1000 +hecto = 100 +deka = 10 +deci = .1 +centi = .01 +milli = .001 +micro = 1e-6 +nano = 1e-9 +pico = 1e-12 +femto = 1e-15 +atto = 1e-18 +zepto = 1e-21 +yocto = 1e-24 + + +# +# Test +# + +if __name__ == "__main__": + + print "The 7 base SI units:" + print " meter: %s" % meter + print " kilogram: %s" % kilogram + print " second: %s" % second + print " ampere: %s" % ampere + print " kelvin: %s" % kelvin + print " mole: %s" % mole + print " candela: %s" % candela + print + print "The 21 SI derived units with special names:" + print " radian: %s" % radian + print " steradian: %s" % steradian + print " hertz: %s" % hertz + + print " newton: %s" % newton + print " pascal: %s" % pascal + print " joule: %s" % joule + print " watt: %s" % watt + + print " coulomb: %s" % coulomb + print " volt: %s" % volt + print " farad: %s" % farad + print " ohm: %s" % ohm + print " siemens: %s" % siemens + print " weber: %s" % weber + print " tesla: %s" % tesla + print " henry: %s" % henry + + print " degree Celcius: %s" % celcius + + print " lumen: %s" % lumen + print " lux: %s" % lux + + print " becquerel: %s" % becquerel + print " gray: %s" % gray + print " sievert: %s" % sievert + +# +# End of file diff --git a/apps/MixMaster/Units/__init__.py b/apps/MixMaster/Units/__init__.py new file mode 100755 index 000000000..c95dcb43e --- /dev/null +++ b/apps/MixMaster/Units/__init__.py @@ -0,0 +1,27 @@ +#!/bin/env python +# +#-------------------------------------------------------------------------- +# +# $License$ +# +#-------------------------------------------------------------------------- + +# $Log$ +# Revision 1.1 2003-04-14 17:57:49 dggoodwin +# Initial revision +# +# Revision 1.1 2002/12/20 13:23:41 dgg +# first commit +# +# Revision 1.1.1.1 2000/01/21 22:59:51 dgg +# dgg Cantera +# +# Revision 1.1 1999/11/27 17:27:35 dgg +# initial import to Cantera repository +# +# Revision 1.1 1999/11/25 19:50:58 aivazis +# Original source +# + +# +# End of file diff --git a/apps/MixMaster/Units/area.py b/apps/MixMaster/Units/area.py new file mode 100755 index 000000000..0679c5ff0 --- /dev/null +++ b/apps/MixMaster/Units/area.py @@ -0,0 +1,46 @@ +#!/bin/env python +# +#-------------------------------------------------------------------------- +# +# $License$ +# +#-------------------------------------------------------------------------- + +# $Log$ +# Revision 1.1 2003-04-14 17:57:49 dggoodwin +# Initial revision +# +# Revision 1.1 2002/12/20 13:23:41 dgg +# first commit +# +# Revision 1.1.1.1 2000/01/21 22:59:51 dgg +# dgg Cantera +# +# Revision 1.1 1999/11/27 17:27:35 dgg +# initial import to Cantera repository +# +# Revision 1.1 1999/11/25 19:50:58 aivazis +# Original source +# + +from length import meter, centimeter, inch, foot, mile + +# +# Definitions of common area units +# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics", +# fourth edition, John Willey and Sons, 1993 + +square_meter = meter**2 +square_centimeter = centimeter**2 + +square_foot = foot**2 +square_inch = inch**2 +square_mile = mile**2 + +acre = 43560 * square_foot +hectare = 1000 * square_meter + +barn = 1e-28 * square_meter + +# +# End of file diff --git a/apps/MixMaster/Units/density.py b/apps/MixMaster/Units/density.py new file mode 100755 index 000000000..42f5b7846 --- /dev/null +++ b/apps/MixMaster/Units/density.py @@ -0,0 +1,38 @@ +#!/bin/env python +# +#-------------------------------------------------------------------------- +# +# $License$ +# +#-------------------------------------------------------------------------- + +# $Log$ +# Revision 1.1 2003-04-14 17:57:49 dggoodwin +# Initial revision +# +# Revision 1.1 2002/12/20 13:23:41 dgg +# first commit +# +# Revision 1.1.1.1 2000/01/21 22:59:51 dgg +# dgg Cantera +# +# Revision 1.1 1999/11/27 17:27:35 dgg +# initial import to Cantera repository +# +# Revision 1.1 1999/11/25 19:50:58 aivazis +# Original source +# + +import SI, math + +# +# Definitions of common density units +# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics", +# fourth edition, John Willey and Sons, 1993 +units = ['kg__m3', 'g__m3', 'g__cm3'] + +kg__m3 = SI.kilogram/(SI.meter * SI.meter * SI.meter) +g__m3 = 1.e-3*kg__m3 +g__cm3 = 1.e3*kg__m3 +# +# End of file diff --git a/apps/MixMaster/Units/energy.py b/apps/MixMaster/Units/energy.py new file mode 100755 index 000000000..c454b2b09 --- /dev/null +++ b/apps/MixMaster/Units/energy.py @@ -0,0 +1,46 @@ +#!/bin/env python +# +#-------------------------------------------------------------------------- +# +# $License$ +# +#-------------------------------------------------------------------------- + +# $Log$ +# Revision 1.1 2003-04-14 17:57:49 dggoodwin +# Initial revision +# +# Revision 1.1 2002/12/20 13:23:41 dgg +# first commit +# +# Revision 1.1.1.1 2000/01/21 22:59:51 dgg +# dgg Cantera +# +# Revision 1.1 1999/11/27 17:27:35 dgg +# initial import to Cantera repository +# +# Revision 1.1 1999/11/25 19:50:58 aivazis +# Original source +# + +from SI import joule + +# +# Definitions of common energy units +# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics", +# fourth edition, John Willey and Sons, 1993 + + +Btu = 1055 * joule +erg = 1e-7 * joule +foot_pound = 1.356 * joule +horse_power_hour = 2.685e6 * joule + +calorie = 4.186 * joule +Calorie = 1000 * calorie +kilowatt_hour = 3.6e6 * joule + +electron_volt = 1.602e-19 * joule + +# +# End of file diff --git a/apps/MixMaster/Units/force.py b/apps/MixMaster/Units/force.py new file mode 100755 index 000000000..7cb048006 --- /dev/null +++ b/apps/MixMaster/Units/force.py @@ -0,0 +1,35 @@ +#!/bin/env python +# +#-------------------------------------------------------------------------- +# +# $License$ +# +#-------------------------------------------------------------------------- + +# $Log$ +# Revision 1.1 2003-04-14 17:57:49 dggoodwin +# Initial revision +# +# Revision 1.1 2002/12/20 13:23:41 dgg +# first commit +# +# Revision 1.1.1.1 2000/01/21 22:59:51 dgg +# dgg Cantera +# +# Revision 1.1 1999/11/27 17:27:35 dgg +# initial import to Cantera repository +# +# Revision 1.1 1999/11/25 19:50:58 aivazis +# Original source +# + +from SI import meter + +# +# Definitions of common force units +# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics", +# fourth edition, John Willey and Sons, 1993 + + +# +# End of file diff --git a/apps/MixMaster/Units/length.py b/apps/MixMaster/Units/length.py new file mode 100755 index 000000000..0c5964b79 --- /dev/null +++ b/apps/MixMaster/Units/length.py @@ -0,0 +1,54 @@ +#!/bin/env python +# +#-------------------------------------------------------------------------- +# +# $License$ +# +#-------------------------------------------------------------------------- + +# $Log$ +# Revision 1.1 2003-04-14 17:57:49 dggoodwin +# Initial revision +# +# Revision 1.1 2002/12/20 13:23:41 dgg +# first commit +# +# Revision 1.1.1.1 2000/01/21 22:59:51 dgg +# dgg Cantera +# +# Revision 1.1 1999/11/27 17:27:35 dgg +# initial import to Cantera repository +# +# Revision 1.1 1999/11/25 19:50:58 aivazis +# Original source +# + +from SI import meter +from SI import nano, milli, centi, kilo + +# +# Definitions of common length units +# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics", +# fourth edition, John Willey and Sons, 1993 + + +nanometer = nano * meter +millimeter = milli * meter +centimeter = centi * meter +kilometer = kilo * meter + +inch = 2.540 * centimeter +foot = 12 * inch +yard = 3 * foot +mile = 5280 * foot + +fathom = 6 * foot +nautical_mile = 6076 * foot + +angstrom = 1e-10 * meter +fermi = 1e-15 * meter +light_year = 9.460e12 * kilometer +parsec = 3.084e13 * kilometer + +# +# End of file diff --git a/apps/MixMaster/Units/mass.py b/apps/MixMaster/Units/mass.py new file mode 100755 index 000000000..697c9c191 --- /dev/null +++ b/apps/MixMaster/Units/mass.py @@ -0,0 +1,42 @@ +#!/bin/env python +# +#-------------------------------------------------------------------------- +# +# $License$ +# +#-------------------------------------------------------------------------- + +# $Log$ +# Revision 1.1 2003-04-14 17:57:49 dggoodwin +# Initial revision +# +# Revision 1.1 2002/12/20 13:23:41 dgg +# first commit +# +# Revision 1.1.1.1 2000/01/21 22:59:51 dgg +# dgg Cantera +# +# Revision 1.1 1999/11/27 17:27:35 dgg +# initial import to Cantera repository +# +# Revision 1.1 1999/11/25 19:50:58 aivazis +# Original source +# + +from SI import kilogram + +# +# Definitions of common mass units +# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics", +# fourth edition, John Willey and Sons, 1993 + +gram = 1e-3 * kilogram + +metric_ton = 1000 * kilogram + +ounce = 28.35 * gram +pound = 16 * ounce +ton = 2000 * pound + +# +# End of file diff --git a/apps/MixMaster/Units/power.py b/apps/MixMaster/Units/power.py new file mode 100755 index 000000000..288b8f044 --- /dev/null +++ b/apps/MixMaster/Units/power.py @@ -0,0 +1,37 @@ +#!/bin/env python +# +#-------------------------------------------------------------------------- +# +# $License$ +# +#-------------------------------------------------------------------------- + +# $Log$ +# Revision 1.1 2003-04-14 17:57:49 dggoodwin +# Initial revision +# +# Revision 1.1 2002/12/20 13:23:41 dgg +# first commit +# +# Revision 1.1.1.1 2000/01/21 22:59:51 dgg +# dgg Cantera +# +# Revision 1.1 1999/11/27 17:27:35 dgg +# initial import to Cantera repository +# +# Revision 1.1 1999/11/25 19:50:58 aivazis +# Original source +# + +from SI import watt, kilo + +# +# Definitions of common power units +# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics", +# fourth edition, John Willey and Sons, 1993 + +kilowatt = kilo * watt +horsepower = 745.7 * watt + +# +# End of file diff --git a/apps/MixMaster/Units/pressure.py b/apps/MixMaster/Units/pressure.py new file mode 100755 index 000000000..fb4d48e83 --- /dev/null +++ b/apps/MixMaster/Units/pressure.py @@ -0,0 +1,41 @@ +#!/bin/env python +# +#-------------------------------------------------------------------------- +# +# $License$ +# +#-------------------------------------------------------------------------- + +# $Log$ +# Revision 1.1 2003-04-14 17:57:49 dggoodwin +# Initial revision +# +# Revision 1.1 2002/12/20 13:23:41 dgg +# first commit +# +# Revision 1.1.1.1 2000/01/21 22:59:51 dgg +# dgg Cantera +# +# Revision 1.1 1999/11/27 17:27:35 dgg +# initial import to Cantera repository +# +# Revision 1.1 1999/11/25 19:50:58 aivazis +# Original source +# + +import SI + +# +# Definitions of common pressure units +# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics", +# fourth edition, John Willey and Sons, 1993 + + +bar = 1e5 * SI.pascal +mbar = 100 * SI.pascal +Pa = SI.pascal +torr = 133.3 * SI.pascal +atm = 1.01325e5 * SI.pascal + +# +# End of file diff --git a/apps/MixMaster/Units/specificEnergy.py b/apps/MixMaster/Units/specificEnergy.py new file mode 100755 index 000000000..0ed66f8a9 --- /dev/null +++ b/apps/MixMaster/Units/specificEnergy.py @@ -0,0 +1,41 @@ +#!/bin/env python +# +#-------------------------------------------------------------------------- +# +# $License$ +# +#-------------------------------------------------------------------------- + +# $Log$ +# Revision 1.1 2003-04-14 17:57:49 dggoodwin +# Initial revision +# +# Revision 1.1 2002/12/20 13:23:41 dgg +# first commit +# +# Revision 1.1.1.1 2000/01/21 22:59:51 dgg +# dgg Cantera +# +# Revision 1.1 1999/11/27 17:27:35 dgg +# initial import to Cantera repository +# +# Revision 1.1 1999/11/25 19:50:58 aivazis +# Original source +# + +import SI, energy, mass + +# +# Definitions of common energy units +# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics", +# fourth edition, John Willey and Sons, 1993 +units = ['J__kg', 'kJ__kg', 'Btu__lbm', 'cal__g', 'kcal__g', 'kcal__kg'] + +J__kg = SI.joule/SI.kilogram +kJ__kg = 1000.0*J__kg +Btu__lbm = energy.Btu/mass.pound +cal__g = energy.calorie/mass.gram +kcal__g = 1000.0*cal__g +kcal__kg = cal__g +# +# End of file diff --git a/apps/MixMaster/Units/specificEntropy.py b/apps/MixMaster/Units/specificEntropy.py new file mode 100755 index 000000000..8e50f44d3 --- /dev/null +++ b/apps/MixMaster/Units/specificEntropy.py @@ -0,0 +1,35 @@ +#!/bin/env python +# +#-------------------------------------------------------------------------- +# +# $License$ +# +#-------------------------------------------------------------------------- + +# $Log$ +# Revision 1.1 2003-04-14 17:57:49 dggoodwin +# Initial revision +# +# Revision 1.1 2002/12/20 13:23:41 dgg +# first commit +# +# Revision 1.1.1.1 2000/01/21 22:59:51 dgg +# dgg Cantera +# +# Revision 1.1 1999/11/27 17:27:35 dgg +# initial import to Cantera repository +# +# Revision 1.1 1999/11/25 19:50:58 aivazis +# Original source +# + +import SI, energy, mass + +units = ['J__kg_K', 'kJ__kg_K', 'cal__g_K'] + +J__kg_K = SI.joule/(SI.kilogram * SI.kelvin) +kJ__kg_K = 1000.0*J__kg_K +cal__g_K = energy.calorie/(mass.gram * SI.kelvin) + +# +# End of file diff --git a/apps/MixMaster/Units/speed.py b/apps/MixMaster/Units/speed.py new file mode 100755 index 000000000..f4f1578cc --- /dev/null +++ b/apps/MixMaster/Units/speed.py @@ -0,0 +1,38 @@ +#!/bin/env python +# +#-------------------------------------------------------------------------- +# +# $License$ +# +#-------------------------------------------------------------------------- + +# $Log$ +# Revision 1.1 2003-04-14 17:57:49 dggoodwin +# Initial revision +# +# Revision 1.1 2002/12/20 13:23:41 dgg +# first commit +# +# Revision 1.1.1.1 2000/01/21 22:59:51 dgg +# dgg Cantera +# +# Revision 1.1 1999/11/27 17:27:35 dgg +# initial import to Cantera repository +# +# Revision 1.1 1999/11/25 19:50:58 aivazis +# Original source +# + +from time import hour +from length import nautical_mile + +# +# Definitions of common speed units +# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics", +# fourth edition, John Willey and Sons, 1993 + + +knot = nautical_mile/hour + +# +# End of file diff --git a/apps/MixMaster/Units/temperature.py b/apps/MixMaster/Units/temperature.py new file mode 100755 index 000000000..652654d6e --- /dev/null +++ b/apps/MixMaster/Units/temperature.py @@ -0,0 +1,32 @@ +#!/bin/env python +# +#-------------------------------------------------------------------------- +# +# $License$ +# +#-------------------------------------------------------------------------- + +# $Log$ +# Revision 1.1 2003-04-14 17:57:49 dggoodwin +# Initial revision +# +# Revision 1.1 2002/12/20 13:23:41 dgg +# first commit +# +# Revision 1.1.1.1 2000/01/21 22:59:51 dgg +# dgg Cantera +# +# Revision 1.1 1999/11/27 17:27:35 dgg +# initial import to Cantera repository +# +# Revision 1.1 1999/11/25 19:50:58 aivazis +# Original source +# + +import SI + +K = SI.kelvin +R = (9.0/5.0)*K + +# +# End of file diff --git a/apps/MixMaster/Units/time.py b/apps/MixMaster/Units/time.py new file mode 100755 index 000000000..c55d570b1 --- /dev/null +++ b/apps/MixMaster/Units/time.py @@ -0,0 +1,39 @@ +#!/bin/env python +# +#-------------------------------------------------------------------------- +# +# $License$ +# +#-------------------------------------------------------------------------- + +# $Log$ +# Revision 1.1 2003-04-14 17:57:49 dggoodwin +# Initial revision +# +# Revision 1.1 2002/12/20 13:23:41 dgg +# first commit +# +# Revision 1.1.1.1 2000/01/21 22:59:51 dgg +# dgg Cantera +# +# Revision 1.1 1999/11/27 17:27:35 dgg +# initial import to Cantera repository +# +# Revision 1.1 1999/11/25 19:50:58 aivazis +# Original source +# + +from SI import second + +# +# Definitions of common time units +# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics", +# fourth edition, John Willey and Sons, 1993 + +minute = 60 * second +hour = 60 * minute +day = 24 * hour +year = 365.25 * day + +# +# End of file diff --git a/apps/MixMaster/Units/unit.py b/apps/MixMaster/Units/unit.py new file mode 100755 index 000000000..664c74c2b --- /dev/null +++ b/apps/MixMaster/Units/unit.py @@ -0,0 +1,135 @@ +#!/bin/env python +# +#-------------------------------------------------------------------------- +# +# $License$ +# +#-------------------------------------------------------------------------- + +# $Log$ +# Revision 1.1 2003-04-14 17:57:49 dggoodwin +# Initial revision +# +# Revision 1.1 2002/12/20 13:23:41 dgg +# first commit +# +# Revision 1.1.1.1 2000/01/21 22:59:51 dgg +# dgg Cantera +# +# Revision 1.1 1999/11/27 17:27:35 dgg +# initial import to Cantera repository +# +# Revision 1.1 1999/11/25 19:50:58 aivazis +# Original source +# + +import operator + +class unit: + + _zero = (0,) * 7 + _negativeOne = (-1, ) * 7 + + _labels = ('m', 'kg', 's', 'A', 'K', 'mol', 'cd') + + + def __init__(self, value, derivation): + self.value = value + self.derivation = derivation + return + + + def __add__(self, other): + if not self.derivation == other.derivation: + raise ImcompatibleUnits(self, other) + + return unit(self.value + other.value, self.derivation) + + + def __sub__(self, other): + if not self.derivation == other.derivation: + raise ImcompatibleUnits(self, other) + + return unit(self.value - other.value, self.derivation) + + + def __mul__(self, other): + if type(other) == type(0) or type(other) == type(0.0): + return unit(other*self.value, self.derivation) + + value = self.value * other.value + derivation = tuple(map(operator.add, self.derivation, other.derivation)) + + return unit(value, derivation) + + + def __div__(self, other): + if type(other) == type(0) or type(other) == type(0.0): + return unit(self.value/other, self.derivation) + + value = self.value / other.value + derivation = tuple(map(operator.sub, self.derivation, other.derivation)) + + return unit(value, derivation) + + + def __pow__(self, other): + if type(other) != type(0) and type(other) != type(0.0): + raise BadOperation + + value = self.value ** other + derivation = tuple(map(operator.mul, [other]*7, self.derivation)) + + return unit(value, derivation) + + + def __pos__(self): return self + + + def __neg__(self): return unit(-self.value, self.derivation) + + + def __abs__(self): return unit(abs(self.value), self.derivation) + + + def __invert__(self): + value = 1./self.value + derivation = tuple(map(operator.mul, self._negativeOne, self.derivation)) + return unit(value, derivation) + + + def __rmul__(self, other): + return unit.__mul__(self, other) + + def __rdiv__(self, other): + if type(other) != type(0) and type(other) != type(0.0): + raise BadOperation(self, other) + + value = other/self.value + derivation = tuple(map(operator.mul, self._negativeOne, self.derivation)) + + return unit(value, derivation) + + + def __float__(self): + return self.value + #if self.derivation == self._zero: return self.value + #raise BadConversion(self) + + + def __str__(self): + str = "%g" % self.value + for i in range(0, 7): + exponent = self.derivation[i] + if exponent == 0: continue + if exponent == 1: + str = str + " %s" % (self._labels[i]) + else: + str = str + " %s^%d" % (self._labels[i], exponent) + + return str + +dimensionless = unit(1, unit._zero) + +# +# End of file diff --git a/apps/MixMaster/Units/volume.py b/apps/MixMaster/Units/volume.py new file mode 100755 index 000000000..3b65f8079 --- /dev/null +++ b/apps/MixMaster/Units/volume.py @@ -0,0 +1,46 @@ +#!/bin/env python +# +#-------------------------------------------------------------------------- +# +# $License$ +# +#-------------------------------------------------------------------------- + +# $Log$ +# Revision 1.1 2003-04-14 17:57:49 dggoodwin +# Initial revision +# +# Revision 1.1 2002/12/20 13:23:41 dgg +# first commit +# +# Revision 1.1.1.1 2000/01/21 22:59:51 dgg +# dgg Cantera +# +# Revision 1.1 1999/11/27 17:27:35 dgg +# initial import to Cantera repository +# +# Revision 1.1 1999/11/25 19:50:58 aivazis +# Original source +# + +from length import meter, centimeter, foot, inch + +# +# Definitions of common volume units +# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics", +# fourth edition, John Willey and Sons, 1993 + +cubic_meter = meter**3 +cubic_centimeter = centimeter**3 +cubic_foot = foot**3 +cubic_inch = inch**3 + +liter = 1000 * cubic_centimeter + +us_fluid_ounce = 231./128 * cubic_inch +us_pint = 16 * us_fluid_ounce +us_fluid_quart = 2 * us_pint +us_fluid_gallon = 4 * us_fluid_quart + +# +# End of file diff --git a/apps/MixMaster/__init__.py b/apps/MixMaster/__init__.py new file mode 100644 index 000000000..28171ea12 --- /dev/null +++ b/apps/MixMaster/__init__.py @@ -0,0 +1,5 @@ + +# from Cantera import * + +from main import MixMaster + diff --git a/apps/MixMaster/config.py b/apps/MixMaster/config.py new file mode 100644 index 000000000..9389b9eb9 --- /dev/null +++ b/apps/MixMaster/config.py @@ -0,0 +1,7 @@ + +from Cantera import * + +# thermo parametrizations +#from Cantera.Species.Thermo.NasaPolynomial import NasaPolynomial + + diff --git a/apps/MixMaster/flowpanel.py b/apps/MixMaster/flowpanel.py new file mode 100644 index 000000000..04b8dfa08 --- /dev/null +++ b/apps/MixMaster/flowpanel.py @@ -0,0 +1,56 @@ + + +# functionality imports +from Tkinter import * + +from Cantera.gui import menu, newflow + +class App: + def __init__(self, master): + + try: + self.root = master.root + except: + self.root = master + + self.frame = Frame(master) + self.frame.grid(row = 0, column = 0) + + self.makemenu(self.frame) + + self.quitbutton = Button(self.frame, text = "Quit", + command = self.frame.quit) + self.quitbutton.grid(row = 1, column = 0) + + self.newbutton = Button(self.frame, text = "New...", + command = self.notyet) + self.newbutton.grid(row = 1, column = 1) + + def notyet(self): + print 'not yet!' + + + def newflow(self): + n = newflow.NewFlowDialog(self.root) + + def makemenu(self,frame): + self.menubar = Frame(frame, relief=FLAT, bd=0) + self.menubar.grid(row = 0, column = 0) + + self.filemenu = menu.make_menu('File', self.menubar, + [('New...', self.newflow), + ('Open...', self.notyet), + ('Save As...', self.notyet), + 'separator', + ('Exit', frame.quit), + [] + ]) + + + +root = Tk() + +app = App(root) + +root.mainloop() + diff --git a/apps/MixMaster/gri30.py b/apps/MixMaster/gri30.py new file mode 100644 index 000000000..3ea536024 --- /dev/null +++ b/apps/MixMaster/gri30.py @@ -0,0 +1,1186 @@ +from Cantera.Lib import build +elements = { + 'O':build.element(8, 'O', 'Oxygen', 15.9994), + 'H':build.element(1, 'H', 'Hydrogen', 1.00797), + 'C':build.element(6, 'C', 'Carbon', 12.011), + 'N':build.element(7, 'N', 'Nitrogen', 14.0067), + 'Ar':build.element(18, 'Ar', 'Argon', 39.948) +} +species = { + 'H2':Species( name = 'H2', + id = 'TPIS78', + elements = {'H': 2}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [3.3372792, -4.94024731e-005, 4.99456778e-007, -1.79566394e-010, 2.00255376e-014, -950.158922, -3.20502331], + lowCoefficients = [2.34433112, 0.00798052075, -1.9478151e-005, 2.01572094e-008, -7.37611761e-012, -917.935173, 0.683010238]) ) +, + 'H':Species( name = 'H', + id = 'L 7/88', + elements = {'H': 1}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [2.50000001, -2.30842973e-011, 1.61561948e-014, -4.73515235e-018, 4.98197357e-022, 25473.6599, -0.446682914], + lowCoefficients = [2.5, 7.05332819e-013, -1.99591964e-015, 2.30081632e-018, -9.27732332e-022, 25473.6599, -0.446682853]) ) +, + 'O':Species( name = 'O', + id = 'L 1/90', + elements = {'O': 1}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [2.56942078, -8.59741137e-005, 4.19484589e-008, -1.00177799e-011, 1.22833691e-015, 29217.5791, 4.78433864], + lowCoefficients = [3.1682671, -0.00327931884, 6.64306396e-006, -6.12806624e-009, 2.11265971e-012, 29122.2592, 2.05193346]) ) +, + 'O2':Species( name = 'O2', + id = 'TPIS89', + elements = {'O': 2}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [3.28253784, 0.00148308754, -7.57966669e-007, 2.09470555e-010, -2.16717794e-014, -1088.45772, 5.45323129], + lowCoefficients = [3.78245636, -0.00299673416, 9.84730201e-006, -9.68129509e-009, 3.24372837e-012, -1063.94356, 3.65767573]) ) +, + 'OH':Species( name = 'OH', + id = 'RUS 78', + elements = {'O': 1, 'H': 1}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [3.09288767, 0.000548429716, 1.26505228e-007, -8.79461556e-011, 1.17412376e-014, 3858.657, 4.4766961], + lowCoefficients = [3.99201543, -0.00240131752, 4.61793841e-006, -3.88113333e-009, 1.3641147e-012, 3615.08056, -0.103925458]) ) +, + 'H2O':Species( name = 'H2O', + id = 'L 8/89', + elements = {'O': 1, 'H': 2}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [3.03399249, 0.00217691804, -1.64072518e-007, -9.7041987e-011, 1.68200992e-014, -30004.2971, 4.9667701], + lowCoefficients = [4.19864056, -0.0020364341, 6.52040211e-006, -5.48797062e-009, 1.77197817e-012, -30293.7267, -0.849032208]) ) +, + 'HO2':Species( name = 'HO2', + id = 'L 5/89', + elements = {'O': 2, 'H': 1}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [4.0172109, 0.00223982013, -6.3365815e-007, 1.1424637e-010, -1.07908535e-014, 111.856713, 3.78510215], + lowCoefficients = [4.30179801, -0.00474912051, 2.11582891e-005, -2.42763894e-008, 9.29225124e-012, 294.80804, 3.71666245]) ) +, + 'H2O2':Species( name = 'H2O2', + id = 'L 7/88', + elements = {'O': 2, 'H': 2}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [4.16500285, 0.00490831694, -1.90139225e-006, 3.71185986e-010, -2.87908305e-014, -17861.7877, 2.91615662], + lowCoefficients = [4.27611269, -0.000542822417, 1.67335701e-005, -2.15770813e-008, 8.62454363e-012, -17702.5821, 3.43505074]) ) +, + 'C':Species( name = 'C', + id = 'L11/88', + elements = {'C': 1}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [2.49266888, 4.79889284e-005, -7.2433502e-008, 3.74291029e-011, -4.87277893e-015, 85451.2953, 4.80150373], + lowCoefficients = [2.55423955, -0.000321537724, 7.33792245e-007, -7.32234889e-010, 2.66521446e-013, 85443.8832, 4.53130848]) ) +, + 'CH':Species( name = 'CH', + id = 'TPIS79', + elements = {'C': 1, 'H': 1}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [2.87846473, 0.000970913681, 1.44445655e-007, -1.30687849e-010, 1.76079383e-014, 71012.4364, 5.48497999], + lowCoefficients = [3.48981665, 0.000323835541, -1.68899065e-006, 3.16217327e-009, -1.40609067e-012, 70797.2934, 2.08401108]) ) +, + 'CH2':Species( name = 'CH2', + id = 'L S/93', + elements = {'C': 1, 'H': 2}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [2.87410113, 0.00365639292, -1.40894597e-006, 2.60179549e-010, -1.87727567e-014, 46263.604, 6.17119324], + lowCoefficients = [3.76267867, 0.000968872143, 2.79489841e-006, -3.85091153e-009, 1.68741719e-012, 46004.0401, 1.56253185]) ) +, + 'CH2(S)':Species( name = 'CH2(S)', + id = 'L S/93', + elements = {'C': 1, 'H': 2}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [2.29203842, 0.00465588637, -2.01191947e-006, 4.17906e-010, -3.39716365e-014, 50925.9997, 8.62650169], + lowCoefficients = [4.19860411, -0.00236661419, 8.2329622e-006, -6.68815981e-009, 1.94314737e-012, 50496.8163, -0.769118967]) ) +, + 'CH3':Species( name = 'CH3', + id = 'L11/89', + elements = {'C': 1, 'H': 3}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [2.28571772, 0.00723990037, -2.98714348e-006, 5.95684644e-010, -4.67154394e-014, 16775.5843, 8.48007179], + lowCoefficients = [3.6735904, 0.00201095175, 5.73021856e-006, -6.87117425e-009, 2.54385734e-012, 16444.9988, 1.60456433]) ) +, + 'CH4':Species( name = 'CH4', + id = 'L 8/88', + elements = {'C': 1, 'H': 4}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [0.074851495, 0.0133909467, -5.73285809e-006, 1.22292535e-009, -1.0181523e-013, -9468.34459, 18.437318], + lowCoefficients = [5.14987613, -0.0136709788, 4.91800599e-005, -4.84743026e-008, 1.66693956e-011, -10246.6476, -4.64130376]) ) +, + 'CO':Species( name = 'CO', + id = 'TPIS79', + elements = {'O': 1, 'C': 1}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [2.71518561, 0.00206252743, -9.98825771e-007, 2.30053008e-010, -2.03647716e-014, -14151.8724, 7.81868772], + lowCoefficients = [3.57953347, -0.00061035368, 1.01681433e-006, 9.07005884e-010, -9.04424499e-013, -14344.086, 3.50840928]) ) +, + 'CO2':Species( name = 'CO2', + id = 'L 7/88', + elements = {'O': 2, 'C': 1}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [3.85746029, 0.00441437026, -2.21481404e-006, 5.23490188e-010, -4.72084164e-014, -48759.166, 2.27163806], + lowCoefficients = [2.35677352, 0.00898459677, -7.12356269e-006, 2.45919022e-009, -1.43699548e-013, -48371.9697, 9.90105222]) ) +, + 'HCO':Species( name = 'HCO', + id = 'L12/89', + elements = {'O': 1, 'H': 1, 'C': 1}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [2.77217438, 0.00495695526, -2.48445613e-006, 5.89161778e-010, -5.33508711e-014, 4011.91815, 9.79834492], + lowCoefficients = [4.22118584, -0.00324392532, 1.37799446e-005, -1.33144093e-008, 4.33768865e-012, 3839.56496, 3.39437243]) ) +, + 'CH2O':Species( name = 'CH2O', + id = 'L 8/88', + elements = {'O': 1, 'H': 2, 'C': 1}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [1.76069008, 0.00920000082, -4.42258813e-006, 1.00641212e-009, -8.8385564e-014, -13995.8323, 13.656323], + lowCoefficients = [4.79372315, -0.00990833369, 3.73220008e-005, -3.79285261e-008, 1.31772652e-011, -14308.9567, 0.6028129]) ) +, + 'CH2OH':Species( name = 'CH2OH', + id = 'GUNL93', + elements = {'O': 1, 'H': 3, 'C': 1}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [3.69266569, 0.00864576797, -3.7510112e-006, 7.87234636e-010, -6.48554201e-014, -3242.50627, 5.81043215], + lowCoefficients = [3.86388918, 0.00559672304, 5.93271791e-006, -1.04532012e-008, 4.36967278e-012, -3193.91367, 5.47302243]) ) +, + 'CH3O':Species( name = 'CH3O', + id = '121686', + elements = {'O': 1, 'H': 3, 'C': 1}, + phase = 'G', + thermo = NasaPolynomial(300.0, 1000.0, 3000.0, 101325.0, + highCoefficients = [3.770799, 0.007871497, -2.656384e-006, 3.944431e-010, -2.112616e-014, 127.83252, 2.929575], + lowCoefficients = [2.106204, 0.007216595, 5.338472e-006, -7.377636e-009, 2.07561e-012, 978.6011, 13.152177]) ) +, + 'CH3OH':Species( name = 'CH3OH', + id = 'L 8/88', + elements = {'O': 1, 'H': 4, 'C': 1}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [1.78970791, 0.0140938292, -6.36500835e-006, 1.38171085e-009, -1.1706022e-013, -25374.8747, 14.5023623], + lowCoefficients = [5.71539582, -0.0152309129, 6.52441155e-005, -7.10806889e-008, 2.61352698e-011, -25642.7656, -1.50409823]) ) +, + 'C2H':Species( name = 'C2H', + id = 'L 1/91', + elements = {'C': 2, 'H': 1}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [3.16780652, 0.00475221902, -1.83787077e-006, 3.04190252e-010, -1.7723277e-014, 67121.065, 6.63589475], + lowCoefficients = [2.88965733, 0.0134099611, -2.84769501e-005, 2.94791045e-008, -1.09331511e-011, 66839.3932, 6.22296438]) ) +, + 'C2H2':Species( name = 'C2H2', + id = 'L 1/91', + elements = {'C': 2, 'H': 2}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [4.14756964, 0.00596166664, -2.37294852e-006, 4.67412171e-010, -3.61235213e-014, 25935.9992, -1.23028121], + lowCoefficients = [0.808681094, 0.0233615629, -3.55171815e-005, 2.80152437e-008, -8.50072974e-012, 26428.9807, 13.9397051]) ) +, + 'C2H3':Species( name = 'C2H3', + id = 'L 2/92', + elements = {'C': 2, 'H': 3}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [3.016724, 0.0103302292, -4.68082349e-006, 1.01763288e-009, -8.62607041e-014, 34612.8739, 7.78732378], + lowCoefficients = [3.21246645, 0.00151479162, 2.59209412e-005, -3.57657847e-008, 1.47150873e-011, 34859.8468, 8.51054025]) ) +, + 'C2H4':Species( name = 'C2H4', + id = 'L 1/91', + elements = {'C': 2, 'H': 4}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [2.03611116, 0.0146454151, -6.71077915e-006, 1.47222923e-009, -1.25706061e-013, 4939.88614, 10.3053693], + lowCoefficients = [3.95920148, -0.00757052247, 5.70990292e-005, -6.91588753e-008, 2.69884373e-011, 5089.77593, 4.09733096]) ) +, + 'C2H5':Species( name = 'C2H5', + id = 'L12/92', + elements = {'C': 2, 'H': 5}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [1.95465642, 0.0173972722, -7.98206668e-006, 1.75217689e-009, -1.49641576e-013, 12857.52, 13.4624343], + lowCoefficients = [4.30646568, -0.00418658892, 4.97142807e-005, -5.99126606e-008, 2.30509004e-011, 12841.6265, 4.70720924]) ) +, + 'C2H6':Species( name = 'C2H6', + id = 'L 8/88', + elements = {'C': 2, 'H': 6}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [1.0718815, 0.0216852677, -1.00256067e-005, 2.21412001e-009, -1.9000289e-013, -11426.3932, 15.1156107], + lowCoefficients = [4.29142492, -0.0055015427, 5.99438288e-005, -7.08466285e-008, 2.68685771e-011, -11522.2055, 2.66682316]) ) +, + 'HCCO':Species( name = 'HCCO', + id = 'SRIC91', + elements = {'O': 1, 'H': 1, 'C': 2}, + phase = 'G', + thermo = NasaPolynomial(300.0, 1000.0, 4000.0, 101325.0, + highCoefficients = [5.6282058, 0.0040853401, -1.5934547e-006, 2.8626052e-010, -1.9407832e-014, 19327.215, -3.9302595], + lowCoefficients = [2.2517214, 0.017655021, -2.3729101e-005, 1.7275759e-008, -5.0664811e-012, 20059.449, 12.490417]) ) +, + 'CH2CO':Species( name = 'CH2CO', + id = 'L 5/90', + elements = {'O': 1, 'H': 2, 'C': 2}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 3500.0, 101325.0, + highCoefficients = [4.51129732, 0.00900359745, -4.16939635e-006, 9.23345882e-010, -7.94838201e-014, -7551.05311, 0.632247205], + lowCoefficients = [2.1358363, 0.0181188721, -1.73947474e-005, 9.34397568e-009, -2.01457615e-012, -7042.91804, 12.215648]) ) +, + 'HCCOH':Species( name = 'HCCOH', + id = 'SRI91', + elements = {'O': 1, 'H': 2, 'C': 2}, + phase = 'G', + thermo = NasaPolynomial(300.0, 1000.0, 5000.0, 101325.0, + highCoefficients = [5.9238291, 0.00679236, -2.5658564e-006, 4.4987841e-010, -2.9940101e-014, 7264.626, -7.6017742], + lowCoefficients = [1.2423733, 0.031072201, -5.0866864e-005, 4.3137131e-008, -1.4014594e-011, 8031.6143, 13.874319]) ) +, + 'N':Species( name = 'N', + id = 'L 6/88', + elements = {'N': 1}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 6000.0, 101325.0, + highCoefficients = [2.4159429, 0.00017489065, -1.1902369e-007, 3.0226245e-011, -2.0360982e-015, 56133.773, 4.6496096], + lowCoefficients = [2.5, 0.0, 0.0, 0.0, 0.0, 56104.637, 4.1939087]) ) +, + 'NH':Species( name = 'NH', + id = 'And94', + elements = {'N': 1, 'H': 1}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 6000.0, 101325.0, + highCoefficients = [2.7836928, 0.001329843, -4.2478047e-007, 7.8348501e-011, -5.504447e-015, 42120.848, 5.7407799], + lowCoefficients = [3.4929085, 0.00031179198, -1.4890484e-006, 2.4816442e-009, -1.0356967e-012, 41880.629, 1.8483278]) ) +, + 'NH2':Species( name = 'NH2', + id = 'And89', + elements = {'N': 1, 'H': 2}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 6000.0, 101325.0, + highCoefficients = [2.8347421, 0.0032073082, -9.3390804e-007, 1.3702953e-010, -7.9206144e-015, 22171.957, 6.5204163], + lowCoefficients = [4.2040029, -0.0021061385, 7.1068348e-006, -5.6115197e-009, 1.6440717e-012, 21885.91, -0.14184248]) ) +, + 'NH3':Species( name = 'NH3', + id = 'J 6/77', + elements = {'N': 1, 'H': 3}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 6000.0, 101325.0, + highCoefficients = [2.6344521, 0.005666256, -1.7278676e-006, 2.3867161e-010, -1.2578786e-014, -6544.6958, 6.5662928], + lowCoefficients = [4.2860274, -0.004660523, 2.1718513e-005, -2.2808887e-008, 8.2638046e-012, -6741.7285, -0.62537277]) ) +, + 'NNH':Species( name = 'NNH', + id = 'T07/93', + elements = {'N': 2, 'H': 1}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 6000.0, 101325.0, + highCoefficients = [3.7667544, 0.0028915082, -1.041662e-006, 1.6842594e-010, -1.0091896e-014, 28650.697, 4.4705067], + lowCoefficients = [4.3446927, -0.0048497072, 2.0059459e-005, -2.1726464e-008, 7.9469539e-012, 28791.973, 2.977941]) ) +, + 'NO':Species( name = 'NO', + id = 'RUS 78', + elements = {'N': 1, 'O': 1}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 6000.0, 101325.0, + highCoefficients = [3.2606056, 0.0011911043, -4.2917048e-007, 6.9457669e-011, -4.0336099e-015, 9920.9746, 6.3693027], + lowCoefficients = [4.2184763, -0.004638976, 1.1041022e-005, -9.3361354e-009, 2.803577e-012, 9844.623, 2.2808464]) ) +, + 'NO2':Species( name = 'NO2', + id = 'L 7/88', + elements = {'N': 1, 'O': 2}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 6000.0, 101325.0, + highCoefficients = [4.8847542, 0.0021723956, -8.2806906e-007, 1.574751e-010, -1.0510895e-014, 2316.4983, -0.11741695], + lowCoefficients = [3.9440312, -0.001585429, 1.6657812e-005, -2.0475426e-008, 7.8350564e-012, 2896.6179, 6.3119917]) ) +, + 'N2O':Species( name = 'N2O', + id = 'L 7/88', + elements = {'N': 2, 'O': 1}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 6000.0, 101325.0, + highCoefficients = [4.8230729, 0.0026270251, -9.5850874e-007, 1.6000712e-010, -9.7752303e-015, 8073.4048, -2.2017207], + lowCoefficients = [2.2571502, 0.011304728, -1.3671319e-005, 9.6819806e-009, -2.9307182e-012, 8741.7744, 10.757992]) ) +, + 'HNO':Species( name = 'HNO', + id = 'And93', + elements = {'N': 1, 'O': 1, 'H': 1}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 6000.0, 101325.0, + highCoefficients = [2.9792509, 0.0034944059, -7.8549778e-007, 5.7479594e-011, -1.9335916e-016, 11750.582, 8.6063728], + lowCoefficients = [4.5334916, -0.0056696171, 1.8473207e-005, -1.7137094e-008, 5.5454573e-012, 11548.297, 1.7498417]) ) +, + 'CN':Species( name = 'CN', + id = 'HBH92', + elements = {'N': 1, 'C': 1}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 6000.0, 101325.0, + highCoefficients = [3.7459805, 4.3450775e-005, 2.9705984e-007, -6.8651806e-011, 4.4134173e-015, 51536.188, 2.7867601], + lowCoefficients = [3.6129351, -0.00095551327, 2.1442977e-006, -3.1516323e-010, -4.6430356e-013, 51708.34, 3.9804995]) ) +, + 'HCN':Species( name = 'HCN', + id = 'GRI/98', + elements = {'N': 1, 'C': 1, 'H': 1}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 6000.0, 101325.0, + highCoefficients = [3.8022392, 0.0031464228, -1.0632185e-006, 1.6619757e-010, -9.799757e-015, 14407.292, 1.5754601], + lowCoefficients = [2.2589886, 0.01005117, -1.3351763e-005, 1.0092349e-008, -3.0089028e-012, 14712.633, 8.9164419]) ) +, + 'H2CN':Species( name = 'H2CN', + id = '41687', + elements = {'N': 1, 'C': 1, 'H': 2}, + phase = 'G', + thermo = NasaPolynomial(300.0, 1000.0, 4000.0, 101325.0, + highCoefficients = [5.209703, 0.0029692911, -2.8555891e-007, -1.63555e-010, 3.0432589e-014, 27677.109, -4.444478], + lowCoefficients = [2.851661, 0.0056952331, 1.07114e-006, -1.622612e-009, -2.3511081e-013, 28637.82, 8.9927511]) ) +, + 'HCNN':Species( name = 'HCNN', + id = 'SRI/94', + elements = {'N': 2, 'C': 1, 'H': 1}, + phase = 'G', + thermo = NasaPolynomial(300.0, 1000.0, 5000.0, 101325.0, + highCoefficients = [5.8946362, 0.0039895959, -1.598238e-006, 2.9249395e-010, -2.0094686e-014, 53452.941, -5.1030502], + lowCoefficients = [2.5243194, 0.015960619, -1.8816354e-005, 1.212554e-008, -3.2357378e-012, 54261.984, 11.67587]) ) +, + 'HCNO':Species( name = 'HCNO', + id = 'BDEA94', + elements = {'N': 1, 'O': 1, 'C': 1, 'H': 1}, + phase = 'G', + thermo = NasaPolynomial(300.0, 1382.0, 5000.0, 101325.0, + highCoefficients = [6.59860456, 0.00302778626, -1.07704346e-006, 1.71666528e-010, -1.01439391e-014, 17966.1339, -10.3306599], + lowCoefficients = [2.64727989, 0.0127505342, -1.04794236e-005, 4.41432836e-009, -7.57521466e-013, 19299.0252, 10.7332972]) ) +, + 'HOCN':Species( name = 'HOCN', + id = 'BDEA94', + elements = {'N': 1, 'O': 1, 'C': 1, 'H': 1}, + phase = 'G', + thermo = NasaPolynomial(300.0, 1368.0, 5000.0, 101325.0, + highCoefficients = [5.89784885, 0.00316789393, -1.11801064e-006, 1.77243144e-010, -1.04339177e-014, -3706.53331, -6.18167825], + lowCoefficients = [3.78604952, 0.00688667922, -3.21487864e-006, 5.17195767e-010, 1.19360788e-014, -2826.984, 5.63292162]) ) +, + 'HNCO':Species( name = 'HNCO', + id = 'BDEA94', + elements = {'N': 1, 'O': 1, 'C': 1, 'H': 1}, + phase = 'G', + thermo = NasaPolynomial(300.0, 1478.0, 5000.0, 101325.0, + highCoefficients = [6.22395134, 0.00317864004, -1.09378755e-006, 1.70735163e-010, -9.95021955e-015, -16659.9344, -8.38224741], + lowCoefficients = [3.63096317, 0.00730282357, -2.28050003e-006, -6.61271298e-010, 3.62235752e-013, -15587.3636, 6.19457727]) ) +, + 'NCO':Species( name = 'NCO', + id = 'EA 93', + elements = {'N': 1, 'C': 1, 'O': 1}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 6000.0, 101325.0, + highCoefficients = [5.1521845, 0.0023051761, -8.8033153e-007, 1.4789098e-010, -9.0977996e-015, 14004.123, -2.544266], + lowCoefficients = [2.8269308, 0.0088051688, -8.3866134e-006, 4.8016964e-009, -1.3313595e-012, 14682.477, 9.5504646]) ) +, + 'N2':Species( name = 'N2', + id = '121286', + elements = {'N': 2}, + phase = 'G', + thermo = NasaPolynomial(300.0, 1000.0, 5000.0, 101325.0, + highCoefficients = [2.92664, 0.0014879768, -5.68476e-007, 1.0097038e-010, -6.753351e-015, -922.7977, 5.980528], + lowCoefficients = [3.298677, 0.0014082404, -3.963222e-006, 5.641515e-009, -2.444854e-012, -1020.8999, 3.950372]) ) +, + 'AR':Species( name = 'AR', + id = '120186', + elements = {'Ar': 1}, + phase = 'G', + thermo = NasaPolynomial(300.0, 1000.0, 5000.0, 101325.0, + highCoefficients = [2.5, 0.0, 0.0, 0.0, 0.0, -745.375, 4.366], + lowCoefficients = [2.5, 0.0, 0.0, 0.0, 0.0, -745.375, 4.366]) ) +, + 'C3H7':Species( name = 'C3H7', + id = 'L 9/84', + elements = {'C': 3, 'H': 7}, + phase = 'G', + thermo = NasaPolynomial(300.0, 1000.0, 5000.0, 101325.0, + highCoefficients = [7.7026987, 0.016044203, -5.283322e-006, 7.629859e-010, -3.9392284e-014, 8298.4336, -15.48018], + lowCoefficients = [1.0515518, 0.02599198, 2.380054e-006, -1.9609569e-008, 9.373247e-012, 10631.863, 21.122559]) ) +, + 'C3H8':Species( name = 'C3H8', + id = 'L 4/85', + elements = {'C': 3, 'H': 8}, + phase = 'G', + thermo = NasaPolynomial(300.0, 1000.0, 5000.0, 101325.0, + highCoefficients = [7.5341368, 0.018872239, -6.2718491e-006, 9.1475649e-010, -4.7838069e-014, -16467.516, -17.892349], + lowCoefficients = [0.93355381, 0.026424579, 6.1059727e-006, -2.1977499e-008, 9.5149253e-012, -13958.52, 19.201691]) ) +, + 'CH2CHO':Species( name = 'CH2CHO', + id = 'SAND86', + elements = {'O': 1, 'H': 3, 'C': 2}, + phase = 'G', + thermo = NasaPolynomial(300.0, 1000.0, 5000.0, 101325.0, + highCoefficients = [5.97567, 0.008130591, -2.743624e-006, 4.070304e-010, -2.176017e-014, 490.3218, -5.045251], + lowCoefficients = [3.409062, 0.010738574, 1.891492e-006, -7.158583e-009, 2.867385e-012, 1521.4766, 9.55829]) ) +, + 'CH3CHO':Species( name = 'CH3CHO', + id = 'L 8/88', + elements = {'O': 1, 'H': 4, 'C': 2}, + phase = 'G', + thermo = NasaPolynomial(200.0, 1000.0, 6000.0, 101325.0, + highCoefficients = [5.4041108, 0.011723059, -4.2263137e-006, 6.8372451e-010, -4.0984863e-014, -22593.122, -3.4807917], + lowCoefficients = [4.7294595, -0.0031932858, 4.7534921e-005, -5.7458611e-008, 2.1931112e-011, -21572.878, 4.1030159]) ) + +} +reactions = [ + build.reaction([(-2, 'O'), (1, 'O2')],[1002, 0, 1, 'M', 0], + {'H2': 1.4, 'AR': -0.17, 'C2H6': 2.0, 'CO': 0.75, 'CH4': 1.0, 'CO2': 2.6, 'H2O': 14.4}, + build.rateCoeff('3',build.arrhenius(120000000000.0, -1.0, 0.0) ),species), + build.reaction([(-1, 'O'), (-1, 'H'), (1, 'OH')],[1002, 1, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('3',build.arrhenius(500000000000.0, -1.0, 0.0) ),species), + build.reaction([(-1, 'O'), (-1, 'H2'), (1, 'H'), (1, 'OH')],[0, 2, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(38.7, 2.7, 3150.4781077) ),species), + build.reaction([(-1, 'O'), (-1, 'HO2'), (1, 'OH'), (1, 'O2')],[0, 3, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(20000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'O'), (-1, 'H2O2'), (1, 'OH'), (1, 'HO2')],[0, 4, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(9630.0, 2.0, 2013.08505284) ),species), + build.reaction([(-1, 'O'), (-1, 'CH'), (1, 'H'), (1, 'CO')],[0, 5, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(57000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'O'), (-1, 'CH2'), (1, 'H'), (1, 'HCO')],[0, 6, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(80000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'O'), (-1, 'CH2(S)'), (1, 'H2'), (1, 'CO')],[0, 7, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(15000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'O'), (-1, 'CH2(S)'), (1, 'H'), (1, 'HCO')],[0, 8, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(15000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'O'), (-1, 'CH3'), (1, 'H'), (1, 'CH2O')],[0, 9, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(50600000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'O'), (-1, 'CH4'), (1, 'OH'), (1, 'CH3')],[0, 10, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(1020000.0, 1.5, 4328.13286361) ),species), + build.reaction([(-1, 'O'), (-1, 'CO'), (1, 'CO2')],[1003, 11, 1, 'M', 0], + {'H2': 1.0, 'O2': 5.0, 'AR': -0.5, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 2.5, 'H2O': 5.0}, + build.rateCoeff('f',build.arrhenius(18000000.0, 0.0, 1200.30196276), + build.arrhenius(602000000.0, 0.0, 1509.81378963), + None),species), + build.reaction([(-1, 'O'), (-1, 'HCO'), (1, 'OH'), (1, 'CO')],[0, 12, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(30000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'O'), (-1, 'HCO'), (1, 'H'), (1, 'CO2')],[0, 13, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(30000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'O'), (-1, 'CH2O'), (1, 'OH'), (1, 'HCO')],[0, 14, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(39000000000.0, 0.0, 1781.58027177) ),species), + build.reaction([(-1, 'O'), (-1, 'CH2OH'), (1, 'OH'), (1, 'CH2O')],[0, 15, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(10000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'O'), (-1, 'CH3O'), (1, 'OH'), (1, 'CH2O')],[0, 16, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(10000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'O'), (-1, 'CH3OH'), (1, 'OH'), (1, 'CH2OH')],[0, 17, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(388.0, 2.5, 1560.14091595) ),species), + build.reaction([(-1, 'O'), (-1, 'CH3OH'), (1, 'OH'), (1, 'CH3O')],[0, 18, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(130.0, 2.5, 2516.35631605) ),species), + build.reaction([(-1, 'O'), (-1, 'C2H'), (1, 'CH'), (1, 'CO')],[0, 19, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(50000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'O'), (-1, 'C2H2'), (1, 'H'), (1, 'HCCO')],[0, 20, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(13500.0, 2.0, 956.215400101) ),species), + build.reaction([(-1, 'O'), (-1, 'C2H2'), (1, 'OH'), (1, 'C2H')],[0, 21, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(4.6e+016, -1.41, 14569.70307) ),species), + build.reaction([(-1, 'O'), (-1, 'C2H2'), (1, 'CO'), (1, 'CH2')],[0, 22, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(6940.0, 2.0, 956.215400101) ),species), + build.reaction([(-1, 'O'), (-1, 'C2H3'), (1, 'H'), (1, 'CH2CO')],[0, 23, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(30000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'O'), (-1, 'C2H4'), (1, 'CH3'), (1, 'HCO')],[0, 24, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(12500.0, 1.83, 110.719677906) ),species), + build.reaction([(-1, 'O'), (-1, 'C2H5'), (1, 'CH3'), (1, 'CH2O')],[0, 25, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(22400000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'O'), (-1, 'C2H6'), (1, 'OH'), (1, 'C2H5')],[0, 26, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(89800.0, 1.92, 2863.61348767) ),species), + build.reaction([(-1, 'O'), (-1, 'HCCO'), (1, 'H'), (2, 'CO')],[0, 27, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(100000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'O'), (-1, 'CH2CO'), (1, 'OH'), (1, 'HCCO')],[0, 28, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(10000000000.0, 0.0, 4026.17010569) ),species), + build.reaction([(-1, 'O'), (-1, 'CH2CO'), (1, 'CH2'), (1, 'CO2')],[0, 29, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(1750000000.0, 0.0, 679.416205335) ),species), + build.reaction([(-1, 'O2'), (-1, 'CO'), (1, 'O'), (1, 'CO2')],[0, 30, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(2500000000.0, 0.0, 24056.3663815) ),species), + build.reaction([(-1, 'O2'), (-1, 'CH2O'), (1, 'HO2'), (1, 'HCO')],[0, 31, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(100000000000.0, 0.0, 20130.8505284) ),species), + build.reaction([(-1, 'H'), (-1, 'O2'), (1, 'HO2')],[1002, 32, 1, 'M', 0], + {'O2': -1.0, 'N2': -1.0, 'C2H6': 0.5, 'CO': -0.25, 'CO2': 0.5, 'H2O': -1.0, 'AR': -1.0}, + build.rateCoeff('3',build.arrhenius(2.8e+012, -0.86, 0.0) ),species), + build.reaction([(-1, 'H'), (-2, 'O2'), (1, 'HO2'), (1, 'O2')],[0, 33, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(2.08e+013, -1.24, 0.0) ),species), + build.reaction([(-1, 'H'), (-1, 'O2'), (-1, 'H2O'), (1, 'HO2'), (1, 'H2O')],[0, 34, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(1.126e+013, -0.76, 0.0) ),species), + build.reaction([(-1, 'H'), (-1, 'O2'), (-1, 'N2'), (1, 'HO2'), (1, 'N2')],[0, 35, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(2.6e+013, -1.24, 0.0) ),species), + build.reaction([(-1, 'H'), (-1, 'O2'), (-1, 'AR'), (1, 'HO2'), (1, 'AR')],[0, 36, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(700000000000.0, -0.8, 0.0) ),species), + build.reaction([(-1, 'H'), (-1, 'O2'), (1, 'O'), (1, 'OH')],[0, 37, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(2.65e+013, -0.6707, 8576.24559638) ),species), + build.reaction([(-2, 'H'), (1, 'H2')],[1002, 38, 1, 'M', 0], + {'AR': -0.37, 'CH4': 1.0, 'CO2': -1.0, 'H2O': -1.0, 'C2H6': 2.0, 'H2': -1.0}, + build.rateCoeff('3',build.arrhenius(1e+012, -1.0, 0.0) ),species), + build.reaction([(-2, 'H'), (-1, 'H2'), (2, 'H2')],[0, 39, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(90000000000.0, -0.6, 0.0) ),species), + build.reaction([(-2, 'H'), (-1, 'H2O'), (1, 'H2'), (1, 'H2O')],[0, 40, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(6e+013, -1.25, 0.0) ),species), + build.reaction([(-2, 'H'), (-1, 'CO2'), (1, 'H2'), (1, 'CO2')],[0, 41, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(5.5e+014, -2.0, 0.0) ),species), + build.reaction([(-1, 'H'), (-1, 'OH'), (1, 'H2O')],[1002, 42, 1, 'M', 0], + {'CH4': 1.0, 'AR': -0.62, 'H2O': 2.65, 'C2H6': 2.0, 'H2': -0.27}, + build.rateCoeff('3',build.arrhenius(2.2e+016, -2.0, 0.0) ),species), + build.reaction([(-1, 'H'), (-1, 'HO2'), (1, 'O'), (1, 'H2O')],[0, 43, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(3970000000.0, 0.0, 337.695017614) ),species), + build.reaction([(-1, 'H'), (-1, 'HO2'), (1, 'O2'), (1, 'H2')],[0, 44, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(44800000000.0, 0.0, 537.493709109) ),species), + build.reaction([(-1, 'H'), (-1, 'HO2'), (2, 'OH')],[0, 45, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(84000000000.0, 0.0, 319.577252139) ),species), + build.reaction([(-1, 'H'), (-1, 'H2O2'), (1, 'HO2'), (1, 'H2')],[0, 46, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(12100.0, 2.0, 2617.0105687) ),species), + build.reaction([(-1, 'H'), (-1, 'H2O2'), (1, 'OH'), (1, 'H2O')],[0, 47, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(10000000000.0, 0.0, 1811.77654756) ),species), + build.reaction([(-1, 'H'), (-1, 'CH'), (1, 'C'), (1, 'H2')],[0, 48, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(165000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'H'), (-1, 'CH2'), (1, 'CH3')],[1003, 49, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('f',build.arrhenius(600000000000.0, 0.0, 0.0), + build.arrhenius(1.04e+020, -2.76, 805.234021137), + build.troe([0.562, 91.0, 5836.0, 8552.0])),species), + build.reaction([(-1, 'H'), (-1, 'CH2(S)'), (1, 'CH'), (1, 'H2')],[0, 50, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(30000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'H'), (-1, 'CH3'), (1, 'CH4')],[1003, 51, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 2.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('f',build.arrhenius(1.39e+013, -0.534, 269.753397081), + build.arrhenius(2.62e+027, -4.76, 1227.98188223), + build.troe([0.783, 74.0, 2941.0, 6964.0])),species), + build.reaction([(-1, 'H'), (-1, 'CH4'), (1, 'CH3'), (1, 'H2')],[0, 52, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(660000.0, 1.62, 5455.46049321) ),species), + build.reaction([(-1, 'H'), (-1, 'HCO'), (1, 'CH2O')],[1003, 53, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('f',build.arrhenius(1090000000.0, 0.48, -130.850528435), + build.arrhenius(2.47e+018, -2.57, 213.890286865), + build.troe([0.7824, 271.0, 2755.0, 6570.0])),species), + build.reaction([(-1, 'H'), (-1, 'HCO'), (1, 'H2'), (1, 'CO')],[0, 54, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(73400000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'H'), (-1, 'CH2O'), (1, 'CH2OH')],[1003, 55, 1, 'M', 0], + {'C2H6': 2.0, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0, 'CO': 0.5, 'H2': 1.0}, + build.rateCoeff('f',build.arrhenius(540000000.0, 0.454, 1811.77654756), + build.arrhenius(1.27e+026, -4.82, 3286.36134877), + build.troe([0.7187, 103.0, 1291.0, 4160.0])),species), + build.reaction([(-1, 'H'), (-1, 'CH2O'), (1, 'CH3O')],[1003, 56, 1, 'M', 0], + {'C2H6': 2.0, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0, 'CO': 0.5, 'H2': 1.0}, + build.rateCoeff('f',build.arrhenius(540000000.0, 0.454, 1308.50528435), + build.arrhenius(2.2e+024, -4.8, 2798.18822345), + build.troe([0.758, 94.0, 1555.0, 4200.0])),species), + build.reaction([(-1, 'H'), (-1, 'CH2O'), (1, 'HCO'), (1, 'H2')],[0, 57, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(57400.0, 1.9, 1379.96980372) ),species), + build.reaction([(-1, 'H'), (-1, 'CH2OH'), (1, 'CH3OH')],[1003, 58, 1, 'M', 0], + {'C2H6': 2.0, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0, 'CO': 0.5, 'H2': 1.0}, + build.rateCoeff('f',build.arrhenius(1055000000.0, 0.5, 43.2813286361), + build.arrhenius(4.36e+025, -4.65, 2556.61801711), + build.troe([0.6, 100.0, 90000.0, 10000.0])),species), + build.reaction([(-1, 'H'), (-1, 'CH2OH'), (1, 'H2'), (1, 'CH2O')],[0, 59, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(20000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'H'), (-1, 'CH2OH'), (1, 'OH'), (1, 'CH3')],[0, 60, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(165000000.0, 0.65, -142.929038752) ),species), + build.reaction([(-1, 'H'), (-1, 'CH2OH'), (1, 'CH2(S)'), (1, 'H2O')],[0, 61, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(32800000000.0, -0.09, 306.995470559) ),species), + build.reaction([(-1, 'H'), (-1, 'CH3O'), (1, 'CH3OH')],[1003, 62, 1, 'M', 0], + {'C2H6': 2.0, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0, 'CO': 0.5, 'H2': 1.0}, + build.rateCoeff('f',build.arrhenius(2430000000.0, 0.515, 25.1635631605), + build.arrhenius(4.66e+035, -7.44, 7086.05938601), + build.troe([0.7, 100.0, 90000.0, 10000.0])),species), + build.reaction([(-1, 'H'), (-1, 'CH3O'), (1, 'H'), (1, 'CH2OH')],[0, 63, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(41500.0, 1.63, 968.293910418) ),species), + build.reaction([(-1, 'H'), (-1, 'CH3O'), (1, 'H2'), (1, 'CH2O')],[0, 64, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(20000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'H'), (-1, 'CH3O'), (1, 'OH'), (1, 'CH3')],[0, 65, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(1500000000.0, 0.5, -55.3598389532) ),species), + build.reaction([(-1, 'H'), (-1, 'CH3O'), (1, 'CH2(S)'), (1, 'H2O')],[0, 66, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(262000000000.0, -0.23, 538.500251636) ),species), + build.reaction([(-1, 'H'), (-1, 'CH3OH'), (1, 'CH2OH'), (1, 'H2')],[0, 67, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(17000.0, 2.1, 2450.93105184) ),species), + build.reaction([(-1, 'H'), (-1, 'CH3OH'), (1, 'CH3O'), (1, 'H2')],[0, 68, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(4200.0, 2.1, 2450.93105184) ),species), + build.reaction([(-1, 'H'), (-1, 'C2H'), (1, 'C2H2')],[1003, 69, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('f',build.arrhenius(1e+014, -1.0, 0.0), + build.arrhenius(3.75e+027, -4.8, 956.215400101), + build.troe([0.6464, 132.0, 1315.0, 5566.0])),species), + build.reaction([(-1, 'H'), (-1, 'C2H2'), (1, 'C2H3')],[1003, 70, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('f',build.arrhenius(5600000000.0, 0.0, 1207.85103171), + build.arrhenius(3.8e+034, -7.27, 3633.61852038), + build.troe([0.7507, 98.5, 1302.0, 4167.0])),species), + build.reaction([(-1, 'H'), (-1, 'C2H3'), (1, 'C2H4')],[1003, 71, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('f',build.arrhenius(6080000000.0, 0.27, 140.915953699), + build.arrhenius(1.4e+024, -3.86, 1670.86059386), + build.troe([0.782, 207.5, 2663.0, 6095.0])),species), + build.reaction([(-1, 'H'), (-1, 'C2H3'), (1, 'H2'), (1, 'C2H2')],[0, 72, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(30000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'H'), (-1, 'C2H4'), (1, 'C2H5')],[1003, 73, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('f',build.arrhenius(540000000.0, 0.454, 915.953699044), + build.arrhenius(6e+035, -7.62, 3507.80070458), + build.troe([0.9753, 210.0, 984.0, 4374.0])),species), + build.reaction([(-1, 'H'), (-1, 'C2H4'), (1, 'C2H3'), (1, 'H2')],[0, 74, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(1325.0, 2.53, 6160.0402617) ),species), + build.reaction([(-1, 'H'), (-1, 'C2H5'), (1, 'C2H6')],[1003, 75, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('f',build.arrhenius(5.21e+014, -0.99, 795.168595873), + build.arrhenius(1.99e+035, -7.08, 3364.36839456), + build.troe([0.8422, 125.0, 2219.0, 6882.0])),species), + build.reaction([(-1, 'H'), (-1, 'C2H5'), (1, 'H2'), (1, 'C2H4')],[0, 76, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(2000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'H'), (-1, 'C2H6'), (1, 'C2H5'), (1, 'H2')],[0, 77, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(115000.0, 1.9, 3789.63261198) ),species), + build.reaction([(-1, 'H'), (-1, 'HCCO'), (1, 'CH2(S)'), (1, 'CO')],[0, 78, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(100000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'H'), (-1, 'CH2CO'), (1, 'HCCO'), (1, 'H2')],[0, 79, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(50000000000.0, 0.0, 4026.17010569) ),species), + build.reaction([(-1, 'H'), (-1, 'CH2CO'), (1, 'CH3'), (1, 'CO')],[0, 80, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(11300000000.0, 0.0, 1725.21389029) ),species), + build.reaction([(-1, 'H'), (-1, 'HCCOH'), (1, 'H'), (1, 'CH2CO')],[0, 81, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(10000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'H2'), (-1, 'CO'), (1, 'CH2O')],[1003, 82, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('f',build.arrhenius(43000.0, 1.5, 40060.3925516), + build.arrhenius(5.07e+021, -3.42, 42450.9310518), + build.troe([0.932, 197.0, 1540.0, 10300.0])),species), + build.reaction([(-1, 'OH'), (-1, 'H2'), (1, 'H'), (1, 'H2O')],[0, 83, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(216000.0, 1.51, 1726.22043281) ),species), + build.reaction([(-2, 'OH'), (1, 'H2O2')],[1003, 84, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('f',build.arrhenius(74000000000.0, -0.37, 0.0), + build.arrhenius(2.3e+012, -0.9, -855.561147458), + build.troe([0.7346, 94.0, 1756.0, 5182.0])),species), + build.reaction([(-2, 'OH'), (1, 'O'), (1, 'H2O')],[0, 85, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(35.7, 2.4, -1061.90236537) ),species), + build.reaction([(-1, 'OH'), (-1, 'HO2'), (1, 'O2'), (1, 'H2O')],[0, 86, 1, '', 1],{}, + build.rateCoeff('s',build.arrhenius(14500000000.0, 0.0, -251.635631605) ),species), + build.reaction([(-1, 'OH'), (-1, 'H2O2'), (1, 'HO2'), (1, 'H2O')],[0, 87, 1, '', 1],{}, + build.rateCoeff('s',build.arrhenius(2000000000.0, 0.0, 214.896829391) ),species), + build.reaction([(-1, 'OH'), (-1, 'H2O2'), (1, 'HO2'), (1, 'H2O')],[0, 88, 1, '', 1],{}, + build.rateCoeff('s',build.arrhenius(1.7e+015, 0.0, 14801.207851) ),species), + build.reaction([(-1, 'OH'), (-1, 'C'), (1, 'H'), (1, 'CO')],[0, 89, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(50000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'OH'), (-1, 'CH'), (1, 'H'), (1, 'HCO')],[0, 90, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(30000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'OH'), (-1, 'CH2'), (1, 'H'), (1, 'CH2O')],[0, 91, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(20000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'OH'), (-1, 'CH2'), (1, 'CH'), (1, 'H2O')],[0, 92, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(11300.0, 2.0, 1509.81378963) ),species), + build.reaction([(-1, 'OH'), (-1, 'CH2(S)'), (1, 'H'), (1, 'CH2O')],[0, 93, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(30000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'OH'), (-1, 'CH3'), (1, 'CH3OH')],[1003, 94, 1, 'M', 0], + {'C2H6': 2.0, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0, 'CO': 0.5, 'H2': 1.0}, + build.rateCoeff('f',build.arrhenius(2.79e+015, -1.43, 669.35078007), + build.arrhenius(4e+030, -5.92, 1580.27176648), + build.troe([0.412, 195.0, 5900.0, 6394.0])),species), + build.reaction([(-1, 'OH'), (-1, 'CH3'), (1, 'CH2'), (1, 'H2O')],[0, 95, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(56000.0, 1.6, 2727.7302466) ),species), + build.reaction([(-1, 'OH'), (-1, 'CH3'), (1, 'CH2(S)'), (1, 'H2O')],[0, 96, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(6.44e+014, -1.34, 713.13537997) ),species), + build.reaction([(-1, 'OH'), (-1, 'CH4'), (1, 'CH3'), (1, 'H2O')],[0, 97, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(100000.0, 1.6, 1570.20634122) ),species), + build.reaction([(-1, 'OH'), (-1, 'CO'), (1, 'H'), (1, 'CO2')],[0, 98, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(47600.0, 1.228, 35.2289884248) ),species), + build.reaction([(-1, 'OH'), (-1, 'HCO'), (1, 'H2O'), (1, 'CO')],[0, 99, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(50000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'OH'), (-1, 'CH2O'), (1, 'HCO'), (1, 'H2O')],[0, 100, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(3430000.0, 1.18, -224.962254655) ),species), + build.reaction([(-1, 'OH'), (-1, 'CH2OH'), (1, 'H2O'), (1, 'CH2O')],[0, 101, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(5000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'OH'), (-1, 'CH3O'), (1, 'H2O'), (1, 'CH2O')],[0, 102, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(5000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'OH'), (-1, 'CH3OH'), (1, 'CH2OH'), (1, 'H2O')],[0, 103, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(1440.0, 2.0, -422.747861097) ),species), + build.reaction([(-1, 'OH'), (-1, 'CH3OH'), (1, 'CH3O'), (1, 'H2O')],[0, 104, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(6300.0, 2.0, 754.906894816) ),species), + build.reaction([(-1, 'OH'), (-1, 'C2H'), (1, 'H'), (1, 'HCCO')],[0, 105, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(20000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'OH'), (-1, 'C2H2'), (1, 'H'), (1, 'CH2CO')],[0, 106, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(2.18e-007, 4.5, -503.271263211) ),species), + build.reaction([(-1, 'OH'), (-1, 'C2H2'), (1, 'H'), (1, 'HCCOH')],[0, 107, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(504.0, 2.3, 6794.16205335) ),species), + build.reaction([(-1, 'OH'), (-1, 'C2H2'), (1, 'C2H'), (1, 'H2O')],[0, 108, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(33700.0, 2.0, 7045.79768495) ),species), + build.reaction([(-1, 'OH'), (-1, 'C2H2'), (1, 'CH3'), (1, 'CO')],[0, 109, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(4.83e-007, 4.0, -1006.54252642) ),species), + build.reaction([(-1, 'OH'), (-1, 'C2H3'), (1, 'H2O'), (1, 'C2H2')],[0, 110, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(5000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'OH'), (-1, 'C2H4'), (1, 'C2H3'), (1, 'H2O')],[0, 111, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(3600.0, 2.0, 1258.17815803) ),species), + build.reaction([(-1, 'OH'), (-1, 'C2H6'), (1, 'C2H5'), (1, 'H2O')],[0, 112, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(3540.0, 2.12, 437.845998993) ),species), + build.reaction([(-1, 'OH'), (-1, 'CH2CO'), (1, 'HCCO'), (1, 'H2O')],[0, 113, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(7500000000.0, 0.0, 1006.54252642) ),species), + build.reaction([(-2, 'HO2'), (1, 'O2'), (1, 'H2O2')],[0, 114, 1, '', 1],{}, + build.rateCoeff('s',build.arrhenius(130000000.0, 0.0, -820.332159034) ),species), + build.reaction([(-2, 'HO2'), (1, 'O2'), (1, 'H2O2')],[0, 115, 1, '', 1],{}, + build.rateCoeff('s',build.arrhenius(420000000000.0, 0.0, 6039.25515853) ),species), + build.reaction([(-1, 'HO2'), (-1, 'CH2'), (1, 'OH'), (1, 'CH2O')],[0, 116, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(20000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'HO2'), (-1, 'CH3'), (1, 'O2'), (1, 'CH4')],[0, 117, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(1000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'HO2'), (-1, 'CH3'), (1, 'OH'), (1, 'CH3O')],[0, 118, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(37800000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'HO2'), (-1, 'CO'), (1, 'OH'), (1, 'CO2')],[0, 119, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(150000000000.0, 0.0, 11877.2018118) ),species), + build.reaction([(-1, 'HO2'), (-1, 'CH2O'), (1, 'HCO'), (1, 'H2O2')],[0, 120, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(5600.0, 2.0, 6039.25515853) ),species), + build.reaction([(-1, 'C'), (-1, 'O2'), (1, 'O'), (1, 'CO')],[0, 121, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(58000000000.0, 0.0, 289.884247609) ),species), + build.reaction([(-1, 'C'), (-1, 'CH2'), (1, 'H'), (1, 'C2H')],[0, 122, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(50000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'C'), (-1, 'CH3'), (1, 'H'), (1, 'C2H2')],[0, 123, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(50000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CH'), (-1, 'O2'), (1, 'O'), (1, 'HCO')],[0, 124, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(67100000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CH'), (-1, 'H2'), (1, 'H'), (1, 'CH2')],[0, 125, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(108000000000.0, 0.0, 1565.17362859) ),species), + build.reaction([(-1, 'CH'), (-1, 'H2O'), (1, 'H'), (1, 'CH2O')],[0, 126, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(5710000000.0, 0.0, -379.969803724) ),species), + build.reaction([(-1, 'CH'), (-1, 'CH2'), (1, 'H'), (1, 'C2H2')],[0, 127, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(40000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CH'), (-1, 'CH3'), (1, 'H'), (1, 'C2H3')],[0, 128, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(30000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CH'), (-1, 'CH4'), (1, 'H'), (1, 'C2H4')],[0, 129, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(60000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CH'), (-1, 'CO'), (1, 'HCCO')],[1003, 130, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('f',build.arrhenius(50000000000.0, 0.0, 0.0), + build.arrhenius(2.69e+022, -3.74, 974.333165576), + build.troe([0.5757, 237.0, 1652.0, 5069.0])),species), + build.reaction([(-1, 'CH'), (-1, 'CO2'), (1, 'HCO'), (1, 'CO')],[0, 131, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(190000000000.0, 0.0, 7947.65978863) ),species), + build.reaction([(-1, 'CH'), (-1, 'CH2O'), (1, 'H'), (1, 'CH2CO')],[0, 132, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(94600000000.0, 0.0, -259.184700554) ),species), + build.reaction([(-1, 'CH'), (-1, 'HCCO'), (1, 'CO'), (1, 'C2H2')],[0, 133, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(50000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CH2'), (-1, 'O2'), (1, 'OH'), (1, 'H'), (1, 'CO')],[0, 134, 0, '', 0],{}, + build.rateCoeff('s',build.arrhenius(5000000000.0, 0.0, 754.906894816) ),species), + build.reaction([(-1, 'CH2'), (-1, 'H2'), (1, 'H'), (1, 'CH3')],[0, 135, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(500.0, 2.0, 3638.65123301) ),species), + build.reaction([(-2, 'CH2'), (1, 'H2'), (1, 'C2H2')],[0, 136, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(1.6e+012, 0.0, 6011.07196779) ),species), + build.reaction([(-1, 'CH2'), (-1, 'CH3'), (1, 'H'), (1, 'C2H4')],[0, 137, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(40000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CH2'), (-1, 'CH4'), (2, 'CH3')],[0, 138, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(2460.0, 2.0, 4162.05334675) ),species), + build.reaction([(-1, 'CH2'), (-1, 'CO'), (1, 'CH2CO')],[1003, 139, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('f',build.arrhenius(810000000.0, 0.5, 2269.75339708), + build.arrhenius(2.69e+027, -5.11, 3570.70961248), + build.troe([0.5907, 275.0, 1226.0, 5185.0])),species), + build.reaction([(-1, 'CH2'), (-1, 'HCCO'), (1, 'C2H3'), (1, 'CO')],[0, 140, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(30000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CH2(S)'), (-1, 'N2'), (1, 'CH2'), (1, 'N2')],[0, 141, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(15000000000.0, 0.0, 301.962757927) ),species), + build.reaction([(-1, 'CH2(S)'), (-1, 'AR'), (1, 'CH2'), (1, 'AR')],[0, 142, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(9000000000.0, 0.0, 301.962757927) ),species), + build.reaction([(-1, 'CH2(S)'), (-1, 'O2'), (1, 'H'), (1, 'OH'), (1, 'CO')],[0, 143, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(28000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CH2(S)'), (-1, 'O2'), (1, 'CO'), (1, 'H2O')],[0, 144, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(12000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CH2(S)'), (-1, 'H2'), (1, 'CH3'), (1, 'H')],[0, 145, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(70000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CH2(S)'), (-1, 'H2O'), (1, 'CH3OH')],[1003, 146, 1, 'M', 0], + {'C2H6': 2.0, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0, 'CO': 0.5, 'H2': 1.0}, + build.rateCoeff('f',build.arrhenius(4.82e+014, -1.16, 576.245596376), + build.arrhenius(1.88e+032, -6.36, 2536.48716658), + build.troe([0.6027, 208.0, 3922.0, 10180.0])),species), + build.reaction([(-1, 'CH2(S)'), (-1, 'H2O'), (1, 'CH2'), (1, 'H2O')],[0, 147, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(30000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CH2(S)'), (-1, 'CH3'), (1, 'H'), (1, 'C2H4')],[0, 148, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(12000000000.0, 0.0, -286.86462003) ),species), + build.reaction([(-1, 'CH2(S)'), (-1, 'CH4'), (2, 'CH3')],[0, 149, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(16000000000.0, 0.0, -286.86462003) ),species), + build.reaction([(-1, 'CH2(S)'), (-1, 'CO'), (1, 'CH2'), (1, 'CO')],[0, 150, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(9000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CH2(S)'), (-1, 'CO2'), (1, 'CH2'), (1, 'CO2')],[0, 151, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(7000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CH2(S)'), (-1, 'CO2'), (1, 'CO'), (1, 'CH2O')],[0, 152, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(14000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CH2(S)'), (-1, 'C2H6'), (1, 'CH3'), (1, 'C2H5')],[0, 153, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(40000000000.0, 0.0, -276.799194766) ),species), + build.reaction([(-1, 'CH3'), (-1, 'O2'), (1, 'O'), (1, 'CH3O')],[0, 154, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(35600000000.0, 0.0, 15339.7081027) ),species), + build.reaction([(-1, 'CH3'), (-1, 'O2'), (1, 'OH'), (1, 'CH2O')],[0, 155, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(2310000000.0, 0.0, 10223.9557121) ),species), + build.reaction([(-1, 'CH3'), (-1, 'H2O2'), (1, 'HO2'), (1, 'CH4')],[0, 156, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(24.5, 2.47, 2606.94514343) ),species), + build.reaction([(-2, 'CH3'), (1, 'C2H6')],[1003, 157, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('f',build.arrhenius(6.77e+013, -1.18, 329.13940614), + build.arrhenius(3.4e+035, -7.03, 1390.03522899), + build.troe([0.619, 73.2, 1180.0, 9999.0])),species), + build.reaction([(-2, 'CH3'), (1, 'H'), (1, 'C2H5')],[0, 158, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(6840000000.0, 0.1, 5334.67539004) ),species), + build.reaction([(-1, 'CH3'), (-1, 'HCO'), (1, 'CH4'), (1, 'CO')],[0, 159, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(26480000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CH3'), (-1, 'CH2O'), (1, 'HCO'), (1, 'CH4')],[0, 160, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(3.32, 2.81, 2949.16960242) ),species), + build.reaction([(-1, 'CH3'), (-1, 'CH3OH'), (1, 'CH2OH'), (1, 'CH4')],[0, 161, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(30000.0, 1.5, 5002.51635632) ),species), + build.reaction([(-1, 'CH3'), (-1, 'CH3OH'), (1, 'CH3O'), (1, 'CH4')],[0, 162, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(10000.0, 1.5, 5002.51635632) ),species), + build.reaction([(-1, 'CH3'), (-1, 'C2H4'), (1, 'C2H3'), (1, 'CH4')],[0, 163, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(227.0, 2.0, 4630.09562154) ),species), + build.reaction([(-1, 'CH3'), (-1, 'C2H6'), (1, 'C2H5'), (1, 'CH4')],[0, 164, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(6140.0, 1.74, 5259.18470055) ),species), + build.reaction([(-1, 'HCO'), (-1, 'H2O'), (1, 'H'), (1, 'CO'), (1, 'H2O')],[0, 165, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(1.5e+015, -1.0, 8555.61147458) ),species), + build.reaction([(-1, 'HCO'), (1, 'H'), (1, 'CO')],[1002, 166, 1, 'M', 0], + {'C2H6': 2.0, 'CH4': 1.0, 'CO2': 1.0, 'H2O': -1.0, 'CO': 0.5, 'H2': 1.0}, + build.rateCoeff('3',build.arrhenius(1.87e+014, -1.0, 8555.61147458) ),species), + build.reaction([(-1, 'HCO'), (-1, 'O2'), (1, 'HO2'), (1, 'CO')],[0, 167, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(13450000000.0, 0.0, 201.308505284) ),species), + build.reaction([(-1, 'CH2OH'), (-1, 'O2'), (1, 'HO2'), (1, 'CH2O')],[0, 168, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(18000000000.0, 0.0, 452.94413689) ),species), + build.reaction([(-1, 'CH3O'), (-1, 'O2'), (1, 'HO2'), (1, 'CH2O')],[0, 169, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(4.28e-016, 7.6, -1776.54755913) ),species), + build.reaction([(-1, 'C2H'), (-1, 'O2'), (1, 'HCO'), (1, 'CO')],[0, 170, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(10000000000.0, 0.0, -379.969803724) ),species), + build.reaction([(-1, 'C2H'), (-1, 'H2'), (1, 'H'), (1, 'C2H2')],[0, 171, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(56800000.0, 0.9, 1003.01962758) ),species), + build.reaction([(-1, 'C2H3'), (-1, 'O2'), (1, 'HCO'), (1, 'CH2O')],[0, 172, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(4.58e+013, -1.39, 510.820332159) ),species), + build.reaction([(-1, 'C2H4'), (1, 'H2'), (1, 'C2H2')],[1003, 173, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('f',build.arrhenius(8e+012, 0.44, 43668.8475088), + build.arrhenius(1.58e+048, -9.3, 49219.929542), + build.troe([0.7345, 180.0, 1035.0, 5417.0])),species), + build.reaction([(-1, 'C2H5'), (-1, 'O2'), (1, 'HO2'), (1, 'C2H4')],[0, 174, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(840000000.0, 0.0, 1950.17614494) ),species), + build.reaction([(-1, 'HCCO'), (-1, 'O2'), (1, 'OH'), (2, 'CO')],[0, 175, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(3200000000.0, 0.0, 429.793658782) ),species), + build.reaction([(-2, 'HCCO'), (2, 'CO'), (1, 'C2H2')],[0, 176, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(10000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'N'), (-1, 'NO'), (1, 'N2'), (1, 'O')],[0, 177, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(27000000000.0, 0.0, 178.66129844) ),species), + build.reaction([(-1, 'N'), (-1, 'O2'), (1, 'NO'), (1, 'O')],[0, 178, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(9000000.0, 1.0, 3271.26321087) ),species), + build.reaction([(-1, 'N'), (-1, 'OH'), (1, 'NO'), (1, 'H')],[0, 179, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(33600000000.0, 0.0, 193.759436336) ),species), + build.reaction([(-1, 'N2O'), (-1, 'O'), (1, 'N2'), (1, 'O2')],[0, 180, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(1400000000.0, 0.0, 5440.36235531) ),species), + build.reaction([(-1, 'N2O'), (-1, 'O'), (2, 'NO')],[0, 181, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(29000000000.0, 0.0, 11650.7297433) ),species), + build.reaction([(-1, 'N2O'), (-1, 'H'), (1, 'N2'), (1, 'OH')],[0, 182, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(387000000000.0, 0.0, 9501.76144942) ),species), + build.reaction([(-1, 'N2O'), (-1, 'OH'), (1, 'N2'), (1, 'HO2')],[0, 183, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(2000000000.0, 0.0, 10598.8928032) ),species), + build.reaction([(-1, 'N2O'), (1, 'N2'), (1, 'O')],[1003, 184, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.375, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('f',build.arrhenius(79100000000.0, 0.0, 28193.2561651), + build.arrhenius(637000000000.0, 0.0, 28505.2843483), + None),species), + build.reaction([(-1, 'HO2'), (-1, 'NO'), (1, 'NO2'), (1, 'OH')],[0, 185, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(2110000000.0, 0.0, -241.570206341) ),species), + build.reaction([(-1, 'NO'), (-1, 'O'), (1, 'NO2')],[1002, 186, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('3',build.arrhenius(1.06e+014, -1.41, 0.0) ),species), + build.reaction([(-1, 'NO2'), (-1, 'O'), (1, 'NO'), (1, 'O2')],[0, 187, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(3900000000.0, 0.0, -120.785103171) ),species), + build.reaction([(-1, 'NO2'), (-1, 'H'), (1, 'NO'), (1, 'OH')],[0, 188, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(132000000000.0, 0.0, 181.177654756) ),species), + build.reaction([(-1, 'NH'), (-1, 'O'), (1, 'NO'), (1, 'H')],[0, 189, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(40000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'NH'), (-1, 'H'), (1, 'N'), (1, 'H2')],[0, 190, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(32000000000.0, 0.0, 166.07951686) ),species), + build.reaction([(-1, 'NH'), (-1, 'OH'), (1, 'HNO'), (1, 'H')],[0, 191, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(20000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'NH'), (-1, 'OH'), (1, 'N'), (1, 'H2O')],[0, 192, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(2000000.0, 1.2, 0.0) ),species), + build.reaction([(-1, 'NH'), (-1, 'O2'), (1, 'HNO'), (1, 'O')],[0, 193, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(461.0, 2.0, 3271.26321087) ),species), + build.reaction([(-1, 'NH'), (-1, 'O2'), (1, 'NO'), (1, 'OH')],[0, 194, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(1280.0, 1.5, 50.3271263211) ),species), + build.reaction([(-1, 'NH'), (-1, 'N'), (1, 'N2'), (1, 'H')],[0, 195, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(15000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'NH'), (-1, 'H2O'), (1, 'HNO'), (1, 'H2')],[0, 196, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(20000000000.0, 0.0, 6970.30699547) ),species), + build.reaction([(-1, 'NH'), (-1, 'NO'), (1, 'N2'), (1, 'OH')],[0, 197, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(21600000000.0, -0.23, 0.0) ),species), + build.reaction([(-1, 'NH'), (-1, 'NO'), (1, 'N2O'), (1, 'H')],[0, 198, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(365000000000.0, -0.45, 0.0) ),species), + build.reaction([(-1, 'NH2'), (-1, 'O'), (1, 'OH'), (1, 'NH')],[0, 199, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(3000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'NH2'), (-1, 'O'), (1, 'H'), (1, 'HNO')],[0, 200, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(39000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'NH2'), (-1, 'H'), (1, 'NH'), (1, 'H2')],[0, 201, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(40000000000.0, 0.0, 1836.94011072) ),species), + build.reaction([(-1, 'NH2'), (-1, 'OH'), (1, 'NH'), (1, 'H2O')],[0, 202, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(90000.0, 1.5, -231.504781077) ),species), + build.reaction([(-1, 'NNH'), (1, 'N2'), (1, 'H')],[0, 203, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(330000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'NNH'), (1, 'N2'), (1, 'H')],[1002, 204, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('3',build.arrhenius(130000000000.0, -0.11, 2506.29089079) ),species), + build.reaction([(-1, 'NNH'), (-1, 'O2'), (1, 'HO2'), (1, 'N2')],[0, 205, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(5000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'NNH'), (-1, 'O'), (1, 'OH'), (1, 'N2')],[0, 206, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(25000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'NNH'), (-1, 'O'), (1, 'NH'), (1, 'NO')],[0, 207, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(70000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'NNH'), (-1, 'H'), (1, 'H2'), (1, 'N2')],[0, 208, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(50000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'NNH'), (-1, 'OH'), (1, 'H2O'), (1, 'N2')],[0, 209, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(20000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'NNH'), (-1, 'CH3'), (1, 'CH4'), (1, 'N2')],[0, 210, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(25000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'H'), (-1, 'NO'), (1, 'HNO')],[1002, 211, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('3',build.arrhenius(4.48e+013, -1.32, 372.420734776) ),species), + build.reaction([(-1, 'HNO'), (-1, 'O'), (1, 'NO'), (1, 'OH')],[0, 212, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(25000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'HNO'), (-1, 'H'), (1, 'H2'), (1, 'NO')],[0, 213, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(900000000.0, 0.72, 332.159033719) ),species), + build.reaction([(-1, 'HNO'), (-1, 'OH'), (1, 'NO'), (1, 'H2O')],[0, 214, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(13000.0, 1.9, -478.10770005) ),species), + build.reaction([(-1, 'HNO'), (-1, 'O2'), (1, 'HO2'), (1, 'NO')],[0, 215, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(10000000000.0, 0.0, 6542.52642174) ),species), + build.reaction([(-1, 'CN'), (-1, 'O'), (1, 'CO'), (1, 'N')],[0, 216, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(77000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CN'), (-1, 'OH'), (1, 'NCO'), (1, 'H')],[0, 217, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(40000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CN'), (-1, 'H2O'), (1, 'HCN'), (1, 'OH')],[0, 218, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(8000000000.0, 0.0, 3754.40362355) ),species), + build.reaction([(-1, 'CN'), (-1, 'O2'), (1, 'NCO'), (1, 'O')],[0, 219, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(6140000000.0, 0.0, -221.439355813) ),species), + build.reaction([(-1, 'CN'), (-1, 'H2'), (1, 'HCN'), (1, 'H')],[0, 220, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(295.0, 2.45, 1127.32762959) ),species), + build.reaction([(-1, 'NCO'), (-1, 'O'), (1, 'NO'), (1, 'CO')],[0, 221, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(23500000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'NCO'), (-1, 'H'), (1, 'NH'), (1, 'CO')],[0, 222, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(54000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'NCO'), (-1, 'OH'), (1, 'NO'), (1, 'H'), (1, 'CO')],[0, 223, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(2500000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'NCO'), (-1, 'N'), (1, 'N2'), (1, 'CO')],[0, 224, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(20000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'NCO'), (-1, 'O2'), (1, 'NO'), (1, 'CO2')],[0, 225, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(2000000000.0, 0.0, 10065.4252642) ),species), + build.reaction([(-1, 'NCO'), (1, 'N'), (1, 'CO')],[1002, 226, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('3',build.arrhenius(310000000000.0, 0.0, 27201.8117765) ),species), + build.reaction([(-1, 'NCO'), (-1, 'NO'), (1, 'N2O'), (1, 'CO')],[0, 227, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(1.9e+014, -1.52, 372.420734776) ),species), + build.reaction([(-1, 'NCO'), (-1, 'NO'), (1, 'N2'), (1, 'CO2')],[0, 228, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(3.8e+015, -2.0, 402.617010569) ),species), + build.reaction([(-1, 'HCN'), (1, 'H'), (1, 'CN')],[1002, 229, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('3',build.arrhenius(1.04e+026, -3.3, 63714.1419225) ),species), + build.reaction([(-1, 'HCN'), (-1, 'O'), (1, 'NCO'), (1, 'H')],[0, 230, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(20.3, 2.64, 2506.29089079) ),species), + build.reaction([(-1, 'HCN'), (-1, 'O'), (1, 'NH'), (1, 'CO')],[0, 231, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(5.07, 2.64, 2506.29089079) ),species), + build.reaction([(-1, 'HCN'), (-1, 'O'), (1, 'CN'), (1, 'OH')],[0, 232, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(3910000.0, 1.58, 13387.0156014) ),species), + build.reaction([(-1, 'HCN'), (-1, 'OH'), (1, 'HOCN'), (1, 'H')],[0, 233, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(1100.0, 2.03, 6728.73678913) ),species), + build.reaction([(-1, 'HCN'), (-1, 'OH'), (1, 'HNCO'), (1, 'H')],[0, 234, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(4.4, 2.26, 3220.93608455) ),species), + build.reaction([(-1, 'HCN'), (-1, 'OH'), (1, 'NH2'), (1, 'CO')],[0, 235, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(0.16, 2.56, 4529.4413689) ),species), + build.reaction([(-1, 'H'), (-1, 'HCN'), (1, 'H2CN')],[1003, 236, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('f',build.arrhenius(33000000000.0, 0.0, 0.0), + build.arrhenius(1.4e+020, -3.4, 956.215400101), + None),species), + build.reaction([(-1, 'H2CN'), (-1, 'N'), (1, 'N2'), (1, 'CH2')],[0, 237, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(60000000000.0, 0.0, 201.308505284) ),species), + build.reaction([(-1, 'C'), (-1, 'N2'), (1, 'CN'), (1, 'N')],[0, 238, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(63000000000.0, 0.0, 23160.543533) ),species), + build.reaction([(-1, 'CH'), (-1, 'N2'), (1, 'HCN'), (1, 'N')],[0, 239, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(3120000.0, 0.88, 10130.8505284) ),species), + build.reaction([(-1, 'CH'), (-1, 'N2'), (1, 'HCNN')],[1003, 240, 1, 'M', 0], + {'H2': 1.0, 'AR': 0.0, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('f',build.arrhenius(3100000000.0, 0.15, 0.0), + build.arrhenius(1.3e+019, -3.16, 372.420734776), + build.troe([0.667, 235.0, 2117.0, 4536.0])),species), + build.reaction([(-1, 'CH2'), (-1, 'N2'), (1, 'HCN'), (1, 'NH')],[0, 241, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(10000000000.0, 0.0, 37242.0734776) ),species), + build.reaction([(-1, 'CH2(S)'), (-1, 'N2'), (1, 'NH'), (1, 'HCN')],[0, 242, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(100000000.0, 0.0, 32712.6321087) ),species), + build.reaction([(-1, 'C'), (-1, 'NO'), (1, 'CN'), (1, 'O')],[0, 243, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(19000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'C'), (-1, 'NO'), (1, 'CO'), (1, 'N')],[0, 244, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(29000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CH'), (-1, 'NO'), (1, 'HCN'), (1, 'O')],[0, 245, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(41000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CH'), (-1, 'NO'), (1, 'H'), (1, 'NCO')],[0, 246, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(16200000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CH'), (-1, 'NO'), (1, 'N'), (1, 'HCO')],[0, 247, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(24600000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CH2'), (-1, 'NO'), (1, 'H'), (1, 'HNCO')],[0, 248, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(3.1e+014, -1.38, 639.154504278) ),species), + build.reaction([(-1, 'CH2'), (-1, 'NO'), (1, 'OH'), (1, 'HCN')],[0, 249, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(290000000000.0, -0.69, 382.48616004) ),species), + build.reaction([(-1, 'CH2'), (-1, 'NO'), (1, 'H'), (1, 'HCNO')],[0, 250, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(38000000000.0, -0.36, 291.897332662) ),species), + build.reaction([(-1, 'CH2(S)'), (-1, 'NO'), (1, 'H'), (1, 'HNCO')],[0, 251, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(3.1e+014, -1.38, 639.154504278) ),species), + build.reaction([(-1, 'CH2(S)'), (-1, 'NO'), (1, 'OH'), (1, 'HCN')],[0, 252, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(290000000000.0, -0.69, 382.48616004) ),species), + build.reaction([(-1, 'CH2(S)'), (-1, 'NO'), (1, 'H'), (1, 'HCNO')],[0, 253, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(38000000000.0, -0.36, 291.897332662) ),species), + build.reaction([(-1, 'CH3'), (-1, 'NO'), (1, 'HCN'), (1, 'H2O')],[0, 254, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(96000000000.0, 0.0, 14494.2123805) ),species), + build.reaction([(-1, 'CH3'), (-1, 'NO'), (1, 'H2CN'), (1, 'OH')],[0, 255, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(1000000000.0, 0.0, 10946.1499748) ),species), + build.reaction([(-1, 'HCNN'), (-1, 'O'), (1, 'CO'), (1, 'H'), (1, 'N2')],[0, 256, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(22000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'HCNN'), (-1, 'O'), (1, 'HCN'), (1, 'NO')],[0, 257, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(2000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'HCNN'), (-1, 'O2'), (1, 'O'), (1, 'HCO'), (1, 'N2')],[0, 258, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(12000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'HCNN'), (-1, 'OH'), (1, 'H'), (1, 'HCO'), (1, 'N2')],[0, 259, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(12000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'HCNN'), (-1, 'H'), (1, 'CH2'), (1, 'N2')],[0, 260, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(100000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'HNCO'), (-1, 'O'), (1, 'NH'), (1, 'CO2')],[0, 261, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(98000.0, 1.41, 4277.80573729) ),species), + build.reaction([(-1, 'HNCO'), (-1, 'O'), (1, 'HNO'), (1, 'CO')],[0, 262, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(150000.0, 1.57, 22143.9355813) ),species), + build.reaction([(-1, 'HNCO'), (-1, 'O'), (1, 'NCO'), (1, 'OH')],[0, 263, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(2200.0, 2.11, 5737.2924006) ),species), + build.reaction([(-1, 'HNCO'), (-1, 'H'), (1, 'NH2'), (1, 'CO')],[0, 264, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(22500.0, 1.7, 1912.4308002) ),species), + build.reaction([(-1, 'HNCO'), (-1, 'H'), (1, 'H2'), (1, 'NCO')],[0, 265, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(105.0, 2.5, 6693.5078007) ),species), + build.reaction([(-1, 'HNCO'), (-1, 'OH'), (1, 'NCO'), (1, 'H2O')],[0, 266, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(33000.0, 1.5, 1811.77654756) ),species), + build.reaction([(-1, 'HNCO'), (-1, 'OH'), (1, 'NH2'), (1, 'CO2')],[0, 267, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(3300.0, 1.5, 1811.77654756) ),species), + build.reaction([(-1, 'HNCO'), (1, 'NH'), (1, 'CO')],[1002, 268, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('3',build.arrhenius(1.18e+013, 0.0, 42637.1414192) ),species), + build.reaction([(-1, 'HCNO'), (-1, 'H'), (1, 'H'), (1, 'HNCO')],[0, 269, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(2.1e+012, -0.69, 1434.32310015) ),species), + build.reaction([(-1, 'HCNO'), (-1, 'H'), (1, 'OH'), (1, 'HCN')],[0, 270, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(270000000.0, 0.18, 1066.93507801) ),species), + build.reaction([(-1, 'HCNO'), (-1, 'H'), (1, 'NH2'), (1, 'CO')],[0, 271, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(170000000000.0, -0.75, 1454.45395068) ),species), + build.reaction([(-1, 'HOCN'), (-1, 'H'), (1, 'H'), (1, 'HNCO')],[0, 272, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(20000.0, 2.0, 1006.54252642) ),species), + build.reaction([(-1, 'HCCO'), (-1, 'NO'), (1, 'HCNO'), (1, 'CO')],[0, 273, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(9000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CH3'), (-1, 'N'), (1, 'H2CN'), (1, 'H')],[0, 274, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(610000000000.0, -0.31, 145.948666331) ),species), + build.reaction([(-1, 'CH3'), (-1, 'N'), (1, 'HCN'), (1, 'H2')],[0, 275, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(3700000000.0, 0.15, -45.294413689) ),species), + build.reaction([(-1, 'NH3'), (-1, 'H'), (1, 'NH2'), (1, 'H2')],[0, 276, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(540.0, 2.4, 4989.93457474) ),species), + build.reaction([(-1, 'NH3'), (-1, 'OH'), (1, 'NH2'), (1, 'H2O')],[0, 277, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(50000.0, 1.6, 480.624056366) ),species), + build.reaction([(-1, 'NH3'), (-1, 'O'), (1, 'NH2'), (1, 'OH')],[0, 278, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(9400.0, 1.94, 3251.13236034) ),species), + build.reaction([(-1, 'NH'), (-1, 'CO2'), (1, 'HNO'), (1, 'CO')],[0, 279, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(10000000000.0, 0.0, 7221.94262708) ),species), + build.reaction([(-1, 'CN'), (-1, 'NO2'), (1, 'NCO'), (1, 'NO')],[0, 280, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(6.16e+012, -0.752, 173.628585808) ),species), + build.reaction([(-1, 'NCO'), (-1, 'NO2'), (1, 'N2O'), (1, 'CO2')],[0, 281, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(3250000000.0, 0.0, -354.806240564) ),species), + build.reaction([(-1, 'N'), (-1, 'CO2'), (1, 'NO'), (1, 'CO')],[0, 282, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(3000000000.0, 0.0, 5686.96527428) ),species), + build.reaction([(-1, 'O'), (-1, 'CH3'), (1, 'H'), (1, 'H2'), (1, 'CO')],[0, 283, 0, '', 0],{}, + build.rateCoeff('s',build.arrhenius(33700000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'O'), (-1, 'C2H4'), (1, 'H'), (1, 'CH2CHO')],[0, 284, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(6700.0, 1.83, 110.719677906) ),species), + build.reaction([(-1, 'O'), (-1, 'C2H5'), (1, 'H'), (1, 'CH3CHO')],[0, 285, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(109600000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'OH'), (-1, 'HO2'), (1, 'O2'), (1, 'H2O')],[0, 286, 1, '', 1],{}, + build.rateCoeff('s',build.arrhenius(5e+012, 0.0, 8721.69099144) ),species), + build.reaction([(-1, 'OH'), (-1, 'CH3'), (1, 'H2'), (1, 'CH2O')],[0, 287, 0, '', 0],{}, + build.rateCoeff('s',build.arrhenius(8000000.0, 0.5, -883.241066935) ),species), + build.reaction([(-1, 'CH'), (-1, 'H2'), (1, 'CH3')],[1003, 288, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('f',build.arrhenius(1970000000.0, 0.43, -186.210367388), + build.arrhenius(4.82e+019, -2.8, 296.930045294), + build.troe([0.578, 122.0, 2535.0, 9365.0])),species), + build.reaction([(-1, 'CH2'), (-1, 'O2'), (2, 'H'), (1, 'CO2')],[0, 289, 0, '', 0],{}, + build.rateCoeff('s',build.arrhenius(5800000000.0, 0.0, 754.906894816) ),species), + build.reaction([(-1, 'CH2'), (-1, 'O2'), (1, 'O'), (1, 'CH2O')],[0, 290, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(2400000000.0, 0.0, 754.906894816) ),species), + build.reaction([(-1, 'CH2'), (-1, 'CH2'), (2, 'H'), (1, 'C2H2')],[0, 291, 0, '', 0],{}, + build.rateCoeff('s',build.arrhenius(200000000000.0, 0.0, 5530.44791142) ),species), + build.reaction([(-1, 'CH2(S)'), (-1, 'H2O'), (1, 'H2'), (1, 'CH2O')],[0, 292, 0, '', 0],{}, + build.rateCoeff('s',build.arrhenius(68200000.0, 0.25, -470.558631102) ),species), + build.reaction([(-1, 'C2H3'), (-1, 'O2'), (1, 'O'), (1, 'CH2CHO')],[0, 293, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(303000000.0, 0.29, 5.53598389532) ),species), + build.reaction([(-1, 'C2H3'), (-1, 'O2'), (1, 'HO2'), (1, 'C2H2')],[0, 294, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(1337.0, 1.61, -193.256165073) ),species), + build.reaction([(-1, 'O'), (-1, 'CH3CHO'), (1, 'OH'), (1, 'CH2CHO')],[0, 295, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(5840000000.0, 0.0, 909.914443885) ),species), + build.reaction([(-1, 'O'), (-1, 'CH3CHO'), (1, 'OH'), (1, 'CH3'), (1, 'CO')],[0, 296, 0, '', 0],{}, + build.rateCoeff('s',build.arrhenius(5840000000.0, 0.0, 909.914443885) ),species), + build.reaction([(-1, 'O2'), (-1, 'CH3CHO'), (1, 'HO2'), (1, 'CH3'), (1, 'CO')],[0, 297, 0, '', 0],{}, + build.rateCoeff('s',build.arrhenius(30100000000.0, 0.0, 19703.0699547) ),species), + build.reaction([(-1, 'H'), (-1, 'CH3CHO'), (1, 'CH2CHO'), (1, 'H2')],[0, 298, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(2050000.0, 1.16, 1210.36738802) ),species), + build.reaction([(-1, 'H'), (-1, 'CH3CHO'), (1, 'CH3'), (1, 'H2'), (1, 'CO')],[0, 299, 0, '', 0],{}, + build.rateCoeff('s',build.arrhenius(2050000.0, 1.16, 1210.36738802) ),species), + build.reaction([(-1, 'OH'), (-1, 'CH3CHO'), (1, 'CH3'), (1, 'H2O'), (1, 'CO')],[0, 300, 0, '', 0],{}, + build.rateCoeff('s',build.arrhenius(23430000.0, 0.73, -560.140915954) ),species), + build.reaction([(-1, 'HO2'), (-1, 'CH3CHO'), (1, 'CH3'), (1, 'H2O2'), (1, 'CO')],[0, 301, 0, '', 0],{}, + build.rateCoeff('s',build.arrhenius(3010000000.0, 0.0, 6000.50327126) ),species), + build.reaction([(-1, 'CH3'), (-1, 'CH3CHO'), (1, 'CH3'), (1, 'CH4'), (1, 'CO')],[0, 302, 0, '', 0],{}, + build.rateCoeff('s',build.arrhenius(2720.0, 1.77, 2979.36587821) ),species), + build.reaction([(-1, 'H'), (-1, 'CH2CO'), (1, 'CH2CHO')],[1003, 303, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('f',build.arrhenius(486500000.0, 0.422, -883.241066935), + build.arrhenius(1.012e+036, -7.63, 1939.60744841), + build.troe([0.465, 201.0, 1773.0, 5333.0])),species), + build.reaction([(-1, 'O'), (-1, 'CH2CHO'), (1, 'H'), (1, 'CH2'), (1, 'CO2')],[0, 304, 0, '', 0],{}, + build.rateCoeff('s',build.arrhenius(150000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'O2'), (-1, 'CH2CHO'), (1, 'OH'), (1, 'CO'), (1, 'CH2O')],[0, 305, 0, '', 0],{}, + build.rateCoeff('s',build.arrhenius(18100000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'O2'), (-1, 'CH2CHO'), (1, 'OH'), (2, 'HCO')],[0, 306, 0, '', 0],{}, + build.rateCoeff('s',build.arrhenius(23500000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'H'), (-1, 'CH2CHO'), (1, 'CH3'), (1, 'HCO')],[0, 307, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(22000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'H'), (-1, 'CH2CHO'), (1, 'CH2CO'), (1, 'H2')],[0, 308, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(11000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'OH'), (-1, 'CH2CHO'), (1, 'H2O'), (1, 'CH2CO')],[0, 309, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(12000000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'OH'), (-1, 'CH2CHO'), (1, 'HCO'), (1, 'CH2OH')],[0, 310, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(30100000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CH3'), (-1, 'C2H5'), (1, 'C3H8')],[1003, 311, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('f',build.arrhenius(9430000000.0, 0.0, 0.0), + build.arrhenius(2.71e+068, -16.82, 6575.23905385), + build.troe([0.1527, 291.0, 2742.0, 7748.0])),species), + build.reaction([(-1, 'O'), (-1, 'C3H8'), (1, 'OH'), (1, 'C3H7')],[0, 312, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(193.0, 2.68, 1870.15601409) ),species), + build.reaction([(-1, 'H'), (-1, 'C3H8'), (1, 'C3H7'), (1, 'H2')],[0, 313, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(1320.0, 2.54, 3400.10065425) ),species), + build.reaction([(-1, 'OH'), (-1, 'C3H8'), (1, 'C3H7'), (1, 'H2O')],[0, 314, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(31600.0, 1.8, 470.055359839) ),species), + build.reaction([(-1, 'C3H7'), (-1, 'H2O2'), (1, 'HO2'), (1, 'C3H8')],[0, 315, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(0.378, 2.72, 754.906894816) ),species), + build.reaction([(-1, 'CH3'), (-1, 'C3H8'), (1, 'C3H7'), (1, 'CH4')],[0, 316, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(0.000903, 3.65, 3600.40261701) ),species), + build.reaction([(-1, 'CH3'), (-1, 'C2H4'), (1, 'C3H7')],[1003, 317, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('f',build.arrhenius(2550.0, 1.6, 2868.6462003), + build.arrhenius(3e+057, -14.6, 9144.43885254), + build.troe([0.1894, 277.0, 8748.0, 7891.0])),species), + build.reaction([(-1, 'O'), (-1, 'C3H7'), (1, 'C2H5'), (1, 'CH2O')],[0, 318, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(96400000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'H'), (-1, 'C3H7'), (1, 'C3H8')],[1003, 319, 1, 'M', 0], + {'H2': 1.0, 'AR': -0.3, 'C2H6': 2.0, 'CO': 0.5, 'CH4': 1.0, 'CO2': 1.0, 'H2O': 5.0}, + build.rateCoeff('f',build.arrhenius(36130000000.0, 0.0, 0.0), + build.arrhenius(4.42e+055, -13.545, 5715.65173629), + build.troe([0.315, 369.0, 3285.0, 6667.0])),species), + build.reaction([(-1, 'H'), (-1, 'C3H7'), (1, 'CH3'), (1, 'C2H5')],[0, 320, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(4060.0, 2.19, 447.911424258) ),species), + build.reaction([(-1, 'OH'), (-1, 'C3H7'), (1, 'C2H5'), (1, 'CH2OH')],[0, 321, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(24100000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'HO2'), (-1, 'C3H7'), (1, 'O2'), (1, 'C3H8')],[0, 322, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(25500000.0, 0.255, -474.584801208) ),species), + build.reaction([(-1, 'HO2'), (-1, 'C3H7'), (1, 'OH'), (1, 'C2H5'), (1, 'CH2O')],[0, 323, 0, '', 0],{}, + build.rateCoeff('s',build.arrhenius(24100000000.0, 0.0, 0.0) ),species), + build.reaction([(-1, 'CH3'), (-1, 'C3H7'), (2, 'C2H5')],[0, 324, 1, '', 0],{}, + build.rateCoeff('s',build.arrhenius(19270000000.0, -0.32, 0.0) ),species) +] +gri30 = build.mechanism(elements, species, reactions) diff --git a/apps/MixMaster/main.py b/apps/MixMaster/main.py new file mode 100644 index 000000000..cb6ef056d --- /dev/null +++ b/apps/MixMaster/main.py @@ -0,0 +1,330 @@ +############################################################################# +# +# MixMaster +# +############################################################################# + +# options +_app_title = 'MixMaster' +_app_version = '1.0' + + +# functionality imports +from Tkinter import * +import tkMessageBox +import sys, os, string +from Numeric import zeros + +# Cantera imports +from Cantera import * +import utilities +from Cantera.gases import IdealGasMix + +# local imports +from TransportFrame import TransportFrame +from CompositionFrame import MixtureFrame +from ThermoFrame import ThermoFrame +from ImportFrame import ImportFrame +from DataFrame import DataFrame +from KineticsFrame import SpeciesKineticsFrame, ReactionKineticsFrame, ReactionPathFrame +#from Edit import EditFrame +from MechManager import MechManager, _autoload +from UnitChooser import UnitVar +from ControlPanel import ControlWindow +from ControlPanel import make_menu, menuitem_state +from Mix import Mix, Species + +def testit(): + return + + +class MixMaster: + + def stop(self): + sys.exit(0) + + def openmech(self): + from tkFileDialog import askopenfilename + pathname = askopenfilename(filetypes=[("XML Files", "*.xml *.ctml"), + ("All Files", "*.*")]) + if pathname: + self.loadmech('', pathname) + + + def loadmech(self, mechname, pathname, mw=1): + + p = os.path.normpath(os.path.dirname(pathname)) + self.fname = os.path.basename(pathname) + ff = os.path.splitext(self.fname) + + try: + self.mech = IdealGasMix(pathname) + self.mechname = ff[0] + + except: + utilities.handleError('could not create gas mixture object: ' + +ff[0]+'\n') + self.mechname = 'Error' + return + + self.makeMix() + + if not mechname: + mechname = self.mechname + + self.mechframe.addMechanism(mechname, self.mech) + if mw==1: + self.makeWindows() + + + def addWindow(self, name, w): + """Add a new window, or replace an existing one.""" + wstate = '' + if self._windows.has_key(name): + try: + wstate = self._windows[name].master.state() + self._windows[name].master.destroy() + except: + pass + else: + wstate = 'withdrawn' + self._windows[name] = w + self._vis[name] = IntVar() + if wstate == 'withdrawn': + self._windows[name].master.withdraw() + else: + self._windows[name].show() + + + + def update(self): + """Update all windows to reflect the current mixture state.""" + for w in self._windows.keys(): + try: + m = self._windows[w].master + if m.state() != 'withdrawn': + self._windows[w].show() + except: + pass + self.thermo.showState() + self.mixfr.show() + + + + def makeMix(self): + self.mix = Mix(self.mech) + nsp = self.mech.nSpecies() + self.species = [] + nm = self.mech.speciesNames() + + for k in range(nsp): + self.species.append(Species(self.mech, nm[k])) + + x = self.mech.moleFractions() + self.mix.setMoles(x) + self.mix.set(temperature = self.mech.temperature(), + pressure = self.mech.pressure()) + + + + def __init__(self, master=None): + """ + Create a new Application instance. + Usually this is only called once. + """ + if master: + self.master = master + else: + t = Tk() + self.master = t + + self._windows = {} + self._vis = {} + self.windows = [] + + self.cwin = ControlWindow(_app_title,self.master) + self.cwin.master.resizable(FALSE,FALSE) + + self.menubar = Frame(self.cwin, relief=GROOVE,bd=2) + self.menubar.grid(row=0,column=0,sticky=N+W+E) + + self.mixfr = None + self.thermo = None + self.transport = None + self.kinetics = None + self.rxndata = None + self.rxnpaths = None + self.edit = None + self.fname = None + + self.mechframe = MechManager(self.cwin, self) + self.mechframe.grid(row=1,column=0,sticky=N+W) + + fileitems = [('Load Mixture...', self.openmech), + ('Import Mechanism File...',self.importfile), + 'separator', + ('Load Data File...',self.showdata), + 'separator', + ('Exit', self.stop), + [] + ] + self.filemenu = make_menu('File', self.menubar, fileitems) + + + self.vtherm = IntVar() + self.vcomp = IntVar() + self.vtran = IntVar() + self.vkin = IntVar() + self.vrxn = IntVar() + self.vrxn.set(0) + self.vtherm.set(1) + self.vedit = IntVar() + + + dataitems = [(' Import Flame Data', testit), + (' Import CSV Data', testit), + []] + #self.datamenu = make_menu('Data', self.menubar, dataitems) + + + #toolitems = [(' Convert...', self.importfile), + # []] + #self.toolmenu = make_menu('Tools', self.menubar, toolitems) + + + w = [(' Thermodynamic State', self.showthermo, 'check', self.vtherm), + (' Composition', self.showcomp, 'check', self.vcomp), + 'separator', + (' Kinetics', self.showkinetics, 'check', self.vkin), + (' Reactions...', self.showrxns), + (' Reaction Paths...', self.showrpaths), + []] + + self.viewmenu = make_menu('Windows', self.menubar, w) + + self.helpmenu = make_menu('Help', self.menubar, + [('About '+_app_title+'...', self.aboutmix), + ('About Cantera...', testit), + [] + + ]) + + # load the preloaded mechanisms + for m in _autoload: + self.loadmech(m[0],m[1],0) + + self.makeWindows() + self.addWindow('import',ImportFrame(self)) + + self.vtherm.set(1) + self.showthermo() +## self.vcomp.set(1) +## self.showcomp() + + self.master.iconify() + self.master.update() + self.master.deiconify() + self.cwin.mainloop() + + + def importfile(self): + #self.vimport.set(1) + w = self._windows['import'] + w.show() + + + def makeWindows(self): +# if self.mixfr: + for w in self.windows: + try: + w.destroy() + except: + pass + + fr = [MixtureFrame, ThermoFrame, TransportFrame] + + self.mixfr = MixtureFrame(self.cwin, self) + self.thermo = ThermoFrame(self.cwin, self) + +# self.transport = TransportFrame(self.cwin, self) + self.kinetics = SpeciesKineticsFrame(self.cwin, self) + + self.addWindow('rxndata',ReactionKineticsFrame(self.vrxn, self)) + self.addWindow('rxnpaths',ReactionPathFrame(self)) + self.addWindow('dataset',DataFrame(None, self)) + + + #self.edit = EditFrame(t, self) + + self.windows = [self.mixfr, + self.thermo, self.transport, + self.kinetics] + + self.showthermo() + self.showcomp() + #self.showtransport() + self.showkinetics() + #self.showrxns() + #self.showrpaths() + #self.showdata() + + if self.mech: + self.mechframe.grid(row=1,column=0) + else: + self.mechframe.grid_forget() + #self.showedit() + + def show(self, frame, vis, row, col): + if vis: + frame.grid(row=row,column=col,sticky=N+E+S+W) + else: + frame.grid_forget() + + def showthermo(self): + if self.thermo: + self.show(self.thermo, self.vtherm.get(), 7, 0) + + def showcomp(self): + if self.mixfr: + self.show(self.mixfr, self.vcomp.get(), 8, 0) + + def showkinetics(self): + if self.kinetics: + self.show(self.kinetics, self.vkin.get(), 10, 0) + + def showrxns(self): + self._windows['rxndata'].show() + + def showrpaths(self): + self._windows['rxnpaths'].show() + + def showdata(self): + self._windows['dataset'].browseForDatafile() + + def aboutmix(self): + + m = tkMessageBox.showinfo(title = 'About MixMaster', + message = """ + MixMaster + + version """+_app_version+""" + +written by: + +Prof. David G. Goodwin +California Institute of Technology + +copyright 2003 +California Institute of Technology + """) + + + +if __name__ == "__main__": + MixMaster() + + + + + + diff --git a/apps/MixMaster/menu.py b/apps/MixMaster/menu.py new file mode 100644 index 000000000..2ebeab463 --- /dev/null +++ b/apps/MixMaster/menu.py @@ -0,0 +1,31 @@ +from Tkinter import * + +def make_menu(name, menubar, list): + from types import * + button=Menubutton(menubar, text=name, padx=3,pady=1) + button.pack(side=LEFT, anchor=W) + menu = Menu(button,tearoff=FALSE) + for entry in list: + if entry == 'separator': + menu.add_separator({}) + elif type(entry)==ListType: + for num in entry: + menu.entryconfig(num,state=DISABLED) + elif type(entry[1]) != ListType: + if len(entry) == 2 or entry[2] == 'command': + menu.add_command(label=entry[0], + command=entry[1]) + elif entry[2] == 'check': + entry[3].set(0) + if len(entry) >= 5: val = entry[4] + else: val = 1 + menu.add_checkbutton(label=entry[0], + command=entry[1], variable = entry[3], + onvalue=val) + else: + submenu=make_menu(entry[0],menu, entry[1]) + menu.add_cascade(label=entry[0], + menu=submenu) + + button['menu']=menu + return button diff --git a/apps/MixMaster/newflow.py b/apps/MixMaster/newflow.py new file mode 100644 index 000000000..c9583e98a --- /dev/null +++ b/apps/MixMaster/newflow.py @@ -0,0 +1,135 @@ + +from Tkinter import * +from tkFileDialog import askopenfilename +import tkMessageBox + +from Cantera.gases import IdealGasMix +from Cantera import * + +class NewFlowDialog: + + def __init__(self, parent): + + top = self.top = Toplevel(parent) + + pl = Label(top, text='Pressure') + pl.grid(row = 0, column = 0) + + geom = Frame(top, bd=2, relief=GROOVE) + geom.grid(row = 1, column = 0) + lb = Listbox(geom) + for item in ["One-Dimensional", "Stagnation"]: + lb.insert(END, item) + lb.grid(row = 0, column = 0) + glb = Listbox(geom) + for item in ["Axisymmetric","2D"]: + glb.insert(END, item) + glb.grid(row = 1, column = 0) + + # ------------- pressure input ---------------- + + self.p = DoubleVar() + self.pbox = Entry(top, textvariable = self.p) + self.pbox.grid(row = 0, column = 1) + + + + # ------------- gas file name input ----------- + + + gasf = Frame(top, bd=2, relief=GROOVE) + gasf.grid(row = 4, column = 0, columnspan=2) + gl = Label(gasf, text='Gas Mixture Specification') + gl.grid(row = 0, column = 0) + + + self.infile = StringVar() + Label(gasf, text='Mixture Input File').grid(row = 1, column = 0) + Entry(gasf, textvariable = self.infile).grid(row = 1, column = 1) + Button(gasf, text='Browse..', command=self.getinfile).grid(row = 1, + column = 2) + + self.spfile = StringVar() + Label(gasf, text='Species Database').grid(row = 2, column = 0) + Entry(gasf, textvariable = self.spfile).grid(row = 2, column = 1) + Button(gasf, text='Browse..', command=self.getspfile).grid(row = 2, + column = 2) + + + self.trfile = StringVar() + Label(gasf, text='Transport Database').grid(row = 3, column = 0) + Entry(gasf, textvariable = self.trfile).grid(row = 3, column = 1) + Button(gasf, text='Browse..', command=self.gettrfile).grid(row = 3, + column = 2) + + + # ------------- grid ------------------------- + + gf = Frame(top, bd=2, relief=GROOVE) + gf.grid(row = 5, column = 0, columnspan=2) + + gr = Label(gf, text='Initial Grid') + gr.grid(row = 0, column = 0) + + self.zleft = DoubleVar() + self.zright = DoubleVar() + ll = Label(gf, text='Left boundary at ') + rl = Label(gf, text='Right boundary at ') + lbb = Entry(gf, textvariable = self.zleft) + rbb = Entry(gf, textvariable = self.zright) + ll.grid(row = 1, column = 0) + rl.grid(row = 2, column = 0) + lbb.grid(row = 1, column = 1) + rbb.grid(row = 2, column = 1) + + ok = Button(top, text = 'OK', command=self.ok) + ok.grid(row = 20, column = 20) + + + + def ok(self): + p = self.p.get() + try: + infile = self.infile.get() + spfile = self.spfile.get() + trfile = self.trfile.get() + if spfile and trfile: + self.gas = IdealGasMix(import_file = infile, + thermo_db = spfile, + transport_db = trfile) + elif spfile: + self.gas = IdealGasMix(import_file = infile, + thermo_db = spfile) + else: + self.gas = IdealGasMix(import_file = infile) + + except: + tkMessageBox.showerror('Create Gas', + 'Error reading file %s. See log file for more information.' % infile) + + #self.flow = Flow1D(flow_type = ftype, flow_geom = fgeom, + # pressure = p, grid = gr, gas = g) + self.top.destroy() + + def getinfile(self): + pathname = askopenfilename(filetypes=[ + ("Input Files", "*.xml *.inp"), + ("All Files", "*.*")]) + self.infile.set(pathname) + + def getspfile(self): + pathname = askopenfilename(filetypes=[ + ("Species Data Files", "*.xml *.dat"), + ("All Files", "*.*")]) + self.spfile.set(pathname) + + def gettrfile(self): + pathname = askopenfilename(filetypes=[ + ("Transport Data Files", "*.xml *.dat"), + ("All Files", "*.*")]) + self.trfile.set(pathname) + + + + + diff --git a/apps/MixMaster/utilities.py b/apps/MixMaster/utilities.py new file mode 100644 index 000000000..37458f605 --- /dev/null +++ b/apps/MixMaster/utilities.py @@ -0,0 +1,44 @@ +import string +import os, sys +import types, traceback + +try: + from Tkinter import Tk + import tkMessageBox + _hasTk = 1 +except: + _hasTk = 0 + + +def write_CSV(f,x): + """write list x to file f in comma-separated-value format.""" + for e in x: + f.write( `e`+',') + f.write('\n') + + +def _print_value(name, value, unitstr): + print string.rjust(name, 15)+ \ + string.rjust('%10.5e' %value, 15) + ' ' + \ + string.ljust(unitstr,5), + +def hasTk(): + try: + import tkMessageBox + return 1 + except: + return 0 + +def handleError(message = '', window = None, + fatal = 0, warning = 0, options = None): + if warning: + tkMessageBox.showwarning(title = 'Warning', message = message, + parent = window) + else: + m = tkMessageBox.showerror(title = 'Error', message = message, + parent = window) + + + + + diff --git a/apps/README.txt b/apps/README.txt new file mode 100644 index 000000000..6c6cafadd --- /dev/null +++ b/apps/README.txt @@ -0,0 +1,8 @@ +This directory is for applications that are not part of Cantera +itself, but may be distributed with Cantera. + +Contents: + +MixMaster -- A graphical control panel for viewing mixture properties + (Python) + diff --git a/bin/.cvsignore b/bin/.cvsignore new file mode 100644 index 000000000..752633d4a --- /dev/null +++ b/bin/.cvsignore @@ -0,0 +1,5 @@ +ck2ctml +ctsetup +cxx_examples +validate +csvdiff diff --git a/bin/README b/bin/README new file mode 100755 index 000000000..8d1c8b69c --- /dev/null +++ b/bin/README @@ -0,0 +1 @@ + diff --git a/bin/mixmaster.py b/bin/mixmaster.py new file mode 100755 index 000000000..8f17ec42a --- /dev/null +++ b/bin/mixmaster.py @@ -0,0 +1,2 @@ +from MixMaster import MixMaster +o = MixMaster() diff --git a/bin/rm_cvsignore b/bin/rm_cvsignore new file mode 100755 index 000000000..01db905ea --- /dev/null +++ b/bin/rm_cvsignore @@ -0,0 +1,40 @@ +#!/bin/sh +# +# rm_cvsignore: +# +# This script will delete all files listed in .cvsignore +# except the file Makefile +# +################################################################### +# +delete_file() +# +# This routine will delete a file +# +{ +dferrorStatus=0 +for aaa in $* +do + if [ $aaa != "Makefile" ] + then + if [ -f $aaa ] + then + /bin/rm -f $aaa + fi + fi +done +return $dferrorStatus +} +# +################################################################### +# +ignore_list=`cat .cvsignore` +for item in $ignore_list +do + delete_file $item +done +# +# +#################################################################### +# + diff --git a/config.h b/config.h new file mode 100755 index 000000000..f3a842bce --- /dev/null +++ b/config.h @@ -0,0 +1,59 @@ +/* ../config.h. Generated automatically by configure. */ +// +// Run the 'configure' script to generate 'config.h' from this input file. +// +#ifndef CT_CONFIG_H +#define CT_CONFIG_H + + +//------------------------ Fortran settings -------------------// + + +// define types doublereal, integer, and ftnlen to match the +// corresponding Fortran data types on your system. The defaults +// are OK for most systems + +typedef double doublereal; // Fortran double precision +typedef int integer; // Fortran integer +typedef int ftnlen; // Fortran hidden string length type + + +// Fortran compilers pass character strings in argument lists by +// adding a hidden argement with the length of the string. Some +// compilers add the hidden length argument immediately after the +// CHARACTER variable being passed, while others put all of the hidden +// length arguments at the end of the argument list. Define this if +// the lengths are at the end of the argument list. This is usually the +// case for most unix Fortran compilers, but is (by default) false for +// Visual Fortran under Windows. +#define STRING_LEN_AT_END + + +// Define this if Fortran adds a trailing underscore to names in object files. +// For linux and most unix systems, this is the case. +#define FTN_TRAILING_UNDERSCORE + + +//-------- LAPACK / BLAS --------- + +// Define if you are using LAPACK and BLAS from the Intel Math Kernel +// Library +/* #undef HAVE_INTEL_MKL */ + +#define LAPACK_FTN_STRING_LEN_AT_END +#define LAPACK_NAMES_LOWERCASE +#define LAPACK_FTN_TRAILING_UNDERSCORE + + +//--------- Cantera -------------- + + +//--------- CKReader ------------- + + + +//--------- CtLib ---------------- + + + +#endif diff --git a/config.h.in b/config.h.in new file mode 100755 index 000000000..fc6b8ff45 --- /dev/null +++ b/config.h.in @@ -0,0 +1,58 @@ +// +// Run the 'configure' script to generate 'config.h' from this input file. +// +#ifndef CT_CONFIG_H +#define CT_CONFIG_H + + +//------------------------ Fortran settings -------------------// + + +// define types doublereal, integer, and ftnlen to match the +// corresponding Fortran data types on your system. The defaults +// are OK for most systems + +typedef double doublereal; // Fortran double precision +typedef int integer; // Fortran integer +typedef int ftnlen; // Fortran hidden string length type + + +// Fortran compilers pass character strings in argument lists by +// adding a hidden argement with the length of the string. Some +// compilers add the hidden length argument immediately after the +// CHARACTER variable being passed, while others put all of the hidden +// length arguments at the end of the argument list. Define this if +// the lengths are at the end of the argument list. This is usually the +// case for most unix Fortran compilers, but is (by default) false for +// Visual Fortran under Windows. +#define STRING_LEN_AT_END + + +// Define this if Fortran adds a trailing underscore to names in object files. +// For linux and most unix systems, this is the case. +#define FTN_TRAILING_UNDERSCORE + + +//-------- LAPACK / BLAS --------- + +// Define if you are using LAPACK and BLAS from the Intel Math Kernel +// Library +#undef HAVE_INTEL_MKL + +#define LAPACK_FTN_STRING_LEN_AT_END +#define LAPACK_NAMES_LOWERCASE +#define LAPACK_FTN_TRAILING_UNDERSCORE + + +//--------- Cantera -------------- + + +//--------- CKReader ------------- + + + +//--------- CtLib ---------------- + + + +#endif diff --git a/config/.cvsignore b/config/.cvsignore new file mode 100644 index 000000000..fad0e9b3b --- /dev/null +++ b/config/.cvsignore @@ -0,0 +1,2 @@ +config.status +config.log diff --git a/config/Cantera.README b/config/Cantera.README new file mode 100755 index 000000000..8d1c8b69c --- /dev/null +++ b/config/Cantera.README @@ -0,0 +1 @@ + diff --git a/config/config.guess b/config/config.guess new file mode 100755 index 000000000..ed2e03b7f --- /dev/null +++ b/config/config.guess @@ -0,0 +1,1321 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-03-20' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + + +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int dummy(){}" > $dummy.c ; + for c in cc gcc c89 c99 ; do + ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ; + if test $? = 0 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + rm -f $dummy.c $dummy.o $dummy.rel ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + cat <$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + eval $set_cc_for_build + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + 2-1307) + UNAME_MACHINE="alphaev68" + ;; + esac + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy` + if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi + rm -f $dummy.c $dummy + fi ;; + esac + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3D:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:3*) + echo i386-pc-interix3 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + rm -f $dummy.c + test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + rm -f $dummy.c + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config/config.h.in b/config/config.h.in new file mode 100755 index 000000000..e8506e7ba --- /dev/null +++ b/config/config.h.in @@ -0,0 +1,12 @@ + +// define STORE_MOLE_FRACTIONS if you want Cantera to internally +// represent the composition of a mixture as mole fractions. Usually +// the best choice. +#define STORE_MOLE_FRACTIONS + +// define STORE_MASS_FRACTIONS if you want Cantera to internally +// represent the composition of a mixture as mass fractions. Usually +// results in slightly worse performance, but may not in all cases. +//#define STORE_MASS_FRACTIONS +#undef STORE_MASS_FRACTIONS + diff --git a/config/config.sub b/config/config.sub new file mode 100755 index 000000000..f3657978c --- /dev/null +++ b/config/config.sub @@ -0,0 +1,1443 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-03-07' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | c4x | clipper \ + | d10v | d30v | dsp16xx \ + | fr30 \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips | mips16 | mips64 | mips64el | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el | mips64vr4300 \ + | mips64vr4300el | mips64vr5000 | mips64vr5000el \ + | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \ + | mipsisa32 | mipsisa64 \ + | mn10200 | mn10300 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[34] | sh[34]eb | shbe | shle | sh64 \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c54x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | m32r-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \ + | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \ + | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* | sh64-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i686-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3d) + basic_machine=alpha-cray + os=-unicos + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + windows32) + basic_machine=i386-pc + os=-windows32-msvcrt + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh3eb | sh4eb) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config/configure b/config/configure new file mode 100755 index 000000000..4b8c8f28e --- /dev/null +++ b/config/configure @@ -0,0 +1,3741 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by Autoconf 2.52. +# +# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Name of the executable. +as_me=`echo "$0" |sed 's,.*[\\/],,'` + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +as_executable_p="test -f" + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + +# NLS nuisances. +$as_unset LANG || test "${LANG+set}" != set || { LANG=C; export LANG; } +$as_unset LC_ALL || test "${LC_ALL+set}" != set || { LC_ALL=C; export LC_ALL; } +$as_unset LC_TIME || test "${LC_TIME+set}" != set || { LC_TIME=C; export LC_TIME; } +$as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set || { LC_CTYPE=C; export LC_CTYPE; } +$as_unset LANGUAGE || test "${LANGUAGE+set}" != set || { LANGUAGE=C; export LANGUAGE; } +$as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set || { LC_COLLATE=C; export LC_COLLATE; } +$as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set || { LC_NUMERIC=C; export LC_NUMERIC; } +$as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set || { LC_MESSAGES=C; export LC_MESSAGES; } + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=:; export CDPATH; } + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +cross_compiling=no +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +ac_unique_file="Cantera.README" +ac_default_prefix=/usr/local + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_prev= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute path for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute path for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: should be removed in autoconf 3.0. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo "$ac_prog" | sed 's%[\\/][^\\/][^\\/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CXX_set=${CXX+set} +ac_env_CXX_value=$CXX +ac_cv_env_CXX_set=${CXX+set} +ac_cv_env_CXX_value=$CXX +ac_env_CXXFLAGS_set=${CXXFLAGS+set} +ac_env_CXXFLAGS_value=$CXXFLAGS +ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set} +ac_cv_env_CXXFLAGS_value=$CXXFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_F77_set=${F77+set} +ac_env_F77_value=$F77 +ac_cv_env_F77_set=${F77+set} +ac_cv_env_F77_value=$F77 +ac_env_FFLAGS_set=${FFLAGS+set} +ac_env_FFLAGS_value=$FFLAGS +ac_cv_env_FFLAGS_set=${FFLAGS+set} +ac_cv_env_FFLAGS_value=$FFLAGS + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat < if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + CC C compiler command + CFLAGS C compiler flags + F77 Fortran 77 compiler command + FFLAGS Fortran 77 compiler flags + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +EOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_subdir in : $ac_subdirs_all; do test "x$ac_subdir" = x: && continue + cd $ac_subdir + # A "../" for each directory in /$ac_subdir. + ac_dots=`echo $ac_subdir | + sed 's,^\./,,;s,[^/]$,&/,;s,[^/]*/,../,g'` + + case $srcdir in + .) # No --srcdir option. We are building in place. + ac_sub_srcdir=$srcdir ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_sub_srcdir=$srcdir/$ac_subdir ;; + *) # Relative path. + ac_sub_srcdir=$ac_dots$srcdir/$ac_subdir ;; + esac + + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_sub_srcdir/configure.gnu; then + echo + $SHELL $ac_sub_srcdir/configure.gnu --help=recursive + elif test -f $ac_sub_srcdir/configure; then + echo + $SHELL $ac_sub_srcdir/configure --help=recursive + elif test -f $ac_sub_srcdir/configure.ac || + test -f $ac_sub_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_subdir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\EOF + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +EOF + exit 0 +fi +exec 5>config.log +cat >&5 </dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +PATH = $PATH + +_ASUNAME +} >&5 + +cat >&5 <\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + ac_sep=" " ;; + *) ac_configure_args="$ac_configure_args$ac_sep$ac_arg" + ac_sep=" " ;; + esac + # Get rid of the leading space. +done + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + echo >&5 + echo "## ----------------- ##" >&5 + echo "## Cache variables. ##" >&5 + echo "## ----------------- ##" >&5 + echo >&5 + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} >&5 + sed "/^$/d" confdefs.h >conftest.log + if test -s conftest.log; then + echo >&5 + echo "## ------------ ##" >&5 + echo "## confdefs.h. ##" >&5 + echo "## ------------ ##" >&5 + echo >&5 + cat conftest.log >&5 + fi + (echo; echo) >&5 + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" >&5 + echo "$as_me: exit $exit_status" >&5 + rm -rf conftest* confdefs* core core.* *.core conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:840: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + cat "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:858: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:862: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:868: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:870: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:872: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. It doesn't matter if + # we pass some twice (in addition to the command line arguments). + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + *) ac_configure_args="$ac_configure_args $ac_var=$ac_new_val" + ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:891: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:893: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac +echo "#! $SHELL" >conftest.sh +echo "exit 0" >>conftest.sh +chmod +x conftest.sh +if { (echo "$as_me:913: PATH=\".;.\"; conftest.sh") >&5 + (PATH=".;."; conftest.sh) 2>&5 + ac_status=$? + echo "$as_me:916: \$? = $ac_status" >&5 + (exit $ac_status); }; then + ac_path_separator=';' +else + ac_path_separator=: +fi +PATH_SEPARATOR="$ac_path_separator" +rm -f conftest.sh + +ac_config_headers="$ac_config_headers ../config.h" + +ac_aux_dir= +for ac_dir in . $srcdir/.; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:944: error: cannot find install-sh or install.sh in . $srcdir/." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in . $srcdir/." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +cat >>confdefs.h <<\EOF +#define NDEBUG 1 +EOF + +ac_sys_system=`uname -s` +ac_sys_release=`uname -r` + +if test "x${prefix}" = "xNONE"; then + prefix=${ac_default_prefix} + +fi +CANTERA_LIBDIR=$prefix/lib/cantera +CANTERA_INCDIR=$prefix/include/cantera + +ctroot=`(cd ..;pwd)` + +# Make sure we can run config.sub. +$ac_config_sub sun4 >/dev/null 2>&1 || + { { echo "$as_me:970: error: cannot run $ac_config_sub" >&5 +echo "$as_me: error: cannot run $ac_config_sub" >&2;} + { (exit 1); exit 1; }; } + +echo "$as_me:974: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6 +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_build_alias=$build_alias +test -z "$ac_cv_build_alias" && + ac_cv_build_alias=`$ac_config_guess` +test -z "$ac_cv_build_alias" && + { { echo "$as_me:983: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || + { { echo "$as_me:987: error: $ac_config_sub $ac_cv_build_alias failed." >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed." >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:992: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6 +build=$ac_cv_build +build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + +echo "$as_me:999: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6 +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_host_alias=$host_alias +test -z "$ac_cv_host_alias" && + ac_cv_host_alias=$ac_cv_build_alias +ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || + { { echo "$as_me:1008: error: $ac_config_sub $ac_cv_host_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:1013: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6 +host=$ac_cv_host +host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + +echo "$as_me:1020: checking target system type" >&5 +echo $ECHO_N "checking target system type... $ECHO_C" >&6 +if test "${ac_cv_target+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_target_alias=$target_alias +test "x$ac_cv_target_alias" = "x" && + ac_cv_target_alias=$ac_cv_host_alias +ac_cv_target=`$ac_config_sub $ac_cv_target_alias` || + { { echo "$as_me:1029: error: $ac_config_sub $ac_cv_target_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_target_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:1034: result: $ac_cv_target" >&5 +echo "${ECHO_T}$ac_cv_target" >&6 +target=$ac_cv_target +target_cpu=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + +#case "$target" in +#mips-sgi-irix*.*) +# if test -z "$CXX"; then CXX=CC; fi +# if test -z "$F77"; then F77=f77; fi +# if test -z "$F90"; then F90=f90; fi +# if test -z "$CC"; then CC=cc; fi +# if test -z "$FFLAGS"; then FFLAGS='-O2 -static'; fi +# if test -z "$CXX_DEPENDS"; then CXX_DEPENDS='-M'; fi +# if test -z "$CXXFLAGS"; then CXXFLAGS='-O2 -ptused -LANG:std'; fi;; +#esac + +#if test -z "$CXXFLAGS"; then CXXFLAGS='-O2'; fi + +if test -z "$MAKE"; then MAKE='make'; fi + +#if test -z "$ARCHIVE"; then ARCHIVE='ar ruv'; fi + +#if test -z "$SOEXT"; then SOEXT='so'; fi + +if test -z "$SHARED"; then SHARED='-shared'; fi + +if test -z "$PIC"; then PIC='-fPIC'; fi + +#if test -z "$LCXX_FLAGS"; then LCXX_FLAGS="$CXXFLAGS"; fi + +#if test -z "$LCXX_END_LIBS"; then LCXX_END_LIBS='-lm'; fi + +######################################################### +# The Cantera Kernel +######################################################### +KERNEL='base' +BUILD_CK= + +NEED_CKREADER= +NEED_BLAS= +NEED_LAPACK= +NEED_RECIPES= +NEED_MATH= +NEED_TPX= +NEED_CVODE= +NEED_TRANSPORT= +NEED_ZEROD= +NEED_ONED= + +if test "$ENABLE_THERMO" = "y"; then KERNEL=$KERNEL' 'thermo; fi +if test "$ENABLE_KINETICS" = "y"; then KERNEL=$KERNEL' 'kinetics; fi + +if test "$ENABLE_CK" = "y" +then KERNEL=$KERNEL' 'ck +BUILD_CK=1 +NEED_CKREADER=1 +fi + +if test "$ENABLE_TRANSPORT" = "y" +then KERNEL=$KERNEL' 'trprops +NEED_BLAS=1 +NEED_LAPACK=1 +NEED_MATH=1 +NEED_TRANSPORT=1 +fi + +if test "$ENABLE_EQUIL" = "y" +then KERNEL=$KERNEL' 'equil +NEED_BLAS=1 +NEED_LAPACK=1 +NEED_RECIPES=1 +fi + +if test "$ENABLE_REACTORS" = "y" +then KERNEL=$KERNEL' 'reactor +NEED_CVODE=1 +NEED_ZEROD=1 +fi + +if test "$ENABLE_SOLVERS" = "y" +then KERNEL=$KERNEL' 'solvers +NEED_CVODE=1 +NEED_MATH=1 +fi + +if test "$ENABLE_FLOW1D" = "y" +then KERNEL=$KERNEL' 'flow1D +NEED_BLAS=1 +NEED_LAPACK=1 +NEED_MATH=1 +NEED_ONED=1 +fi + +if test "$ENABLE_RXNPATH" = "y" +then KERNEL=$KERNEL' 'rpath +fi + +if test "$ENABLE_TPX" = "y" +then KERNEL=$KERNEL' 'tpx +NEED_TPX=1 +fi + +######################################################## +# BLAS and LAPACK +######################################################## +# +# if lapack and blas libraries have been specified, then skip building the +# supplied libraries + +build_lapack=0 +if test -z "$LAPACK_LIBRARY"; then LAPACK_LIBRARY=-lctlapack; build_lapack=1; fi + +build_blas=0 +if test -z "$BLAS_LIBRARY"; then BLAS_LIBRARY=-lctblas; build_blas=1; fi + +LOCAL_LIBS= + +if test -n "$NEED_ONED" +then LOCAL_LIBS=$LOCAL_LIBS' '-loneD +fi + +if test -n "$NEED_ZEROD" +then LOCAL_LIBS=$LOCAL_LIBS' '-lzeroD +fi + +if test -n "$NEED_TRANSPORT" +then LOCAL_LIBS=$LOCAL_LIBS' '-ltransport +fi + +if test -n "$NEED_CKREADER" +then LOCAL_LIBS=$LOCAL_LIBS' '-lconverters +fi + +LOCAL_LIBS=$LOCAL_LIBS' '-lcantera + +if test -n "$NEED_RECIPES" +then LOCAL_LIBS=$LOCAL_LIBS' '-lrecipes +fi + +if test -n "$NEED_CVODE" +then LOCAL_LIBS=$LOCAL_LIBS' '-lcvode +fi + +if test -n "$NEED_LAPACK" +then LOCAL_LIBS=$LOCAL_LIBS' '$LAPACK_LIBRARY +fi + +if test -n "$NEED_MATH" +then LOCAL_LIBS=$LOCAL_LIBS' '-lctmath +fi + +if test -n "$NEED_BLAS" +then LOCAL_LIBS=$LOCAL_LIBS' '$BLAS_LIBRARY +fi + +if test -n "$NEED_TPX" +then LOCAL_LIBS=$LOCAL_LIBS' '-ltpx +fi + +# +# Cantera directory structure +# +if test -z "$CANTERA_ROOT"; then CANTERA_ROOT=$prefix/cantera; fi +#AC_SUBST(CANTERA_ROOT) +#if test -z "$CANTERA_LIBDIR"; then CANTERA_LIBDIR=$CANTERA_ROOT/lib; fi + +#if test -z "$CANTERA_INCDIR"; then CANTERA_INCDIR=$CANTERA_ROOT/include; fi + +if test -z "$CT_TOOLS_BIN"; then CT_TOOLS_BIN=$CANTERA_ROOT/tools/bin; fi + +if test -z "$CANTERA_BINDIR"; then CANTERA_BINDIR=$CANTERA_ROOT/bin; fi + +if test -z "$CANTERA_EXAMPLES_DIR"; then CANTERA_EXAMPLES_DIR=$CANTERA_ROOT/examples; fi + +if test -z "$CANTERA_DATA_DIR"; then CANTERA_DATA_DIR=$CANTERA_ROOT/data; fi + +#------------------------------------------------- +# Language Interfaces +#------------------------------------------------- + +BUILD_CLIB=0 +# +# Fortran 90 Interface +# +BUILD_F90=0 +if test "$BUILD_FORTRAN_90_INTERFACE" = "y"; then BUILD_F90=1; BUILD_CLIB=1; fi + +# +# Python Interface +# +BUILD_PYTHON=0 +if test "$BUILD_PYTHON_INTERFACE" = "y"; then BUILD_PYTHON=1; BUILD_CLIB=1; fi + +# +# Matlab Interface +# +BUILD_MATLAB=0 +if test "$BUILD_MATLAB_TOOLBOX" = "y"; then BUILD_MATLAB=1; BUILD_CLIB=1; fi + +#------------------------------------------------- + +export_name=$target + +ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -n "$ac_tool_prefix"; then + for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:1256: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" +echo "$as_me:1271: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + echo "$as_me:1279: result: $CXX" >&5 +echo "${ECHO_T}$CXX" >&6 +else + echo "$as_me:1282: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:1295: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_ac_ct_CXX="$ac_prog" +echo "$as_me:1310: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + echo "$as_me:1318: result: $ac_ct_CXX" >&5 +echo "${ECHO_T}$ac_ct_CXX" >&6 +else + echo "$as_me:1321: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CXX" && break +done +test -n "$ac_ct_CXX" || ac_ct_CXX="g++" + + CXX=$ac_ct_CXX +fi + +# Provide some information about the compiler. +echo "$as_me:1333:" \ + "checking for C++ compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:1336: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:1339: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:1341: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:1344: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:1346: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:1349: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +#line 1353 "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:1369: checking for C++ compiler default output" >&5 +echo $ECHO_N "checking for C++ compiler default output... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:1372: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:1375: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. +for ac_file in `ls a.exe conftest.exe 2>/dev/null; + ls a.out conftest 2>/dev/null; + ls a.* conftest.* 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb ) ;; + a.out ) # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool --akim. + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +{ { echo "$as_me:1398: error: C++ compiler cannot create executables" >&5 +echo "$as_me: error: C++ compiler cannot create executables" >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:1404: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:1409: checking whether the C++ compiler works" >&5 +echo $ECHO_N "checking whether the C++ compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:1415: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:1418: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:1425: error: cannot run C++ compiled programs. +If you meant to cross compile, use \`--host'." >&5 +echo "$as_me: error: cannot run C++ compiled programs. +If you meant to cross compile, use \`--host'." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:1433: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:1440: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:1442: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:1445: checking for executable suffix" >&5 +echo $ECHO_N "checking for executable suffix... $ECHO_C" >&6 +if { (eval echo "$as_me:1447: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:1450: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in `(ls conftest.exe; ls conftest; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:1466: error: cannot compute EXEEXT: cannot compile and link" >&5 +echo "$as_me: error: cannot compute EXEEXT: cannot compile and link" >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:1472: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:1478: checking for object suffix" >&5 +echo $ECHO_N "checking for object suffix... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 1484 "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:1496: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:1499: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +{ { echo "$as_me:1511: error: cannot compute OBJEXT: cannot compile" >&5 +echo "$as_me: error: cannot compute OBJEXT: cannot compile" >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:1518: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:1522: checking whether we are using the GNU C++ compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6 +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 1528 "configure" +#include "confdefs.h" + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:1543: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:1546: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:1549: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:1552: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_compiler_gnu=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:1564: result: $ac_cv_cxx_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6 +GXX=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +CXXFLAGS="-g" +echo "$as_me:1570: checking whether $CXX accepts -g" >&5 +echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cxx_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 1576 "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:1588: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:1591: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:1594: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:1597: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_prog_cxx_g=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:1607: result: $ac_cv_prog_cxx_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6 +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +for ac_declaration in \ + ''\ + '#include ' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +#line 1634 "configure" +#include "confdefs.h" +#include +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:1647: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:1650: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:1653: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:1656: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +continue +fi +rm -f conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +#line 1666 "configure" +#include "confdefs.h" +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:1678: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:1681: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:1684: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:1687: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:1717: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_CC="${ac_tool_prefix}gcc" +echo "$as_me:1732: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:1740: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:1743: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:1752: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_ac_ct_CC="gcc" +echo "$as_me:1767: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:1775: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:1778: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:1791: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_CC="${ac_tool_prefix}cc" +echo "$as_me:1806: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:1814: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:1817: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:1826: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_ac_ct_CC="cc" +echo "$as_me:1841: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:1849: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:1852: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:1865: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue +fi +ac_cv_prog_CC="cc" +echo "$as_me:1885: found $ac_dir/$ac_word" >&5 +break +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" ${1+"$@"} + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:1907: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:1910: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:1921: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_CC="$ac_tool_prefix$ac_prog" +echo "$as_me:1936: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:1944: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:1947: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:1960: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_ac_ct_CC="$ac_prog" +echo "$as_me:1975: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:1983: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:1986: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + +test -z "$CC" && { { echo "$as_me:1998: error: no acceptable cc found in \$PATH" >&5 +echo "$as_me: error: no acceptable cc found in \$PATH" >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:2003:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:2006: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:2009: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:2011: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:2014: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:2016: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:2019: \$? = $ac_status" >&5 + (exit $ac_status); } + +echo "$as_me:2022: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 2028 "configure" +#include "confdefs.h" + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:2043: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:2046: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:2049: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2052: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_compiler_gnu=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:2064: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:2070: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line 2076 "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:2088: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:2091: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:2094: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2097: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_prog_cc_g=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:2107: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:2134: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:2137: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:2140: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2143: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + ''\ + '#include ' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +#line 2155 "configure" +#include "confdefs.h" +#include +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:2168: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:2171: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:2174: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2177: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +continue +fi +rm -f conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +#line 2187 "configure" +#include "confdefs.h" +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:2199: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:2202: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:2205: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2208: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:2247: checking for a BSD compatible install" >&5 +echo $ECHO_N "checking for a BSD compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_IFS=$IFS; IFS=$ac_path_separator + for ac_dir in $PATH; do + IFS=$ac_save_IFS + # Account for people who put trailing slashes in PATH elements. + case $ac_dir/ in + / | ./ | .// | /cC/* \ + | /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* \ + | /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if $as_executable_p "$ac_dir/$ac_prog"; then + if test $ac_prog = install && + grep dspmsg "$ac_dir/$ac_prog" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$ac_dir/$ac_prog" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:2296: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +#--------------------------------- +# Fortran +#--------------------------------- + +ac_ext=f +ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' +ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_f77_compiler_gnu +if test -n "$ac_tool_prefix"; then + for ac_prog in g77 f77 xlf cf77 cft77 frt pgf77 fl32 af77 fort77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 lf95 g95 fc + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:2320: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$F77"; then + ac_cv_prog_F77="$F77" # Let the user override the test. +else + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_F77="$ac_tool_prefix$ac_prog" +echo "$as_me:2335: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +F77=$ac_cv_prog_F77 +if test -n "$F77"; then + echo "$as_me:2343: result: $F77" >&5 +echo "${ECHO_T}$F77" >&6 +else + echo "$as_me:2346: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$F77" && break + done +fi +if test -z "$F77"; then + ac_ct_F77=$F77 + for ac_prog in g77 f77 xlf cf77 cft77 frt pgf77 fl32 af77 fort77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 lf95 g95 fc +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:2359: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_F77"; then + ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test. +else + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_ac_ct_F77="$ac_prog" +echo "$as_me:2374: found $ac_dir/$ac_word" >&5 +break +done + +fi +fi +ac_ct_F77=$ac_cv_prog_ac_ct_F77 +if test -n "$ac_ct_F77"; then + echo "$as_me:2382: result: $ac_ct_F77" >&5 +echo "${ECHO_T}$ac_ct_F77" >&6 +else + echo "$as_me:2385: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_F77" && break +done + + F77=$ac_ct_F77 +fi + +# Provide some information about the compiler. +echo "$as_me:2396:" \ + "checking for Fortran 77 compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:2399: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:2402: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:2404: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:2407: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:2409: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:2412: \$? = $ac_status" >&5 + (exit $ac_status); } + +# If we don't use `.F' as extension, the preprocessor is not run on the +# input file. +ac_save_ext=$ac_ext +ac_ext=F +echo "$as_me:2419: checking whether we are using the GNU Fortran 77 compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU Fortran 77 compiler... $ECHO_C" >&6 +if test "${ac_cv_f77_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF + program main +#ifndef __GNUC__ + choke me +#endif + + end +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:2433: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:2436: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:2439: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2442: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_compiler_gnu=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_cv_f77_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:2454: result: $ac_cv_f77_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6 +ac_ext=$ac_save_ext +G77=`test $ac_compiler_gnu = yes && echo yes` +ac_test_FFLAGS=${FFLAGS+set} +ac_save_FFLAGS=$FFLAGS +FFLAGS= +echo "$as_me:2461: checking whether $F77 accepts -g" >&5 +echo $ECHO_N "checking whether $F77 accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_f77_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + FFLAGS=-g +cat >conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:2473: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:2476: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:2479: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2482: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_f77_g=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_prog_f77_g=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext + +fi +echo "$as_me:2493: result: $ac_cv_prog_f77_g" >&5 +echo "${ECHO_T}$ac_cv_prog_f77_g" >&6 +if test "$ac_test_FFLAGS" = set; then + FFLAGS=$ac_save_FFLAGS +elif test $ac_cv_prog_f77_g = yes; then + if test "$G77" = yes; then + FFLAGS="-g -O2" + else + FFLAGS="-g" + fi +else + if test "$G77" = yes; then + FFLAGS="-O2" + else + FFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +# if G77 is defined, then add a flag to turn off adding a second underscore +# to procedures that have an underscore in the name +if test -n "$G77"; then + FFLAGS=$FFLAGS' -fno-second-underscore' +fi +SHARED_CTLIB=0 +OS_IS_DARWIN=0 +mex_ext=mexglx + +ac_ext=f +ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' +ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_f77_compiler_gnu +echo "$as_me:2529: checking how to get verbose linking output from $F77" >&5 +echo $ECHO_N "checking how to get verbose linking output from $F77... $ECHO_C" >&6 +if test "${ac_cv_prog_f77_v+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +cat >conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:2541: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:2544: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:2547: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:2550: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_f77_v= +# Try some options frequently used verbose output +for ac_verb in -v -verbose --verbose -V -\#\#\#; do + ac_ext=f +ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' +ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_f77_compiler_gnu + +cat >conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF + +# Compile and link our simple test program by passing a flag (argument +# 1 to this macro) to the Fortran 77 compiler in order to get +# "verbose" output that we can then parse for the Fortran 77 linker +# flags. +ac_save_FFLAGS=$FFLAGS +FFLAGS="$FFLAGS $ac_verb" +(eval echo $as_me:2572: \"$ac_link\") >&5 +ac_f77_v_output=`eval $ac_link 5>&1 2>&1 | grep -v 'Driving:'` +echo "$ac_f77_v_output" >&5 +FFLAGS=$ac_save_FFLAGS + +rm -f conftest* +ac_ext=f +ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' +ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_f77_compiler_gnu + +# If we are using xlf then replace all the commas with spaces. +if echo $ac_f77_v_output | grep xlfentry >/dev/null 2>&1; then + ac_f77_v_output=`echo $ac_f77_v_output | sed 's/,/ /g'` +fi + +# If we are using Cray Fortran then delete quotes. +# Use "\"" instead of '"' for font-lock-mode. +# FIXME: a more general fix for quoted arguments with spaces? +if echo $ac_f77_v_output | grep cft90 >/dev/null 2>&1; then + ac_f77_v_output=`echo $ac_f77_v_output | sed "s/\"//g"` +fi + # look for -l* and *.a constructs in the output + for ac_arg in $ac_f77_v_output; do + case $ac_arg in + [\\/]*.a | ?:[\\/]*.a | -[lLRu]*) + ac_cv_prog_f77_v=$ac_verb + break 2 ;; + esac + done +done +if test -z "$ac_cv_prog_f77_v"; then + { echo "$as_me:2604: WARNING: cannot determine how to obtain linking information from $F77" >&5 +echo "$as_me: WARNING: cannot determine how to obtain linking information from $F77" >&2;} +fi +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +{ echo "$as_me:2610: WARNING: compilation failed" >&5 +echo "$as_me: WARNING: compilation failed" >&2;} +fi +rm -f conftest.$ac_objext conftest.$ac_ext + +fi +echo "$as_me:2616: result: $ac_cv_prog_f77_v" >&5 +echo "${ECHO_T}$ac_cv_prog_f77_v" >&6 +echo "$as_me:2618: checking for Fortran 77 libraries" >&5 +echo $ECHO_N "checking for Fortran 77 libraries... $ECHO_C" >&6 +if test "${ac_cv_flibs+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "x$FLIBS" != "x"; then + ac_cv_flibs="$FLIBS" # Let the user override the test. +else + +ac_ext=f +ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' +ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_f77_compiler_gnu + +cat >conftest.$ac_ext <<_ACEOF + program main + + end +_ACEOF + +# Compile and link our simple test program by passing a flag (argument +# 1 to this macro) to the Fortran 77 compiler in order to get +# "verbose" output that we can then parse for the Fortran 77 linker +# flags. +ac_save_FFLAGS=$FFLAGS +FFLAGS="$FFLAGS $ac_cv_prog_f77_v" +(eval echo $as_me:2644: \"$ac_link\") >&5 +ac_f77_v_output=`eval $ac_link 5>&1 2>&1 | grep -v 'Driving:'` +echo "$ac_f77_v_output" >&5 +FFLAGS=$ac_save_FFLAGS + +rm -f conftest* +ac_ext=f +ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' +ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_f77_compiler_gnu + +# If we are using xlf then replace all the commas with spaces. +if echo $ac_f77_v_output | grep xlfentry >/dev/null 2>&1; then + ac_f77_v_output=`echo $ac_f77_v_output | sed 's/,/ /g'` +fi + +# If we are using Cray Fortran then delete quotes. +# Use "\"" instead of '"' for font-lock-mode. +# FIXME: a more general fix for quoted arguments with spaces? +if echo $ac_f77_v_output | grep cft90 >/dev/null 2>&1; then + ac_f77_v_output=`echo $ac_f77_v_output | sed "s/\"//g"` +fi + +ac_cv_flibs= + +# Save positional arguments (if any) +ac_save_positional="$@" + +set X $ac_f77_v_output +while test $# != 1; do + shift + ac_arg=$1 + case $ac_arg in + [\\/]*.a | ?:[\\/]*.a) + + ac_exists=false + for ac_i in $ac_cv_flibs; do + if test x"$ac_arg" = x"$ac_i"; then + ac_exists=true + break + fi + done + + if test x"$ac_exists" = xtrue; then + : +else + ac_cv_flibs="$ac_cv_flibs $ac_arg" +fi + + ;; + -bI:*) + + ac_exists=false + for ac_i in $ac_cv_flibs; do + if test x"$ac_arg" = x"$ac_i"; then + ac_exists=true + break + fi + done + + if test x"$ac_exists" = xtrue; then + : +else + if test "$ac_compiler_gnu" = yes; then + for ac_link_opt in $ac_arg; do + ac_cv_flibs="$ac_cv_flibs -Xlinker $ac_link_opt" + done +else + ac_cv_flibs="$ac_cv_flibs $ac_arg" +fi +fi + + ;; + # Ignore these flags. + -lang* | -lcrt0.o | -lc | -lgcc | -LANG:=*) + ;; + -lkernel32) + test x"$CYGWIN" != xyes && ac_cv_flibs="$ac_cv_flibs $ac_arg" + ;; + -[LRuY]) + # These flags, when seen by themselves, take an argument. + # We remove the space between option and argument and re-iterate + # unless we find an empty arg or a new option (starting with -) + case $2 in + "" | -*);; + *) + ac_arg="$ac_arg$2" + shift; shift + set X $ac_arg "$@" + ;; + esac + ;; + -YP,*) + for ac_j in `echo $ac_arg | sed -e 's/-YP,/-L/;s/:/ -L/g'`; do + + ac_exists=false + for ac_i in $ac_cv_flibs; do + if test x"$ac_j" = x"$ac_i"; then + ac_exists=true + break + fi + done + + if test x"$ac_exists" = xtrue; then + : +else + ac_arg="$ac_arg $ac_j" + ac_cv_flibs="$ac_cv_flibs $ac_j" +fi + + done + ;; + -[lLR]*) + + ac_exists=false + for ac_i in $ac_cv_flibs; do + if test x"$ac_arg" = x"$ac_i"; then + ac_exists=true + break + fi + done + + if test x"$ac_exists" = xtrue; then + : +else + ac_cv_flibs="$ac_cv_flibs $ac_arg" +fi + + ;; + # Ignore everything else. + esac +done +# restore positional arguments +set X $ac_save_positional; shift + +# We only consider "LD_RUN_PATH" on Solaris systems. If this is seen, +# then we insist that the "run path" must be an absolute path (i.e. it +# must begin with a "/"). +case `(uname -sr) 2>/dev/null` in + "SunOS 5"*) + ac_ld_run_path=`echo $ac_f77_v_output | + sed -n 's,^.*LD_RUN_PATH *= *\(/[^ ]*\).*$,-R\1,p'` + test "x$ac_ld_run_path" != x && + if test "$ac_compiler_gnu" = yes; then + for ac_link_opt in $ac_ld_run_path; do + ac_cv_flibs="$ac_cv_flibs -Xlinker $ac_link_opt" + done +else + ac_cv_flibs="$ac_cv_flibs $ac_ld_run_path" +fi + ;; +esac +fi # test "x$FLIBS" = "x" + +fi +echo "$as_me:2799: result: $ac_cv_flibs" >&5 +echo "${ECHO_T}$ac_cv_flibs" >&6 +FLIBS="$ac_cv_flibs" + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +case $ac_sys_system in + Darwin*) FLIBS='-lg2c -lgcc'; SHARED_CTLIB=0; OS_IS_DARWIN=1; mex_ext=mexmac; + +esac + +# filename extensions for Fortran 77 and Fortran 90 +if test -z "$F77_EXT"; then F77_EXT=f; fi + +if test -z "$F90_EXT"; then F90_EXT=f90; fi + +if test -n "$FORT_MODULE_PATH_CMD" +then FORT_MOD_PATH=$FORT_MODULE_PATH_CMD +fi + +ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +if test -z "$CXX_EXT"; then CXX_EXT=cpp; fi + +if test -z "$OBJ_EXT"; then OBJ_EXT=$OBJEXT; fi + +if test -z "$EXE_EXT"; then EXE_EXT=$EXEEXT; fi + +local_math_libs='-lrecipes -lcvode' + +math_libs='-lrecipes -lcvode -lctmath' + +if test "$LAPACK_FTN_TRAILING_UNDERSCORE" = "y" +then cat >>confdefs.h <<\EOF +#define LAPACK_FTN_TRAILING_UNDERSCORE 1 +EOF + +fi + +if test "$LAPACK_FTN_STRING_LEN_AT_END" = "y" +then cat >>confdefs.h <<\EOF +#define LAPACK_FTN_STRING_LEN_AT_END 1 +EOF + +fi + +if test "$LAPACK_NAMES" = "lower" +then cat >>confdefs.h <<\EOF +#define LAPACK_NAMES_LOWERCASE 1 +EOF + +fi + +# from the Python configure.in file... + +# Set info about shared libraries. + +# SO is the extension of shared libraries `(including the dot!) +# -- usually .so, .sl on HP-UX, .dll on Cygwin +echo "$as_me:2866: checking SO" >&5 +echo $ECHO_N "checking SO... $ECHO_C" >&6 +if test -z "$SO" +then + case $ac_sys_system in + hp*|HP*) SO=.sl;; + CYGWIN*) SO=.dll;; + Darwin*) SO=.dylib;; + *) SO=.so;; + esac +fi +echo "$as_me:2877: result: $SO" >&5 +echo "${ECHO_T}$SO" >&6 + +ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +ac_config_files="$ac_config_files ../Cantera/Makefile ../Cantera/src/Makefile ../Cantera/src/zeroD/Makefile ../Cantera/src/oneD/Makefile ../Cantera/src/converters/Makefile ../Cantera/src/transport/Makefile ../Cantera/clib/src/Makefile ../Cantera/matlab/Makefile ../Cantera/python/Makefile ../Cantera/python/src/Makefile ../ext/lapack/Makefile ../ext/blas/Makefile ../ext/cvode/Makefile ../ext/math/Makefile ../ext/tpx/Makefile ../ext/Makefile ../ext/recipes/Makefile ../examples/Makefile ../examples/cxx/Makefile ../Makefile ../tools/Makefile ../tools/src/Makefile ../tools/src/sample.mak ../tools/templates/f77/sample.mak ../tools/testtools/Makefile ../data/inputs/Makefile ../test_problems/Makefile ../test_problems/cxx_ex/Makefile ../test_problems/silane_equil/Makefile" + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +DEFS=-DHAVE_CONFIG_H + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:2912: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +SHELL=\${CONFIG_SHELL-$SHELL} +ac_cs_invocation="\$0 \$@" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Name of the executable. +as_me=`echo "$0" |sed 's,.*[\\/],,'` + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +as_executable_p="test -f" + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + +# NLS nuisances. +$as_unset LANG || test "${LANG+set}" != set || { LANG=C; export LANG; } +$as_unset LC_ALL || test "${LC_ALL+set}" != set || { LC_ALL=C; export LC_ALL; } +$as_unset LC_TIME || test "${LC_TIME+set}" != set || { LC_TIME=C; export LC_TIME; } +$as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set || { LC_CTYPE=C; export LC_CTYPE; } +$as_unset LANGUAGE || test "${LANGUAGE+set}" != set || { LANGUAGE=C; export LANGUAGE; } +$as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set || { LC_COLLATE=C; export LC_COLLATE; } +$as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set || { LC_NUMERIC=C; export LC_NUMERIC; } +$as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set || { LC_MESSAGES=C; export LC_MESSAGES; } + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=:; export CDPATH; } + +exec 6>&1 + +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\EOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to ." +EOF + +cat >>$CONFIG_STATUS <>$CONFIG_STATUS <<\EOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + shift + set dummy "$ac_option" "$ac_optarg" ${1+"$@"} + shift + ;; + -*);; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_need_defaults=false;; + esac + + case $1 in + # Handling of the options. +EOF +cat >>$CONFIG_STATUS <>$CONFIG_STATUS <<\EOF + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:3085: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + shift + CONFIG_FILES="$CONFIG_FILES $1" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + shift + CONFIG_HEADERS="$CONFIG_HEADERS $1" + ac_need_defaults=false;; + + # This is an error. + -*) { { echo "$as_me:3104: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +exec 5>>config.log +cat >&5 << _ACEOF + +## ----------------------- ## +## Running config.status. ## +## ----------------------- ## + +This file was extended by $as_me 2.52, executed with + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + > $ac_cs_invocation +on `(hostname || uname -n) 2>/dev/null | sed 1q` + +_ACEOF +EOF + +cat >>$CONFIG_STATUS <<\EOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "../Cantera/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../Cantera/Makefile" ;; + "../Cantera/src/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../Cantera/src/Makefile" ;; + "../Cantera/src/zeroD/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../Cantera/src/zeroD/Makefile" ;; + "../Cantera/src/oneD/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../Cantera/src/oneD/Makefile" ;; + "../Cantera/src/converters/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../Cantera/src/converters/Makefile" ;; + "../Cantera/src/transport/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../Cantera/src/transport/Makefile" ;; + "../Cantera/clib/src/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../Cantera/clib/src/Makefile" ;; + "../Cantera/matlab/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../Cantera/matlab/Makefile" ;; + "../Cantera/python/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../Cantera/python/Makefile" ;; + "../Cantera/python/src/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../Cantera/python/src/Makefile" ;; + "../ext/lapack/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../ext/lapack/Makefile" ;; + "../ext/blas/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../ext/blas/Makefile" ;; + "../ext/cvode/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../ext/cvode/Makefile" ;; + "../ext/math/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../ext/math/Makefile" ;; + "../ext/tpx/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../ext/tpx/Makefile" ;; + "../ext/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../ext/Makefile" ;; + "../ext/recipes/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../ext/recipes/Makefile" ;; + "../examples/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../examples/Makefile" ;; + "../examples/cxx/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../examples/cxx/Makefile" ;; + "../Makefile" ) CONFIG_FILES="$CONFIG_FILES ../Makefile" ;; + "../tools/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../tools/Makefile" ;; + "../tools/src/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../tools/src/Makefile" ;; + "../tools/src/sample.mak" ) CONFIG_FILES="$CONFIG_FILES ../tools/src/sample.mak" ;; + "../tools/templates/f77/sample.mak" ) CONFIG_FILES="$CONFIG_FILES ../tools/templates/f77/sample.mak" ;; + "../tools/testtools/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../tools/testtools/Makefile" ;; + "../data/inputs/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../data/inputs/Makefile" ;; + "../test_problems/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../test_problems/Makefile" ;; + "../test_problems/cxx_ex/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../test_problems/cxx_ex/Makefile" ;; + "../test_problems/silane_equil/Makefile" ) CONFIG_FILES="$CONFIG_FILES ../test_problems/silane_equil/Makefile" ;; + "../config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS ../config.h" ;; + *) { { echo "$as_me:3169: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. +: ${TMPDIR=/tmp} +{ + tmp=`(umask 077 && mktemp -d -q "$TMPDIR/csXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=$TMPDIR/cs$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in $TMPDIR" >&2 + { (exit 1); exit 1; } +} + +EOF + +cat >>$CONFIG_STATUS <\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@DEFS@,$DEFS,;t t +s,@LIBS@,$LIBS,;t t +s,@ctroot@,$ctroot,;t t +s,@build@,$build,;t t +s,@build_cpu@,$build_cpu,;t t +s,@build_vendor@,$build_vendor,;t t +s,@build_os@,$build_os,;t t +s,@host@,$host,;t t +s,@host_cpu@,$host_cpu,;t t +s,@host_vendor@,$host_vendor,;t t +s,@host_os@,$host_os,;t t +s,@target@,$target,;t t +s,@target_cpu@,$target_cpu,;t t +s,@target_vendor@,$target_vendor,;t t +s,@target_os@,$target_os,;t t +s,@MAKE@,$MAKE,;t t +s,@ARCHIVE@,$ARCHIVE,;t t +s,@SOEXT@,$SOEXT,;t t +s,@SHARED@,$SHARED,;t t +s,@PIC@,$PIC,;t t +s,@LCXX_FLAGS@,$LCXX_FLAGS,;t t +s,@LCXX_END_LIBS@,$LCXX_END_LIBS,;t t +s,@KERNEL@,$KERNEL,;t t +s,@BUILD_CK@,$BUILD_CK,;t t +s,@LIB_DIR@,$LIB_DIR,;t t +s,@LAPACK_LIBRARY@,$LAPACK_LIBRARY,;t t +s,@build_lapack@,$build_lapack,;t t +s,@BLAS_LIBRARY@,$BLAS_LIBRARY,;t t +s,@build_blas@,$build_blas,;t t +s,@LOCAL_LIBS@,$LOCAL_LIBS,;t t +s,@CANTERA_LIBDIR@,$CANTERA_LIBDIR,;t t +s,@CANTERA_INCDIR@,$CANTERA_INCDIR,;t t +s,@CT_TOOLS_BIN@,$CT_TOOLS_BIN,;t t +s,@CANTERA_BINDIR@,$CANTERA_BINDIR,;t t +s,@CANTERA_EXAMPLES_DIR@,$CANTERA_EXAMPLES_DIR,;t t +s,@CANTERA_DATA_DIR@,$CANTERA_DATA_DIR,;t t +s,@CT_SHARED_LIB@,$CT_SHARED_LIB,;t t +s,@BUILD_F90@,$BUILD_F90,;t t +s,@BUILD_PYTHON@,$BUILD_PYTHON,;t t +s,@PYTHON_CMD@,$PYTHON_CMD,;t t +s,@BUILD_MATLAB@,$BUILD_MATLAB,;t t +s,@MATLAB_CMD@,$MATLAB_CMD,;t t +s,@BUILD_CLIB@,$BUILD_CLIB,;t t +s,@export_name@,$export_name,;t t +s,@CXX@,$CXX,;t t +s,@CXXFLAGS@,$CXXFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CXX@,$ac_ct_CXX,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@CXX_DEPENDS@,$CXX_DEPENDS,;t t +s,@F77@,$F77,;t t +s,@FFLAGS@,$FFLAGS,;t t +s,@ac_ct_F77@,$ac_ct_F77,;t t +s,@F90@,$F90,;t t +s,@FLIBS@,$FLIBS,;t t +s,@OS_IS_DARWIN@,$OS_IS_DARWIN,;t t +s,@SHARED_CTLIB@,$SHARED_CTLIB,;t t +s,@mex_ext@,$mex_ext,;t t +s,@F77_EXT@,$F77_EXT,;t t +s,@F90_EXT@,$F90_EXT,;t t +s,@FORT_MOD_PATH@,$FORT_MOD_PATH,;t t +s,@CXX_EXT@,$CXX_EXT,;t t +s,@OBJ_EXT@,$OBJ_EXT,;t t +s,@EXE_EXT@,$EXE_EXT,;t t +s,@local_math_libs@,$local_math_libs,;t t +s,@math_libs@,$math_libs,;t t +s,@SO@,$SO,;t t +s,@LDSHARED@,$LDSHARED,;t t +CEOF + +EOF + + cat >>$CONFIG_STATUS <<\EOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +EOF +cat >>$CONFIG_STATUS <<\EOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + { case "$ac_dir" in + [\\/]* | ?:[\\/]* ) as_incr_dir=;; + *) as_incr_dir=.;; +esac +as_dummy="$ac_dir" +for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do + case $as_mkdir_dir in + # Skip DOS drivespec + ?:) as_incr_dir=$as_mkdir_dir ;; + *) + as_incr_dir=$as_incr_dir/$as_mkdir_dir + test -d "$as_incr_dir" || mkdir "$as_incr_dir" + ;; + esac +done; } + + ac_dir_suffix="/`echo $ac_dir|sed 's,^\./,,'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo "$ac_dir_suffix" | sed 's,/[^/]*,../,g'` + else + ac_dir_suffix= ac_dots= + fi + + case $srcdir in + .) ac_srcdir=. + if test -z "$ac_dots"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_dots | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_dots$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_dots$srcdir ;; + esac + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_dots$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:3438: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated automatically by config.status. */ + configure_input="Generated automatically from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:3456: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:3469: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +EOF +cat >>$CONFIG_STATUS <>$CONFIG_STATUS <<\EOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +EOF +cat >>$CONFIG_STATUS <<\EOF + +# +# CONFIG_HEADER section. +# + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='[ ].*$,\1#\2' +ac_dC=' ' +ac_dD=',;t' +# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='$,\1#\2define\3' +ac_uC=' ' +ac_uD=',;t' + +for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + test x"$ac_file" != x- && { echo "$as_me:3530: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:3541: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:3554: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + # Remove the trailing spaces. + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + +EOF + +# Transform confdefs.h into two sed scripts, `conftest.defines' and +# `conftest.undefs', that substitutes the proper values into +# config.h.in to produce config.h. The first handles `#define' +# templates, and the second `#undef' templates. +# And first: Protect against being on the right side of a sed subst in +# config.status. Protect against being in an unquoted here document +# in config.status. +rm -f conftest.defines conftest.undefs +# Using a here document instead of a string reduces the quoting nightmare. +# Putting comments in sed scripts is not portable. +# +# `end' is used to avoid that the second main sed command (meant for +# 0-ary CPP macros) applies to n-ary macro definitions. +# See the Autoconf documentation for `clear'. +cat >confdef2sed.sed <<\EOF +s/[\\&,]/\\&/g +s,[\\$`],\\&,g +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\(\([^ (][^ (]*\)([^)]*)\)[ ]*\(.*\)$,${ac_dA}\2${ac_dB}\1${ac_dC}\3${ac_dD},gp +t end +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp +: end +EOF +# If some macros were called several times there might be several times +# the same #defines, which is useless. Nevertheless, we may not want to +# sort them, since we want the *last* AC-DEFINE to be honored. +uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines +sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs +rm -f confdef2sed.sed + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >>conftest.undefs <<\EOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +EOF + +# Break up conftest.defines because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS +echo ' if egrep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS +echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS +echo ' :' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.defines >/dev/null +do + # Write a limited-size here document to $tmp/defines.sed. + echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#define' lines. + echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/defines.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines +echo ' fi # egrep' >>$CONFIG_STATUS +echo >>$CONFIG_STATUS + +# Break up conftest.undefs because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #undef templates' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.undefs >/dev/null +do + # Write a limited-size here document to $tmp/undefs.sed. + echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#undef' + echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/undefs.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail + rm -f conftest.undefs + mv conftest.tail conftest.undefs +done +rm -f conftest.undefs + +cat >>$CONFIG_STATUS <<\EOF + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated automatically by config.status. */ + if test x"$ac_file" = x-; then + echo "/* Generated automatically by configure. */" >$tmp/config.h + else + echo "/* $ac_file. Generated automatically by configure. */" >$tmp/config.h + fi + cat $tmp/in >>$tmp/config.h + rm -f $tmp/in + if test x"$ac_file" != x-; then + if cmp -s $ac_file $tmp/config.h 2>/dev/null; then + { echo "$as_me:3671: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + ac_dir=`$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + { case "$ac_dir" in + [\\/]* | ?:[\\/]* ) as_incr_dir=;; + *) as_incr_dir=.;; +esac +as_dummy="$ac_dir" +for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do + case $as_mkdir_dir in + # Skip DOS drivespec + ?:) as_incr_dir=$as_mkdir_dir ;; + *) + as_incr_dir=$as_incr_dir/$as_mkdir_dir + test -d "$as_incr_dir" || mkdir "$as_incr_dir" + ;; + esac +done; } + + fi + rm -f $ac_file + mv $tmp/config.h $ac_file + fi + else + cat $tmp/config.h + rm -f $tmp/config.h + fi +done +EOF + +cat >>$CONFIG_STATUS <<\EOF + +{ (exit 0); exit 0; } +EOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + exec 5>/dev/null + $SHELL $CONFIG_STATUS || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + +# ) + +# $Log: configure.in,v + diff --git a/config/configure.in b/config/configure.in new file mode 100755 index 000000000..33e218ed2 --- /dev/null +++ b/config/configure.in @@ -0,0 +1,431 @@ +dnl Process this file with autoconf to produce a configure script. +define([AC_CACHE_LOAD], )dnl +define([AC_CACHE_SAVE], )dnl +AC_INIT(Cantera.README) +AC_CONFIG_HEADER(../config.h) +AC_CONFIG_AUX_DIR(.) + + +AC_DEFINE(NDEBUG) + +ac_sys_system=`uname -s` +ac_sys_release=`uname -r` + +AC_PREFIX_DEFAULT([/usr/local]) +if test "x${prefix}" = "xNONE"; then + prefix=${ac_default_prefix} + AC_SUBST(prefix) +fi +CANTERA_LIBDIR=$prefix/lib/cantera +CANTERA_INCDIR=$prefix/include/cantera + +ctroot=`(cd ..;pwd)` +AC_SUBST(ctroot) + + +AC_CANONICAL_SYSTEM() + +#case "$target" in +#mips-sgi-irix*.*) +# if test -z "$CXX"; then CXX=CC; fi +# if test -z "$F77"; then F77=f77; fi +# if test -z "$F90"; then F90=f90; fi +# if test -z "$CC"; then CC=cc; fi +# if test -z "$FFLAGS"; then FFLAGS='-O2 -static'; fi +# if test -z "$CXX_DEPENDS"; then CXX_DEPENDS='-M'; fi +# if test -z "$CXXFLAGS"; then CXXFLAGS='-O2 -ptused -LANG:std'; fi;; +#esac + +#if test -z "$CXXFLAGS"; then CXXFLAGS='-O2'; fi + +if test -z "$MAKE"; then MAKE='make'; fi +AC_SUBST(MAKE) + +#if test -z "$ARCHIVE"; then ARCHIVE='ar ruv'; fi +AC_SUBST(ARCHIVE) + +#if test -z "$SOEXT"; then SOEXT='so'; fi +AC_SUBST(SOEXT) + +if test -z "$SHARED"; then SHARED='-shared'; fi +AC_SUBST(SHARED) + +if test -z "$PIC"; then PIC='-fPIC'; fi +AC_SUBST(PIC) + +#if test -z "$LCXX_FLAGS"; then LCXX_FLAGS="$CXXFLAGS"; fi +AC_SUBST(LCXX_FLAGS) + +#if test -z "$LCXX_END_LIBS"; then LCXX_END_LIBS='-lm'; fi +AC_SUBST(LCXX_END_LIBS) + +######################################################### +# The Cantera Kernel +######################################################### +KERNEL='base' +BUILD_CK= + +NEED_CKREADER= +NEED_BLAS= +NEED_LAPACK= +NEED_RECIPES= +NEED_MATH= +NEED_TPX= +NEED_CVODE= +NEED_TRANSPORT= +NEED_ZEROD= +NEED_ONED= + +if test "$ENABLE_THERMO" = "y"; then KERNEL=$KERNEL' 'thermo; fi +if test "$ENABLE_KINETICS" = "y"; then KERNEL=$KERNEL' 'kinetics; fi + +if test "$ENABLE_CK" = "y" +then KERNEL=$KERNEL' 'ck +BUILD_CK=1 +NEED_CKREADER=1 +fi + +if test "$ENABLE_TRANSPORT" = "y" +then KERNEL=$KERNEL' 'trprops +NEED_BLAS=1 +NEED_LAPACK=1 +NEED_MATH=1 +NEED_TRANSPORT=1 +fi + +if test "$ENABLE_EQUIL" = "y" +then KERNEL=$KERNEL' 'equil +NEED_BLAS=1 +NEED_LAPACK=1 +NEED_RECIPES=1 +fi + +if test "$ENABLE_REACTORS" = "y" +then KERNEL=$KERNEL' 'reactor +NEED_CVODE=1 +NEED_ZEROD=1 +fi + +if test "$ENABLE_SOLVERS" = "y" +then KERNEL=$KERNEL' 'solvers +NEED_CVODE=1 +NEED_MATH=1 +fi + +if test "$ENABLE_FLOW1D" = "y" +then KERNEL=$KERNEL' 'flow1D +NEED_BLAS=1 +NEED_LAPACK=1 +NEED_MATH=1 +NEED_ONED=1 +fi + +if test "$ENABLE_RXNPATH" = "y" +then KERNEL=$KERNEL' 'rpath +fi + +if test "$ENABLE_TPX" = "y" +then KERNEL=$KERNEL' 'tpx +NEED_TPX=1 +fi + +AC_SUBST(KERNEL) +AC_SUBST(BUILD_CK) +AC_SUBST(LIB_DIR) + +######################################################## +# BLAS and LAPACK +######################################################## +# +# if lapack and blas libraries have been specified, then skip building the +# supplied libraries + +build_lapack=0 +if test -z "$LAPACK_LIBRARY"; then LAPACK_LIBRARY=-lctlapack; build_lapack=1; fi +AC_SUBST(LAPACK_LIBRARY) +AC_SUBST(build_lapack) + +build_blas=0 +if test -z "$BLAS_LIBRARY"; then BLAS_LIBRARY=-lctblas; build_blas=1; fi +AC_SUBST(BLAS_LIBRARY) +AC_SUBST(build_blas) + + +LOCAL_LIBS= + +if test -n "$NEED_ONED" +then LOCAL_LIBS=$LOCAL_LIBS' '-loneD +fi + +if test -n "$NEED_ZEROD" +then LOCAL_LIBS=$LOCAL_LIBS' '-lzeroD +fi + +if test -n "$NEED_TRANSPORT" +then LOCAL_LIBS=$LOCAL_LIBS' '-ltransport +fi + +if test -n "$NEED_CKREADER" +then LOCAL_LIBS=$LOCAL_LIBS' '-lconverters +fi + +LOCAL_LIBS=$LOCAL_LIBS' '-lcantera + + +if test -n "$NEED_RECIPES" +then LOCAL_LIBS=$LOCAL_LIBS' '-lrecipes +fi + +if test -n "$NEED_CVODE" +then LOCAL_LIBS=$LOCAL_LIBS' '-lcvode +fi + +if test -n "$NEED_LAPACK" +then LOCAL_LIBS=$LOCAL_LIBS' '$LAPACK_LIBRARY +fi + +if test -n "$NEED_MATH" +then LOCAL_LIBS=$LOCAL_LIBS' '-lctmath +fi + +if test -n "$NEED_BLAS" +then LOCAL_LIBS=$LOCAL_LIBS' '$BLAS_LIBRARY +fi + +if test -n "$NEED_TPX" +then LOCAL_LIBS=$LOCAL_LIBS' '-ltpx +fi + +AC_SUBST(LOCAL_LIBS) + + +# +# Cantera directory structure +# +if test -z "$CANTERA_ROOT"; then CANTERA_ROOT=$prefix/cantera; fi +#AC_SUBST(CANTERA_ROOT) +#if test -z "$CANTERA_LIBDIR"; then CANTERA_LIBDIR=$CANTERA_ROOT/lib; fi +AC_SUBST(CANTERA_LIBDIR) +#if test -z "$CANTERA_INCDIR"; then CANTERA_INCDIR=$CANTERA_ROOT/include; fi +AC_SUBST(CANTERA_INCDIR) +if test -z "$CT_TOOLS_BIN"; then CT_TOOLS_BIN=$CANTERA_ROOT/tools/bin; fi +AC_SUBST(CT_TOOLS_BIN) +if test -z "$CANTERA_BINDIR"; then CANTERA_BINDIR=$CANTERA_ROOT/bin; fi +AC_SUBST(CANTERA_BINDIR) +if test -z "$CANTERA_EXAMPLES_DIR"; then CANTERA_EXAMPLES_DIR=$CANTERA_ROOT/examples; fi +AC_SUBST(CANTERA_EXAMPLES_DIR) +if test -z "$CANTERA_DATA_DIR"; then CANTERA_DATA_DIR=$CANTERA_ROOT/data; fi +AC_SUBST(CANTERA_DATA_DIR) + + +#------------------------------------------------- +# Language Interfaces +#------------------------------------------------- + +AC_SUBST(CT_SHARED_LIB) + +BUILD_CLIB=0 +# +# Fortran 90 Interface +# +BUILD_F90=0 +if test "$BUILD_FORTRAN_90_INTERFACE" = "y"; then BUILD_F90=1; BUILD_CLIB=1; fi +AC_SUBST(BUILD_F90) + +# +# Python Interface +# +BUILD_PYTHON=0 +if test "$BUILD_PYTHON_INTERFACE" = "y"; then BUILD_PYTHON=1; BUILD_CLIB=1; fi +AC_SUBST(BUILD_PYTHON) +AC_SUBST(PYTHON_CMD) + + +# +# Matlab Interface +# +BUILD_MATLAB=0 +if test "$BUILD_MATLAB_TOOLBOX" = "y"; then BUILD_MATLAB=1; BUILD_CLIB=1; fi +AC_SUBST(BUILD_MATLAB) +AC_SUBST(MATLAB_CMD) + +AC_SUBST(BUILD_CLIB) + +#------------------------------------------------- + +export_name=$target +AC_SUBST(export_name) + + +dnl Checks for programs. +AC_PROG_CXX() +AC_PROG_CC() +AC_PROG_INSTALL + +AC_SUBST(CXX_DEPENDS) + +#--------------------------------- +# Fortran +#--------------------------------- + +AC_PROG_F77() +AC_SUBST(F90) + +# if G77 is defined, then add a flag to turn off adding a second underscore +# to procedures that have an underscore in the name +if test -n "$G77"; then + FFLAGS=$FFLAGS' -fno-second-underscore' +fi +SHARED_CTLIB=0 +OS_IS_DARWIN=0 +mex_ext=mexglx + +dnl Checks for libraries. +AC_F77_LIBRARY_LDFLAGS() +case $ac_sys_system in + Darwin*) FLIBS='-lg2c -lgcc'; SHARED_CTLIB=0; OS_IS_DARWIN=1; mex_ext=mexmac; + AC_SUBST(FLIBS) + AC_SUBST(OS_IS_DARWIN) +esac +AC_SUBST(SHARED_CTLIB) +AC_SUBST(mex_ext) + +# filename extensions for Fortran 77 and Fortran 90 +if test -z "$F77_EXT"; then F77_EXT=f; fi +AC_SUBST(F77_EXT) +if test -z "$F90_EXT"; then F90_EXT=f90; fi +AC_SUBST(F90_EXT) + + +if test -n "$FORT_MODULE_PATH_CMD" +then FORT_MOD_PATH=$FORT_MODULE_PATH_CMD +fi +AC_SUBST(FORT_MOD_PATH) + + +AC_LANG_CPLUSPLUS + +AC_OBJEXT +AC_EXEEXT + +if test -z "$CXX_EXT"; then CXX_EXT=cpp; fi +AC_SUBST(CXX_EXT) + +if test -z "$OBJ_EXT"; then OBJ_EXT=$OBJEXT; fi +AC_SUBST(OBJ_EXT) + +if test -z "$EXE_EXT"; then EXE_EXT=$EXEEXT; fi +AC_SUBST(EXE_EXT) + +dnl AC_LANG_FORTRAN77 +local_math_libs='-lrecipes -lcvode' +AC_SUBST(local_math_libs) + + +math_libs='-lrecipes -lcvode -lctmath' +AC_SUBST(math_libs) + +if test "$LAPACK_FTN_TRAILING_UNDERSCORE" = "y" +then AC_DEFINE(LAPACK_FTN_TRAILING_UNDERSCORE) +fi + +if test "$LAPACK_FTN_STRING_LEN_AT_END" = "y" +then AC_DEFINE(LAPACK_FTN_STRING_LEN_AT_END) +fi + +if test "$LAPACK_NAMES" = "lower" +then AC_DEFINE(LAPACK_NAMES_LOWERCASE) +fi + +# from the Python configure.in file... + +# Set info about shared libraries. +AC_SUBST(SO) +AC_SUBST(LDSHARED) +# SO is the extension of shared libraries `(including the dot!) +# -- usually .so, .sl on HP-UX, .dll on Cygwin +AC_MSG_CHECKING(SO) +if test -z "$SO" +then + case $ac_sys_system in + hp*|HP*) SO=.sl;; + CYGWIN*) SO=.dll;; + Darwin*) SO=.dylib;; + *) SO=.so;; + esac +fi +AC_MSG_RESULT($SO) + +dnl Checks for header files. + +dnl Checks for typedefs, structures, and compiler characteristics. + +AC_LANG_CPLUSPLUS + +dnl AC_MSG_CHECKING(for the Standard Template Library) + +dnl Checks for library functions. + +AC_OUTPUT(../Cantera/Makefile \ + ../Cantera/src/Makefile \ + ../Cantera/src/zeroD/Makefile \ + ../Cantera/src/oneD/Makefile \ + ../Cantera/src/converters/Makefile \ + ../Cantera/src/transport/Makefile \ + ../Cantera/clib/src/Makefile \ + ../Cantera/matlab/Makefile \ + ../Cantera/python/Makefile \ + ../Cantera/python/src/Makefile \ + ../ext/lapack/Makefile \ + ../ext/blas/Makefile \ + ../ext/cvode/Makefile \ + ../ext/math/Makefile \ + ../ext/tpx/Makefile \ + ../ext/Makefile \ + ../ext/recipes/Makefile \ + ../examples/Makefile \ + ../examples/cxx/Makefile \ + ../Makefile \ + ../tools/Makefile \ + ../tools/src/Makefile \ + ../tools/src/sample.mak \ + ../tools/templates/f77/sample.mak \ + ../tools/testtools/Makefile \ + ../data/inputs/Makefile \ + ../test_problems/Makefile \ + ../test_problems/cxx_ex/Makefile \ + ../test_problems/silane_equil/Makefile) +# ) + +# $Log: configure.in,v + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/install-sh b/config/install-sh new file mode 100755 index 000000000..e9de23842 --- /dev/null +++ b/config/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/configure b/configure new file mode 100755 index 000000000..46b8911de --- /dev/null +++ b/configure @@ -0,0 +1,293 @@ +#!/bin/sh +# +# $Source$ +# $Author$ +# $Revision$ +# $Date$ +# + + +####################################################################### +# +# Unix / Linux / Cygwin / Mac OS X Configuration File +# +# Edit this file to control how Cantera is built. Parameters can be set +# here, or alternatively environment variables may be set before calling +# this script. +# +# NOTE: if you make changes to this file, save it with another name +# so that it will not be overwritten if you update the source +# distribution. + +# Any parameters you are unsure of may be commented out, and +# 'configure' will attempt to find suitable values for your system. + +####################################################################### + + +#---------------------------------------------------------------------- +# Language Interfaces +#---------------------------------------------------------------------- +# + +# Cantera provides interfaces for several languages. Set to 'y' to +# build the specified interface. If you only plan to use Cantera from +# C++, you do not need to build any of these. + + +#------------ Fortran 90 -------------------------------------------- + +# Build the Fortran 90 interface. + +BUILD_FORTRAN_90_INTERFACE='n' # Fortran is temporarily not working + + +#------------ Python ------------------------------------------------- + +# Set this if you want to build the Cantera Python interface. Python +# must be installed on your system first, since the build process runs +# a python script. Python 2.0 or greater is required. Set PYTHON_CMD +# to the path to the Python interpreter to use, if there is more than +# one on your system. + +BUILD_PYTHON_INTERFACE=${BUILD_PYTHON_INTERFACE:="y"} +PYTHON_CMD=${PYTHON_CMD:=python} + + +#----------- Matlab -------------------------------------------------- + +# Set this to "y" if you want to build the Matlab toolbox. Matlab must +# be installed on your system first, since the build process runs a +# Matlab script. + +BUILD_MATLAB_TOOLBOX=${BUILD_MATLAB_TOOLBOX:="y"} +MATLAB_CMD=${MATLAB_CMD:=matlab} + + + +#---------------------------------------------------------------------- +# Kernel Configuration +#---------------------------------------------------------------------- + +# If you are only planning to use a portion of Cantera, you may only +# need a stripped-down kernel. Set those features you want enabled to +# 'y', and set those you want to skip to 'n' (actually anything but +# 'y') or comment them out. Some features are dependent on others; for +# example, enabling 'CK' automatically enables KINETICS and THERMO. + +# If you only need to use Cantera to evaluate thermodynamic, kinetic, +# and transport properties, it is sufficient to enable only KINETICS +# and TRANSPORT. + + +# thermodynamic properties +ENABLE_THERMO='y' + +# enable importing Chemkin input files +ENABLE_CK='y' + +# homogeneous and heterogeneous kinetics +ENABLE_KINETICS='y' + +# transport properties +ENABLE_TRANSPORT='y' + +# chemical equilibrium +ENABLE_EQUIL='y' + +# stirred reactor models +ENABLE_REACTORS='y' + +# One-dimensional flows +ENABLE_FLOW1D='y' + +# ODE integrators and DAE solvers +ENABLE_SOLVERS='y' + +# reaction path analysis +ENABLE_RXNPATH='y' + +# non-ideal pure substance models for a few fluids imported from the +# 'TPX' package (http://adam.caltech.edu/software/tpx) +ENABLE_TPX='n' + + + +#----------------------------------------------------------------- +# BLAS and LAPACK +#----------------------------------------------------------------- +# +# Cantera comes with Fortran versions of those parts of BLAS and +# LAPACK it requires. But if you have another version of BLAS and/or +# LAPACK you'd like to use, uncomment one or both of the following +# lines, and enter here the string that should be added to the link +# command to link to it. +# +# BLAS_LIBRARY=-lblas +# +# LAPACK_LIBRARY=-llapack +# +# The options below do not need be set if you are using the default libraries. +# +# Set to 'lower' or 'upper', depending on whether the procedure names +# in the libraries are lowercase or uppercase. If you don't know, run +# 'nm' on the library file (e.g. 'nm libblas.a') Note that the these options +# apply to both the BLAS and LAPACK libraries. +LAPACK_NAMES='lower' +LAPACK_FTN_TRAILING_UNDERSCORE='y' + +# Currently this must be set to 'y'. +LAPACK_FTN_STRING_LEN_AT_END='y' + + +#------------------------------------------------------------------ +# C++ compiler options +#------------------------------------------------------------------ +# + +# the C++ compiler to use. +# +CXX=${CXX:=g++} + +# C++ compiler flags +CXXFLAGS=${CXXFLAGS:="-O3 -Wall -Wstrict-prototypes"} + +# the C++ flags required for linking +#LCXX_FLAGS= + +# Ending libraries to tack onto the linking of all C++ programs +LCXX_END_LIBS="-lm" + +# the compiler flag to use to compile code that will be inserted into shared +# libraries. +PIC=${PIC:=-fPIC} + +# the compiler option to create a shared library from object files +SHARED=${SHARED:="-shared"} + + +#------------------------------------------------------------------- +# Fortran compiler options +#------------------------------------------------------------------- + +# Cantera uses some external procedures written in Fortran 77. +# In addition, Cantera implements an interface for Fortran 90 +# application programs. The parameters in this section apply +# to both. + +# the Fortran 77 and Fortran 90 compilers. You only need a Fortran 90 +# compiler if you are building the Fortran 90 interface. +#F77=${F77:=f77} +F90=${F90:=f90} + +# Fortran compiler flags +FFLAGS=${FFLAGS:='-O3 -Wall'} + +# the additional Fortran flags required for linking, if any +#LFORT_FLAGS = + +# Fortran 90 module directory +FORT_MODULE_DIRECTORY=${FORT_MODULE_DIRECTORY:=$CANTERA_ROOT/include/fortran} + +# Fortran 90 module search path command +FORT_MODULE_PATH_CMD=${FORT_MODULE_PATH_CMD:="-I$FORT_MODULE_DIRECTORY"} + + +#------------------------------------------------------ +# other programs +#------------------------------------------------------ + +# the command to create a static library +ARCHIVE=${ARCHIVE:="ar ruv"} + +# the command to run the 'make' utility. The Cantera Makefiles are +# compatible with the GNU make utility, so if your make utility +# doesn't work, try GNU make. +MAKE=${MAKE:=make} + +# +# file extensions +CXX_EXT=${CXX_EXT:=cpp} +F77_EXT=${F77_EXT:=f} +F90_EXT=${F90_EXT:=f90} +#OBJ_EXT= +#EXE_EXT= + + +CT_SHARED_LIB=${CT_SHARED_LIB:=ct14} + + +#----------------------------------------------------------------------- +#------------------- don't change anything below!! --------------------- +#----------------------------------------------------------------------- + +export ARCHIVE +export BLAS_LIBRARY +export BUILD_F90 +export BUILD_FORTRAN_90_INTERFACE +export BUILD_PYTHON_INTERFACE +export BUILD_MATLAB_TOOLBOX +export MATLAB_CMD +export CANTERA_ROOT +export CT_SHARED_LIB +export CXX +export CXX_EXT +export CXXFLAGS +export CXX_INCLUDES +export ENABLE_THERMO +export ENABLE_KINETICS +export ENABLE_TRANSPORT +export ENABLE_CK +export ENABLE_EQUIL +export ENABLE_REACTORS +export ENABLE_SOLVERS +export ENABLE_RXNPATH +export ENABLE_TPX +export ENABLE_FLOW1D +export EXE_EXT +export F77 +export F77_EXT +export F90 +export F90_EXT +export FFLAGS +export LAPACK_LIBRARY +export LAPACK_NAMES +export LCXX_FLAGS +export LCXX_END_LIBS +export LFORT_FLAGS +export LAPACK_FTN_STRING_LEN_AT_END +export LAPACK_FTN_TRAILING_UNDERSCORE +export LIB_DIR +export FORT_MODULE_DIRECTORY +export FORT_MODULE_PATH_COMMAND +export OBJ_EXT +export PYTHON_INCDIR +export PYTHON_CMD +export PIC +export SHARED +export SOEXT +export MAKE + +#checkroot="checking whether CANTERA_ROOT is properly set..." +#if test "$CANTERA_ROOT_INIT" = "$CANTERA_ROOT"; then +# echo $checkroot' 'yes +#else +# echo $checkroot' 'no +# echo ' +#### IMPORTANT! +#### before using Cantera, set environment variable +#### CANTERA_ROOT to '$CANTERA_ROOT +# if test -n "$CANTERA_ROOT_INIT"; then +# echo '#### (CANTERA_ROOT is currently set to '$CANTERA_ROOT_INIT') +# ' +# fi +# +#fi + +cd config +chmod +x ./configure +chmod +x ./config.guess +chmod +x ./config.sub +chmod +x ./install-sh +./configure $1 $2 $3 $4 + diff --git a/data/README b/data/README new file mode 100755 index 000000000..88323994d --- /dev/null +++ b/data/README @@ -0,0 +1,5 @@ + + This directory contains subdirectories with data files of various types. + By default, Cantera looks for files in the 'inputs', 'thermo', and + 'transport' directories. These defaults can be modified by editing + Cantera/src/misc.cpp. diff --git a/data/inputs/.cvsignore b/data/inputs/.cvsignore new file mode 100644 index 000000000..ab9d6cc12 --- /dev/null +++ b/data/inputs/.cvsignore @@ -0,0 +1,3 @@ +Makefile +gri30.log +ck2ctml.log diff --git a/data/inputs/Makefile.in b/data/inputs/Makefile.in new file mode 100755 index 000000000..44549eb9c --- /dev/null +++ b/data/inputs/Makefile.in @@ -0,0 +1,15 @@ +#!/bin/sh + +SUFFIXES= +SUFFIXES= .inp .log .dat + +# list all mechanism files here +MECHS = + + +#LOGS = $(MECHS:.inp=.log) + +#all: $(LOGS) + +#gri30.log: gri30.inp +# @CANTERA_BINDIR@/ck2ctml $< diff --git a/data/inputs/air.inp b/data/inputs/air.inp new file mode 100755 index 000000000..75bc01f64 --- /dev/null +++ b/data/inputs/air.inp @@ -0,0 +1,20 @@ +ELEMENTS +O N AR +END +SPECIES +O O2 N NO NO2 N2O N2 AR +END +REACTIONS +2O+M<=>O2+M 1.200E+17 -1.000 .00 + AR/.83/ +N+NO<=>N2+O 2.700E+13 .000 355.00 +N+O2<=>NO+O 9.000E+09 1.000 6500.00 +N2O+O<=>N2+O2 1.400E+12 .000 10810.00 +N2O+O<=>2NO 2.900E+13 .000 23150.00 +N2O(+M)<=>N2+O(+M) 7.910E+10 .000 56020.00 + LOW / 6.370E+14 .000 56640.00/ + AR/ .625/ +NO+O+M<=>NO2+M 1.060E+20 -1.410 .00 + AR/ .70/ +NO2+O<=>NO+O2 3.900E+12 .000 -240.00 +END diff --git a/data/inputs/air.xml b/data/inputs/air.xml new file mode 100644 index 000000000..2f015db57 --- /dev/null +++ b/data/inputs/air.xml @@ -0,0 +1,296 @@ + + + + + + + + 300 + 1 + O:1.0 + + + O N Ar + O O2 N NO NO2 N2O N2 AR + + + + + + + + + + L 1/90 + O:1 + + + 3.168267100E+00, + -3.279318840E-03, 6.643063960E-06, + -6.128066240E-09, 2.112659710E-12, + 2.912225920E+04, 2.051933460E+00 + + 2.569420780E+00, -8.597411370E-05, + 4.194845890E-08, -1.001777990E-11, + 1.228336910E-15, 2.921757910E+04, + 4.784338640E+00 + + + + atom + 8.000000000E+01 + 2.750000000E+00 + + + + + TPIS89 + O:2 + + + 3.782456360E+00, + -2.996734160E-03, 9.847302010E-06, + -9.681295090E-09, 3.243728370E-12, + -1.063943560E+03, 3.657675730E+00 + + 3.282537840E+00, 1.483087540E-03, + -7.579666690E-07, 2.094705550E-10, + -2.167177940E-14, -1.088457720E+03, + 5.453231290E+00 + + + + linear + 1.074000000E+02 + 3.458000000E+00 + 1.600000000E+00 + 3.800000000E+00 + + + + + L 6/88 + N:1 + + + 2.500000000E+00, + 0.000000000E+00, 0.000000000E+00, + 0.000000000E+00, 0.000000000E+00, + 5.610463700E+04, 4.193908700E+00 + + 2.415942900E+00, 1.748906500E-04, + -1.190236900E-07, 3.022624500E-11, + -2.036098200E-15, 5.613377300E+04, + 4.649609600E+00 + + + + atom + 7.140000000E+01 + 3.298000000E+00 + + + + + RUS 78 + N:1 O:1 + + + 4.218476300E+00, + -4.638976000E-03, 1.104102200E-05, + -9.336135400E-09, 2.803577000E-12, + 9.844623000E+03, 2.280846400E+00 + + 3.260605600E+00, 1.191104300E-03, + -4.291704800E-07, 6.945766900E-11, + -4.033609900E-15, 9.920974600E+03, + 6.369302700E+00 + + + + linear + 9.753000000E+01 + 3.621000000E+00 + 1.760000000E+00 + 4.000000000E+00 + + + + + L 7/88 + N:1 O:2 + + + 3.944031200E+00, + -1.585429000E-03, 1.665781200E-05, + -2.047542600E-08, 7.835056400E-12, + 2.896617900E+03, 6.311991700E+00 + + 4.884754200E+00, 2.172395600E-03, + -8.280690600E-07, 1.574751000E-10, + -1.051089500E-14, 2.316498300E+03, + -1.174169500E-01 + + + + nonlinear + 2.000000000E+02 + 3.500000000E+00 + 1.000000000E+00 + + + + + L 7/88 + N:2 O:1 + + + 2.257150200E+00, + 1.130472800E-02, -1.367131900E-05, + 9.681980600E-09, -2.930718200E-12, + 8.741774400E+03, 1.075799200E+01 + + 4.823072900E+00, 2.627025100E-03, + -9.585087400E-07, 1.600071200E-10, + -9.775230300E-15, 8.073404800E+03, + -2.201720700E+00 + + + + linear + 2.324000000E+02 + 3.828000000E+00 + 1.000000000E+00 + + + + + 121286 + N:2 + + + 3.298677000E+00, + 1.408240400E-03, -3.963222000E-06, + 5.641515000E-09, -2.444854000E-12, + -1.020899900E+03, 3.950372000E+00 + + 2.926640000E+00, 1.487976800E-03, + -5.684760000E-07, 1.009703800E-10, + -6.753351000E-15, -9.227977000E+02, + 5.980528000E+00 + + + + linear + 9.753000000E+01 + 3.621000000E+00 + 1.760000000E+00 + 4.000000000E+00 + + + + + 120186 + Ar:1 + + + 2.500000000E+00, + 0.000000000E+00, 0.000000000E+00, + 0.000000000E+00, 0.000000000E+00, + -7.453750000E+02, 4.366000000E+00 + + 2.500000000E+00, 0.000000000E+00, + 0.000000000E+00, 0.000000000E+00, + 0.000000000E+00, -7.453750000E+02, + 4.366000000E+00 + + + + atom + 1.365000000E+02 + 3.330000000E+00 + + + + + + + + 2 O + M [=] O2 + M + O:2 + O2:1 + + 1.2e+17 -1 0 + AR:0.83 + + + + + N + NO [=] N2 + O + N:1 NO:1 + N2:1 O:1 + + 2.7e+13 0 355 + + + + + N + O2 [=] NO + O + N:1 O2:1 + NO:1 O:1 + + 9e+09 1 6500 + + + + + N2O + O [=] N2 + O2 + N2O:1 O:1 + N2:1 O2:1 + + 1.4e+12 0 10810 + + + + + N2O + O [=] 2 NO + N2O:1 O:1 + NO:2 + + 2.9e+13 0 23150 + + + + + N2O (+ M) [=] N2 + O (+ M) + N2O:1 + N2:1 O:1 + + 7.91e+10 0 56020 + 6.37e+14 0 56640 + + AR:0.625 + + + + + NO + O + M [=] NO2 + M + NO:1 O:1 + NO2:1 + + 1.06e+20 -1.41 0 + AR:0.7 + + + + + NO2 + O [=] NO + O2 + NO2:1 O:1 + NO:1 O2:1 + + 3.9e+12 0 -240 + + + + diff --git a/data/inputs/argon.inp b/data/inputs/argon.inp new file mode 100644 index 000000000..4aae107d4 --- /dev/null +++ b/data/inputs/argon.inp @@ -0,0 +1,8 @@ +ELEMENTS +AR +END +SPECIES +AR +END +REACTIONS +END diff --git a/data/inputs/argon.xml b/data/inputs/argon.xml new file mode 100644 index 000000000..04e2a899e --- /dev/null +++ b/data/inputs/argon.xml @@ -0,0 +1,55 @@ + + + + + + + + + 300 + 1 + AR:1.0 + + + Ar + + AR + + + + + + + + + + + + + 120186 + Ar:1 + + + + 2.500000000E+000, 0.000000000E+000, 0.000000000E+000, + 0.000000000E+000, 0.000000000E+000, -7.453750000E+002, + 4.366000000E+000 + + + 2.500000000E+000, 0.000000000E+000, 0.000000000E+000, + 0.000000000E+000, 0.000000000E+000, -7.453750000E+002, + 4.366000000E+000 + + + + + atom + 1.365000000E+002 + 3.330000000E+000 + + + + + + + \ No newline at end of file diff --git a/data/inputs/elements.xml b/data/inputs/elements.xml new file mode 100644 index 000000000..d0139e2b5 --- /dev/null +++ b/data/inputs/elements.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/inputs/gases.xml b/data/inputs/gases.xml new file mode 100644 index 000000000..e2e61ba23 --- /dev/null +++ b/data/inputs/gases.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data/inputs/gri30.inp b/data/inputs/gri30.inp new file mode 100755 index 000000000..11f4ab71b --- /dev/null +++ b/data/inputs/gri30.inp @@ -0,0 +1,661 @@ +! GRI-Mech Version 3.0 3/12/99 CHEMKIN-II format +! See README30 file at anonymous FTP site unix.sri.com, directory gri; +! WorldWideWeb home page http://www.me.berkeley.edu/gri_mech/ or +! through http://www.gri.org , under 'Basic Research', +! for additional information, contacts, and disclaimer +ELEMENTS +O H C N AR +END +SPECIES +H2 H O O2 OH H2O HO2 H2O2 +C CH CH2 CH2(S) CH3 CH4 CO CO2 +HCO CH2O CH2OH CH3O CH3OH C2H C2H2 C2H3 +C2H4 C2H5 C2H6 HCCO CH2CO HCCOH N NH +NH2 NH3 NNH NO NO2 N2O HNO CN +HCN H2CN HCNN HCNO HOCN HNCO NCO N2 +AR C3H7 C3H8 CH2CHO CH3CHO +END +THERMO ALL + 300.000 1000.000 5000.000 +O L 1/90O 1 00 00 00G 200.000 3500.000 1000.000 1 + 2.56942078E+00-8.59741137E-05 4.19484589E-08-1.00177799E-11 1.22833691E-15 2 + 2.92175791E+04 4.78433864E+00 3.16826710E+00-3.27931884E-03 6.64306396E-06 3 +-6.12806624E-09 2.11265971E-12 2.91222592E+04 2.05193346E+00 4 +O2 TPIS89O 2 00 00 00G 200.000 3500.000 1000.000 1 + 3.28253784E+00 1.48308754E-03-7.57966669E-07 2.09470555E-10-2.16717794E-14 2 +-1.08845772E+03 5.45323129E+00 3.78245636E+00-2.99673416E-03 9.84730201E-06 3 +-9.68129509E-09 3.24372837E-12-1.06394356E+03 3.65767573E+00 4 +H L 7/88H 1 00 00 00G 200.000 3500.000 1000.000 1 + 2.50000001E+00-2.30842973E-11 1.61561948E-14-4.73515235E-18 4.98197357E-22 2 + 2.54736599E+04-4.46682914E-01 2.50000000E+00 7.05332819E-13-1.99591964E-15 3 + 2.30081632E-18-9.27732332E-22 2.54736599E+04-4.46682853E-01 4 +H2 TPIS78H 2 00 00 00G 200.000 3500.000 1000.000 1 + 3.33727920E+00-4.94024731E-05 4.99456778E-07-1.79566394E-10 2.00255376E-14 2 +-9.50158922E+02-3.20502331E+00 2.34433112E+00 7.98052075E-03-1.94781510E-05 3 + 2.01572094E-08-7.37611761E-12-9.17935173E+02 6.83010238E-01 4 +OH RUS 78O 1H 1 00 00G 200.000 3500.000 1000.000 1 + 3.09288767E+00 5.48429716E-04 1.26505228E-07-8.79461556E-11 1.17412376E-14 2 + 3.85865700E+03 4.47669610E+00 3.99201543E+00-2.40131752E-03 4.61793841E-06 3 +-3.88113333E-09 1.36411470E-12 3.61508056E+03-1.03925458E-01 4 +H2O L 8/89H 2O 1 00 00G 200.000 3500.000 1000.000 1 + 3.03399249E+00 2.17691804E-03-1.64072518E-07-9.70419870E-11 1.68200992E-14 2 +-3.00042971E+04 4.96677010E+00 4.19864056E+00-2.03643410E-03 6.52040211E-06 3 +-5.48797062E-09 1.77197817E-12-3.02937267E+04-8.49032208E-01 4 +HO2 L 5/89H 1O 2 00 00G 200.000 3500.000 1000.000 1 + 4.01721090E+00 2.23982013E-03-6.33658150E-07 1.14246370E-10-1.07908535E-14 2 + 1.11856713E+02 3.78510215E+00 4.30179801E+00-4.74912051E-03 2.11582891E-05 3 +-2.42763894E-08 9.29225124E-12 2.94808040E+02 3.71666245E+00 4 +H2O2 L 7/88H 2O 2 00 00G 200.000 3500.000 1000.000 1 + 4.16500285E+00 4.90831694E-03-1.90139225E-06 3.71185986E-10-2.87908305E-14 2 +-1.78617877E+04 2.91615662E+00 4.27611269E+00-5.42822417E-04 1.67335701E-05 3 +-2.15770813E-08 8.62454363E-12-1.77025821E+04 3.43505074E+00 4 +C L11/88C 1 00 00 00G 200.000 3500.000 1000.000 1 + 2.49266888E+00 4.79889284E-05-7.24335020E-08 3.74291029E-11-4.87277893E-15 2 + 8.54512953E+04 4.80150373E+00 2.55423955E+00-3.21537724E-04 7.33792245E-07 3 +-7.32234889E-10 2.66521446E-13 8.54438832E+04 4.53130848E+00 4 +CH TPIS79C 1H 1 00 00G 200.000 3500.000 1000.000 1 + 2.87846473E+00 9.70913681E-04 1.44445655E-07-1.30687849E-10 1.76079383E-14 2 + 7.10124364E+04 5.48497999E+00 3.48981665E+00 3.23835541E-04-1.68899065E-06 3 + 3.16217327E-09-1.40609067E-12 7.07972934E+04 2.08401108E+00 4 +CH2 L S/93C 1H 2 00 00G 200.000 3500.000 1000.000 1 + 2.87410113E+00 3.65639292E-03-1.40894597E-06 2.60179549E-10-1.87727567E-14 2 + 4.62636040E+04 6.17119324E+00 3.76267867E+00 9.68872143E-04 2.79489841E-06 3 +-3.85091153E-09 1.68741719E-12 4.60040401E+04 1.56253185E+00 4 +CH2(S) L S/93C 1H 2 00 00G 200.000 3500.000 1000.000 1 + 2.29203842E+00 4.65588637E-03-2.01191947E-06 4.17906000E-10-3.39716365E-14 2 + 5.09259997E+04 8.62650169E+00 4.19860411E+00-2.36661419E-03 8.23296220E-06 3 +-6.68815981E-09 1.94314737E-12 5.04968163E+04-7.69118967E-01 4 +CH3 L11/89C 1H 3 00 00G 200.000 3500.000 1000.000 1 + 2.28571772E+00 7.23990037E-03-2.98714348E-06 5.95684644E-10-4.67154394E-14 2 + 1.67755843E+04 8.48007179E+00 3.67359040E+00 2.01095175E-03 5.73021856E-06 3 +-6.87117425E-09 2.54385734E-12 1.64449988E+04 1.60456433E+00 4 +CH4 L 8/88C 1H 4 00 00G 200.000 3500.000 1000.000 1 + 7.48514950E-02 1.33909467E-02-5.73285809E-06 1.22292535E-09-1.01815230E-13 2 +-9.46834459E+03 1.84373180E+01 5.14987613E+00-1.36709788E-02 4.91800599E-05 3 +-4.84743026E-08 1.66693956E-11-1.02466476E+04-4.64130376E+00 4 +CO TPIS79C 1O 1 00 00G 200.000 3500.000 1000.000 1 + 2.71518561E+00 2.06252743E-03-9.98825771E-07 2.30053008E-10-2.03647716E-14 2 +-1.41518724E+04 7.81868772E+00 3.57953347E+00-6.10353680E-04 1.01681433E-06 3 + 9.07005884E-10-9.04424499E-13-1.43440860E+04 3.50840928E+00 4 +CO2 L 7/88C 1O 2 00 00G 200.000 3500.000 1000.000 1 + 3.85746029E+00 4.41437026E-03-2.21481404E-06 5.23490188E-10-4.72084164E-14 2 +-4.87591660E+04 2.27163806E+00 2.35677352E+00 8.98459677E-03-7.12356269E-06 3 + 2.45919022E-09-1.43699548E-13-4.83719697E+04 9.90105222E+00 4 +HCO L12/89H 1C 1O 1 00G 200.000 3500.000 1000.000 1 + 2.77217438E+00 4.95695526E-03-2.48445613E-06 5.89161778E-10-5.33508711E-14 2 + 4.01191815E+03 9.79834492E+00 4.22118584E+00-3.24392532E-03 1.37799446E-05 3 +-1.33144093E-08 4.33768865E-12 3.83956496E+03 3.39437243E+00 4 +CH2O L 8/88H 2C 1O 1 00G 200.000 3500.000 1000.000 1 + 1.76069008E+00 9.20000082E-03-4.42258813E-06 1.00641212E-09-8.83855640E-14 2 +-1.39958323E+04 1.36563230E+01 4.79372315E+00-9.90833369E-03 3.73220008E-05 3 +-3.79285261E-08 1.31772652E-11-1.43089567E+04 6.02812900E-01 4 +CH2OH GUNL93C 1H 3O 1 00G 200.000 3500.000 1000.000 1 + 3.69266569E+00 8.64576797E-03-3.75101120E-06 7.87234636E-10-6.48554201E-14 2 +-3.24250627E+03 5.81043215E+00 3.86388918E+00 5.59672304E-03 5.93271791E-06 3 +-1.04532012E-08 4.36967278E-12-3.19391367E+03 5.47302243E+00 4 +CH3O 121686C 1H 3O 1 G 0300.00 3000.00 1000.000 1 + 0.03770799E+02 0.07871497E-01-0.02656384E-04 0.03944431E-08-0.02112616E-12 2 + 0.12783252E+03 0.02929575E+02 0.02106204E+02 0.07216595E-01 0.05338472E-04 3 +-0.07377636E-07 0.02075610E-10 0.09786011E+04 0.13152177E+02 4 +CH3OH L 8/88C 1H 4O 1 00G 200.000 3500.000 1000.000 1 + 1.78970791E+00 1.40938292E-02-6.36500835E-06 1.38171085E-09-1.17060220E-13 2 +-2.53748747E+04 1.45023623E+01 5.71539582E+00-1.52309129E-02 6.52441155E-05 3 +-7.10806889E-08 2.61352698E-11-2.56427656E+04-1.50409823E+00 4 +C2H L 1/91C 2H 1 00 00G 200.000 3500.000 1000.000 1 + 3.16780652E+00 4.75221902E-03-1.83787077E-06 3.04190252E-10-1.77232770E-14 2 + 6.71210650E+04 6.63589475E+00 2.88965733E+00 1.34099611E-02-2.84769501E-05 3 + 2.94791045E-08-1.09331511E-11 6.68393932E+04 6.22296438E+00 4 +C2H2 L 1/91C 2H 2 00 00G 200.000 3500.000 1000.000 1 + 4.14756964E+00 5.96166664E-03-2.37294852E-06 4.67412171E-10-3.61235213E-14 2 + 2.59359992E+04-1.23028121E+00 8.08681094E-01 2.33615629E-02-3.55171815E-05 3 + 2.80152437E-08-8.50072974E-12 2.64289807E+04 1.39397051E+01 4 +C2H3 L 2/92C 2H 3 00 00G 200.000 3500.000 1000.000 1 + 3.01672400E+00 1.03302292E-02-4.68082349E-06 1.01763288E-09-8.62607041E-14 2 + 3.46128739E+04 7.78732378E+00 3.21246645E+00 1.51479162E-03 2.59209412E-05 3 +-3.57657847E-08 1.47150873E-11 3.48598468E+04 8.51054025E+00 4 +C2H4 L 1/91C 2H 4 00 00G 200.000 3500.000 1000.000 1 + 2.03611116E+00 1.46454151E-02-6.71077915E-06 1.47222923E-09-1.25706061E-13 2 + 4.93988614E+03 1.03053693E+01 3.95920148E+00-7.57052247E-03 5.70990292E-05 3 +-6.91588753E-08 2.69884373E-11 5.08977593E+03 4.09733096E+00 4 +C2H5 L12/92C 2H 5 00 00G 200.000 3500.000 1000.000 1 + 1.95465642E+00 1.73972722E-02-7.98206668E-06 1.75217689E-09-1.49641576E-13 2 + 1.28575200E+04 1.34624343E+01 4.30646568E+00-4.18658892E-03 4.97142807E-05 3 +-5.99126606E-08 2.30509004E-11 1.28416265E+04 4.70720924E+00 4 +C2H6 L 8/88C 2H 6 00 00G 200.000 3500.000 1000.000 1 + 1.07188150E+00 2.16852677E-02-1.00256067E-05 2.21412001E-09-1.90002890E-13 2 +-1.14263932E+04 1.51156107E+01 4.29142492E+00-5.50154270E-03 5.99438288E-05 3 +-7.08466285E-08 2.68685771E-11-1.15222055E+04 2.66682316E+00 4 +CH2CO L 5/90C 2H 2O 1 00G 200.000 3500.000 1000.000 1 + 4.51129732E+00 9.00359745E-03-4.16939635E-06 9.23345882E-10-7.94838201E-14 2 +-7.55105311E+03 6.32247205E-01 2.13583630E+00 1.81188721E-02-1.73947474E-05 3 + 9.34397568E-09-2.01457615E-12-7.04291804E+03 1.22156480E+01 4 +HCCO SRIC91H 1C 2O 1 G 0300.00 4000.00 1000.000 1 + 0.56282058E+01 0.40853401E-02-0.15934547E-05 0.28626052E-09-0.19407832E-13 2 + 0.19327215E+05-0.39302595E+01 0.22517214E+01 0.17655021E-01-0.23729101E-04 3 + 0.17275759E-07-0.50664811E-11 0.20059449E+05 0.12490417E+02 4 +HCCOH SRI91C 2O 1H 20 0G 300.000 5000.000 1000.000 1 + 0.59238291E+01 0.67923600E-02-0.25658564E-05 0.44987841E-09-0.29940101E-13 2 + 0.72646260E+04-0.76017742E+01 0.12423733E+01 0.31072201E-01-0.50866864E-04 3 + 0.43137131E-07-0.14014594E-10 0.80316143E+04 0.13874319E+02 4 +H2CN 41687H 2C 1N 1 G 0300.00 4000.000 1000.000 1 + 0.52097030E+01 0.29692911E-02-0.28555891E-06-0.16355500E-09 0.30432589E-13 2 + 0.27677109E+05-0.44444780E+01 0.28516610E+01 0.56952331E-02 0.10711400E-05 3 +-0.16226120E-08-0.23511081E-12 0.28637820E+05 0.89927511E+01 4 +HCN GRI/98H 1C 1N 1 0G 200.000 6000.000 1000.000 1 + 0.38022392E+01 0.31464228E-02-0.10632185E-05 0.16619757E-09-0.97997570E-14 2 + 0.14407292E+05 0.15754601E+01 0.22589886E+01 0.10051170E-01-0.13351763E-04 3 + 0.10092349E-07-0.30089028E-11 0.14712633E+05 0.89164419E+01 4 +HNO And93 H 1N 1O 1 0G 200.000 6000.000 1000.000 1 + 0.29792509E+01 0.34944059E-02-0.78549778E-06 0.57479594E-10-0.19335916E-15 2 + 0.11750582E+05 0.86063728E+01 0.45334916E+01-0.56696171E-02 0.18473207E-04 3 +-0.17137094E-07 0.55454573E-11 0.11548297E+05 0.17498417E+01 4 +N L 6/88N 1 0 0 0G 200.000 6000.000 1000.000 1 + 0.24159429E+01 0.17489065E-03-0.11902369E-06 0.30226245E-10-0.20360982E-14 2 + 0.56133773E+05 0.46496096E+01 0.25000000E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.56104637E+05 0.41939087E+01 4 +NNH T07/93N 2H 1 00 00G 200.000 6000.000 1000.000 1 + 0.37667544E+01 0.28915082E-02-0.10416620E-05 0.16842594E-09-0.10091896E-13 2 + 0.28650697E+05 0.44705067E+01 0.43446927E+01-0.48497072E-02 0.20059459E-04 3 +-0.21726464E-07 0.79469539E-11 0.28791973E+05 0.29779410E+01 4 +N2O L 7/88N 2O 1 0 0G 200.000 6000.000 1000.000 1 + 0.48230729E+01 0.26270251E-02-0.95850874E-06 0.16000712E-09-0.97752303E-14 2 + 0.80734048E+04-0.22017207E+01 0.22571502E+01 0.11304728E-01-0.13671319E-04 3 + 0.96819806E-08-0.29307182E-11 0.87417744E+04 0.10757992E+02 4 +NH And94 N 1H 1 0 0G 200.000 6000.000 1000.000 1 + 0.27836928E+01 0.13298430E-02-0.42478047E-06 0.78348501E-10-0.55044470E-14 2 + 0.42120848E+05 0.57407799E+01 0.34929085E+01 0.31179198E-03-0.14890484E-05 3 + 0.24816442E-08-0.10356967E-11 0.41880629E+05 0.18483278E+01 4 +NH2 And89 N 1H 2 0 0G 200.000 6000.000 1000.000 1 + 0.28347421E+01 0.32073082E-02-0.93390804E-06 0.13702953E-09-0.79206144E-14 2 + 0.22171957E+05 0.65204163E+01 0.42040029E+01-0.21061385E-02 0.71068348E-05 3 +-0.56115197E-08 0.16440717E-11 0.21885910E+05-0.14184248E+00 4 +NH3 J 6/77N 1H 3 0 0G 200.000 6000.000 1000.000 1 + 0.26344521E+01 0.56662560E-02-0.17278676E-05 0.23867161E-09-0.12578786E-13 2 +-0.65446958E+04 0.65662928E+01 0.42860274E+01-0.46605230E-02 0.21718513E-04 3 +-0.22808887E-07 0.82638046E-11-0.67417285E+04-0.62537277E+00 4 +NO RUS 78N 1O 1 0 0G 200.000 6000.000 1000.000 1 + 0.32606056E+01 0.11911043E-02-0.42917048E-06 0.69457669E-10-0.40336099E-14 2 + 0.99209746E+04 0.63693027E+01 0.42184763E+01-0.46389760E-02 0.11041022E-04 3 +-0.93361354E-08 0.28035770E-11 0.98446230E+04 0.22808464E+01 4 +NO2 L 7/88N 1O 2 0 0G 200.000 6000.000 1000.000 1 + 0.48847542E+01 0.21723956E-02-0.82806906E-06 0.15747510E-09-0.10510895E-13 2 + 0.23164983E+04-0.11741695E+00 0.39440312E+01-0.15854290E-02 0.16657812E-04 3 +-0.20475426E-07 0.78350564E-11 0.28966179E+04 0.63119917E+01 4 +HCNO BDEA94H 1N 1C 1O 1G 300.000 5000.000 1382.000 1 + 6.59860456E+00 3.02778626E-03-1.07704346E-06 1.71666528E-10-1.01439391E-14 2 + 1.79661339E+04-1.03306599E+01 2.64727989E+00 1.27505342E-02-1.04794236E-05 3 + 4.41432836E-09-7.57521466E-13 1.92990252E+04 1.07332972E+01 4 +HOCN BDEA94H 1N 1C 1O 1G 300.000 5000.000 1368.000 1 + 5.89784885E+00 3.16789393E-03-1.11801064E-06 1.77243144E-10-1.04339177E-14 2 +-3.70653331E+03-6.18167825E+00 3.78604952E+00 6.88667922E-03-3.21487864E-06 3 + 5.17195767E-10 1.19360788E-14-2.82698400E+03 5.63292162E+00 4 +HNCO BDEA94H 1N 1C 1O 1G 300.000 5000.000 1478.000 1 + 6.22395134E+00 3.17864004E-03-1.09378755E-06 1.70735163E-10-9.95021955E-15 2 +-1.66599344E+04-8.38224741E+00 3.63096317E+00 7.30282357E-03-2.28050003E-06 3 +-6.61271298E-10 3.62235752E-13-1.55873636E+04 6.19457727E+00 4 +NCO EA 93 N 1C 1O 1 0G 200.000 6000.000 1000.000 1 + 0.51521845E+01 0.23051761E-02-0.88033153E-06 0.14789098E-09-0.90977996E-14 2 + 0.14004123E+05-0.25442660E+01 0.28269308E+01 0.88051688E-02-0.83866134E-05 3 + 0.48016964E-08-0.13313595E-11 0.14682477E+05 0.95504646E+01 4 +CN HBH92 C 1N 1 0 0G 200.000 6000.000 1000.000 1 + 0.37459805E+01 0.43450775E-04 0.29705984E-06-0.68651806E-10 0.44134173E-14 2 + 0.51536188E+05 0.27867601E+01 0.36129351E+01-0.95551327E-03 0.21442977E-05 3 +-0.31516323E-09-0.46430356E-12 0.51708340E+05 0.39804995E+01 4 +HCNN SRI/94C 1N 2H 10 0G 300.000 5000.000 1000.000 1 + 0.58946362E+01 0.39895959E-02-0.15982380E-05 0.29249395E-09-0.20094686E-13 2 + 0.53452941E+05-0.51030502E+01 0.25243194E+01 0.15960619E-01-0.18816354E-04 3 + 0.12125540E-07-0.32357378E-11 0.54261984E+05 0.11675870E+02 4 +N2 121286N 2 G 300.000 5000.000 1000.000 1 + 0.02926640E+02 0.14879768E-02-0.05684760E-05 0.10097038E-09-0.06753351E-13 2 +-0.09227977E+04 0.05980528E+02 0.03298677E+02 0.14082404E-02-0.03963222E-04 3 + 0.05641515E-07-0.02444854E-10-0.10208999E+04 0.03950372E+02 4 +AR 120186AR 1 G 300.000 5000.000 1000.000 1 + 0.02500000E+02 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-0.07453750E+04 0.04366000E+02 0.02500000E+02 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-0.07453750E+04 0.04366000E+02 4 +C3H8 L 4/85C 3H 8 0 0G 300.000 5000.000 1000.00 1 + 0.75341368E+01 0.18872239E-01-0.62718491E-05 0.91475649E-09-0.47838069E-13 2 +-0.16467516E+05-0.17892349E+02 0.93355381E+00 0.26424579E-01 0.61059727E-05 3 +-0.21977499E-07 0.95149253E-11-0.13958520E+05 0.19201691E+02 4 +C3H7 L 9/84C 3H 7 0 0G 300.000 5000.000 1000.00 1 + 0.77026987E+01 0.16044203E-01-0.52833220E-05 0.76298590E-09-0.39392284E-13 2 + 0.82984336E+04-0.15480180E+02 0.10515518E+01 0.25991980E-01 0.23800540E-05 3 +-0.19609569E-07 0.93732470E-11 0.10631863E+05 0.21122559E+02 4 +CH3CHO L 8/88C 2H 4O 1 0G 200.000 6000.000 1000.00 1 + 0.54041108E+01 0.11723059E-01-0.42263137E-05 0.68372451E-09-0.40984863E-13 2 +-0.22593122E+05-0.34807917E+01 0.47294595E+01-0.31932858E-02 0.47534921E-04 3 +-0.57458611E-07 0.21931112E-10-0.21572878E+05 0.41030159E+01 4 +CH2CHO SAND86O 1H 3C 2 G 300.00 5000.00 1000.00 1 + 0.05975670E+02 0.08130591E-01-0.02743624E-04 0.04070304E-08-0.02176017E-12 2 + 0.04903218E+04-0.05045251E+02 0.03409062E+02 0.10738574E-01 0.01891492E-04 3 +-0.07158583E-07 0.02867385E-10 0.15214766E+04 0.09558290E+02 4 +END +REACTIONS +2O+M<=>O2+M 1.200E+17 -1.000 .00 +H2/ 2.40/ H2O/15.40/ CH4/ 2.00/ CO/ 1.75/ CO2/ 3.60/ C2H6/ 3.00/ AR/ .83/ +O+H+M<=>OH+M 5.000E+17 -1.000 .00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +O+H2<=>H+OH 3.870E+04 2.700 6260.00 +O+HO2<=>OH+O2 2.000E+13 .000 .00 +O+H2O2<=>OH+HO2 9.630E+06 2.000 4000.00 +O+CH<=>H+CO 5.700E+13 .000 .00 +O+CH2<=>H+HCO 8.000E+13 .000 .00 +O+CH2(S)<=>H2+CO 1.500E+13 .000 .00 +O+CH2(S)<=>H+HCO 1.500E+13 .000 .00 +O+CH3<=>H+CH2O 5.060E+13 .000 .00 +O+CH4<=>OH+CH3 1.020E+09 1.500 8600.00 +O+CO(+M)<=>CO2(+M) 1.800E+10 .000 2385.00 + LOW/ 6.020E+14 .000 3000.00/ +H2/2.00/ O2/6.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/3.50/ C2H6/3.00/ AR/ .50/ +O+HCO<=>OH+CO 3.000E+13 .000 .00 +O+HCO<=>H+CO2 3.000E+13 .000 .00 +O+CH2O<=>OH+HCO 3.900E+13 .000 3540.00 +O+CH2OH<=>OH+CH2O 1.000E+13 .000 .00 +O+CH3O<=>OH+CH2O 1.000E+13 .000 .00 +O+CH3OH<=>OH+CH2OH 3.880E+05 2.500 3100.00 +O+CH3OH<=>OH+CH3O 1.300E+05 2.500 5000.00 +O+C2H<=>CH+CO 5.000E+13 .000 .00 +O+C2H2<=>H+HCCO 1.350E+07 2.000 1900.00 +O+C2H2<=>OH+C2H 4.600E+19 -1.410 28950.00 +O+C2H2<=>CO+CH2 6.940E+06 2.000 1900.00 +O+C2H3<=>H+CH2CO 3.000E+13 .000 .00 +O+C2H4<=>CH3+HCO 1.250E+07 1.830 220.00 +O+C2H5<=>CH3+CH2O 2.240E+13 .000 .00 +O+C2H6<=>OH+C2H5 8.980E+07 1.920 5690.00 +O+HCCO<=>H+2CO 1.000E+14 .000 .00 +O+CH2CO<=>OH+HCCO 1.000E+13 .000 8000.00 +O+CH2CO<=>CH2+CO2 1.750E+12 .000 1350.00 +O2+CO<=>O+CO2 2.500E+12 .000 47800.00 +O2+CH2O<=>HO2+HCO 1.000E+14 .000 40000.00 +H+O2+M<=>HO2+M 2.800E+18 -.860 .00 +O2/ .00/ H2O/ .00/ CO/ .75/ CO2/1.50/ C2H6/1.50/ N2/ .00/ AR/ .00/ +H+2O2<=>HO2+O2 2.080E+19 -1.240 .00 +H+O2+H2O<=>HO2+H2O 11.26E+18 -.760 .00 +H+O2+N2<=>HO2+N2 2.600E+19 -1.240 .00 +H+O2+AR<=>HO2+AR 7.000E+17 -.800 .00 +H+O2<=>O+OH 2.650E+16 -.6707 17041.00 +2H+M<=>H2+M 1.000E+18 -1.000 .00 +H2/ .00/ H2O/ .00/ CH4/2.00/ CO2/ .00/ C2H6/3.00/ AR/ .63/ +2H+H2<=>2H2 9.000E+16 -.600 .00 +2H+H2O<=>H2+H2O 6.000E+19 -1.250 .00 +2H+CO2<=>H2+CO2 5.500E+20 -2.000 .00 +H+OH+M<=>H2O+M 2.200E+22 -2.000 .00 +H2/ .73/ H2O/3.65/ CH4/2.00/ C2H6/3.00/ AR/ .38/ +H+HO2<=>O+H2O 3.970E+12 .000 671.00 +H+HO2<=>O2+H2 4.480E+13 .000 1068.00 +H+HO2<=>2OH 0.840E+14 .000 635.00 +H+H2O2<=>HO2+H2 1.210E+07 2.000 5200.00 +H+H2O2<=>OH+H2O 1.000E+13 .000 3600.00 +H+CH<=>C+H2 1.650E+14 .000 .00 +H+CH2(+M)<=>CH3(+M) 6.000E+14 .000 .00 + LOW / 1.040E+26 -2.760 1600.00/ + TROE/ .5620 91.00 5836.00 8552.00/ +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+CH2(S)<=>CH+H2 3.000E+13 .000 .00 +H+CH3(+M)<=>CH4(+M) 13.90E+15 -.534 536.00 + LOW / 2.620E+33 -4.760 2440.00/ + TROE/ .7830 74.00 2941.00 6964.00 / +H2/2.00/ H2O/6.00/ CH4/3.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+CH4<=>CH3+H2 6.600E+08 1.620 10840.00 +H+HCO(+M)<=>CH2O(+M) 1.090E+12 .480 -260.00 + LOW / 2.470E+24 -2.570 425.00/ + TROE/ .7824 271.00 2755.00 6570.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+HCO<=>H2+CO 7.340E+13 .000 .00 +H+CH2O(+M)<=>CH2OH(+M) 5.400E+11 .454 3600.00 + LOW / 1.270E+32 -4.820 6530.00/ + TROE/ .7187 103.00 1291.00 4160.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +H+CH2O(+M)<=>CH3O(+M) 5.400E+11 .454 2600.00 + LOW / 2.200E+30 -4.800 5560.00/ + TROE/ .7580 94.00 1555.00 4200.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +H+CH2O<=>HCO+H2 5.740E+07 1.900 2742.00 +H+CH2OH(+M)<=>CH3OH(+M) 1.055E+12 .500 86.00 + LOW / 4.360E+31 -4.650 5080.00/ + TROE/ .600 100.00 90000.0 10000.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +H+CH2OH<=>H2+CH2O 2.000E+13 .000 .00 +H+CH2OH<=>OH+CH3 1.650E+11 .650 -284.00 +H+CH2OH<=>CH2(S)+H2O 3.280E+13 -.090 610.00 +H+CH3O(+M)<=>CH3OH(+M) 2.430E+12 .515 50.00 + LOW / 4.660E+41 -7.440 14080.0/ + TROE/ .700 100.00 90000.0 10000.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +H+CH3O<=>H+CH2OH 4.150E+07 1.630 1924.00 +H+CH3O<=>H2+CH2O 2.000E+13 .000 .00 +H+CH3O<=>OH+CH3 1.500E+12 .500 -110.00 +H+CH3O<=>CH2(S)+H2O 2.620E+14 -.230 1070.00 +H+CH3OH<=>CH2OH+H2 1.700E+07 2.100 4870.00 +H+CH3OH<=>CH3O+H2 4.200E+06 2.100 4870.00 +H+C2H(+M)<=>C2H2(+M) 1.000E+17 -1.000 .00 + LOW / 3.750E+33 -4.800 1900.00/ + TROE/ .6464 132.00 1315.00 5566.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C2H2(+M)<=>C2H3(+M) 5.600E+12 .000 2400.00 + LOW / 3.800E+40 -7.270 7220.00/ + TROE/ .7507 98.50 1302.00 4167.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C2H3(+M)<=>C2H4(+M) 6.080E+12 .270 280.00 + LOW / 1.400E+30 -3.860 3320.00/ + TROE/ .7820 207.50 2663.00 6095.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C2H3<=>H2+C2H2 3.000E+13 .000 .00 +H+C2H4(+M)<=>C2H5(+M) 0.540E+12 .454 1820.00 + LOW / 0.600E+42 -7.620 6970.00/ + TROE/ .9753 210.00 984.00 4374.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C2H4<=>C2H3+H2 1.325E+06 2.530 12240.00 +H+C2H5(+M)<=>C2H6(+M) 5.210E+17 -.990 1580.00 + LOW / 1.990E+41 -7.080 6685.00/ + TROE/ .8422 125.00 2219.00 6882.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C2H5<=>H2+C2H4 2.000E+12 .000 .00 +H+C2H6<=>C2H5+H2 1.150E+08 1.900 7530.00 +H+HCCO<=>CH2(S)+CO 1.000E+14 .000 .00 +H+CH2CO<=>HCCO+H2 5.000E+13 .000 8000.00 +H+CH2CO<=>CH3+CO 1.130E+13 .000 3428.00 +H+HCCOH<=>H+CH2CO 1.000E+13 .000 .00 +H2+CO(+M)<=>CH2O(+M) 4.300E+07 1.500 79600.00 + LOW / 5.070E+27 -3.420 84350.00/ + TROE/ .9320 197.00 1540.00 10300.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +OH+H2<=>H+H2O 2.160E+08 1.510 3430.00 +2OH(+M)<=>H2O2(+M) 7.400E+13 -.370 .00 + LOW / 2.300E+18 -.900 -1700.00/ + TROE/ .7346 94.00 1756.00 5182.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +2OH<=>O+H2O 3.570E+04 2.400 -2110.00 +OH+HO2<=>O2+H2O 1.450E+13 .000 -500.00 + DUPLICATE +OH+H2O2<=>HO2+H2O 2.000E+12 .000 427.00 + DUPLICATE +OH+H2O2<=>HO2+H2O 1.700E+18 .000 29410.00 + DUPLICATE +OH+C<=>H+CO 5.000E+13 .000 .00 +OH+CH<=>H+HCO 3.000E+13 .000 .00 +OH+CH2<=>H+CH2O 2.000E+13 .000 .00 +OH+CH2<=>CH+H2O 1.130E+07 2.000 3000.00 +OH+CH2(S)<=>H+CH2O 3.000E+13 .000 .00 +OH+CH3(+M)<=>CH3OH(+M) 2.790E+18 -1.430 1330.00 + LOW / 4.000E+36 -5.920 3140.00/ + TROE/ .4120 195.0 5900.00 6394.00/ +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +OH+CH3<=>CH2+H2O 5.600E+07 1.600 5420.00 +OH+CH3<=>CH2(S)+H2O 6.440E+17 -1.340 1417.00 +OH+CH4<=>CH3+H2O 1.000E+08 1.600 3120.00 +OH+CO<=>H+CO2 4.760E+07 1.228 70.00 +OH+HCO<=>H2O+CO 5.000E+13 .000 .00 +OH+CH2O<=>HCO+H2O 3.430E+09 1.180 -447.00 +OH+CH2OH<=>H2O+CH2O 5.000E+12 .000 .00 +OH+CH3O<=>H2O+CH2O 5.000E+12 .000 .00 +OH+CH3OH<=>CH2OH+H2O 1.440E+06 2.000 -840.00 +OH+CH3OH<=>CH3O+H2O 6.300E+06 2.000 1500.00 +OH+C2H<=>H+HCCO 2.000E+13 .000 .00 +OH+C2H2<=>H+CH2CO 2.180E-04 4.500 -1000.00 +OH+C2H2<=>H+HCCOH 5.040E+05 2.300 13500.00 +OH+C2H2<=>C2H+H2O 3.370E+07 2.000 14000.00 +OH+C2H2<=>CH3+CO 4.830E-04 4.000 -2000.00 +OH+C2H3<=>H2O+C2H2 5.000E+12 .000 .00 +OH+C2H4<=>C2H3+H2O 3.600E+06 2.000 2500.00 +OH+C2H6<=>C2H5+H2O 3.540E+06 2.120 870.00 +OH+CH2CO<=>HCCO+H2O 7.500E+12 .000 2000.00 +2HO2<=>O2+H2O2 1.300E+11 .000 -1630.00 + DUPLICATE +2HO2<=>O2+H2O2 4.200E+14 .000 12000.00 + DUPLICATE +HO2+CH2<=>OH+CH2O 2.000E+13 .000 .00 +HO2+CH3<=>O2+CH4 1.000E+12 .000 .00 +HO2+CH3<=>OH+CH3O 3.780E+13 .000 .00 +HO2+CO<=>OH+CO2 1.500E+14 .000 23600.00 +HO2+CH2O<=>HCO+H2O2 5.600E+06 2.000 12000.00 +C+O2<=>O+CO 5.800E+13 .000 576.00 +C+CH2<=>H+C2H 5.000E+13 .000 .00 +C+CH3<=>H+C2H2 5.000E+13 .000 .00 +CH+O2<=>O+HCO 6.710E+13 .000 .00 +CH+H2<=>H+CH2 1.080E+14 .000 3110.00 +CH+H2O<=>H+CH2O 5.710E+12 .000 -755.00 +CH+CH2<=>H+C2H2 4.000E+13 .000 .00 +CH+CH3<=>H+C2H3 3.000E+13 .000 .00 +CH+CH4<=>H+C2H4 6.000E+13 .000 .00 +CH+CO(+M)<=>HCCO(+M) 5.000E+13 .000 .00 + LOW / 2.690E+28 -3.740 1936.00/ + TROE/ .5757 237.00 1652.00 5069.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +CH+CO2<=>HCO+CO 1.900E+14 .000 15792.00 +CH+CH2O<=>H+CH2CO 9.460E+13 .000 -515.00 +CH+HCCO<=>CO+C2H2 5.000E+13 .000 .00 +CH2+O2=>OH+H+CO 5.000E+12 .000 1500.00 +CH2+H2<=>H+CH3 5.000E+05 2.000 7230.00 +2CH2<=>H2+C2H2 1.600E+15 .000 11944.00 +CH2+CH3<=>H+C2H4 4.000E+13 .000 .00 +CH2+CH4<=>2CH3 2.460E+06 2.000 8270.00 +CH2+CO(+M)<=>CH2CO(+M) 8.100E+11 .500 4510.00 + LOW / 2.690E+33 -5.110 7095.00/ + TROE/ .5907 275.00 1226.00 5185.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +CH2+HCCO<=>C2H3+CO 3.000E+13 .000 .00 +CH2(S)+N2<=>CH2+N2 1.500E+13 .000 600.00 +CH2(S)+AR<=>CH2+AR 9.000E+12 .000 600.00 +CH2(S)+O2<=>H+OH+CO 2.800E+13 .000 .00 +CH2(S)+O2<=>CO+H2O 1.200E+13 .000 .00 +CH2(S)+H2<=>CH3+H 7.000E+13 .000 .00 +CH2(S)+H2O(+M)<=>CH3OH(+M) 4.820E+17 -1.160 1145.00 + LOW / 1.880E+38 -6.360 5040.00/ + TROE/ .6027 208.00 3922.00 10180.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +CH2(S)+H2O<=>CH2+H2O 3.000E+13 .000 .00 +CH2(S)+CH3<=>H+C2H4 1.200E+13 .000 -570.00 +CH2(S)+CH4<=>2CH3 1.600E+13 .000 -570.00 +CH2(S)+CO<=>CH2+CO 9.000E+12 .000 .00 +CH2(S)+CO2<=>CH2+CO2 7.000E+12 .000 .00 +CH2(S)+CO2<=>CO+CH2O 1.400E+13 .000 .00 +CH2(S)+C2H6<=>CH3+C2H5 4.000E+13 .000 -550.00 +CH3+O2<=>O+CH3O 3.560E+13 .000 30480.00 +CH3+O2<=>OH+CH2O 2.310E+12 .000 20315.00 +CH3+H2O2<=>HO2+CH4 2.450E+04 2.470 5180.00 +2CH3(+M)<=>C2H6(+M) 6.770E+16 -1.180 654.00 + LOW / 3.400E+41 -7.030 2762.00/ + TROE/ .6190 73.20 1180.00 9999.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +2CH3<=>H+C2H5 6.840E+12 .100 10600.00 +CH3+HCO<=>CH4+CO 2.648E+13 .000 .00 +CH3+CH2O<=>HCO+CH4 3.320E+03 2.810 5860.00 +CH3+CH3OH<=>CH2OH+CH4 3.000E+07 1.500 9940.00 +CH3+CH3OH<=>CH3O+CH4 1.000E+07 1.500 9940.00 +CH3+C2H4<=>C2H3+CH4 2.270E+05 2.000 9200.00 +CH3+C2H6<=>C2H5+CH4 6.140E+06 1.740 10450.00 +HCO+H2O<=>H+CO+H2O 1.500E+18 -1.000 17000.00 +HCO+M<=>H+CO+M 1.870E+17 -1.000 17000.00 +H2/2.00/ H2O/ .00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +HCO+O2<=>HO2+CO 13.45E+12 .000 400.00 +CH2OH+O2<=>HO2+CH2O 1.800E+13 .000 900.00 +CH3O+O2<=>HO2+CH2O 4.280E-13 7.600 -3530.00 +C2H+O2<=>HCO+CO 1.000E+13 .000 -755.00 +C2H+H2<=>H+C2H2 5.680E+10 0.900 1993.00 +C2H3+O2<=>HCO+CH2O 4.580E+16 -1.390 1015.00 +C2H4(+M)<=>H2+C2H2(+M) 8.000E+12 .440 86770.00 + LOW / 1.580E+51 -9.300 97800.00/ + TROE/ .7345 180.00 1035.00 5417.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +C2H5+O2<=>HO2+C2H4 8.400E+11 .000 3875.00 +HCCO+O2<=>OH+2CO 3.200E+12 .000 854.00 +2HCCO<=>2CO+C2H2 1.000E+13 .000 .00 +N+NO<=>N2+O 2.700E+13 .000 355.00 +N+O2<=>NO+O 9.000E+09 1.000 6500.00 +N+OH<=>NO+H 3.360E+13 .000 385.00 +N2O+O<=>N2+O2 1.400E+12 .000 10810.00 +N2O+O<=>2NO 2.900E+13 .000 23150.00 +N2O+H<=>N2+OH 3.870E+14 .000 18880.00 +N2O+OH<=>N2+HO2 2.000E+12 .000 21060.00 +N2O(+M)<=>N2+O(+M) 7.910E+10 .000 56020.00 + LOW / 6.370E+14 .000 56640.00/ +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .625/ +HO2+NO<=>NO2+OH 2.110E+12 .000 -480.00 +NO+O+M<=>NO2+M 1.060E+20 -1.410 .00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +NO2+O<=>NO+O2 3.900E+12 .000 -240.00 +NO2+H<=>NO+OH 1.320E+14 .000 360.00 +NH+O<=>NO+H 4.000E+13 .000 .00 +NH+H<=>N+H2 3.200E+13 .000 330.00 +NH+OH<=>HNO+H 2.000E+13 .000 .00 +NH+OH<=>N+H2O 2.000E+09 1.200 .00 +NH+O2<=>HNO+O 4.610E+05 2.000 6500.00 +NH+O2<=>NO+OH 1.280E+06 1.500 100.00 +NH+N<=>N2+H 1.500E+13 .000 .00 +NH+H2O<=>HNO+H2 2.000E+13 .000 13850.00 +NH+NO<=>N2+OH 2.160E+13 -.230 .00 +NH+NO<=>N2O+H 3.650E+14 -.450 .00 +NH2+O<=>OH+NH 3.000E+12 .000 .00 +NH2+O<=>H+HNO 3.900E+13 .000 .00 +NH2+H<=>NH+H2 4.000E+13 .000 3650.00 +NH2+OH<=>NH+H2O 9.000E+07 1.500 -460.00 +NNH<=>N2+H 3.300E+08 .000 .00 +NNH+M<=>N2+H+M 1.300E+14 -.110 4980.00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +NNH+O2<=>HO2+N2 5.000E+12 .000 .00 +NNH+O<=>OH+N2 2.500E+13 .000 .00 +NNH+O<=>NH+NO 7.000E+13 .000 .00 +NNH+H<=>H2+N2 5.000E+13 .000 .00 +NNH+OH<=>H2O+N2 2.000E+13 .000 .00 +NNH+CH3<=>CH4+N2 2.500E+13 .000 .00 +H+NO+M<=>HNO+M 4.480E+19 -1.320 740.00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +HNO+O<=>NO+OH 2.500E+13 .000 .00 +HNO+H<=>H2+NO 9.000E+11 .720 660.00 +HNO+OH<=>NO+H2O 1.300E+07 1.900 -950.00 +HNO+O2<=>HO2+NO 1.000E+13 .000 13000.00 +CN+O<=>CO+N 7.700E+13 .000 .00 +CN+OH<=>NCO+H 4.000E+13 .000 .00 +CN+H2O<=>HCN+OH 8.000E+12 .000 7460.00 +CN+O2<=>NCO+O 6.140E+12 .000 -440.00 +CN+H2<=>HCN+H 2.950E+05 2.450 2240.00 +NCO+O<=>NO+CO 2.350E+13 .000 .00 +NCO+H<=>NH+CO 5.400E+13 .000 .00 +NCO+OH<=>NO+H+CO 0.250E+13 .000 .00 +NCO+N<=>N2+CO 2.000E+13 .000 .00 +NCO+O2<=>NO+CO2 2.000E+12 .000 20000.00 +NCO+M<=>N+CO+M 3.100E+14 .000 54050.00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +NCO+NO<=>N2O+CO 1.900E+17 -1.520 740.00 +NCO+NO<=>N2+CO2 3.800E+18 -2.000 800.00 +HCN+M<=>H+CN+M 1.040E+29 -3.300 126600.00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +HCN+O<=>NCO+H 2.030E+04 2.640 4980.00 +HCN+O<=>NH+CO 5.070E+03 2.640 4980.00 +HCN+O<=>CN+OH 3.910E+09 1.580 26600.00 +HCN+OH<=>HOCN+H 1.100E+06 2.030 13370.00 +HCN+OH<=>HNCO+H 4.400E+03 2.260 6400.00 +HCN+OH<=>NH2+CO 1.600E+02 2.560 9000.00 +H+HCN(+M)<=>H2CN(+M) 3.300E+13 .000 .00 + LOW / 1.400E+26 -3.400 1900.00/ +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H2CN+N<=>N2+CH2 6.000E+13 .000 400.00 +C+N2<=>CN+N 6.300E+13 .000 46020.00 +CH+N2<=>HCN+N 3.120E+09 0.880 20130.00 +CH+N2(+M)<=>HCNN(+M) 3.100E+12 .150 .00 + LOW / 1.300E+25 -3.160 740.00/ + TROE/ .6670 235.00 2117.00 4536.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ 1.0/ +CH2+N2<=>HCN+NH 1.000E+13 .000 74000.00 +CH2(S)+N2<=>NH+HCN 1.000E+11 .000 65000.00 +C+NO<=>CN+O 1.900E+13 .000 .00 +C+NO<=>CO+N 2.900E+13 .000 .00 +CH+NO<=>HCN+O 4.100E+13 .000 .00 +CH+NO<=>H+NCO 1.620E+13 .000 .00 +CH+NO<=>N+HCO 2.460E+13 .000 .00 +CH2+NO<=>H+HNCO 3.100E+17 -1.380 1270.00 +CH2+NO<=>OH+HCN 2.900E+14 -.690 760.00 +CH2+NO<=>H+HCNO 3.800E+13 -.360 580.00 +CH2(S)+NO<=>H+HNCO 3.100E+17 -1.380 1270.00 +CH2(S)+NO<=>OH+HCN 2.900E+14 -.690 760.00 +CH2(S)+NO<=>H+HCNO 3.800E+13 -.360 580.00 +CH3+NO<=>HCN+H2O 9.600E+13 .000 28800.00 +CH3+NO<=>H2CN+OH 1.000E+12 .000 21750.00 +HCNN+O<=>CO+H+N2 2.200E+13 .000 .00 +HCNN+O<=>HCN+NO 2.000E+12 .000 .00 +HCNN+O2<=>O+HCO+N2 1.200E+13 .000 .00 +HCNN+OH<=>H+HCO+N2 1.200E+13 .000 .00 +HCNN+H<=>CH2+N2 1.000E+14 .000 .00 +HNCO+O<=>NH+CO2 9.800E+07 1.410 8500.00 +HNCO+O<=>HNO+CO 1.500E+08 1.570 44000.00 +HNCO+O<=>NCO+OH 2.200E+06 2.110 11400.00 +HNCO+H<=>NH2+CO 2.250E+07 1.700 3800.00 +HNCO+H<=>H2+NCO 1.050E+05 2.500 13300.00 +HNCO+OH<=>NCO+H2O 3.300E+07 1.500 3600.00 +HNCO+OH<=>NH2+CO2 3.300E+06 1.500 3600.00 +HNCO+M<=>NH+CO+M 1.180E+16 .000 84720.00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +HCNO+H<=>H+HNCO 2.100E+15 -.690 2850.00 +HCNO+H<=>OH+HCN 2.700E+11 .180 2120.00 +HCNO+H<=>NH2+CO 1.700E+14 -.750 2890.00 +HOCN+H<=>H+HNCO 2.000E+07 2.000 2000.00 +HCCO+NO<=>HCNO+CO 0.900E+13 .000 .00 +CH3+N<=>H2CN+H 6.100E+14 -.310 290.00 +CH3+N<=>HCN+H2 3.700E+12 .150 -90.00 +NH3+H<=>NH2+H2 5.400E+05 2.400 9915.00 +NH3+OH<=>NH2+H2O 5.000E+07 1.600 955.00 +NH3+O<=>NH2+OH 9.400E+06 1.940 6460.00 +NH+CO2<=>HNO+CO 1.000E+13 .000 14350.00 +CN+NO2<=>NCO+NO 6.160E+15 -0.752 345.00 +NCO+NO2<=>N2O+CO2 3.250E+12 .000 -705.00 +N+CO2<=>NO+CO 3.000E+12 .000 11300.00 +O+CH3=>H+H2+CO 3.370E+13 .000 .00 +O+C2H4<=>H+CH2CHO 6.700E+06 1.830 220.00 +O+C2H5<=>H+CH3CHO 1.096E+14 .000 .00 +OH+HO2<=>O2+H2O 0.500E+16 .000 17330.00 + DUPLICATE +OH+CH3=>H2+CH2O 8.000E+09 .500 -1755.00 +CH+H2(+M)<=>CH3(+M) 1.970E+12 .430 -370.00 + LOW/ 4.820E+25 -2.80 590.0 / + TROE/ .578 122.0 2535.0 9365.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +CH2+O2=>2H+CO2 5.800E+12 .000 1500.00 +CH2+O2<=>O+CH2O 2.400E+12 .000 1500.00 +CH2+CH2=>2H+C2H2 2.000E+14 .000 10989.00 +CH2(S)+H2O=>H2+CH2O 6.820E+10 .250 -935.00 +C2H3+O2<=>O+CH2CHO 3.030E+11 .290 11.00 +C2H3+O2<=>HO2+C2H2 1.337E+06 1.610 -384.00 +O+CH3CHO<=>OH+CH2CHO 5.840E+12 .000 1808.00 +O+CH3CHO=>OH+CH3+CO 5.840E+12 .000 1808.00 +O2+CH3CHO=>HO2+CH3+CO 3.010E+13 .000 39150.00 +H+CH3CHO<=>CH2CHO+H2 2.050E+09 1.160 2405.00 +H+CH3CHO=>CH3+H2+CO 2.050E+09 1.160 2405.00 +OH+CH3CHO=>CH3+H2O+CO 2.343E+10 0.730 -1113.00 +HO2+CH3CHO=>CH3+H2O2+CO 3.010E+12 .000 11923.00 +CH3+CH3CHO=>CH3+CH4+CO 2.720E+06 1.770 5920.00 +H+CH2CO(+M)<=>CH2CHO(+M) 4.865E+11 0.422 -1755.00 + LOW/ 1.012E+42 -7.63 3854.0/ + TROE/ 0.465 201.0 1773.0 5333.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +O+CH2CHO=>H+CH2+CO2 1.500E+14 .000 .00 +O2+CH2CHO=>OH+CO+CH2O 1.810E+10 .000 .00 +O2+CH2CHO=>OH+2HCO 2.350E+10 .000 .00 +H+CH2CHO<=>CH3+HCO 2.200E+13 .000 .00 +H+CH2CHO<=>CH2CO+H2 1.100E+13 .000 .00 +OH+CH2CHO<=>H2O+CH2CO 1.200E+13 .000 .00 +OH+CH2CHO<=>HCO+CH2OH 3.010E+13 .000 .00 +CH3+C2H5(+M)<=>C3H8(+M) .9430E+13 .000 .00 + LOW/ 2.710E+74 -16.82 13065.0 / + TROE/ .1527 291.0 2742.0 7748.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +O+C3H8<=>OH+C3H7 1.930E+05 2.680 3716.00 +H+C3H8<=>C3H7+H2 1.320E+06 2.540 6756.00 +OH+C3H8<=>C3H7+H2O 3.160E+07 1.800 934.00 +C3H7+H2O2<=>HO2+C3H8 3.780E+02 2.720 1500.00 +CH3+C3H8<=>C3H7+CH4 0.903E+00 3.650 7154.00 +CH3+C2H4(+M)<=>C3H7(+M) 2.550E+06 1.600 5700.00 + LOW/ 3.00E+63 -14.6 18170./ + TROE/ .1894 277.0 8748.0 7891.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +O+C3H7<=>C2H5+CH2O 9.640E+13 .000 .00 +H+C3H7(+M)<=>C3H8(+M) 3.613E+13 .000 .00 + LOW/ 4.420E+61 -13.545 11357.0/ + TROE/ .315 369.0 3285.0 6667.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C3H7<=>CH3+C2H5 4.060E+06 2.190 890.00 +OH+C3H7<=>C2H5+CH2OH 2.410E+13 .000 .00 +HO2+C3H7<=>O2+C3H8 2.550E+10 0.255 -943.00 +HO2+C3H7=>OH+C2H5+CH2O 2.410E+13 .000 .00 +CH3+C3H7<=>2C2H5 1.927E+13 -0.320 .00 +END diff --git a/data/inputs/gri30.xml b/data/inputs/gri30.xml new file mode 100755 index 000000000..da7da5613 --- /dev/null +++ b/data/inputs/gri30.xml @@ -0,0 +1,4877 @@ + + + + + + + + + 300 + 1 + H2:1.0 + + + O H C N Ar + + H2 H O O2 OH H2O HO2 H2O2 C CH + CH2 CH2(S) CH3 CH4 CO CO2 HCO CH2O CH2OH CH3O + CH3OH C2H C2H2 C2H3 C2H4 C2H5 C2H6 HCCO CH2CO HCCOH + N NH NH2 NH3 NNH NO NO2 N2O HNO CN + HCN H2CN HCNN HCNO HOCN HNCO NCO N2 AR C3H7 + C3H8 CH2CHO CH3CHO + + + + + + + + + + + + 300 + 1 + H2:1.0 + + + O H C N Ar + + H2 H O O2 OH H2O HO2 H2O2 C CH + CH2 CH2(S) CH3 CH4 CO CO2 HCO CH2O CH2OH CH3O + CH3OH C2H C2H2 C2H3 C2H4 C2H5 C2H6 HCCO CH2CO HCCOH + N NH NH2 NH3 NNH NO NO2 N2O HNO CN + HCN H2CN HCNN HCNO HOCN HNCO NCO N2 AR C3H7 + C3H8 CH2CHO CH3CHO + + + + + + + + + + + + + + TPIS78 + H:2 + + + + 2.344331120E+000, 7.980520750E-003, -1.947815100E-005, + 2.015720940E-008, -7.376117610E-012, -9.179351730E+002, + 6.830102380E-001 + + + 3.337279200E+000, -4.940247310E-005, 4.994567780E-007, + -1.795663940E-010, 2.002553760E-014, -9.501589220E+002, + -3.205023310E+000 + + + + + linear + 3.800000000E+001 + 2.920000000E+000 + 7.900000000E-001 + 2.800000000E+002 + + + + + + L 7/88 + H:1 + + + + 2.500000000E+000, 7.053328190E-013, -1.995919640E-015, + 2.300816320E-018, -9.277323320E-022, 2.547365990E+004, + -4.466828530E-001 + + + 2.500000010E+000, -2.308429730E-011, 1.615619480E-014, + -4.735152350E-018, 4.981973570E-022, 2.547365990E+004, + -4.466829140E-001 + + + + + atom + 1.450000000E+002 + 2.050000000E+000 + + + + + + L 1/90 + O:1 + + + + 3.168267100E+000, -3.279318840E-003, 6.643063960E-006, + -6.128066240E-009, 2.112659710E-012, 2.912225920E+004, + 2.051933460E+000 + + + 2.569420780E+000, -8.597411370E-005, 4.194845890E-008, + -1.001777990E-011, 1.228336910E-015, 2.921757910E+004, + 4.784338640E+000 + + + + + atom + 8.000000000E+001 + 2.750000000E+000 + + + + + + TPIS89 + O:2 + + + + 3.782456360E+000, -2.996734160E-003, 9.847302010E-006, + -9.681295090E-009, 3.243728370E-012, -1.063943560E+003, + 3.657675730E+000 + + + 3.282537840E+000, 1.483087540E-003, -7.579666690E-007, + 2.094705550E-010, -2.167177940E-014, -1.088457720E+003, + 5.453231290E+000 + + + + + linear + 1.074000000E+002 + 3.458000000E+000 + 1.600000000E+000 + 3.800000000E+000 + + + + + + RUS 78 + O:1 H:1 + + + + 3.992015430E+000, -2.401317520E-003, 4.617938410E-006, + -3.881133330E-009, 1.364114700E-012, 3.615080560E+003, + -1.039254580E-001 + + + 3.092887670E+000, 5.484297160E-004, 1.265052280E-007, + -8.794615560E-011, 1.174123760E-014, 3.858657000E+003, + 4.476696100E+000 + + + + + linear + 8.000000000E+001 + 2.750000000E+000 + + + + + + L 8/89 + H:2 O:1 + + + + 4.198640560E+000, -2.036434100E-003, 6.520402110E-006, + -5.487970620E-009, 1.771978170E-012, -3.029372670E+004, + -8.490322080E-001 + + + 3.033992490E+000, 2.176918040E-003, -1.640725180E-007, + -9.704198700E-011, 1.682009920E-014, -3.000429710E+004, + 4.966770100E+000 + + + + + nonlinear + 5.724000000E+002 + 2.605000000E+000 + 1.844000000E+000 + 4.000000000E+000 + + + + + + L 5/89 + H:1 O:2 + + + + 4.301798010E+000, -4.749120510E-003, 2.115828910E-005, + -2.427638940E-008, 9.292251240E-012, 2.948080400E+002, + 3.716662450E+000 + + + 4.017210900E+000, 2.239820130E-003, -6.336581500E-007, + 1.142463700E-010, -1.079085350E-014, 1.118567130E+002, + 3.785102150E+000 + + + + + nonlinear + 1.074000000E+002 + 3.458000000E+000 + 1.000000000E+000 + + + + + + L 7/88 + H:2 O:2 + + + + 4.276112690E+000, -5.428224170E-004, 1.673357010E-005, + -2.157708130E-008, 8.624543630E-012, -1.770258210E+004, + 3.435050740E+000 + + + 4.165002850E+000, 4.908316940E-003, -1.901392250E-006, + 3.711859860E-010, -2.879083050E-014, -1.786178770E+004, + 2.916156620E+000 + + + + + nonlinear + 1.074000000E+002 + 3.458000000E+000 + 3.800000000E+000 + + + + + + L11/88 + C:1 + + + + 2.554239550E+000, -3.215377240E-004, 7.337922450E-007, + -7.322348890E-010, 2.665214460E-013, 8.544388320E+004, + 4.531308480E+000 + + + 2.492668880E+000, 4.798892840E-005, -7.243350200E-008, + 3.742910290E-011, -4.872778930E-015, 8.545129530E+004, + 4.801503730E+000 + + + + + atom + 7.140000000E+001 + 3.298000000E+000 + + + + + + TPIS79 + C:1 H:1 + + + + 3.489816650E+000, 3.238355410E-004, -1.688990650E-006, + 3.162173270E-009, -1.406090670E-012, 7.079729340E+004, + 2.084011080E+000 + + + 2.878464730E+000, 9.709136810E-004, 1.444456550E-007, + -1.306878490E-010, 1.760793830E-014, 7.101243640E+004, + 5.484979990E+000 + + + + + linear + 8.000000000E+001 + 2.750000000E+000 + + + + + + L S/93 + C:1 H:2 + + + + 3.762678670E+000, 9.688721430E-004, 2.794898410E-006, + -3.850911530E-009, 1.687417190E-012, 4.600404010E+004, + 1.562531850E+000 + + + 2.874101130E+000, 3.656392920E-003, -1.408945970E-006, + 2.601795490E-010, -1.877275670E-014, 4.626360400E+004, + 6.171193240E+000 + + + + + linear + 1.440000000E+002 + 3.800000000E+000 + + + + + + L S/93 + C:1 H:2 + + + + 4.198604110E+000, -2.366614190E-003, 8.232962200E-006, + -6.688159810E-009, 1.943147370E-012, 5.049681630E+004, + -7.691189670E-001 + + + 2.292038420E+000, 4.655886370E-003, -2.011919470E-006, + 4.179060000E-010, -3.397163650E-014, 5.092599970E+004, + 8.626501690E+000 + + + + + linear + 1.440000000E+002 + 3.800000000E+000 + + + + + + L11/89 + C:1 H:3 + + + + 3.673590400E+000, 2.010951750E-003, 5.730218560E-006, + -6.871174250E-009, 2.543857340E-012, 1.644499880E+004, + 1.604564330E+000 + + + 2.285717720E+000, 7.239900370E-003, -2.987143480E-006, + 5.956846440E-010, -4.671543940E-014, 1.677558430E+004, + 8.480071790E+000 + + + + + linear + 1.440000000E+002 + 3.800000000E+000 + + + + + + L 8/88 + C:1 H:4 + + + + 5.149876130E+000, -1.367097880E-002, 4.918005990E-005, + -4.847430260E-008, 1.666939560E-011, -1.024664760E+004, + -4.641303760E+000 + + + 7.485149500E-002, 1.339094670E-002, -5.732858090E-006, + 1.222925350E-009, -1.018152300E-013, -9.468344590E+003, + 1.843731800E+001 + + + + + nonlinear + 1.414000000E+002 + 3.746000000E+000 + 2.600000000E+000 + 1.300000000E+001 + + + + + + TPIS79 + C:1 O:1 + + + + 3.579533470E+000, -6.103536800E-004, 1.016814330E-006, + 9.070058840E-010, -9.044244990E-013, -1.434408600E+004, + 3.508409280E+000 + + + 2.715185610E+000, 2.062527430E-003, -9.988257710E-007, + 2.300530080E-010, -2.036477160E-014, -1.415187240E+004, + 7.818687720E+000 + + + + + linear + 9.810000000E+001 + 3.650000000E+000 + 1.950000000E+000 + 1.800000000E+000 + + + + + + L 7/88 + C:1 O:2 + + + + 2.356773520E+000, 8.984596770E-003, -7.123562690E-006, + 2.459190220E-009, -1.436995480E-013, -4.837196970E+004, + 9.901052220E+000 + + + 3.857460290E+000, 4.414370260E-003, -2.214814040E-006, + 5.234901880E-010, -4.720841640E-014, -4.875916600E+004, + 2.271638060E+000 + + + + + linear + 2.440000000E+002 + 3.763000000E+000 + 2.650000000E+000 + 2.100000000E+000 + + + + + + L12/89 + H:1 C:1 O:1 + + + + 4.221185840E+000, -3.243925320E-003, 1.377994460E-005, + -1.331440930E-008, 4.337688650E-012, 3.839564960E+003, + 3.394372430E+000 + + + 2.772174380E+000, 4.956955260E-003, -2.484456130E-006, + 5.891617780E-010, -5.335087110E-014, 4.011918150E+003, + 9.798344920E+000 + + + + + nonlinear + 4.980000000E+002 + 3.590000000E+000 + + + + + + L 8/88 + H:2 C:1 O:1 + + + + 4.793723150E+000, -9.908333690E-003, 3.732200080E-005, + -3.792852610E-008, 1.317726520E-011, -1.430895670E+004, + 6.028129000E-001 + + + 1.760690080E+000, 9.200000820E-003, -4.422588130E-006, + 1.006412120E-009, -8.838556400E-014, -1.399583230E+004, + 1.365632300E+001 + + + + + nonlinear + 4.980000000E+002 + 3.590000000E+000 + 2.000000000E+000 + + + + + + GUNL93 + C:1 H:3 O:1 + + + + 3.863889180E+000, 5.596723040E-003, 5.932717910E-006, + -1.045320120E-008, 4.369672780E-012, -3.193913670E+003, + 5.473022430E+000 + + + 3.692665690E+000, 8.645767970E-003, -3.751011200E-006, + 7.872346360E-010, -6.485542010E-014, -3.242506270E+003, + 5.810432150E+000 + + + + + nonlinear + 4.170000000E+002 + 3.690000000E+000 + 1.700000000E+000 + 2.000000000E+000 + + + + + + 121686 + C:1 H:3 O:1 + + + + 2.106204000E+000, 7.216595000E-003, 5.338472000E-006, + -7.377636000E-009, 2.075610000E-012, 9.786011000E+002, + 1.315217700E+001 + + + 3.770799000E+000, 7.871497000E-003, -2.656384000E-006, + 3.944431000E-010, -2.112616000E-014, 1.278325200E+002, + 2.929575000E+000 + + + + + nonlinear + 4.170000000E+002 + 3.690000000E+000 + 1.700000000E+000 + 2.000000000E+000 + + + + + + L 8/88 + C:1 H:4 O:1 + + + + 5.715395820E+000, -1.523091290E-002, 6.524411550E-005, + -7.108068890E-008, 2.613526980E-011, -2.564276560E+004, + -1.504098230E+000 + + + 1.789707910E+000, 1.409382920E-002, -6.365008350E-006, + 1.381710850E-009, -1.170602200E-013, -2.537487470E+004, + 1.450236230E+001 + + + + + nonlinear + 4.818000000E+002 + 3.626000000E+000 + 1.000000000E+000 + + + + + + L 1/91 + C:2 H:1 + + + + 2.889657330E+000, 1.340996110E-002, -2.847695010E-005, + 2.947910450E-008, -1.093315110E-011, 6.683939320E+004, + 6.222964380E+000 + + + 3.167806520E+000, 4.752219020E-003, -1.837870770E-006, + 3.041902520E-010, -1.772327700E-014, 6.712106500E+004, + 6.635894750E+000 + + + + + linear + 2.090000000E+002 + 4.100000000E+000 + 2.500000000E+000 + + + + + + L 1/91 + C:2 H:2 + + + + 8.086810940E-001, 2.336156290E-002, -3.551718150E-005, + 2.801524370E-008, -8.500729740E-012, 2.642898070E+004, + 1.393970510E+001 + + + 4.147569640E+000, 5.961666640E-003, -2.372948520E-006, + 4.674121710E-010, -3.612352130E-014, 2.593599920E+004, + -1.230281210E+000 + + + + + linear + 2.090000000E+002 + 4.100000000E+000 + 2.500000000E+000 + + + + + + L 2/92 + C:2 H:3 + + + + 3.212466450E+000, 1.514791620E-003, 2.592094120E-005, + -3.576578470E-008, 1.471508730E-011, 3.485984680E+004, + 8.510540250E+000 + + + 3.016724000E+000, 1.033022920E-002, -4.680823490E-006, + 1.017632880E-009, -8.626070410E-014, 3.461287390E+004, + 7.787323780E+000 + + + + + nonlinear + 2.090000000E+002 + 4.100000000E+000 + 1.000000000E+000 + + + + + + L 1/91 + C:2 H:4 + + + + 3.959201480E+000, -7.570522470E-003, 5.709902920E-005, + -6.915887530E-008, 2.698843730E-011, 5.089775930E+003, + 4.097330960E+000 + + + 2.036111160E+000, 1.464541510E-002, -6.710779150E-006, + 1.472229230E-009, -1.257060610E-013, 4.939886140E+003, + 1.030536930E+001 + + + + + nonlinear + 2.808000000E+002 + 3.971000000E+000 + 1.500000000E+000 + + + + + + L12/92 + C:2 H:5 + + + + 4.306465680E+000, -4.186588920E-003, 4.971428070E-005, + -5.991266060E-008, 2.305090040E-011, 1.284162650E+004, + 4.707209240E+000 + + + 1.954656420E+000, 1.739727220E-002, -7.982066680E-006, + 1.752176890E-009, -1.496415760E-013, 1.285752000E+004, + 1.346243430E+001 + + + + + nonlinear + 2.523000000E+002 + 4.302000000E+000 + 1.500000000E+000 + + + + + + L 8/88 + C:2 H:6 + + + + 4.291424920E+000, -5.501542700E-003, 5.994382880E-005, + -7.084662850E-008, 2.686857710E-011, -1.152220550E+004, + 2.666823160E+000 + + + 1.071881500E+000, 2.168526770E-002, -1.002560670E-005, + 2.214120010E-009, -1.900028900E-013, -1.142639320E+004, + 1.511561070E+001 + + + + + nonlinear + 2.523000000E+002 + 4.302000000E+000 + 1.500000000E+000 + + + + + + SRIC91 + H:1 C:2 O:1 + + + + 2.251721400E+000, 1.765502100E-002, -2.372910100E-005, + 1.727575900E-008, -5.066481100E-012, 2.005944900E+004, + 1.249041700E+001 + + + 5.628205800E+000, 4.085340100E-003, -1.593454700E-006, + 2.862605200E-010, -1.940783200E-014, 1.932721500E+004, + -3.930259500E+000 + + + + + nonlinear + 1.500000000E+002 + 2.500000000E+000 + 1.000000000E+000 + + + + + + L 5/90 + C:2 H:2 O:1 + + + + 2.135836300E+000, 1.811887210E-002, -1.739474740E-005, + 9.343975680E-009, -2.014576150E-012, -7.042918040E+003, + 1.221564800E+001 + + + 4.511297320E+000, 9.003597450E-003, -4.169396350E-006, + 9.233458820E-010, -7.948382010E-014, -7.551053110E+003, + 6.322472050E-001 + + + + + nonlinear + 4.360000000E+002 + 3.970000000E+000 + 2.000000000E+000 + + + + + + SRI91 + C:2 O:1 H:2 + + + + 1.242373300E+000, 3.107220100E-002, -5.086686400E-005, + 4.313713100E-008, -1.401459400E-011, 8.031614300E+003, + 1.387431900E+001 + + + 5.923829100E+000, 6.792360000E-003, -2.565856400E-006, + 4.498784100E-010, -2.994010100E-014, 7.264626000E+003, + -7.601774200E+000 + + + + + nonlinear + 4.360000000E+002 + 3.970000000E+000 + 2.000000000E+000 + + + + + + L 6/88 + N:1 + + + + 2.500000000E+000, 0.000000000E+000, 0.000000000E+000, + 0.000000000E+000, 0.000000000E+000, 5.610463700E+004, + 4.193908700E+000 + + + 2.415942900E+000, 1.748906500E-004, -1.190236900E-007, + 3.022624500E-011, -2.036098200E-015, 5.613377300E+004, + 4.649609600E+000 + + + + + atom + 7.140000000E+001 + 3.298000000E+000 + + + + + + And94 + N:1 H:1 + + + + 3.492908500E+000, 3.117919800E-004, -1.489048400E-006, + 2.481644200E-009, -1.035696700E-012, 4.188062900E+004, + 1.848327800E+000 + + + 2.783692800E+000, 1.329843000E-003, -4.247804700E-007, + 7.834850100E-011, -5.504447000E-015, 4.212084800E+004, + 5.740779900E+000 + + + + + linear + 8.000000000E+001 + 2.650000000E+000 + 4.000000000E+000 + + + + + + And89 + N:1 H:2 + + + + 4.204002900E+000, -2.106138500E-003, 7.106834800E-006, + -5.611519700E-009, 1.644071700E-012, 2.188591000E+004, + -1.418424800E-001 + + + 2.834742100E+000, 3.207308200E-003, -9.339080400E-007, + 1.370295300E-010, -7.920614400E-015, 2.217195700E+004, + 6.520416300E+000 + + + + + nonlinear + 8.000000000E+001 + 2.650000000E+000 + 2.260000000E+000 + 4.000000000E+000 + + + + + + J 6/77 + N:1 H:3 + + + + 4.286027400E+000, -4.660523000E-003, 2.171851300E-005, + -2.280888700E-008, 8.263804600E-012, -6.741728500E+003, + -6.253727700E-001 + + + 2.634452100E+000, 5.666256000E-003, -1.727867600E-006, + 2.386716100E-010, -1.257878600E-014, -6.544695800E+003, + 6.566292800E+000 + + + + + nonlinear + 4.810000000E+002 + 2.920000000E+000 + 1.470000000E+000 + 1.000000000E+001 + + + + + + T07/93 + N:2 H:1 + + + + 4.344692700E+000, -4.849707200E-003, 2.005945900E-005, + -2.172646400E-008, 7.946953900E-012, 2.879197300E+004, + 2.977941000E+000 + + + 3.766754400E+000, 2.891508200E-003, -1.041662000E-006, + 1.684259400E-010, -1.009189600E-014, 2.865069700E+004, + 4.470506700E+000 + + + + + nonlinear + 7.140000000E+001 + 3.798000000E+000 + 1.000000000E+000 + + + + + + RUS 78 + N:1 O:1 + + + + 4.218476300E+000, -4.638976000E-003, 1.104102200E-005, + -9.336135400E-009, 2.803577000E-012, 9.844623000E+003, + 2.280846400E+000 + + + 3.260605600E+000, 1.191104300E-003, -4.291704800E-007, + 6.945766900E-011, -4.033609900E-015, 9.920974600E+003, + 6.369302700E+000 + + + + + linear + 9.753000000E+001 + 3.621000000E+000 + 1.760000000E+000 + 4.000000000E+000 + + + + + + L 7/88 + N:1 O:2 + + + + 3.944031200E+000, -1.585429000E-003, 1.665781200E-005, + -2.047542600E-008, 7.835056400E-012, 2.896617900E+003, + 6.311991700E+000 + + + 4.884754200E+000, 2.172395600E-003, -8.280690600E-007, + 1.574751000E-010, -1.051089500E-014, 2.316498300E+003, + -1.174169500E-001 + + + + + nonlinear + 2.000000000E+002 + 3.500000000E+000 + 1.000000000E+000 + + + + + + L 7/88 + N:2 O:1 + + + + 2.257150200E+000, 1.130472800E-002, -1.367131900E-005, + 9.681980600E-009, -2.930718200E-012, 8.741774400E+003, + 1.075799200E+001 + + + 4.823072900E+000, 2.627025100E-003, -9.585087400E-007, + 1.600071200E-010, -9.775230300E-015, 8.073404800E+003, + -2.201720700E+000 + + + + + linear + 2.324000000E+002 + 3.828000000E+000 + 1.000000000E+000 + + + + + + And93 + H:1 N:1 O:1 + + + + 4.533491600E+000, -5.669617100E-003, 1.847320700E-005, + -1.713709400E-008, 5.545457300E-012, 1.154829700E+004, + 1.749841700E+000 + + + 2.979250900E+000, 3.494405900E-003, -7.854977800E-007, + 5.747959400E-011, -1.933591600E-016, 1.175058200E+004, + 8.606372800E+000 + + + + + nonlinear + 1.167000000E+002 + 3.492000000E+000 + 1.000000000E+000 + + + + + + HBH92 + C:1 N:1 + + + + 3.612935100E+000, -9.555132700E-004, 2.144297700E-006, + -3.151632300E-010, -4.643035600E-013, 5.170834000E+004, + 3.980499500E+000 + + + 3.745980500E+000, 4.345077500E-005, 2.970598400E-007, + -6.865180600E-011, 4.413417300E-015, 5.153618800E+004, + 2.786760100E+000 + + + + + linear + 7.500000000E+001 + 3.856000000E+000 + 1.000000000E+000 + + + + + + GRI/98 + H:1 C:1 N:1 + + + + 2.258988600E+000, 1.005117000E-002, -1.335176300E-005, + 1.009234900E-008, -3.008902800E-012, 1.471263300E+004, + 8.916441900E+000 + + + 3.802239200E+000, 3.146422800E-003, -1.063218500E-006, + 1.661975700E-010, -9.799757000E-015, 1.440729200E+004, + 1.575460100E+000 + + + + + linear + 5.690000000E+002 + 3.630000000E+000 + 1.000000000E+000 + + + + + + 41687 + H:2 C:1 N:1 + + + + 2.851661000E+000, 5.695233100E-003, 1.071140000E-006, + -1.622612000E-009, -2.351108100E-013, 2.863782000E+004, + 8.992751100E+000 + + + 5.209703000E+000, 2.969291100E-003, -2.855589100E-007, + -1.635550000E-010, 3.043258900E-014, 2.767710900E+004, + -4.444478000E+000 + + + + + linear + 5.690000000E+002 + 3.630000000E+000 + 1.000000000E+000 + + + + + + SRI/94 + C:1 N:2 H:1 + + + + 2.524319400E+000, 1.596061900E-002, -1.881635400E-005, + 1.212554000E-008, -3.235737800E-012, 5.426198400E+004, + 1.167587000E+001 + + + 5.894636200E+000, 3.989595900E-003, -1.598238000E-006, + 2.924939500E-010, -2.009468600E-014, 5.345294100E+004, + -5.103050200E+000 + + + + + nonlinear + 1.500000000E+002 + 2.500000000E+000 + 1.000000000E+000 + + + + + + BDEA94 + H:1 N:1 C:1 O:1 + + + + 2.647279890E+000, 1.275053420E-002, -1.047942360E-005, + 4.414328360E-009, -7.575214660E-013, 1.929902520E+004, + 1.073329720E+001 + + + 6.598604560E+000, 3.027786260E-003, -1.077043460E-006, + 1.716665280E-010, -1.014393910E-014, 1.796613390E+004, + -1.033065990E+001 + + + + + nonlinear + 2.324000000E+002 + 3.828000000E+000 + 1.000000000E+000 + + + + + + BDEA94 + H:1 N:1 C:1 O:1 + + + + 3.786049520E+000, 6.886679220E-003, -3.214878640E-006, + 5.171957670E-010, 1.193607880E-014, -2.826984000E+003, + 5.632921620E+000 + + + 5.897848850E+000, 3.167893930E-003, -1.118010640E-006, + 1.772431440E-010, -1.043391770E-014, -3.706533310E+003, + -6.181678250E+000 + + + + + nonlinear + 2.324000000E+002 + 3.828000000E+000 + 1.000000000E+000 + + + + + + BDEA94 + H:1 N:1 C:1 O:1 + + + + 3.630963170E+000, 7.302823570E-003, -2.280500030E-006, + -6.612712980E-010, 3.622357520E-013, -1.558736360E+004, + 6.194577270E+000 + + + 6.223951340E+000, 3.178640040E-003, -1.093787550E-006, + 1.707351630E-010, -9.950219550E-015, -1.665993440E+004, + -8.382247410E+000 + + + + + nonlinear + 2.324000000E+002 + 3.828000000E+000 + 1.000000000E+000 + + + + + + EA 93 + N:1 C:1 O:1 + + + + 2.826930800E+000, 8.805168800E-003, -8.386613400E-006, + 4.801696400E-009, -1.331359500E-012, 1.468247700E+004, + 9.550464600E+000 + + + 5.152184500E+000, 2.305176100E-003, -8.803315300E-007, + 1.478909800E-010, -9.097799600E-015, 1.400412300E+004, + -2.544266000E+000 + + + + + linear + 2.324000000E+002 + 3.828000000E+000 + 1.000000000E+000 + + + + + + 121286 + N:2 + + + + 3.298677000E+000, 1.408240400E-003, -3.963222000E-006, + 5.641515000E-009, -2.444854000E-012, -1.020899900E+003, + 3.950372000E+000 + + + 2.926640000E+000, 1.487976800E-003, -5.684760000E-007, + 1.009703800E-010, -6.753351000E-015, -9.227977000E+002, + 5.980528000E+000 + + + + + linear + 9.753000000E+001 + 3.621000000E+000 + 1.760000000E+000 + 4.000000000E+000 + + + + + + 120186 + Ar:1 + + + + 2.500000000E+000, 0.000000000E+000, 0.000000000E+000, + 0.000000000E+000, 0.000000000E+000, -7.453750000E+002, + 4.366000000E+000 + + + 2.500000000E+000, 0.000000000E+000, 0.000000000E+000, + 0.000000000E+000, 0.000000000E+000, -7.453750000E+002, + 4.366000000E+000 + + + + + atom + 1.365000000E+002 + 3.330000000E+000 + + + + + + L 9/84 + C:3 H:7 + + + + 1.051551800E+000, 2.599198000E-002, 2.380054000E-006, + -1.960956900E-008, 9.373247000E-012, 1.063186300E+004, + 2.112255900E+001 + + + 7.702698700E+000, 1.604420300E-002, -5.283322000E-006, + 7.629859000E-010, -3.939228400E-014, 8.298433600E+003, + -1.548018000E+001 + + + + + nonlinear + 2.668000000E+002 + 4.982000000E+000 + 1.000000000E+000 + + + + + + L 4/85 + C:3 H:8 + + + + 9.335538100E-001, 2.642457900E-002, 6.105972700E-006, + -2.197749900E-008, 9.514925300E-012, -1.395852000E+004, + 1.920169100E+001 + + + 7.534136800E+000, 1.887223900E-002, -6.271849100E-006, + 9.147564900E-010, -4.783806900E-014, -1.646751600E+004, + -1.789234900E+001 + + + + + nonlinear + 2.668000000E+002 + 4.982000000E+000 + 1.000000000E+000 + + + + + + SAND86 + O:1 H:3 C:2 + + + + 3.409062000E+000, 1.073857400E-002, 1.891492000E-006, + -7.158583000E-009, 2.867385000E-012, 1.521476600E+003, + 9.558290000E+000 + + + 5.975670000E+000, 8.130591000E-003, -2.743624000E-006, + 4.070304000E-010, -2.176017000E-014, 4.903218000E+002, + -5.045251000E+000 + + + + + nonlinear + 4.360000000E+002 + 3.970000000E+000 + 2.000000000E+000 + + + + + + L 8/88 + C:2 H:4 O:1 + + + + 4.729459500E+000, -3.193285800E-003, 4.753492100E-005, + -5.745861100E-008, 2.193111200E-011, -2.157287800E+004, + 4.103015900E+000 + + + 5.404110800E+000, 1.172305900E-002, -4.226313700E-006, + 6.837245100E-010, -4.098486300E-014, -2.259312200E+004, + -3.480791700E+000 + + + + + nonlinear + 4.360000000E+002 + 3.970000000E+000 + 2.000000000E+000 + + + + + + + + + + 2 O + M [=] O2 + M + O:2 + O2:1 + + 1.2e+017 -1 0 + + AR:0.83 C2H6:3 CH4:2 CO:1.75 CO2:3.6 H2:2.4 H2O:15.4 + + + + + + + O + H + M [=] OH + M + O:1 H:1 + OH:1 + + 5e+017 -1 0 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + O + H2 [=] H + OH + O:1 H2:1 + H:1 OH:1 + + 38700 2.7 6260 + + + + + + O + HO2 [=] OH + O2 + O:1 HO2:1 + OH:1 O2:1 + + 2e+013 0 0 + + + + + + O + H2O2 [=] OH + HO2 + O:1 H2O2:1 + OH:1 HO2:1 + + 9.63e+006 2 4000 + + + + + + O + CH [=] H + CO + O:1 CH:1 + H:1 CO:1 + + 5.7e+013 0 0 + + + + + + O + CH2 [=] H + HCO + O:1 CH2:1 + H:1 HCO:1 + + 8e+013 0 0 + + + + + + O + CH2(S) [=] H2 + CO + O:1 CH2(S):1 + H2:1 CO:1 + + 1.5e+013 0 0 + + + + + + O + CH2(S) [=] H + HCO + O:1 CH2(S):1 + H:1 HCO:1 + + 1.5e+013 0 0 + + + + + + O + CH3 [=] H + CH2O + O:1 CH3:1 + H:1 CH2O:1 + + 5.06e+013 0 0 + + + + + + O + CH4 [=] OH + CH3 + O:1 CH4:1 + OH:1 CH3:1 + + 1.02e+009 1.5 8600 + + + + + + O + CO (+ M) [=] CO2 (+ M) + O:1 CO:1 + CO2:1 + + 1.8e+010 0 2385 + 6.02e+014 0 3000 + + + AR:0.5 C2H6:3 CH4:2 CO:1.5 CO2:3.5 H2:2 H2O:6 O2:6 + + + + + + + O + HCO [=] OH + CO + O:1 HCO:1 + OH:1 CO:1 + + 3e+013 0 0 + + + + + + O + HCO [=] H + CO2 + O:1 HCO:1 + H:1 CO2:1 + + 3e+013 0 0 + + + + + + O + CH2O [=] OH + HCO + O:1 CH2O:1 + OH:1 HCO:1 + + 3.9e+013 0 3540 + + + + + + O + CH2OH [=] OH + CH2O + O:1 CH2OH:1 + OH:1 CH2O:1 + + 1e+013 0 0 + + + + + + O + CH3O [=] OH + CH2O + O:1 CH3O:1 + OH:1 CH2O:1 + + 1e+013 0 0 + + + + + + O + CH3OH [=] OH + CH2OH + O:1 CH3OH:1 + OH:1 CH2OH:1 + + 388000 2.5 3100 + + + + + + O + CH3OH [=] OH + CH3O + O:1 CH3OH:1 + OH:1 CH3O:1 + + 130000 2.5 5000 + + + + + + O + C2H [=] CH + CO + O:1 C2H:1 + CH:1 CO:1 + + 5e+013 0 0 + + + + + + O + C2H2 [=] H + HCCO + O:1 C2H2:1 + H:1 HCCO:1 + + 1.35e+007 2 1900 + + + + + + O + C2H2 [=] OH + C2H + O:1 C2H2:1 + OH:1 C2H:1 + + 4.6e+019 -1.41 28950 + + + + + + O + C2H2 [=] CO + CH2 + O:1 C2H2:1 + CO:1 CH2:1 + + 6.94e+006 2 1900 + + + + + + O + C2H3 [=] H + CH2CO + O:1 C2H3:1 + H:1 CH2CO:1 + + 3e+013 0 0 + + + + + + O + C2H4 [=] CH3 + HCO + O:1 C2H4:1 + CH3:1 HCO:1 + + 1.25e+007 1.83 220 + + + + + + O + C2H5 [=] CH3 + CH2O + O:1 C2H5:1 + CH3:1 CH2O:1 + + 2.24e+013 0 0 + + + + + + O + C2H6 [=] OH + C2H5 + O:1 C2H6:1 + OH:1 C2H5:1 + + 8.98e+007 1.92 5690 + + + + + + O + HCCO [=] H + 2 CO + O:1 HCCO:1 + H:1 CO:2 + + 1e+014 0 0 + + + + + + O + CH2CO [=] OH + HCCO + O:1 CH2CO:1 + OH:1 HCCO:1 + + 1e+013 0 8000 + + + + + + O + CH2CO [=] CH2 + CO2 + O:1 CH2CO:1 + CH2:1 CO2:1 + + 1.75e+012 0 1350 + + + + + + O2 + CO [=] O + CO2 + O2:1 CO:1 + O:1 CO2:1 + + 2.5e+012 0 47800 + + + + + + O2 + CH2O [=] HO2 + HCO + O2:1 CH2O:1 + HO2:1 HCO:1 + + 1e+014 0 40000 + + + + + + H + O2 + M [=] HO2 + M + H:1 O2:1 + HO2:1 + + 2.8e+018 -0.86 0 + + AR:0 C2H6:1.5 CO:0.75 CO2:1.5 H2O:0 N2:0 O2:0 + + + + + + + H + 2 O2 [=] HO2 + O2 + H:1 O2:2 + HO2:1 O2:1 + + 2.08e+019 -1.24 0 + + + + + + H + O2 + H2O [=] HO2 + H2O + H:1 O2:1 H2O:1 + HO2:1 H2O:1 + + 1.126e+019 -0.76 0 + + + + + + H + O2 + N2 [=] HO2 + N2 + H:1 O2:1 N2:1 + HO2:1 N2:1 + + 2.6e+019 -1.24 0 + + + + + + H + O2 + AR [=] HO2 + AR + H:1 O2:1 AR:1 + HO2:1 AR:1 + + 7e+017 -0.8 0 + + + + + + H + O2 [=] O + OH + H:1 O2:1 + O:1 OH:1 + + 2.65e+016 -0.6707 17041 + + + + + + 2 H + M [=] H2 + M + H:2 + H2:1 + + 1e+018 -1 0 + + AR:0.63 C2H6:3 CH4:2 CO2:0 H2:0 H2O:0 + + + + + + + 2 H + H2 [=] 2 H2 + H:2 H2:1 + H2:2 + + 9e+016 -0.6 0 + + + + + + 2 H + H2O [=] H2 + H2O + H:2 H2O:1 + H2:1 H2O:1 + + 6e+019 -1.25 0 + + + + + + 2 H + CO2 [=] H2 + CO2 + H:2 CO2:1 + H2:1 CO2:1 + + 5.5e+020 -2 0 + + + + + + H + OH + M [=] H2O + M + H:1 OH:1 + H2O:1 + + 2.2e+022 -2 0 + + AR:0.38 C2H6:3 CH4:2 H2:0.73 H2O:3.65 + + + + + + + H + HO2 [=] O + H2O + H:1 HO2:1 + O:1 H2O:1 + + 3.97e+012 0 671 + + + + + + H + HO2 [=] O2 + H2 + H:1 HO2:1 + O2:1 H2:1 + + 4.48e+013 0 1068 + + + + + + H + HO2 [=] 2 OH + H:1 HO2:1 + OH:2 + + 8.4e+013 0 635 + + + + + + H + H2O2 [=] HO2 + H2 + H:1 H2O2:1 + HO2:1 H2:1 + + 1.21e+007 2 5200 + + + + + + H + H2O2 [=] OH + H2O + H:1 H2O2:1 + OH:1 H2O:1 + + 1e+013 0 3600 + + + + + + H + CH [=] C + H2 + H:1 CH:1 + C:1 H2:1 + + 1.65e+014 0 0 + + + + + + H + CH2 (+ M) [=] CH3 (+ M) + H:1 CH2:1 + CH3:1 + + 6e+014 0 0 + 1.04e+026 -2.76 1600 + 0.562 91 5836 8552 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + CH2(S) [=] CH + H2 + H:1 CH2(S):1 + CH:1 H2:1 + + 3e+013 0 0 + + + + + + H + CH3 (+ M) [=] CH4 (+ M) + H:1 CH3:1 + CH4:1 + + 1.39e+016 -0.534 536 + 2.62e+033 -4.76 2440 + 0.783 74 2941 6964 + + AR:0.7 C2H6:3 CH4:3 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + CH4 [=] CH3 + H2 + H:1 CH4:1 + CH3:1 H2:1 + + 6.6e+008 1.62 10840 + + + + + + H + HCO (+ M) [=] CH2O (+ M) + H:1 HCO:1 + CH2O:1 + + 1.09e+012 0.48 -260 + 2.47e+024 -2.57 425 + 0.7824 271 2755 6570 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + HCO [=] H2 + CO + H:1 HCO:1 + H2:1 CO:1 + + 7.34e+013 0 0 + + + + + + H + CH2O (+ M) [=] CH2OH (+ M) + H:1 CH2O:1 + CH2OH:1 + + 5.4e+011 0.454 3600 + 1.27e+032 -4.82 6530 + 0.7187 103 1291 4160 + + C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + CH2O (+ M) [=] CH3O (+ M) + H:1 CH2O:1 + CH3O:1 + + 5.4e+011 0.454 2600 + 2.2e+030 -4.8 5560 + 0.758 94 1555 4200 + + C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + CH2O [=] HCO + H2 + H:1 CH2O:1 + HCO:1 H2:1 + + 5.74e+007 1.9 2742 + + + + + + H + CH2OH (+ M) [=] CH3OH (+ M) + H:1 CH2OH:1 + CH3OH:1 + + 1.055e+012 0.5 86 + 4.36e+031 -4.65 5080 + 0.6 100 90000 10000 + + C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + CH2OH [=] H2 + CH2O + H:1 CH2OH:1 + H2:1 CH2O:1 + + 2e+013 0 0 + + + + + + H + CH2OH [=] OH + CH3 + H:1 CH2OH:1 + OH:1 CH3:1 + + 1.65e+011 0.65 -284 + + + + + + H + CH2OH [=] CH2(S) + H2O + H:1 CH2OH:1 + CH2(S):1 H2O:1 + + 3.28e+013 -0.09 610 + + + + + + H + CH3O (+ M) [=] CH3OH (+ M) + H:1 CH3O:1 + CH3OH:1 + + 2.43e+012 0.515 50 + 4.66e+041 -7.44 14080 + 0.7 100 90000 10000 + + C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + CH3O [=] H + CH2OH + H:1 CH3O:1 + H:1 CH2OH:1 + + 4.15e+007 1.63 1924 + + + + + + H + CH3O [=] H2 + CH2O + H:1 CH3O:1 + H2:1 CH2O:1 + + 2e+013 0 0 + + + + + + H + CH3O [=] OH + CH3 + H:1 CH3O:1 + OH:1 CH3:1 + + 1.5e+012 0.5 -110 + + + + + + H + CH3O [=] CH2(S) + H2O + H:1 CH3O:1 + CH2(S):1 H2O:1 + + 2.62e+014 -0.23 1070 + + + + + + H + CH3OH [=] CH2OH + H2 + H:1 CH3OH:1 + CH2OH:1 H2:1 + + 1.7e+007 2.1 4870 + + + + + + H + CH3OH [=] CH3O + H2 + H:1 CH3OH:1 + CH3O:1 H2:1 + + 4.2e+006 2.1 4870 + + + + + + H + C2H (+ M) [=] C2H2 (+ M) + H:1 C2H:1 + C2H2:1 + + 1e+017 -1 0 + 3.75e+033 -4.8 1900 + 0.6464 132 1315 5566 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + C2H2 (+ M) [=] C2H3 (+ M) + H:1 C2H2:1 + C2H3:1 + + 5.6e+012 0 2400 + 3.8e+040 -7.27 7220 + 0.7507 98.5 1302 4167 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + C2H3 (+ M) [=] C2H4 (+ M) + H:1 C2H3:1 + C2H4:1 + + 6.08e+012 0.27 280 + 1.4e+030 -3.86 3320 + 0.782 207.5 2663 6095 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + C2H3 [=] H2 + C2H2 + H:1 C2H3:1 + H2:1 C2H2:1 + + 3e+013 0 0 + + + + + + H + C2H4 (+ M) [=] C2H5 (+ M) + H:1 C2H4:1 + C2H5:1 + + 5.4e+011 0.454 1820 + 6e+041 -7.62 6970 + 0.9753 210 984 4374 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + C2H4 [=] C2H3 + H2 + H:1 C2H4:1 + C2H3:1 H2:1 + + 1.325e+006 2.53 12240 + + + + + + H + C2H5 (+ M) [=] C2H6 (+ M) + H:1 C2H5:1 + C2H6:1 + + 5.21e+017 -0.99 1580 + 1.99e+041 -7.08 6685 + 0.8422 125 2219 6882 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + C2H5 [=] H2 + C2H4 + H:1 C2H5:1 + H2:1 C2H4:1 + + 2e+012 0 0 + + + + + + H + C2H6 [=] C2H5 + H2 + H:1 C2H6:1 + C2H5:1 H2:1 + + 1.15e+008 1.9 7530 + + + + + + H + HCCO [=] CH2(S) + CO + H:1 HCCO:1 + CH2(S):1 CO:1 + + 1e+014 0 0 + + + + + + H + CH2CO [=] HCCO + H2 + H:1 CH2CO:1 + HCCO:1 H2:1 + + 5e+013 0 8000 + + + + + + H + CH2CO [=] CH3 + CO + H:1 CH2CO:1 + CH3:1 CO:1 + + 1.13e+013 0 3428 + + + + + + H + HCCOH [=] H + CH2CO + H:1 HCCOH:1 + H:1 CH2CO:1 + + 1e+013 0 0 + + + + + + H2 + CO (+ M) [=] CH2O (+ M) + H2:1 CO:1 + CH2O:1 + + 4.3e+007 1.5 79600 + 5.07e+027 -3.42 84350 + 0.932 197 1540 10300 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + OH + H2 [=] H + H2O + OH:1 H2:1 + H:1 H2O:1 + + 2.16e+008 1.51 3430 + + + + + + 2 OH (+ M) [=] H2O2 (+ M) + OH:2 + H2O2:1 + + 7.4e+013 -0.37 0 + 2.3e+018 -0.9 -1700 + 0.7346 94 1756 5182 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + 2 OH [=] O + H2O + OH:2 + O:1 H2O:1 + + 35700 2.4 -2110 + + + + + + OH + HO2 [=] O2 + H2O + OH:1 HO2:1 + O2:1 H2O:1 + + 1.45e+013 0 -500 + + idtag_rxn_287 + + + + + OH + H2O2 [=] HO2 + H2O + OH:1 H2O2:1 + HO2:1 H2O:1 + + 2e+012 0 427 + + idtag_rxn_89 + + + + + OH + H2O2 [=] HO2 + H2O + OH:1 H2O2:1 + HO2:1 H2O:1 + + 1.7e+018 0 29410 + + idtag_rxn_88 + + + + + OH + C [=] H + CO + OH:1 C:1 + H:1 CO:1 + + 5e+013 0 0 + + + + + + OH + CH [=] H + HCO + OH:1 CH:1 + H:1 HCO:1 + + 3e+013 0 0 + + + + + + OH + CH2 [=] H + CH2O + OH:1 CH2:1 + H:1 CH2O:1 + + 2e+013 0 0 + + + + + + OH + CH2 [=] CH + H2O + OH:1 CH2:1 + CH:1 H2O:1 + + 1.13e+007 2 3000 + + + + + + OH + CH2(S) [=] H + CH2O + OH:1 CH2(S):1 + H:1 CH2O:1 + + 3e+013 0 0 + + + + + + OH + CH3 (+ M) [=] CH3OH (+ M) + OH:1 CH3:1 + CH3OH:1 + + 2.79e+018 -1.43 1330 + 4e+036 -5.92 3140 + 0.412 195 5900 6394 + + C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + OH + CH3 [=] CH2 + H2O + OH:1 CH3:1 + CH2:1 H2O:1 + + 5.6e+007 1.6 5420 + + + + + + OH + CH3 [=] CH2(S) + H2O + OH:1 CH3:1 + CH2(S):1 H2O:1 + + 6.44e+017 -1.34 1417 + + + + + + OH + CH4 [=] CH3 + H2O + OH:1 CH4:1 + CH3:1 H2O:1 + + 1e+008 1.6 3120 + + + + + + OH + CO [=] H + CO2 + OH:1 CO:1 + H:1 CO2:1 + + 4.76e+007 1.228 70 + + + + + + OH + HCO [=] H2O + CO + OH:1 HCO:1 + H2O:1 CO:1 + + 5e+013 0 0 + + + + + + OH + CH2O [=] HCO + H2O + OH:1 CH2O:1 + HCO:1 H2O:1 + + 3.43e+009 1.18 -447 + + + + + + OH + CH2OH [=] H2O + CH2O + OH:1 CH2OH:1 + H2O:1 CH2O:1 + + 5e+012 0 0 + + + + + + OH + CH3O [=] H2O + CH2O + OH:1 CH3O:1 + H2O:1 CH2O:1 + + 5e+012 0 0 + + + + + + OH + CH3OH [=] CH2OH + H2O + OH:1 CH3OH:1 + CH2OH:1 H2O:1 + + 1.44e+006 2 -840 + + + + + + OH + CH3OH [=] CH3O + H2O + OH:1 CH3OH:1 + CH3O:1 H2O:1 + + 6.3e+006 2 1500 + + + + + + OH + C2H [=] H + HCCO + OH:1 C2H:1 + H:1 HCCO:1 + + 2e+013 0 0 + + + + + + OH + C2H2 [=] H + CH2CO + OH:1 C2H2:1 + H:1 CH2CO:1 + + 0.000218 4.5 -1000 + + + + + + OH + C2H2 [=] H + HCCOH + OH:1 C2H2:1 + H:1 HCCOH:1 + + 504000 2.3 13500 + + + + + + OH + C2H2 [=] C2H + H2O + OH:1 C2H2:1 + C2H:1 H2O:1 + + 3.37e+007 2 14000 + + + + + + OH + C2H2 [=] CH3 + CO + OH:1 C2H2:1 + CH3:1 CO:1 + + 0.000483 4 -2000 + + + + + + OH + C2H3 [=] H2O + C2H2 + OH:1 C2H3:1 + H2O:1 C2H2:1 + + 5e+012 0 0 + + + + + + OH + C2H4 [=] C2H3 + H2O + OH:1 C2H4:1 + C2H3:1 H2O:1 + + 3.6e+006 2 2500 + + + + + + OH + C2H6 [=] C2H5 + H2O + OH:1 C2H6:1 + C2H5:1 H2O:1 + + 3.54e+006 2.12 870 + + + + + + OH + CH2CO [=] HCCO + H2O + OH:1 CH2CO:1 + HCCO:1 H2O:1 + + 7.5e+012 0 2000 + + + + + + 2 HO2 [=] O2 + H2O2 + HO2:2 + O2:1 H2O2:1 + + 1.3e+011 0 -1630 + + idtag_rxn_116 + + + + + 2 HO2 [=] O2 + H2O2 + HO2:2 + O2:1 H2O2:1 + + 4.2e+014 0 12000 + + idtag_rxn_115 + + + + + HO2 + CH2 [=] OH + CH2O + HO2:1 CH2:1 + OH:1 CH2O:1 + + 2e+013 0 0 + + + + + + HO2 + CH3 [=] O2 + CH4 + HO2:1 CH3:1 + O2:1 CH4:1 + + 1e+012 0 0 + + + + + + HO2 + CH3 [=] OH + CH3O + HO2:1 CH3:1 + OH:1 CH3O:1 + + 3.78e+013 0 0 + + + + + + HO2 + CO [=] OH + CO2 + HO2:1 CO:1 + OH:1 CO2:1 + + 1.5e+014 0 23600 + + + + + + HO2 + CH2O [=] HCO + H2O2 + HO2:1 CH2O:1 + HCO:1 H2O2:1 + + 5.6e+006 2 12000 + + + + + + C + O2 [=] O + CO + C:1 O2:1 + O:1 CO:1 + + 5.8e+013 0 576 + + + + + + C + CH2 [=] H + C2H + C:1 CH2:1 + H:1 C2H:1 + + 5e+013 0 0 + + + + + + C + CH3 [=] H + C2H2 + C:1 CH3:1 + H:1 C2H2:1 + + 5e+013 0 0 + + + + + + CH + O2 [=] O + HCO + CH:1 O2:1 + O:1 HCO:1 + + 6.71e+013 0 0 + + + + + + CH + H2 [=] H + CH2 + CH:1 H2:1 + H:1 CH2:1 + + 1.08e+014 0 3110 + + + + + + CH + H2O [=] H + CH2O + CH:1 H2O:1 + H:1 CH2O:1 + + 5.71e+012 0 -755 + + + + + + CH + CH2 [=] H + C2H2 + CH:1 CH2:1 + H:1 C2H2:1 + + 4e+013 0 0 + + + + + + CH + CH3 [=] H + C2H3 + CH:1 CH3:1 + H:1 C2H3:1 + + 3e+013 0 0 + + + + + + CH + CH4 [=] H + C2H4 + CH:1 CH4:1 + H:1 C2H4:1 + + 6e+013 0 0 + + + + + + CH + CO (+ M) [=] HCCO (+ M) + CH:1 CO:1 + HCCO:1 + + 5e+013 0 0 + 2.69e+028 -3.74 1936 + 0.5757 237 1652 5069 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + CH + CO2 [=] HCO + CO + CH:1 CO2:1 + HCO:1 CO:1 + + 1.9e+014 0 15792 + + + + + + CH + CH2O [=] H + CH2CO + CH:1 CH2O:1 + H:1 CH2CO:1 + + 9.46e+013 0 -515 + + + + + + CH + HCCO [=] CO + C2H2 + CH:1 HCCO:1 + CO:1 C2H2:1 + + 5e+013 0 0 + + + + + + CH2 + O2 =] OH + H + CO + CH2:1 O2:1 + OH:1 H:1 CO:1 + + 5e+012 0 1500 + + + + + + CH2 + H2 [=] H + CH3 + CH2:1 H2:1 + H:1 CH3:1 + + 500000 2 7230 + + + + + + 2 CH2 [=] H2 + C2H2 + CH2:2 + H2:1 C2H2:1 + + 1.6e+015 0 11944 + + + + + + CH2 + CH3 [=] H + C2H4 + CH2:1 CH3:1 + H:1 C2H4:1 + + 4e+013 0 0 + + + + + + CH2 + CH4 [=] 2 CH3 + CH2:1 CH4:1 + CH3:2 + + 2.46e+006 2 8270 + + + + + + CH2 + CO (+ M) [=] CH2CO (+ M) + CH2:1 CO:1 + CH2CO:1 + + 8.1e+011 0.5 4510 + 2.69e+033 -5.11 7095 + 0.5907 275 1226 5185 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + CH2 + HCCO [=] C2H3 + CO + CH2:1 HCCO:1 + C2H3:1 CO:1 + + 3e+013 0 0 + + + + + + CH2(S) + N2 [=] CH2 + N2 + CH2(S):1 N2:1 + CH2:1 N2:1 + + 1.5e+013 0 600 + + + + + + CH2(S) + AR [=] CH2 + AR + CH2(S):1 AR:1 + CH2:1 AR:1 + + 9e+012 0 600 + + + + + + CH2(S) + O2 [=] H + OH + CO + CH2(S):1 O2:1 + H:1 OH:1 CO:1 + + 2.8e+013 0 0 + + + + + + CH2(S) + O2 [=] CO + H2O + CH2(S):1 O2:1 + CO:1 H2O:1 + + 1.2e+013 0 0 + + + + + + CH2(S) + H2 [=] CH3 + H + CH2(S):1 H2:1 + CH3:1 H:1 + + 7e+013 0 0 + + + + + + CH2(S) + H2O (+ M) [=] CH3OH (+ M) + CH2(S):1 H2O:1 + CH3OH:1 + + 4.82e+017 -1.16 1145 + 1.88e+038 -6.36 5040 + 0.6027 208 3922 10180 + + C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + CH2(S) + H2O [=] CH2 + H2O + CH2(S):1 H2O:1 + CH2:1 H2O:1 + + 3e+013 0 0 + + + + + + CH2(S) + CH3 [=] H + C2H4 + CH2(S):1 CH3:1 + H:1 C2H4:1 + + 1.2e+013 0 -570 + + + + + + CH2(S) + CH4 [=] 2 CH3 + CH2(S):1 CH4:1 + CH3:2 + + 1.6e+013 0 -570 + + + + + + CH2(S) + CO [=] CH2 + CO + CH2(S):1 CO:1 + CH2:1 CO:1 + + 9e+012 0 0 + + + + + + CH2(S) + CO2 [=] CH2 + CO2 + CH2(S):1 CO2:1 + CH2:1 CO2:1 + + 7e+012 0 0 + + + + + + CH2(S) + CO2 [=] CO + CH2O + CH2(S):1 CO2:1 + CO:1 CH2O:1 + + 1.4e+013 0 0 + + + + + + CH2(S) + C2H6 [=] CH3 + C2H5 + CH2(S):1 C2H6:1 + CH3:1 C2H5:1 + + 4e+013 0 -550 + + + + + + CH3 + O2 [=] O + CH3O + CH3:1 O2:1 + O:1 CH3O:1 + + 3.56e+013 0 30480 + + + + + + CH3 + O2 [=] OH + CH2O + CH3:1 O2:1 + OH:1 CH2O:1 + + 2.31e+012 0 20315 + + + + + + CH3 + H2O2 [=] HO2 + CH4 + CH3:1 H2O2:1 + HO2:1 CH4:1 + + 24500 2.47 5180 + + + + + + 2 CH3 (+ M) [=] C2H6 (+ M) + CH3:2 + C2H6:1 + + 6.77e+016 -1.18 654 + 3.4e+041 -7.03 2762 + 0.619 73.2 1180 9999 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + 2 CH3 [=] H + C2H5 + CH3:2 + H:1 C2H5:1 + + 6.84e+012 0.1 10600 + + + + + + CH3 + HCO [=] CH4 + CO + CH3:1 HCO:1 + CH4:1 CO:1 + + 2.648e+013 0 0 + + + + + + CH3 + CH2O [=] HCO + CH4 + CH3:1 CH2O:1 + HCO:1 CH4:1 + + 3320 2.81 5860 + + + + + + CH3 + CH3OH [=] CH2OH + CH4 + CH3:1 CH3OH:1 + CH2OH:1 CH4:1 + + 3e+007 1.5 9940 + + + + + + CH3 + CH3OH [=] CH3O + CH4 + CH3:1 CH3OH:1 + CH3O:1 CH4:1 + + 1e+007 1.5 9940 + + + + + + CH3 + C2H4 [=] C2H3 + CH4 + CH3:1 C2H4:1 + C2H3:1 CH4:1 + + 227000 2 9200 + + + + + + CH3 + C2H6 [=] C2H5 + CH4 + CH3:1 C2H6:1 + C2H5:1 CH4:1 + + 6.14e+006 1.74 10450 + + + + + + HCO + H2O [=] H + CO + H2O + HCO:1 H2O:1 + H:1 CO:1 H2O:1 + + 1.5e+018 -1 17000 + + + + + + HCO + M [=] H + CO + M + HCO:1 + H:1 CO:1 + + 1.87e+017 -1 17000 + + C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:0 + + + + + + + HCO + O2 [=] HO2 + CO + HCO:1 O2:1 + HO2:1 CO:1 + + 1.345e+013 0 400 + + + + + + CH2OH + O2 [=] HO2 + CH2O + CH2OH:1 O2:1 + HO2:1 CH2O:1 + + 1.8e+013 0 900 + + + + + + CH3O + O2 [=] HO2 + CH2O + CH3O:1 O2:1 + HO2:1 CH2O:1 + + 4.28e-013 7.6 -3530 + + + + + + C2H + O2 [=] HCO + CO + C2H:1 O2:1 + HCO:1 CO:1 + + 1e+013 0 -755 + + + + + + C2H + H2 [=] H + C2H2 + C2H:1 H2:1 + H:1 C2H2:1 + + 5.68e+010 0.9 1993 + + + + + + C2H3 + O2 [=] HCO + CH2O + C2H3:1 O2:1 + HCO:1 CH2O:1 + + 4.58e+016 -1.39 1015 + + + + + + C2H4 (+ M) [=] H2 + C2H2 (+ M) + C2H4:1 + H2:1 C2H2:1 + + 8e+012 0.44 86770 + 1.58e+051 -9.3 97800 + 0.7345 180 1035 5417 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + C2H5 + O2 [=] HO2 + C2H4 + C2H5:1 O2:1 + HO2:1 C2H4:1 + + 8.4e+011 0 3875 + + + + + + HCCO + O2 [=] OH + 2 CO + HCCO:1 O2:1 + OH:1 CO:2 + + 3.2e+012 0 854 + + + + + + 2 HCCO [=] 2 CO + C2H2 + HCCO:2 + CO:2 C2H2:1 + + 1e+013 0 0 + + + + + + N + NO [=] N2 + O + N:1 NO:1 + N2:1 O:1 + + 2.7e+013 0 355 + + + + + + N + O2 [=] NO + O + N:1 O2:1 + NO:1 O:1 + + 9e+009 1 6500 + + + + + + N + OH [=] NO + H + N:1 OH:1 + NO:1 H:1 + + 3.36e+013 0 385 + + + + + + N2O + O [=] N2 + O2 + N2O:1 O:1 + N2:1 O2:1 + + 1.4e+012 0 10810 + + + + + + N2O + O [=] 2 NO + N2O:1 O:1 + NO:2 + + 2.9e+013 0 23150 + + + + + + N2O + H [=] N2 + OH + N2O:1 H:1 + N2:1 OH:1 + + 3.87e+014 0 18880 + + + + + + N2O + OH [=] N2 + HO2 + N2O:1 OH:1 + N2:1 HO2:1 + + 2e+012 0 21060 + + + + + + N2O (+ M) [=] N2 + O (+ M) + N2O:1 + N2:1 O:1 + + 7.91e+010 0 56020 + 6.37e+014 0 56640 + + + AR:0.625 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + HO2 + NO [=] NO2 + OH + HO2:1 NO:1 + NO2:1 OH:1 + + 2.11e+012 0 -480 + + + + + + NO + O + M [=] NO2 + M + NO:1 O:1 + NO2:1 + + 1.06e+020 -1.41 0 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + NO2 + O [=] NO + O2 + NO2:1 O:1 + NO:1 O2:1 + + 3.9e+012 0 -240 + + + + + + NO2 + H [=] NO + OH + NO2:1 H:1 + NO:1 OH:1 + + 1.32e+014 0 360 + + + + + + NH + O [=] NO + H + NH:1 O:1 + NO:1 H:1 + + 4e+013 0 0 + + + + + + NH + H [=] N + H2 + NH:1 H:1 + N:1 H2:1 + + 3.2e+013 0 330 + + + + + + NH + OH [=] HNO + H + NH:1 OH:1 + HNO:1 H:1 + + 2e+013 0 0 + + + + + + NH + OH [=] N + H2O + NH:1 OH:1 + N:1 H2O:1 + + 2e+009 1.2 0 + + + + + + NH + O2 [=] HNO + O + NH:1 O2:1 + HNO:1 O:1 + + 461000 2 6500 + + + + + + NH + O2 [=] NO + OH + NH:1 O2:1 + NO:1 OH:1 + + 1.28e+006 1.5 100 + + + + + + NH + N [=] N2 + H + NH:1 N:1 + N2:1 H:1 + + 1.5e+013 0 0 + + + + + + NH + H2O [=] HNO + H2 + NH:1 H2O:1 + HNO:1 H2:1 + + 2e+013 0 13850 + + + + + + NH + NO [=] N2 + OH + NH:1 NO:1 + N2:1 OH:1 + + 2.16e+013 -0.23 0 + + + + + + NH + NO [=] N2O + H + NH:1 NO:1 + N2O:1 H:1 + + 3.65e+014 -0.45 0 + + + + + + NH2 + O [=] OH + NH + NH2:1 O:1 + OH:1 NH:1 + + 3e+012 0 0 + + + + + + NH2 + O [=] H + HNO + NH2:1 O:1 + H:1 HNO:1 + + 3.9e+013 0 0 + + + + + + NH2 + H [=] NH + H2 + NH2:1 H:1 + NH:1 H2:1 + + 4e+013 0 3650 + + + + + + NH2 + OH [=] NH + H2O + NH2:1 OH:1 + NH:1 H2O:1 + + 9e+007 1.5 -460 + + + + + + NNH [=] N2 + H + NNH:1 + N2:1 H:1 + + 3.3e+008 0 0 + + + + + + NNH + M [=] N2 + H + M + NNH:1 + N2:1 H:1 + + 1.3e+014 -0.11 4980 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + NNH + O2 [=] HO2 + N2 + NNH:1 O2:1 + HO2:1 N2:1 + + 5e+012 0 0 + + + + + + NNH + O [=] OH + N2 + NNH:1 O:1 + OH:1 N2:1 + + 2.5e+013 0 0 + + + + + + NNH + O [=] NH + NO + NNH:1 O:1 + NH:1 NO:1 + + 7e+013 0 0 + + + + + + NNH + H [=] H2 + N2 + NNH:1 H:1 + H2:1 N2:1 + + 5e+013 0 0 + + + + + + NNH + OH [=] H2O + N2 + NNH:1 OH:1 + H2O:1 N2:1 + + 2e+013 0 0 + + + + + + NNH + CH3 [=] CH4 + N2 + NNH:1 CH3:1 + CH4:1 N2:1 + + 2.5e+013 0 0 + + + + + + H + NO + M [=] HNO + M + H:1 NO:1 + HNO:1 + + 4.48e+019 -1.32 740 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + HNO + O [=] NO + OH + HNO:1 O:1 + NO:1 OH:1 + + 2.5e+013 0 0 + + + + + + HNO + H [=] H2 + NO + HNO:1 H:1 + H2:1 NO:1 + + 9e+011 0.72 660 + + + + + + HNO + OH [=] NO + H2O + HNO:1 OH:1 + NO:1 H2O:1 + + 1.3e+007 1.9 -950 + + + + + + HNO + O2 [=] HO2 + NO + HNO:1 O2:1 + HO2:1 NO:1 + + 1e+013 0 13000 + + + + + + CN + O [=] CO + N + CN:1 O:1 + CO:1 N:1 + + 7.7e+013 0 0 + + + + + + CN + OH [=] NCO + H + CN:1 OH:1 + NCO:1 H:1 + + 4e+013 0 0 + + + + + + CN + H2O [=] HCN + OH + CN:1 H2O:1 + HCN:1 OH:1 + + 8e+012 0 7460 + + + + + + CN + O2 [=] NCO + O + CN:1 O2:1 + NCO:1 O:1 + + 6.14e+012 0 -440 + + + + + + CN + H2 [=] HCN + H + CN:1 H2:1 + HCN:1 H:1 + + 295000 2.45 2240 + + + + + + NCO + O [=] NO + CO + NCO:1 O:1 + NO:1 CO:1 + + 2.35e+013 0 0 + + + + + + NCO + H [=] NH + CO + NCO:1 H:1 + NH:1 CO:1 + + 5.4e+013 0 0 + + + + + + NCO + OH [=] NO + H + CO + NCO:1 OH:1 + NO:1 H:1 CO:1 + + 2.5e+012 0 0 + + + + + + NCO + N [=] N2 + CO + NCO:1 N:1 + N2:1 CO:1 + + 2e+013 0 0 + + + + + + NCO + O2 [=] NO + CO2 + NCO:1 O2:1 + NO:1 CO2:1 + + 2e+012 0 20000 + + + + + + NCO + M [=] N + CO + M + NCO:1 + N:1 CO:1 + + 3.1e+014 0 54050 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + NCO + NO [=] N2O + CO + NCO:1 NO:1 + N2O:1 CO:1 + + 1.9e+017 -1.52 740 + + + + + + NCO + NO [=] N2 + CO2 + NCO:1 NO:1 + N2:1 CO2:1 + + 3.8e+018 -2 800 + + + + + + HCN + M [=] H + CN + M + HCN:1 + H:1 CN:1 + + 1.04e+029 -3.3 126600 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + HCN + O [=] NCO + H + HCN:1 O:1 + NCO:1 H:1 + + 20300 2.64 4980 + + + + + + HCN + O [=] NH + CO + HCN:1 O:1 + NH:1 CO:1 + + 5070 2.64 4980 + + + + + + HCN + O [=] CN + OH + HCN:1 O:1 + CN:1 OH:1 + + 3.91e+009 1.58 26600 + + + + + + HCN + OH [=] HOCN + H + HCN:1 OH:1 + HOCN:1 H:1 + + 1.1e+006 2.03 13370 + + + + + + HCN + OH [=] HNCO + H + HCN:1 OH:1 + HNCO:1 H:1 + + 4400 2.26 6400 + + + + + + HCN + OH [=] NH2 + CO + HCN:1 OH:1 + NH2:1 CO:1 + + 160 2.56 9000 + + + + + + H + HCN (+ M) [=] H2CN (+ M) + H:1 HCN:1 + H2CN:1 + + 3.3e+013 0 0 + 1.4e+026 -3.4 1900 + + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H2CN + N [=] N2 + CH2 + H2CN:1 N:1 + N2:1 CH2:1 + + 6e+013 0 400 + + + + + + C + N2 [=] CN + N + C:1 N2:1 + CN:1 N:1 + + 6.3e+013 0 46020 + + + + + + CH + N2 [=] HCN + N + CH:1 N2:1 + HCN:1 N:1 + + 3.12e+009 0.88 20130 + + + + + + CH + N2 (+ M) [=] HCNN (+ M) + CH:1 N2:1 + HCNN:1 + + 3.1e+012 0.15 0 + 1.3e+025 -3.16 740 + 0.667 235 2117 4536 + + AR:1 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + CH2 + N2 [=] HCN + NH + CH2:1 N2:1 + HCN:1 NH:1 + + 1e+013 0 74000 + + + + + + CH2(S) + N2 [=] NH + HCN + CH2(S):1 N2:1 + NH:1 HCN:1 + + 1e+011 0 65000 + + + + + + C + NO [=] CN + O + C:1 NO:1 + CN:1 O:1 + + 1.9e+013 0 0 + + + + + + C + NO [=] CO + N + C:1 NO:1 + CO:1 N:1 + + 2.9e+013 0 0 + + + + + + CH + NO [=] HCN + O + CH:1 NO:1 + HCN:1 O:1 + + 4.1e+013 0 0 + + + + + + CH + NO [=] H + NCO + CH:1 NO:1 + H:1 NCO:1 + + 1.62e+013 0 0 + + + + + + CH + NO [=] N + HCO + CH:1 NO:1 + N:1 HCO:1 + + 2.46e+013 0 0 + + + + + + CH2 + NO [=] H + HNCO + CH2:1 NO:1 + H:1 HNCO:1 + + 3.1e+017 -1.38 1270 + + + + + + CH2 + NO [=] OH + HCN + CH2:1 NO:1 + OH:1 HCN:1 + + 2.9e+014 -0.69 760 + + + + + + CH2 + NO [=] H + HCNO + CH2:1 NO:1 + H:1 HCNO:1 + + 3.8e+013 -0.36 580 + + + + + + CH2(S) + NO [=] H + HNCO + CH2(S):1 NO:1 + H:1 HNCO:1 + + 3.1e+017 -1.38 1270 + + + + + + CH2(S) + NO [=] OH + HCN + CH2(S):1 NO:1 + OH:1 HCN:1 + + 2.9e+014 -0.69 760 + + + + + + CH2(S) + NO [=] H + HCNO + CH2(S):1 NO:1 + H:1 HCNO:1 + + 3.8e+013 -0.36 580 + + + + + + CH3 + NO [=] HCN + H2O + CH3:1 NO:1 + HCN:1 H2O:1 + + 9.6e+013 0 28800 + + + + + + CH3 + NO [=] H2CN + OH + CH3:1 NO:1 + H2CN:1 OH:1 + + 1e+012 0 21750 + + + + + + HCNN + O [=] CO + H + N2 + HCNN:1 O:1 + CO:1 H:1 N2:1 + + 2.2e+013 0 0 + + + + + + HCNN + O [=] HCN + NO + HCNN:1 O:1 + HCN:1 NO:1 + + 2e+012 0 0 + + + + + + HCNN + O2 [=] O + HCO + N2 + HCNN:1 O2:1 + O:1 HCO:1 N2:1 + + 1.2e+013 0 0 + + + + + + HCNN + OH [=] H + HCO + N2 + HCNN:1 OH:1 + H:1 HCO:1 N2:1 + + 1.2e+013 0 0 + + + + + + HCNN + H [=] CH2 + N2 + HCNN:1 H:1 + CH2:1 N2:1 + + 1e+014 0 0 + + + + + + HNCO + O [=] NH + CO2 + HNCO:1 O:1 + NH:1 CO2:1 + + 9.8e+007 1.41 8500 + + + + + + HNCO + O [=] HNO + CO + HNCO:1 O:1 + HNO:1 CO:1 + + 1.5e+008 1.57 44000 + + + + + + HNCO + O [=] NCO + OH + HNCO:1 O:1 + NCO:1 OH:1 + + 2.2e+006 2.11 11400 + + + + + + HNCO + H [=] NH2 + CO + HNCO:1 H:1 + NH2:1 CO:1 + + 2.25e+007 1.7 3800 + + + + + + HNCO + H [=] H2 + NCO + HNCO:1 H:1 + H2:1 NCO:1 + + 105000 2.5 13300 + + + + + + HNCO + OH [=] NCO + H2O + HNCO:1 OH:1 + NCO:1 H2O:1 + + 3.3e+007 1.5 3600 + + + + + + HNCO + OH [=] NH2 + CO2 + HNCO:1 OH:1 + NH2:1 CO2:1 + + 3.3e+006 1.5 3600 + + + + + + HNCO + M [=] NH + CO + M + HNCO:1 + NH:1 CO:1 + + 1.18e+016 0 84720 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + HCNO + H [=] H + HNCO + HCNO:1 H:1 + H:1 HNCO:1 + + 2.1e+015 -0.69 2850 + + + + + + HCNO + H [=] OH + HCN + HCNO:1 H:1 + OH:1 HCN:1 + + 2.7e+011 0.18 2120 + + + + + + HCNO + H [=] NH2 + CO + HCNO:1 H:1 + NH2:1 CO:1 + + 1.7e+014 -0.75 2890 + + + + + + HOCN + H [=] H + HNCO + HOCN:1 H:1 + H:1 HNCO:1 + + 2e+007 2 2000 + + + + + + HCCO + NO [=] HCNO + CO + HCCO:1 NO:1 + HCNO:1 CO:1 + + 9e+012 0 0 + + + + + + CH3 + N [=] H2CN + H + CH3:1 N:1 + H2CN:1 H:1 + + 6.1e+014 -0.31 290 + + + + + + CH3 + N [=] HCN + H2 + CH3:1 N:1 + HCN:1 H2:1 + + 3.7e+012 0.15 -90 + + + + + + NH3 + H [=] NH2 + H2 + NH3:1 H:1 + NH2:1 H2:1 + + 540000 2.4 9915 + + + + + + NH3 + OH [=] NH2 + H2O + NH3:1 OH:1 + NH2:1 H2O:1 + + 5e+007 1.6 955 + + + + + + NH3 + O [=] NH2 + OH + NH3:1 O:1 + NH2:1 OH:1 + + 9.4e+006 1.94 6460 + + + + + + NH + CO2 [=] HNO + CO + NH:1 CO2:1 + HNO:1 CO:1 + + 1e+013 0 14350 + + + + + + CN + NO2 [=] NCO + NO + CN:1 NO2:1 + NCO:1 NO:1 + + 6.16e+015 -0.752 345 + + + + + + NCO + NO2 [=] N2O + CO2 + NCO:1 NO2:1 + N2O:1 CO2:1 + + 3.25e+012 0 -705 + + + + + + N + CO2 [=] NO + CO + N:1 CO2:1 + NO:1 CO:1 + + 3e+012 0 11300 + + + + + + O + CH3 =] H + H2 + CO + O:1 CH3:1 + H:1 H2:1 CO:1 + + 3.37e+013 0 0 + + + + + + O + C2H4 [=] H + CH2CHO + O:1 C2H4:1 + H:1 CH2CHO:1 + + 6.7e+006 1.83 220 + + + + + + O + C2H5 [=] H + CH3CHO + O:1 C2H5:1 + H:1 CH3CHO:1 + + 1.096e+014 0 0 + + + + + + OH + HO2 [=] O2 + H2O + OH:1 HO2:1 + O2:1 H2O:1 + + 5e+015 0 17330 + + idtag_rxn_87 + + + + + OH + CH3 =] H2 + CH2O + OH:1 CH3:1 + H2:1 CH2O:1 + + 8e+009 0.5 -1755 + + + + + + CH + H2 (+ M) [=] CH3 (+ M) + CH:1 H2:1 + CH3:1 + + 1.97e+012 0.43 -370 + 4.82e+025 -2.8 590 + 0.578 122 2535 9365 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + CH2 + O2 =] 2 H + CO2 + CH2:1 O2:1 + H:2 CO2:1 + + 5.8e+012 0 1500 + + + + + + CH2 + O2 [=] O + CH2O + CH2:1 O2:1 + O:1 CH2O:1 + + 2.4e+012 0 1500 + + + + + + CH2 + CH2 =] 2 H + C2H2 + CH2:1 CH2:1 + H:2 C2H2:1 + + 2e+014 0 10989 + + + + + + CH2(S) + H2O =] H2 + CH2O + CH2(S):1 H2O:1 + H2:1 CH2O:1 + + 6.82e+010 0.25 -935 + + + + + + C2H3 + O2 [=] O + CH2CHO + C2H3:1 O2:1 + O:1 CH2CHO:1 + + 3.03e+011 0.29 11 + + + + + + C2H3 + O2 [=] HO2 + C2H2 + C2H3:1 O2:1 + HO2:1 C2H2:1 + + 1.337e+006 1.61 -384 + + + + + + O + CH3CHO [=] OH + CH2CHO + O:1 CH3CHO:1 + OH:1 CH2CHO:1 + + 5.84e+012 0 1808 + + + + + + O + CH3CHO =] OH + CH3 + CO + O:1 CH3CHO:1 + OH:1 CH3:1 CO:1 + + 5.84e+012 0 1808 + + + + + + O2 + CH3CHO =] HO2 + CH3 + CO + O2:1 CH3CHO:1 + HO2:1 CH3:1 CO:1 + + 3.01e+013 0 39150 + + + + + + H + CH3CHO [=] CH2CHO + H2 + H:1 CH3CHO:1 + CH2CHO:1 H2:1 + + 2.05e+009 1.16 2405 + + + + + + H + CH3CHO =] CH3 + H2 + CO + H:1 CH3CHO:1 + CH3:1 H2:1 CO:1 + + 2.05e+009 1.16 2405 + + + + + + OH + CH3CHO =] CH3 + H2O + CO + OH:1 CH3CHO:1 + CH3:1 H2O:1 CO:1 + + 2.343e+010 0.73 -1113 + + + + + + HO2 + CH3CHO =] CH3 + H2O2 + CO + HO2:1 CH3CHO:1 + CH3:1 H2O2:1 CO:1 + + 3.01e+012 0 11923 + + + + + + CH3 + CH3CHO =] CH3 + CH4 + CO + CH3:1 CH3CHO:1 + CH3:1 CH4:1 CO:1 + + 2.72e+006 1.77 5920 + + + + + + H + CH2CO (+ M) [=] CH2CHO (+ M) + H:1 CH2CO:1 + CH2CHO:1 + + 4.865e+011 0.422 -1755 + 1.012e+042 -7.63 3854 + 0.465 201 1773 5333 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + O + CH2CHO =] H + CH2 + CO2 + O:1 CH2CHO:1 + H:1 CH2:1 CO2:1 + + 1.5e+014 0 0 + + + + + + O2 + CH2CHO =] OH + CO + CH2O + O2:1 CH2CHO:1 + OH:1 CO:1 CH2O:1 + + 1.81e+010 0 0 + + + + + + O2 + CH2CHO =] OH + 2 HCO + O2:1 CH2CHO:1 + OH:1 HCO:2 + + 2.35e+010 0 0 + + + + + + H + CH2CHO [=] CH3 + HCO + H:1 CH2CHO:1 + CH3:1 HCO:1 + + 2.2e+013 0 0 + + + + + + H + CH2CHO [=] CH2CO + H2 + H:1 CH2CHO:1 + CH2CO:1 H2:1 + + 1.1e+013 0 0 + + + + + + OH + CH2CHO [=] H2O + CH2CO + OH:1 CH2CHO:1 + H2O:1 CH2CO:1 + + 1.2e+013 0 0 + + + + + + OH + CH2CHO [=] HCO + CH2OH + OH:1 CH2CHO:1 + HCO:1 CH2OH:1 + + 3.01e+013 0 0 + + + + + + CH3 + C2H5 (+ M) [=] C3H8 (+ M) + CH3:1 C2H5:1 + C3H8:1 + + 9.43e+012 0 0 + 2.71e+074 -16.82 13065 + 0.1527 291 2742 7748 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + O + C3H8 [=] OH + C3H7 + O:1 C3H8:1 + OH:1 C3H7:1 + + 193000 2.68 3716 + + + + + + H + C3H8 [=] C3H7 + H2 + H:1 C3H8:1 + C3H7:1 H2:1 + + 1.32e+006 2.54 6756 + + + + + + OH + C3H8 [=] C3H7 + H2O + OH:1 C3H8:1 + C3H7:1 H2O:1 + + 3.16e+007 1.8 934 + + + + + + C3H7 + H2O2 [=] HO2 + C3H8 + C3H7:1 H2O2:1 + HO2:1 C3H8:1 + + 378 2.72 1500 + + + + + + CH3 + C3H8 [=] C3H7 + CH4 + CH3:1 C3H8:1 + C3H7:1 CH4:1 + + 0.903 3.65 7154 + + + + + + CH3 + C2H4 (+ M) [=] C3H7 (+ M) + CH3:1 C2H4:1 + C3H7:1 + + 2.55e+006 1.6 5700 + 3e+063 -14.6 18170 + 0.1894 277 8748 7891 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + O + C3H7 [=] C2H5 + CH2O + O:1 C3H7:1 + C2H5:1 CH2O:1 + + 9.64e+013 0 0 + + + + + + H + C3H7 (+ M) [=] C3H8 (+ M) + H:1 C3H7:1 + C3H8:1 + + 3.613e+013 0 0 + 4.42e+061 -13.545 11357 + 0.315 369 3285 6667 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + C3H7 [=] CH3 + C2H5 + H:1 C3H7:1 + CH3:1 C2H5:1 + + 4.06e+006 2.19 890 + + + + + + OH + C3H7 [=] C2H5 + CH2OH + OH:1 C3H7:1 + C2H5:1 CH2OH:1 + + 2.41e+013 0 0 + + + + + + HO2 + C3H7 [=] O2 + C3H8 + HO2:1 C3H7:1 + O2:1 C3H8:1 + + 2.55e+010 0.255 -943 + + + + + + HO2 + C3H7 =] OH + C2H5 + CH2O + HO2:1 C3H7:1 + OH:1 C2H5:1 CH2O:1 + + 2.41e+013 0 0 + + + + + + CH3 + C3H7 [=] 2 C2H5 + CH3:1 C3H7:1 + C2H5:2 + + 1.927e+013 -0.32 0 + + + + \ No newline at end of file diff --git a/data/inputs/gri30mod.inp b/data/inputs/gri30mod.inp new file mode 100755 index 000000000..4c364b032 --- /dev/null +++ b/data/inputs/gri30mod.inp @@ -0,0 +1,692 @@ +! GRI-Mech Version 3.0 3/12/99 CHEMKIN-II format +! See README30 file at anonymous FTP site unix.sri.com, directory gri; +! WorldWideWeb home page http://www.me.berkeley.edu/gri_mech/ or +! through http://www.gri.org , under 'Basic Research', +! for additional information, contacts, and disclaimer +ELEMENTS +O H C N AR +END +SPECIES +H2 H O O2 OH H2O HO2 H2O2 +C CH CH2 CH2(S) CH3 CH4 CO CO2 +HCO CH2O CH2OH CH3O CH3OH C2H C2H2 C2H3 +C2H4 C2H5 C2H6 HCCO CH2CO HCCOH N NH +NH2 NH3 NNH NO NO2 N2O HNO CN +HCN H2CN HCNN HCNO HOCN HNCO NCO N2 +AR C3H7 C3H8 CH2CHO CH3CHO +END +THERMO ALL + 300.000 1000.000 5000.000 +O L 1/90O 1 00 00 00G 200.000 3500.000 1000.000 1 + 2.56942078E+00-8.59741137E-05 4.19484589E-08-1.00177799E-11 1.22833691E-15 2 + 2.92175791E+04 4.78433864E+00 3.16826710E+00-3.27931884E-03 6.64306396E-06 3 +-6.12806624E-09 2.11265971E-12 2.91222592E+04 2.05193346E+00 4 +O2 TPIS89O 2 00 00 00G 200.000 3500.000 1000.000 1 + 3.28253784E+00 1.48308754E-03-7.57966669E-07 2.09470555E-10-2.16717794E-14 2 +-1.08845772E+03 5.45323129E+00 3.78245636E+00-2.99673416E-03 9.84730201E-06 3 +-9.68129509E-09 3.24372837E-12-1.06394356E+03 3.65767573E+00 4 +H L 7/88H 1 00 00 00G 200.000 3500.000 1000.000 1 + 2.50000001E+00-2.30842973E-11 1.61561948E-14-4.73515235E-18 4.98197357E-22 2 + 2.54736599E+04-4.46682914E-01 2.50000000E+00 7.05332819E-13-1.99591964E-15 3 + 2.30081632E-18-9.27732332E-22 2.54736599E+04-4.46682853E-01 4 +H2 TPIS78H 2 00 00 00G 200.000 3500.000 1000.000 1 + 3.33727920E+00-4.94024731E-05 4.99456778E-07-1.79566394E-10 2.00255376E-14 2 +-9.50158922E+02-3.20502331E+00 2.34433112E+00 7.98052075E-03-1.94781510E-05 3 + 2.01572094E-08-7.37611761E-12-9.17935173E+02 6.83010238E-01 4 +OH RUS 78O 1H 1 00 00G 200.000 3500.000 1000.000 1 + 3.09288767E+00 5.48429716E-04 1.26505228E-07-8.79461556E-11 1.17412376E-14 2 + 3.85865700E+03 4.47669610E+00 3.99201543E+00-2.40131752E-03 4.61793841E-06 3 +-3.88113333E-09 1.36411470E-12 3.61508056E+03-1.03925458E-01 4 +H2O L 8/89H 2O 1 00 00G 200.000 3500.000 1000.000 1 + 3.03399249E+00 2.17691804E-03-1.64072518E-07-9.70419870E-11 1.68200992E-14 2 +-3.00042971E+04 4.96677010E+00 4.19864056E+00-2.03643410E-03 6.52040211E-06 3 +-5.48797062E-09 1.77197817E-12-3.02937267E+04-8.49032208E-01 4 +HO2 L 5/89H 1O 2 00 00G 200.000 3500.000 1000.000 1 + 4.01721090E+00 2.23982013E-03-6.33658150E-07 1.14246370E-10-1.07908535E-14 2 + 1.11856713E+02 3.78510215E+00 4.30179801E+00-4.74912051E-03 2.11582891E-05 3 +-2.42763894E-08 9.29225124E-12 2.94808040E+02 3.71666245E+00 4 +H2O2 L 7/88H 2O 2 00 00G 200.000 3500.000 1000.000 1 + 4.16500285E+00 4.90831694E-03-1.90139225E-06 3.71185986E-10-2.87908305E-14 2 +-1.78617877E+04 2.91615662E+00 4.27611269E+00-5.42822417E-04 1.67335701E-05 3 +-2.15770813E-08 8.62454363E-12-1.77025821E+04 3.43505074E+00 4 +C L11/88C 1 00 00 00G 200.000 3500.000 1000.000 1 + 2.49266888E+00 4.79889284E-05-7.24335020E-08 3.74291029E-11-4.87277893E-15 2 + 8.54512953E+04 4.80150373E+00 2.55423955E+00-3.21537724E-04 7.33792245E-07 3 +-7.32234889E-10 2.66521446E-13 8.54438832E+04 4.53130848E+00 4 +CH TPIS79C 1H 1 00 00G 200.000 3500.000 1000.000 1 + 2.87846473E+00 9.70913681E-04 1.44445655E-07-1.30687849E-10 1.76079383E-14 2 + 7.10124364E+04 5.48497999E+00 3.48981665E+00 3.23835541E-04-1.68899065E-06 3 + 3.16217327E-09-1.40609067E-12 7.07972934E+04 2.08401108E+00 4 +CH2 L S/93C 1H 2 00 00G 200.000 3500.000 1000.000 1 + 2.87410113E+00 3.65639292E-03-1.40894597E-06 2.60179549E-10-1.87727567E-14 2 + 4.62636040E+04 6.17119324E+00 3.76267867E+00 9.68872143E-04 2.79489841E-06 3 +-3.85091153E-09 1.68741719E-12 4.60040401E+04 1.56253185E+00 4 +CH2(S) L S/93C 1H 2 00 00G 200.000 3500.000 1000.000 1 + 2.29203842E+00 4.65588637E-03-2.01191947E-06 4.17906000E-10-3.39716365E-14 2 + 5.09259997E+04 8.62650169E+00 4.19860411E+00-2.36661419E-03 8.23296220E-06 3 +-6.68815981E-09 1.94314737E-12 5.04968163E+04-7.69118967E-01 4 +CH3 L11/89C 1H 3 00 00G 200.000 3500.000 1000.000 1 + 2.28571772E+00 7.23990037E-03-2.98714348E-06 5.95684644E-10-4.67154394E-14 2 + 1.67755843E+04 8.48007179E+00 3.67359040E+00 2.01095175E-03 5.73021856E-06 3 +-6.87117425E-09 2.54385734E-12 1.64449988E+04 1.60456433E+00 4 +CH4 L 8/88C 1H 4 00 00G 200.000 3500.000 1000.000 1 + 7.48514950E-02 1.33909467E-02-5.73285809E-06 1.22292535E-09-1.01815230E-13 2 +-9.46834459E+03 1.84373180E+01 5.14987613E+00-1.36709788E-02 4.91800599E-05 3 +-4.84743026E-08 1.66693956E-11-1.02466476E+04-4.64130376E+00 4 +CO TPIS79C 1O 1 00 00G 200.000 3500.000 1000.000 1 + 2.71518561E+00 2.06252743E-03-9.98825771E-07 2.30053008E-10-2.03647716E-14 2 +-1.41518724E+04 7.81868772E+00 3.57953347E+00-6.10353680E-04 1.01681433E-06 3 + 9.07005884E-10-9.04424499E-13-1.43440860E+04 3.50840928E+00 4 +CO2 L 7/88C 1O 2 00 00G 200.000 3500.000 1000.000 1 + 3.85746029E+00 4.41437026E-03-2.21481404E-06 5.23490188E-10-4.72084164E-14 2 +-4.87591660E+04 2.27163806E+00 2.35677352E+00 8.98459677E-03-7.12356269E-06 3 + 2.45919022E-09-1.43699548E-13-4.83719697E+04 9.90105222E+00 4 +HCO L12/89H 1C 1O 1 00G 200.000 3500.000 1000.000 1 + 2.77217438E+00 4.95695526E-03-2.48445613E-06 5.89161778E-10-5.33508711E-14 2 + 4.01191815E+03 9.79834492E+00 4.22118584E+00-3.24392532E-03 1.37799446E-05 3 +-1.33144093E-08 4.33768865E-12 3.83956496E+03 3.39437243E+00 4 +CH2O L 8/88H 2C 1O 1 00G 200.000 3500.000 1000.000 1 + 1.76069008E+00 9.20000082E-03-4.42258813E-06 1.00641212E-09-8.83855640E-14 2 +-1.39958323E+04 1.36563230E+01 4.79372315E+00-9.90833369E-03 3.73220008E-05 3 +-3.79285261E-08 1.31772652E-11-1.43089567E+04 6.02812900E-01 4 +CH2OH GUNL93C 1H 3O 1 00G 200.000 3500.000 1000.000 1 + 3.69266569E+00 8.64576797E-03-3.75101120E-06 7.87234636E-10-6.48554201E-14 2 +-3.24250627E+03 5.81043215E+00 3.86388918E+00 5.59672304E-03 5.93271791E-06 3 +-1.04532012E-08 4.36967278E-12-3.19391367E+03 5.47302243E+00 4 +CH3O 121686C 1H 3O 1 G 0300.00 3000.00 1000.000 1 + 0.03770799E+02 0.07871497E-01-0.02656384E-04 0.03944431E-08-0.02112616E-12 2 + 0.12783252E+03 0.02929575E+02 0.02106204E+02 0.07216595E-01 0.05338472E-04 3 +-0.07377636E-07 0.02075610E-10 0.09786011E+04 0.13152177E+02 4 +CH3OH L 8/88C 1H 4O 1 00G 200.000 3500.000 1000.000 1 + 1.78970791E+00 1.40938292E-02-6.36500835E-06 1.38171085E-09-1.17060220E-13 2 +-2.53748747E+04 1.45023623E+01 5.71539582E+00-1.52309129E-02 6.52441155E-05 3 +-7.10806889E-08 2.61352698E-11-2.56427656E+04-1.50409823E+00 4 +C2H L 1/91C 2H 1 00 00G 200.000 3500.000 1000.000 1 + 3.16780652E+00 4.75221902E-03-1.83787077E-06 3.04190252E-10-1.77232770E-14 2 + 6.71210650E+04 6.63589475E+00 2.88965733E+00 1.34099611E-02-2.84769501E-05 3 + 2.94791045E-08-1.09331511E-11 6.68393932E+04 6.22296438E+00 4 +C2H2 L 1/91C 2H 2 00 00G 200.000 3500.000 1000.000 1 + 4.14756964E+00 5.96166664E-03-2.37294852E-06 4.67412171E-10-3.61235213E-14 2 + 2.59359992E+04-1.23028121E+00 8.08681094E-01 2.33615629E-02-3.55171815E-05 3 + 2.80152437E-08-8.50072974E-12 2.64289807E+04 1.39397051E+01 4 +C2H3 L 2/92C 2H 3 00 00G 200.000 3500.000 1000.000 1 + 3.01672400E+00 1.03302292E-02-4.68082349E-06 1.01763288E-09-8.62607041E-14 2 + 3.46128739E+04 7.78732378E+00 3.21246645E+00 1.51479162E-03 2.59209412E-05 3 +-3.57657847E-08 1.47150873E-11 3.48598468E+04 8.51054025E+00 4 +C2H4 L 1/91C 2H 4 00 00G 200.000 3500.000 1000.000 1 + 2.03611116E+00 1.46454151E-02-6.71077915E-06 1.47222923E-09-1.25706061E-13 2 + 4.93988614E+03 1.03053693E+01 3.95920148E+00-7.57052247E-03 5.70990292E-05 3 +-6.91588753E-08 2.69884373E-11 5.08977593E+03 4.09733096E+00 4 +C2H5 L12/92C 2H 5 00 00G 200.000 3500.000 1000.000 1 + 1.95465642E+00 1.73972722E-02-7.98206668E-06 1.75217689E-09-1.49641576E-13 2 + 1.28575200E+04 1.34624343E+01 4.30646568E+00-4.18658892E-03 4.97142807E-05 3 +-5.99126606E-08 2.30509004E-11 1.28416265E+04 4.70720924E+00 4 +C2H6 L 8/88C 2H 6 00 00G 200.000 3500.000 1000.000 1 + 1.07188150E+00 2.16852677E-02-1.00256067E-05 2.21412001E-09-1.90002890E-13 2 +-1.14263932E+04 1.51156107E+01 4.29142492E+00-5.50154270E-03 5.99438288E-05 3 +-7.08466285E-08 2.68685771E-11-1.15222055E+04 2.66682316E+00 4 +CH2CO L 5/90C 2H 2O 1 00G 200.000 3500.000 1000.000 1 + 4.51129732E+00 9.00359745E-03-4.16939635E-06 9.23345882E-10-7.94838201E-14 2 +-7.55105311E+03 6.32247205E-01 2.13583630E+00 1.81188721E-02-1.73947474E-05 3 + 9.34397568E-09-2.01457615E-12-7.04291804E+03 1.22156480E+01 4 +HCCO SRIC91H 1C 2O 1 G 0300.00 4000.00 1000.000 1 + 0.56282058E+01 0.40853401E-02-0.15934547E-05 0.28626052E-09-0.19407832E-13 2 + 0.19327215E+05-0.39302595E+01 0.22517214E+01 0.17655021E-01-0.23729101E-04 3 + 0.17275759E-07-0.50664811E-11 0.20059449E+05 0.12490417E+02 4 +HCCOH SRI91C 2O 1H 20 0G 300.000 5000.000 1000.000 1 + 0.59238291E+01 0.67923600E-02-0.25658564E-05 0.44987841E-09-0.29940101E-13 2 + 0.72646260E+04-0.76017742E+01 0.12423733E+01 0.31072201E-01-0.50866864E-04 3 + 0.43137131E-07-0.14014594E-10 0.80316143E+04 0.13874319E+02 4 +H2CN 41687H 2C 1N 1 G 0300.00 4000.000 1000.000 1 + 0.52097030E+01 0.29692911E-02-0.28555891E-06-0.16355500E-09 0.30432589E-13 2 + 0.27677109E+05-0.44444780E+01 0.28516610E+01 0.56952331E-02 0.10711400E-05 3 +-0.16226120E-08-0.23511081E-12 0.28637820E+05 0.89927511E+01 4 +HCN GRI/98H 1C 1N 1 0G 200.000 6000.000 1000.000 1 + 0.38022392E+01 0.31464228E-02-0.10632185E-05 0.16619757E-09-0.97997570E-14 2 + 0.14407292E+05 0.15754601E+01 0.22589886E+01 0.10051170E-01-0.13351763E-04 3 + 0.10092349E-07-0.30089028E-11 0.14712633E+05 0.89164419E+01 4 +HNO And93 H 1N 1O 1 0G 200.000 6000.000 1000.000 1 + 0.29792509E+01 0.34944059E-02-0.78549778E-06 0.57479594E-10-0.19335916E-15 2 + 0.11750582E+05 0.86063728E+01 0.45334916E+01-0.56696171E-02 0.18473207E-04 3 +-0.17137094E-07 0.55454573E-11 0.11548297E+05 0.17498417E+01 4 +N L 6/88N 1 0 0 0G 200.000 6000.000 1000.000 1 + 0.24159429E+01 0.17489065E-03-0.11902369E-06 0.30226245E-10-0.20360982E-14 2 + 0.56133773E+05 0.46496096E+01 0.25000000E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.56104637E+05 0.41939087E+01 4 +NNH T07/93N 2H 1 00 00G 200.000 6000.000 1000.000 1 + 0.37667544E+01 0.28915082E-02-0.10416620E-05 0.16842594E-09-0.10091896E-13 2 + 0.28650697E+05 0.44705067E+01 0.43446927E+01-0.48497072E-02 0.20059459E-04 3 +-0.21726464E-07 0.79469539E-11 0.28791973E+05 0.29779410E+01 4 +N2O L 7/88N 2O 1 0 0G 200.000 6000.000 1000.000 1 + 0.48230729E+01 0.26270251E-02-0.95850874E-06 0.16000712E-09-0.97752303E-14 2 + 0.80734048E+04-0.22017207E+01 0.22571502E+01 0.11304728E-01-0.13671319E-04 3 + 0.96819806E-08-0.29307182E-11 0.87417744E+04 0.10757992E+02 4 +NH And94 N 1H 1 0 0G 200.000 6000.000 1000.000 1 + 0.27836928E+01 0.13298430E-02-0.42478047E-06 0.78348501E-10-0.55044470E-14 2 + 0.42120848E+05 0.57407799E+01 0.34929085E+01 0.31179198E-03-0.14890484E-05 3 + 0.24816442E-08-0.10356967E-11 0.41880629E+05 0.18483278E+01 4 +NH2 And89 N 1H 2 0 0G 200.000 6000.000 1000.000 1 + 0.28347421E+01 0.32073082E-02-0.93390804E-06 0.13702953E-09-0.79206144E-14 2 + 0.22171957E+05 0.65204163E+01 0.42040029E+01-0.21061385E-02 0.71068348E-05 3 +-0.56115197E-08 0.16440717E-11 0.21885910E+05-0.14184248E+00 4 +NH3 J 6/77N 1H 3 0 0G 200.000 6000.000 1000.000 1 + 0.26344521E+01 0.56662560E-02-0.17278676E-05 0.23867161E-09-0.12578786E-13 2 +-0.65446958E+04 0.65662928E+01 0.42860274E+01-0.46605230E-02 0.21718513E-04 3 +-0.22808887E-07 0.82638046E-11-0.67417285E+04-0.62537277E+00 4 +NO RUS 78N 1O 1 0 0G 200.000 6000.000 1000.000 1 + 0.32606056E+01 0.11911043E-02-0.42917048E-06 0.69457669E-10-0.40336099E-14 2 + 0.99209746E+04 0.63693027E+01 0.42184763E+01-0.46389760E-02 0.11041022E-04 3 +-0.93361354E-08 0.28035770E-11 0.98446230E+04 0.22808464E+01 4 +NO2 L 7/88N 1O 2 0 0G 200.000 6000.000 1000.000 1 + 0.48847542E+01 0.21723956E-02-0.82806906E-06 0.15747510E-09-0.10510895E-13 2 + 0.23164983E+04-0.11741695E+00 0.39440312E+01-0.15854290E-02 0.16657812E-04 3 +-0.20475426E-07 0.78350564E-11 0.28966179E+04 0.63119917E+01 4 +HCNO BDEA94H 1N 1C 1O 1G 300.000 5000.000 1382.000 1 + 6.59860456E+00 3.02778626E-03-1.07704346E-06 1.71666528E-10-1.01439391E-14 2 + 1.79661339E+04-1.03306599E+01 2.64727989E+00 1.27505342E-02-1.04794236E-05 3 + 4.41432836E-09-7.57521466E-13 1.92990252E+04 1.07332972E+01 4 +HOCN BDEA94H 1N 1C 1O 1G 300.000 5000.000 1368.000 1 + 5.89784885E+00 3.16789393E-03-1.11801064E-06 1.77243144E-10-1.04339177E-14 2 +-3.70653331E+03-6.18167825E+00 3.78604952E+00 6.88667922E-03-3.21487864E-06 3 + 5.17195767E-10 1.19360788E-14-2.82698400E+03 5.63292162E+00 4 +HNCO BDEA94H 1N 1C 1O 1G 300.000 5000.000 1478.000 1 + 6.22395134E+00 3.17864004E-03-1.09378755E-06 1.70735163E-10-9.95021955E-15 2 +-1.66599344E+04-8.38224741E+00 3.63096317E+00 7.30282357E-03-2.28050003E-06 3 +-6.61271298E-10 3.62235752E-13-1.55873636E+04 6.19457727E+00 4 +NCO EA 93 N 1C 1O 1 0G 200.000 6000.000 1000.000 1 + 0.51521845E+01 0.23051761E-02-0.88033153E-06 0.14789098E-09-0.90977996E-14 2 + 0.14004123E+05-0.25442660E+01 0.28269308E+01 0.88051688E-02-0.83866134E-05 3 + 0.48016964E-08-0.13313595E-11 0.14682477E+05 0.95504646E+01 4 +CN HBH92 C 1N 1 0 0G 200.000 6000.000 1000.000 1 + 0.37459805E+01 0.43450775E-04 0.29705984E-06-0.68651806E-10 0.44134173E-14 2 + 0.51536188E+05 0.27867601E+01 0.36129351E+01-0.95551327E-03 0.21442977E-05 3 +-0.31516323E-09-0.46430356E-12 0.51708340E+05 0.39804995E+01 4 +HCNN SRI/94C 1N 2H 10 0G 300.000 5000.000 1000.000 1 + 0.58946362E+01 0.39895959E-02-0.15982380E-05 0.29249395E-09-0.20094686E-13 2 + 0.53452941E+05-0.51030502E+01 0.25243194E+01 0.15960619E-01-0.18816354E-04 3 + 0.12125540E-07-0.32357378E-11 0.54261984E+05 0.11675870E+02 4 +N2 121286N 2 G 300.000 5000.000 1000.000 1 + 0.02926640E+02 0.14879768E-02-0.05684760E-05 0.10097038E-09-0.06753351E-13 2 +-0.09227977E+04 0.05980528E+02 0.03298677E+02 0.14082404E-02-0.03963222E-04 3 + 0.05641515E-07-0.02444854E-10-0.10208999E+04 0.03950372E+02 4 +AR 120186AR 1 G 300.000 5000.000 1000.000 1 + 0.02500000E+02 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-0.07453750E+04 0.04366000E+02 0.02500000E+02 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-0.07453750E+04 0.04366000E+02 4 +C3H8 L 4/85C 3H 8 0 0G 300.000 5000.000 1000.00 1 + 0.75341368E+01 0.18872239E-01-0.62718491E-05 0.91475649E-09-0.47838069E-13 2 +-0.16467516E+05-0.17892349E+02 0.93355381E+00 0.26424579E-01 0.61059727E-05 3 +-0.21977499E-07 0.95149253E-11-0.13958520E+05 0.19201691E+02 4 +C3H7 L 9/84C 3H 7 0 0G 300.000 5000.000 1000.00 1 + 0.77026987E+01 0.16044203E-01-0.52833220E-05 0.76298590E-09-0.39392284E-13 2 + 0.82984336E+04-0.15480180E+02 0.10515518E+01 0.25991980E-01 0.23800540E-05 3 +-0.19609569E-07 0.93732470E-11 0.10631863E+05 0.21122559E+02 4 +CH3CHO L 8/88C 2H 4O 1 0G 200.000 6000.000 1000.00 1 + 0.54041108E+01 0.11723059E-01-0.42263137E-05 0.68372451E-09-0.40984863E-13 2 +-0.22593122E+05-0.34807917E+01 0.47294595E+01-0.31932858E-02 0.47534921E-04 3 +-0.57458611E-07 0.21931112E-10-0.21572878E+05 0.41030159E+01 4 +CH2CHO SAND86O 1H 3C 2 G 300.00 5000.00 1000.00 1 + 0.05975670E+02 0.08130591E-01-0.02743624E-04 0.04070304E-08-0.02176017E-12 2 + 0.04903218E+04-0.05045251E+02 0.03409062E+02 0.10738574E-01 0.01891492E-04 3 +-0.07158583E-07 0.02867385E-10 0.15214766E+04 0.09558290E+02 4 +END +REACTIONS +2O+M<=>O2+M 1.200E+17 -1.000 .00 +H2/ 2.40/ H2O/15.40/ CH4/ 2.00/ CO/ 1.75/ CO2/ 3.60/ C2H6/ 3.00/ AR/ .83/ +O+H+M<=>OH+M 5.000E+17 -1.000 .00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +O+H2<=>H+OH 3.870E+04 2.700 6260.00 +O+HO2<=>OH+O2 2.000E+13 .000 .00 +!% (O) + (H)(O2) = (O)(H) + (O2) +O+H2O2<=>OH+HO2 9.630E+06 2.000 4000.00 +O+CH<=>H+CO 5.700E+13 .000 .00 +O+CH2<=>H+HCO 8.000E+13 .000 .00 +O+CH2(S)<=>H2+CO 1.500E+13 .000 .00 +O+CH2(S)<=>H+HCO 1.500E+13 .000 .00 +O+CH3<=>H+CH2O 5.060E+13 .000 .00 +O+CH4<=>OH+CH3 1.020E+09 1.500 8600.00 +O+CO(+M)<=>CO2(+M) 1.800E+10 .000 2385.00 + LOW/ 6.020E+14 .000 3000.00/ +H2/2.00/ O2/6.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/3.50/ C2H6/3.00/ AR/ .50/ +O+HCO<=>OH+CO 3.000E+13 .000 .00 +O+HCO<=>H+CO2 3.000E+13 .000 .00 +O+CH2O<=>OH+HCO 3.900E+13 .000 3540.00 +O+CH2OH<=>OH+CH2O 1.000E+13 .000 .00 +O+CH3O<=>OH+CH2O 1.000E+13 .000 .00 +O+CH3OH<=>OH+CH2OH 3.880E+05 2.500 3100.00 +O+CH3OH<=>OH+CH3O 1.300E+05 2.500 5000.00 +O+C2H<=>CH+CO 5.000E+13 .000 .00 +O+C2H2<=>H+HCCO 1.350E+07 2.000 1900.00 +O+C2H2<=>OH+C2H 4.600E+19 -1.410 28950.00 +O+C2H2<=>CO+CH2 6.940E+06 2.000 1900.00 +O+C2H3<=>H+CH2CO 3.000E+13 .000 .00 +O+C2H4<=>CH3+HCO 1.250E+07 1.830 220.00 +O+C2H5<=>CH3+CH2O 2.240E+13 .000 .00 +O+C2H6<=>OH+C2H5 8.980E+07 1.920 5690.00 +O+HCCO<=>H+2CO 1.000E+14 .000 .00 +!% (O) + (H)(C)(C-O) = (H) + (C)(O) + (C-O) +O+CH2CO<=>OH+HCCO 1.000E+13 .000 8000.00 +O+CH2CO<=>CH2+CO2 1.750E+12 .000 1350.00 +O2+CO<=>O+CO2 2.500E+12 .000 47800.00 +O2+CH2O<=>HO2+HCO 1.000E+14 .000 40000.00 +H+O2+M<=>HO2+M 2.800E+18 -.860 .00 +O2/ .00/ H2O/ .00/ CO/ .75/ CO2/1.50/ C2H6/1.50/ N2/ .00/ AR/ .00/ +H+2O2<=>HO2+O2 2.080E+19 -1.240 .00 +H+O2+H2O<=>HO2+H2O 11.26E+18 -.760 .00 +H+O2+N2<=>HO2+N2 2.600E+19 -1.240 .00 +H+O2+AR<=>HO2+AR 7.000E+17 -.800 .00 +H+O2<=>O+OH 2.650E+16 -.6707 17041.00 +2H+M<=>H2+M 1.000E+18 -1.000 .00 +H2/ .00/ H2O/ .00/ CH4/2.00/ CO2/ .00/ C2H6/3.00/ AR/ .63/ +2H+H2<=>2H2 9.000E+16 -.600 .00 +2H+H2O<=>H2+H2O 6.000E+19 -1.250 .00 +2H+CO2<=>H2+CO2 5.500E+20 -2.000 .00 +H+OH+M<=>H2O+M 2.200E+22 -2.000 .00 +H2/ .73/ H2O/3.65/ CH4/2.00/ C2H6/3.00/ AR/ .38/ +H+HO2<=>O+H2O 3.970E+12 .000 671.00 +H+HO2<=>O2+H2 4.480E+13 .000 1068.00 +H+HO2<=>2OH 0.840E+14 .000 635.00 +H+H2O2<=>HO2+H2 1.210E+07 2.000 5200.00 +H+H2O2<=>OH+H2O 1.000E+13 .000 3600.00 +!% (H) + (O-H)(O-H) = (H)(O-H) + (O-H) +H+CH<=>C+H2 1.650E+14 .000 .00 +H+CH2(+M)<=>CH3(+M) 6.000E+14 .000 .00 + LOW / 1.040E+26 -2.760 1600.00/ + TROE/ .5620 91.00 5836.00 8552.00/ +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+CH2(S)<=>CH+H2 3.000E+13 .000 .00 +H+CH3(+M)<=>CH4(+M) 13.90E+15 -.534 536.00 + LOW / 2.620E+33 -4.760 2440.00/ + TROE/ .7830 74.00 2941.00 6964.00 / +H2/2.00/ H2O/6.00/ CH4/3.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+CH4<=>CH3+H2 6.600E+08 1.620 10840.00 +H+HCO(+M)<=>CH2O(+M) 1.090E+12 .480 -260.00 + LOW / 2.470E+24 -2.570 425.00/ + TROE/ .7824 271.00 2755.00 6570.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+HCO<=>H2+CO 7.340E+13 .000 .00 +H+CH2O(+M)<=>CH2OH(+M) 5.400E+11 .454 3600.00 + LOW / 1.270E+32 -4.820 6530.00/ + TROE/ .7187 103.00 1291.00 4160.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +H+CH2O(+M)<=>CH3O(+M) 5.400E+11 .454 2600.00 + LOW / 2.200E+30 -4.800 5560.00/ + TROE/ .7580 94.00 1555.00 4200.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +H+CH2O<=>HCO+H2 5.740E+07 1.900 2742.00 +H+CH2OH(+M)<=>CH3OH(+M) 1.055E+12 .500 86.00 + LOW / 4.360E+31 -4.650 5080.00/ + TROE/ .600 100.00 90000.0 10000.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +H+CH2OH<=>H2+CH2O 2.000E+13 .000 .00 +H+CH2OH<=>OH+CH3 1.650E+11 .650 -284.00 +!% (H) + (H2-C)(O-H) = (H)(H2-C) + (O-H) +H+CH2OH<=>CH2(S)+H2O 3.280E+13 -.090 610.00 +H+CH3O(+M)<=>CH3OH(+M) 2.430E+12 .515 50.00 + LOW / 4.660E+41 -7.440 14080.0/ + TROE/ .700 100.00 90000.0 10000.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +H+CH3O<=>H+CH2OH 4.150E+07 1.630 1924.00 +H+CH3O<=>H2+CH2O 2.000E+13 .000 .00 +H+CH3O<=>OH+CH3 1.500E+12 .500 -110.00 +H+CH3O<=>CH2(S)+H2O 2.620E+14 -.230 1070.00 +H+CH3OH<=>CH2OH+H2 1.700E+07 2.100 4870.00 +H+CH3OH<=>CH3O+H2 4.200E+06 2.100 4870.00 +H+C2H(+M)<=>C2H2(+M) 1.000E+17 -1.000 .00 + LOW / 3.750E+33 -4.800 1900.00/ + TROE/ .6464 132.00 1315.00 5566.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C2H2(+M)<=>C2H3(+M) 5.600E+12 .000 2400.00 + LOW / 3.800E+40 -7.270 7220.00/ + TROE/ .7507 98.50 1302.00 4167.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C2H3(+M)<=>C2H4(+M) 6.080E+12 .270 280.00 + LOW / 1.400E+30 -3.860 3320.00/ + TROE/ .7820 207.50 2663.00 6095.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C2H3<=>H2+C2H2 3.000E+13 .000 .00 +H+C2H4(+M)<=>C2H5(+M) 0.540E+12 .454 1820.00 + LOW / 0.600E+42 -7.620 6970.00/ + TROE/ .9753 210.00 984.00 4374.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C2H4<=>C2H3+H2 1.325E+06 2.530 12240.00 +H+C2H5(+M)<=>C2H6(+M) 5.210E+17 -.990 1580.00 + LOW / 1.990E+41 -7.080 6685.00/ + TROE/ .8422 125.00 2219.00 6882.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C2H5<=>H2+C2H4 2.000E+12 .000 .00 +H+C2H6<=>C2H5+H2 1.150E+08 1.900 7530.00 +H+HCCO<=>CH2(S)+CO 1.000E+14 .000 .00 +H+CH2CO<=>HCCO+H2 5.000E+13 .000 8000.00 +H+CH2CO<=>CH3+CO 1.130E+13 .000 3428.00 +H+HCCOH<=>H+CH2CO 1.000E+13 .000 .00 +H2+CO(+M)<=>CH2O(+M) 4.300E+07 1.500 79600.00 + LOW / 5.070E+27 -3.420 84350.00/ + TROE/ .9320 197.00 1540.00 10300.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +OH+H2<=>H+H2O 2.160E+08 1.510 3430.00 +2OH(+M)<=>H2O2(+M) 7.400E+13 -.370 .00 + LOW / 2.300E+18 -.900 -1700.00/ + TROE/ .7346 94.00 1756.00 5182.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +2OH<=>O+H2O 3.570E+04 2.400 -2110.00 +OH+HO2<=>O2+H2O 1.450E+13 .000 -500.00 + DUPLICATE +OH+H2O2<=>HO2+H2O 2.000E+12 .000 427.00 + DUPLICATE +OH+H2O2<=>HO2+H2O 1.700E+18 .000 29410.00 + DUPLICATE +OH+C<=>H+CO 5.000E+13 .000 .00 +OH+CH<=>H+HCO 3.000E+13 .000 .00 +OH+CH2<=>H+CH2O 2.000E+13 .000 .00 +OH+CH2<=>CH+H2O 1.130E+07 2.000 3000.00 +OH+CH2(S)<=>H+CH2O 3.000E+13 .000 .00 +OH+CH3(+M)<=>CH3OH(+M) 2.790E+18 -1.430 1330.00 + LOW / 4.000E+36 -5.920 3140.00/ + TROE/ .4120 195.0 5900.00 6394.00/ +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +OH+CH3<=>CH2+H2O 5.600E+07 1.600 5420.00 +OH+CH3<=>CH2(S)+H2O 6.440E+17 -1.340 1417.00 +OH+CH4<=>CH3+H2O 1.000E+08 1.600 3120.00 +OH+CO<=>H+CO2 4.760E+07 1.228 70.00 +OH+HCO<=>H2O+CO 5.000E+13 .000 .00 +OH+CH2O<=>HCO+H2O 3.430E+09 1.180 -447.00 +OH+CH2OH<=>H2O+CH2O 5.000E+12 .000 .00 +OH+CH3O<=>H2O+CH2O 5.000E+12 .000 .00 +OH+CH3OH<=>CH2OH+H2O 1.440E+06 2.000 -840.00 +OH+CH3OH<=>CH3O+H2O 6.300E+06 2.000 1500.00 +OH+C2H<=>H+HCCO 2.000E+13 .000 .00 +OH+C2H2<=>H+CH2CO 2.180E-04 4.500 -1000.00 +OH+C2H2<=>H+HCCOH 5.040E+05 2.300 13500.00 +OH+C2H2<=>C2H+H2O 3.370E+07 2.000 14000.00 +OH+C2H2<=>CH3+CO 4.830E-04 4.000 -2000.00 +OH+C2H3<=>H2O+C2H2 5.000E+12 .000 .00 +OH+C2H4<=>C2H3+H2O 3.600E+06 2.000 2500.00 +OH+C2H6<=>C2H5+H2O 3.540E+06 2.120 870.00 +OH+CH2CO<=>HCCO+H2O 7.500E+12 .000 2000.00 +2HO2<=>O2+H2O2 1.300E+11 .000 -1630.00 + DUPLICATE +2HO2<=>O2+H2O2 4.200E+14 .000 12000.00 + DUPLICATE +HO2+CH2<=>OH+CH2O 2.000E+13 .000 .00 +HO2+CH3<=>O2+CH4 1.000E+12 .000 .00 +HO2+CH3<=>OH+CH3O 3.780E+13 .000 .00 +HO2+CO<=>OH+CO2 1.500E+14 .000 23600.00 +HO2+CH2O<=>HCO+H2O2 5.600E+06 2.000 12000.00 +C+O2<=>O+CO 5.800E+13 .000 576.00 +C+CH2<=>H+C2H 5.000E+13 .000 .00 +C+CH3<=>H+C2H2 5.000E+13 .000 .00 +CH+O2<=>O+HCO 6.710E+13 .000 .00 +CH+H2<=>H+CH2 1.080E+14 .000 3110.00 +CH+H2O<=>H+CH2O 5.710E+12 .000 -755.00 +CH+CH2<=>H+C2H2 4.000E+13 .000 .00 +!% (H-C) + (H-C)(H) = (H-C)(H-C) + (H) ! uncertain +CH+CH3<=>H+C2H3 3.000E+13 .000 .00 +!% (H-C) + (H2-C)(H) = (H-C)(H2-C) + (H) ! uncertain +CH+CH4<=>H+C2H4 6.000E+13 .000 .00 +!% (H-C) + (H3-C)(H) = (H-C)(H3-C) + (H) ! uncertain +CH+CO(+M)<=>HCCO(+M) 5.000E+13 .000 .00 + LOW / 2.690E+28 -3.740 1936.00/ + TROE/ .5757 237.00 1652.00 5069.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +CH+CO2<=>HCO+CO 1.900E+14 .000 15792.00 +CH+CH2O<=>H+CH2CO 9.460E+13 .000 -515.00 +!% (O-H2-C) + (C)(H) = (O-H2-C)(C) + (H) ! uncertain +CH+HCCO<=>CO+C2H2 5.000E+13 .000 .00 +CH2+O2=>OH+H+CO 5.000E+12 .000 1500.00 +CH2+H2<=>H+CH3 5.000E+05 2.000 7230.00 +2CH2<=>H2+C2H2 1.600E+15 .000 11944.00 +CH2+CH3<=>H+C2H4 4.000E+13 .000 .00 +!% (H2-C) + (H2-C)(H) = (H2-C)(H2-C) + (H) +CH2+CH4<=>2CH3 2.460E+06 2.000 8270.00 +CH2+CO(+M)<=>CH2CO(+M) 8.100E+11 .500 4510.00 + LOW / 2.690E+33 -5.110 7095.00/ + TROE/ .5907 275.00 1226.00 5185.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +CH2+HCCO<=>C2H3+CO 3.000E+13 .000 .00 +CH2(S)+N2<=>CH2+N2 1.500E+13 .000 600.00 +CH2(S)+AR<=>CH2+AR 9.000E+12 .000 600.00 +CH2(S)+O2<=>H+OH+CO 2.800E+13 .000 .00 +CH2(S)+O2<=>CO+H2O 1.200E+13 .000 .00 +CH2(S)+H2<=>CH3+H 7.000E+13 .000 .00 +CH2(S)+H2O(+M)<=>CH3OH(+M) 4.820E+17 -1.160 1145.00 + LOW / 1.880E+38 -6.360 5040.00/ + TROE/ .6027 208.00 3922.00 10180.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +CH2(S)+H2O<=>CH2+H2O 3.000E+13 .000 .00 +CH2(S)+CH3<=>H+C2H4 1.200E+13 .000 -570.00 +CH2(S)+CH4<=>2CH3 1.600E+13 .000 -570.00 +!% (H2-C) + (H2-C)(H) = (H2-C)(H2-C) + (H) +CH2(S)+CO<=>CH2+CO 9.000E+12 .000 .00 +CH2(S)+CO2<=>CH2+CO2 7.000E+12 .000 .00 +CH2(S)+CO2<=>CO+CH2O 1.400E+13 .000 .00 +CH2(S)+C2H6<=>CH3+C2H5 4.000E+13 .000 -550.00 +CH3+O2<=>O+CH3O 3.560E+13 .000 30480.00 +CH3+O2<=>OH+CH2O 2.310E+12 .000 20315.00 +CH3+H2O2<=>HO2+CH4 2.450E+04 2.470 5180.00 +2CH3(+M)<=>C2H6(+M) 6.770E+16 -1.180 654.00 + LOW / 3.400E+41 -7.030 2762.00/ + TROE/ .6190 73.20 1180.00 9999.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +2CH3<=>H+C2H5 6.840E+12 .100 10600.00 +CH3+HCO<=>CH4+CO 2.648E+13 .000 .00 +CH3+CH2O<=>HCO+CH4 3.320E+03 2.810 5860.00 +CH3+CH3OH<=>CH2OH+CH4 3.000E+07 1.500 9940.00 +CH3+CH3OH<=>CH3O+CH4 1.000E+07 1.500 9940.00 +CH3+C2H4<=>C2H3+CH4 2.270E+05 2.000 9200.00 +CH3+C2H6<=>C2H5+CH4 6.140E+06 1.740 10450.00 +HCO+H2O<=>H+CO+H2O 1.500E+18 -1.000 17000.00 +HCO+M<=>H+CO+M 1.870E+17 -1.000 17000.00 +H2/2.00/ H2O/ .00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +HCO+O2<=>HO2+CO 13.45E+12 .000 400.00 +CH2OH+O2<=>HO2+CH2O 1.800E+13 .000 900.00 +CH3O+O2<=>HO2+CH2O 4.280E-13 7.600 -3530.00 +C2H+O2<=>HCO+CO 1.000E+13 .000 -755.00 +C2H+H2<=>H+C2H2 5.680E+10 0.900 1993.00 +C2H3+O2<=>HCO+CH2O 4.580E+16 -1.390 1015.00 +C2H4(+M)<=>H2+C2H2(+M) 8.000E+12 .440 86770.00 + LOW / 1.580E+51 -9.300 97800.00/ + TROE/ .7345 180.00 1035.00 5417.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +C2H5+O2<=>HO2+C2H4 8.400E+11 .000 3875.00 +HCCO+O2<=>OH+2CO 3.200E+12 .000 854.00 +!% (H)(C)(C-O) + (O)(O) = (O)(H) + (C)(O) + (C-O) +2HCCO<=>2CO+C2H2 1.000E+13 .000 .00 +!% (H-C)(C-O) + (H-C)(C-O) = (C-O) + (C-O) + (H-C)(H-C) +N+NO<=>N2+O 2.700E+13 .000 355.00 +N+O2<=>NO+O 9.000E+09 1.000 6500.00 +N+OH<=>NO+H 3.360E+13 .000 385.00 +N2O+O<=>N2+O2 1.400E+12 .000 10810.00 +N2O+O<=>2NO 2.900E+13 .000 23150.00 +N2O+H<=>N2+OH 3.870E+14 .000 18880.00 +N2O+OH<=>N2+HO2 2.000E+12 .000 21060.00 +N2O(+M)<=>N2+O(+M) 7.910E+10 .000 56020.00 + LOW / 6.370E+14 .000 56640.00/ +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .625/ +HO2+NO<=>NO2+OH 2.110E+12 .000 -480.00 +NO+O+M<=>NO2+M 1.060E+20 -1.410 .00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +NO2+O<=>NO+O2 3.900E+12 .000 -240.00 +NO2+H<=>NO+OH 1.320E+14 .000 360.00 +NH+O<=>NO+H 4.000E+13 .000 .00 +NH+H<=>N+H2 3.200E+13 .000 330.00 +NH+OH<=>HNO+H 2.000E+13 .000 .00 +NH+OH<=>N+H2O 2.000E+09 1.200 .00 +NH+O2<=>HNO+O 4.610E+05 2.000 6500.00 +NH+O2<=>NO+OH 1.280E+06 1.500 100.00 +NH+N<=>N2+H 1.500E+13 .000 .00 +NH+H2O<=>HNO+H2 2.000E+13 .000 13850.00 +NH+NO<=>N2+OH 2.160E+13 -.230 .00 +NH+NO<=>N2O+H 3.650E+14 -.450 .00 +NH2+O<=>OH+NH 3.000E+12 .000 .00 +NH2+O<=>H+HNO 3.900E+13 .000 .00 +NH2+H<=>NH+H2 4.000E+13 .000 3650.00 +NH2+OH<=>NH+H2O 9.000E+07 1.500 -460.00 +NNH<=>N2+H 3.300E+08 .000 .00 +NNH+M<=>N2+H+M 1.300E+14 -.110 4980.00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +NNH+O2<=>HO2+N2 5.000E+12 .000 .00 +NNH+O<=>OH+N2 2.500E+13 .000 .00 +NNH+O<=>NH+NO 7.000E+13 .000 .00 +NNH+H<=>H2+N2 5.000E+13 .000 .00 +NNH+OH<=>H2O+N2 2.000E+13 .000 .00 +NNH+CH3<=>CH4+N2 2.500E+13 .000 .00 +H+NO+M<=>HNO+M 4.480E+19 -1.320 740.00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +HNO+O<=>NO+OH 2.500E+13 .000 .00 +HNO+H<=>H2+NO 9.000E+11 .720 660.00 +HNO+OH<=>NO+H2O 1.300E+07 1.900 -950.00 +HNO+O2<=>HO2+NO 1.000E+13 .000 13000.00 +CN+O<=>CO+N 7.700E+13 .000 .00 +CN+OH<=>NCO+H 4.000E+13 .000 .00 +CN+H2O<=>HCN+OH 8.000E+12 .000 7460.00 +CN+O2<=>NCO+O 6.140E+12 .000 -440.00 +CN+H2<=>HCN+H 2.950E+05 2.450 2240.00 +NCO+O<=>NO+CO 2.350E+13 .000 .00 +!% (O) + (N)(O-C) = (O)(N) + (O-C) +NCO+H<=>NH+CO 5.400E+13 .000 .00 +NCO+OH<=>NO+H+CO 0.250E+13 .000 .00 +!% (N)(C-O) + (O)(H) = (N)(O) + (C-O) + (H) +NCO+N<=>N2+CO 2.000E+13 .000 .00 +NCO+O2<=>NO+CO2 2.000E+12 .000 20000.00 +NCO+M<=>N+CO+M 3.100E+14 .000 54050.00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +NCO+NO<=>N2O+CO 1.900E+17 -1.520 740.00 +NCO+NO<=>N2+CO2 3.800E+18 -2.000 800.00 +HCN+M<=>H+CN+M 1.040E+29 -3.300 126600.00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +HCN+O<=>NCO+H 2.030E+04 2.640 4980.00 +HCN+O<=>NH+CO 5.070E+03 2.640 4980.00 +HCN+O<=>CN+OH 3.910E+09 1.580 26600.00 +HCN+OH<=>HOCN+H 1.100E+06 2.030 13370.00 +!% (O-H) + (C-N)(H) = (O-H)(C-N) + (H) +HCN+OH<=>HNCO+H 4.400E+03 2.260 6400.00 +!% (H-C-N) + (O)(H) = (H-C-N)(O) + (H) +HCN+OH<=>NH2+CO 1.600E+02 2.560 9000.00 +H+HCN(+M)<=>H2CN(+M) 3.300E+13 .000 .00 + LOW / 1.400E+26 -3.400 1900.00/ +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H2CN+N<=>N2+CH2 6.000E+13 .000 400.00 +C+N2<=>CN+N 6.300E+13 .000 46020.00 +CH+N2<=>HCN+N 3.120E+09 0.880 20130.00 +CH+N2(+M)<=>HCNN(+M) 3.100E+12 .150 .00 + LOW / 1.300E+25 -3.160 740.00/ + TROE/ .6670 235.00 2117.00 4536.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ 1.0/ +CH2+N2<=>HCN+NH 1.000E+13 .000 74000.00 +CH2(S)+N2<=>NH+HCN 1.000E+11 .000 65000.00 +C+NO<=>CN+O 1.900E+13 .000 .00 +C+NO<=>CO+N 2.900E+13 .000 .00 +CH+NO<=>HCN+O 4.100E+13 .000 .00 +CH+NO<=>H+NCO 1.620E+13 .000 .00 +CH+NO<=>N+HCO 2.460E+13 .000 .00 +CH2+NO<=>H+HNCO 3.100E+17 -1.380 1270.00 +CH2+NO<=>OH+HCN 2.900E+14 -.690 760.00 +CH2+NO<=>H+HCNO 3.800E+13 -.360 580.00 +CH2(S)+NO<=>H+HNCO 3.100E+17 -1.380 1270.00 +CH2(S)+NO<=>OH+HCN 2.900E+14 -.690 760.00 +CH2(S)+NO<=>H+HCNO 3.800E+13 -.360 580.00 +CH3+NO<=>HCN+H2O 9.600E+13 .000 28800.00 +CH3+NO<=>H2CN+OH 1.000E+12 .000 21750.00 +HCNN+O<=>CO+H+N2 2.200E+13 .000 .00 +HCNN+O<=>HCN+NO 2.000E+12 .000 .00 +HCNN+O2<=>O+HCO+N2 1.200E+13 .000 .00 +HCNN+OH<=>H+HCO+N2 1.200E+13 .000 .00 +!% (H)(C)(N2) + (O-H) = (H) + (C)(O-H) + (N2) +HCNN+H<=>CH2+N2 1.000E+14 .000 .00 +HNCO+O<=>NH+CO2 9.800E+07 1.410 8500.00 +HNCO+O<=>HNO+CO 1.500E+08 1.570 44000.00 +!% (O) + (H-N)(O-C) = (O)(H-N) + (O-C) +HNCO+O<=>NCO+OH 2.200E+06 2.110 11400.00 +HNCO+H<=>NH2+CO 2.250E+07 1.700 3800.00 +HNCO+H<=>H2+NCO 1.050E+05 2.500 13300.00 +HNCO+OH<=>NCO+H2O 3.300E+07 1.500 3600.00 +HNCO+OH<=>NH2+CO2 3.300E+06 1.500 3600.00 +HNCO+M<=>NH+CO+M 1.180E+16 .000 84720.00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +HCNO+H<=>H+HNCO 2.100E+15 -.690 2850.00 +HCNO+H<=>OH+HCN 2.700E+11 .180 2120.00 +!% (H) + (C-N)(O-H) = (H)(C-N) + (O-H) +HCNO+H<=>NH2+CO 1.700E+14 -.750 2890.00 +HOCN+H<=>H+HNCO 2.000E+07 2.000 2000.00 +HCCO+NO<=>HCNO+CO 0.900E+13 .000 .00 +CH3+N<=>H2CN+H 6.100E+14 -.310 290.00 +CH3+N<=>HCN+H2 3.700E+12 .150 -90.00 +NH3+H<=>NH2+H2 5.400E+05 2.400 9915.00 +NH3+OH<=>NH2+H2O 5.000E+07 1.600 955.00 +NH3+O<=>NH2+OH 9.400E+06 1.940 6460.00 +NH+CO2<=>HNO+CO 1.000E+13 .000 14350.00 +CN+NO2<=>NCO+NO 6.160E+15 -0.752 345.00 +NCO+NO2<=>N2O+CO2 3.250E+12 .000 -705.00 +!% (N)(C-O) + (N-O)(O) = (N)(N-O) + (C-O)(O) +N+CO2<=>NO+CO 3.000E+12 .000 11300.00 +O+CH3=>H+H2+CO 3.370E+13 .000 .00 +O+C2H4<=>H+CH2CHO 6.700E+06 1.830 220.00 +O+C2H5<=>H+CH3CHO 1.096E+14 .000 .00 +OH+HO2<=>O2+H2O 0.500E+16 .000 17330.00 + DUPLICATE +OH+CH3=>H2+CH2O 8.000E+09 .500 -1755.00 +CH+H2(+M)<=>CH3(+M) 1.970E+12 .430 -370.00 + LOW/ 4.820E+25 -2.80 590.0 / + TROE/ .578 122.0 2535.0 9365.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +CH2+O2=>2H+CO2 5.800E+12 .000 1500.00 +CH2+O2<=>O+CH2O 2.400E+12 .000 1500.00 +CH2+CH2=>2H+C2H2 2.000E+14 .000 10989.00 +!% (H)(C-H) + (H)(C-H) = (H) + (H) + (C-H)(C-H) +CH2(S)+H2O=>H2+CH2O 6.820E+10 .250 -935.00 +C2H3+O2<=>O+CH2CHO 3.030E+11 .290 11.00 +C2H3+O2<=>HO2+C2H2 1.337E+06 1.610 -384.00 +O+CH3CHO<=>OH+CH2CHO 5.840E+12 .000 1808.00 +O+CH3CHO=>OH+CH3+CO 5.840E+12 .000 1808.00 +!% (O) + (C-H3)(C-O)(H) = (H)(O) + (C-O) + (C-H3) +O2+CH3CHO=>HO2+CH3+CO 3.010E+13 .000 39150.00 +!% (O2) + (C-H3)(C-O)(H) = (H)(O2) + (C-O) + (C-H3) +H+CH3CHO<=>CH2CHO+H2 2.050E+09 1.160 2405.00 +H+CH3CHO=>CH3+H2+CO 2.050E+09 1.160 2405.00 +!% (H) + (C-H3)(H)(C-O) = (H)(H) + (C-O) + (C-H3) +OH+CH3CHO=>CH3+H2O+CO 2.343E+10 0.730 -1113.00 +!% (O-H) + (C-H3)(H)(C-O) = (H)(O-H) + (C-O) + (C-H3) +HO2+CH3CHO=>CH3+H2O2+CO 3.010E+12 .000 11923.00 +!% (O-H2) + (C-H3)(H)(C-O) = (H)(O-H2) + (C-O) + (C-H3) +CH3+CH3CHO=>CH3+CH4+CO 2.720E+06 1.770 5920.00 +!% (C-H3) + (C-H3)(H)(C-O) = (H)(C-H3) + (C-O) + (C-H3) +H+CH2CO(+M)<=>CH2CHO(+M) 4.865E+11 0.422 -1755.00 + LOW/ 1.012E+42 -7.63 3854.0/ + TROE/ 0.465 201.0 1773.0 5333.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +O+CH2CHO=>H+CH2+CO2 1.500E+14 .000 .00 +O2+CH2CHO=>OH+CO+CH2O 1.810E+10 .000 .00 +!% (O)(O) + (C-H2)(C-O)(H) = (O)(H) + (C-H2)(O) + (C-O) +O2+CH2CHO=>OH+2HCO 2.350E+10 .000 .00 +!% (O)(O) + (C-H)(C-H-O)(H) = (O)(H) + (C-H)(O) + (C-H-O) +H+CH2CHO<=>CH3+HCO 2.200E+13 .000 .00 +H+CH2CHO<=>CH2CO+H2 1.100E+13 .000 .00 +OH+CH2CHO<=>H2O+CH2CO 1.200E+13 .000 .00 +OH+CH2CHO<=>HCO+CH2OH 3.010E+13 .000 .00 +!% (O-H) + (H2-C)(O-H-C) = (O-H)(H2-C) + (O-H-C) +CH3+C2H5(+M)<=>C3H8(+M) .9430E+13 .000 .00 + LOW/ 2.710E+74 -16.82 13065.0 / + TROE/ .1527 291.0 2742.0 7748.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +O+C3H8<=>OH+C3H7 1.930E+05 2.680 3716.00 +H+C3H8<=>C3H7+H2 1.320E+06 2.540 6756.00 +OH+C3H8<=>C3H7+H2O 3.160E+07 1.800 934.00 +C3H7+H2O2<=>HO2+C3H8 3.780E+02 2.720 1500.00 +CH3+C3H8<=>C3H7+CH4 0.903E+00 3.650 7154.00 +CH3+C2H4(+M)<=>C3H7(+M) 2.550E+06 1.600 5700.00 + LOW/ 3.00E+63 -14.6 18170./ + TROE/ .1894 277.0 8748.0 7891.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +O+C3H7<=>C2H5+CH2O 9.640E+13 .000 .00 +H+C3H7(+M)<=>C3H8(+M) 3.613E+13 .000 .00 + LOW/ 4.420E+61 -13.545 11357.0/ + TROE/ .315 369.0 3285.0 6667.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C3H7<=>CH3+C2H5 4.060E+06 2.190 890.00 +OH+C3H7<=>C2H5+CH2OH 2.410E+13 .000 .00 +HO2+C3H7<=>O2+C3H8 2.550E+10 0.255 -943.00 +HO2+C3H7=>OH+C2H5+CH2O 2.410E+13 .000 .00 +!% (O-H)(O) + (C2-H5)(C-H2) = (O-H) + (C2-H5) + (O)(C-H2) +CH3+C3H7<=>2C2H5 1.927E+13 -0.320 .00 +END diff --git a/data/inputs/grinc.inp b/data/inputs/grinc.inp new file mode 100755 index 000000000..97c861a0d --- /dev/null +++ b/data/inputs/grinc.inp @@ -0,0 +1,228 @@ +! GRI-Mech Version 3.0 3/12/99 CHEMKIN-II format +! See README30 file at anonymous FTP site unix.sri.com, directory gri; +! WorldWideWeb home page http://www.me.berkeley.edu/gri_mech/ or +! through http://www.gri.org , under 'Basic Research', +! for additional information, contacts, and disclaimer +ELEMENTS +O H N +END +SPECIES +H2 H O O2 OH H2O N2 +END +THERMO ALL + 300.000 1000.000 5000.000 +O L 1/90O 1 00 00 00G 200.000 3500.000 1000.000 1 + 2.56942078E+00-8.59741137E-05 4.19484589E-08-1.00177799E-11 1.22833691E-15 2 + 2.92175791E+04 4.78433864E+00 3.16826710E+00-3.27931884E-03 6.64306396E-06 3 +-6.12806624E-09 2.11265971E-12 2.91222592E+04 2.05193346E+00 4 +O2 TPIS89O 2 00 00 00G 200.000 3500.000 1000.000 1 + 3.28253784E+00 1.48308754E-03-7.57966669E-07 2.09470555E-10-2.16717794E-14 2 +-1.08845772E+03 5.45323129E+00 3.78245636E+00-2.99673416E-03 9.84730201E-06 3 +-9.68129509E-09 3.24372837E-12-1.06394356E+03 3.65767573E+00 4 +H L 7/88H 1 00 00 00G 200.000 3500.000 1000.000 1 + 2.50000001E+00-2.30842973E-11 1.61561948E-14-4.73515235E-18 4.98197357E-22 2 + 2.54736599E+04-4.46682914E-01 2.50000000E+00 7.05332819E-13-1.99591964E-15 3 + 2.30081632E-18-9.27732332E-22 2.54736599E+04-4.46682853E-01 4 +H2 TPIS78H 2 00 00 00G 200.000 3500.000 1000.000 1 + 3.33727920E+00-4.94024731E-05 4.99456778E-07-1.79566394E-10 2.00255376E-14 2 +-9.50158922E+02-3.20502331E+00 2.34433112E+00 7.98052075E-03-1.94781510E-05 3 + 2.01572094E-08-7.37611761E-12-9.17935173E+02 6.83010238E-01 4 +OH RUS 78O 1H 1 00 00G 200.000 3500.000 1000.000 1 + 3.09288767E+00 5.48429716E-04 1.26505228E-07-8.79461556E-11 1.17412376E-14 2 + 3.85865700E+03 4.47669610E+00 3.99201543E+00-2.40131752E-03 4.61793841E-06 3 +-3.88113333E-09 1.36411470E-12 3.61508056E+03-1.03925458E-01 4 +H2O L 8/89H 2O 1 00 00G 200.000 3500.000 1000.000 1 + 3.03399249E+00 2.17691804E-03-1.64072518E-07-9.70419870E-11 1.68200992E-14 2 +-3.00042971E+04 4.96677010E+00 4.19864056E+00-2.03643410E-03 6.52040211E-06 3 +-5.48797062E-09 1.77197817E-12-3.02937267E+04-8.49032208E-01 4 +HO2 L 5/89H 1O 2 00 00G 200.000 3500.000 1000.000 1 + 4.01721090E+00 2.23982013E-03-6.33658150E-07 1.14246370E-10-1.07908535E-14 2 + 1.11856713E+02 3.78510215E+00 4.30179801E+00-4.74912051E-03 2.11582891E-05 3 +-2.42763894E-08 9.29225124E-12 2.94808040E+02 3.71666245E+00 4 +H2O2 L 7/88H 2O 2 00 00G 200.000 3500.000 1000.000 1 + 4.16500285E+00 4.90831694E-03-1.90139225E-06 3.71185986E-10-2.87908305E-14 2 +-1.78617877E+04 2.91615662E+00 4.27611269E+00-5.42822417E-04 1.67335701E-05 3 +-2.15770813E-08 8.62454363E-12-1.77025821E+04 3.43505074E+00 4 +C L11/88C 1 00 00 00G 200.000 3500.000 1000.000 1 + 2.49266888E+00 4.79889284E-05-7.24335020E-08 3.74291029E-11-4.87277893E-15 2 + 8.54512953E+04 4.80150373E+00 2.55423955E+00-3.21537724E-04 7.33792245E-07 3 +-7.32234889E-10 2.66521446E-13 8.54438832E+04 4.53130848E+00 4 +CH TPIS79C 1H 1 00 00G 200.000 3500.000 1000.000 1 + 2.87846473E+00 9.70913681E-04 1.44445655E-07-1.30687849E-10 1.76079383E-14 2 + 7.10124364E+04 5.48497999E+00 3.48981665E+00 3.23835541E-04-1.68899065E-06 3 + 3.16217327E-09-1.40609067E-12 7.07972934E+04 2.08401108E+00 4 +CH2 L S/93C 1H 2 00 00G 200.000 3500.000 1000.000 1 + 2.87410113E+00 3.65639292E-03-1.40894597E-06 2.60179549E-10-1.87727567E-14 2 + 4.62636040E+04 6.17119324E+00 3.76267867E+00 9.68872143E-04 2.79489841E-06 3 +-3.85091153E-09 1.68741719E-12 4.60040401E+04 1.56253185E+00 4 +CH2(S) L S/93C 1H 2 00 00G 200.000 3500.000 1000.000 1 + 2.29203842E+00 4.65588637E-03-2.01191947E-06 4.17906000E-10-3.39716365E-14 2 + 5.09259997E+04 8.62650169E+00 4.19860411E+00-2.36661419E-03 8.23296220E-06 3 +-6.68815981E-09 1.94314737E-12 5.04968163E+04-7.69118967E-01 4 +CH3 L11/89C 1H 3 00 00G 200.000 3500.000 1000.000 1 + 2.28571772E+00 7.23990037E-03-2.98714348E-06 5.95684644E-10-4.67154394E-14 2 + 1.67755843E+04 8.48007179E+00 3.67359040E+00 2.01095175E-03 5.73021856E-06 3 +-6.87117425E-09 2.54385734E-12 1.64449988E+04 1.60456433E+00 4 +CH4 L 8/88C 1H 4 00 00G 200.000 3500.000 1000.000 1 + 7.48514950E-02 1.33909467E-02-5.73285809E-06 1.22292535E-09-1.01815230E-13 2 +-9.46834459E+03 1.84373180E+01 5.14987613E+00-1.36709788E-02 4.91800599E-05 3 +-4.84743026E-08 1.66693956E-11-1.02466476E+04-4.64130376E+00 4 +CO TPIS79C 1O 1 00 00G 200.000 3500.000 1000.000 1 + 2.71518561E+00 2.06252743E-03-9.98825771E-07 2.30053008E-10-2.03647716E-14 2 +-1.41518724E+04 7.81868772E+00 3.57953347E+00-6.10353680E-04 1.01681433E-06 3 + 9.07005884E-10-9.04424499E-13-1.43440860E+04 3.50840928E+00 4 +CO2 L 7/88C 1O 2 00 00G 200.000 3500.000 1000.000 1 + 3.85746029E+00 4.41437026E-03-2.21481404E-06 5.23490188E-10-4.72084164E-14 2 +-4.87591660E+04 2.27163806E+00 2.35677352E+00 8.98459677E-03-7.12356269E-06 3 + 2.45919022E-09-1.43699548E-13-4.83719697E+04 9.90105222E+00 4 +HCO L12/89H 1C 1O 1 00G 200.000 3500.000 1000.000 1 + 2.77217438E+00 4.95695526E-03-2.48445613E-06 5.89161778E-10-5.33508711E-14 2 + 4.01191815E+03 9.79834492E+00 4.22118584E+00-3.24392532E-03 1.37799446E-05 3 +-1.33144093E-08 4.33768865E-12 3.83956496E+03 3.39437243E+00 4 +CH2O L 8/88H 2C 1O 1 00G 200.000 3500.000 1000.000 1 + 1.76069008E+00 9.20000082E-03-4.42258813E-06 1.00641212E-09-8.83855640E-14 2 +-1.39958323E+04 1.36563230E+01 4.79372315E+00-9.90833369E-03 3.73220008E-05 3 +-3.79285261E-08 1.31772652E-11-1.43089567E+04 6.02812900E-01 4 +CH2OH GUNL93C 1H 3O 1 00G 200.000 3500.000 1000.000 1 + 3.69266569E+00 8.64576797E-03-3.75101120E-06 7.87234636E-10-6.48554201E-14 2 +-3.24250627E+03 5.81043215E+00 3.86388918E+00 5.59672304E-03 5.93271791E-06 3 +-1.04532012E-08 4.36967278E-12-3.19391367E+03 5.47302243E+00 4 +CH3O 121686C 1H 3O 1 G 0300.00 3000.00 1000.000 1 + 0.03770799E+02 0.07871497E-01-0.02656384E-04 0.03944431E-08-0.02112616E-12 2 + 0.12783252E+03 0.02929575E+02 0.02106204E+02 0.07216595E-01 0.05338472E-04 3 +-0.07377636E-07 0.02075610E-10 0.09786011E+04 0.13152177E+02 4 +CH3OH L 8/88C 1H 4O 1 00G 200.000 3500.000 1000.000 1 + 1.78970791E+00 1.40938292E-02-6.36500835E-06 1.38171085E-09-1.17060220E-13 2 +-2.53748747E+04 1.45023623E+01 5.71539582E+00-1.52309129E-02 6.52441155E-05 3 +-7.10806889E-08 2.61352698E-11-2.56427656E+04-1.50409823E+00 4 +C2H L 1/91C 2H 1 00 00G 200.000 3500.000 1000.000 1 + 3.16780652E+00 4.75221902E-03-1.83787077E-06 3.04190252E-10-1.77232770E-14 2 + 6.71210650E+04 6.63589475E+00 2.88965733E+00 1.34099611E-02-2.84769501E-05 3 + 2.94791045E-08-1.09331511E-11 6.68393932E+04 6.22296438E+00 4 +C2H2 L 1/91C 2H 2 00 00G 200.000 3500.000 1000.000 1 + 4.14756964E+00 5.96166664E-03-2.37294852E-06 4.67412171E-10-3.61235213E-14 2 + 2.59359992E+04-1.23028121E+00 8.08681094E-01 2.33615629E-02-3.55171815E-05 3 + 2.80152437E-08-8.50072974E-12 2.64289807E+04 1.39397051E+01 4 +C2H3 L 2/92C 2H 3 00 00G 200.000 3500.000 1000.000 1 + 3.01672400E+00 1.03302292E-02-4.68082349E-06 1.01763288E-09-8.62607041E-14 2 + 3.46128739E+04 7.78732378E+00 3.21246645E+00 1.51479162E-03 2.59209412E-05 3 +-3.57657847E-08 1.47150873E-11 3.48598468E+04 8.51054025E+00 4 +C2H4 L 1/91C 2H 4 00 00G 200.000 3500.000 1000.000 1 + 2.03611116E+00 1.46454151E-02-6.71077915E-06 1.47222923E-09-1.25706061E-13 2 + 4.93988614E+03 1.03053693E+01 3.95920148E+00-7.57052247E-03 5.70990292E-05 3 +-6.91588753E-08 2.69884373E-11 5.08977593E+03 4.09733096E+00 4 +C2H5 L12/92C 2H 5 00 00G 200.000 3500.000 1000.000 1 + 1.95465642E+00 1.73972722E-02-7.98206668E-06 1.75217689E-09-1.49641576E-13 2 + 1.28575200E+04 1.34624343E+01 4.30646568E+00-4.18658892E-03 4.97142807E-05 3 +-5.99126606E-08 2.30509004E-11 1.28416265E+04 4.70720924E+00 4 +C2H6 L 8/88C 2H 6 00 00G 200.000 3500.000 1000.000 1 + 1.07188150E+00 2.16852677E-02-1.00256067E-05 2.21412001E-09-1.90002890E-13 2 +-1.14263932E+04 1.51156107E+01 4.29142492E+00-5.50154270E-03 5.99438288E-05 3 +-7.08466285E-08 2.68685771E-11-1.15222055E+04 2.66682316E+00 4 +CH2CO L 5/90C 2H 2O 1 00G 200.000 3500.000 1000.000 1 + 4.51129732E+00 9.00359745E-03-4.16939635E-06 9.23345882E-10-7.94838201E-14 2 +-7.55105311E+03 6.32247205E-01 2.13583630E+00 1.81188721E-02-1.73947474E-05 3 + 9.34397568E-09-2.01457615E-12-7.04291804E+03 1.22156480E+01 4 +HCCO SRIC91H 1C 2O 1 G 0300.00 4000.00 1000.000 1 + 0.56282058E+01 0.40853401E-02-0.15934547E-05 0.28626052E-09-0.19407832E-13 2 + 0.19327215E+05-0.39302595E+01 0.22517214E+01 0.17655021E-01-0.23729101E-04 3 + 0.17275759E-07-0.50664811E-11 0.20059449E+05 0.12490417E+02 4 +HCCOH SRI91C 2O 1H 20 0G 300.000 5000.000 1000.000 1 + 0.59238291E+01 0.67923600E-02-0.25658564E-05 0.44987841E-09-0.29940101E-13 2 + 0.72646260E+04-0.76017742E+01 0.12423733E+01 0.31072201E-01-0.50866864E-04 3 + 0.43137131E-07-0.14014594E-10 0.80316143E+04 0.13874319E+02 4 +H2CN 41687H 2C 1N 1 G 0300.00 4000.000 1000.000 1 + 0.52097030E+01 0.29692911E-02-0.28555891E-06-0.16355500E-09 0.30432589E-13 2 + 0.27677109E+05-0.44444780E+01 0.28516610E+01 0.56952331E-02 0.10711400E-05 3 +-0.16226120E-08-0.23511081E-12 0.28637820E+05 0.89927511E+01 4 +HCN GRI/98H 1C 1N 1 0G 200.000 6000.000 1000.000 1 + 0.38022392E+01 0.31464228E-02-0.10632185E-05 0.16619757E-09-0.97997570E-14 2 + 0.14407292E+05 0.15754601E+01 0.22589886E+01 0.10051170E-01-0.13351763E-04 3 + 0.10092349E-07-0.30089028E-11 0.14712633E+05 0.89164419E+01 4 +HNO And93 H 1N 1O 1 0G 200.000 6000.000 1000.000 1 + 0.29792509E+01 0.34944059E-02-0.78549778E-06 0.57479594E-10-0.19335916E-15 2 + 0.11750582E+05 0.86063728E+01 0.45334916E+01-0.56696171E-02 0.18473207E-04 3 +-0.17137094E-07 0.55454573E-11 0.11548297E+05 0.17498417E+01 4 +N L 6/88N 1 0 0 0G 200.000 6000.000 1000.000 1 + 0.24159429E+01 0.17489065E-03-0.11902369E-06 0.30226245E-10-0.20360982E-14 2 + 0.56133773E+05 0.46496096E+01 0.25000000E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.56104637E+05 0.41939087E+01 4 +NNH T07/93N 2H 1 00 00G 200.000 6000.000 1000.000 1 + 0.37667544E+01 0.28915082E-02-0.10416620E-05 0.16842594E-09-0.10091896E-13 2 + 0.28650697E+05 0.44705067E+01 0.43446927E+01-0.48497072E-02 0.20059459E-04 3 +-0.21726464E-07 0.79469539E-11 0.28791973E+05 0.29779410E+01 4 +N2O L 7/88N 2O 1 0 0G 200.000 6000.000 1000.000 1 + 0.48230729E+01 0.26270251E-02-0.95850874E-06 0.16000712E-09-0.97752303E-14 2 + 0.80734048E+04-0.22017207E+01 0.22571502E+01 0.11304728E-01-0.13671319E-04 3 + 0.96819806E-08-0.29307182E-11 0.87417744E+04 0.10757992E+02 4 +NH And94 N 1H 1 0 0G 200.000 6000.000 1000.000 1 + 0.27836928E+01 0.13298430E-02-0.42478047E-06 0.78348501E-10-0.55044470E-14 2 + 0.42120848E+05 0.57407799E+01 0.34929085E+01 0.31179198E-03-0.14890484E-05 3 + 0.24816442E-08-0.10356967E-11 0.41880629E+05 0.18483278E+01 4 +NH2 And89 N 1H 2 0 0G 200.000 6000.000 1000.000 1 + 0.28347421E+01 0.32073082E-02-0.93390804E-06 0.13702953E-09-0.79206144E-14 2 + 0.22171957E+05 0.65204163E+01 0.42040029E+01-0.21061385E-02 0.71068348E-05 3 +-0.56115197E-08 0.16440717E-11 0.21885910E+05-0.14184248E+00 4 +NH3 J 6/77N 1H 3 0 0G 200.000 6000.000 1000.000 1 + 0.26344521E+01 0.56662560E-02-0.17278676E-05 0.23867161E-09-0.12578786E-13 2 +-0.65446958E+04 0.65662928E+01 0.42860274E+01-0.46605230E-02 0.21718513E-04 3 +-0.22808887E-07 0.82638046E-11-0.67417285E+04-0.62537277E+00 4 +NO RUS 78N 1O 1 0 0G 200.000 6000.000 1000.000 1 + 0.32606056E+01 0.11911043E-02-0.42917048E-06 0.69457669E-10-0.40336099E-14 2 + 0.99209746E+04 0.63693027E+01 0.42184763E+01-0.46389760E-02 0.11041022E-04 3 +-0.93361354E-08 0.28035770E-11 0.98446230E+04 0.22808464E+01 4 +NO2 L 7/88N 1O 2 0 0G 200.000 6000.000 1000.000 1 + 0.48847542E+01 0.21723956E-02-0.82806906E-06 0.15747510E-09-0.10510895E-13 2 + 0.23164983E+04-0.11741695E+00 0.39440312E+01-0.15854290E-02 0.16657812E-04 3 +-0.20475426E-07 0.78350564E-11 0.28966179E+04 0.63119917E+01 4 +HCNO BDEA94H 1N 1C 1O 1G 300.000 5000.000 1382.000 1 + 6.59860456E+00 3.02778626E-03-1.07704346E-06 1.71666528E-10-1.01439391E-14 2 + 1.79661339E+04-1.03306599E+01 2.64727989E+00 1.27505342E-02-1.04794236E-05 3 + 4.41432836E-09-7.57521466E-13 1.92990252E+04 1.07332972E+01 4 +HOCN BDEA94H 1N 1C 1O 1G 300.000 5000.000 1368.000 1 + 5.89784885E+00 3.16789393E-03-1.11801064E-06 1.77243144E-10-1.04339177E-14 2 +-3.70653331E+03-6.18167825E+00 3.78604952E+00 6.88667922E-03-3.21487864E-06 3 + 5.17195767E-10 1.19360788E-14-2.82698400E+03 5.63292162E+00 4 +HNCO BDEA94H 1N 1C 1O 1G 300.000 5000.000 1478.000 1 + 6.22395134E+00 3.17864004E-03-1.09378755E-06 1.70735163E-10-9.95021955E-15 2 +-1.66599344E+04-8.38224741E+00 3.63096317E+00 7.30282357E-03-2.28050003E-06 3 +-6.61271298E-10 3.62235752E-13-1.55873636E+04 6.19457727E+00 4 +NCO EA 93 N 1C 1O 1 0G 200.000 6000.000 1000.000 1 + 0.51521845E+01 0.23051761E-02-0.88033153E-06 0.14789098E-09-0.90977996E-14 2 + 0.14004123E+05-0.25442660E+01 0.28269308E+01 0.88051688E-02-0.83866134E-05 3 + 0.48016964E-08-0.13313595E-11 0.14682477E+05 0.95504646E+01 4 +CN HBH92 C 1N 1 0 0G 200.000 6000.000 1000.000 1 + 0.37459805E+01 0.43450775E-04 0.29705984E-06-0.68651806E-10 0.44134173E-14 2 + 0.51536188E+05 0.27867601E+01 0.36129351E+01-0.95551327E-03 0.21442977E-05 3 +-0.31516323E-09-0.46430356E-12 0.51708340E+05 0.39804995E+01 4 +HCNN SRI/94C 1N 2H 10 0G 300.000 5000.000 1000.000 1 + 0.58946362E+01 0.39895959E-02-0.15982380E-05 0.29249395E-09-0.20094686E-13 2 + 0.53452941E+05-0.51030502E+01 0.25243194E+01 0.15960619E-01-0.18816354E-04 3 + 0.12125540E-07-0.32357378E-11 0.54261984E+05 0.11675870E+02 4 +N2 121286N 2 G 300.000 5000.000 1000.000 1 + 0.02926640E+02 0.14879768E-02-0.05684760E-05 0.10097038E-09-0.06753351E-13 2 +-0.09227977E+04 0.05980528E+02 0.03298677E+02 0.14082404E-02-0.03963222E-04 3 + 0.05641515E-07-0.02444854E-10-0.10208999E+04 0.03950372E+02 4 +AR 120186AR 1 G 300.000 5000.000 1000.000 1 + 0.02500000E+02 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-0.07453750E+04 0.04366000E+02 0.02500000E+02 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-0.07453750E+04 0.04366000E+02 4 +C3H8 L 4/85C 3H 8 0 0G 300.000 5000.000 1000.00 1 + 0.75341368E+01 0.18872239E-01-0.62718491E-05 0.91475649E-09-0.47838069E-13 2 +-0.16467516E+05-0.17892349E+02 0.93355381E+00 0.26424579E-01 0.61059727E-05 3 +-0.21977499E-07 0.95149253E-11-0.13958520E+05 0.19201691E+02 4 +C3H7 L 9/84C 3H 7 0 0G 300.000 5000.000 1000.00 1 + 0.77026987E+01 0.16044203E-01-0.52833220E-05 0.76298590E-09-0.39392284E-13 2 + 0.82984336E+04-0.15480180E+02 0.10515518E+01 0.25991980E-01 0.23800540E-05 3 +-0.19609569E-07 0.93732470E-11 0.10631863E+05 0.21122559E+02 4 +CH3CHO L 8/88C 2H 4O 1 0G 200.000 6000.000 1000.00 1 + 0.54041108E+01 0.11723059E-01-0.42263137E-05 0.68372451E-09-0.40984863E-13 2 +-0.22593122E+05-0.34807917E+01 0.47294595E+01-0.31932858E-02 0.47534921E-04 3 +-0.57458611E-07 0.21931112E-10-0.21572878E+05 0.41030159E+01 4 +CH2CHO SAND86O 1H 3C 2 G 300.00 5000.00 1000.00 1 + 0.05975670E+02 0.08130591E-01-0.02743624E-04 0.04070304E-08-0.02176017E-12 2 + 0.04903218E+04-0.05045251E+02 0.03409062E+02 0.10738574E-01 0.01891492E-04 3 +-0.07158583E-07 0.02867385E-10 0.15214766E+04 0.09558290E+02 4 +END +REACTIONS +END diff --git a/data/inputs/h2o2.inp b/data/inputs/h2o2.inp new file mode 100755 index 000000000..04c31b06b --- /dev/null +++ b/data/inputs/h2o2.inp @@ -0,0 +1,88 @@ +ELEMENTS +O H AR +END +SPECIES +H2 H O O2 OH H2O HO2 H2O2 +AR +END +THERMO ALL + 300.000 1000.000 5000.000 +O L 1/90O 1 00 00 00G 200.000 3500.000 1000.000 1 + 2.56942078E+00-8.59741137E-05 4.19484589E-08-1.00177799E-11 1.22833691E-15 2 + 2.92175791E+04 4.78433864E+00 3.16826710E+00-3.27931884E-03 6.64306396E-06 3 +-6.12806624E-09 2.11265971E-12 2.91222592E+04 2.05193346E+00 4 +O2 TPIS89O 2 00 00 00G 200.000 3500.000 1000.000 1 + 3.28253784E+00 1.48308754E-03-7.57966669E-07 2.09470555E-10-2.16717794E-14 2 +-1.08845772E+03 5.45323129E+00 3.78245636E+00-2.99673416E-03 9.84730201E-06 3 +-9.68129509E-09 3.24372837E-12-1.06394356E+03 3.65767573E+00 4 +H L 7/88H 1 00 00 00G 200.000 3500.000 1000.000 1 + 2.50000001E+00-2.30842973E-11 1.61561948E-14-4.73515235E-18 4.98197357E-22 2 + 2.54736599E+04-4.46682914E-01 2.50000000E+00 7.05332819E-13-1.99591964E-15 3 + 2.30081632E-18-9.27732332E-22 2.54736599E+04-4.46682853E-01 4 +H2 TPIS78H 2 00 00 00G 200.000 3500.000 1000.000 1 + 3.33727920E+00-4.94024731E-05 4.99456778E-07-1.79566394E-10 2.00255376E-14 2 +-9.50158922E+02-3.20502331E+00 2.34433112E+00 7.98052075E-03-1.94781510E-05 3 + 2.01572094E-08-7.37611761E-12-9.17935173E+02 6.83010238E-01 4 +OH RUS 78O 1H 1 00 00G 200.000 3500.000 1000.000 1 + 3.09288767E+00 5.48429716E-04 1.26505228E-07-8.79461556E-11 1.17412376E-14 2 + 3.85865700E+03 4.47669610E+00 3.99201543E+00-2.40131752E-03 4.61793841E-06 3 +-3.88113333E-09 1.36411470E-12 3.61508056E+03-1.03925458E-01 4 +H2O L 8/89H 2O 1 00 00G 200.000 3500.000 1000.000 1 + 3.03399249E+00 2.17691804E-03-1.64072518E-07-9.70419870E-11 1.68200992E-14 2 +-3.00042971E+04 4.96677010E+00 4.19864056E+00-2.03643410E-03 6.52040211E-06 3 +-5.48797062E-09 1.77197817E-12-3.02937267E+04-8.49032208E-01 4 +HO2 L 5/89H 1O 2 00 00G 200.000 3500.000 1000.000 1 + 4.01721090E+00 2.23982013E-03-6.33658150E-07 1.14246370E-10-1.07908535E-14 2 + 1.11856713E+02 3.78510215E+00 4.30179801E+00-4.74912051E-03 2.11582891E-05 3 +-2.42763894E-08 9.29225124E-12 2.94808040E+02 3.71666245E+00 4 +H2O2 L 7/88H 2O 2 00 00G 200.000 3500.000 1000.000 1 + 4.16500285E+00 4.90831694E-03-1.90139225E-06 3.71185986E-10-2.87908305E-14 2 +-1.78617877E+04 2.91615662E+00 4.27611269E+00-5.42822417E-04 1.67335701E-05 3 +-2.15770813E-08 8.62454363E-12-1.77025821E+04 3.43505074E+00 4 +AR 120186AR 1 G 300.000 5000.000 1000.000 1 + 0.02500000E+02 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-0.07453750E+04 0.04366000E+02 0.02500000E+02 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-0.07453750E+04 0.04366000E+02 4 +END +REACTIONS +2O+M<=>O2+M 1.200E+17 -1.000 .00 +H2/ 2.40/ H2O/15.40/ AR/ .83/ +O+H+M<=>OH+M 5.000E+17 -1.000 .00 +H2/2.00/ H2O/6.00/ AR/ .70/ +O+H2<=>H+OH 3.870E+04 2.700 6260.00 +O+HO2<=>OH+O2 2.000E+13 .000 .00 +O+H2O2<=>OH+HO2 9.630E+06 2.000 4000.00 +H+2O2<=>HO2+O2 2.080E+19 -1.240 .00 +H+O2+H2O<=>HO2+H2O 11.26E+18 -.760 .00 +H+O2+AR<=>HO2+AR 7.000E+17 -.800 .00 +H+O2<=>O+OH 2.650E+16 -.6707 17041.00 +2H+M<=>H2+M 1.000E+18 -1.000 .00 +H2/ .00/ H2O/ .00/ AR/ .63/ +2H+H2<=>2H2 9.000E+16 -.600 .00 +2H+H2O<=>H2+H2O 6.000E+19 -1.250 .00 +H+OH+M<=>H2O+M 2.200E+22 -2.000 .00 +H2/ .73/ H2O/3.65/ AR/ .38/ +H+HO2<=>O+H2O 3.970E+12 .000 671.00 +H+HO2<=>O2+H2 4.480E+13 .000 1068.00 +H+HO2<=>2OH 0.840E+14 .000 635.00 +H+H2O2<=>HO2+H2 1.210E+07 2.000 5200.00 +H+H2O2<=>OH+H2O 1.000E+13 .000 3600.00 +OH+H2<=>H+H2O 2.160E+08 1.510 3430.00 +2OH(+M)<=>H2O2(+M) 7.400E+13 -.370 .00 + LOW / 2.300E+18 -.900 -1700.00/ + TROE/ .7346 94.00 1756.00 5182.00 / +H2/2.00/ H2O/6.00/ AR/ .70/ +2OH<=>O+H2O 3.570E+04 2.400 -2110.00 +OH+HO2<=>O2+H2O 1.450E+13 .000 -500.00 + DUPLICATE +OH+H2O2<=>HO2+H2O 2.000E+12 .000 427.00 + DUPLICATE +OH+H2O2<=>HO2+H2O 1.700E+18 .000 29410.00 + DUPLICATE +2HO2<=>O2+H2O2 1.300E+11 .000 -1630.00 + DUPLICATE +2HO2<=>O2+H2O2 4.200E+14 .000 12000.00 + DUPLICATE +OH+HO2<=>O2+H2O 0.500E+16 .000 17330.00 + DUPLICATE +END diff --git a/data/inputs/h2o2.xml b/data/inputs/h2o2.xml new file mode 100644 index 000000000..8e9b84a97 --- /dev/null +++ b/data/inputs/h2o2.xml @@ -0,0 +1,558 @@ + + + + + + + + + 300 + 1 + H2:1.0 + + + O H Ar + + H2 H O O2 OH H2O HO2 H2O2 AR + + + + + + + + + + + + + + TPIS78 + H:2 + + + + 2.344331120E+00, 7.980520750E-03, -1.947815100E-05, + 2.015720940E-08, -7.376117610E-12, -9.179351730E+02, + 6.830102380E-01 + + + 3.337279200E+00, -4.940247310E-05, 4.994567780E-07, + -1.795663940E-10, 2.002553760E-14, -9.501589220E+02, + -3.205023310E+00 + + + + + linear + 3.800000000E+01 + 2.920000000E+00 + 7.900000000E-01 + 2.800000000E+02 + + + + + + L 7/88 + H:1 + + + + 2.500000000E+00, 7.053328190E-13, -1.995919640E-15, + 2.300816320E-18, -9.277323320E-22, 2.547365990E+04, + -4.466828530E-01 + + + 2.500000010E+00, -2.308429730E-11, 1.615619480E-14, + -4.735152350E-18, 4.981973570E-22, 2.547365990E+04, + -4.466829140E-01 + + + + + atom + 1.450000000E+02 + 2.050000000E+00 + + + + + + L 1/90 + O:1 + + + + 3.168267100E+00, -3.279318840E-03, 6.643063960E-06, + -6.128066240E-09, 2.112659710E-12, 2.912225920E+04, + 2.051933460E+00 + + + 2.569420780E+00, -8.597411370E-05, 4.194845890E-08, + -1.001777990E-11, 1.228336910E-15, 2.921757910E+04, + 4.784338640E+00 + + + + + atom + 8.000000000E+01 + 2.750000000E+00 + + + + + + TPIS89 + O:2 + + + + 3.782456360E+00, -2.996734160E-03, 9.847302010E-06, + -9.681295090E-09, 3.243728370E-12, -1.063943560E+03, + 3.657675730E+00 + + + 3.282537840E+00, 1.483087540E-03, -7.579666690E-07, + 2.094705550E-10, -2.167177940E-14, -1.088457720E+03, + 5.453231290E+00 + + + + + linear + 1.074000000E+02 + 3.458000000E+00 + 1.600000000E+00 + 3.800000000E+00 + + + + + + RUS 78 + O:1 H:1 + + + + 3.992015430E+00, -2.401317520E-03, 4.617938410E-06, + -3.881133330E-09, 1.364114700E-12, 3.615080560E+03, + -1.039254580E-01 + + + 3.092887670E+00, 5.484297160E-04, 1.265052280E-07, + -8.794615560E-11, 1.174123760E-14, 3.858657000E+03, + 4.476696100E+00 + + + + + linear + 8.000000000E+01 + 2.750000000E+00 + + + + + + L 8/89 + H:2 O:1 + + + + 4.198640560E+00, -2.036434100E-03, 6.520402110E-06, + -5.487970620E-09, 1.771978170E-12, -3.029372670E+04, + -8.490322080E-01 + + + 3.033992490E+00, 2.176918040E-03, -1.640725180E-07, + -9.704198700E-11, 1.682009920E-14, -3.000429710E+04, + 4.966770100E+00 + + + + + nonlinear + 5.724000000E+02 + 2.605000000E+00 + 1.844000000E+00 + 4.000000000E+00 + + + + + + L 5/89 + H:1 O:2 + + + + 4.301798010E+00, -4.749120510E-03, 2.115828910E-05, + -2.427638940E-08, 9.292251240E-12, 2.948080400E+02, + 3.716662450E+00 + + + 4.017210900E+00, 2.239820130E-03, -6.336581500E-07, + 1.142463700E-10, -1.079085350E-14, 1.118567130E+02, + 3.785102150E+00 + + + + + nonlinear + 1.074000000E+02 + 3.458000000E+00 + 1.000000000E+00 + + + + + + L 7/88 + H:2 O:2 + + + + 4.276112690E+00, -5.428224170E-04, 1.673357010E-05, + -2.157708130E-08, 8.624543630E-12, -1.770258210E+04, + 3.435050740E+00 + + + 4.165002850E+00, 4.908316940E-03, -1.901392250E-06, + 3.711859860E-10, -2.879083050E-14, -1.786178770E+04, + 2.916156620E+00 + + + + + nonlinear + 1.074000000E+02 + 3.458000000E+00 + 3.800000000E+00 + + + + + + 120186 + Ar:1 + + + + 2.500000000E+00, 0.000000000E+00, 0.000000000E+00, + 0.000000000E+00, 0.000000000E+00, -7.453750000E+02, + 4.366000000E+00 + + + 2.500000000E+00, 0.000000000E+00, 0.000000000E+00, + 0.000000000E+00, 0.000000000E+00, -7.453750000E+02, + 4.366000000E+00 + + + + + atom + 1.365000000E+02 + 3.330000000E+00 + + + + + + + + + + 2 O + M [=] O2 + M + O:2 + O2:1 + + 1.2e+17 -1 0 + + AR:0.83 H2:2.4 H2O:15.4 + + + + + + + O + H + M [=] OH + M + O:1 H:1 + OH:1 + + 5e+17 -1 0 + + AR:0.7 H2:2 H2O:6 + + + + + + + O + H2 [=] H + OH + O:1 H2:1 + H:1 OH:1 + + 38700 2.7 6260 + + + + + + O + HO2 [=] OH + O2 + O:1 HO2:1 + OH:1 O2:1 + + 2e+13 0 0 + + + + + + O + H2O2 [=] OH + HO2 + O:1 H2O2:1 + OH:1 HO2:1 + + 9.63e+06 2 4000 + + + + + + H + 2 O2 [=] HO2 + O2 + H:1 O2:2 + HO2:1 O2:1 + + 2.08e+19 -1.24 0 + + + + + + H + O2 + H2O [=] HO2 + H2O + H:1 O2:1 H2O:1 + HO2:1 H2O:1 + + 1.126e+19 -0.76 0 + + + + + + H + O2 + AR [=] HO2 + AR + H:1 O2:1 AR:1 + HO2:1 AR:1 + + 7e+17 -0.8 0 + + + + + + H + O2 [=] O + OH + H:1 O2:1 + O:1 OH:1 + + 2.65e+16 -0.6707 17041 + + + + + + 2 H + M [=] H2 + M + H:2 + H2:1 + + 1e+18 -1 0 + + AR:0.63 H2:0 H2O:0 + + + + + + + 2 H + H2 [=] 2 H2 + H:2 H2:1 + H2:2 + + 9e+16 -0.6 0 + + + + + + 2 H + H2O [=] H2 + H2O + H:2 H2O:1 + H2:1 H2O:1 + + 6e+19 -1.25 0 + + + + + + H + OH + M [=] H2O + M + H:1 OH:1 + H2O:1 + + 2.2e+22 -2 0 + + AR:0.38 H2:0.73 H2O:3.65 + + + + + + + H + HO2 [=] O + H2O + H:1 HO2:1 + O:1 H2O:1 + + 3.97e+12 0 671 + + + + + + H + HO2 [=] O2 + H2 + H:1 HO2:1 + O2:1 H2:1 + + 4.48e+13 0 1068 + + + + + + H + HO2 [=] 2 OH + H:1 HO2:1 + OH:2 + + 8.4e+13 0 635 + + + + + + H + H2O2 [=] HO2 + H2 + H:1 H2O2:1 + HO2:1 H2:1 + + 1.21e+07 2 5200 + + + + + + H + H2O2 [=] OH + H2O + H:1 H2O2:1 + OH:1 H2O:1 + + 1e+13 0 3600 + + + + + + OH + H2 [=] H + H2O + OH:1 H2:1 + H:1 H2O:1 + + 2.16e+08 1.51 3430 + + + + + + 2 OH (+ M) [=] H2O2 (+ M) + OH:2 + H2O2:1 + + 7.4e+13 -0.37 0 + 2.3e+18 -0.9 -1700 + 0.7346 94 1756 5182 + + AR:0.7 H2:2 H2O:6 + + + + + + + 2 OH [=] O + H2O + OH:2 + O:1 H2O:1 + + 35700 2.4 -2110 + + + + + + OH + HO2 [=] O2 + H2O + OH:1 HO2:1 + O2:1 H2O:1 + + 1.45e+13 0 -500 + + idtag_rxn_27 + + + + + OH + H2O2 [=] HO2 + H2O + OH:1 H2O2:1 + HO2:1 H2O:1 + + 2e+12 0 427 + + idtag_rxn_24 + + + + + OH + H2O2 [=] HO2 + H2O + OH:1 H2O2:1 + HO2:1 H2O:1 + + 1.7e+18 0 29410 + + idtag_rxn_23 + + + + + 2 HO2 [=] O2 + H2O2 + HO2:2 + O2:1 H2O2:1 + + 1.3e+11 0 -1630 + + idtag_rxn_26 + + + + + 2 HO2 [=] O2 + H2O2 + HO2:2 + O2:1 H2O2:1 + + 4.2e+14 0 12000 + + idtag_rxn_25 + + + + + OH + HO2 [=] O2 + H2O + OH:1 HO2:1 + O2:1 H2O:1 + + 5e+15 0 17330 + + idtag_rxn_22 + + + \ No newline at end of file diff --git a/data/inputs/h2o2_noch.inp b/data/inputs/h2o2_noch.inp new file mode 100755 index 000000000..a078b394e --- /dev/null +++ b/data/inputs/h2o2_noch.inp @@ -0,0 +1,48 @@ +ELEMENTS +O H AR +END +SPECIES +H2 H O O2 OH H2O HO2 H2O2 +AR +END +THERMO ALL + 300.000 1000.000 5000.000 +O L 1/90O 1 00 00 00G 200.000 3500.000 1000.000 1 + 2.56942078E+00-8.59741137E-05 4.19484589E-08-1.00177799E-11 1.22833691E-15 2 + 2.92175791E+04 4.78433864E+00 3.16826710E+00-3.27931884E-03 6.64306396E-06 3 +-6.12806624E-09 2.11265971E-12 2.91222592E+04 2.05193346E+00 4 +O2 TPIS89O 2 00 00 00G 200.000 3500.000 1000.000 1 + 3.28253784E+00 1.48308754E-03-7.57966669E-07 2.09470555E-10-2.16717794E-14 2 +-1.08845772E+03 5.45323129E+00 3.78245636E+00-2.99673416E-03 9.84730201E-06 3 +-9.68129509E-09 3.24372837E-12-1.06394356E+03 3.65767573E+00 4 +H L 7/88H 1 00 00 00G 200.000 3500.000 1000.000 1 + 2.50000001E+00-2.30842973E-11 1.61561948E-14-4.73515235E-18 4.98197357E-22 2 + 2.54736599E+04-4.46682914E-01 2.50000000E+00 7.05332819E-13-1.99591964E-15 3 + 2.30081632E-18-9.27732332E-22 2.54736599E+04-4.46682853E-01 4 +H2 TPIS78H 2 00 00 00G 200.000 3500.000 1000.000 1 + 3.33727920E+00-4.94024731E-05 4.99456778E-07-1.79566394E-10 2.00255376E-14 2 +-9.50158922E+02-3.20502331E+00 2.34433112E+00 7.98052075E-03-1.94781510E-05 3 + 2.01572094E-08-7.37611761E-12-9.17935173E+02 6.83010238E-01 4 +OH RUS 78O 1H 1 00 00G 200.000 3500.000 1000.000 1 + 3.09288767E+00 5.48429716E-04 1.26505228E-07-8.79461556E-11 1.17412376E-14 2 + 3.85865700E+03 4.47669610E+00 3.99201543E+00-2.40131752E-03 4.61793841E-06 3 +-3.88113333E-09 1.36411470E-12 3.61508056E+03-1.03925458E-01 4 +H2O L 8/89H 2O 1 00 00G 200.000 3500.000 1000.000 1 + 3.03399249E+00 2.17691804E-03-1.64072518E-07-9.70419870E-11 1.68200992E-14 2 +-3.00042971E+04 4.96677010E+00 4.19864056E+00-2.03643410E-03 6.52040211E-06 3 +-5.48797062E-09 1.77197817E-12-3.02937267E+04-8.49032208E-01 4 +HO2 L 5/89H 1O 2 00 00G 200.000 3500.000 1000.000 1 + 4.01721090E+00 2.23982013E-03-6.33658150E-07 1.14246370E-10-1.07908535E-14 2 + 1.11856713E+02 3.78510215E+00 4.30179801E+00-4.74912051E-03 2.11582891E-05 3 +-2.42763894E-08 9.29225124E-12 2.94808040E+02 3.71666245E+00 4 +H2O2 L 7/88H 2O 2 00 00G 200.000 3500.000 1000.000 1 + 4.16500285E+00 4.90831694E-03-1.90139225E-06 3.71185986E-10-2.87908305E-14 2 +-1.78617877E+04 2.91615662E+00 4.27611269E+00-5.42822417E-04 1.67335701E-05 3 +-2.15770813E-08 8.62454363E-12-1.77025821E+04 3.43505074E+00 4 +AR 120186AR 1 G 300.000 5000.000 1000.000 1 + 0.02500000E+02 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-0.07453750E+04 0.04366000E+02 0.02500000E+02 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-0.07453750E+04 0.04366000E+02 4 +END +REACTIONS +END diff --git a/data/inputs/mkxml b/data/inputs/mkxml new file mode 100755 index 000000000..554876439 --- /dev/null +++ b/data/inputs/mkxml @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +../../bin/ck2ctml -i gri30.inp -id gri30 -o gri30.xml -tr ../transport/gri30_tran.dat +../../bin/ck2ctml -i air.inp -o air.xml -t gri30.inp -id air -tr ../transport/gri30_tran.dat +../../bin/ck2ctml -i h2o2.inp -o h2o2.xml -id ohmech -tr ../transport/gri30_tran.dat +../../bin/ck2ctml -i silane.inp -o silane.xml -id silane +../../bin/ck2ctml -i argon.inp -o argon.xml -id argon -t gri30.inp -tr ../transport/gri30_tran.dat diff --git a/data/inputs/silane.inp b/data/inputs/silane.inp new file mode 100755 index 000000000..efe972bd8 --- /dev/null +++ b/data/inputs/silane.inp @@ -0,0 +1,108 @@ +ELEMENTS +SI H HE +END +SPECIES +H2 H HE SIH4 SI SIH SIH2 SIH3 +H3SISIH +SI2H6 H2SISIH2 +SI3H8 +SI2 SI3 +END +THERMO ALL + 300.000 1000.000 5000.000 +HE 120186HE 1 G 0300.00 5000.00 1000.00 1 + 0.02500000E+02 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-0.07453750E+04 0.09153489E+01 0.02500000E+02 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-0.07453750E+04 0.09153488E+01 4 +SIH 121986SI 1H 1 G 0300.00 2000.00 1000.00 1 + 0.03110430E+02 0.01094946E-01 0.02898629E-06-0.02745104E-08 0.07051799E-12 2 + 0.04516898E+06 0.04193487E+02 0.03836010E+02-0.02702657E-01 0.06849070E-04 3 +-0.05424184E-07 0.01472131E-10 0.04507593E+06 0.09350778E+01 4 +SIH2 42489SI 1H 2 G 0300.00 3000.00 1000.00 1 + 0.04142390E+02 0.02150191E-01-0.02190730E-05-0.02073725E-08 0.04741018E-12 2 + 0.03110484E+06 0.02930745E+01 0.03475092E+02 0.02139338E-01 0.07672306E-05 3 + 0.05217668E-08-0.09898824E-11 0.03147397E+06 0.04436585E+02 4 +SIH3 42489SI 1H 3 G 0300.00 3000.00 1000.00 1 + 0.05015906E+02 0.03732750E-01-0.03609053E-05-0.03729193E-08 0.08468490E-12 2 + 0.02190233E+06-0.04291368E+02 0.02946733E+02 0.06466764E-01 0.05991653E-05 3 +-0.02218413E-07 0.03052670E-11 0.02270173E+06 0.07347948E+02 4 +H3SISIH 111191H 4SI 2 G 0300.00 4000.00 1500.00 1 + 0.01127202E+03 0.02538145E-01-0.02998472E-05-0.09465367E-09 0.01855053E-12 2 + 0.03297169E+06-0.03264598E+03 0.03698707E+02 0.01870180E+00-0.01430704E-03 3 + 0.06005836E-07-0.01116293E-10 0.03590825E+06 0.08825191E+02 4 +H2SISIH2 42489SI 2H 4 G 0300.00 3000.00 1000.00 1 + 0.08986817E+02 0.05405047E-01-0.05214022E-05-0.05313742E-08 0.01188727E-11 2 + 0.02832748E+06-0.02004478E+03 0.05133186E+02 0.01252855E+00-0.04620421E-05 3 +-0.06606075E-07 0.02864345E-10 0.02956915E+06 0.07605133E+01 4 +SIH4 90784SI 1H 4 0 0G 300.000 2000.000 1 + 0.79359380E+00 0.17671899E-01-0.11398009E-04 0.35992604E-08-0.45241571E-12 2 + 0.31982127E+04 0.15242257E+02 0.14516404E+01 0.13987363E-01-0.42345639E-05 3 +-0.23606142E-08 0.13712089E-11 0.31134105E+04 0.12321855E+02 4 +SI2H6 90784SI 2H 6 0 0G 300.000 2000.000 1 + 0.34074936E+01 0.27206479E-01-0.17713204E-04 0.56391177E-08 -.71378682E-12 2 + 0.75321842E+04 0.61321754E+01 0.67347983E+00 0.40931531E-01 -.44841255E-04 3 + 0.29952232E-07-0.89010854E-11 0.79327875E+04 0.18627403E+02 4 +SI2 90784SI 2 0 0 0G 300.000 2000.000 1 + 0.41446779E+01 0.65234677E-03-0.50108520E-06 0.18062843E-09 -.25161111E-13 2 + 0.69694707E+05 0.38627366E+01 0.29671976E+01 0.63119558E-02 -.10970790E-04 3 + 0.89278680E-08-0.27873689E-11 0.69870738E+05 0.92789503E+01 4 +SI3H8 90784SI 3H 8 0 0G 300.000 2000.000 1 + 0.60933341E+01 0.36580112E-01-0.23892361E-04 0.76271932E-08 -.96769384E-12 2 + 0.11297205E+05-0.27475654E+01 0.77196846E+00 0.63442740E-01 -.76726109E-04 3 + 0.54543715E-07-0.16611729E-10 0.12071263E+05 0.21532507E+02 4 +SI J 3/67SI 1 0 0 0G 300.000 5000.000 1 + 0.26506014E+01-0.35763852E-03 0.29592293E-06-0.72804829E-10 0.57963329E-14 2 + 0.53437054E+05 0.52204057E+01 0.31793537E+01-0.27646992E-02 0.44784038E-05 3 +-0.32833177E-08 0.91213631E-12 0.53339032E+05 0.27273204E+01 4 +SI3 J 3/67SI 3 0 0 0G 300.000 5000.000 1 + 0.74213360E+01-0.11709948E-03 0.89820775E-07 0.71935964E-11-0.25670837E-14 2 + 0.74146699E+05-0.10365274E+02 0.45979129E+01 0.10715274E-01-0.16100422E-04 3 + 0.10969207E-07-0.27832875E-11 0.74766324E+05 0.34421671E+01 4 +H L 7/88H 1 00 00 00G 200.000 3500.000 1000.000 1 + 2.50000001E+00-2.30842973E-11 1.61561948E-14-4.73515235E-18 4.98197357E-22 2 + 2.54736599E+04-4.46682914E-01 2.50000000E+00 7.05332819E-13-1.99591964E-15 3 + 2.30081632E-18-9.27732332E-22 2.54736599E+04-4.46682853E-01 4 +H2 TPIS78H 2 00 00 00G 200.000 3500.000 1000.000 1 + 3.33727920E+00-4.94024731E-05 4.99456778E-07-1.79566394E-10 2.00255376E-14 2 +-9.50158922E+02-3.20502331E+00 2.34433112E+00 7.98052075E-03-1.94781510E-05 3 + 2.01572094E-08-7.37611761E-12-9.17935173E+02 6.83010238E-01 4 +END +REACTIONS +SIH4 + H = SIH3 + H2 7.8e14 0.0 2260. ! Roth +SIH4 + M = SIH3 + H + M 3.91e15 0.0 89356. ! 94TAK/MOM tst calc +SIH3 + H = SIH2 + H2 7.8e14 0.0 2260. ! assume same as SIH4 +SI + SI + M = SI2 + M 2.47e16 0.0 1178.0 ! 90MAR/RAF +SIH4 + SIH2 = H3SISIH + H2 1.3E13 0.0 0.0 ! R8 +SIH + H2 = SIH2 + H 4.8E14 0.0 23.64 ! R11 +SIH + SIH4 = H3SISIH + H 1.6E14 0.0 0.0 ! R12 +SI + H2 = SIH + H 1.5E15 0.0 31.8 ! R13 +! +SIH4(+M)=SIH2+H2(+M) 0.3119E+10 1.669 54710. ! R1 + LOW / 0.5214E30 -3.545 57550./ + TROE / -0.4984 888.3 209.4 2760./ + SIH4/4./ SI2H6/4./ ! HF(SiH2)=64.3, anh_inc.16b, beta(Ar,300) = 0.25 fit from 300 to 1200K + +H3SISIH(+M)=H2SISIH2(+M) 0.254E+14 -0.2239 5381.000 ! A6 + LOW / 0.1099E34 -5.765 9152. / + TROE / -0.4202 214.5 103. 136.3 / + SIH4/4./ SI2H6/4./ +! +! RRKM fits 3/18/93 by MEC +SI3H8(+M)=SIH4+H3SISIH(+M) 3.73E+12 0.992 50850.000 + LOW / 4.36E76 -17.26 59303. / + TROE / 0.4157 365.3 3102. 9.724 / + SIH4/4./ SI2H6/4./ +SI3H8(+M)=SIH2+SI2H6(+M) 6.97E+12 0.9691 52677.000 + LOW / 1.73E69 -15.07 60491. / + TROE / -3.47E-5 442.0 2412. 128.3 / + SIH4/4./ SI2H6/4./ +SI2H6(+M)=H2+H3SISIH(+M) 9.086E+9 1.834 54197.000 + LOW / 1.945E44 -7.772 59023. / + TROE / -0.1224 793.3 2400. 11.39 / + SIH4/4./ SI2H6/4./ + +SI2H6(+M)=SIH4+SIH2(+M) 1.81E+10 1.747 50203.000 ! A3 + LOW / 5.09E53 -10.37 56034. / + TROE / 4.375E-5 438.5 2726. 438.2 / + SIH4/4./ SI2H6/4./ +END diff --git a/data/inputs/silane.xml b/data/inputs/silane.xml new file mode 100644 index 000000000..a64f8192a --- /dev/null +++ b/data/inputs/silane.xml @@ -0,0 +1,480 @@ + + + + + + + 300 + 1 + H2:1.0 + + + Si H He + + H2 H HE SIH4 SI SIH SIH2 SIH3 H3SISIH SI2H6 + H2SISIH2 SI3H8 SI2 SI3 + + + + + + + + + + + + + TPIS78 + H:2 + + + + 2.344331120E+00, 7.980520750E-03, -1.947815100E-05, + 2.015720940E-08, -7.376117610E-12, -9.179351730E+02, + 6.830102380E-01 + + + 3.337279200E+00, -4.940247310E-05, 4.994567780E-07, + -1.795663940E-10, 2.002553760E-14, -9.501589220E+02, + -3.205023310E+00 + + + + + + + + L 7/88 + H:1 + + + + 2.500000000E+00, 7.053328190E-13, -1.995919640E-15, + 2.300816320E-18, -9.277323320E-22, 2.547365990E+04, + -4.466828530E-01 + + + 2.500000010E+00, -2.308429730E-11, 1.615619480E-14, + -4.735152350E-18, 4.981973570E-22, 2.547365990E+04, + -4.466829140E-01 + + + + + + + + 120186 + He:1 + + + + 2.500000000E+00, 0.000000000E+00, 0.000000000E+00, + 0.000000000E+00, 0.000000000E+00, -7.453750000E+02, + 9.153488000E-01 + + + 2.500000000E+00, 0.000000000E+00, 0.000000000E+00, + 0.000000000E+00, 0.000000000E+00, -7.453750000E+02, + 9.153489000E-01 + + + + + + + + 90784 + Si:1 H:4 + + + + 1.451640400E+00, 1.398736300E-02, -4.234563900E-06, + -2.360614200E-09, 1.371208900E-12, 3.113410500E+03, + 1.232185500E+01 + + + 7.935938000E-01, 1.767189900E-02, -1.139800900E-05, + 3.599260400E-09, -4.524157100E-13, 3.198212700E+03, + 1.524225700E+01 + + + + + + + + J 3/67 + Si:1 + + + + 3.179353700E+00, -2.764699200E-03, 4.478403800E-06, + -3.283317700E-09, 9.121363100E-13, 5.333903200E+04, + 2.727320400E+00 + + + 2.650601400E+00, -3.576385200E-04, 2.959229300E-07, + -7.280482900E-11, 5.796332900E-15, 5.343705400E+04, + 5.220405700E+00 + + + + + + + + 121986 + Si:1 H:1 + + + + 3.836010000E+00, -2.702657000E-03, 6.849070000E-06, + -5.424184000E-09, 1.472131000E-12, 4.507593000E+04, + 9.350778000E-01 + + + 3.110430000E+00, 1.094946000E-03, 2.898629000E-08, + -2.745104000E-10, 7.051799000E-14, 4.516898000E+04, + 4.193487000E+00 + + + + + + + + 42489 + Si:1 H:2 + + + + 3.475092000E+00, 2.139338000E-03, 7.672306000E-07, + 5.217668000E-10, -9.898824000E-13, 3.147397000E+04, + 4.436585000E+00 + + + 4.142390000E+00, 2.150191000E-03, -2.190730000E-07, + -2.073725000E-10, 4.741018000E-14, 3.110484000E+04, + 2.930745000E-01 + + + + + + + + 42489 + Si:1 H:3 + + + + 2.946733000E+00, 6.466764000E-03, 5.991653000E-07, + -2.218413000E-09, 3.052670000E-13, 2.270173000E+04, + 7.347948000E+00 + + + 5.015906000E+00, 3.732750000E-03, -3.609053000E-07, + -3.729193000E-10, 8.468490000E-14, 2.190233000E+04, + -4.291368000E+00 + + + + + + + + 111191 + H:4 Si:2 + + + + 3.698707000E+00, 1.870180000E-02, -1.430704000E-05, + 6.005836000E-09, -1.116293000E-12, 3.590825000E+04, + 8.825191000E+00 + + + 1.127202000E+01, 2.538145000E-03, -2.998472000E-07, + -9.465367000E-11, 1.855053000E-14, 3.297169000E+04, + -3.264598000E+01 + + + + + + + + 90784 + Si:2 H:6 + + + + 6.734798300E-01, 4.093153100E-02, -4.484125500E-05, + 2.995223200E-08, -8.901085400E-12, 7.932787500E+03, + 1.862740300E+01 + + + 3.407493600E+00, 2.720647900E-02, -1.771320400E-05, + 5.639117700E-09, -7.137868200E-13, 7.532184200E+03, + 6.132175400E+00 + + + + + + + + 42489 + Si:2 H:4 + + + + 5.133186000E+00, 1.252855000E-02, -4.620421000E-07, + -6.606075000E-09, 2.864345000E-12, 2.956915000E+04, + 7.605133000E-01 + + + 8.986817000E+00, 5.405047000E-03, -5.214022000E-07, + -5.313742000E-10, 1.188727000E-13, 2.832748000E+04, + -2.004478000E+01 + + + + + + + + 90784 + Si:3 H:8 + + + + 7.719684600E-01, 6.344274000E-02, -7.672610900E-05, + 5.454371500E-08, -1.661172900E-11, 1.207126300E+04, + 2.153250700E+01 + + + 6.093334100E+00, 3.658011200E-02, -2.389236100E-05, + 7.627193200E-09, -9.676938400E-13, 1.129720500E+04, + -2.747565400E+00 + + + + + + + + 90784 + Si:2 + + + + 2.967197600E+00, 6.311955800E-03, -1.097079000E-05, + 8.927868000E-09, -2.787368900E-12, 6.987073800E+04, + 9.278950300E+00 + + + 4.144677900E+00, 6.523467700E-04, -5.010852000E-07, + 1.806284300E-10, -2.516111100E-14, 6.969470700E+04, + 3.862736600E+00 + + + + + + + + J 3/67 + Si:3 + + + + 4.597912900E+00, 1.071527400E-02, -1.610042200E-05, + 1.096920700E-08, -2.783287500E-12, 7.476632400E+04, + 3.442167100E+00 + + + 7.421336000E+00, -1.170994800E-04, 8.982077500E-08, + 7.193596400E-12, -2.567083700E-15, 7.414669900E+04, + -1.036527400E+01 + + + + + + + + + + + + SIH4 + H [=] SIH3 + H2 + SIH4:1 H:1 + SIH3:1 H2:1 + + 7.8e+14 0 2260 + + + + + + SIH4 + M [=] SIH3 + H + M + SIH4:1 + SIH3:1 H:1 + + 3.91e+15 0 89356 + + + + + + SIH3 + H [=] SIH2 + H2 + SIH3:1 H:1 + SIH2:1 H2:1 + + 7.8e+14 0 2260 + + + + + + SI + SI + M [=] SI2 + M + SI:1 SI:1 + SI2:1 + + 2.47e+16 0 1178 + + + + + + SIH4 + SIH2 [=] H3SISIH + H2 + SIH4:1 SIH2:1 + H3SISIH:1 H2:1 + + 1.3e+13 0 0 + + + + + + SIH + H2 [=] SIH2 + H + SIH:1 H2:1 + SIH2:1 H:1 + + 4.8e+14 0 23.64 + + + + + + SIH + SIH4 [=] H3SISIH + H + SIH:1 SIH4:1 + H3SISIH:1 H:1 + + 1.6e+14 0 0 + + + + + + SI + H2 [=] SIH + H + SI:1 H2:1 + SIH:1 H:1 + + 1.5e+15 0 31.8 + + + + + + SIH4 (+ M) [=] SIH2 + H2 (+ M) + SIH4:1 + SIH2:1 H2:1 + + 3.119e+09 1.669 54710 + 5.214e+29 -3.545 57550 + -0.4984 888.3 209.4 2760 + + SI2H6:4 SIH4:4 + + + + + + + H3SISIH (+ M) [=] H2SISIH2 (+ M) + H3SISIH:1 + H2SISIH2:1 + + 2.54e+13 -0.2239 5381 + 1.099e+33 -5.765 9152 + -0.4202 214.5 103 136.3 + + SI2H6:4 SIH4:4 + + + + + + + SI3H8 (+ M) [=] SIH4 + H3SISIH (+ M) + SI3H8:1 + SIH4:1 H3SISIH:1 + + 3.73e+12 0.992 50850 + 4.36e+76 -17.26 59303 + 0.4157 365.3 3102 9.724 + + SI2H6:4 SIH4:4 + + + + + + + SI3H8 (+ M) [=] SIH2 + SI2H6 (+ M) + SI3H8:1 + SIH2:1 SI2H6:1 + + 6.97e+12 0.9691 52677 + 1.73e+69 -15.07 60491 + -3.47e-05 442 2412 128.3 + + SI2H6:4 SIH4:4 + + + + + + + SI2H6 (+ M) [=] H2 + H3SISIH (+ M) + SI2H6:1 + H2:1 H3SISIH:1 + + 9.086e+09 1.834 54197 + 1.945e+44 -7.772 59023 + -0.1224 793.3 2400 11.39 + + SI2H6:4 SIH4:4 + + + + + + + SI2H6 (+ M) [=] SIH4 + SIH2 (+ M) + SI2H6:1 + SIH4:1 SIH2:1 + + 1.81e+10 1.747 50203 + 5.09e+53 -10.37 56034 + 4.375e-05 438.5 2726 438.2 + + SI2H6:4 SIH4:4 + + + + + \ No newline at end of file diff --git a/data/thermo/nasathermo.dat b/data/thermo/nasathermo.dat new file mode 100755 index 000000000..d78b570aa --- /dev/null +++ b/data/thermo/nasathermo.dat @@ -0,0 +1,4561 @@ +THERMO NO_TMID + 300.0 1000.0 5000.0 +! +! This is the NASA thermodynamic database, which is available for download +! from http://www.galcit.caltech.edu/EDL/public/thermo.html. The original +! sources are +! +! S. Gordon and B.J. McBride, "Computer Program for Calculation of Complex +! Chemical Equilibrium Composition, Rocket Performance, Incident and +! Reflected Shocks and Chapman-Jouguet Detonations", NASA Report SP-273, 1971. +! +! B.J. McBride, S. Gordon, and M.A. Reno, "Coefficients for Calculating +! Thermodynamic and Transport Properties of Individual Species", NASA +! Report TM-4513, October 1993. +!----------------------------------------------------------------------------- +! +Electron gas L10/92E 1. 0. 0. 0.G 200.000 6000.0005.48579903-04 1 + 2.50000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-7.45375000E+02-1.17246902E+01 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-7.45375000E+02-1.17246902E+01 0.00000000E+00 4 +AL J 6/83AL 1. 0. 0. 0.G 200.000 6000.000 26.98154 1 + 2.53385701E+00-4.65859492E-05 2.82798048E-08-8.54362013E-12 1.02207983E-15 2 + 3.89045662E+04 5.37984173E+00 3.11112433E+00-3.59382310E-03 8.14749313E-06 3 +-8.08808966E-09 2.93132463E-12 3.88283390E+04 2.84045724E+00 3.96535695E+04 4 +AL+ J 6/83AL 1.E -1. 0. 0.G 298.150 6000.000 26.98099 1 + 2.51215337E+00-2.61011300E-05 1.90360463E-08-5.68881493E-12 6.00529995E-16 2 + 1.09023995E+05 3.72538261E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 1.09028141E+05 3.79100586E+00 1.09773516E+05 4 +AL- J 6/83AL 1.E 1. 0. 0.G 298.150 6000.000 26.98209 1 + 2.18963489E+00 8.03446211E-04-3.79389535E-07 6.90059853E-11-4.39884116E-15 2 + 3.30960260E+04 7.55557187E+00 2.64731898E+00-7.20371592E-04 1.02539612E-06 3 +-3.51118197E-11-2.38932974E-13 3.30049252E+04 5.30876665E+00 3.37710821E+04 4 +ALBO2 J 6/66AL 1.B 1.O 2. 0.G 300.000 5000.000 69.79134 1 + 7.17229950E+00 2.97807410E-03-1.24311070E-06 2.31887790E-10-1.60412080E-14 2 +-6.76836820E+04-9.98173976E+00 2.30872340E+00 1.88905390E-02-2.06333480E-05 3 + 1.02513240E-08-1.69412830E-12-6.64821670E+04 1.44770185E+01-6.51170313E+04 4 +ALBr J 9/79AL 1.BR 1. 0. 0.G 300.000 5000.000 106.88554 1 + 4.38224240E+00 2.12007070E-04-7.07644470E-08 1.06590180E-11 1.48302660E-16 2 + 5.76168490E+02 3.73910857E+00 3.49006110E+00 4.54767970E-03-8.19355780E-06 3 + 6.86661520E-09-2.17650580E-12 7.29453060E+02 7.88664757E+00 1.91229750E+03 4 +ALBr3 J 9/79AL 1.BR 3. 0. 0.G 300.000 5000.000 266.69354 1 + 9.61505900E+00 4.44685460E-04-1.99029830E-07 3.92518180E-11-2.84279750E-15 2 +-5.23495440E+04-1.31191090E+01 6.25372060E+00 1.60802170E-02-2.86597580E-05 3 + 2.36160760E-08-7.39313140E-12-5.17352110E+04 2.68365807E+00-4.93659766E+04 4 +ALC J 6/63AL 1.C 1. 0. 0.G 300.000 5000.000 38.99254 1 + 4.15644780E+00 4.46924900E-04-1.74670400E-07 3.43043360E-11-2.47727060E-15 2 + 8.16066050E+04 2.90472521E+00 2.64224830E+00 6.44651610E-03-9.58923760E-06 3 + 6.90408050E-09-1.94307790E-12 8.19298740E+04 1.02673620E+01 8.29321939E+04 4 +ALCL J 9/79AL 1.CL 1. 0. 0.G 300.000 5000.000 62.43424 1 + 4.33952710E+00 2.48388740E-04-8.29218520E-08 1.23423190E-11-2.37558180E-17 2 +-7.52810810E+03 2.53729424E+00 3.12222860E+00 5.92804740E-03-1.04158320E-05 3 + 8.55510650E-09-2.67223800E-12-7.30758390E+03 8.25335614E+00-6.18958661E+03 4 +ALCL+ J 6/76AL 1.CL 1.E -1. 0.G 300.000 5000.000 62.43369 1 + 4.62849650E+00-3.47505350E-04 2.29973510E-07-2.42797980E-11-2.64405440E-16 2 + 1.02204470E+05 1.43039989E+00 2.86983520E+00 6.65345860E-03-1.13277070E-05 3 + 9.07029740E-09-2.77946400E-12 1.02597410E+05 1.00199526E+01 1.03665310E+05 4 +ALCLF J 6/76AL 1.CL 1.F 1. 0.G 300.000 5000.000 81.43264 1 + 6.42626220E+00 6.78611680E-04-3.11863920E-07 6.21423790E-11-4.25195730E-15 2 +-6.09387690E+04-3.06227076E+00 3.21759680E+00 1.45245490E-02-2.39224880E-05 3 + 1.86216090E-08-5.59036670E-12-6.03055080E+04 1.22718185E+01-5.88778039E+04 4 +ALCLF+ J 6/76AL 1.CL 1.F 1.E -1.G 300.000 5000.000 81.43209 1 + 6.88359050E+00 7.05093660E-04-3.13660880E-07 6.16073100E-11-4.44905370E-15 2 + 3.10059900E+04-8.48211353E+00 3.73412920E+00 1.38890430E-02-2.22225390E-05 3 + 1.69376830E-08-5.00613420E-12 3.16477550E+04 6.66914747E+00 3.32131840E+04 4 +ALCLF2 J 6/76AL 1.CL 1.F 2. 0.G 300.000 5000.000 100.43105 1 + 8.86745440E+00 1.29333190E-03-5.74687960E-07 1.12784190E-10-8.13981540E-15 2 +-1.23092500E+05-1.56007846E+01 3.49052450E+00 2.34106220E-02-3.67308020E-05 3 + 2.75774850E-08-8.05708740E-12-1.21978570E+05 1.03598344E+01-1.20171161E+05 4 +ALCL2 J 6/76AL 1.CL 2. 0. 0.G 300.000 5000.000 97.88694 1 + 6.64141330E+00 4.33919070E-04-2.03424560E-07 4.09001350E-11-2.72093750E-15 2 +-3.57946890E+04-3.34843904E+00 3.93367410E+00 1.29289180E-02-2.27679920E-05 3 + 1.86055150E-08-5.79002790E-12-3.52966190E+04 9.40186676E+00-3.37162634E+04 4 +ALCL2+ J 6/76AL 1.CL 2.E -1. 0.G 300.000 5000.000 97.88639 1 + 7.09545770E+00 4.65254700E-04-2.07664790E-07 4.08799060E-11-2.95689140E-15 2 + 5.56437750E+04-8.51809862E+00 4.35611280E+00 1.26406120E-02-2.15540600E-05 3 + 1.72227530E-08-5.27444730E-12 5.61697360E+04 4.49304738E+00 5.78714632E+04 4 +ALCL2- J 6/76AL 1.CL 2.E 1. 0.G 300.000 5000.000 97.88749 1 + 6.71256180E+00 3.46568360E-04-1.58843540E-07 2.99500630E-11-1.65448150E-15 2 +-5.99542570E+04-4.13632915E+00 4.25109460E+00 1.19685620E-02-2.15382290E-05 3 + 1.78692300E-08-5.62207530E-12-5.95130610E+04 7.39326185E+00-5.78712622E+04 4 +ALCL2F J 6/76AL 1.CL 2.F 1. 0.G 300.000 5000.000 116.88534 1 + 9.14760670E+00 9.76691590E-04-4.34886760E-07 8.54640750E-11-6.17394740E-15 2 +-9.80602870E+04-1.53791197E+01 4.25516640E+00 2.20167890E-02-3.62769860E-05 3 + 2.82748420E-08-8.50110950E-12-9.70888870E+04 8.02488765E+00-9.51102737E+04 4 +ALCL3 J 9/79AL 1.CL 3. 0. 0.G 300.000 5000.000 133.33964 1 + 9.40410830E+00 6.86418720E-04-3.06638500E-07 6.03915090E-11-4.36935740E-15 2 +-7.32858130E+04-1.62963831E+01 4.91326650E+00 2.10318640E-02-3.65469310E-05 3 + 2.95868120E-08-9.14510050E-12-7.24410560E+04 4.94299604E+00-7.03101033E+04 4 +ALF J 9/79AL 1.F 1. 0. 0.G 300.000 5000.000 45.97994 1 + 4.12613950E+00 4.62680540E-04-1.74777330E-07 3.00154840E-11-1.53288410E-15 2 +-3.32759380E+04 2.06640743E+00 2.64729250E+00 6.08226860E-03-8.59634290E-06 3 + 5.89798370E-09-1.58867650E-12-3.29492600E+04 9.31391243E+00-3.19546746E+04 4 +ALF+ J 6/76AL 1.F 1.E -1. 0.G 300.000 5000.000 45.97939 1 + 3.35221860E+00 1.31038670E-03-1.43183830E-07-4.54423300E-11 7.34207490E-15 2 + 8.22325000E+04 7.08370839E+00 2.72530530E+00 4.81203130E-03-5.44117190E-06 3 + 2.74390840E-09-3.58751920E-13 8.22504680E+04 9.72336109E+00 8.32340781E+04 4 +ALF2 J 6/76AL 1.F 2. 0. 0.G 300.000 5000.000 64.97835 1 + 6.15793000E+00 9.81322870E-04-4.45350280E-07 8.82059600E-11-6.12622550E-15 2 +-8.55664790E+04-3.95119233E+00 2.74084650E+00 1.44667450E-02-2.15206190E-05 3 + 1.54119890E-08-4.32297970E-12-8.48345940E+04 1.26766818E+01-8.35361263E+04 4 +ALF2+ J 6/76AL 1.F 2.E -1. 0.G 300.000 5000.000 64.97780 1 + 6.59253940E+00 1.03194890E-03-4.57394400E-07 8.96205990E-11-6.46098250E-15 2 + 8.89919430E+03-9.45969765E+00 3.12391760E+00 1.45230560E-02-2.13154430E-05 3 + 1.51561330E-08-4.23740960E-12 9.65450720E+03 7.47417645E+00 1.10710379E+04 4 +ALF2- J 6/76AL 1.F 2.E 1. 0.G 300.000 5000.000 64.97889 1 + 6.26667450E+00 8.37111720E-04-3.68400210E-07 7.01504770E-11-4.68762980E-15 2 +-1.11252900E+05-5.02117966E+00 2.67153500E+00 1.56019440E-02-2.44193220E-05 3 + 1.82531690E-08-5.30647750E-12-1.10508600E+05 1.23382337E+01-1.09200801E+05 4 +ALF2O J 6/76AL 1.F 2.O 1. 0.G 300.000 5000.000 80.97775 1 + 8.82056220E+00 1.25486940E-03-5.45244650E-07 1.20368600E-10-9.64835990E-15 2 +-1.36306680E+05-1.60428722E+01 3.08740900E+00 2.38332390E-02-3.60629830E-05 3 + 2.62689190E-08-7.48567600E-12-1.35065400E+05 1.18936718E+01-1.33355812E+05 4 +ALF2O- J 6/76AL 1.F 2.O 1.E 1.G 300.000 5000.000 80.97829 1 + 8.61427860E+00 1.57845960E-03-7.00291150E-07 1.37292120E-10-9.90139850E-15 2 +-1.60403360E+05-1.58792508E+01 2.91975970E+00 2.40940130E-02-3.60809440E-05 3 + 2.60678480E-08-7.38083790E-12-1.59181520E+05 1.18310822E+01-1.57510833E+05 4 +ALF3 J 9/79AL 1.F 3. 0. 0.G 200.000 6000.000 83.97675 1 + 8.72897229E+00 1.31428559E-03-5.17599581E-07 8.86782789E-11-5.52837363E-15 2 +-1.48390330E+05-1.75036661E+01 3.10285412E+00 2.23455765E-02-3.14588690E-05 3 + 2.11582073E-08-5.53896073E-12-1.47126797E+05 1.01597069E+01-1.45447229E+05 4 +ALF4- J 6/76AL 1.F 4.E 1. 0.G 300.000 5000.000 102.97570 1 + 1.14714510E+01 1.75257860E-03-7.80642270E-07 1.53444740E-10-1.10863740E-14 2 +-2.43360360E+05-3.11980750E+01 2.58785930E+00 3.99304410E-02-6.57369140E-05 3 + 5.11630550E-08-1.53586950E-11-2.41596490E+05 1.13015770E+01-2.39537061E+05 4 +ALH J 6/63AL 1.H 1. 0. 0.G 300.000 5000.000 27.98948 1 + 3.33668980E+00 1.28778640E-03-4.98699410E-07 9.22946330E-11-6.34516940E-15 2 + 3.00917610E+04 3.09548823E+00 3.65768570E+00-1.97446980E-03 6.86633980E-06 3 +-6.20414040E-09 1.86631030E-12 3.01464580E+04 2.08851103E+00 3.11985222E+04 4 +ALI J 9/79AL 1.I 1. 0. 0.G 200.000 6000.000 153.88601 1 + 4.30067835E+00 3.94526798E-04-1.94717877E-07 4.31766594E-11-2.50995942E-15 2 + 6.87733839E+03 5.19554990E+00 3.37619386E+00 6.20358000E-03-1.33437988E-05 3 + 1.28978040E-08-4.59262508E-12 6.98468944E+03 9.20980277E+00 8.17245995E+03 4 +ALI3 J 9/79AL 1.I 3. 0. 0.G 300.000 5000.000 407.69495 1 + 9.70924960E+00 3.36646920E-04-1.50948540E-07 2.98131580E-11-2.16179940E-15 2 +-2.62339960E+04-1.06639943E+01 6.97612980E+00 1.32127780E-02-2.38290730E-05 3 + 1.97963930E-08-6.23362760E-12-2.57415850E+04 2.14766716E+00-2.32487352E+04 4 +ALN J12/79AL 1.N 1. 0. 0.G 300.000 5000.000 40.98828 1 + 4.14504680E+00 4.85609620E-04-2.01264090E-07 4.12594880E-11-2.88543080E-15 2 + 6.15832400E+04 3.58234298E+00 2.64486500E+00 6.54168760E-03-9.86253390E-06 3 + 7.18823230E-09-2.04448450E-12 6.18973820E+04 1.08478644E+01 6.29028113E+04 4 +ALO J12/79AL 1.O 1. 0. 0.G 300.000 5000.000 42.98094 1 + 3.31390640E+00 1.04524210E-03 2.74855330E-07-1.79286060E-10 1.99878130E-14 2 + 7.09433360E+03 7.20963423E+00 2.81161030E+00 3.95842610E-03-3.36953040E-06 3 + 6.73304970E-10 4.00894550E-13 7.06550370E+03 9.20895753E+00 8.05147516E+03 4 +ALO+ J12/79AL 1.O 1.E -1. 0.G 300.000 5000.000 42.98039 1 + 4.19084670E+00 6.93581980E-04-3.44599990E-07 7.61723270E-11-5.90324000E-15 2 + 1.18074390E+05 3.52951982E+00 2.94144340E+00 5.25921680E-03-7.34390730E-06 3 + 5.33167830E-09-1.57833360E-12 1.18374690E+05 9.73538252E+00 1.19430345E+05 4 +ALO- J12/79AL 1.O 1.E 1. 0.G 300.000 5000.000 42.98149 1 + 4.03805550E+00 5.58371100E-04-2.18886650E-07 3.85330240E-11-2.10955500E-15 2 +-3.37100890E+04 2.24480652E+00 2.72267540E+00 4.94755180E-03-5.75717540E-06 3 + 3.14244000E-09-6.41528320E-13-3.33912960E+04 8.83631372E+00-3.24045842E+04 4 +ALOCL J 9/64AL 1.O 1.CL 1. 0.G 300.000 5000.000 78.43364 1 + 6.78052000E+00 7.96628220E-04-3.42333550E-07 6.50226480E-11-4.55191970E-15 2 +-4.40808320E+04-9.30014039E+00 3.24444090E+00 1.41170050E-02-1.93220380E-05 3 + 1.19627980E-08-2.70691800E-12-4.33123430E+04 8.00537211E+00-4.18659024E+04 4 +ALOF J12/75AL 1.O 1.F 1. 0.G 300.000 5000.000 61.97934 1 + 6.45216220E+00 1.19265950E-03-5.28931370E-07 1.03678110E-10-7.47653670E-15 2 +-7.21163630E+04-9.01812781E+00 2.03914610E+00 1.89487620E-02-2.89787700E-05 3 + 2.13609410E-08-6.15798730E-12-7.11823330E+04 1.23865982E+01-6.99488680E+04 4 +ALOH J12/67AL 1.O 1.H 1. 0.G 300.000 5000.000 43.98888 1 + 3.68606740E+00 3.36368220E-03-1.24662440E-06 2.13822050E-10-1.38983190E-14 2 +-2.30461050E+04 3.69015559E+00 2.61322110E+00 2.77168940E-03 7.41578300E-06 3 +-1.13546020E-08 4.55695590E-12-2.25867970E+04 1.00753303E+01-2.16392416E+04 4 +ALOH+ J12/67AL 1.O 1.H 1.E -1.G 300.000 5000.000 43.98833 1 + 4.15019870E+00 2.89252120E-03-1.05654140E-06 1.79451670E-10-1.15870140E-14 2 + 6.38928880E+04 2.64013812E+00 1.96034390E+00 7.91911400E-03-2.28579590E-06 3 +-4.01037890E-09 2.57075960E-12 6.45101850E+04 1.41061776E+01 6.54197350E+04 4 +ALOH- J12/67AL 1.O 1.H 1.E 1.G 300.000 5000.000 43.98943 1 + 4.30107180E+00 2.16685030E-03-7.39886450E-07 1.18210550E-10-7.22088410E-15 2 +-2.91340950E+04 3.52700755E+00 2.91302040E+00 5.95307150E-03-3.05580540E-06 3 +-1.25987090E-09 1.28860940E-12-2.87818270E+04 1.06224669E+01-2.76775938E+04 4 +ALO2 J12/79AL 1.O 2. 0. 0.G 300.000 5000.000 58.98034 1 + 6.60646410E+00 1.08022520E-03-5.22293440E-07 1.13242200E-10-8.52909680E-15 2 +-1.25324320E+04-8.01717587E+00 3.25451480E+00 1.42758440E-02-2.11032480E-05 3 + 1.50562590E-08-4.21426140E-12-1.18125820E+04 8.30255493E+00-1.03664132E+04 4 +ALO2- J12/79AL 1.O 2.E 1. 0.G 300.000 5000.000 58.98089 1 + 6.36874820E+00 1.27920300E-03-5.65039910E-07 1.10463790E-10-7.95124420E-15 2 +-6.09720090E+04-8.79879504E+00 3.08120380E+00 1.30396540E-02-1.71199220E-05 3 + 1.09787000E-08-2.79421200E-12-6.02062030E+04 7.50156686E+00-5.88388468E+04 4 +ALO2H J12/68AL 1.O 2.H 1. 0.G 300.000 5000.000 59.98828 1 + 6.42643460E+00 3.22303620E-03-1.21393480E-06 2.10745000E-10-1.38280000E-14 2 +-5.76261540E+04-7.45759256E+00 2.48004560E+00 1.61492640E-02-1.60335240E-05 3 + 6.44661660E-09-4.09947690E-13-5.66827590E+04 1.23070710E+01-5.53546581E+04 4 +ALS J12/79AL 1.S 1. 0. 0.G 200.000 6000.000 59.04754 1 + 1.98171118E+00 3.97526437E-03-1.49428858E-06 2.26365870E-10-1.21036384E-14 2 + 2.82405754E+04 1.59882273E+01 2.71455183E+00 7.31180725E-03-1.26528925E-05 3 + 1.01796165E-08-2.87613387E-12 2.76434914E+04 1.05669599E+01 2.86847932E+04 4 +AL2 J 6/79AL 2. 0. 0. 0.G 300.000 5000.000 53.96308 1 + 5.81580620E+00-1.32505370E-03 6.07518860E-07-1.06924190E-10 7.06114090E-15 2 + 5.67890470E+04-4.95471063E+00 1.80944810E+00 1.59365020E-02-2.72502580E-05 3 + 1.98711200E-08-5.36840460E-12 5.75311340E+04 1.40720808E+01 5.85749290E+04 4 +AL2Br6 J 9/79AL 2.BR 6. 0. 0.G 300.000 5000.000 533.38708 1 + 2.12743310E+01 8.39396350E-04-3.75947780E-07 7.41701100E-11-5.37285510E-15 2 +-1.19293250E+05-5.61068200E+01 1.41859790E+01 3.44525060E-02-6.25224370E-05 3 + 5.21732380E-08-1.64827090E-11-1.18025250E+05-2.29291060E+01-1.12721454E+05 4 +AL2CL6 J 9/79AL 2.CL 6. 0. 0.G 300.000 5000.000 266.67928 1 + 2.07940030E+01 1.39142470E-03-6.22136710E-07 1.22593770E-10-8.87275850E-15 2 +-1.62404720E+05-6.24731881E+01 1.05091980E+01 4.90774360E-02-8.72087260E-05 3 + 7.17234320E-08-2.24243280E-11-1.60517840E+05-1.40840671E+01-1.55842516E+05 4 +AL2F6 J 9/79AL 2.F 6. 0. 0.G 300.000 5000.000 167.95350 1 + 1.88298460E+01 3.62022300E-03-1.60855520E-06 3.15662520E-10-2.27802870E-14 2 +-3.23151100E+05-6.32400790E+01 3.16181180E+00 6.88988900E-02-1.09658600E-04 3 + 8.32933420E-08-2.45610490E-11-3.19942480E+05 1.22125640E+01-3.16753265E+05 4 +AL2I6 J 9/79AL 2.I 6. 0. 0.G 300.000 5000.000 815.38990 1 + 2.15031910E+01 5.75941930E-04-2.58390280E-07 5.10459770E-11-3.70177380E-15 2 +-6.54491310E+04-5.11660663E+01 1.62254980E+01 2.59384390E-02-4.76423520E-05 3 + 4.00836850E-08-1.27371840E-11-6.45194970E+04-2.65404143E+01-5.88767000E+04 4 +AL2O J12/79AL 2.O 1. 0. 0.G 300.000 5000.000 69.96248 1 + 6.77206270E+00 8.25500920E-04-3.62910010E-07 6.95313000E-11-4.73452110E-15 2 +-1.96431970E+04-8.77233129E+00 4.07326560E+00 1.13076130E-02-1.65651620E-05 3 + 1.17842840E-08-3.30055030E-12-1.90542300E+04 4.40834831E+00-1.74618202E+04 4 +AL2O+ J12/79AL 2.O 1.E -1. 0.G 300.000 5000.000 69.96193 1 + 6.87978550E+00 7.07498770E-04-3.14192440E-07 6.16409830E-11-4.44786980E-15 2 + 7.62707560E+04-8.33181442E+00 4.10457360E+00 1.19783510E-02-1.85225890E-05 3 + 1.37566910E-08-3.98674230E-12 7.68527030E+04 5.10257248E+00 7.84705396E+04 4 +AL2O2 J12/79AL 2.O 2. 0. 0.G 300.000 5000.000 85.96188 1 + 9.15909760E+00 9.68539270E-04-4.32585130E-07 8.51788400E-11-6.16153700E-15 2 +-5.04280590E+04-1.91564680E+01 2.75964110E+00 2.99975990E-02-5.21904970E-05 3 + 4.22826860E-08-1.30753600E-11-4.92260320E+04 1.11007720E+01-4.74536598E+04 4 +AL2O2+ J12/79AL 2.O 2.E -1. 0.G 300.000 5000.000 85.96133 1 + 9.27516930E+00 8.35872230E-04-3.73616080E-07 7.36051680E-11-5.32627940E-15 2 + 6.52640680E+04-1.86772586E+01 3.34219040E+00 2.81112490E-02-4.95471780E-05 3 + 4.05097520E-08-1.26103100E-11 6.63625060E+04 9.29024167E+00 6.82447923E+04 4 +Ar L 6/88AR 1. 0. 0. 0.G 200.000 6000.000 39.94800 1 + 2.50000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-7.45375000E+02 4.37967491E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-7.45375000E+02 4.37967491E+00 0.00000000E+00 4 +Ar+ L10/92AR 1.E -1. 0. 0.G 298.150 6000.000 39.94745 1 + 2.86999547E+00-1.42547242E-04 9.36688776E-09 2.92580859E-12-3.58247941E-16 2 + 1.82702617E+05 3.53229980E+00 2.59316097E+00-1.32892944E-03 5.26503944E-06 3 +-5.97956691E-09 2.18967862E-12 1.82878368E+05 5.44980575E+00 1.83628186E+05 4 +B J 6/83B 1. 0. 0. 0.G 200.000 6000.000 10.81100 1 + 2.49860273E+00 1.40267322E-06 1.09458278E-09-1.20006414E-12 2.43121994E-16 2 + 6.66075914E+04 4.21887979E+00 2.51054099E+00-6.23801328E-05 1.42178099E-07 3 +-1.41697796E-10 5.15018749E-14 6.66053894E+04 4.16367209E+00 6.73521350E+04 4 +B+ J 6/83B 1.E -1. 0. 0.G 298.150 6000.000 10.81045 1 + 2.51207118E+00-2.60008491E-05 1.90411755E-08-5.71840071E-12 6.06893037E-16 2 + 1.63627851E+05 2.35392699E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 1.63631960E+05 2.41907708E+00 1.64377336E+05 4 +B- J 6/83B 1.E 1. 0. 0.G 298.150 6000.000 10.81155 1 + 2.50007592E+00-8.17294256E-08 3.29965783E-11-5.74649652E-15 3.62366056E-19 2 + 6.26417693E+04 4.61598593E+00 2.50120271E+00-5.73427208E-06 1.09670435E-08 3 +-9.50303533E-12 3.08935774E-15 6.26415806E+04 4.61078138E+00 6.33871389E+04 4 +BCL J12/64B 1.CL 1. 0. 0.G 300.000 5000.000 46.26370 1 + 4.10205710E+00 4.86591930E-04-1.88643260E-07 3.58333420E-11-2.50990690E-15 2 + 1.56879580E+04 1.95525119E+00 2.83644630E+00 4.43688120E-03-4.38875220E-06 3 + 1.51610780E-09 3.26461950E-14 1.60013610E+04 8.34533209E+00 1.70084902E+04 4 +BCL+ J 6/68B 1.CL 1.E -1. 0.G 300.000 5000.000 46.26315 1 + 4.10608880E+00 4.72741700E-04-1.79285840E-07 3.24161370E-11-2.05457580E-15 2 + 1.47130970E+05 2.64272945E+00 2.81241970E+00 4.60063920E-03-4.81199620E-06 3 + 1.96722160E-09-1.38378020E-13 1.47448490E+05 9.15668245E+00 1.48452806E+05 4 +BCLF J12/64B 1.CL 1.F 1. 0.G 300.000 5000.000 65.26210 1 + 5.70767570E+00 1.41002030E-03-6.01141370E-07 1.13670440E-10-7.93680630E-15 2 +-3.96933270E+04-1.53503838E+00 3.31202340E+00 7.41987630E-03-4.34859490E-06 3 +-1.13740570E-09 1.37638900E-12-3.90175480E+04 1.09483563E+01-3.77402953E+04 4 +BCL2 J 6/72B 1.CL 2. 0. 0.G 300.000 5000.000 81.71640 1 + 6.44598380E+00 5.79279480E-04-2.60497050E-07 6.35963580E-11-5.39822150E-15 2 +-1.16613040E+04-4.46086977E+00 3.29747860E+00 1.20825760E-02-1.61237550E-05 3 + 9.62658560E-09-2.05991990E-12-1.09565370E+04 1.10425333E+01-9.56076191E+03 4 +BCL2+ J12/70B 1.CL 2.E -1. 0.G 300.000 5000.000 81.71585 1 + 6.92666270E+00 6.77776330E-04-3.21014960E-07 6.83444220E-11-5.00735920E-15 2 + 7.88578220E+04-8.93462661E+00 4.27049310E+00 1.06037910E-02-1.42298380E-05 3 + 8.53728310E-09-1.83496710E-12 7.94360160E+04 4.07645069E+00 8.10708542E+04 4 +BCL2- J 6/72B 1.CL 2.E 1. 0.G 300.000 5000.000 81.71695 1 + 6.35182180E+00 7.70288480E-04-4.46998630E-07 1.38311780E-10-1.32219950E-14 2 +-1.97054320E+04-4.77472073E+00 3.23587910E+00 1.16902190E-02-1.47782590E-05 3 + 8.21815460E-09-1.56579130E-12-1.89818150E+04 1.06900104E+01-1.76125075E+04 4 +BCL3 J12/64B 1.CL 3. 0. 0.G 300.000 5000.000 117.16910 1 + 8.59853800E+00 1.55319230E-03-6.70006020E-07 1.27891120E-10-9.00000590E-15 2 +-5.13570710E+04-1.51584297E+01 3.73952650E+00 1.81058130E-02-2.13404610E-05 3 + 1.08283350E-08-1.73259670E-12-5.02146090E+04 9.05312747E+00-4.84628831E+04 4 +BF J12/64B 1.F 1. 0. 0.G 300.000 5000.000 29.80940 1 + 3.57718880E+00 1.01929080E-03-4.12515640E-07 7.71964380E-11-5.34987410E-15 2 +-1.51272640E+04 3.26612243E+00 3.46136090E+00-9.56854680E-04 6.01357440E-06 3 +-6.49780570E-09 2.23553490E-12-1.49698200E+04 4.46077963E+00-1.39390003E+04 4 +BF2 J 6/72B 1.F 2. 0. 0.G 300.000 5000.000 48.80781 1 + 5.44474570E+00 1.75332110E-03-7.84444740E-07 1.57198590E-10-1.13110710E-14 2 +-7.28603670E+04-2.27331920E+00 3.03093030E+00 7.24110210E-03-2.82509190E-06 3 +-2.89204130E-09 2.00461020E-12-7.21511020E+04 1.04457035E+01-7.09553140E+04 4 +BF2+ J12/70B 1.F 2.E -1. 0.G 300.000 5000.000 48.80726 1 + 5.81276380E+00 1.81934240E-03-7.71034570E-07 1.44897820E-10-9.98091560E-15 2 + 3.67948010E+04-7.00431192E+00 3.31464740E+00 8.64436540E-03-6.75253960E-06 3 + 1.33836650E-09 4.51149100E-13 3.74836490E+04 5.90468978E+00 3.87993258E+04 4 +BF2- J 6/72B 1.F 2.E 1. 0.G 300.000 5000.000 48.80835 1 + 5.31003480E+00 2.00204390E-03-9.72355100E-07 2.16414430E-10-1.66408810E-14 2 +-9.83369280E+04-2.32776078E+00 3.14245810E+00 6.41045790E-03-1.23864610E-06 3 +-4.12201000E-09 2.34723670E-12-9.76729640E+04 9.22523232E+00-9.64690963E+04 4 +BF3 J 6/69B 1.F 3.0 0. 0.G 300.000 5000.000 67.80621 1 + 7.02419850E+00 3.22215590E-03-1.37051540E-06 2.59196710E-10-1.81223100E-14 2 +-1.39180720E+05-1.11843009E+01 2.44682440E+00 1.52763120E-02-1.07846170E-05 3 + 6.89075020E-10 1.48931870E-12-1.37901350E+05 1.25678211E+01-1.36586061E+05 4 +BH J12/64B 1.H 1. 0. 0.G 300.000 5000.000 11.81894 1 + 2.89190790E+00 1.58329460E-03-5.82617290E-07 1.02420680E-10-6.76695690E-15 2 + 5.23287140E+04 3.79624329E+00 3.68622060E+00-1.30554350E-03 2.67421050E-06 3 +-9.10737380E-10-1.55911360E-13 5.21763300E+04-5.52454012E-02 5.32391023E+04 4 +BHF2 J12/65B 1.H 1.F 2. 0.G 300.000 5000.000 49.81575 1 + 5.31845270E+00 4.74444660E-03-1.93378580E-06 3.55083820E-10-2.42936670E-14 2 +-9.03750120E+04-3.04314031E+00 2.40536020E+00 9.27558440E-03 1.33864610E-06 3 +-8.68078950E-09 4.12110150E-12-8.93884090E+04 1.28880441E+01-8.82623625E+04 4 +BH2 J12/64B 1.H 2. 0. 0.G 300.000 5000.000 12.82688 1 + 3.36252850E+00 3.90128540E-03-1.50975510E-06 2.66728050E-10-1.77130530E-14 2 + 2.29190280E+04 1.25928259E+00 2.39582820E+00 7.47762600E-03-7.20195140E-06 3 + 4.58263980E-09-1.25106800E-12 2.31626500E+04 6.07647039E+00 2.41541598E+04 4 +BH3 J12/64B 1.H 3. 0. 0.G 300.000 5000.000 13.83482 1 + 2.06217260E+00 7.26558950E-03-2.75103370E-06 4.78037090E-10-3.13342850E-14 2 + 1.19237530E+04 8.84945083E+00 3.94870330E+00-5.21705430E-04 7.64811640E-06 3 +-4.61486940E-09 5.63186160E-13 1.16188090E+04-4.55174579E-02 1.28316429E+04 4 +BN J 6/66B 1.N 1. 0. 0.G 300.000 5000.000 24.81774 1 + 3.59818320E+00 8.71768050E-04-2.99726440E-07 5.60369440E-11-4.07504210E-15 2 + 5.61712410E+04 4.60022525E+00 3.53750650E+00-1.35565860E-03 6.22141890E-06 3 +-6.16832690E-09 1.98724610E-12 5.63297430E+04 5.56317675E+00 5.73679101E+04 4 +BO J 6/68B 1.O 1. 0. 0.G 300.000 5000.000 26.81040 1 + 3.15649560E+00 1.38165890E-03-5.50496300E-07 9.91166780E-11-6.41645460E-15 2 +-1.03034220E+03 6.03748954E+00 3.72972500E+00-2.08783240E-03 5.73628490E-06 3 +-4.38948280E-09 1.09166320E-12-1.06188590E+03 3.62554104E+00-1.45402311E-01 4 +BOCL J12/65B 1.O 1.CL 1. 0.G 300.000 5000.000 62.26310 1 + 5.71355660E+00 1.86646890E-03-7.74878980E-07 1.43985720E-10-9.93177450E-15 2 +-3.99773530E+04-4.88040355E+00 3.27053210E+00 1.02277500E-02-1.20701630E-05 3 + 7.20255620E-09-1.69147380E-12-3.93782080E+04 7.34930225E+00-3.80417115E+04 4 +BOF J12/65B 1.O 1.F 1. 0.G 200.000 6000.000 45.80880 1 + 5.39296603E+00 2.07444500E-03-7.93600586E-07 1.33476571E-10-8.21779331E-15 2 +-7.43113852E+04-4.76500535E+00 2.23703738E+00 1.33495496E-02-1.81530614E-05 3 + 1.36093676E-08-4.24382397E-12-7.35283735E+04 1.10069411E+01-7.24035451E+04 4 +BOF2 J12/66B 1.O 1.F 2. 0.G 300.000 5000.000 64.80721 1 + 7.30772330E+00 2.99036200E-03-1.30596170E-06 2.53082420E-10-1.76873330E-14 2 +-1.03345760E+05-1.11924160E+01 1.74459770E+00 1.86932770E-02-1.52461640E-05 3 + 2.65594700E-09 1.37986060E-12-1.01867580E+05 1.73531390E+01-1.00645369E+05 4 +BO2 J 6/68B 1.O 2. 0. 0.G 300.000 5000.000 42.80980 1 + 5.81984340E+00 1.86265740E-03-8.13027970E-07 1.57358210E-10-1.09442380E-14 2 +-3.62551170E+04-6.56090797E+00 3.12120480E+00 8.46808830E-03-4.59722780E-06 3 +-1.64200210E-09 1.66582330E-12-3.54833070E+04 7.54789163E+00-3.42194143E+04 4 +BO2- J12/68B 1.O 2.E 1. 0.G 300.000 5000.000 42.81035 1 + 4.88051690E+00 2.67436510E-03-1.09321940E-06 2.00808730E-10-1.37177690E-14 2 +-8.52843240E+04-3.00927640E+00 2.49163370E+00 9.74706440E-03-8.76408640E-06 3 + 3.58025440E-09-4.06112210E-13-8.46412180E+04 9.22689570E+00-8.35356575E+04 4 +BS J 6/72B 1.S 1. 0. 0.G 300.000 5000.000 42.87700 1 + 3.70685420E+00 9.86828950E-04-4.74952660E-07 1.06546010E-10-8.05196430E-15 2 + 2.80128160E+04 4.42462090E+00 3.17420460E+00 9.85449720E-04 2.77113190E-06 3 +-4.37518010E-09 1.76161790E-12 2.82306240E+04 7.53386240E+00 2.92374816E+04 4 +B2 J 3/79B 2. 0. 0. 0.G 200.000 6000.000 21.62200 1 + 5.23869155E+00-5.23607507E-04 1.69704978E-07-2.06549042E-11 9.41435925E-16 2 + 9.79873828E+04-6.00742217E+00 3.79099744E+00-5.87536359E-03 3.00514162E-05 3 +-3.91439173E-08 1.60419428E-11 9.87229998E+04 3.43463203E+00 9.97878648E+04 4 +B2O J 6/66B 2.O 1. 0. 0.G 300.000 5000.000 37.62140 1 + 4.73005380E+00 2.39414860E-03-1.00083240E-06 1.86975100E-10-1.29536720E-14 2 + 9.88533540E+03-6.35851289E-01 3.52947300E+00 3.19938260E-03 3.03292570E-06 3 +-5.74912550E-09 2.28473490E-12 1.03632010E+04 6.23963143E+00 1.15742290E+04 4 +B2O2 J12/64B 2.O 2. 0. 0.G 300.000 5000.000 53.62080 1 + 6.99385740E+00 3.59403930E-03-1.47536110E-06 2.72251240E-10-1.86959960E-14 2 +-5.72961780E+04-1.21677771E+01 3.68070780E+00 1.53611320E-02-1.86060970E-05 3 + 1.21714510E-08-3.24110180E-12-5.64866470E+04 4.35612734E+00-5.48483506E+04 4 +B2O3 J 6/71B 2.O 3. 0. 0.G 300.000 5000.000 69.62020 1 + 8.39941060E+00 4.74363380E-03-1.95523040E-06 3.61877490E-10-2.49072320E-14 2 +-1.03571580E+05-1.58100009E+01 3.66088370E+00 2.02620760E-02-2.19473380E-05 3 + 1.22530040E-08-2.70384020E-12-1.02365240E+05 8.10622068E+00-1.00544127E+05 4 +B3O3CL3 J 3/65B 3.O 3.CL 3. 0.G 300.000 5000.000 186.78930 1 + 1.92825640E+01 6.31725810E-03-2.72429260E-06 5.20479100E-10-3.66777900E-14 2 +-2.03208830E+05-6.78851521E+01 4.04449830E+00 5.42605970E-02-5.57507610E-05 3 + 2.22231280E-08-1.41812950E-12-1.99416320E+05 9.05672255E+00-1.96248045E+05 4 +B3O3F3 J 3/65B 3.O 3.F 3. 0.G 300.000 5000.000 137.42641 1 + 1.68586160E+01 8.86857540E-03-3.78810580E-06 7.18704010E-10-5.03769170E-14 2 +-2.90931040E+05-5.98587523E+01 3.07988610E+00 4.56365920E-02-3.30988260E-05 3 + 2.55388390E-09 4.43587610E-12-2.87122130E+05 1.14753917E+01-2.84460743E+05 4 +B3O3H3 J 3/65B 3.O 3.H 3. 0.G 200.000 6000.000 83.45502 1 + 1.21201212E+01 1.22811209E-02-4.60922487E-06 7.65824542E-10-4.67623793E-14 2 +-1.51648629E+05-3.98918007E+01 2.76989078E+00 2.53425900E-02 1.22486701E-05 3 +-3.73057611E-08 1.74556897E-11-1.48431026E+05 1.15218019E+01-1.46436050E+05 4 +Ba J12/70BA 1. 0. 0. 0.G 300.000 5000.000 137.32700 1 + 7.97305450E+00-1.11612150E-02 7.11721470E-06-1.53366730E-09 1.08767000E-13 2 + 1.88899660E+04-2.34876848E+01 2.50387770E+00-3.78039140E-05 1.29149660E-07 3 +-1.84004090E-10 9.29348290E-14 2.07925440E+04 6.21674222E+00 2.15382161E+04 4 +BaBr J12/74BA 1.BR 1. 0. 0.G 300.000 5000.000 217.23100 1 + 4.36897740E+00 3.90758870E-04-2.99017490E-07 1.06413010E-10-9.84160490E-15 2 +-1.46176850E+04 7.52526087E+00 4.17145530E+00 1.59608130E-03-2.88865420E-06 3 + 2.47671470E-09-7.98307000E-13-1.45944950E+04 8.38620677E+00-1.33008383E+04 4 +BaBr2 J12/74BA 1.BR 2. 0. 0.G 300.000 5000.000 297.13500 1 + 6.95023380E+00 5.80660230E-05-2.61954280E-08 5.19928280E-12-3.78527700E-16 2 +-5.31668420E+04 1.49002755E+00 6.34052750E+00 3.05619520E-03-5.72858640E-06 3 + 4.88759680E-09-1.56880810E-12-5.30623160E+04 4.31943715E+00-5.10777430E+04 4 +BaCL J12/72BA 1.CL 1. 0. 0.G 300.000 5000.000 172.77970 1 + 4.66752380E+00-2.21872510E-04 8.12706800E-08 3.02169620E-11-5.31833010E-15 2 +-1.85421420E+04 4.46444204E+00 3.97811480E+00 2.18032180E-03-3.43425650E-06 3 + 2.51822120E-09-6.90580270E-13-1.83669370E+04 7.92426104E+00-1.71096446E+04 4 +BaCL2 J12/72BA 1.CL 2. 0. 0.G 300.000 5000.000 208.23240 1 + 6.91386370E+00 9.82139630E-05-4.32683480E-08 8.39690060E-12-5.98920850E-16 2 +-6.20760510E+04-3.05863075E-01 6.05712380E+00 3.84261490E-03-6.26832050E-06 3 + 4.61966650E-09-1.27447680E-12-6.19145360E+04 3.76179166E+00-5.99846649E+04 4 +BaF J12/72BA 1.F 1. 0. 0.G 300.000 5000.000 156.32540 1 + 4.35871250E+00 3.01107380E-04-2.28633150E-07 8.98655540E-11-8.76575950E-15 2 +-4.01013760E+04 4.60148546E+00 3.35375060E+00 4.38195800E-03-6.64059290E-06 3 + 4.61432290E-09-1.19715180E-12-3.98929560E+04 9.45758926E+00-3.87483866E+04 4 +BaF+ J12/72BA 1.F 1.E -1. 0.G 300.000 5000.000 156.32485 1 + 6.49455650E+00-4.11300560E-03 2.58828080E-06-5.04586980E-10 3.07195600E-14 2 + 1.59606510E+04-7.88498449E+00 3.16174640E+00 4.88760790E-03-7.12198820E-06 3 + 4.71449710E-09-1.14589830E-12 1.69604640E+04 9.54623291E+00 1.80662310E+04 4 +BaF2 J12/72BA 1.F 2. 0. 0.G 300.000 5000.000 175.32381 1 + 6.79771590E+00 2.29321960E-04-1.00535210E-07 1.94285660E-11-1.38075070E-15 2 +-9.87631140E+04-2.69528324E+00 5.09682390E+00 7.42262500E-03-1.16828330E-05 3 + 8.32962180E-09-2.22168560E-12-9.84315950E+04 5.43692086E+00-9.66698696E+04 4 +BaOH J12/75BA 1.O 1.H 1. 0.G 300.000 5000.000 154.33434 1 + 5.51784680E+00 1.47809030E-03-5.78233070E-07 1.40402220E-10-1.20357650E-14 2 +-2.89590740E+04-1.49787288E+00 2.66818310E+00 1.68839760E-02-3.10317770E-05 3 + 2.64210480E-08-8.39535880E-12-2.85546680E+04 1.13434092E+01-2.72346238E+04 4 +BaOH+ J 6/76BA 1.O 1.H 1.E -1.G 300.000 5000.000 154.33379 1 + 5.51260190E+00 1.40138400E-03-4.23502160E-07 6.05783630E-11-3.35196530E-15 2 + 3.08713490E+04-2.10767300E+00 2.70904900E+00 1.67265250E-02-3.07679270E-05 3 + 2.62104480E-08-8.33038390E-12 3.12550790E+04 1.04707909E+01 3.25822547E+04 4 +BaO2H2 J12/75BA 1.O 2.H 2. 0.G 300.000 5000.000 171.34168 1 + 9.08247350E+00 2.73683110E-03-8.17536780E-07 1.15348840E-10-6.28337560E-15 2 +-7.81865860E+04-1.46886716E+01 3.79093560E+00 3.20754490E-02-5.93508060E-05 3 + 5.07763850E-08-1.61811310E-11-7.74835580E+04 8.94869323E+00-7.53592938E+04 4 +BaS J 9/77BA 1.S 1. 0. 0.G 300.000 5000.000 169.39300 1 + 4.44025870E+00 7.42693980E-04-1.17956810E-06 5.76186380E-10-6.75463240E-14 2 + 3.11598200E+03 4.28598436E+00 3.48161710E+00 4.56581350E-03-8.27264100E-06 3 + 6.93725940E-09-2.20002430E-12 3.36364880E+03 9.04422506E+00 4.54421146E+03 4 +Be J 9/83BE 1. 0. 0. 0.G 200.000 6000.000 9.01218 1 + 2.29438566E+00 4.11669841E-04-2.64730832E-07 6.25681388E-11-3.89281007E-15 2 + 3.82958055E+04 3.26731942E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 3.82226460E+04 2.14617316E+00 3.89680210E+04 4 +Be+ J 9/83BE 1.E -1. 0. 0.G 298.150 6000.000 9.01163 1 + 2.50168976E+00-5.10373647E-06 5.27481090E-09-2.16155049E-12 3.00713026E-16 2 + 1.45893277E+05 2.83066847E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 1.45893693E+05 2.83922927E+00 1.46639068E+05 4 +BeBO2 J 6/66BE 1.B 1.O 2. 0.G 300.000 5000.000 51.82198 1 + 6.91083760E+00 3.26686840E-03-1.36781200E-06 2.55762110E-10-1.77277410E-14 2 +-6.05057150E+04-9.16165805E+00 2.00691200E+00 1.80448240E-02-1.69175810E-05 3 + 6.08653730E-09-1.72762850E-13-5.92341970E+04 1.58055571E+01-5.79713193E+04 4 +BeBr J 6/75BE 1.BR 1. 0. 0.G 300.000 5000.000 88.91618 1 + 4.19438870E+00 3.99390230E-04-1.48388730E-07 2.67622720E-11-1.56261270E-15 2 + 1.31154640E+04 3.32294845E+00 2.65914570E+00 6.70272780E-03-1.04037110E-05 3 + 7.76551940E-09-2.25309180E-12 1.34330960E+04 1.07356520E+01 1.44462019E+04 4 +BeBr2 J 6/75BE 1.BR 2. 0. 0.G 300.000 5000.000 168.82018 1 + 6.83448720E+00 7.54292870E-04-3.33682060E-07 6.53023490E-11-4.70410960E-15 2 +-2.97571170E+04-6.47179187E+00 4.64222830E+00 9.00844510E-03-1.26985560E-05 3 + 8.75589850E-09-2.39231940E-12-2.92654350E+04 4.30011933E+00-2.75769745E+04 4 +BeCL J 9/66BE 1.CL 1. 0. 0.G 300.000 5000.000 44.46488 1 + 4.10528780E+00 4.74617010E-04-1.79965280E-07 3.25639030E-11-2.06528400E-15 2 + 5.97530600E+03 2.46451741E+00 2.83219870E+00 4.45667640E-03-4.44821610E-06 3 + 1.58525870E-09 4.52068940E-15 6.29062480E+03 8.89156051E+00 7.29696540E+03 4 +BeCL+ J 6/68BE 1.CL 1.E -1. 0.G 300.000 5000.000 44.46433 1 + 5.38275000E+00-1.84711980E-03 1.11236830E-06-1.69529940E-10 6.10070910E-15 2 + 1.15997170E+05-5.06224135E+00 2.89659840E+00 5.12674920E-03-6.44279110E-06 3 + 3.56326400E-09-6.59250880E-13 1.16714660E+05 7.83727045E+00 1.17755958E+05 4 +BeCLF J 6/65BE 1.CL 1.F 1. 0.G 300.000 5000.000 63.46329 1 + 6.44027910E+00 1.14636930E-03-4.85453600E-07 9.12878650E-11-6.34435490E-15 2 +-7.10597710E+04-7.72869969E+00 4.10243810E+00 8.50174900E-03-8.90939630E-06 3 + 4.00762320E-09-5.16275390E-13-7.04687360E+04 4.09916281E+00-6.89387557E+04 4 +BeCL2 J 6/65BE 1.CL 2. 0. 0.G 300.000 5000.000 79.91758 1 + 6.70431910E+00 8.71664680E-04-3.72550530E-07 7.05670060E-11-4.93353600E-15 2 +-4.54945580E+04-8.42201229E+00 4.49271250E+00 8.05355450E-03-8.83192390E-06 3 + 4.08970490E-09-5.34980920E-13-4.49528810E+04 2.69582141E+00-4.33256234E+04 4 +BeF J12/71BE 1.F 1. 0. 0.G 300.000 5000.000 28.01059 1 + 3.70952950E+00 8.93836000E-04-3.61130680E-07 6.76010920E-11-4.64208330E-15 2 +-2.16600520E+04 3.16419241E+00 3.27618620E+00 2.52337590E-04 4.09399440E-06 3 +-5.31281500E-09 1.99549000E-12-2.14459240E+04 5.86499651E+00-2.04313003E+04 4 +BeF2 J 6/70BE 1.F 2. 0. 0.G 300.000 5000.000 47.00899 1 + 6.04576310E+00 1.56293740E-03-6.61081970E-07 1.24475510E-10-8.67160630E-15 2 +-9.77791270E+04-7.91788261E+00 3.52342740E+00 9.38902840E-03-9.56362080E-06 3 + 4.29209890E-09-5.77511130E-13-9.71304610E+04 4.88397539E+00-9.57389228E+04 4 +BeH J 3/63BE 1.H 1. 0. 0.G 300.000 5000.000 10.02012 1 + 3.05702180E+00 1.49772230E-03-5.68729630E-07 1.02608170E-10-6.91669790E-15 2 + 3.76395130E+04 3.40027478E+00 3.73123050E+00-1.91435480E-03 4.89103250E-06 3 +-3.29258830E-09 6.66385620E-13 3.75655600E+04 3.88608523E-01 3.86299590E+04 4 +BeH+ J 9/66BE 1.H 1.E -1. 0.G 300.000 5000.000 10.01957 1 + 2.90159920E+00 1.67517610E-03-6.68055030E-07 1.25109510E-10-8.17414660E-15 2 + 1.38168120E+05 3.55562916E+00 3.70957120E+00-1.58520310E-03 3.62287690E-06 3 +-1.89332210E-09 1.71732640E-13 1.38028660E+05-2.82896408E-01 1.39092559E+05 4 +BeI J12/75BE 1.I 1. 0. 0.G 300.000 5000.000 135.91665 1 + 4.26004930E+00 3.43208190E-04-1.27594770E-07 2.41897090E-11-1.45701420E-15 2 + 1.91103520E+04 4.04766770E+00 2.78261220E+00 6.84103480E-03-1.13898960E-05 3 + 8.99241280E-09-2.72776860E-12 1.93961830E+04 1.10789367E+01 2.04457353E+04 4 +BeI2 J12/75BE 1.I 2. 0. 0.G 300.000 5000.000 262.82112 1 + 7.00112620E+00 5.68788720E-04-2.52537550E-07 4.95410540E-11-3.57472040E-15 2 +-9.90388590E+03-5.21025523E+00 4.93737860E+00 8.74047370E-03-1.31147240E-05 3 + 9.49284940E-09-2.69263360E-12-9.46160050E+03 4.82951137E+00-7.69941366E+03 4 +BeN J 6/63BE 1.N 1. 0. 0.G 300.000 5000.000 23.01892 1 + 3.78559370E+00 8.23865750E-04-3.27116020E-07 6.15518880E-11-4.28090410E-15 2 + 5.00661800E+04 3.10558526E+00 3.16842860E+00 1.02824830E-03 2.73760170E-06 3 +-4.34810990E-09 1.75344530E-12 5.03104510E+04 6.66252496E+00 5.13172421E+04 4 +BeO J12/74BE 1.O 1. 0. 0.G 200.000 6000.000 25.01158 1 + 5.66778473E+00-4.07847614E-03 3.41112608E-06-8.21052371E-10 6.13773279E-14 2 + 1.45899580E+04-8.08580700E+00 3.78974248E+00-3.24896226E-03 1.12988533E-05 3 +-1.18056315E-08 4.20675761E-12 1.53410696E+04 2.73905306E+00 1.64050557E+04 4 +BeOH J12/75BE 1.O 1.H 1. 0.G 300.000 5000.000 26.01952 1 + 4.61167200E+00 2.39720130E-03-8.54891620E-07 1.43090620E-10-9.11123990E-15 2 +-1.53618380E+04-1.98829207E+00 1.91391480E+00 1.35071590E-02-1.85316870E-05 3 + 1.29424710E-08-3.54389610E-12-1.48196830E+04 1.09928305E+01-1.37885210E+04 4 +BeOH+ J12/75BE 1.O 1.H 1.E -1.G 300.000 5000.000 26.01897 1 + 4.62235270E+00 2.39025710E-03-8.55494730E-07 1.44416710E-10-9.35602940E-15 2 + 8.98294360E+04-2.72614661E+00 1.92809820E+00 1.35342400E-02-1.86540260E-05 3 + 1.30739210E-08-3.59005760E-12 9.03683050E+04 1.02257270E+01 9.14040565E+04 4 +BeO2H2 J12/75BE 1.O 2.H 2. 0.G 300.000 5000.000 43.02686 1 + 7.85504780E+00 4.64775800E-03-1.65028340E-06 2.76706230E-10-1.78262980E-14 2 +-8.41062590E+04-1.84294660E+01 2.41843930E-01 3.99135680E-02-6.45882810E-05 3 + 5.10234760E-08-1.54792050E-11-8.27410450E+04 1.73136260E+01-8.13720155E+04 4 +BeS J 9/77BE 1.S 1. 0. 0.G 300.000 5000.000 41.07818 1 + 5.20407340E+00-3.87420220E-03 4.25788910E-06-1.25605990E-09 1.13434030E-13 2 + 3.02260840E+04-3.57801196E+00 2.90225380E+00 3.18974130E-03-1.36518250E-06 3 +-1.50927100E-09 1.22759290E-12 3.07107600E+04 7.87585064E+00 3.17033766E+04 4 +Be2O J 9/63BE 2.O 1. 0. 0.G 300.000 5000.000 34.02376 1 + 5.45497340E+00 2.19703850E-03-9.29195780E-07 1.74964100E-10-1.21899820E-14 2 +-9.49589850E+03-5.67042265E+00 2.75278970E+00 8.96486990E-03-5.58592470E-06 3 +-3.47691880E-10 1.10154720E-12-8.71747090E+03 8.45191895E+00-7.54778448E+03 4 +Be2OF2 J 6/66BE 2.O 1.F 2. 0.G 300.000 5000.000 72.02057 1 + 1.03113430E+01 2.92581510E-03-1.24819870E-06 2.36521690E-10-1.65591600E-14 2 +-1.48446230E+05-2.44876830E+01 4.86000260E+00 1.94389820E-02-1.88187600E-05 3 + 7.10095030E-09-3.72252580E-13-1.47039590E+05 3.24173341E+00-1.44878984E+05 4 +Be2O2 J 9/63BE 2.O 2. 0. 0.G 300.000 5000.000 50.02316 1 + 7.17836520E+00 3.07969260E-03-1.31622730E-06 2.49706140E-10-1.74963390E-14 2 +-5.19848760E+04-1.29255948E+01 1.71027390E+00 1.82449390E-02-1.43772530E-05 3 + 2.12688160E-09 1.46919930E-12-5.05123660E+04 1.52145102E+01-4.93136425E+04 4 +Be3O3 J 9/63BE 3.O 3. 0. 0.G 300.000 5000.000 75.03475 1 + 9.19073220E+00 7.36237010E-03-3.12927290E-06 5.91625890E-10-4.13601940E-14 2 +-1.30618490E+05-2.33168800E+01 2.00026920E+00 2.00051720E-02 5.75178470E-07 3 +-1.70928050E-08 8.48627850E-12-1.28268670E+05 1.56209530E+01-1.26807812E+05 4 +Be4O4 J 9/63BE 4.O 4. 0. 0.G 300.000 5000.000 100.04633 1 + 1.45470300E+01 8.19037300E-03-3.51627890E-06 6.69234570E-10-4.70059630E-14 2 +-1.97048450E+05-5.14967659E+01-1.38184380E+00 5.23848280E-02-4.08930180E-05 3 + 4.73797070E-09 4.99541640E-12-1.92783560E+05 3.04130661E+01-1.91216780E+05 4 +Br J 6/82BR 1. 0. 0. 0.G 200.000 6000.000 79.90400 1 + 2.08851053E+00 7.12118611E-04-2.70003073E-07 4.14986299E-11-2.31188294E-15 2 + 1.28568767E+04 9.07351144E+00 2.48571711E+00 1.50647525E-04-5.37267333E-07 3 + 7.20921065E-10-2.50205558E-13 1.27092168E+04 6.86030804E+00 1.34535890E+04 4 +Br2 TPIS89BR 2. 0. 0. 0.G 200.000 6000.000 159.80800 1 + 5.18728187E+00-1.38651104E-03 9.34745153E-07-2.07065391E-10 1.41808517E-14 2 + 2.10705678E+03 7.76223394E-02 3.34331004E+00 6.35230769E-03-1.36418815E-05 3 + 1.31726300E-08-4.68373476E-12 2.53515408E+03 9.07940353E+00 3.71759731E+03 4 +C L11/88C 1. 0. 0. 0.G 200.000 6000.000 12.01100 1 + 2.60558298E+00-1.95934335E-04 1.06737219E-07-1.64239390E-11 8.18705752E-16 2 + 8.54129443E+04 4.19238681E+00 2.55423955E+00-3.21537724E-04 7.33792245E-07 3 +-7.32234889E-10 2.66521446E-13 8.54438832E+04 4.53130848E+00 8.61963002E+04 4 +C+ L 7/88C 1.E -1. 0. 0.G 298.150 6000.000 12.01045 1 + 2.50853519E+00-1.08599270E-05 5.37069210E-09-1.18270596E-12 9.71267564E-17 2 + 2.16879493E+05 4.31739655E+00 2.61523966E+00-5.53783873E-04 1.06348636E-06 3 +-9.23756345E-10 3.00774568E-13 2.16862053E+05 3.82652944E+00 2.17624885E+05 4 +C- TPIS91C 1.E 1. 0. 0.G 298.150 6000.000 12.01155 1 + 2.50000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 6.99315654E+04 3.96340403E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 6.99315654E+04 3.96340403E+00 7.06769404E+04 4 +CCL J12/69C 1.CL 1. 0. 0.G 300.000 5000.000 47.46370 1 + 4.09847270E+00 5.00778450E-04-2.00128330E-07 3.86809920E-11-2.54411130E-15 2 + 5.90765990E+04 3.35017361E+00 3.19535570E+00 2.80763180E-03-1.60438450E-06 3 +-5.77440650E-10 6.14097320E-13 5.93250770E+04 8.03517321E+00 6.03875369E+04 4 +CCLF3 L12/77C 1.CL 1.F 3. 0.G 298.150 5000.000 104.45891 1 + 1.01650960E+01 2.84600420E-03-1.09260240E-06 1.83143740E-10-1.11940590E-14 2 +-8.88487500E+04-2.57041113E+01 2.90119360E+00 2.05636580E-02-8.55086360E-06 3 +-1.03956450E-08 7.57218250E-12-8.68295630E+04 1.21150667E+01-8.51452700E+04 4 +CCL2 J12/68C 1.CL 2. 0. 0.G 300.000 5000.000 82.91640 1 + 3.71849990E+00 5.34497450E-03-2.34312840E-06 4.18061770E-10-2.67652950E-14 2 + 2.75547930E+04 9.64597954E+00 2.85885050E+00 1.39579380E-02-2.00388980E-05 3 + 1.35007260E-08-3.16697150E-12 2.73639260E+04 1.22433131E+01 2.86848211E+04 4 +CCL2F2 L12/77C 1.CL 2.F 2. 0.G 298.150 5000.000 120.91321 1 + 1.07082480E+01 2.32321860E-03-9.00732230E-07 1.52617020E-10-9.44349580E-15 2 +-6.31026020E+04-2.66228765E+01 3.81349660E+00 2.00368350E-02-9.89866930E-06 3 +-8.79953530E-09 7.12185520E-12-6.12535510E+04 8.99097110E+00-5.93299490E+04 4 +CCL3 J 6/70C 1.CL 3. 0. 0.G 300.000 5000.000 118.36910 1 + 8.78154730E+00 1.35161300E-03-5.82494530E-07 1.10986970E-10-7.79372640E-15 2 + 6.63441510E+03-1.53161324E+01 3.71533570E+00 1.94437960E-02-2.46278410E-05 3 + 1.37864640E-08-2.66389340E-12 7.78200200E+03 9.71604259E+00 9.56234693E+03 4 +CCL3F L12/77C 1.CL 3.F 1. 0.G 298.150 5000.000 137.36750 1 + 1.12465300E+01 1.78376980E-03-6.92604430E-07 1.17407240E-10-7.26402920E-15 2 +-3.81083090E+04-2.82759858E+01 4.82876870E+00 1.89817400E-02-1.03606620E-05 3 +-7.84721270E-09 6.84527520E-12-3.64461840E+04 4.63413730E+00-3.42694620E+04 4 +CCL4 L12/81C 1.CL 4. 0. 0.G 298.150 5000.000 153.82180 1 + 1.17390960E+01 1.28375530E-03-4.96502590E-07 8.35250200E-11-5.11072240E-15 2 +-1.54190900E+04-3.07778187E+01 5.79662990E+00 1.79774390E-02-1.09565460E-05 3 +-6.66818070E-09 6.45548980E-12-1.39409650E+04-5.56959635E-01-1.15237980E+04 4 +CF J 6/70C 1.F 1. 0. 0.G 300.000 5000.000 31.00940 1 + 3.68696790E+00 9.11434910E-04-3.64638550E-07 6.74828540E-11-4.52695960E-15 2 + 2.94781250E+04 4.17451009E+00 3.46551430E+00-6.87798050E-04 5.67847660E-06 3 +-6.45829820E-09 2.29882480E-12 2.96555980E+04 5.88135489E+00 3.06967621E+04 4 +CF+ J12/70C 1.F 1.E -1. 0.G 298.150 6000.000 31.00885 1 + 3.67596084E+00 8.52823073E-04-3.06755661E-07 4.97430057E-11-2.83969038E-15 2 + 1.37018878E+05 2.84608813E+00 3.58285095E+00-1.86390930E-03 8.53435341E-06 3 +-9.32378062E-09 3.33941713E-12 1.37198248E+05 4.07439000E+00 1.38242181E+05 4 +CF2 J 6/70C 1.F 2. 0. 0.G 300.000 5000.000 50.00781 1 + 5.22671420E+00 2.08376800E-03-9.90372780E-07 2.12648480E-10-1.58311140E-14 2 +-2.37558470E+04-1.91090423E+00 2.76888210E+00 7.23729620E-03-1.60281520E-06 3 +-4.55123790E-09 2.66480110E-12-2.30157860E+04 1.11376958E+01-2.18904653E+04 4 +CF2+ J12/70C 1.F 2.E -1. 0.G 300.000 5000.000 50.00726 1 + 5.15542300E+00 2.05283100E-03-9.11739110E-07 1.82727610E-10-1.32136400E-14 2 + 1.11431220E+05-7.78766841E-01 2.97835220E+00 6.03366020E-03 6.58587850E-10 3 +-5.21294490E-09 2.66630210E-12 1.12126750E+05 1.09515563E+01 1.13273886E+05 4 +CF3 J 6/69C 1.F 3. 0. 0.G 300.000 5000.000 69.00621 1 + 7.20126220E+00 3.06639350E-03-1.31441810E-06 2.49969250E-10-1.75509280E-14 2 +-5.92386310E+04-1.09457100E+01 2.06501680E+00 1.64241580E-02-1.08381460E-05 3 +-8.53179970E-10 2.38780700E-12-5.78119760E+04 1.57046930E+01-5.65626016E+04 4 +CF3+ J12/71C 1.F 3.E -1. 0.G 300.000 5000.000 69.00566 1 + 7.02254060E+00 3.24412710E-03-1.38648750E-06 2.63236370E-10-1.84644020E-14 2 + 4.80223180E+04-1.12065339E+01 2.26055760E+00 1.54223230E-02-9.89566740E-06 3 +-7.83450460E-10 2.12118920E-12 4.93653380E+04 1.35784551E+01 5.06368231E+04 4 +CF4 L 6/83C 1.F 4. 0. 0.G 200.000 6000.000 88.00461 1 + 9.47215359E+00 3.59525216E-03-1.40378502E-06 2.39188188E-10-1.48558906E-14 2 +-1.15816337E+05-2.49709091E+01 1.05143992E+00 2.78246468E-02-2.46525260E-05 3 + 6.74548304E-09 9.18909316E-13-1.13574067E+05 1.81900899E+01-1.12227900E+05 4 +CH TPIS79C 1.H 1. 0. 0.G 200.000 6000.000 13.01894 1 + 2.52090627E+00 1.76537235E-03-4.61475705E-07 5.92885472E-11-3.34731962E-15 2 + 7.11314363E+04 7.40532163E+00 3.48981665E+00 3.23835541E-04-1.68899065E-06 3 + 3.16217327E-09-1.40609067E-12 7.07972934E+04 2.08401108E+00 7.18428386E+04 4 +CH+ TPIS91C 1.H 1.E -1. 0.G 298.150 6000.000 13.01839 1 + 4.53726693E+00-2.05165403E-03 1.69587170E-06-3.51097709E-10 2.22129197E-14 2 + 1.94661079E+05-5.02782224E+00 3.53796552E+00-7.59260194E-05-6.09566708E-07 3 + 2.00819522E-09-1.00806821E-12 1.95057229E+05 5.23237838E-01 1.96106806E+05 4 +CHCL TPIS79C 1.H 1.CL 1. 0.G 298.150 5000.000 48.47164 1 + 5.15660360E+00 4.58883250E-04 4.47490230E-07-1.36067870E-10 1.02424450E-14 2 + 3.53105770E+04-1.75116146E+00 2.96136110E+00 6.11519160E-03-4.52031800E-06 3 + 1.30933890E-09 7.15780860E-14 3.59599830E+04 9.74349584E+00 3.70773980E+04 4 +CHCLF2 L12/77C 1.H 1.CL 1.F 2.G 298.150 5000.000 86.46845 1 + 7.90298270E+00 4.62519000E-03-1.64898670E-06 2.59104290E-10-1.48362120E-14 2 +-6.12342660E+04-1.37342976E+01 2.46811200E+00 1.58839450E-02-2.82090150E-06 3 +-1.04781320E-08 6.07048960E-12-5.95708790E+04 1.51934234E+01-5.81725370E+04 4 +CHCL2F L12/77C 1.H 1.CL 2.F 1.G 298.150 5000.000 102.92274 1 + 8.50839230E+00 4.03457130E-03-1.42682260E-06 2.22473030E-10-1.26301730E-14 2 +-3.74279100E+04-1.54116621E+01 3.11071590E+00 1.62958910E-02-4.73311870E-06 3 +-9.47981600E-09 6.13237500E-12-3.58622110E+04 1.29638499E+01-3.42694620E+04 4 +CHCL3 X 6/81C 1.H 1.CL 3. 0.G 298.150 5000.000 119.37704 1 + 8.99380300E+00 3.56521920E-03-1.25376480E-06 1.94791310E-10-1.10320210E-14 2 +-1.56090000E+04-1.76316998E+01 3.68198010E+00 1.66110210E-02-6.61808010E-06 3 +-8.12915600E-09 5.94331350E-12-1.41418440E+04 9.98349958E+00-1.23792770E+04 4 +CHF3 L 6/81C 1.H 1.F 3. 0.G 298.150 5000.000 70.01415 1 + 7.38702490E+00 5.12669240E-03-1.83717750E-06 2.90046430E-10-1.66920890E-14 2 +-8.63674380E+04-1.36102612E+01 1.78570940E+00 1.59611290E-02-1.55750150E-06 3 +-1.13669110E-08 6.12752900E-12-8.45911250E+04 1.64575908E+01-8.33829360E+04 4 +CH2 L11/89C 1.H 2. 0. 0.G 200.000 6000.000 14.02688 1 + 2.77723166E+00 3.83663476E-03-1.34853220E-06 2.11641255E-10-1.23445662E-14 2 + 4.58590304E+04 6.67286429E+00 3.74484879E+00 1.17960823E-03 1.94502264E-06 3 +-2.52932506E-09 1.12447631E-12 4.55799523E+04 1.62850125E+00 4.67616252E+04 4 +CH2CLF L12/77C 1.H 2.CL 1.F 1.G 298.150 5000.000 68.47798 1 + 5.95727830E+00 6.08797000E-03-2.08137590E-06 3.13462150E-10-1.70848780E-14 2 +-3.42807810E+04-4.87988626E+00 2.09755330E+00 1.25518960E-02 2.71470360E-07 3 +-9.13198410E-09 4.47135730E-12-3.29736170E+04 1.61681723E+01-3.18036710E+04 4 +CH2CL2 L12/81C 1.H 2.CL 2. 0.G 298.150 5000.000 84.93228 1 + 6.49912830E+00 5.56723400E-03-1.88874490E-06 2.82333930E-10-1.52568690E-14 2 +-1.40488130E+04-7.01156159E+00 2.36261270E+00 1.38855320E-02-2.08721670E-06 3 +-8.66561580E-09 4.94943150E-12-1.27612300E+04 1.50849058E+01-1.14734760E+04 4 +CH2F2 L 6/81C 1.H 2.F 2. 0.G 298.150 5000.000 52.02369 1 + 5.29831120E+00 6.75680120E-03-2.34015530E-06 3.57223810E-10-1.97899860E-14 2 +-5.67992150E+04-3.52851131E+00 1.92640780E+00 1.05290970E-02 3.46599150E-06 3 +-9.68559990E-09 3.81653220E-12-5.55053950E+04 1.54769392E+01-5.44486890E+04 4 +CH3 L11/89C 1.H 3. 0. 0.G 200.000 6000.000 15.03482 1 + 2.96866033E+00 5.80717546E-03-1.97778534E-06 3.07278752E-10-1.78853897E-14 2 + 1.65388869E+04 4.77944503E+00 3.67359040E+00 2.01095175E-03 5.73021856E-06 3 +-6.87117425E-09 2.54385734E-12 1.64449988E+04 1.60456433E+00 1.76679083E+04 4 +CH3CL L12/81C 1.H 3.CL 1. 0.G 298.150 5000.000 50.48752 1 + 4.29529860E+00 7.28468220E-03-2.41611910E-06 3.52058380E-10-1.84061850E-14 2 +-1.17934650E+04 8.59296529E-01 2.06724450E+00 9.20915230E-03 3.04260540E-06 3 +-8.03420620E-09 3.21274430E-12-1.08968830E+04 1.35839517E+01-9.85813150E+03 4 +CH3F L 6/81C 1.H 3.F 1. 0.G 298.150 5000.000 34.03322 1 + 3.62565230E+00 7.96836990E-03-2.68453190E-06 3.98411080E-10-2.13486390E-14 2 +-3.03724800E+04 3.06990342E+00 2.26510240E+00 6.07338550E-03 6.98254100E-06 3 +-8.13809110E-09 2.10363410E-12-2.95776640E+04 1.18439594E+01-2.85841050E+04 4 +CH2OH L12/92C 1.H 3.O 1. 0.G 200.000 6000.000 31.03422 1 + 4.67625639E+00 6.56406014E-03-2.26525471E-06 3.55602481E-10-2.08626190E-14 2 +-2.89248574E+03 4.87737005E-01 3.86388918E+00 5.59672304E-03 5.93271791E-06 3 +-1.04532012E-08 4.36967278E-12-2.50501367E+03 5.47302243E+00-1.07041786E+03 4 +CH3O L10/92C 1.H 3.O 1. 0.G 200.000 6000.000 31.03422 1 + 4.26676538E+00 7.85380110E-03-2.83739943E-06 4.59039659E-10-2.74426084E-14 2 +-3.40073227E+02 3.85637447E-01 3.26524894E+00 3.30300117E-03 1.70493964E-05 3 +-2.27104476E-08 8.80756520E-12 3.33281488E+02 7.42568040E+00 1.56353171E+03 4 +CH4 L 8/88C 1.H 4. 0. 0.G 200.000 6000.000 16.04276 1 + 1.63552643E+00 1.00842795E-02-3.36916254E-06 5.34958667E-10-3.15518833E-14 2 +-1.00056455E+04 9.99313326E+00 5.14987613E+00-1.36709788E-02 4.91800599E-05 3 +-4.84743026E-08 1.66693956E-11-1.02466476E+04-4.64130376E+00-8.97226656E+03 4 +CH3OH L 8/88C 1.H 4.O 1. 0.G 200.000 6000.000 32.04216 1 + 3.60134486E+00 1.02430954E-02-3.59985517E-06 5.72505986E-10-3.39117640E-14 2 +-2.59971910E+04 4.70512253E+00 5.71539582E+00-1.52309129E-02 6.52441155E-05 3 +-7.10806889E-08 2.61352698E-11-2.56427656E+04-1.50409823E+00-2.41673893E+04 4 +CN TPIS91C 1.N 1. 0. 0.G 200.000 6000.000 26.01774 1 + 3.74818333E+00 3.91753271E-05 2.99702996E-07-6.92704532E-11 4.46137691E-15 2 + 5.17278419E+04 2.77469044E+00 3.61293502E+00-9.55513275E-04 2.14429765E-06 3 +-3.15163270E-10-4.64303546E-13 5.19007958E+04 3.98049947E+00 5.29536254E+04 4 +CN+ TPIS91C 1.N 1.E -1. 0.G 298.150 6000.000 26.01719 1 + 7.29006713E+00-2.46331139E-03 9.03599308E-07-1.35970586E-10 7.33709859E-15 2 + 2.13579081E+05-1.91340386E+01 6.92808505E+00-2.81492178E-02 7.58511376E-05 3 +-7.24174336E-08 2.33891503E-11 2.15195507E+05-1.01730500E+01 2.16548044E+05 4 +CN- L10/92C 1.N 1.E 1. 0.G 298.150 6000.000 26.01829 1 + 3.09051928E+00 1.33181759E-03-4.84902266E-07 7.96865228E-11-4.82770916E-15 2 + 6.88195665E+03 5.63128343E+00 3.81962846E+00-2.48247316E-03 6.04567838E-06 3 +-4.52733194E-09 1.15679167E-12 6.80256336E+03 2.38904403E+00 7.87605980E+03 4 +CNN L12/89C 1.N 2. 0. 0.G 200.000 6000.000 40.02448 1 + 4.86658084E+00 2.38499612E-03-8.52577832E-07 1.38423853E-10-8.18423116E-15 2 + 7.45586920E+04-6.77587146E-01 2.78240849E+00 1.25533110E-02-2.13082026E-05 3 + 1.90941637E-08-6.59244187E-12 7.49551651E+04 9.10634736E+00 7.61890601E+04 4 +CO TPIS79C 1.O 1. 0. 0.G 200.000 6000.000 28.01040 1 + 3.04848583E+00 1.35172818E-03-4.85794075E-07 7.88536486E-11-4.69807489E-15 2 +-1.42661171E+04 6.01709790E+00 3.57953347E+00-6.10353680E-04 1.01681433E-06 3 + 9.07005884E-10-9.04424499E-13-1.43440860E+04 3.50840928E+00-1.32936276E+04 4 +CO+ TPIS91C 1.O 1.E -1. 0.G 298.150 6000.000 28.00985 1 + 2.93059407E+00 1.56031391E-03-6.16238969E-07 1.09956019E-10-6.66111307E-15 2 + 1.49144692E+05 7.33837928E+00 3.77057107E+00-2.01770820E-03 4.61076194E-06 3 +-2.99171866E-09 6.06057760E-13 1.49004267E+05 3.38125724E+00 1.50073892E+05 4 +COCL J12/65C 1.O 1.CL 1. 0.G 300.000 5000.000 63.46310 1 + 5.42912360E+00 1.61215350E-03-6.60062800E-07 1.21271140E-10-8.28586010E-15 2 +-9.33050070E+03 3.82874056E-01 4.28637920E+00 5.08689800E-03-5.07294110E-06 3 + 2.96479830E-09-7.70934530E-13-9.01252120E+03 6.25118670E+00-7.54776465E+03 4 +COCLF J 6/61C 1.O 1.CL 1.F 1.G 300.000 5000.000 82.46150 1 + 7.08810810E+00 3.18164790E-03-1.37633160E-06 2.65440050E-10-1.89289690E-14 2 +-5.38837810E+04-8.68499355E+00 1.70666610E+00 2.27225650E-02-3.01156390E-05 3 + 2.04835660E-08-5.65722280E-12-5.26199020E+04 1.79876257E+01-5.13293738E+04 4 +COCL2 TPIS91C 1.O 1.CL 2. 0.G 200.000 6000.000 98.91580 1 + 7.86018378E+00 2.13271500E-03-8.22077158E-07 1.38951133E-10-8.58406653E-15 2 +-2.91056423E+04-1.19011907E+01 1.70787910E+00 2.89369464E-02-4.93289116E-05 3 + 4.16910139E-08-1.37057391E-11-2.78350932E+04 1.76202114E+01-2.63996315E+04 4 +COF J12/65C 1.O 1.F 1. 0.G 300.000 5000.000 47.00880 1 + 4.89082140E+00 2.21797030E-03-9.25507250E-07 1.72701200E-10-1.19553430E-14 2 +-2.23579840E+04 9.92784061E-01 3.20197270E+00 5.58377700E-03-1.49054810E-06 3 +-2.31260690E-09 1.36143530E-12-2.18170430E+04 1.00607392E+01-2.06312897E+04 4 +COF2 TPIS91C 1.O 1.F 2. 0.G 200.000 6000.000 66.00721 1 + 6.81631730E+00 3.16473282E-03-1.21776269E-06 2.05582261E-10-1.26893125E-14 2 +-7.95482716E+04-9.52864574E+00 2.12979489E+00 1.41019723E-02-5.94381359E-06 3 +-5.30544790E-09 3.97367469E-12-7.81745339E+04 1.51109092E+01-7.69738686E+04 4 +COS J 3/61C 1.O 1.S 1. 0.G 300.000 5000.000 60.07640 1 + 5.23920000E+00 2.41005840E-03-9.60645220E-07 1.77783470E-10-1.22357040E-14 2 +-1.84804550E+04-3.07773889E+00 2.46253210E+00 1.19479920E-02-1.37943700E-05 3 + 8.07077360E-09-1.83276530E-12-1.78039870E+04 1.08058688E+01-1.66455205E+04 4 +CO2 L 7/88C 1.O 2. 0. 0.G 200.000 6000.000 44.00980 1 + 4.63659493E+00 2.74131991E-03-9.95828531E-07 1.60373011E-10-9.16103468E-15 2 +-4.90249341E+04-1.93534855E+00 2.35677352E+00 8.98459677E-03-7.12356269E-06 3 + 2.45919022E-09-1.43699548E-13-4.83719697E+04 9.90105222E+00-4.73281047E+04 4 +CO2+ L10/92C 1.O 2.E -1. 0.G 298.150 6000.000 44.00925 1 + 5.61292513E+00 1.89829994E-03-7.34596383E-07 1.23975665E-10-7.57692288E-15 2 + 1.11621136E+05-5.65135698E+00 3.39305653E+00 5.82300415E-03 4.38012075E-08 3 +-4.68236271E-09 2.31552825E-12 1.12356151E+05 6.39038553E+00 1.13618832E+05 4 +COOH TPIS91C 1.O 2.H 1. 0.G 200.000 6000.000 45.01774 1 + 5.39206247E+00 4.11221305E-03-1.48194817E-06 2.39875278E-10-1.43902965E-14 2 +-2.76708786E+04-2.23528631E+00 2.92207915E+00 7.62453820E-03 3.29884683E-06 3 +-1.07135249E-08 5.11587309E-12-2.68383588E+04 1.12925989E+01-2.56178656E+04 4 +CP L 9/93C 1.P 1. 0. 0.G 200.000 6000.000 42.98476 1 + 4.16986061E+00-3.33893154E-04 6.30510095E-07-1.65248916E-10 1.25248542E-14 2 + 6.12121016E+04 2.05762288E+00 3.70291400E+00-2.94026330E-03 1.25263783E-05 3 +-1.45948287E-08 5.61955320E-12 6.15029332E+04 5.34971467E+00 6.25607522E+04 4 +CS J12/76C 1.S 1. 0. 0.G 300.000 5000.000 44.07700 1 + 3.68260120E+00 9.04732030E-04-3.64363740E-07 6.38542940E-11-3.69339820E-15 2 + 3.24974900E+04 3.89841679E+00 3.40393440E+00-6.57733080E-04 6.17121570E-06 3 +-7.36896040E-09 2.73467380E-12 3.26893930E+04 5.91106729E+00 3.37162928E+04 4 +CS2 J12/76C 1.S 2. 0. 0.G 300.000 5000.000 76.14300 1 + 5.92526100E+00 1.82529960E-03-7.55853800E-07 1.46050730E-10-1.04385950E-14 2 + 1.20480710E+04-6.05893229E+00 2.83260130E+00 1.32907910E-02-1.81446940E-05 3 + 1.28316810E-08-3.68006090E-12 1.27667820E+04 9.22219411E+00 1.40653694E+04 4 +C2 TPIS91C 2. 0. 0. 0.G 200.000 6000.000 24.02200 1 + 4.12487314E+00 1.08346618E-04 1.57250890E-07-4.24042102E-11 3.25055714E-15 2 + 9.89228066E+04 7.97421015E-01-1.96258641E+00 5.76815310E-02-1.58037735E-04 3 + 1.72460636E-07-6.57905286E-11 9.89883317E+04 2.33198418E+01 9.98804500E+04 4 +C2+ TPIS91C 2.E -1. 0. 0.G 298.150 6000.000 24.02145 1 + 1.47436235E+00 3.90858415E-03-1.15362712E-06 1.28522790E-10-4.37160939E-15 2 + 2.40801585E+05 1.56570956E+01 3.74438466E+00-2.75060804E-03 9.41697986E-06 3 +-9.54472049E-09 3.48743458E-12 2.40057573E+05 3.70168864E+00 2.41117688E+05 4 +C2- TPIS91C 2.E 1. 0. 0.G 298.150 6000.000 24.02255 1 + 1.94147766E+00 3.34554328E-03-1.21401317E-06 1.86836326E-10-1.03447699E-14 2 + 5.72696669E+04 1.20032530E+01 3.82038230E+00-2.88162408E-03 8.21923044E-06 3 +-7.32254863E-09 2.41405929E-12 5.67523968E+04 2.43181238E+00 5.78226498E+04 4 +C2CL2 J12/68C 2.CL 2. 0. 0.G 300.000 5000.000 94.92740 1 + 8.17285470E+00 2.36598920E-03-9.65525050E-07 1.77361480E-10-1.21352030E-14 2 + 2.25101900E+04-1.49035905E+01 5.02294820E+00 1.40826670E-02-1.80956690E-05 3 + 1.16103480E-08-2.88174780E-12 2.32274820E+04 6.09995206E-01 2.52127141E+04 4 +C2CL4 L10/87C 2.CL 4. 0. 0.G 298.150 5000.000 165.83280 1 + 1.29359370E+01 3.43092000E-03-1.50671940E-06 2.93469930E-10-2.10708960E-14 2 +-5.89323370E+03-3.46807029E+01 4.14347920E+00 3.74223720E-02-5.43697930E-05 3 + 3.91128630E-08-1.11763840E-11-3.94926290E+03 8.34455934E+00-1.45891290E+03 4 +C2CL6 L10/87C 2.CL 6. 0. 0.G 298.150 5000.000 236.73820 1 + 1.90342860E+01 3.39568210E-03-1.51152890E-06 2.97003150E-10-2.14538270E-14 2 +-2.31038030E+04-6.28529284E+01 4.63835310E+00 6.33655610E-02-1.00800300E-04 3 + 7.66369220E-08-2.26465500E-11-2.01565130E+04 6.47479559E+00-1.67069940E+04 4 +C2F2 J12/67C 2.F 2. 0. 0.G 300.000 5000.000 62.01881 1 + 7.51645810E+00 3.16864620E-03-1.33113850E-06 2.49600490E-10-1.73420720E-14 2 +-1.61076550E+02-1.50680622E+01 3.53458370E+00 1.44458450E-02-1.21896920E-05 3 + 3.60429850E-09 1.91189510E-13 9.21335620E+02 5.41946511E+00 2.51676233E+03 4 +C2F4 J 6/69C 2.F 4. 0. 0.G 300.000 5000.000 100.01561 1 + 1.10864680E+01 5.27884290E-03-2.23544000E-06 4.21668460E-10-2.94339140E-14 2 +-8.32928840E+04-2.98668810E+01 3.61661830E+00 2.64886180E-02-2.24332660E-05 3 + 6.22864450E-09 6.21492440E-13-8.12772420E+04 8.52376407E+00-7.92072049E+04 4 +C2H L 1/91C 2.H 1. 0. 0.G 200.000 6000.000 25.02994 1 + 3.36118395E+00 4.38989724E-03-1.62772218E-06 2.60556663E-10-1.52939305E-14 2 + 6.70492214E+04 5.57127542E+00 2.88965733E+00 1.34099611E-02-2.84769501E-05 3 + 2.94791045E-08-1.09331511E-11 6.68393932E+04 6.22296438E+00 6.80984775E+04 4 +C2HCL TPIS91C 2.H 1.CL 1. 0.G 298.150 5000.000 60.48264 1 + 6.32104570E+00 3.84597370E-03-1.48646060E-06 2.65613790E-10-1.79524660E-14 2 + 2.34404780E+04-8.28465086E+00 1.80471580E+00 2.58378710E-02-4.31499540E-05 3 + 3.58835790E-08-1.14479920E-11 2.42302070E+04 1.27377546E+01 2.56009760E+04 4 +C2HF J12/67C 2.H 1.F 1. 0.G 300.000 5000.000 44.02834 1 + 6.09495010E+00 3.94324280E-03-1.47114380E-06 2.52946410E-10-1.64466630E-14 2 + 1.29769070E+04-8.31534293E+00 2.69017700E+00 1.76808530E-02-2.27498550E-05 3 + 1.49205680E-08-3.73819250E-12 1.36832230E+04 8.14697187E+00 1.50978852E+04 4 +CHCO,ketyl L 6/89C 2.H 1.O 1. 0.G 200.000 6000.000 41.02934 1 + 4.26038110E+00 4.82740500E-03-1.66618844E-06 2.61405204E-10-1.53257963E-14 2 + 1.78804760E+04 3.97874320E+00 2.76593971E+00 1.41741202E-02-2.32600986E-05 3 + 2.15728089E-08-7.58509308E-12 1.80856324E+04 1.05408591E+01 1.93738416E+04 4 +C2H2,acetylene L 1/91C 2.H 2. 0. 0.G 200.000 6000.000 26.03788 1 + 4.65878504E+00 4.88396547E-03-1.60828775E-06 2.46974226E-10-1.38605680E-14 2 + 2.57594044E+04-3.99834772E+00 8.08681094E-01 2.33615629E-02-3.55171815E-05 3 + 2.80152437E-08-8.50072974E-12 2.64289807E+04 1.39397051E+01 2.74459950E+04 4 +C2H2,vinylidene L12/89C 2.H 2. 0. 0.G 200.000 6000.000 26.03788 1 + 4.27807139E+00 4.75622883E-03-1.63007513E-06 2.54622981E-10-1.48860326E-14 2 + 4.83166722E+04 6.40022600E-01 3.28154933E+00 6.97642740E-03-2.38528283E-06 3 +-1.21077045E-09 9.82038579E-13 4.86217943E+04 5.92039169E+00 4.98872655E+04 4 +CH2CO,ketene L 5/90C 2.H 2.O 1. 0.G 200.000 6000.000 42.03728 1 + 5.75793307E+00 6.34911413E-03-2.25814835E-06 3.62026733E-10-2.15651204E-14 2 +-7.97878384E+03-6.10772150E+00 2.13583630E+00 1.81188721E-02-1.73947474E-05 3 + 9.34397568E-09-2.01457615E-12-7.04291804E+03 1.22156480E+01-5.73695864E+03 4 +C2H3,vinyl L 2/92C 2.H 3. 0. 0.G 200.000 6000.000 27.04582 1 + 4.35105055E+00 7.49330091E-03-2.64314586E-06 4.21285906E-10-2.49896119E-14 2 + 3.41546181E+04 5.71676529E-01 3.21246645E+00 1.51479162E-03 2.59209412E-05 3 +-3.57657847E-08 1.47150873E-11 3.48598468E+04 8.51054025E+00 3.60502484E+04 4 +CH3CN L12/92C 2.H 3.N 1. 0.G 200.000 6000.000 41.05256 1 + 5.08576974E+00 9.70797040E-03-3.48484946E-06 5.62106760E-10-3.36234670E-14 2 + 5.45853074E+03-3.26553903E+00 3.82484221E+00 4.10100359E-03 2.14545679E-05 3 +-2.87234543E-08 1.11804146E-11 6.28838522E+03 5.54024211E+00 7.74910368E+03 4 +CH3CO,acetyl BUR 84C 2.H 3.O 1. 0.G 300.000 5000.000 43.04522 1 + 5.61227890E+00 8.44988600E-03-2.85414720E-06 4.23837630E-10-2.26840370E-14 2 +-5.18786330E+03-3.26178193E+00 3.12527850E+00 9.77822020E-03 4.52144830E-06 3 +-9.00946160E-09 3.19371790E-12-4.10850780E+03 1.12420212E+01-2.71844485E+03 4 +C2H4 L 1/91C 2.H 4. 0. 0.G 200.000 6000.000 28.05376 1 + 3.99182761E+00 1.04833910E-02-3.71721385E-06 5.94628514E-10-3.53630526E-14 2 + 4.26865819E+03-2.69052151E-01 3.95920148E+00-7.57052247E-03 5.70990292E-05 3 +-6.91588753E-08 2.69884373E-11 5.08977593E+03 4.09733096E+00 6.31426266E+03 4 +C2H4O,ethylen o L 8/88C 2.H 4.O 1. 0.G 200.000 6000.000 44.05316 1 + 5.48888429E+00 1.20460231E-02-4.33361545E-06 7.00269000E-10-4.19481870E-14 2 +-9.18047576E+03-7.08063868E+00 3.75904931E+00-9.44119292E-03 8.03096770E-05 3 +-1.00807756E-07 4.00398357E-11-7.56081402E+03 7.84977030E+00-6.33046566E+03 4 +CH3CHO,ethanal L 8/88C 2.H 4.O 1. 0.G 200.000 6000.000 44.05316 1 + 5.40417899E+00 1.17229675E-02-4.22626830E-06 6.83715733E-10-4.09842676E-14 2 +-2.25931508E+04-3.48117593E+00 4.72947627E+00-3.19343161E-03 4.75353505E-05 3 +-5.74590474E-08 2.19312619E-11-2.15728799E+04 4.10295455E+00-1.99879488E+04 4 +CH3COOH L 8/88C 2.H 4.O 2. 0.G 200.000 6000.000 60.05256 1 + 7.67083678E+00 1.35152695E-02-5.25874688E-06 8.93185062E-10-5.53180891E-14 2 +-5.57560971E+04-1.54676590E+01 2.78936844E+00 1.00001016E-02 3.42557978E-05 3 +-5.09017919E-08 2.06217504E-11-5.34752292E+04 1.41059504E+01-5.19873137E+04 4 +(HCOOH)2 BUR 92C 2.H 4.O 4. 0.G 300.000 5000.000 92.05136 1 + 1.22073710E+01 1.36888510E-02-4.68403690E-06 7.05116630E-10-3.83692850E-14 2 +-1.03959380E+05-3.57098054E+01 3.76923850E+00 2.72247160E-02 1.72380530E-06 3 +-2.07767240E-08 9.93799490E-12-1.01049880E+05 1.05054966E+01-9.87373140E+04 4 +C2H5 L12/92C 2.H 5. 0. 0.G 200.000 6000.000 29.06170 1 + 4.28800535E+00 1.24337374E-02-4.41383829E-06 7.06526943E-10-4.20341856E-14 2 + 1.20564200E+04 8.45299623E-01 4.30646568E+00-4.18658892E-03 4.97142807E-05 3 +-5.99126606E-08 2.30509004E-11 1.28416265E+04 4.70720924E+00 1.42712246E+04 4 +C2H6 L 8/88C 2.H 6. 0. 0.G 200.000 6000.000 30.06964 1 + 4.04666674E+00 1.53538766E-02-5.47039321E-06 8.77826228E-10-5.23167305E-14 2 +-1.24473512E+04-9.68683607E-01 4.29142492E+00-5.50154270E-03 5.99438288E-05 3 +-7.08466285E-08 2.68685771E-11-1.15222055E+04 2.66682316E+00-1.00849652E+04 4 +CH3N2CH3 L 8/88C 2.H 6.N 2. 0.G 200.000 6000.000 58.08312 1 + 7.44954851E+00 1.74406153E-02-6.27382453E-06 1.01351178E-09-6.06937494E-14 2 + 1.41979978E+04-1.41567638E+01 6.29613632E+00-2.25815427E-03 6.21232803E-05 3 +-7.46292997E-08 2.80371947E-11 1.56928850E+04-2.49925915E+00 1.78843203E+04 4 +CH3OCH3 L12/92C 2.H 6.O 1. 0.G 200.000 6000.000 46.06904 1 + 5.64844183E+00 1.63381899E-02-5.86802367E-06 9.46836869E-10-5.66504738E-14 2 +-2.51074690E+04-5.96264939E+00 5.30562279E+00-2.14254272E-03 5.30873244E-05 3 +-6.23147136E-08 2.30731036E-11-2.39866295E+04 7.13264209E-01-2.21432171E+04 4 +C2H5OH L 8/88C 2.H 6.O 1. 0.G 200.000 6000.000 46.06904 1 + 6.56289770E+00 1.52034264E-02-5.38922247E-06 8.62150224E-10-5.12824683E-14 2 +-3.15257984E+04-9.47557644E+00 4.85868178E+00-3.74006740E-03 6.95550267E-05 3 +-8.86541147E-08 3.51684430E-11-2.99961309E+04 4.80192294E+00-2.82578288E+04 4 +CCN L12/92C 2.N 1. 0. 0.G 200.000 6000.000 38.02874 1 + 5.53594940E+00 1.93336181E-03-7.43007993E-07 1.25654167E-10-7.70420035E-15 2 + 9.49028065E+04-3.70380637E+00 3.67600724E+00 7.88842348E-03-9.55326639E-06 3 + 7.31344088E-09-2.48035202E-12 9.54195535E+04 5.81651950E+00 9.67950500E+04 4 +CNC TPIS91C 2.N 1. 0. 0.G 200.000 6000.000 38.02874 1 + 5.93259696E+00 1.57914754E-03-6.12333532E-07 1.03869610E-10-6.43161897E-15 2 + 8.03326833E+04-6.60207157E+00 3.98958871E+00 5.21977832E-03-5.81083706E-07 3 +-3.39416520E-09 1.76273084E-12 8.09656357E+04 3.88721926E+00 8.23761254E+04 4 +C2N2 TPIS79C 2.N 2. 0. 0.G 200.000 6000.000 52.03548 1 + 6.70544769E+00 3.64260339E-03-1.30934250E-06 2.16411061E-10-1.31187410E-14 2 + 3.48608005E+04-1.04803695E+01 2.32925325E+00 2.61537847E-02-4.90003994E-05 3 + 4.61917478E-08-1.64323855E-11 3.56684424E+04 9.86336227E+00 3.71759731E+04 4 +C2O L12/89C 2.O 1. 0. 0.G 200.000 6000.000 40.02140 1 + 5.51576444E+00 1.87745704E-03-7.01159757E-07 1.21505291E-10-7.76778855E-15 2 + 3.30970458E+04-4.27636138E+00 2.86345422E+00 1.19732969E-02-1.81232501E-05 3 + 1.53813634E-08-5.28906524E-12 3.37500945E+04 8.89405881E+00 3.50037906E+04 4 +C3 TPIS79C 3. 0. 0. 0.G 200.000 6000.000 36.03300 1 + 4.80357768E+00 2.14511233E-03-1.07292074E-06 2.60735259E-10-2.01631960E-14 2 + 9.93965416E+04 3.89369308E-01 5.43283963E+00-4.46754383E-03 1.49321482E-05 3 +-1.47953138E-08 5.01421112E-12 9.94957222E+04-1.58720715E+00 1.01022009E+05 4 +C3H3,propargyl BUR 92C 3.H 3. 0. 0.G 200.000 6000.000 39.05682 1 + 6.64175821E+00 8.08587428E-03-2.84787887E-06 4.53525977E-10-2.68879815E-14 2 + 3.89793699E+04-1.04004255E+01 1.82840766E+00 2.37839036E-02-2.19228176E-05 3 + 1.00067444E-08-1.38984644E-12 4.01863058E+04 1.38447957E+01 4.16139977E+04 4 +C3H4,allene L12/92C 3.H 4. 0. 0.G 200.000 6000.000 40.06476 1 + 6.31694869E+00 1.11336262E-02-3.96289018E-06 6.35633775E-10-3.78749885E-14 2 + 2.01174617E+04-1.09718862E+01 2.61307487E+00 1.21223371E-02 1.85405400E-05 3 +-3.45258475E-08 1.53353389E-11 2.15415642E+04 1.02503319E+01 2.29622672E+04 4 +C3H4,propyne L12/92C 3.H 4. 0. 0.G 200.000 6000.000 40.06476 1 + 6.02531092E+00 1.13364427E-02-4.02229048E-06 6.43751365E-10-3.82990082E-14 2 + 1.95101792E+04-8.58912592E+00 2.68040760E+00 1.57994429E-02 2.50775737E-06 3 +-1.36584584E-08 6.61576607E-12 2.06916392E+04 9.89251047E+00 2.21913258E+04 4 +C3H4,cyclo- L 5/90C 3.H 4. 0. 0.G 200.000 6000.000 40.06476 1 + 6.28078730E+00 1.12393819E-02-4.01957526E-06 6.46920648E-10-3.86433248E-14 2 + 3.03415086E+04-1.11419945E+01 2.24666553E+00 5.76238084E-03 4.42080305E-05 3 +-6.62906786E-08 2.81824730E-11 3.21284389E+04 1.33451837E+01 3.33272797E+04 4 +C3H5,allyl BUR 92C 3.H 5. 0. 0.G 200.000 6000.000 41.07270 1 + 6.54761132E+00 1.33152246E-02-4.78333100E-06 7.71949814E-10-4.61930808E-14 2 + 1.72714707E+04-9.27486841E+00 3.78794693E+00 9.48414335E-03 2.42343368E-05 3 +-3.65604010E-08 1.48592356E-11 1.86261218E+04 7.82822499E+00 2.03259122E+04 4 +C3H6,propylene L 7/90C 3.H 6. 0. 0.G 200.000 6000.000 42.08064 1 + 6.03870499E+00 1.62963895E-02-5.82130624E-06 9.35936483E-10-5.58602903E-14 2 +-7.76595092E+02-8.43824322E+00 3.83464524E+00 3.29078405E-03 5.05228184E-05 3 +-6.66251418E-08 2.63707585E-11 7.53838295E+02 7.53410995E+00 2.37055461E+03 4 +C3H6,cyclo- L 1/93C 3.H 6. 0. 0.G 200.000 6000.000 42.08064 1 + 6.21663293E+00 1.65393614E-02-5.90075961E-06 9.48095473E-10-5.65661737E-14 2 + 2.95937555E+03-1.36040607E+01 2.83278555E+00-5.21027462E-03 9.29582837E-05 3 +-1.22753146E-07 4.99191154E-11 5.19520057E+03 1.08306700E+01 6.41047999E+03 4 +C3H6O L 6/90C 3.H 6.O 1. 0.G 200.000 6000.000 58.08004 1 + 7.94555710E+00 1.74061678E-02-6.25436463E-06 1.00975457E-09-6.04488953E-14 2 +-1.52867683E+04-1.84184133E+01 3.56851051E+00 5.02717292E-03 6.42315607E-05 3 +-8.90229548E-08 3.62423766E-11-1.29679205E+04 9.88838229E+00-1.12718609E+04 4 +C3H7,n-propyl L 6/90C 3.H 7. 0. 0.G 200.000 6000.000 43.08858 1 + 6.96468462E+00 1.75451946E-02-6.23370055E-06 9.98529735E-10-5.94394793E-14 2 + 8.54244358E+03-1.14831478E+01 4.03239996E+00 3.42728312E-03 6.14344420E-05 3 +-8.37646338E-08 3.40857776E-11 1.03393839E+04 8.77428079E+00 1.20873028E+04 4 +C3H7,i-propyl L 9/85C 3.H 7. 0. 0.G 200.000 6000.000 43.08858 1 + 5.75125882E+00 1.87605762E-02-6.70191976E-06 1.07751871E-09-6.43090885E-14 2 + 7.97977293E+03-4.91359355E+00 5.40872872E+00-8.55221825E-03 8.42178491E-05 3 +-1.00942683E-07 3.86914479E-11 9.42600956E+03 3.62322504E+00 1.12213468E+04 4 +C3H8 L 6/90C 3.H 8. 0. 0.G 200.000 6000.000 44.09652 1 + 6.66789363E+00 2.06120214E-02-7.36553027E-06 1.18440761E-09-7.06953210E-14 2 +-1.62748521E+04-1.31859503E+01 4.21102620E+00 1.71599803E-03 7.06183472E-05 3 +-9.19594116E-08 3.64421372E-11-1.43812106E+04 5.60930491E+00-1.25900384E+04 4 +C3H8O,1propanol L 9/88C 3.H 8.O 1. 0.G 200.000 6000.000 60.09592 1 + 8.71010929E+00 2.08051473E-02-7.38480898E-06 1.18188977E-09-7.03597783E-14 2 +-3.51244024E+04-1.88965453E+01 5.27799420E+00 8.08660546E-04 8.21548179E-05 3 +-1.08488185E-07 4.34886897E-11-3.28348774E+04 5.70526835E+00-3.06933301E+04 4 +C3H8O,2propanol L 9/88C 3.H 8.O 1. 0.G 200.000 6000.000 60.09592 1 + 9.64271113E+00 2.00224413E-02-7.11948364E-06 1.14136355E-09-6.79921667E-14 2 +-3.74840095E+04-2.56346074E+01 4.30803027E+00 1.02498010E-02 6.19857805E-05 3 +-9.03311088E-08 3.74065372E-11-3.49248843E+04 7.55826254E+00-3.27980843E+04 4 +C3O2 L 7/88C 3.O 2. 0. 0.G 200.000 6000.000 68.03180 1 + 8.46175920E+00 4.81552825E-03-1.80930759E-06 3.00787080E-10-1.83722162E-14 2 +-1.43271654E+04-1.70605688E+01 2.19668211E+00 3.14553138E-02-5.07458623E-05 3 + 4.35794398E-08-1.47351787E-11-1.29460980E+04 1.32985264E+01-1.12622391E+04 4 +C4 L 7/88C 4. 0. 0. 0.G 200.000 6000.000 48.04400 1 + 5.63091494E+00 4.83116397E-03-1.50405642E-06 2.02872357E-10-1.00345687E-14 2 + 1.22500879E+05-2.98954731E+00 3.32273482E+00 2.02596453E-02-3.73466071E-05 3 + 3.56878255E-08-1.27727382E-11 1.22723638E+05 6.80994829E+00 1.24349329E+05 4 +C4H2 L 2/93C 4.H 2. 0. 0.G 200.000 6000.000 50.05988 1 + 8.66704895E+00 6.71505191E-03-2.35355060E-06 3.73635366E-10-2.21054043E-14 2 + 5.10016978E+04-2.18002050E+01-4.07132393E-01 5.20775143E-02-9.21138340E-05 3 + 8.08657403E-08-2.70422080E-11 5.25957367E+04 2.03240223E+01 5.41222513E+04 4 +C4H4,1,3-cyclo- L 5/90C 4.H 4. 0. 0.G 200.000 6000.000 52.07576 1 + 8.04207751E+00 1.25202174E-02-4.52337047E-06 7.33120443E-10-4.40110864E-14 2 + 4.25108494E+04-2.11284483E+01 1.27895318E+00 1.34203350E-02 4.11992063E-05 3 +-6.98956727E-08 3.07252120E-11 4.50864097E+04 1.76787788E+01 4.63045928E+04 4 +C4H6,butadiene X10/92C 4.H 6. 0. 0.G 200.000 6000.000 54.09164 1 + 1.60010139E+01 3.91825115E-03 1.14355733E-06-2.07925748E-10 7.57713551E-15 2 + 6.51708221E+03-6.28204145E+01 1.68530424E+00 1.96120012E-02 4.46523571E-05 3 +-8.31523114E-08 3.80651226E-11 1.16075709E+04 1.67545967E+01 1.32298837E+04 4 +C4H6,2-butyne X10/88C 4.H 6. 0. 0.G 200.000 6000.000 54.09164 1 + 6.93232090E+00 1.86425873E-02-6.82359104E-06 1.11910485E-09-6.76783113E-14 2 + 1.40309558E+04-1.22084283E+01 5.42481699E+00 2.65380004E-03 5.30443281E-05 3 +-6.71392095E-08 2.58190081E-11 1.54641216E+04 5.40967409E-01 1.75476366E+04 4 +C4H6,cyclo- L 5/90C 4.H 6. 0. 0.G 200.000 6000.000 54.09164 1 + 7.84858253E+00 1.80812892E-02-6.53186644E-06 1.05842123E-09-6.35253939E-14 2 + 1.46153461E+04-2.08980257E+01 2.91633433E+00-3.20584810E-03 1.00263571E-04 3 +-1.34248167E-07 5.46670100E-11 1.74732236E+04 1.24817183E+01 1.88465706E+04 4 +C4H8,1-butene X 4/88C 4.H 8. 0. 0.G 200.000 6000.000 56.10752 1 + 8.02147991E+00 2.26010707E-02-8.31284033E-06 1.37803072E-09-8.42175459E-14 2 +-4.30852153E+03-1.71170697E+01 4.42674073E+00 6.63946249E-03 6.80652815E-05 3 +-9.28753562E-08 3.73473949E-11-2.11532796E+03 7.54694860E+00-6.49467016E+01 4 +C4H8,cis2-buten X 4/88C 4.H 8. 0. 0.G 200.000 6000.000 56.10752 1 + 7.08335025E+00 2.34982430E-02-8.64483079E-06 1.43160107E-09-8.73762642E-14 2 +-4.92320266E+03-1.28709317E+01 5.44417817E+00-5.20451694E-03 9.62906577E-05 3 +-1.20068814E-07 4.68194825E-11-2.91741472E+03 3.46050733E+00-8.90010355E+02 4 +C4H8,tr2-butene X 4/88C 4.H 8. 0. 0.G 200.000 6000.000 56.10752 1 + 7.62514670E+00 2.30451042E-02-8.49424864E-06 1.41152554E-09-8.64751757E-14 2 +-5.40102815E+03-1.61987080E+01 5.57278967E+00 3.76541017E-03 6.52226708E-05 3 +-8.30909522E-08 3.20311342E-11-3.57903301E+03 5.37796708E-01-1.32298837E+03 4 +C4H8,isobutene X 4/88C 4.H 8. 0. 0.G 200.000 6000.000 56.10752 1 + 7.83555330E+00 2.27459679E-02-8.36517549E-06 1.39076250E-09-8.53329969E-14 2 +-6.16356322E+03-1.76540719E+01 3.68049727E+00 1.69414445E-02 3.51963555E-05 3 +-5.43166856E-08 2.20201636E-11-4.12099308E+03 8.11457149E+00-2.05664555E+03 4 +C4H8,cyclo- L 5/90C 4.H 8. 0. 0.G 200.000 6000.000 56.10752 1 + 7.76331054E+00 2.30653350E-02-8.25983758E-06 1.33412389E-09-7.99363302E-14 2 +-1.17672008E+03-2.19148211E+01 3.81144720E+00-9.68049998E-03 1.27917694E-04 3 +-1.63057125E-07 6.48314790E-11 1.87107930E+03 8.60998196E+00 3.41571542E+03 4 +(CH3COOH)2 L 6/90C 4.H 8.O 4. 0.G 200.000 6000.000 120.10512 1 + 1.58245208E+01 2.61835117E-02-9.46098358E-06 1.53337616E-09-9.20476545E-14 2 +-1.19039141E+05-5.11097617E+01 7.75481743E+00 1.38918897E-02 8.32955609E-05 3 +-1.20021855E-07 4.90679645E-11-1.15185669E+05-1.22446814E+00-1.11734228E+05 4 +C4H9,n-butyl X10/84C 4.H 9. 0. 0.G 200.000 6000.000 57.11546 1 + 9.18975615E+00 2.36322267E-02-8.64270985E-06 1.42770515E-09-8.70203716E-14 2 + 3.37702909E+03-2.15600560E+01 5.82430540E+00 5.50309080E-03 7.49300330E-05 3 +-1.02085943E-07 4.13484714E-11 5.54078049E+03 2.17609509E+00 8.00167418E+03 4 +C4H9,i-butyl X10/84C 4.H 9. 0. 0.G 200.000 6000.000 57.11546 1 + 9.43040607E+00 2.34271349E-02-8.53599182E-06 1.39748355E-09-8.44057456E-14 2 + 2.14214862E+03-2.42207994E+01 3.54885235E+00 1.78747638E-02 5.00782825E-05 3 +-7.94475071E-08 3.35802354E-11 4.74011588E+03 1.11849382E+01 6.89397210E+03 4 +C4H9,s-butyl L 1/93C 4.H 9. 0. 0.G 200.000 6000.000 57.11546 1 + 8.42611939E+00 2.39379265E-02-8.56035783E-06 1.37735160E-09-8.22496005E-14 2 + 3.96484253E+03-1.69876875E+01 5.03930607E+00 4.09387100E-04 9.15574112E-05 3 +-1.19411713E-07 4.75043987E-11 6.42327236E+03 8.24360444E+00 8.53928854E+03 4 +C4H9,t-butyl L 1/93C 4.H 9. 0. 0.G 200.000 6000.000 57.11546 1 + 6.63074656E+00 2.59353745E-02-9.37163111E-06 1.51845890E-09-9.11190863E-14 2 + 2.00861323E+03-9.20581440E+00 6.87327133E+00-1.85146306E-02 1.30560116E-04 3 +-1.50832755E-07 5.65358282E-11 4.10958938E+03 2.30016604E-01 6.21804532E+03 4 +C4H10,isobutane L 6/90C 4.H 10. 0. 0.G 200.000 6000.000 58.12340 1 + 9.76991245E+00 2.54997210E-02-9.14142932E-06 1.47328271E-09-8.80800188E-14 2 +-2.14052647E+04-3.00329101E+01 4.45479276E+00 8.26057985E-03 8.29886664E-05 3 +-1.14647642E-07 4.64570101E-11-1.84593931E+04 4.92743175E+00-1.62354727E+04 4 +C4H10,n-butane L 6/90C 4.H 10. 0. 0.G 200.000 6000.000 58.12340 1 + 9.44535834E+00 2.57858073E-02-9.23619122E-06 1.48632755E-09-8.87897158E-14 2 +-2.01382165E+04-2.63470076E+01 6.14746806E+00 1.55947389E-04 9.67913517E-05 3 +-1.25483910E-07 4.97816555E-11-1.75994402E+04-1.09409879E+00-1.51289733E+04 4 +C4N2 J 3/61C 4.N 2. 0. 0.G 200.000 6000.000 76.05748 1 + 1.04854800E+01 5.69544889E-03-2.12745547E-06 3.52323196E-10-2.14631729E-14 2 + 6.04620630E+04-2.72266502E+01 2.28116845E+00 4.61273513E-02-8.53293243E-05 3 + 7.93407779E-08-2.80356399E-11 6.20401013E+04 1.12898174E+01 6.41601249E+04 4 +C5 L 7/88C 5. 0. 0. 0.G 200.000 6000.000 60.05500 1 + 9.57456888E+00 3.86016798E-03-1.47558014E-06 2.48048833E-10-1.52660253E-14 2 + 1.23053517E+05-2.37137980E+01 3.35873023E+00 3.24350875E-02-5.93058470E-05 3 + 5.60114864E-08-2.03075176E-11 1.24376242E+05 6.04915848E+00 1.26396424E+05 4 +C5H6,1,3cyclo- L 5/90C 5.H 6. 0. 0.G 200.000 6000.000 66.10264 1 + 9.97582745E+00 1.89055233E-02-6.84110300E-06 1.10992117E-09-6.66791427E-14 2 + 1.10816727E+04-3.22096892E+01 8.61044032E-01 1.48045870E-02 7.21072084E-05 3 +-1.13378398E-07 4.86890482E-11 1.48017548E+04 2.13536259E+01 1.61524852E+04 4 +C5H8,cyclo- L 1/93C 5.H 8. 0. 0.G 200.000 6000.000 68.11852 1 + 9.64282423E+00 2.42562834E-02-8.72089503E-06 1.41190868E-09-8.47267848E-14 2 +-1.29255032E+03-3.01225606E+01 2.68980514E+00 2.09635533E-03 1.13034459E-04 3 +-1.54077581E-07 6.27623564E-11 2.45827067E+03 1.53075040E+01 4.07720960E+03 4 +C5H10,1-pentene X 4/87C 5.H 10. 0. 0.G 200.000 6000.000 70.13440 1 + 1.17397055E+01 2.57467071E-02-9.25988701E-06 1.51497885E-09-9.17883939E-14 2 +-8.46274839E+03-3.54375619E+01 5.88356456E+00 5.10401267E-03 9.78282156E-05 3 +-1.32389227E-07 5.32231507E-11-5.16823068E+03 3.41987031E+00-2.55938113E+03 4 +C5H10,cyclo- L 6/90C 5.H 10. 0. 0.G 200.000 6000.000 70.13440 1 + 9.13295790E+00 3.01130430E-02-1.09169137E-05 1.77298767E-09-1.06575248E-13 2 +-1.51597372E+04-2.92618828E+01 3.70327955E+00-1.15565354E-02 1.64111439E-04 3 +-2.09368134E-07 8.31054507E-11-1.10951786E+04 1.19777761E+01-9.42929890E+03 4 +C5H11,pentyl X10/84C 5.H 11. 0. 0.G 200.000 6000.000 71.14234 1 + 1.12985135E+01 2.97314215E-02-1.09772714E-05 1.82708895E-09-1.11996026E-13 2 +-2.39764167E+02-3.10395910E+01 7.17401432E+00 3.80921588E-03 1.04379065E-04 3 +-1.39634050E-07 5.60395117E-11 2.52870902E+03-1.18868630E+00 5.50964519E+03 4 +C5H11,t-pentyl L 1/93C 5.H 11. 0. 0.G 200.000 6000.000 71.14234 1 + 9.23121001E+00 3.11688383E-02-1.12478586E-05 1.82090658E-09-1.09205395E-13 2 +-1.60069498E+03-2.06141974E+01 6.44622533E+00-9.54177763E-03 1.37891362E-04 3 +-1.69241631E-07 6.53097127E-11 1.50837506E+03 5.43091742E+00 3.92085643E+03 4 +C5H12,n-pentane X10/85C 5.H 12. 0. 0.G 298.150 5000.000 72.15028 1 + 1.35469980E+01 2.84217860E-02-9.41746480E-06 1.38935890E-09-7.42126090E-14 2 +-2.45776800E+04-4.70211750E+01 1.89836790E+00 4.12030370E-02 1.23121750E-05 3 +-3.65895010E-08 1.50425090E-11-2.00915000E+04 1.86790820E+01-1.76512800E+04 4 +C5H12,i-pentane X10/85C 5.H 12. 0. 0.G 298.150 5000.000 72.15028 1 + 1.23277870E+01 3.06130870E-02-9.84157850E-06 1.39197760E-09-7.03373450E-14 2 +-2.50374920E+04-4.11334940E+01 1.08328820E+00 4.45710760E-02 8.23899340E-06 3 +-3.52580470E-08 1.57857620E-11-2.08075350E+04 2.17951550E+01-1.84859760E+04 4 +CH3C(CH3)2CH3 X10/85C 5.H 12. 0. 0.G 298.150 5000.000 72.15028 1 + 1.01104160E+01 3.53495660E-02-1.10399670E-05 1.47777210E-09-6.84670420E-14 2 +-2.58067110E+04-3.37569840E+01 7.26389940E-01 4.81254760E-02 1.59174580E-06 3 +-2.66924580E-08 1.20782820E-11-2.24079800E+04 1.83272140E+01-2.01962590E+04 4 +C6H2 L 2/93C 6.H 2. 0. 0.G 200.000 6000.000 74.08188 1 + 1.25238060E+01 8.78596282E-03-3.13663173E-06 5.04345908E-10-3.01109700E-14 2 + 7.60771037E+04-3.88501245E+01-5.94405026E-01 7.46613329E-02-1.35847980E-04 3 + 1.22198100E-07-4.17696751E-11 7.84192204E+04 2.21178780E+01 8.05820187E+04 4 +C6H5,phenyl L 1/91C 6.H 5. 0. 0.G 200.000 6000.000 77.10570 1 + 1.07702200E+01 1.83848597E-02-6.69985951E-06 1.09225620E-09-6.58414439E-14 2 + 3.52040328E+04-3.50146837E+01 7.09725032E-01 1.93299484E-02 5.94079007E-05 3 +-9.85084147E-08 4.25424755E-11 3.91345677E+04 2.30299294E+01 4.05556070E+04 4 +C6D5 L12/84C 6.D 5. 0. 0.G 300.000 5000.000 82.13651 1 + 1.47294920E+01 1.52105350E-02-5.52416350E-06 8.79845750E-10-5.09792170E-14 2 + 3.02826290E+04-5.57549640E+01-1.25497820E+00 4.73287660E-02-8.07598830E-06 3 +-2.99019720E-08 1.71490600E-11 3.53140630E+04 2.97801460E+01 3.69171280E+04 4 +C6H5O,phenoxy L 6/90C 6.H 5.O 1. 0.G 200.000 6000.000 93.10510 1 + 1.31515134E+01 1.90165507E-02-6.94695592E-06 1.13442172E-09-6.84634203E-14 2 +-4.72968266E+02-4.67107225E+01 7.76296446E-02 3.30574915E-02 3.60356256E-05 3 +-7.93165426E-08 3.64328623E-11 4.06539383E+03 2.57598920E+01 5.73666999E+03 4 +C6H6 L 1/91C 6.H 6. 0. 0.G 200.000 6000.000 78.11364 1 + 1.10771708E+01 2.07067895E-02-7.51625100E-06 1.22209416E-09-7.35312513E-14 2 + 4.30988395E+03-4.00116950E+01 5.03469664E-01 1.85142363E-02 7.37864409E-05 3 +-1.18106127E-07 5.07182527E-11 8.55266293E+03 2.16481796E+01 9.96811598E+03 4 +C6D6 L12/84C 6.D 6. 0. 0.G 300.000 5000.000 84.15061 1 + 1.56198640E+01 1.71239340E-02-6.20127590E-06 9.84930580E-10-5.68915570E-14 2 +-1.44330520E+02-6.38881890E+01-2.07012180E+00 5.29381970E-02-9.60748280E-06 3 +-3.28023720E-08 1.90125280E-11 5.40689840E+03 3.06938730E+01 6.99716330E+03 4 +C6H5OH,phenol L 6/90C 6.H 6.O 1. 0.G 200.000 6000.000 94.11304 1 + 1.41553674E+01 1.99349498E-02-7.18217132E-06 1.16228680E-09-6.97145840E-14 2 +-1.81287342E+04-5.17991412E+01-2.91049229E-01 4.08567842E-02 2.42823545E-05 3 +-7.14476757E-08 3.46003044E-11-1.34129231E+04 2.68748886E+01-1.15940687E+04 4 +C6H10,cyclo- L 1/93C 6.H 10. 0. 0.G 200.000 6000.000 82.14540 1 + 1.17733889E+01 3.09482743E-02-1.12347262E-05 1.82632045E-09-1.09855683E-13 2 +-7.20263233E+03-4.26557933E+01 2.36627804E+00 1.06814158E-02 1.18222243E-04 3 +-1.65679913E-07 6.76133786E-11-2.48250358E+03 1.67692033E+01-5.53249680E+02 4 +C6H12,1-hexene X 4/87C 6.H 12. 0. 0.G 200.000 6000.000 84.16128 1 + 1.51268820E+01 2.94975192E-02-1.05411189E-05 1.72131394E-09-1.04218853E-13 2 +-1.24861590E+04-5.19351758E+01 7.31539830E+00 3.70903758E-03 1.27255723E-04 3 +-1.71562233E-07 6.89824521E-11-8.20916239E+03-5.95782436E-01-5.04539654E+03 4 +C6H12,cyclo- L 6/90C 6.H 12. 0. 0.G 200.000 6000.000 84.16128 1 + 1.32147562E+01 3.58242410E-02-1.32110595E-05 2.17202254E-09-1.31730540E-13 2 +-2.28091954E+04-5.53526464E+01 4.04348764E+00-6.19527424E-03 1.76621086E-04 3 +-2.22967809E-07 8.63667390E-11-1.69202872E+04 8.52566766E+00-1.48294969E+04 4 +C6H13,n-hexyl X10/83C 6.H 13. 0. 0.G 200.000 6000.000 85.16922 1 + 1.40301977E+01 3.47114029E-02-1.26836103E-05 2.09365902E-09-1.27627985E-13 2 +-4.06907890E+03-4.39643824E+01 8.76344954E+00 2.16243850E-03 1.31674084E-04 3 +-1.73827452E-07 6.92515009E-11-5.42628115E+02-5.91726978E+00 3.01881891E+03 4 +C7H7,benzyl L 1/93C 7.H 7. 0. 0.G 200.000 6000.000 91.13258 1 + 1.40435627E+01 2.34946209E-02-8.53786999E-06 1.38914523E-09-8.36183659E-14 2 + 1.85643697E+04-5.16632394E+01 4.81145711E-01 3.85126943E-02 3.28618341E-05 3 +-7.69728603E-08 3.54230267E-11 2.33070210E+04 2.35487000E+01 2.53171865E+04 4 +C7H8 L 1/93C 7.H 8. 0. 0.G 200.000 6000.000 92.14052 1 + 1.29394750E+01 2.66921558E-02-9.68420108E-06 1.57392140E-09-9.46670482E-14 2 +-6.77035769E+02-4.67255302E+01 1.61191400E+00 2.11188902E-02 8.53221453E-05 3 +-1.32566876E-07 5.59406109E-11 4.09651976E+03 2.02973614E+01 6.03402967E+03 4 +C7H8O,cresol mx L 1/93C 7.H 8.O 1. 0.G 200.000 6000.000 108.13992 1 + 1.65179499E+01 2.54721604E-02-9.18781249E-06 1.48772675E-09-8.92617180E-14 2 +-2.36116775E+04-6.19386224E+01 7.98026029E-01 4.67284934E-02 2.73617362E-05 3 +-7.75823278E-08 3.68948350E-11-1.83324087E+04 2.42303179E+01-1.59117014E+04 4 +C7H14,1-heptene X 4/87C 7.H 14. 0. 0.G 200.000 6000.000 98.18816 1 + 1.84972484E+01 3.32575990E-02-1.18150330E-05 1.92513278E-09-1.16441886E-13 2 +-1.65142044E+04-6.83095138E+01 8.70575623E+00 2.79788048E-03 1.55212260E-04 3 +-2.09020114E-07 8.40527224E-11-1.12661385E+04-4.45341873E+00-7.54824999E+03 4 +C7H15,n-heptyl X10/83C 7.H 15. 0. 0.G 200.000 6000.000 99.19610 1 + 1.64117107E+01 4.03602901E-02-1.47823188E-05 2.44414560E-09-1.49160374E-13 2 +-7.76310920E+03-5.49531828E+01 1.02804136E+01 7.01553566E-04 1.59551347E-04 3 +-2.09593179E-07 8.33445318E-11-3.60307311E+03-1.03020940E+01 5.27992630E+02 4 +C7H16,n-heptane X10/85C 7.H 16. 0. 0.G 200.000 6000.000 100.20404 1 + 1.85354704E+01 3.91420468E-02-1.38030268E-05 2.22403874E-09-1.33452580E-13 2 +-3.19500783E+04-7.01902840E+01 1.11532484E+01-9.49415433E-03 1.95571181E-04 3 +-2.49752520E-07 9.84873213E-11-2.67711735E+04-1.59096110E+01-2.25870196E+04 4 +C8H8,styrene X 4/89C 8.H 8. 0. 0.G 200.000 6000.000 104.15152 1 + 1.58813334E+01 2.68374055E-02-9.90244561E-06 1.63759141E-09-9.98448972E-14 2 + 1.00847804E+04-6.09419319E+01 1.18175769E+00 3.34876025E-02 6.92366253E-05 3 +-1.24490419E-07 5.49384735E-11 1.56039062E+04 2.26624980E+01 1.78362886E+04 4 +C8H10,ethylbenz X10/86C 8.H 10. 0. 0.G 200.000 6000.000 106.16740 1 + 1.55760759E+01 3.23064579E-02-1.19002723E-05 1.96792542E-09-1.19911164E-13 2 +-4.41157516E+03-5.91043877E+01 3.51534963E+00 1.78145681E-02 1.18934012E-04 3 +-1.75639764E-07 7.32061099E-11 1.02038595E+03 1.41539629E+01 3.59852836E+03 4 +C8H16,1-octene X 4/87C 8.H 16. 0. 0.G 200.000 6000.000 112.21504 1 + 2.20134086E+01 3.67972174E-02-1.29830482E-05 2.10854637E-09-1.27294158E-13 2 +-2.06109835E+04-8.55337170E+01 1.01487860E+01 1.25107538E-03 1.85252736E-04 3 +-2.49094162E-07 1.00250395E-10-1.43267453E+04-8.50774418E+00-1.00535089E+04 4 +C8H17,n-octyl X10/83C 8.H 17. 0. 0.G 200.000 6000.000 113.22298 1 + 1.87968043E+01 4.60048523E-02-1.68790126E-05 2.79422477E-09-1.70663886E-13 2 +-1.14592578E+04-6.59622206E+01 1.18082518E+01-8.50348136E-04 1.87697700E-04 3 +-2.45690702E-07 9.75813027E-11-6.66450442E+03-1.47298487E+01-1.96283365E+03 4 +C8H18,isooctane X 4/85C 8.H 18. 0. 0.G 200.000 6000.000 114.23092 1 + 1.59899273E+01 5.53184790E-02-1.95267072E-05 3.11779172E-09-1.85312577E-13 2 +-3.58757973E+04-6.01161414E+01 8.15737338E-01 7.32643959E-02 1.78300688E-05 3 +-6.93589620E-08 3.21629382E-11-3.04772862E+04 2.41509994E+01-2.69420567E+04 4 +C8H18,n-octane X 4/85C 8.H 18. 0. 0.G 200.000 6000.000 114.23092 1 + 2.21755407E+01 4.24426161E-02-1.49161103E-05 2.40376673E-09-1.44359037E-13 2 +-3.61030944E+04-8.80854457E+01 1.25244908E+01-1.01018365E-02 2.21991595E-04 3 +-2.84862420E-07 1.12409624E-10-2.98433034E+04-1.97108554E+01-2.51067110E+04 4 +C9H19,n-nonyl X10/83C 9.H 19. 0. 0.G 298.150 5000.000 127.24986 1 + 1.91952670E+01 5.54392490E-02-2.14366010E-05 3.78851440E-09-2.50029870E-13 2 +-1.43737110E+04-6.60562860E+01 2.87564850E+00 7.57927890E-02 1.34624310E-05 3 +-6.40883970E-08 2.86941720E-11-8.68345310E+03 2.42622410E+01-4.45371290E+03 4 +C10H8,naphthale L 8/93C 10.H 8. 0. 0.G 200.000 6000.000 128.17352 1 + 1.86129899E+01 3.04494141E-02-1.11224799E-05 1.81615406E-09-1.09601224E-13 2 + 8.91552944E+03-8.00230479E+01-1.04919326E+00 4.62970611E-02 7.07592203E-05 3 +-1.38408186E-07 6.20475748E-11 1.59846388E+04 3.02121571E+01 1.81105080E+04 4 +C10H21,n-decyl X10/83C 10.H 21. 0. 0.G 298.150 5000.000 141.27674 1 + 2.13221280E+01 6.15735240E-02-2.38494830E-05 4.22091160E-09-2.78893070E-13 2 +-1.79678090E+04-7.56437801E+01 3.08970070E+00 8.41179490E-02 1.59018380E-05 3 +-7.23879340E-08 3.22669250E-11-1.16149410E+04 2.52811929E+01-6.94456890E+03 4 +C12H9,o-bipheny L12/84C 12.H 9. 0. 0.G 200.000 6000.000 153.20346 1 + 2.25693421E+01 3.45619386E-02-1.27020788E-05 2.08111827E-09-1.25849480E-13 2 + 4.05905091E+04-9.57792390E+01 4.07649156E-01 5.42797841E-02 7.12514701E-05 3 +-1.44404490E-07 6.48500575E-11 4.85349837E+04 2.81982515E+01 5.14438397E+04 4 +O-C12D9 L12/84C 12.D 9. 0. 0.G 300.000 5000.000 162.25892 1 + 3.01231990E+01 2.83282550E-02-1.03665400E-05 1.65933380E-09-9.65271160E-14 2 + 3.32077890E+04-1.35191307E+02-7.32993960E-01 8.98368950E-02-1.37312750E-05 3 +-5.94270200E-08 3.37024300E-11 4.29430940E+04 3.00419560E+01 4.64864100E+04 4 +C12H10,bipheny L12/84C 12.H 10. 0. 0.G 200.000 6000.000 154.21140 1 + 2.28964892E+01 3.68452570E-02-1.35016270E-05 2.20802808E-09-1.33358223E-13 2 + 1.07394499E+04-1.00510148E+02 1.94566186E-01 5.35264368E-02 8.54996701E-05 3 +-1.63903606E-07 7.29977217E-11 1.90020431E+04 2.72151271E+01 2.19050792E+04 4 +C12D10 L12/84C 12.D 10. 0. 0.G 300.000 5000.000 164.27302 1 + 3.09050600E+01 3.03499880E-02-1.10950480E-05 1.77558100E-09-1.03323270E-13 2 + 2.88344530E+03-1.42438937E+02-1.57934860E+00 9.50595740E-02-1.45320710E-05 3 +-6.26455970E-08 3.55300790E-11 1.31374220E+04 3.15298410E+01 1.66475020E+04 4 +Jet-A(g) L 6/88C 12.H 23. 0. 0.G 273.150 5000.000 167.31462 1 + 2.48802010E+01 7.82500480E-02-3.15509730E-05 5.78789000E-09-3.98279680E-13 2 +-4.31106840E+04-9.36552468E+01 2.08692170E+00 1.33149650E-01-8.11574520E-05 3 + 2.94092860E-08-6.51952130E-12-3.59128140E+04 2.73552972E+01-3.00344960E+04 4 +Ca L 3/93CA 1. 0. 0. 0.G 200.000 6000.000 40.07800 1 + 1.92707623E+00 1.34909167E-03-1.07515862E-06 3.25457865E-10-2.64671538E-14 2 + 2.08196210E+04 7.42878398E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 2.06389279E+04 4.38454833E+00 2.13843029E+04 4 +Ca+ J 9/83CA 1.E -1. 0. 0.G 298.150 6000.000 40.07745 1 + 2.64221438E+00-1.60517359E-04-2.70843966E-08 5.13522496E-11-5.96487048E-15 2 + 9.22596379E+04 4.25372628E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 9.23242106E+04 5.07767503E+00 9.30695856E+04 4 +CaBr J12/74CA 1.BR 1. 0. 0.G 300.000 5000.000 119.98200 1 + 4.32173630E+00 4.09036740E-04-2.45415310E-07 6.90268740E-11-5.36841960E-15 2 +-7.24627320E+03 5.67668059E+00 3.85118770E+00 3.02714810E-03-5.50978070E-06 3 + 4.67645710E-09-1.49599600E-12-7.18372390E+03 7.77803289E+00-5.94108833E+03 4 +CaBr2 J 6/74CA 1.BR 2. 0. 0.G 300.000 5000.000 199.88600 1 + 7.41516390E+00 9.65490130E-05-4.24638160E-08 8.22868650E-12-5.86170570E-16 2 +-4.85368240E+04-4.48080162E+00 6.60571570E+00 3.60588920E-03-5.83146500E-06 3 + 4.26348010E-09-1.16672780E-12-4.83829630E+04-6.31052281E-01-4.62968444E+04 4 +CaCL J 6/70CA 1.CL 1. 0. 0.G 300.000 5000.000 75.53070 1 + 4.30671160E+00 4.00849630E-04-2.33136610E-07 6.39217970E-11-4.86623830E-15 2 +-1.38926560E+04 4.37337421E+00 3.67305150E+00 3.31441640E-03-5.16824350E-06 3 + 3.71112670E-09-9.96870310E-13-1.37841440E+04 7.33679641E+00-1.25805061E+04 4 +CaCL2 J 6/70CA 1.CL 2. 0. 0.G 300.000 5000.000 110.98340 1 + 7.36500140E+00 1.53271080E-04-6.72752850E-08 1.30141310E-11-9.25679680E-16 2 +-5.89547310E+04-7.18852085E+00 6.16133630E+00 5.30604290E-03-8.46494630E-06 3 + 6.11288970E-09-1.65223620E-12-5.87229350E+04-1.44829735E+00-5.67135827E+04 4 +CaF J12/68CA 1.F 1. 0. 0.G 300.000 5000.000 59.07640 1 + 4.19886210E+00 4.92440930E-04-2.61021230E-07 6.47916350E-11-4.73039510E-15 2 +-3.40211290E+04 3.46314757E+00 3.05089900E+00 5.15494390E-03-7.35082960E-06 3 + 4.78764580E-09-1.15231550E-12-3.37923450E+04 8.98800887E+00-3.27096252E+04 4 +CaF2 J12/68CA 1.F 2. 0. 0.G 300.000 5000.000 78.07481 1 + 6.65434310E+00 3.90526920E-04-1.70810700E-07 3.29528400E-11-2.33877410E-15 2 +-9.64452790E+04-5.31072117E+00 4.23081520E+00 1.02558050E-02-1.54443450E-05 3 + 1.05467910E-08-2.68439160E-12-9.59552610E+04 6.36780653E+00-9.43548797E+04 4 +CaI J 6/74CA 1.I 1. 0. 0.G 300.000 5000.000 166.98247 1 + 4.31984710E+00 4.34666910E-04-2.74419200E-07 8.00804410E-11-6.54516080E-15 2 +-1.90648040E+03 6.71480235E+00 4.02391010E+00 2.25599780E-03-4.09398330E-06 3 + 3.48400510E-09-1.11629960E-12-1.87705110E+03 7.99031065E+00-6.06862329E+02 4 +CaI2 J 6/74CA 1.I 2. 0. 0.G 300.000 5000.000 293.88694 1 + 7.42386650E+00 8.85553580E-05-3.98468930E-08 7.89183570E-12-5.73526580E-16 2 +-3.32877520E+04-2.97844542E+00 6.56417270E+00 4.26846500E-03-7.92475830E-06 3 + 6.72056000E-09-2.14854610E-12-3.31382820E+04 1.02209228E+00-3.10492020E+04 4 +CaO J12/74CA 1.O 1. 0. 0.G 300.000 5000.000 56.07740 1 + 9.17458650E+00-1.06432340E-02 7.69689680E-06-1.90704430E-09 1.55092310E-13 2 + 2.32480410E+03-2.44275825E+01 2.67186020E+00 6.43240250E-03-9.57270300E-06 3 + 6.76204240E-09-1.81730490E-12 4.27345310E+03 9.65422679E+00 5.28389925E+03 4 +CaOH J12/75CA 1.O 1.H 1. 0.G 300.000 5000.000 57.08534 1 + 5.27547590E+00 1.80256200E-03-6.84356480E-07 1.30601960E-10-8.91315800E-15 2 +-2.49846810E+04-2.31108541E+00 2.10048520E+00 1.86951590E-02-3.35066440E-05 3 + 2.80256380E-08-8.79926890E-12-2.45309150E+04 1.20387635E+01-2.33185135E+04 4 +CaOH+ J12/75CA 1.O 1.H 1.E -1.G 300.000 5000.000 57.08479 1 + 5.40510870E+00 1.52450030E-03-4.78308080E-07 7.13472160E-11-4.12983490E-15 2 + 4.26859330E+04-3.66981129E+00 2.15664600E+00 1.85186760E-02-3.32682220E-05 3 + 2.78722200E-08-8.76080100E-12 4.31683950E+04 1.10927661E+01 4.43915181E+04 4 +CaO2H2 J12/75CA 1.O 2.H 2. 0.G 300.000 5000.000 74.09268 1 + 8.85820360E+00 2.99419090E-03-9.32192990E-07 1.37883860E-10-7.91119850E-15 2 +-7.62794960E+04-1.71393039E+01 2.32221660E+00 3.75156820E-02-6.79965130E-05 3 + 5.72902630E-08-1.80814750E-11-7.53228630E+04 1.24879611E+01-7.34591048E+04 4 +CaS J 9/77CA 1.S 1. 0. 0.G 298.150 5000.000 72.14400 1 + 5.35707752E+00-4.18392513E-03 4.68291375E-06-1.40725075E-09 1.28892668E-13 2 + 1.34741825E+04-1.43173210E+00 3.22586008E+00 5.30640418E-03-8.76527639E-06 3 + 6.42601054E-09-1.61529035E-12 1.37334866E+04 8.34892080E+00 1.48655784E+04 4 +Ca2 J 9/83CA 2. 0. 0. 0.G 200.000 6000.000 80.15600 1 + 3.16700199E+00-6.16814444E-04 2.03540960E-07-2.77128180E-11 1.65003046E-15 2 + 4.04382380E+04 1.37113509E+01 4.94590110E+00 4.30621337E-03-3.23384227E-05 3 + 4.51640811E-08-1.93501071E-11 3.96175492E+04 2.54511315E+00 4.10779763E+04 4 +CL J 6/82CL 1. 0. 0. 0.G 200.000 6000.000 35.45270 1 + 2.94658358E+00-3.85985408E-04 1.36139388E-07-2.17032923E-11 1.28751025E-15 2 + 1.36970327E+04 3.11330136E+00 2.26062480E+00 1.54154399E-03-6.80283622E-07 3 +-1.59972975E-09 1.15416636E-12 1.38552986E+04 6.57020799E+00 1.45891941E+04 4 +CL+ J 6/82CL 1.E -1. 0. 0.G 298.150 6000.000 35.45215 1 + 3.12286072E+00-6.36624037E-04 2.48337920E-07-3.72507849E-11 1.98433686E-15 2 + 1.64912234E+05 2.49731349E+00 1.71435396E+00 6.62489248E-03-1.35523086E-05 3 + 1.14999760E-08-3.58760566E-12 1.65123809E+05 8.91739552E+00 1.65830698E+05 4 +CL- J 6/82CL 1.E 1. 0. 0.G 298.150 6000.000 35.45325 1 + 2.50000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-2.88834132E+04 4.20062927E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-2.88834132E+04 4.20062927E+00-2.81380382E+04 4 +CLCN J 6/66CL 1.C 1.N 1. 0.G 300.000 5000.000 61.47044 1 + 5.49200210E+00 2.09872480E-03-7.74159140E-07 1.38238820E-10-9.23348640E-15 2 + 1.47491610E+04-3.73046245E+00 3.33908540E+00 1.03974680E-02-1.37046500E-05 3 + 9.50619620E-09-2.59252600E-12 1.52375390E+04 6.83103255E+00 1.65917045E+04 4 +CLF J 6/77CL 1.F 1. 0. 0.G 300.000 5000.000 54.45110 1 + 2.84862330E+00 3.17332790E-03-2.05233870E-06 5.21627330E-10-3.74722620E-14 2 +-6.92788240E+03 9.31699660E+00 2.64455690E+00 6.24812560E-03-9.03543510E-06 3 + 6.34005750E-09-1.74353720E-12-7.04691060E+03 9.63042800E+00-6.04884780E+03 4 +CLF3 J 9/65CL 1.F 3. 0. 0.G 300.000 5000.000 92.44791 1 + 8.95359670E+00 1.17221630E-03-5.08961880E-07 9.75634890E-11-6.88587310E-15 2 +-2.20759680E+04-1.80815549E+01 2.89491190E+00 2.47185500E-02-3.51393230E-05 3 + 2.25595910E-08-5.32619780E-12-2.07986400E+04 1.13816921E+01-1.91052460E+04 4 +CLO J 6/61CL 1.O 1. 0. 0.G 300.000 5000.000 51.45210 1 + 4.09126190E+00 5.00031260E-04-1.87782060E-07 3.50976710E-11-2.42050380E-15 2 + 1.08532230E+04 3.61889244E+00 2.81793640E+00 4.45313330E-03-4.41248930E-06 3 + 1.59209420E-09-1.44862420E-14 1.11713970E+04 1.00579823E+01 1.21736480E+04 4 +CLO2 L 7/93CL 1.O 2. 0. 0.G 200.000 6000.000 67.45150 1 + 5.76647681E+00 1.41132506E-03-5.43714031E-07 1.00734295E-10-6.43543762E-15 2 + 1.06324182E+04-2.86560082E+00 3.29338614E+00 6.19311337E-03 1.05685372E-06 3 +-8.16191254E-09 4.34694600E-12 1.13760776E+04 1.03017024E+01 1.26285253E+04 4 +CL2 TPIS89CL 2. 0. 0. 0.G 200.000 6000.000 70.90540 1 + 4.74727508E+00-4.88581710E-04 2.68444871E-07-2.43476083E-11-1.03683148E-15 2 +-1.51101862E+03-3.44551305E-01 2.73638114E+00 7.83525700E-03-1.45104963E-05 3 + 1.25730834E-08-4.13247145E-12-1.05880114E+03 9.44555879E+00 0.00000000E+00 4 +CL2O J12/65CL 2.O 1. 0. 0.G 300.000 5000.000 86.90480 1 + 6.43400620E+00 6.27288090E-04-2.69332520E-07 5.10763940E-11-3.56915450E-15 2 + 8.48605300E+03-4.93672407E+00 3.25452380E+00 1.27994490E-02-1.78824600E-05 3 + 1.12643830E-08-2.59642520E-12 9.16574230E+03 1.05712106E+01 1.05680184E+04 4 +Cr J 6/79CR 1. 0. 0. 0.G 200.000 6000.000 51.99610 1 + 3.08497752E+00-1.44703683E-03 1.08492194E-06-2.35643635E-10 1.86355816E-14 2 + 4.68928202E+04 3.65913914E+00 2.50259371E+00-2.76560170E-05 1.03974095E-07 3 +-1.61996406E-10 8.89391985E-14 4.70600237E+04 6.71107210E+00 4.78055833E+04 4 +CrN J12/73CR 1.N 1. 0. 0.G 300.000 5000.000 66.00284 1 + 3.86496020E+00 8.51604560E-04-4.40707580E-07 1.06676010E-10-8.37314220E-15 2 + 5.94774370E+04 5.29506757E+00 2.93046360E+00 3.03770420E-03-1.27139640E-06 3 +-1.17812490E-09 8.55513490E-13 5.97442030E+04 1.01918812E+01 6.07397802E+04 4 +CrO J12/73CR 1.O 1. 0. 0.G 300.000 5000.000 67.99550 1 + 4.01398180E+00 6.27002450E-04-2.79567940E-07 6.00031000E-11-4.40579160E-15 2 + 2.13466930E+04 5.55171510E+00 2.84149960E+00 4.09533580E-03-3.57764630E-06 3 + 8.17104390E-10 2.40720090E-13 2.16460670E+04 1.15179922E+01 2.26454051E+04 4 +CrO2 J12/73CR 1.O 2. 0. 0.G 300.000 5000.000 83.99490 1 + 5.84999980E+00 1.27251010E-03-5.49205480E-07 1.04974910E-10-7.39954860E-15 2 +-1.10421830E+04-1.74497632E+00 3.30126450E+00 8.16258570E-03-5.89076800E-06 3 + 1.61708560E-11 1.08162670E-12-1.03535690E+04 1.13991138E+01-9.05799743E+03 4 +CrO3 J12/73CR 1.O 3. 0. 0.G 300.000 5000.000 99.99430 1 + 8.16289460E+00 2.04508390E-03-8.85941310E-07 1.69762820E-10-1.19877650E-14 2 +-3.80925570E+04-1.58958945E+01 1.90728580E+00 2.30496080E-02-2.65012940E-05 3 + 1.28624130E-08-1.83819910E-12-3.66086800E+04 1.53451415E+01-3.52251261E+04 4 +Cs L 3/93CS 1. 0. 0. 0.G 200.000 6000.000 132.90543 1 + 2.82023315E+00-3.34840327E-04-9.82915709E-08 1.27564369E-10-1.46119271E-14 2 + 8.30639354E+03 5.00894042E+00 2.50004554E+00-4.66833356E-07 1.68005061E-09 3 +-2.48218029E-12 1.27712190E-15 8.45540436E+03 6.87573539E+00 9.20078273E+03 4 +Cs+ J12/83CS 1.E -1. 0. 0.G 298.150 6000.000 132.90488 1 + 2.50000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 5.43873989E+04 6.18275756E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 5.43873989E+04 6.18275756E+00 5.51327739E+04 4 +CsCL J 6/68CS 1.CL 1. 0. 0.G 300.000 5000.000 168.35813 1 + 4.47984550E+00 1.09491640E-04-3.99899140E-09 2.06419950E-13 2.21846400E-17 2 +-3.02358090E+04 5.21731708E+00 4.18230300E+00 1.37595530E-03-2.05869330E-06 3 + 1.48364740E-09-3.97645460E-13-3.01779270E+04 6.63848788E+00-2.88852607E+04 4 +CsF J 6/68CS 1.F 1. 0. 0.G 300.000 5000.000 151.90383 1 + 4.43733090E+00 1.27150000E-04-2.05476500E-08 2.98133570E-12-1.47742450E-16 2 +-4.42279950E+04 3.87355585E+00 3.74498790E+00 3.01005160E-03-4.58838160E-06 3 + 3.21796940E-09-8.37860170E-13-4.40906960E+04 7.19487315E+00-4.28749148E+04 4 +CsO J12/68CS 1.O 1. 0. 0.G 300.000 5000.000 148.90483 1 + 4.46602820E+00 1.15632320E-04-5.99891870E-09 1.31766990E-13 5.76397450E-17 2 + 6.19503090E+03 5.21454869E+00 3.98574190E+00 2.12792510E-03-3.21702550E-06 3 + 2.27642950E-09-5.97219760E-13 6.28989400E+03 7.51602259E+00 7.54861703E+03 4 +CsOH J 6/71CS 1.O 1.H 1. 0.G 300.000 5000.000 149.91277 1 + 5.70056490E+00 1.18203840E-03-3.19390940E-07 3.86429170E-11-1.66356360E-15 2 +-3.29192050E+04-2.11870021E+00 4.54860030E+00 7.96123330E-03-1.33264970E-05 3 + 1.03142340E-08-2.89737770E-12-3.28108900E+04 2.86187969E+00-3.11995968E+04 4 +CsOH+ J12/71CS 1.O 1.H 1.E -1.G 300.000 5000.000 149.91222 1 + 5.72925630E+00 1.15713240E-03-3.10444310E-07 3.70962910E-11-1.55094630E-15 2 + 5.16264830E+04-5.76482218E-01 4.84871580E+00 6.89083460E-03-1.18393280E-05 3 + 9.43353720E-09-2.72226850E-12 5.16781670E+04 3.08484851E+00 5.33428450E+04 4 +Cs2 J12/83CS 2. 0. 0. 0.G 200.000 6000.000 265.81086 1 + 6.86645178E+00-3.99014326E-03 1.31948084E-06-1.63413186E-10 6.88125908E-15 2 + 1.08054293E+04-4.29749465E+00 4.74588225E+00-2.63862819E-03 1.14139305E-05 3 +-1.60430500E-08 6.56112294E-12 1.15444856E+04 7.60679272E+00 1.29144271E+04 4 +Cs2CL2 J 6/68CS 2.CL 2. 0. 0.G 300.000 5000.000 336.71626 1 + 9.94243750E+00 6.26593030E-05-2.63310970E-08 4.89121420E-12-3.35541520E-16 2 +-8.23458550E+04-1.05980604E+01 9.29526420E+00 2.85056000E-03-4.55760190E-06 3 + 3.25577310E-09-8.60673620E-13-8.22228620E+04-7.51835332E+00-7.93590189E+04 4 +Cs2F2 J 6/68CS 2.F 2. 0. 0.G 300.000 5000.000 303.80767 1 + 9.87937250E+00 1.26748290E-04-5.09052530E-08 8.97117620E-12-5.80909600E-16 2 +-1.10050570E+05-1.40548217E+01 8.44255610E+00 6.49210010E-03-1.08327570E-05 3 + 8.17910540E-09-2.31739780E-12-1.09781650E+05-7.24824485E+00-1.07056586E+05 4 +Cs2O J12/68CS 2.O 1. 0. 0.G 300.000 5000.000 281.81026 1 + 6.89794670E+00 1.01650980E-04-3.80620620E-08 6.14663930E-12-3.57582160E-16 2 +-1.31699890E+04-1.16591689E+00 5.75536390E+00 4.91160730E-03-7.70725180E-06 3 + 5.41569570E-09-1.40808980E-12-1.29468290E+04 4.30015461E+00-1.10706171E+04 4 +Cs2O2H2 J 6/71CS 2.O 2.H 2. 0.G 300.000 5000.000 299.82554 1 + 9.58093620E+00 5.32605090E-03-1.87805450E-06 3.09259250E-10-1.94295330E-14 2 +-8.60258390E+04-1.32145943E+01 7.52281910E+00 7.90783720E-03 3.54302990E-06 3 +-1.04563280E-08 4.80140320E-12-8.53384120E+04-1.90663311E+00-8.27310993E+04 4 +Cs2SO4 J 6/79CS 2.S 1.O 4. 0.G 300.000 5000.000 361.87446 1 + 1.54190450E+01 4.05276500E-03-1.79103410E-06 3.50246530E-10-2.52157360E-14 2 +-1.40367750E+05-4.14921849E+01 4.29653850E+00 4.48543000E-02-6.09879230E-05 3 + 4.05163880E-08-1.06734950E-11-1.37825590E+05 1.34096371E+01-1.35014739E+05 4 +Cu J 9/84CU 1. 0. 0. 0.G 200.000 6000.000 63.54600 1 + 3.13522595E+00-1.13337547E-03 5.72023041E-07-7.66326177E-11 2.83881466E-15 2 + 3.96177240E+04 2.25331944E+00 2.50006597E+00-6.77306412E-07 2.44116818E-09 3 +-3.61314758E-12 1.86303224E-15 3.98583358E+04 5.76884604E+00 4.06037157E+04 4 +Cu+ J 9/84CU 1.E -1. 0. 0.G 298.150 6000.000 63.54545 1 + 2.49981754E+00 3.57922146E-07-2.21769848E-10 4.86937918E-14-2.39019610E-18 2 + 1.30263854E+05 1.24951186E+01 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 1.30263788E+05 1.24941209E+01 1.31009163E+05 4 +CuCL J 3/66CU 1.CL 1. 0. 0.G 300.000 5000.000 98.99870 1 + 4.39029880E+00 1.83494840E-04-5.71107030E-08 1.12933210E-11-8.19755200E-16 2 + 9.60972660E+03 3.39216514E+00 3.34916000E+00 5.10283020E-03-9.12780020E-06 3 + 7.60141550E-09-2.39844890E-12 9.79675620E+03 8.26947304E+00 1.09553590E+04 4 +CuF J12/77CU 1.F 1. 0. 0.G 300.000 5000.000 82.54440 1 + 4.12273990E+00 6.31634630E-04-3.34728200E-07 8.08373670E-11-5.78348170E-15 2 +-2.80059530E+03 3.48564571E+00 2.76545050E+00 6.85118050E-03-1.13388190E-05 3 + 8.90965780E-09-2.69276920E-12-2.55485650E+03 9.87277411E+00-1.50966578E+03 4 +CuF2 J12/77CU 1.F 2. 0. 0.G 300.000 5000.000 101.54281 1 + 6.81842360E+00-1.64979080E-04 2.02917740E-07-2.54531130E-11 1.20657320E-16 2 +-3.43227440E+04-7.12862921E+00 3.11076960E+00 1.43258070E-02-2.28117430E-05 3 + 1.72788930E-08-5.07269770E-12-3.35004530E+04 1.09995698E+01-3.21060286E+04 4 +CuO J12/77CU 1.O 1. 0. 0.G 300.000 5000.000 79.54540 1 + 4.27236250E+00 4.47132760E-04-2.39569790E-07 6.04053160E-11-4.24560160E-15 2 + 3.55353490E+04 3.72701889E+00 3.70935200E+00 3.19650590E-03-5.29701090E-06 3 + 4.21642380E-09-1.28918550E-12 3.56274700E+04 6.33140079E+00 3.68364130E+04 4 +Cu2 J 9/66CU 2. 0. 0. 0.G 300.000 5000.000 127.09200 1 + 4.42397340E+00 2.02489520E-04-6.44897930E-08 1.40654120E-11-7.60204940E-16 2 + 5.70381310E+04 3.78535579E+00 3.92443580E+00 2.72749490E-03-4.91949560E-06 3 + 4.18219650E-09-1.33935330E-12 5.71191870E+04 6.08380829E+00 5.83746552E+04 4 +Cu3CL3 J 3/66CU 3.CL 3. 0. 0.G 300.000 5000.000 296.99610 1 + 1.56261270E+01 4.33738330E-04-1.94670060E-07 3.84669380E-11-2.78997000E-15 2 +-3.58818530E+04-3.77523345E+01 1.14429000E+01 2.06908060E-02-3.82640030E-05 3 + 3.23410530E-08-1.03098840E-11-3.51516100E+04-1.82687865E+01-3.10992833E+04 4 +D J 3/82D 1. 0. 0. 0.G 200.000 6000.000 2.01410 1 + 2.50000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 2.59212596E+04 5.91715827E-01 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 2.59212596E+04 5.91715827E-01 2.66666346E+04 4 +D+ J 3/82D 1.E -1. 0. 0.G 298.150 6000.000 2.01355 1 + 2.50000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 1.84511964E+05-1.01838904E-01 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 1.84511964E+05-1.01838904E-01 1.85257339E+05 4 +D- J 3/82D 1.E 1. 0. 0.G 298.150 6000.000 2.01465 1 + 2.50000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 1.64237667E+04-1.01023912E-01 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 1.64237667E+04-1.01023912E-01 1.71691417E+04 4 +DCL J 6/77D 1.CL 1. 0. 0.G 300.000 5000.000 37.46680 1 + 2.95720340E+00 1.59181600E-03-6.33202720E-07 1.17556580E-10-8.15999110E-15 2 +-1.21735150E+04 5.89879674E+00 3.82692130E+00-2.50133260E-03 6.04661240E-06 3 +-4.48375190E-09 1.13676410E-12-1.23019210E+04 1.89177784E+00-1.12270035E+04 4 +DF J 6/77D 1.F 1. 0. 0.G 300.000 5000.000 21.01251 1 + 2.72646200E+00 1.50912930E-03-5.17049380E-07 8.54853710E-11-5.41960240E-15 2 +-3.39369400E+04 5.82981981E+00 3.49813860E+00 2.21767930E-04-1.33202400E-06 3 + 2.56194930E-09-1.15122410E-12-3.41832320E+04 1.65507861E+00-3.31376542E+04 4 +DOCL J 3/79D 1.O 1.CL 1. 0.G 300.000 5000.000 53.46620 1 + 4.43507610E+00 2.53223870E-03-1.03123310E-06 1.90054540E-10-1.26823840E-14 2 +-1.09194020E+04 2.72715969E+00 2.47904180E+00 1.08458960E-02-1.52283050E-05 3 + 1.14373140E-08-3.42049250E-12-1.05180920E+04 1.21267107E+01-9.41045332E+03 4 +D2 TPIS89D 2. 0. 0. 0.G 200.000 6000.000 4.02820 1 + 2.73068929E+00 1.48004781E-03-4.79314848E-07 7.89496274E-11-4.88380823E-15 2 +-7.95267504E+02 1.64266243E+00 3.49546974E+00 2.58348159E-04-1.31762502E-06 3 + 2.42912018E-09-1.05982498E-12-1.04631580E+03-2.51905385E+00 0.00000000E+00 4 +D2+ J 9/77D 2.E -1. 0. 0.G 300.000 5000.000 4.02766 1 + 3.58918000E+00 8.92146510E-04-2.42644840E-07 5.75844090E-11-6.73805600E-15 2 + 1.79037520E+05-2.05817885E+00 3.80751400E+00-3.11062600E-03 1.01629820E-05 3 +-9.83632710E-09 3.26598530E-12 1.79170960E+05-2.28662825E+00 1.80239805E+05 4 +D2- J 9/77D 2.E 1. 0. 0.G 300.000 5000.000 4.02875 1 + 3.75310420E+00 9.80189910E-04-3.63879600E-07 7.07004820E-11-5.06742720E-15 2 + 2.70647080E+04-2.81955172E+00 3.21448000E+00 7.83581650E-04 3.58926850E-06 3 +-5.23941900E-09 2.08713650E-12 2.72930090E+04 3.68155837E-01 2.83085763E+04 4 +D2O J 6/77D 2.O 1. 0. 0.G 300.000 5000.000 20.02760 1 + 2.72645950E+00 3.98451730E-03-1.49326260E-06 2.63497720E-10-1.76495570E-14 2 +-3.09026380E+04 7.31820134E+00 3.85411310E+00 1.47122880E-04 3.00690060E-06 3 +-1.77476280E-09 2.30188620E-13-3.11516510E+04 1.73341984E+00-2.99728411E+04 4 +D2S J 6/77D 2.S 1. 0. 0.G 300.000 5000.000 36.09420 1 + 3.66629010E+00 3.49922640E-03-1.42072840E-06 2.66856390E-10-1.86847390E-14 2 +-4.21473080E+03 3.79969969E+00 3.80708240E+00 3.75963110E-04 5.75307990E-06 3 +-5.34857400E-09 1.40540830E-12-4.06612190E+03 3.87928749E+00-2.87340817E+03 4 +F J 6/82F 1. 0. 0. 0.G 200.000 6000.000 18.99840 1 + 2.66749541E+00-1.66693548E-04 6.42448457E-08-1.08588758E-11 6.70845755E-16 2 + 8.78895350E+03 4.00729198E+00 2.41951429E+00 2.94132793E-03-8.92799246E-06 3 + 9.92060935E-09-3.79860044E-12 8.75732351E+03 4.74771042E+00 9.54836785E+03 4 +F+ J 6/82F 1.E -1. 0. 0.G 298.150 6000.000 18.99785 1 + 2.68834861E+00-1.76182961E-04 6.06940639E-08-8.91530067E-12 5.47552167E-16 2 + 2.11744095E+05 4.27480838E+00 3.08421084E+00-9.00062139E-04-1.64599174E-07 3 + 1.10121336E-09-5.56270920E-13 2.11619101E+05 2.14597653E+00 2.12499113E+05 4 +F- J 6/82F 1.E 1. 0. 0.G 298.150 6000.000 18.99895 1 + 2.50000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-3.14241522E+04 3.26488285E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-3.14241522E+04 3.26488285E+00-3.06787772E+04 4 +FCN J 6/69F 1.C 1.N 1. 0.G 300.000 5000.000 45.01614 1 + 5.08985570E+00 2.41706840E-03-9.76827660E-07 1.78134420E-10-1.21185670E-14 2 + 2.57807810E+03-2.87278096E+00 3.25169410E+00 8.30731440E-03-8.36663580E-06 3 + 4.41256440E-09-9.08824230E-13 3.05511980E+03 6.44214774E+00 4.32821878E+03 4 +FO J12/66F 1.O 1. 0. 0.G 300.000 5000.000 34.99780 1 + 3.91927740E+00 7.04423450E-04-2.66482040E-07 4.96175990E-11-3.36885710E-15 2 + 1.17981930E+04 3.32875837E+00 2.96800240E+00 2.64833930E-03-3.73680050E-07 3 +-1.90062250E-09 1.06142830E-12 1.20878440E+04 8.39349747E+00 1.30839080E+04 4 +FO2 J 9/66F 1.O 2. 0. 0.G 300.000 5000.000 50.99720 1 + 5.70409350E+00 1.38628890E-03-5.83553740E-07 1.09372140E-10-7.58691810E-15 2 +-3.96786780E+02-2.06791733E+00 3.78050730E+00 6.81745950E-03-5.81336050E-06 3 + 1.75625040E-09 6.77574300E-14 1.27694680E+02 7.83568297E+00 1.51000973E+03 4 +F2 TPIS89F 2. 0. 0. 0.G 200.000 6000.000 37.99681 1 + 3.86166219E+00 7.88367679E-04-1.81982940E-07-9.17436560E-12 2.65193472E-15 2 +-1.23238655E+03 2.04119855E+00 3.20832415E+00 1.25919179E-03 3.89747979E-06 3 +-7.22184984E-09 3.31837862E-12-1.03425794E+03 5.61903589E+00 0.00000000E+00 4 +F2O J12/69F 2.O 1. 0. 0.G 300.000 5000.000 53.99621 1 + 6.00518710E+00 1.10284020E-03-4.75479370E-07 9.06831450E-11-6.37570980E-15 2 + 9.19060650E+02-5.22210581E+00 2.61092190E+00 1.22312800E-02-1.34414150E-05 3 + 5.89094120E-09-5.74871750E-13 1.73471960E+03 1.17878818E+01 2.94942436E+03 4 +FS2F,fluorodisu J 6/76F 2.S 2. 0. 0.G 200.000 6000.000 102.12881 1 + 9.11491404E+00 9.25549788E-04-3.66972859E-07 6.31489899E-11-3.94877764E-15 2 +-4.34448561E+04-1.73685774E+01 2.22664682E+00 3.28125204E-02-5.92797021E-05 3 + 5.02331280E-08-1.62599019E-11-4.21538019E+04 1.51239428E+01-4.04636521E+04 4 +Fe J 3/78FE 1. 0. 0. 0.G 200.000 6000.000 55.84700 1 + 3.26197970E+00-1.05582533E-03 5.92906998E-07-1.07189455E-10 7.48064402E-15 2 + 4.90969873E+04 3.52443894E+00 1.70744428E+00 1.06339224E-02-2.76118171E-05 3 + 2.80917854E-08-1.01219824E-11 4.91843725E+04 9.80811099E+00 4.99728787E+04 4 +Fe+ J 6/84FE 1.E -1. 0. 0.G 298.150 6000.000 55.84645 1 + 3.33602399E+00-2.72549262E-04 8.05440344E-09 1.51229089E-11-1.43376595E-15 2 + 1.41036455E+05 2.86476968E+00 2.76418106E+00 2.86948238E-03-7.61235651E-06 3 + 8.18183334E-09-3.11792199E-12 1.41159039E+05 5.53997981E+00 1.42058161E+05 4 +Fe- J 6/84FE 1.E 1. 0. 0.G 298.150 6000.000 55.84755 1 + 3.36310586E+00-8.29375042E-04 3.12426241E-07-5.20068355E-11 3.17875241E-15 2 + 4.63564307E+04 2.76802421E+00 1.52174510E+00 9.79673193E-03-2.11078670E-05 3 + 1.84820903E-08-5.89537134E-12 4.65710215E+04 1.08683385E+01 4.73074180E+04 4 +FeC5O5 J 3/78FE 1.C 5.O 5. 0.G 300.000 5000.000 195.89900 1 + 2.11640210E+01 1.03331030E-02-4.33109360E-06 8.20474970E-10-5.77738740E-14 2 +-9.48889340E+04-7.20736520E+01 6.60654600E+00 7.50421290E-02-1.22012750E-04 3 + 1.00553780E-07-3.22609730E-11-9.19514380E+04-2.57600621E+00-8.75408014E+04 4 +FeCL J 6/65FE 1.CL 1. 0. 0.G 300.000 5000.000 91.29970 1 + 4.69406690E+00 1.16040780E-04-2.08401750E-08-1.76265560E-12 5.23138140E-16 2 + 2.87903440E+04 4.19355506E+00 3.78858260E+00 4.36780110E-03-6.69223280E-06 3 + 4.17074540E-09-8.46867730E-13 2.89200970E+04 8.35336756E+00 3.01925149E+04 4 +FeCL2 J12/70FE 1.CL 2. 0. 0.G 300.000 5000.000 126.75240 1 + 6.94926010E+00 5.33716410E-04 7.02212070E-08-6.14754900E-11 6.79331430E-15 2 +-1.90458320E+04-3.75951441E+00 5.45575050E+00 7.96329270E-03-1.25939640E-05 3 + 8.99767340E-09-2.32423630E-12-1.88442970E+04 3.02284219E+00-1.69583047E+04 4 +FeCL3 J 6/65FE 1.CL 3. 0. 0.G 300.000 5000.000 162.20510 1 + 9.77711060E+00 2.44213620E-04-1.03139940E-07 1.92074260E-11-1.31792990E-15 2 +-3.34395700E+04-1.45491463E+01 7.56148730E+00 9.73382490E-03-1.55433050E-05 3 + 1.11863680E-08-3.00229980E-12-3.30136240E+04-3.98583203E+00-3.04431637E+04 4 +FeO J 9/66FE 1.O 1. 0. 0.G 300.000 5000.000 71.84640 1 + 4.20498170E+00 2.68384520E-04-8.94267360E-08 3.18559110E-11-3.39225430E-15 2 + 2.88291700E+04 4.83043159E+00 2.82452560E+00 4.30492070E-03-4.10847810E-06 3 + 1.32011890E-09 7.13162170E-14 2.91940350E+04 1.18911760E+01 3.01938519E+04 4 +Fe(OH)2 J12/66FE 1.O 2.H 2. 0.G 200.000 6000.000 89.86168 1 + 8.96262012E+00 4.20137342E-03-1.61017443E-06 2.68347076E-10-1.63497305E-14 2 +-4.27994358E+04-1.86912367E+01-1.67667734E+00 6.16931464E-02-1.20738995E-04 3 + 1.09814026E-07-3.72856831E-11-4.11289708E+04 2.96771710E+01-3.97541166E+04 4 +Fe2CL4 J12/70FE 2.CL 4. 0. 0.G 300.000 5000.000 253.50480 1 + 1.53575000E+01 6.42078610E-04 2.08177300E-08-5.15805590E-11 6.06734950E-15 2 +-5.65100370E+04-3.18965871E+01 1.27382420E+01 1.32355580E-02-2.16418730E-05 3 + 1.59936670E-08-4.35070970E-12-5.61065790E+04-1.98247491E+01-5.18820452E+04 4 +Fe2CL6 J 6/65FE 2.CL 6. 0. 0.G 200.000 6000.000 324.41020 1 + 2.15645031E+01 4.62349015E-04-1.84952078E-07 3.20143043E-11-2.01002737E-15 2 +-8.52432375E+04-5.86538185E+01 1.42211808E+01 4.35485968E-02-9.60390188E-05 3 + 9.37463081E-08-3.36051626E-11-8.41996265E+04-2.59244694E+01-7.87030865E+04 4 +H L 5/93H 1. 0. 0. 0.G 200.000 6000.000 1.00794 1 + 2.50000286E+00-5.65334214E-09 3.63251723E-12-9.19949720E-16 7.95260746E-20 2 + 2.54736589E+04-4.46698494E-01 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 2.54736599E+04-4.46682853E-01 2.62190349E+04 4 +H+ L 7/88H 1.E -1. 0. 0.G 298.150 6000.000 1.00739 1 + 2.50000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 1.84021428E+05-1.14064453E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 1.84021428E+05-1.14064453E+00 1.84766803E+05 4 +H- L/7/88H 1.E 1. 0. 0.G 298.150 6000.000 1.00849 1 + 2.50000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 1.59761670E+04-1.13901598E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 1.59761670E+04-1.13901598E+00 1.67215420E+04 4 +HALO J 3/64H 1.AL 1.O 1. 0.G 200.000 6000.000 43.98888 1 + 5.09075339E+00 2.42514117E-03-9.39932946E-07 1.59391004E-10-9.86747317E-15 2 + 2.05009459E+03-4.61450791E+00 3.29221159E+00-2.68200399E-03 2.86841292E-05 3 +-3.79708866E-08 1.54020350E-11 2.97771050E+03 6.96160970E+00 4.02573333E+03 4 +HBO J12/75H 1.B 1.O 1. 0.G 300.000 5000.000 27.81834 1 + 3.74851810E+00 3.66108590E-03-1.46354090E-06 2.65199030E-10-1.78342750E-14 2 +-2.52257980E+04 1.74647757E+00 2.21431060E+00 9.37185130E-03-1.07110740E-05 3 + 7.67697740E-09-2.35863710E-12-2.48492460E+04 9.37201677E+00-2.38530740E+04 4 +HBO+ J12/75H 1.B 1.O 1.E -1.G 300.000 5000.000 27.81779 1 + 3.94750800E+00 3.43154360E-03-1.27870840E-06 2.21806040E-10-1.47571920E-14 2 + 1.41359980E+05 1.99889597E+00 2.25442830E+00 8.03018720E-03-5.97490720E-06 3 + 2.42819500E-09-4.30511240E-13 1.41850690E+05 1.08122076E+01 1.42831572E+05 4 +HBO- J12/75H 1.B 1.O 1.E 1.G 300.000 5000.000 27.81889 1 + 4.08692650E+00 2.97847560E-03-1.23871070E-06 2.46933350E-10-1.84550480E-14 2 +-3.09300260E+04 2.78014247E+00 3.97079550E+00-2.21001070E-03 1.45354130E-05 3 +-1.56389250E-08 5.39789660E-12-3.05894990E+04 4.82496967E+00-2.94037719E+04 4 +HBO2 J12/64H 1.B 1.O 2. 0.G 300.000 5000.000 43.81774 1 + 4.73895190E+00 4.77187710E-03-1.80634940E-06 3.14928890E-10-2.07383120E-14 2 +-6.92488380E+04 9.86391767E-03 2.87078660E+00 7.88626440E-03-4.07368420E-07 3 +-4.70590220E-09 2.35488930E-12-6.86241110E+04 1.01805186E+01-6.74294533E+04 4 +HBS J12/75H 1.B 1.S 1. 0.G 300.000 5000.000 43.88494 1 + 4.44122650E+00 2.99798250E-03-1.19382300E-06 2.11958320E-10-1.34660970E-14 2 + 4.44029750E+03-6.46783174E-01 1.55959030E+00 1.39668380E-02-1.79885950E-05 3 + 1.23151410E-08-3.40909570E-12 5.08909360E+03 1.35018986E+01 6.03866710E+03 4 +HBS+ J12/75H 1.B 1.S 1.E -1.G 300.000 5000.000 43.88439 1 + 4.70975420E+00 2.81870360E-03-1.16330880E-06 2.17688390E-10-1.51086860E-14 2 + 1.34191390E+05-8.37472146E-01 2.25115610E+00 1.20771680E-02-1.53221560E-05 3 + 1.04940900E-08-2.93252920E-12 1.34754760E+05 1.12707699E+01 1.35846718E+05 4 +HBr J 9/65H 1.BR 1. 0. 0.G 300.000 5000.000 80.91194 1 + 2.79358040E+00 1.56559250E-03-5.61710640E-07 9.57831420E-11-6.18139900E-15 2 +-5.23383840E+03 7.65553403E+00 3.60566900E+00-5.95294310E-04 6.50295680E-07 3 + 9.37812190E-10-7.11418520E-13-5.43894550E+03 3.49634113E+00-4.38311167E+03 4 +HCN L 7/88H 1.C 1.N 1. 0.G 200.000 6000.000 27.02568 1 + 3.80231733E+00 3.14630009E-03-1.06315698E-06 1.66185395E-10-9.79891789E-15 2 + 1.49104829E+04 1.57503584E+00 2.25901123E+00 1.00510591E-02-1.33514911E-05 3 + 1.00920882E-08-3.00882048E-12 1.52158495E+04 8.91634590E+00 1.62366754E+04 4 +HCO L12/89H 1.C 1.O 1. 0.G 200.000 6000.000 29.01834 1 + 3.64896209E+00 3.08090819E-03-1.12429876E-06 1.86308085E-10-1.13951828E-14 2 + 3.71209048E+03 5.06147406E+00 4.22118584E+00-3.24392532E-03 1.37799446E-05 3 +-1.33144093E-08 4.33768865E-12 3.83956496E+03 3.39437243E+00 5.05141013E+03 4 +HCO+ J12/70H 1.C 1.O 1.E -1.G 300.000 5000.000 29.01779 1 + 3.74118800E+00 3.34415170E-03-1.23971210E-06 2.11893880E-10-1.37041500E-14 2 + 9.88840780E+04 2.07861357E+00 2.47397360E+00 8.67155900E-03-1.00315000E-05 3 + 6.71705270E-09-1.78726740E-12 9.91466080E+04 8.17571187E+00 1.00193449E+05 4 +HCCN TPIS91H 1.C 2.N 1. 0.G 200.000 6000.000 39.03668 1 + 6.56314169E+00 3.48040967E-03-1.24603080E-06 2.00764486E-10-1.20044547E-14 2 + 7.11347086E+04-9.86556141E+00 1.87184307E+00 2.60611314E-02-4.62723965E-05 3 + 4.18609731E-08-1.45352705E-11 7.20340360E+04 1.22173228E+01 7.34175107E+04 4 +HCL J 9/64H 1.CL 1. 0. 0.G 300.000 5000.000 36.46064 1 + 2.76658840E+00 1.43818830E-03-4.69930000E-07 7.34994080E-11-4.37311060E-15 2 +-1.19174680E+04 6.47150629E+00 3.52481710E+00 2.99848620E-05-8.62218910E-07 3 + 2.09797210E-09-9.86581910E-13-1.21505090E+04 2.40892359E+00-1.11021897E+04 4 +HD J 6/77H 1.D 1. 0. 0.G 300.000 5000.000 3.02204 1 + 2.84645440E+00 1.06319610E-03-2.44338050E-07 2.90508340E-11-1.16215310E-15 2 +-7.61824650E+02 9.80143997E-01 3.43254770E+00 6.51070280E-04-1.93326660E-06 3 + 2.41017360E-09-8.67323970E-13-1.00092720E+03-2.38902247E+00 3.86979786E+01 4 +HD+ J 9/77H 1.D 1.E -1. 0.G 300.000 5000.000 3.02149 1 + 3.29097640E+00 1.15515290E-03-3.44494630E-07 7.67226820E-11-8.09481330E-15 2 + 1.78942790E+05-4.78607212E-01 3.88271360E+00-3.07793810E-03 8.19144730E-06 3 +-6.81194990E-09 1.98598980E-12 1.78945630E+05-2.80335978E+00 1.80026303E+05 4 +HD- J 9/77H 1.D 1.E 1. 0.G 300.000 5000.000 3.02259 1 + 3.49399490E+00 1.24486670E-03-4.72887140E-07 9.10596370E-11-6.48629260E-15 2 + 2.71577340E+04-2.23110461E+00 3.64288770E+00-2.12912890E-03 8.92841230E-06 3 +-9.34812040E-09 3.25649710E-12 2.72692710E+04-2.25562661E+00 2.83227106E+04 4 +HDO J 6/77H 1.D 1.O 1. 0.G 300.000 5000.000 19.02144 1 + 2.66726880E+00 3.55752090E-03-1.20260030E-06 1.96072090E-10-1.23526200E-14 2 +-3.03728690E+04 7.98359926E+00 4.07544220E+00-1.38202850E-03 5.70255340E-06 3 +-4.41636460E-09 1.22630620E-12-3.07076080E+04 9.71068127E-01-2.95117089E+04 4 +HF J 6/77H 1.F 1. 0. 0.G 300.000 5000.000 20.00634 1 + 2.99191100E+00 7.14894750E-04-6.86309730E-08-1.16171300E-11 1.94123750E-15 2 +-3.36213640E+04 3.82549527E+00 3.43799860E+00 5.35715980E-04-1.52296550E-06 3 + 1.75644910E-09-5.78699400E-13-3.38189720E+04 1.20618177E+00-3.27803794E+04 4 +HI J 9/61H 1.I 1. 0. 0.G 300.000 5000.000 127.91241 1 + 2.91040080E+00 1.56881880E-03-5.92276320E-07 1.05370940E-10-7.03751160E-15 2 + 2.25086590E+03 7.86447051E+00 3.69637220E+00-1.42247550E-03 3.01311880E-06 3 +-1.26664030E-09-3.50987650E-14 2.10735810E+03 4.08812111E+00 3.17030779E+03 4 +HNC L11/92H 1.N 1.C 1. 0.G 200.000 6000.000 27.02568 1 + 4.22248103E+00 2.59458278E-03-8.58480969E-07 1.30745002E-10-7.50339765E-15 2 + 2.20127593E+04-7.79447358E-02 2.30186735E+00 1.54157529E-02-3.13262156E-05 3 + 3.08816551E-08-1.11912353E-11 2.22277183E+04 8.14751135E+00 2.33781812E+04 4 +HNCO J12/70H 1.N 1.C 1.O 1.G 200.000 6000.000 43.02508 1 + 5.29404664E+00 4.03039650E-03-1.41290348E-06 2.24428234E-10-1.32859380E-14 2 +-1.41653759E+04-3.08763130E+00 2.24322454E+00 1.44986380E-02-1.52609054E-05 3 + 8.36364453E-09-1.72191967E-12-1.34257512E+04 1.21565469E+01-1.22316288E+04 4 +HNO L12/89H 1.N 1.O 1. 0.G 200.000 6000.000 31.01408 1 + 3.16554762E+00 3.00005132E-03-3.94350282E-07-3.85787491E-11 7.08091931E-15 2 + 1.11944169E+04 7.64764695E+00 4.53525882E+00-5.68546910E-03 1.85199976E-05 3 +-1.71883674E-08 5.55833090E-12 1.10398805E+04 1.74314734E+00 1.22716461E+04 4 +HNO2 TPIS89H 1.N 1.O 2. 0.G 200.000 6000.000 47.01348 1 + 5.79182658E+00 3.65162663E-03-1.29293451E-06 2.06892932E-10-1.23154855E-14 2 +-1.15655526E+04-4.05538525E+00 3.21415925E+00 8.12777920E-03 1.65999516E-06 3 +-9.52815563E-09 4.87131816E-12-1.07532360E+04 9.82200021E+00-9.43554377E+03 4 +HNO3 L 4/90H 1.N 1.O 3. 0.G 200.000 6000.000 63.01288 1 + 8.00379234E+00 4.49837533E-03-1.73648758E-06 2.93685555E-10-1.81478673E-14 2 +-1.92563022E+04-1.60985546E+01 1.74492946E+00 1.88040888E-02-8.15963597E-06 3 +-5.78584532E-09 4.43768083E-12-1.73805296E+04 1.69545524E+01-1.61059245E+04 4 +HOCL J 3/79H 1.O 1.CL 1. 0.G 300.000 5000.000 52.46004 1 + 4.22501050E+00 2.31826750E-03-8.38423800E-07 1.41763980E-10-8.74699940E-15 2 +-1.03686570E+04 3.59007556E+00 2.93205370E+00 6.93777440E-03-6.71918450E-06 3 + 3.15688660E-09-4.69658800E-13-1.00867990E+04 9.95256576E+00-8.95759158E+03 4 +HOF J12/72H 1.O 1.F 1. 0.G 300.000 5000.000 36.00574 1 + 4.04643360E+00 2.44862830E-03-8.62835530E-07 1.42099040E-10-8.93569150E-15 2 +-1.32090670E+04 3.34993292E+00 3.23109290E+00 3.73898570E-03 6.30097620E-07 3 +-3.62150020E-09 1.78671330E-12-1.29547790E+04 7.75090362E+00-1.18259888E+04 4 +HO2 L 5/89H 1.O 2. 0. 0.G 200.000 6000.000 33.00674 1 + 4.17228728E+00 1.88117647E-03-3.46277408E-07 1.94657853E-11 1.76254294E-16 2 + 6.18102964E+01 2.95767746E+00 4.30179801E+00-4.74912051E-03 2.11582891E-05 3 +-2.42763894E-08 9.29225124E-12 2.94808040E+02 3.71666245E+00 1.50965000E+03 4 +HSO3F J 6/72H 1.S 1.O 3.F 1.G 300.000 5000.000 100.07054 1 + 1.03641900E+01 5.38611640E-03-2.12315720E-06 3.82083430E-10-2.58070900E-14 2 +-9.43983340E+04-2.60055034E+01 2.11924450E+00 3.15457100E-02-3.13178880E-05 3 + 1.24615070E-08-8.25146300E-13-9.23615960E+04 1.55596956E+01-9.05800898E+04 4 +H2 TPIS78H 2. 0. 0. 0.G 200.000 6000.000 2.01588 1 + 2.93286579E+00 8.26607967E-04-1.46402335E-07 1.54100359E-11-6.88804432E-16 2 +-8.13065597E+02-1.02432887E+00 2.34433112E+00 7.98052075E-03-1.94781510E-05 3 + 2.01572094E-08-7.37611761E-12-9.17935173E+02 6.83010238E-01 0.00000000E+00 4 +H2+ TPIS78H 2.E -1. 0. 0.G 298.150 6000.000 2.01533 1 + 3.44204765E+00 5.99083239E-04 6.69133685E-08-3.43574373E-11 1.97626599E-15 2 + 1.78649686E+05-2.79498949E+00 3.77256072E+00-1.95746589E-03 4.54812047E-06 3 +-2.82152141E-09 5.33969209E-13 1.78694104E+05-3.96609086E+00 1.79766749E+05 4 +H2- J 9/77H 2.E 1. 0. 0.G 300.000 5000.000 2.01643 1 + 3.29210760E+00 1.43586260E-03-5.47055930E-07 1.04338830E-10-7.38279980E-15 2 + 2.72161810E+04-1.98277770E+00 3.83801420E+00-3.17947680E-03 1.00430110E-05 3 +-9.55181160E-09 3.12813300E-12 2.72348560E+04-3.99862360E+00 2.83091721E+04 4 +HCHO,formaldehy L 8/88H 2.C 1.O 1. 0.G 200.000 6000.000 30.02628 1 + 3.16952654E+00 6.19320583E-03-2.25056377E-06 3.65975680E-10-2.20149470E-14 2 +-1.44784444E+04 6.04209449E+00 4.79372315E+00-9.90833369E-03 3.73220008E-05 3 +-3.79285261E-08 1.31772652E-11-1.43089567E+04 6.02812900E-01-1.30590979E+04 4 +HCOOH L 8/88H 2.C 1.O 2. 0.G 200.000 6000.000 46.02568 1 + 5.69579404E+00 7.72237361E-03-3.18037808E-06 5.57949466E-10-3.52618226E-14 2 +-4.81599723E+04-6.01680080E+00 3.23262453E+00 2.81129582E-03 2.44034975E-05 3 +-3.17501066E-08 1.20631660E-11-4.67785606E+04 9.86205647E+00-4.55312460E+04 4 +H2F2 J 6/77H 2.F 2. 0. 0.G 300.000 5000.000 40.01269 1 + 4.91603890E+00 3.98576540E-03-1.35587070E-06 2.19309210E-10-1.37160050E-14 2 +-7.05947770E+04-6.29605894E-01 2.67633120E+00 1.22979910E-02-1.24559650E-05 3 + 6.36025230E-09-1.12708230E-12-7.01237150E+04 1.03109298E+01-6.88771705E+04 4 +H2O L 8/89H 2.O 1. 0. 0.G 200.000 6000.000 18.01528 1 + 2.67703787E+00 2.97318329E-03-7.73769690E-07 9.44336689E-11-4.26900959E-15 2 +-2.98858938E+04 6.88255571E+00 4.19864056E+00-2.03643410E-03 6.52040211E-06 3 +-5.48797062E-09 1.77197817E-12-3.02937267E+04-8.49032208E-01-2.90848168E+04 4 +H2O+ TPIS89H 2.O 1.E -1. 0.G 298.150 6000.000 18.01473 1 + 3.31570460E+00 2.10648728E-03-3.76341449E-07 3.47525900E-11-1.70335651E-15 2 + 1.16991617E+05 4.03220441E+00 4.02465853E+00-1.08850969E-03 5.13575400E-06 3 +-4.40026592E-09 1.40726274E-12 1.16869757E+05 6.99971363E-01 1.18058671E+05 4 +H2O2 L 2/93H 2.O 2. 0. 0.G 200.000 6000.000 34.01468 1 + 4.57333537E+00 4.04984070E-03-1.29479479E-06 1.97281710E-10-1.13402846E-14 2 +-1.80548121E+04 7.04278488E-01 4.27611269E+00-5.42822417E-04 1.67335701E-05 3 +-2.15770813E-08 8.62454363E-12-1.77542989E+04 3.43505074E+00-1.63942313E+04 4 +H2S J 6/77H 2.S 1. 0. 0.G 300.000 5000.000 34.08188 1 + 2.74521990E+00 4.04346070E-03-1.53845100E-06 2.75202490E-10-1.85920950E-14 2 +-3.41994440E+03 8.05467450E+00 3.93234760E+00-5.02609050E-04 4.59284730E-06 3 +-3.18072140E-09 6.64975610E-13-3.65053590E+03 2.31579050E+00-2.46584037E+03 4 +H2SO4 J 9/77H 2.S 1.O 4. 0.G 300.000 5000.000 98.07948 1 + 1.08895320E+01 7.50041780E-03-2.92104780E-06 5.25955130E-10-3.57894150E-14 2 +-9.24713640E+04-2.94047820E+01 1.07256800E+00 4.37692260E-02-5.53332430E-05 3 + 3.55182530E-08-9.06773580E-12-9.02597580E+04 1.89395820E+01-8.84175226E+04 4 +H3B3O6 J12/64H 3.B 3.O 6. 0.G 300.000 5000.000 131.45322 1 + 2.01535790E+01 1.30162860E-02-5.06696190E-06 9.03082530E-10-6.05324100E-14 2 +-2.81040920E+05-7.96763324E+01-2.27051160E+00 8.70248940E-02-9.15877140E-05 3 + 3.94453920E-08-3.66660350E-12-2.75695230E+05 3.25296526E+01-2.73237150E+05 4 +H3F3 J 6/77H 3.F 3. 0. 0.G 300.000 5000.000 60.01903 1 + 8.53073730E+00 6.71659390E-03-2.54567000E-06 4.47809290E-10-2.98942750E-14 2 +-1.08717940E+05-1.62112010E+01 2.07178640E+00 3.72793820E-02-5.81502920E-05 3 + 4.59061980E-08-1.39874980E-11-1.07578590E+05 1.39817790E+01-1.05733574E+05 4 +H3O+ TPIS89H 3.O 1.E -1. 0.G 298.150 6000.000 19.02267 1 + 2.49647716E+00 5.72844920E-03-1.83953281E-06 2.73577439E-10-1.54093985E-14 2 + 7.09729113E+04 7.45850779E+00 3.79295270E+00-9.10854000E-04 1.16363549E-05 3 +-1.21364887E-08 4.26159663E-12 7.07512401E+04 1.47156856E+00 7.19224584E+04 4 +(HCOOH)2 L 8/88H 4.C 2.O 4. 0.G 200.000 6000.000 92.05136 1 + 1.16290939E+01 1.48350345E-02-5.39529341E-06 8.78326929E-10-5.28913475E-14 2 +-1.03759144E+05-3.25539738E+01 5.12766711E+00 1.68445826E-02 2.91126977E-05 3 +-5.07453596E-08 2.15546828E-11-1.01180748E+05 4.89874978E+00-9.87361420E+04 4 +H4F4 J 6/77H 4.F 4. 0. 0.G 300.000 5000.000 80.02537 1 + 1.20373850E+01 8.95958620E-03-3.39605690E-06 5.97436530E-10-3.98846930E-14 2 +-1.46561930E+05-2.96546038E+01 3.38217550E+00 4.99124510E-02-7.78999700E-05 3 + 6.15036210E-08-1.87398120E-11-1.45035070E+05 1.08054742E+01-1.42383768E+05 4 +H5F5 J 6/77H 5.F 5. 0. 0.G 300.000 5000.000 100.03172 1 + 1.55441350E+01 1.12023770E-02-4.24631630E-06 7.47031830E-10-4.98723600E-14 2 +-1.84546860E+05-4.32813902E+01 4.68417500E+00 6.26053080E-02-9.77989890E-05 3 + 7.72573220E-08-2.35504610E-11-1.82631590E+05 7.48167497E+00-1.79174885E+05 4 +H6F6 J 6/77H 6.F 6. 0. 0.G 300.000 5000.000 120.03806 1 + 1.90509240E+01 1.34450930E-02-5.09652930E-06 8.96615810E-10-5.98590720E-14 2 +-2.23981100E+05-5.70591470E+01 5.99633170E+00 7.52257730E-02-1.17517160E-04 3 + 9.28217600E-08-2.82904570E-11-2.21678470E+05 3.96435297E+00-2.17415294E+05 4 +H7F7 J 6/77H 7.F 7. 0. 0.G 300.000 5000.000 140.04440 1 + 2.25575360E+01 1.56881520E-02-5.94695760E-06 1.04625320E-09-6.98503510E-14 2 +-2.60642480E+05-7.09521060E+01 7.30097910E+00 8.78997660E-02-1.37369080E-04 3 + 1.08526180E-07-3.30827150E-11-2.57951770E+05 3.62476078E-01-2.52882912E+05 4 +He L10/90HE 1. 0. 0. 0.G 200.000 6000.000 4.00260 1 + 2.50000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-7.45375000E+02 9.28724724E-01 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-7.45375000E+02 9.28724724E-01 0.00000000E+00 4 +He+ L10/92HE 1.E -1. 0. 0.G 298.150 6000.000 4.00205 1 + 2.50000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 2.85315086E+05 1.62166684E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 2.85315086E+05 1.62166684E+00 2.86060462E+05 4 +Hg J 9/84HG 1. 0. 0. 0.G 200.000 6000.000 200.59000 1 + 2.50953611E+00-1.98827279E-05 1.38910849E-08-3.93542920E-12 3.90959219E-16 2 + 6.63358064E+03 6.74847966E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 6.63690008E+03 6.80020154E+00 7.38227508E+03 4 +HgBr2 J 3/62HG 1.BR 2. 0. 0.G 300.000 5000.000 360.39800 1 + 7.42269900E+00 7.86876630E-05-2.99103070E-08 4.84982280E-12-2.79309330E-16 2 +-1.25220200E+04-3.86733971E+00 6.71889210E+00 2.57827430E-03-2.91802370E-06 3 + 9.58184420E-10 1.38723070E-13-1.23714340E+04-4.13670823E-01-1.02774216E+04 4 +I J 6/82I 1. 0. 0. 0.G 200.000 6000.000 126.90447 1 + 2.61667712E+00-2.66010320E-04 1.86060150E-07-3.81927472E-11 2.52036053E-15 2 + 1.20582790E+04 6.87896653E+00 2.50041683E+00-4.48046831E-06 1.69962536E-08 3 +-2.67708030E-11 1.48927452E-14 1.20947990E+04 7.49816581E+00 1.28402035E+04 4 +I2 TPIS89I 2. 0. 0. 0.G 200.000 6000.000 253.80894 1 + 4.56588102E+00-3.42229361E-04 4.84410977E-07-1.42632157E-10 1.14951099E-14 2 + 6.16085432E+03 5.41958286E+00 3.87234634E+00 3.64265414E-03-7.95349191E-06 3 + 7.82149773E-09-2.80608071E-12 6.24706424E+03 8.49410267E+00 7.50737217E+03 4 +K L 4/93K 1. 0. 0. 0.G 200.000 6000.000 39.09830 1 + 2.26026721E+00 5.62341179E-04-4.48551838E-07 1.36243498E-10-1.02926268E-14 2 + 1.00348812E+04 6.31568201E+00 2.50000712E+00-7.25113166E-08 2.59068481E-10 3 +-3.79460911E-13 1.93210641E-16 9.95880307E+03 5.04054517E+00 1.07041786E+04 4 +K+ J12/83K 1.E -1. 0. 0.G 298.150 6000.000 39.09775 1 + 2.50000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 6.10751051E+04 4.34740449E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 6.10751051E+04 4.34740449E+00 6.18204801E+04 4 +KBO2 J 6/71K 1.B 1.O 2. 0.G 300.000 5000.000 81.90810 1 + 7.55025080E+00 2.56618230E-03-1.06715660E-06 1.98518850E-10-1.37041680E-14 2 +-8.36538340E+04-8.49270000E+00 4.39678010E+00 1.21692020E-02-1.18042180E-05 3 + 5.13165510E-09-6.59327200E-13-8.28270120E+04 7.57324310E+00-8.10696887E+04 4 +KCN J 3/66K 1.C 1.N 1. 0.G 300.000 5000.000 65.11604 1 + 5.80071200E+00 1.72007860E-03-7.07910740E-07 1.31992470E-10-9.19083230E-15 2 + 7.72726280E+03-3.15883419E+00 5.08107110E+00 5.52659560E-03-9.11571210E-06 3 + 8.44888170E-09-3.00515480E-12 7.86621610E+03 1.86346868E-01 9.56151829E+03 4 +KCL J 3/66K 1.CL 1. 0. 0.G 300.000 5000.000 74.55100 1 + 4.46367330E+00 1.22292070E-04-9.17192100E-09 9.26482420E-13-1.04079170E-17 2 +-2.71731330E+04 3.24808995E+00 3.99085690E+00 2.10891690E-03-3.18365300E-06 3 + 2.25253080E-09-5.90941790E-13-2.70801840E+04 5.51200445E+00-2.58205302E+04 4 +KF J 6/69K 1.F 1. 0. 0.G 300.000 5000.000 58.09670 1 + 4.40407000E+00 1.78337250E-04-3.60937970E-08 5.88395870E-12-3.46940460E-16 2 +-4.06558890E+04 2.03109585E+00 3.51560660E+00 3.78684220E-03-5.58649950E-06 3 + 3.77514380E-09-9.39242180E-13-4.04760790E+04 6.31338545E+00-3.93019270E+04 4 +KF2- J12/68K 1.F 2.E 1. 0.G 300.000 5000.000 77.09565 1 + 7.25816380E+00 2.67035570E-04-1.13846300E-07 2.14076850E-11-1.48270700E-15 2 +-8.57808390E+04-1.01032783E+01 5.25075730E+00 8.63837180E-03-1.34036730E-05 3 + 9.41408320E-09-2.46826020E-12-8.53839710E+04-4.77224713E-01-8.35354910E+04 4 +KH J 3/63K 1.H 1. 0. 0.G 300.000 5000.000 40.10624 1 + 3.96033860E+00 7.21903230E-04-2.69187150E-07 5.26173000E-11-3.78726830E-15 2 + 1.35018370E+04 8.55345083E-01 2.81577560E+00 3.98710600E-03-3.34105480E-06 3 + 8.86029420E-10 1.14028470E-13 1.38058380E+04 6.72517899E+00 1.47948627E+04 4 +KO J12/67K 1.O 1. 0. 0.G 300.000 5000.000 55.09770 1 + 4.42447780E+00 1.99361550E-04-3.71288370E-08 7.13083000E-12-5.03696870E-16 2 + 7.20523310E+03 3.30766849E+00 3.74107780E+00 3.12420170E-03-4.80200390E-06 3 + 3.46606050E-09-9.35997910E-13 7.33687140E+03 6.56692389E+00 8.55511701E+03 4 +KO- J12/67K 1.O 1.E 1. 0.G 300.000 5000.000 55.09825 1 + 4.42010840E+00 2.01242660E-04-3.93309960E-08 7.55985110E-12-5.34422750E-16 2 +-1.79561090E+04 1.92000408E+00 3.70836600E+00 3.23764800E-03-4.96905000E-06 3 + 3.57288460E-09-9.60802680E-13-1.78186070E+04 5.31662588E+00-1.66063485E+04 4 +KOH J12/70K 1.O 1.H 1. 0.G 300.000 5000.000 56.10564 1 + 5.64009490E+00 1.25102260E-03-3.49845470E-07 4.45669930E-11-2.08702790E-15 2 +-2.96987320E+04-4.04365464E+00 4.07334410E+00 9.72179450E-03-1.59888040E-05 3 + 1.21483530E-08-3.37093420E-12-2.95065580E+04 2.93540136E+00-2.79788313E+04 4 +KOH+ J12/71K 1.O 1.H 1.E -1.G 300.000 5000.000 56.10509 1 + 5.68061400E+00 1.21209510E-03-3.34471170E-07 4.17279320E-11-1.87939130E-15 2 + 5.81676020E+04-2.55415137E+00 4.43251670E+00 8.46316250E-03-1.42478550E-05 3 + 1.11066250E-08-3.15636120E-12 5.82926320E+04 2.87334573E+00 5.98849275E+04 4 +K2 J12/83K 2. 0. 0. 0.G 200.000 6000.000 78.19660 1 + 6.94866371E+00-3.60468319E-03 1.17553193E-06-1.74220367E-10 9.70302874E-15 2 + 1.26044349E+04-9.31939051E+00 4.50665127E+00-4.35676221E-04 3.26618741E-06 3 +-4.17835102E-09 1.19618367E-12 1.35287953E+04 4.37318917E+00 1.48742534E+04 4 +K2C2N2 J 3/66K 2.C 2.N 2. 0.G 300.000 5000.000 130.23208 1 + 1.26257540E+01 3.41239960E-03-1.40348880E-06 2.61563960E-10-1.82068650E-14 2 +-4.97536140E+03-2.81538911E+01 1.11330580E+01 1.15163620E-02-1.94765330E-05 3 + 1.81698590E-08-6.46472520E-12-4.69806930E+03-2.12679591E+01-1.00610098E+03 4 +K2CL2 J 3/66K 2.CL 2. 0. 0.G 300.000 5000.000 149.10200 1 + 9.90410690E+00 1.11797070E-04-5.03911970E-08 9.99346140E-12-7.27030090E-16 2 +-7.72723300E+04-1.40902820E+01 8.70679740E+00 6.01540470E-03-1.13039390E-05 3 + 9.66208140E-09-3.10556570E-12-7.70676960E+04-8.53754725E+00-7.42866401E+04 4 +K2F2 J 6/69K 2.F 2. 0. 0.G 300.000 5000.000 116.19341 1 + 9.81480960E+00 2.04530810E-04-8.70716650E-08 1.63372270E-11-1.12872560E-15 2 +-1.06759870E+05-1.76418030E+01 7.83295040E+00 8.92408310E-03-1.47198520E-05 3 + 1.09824690E-08-3.07217200E-12-1.06387520E+05-8.24238281E+00-1.03765274E+05 4 +K2O2H2 J12/70K 2.O 2.H 2. 0.G 300.000 5000.000 112.21128 1 + 9.50977220E+00 5.41670660E-03-1.92235320E-06 3.18660660E-10-2.01525080E-14 2 +-8.20483520E+04-1.68125059E+01 6.91905960E+00 1.03007030E-02-2.51732960E-07 3 +-7.74500140E-09 4.07960410E-12-8.12605480E+04-2.97285644E+00-7.87554000E+04 4 +K2SO4 J 6/78K 2.S 1.O 4. 0.G 300.000 5000.000 174.26020 1 + 1.53741080E+01 4.10561390E-03-1.81489350E-06 3.54972430E-10-2.55587540E-14 2 +-1.36953290E+05-4.61438154E+01 3.47585200E+00 4.87732370E-02-6.84200800E-05 3 + 4.68863160E-08-1.27210820E-11-1.34280850E+05 1.23448286E+01-1.31594543E+05 4 +Kr L10/90KR 1. 0. 0. 0.G 200.000 6000.000 83.80000 1 + 2.50000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-7.45375000E+02 5.49095651E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-7.45375000E+02 5.49095651E+00 0.00000000E+00 4 +Kr+ L10/92KR 1.E -1. 0. 0.G 298.150 6000.000 83.79945 1 + 2.18968725E+00 4.63775689E-04-1.29507482E-07 1.31158688E-11-3.84977987E-16 2 + 1.62583110E+05 8.62427688E+00 2.48153546E+00 1.49864676E-04-4.15576590E-07 3 + 4.40237547E-10-1.19374746E-13 1.62460592E+05 6.95257998E+00 1.63204264E+05 4 +Li J12/83LI 1. 0. 0. 0.G 200.000 6000.000 6.94100 1 + 2.50413107E+00 3.45604704E-05-6.44790018E-08 2.75752966E-11-1.78783935E-15 2 + 1.84074474E+04 2.40802074E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 1.84139020E+04 2.44762297E+00 1.91592770E+04 4 +Li+ J12/83LI 1.E -1. 0. 0.G 298.150 6000.000 6.94045 1 + 2.50000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 8.17271940E+04 1.75435754E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 8.17271940E+04 1.75435754E+00 8.24725690E+04 4 +LiALF4 J12/79LI 1.AL 1.F 4. 0.G 300.000 5000.000 109.91615 1 + 1.40377420E+01 2.24826420E-03-1.00100020E-06 1.96702490E-10-1.42088860E-14 2 +-2.27627570E+05-4.23601480E+01 2.54034210E+00 5.19858810E-02-8.61880310E-05 3 + 6.74968160E-08-2.03675090E-11-2.25357670E+05 1.25719320E+01-2.22927352E+05 4 +LiBO2 J 6/71LI 1.B 1.O 2. 0.G 300.000 5000.000 49.75080 1 + 7.42660960E+00 2.70437570E-03-1.12847410E-06 2.10623980E-10-1.45849090E-14 2 +-8.03702850E+04-1.06007918E+01 3.74354740E+00 1.44752570E-02-1.52096880E-05 3 + 7.41365410E-09-1.22421910E-12-7.94377560E+04 8.01202564E+00-7.77985412E+04 4 +LiCL J 6/62LI 1.CL 1. 0. 0.G 300.000 5000.000 42.39370 1 + 4.27121430E+00 3.14002910E-04-1.01231300E-07 1.84518530E-11-1.23987310E-15 2 +-2.48844420E+04 1.04172158E+00 2.99069060E+00 5.03386420E-03-6.56719790E-06 3 + 3.80501600E-09-7.61174550E-13-2.46031820E+04 7.32818448E+00-2.35386288E+04 4 +LiF J12/68LI 1.F 1. 0. 0.G 300.000 5000.000 25.93940 1 + 4.04302480E+00 5.70410540E-04-2.14541440E-07 4.06090130E-11-2.83579200E-15 2 +-4.22993180E+04 6.97695467E-01 2.85288690E+00 3.95327810E-03-3.17249850E-06 3 + 4.32443970E-10 3.70556670E-13-4.19872650E+04 6.79102887E+00-4.09879652E+04 4 +LiFO J 9/65LI 1.F 1.O 1. 0.G 300.000 5000.000 41.93880 1 + 5.99261090E+00 1.11392000E-03-4.78884930E-07 9.10683320E-11-6.38491230E-15 2 +-1.31009890E+04-5.33660329E+00 2.50017900E+00 1.26617170E-02-1.41575890E-05 3 + 6.45063740E-09-7.42614310E-13-1.22655340E+04 1.21440182E+01-1.10700161E+04 4 +LiF2- J12/68LI 1.F 2.E 1. 0.G 300.000 5000.000 44.93835 1 + 6.34485900E+00 1.25712720E-03-5.35228300E-07 1.01130250E-10-7.05817440E-15 2 +-8.76678900E+04-9.29840285E+00 3.47181360E+00 1.06367130E-02-1.17776460E-05 3 + 5.67654870E-09-8.46598400E-13-8.69631110E+04 5.14092795E+00-8.55484576E+04 4 +LiH J 9/67LI 1.H 1. 0. 0.G 300.000 5000.000 7.94894 1 + 3.58842970E+00 1.07276910E-03-4.01945880E-07 7.38285570E-11-4.92696440E-15 2 + 1.57176250E+04-3.75038965E-01 3.42094860E+00-6.80673660E-04 5.65273810E-06 3 +-6.21803480E-09 2.15317550E-12 1.58849450E+04 1.06574194E+00 1.69133172E+04 4 +LiN J12/66LI 1.N 1. 0. 0.G 300.000 5000.000 20.94774 1 + 4.22580770E+00 3.96671870E-04-1.24939930E-07 2.31747590E-11-1.58519170E-15 2 + 3.89169520E+04 7.00851481E-01 2.88943000E+00 5.22125340E-03-6.59690210E-06 3 + 3.72889970E-09-7.23551430E-13 3.92163230E+04 7.28887145E+00 4.02586191E+04 4 +LiO J 3/64LI 1.O 1. 0. 0.G 300.000 5000.000 22.94040 1 + 4.18762050E+00 4.11865740E-04-1.45202960E-07 2.72530700E-11-1.88647750E-15 2 + 8.77952590E+03 1.23142599E+00 2.83890070E+00 5.15386260E-03-6.30823820E-06 3 + 3.41143850E-09-6.16313430E-13 9.08843140E+03 7.91311789E+00 1.01146405E+04 4 +LiO- J12/67LI 1.O 1.E 1. 0.G 300.000 5000.000 22.94095 1 + 4.18102170E+00 4.17850000E-04-1.50248450E-07 2.83977320E-11-1.97891810E-15 2 +-9.38497020E+03-1.42392337E-01 2.85158660E+00 5.01698800E-03-5.95474750E-06 3 + 3.03994510E-09-4.78729690E-13-9.07780760E+03 6.45947067E+00-8.05144594E+03 4 +LiOH J 6/71LI 1.O 1.H 1. 0.G 300.000 5000.000 23.94834 1 + 5.50969570E+00 1.36854640E-03-3.94414690E-07 5.23321950E-11-2.59586760E-15 2 +-2.98992310E+04-6.50701600E+00 3.34623000E+00 1.17872530E-02-1.82526570E-05 3 + 1.30856140E-08-3.43287420E-12-2.95646360E+04 3.46123330E+00-2.81800732E+04 4 +LiOH+ J12/71LI 1.O 1.H 1.E -1.G 300.000 5000.000 23.94779 1 + 5.53292690E+00 1.37779310E-03-4.06593090E-07 5.55909100E-11-2.86046240E-15 2 + 9.18885790E+04-4.99359268E+00 3.63797390E+00 1.08971540E-02-1.72296700E-05 3 + 1.26679270E-08-3.41652590E-12 9.21611930E+04 3.63776092E+00 9.36013974E+04 4 +LiON J 9/66LI 1.O 1.N 1. 0.G 300.000 5000.000 36.94714 1 + 5.81234960E+00 1.28706260E-03-5.46677100E-07 1.03149870E-10-7.19304470E-15 2 + 1.96923020E+04-4.34470559E+00 3.67011640E+00 7.25681770E-03-5.86811460E-06 3 + 1.16283120E-09 4.27041220E-13 2.02717030E+04 6.68249511E+00 2.16391463E+04 4 +Li2 J12/83LI 2. 0. 0. 0.G 200.000 6000.000 13.88200 1 + 5.58393935E+00-7.87699402E-04-3.84878120E-07 2.91133039E-10-3.39438475E-14 2 + 2.40394686E+04-8.50679127E+00 3.21590490E+00 7.09389748E-03-1.50723370E-05 3 + 1.48684882E-08-5.43740256E-12 2.47988772E+04 3.80489004E+00 2.59666535E+04 4 +Li2CL2 J 6/62LI 2.CL 2. 0. 0.G 300.000 5000.000 84.78740 1 + 9.52456140E+00 5.24588340E-04-2.23379490E-07 4.19511140E-11-2.90213060E-15 2 +-7.49902630E+04-2.00316716E+01 5.28013510E+00 1.83841000E-02-2.87694480E-05 3 + 2.03133590E-08-5.34332470E-12-7.41600030E+04 2.79279422E-01-7.19851709E+04 4 +Li2F2 J12/68LI 2.F 2. 0. 0.G 300.000 5000.000 51.87881 1 + 8.95666360E+00 1.17192690E-03-5.09905040E-07 9.79175340E-11-6.92156020E-15 2 +-1.16372280E+05-2.08863312E+01 2.40075080E+00 2.70662370E-02-3.92561800E-05 3 + 2.57225990E-08-6.22372250E-12-1.15010910E+05 1.08917788E+01-1.13391048E+05 4 +Li2O J 3/64LI 2.O 1. 0. 0.G 300.000 5000.000 29.88140 1 + 6.61987480E+00 9.68794480E-04-4.14905060E-07 7.86373370E-11-5.49692920E-15 2 +-2.22553250E+04-1.08215590E+01 3.97217080E+00 9.24609210E-03-9.35961490E-06 3 + 3.46391600E-09-7.56588800E-14-2.15969880E+04 2.55230409E+00-2.00776073E+04 4 +Li2O2 J 3/64LI 2.O 2. 0. 0.G 300.000 5000.000 45.88080 1 + 9.52752600E+00 5.30210130E-04-2.30058620E-07 4.40308310E-11-3.10187020E-15 2 +-3.21824840E+04-2.18591120E+01 5.53752320E+00 1.73442230E-02-2.71979710E-05 3 + 1.93056290E-08-5.12079570E-12-3.14020440E+04-2.76831291E+00-2.91846934E+04 4 +Li2O2H2 J 6/71LI 2.O 2.H 2. 0.G 300.000 5000.000 47.89668 1 + 8.99361290E+00 6.00396330E-03-2.18101810E-06 3.68887260E-10-2.37380140E-14 2 +-8.88441500E+04-2.13586495E+01 2.86466370E+00 2.52373090E-02-2.26327910E-05 3 + 7.46327130E-09 2.29254980E-13-8.73388110E+04 9.54312960E+00-8.55480943E+04 4 +Li2SO4 J12/78LI 2.S 1.O 4. 0.G 300.000 5000.000 109.94560 1 + 1.49295950E+01 4.60974740E-03-2.03795560E-06 3.98625790E-10-2.87030300E-14 2 +-1.30635280E+05-4.91664911E+01 7.11457250E-01 5.94511790E-02-8.63634900E-05 3 + 6.11710870E-08-1.70989230E-11-1.27508420E+05 2.03803279E+01-1.25304083E+05 4 +Li3CL3 J 6/62LI 3.CL 3. 0. 0.G 300.000 5000.000 127.18110 1 + 1.43194400E+01 1.88540070E-03-8.19783300E-07 1.57354940E-10-1.11194720E-14 2 +-1.25588510E+05-4.27110226E+01 4.57459590E+00 3.97492390E-02-5.65082130E-05 3 + 3.62941450E-08-8.57847000E-12-1.23533510E+05 4.68059658E+00-1.20834437E+05 4 +Li3F3 J12/68LI 3.F 3. 0. 0.G 300.000 5000.000 77.81821 1 + 1.43644220E+01 1.82854980E-03-7.92211590E-07 1.51545290E-10-1.06756730E-14 2 +-1.87237360E+05-4.50609130E+01 4.64139750E+00 3.98786960E-02-5.72489910E-05 3 + 3.71935440E-08-8.92301250E-12-1.85198520E+05 2.16235967E+00-1.82478706E+05 4 +Mg J 9/83MG 1. 0. 0. 0.G 200.000 6000.000 24.30500 1 + 2.31664484E+00 3.65866339E-04-2.33227803E-07 5.37117570E-11-2.99513065E-15 2 + 1.70119233E+04 4.63449516E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 1.69465876E+04 3.63433014E+00 1.76919626E+04 4 +Mg+ J 9/83MG 1.E -1. 0. 0.G 298.150 6000.000 24.30445 1 + 2.50416574E+00-9.19340966E-06 6.96171478E-09-2.17494938E-12 2.40903346E-16 2 + 1.06420941E+05 4.30504494E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 1.06422335E+05 4.32744355E+00 1.07167710E+05 4 +MgBr J 6/75MG 1.BR 1. 0. 0.G 300.000 5000.000 104.20900 1 + 4.40998540E+00 1.60217360E-04-4.15012230E-08 5.93703420E-12-4.82315730E-17 2 +-5.59619090E+03 4.22960309E+00 3.51072850E+00 4.45285100E-03-8.01240750E-06 3 + 6.70669000E-09-2.12327180E-12-5.43682570E+03 8.43148999E+00-4.25072458E+03 4 +MgBr2 J 6/74MG 1.BR 2. 0. 0.G 300.000 5000.000 184.11300 1 + 7.32151000E+00 2.06437250E-04-9.24892080E-08 1.82558380E-11-1.32311700E-15 2 +-3.86713040E+04-5.67846591E+00 5.71391020E+00 7.73216170E-03-1.38657930E-05 3 + 1.14779000E-08-3.60578840E-12-3.83794830E+04 1.86860229E+00-3.64337335E+04 4 +MgCL J 3/66MG 1.CL 1. 0. 0.G 300.000 5000.000 59.75770 1 + 4.37758330E+00 1.88341780E-04-5.44885920E-08 9.94810310E-12-6.69496110E-16 2 +-6.58308260E+03 2.98938866E+00 3.38005340E+00 4.28133890E-03-6.44573330E-06 3 + 4.44722910E-09-1.14217270E-12-6.38265600E+03 7.78898816E+00-5.23329928E+03 4 +MgCL+ J 6/68MG 1.CL 1.E -1. 0.G 300.000 5000.000 59.75715 1 + 6.35123440E+00-3.79671900E-03 2.47129450E-06-5.08236530E-10 3.36726250E-14 2 + 7.64808790E+04-8.29036227E+00 3.60122300E+00 3.47918590E-03-5.13531430E-06 3 + 3.44463370E-09-8.38482060E-13 7.73146880E+04 6.13385933E+00 7.85040728E+04 4 +MgCLF J 3/66MG 1.CL 1.F 1. 0.G 200.000 6000.000 78.75610 1 + 6.57082252E+00 4.48876208E-04-1.77994819E-07 3.06318205E-11-1.91554544E-15 2 +-7.05235977E+04-5.83555414E+00 3.15704293E+00 1.64534790E-02-3.01126869E-05 3 + 2.57974606E-08-8.42487547E-12-6.98910040E+04 1.02255402E+01-6.84374665E+04 4 +MgCL2 J12/69MG 1.CL 2. 0. 0.G 300.000 5000.000 95.21040 1 + 7.24019130E+00 2.88562390E-04-1.24011870E-07 2.35271010E-11-1.64432050E-15 2 +-4.94423260E+04-8.18090146E+00 5.40955290E+00 7.72062810E-03-1.16200940E-05 3 + 7.94178890E-09-2.02525020E-12-4.90705370E+04 6.47158084E-01-4.72024455E+04 4 +MgF J 6/76MG 1.F 1. 0. 0.G 300.000 5000.000 43.30340 1 + 4.19221190E+00 4.03626440E-04-1.50976310E-07 2.81692210E-11-1.82758920E-15 2 +-2.98137100E+04 2.43696211E+00 2.65707520E+00 6.68261350E-03-1.03311560E-05 3 + 7.68717660E-09-2.22450570E-12-2.94948900E+04 9.85508041E+00-2.84827958E+04 4 +MgF+ J12/75MG 1.F 1.E -1. 0.G 300.000 5000.000 43.30285 1 + 4.36810570E+00 4.11759660E-03-2.93947970E-06 7.27118430E-10-5.98448020E-14 2 + 5.95360000E+04-1.34577794E+00 3.43876540E+00 2.22526540E-03-5.46212020E-06 3 + 1.40842760E-08-8.07269060E-12 6.05156660E+04 5.77835456E+00 6.16156042E+04 4 +MgF2 J 6/75MG 1.F 2. 0. 0.G 300.000 5000.000 62.30181 1 + 6.36420730E+00 7.26278270E-04-3.22800460E-07 6.33636660E-11-4.57384370E-15 2 +-8.94644290E+04-5.91513079E+00 3.34790580E+00 1.31152970E-02-2.05416070E-05 3 + 1.53957840E-08-4.49090410E-12-8.88388740E+04 8.65190211E+00-8.74109410E+04 4 +MgF2+ J12/75MG 1.F 2.E -1. 0.G 300.000 5000.000 62.30126 1 + 6.89106730E+00 7.17812830E-04-3.29411720E-07 6.58811280E-11-4.58732280E-15 2 + 6.89931450E+04-8.71301395E+00 3.52128840E+00 1.52695560E-02-2.51800890E-05 3 + 1.96354990E-08-5.90549190E-12 6.96583880E+04 7.39020945E+00 7.12004950E+04 4 +MgH J12/66MG 1.H 1. 0. 0.G 300.000 5000.000 25.31294 1 + 3.46385910E+00 1.24040550E-03-5.02782100E-07 9.81188340E-11-6.61830680E-15 2 + 1.91763100E+04 2.99775186E+00 3.51023970E+00-1.23683520E-03 6.42469980E-06 3 +-6.60548460E-09 2.20036250E-12 1.92938930E+04 3.37365416E+00 2.03302445E+04 4 +MgI J12/74MG 1.I 1. 0. 0.G 200.000 6000.000 151.20947 1 + 4.41245599E+00 1.78910914E-04-5.22986679E-08 9.68713486E-12-4.67113786E-16 2 + 1.62581907E+03 5.16451018E+00 3.39596606E+00 6.11494866E-03-1.31544146E-05 3 + 1.27259311E-08-4.53414297E-12 1.76933628E+03 9.69586508E+00 2.96042364E+03 4 +MgI2 J12/74MG 1.I 2. 0. 0.G 300.000 5000.000 278.11394 1 + 7.37111620E+00 1.49419540E-04-6.70677380E-08 1.32575590E-11-9.62005020E-16 2 +-2.15119230E+04-3.93845663E+00 6.10814260E+00 6.14621180E-03-1.11665270E-05 3 + 9.32665250E-09-2.94871660E-12-2.12863230E+04 1.97126687E+00-1.92736169E+04 4 +MgN J 3/64MG 1.N 1. 0. 0.G 300.000 5000.000 38.31174 1 + 4.22144170E+00 3.64892400E-04-1.29957300E-07 2.44189400E-11-1.69177590E-15 2 + 3.33829310E+04 2.73205196E+00 2.88945490E+00 5.17571750E-03-6.58490160E-06 3 + 3.72189330E-09-7.23059640E-13 3.36810580E+04 9.29758946E+00 3.47214301E+04 4 +MgO J12/74MG 1.O 1. 0. 0.G 300.000 5000.000 40.30440 1 + 7.94944280E+00-1.26407550E-03-2.40097300E-07 1.62732770E-10-1.76119090E-14 2 + 3.49443840E+03-2.18011730E+01 5.33534970E+00-1.33391340E-02 3.56675260E-05 3 +-2.60574710E-08 4.98411960E-12 5.73155730E+03-2.13277681E+00 6.99538853E+03 4 +MgOH J12/75MG 1.O 1.H 1. 0.G 300.000 5000.000 41.31234 1 + 5.26714240E+00 1.67827200E-03-5.43091730E-07 8.25633490E-11-4.71335130E-15 2 +-2.15093360E+04-3.39516556E+00 1.76243570E+00 1.91670050E-02-3.32193180E-05 3 + 2.71589780E-08-8.38892750E-12-2.09491820E+04 1.27344525E+01-1.98155784E+04 4 +MgOH+ J12/75MG 1.O 1.H 1.E -1.G 300.000 5000.000 41.31179 1 + 5.28244790E+00 1.66404370E-03-5.40166510E-07 8.34678240E-11-5.00361680E-15 2 + 6.85958160E+04-4.15038863E+00 1.78314210E+00 1.92285270E-02-3.35031430E-05 3 + 2.74913640E-08-8.51510070E-12 6.91505840E+04 1.19305236E+01 7.02911854E+04 4 +MgO2H2 J12/75MG 1.O 2.H 2. 0.G 300.000 5000.000 58.31968 1 + 8.51783840E+00 3.37913800E-03-1.10220330E-06 1.71111790E-10-1.03022860E-14 2 +-7.16267310E+04-1.76294649E+01 1.54947500E+00 3.82704800E-02-6.65093280E-05 3 + 5.45362940E-08-1.68913380E-11-7.05167540E+04 1.44170361E+01-6.88415815E+04 4 +MgS J 9/77MG 1.S 1. 0. 0.G 300.000 5000.000 56.37100 1 + 1.03585650E+01-5.53070850E-03 2.09511990E-06-3.52248380E-10 2.22827360E-14 2 + 1.33293460E+04-3.31905223E+01 7.80892150E+00-3.24935950E-02 9.25172570E-05 3 +-9.09652030E-08 2.97256310E-11 1.59322900E+04-1.10479053E+01 1.74679365E+04 4 +Mg2 J 9/83MG 2. 0. 0. 0.G 200.000 6000.000 48.61000 1 + 1.55499308E+00 3.13771932E-03-3.15497401E-06 1.11815199E-09-1.08539001E-13 2 + 3.41094885E+04 1.94547704E+01 5.66548917E+00-1.81207983E-02 4.05706233E-05 3 +-4.00720091E-08 1.45040463E-11 3.34280753E+04 5.33095711E-01 3.45979248E+04 4 +Mg2F4 J12/75MG 2.F 4. 0. 0.G 300.000 5000.000 124.60361 1 + 1.46720160E+01 1.52993180E-03-6.83471170E-07 1.34604690E-10-9.73833980E-15 2 +-2.11437660E+05-4.42782440E+01 4.22990530E+00 4.92908490E-02-8.64496720E-05 3 + 7.04593710E-08-2.18871100E-11-2.09492990E+05 5.00323615E+00-2.06675889E+05 4 +MoO3 TPIS82MO 1.O 3. 0. 0.G 298.150 5000.000 143.93820 1 + 8.55990790E+00 1.51369070E-03-6.13732600E-07 1.07588900E-10-6.22775550E-15 2 +-4.67652700E+04-1.67028250E+01 3.65431210E+00 1.44909920E-02-7.66813900E-06 3 +-6.09846400E-09 5.18258090E-12-4.54830940E+04 8.50521889E+00-4.38287210E+04 4 +Mo2O6 TPIS82MO 2.O 6. 0. 0.G 298.150 5000.000 287.87640 1 + 1.39233320E+01 1.29087490E-02-7.39293860E-06 1.74541090E-09-1.44106680E-13 2 +-1.42928310E+05-3.64486140E+01 7.75467210E+00 3.26250640E-02-1.66599060E-05 3 +-1.50396000E-08 1.23603580E-11-1.41833380E+05-6.45092731E+00-1.38247070E+05 4 +Mo3O9 TPIS82MO 3.O 9. 0. 0.G 298.150 5000.000 431.81460 1 + 2.22622990E+01 1.85849670E-02-1.05893570E-05 2.49267520E-09-2.05425360E-13 2 +-2.36200380E+05-7.10881860E+01 1.35774240E+01 4.53893100E-02-2.13059540E-05 3 +-2.28677660E-08 1.77523270E-11-2.34596880E+05-2.85771390E+01-2.28762570E+05 4 +Mo4O12 TPIS82MO 4.O 12. 0. 0.G 298.150 5000.000 575.75280 1 + 3.04317470E+01 2.47326460E-02-1.41185490E-05 3.32712920E-09-2.74390160E-13 2 +-3.25903630E+05-1.07280337E+02 1.87274780E+01 6.11594990E-02-2.91419130E-05 3 +-3.06580500E-08 2.40118200E-11-3.23765940E+05-5.00883840E+01-3.15779310E+05 4 +Mo5O15 TPIS82MO 5.O 15. 0. 0.G 298.150 5000.000 719.69100 1 + 3.86225430E+01 3.07427420E-02-1.75360470E-05 4.13062300E-09-3.40557710E-13 2 +-4.13241560E+05-1.43736757E+02 2.38870540E+01 7.61410000E-02-3.51747290E-05 3 +-3.98648650E-08 3.06311230E-11-4.10521060E+05-7.16041770E+01-4.00401060E+05 4 +N L 6/88N 1. 0. 0. 0.G 200.000 6000.000 14.00674 1 + 2.41594293E+00 1.74890600E-04-1.19023667E-07 3.02262387E-11-2.03609790E-15 2 + 5.61337748E+04 4.64960986E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 5.61046378E+04 4.19390932E+00 5.68500128E+04 4 +N+ L 7/88N 1.E -1. 0. 0.G 298.150 6000.000 14.00619 1 + 2.51112967E+00 3.46441751E-06-1.59426938E-08 7.24865663E-12-6.44501426E-16 2 + 2.25624340E+05 4.92767661E+00 2.80269445E+00-1.44758911E-03 2.77118380E-06 3 +-2.40187352E-09 7.80839931E-13 2.25575244E+05 3.57877835E+00 2.26366632E+05 4 +N- L 7/88N 1.E 1. 0. 0.G 298.150 6000.000 14.00729 1 + 2.50897099E+00-9.58412751E-06 3.85210062E-09-6.68935998E-13 4.20991172E-17 2 + 5.62083017E+04 4.94953202E+00 2.62723403E+00-5.93445018E-04 1.12028916E-06 3 +-9.62585603E-10 3.11119557E-13 5.61880871E+04 4.40111176E+00 5.69531625E+04 4 +NCO L12/89N 1.C 1.O 1. 0.G 200.000 6000.000 42.01714 1 + 5.15255717E+00 2.30945594E-03-8.83699519E-07 1.48525346E-10-9.08857905E-15 2 + 1.94963750E+04-2.56406350E+00 2.75452392E+00 9.23008037E-03-9.28006629E-06 3 + 5.62521381E-09-1.61200144E-12 2.01842954E+04 9.85368773E+00 2.13441716E+04 4 +ND J 6/77N 1.D 1. 0. 0.G 298.150 5000.000 16.02084 1 + 2.82970340E+00 1.65841750E-03-6.32873330E-07 1.14776850E-10-7.83185840E-15 2 + 4.42559510E+04 6.00662882E+00 3.72064880E+00-1.53418480E-03 3.18774260E-06 3 +-1.50914010E-09 9.71261140E-14 4.40727560E+04 1.64955672E+00 4.51390710E+04 4 +ND2 J 6/77N 1.D 2. 0. 0.G 298.150 5000.000 18.03494 1 + 3.35153910E+00 3.37631620E-03-1.32134570E-06 2.68006790E-10-2.08101740E-14 2 + 2.10777490E+04 4.37387975E+00 4.02697800E+00-1.40851280E-03 7.77658150E-06 3 +-6.49675750E-09 1.75541700E-12 2.10980280E+04 1.75484295E+00 2.22927630E+04 4 +ND3 J 6/77N 1.D 3. 0. 0.G 298.150 5000.000 20.04905 1 + 3.19615660E+00 6.73117580E-03-2.64234000E-06 4.76308680E-10-3.28048280E-14 2 +-8.39665270E+03 4.16290718E+00 2.94278390E+00 5.10352910E-03 2.73928210E-06 3 +-4.68476620E-09 1.62766740E-12-8.16515630E+03 6.15522038E+00-7.04511980E+03 4 +NF TPIS89N 1.F 1. 0. 0.G 200.000 6000.000 33.00514 1 + 4.06042292E+00 3.50654850E-04-6.95721815E-08 1.45925454E-11-1.56372401E-15 2 + 2.66711982E+04 2.08774805E+00 3.59927999E+00-2.18190788E-03 1.14106853E-05 3 +-1.40068494E-08 5.53332638E-12 2.69702525E+04 5.35573603E+00 2.80221438E+04 4 +NF2 TPIS78N 1.F 2. 0. 0.G 298.150 5000.000 52.00355 1 + 5.67109980E+00 1.52490640E-03-6.64320500E-07 1.29882090E-10-9.34891620E-15 2 + 2.17289180E+03-3.21733726E+00 2.18233810E+00 1.30700080E-02-1.51478870E-05 3 + 8.23364600E-09-1.68588640E-12 3.02632470E+03 1.42967360E+01 4.13964480E+03 4 +NF3 L12/86N 1.F 3. 0. 0.G 298.150 5000.000 71.00195 1 + 7.84199640E+00 2.69275920E-03-1.08013060E-06 2.12212560E-10-1.52881240E-14 2 +-1.86684320E+04-1.49708922E+01 3.47412870E-01 3.07504790E-02-4.25860860E-05 3 + 2.88432090E-08-7.70346550E-12-1.69875040E+04 2.18734938E+01-1.58399670E+04 4 +NH L11/89N 1.H 1. 0. 0.G 200.000 6000.000 15.01468 1 + 2.78372645E+00 1.32985886E-03-4.24785565E-07 7.83494425E-11-5.50451298E-15 2 + 4.21345163E+04 5.74084857E+00 3.49295037E+00 3.11795722E-04-1.48906628E-06 3 + 2.48167403E-09-1.03570916E-12 4.18942940E+04 1.84834974E+00 4.29408348E+04 4 +NH+ L 2/89N 1.H 1.E -1. 0.G 298.150 6000.000 15.01413 1 + 2.95918980E+00 1.34991719E-03-4.61487782E-07 8.26977666E-11-5.55758913E-15 2 + 1.99524505E+05 5.59978021E+00 4.61611136E+00-3.13435677E-03 2.91705130E-06 3 + 2.57384848E-10-7.31431347E-13 1.99085043E+05-2.92758460E+00 2.00347960E+05 4 +NHF TPIS78N 1.H 1.F 1. 0.G 298.150 5000.000 34.01308 1 + 3.70551560E+00 3.05928380E-03-1.19481890E-06 2.15320410E-10-1.44712850E-14 2 + 1.21713170E+04 5.63012846E+00 3.50790490E+00 1.46885700E-03 5.13893190E-06 3 +-7.07642930E-09 2.73156520E-12 1.23266210E+04 7.16280056E+00 1.34705930E+04 4 +NHF2 TPIS78N 1.H 1.F 2. 0.G 298.150 5000.000 53.01149 1 + 5.28756150E+00 4.63323300E-03-1.87737490E-06 3.46993030E-10-2.40367500E-14 2 +-1.44236330E+04-1.64462815E+00 2.20674810E+00 1.18774010E-02-5.50126930E-06 3 +-2.19112190E-09 1.97461810E-12-1.35221410E+04 1.45510312E+01-1.23881340E+04 4 +NH2 L12/89N 1.H 2. 0. 0.G 200.000 6000.000 16.02262 1 + 2.84768992E+00 3.14280035E-03-8.98641458E-07 1.30318284E-10-7.48812926E-15 2 + 2.18239049E+04 6.47165433E+00 4.20556857E+00-2.13561363E-03 7.26851301E-06 3 +-5.93069876E-09 1.80690978E-12 2.15352231E+04-1.46662770E-01 2.27475415E+04 4 +NH2F TPIS78N 1.H 2.F 1. 0.G 298.150 5000.000 35.02102 1 + 3.03168860E+00 6.42239370E-03-2.48327540E-06 4.43703310E-10-2.99811000E-14 2 +-1.03021670E+04 8.27719987E+00 3.64634270E+00-1.12299140E-03 1.71560860E-05 3 +-1.90333680E-08 6.73845950E-12-1.01750020E+04 6.55727107E+00-9.02048620E+03 4 +NH3 TPIS89N 1.H 3. 0. 0.G 200.000 6000.000 17.03056 1 + 2.71709692E+00 5.56856338E-03-1.76886396E-06 2.67417260E-10-1.52731419E-14 2 +-6.58451989E+03 6.09289837E+00 4.30177808E+00-4.77127330E-03 2.19341619E-05 3 +-2.29856489E-08 8.28992268E-12-6.74806394E+03-6.90644393E-01-5.52528050E+03 4 +NH2OH TPIS89N 1.H 3.O 1. 0.G 200.000 6000.000 33.02996 1 + 3.88112362E+00 8.15708719E-03-2.82615742E-06 4.37931330E-10-2.52724921E-14 2 +-7.58782727E+03 3.79156901E+00 3.21016076E+00 6.19671780E-03 1.10594913E-05 3 +-1.96668207E-08 8.82516311E-12-7.30912839E+03 7.93293640E+00-6.01358348E+03 4 +NH4+ TPIS89N 1.H 4.E -1. 0.G 298.150 6000.000 18.03795 1 + 1.31570311E+00 9.64926653E-03-3.29049595E-06 5.12045396E-10-2.98499060E-14 2 + 7.67277044E+04 1.20930981E+01 5.02209278E+00-1.17098960E-02 3.97600112E-05 3 +-3.69419871E-08 1.20264483E-11 7.63029754E+04-4.20522286E+00 7.75637944E+04 4 +NO TPIS89N 1.O 1. 0. 0.G 200.000 6000.000 30.00614 1 + 3.26071234E+00 1.19101135E-03-4.29122646E-07 6.94481463E-11-4.03295681E-15 2 + 9.92143132E+03 6.36900518E+00 4.21859896E+00-4.63988124E-03 1.10443049E-05 3 +-9.34055507E-09 2.80554874E-12 9.84509964E+03 2.28061001E+00 1.09770882E+04 4 +NO+ TPIS89N 1.O 1.E -1. 0.G 298.150 6000.000 30.00559 1 + 2.94587702E+00 1.40325260E-03-4.95503196E-07 7.95948973E-11-4.72076668E-15 2 + 1.18244340E+05 6.70644641E+00 3.69301231E+00-1.34229158E-03 2.67343395E-06 3 +-1.02609308E-09-6.95610492E-14 1.18103055E+05 3.09126698E+00 1.19166025E+05 4 +NOCL L12/86N 1.O 1.CL 1. 0.G 298.150 5000.000 65.45884 1 + 5.86956760E+00 9.32184760E-04-2.52355420E-07 8.09444930E-11-9.02037270E-15 2 + 4.37178100E+03-2.64405757E+00 3.84293630E+00 7.30757200E-03-9.14007260E-06 3 + 6.66117580E-09-2.05029050E-12 4.93648720E+03 7.74079403E+00 6.33842060E+03 4 +NOF TPIS78N 1.O 1.F 1. 0.G 298.150 5000.000 49.00454 1 + 4.98781620E+00 2.43822500E-03-1.11040450E-06 2.45413670E-10-1.88888130E-14 2 +-9.53283150E+03 4.59173349E-01 3.01678900E+00 9.40745900E-03-1.14103680E-05 3 + 7.75157000E-09-2.22328880E-12-9.04875930E+03 1.03043423E+01-7.81775470E+03 4 +NOF3 TPIS78N 1.O 1.F 3. 0.G 298.150 5000.000 87.00135 1 + 9.81602980E+00 3.54622150E-03-1.55212690E-06 3.01635030E-10-2.16229090E-14 2 +-2.60181200E+04-2.45950113E+01 1.57858830E-01 4.18848250E-02-6.27310050E-05 3 + 4.61904830E-08-1.34120260E-11-2.39304230E+04 2.24234237E+01-2.24910790E+04 4 +NO2 L 7/88N 1.O 2. 0. 0.G 200.000 6000.000 46.00554 1 + 4.88474429E+00 2.17241639E-03-8.28079020E-07 1.57477293E-10-1.05110549E-14 2 + 2.31648462E+03-1.17357075E-01 3.94403907E+00-1.58547444E-03 1.66578984E-05 3 +-2.04754478E-08 7.83503265E-12 2.89659865E+03 6.31196225E+00 4.11245173E+03 4 +NO2- TPIS89N 1.O 2.E 1. 0.G 298.150 6000.000 46.00609 1 + 5.05329280E+00 2.07555672E-03-8.70003077E-07 1.61074250E-10-1.03448062E-14 2 +-2.59043616E+04-1.54065063E+00 3.09783648E+00 3.70486312E-03 5.92938975E-06 3 +-1.09497307E-08 4.62721721E-12-2.51798339E+04 9.48237143E+00-2.40586126E+04 4 +NO2CL L12/86N 1.O 2.CL 1. 0.G 298.150 5000.000 81.45824 1 + 7.12026010E+00 3.18695570E-03-1.37798970E-06 2.66531630E-10-1.90437960E-14 2 +-1.06153470E+03-9.45476560E+00 2.55980390E+00 1.79693190E-02-2.02652550E-05 3 + 1.16991830E-08-2.78633720E-12 9.87906800E+01 1.35899582E+01 1.50341440E+03 4 +NO2F L12/86N 1.O 2.F 1. 0.G 298.150 5000.000 65.00394 1 + 6.71038200E+00 3.62401660E-03-1.56660230E-06 3.02666410E-10-2.16088660E-14 2 +-1.56110410E+04-8.88169601E+00 1.44668080E+00 2.08840580E-02-2.38855280E-05 3 + 1.39438940E-08-3.34025010E-12-1.42842970E+04 1.76606700E+01-1.31097730E+04 4 +NO3 J12/64N 1.O 3. 0. 0.G 200.000 6000.000 62.00494 1 + 7.48347734E+00 2.57772041E-03-1.00945831E-06 1.72314072E-10-1.07154015E-14 2 + 5.70919428E+03-1.41618155E+01 2.17359310E+00 1.04902697E-02 1.10472650E-05 3 +-2.81561854E-08 1.36583958E-11 7.39219877E+03 1.46022098E+01 8.55492386E+03 4 +NO3- TPIS89N 1.O 3.E 1. 0.G 298.150 6000.000 62.00549 1 + 6.88404739E+00 3.16062982E-03-1.23048782E-06 2.09257989E-10-1.29795471E-14 2 +-4.00548152E+04-1.17087097E+01 1.21258521E+00 1.71545193E-02-1.05270457E-05 3 +-1.16074097E-09 2.33114998E-12-3.84077713E+04 1.79933865E+01-3.73779731E+04 4 +NO3F L12/86N 1.O 3.F 1. 0.G 298.150 5000.000 81.00334 1 + 9.28947900E+00 4.60181370E-03-2.21870670E-06 4.51297580E-10-3.32406540E-14 2 +-1.64685160E+03-2.00889242E+01 2.03635710E+00 2.87840980E-02-3.48403410E-05 3 + 2.17601730E-08-5.64964360E-12 1.85068170E+02 1.64435428E+01 1.80409650E+03 4 +N2 TPIS78N 2. 0. 0. 0.G 200.000 6000.000 28.01348 1 + 2.95257626E+00 1.39690057E-03-4.92631691E-07 7.86010367E-11-4.60755321E-15 2 +-9.23948645E+02 5.87189252E+00 3.53100528E+00-1.23660987E-04-5.02999437E-07 3 + 2.43530612E-09-1.40881235E-12-1.04697628E+03 2.96747468E+00 0.00000000E+00 4 +N2+ TPIS89N 2.E -1. 0. 0.G 298.150 6000.000 28.01293 1 + 3.58661363E+00 2.53071949E-04 1.84778214E-07-4.55257223E-11 3.26818029E-15 2 + 1.80390994E+05 3.09584150E+00 3.77540711E+00-2.06459157E-03 4.75752301E-06 3 +-3.15664228E-09 6.70509973E-13 1.80481115E+05 2.69322186E+00 1.81551099E+05 4 +N2- J 9/77N 2.E 1. 0. 0.G 298.150 5000.000 28.01403 1 + 3.11567530E+00 1.45886880E-03-6.01731480E-07 1.13484230E-10-7.96585180E-15 2 + 1.68590580E+04 6.38985600E+00 3.88268480E+00-3.19244460E-03 8.52278380E-06 3 +-7.34037460E-09 2.20568150E-12 1.67969350E+04 3.11180520E+00 1.78744680E+04 4 +NCN L12/89N 2.C 1. 0. 0.G 200.000 6000.000 40.02448 1 + 5.73815514E+00 1.77244606E-03-6.85751131E-07 1.15711980E-10-7.07567907E-15 2 + 5.82214890E+04-6.30533665E+00 3.24134033E+00 8.50091346E-03-7.61608140E-06 3 + 3.64986585E-09-8.42551872E-13 5.89477370E+04 6.70956450E+00 6.02315091E+04 4 +cis-N2D2 J 6/77N 2.D 2. 0. 0.G 200.000 6000.000 32.04168 1 + 4.51455308E+00 5.18901318E-03-1.93684288E-06 3.20575967E-10-1.95208624E-14 2 + 2.30230396E+04-9.52662254E-01 3.87335899E+00-2.62328791E-03 2.63075819E-05 3 +-3.13008744E-08 1.18109999E-11 2.36948344E+04 4.74949160E+00 2.49092250E+04 4 +N2F2 L12/86N 2.F 2. 0. 0.G 298.150 5000.000 66.01029 1 + 7.66719230E+00 2.59466270E-03-1.13460230E-06 2.20352680E-10-1.57886580E-14 2 + 4.81399990E+03-1.28292913E+01 2.80589260E+00 1.92519670E-02-2.36977440E-05 3 + 1.46168610E-08-3.64516030E-12 5.99444190E+03 1.14841507E+01 7.50450950E+03 4 +N2F4 L12/86N 2.F 4. 0. 0.G 298.150 5000.000 104.00709 1 + 1.29150660E+01 3.50813620E-03-1.55468900E-06 3.04562180E-10-2.19523540E-14 2 +-7.20081890E+03-3.77108998E+01 9.87812940E-01 5.00295240E-02-7.36767080E-05 3 + 5.25234550E-08-1.47129610E-11-4.61010860E+03 2.04857192E+01-2.64600820E+03 4 +N2H2 L 5/90N 2.H 2. 0. 0.G 200.000 6000.000 30.02936 1 + 1.31115086E+00 9.00187272E-03-3.14911866E-06 4.81449690E-10-2.71897983E-14 2 + 2.47864167E+04 1.64091085E+01 4.91066016E+00-1.07791866E-02 3.86516441E-05 3 +-3.86501628E-08 1.34852100E-11 2.42242727E+04 9.10279703E-02 2.54807559E+04 4 +NH2NO2 TPIS89N 2.H 2.O 2. 0.G 200.000 6000.000 62.02816 1 + 7.38890998E+00 7.65188026E-03-2.75087039E-06 4.44622886E-10-2.66488122E-14 2 +-6.21767034E+03-1.32737000E+01 2.17310105E+00 1.43162299E-02 1.09031619E-05 3 +-2.76714677E-08 1.29868687E-11-4.45906121E+03 1.53831166E+01-3.12706341E+03 4 +N2H4 L 5/90N 2.H 4. 0. 0.G 200.000 6000.000 32.04524 1 + 4.93957357E+00 8.75017187E-03-2.99399058E-06 4.67278418E-10-2.73068599E-14 2 + 9.28265548E+03-2.69439772E+00 3.83472149E+00-6.49129555E-04 3.76848463E-05 3 +-5.00709182E-08 2.03362064E-11 1.00893925E+04 5.75272030E+00 1.14474575E+04 4 +N2O L 7/88N 2.O 1. 0. 0.G 200.000 6000.000 44.01288 1 + 4.82318873E+00 2.62685279E-03-9.58426058E-07 1.59991296E-10-9.77416939E-15 2 + 8.07335662E+03-2.20236600E+00 2.25716860E+00 1.13046338E-02-1.36710350E-05 3 + 9.68162098E-09-2.93055583E-12 8.74177146E+03 1.07579154E+01 9.81416824E+03 4 +N2O+ J12/70N 2.O 1.E -1. 0.G 298.150 6000.000 44.01233 1 + 5.52859730E+00 1.95956970E-03-7.53758228E-07 1.27045911E-10-7.80207625E-15 2 + 1.58375902E+05-4.41896700E+00 3.28688978E+00 7.40234563E-03-4.86688552E-06 3 + 7.33141038E-10 2.98161683E-13 1.59054547E+05 7.40146504E+00 1.60322136E+05 4 +N2O3 L 4/90N 2.O 3. 0. 0.G 200.000 6000.000 76.01168 1 + 9.08583845E+00 3.37756330E-03-1.31583890E-06 2.30762329E-10-1.47151267E-14 2 + 7.27160146E+03-1.55361904E+01 5.81083964E+00 1.43330962E-02-1.96208597E-05 3 + 1.73060735E-08-6.46553954E-12 8.19184453E+03 1.20461321E+00 1.04192062E+04 4 +N2O4 TPIS89N 2.O 4. 0. 0.G 200.000 6000.000 92.01108 1 + 1.15752899E+01 4.01616086E-03-1.57178323E-06 2.68274309E-10-1.66922019E-14 2 +-2.92191226E+03-3.19488439E+01 3.02002308E+00 2.95904321E-02-3.01342458E-05 3 + 1.42360407E-08-2.44100049E-12-6.40040162E+02 1.18059606E+01 1.33632866E+03 4 +N2O5 L 4/90N 2.O 5. 0. 0.G 200.000 6000.000 108.01048 1 + 1.31108082E+01 4.87435791E-03-1.87548389E-06 3.16374121E-10-1.95926845E-14 2 +-3.11634700E+03-3.46877692E+01 3.68767444E+00 3.92120798E-02-5.53770029E-05 3 + 4.20097833E-08-1.31260710E-11-8.30291184E+02 1.21967866E+01 1.59961321E+03 4 +N3 TPIS89N 3. 0. 0. 0.G 200.000 6000.000 42.02022 1 + 4.64110696E+00 2.76960700E-03-1.04917582E-06 1.75340720E-10-1.07482704E-14 2 + 5.06984238E+04-9.40135456E-01 2.86063038E+00 4.24883549E-03 5.14572136E-06 3 +-1.01478406E-08 4.41878398E-12 5.13692093E+04 9.11596131E+00 5.24384480E+04 4 +N3H L 7/88N 3.H 1. 0. 0.G 200.000 6000.000 43.02816 1 + 5.14700291E+00 4.30561265E-03-1.52704575E-06 2.46295774E-10-1.47144164E-14 2 + 3.34283986E+04-2.25529103E+00 2.88510881E+00 9.44343451E-03-3.87919336E-06 3 +-1.89404011E-09 1.60184132E-12 3.41172038E+04 9.71687818E+00 3.53598709E+04 4 +Na L 4/93NA 1. 0. 0. 0.G 200.000 6000.000 22.98977 1 + 2.39858879E+00 2.15466997E-04-1.49077568E-07 3.66821795E-11-1.66036037E-15 2 + 1.21943069E+04 4.79181120E+00 2.50000005E+00-4.98492323E-10 1.76034086E-12 3 +-2.54461602E-15 1.27603872E-18 1.21597752E+04 4.24402773E+00 1.29051502E+04 4 +Na+ J12/83NA 1.E -1. 0. 0.G 298.150 6000.000 22.98922 1 + 2.50000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 7.25413250E+04 3.55084504E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 7.25413250E+04 3.55084504E+00 7.32867000E+04 4 +NaALF4 J12/79NA 1.AL 1.F 4. 0.G 300.000 5000.000 125.96492 1 + 1.42715530E+01 1.98001910E-03-8.81514840E-07 1.73221480E-10-1.25129150E-14 2 +-2.26123470E+05-4.12755180E+01 4.30521450E+00 4.49680340E-02-7.43237870E-05 3 + 5.80808610E-08-1.74995560E-11-2.24149880E+05 6.37184599E+00-2.21417721E+05 4 +NaBO2 J 6/71NA 1.B 1.O 2. 0.G 300.000 5000.000 65.79957 1 + 7.49652500E+00 2.63098620E-03-1.09791360E-06 2.04939980E-10-1.41931460E-14 2 +-8.05785910E+04-9.44630181E+00 4.06547490E+00 1.34549260E-02-1.38666930E-05 3 + 6.63950420E-09-1.07286710E-12-7.97001570E+04 7.93481629E+00-7.79999032E+04 4 +NaBr J 9/64NA 1.BR 1. 0. 0.G 300.000 5000.000 102.89377 1 + 4.44331350E+00 1.57836570E-04-2.79896190E-08 5.38490380E-12-3.80940540E-16 2 +-1.86594890E+04 3.60858213E+00 3.90108900E+00 2.50254010E-03-3.88510880E-06 3 + 2.83184970E-09-7.72205280E-13-1.85561610E+04 6.18879323E+00-1.73109142E+04 4 +NaCN J3/66 NA 1.C 1.N 1. 0.G 300.000 5000.000 49.00751 1 + 5.79897750E+00 1.68279460E-03-6.74379240E-07 1.22345020E-10-8.29660910E-15 2 + 9.49334440E+03-4.34426041E+00 4.97725580E+00 5.32259370E-03-7.55524410E-06 3 + 6.18397940E-09-2.00714270E-12 9.67314900E+03-3.88207281E-01 1.13382134E+04 4 +NaCL J12/64NA 1.CL 1. 0. 0.G 300.000 5000.000 58.44247 1 + 4.42829310E+00 1.56272410E-04-2.81083830E-08 4.71635710E-12-2.88325570E-16 2 +-2.31709000E+04 2.30097459E+00 3.70322860E+00 3.19976080E-03-4.89245020E-06 3 + 3.46392180E-09-9.13575210E-13-2.30282760E+04 5.77347949E+00-2.18187495E+04 4 +NaF J12/68NA 1.F 1. 0. 0.G 200.000 6000.000 41.98817 1 + 4.33376796E+00 2.56807777E-04-6.94232621E-08 1.19679617E-11-7.49308393E-16 2 +-3.62797872E+04 1.30046354E+00 2.74871833E+00 8.03243289E-03-1.51563523E-05 3 + 1.33592246E-08-4.45165244E-12-3.60002074E+04 8.68107812E+00-3.49332673E+04 4 +NaF2- J12/68NA 1.F 2.E 1. 0.G 300.000 5000.000 60.98712 1 + 7.12231930E+00 4.18840550E-04-1.79722990E-07 3.40412290E-11-2.37519350E-15 2 +-8.27557300E+04-1.07866745E+01 4.58268890E+00 1.06052110E-02-1.57205010E-05 3 + 1.05672970E-08-2.64159200E-12-8.22344970E+04 1.48920761E+00-8.05160536E+04 4 +NaH J 3/63NA 1.H 1. 0. 0.G 300.000 5000.000 23.99771 1 + 3.81305790E+00 8.56438000E-04-3.12268160E-07 5.85024710E-11-4.05139240E-15 2 + 1.36830620E+04 4.84168087E-01 3.12039500E+00 1.39962170E-03 2.21412340E-06 3 +-3.99507950E-09 1.67261780E-12 1.39400650E+04 4.39456114E+00 1.49450759E+04 4 +NaI L 6/72NA 1.I 1. 0. 0.G 300.000 5000.000 149.89424 1 + 4.45845700E+00 1.42412780E-04-1.69262750E-08 3.89600870E-12-2.79663110E-16 2 +-1.20668430E+04 4.47595875E+00 4.04062750E+00 1.96871110E-03-3.05454240E-06 3 + 2.25563230E-09-6.22868320E-13-1.19880410E+04 6.45980105E+00-1.07186481E+04 4 +NaO J12/67NA 1.O 1. 0. 0.G 300.000 5000.000 38.98917 1 + 4.39241580E+00 2.13205740E-04-4.52205980E-08 7.97518210E-12-5.17359890E-16 2 + 8.71189950E+03 2.38808963E+00 3.44210070E+00 4.16172410E-03-6.31183680E-06 3 + 4.44791990E-09-1.17204860E-12 8.90114770E+03 6.95032533E+00 1.00648575E+04 4 +NaO- J12/67NA 1.O 1.E 1. 0.G 300.000 5000.000 38.98972 1 + 4.38680080E+00 2.23446720E-04-4.82124720E-08 8.57208620E-12-5.60943340E-16 2 +-1.59462680E+04 1.01363479E+00 3.41868550E+00 4.21173820E-03-6.31046460E-06 3 + 4.38735150E-09-1.13726390E-12-1.57522340E+04 5.66855639E+00-1.45933736E+04 4 +NaOH J12/70NA 1.O 1.H 1. 0.G 300.000 5000.000 39.99711 1 + 5.64693770E+00 1.22273850E-03-3.32710360E-07 4.06662980E-11-1.77906880E-15 2 +-2.55082220E+04-5.03687466E+00 4.00503880E+00 9.99220430E-03-1.64342130E-05 3 + 1.24765850E-08-3.46376100E-12-2.53004710E+04 2.30643604E+00-2.37844210E+04 4 +NaOH+ J12/71NA 1.O 1.H 1.E -1.G 300.000 5000.000 39.99656 1 + 5.66885470E+00 1.22539300E-03-3.40295630E-07 4.28532680E-11-1.95937600E-15 2 + 7.98065140E+04-3.42468268E+00 4.35052040E+00 8.74650150E-03-1.46426730E-05 3 + 1.13515010E-08-3.21100260E-12 7.99463990E+04 2.34484072E+00 8.15238108E+04 4 +Na2 J12/83NA 2. 0. 0. 0.G 200.000 6000.000 45.97954 1 + 5.96201900E+00-1.06049506E-03-4.39279769E-07 3.05174810E-10-3.39488816E-14 2 + 1.49990927E+04-6.69613647E+00 4.11568261E+00 2.52904040E-03-5.62168645E-06 3 + 6.46171665E-09-2.75128310E-12 1.57824616E+04 3.68672433E+00 1.70837638E+04 4 +Na2C2N2 J 3/66NA 2.C 2.N 2. 0.G 300.000 5000.000 98.01502 1 + 1.25727860E+01 3.39473180E-03-1.36169340E-06 2.47209590E-10-1.67732540E-14 2 +-5.04910210E+03-3.10741979E+01 1.03680290E+01 1.33485470E-02-1.99103340E-05 3 + 1.61564750E-08-5.12645500E-12-4.59375270E+03-2.05494429E+01-1.05562247E+03 4 +Na2CL2 J12/64NA 2.CL 2. 0. 0.G 300.000 5000.000 116.88494 1 + 9.82620010E+00 1.91847630E-04-8.16087430E-08 1.52981810E-11-1.05589940E-15 2 +-7.10771490E+04-1.70361009E+01 7.95839530E+00 8.39623600E-03-1.38171160E-05 3 + 1.02776660E-08-2.86449940E-12-7.07259390E+04-8.17532471E+00-6.80830721E+04 4 +Na2F2 J12/68NA 2.F 2. 0. 0.G 300.000 5000.000 83.97634 1 + 9.43355300E+00 6.36115880E-04-2.76247200E-07 5.29171900E-11-3.73103530E-15 2 +-1.04801140E+05-1.97529921E+01 4.82121910E+00 1.98363960E-02-3.06176140E-05 3 + 2.13370400E-08-5.53443140E-12-1.03890050E+05 2.36625459E+00-1.01801889E+05 4 +Na2O L10/74NA 2.O 1. 0. 0.G 300.000 5000.000 61.97894 1 + 7.14705820E+00 3.98330990E-04-1.74089110E-07 3.35651620E-11-2.38108010E-15 2 +-7.21912610E+03-9.63481061E+00 4.77871770E+00 9.94877160E-03-1.48144560E-05 3 + 1.00032390E-08-2.51378740E-12-6.73602060E+03 1.79947619E+00-4.98135741E+03 4 +Na2O2H2 J12/70NA 2.O 2.H 2. 0.G 300.000 5000.000 79.99422 1 + 9.41607430E+00 5.51965220E-03-1.96596110E-06 3.26803440E-10-2.07124850E-14 2 +-7.63663690E+04-1.88543497E+01 5.97129300E+00 1.40492750E-02-6.24451420E-06 3 +-3.39357460E-09 2.89337690E-12-7.54129380E+04-9.37386453E-01-7.30686609E+04 4 +Na2SO4 J 6/78NA 2.S 1.O 4. 0.G 300.000 5000.000 142.04314 1 + 1.52061280E+01 4.29842640E-03-1.90084090E-06 3.71875300E-10-2.67804570E-14 2 +-1.29673570E+05-4.76569217E+01 2.07274980E+00 5.45820470E-02-7.85435330E-05 3 + 5.51042210E-08-1.52666760E-11-1.26769550E+05 1.66688263E+01-1.24317797E+05 4 +Nb J12/73NB 1. 0. 0. 0.G 300.000 5000.000 92.90638 1 + 4.22059050E+00-1.81874390E-03 8.23739430E-07-1.18328990E-10 5.36370530E-15 2 + 8.69607130E+04-1.18468643E+00 3.47550740E+00 2.05385640E-03-6.96702630E-06 3 + 6.80205590E-09-2.25177180E-12 8.70877490E+04 2.24243697E+00 8.81660848E+04 4 +NbO J12/73NB 1.O 1. 0. 0.G 300.000 5000.000 108.90578 1 + 3.88117290E+00 8.19781220E-04-4.25353900E-07 1.02649360E-10-8.04198010E-15 2 + 2.26371320E+04 6.22364151E+00 2.92144850E+00 3.13240820E-03-1.49003690E-06 3 +-9.93452600E-10 7.99840200E-13 2.29078860E+04 1.12362937E+01 2.39033917E+04 4 +NbO2 J12/73NB 1.O 2. 0. 0.G 200.000 6000.000 124.90518 1 + 6.05147948E+00 9.75153707E-04-3.82697108E-07 6.54150420E-11-4.07159079E-15 2 +-2.61008645E+04-2.40015663E+00 3.57672681E+00 6.35895628E-03-5.96442209E-07 3 +-6.34228956E-09 3.70832821E-12-2.53873185E+04 1.06257008E+01-2.40543339E+04 4 +Ne L10/90NE 1. 0. 0. 0.G 200.000 6000.000 20.17970 1 + 2.50000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-7.45375000E+02 3.35532272E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-7.45375000E+02 3.35532272E+00 0.00000000E+00 4 +Ne+ L10/92NE 1.E -1. 0. 0.G 298.150 6000.000 20.17915 1 + 2.90399557E+00-3.63794635E-04 1.31873359E-07-2.14209210E-11 1.28778499E-15 2 + 2.50143726E+05 2.56310332E+00 1.94106917E+00 4.40016552E-03-8.57047417E-06 3 + 6.99691689E-09-2.11573625E-12 2.50294275E+05 6.99178694E+00 2.51005687E+05 4 +Ni J12/76NI 1. 0. 0. 0.G 300.000 5000.000 58.69340 1 + 3.20614900E+00-2.09699230E-04-2.28364480E-08 1.50852110E-11-1.00044450E-15 2 + 5.07081260E+04 3.53171623E+00 2.77666540E+00-7.52206380E-04 4.32561130E-06 3 +-5.47312870E-09 2.11075650E-12 5.09090830E+04 6.16823253E+00 5.17319098E+04 4 +NiCL J 9/77NI 1.CL 1. 0. 0.G 300.000 5000.000 94.14610 1 + 5.58365140E+00-1.43295780E-03 8.52077230E-07-1.48863930E-10 8.15516240E-15 2 + 2.00565050E+04-1.63732144E+00 3.48977570E+00 3.18379300E-03-1.91489120E-06 3 +-3.57363170E-10 4.60747680E-13 2.07259350E+04 9.54974436E+00 2.18905147E+04 4 +NiCL2 J 9/77NI 1.CL 2. 0. 0.G 300.000 5000.000 129.59880 1 + 7.38745300E+00 8.46375950E-04-4.31495420E-07 9.35908460E-11-7.19151390E-15 2 +-1.12358570E+04-7.18895104E+00 4.56061770E+00 1.36137130E-02-2.36601330E-05 3 + 1.96162640E-08-6.24172910E-12-1.06835710E+04 6.23619416E+00-8.89195306E+03 4 +NiO L 2/84NI 1.O 1. 0. 0.G 300.000 5000.000 74.69280 1 + 4.10461140E+00 4.86591600E-04-1.87867840E-07 3.55318550E-11-2.47151660E-15 2 + 3.64456450E+04 4.07679656E+00 2.99196820E+00 3.33092080E-03-1.53524710E-06 3 +-1.56408330E-09 1.21285010E-12 3.67420940E+04 9.82140736E+00 3.77657540E+04 4 +NiS J12/76NI 1.S 1. 0. 0.G 300.000 5000.000 90.75940 1 + 4.91604720E+00 3.13774510E-04-2.97018130E-07 8.01797240E-11-6.72574180E-15 2 + 4.13210320E+04 1.81898797E+00 3.11681070E+00 4.01735280E-03-1.55839110E-06 3 +-1.50635360E-09 9.36838810E-13 4.18968570E+04 1.14677351E+01 4.29883902E+04 4 +O L 1/90O 1. 0. 0. 0.G 200.000 6000.000 15.99940 1 + 2.54363697E+00-2.73162486E-05-4.19029520E-09 4.95481845E-12-4.79553694E-16 2 + 2.92260120E+04 4.92229457E+00 3.16826710E+00-3.27931884E-03 6.64306396E-06 3 +-6.12806624E-09 2.11265971E-12 2.91222592E+04 2.05193346E+00 2.99687009E+04 4 +O+ L 1/90O 1.E -1. 0. 0.G 298.150 6000.000 15.99885 1 + 2.48773317E+00 2.17660016E-05-1.08955806E-08 1.25909212E-12 1.37316720E-16 2 + 1.87939965E+05 4.46134091E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 1.87935291E+05 4.39337689E+00 1.88680666E+05 4 +O- TPIS89O 1.E 1. 0. 0.G 298.150 6000.000 15.99995 1 + 2.54474868E+00-4.66695419E-05 1.84912310E-08-3.18159131E-12 1.98962894E-16 2 + 1.14822713E+04 4.52131005E+00 2.90805921E+00-1.69804907E-03 2.98069956E-06 3 +-2.43835127E-09 7.61229313E-13 1.14138341E+04 2.80339084E+00 1.22272740E+04 4 +OD J 6/77O 1.D 1. 0. 0.G 300.000 5000.000 18.01350 1 + 2.78291070E+00 1.57395670E-03-5.70207870E-07 9.88644090E-11-6.50620140E-15 2 + 3.57598130E+03 6.67567133E+00 4.03467510E+00-2.45613130E-03 3.96102010E-06 3 +-1.85349960E-09 1.92953410E-13 3.27705070E+03 3.94186141E-01 4.40224516E+03 4 +OH TPIS78O 1.H 1. 0. 0.G 200.000 6000.000 17.00734 1 + 2.83864607E+00 1.10725586E-03-2.93914978E-07 4.20524247E-11-2.42169092E-15 2 + 3.94395852E+03 5.84452662E+00 3.99201543E+00-2.40131752E-03 4.61793841E-06 3 +-3.88113333E-09 1.36411470E-12 3.61508056E+03-1.03925458E-01 4.73234213E+03 4 +OH+ TPIS78O 1.H 1.E -1. 0.G 298.150 6000.000 17.00679 1 + 2.68358997E+00 1.57006432E-03-5.39972805E-07 9.37643859E-11-5.70068055E-15 2 + 1.54395744E+05 6.44375901E+00 3.50502572E+00 2.41313749E-04-1.42200949E-06 3 + 2.64780232E-09-1.17038711E-12 1.54127124E+05 1.97907640E+00 1.55174989E+05 4 +OH- L 3/93O 1.H 1.E 1. 0.G 298.150 6000.000 17.00789 1 + 2.83405701E+00 1.07058023E-03-2.62459398E-07 3.08376435E-11-1.31383862E-15 2 +-1.80186974E+04 4.49464749E+00 3.43279956E+00 6.19656310E-04-1.89930992E-06 3 + 2.37365946E-09-8.55103755E-13-1.82613086E+04 1.06053657E+00-1.72227709E+04 4 +O2 TPIS89O 2. 0. 0. 0.G 200.000 6000.000 31.99880 1 + 3.66096083E+00 6.56365523E-04-1.41149485E-07 2.05797658E-11-1.29913248E-15 2 +-1.21597725E+03 3.41536184E+00 3.78245636E+00-2.99673415E-03 9.84730200E-06 3 +-9.68129508E-09 3.24372836E-12-1.06394356E+03 3.65767573E+00 0.00000000E+00 4 +O2+ TPIS89O 2.E -1. 0. 0.G 298.150 6000.000 31.99825 1 + 3.31675922E+00 1.11522244E-03-3.83492556E-07 5.72784687E-11-2.77648381E-15 2 + 1.39876823E+05 5.44726476E+00 4.61017167E+00-6.35951952E-03 1.42425624E-05 3 +-1.20997923E-08 3.70956878E-12 1.39742229E+05-2.01326874E-01 1.40937762E+05 4 +O2- L 4/89O 2.E 1. 0. 0.G 298.150 6000.000 31.99935 1 + 3.95666294E+00 5.98141823E-04-2.12133905E-07 3.63267581E-11-2.24989228E-15 2 +-7.06287229E+03 2.27871010E+00 3.66442522E+00-9.28741138E-04 6.45477082E-06 3 +-7.74703380E-09 2.93332662E-12-6.87076983E+03 4.35140674E+00-5.77639825E+03 4 +O3 L 5/90O 3. 0. 0. 0.G 200.000 6000.000 47.99820 1 + 1.23302914E+01-1.19324783E-02 7.98741278E-06-1.77194552E-09 1.26075824E-13 2 + 1.26755831E+04-4.08823374E+01 3.40738221E+00 2.05379063E-03 1.38486052E-05 3 +-2.23311542E-08 9.76073226E-12 1.58644979E+04 8.28247580E+00 1.70545228E+04 4 +P J12/82P 1. 0. 0. 0.G 200.000 6000.000 30.97376 1 + 2.80721555E+00-5.30841988E-04 2.44543046E-07-2.05708252E-11-2.94546619E-16 2 + 3.71892748E+04 3.67764733E+00 2.50004278E+00-4.38968637E-07 1.58131741E-09 3 +-2.33900457E-12 1.20510940E-15 3.73073754E+04 5.38414729E+00 3.80527536E+04 4 +P+ L12/66P 1.E -1. 0. 0.G 300.000 5000.000 30.97321 1 + 2.90215470E+00-5.88788990E-04 3.12981190E-07-5.97275390E-11 3.93049250E-15 2 + 1.59944127E+05 3.83370649E+00 4.37904170E+00-6.46667230E-03 8.93409620E-06 3 +-5.48580210E-09 1.20988570E-12 1.59647807E+05-3.29374021E+00 1.60734657E+05 4 +PCL3 J 6/70P 1.CL 3. 0. 0.G 300.000 5000.000 137.33186 1 + 9.45661160E+00 6.02784010E-04-2.58468780E-07 4.89042800E-11-3.40832850E-15 2 +-3.77045574E+04-1.69296498E+01 5.25905370E+00 1.78805660E-02-2.73175850E-05 3 + 1.88982400E-08-4.87384960E-12-3.68644304E+04 3.25232970E+00-3.47080119E+04 4 +PF J 6/77P 1.F 1. 0. 0.G 300.000 5000.000 49.97217 1 + 4.28444030E+00 4.65131920E-05 1.29231550E-07-3.54596860E-11 2.93086420E-15 2 +-7.67566495E+03 2.40196381E+00 2.67608630E+00 5.57221620E-03-7.28377960E-06 3 + 4.58194390E-09-1.11881060E-12-7.28916135E+03 1.04341831E+01-6.29944377E+03 4 +PF+ J 6/77P 1.F 1.E -1. 0.G 300.000 5000.000 49.97162 1 + 4.08161840E+00 4.95069100E-04-2.03198080E-07 3.92348470E-11-2.78303370E-15 2 + 1.07145847E+05 3.44441668E+00 3.94021220E+00-5.37845820E-04 3.93561060E-06 3 +-4.67261940E-09 1.74458380E-12 1.07252597E+05 4.51850328E+00 1.08429826E+05 4 +PF- J 6/77P 1.F 1.E 1. 0.G 300.000 5000.000 49.97271 1 + 4.30376910E+00 2.63926300E-04-9.87743030E-08 1.87118210E-11-1.21102520E-15 2 +-2.10581444E+04 2.41229152E+00 3.59513760E+00 3.03129090E-03-4.40629140E-06 3 + 3.15834750E-09-8.92062670E-13-2.09040944E+04 5.86990652E+00-1.97305817E+04 4 +PF2 J 6/77P 1.F 2. 0. 0.G 300.000 5000.000 68.97057 1 + 6.09265880E+00 1.03133240E-03-4.53710200E-07 8.70455830E-11-5.97140520E-15 2 +-6.07553254E+04-3.78513007E+00 2.44285260E+00 1.51863310E-02-2.21969240E-05 3 + 1.56489320E-08-4.32983720E-12-5.99609804E+04 1.40371170E+01-5.87248863E+04 4 +PF2+ J 6/77P 1.F 2.E -1. 0.G 300.000 5000.000 68.97002 1 + 6.07261540E+00 1.05882490E-03-4.67581660E-07 8.96122980E-11-6.04542170E-15 2 + 5.47769396E+04-4.35167158E+00 2.47021360E+00 1.49226760E-02-2.15731390E-05 3 + 1.50543860E-08-4.12671090E-12 5.55655406E+04 1.32636740E+01 5.68025058E+04 4 +PF3 J12/69P 1.F 3. 0. 0.G 300.000 5000.000 87.96897 1 + 8.43477330E+00 1.73939200E-03-7.51198080E-07 1.43442470E-10-1.00939790E-14 2 +-1.18180783E+05-1.64636020E+01 2.36218780E+00 2.28200450E-02-2.76566420E-05 3 + 1.44909620E-08-2.46023600E-12-1.16776903E+05 1.36864320E+01-1.15275206E+05 4 +PF5 J12/69P 1.F 5. 0. 0.G 300.000 5000.000 125.96578 1 + 1.28461840E+01 3.51044850E-03-1.51986040E-06 2.91019040E-10-2.05347080E-14 2 +-1.96362263E+05-3.94755420E+01 1.05232490E+00 4.44540040E-02-5.39014290E-05 3 + 2.84166860E-08-4.91432680E-12-1.93632313E+05 1.90890100E+01-1.91765100E+05 4 +PH J 6/67P 1.H 1. 0. 0.G 300.000 5000.000 31.98170 1 + 3.07454420E+00 1.16989470E-03-3.03816540E-07 4.44363140E-11-2.70009750E-15 2 + 2.74268316E+04 5.76804855E+00 3.68034330E+00-1.27560180E-03 2.59324420E-06 3 +-8.43541070E-10-1.72086090E-13 2.73339656E+04 2.91864125E+00 2.83957262E+04 4 +PH3 J 6/62P 1.H 3. 0. 0.G 300.000 5000.000 33.99758 1 + 3.34487940E+00 6.57709410E-03-2.63367550E-06 4.77446600E-10-3.23543900E-14 2 +-8.16176752E+02 3.95479626E+00 3.15819350E+00 2.49414920E-03 9.02552530E-06 3 +-1.02279040E-08 3.28342500E-12-4.61237252E+02 6.23722486E+00 6.52312908E+02 4 +PO J 6/71P 1.O 1. 0. 0.G 300.000 5000.000 46.97316 1 + 3.84279220E+00 7.23644560E-04-2.89341990E-07 5.30135540E-11-3.54953730E-15 2 +-4.79945495E+03 4.55237741E+00 3.96130800E+00-2.12353990E-03 7.52012190E-06 3 +-7.59509120E-09 2.56375910E-12-4.69896895E+03 4.58369221E+00-3.55964877E+03 4 +PO2 J 9/62P 1.O 2. 0. 0.G 300.000 5000.000 62.97256 1 + 5.69132780E+00 1.48068660E-03-6.54256920E-07 1.27932310E-10-9.20992770E-15 2 +-3.97947254E+04-2.81972201E+00 2.33452730E+00 1.25021000E-02-1.43361950E-05 3 + 7.67621660E-09-1.54016940E-12-3.89688654E+04 1.40544350E+01-3.78293636E+04 4 +P2 J 6/61P 2. 0. 0. 0.G 300.000 5000.000 61.94752 1 + 4.16117330E+00 3.96208000E-04-1.55803390E-07 2.90934740E-11-2.00424580E-15 2 + 1.59468693E+04 2.24109249E+00 2.83911070E+00 4.82661930E-03-5.49474880E-06 3 + 2.58005070E-09-3.22364530E-13 1.62597073E+04 8.84241019E+00 1.72771170E+04 4 +P4 J 6/61P 4. 0. 0. 0.G 300.000 5000.000 123.89505 1 + 9.22627890E+00 8.68941280E-04-3.77583380E-07 7.23796660E-11-5.10661090E-15 2 + 4.09054959E+03-1.96417049E+01 3.53533000E+00 2.41252920E-02-3.64627590E-05 3 + 2.49169060E-08-6.32985630E-12 5.23553359E+03 7.75589567E+00 7.08599199E+03 4 +P4O10 J12/65P 4.O 10. 0. 0.G 300.000 5000.000 283.88905 1 + 2.89396590E+01 1.24520960E-02-5.48543200E-06 1.07047430E-09-7.69568570E-14 2 +-3.60148633E+05-1.23859447E+02-4.41428830E+00 1.37590810E-01-1.92685980E-04 3 + 1.32720680E-07-3.63113780E-11-3.52629523E+05 4.01782260E+01-3.49287392E+05 4 +Pb J 3/83PB 1. 0. 0. 0.G 200.000 6000.000 207.20000 1 + 4.16342379E+00-3.49637723E-03 2.28263170E-06-4.76749242E-10 3.22223800E-14 2 + 2.21687499E+04-2.13525305E+00 2.50229005E+00-2.44053643E-05 9.17082578E-08 3 +-1.42817771E-10 7.83762196E-14 2.27314919E+04 6.84009322E+00 2.34770299E+04 4 +PbBr J12/73PB 1.BR 1. 0. 0.G 300.000 5000.000 287.10400 1 + 4.72687660E+00-4.39183900E-04 3.32155820E-07-6.53072400E-11 4.27261120E-15 2 + 7.09889590E+03 5.86735159E+00 4.19068400E+00 1.34111780E-03-2.09789940E-06 3 + 1.55109080E-09-4.26179120E-13 7.23694690E+03 8.57477819E+00 8.53033705E+03 4 +PbBr2 J12/73PB 1.BR 2. 0. 0.G 300.000 5000.000 367.00800 1 + 6.94729060E+00 6.01990010E-05-2.65566850E-08 5.15960120E-12-3.68370500E-16 2 +-1.46454410E+04 1.18015799E+00 6.39020910E+00 2.52890500E-03-4.19037430E-06 3 + 3.13675230E-09-8.79767450E-13-1.45417920E+04 3.81752929E+00-1.25553875E+04 4 +PbBr4 J12/73PB 1.BR 4. 0. 0.G 300.000 5000.000 526.81600 1 + 1.28569730E+01 1.63239400E-04-7.19703900E-08 1.39757490E-11-9.97361870E-16 2 +-5.87720950E+04-2.21457500E+01 1.13793660E+01 6.66258720E-03-1.09406480E-05 3 + 8.10947390E-09-2.24955750E-12-5.84954310E+04-1.51401680E+01-5.48882380E+04 4 +PbCL J 6/73PB 1.CL 1. 0. 0.G 300.000 5000.000 242.65270 1 + 4.70165350E+00-4.22551710E-04 3.26847790E-07-6.51621470E-11 4.29786020E-15 2 + 3.77979910E+02 4.43744174E+00 3.89729120E+00 2.48674640E-03-3.91571440E-06 3 + 2.84942830E-09-7.72665800E-13 5.68625790E+02 8.42847364E+00 1.81180238E+03 4 +PbCL+ J 6/73PB 1.CL 1.E -1. 0.G 300.000 5000.000 242.65215 1 + 4.45916970E+00 9.74073070E-05-4.88211340E-09-2.54722460E-12 6.24708770E-16 2 + 8.83258470E+04 5.21310065E+00 3.96048080E+00 2.25113840E-03-3.55593020E-06 3 + 2.61309650E-09-7.19012840E-13 8.84213700E+04 7.58774285E+00 8.96756515E+04 4 +PbCL2 J 6/73PB 1.CL 2. 0. 0.G 300.000 5000.000 278.10540 1 + 6.84016780E+00 2.06013080E-04-1.00234340E-07 1.92627720E-11-8.79414190E-16 2 +-2.30163620E+04-9.63755109E-01 5.63994070E+00 5.46221340E-03-8.80568720E-06 3 + 6.41972300E-09-1.75185910E-12-2.27923360E+04 4.72790485E+00-2.09339476E+04 4 +PbCL2+ J 6/73PB 1.CL 2.E -1. 0.G 300.000 5000.000 278.10485 1 + 6.84188370E+00 1.97924730E-04-9.65628220E-08 2.01064400E-11-1.32465790E-15 2 + 9.60940180E+04-8.16043480E-01 5.56538760E+00 5.74684170E-03-9.24450410E-06 3 + 6.72568880E-09-1.83138580E-12 9.63349850E+04 5.24905400E+00 9.81804864E+04 4 +PbCL4 J12/73PB 1.CL 4. 0. 0.G 300.000 5000.000 349.01080 1 + 1.26696730E+01 3.75122560E-04-1.64653700E-07 3.18488550E-11-2.26509470E-15 2 +-7.03291510E+04-2.66238322E+01 9.62829790E+00 1.34564380E-02-2.15717310E-05 3 + 1.56382150E-08-4.24149220E-12-6.97464870E+04-1.21348482E+01-6.64393967E+04 4 +PbF J12/73PB 1.F 1. 0. 0.G 300.000 5000.000 226.19840 1 + 4.60521960E+00-3.26222170E-04 2.82982530E-07-5.71205940E-11 3.73978130E-15 2 +-1.10869170E+04 3.74059423E+00 3.24544820E+00 4.69361660E-03-6.97800280E-06 3 + 4.74593040E-09-1.19839280E-12-1.07770730E+04 1.04437320E+01-9.65366318E+03 4 +PbF2 J12/73PB 1.F 2. 0. 0.G 300.000 5000.000 245.19681 1 + 6.63545930E+00 4.11731090E-04-1.80046090E-07 3.47289840E-11-2.46452690E-15 2 +-5.44250590E+04-2.94686195E+00 4.12956940E+00 1.05616260E-02-1.58081440E-05 3 + 1.07257480E-08-2.70938900E-12-5.39161210E+04 9.14042485E+00-5.23352056E+04 4 +PbF4 J12/73PB 1.F 4. 0. 0.G 300.000 5000.000 283.19361 1 + 1.21277740E+01 9.84210460E-04-4.30061590E-07 8.29024210E-11-5.88002020E-15 2 +-1.40203450E+05-2.97909440E+01 6.27453870E+00 2.45762820E-02-3.65675370E-05 3 + 2.46632660E-08-6.18760080E-12-1.39009170E+05-1.52958549E+00-1.36323331E+05 4 +PbI J12/73PB 1.I 1. 0. 0.G 300.000 5000.000 334.10447 1 + 4.71861120E+00-4.18822360E-04 3.09708470E-07-5.92033530E-11 3.87739700E-15 2 + 1.15341100E+04 6.83919406E+00 4.30733950E+00 8.56682320E-04-1.31645540E-06 3 + 9.71872390E-10-2.65267440E-13 1.16457440E+04 8.94132936E+00 1.29582187E+04 4 +PbI2 J12/73PB 1.I 2. 0. 0.G 300.000 5000.000 461.00894 1 + 6.97611080E+00 2.74745710E-05-1.22042160E-08 2.38624890E-12-1.71337680E-16 2 +-2.47078980E+03 3.47173649E+00 6.71692250E+00 1.18498790E-03-1.97915550E-06 3 + 1.49273780E-09-4.21896460E-13-2.42295050E+03 4.69675599E+00-3.82366018E+02 4 +PbI4 J12/73PB 1.I 4. 0. 0.G 300.000 5000.000 714.81788 1 + 1.29276610E+01 8.29982860E-05-3.67816670E-08 7.17642940E-12-5.14309570E-16 2 +-3.08776290E+04-1.76557593E+01 1.21502660E+01 3.53870810E-03-5.87824340E-06 3 + 4.40721590E-09-1.23740500E-12-3.07335650E+04-1.39781323E+01-2.69974873E+04 4 +PbO J12/71PB 1.O 1. 0. 0.G 300.000 5000.000 223.19940 1 + 4.11362420E+00 5.37788570E-04-2.37633940E-07 4.24256880E-11-1.22940440E-15 2 + 7.15192600E+03 5.15041319E+00 2.65398670E+00 6.66441150E-03-1.03123630E-05 3 + 7.66632590E-09-2.21738640E-12 7.44375130E+03 1.21567130E+01 8.45424386E+03 4 +PbS J 6/73PB 1.S 1. 0. 0.G 300.000 5000.000 239.26600 1 + 4.09115220E+00 8.38853590E-04-5.71572070E-07 1.61604760E-10-1.25118970E-14 2 + 1.46016950E+04 6.70074801E+00 3.47745320E+00 3.97002950E-03-6.10966890E-06 3 + 4.30086820E-09-1.13115490E-12 1.46847510E+04 9.47780941E+00 1.58519958E+04 4 +Pb2 J 9/63PB 2. 0. 0. 0.G 300.000 5000.000 414.40000 1 + 4.45983400E+00 2.40063810E-04-1.92598630E-08 3.64569370E-12-2.53809340E-16 2 + 3.86540490E+04 8.32496049E+00 4.05012220E+00 2.02300010E-03-2.97013460E-06 3 + 2.17859570E-09-5.97553270E-13 3.87316400E+04 1.02719920E+01 4.00068822E+04 4 +S J 9/82S 1. 0. 0. 0.G 200.000 6000.000 32.06600 1 + 2.87936498E+00-5.11050388E-04 2.53806719E-07-4.45455458E-11 2.66717362E-15 2 + 3.25013791E+04 3.98140647E+00 2.31725616E+00 4.78018342E-03-1.42082674E-05 3 + 1.56569538E-08-5.96588299E-12 3.25068976E+04 6.06242434E+00 3.33128471E+04 4 +S+ J 9/82S 1.E -1. 0. 0.G 298.150 6000.000 32.06545 1 + 2.46524359E+00 1.14257212E-04-1.19572699E-07 4.38771359E-11-3.80523639E-15 2 + 1.53485422E+05 5.60821371E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 1.53478145E+05 5.43627019E+00 1.54223520E+05 4 +S- J 9/82S 1.E 1. 0. 0.G 298.150 6000.000 32.06655 1 + 2.72948060E+00-2.24894928E-04 8.58648854E-08-1.44256169E-11 8.87491196E-16 2 + 7.65980069E+03 4.39902726E+00 2.51353070E+00 1.93516857E-03-5.38438357E-06 3 + 5.40313356E-09-1.89053684E-12 7.64303006E+03 5.13282002E+00 8.44066578E+03 4 +SCL J 6/78S 1.CL 1. 0. 0.G 300.000 5000.000 67.51870 1 + 4.59472600E+00-5.97717860E-05 4.52264950E-08-9.37184350E-12 8.07357270E-16 2 + 1.74524260E+04 2.37985153E+00 3.70558800E+00 5.27186230E-03-1.13718200E-05 3 + 1.04978270E-08-3.53184080E-12 1.75611590E+04 6.27945123E+00 1.88189067E+04 4 +SCL2 J 6/78S 1.CL 2. 0. 0.G 300.000 5000.000 102.97140 1 + 6.62714620E+00 4.27470190E-04-1.88168810E-07 3.57611550E-11-2.38494000E-15 2 +-4.20002190E+03-4.23237025E+00 3.59663710E+00 1.43271930E-02-2.51991970E-05 3 + 2.05728820E-08-6.39769080E-12-3.63758370E+03 1.00605557E+01-2.11344531E+03 4 +SCL2+ J 6/78S 1.CL 2.E -1. 0.G 300.000 5000.000 102.97085 1 + 6.58025700E+00 5.21764000E-04-2.50769790E-07 5.09881240E-11-3.27302920E-15 2 + 1.06354860E+05-3.29493832E+00 3.59587270E+00 1.42916650E-02-2.50849980E-05 3 + 2.04468930E-08-6.35046690E-12 1.06902830E+05 1.07558337E+01 1.08425944E+05 4 +SD J 6/77S 1.D 1. 0. 0.G 300.000 5000.000 34.08010 1 + 3.34719880E+00 1.21296460E-03-4.77301380E-07 8.83236690E-11-6.07405910E-15 2 + 1.56271470E+04 4.87764198E+00 4.72855970E+00-5.09398810E-03 9.91346050E-06 3 +-7.32908130E-09 1.94616080E-12 1.53995790E+04-1.56847952E+00 1.66570071E+04 4 +SF J 6/76S 1.F 1. 0. 0.G 300.000 5000.000 51.06440 1 + 4.36908850E+00 1.92044240E-04-6.66303650E-08 1.24485900E-11-7.65374940E-16 2 + 2.20185260E+02 2.07596863E+00 3.42081750E+00 4.55111980E-03-7.93725640E-06 3 + 6.50047110E-09-2.02896650E-12 3.96095030E+02 6.54700583E+00 1.56005789E+03 4 +SF+ J 6/76S 1.F 1.E -1. 0.G 300.000 5000.000 51.06385 1 + 4.28072480E+00 1.03674330E-04 5.54416650E-08-1.14332950E-11 5.58469060E-16 2 + 1.17921920E+05 2.45939467E+00 2.66666480E+00 5.69754910E-03-7.60574220E-06 3 + 4.91194550E-09-1.24145140E-12 1.18310330E+05 1.05150193E+01 1.19300559E+05 4 +SF- J12/76S 1.F 1.E 1. 0.G 300.000 5000.000 51.06495 1 + 4.12706720E+00 6.25693400E-04-3.12469860E-07 7.17224760E-11-4.70614040E-15 2 +-2.37348810E+04 2.55369411E+00 2.75979360E+00 6.86582200E-03-1.13145190E-05 3 + 8.87463700E-09-2.67842700E-12-2.34863060E+04 8.99350681E+00-2.24419989E+04 4 +SF2 J 6/76S 1.F 2. 0. 0.G 300.000 5000.000 70.06281 1 + 6.11941960E+00 1.00514240E-03-4.46533130E-07 8.76240100E-11-6.32365120E-15 2 +-3.77142410E+04-4.55717411E+00 2.41030560E+00 1.55901210E-02-2.31780180E-05 3 + 1.65834970E-08-4.64657610E-12-3.69163730E+04 1.35066803E+01-3.56790061E+04 4 +SF2+ J12/76S 1.F 2.E -1. 0.G 300.000 5000.000 70.06226 1 + 6.12090000E+00 9.99848170E-04-4.39929320E-07 8.43681370E-11-5.77953780E-15 2 + 8.24445850E+04-3.86307542E+00 2.42714900E+00 1.55175460E-02-2.30602590E-05 3 + 1.64996120E-08-4.62464180E-12 8.32395570E+04 1.41278866E+01 8.44796050E+04 4 +SF2- J12/76S 1.F 2.E 1. 0.G 300.000 5000.000 70.06335 1 + 6.58471230E+00 4.78860900E-04-2.14054400E-07 4.21757030E-11-3.05239100E-15 2 +-5.00057050E+04-5.73334787E+00 3.29005030E+00 1.55386120E-02-2.72366040E-05 3 + 2.21827990E-08-6.88621560E-12-4.93919250E+04 9.81747763E+00-4.79204012E+04 4 +SF3 J 6/77S 1.F 3. 0. 0.G 300.000 5000.000 89.06121 1 + 8.80768970E+00 1.36716760E-03-6.08083330E-07 1.18830220E-10-8.44709150E-15 2 +-6.34404940E+04-1.67648869E+01 1.87777280E+00 3.12340350E-02-5.15713790E-05 3 + 4.02473220E-08-1.21105940E-11-6.20679390E+04 1.63694361E+01-6.05016370E+04 4 +SF3+ J12/76S 1.F 3.E -1. 0.G 300.000 5000.000 89.06066 1 + 8.13850160E+00 2.12889140E-03-9.48368220E-07 1.86074360E-10-1.32717290E-14 2 + 4.44867300E+04-1.54212422E+01 1.00185080E+00 2.97551550E-02-4.33567940E-05 3 + 3.05549640E-08-8.46334790E-12 4.60441840E+04 1.94445008E+01 4.73387417E+04 4 +SF3- J12/76S 1.F 3.E 1. 0.G 300.000 5000.000 89.06176 1 + 8.80958260E+00 1.36436780E-03-6.07573210E-07 1.19405320E-10-8.62593320E-15 2 +-9.63202650E+04-1.74943707E+01 1.87887610E+00 3.12261740E-02-5.15517490E-05 3 + 4.02267880E-08-1.21029320E-11-9.49470550E+04 1.56459843E+01-9.33806370E+04 4 +SF4 J 6/76S 1.F 4. 0. 0.G 300.000 5000.000 108.05961 1 + 1.11243830E+01 2.14579940E-03-9.54524440E-07 1.87461110E-10-1.35359530E-14 2 +-9.55816690E+04-2.88756477E+01 1.28196450E+00 4.35698990E-02-7.01251680E-05 3 + 5.36772440E-08-1.59143560E-11-9.35867010E+04 1.84198703E+01-9.17889260E+04 4 +SF4+ J12/76S 1.F 4.E -1. 0.G 300.000 5000.000 108.05906 1 + 1.13519410E+01 1.88756620E-03-8.39040620E-07 1.64149380E-10-1.17351950E-14 2 + 4.62247670E+04-2.85715082E+01 1.96158130E+00 4.21320940E-02-6.91555650E-05 3 + 5.37206660E-08-1.61058950E-11 4.80947400E+04 1.63799008E+01 5.00397986E+04 4 +SF4- J12/76S 1.F 4.E 1. 0.G 300.000 5000.000 108.06016 1 + 1.20033260E+01 1.20077130E-03-5.73982740E-07 1.22993850E-10-9.29527340E-15 2 +-1.10603080E+05-3.16592651E+01 4.07937620E+00 3.78395030E-02-6.69046570E-05 3 + 5.48224340E-08-1.70928440E-11-1.09146420E+05 5.64178775E+00-1.06739135E+05 4 +SF5 J12/77S 1.F 5. 0. 0.G 300.000 5000.000 127.05802 1 + 1.36105630E+01 2.65231300E-03-1.16914630E-06 2.42451320E-10-1.83147180E-14 2 +-1.14002930E+05-4.30151012E+01-1.71476620E+00 6.87160080E-02-1.14079330E-04 3 + 8.93363790E-08-2.69404290E-11-1.10961780E+05 3.02724678E+01-1.09262883E+05 4 +SF5+ J12/77S 1.F 5.E -1. 0.G 300.000 5000.000 127.05747 1 + 1.36842160E+01 2.51770230E-03-1.08543930E-06 2.25337450E-10-1.72239170E-14 2 + 1.60049080E+04-4.41997237E+01-1.71648610E+00 6.89400460E-02-1.14710510E-04 3 + 8.99778650E-08-2.71663260E-11 1.90611490E+04 2.94445133E+01 2.07650756E+04 4 +SF5- J12/77S 1.F 5.E 1. 0.G 300.000 5000.000 127.05856 1 + 1.43219100E+01 1.93130330E-03-8.62199360E-07 1.69723950E-10-1.22748600E-14 2 +-1.57343150E+05-4.51592536E+01 1.84776490E+00 5.83763690E-02-1.01313140E-04 3 + 8.19569770E-08-2.53195050E-11-1.54993260E+05 1.38538844E+01-1.52592788E+05 4 +SF6 J 6/76S 1.F 6. 0. 0.G 300.000 5000.000 146.05642 1 + 1.51629500E+01 4.38423180E-03-1.94863370E-06 3.82471960E-10-2.76050500E-14 2 +-1.52268010E+05-5.44157194E+01-3.83880880E+00 8.32217210E-02-1.31816890E-04 3 + 9.96361540E-08-2.92487670E-11-1.48364770E+05 3.71611426E+01-1.46791868E+05 4 +SF6- J 6/77S 1.F 6.E 1. 0.G 300.000 5000.000 146.05697 1 + 1.54286460E+01 4.08453170E-03-1.81649030E-06 3.56673280E-10-2.57500000E-14 2 +-1.66898840E+05-5.43961218E+01-3.26092720E+00 8.26953690E-02-1.32998120E-04 3 + 1.01737680E-07-3.01463830E-11-1.63108600E+05 3.54233442E+01-1.61393505E+05 4 +SH J 6/77S 1.H 1. 0. 0.G 300.000 5000.000 33.07394 1 + 3.00145370E+00 1.33949570E-03-4.67896630E-07 7.88040150E-11-5.02804530E-15 2 + 1.59053200E+04 6.28462715E+00 4.44203220E+00-2.43591970E-03 1.90645760E-06 3 + 9.91666300E-10-9.57407620E-13 1.55232580E+04-1.14449035E+00 1.67577318E+04 4 +SN J 6/61S 1.N 1. 0. 0.G 300.000 5000.000 46.07274 1 + 3.84939760E+00 7.27567880E-04-2.93702030E-07 5.50136280E-11-3.81235510E-15 2 + 3.04599620E+04 4.43127355E+00 3.94229710E+00-2.00355150E-03 7.35346440E-06 3 +-7.51685600E-09 2.55910980E-12 3.05639490E+04 4.58030805E+00 3.17016142E+04 4 +SO J 6/77S 1.O 1. 0. 0.G 300.000 5000.000 48.06540 1 + 4.01428730E+00 2.70228170E-04 8.28966670E-08-3.43237410E-11 3.11214440E-15 2 +-7.10519560E+02 3.49973505E+00 3.14902330E+00 1.18393470E-03 2.57406860E-06 3 +-4.44434190E-09 1.87351590E-12-4.04075710E+02 8.31987915E+00 6.02271219E+02 4 +SOF2 J 6/72S 1.O 1.F 2. 0.G 300.000 5000.000 86.06221 1 + 8.08742120E+00 2.10957160E-03-9.08669120E-07 1.73448340E-10-1.22141580E-14 2 +-6.82381590E+04-1.38555916E+01 2.47490660E+00 2.09524260E-02-2.41642770E-05 3 + 1.21203770E-08-1.93387310E-12-6.68976020E+04 1.41973404E+01-6.54188894E+04 4 +SO2 J 6/61S 1.O 2. 0. 0.G 300.000 5000.000 64.06480 1 + 5.24513640E+00 1.97042040E-03-8.03757690E-07 1.51499690E-10-1.05580040E-14 2 +-3.75582270E+04-1.07404892E+00 3.26653380E+00 5.32379020E-03 6.84375520E-07 3 +-5.28100470E-09 2.55904540E-12-3.69081480E+04 9.66465108E+00-3.57007867E+04 4 +SO2CLF J 6/71S 1.O 2.CL 1.F 1.G 300.000 5000.000 118.51590 1 + 1.01182860E+01 3.14889940E-03-1.34715140E-06 2.55803100E-10-1.79382560E-14 2 +-7.05092910E+04-2.31278508E+01 2.98175280E+00 2.64491670E-02-2.92001820E-05 3 + 1.39576110E-08-2.03044870E-12-6.87614970E+04 1.27316812E+01-6.69282620E+04 4 +SO2CL2 J 6/71S 1.O 2.CL 2. 0.G 300.000 5000.000 134.97020 1 + 1.05509370E+01 2.67343010E-03-1.14282300E-06 2.16862000E-10-1.51991510E-14 2 +-4.62950560E+04-2.43078570E+01 4.38516770E+00 2.32121570E-02-2.65321120E-05 3 + 1.34999230E-08-2.28192810E-12-4.48029740E+04 6.57867880E+00-4.26726368E+04 4 +SO2F2 J 6/71S 1.O 2.F 2. 0.G 300.000 5000.000 102.06161 1 + 9.60788850E+00 3.71110260E-03-1.58991140E-06 3.02324640E-10-2.12285770E-14 2 +-9.47547680E+04-2.28489420E+01 1.73246800E+00 2.85017600E-02-2.94537980E-05 3 + 1.24013000E-08-1.17155330E-12-9.27813930E+04 1.69484100E+01-9.12343116E+04 4 +SO3 J 9/65S 1.O 3. 0. 0.G 300.000 5000.000 80.06420 1 + 7.07573760E+00 3.17633870E-03-1.35357600E-06 2.56309120E-10-1.79360440E-14 2 +-5.02113760E+04-1.11875176E+01 2.57803850E+00 1.45563350E-02-9.17641730E-06 3 +-7.92030220E-10 1.97094730E-12-4.89317530E+04 1.22651384E+01-4.75978348E+04 4 +S2 J 9/77S 2. 0. 0. 0.G 300.000 5000.000 64.13200 1 + 3.98860690E+00 5.57750510E-04-5.01892780E-08-1.54703190E-11 2.66617710E-15 2 + 1.41980150E+04 4.49119159E+00 2.85857540E+00 5.17583550E-03-6.54934340E-06 3 + 3.39986430E-09-4.01567660E-13 1.44124020E+04 9.89127849E+00 1.54434020E+04 4 +S2CL J 6/78S 2.CL 1. 0. 0.G 200.000 6000.000 99.58470 1 + 6.62320418E+00 4.18284634E-04-1.75659120E-07 3.09718384E-11-1.75155922E-15 2 + 7.37495900E+03-2.98511892E+00 2.97426932E+00 1.90782904E-02-3.76265413E-05 3 + 3.40374979E-08-1.15684664E-11 7.98922980E+03 1.38424354E+01 9.45335323E+03 4 +S2CL2 L 4/93S 2.CL 2. 0. 0.G 200.000 6000.000 135.03740 1 + 9.46841020E+00 1.12186352E-03-6.92784280E-07 1.38654463E-10-9.29397839E-15 2 +-5.05019524E+03-1.52950441E+01 3.47905708E+00 3.25370028E-02-6.63904620E-05 3 + 6.21124845E-08-2.17112325E-11-4.02225567E+03 1.22791824E+01-2.01286666E+03 4 +S2F2,thiothiony J 6/76S 2.F 2. 0. 0.G 200.000 6000.000 102.12881 1 + 8.94018671E+00 1.10450187E-03-4.36227657E-07 7.46298478E-11-4.62043951E-15 2 +-5.12574746E+04-1.66739137E+01 1.49372393E+00 3.42575635E-02-5.94656831E-05 3 + 4.87690344E-08-1.53761684E-11-4.98103490E+04 1.87375138E+01-4.82786117E+04 4 +S2O J 9/65S 2.O 1. 0. 0.G 300.000 5000.000 80.13140 1 + 5.90375240E+00 1.23699750E-03-5.45707900E-07 1.06598420E-10-7.66882430E-15 2 +-8.77520900E+03-2.26999836E+00 2.84142570E+00 1.21884100E-02-1.60002410E-05 3 + 1.03092890E-08-2.64491200E-12-8.06030150E+03 1.29180736E+01-6.79363039E+03 4 +S8 J 9/77S 8. 0. 0. 0.G 200.000 6000.000 256.52800 1 + 2.07249521E+01 1.34686111E-03-5.37225946E-07 9.28122853E-11-5.81951340E-15 2 + 5.53344324E+03-6.74805287E+01 4.19700496E+00 9.15503597E-02-1.91263611E-04 3 + 1.80177196E-07-6.30393695E-11 8.12071691E+03 7.58043917E+00 1.20776811E+04 4 +Si J 3/83SI 1. 0. 0. 0.G 200.000 6000.000 28.08550 1 + 2.58061157E+00-2.06044654E-04 1.93051677E-07-4.56485107E-11 3.36411716E-15 2 + 5.33829933E+04 5.60657423E+00 3.76476150E+00-7.12070985E-03 1.57318301E-05 3 +-1.53824969E-08 5.53194933E-12 5.32050782E+04 3.02168772E-01 5.41222513E+04 4 +Si+ J 3/83SI 1.E -1. 0. 0.G 298.150 6000.000 28.08495 1 + 2.64794579E+00-1.60109008E-04 6.54024155E-08-1.16224655E-11 7.55961272E-16 2 + 1.48703413E+05 4.73171848E+00 4.24419073E+00-7.51160863E-03 1.33368333E-05 3 +-1.09406149E-08 3.41357223E-12 1.48408792E+05-2.78917334E+00 1.49438151E+05 4 +SiBr J12/76SI 1.BR 1. 0. 0.G 300.000 5000.000 107.98950 1 + 4.66816920E+00-1.01694130E-04 7.08389920E-08-1.43348560E-11 1.40767390E-15 2 + 2.69334590E+04 3.22497259E+00 3.97197880E+00 4.77452790E-03-1.11306840E-05 3 + 1.06812020E-08-3.67263830E-12 2.69863040E+04 6.11195719E+00 2.83037975E+04 4 +SiBr2 J12/77SI 1.BR 2. 0. 0.G 300.000 5000.000 187.89350 1 + 6.72247700E+00 3.80579290E-04-2.01385890E-07 4.43511720E-11-2.92396510E-15 2 +-8.35929800E+03-1.81955711E+00 4.67197290E+00 1.02928970E-02-1.87140190E-05 3 + 1.56379000E-08-4.94565210E-12-8.00391630E+03 7.72665519E+00-6.29024918E+03 4 +SiBr3 J12/77SI 1.BR 3. 0. 0.G 300.000 5000.000 267.79750 1 + 9.58549680E+00 4.79238460E-04-2.14605950E-07 4.23382690E-11-3.06707940E-15 2 +-2.72445060E+04-1.27013080E+01 5.77296020E+00 1.83717870E-02-3.30193320E-05 3 + 2.73678640E-08-8.60387870E-12-2.65545540E+04 5.18627029E+00-2.42584791E+04 4 +SiBr4 J12/76SI 1.BR 4. 0. 0.G 300.000 5000.000 347.70150 1 + 1.24560870E+01 6.28443840E-04-2.81289510E-07 5.54744140E-11-4.01759590E-15 2 +-5.38505210E+04-2.58609090E+01 7.61089370E+00 2.32393840E-02-4.15457460E-05 3 + 3.43052410E-08-1.07550760E-11-5.29682090E+04-3.09903931E+00-4.99704412E+04 4 +SiC J 3/67SI 1.C 1. 0. 0.G 300.000 5000.000 40.09650 1 + 5.57990330E+00-1.34093440E-03 7.54830470E-07-1.65437780E-10 1.26633450E-14 2 + 8.50461200E+04-5.65019631E+00-2.19246960E+00 4.13427000E-02-7.82741130E-05 3 + 6.06941200E-08-1.67292070E-11 8.59531430E+04 2.87692430E+01 8.65575097E+04 4 +SiC2 J 3/67SI 1.C 2. 0. 0.G 300.000 5000.000 52.10750 1 + 5.70115230E+00 2.12206900E-03-1.14577690E-06 3.10387680E-10-2.77638970E-14 2 + 7.20233910E+04-4.97373211E+00 3.88063330E+00 6.79477670E-03-5.02779620E-06 3 + 1.05732320E-09 2.55131420E-13 7.25582490E+04 4.55056719E+00 7.39750561E+04 4 +SiC4H12 J12/60SI 1.C 4.H 12. 0.G 298.150 5000.000 88.22478 1 + 1.15637018E+01 3.28112064E-02-1.26370891E-05 2.26868511E-09-1.54269477E-13 2 +-4.01381366E+04-3.36341195E+01 4.94618626E+00 4.11429743E-02-2.93233742E-07 3 +-2.29003694E-08 1.09566773E-11-3.77310492E+04 3.18631099E+00-3.44703416E+04 4 +SiCL J12/76SI 1.CL 1. 0. 0.G 300.000 5000.000 63.53820 1 + 4.39828940E+00 1.67407870E-04-5.36062470E-08 9.57315490E-12-4.45308920E-16 2 + 2.25131450E+04 3.44495821E+00 3.73965330E+00 3.11647160E-03-5.24743830E-06 3 + 4.20125430E-09-1.28872220E-12 2.26382610E+04 6.56734951E+00 2.38530893E+04 4 +SiCL2 J12/77SI 1.CL 2. 0. 0.G 300.000 5000.000 98.99090 1 + 6.63078890E+00 4.38532790E-04-1.98113510E-07 3.70058730E-11-2.07143940E-15 2 +-2.23607190E+04-4.27487020E+00 3.71099610E+00 1.39663520E-02-2.47110540E-05 3 + 2.02592190E-08-6.31937030E-12-2.18259490E+04 9.46158180E+00-2.02800229E+04 4 +SiCL3 J12/77SI 1.CL 3. 0. 0.G 300.000 5000.000 134.44360 1 + 9.35946310E+00 7.38348380E-04-3.29940490E-07 6.49899730E-11-4.70232410E-15 2 +-4.99300680E+04-1.56480110E+01 4.26270270E+00 2.40508690E-02-4.21848820E-05 3 + 3.43739300E-08-1.06744620E-11-4.89812050E+04 8.40523855E+00-4.69511053E+04 4 +SiCL4 J12/70SI 1.CL 4. 0. 0.G 300.000 5000.000 169.89630 1 + 1.20896550E+01 1.01907350E-03-4.41678650E-07 8.44815730E-11-5.94915800E-15 2 +-8.35902500E+04-2.99269336E+01 6.10400100E+00 2.49331140E-02-3.67032630E-05 3 + 2.44487480E-08-6.03701550E-12-8.23592730E+04-9.76400498E-01-7.97099719E+04 4 +SiF J12/76SI 1.F 1. 0. 0.G 300.000 5000.000 47.08390 1 + 4.12278350E+00 4.68048910E-04-1.86776750E-07 3.52420930E-11-2.30150460E-15 2 +-3.72586190E+03 3.38858669E+00 3.24535350E+00 2.97023310E-03-2.48579900E-06 3 + 5.63048360E-10 1.44160340E-13-3.49442720E+03 7.88443469E+00-2.41558858E+03 4 +SiF2 J12/77SI 1.F 2. 0. 0.G 300.000 5000.000 66.08231 1 + 6.05621040E+00 1.07219520E-03-4.71297580E-07 9.01747640E-11-6.13709050E-15 2 +-7.27270830E+04-4.35994757E+00 2.51482400E+00 1.45041570E-02-2.05947790E-05 3 + 1.41301760E-08-3.81323260E-12-7.19424330E+04 1.30046348E+01-7.07038037E+04 4 +SiF3 J12/77SI 1.F 3. 0. 0.G 300.000 5000.000 85.08071 1 + 8.34881910E+00 1.87723690E-03-8.31771250E-07 1.62907180E-10-1.17385330E-14 2 +-1.33399870E+05-1.48343890E+01 2.34802200E+00 2.46650330E-02-3.51093500E-05 3 + 2.42326900E-08-6.59094160E-12-1.32068720E+05 1.45901830E+01-1.30537786E+05 4 +SiF4 J 6/76SI 1.F 4. 0. 0.G 300.000 5000.000 104.07911 1 + 1.04784730E+01 2.85867560E-03-1.26463140E-06 2.47468630E-10-1.78242960E-14 2 +-1.97905500E+05-2.75074780E+01 2.18930680E+00 3.37020070E-02-4.67231790E-05 3 + 3.15846380E-08-8.45061140E-12-1.96032890E+05 1.33004710E+01-1.94236568E+05 4 +SiH J12/76SI 1.H 1. 0. 0.G 300.000 5000.000 29.09344 1 + 3.04531940E+00 1.55875260E-03-6.20726770E-07 1.15182700E-10-7.62897730E-15 2 + 4.43311260E+04 6.04465545E+00 4.33629540E+00-5.05124220E-03 1.14230960E-05 3 +-9.38906520E-09 2.77181490E-12 4.41507140E+04 1.88214679E-01 4.53027449E+04 4 +SiH+ J12/71SI 1.H 1.E -1. 0.G 300.000 5000.000 29.09289 1 + 2.98285950E+00 1.54552220E-03-5.90385550E-07 1.05174000E-10-6.82202340E-15 2 + 1.37079540E+05 5.04035014E+00 3.72925880E+00-1.78816110E-03 4.24692570E-06 3 +-2.55801300E-09 4.06337400E-13 1.36970710E+05 1.58387314E+00 1.38035768E+05 4 +SiHBr3 J12/76SI 1.H 1.BR 3. 0.G 300.000 5000.000 268.80544 1 + 1.02748310E+01 2.86661040E-03-1.21125810E-06 2.30049160E-10-1.62335040E-14 2 +-3.98465760E+04-1.80340658E+01 4.33701100E+00 2.88729900E-02-4.69541200E-05 3 + 3.75230380E-08-1.16349190E-11-3.86638340E+04 1.03216712E+01-3.64336173E+04 4 +SiHCL3 J12/76SI 1.H 1.CL 3. 0.G 300.000 5000.000 135.45154 1 + 9.93356350E+00 3.24812200E-03-1.37871710E-06 2.62660730E-10-1.85748860E-14 2 +-6.30708490E+04-2.04720585E+01 2.67420420E+00 3.43803850E-02-5.49538560E-05 3 + 4.31033320E-08-1.31570120E-11-6.16017230E+04 1.43335095E+01-5.96828537E+04 4 +SiHF3 J 6/76SI 1.H 1.F 3. 0.G 300.000 5000.000 86.08865 1 + 8.75488280E+00 4.55277560E-03-1.94775310E-06 3.73007940E-10-2.64739730E-14 2 +-1.47656580E+05-1.88269773E+01 9.06548160E-01 3.32652670E-02-4.39288250E-05 3 + 2.93283670E-08-7.86491880E-12-1.45841960E+05 1.99732657E+01-1.44426999E+05 4 +SiHI3 J12/76SI 1.H 1.I 3. 0.G 300.000 5000.000 409.80685 1 + 1.05336040E+01 2.58880000E-03-1.09219030E-06 2.07206870E-10-1.46098540E-14 2 +-1.23973450E+04-1.60950342E+01 5.52112250E+00 2.48410540E-02-4.08339840E-05 3 + 3.30683930E-08-1.03737740E-11-1.14071890E+04 7.78466951E+00-8.95727317E+03 4 +SiH2 TPIS79SI 1.H 2. 0. 0.G 298.150 5000.000 30.10138 1 + 5.85938550E+00 1.63825650E-03-8.43962520E-07 1.83233300E-10-1.41143650E-14 2 + 2.71656990E+04-1.00646310E+01 5.31078530E+00-1.44699450E-02 5.14271460E-05 3 +-5.47334740E-08 1.92882860E-11 2.82133940E+04-2.82241862E+00 2.95089590E+04 4 +SiH2Br2 J12/76SI 1.H 2.BR 2. 0.G 300.000 5000.000 189.90938 1 + 8.16926010E+00 5.02856010E-03-2.10975640E-06 3.98721550E-10-2.80358380E-14 2 +-2.58424750E+04-1.13711914E+01 2.00074270E+00 3.02826310E-02-4.46873360E-05 3 + 3.44114310E-08-1.05487200E-11-2.45075070E+04 1.85667366E+01-2.28968040E+04 4 +SiH2CL2 J12/76SI 1.H 2.CL 2. 0.G 300.000 5000.000 101.00678 1 + 7.91214040E+00 5.31278910E-03-2.23367290E-06 4.22748120E-10-2.97556840E-14 2 +-4.14685030E+04-1.28867627E+01 1.02649380E+00 3.30135890E-02-4.79610620E-05 3 + 3.62256760E-08-1.09204470E-11-3.99633870E+04 2.06288573E+01-3.85472871E+04 4 +SiH2F2 J 6/76SI 1.H 2.F 2. 0.G 300.000 5000.000 68.09819 1 + 7.09818570E+00 6.21464900E-03-2.62723520E-06 4.99090850E-10-3.52216410E-14 2 +-9.79187450E+04-1.16725694E+01 1.93759980E-01 3.00798800E-02-3.58741360E-05 3 + 2.26685580E-08-5.91859250E-12-9.62303270E+04 2.28607536E+01-9.51105435E+04 4 +SiH2I2 J12/76SI 1.H 2.I 2. 0.G 300.000 5000.000 283.91032 1 + 8.35730990E+00 4.81635860E-03-2.01614450E-06 3.80436990E-10-2.67205840E-14 2 +-7.54176670E+03-1.02973549E+01 2.65628130E+00 2.86261760E-02-4.30037000E-05 3 + 3.37080310E-08-1.04755470E-11-6.32526120E+03 1.72709251E+01-4.57921431E+03 4 +SiH3 TPIS79SI 1.H 3. 0. 0.G 298.150 5000.000 31.10932 1 + 4.12703760E+00 6.18388660E-03-2.61220960E-06 4.95796950E-10-3.49605200E-14 2 + 2.34068010E+04 1.51808423E-01 3.05068070E+00 3.31032830E-03 1.10939970E-05 3 +-1.44834900E-08 5.18803540E-12 2.40514240E+04 7.29482068E+00 2.51799610E+04 4 +SiH3Br J12/76SI 1.H 3.BR 1. 0.G 300.000 5000.000 111.01332 1 + 6.13503630E+00 7.11129140E-03-2.97350750E-06 5.60618570E-10-3.93508470E-14 2 +-1.18799000E+04-6.17826569E+00 1.00603350E+00 2.53078760E-02-3.03964330E-05 3 + 2.10821500E-08-6.20553980E-12-1.06053600E+04 1.94675446E+01-9.41037333E+03 4 +SiH3CL J12/76SI 1.H 3.CL 1. 0.G 300.000 5000.000 66.56202 1 + 5.99197180E+00 7.27189380E-03-3.04415900E-06 5.74396200E-10-4.03409290E-14 2 +-1.95149300E+04-6.86764367E+00 5.83079850E-01 2.61617280E-02-3.08540730E-05 3 + 2.08783950E-08-6.01536780E-12-1.81619790E+04 2.02365379E+01-1.70595010E+04 4 +SiH3F J 6/76SI 1.H 3.F 1. 0.G 300.000 5000.000 50.10772 1 + 5.57361190E+00 7.74100750E-03-3.25027580E-06 6.14547920E-10-4.32237740E-14 2 +-4.76884860E+04-6.21002292E+00 3.73697260E-01 2.33710360E-02-2.19259730E-05 3 + 1.14386680E-08-2.62175980E-12-4.62686760E+04 2.04541298E+01-4.52908362E+04 4 +SiH3I J12/76SI 1.H 3.I 1. 0.G 300.000 5000.000 158.01379 1 + 6.26866630E+00 6.96523050E-03-2.91027400E-06 5.48414670E-10-3.84800880E-14 2 +-2.73735270E+03-5.82845156E+00 1.36593200E+00 2.45925750E-02-2.99917950E-05 3 + 2.12151430E-08-6.34829710E-12-1.52583550E+03 1.86403979E+01-2.51567625E+02 4 +SiH4 J 6/76SI 1.H 4. 0. 0.G 300.000 5000.000 32.11726 1 + 4.20920380E+00 9.08226280E-03-3.79053960E-06 7.13698880E-10-5.00462860E-14 2 + 2.13446270E+03-2.72768704E+00 1.59226390E+00 1.28410930E-02-1.94562780E-06 3 +-4.31063720E-09 1.98748800E-12 3.10559420E+03 1.18336025E+01 4.12630413E+03 4 +SiI J12/76SI 1.I 1. 0. 0.G 300.000 5000.000 154.98997 1 + 4.97495320E+00-4.08019210E-04 1.91996740E-07-3.88865530E-11 3.85524220E-15 2 + 3.62617270E+04 2.30166920E+00 2.80447120E+00 1.22053060E-02-2.58769970E-05 3 + 2.31709660E-08-7.57984720E-12 3.65294880E+04 1.18753077E+01 3.77217187E+04 4 +SiI2 J12/77SI 1.I 2. 0. 0.G 200.000 6000.000 281.89444 1 + 6.74311855E+00 3.61983156E-04-1.95278644E-07 4.35823201E-11-2.89986792E-15 2 + 9.06975364E+03 1.29097213E-02 4.32155105E+00 1.44273380E-02-3.10517647E-05 3 + 2.98319286E-08-1.05785473E-11 9.41218202E+03 1.08178567E+01 1.11215213E+04 4 +SiN J 3/67SI 1.N 1. 0. 0.G 300.000 5000.000 42.09224 1 + 3.98586210E+00-8.79270560E-06 5.42695390E-07-1.79510170E-10 1.63370690E-14 2 + 4.35248090E+04 3.17468002E+00 3.10519550E+00 1.48524490E-03 1.85610600E-06 3 +-3.77348830E-09 1.68353310E-12 4.37857090E+04 7.88856052E+00 4.47872738E+04 4 +SiO J 9/67SI 1.O 1. 0. 0.G 300.000 5000.000 44.08490 1 + 3.74788350E+00 8.19919430E-04-3.25253960E-07 5.73249620E-11-3.51089440E-15 2 +-1.33174300E+04 3.66100339E+00 3.25282760E+00 4.18231260E-04 3.78062020E-06 3 +-5.10244830E-09 1.94713170E-12-1.30903400E+04 6.66174329E+00-1.20776829E+04 4 +SiO2 J 9/67SI 1.O 2. 0. 0.G 300.000 5000.000 60.08430 1 + 5.86203950E+00 1.77197840E-03-7.51941940E-07 1.41805840E-10-9.88564170E-15 2 +-3.87678160E+04-6.84718711E+00 3.26280580E+00 8.50165840E-03-5.73881440E-06 3 + 1.28965730E-11 9.75449760E-13-3.80359710E+04 6.66807529E+00-3.67355093E+04 4 +SiS J12/71SI 1.S 1. 0. 0.G 300.000 5000.000 60.15150 1 + 4.17357720E+00 3.92825950E-04-1.50051720E-07 2.32425570E-11-6.05688670E-16 2 + 1.14177530E+04 2.86888232E+00 2.84306930E+00 5.11502810E-03-6.33160730E-06 3 + 3.43873260E-09-6.26233850E-13 1.17189310E+04 9.44619192E+00 1.27444997E+04 4 +Si2 J 3/67SI 2. 0. 0. 0.G 300.000 5000.000 56.17100 1 + 5.04741390E+00 5.39900340E-04-4.30783760E-07 1.13552060E-10-9.62628710E-15 2 + 6.91331850E+04-1.91029481E+00 3.81553930E+00-1.90965420E-04 5.92334160E-06 3 +-5.76496030E-09 1.47750040E-12 6.97846550E+04 5.74071859E+00 7.09554076E+04 4 +Si2C J 3/67SI 2.C 1. 0. 0.G 300.000 5000.000 68.18200 1 + 6.25109880E+00 1.32241760E-03-7.28052140E-07 2.32694240E-10-2.32851480E-14 2 + 6.23009990E+04-7.28347851E+00 4.04389380E+00 7.34569570E-03-6.64125490E-06 3 + 2.48850470E-09-1.81965550E-13 6.29354170E+04 4.18441209E+00 6.44137539E+04 4 +Si2N J 3/67SI 2.N 1. 0. 0.G 300.000 5000.000 70.17774 1 + 6.67099120E+00 9.19178820E-04-3.95171300E-07 7.43971450E-11-5.02846910E-15 2 + 4.56201540E+04-7.79827766E+00 3.66867350E+00 1.13018400E-02-1.36371190E-05 3 + 7.16880500E-09-1.23783100E-12 4.63180830E+04 7.12270964E+00 4.78073289E+04 4 +Si3 J 3/67SI 3. 0. 0. 0.G 300.000 5000.000 84.25650 1 + 7.42133600E+00-1.17099480E-04 8.98207750E-08 7.19359640E-12-2.56708370E-15 2 + 7.41466990E+04-1.03521110E+01 4.59791290E+00 1.07152740E-02-1.61004220E-05 3 + 1.09692070E-08-2.78328750E-12 7.47663240E+04 3.45533009E+00 7.64915691E+04 4 +Sr L 4/93SR 1. 0. 0. 0.G 200.000 6000.000 87.62000 1 + 2.05239982E+00 1.19516449E-03-1.07453395E-06 3.57530976E-10-3.05613280E-14 2 + 1.91041043E+04 7.88029928E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 1.89791788E+04 5.55782092E+00 1.97245538E+04 4 +SrBr J12/74SR 1.BR 1. 0. 0.G 300.000 5000.000 167.52400 1 + 4.34361580E+00 3.98959430E-04-2.59761260E-07 7.93207470E-11-6.60838300E-15 2 +-1.20250730E+04 6.87371079E+00 4.09700710E+00 1.93210600E-03-3.50688920E-06 3 + 2.99661940E-09-9.63316960E-13-1.20006440E+04 7.93438499E+00-1.07187613E+04 4 +SrCL J12/72SR 1.CL 1. 0. 0.G 300.000 5000.000 123.07270 1 + 4.33444180E+00 3.89521120E-04-2.44613120E-07 7.32843650E-11-5.97333250E-15 2 +-1.62087810E+04 5.52525593E+00 3.90361850E+00 2.46344280E-03-3.87769650E-06 3 + 2.83033750E-09-7.73041200E-13-1.61397400E+04 7.51664683E+00-1.48954147E+04 4 +SrCL2 J12/72SR 1.CL 2. 0. 0.G 300.000 5000.000 158.52540 1 + 6.89643620E+00 1.17887180E-04-5.18540800E-08 1.00488310E-11-7.15843480E-16 2 +-5.90069040E+04-1.35434839E+00 5.89071410E+00 4.49427890E-03-7.29894040E-06 3 + 5.35881350E-09-1.47306310E-12-5.88164040E+04 3.42525071E+00-5.69149221E+04 4 +SrF J12/72SR 1.F 1. 0. 0.G 300.000 5000.000 106.61840 1 + 4.24571640E+00 4.66335870E-04-2.69258960E-07 7.35600800E-11-5.72137600E-15 2 +-3.67402990E+04 4.46607869E+00 3.27139470E+00 4.62133540E-03-6.90077500E-06 3 + 4.72335820E-09-1.20468070E-12-3.65556300E+04 9.10702069E+00-3.54270622E+04 4 +SrF+ J12/72SR 1.F 1.E -1. 0.G 300.000 5000.000 106.61785 1 + 5.61355180E+00-2.18109170E-03 1.22152480E-06-1.63329710E-10 3.25845090E-15 2 + 2.18821400E+04-3.90142032E+00 3.10937910E+00 5.02700350E-03-7.26893380E-06 3 + 4.79485010E-09-1.16838470E-12 2.26072020E+04 9.07411038E+00 2.37024013E+04 4 +SrF2 J12/72SR 1.F 2. 0. 0.G 300.000 5000.000 125.61681 1 + 6.75478910E+00 2.77619640E-04-1.21588780E-07 2.34787800E-11-1.66751920E-15 2 +-9.42336320E+04-3.64195389E+00 4.81355160E+00 8.38216020E-03-1.29995310E-05 3 + 9.13543920E-09-2.39898770E-12-9.38505430E+04 5.66408021E+00-9.21407511E+04 4 +SrI2 J 6/74SR 1.I 2. 0. 0.G 300.000 5000.000 341.42894 1 + 7.46036780E+00 4.54034760E-05-2.00932740E-08 3.91555060E-12-2.80309800E-16 2 +-3.53003330E+04-1.70876927E+00 7.04504070E+00 1.88416990E-03-3.11751490E-06 3 + 2.32993910E-09-6.52321330E-13-3.52230130E+04 2.57821783E-01-3.30620353E+04 4 +SrO J 6/74SR 1.O 1. 0. 0.G 300.000 5000.000 103.61940 1 + 9.64030240E+00-1.12851500E-02 7.88423220E-06-1.90358770E-09 1.51465470E-13 2 +-4.74994870E+03-2.57981700E+01 2.73299970E+00 6.73994180E-03-1.08004850E-05 3 + 8.17679370E-09-2.36198710E-12-2.64435740E+03 1.05012900E+01-1.61032207E+03 4 +SrOH J12/75SR 1.O 1.H 1. 0.G 300.000 5000.000 104.62734 1 + 5.35708400E+00 1.73507350E-03-6.83396470E-07 1.41070680E-10-1.04150390E-14 2 +-2.63891730E+04-1.38738754E+00 2.52764940E+00 1.73648540E-02-3.17357230E-05 3 + 2.69096460E-08-8.52700990E-12-2.60126780E+04 1.12603266E+01-2.47184763E+04 4 +SrOH+ J 6/76SR 1.O 1.H 1.E -1.G 300.000 5000.000 104.62679 1 + 5.49519810E+00 1.42140660E-03-4.32450190E-07 6.23424290E-11-3.47974840E-15 2 + 3.68741070E+04-2.77068358E+00 2.61018070E+00 1.70676770E-02-3.12755560E-05 3 + 2.65708540E-08-8.43013950E-12 3.72752290E+04 1.02040867E+01 3.85842705E+04 4 +SrO2H2 J12/75SR 1.O 2.H 2. 0.G 300.000 5000.000 121.63468 1 + 9.02326740E+00 2.80491020E-03-8.47910070E-07 1.21324930E-10-6.71541830E-15 2 +-7.44850350E+04-1.56026680E+01 3.36588500E+00 3.37099400E-02-6.20281710E-05 3 + 5.28432690E-08-1.67960460E-11-7.37093680E+04 9.78559688E+00-7.16590447E+04 4 +SrS J 9/77SR 1.S 1. 0. 0.G 300.000 5000.000 119.68600 1 + 8.98347000E+00-1.09956910E-02 8.65884170E-06-2.29554820E-09 1.96596830E-13 2 + 1.03014190E+04-2.00762668E+01 3.48633180E+00 4.38413110E-03-7.50675530E-06 3 + 5.81928180E-09-1.63532040E-12 1.18348540E+04 8.35263069E+00 1.30135709E+04 4 +Ta J12/72TA 1. 0. 0. 0.G 300.000 5000.000 180.94790 1 + 1.51090940E+00 2.70295010E-03-1.07055940E-06 2.02388530E-10-1.39701730E-14 2 + 9.35177620E+04 1.29827060E+01 2.83816310E+00-2.78785630E-03 6.89733340E-06 3 +-4.55717510E-09 9.41252680E-13 9.32787930E+04 6.66893679E+00 9.40534557E+04 4 +TaO J12/73TA 1.O 1. 0. 0.G 300.000 5000.000 196.94730 1 + 3.49966030E+00 1.51125350E-03-6.53845780E-07 1.77843140E-10-1.69194050E-14 2 + 2.19941510E+04 8.52695899E+00 2.93401080E+00 3.05920380E-03-1.93963640E-06 3 + 1.62888300E-10 3.01525350E-13 2.21544720E+04 1.14546460E+01 2.31485470E+04 4 +TaO2 J12/73TA 1.O 2. 0. 0.G 300.000 5000.000 212.94670 1 + 5.97016690E+00 1.17921280E-03-5.65174130E-07 1.31137870E-10-1.05644370E-14 2 +-2.61694810E+04-1.07399801E+00 3.18038260E+00 9.47028050E-03-8.73468680E-06 3 + 2.45226890E-09 3.36534210E-13-2.54517620E+04 1.31303530E+01-2.41547719E+04 4 +Ti J 6/79TI 1. 0. 0. 0.G 200.000 6000.000 47.88000 1 + 3.03774314E+00-1.11117144E-03 7.58571090E-07-1.27073773E-10 6.90819279E-15 2 + 5.61236728E+04 4.73001888E+00 4.14448119E+00-6.80469009E-03 1.18867765E-05 3 +-9.75223462E-09 3.09064423E-12 5.59438352E+04-3.48187822E-01 5.69642709E+04 4 +Ti+ J 3/84TI 1.E -1. 0. 0.G 298.150 6000.000 47.87945 1 + 3.67371639E+00-1.48559525E-03 7.82266735E-07-1.43853227E-10 8.95284394E-15 2 + 1.35855735E+05 1.53150180E+00 2.79511128E+00 2.52231176E-03-5.63121401E-06 3 + 4.16371169E-09-1.01443322E-12 1.35995999E+05 5.61951580E+00 1.36899469E+05 4 +Ti- J 3/84TI 1.E 1. 0. 0.G 298.150 6000.000 47.88055 1 + 2.58526086E+00-9.08419479E-05 3.64323275E-08-6.31640098E-12 3.97035041E-16 2 + 5.45643467E+04 7.45711066E+00 3.58958633E+00-4.91444420E-03 9.06483220E-06 3 +-7.66228403E-09 2.44724157E-12 5.43869787E+04 2.76915648E+00 5.53048827E+04 4 +TiCL J12/68TI 1.CL 1. 0. 0.G 300.000 5000.000 83.33270 1 + 5.29697600E+00-1.64016920E-04 1.57197610E-07-3.85670890E-11 3.07396630E-15 2 + 1.68576740E+04-4.94472671E-01 2.85430890E+00 7.95933450E-03-9.82111620E-06 3 + 5.24199810E-09-9.79861770E-13 1.74412160E+04 1.17302246E+01 1.85691235E+04 4 +TiCL2 J12/68TI 1.CL 2. 0. 0.G 300.000 5000.000 118.78540 1 + 7.76248520E+00-9.38724250E-04 8.01215180E-07-1.90480300E-10 1.49615450E-14 2 +-3.09158050E+04-1.07526011E+01 4.97234750E+00 1.12773350E-02-2.05819160E-05 3 + 1.71866500E-08-5.40495900E-12-3.03662850E+04 2.55909638E+00-2.85329650E+04 4 +TiCL3 J12/68TI 1.CL 3. 0. 0.G 300.000 5000.000 154.23810 1 + 1.00081030E+01 4.19363740E-04-2.15048730E-07 4.53370180E-11-3.45468380E-15 2 +-6.80612500E+04-1.95106532E+01 2.88015570E+00 3.35589330E-02-5.99574600E-05 3 + 4.88636640E-08-1.50909920E-11-6.67760230E+04 1.39582088E+01-6.48659962E+04 4 +TiCL4 J12/67TI 1.CL 4. 0. 0.G 300.000 5000.000 189.69080 1 + 1.23860300E+01 7.09313160E-04-3.17460780E-07 6.26039580E-11-4.53370380E-15 2 +-9.56690780E+04-2.84715956E+01 6.94967570E+00 2.60496590E-02-4.65203020E-05 3 + 3.83848340E-08-1.20279150E-11-9.46778310E+04-2.92575094E+00-9.17887862E+04 4 +TiO J12/73TI 1.O 1. 0. 0.G 300.000 5000.000 63.87940 1 + 4.13601760E+00 7.39264580E-04-4.54444640E-07 1.30436580E-10-1.15225570E-14 2 + 5.19834830E+03 4.12237043E+00 3.11988810E+00 3.12024870E-03-1.32970730E-06 3 +-1.33383620E-09 9.63158280E-13 5.48687190E+03 9.44261203E+00 6.54182283E+03 4 +TiOCL J 9/63TI 1.O 1.CL 1. 0.G 300.000 5000.000 99.33210 1 + 6.83199240E+00 7.63593870E-04-3.39530890E-07 6.66670690E-11-4.81329460E-15 2 +-3.15823110E+04-7.75381613E+00 3.40938560E+00 1.51705540E-02-2.44284830E-05 3 + 1.87345210E-08-5.56806840E-12-3.08878460E+04 8.69442617E+00-2.93784839E+04 4 +TiOCL2 J 9/63TI 1.O 1.CL 2. 0.G 300.000 5000.000 134.78480 1 + 9.33686550E+00 7.59699870E-04-3.38273780E-07 6.64838630E-11-4.80337930E-15 2 +-6.85726450E+04-1.51441772E+01 5.44081400E+00 1.77050490E-02-2.95252410E-05 3 + 2.32473280E-08-7.04797770E-12-6.78068540E+04 3.45077325E+00-6.56159812E+04 4 +TiO2 J12/73TI 1.O 2. 0. 0.G 300.000 5000.000 79.87880 1 + 5.84550610E+00 1.39382130E-03-6.64030620E-07 1.38573800E-10-9.88421840E-15 2 +-3.87005930E+04-2.79599903E+00 3.01427170E+00 1.09421010E-02-1.28785880E-05 3 + 7.11895290E-09-1.49275100E-12-3.80205010E+04 1.13643975E+01-3.67358715E+04 4 +V J 6/73V 1. 0. 0. 0.G 300.000 5000.000 50.94150 1 + 2.91778520E+00 4.62368900E-04-4.97320300E-07 1.67752330E-10-1.52025520E-14 2 + 6.10642730E+04 5.10621469E+00 4.51736930E+00-7.92906600E-03 1.33808390E-05 3 +-8.82829010E-09 1.89453070E-12 6.09014170E+04-1.96971791E+00 6.19975154E+04 4 +VCL4 L 2/76V 1.CL 4. 0. 0.G 300.000 5000.000 192.75230 1 + 1.27186470E+01 1.66001760E-05 1.41614980E-07-3.47618330E-11 2.28897630E-15 2 +-6.71879920E+04-2.88480103E+01 7.11664620E+00 2.54232170E-02-4.54990170E-05 3 + 3.75838860E-08-1.17803440E-11-6.61238930E+04-2.33095475E+00-6.32053523E+04 4 +VN J12/73V 1.N 1. 0. 0.G 300.000 5000.000 64.94824 1 + 4.18522800E+00 6.15147200E-04-3.57763350E-07 1.07488620E-10-9.72755050E-15 2 + 6.15115400E+04 3.77618661E+00 2.72335900E+00 4.16429890E-03-2.19128120E-06 3 +-1.23518720E-09 1.07918330E-12 6.19278930E+04 1.14173579E+01 6.29036613E+04 4 +VO J12/73V 1.O 1. 0. 0.G 300.000 5000.000 66.94090 1 + 3.91147020E+00 7.75477920E-04-4.22637860E-07 1.16088380E-10-1.00707240E-14 2 + 1.40652040E+04 5.07185409E+00 2.94384410E+00 2.90592340E-03-9.95165750E-07 3 +-1.40865920E-09 9.24385080E-13 1.43527460E+04 1.01864310E+01 1.53484728E+04 4 +VO2 J12/73V 1.O 2. 0. 0.G 300.000 5000.000 82.94030 1 + 5.94701470E+00 1.16867790E-03-5.05363790E-07 9.67236110E-11-6.82458830E-15 2 +-2.99838020E+04-2.73802511E+00 3.19378590E+00 9.29794570E-03-8.34224690E-06 3 + 2.10491700E-09 4.45826450E-13-2.92754910E+04 1.12872190E+01-2.79793321E+04 4 +Xe L12/91XE 1. 0. 0. 0.G 200.000 6000.000 131.29000 1 + 2.50005322E+00-1.05136544E-07 6.75326897E-11-1.70944909E-14 1.47681049E-18 2 +-7.45394186E+02 6.16412898E+00 2.50000000E+00-8.99141330E-14 2.52196860E-16 3 +-2.92186662E-19 1.18949218E-22-7.45375000E+02 6.16441993E+00 0.00000000E+00 4 +Xe+ L10/92XE 1.E -1. 0. 0.G 298.150 6000.000 131.28945 1 + 2.58350579E+00-1.53488750E-04 8.09594639E-08-1.14289234E-11 4.82081406E-16 2 + 1.40730117E+05 7.09057069E+00 2.50007477E+00-6.25614186E-07 1.86430963E-09 3 +-2.35599457E-12 1.07219368E-15 1.40761095E+05 7.55040438E+00 1.41506477E+05 4 +Zn L 7/93ZN 1. 0. 0. 0.G 200.000 6000.000 65.39000 1 + 2.51233674E+00-2.92859430E-05 2.43130241E-08-8.39058754E-12 1.02676892E-15 2 + 1.49341449E+04 5.05331145E+00 2.50000000E+00-4.89383187E-12 1.38012101E-14 3 +-1.58679678E-17 6.38498776E-21 1.49380507E+04 5.11886101E+00 1.56834257E+04 4 +Zn+ L 7/93ZN 1. 0. 0. 0.G 200.000 6000.000 65.39000 1 + 2.48069577E+00 3.36021020E-05-1.60287169E-08 1.43795031E-12 2.92898690E-16 2 + 1.23956404E+05 5.91921683E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 1.23948976E+05 5.81200819E+00 1.24694351E+05 4 +Zn- J12/78ZN 1.E 1. 0. 0.G 298.150 6000.000 65.39055 1 + 2.50000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 1.24688733E+04 5.81202078E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 1.24688733E+04 5.81202078E+00 1.32142483E+04 4 +Zr L 7/93ZR 1. 0. 0. 0.G 200.000 6000.000 91.22400 1 + 2.54294206E+00 6.22889707E-04-1.07432636E-07 2.38744516E-11-2.17632296E-15 2 + 7.27918166E+04 7.57951451E+00 1.23655929E+00 1.28280820E-02-2.72138432E-05 3 + 2.33237341E-08-7.09443491E-12 7.26245603E+04 1.19581447E+01 7.33657185E+04 4 +ZrN J 6/63ZR 1.N 1. 0. 0.G 200.000 6000.000 105.23074 1 + 4.14378922E+00 4.04307213E-04-1.44633107E-07 2.47606374E-11-1.54280202E-15 2 + 8.44614200E+04 4.15937906E+00 3.07188717E+00 2.64300474E-03 3.18499428E-07 3 +-3.63350581E-09 2.02679564E-12 8.47684947E+04 9.80588987E+00 8.57984415E+04 4 +ZrO L 7/93ZR 1.O 1. 0. 0.G 200.000 6000.000 107.22340 1 + 7.29696029E+00-2.90119328E-03 1.15957574E-06-1.80299021E-10 1.01758876E-14 2 + 7.68180377E+03-1.42192551E+01 4.12291576E+00-1.31886153E-02 6.92922420E-05 3 +-9.58719313E-08 4.10306085E-11 9.00749212E+03 5.56945930E+00 1.00926504E+04 4 +ZrO2 J12/65ZR 1.O 2. 0. 0.G 300.000 5000.000 123.22280 1 + 6.14185450E+00 9.77036950E-04-4.33371820E-07 8.49545890E-11-6.12666480E-15 2 +-3.64461780E+04-2.70978912E+00 3.21037790E+00 1.16289760E-02-1.55753600E-05 3 + 1.00442430E-08-2.54388900E-12-3.57756120E+04 1.17738677E+01-3.44205252E+04 4 +AL(cr) CODA89AL 1. 0. 0. 0.C 200.000 933.610 26.98154 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 1.01040191E+00 1.20769743E-02-2.62083556E-05 3 + 2.64282413E-08-9.01916513E-12-6.54454196E+02-5.00471254E+00 0.00000000E+00 4 +AL(L) CODA89AL 1. 0. 0. 0.C 933.610 6000.000 26.98154 1 + 3.81862551E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-9.49651808E+01-1.75229704E+01 3.81862551E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-9.49651808E+01-1.75229704E+01 0.00000000E+00 4 +ALBr3(s) J 9/79AL 1.BR 3. 0. 0.C 300.000 370.600 266.69354 1 + 5.84479560E+00 2.09263340E-02 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-6.41705100E+04-1.78769010E+01 5.84479560E+00 2.09263340E-02 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-6.41705100E+04-1.78769010E+01-6.14977775E+04 4 +ALBr3(L) J 9/79AL 1.BR 3. 0. 0.C 370.600 5000.000 266.69354 1 + 1.50297500E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-6.47837290E+04-6.07991010E+01 1.50297500E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-6.47837290E+04-6.07991010E+01 0.00000000E+00 4 +ALCL3(s) J 9/79AL 1.CL 3. 0. 0.C 300.000 465.700 133.33964 1 + 7.80933750E+00 1.05709850E-02-3.28592480E-09 0.00000000E+00 0.00000000E+00 2 +-8.76667830E+04-3.45017220E+01 7.80933750E+00 1.05709850E-02-3.28592480E-09 3 + 0.00000000E+00 0.00000000E+00-8.76667830E+04-3.45017220E+01-8.48686125E+04 4 +ALCL3(L) J 9/79AL 1.CL 3. 0. 0.C 465.700 5000.000 133.33964 1 + 1.50966790E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-8.56620790E+04-6.52184190E+01 1.50966790E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-8.56620790E+04-6.52184190E+01 0.00000000E+00 4 +ALF3(a) J 9/79AL 1.F 3. 0. 0.C 300.000 728.000 83.97675 1 +-3.08352720E+00 7.03503170E-02-1.22494050E-04 7.62413620E-08 1.58436870E-12 2 +-1.82940320E+05 9.35706830E+00-3.08352720E+00 7.03503170E-02-1.22494050E-04 3 + 7.62413620E-08 1.58436870E-12-1.82940320E+05 9.35706830E+00-1.81663648E+05 4 +ALF3(b) J 9/79AL 1.F 3. 0. 0.C 728.000 2523.000 83.97675 1 + 1.04194700E+01 2.33765010E-03-8.80830770E-07 2.85578830E-10-3.46072630E-14 2 +-1.84922050E+05-5.23714020E+01 9.50345050E+00 5.13025090E-03-3.71167640E-06 3 + 1.20523570E-09 0.00000000E+00-1.84695550E+05-4.77361470E+01 0.00000000E+00 4 +ALF3(L) J 9/79AL 1.F 3. 0. 0.C 2523.000 5000.000 83.97675 1 + 1.50966790E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.79986860E+05-8.00491030E+01 1.50966790E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.79986860E+05-8.00491030E+01 0.00000000E+00 4 +ALI3(s) J 9/79AL 1.I 3. 0. 0.C 300.000 464.140 407.69495 1 + 8.52416000E+00 1.12577990E-02 1.64430050E-07 0.00000000E+00 0.00000000E+00 2 +-3.94766660E+04-2.83445950E+01 8.52416000E+00 1.12577990E-02 1.64430050E-07 3 + 0.00000000E+00 0.00000000E+00-3.94766660E+04-2.83445950E+01-3.64333629E+04 4 +ALI3(L) J 9/79AL 1.I 3. 0. 0.C 464.140 5000.000 407.69495 1 + 1.45934560E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-3.91633320E+04-5.62483220E+01 1.45934560E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-3.91633320E+04-5.62483220E+01 0.00000000E+00 4 +ALN(s) J12/79AL 1.N 1. 0. 0.C 300.000 3000.000 40.98828 1 + 4.08412120E+00 3.18814960E-03-1.90297650E-06 5.25234110E-10-5.51330660E-14 2 +-3.97818430E+04-2.21901450E+01-1.54500310E+00 2.76322490E-02-4.35394640E-05 3 + 3.30926660E-08-9.80105240E-12-3.86886140E+04 4.64928220E+00-3.82449879E+04 4 +AL2O3(a) J12/79AL 2.O 3. 0. 0.C 300.000 2327.000 101.96128 1 + 1.18336660E+01 3.77088780E-03-1.78631910E-07-5.60088070E-10 1.40768250E-13 2 +-2.05711310E+05-6.35998350E+01-4.91383090E+00 7.93984430E-02-1.32379180E-04 3 + 1.04467500E-07-3.15663300E-11-2.02626220E+05 1.54780730E+01-2.01540284E+05 4 +AL2O3(L) J12/79AL 2.O 3. 0. 0.C 2327.000 6000.000 101.96128 1 + 2.31482410E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-2.11405200E+05-1.38602050E+02 2.31482410E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-2.11405200E+05-1.38602050E+02 0.00000000E+00 4 +AL2SiO5(an) J 9/67AL 2.SI 1.O 5. 0.C 300.000 3000.000 162.04558 1 + 1.73517420E+01 8.74381350E-03-3.70847180E-06 1.06882830E-09-1.17639500E-13 2 +-3.17941510E+05-9.17387440E+01-9.28663420E+00 1.34767200E-01-2.32370000E-04 3 + 1.87609190E-07-5.73814830E-11-3.13276640E+05 3.27158590E+01-3.11764784E+05 4 +AL6Si2O13(s) J 9/67AL 6.SI 2.O 13. 0.C 300.000 3000.000 426.05243 1 + 4.52383640E+01 2.76614240E-02-1.46755120E-05 3.88858480E-09-3.66604820E-13 2 +-8.36864170E+05-2.37395650E+02-1.10346710E+01 2.66756430E-01-4.15247630E-04 3 + 3.13769720E-07-9.24975970E-11-8.25658700E+05 3.22547910E+01-8.20184486E+05 4 +B(b) J 6/83B 1. 0. 0. 0.C 200.000 2350.000 10.81100 1 + 1.83494094E+00 1.79198702E-03-7.97879498E-07 2.02764512E-10-1.92028345E-14 2 +-7.83202899E+02-1.06433298E+01-1.15931693E+00 1.13777145E-02-1.06985988E-05 3 + 2.76106443E-09 7.31746996E-13-7.13339210E+01 4.36439895E+00 0.00000000E+00 4 +B(L) J 6/83B 1. 0. 0. 0.C 2350.000 6000.000 10.81100 1 + 3.81862551E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 3.36099275E+03-2.07326473E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4 +BN(s) J 6/66B 1.N 1. 0. 0.C 200.000 6000.000 24.81774 1 + 2.68739930E+00 4.24674311E-03-1.92817705E-06 3.60170748E-10-2.36706055E-14 2 +-3.14630126E+04-1.54187735E+01-6.92827700E-01 1.17984401E-02-3.39339835E-06 3 +-7.14136993E-09 4.77162137E-12-3.04539002E+04 2.41361166E+00-3.01779034E+04 4 +B2O3(L) J 6/71B 2.O 3. 0. 0.C 300.000 5000.000 69.62020 1 + 1.56001140E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.56844550E+05-8.31264440E+01 3.14332740E+01-2.15780390E-01 6.40579860E-04 3 +-7.05724200E-07 2.65091500E-10-1.54901390E+05-1.28038800E+02-1.50730324E+05 4 +B3O3H3(cr) J 3/65B 3.H 3.O 3. 0.C 298.150 2000.000 83.45502 1 +-1.28470517E+01 9.19581322E-02-8.10609436E-05 3.27322840E-08-5.01611948E-12 2 +-1.51109722E+05 7.01536150E+01 8.15951373E+00-7.06683350E-03 9.24924694E-05 3 +-1.02833905E-07 3.50150571E-11-1.54569630E+05-2.75254035E+01-1.51820492E+05 4 +Ba(cr) SRD 93BA 1. 0. 0. 0.C 298.150 1000.000 137.32700 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 2.77334443E+00 2.03752236E-03 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-9.17433810E+02-8.90970626E+00 0.00000000E+00 4 +Ba(L) SRD 93BA 1. 0. 0. 0.C 1000.000 6000.000 137.32700 1 + 4.81086679E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-9.92062381E+02-2.00027571E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4 +BaBr2(s) J12/74BA 1.BR 2. 0. 0.C 300.000 1130.000 297.13500 1 + 8.21359240E+00 3.11437150E-03-2.40116290E-07 0.00000000E+00 0.00000000E+00 2 +-9.36849820E+04-2.97718080E+01 8.49822320E+00 2.51392240E-03 2.43906580E-07 3 +-2.96954400E-10 1.28749890E-13-9.37822410E+04-3.13127320E+01-9.11351313E+04 4 +BaBr2(L) J12/74BA 1.BR 2. 0. 0.C 1130.000 5000.000 297.13500 1 + 1.26109310E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-9.29364180E+04-5.39166730E+01 1.26109310E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-9.29364180E+04-5.39166730E+01 0.00000000E+00 4 +BaCL2(a) J12/72BA 1.CL 2. 0. 0.C 300.000 1198.000 208.23240 1 + 1.10964040E+01-1.11350020E-03-8.18019370E-07-2.36513760E-10 1.83268400E-12 2 +-1.06937770E+05-4.89267460E+01 7.72024720E+00 6.92241780E-03-1.09609270E-05 3 + 9.69916210E-09-2.61984430E-12-1.05792020E+05-3.07683050E+01-1.03261458E+05 4 +BaCL2(b) J12/72BA 1.CL 2. 0. 0.C 1198.000 1235.000 208.23240 1 + 1.48955920E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.09941350E+05-7.52727020E+01 1.48955920E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.09941350E+05-7.52727020E+01 0.00000000E+00 4 +BaCL2(L) J12/72BA 1.CL 2. 0. 0.C 1235.000 5000.000 208.23240 1 + 1.30839670E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.05780590E+05-6.08186470E+01 1.30839670E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.05780590E+05-6.08186470E+01 0.00000000E+00 4 +BaF2(a) J12/72BA 1.F 2. 0. 0.C 300.000 1480.000 175.32381 1 +-2.84392880E+00-2.19972130E-02 4.42010610E-05 5.58246900E-09-1.39069120E-11 2 +-1.37899190E+05 4.44729320E+01 4.32032900E+00 2.76261470E-02-5.94303480E-05 3 + 6.06301470E-08-2.21107930E-11-1.47452460E+05-1.91219160E+01-1.45352145E+05 4 +BaF2(b,c) J12/72BA 1.F 2. 0. 0.C 1480.000 1641.000 175.32381 1 + 1.29480940E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.50331750E+05-6.53836630E+01 1.29480940E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.50331750E+05-6.53836630E+01 0.00000000E+00 4 +BaF2(L) J12/72BA 1.F 2. 0. 0.C 1641.000 5000.000 175.32381 1 + 1.20065520E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.45977150E+05-5.67012820E+01 1.20065520E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.45977150E+05-5.67012820E+01 0.00000000E+00 4 +BaO(s) J 6/74BA 1.O 1. 0. 0.C 300.000 2286.000 153.32640 1 + 5.59705660E+00 1.72428640E-03-6.02495130E-07 1.74000170E-10-1.85947910E-14 2 +-6.77196870E+04-2.38485210E+01 3.92000670E+00 8.91156480E-03-1.25312820E-05 3 + 9.18687030E-09-2.61290690E-12-6.73943690E+04-1.58424680E+01-6.59233196E+04 4 +BaO(L) J 6/74BA 1.O 1. 0. 0.C 2286.000 5000.000 153.32640 1 + 8.05167150E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-6.32237370E+04-3.68186010E+01 8.05167150E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-6.32237370E+04-3.68186010E+01 0.00000000E+00 4 +BaO2H2(s) J12/75BA 1.O 2.H 2. 0.C 300.000 681.150 171.34168 1 +-1.54291680E-01 7.51087380E-02-1.49150720E-04 1.34625140E-07-4.27154090E-11 2 +-1.16035520E+05-3.10750780E+00-1.54291680E-01 7.51087380E-02-1.49150720E-04 3 + 1.34625140E-07-4.27154090E-11-1.16035520E+05-3.10750780E+00-1.13815035E+05 4 +BaO2H2(L) J12/75BA 1.O 2.H 2. 0.C 681.150 5000.000 171.34168 1 + 1.69588330E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.17974980E+05-8.33516110E+01 1.69588330E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.17974980E+05-8.33516110E+01 0.00000000E+00 4 +BaS(s) J 9/77BA 1.S 1. 0. 0.C 300.000 3000.000 169.39300 1 + 5.90966310E+00 1.15935610E-03-1.92798100E-07 6.66090070E-11-8.32804110E-15 2 +-5.76245380E+04-2.47107370E+01 5.36586760E+00 1.24182840E-03 3.98045900E-06 3 +-6.62154280E-09 2.96788980E-12-5.74362700E+04-2.16381020E+01-5.57577584E+04 4 +Be(a) SRD 93BE 1. 0. 0. 0.C 298.150 1543.000 9.01218 1 + 8.06036468E-01 5.37325946E-03-4.86241757E-06 2.39834017E-09-4.37186552E-13 2 +-4.10525129E+02-4.79961716E+00-1.34774902E+00 1.92340834E-02-3.54163423E-05 3 + 3.08895143E-08-1.00814744E-11-1.96446005E+02 4.40835822E+00 0.00000000E+00 4 +Be(b) SRD 93BE 1. 0. 0. 0.C 1543.000 1563.000 9.01218 1 + 3.60815009E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-8.52229192E+02-2.00291024E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4 +Be(L) SRD 93BE 1. 0. 0. 0.C 1563.000 6000.000 9.01218 1 + 3.54560882E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 2.07475580E+02-1.89534126E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4 +BeAL2O4(s) J12/79BE 1.AL 2.O 4. 0.C 300.000 2146.000 126.97286 1 + 2.02655590E+01-1.04666490E-02 2.30439540E-05-1.54936830E-08 3.60249400E-12 2 +-2.83363010E+05-1.07472220E+02-8.05473800E+00 1.13572400E-01-1.87827280E-04 3 + 1.48068570E-07-4.48072780E-11-2.77980440E+05 2.71357190E+01-2.76722007E+05 4 +BeAL2O4(L) J12/79BE 1.AL 2.O 4. 0.C 2146.000 5000.000 126.97286 1 + 2.96362910E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-2.80569820E+05-1.71169540E+02 2.96362910E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-2.80569820E+05-1.71169540E+02 0.00000000E+00 4 +BeBr2(s) J 6/75BE 1.BR 2. 0. 0.C 300.000 1500.000 168.82018 1 +-2.27183290E+00 3.71850840E-02-4.33216390E-05 2.30580060E-08-4.57496410E-12 2 +-4.29712510E+04 1.67088690E+01 5.85510580E+00 7.29917640E-03 1.26780450E-06 3 +-9.17810970E-09 4.83067700E-12-4.48404830E+04-2.34448860E+01-4.27750136E+04 4 +BeCL2(s) J 6/65BE 1.CL 2. 0. 0.C 300.000 688.000 79.91758 1 + 3.00657450E+00 1.95395590E-02-4.89136050E-06-2.96041580E-08 2.35348610E-11 2 +-6.07221000E+04-1.25797720E+01 3.00657450E+00 1.95395590E-02-4.89136050E-06 3 +-2.96041580E-08 2.35348610E-11-6.07221000E+04-1.25797720E+01-5.90478272E+04 4 +BeCL2(L) J 6/65BE 1.CL 2. 0. 0.C 688.000 5000.000 79.91758 1 + 1.46037190E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-6.44984170E+04-7.64487840E+01 1.46037190E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-6.44984170E+04-7.64487840E+01 0.00000000E+00 4 +BeF2(Lqz) J 6/70BE 1.F 2. 0. 0.C 300.000 500.000 47.00899 1 + 2.05937700E+01-6.63969300E-02-1.20323980E-04 8.98005550E-07-9.66692640E-10 2 +-1.26937080E+05-9.17851130E+01 2.05937700E+01-6.63969300E-02-1.20323980E-04 3 + 8.98005550E-07-9.66692640E-10-1.26937080E+05-9.17851130E+01-1.23492663E+05 4 +BeF2(hqz) J 6/70BE 1.F 2. 0. 0.C 500.000 825.000 47.00899 1 + 5.69655760E+00 4.02583580E-03 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.25288840E+05-2.70913890E+01 5.69655760E+00 4.02583580E-03 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.25288840E+05-2.70913890E+01 0.00000000E+00 4 +BeF2(L) J 6/70BE 1.F 2. 0. 0.C 825.000 2000.000 47.00899 1 + 6.04896390E+00 4.33284980E-03 1.87544030E-07-3.60194820E-10 9.13388220E-14 2 +-1.25113610E+05-2.90262480E+01 7.74233610E+00-6.96800650E-04 2.67434060E-06 3 + 3.12625420E-09-2.54562790E-12-1.25465300E+05-3.74403040E+01 0.00000000E+00 4 +BeI2(s) J12/75BE 1.I 2. 0. 0.C 300.000 753.000 262.82112 1 + 2.67722950E+00 2.69230920E-02-2.88952040E-05 4.00766040E-09 6.40517020E-12 2 +-2.44469680E+04-7.55309190E+00 2.67722950E+00 2.69230920E-02-2.88952040E-05 3 + 4.00766040E-09 6.40517020E-12-2.44469680E+04-7.55309190E+00-2.26964492E+04 4 +BeI2(L) J12/75BE 1.I 2. 0. 0.C 753.000 5000.000 262.82112 1 + 1.35871960E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-2.59933120E+04-6.33135730E+01 1.35871960E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-2.59933120E+04-6.33135730E+01 0.00000000E+00 4 +BeO(a) J12/74BE 1.O 1. 0. 0.C 200.000 2373.001 25.01158 1 + 3.22375488E+00 4.89276244E-03-3.05832591E-06 9.91401433E-10-1.23442571E-13 2 +-7.45140761E+04-1.85239582E+01-3.06995225E+00 3.22099414E-02-4.85141436E-05 3 + 3.51263133E-08-9.82600858E-12-7.33202340E+04 1.14094979E+01-7.31677513E+04 4 +BeO(b) J12/74BE 1.O 1. 0. 0.C 2373.001 2821.220 25.01158 1 + 1.23933471E+01-1.03223075E-02 6.52733591E-06-1.73093889E-09 1.70986494E-13 2 +-7.81759610E+04-7.05417631E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00-7.31677513E+04 4 +BeO(L) J12/74BE 1.O 1. 0. 0.C 2821.220 6000.000 25.01158 1 + 9.56123164E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-7.42016413E+04-5.80635442E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00-7.31677513E+04 4 +BeO2H2(b) J12/75BE 1.O 2.H 2. 0.C 300.000 1000.000 43.02686 1 +-7.01683250E+00 8.30056540E-02-1.41520290E-04 1.14216650E-07-3.51055350E-11 2 +-1.09507110E+05 2.66160610E+01-7.01683250E+00 8.30056540E-02-1.41520290E-04 3 + 1.14216650E-07-3.51055350E-11-1.09507110E+05 2.66160610E+01-1.08951020E+05 4 +BeS(s) J 9/77BE 1.S 1. 0. 0.C 300.000 3000.000 41.07818 1 + 3.47870360E+00 6.51062330E-03-4.13140450E-06 1.24499300E-09-1.38219470E-13 2 +-2.95665300E+04-1.73913260E+01-2.87300050E+00 3.80787040E-02-6.25067050E-05 3 + 4.89042780E-08-1.46385810E-11-2.85551820E+04 1.18429220E+01-2.81817977E+04 4 +Be2C(s) BAR 73BE 2.C 1. 0. 0.C 300.000 2400.000 30.03536 1 + 4.43741700E+00 2.56945380E-03 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.55073240E+04-2.40861210E+01 4.43741700E+00 2.56945380E-03 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.55073240E+04-2.40861210E+01-1.40701050E+04 4 +Be2C(L) BAR 73BE 2.C 1. 0. 0.C 2400.000 5000.000 30.03536 1 + 1.10708970E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.49696410E+04-6.57751160E+01 1.10708970E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.49696410E+04-6.57751160E+01-1.40701050E+04 4 +Br2(cr) L 1/93BR 2. 0. 0. 0.C 200.000 265.900 159.80800 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 9.12545994E+00-8.26160881E-02 6.99861517E-04 3 +-2.40843064E-06 3.21106016E-09-3.30408820E+03-3.01727996E+01 0.00000000E+00 4 +Br2(L) L 1/93BR 2. 0. 0. 0.C 265.900 332.503 159.80800 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 1.04252937E+01 1.11181227E-01-1.06856988E-03 3 + 3.25976572E-06-3.27490398E-09-3.50620403E+03-4.90757083E+01 0.00000000E+00 4 +Br2(L) L 1/93BR 2. 0. 0. 0.C 332.503 6000.000 159.80800 1 + 9.05669727E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-2.69988017E+03-3.32936281E+01 9.05669727E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-2.69988017E+03-3.32936281E+01 0.00000000E+00 4 +C(gr) X 4/83C 1. 0. 0. 0.C 200.000 5000.000 12.01100 1 + 1.45571829E+00 1.71702216E-03-6.97562786E-07 1.35277032E-10-9.67590652E-15 2 +-6.95138814E+02-8.52583033E+00-3.10872072E-01 4.40353686E-03 1.90394118E-06 3 +-6.38546966E-09 2.98964248E-12-1.08650794E+02 1.11382953E+00 0.00000000E+00 4 +C6H6(L) X10/86C 6.H 6. 0. 0.C 278.680 500.000 78.11364 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 6.36690229E+01-6.00534398E-01 2.66792810E-03 3 +-5.06308828E-06 3.63955562E-09-1.67085472E+03-2.43891797E+02 5.90293355E+03 4 +C7H8(L) X10/86C 7.H 8. 0. 0.C 178.150 500.000 92.14052 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 2.93676022E+01-1.94722686E-01 9.74773096E-04 3 +-1.91472689E-06 1.48097019E-09-4.16318442E+03-1.12019966E+02 1.46490894E+03 4 +C8H18(L),n-octa X10/76C 8.H 18. 0. 0.C 220.000 300.000 114.23092 1 + 7.14133930E+01-5.02079500E-01 1.83419900E-03-2.04501650E-06 0.00000000E+00 2 +-4.12437250E+04-2.77222400E+02 7.14133930E+01-5.02079500E-01 1.83419900E-03 3 +-2.04501650E-06 0.00000000E+00-4.12437250E+04-2.77222400E+02-3.01032790E+04 4 +Jet-A(L) L 6/88C 12.H 23. 0. 0.C 220.000 550.000 167.31462 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 1.90496130E+01-1.69185320E-02 6.30220350E-04 3 +-1.33365770E-06 9.43356380E-10-4.48039640E+04-6.76902000E+01-3.64987440E+04 4 +Ca(a) SRD 93CA 1. 0. 0. 0.C 298.150 716.000 40.07800 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 3.03325649E+00-1.41800064E-03 7.24487574E-06 3 +-6.68790594E-09 2.49903889E-12-8.93310508E+02-1.20114288E+01 0.00000000E+00 4 +Ca(b) SRD 93CA 1. 0. 0. 0.C 716.000 1115.000 40.07800 1 + 5.70111768E+00-5.81056490E-03 4.02212518E-06 0.00000000E+00 0.00000000E+00 2 +-1.51676361E+03-2.60758134E+01 5.70111768E+00-5.81056490E-03 4.02212518E-06 3 + 0.00000000E+00 0.00000000E+00-1.51676361E+03-2.60758134E+01 0.00000000E+00 4 +Ca(L) SRD 93CA 1. 0. 0. 0.C 1115.000 6000.000 40.07800 1 + 4.57032345E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-9.82243308E+02-2.11988643E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4 +CaBr2(s) J 6/74CA 1.BR 2. 0. 0.C 300.000 1015.000 199.88600 1 + 6.62997070E+00 4.02839100E-03 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-8.39396740E+04-2.25238430E+01 5.26933940E+00 2.36978050E-02-4.97999090E-05 3 + 4.67072240E-08-1.52160970E-11-8.44473670E+04-1.96594450E+01-8.21778817E+04 4 +CaBr2(L) J 6/74CA 1.BR 2. 0. 0.C 1015.000 5000.000 199.88600 1 + 1.35871960E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-8.54287380E+04-6.31516590E+01 1.35871960E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-8.54287380E+04-6.31516590E+01 0.00000000E+00 4 +CaCO3(caL) BAR 89CA 1.C 1.O 3. 0.C 298.150 1200.000 100.08720 1 + 1.44388162E+01-1.39777807E-03 2.04333103E-06 0.00000000E+00 0.00000000E+00 2 +-1.50400710E+05-7.28445489E+01-1.76968953E+00 6.18884685E-02-8.82380139E-05 3 + 4.61909015E-08-2.98729740E-12-1.46691812E+05 6.32412532E+00-1.45158404E+05 4 +CaCL2(s) J 6/70CA 1.CL 2. 0. 0.C 300.000 1045.000 110.98340 1 + 8.73324080E+00 2.39551410E-04 9.44673770E-07 4.58518630E-10-5.97495290E-14 2 +-9.83080800E+04-3.72366670E+01 6.35546750E+00 1.37843100E-02-2.44214030E-05 3 + 1.95512800E-08-4.95341690E-12-9.80417830E+04-2.68141460E+01-9.57136949E+04 4 +CaCL2(L) J 6/70CA 1.CL 2. 0. 0.C 1045.000 5000.000 110.98340 1 + 1.23321410E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-9.80239520E+04-5.80474680E+01 1.23321410E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-9.80239520E+04-5.80474680E+01 0.00000000E+00 4 +CaF2(a) J12/68CA 1.F 2. 0. 0.C 200.000 1424.000 78.07481 1 + 1.03439908E+00 2.18402489E-02-2.04796113E-05 1.03381996E-08-1.91843768E-12 2 +-1.48010445E+05-2.08048925E+00-3.91537176E-01 5.74664742E-02-1.30834259E-04 3 + 1.32738284E-07-4.81641634E-11-1.48963614E+05-1.91796873E+00-1.47442483E+05 4 +CaF2(b) J12/68CA 1.F 2. 0. 0.C 1424.000 1691.000 78.07481 1 + 1.42866105E+01-1.10249437E-03 1.41775401E-06-2.81232082E-10 0.00000000E+00 2 +-1.55453320E+05-7.91866360E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00-1.47442483E+05 4 +CaF2(L) J12/68CA 1.F 2. 0. 0.C 1691.000 6000.000 78.07481 1 + 1.20168140E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.47908292E+05-6.04927984E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00-1.47442483E+05 4 +CaO(s) J 6/73CA 1.O 1. 0. 0.C 300.000 3200.000 56.07740 1 + 5.65575170E+00 1.01654390E-03-2.55768990E-07 5.45143950E-11-4.25799500E-15 2 +-7.82383810E+04-2.82233720E+01 1.69376880E+00 1.81496630E-02-2.83726090E-05 3 + 2.05135390E-08-5.51757680E-12-7.74827690E+04-9.37100810E+00-7.63838127E+04 4 +CaO(L) J 6/73CA 1.O 1. 0. 0.C 3200.000 5000.000 56.07740 1 + 7.54844210E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-7.11792920E+04-3.80839480E+01 7.54844210E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-7.11792920E+04-3.80839480E+01 0.00000000E+00 4 +CaO2H2(s) J12/75CA 1.O 2.H 2. 0.C 300.000 1000.000 74.09268 1 +-7.40227670E-01 6.75664680E-02-1.31912810E-04 1.19890680E-07-4.06130450E-11 2 +-1.20435430E+05-1.00970750E+00-7.40227670E-01 6.75664680E-02-1.31912810E-04 3 + 1.19890680E-07-4.06130450E-11-1.20435430E+05-1.00970750E+00-1.18600700E+05 4 +CaS(s) J 9/77CA 1.S 1. 0. 0.C 300.000 3000.000 72.14400 1 + 5.65305190E+00 1.36258740E-03-7.27811760E-07 2.49897630E-10-3.09681260E-14 2 +-5.87103410E+04-2.59063950E+01 4.64755580E+00 4.93155160E-03-5.53089030E-06 3 + 3.06639590E-09-6.07856100E-13-5.84770470E+04-2.09227100E+01-5.69152785E+04 4 +CaSO4(s) BAR 73CA 1.S 1.O 4. 0.C 300.000 5000.000 136.14160 1 + 8.44419050E+00 1.18762150E-02 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.75532420E+05-3.88201340E+01 8.44419050E+00 1.18762150E-02 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.75532420E+05-3.88201340E+01-1.72486926E+05 4 +Cr(cr) J 6/73CR 1. 0. 0. 0.C 200.000 311.500 51.99610 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 7.84826024E+00-1.16276020E-01 8.12369251E-04 3 +-2.30807086E-06 2.35328142E-09-8.98013946E+02-2.75733139E+01 0.00000000E+00 4 +Cr(cr) J 6/73CR 1. 0. 0. 0.C 311.500 2130.000 51.99610 1 + 4.59782637E+00-4.81791132E-03 5.84129754E-06-2.07036847E-09 2.82102268E-13 2 +-1.31489668E+03-2.24454748E+01 1.82863471E+00 4.19562267E-03-2.82735082E-06 3 +-9.15990578E-10 1.55203040E-12-7.05502663E+02-8.69806103E+00 0.00000000E+00 4 +Cr(L) J 6/73CR 1. 0. 0. 0.C 2130.000 6000.000 51.99610 1 + 4.73028477E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 5.75359221E+02-2.45318309E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4 +CrN(s) J12/73CR 1.N 1. 0. 0.C 300.000 2500.000 66.00284 1 + 5.69445390E+00 5.30116900E-04 2.27058290E-07-8.14832540E-11 1.08037960E-14 2 +-1.58360020E+04-2.81317040E+01 9.71529040E+00-2.37753720E-02 5.25610150E-05 3 +-4.83907470E-08 1.62707570E-11-1.63234220E+04-4.57300500E+01-1.41071233E+04 4 +Cr2N(s) J12/73CR 2.N 1. 0. 0.C 300.000 2500.000 117.99894 1 + 8.09841850E+00 1.85336110E-03 1.42273060E-06-5.58963900E-10 6.93071100E-14 2 +-1.76848010E+04-3.91474720E+01 2.03033880E+00 3.40064410E-02-6.15249460E-05 3 + 5.31425480E-08-1.67695210E-11-1.67683130E+04-1.16006980E+01-1.50979548E+04 4 +Cr2O3(s) J12/73CR 2.O 3. 0. 0.C 300.000 2603.000 151.99040 1 + 1.40122350E+01 1.38239780E-03-2.37792260E-07 1.69950850E-10-3.77058570E-14 2 +-1.40982170E+05-7.11015690E+01 2.93327730E+01-1.02073850E-01 2.36011030E-04 3 +-2.25780190E-07 7.77992890E-11-1.42404060E+05-1.35742810E+02-1.36519668E+05 4 +Cr2O3(L) J12/73CR 2.O 3. 0. 0.C 2603.000 5000.000 151.99040 1 + 1.88711050E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.33694980E+05-9.99614700E+01 1.88711050E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.33694980E+05-9.99614700E+01 0.00000000E+00 4 +Cs(cr) CODA89CS 1. 0. 0. 0.C 100.000 301.590 132.90543 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 3.31157194E+00-9.67974793E-03 1.19926576E-04 3 +-5.20608084E-07 8.33415927E-10-9.80844435E+02-8.10866871E+00 0.00000000E+00 4 +Cs(L) CODA89CS 1. 0. 0. 0.C 301.590 2000.000 132.90543 1 + 5.11512955E+00-3.83970291E-03 2.01555257E-06 3.64202599E-10-5.43974501E-14 2 +-1.13841767E+03-1.70567624E+01 3.20358130E+00 6.53560206E-03-1.88609302E-05 3 + 1.88262490E-08-6.10371782E-12-8.61341855E+02-8.43100388E+00 0.00000000E+00 4 +CsCL(a) J 6/68CS 1.CL 1. 0. 0.C 300.000 743.000 168.35813 1 + 5.54534000E+00 2.38058340E-03 8.35703300E-07-9.95716400E-10 3.80548030E-13 2 +-5.50265350E+04-2.01642600E+01 5.54534000E+00 2.38058340E-03 8.35703300E-07 3 +-9.95716400E-10 3.80548030E-13-5.50265350E+04-2.01642600E+01-5.32617875E+04 4 +CsCL(b) J 6/68CS 1.CL 1. 0. 0.C 743.000 918.000 168.35813 1 + 8.16107370E+00-1.76235680E-03-2.25085160E-07 3.93073170E-09-2.34523410E-12 2 +-5.54804310E+04-3.39413960E+01 8.16107370E+00-1.76235680E-03-2.25085160E-07 3 + 3.93073170E-09-2.34523410E-12-5.54804310E+04-3.39413960E+01 0.00000000E+00 4 +CsCL(L) J 6/68CS 1.CL 1. 0. 0.C 918.000 5000.000 168.35813 1 + 9.30974520E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-5.50311610E+04-4.08101330E+01 9.30974520E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-5.50311610E+04-4.08101330E+01 0.00000000E+00 4 +CsF(s) J 6/68CS 1.F 1. 0. 0.C 300.000 976.000 151.90383 1 + 5.64899930E+00 1.87113980E-03 6.62423820E-07-6.30848710E-10 1.86923390E-13 2 +-6.84851020E+04-2.21499590E+01 5.64899930E+00 1.87113980E-03 6.62423820E-07 3 +-6.30848710E-10 1.86923390E-13-6.84851020E+04-2.21499590E+01-6.67129928E+04 4 +CsF(L) J 6/68CS 1.F 1. 0. 0.C 976.000 5000.000 151.90383 1 + 8.90716170E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-6.80668170E+04-3.99127740E+01 8.90716170E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-6.80668170E+04-3.99127740E+01 0.00000000E+00 4 +CsOH(a) J 6/71CS 1.O 1.H 1. 0.C 298.150 410.000 149.91277 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 5.88946051E+00 6.13189982E-03 8.60763952E-06 3 +-1.20614689E-08 0.00000000E+00-5.22010341E+04-2.37840127E+01-5.01203318E+04 4 +CsOH(b) J 6/71CS 1.O 1.H 1. 0.C 410.000 493.000 149.91277 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 4.92104624E+00 1.00655116E-02 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-5.18660681E+04-1.87438113E+01-5.01203318E+04 4 +CsOH(c) J 6/71CS 1.O 1.H 1. 0.C 493.000 588.000 149.91277 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 1.00644544E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-5.24488650E+04-4.41931478E+01-5.01203318E+04 4 +CsOH(L) J 6/71CS 1.O 1.H 1. 0.C 588.000 6000.000 149.91277 1 + 9.81284300E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-5.17524722E+04-4.16559605E+01 9.81284300E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-5.17524722E+04-4.16559605E+01-5.01203318E+04 4 +Cs2SO4(II) J 6/79CS 2.S 1.O 4. 0.C 300.000 940.000 361.87446 1 +-2.97893070E+00 1.26508840E-01-2.95532060E-04 3.32073080E-07-1.31049910E-10 2 +-1.76233520E+05 1.51857470E+01-2.97893070E+00 1.26508840E-01-2.95532060E-04 3 + 3.32073080E-07-1.31049910E-10-1.76233520E+05 1.51857470E+01-1.73515408E+05 4 +Cs2SO4(I) J 6/79CS 2.S 1.O 4. 0.C 940.000 1278.000 361.87446 1 +-2.72327220E-02 3.13540360E-02-1.13005310E-05 3.32831080E-09 0.00000000E+00 2 +-1.70211630E+05 2.48399880E+01 4.73498360E+00 1.86196000E-02 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.71541390E+05 1.37370460E-01 0.00000000E+00 4 +Cs2SO4(L) J 6/79CS 2.S 1.O 4. 0.C 1278.000 5000.000 361.87446 1 + 2.48591980E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.77761980E+05-1.16657440E+02 2.48591980E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.77761980E+05-1.16657440E+02 0.00000000E+00 4 +Cu(cr) CODA89CU 1. 0. 0. 0.C 200.000 1358.000 63.54600 1 + 3.42008910E+00-1.61201394E-03 3.05145917E-06-2.11162788E-09 6.99858397E-13 2 +-9.90295636E+02-1.51932294E+01 1.76672074E+00 7.34699432E-03-1.54712960E-05 3 + 1.50539591E-08-5.24861335E-12-7.43882087E+02-7.70454044E+00 0.00000000E+00 4 +Cu(L) CODA89CU 1. 0. 0. 0.C 1358.000 6000.000 63.54600 1 + 3.94491076E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-2.10634669E+02-1.83585676E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4 +CuF(s) J12/77CU 1.F 1. 0. 0.C 300.000 2000.000 82.54440 1 + 5.32155060E+00 4.85498320E-03-3.54400480E-06 1.11090230E-09-1.24537160E-13 2 +-3.55217150E+04-2.39026430E+01 4.44212880E+00 7.96690760E-03-7.28073110E-06 3 + 2.76377730E-09-2.73188420E-13-3.53361680E+04-1.95851700E+01-3.37166351E+04 4 +CuF2(s) J12/77CU 1.F 2. 0. 0.C 300.000 1109.000 101.54281 1 + 2.35576760E+00 1.49135080E-02-6.39951930E-06 0.00000000E+00 0.00000000E+00 2 +-6.56106220E+04-7.16267570E+00 4.38736760E+00 1.43971090E-02-8.62134970E-06 3 +-1.98304460E-09 2.68967400E-12-6.66855850E+04-1.95805610E+01-6.48164029E+04 4 +CuF2(L) J12/77CU 1.F 2. 0. 0.C 1109.000 5000.000 101.54281 1 + 1.20775070E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-6.34879980E+04-5.67303700E+01 1.20775070E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-6.34879980E+04-5.67303700E+01 0.00000000E+00 4 +CuO(s) J12/77CU 1.O 1. 0. 0.C 300.000 2000.000 79.54540 1 + 5.02581240E+00 2.54240770E-03-1.37682940E-06 5.34928310E-10-7.96642810E-14 2 +-2.04332810E+04-2.43766950E+01 8.84038660E-01 2.41588520E-02-4.38941420E-05 3 + 3.75861810E-08-1.20882750E-11-1.97883820E+04-5.47238800E+00-1.87702523E+04 4 +CuO2H2(s) J 6/66CU 1.O 2.H 2. 0.C 300.000 1500.000 97.56068 1 + 8.67307870E+00 1.03857620E-02-4.69948410E-06-5.02925130E-10 5.35931600E-13 2 +-5.72303820E+04-3.93661610E+01 1.04511850E+01 1.34582050E-03 8.66023390E-06 3 +-6.80923490E-09 7.44358590E-13-5.74068650E+04-4.72388030E+01-5.41676188E+04 4 +CuSO4(s) J 6/66CU 1.S 1.O 4. 0.C 300.000 2000.000 159.60960 1 + 1.13145360E+01 1.40503520E-02-1.00635680E-05 3.72042210E-09-5.28059140E-13 2 +-9.69982080E+04-5.62546900E+01 3.30191660E+00 3.70123210E-02-2.89908040E-05 3 + 4.53140450E-09 2.63884450E-12-9.49936210E+04-1.54658780E+01-9.26100033E+04 4 +Cu2O(s) J12/77CU 2.O 1. 0. 0.C 300.000 1516.720 143.09140 1 + 1.47556410E+01-1.58766570E-02 1.49711930E-05-4.48402640E-09 4.05560050E-13 2 +-2.50650680E+04-7.05418770E+01 3.38324660E+00 2.29541760E-02-3.95423040E-05 3 + 3.40204010E-08-1.10438090E-11-2.22731570E+04-1.35307130E+01-2.05315380E+04 4 +Cu2O(L) J12/77CU 2.O 1. 0. 0.C 1516.720 5000.000 143.09140 1 + 1.20171200E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.92523870E+04-5.68868660E+01 1.20171200E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.92523870E+04-5.68868660E+01 0.00000000E+00 4 +Cu2O5S(s) J 6/66CU 2.O 5.S 1. 0.C 300.000 1500.000 239.15500 1 + 1.60116340E+01 1.94246680E-02-1.84482510E-05 1.11872040E-08-2.61119830E-12 2 +-1.17616200E+05-7.87274890E+01 2.52571780E+00 7.22059580E-02-9.78556650E-05 3 + 6.54324990E-08-1.67444530E-11-1.14786460E+05-1.31961120E+01-1.11567236E+05 4 +Fe(a) J 3/78FE 1. 0. 0. 0.C 200.000 1042.000 55.84700 1 + 4.69080173E+03-9.90659991E+00 2.69427446E-03 5.54445321E-06-3.01659823E-09 2 +-1.41547586E+06-2.49294387E+04 2.41337476E+00-1.57780744E-03 2.14701339E-05 3 +-3.80171438E-08 2.20426984E-11-7.74380998E+02-1.06560296E+01 0.00000000E+00 4 +Fe(a) J 3/78FE 1. 0. 0. 0.C 1042.000 1184.000 55.84700 1 + 6.59678809E+02-1.14058217E+00 4.96306997E-04 0.00000000E+00 0.00000000E+00 2 +-2.52106802E+05-3.65665236E+03 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4 +Fe(c) J 3/78FE 1. 0. 0. 0.C 1184.000 1665.000 55.84700 1 + 6.10109990E+01-1.60945061E-01 1.68369493E-04-7.74563702E-08 1.33091290E-11 2 +-1.65335454E+04-3.13710668E+02 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4 +Fe(d) J 3/78FE 1. 0. 0. 0.C 1665.000 1809.000 55.84700 1 +-4.35904698E+02 7.68489448E-01-4.46898892E-04 8.67070913E-08 0.00000000E+00 2 + 1.87925534E+05 2.45057619E+03 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4 +Fe(L) J 3/78FE 1. 0. 0. 0.C 1809.000 6000.000 55.84700 1 + 5.53538332E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.27428941E+03-2.94772271E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4 +FeC5O5(L) J 3/78FE 1.C 5.O 5. 0.C 300.000 5000.000 195.89900 1 + 2.81184500E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.00524830E+05-1.19665410E+02 2.81184500E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.00524830E+05-1.19665410E+02-9.21413141E+04 4 +FeCL2(s) J12/70FE 1.CL 2. 0. 0.C 300.000 950.000 126.75240 1 + 7.11222710E+00 1.10869530E-02-1.70727420E-05 1.35158170E-08-4.13650360E-12 2 +-4.36009850E+04-2.89940550E+01 7.11222710E+00 1.10869530E-02-1.70727420E-05 3 + 1.35158170E-08-4.13650360E-12-4.36009850E+04-2.89940550E+01-4.11137739E+04 4 +FeCL2(L) J12/70FE 1.CL 2. 0. 0.C 950.000 5000.000 126.75240 1 + 1.22888630E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-4.11098210E+04-5.31930570E+01 1.22888630E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-4.11098210E+04-5.31930570E+01 0.00000000E+00 4 +FeCL3(s) J 6/65FE 1.CL 3. 0. 0.C 200.000 577.000 162.20510 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00-7.39556855E+00 2.02608434E-01-8.44505923E-04 3 + 1.59286602E-06-1.07989321E-09-5.00144664E+04 2.44450935E+01-4.80371062E+04 4 +FeCL3(L) J 6/65FE 1.CL 3. 0. 0.C 577.000 6000.000 162.20510 1 + 1.61031270E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-4.84135278E+04-6.75758990E+01 1.61031270E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-4.84135278E+04-6.75758990E+01-4.80371062E+04 4 +FeO(s) J 6/65FE 1.O 1. 0. 0.C 300.000 1650.000 71.84640 1 + 5.83164890E+00 1.42751560E-03-9.32081430E-08-6.59977630E-12-2.25121430E-14 2 +-3.45669020E+04-2.64469900E+01 5.31954750E+00 2.20965910E-03 1.07217750E-06 3 +-2.79297290E-09 1.33207330E-12-3.44071650E+04-2.36860340E+01-3.27183475E+04 4 +FeO(L) J 6/65FE 1.O 1. 0. 0.C 1650.000 5000.000 71.84640 1 + 8.20224820E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-3.38486150E+04-4.00791290E+01 8.20224820E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-3.38486150E+04-4.00791290E+01 0.00000000E+00 4 +Fe(OH)2(s) J 6/66FE 1.O 2.H 2. 0.C 300.000 1500.000 89.86168 1 + 7.40318080E+00 1.19817420E-02-1.49576110E-06-5.05263590E-09 2.00371110E-12 2 +-7.15922660E+04-3.46732670E+01 1.00912180E+01 4.45231410E-03 4.06668550E-06 3 +-4.00945250E-09 2.39471640E-13-7.22776880E+04-4.84000340E+01-6.90429813E+04 4 +Fe(OH)3(s) J 6/66FE 1.O 3.H 3. 0.C 300.000 1500.000 106.86902 1 + 8.02239260E+00 1.64201350E-02-1.23693780E-07-6.81928380E-09 2.32769070E-12 2 +-1.03213360E+05-3.79340200E+01 4.41168360E+00 3.26824620E-02-2.23938150E-05 3 + 2.86467920E-09 2.26223210E-12-1.02718340E+05-2.13310140E+01-1.00141482E+05 4 +FeS(a) J 9/77FE 1.S 1. 0. 0.C 300.000 411.000 87.91300 1 + 1.89776270E+01-1.09542820E-01 2.21860160E-04 0.00000000E+00 0.00000000E+00 2 +-1.49952420E+04-7.81254350E+01 1.89776270E+01-1.09542820E-01 2.21860160E-04 3 + 0.00000000E+00 0.00000000E+00-1.49952420E+04-7.81254350E+01-1.22458515E+04 4 +FeS(b) J 9/77FE 1.S 1. 0. 0.C 411.000 598.000 87.91300 1 + 8.70285050E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.46897380E+04-4.20821020E+01 8.70285050E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.46897380E+04-4.20821020E+01 0.00000000E+00 4 +FeS(c) J 9/77FE 1.S 1. 0. 0.C 598.000 1463.000 87.91300 1 +-2.68304830E+00 3.67651040E-02-5.21822740E-05 3.16071700E-08-6.41260410E-12 2 +-1.14986840E+04 1.62391240E+01 9.37241760E+00 9.41620590E-04-1.58298640E-05 3 + 1.83808810E-08-5.77070670E-12-1.45816850E+04-4.51415160E+01 0.00000000E+00 4 +FeS(L) J 9/77FE 1.S 1. 0. 0.C 1463.000 5000.000 87.91300 1 + 7.52328060E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.01642370E+04-3.19709300E+01 7.52328060E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.01642370E+04-3.19709300E+01 0.00000000E+00 4 +FeSO4(s) J 6/66FE 1.S 1.O 4. 0.C 300.000 2000.000 151.91060 1 + 1.16089290E+01 1.38046970E-02-9.81263800E-06 3.60878110E-09-5.09762790E-13 2 +-1.16191860E+05-5.64778170E+01 3.50576840E+00 3.70297010E-02-2.90335310E-05 3 + 4.57785890E-09 2.62020870E-12-1.14162500E+05-1.52232410E+01-1.11717626E+05 4 +FeS2(s) J 9/77FE 1.S 2. 0. 0.C 300.000 1400.000 119.97900 1 +-8.85153200E+01 3.27489310E-01-4.10574390E-04 2.29281460E-07-4.77644150E-11 2 +-4.65124760E+02 4.41730450E+02 4.03456630E-01 4.26746840E-02-8.40306260E-05 3 + 7.63014410E-08-2.54323160E-11-2.20459270E+04-5.54563930E+00-2.06325071E+04 4 +Fe2O3(s) J 6/65FE 2.O 3. 0. 0.C 300.000 2500.000 159.69220 1 + 4.04975300E+01-4.61315960E-02 3.18264060E-05-8.92263310E-09 8.46554170E-13 2 +-1.13176270E+05-2.16350880E+02-7.70378430E+00 1.36474710E-01-3.29056550E-04 3 + 3.81504780E-07-1.63102850E-10-1.00800760E+05 2.52920850E+01-9.92620367E+04 4 +Fe2S3O12(s) J 6/66FE 2.S 3.O 12. 0.C 300.000 2000.000 399.88480 1 + 3.91144380E+01 1.17963270E-02-3.38710140E-08-2.29703990E-09 6.41019860E-13 2 +-3.24782620E+05-1.94004290E+02 1.11169550E+01 8.37067780E-02-4.13650750E-05 3 +-2.52792220E-08 2.10414350E-11-3.17297820E+05-4.92887500E+01-3.10668274E+05 4 +Fe3O4(s) J 6/65FE 3.O 4. 0. 0.C 300.000 5000.000 231.53860 1 + 2.41337200E+01 4.15922260E-05-2.63314920E-08 6.60350940E-12-5.69246800E-16 2 +-1.41210520E+05-1.20064120E+02 3.61981480E+01-1.74379760E-01 5.24756730E-04 3 +-5.42382190E-07 1.79962020E-10-1.41387300E+05-1.55566830E+02-1.34696136E+05 4 +H2O(s) L 8/89H 2.O 1. 0. 0.C 200.000 273.150 18.01528 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 5.29677970E+00-6.75749247E-02 5.16942109E-04 3 +-1.43853360E-06 1.52564794E-09-3.62266557E+04-1.79220428E+01-3.59742186E+04 4 +H2O(L) L 8/89H 2.O 1. 0. 0.C 273.150 600.000 18.01528 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 7.25575005E+01-6.62445402E-01 2.56198746E-03 3 +-4.36591923E-06 2.78178981E-09-4.18865499E+04-2.88280137E+02-3.43772513E+04 4 +H2SO4(L) J 9/77H 2.S 1.O 4. 0.C 300.000 1000.000 98.07948 1 + 9.94215250E+00 2.17863690E-02 3.49744580E-06-3.35488570E-09 1.16995860E-12 2 +-1.01859790E+05-4.43986950E+01 9.94215250E+00 2.17863690E-02 3.49744580E-06 3 +-3.35488570E-09 1.16995860E-12-1.01859790E+05-4.43986950E+01-9.79023828E+04 4 +Hg(cr) J12/61HG 1. 0. 0. 0.C 200.000 234.290 200.59000 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 2.43103385E+00 4.24646658E-03 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.17886806E+03-7.11248114E+00 0.00000000E+00 4 +Hg(L) J12/61HG 1. 0. 0. 0.C 234.290 2000.000 200.59000 1 + 3.03653487E+00 3.16006666E-04 6.43901172E-08-2.92306991E-11 4.86860918E-15 2 +-8.88170502E+02-8.17243018E+00 3.79685248E+00-2.09026109E-03 2.22267107E-06 3 +-1.08605655E-10-4.28087248E-13-1.05834631E+03-1.19626936E+01 0.00000000E+00 4 +HgBr2(s) J 3/62HG 1.BR 2. 0. 0.C 300.000 514.000 360.39800 1 + 8.28297140E+00 1.63023640E-03 3.42298790E-06 7.09619920E-10-4.33538620E-12 2 +-2.29524380E+04-2.73452760E+01 8.28297140E+00 1.63023640E-03 3.42298790E-06 3 + 7.09619920E-10-4.33538620E-12-2.29524380E+04-2.73452760E+01-2.03808119E+04 4 +HgBr2(L) J 3/62HG 1.BR 2. 0. 0.C 514.000 5000.000 360.39800 1 + 1.22787990E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-2.25008980E+04-4.68512120E+01 1.22787990E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-2.25008980E+04-4.68512120E+01 0.00000000E+00 4 +HgO(s) J 6/62HG 1.O 1. 0. 0.C 300.000 1000.000 216.58940 1 + 3.41708660E+00 7.11605700E-03-1.48969960E-06-4.49135480E-09 2.59379240E-12 2 +-1.22332700E+04-1.30371850E+01 3.41708660E+00 7.11605700E-03-1.48969960E-06 3 +-4.49135480E-09 2.59379240E-12-1.22332700E+04-1.30371850E+01-1.09189916E+04 4 +I2(cr) TPIS89I 2. 0. 0. 0.C 200.000 386.750 253.80894 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00-1.05757713E+01 2.26905653E-01-1.12461645E-03 3 + 2.41678452E-06-1.84901377E-09-8.99721615E+02 3.88598964E+01 0.00000000E+00 4 +I2(L) TPIS89I 2. 0. 0. 0.C 386.750 6000.000 253.80894 1 + 9.56821268E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.20451948E+03-3.63733927E+01 9.56821268E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.20451948E+03-3.63733927E+01 0.00000000E+00 4 +K(cr) CODA89K 1. 0. 0. 0.C 200.000 336.860 39.09830 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00-2.08951123E+00 6.16320193E-02-2.40731903E-04 3 + 3.27255823E-07 0.00000000E+00-6.36098059E+02 9.11736910E+00 0.00000000E+00 4 +K(L) CODA89K 1. 0. 0. 0.C 336.860 2200.000 39.09830 1 + 4.64954931E+00-2.79174106E-03 1.80836337E-06 3.41244868E-11-4.48782184E-15 2 +-1.01467797E+03-1.71767347E+01 4.22910563E+00-7.06885543E-04-2.12965848E-06 3 + 3.36227270E-09-1.05902602E-12-9.45117514E+02-1.52340054E+01 0.00000000E+00 4 +KCN(s) J 3/66K 1.C 1.N 1. 0.C 300.000 895.000 65.11604 1 + 8.17997280E+00-1.40107820E-03 3.42377250E-06-3.49617380E-09 1.30527800E-12 2 +-1.60482010E+04-3.09445250E+01 8.17997280E+00-1.40107820E-03 3.42377250E-06 3 +-3.49617380E-09 1.30527800E-12-1.60482010E+04-3.09445250E+01-1.36476597E+04 4 +KCN(L) J 3/66K 1.C 1.N 1. 0.C 895.000 5000.000 65.11604 1 + 9.05813050E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.52267170E+04-3.54540830E+01 9.05813050E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.52267170E+04-3.54540830E+01 0.00000000E+00 4 +KCL(s) J 3/66K 1.CL 1. 0. 0.C 300.000 1044.000 74.55100 1 + 3.91571690E+00-2.09272710E-03 4.73101820E-06 7.01525370E-09-5.51460980E-12 2 +-5.27470660E+04-1.01448000E+01 5.39343110E+00 2.65352420E-03 9.60756550E-07 3 +-5.02518430E-09 4.07212280E-12-5.42483890E+04-2.15968140E+01-5.25219178E+04 4 +KCL(L) J 3/66K 1.CL 1. 0. 0.C 1044.000 5000.000 74.55100 1 + 8.85180640E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-5.33694780E+04-4.00100590E+01 8.85180640E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-5.33694780E+04-4.00100590E+01 0.00000000E+00 4 +KF(s) J 6/69K 1.F 1. 0. 0.C 300.000 1131.000 58.09670 1 + 9.46277820E+00-6.40575120E-03 6.39132620E-08 7.59495890E-09-3.35981040E-12 2 +-7.12491070E+04-4.48318040E+01 4.98439720E+00 3.59431900E-03-1.76964010E-06 3 +-4.81061410E-10 1.02807300E-12-7.00181490E+04-2.13845040E+01-6.83883952E+04 4 +KF(L) J 6/69K 1.F 1. 0. 0.C 1131.000 5000.000 58.09670 1 + 8.65554690E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-6.92680250E+04-4.11799320E+01 8.65554690E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-6.92680250E+04-4.11799320E+01 0.00000000E+00 4 +KHF2(a) J 6/71K 1.H 1.F 2. 0.C 300.000 469.850 78.10305 1 +-9.12984980E+00 8.66188890E-02 4.39044120E-05-6.68675990E-07 8.04541630E-10 2 +-1.12582590E+05 4.10828000E+01-9.12984980E+00 8.66188890E-02 4.39044120E-05 3 +-6.68675990E-07 8.04541630E-10-1.12582590E+05 4.10828000E+01-1.12008733E+05 4 +KHF2(b) J 6/71K 1.H 1.F 2. 0.C 469.850 511.950 78.10305 1 + 1.20573780E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.14571260E+05-5.41701400E+01 1.20573780E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.14571260E+05-5.41701400E+01 0.00000000E+00 4 +KHF2(L) J 6/71K 1.H 1.F 2. 0.C 511.950 6000.000 78.10305 1 + 1.25807370E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.14043090E+05-5.58799150E+01 1.25807370E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.14043090E+05-5.58799150E+01 0.00000000E+00 4 +KOH(a) J12/70K 1.O 1.H 1. 0.C 300.000 516.000 56.10564 1 + 6.44009770E+00 1.13101680E-03 1.50732720E-05-1.49061190E-08 1.05563250E-11 2 +-5.31618980E+04-2.80988530E+01 6.44009770E+00 1.13101680E-03 1.50732720E-05 3 +-1.49061190E-08 1.05563250E-11-5.31618980E+04-2.80988530E+01-5.10828208E+04 4 +KOH(b) J12/70K 1.O 1.H 1. 0.C 516.000 679.000 56.10564 1 + 9.46071400E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-5.32916480E+04-4.33693260E+01 9.46071400E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-5.32916480E+04-4.33693260E+01 0.00000000E+00 4 +KOH(L) J12/70K 1.O 1.H 1. 0.C 679.000 5000.000 56.10564 1 + 9.99564690E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-5.26207310E+04-4.53343920E+01 9.99564690E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-5.26207310E+04-4.53343920E+01 0.00000000E+00 4 +KO2(s) J 6/71K 1.O 2. 0. 0.C 300.000 1500.000 71.09710 1 +-1.04945450E+01 6.88589880E-02-8.14023070E-05 4.29476920E-08-8.49658320E-12 2 +-3.24899890E+04 5.96859130E+01 3.87754870E+00 3.01570310E-02-5.11822510E-05 3 + 4.16338720E-08-1.30729560E-11-3.63407270E+04-1.44190320E+01-3.42203377E+04 4 +K2CO3(s) J 3/66K 2.C 1.O 3. 0.C 300.000 1174.000 138.20580 1 + 2.28243410E+01-1.35809930E-02 8.74098900E-06 1.14944250E-08-6.75881490E-12 2 +-1.45778440E+05-1.10486650E+02 8.43986320E+00 1.88362560E-02-4.68274830E-07 3 +-1.05196100E-08 6.43184120E-12-1.41667440E+05-3.48944240E+01-1.38335773E+05 4 +K2CO3(L) J 3/66K 2.C 1.O 3. 0.C 1174.000 5000.000 138.20580 1 + 2.51614690E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.47401380E+05-1.31107300E+02 2.51614690E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.47401380E+05-1.31107300E+02 0.00000000E+00 4 +K2O(s) J 6/63K 2.O 1. 0. 0.C 298.150 2000.000 94.19600 1 + 7.18702640E+00 9.11492365E-03-4.18066880E-06 1.79898267E-09-2.83941251E-13 2 +-4.60009426E+04-3.17449802E+01 4.43039872E-01 6.20637705E-02-1.36231073E-04 3 + 1.36376972E-07-4.90163860E-11-4.56125862E+04-4.75903470E+00-4.36791825E+04 4 +K2O2(s) J 9/63K 2.O 2. 0. 0.C 298.150 2000.000 110.19540 1 + 1.04816299E+01 6.90861807E-03 4.86567038E-07-2.54902723E-10 4.08386186E-14 2 +-6.31814318E+04-4.84772902E+01 8.82674208E+00 1.32621264E-02-1.11439578E-05 3 + 1.09588563E-08-4.24101605E-12-6.27735254E+04-4.02514321E+01-5.96311749E+04 4 +K2S(1) J 3/78K 2.S 1. 0. 0.C 300.000 1050.000 110.26260 1 +-7.48493370E+01 9.36197960E-02 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-9.72179390E+03 4.49673930E+02 3.13644310E+01-1.88106630E-01 5.60057270E-04 3 +-6.97035550E-07 3.12490940E-10-4.99974060E+04-1.28104550E+02-4.52887377E+04 4 +K2S(2) J 3/78K 2.S 1. 0. 0.C 1050.000 1100.000 110.26260 1 + 1.56428160E+02-1.26644440E-01 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.31144190E+05-9.27942750E+02 1.56428160E+02-1.26644440E-01 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.31144190E+05-9.27942750E+02 0.00000000E+00 4 +K2S(3) J 3/78K 2.S 1. 0. 0.C 1100.000 1221.000 110.26260 1 + 1.71198670E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-5.45249530E+04-9.16665110E+01 1.71198670E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-5.45249530E+04-9.16665110E+01 0.00000000E+00 4 +K2S(L) J 3/78K 2.S 1. 0. 0.C 1221.000 5000.000 110.26260 1 + 1.21429270E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-4.65203490E+04-5.47160430E+01 1.21429270E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-4.65203490E+04-5.47160430E+01 0.00000000E+00 4 +K2SO4(a) J 6/78K 2.S 1.O 4. 0.C 300.000 857.000 174.26020 1 + 1.70265260E+00 8.47097140E-02-1.76325730E-04 1.92828030E-07-7.64708900E-11 2 +-1.75980870E+05-7.56319510E+00 1.70265260E+00 8.47097140E-02-1.76325730E-04 3 + 1.92828030E-07-7.64708900E-11-1.75980870E+05-7.56319510E+00-1.72921009E+05 4 +K2SO4(b) J 6/78K 2.S 1.O 4. 0.C 857.000 1342.000 174.26020 1 +-2.90198660E+02 1.05696310E+00-1.34752990E-03 7.67665760E-07-1.63374400E-10 2 +-1.05542140E+05 1.45300940E+03 1.38071770E+01 9.67305900E-03 4.56585510E-08 3 + 0.00000000E+00 0.00000000E+00-1.75853260E+05-5.84412960E+01 0.00000000E+00 4 +K2SO4(L) J 6/78K 2.S 1.O 4. 0.C 1342.000 5000.000 174.26020 1 + 2.42304990E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.76955190E+05-1.17402220E+02 2.42304990E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.76955190E+05-1.17402220E+02 0.00000000E+00 4 +Li(cr) TPIS82LI 1. 0. 0. 0.C 200.000 453.690 6.94100 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 6.10909942E-01 1.41041217E-02-1.74958170E-05 3 +-3.33741023E-08 7.76629665E-11-6.25121208E+02-3.26449947E+00 0.00000000E+00 4 +Li(L) TPIS82LI 1. 0. 0. 0.C 453.690 3000.000 6.94100 1 + 3.89314223E+00-8.42787696E-04 4.45546328E-07-3.65337454E-11 3.89279220E-15 2 +-8.22019556E+02-1.78183077E+01 4.62266638E+00-4.06164205E-03 5.91666170E-06 3 +-4.24960085E-09 1.23517473E-12-9.58811267E+02-2.12778501E+01 0.00000000E+00 4 +LiALO2(s) J12/79LI 1.AL 1.O 2. 0.C 300.000 1973.000 65.92134 1 + 8.54408940E+00 6.48867910E-03-4.08639690E-06 1.54714660E-09-2.24950380E-13 2 +-1.45981500E+05-4.45906180E+01-5.28411560E+00 7.84525870E-02-1.45415780E-04 3 + 1.24629580E-07-4.01137050E-11-1.43818310E+05 1.85767330E+01-1.42964183E+05 4 +LiALO2(L) J12/79LI 1.AL 1.O 2. 0.C 1973.000 5000.000 65.92134 1 + 1.50966790E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.41658390E+05-8.09937670E+01 1.50966790E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.41658390E+05-8.09937670E+01 0.00000000E+00 4 +LiCL(s) J 6/62LI 1.CL 1. 0. 0.C 300.000 883.000 42.39370 1 + 4.10952450E+00 8.19810030E-03-1.15418740E-05 1.05853860E-08-3.64570220E-12 2 +-5.06082660E+04-1.82988940E+01 4.10952450E+00 8.19810030E-03-1.15418740E-05 3 + 1.05853860E-08-3.64570220E-12-5.06082660E+04-1.82988940E+01-4.91014060E+04 4 +LiCL(L) J 6/62LI 1.CL 1. 0. 0.C 883.000 2000.000 42.39370 1 + 8.21494770E+00 5.63913610E-04-1.73503310E-06 7.65950080E-10-1.23784770E-13 2 +-5.00073220E+04-3.88089610E+01 1.03830280E+01-4.71796990E-03-1.61383170E-06 3 + 8.08071740E-09-4.44594930E-12-5.05391200E+04-4.99219600E+01 0.00000000E+00 4 +LiF(s) J12/68LI 1.F 1. 0. 0.C 300.000 1121.300 25.93940 1 + 5.54057380E+00-1.34210800E-04 1.78256060E-06 8.89964440E-10-9.12966540E-13 2 +-7.59003650E+04-2.74472760E+01 1.76943250E+00 1.75052240E-02-2.80387510E-05 3 + 2.28933850E-08-6.96336580E-12-7.52992780E+04-9.94780570E+00-7.41994361E+04 4 +LiF(L) J12/68LI 1.F 1. 0. 0.C 1121.300 5000.000 25.93940 1 + 7.71954010E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-7.43043470E+04-3.88154870E+01 7.71954010E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-7.43043470E+04-3.88154870E+01 0.00000000E+00 4 +LiH(s) J 9/67LI 1.H 1. 0. 0.C 300.000 961.800 7.94894 1 + 3.86118120E-01 1.21279570E-02-8.69003360E-06 5.63115550E-09-1.26934830E-12 2 +-1.14869910E+04-3.06545750E+00 3.86118120E-01 1.21279570E-02-8.69003360E-06 3 + 5.63115550E-09-1.26934830E-12-1.14869910E+04-3.06545750E+00-1.08990681E+04 4 +LiH(L) J 9/67LI 1.H 1. 0. 0.C 961.800 5000.000 7.94894 1 + 7.49811910E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.15818260E+04-4.00472780E+01 7.49811910E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.15818260E+04-4.00472780E+01 0.00000000E+00 4 +LiOH(s) J 6/71LI 1.O 1.H 1. 0.C 300.000 744.300 23.94834 1 + 6.32277970E-01 2.53405380E-02-2.78979500E-05 8.69258930E-09 4.14998940E-12 2 +-5.94126800E+04-4.83826970E+00 6.32277970E-01 2.53405380E-02-2.78979500E-05 3 + 8.69258930E-09 4.14998940E-12-5.94126800E+04-4.83826970E+00-5.83252001E+04 4 +LiOH(L) J 6/71LI 1.O 1.H 1. 0.C 744.300 5000.000 23.94834 1 + 1.04742180E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-6.01856710E+04-5.38971400E+01 1.04742180E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-6.01856710E+04-5.38971400E+01 0.00000000E+00 4 +Li2O(s) J 3/64LI 2.O 1. 0. 0.C 300.000 1843.000 29.88140 1 + 4.27747760E+00 7.85216720E-03-5.22250900E-07-1.78644260E-09 5.39610350E-13 2 +-7.33962780E+04-2.17654970E+01-3.17272390E-01 3.61493560E-02-5.54559210E-05 3 + 4.17964370E-08-1.18040480E-11-7.31061960E+04-2.28883300E+00-7.20069902E+04 4 +Li2O(L) J 3/64LI 2.O 1. 0. 0.C 1843.000 5000.000 29.88140 1 + 1.20769310E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-7.13379210E+04-6.51749740E+01 1.20769310E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-7.13379210E+04-6.51749740E+01 0.00000000E+00 4 +Li2SO4(a) J12/78LI 2.S 1.O 4. 0.C 200.000 848.000 109.94560 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00-4.13873597E+00 1.06940568E-01-2.09346052E-04 3 + 2.12892822E-07-8.01625106E-11-1.74806776E+05 1.29835773E+01-1.72754257E+05 4 +Li2SO4(b) J12/78LI 2.S 1.O 4. 0.C 848.000 1132.000 109.94560 1 + 2.61026513E+01-8.29304728E-04 3.90810735E-07 0.00000000E+00 0.00000000E+00 2 +-1.80422445E+05-1.38008099E+02 2.57954812E+01-2.84625052E-04 1.53301129E-07 3 + 0.00000000E+00 0.00000000E+00-1.80308445E+05-1.36312168E+02-1.72754257E+05 4 +Li2SO4(L) J12/78LI 2.S 1.O 4. 0.C 1132.000 6000.000 109.94560 1 + 2.46579132E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.78097798E+05-1.27626158E+02 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00-1.72754257E+05 4 +Li3N(s) J 3/78LI 3.N 1. 0. 0.C 300.000 1300.000 34.82974 1 + 5.44225030E+00 1.34777370E-02-1.94223220E-06-2.49601090E-11 0.00000000E+00 2 +-2.20157760E+04-2.74572750E+01 2.92255580E+00 2.85987020E-02-3.53369470E-05 3 + 3.18619850E-08-1.10935010E-11-2.16780290E+04-1.63310570E+01-1.97900194E+04 4 +Mg(cr) SRD 93MG 1. 0. 0. 0.C 298.150 923.000 24.30500 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 1.47884944E+00 9.27430526E-03-1.95050788E-05 3 + 1.98215527E-08-7.04927374E-12-7.16649299E+02-6.57222695E+00 0.00000000E+00 4 +Mg(L) SRD 93MG 1. 0. 0. 0.C 923.000 6000.000 24.30500 1 + 4.12531827E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-6.58934341E+02-1.93786894E+01 4.12531827E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-6.58934341E+02-1.93786894E+01 0.00000000E+00 4 +MgAL2O4(s) J12/79MG 1.AL 2.O 4. 0.C 300.000 2408.000 142.26568 1 + 1.46976790E+01 9.33047970E-03-3.55225980E-06 1.15505300E-09-1.43345310E-13 2 +-2.81664110E+05-7.66686850E+01-6.39126250E+00 1.17188600E-01-2.13251780E-04 3 + 1.82774050E-07-5.88319910E-11-2.78271410E+05 2.01327010E+01-2.76518945E+05 4 +MgAL2O4(L) J12/79MG 1.AL 2.O 4. 0.C 2408.000 5000.000 142.26568 1 + 2.64191880E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-2.68835360E+05-1.41985810E+02 2.64191880E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-2.68835360E+05-1.41985810E+02 0.00000000E+00 4 +MgBr2(s) J 6/74MG 1.BR 2. 0. 0.C 300.000 984.000 184.11300 1 + 5.19664220E+00 2.06702530E-02-3.72539390E-05 3.19375640E-08-9.95070160E-12 2 +-6.52526160E+04-2.02889100E+01 5.19664220E+00 2.06702530E-02-3.72539390E-05 3 + 3.19375640E-08-9.95070160E-12-6.52526160E+04-2.02889100E+01-6.30552290E+04 4 +MgBr2(L) J 6/74MG 1.BR 2. 0. 0.C 984.000 5000.000 184.11300 1 + 1.25807370E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-6.39629820E+04-5.62554600E+01 1.25807370E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-6.39629820E+04-5.62554600E+01 0.00000000E+00 4 +MgCO3(s) J12/66MG 1.C 1.O 3. 0.C 300.000 1000.000 84.31420 1 + 1.34919240E+00 3.69341120E-02-4.44929520E-05 3.18159060E-08-9.75453000E-12 2 +-1.35416850E+05-9.06187320E+00 1.34919240E+00 3.69341120E-02-4.44929520E-05 3 + 3.18159060E-08-9.75453000E-12-1.35416850E+05-9.06187320E+00-1.33707806E+05 4 +MgCL2(s) J12/65MG 1.CL 2. 0. 0.C 300.000 987.000 95.21040 1 + 5.44912960E+00 1.67452240E-02-2.59569070E-05 1.91115730E-08-5.10590140E-12 2 +-7.93438940E+04-2.42610840E+01 5.44912960E+00 1.67452240E-02-2.59569070E-05 3 + 1.91115730E-08-5.10590140E-12-7.93438940E+04-2.42610840E+01-7.71689336E+04 4 +MgCL2(L) J12/65MG 1.CL 2. 0. 0.C 987.000 5000.000 95.21040 1 + 1.10710480E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-7.62946180E+04-4.89725880E+01 1.10710480E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-7.62946180E+04-4.89725880E+01 0.00000000E+00 4 +MgF2(s) J 6/75MG 1.F 2. 0. 0.C 300.000 1536.000 62.30181 1 +-2.10224270E+00 3.50242280E-02-3.97498930E-05 2.04618590E-08-3.95344100E-12 2 +-1.35393080E+05 1.10445550E+01 1.60361100E+00 3.17944860E-02-5.26857980E-05 3 + 4.15877060E-08-1.26194950E-11-1.36720340E+05-9.73231710E+00-1.35218306E+05 4 +MgF2(L) J 6/75MG 1.F 2. 0. 0.C 1536.000 5000.000 62.30181 1 + 1.14167670E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.34084100E+05-5.74250690E+01 1.14167670E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.34084100E+05-5.74250690E+01 0.00000000E+00 4 +MgI2(s) J12/74MG 1.I 2. 0. 0.C 300.000 907.000 278.11394 1 + 6.70171590E+00 1.16970220E-02-1.68363080E-05 1.31438090E-08-4.00999570E-12 2 +-4.65277610E+04-2.54320430E+01 6.70171590E+00 1.16970220E-02-1.68363080E-05 3 + 1.31438090E-08-4.00999570E-12-4.65277610E+04-2.54320430E+01-4.41344148E+04 4 +MgI2(L) J12/74MG 1.I 2. 0. 0.C 907.000 5000.000 278.11394 1 + 1.20775070E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-4.55256600E+04-5.18835260E+01 1.20775070E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-4.55256600E+04-5.18835260E+01 0.00000000E+00 4 +MgO(s) J12/74MG 1.O 1. 0. 0.C 300.000 3105.000 40.30440 1 + 5.04486810E+00 1.68982010E-03-7.56176950E-07 2.02868930E-10-2.05912710E-14 2 +-7.40292850E+04-2.63288920E+01-4.54039530E-01 2.78732690E-02-4.90622470E-05 3 + 4.04741510E-08-1.26703440E-11-7.30579480E+04-6.35520200E-01-7.23138995E+04 4 +MgO(L) J12/74MG 1.O 1. 0. 0.C 3105.000 5000.000 40.30440 1 + 8.05167150E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-6.98794510E+04-4.43438250E+01 8.05167150E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-6.98794510E+04-4.43438250E+01 0.00000000E+00 4 +MgO2H2(s) J12/75MG 1.O 2.H 2. 0.C 300.000 1000.000 58.31968 1 +-4.16642480E+00 7.68449870E-02-1.37207670E-04 1.14268590E-07-3.59258370E-11 2 +-1.12384340E+05 1.35926370E+01-4.16642480E+00 7.68449870E-02-1.37207670E-04 3 + 1.14268590E-07-3.59258370E-11-1.12384340E+05 1.35926370E+01-1.11214407E+05 4 +MgS(s) J 9/77MG 1.S 1. 0. 0.C 300.000 3000.000 56.37100 1 + 5.35012290E+00 1.34336550E-03-6.29050000E-07 1.98198580E-10-2.25916480E-14 2 +-4.32385480E+04-2.48378310E+01 4.09728770E+00 6.92978580E-03-9.20292860E-06 3 + 5.63293350E-09-1.21703300E-12-4.30407590E+04-1.89960010E+01-4.15818955E+04 4 +MgSO4(s) L 7/76MG 1.S 1.O 4. 0.C 300.000 1400.000 120.36860 1 +-6.44769200E+01 2.63753170E-01-3.24918840E-04 1.82572340E-07-3.86907670E-11 2 +-1.40661070E+05 3.21883890E+02 2.15340590E+00 4.87565320E-02-7.36650300E-05 3 + 5.94277870E-08-1.84337080E-11-1.56809620E+05-1.30284440E+01-1.54542596E+05 4 +MgSO4(L) L 7/76MG 1.S 1.O 4. 0.C 1400.000 5000.000 120.36860 1 + 1.91227200E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.60928760E+05-1.01804650E+02 1.91227200E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.60928760E+05-1.01804650E+02 0.00000000E+00 4 +MgSiO3(I) J12/67MG 1.SI 1.O 3. 0.C 300.000 903.000 100.38870 1 + 1.33777790E+00 4.44532220E-02-6.59737530E-05 4.74142570E-08-1.23310980E-11 2 +-1.88172260E+05-1.01789360E+01 1.33777790E+00 4.44532220E-02-6.59737530E-05 3 + 4.74142570E-08-1.23310980E-11-1.88172260E+05-1.01789360E+01-1.86292592E+05 4 +MgSiO3(II) J12/67MG 1.SI 1.O 3. 0.C 903.000 1258.000 100.38870 1 + 1.44738860E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.91621720E+05-7.66594640E+01 1.44738860E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.91621720E+05-7.66594640E+01 0.00000000E+00 4 +MgSiO3(III) J12/67MG 1.SI 1.O 3. 0.C 1258.000 1850.000 100.38870 1 + 1.47255010E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.91741990E+05-7.82992980E+01 1.47255010E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.91741990E+05-7.82992980E+01 0.00000000E+00 4 +MgSiO3(L) J12/67MG 1.SI 1.O 3. 0.C 1850.000 5000.000 100.38870 1 + 1.76130310E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.88025790E+05-9.51257310E+01 1.76130310E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.88025790E+05-9.51257310E+01 0.00000000E+00 4 +MgTiO3(s) J 6/67MG 1.TI 1.O 3. 0.C 300.000 1953.000 120.18320 1 + 1.02882240E+01 1.03437300E-02-7.40121790E-06 2.79288240E-09-3.95324480E-13 2 +-1.92811680E+05-5.29580880E+01-1.57777430E-01 6.20183970E-02-1.04805960E-04 3 + 8.49409250E-08-2.63672950E-11-1.91077380E+05-4.66165350E+00-1.89138441E+05 4 +MgTiO3(L) J 6/67MG 1.TI 1.O 3. 0.C 1953.000 5000.000 120.18320 1 + 1.96259490E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.90918120E+05-1.06562040E+02 1.96259490E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.90918120E+05-1.06562040E+02 0.00000000E+00 4 +MgTi2O5(s) J 6/67MG 1.TI 2.O 5. 0.C 300.000 1963.000 200.06200 1 + 1.67766080E+01 1.22377910E-02-6.30131600E-06 2.40194880E-09-3.54129300E-13 2 +-3.07546550E+05-8.32933900E+01 1.27163110E+00 9.26637940E-02-1.63695020E-04 3 + 1.39033730E-07-4.45132320E-11-3.05116130E+05-1.24221020E+01-3.01810872E+05 4 +MgTi2O5(L) J 6/67MG 1.TI 2.O 5. 0.C 1963.000 5000.000 200.06200 1 + 3.14015190E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-3.04100010E+05-1.68586490E+02 3.14015190E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-3.04100010E+05-1.68586490E+02 0.00000000E+00 4 +Mg2SiO4(s) J12/67MG 2.SI 1.O 4. 0.C 300.000 2171.000 140.69310 1 + 1.57526790E+01 6.80046500E-03-1.62039510E-06 7.73681120E-12 6.33375730E-14 2 +-2.67299550E+05-8.14579920E+01 1.34289820E+00 6.68665880E-02-9.64456250E-05 3 + 6.64239600E-08-1.71839900E-11-2.64469010E+05-1.23991620E+01-2.61825552E+05 4 +Mg2SiO4(L) J12/67MG 2.SI 1.O 4. 0.C 2171.000 5000.000 140.69310 1 + 2.46582440E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-2.66925490E+05-1.34615100E+02 2.46582440E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-2.66925490E+05-1.34615100E+02 0.00000000E+00 4 +Mg2TiO4(s) J 6/67MG 2.TI 1.O 4. 0.C 300.000 2013.000 160.48760 1 + 1.47725770E+01 1.08241470E-02-4.99075600E-06 1.74079440E-09-2.53981950E-13 2 +-2.65390780E+05-7.39337100E+01-5.04411560E-02 8.80864240E-02-1.56837890E-04 3 + 1.34018470E-07-4.31237870E-11-2.63078650E+05-6.25375070E+00-2.60319690E+05 4 +Mg2TiO4(L) J 6/67MG 2.TI 1.O 4. 0.C 2013.000 5000.000 160.48760 1 + 2.74763290E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-2.61535590E+05-1.47458370E+02 2.74763290E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-2.61535590E+05-1.47458370E+02 0.00000000E+00 4 +Mo(cr) J 3/78MO 1. 0. 0. 0.C 200.000 2896.000 95.94000 1 + 5.38432823E+00-6.01622180E-03 6.01482526E-06-2.32962338E-09 3.52007808E-13 2 +-1.62657220E+03-2.62488891E+01 1.32884141E+00 9.82553689E-03-2.10929825E-05 3 + 2.09509528E-08-7.60703244E-12-6.84364789E+02-6.29286538E+00 0.00000000E+00 4 +Mo(L) J 3/78MO 1. 0. 0. 0.C 2896.000 6000.000 95.94000 1 + 4.52894999E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 2.02140667E+03-2.28074752E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4 +NH4CL(a) BAR 73N 1.H 4.CL 1. 0.C 298.150 458.000 53.49120 1 + 4.67493830E+00 1.92734250E-02 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-4.00827510E+04-2.09591330E+01 4.67493830E+00 1.92734250E-02 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-4.00827510E+04-2.09591330E+01-3.78322780E+04 4 +NH4CL(b) BAR 73N 1.H 4.CL 1. 0.C 458.000 793.200 53.49120 1 + 4.16668500E+00 1.34360490E-02 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-3.87626930E+04-1.41344020E+01 4.16668500E+00 1.34360490E-02 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-3.87626930E+04-1.41344020E+01-3.78322780E+04 4 +Na(cr) CODA89NA 1. 0. 0. 0.C 200.000 371.010 22.98977 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 1.23954242E+00 2.00562189E-02-7.36418252E-05 3 + 1.02712149E-07 0.00000000E+00-8.13320916E+02-4.50651391E+00 0.00000000E+00 4 +Na(L) CODA89NA 1. 0. 0. 0.C 371.010 2300.000 22.98977 1 + 4.59858543E+00-2.42459406E-03 1.32453794E-06-4.12375317E-11 6.40167081E-15 2 +-9.98535534E+02-1.86257127E+01 4.32382419E+00-1.41145451E-03-1.31068846E-07 3 + 9.17457679E-10-2.35065070E-13-9.36522263E+02-1.72722638E+01 0.00000000E+00 4 +NaALO2(a) J 3/63NA 1.AL 1.O 2. 0.C 300.000 740.000 81.97011 1 +-8.05047800E-01 5.84349680E-02-1.18844150E-04 1.19700420E-07-4.62247930E-11 2 +-1.37816650E+05-5.33352820E-02-8.05047800E-01 5.84349680E-02-1.18844150E-04 3 + 1.19700420E-07-4.62247930E-11-1.37816650E+05-5.33352820E-02-1.36294676E+05 4 +NaALO2(b) J 3/63NA 1.AL 1.O 2. 0.C 740.000 3000.000 81.97011 1 + 1.19662150E+01-2.28172770E-03 3.77137410E-06-1.29326700E-09 1.41350220E-13 2 +-1.40048180E+05-6.00064550E+01 1.05423430E+01 8.84839070E-04 1.39067630E-06 3 +-5.13913930E-10 0.00000000E+00-1.39580600E+05-5.23713620E+01 0.00000000E+00 4 +NaBr(s) J 9/64NA 1.BR 1. 0. 0.C 300.000 1020.000 102.89377 1 + 6.62464480E+00 1.23829830E-04 4.09902760E-07 2.06836510E-10-1.80764850E-14 2 +-4.55603720E+04-2.76058000E+01 4.87664610E+00 6.83189280E-03-1.06411630E-05 3 + 9.16139280E-09-2.88162970E-12-4.51486440E+04-1.89825450E+01-4.34682858E+04 4 +NaBr(L) J 9/64NA 1.BR 1. 0. 0.C 1020.000 5000.000 102.89377 1 + 7.49811910E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-4.30497700E+04-3.01704510E+01 7.49811910E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-4.30497700E+04-3.01704510E+01 0.00000000E+00 4 +NaCN(s) J 3/66NA 1.C 1.N 1. 0.C 300.000 835.000 49.00751 1 + 7.99677320E+00 1.91545500E-03-5.34215910E-06 6.80916420E-09-3.14149110E-12 2 +-1.33402940E+04-3.17039330E+01 7.99677320E+00 1.91545500E-03-5.34215910E-06 3 + 6.80916420E-09-3.14149110E-12-1.33402940E+04-3.17039330E+01-1.09061445E+04 4 +NaCN(L) J 3/66NA 1.C 1.N 1. 0.C 835.000 5000.000 49.00751 1 + 9.56136000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.33864070E+04-4.02873090E+01 9.56136000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.33864070E+04-4.02873090E+01 0.00000000E+00 4 +NaCL(s) J 9/64NA 1.CL 1. 0. 0.C 300.000 1073.800 58.44247 1 + 2.21349270E+00 1.58599020E-03 5.04863830E-06 2.60205490E-09-3.64870960E-12 2 +-4.92632030E+04-2.60256600E+00 5.02407780E+00 5.19490660E-03-7.28337300E-06 3 + 6.06719790E-09-1.20134240E-12-5.11233350E+04-2.12272010E+01-4.94474351E+04 4 +NaCL(L) J 9/64NA 1.CL 1. 0. 0.C 1073.800 5000.000 58.44247 1 + 1.23584880E+01-6.30712010E-03 3.20047230E-06-6.77173620E-10 5.10156120E-14 2 +-5.14232650E+04-6.05855300E+01 1.23584880E+01-6.30712010E-03 3.20047230E-06 3 +-6.77173620E-10 5.10156120E-14-5.14232650E+04-6.05855300E+01 0.00000000E+00 4 +NaF(s) J12/68NA 1.F 1. 0. 0.C 300.000 1269.000 41.98817 1 + 7.83420260E+00-9.48391800E-04-5.48439860E-06 8.68430220E-09-2.92858600E-12 2 +-7.18104050E+04-3.88157100E+01 3.69775520E+00 1.05205720E-02-1.72356560E-05 3 + 1.41259110E-08-3.95145290E-12-7.06471830E+04-1.73936330E+01-6.92033173E+04 4 +NaF(L) J12/68NA 1.F 1. 0. 0.C 1269.000 3500.000 41.98817 1 + 1.09632610E+01-3.20684590E-03 1.16116620E-06-1.62992970E-10 5.24561410E-15 2 +-7.06739430E+04-5.63756950E+01 1.09632610E+01-3.20684590E-03 1.16116620E-06 3 +-1.62992970E-10 5.24561410E-15-7.06739430E+04-5.63756950E+01 0.00000000E+00 4 +NaI(s) J 9/63NA 1.I 1. 0. 0.C 300.000 933.000 149.89424 1 + 5.49959840E+00 3.56680530E-03-3.99656300E-06 3.18410730E-09-9.53087220E-13 2 +-3.63903560E+04-2.03992510E+01 5.49959840E+00 3.56680530E-03-3.99656300E-06 3 + 3.18410730E-09-9.53087220E-13-3.63903560E+04-2.03992510E+01-3.46215846E+04 4 +NaI(L) J 9/63NA 1.I 1. 0. 0.C 933.000 5000.000 149.89424 1 + 7.80005680E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-3.47595680E+04-3.08188810E+01 7.80005680E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-3.47595680E+04-3.08188810E+01 0.00000000E+00 4 +NaOH(a) J12/70NA 1.O 1.H 1. 0.C 300.000 596.000 39.99711 1 + 8.58794940E+00-3.54060130E-03-4.55333940E-05 1.84184830E-07-1.50189730E-10 2 +-5.35118510E+04-3.94075850E+01 8.58794940E+00-3.54060130E-03-4.55333940E-05 3 + 1.84184830E-07-1.50189730E-10-5.35118510E+04-3.94075850E+01-5.12178981E+04 4 +NaOH(L) J12/70NA 1.O 1.H 1. 0.C 596.000 2500.000 39.99711 1 + 9.49723210E+00 2.27179720E-03-2.39779340E-06 7.83984770E-10-8.19764720E-14 2 +-5.29068240E+04-4.52999000E+01 9.05567750E+00 4.30250410E-03-2.42591320E-06 3 +-3.54796640E-09 2.68894200E-12-5.29424450E+04-4.35151400E+01 0.00000000E+00 4 +NaO2(s) J 6/63NA 1.O 2. 0. 0.C 300.000 2000.000 54.98857 1 + 6.67531770E+00 6.42345130E-03-1.54377730E-06 6.83577740E-10-1.10739220E-13 2 +-3.35725460E+04-2.58486080E+01 7.27988820E+00 4.41607210E-03 1.24139210E-06 3 +-1.29211710E-09 4.82594790E-13-3.37265610E+04-2.88998070E+01-3.13511405E+04 4 +Na2CO3(I) J 3/66NA 2.C 1.O 3. 0.C 300.000 723.150 105.98874 1 + 6.78356590E+00 3.88297010E-02-9.82624550E-05 1.65430840E-07-8.32945150E-11 2 +-1.39170100E+05-3.04632930E+01 6.78356590E+00 3.88297010E-02-9.82624550E-05 3 + 1.65430840E-07-8.32945150E-11-1.39170100E+05-3.04632930E+01-1.36002267E+05 4 +Na2CO3(II) J 3/66NA 2.C 1.O 3. 0.C 723.150 1123.150 105.98874 1 + 8.28177550E+00 1.12753890E-02 1.99632940E-06 0.00000000E+00 0.00000000E+00 2 +-1.37612660E+05-3.13725800E+01 1.18483410E+01-3.51389860E-03 2.06155690E-05 3 +-7.39651750E-09 0.00000000E+00-1.38141870E+05-4.80643680E+01 0.00000000E+00 4 +Na2CO3(L) J 3/66NA 2.C 1.O 3. 0.C 1123.150 5000.000 105.98874 1 + 2.27962950E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.42292180E+05-1.16221210E+02 2.27962950E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.42292180E+05-1.16221210E+02 0.00000000E+00 4 +Na2O(c) J 6/68NA 2.O 1. 0. 0.C 300.000 1243.200 61.97894 1 + 2.41689560E+01-2.52797440E-02-4.73906580E-06 3.18363870E-08-1.45702650E-11 2 +-5.80482360E+04-1.25180650E+02 5.26545830E+00 1.11168720E-02-6.38753820E-07 3 +-9.69932070E-09 5.37200710E-12-5.23143450E+04-2.41870240E+01-5.02726131E+04 4 +Na2O(a) J 6/68NA 2.O 1. 0. 0.C 1243.200 1405.200 61.97894 1 +-1.49065900E+02 2.27990380E-01 3.83912680E-05-1.70999190E-07 6.13959260E-11 2 + 1.16147950E+04 8.46892680E+02-1.49065900E+02 2.27990380E-01 3.83912680E-05 3 +-1.70999190E-07 6.13959260E-11 1.16147950E+04 8.46892680E+02 0.00000000E+00 4 +Na2O(L) J 6/68NA 2.O 1. 0. 0.C 1405.200 5000.000 61.97894 1 + 1.25807370E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-4.85948570E+04-6.06615490E+01 1.25807370E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-4.85948570E+04-6.06615490E+01 0.00000000E+00 4 +Na2O2(a) J 6/68NA 2.O 2. 0. 0.C 300.000 785.000 77.97834 1 + 4.58152780E+00 3.24559100E-02-5.11542010E-05 4.26639790E-08-1.39916370E-11 2 +-6.41610530E+04-2.24554530E+01 4.58152780E+00 3.24559100E-02-5.11542010E-05 3 + 4.26639790E-08-1.39916370E-11-6.41610530E+04-2.24554530E+01-6.17267448E+04 4 +Na2O2(b) J 6/68NA 2.O 2. 0. 0.C 785.000 5000.000 77.97834 1 + 1.36626800E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-6.56325710E+04-6.68415510E+01 1.36626800E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-6.56325710E+04-6.68415510E+01 0.00000000E+00 4 +Na2S(1) J 3/78NA 2.S 1. 0. 0.C 300.000 1276.000 78.04554 1 + 4.46755600E+02-1.05851110E+00 8.11700930E-04-1.88778780E-07 0.00000000E+00 2 +-1.77483940E+05-2.34626590E+03 9.70755990E+00-3.11261830E-04 5.51211610E-06 3 +-6.04350720E-09 2.30175490E-12-4.69503790E+04-4.38376130E+01-4.40320621E+04 4 +Na2S(2) J 3/78NA 2.S 1. 0. 0.C 1276.000 1445.000 78.04554 1 +-5.67935490E+05 1.68041210E+03-1.86226790E+00 9.16205880E-04-1.68848790E-07 2 + 1.53328050E+08 2.91086870E+06-5.67935490E+05 1.68041210E+03-1.86226790E+00 3 + 9.16205880E-04-1.68848790E-07 1.53328050E+08 2.91086870E+06 0.00000000E+00 4 +Na2S(L) J 3/78NA 2.S 1. 0. 0.C 1445.000 5000.000 78.04554 1 + 1.10710480E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-4.27909300E+04-4.86158890E+01 1.10710480E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-4.27909300E+04-4.86158890E+01 0.00000000E+00 4 +Na2SO4(V) J 6/78NA 2.S 1.O 4. 0.C 200.000 458.000 142.04314 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 5.83393186E+00 3.08201992E-02 5.97986350E-05 3 +-2.59779078E-07 2.47853998E-10-1.70156075E+05-2.52886427E+01-1.66914947E+05 4 +Na2SO4(IV) J 6/78NA 2.S 1.O 4. 0.C 458.000 514.000 142.04314 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 9.71967784E+00 2.18820420E-02-6.19770747E-06 3 + 0.00000000E+00 0.00000000E+00-1.70712819E+05-4.36063369E+01-1.66914947E+05 4 +Na2SO4(I) J 6/78NA 2.S 1.O 4. 0.C 514.000 1157.000 142.04314 1 + 1.61157389E+01 8.20925891E-03-2.33305547E-07 0.00000000E+00 0.00000000E+00 2 +-1.71129101E+05-7.46990748E+01 1.54854389E+01 1.92613777E-02-3.32257332E-05 3 + 3.56283302E-08-1.30577214E-11-1.71322923E+05-7.35127015E+01-1.66914947E+05 4 +Na2SO4(L) J 6/78NA 2.S 1.O 4. 0.C 1157.000 6000.000 142.04314 1 + 2.36977729E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.71658912E+05-1.16358482E+02 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00-1.66914947E+05 4 +Na3ALF6(a) J12/79NA 3.AL 1.F 6. 0.C 300.000 836.000 209.94126 1 + 2.25929580E+00 1.55696660E-01-3.61618440E-04 4.04790800E-07-1.65055520E-10 2 +-4.04059930E+05-1.77985450E+01 2.25929580E+00 1.55696660E-01-3.61618440E-04 3 + 4.04790800E-07-1.65055520E-10-4.04059930E+05-1.77985450E+01-3.98938949E+05 4 +Na3ALF6(b) J12/79NA 3.AL 1.F 6. 0.C 836.000 1285.000 209.94126 1 + 9.55439570E+00 3.52015420E-02-1.46209940E-05 4.40206690E-09 0.00000000E+00 2 +-3.99075520E+05-2.82161770E+01 1.65936570E+01 1.69116940E-02 1.03166000E-06 3 + 0.00000000E+00 0.00000000E+00-4.01086890E+05-6.49107920E+01 0.00000000E+00 4 +Na3ALF6(L) J12/79NA 3.AL 1.F 6. 0.C 1285.000 5000.000 209.94126 1 + 4.75676230E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-4.12965380E+05-2.53758800E+02 4.75676230E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-4.12965380E+05-2.53758800E+02 0.00000000E+00 4 +Na5AL3F14(s) J12/79NA 5.AL 3.F 14. 0.C 300.000 1010.000 461.87110 1 + 6.08053760E+01 1.01490150E-02 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-9.31943650E+05-2.94919480E+02 1.37281710E+01 2.32983000E-01-4.16721720E-04 3 + 3.53732680E-07-1.12767740E-10-9.23255820E+05-7.39137540E+01-9.11843310E+05 4 +Na5AL3F14(L) J12/79NA 5.AL 3.F 14. 0.C 1010.000 5000.000 461.87110 1 + 1.17130100E+02 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-9.56128840E+05-6.47053090E+02 1.17130100E+02 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-9.56128840E+05-6.47053090E+02 0.00000000E+00 4 +Nb(cr) J12/73NB 1. 0. 0. 0.C 200.000 2750.000 92.90638 1 + 4.21499986E+00-2.90686491E-03 3.12396990E-06-1.27909749E-09 2.09229406E-13 2 +-1.28682102E+03-1.91976179E+01 1.91200557E+00 6.92396275E-03-1.56081201E-05 3 + 1.61804090E-08-6.04602043E-12-7.69037196E+02-8.00990261E+00 0.00000000E+00 4 +Nb(L) J12/73NB 1. 0. 0. 0.C 2750.000 6000.000 92.90638 1 + 4.02573333E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 1.42704047E+03-1.85790552E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4 +NbO(s) J12/73NB 1.O 1. 0. 0.C 300.000 2210.000 108.90578 1 + 5.12365530E+00 8.93758600E-04 3.09308450E-07-1.64337020E-10 2.85698350E-14 2 +-5.21109100E+04-2.40995200E+01 2.98212600E+00 1.02175450E-02-1.51788950E-05 3 + 1.13084670E-08-3.13828580E-12-5.17033690E+04-1.39185970E+01-5.04733489E+04 4 +NbO(L) J12/73NB 1.O 1. 0. 0.C 2210.000 5000.000 108.90578 1 + 7.54844210E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-4.45871380E+04-3.58173400E+01 7.54844210E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-4.45871380E+04-3.58173400E+01 0.00000000E+00 4 +NbO2(I) J12/73NB 1.O 2. 0. 0.C 200.000 1090.000 124.90518 1 + 5.28902716E+00 5.20386062E-03 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-9.72972461E+04-2.48908597E+01-1.54841792E+00 5.45536428E-02-1.20674626E-04 3 + 1.23777770E-07-4.56154808E-11-9.67311630E+04 3.47268215E+00-9.56111665E+04 4 +NbO2(II) J12/73NB 1.O 2. 0. 0.C 1090.000 1200.000 124.90518 1 + 1.11714100E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.00205998E+05-5.99819441E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00-9.56111665E+04 4 +NbO2(III) J12/73NB 1.O 2. 0. 0.C 1200.000 2175.000 124.90518 1 + 9.98885082E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-9.87869274E+04-5.15975088E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00-9.56111665E+04 4 +NbO2(L) J12/73NB 1.O 2. 0. 0.C 2175.000 6000.000 124.90518 1 + 1.13223750E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-9.06165758E+04-5.67553462E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00-9.56111665E+04 4 +Nb2O5(s) J12/72NB 2.O 5. 0. 0.C 300.000 1785.000 265.80976 1 + 1.70548920E+01 4.91405580E-03 4.72946440E-07-1.83760710E-09 5.06219220E-13 2 +-2.34230270E+05-8.32247990E+01 8.50534880E+00 3.44012140E-02-3.76987480E-05 3 + 1.98637200E-08-3.96102670E-12-2.32232290E+05-4.06849200E+01-2.28463075E+05 4 +Nb2O5(L) J12/72NB 2.O 5. 0. 0.C 1785.000 5000.000 265.80976 1 + 2.91369870E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-2.37360250E+05-1.59333960E+02 2.91369870E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-2.37360250E+05-1.59333960E+02 0.00000000E+00 4 +Ni(cr) J12/76NI 1. 0. 0. 0.C 200.000 631.000 58.69340 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 3.92097614E+00-2.34184719E-02 1.34230145E-04 3 +-2.75971639E-07 1.98530861E-10-8.62387206E+02-1.56856186E+01 0.00000000E+00 4 +Ni(cr) J12/76NI 1. 0. 0. 0.C 631.000 1728.000 58.69340 1 + 9.58208572E+00-1.78945122E-02 1.97185112E-05-9.11957952E-09 1.58728609E-12 2 +-2.61782185E+03-4.74612393E+01 4.85484877E+02-2.30395380E+00 4.10622634E-03 3 +-3.23350101E-06 9.49617381E-10-8.11709085E+04-2.25428960E+03 0.00000000E+00 4 +Ni(L) J12/76NI 1. 0. 0. 0.C 1728.000 6000.000 58.69340 1 + 4.67989094E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-3.22238346E+02-2.33517797E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4 +NiS(b) J12/76NI 1.S 1. 0. 0.C 300.000 652.000 90.75940 1 + 2.51505130E+00 1.98108790E-02-4.47517130E-05 5.35527360E-08-2.47391510E-11 2 +-1.18972750E+04-1.22988050E+01 2.51505130E+00 1.98108790E-02-4.47517130E-05 3 + 5.35527360E-08-2.47391510E-11-1.18972750E+04-1.22988050E+01-1.05681072E+04 4 +NiS(a) J12/76NI 1.S 1. 0. 0.C 652.000 1249.000 90.75940 1 +-2.16882770E+00 2.04672610E-02-1.52390680E-05 4.52420390E-09 0.00000000E+00 2 +-9.25397310E+03 1.60189760E+01 1.59778550E+00 1.62791590E-02-2.39592640E-05 3 + 1.96652470E-08-5.99935920E-12-1.06051920E+04-4.99884140E+00 0.00000000E+00 4 +NiS(L) J12/76NI 1.S 1. 0. 0.C 1249.000 5000.000 90.75940 1 + 9.23426080E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.10536520E+04-4.57697360E+01 9.23426080E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.10536520E+04-4.57697360E+01 0.00000000E+00 4 +NiS2(s) J 3/77NI 1.S 2. 0. 0.C 300.000 1280.000 122.82540 1 + 5.27426400E+00 9.08709310E-03-5.82010990E-06 1.70500810E-09 0.00000000E+00 2 +-1.75287250E+04-2.33922190E+01 7.74493490E+00 2.53517140E-03-9.97675870E-08 3 + 1.07829500E-10-4.19129410E-14-1.82225390E+04-3.62243880E+01-1.58013948E+04 4 +NiS2(L) J 3/77NI 1.S 2. 0. 0.C 1280.000 5000.000 122.82540 1 + 1.09452410E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.23449250E+04-4.97206240E+01 1.09452410E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.23449250E+04-4.97206240E+01 0.00000000E+00 4 +Ni3S2(I) J12/76NI 3.S 2. 0. 0.C 300.000 829.000 240.21220 1 + 6.92383000E+00 4.04466800E-02-7.30739570E-05 7.10070760E-08-2.62218590E-11 2 +-2.93621960E+04-3.27350520E+01 6.92383000E+00 4.04466800E-02-7.30739570E-05 3 + 7.10070760E-08-2.62218590E-11-2.93621960E+04-3.27350520E+01-2.60177884E+04 4 +Ni3S2(II) J12/76NI 3.S 2. 0. 0.C 829.000 1062.000 240.21220 1 + 2.26855850E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-2.93134790E+04-1.11689780E+02 2.26855850E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-2.93134790E+04-1.11689780E+02 0.00000000E+00 4 +Ni3S2(L) J12/76NI 3.S 2. 0. 0.C 1062.000 5000.000 240.21220 1 + 2.30680390E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-2.73444020E+04-1.12118110E+02 2.30680390E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-2.73444020E+04-1.12118110E+02 0.00000000E+00 4 +Ni3S4(s) J 3/77NI 3.S 4. 0. 0.C 300.000 1100.000 304.34420 1 + 1.46738180E+01 1.72757180E-02 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-4.13600010E+04-6.63291620E+01 1.46711930E+01 1.72771640E-02-2.75692840E-09 3 + 1.02338580E-11-6.29839560E-15-4.13584790E+04-6.63129390E+01-3.62163568E+04 4 +P(cr) TPIS89P 1. 0. 0. 0.C 195.400 317.300 30.97376 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 8.02469681E-01 1.85779347E-02-8.34080748E-05 3 + 2.11104876E-07-2.09658894E-10-6.46362570E+02-2.91281027E+00 0.00000000E+00 4 +P(L) TPIS89P 1. 0. 0. 0.C 317.300 6000.000 30.97376 1 + 3.14149601E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-8.62148564E+02-1.27227472E+01 3.14149601E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-8.62148564E+02-1.27227472E+01 0.00000000E+00 4 +P4O10(s) J12/65P 4.O 10. 0. 0.C 300.000 1500.000 283.88905 1 +-4.33006250E+01 2.15673760E-01-1.76863440E-04 6.76428520E-08-9.91087100E-12 2 +-3.53461393E+05 2.26054720E+02 3.95560990E-01 1.13338170E-01-1.24099820E-04 3 + 9.77156010E-08-3.41078390E-11-3.66256443E+05-3.80906970E+00-3.62020394E+05 4 +Pb(cr) TPIS91PB 1. 0. 0. 0.C 200.000 600.650 207.20000 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 3.36014248E+00-4.31525514E-03 2.10404411E-05 3 +-3.35897357E-08 1.91850988E-11-9.38593007E+02-1.07408687E+01 0.00000000E+00 4 +Pb(L) TPIS91PB 1. 0. 0. 0.C 600.650 3600.000 207.20000 1 + 4.18191355E+00-9.84150979E-04 3.55339809E-07-1.75808349E-11-3.23884419E-15 2 +-7.56065769E+02-1.51099545E+01 3.40679935E+00 2.03221927E-03-4.17417470E-06 3 + 3.08397022E-09-8.16531438E-13-5.92027769E+02-1.13377955E+01 0.00000000E+00 4 +PbBr2(s) J12/73PB 1.BR 2. 0. 0.C 300.000 644.000 367.00800 1 + 1.05575540E+01-7.06173930E-03 1.01876020E-05 1.30528760E-08-1.63730940E-11 2 +-3.63048010E+04-3.91990320E+01 1.05575540E+01-7.06173930E-03 1.01876020E-05 3 + 1.30528760E-08-1.63730940E-11-3.63048010E+04-3.91990320E+01-3.33628636E+04 4 +PbBr2(L) J12/73PB 1.BR 2. 0. 0.C 644.000 5000.000 367.00800 1 + 1.34865490E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-3.65722010E+04-5.70490870E+01 1.34865490E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-3.65722010E+04-5.70490870E+01 0.00000000E+00 4 +PbCL2(s) J 6/73PB 1.CL 2. 0. 0.C 300.000 774.000 278.10540 1 + 8.28026900E+00 3.04143430E-03 1.56025800E-06-2.22846100E-09 1.11154400E-12 2 +-4.58412180E+04-3.17812420E+01 8.28026900E+00 3.04143430E-03 1.56025800E-06 3 +-2.22846100E-09 1.11154400E-12-4.58412180E+04-3.17812420E+01-4.32273685E+04 4 +PbCL2(L) J 6/73PB 1.CL 2. 0. 0.C 774.000 5000.000 278.10540 1 + 1.34110650E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-4.61670770E+04-5.99326540E+01 1.34110650E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-4.61670770E+04-5.99326540E+01 0.00000000E+00 4 +PbF2(a) J12/73PB 1.F 2. 0. 0.C 298.150 583.000 245.19681 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 2.46966471E+01-1.59658886E-01 5.67676318E-04 3 +-8.51030524E-07 4.66841985E-10-8.52413317E+04-9.81573714E+01-8.14204325E+04 4 +PbF2(b) J12/73PB 1.F 2. 0. 0.C 583.000 1103.000 245.19681 1 + 9.93284674E+02-1.87255943E+00 8.90699273E-04 0.00000000E+00 0.00000000E+00 2 +-4.26962008E+05-5.40678897E+03-9.63524957E+02 4.50587453E+00-7.58224107E-03 3 + 5.52315524E-06-1.47183923E-09 7.85231255E+04 4.49531736E+03-8.14204325E+04 4 +PbF2(L) J12/73PB 1.F 2. 0. 0.C 1103.000 6000.000 245.19681 1 + 1.31340648E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-8.47552152E+04-6.20713278E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00-8.14204325E+04 4 +PbI2(s) J12/73PB 1.I 2. 0. 0.C 300.000 683.000 461.00894 1 + 8.44244310E+00 5.91957720E-03-1.38886860E-05 1.32213930E-08 1.61640680E-12 2 +-2.37790490E+04-2.83379000E+01 8.44244310E+00 5.91957720E-03-1.38886860E-05 3 + 1.32213930E-08 1.61640680E-12-2.37790490E+04-2.83379000E+01-2.10946481E+04 4 +PbI2(L) J12/73PB 1.I 2. 0. 0.C 683.000 5000.000 461.00894 1 + 1.30588050E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-2.34409320E+04-5.20448070E+01 1.30588050E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-2.34409320E+04-5.20448070E+01 0.00000000E+00 4 +PbO(rd) J12/71PB 1.O 1. 0. 0.C 300.000 762.000 223.19940 1 + 2.86460100E+00 1.07723720E-02-3.66130960E-06-1.22810870E-08 1.00664350E-11 2 +-2.76701740E+04-1.13045130E+01 2.86460100E+00 1.07723720E-02-3.66130960E-06 3 +-1.22810870E-08 1.00664350E-11-2.76701740E+04-1.13045130E+01-2.63891608E+04 4 +PbO(yw) J12/71PB 1.O 1. 0. 0.C 762.000 1159.000 223.19940 1 + 5.11246260E+00 2.03944890E-03-2.04282280E-07 0.00000000E+00 0.00000000E+00 2 +-2.78546610E+04-2.15059440E+01 4.20732530E+00 5.21764810E-03-3.86135870E-06 3 + 1.38401460E-09 0.00000000E+00-2.76656010E+04-1.70644760E+01 0.00000000E+00 4 +PbO(L) J12/71PB 1.O 1. 0. 0.C 1159.000 5000.000 223.19940 1 + 7.81766980E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-2.66565330E+04-3.57169340E+01 7.81766980E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-2.66565330E+04-3.57169340E+01 0.00000000E+00 4 +PbO2(s) J12/71PB 1.O 2. 0. 0.C 300.000 1200.000 239.19880 1 + 6.86954900E+00 4.68879400E-03-2.02063490E-06 0.00000000E+00 0.00000000E+00 2 +-3.53187500E+04-3.20013720E+01 2.34297850E+00 2.66129100E-02-4.12126330E-05 3 + 3.07232400E-08-8.92878750E-12-3.45852910E+04-1.10699310E+01-3.30114828E+04 4 +PbS(s) J 6/73PB 1.S 1. 0. 0.C 300.000 1386.500 239.26600 1 + 4.86954080E+00 2.55098480E-03-3.80428790E-07-5.48146380E-10 2.65738190E-13 2 +-1.32984520E+04-1.72996060E+01 5.51609700E+00 1.71966880E-03-1.26586040E-06 3 + 1.25056850E-09-4.62785080E-13-1.35381800E+04-2.09092670E+01-1.18260529E+04 4 +PbS(L) J 6/73PB 1.S 1. 0. 0.C 1386.500 5000.000 239.26600 1 + 8.05167150E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.35660600E+04-3.57577960E+01 8.05167150E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.35660600E+04-3.57577960E+01 0.00000000E+00 4 +Pb3O4(s) J12/71PB 3.O 4. 0. 0.C 300.000 5000.000 685.59760 1 + 1.99272030E+01 5.03362330E-03-8.34392170E-10 2.07608990E-13-1.77708800E-17 2 +-9.28767870E+04-9.02884070E+01 2.47093570E+00 8.98670090E-02-1.52313110E-04 3 + 1.19885000E-07-3.49496520E-11-9.00477260E+04-9.60622350E+00-8.64419716E+04 4 +S(cr1) TPIS89S 1. 0. 0. 0.C 200.000 368.300 32.06600 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 3.71369512E-01 1.53373501E-02-3.35441107E-05 3 + 2.89249500E-08 0.00000000E+00-5.53213850E+02-1.59624498E+00 0.00000000E+00 4 +S(cr2) TPIS89S 1. 0. 0. 0.C 368.300 388.360 32.06600 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 2.08033146E+00 2.44137554E-03 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-6.85306695E+02-8.60715487E+00 0.00000000E+00 4 +S(L) TPIS89S 1. 0. 0. 0.C 388.360 6000.000 32.06600 1 + 3.50078410E+00 3.81662100E-04-1.55569962E-07 2.72783689E-11-1.72812554E-15 2 +-5.90873035E+02-1.52167270E+01-7.27405684E+01 4.81222534E-01-1.07842233E-03 3 + 1.03257728E-06-3.58884490E-10 8.29134856E+03 3.15269743E+02 0.00000000E+00 4 +SCL2(L) J 6/78S 1.CL 2. 0. 0.C 300.000 5000.000 102.97140 1 + 1.09452410E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-9.25175430E+03-4.02697950E+01 1.09452410E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-9.25175430E+03-4.02697950E+01-5.98843070E+03 4 +S2CL2(L) J 6/78S 2.CL 2. 0. 0.C 300.000 5000.000 135.03740 1 + 1.49489350E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.14519150E+04-5.82502250E+01 1.49489350E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.14519150E+04-5.82502250E+01-6.99489003E+03 4 +Si(cr) TPIS91SI 1. 0. 0. 0.C 200.000 1690.000 28.08550 1 + 1.75547382E+00 3.17285497E-03-2.78236402E-06 1.26458065E-09-2.17128464E-13 2 +-6.28657363E+02-8.55341177E+00-1.29176912E-01 1.47203139E-02-2.76510160E-05 3 + 2.41878251E-08-7.93452912E-12-4.15516417E+02-3.59570008E-01 0.00000000E+00 4 +Si(L) TPIS91SI 1. 0. 0. 0.C 1690.000 6000.000 28.08550 1 + 3.27138941E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 4.88286795E+03-1.32665477E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4 +SiC(b) J 3/67SI 1.C 1. 0. 0.C 300.000 4000.000 40.09650 1 + 3.79748090E+00 3.18728860E-03-1.45023340E-06 3.15497440E-10-2.61589910E-14 2 +-1.02919370E+04-2.10677910E+01-2.47159070E+00 3.06937830E-02-4.92630850E-05 3 + 3.86263890E-08-1.17616210E-11-9.06912600E+03 8.80092140E+00-8.80624423E+03 4 +SiO2(Lqz) J 6/67SI 1.O 2. 0. 0.C 200.000 847.000 60.08430 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00-7.58511380E-01 3.05773989E-02-4.00861855E-05 3 + 2.16194849E-08-6.17249042E-13-1.10371483E+05 1.78384529E+00-1.09550292E+05 4 +SiO2(hqz) J 6/67SI 1.O 2. 0. 0.C 847.000 1696.000 60.08430 1 + 7.23537106E+00 7.61842227E-04 4.89502294E-07-2.35754591E-10 4.20839131E-14 2 +-1.11823834E+05-3.69642796E+01 7.11787621E+00 1.13819527E-03 3.69734234E-08 3 + 0.00000000E+00 0.00000000E+00-1.11794194E+05-3.63708064E+01-1.09550292E+05 4 +SiO2(L) J 6/67SI 1.O 2. 0. 0.C 1696.000 6000.000 60.08430 1 + 1.03160657E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.14600563E+05-5.76266603E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00-1.09550292E+05 4 +Si2N2O(s) L 1/84SI 2.N 2.O 1. 0.C 298.150 2500.000 100.18388 1 + 1.18490230E+01 2.42446810E-03 3.65292350E-07-4.25788290E-10 8.62759300E-14 2 +-1.18214940E+05-6.42500920E+01-4.12268540E+00 5.41728140E-02-4.23929300E-05 3 +-1.07245950E-08 1.73668580E-11-1.14746000E+05 1.48221580E+01-1.13982840E+05 4 +Si3N4(a) J 3/67SI 3.N 4. 0. 0.C 300.000 3000.000 140.28346 1 + 2.79817450E+00 2.79750180E-02-1.50205780E-05 3.58722880E-09-3.17769690E-13 2 +-9.10172410E+04-8.92688190E+00 7.16356800E+00 1.90071110E-02-1.14693330E-05 3 + 7.06659150E-09-2.74586400E-12-9.24666510E+04-3.24424310E+01-8.95746895E+04 4 +Sr(a) SRD 93SR 1. 0. 0. 0.C 298.150 820.000 87.62000 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 2.61121855E+00 3.06923896E-03-4.43980854E-06 3 + 4.03524789E-09-1.48087835E-12-8.83002675E+02-9.01331093E+00 0.00000000E+00 4 +Sr(b) SRD 93SR 1. 0. 0. 0.C 820.000 1041.000 87.62000 1 + 3.19032631E+00 4.83732655E-04 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-8.56080629E+02-1.15723466E+01 3.19032631E+00 4.83732655E-04 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-8.56080629E+02-1.15723466E+01 0.00000000E+00 4 +Sr(L) SRD 93SR 1. 0. 0. 0.C 1041.000 6000.000 87.62000 1 + 4.45005178E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-9.43175540E+02-1.88969962E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4 +SrCL2(a) J12/72SR 1.CL 2. 0. 0.C 300.000 1000.000 158.52540 1 + 6.93696350E+00 1.07876000E-02-1.39079400E-05 5.89822760E-09 3.01333260E-12 2 +-1.02127190E+05-2.83708820E+01 6.93696350E+00 1.07876000E-02-1.39079400E-05 3 + 5.89822760E-09 3.01333260E-12-1.02127190E+05-2.83708820E+01-9.96892591E+04 4 +SrCL2(b) J12/72SR 1.CL 2. 0. 0.C 1000.000 1147.000 158.52540 1 + 1.47949470E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.06427500E+05-7.53762280E+01 1.47949470E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.06427500E+05-7.53762280E+01 0.00000000E+00 4 +SrCL2(L) J12/72SR 1.CL 2. 0. 0.C 1147.000 5000.000 158.52540 1 + 1.25807370E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.01936770E+05-5.80763530E+01 1.25807370E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.01936770E+05-5.80763530E+01 0.00000000E+00 4 +SrF2(s) J12/72SR 1.F 2. 0. 0.C 300.000 1750.000 125.61681 1 + 8.87471680E+01-1.63765080E-01 6.51968990E-05 4.35483950E-08-2.36734740E-11 2 +-1.74561220E+05-4.69345230E+02 5.29162130E+00 1.55376550E-02-1.92119080E-05 3 + 7.49652320E-09 9.40005730E-13-1.48530500E+05-2.40891530E+01-1.46416681E+05 4 +SrF2(L) J12/72SR 1.F 2. 0. 0.C 1750.000 5000.000 125.61681 1 + 1.19129510E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.46428080E+05-5.80228420E+01 1.19129510E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.46428080E+05-5.80228420E+01 0.00000000E+00 4 +SrO(s) J12/72SR 1.O 1. 0. 0.C 300.000 2938.000 103.61940 1 + 5.64779350E+00 1.31539990E-03-2.76404120E-07 6.73083310E-11-6.56263530E-15 2 +-7.30373440E+04-2.60983600E+01 3.56313720E+00 9.27178460E-03-1.16465790E-05 3 + 7.08518320E-09-1.52599060E-12-7.25914040E+04-1.59287960E+01-7.12065685E+04 4 +SrO(L) J12/72SR 1.O 1. 0. 0.C 2938.000 5000.000 103.61940 1 + 8.05167150E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-6.67347690E+04-3.90929440E+01 8.05167150E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-6.67347690E+04-3.90929440E+01 0.00000000E+00 4 +SrO2H2(s) J12/75SR 1.O 2.H 2. 0.C 300.000 783.150 121.63468 1 + 4.17069560E+00 1.65037010E-02-1.30297450E-06 1.39718190E-09-5.39489420E-13 2 +-1.18500560E+05-1.69628130E+01 4.17069560E+00 1.65037010E-02-1.30297450E-06 3 + 1.39718190E-09-5.39489420E-13-1.18500560E+05-1.69628130E+01-1.16532537E+05 4 +SrO2H2(L) J12/75SR 1.O 2.H 2. 0.C 783.150 5000.000 121.63468 1 + 1.89717510E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.22611740E+05-9.96605010E+01 1.89717510E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.22611740E+05-9.96605010E+01 0.00000000E+00 4 +SrS(s) J 9/77SR 1.S 1. 0. 0.C 300.000 3000.000 119.68600 1 + 5.94054630E+00 1.04473280E-03-3.07943920E-07 9.71985450E-11-1.11296850E-14 2 +-5.82547290E+04-2.60999610E+01 5.74442320E+00-2.03636100E-03 1.19833400E-05 3 +-1.48896430E-08 5.96164430E-12-5.80629980E+04-2.43073180E+01-5.63615462E+04 4 +Ta(cr) J12/72TA 1. 0. 0. 0.C 200.000 3258.000 180.94790 1 + 2.89594963E+00 5.33759133E-04-3.59144721E-08-7.20761461E-11 3.13302008E-14 2 +-8.71255826E+02-1.16440280E+01 2.32998499E+00 4.45028402E-03-9.52242819E-06 3 + 9.87829159E-09-3.78308406E-12-8.26091467E+02-9.27093646E+00 0.00000000E+00 4 +Ta(L) J12/72TA 1. 0. 0. 0.C 3258.000 6000.000 180.94790 1 + 5.03216666E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-7.44223758E+02-2.59736577E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4 +TaC(s) J12/73TA 1.C 1. 0. 0.C 300.000 4273.000 192.95890 1 + 5.00270560E+00 1.28490410E-03-1.74959390E-07 3.52455810E-11-2.64292600E-15 2 +-1.90205530E+04-2.41296910E+01 1.02497170E+00 1.76286200E-02-2.55158590E-05 3 + 1.73133080E-08-4.30578580E-12-1.82265970E+04-5.00931270E+00-1.73307143E+04 4 +TaC(L) J12/73TA 1.C 1. 0. 0.C 4273.000 5000.000 192.95890 1 + 8.05167150E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.01033380E+04-4.20855450E+01 8.05167150E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.01033380E+04-4.20855450E+01 0.00000000E+00 4 +Ta2O5(s) J12/72TA 2.O 5. 0. 0.C 300.000 2058.000 441.89280 1 + 1.84736840E+01 3.49024330E-03 9.11565840E-07-1.15082870E-09 2.47020600E-13 2 +-2.52459110E+05-9.07334910E+01 1.01199420E+01 2.55375590E-02-1.68473510E-05 3 + 3.47340780E-11 3.12680110E-12-2.50081740E+05-4.73108770E+01-2.46076715E+05 4 +Ta2O5(L) J12/72TA 2.O 5. 0. 0.C 2058.000 5000.000 441.89280 1 + 2.91873090E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-2.53362450E+05-1.58577740E+02 2.91873090E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-2.53362450E+05-1.58577740E+02 0.00000000E+00 4 +Ti(a) CODA89TI 1. 0. 0. 0.C 200.000 1156.000 47.88000 1 + 2.97987171E+01-5.67369024E-02 3.08487350E-05 0.00000000E+00 0.00000000E+00 2 +-9.27557025E+03-1.56730793E+02 1.32829640E+00 1.04776117E-02-2.19816539E-05 3 + 2.17468998E-08-7.66060428E-12-7.06881044E+02-6.19722912E+00 0.00000000E+00 4 +Ti(b) CODA89TI 1. 0. 0. 0.C 1156.000 1944.000 47.88000 1 + 4.55050938E+00-5.78446834E-03 6.58428776E-06-2.60523484E-09 4.06930218E-13 2 +-1.86695724E+02-1.97953040E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4 +Ti(L) CODA89TI 1. 0. 0. 0.C 1944.000 6000.000 47.88000 1 + 5.62871414E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-2.37509598E+03-3.07872691E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4 +TiC(s) J 6/68TI 1.C 1. 0. 0.C 300.000 3290.000 59.89100 1 + 5.94139360E+00-3.72799670E-04 7.12099530E-07-1.35170900E-10 9.98036600E-15 2 +-2.41734450E+04-3.15302220E+01-1.36339420E+00 2.82522370E-02-4.11752110E-05 3 + 2.67888580E-08-6.34698680E-12-2.26783520E+04 3.86264830E+00-2.21429614E+04 4 +TiC(L) J 6/68TI 1.C 1. 0. 0.C 3290.000 5000.000 59.89100 1 + 7.54844210E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.76602040E+04-4.06296610E+01 7.54844210E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.76602040E+04-4.06296610E+01 0.00000000E+00 4 +TiCL2(s) J12/68TI 1.CL 2. 0. 0.C 300.000 2000.000 118.78540 1 + 7.96841470E+00 2.54479250E-03-2.86481190E-07 1.31878060E-10-2.22708260E-14 2 +-6.45084420E+04-3.57130890E+01 5.75675180E+00 1.36310330E-02-2.04162290E-05 3 + 1.59098880E-08-4.54511040E-12-6.41699180E+04-2.55854560E+01-6.19987670E+04 4 +TiCL3(s) J 6/68TI 1.CL 3. 0. 0.C 300.000 5000.000 154.23810 1 + 1.14626580E+01 1.40178060E-03-3.06897240E-08 1.23390070E-13-1.05612980E-17 2 +-9.03169600E+04-4.89930780E+01 1.09379360E+01 2.66227360E-03-1.47859230E-07 3 +-1.54067680E-09 9.22187740E-13-9.01826680E+04-4.62872870E+01-8.68071084E+04 4 +TiCL4(L) J12/67TI 1.CL 4. 0. 0.C 300.000 5000.000 189.69080 1 + 1.71426430E+01 1.09370870E-03-1.06903110E-09 2.66167570E-13-2.27944800E-17 2 +-1.01880270E+05-6.76401420E+01 1.70660420E+01 1.57771680E-03-1.08703760E-06 3 + 1.03903030E-09-3.60225300E-13-1.01871340E+05-6.73082280E+01-9.67206958E+04 4 +TiN(s) J 6/68TI 1.N 1. 0. 0.C 300.000 3220.000 61.88674 1 + 5.60100510E+00 3.56459390E-04 3.95218030E-07-8.87180020E-11 7.78445130E-15 2 +-4.24434300E+04-2.87732930E+01-2.53201190E+00 4.11748560E-02-7.70557760E-05 3 + 6.52898690E-08-2.06051870E-11-4.11246660E+04 8.67507960E+00-4.06109779E+04 4 +TiN(L) J 6/68TI 1.N 1. 0. 0.C 3220.000 5000.000 61.88674 1 + 7.54844210E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-3.62617090E+04-3.95839060E+01 7.54844210E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-3.62617090E+04-3.95839060E+01 0.00000000E+00 4 +TiO(a) J12/73TI 1.O 1. 0. 0.C 300.000 1265.000 63.87940 1 + 2.65167850E+00 7.99632030E-03-4.95528280E-06 1.41288420E-09 0.00000000E+00 2 +-6.62883610E+04-1.29187030E+01 8.98095640E-01 2.13543830E-02-3.58428730E-05 3 + 3.04081570E-08-9.71216350E-12-6.62243320E+04-5.95670040E+00-6.52685922E+04 4 +TiO(b) J12/73TI 1.O 1. 0. 0.C 1265.000 2023.000 63.87940 1 + 1.79714190E+00 1.01288630E-02-7.45855710E-06 3.08358150E-09-4.75617470E-13 2 +-6.54827730E+04-7.93491750E+00 1.79714190E+00 1.01288630E-02-7.45855710E-06 3 + 3.08358150E-09-4.75617470E-13-6.54827730E+04-7.93491750E+00 0.00000000E+00 4 +TiO(L) J12/73TI 1.O 1. 0. 0.C 2023.000 5000.000 63.87940 1 + 8.05167150E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-6.32721380E+04-4.13121090E+01 8.05167150E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-6.32721380E+04-4.13121090E+01 0.00000000E+00 4 +TiO2(ru) J12/73TI 1.O 2. 0. 0.C 300.000 2130.000 79.87880 1 + 6.84891510E+00 4.24634610E-03-3.00889840E-06 1.06025190E-09-1.43795970E-13 2 +-1.15992460E+05-3.45141060E+01-1.61175170E-01 3.79666600E-02-6.51547500E-05 3 + 5.25521360E-08-1.62000510E-11-1.14788970E+05-1.88740350E+00-1.13628959E+05 4 +TiO2(L) J12/73TI 1.O 2. 0. 0.C 2130.000 5000.000 79.87880 1 + 1.20775070E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.14942300E+05-6.59107590E+01 1.20775070E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.14942300E+05-6.59107590E+01 0.00000000E+00 4 +Ti2O3(a) J 6/73TI 2.O 3. 0. 0.C 300.000 470.000 143.75820 1 + 1.46235420E+01-3.71617170E-02 9.00264700E-05 0.00000000E+00 0.00000000E+00 2 +-1.86416930E+05-6.69148990E+01 1.46235420E+01-3.71617170E-02 9.00264700E-05 3 + 0.00000000E+00 0.00000000E+00-1.86416930E+05-6.69148990E+01-1.82913296E+05 4 +Ti2O3(b) J 6/73TI 2.O 3. 0. 0.C 470.000 2115.000 143.75820 1 + 1.48742220E+01 4.54656950E-03-2.36463630E-06 5.99603920E-10-5.34142600E-14 2 +-1.87973420E+05-7.78631650E+01 1.69774850E+00 5.71374340E-02-8.33206810E-05 3 + 5.72995280E-08-1.52116850E-11-1.85250360E+05-1.40665590E+01 0.00000000E+00 4 +Ti2O3(L) J 6/73TI 2.O 3. 0. 0.C 2115.000 5000.000 143.75820 1 + 1.88711050E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.78586980E+05-9.65672570E+01 1.88711050E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.78586980E+05-9.65672570E+01 0.00000000E+00 4 +Ti3O5(a) J12/73TI 3.O 5. 0. 0.C 300.000 450.000 223.63700 1 +-3.73374340E+00 1.06193190E-01-1.04723810E-04 0.00000000E+00 0.00000000E+00 2 +-2.98456170E+05 9.82410160E+00-3.73374340E+00 1.06193190E-01-1.04723810E-04 3 + 0.00000000E+00 0.00000000E+00-2.98456170E+05 9.82410160E+00-2.95774633E+05 4 +Ti3O5(b) J12/73TI 3.O 5. 0. 0.C 450.000 2050.000 223.63700 1 + 1.84151590E+01 8.00131020E-03-1.99070560E-06 8.78123970E-10-1.42452750E-13 2 +-2.99986840E+05-8.81354790E+01 1.86928170E+01 8.50510620E-03-5.12462080E-06 3 + 4.61198750E-09-1.52385570E-12-3.00128950E+05-8.98895860E+01 0.00000000E+00 4 +Ti3O5(L) J12/73TI 3.O 5. 0. 0.C 2050.000 5000.000 223.63700 1 + 3.22066860E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-2.93685410E+05-1.69127030E+02 3.22066860E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-2.93685410E+05-1.69127030E+02 0.00000000E+00 4 +Ti4O7(s) J12/73TI 4.O 7. 0. 0.C 300.000 1950.000 303.51580 1 + 2.41129150E+01 2.29277140E-02-1.71191630E-05 6.48492060E-09-9.48838110E-13 2 +-4.18107160E+05-1.21046500E+02-8.63335600E-01 1.41604620E-01-2.32423050E-04 3 + 1.81940730E-07-5.48014130E-11-4.13794840E+05-4.56375800E+00-4.09478128E+05 4 +Ti4O7(L) J12/73TI 4.O 7. 0. 0.C 1950.000 5000.000 303.51580 1 + 4.42841940E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-4.10896730E+05-2.35160430E+02 4.42841940E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-4.10896730E+05-2.35160430E+02 0.00000000E+00 4 +V(cr) J 6/73V 1. 0. 0. 0.C 200.000 2190.000 50.94150 1 + 4.48215589E+00-4.25728053E-03 5.38325211E-06-2.42044016E-09 4.23981192E-13 2 +-1.28420195E+03-2.12401625E+01 8.64273023E-01 1.40301270E-02-3.15228495E-05 3 + 3.16728638E-08-1.14327459E-11-6.59969586E+02-4.48332268E+00 0.00000000E+00 4 +V(L) J 6/73V 1. 0. 0. 0.C 2190.000 6000.000 50.94150 1 + 5.55703222E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.89958163E+03-3.07034308E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4 +VCL2(s) L 2/76V 1.CL 2. 0. 0.C 300.000 1300.000 121.84690 1 + 6.27112160E+00 7.48900460E-03-5.25310000E-06 1.50673690E-09 0.00000000E+00 2 +-5.63580560E+04-2.57265380E+01 6.73955990E+00 1.04872230E-02-1.72267800E-05 3 + 1.47688310E-08-4.75507060E-12-5.66988860E+04-2.92057040E+01-5.43486187E+04 4 +VCL3(s) L 2/76V 1.CL 3. 0. 0.C 300.000 1000.000 157.29960 1 + 6.97704130E+00 2.35420110E-02-4.07452720E-05 3.49284830E-08-1.12449000E-11 2 +-7.26781690E+04-2.94937120E+01 6.97704130E+00 2.35420110E-02-4.07452720E-05 3 + 3.49284830E-08-1.12449000E-11-7.26781690E+04-2.94937120E+01-6.98478613E+04 4 +VCL4(L) L 2/76V 1.CL 4. 0. 0.C 300.000 2000.000 192.75230 1 + 1.74620630E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-7.36958450E+04-6.87947920E+01 1.74620630E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-7.36958450E+04-6.87947920E+01-6.84895309E+04 4 +VN(s) J12/73V 1.N 1. 0. 0.C 300.000 3500.000 64.94824 1 + 4.83687400E+00 1.89001470E-03-3.16104630E-07 4.60506600E-11-1.91020370E-15 2 +-2.77381520E+04-2.38733530E+01 8.12713570E-01 2.01010430E-02-3.11780040E-05 3 + 2.31036890E-08-6.38451440E-12-2.70200940E+04-4.94574360E+00-2.61171678E+04 4 +VO(s) J12/73V 1.O 1. 0. 0.C 300.000 2063.000 66.94090 1 + 5.33987150E+00 1.75917030E-03 3.84776170E-07-2.61824710E-10 5.10093950E-14 2 +-5.36513790E+04-2.63823640E+01 2.53804010E+00 1.64470780E-02-2.85598100E-05 3 + 2.48363920E-08-7.98869480E-12-5.32119190E+04-1.35997580E+01-5.19311959E+04 4 +VO(L) J12/73V 1.O 1. 0. 0.C 2063.000 5000.000 66.94090 1 + 7.54844210E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-4.76004740E+04-3.61542130E+01 7.54844210E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-4.76004740E+04-3.61542130E+01 0.00000000E+00 4 +V2O3(s) J12/73V 2.O 3. 0. 0.C 300.000 2340.000 149.88120 1 + 1.39642110E+01 1.68712980E-03 1.13712060E-06-2.08060070E-10 1.00283250E-14 2 +-1.51005750E+05-6.87828940E+01 2.28770330E+00 5.76327630E-02-9.67385560E-05 3 + 7.40669160E-08-2.06583890E-11-1.49111890E+05-1.47234460E+01-1.46586278E+05 4 +V2O3(L) J12/73V 2.O 3. 0. 0.C 2340.000 5000.000 149.88120 1 + 1.88711050E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.40340630E+05-9.45809200E+01 1.88711050E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.40340630E+05-9.45809200E+01 0.00000000E+00 4 +V2O4(I) J 6/73V 2.O 4. 0. 0.C 300.000 340.000 165.88060 1 + 6.89145420E+00 9.91420220E-03 5.78371010E-05 4.30539190E-08-2.84826940E-10 2 +-1.74608640E+05-3.21573580E+01 6.89145420E+00 9.91420220E-03 5.78371010E-05 3 + 4.30539190E-08-2.84826940E-10-1.74608640E+05-3.21573580E+01-1.71651493E+05 4 +V2O4(II) J 6/73V 2.O 4. 0. 0.C 340.000 1818.000 165.88060 1 + 1.66102560E+01 2.33294190E-03 9.89047860E-07-7.50324960E-10 1.61354610E-13 2 +-1.76073890E+05-8.08319970E+01 4.90036240E+00 5.00269520E-02-7.13163320E-05 3 + 4.65155670E-08-1.07832680E-11-1.73736760E+05-2.45033750E+01 0.00000000E+00 4 +V2O4(L) J 6/73V 2.O 4. 0. 0.C 1818.000 5000.000 165.88060 1 + 2.56647030E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.74630090E+05-1.36559400E+02 2.56647030E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.74630090E+05-1.36559400E+02 0.00000000E+00 4 +V2O5(s) J 6/73V 2.O 5. 0. 0.C 300.000 943.000 181.88000 1 +-1.16403600E+00 9.35358840E-02-1.56750970E-04 1.22235240E-07-3.57388450E-11 2 +-1.89145310E+05 4.07227530E-01-1.16403600E+00 9.35358840E-02-1.56750970E-04 3 + 1.22235240E-07-3.57388450E-11-1.89145310E+05 4.07227530E-01-1.86495188E+05 4 +V2O5(L) J 6/73V 2.O 5. 0. 0.C 943.000 5000.000 181.88000 1 + 2.29472640E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.87514470E+05-1.10892770E+02 2.29472640E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.87514470E+05-1.10892770E+02 0.00000000E+00 4 +Zn(cr) CODA89ZN 1. 0. 0. 0.C 200.000 692.730 65.39000 1 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 + 0.00000000E+00 0.00000000E+00 1.85068929E+00 9.17791410E-03-2.61047009E-05 3 + 3.38568767E-08-1.39430709E-11-7.89403133E+02-7.38526333E+00 0.00000000E+00 4 +Zn(L) CODA89ZN 1. 0. 0. 0.C 692.730 6000.000 65.39000 1 + 3.77653043E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-4.31695298E+02-1.56708437E+01 3.77653043E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-4.31695298E+02-1.56708437E+01 0.00000000E+00 4 +ZnSO4(a) J 3/79ZN 1.S 1.O 4. 0.C 300.000 540.000 161.45360 1 + 5.16573640E+00 2.39773940E-02-3.07007440E-06-4.84501640E-09 0.00000000E+00 2 +-1.20453590E+05-2.31053690E+01 5.16573640E+00 2.39773940E-02-3.07007440E-06 3 +-4.84501640E-09 0.00000000E+00-1.20453590E+05-2.31053690E+01-1.17884403E+05 4 +ZnSO4(a) J 3/79ZN 1.S 1.O 4. 0.C 540.000 1013.000 161.45360 1 + 1.58952590E+01 1.18409420E-03 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.22604330E+05-7.79153220E+01 1.55534950E+01 2.77373190E-03-3.80347210E-06 3 + 4.08455430E-09-1.52895620E-12-1.22504900E+05-7.62216840E+01 0.00000000E+00 4 +ZnSO4(b) J 3/79ZN 1.S 1.O 4. 0.C 1013.000 5000.000 161.45360 1 + 1.74618250E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.21138060E+05-8.51432530E+01 1.74618250E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.21138060E+05-8.51432530E+01 0.00000000E+00 4 +Zr(a) J 6/79ZR 1. 0. 0. 0.C 200.000 1135.000 91.22400 1 + 2.28119546E+00 1.46971684E-03-1.04657616E-08 0.00000000E+00 0.00000000E+00 2 +-6.61803147E+02-8.57377198E+00 2.18288840E+00 5.42886393E-03-1.21463952E-05 3 + 1.31132729E-08-4.83818355E-12-8.08441355E+02-8.94741836E+00 0.00000000E+00 4 +Zr(b) J 6/79ZR 1. 0. 0. 0.C 1135.000 2125.000 91.22400 1 + 4.06876245E+00-1.58489721E-03 1.02995129E-06-1.55767557E-10 2.30284611E-14 2 +-6.91172261E+02-1.78593403E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4 +Zr(L) J 6/79ZR 1. 0. 0. 0.C 2125.000 6000.000 91.22400 1 + 5.03216666E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.10084626E+03-2.54797587E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 4 +ZrN(s) J 6/61ZR 1.N 1. 0. 0.C 300.000 3225.000 105.23074 1 + 5.54078200E+00 6.18393530E-04 2.95421100E-07-1.17843110E-10 1.52414300E-14 2 +-4.57513240E+04-2.74206540E+01 2.85562900E+00 8.61669700E-03-5.34866380E-06 3 +-2.88042190E-09 3.10878490E-12-4.51120200E+04-1.39010690E+01-4.39291087E+04 4 +ZrN(L) J 6/61ZR 1.N 1. 0. 0.C 3225.000 5000.000 105.23074 1 + 7.04511640E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-3.81055270E+04-3.44362640E+01 7.04511640E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-3.81055270E+04-3.44362640E+01 0.00000000E+00 4 +ZrO2(a) J12/65ZR 1.O 2. 0. 0.C 300.000 1478.000 123.22280 1 +-2.21443950E+01 9.96397630E-02-1.20066880E-04 6.46867360E-08-1.30048810E-11 2 +-1.27327970E+05 1.11008910E+02-7.95371060E-01 4.39334580E-02-8.12144440E-05 3 + 6.95676480E-08-2.23809470E-11-1.33119670E+05 5.32210090E-01-1.31994717E+05 4 +ZrO2(b) J12/65ZR 1.O 2. 0. 0.C 1478.000 2950.000 123.22280 1 + 8.95736290E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.34143540E+05-4.52740170E+01 8.95736290E+00 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.34143540E+05-4.52740170E+01 0.00000000E+00 4 +ZrO2(L) J12/65ZR 1.O 2. 0. 0.C 2950.000 5000.000 123.22280 1 + 1.05676750E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-1.28427450E+05-5.45922640E+01 1.05676750E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-1.28427450E+05-5.45922640E+01 0.00000000E+00 4 +END \ No newline at end of file diff --git a/data/transport/gri30_tran.dat b/data/transport/gri30_tran.dat new file mode 100755 index 000000000..c79ad37bd --- /dev/null +++ b/data/transport/gri30_tran.dat @@ -0,0 +1,110 @@ +AR 0 136.500 3.330 0.000 0.000 0.000 +C 0 71.400 3.298 0.000 0.000 0.000 ! * +C2 1 97.530 3.621 0.000 1.760 4.000 +C2O 1 232.400 3.828 0.000 0.000 1.000 ! * +CN2 1 232.400 3.828 0.000 0.000 1.000 ! OIS +C2H 1 209.000 4.100 0.000 0.000 2.500 +C2H2 1 209.000 4.100 0.000 0.000 2.500 +C2H2OH 2 224.700 4.162 0.000 0.000 1.000 ! * +C2H3 2 209.000 4.100 0.000 0.000 1.000 ! * +C2H4 2 280.800 3.971 0.000 0.000 1.500 +C2H5 2 252.300 4.302 0.000 0.000 1.500 +C2H6 2 252.300 4.302 0.000 0.000 1.500 +C2N 1 232.400 3.828 0.000 0.000 1.000 ! OIS +C2N2 1 349.000 4.361 0.000 0.000 1.000 ! OIS +C3H2 2 209.000 4.100 0.000 0.000 1.000 ! * +C3H4 1 252.000 4.760 0.000 0.000 1.000 +C3H6 2 266.800 4.982 0.000 0.000 1.000 +C3H7 2 266.800 4.982 0.000 0.000 1.000 +C4H6 2 357.000 5.180 0.000 0.000 1.000 +I*C3H7 2 266.800 4.982 0.000 0.000 1.000 +N*C3H7 2 266.800 4.982 0.000 0.000 1.000 +C3H8 2 266.800 4.982 0.000 0.000 1.000 +C4H 1 357.000 5.180 0.000 0.000 1.000 +C4H2 1 357.000 5.180 0.000 0.000 1.000 +C4H2OH 2 224.700 4.162 0.000 0.000 1.000 ! * +C4H8 2 357.000 5.176 0.000 0.000 1.000 +C4H9 2 357.000 5.176 0.000 0.000 1.000 +I*C4H9 2 357.000 5.176 0.000 0.000 1.000 +C5H2 1 357.000 5.180 0.000 0.000 1.000 +C5H3 1 357.000 5.180 0.000 0.000 1.000 +C6H2 1 357.000 5.180 0.000 0.000 1.000 +C6H5 2 412.300 5.349 0.000 0.000 1.000 ! JAM +C6H5O 2 450.000 5.500 0.000 0.000 1.000 ! JAM +C5H5OH 2 450.000 5.500 0.000 0.000 1.000 ! JAM +C6H6 2 412.300 5.349 0.000 0.000 1.000 ! SVE +C6H7 2 412.300 5.349 0.000 0.000 1.000 ! JAM +CH 1 80.000 2.750 0.000 0.000 0.000 +CH2 1 144.000 3.800 0.000 0.000 0.000 +CH2(S) 1 144.000 3.800 0.000 0.000 0.000 +CH2* 1 144.000 3.800 0.000 0.000 0.000 +CH2CHCCH 2 357.000 5.180 0.000 0.000 1.000 ! JAM +CH2CHCCH2 2 357.000 5.180 0.000 0.000 1.000 ! JAM +CH2CHCH2 2 260.000 4.850 0.000 0.000 1.000 ! JAM +CH2CHCHCH 2 357.000 5.180 0.000 0.000 1.000 ! JAM +CH2CHCHCH2 2 357.000 5.180 0.000 0.000 1.000 ! JAM +CH2CO 2 436.000 3.970 0.000 0.000 2.000 +CH2O 2 498.000 3.590 0.000 0.000 2.000 +CH2OH 2 417.000 3.690 1.700 0.000 2.000 +CH3 1 144.000 3.800 0.000 0.000 0.000 +CH3CC 2 252.000 4.760 0.000 0.000 1.000 ! JAM +CH3CCCH2 2 357.000 5.180 0.000 0.000 1.000 ! JAM +CH3CCCH3 2 357.000 5.180 0.000 0.000 1.000 ! JAM +CH3CCH2 2 260.000 4.850 0.000 0.000 1.000 ! JAM +CH3CHCH 2 260.000 4.850 0.000 0.000 1.000 ! JAM +CH3CH2CCH 2 357.000 5.180 0.000 0.000 1.000 ! JAM +CH3CHO 2 436.000 3.970 0.000 0.000 2.000 +CH2CHO 2 436.000 3.970 0.000 0.000 2.000 +CH3CO 2 436.000 3.970 0.000 0.000 2.000 +CH3O 2 417.000 3.690 1.700 0.000 2.000 +CH3OH 2 481.800 3.626 0.000 0.000 1.000 ! SVE +CH4 2 141.400 3.746 0.000 2.600 13.000 +CH4O 2 417.000 3.690 1.700 0.000 2.000 +CN 1 75.000 3.856 0.000 0.000 1.000 ! OIS +CNC 1 232.400 3.828 0.000 0.000 1.000 ! OIS +CNN 1 232.400 3.828 0.000 0.000 1.000 ! OIS +CO 1 98.100 3.650 0.000 1.950 1.800 +CO2 1 244.000 3.763 0.000 2.650 2.100 +H 0 145.000 2.050 0.000 0.000 0.000 +H2C4O 2 357.000 5.180 0.000 0.000 1.000 ! JAM +H2 1 38.000 2.920 0.000 0.790 280.000 +H2CCCCH 2 357.000 5.180 0.000 0.000 1.000 ! JAM +H2CCCCH2 2 357.000 5.180 0.000 0.000 1.000 ! JAM +H2CCCH 2 252.000 4.760 0.000 0.000 1.000 ! JAM +H2CN 1 569.000 3.630 0.000 0.000 1.000 ! os/jm +H2NO 2 116.700 3.492 0.000 0.000 1.000 ! JAM +H2O 2 572.400 2.605 1.844 0.000 4.000 +H2O2 2 107.400 3.458 0.000 0.000 3.800 +HC2N2 1 349.000 4.361 0.000 0.000 1.000 ! OIS +HCCHCCH 2 357.000 5.180 0.000 0.000 1.000 ! JAM +HCCO 2 150.000 2.500 0.000 0.000 1.000 ! * +HCNN 2 150.000 2.500 0.000 0.000 1.000 ! * +HCCOH 2 436.000 3.970 0.000 0.000 2.000 +HCN 1 569.000 3.630 0.000 0.000 1.000 ! OIS +HCO 2 498.000 3.590 0.000 0.000 0.000 +HE 0 10.200 2.576 0.000 0.000 0.000 ! * +HCNO 2 232.400 3.828 0.000 0.000 1.000 ! JAM +HOCN 2 232.400 3.828 0.000 0.000 1.000 ! JAM +HNCO 2 232.400 3.828 0.000 0.000 1.000 ! OIS +HNNO 2 232.400 3.828 0.000 0.000 1.000 ! * +HNO 2 116.700 3.492 0.000 0.000 1.000 ! * +HNOH 2 116.700 3.492 0.000 0.000 1.000 ! JAM +HO2 2 107.400 3.458 0.000 0.000 1.000 ! * +N 0 71.400 3.298 0.000 0.000 0.000 ! * +N2 1 97.530 3.621 0.000 1.760 4.000 +N2H2 2 71.400 3.798 0.000 0.000 1.000 ! * +N2H3 2 200.000 3.900 0.000 0.000 1.000 ! * +N2H4 2 205.000 4.230 0.000 4.260 1.500 +N2O 1 232.400 3.828 0.000 0.000 1.000 ! * +NCN 1 232.400 3.828 0.000 0.000 1.000 ! OIS +NCO 1 232.400 3.828 0.000 0.000 1.000 ! OIS +NH 1 80.000 2.650 0.000 0.000 4.000 +NH2 2 80.000 2.650 0.000 2.260 4.000 +NH3 2 481.000 2.920 1.470 0.000 10.000 +NNH 2 71.400 3.798 0.000 0.000 1.000 ! * +NO 1 97.530 3.621 0.000 1.760 4.000 +NCNO 2 232.400 3.828 0.000 0.000 1.000 ! OIS +NO2 2 200.000 3.500 0.000 0.000 1.000 ! * +O 0 80.000 2.750 0.000 0.000 0.000 +O2 1 107.400 3.458 0.000 1.600 3.800 +OH 1 80.000 2.750 0.000 0.000 0.000 diff --git a/examples/.cvsignore b/examples/.cvsignore new file mode 100644 index 000000000..f3c7a7c5d --- /dev/null +++ b/examples/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/examples/Makefile.in b/examples/Makefile.in new file mode 100755 index 000000000..ced72344e --- /dev/null +++ b/examples/Makefile.in @@ -0,0 +1,12 @@ +#/bin/sh + +all: + @echo 'building example programs....' + cd cxx; @MAKE@ all + +clean: + cd cxx; @MAKE@ clean + +depends: + cd cxx; @MAKE@ depends + diff --git a/examples/cxx/.cvsignore b/examples/cxx/.cvsignore new file mode 100644 index 000000000..57751bad9 --- /dev/null +++ b/examples/cxx/.cvsignore @@ -0,0 +1,2 @@ +Makefile +.depends diff --git a/examples/cxx/Makefile.in b/examples/cxx/Makefile.in new file mode 100755 index 000000000..4b07f970b --- /dev/null +++ b/examples/cxx/Makefile.in @@ -0,0 +1,100 @@ +#!/bin/sh + +############################################################################ +# +# Makefile to compile and link a C++ application to +# Cantera. +# +############################################################################# + +# the name of the executable program to be created +PROG_NAME = cxx_examples + +# the object files to be linked together. List those generated from Fortran +# and from C/C++ separately +OBJS = examples.o kinetics_example1.o kinetics_example2.o \ + equil_example1.o \ + transport_example1.o transport_example2.o \ + rxnpath_example1.o + +# additional flags to be passed to the linker. If your program +# requires other external libraries, put them here +LINK_OPTIONS = + + +############################################################################# + +# the Fortran compiler +FORT = @F90@ + +# Fortran compile flags +FORT_FLAGS = @FFLAGS@ + +# Fortran libraries +FORT_LIBS = @FLIBS@ + +# the C++ compiler +CXX = @CXX@ + +# C++ compile flags +CXX_FLAGS = @CXXFLAGS@ + +# external libraries +EXT_LIBS = @LOCAL_LIBS@ + +# Ending C++ linking libraries +LCXX_END_LIBS = @LCXX_END_LIBS@ + + +#------ you probably don't have to change anything below this line ----- + + +# the directory where the Cantera libraries are located +CANTERA_LIBDIR=@ctroot@/lib + +# required Cantera libraries +CANTERA_LIBS = -lzeroD -lcantera -lckreader + +# the directory where Cantera include files may be found. +CANTERA_INC=-I@ctroot@/include + +# flags passed to the C++ compiler/linker for the linking step +LCXX_FLAGS = -L$(CANTERA_LIBDIR) @CXXFLAGS@ + +# how to compile C++ source files to object files +.@CXX_EXT@.@OBJ_EXT@: + $(CXX) -c $< $(CANTERA_INC) $(CXX_FLAGS) + +# how to compile Fortran source files to object files +.@F77_EXT@.@OBJ_EXT@: + $(FORT) -c $< $(FORT_FLAGS) + +PROGRAM = @CANTERA_BINDIR@/$(PROG_NAME)$(EXE_EXT) + +all: $(PROGRAM) + +DEPENDS=$(OBJS:.o=.d) + +%.d: + g++ -MM -I$(CANTERA_INCDIR) $(CXX_FLAGS) $*.cpp > $*.d + +$(PROGRAM): $(OBJS) $(CANTERA_LIBDIR)/libcantera.a $(CANTERA_LIBDIR)/libzeroD.a + $(CXX) -o $(PROGRAM) $(OBJS) $(LCXX_FLAGS) $(CANTERA_LIBS) \ + $(LINK_OPTIONS) $(EXT_LIBS) @LIBS@ $(FORT_LIBS) \ + $(LCXX_END_LIBS) + +clean: + $(RM) $(OBJS) $(PROGRAM) + + +depends: $(DEPENDS) + cat *.d > .depends + $(RM) $(DEPENDS) + +TAGS: + etags *.h *.cpp + +ifeq ($(wildcard .depends), .depends) +include .depends +endif + diff --git a/examples/cxx/equil_example1.cpp b/examples/cxx/equil_example1.cpp new file mode 100755 index 000000000..ea9f4adbf --- /dev/null +++ b/examples/cxx/equil_example1.cpp @@ -0,0 +1,119 @@ +///////////////////////////////////////////////////////////// +// +// chemical equilibrium +// +// $Author$ +// $Revision$ +// $Date$ +// +// copyright California Institute of Technology 2002 +// +///////////////////////////////////////////////////////////// + + +#include "Cantera.h" +#include +#include "example_utils.h" +#include "equilibrium.h" + +#include "IdealGasMix.h" + +//------------------------------------------------------------------- + +// utility functions for plotting + +template +void makeEquilDataLabels(const G& gas, V& names) { + int nsp = gas.nSpecies(); + names.resize(nsp + 2); + names[0] = "Temperature (K)"; + names[1] = "Pressure (Pa)"; + int k; + for (k = 0; k < nsp; k++) names[2+k] = gas.speciesName(k); +} + +template +void plotEquilSoln(string fname, string fmt, string title, const G& gas, + const A& soln) { + vector names; + makeEquilDataLabels(gas, names); + writePlotFile(fname, fmt, title, names, soln); +} +//----------------------------------------------------------------- + + +// Equilibrium example. This is written as a function so that one +// driver program can run multiple examples. +// The action taken depends on input parameter job: +// job = 0: print a one-line description of the example. +// job = 1: print a longer description +// job = 2: print description, then run the example. + + +int equil_example1(int job) { + + try { + cout << "Chemical equilibrium." << endl; + if (job > 0) { + cout << "Equilibrium composition and pressure for a " + << "range of temperatures at constant density." << endl; + } + if (job <= 1) return 0; + + // header + writeCanteraHeader(cout); + + // create a gas mixture, and set its state + + IdealGasMix gas("silane.xml"); + int nsp = gas.nSpecies(); + + int ntemps = 50; // number of temperatures + Array2D output(nsp+2, ntemps); + + // main loop + doublereal temp; + doublereal pres = 0.01*OneAtm; + clock_t t0 = clock(); + for (int i = 0; i < ntemps; i++) { + temp = 500.0 + 50.0*i; + gas.setState_TPX(temp, pres, "SIH4:0.01, H2:1.0"); + try { + equilibrate(gas,TP); + output(0,i) = temp; + output(1,i) = gas.pressure(); + gas.getMoleFractions(&output(2,i)); + } + catch (CanteraError) { + showErrors(cout); + } + catch (...) { + cout << "exception...." << endl; + } + } + clock_t t1 = clock(); + + // make a Tecplot data file and an Excel spreadsheet + string plotTitle = "equilibrium example 1: " + "chemical equilibrium"; + plotEquilSoln("eq1.dat", "TEC", plotTitle, gas, output); + plotEquilSoln("eq1.csv", "XL", plotTitle, gas, output); + + // print timing data + doublereal tmm = 1.0*(t1 - t0)/CLOCKS_PER_SEC; + cout << " time = " << tmm << endl << endl; + + cout << "Output files:" << endl + << " eq1.csv (Excel CSV file)" << endl + << " eq1.dat (Tecplot data file)" << endl; + + return 0; + } + + // handle exceptions thrown by Cantera + catch (CanteraError) { + showErrors(cout); + cout << " terminating... " << endl; + return -1; + } +} diff --git a/examples/cxx/example_utils.h b/examples/cxx/example_utils.h new file mode 100755 index 000000000..2d5b83ae7 --- /dev/null +++ b/examples/cxx/example_utils.h @@ -0,0 +1,58 @@ +#ifndef CT_EXAMPLE_UTILS_H +#define CT_EXAMPLE_UTILS_H + +#include "Array.h" +#include "plots.h" + +// Save the temperature, density, pressure, and mole fractions at one +// time +template +void saveSoln(int i, double time, const G& gas, A& soln) { + soln(0,i) = time; + soln(1,i) = gas.temperature(); + soln(2,i) = gas.density(); + soln(3,i) = gas.pressure(); + gas.getMoleFractions(&soln(4,i)); +} + +template +void saveSoln(double time, const G& gas, A& soln) { + soln.resize(soln.nRows(), soln.nColumns() + 1); + int back = soln.nColumns() - 1; + soln(0,back) = time; + soln(1,back) = gas.temperature(); + soln(2,back) = gas.density(); + soln(3,back) = gas.pressure(); + int nsp = gas.nSpecies(); + for (int k = 0; k < nsp; k++) + soln(4+k,back) = gas.moleFraction(k); +} + +template +void makeDataLabels(const G& gas, V& names) { + int nsp = gas.nSpecies(); + names.resize(nsp + 4); + names[0] = "time (s)"; + names[1] = "Temperature (K)"; + names[2] = "Density (kg/m3)"; + names[3] = "Pressure (Pa)"; + int k; + for (k = 0; k < nsp; k++) names[4+k] = gas.speciesName(k); +} + +template +void plotSoln(string fname, string fmt, string title, const G& gas, const A& soln) { + vector names; + makeDataLabels(gas, names); + writePlotFile(fname, fmt, title, names, soln); +} + +inline void writeCanteraHeader(ostream& s) { + s << endl; + s << " Cantera version " << CANTERA_VERSION << endl; + s << " Copyright California Institute of Technology, 2002." << endl; + s << " http://www.cantera.org" << endl; + s << endl; +} + +#endif diff --git a/examples/cxx/examples.cpp b/examples/cxx/examples.cpp new file mode 100755 index 000000000..863badba1 --- /dev/null +++ b/examples/cxx/examples.cpp @@ -0,0 +1,75 @@ + +#include "Cantera.h" +#include "ctexceptions.h" + +#define NUM_EXAMPLES 6 + +int kinetics_example1(int job); +int kinetics_example2(int job); +int transport_example1(int job); +int transport_example2(int job); +int equil_example1(int job); +int rxnpath_example1(int job); + +typedef int (*exfun)(int n=2); + +int run_example(int n, exfun f) { + cout << "\n\n\n\n>>>>> example " << n+1 << "\n\nDescription: "; + int i = f(); + showErrors(cout); + return i; +} + +// array of example functions +exfun fex[] = {kinetics_example1, kinetics_example2, + equil_example1, + transport_example1, transport_example2, rxnpath_example1}; + + +// main program +int main(int argc, char** argv) { + + int example_num = 0; + cout << endl + << "-----------------------------------" << endl + << " Cantera C++ examples " << endl + << "-----------------------------------" << endl; + + if (argc > 1) { + string v1 = string(argv[1]); + if (v1 == "-h") { + cout << "\nusage: examples \n\nwhere " + "is the example number to run." << endl; + cout << "if is omitted, all examples are run." + << endl << endl; + cout << "Examples: " << endl; + for (int i = 0; i < NUM_EXAMPLES; i++) { + cout << "(" << i+1 << ") "; + fex[i](0); + cout << endl; + } + exit(0); + } + else + example_num = atoi(argv[1]); + } + try { + + int i = 0; + if (example_num == 0) { + int j; + for (j = 0; j < NUM_EXAMPLES; j++) { + i = run_example(j, fex[j]); + } + } + else if (example_num > 0 && example_num <= NUM_EXAMPLES) + i = run_example(example_num-1, fex[example_num-1]); + + return 0; + } + catch (CanteraError) { + showErrors(cerr); + cerr << "program terminating." << endl; + return -1; + } +} diff --git a/examples/cxx/examples.dsp b/examples/cxx/examples.dsp new file mode 100755 index 000000000..81cc1a8b4 --- /dev/null +++ b/examples/cxx/examples.dsp @@ -0,0 +1,134 @@ +# Microsoft Developer Studio Project File - Name="examples" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=examples - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "examples.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "examples.mak" CFG="examples - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "examples - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "examples - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +F90=df.exe +RSC=rc.exe + +!IF "$(CFG)" == "examples - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE F90 /compile_only /nologo /warn:nofileopt +# ADD F90 /assume:underscore /compile_only /iface:nomixed_str_len_arg /iface:cref /math_library:fast /names:lowercase /nologo /warn:nofileopt /module:"" +# SUBTRACT F90 /threads +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /Ob2 /I "../../include" /I "../../Cantera/src" /I "../../Cantera/cxx/src" /I "../.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 dfor.lib /nologo /subsystem:console /machine:I386 /include:"__matherr" /out:"../../bin/examples.exe" /libpath:"../../lib" +# SUBTRACT LINK32 /profile /nodefaultlib + +!ELSEIF "$(CFG)" == "examples - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE F90 /check:bounds /compile_only /debug:full /nologo /traceback /warn:argument_checking /warn:nofileopt +# ADD F90 /assume:underscore /check:bounds /compile_only /dbglibs /debug:full /iface:nomixed_str_len_arg /iface:cref /names:lowercase /nologo /traceback /warn:argument_checking /warn:nofileopt /module:"" +# SUBTRACT F90 /threads +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../include" /I "../../Cantera/src" /I "../../Cantera/cxx/src" /I "../.." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib cantera_d.lib ckreader_d.lib ctmath_d.lib ctlapack_d.lib ctblas_d.lib cvode_d.lib recipes_d.lib dfor.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../../bin/examples.exe" /pdbtype:sept /libpath:"../../lib" + +!ENDIF + +# Begin Target + +# Name "examples - Win32 Release" +# Name "examples - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;f90;for;f;fpp" +# Begin Source File + +SOURCE=.\equil_example1.cpp +# End Source File +# Begin Source File + +SOURCE=.\examples.cpp +# End Source File +# Begin Source File + +SOURCE=.\kinetics_example1.cpp +# End Source File +# Begin Source File + +SOURCE=.\kinetics_example2.cpp +# End Source File +# Begin Source File + +SOURCE=.\rxnpath_example1.cpp +# End Source File +# Begin Source File + +SOURCE=.\transport_example1.cpp +# End Source File +# Begin Source File + +SOURCE=.\transport_example2.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/cxx/kinetics_example1.cpp b/examples/cxx/kinetics_example1.cpp new file mode 100755 index 000000000..091cabfa7 --- /dev/null +++ b/examples/cxx/kinetics_example1.cpp @@ -0,0 +1,126 @@ +///////////////////////////////////////////////////////////// +// +// zero-dimensional kinetics example program +// +// $Author$ +// $Revision$ +// $Date$ +// +// copyright California Institute of Technology 2002 +// +///////////////////////////////////////////////////////////// + + +#include "reactors.h" +#include "IdealGasMix.h" +#include +#include "example_utils.h" + +// Kinetics example. This is written as a function so that one +// driver program can run multiple examples. +// The action taken depends on input parameter job: +// job = 0: print a one-line description of the example. +// job = 1: print a longer description +// job = 2: print description, then run the example. + + +int kinetics_example1(int job) { + + try { + + cout << "Ignition simulation using class IdealGasMix " + << "with file gri30.inp." + << endl; + + if (job >= 1) { + cout << "Constant-pressure ignition of a " + << "hydrogen/oxygen/nitrogen" + " mixture \nbeginning at T = 1001 K and P = 1 atm." << endl; + } + if (job < 2) return 0; + + // header + writeCanteraHeader(cout); + + // create an ideal gas mixture that corresponds to GRI-Mech + // 3.0 + IdealGasMix* gg = new IdealGasMix("gri30.xml"); + IdealGasMix& gas = *gg; + + // set the state + gas.setState_TPX(1001.0, OneAtm, "H2:2.0, O2:1.0, N2:4.0"); + int kk = gas.nSpecies(); + + // create a reactor + Reactor r; + + // create a reservoir to represent the environment + Reservoir env; + + // specify the thermodynamic property and kinetics managers + r.setThermoMgr(gas); + r.setKineticsMgr(gas); + env.setThermoMgr(gas); + + // create a flexible, insulating wall between the reactor and the + // environment + Wall w; + w.install(r,env); + + // set the "Vdot coefficient" to a large value, in order to + // approach the constant-pressure limit; see the documentation + // for class Reactor + w.setExpansionRateCoeff(1.e9); + w.setArea(1.0); + + double tm; + double dt = 1.e-5; // interval at which output is written + int nsteps = 100; // number of intervals + + // create a 2D array to hold the output variables, + // and store the values for the initial state + Array2D soln(kk+4, 1); + saveSoln(0, 0.0, gas, soln); + + // main loop + clock_t t0 = clock(); + for (int i = 1; i <= nsteps; i++) { + tm = i*dt; + r.advance(tm); + saveSoln(tm, gas, soln); + } + clock_t t1 = clock(); + + + // make a Tecplot data file and an Excel spreadsheet + string plotTitle = "kinetics example 1: constant-pressure ignition"; + plotSoln("kin1.dat", "TEC", plotTitle, gas, soln); + plotSoln("kin1.csv", "XL", plotTitle, gas, soln); + + + // print final temperature and timing data + doublereal tmm = 1.0*(t1 - t0)/CLOCKS_PER_SEC; + cout << " Tfinal = " << r.temperature() << endl; + cout << " time = " << tmm << endl; + cout << " number of residual function evaluations = " + << r.integrator().nEvals() << endl; + cout << " time per evaluation = " << tmm/r.integrator().nEvals() + << endl << endl; + cout << "Output files:" << endl + << " kin1.csv (Excel CSV file)" << endl + << " kin1.dat (Tecplot data file)" << endl; + +#define DEBUG_HKM +#ifdef DEBUG_HKM + delete gg; +#endif + return 0; + } + + // handle exceptions thrown by Cantera + catch (CanteraError) { + showErrors(cout); + cout << " terminating... " << endl; + return -1; + } +} diff --git a/examples/cxx/kinetics_example2.cpp b/examples/cxx/kinetics_example2.cpp new file mode 100755 index 000000000..a4fd931c5 --- /dev/null +++ b/examples/cxx/kinetics_example2.cpp @@ -0,0 +1,114 @@ +///////////////////////////////////////////////////////////// +// +// zero-dimensional kinetics example program +// +// $Author$ +// $Revision$ +// $Date$ +// +// copyright California Institute of Technology 2002 +// +///////////////////////////////////////////////////////////// + + +#include "Cantera.h" +#include "IdealGasMix.h" +#include "reactors.h" +#include +#include "example_utils.h" + +/** + * Same as kinetics_example1, except that it uses class GRI30 instead + * of class IdealGasMix. + */ +int kinetics_example2(int job) { + + try { + + cout << "Ignition simulation using class GRI30." << endl; + + if (job >= 1) { + cout << "Constant-pressure ignition of a " + << "hydrogen/oxygen/nitrogen" + " mixture \nbeginning at T = 1001 K and P = 1 atm." << endl; + } + if (job < 2) return 0; + + // header + writeCanteraHeader(cout); + + // create a GRI30 object + GRI30 gas; + gas.setState_TPX(1001.0, OneAtm, "H2:2.0, O2:1.0, N2:4.0"); + int kk = gas.nSpecies(); + + // create a reactor + Reactor r; + + // create a reservoir to represent the environment + Reservoir env; + + // specify the thermodynamic property and kinetics managers + r.setThermoMgr(gas); + r.setKineticsMgr(gas); + env.setThermoMgr(gas); + + // create a flexible, insulating wall between the reactor and the + // environment + Wall w; + w.install(r,env); + + // set the "Vdot coefficient" to a large value, in order to + // approach the constant-pressure limit; see the documentation + // for class Reactor + w.setExpansionRateCoeff(1.e9); + w.setArea(1.0); + + double tm; + double dt = 1.e-5; // interval at which output is written + int nsteps = 100; // number of intervals + + // create a 2D array to hold the output variables, + // and store the values for the initial state + Array2D soln(kk+4, 1); + saveSoln(0, 0.0, gas, soln); + + // main loop + clock_t t0 = clock(); + for (int i = 1; i <= nsteps; i++) { + tm = i*dt; + r.advance(tm); + saveSoln(tm, gas, soln); + } + clock_t t1 = clock(); + + + // make a Tecplot data file and an Excel spreadsheet + string plotTitle = "kinetics example 1: constant-pressure ignition"; + plotSoln("kin2.dat", "TEC", plotTitle, gas, soln); + plotSoln("kin2.csv", "XL", plotTitle, gas, soln); + + + // print final temperature and timing data + doublereal tmm = 1.0*(t1 - t0)/CLOCKS_PER_SEC; + cout << " Tfinal = " << r.temperature() << endl; + cout << " time = " << tmm << endl; + cout << " number of residual function evaluations = " + << r.integrator().nEvals() << endl; + cout << " time per evaluation = " << tmm/r.integrator().nEvals() + << endl << endl; + + cout << "Output files:" << endl + << " kin2.csv (Excel CSV file)" << endl + << " kin2.dat (Tecplot data file)" << endl; + + return 0; + } + + // handle exceptions thrown by Cantera + catch (CanteraError) { + showErrors(cout); + cout << " terminating... " << endl; + return -1; + } +} diff --git a/examples/cxx/rxnpath_example1.cpp b/examples/cxx/rxnpath_example1.cpp new file mode 100755 index 000000000..842169b68 --- /dev/null +++ b/examples/cxx/rxnpath_example1.cpp @@ -0,0 +1,161 @@ +///////////////////////////////////////////////////////////// +// +// reaction path diagrams +// +// $Author$ +// $Revision$ +// $Date$ +// +// copyright California Institute of Technology 2002 +// +///////////////////////////////////////////////////////////// + + +#include "Cantera.h" +#include "reactors.h" +#include +#include "example_utils.h" +#include "ReactionPath.h" +#include "IdealGasMix.h" + +// #include +// using namespace std; + +void writeRxnPathDiagram(double time, ReactionPathBuilder& b, + IdealGasMix& gas, ostream& logfile, ostream& outfile) { + + // create a new empty diagram + ReactionPathDiagram d; + + // show the details of which reactions contribute to the flux + d.show_details = false; + + // set the threshold for the minimum flux relative value that will + // be plotted + d.threshold = 0.001; + + // color for bold lines + d.bold_color = "orange"; + + // color for normal-weight lines + d.normal_color = "steelblue"; + + // color for dashed lines + d.dashed_color = "gray"; + + // options for the 'dot' program + d.dot_options = "center=1;size=\"6,9\";ratio=auto"; + + // minimum relative flux for bold lines + d.bold_min = 0.0; + + // maximum relative flux for dashed lines + d.dashed_max = 0.01; + + // minimum relative flux for labels + d.label_min = 0.01; + + // autoscale + d.scale = -1; + + // set to either NetFlow or OneWayFlow + d.flow_type = NetFlow; //OneWayFlow; + + // arrow width. If < 0, then scale with flux value + d.arrow_width = -2.0; + + // title + d.title = "time = "+fp2str(time)+" (s)"; + + // build the diagram following elemental nitrogen + b.build(gas, "N", logfile, d); + + // write an input file for 'dot' + d.exportToDot(outfile); + +} + + +int rxnpath_example1(int job) { + + try { + + cout << "Reaction path diagram movies with file gri30mod.inp." << endl; + if (job >= 1) { + cout << "Generate reaction path diagrams following nitrogen\n" + << "as a function of time for constant-pressure ignition of a\n" + << "hydrogen/oxygen/nitrogen" + " mixture \nbeginning at T = 1001 K and P = 1 atm." << endl; + } + if (job < 2) return 0; + + // header + writeCanteraHeader(cout); + + // create an ideal gas mixture that corresponds to GRI-Mech + // 3.0 + IdealGasMix gas("gri30.xml"); + gas.setState_TPX(1001.0, OneAtm, "H2:2.0, O2:1.0, N2:4.0"); + int nsp = gas.nSpecies(); + cout << "number of species = " << nsp << endl; + // create a reactor + Reactor r; + + // create a reservoir to represent the environment + Reservoir env; + + // specify the thermodynamic property and kinetics managers + r.setThermoMgr(gas); + r.setKineticsMgr(gas); + env.setThermoMgr(gas); + + // create a flexible, insulating wall between the reactor and the + // environment + Wall w; + w.install(r,env); + + // set the "Vdot coefficient" to a large value, in order to + // approach the constant-pressure limit; see the documentation + // for class Reactor + w.setExpansionRateCoeff(1.e9); + w.setArea(1.0); + + double tm; + double dt = 1.e-5; // interval at which output is written + int nsteps = 100; // number of intervals + + // create a reaction path diagram builder + ReactionPathBuilder b; + ofstream rplog("rp1.log"); // log file + ofstream rplot("rp1.dot"); // output file + b.init(rplog, gas); // initialize + + // main loop + clock_t t0 = clock(); + for (int i = 1; i <= nsteps; i++) { + tm = i*dt; + r.advance(tm); + writeRxnPathDiagram(tm, b, gas, rplog, rplot); + } + clock_t t1 = clock(); + + // print final temperature and timing data + doublereal tmm = 1.0*(t1 - t0)/CLOCKS_PER_SEC; + cout << " time = " << tmm << endl; + cout << "Output files:" << endl + << " rp1.log (log file)" << endl + << " rp1.dot (input file for dot)" << endl; + cout << "To generate the diagrams in Postscript, execute the command" << endl << endl + << "dot -Tps rp1.dot > rp1.ps" << endl << endl + << "Get dot for Windows here: http://blue.caltech.edu/dot.exe" << endl; + + return 0; + } + + // handle exceptions thrown by Cantera + catch (CanteraError) { + showErrors(cout); + cout << " terminating... " << endl; + return -1; + } +} diff --git a/examples/cxx/transport_example1.cpp b/examples/cxx/transport_example1.cpp new file mode 100755 index 000000000..1c9e5f4cb --- /dev/null +++ b/examples/cxx/transport_example1.cpp @@ -0,0 +1,110 @@ +///////////////////////////////////////////////////////////// +// +// mixture-averaged transport properties +// +// $Author$ +// $Revision$ +// $Date$ +// +// copyright California Institute of Technology 2002 +// +///////////////////////////////////////////////////////////// + + +#include "Cantera.h" +#include "transport.h" +#include +#include "example_utils.h" +#include "IdealGasMix.h" + +template +void makeTransportDataLabels(const G& gas, V& names) { + int nsp = gas.nSpecies(); + names.resize(nsp + 3); + names[0] = "Temperature (K)"; + names[1] = "Viscosity ()"; + names[2] = "Thermal Conductivity (W/m-K)"; + int k; + for (k = 0; k < nsp; k++) names[3+k] = gas.speciesName(k); +} + +template +void plotTransportSoln(string fname, string fmt, string title, const G& gas, + const A& soln) { + vector names; + makeTransportDataLabels(gas, names); + writePlotFile(fname, fmt, title, names, soln); +} + + +int transport_example1(int job) { + + try { + + cout << "Mixture-averaged transport properties." << endl; + if (job > 0) { + cout << "Viscosity, thermal conductivity, and mixture-averaged\n" + << "diffusion coefficients at 2 atm for a " + << "range of temperatures" << endl; + } + if (job <= 1) return 0; + + // header + writeCanteraHeader(cout); + + + // create a gas mixture, and set its state + + IdealGasMix gas("gri30.xml"); + doublereal temp = 500.0; + doublereal pres = 2.0*OneAtm; + gas.setState_TPX(temp, pres, "H2:1.0, CH4:0.1"); + + // create a transport manager that implements + // mixture-averaged transport properties + + Transport* tr = newTransportMgr("Mix", &gas); + + int nsp = gas.nSpecies(); + + + // create a 2D array to hold the outputs + int ntemps = 20; + Array2D output(nsp+3, ntemps); + + // main loop + clock_t t0 = clock(); + for (int i = 0; i < ntemps; i++) { + temp = 500.0 + 100.0*i; + gas.setState_TP(temp, pres); + output(0,i) = temp; + output(1,i) = tr->viscosity(); + output(2,i) = tr->thermalConductivity(); + tr->getMixDiffCoeffs(&output(3,i)); + } + clock_t t1 = clock(); + + // make a Tecplot data file and an Excel spreadsheet + string plotTitle = "transport example 1: " + "mixture-averaged transport properties"; + plotTransportSoln("tr1.dat", "TEC", plotTitle, gas, output); + plotTransportSoln("tr1.csv", "XL", plotTitle, gas, output); + + // print final temperature and timing data + doublereal tmm = 1.0*(t1 - t0)/CLOCKS_PER_SEC; + cout << " time = " << tmm << endl << endl; + + cout << "Output files:" << endl + << " tr1.csv (Excel CSV file)" << endl + << " tr1.dat (Tecplot data file)" << endl; + + return 0; + } + + // handle exceptions thrown by Cantera + catch (CanteraError) { + showErrors(cout); + cout << " terminating... " << endl; + return -1; + } +} diff --git a/examples/cxx/transport_example2.cpp b/examples/cxx/transport_example2.cpp new file mode 100755 index 000000000..ca2a6b0fc --- /dev/null +++ b/examples/cxx/transport_example2.cpp @@ -0,0 +1,112 @@ +///////////////////////////////////////////////////////////// +// +// mixture-averaged transport properties +// +// $Author$ +// $Revision$ +// $Date$ +// +// copyright California Institute of Technology 2002 +// +///////////////////////////////////////////////////////////// + + +#include "Cantera.h" +#include "transport.h" +#include +#include "example_utils.h" +#include "equilibrium.h" +#include "IdealGasMix.h" + +template +void makeTransportDataLabels(const G& gas, V& names) { + int nsp = gas.nSpecies(); + names.resize(nsp + 3); + names[0] = "Temperature (K)"; + names[1] = "Viscosity ()"; + names[2] = "Thermal Conductivity (W/m-K)"; + int k; + for (k = 0; k < nsp; k++) names[3+k] = gas.speciesName(k); +} + +template +void plotTransportSoln(string fname, string fmt, string title, const G& gas, + const A& soln) { + vector names; + makeTransportDataLabels(gas, names); + writePlotFile(fname, fmt, title, names, soln); +} + + +int transport_example2(int job) { + + try { + + cout << "Multicomponent transport properties." << endl; + if (job > 0) { + cout << "Viscosity, thermal conductivity, and thermal diffusion\n" + " coefficients at 2 atm for a " + << "range of temperatures" << endl; + } + if (job <= 1) return 0; + + // header + writeCanteraHeader(cout); + + + // create a gas mixture, and set its state + + IdealGasMix gas("gri30.xml"); + doublereal temp = 2000.0; + doublereal pres = 2.0*OneAtm; + gas.setState_TPX(temp, pres, "H2:1.0, O2:0.5, CH4:0.1, N2:0.2"); + equilibrate(gas,TP); + + + // create a transport manager that implements + // multicomponent transport properties + + Transport* tr = newTransportMgr("Multi", &gas); + int nsp = gas.nSpecies(); + + + // create a 2D array to hold the outputs + int ntemps = 20; + Array2D output(nsp+3, ntemps); + + // main loop + clock_t t0 = clock(); + for (int i = 0; i < ntemps; i++) { + temp = 500.0 + 100.0*i; + gas.setState_TP(temp, pres); + output(0,i) = temp; + output(1,i) = tr->viscosity(); + output(2,i) = tr->thermalConductivity(); + tr->getThermalDiffCoeffs(&output(3,i)); + } + clock_t t1 = clock(); + + // make a Tecplot data file and an Excel spreadsheet + string plotTitle = "transport example 2: " + "multicomponent transport properties"; + plotTransportSoln("tr2.dat", "TEC", plotTitle, gas, output); + plotTransportSoln("tr2.csv", "XL", plotTitle, gas, output); + + // print final temperature and timing data + doublereal tmm = 1.0*(t1 - t0)/CLOCKS_PER_SEC; + cout << " time = " << tmm << endl << endl; + + cout << "Output files:" << endl + << " tr2.csv (Excel CSV file)" << endl + << " tr2.dat (Tecplot data file)" << endl; + + return 0; + } + + // handle exceptions thrown by Cantera + catch (CanteraError) { + showErrors(cout); + cout << " terminating... " << endl; + return -1; + } +} diff --git a/ext/.cvsignore b/ext/.cvsignore new file mode 100644 index 000000000..f3c7a7c5d --- /dev/null +++ b/ext/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/ext/Makefile.in b/ext/Makefile.in new file mode 100755 index 000000000..dce908022 --- /dev/null +++ b/ext/Makefile.in @@ -0,0 +1,33 @@ + +BUILD_LAPACK=@build_lapack@ +BUILD_BLAS=@build_blas@ + +LIBS = blas/libctblas.a lapack/libctlapack.a math/libctmath.a \ + recipes/librecipes.a cvode/libcvode.a tpx/libtpx.a + +all: +ifeq ($(BUILD_LAPACK),1) + cd lapack; @MAKE@ +else + cd lapack; @MAKE@ clean +endif +ifeq ($(BUILD_BLAS),1) + cd blas; @MAKE@ +else + cd blas; @MAKE@ clean +endif + cd recipes; @MAKE@ + cd cvode; @MAKE@ + cd math; @MAKE@ + cd tpx; @MAKE@ + +clean: + cd lapack; @MAKE@ clean + cd blas; @MAKE@ clean + cd recipes; @MAKE@ clean + cd cvode; @MAKE@ clean + cd math; @MAKE@ clean + cd tpx; @MAKE@ clean + +install: + @INSTALL@ -m 644 $(LIBS) @prefix@/lib diff --git a/ext/blas/.cvsignore b/ext/blas/.cvsignore new file mode 100644 index 000000000..f3c7a7c5d --- /dev/null +++ b/ext/blas/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/ext/blas/Makefile.in b/ext/blas/Makefile.in new file mode 100755 index 000000000..bb09358ef --- /dev/null +++ b/ext/blas/Makefile.in @@ -0,0 +1,69 @@ +# $License$ +# +#/bin/sh + +BLASLIB = ./libctblas.a + +SUFFIXES= +SUFFIXES= .f .o + +F_FLAGS = @FFLAGS@ $(F77_FLAGS) + +OBJS = \ +dasum.o \ +daxpy.o \ +dcabs1.o \ +dcopy.o \ +ddot.o \ +dgbmv.o \ +dgemm.o \ +dgemv.o \ +dger.o \ +dnrm2.o \ +drot.o \ +drotg.o \ +drotm.o \ +drotmg.o \ +dsbmv.o \ +dscal.o \ +dsdot.o \ +dspmv.o \ +dspr.o \ +dspr2.o \ +dswap.o \ +dsymm.o \ +dsymv.o \ +dsyr.o \ +dsyr2.o \ +dsyr2k.o \ +dsyrk.o \ +dtbmv.o \ +dtbsv.o \ +dtpmv.o \ +dtpsv.o \ +dtrmm.o \ +dtrmv.o \ +dtrsm.o \ +dtrsv.o \ +dzasum.o \ +dznrm2.o \ +idamax.o \ +lsame.o \ +xerbla.o + + +#SRCS = $(OBJS:.o=.cpp) + + +$(BLASLIB): $(OBJS) + @ARCHIVE@ $(BLASLIB) $(OBJS) > /dev/null + +.f.o: + @F77@ -c $< $(F77_INCLUDES) $(F_FLAGS) + +clean: + $(RM) $(OBJS) $(BLASLIB) + + + + diff --git a/ext/blas/dasum.f b/ext/blas/dasum.f new file mode 100755 index 000000000..28b128a84 --- /dev/null +++ b/ext/blas/dasum.f @@ -0,0 +1,43 @@ + double precision function dasum(n,dx,incx) +c +c takes the sum of the absolute values. +c jack dongarra, linpack, 3/11/78. +c modified 3/93 to return if incx .le. 0. +c modified 12/3/93, array(1) declarations changed to array(*) +c + double precision dx(*),dtemp + integer i,incx,m,mp1,n,nincx +c + dasum = 0.0d0 + dtemp = 0.0d0 + if( n.le.0 .or. incx.le.0 )return + if(incx.eq.1)go to 20 +c +c code for increment not equal to 1 +c + nincx = n*incx + do 10 i = 1,nincx,incx + dtemp = dtemp + dabs(dx(i)) + 10 continue + dasum = dtemp + return +c +c code for increment equal to 1 +c +c +c clean-up loop +c + 20 m = mod(n,6) + if( m .eq. 0 ) go to 40 + do 30 i = 1,m + dtemp = dtemp + dabs(dx(i)) + 30 continue + if( n .lt. 6 ) go to 60 + 40 mp1 = m + 1 + do 50 i = mp1,n,6 + dtemp = dtemp + dabs(dx(i)) + dabs(dx(i + 1)) + dabs(dx(i + 2)) + * + dabs(dx(i + 3)) + dabs(dx(i + 4)) + dabs(dx(i + 5)) + 50 continue + 60 dasum = dtemp + return + end diff --git a/ext/blas/daxpy.f b/ext/blas/daxpy.f new file mode 100755 index 000000000..91daa3c64 --- /dev/null +++ b/ext/blas/daxpy.f @@ -0,0 +1,48 @@ + subroutine daxpy(n,da,dx,incx,dy,incy) +c +c constant times a vector plus a vector. +c uses unrolled loops for increments equal to one. +c jack dongarra, linpack, 3/11/78. +c modified 12/3/93, array(1) declarations changed to array(*) +c + double precision dx(*),dy(*),da + integer i,incx,incy,ix,iy,m,mp1,n +c + if(n.le.0)return + if (da .eq. 0.0d0) return + if(incx.eq.1.and.incy.eq.1)go to 20 +c +c code for unequal increments or equal increments +c not equal to 1 +c + ix = 1 + iy = 1 + if(incx.lt.0)ix = (-n+1)*incx + 1 + if(incy.lt.0)iy = (-n+1)*incy + 1 + do 10 i = 1,n + dy(iy) = dy(iy) + da*dx(ix) + ix = ix + incx + iy = iy + incy + 10 continue + return +c +c code for both increments equal to 1 +c +c +c clean-up loop +c + 20 m = mod(n,4) + if( m .eq. 0 ) go to 40 + do 30 i = 1,m + dy(i) = dy(i) + da*dx(i) + 30 continue + if( n .lt. 4 ) return + 40 mp1 = m + 1 + do 50 i = mp1,n,4 + dy(i) = dy(i) + da*dx(i) + dy(i + 1) = dy(i + 1) + da*dx(i + 1) + dy(i + 2) = dy(i + 2) + da*dx(i + 2) + dy(i + 3) = dy(i + 3) + da*dx(i + 3) + 50 continue + return + end diff --git a/ext/blas/dcabs1.f b/ext/blas/dcabs1.f new file mode 100755 index 000000000..385ea5e1a --- /dev/null +++ b/ext/blas/dcabs1.f @@ -0,0 +1,8 @@ + double precision function dcabs1(z) + double complex z,zz + double precision t(2) + equivalence (zz,t(1)) + zz = z + dcabs1 = dabs(t(1)) + dabs(t(2)) + return + end diff --git a/ext/blas/dcopy.f b/ext/blas/dcopy.f new file mode 100755 index 000000000..e16892716 --- /dev/null +++ b/ext/blas/dcopy.f @@ -0,0 +1,50 @@ + subroutine dcopy(n,dx,incx,dy,incy) +c +c copies a vector, x, to a vector, y. +c uses unrolled loops for increments equal to one. +c jack dongarra, linpack, 3/11/78. +c modified 12/3/93, array(1) declarations changed to array(*) +c + double precision dx(*),dy(*) + integer i,incx,incy,ix,iy,m,mp1,n +c + if(n.le.0)return + if(incx.eq.1.and.incy.eq.1)go to 20 +c +c code for unequal increments or equal increments +c not equal to 1 +c + ix = 1 + iy = 1 + if(incx.lt.0)ix = (-n+1)*incx + 1 + if(incy.lt.0)iy = (-n+1)*incy + 1 + do 10 i = 1,n + dy(iy) = dx(ix) + ix = ix + incx + iy = iy + incy + 10 continue + return +c +c code for both increments equal to 1 +c +c +c clean-up loop +c + 20 m = mod(n,7) + if( m .eq. 0 ) go to 40 + do 30 i = 1,m + dy(i) = dx(i) + 30 continue + if( n .lt. 7 ) return + 40 mp1 = m + 1 + do 50 i = mp1,n,7 + dy(i) = dx(i) + dy(i + 1) = dx(i + 1) + dy(i + 2) = dx(i + 2) + dy(i + 3) = dx(i + 3) + dy(i + 4) = dx(i + 4) + dy(i + 5) = dx(i + 5) + dy(i + 6) = dx(i + 6) + 50 continue + return + end diff --git a/ext/blas/ddot.f b/ext/blas/ddot.f new file mode 100755 index 000000000..e04c7c25e --- /dev/null +++ b/ext/blas/ddot.f @@ -0,0 +1,49 @@ + double precision function ddot(n,dx,incx,dy,incy) +c +c forms the dot product of two vectors. +c uses unrolled loops for increments equal to one. +c jack dongarra, linpack, 3/11/78. +c modified 12/3/93, array(1) declarations changed to array(*) +c + double precision dx(*),dy(*),dtemp + integer i,incx,incy,ix,iy,m,mp1,n +c + ddot = 0.0d0 + dtemp = 0.0d0 + if(n.le.0)return + if(incx.eq.1.and.incy.eq.1)go to 20 +c +c code for unequal increments or equal increments +c not equal to 1 +c + ix = 1 + iy = 1 + if(incx.lt.0)ix = (-n+1)*incx + 1 + if(incy.lt.0)iy = (-n+1)*incy + 1 + do 10 i = 1,n + dtemp = dtemp + dx(ix)*dy(iy) + ix = ix + incx + iy = iy + incy + 10 continue + ddot = dtemp + return +c +c code for both increments equal to 1 +c +c +c clean-up loop +c + 20 m = mod(n,5) + if( m .eq. 0 ) go to 40 + do 30 i = 1,m + dtemp = dtemp + dx(i)*dy(i) + 30 continue + if( n .lt. 5 ) go to 60 + 40 mp1 = m + 1 + do 50 i = mp1,n,5 + dtemp = dtemp + dx(i)*dy(i) + dx(i + 1)*dy(i + 1) + + * dx(i + 2)*dy(i + 2) + dx(i + 3)*dy(i + 3) + dx(i + 4)*dy(i + 4) + 50 continue + 60 ddot = dtemp + return + end diff --git a/ext/blas/dgbmv.f b/ext/blas/dgbmv.f new file mode 100755 index 000000000..e9c8f76fb --- /dev/null +++ b/ext/blas/dgbmv.f @@ -0,0 +1,300 @@ + SUBROUTINE DGBMV ( TRANS, M, N, KL, KU, ALPHA, A, LDA, X, INCX, + $ BETA, Y, INCY ) +* .. Scalar Arguments .. + DOUBLE PRECISION ALPHA, BETA + INTEGER INCX, INCY, KL, KU, LDA, M, N + CHARACTER*1 TRANS +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), X( * ), Y( * ) +* .. +* +* Purpose +* ======= +* +* DGBMV performs one of the matrix-vector operations +* +* y := alpha*A*x + beta*y, or y := alpha*A'*x + beta*y, +* +* where alpha and beta are scalars, x and y are vectors and A is an +* m by n band matrix, with kl sub-diagonals and ku super-diagonals. +* +* Parameters +* ========== +* +* TRANS - CHARACTER*1. +* On entry, TRANS specifies the operation to be performed as +* follows: +* +* TRANS = 'N' or 'n' y := alpha*A*x + beta*y. +* +* TRANS = 'T' or 't' y := alpha*A'*x + beta*y. +* +* TRANS = 'C' or 'c' y := alpha*A'*x + beta*y. +* +* Unchanged on exit. +* +* M - INTEGER. +* On entry, M specifies the number of rows of the matrix A. +* M must be at least zero. +* Unchanged on exit. +* +* N - INTEGER. +* On entry, N specifies the number of columns of the matrix A. +* N must be at least zero. +* Unchanged on exit. +* +* KL - INTEGER. +* On entry, KL specifies the number of sub-diagonals of the +* matrix A. KL must satisfy 0 .le. KL. +* Unchanged on exit. +* +* KU - INTEGER. +* On entry, KU specifies the number of super-diagonals of the +* matrix A. KU must satisfy 0 .le. KU. +* Unchanged on exit. +* +* ALPHA - DOUBLE PRECISION. +* On entry, ALPHA specifies the scalar alpha. +* Unchanged on exit. +* +* A - DOUBLE PRECISION array of DIMENSION ( LDA, n ). +* Before entry, the leading ( kl + ku + 1 ) by n part of the +* array A must contain the matrix of coefficients, supplied +* column by column, with the leading diagonal of the matrix in +* row ( ku + 1 ) of the array, the first super-diagonal +* starting at position 2 in row ku, the first sub-diagonal +* starting at position 1 in row ( ku + 2 ), and so on. +* Elements in the array A that do not correspond to elements +* in the band matrix (such as the top left ku by ku triangle) +* are not referenced. +* The following program segment will transfer a band matrix +* from conventional full matrix storage to band storage: +* +* DO 20, J = 1, N +* K = KU + 1 - J +* DO 10, I = MAX( 1, J - KU ), MIN( M, J + KL ) +* A( K + I, J ) = matrix( I, J ) +* 10 CONTINUE +* 20 CONTINUE +* +* Unchanged on exit. +* +* LDA - INTEGER. +* On entry, LDA specifies the first dimension of A as declared +* in the calling (sub) program. LDA must be at least +* ( kl + ku + 1 ). +* Unchanged on exit. +* +* X - DOUBLE PRECISION array of DIMENSION at least +* ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n' +* and at least +* ( 1 + ( m - 1 )*abs( INCX ) ) otherwise. +* Before entry, the incremented array X must contain the +* vector x. +* Unchanged on exit. +* +* INCX - INTEGER. +* On entry, INCX specifies the increment for the elements of +* X. INCX must not be zero. +* Unchanged on exit. +* +* BETA - DOUBLE PRECISION. +* On entry, BETA specifies the scalar beta. When BETA is +* supplied as zero then Y need not be set on input. +* Unchanged on exit. +* +* Y - DOUBLE PRECISION array of DIMENSION at least +* ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n' +* and at least +* ( 1 + ( n - 1 )*abs( INCY ) ) otherwise. +* Before entry, the incremented array Y must contain the +* vector y. On exit, Y is overwritten by the updated vector y. +* +* INCY - INTEGER. +* On entry, INCY specifies the increment for the elements of +* Y. INCY must not be zero. +* Unchanged on exit. +* +* +* Level 2 Blas routine. +* +* -- Written on 22-October-1986. +* Jack Dongarra, Argonne National Lab. +* Jeremy Du Croz, Nag Central Office. +* Sven Hammarling, Nag Central Office. +* Richard Hanson, Sandia National Labs. +* +* .. Parameters .. + DOUBLE PRECISION ONE , ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. Local Scalars .. + DOUBLE PRECISION TEMP + INTEGER I, INFO, IX, IY, J, JX, JY, K, KUP1, KX, KY, + $ LENX, LENY +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. External Subroutines .. + EXTERNAL XERBLA +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + IF ( .NOT.LSAME( TRANS, 'N' ).AND. + $ .NOT.LSAME( TRANS, 'T' ).AND. + $ .NOT.LSAME( TRANS, 'C' ) )THEN + INFO = 1 + ELSE IF( M.LT.0 )THEN + INFO = 2 + ELSE IF( N.LT.0 )THEN + INFO = 3 + ELSE IF( KL.LT.0 )THEN + INFO = 4 + ELSE IF( KU.LT.0 )THEN + INFO = 5 + ELSE IF( LDA.LT.( KL + KU + 1 ) )THEN + INFO = 8 + ELSE IF( INCX.EQ.0 )THEN + INFO = 10 + ELSE IF( INCY.EQ.0 )THEN + INFO = 13 + END IF + IF( INFO.NE.0 )THEN + CALL XERBLA( 'DGBMV ', INFO ) + RETURN + END IF +* +* Quick return if possible. +* + IF( ( M.EQ.0 ).OR.( N.EQ.0 ).OR. + $ ( ( ALPHA.EQ.ZERO ).AND.( BETA.EQ.ONE ) ) ) + $ RETURN +* +* Set LENX and LENY, the lengths of the vectors x and y, and set +* up the start points in X and Y. +* + IF( LSAME( TRANS, 'N' ) )THEN + LENX = N + LENY = M + ELSE + LENX = M + LENY = N + END IF + IF( INCX.GT.0 )THEN + KX = 1 + ELSE + KX = 1 - ( LENX - 1 )*INCX + END IF + IF( INCY.GT.0 )THEN + KY = 1 + ELSE + KY = 1 - ( LENY - 1 )*INCY + END IF +* +* Start the operations. In this version the elements of A are +* accessed sequentially with one pass through the band part of A. +* +* First form y := beta*y. +* + IF( BETA.NE.ONE )THEN + IF( INCY.EQ.1 )THEN + IF( BETA.EQ.ZERO )THEN + DO 10, I = 1, LENY + Y( I ) = ZERO + 10 CONTINUE + ELSE + DO 20, I = 1, LENY + Y( I ) = BETA*Y( I ) + 20 CONTINUE + END IF + ELSE + IY = KY + IF( BETA.EQ.ZERO )THEN + DO 30, I = 1, LENY + Y( IY ) = ZERO + IY = IY + INCY + 30 CONTINUE + ELSE + DO 40, I = 1, LENY + Y( IY ) = BETA*Y( IY ) + IY = IY + INCY + 40 CONTINUE + END IF + END IF + END IF + IF( ALPHA.EQ.ZERO ) + $ RETURN + KUP1 = KU + 1 + IF( LSAME( TRANS, 'N' ) )THEN +* +* Form y := alpha*A*x + y. +* + JX = KX + IF( INCY.EQ.1 )THEN + DO 60, J = 1, N + IF( X( JX ).NE.ZERO )THEN + TEMP = ALPHA*X( JX ) + K = KUP1 - J + DO 50, I = MAX( 1, J - KU ), MIN( M, J + KL ) + Y( I ) = Y( I ) + TEMP*A( K + I, J ) + 50 CONTINUE + END IF + JX = JX + INCX + 60 CONTINUE + ELSE + DO 80, J = 1, N + IF( X( JX ).NE.ZERO )THEN + TEMP = ALPHA*X( JX ) + IY = KY + K = KUP1 - J + DO 70, I = MAX( 1, J - KU ), MIN( M, J + KL ) + Y( IY ) = Y( IY ) + TEMP*A( K + I, J ) + IY = IY + INCY + 70 CONTINUE + END IF + JX = JX + INCX + IF( J.GT.KU ) + $ KY = KY + INCY + 80 CONTINUE + END IF + ELSE +* +* Form y := alpha*A'*x + y. +* + JY = KY + IF( INCX.EQ.1 )THEN + DO 100, J = 1, N + TEMP = ZERO + K = KUP1 - J + DO 90, I = MAX( 1, J - KU ), MIN( M, J + KL ) + TEMP = TEMP + A( K + I, J )*X( I ) + 90 CONTINUE + Y( JY ) = Y( JY ) + ALPHA*TEMP + JY = JY + INCY + 100 CONTINUE + ELSE + DO 120, J = 1, N + TEMP = ZERO + IX = KX + K = KUP1 - J + DO 110, I = MAX( 1, J - KU ), MIN( M, J + KL ) + TEMP = TEMP + A( K + I, J )*X( IX ) + IX = IX + INCX + 110 CONTINUE + Y( JY ) = Y( JY ) + ALPHA*TEMP + JY = JY + INCY + IF( J.GT.KU ) + $ KX = KX + INCX + 120 CONTINUE + END IF + END IF +* + RETURN +* +* End of DGBMV . +* + END diff --git a/ext/blas/dgemm.f b/ext/blas/dgemm.f new file mode 100755 index 000000000..baabe4c52 --- /dev/null +++ b/ext/blas/dgemm.f @@ -0,0 +1,313 @@ + SUBROUTINE DGEMM ( TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, + $ BETA, C, LDC ) +* .. Scalar Arguments .. + CHARACTER*1 TRANSA, TRANSB + INTEGER M, N, K, LDA, LDB, LDC + DOUBLE PRECISION ALPHA, BETA +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), B( LDB, * ), C( LDC, * ) +* .. +* +* Purpose +* ======= +* +* DGEMM performs one of the matrix-matrix operations +* +* C := alpha*op( A )*op( B ) + beta*C, +* +* where op( X ) is one of +* +* op( X ) = X or op( X ) = X', +* +* alpha and beta are scalars, and A, B and C are matrices, with op( A ) +* an m by k matrix, op( B ) a k by n matrix and C an m by n matrix. +* +* Parameters +* ========== +* +* TRANSA - CHARACTER*1. +* On entry, TRANSA specifies the form of op( A ) to be used in +* the matrix multiplication as follows: +* +* TRANSA = 'N' or 'n', op( A ) = A. +* +* TRANSA = 'T' or 't', op( A ) = A'. +* +* TRANSA = 'C' or 'c', op( A ) = A'. +* +* Unchanged on exit. +* +* TRANSB - CHARACTER*1. +* On entry, TRANSB specifies the form of op( B ) to be used in +* the matrix multiplication as follows: +* +* TRANSB = 'N' or 'n', op( B ) = B. +* +* TRANSB = 'T' or 't', op( B ) = B'. +* +* TRANSB = 'C' or 'c', op( B ) = B'. +* +* Unchanged on exit. +* +* M - INTEGER. +* On entry, M specifies the number of rows of the matrix +* op( A ) and of the matrix C. M must be at least zero. +* Unchanged on exit. +* +* N - INTEGER. +* On entry, N specifies the number of columns of the matrix +* op( B ) and the number of columns of the matrix C. N must be +* at least zero. +* Unchanged on exit. +* +* K - INTEGER. +* On entry, K specifies the number of columns of the matrix +* op( A ) and the number of rows of the matrix op( B ). K must +* be at least zero. +* Unchanged on exit. +* +* ALPHA - DOUBLE PRECISION. +* On entry, ALPHA specifies the scalar alpha. +* Unchanged on exit. +* +* A - DOUBLE PRECISION array of DIMENSION ( LDA, ka ), where ka is +* k when TRANSA = 'N' or 'n', and is m otherwise. +* Before entry with TRANSA = 'N' or 'n', the leading m by k +* part of the array A must contain the matrix A, otherwise +* the leading k by m part of the array A must contain the +* matrix A. +* Unchanged on exit. +* +* LDA - INTEGER. +* On entry, LDA specifies the first dimension of A as declared +* in the calling (sub) program. When TRANSA = 'N' or 'n' then +* LDA must be at least max( 1, m ), otherwise LDA must be at +* least max( 1, k ). +* Unchanged on exit. +* +* B - DOUBLE PRECISION array of DIMENSION ( LDB, kb ), where kb is +* n when TRANSB = 'N' or 'n', and is k otherwise. +* Before entry with TRANSB = 'N' or 'n', the leading k by n +* part of the array B must contain the matrix B, otherwise +* the leading n by k part of the array B must contain the +* matrix B. +* Unchanged on exit. +* +* LDB - INTEGER. +* On entry, LDB specifies the first dimension of B as declared +* in the calling (sub) program. When TRANSB = 'N' or 'n' then +* LDB must be at least max( 1, k ), otherwise LDB must be at +* least max( 1, n ). +* Unchanged on exit. +* +* BETA - DOUBLE PRECISION. +* On entry, BETA specifies the scalar beta. When BETA is +* supplied as zero then C need not be set on input. +* Unchanged on exit. +* +* C - DOUBLE PRECISION array of DIMENSION ( LDC, n ). +* Before entry, the leading m by n part of the array C must +* contain the matrix C, except when beta is zero, in which +* case C need not be set on entry. +* On exit, the array C is overwritten by the m by n matrix +* ( alpha*op( A )*op( B ) + beta*C ). +* +* LDC - INTEGER. +* On entry, LDC specifies the first dimension of C as declared +* in the calling (sub) program. LDC must be at least +* max( 1, m ). +* Unchanged on exit. +* +* +* Level 3 Blas routine. +* +* -- Written on 8-February-1989. +* Jack Dongarra, Argonne National Laboratory. +* Iain Duff, AERE Harwell. +* Jeremy Du Croz, Numerical Algorithms Group Ltd. +* Sven Hammarling, Numerical Algorithms Group Ltd. +* +* +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. External Subroutines .. + EXTERNAL XERBLA +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. Local Scalars .. + LOGICAL NOTA, NOTB + INTEGER I, INFO, J, L, NCOLA, NROWA, NROWB + DOUBLE PRECISION TEMP +* .. Parameters .. + DOUBLE PRECISION ONE , ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Executable Statements .. +* +* Set NOTA and NOTB as true if A and B respectively are not +* transposed and set NROWA, NCOLA and NROWB as the number of rows +* and columns of A and the number of rows of B respectively. +* + NOTA = LSAME( TRANSA, 'N' ) + NOTB = LSAME( TRANSB, 'N' ) + IF( NOTA )THEN + NROWA = M + NCOLA = K + ELSE + NROWA = K + NCOLA = M + END IF + IF( NOTB )THEN + NROWB = K + ELSE + NROWB = N + END IF +* +* Test the input parameters. +* + INFO = 0 + IF( ( .NOT.NOTA ).AND. + $ ( .NOT.LSAME( TRANSA, 'C' ) ).AND. + $ ( .NOT.LSAME( TRANSA, 'T' ) ) )THEN + INFO = 1 + ELSE IF( ( .NOT.NOTB ).AND. + $ ( .NOT.LSAME( TRANSB, 'C' ) ).AND. + $ ( .NOT.LSAME( TRANSB, 'T' ) ) )THEN + INFO = 2 + ELSE IF( M .LT.0 )THEN + INFO = 3 + ELSE IF( N .LT.0 )THEN + INFO = 4 + ELSE IF( K .LT.0 )THEN + INFO = 5 + ELSE IF( LDA.LT.MAX( 1, NROWA ) )THEN + INFO = 8 + ELSE IF( LDB.LT.MAX( 1, NROWB ) )THEN + INFO = 10 + ELSE IF( LDC.LT.MAX( 1, M ) )THEN + INFO = 13 + END IF + IF( INFO.NE.0 )THEN + CALL XERBLA( 'DGEMM ', INFO ) + RETURN + END IF +* +* Quick return if possible. +* + IF( ( M.EQ.0 ).OR.( N.EQ.0 ).OR. + $ ( ( ( ALPHA.EQ.ZERO ).OR.( K.EQ.0 ) ).AND.( BETA.EQ.ONE ) ) ) + $ RETURN +* +* And if alpha.eq.zero. +* + IF( ALPHA.EQ.ZERO )THEN + IF( BETA.EQ.ZERO )THEN + DO 20, J = 1, N + DO 10, I = 1, M + C( I, J ) = ZERO + 10 CONTINUE + 20 CONTINUE + ELSE + DO 40, J = 1, N + DO 30, I = 1, M + C( I, J ) = BETA*C( I, J ) + 30 CONTINUE + 40 CONTINUE + END IF + RETURN + END IF +* +* Start the operations. +* + IF( NOTB )THEN + IF( NOTA )THEN +* +* Form C := alpha*A*B + beta*C. +* + DO 90, J = 1, N + IF( BETA.EQ.ZERO )THEN + DO 50, I = 1, M + C( I, J ) = ZERO + 50 CONTINUE + ELSE IF( BETA.NE.ONE )THEN + DO 60, I = 1, M + C( I, J ) = BETA*C( I, J ) + 60 CONTINUE + END IF + DO 80, L = 1, K + IF( B( L, J ).NE.ZERO )THEN + TEMP = ALPHA*B( L, J ) + DO 70, I = 1, M + C( I, J ) = C( I, J ) + TEMP*A( I, L ) + 70 CONTINUE + END IF + 80 CONTINUE + 90 CONTINUE + ELSE +* +* Form C := alpha*A'*B + beta*C +* + DO 120, J = 1, N + DO 110, I = 1, M + TEMP = ZERO + DO 100, L = 1, K + TEMP = TEMP + A( L, I )*B( L, J ) + 100 CONTINUE + IF( BETA.EQ.ZERO )THEN + C( I, J ) = ALPHA*TEMP + ELSE + C( I, J ) = ALPHA*TEMP + BETA*C( I, J ) + END IF + 110 CONTINUE + 120 CONTINUE + END IF + ELSE + IF( NOTA )THEN +* +* Form C := alpha*A*B' + beta*C +* + DO 170, J = 1, N + IF( BETA.EQ.ZERO )THEN + DO 130, I = 1, M + C( I, J ) = ZERO + 130 CONTINUE + ELSE IF( BETA.NE.ONE )THEN + DO 140, I = 1, M + C( I, J ) = BETA*C( I, J ) + 140 CONTINUE + END IF + DO 160, L = 1, K + IF( B( J, L ).NE.ZERO )THEN + TEMP = ALPHA*B( J, L ) + DO 150, I = 1, M + C( I, J ) = C( I, J ) + TEMP*A( I, L ) + 150 CONTINUE + END IF + 160 CONTINUE + 170 CONTINUE + ELSE +* +* Form C := alpha*A'*B' + beta*C +* + DO 200, J = 1, N + DO 190, I = 1, M + TEMP = ZERO + DO 180, L = 1, K + TEMP = TEMP + A( L, I )*B( J, L ) + 180 CONTINUE + IF( BETA.EQ.ZERO )THEN + C( I, J ) = ALPHA*TEMP + ELSE + C( I, J ) = ALPHA*TEMP + BETA*C( I, J ) + END IF + 190 CONTINUE + 200 CONTINUE + END IF + END IF +* + RETURN +* +* End of DGEMM . +* + END diff --git a/ext/blas/dgemv.f b/ext/blas/dgemv.f new file mode 100755 index 000000000..8ef80b3a5 --- /dev/null +++ b/ext/blas/dgemv.f @@ -0,0 +1,261 @@ + SUBROUTINE DGEMV ( TRANS, M, N, ALPHA, A, LDA, X, INCX, + $ BETA, Y, INCY ) +* .. Scalar Arguments .. + DOUBLE PRECISION ALPHA, BETA + INTEGER INCX, INCY, LDA, M, N + CHARACTER*1 TRANS +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), X( * ), Y( * ) +* .. +* +* Purpose +* ======= +* +* DGEMV performs one of the matrix-vector operations +* +* y := alpha*A*x + beta*y, or y := alpha*A'*x + beta*y, +* +* where alpha and beta are scalars, x and y are vectors and A is an +* m by n matrix. +* +* Parameters +* ========== +* +* TRANS - CHARACTER*1. +* On entry, TRANS specifies the operation to be performed as +* follows: +* +* TRANS = 'N' or 'n' y := alpha*A*x + beta*y. +* +* TRANS = 'T' or 't' y := alpha*A'*x + beta*y. +* +* TRANS = 'C' or 'c' y := alpha*A'*x + beta*y. +* +* Unchanged on exit. +* +* M - INTEGER. +* On entry, M specifies the number of rows of the matrix A. +* M must be at least zero. +* Unchanged on exit. +* +* N - INTEGER. +* On entry, N specifies the number of columns of the matrix A. +* N must be at least zero. +* Unchanged on exit. +* +* ALPHA - DOUBLE PRECISION. +* On entry, ALPHA specifies the scalar alpha. +* Unchanged on exit. +* +* A - DOUBLE PRECISION array of DIMENSION ( LDA, n ). +* Before entry, the leading m by n part of the array A must +* contain the matrix of coefficients. +* Unchanged on exit. +* +* LDA - INTEGER. +* On entry, LDA specifies the first dimension of A as declared +* in the calling (sub) program. LDA must be at least +* max( 1, m ). +* Unchanged on exit. +* +* X - DOUBLE PRECISION array of DIMENSION at least +* ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n' +* and at least +* ( 1 + ( m - 1 )*abs( INCX ) ) otherwise. +* Before entry, the incremented array X must contain the +* vector x. +* Unchanged on exit. +* +* INCX - INTEGER. +* On entry, INCX specifies the increment for the elements of +* X. INCX must not be zero. +* Unchanged on exit. +* +* BETA - DOUBLE PRECISION. +* On entry, BETA specifies the scalar beta. When BETA is +* supplied as zero then Y need not be set on input. +* Unchanged on exit. +* +* Y - DOUBLE PRECISION array of DIMENSION at least +* ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n' +* and at least +* ( 1 + ( n - 1 )*abs( INCY ) ) otherwise. +* Before entry with BETA non-zero, the incremented array Y +* must contain the vector y. On exit, Y is overwritten by the +* updated vector y. +* +* INCY - INTEGER. +* On entry, INCY specifies the increment for the elements of +* Y. INCY must not be zero. +* Unchanged on exit. +* +* +* Level 2 Blas routine. +* +* -- Written on 22-October-1986. +* Jack Dongarra, Argonne National Lab. +* Jeremy Du Croz, Nag Central Office. +* Sven Hammarling, Nag Central Office. +* Richard Hanson, Sandia National Labs. +* +* +* .. Parameters .. + DOUBLE PRECISION ONE , ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. Local Scalars .. + DOUBLE PRECISION TEMP + INTEGER I, INFO, IX, IY, J, JX, JY, KX, KY, LENX, LENY +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. External Subroutines .. + EXTERNAL XERBLA +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + IF ( .NOT.LSAME( TRANS, 'N' ).AND. + $ .NOT.LSAME( TRANS, 'T' ).AND. + $ .NOT.LSAME( TRANS, 'C' ) )THEN + INFO = 1 + ELSE IF( M.LT.0 )THEN + INFO = 2 + ELSE IF( N.LT.0 )THEN + INFO = 3 + ELSE IF( LDA.LT.MAX( 1, M ) )THEN + INFO = 6 + ELSE IF( INCX.EQ.0 )THEN + INFO = 8 + ELSE IF( INCY.EQ.0 )THEN + INFO = 11 + END IF + IF( INFO.NE.0 )THEN + CALL XERBLA( 'DGEMV ', INFO ) + RETURN + END IF +* +* Quick return if possible. +* + IF( ( M.EQ.0 ).OR.( N.EQ.0 ).OR. + $ ( ( ALPHA.EQ.ZERO ).AND.( BETA.EQ.ONE ) ) ) + $ RETURN +* +* Set LENX and LENY, the lengths of the vectors x and y, and set +* up the start points in X and Y. +* + IF( LSAME( TRANS, 'N' ) )THEN + LENX = N + LENY = M + ELSE + LENX = M + LENY = N + END IF + IF( INCX.GT.0 )THEN + KX = 1 + ELSE + KX = 1 - ( LENX - 1 )*INCX + END IF + IF( INCY.GT.0 )THEN + KY = 1 + ELSE + KY = 1 - ( LENY - 1 )*INCY + END IF +* +* Start the operations. In this version the elements of A are +* accessed sequentially with one pass through A. +* +* First form y := beta*y. +* + IF( BETA.NE.ONE )THEN + IF( INCY.EQ.1 )THEN + IF( BETA.EQ.ZERO )THEN + DO 10, I = 1, LENY + Y( I ) = ZERO + 10 CONTINUE + ELSE + DO 20, I = 1, LENY + Y( I ) = BETA*Y( I ) + 20 CONTINUE + END IF + ELSE + IY = KY + IF( BETA.EQ.ZERO )THEN + DO 30, I = 1, LENY + Y( IY ) = ZERO + IY = IY + INCY + 30 CONTINUE + ELSE + DO 40, I = 1, LENY + Y( IY ) = BETA*Y( IY ) + IY = IY + INCY + 40 CONTINUE + END IF + END IF + END IF + IF( ALPHA.EQ.ZERO ) + $ RETURN + IF( LSAME( TRANS, 'N' ) )THEN +* +* Form y := alpha*A*x + y. +* + JX = KX + IF( INCY.EQ.1 )THEN + DO 60, J = 1, N + IF( X( JX ).NE.ZERO )THEN + TEMP = ALPHA*X( JX ) + DO 50, I = 1, M + Y( I ) = Y( I ) + TEMP*A( I, J ) + 50 CONTINUE + END IF + JX = JX + INCX + 60 CONTINUE + ELSE + DO 80, J = 1, N + IF( X( JX ).NE.ZERO )THEN + TEMP = ALPHA*X( JX ) + IY = KY + DO 70, I = 1, M + Y( IY ) = Y( IY ) + TEMP*A( I, J ) + IY = IY + INCY + 70 CONTINUE + END IF + JX = JX + INCX + 80 CONTINUE + END IF + ELSE +* +* Form y := alpha*A'*x + y. +* + JY = KY + IF( INCX.EQ.1 )THEN + DO 100, J = 1, N + TEMP = ZERO + DO 90, I = 1, M + TEMP = TEMP + A( I, J )*X( I ) + 90 CONTINUE + Y( JY ) = Y( JY ) + ALPHA*TEMP + JY = JY + INCY + 100 CONTINUE + ELSE + DO 120, J = 1, N + TEMP = ZERO + IX = KX + DO 110, I = 1, M + TEMP = TEMP + A( I, J )*X( IX ) + IX = IX + INCX + 110 CONTINUE + Y( JY ) = Y( JY ) + ALPHA*TEMP + JY = JY + INCY + 120 CONTINUE + END IF + END IF +* + RETURN +* +* End of DGEMV . +* + END diff --git a/ext/blas/dger.f b/ext/blas/dger.f new file mode 100755 index 000000000..d316000ab --- /dev/null +++ b/ext/blas/dger.f @@ -0,0 +1,157 @@ + SUBROUTINE DGER ( M, N, ALPHA, X, INCX, Y, INCY, A, LDA ) +* .. Scalar Arguments .. + DOUBLE PRECISION ALPHA + INTEGER INCX, INCY, LDA, M, N +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), X( * ), Y( * ) +* .. +* +* Purpose +* ======= +* +* DGER performs the rank 1 operation +* +* A := alpha*x*y' + A, +* +* where alpha is a scalar, x is an m element vector, y is an n element +* vector and A is an m by n matrix. +* +* Parameters +* ========== +* +* M - INTEGER. +* On entry, M specifies the number of rows of the matrix A. +* M must be at least zero. +* Unchanged on exit. +* +* N - INTEGER. +* On entry, N specifies the number of columns of the matrix A. +* N must be at least zero. +* Unchanged on exit. +* +* ALPHA - DOUBLE PRECISION. +* On entry, ALPHA specifies the scalar alpha. +* Unchanged on exit. +* +* X - DOUBLE PRECISION array of dimension at least +* ( 1 + ( m - 1 )*abs( INCX ) ). +* Before entry, the incremented array X must contain the m +* element vector x. +* Unchanged on exit. +* +* INCX - INTEGER. +* On entry, INCX specifies the increment for the elements of +* X. INCX must not be zero. +* Unchanged on exit. +* +* Y - DOUBLE PRECISION array of dimension at least +* ( 1 + ( n - 1 )*abs( INCY ) ). +* Before entry, the incremented array Y must contain the n +* element vector y. +* Unchanged on exit. +* +* INCY - INTEGER. +* On entry, INCY specifies the increment for the elements of +* Y. INCY must not be zero. +* Unchanged on exit. +* +* A - DOUBLE PRECISION array of DIMENSION ( LDA, n ). +* Before entry, the leading m by n part of the array A must +* contain the matrix of coefficients. On exit, A is +* overwritten by the updated matrix. +* +* LDA - INTEGER. +* On entry, LDA specifies the first dimension of A as declared +* in the calling (sub) program. LDA must be at least +* max( 1, m ). +* Unchanged on exit. +* +* +* Level 2 Blas routine. +* +* -- Written on 22-October-1986. +* Jack Dongarra, Argonne National Lab. +* Jeremy Du Croz, Nag Central Office. +* Sven Hammarling, Nag Central Office. +* Richard Hanson, Sandia National Labs. +* +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D+0 ) +* .. Local Scalars .. + DOUBLE PRECISION TEMP + INTEGER I, INFO, IX, J, JY, KX +* .. External Subroutines .. + EXTERNAL XERBLA +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + IF ( M.LT.0 )THEN + INFO = 1 + ELSE IF( N.LT.0 )THEN + INFO = 2 + ELSE IF( INCX.EQ.0 )THEN + INFO = 5 + ELSE IF( INCY.EQ.0 )THEN + INFO = 7 + ELSE IF( LDA.LT.MAX( 1, M ) )THEN + INFO = 9 + END IF + IF( INFO.NE.0 )THEN + CALL XERBLA( 'DGER ', INFO ) + RETURN + END IF +* +* Quick return if possible. +* + IF( ( M.EQ.0 ).OR.( N.EQ.0 ).OR.( ALPHA.EQ.ZERO ) ) + $ RETURN +* +* Start the operations. In this version the elements of A are +* accessed sequentially with one pass through A. +* + IF( INCY.GT.0 )THEN + JY = 1 + ELSE + JY = 1 - ( N - 1 )*INCY + END IF + IF( INCX.EQ.1 )THEN + DO 20, J = 1, N + IF( Y( JY ).NE.ZERO )THEN + TEMP = ALPHA*Y( JY ) + DO 10, I = 1, M + A( I, J ) = A( I, J ) + X( I )*TEMP + 10 CONTINUE + END IF + JY = JY + INCY + 20 CONTINUE + ELSE + IF( INCX.GT.0 )THEN + KX = 1 + ELSE + KX = 1 - ( M - 1 )*INCX + END IF + DO 40, J = 1, N + IF( Y( JY ).NE.ZERO )THEN + TEMP = ALPHA*Y( JY ) + IX = KX + DO 30, I = 1, M + A( I, J ) = A( I, J ) + X( IX )*TEMP + IX = IX + INCX + 30 CONTINUE + END IF + JY = JY + INCY + 40 CONTINUE + END IF +* + RETURN +* +* End of DGER . +* + END diff --git a/ext/blas/dnrm2.f b/ext/blas/dnrm2.f new file mode 100755 index 000000000..119d0477e --- /dev/null +++ b/ext/blas/dnrm2.f @@ -0,0 +1,60 @@ + DOUBLE PRECISION FUNCTION DNRM2 ( N, X, INCX ) +* .. Scalar Arguments .. + INTEGER INCX, N +* .. Array Arguments .. + DOUBLE PRECISION X( * ) +* .. +* +* DNRM2 returns the euclidean norm of a vector via the function +* name, so that +* +* DNRM2 := sqrt( x'*x ) +* +* +* +* -- This version written on 25-October-1982. +* Modified on 14-October-1993 to inline the call to DLASSQ. +* Sven Hammarling, Nag Ltd. +* +* +* .. Parameters .. + DOUBLE PRECISION ONE , ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. Local Scalars .. + INTEGER IX + DOUBLE PRECISION ABSXI, NORM, SCALE, SSQ +* .. Intrinsic Functions .. + INTRINSIC ABS, SQRT +* .. +* .. Executable Statements .. + IF( N.LT.1 .OR. INCX.LT.1 )THEN + NORM = ZERO + ELSE IF( N.EQ.1 )THEN + NORM = ABS( X( 1 ) ) + ELSE + SCALE = ZERO + SSQ = ONE +* The following loop is equivalent to this call to the LAPACK +* auxiliary routine: +* CALL DLASSQ( N, X, INCX, SCALE, SSQ ) +* + DO 10, IX = 1, 1 + ( N - 1 )*INCX, INCX + IF( X( IX ).NE.ZERO )THEN + ABSXI = ABS( X( IX ) ) + IF( SCALE.LT.ABSXI )THEN + SSQ = ONE + SSQ*( SCALE/ABSXI )**2 + SCALE = ABSXI + ELSE + SSQ = SSQ + ( ABSXI/SCALE )**2 + END IF + END IF + 10 CONTINUE + NORM = SCALE * SQRT( SSQ ) + END IF +* + DNRM2 = NORM + RETURN +* +* End of DNRM2. +* + END diff --git a/ext/blas/drot.f b/ext/blas/drot.f new file mode 100755 index 000000000..b9ea3bd91 --- /dev/null +++ b/ext/blas/drot.f @@ -0,0 +1,37 @@ + subroutine drot (n,dx,incx,dy,incy,c,s) +c +c applies a plane rotation. +c jack dongarra, linpack, 3/11/78. +c modified 12/3/93, array(1) declarations changed to array(*) +c + double precision dx(*),dy(*),dtemp,c,s + integer i,incx,incy,ix,iy,n +c + if(n.le.0)return + if(incx.eq.1.and.incy.eq.1)go to 20 +c +c code for unequal increments or equal increments not equal +c to 1 +c + ix = 1 + iy = 1 + if(incx.lt.0)ix = (-n+1)*incx + 1 + if(incy.lt.0)iy = (-n+1)*incy + 1 + do 10 i = 1,n + dtemp = c*dx(ix) + s*dy(iy) + dy(iy) = c*dy(iy) - s*dx(ix) + dx(ix) = dtemp + ix = ix + incx + iy = iy + incy + 10 continue + return +c +c code for both increments equal to 1 +c + 20 do 30 i = 1,n + dtemp = c*dx(i) + s*dy(i) + dy(i) = c*dy(i) - s*dx(i) + dx(i) = dtemp + 30 continue + return + end diff --git a/ext/blas/drotg.f b/ext/blas/drotg.f new file mode 100755 index 000000000..67838e2cb --- /dev/null +++ b/ext/blas/drotg.f @@ -0,0 +1,27 @@ + subroutine drotg(da,db,c,s) +c +c construct givens plane rotation. +c jack dongarra, linpack, 3/11/78. +c + double precision da,db,c,s,roe,scale,r,z +c + roe = db + if( dabs(da) .gt. dabs(db) ) roe = da + scale = dabs(da) + dabs(db) + if( scale .ne. 0.0d0 ) go to 10 + c = 1.0d0 + s = 0.0d0 + r = 0.0d0 + z = 0.0d0 + go to 20 + 10 r = scale*dsqrt((da/scale)**2 + (db/scale)**2) + r = dsign(1.0d0,roe)*r + c = da/r + s = db/r + z = 1.0d0 + if( dabs(da) .gt. dabs(db) ) z = s + if( dabs(db) .ge. dabs(da) .and. c .ne. 0.0d0 ) z = 1.0d0/c + 20 da = r + db = z + return + end diff --git a/ext/blas/drotm.f b/ext/blas/drotm.f new file mode 100755 index 000000000..9a99eb7d1 --- /dev/null +++ b/ext/blas/drotm.f @@ -0,0 +1,108 @@ + SUBROUTINE DROTM (N,DX,INCX,DY,INCY,DPARAM) +C +C APPLY THE MODIFIED GIVENS TRANSFORMATION, H, TO THE 2 BY N MATRIX +C +C (DX**T) , WHERE **T INDICATES TRANSPOSE. THE ELEMENTS OF DX ARE IN +C (DY**T) +C +C DX(LX+I*INCX), I = 0 TO N-1, WHERE LX = 1 IF INCX .GE. 0, ELSE +C LX = (-INCX)*N, AND SIMILARLY FOR SY USING LY AND INCY. +C WITH DPARAM(1)=DFLAG, H HAS ONE OF THE FOLLOWING FORMS.. +C +C DFLAG=-1.D0 DFLAG=0.D0 DFLAG=1.D0 DFLAG=-2.D0 +C +C (DH11 DH12) (1.D0 DH12) (DH11 1.D0) (1.D0 0.D0) +C H=( ) ( ) ( ) ( ) +C (DH21 DH22), (DH21 1.D0), (-1.D0 DH22), (0.D0 1.D0). +C SEE DROTMG FOR A DESCRIPTION OF DATA STORAGE IN DPARAM. +C + DOUBLE PRECISION DFLAG,DH12,DH22,DX,TWO,Z,DH11,DH21, + 1 DPARAM,DY,W,ZERO + DIMENSION DX(1),DY(1),DPARAM(5) + DATA ZERO,TWO/0.D0,2.D0/ +C + DFLAG=DPARAM(1) + IF(N .LE. 0 .OR.(DFLAG+TWO.EQ.ZERO)) GO TO 140 + IF(.NOT.(INCX.EQ.INCY.AND. INCX .GT.0)) GO TO 70 +C + NSTEPS=N*INCX + IF(DFLAG) 50,10,30 + 10 CONTINUE + DH12=DPARAM(4) + DH21=DPARAM(3) + DO 20 I=1,NSTEPS,INCX + W=DX(I) + Z=DY(I) + DX(I)=W+Z*DH12 + DY(I)=W*DH21+Z + 20 CONTINUE + GO TO 140 + 30 CONTINUE + DH11=DPARAM(2) + DH22=DPARAM(5) + DO 40 I=1,NSTEPS,INCX + W=DX(I) + Z=DY(I) + DX(I)=W*DH11+Z + DY(I)=-W+DH22*Z + 40 CONTINUE + GO TO 140 + 50 CONTINUE + DH11=DPARAM(2) + DH12=DPARAM(4) + DH21=DPARAM(3) + DH22=DPARAM(5) + DO 60 I=1,NSTEPS,INCX + W=DX(I) + Z=DY(I) + DX(I)=W*DH11+Z*DH12 + DY(I)=W*DH21+Z*DH22 + 60 CONTINUE + GO TO 140 + 70 CONTINUE + KX=1 + KY=1 + IF(INCX .LT. 0) KX=1+(1-N)*INCX + IF(INCY .LT. 0) KY=1+(1-N)*INCY +C + IF(DFLAG)120,80,100 + 80 CONTINUE + DH12=DPARAM(4) + DH21=DPARAM(3) + DO 90 I=1,N + W=DX(KX) + Z=DY(KY) + DX(KX)=W+Z*DH12 + DY(KY)=W*DH21+Z + KX=KX+INCX + KY=KY+INCY + 90 CONTINUE + GO TO 140 + 100 CONTINUE + DH11=DPARAM(2) + DH22=DPARAM(5) + DO 110 I=1,N + W=DX(KX) + Z=DY(KY) + DX(KX)=W*DH11+Z + DY(KY)=-W+DH22*Z + KX=KX+INCX + KY=KY+INCY + 110 CONTINUE + GO TO 140 + 120 CONTINUE + DH11=DPARAM(2) + DH12=DPARAM(4) + DH21=DPARAM(3) + DH22=DPARAM(5) + DO 130 I=1,N + W=DX(KX) + Z=DY(KY) + DX(KX)=W*DH11+Z*DH12 + DY(KY)=W*DH21+Z*DH22 + KX=KX+INCX + KY=KY+INCY + 130 CONTINUE + 140 CONTINUE + RETURN + END diff --git a/ext/blas/drotmg.f b/ext/blas/drotmg.f new file mode 100755 index 000000000..0068594c0 --- /dev/null +++ b/ext/blas/drotmg.f @@ -0,0 +1,169 @@ + SUBROUTINE DROTMG (DD1,DD2,DX1,DY1,DPARAM) +C +C CONSTRUCT THE MODIFIED GIVENS TRANSFORMATION MATRIX H WHICH ZEROS +C THE SECOND COMPONENT OF THE 2-VECTOR (DSQRT(DD1)*DX1,DSQRT(DD2)* +C DY2)**T. +C WITH DPARAM(1)=DFLAG, H HAS ONE OF THE FOLLOWING FORMS.. +C +C DFLAG=-1.D0 DFLAG=0.D0 DFLAG=1.D0 DFLAG=-2.D0 +C +C (DH11 DH12) (1.D0 DH12) (DH11 1.D0) (1.D0 0.D0) +C H=( ) ( ) ( ) ( ) +C (DH21 DH22), (DH21 1.D0), (-1.D0 DH22), (0.D0 1.D0). +C LOCATIONS 2-4 OF DPARAM CONTAIN DH11, DH21, DH12, AND DH22 +C RESPECTIVELY. (VALUES OF 1.D0, -1.D0, OR 0.D0 IMPLIED BY THE +C VALUE OF DPARAM(1) ARE NOT STORED IN DPARAM.) +C +C THE VALUES OF GAMSQ AND RGAMSQ SET IN THE DATA STATEMENT MAY BE +C INEXACT. THIS IS OK AS THEY ARE ONLY USED FOR TESTING THE SIZE +C OF DD1 AND DD2. ALL ACTUAL SCALING OF DATA IS DONE USING GAM. +C + DOUBLE PRECISION GAM,ONE,RGAMSQ,DD2,DH11,DH21,DPARAM,DP2, + 1 DQ2,DU,DY1,ZERO,GAMSQ,DD1,DFLAG,DH12,DH22,DP1,DQ1, + 2 DTEMP,DX1,TWO + DIMENSION DPARAM(5) +C + DATA ZERO,ONE,TWO /0.D0,1.D0,2.D0/ + DATA GAM,GAMSQ,RGAMSQ/4096.D0,16777216.D0,5.9604645D-8/ + IF(.NOT. DD1 .LT. ZERO) GO TO 10 +C GO ZERO-H-D-AND-DX1.. + GO TO 60 + 10 CONTINUE +C CASE-DD1-NONNEGATIVE + DP2=DD2*DY1 + IF(.NOT. DP2 .EQ. ZERO) GO TO 20 + DFLAG=-TWO + GO TO 260 +C REGULAR-CASE.. + 20 CONTINUE + DP1=DD1*DX1 + DQ2=DP2*DY1 + DQ1=DP1*DX1 +C + IF(.NOT. DABS(DQ1) .GT. DABS(DQ2)) GO TO 40 + DH21=-DY1/DX1 + DH12=DP2/DP1 +C + DU=ONE-DH12*DH21 +C + IF(.NOT. DU .LE. ZERO) GO TO 30 +C GO ZERO-H-D-AND-DX1.. + GO TO 60 + 30 CONTINUE + DFLAG=ZERO + DD1=DD1/DU + DD2=DD2/DU + DX1=DX1*DU +C GO SCALE-CHECK.. + GO TO 100 + 40 CONTINUE + IF(.NOT. DQ2 .LT. ZERO) GO TO 50 +C GO ZERO-H-D-AND-DX1.. + GO TO 60 + 50 CONTINUE + DFLAG=ONE + DH11=DP1/DP2 + DH22=DX1/DY1 + DU=ONE+DH11*DH22 + DTEMP=DD2/DU + DD2=DD1/DU + DD1=DTEMP + DX1=DY1*DU +C GO SCALE-CHECK + GO TO 100 +C PROCEDURE..ZERO-H-D-AND-DX1.. + 60 CONTINUE + DFLAG=-ONE + DH11=ZERO + DH12=ZERO + DH21=ZERO + DH22=ZERO +C + DD1=ZERO + DD2=ZERO + DX1=ZERO +C RETURN.. + GO TO 220 +C PROCEDURE..FIX-H.. + 70 CONTINUE + IF(.NOT. DFLAG .GE. ZERO) GO TO 90 +C + IF(.NOT. DFLAG .EQ. ZERO) GO TO 80 + DH11=ONE + DH22=ONE + DFLAG=-ONE + GO TO 90 + 80 CONTINUE + DH21=-ONE + DH12=ONE + DFLAG=-ONE + 90 CONTINUE + GO TO IGO,(120,150,180,210) +C PROCEDURE..SCALE-CHECK + 100 CONTINUE + 110 CONTINUE + IF(.NOT. DD1 .LE. RGAMSQ) GO TO 130 + IF(DD1 .EQ. ZERO) GO TO 160 + ASSIGN 120 TO IGO +C FIX-H.. + GO TO 70 + 120 CONTINUE + DD1=DD1*GAM**2 + DX1=DX1/GAM + DH11=DH11/GAM + DH12=DH12/GAM + GO TO 110 + 130 CONTINUE + 140 CONTINUE + IF(.NOT. DD1 .GE. GAMSQ) GO TO 160 + ASSIGN 150 TO IGO +C FIX-H.. + GO TO 70 + 150 CONTINUE + DD1=DD1/GAM**2 + DX1=DX1*GAM + DH11=DH11*GAM + DH12=DH12*GAM + GO TO 140 + 160 CONTINUE + 170 CONTINUE + IF(.NOT. DABS(DD2) .LE. RGAMSQ) GO TO 190 + IF(DD2 .EQ. ZERO) GO TO 220 + ASSIGN 180 TO IGO +C FIX-H.. + GO TO 70 + 180 CONTINUE + DD2=DD2*GAM**2 + DH21=DH21/GAM + DH22=DH22/GAM + GO TO 170 + 190 CONTINUE + 200 CONTINUE + IF(.NOT. DABS(DD2) .GE. GAMSQ) GO TO 220 + ASSIGN 210 TO IGO +C FIX-H.. + GO TO 70 + 210 CONTINUE + DD2=DD2/GAM**2 + DH21=DH21*GAM + DH22=DH22*GAM + GO TO 200 + 220 CONTINUE + IF(DFLAG)250,230,240 + 230 CONTINUE + DPARAM(3)=DH21 + DPARAM(4)=DH12 + GO TO 260 + 240 CONTINUE + DPARAM(2)=DH11 + DPARAM(5)=DH22 + GO TO 260 + 250 CONTINUE + DPARAM(2)=DH11 + DPARAM(3)=DH21 + DPARAM(4)=DH12 + DPARAM(5)=DH22 + 260 CONTINUE + DPARAM(1)=DFLAG + RETURN + END diff --git a/ext/blas/dsbmv.f b/ext/blas/dsbmv.f new file mode 100755 index 000000000..272042af6 --- /dev/null +++ b/ext/blas/dsbmv.f @@ -0,0 +1,303 @@ + SUBROUTINE DSBMV ( UPLO, N, K, ALPHA, A, LDA, X, INCX, + $ BETA, Y, INCY ) +* .. Scalar Arguments .. + DOUBLE PRECISION ALPHA, BETA + INTEGER INCX, INCY, K, LDA, N + CHARACTER*1 UPLO +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), X( * ), Y( * ) +* .. +* +* Purpose +* ======= +* +* DSBMV performs the matrix-vector operation +* +* y := alpha*A*x + beta*y, +* +* where alpha and beta are scalars, x and y are n element vectors and +* A is an n by n symmetric band matrix, with k super-diagonals. +* +* Parameters +* ========== +* +* UPLO - CHARACTER*1. +* On entry, UPLO specifies whether the upper or lower +* triangular part of the band matrix A is being supplied as +* follows: +* +* UPLO = 'U' or 'u' The upper triangular part of A is +* being supplied. +* +* UPLO = 'L' or 'l' The lower triangular part of A is +* being supplied. +* +* Unchanged on exit. +* +* N - INTEGER. +* On entry, N specifies the order of the matrix A. +* N must be at least zero. +* Unchanged on exit. +* +* K - INTEGER. +* On entry, K specifies the number of super-diagonals of the +* matrix A. K must satisfy 0 .le. K. +* Unchanged on exit. +* +* ALPHA - DOUBLE PRECISION. +* On entry, ALPHA specifies the scalar alpha. +* Unchanged on exit. +* +* A - DOUBLE PRECISION array of DIMENSION ( LDA, n ). +* Before entry with UPLO = 'U' or 'u', the leading ( k + 1 ) +* by n part of the array A must contain the upper triangular +* band part of the symmetric matrix, supplied column by +* column, with the leading diagonal of the matrix in row +* ( k + 1 ) of the array, the first super-diagonal starting at +* position 2 in row k, and so on. The top left k by k triangle +* of the array A is not referenced. +* The following program segment will transfer the upper +* triangular part of a symmetric band matrix from conventional +* full matrix storage to band storage: +* +* DO 20, J = 1, N +* M = K + 1 - J +* DO 10, I = MAX( 1, J - K ), J +* A( M + I, J ) = matrix( I, J ) +* 10 CONTINUE +* 20 CONTINUE +* +* Before entry with UPLO = 'L' or 'l', the leading ( k + 1 ) +* by n part of the array A must contain the lower triangular +* band part of the symmetric matrix, supplied column by +* column, with the leading diagonal of the matrix in row 1 of +* the array, the first sub-diagonal starting at position 1 in +* row 2, and so on. The bottom right k by k triangle of the +* array A is not referenced. +* The following program segment will transfer the lower +* triangular part of a symmetric band matrix from conventional +* full matrix storage to band storage: +* +* DO 20, J = 1, N +* M = 1 - J +* DO 10, I = J, MIN( N, J + K ) +* A( M + I, J ) = matrix( I, J ) +* 10 CONTINUE +* 20 CONTINUE +* +* Unchanged on exit. +* +* LDA - INTEGER. +* On entry, LDA specifies the first dimension of A as declared +* in the calling (sub) program. LDA must be at least +* ( k + 1 ). +* Unchanged on exit. +* +* X - DOUBLE PRECISION array of DIMENSION at least +* ( 1 + ( n - 1 )*abs( INCX ) ). +* Before entry, the incremented array X must contain the +* vector x. +* Unchanged on exit. +* +* INCX - INTEGER. +* On entry, INCX specifies the increment for the elements of +* X. INCX must not be zero. +* Unchanged on exit. +* +* BETA - DOUBLE PRECISION. +* On entry, BETA specifies the scalar beta. +* Unchanged on exit. +* +* Y - DOUBLE PRECISION array of DIMENSION at least +* ( 1 + ( n - 1 )*abs( INCY ) ). +* Before entry, the incremented array Y must contain the +* vector y. On exit, Y is overwritten by the updated vector y. +* +* INCY - INTEGER. +* On entry, INCY specifies the increment for the elements of +* Y. INCY must not be zero. +* Unchanged on exit. +* +* +* Level 2 Blas routine. +* +* -- Written on 22-October-1986. +* Jack Dongarra, Argonne National Lab. +* Jeremy Du Croz, Nag Central Office. +* Sven Hammarling, Nag Central Office. +* Richard Hanson, Sandia National Labs. +* +* +* .. Parameters .. + DOUBLE PRECISION ONE , ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. Local Scalars .. + DOUBLE PRECISION TEMP1, TEMP2 + INTEGER I, INFO, IX, IY, J, JX, JY, KPLUS1, KX, KY, L +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. External Subroutines .. + EXTERNAL XERBLA +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + IF ( .NOT.LSAME( UPLO, 'U' ).AND. + $ .NOT.LSAME( UPLO, 'L' ) )THEN + INFO = 1 + ELSE IF( N.LT.0 )THEN + INFO = 2 + ELSE IF( K.LT.0 )THEN + INFO = 3 + ELSE IF( LDA.LT.( K + 1 ) )THEN + INFO = 6 + ELSE IF( INCX.EQ.0 )THEN + INFO = 8 + ELSE IF( INCY.EQ.0 )THEN + INFO = 11 + END IF + IF( INFO.NE.0 )THEN + CALL XERBLA( 'DSBMV ', INFO ) + RETURN + END IF +* +* Quick return if possible. +* + IF( ( N.EQ.0 ).OR.( ( ALPHA.EQ.ZERO ).AND.( BETA.EQ.ONE ) ) ) + $ RETURN +* +* Set up the start points in X and Y. +* + IF( INCX.GT.0 )THEN + KX = 1 + ELSE + KX = 1 - ( N - 1 )*INCX + END IF + IF( INCY.GT.0 )THEN + KY = 1 + ELSE + KY = 1 - ( N - 1 )*INCY + END IF +* +* Start the operations. In this version the elements of the array A +* are accessed sequentially with one pass through A. +* +* First form y := beta*y. +* + IF( BETA.NE.ONE )THEN + IF( INCY.EQ.1 )THEN + IF( BETA.EQ.ZERO )THEN + DO 10, I = 1, N + Y( I ) = ZERO + 10 CONTINUE + ELSE + DO 20, I = 1, N + Y( I ) = BETA*Y( I ) + 20 CONTINUE + END IF + ELSE + IY = KY + IF( BETA.EQ.ZERO )THEN + DO 30, I = 1, N + Y( IY ) = ZERO + IY = IY + INCY + 30 CONTINUE + ELSE + DO 40, I = 1, N + Y( IY ) = BETA*Y( IY ) + IY = IY + INCY + 40 CONTINUE + END IF + END IF + END IF + IF( ALPHA.EQ.ZERO ) + $ RETURN + IF( LSAME( UPLO, 'U' ) )THEN +* +* Form y when upper triangle of A is stored. +* + KPLUS1 = K + 1 + IF( ( INCX.EQ.1 ).AND.( INCY.EQ.1 ) )THEN + DO 60, J = 1, N + TEMP1 = ALPHA*X( J ) + TEMP2 = ZERO + L = KPLUS1 - J + DO 50, I = MAX( 1, J - K ), J - 1 + Y( I ) = Y( I ) + TEMP1*A( L + I, J ) + TEMP2 = TEMP2 + A( L + I, J )*X( I ) + 50 CONTINUE + Y( J ) = Y( J ) + TEMP1*A( KPLUS1, J ) + ALPHA*TEMP2 + 60 CONTINUE + ELSE + JX = KX + JY = KY + DO 80, J = 1, N + TEMP1 = ALPHA*X( JX ) + TEMP2 = ZERO + IX = KX + IY = KY + L = KPLUS1 - J + DO 70, I = MAX( 1, J - K ), J - 1 + Y( IY ) = Y( IY ) + TEMP1*A( L + I, J ) + TEMP2 = TEMP2 + A( L + I, J )*X( IX ) + IX = IX + INCX + IY = IY + INCY + 70 CONTINUE + Y( JY ) = Y( JY ) + TEMP1*A( KPLUS1, J ) + ALPHA*TEMP2 + JX = JX + INCX + JY = JY + INCY + IF( J.GT.K )THEN + KX = KX + INCX + KY = KY + INCY + END IF + 80 CONTINUE + END IF + ELSE +* +* Form y when lower triangle of A is stored. +* + IF( ( INCX.EQ.1 ).AND.( INCY.EQ.1 ) )THEN + DO 100, J = 1, N + TEMP1 = ALPHA*X( J ) + TEMP2 = ZERO + Y( J ) = Y( J ) + TEMP1*A( 1, J ) + L = 1 - J + DO 90, I = J + 1, MIN( N, J + K ) + Y( I ) = Y( I ) + TEMP1*A( L + I, J ) + TEMP2 = TEMP2 + A( L + I, J )*X( I ) + 90 CONTINUE + Y( J ) = Y( J ) + ALPHA*TEMP2 + 100 CONTINUE + ELSE + JX = KX + JY = KY + DO 120, J = 1, N + TEMP1 = ALPHA*X( JX ) + TEMP2 = ZERO + Y( JY ) = Y( JY ) + TEMP1*A( 1, J ) + L = 1 - J + IX = JX + IY = JY + DO 110, I = J + 1, MIN( N, J + K ) + IX = IX + INCX + IY = IY + INCY + Y( IY ) = Y( IY ) + TEMP1*A( L + I, J ) + TEMP2 = TEMP2 + A( L + I, J )*X( IX ) + 110 CONTINUE + Y( JY ) = Y( JY ) + ALPHA*TEMP2 + JX = JX + INCX + JY = JY + INCY + 120 CONTINUE + END IF + END IF +* + RETURN +* +* End of DSBMV . +* + END diff --git a/ext/blas/dscal.f b/ext/blas/dscal.f new file mode 100755 index 000000000..e1467faf2 --- /dev/null +++ b/ext/blas/dscal.f @@ -0,0 +1,43 @@ + subroutine dscal(n,da,dx,incx) +c +c scales a vector by a constant. +c uses unrolled loops for increment equal to one. +c jack dongarra, linpack, 3/11/78. +c modified 3/93 to return if incx .le. 0. +c modified 12/3/93, array(1) declarations changed to array(*) +c + double precision da,dx(*) + integer i,incx,m,mp1,n,nincx +c + if( n.le.0 .or. incx.le.0 )return + if(incx.eq.1)go to 20 +c +c code for increment not equal to 1 +c + nincx = n*incx + do 10 i = 1,nincx,incx + dx(i) = da*dx(i) + 10 continue + return +c +c code for increment equal to 1 +c +c +c clean-up loop +c + 20 m = mod(n,5) + if( m .eq. 0 ) go to 40 + do 30 i = 1,m + dx(i) = da*dx(i) + 30 continue + if( n .lt. 5 ) return + 40 mp1 = m + 1 + do 50 i = mp1,n,5 + dx(i) = da*dx(i) + dx(i + 1) = da*dx(i + 1) + dx(i + 2) = da*dx(i + 2) + dx(i + 3) = da*dx(i + 3) + dx(i + 4) = da*dx(i + 4) + 50 continue + return + end diff --git a/ext/blas/dsdot.f b/ext/blas/dsdot.f new file mode 100755 index 000000000..85adb68d6 --- /dev/null +++ b/ext/blas/dsdot.f @@ -0,0 +1,74 @@ +*DECK DSDOT + DOUBLE PRECISION FUNCTION DSDOT (N, SX, INCX, SY, INCY) +C***BEGIN PROLOGUE DSDOT +C***PURPOSE Compute the inner product of two vectors with extended +C precision accumulation and result. +C***LIBRARY SLATEC (BLAS) +C***CATEGORY D1A4 +C***TYPE DOUBLE PRECISION (DSDOT-D, DCDOT-C) +C***KEYWORDS BLAS, COMPLEX VECTORS, DOT PRODUCT, INNER PRODUCT, +C LINEAR ALGEBRA, VECTOR +C***AUTHOR Lawson, C. L., (JPL) +C Hanson, R. J., (SNLA) +C Kincaid, D. R., (U. of Texas) +C Krogh, F. T., (JPL) +C***DESCRIPTION +C +C B L A S Subprogram +C Description of Parameters +C +C --Input-- +C N number of elements in input vector(s) +C SX single precision vector with N elements +C INCX storage spacing between elements of SX +C SY single precision vector with N elements +C INCY storage spacing between elements of SY +C +C --Output-- +C DSDOT double precision dot product (zero if N.LE.0) +C +C Returns D.P. dot product accumulated in D.P., for S.P. SX and SY +C DSDOT = sum for I = 0 to N-1 of SX(LX+I*INCX) * SY(LY+I*INCY), +C where LX = 1 if INCX .GE. 0, else LX = 1+(1-N)*INCX, and LY is +C defined in a similar way using INCY. +C +C***REFERENCES C. L. Lawson, R. J. Hanson, D. R. Kincaid and F. T. +C Krogh, Basic linear algebra subprograms for Fortran +C usage, Algorithm No. 539, Transactions on Mathematical +C Software 5, 3 (September 1979), pp. 308-323. +C***ROUTINES CALLED (NONE) +C***REVISION HISTORY (YYMMDD) +C 791001 DATE WRITTEN +C 890831 Modified array declarations. (WRB) +C 890831 REVISION DATE from Version 3.2 +C 891214 Prologue converted to Version 4.0 format. (BAB) +C 920310 Corrected definition of LX in DESCRIPTION. (WRB) +C 920501 Reformatted the REFERENCES section. (WRB) +C***END PROLOGUE DSDOT + REAL SX(*),SY(*) +C***FIRST EXECUTABLE STATEMENT DSDOT + DSDOT = 0.0D0 + IF (N .LE. 0) RETURN + IF (INCX.EQ.INCY .AND. INCX.GT.0) GO TO 20 +C +C Code for unequal or nonpositive increments. +C + KX = 1 + KY = 1 + IF (INCX .LT. 0) KX = 1+(1-N)*INCX + IF (INCY .LT. 0) KY = 1+(1-N)*INCY + DO 10 I = 1,N + DSDOT = DSDOT + DBLE(SX(KX))*DBLE(SY(KY)) + KX = KX + INCX + KY = KY + INCY + 10 CONTINUE + RETURN +C +C Code for equal, positive, non-unit increments. +C + 20 NS = N*INCX + DO 30 I = 1,NS,INCX + DSDOT = DSDOT + DBLE(SX(I))*DBLE(SY(I)) + 30 CONTINUE + RETURN + END diff --git a/ext/blas/dspmv.f b/ext/blas/dspmv.f new file mode 100755 index 000000000..3ace7bf26 --- /dev/null +++ b/ext/blas/dspmv.f @@ -0,0 +1,262 @@ + SUBROUTINE DSPMV ( UPLO, N, ALPHA, AP, X, INCX, BETA, Y, INCY ) +* .. Scalar Arguments .. + DOUBLE PRECISION ALPHA, BETA + INTEGER INCX, INCY, N + CHARACTER*1 UPLO +* .. Array Arguments .. + DOUBLE PRECISION AP( * ), X( * ), Y( * ) +* .. +* +* Purpose +* ======= +* +* DSPMV performs the matrix-vector operation +* +* y := alpha*A*x + beta*y, +* +* where alpha and beta are scalars, x and y are n element vectors and +* A is an n by n symmetric matrix, supplied in packed form. +* +* Parameters +* ========== +* +* UPLO - CHARACTER*1. +* On entry, UPLO specifies whether the upper or lower +* triangular part of the matrix A is supplied in the packed +* array AP as follows: +* +* UPLO = 'U' or 'u' The upper triangular part of A is +* supplied in AP. +* +* UPLO = 'L' or 'l' The lower triangular part of A is +* supplied in AP. +* +* Unchanged on exit. +* +* N - INTEGER. +* On entry, N specifies the order of the matrix A. +* N must be at least zero. +* Unchanged on exit. +* +* ALPHA - DOUBLE PRECISION. +* On entry, ALPHA specifies the scalar alpha. +* Unchanged on exit. +* +* AP - DOUBLE PRECISION array of DIMENSION at least +* ( ( n*( n + 1 ) )/2 ). +* Before entry with UPLO = 'U' or 'u', the array AP must +* contain the upper triangular part of the symmetric matrix +* packed sequentially, column by column, so that AP( 1 ) +* contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 1, 2 ) +* and a( 2, 2 ) respectively, and so on. +* Before entry with UPLO = 'L' or 'l', the array AP must +* contain the lower triangular part of the symmetric matrix +* packed sequentially, column by column, so that AP( 1 ) +* contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 2, 1 ) +* and a( 3, 1 ) respectively, and so on. +* Unchanged on exit. +* +* X - DOUBLE PRECISION array of dimension at least +* ( 1 + ( n - 1 )*abs( INCX ) ). +* Before entry, the incremented array X must contain the n +* element vector x. +* Unchanged on exit. +* +* INCX - INTEGER. +* On entry, INCX specifies the increment for the elements of +* X. INCX must not be zero. +* Unchanged on exit. +* +* BETA - DOUBLE PRECISION. +* On entry, BETA specifies the scalar beta. When BETA is +* supplied as zero then Y need not be set on input. +* Unchanged on exit. +* +* Y - DOUBLE PRECISION array of dimension at least +* ( 1 + ( n - 1 )*abs( INCY ) ). +* Before entry, the incremented array Y must contain the n +* element vector y. On exit, Y is overwritten by the updated +* vector y. +* +* INCY - INTEGER. +* On entry, INCY specifies the increment for the elements of +* Y. INCY must not be zero. +* Unchanged on exit. +* +* +* Level 2 Blas routine. +* +* -- Written on 22-October-1986. +* Jack Dongarra, Argonne National Lab. +* Jeremy Du Croz, Nag Central Office. +* Sven Hammarling, Nag Central Office. +* Richard Hanson, Sandia National Labs. +* +* +* .. Parameters .. + DOUBLE PRECISION ONE , ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. Local Scalars .. + DOUBLE PRECISION TEMP1, TEMP2 + INTEGER I, INFO, IX, IY, J, JX, JY, K, KK, KX, KY +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. External Subroutines .. + EXTERNAL XERBLA +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + IF ( .NOT.LSAME( UPLO, 'U' ).AND. + $ .NOT.LSAME( UPLO, 'L' ) )THEN + INFO = 1 + ELSE IF( N.LT.0 )THEN + INFO = 2 + ELSE IF( INCX.EQ.0 )THEN + INFO = 6 + ELSE IF( INCY.EQ.0 )THEN + INFO = 9 + END IF + IF( INFO.NE.0 )THEN + CALL XERBLA( 'DSPMV ', INFO ) + RETURN + END IF +* +* Quick return if possible. +* + IF( ( N.EQ.0 ).OR.( ( ALPHA.EQ.ZERO ).AND.( BETA.EQ.ONE ) ) ) + $ RETURN +* +* Set up the start points in X and Y. +* + IF( INCX.GT.0 )THEN + KX = 1 + ELSE + KX = 1 - ( N - 1 )*INCX + END IF + IF( INCY.GT.0 )THEN + KY = 1 + ELSE + KY = 1 - ( N - 1 )*INCY + END IF +* +* Start the operations. In this version the elements of the array AP +* are accessed sequentially with one pass through AP. +* +* First form y := beta*y. +* + IF( BETA.NE.ONE )THEN + IF( INCY.EQ.1 )THEN + IF( BETA.EQ.ZERO )THEN + DO 10, I = 1, N + Y( I ) = ZERO + 10 CONTINUE + ELSE + DO 20, I = 1, N + Y( I ) = BETA*Y( I ) + 20 CONTINUE + END IF + ELSE + IY = KY + IF( BETA.EQ.ZERO )THEN + DO 30, I = 1, N + Y( IY ) = ZERO + IY = IY + INCY + 30 CONTINUE + ELSE + DO 40, I = 1, N + Y( IY ) = BETA*Y( IY ) + IY = IY + INCY + 40 CONTINUE + END IF + END IF + END IF + IF( ALPHA.EQ.ZERO ) + $ RETURN + KK = 1 + IF( LSAME( UPLO, 'U' ) )THEN +* +* Form y when AP contains the upper triangle. +* + IF( ( INCX.EQ.1 ).AND.( INCY.EQ.1 ) )THEN + DO 60, J = 1, N + TEMP1 = ALPHA*X( J ) + TEMP2 = ZERO + K = KK + DO 50, I = 1, J - 1 + Y( I ) = Y( I ) + TEMP1*AP( K ) + TEMP2 = TEMP2 + AP( K )*X( I ) + K = K + 1 + 50 CONTINUE + Y( J ) = Y( J ) + TEMP1*AP( KK + J - 1 ) + ALPHA*TEMP2 + KK = KK + J + 60 CONTINUE + ELSE + JX = KX + JY = KY + DO 80, J = 1, N + TEMP1 = ALPHA*X( JX ) + TEMP2 = ZERO + IX = KX + IY = KY + DO 70, K = KK, KK + J - 2 + Y( IY ) = Y( IY ) + TEMP1*AP( K ) + TEMP2 = TEMP2 + AP( K )*X( IX ) + IX = IX + INCX + IY = IY + INCY + 70 CONTINUE + Y( JY ) = Y( JY ) + TEMP1*AP( KK + J - 1 ) + ALPHA*TEMP2 + JX = JX + INCX + JY = JY + INCY + KK = KK + J + 80 CONTINUE + END IF + ELSE +* +* Form y when AP contains the lower triangle. +* + IF( ( INCX.EQ.1 ).AND.( INCY.EQ.1 ) )THEN + DO 100, J = 1, N + TEMP1 = ALPHA*X( J ) + TEMP2 = ZERO + Y( J ) = Y( J ) + TEMP1*AP( KK ) + K = KK + 1 + DO 90, I = J + 1, N + Y( I ) = Y( I ) + TEMP1*AP( K ) + TEMP2 = TEMP2 + AP( K )*X( I ) + K = K + 1 + 90 CONTINUE + Y( J ) = Y( J ) + ALPHA*TEMP2 + KK = KK + ( N - J + 1 ) + 100 CONTINUE + ELSE + JX = KX + JY = KY + DO 120, J = 1, N + TEMP1 = ALPHA*X( JX ) + TEMP2 = ZERO + Y( JY ) = Y( JY ) + TEMP1*AP( KK ) + IX = JX + IY = JY + DO 110, K = KK + 1, KK + N - J + IX = IX + INCX + IY = IY + INCY + Y( IY ) = Y( IY ) + TEMP1*AP( K ) + TEMP2 = TEMP2 + AP( K )*X( IX ) + 110 CONTINUE + Y( JY ) = Y( JY ) + ALPHA*TEMP2 + JX = JX + INCX + JY = JY + INCY + KK = KK + ( N - J + 1 ) + 120 CONTINUE + END IF + END IF +* + RETURN +* +* End of DSPMV . +* + END diff --git a/ext/blas/dspr.f b/ext/blas/dspr.f new file mode 100755 index 000000000..3da6889c9 --- /dev/null +++ b/ext/blas/dspr.f @@ -0,0 +1,198 @@ + SUBROUTINE DSPR ( UPLO, N, ALPHA, X, INCX, AP ) +* .. Scalar Arguments .. + DOUBLE PRECISION ALPHA + INTEGER INCX, N + CHARACTER*1 UPLO +* .. Array Arguments .. + DOUBLE PRECISION AP( * ), X( * ) +* .. +* +* Purpose +* ======= +* +* DSPR performs the symmetric rank 1 operation +* +* A := alpha*x*x' + A, +* +* where alpha is a real scalar, x is an n element vector and A is an +* n by n symmetric matrix, supplied in packed form. +* +* Parameters +* ========== +* +* UPLO - CHARACTER*1. +* On entry, UPLO specifies whether the upper or lower +* triangular part of the matrix A is supplied in the packed +* array AP as follows: +* +* UPLO = 'U' or 'u' The upper triangular part of A is +* supplied in AP. +* +* UPLO = 'L' or 'l' The lower triangular part of A is +* supplied in AP. +* +* Unchanged on exit. +* +* N - INTEGER. +* On entry, N specifies the order of the matrix A. +* N must be at least zero. +* Unchanged on exit. +* +* ALPHA - DOUBLE PRECISION. +* On entry, ALPHA specifies the scalar alpha. +* Unchanged on exit. +* +* X - DOUBLE PRECISION array of dimension at least +* ( 1 + ( n - 1 )*abs( INCX ) ). +* Before entry, the incremented array X must contain the n +* element vector x. +* Unchanged on exit. +* +* INCX - INTEGER. +* On entry, INCX specifies the increment for the elements of +* X. INCX must not be zero. +* Unchanged on exit. +* +* AP - DOUBLE PRECISION array of DIMENSION at least +* ( ( n*( n + 1 ) )/2 ). +* Before entry with UPLO = 'U' or 'u', the array AP must +* contain the upper triangular part of the symmetric matrix +* packed sequentially, column by column, so that AP( 1 ) +* contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 1, 2 ) +* and a( 2, 2 ) respectively, and so on. On exit, the array +* AP is overwritten by the upper triangular part of the +* updated matrix. +* Before entry with UPLO = 'L' or 'l', the array AP must +* contain the lower triangular part of the symmetric matrix +* packed sequentially, column by column, so that AP( 1 ) +* contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 2, 1 ) +* and a( 3, 1 ) respectively, and so on. On exit, the array +* AP is overwritten by the lower triangular part of the +* updated matrix. +* +* +* Level 2 Blas routine. +* +* -- Written on 22-October-1986. +* Jack Dongarra, Argonne National Lab. +* Jeremy Du Croz, Nag Central Office. +* Sven Hammarling, Nag Central Office. +* Richard Hanson, Sandia National Labs. +* +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D+0 ) +* .. Local Scalars .. + DOUBLE PRECISION TEMP + INTEGER I, INFO, IX, J, JX, K, KK, KX +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. External Subroutines .. + EXTERNAL XERBLA +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + IF ( .NOT.LSAME( UPLO, 'U' ).AND. + $ .NOT.LSAME( UPLO, 'L' ) )THEN + INFO = 1 + ELSE IF( N.LT.0 )THEN + INFO = 2 + ELSE IF( INCX.EQ.0 )THEN + INFO = 5 + END IF + IF( INFO.NE.0 )THEN + CALL XERBLA( 'DSPR ', INFO ) + RETURN + END IF +* +* Quick return if possible. +* + IF( ( N.EQ.0 ).OR.( ALPHA.EQ.ZERO ) ) + $ RETURN +* +* Set the start point in X if the increment is not unity. +* + IF( INCX.LE.0 )THEN + KX = 1 - ( N - 1 )*INCX + ELSE IF( INCX.NE.1 )THEN + KX = 1 + END IF +* +* Start the operations. In this version the elements of the array AP +* are accessed sequentially with one pass through AP. +* + KK = 1 + IF( LSAME( UPLO, 'U' ) )THEN +* +* Form A when upper triangle is stored in AP. +* + IF( INCX.EQ.1 )THEN + DO 20, J = 1, N + IF( X( J ).NE.ZERO )THEN + TEMP = ALPHA*X( J ) + K = KK + DO 10, I = 1, J + AP( K ) = AP( K ) + X( I )*TEMP + K = K + 1 + 10 CONTINUE + END IF + KK = KK + J + 20 CONTINUE + ELSE + JX = KX + DO 40, J = 1, N + IF( X( JX ).NE.ZERO )THEN + TEMP = ALPHA*X( JX ) + IX = KX + DO 30, K = KK, KK + J - 1 + AP( K ) = AP( K ) + X( IX )*TEMP + IX = IX + INCX + 30 CONTINUE + END IF + JX = JX + INCX + KK = KK + J + 40 CONTINUE + END IF + ELSE +* +* Form A when lower triangle is stored in AP. +* + IF( INCX.EQ.1 )THEN + DO 60, J = 1, N + IF( X( J ).NE.ZERO )THEN + TEMP = ALPHA*X( J ) + K = KK + DO 50, I = J, N + AP( K ) = AP( K ) + X( I )*TEMP + K = K + 1 + 50 CONTINUE + END IF + KK = KK + N - J + 1 + 60 CONTINUE + ELSE + JX = KX + DO 80, J = 1, N + IF( X( JX ).NE.ZERO )THEN + TEMP = ALPHA*X( JX ) + IX = JX + DO 70, K = KK, KK + N - J + AP( K ) = AP( K ) + X( IX )*TEMP + IX = IX + INCX + 70 CONTINUE + END IF + JX = JX + INCX + KK = KK + N - J + 1 + 80 CONTINUE + END IF + END IF +* + RETURN +* +* End of DSPR . +* + END diff --git a/ext/blas/dspr2.f b/ext/blas/dspr2.f new file mode 100755 index 000000000..1cfce21b0 --- /dev/null +++ b/ext/blas/dspr2.f @@ -0,0 +1,229 @@ + SUBROUTINE DSPR2 ( UPLO, N, ALPHA, X, INCX, Y, INCY, AP ) +* .. Scalar Arguments .. + DOUBLE PRECISION ALPHA + INTEGER INCX, INCY, N + CHARACTER*1 UPLO +* .. Array Arguments .. + DOUBLE PRECISION AP( * ), X( * ), Y( * ) +* .. +* +* Purpose +* ======= +* +* DSPR2 performs the symmetric rank 2 operation +* +* A := alpha*x*y' + alpha*y*x' + A, +* +* where alpha is a scalar, x and y are n element vectors and A is an +* n by n symmetric matrix, supplied in packed form. +* +* Parameters +* ========== +* +* UPLO - CHARACTER*1. +* On entry, UPLO specifies whether the upper or lower +* triangular part of the matrix A is supplied in the packed +* array AP as follows: +* +* UPLO = 'U' or 'u' The upper triangular part of A is +* supplied in AP. +* +* UPLO = 'L' or 'l' The lower triangular part of A is +* supplied in AP. +* +* Unchanged on exit. +* +* N - INTEGER. +* On entry, N specifies the order of the matrix A. +* N must be at least zero. +* Unchanged on exit. +* +* ALPHA - DOUBLE PRECISION. +* On entry, ALPHA specifies the scalar alpha. +* Unchanged on exit. +* +* X - DOUBLE PRECISION array of dimension at least +* ( 1 + ( n - 1 )*abs( INCX ) ). +* Before entry, the incremented array X must contain the n +* element vector x. +* Unchanged on exit. +* +* INCX - INTEGER. +* On entry, INCX specifies the increment for the elements of +* X. INCX must not be zero. +* Unchanged on exit. +* +* Y - DOUBLE PRECISION array of dimension at least +* ( 1 + ( n - 1 )*abs( INCY ) ). +* Before entry, the incremented array Y must contain the n +* element vector y. +* Unchanged on exit. +* +* INCY - INTEGER. +* On entry, INCY specifies the increment for the elements of +* Y. INCY must not be zero. +* Unchanged on exit. +* +* AP - DOUBLE PRECISION array of DIMENSION at least +* ( ( n*( n + 1 ) )/2 ). +* Before entry with UPLO = 'U' or 'u', the array AP must +* contain the upper triangular part of the symmetric matrix +* packed sequentially, column by column, so that AP( 1 ) +* contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 1, 2 ) +* and a( 2, 2 ) respectively, and so on. On exit, the array +* AP is overwritten by the upper triangular part of the +* updated matrix. +* Before entry with UPLO = 'L' or 'l', the array AP must +* contain the lower triangular part of the symmetric matrix +* packed sequentially, column by column, so that AP( 1 ) +* contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 2, 1 ) +* and a( 3, 1 ) respectively, and so on. On exit, the array +* AP is overwritten by the lower triangular part of the +* updated matrix. +* +* +* Level 2 Blas routine. +* +* -- Written on 22-October-1986. +* Jack Dongarra, Argonne National Lab. +* Jeremy Du Croz, Nag Central Office. +* Sven Hammarling, Nag Central Office. +* Richard Hanson, Sandia National Labs. +* +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D+0 ) +* .. Local Scalars .. + DOUBLE PRECISION TEMP1, TEMP2 + INTEGER I, INFO, IX, IY, J, JX, JY, K, KK, KX, KY +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. External Subroutines .. + EXTERNAL XERBLA +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + IF ( .NOT.LSAME( UPLO, 'U' ).AND. + $ .NOT.LSAME( UPLO, 'L' ) )THEN + INFO = 1 + ELSE IF( N.LT.0 )THEN + INFO = 2 + ELSE IF( INCX.EQ.0 )THEN + INFO = 5 + ELSE IF( INCY.EQ.0 )THEN + INFO = 7 + END IF + IF( INFO.NE.0 )THEN + CALL XERBLA( 'DSPR2 ', INFO ) + RETURN + END IF +* +* Quick return if possible. +* + IF( ( N.EQ.0 ).OR.( ALPHA.EQ.ZERO ) ) + $ RETURN +* +* Set up the start points in X and Y if the increments are not both +* unity. +* + IF( ( INCX.NE.1 ).OR.( INCY.NE.1 ) )THEN + IF( INCX.GT.0 )THEN + KX = 1 + ELSE + KX = 1 - ( N - 1 )*INCX + END IF + IF( INCY.GT.0 )THEN + KY = 1 + ELSE + KY = 1 - ( N - 1 )*INCY + END IF + JX = KX + JY = KY + END IF +* +* Start the operations. In this version the elements of the array AP +* are accessed sequentially with one pass through AP. +* + KK = 1 + IF( LSAME( UPLO, 'U' ) )THEN +* +* Form A when upper triangle is stored in AP. +* + IF( ( INCX.EQ.1 ).AND.( INCY.EQ.1 ) )THEN + DO 20, J = 1, N + IF( ( X( J ).NE.ZERO ).OR.( Y( J ).NE.ZERO ) )THEN + TEMP1 = ALPHA*Y( J ) + TEMP2 = ALPHA*X( J ) + K = KK + DO 10, I = 1, J + AP( K ) = AP( K ) + X( I )*TEMP1 + Y( I )*TEMP2 + K = K + 1 + 10 CONTINUE + END IF + KK = KK + J + 20 CONTINUE + ELSE + DO 40, J = 1, N + IF( ( X( JX ).NE.ZERO ).OR.( Y( JY ).NE.ZERO ) )THEN + TEMP1 = ALPHA*Y( JY ) + TEMP2 = ALPHA*X( JX ) + IX = KX + IY = KY + DO 30, K = KK, KK + J - 1 + AP( K ) = AP( K ) + X( IX )*TEMP1 + Y( IY )*TEMP2 + IX = IX + INCX + IY = IY + INCY + 30 CONTINUE + END IF + JX = JX + INCX + JY = JY + INCY + KK = KK + J + 40 CONTINUE + END IF + ELSE +* +* Form A when lower triangle is stored in AP. +* + IF( ( INCX.EQ.1 ).AND.( INCY.EQ.1 ) )THEN + DO 60, J = 1, N + IF( ( X( J ).NE.ZERO ).OR.( Y( J ).NE.ZERO ) )THEN + TEMP1 = ALPHA*Y( J ) + TEMP2 = ALPHA*X( J ) + K = KK + DO 50, I = J, N + AP( K ) = AP( K ) + X( I )*TEMP1 + Y( I )*TEMP2 + K = K + 1 + 50 CONTINUE + END IF + KK = KK + N - J + 1 + 60 CONTINUE + ELSE + DO 80, J = 1, N + IF( ( X( JX ).NE.ZERO ).OR.( Y( JY ).NE.ZERO ) )THEN + TEMP1 = ALPHA*Y( JY ) + TEMP2 = ALPHA*X( JX ) + IX = JX + IY = JY + DO 70, K = KK, KK + N - J + AP( K ) = AP( K ) + X( IX )*TEMP1 + Y( IY )*TEMP2 + IX = IX + INCX + IY = IY + INCY + 70 CONTINUE + END IF + JX = JX + INCX + JY = JY + INCY + KK = KK + N - J + 1 + 80 CONTINUE + END IF + END IF +* + RETURN +* +* End of DSPR2 . +* + END diff --git a/ext/blas/dswap.f b/ext/blas/dswap.f new file mode 100755 index 000000000..7f7d1fbba --- /dev/null +++ b/ext/blas/dswap.f @@ -0,0 +1,56 @@ + subroutine dswap (n,dx,incx,dy,incy) +c +c interchanges two vectors. +c uses unrolled loops for increments equal one. +c jack dongarra, linpack, 3/11/78. +c modified 12/3/93, array(1) declarations changed to array(*) +c + double precision dx(*),dy(*),dtemp + integer i,incx,incy,ix,iy,m,mp1,n +c + if(n.le.0)return + if(incx.eq.1.and.incy.eq.1)go to 20 +c +c code for unequal increments or equal increments not equal +c to 1 +c + ix = 1 + iy = 1 + if(incx.lt.0)ix = (-n+1)*incx + 1 + if(incy.lt.0)iy = (-n+1)*incy + 1 + do 10 i = 1,n + dtemp = dx(ix) + dx(ix) = dy(iy) + dy(iy) = dtemp + ix = ix + incx + iy = iy + incy + 10 continue + return +c +c code for both increments equal to 1 +c +c +c clean-up loop +c + 20 m = mod(n,3) + if( m .eq. 0 ) go to 40 + do 30 i = 1,m + dtemp = dx(i) + dx(i) = dy(i) + dy(i) = dtemp + 30 continue + if( n .lt. 3 ) return + 40 mp1 = m + 1 + do 50 i = mp1,n,3 + dtemp = dx(i) + dx(i) = dy(i) + dy(i) = dtemp + dtemp = dx(i + 1) + dx(i + 1) = dy(i + 1) + dy(i + 1) = dtemp + dtemp = dx(i + 2) + dx(i + 2) = dy(i + 2) + dy(i + 2) = dtemp + 50 continue + return + end diff --git a/ext/blas/dsymm.f b/ext/blas/dsymm.f new file mode 100755 index 000000000..0f2514170 --- /dev/null +++ b/ext/blas/dsymm.f @@ -0,0 +1,294 @@ + SUBROUTINE DSYMM ( SIDE, UPLO, M, N, ALPHA, A, LDA, B, LDB, + $ BETA, C, LDC ) +* .. Scalar Arguments .. + CHARACTER*1 SIDE, UPLO + INTEGER M, N, LDA, LDB, LDC + DOUBLE PRECISION ALPHA, BETA +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), B( LDB, * ), C( LDC, * ) +* .. +* +* Purpose +* ======= +* +* DSYMM performs one of the matrix-matrix operations +* +* C := alpha*A*B + beta*C, +* +* or +* +* C := alpha*B*A + beta*C, +* +* where alpha and beta are scalars, A is a symmetric matrix and B and +* C are m by n matrices. +* +* Parameters +* ========== +* +* SIDE - CHARACTER*1. +* On entry, SIDE specifies whether the symmetric matrix A +* appears on the left or right in the operation as follows: +* +* SIDE = 'L' or 'l' C := alpha*A*B + beta*C, +* +* SIDE = 'R' or 'r' C := alpha*B*A + beta*C, +* +* Unchanged on exit. +* +* UPLO - CHARACTER*1. +* On entry, UPLO specifies whether the upper or lower +* triangular part of the symmetric matrix A is to be +* referenced as follows: +* +* UPLO = 'U' or 'u' Only the upper triangular part of the +* symmetric matrix is to be referenced. +* +* UPLO = 'L' or 'l' Only the lower triangular part of the +* symmetric matrix is to be referenced. +* +* Unchanged on exit. +* +* M - INTEGER. +* On entry, M specifies the number of rows of the matrix C. +* M must be at least zero. +* Unchanged on exit. +* +* N - INTEGER. +* On entry, N specifies the number of columns of the matrix C. +* N must be at least zero. +* Unchanged on exit. +* +* ALPHA - DOUBLE PRECISION. +* On entry, ALPHA specifies the scalar alpha. +* Unchanged on exit. +* +* A - DOUBLE PRECISION array of DIMENSION ( LDA, ka ), where ka is +* m when SIDE = 'L' or 'l' and is n otherwise. +* Before entry with SIDE = 'L' or 'l', the m by m part of +* the array A must contain the symmetric matrix, such that +* when UPLO = 'U' or 'u', the leading m by m upper triangular +* part of the array A must contain the upper triangular part +* of the symmetric matrix and the strictly lower triangular +* part of A is not referenced, and when UPLO = 'L' or 'l', +* the leading m by m lower triangular part of the array A +* must contain the lower triangular part of the symmetric +* matrix and the strictly upper triangular part of A is not +* referenced. +* Before entry with SIDE = 'R' or 'r', the n by n part of +* the array A must contain the symmetric matrix, such that +* when UPLO = 'U' or 'u', the leading n by n upper triangular +* part of the array A must contain the upper triangular part +* of the symmetric matrix and the strictly lower triangular +* part of A is not referenced, and when UPLO = 'L' or 'l', +* the leading n by n lower triangular part of the array A +* must contain the lower triangular part of the symmetric +* matrix and the strictly upper triangular part of A is not +* referenced. +* Unchanged on exit. +* +* LDA - INTEGER. +* On entry, LDA specifies the first dimension of A as declared +* in the calling (sub) program. When SIDE = 'L' or 'l' then +* LDA must be at least max( 1, m ), otherwise LDA must be at +* least max( 1, n ). +* Unchanged on exit. +* +* B - DOUBLE PRECISION array of DIMENSION ( LDB, n ). +* Before entry, the leading m by n part of the array B must +* contain the matrix B. +* Unchanged on exit. +* +* LDB - INTEGER. +* On entry, LDB specifies the first dimension of B as declared +* in the calling (sub) program. LDB must be at least +* max( 1, m ). +* Unchanged on exit. +* +* BETA - DOUBLE PRECISION. +* On entry, BETA specifies the scalar beta. When BETA is +* supplied as zero then C need not be set on input. +* Unchanged on exit. +* +* C - DOUBLE PRECISION array of DIMENSION ( LDC, n ). +* Before entry, the leading m by n part of the array C must +* contain the matrix C, except when beta is zero, in which +* case C need not be set on entry. +* On exit, the array C is overwritten by the m by n updated +* matrix. +* +* LDC - INTEGER. +* On entry, LDC specifies the first dimension of C as declared +* in the calling (sub) program. LDC must be at least +* max( 1, m ). +* Unchanged on exit. +* +* +* Level 3 Blas routine. +* +* -- Written on 8-February-1989. +* Jack Dongarra, Argonne National Laboratory. +* Iain Duff, AERE Harwell. +* Jeremy Du Croz, Numerical Algorithms Group Ltd. +* Sven Hammarling, Numerical Algorithms Group Ltd. +* +* +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. External Subroutines .. + EXTERNAL XERBLA +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. Local Scalars .. + LOGICAL UPPER + INTEGER I, INFO, J, K, NROWA + DOUBLE PRECISION TEMP1, TEMP2 +* .. Parameters .. + DOUBLE PRECISION ONE , ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Executable Statements .. +* +* Set NROWA as the number of rows of A. +* + IF( LSAME( SIDE, 'L' ) )THEN + NROWA = M + ELSE + NROWA = N + END IF + UPPER = LSAME( UPLO, 'U' ) +* +* Test the input parameters. +* + INFO = 0 + IF( ( .NOT.LSAME( SIDE, 'L' ) ).AND. + $ ( .NOT.LSAME( SIDE, 'R' ) ) )THEN + INFO = 1 + ELSE IF( ( .NOT.UPPER ).AND. + $ ( .NOT.LSAME( UPLO, 'L' ) ) )THEN + INFO = 2 + ELSE IF( M .LT.0 )THEN + INFO = 3 + ELSE IF( N .LT.0 )THEN + INFO = 4 + ELSE IF( LDA.LT.MAX( 1, NROWA ) )THEN + INFO = 7 + ELSE IF( LDB.LT.MAX( 1, M ) )THEN + INFO = 9 + ELSE IF( LDC.LT.MAX( 1, M ) )THEN + INFO = 12 + END IF + IF( INFO.NE.0 )THEN + CALL XERBLA( 'DSYMM ', INFO ) + RETURN + END IF +* +* Quick return if possible. +* + IF( ( M.EQ.0 ).OR.( N.EQ.0 ).OR. + $ ( ( ALPHA.EQ.ZERO ).AND.( BETA.EQ.ONE ) ) ) + $ RETURN +* +* And when alpha.eq.zero. +* + IF( ALPHA.EQ.ZERO )THEN + IF( BETA.EQ.ZERO )THEN + DO 20, J = 1, N + DO 10, I = 1, M + C( I, J ) = ZERO + 10 CONTINUE + 20 CONTINUE + ELSE + DO 40, J = 1, N + DO 30, I = 1, M + C( I, J ) = BETA*C( I, J ) + 30 CONTINUE + 40 CONTINUE + END IF + RETURN + END IF +* +* Start the operations. +* + IF( LSAME( SIDE, 'L' ) )THEN +* +* Form C := alpha*A*B + beta*C. +* + IF( UPPER )THEN + DO 70, J = 1, N + DO 60, I = 1, M + TEMP1 = ALPHA*B( I, J ) + TEMP2 = ZERO + DO 50, K = 1, I - 1 + C( K, J ) = C( K, J ) + TEMP1 *A( K, I ) + TEMP2 = TEMP2 + B( K, J )*A( K, I ) + 50 CONTINUE + IF( BETA.EQ.ZERO )THEN + C( I, J ) = TEMP1*A( I, I ) + ALPHA*TEMP2 + ELSE + C( I, J ) = BETA *C( I, J ) + + $ TEMP1*A( I, I ) + ALPHA*TEMP2 + END IF + 60 CONTINUE + 70 CONTINUE + ELSE + DO 100, J = 1, N + DO 90, I = M, 1, -1 + TEMP1 = ALPHA*B( I, J ) + TEMP2 = ZERO + DO 80, K = I + 1, M + C( K, J ) = C( K, J ) + TEMP1 *A( K, I ) + TEMP2 = TEMP2 + B( K, J )*A( K, I ) + 80 CONTINUE + IF( BETA.EQ.ZERO )THEN + C( I, J ) = TEMP1*A( I, I ) + ALPHA*TEMP2 + ELSE + C( I, J ) = BETA *C( I, J ) + + $ TEMP1*A( I, I ) + ALPHA*TEMP2 + END IF + 90 CONTINUE + 100 CONTINUE + END IF + ELSE +* +* Form C := alpha*B*A + beta*C. +* + DO 170, J = 1, N + TEMP1 = ALPHA*A( J, J ) + IF( BETA.EQ.ZERO )THEN + DO 110, I = 1, M + C( I, J ) = TEMP1*B( I, J ) + 110 CONTINUE + ELSE + DO 120, I = 1, M + C( I, J ) = BETA*C( I, J ) + TEMP1*B( I, J ) + 120 CONTINUE + END IF + DO 140, K = 1, J - 1 + IF( UPPER )THEN + TEMP1 = ALPHA*A( K, J ) + ELSE + TEMP1 = ALPHA*A( J, K ) + END IF + DO 130, I = 1, M + C( I, J ) = C( I, J ) + TEMP1*B( I, K ) + 130 CONTINUE + 140 CONTINUE + DO 160, K = J + 1, N + IF( UPPER )THEN + TEMP1 = ALPHA*A( J, K ) + ELSE + TEMP1 = ALPHA*A( K, J ) + END IF + DO 150, I = 1, M + C( I, J ) = C( I, J ) + TEMP1*B( I, K ) + 150 CONTINUE + 160 CONTINUE + 170 CONTINUE + END IF +* + RETURN +* +* End of DSYMM . +* + END diff --git a/ext/blas/dsymv.f b/ext/blas/dsymv.f new file mode 100755 index 000000000..7592d156b --- /dev/null +++ b/ext/blas/dsymv.f @@ -0,0 +1,262 @@ + SUBROUTINE DSYMV ( UPLO, N, ALPHA, A, LDA, X, INCX, + $ BETA, Y, INCY ) +* .. Scalar Arguments .. + DOUBLE PRECISION ALPHA, BETA + INTEGER INCX, INCY, LDA, N + CHARACTER*1 UPLO +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), X( * ), Y( * ) +* .. +* +* Purpose +* ======= +* +* DSYMV performs the matrix-vector operation +* +* y := alpha*A*x + beta*y, +* +* where alpha and beta are scalars, x and y are n element vectors and +* A is an n by n symmetric matrix. +* +* Parameters +* ========== +* +* UPLO - CHARACTER*1. +* On entry, UPLO specifies whether the upper or lower +* triangular part of the array A is to be referenced as +* follows: +* +* UPLO = 'U' or 'u' Only the upper triangular part of A +* is to be referenced. +* +* UPLO = 'L' or 'l' Only the lower triangular part of A +* is to be referenced. +* +* Unchanged on exit. +* +* N - INTEGER. +* On entry, N specifies the order of the matrix A. +* N must be at least zero. +* Unchanged on exit. +* +* ALPHA - DOUBLE PRECISION. +* On entry, ALPHA specifies the scalar alpha. +* Unchanged on exit. +* +* A - DOUBLE PRECISION array of DIMENSION ( LDA, n ). +* Before entry with UPLO = 'U' or 'u', the leading n by n +* upper triangular part of the array A must contain the upper +* triangular part of the symmetric matrix and the strictly +* lower triangular part of A is not referenced. +* Before entry with UPLO = 'L' or 'l', the leading n by n +* lower triangular part of the array A must contain the lower +* triangular part of the symmetric matrix and the strictly +* upper triangular part of A is not referenced. +* Unchanged on exit. +* +* LDA - INTEGER. +* On entry, LDA specifies the first dimension of A as declared +* in the calling (sub) program. LDA must be at least +* max( 1, n ). +* Unchanged on exit. +* +* X - DOUBLE PRECISION array of dimension at least +* ( 1 + ( n - 1 )*abs( INCX ) ). +* Before entry, the incremented array X must contain the n +* element vector x. +* Unchanged on exit. +* +* INCX - INTEGER. +* On entry, INCX specifies the increment for the elements of +* X. INCX must not be zero. +* Unchanged on exit. +* +* BETA - DOUBLE PRECISION. +* On entry, BETA specifies the scalar beta. When BETA is +* supplied as zero then Y need not be set on input. +* Unchanged on exit. +* +* Y - DOUBLE PRECISION array of dimension at least +* ( 1 + ( n - 1 )*abs( INCY ) ). +* Before entry, the incremented array Y must contain the n +* element vector y. On exit, Y is overwritten by the updated +* vector y. +* +* INCY - INTEGER. +* On entry, INCY specifies the increment for the elements of +* Y. INCY must not be zero. +* Unchanged on exit. +* +* +* Level 2 Blas routine. +* +* -- Written on 22-October-1986. +* Jack Dongarra, Argonne National Lab. +* Jeremy Du Croz, Nag Central Office. +* Sven Hammarling, Nag Central Office. +* Richard Hanson, Sandia National Labs. +* +* +* .. Parameters .. + DOUBLE PRECISION ONE , ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. Local Scalars .. + DOUBLE PRECISION TEMP1, TEMP2 + INTEGER I, INFO, IX, IY, J, JX, JY, KX, KY +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. External Subroutines .. + EXTERNAL XERBLA +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + IF ( .NOT.LSAME( UPLO, 'U' ).AND. + $ .NOT.LSAME( UPLO, 'L' ) )THEN + INFO = 1 + ELSE IF( N.LT.0 )THEN + INFO = 2 + ELSE IF( LDA.LT.MAX( 1, N ) )THEN + INFO = 5 + ELSE IF( INCX.EQ.0 )THEN + INFO = 7 + ELSE IF( INCY.EQ.0 )THEN + INFO = 10 + END IF + IF( INFO.NE.0 )THEN + CALL XERBLA( 'DSYMV ', INFO ) + RETURN + END IF +* +* Quick return if possible. +* + IF( ( N.EQ.0 ).OR.( ( ALPHA.EQ.ZERO ).AND.( BETA.EQ.ONE ) ) ) + $ RETURN +* +* Set up the start points in X and Y. +* + IF( INCX.GT.0 )THEN + KX = 1 + ELSE + KX = 1 - ( N - 1 )*INCX + END IF + IF( INCY.GT.0 )THEN + KY = 1 + ELSE + KY = 1 - ( N - 1 )*INCY + END IF +* +* Start the operations. In this version the elements of A are +* accessed sequentially with one pass through the triangular part +* of A. +* +* First form y := beta*y. +* + IF( BETA.NE.ONE )THEN + IF( INCY.EQ.1 )THEN + IF( BETA.EQ.ZERO )THEN + DO 10, I = 1, N + Y( I ) = ZERO + 10 CONTINUE + ELSE + DO 20, I = 1, N + Y( I ) = BETA*Y( I ) + 20 CONTINUE + END IF + ELSE + IY = KY + IF( BETA.EQ.ZERO )THEN + DO 30, I = 1, N + Y( IY ) = ZERO + IY = IY + INCY + 30 CONTINUE + ELSE + DO 40, I = 1, N + Y( IY ) = BETA*Y( IY ) + IY = IY + INCY + 40 CONTINUE + END IF + END IF + END IF + IF( ALPHA.EQ.ZERO ) + $ RETURN + IF( LSAME( UPLO, 'U' ) )THEN +* +* Form y when A is stored in upper triangle. +* + IF( ( INCX.EQ.1 ).AND.( INCY.EQ.1 ) )THEN + DO 60, J = 1, N + TEMP1 = ALPHA*X( J ) + TEMP2 = ZERO + DO 50, I = 1, J - 1 + Y( I ) = Y( I ) + TEMP1*A( I, J ) + TEMP2 = TEMP2 + A( I, J )*X( I ) + 50 CONTINUE + Y( J ) = Y( J ) + TEMP1*A( J, J ) + ALPHA*TEMP2 + 60 CONTINUE + ELSE + JX = KX + JY = KY + DO 80, J = 1, N + TEMP1 = ALPHA*X( JX ) + TEMP2 = ZERO + IX = KX + IY = KY + DO 70, I = 1, J - 1 + Y( IY ) = Y( IY ) + TEMP1*A( I, J ) + TEMP2 = TEMP2 + A( I, J )*X( IX ) + IX = IX + INCX + IY = IY + INCY + 70 CONTINUE + Y( JY ) = Y( JY ) + TEMP1*A( J, J ) + ALPHA*TEMP2 + JX = JX + INCX + JY = JY + INCY + 80 CONTINUE + END IF + ELSE +* +* Form y when A is stored in lower triangle. +* + IF( ( INCX.EQ.1 ).AND.( INCY.EQ.1 ) )THEN + DO 100, J = 1, N + TEMP1 = ALPHA*X( J ) + TEMP2 = ZERO + Y( J ) = Y( J ) + TEMP1*A( J, J ) + DO 90, I = J + 1, N + Y( I ) = Y( I ) + TEMP1*A( I, J ) + TEMP2 = TEMP2 + A( I, J )*X( I ) + 90 CONTINUE + Y( J ) = Y( J ) + ALPHA*TEMP2 + 100 CONTINUE + ELSE + JX = KX + JY = KY + DO 120, J = 1, N + TEMP1 = ALPHA*X( JX ) + TEMP2 = ZERO + Y( JY ) = Y( JY ) + TEMP1*A( J, J ) + IX = JX + IY = JY + DO 110, I = J + 1, N + IX = IX + INCX + IY = IY + INCY + Y( IY ) = Y( IY ) + TEMP1*A( I, J ) + TEMP2 = TEMP2 + A( I, J )*X( IX ) + 110 CONTINUE + Y( JY ) = Y( JY ) + ALPHA*TEMP2 + JX = JX + INCX + JY = JY + INCY + 120 CONTINUE + END IF + END IF +* + RETURN +* +* End of DSYMV . +* + END diff --git a/ext/blas/dsyr.f b/ext/blas/dsyr.f new file mode 100755 index 000000000..873771967 --- /dev/null +++ b/ext/blas/dsyr.f @@ -0,0 +1,197 @@ + SUBROUTINE DSYR ( UPLO, N, ALPHA, X, INCX, A, LDA ) +* .. Scalar Arguments .. + DOUBLE PRECISION ALPHA + INTEGER INCX, LDA, N + CHARACTER*1 UPLO +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), X( * ) +* .. +* +* Purpose +* ======= +* +* DSYR performs the symmetric rank 1 operation +* +* A := alpha*x*x' + A, +* +* where alpha is a real scalar, x is an n element vector and A is an +* n by n symmetric matrix. +* +* Parameters +* ========== +* +* UPLO - CHARACTER*1. +* On entry, UPLO specifies whether the upper or lower +* triangular part of the array A is to be referenced as +* follows: +* +* UPLO = 'U' or 'u' Only the upper triangular part of A +* is to be referenced. +* +* UPLO = 'L' or 'l' Only the lower triangular part of A +* is to be referenced. +* +* Unchanged on exit. +* +* N - INTEGER. +* On entry, N specifies the order of the matrix A. +* N must be at least zero. +* Unchanged on exit. +* +* ALPHA - DOUBLE PRECISION. +* On entry, ALPHA specifies the scalar alpha. +* Unchanged on exit. +* +* X - DOUBLE PRECISION array of dimension at least +* ( 1 + ( n - 1 )*abs( INCX ) ). +* Before entry, the incremented array X must contain the n +* element vector x. +* Unchanged on exit. +* +* INCX - INTEGER. +* On entry, INCX specifies the increment for the elements of +* X. INCX must not be zero. +* Unchanged on exit. +* +* A - DOUBLE PRECISION array of DIMENSION ( LDA, n ). +* Before entry with UPLO = 'U' or 'u', the leading n by n +* upper triangular part of the array A must contain the upper +* triangular part of the symmetric matrix and the strictly +* lower triangular part of A is not referenced. On exit, the +* upper triangular part of the array A is overwritten by the +* upper triangular part of the updated matrix. +* Before entry with UPLO = 'L' or 'l', the leading n by n +* lower triangular part of the array A must contain the lower +* triangular part of the symmetric matrix and the strictly +* upper triangular part of A is not referenced. On exit, the +* lower triangular part of the array A is overwritten by the +* lower triangular part of the updated matrix. +* +* LDA - INTEGER. +* On entry, LDA specifies the first dimension of A as declared +* in the calling (sub) program. LDA must be at least +* max( 1, n ). +* Unchanged on exit. +* +* +* Level 2 Blas routine. +* +* -- Written on 22-October-1986. +* Jack Dongarra, Argonne National Lab. +* Jeremy Du Croz, Nag Central Office. +* Sven Hammarling, Nag Central Office. +* Richard Hanson, Sandia National Labs. +* +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D+0 ) +* .. Local Scalars .. + DOUBLE PRECISION TEMP + INTEGER I, INFO, IX, J, JX, KX +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. External Subroutines .. + EXTERNAL XERBLA +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + IF ( .NOT.LSAME( UPLO, 'U' ).AND. + $ .NOT.LSAME( UPLO, 'L' ) )THEN + INFO = 1 + ELSE IF( N.LT.0 )THEN + INFO = 2 + ELSE IF( INCX.EQ.0 )THEN + INFO = 5 + ELSE IF( LDA.LT.MAX( 1, N ) )THEN + INFO = 7 + END IF + IF( INFO.NE.0 )THEN + CALL XERBLA( 'DSYR ', INFO ) + RETURN + END IF +* +* Quick return if possible. +* + IF( ( N.EQ.0 ).OR.( ALPHA.EQ.ZERO ) ) + $ RETURN +* +* Set the start point in X if the increment is not unity. +* + IF( INCX.LE.0 )THEN + KX = 1 - ( N - 1 )*INCX + ELSE IF( INCX.NE.1 )THEN + KX = 1 + END IF +* +* Start the operations. In this version the elements of A are +* accessed sequentially with one pass through the triangular part +* of A. +* + IF( LSAME( UPLO, 'U' ) )THEN +* +* Form A when A is stored in upper triangle. +* + IF( INCX.EQ.1 )THEN + DO 20, J = 1, N + IF( X( J ).NE.ZERO )THEN + TEMP = ALPHA*X( J ) + DO 10, I = 1, J + A( I, J ) = A( I, J ) + X( I )*TEMP + 10 CONTINUE + END IF + 20 CONTINUE + ELSE + JX = KX + DO 40, J = 1, N + IF( X( JX ).NE.ZERO )THEN + TEMP = ALPHA*X( JX ) + IX = KX + DO 30, I = 1, J + A( I, J ) = A( I, J ) + X( IX )*TEMP + IX = IX + INCX + 30 CONTINUE + END IF + JX = JX + INCX + 40 CONTINUE + END IF + ELSE +* +* Form A when A is stored in lower triangle. +* + IF( INCX.EQ.1 )THEN + DO 60, J = 1, N + IF( X( J ).NE.ZERO )THEN + TEMP = ALPHA*X( J ) + DO 50, I = J, N + A( I, J ) = A( I, J ) + X( I )*TEMP + 50 CONTINUE + END IF + 60 CONTINUE + ELSE + JX = KX + DO 80, J = 1, N + IF( X( JX ).NE.ZERO )THEN + TEMP = ALPHA*X( JX ) + IX = JX + DO 70, I = J, N + A( I, J ) = A( I, J ) + X( IX )*TEMP + IX = IX + INCX + 70 CONTINUE + END IF + JX = JX + INCX + 80 CONTINUE + END IF + END IF +* + RETURN +* +* End of DSYR . +* + END diff --git a/ext/blas/dsyr2.f b/ext/blas/dsyr2.f new file mode 100755 index 000000000..918ad8a7d --- /dev/null +++ b/ext/blas/dsyr2.f @@ -0,0 +1,230 @@ + SUBROUTINE DSYR2 ( UPLO, N, ALPHA, X, INCX, Y, INCY, A, LDA ) +* .. Scalar Arguments .. + DOUBLE PRECISION ALPHA + INTEGER INCX, INCY, LDA, N + CHARACTER*1 UPLO +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), X( * ), Y( * ) +* .. +* +* Purpose +* ======= +* +* DSYR2 performs the symmetric rank 2 operation +* +* A := alpha*x*y' + alpha*y*x' + A, +* +* where alpha is a scalar, x and y are n element vectors and A is an n +* by n symmetric matrix. +* +* Parameters +* ========== +* +* UPLO - CHARACTER*1. +* On entry, UPLO specifies whether the upper or lower +* triangular part of the array A is to be referenced as +* follows: +* +* UPLO = 'U' or 'u' Only the upper triangular part of A +* is to be referenced. +* +* UPLO = 'L' or 'l' Only the lower triangular part of A +* is to be referenced. +* +* Unchanged on exit. +* +* N - INTEGER. +* On entry, N specifies the order of the matrix A. +* N must be at least zero. +* Unchanged on exit. +* +* ALPHA - DOUBLE PRECISION. +* On entry, ALPHA specifies the scalar alpha. +* Unchanged on exit. +* +* X - DOUBLE PRECISION array of dimension at least +* ( 1 + ( n - 1 )*abs( INCX ) ). +* Before entry, the incremented array X must contain the n +* element vector x. +* Unchanged on exit. +* +* INCX - INTEGER. +* On entry, INCX specifies the increment for the elements of +* X. INCX must not be zero. +* Unchanged on exit. +* +* Y - DOUBLE PRECISION array of dimension at least +* ( 1 + ( n - 1 )*abs( INCY ) ). +* Before entry, the incremented array Y must contain the n +* element vector y. +* Unchanged on exit. +* +* INCY - INTEGER. +* On entry, INCY specifies the increment for the elements of +* Y. INCY must not be zero. +* Unchanged on exit. +* +* A - DOUBLE PRECISION array of DIMENSION ( LDA, n ). +* Before entry with UPLO = 'U' or 'u', the leading n by n +* upper triangular part of the array A must contain the upper +* triangular part of the symmetric matrix and the strictly +* lower triangular part of A is not referenced. On exit, the +* upper triangular part of the array A is overwritten by the +* upper triangular part of the updated matrix. +* Before entry with UPLO = 'L' or 'l', the leading n by n +* lower triangular part of the array A must contain the lower +* triangular part of the symmetric matrix and the strictly +* upper triangular part of A is not referenced. On exit, the +* lower triangular part of the array A is overwritten by the +* lower triangular part of the updated matrix. +* +* LDA - INTEGER. +* On entry, LDA specifies the first dimension of A as declared +* in the calling (sub) program. LDA must be at least +* max( 1, n ). +* Unchanged on exit. +* +* +* Level 2 Blas routine. +* +* -- Written on 22-October-1986. +* Jack Dongarra, Argonne National Lab. +* Jeremy Du Croz, Nag Central Office. +* Sven Hammarling, Nag Central Office. +* Richard Hanson, Sandia National Labs. +* +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D+0 ) +* .. Local Scalars .. + DOUBLE PRECISION TEMP1, TEMP2 + INTEGER I, INFO, IX, IY, J, JX, JY, KX, KY +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. External Subroutines .. + EXTERNAL XERBLA +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + IF ( .NOT.LSAME( UPLO, 'U' ).AND. + $ .NOT.LSAME( UPLO, 'L' ) )THEN + INFO = 1 + ELSE IF( N.LT.0 )THEN + INFO = 2 + ELSE IF( INCX.EQ.0 )THEN + INFO = 5 + ELSE IF( INCY.EQ.0 )THEN + INFO = 7 + ELSE IF( LDA.LT.MAX( 1, N ) )THEN + INFO = 9 + END IF + IF( INFO.NE.0 )THEN + CALL XERBLA( 'DSYR2 ', INFO ) + RETURN + END IF +* +* Quick return if possible. +* + IF( ( N.EQ.0 ).OR.( ALPHA.EQ.ZERO ) ) + $ RETURN +* +* Set up the start points in X and Y if the increments are not both +* unity. +* + IF( ( INCX.NE.1 ).OR.( INCY.NE.1 ) )THEN + IF( INCX.GT.0 )THEN + KX = 1 + ELSE + KX = 1 - ( N - 1 )*INCX + END IF + IF( INCY.GT.0 )THEN + KY = 1 + ELSE + KY = 1 - ( N - 1 )*INCY + END IF + JX = KX + JY = KY + END IF +* +* Start the operations. In this version the elements of A are +* accessed sequentially with one pass through the triangular part +* of A. +* + IF( LSAME( UPLO, 'U' ) )THEN +* +* Form A when A is stored in the upper triangle. +* + IF( ( INCX.EQ.1 ).AND.( INCY.EQ.1 ) )THEN + DO 20, J = 1, N + IF( ( X( J ).NE.ZERO ).OR.( Y( J ).NE.ZERO ) )THEN + TEMP1 = ALPHA*Y( J ) + TEMP2 = ALPHA*X( J ) + DO 10, I = 1, J + A( I, J ) = A( I, J ) + X( I )*TEMP1 + Y( I )*TEMP2 + 10 CONTINUE + END IF + 20 CONTINUE + ELSE + DO 40, J = 1, N + IF( ( X( JX ).NE.ZERO ).OR.( Y( JY ).NE.ZERO ) )THEN + TEMP1 = ALPHA*Y( JY ) + TEMP2 = ALPHA*X( JX ) + IX = KX + IY = KY + DO 30, I = 1, J + A( I, J ) = A( I, J ) + X( IX )*TEMP1 + $ + Y( IY )*TEMP2 + IX = IX + INCX + IY = IY + INCY + 30 CONTINUE + END IF + JX = JX + INCX + JY = JY + INCY + 40 CONTINUE + END IF + ELSE +* +* Form A when A is stored in the lower triangle. +* + IF( ( INCX.EQ.1 ).AND.( INCY.EQ.1 ) )THEN + DO 60, J = 1, N + IF( ( X( J ).NE.ZERO ).OR.( Y( J ).NE.ZERO ) )THEN + TEMP1 = ALPHA*Y( J ) + TEMP2 = ALPHA*X( J ) + DO 50, I = J, N + A( I, J ) = A( I, J ) + X( I )*TEMP1 + Y( I )*TEMP2 + 50 CONTINUE + END IF + 60 CONTINUE + ELSE + DO 80, J = 1, N + IF( ( X( JX ).NE.ZERO ).OR.( Y( JY ).NE.ZERO ) )THEN + TEMP1 = ALPHA*Y( JY ) + TEMP2 = ALPHA*X( JX ) + IX = JX + IY = JY + DO 70, I = J, N + A( I, J ) = A( I, J ) + X( IX )*TEMP1 + $ + Y( IY )*TEMP2 + IX = IX + INCX + IY = IY + INCY + 70 CONTINUE + END IF + JX = JX + INCX + JY = JY + INCY + 80 CONTINUE + END IF + END IF +* + RETURN +* +* End of DSYR2 . +* + END diff --git a/ext/blas/dsyr2k.f b/ext/blas/dsyr2k.f new file mode 100755 index 000000000..ac7d97de6 --- /dev/null +++ b/ext/blas/dsyr2k.f @@ -0,0 +1,327 @@ + SUBROUTINE DSYR2K( UPLO, TRANS, N, K, ALPHA, A, LDA, B, LDB, + $ BETA, C, LDC ) +* .. Scalar Arguments .. + CHARACTER*1 UPLO, TRANS + INTEGER N, K, LDA, LDB, LDC + DOUBLE PRECISION ALPHA, BETA +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), B( LDB, * ), C( LDC, * ) +* .. +* +* Purpose +* ======= +* +* DSYR2K performs one of the symmetric rank 2k operations +* +* C := alpha*A*B' + alpha*B*A' + beta*C, +* +* or +* +* C := alpha*A'*B + alpha*B'*A + beta*C, +* +* where alpha and beta are scalars, C is an n by n symmetric matrix +* and A and B are n by k matrices in the first case and k by n +* matrices in the second case. +* +* Parameters +* ========== +* +* UPLO - CHARACTER*1. +* On entry, UPLO specifies whether the upper or lower +* triangular part of the array C is to be referenced as +* follows: +* +* UPLO = 'U' or 'u' Only the upper triangular part of C +* is to be referenced. +* +* UPLO = 'L' or 'l' Only the lower triangular part of C +* is to be referenced. +* +* Unchanged on exit. +* +* TRANS - CHARACTER*1. +* On entry, TRANS specifies the operation to be performed as +* follows: +* +* TRANS = 'N' or 'n' C := alpha*A*B' + alpha*B*A' + +* beta*C. +* +* TRANS = 'T' or 't' C := alpha*A'*B + alpha*B'*A + +* beta*C. +* +* TRANS = 'C' or 'c' C := alpha*A'*B + alpha*B'*A + +* beta*C. +* +* Unchanged on exit. +* +* N - INTEGER. +* On entry, N specifies the order of the matrix C. N must be +* at least zero. +* Unchanged on exit. +* +* K - INTEGER. +* On entry with TRANS = 'N' or 'n', K specifies the number +* of columns of the matrices A and B, and on entry with +* TRANS = 'T' or 't' or 'C' or 'c', K specifies the number +* of rows of the matrices A and B. K must be at least zero. +* Unchanged on exit. +* +* ALPHA - DOUBLE PRECISION. +* On entry, ALPHA specifies the scalar alpha. +* Unchanged on exit. +* +* A - DOUBLE PRECISION array of DIMENSION ( LDA, ka ), where ka is +* k when TRANS = 'N' or 'n', and is n otherwise. +* Before entry with TRANS = 'N' or 'n', the leading n by k +* part of the array A must contain the matrix A, otherwise +* the leading k by n part of the array A must contain the +* matrix A. +* Unchanged on exit. +* +* LDA - INTEGER. +* On entry, LDA specifies the first dimension of A as declared +* in the calling (sub) program. When TRANS = 'N' or 'n' +* then LDA must be at least max( 1, n ), otherwise LDA must +* be at least max( 1, k ). +* Unchanged on exit. +* +* B - DOUBLE PRECISION array of DIMENSION ( LDB, kb ), where kb is +* k when TRANS = 'N' or 'n', and is n otherwise. +* Before entry with TRANS = 'N' or 'n', the leading n by k +* part of the array B must contain the matrix B, otherwise +* the leading k by n part of the array B must contain the +* matrix B. +* Unchanged on exit. +* +* LDB - INTEGER. +* On entry, LDB specifies the first dimension of B as declared +* in the calling (sub) program. When TRANS = 'N' or 'n' +* then LDB must be at least max( 1, n ), otherwise LDB must +* be at least max( 1, k ). +* Unchanged on exit. +* +* BETA - DOUBLE PRECISION. +* On entry, BETA specifies the scalar beta. +* Unchanged on exit. +* +* C - DOUBLE PRECISION array of DIMENSION ( LDC, n ). +* Before entry with UPLO = 'U' or 'u', the leading n by n +* upper triangular part of the array C must contain the upper +* triangular part of the symmetric matrix and the strictly +* lower triangular part of C is not referenced. On exit, the +* upper triangular part of the array C is overwritten by the +* upper triangular part of the updated matrix. +* Before entry with UPLO = 'L' or 'l', the leading n by n +* lower triangular part of the array C must contain the lower +* triangular part of the symmetric matrix and the strictly +* upper triangular part of C is not referenced. On exit, the +* lower triangular part of the array C is overwritten by the +* lower triangular part of the updated matrix. +* +* LDC - INTEGER. +* On entry, LDC specifies the first dimension of C as declared +* in the calling (sub) program. LDC must be at least +* max( 1, n ). +* Unchanged on exit. +* +* +* Level 3 Blas routine. +* +* +* -- Written on 8-February-1989. +* Jack Dongarra, Argonne National Laboratory. +* Iain Duff, AERE Harwell. +* Jeremy Du Croz, Numerical Algorithms Group Ltd. +* Sven Hammarling, Numerical Algorithms Group Ltd. +* +* +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. External Subroutines .. + EXTERNAL XERBLA +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. Local Scalars .. + LOGICAL UPPER + INTEGER I, INFO, J, L, NROWA + DOUBLE PRECISION TEMP1, TEMP2 +* .. Parameters .. + DOUBLE PRECISION ONE , ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + IF( LSAME( TRANS, 'N' ) )THEN + NROWA = N + ELSE + NROWA = K + END IF + UPPER = LSAME( UPLO, 'U' ) +* + INFO = 0 + IF( ( .NOT.UPPER ).AND. + $ ( .NOT.LSAME( UPLO , 'L' ) ) )THEN + INFO = 1 + ELSE IF( ( .NOT.LSAME( TRANS, 'N' ) ).AND. + $ ( .NOT.LSAME( TRANS, 'T' ) ).AND. + $ ( .NOT.LSAME( TRANS, 'C' ) ) )THEN + INFO = 2 + ELSE IF( N .LT.0 )THEN + INFO = 3 + ELSE IF( K .LT.0 )THEN + INFO = 4 + ELSE IF( LDA.LT.MAX( 1, NROWA ) )THEN + INFO = 7 + ELSE IF( LDB.LT.MAX( 1, NROWA ) )THEN + INFO = 9 + ELSE IF( LDC.LT.MAX( 1, N ) )THEN + INFO = 12 + END IF + IF( INFO.NE.0 )THEN + CALL XERBLA( 'DSYR2K', INFO ) + RETURN + END IF +* +* Quick return if possible. +* + IF( ( N.EQ.0 ).OR. + $ ( ( ( ALPHA.EQ.ZERO ).OR.( K.EQ.0 ) ).AND.( BETA.EQ.ONE ) ) ) + $ RETURN +* +* And when alpha.eq.zero. +* + IF( ALPHA.EQ.ZERO )THEN + IF( UPPER )THEN + IF( BETA.EQ.ZERO )THEN + DO 20, J = 1, N + DO 10, I = 1, J + C( I, J ) = ZERO + 10 CONTINUE + 20 CONTINUE + ELSE + DO 40, J = 1, N + DO 30, I = 1, J + C( I, J ) = BETA*C( I, J ) + 30 CONTINUE + 40 CONTINUE + END IF + ELSE + IF( BETA.EQ.ZERO )THEN + DO 60, J = 1, N + DO 50, I = J, N + C( I, J ) = ZERO + 50 CONTINUE + 60 CONTINUE + ELSE + DO 80, J = 1, N + DO 70, I = J, N + C( I, J ) = BETA*C( I, J ) + 70 CONTINUE + 80 CONTINUE + END IF + END IF + RETURN + END IF +* +* Start the operations. +* + IF( LSAME( TRANS, 'N' ) )THEN +* +* Form C := alpha*A*B' + alpha*B*A' + C. +* + IF( UPPER )THEN + DO 130, J = 1, N + IF( BETA.EQ.ZERO )THEN + DO 90, I = 1, J + C( I, J ) = ZERO + 90 CONTINUE + ELSE IF( BETA.NE.ONE )THEN + DO 100, I = 1, J + C( I, J ) = BETA*C( I, J ) + 100 CONTINUE + END IF + DO 120, L = 1, K + IF( ( A( J, L ).NE.ZERO ).OR. + $ ( B( J, L ).NE.ZERO ) )THEN + TEMP1 = ALPHA*B( J, L ) + TEMP2 = ALPHA*A( J, L ) + DO 110, I = 1, J + C( I, J ) = C( I, J ) + + $ A( I, L )*TEMP1 + B( I, L )*TEMP2 + 110 CONTINUE + END IF + 120 CONTINUE + 130 CONTINUE + ELSE + DO 180, J = 1, N + IF( BETA.EQ.ZERO )THEN + DO 140, I = J, N + C( I, J ) = ZERO + 140 CONTINUE + ELSE IF( BETA.NE.ONE )THEN + DO 150, I = J, N + C( I, J ) = BETA*C( I, J ) + 150 CONTINUE + END IF + DO 170, L = 1, K + IF( ( A( J, L ).NE.ZERO ).OR. + $ ( B( J, L ).NE.ZERO ) )THEN + TEMP1 = ALPHA*B( J, L ) + TEMP2 = ALPHA*A( J, L ) + DO 160, I = J, N + C( I, J ) = C( I, J ) + + $ A( I, L )*TEMP1 + B( I, L )*TEMP2 + 160 CONTINUE + END IF + 170 CONTINUE + 180 CONTINUE + END IF + ELSE +* +* Form C := alpha*A'*B + alpha*B'*A + C. +* + IF( UPPER )THEN + DO 210, J = 1, N + DO 200, I = 1, J + TEMP1 = ZERO + TEMP2 = ZERO + DO 190, L = 1, K + TEMP1 = TEMP1 + A( L, I )*B( L, J ) + TEMP2 = TEMP2 + B( L, I )*A( L, J ) + 190 CONTINUE + IF( BETA.EQ.ZERO )THEN + C( I, J ) = ALPHA*TEMP1 + ALPHA*TEMP2 + ELSE + C( I, J ) = BETA *C( I, J ) + + $ ALPHA*TEMP1 + ALPHA*TEMP2 + END IF + 200 CONTINUE + 210 CONTINUE + ELSE + DO 240, J = 1, N + DO 230, I = J, N + TEMP1 = ZERO + TEMP2 = ZERO + DO 220, L = 1, K + TEMP1 = TEMP1 + A( L, I )*B( L, J ) + TEMP2 = TEMP2 + B( L, I )*A( L, J ) + 220 CONTINUE + IF( BETA.EQ.ZERO )THEN + C( I, J ) = ALPHA*TEMP1 + ALPHA*TEMP2 + ELSE + C( I, J ) = BETA *C( I, J ) + + $ ALPHA*TEMP1 + ALPHA*TEMP2 + END IF + 230 CONTINUE + 240 CONTINUE + END IF + END IF +* + RETURN +* +* End of DSYR2K. +* + END diff --git a/ext/blas/dsyrk.f b/ext/blas/dsyrk.f new file mode 100755 index 000000000..b618b2968 --- /dev/null +++ b/ext/blas/dsyrk.f @@ -0,0 +1,294 @@ + SUBROUTINE DSYRK ( UPLO, TRANS, N, K, ALPHA, A, LDA, + $ BETA, C, LDC ) +* .. Scalar Arguments .. + CHARACTER*1 UPLO, TRANS + INTEGER N, K, LDA, LDC + DOUBLE PRECISION ALPHA, BETA +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), C( LDC, * ) +* .. +* +* Purpose +* ======= +* +* DSYRK performs one of the symmetric rank k operations +* +* C := alpha*A*A' + beta*C, +* +* or +* +* C := alpha*A'*A + beta*C, +* +* where alpha and beta are scalars, C is an n by n symmetric matrix +* and A is an n by k matrix in the first case and a k by n matrix +* in the second case. +* +* Parameters +* ========== +* +* UPLO - CHARACTER*1. +* On entry, UPLO specifies whether the upper or lower +* triangular part of the array C is to be referenced as +* follows: +* +* UPLO = 'U' or 'u' Only the upper triangular part of C +* is to be referenced. +* +* UPLO = 'L' or 'l' Only the lower triangular part of C +* is to be referenced. +* +* Unchanged on exit. +* +* TRANS - CHARACTER*1. +* On entry, TRANS specifies the operation to be performed as +* follows: +* +* TRANS = 'N' or 'n' C := alpha*A*A' + beta*C. +* +* TRANS = 'T' or 't' C := alpha*A'*A + beta*C. +* +* TRANS = 'C' or 'c' C := alpha*A'*A + beta*C. +* +* Unchanged on exit. +* +* N - INTEGER. +* On entry, N specifies the order of the matrix C. N must be +* at least zero. +* Unchanged on exit. +* +* K - INTEGER. +* On entry with TRANS = 'N' or 'n', K specifies the number +* of columns of the matrix A, and on entry with +* TRANS = 'T' or 't' or 'C' or 'c', K specifies the number +* of rows of the matrix A. K must be at least zero. +* Unchanged on exit. +* +* ALPHA - DOUBLE PRECISION. +* On entry, ALPHA specifies the scalar alpha. +* Unchanged on exit. +* +* A - DOUBLE PRECISION array of DIMENSION ( LDA, ka ), where ka is +* k when TRANS = 'N' or 'n', and is n otherwise. +* Before entry with TRANS = 'N' or 'n', the leading n by k +* part of the array A must contain the matrix A, otherwise +* the leading k by n part of the array A must contain the +* matrix A. +* Unchanged on exit. +* +* LDA - INTEGER. +* On entry, LDA specifies the first dimension of A as declared +* in the calling (sub) program. When TRANS = 'N' or 'n' +* then LDA must be at least max( 1, n ), otherwise LDA must +* be at least max( 1, k ). +* Unchanged on exit. +* +* BETA - DOUBLE PRECISION. +* On entry, BETA specifies the scalar beta. +* Unchanged on exit. +* +* C - DOUBLE PRECISION array of DIMENSION ( LDC, n ). +* Before entry with UPLO = 'U' or 'u', the leading n by n +* upper triangular part of the array C must contain the upper +* triangular part of the symmetric matrix and the strictly +* lower triangular part of C is not referenced. On exit, the +* upper triangular part of the array C is overwritten by the +* upper triangular part of the updated matrix. +* Before entry with UPLO = 'L' or 'l', the leading n by n +* lower triangular part of the array C must contain the lower +* triangular part of the symmetric matrix and the strictly +* upper triangular part of C is not referenced. On exit, the +* lower triangular part of the array C is overwritten by the +* lower triangular part of the updated matrix. +* +* LDC - INTEGER. +* On entry, LDC specifies the first dimension of C as declared +* in the calling (sub) program. LDC must be at least +* max( 1, n ). +* Unchanged on exit. +* +* +* Level 3 Blas routine. +* +* -- Written on 8-February-1989. +* Jack Dongarra, Argonne National Laboratory. +* Iain Duff, AERE Harwell. +* Jeremy Du Croz, Numerical Algorithms Group Ltd. +* Sven Hammarling, Numerical Algorithms Group Ltd. +* +* +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. External Subroutines .. + EXTERNAL XERBLA +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. Local Scalars .. + LOGICAL UPPER + INTEGER I, INFO, J, L, NROWA + DOUBLE PRECISION TEMP +* .. Parameters .. + DOUBLE PRECISION ONE , ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + IF( LSAME( TRANS, 'N' ) )THEN + NROWA = N + ELSE + NROWA = K + END IF + UPPER = LSAME( UPLO, 'U' ) +* + INFO = 0 + IF( ( .NOT.UPPER ).AND. + $ ( .NOT.LSAME( UPLO , 'L' ) ) )THEN + INFO = 1 + ELSE IF( ( .NOT.LSAME( TRANS, 'N' ) ).AND. + $ ( .NOT.LSAME( TRANS, 'T' ) ).AND. + $ ( .NOT.LSAME( TRANS, 'C' ) ) )THEN + INFO = 2 + ELSE IF( N .LT.0 )THEN + INFO = 3 + ELSE IF( K .LT.0 )THEN + INFO = 4 + ELSE IF( LDA.LT.MAX( 1, NROWA ) )THEN + INFO = 7 + ELSE IF( LDC.LT.MAX( 1, N ) )THEN + INFO = 10 + END IF + IF( INFO.NE.0 )THEN + CALL XERBLA( 'DSYRK ', INFO ) + RETURN + END IF +* +* Quick return if possible. +* + IF( ( N.EQ.0 ).OR. + $ ( ( ( ALPHA.EQ.ZERO ).OR.( K.EQ.0 ) ).AND.( BETA.EQ.ONE ) ) ) + $ RETURN +* +* And when alpha.eq.zero. +* + IF( ALPHA.EQ.ZERO )THEN + IF( UPPER )THEN + IF( BETA.EQ.ZERO )THEN + DO 20, J = 1, N + DO 10, I = 1, J + C( I, J ) = ZERO + 10 CONTINUE + 20 CONTINUE + ELSE + DO 40, J = 1, N + DO 30, I = 1, J + C( I, J ) = BETA*C( I, J ) + 30 CONTINUE + 40 CONTINUE + END IF + ELSE + IF( BETA.EQ.ZERO )THEN + DO 60, J = 1, N + DO 50, I = J, N + C( I, J ) = ZERO + 50 CONTINUE + 60 CONTINUE + ELSE + DO 80, J = 1, N + DO 70, I = J, N + C( I, J ) = BETA*C( I, J ) + 70 CONTINUE + 80 CONTINUE + END IF + END IF + RETURN + END IF +* +* Start the operations. +* + IF( LSAME( TRANS, 'N' ) )THEN +* +* Form C := alpha*A*A' + beta*C. +* + IF( UPPER )THEN + DO 130, J = 1, N + IF( BETA.EQ.ZERO )THEN + DO 90, I = 1, J + C( I, J ) = ZERO + 90 CONTINUE + ELSE IF( BETA.NE.ONE )THEN + DO 100, I = 1, J + C( I, J ) = BETA*C( I, J ) + 100 CONTINUE + END IF + DO 120, L = 1, K + IF( A( J, L ).NE.ZERO )THEN + TEMP = ALPHA*A( J, L ) + DO 110, I = 1, J + C( I, J ) = C( I, J ) + TEMP*A( I, L ) + 110 CONTINUE + END IF + 120 CONTINUE + 130 CONTINUE + ELSE + DO 180, J = 1, N + IF( BETA.EQ.ZERO )THEN + DO 140, I = J, N + C( I, J ) = ZERO + 140 CONTINUE + ELSE IF( BETA.NE.ONE )THEN + DO 150, I = J, N + C( I, J ) = BETA*C( I, J ) + 150 CONTINUE + END IF + DO 170, L = 1, K + IF( A( J, L ).NE.ZERO )THEN + TEMP = ALPHA*A( J, L ) + DO 160, I = J, N + C( I, J ) = C( I, J ) + TEMP*A( I, L ) + 160 CONTINUE + END IF + 170 CONTINUE + 180 CONTINUE + END IF + ELSE +* +* Form C := alpha*A'*A + beta*C. +* + IF( UPPER )THEN + DO 210, J = 1, N + DO 200, I = 1, J + TEMP = ZERO + DO 190, L = 1, K + TEMP = TEMP + A( L, I )*A( L, J ) + 190 CONTINUE + IF( BETA.EQ.ZERO )THEN + C( I, J ) = ALPHA*TEMP + ELSE + C( I, J ) = ALPHA*TEMP + BETA*C( I, J ) + END IF + 200 CONTINUE + 210 CONTINUE + ELSE + DO 240, J = 1, N + DO 230, I = J, N + TEMP = ZERO + DO 220, L = 1, K + TEMP = TEMP + A( L, I )*A( L, J ) + 220 CONTINUE + IF( BETA.EQ.ZERO )THEN + C( I, J ) = ALPHA*TEMP + ELSE + C( I, J ) = ALPHA*TEMP + BETA*C( I, J ) + END IF + 230 CONTINUE + 240 CONTINUE + END IF + END IF +* + RETURN +* +* End of DSYRK . +* + END diff --git a/ext/blas/dtbmv.f b/ext/blas/dtbmv.f new file mode 100755 index 000000000..1363db79c --- /dev/null +++ b/ext/blas/dtbmv.f @@ -0,0 +1,342 @@ + SUBROUTINE DTBMV ( UPLO, TRANS, DIAG, N, K, A, LDA, X, INCX ) +* .. Scalar Arguments .. + INTEGER INCX, K, LDA, N + CHARACTER*1 DIAG, TRANS, UPLO +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), X( * ) +* .. +* +* Purpose +* ======= +* +* DTBMV performs one of the matrix-vector operations +* +* x := A*x, or x := A'*x, +* +* where x is an n element vector and A is an n by n unit, or non-unit, +* upper or lower triangular band matrix, with ( k + 1 ) diagonals. +* +* Parameters +* ========== +* +* UPLO - CHARACTER*1. +* On entry, UPLO specifies whether the matrix is an upper or +* lower triangular matrix as follows: +* +* UPLO = 'U' or 'u' A is an upper triangular matrix. +* +* UPLO = 'L' or 'l' A is a lower triangular matrix. +* +* Unchanged on exit. +* +* TRANS - CHARACTER*1. +* On entry, TRANS specifies the operation to be performed as +* follows: +* +* TRANS = 'N' or 'n' x := A*x. +* +* TRANS = 'T' or 't' x := A'*x. +* +* TRANS = 'C' or 'c' x := A'*x. +* +* Unchanged on exit. +* +* DIAG - CHARACTER*1. +* On entry, DIAG specifies whether or not A is unit +* triangular as follows: +* +* DIAG = 'U' or 'u' A is assumed to be unit triangular. +* +* DIAG = 'N' or 'n' A is not assumed to be unit +* triangular. +* +* Unchanged on exit. +* +* N - INTEGER. +* On entry, N specifies the order of the matrix A. +* N must be at least zero. +* Unchanged on exit. +* +* K - INTEGER. +* On entry with UPLO = 'U' or 'u', K specifies the number of +* super-diagonals of the matrix A. +* On entry with UPLO = 'L' or 'l', K specifies the number of +* sub-diagonals of the matrix A. +* K must satisfy 0 .le. K. +* Unchanged on exit. +* +* A - DOUBLE PRECISION array of DIMENSION ( LDA, n ). +* Before entry with UPLO = 'U' or 'u', the leading ( k + 1 ) +* by n part of the array A must contain the upper triangular +* band part of the matrix of coefficients, supplied column by +* column, with the leading diagonal of the matrix in row +* ( k + 1 ) of the array, the first super-diagonal starting at +* position 2 in row k, and so on. The top left k by k triangle +* of the array A is not referenced. +* The following program segment will transfer an upper +* triangular band matrix from conventional full matrix storage +* to band storage: +* +* DO 20, J = 1, N +* M = K + 1 - J +* DO 10, I = MAX( 1, J - K ), J +* A( M + I, J ) = matrix( I, J ) +* 10 CONTINUE +* 20 CONTINUE +* +* Before entry with UPLO = 'L' or 'l', the leading ( k + 1 ) +* by n part of the array A must contain the lower triangular +* band part of the matrix of coefficients, supplied column by +* column, with the leading diagonal of the matrix in row 1 of +* the array, the first sub-diagonal starting at position 1 in +* row 2, and so on. The bottom right k by k triangle of the +* array A is not referenced. +* The following program segment will transfer a lower +* triangular band matrix from conventional full matrix storage +* to band storage: +* +* DO 20, J = 1, N +* M = 1 - J +* DO 10, I = J, MIN( N, J + K ) +* A( M + I, J ) = matrix( I, J ) +* 10 CONTINUE +* 20 CONTINUE +* +* Note that when DIAG = 'U' or 'u' the elements of the array A +* corresponding to the diagonal elements of the matrix are not +* referenced, but are assumed to be unity. +* Unchanged on exit. +* +* LDA - INTEGER. +* On entry, LDA specifies the first dimension of A as declared +* in the calling (sub) program. LDA must be at least +* ( k + 1 ). +* Unchanged on exit. +* +* X - DOUBLE PRECISION array of dimension at least +* ( 1 + ( n - 1 )*abs( INCX ) ). +* Before entry, the incremented array X must contain the n +* element vector x. On exit, X is overwritten with the +* tranformed vector x. +* +* INCX - INTEGER. +* On entry, INCX specifies the increment for the elements of +* X. INCX must not be zero. +* Unchanged on exit. +* +* +* Level 2 Blas routine. +* +* -- Written on 22-October-1986. +* Jack Dongarra, Argonne National Lab. +* Jeremy Du Croz, Nag Central Office. +* Sven Hammarling, Nag Central Office. +* Richard Hanson, Sandia National Labs. +* +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D+0 ) +* .. Local Scalars .. + DOUBLE PRECISION TEMP + INTEGER I, INFO, IX, J, JX, KPLUS1, KX, L + LOGICAL NOUNIT +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. External Subroutines .. + EXTERNAL XERBLA +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + IF ( .NOT.LSAME( UPLO , 'U' ).AND. + $ .NOT.LSAME( UPLO , 'L' ) )THEN + INFO = 1 + ELSE IF( .NOT.LSAME( TRANS, 'N' ).AND. + $ .NOT.LSAME( TRANS, 'T' ).AND. + $ .NOT.LSAME( TRANS, 'C' ) )THEN + INFO = 2 + ELSE IF( .NOT.LSAME( DIAG , 'U' ).AND. + $ .NOT.LSAME( DIAG , 'N' ) )THEN + INFO = 3 + ELSE IF( N.LT.0 )THEN + INFO = 4 + ELSE IF( K.LT.0 )THEN + INFO = 5 + ELSE IF( LDA.LT.( K + 1 ) )THEN + INFO = 7 + ELSE IF( INCX.EQ.0 )THEN + INFO = 9 + END IF + IF( INFO.NE.0 )THEN + CALL XERBLA( 'DTBMV ', INFO ) + RETURN + END IF +* +* Quick return if possible. +* + IF( N.EQ.0 ) + $ RETURN +* + NOUNIT = LSAME( DIAG, 'N' ) +* +* Set up the start point in X if the increment is not unity. This +* will be ( N - 1 )*INCX too small for descending loops. +* + IF( INCX.LE.0 )THEN + KX = 1 - ( N - 1 )*INCX + ELSE IF( INCX.NE.1 )THEN + KX = 1 + END IF +* +* Start the operations. In this version the elements of A are +* accessed sequentially with one pass through A. +* + IF( LSAME( TRANS, 'N' ) )THEN +* +* Form x := A*x. +* + IF( LSAME( UPLO, 'U' ) )THEN + KPLUS1 = K + 1 + IF( INCX.EQ.1 )THEN + DO 20, J = 1, N + IF( X( J ).NE.ZERO )THEN + TEMP = X( J ) + L = KPLUS1 - J + DO 10, I = MAX( 1, J - K ), J - 1 + X( I ) = X( I ) + TEMP*A( L + I, J ) + 10 CONTINUE + IF( NOUNIT ) + $ X( J ) = X( J )*A( KPLUS1, J ) + END IF + 20 CONTINUE + ELSE + JX = KX + DO 40, J = 1, N + IF( X( JX ).NE.ZERO )THEN + TEMP = X( JX ) + IX = KX + L = KPLUS1 - J + DO 30, I = MAX( 1, J - K ), J - 1 + X( IX ) = X( IX ) + TEMP*A( L + I, J ) + IX = IX + INCX + 30 CONTINUE + IF( NOUNIT ) + $ X( JX ) = X( JX )*A( KPLUS1, J ) + END IF + JX = JX + INCX + IF( J.GT.K ) + $ KX = KX + INCX + 40 CONTINUE + END IF + ELSE + IF( INCX.EQ.1 )THEN + DO 60, J = N, 1, -1 + IF( X( J ).NE.ZERO )THEN + TEMP = X( J ) + L = 1 - J + DO 50, I = MIN( N, J + K ), J + 1, -1 + X( I ) = X( I ) + TEMP*A( L + I, J ) + 50 CONTINUE + IF( NOUNIT ) + $ X( J ) = X( J )*A( 1, J ) + END IF + 60 CONTINUE + ELSE + KX = KX + ( N - 1 )*INCX + JX = KX + DO 80, J = N, 1, -1 + IF( X( JX ).NE.ZERO )THEN + TEMP = X( JX ) + IX = KX + L = 1 - J + DO 70, I = MIN( N, J + K ), J + 1, -1 + X( IX ) = X( IX ) + TEMP*A( L + I, J ) + IX = IX - INCX + 70 CONTINUE + IF( NOUNIT ) + $ X( JX ) = X( JX )*A( 1, J ) + END IF + JX = JX - INCX + IF( ( N - J ).GE.K ) + $ KX = KX - INCX + 80 CONTINUE + END IF + END IF + ELSE +* +* Form x := A'*x. +* + IF( LSAME( UPLO, 'U' ) )THEN + KPLUS1 = K + 1 + IF( INCX.EQ.1 )THEN + DO 100, J = N, 1, -1 + TEMP = X( J ) + L = KPLUS1 - J + IF( NOUNIT ) + $ TEMP = TEMP*A( KPLUS1, J ) + DO 90, I = J - 1, MAX( 1, J - K ), -1 + TEMP = TEMP + A( L + I, J )*X( I ) + 90 CONTINUE + X( J ) = TEMP + 100 CONTINUE + ELSE + KX = KX + ( N - 1 )*INCX + JX = KX + DO 120, J = N, 1, -1 + TEMP = X( JX ) + KX = KX - INCX + IX = KX + L = KPLUS1 - J + IF( NOUNIT ) + $ TEMP = TEMP*A( KPLUS1, J ) + DO 110, I = J - 1, MAX( 1, J - K ), -1 + TEMP = TEMP + A( L + I, J )*X( IX ) + IX = IX - INCX + 110 CONTINUE + X( JX ) = TEMP + JX = JX - INCX + 120 CONTINUE + END IF + ELSE + IF( INCX.EQ.1 )THEN + DO 140, J = 1, N + TEMP = X( J ) + L = 1 - J + IF( NOUNIT ) + $ TEMP = TEMP*A( 1, J ) + DO 130, I = J + 1, MIN( N, J + K ) + TEMP = TEMP + A( L + I, J )*X( I ) + 130 CONTINUE + X( J ) = TEMP + 140 CONTINUE + ELSE + JX = KX + DO 160, J = 1, N + TEMP = X( JX ) + KX = KX + INCX + IX = KX + L = 1 - J + IF( NOUNIT ) + $ TEMP = TEMP*A( 1, J ) + DO 150, I = J + 1, MIN( N, J + K ) + TEMP = TEMP + A( L + I, J )*X( IX ) + IX = IX + INCX + 150 CONTINUE + X( JX ) = TEMP + JX = JX + INCX + 160 CONTINUE + END IF + END IF + END IF +* + RETURN +* +* End of DTBMV . +* + END diff --git a/ext/blas/dtbsv.f b/ext/blas/dtbsv.f new file mode 100755 index 000000000..d87ed82d5 --- /dev/null +++ b/ext/blas/dtbsv.f @@ -0,0 +1,346 @@ + SUBROUTINE DTBSV ( UPLO, TRANS, DIAG, N, K, A, LDA, X, INCX ) +* .. Scalar Arguments .. + INTEGER INCX, K, LDA, N + CHARACTER*1 DIAG, TRANS, UPLO +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), X( * ) +* .. +* +* Purpose +* ======= +* +* DTBSV solves one of the systems of equations +* +* A*x = b, or A'*x = b, +* +* where b and x are n element vectors and A is an n by n unit, or +* non-unit, upper or lower triangular band matrix, with ( k + 1 ) +* diagonals. +* +* No test for singularity or near-singularity is included in this +* routine. Such tests must be performed before calling this routine. +* +* Parameters +* ========== +* +* UPLO - CHARACTER*1. +* On entry, UPLO specifies whether the matrix is an upper or +* lower triangular matrix as follows: +* +* UPLO = 'U' or 'u' A is an upper triangular matrix. +* +* UPLO = 'L' or 'l' A is a lower triangular matrix. +* +* Unchanged on exit. +* +* TRANS - CHARACTER*1. +* On entry, TRANS specifies the equations to be solved as +* follows: +* +* TRANS = 'N' or 'n' A*x = b. +* +* TRANS = 'T' or 't' A'*x = b. +* +* TRANS = 'C' or 'c' A'*x = b. +* +* Unchanged on exit. +* +* DIAG - CHARACTER*1. +* On entry, DIAG specifies whether or not A is unit +* triangular as follows: +* +* DIAG = 'U' or 'u' A is assumed to be unit triangular. +* +* DIAG = 'N' or 'n' A is not assumed to be unit +* triangular. +* +* Unchanged on exit. +* +* N - INTEGER. +* On entry, N specifies the order of the matrix A. +* N must be at least zero. +* Unchanged on exit. +* +* K - INTEGER. +* On entry with UPLO = 'U' or 'u', K specifies the number of +* super-diagonals of the matrix A. +* On entry with UPLO = 'L' or 'l', K specifies the number of +* sub-diagonals of the matrix A. +* K must satisfy 0 .le. K. +* Unchanged on exit. +* +* A - DOUBLE PRECISION array of DIMENSION ( LDA, n ). +* Before entry with UPLO = 'U' or 'u', the leading ( k + 1 ) +* by n part of the array A must contain the upper triangular +* band part of the matrix of coefficients, supplied column by +* column, with the leading diagonal of the matrix in row +* ( k + 1 ) of the array, the first super-diagonal starting at +* position 2 in row k, and so on. The top left k by k triangle +* of the array A is not referenced. +* The following program segment will transfer an upper +* triangular band matrix from conventional full matrix storage +* to band storage: +* +* DO 20, J = 1, N +* M = K + 1 - J +* DO 10, I = MAX( 1, J - K ), J +* A( M + I, J ) = matrix( I, J ) +* 10 CONTINUE +* 20 CONTINUE +* +* Before entry with UPLO = 'L' or 'l', the leading ( k + 1 ) +* by n part of the array A must contain the lower triangular +* band part of the matrix of coefficients, supplied column by +* column, with the leading diagonal of the matrix in row 1 of +* the array, the first sub-diagonal starting at position 1 in +* row 2, and so on. The bottom right k by k triangle of the +* array A is not referenced. +* The following program segment will transfer a lower +* triangular band matrix from conventional full matrix storage +* to band storage: +* +* DO 20, J = 1, N +* M = 1 - J +* DO 10, I = J, MIN( N, J + K ) +* A( M + I, J ) = matrix( I, J ) +* 10 CONTINUE +* 20 CONTINUE +* +* Note that when DIAG = 'U' or 'u' the elements of the array A +* corresponding to the diagonal elements of the matrix are not +* referenced, but are assumed to be unity. +* Unchanged on exit. +* +* LDA - INTEGER. +* On entry, LDA specifies the first dimension of A as declared +* in the calling (sub) program. LDA must be at least +* ( k + 1 ). +* Unchanged on exit. +* +* X - DOUBLE PRECISION array of dimension at least +* ( 1 + ( n - 1 )*abs( INCX ) ). +* Before entry, the incremented array X must contain the n +* element right-hand side vector b. On exit, X is overwritten +* with the solution vector x. +* +* INCX - INTEGER. +* On entry, INCX specifies the increment for the elements of +* X. INCX must not be zero. +* Unchanged on exit. +* +* +* Level 2 Blas routine. +* +* -- Written on 22-October-1986. +* Jack Dongarra, Argonne National Lab. +* Jeremy Du Croz, Nag Central Office. +* Sven Hammarling, Nag Central Office. +* Richard Hanson, Sandia National Labs. +* +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D+0 ) +* .. Local Scalars .. + DOUBLE PRECISION TEMP + INTEGER I, INFO, IX, J, JX, KPLUS1, KX, L + LOGICAL NOUNIT +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. External Subroutines .. + EXTERNAL XERBLA +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + IF ( .NOT.LSAME( UPLO , 'U' ).AND. + $ .NOT.LSAME( UPLO , 'L' ) )THEN + INFO = 1 + ELSE IF( .NOT.LSAME( TRANS, 'N' ).AND. + $ .NOT.LSAME( TRANS, 'T' ).AND. + $ .NOT.LSAME( TRANS, 'C' ) )THEN + INFO = 2 + ELSE IF( .NOT.LSAME( DIAG , 'U' ).AND. + $ .NOT.LSAME( DIAG , 'N' ) )THEN + INFO = 3 + ELSE IF( N.LT.0 )THEN + INFO = 4 + ELSE IF( K.LT.0 )THEN + INFO = 5 + ELSE IF( LDA.LT.( K + 1 ) )THEN + INFO = 7 + ELSE IF( INCX.EQ.0 )THEN + INFO = 9 + END IF + IF( INFO.NE.0 )THEN + CALL XERBLA( 'DTBSV ', INFO ) + RETURN + END IF +* +* Quick return if possible. +* + IF( N.EQ.0 ) + $ RETURN +* + NOUNIT = LSAME( DIAG, 'N' ) +* +* Set up the start point in X if the increment is not unity. This +* will be ( N - 1 )*INCX too small for descending loops. +* + IF( INCX.LE.0 )THEN + KX = 1 - ( N - 1 )*INCX + ELSE IF( INCX.NE.1 )THEN + KX = 1 + END IF +* +* Start the operations. In this version the elements of A are +* accessed by sequentially with one pass through A. +* + IF( LSAME( TRANS, 'N' ) )THEN +* +* Form x := inv( A )*x. +* + IF( LSAME( UPLO, 'U' ) )THEN + KPLUS1 = K + 1 + IF( INCX.EQ.1 )THEN + DO 20, J = N, 1, -1 + IF( X( J ).NE.ZERO )THEN + L = KPLUS1 - J + IF( NOUNIT ) + $ X( J ) = X( J )/A( KPLUS1, J ) + TEMP = X( J ) + DO 10, I = J - 1, MAX( 1, J - K ), -1 + X( I ) = X( I ) - TEMP*A( L + I, J ) + 10 CONTINUE + END IF + 20 CONTINUE + ELSE + KX = KX + ( N - 1 )*INCX + JX = KX + DO 40, J = N, 1, -1 + KX = KX - INCX + IF( X( JX ).NE.ZERO )THEN + IX = KX + L = KPLUS1 - J + IF( NOUNIT ) + $ X( JX ) = X( JX )/A( KPLUS1, J ) + TEMP = X( JX ) + DO 30, I = J - 1, MAX( 1, J - K ), -1 + X( IX ) = X( IX ) - TEMP*A( L + I, J ) + IX = IX - INCX + 30 CONTINUE + END IF + JX = JX - INCX + 40 CONTINUE + END IF + ELSE + IF( INCX.EQ.1 )THEN + DO 60, J = 1, N + IF( X( J ).NE.ZERO )THEN + L = 1 - J + IF( NOUNIT ) + $ X( J ) = X( J )/A( 1, J ) + TEMP = X( J ) + DO 50, I = J + 1, MIN( N, J + K ) + X( I ) = X( I ) - TEMP*A( L + I, J ) + 50 CONTINUE + END IF + 60 CONTINUE + ELSE + JX = KX + DO 80, J = 1, N + KX = KX + INCX + IF( X( JX ).NE.ZERO )THEN + IX = KX + L = 1 - J + IF( NOUNIT ) + $ X( JX ) = X( JX )/A( 1, J ) + TEMP = X( JX ) + DO 70, I = J + 1, MIN( N, J + K ) + X( IX ) = X( IX ) - TEMP*A( L + I, J ) + IX = IX + INCX + 70 CONTINUE + END IF + JX = JX + INCX + 80 CONTINUE + END IF + END IF + ELSE +* +* Form x := inv( A')*x. +* + IF( LSAME( UPLO, 'U' ) )THEN + KPLUS1 = K + 1 + IF( INCX.EQ.1 )THEN + DO 100, J = 1, N + TEMP = X( J ) + L = KPLUS1 - J + DO 90, I = MAX( 1, J - K ), J - 1 + TEMP = TEMP - A( L + I, J )*X( I ) + 90 CONTINUE + IF( NOUNIT ) + $ TEMP = TEMP/A( KPLUS1, J ) + X( J ) = TEMP + 100 CONTINUE + ELSE + JX = KX + DO 120, J = 1, N + TEMP = X( JX ) + IX = KX + L = KPLUS1 - J + DO 110, I = MAX( 1, J - K ), J - 1 + TEMP = TEMP - A( L + I, J )*X( IX ) + IX = IX + INCX + 110 CONTINUE + IF( NOUNIT ) + $ TEMP = TEMP/A( KPLUS1, J ) + X( JX ) = TEMP + JX = JX + INCX + IF( J.GT.K ) + $ KX = KX + INCX + 120 CONTINUE + END IF + ELSE + IF( INCX.EQ.1 )THEN + DO 140, J = N, 1, -1 + TEMP = X( J ) + L = 1 - J + DO 130, I = MIN( N, J + K ), J + 1, -1 + TEMP = TEMP - A( L + I, J )*X( I ) + 130 CONTINUE + IF( NOUNIT ) + $ TEMP = TEMP/A( 1, J ) + X( J ) = TEMP + 140 CONTINUE + ELSE + KX = KX + ( N - 1 )*INCX + JX = KX + DO 160, J = N, 1, -1 + TEMP = X( JX ) + IX = KX + L = 1 - J + DO 150, I = MIN( N, J + K ), J + 1, -1 + TEMP = TEMP - A( L + I, J )*X( IX ) + IX = IX - INCX + 150 CONTINUE + IF( NOUNIT ) + $ TEMP = TEMP/A( 1, J ) + X( JX ) = TEMP + JX = JX - INCX + IF( ( N - J ).GE.K ) + $ KX = KX - INCX + 160 CONTINUE + END IF + END IF + END IF +* + RETURN +* +* End of DTBSV . +* + END diff --git a/ext/blas/dtpmv.f b/ext/blas/dtpmv.f new file mode 100755 index 000000000..ee11bc1b0 --- /dev/null +++ b/ext/blas/dtpmv.f @@ -0,0 +1,299 @@ + SUBROUTINE DTPMV ( UPLO, TRANS, DIAG, N, AP, X, INCX ) +* .. Scalar Arguments .. + INTEGER INCX, N + CHARACTER*1 DIAG, TRANS, UPLO +* .. Array Arguments .. + DOUBLE PRECISION AP( * ), X( * ) +* .. +* +* Purpose +* ======= +* +* DTPMV performs one of the matrix-vector operations +* +* x := A*x, or x := A'*x, +* +* where x is an n element vector and A is an n by n unit, or non-unit, +* upper or lower triangular matrix, supplied in packed form. +* +* Parameters +* ========== +* +* UPLO - CHARACTER*1. +* On entry, UPLO specifies whether the matrix is an upper or +* lower triangular matrix as follows: +* +* UPLO = 'U' or 'u' A is an upper triangular matrix. +* +* UPLO = 'L' or 'l' A is a lower triangular matrix. +* +* Unchanged on exit. +* +* TRANS - CHARACTER*1. +* On entry, TRANS specifies the operation to be performed as +* follows: +* +* TRANS = 'N' or 'n' x := A*x. +* +* TRANS = 'T' or 't' x := A'*x. +* +* TRANS = 'C' or 'c' x := A'*x. +* +* Unchanged on exit. +* +* DIAG - CHARACTER*1. +* On entry, DIAG specifies whether or not A is unit +* triangular as follows: +* +* DIAG = 'U' or 'u' A is assumed to be unit triangular. +* +* DIAG = 'N' or 'n' A is not assumed to be unit +* triangular. +* +* Unchanged on exit. +* +* N - INTEGER. +* On entry, N specifies the order of the matrix A. +* N must be at least zero. +* Unchanged on exit. +* +* AP - DOUBLE PRECISION array of DIMENSION at least +* ( ( n*( n + 1 ) )/2 ). +* Before entry with UPLO = 'U' or 'u', the array AP must +* contain the upper triangular matrix packed sequentially, +* column by column, so that AP( 1 ) contains a( 1, 1 ), +* AP( 2 ) and AP( 3 ) contain a( 1, 2 ) and a( 2, 2 ) +* respectively, and so on. +* Before entry with UPLO = 'L' or 'l', the array AP must +* contain the lower triangular matrix packed sequentially, +* column by column, so that AP( 1 ) contains a( 1, 1 ), +* AP( 2 ) and AP( 3 ) contain a( 2, 1 ) and a( 3, 1 ) +* respectively, and so on. +* Note that when DIAG = 'U' or 'u', the diagonal elements of +* A are not referenced, but are assumed to be unity. +* Unchanged on exit. +* +* X - DOUBLE PRECISION array of dimension at least +* ( 1 + ( n - 1 )*abs( INCX ) ). +* Before entry, the incremented array X must contain the n +* element vector x. On exit, X is overwritten with the +* tranformed vector x. +* +* INCX - INTEGER. +* On entry, INCX specifies the increment for the elements of +* X. INCX must not be zero. +* Unchanged on exit. +* +* +* Level 2 Blas routine. +* +* -- Written on 22-October-1986. +* Jack Dongarra, Argonne National Lab. +* Jeremy Du Croz, Nag Central Office. +* Sven Hammarling, Nag Central Office. +* Richard Hanson, Sandia National Labs. +* +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D+0 ) +* .. Local Scalars .. + DOUBLE PRECISION TEMP + INTEGER I, INFO, IX, J, JX, K, KK, KX + LOGICAL NOUNIT +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. External Subroutines .. + EXTERNAL XERBLA +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + IF ( .NOT.LSAME( UPLO , 'U' ).AND. + $ .NOT.LSAME( UPLO , 'L' ) )THEN + INFO = 1 + ELSE IF( .NOT.LSAME( TRANS, 'N' ).AND. + $ .NOT.LSAME( TRANS, 'T' ).AND. + $ .NOT.LSAME( TRANS, 'C' ) )THEN + INFO = 2 + ELSE IF( .NOT.LSAME( DIAG , 'U' ).AND. + $ .NOT.LSAME( DIAG , 'N' ) )THEN + INFO = 3 + ELSE IF( N.LT.0 )THEN + INFO = 4 + ELSE IF( INCX.EQ.0 )THEN + INFO = 7 + END IF + IF( INFO.NE.0 )THEN + CALL XERBLA( 'DTPMV ', INFO ) + RETURN + END IF +* +* Quick return if possible. +* + IF( N.EQ.0 ) + $ RETURN +* + NOUNIT = LSAME( DIAG, 'N' ) +* +* Set up the start point in X if the increment is not unity. This +* will be ( N - 1 )*INCX too small for descending loops. +* + IF( INCX.LE.0 )THEN + KX = 1 - ( N - 1 )*INCX + ELSE IF( INCX.NE.1 )THEN + KX = 1 + END IF +* +* Start the operations. In this version the elements of AP are +* accessed sequentially with one pass through AP. +* + IF( LSAME( TRANS, 'N' ) )THEN +* +* Form x:= A*x. +* + IF( LSAME( UPLO, 'U' ) )THEN + KK =1 + IF( INCX.EQ.1 )THEN + DO 20, J = 1, N + IF( X( J ).NE.ZERO )THEN + TEMP = X( J ) + K = KK + DO 10, I = 1, J - 1 + X( I ) = X( I ) + TEMP*AP( K ) + K = K + 1 + 10 CONTINUE + IF( NOUNIT ) + $ X( J ) = X( J )*AP( KK + J - 1 ) + END IF + KK = KK + J + 20 CONTINUE + ELSE + JX = KX + DO 40, J = 1, N + IF( X( JX ).NE.ZERO )THEN + TEMP = X( JX ) + IX = KX + DO 30, K = KK, KK + J - 2 + X( IX ) = X( IX ) + TEMP*AP( K ) + IX = IX + INCX + 30 CONTINUE + IF( NOUNIT ) + $ X( JX ) = X( JX )*AP( KK + J - 1 ) + END IF + JX = JX + INCX + KK = KK + J + 40 CONTINUE + END IF + ELSE + KK = ( N*( N + 1 ) )/2 + IF( INCX.EQ.1 )THEN + DO 60, J = N, 1, -1 + IF( X( J ).NE.ZERO )THEN + TEMP = X( J ) + K = KK + DO 50, I = N, J + 1, -1 + X( I ) = X( I ) + TEMP*AP( K ) + K = K - 1 + 50 CONTINUE + IF( NOUNIT ) + $ X( J ) = X( J )*AP( KK - N + J ) + END IF + KK = KK - ( N - J + 1 ) + 60 CONTINUE + ELSE + KX = KX + ( N - 1 )*INCX + JX = KX + DO 80, J = N, 1, -1 + IF( X( JX ).NE.ZERO )THEN + TEMP = X( JX ) + IX = KX + DO 70, K = KK, KK - ( N - ( J + 1 ) ), -1 + X( IX ) = X( IX ) + TEMP*AP( K ) + IX = IX - INCX + 70 CONTINUE + IF( NOUNIT ) + $ X( JX ) = X( JX )*AP( KK - N + J ) + END IF + JX = JX - INCX + KK = KK - ( N - J + 1 ) + 80 CONTINUE + END IF + END IF + ELSE +* +* Form x := A'*x. +* + IF( LSAME( UPLO, 'U' ) )THEN + KK = ( N*( N + 1 ) )/2 + IF( INCX.EQ.1 )THEN + DO 100, J = N, 1, -1 + TEMP = X( J ) + IF( NOUNIT ) + $ TEMP = TEMP*AP( KK ) + K = KK - 1 + DO 90, I = J - 1, 1, -1 + TEMP = TEMP + AP( K )*X( I ) + K = K - 1 + 90 CONTINUE + X( J ) = TEMP + KK = KK - J + 100 CONTINUE + ELSE + JX = KX + ( N - 1 )*INCX + DO 120, J = N, 1, -1 + TEMP = X( JX ) + IX = JX + IF( NOUNIT ) + $ TEMP = TEMP*AP( KK ) + DO 110, K = KK - 1, KK - J + 1, -1 + IX = IX - INCX + TEMP = TEMP + AP( K )*X( IX ) + 110 CONTINUE + X( JX ) = TEMP + JX = JX - INCX + KK = KK - J + 120 CONTINUE + END IF + ELSE + KK = 1 + IF( INCX.EQ.1 )THEN + DO 140, J = 1, N + TEMP = X( J ) + IF( NOUNIT ) + $ TEMP = TEMP*AP( KK ) + K = KK + 1 + DO 130, I = J + 1, N + TEMP = TEMP + AP( K )*X( I ) + K = K + 1 + 130 CONTINUE + X( J ) = TEMP + KK = KK + ( N - J + 1 ) + 140 CONTINUE + ELSE + JX = KX + DO 160, J = 1, N + TEMP = X( JX ) + IX = JX + IF( NOUNIT ) + $ TEMP = TEMP*AP( KK ) + DO 150, K = KK + 1, KK + N - J + IX = IX + INCX + TEMP = TEMP + AP( K )*X( IX ) + 150 CONTINUE + X( JX ) = TEMP + JX = JX + INCX + KK = KK + ( N - J + 1 ) + 160 CONTINUE + END IF + END IF + END IF +* + RETURN +* +* End of DTPMV . +* + END diff --git a/ext/blas/dtpsv.f b/ext/blas/dtpsv.f new file mode 100755 index 000000000..91930d9fb --- /dev/null +++ b/ext/blas/dtpsv.f @@ -0,0 +1,302 @@ + SUBROUTINE DTPSV ( UPLO, TRANS, DIAG, N, AP, X, INCX ) +* .. Scalar Arguments .. + INTEGER INCX, N + CHARACTER*1 DIAG, TRANS, UPLO +* .. Array Arguments .. + DOUBLE PRECISION AP( * ), X( * ) +* .. +* +* Purpose +* ======= +* +* DTPSV solves one of the systems of equations +* +* A*x = b, or A'*x = b, +* +* where b and x are n element vectors and A is an n by n unit, or +* non-unit, upper or lower triangular matrix, supplied in packed form. +* +* No test for singularity or near-singularity is included in this +* routine. Such tests must be performed before calling this routine. +* +* Parameters +* ========== +* +* UPLO - CHARACTER*1. +* On entry, UPLO specifies whether the matrix is an upper or +* lower triangular matrix as follows: +* +* UPLO = 'U' or 'u' A is an upper triangular matrix. +* +* UPLO = 'L' or 'l' A is a lower triangular matrix. +* +* Unchanged on exit. +* +* TRANS - CHARACTER*1. +* On entry, TRANS specifies the equations to be solved as +* follows: +* +* TRANS = 'N' or 'n' A*x = b. +* +* TRANS = 'T' or 't' A'*x = b. +* +* TRANS = 'C' or 'c' A'*x = b. +* +* Unchanged on exit. +* +* DIAG - CHARACTER*1. +* On entry, DIAG specifies whether or not A is unit +* triangular as follows: +* +* DIAG = 'U' or 'u' A is assumed to be unit triangular. +* +* DIAG = 'N' or 'n' A is not assumed to be unit +* triangular. +* +* Unchanged on exit. +* +* N - INTEGER. +* On entry, N specifies the order of the matrix A. +* N must be at least zero. +* Unchanged on exit. +* +* AP - DOUBLE PRECISION array of DIMENSION at least +* ( ( n*( n + 1 ) )/2 ). +* Before entry with UPLO = 'U' or 'u', the array AP must +* contain the upper triangular matrix packed sequentially, +* column by column, so that AP( 1 ) contains a( 1, 1 ), +* AP( 2 ) and AP( 3 ) contain a( 1, 2 ) and a( 2, 2 ) +* respectively, and so on. +* Before entry with UPLO = 'L' or 'l', the array AP must +* contain the lower triangular matrix packed sequentially, +* column by column, so that AP( 1 ) contains a( 1, 1 ), +* AP( 2 ) and AP( 3 ) contain a( 2, 1 ) and a( 3, 1 ) +* respectively, and so on. +* Note that when DIAG = 'U' or 'u', the diagonal elements of +* A are not referenced, but are assumed to be unity. +* Unchanged on exit. +* +* X - DOUBLE PRECISION array of dimension at least +* ( 1 + ( n - 1 )*abs( INCX ) ). +* Before entry, the incremented array X must contain the n +* element right-hand side vector b. On exit, X is overwritten +* with the solution vector x. +* +* INCX - INTEGER. +* On entry, INCX specifies the increment for the elements of +* X. INCX must not be zero. +* Unchanged on exit. +* +* +* Level 2 Blas routine. +* +* -- Written on 22-October-1986. +* Jack Dongarra, Argonne National Lab. +* Jeremy Du Croz, Nag Central Office. +* Sven Hammarling, Nag Central Office. +* Richard Hanson, Sandia National Labs. +* +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D+0 ) +* .. Local Scalars .. + DOUBLE PRECISION TEMP + INTEGER I, INFO, IX, J, JX, K, KK, KX + LOGICAL NOUNIT +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. External Subroutines .. + EXTERNAL XERBLA +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + IF ( .NOT.LSAME( UPLO , 'U' ).AND. + $ .NOT.LSAME( UPLO , 'L' ) )THEN + INFO = 1 + ELSE IF( .NOT.LSAME( TRANS, 'N' ).AND. + $ .NOT.LSAME( TRANS, 'T' ).AND. + $ .NOT.LSAME( TRANS, 'C' ) )THEN + INFO = 2 + ELSE IF( .NOT.LSAME( DIAG , 'U' ).AND. + $ .NOT.LSAME( DIAG , 'N' ) )THEN + INFO = 3 + ELSE IF( N.LT.0 )THEN + INFO = 4 + ELSE IF( INCX.EQ.0 )THEN + INFO = 7 + END IF + IF( INFO.NE.0 )THEN + CALL XERBLA( 'DTPSV ', INFO ) + RETURN + END IF +* +* Quick return if possible. +* + IF( N.EQ.0 ) + $ RETURN +* + NOUNIT = LSAME( DIAG, 'N' ) +* +* Set up the start point in X if the increment is not unity. This +* will be ( N - 1 )*INCX too small for descending loops. +* + IF( INCX.LE.0 )THEN + KX = 1 - ( N - 1 )*INCX + ELSE IF( INCX.NE.1 )THEN + KX = 1 + END IF +* +* Start the operations. In this version the elements of AP are +* accessed sequentially with one pass through AP. +* + IF( LSAME( TRANS, 'N' ) )THEN +* +* Form x := inv( A )*x. +* + IF( LSAME( UPLO, 'U' ) )THEN + KK = ( N*( N + 1 ) )/2 + IF( INCX.EQ.1 )THEN + DO 20, J = N, 1, -1 + IF( X( J ).NE.ZERO )THEN + IF( NOUNIT ) + $ X( J ) = X( J )/AP( KK ) + TEMP = X( J ) + K = KK - 1 + DO 10, I = J - 1, 1, -1 + X( I ) = X( I ) - TEMP*AP( K ) + K = K - 1 + 10 CONTINUE + END IF + KK = KK - J + 20 CONTINUE + ELSE + JX = KX + ( N - 1 )*INCX + DO 40, J = N, 1, -1 + IF( X( JX ).NE.ZERO )THEN + IF( NOUNIT ) + $ X( JX ) = X( JX )/AP( KK ) + TEMP = X( JX ) + IX = JX + DO 30, K = KK - 1, KK - J + 1, -1 + IX = IX - INCX + X( IX ) = X( IX ) - TEMP*AP( K ) + 30 CONTINUE + END IF + JX = JX - INCX + KK = KK - J + 40 CONTINUE + END IF + ELSE + KK = 1 + IF( INCX.EQ.1 )THEN + DO 60, J = 1, N + IF( X( J ).NE.ZERO )THEN + IF( NOUNIT ) + $ X( J ) = X( J )/AP( KK ) + TEMP = X( J ) + K = KK + 1 + DO 50, I = J + 1, N + X( I ) = X( I ) - TEMP*AP( K ) + K = K + 1 + 50 CONTINUE + END IF + KK = KK + ( N - J + 1 ) + 60 CONTINUE + ELSE + JX = KX + DO 80, J = 1, N + IF( X( JX ).NE.ZERO )THEN + IF( NOUNIT ) + $ X( JX ) = X( JX )/AP( KK ) + TEMP = X( JX ) + IX = JX + DO 70, K = KK + 1, KK + N - J + IX = IX + INCX + X( IX ) = X( IX ) - TEMP*AP( K ) + 70 CONTINUE + END IF + JX = JX + INCX + KK = KK + ( N - J + 1 ) + 80 CONTINUE + END IF + END IF + ELSE +* +* Form x := inv( A' )*x. +* + IF( LSAME( UPLO, 'U' ) )THEN + KK = 1 + IF( INCX.EQ.1 )THEN + DO 100, J = 1, N + TEMP = X( J ) + K = KK + DO 90, I = 1, J - 1 + TEMP = TEMP - AP( K )*X( I ) + K = K + 1 + 90 CONTINUE + IF( NOUNIT ) + $ TEMP = TEMP/AP( KK + J - 1 ) + X( J ) = TEMP + KK = KK + J + 100 CONTINUE + ELSE + JX = KX + DO 120, J = 1, N + TEMP = X( JX ) + IX = KX + DO 110, K = KK, KK + J - 2 + TEMP = TEMP - AP( K )*X( IX ) + IX = IX + INCX + 110 CONTINUE + IF( NOUNIT ) + $ TEMP = TEMP/AP( KK + J - 1 ) + X( JX ) = TEMP + JX = JX + INCX + KK = KK + J + 120 CONTINUE + END IF + ELSE + KK = ( N*( N + 1 ) )/2 + IF( INCX.EQ.1 )THEN + DO 140, J = N, 1, -1 + TEMP = X( J ) + K = KK + DO 130, I = N, J + 1, -1 + TEMP = TEMP - AP( K )*X( I ) + K = K - 1 + 130 CONTINUE + IF( NOUNIT ) + $ TEMP = TEMP/AP( KK - N + J ) + X( J ) = TEMP + KK = KK - ( N - J + 1 ) + 140 CONTINUE + ELSE + KX = KX + ( N - 1 )*INCX + JX = KX + DO 160, J = N, 1, -1 + TEMP = X( JX ) + IX = KX + DO 150, K = KK, KK - ( N - ( J + 1 ) ), -1 + TEMP = TEMP - AP( K )*X( IX ) + IX = IX - INCX + 150 CONTINUE + IF( NOUNIT ) + $ TEMP = TEMP/AP( KK - N + J ) + X( JX ) = TEMP + JX = JX - INCX + KK = KK - (N - J + 1 ) + 160 CONTINUE + END IF + END IF + END IF +* + RETURN +* +* End of DTPSV . +* + END diff --git a/ext/blas/dtrmm.f b/ext/blas/dtrmm.f new file mode 100755 index 000000000..40c7740c9 --- /dev/null +++ b/ext/blas/dtrmm.f @@ -0,0 +1,355 @@ + SUBROUTINE DTRMM ( SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA, A, LDA, + $ B, LDB ) +* .. Scalar Arguments .. + CHARACTER*1 SIDE, UPLO, TRANSA, DIAG + INTEGER M, N, LDA, LDB + DOUBLE PRECISION ALPHA +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), B( LDB, * ) +* .. +* +* Purpose +* ======= +* +* DTRMM performs one of the matrix-matrix operations +* +* B := alpha*op( A )*B, or B := alpha*B*op( A ), +* +* where alpha is a scalar, B is an m by n matrix, A is a unit, or +* non-unit, upper or lower triangular matrix and op( A ) is one of +* +* op( A ) = A or op( A ) = A'. +* +* Parameters +* ========== +* +* SIDE - CHARACTER*1. +* On entry, SIDE specifies whether op( A ) multiplies B from +* the left or right as follows: +* +* SIDE = 'L' or 'l' B := alpha*op( A )*B. +* +* SIDE = 'R' or 'r' B := alpha*B*op( A ). +* +* Unchanged on exit. +* +* UPLO - CHARACTER*1. +* On entry, UPLO specifies whether the matrix A is an upper or +* lower triangular matrix as follows: +* +* UPLO = 'U' or 'u' A is an upper triangular matrix. +* +* UPLO = 'L' or 'l' A is a lower triangular matrix. +* +* Unchanged on exit. +* +* TRANSA - CHARACTER*1. +* On entry, TRANSA specifies the form of op( A ) to be used in +* the matrix multiplication as follows: +* +* TRANSA = 'N' or 'n' op( A ) = A. +* +* TRANSA = 'T' or 't' op( A ) = A'. +* +* TRANSA = 'C' or 'c' op( A ) = A'. +* +* Unchanged on exit. +* +* DIAG - CHARACTER*1. +* On entry, DIAG specifies whether or not A is unit triangular +* as follows: +* +* DIAG = 'U' or 'u' A is assumed to be unit triangular. +* +* DIAG = 'N' or 'n' A is not assumed to be unit +* triangular. +* +* Unchanged on exit. +* +* M - INTEGER. +* On entry, M specifies the number of rows of B. M must be at +* least zero. +* Unchanged on exit. +* +* N - INTEGER. +* On entry, N specifies the number of columns of B. N must be +* at least zero. +* Unchanged on exit. +* +* ALPHA - DOUBLE PRECISION. +* On entry, ALPHA specifies the scalar alpha. When alpha is +* zero then A is not referenced and B need not be set before +* entry. +* Unchanged on exit. +* +* A - DOUBLE PRECISION array of DIMENSION ( LDA, k ), where k is m +* when SIDE = 'L' or 'l' and is n when SIDE = 'R' or 'r'. +* Before entry with UPLO = 'U' or 'u', the leading k by k +* upper triangular part of the array A must contain the upper +* triangular matrix and the strictly lower triangular part of +* A is not referenced. +* Before entry with UPLO = 'L' or 'l', the leading k by k +* lower triangular part of the array A must contain the lower +* triangular matrix and the strictly upper triangular part of +* A is not referenced. +* Note that when DIAG = 'U' or 'u', the diagonal elements of +* A are not referenced either, but are assumed to be unity. +* Unchanged on exit. +* +* LDA - INTEGER. +* On entry, LDA specifies the first dimension of A as declared +* in the calling (sub) program. When SIDE = 'L' or 'l' then +* LDA must be at least max( 1, m ), when SIDE = 'R' or 'r' +* then LDA must be at least max( 1, n ). +* Unchanged on exit. +* +* B - DOUBLE PRECISION array of DIMENSION ( LDB, n ). +* Before entry, the leading m by n part of the array B must +* contain the matrix B, and on exit is overwritten by the +* transformed matrix. +* +* LDB - INTEGER. +* On entry, LDB specifies the first dimension of B as declared +* in the calling (sub) program. LDB must be at least +* max( 1, m ). +* Unchanged on exit. +* +* +* Level 3 Blas routine. +* +* -- Written on 8-February-1989. +* Jack Dongarra, Argonne National Laboratory. +* Iain Duff, AERE Harwell. +* Jeremy Du Croz, Numerical Algorithms Group Ltd. +* Sven Hammarling, Numerical Algorithms Group Ltd. +* +* +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. External Subroutines .. + EXTERNAL XERBLA +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. Local Scalars .. + LOGICAL LSIDE, NOUNIT, UPPER + INTEGER I, INFO, J, K, NROWA + DOUBLE PRECISION TEMP +* .. Parameters .. + DOUBLE PRECISION ONE , ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + LSIDE = LSAME( SIDE , 'L' ) + IF( LSIDE )THEN + NROWA = M + ELSE + NROWA = N + END IF + NOUNIT = LSAME( DIAG , 'N' ) + UPPER = LSAME( UPLO , 'U' ) +* + INFO = 0 + IF( ( .NOT.LSIDE ).AND. + $ ( .NOT.LSAME( SIDE , 'R' ) ) )THEN + INFO = 1 + ELSE IF( ( .NOT.UPPER ).AND. + $ ( .NOT.LSAME( UPLO , 'L' ) ) )THEN + INFO = 2 + ELSE IF( ( .NOT.LSAME( TRANSA, 'N' ) ).AND. + $ ( .NOT.LSAME( TRANSA, 'T' ) ).AND. + $ ( .NOT.LSAME( TRANSA, 'C' ) ) )THEN + INFO = 3 + ELSE IF( ( .NOT.LSAME( DIAG , 'U' ) ).AND. + $ ( .NOT.LSAME( DIAG , 'N' ) ) )THEN + INFO = 4 + ELSE IF( M .LT.0 )THEN + INFO = 5 + ELSE IF( N .LT.0 )THEN + INFO = 6 + ELSE IF( LDA.LT.MAX( 1, NROWA ) )THEN + INFO = 9 + ELSE IF( LDB.LT.MAX( 1, M ) )THEN + INFO = 11 + END IF + IF( INFO.NE.0 )THEN + CALL XERBLA( 'DTRMM ', INFO ) + RETURN + END IF +* +* Quick return if possible. +* + IF( N.EQ.0 ) + $ RETURN +* +* And when alpha.eq.zero. +* + IF( ALPHA.EQ.ZERO )THEN + DO 20, J = 1, N + DO 10, I = 1, M + B( I, J ) = ZERO + 10 CONTINUE + 20 CONTINUE + RETURN + END IF +* +* Start the operations. +* + IF( LSIDE )THEN + IF( LSAME( TRANSA, 'N' ) )THEN +* +* Form B := alpha*A*B. +* + IF( UPPER )THEN + DO 50, J = 1, N + DO 40, K = 1, M + IF( B( K, J ).NE.ZERO )THEN + TEMP = ALPHA*B( K, J ) + DO 30, I = 1, K - 1 + B( I, J ) = B( I, J ) + TEMP*A( I, K ) + 30 CONTINUE + IF( NOUNIT ) + $ TEMP = TEMP*A( K, K ) + B( K, J ) = TEMP + END IF + 40 CONTINUE + 50 CONTINUE + ELSE + DO 80, J = 1, N + DO 70 K = M, 1, -1 + IF( B( K, J ).NE.ZERO )THEN + TEMP = ALPHA*B( K, J ) + B( K, J ) = TEMP + IF( NOUNIT ) + $ B( K, J ) = B( K, J )*A( K, K ) + DO 60, I = K + 1, M + B( I, J ) = B( I, J ) + TEMP*A( I, K ) + 60 CONTINUE + END IF + 70 CONTINUE + 80 CONTINUE + END IF + ELSE +* +* Form B := alpha*A'*B. +* + IF( UPPER )THEN + DO 110, J = 1, N + DO 100, I = M, 1, -1 + TEMP = B( I, J ) + IF( NOUNIT ) + $ TEMP = TEMP*A( I, I ) + DO 90, K = 1, I - 1 + TEMP = TEMP + A( K, I )*B( K, J ) + 90 CONTINUE + B( I, J ) = ALPHA*TEMP + 100 CONTINUE + 110 CONTINUE + ELSE + DO 140, J = 1, N + DO 130, I = 1, M + TEMP = B( I, J ) + IF( NOUNIT ) + $ TEMP = TEMP*A( I, I ) + DO 120, K = I + 1, M + TEMP = TEMP + A( K, I )*B( K, J ) + 120 CONTINUE + B( I, J ) = ALPHA*TEMP + 130 CONTINUE + 140 CONTINUE + END IF + END IF + ELSE + IF( LSAME( TRANSA, 'N' ) )THEN +* +* Form B := alpha*B*A. +* + IF( UPPER )THEN + DO 180, J = N, 1, -1 + TEMP = ALPHA + IF( NOUNIT ) + $ TEMP = TEMP*A( J, J ) + DO 150, I = 1, M + B( I, J ) = TEMP*B( I, J ) + 150 CONTINUE + DO 170, K = 1, J - 1 + IF( A( K, J ).NE.ZERO )THEN + TEMP = ALPHA*A( K, J ) + DO 160, I = 1, M + B( I, J ) = B( I, J ) + TEMP*B( I, K ) + 160 CONTINUE + END IF + 170 CONTINUE + 180 CONTINUE + ELSE + DO 220, J = 1, N + TEMP = ALPHA + IF( NOUNIT ) + $ TEMP = TEMP*A( J, J ) + DO 190, I = 1, M + B( I, J ) = TEMP*B( I, J ) + 190 CONTINUE + DO 210, K = J + 1, N + IF( A( K, J ).NE.ZERO )THEN + TEMP = ALPHA*A( K, J ) + DO 200, I = 1, M + B( I, J ) = B( I, J ) + TEMP*B( I, K ) + 200 CONTINUE + END IF + 210 CONTINUE + 220 CONTINUE + END IF + ELSE +* +* Form B := alpha*B*A'. +* + IF( UPPER )THEN + DO 260, K = 1, N + DO 240, J = 1, K - 1 + IF( A( J, K ).NE.ZERO )THEN + TEMP = ALPHA*A( J, K ) + DO 230, I = 1, M + B( I, J ) = B( I, J ) + TEMP*B( I, K ) + 230 CONTINUE + END IF + 240 CONTINUE + TEMP = ALPHA + IF( NOUNIT ) + $ TEMP = TEMP*A( K, K ) + IF( TEMP.NE.ONE )THEN + DO 250, I = 1, M + B( I, K ) = TEMP*B( I, K ) + 250 CONTINUE + END IF + 260 CONTINUE + ELSE + DO 300, K = N, 1, -1 + DO 280, J = K + 1, N + IF( A( J, K ).NE.ZERO )THEN + TEMP = ALPHA*A( J, K ) + DO 270, I = 1, M + B( I, J ) = B( I, J ) + TEMP*B( I, K ) + 270 CONTINUE + END IF + 280 CONTINUE + TEMP = ALPHA + IF( NOUNIT ) + $ TEMP = TEMP*A( K, K ) + IF( TEMP.NE.ONE )THEN + DO 290, I = 1, M + B( I, K ) = TEMP*B( I, K ) + 290 CONTINUE + END IF + 300 CONTINUE + END IF + END IF + END IF +* + RETURN +* +* End of DTRMM . +* + END diff --git a/ext/blas/dtrmv.f b/ext/blas/dtrmv.f new file mode 100755 index 000000000..3d5c61b20 --- /dev/null +++ b/ext/blas/dtrmv.f @@ -0,0 +1,286 @@ + SUBROUTINE DTRMV ( UPLO, TRANS, DIAG, N, A, LDA, X, INCX ) +* .. Scalar Arguments .. + INTEGER INCX, LDA, N + CHARACTER*1 DIAG, TRANS, UPLO +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), X( * ) +* .. +* +* Purpose +* ======= +* +* DTRMV performs one of the matrix-vector operations +* +* x := A*x, or x := A'*x, +* +* where x is an n element vector and A is an n by n unit, or non-unit, +* upper or lower triangular matrix. +* +* Parameters +* ========== +* +* UPLO - CHARACTER*1. +* On entry, UPLO specifies whether the matrix is an upper or +* lower triangular matrix as follows: +* +* UPLO = 'U' or 'u' A is an upper triangular matrix. +* +* UPLO = 'L' or 'l' A is a lower triangular matrix. +* +* Unchanged on exit. +* +* TRANS - CHARACTER*1. +* On entry, TRANS specifies the operation to be performed as +* follows: +* +* TRANS = 'N' or 'n' x := A*x. +* +* TRANS = 'T' or 't' x := A'*x. +* +* TRANS = 'C' or 'c' x := A'*x. +* +* Unchanged on exit. +* +* DIAG - CHARACTER*1. +* On entry, DIAG specifies whether or not A is unit +* triangular as follows: +* +* DIAG = 'U' or 'u' A is assumed to be unit triangular. +* +* DIAG = 'N' or 'n' A is not assumed to be unit +* triangular. +* +* Unchanged on exit. +* +* N - INTEGER. +* On entry, N specifies the order of the matrix A. +* N must be at least zero. +* Unchanged on exit. +* +* A - DOUBLE PRECISION array of DIMENSION ( LDA, n ). +* Before entry with UPLO = 'U' or 'u', the leading n by n +* upper triangular part of the array A must contain the upper +* triangular matrix and the strictly lower triangular part of +* A is not referenced. +* Before entry with UPLO = 'L' or 'l', the leading n by n +* lower triangular part of the array A must contain the lower +* triangular matrix and the strictly upper triangular part of +* A is not referenced. +* Note that when DIAG = 'U' or 'u', the diagonal elements of +* A are not referenced either, but are assumed to be unity. +* Unchanged on exit. +* +* LDA - INTEGER. +* On entry, LDA specifies the first dimension of A as declared +* in the calling (sub) program. LDA must be at least +* max( 1, n ). +* Unchanged on exit. +* +* X - DOUBLE PRECISION array of dimension at least +* ( 1 + ( n - 1 )*abs( INCX ) ). +* Before entry, the incremented array X must contain the n +* element vector x. On exit, X is overwritten with the +* tranformed vector x. +* +* INCX - INTEGER. +* On entry, INCX specifies the increment for the elements of +* X. INCX must not be zero. +* Unchanged on exit. +* +* +* Level 2 Blas routine. +* +* -- Written on 22-October-1986. +* Jack Dongarra, Argonne National Lab. +* Jeremy Du Croz, Nag Central Office. +* Sven Hammarling, Nag Central Office. +* Richard Hanson, Sandia National Labs. +* +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D+0 ) +* .. Local Scalars .. + DOUBLE PRECISION TEMP + INTEGER I, INFO, IX, J, JX, KX + LOGICAL NOUNIT +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. External Subroutines .. + EXTERNAL XERBLA +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + IF ( .NOT.LSAME( UPLO , 'U' ).AND. + $ .NOT.LSAME( UPLO , 'L' ) )THEN + INFO = 1 + ELSE IF( .NOT.LSAME( TRANS, 'N' ).AND. + $ .NOT.LSAME( TRANS, 'T' ).AND. + $ .NOT.LSAME( TRANS, 'C' ) )THEN + INFO = 2 + ELSE IF( .NOT.LSAME( DIAG , 'U' ).AND. + $ .NOT.LSAME( DIAG , 'N' ) )THEN + INFO = 3 + ELSE IF( N.LT.0 )THEN + INFO = 4 + ELSE IF( LDA.LT.MAX( 1, N ) )THEN + INFO = 6 + ELSE IF( INCX.EQ.0 )THEN + INFO = 8 + END IF + IF( INFO.NE.0 )THEN + CALL XERBLA( 'DTRMV ', INFO ) + RETURN + END IF +* +* Quick return if possible. +* + IF( N.EQ.0 ) + $ RETURN +* + NOUNIT = LSAME( DIAG, 'N' ) +* +* Set up the start point in X if the increment is not unity. This +* will be ( N - 1 )*INCX too small for descending loops. +* + IF( INCX.LE.0 )THEN + KX = 1 - ( N - 1 )*INCX + ELSE IF( INCX.NE.1 )THEN + KX = 1 + END IF +* +* Start the operations. In this version the elements of A are +* accessed sequentially with one pass through A. +* + IF( LSAME( TRANS, 'N' ) )THEN +* +* Form x := A*x. +* + IF( LSAME( UPLO, 'U' ) )THEN + IF( INCX.EQ.1 )THEN + DO 20, J = 1, N + IF( X( J ).NE.ZERO )THEN + TEMP = X( J ) + DO 10, I = 1, J - 1 + X( I ) = X( I ) + TEMP*A( I, J ) + 10 CONTINUE + IF( NOUNIT ) + $ X( J ) = X( J )*A( J, J ) + END IF + 20 CONTINUE + ELSE + JX = KX + DO 40, J = 1, N + IF( X( JX ).NE.ZERO )THEN + TEMP = X( JX ) + IX = KX + DO 30, I = 1, J - 1 + X( IX ) = X( IX ) + TEMP*A( I, J ) + IX = IX + INCX + 30 CONTINUE + IF( NOUNIT ) + $ X( JX ) = X( JX )*A( J, J ) + END IF + JX = JX + INCX + 40 CONTINUE + END IF + ELSE + IF( INCX.EQ.1 )THEN + DO 60, J = N, 1, -1 + IF( X( J ).NE.ZERO )THEN + TEMP = X( J ) + DO 50, I = N, J + 1, -1 + X( I ) = X( I ) + TEMP*A( I, J ) + 50 CONTINUE + IF( NOUNIT ) + $ X( J ) = X( J )*A( J, J ) + END IF + 60 CONTINUE + ELSE + KX = KX + ( N - 1 )*INCX + JX = KX + DO 80, J = N, 1, -1 + IF( X( JX ).NE.ZERO )THEN + TEMP = X( JX ) + IX = KX + DO 70, I = N, J + 1, -1 + X( IX ) = X( IX ) + TEMP*A( I, J ) + IX = IX - INCX + 70 CONTINUE + IF( NOUNIT ) + $ X( JX ) = X( JX )*A( J, J ) + END IF + JX = JX - INCX + 80 CONTINUE + END IF + END IF + ELSE +* +* Form x := A'*x. +* + IF( LSAME( UPLO, 'U' ) )THEN + IF( INCX.EQ.1 )THEN + DO 100, J = N, 1, -1 + TEMP = X( J ) + IF( NOUNIT ) + $ TEMP = TEMP*A( J, J ) + DO 90, I = J - 1, 1, -1 + TEMP = TEMP + A( I, J )*X( I ) + 90 CONTINUE + X( J ) = TEMP + 100 CONTINUE + ELSE + JX = KX + ( N - 1 )*INCX + DO 120, J = N, 1, -1 + TEMP = X( JX ) + IX = JX + IF( NOUNIT ) + $ TEMP = TEMP*A( J, J ) + DO 110, I = J - 1, 1, -1 + IX = IX - INCX + TEMP = TEMP + A( I, J )*X( IX ) + 110 CONTINUE + X( JX ) = TEMP + JX = JX - INCX + 120 CONTINUE + END IF + ELSE + IF( INCX.EQ.1 )THEN + DO 140, J = 1, N + TEMP = X( J ) + IF( NOUNIT ) + $ TEMP = TEMP*A( J, J ) + DO 130, I = J + 1, N + TEMP = TEMP + A( I, J )*X( I ) + 130 CONTINUE + X( J ) = TEMP + 140 CONTINUE + ELSE + JX = KX + DO 160, J = 1, N + TEMP = X( JX ) + IX = JX + IF( NOUNIT ) + $ TEMP = TEMP*A( J, J ) + DO 150, I = J + 1, N + IX = IX + INCX + TEMP = TEMP + A( I, J )*X( IX ) + 150 CONTINUE + X( JX ) = TEMP + JX = JX + INCX + 160 CONTINUE + END IF + END IF + END IF +* + RETURN +* +* End of DTRMV . +* + END diff --git a/ext/blas/dtrsm.f b/ext/blas/dtrsm.f new file mode 100755 index 000000000..e8425142b --- /dev/null +++ b/ext/blas/dtrsm.f @@ -0,0 +1,378 @@ + SUBROUTINE DTRSM ( SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA, A, LDA, + $ B, LDB ) +* .. Scalar Arguments .. + CHARACTER*1 SIDE, UPLO, TRANSA, DIAG + INTEGER M, N, LDA, LDB + DOUBLE PRECISION ALPHA +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), B( LDB, * ) +* .. +* +* Purpose +* ======= +* +* DTRSM solves one of the matrix equations +* +* op( A )*X = alpha*B, or X*op( A ) = alpha*B, +* +* where alpha is a scalar, X and B are m by n matrices, A is a unit, or +* non-unit, upper or lower triangular matrix and op( A ) is one of +* +* op( A ) = A or op( A ) = A'. +* +* The matrix X is overwritten on B. +* +* Parameters +* ========== +* +* SIDE - CHARACTER*1. +* On entry, SIDE specifies whether op( A ) appears on the left +* or right of X as follows: +* +* SIDE = 'L' or 'l' op( A )*X = alpha*B. +* +* SIDE = 'R' or 'r' X*op( A ) = alpha*B. +* +* Unchanged on exit. +* +* UPLO - CHARACTER*1. +* On entry, UPLO specifies whether the matrix A is an upper or +* lower triangular matrix as follows: +* +* UPLO = 'U' or 'u' A is an upper triangular matrix. +* +* UPLO = 'L' or 'l' A is a lower triangular matrix. +* +* Unchanged on exit. +* +* TRANSA - CHARACTER*1. +* On entry, TRANSA specifies the form of op( A ) to be used in +* the matrix multiplication as follows: +* +* TRANSA = 'N' or 'n' op( A ) = A. +* +* TRANSA = 'T' or 't' op( A ) = A'. +* +* TRANSA = 'C' or 'c' op( A ) = A'. +* +* Unchanged on exit. +* +* DIAG - CHARACTER*1. +* On entry, DIAG specifies whether or not A is unit triangular +* as follows: +* +* DIAG = 'U' or 'u' A is assumed to be unit triangular. +* +* DIAG = 'N' or 'n' A is not assumed to be unit +* triangular. +* +* Unchanged on exit. +* +* M - INTEGER. +* On entry, M specifies the number of rows of B. M must be at +* least zero. +* Unchanged on exit. +* +* N - INTEGER. +* On entry, N specifies the number of columns of B. N must be +* at least zero. +* Unchanged on exit. +* +* ALPHA - DOUBLE PRECISION. +* On entry, ALPHA specifies the scalar alpha. When alpha is +* zero then A is not referenced and B need not be set before +* entry. +* Unchanged on exit. +* +* A - DOUBLE PRECISION array of DIMENSION ( LDA, k ), where k is m +* when SIDE = 'L' or 'l' and is n when SIDE = 'R' or 'r'. +* Before entry with UPLO = 'U' or 'u', the leading k by k +* upper triangular part of the array A must contain the upper +* triangular matrix and the strictly lower triangular part of +* A is not referenced. +* Before entry with UPLO = 'L' or 'l', the leading k by k +* lower triangular part of the array A must contain the lower +* triangular matrix and the strictly upper triangular part of +* A is not referenced. +* Note that when DIAG = 'U' or 'u', the diagonal elements of +* A are not referenced either, but are assumed to be unity. +* Unchanged on exit. +* +* LDA - INTEGER. +* On entry, LDA specifies the first dimension of A as declared +* in the calling (sub) program. When SIDE = 'L' or 'l' then +* LDA must be at least max( 1, m ), when SIDE = 'R' or 'r' +* then LDA must be at least max( 1, n ). +* Unchanged on exit. +* +* B - DOUBLE PRECISION array of DIMENSION ( LDB, n ). +* Before entry, the leading m by n part of the array B must +* contain the right-hand side matrix B, and on exit is +* overwritten by the solution matrix X. +* +* LDB - INTEGER. +* On entry, LDB specifies the first dimension of B as declared +* in the calling (sub) program. LDB must be at least +* max( 1, m ). +* Unchanged on exit. +* +* +* Level 3 Blas routine. +* +* +* -- Written on 8-February-1989. +* Jack Dongarra, Argonne National Laboratory. +* Iain Duff, AERE Harwell. +* Jeremy Du Croz, Numerical Algorithms Group Ltd. +* Sven Hammarling, Numerical Algorithms Group Ltd. +* +* +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. External Subroutines .. + EXTERNAL XERBLA +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. Local Scalars .. + LOGICAL LSIDE, NOUNIT, UPPER + INTEGER I, INFO, J, K, NROWA + DOUBLE PRECISION TEMP +* .. Parameters .. + DOUBLE PRECISION ONE , ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + LSIDE = LSAME( SIDE , 'L' ) + IF( LSIDE )THEN + NROWA = M + ELSE + NROWA = N + END IF + NOUNIT = LSAME( DIAG , 'N' ) + UPPER = LSAME( UPLO , 'U' ) +* + INFO = 0 + IF( ( .NOT.LSIDE ).AND. + $ ( .NOT.LSAME( SIDE , 'R' ) ) )THEN + INFO = 1 + ELSE IF( ( .NOT.UPPER ).AND. + $ ( .NOT.LSAME( UPLO , 'L' ) ) )THEN + INFO = 2 + ELSE IF( ( .NOT.LSAME( TRANSA, 'N' ) ).AND. + $ ( .NOT.LSAME( TRANSA, 'T' ) ).AND. + $ ( .NOT.LSAME( TRANSA, 'C' ) ) )THEN + INFO = 3 + ELSE IF( ( .NOT.LSAME( DIAG , 'U' ) ).AND. + $ ( .NOT.LSAME( DIAG , 'N' ) ) )THEN + INFO = 4 + ELSE IF( M .LT.0 )THEN + INFO = 5 + ELSE IF( N .LT.0 )THEN + INFO = 6 + ELSE IF( LDA.LT.MAX( 1, NROWA ) )THEN + INFO = 9 + ELSE IF( LDB.LT.MAX( 1, M ) )THEN + INFO = 11 + END IF + IF( INFO.NE.0 )THEN + CALL XERBLA( 'DTRSM ', INFO ) + RETURN + END IF +* +* Quick return if possible. +* + IF( N.EQ.0 ) + $ RETURN +* +* And when alpha.eq.zero. +* + IF( ALPHA.EQ.ZERO )THEN + DO 20, J = 1, N + DO 10, I = 1, M + B( I, J ) = ZERO + 10 CONTINUE + 20 CONTINUE + RETURN + END IF +* +* Start the operations. +* + IF( LSIDE )THEN + IF( LSAME( TRANSA, 'N' ) )THEN +* +* Form B := alpha*inv( A )*B. +* + IF( UPPER )THEN + DO 60, J = 1, N + IF( ALPHA.NE.ONE )THEN + DO 30, I = 1, M + B( I, J ) = ALPHA*B( I, J ) + 30 CONTINUE + END IF + DO 50, K = M, 1, -1 + IF( B( K, J ).NE.ZERO )THEN + IF( NOUNIT ) + $ B( K, J ) = B( K, J )/A( K, K ) + DO 40, I = 1, K - 1 + B( I, J ) = B( I, J ) - B( K, J )*A( I, K ) + 40 CONTINUE + END IF + 50 CONTINUE + 60 CONTINUE + ELSE + DO 100, J = 1, N + IF( ALPHA.NE.ONE )THEN + DO 70, I = 1, M + B( I, J ) = ALPHA*B( I, J ) + 70 CONTINUE + END IF + DO 90 K = 1, M + IF( B( K, J ).NE.ZERO )THEN + IF( NOUNIT ) + $ B( K, J ) = B( K, J )/A( K, K ) + DO 80, I = K + 1, M + B( I, J ) = B( I, J ) - B( K, J )*A( I, K ) + 80 CONTINUE + END IF + 90 CONTINUE + 100 CONTINUE + END IF + ELSE +* +* Form B := alpha*inv( A' )*B. +* + IF( UPPER )THEN + DO 130, J = 1, N + DO 120, I = 1, M + TEMP = ALPHA*B( I, J ) + DO 110, K = 1, I - 1 + TEMP = TEMP - A( K, I )*B( K, J ) + 110 CONTINUE + IF( NOUNIT ) + $ TEMP = TEMP/A( I, I ) + B( I, J ) = TEMP + 120 CONTINUE + 130 CONTINUE + ELSE + DO 160, J = 1, N + DO 150, I = M, 1, -1 + TEMP = ALPHA*B( I, J ) + DO 140, K = I + 1, M + TEMP = TEMP - A( K, I )*B( K, J ) + 140 CONTINUE + IF( NOUNIT ) + $ TEMP = TEMP/A( I, I ) + B( I, J ) = TEMP + 150 CONTINUE + 160 CONTINUE + END IF + END IF + ELSE + IF( LSAME( TRANSA, 'N' ) )THEN +* +* Form B := alpha*B*inv( A ). +* + IF( UPPER )THEN + DO 210, J = 1, N + IF( ALPHA.NE.ONE )THEN + DO 170, I = 1, M + B( I, J ) = ALPHA*B( I, J ) + 170 CONTINUE + END IF + DO 190, K = 1, J - 1 + IF( A( K, J ).NE.ZERO )THEN + DO 180, I = 1, M + B( I, J ) = B( I, J ) - A( K, J )*B( I, K ) + 180 CONTINUE + END IF + 190 CONTINUE + IF( NOUNIT )THEN + TEMP = ONE/A( J, J ) + DO 200, I = 1, M + B( I, J ) = TEMP*B( I, J ) + 200 CONTINUE + END IF + 210 CONTINUE + ELSE + DO 260, J = N, 1, -1 + IF( ALPHA.NE.ONE )THEN + DO 220, I = 1, M + B( I, J ) = ALPHA*B( I, J ) + 220 CONTINUE + END IF + DO 240, K = J + 1, N + IF( A( K, J ).NE.ZERO )THEN + DO 230, I = 1, M + B( I, J ) = B( I, J ) - A( K, J )*B( I, K ) + 230 CONTINUE + END IF + 240 CONTINUE + IF( NOUNIT )THEN + TEMP = ONE/A( J, J ) + DO 250, I = 1, M + B( I, J ) = TEMP*B( I, J ) + 250 CONTINUE + END IF + 260 CONTINUE + END IF + ELSE +* +* Form B := alpha*B*inv( A' ). +* + IF( UPPER )THEN + DO 310, K = N, 1, -1 + IF( NOUNIT )THEN + TEMP = ONE/A( K, K ) + DO 270, I = 1, M + B( I, K ) = TEMP*B( I, K ) + 270 CONTINUE + END IF + DO 290, J = 1, K - 1 + IF( A( J, K ).NE.ZERO )THEN + TEMP = A( J, K ) + DO 280, I = 1, M + B( I, J ) = B( I, J ) - TEMP*B( I, K ) + 280 CONTINUE + END IF + 290 CONTINUE + IF( ALPHA.NE.ONE )THEN + DO 300, I = 1, M + B( I, K ) = ALPHA*B( I, K ) + 300 CONTINUE + END IF + 310 CONTINUE + ELSE + DO 360, K = 1, N + IF( NOUNIT )THEN + TEMP = ONE/A( K, K ) + DO 320, I = 1, M + B( I, K ) = TEMP*B( I, K ) + 320 CONTINUE + END IF + DO 340, J = K + 1, N + IF( A( J, K ).NE.ZERO )THEN + TEMP = A( J, K ) + DO 330, I = 1, M + B( I, J ) = B( I, J ) - TEMP*B( I, K ) + 330 CONTINUE + END IF + 340 CONTINUE + IF( ALPHA.NE.ONE )THEN + DO 350, I = 1, M + B( I, K ) = ALPHA*B( I, K ) + 350 CONTINUE + END IF + 360 CONTINUE + END IF + END IF + END IF +* + RETURN +* +* End of DTRSM . +* + END diff --git a/ext/blas/dtrsv.f b/ext/blas/dtrsv.f new file mode 100755 index 000000000..9c3e90a97 --- /dev/null +++ b/ext/blas/dtrsv.f @@ -0,0 +1,289 @@ + SUBROUTINE DTRSV ( UPLO, TRANS, DIAG, N, A, LDA, X, INCX ) +* .. Scalar Arguments .. + INTEGER INCX, LDA, N + CHARACTER*1 DIAG, TRANS, UPLO +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), X( * ) +* .. +* +* Purpose +* ======= +* +* DTRSV solves one of the systems of equations +* +* A*x = b, or A'*x = b, +* +* where b and x are n element vectors and A is an n by n unit, or +* non-unit, upper or lower triangular matrix. +* +* No test for singularity or near-singularity is included in this +* routine. Such tests must be performed before calling this routine. +* +* Parameters +* ========== +* +* UPLO - CHARACTER*1. +* On entry, UPLO specifies whether the matrix is an upper or +* lower triangular matrix as follows: +* +* UPLO = 'U' or 'u' A is an upper triangular matrix. +* +* UPLO = 'L' or 'l' A is a lower triangular matrix. +* +* Unchanged on exit. +* +* TRANS - CHARACTER*1. +* On entry, TRANS specifies the equations to be solved as +* follows: +* +* TRANS = 'N' or 'n' A*x = b. +* +* TRANS = 'T' or 't' A'*x = b. +* +* TRANS = 'C' or 'c' A'*x = b. +* +* Unchanged on exit. +* +* DIAG - CHARACTER*1. +* On entry, DIAG specifies whether or not A is unit +* triangular as follows: +* +* DIAG = 'U' or 'u' A is assumed to be unit triangular. +* +* DIAG = 'N' or 'n' A is not assumed to be unit +* triangular. +* +* Unchanged on exit. +* +* N - INTEGER. +* On entry, N specifies the order of the matrix A. +* N must be at least zero. +* Unchanged on exit. +* +* A - DOUBLE PRECISION array of DIMENSION ( LDA, n ). +* Before entry with UPLO = 'U' or 'u', the leading n by n +* upper triangular part of the array A must contain the upper +* triangular matrix and the strictly lower triangular part of +* A is not referenced. +* Before entry with UPLO = 'L' or 'l', the leading n by n +* lower triangular part of the array A must contain the lower +* triangular matrix and the strictly upper triangular part of +* A is not referenced. +* Note that when DIAG = 'U' or 'u', the diagonal elements of +* A are not referenced either, but are assumed to be unity. +* Unchanged on exit. +* +* LDA - INTEGER. +* On entry, LDA specifies the first dimension of A as declared +* in the calling (sub) program. LDA must be at least +* max( 1, n ). +* Unchanged on exit. +* +* X - DOUBLE PRECISION array of dimension at least +* ( 1 + ( n - 1 )*abs( INCX ) ). +* Before entry, the incremented array X must contain the n +* element right-hand side vector b. On exit, X is overwritten +* with the solution vector x. +* +* INCX - INTEGER. +* On entry, INCX specifies the increment for the elements of +* X. INCX must not be zero. +* Unchanged on exit. +* +* +* Level 2 Blas routine. +* +* -- Written on 22-October-1986. +* Jack Dongarra, Argonne National Lab. +* Jeremy Du Croz, Nag Central Office. +* Sven Hammarling, Nag Central Office. +* Richard Hanson, Sandia National Labs. +* +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D+0 ) +* .. Local Scalars .. + DOUBLE PRECISION TEMP + INTEGER I, INFO, IX, J, JX, KX + LOGICAL NOUNIT +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. External Subroutines .. + EXTERNAL XERBLA +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + IF ( .NOT.LSAME( UPLO , 'U' ).AND. + $ .NOT.LSAME( UPLO , 'L' ) )THEN + INFO = 1 + ELSE IF( .NOT.LSAME( TRANS, 'N' ).AND. + $ .NOT.LSAME( TRANS, 'T' ).AND. + $ .NOT.LSAME( TRANS, 'C' ) )THEN + INFO = 2 + ELSE IF( .NOT.LSAME( DIAG , 'U' ).AND. + $ .NOT.LSAME( DIAG , 'N' ) )THEN + INFO = 3 + ELSE IF( N.LT.0 )THEN + INFO = 4 + ELSE IF( LDA.LT.MAX( 1, N ) )THEN + INFO = 6 + ELSE IF( INCX.EQ.0 )THEN + INFO = 8 + END IF + IF( INFO.NE.0 )THEN + CALL XERBLA( 'DTRSV ', INFO ) + RETURN + END IF +* +* Quick return if possible. +* + IF( N.EQ.0 ) + $ RETURN +* + NOUNIT = LSAME( DIAG, 'N' ) +* +* Set up the start point in X if the increment is not unity. This +* will be ( N - 1 )*INCX too small for descending loops. +* + IF( INCX.LE.0 )THEN + KX = 1 - ( N - 1 )*INCX + ELSE IF( INCX.NE.1 )THEN + KX = 1 + END IF +* +* Start the operations. In this version the elements of A are +* accessed sequentially with one pass through A. +* + IF( LSAME( TRANS, 'N' ) )THEN +* +* Form x := inv( A )*x. +* + IF( LSAME( UPLO, 'U' ) )THEN + IF( INCX.EQ.1 )THEN + DO 20, J = N, 1, -1 + IF( X( J ).NE.ZERO )THEN + IF( NOUNIT ) + $ X( J ) = X( J )/A( J, J ) + TEMP = X( J ) + DO 10, I = J - 1, 1, -1 + X( I ) = X( I ) - TEMP*A( I, J ) + 10 CONTINUE + END IF + 20 CONTINUE + ELSE + JX = KX + ( N - 1 )*INCX + DO 40, J = N, 1, -1 + IF( X( JX ).NE.ZERO )THEN + IF( NOUNIT ) + $ X( JX ) = X( JX )/A( J, J ) + TEMP = X( JX ) + IX = JX + DO 30, I = J - 1, 1, -1 + IX = IX - INCX + X( IX ) = X( IX ) - TEMP*A( I, J ) + 30 CONTINUE + END IF + JX = JX - INCX + 40 CONTINUE + END IF + ELSE + IF( INCX.EQ.1 )THEN + DO 60, J = 1, N + IF( X( J ).NE.ZERO )THEN + IF( NOUNIT ) + $ X( J ) = X( J )/A( J, J ) + TEMP = X( J ) + DO 50, I = J + 1, N + X( I ) = X( I ) - TEMP*A( I, J ) + 50 CONTINUE + END IF + 60 CONTINUE + ELSE + JX = KX + DO 80, J = 1, N + IF( X( JX ).NE.ZERO )THEN + IF( NOUNIT ) + $ X( JX ) = X( JX )/A( J, J ) + TEMP = X( JX ) + IX = JX + DO 70, I = J + 1, N + IX = IX + INCX + X( IX ) = X( IX ) - TEMP*A( I, J ) + 70 CONTINUE + END IF + JX = JX + INCX + 80 CONTINUE + END IF + END IF + ELSE +* +* Form x := inv( A' )*x. +* + IF( LSAME( UPLO, 'U' ) )THEN + IF( INCX.EQ.1 )THEN + DO 100, J = 1, N + TEMP = X( J ) + DO 90, I = 1, J - 1 + TEMP = TEMP - A( I, J )*X( I ) + 90 CONTINUE + IF( NOUNIT ) + $ TEMP = TEMP/A( J, J ) + X( J ) = TEMP + 100 CONTINUE + ELSE + JX = KX + DO 120, J = 1, N + TEMP = X( JX ) + IX = KX + DO 110, I = 1, J - 1 + TEMP = TEMP - A( I, J )*X( IX ) + IX = IX + INCX + 110 CONTINUE + IF( NOUNIT ) + $ TEMP = TEMP/A( J, J ) + X( JX ) = TEMP + JX = JX + INCX + 120 CONTINUE + END IF + ELSE + IF( INCX.EQ.1 )THEN + DO 140, J = N, 1, -1 + TEMP = X( J ) + DO 130, I = N, J + 1, -1 + TEMP = TEMP - A( I, J )*X( I ) + 130 CONTINUE + IF( NOUNIT ) + $ TEMP = TEMP/A( J, J ) + X( J ) = TEMP + 140 CONTINUE + ELSE + KX = KX + ( N - 1 )*INCX + JX = KX + DO 160, J = N, 1, -1 + TEMP = X( JX ) + IX = KX + DO 150, I = N, J + 1, -1 + TEMP = TEMP - A( I, J )*X( IX ) + IX = IX - INCX + 150 CONTINUE + IF( NOUNIT ) + $ TEMP = TEMP/A( J, J ) + X( JX ) = TEMP + JX = JX - INCX + 160 CONTINUE + END IF + END IF + END IF +* + RETURN +* +* End of DTRSV . +* + END diff --git a/ext/blas/dzasum.f b/ext/blas/dzasum.f new file mode 100755 index 000000000..d21c1ffc9 --- /dev/null +++ b/ext/blas/dzasum.f @@ -0,0 +1,34 @@ + double precision function dzasum(n,zx,incx) +c +c takes the sum of the absolute values. +c jack dongarra, 3/11/78. +c modified 3/93 to return if incx .le. 0. +c modified 12/3/93, array(1) declarations changed to array(*) +c + double complex zx(*) + double precision stemp,dcabs1 + integer i,incx,ix,n +c + dzasum = 0.0d0 + stemp = 0.0d0 + if( n.le.0 .or. incx.le.0 )return + if(incx.eq.1)go to 20 +c +c code for increment not equal to 1 +c + ix = 1 + do 10 i = 1,n + stemp = stemp + dcabs1(zx(ix)) + ix = ix + incx + 10 continue + dzasum = stemp + return +c +c code for increment equal to 1 +c + 20 do 30 i = 1,n + stemp = stemp + dcabs1(zx(i)) + 30 continue + dzasum = stemp + return + end diff --git a/ext/blas/dznrm2.f b/ext/blas/dznrm2.f new file mode 100755 index 000000000..205ce3932 --- /dev/null +++ b/ext/blas/dznrm2.f @@ -0,0 +1,67 @@ + DOUBLE PRECISION FUNCTION DZNRM2( N, X, INCX ) +* .. Scalar Arguments .. + INTEGER INCX, N +* .. Array Arguments .. + COMPLEX*16 X( * ) +* .. +* +* DZNRM2 returns the euclidean norm of a vector via the function +* name, so that +* +* DZNRM2 := sqrt( conjg( x' )*x ) +* +* +* +* -- This version written on 25-October-1982. +* Modified on 14-October-1993 to inline the call to ZLASSQ. +* Sven Hammarling, Nag Ltd. +* +* +* .. Parameters .. + DOUBLE PRECISION ONE , ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. Local Scalars .. + INTEGER IX + DOUBLE PRECISION NORM, SCALE, SSQ, TEMP +* .. Intrinsic Functions .. + INTRINSIC ABS, DIMAG, DBLE, SQRT +* .. +* .. Executable Statements .. + IF( N.LT.1 .OR. INCX.LT.1 )THEN + NORM = ZERO + ELSE + SCALE = ZERO + SSQ = ONE +* The following loop is equivalent to this call to the LAPACK +* auxiliary routine: +* CALL ZLASSQ( N, X, INCX, SCALE, SSQ ) +* + DO 10, IX = 1, 1 + ( N - 1 )*INCX, INCX + IF( DBLE( X( IX ) ).NE.ZERO )THEN + TEMP = ABS( DBLE( X( IX ) ) ) + IF( SCALE.LT.TEMP )THEN + SSQ = ONE + SSQ*( SCALE/TEMP )**2 + SCALE = TEMP + ELSE + SSQ = SSQ + ( TEMP/SCALE )**2 + END IF + END IF + IF( DIMAG( X( IX ) ).NE.ZERO )THEN + TEMP = ABS( DIMAG( X( IX ) ) ) + IF( SCALE.LT.TEMP )THEN + SSQ = ONE + SSQ*( SCALE/TEMP )**2 + SCALE = TEMP + ELSE + SSQ = SSQ + ( TEMP/SCALE )**2 + END IF + END IF + 10 CONTINUE + NORM = SCALE * SQRT( SSQ ) + END IF +* + DZNRM2 = NORM + RETURN +* +* End of DZNRM2. +* + END diff --git a/ext/blas/icamax.f b/ext/blas/icamax.f new file mode 100755 index 000000000..b13d4904f --- /dev/null +++ b/ext/blas/icamax.f @@ -0,0 +1,43 @@ + integer function icamax(n,cx,incx) +c +c finds the index of element having max. absolute value. +c jack dongarra, linpack, 3/11/78. +c modified 3/93 to return if incx .le. 0. +c modified 12/3/93, array(1) declarations changed to array(*) +c + complex cx(*) + real smax + integer i,incx,ix,n + complex zdum + real cabs1 + cabs1(zdum) = abs(real(zdum)) + abs(aimag(zdum)) +c + icamax = 0 + if( n.lt.1 .or. incx.le.0 ) return + icamax = 1 + if(n.eq.1)return + if(incx.eq.1)go to 20 +c +c code for increment not equal to 1 +c + ix = 1 + smax = cabs1(cx(1)) + ix = ix + incx + do 10 i = 2,n + if(cabs1(cx(ix)).le.smax) go to 5 + icamax = i + smax = cabs1(cx(ix)) + 5 ix = ix + incx + 10 continue + return +c +c code for increment equal to 1 +c + 20 smax = cabs1(cx(1)) + do 30 i = 2,n + if(cabs1(cx(i)).le.smax) go to 30 + icamax = i + smax = cabs1(cx(i)) + 30 continue + return + end diff --git a/ext/blas/idamax.f b/ext/blas/idamax.f new file mode 100755 index 000000000..59d80dc41 --- /dev/null +++ b/ext/blas/idamax.f @@ -0,0 +1,39 @@ + integer function idamax(n,dx,incx) +c +c finds the index of element having max. absolute value. +c jack dongarra, linpack, 3/11/78. +c modified 3/93 to return if incx .le. 0. +c modified 12/3/93, array(1) declarations changed to array(*) +c + double precision dx(*),dmax + integer i,incx,ix,n +c + idamax = 0 + if( n.lt.1 .or. incx.le.0 ) return + idamax = 1 + if(n.eq.1)return + if(incx.eq.1)go to 20 +c +c code for increment not equal to 1 +c + ix = 1 + dmax = dabs(dx(1)) + ix = ix + incx + do 10 i = 2,n + if(dabs(dx(ix)).le.dmax) go to 5 + idamax = i + dmax = dabs(dx(ix)) + 5 ix = ix + incx + 10 continue + return +c +c code for increment equal to 1 +c + 20 dmax = dabs(dx(1)) + do 30 i = 2,n + if(dabs(dx(i)).le.dmax) go to 30 + idamax = i + dmax = dabs(dx(i)) + 30 continue + return + end diff --git a/ext/blas/isamax.f b/ext/blas/isamax.f new file mode 100755 index 000000000..a649e0281 --- /dev/null +++ b/ext/blas/isamax.f @@ -0,0 +1,39 @@ + integer function isamax(n,sx,incx) +c +c finds the index of element having max. absolute value. +c jack dongarra, linpack, 3/11/78. +c modified 3/93 to return if incx .le. 0. +c modified 12/3/93, array(1) declarations changed to array(*) +c + real sx(*),smax + integer i,incx,ix,n +c + isamax = 0 + if( n.lt.1 .or. incx.le.0 ) return + isamax = 1 + if(n.eq.1)return + if(incx.eq.1)go to 20 +c +c code for increment not equal to 1 +c + ix = 1 + smax = abs(sx(1)) + ix = ix + incx + do 10 i = 2,n + if(abs(sx(ix)).le.smax) go to 5 + isamax = i + smax = abs(sx(ix)) + 5 ix = ix + incx + 10 continue + return +c +c code for increment equal to 1 +c + 20 smax = abs(sx(1)) + do 30 i = 2,n + if(abs(sx(i)).le.smax) go to 30 + isamax = i + smax = abs(sx(i)) + 30 continue + return + end diff --git a/ext/blas/izamax.f b/ext/blas/izamax.f new file mode 100755 index 000000000..ec14f827d --- /dev/null +++ b/ext/blas/izamax.f @@ -0,0 +1,41 @@ + integer function izamax(n,zx,incx) +c +c finds the index of element having max. absolute value. +c jack dongarra, 1/15/85. +c modified 3/93 to return if incx .le. 0. +c modified 12/3/93, array(1) declarations changed to array(*) +c + double complex zx(*) + double precision smax + integer i,incx,ix,n + double precision dcabs1 +c + izamax = 0 + if( n.lt.1 .or. incx.le.0 )return + izamax = 1 + if(n.eq.1)return + if(incx.eq.1)go to 20 +c +c code for increment not equal to 1 +c + ix = 1 + smax = dcabs1(zx(1)) + ix = ix + incx + do 10 i = 2,n + if(dcabs1(zx(ix)).le.smax) go to 5 + izamax = i + smax = dcabs1(zx(ix)) + 5 ix = ix + incx + 10 continue + return +c +c code for increment equal to 1 +c + 20 smax = dcabs1(zx(1)) + do 30 i = 2,n + if(dcabs1(zx(i)).le.smax) go to 30 + izamax = i + smax = dcabs1(zx(i)) + 30 continue + return + end diff --git a/ext/blas/lsame.f b/ext/blas/lsame.f new file mode 100755 index 000000000..f89517460 --- /dev/null +++ b/ext/blas/lsame.f @@ -0,0 +1,87 @@ + LOGICAL FUNCTION LSAME( CA, CB ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* January 31, 1994 +* +* .. Scalar Arguments .. + CHARACTER CA, CB +* .. +* +* Purpose +* ======= +* +* LSAME returns .TRUE. if CA is the same letter as CB regardless of +* case. +* +* Arguments +* ========= +* +* CA (input) CHARACTER*1 +* CB (input) CHARACTER*1 +* CA and CB specify the single characters to be compared. +* +* ===================================================================== +* +* .. Intrinsic Functions .. + INTRINSIC ICHAR +* .. +* .. Local Scalars .. + INTEGER INTA, INTB, ZCODE +* .. +* .. Executable Statements .. +* +* Test if the characters are equal +* + LSAME = CA.EQ.CB + IF( LSAME ) + $ RETURN +* +* Now test for equivalence if both characters are alphabetic. +* + ZCODE = ICHAR( 'Z' ) +* +* Use 'Z' rather than 'A' so that ASCII can be detected on Prime +* machines, on which ICHAR returns a value with bit 8 set. +* ICHAR('A') on Prime machines returns 193 which is the same as +* ICHAR('A') on an EBCDIC machine. +* + INTA = ICHAR( CA ) + INTB = ICHAR( CB ) +* + IF( ZCODE.EQ.90 .OR. ZCODE.EQ.122 ) THEN +* +* ASCII is assumed - ZCODE is the ASCII code of either lower or +* upper case 'Z'. +* + IF( INTA.GE.97 .AND. INTA.LE.122 ) INTA = INTA - 32 + IF( INTB.GE.97 .AND. INTB.LE.122 ) INTB = INTB - 32 +* + ELSE IF( ZCODE.EQ.233 .OR. ZCODE.EQ.169 ) THEN +* +* EBCDIC is assumed - ZCODE is the EBCDIC code of either lower or +* upper case 'Z'. +* + IF( INTA.GE.129 .AND. INTA.LE.137 .OR. + $ INTA.GE.145 .AND. INTA.LE.153 .OR. + $ INTA.GE.162 .AND. INTA.LE.169 ) INTA = INTA + 64 + IF( INTB.GE.129 .AND. INTB.LE.137 .OR. + $ INTB.GE.145 .AND. INTB.LE.153 .OR. + $ INTB.GE.162 .AND. INTB.LE.169 ) INTB = INTB + 64 +* + ELSE IF( ZCODE.EQ.218 .OR. ZCODE.EQ.250 ) THEN +* +* ASCII is assumed, on Prime machines - ZCODE is the ASCII code +* plus 128 of either lower or upper case 'Z'. +* + IF( INTA.GE.225 .AND. INTA.LE.250 ) INTA = INTA - 32 + IF( INTB.GE.225 .AND. INTB.LE.250 ) INTB = INTB - 32 + END IF + LSAME = INTA.EQ.INTB +* +* RETURN +* +* End of LSAME +* + END diff --git a/ext/blas/xerbla.f b/ext/blas/xerbla.f new file mode 100755 index 000000000..18100082c --- /dev/null +++ b/ext/blas/xerbla.f @@ -0,0 +1,43 @@ + SUBROUTINE XERBLA( SRNAME, INFO ) +* +* -- LAPACK auxiliary routine (preliminary version) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* February 29, 1992 +* +* .. Scalar Arguments .. + CHARACTER*6 SRNAME + INTEGER INFO +* .. +* +* Purpose +* ======= +* +* XERBLA is an error handler for the LAPACK routines. +* It is called by an LAPACK routine if an input parameter has an +* invalid value. A message is printed and execution stops. +* +* Installers may consider modifying the STOP statement in order to +* call system-specific exception-handling facilities. +* +* Arguments +* ========= +* +* SRNAME (input) CHARACTER*6 +* The name of the routine which called XERBLA. +* +* INFO (input) INTEGER +* The position of the invalid parameter in the parameter list +* of the calling routine. +* +* + WRITE( *, FMT = 9999 )SRNAME, INFO +* + STOP +* + 9999 FORMAT( ' ** On entry to ', A6, ' parameter number ', I2, ' had ', + $ 'an illegal value' ) +* +* End of XERBLA +* + END diff --git a/ext/cvode/.cvsignore b/ext/cvode/.cvsignore new file mode 100644 index 000000000..f3c7a7c5d --- /dev/null +++ b/ext/cvode/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/ext/cvode/Makefile.in b/ext/cvode/Makefile.in new file mode 100755 index 000000000..f0f055726 --- /dev/null +++ b/ext/cvode/Makefile.in @@ -0,0 +1,96 @@ +# +# $Source$ +# $Author$ +# $Revision$ +# $Date$ +# +#---------------------------------------------------------------------------- +# CVODE +#---------------------------------------------------------------------------- +# This file will compile all the CVODE modules in order to make the Unix +# library cvodelib.a. All object (.o) files are removed after the library +# has been created. +# +# The following variables are used: +# +# COMPILER - set to use the gcc compiler +# OPTS - list of compiler options +# OBJS - list of object files in cvodelib.a +# +# Modify the COMPILER and OPTS variables as needed. +# +# If the ranlib utility is not available on your system, then remove the call +# to ranlib from the commands to create libcvode.a. + +all: ./libcvode.a + +COMPILER = @CC@ + +OPTS = -I../include @CXXFLAGS@ $(CXX_OPT) + +OBJS = source/cvode.o source/cvdense.o source/dense.o source/cvband.o \ + source/band.o source/cvdiag.o source/cvspgmr.o source/spgmr.o \ + source/iterativ.o source/cvbandpre.o source/nvector.o source/llnlmath.o + + +./libcvode.a: $(OBJS) + $(RM) ./libcvode.a + (ar rcv ./libcvode.a $(OBJS); ranlib ./libcvode.a) + +source/cvode.o: source/cvode.c include/cvode.h include/llnltyps.h \ + include/nvector.h include/llnlmath.h + (cd source; $(COMPILER) $(OPTS) -c cvode.c) + +source/cvdense.o: source/cvdense.c include/cvdense.h include/cvode.h \ + include/dense.h include/llnltyps.h include/nvector.h \ + include/llnlmath.h + (cd source; $(COMPILER) $(OPTS) -c cvdense.c) + +source/dense.o: source/dense.c include/dense.h include/llnltyps.h \ + include/nvector.h include/llnlmath.h + (cd source; $(COMPILER) $(OPTS) -c dense.c) + +source/cvband.o: source/cvband.c include/cvband.h include/cvode.h \ + include/band.h include/llnltyps.h include/nvector.h \ + include/llnlmath.h + (cd source; $(COMPILER) $(OPTS) -c cvband.c) + +source/band.o: source/band.c include/band.h include/llnltyps.h \ + include/nvector.h include/llnlmath.h + (cd source; $(COMPILER) $(OPTS) -c band.c) + +source/cvdiag.o: source/cvdiag.c include/cvdiag.h include/cvode.h \ + include/llnltyps.h include/nvector.h + (cd source; $(COMPILER) $(OPTS) -c cvdiag.c) + +source/cvspgmr.o: source/cvspgmr.c include/cvspgmr.h include/cvode.h \ + include/llnltyps.h include/nvector.h include/llnlmath.h \ + include/iterativ.h include/spgmr.h + (cd source; $(COMPILER) $(OPTS) -c cvspgmr.c) + +source/spgmr.o: source/spgmr.c include/spgmr.h include/iterativ.h \ + include/llnltyps.h include/nvector.h include/llnlmath.h + (cd source; $(COMPILER) $(OPTS) -c spgmr.c) + +source/iterativ.o: source/iterativ.c include/iterativ.h include/llnltyps.h \ + include/nvector.h include/llnlmath.h + (cd source; $(COMPILER) $(OPTS) -c iterativ.c) + +source/cvbandpre.o: source/cvbandpre.c include/cvbandpre.h include/cvode.h \ + include/nvector.h include/llnltyps.h include/llnlmath.h \ + include/band.h + (cd source; $(COMPILER) $(OPTS) -c cvbandpre.c) + +source/nvector.o: source/nvector.c include/nvector.h include/llnltyps.h \ + include/llnlmath.h + (cd source; $(COMPILER) $(OPTS) -c nvector.c) + +source/llnlmath.o: source/llnlmath.c include/llnlmath.h include/llnltyps.h + (cd source; $(COMPILER) $(OPTS) -c llnlmath.c) + +clean: + $(RM) ./libcvode.a + $(RM) $(OBJS) + + + diff --git a/ext/cvode/include/band.h b/ext/cvode/include/band.h new file mode 100755 index 000000000..f9e2cb804 --- /dev/null +++ b/ext/cvode/include/band.h @@ -0,0 +1,609 @@ + +/****************************************************************** + * * + * File : band.h * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 5 May 1998 * + *----------------------------------------------------------------* + * This is the header file for a generic BAND linear solver * + * package. There are two sets of band solver routines listed in * + * this file: one set uses type BandMat defined below and the * + * other set uses the type real ** for band matrix arguments. * + * The two sets of band solver routines make it easy to work * + * with two types of band matrices: * + * * + * (1) The BandMat type is intended for use with large * + * band matrices whose elements/columns may be stored in * + * non-contiguous memory locations or even distributed into * + * different processor memories. This type may be modified to * + * include such distribution information. If this is done, * + * then all the routines that use BandMat must be modified to * + * reflect the new data structure. * + * * + * (2) The set of routines that use real ** (and NOT the BandMat * + * type) is intended for use with small matrices which can * + * easily be allocated within a contiguous block of memory * + * on a single processor. * + * * + * Routines that work with the type BandMat begin with "Band". * + * The BandAllocMat function allocates a band matrix for use in * + * the other matrix routines listed in this file. Matrix storage * + * details are given in the documentation for the type BandMat. * + * The BandAllocPiv function allocates memory for pivot * + * information. The storage allocated by BandAllocMat and * + * BandAllocPiv is deallocated by the routines BandFreeMat and * + * BandFreePiv, respectively. The BandFactor and BandBacksolve * + * routines perform the actual solution of a band linear system. * + * Note that the BandBacksolve routine has a parameter b of type * + * N_Vector. The current implementation makes use of a machine * + * environment specific macro (N_VDATA) which may not exist for * + * other implementations of the type N_Vector. Thus, the * + * implementation of BandBacksolve may need to change if the * + * type N_Vector is changed. * + * * + * Routines that work with real ** begin with "band" (except for * + * the factor and solve routines which are called gbfa and gbsl, * + * respectively). The underlying matrix storage is described in * + * the documentation for bandalloc. * + * * + ******************************************************************/ + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +#ifndef _band_h +#define _band_h + +#include "llnltyps.h" +#include "nvector.h" + + +/****************************************************************** + * * + * Type: BandMat * + *----------------------------------------------------------------* + * The type BandMat is the type of a large (possibly distributed) * + * band matrix. It is defined to be a pointer to a structure * + * with the following fields: * + * * + * size is the number of columns (== number of rows) * + * * + * mu is the upper bandwidth, 0 <= mu <= size-1 * + * * + * ml is the lower bandwidth, 0 <= ml <= size-1 * + * * + * smu is the storage upper bandwidth, mu <= smu <= size-1. * + * The BandFactor routine writes the LU factors * + * into the storage for A. The upper triangular factor U, * + * however, may have an upper bandwidth as big as * + * MIN(size-1,mu+ml) because of partial pivoting. The smu * + * field holds the upper bandwidth allocated for A. * + * * + * data is a two dimensional array used for component storage. * + * The elements of a band matrix of type BandMat are * + * stored columnwise (i.e. columns are stored one on top * + * of the other in memory). Only elements within the * + * specified bandwidths are stored. * + * * + * If we number rows and columns in the band matrix starting * + * from 0, then * + * * + * data[0] is a pointer to (smu+ml+1)*size contiguous locations * + * which hold the elements within the band of A * + * * + * data[j] is a pointer to the uppermost element within the band * + * in the jth column. This pointer may be treated as * + * an array indexed from smu-mu (to access the * + * uppermost element within the band in the jth * + * column) to smu+ml (to access the lowest element * + * within the band in the jth column). (Indices from 0 * + * to smu-mu-1 give access to extra storage elements * + * required by BandFactor.) * + * * + * data[j][i-j+smu] is the (i,j)th element, j-mu <= i <= j+ml. * + * * + * The macros below allow a user to access individual matrix * + * elements without writing out explicit data structure * + * references and without knowing too much about the underlying * + * element storage. The only storage assumption needed is that * + * elements are stored columnwise and that a pointer into the jth * + * column of elements can be obtained via the BAND_COL macro. The * + * BAND_COL_ELEM macro selects an element from a column which has * + * already been isolated via BAND_COL. BAND_COL_ELEM allows the * + * user to avoid the translation from the matrix location (i,j) * + * to the index in the array returned by BAND_COL at which the * + * (i,j)th element is stored. See the documentation for BAND_COL * + * and BAND_COL_ELEM for usage details. Users should use these * + * macros whenever possible. * + * * + ******************************************************************/ + + +typedef struct { + integer size; + integer mu, ml, smu; + real **data; +} *BandMat; + + +/* BandMat accessor macros */ + + +/****************************************************************** + * * + * Macro : BAND_ELEM * + * Usage : BAND_ELEM(A,i,j) = a_ij; OR * + * a_ij = BAND_ELEM(A,i,j); * + *----------------------------------------------------------------* + * BAND_ELEM(A,i,j) references the (i,j)th element of the * + * N by N band matrix A, where 0 <= i,j <= N-1. The location * + * (i,j) should further satisfy j-(A->mu) <= i <= j+(A->ml). * + * * + ******************************************************************/ + +#define BAND_ELEM(A,i,j) ((A->data)[j][i-j+(A->smu)]) + + +/****************************************************************** + * * + * Macro : BAND_COL * + * Usage : col_j = BAND_COL(A,j); * + *----------------------------------------------------------------* + * BAND_COL(A,j) references the diagonal element of the jth * + * column of the N by N band matrix A, 0 <= j <= N-1. The type of * + * the expression BAND_COL(A,j) is real *. The pointer returned * + * by the call BAND_COL(A,j) can be treated as an array which is * + * indexed from -(A->mu) to (A->ml). * + * * + ******************************************************************/ + +#define BAND_COL(A,j) (((A->data)[j])+(A->smu)) + + +/****************************************************************** + * * + * Macro : BAND_COL_ELEM * + * Usage : col_j = BAND_COL(A,j); * + * BAND_COL_ELEM(col_j,i,j) = a_ij; OR * + * a_ij = BAND_COL_ELEM(col_j,i,j); * + *----------------------------------------------------------------* + * This macro references the (i,j)th entry of the band matrix A * + * when used in conjunction with BAND_COL as shown above. The * + * index (i,j) should satisfy j-(A->mu) <= i <= j+(A->ml). * + * * + ******************************************************************/ + +#define BAND_COL_ELEM(col_j,i,j) (col_j[i-j]) + + +/* Functions that use the BandMat representation for a band matrix */ + + +/****************************************************************** + * * + * Function : BandAllocMat * + * Usage : A = BandAllocMat(N, mu, ml, smu); * + * if (A == NULL) ... memory request failed * + *----------------------------------------------------------------* + * BandAllocMat allocates memory for an N by N band matrix with * + * upper bandwidth mu, lower bandwidth ml, and storage upper * + * bandwidth smu. Pass smu as follows depending on whether A will * + * be factored by BandFactor: * + * * + * (1) Pass smu = mu if A will not be factored. * + * * + * (2) Pass smu = MIN(N-1,mu+ml) if A will be factored. * + * * + * BandAllocMat returns the storage allocated (type BandMat) or * + * NULL if the request for matrix storage cannot be satisfied. * + * See the documentation for the type BandMat for matrix storage * + * details. * + * * + ******************************************************************/ + +BandMat BandAllocMat(integer N, integer mu, integer ml, integer smu); + + +/****************************************************************** + * * + * Function : BandAllocPiv * + * Usage : p = BandAllocPiv(N); * + * if (p == NULL) ... memory request failed * + *----------------------------------------------------------------* + * BandAllocPiv allocates memory for pivot information to be * + * filled in by the BandFactor routine during the factorization * + * of an N by N band matrix. The underlying type for pivot * + * information is an array of N integers and this routine returns * + * the pointer to the memory it allocates. If the request for * + * pivot storage cannot be satisfied, BandAllocPiv returns NULL. * + * * + ******************************************************************/ + +integer *BandAllocPiv(integer N); + + +/****************************************************************** + * * + * Function : BandFactor * + * Usage : ier = BandFactor(A, p); * + * if (ier != 0) ... A is singular * + *----------------------------------------------------------------* + * BandFactor performs the LU factorization of the N by N band * + * matrix A. This is done using standard Gaussian elimination * + * with partial pivoting. * + * * + * A successful LU factorization leaves the "matrix" A and the * + * pivot array p with the following information: * + * * + * (1) p[k] contains the row number of the pivot element chosen * + * at the beginning of elimination step k, k=0, 1, ..., N-1. * + * * + * (2) If the unique LU factorization of A is given by PA = LU, * + * where P is a permutation matrix, L is a lower triangular * + * matrix with all 1's on the diagonal, and U is an upper * + * triangular matrix, then the upper triangular part of A * + * (including its diagonal) contains U and the strictly lower * + * triangular part of A contains the multipliers, I-L. * + * * + * BandFactor returns 0 if successful. Otherwise it encountered * + * a zero diagonal element during the factorization. In this case * + * it returns the column index (numbered from one) at which * + * it encountered the zero. * + * * + * Important Note: A must be allocated to accommodate the increase* + * in upper bandwidth that occurs during factorization. If, * + * mathematically, A is a band matrix with upper bandwidth mu and * + * lower bandwidth ml, then the upper triangular factor U can * + * have upper bandwidth as big as smu=MIN(n-1,mu+ml). The lower * + * triangular factor L has lower bandwidth ml. Allocate A with * + * call A = BandAllocMat(N,mu,ml,smu), where mu, ml, and smu are * + * as defined above. The user does not have to zero the "extra" * + * storage allocated for the purpose of factorization. This will * + * handled by the BandFactor routine. * + * * + ******************************************************************/ + +integer BandFactor(BandMat A, integer *p); + + +/****************************************************************** + * * + * Function : BandBacksolve * + * Usage : BandBacksolve(A, p, b); * + *----------------------------------------------------------------* + * BandBacksolve solves the N-dimensional system A x = b using * + * the LU factorization in A and the pivot information in p * + * computed in BandFactor. The solution x is returned in b. This * + * routine cannot fail if the corresponding call to BandFactor * + * did not fail. * + * * + ******************************************************************/ + +void BandBacksolve(BandMat A, integer *p, N_Vector b); + + +/****************************************************************** + * * + * Function : BandZero * + * Usage : BandZero(A); * + *----------------------------------------------------------------* + * A(i,j) <- 0.0, j-(A->mu) <= i <= j+(A->ml). * + * * + ******************************************************************/ + +void BandZero(BandMat A); + + +/****************************************************************** + * * + * Function : BandCopy * + * Usage : BandCopy(A, B, copymu, copyml); * + *----------------------------------------------------------------* + * BandCopy copies the submatrix with upper and lower bandwidths * + * copymu, copyml of the N by N band matrix A into the N by N * + * band matrix B. * + * * + ******************************************************************/ + +void BandCopy(BandMat A, BandMat B, integer copymu, integer copyml); + + +/****************************************************************** + * * + * Function: BandScale * + * Usage : BandScale(c, A); * + *----------------------------------------------------------------* + * A(i,j) <- c*A(i,j), j-(A->mu) <= i <= j+(A->ml). * + * * + ******************************************************************/ + +void BandScale(real c, BandMat A); + + +/****************************************************************** + * * + * Function : BandAddI * + * Usage : BandAddI(A); * + *----------------------------------------------------------------* + * A(j,j) <- A(j,j)+1.0, 0 <= j <= (A->size)-1. * + * * + ******************************************************************/ + +void BandAddI(BandMat A); + + +/****************************************************************** + * * + * Function : BandFreeMat * + * Usage : BandFreeMat(A); * + *----------------------------------------------------------------* + * BandFreeMat frees the memory allocated by BandAllocMat for * + * the band matrix A. * + * * + ******************************************************************/ + +void BandFreeMat(BandMat A); + + +/****************************************************************** + * * + * Function : BandFreePiv * + * Usage : BandFreePiv(p); * + *----------------------------------------------------------------* + * BandFreePiv frees the memory allocated by BandAllocPiv for * + * the pivot information array p. * + * * + ******************************************************************/ + +void BandFreePiv(integer *p); + + +/****************************************************************** + * * + * Function : BandPrint * + * Usage : BandPrint(A); * + *----------------------------------------------------------------* + * This routine prints the N by N band matrix A (upper and lower * + * bandwidths A->mu and A->ml, respectively) to standard output * + * as it would normally appear on paper. It is intended as a * + * debugging tool with small values of N. The elements are * + * printed using the %g option. A blank line is printed before * + * and after the matrix. * + * * + ******************************************************************/ + +void BandPrint(BandMat A); + + + +/* Functions that use the real ** representation for a band matrix */ + + +/****************************************************************** + * * + * Function : bandalloc * + * Usage : real **a; * + * a = bandalloc(n, smu, ml); * + * if (a == NULL) ... memory request failed * + *----------------------------------------------------------------* + * bandalloc(n, smu, ml) allocates storage for an n by n band * + * matrix A with storage upper bandwidth smu and lower bandwidth * + * ml. It returns a pointer to the newly allocated storage if * + * successful. If the memory request cannot be satisfied, then * + * bandalloc returns NULL. If, mathematically, A has upper and * + * lower bandwidths mu and ml, respectively, then the value * + * passed to bandalloc for smu may need to be greater than mu. * + * The gbfa routine writes the LU factors into the storage (named * + * "a" in the above usage documentation) for A (thus destroying * + * the original elements of A). The upper triangular factor U, * + * however, may have a larger upper bandwidth than the upper * + * bandwidth mu of A. Thus some "extra" storage for A must be * + * allocated if A is to be factored by gbfa. Pass smu as follows: * + * * + * (1) Pass smu = mu if A will not be factored. * + * * + * (2) Pass smu = MIN(n-1,mu+ml) if A will be factored. * + * * + * The underlying type of the band matrix returned is real **. If * + * we allocate a band matrix A in real **a by * + * a = bandalloc(n,smu,ml), then a[0] is a pointer to * + * n * (smu + ml + 1) contiguous storage locations and a[j] is a * + * pointer to the uppermost element in the storage for the jth * + * column. The expression a[j][i-j+smu] references the (i,j)th * + * element of A, where 0 <= i,j <= n-1 and j-mu <= i <= j+ml. * + * (The elements a[j][0], a[j][1], ..., a[j][smu-mu-1] are used * + * by gbfa and gbsl.) * + * * + ******************************************************************/ + +real **bandalloc(integer n, integer smu, integer ml); + + +/****************************************************************** + * * + * Function : bandallocpiv * + * Usage : integer *pivot; * + * pivot = bandallocpiv(n); * + * if (pivot == NULL) ... memory request failed * + *----------------------------------------------------------------* + * bandallocpiv(n) allocates an array of n integers. It returns a * + * pointer to the first element in the array if successful. It * + * returns NULL if the memory request could not be satisfied. * + * * + ******************************************************************/ + +integer *bandallocpiv(integer n); + + +/****************************************************************** + * * + * Function : gbfa * + * Usage : integer ier; * + * ier = gbfa(a,n,mu,ml,smu,p); * + * if (ier > 0) ... zero element encountered during * + * the factorization * + *----------------------------------------------------------------* + * gbfa(a,n,mu,ml,smu,p) factors the n by n band matrix A (upper * + * and lower bandwidths mu and ml, storage upper bandwidth smu) * + * stored in "a". It overwrites the elements of A with the LU * + * factors and it keeps track of the pivot rows chosen in the * + * pivot array p. * + * * + * A successful LU factorization leaves a and pivot array p with * + * the following information: * + * * + * (1) p[k] contains the row number of the pivot element chosen * + * at the beginning of elimination step k, k=0, 1, ..., n-1. * + * * + * (2) If the unique LU factorization of A is given by PA = LU, * + * where P is a permutation matrix, L is a lower triangular * + * matrix with all 1's on the diagonal, and U is an upper * + * triangular matrix, then the upper triangular part of A * + * (including its diagonal) contains U and the strictly lower * + * triangular part of A contains the multipliers, I-L. * + * * + * gbfa returns 0 if successful. Otherwise it encountered a zero * + * diagonal element during the factorization. In this case it * + * returns the column index (numbered from one) at which it * + * encountered the zero. * + * * + * IMPORTANT NOTE: Suppose A is a band matrix with upper * + * bandwidth mu and lower bandwidth ml, then the upper triangular * + * factor U can have upper bandwidth as big as MIN(n-1,mu+ml) * + * because of partial pivoting. The lower triangular factor L has * + * lower bandwidth ml. Thus, if A is to be factored and * + * backsolved using gbfa and gbsl, then it should be allocated * + * as a = bandalloc(n,smu,ml), where smu = MIN(n-1,mu+ml). The * + * call to gbfa is ier = gbfa(a,n,mu,ml,smu,p). The corresponding * + * call to gbsl is gbsl(a,n,smu,ml,p,b). The user does not need * + * to zero the "extra" storage allocated for the purpose of * + * factorization. This is handled by the gbfa routine. If A is * + * not going to be factored and backsolved, then it can be * + * allocated as a = bandalloc(n,smu,ml). In either case, all * + * routines in this section use the parameter name smu for a * + * parameter which must be the "storage upper bandwidth" which * + * was passed to bandalloc. * + * * + ******************************************************************/ + +integer gbfa(real **a, integer n, integer mu, integer ml, integer smu, + integer *p); + + +/****************************************************************** + * * + * Function : gbsl * + * Usage : real *b; * + * ier = gbfa(a,n,mu,ml,smu,p); * + * if (ier == 0) gbsl(a,n,smu,ml,p,b); * + *----------------------------------------------------------------* + * gbsl(a,n,smu,ml,p,b) solves the n by n linear system * + * Ax = b, where A is band matrix stored in "a" with storage * + * upper bandwidth smu and lower bandwidth ml. It assumes that A * + * has been LU factored and the pivot array p has been set by a * + * successful call gbfa(a,n,mu,ml,smu,p). The solution x is * + * written into the b array. * + * * + ******************************************************************/ + +void gbsl(real **a, integer n, integer smu, integer ml, integer *p, real *b); + + +/****************************************************************** + * * + * Function : bandzero * + * Usage : bandzero(a,n,mu,ml,smu); * + *----------------------------------------------------------------* + * a(i,j) <- 0.0, 0 <= i,j <= n-1, j-mu <= i <= j+ml. * + * * + ******************************************************************/ + +void bandzero(real **a, integer n, integer mu, integer ml, integer smu); + + +/****************************************************************** + * * + * Function : bandcopy * + * Usage : bandcopy(a,b,n,a_smu,b_smu,copymu,copyml); * + *----------------------------------------------------------------* + * b(i,j) <- a(i,j), 0 <= i,j <= n-1, j-copymu <= i <= j+copyml. * + * * + ******************************************************************/ + +void bandcopy(real **a, real **b, integer n, integer a_smu, integer b_smu, + integer copymu, integer copyml); + + +/****************************************************************** + * * + * Function : bandscale * + * Usage : bandscale(c,a,n,mu,ml); * + *----------------------------------------------------------------* + * a(i,j) <- c*a(i,j), 0 <= i,j <= n-1, j-mu <= i <= j+ml. * + * * + ******************************************************************/ + +void bandscale(real c, real **a, integer n, integer mu, integer ml, + integer smu); + + +/****************************************************************** + * * + * Function : bandaddI * + * Usage : bandaddI(a,n,smu); * + *----------------------------------------------------------------* + * a(j,j) <- a(j,j)+1.0, 0 <= j <= n-1. * + * * + ******************************************************************/ + +void bandaddI(real **a, integer n, integer smu); + + +/****************************************************************** + * * + * Function : bandfreepiv * + * Usage : bandfreepiv(p); * + *----------------------------------------------------------------* + * bandfreepiv(p) frees the pivot array p allocated by * + * bandallocpiv. * + * * + ******************************************************************/ + +void bandfreepiv(integer *p); + + +/****************************************************************** + * * + * Function : bandfree * + * Usage : bandfree(a); * + *----------------------------------------------------------------* + * bandfree(a) frees the band matrix a allocated by bandalloc. * + * * + ******************************************************************/ + +void bandfree(real **a); + + +/****************************************************************** + * * + * Function : bandprint * + * Usage : bandprint(a,n,mu,ml,smu); * + *----------------------------------------------------------------* + * bandprint(a,n,mu,ml,smu) prints the n by n band matrix stored * + * in a (with upper bandwidth mu and lower bandwidth ml) to * + * standard output as it would normally appear on paper. It is * + * intended as a debugging tool with small values of n. The * + * elements are printed using the %g option. A blank line is * + * printed before and after the matrix. * + * * + ******************************************************************/ + +void bandprint(real **a, integer n, integer mu, integer ml, integer smu); + + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/ext/cvode/include/cvband.h b/ext/cvode/include/cvband.h new file mode 100755 index 000000000..e250f83ef --- /dev/null +++ b/ext/cvode/include/cvband.h @@ -0,0 +1,221 @@ +/****************************************************************** + * * + * File : cvband.h * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 24 February 2000 * + *----------------------------------------------------------------* + * This is the header file for the CVODE band linear solver, * + * CVBAND. * + * * + * Note: The type integer must be large enough to store the value * + * N + mupper + mlower, where N is the linear system size and * + * mupper and mlower are the upper and lower bandwidths, * + * respectively, passed to CVBand. * + * * + ******************************************************************/ + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +#ifndef _cvband_h +#define _cvband_h + + +#include +#include "cvode.h" +#include "llnltyps.h" +#include "band.h" +#include "nvector.h" + + +/****************************************************************** + * * + * CVBAND solver statistics indices * + *----------------------------------------------------------------* + * The following enumeration gives a symbolic name to each * + * CVBAND statistic. The symbolic names are used as indices into * + * the iopt and ropt arrays passed to CVodeMalloc. * + * The CVBAND statistics are: * + * * + * iopt[BAND_NJE] : number of Jacobian evaluations, i.e. of * + * calls made to the band Jacobian routine * + * (default or user-supplied). * + * * + * iopt[BAND_LRW] : size (in real words) of real workspace * + * matrices and vectors used by this solver. * + * * + * iopt[BAND_LIW] : size (in integer words) of integer * + * workspace vectors used by this solver. * + * * + ******************************************************************/ + +enum { BAND_NJE=CVODE_IOPT_SIZE, BAND_LRW, BAND_LIW }; + + +/****************************************************************** + * * + * CVBAND solver constants * + *----------------------------------------------------------------* + * CVB_MSBJ : maximum number of steps between band Jacobian * + * evaluations * + * * + * CVB_DGMAX : maximum change in gamma between band Jacobian * + * evaluations * + * * + ******************************************************************/ + +#define CVB_MSBJ 50 + +#define CVB_DGMAX RCONST(0.2) + + +/****************************************************************** + * * + * Type : CVBandJacFn * + *----------------------------------------------------------------* + * A band Jacobian approximation function Jac must have the * + * prototype given below. Its parameters are: * + * * + * N is the length of all vector arguments. * + * * + * mupper is the upper half-bandwidth of the approximate banded * + * Jacobian. This parameter is the same as the mupper parameter * + * passed by the user to the CVBand function. * + * * + * mlower is the lower half-bandwidth of the approximate banded * + * Jacobian. This parameter is the same as the mlower parameter * + * passed by the user to the CVBand function. * + * * + * J is the band matrix (of type BandMat) that will be loaded * + * by a CVBandJacFn with an approximation to the Jacobian matrix * + * J = (df_i/dy_j) at the point (t,y). * + * J is preset to zero, so only the nonzero elements need to be * + * loaded. Three efficient ways to load J are: * + * * + * (1) (with macros - no explicit data structure references) * + * for (j=0; j < N; j++) { * + * col_j = BAND_COL(J,j); * + * for (i=j-mupper; i <= j+mlower; i++) { * + * generate J_ij = the (i,j)th Jacobian element * + * BAND_COL_ELEM(col_j,i,j) = J_ij; * + * } * + * } * + * * + * (2) (with BAND_COL macro, but without BAND_COL_ELEM macro) * + * for (j=0; j < N; j++) { * + * col_j = BAND_COL(J,j); * + * for (k=-mupper; k <= mlower; k++) { * + * generate J_ij = the (i,j)th Jacobian element, i=j+k * + * col_j[k] = J_ij; * + * } * + * } * + * * + * (3) (without macros - explicit data structure references) * + * offset = J->smu; * + * for (j=0; j < N; j++) { * + * col_j = ((J->data)[j])+offset; * + * for (k=-mupper; k <= mlower; k++) { * + * generate J_ij = the (i,j)th Jacobian element, i=j+k * + * col_j[k] = J_ij; * + * } * + * } * + * Caution: J->smu is generally NOT the same as mupper. * + * * + * The BAND_ELEM(A,i,j) macro is appropriate for use in small * + * problems in which efficiency of access is NOT a major concern. * + * * + * f is the right hand side function for the ODE problem. * + * * + * f_data is a pointer to user data to be passed to f, the same * + * as the F_data parameter passed to CVodeMalloc. * + * * + * t is the current value of the independent variable. * + * * + * y is the current value of the dependent variable vector, * + * namely the predicted value of y(t). * + * * + * fy is the vector f(t,y). * + * * + * ewt is the error weight vector. * + * * + * h is a tentative step size in t. * + * * + * uround is the machine unit roundoff. * + * * + * jac_data is a pointer to user data - the same as the jac_data * + * parameter passed to CVBand. * + * * + * nfePtr is a pointer to the memory location containing the * + * CVODE problem data nfe = number of calls to f. The Jacobian * + * routine should update this counter by adding on the number * + * of f calls made in order to approximate the Jacobian, if any. * + * For example, if the routine calls f a total of N times, then * + * the update is *nfePtr += N. * + * * + * vtemp1, vtemp2, and vtemp3 are pointers to memory allocated * + * for vectors of length N which can be used by a CVBandJacFn * + * as temporary storage or work space. * + * * + ******************************************************************/ + +typedef void (*CVBandJacFn)(integer N, integer mupper, integer mlower, + BandMat J, RhsFn f, void *f_data, real t, + N_Vector y, N_Vector fy, N_Vector ewt, real h, + real uround, void *jac_data, long int *nfePtr, + N_Vector vtemp1, N_Vector vtemp2, N_Vector vtemp3); + + +/****************************************************************** + * * + * Function : CVBand * + *----------------------------------------------------------------* + * A call to the CVBand function links the main CVODE integrator * + * with the CVBAND linear solver. * + * * + * cvode_mem is the pointer to CVODE memory returned by * + * CVodeMalloc. * + * * + * mupper is the upper bandwidth of the band Jacobian * + * approximation. * + * * + * mlower is the lower bandwidth of the band Jacobian * + * approximation. * + * * + * * + * bjac is the band Jacobian approximation routine to be used. * + * A user-supplied bjac routine must be of type * + * CVBandJacFn. Pass NULL for bjac to use the default * + * difference quotient routine CVBandDQJac supplied * + * with this solver. * + * * + * jac_data is a pointer to user data which is passed to the * + * bjac routine every time it is called. * + * * + ******************************************************************/ + +void CVBand(void *cvode_mem, integer mupper, integer mlower, CVBandJacFn bjac, + void *jac_data); + + +/****************************************************************** + * * + * Function : CVBandDQJac * + *----------------------------------------------------------------* + * This routine generates a banded difference quotient * + * approximation to the Jacobian of f(t,y). * + * * + ******************************************************************/ + +void CVBandDQJac(integer N, integer mupper, integer mlower, BandMat J, + RhsFn f, void *f_data, real t, N_Vector y, N_Vector fy, + N_Vector ewt, real h, real uround, void *jac_data, + long int *nfePtr, N_Vector vtemp1, N_Vector vtemp2, + N_Vector vtemp3); + + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/ext/cvode/include/cvbandpre.h b/ext/cvode/include/cvbandpre.h new file mode 100755 index 000000000..14d911cb1 --- /dev/null +++ b/ext/cvode/include/cvbandpre.h @@ -0,0 +1,151 @@ +/****************************************************************** + * * + * File : cvbandpre.h * + * Programmers : Michael Wittman and Alan C. Hindmarsh @ LLNL * + * Version of : 23 March 2000 * + *----------------------------------------------------------------* + * This is the header file for the CVBANDPRE module, which * + * provides a banded difference quotient Jacobian-based * + * preconditioner and solver routines for use with CVSPGMR. * + * * + * Summary: * + * These routines provide a band matrix preconditioner based on * + * difference quotients of the ODE right-hand side function f. * + * The user supplies parameters * + * mu = upper half-bandwidth (number of super-diagonals) * + * ml = lower half-bandwidth (number of sub-diagonals) * + * The routines generate a band matrix of bandwidth ml + mu + 1 * + * and use this to form a preconditioner for use with the Krylov * + * linear solver in CVSPGMR. Although this matrix is intended * + * to approximate the Jacobian df/dy, it may be a very crude * + * approximation. The true Jacobian need not be banded, or its * + * true bandwith may be larger than ml + mu + 1, as long as the * + * banded approximation generated here is sufficiently accurate * + * to speed convergence as a preconditioner. * + * * + * Usage: * + * The following is a summary of the usage of this module. * + * Details of the calls to CVodeMalloc, CVSpgmr, and CVode are * + * available in the CVODE User Guide. * + * To use these routines, the sequence of calls in the user * + * main program should be as follows: * + * * + * CVBandPreData bp_data; * + * ... * + * bp_data = CVBandPreAlloc(N, f, f_data, mu, ml); * + * ... * + * cvode_mem = CVodeMalloc(...); * + * ... * + * CVSpgmr(cvode_mem, pretype, gstype, maxl, delt, * + * CVBandPrecond, CVBandPSolve, bp_data); * + * ... * + * flag = CVode(...); * + * ... * + * CVBandPreFree(bp_data); * + * ... * + * CVodeFree(cvode_mem); * + * * + * Notes: * + * (1) Include this file for the CVBandPreData type definition. * + * (2) In the CVBandPreAlloc call, the arguments N, f, and f_data * + * are the same as in the call to CVodeMalloc. * + * (3) In the CVSpgmr call, the user is free to specify the inputs* + * pretype and gstype, and the optional inputs maxl and delt. * + * But the last three arguments must be as shown, with the * + * last argument being the pointer returned by CVBandPreAlloc.* + * (4) The CVBandPrecond and CVBandPSolve functions are never * + * called by the user explicitly; they are simply passed to * + * the CVSpgmr function. * + * * + ******************************************************************/ + + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +#ifndef _cvbandpre_h +#define _cvbandpre_h + +#include "cvode.h" +#include "llnltyps.h" +#include "nvector.h" +#include "band.h" + + +/************* CVBandPreData type definition ************/ + +typedef struct { + /* Data set by user in CVBandPreAlloc: */ + RhsFn f; + void *f_data; + integer ml, mu; + + /* Data set by CVBandPrecond: */ + BandMat savedJ; + BandMat savedP; + integer *pivots; +} *CVBandPreData; + + +/****************************************************************** + * * + * Function : CVBandPreAlloc * + *----------------------------------------------------------------* + * CVBandPreAlloc allocates and initializes a CVBandPreData * + * structure to be passed to CVSpgmr (and subsequently used by * + * CVBandPrecond and CVBandPSolve). * + * * + * The parameters of CVBandPreAlloc are as follows: * + * * + * N is the length of all vector arguments. * + * * + * f is the right hand side function. * + * * + * f_data is a pointer to the optional extra data for f. * + * * + * mu is the upper half bandwidth. * + * * + * ml is the lower half bandwidth. * + * * + * CVBandPreAlloc returns the storage pointer (type CVBandPreData)* + * or NULL if the request for storage cannot be satisfied. * + * * + ******************************************************************/ + +CVBandPreData CVBandPreAlloc(integer N, RhsFn f, void *f_data, + integer mu, integer ml); + + +/****************************************************************** + * * + * Function : CVBandPreFree * + *----------------------------------------------------------------* + * CVBandPreFree frees the memory allocated by CVBandPreAlloc in * + * the argument pdata. * + * * + ******************************************************************/ + +void CVBandPreFree(CVBandPreData pdata); + + + +/* Prototypes of CVBandPrecond and CVBandPSolve */ + + +int CVBandPrecond(integer N, real t, N_Vector y, N_Vector fy, boole jok, + boole *jcurPtr, real gamma, N_Vector ewt, real h, + real uround, long int *nfePtr, void *bp_data, + N_Vector vtemp1, N_Vector vtemp2, N_Vector vtemp3); + + +int CVBandPSolve(integer N, real t, N_Vector y, N_Vector fy, N_Vector vtemp, + real gamma, N_Vector ewt, real delta, long int *nfePtr, + N_Vector r, int lr, void *bp_data, N_Vector z); + + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/ext/cvode/include/cvdense.h b/ext/cvode/include/cvdense.h new file mode 100755 index 000000000..5b6ecafbf --- /dev/null +++ b/ext/cvode/include/cvdense.h @@ -0,0 +1,191 @@ +/****************************************************************** + * * + * File : cvdense.h * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 24 February 2000 * + *----------------------------------------------------------------* + * This is the header file for the CVODE dense linear solver, * + * CVDENSE. * + * * + * Note: The type integer must be large enough to store the value * + * of the linear system size N. * + * * + ******************************************************************/ + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +#ifndef _cvdense_h +#define _cvdense_h + + +#include +#include "cvode.h" +#include "llnltyps.h" +#include "dense.h" +#include "nvector.h" + + +/****************************************************************** + * * + * CVDENSE solver statistics indices * + *----------------------------------------------------------------* + * The following enumeration gives a symbolic name to each * + * CVDENSE statistic. The symbolic names are used as indices into * + * the iopt and ropt arrays passed to CVodeMalloc. * + * The CVDENSE statistics are: * + * * + * iopt[DENSE_NJE] : number of Jacobian evaluations, i.e. of * + * calls made to the dense Jacobian routine * + * (default or user-supplied). * + * * + * iopt[DENSE_LRW] : size (in real words) of real workspace * + * matrices and vectors used by this solver. * + * * + * iopt[DENSE_LIW] : size (in integer words) of integer * + * workspace vectors used by this solver. * + * * + ******************************************************************/ + +enum { DENSE_NJE=CVODE_IOPT_SIZE, DENSE_LRW, DENSE_LIW }; + + +/****************************************************************** + * * + * CVDENSE solver constants * + *----------------------------------------------------------------* + * CVD_MSBJ : maximum number of steps between dense Jacobian * + * evaluations * + * * + * CVD_DGMAX : maximum change in gamma between dense Jacobian * + * evaluations * + * * + ******************************************************************/ + +#define CVD_MSBJ 50 + +#define CVD_DGMAX RCONST(0.2) + + +/****************************************************************** + * * + * Type : CVDenseJacFn * + *----------------------------------------------------------------* + * A dense Jacobian approximation function Jac must have the * + * prototype given below. Its parameters are: * + * * + * N is the length of all vector arguments. * + * * + * J is the dense matrix (of type DenseMat) that will be loaded * + * by a CVDenseJacFn with an approximation to the Jacobian matrix * + * J = (df_i/dy_j) at the point (t,y). * + * J is preset to zero, so only the nonzero elements need to be * + * loaded. Two efficient ways to load J are: * + * * + * (1) (with macros - no explicit data structure references) * + * for (j=0; j < N; j++) { * + * col_j = DENSE_COL(J,j); * + * for (i=0; i < N; i++) { * + * generate J_ij = the (i,j)th Jacobian element * + * col_j[i] = J_ij; * + * } * + * } * + * * + * (2) (without macros - explicit data structure references) * + * for (j=0; j < N; j++) { * + * col_j = (J->data)[j]; * + * for (i=0; i < N; i++) { * + * generate J_ij = the (i,j)th Jacobian element * + * col_j[i] = J_ij; * + * } * + * } * + * * + * The DENSE_ELEM(A,i,j) macro is appropriate for use in small * + * problems in which efficiency of access is NOT a major concern. * + * * + * f is the right hand side function for the ODE problem. * + * * + * f_data is a pointer to user data to be passed to f, the same * + * as the F_data parameter passed to CVodeMalloc. * + * * + * t is the current value of the independent variable. * + * * + * y is the current value of the dependent variable vector, * + * namely the predicted value of y(t). * + * * + * fy is the vector f(t,y). * + * * + * ewt is the error weight vector. * + * * + * h is a tentative step size in t. * + * * + * uround is the machine unit roundoff. * + * * + * jac_data is a pointer to user data - the same as the jac_data * + * parameter passed to CVDense. * + * * + * nfePtr is a pointer to the memory location containing the * + * CVODE problem data nfe = number of calls to f. The Jacobian * + * routine should update this counter by adding on the number * + * of f calls made in order to approximate the Jacobian, if any. * + * For example, if the routine calls f a total of N times, then * + * the update is *nfePtr += N. * + * * + * vtemp1, vtemp2, and vtemp3 are pointers to memory allocated * + * for vectors of length N which can be used by a CVDenseJacFn * + * as temporary storage or work space. * + * * + ******************************************************************/ + +typedef void (*CVDenseJacFn)(integer N, DenseMat J, RhsFn f, void *f_data, + real t, N_Vector y, N_Vector fy, N_Vector ewt, + real h, real uround, void *jac_data, + long int *nfePtr, N_Vector vtemp1, + N_Vector vtemp2, N_Vector vtemp3); + + +/****************************************************************** + * * + * Function : CVDense * + *----------------------------------------------------------------* + * A call to the CVDense function links the main CVODE integrator * + * with the CVDENSE linear solver. * + * * + * cvode_mem is the pointer to CVODE memory returned by * + * CVodeMalloc. * + * * + * djac is the dense Jacobian approximation routine to be used. * + * A user-supplied djac routine must be of type * + * CVDenseJacFn. Pass NULL for djac to use the default * + * difference quotient routine CVDenseDQJac supplied * + * with this solver. * + * * + * jac_data is a pointer to user data which is passed to the * + * djac routine every time it is called. * + * * + ******************************************************************/ + +void CVDense(void *cvode_mem, CVDenseJacFn djac, void *jac_data); + + +/****************************************************************** + * * + * Function : CVDenseDQJac * + *----------------------------------------------------------------* + * This routine generates a dense difference quotient * + * approximation to the Jacobian of f(t,y). * + * * + ******************************************************************/ + +void CVDenseDQJac(integer N, DenseMat J, RhsFn f, void *f_data, real t, + N_Vector y, N_Vector fy, N_Vector ewt, real h, real uround, + void *jac_data, long int *nfePtr, N_Vector vtemp1, + N_Vector vtemp2, N_Vector vtemp3); + + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/ext/cvode/include/cvdiag.h b/ext/cvode/include/cvdiag.h new file mode 100755 index 000000000..9c5399149 --- /dev/null +++ b/ext/cvode/include/cvdiag.h @@ -0,0 +1,71 @@ +/****************************************************************** + * * + * File : cvdiag.h * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 4 May 1998 * + *----------------------------------------------------------------* + * This is the header file for the CVODE diagonal linear solver, * + * CVDIAG. * + * * + * Note: The type integer must be large enough to store the value * + * of the linear system size N. * + * * + ******************************************************************/ + + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +#ifndef _cvdiag_h +#define _cvdiag_h + +#include +#include "cvode.h" +#include "llnltyps.h" +#include "nvector.h" + + +/****************************************************************** + * * + * CVDIAG solver statistics indices * + *----------------------------------------------------------------* + * The following enumeration gives a symbolic name to each * + * CVDIAG statistic. The symbolic names are used as indices into * + * the iopt and ropt arrays passed to CVodeMalloc. * + * The CVDIAG statistics are: * + * * + * iopt[DIAG_LRW] : size (in real words) of real workspace * + * vectors used by this solver. * + * * + * iopt[DIAG_LIW] : size (in integer words) of integer * + * workspace vectors used by this solver. * + * * + * The number of diagonal approximate Jacobians formed is equal * + * to the number of CVDiagSetup calls. This number is available * + * in cv_iopt[NSETUPS]. * + * * + ******************************************************************/ + +enum { DIAG_LRW=CVODE_IOPT_SIZE, DIAG_LIW }; + + +/****************************************************************** + * * + * Function : CVDiag * + *----------------------------------------------------------------* + * A call to the CVDiag function links the main CVODE integrator * + * with the CVDIAG linear solver. * + * * + * cvode_mem is the pointer to CVODE memory returned by * + * CVodeMalloc. * + * * + ******************************************************************/ + +void CVDiag(void *cvode_mem); + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/ext/cvode/include/cvode.h b/ext/cvode/include/cvode.h new file mode 100755 index 000000000..95ea01747 --- /dev/null +++ b/ext/cvode/include/cvode.h @@ -0,0 +1,826 @@ +/****************************************************************** + * * + * File : cvode.h * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 29 February 2000 * + *----------------------------------------------------------------* + * This is the interface file for the main CVODE integrator. * + * * + ******************************************************************/ + + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +#ifndef _cvode_h +#define _cvode_h + +#ifdef WIN32 +#include +#endif + +#include +#include "llnltyps.h" +#include "nvector.h" + +/****************************************************************** + * * + * CVODE is used to solve numerically the ordinary initial value * + * problem : * + * * + * y' = f(t,y), * + * y(t0) = y0, * + * * + * where t0, y0 in R^N, and f: R x R^N -> R^N are given. * + * * + ******************************************************************/ + + +/****************************************************************** + * * + * Enumerations for inputs to CVodeMalloc, CVReInit, and CVode. * + *----------------------------------------------------------------* + * Symbolic constants for the lmm, iter, and itol input * + * parameters to CVodeMalloc and CVReInit, as well as the input * + * parameter itask to CVode, are given below. * + * * + * lmm : The user of the CVODE package specifies whether to use * + * the ADAMS or BDF (backward differentiation formula) * + * linear multistep method. The BDF method is recommended * + * for stiff problems, and the ADAMS method is recommended * + * for nonstiff problems. * + * * + * iter : At each internal time step, a nonlinear equation must * + * be solved. The user can specify either FUNCTIONAL * + * iteration, which does not require linear algebra, or a * + * NEWTON iteration, which requires the solution of linear * + * systems. In the NEWTON case, the user also specifies a * + * CVODE linear solver. NEWTON is recommended in case of * + * stiff problems. * + * * + * itol : This parameter specifies the relative and absolute * + * tolerance types to be used. The SS tolerance type means * + * a scalar relative and absolute tolerance, while the SV * + * tolerance type means a scalar relative tolerance and a * + * vector absolute tolerance (a potentially different * + * absolute tolerance for each vector component). * + * * + * itask : The itask input parameter to CVode indicates the job * + * of the solver for the next user step. The NORMAL * + * itask is to have the solver take internal steps until * + * it has reached or just passed the user specified tout * + * parameter. The solver then interpolates in order to * + * return an approximate value of y(tout). The ONE_STEP * + * option tells the solver to just take one internal step * + * and return the solution at the point reached by that * + * step. * + * * + ******************************************************************/ + +enum { ADAMS, BDF }; /* lmm */ + +enum { FUNCTIONAL, NEWTON }; /* iter */ + +enum { SS, SV }; /* itol */ + +enum { NORMAL, ONE_STEP }; /* itask */ + + +/****************************************************************** + * * + * Type : RhsFn * + *----------------------------------------------------------------* + * The f function which defines the right hand side of the ODE * + * system y' = f(t,y) must have type RhsFn. * + * f takes as input the problem size N, the independent variable * + * value t, and the dependent variable vector y. It stores the * + * result of f(t,y) in the vector ydot. The y and ydot arguments * + * are of type N_Vector. * + * (Allocation of memory for ydot is handled within CVODE.) * + * The f_data parameter is the same as the f_data * + * parameter passed by the user to the CVodeMalloc routine. This * + * user-supplied pointer is passed to the user's f function * + * every time it is called. * + * A RhsFn f does not have a return value. * + * * + ******************************************************************/ + +typedef void (*RhsFn)(integer N, real t, N_Vector y, N_Vector ydot, + void *f_data); + + +/****************************************************************** + * * + * Function : CVodeMalloc * + *----------------------------------------------------------------* + * CVodeMalloc allocates and initializes memory for a problem to * + * to be solved by CVODE. * + * * + * N is the number of equations in the ODE system. * + * * + * f is the right hand side function in y' = f(t,y). * + * * + * t0 is the initial value of t. * + * * + * y0 is the initial condition vector y(t0). * + * * + * lmm is the type of linear multistep method to be used. * + * The legal values are ADAMS and BDF (see previous * + * description). * + * * + * iter is the type of iteration used to solve the nonlinear * + * system that arises during each internal time step. * + * The legal values are FUNCTIONAL and NEWTON. * + * * + * itol is the type of tolerances to be used. * + * The legal values are: * + * SS (scalar relative and absolute tolerances), * + * SV (scalar relative tolerance and vector * + * absolute tolerance). * + * * + * reltol is a pointer to the relative tolerance scalar. * + * * + * abstol is a pointer to the absolute tolerance scalar or * + * an N_Vector of absolute tolerances. * + * * + * The parameters itol, reltol, and abstol define a vector of * + * error weights, ewt, with components * + * ewt[i] = 1/(reltol*abs(y[i]) + abstol) (if itol = SS), or * + * ewt[i] = 1/(reltol*abs(y[i]) + abstol[i]) (if itol = SV). * + * This vector is used in all error and convergence tests, which * + * use a weighted RMS norm on all error-like vectors v: * + * WRMSnorm(v) = sqrt( (1/N) sum(i=1..N) (v[i]*ewt[i])^2 ). * + * * + * f_data is a pointer to user data that will be passed to the * + * user's f function every time f is called. * + * * + * errfp is the file pointer for an error file where all CVODE * + * warning and error messages will be written. This * + * parameter can be stdout (standard output), stderr * + * (standard error), a file pointer (corresponding to * + * a user error file opened for writing) returned by * + * fopen, or NULL. If the user passes NULL, then all * + * messages will be written to standard output. * + * * + * optIn is a flag indicating whether there are any optional * + * inputs from the user in the arrays iopt and ropt. * + * Pass FALSE to indicate no optional inputs and TRUE * + * to indicate that optional inputs are present. * + * * + * iopt is the user-allocated array (of size OPT_SIZE given * + * later) that will hold optional integer inputs and * + * outputs. The user can pass NULL if he/she does not * + * wish to use optional integer inputs or outputs. * + * If optIn is TRUE, the user should preset to 0 those * + * locations for which default values are to be used. * + * * + * ropt is the user-allocated array (of size OPT_SIZE given * + * later) that will hold optional real inputs and * + * outputs. The user can pass NULL if he/she does not * + * wish to use optional real inputs or outputs. * + * If optIn is TRUE, the user should preset to 0.0 the * + * locations for which default values are to be used. * + * * + * machEnv is a pointer to machine environment-specific * + * information. * + * * + * Note: The tolerance values may be changed in between calls to * + * CVode for the same problem. These values refer to * + * (*reltol) and either (*abstol), for a scalar absolute * + * tolerance, or the components of abstol, for a vector * + * absolute tolerance. * + * * + * If successful, CVodeMalloc returns a pointer to initialized * + * problem memory. This pointer should be passed to CVode. If * + * an initialization error occurs, CVodeMalloc prints an error * + * message to the file specified by errfp and returns NULL. * + * * + ******************************************************************/ + + +void *CVodeMalloc(integer N, RhsFn f, real t0, N_Vector y0, int lmm, int iter, + int itol, real *reltol, void *abstol, void *f_data, + FILE *errfp, boole optIn, long int iopt[], real ropt[], + void *machEnv); + + +/****************************************************************** + * * + * Function : CVReInit * + *----------------------------------------------------------------* + * CVReInit re-initializes CVode for the solution of a problem, * + * where a prior call to CVodeMalloc has been made with the same * + * problem size N. CVReInit performs the same input checking * + * and initializations that CVodeMalloc does (except for N). * + * But it does no memory allocation, assuming that the existing * + * internal memory is sufficient for the new problem. * + * * + * The use of CVReInit requires that the maximum method order, * + * maxord, is no larger for the new problem than for the problem * + * specified in the last call to CVodeMalloc. This condition is * + * automatically fulfilled if the multistep method parameter lmm * + * is unchanged (or changed from ADAMS to BDF) and the default * + * value for maxord is specified. * + * * + * The first argument to CVReInit is: * + * * + * cvode_mem = pointer to CVODE memory returned by CVodeMalloc. * + * * + * All the remaining arguments to CVReInit have names and * + * meanings identical to those of CVodeMalloc. Note that the * + * problem size N is not passed as an argument to CVReInit, * + * as that is assumed to unchanged since the CVodeMalloc call. * + * * + * The return value of CVReInit is equal to SUCCESS = 0 if there * + * were no errors; otherwise it is a negative int equal to: * + * CVREI_NO_MEM indicating cvode_mem was NULL, or * + * CVREI_ILL_INPUT indicating an input argument was illegal * + * (including an attempt to increase maxord). * + * In case of an error return, an error message is also printed. * + * * + * Note: the reported workspace sizes iopt[LENRW] and iopt[LENIW] * + * are left unchanged from the values computed by CVodeMalloc, and* + * so may be larger than would be computed for the new problem. * + ******************************************************************/ + + +int CVReInit(void *cvode_mem, RhsFn f, real t0, N_Vector y0, + int lmm, int iter, int itol, real *reltol, void *abstol, + void *f_data, FILE *errfp, boole optIn, long int iopt[], + real ropt[], void *machEnv); + + +/* CVReInit return values: */ + +/* SUCCESS = 0 (Defined under CVode return values, but listed + here also for completeness) */ +enum {CVREI_NO_MEM = -1, CVREI_ILL_INPUT = -2}; + + +/****************************************************************** + * * + * Function : CVode * + *----------------------------------------------------------------* + * CVode integrates the ODE over an interval in t. * + * If itask is NORMAL, then the solver integrates from its * + * current internal t value to a point at or beyond tout, then * + * interpolates to t = tout and returns y(tout) in the user- * + * allocated vector yout. If itask is ONE_STEP, then the solver * + * takes one internal time step and returns in yout the value of * + * y at the new internal time. In this case, tout is used only * + * during the first call to CVode to determine the direction of * + * integration and the rough scale of the problem. In either * + * case, the time reached by the solver is placed in (*t). The * + * user is responsible for allocating the memory for this value. * + * * + * cvode_mem is the pointer to CVODE memory returned by * + * CVodeMalloc. * + * * + * tout is the next time at which a computed solution is desired * + * * + * yout is the computed solution vector. In NORMAL mode with no * + * errors, yout=y(tout). * + * * + * t is a pointer to a real location. CVode sets (*t) to the * + * time reached by the solver and returns yout=y(*t). * + * * + * itask is either NORMAL or ONE_STEP mode. These two modes have * + * described above. * + * * + * The return values for CVode are defined later in this file. * + * Here is a brief description of each return value: * + * * + * SUCCESS : CVode succeeded. * + * * + * CVODE_NO_MEM : The cvode_mem argument was NULL. * + * * + * ILL_INPUT : One of the inputs to CVode is illegal. This * + * includes the situation when a component of the * + * error weight vectors becomes < 0 during * + * internal time-stepping. The ILL_INPUT flag * + * will also be returned if the linear solver * + * routine CV--- (called by the user after * + * calling CVodeMalloc) failed to set one of the * + * linear solver-related fields in cvode_mem or * + * if the linear solver's init routine failed. In * + * any case, the user should see the printed * + * error message for more details. * + * * + * TOO_MUCH_WORK : The solver took mxstep internal steps but * + * could not reach tout. The default value for * + * mxstep is MXSTEP_DEFAULT = 500. * + * * + * TOO_MUCH_ACC : The solver could not satisfy the accuracy * + * demanded by the user for some internal step. * + * * + * ERR_FAILURE : Error test failures occurred too many times * + * (= MXNEF = 7) during one internal time step or * + * occurred with |h| = hmin. * + * * + * CONV_FAILURE : Convergence test failures occurred too many * + * times (= MXNCF = 10) during one internal time * + * step or occurred with |h| = hmin. * + * * + * SETUP_FAILURE : The linear solver's setup routine failed in an * + * unrecoverable manner. * + * * + * SOLVE_FAILURE : The linear solver's solve routine failed in an * + * unrecoverable manner. * + * * + ******************************************************************/ + + +int CVode(void *cvode_mem, real tout, N_Vector yout, real *t, int itask); + + +/* CVode return values */ + +enum { SUCCESS=0, CVODE_NO_MEM=-1, ILL_INPUT=-2, TOO_MUCH_WORK=-3, + TOO_MUCH_ACC=-4, ERR_FAILURE=-5, CONV_FAILURE=-6, + SETUP_FAILURE=-7, SOLVE_FAILURE=-8 }; + + +/****************************************************************** + * * + * Function : CVodeDky * + *----------------------------------------------------------------* + * CVodeDky computes the kth derivative of the y function at * + * time t, where tn-hu <= t <= tn, tn denotes the current * + * internal time reached, and hu is the last internal step size * + * successfully used by the solver. The user may request * + * k=0, 1, ..., qu, where qu is the current order. The * + * derivative vector is returned in dky. This vector must be * + * allocated by the caller. It is only legal to call this * + * function after a successful return from CVode. * + * * + * cvode_mem is the pointer to CVODE memory returned by * + * CVodeMalloc. * + * * + * t is the time at which the kth derivative of y is evaluated. * + * The legal range for t is [tn-hu,tn] as described above. * + * * + * k is the order of the derivative of y to be computed. The * + * legal range for k is [0,qu] as described above. * + * * + * dky is the output derivative vector [(D_k)y](t). * + * * + * The return values for CVodeDky are defined later in this file. * + * Here is a brief description of each return value: * + * * + * OKAY : CVodeDky succeeded. * + * * + * BAD_K : k is not in the range 0, 1, ..., qu. * + * * + * BAD_T : t is not in the interval [tn-hu,tn]. * + * * + * BAD_DKY : The dky argument was NULL. * + * * + * DKY_NO_MEM : The cvode_mem argument was NULL. * + * * + ******************************************************************/ + + +int CVodeDky(void *cvode_mem, real t, int k, N_Vector dky); + + +/* CVodeDky return values */ + +enum { OKAY=0, BAD_K=-1, BAD_T=-2, BAD_DKY=-3, DKY_NO_MEM=-4 }; + + +/****************************************************************** + * * + * Function : CVodeFree * + *----------------------------------------------------------------* + * CVodeFree frees the problem memory cvode_mem allocated by * + * CVodeMalloc. Its only argument is the pointer cvode_mem * + * returned by CVodeMalloc. * + * * + ******************************************************************/ + +void CVodeFree(void *cvode_mem); + + +/****************************************************************** + * * + * Optional Inputs and Outputs * + *----------------------------------------------------------------* + * The user should declare two arrays for optional input and * + * output, an iopt array for optional integer input and output * + * and an ropt array for optional real input and output. The * + * size of both these arrays should be OPT_SIZE. * + * So the user's declaration should look like: * + * * + * long int iopt[OPT_SIZE]; * + * real ropt[OPT_SIZE]; * + * * + * The enumerations below the OPT_SIZE definition * + * are indices into the iopt and ropt arrays. Here is a brief * + * description of the contents of these positions: * + * * + * iopt[MAXORD] : maximum lmm order to be used by the solver. * + * Optional input. (Default = 12 for ADAMS, 5 for * + * BDF). * + * * + * iopt[MXSTEP] : maximum number of internal steps to be taken by * + * the solver in its attempt to reach tout. * + * Optional input. (Default = 500). * + * * + * iopt[MXHNIL] : maximum number of warning messages issued * + * by the solver that t+h==t on the next internal * + * step. Optional input. (Default = 10). * + * * + * iopt[NST] : cumulative number of internal steps taken by * + * the solver (total so far). Optional output. * + * * + * iopt[NFE] : number of calls to the user's f function. * + * Optional output. * + * * + * iopt[NSETUPS] : number of calls made to the linear solver's * + * setup routine. Optional output. * + * * + * iopt[NNI] : number of NEWTON iterations performed. * + * Optional output. * + * * + * iopt[NCFN] : number of nonlinear convergence failures * + * that have occurred. Optional output. * + * * + * iopt[NETF] : number of local error test failures that * + * have occurred. Optional output. * + * * + * iopt[QU] : order used during the last internal step. * + * Optional output. * + * * + * iopt[QCUR] : order to be used on the next internal step. * + * Optional output. * + * * + * iopt[LENRW] : size of required CVODE internal real work * + * space, in real words. Optional output. * + * * + * iopt[LENIW] : size of required CVODE internal integer work * + * space, in integer words. Optional output. * + * * + * ropt[H0] : initial step size. Optional input. * + * * + * ropt[HMAX] : maximum absolute value of step size allowed. * + * Optional input. (Default is infinity). * + * * + * ropt[HMIN] : minimum absolute value of step size allowed. * + * Optional input. (Default is 0.0). * + * * + * ropt[HU] : step size for the last internal step. * + * Optional output. * + * * + * ropt[HCUR] : step size to be attempted on the next internal * + * step. Optional output. * + * * + * ropt[TCUR] : current internal time reached by the solver. * + * Optional output. * + * * + * ropt[TOLSF] : a suggested factor by which the user's * + * tolerances should be scaled when too much * + * accuracy has been requested for some internal * + * step. Optional output. * + * * + ******************************************************************/ + +/* iopt, ropt array sizes */ + +#define OPT_SIZE 40 + + +/* iopt and ropt offsets * + * The constants CVODE_IOPT_SIZE and CVODE_ROPT_SIZE are equal to * + * the number of integer and real optional inputs and outputs * + * actually accessed in cvode.c. The locations beyond these * + * values are used by the linear solvers. */ + +#define CVODE_IOPT_SIZE 13 +#define CVODE_ROPT_SIZE 7 + +/* iopt indices */ + +enum { MAXORD, MXSTEP, MXHNIL, + NST, NFE, NSETUPS, NNI, NCFN, NETF, QU, QCUR, + LENRW, LENIW }; + +/* ropt indices */ + +enum { H0, HMAX, HMIN, + HU, HCUR, TCUR, TOLSF }; + + +/* Basic CVODE constants */ + +#define ADAMS_Q_MAX 12 /* max value of q for lmm == ADAMS */ +#define BDF_Q_MAX 5 /* max value of q for lmm == BDF */ +#define Q_MAX ADAMS_Q_MAX /* max value of q for either lmm */ +#define L_MAX (Q_MAX+1) /* max value of L for either lmm */ +#define NUM_TESTS 5 /* number of error test quantities */ + + +/****************************************************************** + * * + * Types : struct CVodeMemRec, CVodeMem * + *----------------------------------------------------------------* + * The type CVodeMem is type pointer to struct CVodeMemRec. This * + * structure contains fields to keep track of problem state. * + * * + ******************************************************************/ + +typedef struct CVodeMemRec { + + real cv_uround; /* machine unit roundoff */ + + /* Problem Specification Data */ + + integer cv_N; /* ODE system size */ + RhsFn cv_f; /* y' = f(t,y(t)) */ + void *cv_f_data; /* user pointer passed to f */ + int cv_lmm; /* lmm = ADAMS or BDF */ + int cv_iter; /* iter = FUNCTIONAL or NEWTON */ + int cv_itol; /* itol = SS or SV */ + real *cv_reltol; /* ptr to relative tolerance */ + void *cv_abstol; /* ptr to absolute tolerance */ + + /* Nordsieck History Array */ + + N_Vector cv_zn[L_MAX]; /* Nordsieck array N x (q+1), */ + /* zn[j] is a vector of length N, j=0, ... , q */ + /* zn[j] = h^j * jth derivative of the */ + /* interpolating polynomial */ + + /* Vectors of length N */ + + N_Vector cv_ewt; /* error weight vector */ + N_Vector cv_y; /* y is used as temporary storage by the solver */ + /* The memory is provided by the user to CVode */ + /* where the vector is named yout. */ + N_Vector cv_acor; /* In the context of the solution of the */ + /* nonlinear equation, acor = y_n(m) - y_n(0). */ + /* On return, this vector is scaled to give */ + /* the estimated local error in y. */ + N_Vector cv_tempv; /* temporary storage vector */ + N_Vector cv_ftemp; /* temporary storage vector */ + + /* Step Data */ + + int cv_q; /* current order */ + int cv_qprime; /* order to be used on the next step */ + /* = q-1, q, or q+1 */ + int cv_qwait; /* number of internal steps to wait before */ + /* considering a change in q */ + int cv_L; /* L = q + 1 */ + + real cv_h; /* current step size */ + real cv_hprime; /* step size to be used on the next step */ + real cv_eta; /* eta = hprime / h */ + real cv_hscale; /* value of h used in zn */ + real cv_tn; /* current internal value of t */ + + real cv_tau[L_MAX+1]; /* array of previous q+1 successful step */ + /* sizes indexed from 1 to q+1 */ + real cv_tq[NUM_TESTS+1]; /* array of test quantities indexed from */ + /* 1 to NUM_TESTS(=5) */ + real cv_l[L_MAX]; /* coefficients of l(x) (degree q poly) */ + + real cv_rl1; /* 1 / l[1] */ + real cv_gamma; /* gamma = h * rl1 */ + real cv_gammap; /* gamma at the last setup call */ + real cv_gamrat; /* gamma / gammap */ + + real cv_crate; /* estimated corrector convergence rate */ + real cv_acnrm; /* | acor | wrms */ + int cv_mnewt; /* Newton iteration counter */ + + /* Limits */ + + int cv_qmax; /* q <= qmax */ + int cv_mxstep; /* maximum number of internal steps for one user call */ + int cv_maxcor; /* maximum number of corrector iterations for the */ + /* solution of the nonlinear equation */ + int cv_mxhnil; /* maximum number of warning messages issued to the */ + /* user that t + h == t for the next internal step */ + + real cv_hmin; /* |h| >= hmin */ + real cv_hmax_inv; /* |h| <= 1/hmax_inv */ + real cv_etamax; /* eta <= etamax */ + + /* Counters */ + + long int cv_nst; /* number of internal steps taken */ + long int cv_nfe; /* number of f calls */ + long int cv_ncfn; /* number of corrector convergence failures */ + long int cv_netf; /* number of error test failures */ + long int cv_nni; /* number of Newton iterations performed */ + long int cv_nsetups; /* number of setup calls */ + int cv_nhnil; /* number of messages issued to the user that */ + /* t + h == t for the next iternal step */ + long int cv_lrw; /* number of real words in CVODE work vectors */ + long int cv_liw; /* no. of integer words in CVODE work vectors */ + + /* Linear Solver Data */ + + /* Linear Solver functions to be called */ + + int (*cv_linit)(struct CVodeMemRec *cv_mem, boole *setupNonNull); + + int (*cv_lsetup)(struct CVodeMemRec *cv_mem, int convfail, N_Vector ypred, + N_Vector fpred, boole *jcurPtr, N_Vector vtemp1, + N_Vector vtemp2, N_Vector vtemp3); + + int (*cv_lsolve)(struct CVodeMemRec *cv_mem, N_Vector b, N_Vector ycur, + N_Vector fcur); + + void (*cv_lfree)(struct CVodeMemRec *cv_mem); + + /* Linear Solver specific memory */ + + void *cv_lmem; + + /* Flag to indicate successful cv_linit call */ + + boole cv_linitOK; + + /* Saved Values */ + + int cv_qu; /* last successful q value used */ + long int cv_nstlp; /* step number of last setup call */ + real cv_hu; /* last successful h value used */ + real cv_saved_tq5; /* saved value of tq[5] */ + boole cv_jcur; /* Is the Jacobian info used by */ + /* linear solver current? */ + real cv_tolsf; /* tolerance scale factor */ + boole cv_setupNonNull;/* Does setup do something? */ + + /* Arrays for Optional Input and Optional Output */ + + long int *cv_iopt; /* long int optional input, output */ + real *cv_ropt; /* real optional input, output */ + + /* Error File */ + + FILE *cv_errfp; /* CVODE error messages are sent to errfp */ + + /* Pointer to Machine Environment-Specific Information */ + + void *cv_machenv; + +} *CVodeMem; + + +/****************************************************************** + * * + * Communication between cvode.c and a CVODE Linear Solver * + *----------------------------------------------------------------* + * (1) cv_linit return values * + * * + * LINIT_OK : The cv_linit routine succeeded. * + * * + * LINIT_ERR : The cv_linit routine failed. Each linear solver * + * init routine should print an appropriate error * + * message to (cv_mem->errfp). * + * * + * (2) convfail (input to cv_lsetup) * + * * + * NO_FAILURES : Either this is the first cv_setup call for this * + * step, or the local error test failed on the * + * previous attempt at this step (but the Newton * + * iteration converged). * + * * + * FAIL_BAD_J : This value is passed to cv_lsetup if * + * * + * (1) The previous Newton corrector iteration * + * did not converge and the linear solver's * + * setup routine indicated that its Jacobian- * + * related data is not current. * + * or * + * (2) During the previous Newton corrector * + * iteration, the linear solver's solve routine * + * failed in a recoverable manner and the * + * linear solver's setup routine indicated that * + * its Jacobian-related data is not current. * + * * + * FAIL_OTHER : During the current internal step try, the * + * previous Newton iteration failed to converge * + * even though the linear solver was using current * + * Jacobian-related data. * + * * + * (3) Parameter documentation, as well as a brief description * + * of purpose, for each CVODE linear solver routine to be * + * called in cvode.c is given below the constant declarations * + * that follow. * + * * + ******************************************************************/ + +/* cv_linit return values */ + +#define LINIT_OK 0 +#define LINIT_ERR -1 + +/* Constants for convfail (input to cv_lsetup) */ + +#define NO_FAILURES 0 +#define FAIL_BAD_J 1 +#define FAIL_OTHER 2 + + +/******************************************************************* + * * + * int (*cv_linit)(CVodeMem cv_mem, boole *setupNonNull); * + *-----------------------------------------------------------------* + * The purpose of cv_linit is to allocate memory for the * + * solver-specific fields in the structure *(cv_mem->cv_lmem) and * + * perform any needed initializations of solver-specific memory, * + * such as counters/statistics. The cv_linit routine should set * + * *setupNonNull to be TRUE if the setup operation for the linear * + * solver is non-empty and FALSE if the setup operation does * + * nothing. An LInitFn should return LINIT_OK (== 0) if it has * + * successfully initialized the CVODE linear solver and LINIT_ERR * + * (== -1) otherwise. These constants are defined above. If an * + * error does occur, an appropriate message should be sent to * + * (cv_mem->errfp). * + * * + *******************************************************************/ + +/******************************************************************* + * * + * int (*cv_lsetup)(CVodeMem cv_mem, int convfail, N_Vector ypred, * + * N_Vector fpred, boole *jcurPtr, N_Vector vtemp1,* + * N_Vector vtemp2, N_Vector vtemp3); * + *-----------------------------------------------------------------* + * The job of cv_lsetup is to prepare the linear solver for * + * subsequent calls to cv_lsolve. It may re-compute Jacobian- * + * related data is it deems necessary. Its parameters are as * + * follows: * + * * + * cv_mem - problem memory pointer of type CVodeMem. See the big * + * typedef earlier in this file. * + * * + * convfail - a flag to indicate any problem that occurred during * + * the solution of the nonlinear equation on the * + * current time step for which the linear solver is * + * being used. This flag can be used to help decide * + * whether the Jacobian data kept by a CVODE linear * + * solver needs to be updated or not. * + * Its possible values have been documented above. * + * * + * ypred - the predicted y vector for the current CVODE internal * + * step. * + * * + * fpred - f(tn, ypred). * + * * + * jcurPtr - a pointer to a boolean to be filled in by cv_lsetup. * + * The function should set *jcurPtr=TRUE if its Jacobian * + * data is current after the call and should set * + * *jcurPtr=FALSE if its Jacobian data is not current. * + * Note: If cv_lsetup calls for re-evaluation of * + * Jacobian data (based on convfail and CVODE state * + * data), it should return *jcurPtr=TRUE unconditionally;* + * otherwise an infinite loop can result. * + * * + * vtemp1 - temporary N_Vector provided for use by cv_lsetup. * + * * + * vtemp3 - temporary N_Vector provided for use by cv_lsetup. * + * * + * vtemp3 - temporary N_Vector provided for use by cv_lsetup. * + * * + * The cv_lsetup routine should return 0 if successful, * + * a positive value for a recoverable error, and a negative value * + * for an unrecoverable error. * + * * + *******************************************************************/ + +/******************************************************************* + * * + * int (*cv_lsolve)(CVodeMem cv_mem, N_Vector b, N_Vector ycur, * + * N_Vector fcur); * + *-----------------------------------------------------------------* + * cv_lsolve must solve the linear equation P x = b, where * + * P is some approximation to (I - gamma J), J = (df/dy)(tn,ycur) * + * and the RHS vector b is input. The N-vector ycur contains * + * the solver's current approximation to y(tn) and the vector * + * fcur contains the N-vector f(tn,ycur). The solution is to be * + * returned in the vector b. cv_lsolve returns a positive value * + * for a recoverable error and a negative value for an * + * unrecoverable error. Success is indicated by a 0 return value. * + * * + *******************************************************************/ + +/******************************************************************* + * * + * void (*cv_lfree)(CVodeMem cv_mem); * + *-----------------------------------------------------------------* + * cv_lfree should free up any memory allocated by the linear * + * solver. This routine is called once a problem has been * + * completed and the linear solver is no longer needed. * + * * + *******************************************************************/ + + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/ext/cvode/include/cvspgmr.h b/ext/cvode/include/cvspgmr.h new file mode 100755 index 000000000..a789546e7 --- /dev/null +++ b/ext/cvode/include/cvspgmr.h @@ -0,0 +1,336 @@ +/****************************************************************** + * * + * File : cvspgmr.h * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 4 May 1998 * + *----------------------------------------------------------------* + * This is the header file for the CVODE scaled, preconditioned * + * GMRES linear solver, CVSPGMR. * + * * + * Note: The type integer must be large enough to store the value * + * of the linear system size N. * + * * + ******************************************************************/ + + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +#ifndef _cvspgmr_h +#define _cvspgmr_h + + +#include +#include "cvode.h" +#include "spgmr.h" +#include "llnltyps.h" +#include "nvector.h" + + +/****************************************************************** + * * + * CVSPGMR solver statistics indices * + *----------------------------------------------------------------* + * The following enumeration gives a symbolic name to each * + * CVSPGMR statistic. The symbolic names are used as indices into * + * the iopt and ropt arrays passed to CVodeMalloc. * + * The CVSPGMR statistics are: * + * * + * iopt[SPGMR_NPE] : number of preconditioner evaluations, * + * i.e. of calls made to user's precond * + * function with jok == FALSE. * + * * + * iopt[SPGMR_NLI] : number of linear iterations. * + * * + * iopt[SPGMR_NPS] : number of calls made to user's psolve * + * function. * + * * + * iopt[SPGMR_NCFL] : number of linear convergence failures. * + * * + * iopt[SPGMR_LRW] : size (in real words) of real workspace * + * vectors and small matrices used by this * + * solver. * + * * + * iopt[SPGMR_LIW] : size (in integer words) of integer * + * workspace vectors used by this solver. * + * * + ******************************************************************/ + +enum { SPGMR_NPE = CVODE_IOPT_SIZE, + SPGMR_NLI, SPGMR_NPS, SPGMR_NCFL, SPGMR_LRW, SPGMR_LIW }; + + +/****************************************************************** + * * + * CVSPGMR solver constants * + *----------------------------------------------------------------* + * CVSPGMR_MAXL : default value for the maximum Krylov * + * dimension is MIN(N, CVSPGMR_MAXL) * + * * + * CVSPGMR_MSBPRE : maximum number of steps between * + * preconditioner evaluations * + * * + * CVSPGMR_DGMAX : maximum change in gamma between * + * preconditioner evaluations * + * * + * CVSPGMR_DELT : default value for factor by which the * + * tolerance on the nonlinear iteration is * + * multiplied to get a tolerance on the linear * + * iteration * + * * + ******************************************************************/ + +#define CVSPGMR_MAXL 5 + +#define CVSPGMR_MSBPRE 50 + +#define CVSPGMR_DGMAX RCONST(0.2) + +#define CVSPGMR_DELT RCONST(0.05) + + +/****************************************************************** + * * + * Type : CVSpgmrPrecondFn * + *----------------------------------------------------------------* + * The user-supplied preconditioner setup function Precond and * + * the user-supplied preconditioner solve function PSolve * + * together must define left and right preconditoner matrices * + * P1 and P2 (either of which may be trivial), such that the * + * product P1*P2 is an approximation to the Newton matrix * + * M = I - gamma*J. Here J is the system Jacobian J = df/dy, * + * and gamma is a scalar proportional to the integration step * + * size h. The solution of systems P z = r, with P = P1 or P2, * + * is to be carried out by the PSolve function, and Precond is * + * to do any necessary setup operations. * + * * + * The user-supplied preconditioner setup function Precond * + * is to evaluate and preprocess any Jacobian-related data * + * needed by the preconditioner solve function PSolve. * + * This might include forming a crude approximate Jacobian, * + * and performing an LU factorization on the resulting * + * approximation to M. This function will not be called in * + * advance of every call to PSolve, but instead will be called * + * only as often as necessary to achieve convergence within the * + * Newton iteration in CVODE. If the PSolve function needs no * + * preparation, the Precond function can be NULL. * + * * + * For greater efficiency, the Precond function may save * + * Jacobian-related data and reuse it, rather than generating it * + * from scratch. In this case, it should use the input flag jok * + * to decide whether to recompute the data, and set the output * + * flag *jcurPtr accordingly. * + * * + * Each call to the Precond function is preceded by a call to * + * the RhsFn f with the same (t,y) arguments. Thus the Precond * + * function can use any auxiliary data that is computed and * + * saved by the f function and made accessible to Precond. * + * * + * The error weight vector ewt, step size h, and unit roundoff * + * uround are provided to the Precond function for possible use * + * in approximating Jacobian data, e.g. by difference quotients. * + * * + * A function Precond must have the prototype given below. * + * Its parameters are as follows: * + * * + * N is the length of all vector arguments. * + * * + * t is the current value of the independent variable. * + * * + * y is the current value of the dependent variable vector, * + * namely the predicted value of y(t). * + * * + * fy is the vector f(t,y). * + * * + * jok is an input flag indicating whether Jacobian-related * + * data needs to be recomputed, as follows: * + * jok == FALSE means recompute Jacobian-related data * + * from scratch. * + * jok == TRUE means that Jacobian data, if saved from * + * the previous Precond call, can be reused * + * (with the current value of gamma). * + * A Precond call with jok == TRUE can only occur after * + * a call with jok == FALSE. * + * * + * jcurPtr is a pointer to an output integer flag which is * + * to be set by Precond as follows: * + * Set *jcurPtr = TRUE if Jacobian data was recomputed. * + * Set *jcurPtr = FALSE if Jacobian data was not * + * recomputed, but saved data was reused. * + * * + * gamma is the scalar appearing in the Newton matrix. * + * * + * ewt is the error weight vector. * + * * + * h is a tentative step size in t. * + * * + * uround is the machine unit roundoff. * + * * + * nfePtr is a pointer to the memory location containing the * + * CVODE problem data nfe = number of calls to f. * + * The Precond routine should update this counter by * + * adding on the number of f calls made in order to * + * approximate the Jacobian, if any. For example, if * + * the routine calls f a total of W times, then the * + * update is *nfePtr += W. * + * * + * P_data is a pointer to user data - the same as the P_data * + * parameter passed to CVSpgmr. * + * * + * vtemp1, vtemp2, and vtemp3 are pointers to memory allocated * + * for vectors of length N which can be used by * + * CVSpgmrPrecondFn as temporary storage or work space. * + * * + * * + * Returned value: * + * The value to be returned by the Precond function is a flag * + * indicating whether it was successful. This value should be * + * 0 if successful, * + * > 0 for a recoverable error (step will be retried), * + * < 0 for an unrecoverable error (integration is halted). * + * * + ******************************************************************/ + +typedef int (*CVSpgmrPrecondFn)(integer N, real t, N_Vector y, N_Vector fy, + boole jok, boole *jcurPtr, real gamma, + N_Vector ewt, real h, real uround, + long int *nfePtr, void *P_data, + N_Vector vtemp1, N_Vector vtemp2, + N_Vector vtemp3); + + +/****************************************************************** + * * + * Type : CVSpgmrPSolveFn * + *----------------------------------------------------------------* + * The user-supplied preconditioner solve function PSolve * + * is to solve a linear system P z = r in which the matrix P is * + * one of the preconditioner matrices P1 or P2, depending on the * + * type of preconditioning chosen. * + * * + * A function PSolve must have the prototype given below. * + * Its parameters are as follows: * + * * + * N is the length of all vector arguments. * + * * + * t is the current value of the independent variable. * + * * + * y is the current value of the dependent variable vector. * + * * + * fy is the vector f(t,y). * + * * + * vtemp is a pointer to memory allocated for a vector of * + * length N which can be used by PSolve for work space. * + * * + * gamma is the scalar appearing in the Newton matrix. * + * * + * ewt is the error weight vector (input). See delta below. * + * * + * delta is an input tolerance for use by PSolve if it uses * + * an iterative method in its solution. In that case, * + * the residual vector Res = r - P z of the system * + * should be made less than delta in weighted L2 norm, * + * i.e., sqrt [ Sum (Res[i]*ewt[i])^2 ] < delta . * + * * + * nfePtr is a pointer to the memory location containing the * + * CVODE problem data nfe = number of calls to f. The * + * PSolve routine should update this counter by adding * + * on the number of f calls made in order to carry out * + * the solution, if any. For example, if the routine * + * calls f a total of W times, then the update is * + * *nfePtr += W. * + * * + * r is the right-hand side vector of the linear system. * + * * + * lr is an input flag indicating whether PSolve is to use * + * the left preconditioner P1 or right preconditioner * + * P2: lr = 1 means use P1, and lr = 2 means use P2. * + * * + * P_data is a pointer to user data - the same as the P_data * + * parameter passed to CVSpgmr. * + * * + * z is the output vector computed by PSolve. * + * * + * Returned value: * + * The value to be returned by the PSolve function is a flag * + * indicating whether it was successful. This value should be * + * 0 if successful, * + * positive for a recoverable error (step will be retried), * + * negative for an unrecoverable error (integration is halted). * + * * + ******************************************************************/ + +typedef int (*CVSpgmrPSolveFn)(integer N, real t, N_Vector y, N_Vector fy, + N_Vector vtemp, real gamma, N_Vector ewt, + real delta, long int *nfePtr, N_Vector r, + int lr, void *P_data, N_Vector z); + + +/****************************************************************** + * * + * Function : CVSpgmr * + *----------------------------------------------------------------* + * A call to the CVSpgmr function links the main CVODE integrator * + * with the CVSPGMR linear solver. * + * * + * cvode_mem is the pointer to CVODE memory returned by * + * CVodeMalloc. * + * * + * pretype is the type of user preconditioning to be done. * + * This must be one of the four enumeration constants * + * NONE, LEFT, RIGHT, or BOTH defined in iterativ.h. * + * These correspond to no preconditioning, * + * left preconditioning only, right preconditioning * + * only, and both left and right preconditioning, * + * respectively. * + * * + * gstype is the type of Gram-Schmidt orthogonalization to be * + * used. This must be one of the two enumeration * + * constants MODIFIED_GS or CLASSICAL_GS defined in * + * iterativ.h. These correspond to using modified * + * Gram-Schmidt and classical Gram-Schmidt, * + * respectively. * + * * + * maxl is the maximum Krylov dimension. This is an * + * optional input to the CVSPGMR solver. Pass 0 to * + * use the default value MIN(N, CVSPGMR_MAXL=5). * + * * + * delt is the factor by which the tolerance on the * + * nonlinear iteration is multiplied to get a * + * tolerance on the linear iteration. This is an * + * optional input to the CVSPGMR solver. Pass 0 to * + * use the default value CVSPGMR_DELT = 0.05. * + * * + * precond is the user's preconditioner routine. It is used to * + * evaluate and preprocess any Jacobian-related data * + * needed by the psolve routine. See the * + * documentation for the type CVSpgmrPrecondFn for * + * full details. Pass NULL if no such setup of * + * Jacobian data is required. A precond routine is * + * NOT required for any of the four possible values * + * of pretype. * + * * + * psolve is the user's preconditioner solve routine. It is * + * used to solve Pz=r, where P is a preconditioner * + * matrix. See the documentation for the type * + * CVSpgmrPSolveFn for full details. The only case * + * in which psolve is allowed to be NULL is when * + * pretype is NONE. A valid psolve function must be * + * supplied when any preconditioning is to be done. * + * * + * P_data is a pointer to user preconditioner data. This * + * pointer is passed to precond and psolve every time * + * these routines are called. * + * * + ******************************************************************/ + +void CVSpgmr(void *cvode_mem, int pretype, int gstype, int maxl, real delt, + CVSpgmrPrecondFn precond, CVSpgmrPSolveFn psolve, void *P_data); + + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/ext/cvode/include/dense.h b/ext/cvode/include/dense.h new file mode 100755 index 000000000..64ec3c850 --- /dev/null +++ b/ext/cvode/include/dense.h @@ -0,0 +1,494 @@ +/****************************************************************** + * * + * File : dense.h * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 6 May 1998 * + *----------------------------------------------------------------* + * This is the header file for a generic DENSE linear solver * + * package. There are two sets of dense solver routines listed in * + * this file: one set uses type DenseMat defined below and the * + * other set uses the type real ** for dense matrix arguments. * + * The two sets of dense solver routines make it easy to work * + * with two types of dense matrices: * + * * + * (1) The DenseMat type is intended for use with large dense * + * matrices whose elements/columns may be stored in * + * non-contiguous memory locations or even distributed into * + * different processor memories. This type may be modified to * + * include such distribution information. If this is done, * + * then all the routines that use DenseMat must be modified * + * to reflect the new data structure. * + * * + * (2) The set of routines that use real ** (and NOT the DenseMat * + * type) is intended for use with small matrices which can * + * easily be allocated within a contiguous block of memory * + * on a single processor. * + * * + * Routines that work with the type DenseMat begin with "Dense". * + * The DenseAllocMat function allocates a dense matrix for use in * + * the other DenseMat routines listed in this file. Matrix * + * storage details are given in the documentation for the type * + * DenseMat. The DenseAllocPiv function allocates memory for * + * pivot information. The storage allocated by DenseAllocMat and * + * DenseAllocPiv is deallocated by the routines DenseFreeMat and * + * DenseFreePiv, respectively. The DenseFactor and DenseBacksolve * + * routines perform the actual solution of a dense linear system. * + * Note that the DenseBacksolve routine has a parameter b of type * + * N_Vector. The current implementation makes use of a machine * + * environment-specific macro (N_VDATA) which may not exist for * + * other implementations of the type N_Vector. Thus, the * + * implementation of DenseBacksolve may need to change if the * + * type N_Vector is changed. * + * * + * Routines that work with real ** begin with "den" (except for * + * the factor and solve routines which are called gefa and gesl, * + * respectively). The underlying matrix storage is described in * + * the documentation for denalloc. * + * * + ******************************************************************/ + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif +#ifndef _dense_h +#define _dense_h + + +#include "llnltyps.h" +#include "nvector.h" + + +/****************************************************************** + * * + * Type: DenseMat * + *----------------------------------------------------------------* + * The type DenseMat is defined to be a pointer to a structure * + * with a size and a data field. The size field indicates the * + * number of columns (== number of rows) of a dense matrix, while * + * the data field is a two dimensional array used for component * + * storage. The elements of a dense matrix are stored columnwise * + * (i.e columns are stored one on top of the other in memory). If * + * A is of type DenseMat, then the (i,j)th element of A (with * + * 0 <= i,j <= size-1) is given by the expression (A->data)[j][i] * + * or by the expression (A->data)[0][j*n+i]. The macros below * + * allow a user to access efficiently individual matrix * + * elements without writing out explicit data structure * + * references and without knowing too much about the underlying * + * element storage. The only storage assumption needed is that * + * elements are stored columnwise and that a pointer to the jth * + * column of elements can be obtained via the DENSE_COL macro. * + * Users should use these macros whenever possible. * + * * + ******************************************************************/ + +typedef struct { + integer size; + real **data; +} *DenseMat; + + +/* DenseMat accessor macros */ + + +/****************************************************************** + * * + * Macro : DENSE_ELEM * + * Usage : DENSE_ELEM(A,i,j) = a_ij; OR * + * a_ij = DENSE_ELEM(A,i,j); * + *----------------------------------------------------------------* + * DENSE_ELEM(A,i,j) references the (i,j)th element of the N by N * + * DenseMat A, 0 <= i,j <= N-1. * + * * + ******************************************************************/ + +#define DENSE_ELEM(A,i,j) ((A->data)[j][i]) + + +/****************************************************************** + * * + * Macro : DENSE_COL * + * Usage : col_j = DENSE_COL(A,j); * + *----------------------------------------------------------------* + * DENSE_COL(A,j) references the jth column of the N by N * + * DenseMat A, 0 <= j <= N-1. The type of the expression * + * DENSE_COL(A,j) is real *. After the assignment in the usage * + * above, col_j may be treated as an array indexed from 0 to N-1. * + * The (i,j)th element of A is referenced by col_j[i]. * + * * + ******************************************************************/ + +#define DENSE_COL(A,j) ((A->data)[j]) + + +/* Functions that use the DenseMat representation for a dense matrix */ + + +/****************************************************************** + * * + * Function : DenseAllocMat * + * Usage : A = DenseAllocMat(N); * + * if (A == NULL) ... memory request failed * + *----------------------------------------------------------------* + * DenseAllocMat allocates memory for an N by N dense matrix and * + * returns the storage allocated (type DenseMat). DenseAllocMat * + * returns NULL if the request for matrix storage cannot be * + * satisfied. See the above documentation for the type DenseMat * + * for matrix storage details. * + * * + ******************************************************************/ + +DenseMat DenseAllocMat(integer N); + + +/****************************************************************** + * * + * Function : DenseAllocPiv * + * Usage : p = DenseAllocPiv(N); * + * if (p == NULL) ... memory request failed * + *----------------------------------------------------------------* + * DenseAllocPiv allocates memory for pivot information to be * + * filled in by the DenseFactor routine during the factorization * + * of an N by N dense matrix. The underlying type for pivot * + * information is an array of N integers and this routine returns * + * the pointer to the memory it allocates. If the request for * + * pivot storage cannot be satisfied, DenseAllocPiv returns NULL. * + * * + ******************************************************************/ + +integer *DenseAllocPiv(integer N); + + +/****************************************************************** + * * + * Function : DenseFactor * + * Usage : ier = DenseFactor(A, p); * + * if (ier != 0) ... A is singular * + *----------------------------------------------------------------* + * DenseFactor performs the LU factorization of the N by N dense * + * matrix A. This is done using standard Gaussian elimination * + * with partial pivoting. * + * * + * A successful LU factorization leaves the matrix A and the * + * pivot array p with the following information: * + * * + * (1) p[k] contains the row number of the pivot element chosen * + * at the beginning of elimination step k, k=0, 1, ..., N-1. * + * * + * (2) If the unique LU factorization of A is given by PA = LU, * + * where P is a permutation matrix, L is a lower triangular * + * matrix with all 1's on the diagonal, and U is an upper * + * triangular matrix, then the upper triangular part of A * + * (including its diagonal) contains U and the strictly lower * + * triangular part of A contains the multipliers, I-L. * + * * + * DenseFactor returns 0 if successful. Otherwise it encountered * + * a zero diagonal element during the factorization. In this case * + * it returns the column index (numbered from one) at which * + * it encountered the zero. * + * * + ******************************************************************/ + +integer DenseFactor(DenseMat A, integer *p); + + +/****************************************************************** + * * + * Function : DenseBacksolve * + * Usage : DenseBacksolve(A, p, b); * + *----------------------------------------------------------------* + * DenseBacksolve solves the N-dimensional system A x = b using * + * the LU factorization in A and the pivot information in p * + * computed in DenseFactor. The solution x is returned in b. This * + * routine cannot fail if the corresponding call to DenseFactor * + * did not fail. * + * * + ******************************************************************/ + +void DenseBacksolve(DenseMat A, integer *p, N_Vector b); + + +/****************************************************************** + * * + * Function : DenseZero * + * Usage : DenseZero(A); * + *----------------------------------------------------------------* + * DenseZero sets all the elements of the N by N matrix A to 0.0. * + * * + ******************************************************************/ + +void DenseZero(DenseMat A); + + +/****************************************************************** + * * + * Function : DenseCopy * + * Usage : DenseCopy(A, B); * + *----------------------------------------------------------------* + * DenseCopy copies the contents of the N by N matrix A into the * + * N by N matrix B. * + * * + ******************************************************************/ + +void DenseCopy(DenseMat A, DenseMat B); + + +/****************************************************************** + * * + * Function: DenseScale * + * Usage : DenseScale(c, A); * + *----------------------------------------------------------------* + * DenseScale scales the elements of the N by N matrix A by the * + * constant c and stores the result back in A. * + * * + ******************************************************************/ + +void DenseScale(real c, DenseMat A); + + +/****************************************************************** + * * + * Function : DenseAddI * + * Usage : DenseAddI(A); * + *----------------------------------------------------------------* + * DenseAddI adds the identity matrix to A and stores the result * + * back in A. * + * * + ******************************************************************/ + +void DenseAddI(DenseMat A); + + +/****************************************************************** + * * + * Function : DenseFreeMat * + * Usage : DenseFreeMat(A); * + *----------------------------------------------------------------* + * DenseFreeMat frees the memory allocated by DenseAllocMat for * + * the N by N matrix A. * + * * + ******************************************************************/ + +void DenseFreeMat(DenseMat A); + + +/****************************************************************** + * * + * Function : DenseFreePiv * + * Usage : DenseFreePiv(p); * + *----------------------------------------------------------------* + * DenseFreePiv frees the memory allocated by DenseAllocPiv for * + * the pivot information array p. * + * * + ******************************************************************/ + +void DenseFreePiv(integer *p); + + +/****************************************************************** + * * + * Function : DensePrint * + * Usage : DensePrint(A); * + *----------------------------------------------------------------* + * This routine prints the N by N dense matrix A to standard * + * output as it would normally appear on paper. It is intended * + * as a debugging tool with small values of N. The elements are * + * printed using the %g option. A blank line is printed before * + * and after the matrix. * + * * + ******************************************************************/ + +void DensePrint(DenseMat A); + + + +/* Functions that use the real ** representation for a dense matrix */ + + +/****************************************************************** + * * + * Function : denalloc * + * Usage : real **a; * + * a = denalloc(n); * + * if (a == NULL) ... memory request failed * + *----------------------------------------------------------------* + * denalloc(n) allocates storage for an n by n dense matrix. It * + * returns a pointer to the newly allocated storage if * + * successful. If the memory request cannot be satisfied, then * + * denalloc returns NULL. The underlying type of the dense matrix * + * returned is real **. If we allocate a dense matrix real **a by * + * a = denalloc(n), then a[j][i] references the (i,j)th element * + * of the matrix a, 0 <= i,j <= n-1, and a[j] is a pointer to the * + * first element in the jth column of a. The location a[0] * + * contains a pointer to n^2 contiguous locations which contain * + * the elements of a. * + * * + ******************************************************************/ + +real **denalloc(integer n); + + +/****************************************************************** + * * + * Function : denallocpiv * + * Usage : integer *pivot; * + * pivot = denallocpiv(n); * + * if (pivot == NULL) ... memory request failed * + *----------------------------------------------------------------* + * denallocpiv(n) allocates an array of n integers. It returns a * + * pointer to the first element in the array if successful. It * + * returns NULL if the memory request could not be satisfied. * + * * + ******************************************************************/ + +integer *denallocpiv(integer n); + + +/****************************************************************** + * * + * Function : gefa * + * Usage : integer ier; * + * ier = gefa(a,n,p); * + * if (ier > 0) ... zero element encountered during * + * the factorization * + *----------------------------------------------------------------* + * gefa(a,n,p) factors the n by n dense matrix a. It overwrites * + * the elements of a with its LU factors and keeps track of the * + * pivot rows chosen in the pivot array p. * + * * + * A successful LU factorization leaves the matrix a and the * + * pivot array p with the following information: * + * * + * (1) p[k] contains the row number of the pivot element chosen * + * at the beginning of elimination step k, k=0, 1, ..., n-1. * + * * + * (2) If the unique LU factorization of a is given by Pa = LU, * + * where P is a permutation matrix, L is a lower triangular * + * matrix with all 1's on the diagonal, and U is an upper * + * triangular matrix, then the upper triangular part of a * + * (including its diagonal) contains U and the strictly lower * + * triangular part of a contains the multipliers, I-L. * + * * + * gefa returns 0 if successful. Otherwise it encountered a zero * + * diagonal element during the factorization. In this case it * + * returns the column index (numbered from one) at which it * + * encountered the zero. * + * * + ******************************************************************/ + +integer gefa(real **a, integer n, integer *p); + + +/****************************************************************** + * * + * Function : gesl * + * Usage : real *b; * + * ier = gefa(a,n,p); * + * if (ier == 0) gesl(a,n,p,b); * + *----------------------------------------------------------------* + * gesl(a,n,p,b) solves the n by n linear system ax = b. It * + * assumes that a has been LU factored and the pivot array p has * + * been set by a successful call to gefa(a,n,p). The solution x * + * is written into the b array. * + * * + ******************************************************************/ + +void gesl(real **a, integer n, integer *p, real *b); + + +/****************************************************************** + * * + * Function : denzero * + * Usage : denzero(a,n); * + *----------------------------------------------------------------* + * denzero(a,n) sets all the elements of the n by n dense matrix * + * a to be 0.0. * + * * + ******************************************************************/ + +void denzero(real **a, integer n); + + +/****************************************************************** + * * + * Function : dencopy * + * Usage : dencopy(a,b,n); * + *----------------------------------------------------------------* + * dencopy(a,b,n) copies the n by n dense matrix a into the * + * n by n dense matrix b. * + * * + ******************************************************************/ + +void dencopy(real **a, real **b, integer n); + + +/****************************************************************** + * * + * Function : denscale * + * Usage : denscale(c,a,n); * + *----------------------------------------------------------------* + * denscale(c,a,n) scales every element in the n by n dense * + * matrix a by c. * + * * + ******************************************************************/ + +void denscale(real c, real **a, integer n); + + +/****************************************************************** + * * + * Function : denaddI * + * Usage : denaddI(a,n); * + *----------------------------------------------------------------* + * denaddI(a,n) increments the n by n dense matrix a by the * + * identity matrix. * + * * + ******************************************************************/ + +void denaddI(real **a, integer n); + + +/****************************************************************** + * * + * Function : denfreepiv * + * Usage : denfreepiv(p); * + *----------------------------------------------------------------* + * denfreepiv(p) frees the pivot array p allocated by * + * denallocpiv. * + * * + ******************************************************************/ + +void denfreepiv(integer *p); + + +/****************************************************************** + * * + * Function : denfree * + * Usage : denfree(a); * + *----------------------------------------------------------------* + * denfree(a) frees the dense matrix a allocated by denalloc. * + * * + ******************************************************************/ + +void denfree(real **a); + + +/****************************************************************** + * * + * Function : denprint * + * Usage : denprint(a,n); * + *----------------------------------------------------------------* + * denprint(a,n) prints the n by n dense matrix a to standard * + * output as it would normally appear on paper. It is intended as * + * a debugging tool with small values of n. The elements are * + * printed using the %g option. A blank line is printed before * + * and after the matrix. * + * * + ******************************************************************/ + +void denprint(real **a, integer n); + + +#endif +#ifdef __cplusplus +} +#endif diff --git a/ext/cvode/include/iterativ.h b/ext/cvode/include/iterativ.h new file mode 100755 index 000000000..1269e0144 --- /dev/null +++ b/ext/cvode/include/iterativ.h @@ -0,0 +1,243 @@ +/****************************************************************** + * * + * File : iterativ.h * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 4 May 1998 * + *----------------------------------------------------------------* + * This header file contains declarations intended for use by * + * generic iterative solvers of Ax = b. The enumeration gives * + * symbolic names for the type of preconditioning to be used. * + * The function type declarations give the prototypes for the * + * functions to be called within an iterative linear solver, that * + * are responsible for * + * multiplying A by a given vector v (ATimesFn), and * + * solving the preconditioner equation Pz = r (PSolveFn). * + * * + ******************************************************************/ + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +#ifndef _iterativ_h +#define _iterativ_h + +#include "llnltyps.h" +#include "nvector.h" + + +/****************************************************************** + * * + * enum : types of preconditioning * + *----------------------------------------------------------------* + * NONE : The iterative linear solver should not use * + * preconditioning. * + * * + * LEFT : The iterative linear solver uses preconditioning on * + * the left only. * + * * + * RIGHT : The iterative linear solver uses preconditioning on * + * the right only. * + * * + * BOTH : The iterative linear solver uses preconditioning on * + * both the left and the right. * + * * + ******************************************************************/ + +enum { NONE, LEFT, RIGHT, BOTH }; + + +/****************************************************************** + * * + * enum : types of Gram-Schmidt routines * + *----------------------------------------------------------------* + * MODIFIED_GS : The iterative solver uses the modified * + * Gram-Schmidt routine ModifiedGS listed in this * + * file. * + * * + * CLASSICAL_GS : The iterative solver uses the classical * + * Gram-Schmidt routine ClassicalGS listed in this * + * file. * + * * + ******************************************************************/ + +enum { MODIFIED_GS, CLASSICAL_GS }; + + +/****************************************************************** + * * + * Type: ATimesFn * + *----------------------------------------------------------------* + * An ATimesFn multiplies Av and stores the result in z. The * + * caller is responsible for allocating memory for the z vector. * + * The parameter A_data is a pointer to any information about A * + * which the function needs in order to do its job. The vector v * + * is unchanged. An ATimesFn returns 0 if successful and a * + * non-zero value if unsuccessful. * + * * + ******************************************************************/ + +typedef int (*ATimesFn)(void *A_data, N_Vector v, N_Vector z); + + +/****************************************************************** + * * + * Type: PSolveFn * + *----------------------------------------------------------------* + * A PSolveFn solves the preconditioner equation Pz = r for the * + * vector z. The caller is responsible for allocating memory for * + * the z vector. The parameter P_data is a pointer to any * + * information about P which the function needs in order to do * + * its job. The parameter lr is input, and indicates whether P * + * is to be taken as the left preconditioner or the right * + * preconditioner: lr = 1 for left and lr = 2 for right. * + * If preconditioning is on one side only, lr can be ignored. * + * The vector r is unchanged. * + * A PSolveFn returns 0 if successful and a non-zero value if * + * unsuccessful. On a failure, a negative return value indicates * + * an unrecoverable condition, while a positive value indicates * + * a recoverable one, in which the calling routine may reattempt * + * the solution after updating preconditioner data. * + * * + ******************************************************************/ + +typedef int (*PSolveFn)(void *P_data, N_Vector r, N_Vector z, int lr); + + +/****************************************************************** + * * + * Function: ModifiedGS * + *----------------------------------------------------------------* + * ModifiedGS performs a modified Gram-Schmidt orthogonalization * + * of the N_Vector v[k] against the p unit N_Vectors at * + * v[k-1], v[k-2], ..., v[k-p]. * + * * + * v is an array of (k+1) N_Vectors v[i], i=0, 1, ..., k. * + * v[k-1], v[k-2], ..., v[k-p] are assumed to have L2-norm * + * equal to 1. * + * * + * h is the output k by k Hessenberg matrix of inner products. * + * This matrix must be allocated row-wise so that the (i,j)th * + * entry is h[i][j]. The inner products (v[i],v[k]), * + * i=i0, i0+1, ..., k-1, are stored at h[i][k-1]. Here * + * i0=MAX(0,k-p). * + * * + * k is the index of the vector in the v array that needs to be * + * orthogonalized against previous vectors in the v array. * + * * + * p is the number of previous vectors in the v array against * + * which v[k] is to be orthogonalized. * + * * + * new_vk_norm is a pointer to memory allocated by the caller to * + * hold the Euclidean norm of the orthogonalized vector v[k]. * + * * + * If (k-p) < 0, then ModifiedGS uses p=k. The orthogonalized * + * v[k] is NOT normalized and is stored over the old v[k]. Once * + * the orthogonalization has been performed, the Euclidean norm * + * of v[k] is stored in (*new_vk_norm). * + * * + * ModifiedGS returns 0 to indicate success. It cannot fail. * + * * + ******************************************************************/ + +int ModifiedGS(N_Vector *v, real **h, int k, int p, real *new_vk_norm); + + +/****************************************************************** + * * + * Function: ClassicalGS * + *----------------------------------------------------------------* + * ClassicalGS performs a classical Gram-Schmidt * + * orthogonalization of the N_Vector v[k] against the p unit * + * N_Vectors at v[k-1], v[k-2], ..., v[k-p]. The parameters v, h, * + * k, p, and new_vk_norm are as described in the documentation * + * for ModifiedGS. * + * * + * temp is an N_Vector which can be used as workspace by the * + * ClassicalGS routine. * + * * + * s is a length k array of reals which can be used as workspace * + * by the ClassicalGS routine. * + * * + * ClassicalGS returns 0 to indicate success. It cannot fail. * + * * + ******************************************************************/ + +int ClassicalGS(N_Vector *v, real **h, int k, int p, real *new_vk_norm, + N_Vector temp, real *s); + + +/****************************************************************** + * * + * Function: QRfact * + *----------------------------------------------------------------* + * QRfact performs a QR factorization of the Hessenberg matrix H. * + * * + * n is the problem size; the matrix H is (n+1) by n. * + * * + * h is the (n+1) by n Hessenberg matrix H to be factored. It is * + * stored row-wise. * + * * + * q is an array of length 2*n containing the Givens rotations * + * computed by this function. A Givens rotation has the form: * + * | c -s | * + * | s c |. * + * The components of the Givens rotations are stored in q as * + * (c, s, c, s, ..., c, s). * + * * + * job is a control flag. If job==0, then a new QR factorization * + * is performed. If job!=0, then it is assumed that the first * + * n-1 columns of h have already been factored and only the last * + * column needs to be updated. * + * * + * QRfact returns 0 if successful. If a zero is encountered on * + * the diagonal of the triangular factor R, then QRfact returns * + * the equation number of the zero entry, where the equations are * + * numbered from 1, not 0. If QRsol is subsequently called in * + * this situation, it will return an error because it could not * + * divide by the zero diagonal entry. * + * * + ******************************************************************/ + +int QRfact(int n, real **h, real *q, int job); + + +/****************************************************************** + * * + * Function: QRsol * + *----------------------------------------------------------------* + * QRsol solves the linear least squares problem * + * * + * min (b - H*x, b - H*x), x in R^n, * + * * + * where H is a Hessenberg matrix, and b is in R^(n+1). * + * It uses the QR factors of H computed by QRfact. * + * * + * n is the problem size; the matrix H is (n+1) by n. * + * * + * h is a matrix (computed by QRfact) containing the upper * + * triangular factor R of the original Hessenberg matrix H. * + * * + * q is an array of length 2*n (computed by QRfact) containing * + * the Givens rotations used to factor H. * + * * + * b is the (n+1)-vector appearing in the least squares problem * + * above. * + * * + * On return, b contains the solution x of the least squares * + * problem, if QRsol was successful. * + * * + * QRsol returns a 0 if successful. Otherwise, a zero was * + * encountered on the diagonal of the triangular factor R. * + * In this case, QRsol returns the equation number (numbered * + * from 1, not 0) of the zero entry. * + * * + ******************************************************************/ + +int QRsol(int n, real **h, real *q, real *b); + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/ext/cvode/include/llnlmath.h b/ext/cvode/include/llnlmath.h new file mode 100755 index 000000000..079ce55b8 --- /dev/null +++ b/ext/cvode/include/llnlmath.h @@ -0,0 +1,121 @@ +/****************************************************************** + * * + * File : llnlmath.h * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 4 May 1998 * + *----------------------------------------------------------------* + * This is the header file for a C math library. The routines * + * listed here work with the type real as defined in llnltyps.h. * + * To do single precision floating point arithmetic, set the type * + * real to be float. To do double precision arithmetic, set the * + * type real to be double. The default implementations for * + * RPowerR and RSqrt call standard math library functions which * + * do double precision arithmetic. If this is unacceptable when * + * real is float, then the user should re-implement these two * + * routines by calling single precision routines available on * + * his/her machine. * + * * + ******************************************************************/ + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +#ifndef _llnlmath_h +#define _llnlmath_h + +#include "llnltyps.h" + + +/****************************************************************** + * * + * Macros : MIN, MAX, ABS, SQR * + *----------------------------------------------------------------* + * MIN(A, B) returns the minimum of A and B. * + * * + * MAX(A, B) returns the maximum of A and B. * + * * + * ABS(A) returns the absolute value of A. * + * * + * SQR(A) returns the square of A. * + * * + ******************************************************************/ +#ifndef MIN +#define MIN(A, B) ((A) < (B) ? (A) : (B)) +#endif + +#ifndef MAX +#define MAX(A, B) ((A) > (B) ? (A) : (B)) +#endif + +#ifndef ABS +#define ABS(A) ((A < 0) ? -(A) : (A)) +#endif + +#ifndef SQR +#define SQR(A) ((A) * (A)) +#endif + +/****************************************************************** + * * + * Function : UnitRoundoff * + * Usage : real uround; * + * uround = UnitRoundoff(); * + *----------------------------------------------------------------* + * UnitRoundoff returns the unit roundoff u for real floating * + * point arithmetic, where u is defined to be the smallest * + * positive real such that 1.0 + u != 1.0. * + * * + ******************************************************************/ + +real UnitRoundoff(void); + + +/****************************************************************** + * * + * Function : RPowerI * + * Usage : int exponent; * + * real base, ans; * + * ans = RPowerI(base,exponent); * + *----------------------------------------------------------------* + * RPowerI returns the value base^exponent, where base is a real * + * and exponent is an int. * + * * + ******************************************************************/ + +real RPowerI(real base, int exponent); + + +/****************************************************************** + * * + * Function : RPowerR * + * Usage : real base, exponent, ans; * + * ans = RPowerR(base,exponent); * + *----------------------------------------------------------------* + * RPowerR returns the value base^exponent, where both base and * + * exponent are reals. If base < 0.0, then RPowerR returns 0.0. * + * * + ******************************************************************/ + +real RPowerR(real base, real exponent); + + +/****************************************************************** + * * + * Function : RSqrt * + * Usage : real sqrt_x; * + * sqrt_x = RSqrt(x); * + *----------------------------------------------------------------* + * RSqrt(x) returns the square root of x. If x < 0.0, then RSqrt * + * returns 0.0. * + * * + ******************************************************************/ + +real RSqrt(real x); + + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/ext/cvode/include/llnltyps.h b/ext/cvode/include/llnltyps.h new file mode 100755 index 000000000..5695625ed --- /dev/null +++ b/ext/cvode/include/llnltyps.h @@ -0,0 +1,131 @@ +/****************************************************************** + * * + * File : llnltyps.h * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 4 May 1998 * + *----------------------------------------------------------------* + * This header file exports three types: real, integer, and boole * + * (short for boolean), as well as the constants TRUE and FALSE. * + * * + * Users should #include "llnltyps.h" in any file that should * + * be easily modifiable to work with different real or integer * + * types and use the exported names real and integer within such * + * a file. The types for real and integer below have been set to * + * double and int, respectively. A user should modify these * + * type declarations as he/she sees fit. For example, if a user * + * wants the work with type float because double precision * + * floating point arithmetic is too expensive on the user's * + * machine, then the definition below should be changed to: * + * * + * typedef float real; * + * * + * Similarly, if a user needs to work with extremely large * + * integers (see the system header file for the limits * + * on type int and long int on your machine), then the user * + * should change the definition below to: * + * * + * typedef long int integer; * + * * + * The constants LLNL_FLOAT, LLNL_DOUBLE, LLNL_INT, LLNL_LONG * + * indicate the underlying types for real and integer. * + * They should be set as follows: * + * * + * (1) #define LLNL_FLOAT 1 * + * #define LLNL_DOUBLE 0 (real is float) * + * * + * (2) #define LLNL_FLOAT 0 * + * #define LLNL_DOUBLE 1 (real is double) * + * * + * (3) #define LLNL_INT 1 * + * #define LLNL_LONG 0 (integer is int) * + * * + * (4) #define LLNL_INT 0 * + * #define LLNL_LONG 1 (integer is long int) * + * * + * Thus the legal types for real are float and double, while * + * the legal types for integer are int and long int. The macro * + * RCONST gives a user a convenient way to define real * + * constants. To use the real constant 1.0, for example, the * + * user should write * + * * + * #define ONE RCONST(1.0) * + * * + * If real is double, then RCONST(1.0) expands to 1.0. If real is * + * float, then RCONST(1.0) expands to 1.0F. There is never a * + * need to explicitly cast 1.0 to (real). * + * * + ******************************************************************/ + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +#ifndef _llnltyps_h +#define _llnltyps_h + + +/****************************************************************** + * * + * Types : real, integer * + *----------------------------------------------------------------* + * The types real and integer are currently set to double and * + * int, respectively. See the documentation at the top for * + * usage details and a description of associated constants and * + * macros. * + * * + ******************************************************************/ + +typedef double real; + +/* typedef long integer; dgg */ +typedef int integer; + +#define LLNL_FLOAT 0 +#define LLNL_DOUBLE 1 + +#define LLNL_INT 1 +#define LLNL_LONG 0 + +#if LLNL_FLOAT + +#define RCONST(x) x##F + +#elif LLNL_DOUBLE + +#define RCONST(x) x + +#endif + + +/****************************************************************** + * * + * Type : boole * + * Constants : FALSE, TRUE * + *----------------------------------------------------------------* + * ANSI C does not have a built-in boolean type. Below is the * + * definition for a new type boole. The advantage of using the * + * name boole (instead of int) is an increase in code readability.* + * It allows the programmer to make a distinction between int and * + * boolean data. Variables of type boole are intended to have only* + * the two values FALSE and TRUE which are defined below to be * + * equal to 0 and 1, respectively. * + * * + ******************************************************************/ + +#ifndef boole +#define boole int +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/ext/cvode/include/nvector.h b/ext/cvode/include/nvector.h new file mode 100755 index 000000000..19e4f3aa3 --- /dev/null +++ b/ext/cvode/include/nvector.h @@ -0,0 +1,535 @@ +/**************************************************************** + * * + * File : nvector.h * + * Programmers : Scott D. Cohen, Alan C. Hindmarsh, and * + * : Allan G. Taylor, LLNL * + * Version of : 17 December 1999 * + *--------------------------------------------------------------* + * * + * This is the header file for a generic serial NVECTOR package.* + * It exports the type N_Vector. * + * * + * Part I of this file contains declarations which are specific * + * to the particular machine environment in which this version * + * of the vector package is to be used. This includes the * + * typedef for the type N_Vector, as well as accessor macros * + * that allow the user to use efficiently the type N_Vector * + * without making explicit references to its underlying * + * representation. The underlying type of N_Vector will always * + * be some pointer type. * + * * + * Part II of this file contains the prototypes for the vector * + * kernels which operate on the type N_Vector. These prototypes * + * are fixed for all implementations of the vector package. The * + * definitions of the types real and integer are in the header * + * file llnltyps.h and these may be changed according to the * + * user's needs. The llnltyps.h file also contains the * + * definition for the type boole (short for boolean) that is the* + * return type for the routine N_VInvTest. * + * * + * Important Note: N_Vector arguments to arithmetic kernels * + * need not be distinct. Thus, for example, the call * + * N_VLinearSum(a,x,b,y,y); y <- ax+by * + * is legal. * + * * + * This version of nvector.h is for the ordinary sequential * + * machine environment. In the documentation given below, N is * + * the length of all N_Vector parameters and x[i] denotes the * + * ith component of the N_Vector x, where 0 <= i <= N-1. * + * * + ****************************************************************/ + + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif +#ifndef nvector_h +#define nvector_h + + +#include "llnltyps.h" + + +/* Part I: Machine Environment-Dependent Declarations */ + + +/* Environment: Sequential */ + + typedef struct { + int dummy; /* dummy element */ +} *machEnvType; /* dummy machEnvType definition */ + + +/*************************************************************** + * * + * Type: N_Vector * + *-------------------------------------------------------------* + * The type N_Vector is an abstract vector type. The fields of * + * its concrete representation should not be accessed * + * directly, but rather through the macros given below. * + * * + * A user may assume that the N components of an N_Vector * + * are stored contiguously. A pointer to the first component * + * can be obtained via the macro N_VDATA. * + * * + ***************************************************************/ + +typedef struct { + integer length; + real *data; +} *N_Vector; + + +/*************************************************************** + * * + * Macros: N_VMAKE, N_VDISPOSE, N_VDATA, N_VLENGTH, N_VIth * + *-------------------------------------------------------------* + * In the descriptions below, the following user * + * declarations are assumed: * + * * + * N_Vector v; real *v_data, r; integer v_len, i; * + * * + * (1) N_VMAKE, N_VDISPOSE * + * * + * These companion routines are used to create and * + * destroy an N_Vector with a component array v_data * + * allocated by the user. * + * * + * The call N_VMAKE(v, v_data, v_len) makes v an * + * N_Vector with component array v_data and length v_len. * + * N_VMAKE stores the pointer v_data so that changes * + * made by the user to the elements of v_data are * + * simultaneously reflected in v. There is no copying of * + * elements. * + * * + * The call N_VDISPOSE(v) frees all memory associated * + * with v except for its component array. This memory was * + * allocated by the user and, therefore, should be * + * deallocated by the user. * + * * + * (2) N_VDATA, N_VLENGTH * + * * + * These routines give individual access to the parts of * + * an N_Vector. * + * * + * The assignment v_data=N_VDATA(v) sets v_data to be * + * a pointer to the first component of v. The assignment * + * N_VDATA(v)=v_data sets the component array of v to * + * be v_data by storing the pointer v_data. * + * * + * The assignment v_len=N_VLENGTH(v) sets v_len to be * + * the length of v. The call N_VLENGTH(v)=len_v sets * + * the length of v to be len_v. * + * * + * (3) N_VIth * + * * + * In the following description, the components of an * + * N_Vector are numbered 0..N-1, where N is the length of * + * v. * + * * + * The assignment r=N_VIth(v,i) sets r to be the value of * + * the ith component of v. The assignment N_VIth(v,i)=r * + * sets the value of the ith component of v to be r. * + * * + * Notes.. * + * * + * Users who use the macros (1) must #include * + * since these macros expand to calls to malloc and free. * + * * + * When looping over the components of an N_Vector v, it is * + * more efficient to first obtain the component array via * + * v_data=N_VDATA(v) and then access v_data[i] within the * + * loop than it is to use N_VIth(v,i) within the loop. * + * * + * N_VMAKE and N_VDISPOSE are similar to N_VNew and N_VFree. * + * The difference is one of responsibility for component * + * memory allocation and deallocation. N_VNew allocates memory * + * for the N_Vector components and N_VFree frees the component * + * memory allocated by N_VNew. For N_VMAKE and N_VDISPOSE, the * + * component memory is allocated and freed by the user of * + * this package. * + * * + ***************************************************************/ + +#define N_VMAKE(v, v_data, v_len) v = (N_Vector) malloc(sizeof(*v)); \ + v->data = v_data; \ + v->length = v_len + +#define N_VDISPOSE(v) free(v) + +#define N_VDATA(v) (v->data) + +#define N_VLENGTH(v) (v->length) + +#define N_VIth(v,i) ((v->data)[i]) + + +/* Part II: N_Vector Kernel Prototypes (Machine Environment-Independent) */ + + +/*************************************************************** + * * + * Memory Allocation and Deallocation: N_VNew, N_VFree * + * * + ***************************************************************/ + + +/*************************************************************** + * * + * Function : N_VNew * + * Usage : x = N_VNew(N, machEnv); * + *-------------------------------------------------------------* + * * + * Returns a new N_Vector of length N. The parameter machEnv * + * is a pointer to machine environment-specific information. * + * It is ignored in the sequential machine environment and the * + * user in this environment should simply pass NULL for this * + * argument. If there is not enough memory for a new N_Vector, * + * then N_VNew returns NULL. * + * * + ***************************************************************/ + +N_Vector N_VNew(integer n, void *machEnv); + + +/*************************************************************** + * * + * Function : N_VFree * + * Usage : N_VFree(x); * + *-------------------------------------------------------------* + * * + * Frees the N_Vector x. It is illegal to use x after the call * + * N_VFree(x). * + * * + ***************************************************************/ + +void N_VFree(N_Vector x); + + +/*************************************************************** + * * + * N_Vector Arithmetic: N_VLinearSum, N_VConst, N_VProd, * + * N_VDiv, N_VScale, N_VAbs, N_VInv, * + * N_VAddConst * + * * + ***************************************************************/ + + +/*************************************************************** + * * + * Function : N_VLinearSum * + * Operation : z = a x + b y * + * * + ***************************************************************/ + +void N_VLinearSum(real a, N_Vector x, real b, N_Vector y, N_Vector z); + + +/*************************************************************** + * * + * Function : N_VConst * + * Operation : z[i] = c for i=0, 1, ..., N-1 * + * * + ***************************************************************/ + +void N_VConst(real c, N_Vector z); + + +/*************************************************************** + * * + * Function : N_VProd * + * Operation : z[i] = x[i] * y[i] for i=0, 1, ..., N-1 * + * * + ***************************************************************/ + +void N_VProd(N_Vector x, N_Vector y, N_Vector z); + + +/*************************************************************** + * * + * Function : N_VDiv * + * Operation : z[i] = x[i] / y[i] for i=0, 1, ..., N-1 * + * * + ***************************************************************/ + +void N_VDiv(N_Vector x, N_Vector y, N_Vector z); + + +/*************************************************************** + * * + * Function : N_VScale * + * Operation : z = c x * + * * + ***************************************************************/ + +void N_VScale(real c, N_Vector x, N_Vector z); + + +/*************************************************************** + * * + * Function : N_VAbs * + * Operation : z[i] = |x[i]|, for i=0, 1, ..., N-1 * + * * + ***************************************************************/ + +void N_VAbs(N_Vector x, N_Vector z); + + +/*************************************************************** + * * + * Function : N_VInv * + * Operation : z[i] = 1.0 / x[i] for i = 0, 1, ..., N-1 * + *-------------------------------------------------------------* + * * + * This routine does not check for division by 0. It should be * + * called only with an N_Vector x which is guaranteed to have * + * all non-zero components. * + * * + ***************************************************************/ + +void N_VInv(N_Vector x, N_Vector z); + + +/*************************************************************** + * * + * Function : N_VAddConst * + * Operation : z[i] = x[i] + b for i = 0, 1, ..., N-1 * + * * + ***************************************************************/ + +void N_VAddConst(N_Vector x, real b, N_Vector z); + + +/*************************************************************** + * * + * N_Vector Measures: N_VDotProd, N_VMaxNorm, VWrmsNorm, * + * N_VMin, N_VWL2Norm, N_VL1Norm * + * * + * * + ***************************************************************/ + + +/*************************************************************** + * * + * Function : N_VDotProd * + * Usage : dotprod = N_VDotProd(x, y); * + *-------------------------------------------------------------* + * * + * Returns the value of the ordinary dot product of x and y: * + * * + * -> sum (i=0 to N-1) {x[i] * y[i]} * + * * + * Returns 0.0 if N <= 0. * + * * + ***************************************************************/ + +real N_VDotProd(N_Vector x, N_Vector y); + + +/*************************************************************** + * * + * Function : N_VMaxNorm * + * Usage : maxnorm = N_VMaxNorm(x); * + *-------------------------------------------------------------* + * * + * Returns the maximum norm of x: * + * * + * -> max (i=0 to N-1) |x[i]| * + * * + * Returns 0.0 if N <= 0. * + * * + ***************************************************************/ + +real N_VMaxNorm(N_Vector x); + + +/*************************************************************** + * * + * Function : N_VWrmsNorm * + * Usage : wrmsnorm = N_VWrmsNorm(x, w); * + *-------------------------------------------------------------* + * * + * Returns the weighted root mean square norm of x with * + * weight vector w: * + * * + * -> sqrt [(sum (i=0 to N-1) {(x[i] * w[i])^2}) / N] * + * * + * Returns 0.0 if N <= 0. * + * * + ***************************************************************/ + +real N_VWrmsNorm(N_Vector x, N_Vector w); + + +/*************************************************************** + * * + * Function : N_VMin * + * Usage : min = N_VMin(x); * + *-------------------------------------------------------------* + * * + * Returns min x[i] if N > 0 and returns 0.0 if N <= 0. * + * i * + * * + ***************************************************************/ + +real N_VMin(N_Vector x); + + +/*************************************************************** + * * + * Function : N_VWL2Norm * + * Usage : wl2norm = N_VWL2Norm(x, w); * + *-------------------------------------------------------------* + * * + * Returns the weighted Euclidean L2 norm of x with * + * weight vector w: * + * * + * -> sqrt [(sum (i=0 to N-1) {(x[i] * w[i])^2}) ] * + * * + * Returns 0.0 if N <= 0. * + * * + ***************************************************************/ + +real N_VWL2Norm(N_Vector x, N_Vector w); + + +/*************************************************************** + * * + * Function : N_VL1Norm * + * Usage : l1norm = N_VL1Norm(x); * + *-------------------------------------------------------------* + * * + * Returns sum of ABS(x[i]) if N > 0 and returns 0.0 if N <= 0.* + * i * + * + * i.e., calculates and returns the L1 norm of x * + * * + ***************************************************************/ + +real N_VL1Norm(N_Vector x); + + +/*************************************************************** + * * + * Miscellaneous : N_VOneMask, N_VCompare, N_VInvTest, * + * N_VConstrProdPos, N_VConstrMask, and N_VMinQuotient * + * * + ***************************************************************/ + +/*************************************************************** + * * + * Function : N_VOneMask * + * Operation : x[i] = 1.0 if |x[i]| != 0. i = 0, 1, ..., N-1 * + * 0.0 otherwise * + * * + ***************************************************************/ + +void N_VOneMask(N_Vector x); + + +/*************************************************************** + * * + * Function : N_VCompare * + * Operation : z[i] = 1.0 if |x[i]| >= c i = 0, 1, ..., N-1 * + * 0.0 otherwise * + * * + ***************************************************************/ + + +void N_VCompare(real c, N_Vector x, N_Vector z); + + +/*************************************************************** + * * + * Function : N_VInvTest * + * Operation : z[i] = 1.0 / x[i] with a test for x[i]==0.0 * + * before inverting x[i]. * + *-------------------------------------------------------------* + * * + * This routine returns TRUE if all components of x are * + * non-zero (successful inversion) and returns FALSE * + * otherwise. * + * * + ***************************************************************/ + +boole N_VInvTest(N_Vector x, N_Vector z); + + +/*************************************************************** + * * + * Function : N_VConstrProdPos * + * Usage : booltest = N_VConstrProdPos(c,x); * + *-------------------------------------------------------------* + * * + * Returns a boolean FALSE if some c[i]!=0.0 and x[i]*c[i]<=0.0* + * and TRUE otherwise * + * * + * This routine is used for constraint checking. * + * * + ***************************************************************/ + +boole N_VConstrProdPos(N_Vector c, N_Vector x); + + +/*************************************************************** + * * + * Function : N_VConstrMask * + * Operation : m[i] = 1.0 , if constraint test fails, for i * + * m[i] = 0.0 , if constraint test passes, for i * + * where the constraint tests parallel those * + * of routine N_VConstrProdPos * + *-------------------------------------------------------------* + * This routine returns a boole FALSE if any element failed * + * the constraint test, TRUE if all passed. It also creates a * + * mask vector, m, which has all elements whose corresponding * + * constraint test failed, marked with 1.0, passed with 0.0 * + * This routine is specialized in that it is used only for * + * constraint checking. * + ***************************************************************/ + +boole N_VConstrMask(N_Vector c, N_Vector x, N_Vector m); + + +/*************************************************************** + * * + * Function : N_VMinQuotient * + * Operation : minq = min ( num[i]/denom[i]) over all i such * + * that denom[i] != 0. * + *-------------------------------------------------------------* + * * + * This routine returns the minimum of the quotients obtained * + * by term-wise dividing num[i] by denom[i]. A zero element * + * in denom will be skipped. If no such quotients are found, * + * then the large value 1.e99 is returned. * + * * + ***************************************************************/ + +real N_VMinQuotient(N_Vector num, N_Vector denom); + + +/*************************************************************** + * * + * Debugging Tools : N_VPrint * + * * + ***************************************************************/ + +/*************************************************************** + * * + * Function : N_VPrint * + * Usage : N_VPrint(x); * + *-------------------------------------------------------------* + * * + * Prints the N_Vector x to stdout. Each component of x is * + * printed on a separate line using the %g specification. This * + * routine is provided as an aid in debugging code which uses * + * this vector package. * + * * + ***************************************************************/ + +void N_VPrint(N_Vector x); + + +#endif +#ifdef __cplusplus +} +#endif diff --git a/ext/cvode/include/spgmr.h b/ext/cvode/include/spgmr.h new file mode 100755 index 000000000..fb3d26542 --- /dev/null +++ b/ext/cvode/include/spgmr.h @@ -0,0 +1,295 @@ +/***************************************************************************** + * File : spgmr.h * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 17 December 1999 * + *---------------------------------------------------------------------------* + * This is the header file for the implementation of SPGMR Krylov * + * iterative linear solver. The SPGMR algorithm is based on the Scaled * + * Preconditioned GMRES (Generalized Minimal Residual) method. * + * * + * The SPGMR algorithm solves a N by N linear system A x = b. * + * Preconditioning is allowed on the left, right, or both. * + * Scaling is allowed on both sides, and restarts are also allowed. * + * We denote the preconditioner and scaling matrices as follows: * + * P1 = left preconditioner * + * P2 = right preconditioner * + * S1 = diagonal matrix of scale factors for P1-inverse b * + * S2 = diagonal matrix of scale factors for P2 x * + * The matrices A, P1, and P2 are not required explicitly; only routines * + * that provide A, P1-inverse, and P2-inverse as operators are required. * + * * + * In this notation, SPGMR applies the underlying GMRES method to the * + * equivalent transformed system * + * Abar xbar = bbar , where * + * Abar = S1 (P1-inverse) A (P2-inverse) (S2-inverse) , * + * bbar = S1 (P1-inverse) b , and xbar = S2 P2 x . * + * * + * The scaling matrices must be chosen so that vectors S1 P1-inverse b * + * and S2 P2 x have dimensionless components. If preconditioning is done * + * on the left only (P2 = I), by a matrix P, then S2 must be a scaling * + * for x, while S1 is a scaling for P-inverse b, and so may also be taken * + * as a scaling for x. Similarly, if preconditioning is done on the * + * right only (P1 = I, P2 = P), then S1 must be a scaling for b, while S2 * + * is a scaling for P x, and may also be taken as a scaling for b. * + * * + * The stopping test for the SPGMR iterations is on the L2 norm of the * + * scaled preconditioned residual: * + * || bbar - Abar xbar ||_2 < delta * + * with an input test constant delta. * + * * + * The usage of this SPGMR solver involves supplying two routines and * + * making three calls. The user-supplied routines are * + * atimes (A_data, x, y) to compute the product y = A x, given x, * + * and * + * psolve (P_data, x, y, lr) to solve P1 x = y or P2 x = y for x, given y.* + * The three user calls are: * + * mem = SpgmrMalloc(N, lmax, machEnv); * + * to initialize memory, * + * flag = SpgmrSolve(mem,A_data,x,b,...,P_data,s1,s2,atimes,psolve,...); * + * to solve the system, and * + * SpgmrFree(mem); * + * to free the memory created by SpgmrMalloc. * + * Complete details for specifying atimes and psolve and for the usage calls * + * are given in the paragraphs below and in iterativ.h. * + * * + *****************************************************************************/ + +#ifdef __cplusplus /* wrapper to enable C++ usage */ +extern "C" { +#endif + +#ifndef _spgmr_h +#define _spgmr_h + +#include "llnltyps.h" +#include "iterativ.h" +#include "nvector.h" + + +/****************************************************************** + * * + * Types: SpgmrMemRec, SpgmrMem * + *----------------------------------------------------------------* + * SpgmrMem is a pointer to an SpgmrMemRec which contains * + * the memory needed by SpgmrSolve. The SpgmrMalloc routine * + * returns a pointer of type SpgmrMem which should then be passed * + * in subsequent calls to SpgmrSolve. The SpgmrFree routine frees * + * the memory allocated by SpgmrMalloc. * + * * + * N is the linear system size. * + * * + * l_max is the maximum Krylov dimension that SpgmrSolve will be * + * permitted to use. * + * * + * V is the array of Krylov basis vectors v_1, ..., v_(l_max+1), * + * stored in V[0], ..., V[l_max], where l_max is the second * + * parameter to SpgmrMalloc. Each v_i is a length N vector of * + * type N_Vector. (N is the first parameter to SpgmrMalloc and * + * represents the size of the linear system.) * + * * + * Hes is the (l_max+1) x l_max Hessenberg matrix. It is stored * + * row-wise so that the (i,j)th element is given by Hes[i][j]. * + * * + * givens is a length 2*l_max array which represents the * + * Givens rotation matrices that arise in the algorithm. The * + * Givens rotation matrices F_0, F_1, ..., F_j, where F_i is * + * * + * 1 * + * 1 * + * c_i -s_i <--- row i * + * s_i c_i * + * 1 * + * 1 * + * * + * are represented in the givens vector as * + * givens[0]=c_0, givens[1]=s_0, givens[2]=c_1, givens[3]=s_1, * + * ..., givens[2j]=c_j, givens[2j+1]=s_j. * + * * + * xcor is a length N vector (type N_Vector) which holds the * + * scaled, preconditioned correction to the initial guess. * + * * + * yg is a length (l_max+1) array of reals used to hold "short" * + * vectors (e.g. y and g). * + * * + * vtemp is a length N vector (type N_Vector) used as temporary * + * vector storage during calculations. * + * * + ******************************************************************/ + +typedef struct { + + integer N; + int l_max; + + N_Vector *V; + real **Hes; + real *givens; + N_Vector xcor; + real *yg; + N_Vector vtemp; + +} SpgmrMemRec, *SpgmrMem; + + +/****************************************************************** + * * + * Function : SpgmrMalloc * + *----------------------------------------------------------------* + * SpgmrMalloc allocates the memory used by SpgmrSolve. It * + * returns a pointer of type SpgmrMem which the user of the * + * SPGMR package should pass to SpgmrSolve. The parameter N * + * is the size of the system to be solved by SpgmrSolve and l_max * + * is the maximum Krylov dimension that SpgmrSolve will be * + * permitted to use. The parameter machEnv is a pointer to * + * machine environment-specific information. Pass NULL in the * + * ordinary sequential case (see nvector.h). This routine returns * + * NULL if there is a memory request failure. * + * * + ******************************************************************/ + +SpgmrMem SpgmrMalloc(integer N, int l_max, void *machEnv); + + +/****************************************************************** + * * + * Function : SpgmrSolve * + *----------------------------------------------------------------* + * SpgmrSolve solves the linear system Ax = b using the SPGMR * + * method. The return values are given by the symbolic constants * + * below. The first SpgmrSolve parameter is a pointer to memory * + * allocated by a prior call to SpgmrMalloc. The system size N * + * passed in the call to SpgmrMalloc should be the same as the * + * length of all N_Vector arguments passed to SpgmrSolve. * + * * + * mem is the pointer returned by SpgmrMalloc to the structure * + * containing the memory needed by SpgmrSolve. * + * * + * A_data is a pointer to information about the coefficient * + * matrix A. This pointer is passed to the user-supplied function * + * atimes. * + * * + * x is the initial guess x_0 upon entry and the solution * + * N_Vector upon exit with return value SPGMR_SUCCESS or * + * SPGMR_RES_REDUCED. For all other return values, the output x * + * is undefined. * + * * + * b is the right hand side N_Vector. It is undisturbed by this * + * function. * + * * + * pretype is the type of preconditioning to be used. Its * + * legal possible values are enumerated in iterativ.h. These * + * values are NONE=0, LEFT=1, RIGHT=2, and BOTH=3. * + * * + * gstype is the type of Gram-Schmidt orthogonalization to be * + * used. Its legal values are enumerated in iterativ.h. These * + * values are MODIFIED_GS=0 and CLASSICAL_GS=1. * + * * + * delta is the tolerance on the L2 norm of the scaled, * + * preconditioned residual. On return with value SPGMR_SUCCESS, * + * this residual satisfies || s1 P1_inv (b - Ax) ||_2 <= delta. * + * * + * max_restarts is the maximum number of times the algorithm is * + * allowed to restart. * + * * + * P_data is a pointer to preconditioner information. This * + * pointer is passed to the user-supplied function psolve. * + * * + * s1 is an N_Vector of positive scale factors for P1-inv b, where* + * P1 is the left preconditioner. (Not tested for positivity.) * + * Pass NULL if no scaling on P1-inv b is required. * + * * + * s2 is an N_Vector of positive scale factors for P2 x, where * + * P2 is the right preconditioner. (Not tested for positivity.) * + * Pass NULL if no scaling on P2 x is required. * + * * + * atimes is the user-supplied function which performs the * + * operation of multiplying A by a given vector. Its description * + * is given in iterativ.h. * + * * + * psolve is the user-supplied function which solves a * + * preconditioner system Pz = r, where P is P1 or P2. Its full * + * description is given in iterativ.h. The psolve function will * + * not be called if pretype is NONE; in that case, the user * + * should pass NULL for psolve. * + * * + * res_norm is a pointer to the L2 norm of the scaled, * + * preconditioned residual. On return with value SPGMR_SUCCESS or * + * SPGMR_RES_REDUCED, (*res_norm) contains the value * + * || s1 P1_inv (b - Ax) ||_2 for the computed solution x. * + * For all other return values, (*res_norm) is undefined. The * + * caller is responsible for allocating the memory (*res_norm) * + * to be filled in by SpgmrSolve. * + * * + * nli is a pointer to the number of linear iterations done in * + * the execution of SpgmrSolve. The caller is responsible for * + * allocating the memory (*nli) to be filled in by SpgmrSolve. * + * * + * nps is a pointer to the number of calls made to psolve during * + * the execution of SpgmrSolve. The caller is responsible for * + * allocating the memory (*nps) to be filled in by SpgmrSolve. * + * * + * Note.. Repeated calls can be made to SpgmrSolve with varying * + * input arguments. If, however, the problem size N or the * + * maximum Krylov dimension l_max changes, then a call to * + * SpgmrMalloc must be made to obtain new memory for SpgmrSolve * + * to use. * + * * + ******************************************************************/ + + +int SpgmrSolve(SpgmrMem mem, void *A_data, N_Vector x, N_Vector b, + int pretype, int gstype, real delta, int max_restarts, + void *P_data, N_Vector s1, N_Vector s2, ATimesFn atimes, + PSolveFn psolve, real *res_norm, int *nli, int *nps); + + +/* Return values for SpgmrSolve */ + +#define SPGMR_SUCCESS 0 /* Converged */ +#define SPGMR_RES_REDUCED 1 /* Did not converge, but reduced + norm of residual */ +#define SPGMR_CONV_FAIL 2 /* Failed to converge */ +#define SPGMR_QRFACT_FAIL 3 /* QRfact found singular matrix */ +#define SPGMR_PSOLVE_FAIL_REC 4 /* psolve failed recoverably */ +#define SPGMR_MEM_NULL -1 /* mem argument is NULL */ +#define SPGMR_ATIMES_FAIL -2 /* atimes returned failure flag */ +#define SPGMR_PSOLVE_FAIL_UNREC -3 /* psolve failed unrecoverably */ +#define SPGMR_GS_FAIL -4 /* Gram-Schmidt routine + returned failure flag */ +#define SPGMR_QRSOL_FAIL -5 /* QRsol found singular R */ + + +/****************************************************************** + * * + * Function : SpgmrFree * + *----------------------------------------------------------------* + * SpgmrMalloc frees the memory allocated by SpgmrMalloc. It is * + * illegal to use the pointer mem after a call to SpgmrFree. * + * * + ******************************************************************/ + +void SpgmrFree(SpgmrMem mem); + + +/****************************************************************** + * Macro: SPGMR_VTEMP * + * * + *----------------------------------------------------------------* + * This macro provides access to the work vector vtemp in the * + * memory block of the SPGMR module. The argument mem is the * + * memory pointer returned by SpgmrMalloc, of type SpgmrMem, * + * and the macro value is of type N_Vector. * + * On a return from SpgmrSolve with *nli = 0, this vector * + * contains the scaled preconditioned initial residual, * + * s1 * P1_inverse * (b - A x_0). * + ******************************************************************/ + +#define SPGMR_VTEMP(mem) (mem->vtemp) + + + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/ext/cvode/source/band.c b/ext/cvode/source/band.c new file mode 100755 index 000000000..d7386d388 --- /dev/null +++ b/ext/cvode/source/band.c @@ -0,0 +1,356 @@ +/****************************************************************** + * * + * File : band.c * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 25 February 2000 * + *----------------------------------------------------------------* + * This is the implementation file for a generic BAND linear * + * solver package. * + * * + ******************************************************************/ + +#include +#include +#include "band.h" +#include "llnltyps.h" +#include "nvector.h" +#include "llnlmath.h" + + +#define ZERO RCONST(0.0) +#define ONE RCONST(1.0) + +#define ROW(i,j,smu) (i-j+smu) + + +/* Implementation */ + +BandMat BandAllocMat(integer N, integer mu, integer ml, integer smu) +{ + BandMat A; + + if (N <= 0) return(NULL); + + A = (BandMat) malloc(sizeof *A); + if (A == NULL) return (NULL); + + A->data = bandalloc(N, smu, ml); + if (A->data == NULL) { + free(A); + return(NULL); + } + + A->size = N; + A->mu = mu; + A->ml = ml; + A->smu = smu; + + return(A); +} + + +integer *BandAllocPiv(integer N) +{ + if (N <= 0) return(NULL); + + return((integer *) malloc(N * sizeof(integer))); +} + + +integer BandFactor(BandMat A, integer *p) +{ + return(gbfa(A->data, A->size, A->mu, A->ml, A->smu, p)); +} + + +void BandBacksolve(BandMat A, integer *p, N_Vector b) +{ + gbsl(A->data, A->size, A->smu, A->ml, p, N_VDATA(b)); +} + +void BandZero(BandMat A) +{ + bandzero(A->data, A->size, A->mu, A->ml, A->smu); +} + +void BandCopy(BandMat A, BandMat B, integer copymu, integer copyml) +{ + bandcopy(A->data, B->data, A->size, A->smu, B->smu, copymu, copyml); +} + +void BandScale(real c, BandMat A) +{ + bandscale(c, A->data, A->size, A->mu, A->ml, A->smu); +} + +void BandAddI(BandMat A) +{ + bandaddI(A->data, A->size, A->smu); +} + +void BandFreeMat(BandMat A) +{ + bandfree(A->data); + free(A); +} + +void BandFreePiv(integer *p) +{ + free(p); +} + +void BandPrint(BandMat A) +{ + bandprint(A->data, A->size, A->mu, A->ml, A->smu); +} + + +real **bandalloc(integer n, integer smu, integer ml) +{ + real **a; + integer j, colSize; + + if (n <= 0) return(NULL); + + a = (real **) malloc(n * sizeof(real *)); + if (a == NULL) return(NULL); + + colSize = smu + ml + 1; + a[0] = (real *) malloc(n * colSize * sizeof(real)); + if (a[0] == NULL) { + free(a); + return(NULL); + } + + for (j=1; j < n; j++) a[j] = a[0] + j * colSize; + + return(a); +} + +integer *bandallocpiv(integer n) +{ + if (n <= 0) return(NULL); + + return((integer *) malloc(n * sizeof(integer))); +} + + +integer gbfa(real **a, integer n, integer mu, integer ml, integer smu, + integer *p) +{ + integer c, r, num_rows; + integer i, j, k, l, storage_l, storage_k, last_col_k, last_row_k; + real *a_c, *col_k, *diag_k, *sub_diag_k, *col_j, *kptr, *jptr; + real max, temp, mult, a_kj; + boole swap; + + /* zero out the first smu - mu rows of the rectangular array a */ + + num_rows = smu - mu; + if (num_rows > 0) { + for (c=0; c < n; c++) { + a_c = a[c]; + for (r=0; r < num_rows; r++) { + a_c[r] = ZERO; + } + } + } + + /* k = elimination step number */ + + for (k=0; k < n-1; k++, p++) { + + col_k = a[k]; + diag_k = col_k + smu; + sub_diag_k = diag_k + 1; + last_row_k = MIN(n-1,k+ml); + + /* find l = pivot row number */ + + l=k; + max = ABS(*diag_k); + for (i=k+1, kptr=sub_diag_k; i <= last_row_k; i++, kptr++) { + if (ABS(*kptr) > max) { + l=i; + max = ABS(*kptr); + } + } + storage_l = ROW(l, k, smu); + *p = l; + + /* check for zero pivot element */ + + if (col_k[storage_l] == ZERO) return(k+1); + + /* swap a(l,k) and a(k,k) if necessary */ + + if ( (swap = (l != k) )) { + temp = col_k[storage_l]; + col_k[storage_l] = *diag_k; + *diag_k = temp; + } + + /* Scale the elements below the diagonal in */ + /* column k by -1.0 / a(k,k). After the above swap, */ + /* a(k,k) holds the pivot element. This scaling */ + /* stores the pivot row multipliers -a(i,k)/a(k,k) */ + /* in a(i,k), i=k+1, ..., MIN(n-1,k+ml). */ + + mult = -ONE / (*diag_k); + for (i=k+1, kptr = sub_diag_k; i <= last_row_k; i++, kptr++) + (*kptr) *= mult; + + /* row_i = row_i - [a(i,k)/a(k,k)] row_k, i=k+1, ..., MIN(n-1,k+ml) */ + /* row k is the pivot row after swapping with row l. */ + /* The computation is done one column at a time, */ + /* column j=k+1, ..., MIN(k+smu,n-1). */ + + last_col_k = MIN(k+smu,n-1); + for (j=k+1; j <= last_col_k; j++) { + + col_j = a[j]; + storage_l = ROW(l,j,smu); + storage_k = ROW(k,j,smu); + a_kj = col_j[storage_l]; + + /* Swap the elements a(k,j) and a(k,l) if l!=k. */ + + if (swap) { + col_j[storage_l] = col_j[storage_k]; + col_j[storage_k] = a_kj; + } + + /* a(i,j) = a(i,j) - [a(i,k)/a(k,k)]*a(k,j) */ + /* a_kj = a(k,j), *kptr = - a(i,k)/a(k,k), *jptr = a(i,j) */ + + if (a_kj != ZERO) { + for (i=k+1, kptr=sub_diag_k, jptr=col_j+ROW(k+1,j,smu); + i <= last_row_k; + i++, kptr++, jptr++) + (*jptr) += a_kj * (*kptr); + } + } + } + + /* set the last pivot row to be n-1 and check for a zero pivot */ + + *p = n-1; + if (a[n-1][smu] == ZERO) return(n); + + /* return 0 to indicate success */ + + return(0); +} + +void gbsl(real **a, integer n, integer smu, integer ml, integer *p, + real *b) +{ + integer k, l, i, first_row_k, last_row_k; + real mult, *diag_k; + + /* Solve Ly = Pb, store solution y in b */ + + for (k=0; k < n-1; k++) { + l = p[k]; + mult = b[l]; + if (l != k) { + b[l] = b[k]; + b[k] = mult; + } + diag_k = a[k]+smu; + last_row_k = MIN(n-1,k+ml); + for (i=k+1; i <= last_row_k; i++) + b[i] += mult * diag_k[i-k]; + } + + /* Solve Ux = y, store solution x in b */ + + for (k=n-1; k >= 0; k--) { + diag_k = a[k]+smu; + first_row_k = MAX(0,k-smu); + b[k] /= (*diag_k); + mult = -b[k]; + for (i=first_row_k; i <= k-1; i++) + b[i] += mult*diag_k[i-k]; + } +} + +void bandzero(real **a, integer n, integer mu, integer ml, integer smu) +{ + integer i, j, colSize; + real *col_j; + + colSize = mu + ml + 1; + for (j=0; j < n; j++) { + col_j = a[j]+smu-mu; + for (i=0; i < colSize; i++) + col_j[i] = ZERO; + } +} + +void bandcopy(real **a, real **b, integer n, integer a_smu, integer b_smu, + integer copymu, integer copyml) +{ + integer i, j, copySize; + real *a_col_j, *b_col_j; + + copySize = copymu + copyml + 1; + + for (j=0; j < n; j++) { + a_col_j = a[j]+a_smu-copymu; + b_col_j = b[j]+b_smu-copymu; + for (i=0; i < copySize; i++) + b_col_j[i] = a_col_j[i]; + } +} + +void bandscale(real c, real **a, integer n, integer mu, integer ml, + integer smu) +{ + integer i, j, colSize; + real *col_j; + + colSize = mu + ml + 1; + + for(j=0; j < n; j++) { + col_j = a[j]+smu-mu; + for (i=0; i < colSize; i++) + col_j[i] *= c; + } +} + +void bandaddI(real **a, integer n, integer smu) +{ + integer j; + + for(j=0; j < n; j++) + a[j][smu] += ONE; +} + +void bandfreepiv(integer *p) +{ + free(p); +} + +void bandfree(real **a) +{ + free(a[0]); + free(a); +} + +void bandprint(real **a, integer n, integer mu, integer ml, integer smu) +{ + integer i, j, start, finish; + + printf("\n"); + for (i=0; i < n; i++) { + start = MAX(0,i-ml); + finish = MIN(n-1,i+mu); + for (j=0; j < start; j++) printf("%10s",""); + for (j=start; j <= finish; j++) { + printf("%10g", a[j][i-j+smu]); + } + printf("\n"); + } + printf("\n"); +} diff --git a/ext/cvode/source/cvband.c b/ext/cvode/source/cvband.c new file mode 100755 index 000000000..f3fd3fd7f --- /dev/null +++ b/ext/cvode/source/cvband.c @@ -0,0 +1,415 @@ +/****************************************************************** + * * + * File : cvband.c * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 24 February 2000 * + *----------------------------------------------------------------* + * This is the implementation file for the CVODE band linear * + * solver, CVBAND. * + * * + ******************************************************************/ + + +#include +#include +#include "cvband.h" +#include "cvode.h" +#include "band.h" +#include "llnltyps.h" +#include "nvector.h" +#include "llnlmath.h" + + +/* Error Messages */ + +#define CVBAND_INIT "CVBandInit-- " + +#define MSG_MEM_FAIL CVBAND_INIT "A memory request failed.\n\n" + +#define MSG_BAD_SIZES_1 CVBAND_INIT "Illegal bandwidth parameter(s) " +#define MSG_BAD_SIZES_2 "ml = %ld, mu = %ld.\n" +#define MSG_BAD_SIZES_3 "Must have 0 <= ml, mu <= N-1=%ld.\n\n" +#define MSG_BAD_SIZES MSG_BAD_SIZES_1 MSG_BAD_SIZES_2 MSG_BAD_SIZES_3 + + +/* Other Constants */ + +#define MIN_INC_MULT RCONST(1000.0) +#define ZERO RCONST(0.0) +#define ONE RCONST(1.0) +#define TWO RCONST(2.0) + + +/****************************************************************** + * * + * Types : CVBandMemRec, CVBandMem * + *----------------------------------------------------------------* + * The type CVBandMem is pointer to a CVBandMemRec. This * + * structure contains CVBand solver-specific data. * + * * + ******************************************************************/ + +typedef struct { + + CVBandJacFn b_jac; /* jac = Jacobian routine to be called */ + + integer b_ml; /* b_ml = lower bandwidth of savedJ */ + + integer b_mu; /* b_mu = upper bandwidth of savedJ */ + + integer b_storage_mu; /* upper bandwith of M = MIN(N-1,b_mu+b_ml) */ + + BandMat b_M; /* M = I - gamma J, gamma = h / l1 */ + + integer *b_pivots; /* pivots = pivot array for PM = LU */ + + BandMat b_savedJ; /* savedJ = old Jacobian */ + + long int b_nstlj; /* nstlj = nst at last Jacobian eval. */ + + long int b_nje; /* nje = no. of calls to jac */ + + void *b_J_data; /* J_data is passed to jac */ + +} CVBandMemRec, *CVBandMem; + + +/* CVBAND linit, lsetup, lsolve, and lfree routines */ + +static int CVBandInit(CVodeMem cv_mem, boole *setupNonNull); + +static int CVBandSetup(CVodeMem cv_mem, int convfail, N_Vector ypred, + N_Vector fpred, boole *jcurPtr, N_Vector vtemp1, + N_Vector vtemp2, N_Vector vtemp3); + +static int CVBandSolve(CVodeMem cv_mem, N_Vector b, N_Vector ycur, + N_Vector fcur); + +static void CVBandFree(CVodeMem cv_mem); + + +/*************** CVBandDQJac ***************************************** + + This routine generates a banded difference quotient approximation to + the Jacobian of f(t,y). It assumes that a band matrix of type + BandMat is stored column-wise, and that elements within each column + are contiguous. This makes it possible to get the address of a column + of J via the macro BAND_COL and to write a simple for loop to set + each of the elements of a column in succession. + +**********************************************************************/ + +void CVBandDQJac(integer N, integer mupper, integer mlower, BandMat J, + RhsFn f, void *f_data, real tn, N_Vector y, + N_Vector fy, N_Vector ewt, real h, real uround, + void *jac_data, long int *nfePtr, N_Vector vtemp1, + N_Vector vtemp2, N_Vector vtemp3) +{ + real fnorm, minInc, inc, inc_inv, srur; + N_Vector ftemp, ytemp; + integer group, i, j, width, ngroups, i1, i2; + real *col_j, *ewt_data, *fy_data, *ftemp_data, *y_data, *ytemp_data; + + /* Rename work vectors for use as temporary values of y and f */ + ftemp = vtemp1; + ytemp = vtemp2; + + /* Obtain pointers to the data for ewt, fy, ftemp, y, ytemp */ + ewt_data = N_VDATA(ewt); + fy_data = N_VDATA(fy); + ftemp_data = N_VDATA(ftemp); + y_data = N_VDATA(y); + ytemp_data = N_VDATA(ytemp); + + /* Load ytemp with y = predicted y vector */ + N_VScale(ONE, y, ytemp); + + /* Set minimum increment based on uround and norm of f */ + srur = RSqrt(uround); + fnorm = N_VWrmsNorm(fy, ewt); + minInc = (fnorm != ZERO) ? + (MIN_INC_MULT * ABS(h) * uround * N * fnorm) : ONE; + + /* Set bandwidth and number of column groups for band differencing */ + width = mlower + mupper + 1; + ngroups = MIN(width, N); + + for (group=1; group <= ngroups; group++) { + + /* Increment all y_j in group */ + for(j=group-1; j < N; j+=width) { + inc = MAX(srur*ABS(y_data[j]), minInc/ewt_data[j]); + ytemp_data[j] += inc; + } + + /* Evaluate f with incremented y */ + f(N, tn, ytemp, ftemp, f_data); + + /* Restore ytemp, then form and load difference quotients */ + for (j=group-1; j < N; j+=width) { + ytemp_data[j] = y_data[j]; + col_j = BAND_COL(J,j); + inc = MAX(srur*ABS(y_data[j]), minInc/ewt_data[j]); + inc_inv = ONE/inc; + i1 = MAX(0, j-mupper); + i2 = MIN(j+mlower, N-1); + for (i=i1; i <= i2; i++) + BAND_COL_ELEM(col_j,i,j) = + inc_inv * (ftemp_data[i] - fy_data[i]); + } + } + + /* Increment counter nfe = *nfePtr */ + *nfePtr += ngroups; +} + + +/* Readability Replacements */ + +#define N (cv_mem->cv_N) +#define lmm (cv_mem->cv_lmm) +#define f (cv_mem->cv_f) +#define f_data (cv_mem->cv_f_data) +#define uround (cv_mem->cv_uround) +#define nst (cv_mem->cv_nst) +#define tn (cv_mem->cv_tn) +#define h (cv_mem->cv_h) +#define gamma (cv_mem->cv_gamma) +#define gammap (cv_mem->cv_gammap) +#define gamrat (cv_mem->cv_gamrat) +#define ewt (cv_mem->cv_ewt) +#define nfe (cv_mem->cv_nfe) +#define errfp (cv_mem->cv_errfp) +#define iopt (cv_mem->cv_iopt) +#define linit (cv_mem->cv_linit) +#define lsetup (cv_mem->cv_lsetup) +#define lsolve (cv_mem->cv_lsolve) +#define lfree (cv_mem->cv_lfree) +#define lmem (cv_mem->cv_lmem) + +#define jac (cvband_mem->b_jac) +#define M (cvband_mem->b_M) +#define mu (cvband_mem->b_mu) +#define ml (cvband_mem->b_ml) +#define storage_mu (cvband_mem->b_storage_mu) +#define pivots (cvband_mem->b_pivots) +#define savedJ (cvband_mem->b_savedJ) +#define nstlj (cvband_mem->b_nstlj) +#define nje (cvband_mem->b_nje) +#define J_data (cvband_mem->b_J_data) + + +/*************** CVBand ********************************************** + + This routine initializes the memory record and sets various function + fields specific to the band linear solver module. CVBand sets the + cv_linit, cv_lsetup, cv_lsolve, and cv_lfree fields in (*cvode_mem) + to be CVBandInit, CVBandSetup, CVBandSolve, and CVBandFree, + respectively. It allocates memory for a structure of type + CVBandMemRec and sets the cv_lmem field in (*cvode_mem) to the + address of this structure. Finally, it sets b_J_data field in the + CVBandMemRec structure to be the input parameter jac_data, b_mu to + be mupper, b_ml to be mlower, and the b_jac field to be: + + (1) the input parameter bjac if bjac != NULL or + + (2) CVBandDQJac if bjac == NULL. + +**********************************************************************/ + +void CVBand(void *cvode_mem, integer mupper, integer mlower, CVBandJacFn bjac, + void *jac_data) +{ + CVodeMem cv_mem; + CVBandMem cvband_mem; + + /* Return immediately if cvode_mem is NULL */ + cv_mem = (CVodeMem) cvode_mem; + if (cv_mem == NULL) return; /* CVode reports this error */ + + /* Set four main function fields in cv_mem */ + linit = CVBandInit; + lsetup = CVBandSetup; + lsolve = CVBandSolve; + lfree = CVBandFree; + + /* Get memory for CVBandMemRec */ + lmem = cvband_mem = (CVBandMem) malloc(sizeof(CVBandMemRec)); + if (cvband_mem == NULL) return; /* CVBandInit reports this error */ + + /* Set Jacobian routine field to user's bjac or CVBandDQJac */ + if (bjac == NULL) { + jac = CVBandDQJac; + } else { + jac = bjac; + } + J_data = jac_data; + + /* Load half-bandwiths in cvband_mem */ + ml = mlower; + mu = mupper; +} + +/*************** CVBandInit ****************************************** + + This routine initializes remaining memory specific to the band + linear solver. If any memory request fails, all memory previously + allocated is freed, and an error message printed, before returning. + +**********************************************************************/ + +static int CVBandInit(CVodeMem cv_mem, boole *setupNonNull) +{ + CVBandMem cvband_mem; + + cvband_mem = (CVBandMem) lmem; + + /* Print error message and return if cvband_mem is NULL */ + if (cvband_mem == NULL) { + fprintf(errfp, MSG_MEM_FAIL); + return(LINIT_ERR); + } + + /* Set flag setupNonNull = TRUE */ + *setupNonNull = TRUE; + + /* Test ml and mu for legality */ + if ((ml < 0) || (mu < 0) || (ml >= N) || (mu >= N)) { + fprintf(errfp, MSG_BAD_SIZES, ml, mu, N-1); + return(LINIT_ERR); + } + + /* Set extended upper half-bandwith for M (required for pivoting) */ + storage_mu = MIN(N-1, mu + ml); + + /* Allocate memory for M, savedJ, and pivot arrays */ + M = BandAllocMat(N, mu, ml, storage_mu); + if (M == NULL) { + fprintf(errfp, MSG_MEM_FAIL); + return(LINIT_ERR); + } + savedJ = BandAllocMat(N, mu, ml, mu); + if (savedJ == NULL) { + fprintf(errfp, MSG_MEM_FAIL); + BandFreeMat(M); + return(LINIT_ERR); + } + pivots = BandAllocPiv(N); + if (pivots == NULL) { + fprintf(errfp, MSG_MEM_FAIL); + BandFreeMat(M); + BandFreeMat(savedJ); + return(LINIT_ERR); + } + + /* Initialize nje and nstlj, and set workspace lengths */ + nje = 0; + if (iopt != NULL) { + iopt[BAND_NJE] = nje; + iopt[BAND_LRW] = N*(storage_mu + mu + 2*ml + 2); + iopt[BAND_LIW] = N; + } + nstlj = 0; + + return(LINIT_OK); +} + +/*************** CVBandSetup ***************************************** + + This routine does the setup operations for the band linear solver. + It makes a decision whether or not to call the Jacobian evaluation + routine based on various state variables, and if not it uses the + saved copy. In any case, it constructs the Newton matrix + M = I - gamma*J, updates counters, and calls the band LU + factorization routine. + +**********************************************************************/ + +static int CVBandSetup(CVodeMem cv_mem, int convfail, N_Vector ypred, + N_Vector fpred, boole *jcurPtr, N_Vector vtemp1, + N_Vector vtemp2, N_Vector vtemp3) +{ + boole jbad, jok; + real dgamma; + integer ier; + CVBandMem cvband_mem; + + cvband_mem = (CVBandMem) lmem; + + /* Use nst, gamma/gammap, and convfail to set J eval. flag jok */ + + dgamma = ABS((gamma/gammap) - ONE); + jbad = (nst == 0) || (nst > nstlj + CVB_MSBJ) || + ((convfail == FAIL_BAD_J) && (dgamma < CVB_DGMAX)) || + (convfail == FAIL_OTHER); + jok = !jbad; + + if (jok) { + /* If jok = TRUE, use saved copy of J */ + *jcurPtr = FALSE; + BandCopy(savedJ, M, mu, ml); + } else { + /* If jok = FALSE, call jac routine for new J value */ + nje++; + if (iopt != NULL) iopt[BAND_NJE] = nje; + nstlj = nst; + *jcurPtr = TRUE; + BandZero(M); + jac(N, mu, ml, M, f, f_data, tn, ypred, fpred, ewt, + h, uround, J_data, &nfe, vtemp1, vtemp2, vtemp3); + BandCopy(M, savedJ, mu, ml); + } + + /* Scale and add I to get M = I - gamma*J */ + BandScale(-gamma, M); + BandAddI(M); + + /* Do LU factorization of M */ + ier = BandFactor(M, pivots); + + /* Return 0 if the LU was complete; otherwise return 1 */ + if (ier > 0) return(1); + return(0); +} + +/*************** CVBandSolve ***************************************** + + This routine handles the solve operation for the band linear solver + by calling the band backsolve routine. The return value is 0. + +**********************************************************************/ + +static int CVBandSolve(CVodeMem cv_mem, N_Vector b, N_Vector ycur, + N_Vector fcur) +{ + CVBandMem cvband_mem; + + cvband_mem = (CVBandMem) lmem; + + BandBacksolve(M, pivots, b); + + /* If BDF, scale the correction to account for change in gamma */ + if ((lmm == BDF) && (gamrat != ONE)) { + N_VScale(TWO/(ONE + gamrat), b, b); + } + + return(0); +} + +/*************** CVBandFree ****************************************** + + This routine frees memory specific to the band linear solver. + +**********************************************************************/ + +static void CVBandFree(CVodeMem cv_mem) +{ + CVBandMem cvband_mem; + + cvband_mem = (CVBandMem) lmem; + + BandFreeMat(M); + BandFreeMat(savedJ); + BandFreePiv(pivots); + free(lmem); +} diff --git a/ext/cvode/source/cvbandpre.c b/ext/cvode/source/cvbandpre.c new file mode 100755 index 000000000..f2ab6d6fe --- /dev/null +++ b/ext/cvode/source/cvbandpre.c @@ -0,0 +1,316 @@ +/****************************************************************** + * * + * File : cvbandpre.c * + * Programmers : Michael Wittman and Alan C. Hindmarsh @ LLNL * + * Version of : 23 March 2000 * + *----------------------------------------------------------------* + * This file contains implementations of the banded difference * + * quotient Jacobian-based preconditioner and solver routines for * + * use with CVSpgmr. * + * * + ******************************************************************/ + +#include "cvbandpre.h" +#include "cvode.h" +#include "llnltyps.h" +#include "nvector.h" +#include "llnlmath.h" +#include "band.h" + +#define MIN_INC_MULT RCONST(1000.0) +#define ZERO RCONST(0.0) +#define ONE RCONST(1.0) + +/* Prototype for difference quotient Jacobian calculation routine */ + +static void CVBandPDQJac(integer N, integer mupper, integer mlower, BandMat J, + RhsFn f, void *f_data, real tn, N_Vector y, + N_Vector fy, N_Vector ewt, real h, real uround, + N_Vector ftemp, N_Vector ytemp); + + +/********************** Malloc and Free Functions **********************/ + +CVBandPreData CVBandPreAlloc(integer N, RhsFn f, void *f_data, + integer mu, integer ml) +{ + CVBandPreData pdata; + integer mup, mlp, storagemu; + + pdata = (CVBandPreData) malloc(sizeof *pdata); /* Allocate data memory */ + if (pdata == NULL) return(NULL); + + /* Load pointers and bandwidths into pdata block. */ + pdata->f = f; + pdata->f_data = f_data; + pdata->mu = mup = MIN( N-1, MAX(0,mu) ); + pdata->ml = mlp = MIN( N-1, MAX(0,ml) ); + + /* Allocate memory for saved banded Jacobian approximation. */ + pdata->savedJ = BandAllocMat(N, mup, mlp, mup); + if (pdata->savedJ == NULL) { + free(pdata); + return(NULL); + } + + /* Allocate memory for banded preconditioner. */ + storagemu = MIN( N-1, mup + mlp); + pdata->savedP = BandAllocMat(N, mup, mlp, storagemu); + if (pdata->savedP == NULL) { + BandFreeMat(pdata->savedJ); + free(pdata); + return(NULL); + } + + /* Allocate memory for pivot array. */ + pdata->pivots = BandAllocPiv(N); + if (pdata->savedJ == NULL) { + BandFreeMat(pdata->savedP); + BandFreeMat(pdata->savedJ); + free(pdata); + return(NULL); + } + + return(pdata); +} + +void CVBandPreFree(CVBandPreData pdata) +{ + BandFreeMat(pdata->savedJ); + BandFreeMat(pdata->savedP); + BandFreePiv(pdata->pivots); + free(pdata); +} + + +/***************** Preconditioner setup and solve functions *******/ + + +/* Readability Replacements */ + +#define f (pdata->f) +#define f_data (pdata->f_data) +#define mu (pdata->mu) +#define ml (pdata->ml) +#define pivots (pdata->pivots) +#define savedJ (pdata->savedJ) +#define savedP (pdata->savedP) + + +/* Preconditioner setup routine CVBandPrecond. */ + +/****************************************************************** + * Together CVBandPrecond and CVBandPSolve use a banded * + * difference quotient Jacobian to create a preconditioner. * + * CVBandPrecond calculates a new J, if necessary, then * + * calculates P = I - gamma*J, and does an LU factorization of P. * + * * + * The parameters of CVBandPrecond are as follows: * + * * + * N is the length of all vector arguments. * + * * + * t is the current value of the independent variable. * + * * + * y is the current value of the dependent variable vector, * + * namely the predicted value of y(t). * + * * + * fy is the vector f(t,y). * + * * + * jok is an input flag indicating whether Jacobian-related * + * data needs to be recomputed, as follows: * + * jok == FALSE means recompute Jacobian-related data * + * from scratch. * + * jok == TRUE means that Jacobian data from the * + * previous Precond call will be reused * + * (with the current value of gamma). * + * A CVBandPrecond call with jok == TRUE should only * + * occur after a call with jok == FALSE. * + * * + * jcurPtr is a pointer to an output integer flag which is * + * set by CVBandPrecond as follows: * + * *jcurPtr = TRUE if Jacobian data was recomputed. * + * *jcurPtr = FALSE if Jacobian data was not recomputed,* + * but saved data was reused. * + * * + * gamma is the scalar appearing in the Newton matrix. * + * * + * ewt is the error weight vector. * + * * + * h is a tentative step size in t. * + * * + * uround is the machine unit roundoff. * + * * + * nfePtr is a pointer to the memory location containing the * + * CVODE problem data nfe = number of calls to f. * + * The routine calls f a total of ml+mu+1 times, so * + * it increments *nfePtr by ml+mu+1. * + * * + * bp_data is a pointer to preconditoner data - the same as the * + * bp_data parameter passed to CVSpgmr. * + * * + * vtemp1, vtemp2, and vtemp3 are pointers to memory allocated * + * for vectors of length N for work space. This * + * routine uses only vtemp1 and vtemp2. * + * * + * * + * The value to be returned by the CVBandPrecond function is * + * 0 if successful, or * + * 1 if the band factorization failed. * + ******************************************************************/ + +int CVBandPrecond(integer N, real t, N_Vector y, N_Vector fy, + boole jok, boole *jcurPtr, real gamma, + N_Vector ewt, real h, real uround, + long int *nfePtr, void *bp_data, + N_Vector vtemp1, N_Vector vtemp2, + N_Vector vtemp3) +{ + integer ier; + CVBandPreData pdata; + + /* Assume matrix and pivots have already been allocated. */ + pdata = (CVBandPreData) bp_data; + + if (jok) { + /* If jok = TRUE, use saved copy of J. */ + *jcurPtr = FALSE; + BandCopy(savedJ, savedP, mu, ml); + } else { + /* If jok = FALSE, call CVBandPDQJac for new J value. */ + *jcurPtr = TRUE; + BandZero(savedJ); + CVBandPDQJac(N, mu, ml, savedJ, f, f_data, t, y, fy, ewt, + h, uround, vtemp1, vtemp2); + BandCopy(savedJ, savedP, mu, ml); + *nfePtr += MIN( N, ml + mu + 1 ); + } + + /* Scale and add I to get savedP = I - gamma*J. */ + BandScale(-gamma, savedP); + BandAddI(savedP); + + /* Do LU factorization of matrix. */ + ier = BandFactor(savedP, pivots); + + /* Return 0 if the LU was complete; otherwise return 1. */ + if (ier > 0) return(1); + return(0); +} + + +/* Preconditioner solve routine CVBandPSolve */ + +/****************************************************************** + * CVBandPSolve solves a linear system P z = r, where P is the * + * matrix computed by CVBandPrecond. * + * * + * The parameters of CVBandPSolve used here are as follows: * + * * + * r is the right-hand side vector of the linear system. * + * * + * bp_data is a pointer to preconditioner data - the same as the * + * bp_data parameter passed to CVSpgmr. * + * * + * z is the output vector computed by CVBandPSolve. * + * * + * The value returned by the CVBandPSolve function is always 0, * + * indicating success. * + * * + ******************************************************************/ + +int CVBandPSolve(integer N, real t, N_Vector y, N_Vector fy, + N_Vector vtemp, real gamma, N_Vector ewt, + real delta, long int *nfePtr, N_Vector r, + int lr, void *bp_data, N_Vector z) +{ + CVBandPreData pdata; + + /* Assume matrix and pivots have already been allocated. */ + pdata = (CVBandPreData) bp_data; + + /* Copy r to z. */ + N_VScale(ONE, r, z); + + /* Do band backsolve on the vector z. */ + BandBacksolve(savedP, pivots, z); + + return(0); +} + + +#undef f +#undef f_data +#undef mu +#undef ml +#undef pivots +#undef savedJ +#undef savedP + + + + +/*************** CVBandPDQJac **************************************** + + This routine generates a banded difference quotient approximation to + the Jacobian of f(t,y). It assumes that a band matrix of type + BandMat is stored column-wise, and that elements within each column + are contiguous. This makes it possible to get the address of a column + of J via the macro BAND_COL and to write a simple for loop to set + each of the elements of a column in succession. + +**********************************************************************/ + +static void CVBandPDQJac(integer N, integer mupper, integer mlower, BandMat J, + RhsFn f, void *f_data, real tn, N_Vector y, + N_Vector fy, N_Vector ewt, real h, real uround, + N_Vector ftemp, N_Vector ytemp) +{ + real fnorm, minInc, inc, inc_inv, srur; + integer group, i, j, width, ngroups, i1, i2; + real *col_j, *ewt_data, *fy_data, *ftemp_data, *y_data, *ytemp_data; + + /* Obtain pointers to the data for ewt, fy, ftemp, y, ytemp. */ + ewt_data = N_VDATA(ewt); + fy_data = N_VDATA(fy); + ftemp_data = N_VDATA(ftemp); + y_data = N_VDATA(y); + ytemp_data = N_VDATA(ytemp); + + /* Load ytemp with y = predicted y vector. */ + N_VScale(ONE, y, ytemp); + + /* Set minimum increment based on uround and norm of f. */ + srur = RSqrt(uround); + fnorm = N_VWrmsNorm(fy, ewt); + minInc = (fnorm != ZERO) ? + (MIN_INC_MULT * ABS(h) * uround * N * fnorm) : ONE; + + /* Set bandwidth and number of column groups for band differencing. */ + width = mlower + mupper + 1; + ngroups = MIN(width, N); + + for (group = 1; group <= ngroups; group++) { + + /* Increment all y_j in group. */ + for(j = group-1; j < N; j += width) { + inc = MAX(srur*ABS(y_data[j]), minInc/ewt_data[j]); + ytemp_data[j] += inc; + } + + /* Evaluate f with incremented y. */ + f(N, tn, ytemp, ftemp, f_data); + + /* Restore ytemp, then form and load difference quotients. */ + for (j = group-1; j < N; j += width) { + ytemp_data[j] = y_data[j]; + col_j = BAND_COL(J,j); + inc = MAX(srur*ABS(y_data[j]), minInc/ewt_data[j]); + inc_inv = ONE/inc; + i1 = MAX(0, j-mupper); + i2 = MIN(j+mlower, N-1); + for (i=i1; i <= i2; i++) + BAND_COL_ELEM(col_j,i,j) = + inc_inv * (ftemp_data[i] - fy_data[i]); + } + } +} diff --git a/ext/cvode/source/cvdense.c b/ext/cvode/source/cvdense.c new file mode 100755 index 000000000..83ed4870d --- /dev/null +++ b/ext/cvode/source/cvdense.c @@ -0,0 +1,372 @@ +/****************************************************************** + * * + * File : cvdense.c * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 25 February 2000 * + *----------------------------------------------------------------* + * This is the implementation file for the CVODE dense linear * + * solver, CVDENSE. * + * * + ******************************************************************/ + + +#include +#include +#include "cvdense.h" +#include "cvode.h" +#include "dense.h" +#include "llnltyps.h" +#include "nvector.h" +#include "llnlmath.h" + + +/* Error Messages */ + +#define CVDENSE_INIT "CVDenseInit-- " + +#define MSG_MEM_FAIL CVDENSE_INIT "A memory request failed.\n\n" + + +/* Other Constants */ + +#define MIN_INC_MULT RCONST(1000.0) +#define ZERO RCONST(0.0) +#define ONE RCONST(1.0) +#define TWO RCONST(2.0) + + +/****************************************************************** + * * + * Types : CVDenseMemRec, CVDenseMem * + *----------------------------------------------------------------* + * The type CVDenseMem is pointer to a CVDenseMemRec. This * + * structure contains CVDense solver-specific data. * + * * + ******************************************************************/ + +typedef struct { + + CVDenseJacFn d_jac; /* jac = Jacobian routine to be called */ + + DenseMat d_M; /* M = I - gamma J, gamma = h / l1 */ + + integer *d_pivots; /* pivots = pivot array for PM = LU */ + + DenseMat d_savedJ; /* savedJ = old Jacobian */ + + long int d_nstlj; /* nstlj = nst at last Jacobian eval. */ + + long int d_nje; /* nje = no. of calls to jac */ + + void *d_J_data; /* J_data is passed to jac */ + +} CVDenseMemRec, *CVDenseMem; + + +/* CVDENSE linit, lsetup, lsolve, and lfree routines */ + +static int CVDenseInit(CVodeMem cv_mem, boole *setupNonNull); + +static int CVDenseSetup(CVodeMem cv_mem, int convfail, N_Vector ypred, + N_Vector fpred, boole *jcurPtr, N_Vector vtemp1, + N_Vector vtemp2, N_Vector vtemp3); + +static int CVDenseSolve(CVodeMem cv_mem, N_Vector b, N_Vector ycur, + N_Vector fcur); + +static void CVDenseFree(CVodeMem cv_mem); + + +/*************** CVDenseDQJac **************************************** + + This routine generates a dense difference quotient approximation to + the Jacobian of f(t,y). It assumes that a dense matrix of type + DenseMat is stored column-wise, and that elements within each column + are contiguous. The address of the jth column of J is obtained via + the macro DENSE_COL and an N_Vector with the jth column as the + component array is created using N_VMAKE and N_VDATA. Finally, the + actual computation of the jth column of the Jacobian is done with a + call to N_VLinearSum. + +**********************************************************************/ + +void CVDenseDQJac(integer N, DenseMat J, RhsFn f, void *f_data, real tn, + N_Vector y, N_Vector fy, N_Vector ewt, real h, real uround, + void *jac_data, long int *nfePtr, N_Vector vtemp1, + N_Vector vtemp2, N_Vector vtemp3) +{ + real fnorm, minInc, inc, inc_inv, yjsaved, srur; + real *y_data, *ewt_data; + N_Vector ftemp, jthCol; + integer j; + + ftemp = vtemp1; /* Rename work vector for use as f vector value */ + + /* Obtain pointers to the data for ewt, y */ + ewt_data = N_VDATA(ewt); + y_data = N_VDATA(y); + + /* Set minimum increment based on uround and norm of f */ + srur = RSqrt(uround); + fnorm = N_VWrmsNorm(fy, ewt); + minInc = (fnorm != ZERO) ? + (MIN_INC_MULT * ABS(h) * uround * N * fnorm) : ONE; + + N_VMAKE(jthCol, y_data, N); /* j loop overwrites this data address */ + + /* This is the only for loop for 0..N-1 in CVODE */ + for (j = 0; j < N; j++) { + + /* Generate the jth col of J(tn,y) */ + + N_VDATA(jthCol) = DENSE_COL(J,j); + yjsaved = y_data[j]; + inc = MAX(srur*ABS(yjsaved), minInc/ewt_data[j]); + y_data[j] += inc; + f(N, tn, y, ftemp, f_data); + inc_inv = ONE/inc; + N_VLinearSum(inc_inv, ftemp, -inc_inv, fy, jthCol); + y_data[j] = yjsaved; + } + + N_VDISPOSE(jthCol); + + /* Increment counter nfe = *nfePtr */ + *nfePtr += N; +} + + +/* Readability Replacements */ + +#define N (cv_mem->cv_N) +#define lmm (cv_mem->cv_lmm) +#define f (cv_mem->cv_f) +#define f_data (cv_mem->cv_f_data) +#define uround (cv_mem->cv_uround) +#define nst (cv_mem->cv_nst) +#define tn (cv_mem->cv_tn) +#define h (cv_mem->cv_h) +#define gamma (cv_mem->cv_gamma) +#define gammap (cv_mem->cv_gammap) +#define gamrat (cv_mem->cv_gamrat) +#define ewt (cv_mem->cv_ewt) +#define nfe (cv_mem->cv_nfe) +#define errfp (cv_mem->cv_errfp) +#define iopt (cv_mem->cv_iopt) +#define linit (cv_mem->cv_linit) +#define lsetup (cv_mem->cv_lsetup) +#define lsolve (cv_mem->cv_lsolve) +#define lfree (cv_mem->cv_lfree) +#define lmem (cv_mem->cv_lmem) + +#define jac (cvdense_mem->d_jac) +#define M (cvdense_mem->d_M) +#define pivots (cvdense_mem->d_pivots) +#define savedJ (cvdense_mem->d_savedJ) +#define nstlj (cvdense_mem->d_nstlj) +#define nje (cvdense_mem->d_nje) +#define J_data (cvdense_mem->d_J_data) + + +/*************** CVDense ********************************************* + + This routine initializes the memory record and sets various function + fields specific to the dense linear solver module. CVDense sets the + cv_linit, cv_lsetup, cv_lsolve, and cv_lfree fields in (*cvode_mem) + to be CVDenseInit, CVDenseSetup, CVDenseSolve, and CVDenseFree, + respectively. It allocates memory for a structure of type + CVDenseMemRec and sets the cv_lmem field in (*cvode_mem) to the + address of this structure. Finally, it sets d_J_data field in the + CVDenseMemRec structure to be the input parameter jac_data and the + d_jac field to be: + + (1) the input parameter djac if djac != NULL or + + (2) CVDenseDQJac if djac == NULL. + +**********************************************************************/ + +void CVDense(void *cvode_mem, CVDenseJacFn djac, void *jac_data) +{ + CVodeMem cv_mem; + CVDenseMem cvdense_mem; + + /* Return immediately if cvode_mem is NULL */ + cv_mem = (CVodeMem) cvode_mem; + if (cv_mem == NULL) return; /* CVode reports this error */ + + /* Set four main function fields in cv_mem */ + linit = CVDenseInit; + lsetup = CVDenseSetup; + lsolve = CVDenseSolve; + lfree = CVDenseFree; + + /* Get memory for CVDenseMemRec */ + lmem = cvdense_mem = (CVDenseMem) malloc(sizeof(CVDenseMemRec)); + if (cvdense_mem == NULL) return; /* CVDenseInit reports this error */ + + /* Set Jacobian routine field to user's djac or CVDenseDQJac */ + if (djac == NULL) { + jac = CVDenseDQJac; + } else { + jac = djac; + } + J_data = jac_data; +} + +/*************** CVDenseInit ***************************************** + + This routine initializes remaining memory specific to the dense + linear solver. If any memory request fails, all memory previously + allocated is freed, and an error message printed, before returning. + +**********************************************************************/ + +static int CVDenseInit(CVodeMem cv_mem, boole *setupNonNull) +{ + CVDenseMem cvdense_mem; + + cvdense_mem = (CVDenseMem) lmem; + + /* Print error message and return if cvdense_mem is NULL */ + if (cvdense_mem == NULL) { + fprintf(errfp, MSG_MEM_FAIL); + return(LINIT_ERR); + } + + /* Set flag setupNonNull = TRUE */ + *setupNonNull = TRUE; + + /* Allocate memory for M, savedJ, and pivot array */ + + M = DenseAllocMat(N); + if (M == NULL) { + fprintf(errfp, MSG_MEM_FAIL); + return(LINIT_ERR); + } + savedJ = DenseAllocMat(N); + if (savedJ == NULL) { + fprintf(errfp, MSG_MEM_FAIL); + DenseFreeMat(M); + return(LINIT_ERR); + } + pivots = DenseAllocPiv(N); + if (pivots == NULL) { + fprintf(errfp, MSG_MEM_FAIL); + DenseFreeMat(M); + DenseFreeMat(savedJ); + return(LINIT_ERR); + } + + /* Initialize nje and nstlj, and set workspace lengths */ + + nje = 0; + if (iopt != NULL) { + iopt[DENSE_NJE] = nje; + iopt[DENSE_LRW] = 2*N*N; + iopt[DENSE_LIW] = N; + } + nstlj = 0; + + return(LINIT_OK); +} + +/*************** CVDenseSetup **************************************** + + This routine does the setup operations for the dense linear solver. + It makes a decision whether or not to call the Jacobian evaluation + routine based on various state variables, and if not it uses the + saved copy. In any case, it constructs the Newton matrix + M = I - gamma*J, updates counters, and calls the dense LU + factorization routine. + +**********************************************************************/ + +static int CVDenseSetup(CVodeMem cv_mem, int convfail, N_Vector ypred, + N_Vector fpred, boole *jcurPtr, N_Vector vtemp1, + N_Vector vtemp2, N_Vector vtemp3) +{ + boole jbad, jok; + real dgamma; + integer ier; + CVDenseMem cvdense_mem; + + cvdense_mem = (CVDenseMem) lmem; + + /* Use nst, gamma/gammap, and convfail to set J eval. flag jok */ + + dgamma = ABS((gamma/gammap) - ONE); + jbad = (nst == 0) || (nst > nstlj + CVD_MSBJ) || + ((convfail == FAIL_BAD_J) && (dgamma < CVD_DGMAX)) || + (convfail == FAIL_OTHER); + jok = !jbad; + + if (jok) { + /* If jok = TRUE, use saved copy of J */ + *jcurPtr = FALSE; + DenseCopy(savedJ, M); + } else { + /* If jok = FALSE, call jac routine for new J value */ + nje++; + if (iopt != NULL) iopt[DENSE_NJE] = nje; + nstlj = nst; + *jcurPtr = TRUE; + DenseZero(M); + jac(N, M, f, f_data, tn, ypred, fpred, ewt, h, + uround, J_data, &nfe, vtemp1, vtemp2, vtemp3); + DenseCopy(M, savedJ); + } + + /* Scale and add I to get M = I - gamma*J */ + DenseScale(-gamma, M); + DenseAddI(M); + + /* Do LU factorization of M */ + ier = DenseFactor(M, pivots); + + /* Return 0 if the LU was complete; otherwise return 1 */ + if (ier > 0) return(1); + return(0); +} + +/*************** CVDenseSolve **************************************** + + This routine handles the solve operation for the dense linear solver + by calling the dense backsolve routine. The returned value is 0. + +**********************************************************************/ + +static int CVDenseSolve(CVodeMem cv_mem, N_Vector b, N_Vector ycur, + N_Vector fcur) +{ + CVDenseMem cvdense_mem; + + cvdense_mem = (CVDenseMem) lmem; + + DenseBacksolve(M, pivots, b); + + /* If BDF, scale the correction to account for change in gamma */ + if ((lmm == BDF) && (gamrat != ONE)) { + N_VScale(TWO/(ONE + gamrat), b, b); + } + + return(0); +} + +/*************** CVDenseFree ***************************************** + + This routine frees memory specific to the dense linear solver. + +**********************************************************************/ + +static void CVDenseFree(CVodeMem cv_mem) +{ + CVDenseMem cvdense_mem; + + cvdense_mem = (CVDenseMem) lmem; + + DenseFreeMat(M); + DenseFreeMat(savedJ); + DenseFreePiv(pivots); + free(lmem); +} diff --git a/ext/cvode/source/cvdiag.c b/ext/cvode/source/cvdiag.c new file mode 100755 index 000000000..d15939d78 --- /dev/null +++ b/ext/cvode/source/cvdiag.c @@ -0,0 +1,292 @@ +/****************************************************************** + * * + * File : cvdiag.c * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 4 May 1998 * + *----------------------------------------------------------------* + * This is the implementation file for the CVODE diagonal linear * + * solver, CVDIAG. * + * * + ******************************************************************/ + + +#include +#include +#include "cvdiag.h" +#include "cvode.h" +#include "llnltyps.h" +#include "nvector.h" + + +/* Error Messages */ + +#define CVDIAG_INIT "CVDiagInit-- " + +#define MSG_MEM_FAIL CVDIAG_INIT "A memory request failed.\n\n" + + +/* Other Constants */ + +#define FRACT RCONST(0.1) +#define ONE RCONST(1.0) + + +/****************************************************************** + * * + * Types : CVDiagMemRec, CVDiagMem * + *----------------------------------------------------------------* + * The type CVDiagMem is pointer to a CVDiagMemRec. This * + * structure contains CVDiag solver-specific data. * + * * + ******************************************************************/ + + +typedef struct { + + real di_gammasv; /* gammasv = gamma at the last call to setup */ + /* or solve */ + + N_Vector di_M; /* M = (I - gamma J)^{-1} , gamma = h / l1 */ + + N_Vector di_bit; /* temporary storage vector */ + + N_Vector di_bitcomp; /* temporary storage vector */ + +} CVDiagMemRec, *CVDiagMem; + + +/* CVDIAG linit, lsetup, lsolve, and lfree routines */ + +static int CVDiagInit(CVodeMem cv_mem, boole *setupNonNull); + +static int CVDiagSetup(CVodeMem cv_mem, int convfail, N_Vector ypred, + N_Vector fpred, boole *jcurPtr, N_Vector vtemp1, + N_Vector vtemp2, N_Vector vtemp3); + +static int CVDiagSolve(CVodeMem cv_mem, N_Vector b, N_Vector ycur, + N_Vector fcur); + +static void CVDiagFree(CVodeMem cv_mem); + + +/* Readability Replacements */ + +#define N (cv_mem->cv_N) +#define f (cv_mem->cv_f) +#define f_data (cv_mem->cv_f_data) +#define uround (cv_mem->cv_uround) +#define tn (cv_mem->cv_tn) +#define h (cv_mem->cv_h) +#define rl1 (cv_mem->cv_rl1) +#define gamma (cv_mem->cv_gamma) +#define ewt (cv_mem->cv_ewt) +#define nfe (cv_mem->cv_nfe) +#define errfp (cv_mem->cv_errfp) +#define iopt (cv_mem->cv_iopt) +#define zn (cv_mem->cv_zn) +#define linit (cv_mem->cv_linit) +#define lsetup (cv_mem->cv_lsetup) +#define lsolve (cv_mem->cv_lsolve) +#define lfree (cv_mem->cv_lfree) +#define lmem (cv_mem->cv_lmem) +#define machenv (cv_mem->cv_machenv) + +#define gammasv (cvdiag_mem->di_gammasv) +#define M (cvdiag_mem->di_M) +#define bit (cvdiag_mem->di_bit) +#define bitcomp (cvdiag_mem->di_bitcomp) + + + +/*************** CVDiag ********************************************** + + This routine initializes the memory record and sets various function + fields specific to the diagonal linear solver module. CVDiag sets the + cv_linit, cv_lsetup, cv_lsolve, and cv_lfree fields in (*cvode_mem) + to be CVDiagInit, CVDiagSetup, CVDiagSolve, and CVDiagFree, + respectively. It allocates memory for a structure of type + CVDiagMemRec and sets the cv_lmem field in (*cvode_mem) to the + address of this structure. + +**********************************************************************/ + +void CVDiag(void *cvode_mem) +{ + CVodeMem cv_mem; + CVDiagMem cvdiag_mem; + + /* Return immediately if cvode_mem is NULL */ + cv_mem = (CVodeMem) cvode_mem; + if (cv_mem == NULL) return; /* CVode reports this error */ + + /* Set four main function fields in cv_mem */ + linit = CVDiagInit; + lsetup = CVDiagSetup; + lsolve = CVDiagSolve; + lfree = CVDiagFree; + + /* Get memory for CVDiagMemRec */ + lmem = cvdiag_mem = (CVDiagMem) malloc(sizeof(CVDiagMemRec)); + if (cvdiag_mem == NULL) return; /* CVDiagInit reports this error */ +} + +/*************** CVDiagInit ****************************************** + + This routine initializes remaining memory specific to the diagonal + linear solver. If any memory request fails, all memory previously + allocated is freed, and an error message printed, before returning. + +**********************************************************************/ + +static int CVDiagInit(CVodeMem cv_mem, boole *setupNonNull) +{ + CVDiagMem cvdiag_mem; + + cvdiag_mem = (CVDiagMem) lmem; + + /* Print error message and return if cvdiag_mem is NULL */ + if (cvdiag_mem == NULL) { + fprintf(errfp, MSG_MEM_FAIL); + return(LINIT_ERR); + } + + /* Set flag setupNonNull = TRUE */ + *setupNonNull = TRUE; + + /* Allocate memory for M, bit, and bitcomp */ + + M = N_VNew(N, machenv); + if (M == NULL) { + fprintf(errfp, MSG_MEM_FAIL); + return(LINIT_ERR); + } + bit = N_VNew(N, machenv); + if (bit == NULL) { + fprintf(errfp, MSG_MEM_FAIL); + N_VFree(M); + return(LINIT_ERR); + } + bitcomp = N_VNew(N, machenv); + if (bitcomp == NULL) { + fprintf(errfp, MSG_MEM_FAIL); + N_VFree(M); + N_VFree(bit); + return(LINIT_ERR); + } + + /* Set workspace lengths */ + if (iopt != NULL) { + iopt[DIAG_LRW] = N*3; + iopt[DIAG_LIW] = 0; + } + + return(LINIT_OK); +} + +/*************** CVDiagSetup ***************************************** + + This routine does the setup operations for the diagonal linear + solver. It constructs a diagonal approximation to the Newton matrix + M = I - gamma*J, updates counters, and inverts M. + +**********************************************************************/ + +static int CVDiagSetup(CVodeMem cv_mem, int convfail, N_Vector ypred, + N_Vector fpred, boole *jcurPtr, N_Vector vtemp1, + N_Vector vtemp2, N_Vector vtemp3) +{ + real r; + N_Vector ftemp, y; + boole invOK; + CVDiagMem cvdiag_mem; + + cvdiag_mem = (CVDiagMem) lmem; + + /* Rename work vectors for use as temporary values of y and f */ + ftemp = vtemp1; + y = vtemp2; + + /* Form y with perturbation = FRACT*(func. iter. correction) */ + r = FRACT * rl1; + N_VLinearSum(h, fpred, -ONE, zn[1], ftemp); + N_VLinearSum(r, ftemp, ONE, ypred, y); + + /* Evaluate f at perturbed y */ + f(N, tn, y, M, f_data); + nfe++; + + /* Construct M = I - gamma*J with J = diag(deltaf_i/deltay_i) */ + N_VLinearSum(ONE, M, -ONE, fpred, M); + N_VLinearSum(FRACT, ftemp, -h, M, M); + N_VProd(ftemp, ewt, y); + /* Protect against deltay_i being at roundoff level */ + N_VCompare(uround, y, bit); + N_VAddConst(bit, -ONE, bitcomp); + N_VProd(ftemp, bit, y); + N_VLinearSum(FRACT, y, -ONE, bitcomp, y); + N_VDiv(M, y, M); + N_VProd(M, bit, M); + N_VLinearSum(ONE, M, -ONE, bitcomp, M); + + /* Invert M with test for zero components */ + invOK = N_VInvTest(M, M); + if (!invOK) return(1); + + /* Set jcur = TRUE, save gamma in gammasv, and return */ + *jcurPtr = TRUE; + gammasv = gamma; + return(0); +} + +/*************** CVDiagSolve ***************************************** + + This routine performs the solve operation for the diagonal linear + solver. If necessary it first updates gamma in M = I - gamma*J. + +**********************************************************************/ + +static int CVDiagSolve(CVodeMem cv_mem, N_Vector b, N_Vector ycur, + N_Vector fcur) +{ + boole invOK; + real r; + CVDiagMem cvdiag_mem; + + cvdiag_mem = (CVDiagMem) lmem; + + /* If gamma has changed, update factor in M, and save gamma value */ + + if (gammasv != gamma) { + r = gamma / gammasv; + N_VInv(M, M); + N_VAddConst(M, -ONE, M); + N_VScale(r, M, M); + N_VAddConst(M, ONE, M); + invOK = N_VInvTest(M, M); + if (!invOK) return (1); + + gammasv = gamma; + } + + /* Apply M-inverse to b */ + N_VProd(b, M, b); + return(0); +} + +/*************** CVDiagFree ****************************************** + + This routine frees memory specific to the diagonal linear solver. + +**********************************************************************/ + +static void CVDiagFree(CVodeMem cv_mem) +{ + CVDiagMem cvdiag_mem; + + cvdiag_mem = (CVDiagMem) lmem; + + N_VFree(M); + N_VFree(bit); + N_VFree(bitcomp); + free(lmem); +} diff --git a/ext/cvode/source/cvode.c b/ext/cvode/source/cvode.c new file mode 100755 index 000000000..36faf6f98 --- /dev/null +++ b/ext/cvode/source/cvode.c @@ -0,0 +1,2631 @@ +/****************************************************************** + * * + * File : cvode.c * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 29 February 2000 * + *----------------------------------------------------------------* + * This is the implementation file for the main CVODE integrator. * + * It is independent of the CVODE linear solver in use. * + * * + ******************************************************************/ + + +/************************************************************/ +/******************* BEGIN Imports **************************/ +/************************************************************/ + +#include +#include +#include "cvode.h" +#include "llnltyps.h" +#include "nvector.h" +#include "llnlmath.h" + +/************************************************************/ +/******************** END Imports ***************************/ +/************************************************************/ + + +/***************************************************************/ +/*********************** BEGIN Macros **************************/ +/***************************************************************/ + +/* Macro: loop */ + +#define loop for(;;) + +/***************************************************************/ +/************************ END Macros ***************************/ +/***************************************************************/ + + + +/************************************************************/ +/************** BEGIN CVODE Private Constants ***************/ +/************************************************************/ + +#define HALF RCONST(0.5) /* real 0.5 */ +#define ZERO RCONST(0.0) /* real 0.0 */ +#define ONE RCONST(1.0) /* real 1.0 */ +#define TWO RCONST(2.0) /* real 2.0 */ +#define TWELVE RCONST(12.0) /* real 12.0 */ + +/***************************************************************/ +/************** BEGIN Default Constants ************************/ +/***************************************************************/ + +#define HMIN_DEFAULT ZERO /* hmin default value */ +#define HMAX_INV_DEFAULT ZERO /* hmax_inv default value */ +#define MXHNIL_DEFAULT 10 /* mxhnil default value */ +#define MXSTEP_DEFAULT 500 /* mxstep default value */ + + +/***************************************************************/ +/*************** END Default Constants *************************/ +/***************************************************************/ + + +/***************************************************************/ +/************ BEGIN Routine-Specific Constants *****************/ +/***************************************************************/ + +/* CVodeDky */ + +#define FUZZ_FACTOR RCONST(100.0) + +/* CVHin */ + +#define HLB_FACTOR RCONST(100.0) +#define HUB_FACTOR RCONST(0.1) +#define H_BIAS HALF +#define MAX_ITERS 4 + +/* CVSet */ + +#define CORTES RCONST(0.1) + +/* CVStep return values */ + +#define SUCCESS_STEP 0 +#define REP_ERR_FAIL -1 +#define REP_CONV_FAIL -2 +#define SETUP_FAILED -3 +#define SOLVE_FAILED -4 + +/* CVStep control constants */ + +#define PREDICT_AGAIN -5 +#define DO_ERROR_TEST 1 + +/* CVStep */ + +#define THRESH RCONST(1.5) +#define ETAMX1 RCONST(10000.0) +#define ETAMX2 RCONST(10.0) +#define ETAMX3 RCONST(10.0) +#define ETAMXF RCONST(0.2) +#define ETAMIN RCONST(0.1) +#define ETACF RCONST(0.25) +#define ADDON RCONST(0.000001) +#define BIAS1 RCONST(6.0) +#define BIAS2 RCONST(6.0) +#define BIAS3 RCONST(10.0) +#define ONEPSM RCONST(1.000001) + +#define SMALL_NST 10 /* nst > SMALL_NST => use ETAMX3 */ +#define MXNCF 10 /* max no. of convergence failures during */ + /* one step try */ +#define MXNEF 7 /* max no. of error test failures during */ + /* one step try */ +#define MXNEF1 3 /* max no. of error test failures before */ + /* forcing a reduction of order */ +#define SMALL_NEF 2 /* if an error failure occurs and */ + /* SMALL_NEF <= nef <= MXNEF1, then */ + /* reset eta = MIN(eta, ETAMXF) */ +#define LONG_WAIT 10 /* number of steps to wait before */ + /* considering an order change when */ + /* q==1 and MXNEF1 error test failures */ + /* have occurred */ + +/* CVnls return values */ + +#define SOLVED 0 +#define CONV_FAIL -1 +#define SETUP_FAIL_UNREC -2 +#define SOLVE_FAIL_UNREC -3 + +/* CVnls input flags */ + +#define FIRST_CALL 0 +#define PREV_CONV_FAIL -1 +#define PREV_ERR_FAIL -2 + +/* CVnls other constants */ + +#define FUNC_MAXCOR 3 /* maximum no. of corrector iterations */ + /* for iter == FUNCTIONAL */ +#define NEWT_MAXCOR 3 /* maximum no. of corrector iterations */ + /* for iter == NEWTON */ + +#define CRDOWN RCONST(0.3) /* constant used in the estimation of the */ + /* convergence rate (crate) of the */ + /* iterates for the nonlinear equation */ +#define DGMAX RCONST(0.3) /* iter == NEWTON, |gamma/gammap-1| > DGMAX */ + /* => call lsetup */ + +#define RDIV TWO /* declare divergence if ratio del/delp > RDIV */ +#define MSBP 20 /* max no. of steps between lsetup calls */ + +#define TRY_AGAIN 99 /* control constant for CVnlsNewton - should be */ + /* distinct from CVnls return values */ + + +/***************************************************************/ +/*************** END Routine-Specific Constants ***************/ +/***************************************************************/ + + +/***************************************************************/ +/***************** BEGIN Error Messages ************************/ +/***************************************************************/ + +/* CVodeMalloc/CVReInit Error Messages */ + +#define CVM "CVodeMalloc/CVReInit-- " + +#define MSG_Y0_NULL CVM "y0=NULL illegal.\n\n" + +#define MSG_BAD_N CVM "N=%ld < 1 illegal.\n\n" + +#define MSG_BAD_LMM_1 CVM "lmm=%d illegal.\n" +#define MSG_BAD_LMM_2 "The legal values are ADAMS=%d and BDF=%d.\n\n" +#define MSG_BAD_LMM MSG_BAD_LMM_1 MSG_BAD_LMM_2 + +#define MSG_BAD_ITER_1 CVM "iter=%d illegal.\n" +#define MSG_BAD_ITER_2 "The legal values are FUNCTIONAL=%d " +#define MSG_BAD_ITER_3 "and NEWTON=%d.\n\n" +#define MSG_BAD_ITER MSG_BAD_ITER_1 MSG_BAD_ITER_2 MSG_BAD_ITER_3 + +#define MSG_BAD_ITOL_1 CVM "itol=%d illegal.\n" +#define MSG_BAD_ITOL_2 "The legal values are SS=%d and SV=%d.\n\n" +#define MSG_BAD_ITOL MSG_BAD_ITOL_1 MSG_BAD_ITOL_2 + +#define MSG_F_NULL CVM "f=NULL illegal.\n\n" + +#define MSG_RELTOL_NULL CVM "reltol=NULL illegal.\n\n" + +#define MSG_BAD_RELTOL CVM "*reltol=%g < 0 illegal.\n\n" + +#define MSG_ABSTOL_NULL CVM "abstol=NULL illegal.\n\n" + +#define MSG_BAD_ABSTOL CVM "Some abstol component < 0.0 illegal.\n\n" + +#define MSG_BAD_OPTIN_1 CVM "optIn=%d illegal.\n" +#define MSG_BAD_OPTIN_2 "The legal values are FALSE=%d and TRUE=%d.\n\n" +#define MSG_BAD_OPTIN MSG_BAD_OPTIN_1 MSG_BAD_OPTIN_2 + +#define MSG_BAD_OPT CVM "optIn=TRUE, but iopt=ropt=NULL.\n\n" + +#define MSG_BAD_HMIN_HMAX_1 CVM "Inconsistent step size limits:\n" +#define MSG_BAD_HMIN_HMAX_2 "ropt[HMIN]=%g > ropt[HMAX]=%g.\n\n" +#define MSG_BAD_HMIN_HMAX MSG_BAD_HMIN_HMAX_1 MSG_BAD_HMIN_HMAX_2 + +#define MSG_MEM_FAIL CVM "A memory request failed.\n\n" + +#define MSG_BAD_EWT CVM "Some initial ewt component = 0.0 illegal.\n\n" + +#define MSG_REI_NO_MEM "CVReInit-- cvode_mem = NULL illegal.\n\n" + +#define MSG_REI_MAXORD1 "CVReInit-- Illegal attempt to increase " +#define MSG_REI_MAXORD2 "maximum method order from %d to %d.\n\n" +#define MSG_REI_MAXORD MSG_REI_MAXORD1 MSG_REI_MAXORD2 + + +/* CVode error messages */ + +#define CVODE "CVode-- " + +#define NO_MEM "cvode_mem=NULL illegal.\n\n" + +#define MSG_CVODE_NO_MEM CVODE NO_MEM + +#define MSG_LINIT_NULL CVODE "The linear solver's init routine is NULL.\n\n" + +#define MSG_LSETUP_NULL CVODE "The linear solver's setup routine is NULL.\n\n" + +#define MSG_LSOLVE_NULL CVODE "The linear solver's solve routine is NULL.\n\n" + +#define MSG_LFREE_NULL CVODE "The linear solver's free routine is NULL.\n\n" + +#define MSG_LINIT_FAIL CVODE "The linear solver's init routine failed.\n\n" + +#define MSG_YOUT_NULL CVODE "yout=NULL illegal.\n\n" + +#define MSG_T_NULL CVODE "t=NULL illegal.\n\n" + +#define MSG_BAD_ITASK_1 CVODE "itask=%d illegal.\nThe legal values are" +#define MSG_BAD_ITASK_2 " NORMAL=%d and ONE_STEP=%d.\n\n" +#define MSG_BAD_ITASK MSG_BAD_ITASK_1 MSG_BAD_ITASK_2 + +#define MSG_BAD_H0 CVODE "h0=%g and tout-t0=%g inconsistent.\n\n" + +#define MSG_BAD_TOUT_1 CVODE "Trouble interpolating at tout = %g.\n" +#define MSG_BAD_TOUT_2 "tout too far back in direction of integration.\n\n" +#define MSG_BAD_TOUT MSG_BAD_TOUT_1 MSG_BAD_TOUT_2 + +#define MSG_MAX_STEPS_1 CVODE "At t=%g, mxstep=%d steps taken on " +#define MSG_MAX_STEPS_2 "this call before\nreaching tout=%g.\n\n" +#define MSG_MAX_STEPS MSG_MAX_STEPS_1 MSG_MAX_STEPS_2 + +#define MSG_EWT_NOW_BAD_1 CVODE "At t=%g, " +#define MSG_EWT_NOW_BAD_2 "some ewt component has become <= 0.0.\n\n" +#define MSG_EWT_NOW_BAD MSG_EWT_NOW_BAD_1 MSG_EWT_NOW_BAD_2 + +#define MSG_TOO_MUCH_ACC CVODE "At t=%g, too much accuracy requested.\n\n" + +#define MSG_HNIL_1 CVODE "Warning.. internal t=%g and step size h=%g\n" +#define MSG_HNIL_2 "are such that t + h == t on the next step.\n" +#define MSG_HNIL_3 "The solver will continue anyway.\n\n" +#define MSG_HNIL MSG_HNIL_1 MSG_HNIL_2 MSG_HNIL_3 + +#define MSG_HNIL_DONE_1 CVODE "The above warning has been issued %d times " +#define MSG_HNIL_DONE_2 "and will not be\nissued again for this problem.\n\n" +#define MSG_HNIL_DONE MSG_HNIL_DONE_1 MSG_HNIL_DONE_2 + +#define MSG_ERR_FAILS_1 CVODE "At t=%g and step size h=%g, the error test\n" +#define MSG_ERR_FAILS_2 "failed repeatedly or with |h| = hmin.\n\n" +#define MSG_ERR_FAILS MSG_ERR_FAILS_1 MSG_ERR_FAILS_2 + +#define MSG_CONV_FAILS_1 CVODE "At t=%g and step size h=%g, the corrector\n" +#define MSG_CONV_FAILS_2 "convergence failed repeatedly or " +#define MSG_CONV_FAILS_3 "with |h| = hmin.\n\n" +#define MSG_CONV_FAILS MSG_CONV_FAILS_1 MSG_CONV_FAILS_2 MSG_CONV_FAILS_3 + +#define MSG_SETUP_FAILED_1 CVODE "At t=%g, the setup routine failed in an " +#define MSG_SETUP_FAILED_2 "unrecoverable manner.\n\n" +#define MSG_SETUP_FAILED MSG_SETUP_FAILED_1 MSG_SETUP_FAILED_2 + +#define MSG_SOLVE_FAILED_1 CVODE "At t=%g, the solve routine failed in an " +#define MSG_SOLVE_FAILED_2 "unrecoverable manner.\n\n" +#define MSG_SOLVE_FAILED MSG_SOLVE_FAILED_1 MSG_SOLVE_FAILED_2 + +#define MSG_TOO_CLOSE_1 CVODE "tout=%g too close to t0=%g to start" +#define MSG_TOO_CLOSE_2 " integration.\n\n" +#define MSG_TOO_CLOSE MSG_TOO_CLOSE_1 MSG_TOO_CLOSE_2 + + +/* CVodeDky Error Messages */ + +#define DKY "CVodeDky-- " + +#define MSG_DKY_NO_MEM DKY NO_MEM + +#define MSG_BAD_K DKY "k=%d illegal.\n\n" + +#define MSG_BAD_T_1 DKY "t=%g illegal.\n" +#define MSG_BAD_T_2 "t not in interval tcur-hu=%g to tcur=%g.\n\n" +#define MSG_BAD_T MSG_BAD_T_1 MSG_BAD_T_2 + +#define MSG_BAD_DKY DKY "dky=NULL illegal.\n\n" + +/***************************************************************/ +/****************** END Error Messages *************************/ +/***************************************************************/ + + +/************************************************************/ +/*************** END CVODE Private Constants ****************/ +/************************************************************/ + + +/**************************************************************/ +/********* BEGIN Private Helper Functions Prototypes **********/ +/**************************************************************/ + +static boole CVAllocVectors(CVodeMem cv_mem, integer neq, int maxord, + void *machEnv); +static void CVFreeVectors(CVodeMem cv_mem, int maxord); + +static boole CVEwtSet(CVodeMem cv_mem, real *rtol, void *atol, int tol_type, + N_Vector ycur, integer neq); +static boole CVEwtSetSS(CVodeMem cv_mem, real *rtol, real *atol, + N_Vector ycur, integer neq); +static boole CVEwtSetSV(CVodeMem cv_mem, real *rtol, N_Vector atol, + N_Vector ycur, integer neq); + +static boole CVHin(CVodeMem cv_mem, real tout); +static real CVUpperBoundH0(CVodeMem cv_mem, real tdist); +static real CVYddNorm(CVodeMem cv_mem, real hg); + +static int CVStep(CVodeMem cv_mem); + +static void CVAdjustParams(CVodeMem cv_mem); +static void CVAdjustOrder(CVodeMem cv_mem, int deltaq); +static void CVAdjustAdams(CVodeMem cv_mem, int deltaq); +static void CVAdjustBDF(CVodeMem cv_mem, int deltaq); +static void CVIncreaseBDF(CVodeMem cv_mem); +static void CVDecreaseBDF(CVodeMem cv_mem); + +static void CVRescale(CVodeMem cv_mem); + +static void CVPredict(CVodeMem cv_mem); + +static void CVSet(CVodeMem cv_mem); +static void CVSetAdams(CVodeMem cv_mem); +static real CVAdamsStart(CVodeMem cv_mem, real m[]); +static void CVAdamsFinish(CVodeMem cv_mem, real m[], real M[], real hsum); +static real CVAltSum(int iend, real a[], int k); +static void CVSetBDF(CVodeMem cv_mem); +static void CVSetTqBDF(CVodeMem cv_mem, real hsum, real alpha0, + real alpha0_hat, real xi_inv, real xistar_inv); + +static int CVnls(CVodeMem cv_mem, int nflag); +static int CVnlsFunctional(CVodeMem cv_mem); +static int CVnlsNewton(CVodeMem cv_mem, int nflag); +static int CVNewtonIteration(CVodeMem cv_mem); + +static int CVHandleNFlag(CVodeMem cv_mem, int *nflagPtr, real saved_t, + int *ncfPtr); + +static void CVRestore(CVodeMem cv_mem, real saved_t); + +static boole CVDoErrorTest(CVodeMem cv_mem, int *nflagPtr, int *kflagPtr, + real saved_t, int *nefPtr, real *dsmPtr); + +static void CVCompleteStep(CVodeMem cv_mem); + +static void CVPrepareNextStep(CVodeMem cv_mem, real dsm); +static void CVSetEta(CVodeMem cv_mem); +static real CVComputeEtaqm1(CVodeMem cv_mem); +static real CVComputeEtaqp1(CVodeMem cv_mem); +static void CVChooseEta(CVodeMem cv_mem,real etaqm1, real etaq, real etaqp1); + +static int CVHandleFailure(CVodeMem cv_mem,int kflag); + + +/**************************************************************/ +/********** END Private Helper Functions Prototypes ***********/ +/**************************************************************/ + + +/**************************************************************/ +/**************** BEGIN Readability Constants *****************/ +/**************************************************************/ + + +#define uround (cv_mem->cv_uround) +#define zn (cv_mem->cv_zn) +#define ewt (cv_mem->cv_ewt) +#define y (cv_mem->cv_y) +#define acor (cv_mem->cv_acor) +#define tempv (cv_mem->cv_tempv) +#define ftemp (cv_mem->cv_ftemp) +#define q (cv_mem->cv_q) +#define qprime (cv_mem->cv_qprime) +#define qwait (cv_mem->cv_qwait) +#define L (cv_mem->cv_L) +#define h (cv_mem->cv_h) +#define hprime (cv_mem->cv_hprime) +#define eta (cv_mem-> cv_eta) +#define hscale (cv_mem->cv_hscale) +#define tn (cv_mem->cv_tn) +#define tau (cv_mem->cv_tau) +#define tq (cv_mem->cv_tq) +#define l (cv_mem->cv_l) +#define rl1 (cv_mem->cv_rl1) +#define gamma (cv_mem->cv_gamma) +#define gammap (cv_mem->cv_gammap) +#define gamrat (cv_mem->cv_gamrat) +#define crate (cv_mem->cv_crate) +#define acnrm (cv_mem->cv_acnrm) +#define mnewt (cv_mem->cv_mnewt) +#define qmax (cv_mem->cv_qmax) +#define mxstep (cv_mem->cv_mxstep) +#define maxcor (cv_mem->cv_maxcor) +#define mxhnil (cv_mem->cv_mxhnil) +#define hmin (cv_mem->cv_hmin) +#define hmax_inv (cv_mem->cv_hmax_inv) +#define etamax (cv_mem->cv_etamax) +#define nst (cv_mem->cv_nst) +#define nfe (cv_mem->cv_nfe) +#define ncfn (cv_mem->cv_ncfn) +#define netf (cv_mem->cv_netf) +#define nni (cv_mem-> cv_nni) +#define nsetups (cv_mem->cv_nsetups) +#define nhnil (cv_mem->cv_nhnil) +#define lrw (cv_mem->cv_lrw) +#define liw (cv_mem->cv_liw) +#define linit (cv_mem->cv_linit) +#define lsetup (cv_mem->cv_lsetup) +#define lsolve (cv_mem->cv_lsolve) +#define lfree (cv_mem->cv_lfree) +#define lmem (cv_mem->cv_lmem) +#define linitOK (cv_mem->cv_linitOK) +#define qu (cv_mem->cv_qu) +#define nstlp (cv_mem->cv_nstlp) +#define hu (cv_mem->cv_hu) +#define saved_tq5 (cv_mem->cv_saved_tq5) +#define jcur (cv_mem->cv_jcur) +#define tolsf (cv_mem->cv_tolsf) +#define setupNonNull (cv_mem->cv_setupNonNull) +#define machenv (cv_mem->cv_machenv) + +/**************************************************************/ +/***************** END Readability Constants ******************/ +/**************************************************************/ + + +/***************************************************************/ +/************* BEGIN CVODE Implementation **********************/ +/***************************************************************/ + + +/***************************************************************/ +/********* BEGIN Exported Functions Implementation *************/ +/***************************************************************/ + + +/******************** CVodeMalloc ******************************* + + CVodeMalloc allocates and initializes memory for a problem. All + problem specification inputs are checked for errors. If any + error occurs during initialization, it is reported to the file + whose file pointer is errfp and NULL is returned. Otherwise, the + pointer to successfully initialized problem memory is returned. + +*****************************************************************/ + +void *CVodeMalloc(integer N, RhsFn f, real t0, N_Vector y0, int lmm, int iter, + int itol, real *reltol, void *abstol, void *f_data, + FILE *errfp, boole optIn, long int iopt[], real ropt[], + void *machEnv) +{ + boole allocOK, ioptExists, roptExists, neg_abstol, ewtsetOK; + int maxord; + CVodeMem cv_mem; + FILE *fp; + + /* Check for legal input parameters */ + + fp = (errfp == NULL) ? stdout : errfp; + + if (y0==NULL) { + fprintf(fp, MSG_Y0_NULL); + return(NULL); + } + + if (N <= 0) { + fprintf(fp, MSG_BAD_N, N); + return(NULL); + } + + if ((lmm != ADAMS) && (lmm != BDF)) { + fprintf(fp, MSG_BAD_LMM, lmm, ADAMS, BDF); + return(NULL); + } + + if ((iter != FUNCTIONAL) && (iter != NEWTON)) { + fprintf(fp, MSG_BAD_ITER, iter, FUNCTIONAL, NEWTON); + return(NULL); + } + + if ((itol != SS) && (itol != SV)) { + fprintf(fp, MSG_BAD_ITOL, itol, SS, SV); + return(NULL); + } + + if (f == NULL) { + fprintf(fp, MSG_F_NULL); + return(NULL); + } + + if (reltol == NULL) { + fprintf(fp, MSG_RELTOL_NULL); + return(NULL); + } + + if (*reltol < ZERO) { + fprintf(fp, MSG_BAD_RELTOL, *reltol); + return(NULL); + } + + if (abstol == NULL) { + fprintf(fp, MSG_ABSTOL_NULL); + return(NULL); + } + + if (itol == SS) { + neg_abstol = (*((real *)abstol) < ZERO); + } else { + neg_abstol = (N_VMin((N_Vector)abstol) < ZERO); + } + if (neg_abstol) { + fprintf(fp, MSG_BAD_ABSTOL); + return(NULL); + } + + if ((optIn != FALSE) && (optIn != TRUE)) { + fprintf(fp, MSG_BAD_OPTIN, optIn, FALSE, TRUE); + return(NULL); + } + + if ((optIn) && (iopt == NULL) && (ropt == NULL)) { + fprintf(fp, MSG_BAD_OPT); + return(NULL); + } + + ioptExists = (iopt != NULL); + roptExists = (ropt != NULL); + + if (optIn && roptExists) { + if ((ropt[HMAX] > ZERO) && (ropt[HMIN] > ropt[HMAX])) { + fprintf(fp, MSG_BAD_HMIN_HMAX, ropt[HMIN], ropt[HMAX]); + return(NULL); + } + } + + /* Compute maxord */ + + maxord = (lmm == ADAMS) ? ADAMS_Q_MAX : BDF_Q_MAX; + + if (optIn && ioptExists) { + if (iopt[MAXORD] > 0) maxord = MIN(maxord, iopt[MAXORD]); + } + + cv_mem = (CVodeMem) malloc(sizeof(struct CVodeMemRec)); + if (cv_mem == NULL) { + fprintf(fp, MSG_MEM_FAIL); + return(NULL); + } + + /* Allocate the vectors */ + + allocOK = CVAllocVectors(cv_mem, N, maxord, machEnv); + if (!allocOK) { + fprintf(fp, MSG_MEM_FAIL); + free(cv_mem); + return(NULL); + } + + /* Set the ewt vector */ + + ewtsetOK = CVEwtSet(cv_mem, reltol, abstol, itol, y0, N); + if (!ewtsetOK) { + fprintf(fp, MSG_BAD_EWT); + CVFreeVectors(cv_mem, maxord); + free(cv_mem); + return(NULL); + } + + /* All error checking is complete at this point */ + + /* Copy the input parameters into CVODE state */ + + cv_mem->cv_N = N; + cv_mem->cv_f = f; + cv_mem->cv_f_data = f_data; + cv_mem->cv_lmm = lmm; + cv_mem->cv_iter = iter; + cv_mem->cv_itol = itol; + cv_mem->cv_reltol = reltol; + cv_mem->cv_abstol = abstol; + cv_mem->cv_iopt = iopt; + cv_mem->cv_ropt = ropt; + cv_mem->cv_errfp = fp; + tn = t0; + machenv = machEnv; + + /* Set step parameters */ + + q = 1; + L = 2; + qwait = L; + qmax = maxord; + etamax = ETAMX1; + + /* Set uround */ + + uround = UnitRoundoff(); + + /* Set the linear solver addresses to NULL, linitOK to FALSE */ + + linit = NULL; + lsetup = NULL; + lsolve = NULL; + lfree = NULL; + lmem = NULL; + /* We check != NULL later, in CVode and linit, if using NEWTON */ + linitOK = FALSE; + + /* Initialize zn[0] in the history array */ + + N_VScale(ONE, y0, zn[0]); + + /* Handle the remaining optional inputs */ + + hmin = HMIN_DEFAULT; + hmax_inv = HMAX_INV_DEFAULT; + if (optIn && roptExists) { + if (ropt[HMIN] > ZERO) hmin = ropt[HMIN]; + if (ropt[HMAX] > ZERO) hmax_inv = ONE/ropt[HMAX]; + } + + mxhnil = MXHNIL_DEFAULT; + mxstep = MXSTEP_DEFAULT; + if (optIn && ioptExists) { + if (iopt[MXHNIL] > 0) mxhnil = iopt[MXHNIL]; + if (iopt[MXSTEP] > 0) mxstep = iopt[MXSTEP]; + } + + if ((!optIn) && roptExists) ropt[H0] = ZERO; + + /* Set maxcor */ + + maxcor = (iter==NEWTON) ? NEWT_MAXCOR : FUNC_MAXCOR; + + /* Initialize all the counters */ + + nst = nfe = ncfn = netf = nni = nsetups = nhnil = nstlp = 0; + + /* Initialize all other vars corresponding to optional outputs */ + + qu = 0; + hu = ZERO; + tolsf = ONE; + + /* Initialize optional output locations in iopt, ropt */ + + if (ioptExists) { + iopt[NST] = iopt[NFE] = iopt[NSETUPS] = iopt[NNI] = 0; + iopt[NCFN] = iopt[NETF] = 0; + iopt[QU] = qu; + iopt[QCUR] = 0; + iopt[LENRW] = lrw; + iopt[LENIW] = liw; + } + + if (roptExists) { + ropt[HU] = hu; + ropt[HCUR] = ZERO; + ropt[TCUR] = t0; + ropt[TOLSF] = tolsf; + } + + /* Problem has been successfully initialized */ + + return((void *)cv_mem); +} + + +/******************** CVReInit ********************************** + + CVReInit re-initializes CVODE's memory for a problem, assuming + it has already been allocated in a prior CVodeMalloc call. + All problem specification inputs are checked for errors. + The problem size N is assumed to be unchanged since the call to + CVodeMalloc, and the maximum order maxord must not be larger. + If any error occurs during initialization, it is reported to the + file whose file pointer is errfp. + The return value is SUCCESS = 0 if no errors occurred, or + a negative value otherwise. + +*****************************************************************/ + +int CVReInit(void *cvode_mem, RhsFn f, real t0, N_Vector y0, + int lmm, int iter, int itol, real *reltol, void *abstol, + void *f_data, FILE *errfp, boole optIn, long int iopt[], + real ropt[], void *machEnv) +{ + boole allocOK, ioptExists, roptExists, neg_abstol, ewtsetOK; + int maxord; + CVodeMem cv_mem; + FILE *fp; + integer N; + + /* Check for legal input parameters */ + + fp = (errfp == NULL) ? stdout : errfp; + + if (cvode_mem == NULL) { + fprintf(fp, MSG_REI_NO_MEM); + return(CVREI_NO_MEM); + } + cv_mem = (CVodeMem) cvode_mem; + + if (y0 == NULL) { + fprintf(fp, MSG_Y0_NULL); + return(CVREI_ILL_INPUT); + } + + if ((lmm != ADAMS) && (lmm != BDF)) { + fprintf(fp, MSG_BAD_LMM, lmm, ADAMS, BDF); + return(CVREI_ILL_INPUT); + } + + if ((iter != FUNCTIONAL) && (iter != NEWTON)) { + fprintf(fp, MSG_BAD_ITER, iter, FUNCTIONAL, NEWTON); + return(CVREI_ILL_INPUT); + } + + if ((itol != SS) && (itol != SV)) { + fprintf(fp, MSG_BAD_ITOL, itol, SS, SV); + return(CVREI_ILL_INPUT); + } + + if (f == NULL) { + fprintf(fp, MSG_F_NULL); + return(CVREI_ILL_INPUT); + } + + if (reltol == NULL) { + fprintf(fp, MSG_RELTOL_NULL); + return(CVREI_ILL_INPUT); + } + + if (*reltol < ZERO) { + fprintf(fp, MSG_BAD_RELTOL, *reltol); + return(CVREI_ILL_INPUT); + } + + if (abstol == NULL) { + fprintf(fp, MSG_ABSTOL_NULL); + return(CVREI_ILL_INPUT); + } + + if (itol == SS) { + neg_abstol = (*((real *)abstol) < ZERO); + } else { + neg_abstol = (N_VMin((N_Vector)abstol) < ZERO); + } + if (neg_abstol) { + fprintf(fp, MSG_BAD_ABSTOL); + return(CVREI_ILL_INPUT); + } + + if ((optIn != FALSE) && (optIn != TRUE)) { + fprintf(fp, MSG_BAD_OPTIN, optIn, FALSE, TRUE); + return(CVREI_ILL_INPUT); + } + + if ((optIn) && (iopt == NULL) && (ropt == NULL)) { + fprintf(fp, MSG_BAD_OPT); + return(CVREI_ILL_INPUT); + } + + ioptExists = (iopt != NULL); + roptExists = (ropt != NULL); + + if (optIn && roptExists) { + if ((ropt[HMAX] > ZERO) && (ropt[HMIN] > ropt[HMAX])) { + fprintf(fp, MSG_BAD_HMIN_HMAX, ropt[HMIN], ropt[HMAX]); + return(CVREI_ILL_INPUT); + } + } + + /* Compute new maxord and check against old value */ + + maxord = (lmm == ADAMS) ? ADAMS_Q_MAX : BDF_Q_MAX; + if (optIn && ioptExists) + { if (iopt[MAXORD] > 0) maxord = MIN(maxord, iopt[MAXORD]); } + if (maxord > qmax) { + fprintf(fp, MSG_REI_MAXORD, qmax, maxord); + return(CVREI_ILL_INPUT); + } + + /* Set the ewt vector */ + + N = cv_mem->cv_N; + ewtsetOK = CVEwtSet(cv_mem, reltol, abstol, itol, y0, N); + if (!ewtsetOK) { + fprintf(fp, MSG_BAD_EWT); + return(CVREI_ILL_INPUT); + } + + /* All error checking is complete at this point */ + + /* Copy the input parameters into CVODE state */ + + cv_mem->cv_f = f; + cv_mem->cv_f_data = f_data; + cv_mem->cv_lmm = lmm; + cv_mem->cv_iter = iter; + cv_mem->cv_itol = itol; + cv_mem->cv_reltol = reltol; + cv_mem->cv_abstol = abstol; + cv_mem->cv_iopt = iopt; + cv_mem->cv_ropt = ropt; + cv_mem->cv_errfp = fp; + tn = t0; + machenv = machEnv; + + /* Set step parameters */ + + q = 1; + L = 2; + qwait = L; + qmax = maxord; + etamax = ETAMX1; + + /* Set uround */ + + uround = UnitRoundoff(); + + /* Set the linear solver addresses to NULL, linitOK to FALSE */ + + linit = NULL; + lsetup = NULL; + lsolve = NULL; + lfree = NULL; + lmem = NULL; + /* We check != NULL later, in CVode and linit, if using NEWTON */ + linitOK = FALSE; + + /* Initialize zn[0] in the history array */ + + N_VScale(ONE, y0, zn[0]); + + /* Handle the remaining optional inputs */ + + hmin = HMIN_DEFAULT; + hmax_inv = HMAX_INV_DEFAULT; + if (optIn && roptExists) { + if (ropt[HMIN] > ZERO) hmin = ropt[HMIN]; + if (ropt[HMAX] > ZERO) hmax_inv = ONE/ropt[HMAX]; + } + + mxhnil = MXHNIL_DEFAULT; + mxstep = MXSTEP_DEFAULT; + if (optIn && ioptExists) { + if (iopt[MXHNIL] > 0) mxhnil = iopt[MXHNIL]; + if (iopt[MXSTEP] > 0) mxstep = iopt[MXSTEP]; + } + + if ((!optIn) && roptExists) ropt[H0] = ZERO; + + /* Set maxcor */ + + maxcor = (iter==NEWTON) ? NEWT_MAXCOR : FUNC_MAXCOR; + + /* Initialize all the counters */ + + nst = nfe = ncfn = netf = nni = nsetups = nhnil = nstlp = 0; + + /* Initialize all other vars corresponding to optional outputs */ + + qu = 0; + hu = ZERO; + tolsf = ONE; + + /* Initialize optional output locations in iopt, ropt */ + + if (ioptExists) { + iopt[NST] = iopt[NFE] = iopt[NSETUPS] = iopt[NNI] = 0; + iopt[NCFN] = iopt[NETF] = 0; + iopt[QU] = qu; + iopt[QCUR] = 0; + iopt[LENRW] = lrw; + iopt[LENIW] = liw; + } + + if (roptExists) { + ropt[HU] = hu; + ropt[HCUR] = ZERO; + ropt[TCUR] = t0; + ropt[TOLSF] = tolsf; + } + + /* Problem has been successfully re-initialized */ + + return(SUCCESS); +} + + +/**************************************************************/ +/************** BEGIN More Readability Constants **************/ +/**************************************************************/ + +#define N (cv_mem->cv_N) +#define f (cv_mem->cv_f) +#define f_data (cv_mem->cv_f_data) +#define lmm (cv_mem->cv_lmm) +#define iter (cv_mem->cv_iter) +#define itol (cv_mem->cv_itol) +#define reltol (cv_mem->cv_reltol) +#define abstol (cv_mem->cv_abstol) +#define iopt (cv_mem->cv_iopt) +#define ropt (cv_mem->cv_ropt) +#define errfp (cv_mem->cv_errfp) + +/**************************************************************/ +/*************** END More Readability Constants ***************/ +/**************************************************************/ + + +/********************* CVode **************************************** + + This routine is the main driver of the CVODE package. + + It integrates over a time interval defined by the user, by calling + CVStep to do internal time steps. + + The first time that CVode is called for a successfully initialized + problem, it computes a tentative initial step size h. + + CVode supports two modes, specified by itask: NORMAL and ONE_STEP. + In the NORMAL mode, the solver steps until it reaches or passes tout + and then interpolates to obtain y(tout). + In the ONE_STEP mode, it takes one internal step and returns. + +********************************************************************/ + +int CVode(void *cvode_mem, real tout, N_Vector yout, real *t, int itask) +{ + int nstloc, kflag, istate, next_q, ier; + real rh, next_h; + boole hOK, ewtsetOK; + CVodeMem cv_mem; + + /* Check for legal inputs in all cases */ + + cv_mem = (CVodeMem) cvode_mem; + if (cvode_mem == NULL) { + fprintf(stdout, MSG_CVODE_NO_MEM); + return(CVODE_NO_MEM); + } + + if ((y = yout) == NULL) { + fprintf(errfp, MSG_YOUT_NULL); + return(ILL_INPUT); + } + + if (t == NULL) { + fprintf(errfp, MSG_T_NULL); + return(ILL_INPUT); + } + *t = tn; + + if ((itask != NORMAL) && (itask != ONE_STEP)) { + fprintf(errfp, MSG_BAD_ITASK, itask, NORMAL, ONE_STEP); + return(ILL_INPUT); + } + + /* On first call, check solver functions and call linit function */ + + if (nst == 0) { + if (iter == NEWTON) { + if (linit == NULL) { + fprintf(errfp, MSG_LINIT_NULL); + return(ILL_INPUT); + } + if (lsetup == NULL) { + fprintf(errfp, MSG_LSETUP_NULL); + return(ILL_INPUT); + } + if (lsolve == NULL) { + fprintf(errfp, MSG_LSOLVE_NULL); + return(ILL_INPUT); + } + if (lfree == NULL) { + fprintf(errfp, MSG_LFREE_NULL); + return(ILL_INPUT); + } + linitOK = (linit(cv_mem, &(setupNonNull)) == LINIT_OK); + if (!linitOK) { + fprintf(errfp, MSG_LINIT_FAIL); + return(ILL_INPUT); + } + } + + /* On the first call, call f at (t0,y0), set zn[1] = y'(t0), + set initial h (from H0 or CVHin), and scale zn[1] by h */ + + f(N, tn, zn[0], zn[1], f_data); + nfe = 1; + h = ZERO; + if (ropt != NULL) h = ropt[H0]; + if ( (h != ZERO) && ((tout-tn)*h < ZERO) ) { + fprintf(errfp, MSG_BAD_H0, h, tout-tn); + return(ILL_INPUT); + } + if (h == ZERO) { + hOK = CVHin(cv_mem, tout); + if (!hOK) { + fprintf(errfp, MSG_TOO_CLOSE, tout, tn); + return(ILL_INPUT); + } + } + rh = ABS(h)*hmax_inv; + if (rh > ONE) h /= rh; + if (ABS(h) < hmin) h *= hmin/ABS(h); + hscale = h; + N_VScale(h, zn[1], zn[1]); + + } /* end of first call block */ + + /* If not the first call, check if tout already reached */ + + if ( (itask == NORMAL) && (nst > 0) && ((tn-tout)*h >= ZERO) ) { + *t = tout; + ier = CVodeDky(cv_mem, tout, 0, yout); + if (ier != OKAY) { /* ier must be == BAD_T */ + fprintf(errfp, MSG_BAD_TOUT, tout); + return(ILL_INPUT); + } + return(SUCCESS); + } + + /* Looping point for internal steps */ + + nstloc = 0; + loop { + + next_h = h; + next_q = q; + + /* Reset and check ewt */ + + if (nst > 0) { + ewtsetOK = CVEwtSet(cv_mem, reltol, abstol, itol, zn[0], N); + if (!ewtsetOK) { + fprintf(errfp, MSG_EWT_NOW_BAD, tn); + istate = ILL_INPUT; + *t = tn; + N_VScale(ONE, zn[0], yout); + break; + } + } + + /* Check for too many steps */ + + if (nstloc >= mxstep) { + fprintf(errfp, MSG_MAX_STEPS, tn, mxstep, tout); + istate = TOO_MUCH_WORK; + *t = tn; + N_VScale(ONE, zn[0], yout); + break; + } + + /* Check for too much accuracy requested */ + + if ((tolsf = uround * N_VWrmsNorm(zn[0], ewt)) > ONE) { + fprintf(errfp, MSG_TOO_MUCH_ACC, tn); + istate = TOO_MUCH_ACC; + *t = tn; + N_VScale(ONE, zn[0], yout); + tolsf *= TWO; + break; + } + + /* Check for h below roundoff level in tn */ + + if (tn + h == tn) { + nhnil++; + if (nhnil <= mxhnil) fprintf(errfp, MSG_HNIL, tn, h); + if (nhnil == mxhnil) fprintf(errfp, MSG_HNIL_DONE, mxhnil); + } + + /* Call CVStep to take a step */ + + kflag = CVStep(cv_mem); + + /* Process failed step cases, and exit loop */ + + if (kflag != SUCCESS_STEP) { + istate = CVHandleFailure(cv_mem, kflag); + *t = tn; + N_VScale(ONE, zn[0], yout); + break; + } + + nstloc++; + + /* Check if in one-step mode, and if so copy y and exit loop */ + + if (itask == ONE_STEP) { + istate = SUCCESS; + *t = tn; + N_VScale(ONE, zn[0], yout); + next_q = qprime; + next_h = hprime; + break; + } + + /* Check if tout reached, and if so interpolate and exit loop */ + + if ((tn-tout)*h >= ZERO) { + istate = SUCCESS; + *t = tout; + (void) CVodeDky(cv_mem, tout, 0, yout); + next_q = qprime; + next_h = hprime; + break; + } + } + + /* End of step loop; load optional outputs and return */ + + if (iopt != NULL) { + iopt[NST] = nst; + iopt[NFE] = nfe; + iopt[NSETUPS] = nsetups; + iopt[NNI] = nni; + iopt[NCFN] = ncfn; + iopt[NETF] = netf; + iopt[QU] = q; + iopt[QCUR] = next_q; + } + + if (ropt != NULL) { + ropt[HU] = h; + ropt[HCUR] = next_h; + ropt[TCUR] = tn; + ropt[TOLSF] = tolsf; + } + + return(istate); +} + +/*************** CVodeDky ******************************************** + + This routine computes the k-th derivative of the interpolating + polynomial at the time t and stores the result in the vector dky. + The formula is: + q + dky = SUM c(j,k) * (t - tn)^(j-k) * h^(-j) * zn[j] , + j=k + where c(j,k) = j*(j-1)*...*(j-k+1), q is the current order, and + zn[j] is the j-th column of the Nordsieck history array. + + This function is called by CVode with k = 0 and t = tout, but + may also be called directly by the user. + +**********************************************************************/ + +int CVodeDky(void *cvode_mem, real t, int k, N_Vector dky) +{ + real s, c, r; + real tfuzz, tp, tn1; + int i, j; + CVodeMem cv_mem; + + cv_mem = (CVodeMem) cvode_mem; + + /* Check all inputs for legality */ + + if (cvode_mem == NULL) { + fprintf(stdout, MSG_DKY_NO_MEM); + return(DKY_NO_MEM); + } + + if (dky == NULL) { + fprintf(stdout, MSG_BAD_DKY); + return(BAD_DKY); + } + + if ((k < 0) || (k > q)) { + fprintf(errfp, MSG_BAD_K, k); + return(BAD_K); + } + + tfuzz = FUZZ_FACTOR * uround * (tn + hu); + tp = tn - hu - tfuzz; + tn1 = tn + tfuzz; + if ((t-tp)*(t-tn1) > ZERO) { + fprintf(errfp, MSG_BAD_T, t, tn-hu, tn); + return(BAD_T); + } + + /* Sum the differentiated interpolating polynomial */ + + s = (t - tn) / h; + for (j=q; j >= k; j--) { + c = ONE; + for (i=j; i >= j-k+1; i--) c *= i; + if (j == q) { + N_VScale(c, zn[q], dky); + } else { + N_VLinearSum(c, zn[j], s, dky, dky); + } + } + if (k == 0) return(OKAY); + r = RPowerI(h,-k); + N_VScale(r, dky, dky); + return(OKAY); +} + +/********************* CVodeFree ********************************** + + This routine frees the problem memory allocated by CVodeMalloc. + Such memory includes all the vectors allocated by CVAllocVectors, + and the memory lmem for the linear solver (deallocated by a call + to lfree). + +*******************************************************************/ + +void CVodeFree(void *cvode_mem) +{ + CVodeMem cv_mem; + + cv_mem = (CVodeMem) cvode_mem; + + if (cvode_mem == NULL) return; + + CVFreeVectors(cv_mem, qmax); + if ((iter == NEWTON) && linitOK) lfree(cv_mem); + free(cv_mem); +} + + +/***************************************************************/ +/********** END Exported Functions Implementation **************/ +/***************************************************************/ + + +/*******************************************************************/ +/******** BEGIN Private Helper Functions Implementation ************/ +/*******************************************************************/ + +/****************** CVAllocVectors *********************************** + + This routine allocates the CVODE vectors ewt, acor, tempv, ftemp, and + zn[0], ..., zn[maxord]. The length of the vectors is the input + parameter neq and the maximum order (needed to allocate zn) is the + input parameter maxord. If all memory allocations are successful, + CVAllocVectors returns TRUE. Otherwise all allocated memory is freed + and CVAllocVectors returns FALSE. + This routine also sets the optional outputs lrw and liw, which are + (respectively) the lengths of the real and integer work spaces + allocated here. + +**********************************************************************/ + +static boole CVAllocVectors(CVodeMem cv_mem, integer neq, int maxord, + void *machEnv) +{ + int i, j; + + /* Allocate ewt, acor, tempv, ftemp */ + + ewt = N_VNew(neq, machEnv); + if (ewt == NULL) return(FALSE); + acor = N_VNew(neq, machEnv); + if (acor == NULL) { + N_VFree(ewt); + return(FALSE); + } + tempv = N_VNew(neq, machEnv); + if (tempv == NULL) { + N_VFree(ewt); + N_VFree(acor); + return(FALSE); + } + ftemp = N_VNew(neq, machEnv); + if (ftemp == NULL) { + N_VFree(tempv); + N_VFree(ewt); + N_VFree(acor); + return(FALSE); + } + + /* Allocate zn[0] ... zn[maxord] */ + + for (j=0; j <= maxord; j++) { + zn[j] = N_VNew(neq, machEnv); + if (zn[j] == NULL) { + N_VFree(ewt); + N_VFree(acor); + N_VFree(tempv); + N_VFree(ftemp); + for (i=0; i < j; i++) N_VFree(zn[i]); + return(FALSE); + } + } + + /* Set solver workspace lengths */ + + lrw = (maxord + 5)*neq; + liw = 0; + + return(TRUE); +} + +/***************** CVFreeVectors ********************************* + + This routine frees the CVODE vectors allocated in CVAllocVectors. + +******************************************************************/ + +static void CVFreeVectors(CVodeMem cv_mem, int maxord) +{ + int j; + + N_VFree(ewt); + N_VFree(acor); + N_VFree(tempv); + N_VFree(ftemp); + for(j=0; j <= maxord; j++) N_VFree(zn[j]); +} + +/*********************** CVEwtSet ************************************** + + This routine is responsible for setting the error weight vector ewt, + according to tol_type, as follows: + + (1) ewt[i] = 1 / (*rtol * ABS(ycur[i]) + *atol), i=0,...,neq-1 + if tol_type = SS + (2) ewt[i] = 1 / (*rtol * ABS(ycur[i]) + atol[i]), i=0,...,neq-1 + if tol_type = SV + + CVEwtSet returns TRUE if ewt is successfully set as above to a + positive vector and FALSE otherwise. In the latter case, ewt is + considered undefined after the FALSE return from CVEwtSet. + + All the real work is done in the routines CVEwtSetSS, CVEwtSetSV. + +***********************************************************************/ + +static boole CVEwtSet(CVodeMem cv_mem, real *rtol, void *atol, int tol_type, + N_Vector ycur, integer neq) +{ + switch(tol_type) { + case SS: return(CVEwtSetSS(cv_mem, rtol, (real *)atol, ycur, neq)); + case SV: return(CVEwtSetSV(cv_mem, rtol, (N_Vector)atol, ycur, neq)); + } +} + +/*********************** CVEwtSetSS ********************************* + + This routine sets ewt as decribed above in the case tol_type = SS. + It tests for non-positive components before inverting. CVEwtSetSS + returns TRUE if ewt is successfully set to a positive vector + and FALSE otherwise. In the latter case, ewt is considered + undefined after the FALSE return from CVEwtSetSS. + +********************************************************************/ + +static boole CVEwtSetSS(CVodeMem cv_mem, real *rtol, real *atol, + N_Vector ycur, integer neq) +{ + real rtoli, atoli; + + rtoli = *rtol; + atoli = *atol; + N_VAbs(ycur, tempv); + N_VScale(rtoli, tempv, tempv); + N_VAddConst(tempv, atoli, tempv); + if (N_VMin(tempv) <= ZERO) return(FALSE); + N_VInv(tempv, ewt); + return(TRUE); +} + +/*********************** CVEwtSetSV ********************************* + + This routine sets ewt as decribed above in the case tol_type = SV. + It tests for non-positive components before inverting. CVEwtSetSV + returns TRUE if ewt is successfully set to a positive vector + and FALSE otherwise. In the latter case, ewt is considered + undefined after the FALSE return from CVEwtSetSV. + +********************************************************************/ + +static boole CVEwtSetSV(CVodeMem cv_mem, real *rtol, N_Vector atol, + N_Vector ycur, integer neq) +{ + real rtoli; + + rtoli = *rtol; + N_VAbs(ycur, tempv); + N_VLinearSum(rtoli, tempv, ONE, atol, tempv); + if (N_VMin(tempv) <= ZERO) return(FALSE); + N_VInv(tempv, ewt); + return(TRUE); +} + +/******************* CVHin *************************************** + + This routine computes a tentative initial step size h0. + If tout is too close to tn (= t0), then CVHin returns FALSE and + h remains uninitialized. Otherwise, CVHin sets h to the chosen + value h0 and returns TRUE. + + The algorithm used seeks to find h0 as a solution of + (WRMS norm of (h0^2 ydd / 2)) = 1, + where ydd = estimated second derivative of y. + +*****************************************************************/ + +static boole CVHin(CVodeMem cv_mem, real tout) +{ + int sign, count; + real tdiff, tdist, tround, hlb, hub; + real hg, hgs, hnew, hrat, h0, yddnrm; + + /* Test for tout too close to tn */ + + if ((tdiff = tout-tn) == ZERO) return(FALSE); + + sign = (tdiff > ZERO) ? 1 : -1; + tdist = ABS(tdiff); + tround = uround * MAX(ABS(tn), ABS(tout)); + if (tdist < TWO*tround) return(FALSE); + + /* Set lower and upper bounds on h0, and take geometric mean + Exit with this value if the bounds cross each other */ + + hlb = HLB_FACTOR * tround; + hub = CVUpperBoundH0(cv_mem, tdist); + hg = RSqrt(hlb*hub); + if (hub < hlb) { + if (sign == -1) hg = -hg; + h = hg; + return(TRUE); + } + + /* Loop up to MAX_ITERS times to find h0. + Stop if new and previous values differ by a factor < 2. + Stop if hnew/hg > 2 after one iteration, as this probably means + that the ydd value is bad because of cancellation error. */ + + count = 0; + loop { + hgs = hg*sign; + yddnrm = CVYddNorm(cv_mem, hgs); + hnew = (yddnrm*hub*hub > TWO) ? RSqrt(TWO/yddnrm) : RSqrt(hg*hub); + count++; + if (count >= MAX_ITERS) break; + hrat = hnew/hg; + if ((hrat > HALF) && (hrat < TWO)) break; + if ((count >= 2) && (hrat > TWO)) { + hnew = hg; + break; + } + hg = hnew; + } + + /* Apply bounds, bias factor, and attach sign */ + + h0 = H_BIAS*hnew; + if (h0 < hlb) h0 = hlb; + if (h0 > hub) h0 = hub; + if (sign == -1) h0 = -h0; + h = h0; + return(TRUE); +} + +/******************** CVUpperBoundH0 ****************************** + + This routine sets an upper bound on abs(h0) based on + tdist = tn - t0 and the values of y[i]/y'[i]. + +******************************************************************/ + +static real CVUpperBoundH0(CVodeMem cv_mem, real tdist) +{ + real atoli, hub_inv, hub; + boole vectorAtol; + N_Vector temp1, temp2; + + vectorAtol = (itol == SV); + if (!vectorAtol) atoli = *((real *) abstol); + temp1 = tempv; + temp2 = acor; + N_VAbs(zn[0], temp1); + N_VAbs(zn[1], temp2); + if (vectorAtol) { + N_VLinearSum(HUB_FACTOR, temp1, ONE, (N_Vector)abstol, temp1); + } else { + N_VScale(HUB_FACTOR, temp1, temp1); + N_VAddConst(temp1, atoli, temp1); + } + N_VDiv(temp2, temp1, temp1); + hub_inv = N_VMaxNorm(temp1); + hub = HUB_FACTOR*tdist; + if (hub*hub_inv > ONE) hub = ONE/hub_inv; + return(hub); +} + +/****************** CVYddNorm ************************************* + + This routine computes an estimate of the second derivative of y + using a difference quotient, and returns its WRMS norm. + +******************************************************************/ + +static real CVYddNorm(CVodeMem cv_mem, real hg) +{ + real yddnrm; + + N_VLinearSum(hg, zn[1], ONE, zn[0], y); + f(N, tn+hg, y, tempv, f_data); + nfe++; + N_VLinearSum(ONE, tempv, -ONE, zn[1], tempv); + N_VScale(ONE/hg, tempv, tempv); + + yddnrm = N_VWrmsNorm(tempv, ewt); + return(yddnrm); +} + +/********************* CVStep ************************************** + + This routine performs one internal cvode step, from tn to tn + h. + It calls other routines to do all the work. + + The main operations done here are as follows: + * preliminary adjustments if a new step size was chosen; + * prediction of the Nordsieck history array zn at tn + h; + * setting of multistep method coefficients and test quantities; + * solution of the nonlinear system; + * testing the local error; + * updating zn and other state data if successful; + * resetting stepsize and order for the next step. + + On a failure in the nonlinear system solution or error test, the + step may be reattempted, depending on the nature of the failure. + +********************************************************************/ + +static int CVStep(CVodeMem cv_mem) +{ + real saved_t, dsm; + int ncf, nef, nflag, kflag; + boole passed; + + saved_t = tn; + ncf = nef = 0; + nflag = FIRST_CALL; + + if ((nst > 0) && (hprime != h)) CVAdjustParams(cv_mem); + + /* Looping point for attempts to take a step */ + loop { + CVPredict(cv_mem); + CVSet(cv_mem); + + nflag = CVnls(cv_mem, nflag); + kflag = CVHandleNFlag(cv_mem, &nflag, saved_t, &ncf); + if (kflag == PREDICT_AGAIN) continue; + if (kflag != DO_ERROR_TEST) return(kflag); + /* Return if nonlinear solve failed and recovery not possible. */ + + passed = CVDoErrorTest(cv_mem, &nflag, &kflag, saved_t, &nef, &dsm); + if ((!passed) && (kflag == REP_ERR_FAIL)) return(kflag); + /* Return if error test failed and recovery not possible. */ + if (passed) break; + /* Retry step if error test failed, nflag == PREV_ERR_FAIL */ + } + + /* Nonlinear system solve and error test were both successful; + update data, and consider change of step and/or order */ + + CVCompleteStep(cv_mem); + CVPrepareNextStep(cv_mem, dsm); + + return(SUCCESS_STEP); +} + +/********************* CVAdjustParams ******************************** + + This routine is called when a change in step size was decided upon, + and it handles the required adjustments to the history array zn. + If there is to be a change in order, we call CVAdjustOrder and reset + q, L = q+1, and qwait. Then in any case, we call CVRescale, which + resets h and rescales the Nordsieck array. + +**********************************************************************/ + +static void CVAdjustParams(CVodeMem cv_mem) +{ + if (qprime != q) { + CVAdjustOrder(cv_mem, qprime-q); + q = qprime; + L = q+1; + qwait = L; + } + CVRescale(cv_mem); +} + +/********************* CVAdjustOrder ***************************** + + This routine is a high level routine which handles an order + change by an amount deltaq (= +1 or -1). If a decrease in order + is requested and q==2, then the routine returns immediately. + Otherwise CVAdjustAdams or CVAdjustBDF is called to handle the + order change (depending on the value of lmm). + +******************************************************************/ + +static void CVAdjustOrder(CVodeMem cv_mem, int deltaq) +{ + if ((q==2) && (deltaq != 1)) return; + + switch(lmm){ + case ADAMS: CVAdjustAdams(cv_mem, deltaq); + break; + case BDF: CVAdjustBDF(cv_mem, deltaq); + break; + } +} + +/*************** CVAdjustAdams *********************************** + + This routine adjusts the history array on a change of order q by + deltaq, in the case that lmm == ADAMS. + +*****************************************************************/ + +static void CVAdjustAdams(CVodeMem cv_mem, int deltaq) +{ + int i, j; + real xi, hsum; + + /* On an order increase, set new column of zn to zero and return */ + + if (deltaq==1) { + N_VConst(ZERO, zn[L]); + return; + } + + /* On an order decrease, each zn[j] is adjusted by a multiple + of zn[q]. The coefficients in the adjustment are the + coefficients of the polynomial x*x*(x+xi_1)*...*(x+xi_j), + integrated, where xi_j = [t_n - t_(n-j)]/h. */ + + for (i=0; i <= qmax; i++) l[i] = ZERO; + l[1] = ONE; + hsum = ZERO; + for (j=1; j <= q-2; j++) { + hsum += tau[j]; + xi = hsum / hscale; + for (i=j+1; i >= 1; i--) l[i] = l[i]*xi + l[i-1]; + } + + for (j=1; j <= q-2; j++) l[j+1] = q * (l[j] / (j+1)); + + for (j=2; j < q; j++) + N_VLinearSum(-l[j], zn[q], ONE, zn[j], zn[j]); +} + +/********************** CVAdjustBDF ******************************* + + This is a high level routine which handles adjustments to the + history array on a change of order by deltaq in the case that + lmm == BDF. CVAdjustBDF calls CVIncreaseBDF if deltaq = +1 and + CVDecreaseBDF if deltaq = -1 to do the actual work. + +******************************************************************/ + +static void CVAdjustBDF(CVodeMem cv_mem, int deltaq) +{ + switch(deltaq) { + case 1 : CVIncreaseBDF(cv_mem); + return; + case -1: CVDecreaseBDF(cv_mem); + return; + } +} + +/******************** CVIncreaseBDF ********************************** + + This routine adjusts the history array on an increase in the + order q in the case that lmm == BDF. + A new column zn[q+1] is set equal to a multiple of the saved + vector (= acor) in zn[qmax]. Then each zn[j] is adjusted by + a multiple of zn[q+1]. The coefficients in the adjustment are the + coefficients of the polynomial x*x*(x+xi_1)*...*(x+xi_j), + where xi_j = [t_n - t_(n-j)]/h. + +*********************************************************************/ + +static void CVIncreaseBDF(CVodeMem cv_mem) +{ + real alpha0, alpha1, prod, xi, xiold, hsum, A1; + int i, j; + + for (i=0; i <= qmax; i++) l[i] = ZERO; + l[2] = alpha1 = prod = xiold = ONE; + alpha0 = -ONE; + hsum = hscale; + if (q > 1) { + for (j=1; j < q; j++) { + hsum += tau[j+1]; + xi = hsum / hscale; + prod *= xi; + alpha0 -= ONE / (j+1); + alpha1 += ONE / xi; + for (i=j+2; i >= 2; i--) l[i] = l[i]*xiold + l[i-1]; + xiold = xi; + } + } + A1 = (-alpha0 - alpha1) / prod; + N_VScale(A1, zn[qmax], zn[L]); + for (j=2; j <= q; j++) { + N_VLinearSum(l[j], zn[L], ONE, zn[j], zn[j]); + } +} + +/********************* CVDecreaseBDF ****************************** + + This routine adjusts the history array on a decrease in the + order q in the case that lmm == BDF. + Each zn[j] is adjusted by a multiple of zn[q]. The coefficients + in the adjustment are the coefficients of the polynomial + x*x*(x+xi_1)*...*(x+xi_j), where xi_j = [t_n - t_(n-j)]/h. + +******************************************************************/ + +static void CVDecreaseBDF(CVodeMem cv_mem) +{ + real hsum, xi; + int i, j; + + for (i=0; i <= qmax; i++) l[i] = ZERO; + l[2] = ONE; + hsum = ZERO; + for(j=1; j <= q-2; j++) { + hsum += tau[j]; + xi = hsum /hscale; + for (i=j+2; i >= 2; i--) l[i] = l[i]*xi + l[i-1]; + } + + for(j=2; j < q; j++) + N_VLinearSum(-l[j], zn[q], ONE, zn[j], zn[j]); +} + +/**************** CVRescale *********************************** + + This routine rescales the Nordsieck array by multiplying the + jth column zn[j] by eta^j, j = 1, ..., q. Then the value of + h is rescaled by eta, and hscale is reset to h. + +***************************************************************/ + +static void CVRescale(CVodeMem cv_mem) +{ + int j; + real factor; + + factor = eta; + for (j=1; j <= q; j++) { + N_VScale(factor, zn[j], zn[j]); + factor *= eta; + } + h = hscale * eta; + hscale = h; +} + +/********************* CVPredict ************************************* + + This routine advances tn by the tentative step size h, and computes + the predicted array z_n(0), which is overwritten on zn. The + prediction of zn is done by repeated additions. + +*********************************************************************/ + +static void CVPredict(CVodeMem cv_mem) +{ + int j, k; + + tn += h; + for (k = 1; k <= q; k++) + for (j = q; j >= k; j--) + N_VLinearSum(ONE, zn[j-1], ONE, zn[j], zn[j-1]); +} + +/************************** CVSet ********************************* + + This routine is a high level routine which calls CVSetAdams or + CVSetBDF to set the polynomial l, the test quantity array tq, + and the related variables rl1, gamma, and gamrat. + +******************************************************************/ + +static void CVSet(CVodeMem cv_mem) +{ + switch(lmm) { + case ADAMS: CVSetAdams(cv_mem); + break; + case BDF : CVSetBDF(cv_mem); + break; + } + rl1 = ONE / l[1]; + gamma = h * rl1; + if (nst == 0) gammap = gamma; + gamrat = (nst > 0) ? gamma / gammap : ONE; /* protect x / x != 1.0 */ +} + +/******************** CVSetAdams ********************************* + + This routine handles the computation of l and tq for the + case lmm == ADAMS. + + The components of the array l are the coefficients of a + polynomial Lambda(x) = l_0 + l_1 x + ... + l_q x^q, given by + q-1 + (d/dx) Lambda(x) = c * PRODUCT (1 + x / xi_i) , where + i=1 + Lambda(-1) = 0, Lambda(0) = 1, and c is a normalization factor. + Here xi_i = [t_n - t_(n-i)] / h. + + The array tq is set to test quantities used in the convergence + test, the error test, and the selection of h at a new order. + +*****************************************************************/ + +static void CVSetAdams(CVodeMem cv_mem) +{ + real m[L_MAX], M[3], hsum; + + if (q == 1) { + l[0] = l[1] = tq[1] = tq[5] = ONE; + tq[2] = TWO; + tq[3] = TWELVE; + tq[4] = CORTES * tq[2]; /* = 0.1 * tq[2] */ + return; + } + + hsum = CVAdamsStart(cv_mem, m); + + M[0] = CVAltSum(q-1, m, 1); + M[1] = CVAltSum(q-1, m, 2); + + CVAdamsFinish(cv_mem, m, M, hsum); +} + +/****************** CVAdamsStart ******************************** + + This routine generates in m[] the coefficients of the product + polynomial needed for the Adams l and tq coefficients for q > 1. + +******************************************************************/ + +static real CVAdamsStart(CVodeMem cv_mem, real m[]) +{ + real hsum, xi_inv, sum; + int i, j; + + hsum = h; + m[0] = ONE; + for (i=1; i <= q; i++) m[i] = ZERO; + for (j=1; j < q; j++) { + if ((j==q-1) && (qwait == 1)) { + sum = CVAltSum(q-2, m, 2); + tq[1] = m[q-2] / (q * sum); + } + xi_inv = h / hsum; + for (i=j; i >= 1; i--) m[i] += m[i-1] * xi_inv; + hsum += tau[j]; + /* The m[i] are coefficients of product(1 to j) (1 + x/xi_i) */ + } + return(hsum); +} + +/****************** CVAdamsFinish ******************************* + + This routine completes the calculation of the Adams l and tq. + +******************************************************************/ + +static void CVAdamsFinish(CVodeMem cv_mem, real m[], real M[], real hsum) +{ + int i; + real M0_inv, xi, xi_inv; + + M0_inv = ONE / M[0]; + + l[0] = ONE; + for (i=1; i <= q; i++) l[i] = M0_inv * (m[i-1] / i); + xi = hsum / h; + xi_inv = ONE / xi; + + tq[2] = xi * M[0] / M[1]; + tq[5] = xi / l[q]; + + if (qwait == 1) { + for (i=q; i >= 1; i--) m[i] += m[i-1] * xi_inv; + M[2] = CVAltSum(q, m, 2); + tq[3] = L * M[0] / M[2]; + } + + tq[4] = CORTES * tq[2]; +} + +/****************** CVAltSum ************************************** + + CVAltSum returns the value of the alternating sum + sum (i= 0 ... iend) [ (-1)^i * (a[i] / (i + k)) ]. + If iend < 0 then CVAltSum returns 0. + This operation is needed to compute the integral, from -1 to 0, + of a polynomial x^(k-1) M(x) given the coefficients of M(x). + +******************************************************************/ + +static real CVAltSum(int iend, real a[], int k) +{ + int i, sign; + real sum; + + if (iend < 0) return(ZERO); + + sum = ZERO; + sign = 1; + for (i=0; i <= iend; i++) { + sum += sign * (a[i] / (i+k)); + sign = -sign; + } + return(sum); +} + +/***************** CVSetBDF ************************************** + + This routine computes the coefficients l and tq in the case + lmm == BDF. CVSetBDF calls CVSetTqBDF to set the test + quantity array tq. + + The components of the array l are the coefficients of a + polynomial Lambda(x) = l_0 + l_1 x + ... + l_q x^q, given by + q-1 + Lambda(x) = (1 + x / xi*_q) * PRODUCT (1 + x / xi_i) , where + i=1 + xi_i = [t_n - t_(n-i)] / h. + + The array tq is set to test quantities used in the convergence + test, the error test, and the selection of h at a new order. + + +*****************************************************************/ + +static void CVSetBDF(CVodeMem cv_mem) +{ + real alpha0, alpha0_hat, xi_inv, xistar_inv, hsum; + int i,j; + + l[0] = l[1] = xi_inv = xistar_inv = ONE; + for (i=2; i <= q; i++) l[i] = ZERO; + alpha0 = alpha0_hat = -ONE; + hsum = h; + if (q > 1) { + for (j=2; j < q; j++) { + hsum += tau[j-1]; + xi_inv = h / hsum; + alpha0 -= ONE / j; + for(i=j; i >= 1; i--) l[i] += l[i-1]*xi_inv; + /* The l[i] are coefficients of product(1 to j) (1 + x/xi_i) */ + } + + /* j = q */ + alpha0 -= ONE / q; + xistar_inv = -l[1] - alpha0; + hsum += tau[q-1]; + xi_inv = h / hsum; + alpha0_hat = -l[1] - xi_inv; + for (i=q; i >= 1; i--) l[i] += l[i-1]*xistar_inv; + } + + CVSetTqBDF(cv_mem, hsum, alpha0, alpha0_hat, xi_inv, xistar_inv); +} + +/****************** CVSetTqBDF ************************************ + + This routine sets the test quantity array tq in the case + lmm == BDF. + +******************************************************************/ + +static void CVSetTqBDF(CVodeMem cv_mem, real hsum, real alpha0, + real alpha0_hat, real xi_inv, real xistar_inv) +{ + real A1, A2, A3, A4, A5, A6; + real C, CPrime, CPrimePrime; + + A1 = ONE - alpha0_hat + alpha0; + A2 = ONE + q * A1; + tq[2] = ABS(alpha0 * (A2 / A1)); + tq[5] = ABS((A2) / (l[q] * xi_inv/xistar_inv)); + if (qwait == 1) { + C = xistar_inv / l[q]; + A3 = alpha0 + ONE / q; + A4 = alpha0_hat + xi_inv; + CPrime = A3 / (ONE - A4 + A3); + tq[1] = ABS(CPrime / C); + hsum += tau[q]; + xi_inv = h / hsum; + A5 = alpha0 - (ONE / (q+1)); + A6 = alpha0_hat - xi_inv; + CPrimePrime = A2 / (ONE - A6 + A5); + tq[3] = ABS(CPrimePrime * xi_inv * (q+2) * A5); + } + tq[4] = CORTES * tq[2]; +} + +/****************** CVnls ***************************************** + + This routine attempts to solve the nonlinear system associated + with a single implicit step of the linear multistep method. + Depending on iter, it calls CVnlsFunctional or CVnlsNewton + to do the work. + +******************************************************************/ + +static int CVnls(CVodeMem cv_mem, int nflag) +{ + switch(iter) { + case FUNCTIONAL : return(CVnlsFunctional(cv_mem)); + case NEWTON : return(CVnlsNewton(cv_mem, nflag)); + } +} + +/***************** CVnlsFunctional ******************************** + + This routine attempts to solve the nonlinear system using + functional iteration (no matrices involved). + +******************************************************************/ + +static int CVnlsFunctional(CVodeMem cv_mem) +{ + int m; + real del, delp, dcon; + + /* Initialize counter and evaluate f at predicted y */ + + crate = ONE; + m = 0; + f(N, tn, zn[0], tempv, f_data); + nfe++; + N_VConst(ZERO, acor); + + /* Loop until convergence; accumulate corrections in acor */ + + loop { + /* Correct y directly from the last f value */ + N_VLinearSum(h, tempv, -ONE, zn[1], tempv); + N_VScale(rl1, tempv, tempv); + N_VLinearSum(ONE, zn[0], ONE, tempv, y); + /* Get WRMS norm of current correction to use in convergence test */ + N_VLinearSum(ONE, tempv, -ONE, acor, acor); + del = N_VWrmsNorm(acor, ewt); + N_VScale(ONE, tempv, acor); + + /* Test for convergence. If m > 0, an estimate of the convergence + rate constant is stored in crate, and used in the test. */ + if (m > 0) crate = MAX(CRDOWN * crate, del / delp); + dcon = del * MIN(ONE, crate) / tq[4]; + if (dcon <= ONE) { + acnrm = (m == 0) ? del : N_VWrmsNorm(acor, ewt); + return(SOLVED); /* Convergence achieved */ + } + + /* Stop at maxcor iterations or if iter. seems to be diverging */ + m++; + if ((m==maxcor) || ((m >= 2) && (del > RDIV * delp))) + return(CONV_FAIL); + /* Save norm of correction, evaluate f, and loop again */ + delp = del; + f(N, tn, y, tempv, f_data); + nfe++; + } +} + +/*********************** CVnlsNewton ********************************** + + This routine handles the Newton iteration. It calls lsetup if + indicated, calls CVNewtonIteration to perform the iteration, and + retries a failed attempt at Newton iteration if that is indicated. + See return values at top of this file. + +**********************************************************************/ + +static int CVnlsNewton(CVodeMem cv_mem, int nflag) +{ + N_Vector vtemp1, vtemp2, vtemp3; + int convfail, ier; + boole callSetup; + + vtemp1 = acor; /* rename acor as vtemp1 for readability */ + vtemp2 = y; /* rename y as vtemp2 for readability */ + vtemp3 = tempv; /* rename tempv as vtemp3 for readability */ + + /* Set flag convfail, input to lsetup for its evaluation decision */ + convfail = ((nflag == FIRST_CALL) || (nflag == PREV_ERR_FAIL)) ? + NO_FAILURES : FAIL_OTHER; + + /* Decide whether or not to call setup routine (if one exists) */ + if (setupNonNull) { + callSetup = (nflag == PREV_CONV_FAIL) || (nflag == PREV_ERR_FAIL) || + (nst == 0) || (nst >= nstlp + MSBP) || (ABS(gamrat-ONE) > DGMAX); + } else { + crate = ONE; + callSetup = FALSE; + } + + /* Looping point for the solution of the nonlinear system. + Evaluate f at the predicted y, call lsetup if indicated, and + call CVNewtonIteration for the Newton iteration itself. */ + + loop { + + f(N, tn, zn[0], ftemp, f_data); + nfe++; + + if (callSetup) { + ier = lsetup(cv_mem, convfail, zn[0], ftemp, &jcur, + vtemp1, vtemp2, vtemp3); + nsetups++; + callSetup = FALSE; + gamrat = crate = ONE; + gammap = gamma; + nstlp = nst; + /* Return if lsetup failed */ + if (ier < 0) return(SETUP_FAIL_UNREC); + if (ier > 0) return(CONV_FAIL); + } + + /* Set acor to zero and load prediction into y vector */ + N_VConst(ZERO, acor); + N_VScale(ONE, zn[0], y); + + /* Do the Newton iteration */ + ier = CVNewtonIteration(cv_mem); + + /* If there is a convergence failure and the Jacobian-related + data appears not to be current, loop again with a call to lsetup + in which convfail=FAIL_BAD_J. Otherwise return. */ + if (ier != TRY_AGAIN) return(ier); + + callSetup = TRUE; + convfail = FAIL_BAD_J; + } +} + +/********************** CVNewtonIteration **************************** + + This routine performs the Newton iteration. If the iteration succeeds, + it returns the value SOLVED. If not, it may signal the CVnlsNewton + routine to call lsetup again and reattempt the iteration, by + returning the value TRY_AGAIN. (In this case, CVnlsNewton must set + convfail to FAIL_BAD_J before calling setup again). + Otherwise, this routine returns one of the appropriate values + SOLVE_FAIL_UNREC or CONV_FAIL back to CVnlsNewton. + +*********************************************************************/ + +static int CVNewtonIteration(CVodeMem cv_mem) +{ + int m, ret; + real del, delp, dcon; + N_Vector b; + + + mnewt = m = 0; + + /* Looping point for Newton iteration */ + loop { + + /* Evaluate the residual of the nonlinear system*/ + N_VLinearSum(rl1, zn[1], ONE, acor, tempv); + N_VLinearSum(gamma, ftemp, -ONE, tempv, tempv); + + /* Call the lsolve function */ + b = tempv; + ret = lsolve(cv_mem, b, y, ftemp); + nni++; + + if (ret < 0) return(SOLVE_FAIL_UNREC); + + /* If lsolve had a recoverable failure and Jacobian data is + not current, signal to try the solution again */ + if (ret > 0) { + if ((!jcur) && (setupNonNull)) return(TRY_AGAIN); + return(CONV_FAIL); + } + + /* Get WRMS norm of correction; add correction to acor and y */ + del = N_VWrmsNorm(b, ewt); + N_VLinearSum(ONE, acor, ONE, b, acor); + N_VLinearSum(ONE, zn[0], ONE, acor, y); + + /* Test for convergence. If m > 0, an estimate of the convergence + rate constant is stored in crate, and used in the test. */ + if (m > 0) { + crate = MAX(CRDOWN * crate, del/delp); + } + dcon = del * MIN(ONE, crate) / tq[4]; + + if (dcon <= ONE) { + acnrm = (m==0) ? del : N_VWrmsNorm(acor, ewt); + jcur = FALSE; + return(SOLVED); /* Nonlinear system was solved successfully */ + } + + mnewt = ++m; + + /* Stop at maxcor iterations or if iter. seems to be diverging. + If still not converged and Jacobian data is not current, + signal to try the solution again */ + if ((m == maxcor) || ((m >= 2) && (del > RDIV*delp))) { + if ((!jcur) && (setupNonNull)) return(TRY_AGAIN); + return(CONV_FAIL); + } + + /* Save norm of correction, evaluate f, and loop again */ + delp = del; + f(N, tn, y, ftemp, f_data); + nfe++; + } +} + +/********************** CVHandleNFlag ******************************* + + This routine takes action on the return value nflag = *nflagPtr + returned by CVnls, as follows: + + If CVnls succeeded in solving the nonlinear system, then + CVHandleNFlag returns the constant DO_ERROR_TEST, which tells CVStep + to perform the error test. + + If the nonlinear system was not solved successfully, then ncfn and + ncf = *ncfPtr are incremented and Nordsieck array zn is restored. + + If the solution of the nonlinear system failed due to an + unrecoverable failure by setup, we return the value SETUP_FAILED. + + If it failed due to an unrecoverable failure in solve, then we return + the value SOLVE_FAILED. + + Otherwise, a recoverable failure occurred when solving the + nonlinear system (CVnls returned nflag == CONV_FAIL). + In this case, we return the value REP_CONV_FAIL if ncf is now + equal to MXNCF or |h| = hmin. + If not, we set *nflagPtr = PREV_CONV_FAIL and return the value + PREDICT_AGAIN, telling CVStep to reattempt the step. + +*********************************************************************/ + +static int CVHandleNFlag(CVodeMem cv_mem, int *nflagPtr, real saved_t, + int *ncfPtr) +{ + int nflag; + + nflag = *nflagPtr; + + if (nflag == SOLVED) return(DO_ERROR_TEST); + + /* The nonlinear soln. failed; increment ncfn and restore zn */ + ncfn++; + CVRestore(cv_mem, saved_t); + + /* Return if lsetup or lsolve failed unrecoverably */ + if (nflag == SETUP_FAIL_UNREC) return(SETUP_FAILED); + if (nflag == SOLVE_FAIL_UNREC) return(SOLVE_FAILED); + + /* At this point, nflag == CONV_FAIL; increment ncf */ + + (*ncfPtr)++; + etamax = ONE; + /* If we had MXNCF failures or |h| = hmin, return REP_CONV_FAIL */ + if ((ABS(h) <= hmin*ONEPSM) || (*ncfPtr == MXNCF)) + return(REP_CONV_FAIL); + + /* Reduce step size; return to reattempt the step */ + eta = MAX(ETACF, hmin / ABS(h)); + *nflagPtr = PREV_CONV_FAIL; + CVRescale(cv_mem); + return(PREDICT_AGAIN); +} + +/********************** CVRestore ************************************ + + This routine restores the value of tn to saved_t and undoes the + prediction. After execution of CVRestore, the Nordsieck array zn has + the same values as before the call to CVPredict. + +********************************************************************/ + +static void CVRestore(CVodeMem cv_mem, real saved_t) +{ + int j, k; + + tn = saved_t; + for (k = 1; k <= q; k++) + for (j = q; j >= k; j--) + N_VLinearSum(ONE, zn[j-1], -ONE, zn[j], zn[j-1]); +} + +/******************* CVDoErrorTest ******************************** + + This routine performs the local error test. + The weighted local error norm dsm is loaded into *dsmPtr, and + the test dsm ?<= 1 is made. + + If the test passes, CVDoErrorTest returns TRUE. + + If the test fails, we undo the step just taken (call CVRestore), + set *nflagPtr to PREV_ERR_FAIL, and return FALSE. + + If MXNEF error test failures have occurred or if ABS(h) = hmin, + we set *kflagPtr = REP_ERR_FAIL. (Otherwise *kflagPtr has the + value last returned by CVHandleNflag.) + + If more than MXNEF1 error test failures have occurred, an order + reduction is forced. + +******************************************************************/ + +static boole CVDoErrorTest(CVodeMem cv_mem, int *nflagPtr, int *kflagPtr, + real saved_t, int *nefPtr, real *dsmPtr) +{ + real dsm; + + dsm = acnrm / tq[2]; + + /* If est. local error norm dsm passes test, return TRUE */ + *dsmPtr = dsm; + if (dsm <= ONE) return(TRUE); + + /* Test failed; increment counters, set nflag, and restore zn array */ + (*nefPtr)++; + netf++; + *nflagPtr = PREV_ERR_FAIL; + CVRestore(cv_mem, saved_t); + + /* At MXNEF failures or |h| = hmin, return with kflag = REP_ERR_FAIL */ + if ((ABS(h) <= hmin*ONEPSM) || (*nefPtr == MXNEF)) { + *kflagPtr = REP_ERR_FAIL; + return(FALSE); + } + + /* Set etamax = 1 to prevent step size increase at end of this step */ + etamax = ONE; + + /* Set h ratio eta from dsm, rescale, and return for retry of step */ + if (*nefPtr <= MXNEF1) { + eta = ONE / (RPowerR(BIAS2*dsm,ONE/L) + ADDON); + eta = MAX(ETAMIN, MAX(eta, hmin / ABS(h))); + if (*nefPtr >= SMALL_NEF) eta = MIN(eta, ETAMXF); + CVRescale(cv_mem); + return(FALSE); + } + + /* After MXNEF1 failures, force an order reduction and retry step */ + if (q > 1) { + eta = MAX(ETAMIN, hmin / ABS(h)); + CVAdjustOrder(cv_mem,-1); + L = q; + q--; + qwait = L; + CVRescale(cv_mem); + return(FALSE); + } + + /* If already at order 1, restart: reload zn from scratch */ + eta = MAX(ETAMIN, hmin / ABS(h)); + h *= eta; + hscale = h; + qwait = LONG_WAIT; + f(N, tn, zn[0], tempv, f_data); + nfe++; + N_VScale(h, tempv, zn[1]); + return(FALSE); +} + +/*************** CVCompleteStep ********************************** + + This routine performs various update operations when the solution + to the nonlinear system has passed the local error test. + We increment the step counter nst, record the values hu and qu, + update the tau array, and apply the corrections to the zn array. + The tau[i] are the last q values of h, with tau[1] the most recent. + The counter qwait is decremented, and if qwait == 1 (and q < qmax) + we save acor and tq[5] for a possible order increase. + +******************************************************************/ + +static void CVCompleteStep(CVodeMem cv_mem) +{ + int i, j; + + nst++; + hu = h; + qu = q; + + for (i=q; i >= 2; i--) tau[i] = tau[i-1]; + if ((q==1) && (nst > 1)) tau[2] = tau[1]; + tau[1] = h; + + for (j=0; j <= q; j++) + N_VLinearSum(l[j], acor, ONE, zn[j], zn[j]); + qwait--; + if ((qwait == 1) && (q != qmax)) { + N_VScale(ONE, acor, zn[qmax]); + saved_tq5 = tq[5]; + } +} + +/************* CVPrepareNextStep ********************************** + + This routine handles the setting of stepsize and order for the + next step -- hprime and qprime. Along with hprime, it sets the + ratio eta = hprime/h. It also updates other state variables + related to a change of step size or order. Finally, we rescale + the acor array to be the estimated local error vector. + +******************************************************************/ + +static void CVPrepareNextStep(CVodeMem cv_mem, real dsm) +{ + real etaqm1, etaq, etaqp1; + + /* If etamax = 1, defer step size or order changes */ + if (etamax == ONE) { + qwait = MAX(qwait, 2); + qprime = q; + hprime = h; + eta = ONE; + etamax = (nst <= SMALL_NST) ? ETAMX2 : ETAMX3; + N_VScale(ONE/tq[2], acor, acor); + return; + } + + /* etaq is the ratio of new to old h at the current order */ + etaq = ONE /(RPowerR(BIAS2*dsm,ONE/L) + ADDON); + + /* If no order change, adjust eta and acor in CVSetEta and return */ + if (qwait != 0) { + eta = etaq; + qprime = q; + CVSetEta(cv_mem); + return; + } + + /* If qwait = 0, consider an order change. etaqm1 and etaqp1 are + the ratios of new to old h at orders q-1 and q+1, respectively. + CVChooseEta selects the largest; CVSetEta adjusts eta and acor */ + qwait = 2; + etaqm1 = CVComputeEtaqm1(cv_mem); + etaqp1 = CVComputeEtaqp1(cv_mem); + CVChooseEta(cv_mem, etaqm1, etaq, etaqp1); + CVSetEta(cv_mem); +} + +/***************** CVSetEta *************************************** + + This routine adjusts the value of eta according to the various + heuristic limits and the optional input hmax. It also resets + etamax and rescales acor to be the estimated local error vector. + +*******************************************************************/ + +static void CVSetEta(CVodeMem cv_mem) +{ + + /* If eta below the threshhold THRESH, reject a change of step size */ + if (eta < THRESH) { + eta = ONE; + hprime = h; + } else { + /* Limit eta by etamax and hmax, then set hprime */ + eta = MIN(eta, etamax); + eta /= MAX(ONE, ABS(h)*hmax_inv*eta); + hprime = h * eta; + /* printf(" hmax, h = %10.5f %10.5f \n", 1.0/hmax_inv, h); dgg */ + } + + /* Reset etamx for the next step size change, and scale acor */ + etamax = (nst <= SMALL_NST) ? ETAMX2 : ETAMX3; + N_VScale(ONE/tq[2], acor, acor); +} + +/*************** CVComputeEtaqm1 ********************************** + + This routine computes and returns the value of etaqm1 for a + possible decrease in order by 1. + +******************************************************************/ + +static real CVComputeEtaqm1(CVodeMem cv_mem) +{ + real etaqm1, ddn; + + etaqm1 = ZERO; + if (q > 1) { + ddn = N_VWrmsNorm(zn[q], ewt) / tq[1]; + etaqm1 = ONE/(RPowerR(BIAS1*ddn, ONE/q) + ADDON); + } + return(etaqm1); +} + +/*************** CVComputeEtaqp1 ********************************** + + This routine computes and returns the value of etaqp1 for a + possible increase in order by 1. + +******************************************************************/ + +static real CVComputeEtaqp1(CVodeMem cv_mem) +{ + real etaqp1, dup, cquot; + + etaqp1 = ZERO; + if (q != qmax) { + cquot = (tq[5] / saved_tq5) * RPowerI(h/tau[2], L); + N_VLinearSum(-cquot, zn[qmax], ONE, acor, tempv); + dup = N_VWrmsNorm(tempv, ewt) /tq[3]; + etaqp1 = ONE / (RPowerR(BIAS3*dup, ONE/(L+1)) + ADDON); + } + return(etaqp1); +} + +/******************* CVChooseEta ********************************** + + Given etaqm1, etaq, etaqp1 (the values of eta for qprime = + q - 1, q, or q + 1, respectively), this routine chooses the + maximum eta value, sets eta to that value, and sets qprime to the + corresponding value of q. If there is a tie, the preference + order is to (1) keep the same order, then (2) decrease the order, + and finally (3) increase the order. If the maximum eta value + is below the threshhold THRESH, the order is kept unchanged and + eta is set to 1. + +******************************************************************/ + +static void CVChooseEta(CVodeMem cv_mem, real etaqm1, real etaq, real etaqp1) +{ + real etam; + + etam = MAX(etaqm1, MAX(etaq, etaqp1)); + + if (etam < THRESH) { + eta = ONE; + qprime = q; + return; + } + + if (etam == etaq) { + eta = etaq; + qprime = q; + } else if (etam == etaqm1) { + eta = etaqm1; + qprime = q - 1; + } else { + eta = etaqp1; + qprime = q + 1; + N_VScale(ONE, acor, zn[qmax]); + } +} + +/****************** CVHandleFailure ****************************** + + This routine prints error messages for all cases of failure by + CVStep. It returns to CVode the value that CVode is to return to + the user. + +*****************************************************************/ + +static int CVHandleFailure(CVodeMem cv_mem, int kflag) +{ + + /* Set imxer to the index of maximum weighted local error */ + N_VProd(acor, ewt, tempv); + N_VAbs(tempv, tempv); + + /* Depending on kflag, print error message and return error flag */ + switch (kflag) { + case REP_ERR_FAIL: fprintf(errfp, MSG_ERR_FAILS, tn, h); + return(ERR_FAILURE); + case REP_CONV_FAIL: fprintf(errfp, MSG_CONV_FAILS, tn, h); + return(CONV_FAILURE); + case SETUP_FAILED: fprintf(errfp, MSG_SETUP_FAILED, tn); + return(SETUP_FAILURE); + case SOLVE_FAILED: fprintf(errfp, MSG_SOLVE_FAILED, tn); + return(SOLVE_FAILURE); + } +} + +/*******************************************************************/ +/********* END Private Helper Functions Implementation *************/ +/*******************************************************************/ + + +/***************************************************************/ +/************** END CVODE Implementation ***********************/ +/***************************************************************/ diff --git a/ext/cvode/source/cvspgmr.c b/ext/cvode/source/cvspgmr.c new file mode 100755 index 000000000..82155f6ad --- /dev/null +++ b/ext/cvode/source/cvspgmr.c @@ -0,0 +1,499 @@ +/****************************************************************** + * * + * File : cvspgmr.c * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 25 February 2000 * + *----------------------------------------------------------------* + * This is the implementation file for the CVODE scaled, * + * preconditioned GMRES linear solver, CVSPGMR. * + * * + ******************************************************************/ + + +#include +#include +#include "cvspgmr.h" +#include "cvode.h" +#include "llnltyps.h" +#include "nvector.h" +#include "llnlmath.h" +#include "iterativ.h" +#include "spgmr.h" + + +/* Error Messages */ + +#define CVSPGMR_INIT "CVSpgmrInit-- " + +#define MSG_MEM_FAIL CVSPGMR_INIT "A memory request failed.\n\n" + +#define MSG_BAD_PRETYPE_1 CVSPGMR_INIT "pretype=%d illegal.\n" +#define MSG_BAD_PRETYPE_2 "The legal values are NONE=%d, LEFT=%d, " +#define MSG_BAD_PRETYPE_3 "RIGHT=%d, and BOTH=%d.\n\n" +#define MSG_BAD_PRETYPE MSG_BAD_PRETYPE_1 MSG_BAD_PRETYPE_2 MSG_BAD_PRETYPE_3 + +#define MSG_PSOLVE_REQ_1 CVSPGMR_INIT "pretype!=NONE, but PSOLVE=NULL is " +#define MSG_PSOLVE_REQ_2 "illegal.\n\n" +#define MSG_PSOLVE_REQ MSG_PSOLVE_REQ_1 MSG_PSOLVE_REQ_2 + +#define MSG_BAD_GSTYPE_1 CVSPGMR_INIT "gstype=%d illegal.\n" +#define MSG_BAD_GSTYPE_2 "The legal values are MODIFIED_GS=%d and " +#define MSG_BAD_GSTYPE_3 "CLASSICAL_GS=%d.\n\n" +#define MSG_BAD_GSTYPE MSG_BAD_GSTYPE_1 MSG_BAD_GSTYPE_2 MSG_BAD_GSTYPE_3 + +/* Other Constants */ + +#define ZERO RCONST(0.0) +#define ONE RCONST(1.0) + +/****************************************************************** + * * + * Types : CVSpgmrMemRec, CVSpgmrMem * + *----------------------------------------------------------------* + * The type CVSpgmrMem is pointer to a CVSpgmrMemRec. This * + * structure contains CVSpgmr solver-specific data. * + * * + ******************************************************************/ + +typedef struct { + + int g_pretype; /* type of preconditioning */ + int g_gstype; /* type of Gram-Schmidt orthogonalization */ + real g_sqrtN; /* sqrt(N) */ + real g_delt; /* delt = user specified or DELT_DEFAULT */ + real g_deltar; /* deltar = delt * tq4 */ + real g_delta; /* delta = deltar * sqrtN */ + int g_maxl; /* maxl = maximum dimension of the Krylov space */ + + long int g_nstlpre; /* value of nst at the last precond call */ + long int g_npe; /* npe = total number of precond calls */ + long int g_nli; /* nli = total number of linear iterations */ + long int g_nps; /* nps = total number of psolve calls */ + long int g_ncfl; /* ncfl = total number of convergence failures */ + + N_Vector g_ytemp; /* temp vector used by CVAtimesDQ */ + N_Vector g_x; /* temp vector used by CVSpgmrSolve */ + N_Vector g_ycur; /* CVODE current y vector in Newton Iteration */ + N_Vector g_fcur; /* fcur = f(tn, ycur) */ + + CVSpgmrPrecondFn g_precond; /* precond = user-supplied routine to */ + /* compute a preconditioner */ + + CVSpgmrPSolveFn g_psolve; /* psolve = user-supplied routine to */ + /* solve preconditioner linear system */ + + void *g_P_data; /* P_data passed to psolve and precond */ + SpgmrMem g_spgmr_mem; /* spgmr_mem is memory used by the */ + /* generic Spgmr solver */ + +} CVSpgmrMemRec, *CVSpgmrMem; + + +/* CVSPGMR linit, lsetup, lsolve, and lfree routines */ + +static int CVSpgmrInit(CVodeMem cv_mem, boole *setupNonNull); + +static int CVSpgmrSetup(CVodeMem cv_mem, int convfail, N_Vector ypred, + N_Vector fpred, boole *jcurPtr, N_Vector vtemp1, + N_Vector vtemp2, N_Vector vtemp3); + +static int CVSpgmrSolve(CVodeMem cv_mem, N_Vector b, N_Vector ycur, + N_Vector fcur); + +static void CVSpgmrFree(CVodeMem cv_mem); + +/* CVSPGMR Atimes and PSolve routines called by generic SPGMR solver */ + +static int CVSpgmrAtimesDQ(void *cv_mem, N_Vector v, N_Vector z); + +static int CVSpgmrPSolve(void *cv_mem, N_Vector r, N_Vector z, int lr); + + +/* Readability Replacements */ + +#define N (cv_mem->cv_N) +#define uround (cv_mem->cv_uround) +#define tq (cv_mem->cv_tq) +#define nst (cv_mem->cv_nst) +#define tn (cv_mem->cv_tn) +#define h (cv_mem->cv_h) +#define gamma (cv_mem->cv_gamma) +#define gammap (cv_mem->cv_gammap) +#define nfe (cv_mem->cv_nfe) +#define f (cv_mem->cv_f) +#define f_data (cv_mem->cv_f_data) +#define ewt (cv_mem->cv_ewt) +#define errfp (cv_mem->cv_errfp) +#define mnewt (cv_mem->cv_mnewt) +#define iopt (cv_mem->cv_iopt) +#define ropt (cv_mem->cv_ropt) +#define linit (cv_mem->cv_linit) +#define lsetup (cv_mem->cv_lsetup) +#define lsolve (cv_mem->cv_lsolve) +#define lfree (cv_mem->cv_lfree) +#define lmem (cv_mem->cv_lmem) +#define machenv (cv_mem->cv_machenv) + +#define sqrtN (cvspgmr_mem->g_sqrtN) +#define ytemp (cvspgmr_mem->g_ytemp) +#define x (cvspgmr_mem->g_x) +#define ycur (cvspgmr_mem->g_ycur) +#define fcur (cvspgmr_mem->g_fcur) +#define delta (cvspgmr_mem->g_delta) +#define deltar (cvspgmr_mem->g_deltar) +#define npe (cvspgmr_mem->g_npe) +#define nli (cvspgmr_mem->g_nli) +#define nps (cvspgmr_mem->g_nps) +#define ncfl (cvspgmr_mem->g_ncfl) +#define nstlpre (cvspgmr_mem->g_nstlpre) +#define spgmr_mem (cvspgmr_mem->g_spgmr_mem) + + +/*************** CVSpgmr ********************************************* + + This routine initializes the memory record and sets various function + fields specific to the Spgmr linear solver module. CVSpgmr sets the + cv_linit, cv_lsetup, cv_lsolve, and cv_lfree fields in (*cvode_mem) + to be CVSpgmrInit, CVSpgmrSetup, CVSpgmrSolve, and CVSpgmrFree, + respectively. It allocates memory for a structure of type + CVSpgmrMemRec and sets the cv_lmem field in (*cvode_mem) to the + address of this structure. CVSpgmr sets the following fields in the + CVSpgmrMemRec structure: + + g_pretype = pretype + g_maxl = MIN(N,CVSPGMR_MAXL) if maxl <= 0 + = maxl if maxl > 0 + g_delt = CVSPGMR_DELT if delt == 0.0 + = delt if delt != 0.0 + g_P_data = P_data + g_precond = precond + g_psolve = psolve + +**********************************************************************/ + +void CVSpgmr(void *cvode_mem, int pretype, int gstype, int maxl, real delt, + CVSpgmrPrecondFn precond, CVSpgmrPSolveFn psolve, void *P_data) + +{ + CVodeMem cv_mem; + CVSpgmrMem cvspgmr_mem; + + /* Return immediately if cvode_mem is NULL */ + cv_mem = (CVodeMem) cvode_mem; + if (cv_mem == NULL) return; /* CVode reports this error */ + + /* Set four main function fields in cv_mem */ + linit = CVSpgmrInit; + lsetup = CVSpgmrSetup; + lsolve = CVSpgmrSolve; + lfree = CVSpgmrFree; + + /* Get memory for CVSpgmrMemRec */ + lmem = cvspgmr_mem = (CVSpgmrMem) malloc(sizeof(CVSpgmrMemRec)); + if (cvspgmr_mem == NULL) return; /* CVSpgmrInit reports this error */ + + /* Set Spgmr parameters that have been passed in call sequence */ + cvspgmr_mem->g_pretype = pretype; + cvspgmr_mem->g_gstype = gstype; + cvspgmr_mem->g_maxl = (maxl <= 0) ? MIN(CVSPGMR_MAXL, N) : maxl; + cvspgmr_mem->g_delt = (delt == ZERO) ? CVSPGMR_DELT : delt; + cvspgmr_mem->g_P_data = P_data; + cvspgmr_mem->g_precond = precond; + cvspgmr_mem->g_psolve = psolve; +} + + +/* Additional readability Replacements */ + +#define pretype (cvspgmr_mem->g_pretype) +#define gstype (cvspgmr_mem->g_gstype) +#define delt (cvspgmr_mem->g_delt) +#define maxl (cvspgmr_mem->g_maxl) +#define psolve (cvspgmr_mem->g_psolve) +#define precond (cvspgmr_mem->g_precond) +#define P_data (cvspgmr_mem->g_P_data) + + +/*************** CVSpgmrInit ***************************************** + + This routine initializes remaining memory specific to the Spgmr + linear solver. If any memory request fails, all memory previously + allocated is freed, and an error message printed, before returning. + +**********************************************************************/ + +static int CVSpgmrInit(CVodeMem cv_mem, boole *setupNonNull) +{ + CVSpgmrMem cvspgmr_mem; + + cvspgmr_mem = (CVSpgmrMem) lmem; + + /* Print error message and return if cvspgmr_mem is NULL */ + if (cvspgmr_mem == NULL) { + fprintf(errfp, MSG_MEM_FAIL); + return(LINIT_ERR); + } + + /* Check for legal pretype, precond, and psolve */ + if ((pretype != NONE) && (pretype != LEFT) && + (pretype != RIGHT) && (pretype != BOTH)) { + fprintf(errfp, MSG_BAD_PRETYPE, pretype, NONE, LEFT, RIGHT, BOTH); + return(LINIT_ERR); + } + if ((pretype != NONE) && (psolve == NULL)) { + fprintf(errfp, MSG_PSOLVE_REQ); + return(LINIT_ERR); + } + + /* Check for legal gstype */ + if ((gstype != MODIFIED_GS) && (gstype != CLASSICAL_GS)) { + fprintf(errfp, MSG_BAD_GSTYPE, gstype, MODIFIED_GS, CLASSICAL_GS); + return(LINIT_ERR); + } + + /* Allocate memory for ytemp and x */ + ytemp = N_VNew(N, machenv); + if (ytemp == NULL) { + fprintf(errfp, MSG_MEM_FAIL); + return(LINIT_ERR); + } + x = N_VNew(N, machenv); + if (x == NULL) { + fprintf(errfp, MSG_MEM_FAIL); + N_VFree(ytemp); + return(LINIT_ERR); + } + + /* Call SpgmrMalloc to allocate workspace for Spgmr */ + spgmr_mem = SpgmrMalloc(N, maxl, machenv); + if (spgmr_mem == NULL) { + fprintf(errfp, MSG_MEM_FAIL); + N_VFree(ytemp); + N_VFree(x); + return(LINIT_ERR); + } + + /* Initialize sqrtN and counters, and set workspace lengths */ + + sqrtN = RSqrt(N); + npe = nli = nps = ncfl = nstlpre = 0; + + if (iopt != NULL) { + iopt[SPGMR_NPE] = npe; + iopt[SPGMR_NLI] = nli; + iopt[SPGMR_NPS] = nps; + iopt[SPGMR_NCFL] = ncfl; + iopt[SPGMR_LRW] = N*(maxl + 5) + maxl*(maxl + 4) + 1; + iopt[SPGMR_LIW] = 0; + } + + /* Set setupNonNull to TRUE iff there is preconditioning */ + /* (pretype != NONE) and there is a preconditioning setup phase */ + /* (precond != NULL) */ + *setupNonNull = (pretype != NONE) && (precond != NULL); + + return(LINIT_OK); +} + +/*************** CVSpgmrSetup **************************************** + + This routine does the setup operations for the Spgmr linear solver. + It makes a decision as to whether or not to signal for re-evaluation + of Jacobian data in the precond routine, based on various state + variables, then it calls precond. If we signal for re-evaluation, + then we reset jcur = *jcurPtr to TRUE, regardless of the precond output. + In any case, if jcur == TRUE, we increment npe and save nst in nstlpre. + +**********************************************************************/ + +static int CVSpgmrSetup(CVodeMem cv_mem, int convfail, N_Vector ypred, + N_Vector fpred, boole *jcurPtr, N_Vector vtemp1, + N_Vector vtemp2, N_Vector vtemp3) +{ + boole jbad, jok; + real dgamma; + int ier; + CVSpgmrMem cvspgmr_mem; + + cvspgmr_mem = (CVSpgmrMem) lmem; + + /* Use nst, gamma/gammap, and convfail to set J eval. flag jok */ + dgamma = ABS((gamma/gammap) - ONE); + jbad = (nst == 0) || (nst > nstlpre + CVSPGMR_MSBPRE) || + ((convfail == FAIL_BAD_J) && (dgamma < CVSPGMR_DGMAX)) || + (convfail == FAIL_OTHER); + *jcurPtr = jbad; + jok = !jbad; + + /* Call precond routine and possibly reset jcur */ + ier = precond(N, tn, ypred, fpred, jok, jcurPtr, gamma, ewt, h, + uround, &nfe, P_data, vtemp1, vtemp2, vtemp3); + if (jbad) *jcurPtr = TRUE; + + /* If jcur = TRUE, increment npe and save nst value */ + if (*jcurPtr) { + npe++; + nstlpre = nst; + } + + /* Set npe, and return the same value ier that precond returned */ + if (iopt != NULL) iopt[SPGMR_NPE] = npe; + return(ier); +} + +/*************** CVSpgmrSolve **************************************** + + This routine handles the call to the generic solver SpgmrSolve + for the solution of the linear system Ax = b with the SPGMR method, + without restarts. The solution x is returned in the vector b. + + If the WRMS norm of b is small, we return x = b (if this is the first + Newton iteration) or x = 0 (if a later Newton iteration). + + Otherwise, we set the tolerance parameter and initial guess (x = 0), + call SpgmrSolve, and copy the solution x into b. The x-scaling and + b-scaling arrays are both equal to ewt, and no restarts are allowed. + + The counters nli, nps, and ncfl are incremented, and the return value + is set according to the success of SpgmrSolve. The success flag is + returned if SpgmrSolve converged, or if this is the first Newton + iteration and the residual norm was reduced below its initial value. + +**********************************************************************/ + +static int CVSpgmrSolve(CVodeMem cv_mem, N_Vector b, N_Vector ynow, + N_Vector fnow) +{ + real bnorm, res_norm; + CVSpgmrMem cvspgmr_mem; + int nli_inc, nps_inc, ier; + + cvspgmr_mem = (CVSpgmrMem) lmem; + + /* Test norm(b); if small, return x = 0 or x = b */ + deltar = delt*tq[4]; + bnorm = N_VWrmsNorm(b, ewt); + if (bnorm <= deltar) { + if (mnewt > 0) N_VConst(ZERO, b); + return(0); + } + + /* Set vectors ycur and fcur for use by the Atimes and Psolve routines */ + ycur = ynow; + fcur = fnow; + + /* Set inputs delta and initial guess x = 0 to SpgmrSolve */ + delta = deltar * sqrtN; + N_VConst(ZERO, x); + + /* Call SpgmrSolve and copy x to b */ + ier = SpgmrSolve(spgmr_mem, cv_mem, x, b, pretype, gstype, delta, 0, + cv_mem, ewt, ewt, CVSpgmrAtimesDQ, CVSpgmrPSolve, + &res_norm, &nli_inc, &nps_inc); + N_VScale(ONE, x, b); + + /* Increment counters nli, nps, and ncfl */ + nli += nli_inc; + nps += nps_inc; + if (iopt != NULL) { + iopt[SPGMR_NLI] = nli; + iopt[SPGMR_NPS] = nps; + } + if (ier != 0) { + ncfl++; + if (iopt != NULL) iopt[SPGMR_NCFL] = ncfl; + } + + /* Set return value to -1, 0, or 1 */ + if (ier < 0) return(-1); + if ((ier == SPGMR_SUCCESS) || + ((ier == SPGMR_RES_REDUCED) && (mnewt == 0))) + return(0); + return(1); +} + +/*************** CVSpgmrFree ***************************************** + + This routine frees memory specific to the Spgmr linear solver. + +**********************************************************************/ + +static void CVSpgmrFree(CVodeMem cv_mem) +{ + CVSpgmrMem cvspgmr_mem; + + cvspgmr_mem = (CVSpgmrMem) lmem; + + N_VFree(ytemp); + N_VFree(x); + SpgmrFree(spgmr_mem); + free(lmem); +} + +/*************** CVSpgmrAtimesDQ ************************************* + + This routine generates the matrix-vector product z = Mv, where + M = I - gamma*J, by using a difference quotient approximation to + the product Jv. The approximation is Jv = rho[f(y + v/rho) - f(y)], + where rho = (WRMS norm of v), i.e. the WRMS norm of v/rho is 1. + +**********************************************************************/ + +static int CVSpgmrAtimesDQ(void *cvode_mem, N_Vector v, N_Vector z) +{ + real rho; + CVodeMem cv_mem; + CVSpgmrMem cvspgmr_mem; + + cv_mem = (CVodeMem) cvode_mem; + cvspgmr_mem = (CVSpgmrMem) lmem; + + /* If rho = norm(v) is 0, return z = 0 */ + rho = N_VWrmsNorm(v, ewt); + if (rho == ZERO) { + N_VConst(ZERO, z); + return(0); + } + + /* Set ytemp = ycur + (1/rho) v */ + N_VLinearSum(ONE/rho, v, ONE, ycur, ytemp); + + /* Set z = f(tn, ytemp) */ + f(N, tn, ytemp, z, f_data); + nfe++; + + /* Replace z by v - (gamma*rho)(z - fcur) */ + N_VLinearSum(ONE, z, -ONE, fcur, z); + N_VLinearSum(-gamma*rho, z, ONE, v, z); + + return(0); +} + +/*************** CVSpgmrPSolve *************************************** + + This routine interfaces between the generic SpgmrSolve routine and + the user's psolve routine. It passes to psolve all required state + information from cvode_mem. Its return value is the same as that + returned by psolve. Note that the generic SPGMR solver guarantees + that CVSpgmrPSolve will not be called in the case in which + preconditioning is not done. This is the only case in which the + user's psolve routine is allowed to be NULL. + +**********************************************************************/ + +static int CVSpgmrPSolve(void *cvode_mem, N_Vector r, N_Vector z, int lr) +{ + CVodeMem cv_mem; + CVSpgmrMem cvspgmr_mem; + int ier; + + cv_mem = (CVodeMem) cvode_mem; + cvspgmr_mem = (CVSpgmrMem)lmem; + + ier = psolve(N, tn, ycur, fcur, ytemp, gamma, ewt, delta, &nfe, r, + lr, P_data, z); + /* This call is counted in nps within the CVSpgmrSolve routine */ + + return(ier); +} + diff --git a/ext/cvode/source/dense.c b/ext/cvode/source/dense.c new file mode 100755 index 000000000..20be8d239 --- /dev/null +++ b/ext/cvode/source/dense.c @@ -0,0 +1,311 @@ +/****************************************************************** + * * + * File : dense.c * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 25 February 2000 * + *----------------------------------------------------------------* + * This is the implementation file for a generic DENSE linear * + * solver package. * + * * + ******************************************************************/ + +#include +#include +#include "dense.h" +#include "llnltyps.h" +#include "nvector.h" +#include "llnlmath.h" + + +#define ZERO RCONST(0.0) +#define ONE RCONST(1.0) + + +/* Implementation */ + + +DenseMat DenseAllocMat(integer N) +{ + DenseMat A; + + if (N <= 0) return(NULL); + + A = (DenseMat) malloc(sizeof *A); + if (A==NULL) return (NULL); + + A->data = denalloc(N); + if (A->data == NULL) { + free(A); + return(NULL); + } + + A->size = N; + + return(A); +} + + +integer *DenseAllocPiv(integer N) +{ + if (N <= 0) return(NULL); + + return((integer *) malloc(N * sizeof(integer))); +} + + +integer DenseFactor(DenseMat A, integer *p) +{ + return(gefa(A->data, A->size, p)); +} + + +void DenseBacksolve(DenseMat A, integer *p, N_Vector b) +{ + gesl(A->data, A->size, p, N_VDATA(b)); +} + + +void DenseZero(DenseMat A) +{ + denzero(A->data, A->size); +} + +void DenseCopy(DenseMat A, DenseMat B) +{ + dencopy(A->data, B->data, A->size); +} + +void DenseScale(real c, DenseMat A) +{ + denscale(c, A->data, A->size); +} + +void DenseAddI(DenseMat A) +{ + denaddI(A->data, A->size); +} + +void DenseFreeMat(DenseMat A) +{ + denfree(A->data); + free(A); +} + +void DenseFreePiv(integer *p) +{ + free(p); +} + +void DensePrint(DenseMat A) +{ + denprint(A->data, A->size); +} + + +real **denalloc(integer n) +{ + integer j; + real **a; + + if (n <= 0) return(NULL); + + a = (real **) malloc(n * sizeof(real *)); + if (a == NULL) return(NULL); + + a[0] = (real *) malloc(n * n * sizeof(real)); + if (a[0] == NULL) { + free(a); + return(NULL); + } + + for (j=1; j < n; j++) a[j] = a[0] + j * n; + + return(a); +} + +integer *denallocpiv(integer n) +{ + if (n <= 0) return(NULL); + + return((integer *) malloc(n * sizeof(integer))); +} + +integer gefa(real **a, integer n, integer *p) +{ + integer i, j, k, l; + real *col_j, *col_k, *diag_k; + real temp, mult, a_kj; + boole swap; + + /* k = elimination step number */ + + for (k=0; k < n-1; k++, p++) { + + col_k = a[k]; + diag_k = col_k + k; + + /* find l = pivot row number */ + + l=k; + for (i=k+1; i < n; i++) + if (ABS(col_k[i]) > ABS(col_k[l])) l=i; + *p = l; + + /* check for zero pivot element */ + + if (col_k[l] == ZERO) return(k+1); + + /* swap a(l,k) and a(k,k) if necessary */ + + if ( (swap = (l != k) )) { + temp = col_k[l]; + col_k[l] = *diag_k; + *diag_k = temp; + } + + /* Scale the elements below the diagonal in */ + /* column k by -1.0 / a(k,k). After the above swap, */ + /* a(k,k) holds the pivot element. This scaling */ + /* stores the pivot row multipliers -a(i,k)/a(k,k) */ + /* in a(i,k), i=k+1, ..., n-1. */ + + mult = -ONE / (*diag_k); + for(i=k+1; i < n; i++) + col_k[i] *= mult; + + /* row_i = row_i - [a(i,k)/a(k,k)] row_k, i=k+1, ..., n-1 */ + /* row k is the pivot row after swapping with row l. */ + /* The computation is done one column at a time, */ + /* column j=k+1, ..., n-1. */ + + for (j=k+1; j < n; j++) { + + col_j = a[j]; + a_kj = col_j[l]; + + /* Swap the elements a(k,j) and a(k,l) if l!=k. */ + + if (swap) { + col_j[l] = col_j[k]; + col_j[k] = a_kj; + } + + /* a(i,j) = a(i,j) - [a(i,k)/a(k,k)]*a(k,j) */ + /* a_kj = a(k,j), col_k[i] = - a(i,k)/a(k,k) */ + + if (a_kj != ZERO) { + for (i=k+1; i < n; i++) + col_j[i] += a_kj * col_k[i]; + } + } + } + + /* set the last pivot row to be n-1 and check for a zero pivot */ + + *p = n-1; + if (a[n-1][n-1] == ZERO) return(n); + + /* return 0 to indicate success */ + + return(0); +} + +void gesl(real **a, integer n, integer *p, real *b) +{ + integer k, l, i; + real mult, *col_k; + + /* Solve Ly = Pb, store solution y in b */ + + for (k=0; k < n-1; k++) { + l = p[k]; + mult = b[l]; + if (l != k) { + b[l] = b[k]; + b[k] = mult; + } + col_k = a[k]; + for (i=k+1; i < n; i++) + b[i] += mult*col_k[i]; + } + + /* Solve Ux = y, store solution x in b */ + + for (k=n-1; k >= 0; k--) { + col_k = a[k]; + b[k] /= col_k[k]; + mult = -b[k]; + for (i=0; i < k; i++) + b[i] += mult*col_k[i]; + } +} + +void denzero(real **a, integer n) +{ + integer i, j; + real *col_j; + + for (j=0; j < n; j++) { + col_j = a[j]; + for (i=0; i < n; i++) + col_j[i] = ZERO; + } +} + +void dencopy(real **a, real **b, integer n) +{ + integer i, j; + real *a_col_j, *b_col_j; + + for (j=0; j < n; j++) { + a_col_j = a[j]; + b_col_j = b[j]; + for (i=0; i < n; i++) + b_col_j[i] = a_col_j[i]; + } + +} + +void denscale(real c, real **a, integer n) +{ + integer i, j; + real *col_j; + + for (j=0; j < n; j++) { + col_j = a[j]; + for (i=0; i < n; i++) + col_j[i] *= c; + } +} + +void denaddI(real **a, integer n) +{ + integer i; + + for (i=0; i < n; i++) a[i][i] += ONE; +} + +void denfreepiv(integer *p) +{ + free(p); +} + +void denfree(real **a) +{ + free(a[0]); + free(a); +} + +void denprint(real **a, integer n) +{ + integer i, j; + + printf("\n"); + for (i=0; i < n; i++) { + for (j=0; j < n; j++) { + printf("%10g", a[j][i]); + } + printf("\n"); + } + printf("\n"); +} diff --git a/ext/cvode/source/iterativ.c b/ext/cvode/source/iterativ.c new file mode 100755 index 000000000..b4eca8342 --- /dev/null +++ b/ext/cvode/source/iterativ.c @@ -0,0 +1,258 @@ +/****************************************************************** + * * + * File : iterativ.c * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 16 January 1998 * + *----------------------------------------------------------------* + * This is the implementation file for the iterativ.h header * + * file. It contains the implementation of functions that may be * + * useful for many different iterative solvers of A x = b. * + * * + ******************************************************************/ + + +#include "iterativ.h" +#include "llnltyps.h" +#include "nvector.h" +#include "llnlmath.h" + + +#define FACTOR RCONST(1000.0) +#define ZERO RCONST(0.0) +#define ONE RCONST(1.0) + + +/************************* ModifiedGS *********************************** + This implementation of ModifiedGS is a slight modification of a previous + modified Gram-Schmidt routine (called mgs) written by Milo Dorr. +*************************************************************************/ + +int ModifiedGS(N_Vector *v, real **h, int k, int p, real *new_vk_norm) +{ + int i, k_minus_1, i0; + real new_norm_2, new_product, vk_norm, temp; + + vk_norm = RSqrt(N_VDotProd(v[k],v[k])); + k_minus_1 = k - 1; + i0 = MAX(k-p, 0); + + /* Perform modified Gram-Schmidt */ + + for (i=i0; i < k; i++) { + h[i][k_minus_1] = N_VDotProd(v[i], v[k]); + N_VLinearSum(ONE, v[k], -h[i][k_minus_1], v[i], v[k]); + } + + /* Compute the norm of the new vector at v[k]. */ + + *new_vk_norm = RSqrt(N_VDotProd(v[k], v[k])); + + /* If the norm of the new vector at v[k] is less than + FACTOR (== 1000) times unit roundoff times the norm of the + input vector v[k], then the vector will be reorthogonalized + in order to ensure that nonorthogonality is not being masked + by a very small vector length. */ + + temp = FACTOR * vk_norm; + if ((temp + (*new_vk_norm)) != temp) return(0); + + new_norm_2 = ZERO; + + for (i=i0; i < k; i++) { + new_product = N_VDotProd(v[i], v[k]); + temp = FACTOR * h[i][k_minus_1]; + if ((temp + new_product) == temp) continue; + h[i][k_minus_1] += new_product; + N_VLinearSum(ONE, v[k],-new_product, v[i], v[k]); + new_norm_2 += SQR(new_product); + } + + if (new_norm_2 != ZERO) { + new_product = SQR(*new_vk_norm) - new_norm_2; + *new_vk_norm = (new_product > ZERO) ? RSqrt(new_product) : ZERO; + } + + return(0); +} + +/************************ ClassicalGS ******************************** + This implementation of ClassicalGS was contributed to by Homer Walker + and Peter Brown. +**********************************************************************/ + +int ClassicalGS(N_Vector *v, real **h, int k, int p, real *new_vk_norm, + N_Vector temp, real *s) +{ + int i, k_minus_1, i0; + real vk_norm; + + k_minus_1 = k - 1; + + /* Perform Classical Gram-Schmidt */ + + vk_norm = RSqrt(N_VDotProd(v[k], v[k])); + + i0 = MAX(k-p, 0); + for (i=i0; i < k; i++) { + h[i][k_minus_1] = N_VDotProd(v[i], v[k]); + } + + for (i=i0; i < k; i++) { + N_VLinearSum(ONE, v[k], -h[i][k_minus_1], v[i], v[k]); + } + + /* Compute the norm of the new vector at v[k]. */ + + *new_vk_norm = RSqrt(N_VDotProd(v[k], v[k])); + + /* Reorthogonalize if necessary */ + + if ((FACTOR * (*new_vk_norm)) < vk_norm) { + + for (i=i0; i < k; i++) { + s[i] = N_VDotProd(v[i], v[k]); + } + + if (i0 < k) { + N_VScale(s[i0], v[i0], temp); + h[i0][k_minus_1] += s[i0]; + } + for (i=i0+1; i < k; i++) { + N_VLinearSum(s[i], v[i], ONE, temp, temp); + h[i][k_minus_1] += s[i]; + } + N_VLinearSum(ONE, v[k], -ONE, temp, v[k]); + + *new_vk_norm = RSqrt(N_VDotProd(v[k],v[k])); + } + + return(0); +} + +/*************** QRfact ********************************************** + This implementation of QRfact is a slight modification of a previous + routine (called qrfact) written by Milo Dorr. +**********************************************************************/ + +int QRfact(int n, real **h, real *q, int job) +{ + real c, s, temp1, temp2, temp3; + int i, j, k, q_ptr, n_minus_1, code=0; + + switch (job) { + case 0: + /* Compute a new factorization of H. */ + code = 0; + for (k=0; k < n; k++) { + + /* Multiply column k by the previous k-1 Givens rotations. */ + for (j=0; j < k-1; j++) { + i = 2*j; + temp1 = h[j][k]; + temp2 = h[j+1][k]; + c = q[i]; + s = q[i+1]; + h[j][k] = c*temp1 - s*temp2; + h[j+1][k] = s*temp1 + c*temp2; + } + + /* Compute the Givens rotation components c and s */ + q_ptr = 2*k; + temp1 = h[k][k]; + temp2 = h[k+1][k]; + if( temp2 == ZERO) { + c = ONE; + s = ZERO; + } else if (ABS(temp2) >= ABS(temp1)) { + temp3 = temp1/temp2; + s = -ONE/RSqrt(ONE+SQR(temp3)); + c = -s*temp3; + } else { + temp3 = temp2/temp1; + c = ONE/RSqrt(ONE+SQR(temp3)); + s = -c*temp3; + } + q[q_ptr] = c; + q[q_ptr+1] = s; + if( (h[k][k] = c*temp1 - s*temp2) == ZERO) code = k+1; + } + break; + + default: + /* Update the factored H to which a new column has been added. */ + n_minus_1 = n - 1; + code = 0; + + /* Multiply the new column by the previous n-1 Givens rotations. */ + for (k=0; k < n_minus_1; k++) { + i = 2*k; + temp1 = h[k][n_minus_1]; + temp2 = h[k+1][n_minus_1]; + c = q[i]; + s = q[i+1]; + h[k][n_minus_1] = c*temp1 - s*temp2; + h[k+1][n_minus_1] = s*temp1 + c*temp2; + } + + /* Compute new Givens rotation and multiply it times the last two + entries in the new column of H. Note that the second entry of + this product will be 0, so it is not necessary to compute it. */ + temp1 = h[n_minus_1][n_minus_1]; + temp2 = h[n][n_minus_1]; + if (temp2 == ZERO) { + c = ONE; + s = ZERO; + } else if (ABS(temp2) >= ABS(temp1)) { + temp3 = temp1/temp2; + s = -ONE/RSqrt(ONE+SQR(temp3)); + c = -s*temp3; + } else { + temp3 = temp2/temp1; + c = ONE/RSqrt(ONE+SQR(temp3)); + s = -c*temp3; + } + q_ptr = 2*n_minus_1; + q[q_ptr] = c; + q[q_ptr+1] = s; + if ((h[n_minus_1][n_minus_1] = c*temp1 - s*temp2) == ZERO) + code = n; + } + + return (code); +} + +/*************** QRsol ************************************************ + This implementation of QRsol is a slight modification of a previous + routine (called qrsol) written by Milo Dorr. +**********************************************************************/ + +int QRsol(int n, real **h, real *q, real *b) +{ + real c, s, temp1, temp2; + int i, k, q_ptr, code=0; + + /* Compute Q*b. */ + + for (k=0; k < n; k++) { + q_ptr = 2*k; + c = q[q_ptr]; + s = q[q_ptr+1]; + temp1 = b[k]; + temp2 = b[k+1]; + b[k] = c*temp1 - s*temp2; + b[k+1] = s*temp1 + c*temp2; + } + + /* Solve R*x = Q*b. */ + + for (k=n-1; k >= 0; k--) { + if (h[k][k] == ZERO) { + code = k + 1; + break; + } + b[k] /= h[k][k]; + for (i=0; i < k; i++) b[i] -= b[k]*h[i][k]; + } + + return (code); +} diff --git a/ext/cvode/source/llnlmath.c b/ext/cvode/source/llnlmath.c new file mode 100755 index 000000000..9788a60bf --- /dev/null +++ b/ext/cvode/source/llnlmath.c @@ -0,0 +1,67 @@ +/****************************************************************** + * * + * File : llnlmath.c * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 1 September 1994 * + *----------------------------------------------------------------* + * This is the implementation file for a C math library. * + * * + ******************************************************************/ + + +#include +#include +#include "llnlmath.h" +#include "llnltyps.h" + + +#define ZERO RCONST(0.0) +#define ONE RCONST(1.0) +#define TWO RCONST(2.0) + + +real UnitRoundoff(void) +{ + real u; + volatile real one_plus_u; + + u = ONE; + one_plus_u = ONE + u; + while (one_plus_u != ONE) { + u /= TWO; + one_plus_u = ONE + u; + } + u *= TWO; + + return(u); +} + + +real RPowerI(real base, int exponent) +{ + int i, expt; + real prod; + + prod = ONE; + expt = ABS(exponent); + for(i=1; i <= expt; i++) prod *= base; + if (exponent < 0) prod = ONE/prod; + return(prod); +} + + +real RPowerR(real base, real exponent) +{ + + if (base <= ZERO) return(ZERO); + + return((real)pow((double)base,(double)exponent)); +} + + +real RSqrt(real x) +{ + if (x <= ZERO) return(ZERO); + + return((real) sqrt((double) x)); +} diff --git a/ext/cvode/source/nvector.c b/ext/cvode/source/nvector.c new file mode 100755 index 000000000..44934cb28 --- /dev/null +++ b/ext/cvode/source/nvector.c @@ -0,0 +1,670 @@ +/**************************************************************** + * * + * File : nvector.c * + * Programmers : Scott D. Cohen, Alan C. Hindmarsh, and * + * : Allan G. Taylor, LLNL * + * Version of : 17 December 1999 * + *--------------------------------------------------------------* + * * + * This is the implementation file for a generic serial NVECTOR * + * package. It contains the implementation of the N_Vector * + * kernels listed in nvector.h. * + * * + ****************************************************************/ + + +#include +#include +#include "nvector.h" +#include "llnltyps.h" +#include "llnlmath.h" + + +#define ZERO RCONST(0.0) +#define HALF RCONST(0.5) +#define ONE RCONST(1.0) +#define ONEPT5 RCONST(1.5) + + +/* Private Helper Prototypes */ + +static void VCopy(N_Vector x, N_Vector z); /* z=x */ +static void VSum(N_Vector x, N_Vector y, N_Vector z); /* z=x+y */ +static void VDiff(N_Vector x, N_Vector y, N_Vector z); /* z=x-y */ +static void VNeg(N_Vector x, N_Vector z); /* z=-x */ +/* z=c(x+y) */ +static void VScaleSum(real c, N_Vector x, N_Vector y, N_Vector z); +/* z=c(x-y) */ +static void VScaleDiff(real c, N_Vector x, N_Vector y, N_Vector z); +static void VLin1(real a, N_Vector x, N_Vector y, N_Vector z); /* z=ax+y */ +static void VLin2(real a, N_Vector x, N_Vector y, N_Vector z); /* z=ax-y */ +static void Vaxpy(real a, N_Vector x, N_Vector y); /* y <- ax+y */ +static void VScaleBy(real a, N_Vector x); /* x <- ax */ + +/********************* Exported Functions ************************/ + + +N_Vector N_VNew(integer N, void *machEnv) +{ + N_Vector v; + + if (N <= 0) return(NULL); + + v = (N_Vector) malloc(sizeof *v); + if (v == NULL) return(NULL); + + v->data = (real *) malloc(N * sizeof(real)); + if (v->data == NULL) { + free(v); + return(NULL); + } + + v->length = N; + + return(v); +} + + +void N_VFree(N_Vector x) +{ + free(x->data); + free(x); +} + + +void N_VLinearSum(real a, N_Vector x, real b, N_Vector y, N_Vector z) +{ + integer i, N; + real c, *xd, *yd, *zd; + N_Vector v1, v2; + boole test; + + if ((b == ONE) && (z == y)) { /* BLAS usage: axpy y <- ax+y */ + Vaxpy(a,x,y); + return; + } + + if ((a == ONE) && (z == x)) { /* BLAS usage: axpy x <- by+x */ + Vaxpy(b,y,x); + return; + } + + /* Case: a == b == 1.0 */ + + if ((a == ONE) && (b == ONE)) { + VSum(x, y, z); + return; + } + + /* Cases: (1) a == 1.0, b = -1.0, (2) a == -1.0, b == 1.0 */ + + if ((test = ((a == ONE) && (b == -ONE))) || ((a == -ONE) && (b == ONE))) { + v1 = test ? y : x; + v2 = test ? x : y; + VDiff(v2, v1, z); + return; + } + + /* Cases: (1) a == 1.0, b == other or 0.0, (2) a == other or 0.0, b == 1.0 */ + /* if a or b is 0.0, then user should have called N_VScale */ + + if ((test = (a == ONE)) || (b == ONE)) { + c = test ? b : a; + v1 = test ? y : x; + v2 = test ? x : y; + VLin1(c, v1, v2, z); + return; + } + + /* Cases: (1) a == -1.0, b != 1.0, (2) a != 1.0, b == -1.0 */ + + if ((test = (a == -ONE)) || (b == -ONE)) { + c = test ? b : a; + v1 = test ? y : x; + v2 = test ? x : y; + VLin2(c, v1, v2, z); + return; + } + + /* Case: a == b */ + /* catches case both a and b are 0.0 - user should have called N_VConst */ + + if (a == b) { + VScaleSum(a, x, y, z); + return; + } + + /* Case: a == -b */ + + if (a == -b) { + VScaleDiff(a, x, y, z); + return; + } + + /* Do all cases not handled above: + (1) a == other, b == 0.0 - user should have called N_VScale + (2) a == 0.0, b == other - user should have called N_VScale + (3) a,b == other, a !=b, a != -b */ + + N = x->length; + xd = x->data; + yd = y->data; + zd = z->data; + + for (i=0; i < N; i++) + *zd++ = a * (*xd++) + b * (*yd++); +} + + +void N_VConst(real c, N_Vector z) +{ + integer i, N; + real *zd; + + N = z->length; + zd = z->data; + + for (i=0; i < N; i++) + *zd++ = c; +} + + +void N_VProd(N_Vector x, N_Vector y, N_Vector z) +{ + integer i, N; + real *xd, *yd, *zd; + + N = x->length; + xd = x->data; + yd = y->data; + zd = z->data; + + for (i=0; i < N; i++) + *zd++ = (*xd++) * (*yd++); +} + + +void N_VDiv(N_Vector x, N_Vector y, N_Vector z) +{ + integer i, N; + real *xd, *yd, *zd; + + N = x->length; + xd = x->data; + yd = y->data; + zd = z->data; + + for (i=0; i < N; i++) + *zd++ = (*xd++) / (*yd++); +} + + +void N_VScale(real c, N_Vector x, N_Vector z) +{ + integer i, N; + real *xd, *zd; + + if (z == x) { /* BLAS usage: scale x <- cx */ + VScaleBy(c, x); + return; + } + + if (c == ONE) { + VCopy(x, z); + } else if (c == -ONE) { + VNeg(x, z); + } else { + N = x->length; + xd = x->data; + zd = z->data; + for (i=0; i < N; i++) *zd++ = c * (*xd++); + } +} + + +void N_VAbs(N_Vector x, N_Vector z) +{ + integer i, N; + real *xd, *zd; + + N = x->length; + xd = x->data; + zd = z->data; + + for (i=0; i < N; i++, xd++, zd++) + *zd = ABS(*xd); +} + + +void N_VInv(N_Vector x, N_Vector z) +{ + integer i, N; + real *xd, *zd; + + N = x->length; + xd = x->data; + zd = z->data; + + for (i=0; i < N; i++) + *zd++ = ONE / (*xd++); +} + + +void N_VAddConst(N_Vector x, real b, N_Vector z) +{ + integer i, N; + real *xd, *zd; + + N = x->length; + xd = x->data; + zd = z->data; + + for (i=0; i < N; i++) *zd++ = (*xd++) + b; +} + + +real N_VDotProd(N_Vector x, N_Vector y) +{ + integer i, N; + real sum = ZERO, *xd, *yd; + + N = x->length; + xd = x->data; + yd = y->data; + + for (i=0; i < N; i++) + sum += (*xd++) * (*yd++); + + return(sum); +} + + +real N_VMaxNorm(N_Vector x) +{ + integer i, N; + real max = ZERO, *xd; + + N = x->length; + xd = x->data; + + for (i=0; i < N; i++, xd++) { + if (ABS(*xd) > max) max = ABS(*xd); + } + + return(max); +} + + +real N_VWrmsNorm(N_Vector x, N_Vector w) +{ + integer i, N; + real sum = ZERO, prodi, *xd, *wd; + + N = x->length; + xd = x->data; + wd = w->data; + + for (i=0; i < N; i++) { + prodi = (*xd++) * (*wd++); + sum += prodi * prodi; + } + + return(RSqrt(sum / N)); +} + + + +real N_VMin(N_Vector x) +{ + integer i, N; + real min, *xd; + + N = x->length; + xd = x->data; + min = xd[0]; + + for (i=1; i < N; i++, xd++) { + if ((*xd) < min) min = *xd; + } + + return(min); +} + + +real N_VWL2Norm(N_Vector x, N_Vector w) +{ + integer i, N; + real sum = ZERO, prodi, *xd, *wd; + + N = x->length; + xd = x->data; + wd = w->data; + + for (i=0; i < N; i++) { + prodi = (*xd++) * (*wd++); + sum += prodi * prodi; + } + + return(RSqrt(sum)); +} + + +real N_VL1Norm(N_Vector x) +{ + integer i, N; + real sum = ZERO, *xd; + + N = x->length; + xd = x->data; + + for (i=0; ilength; + xd = x->data; + + for (i=0; ilength; + xd = x->data; + zd = z->data; + + for (i=0; i < N; i++, xd++, zd++) { + *zd = (ABS(*xd) >= c) ? ONE : ZERO; + } +} + + +boole N_VInvTest(N_Vector x, N_Vector z) +{ + integer i, N; + real *xd, *zd; + + N = x->length; + xd = x->data; + zd = z->data; + + for (i=0; i < N; i++) { + if (*xd == ZERO) return(FALSE); + *zd++ = ONE / (*xd++); + } + + return(TRUE); +} + + +boole N_VConstrProdPos(N_Vector c, N_Vector x) +{ + integer i, N; + real *xd, *cd; + boole test; + + N = x->length; + xd = x->data; + cd = c->data; + test = TRUE; + + for (i=0; i < N; i++, xd++,cd++) { + if (*cd != ZERO) { + if ((*xd)*(*cd) <= ZERO) { + test = FALSE; + break; + } + } + } + + return(test); +} + +boole N_VConstrMask(N_Vector c, N_Vector x, N_Vector m) +{ + integer i, N; + boole test; + real *cd, *xd, *md; + + N = x->length; + cd = c->data; + xd = x->data; + md = m->data; + + test = TRUE; + + for (i=0; i ONEPT5 || (*cd) < -ONEPT5) + if ( (*xd)*(*cd) <= ZERO) { + test = FALSE; + *md = ONE; + } + else + *md = ZERO; + else if ( (*cd) > HALF || (*cd) < -HALF) + if ( (*xd)*(*cd) < ZERO ) { + test = FALSE; + *md = ONE; + } + else + *md = ZERO; + } + } +return(test); +} + + +real N_VMinQuotient(N_Vector num, N_Vector denom) +{ + boole notEvenOnce; + integer i, N; + real *nd, *dd, min; + + N = num->length; + nd = num->data; + dd = denom->data; + notEvenOnce = TRUE; + + for (i=0; ilength; + xd = x->data; + + for (i=0; i < N; i++) printf("%11.8g\n", *xd++); + + printf("\n"); +} + + +/***************** Private Helper Functions **********************/ + + +static void VCopy(N_Vector x, N_Vector z) +{ + integer i, N; + real *xd, *zd; + + N = x->length; + xd = x->data; + zd = z->data; + + for (i=0; i < N; i++) + *zd++ = *xd++; +} + + +static void VSum(N_Vector x, N_Vector y, N_Vector z) +{ + integer i, N; + real *xd, *yd, *zd; + + N = x->length; + xd = x->data; + yd = y->data; + zd = z->data; + + for (i=0; i < N; i++) + *zd++ = (*xd++) + (*yd++); +} + + +static void VDiff(N_Vector x, N_Vector y, N_Vector z) +{ + integer i, N; + real *xd, *yd, *zd; + + N = x->length; + xd = x->data; + yd = y->data; + zd = z->data; + + for (i=0; i < N; i++) + *zd++ = (*xd++) - (*yd++); +} + + +static void VNeg(N_Vector x, N_Vector z) +{ + integer i, N; + real *xd, *zd; + + N = x->length; + xd = x->data; + zd = z->data; + + for (i=0; i < N; i++) + *zd++ = -(*xd++); +} + + +static void VScaleSum(real c, N_Vector x, N_Vector y, N_Vector z) +{ + integer i, N; + real *xd, *yd, *zd; + + N = x->length; + xd = x->data; + yd = y->data; + zd = z->data; + + for (i=0; i < N; i++) + *zd++ = c * ((*xd++) + (*yd++)); +} + + +static void VScaleDiff(real c, N_Vector x, N_Vector y, N_Vector z) +{ + integer i, N; + real *xd, *yd, *zd; + + N = x->length; + xd = x->data; + yd = y->data; + zd = z->data; + + for (i=0; i < N; i++) + *zd++ = c * ((*xd++) - (*yd++)); +} + + +static void VLin1(real a, N_Vector x, N_Vector y, N_Vector z) +{ + integer i, N; + real *xd, *yd, *zd; + + N = x->length; + xd = x->data; + yd = y->data; + zd = z->data; + + for (i=0; i < N; i++) + *zd++ = a * (*xd++) + (*yd++); +} + + +static void VLin2(real a, N_Vector x, N_Vector y, N_Vector z) +{ + integer i, N; + real *xd, *yd, *zd; + + N = x->length; + xd = x->data; + yd = y->data; + zd = z->data; + + for (i=0; i < N; i++) + *zd++ = a * (*xd++) - (*yd++); +} + +static void Vaxpy(real a, N_Vector x, N_Vector y) +{ + integer i, N; + real *xd, *yd; + + N = x->length; + xd = x->data; + yd = y->data; + + if (a == ONE) { + for (i=0; i < N; i++) + *yd++ += (*xd++); + return; + } + + if (a == -ONE) { + for (i=0; i < N; i++) + *yd++ -= (*xd++); + return; + } + + for (i=0; i < N; i++) + *yd++ += a * (*xd++); +} + +static void VScaleBy(real a, N_Vector x) +{ + integer i, N; + real *xd; + + N = x->length; + xd = x->data; + + for (i=0; i < N; i++) + *xd++ *= a; +} diff --git a/ext/cvode/source/spgmr.c b/ext/cvode/source/spgmr.c new file mode 100755 index 000000000..1842ca2da --- /dev/null +++ b/ext/cvode/source/spgmr.c @@ -0,0 +1,429 @@ +/****************************************************************** + * File : spgmr.c * + * Programmers : Scott D. Cohen and Alan C. Hindmarsh @ LLNL * + * Version of : 17 December 1999 * + *----------------------------------------------------------------* + * This is the implementation file for the scaled preconditioned * + * GMRES (SPGMR) iterative linear solver. * + * * + ******************************************************************/ + + +#include +#include +#include "iterativ.h" +#include "spgmr.h" +#include "llnltyps.h" +#include "nvector.h" +#include "llnlmath.h" + + +#define ZERO RCONST(0.0) +#define ONE RCONST(1.0) + + +/*************** Private Helper Function Prototype *******************/ + +static void FreeVectorArray(N_Vector *A, int indMax); + + +/* Implementation of SPGMR algorithm */ + + +/*************** SpgmrMalloc *****************************************/ + +SpgmrMem SpgmrMalloc(integer N, int l_max, void *machEnv) +{ + SpgmrMem mem; + N_Vector *V, xcor, vtemp; + real **Hes, *givens, *yg; + int k, i; + + /* Check the input parameters. */ + + if ((N <= 0) || (l_max <= 0)) return(NULL); + + /* Get memory for the Krylov basis vectors V[0], ..., V[l_max]. */ + + V = (N_Vector *) malloc((l_max+1)*sizeof(N_Vector)); + if (V == NULL) return(NULL); + + for (k = 0; k <= l_max; k++) { + V[k] = N_VNew(N, machEnv); + if (V[k] == NULL) { + FreeVectorArray(V, k-1); + return(NULL); + } + } + + /* Get memory for the Hessenberg matrix Hes. */ + + Hes = (real **) malloc((l_max+1)*sizeof(real *)); + if (Hes == NULL) { + FreeVectorArray(V, l_max); + return(NULL); + } + + for (k = 0; k <= l_max; k++) { + Hes[k] = (real *) malloc(l_max*sizeof(real)); + if (Hes[k] == NULL) { + for (i = 0; i < k; i++) free(Hes[i]); + FreeVectorArray(V, l_max); + return(NULL); + } + } + + /* Get memory for Givens rotation components. */ + + givens = (real *) malloc(2*l_max*sizeof(real)); + if (givens == NULL) { + for (i = 0; i <= l_max; i++) free(Hes[i]); + FreeVectorArray(V, l_max); + return(NULL); + } + + /* Get memory to hold the correction to z_tilde. */ + + xcor = N_VNew(N, machEnv); + if (xcor == NULL) { + free(givens); + for (i = 0; i <= l_max; i++) free(Hes[i]); + FreeVectorArray(V, l_max); + return(NULL); + } + + /* Get memory to hold SPGMR y and g vectors. */ + + yg = (real *) malloc((l_max+1)*sizeof(real)); + if (yg == NULL) { + N_VFree(xcor); + free(givens); + for (i = 0; i <= l_max; i++) free(Hes[i]); + FreeVectorArray(V, l_max); + return(NULL); + } + + /* Get an array to hold a temporary vector. */ + + vtemp = N_VNew(N, machEnv); + if (vtemp == NULL) { + free(yg); + N_VFree(xcor); + free(givens); + for (i = 0; i <= l_max; i++) free(Hes[i]); + FreeVectorArray(V, l_max); + return(NULL); + } + + /* Get memory for an SpgmrMemRec containing SPGMR matrices and vectors. */ + + mem = (SpgmrMem) malloc(sizeof(SpgmrMemRec)); + if (mem == NULL) { + N_VFree(vtemp); + free(yg); + N_VFree(xcor); + free(givens); + for (i = 0; i <= l_max; i++) free(Hes[i]); + FreeVectorArray(V, l_max); + return(NULL); + } + + /* Set the fields of mem. */ + + mem->N = N; + mem->l_max = l_max; + mem->V = V; + mem->Hes = Hes; + mem->givens = givens; + mem->xcor = xcor; + mem->yg = yg; + mem->vtemp = vtemp; + + /* Return the pointer to SPGMR memory. */ + + return(mem); +} + + +/*************** SpgmrSolve ******************************************/ + +int SpgmrSolve(SpgmrMem mem, void *A_data, N_Vector x, N_Vector b, + int pretype, int gstype, real delta, int max_restarts, + void *P_data, N_Vector s1, N_Vector s2, ATimesFn atimes, + PSolveFn psolve, real *res_norm, int *nli, int *nps) +{ + N_Vector *V, xcor, vtemp; + real **Hes, *givens, *yg; + real beta, rotation_product, r_norm, s_product, rho; + boole preOnLeft, preOnRight, scale2, scale1, converged; + int i, j, k, l, l_plus_1, l_max, krydim, ier, ntries; + + if (mem == NULL) return(SPGMR_MEM_NULL); + + /* Make local copies of mem variables. */ + l_max = mem->l_max; + V = mem->V; + Hes = mem->Hes; + givens = mem->givens; + xcor = mem->xcor; + yg = mem->yg; + vtemp = mem->vtemp; + + *nli = *nps = 0; /* Initialize counters */ + converged = FALSE; /* Initialize converged flag */ + + if (max_restarts < 0) max_restarts = 0; + + if ((pretype != LEFT) && (pretype != RIGHT) && (pretype != BOTH)) + pretype = NONE; + + preOnLeft = ((pretype == LEFT) || (pretype == BOTH)); + preOnRight = ((pretype == RIGHT) || (pretype == BOTH)); + scale1 = (s1 != NULL); + scale2 = (s2 != NULL); + + /* Set vtemp and V[0] to initial (unscaled) residual r_0 = b - A*x_0. */ + + if (N_VDotProd(x, x) == ZERO) { + N_VScale(ONE, b, vtemp); + } else { + if (atimes(A_data, x, vtemp) != 0) + return(SPGMR_ATIMES_FAIL); + N_VLinearSum(ONE, b, -ONE, vtemp, vtemp); + } + N_VScale(ONE, vtemp, V[0]); + + /* Apply left preconditioner and left scaling to V[0] = r_0. */ + + if (preOnLeft) { + ier = psolve(P_data, V[0], vtemp, LEFT); + (*nps)++; + if (ier != 0) + return((ier < 0) ? SPGMR_PSOLVE_FAIL_UNREC : SPGMR_PSOLVE_FAIL_REC); + } else { + N_VScale(ONE, V[0], vtemp); + } + + if (scale1) { + N_VProd(s1, vtemp, V[0]); + } else { + N_VScale(ONE, vtemp, V[0]); + } + + /* Set r_norm = beta to L2 norm of V[0] = s1 P1_inv r_0, and + return if small. */ + + *res_norm = r_norm = beta = RSqrt(N_VDotProd(V[0], V[0])); + if (r_norm <= delta) + return(SPGMR_SUCCESS); + + /* Set xcor = 0. */ + + N_VConst(ZERO, xcor); + + + /* Begin outer iterations: up to (max_restarts + 1) attempts. */ + + for (ntries = 0; ntries <= max_restarts; ntries++) { + + /* Initialize the Hessenberg matrix Hes and Givens rotation + product. Normalize the initial vector V[0]. */ + + for (i = 0; i <= l_max; i++) + for (j = 0; j < l_max; j++) + Hes[i][j] = ZERO; + + rotation_product = ONE; + + N_VScale(ONE/r_norm, V[0], V[0]); + + /* Inner loop: generate Krylov sequence and Arnoldi basis. */ + + for (l = 0; l < l_max; l++) { + + (*nli)++; + + krydim = l_plus_1 = l + 1; + + /* Generate A-tilde V[l], where A-tilde = s1 P1_inv A P2_inv s2_inv. */ + + /* Apply right scaling: vtemp = s2_inv V[l]. */ + if (scale2) N_VDiv(V[l], s2, vtemp); + else N_VScale(ONE, V[l], vtemp); + + /* Apply right preconditioner: vtemp = P2_inv s2_inv V[l]. */ + if (preOnRight) { + N_VScale(ONE, vtemp, V[l_plus_1]); + ier = psolve(P_data, V[l_plus_1], vtemp, RIGHT); + (*nps)++; + if (ier != 0) + return((ier < 0) ? SPGMR_PSOLVE_FAIL_UNREC : SPGMR_PSOLVE_FAIL_REC); + } + + /* Apply A: V[l+1] = A P2_inv s2_inv V[l]. */ + if (atimes(A_data, vtemp, V[l_plus_1] ) != 0) + return(SPGMR_ATIMES_FAIL); + + /* Apply left preconditioning: vtemp = P1_inv A P2_inv s2_inv V[l]. */ + if (preOnLeft) { + ier = psolve(P_data, V[l_plus_1], vtemp, LEFT); + (*nps)++; + if (ier != 0) + return((ier < 0) ? SPGMR_PSOLVE_FAIL_UNREC : SPGMR_PSOLVE_FAIL_REC); + } else { + N_VScale(ONE, V[l_plus_1], vtemp); + } + + /* Apply left scaling: V[l+1] = s1 P1_inv A P2_inv s2_inv V[l]. */ + if (scale1) { + N_VProd(s1, vtemp, V[l_plus_1]); + } else { + N_VScale(ONE, vtemp, V[l_plus_1]); + } + + /* Orthogonalize V[l+1] against previous V[i]: V[l+1] = w_tilde. */ + + if (gstype == CLASSICAL_GS) { + if (ClassicalGS(V, Hes, l_plus_1, l_max, &(Hes[l_plus_1][l]), + vtemp, yg) != 0) + return(SPGMR_GS_FAIL); + } else { + if (ModifiedGS(V, Hes, l_plus_1, l_max, &(Hes[l_plus_1][l])) != 0) + return(SPGMR_GS_FAIL); + } + + /* Update the QR factorization of Hes. */ + + if(QRfact(krydim, Hes, givens, l) != 0 ) + return(SPGMR_QRFACT_FAIL); + + /* Update residual norm estimate; break if convergence test passes. */ + + rotation_product *= givens[2*l+1]; + *res_norm = rho = ABS(rotation_product*r_norm); + + if (rho <= delta) { converged = TRUE; break; } + + /* Normalize V[l+1] with norm value from the Gram-Schmidt routine. */ + N_VScale(ONE/Hes[l_plus_1][l], V[l_plus_1], V[l_plus_1]); + } + + /* Inner loop is done. Compute the new correction vector xcor. */ + + /* Construct g, then solve for y. */ + yg[0] = r_norm; + for (i = 1; i <= krydim; i++) yg[i]=ZERO; + if (QRsol(krydim, Hes, givens, yg) != 0) + return(SPGMR_QRSOL_FAIL); + + /* Add correction vector V_l y to xcor. */ + for (k = 0; k < krydim; k++) + N_VLinearSum(yg[k], V[k], ONE, xcor, xcor); + + /* If converged, construct the final solution vector x and return. */ + if (converged) { + + /* Apply right scaling and right precond.: vtemp = P2_inv s2_inv xcor. */ + + if (scale2) N_VDiv(xcor, s2, xcor); + if (preOnRight) { + ier = psolve(P_data, xcor, vtemp, RIGHT); + (*nps)++; + if (ier != 0) + return((ier < 0) ? SPGMR_PSOLVE_FAIL_UNREC : SPGMR_PSOLVE_FAIL_REC); + } else { + N_VScale(ONE, xcor, vtemp); + } + + /* Add vtemp to initial x to get final solution x, and return */ + N_VLinearSum(ONE, x, ONE, vtemp, x); + + return(SPGMR_SUCCESS); + } + + /* Not yet converged; if allowed, prepare for restart. */ + + if (ntries == max_restarts) break; + + /* Construct last column of Q in yg. */ + s_product = ONE; + for (i = krydim; i > 0; i--) { + yg[i] = s_product*givens[2*i-2]; + s_product *= givens[2*i-1]; + } + yg[0] = s_product; + + /* Scale r_norm and yg. */ + r_norm *= s_product; + for (i = 0; i <= krydim; i++) + yg[i] *= r_norm; + r_norm = ABS(r_norm); + + /* Multiply yg by V_(krydim+1) to get last residual vector; restart. */ + N_VScale(yg[0], V[0], V[0]); + for (k = 1; k <= krydim; k++) + N_VLinearSum(yg[k], V[k], ONE, V[0], V[0]); + + } + + /* Failed to converge, even after allowed restarts. + If the residual norm was reduced below its initial value, compute + and return x anyway. Otherwise return failure flag. */ + + if (rho < beta) { + + /* Apply right scaling and right precond.: vtemp = P2_inv s2_inv xcor. */ + + if (scale2) N_VDiv(xcor, s2, xcor); + if (preOnRight) { + ier = psolve(P_data, xcor, vtemp, RIGHT); + (*nps)++; + if (ier != 0) + return((ier < 0) ? SPGMR_PSOLVE_FAIL_UNREC : SPGMR_PSOLVE_FAIL_REC); + } else { + N_VScale(ONE, xcor, vtemp); + } + + /* Add vtemp to initial x to get final solution x, and return. */ + N_VLinearSum(ONE, x, ONE, vtemp, x); + + return(SPGMR_RES_REDUCED); + } + + return(SPGMR_CONV_FAIL); +} + +/*************** SpgmrFree *******************************************/ + +void SpgmrFree(SpgmrMem mem) +{ + int i, l_max; + real **Hes; + + if (mem == NULL) return; + + l_max = mem->l_max; + Hes = mem->Hes; + + FreeVectorArray(mem->V, l_max); + for (i = 0; i <= l_max; i++) free(Hes[i]); + free(Hes); + free(mem->givens); + N_VFree(mem->xcor); + free(mem->yg); + N_VFree(mem->vtemp); + + free(mem); +} + + +/*************** Private Helper Function: FreeVectorArray ************/ + +static void FreeVectorArray(N_Vector *A, int indMax) +{ + int j; + + for (j = 0; j <= indMax; j++) N_VFree(A[j]); + + free(A); +} diff --git a/ext/lapack/.cvsignore b/ext/lapack/.cvsignore new file mode 100644 index 000000000..f3c7a7c5d --- /dev/null +++ b/ext/lapack/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/ext/lapack/Makefile.in b/ext/lapack/Makefile.in new file mode 100755 index 000000000..ef4e7e29c --- /dev/null +++ b/ext/lapack/Makefile.in @@ -0,0 +1,89 @@ +# $License$ +# +#/bin/sh + +LAPACKLIB = ./libctlapack.a + +SUFFIXES= +SUFFIXES= .f .o + +F_FLAGS = @FFLAGS@ $(F77_FLAGS) + +OBJS = \ +dbdsqr.o \ +dgbtrf.o \ +dgbtf2.o \ +dgbtrs.o \ +dgbsv.o \ +dgebd2.o \ +dgebrd.o \ +dgelq2.o \ +dgelqf.o \ +dgelss.o \ +dgeqr2.o \ +dgeqrf.o \ +dgetf2.o \ +dgetrf.o \ +dgetri.o \ +dgetrs.o \ +dlabad.o \ +dlabrd.o \ +dlacpy.o \ +dlamch.o \ +dlange.o \ +dlapy2.o \ +dlarf.o \ +dlarfb.o \ +dlarfg.o \ +dlarft.o \ +dlartg.o \ +dlas2.o \ +dlascl.o \ +dlaset.o \ +dlasq1.o \ +dlasq2.o \ +dlasq3.o \ +dlasq4.o \ +dlasr.o \ +dlasrt.o \ +dlassq.o \ +dlasv2.o \ +dlaswp.o \ +dorg2r.o \ +dorgbr.o \ +dorgl2.o \ +dorglq.o \ +dorgqr.o \ +dorm2r.o \ +dormbr.o \ +dorml2.o \ +dormlq.o \ +dormqr.o \ +drscl.o \ +ilaenv.o + +#SRCS = $(OBJS:.o=.cpp) + +all: $(LAPACKLIB) + +$(LAPACKLIB): $(OBJS) + @ARCHIVE@ $(LAPACKLIB) $(OBJS) > /dev/null + +.f.o: + @F77@ -c $< $(F77_INCLUDES) $(F_FLAGS) + + +clean: + $(RM) $(OBJS) $(LAPACKLIB) + + + + + + + + + + + + diff --git a/ext/lapack/dbdsqr.f b/ext/lapack/dbdsqr.f new file mode 100755 index 000000000..e89063a7f --- /dev/null +++ b/ext/lapack/dbdsqr.f @@ -0,0 +1,807 @@ + SUBROUTINE DBDSQR( UPLO, N, NCVT, NRU, NCC, D, E, VT, LDVT, U, + $ LDU, C, LDC, WORK, INFO ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + CHARACTER UPLO + INTEGER INFO, LDC, LDU, LDVT, N, NCC, NCVT, NRU +* .. +* .. Array Arguments .. + DOUBLE PRECISION C( LDC, * ), D( * ), E( * ), U( LDU, * ), + $ VT( LDVT, * ), WORK( * ) +* .. +* +* Purpose +* ======= +* +* DBDSQR computes the singular value decomposition (SVD) of a real +* N-by-N (upper or lower) bidiagonal matrix B: B = Q * S * P' (P' +* denotes the transpose of P), where S is a diagonal matrix with +* non-negative diagonal elements (the singular values of B), and Q +* and P are orthogonal matrices. +* +* The routine computes S, and optionally computes U * Q, P' * VT, +* or Q' * C, for given real input matrices U, VT, and C. +* +* See "Computing Small Singular Values of Bidiagonal Matrices With +* Guaranteed High Relative Accuracy," by J. Demmel and W. Kahan, +* LAPACK Working Note #3 (or SIAM J. Sci. Statist. Comput. vol. 11, +* no. 5, pp. 873-912, Sept 1990) and +* "Accurate singular values and differential qd algorithms," by +* B. Parlett and V. Fernando, Technical Report CPAM-554, Mathematics +* Department, University of California at Berkeley, July 1992 +* for a detailed description of the algorithm. +* +* Arguments +* ========= +* +* UPLO (input) CHARACTER*1 +* = 'U': B is upper bidiagonal; +* = 'L': B is lower bidiagonal. +* +* N (input) INTEGER +* The order of the matrix B. N >= 0. +* +* NCVT (input) INTEGER +* The number of columns of the matrix VT. NCVT >= 0. +* +* NRU (input) INTEGER +* The number of rows of the matrix U. NRU >= 0. +* +* NCC (input) INTEGER +* The number of columns of the matrix C. NCC >= 0. +* +* D (input/output) DOUBLE PRECISION array, dimension (N) +* On entry, the n diagonal elements of the bidiagonal matrix B. +* On exit, if INFO=0, the singular values of B in decreasing +* order. +* +* E (input/output) DOUBLE PRECISION array, dimension (N) +* On entry, the elements of E contain the +* offdiagonal elements of the bidiagonal matrix whose SVD +* is desired. On normal exit (INFO = 0), E is destroyed. +* If the algorithm does not converge (INFO > 0), D and E +* will contain the diagonal and superdiagonal elements of a +* bidiagonal matrix orthogonally equivalent to the one given +* as input. E(N) is used for workspace. +* +* VT (input/output) DOUBLE PRECISION array, dimension (LDVT, NCVT) +* On entry, an N-by-NCVT matrix VT. +* On exit, VT is overwritten by P' * VT. +* VT is not referenced if NCVT = 0. +* +* LDVT (input) INTEGER +* The leading dimension of the array VT. +* LDVT >= max(1,N) if NCVT > 0; LDVT >= 1 if NCVT = 0. +* +* U (input/output) DOUBLE PRECISION array, dimension (LDU, N) +* On entry, an NRU-by-N matrix U. +* On exit, U is overwritten by U * Q. +* U is not referenced if NRU = 0. +* +* LDU (input) INTEGER +* The leading dimension of the array U. LDU >= max(1,NRU). +* +* C (input/output) DOUBLE PRECISION array, dimension (LDC, NCC) +* On entry, an N-by-NCC matrix C. +* On exit, C is overwritten by Q' * C. +* C is not referenced if NCC = 0. +* +* LDC (input) INTEGER +* The leading dimension of the array C. +* LDC >= max(1,N) if NCC > 0; LDC >=1 if NCC = 0. +* +* WORK (workspace) DOUBLE PRECISION array, dimension +* 2*N if only singular values wanted (NCVT = NRU = NCC = 0) +* max( 1, 4*N-4 ) otherwise +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: If INFO = -i, the i-th argument had an illegal value +* > 0: the algorithm did not converge; D and E contain the +* elements of a bidiagonal matrix which is orthogonally +* similar to the input matrix B; if INFO = i, i +* elements of E have not converged to zero. +* +* Internal Parameters +* =================== +* +* TOLMUL DOUBLE PRECISION, default = max(10,min(100,EPS**(-1/8))) +* TOLMUL controls the convergence criterion of the QR loop. +* If it is positive, TOLMUL*EPS is the desired relative +* precision in the computed singular values. +* If it is negative, abs(TOLMUL*EPS*sigma_max) is the +* desired absolute accuracy in the computed singular +* values (corresponds to relative accuracy +* abs(TOLMUL*EPS) in the largest singular value. +* abs(TOLMUL) should be between 1 and 1/EPS, and preferably +* between 10 (for fast convergence) and .1/EPS +* (for there to be some accuracy in the results). +* Default is to lose at either one eighth or 2 of the +* available decimal digits in each computed singular value +* (whichever is smaller). +* +* MAXITR INTEGER, default = 6 +* MAXITR controls the maximum number of passes of the +* algorithm through its inner loop. The algorithms stops +* (and so fails to converge) if the number of passes +* through the inner loop exceeds MAXITR*N**2. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D0 ) + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D0 ) + DOUBLE PRECISION NEGONE + PARAMETER ( NEGONE = -1.0D0 ) + DOUBLE PRECISION HNDRTH + PARAMETER ( HNDRTH = 0.01D0 ) + DOUBLE PRECISION TEN + PARAMETER ( TEN = 10.0D0 ) + DOUBLE PRECISION HNDRD + PARAMETER ( HNDRD = 100.0D0 ) + DOUBLE PRECISION MEIGTH + PARAMETER ( MEIGTH = -0.125D0 ) + INTEGER MAXITR + PARAMETER ( MAXITR = 6 ) +* .. +* .. Local Scalars .. + LOGICAL ROTATE + INTEGER I, IDIR, IROT, ISUB, ITER, IUPLO, J, LL, LLL, + $ M, MAXIT, NM1, NM12, NM13, OLDLL, OLDM + DOUBLE PRECISION ABSE, ABSS, COSL, COSR, CS, EPS, F, G, H, MU, + $ OLDCS, OLDSN, R, SHIFT, SIGMN, SIGMX, SINL, + $ SINR, SLL, SMAX, SMIN, SMINL, SMINLO, SMINOA, + $ SN, THRESH, TOL, TOLMUL, UNFL +* .. +* .. External Functions .. + LOGICAL LSAME + DOUBLE PRECISION DLAMCH + EXTERNAL LSAME, DLAMCH +* .. +* .. External Subroutines .. + EXTERNAL DLARTG, DLAS2, DLASQ1, DLASR, DLASV2, DROT, + $ DSCAL, DSWAP, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, DBLE, MAX, MIN, SIGN, SQRT +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + IUPLO = 0 + IF( LSAME( UPLO, 'U' ) ) + $ IUPLO = 1 + IF( LSAME( UPLO, 'L' ) ) + $ IUPLO = 2 + IF( IUPLO.EQ.0 ) THEN + INFO = -1 + ELSE IF( N.LT.0 ) THEN + INFO = -2 + ELSE IF( NCVT.LT.0 ) THEN + INFO = -3 + ELSE IF( NRU.LT.0 ) THEN + INFO = -4 + ELSE IF( NCC.LT.0 ) THEN + INFO = -5 + ELSE IF( ( NCVT.EQ.0 .AND. LDVT.LT.1 ) .OR. + $ ( NCVT.GT.0 .AND. LDVT.LT.MAX( 1, N ) ) ) THEN + INFO = -9 + ELSE IF( LDU.LT.MAX( 1, NRU ) ) THEN + INFO = -11 + ELSE IF( ( NCC.EQ.0 .AND. LDC.LT.1 ) .OR. + $ ( NCC.GT.0 .AND. LDC.LT.MAX( 1, N ) ) ) THEN + INFO = -13 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DBDSQR', -INFO ) + RETURN + END IF + IF( N.EQ.0 ) + $ RETURN + IF( N.EQ.1 ) + $ GO TO 150 +* +* ROTATE is true if any singular vectors desired, false otherwise +* + ROTATE = ( NCVT.GT.0 ) .OR. ( NRU.GT.0 ) .OR. ( NCC.GT.0 ) +* +* If no singular vectors desired, use qd algorithm +* + IF( .NOT.ROTATE ) THEN + CALL DLASQ1( N, D, E, WORK, INFO ) + RETURN + END IF +* + NM1 = N - 1 + NM12 = NM1 + NM1 + NM13 = NM12 + NM1 +* +* Get machine constants +* + EPS = DLAMCH( 'Epsilon' ) + UNFL = DLAMCH( 'Safe minimum' ) +* +* If matrix lower bidiagonal, rotate to be upper bidiagonal +* by applying Givens rotations on the left +* + IF( IUPLO.EQ.2 ) THEN + DO 10 I = 1, N - 1 + CALL DLARTG( D( I ), E( I ), CS, SN, R ) + D( I ) = R + E( I ) = SN*D( I+1 ) + D( I+1 ) = CS*D( I+1 ) + WORK( I ) = CS + WORK( NM1+I ) = SN + 10 CONTINUE +* +* Update singular vectors if desired +* + IF( NRU.GT.0 ) + $ CALL DLASR( 'R', 'V', 'F', NRU, N, WORK( 1 ), WORK( N ), U, + $ LDU ) + IF( NCC.GT.0 ) + $ CALL DLASR( 'L', 'V', 'F', N, NCC, WORK( 1 ), WORK( N ), C, + $ LDC ) + END IF +* +* Compute singular values to relative accuracy TOL +* (By setting TOL to be negative, algorithm will compute +* singular values to absolute accuracy ABS(TOL)*norm(input matrix)) +* + TOLMUL = MAX( TEN, MIN( HNDRD, EPS**MEIGTH ) ) + TOL = TOLMUL*EPS +* +* Compute approximate maximum, minimum singular values +* + SMAX = ABS( D( N ) ) + DO 20 I = 1, N - 1 + SMAX = MAX( SMAX, ABS( D( I ) ), ABS( E( I ) ) ) + 20 CONTINUE + SMINL = ZERO + IF( TOL.GE.ZERO ) THEN +* +* Relative accuracy desired +* + SMINOA = ABS( D( 1 ) ) + IF( SMINOA.EQ.ZERO ) + $ GO TO 40 + MU = SMINOA + DO 30 I = 2, N + MU = ABS( D( I ) )*( MU / ( MU+ABS( E( I-1 ) ) ) ) + SMINOA = MIN( SMINOA, MU ) + IF( SMINOA.EQ.ZERO ) + $ GO TO 40 + 30 CONTINUE + 40 CONTINUE + SMINOA = SMINOA / SQRT( DBLE( N ) ) + THRESH = MAX( TOL*SMINOA, MAXITR*N*N*UNFL ) + ELSE +* +* Absolute accuracy desired +* + THRESH = MAX( ABS( TOL )*SMAX, MAXITR*N*N*UNFL ) + END IF +* +* Prepare for main iteration loop for the singular values +* (MAXIT is the maximum number of passes through the inner +* loop permitted before nonconvergence signalled.) +* + MAXIT = MAXITR*N*N + ITER = 0 + OLDLL = -1 + OLDM = -1 +* +* M points to last element of unconverged part of matrix +* + M = N +* +* Begin main iteration loop +* + 50 CONTINUE +* +* Check for convergence or exceeding iteration count +* + IF( M.LE.1 ) + $ GO TO 150 + IF( ITER.GT.MAXIT ) + $ GO TO 190 +* +* Find diagonal block of matrix to work on +* + IF( TOL.LT.ZERO .AND. ABS( D( M ) ).LE.THRESH ) + $ D( M ) = ZERO + SMAX = ABS( D( M ) ) + SMIN = SMAX + DO 60 LLL = 1, M + LL = M - LLL + IF( LL.EQ.0 ) + $ GO TO 80 + ABSS = ABS( D( LL ) ) + ABSE = ABS( E( LL ) ) + IF( TOL.LT.ZERO .AND. ABSS.LE.THRESH ) + $ D( LL ) = ZERO + IF( ABSE.LE.THRESH ) + $ GO TO 70 + SMIN = MIN( SMIN, ABSS ) + SMAX = MAX( SMAX, ABSS, ABSE ) + 60 CONTINUE + 70 CONTINUE + E( LL ) = ZERO +* +* Matrix splits since E(LL) = 0 +* + IF( LL.EQ.M-1 ) THEN +* +* Convergence of bottom singular value, return to top of loop +* + M = M - 1 + GO TO 50 + END IF + 80 CONTINUE + LL = LL + 1 +* +* E(LL) through E(M-1) are nonzero, E(LL-1) is zero +* + IF( LL.EQ.M-1 ) THEN +* +* 2 by 2 block, handle separately +* + CALL DLASV2( D( M-1 ), E( M-1 ), D( M ), SIGMN, SIGMX, SINR, + $ COSR, SINL, COSL ) + D( M-1 ) = SIGMX + E( M-1 ) = ZERO + D( M ) = SIGMN +* +* Compute singular vectors, if desired +* + IF( NCVT.GT.0 ) + $ CALL DROT( NCVT, VT( M-1, 1 ), LDVT, VT( M, 1 ), LDVT, COSR, + $ SINR ) + IF( NRU.GT.0 ) + $ CALL DROT( NRU, U( 1, M-1 ), 1, U( 1, M ), 1, COSL, SINL ) + IF( NCC.GT.0 ) + $ CALL DROT( NCC, C( M-1, 1 ), LDC, C( M, 1 ), LDC, COSL, + $ SINL ) + M = M - 2 + GO TO 50 + END IF +* +* If working on new submatrix, choose shift direction +* (from larger end diagonal element towards smaller) +* + IF( LL.GT.OLDM .OR. M.LT.OLDLL ) THEN + IF( ABS( D( LL ) ).GE.ABS( D( M ) ) ) THEN +* +* Chase bulge from top (big end) to bottom (small end) +* + IDIR = 1 + ELSE +* +* Chase bulge from bottom (big end) to top (small end) +* + IDIR = 2 + END IF + END IF +* +* Apply convergence tests +* + IF( IDIR.EQ.1 ) THEN +* +* Run convergence test in forward direction +* First apply standard test to bottom of matrix +* + IF( ABS( E( M-1 ) ).LE.ABS( TOL )*ABS( D( M ) ) .OR. + $ ( TOL.LT.ZERO .AND. ABS( E( M-1 ) ).LE.THRESH ) ) THEN + E( M-1 ) = ZERO + GO TO 50 + END IF +* + IF( TOL.GE.ZERO ) THEN +* +* If relative accuracy desired, +* apply convergence criterion forward +* + MU = ABS( D( LL ) ) + SMINL = MU + DO 90 LLL = LL, M - 1 + IF( ABS( E( LLL ) ).LE.TOL*MU ) THEN + E( LLL ) = ZERO + GO TO 50 + END IF + SMINLO = SMINL + MU = ABS( D( LLL+1 ) )*( MU / ( MU+ABS( E( LLL ) ) ) ) + SMINL = MIN( SMINL, MU ) + 90 CONTINUE + END IF +* + ELSE +* +* Run convergence test in backward direction +* First apply standard test to top of matrix +* + IF( ABS( E( LL ) ).LE.ABS( TOL )*ABS( D( LL ) ) .OR. + $ ( TOL.LT.ZERO .AND. ABS( E( LL ) ).LE.THRESH ) ) THEN + E( LL ) = ZERO + GO TO 50 + END IF +* + IF( TOL.GE.ZERO ) THEN +* +* If relative accuracy desired, +* apply convergence criterion backward +* + MU = ABS( D( M ) ) + SMINL = MU + DO 100 LLL = M - 1, LL, -1 + IF( ABS( E( LLL ) ).LE.TOL*MU ) THEN + E( LLL ) = ZERO + GO TO 50 + END IF + SMINLO = SMINL + MU = ABS( D( LLL ) )*( MU / ( MU+ABS( E( LLL ) ) ) ) + SMINL = MIN( SMINL, MU ) + 100 CONTINUE + END IF + END IF + OLDLL = LL + OLDM = M +* +* Compute shift. First, test if shifting would ruin relative +* accuracy, and if so set the shift to zero. +* + IF( TOL.GE.ZERO .AND. N*TOL*( SMINL / SMAX ).LE. + $ MAX( EPS, HNDRTH*TOL ) ) THEN +* +* Use a zero shift to avoid loss of relative accuracy +* + SHIFT = ZERO + ELSE +* +* Compute the shift from 2-by-2 block at end of matrix +* + IF( IDIR.EQ.1 ) THEN + SLL = ABS( D( LL ) ) + CALL DLAS2( D( M-1 ), E( M-1 ), D( M ), SHIFT, R ) + ELSE + SLL = ABS( D( M ) ) + CALL DLAS2( D( LL ), E( LL ), D( LL+1 ), SHIFT, R ) + END IF +* +* Test if shift negligible, and if so set to zero +* + IF( SLL.GT.ZERO ) THEN + IF( ( SHIFT / SLL )**2.LT.EPS ) + $ SHIFT = ZERO + END IF + END IF +* +* Increment iteration count +* + ITER = ITER + M - LL +* +* If SHIFT = 0, do simplified QR iteration +* + IF( SHIFT.EQ.ZERO ) THEN + IF( IDIR.EQ.1 ) THEN +* +* Chase bulge from top to bottom +* Save cosines and sines for later singular vector updates +* + CS = ONE + OLDCS = ONE + CALL DLARTG( D( LL )*CS, E( LL ), CS, SN, R ) + CALL DLARTG( OLDCS*R, D( LL+1 )*SN, OLDCS, OLDSN, D( LL ) ) + WORK( 1 ) = CS + WORK( 1+NM1 ) = SN + WORK( 1+NM12 ) = OLDCS + WORK( 1+NM13 ) = OLDSN + IROT = 1 + DO 110 I = LL + 1, M - 1 + CALL DLARTG( D( I )*CS, E( I ), CS, SN, R ) + E( I-1 ) = OLDSN*R + CALL DLARTG( OLDCS*R, D( I+1 )*SN, OLDCS, OLDSN, D( I ) ) + IROT = IROT + 1 + WORK( IROT ) = CS + WORK( IROT+NM1 ) = SN + WORK( IROT+NM12 ) = OLDCS + WORK( IROT+NM13 ) = OLDSN + 110 CONTINUE + H = D( M )*CS + D( M ) = H*OLDCS + E( M-1 ) = H*OLDSN +* +* Update singular vectors +* + IF( NCVT.GT.0 ) + $ CALL DLASR( 'L', 'V', 'F', M-LL+1, NCVT, WORK( 1 ), + $ WORK( N ), VT( LL, 1 ), LDVT ) + IF( NRU.GT.0 ) + $ CALL DLASR( 'R', 'V', 'F', NRU, M-LL+1, WORK( NM12+1 ), + $ WORK( NM13+1 ), U( 1, LL ), LDU ) + IF( NCC.GT.0 ) + $ CALL DLASR( 'L', 'V', 'F', M-LL+1, NCC, WORK( NM12+1 ), + $ WORK( NM13+1 ), C( LL, 1 ), LDC ) +* +* Test convergence +* + IF( ABS( E( M-1 ) ).LE.THRESH ) + $ E( M-1 ) = ZERO +* + ELSE +* +* Chase bulge from bottom to top +* Save cosines and sines for later singular vector updates +* + CS = ONE + OLDCS = ONE + CALL DLARTG( D( M )*CS, E( M-1 ), CS, SN, R ) + CALL DLARTG( OLDCS*R, D( M-1 )*SN, OLDCS, OLDSN, D( M ) ) + WORK( M-LL ) = CS + WORK( M-LL+NM1 ) = -SN + WORK( M-LL+NM12 ) = OLDCS + WORK( M-LL+NM13 ) = -OLDSN + IROT = M - LL + DO 120 I = M - 1, LL + 1, -1 + CALL DLARTG( D( I )*CS, E( I-1 ), CS, SN, R ) + E( I ) = OLDSN*R + CALL DLARTG( OLDCS*R, D( I-1 )*SN, OLDCS, OLDSN, D( I ) ) + IROT = IROT - 1 + WORK( IROT ) = CS + WORK( IROT+NM1 ) = -SN + WORK( IROT+NM12 ) = OLDCS + WORK( IROT+NM13 ) = -OLDSN + 120 CONTINUE + H = D( LL )*CS + D( LL ) = H*OLDCS + E( LL ) = H*OLDSN +* +* Update singular vectors +* + IF( NCVT.GT.0 ) + $ CALL DLASR( 'L', 'V', 'B', M-LL+1, NCVT, WORK( NM12+1 ), + $ WORK( NM13+1 ), VT( LL, 1 ), LDVT ) + IF( NRU.GT.0 ) + $ CALL DLASR( 'R', 'V', 'B', NRU, M-LL+1, WORK( 1 ), + $ WORK( N ), U( 1, LL ), LDU ) + IF( NCC.GT.0 ) + $ CALL DLASR( 'L', 'V', 'B', M-LL+1, NCC, WORK( 1 ), + $ WORK( N ), C( LL, 1 ), LDC ) +* +* Test convergence +* + IF( ABS( E( LL ) ).LE.THRESH ) + $ E( LL ) = ZERO + END IF + ELSE +* +* Use nonzero shift +* + IF( IDIR.EQ.1 ) THEN +* +* Chase bulge from top to bottom +* Save cosines and sines for later singular vector updates +* + F = ( ABS( D( LL ) )-SHIFT )* + $ ( SIGN( ONE, D( LL ) )+SHIFT / D( LL ) ) + G = E( LL ) + CALL DLARTG( F, G, COSR, SINR, R ) + F = COSR*D( LL ) + SINR*E( LL ) + E( LL ) = COSR*E( LL ) - SINR*D( LL ) + G = SINR*D( LL+1 ) + D( LL+1 ) = COSR*D( LL+1 ) + CALL DLARTG( F, G, COSL, SINL, R ) + D( LL ) = R + F = COSL*E( LL ) + SINL*D( LL+1 ) + D( LL+1 ) = COSL*D( LL+1 ) - SINL*E( LL ) + G = SINL*E( LL+1 ) + E( LL+1 ) = COSL*E( LL+1 ) + WORK( 1 ) = COSR + WORK( 1+NM1 ) = SINR + WORK( 1+NM12 ) = COSL + WORK( 1+NM13 ) = SINL + IROT = 1 + DO 130 I = LL + 1, M - 2 + CALL DLARTG( F, G, COSR, SINR, R ) + E( I-1 ) = R + F = COSR*D( I ) + SINR*E( I ) + E( I ) = COSR*E( I ) - SINR*D( I ) + G = SINR*D( I+1 ) + D( I+1 ) = COSR*D( I+1 ) + CALL DLARTG( F, G, COSL, SINL, R ) + D( I ) = R + F = COSL*E( I ) + SINL*D( I+1 ) + D( I+1 ) = COSL*D( I+1 ) - SINL*E( I ) + G = SINL*E( I+1 ) + E( I+1 ) = COSL*E( I+1 ) + IROT = IROT + 1 + WORK( IROT ) = COSR + WORK( IROT+NM1 ) = SINR + WORK( IROT+NM12 ) = COSL + WORK( IROT+NM13 ) = SINL + 130 CONTINUE + CALL DLARTG( F, G, COSR, SINR, R ) + E( M-2 ) = R + F = COSR*D( M-1 ) + SINR*E( M-1 ) + E( M-1 ) = COSR*E( M-1 ) - SINR*D( M-1 ) + G = SINR*D( M ) + D( M ) = COSR*D( M ) + CALL DLARTG( F, G, COSL, SINL, R ) + D( M-1 ) = R + F = COSL*E( M-1 ) + SINL*D( M ) + D( M ) = COSL*D( M ) - SINL*E( M-1 ) + IROT = IROT + 1 + WORK( IROT ) = COSR + WORK( IROT+NM1 ) = SINR + WORK( IROT+NM12 ) = COSL + WORK( IROT+NM13 ) = SINL + E( M-1 ) = F +* +* Update singular vectors +* + IF( NCVT.GT.0 ) + $ CALL DLASR( 'L', 'V', 'F', M-LL+1, NCVT, WORK( 1 ), + $ WORK( N ), VT( LL, 1 ), LDVT ) + IF( NRU.GT.0 ) + $ CALL DLASR( 'R', 'V', 'F', NRU, M-LL+1, WORK( NM12+1 ), + $ WORK( NM13+1 ), U( 1, LL ), LDU ) + IF( NCC.GT.0 ) + $ CALL DLASR( 'L', 'V', 'F', M-LL+1, NCC, WORK( NM12+1 ), + $ WORK( NM13+1 ), C( LL, 1 ), LDC ) +* +* Test convergence +* + IF( ABS( E( M-1 ) ).LE.THRESH ) + $ E( M-1 ) = ZERO +* + ELSE +* +* Chase bulge from bottom to top +* Save cosines and sines for later singular vector updates +* + F = ( ABS( D( M ) )-SHIFT )*( SIGN( ONE, D( M ) )+SHIFT / + $ D( M ) ) + G = E( M-1 ) + CALL DLARTG( F, G, COSR, SINR, R ) + F = COSR*D( M ) + SINR*E( M-1 ) + E( M-1 ) = COSR*E( M-1 ) - SINR*D( M ) + G = SINR*D( M-1 ) + D( M-1 ) = COSR*D( M-1 ) + CALL DLARTG( F, G, COSL, SINL, R ) + D( M ) = R + F = COSL*E( M-1 ) + SINL*D( M-1 ) + D( M-1 ) = COSL*D( M-1 ) - SINL*E( M-1 ) + G = SINL*E( M-2 ) + E( M-2 ) = COSL*E( M-2 ) + WORK( M-LL ) = COSR + WORK( M-LL+NM1 ) = -SINR + WORK( M-LL+NM12 ) = COSL + WORK( M-LL+NM13 ) = -SINL + IROT = M - LL + DO 140 I = M - 1, LL + 2, -1 + CALL DLARTG( F, G, COSR, SINR, R ) + E( I ) = R + F = COSR*D( I ) + SINR*E( I-1 ) + E( I-1 ) = COSR*E( I-1 ) - SINR*D( I ) + G = SINR*D( I-1 ) + D( I-1 ) = COSR*D( I-1 ) + CALL DLARTG( F, G, COSL, SINL, R ) + D( I ) = R + F = COSL*E( I-1 ) + SINL*D( I-1 ) + D( I-1 ) = COSL*D( I-1 ) - SINL*E( I-1 ) + G = SINL*E( I-2 ) + E( I-2 ) = COSL*E( I-2 ) + IROT = IROT - 1 + WORK( IROT ) = COSR + WORK( IROT+NM1 ) = -SINR + WORK( IROT+NM12 ) = COSL + WORK( IROT+NM13 ) = -SINL + 140 CONTINUE + CALL DLARTG( F, G, COSR, SINR, R ) + E( LL+1 ) = R + F = COSR*D( LL+1 ) + SINR*E( LL ) + E( LL ) = COSR*E( LL ) - SINR*D( LL+1 ) + G = SINR*D( LL ) + D( LL ) = COSR*D( LL ) + CALL DLARTG( F, G, COSL, SINL, R ) + D( LL+1 ) = R + F = COSL*E( LL ) + SINL*D( LL ) + D( LL ) = COSL*D( LL ) - SINL*E( LL ) + IROT = IROT - 1 + WORK( IROT ) = COSR + WORK( IROT+NM1 ) = -SINR + WORK( IROT+NM12 ) = COSL + WORK( IROT+NM13 ) = -SINL + E( LL ) = F +* +* Test convergence +* + IF( ABS( E( LL ) ).LE.THRESH ) + $ E( LL ) = ZERO +* +* Update singular vectors if desired +* + IF( NCVT.GT.0 ) + $ CALL DLASR( 'L', 'V', 'B', M-LL+1, NCVT, WORK( NM12+1 ), + $ WORK( NM13+1 ), VT( LL, 1 ), LDVT ) + IF( NRU.GT.0 ) + $ CALL DLASR( 'R', 'V', 'B', NRU, M-LL+1, WORK( 1 ), + $ WORK( N ), U( 1, LL ), LDU ) + IF( NCC.GT.0 ) + $ CALL DLASR( 'L', 'V', 'B', M-LL+1, NCC, WORK( 1 ), + $ WORK( N ), C( LL, 1 ), LDC ) + END IF + END IF +* +* QR iteration finished, go back and check convergence +* + GO TO 50 +* +* All singular values converged, so make them positive +* + 150 CONTINUE + DO 160 I = 1, N + IF( D( I ).LT.ZERO ) THEN + D( I ) = -D( I ) +* +* Change sign of singular vectors, if desired +* + IF( NCVT.GT.0 ) + $ CALL DSCAL( NCVT, NEGONE, VT( I, 1 ), LDVT ) + END IF + 160 CONTINUE +* +* Sort the singular values into decreasing order (insertion sort on +* singular values, but only one transposition per singular vector) +* + DO 180 I = 1, N - 1 +* +* Scan for smallest D(I) +* + ISUB = 1 + SMIN = D( 1 ) + DO 170 J = 2, N + 1 - I + IF( D( J ).LE.SMIN ) THEN + ISUB = J + SMIN = D( J ) + END IF + 170 CONTINUE + IF( ISUB.NE.N+1-I ) THEN +* +* Swap singular values and vectors +* + D( ISUB ) = D( N+1-I ) + D( N+1-I ) = SMIN + IF( NCVT.GT.0 ) + $ CALL DSWAP( NCVT, VT( ISUB, 1 ), LDVT, VT( N+1-I, 1 ), + $ LDVT ) + IF( NRU.GT.0 ) + $ CALL DSWAP( NRU, U( 1, ISUB ), 1, U( 1, N+1-I ), 1 ) + IF( NCC.GT.0 ) + $ CALL DSWAP( NCC, C( ISUB, 1 ), LDC, C( N+1-I, 1 ), LDC ) + END IF + 180 CONTINUE + GO TO 210 +* +* Maximum number of iterations exceeded, failure to converge +* + 190 CONTINUE + INFO = 0 + DO 200 I = 1, N - 1 + IF( E( I ).NE.ZERO ) + $ INFO = INFO + 1 + 200 CONTINUE + 210 CONTINUE + RETURN +* +* End of DBDSQR +* + END diff --git a/ext/lapack/dgbsv.f b/ext/lapack/dgbsv.f new file mode 100755 index 000000000..e2d8b5ebd --- /dev/null +++ b/ext/lapack/dgbsv.f @@ -0,0 +1,144 @@ + SUBROUTINE DGBSV( N, KL, KU, NRHS, AB, LDAB, IPIV, B, LDB, INFO ) +* +* -- LAPACK driver routine (version 3.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* March 31, 1993 +* +* .. Scalar Arguments .. + INTEGER INFO, KL, KU, LDAB, LDB, N, NRHS +* .. +* .. Array Arguments .. + INTEGER IPIV( * ) + DOUBLE PRECISION AB( LDAB, * ), B( LDB, * ) +* .. +* +* Purpose +* ======= +* +* DGBSV computes the solution to a real system of linear equations +* A * X = B, where A is a band matrix of order N with KL subdiagonals +* and KU superdiagonals, and X and B are N-by-NRHS matrices. +* +* The LU decomposition with partial pivoting and row interchanges is +* used to factor A as A = L * U, where L is a product of permutation +* and unit lower triangular matrices with KL subdiagonals, and U is +* upper triangular with KL+KU superdiagonals. The factored form of A +* is then used to solve the system of equations A * X = B. +* +* Arguments +* ========= +* +* N (input) INTEGER +* The number of linear equations, i.e., the order of the +* matrix A. N >= 0. +* +* KL (input) INTEGER +* The number of subdiagonals within the band of A. KL >= 0. +* +* KU (input) INTEGER +* The number of superdiagonals within the band of A. KU >= 0. +* +* NRHS (input) INTEGER +* The number of right hand sides, i.e., the number of columns +* of the matrix B. NRHS >= 0. +* +* AB (input/output) DOUBLE PRECISION array, dimension (LDAB,N) +* On entry, the matrix A in band storage, in rows KL+1 to +* 2*KL+KU+1; rows 1 to KL of the array need not be set. +* The j-th column of A is stored in the j-th column of the +* array AB as follows: +* AB(KL+KU+1+i-j,j) = A(i,j) for max(1,j-KU)<=i<=min(N,j+KL) +* On exit, details of the factorization: U is stored as an +* upper triangular band matrix with KL+KU superdiagonals in +* rows 1 to KL+KU+1, and the multipliers used during the +* factorization are stored in rows KL+KU+2 to 2*KL+KU+1. +* See below for further details. +* +* LDAB (input) INTEGER +* The leading dimension of the array AB. LDAB >= 2*KL+KU+1. +* +* IPIV (output) INTEGER array, dimension (N) +* The pivot indices that define the permutation matrix P; +* row i of the matrix was interchanged with row IPIV(i). +* +* B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS) +* On entry, the N-by-NRHS right hand side matrix B. +* On exit, if INFO = 0, the N-by-NRHS solution matrix X. +* +* LDB (input) INTEGER +* The leading dimension of the array B. LDB >= max(1,N). +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument had an illegal value +* > 0: if INFO = i, U(i,i) is exactly zero. The factorization +* has been completed, but the factor U is exactly +* singular, and the solution has not been computed. +* +* Further Details +* =============== +* +* The band storage scheme is illustrated by the following example, when +* M = N = 6, KL = 2, KU = 1: +* +* On entry: On exit: +* +* * * * + + + * * * u14 u25 u36 +* * * + + + + * * u13 u24 u35 u46 +* * a12 a23 a34 a45 a56 * u12 u23 u34 u45 u56 +* a11 a22 a33 a44 a55 a66 u11 u22 u33 u44 u55 u66 +* a21 a32 a43 a54 a65 * m21 m32 m43 m54 m65 * +* a31 a42 a53 a64 * * m31 m42 m53 m64 * * +* +* Array elements marked * are not used by the routine; elements marked +* + need not be set on entry, but are required by the routine to store +* elements of U because of fill-in resulting from the row interchanges. +* +* ===================================================================== +* +* .. External Subroutines .. + EXTERNAL DGBTRF, DGBTRS, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + + INFO = 0 + IF( N.LT.0 ) THEN + INFO = -1 + ELSE IF( KL.LT.0 ) THEN + INFO = -2 + ELSE IF( KU.LT.0 ) THEN + INFO = -3 + ELSE IF( NRHS.LT.0 ) THEN + INFO = -4 + ELSE IF( LDAB.LT.2*KL+KU+1 ) THEN + INFO = -6 + ELSE IF( LDB.LT.MAX( N, 1 ) ) THEN + INFO = -9 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DGBSV ', -INFO ) + RETURN + END IF +* +* Compute the LU factorization of the band matrix A. +* + CALL DGBTRF( N, N, KL, KU, AB, LDAB, IPIV, INFO ) + IF( INFO.EQ.0 ) THEN +* +* Solve the system A*X = B, overwriting B with X. +* + CALL DGBTRS( 'No transpose', N, KL, KU, NRHS, AB, LDAB, IPIV, + $ B, LDB, INFO ) + END IF + RETURN +* +* End of DGBSV +* + END diff --git a/ext/lapack/dgbtf2.f b/ext/lapack/dgbtf2.f new file mode 100755 index 000000000..5e25629fc --- /dev/null +++ b/ext/lapack/dgbtf2.f @@ -0,0 +1,203 @@ + SUBROUTINE DGBTF2( M, N, KL, KU, AB, LDAB, IPIV, INFO ) +* +* -- LAPACK routine (version 3.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* February 29, 1992 +* +* .. Scalar Arguments .. + INTEGER INFO, KL, KU, LDAB, M, N +* .. +* .. Array Arguments .. + INTEGER IPIV( * ) + DOUBLE PRECISION AB( LDAB, * ) +* .. +* +* Purpose +* ======= +* +* DGBTF2 computes an LU factorization of a real m-by-n band matrix A +* using partial pivoting with row interchanges. +* +* This is the unblocked version of the algorithm, calling Level 2 BLAS. +* +* Arguments +* ========= +* +* M (input) INTEGER +* The number of rows of the matrix A. M >= 0. +* +* N (input) INTEGER +* The number of columns of the matrix A. N >= 0. +* +* KL (input) INTEGER +* The number of subdiagonals within the band of A. KL >= 0. +* +* KU (input) INTEGER +* The number of superdiagonals within the band of A. KU >= 0. +* +* AB (input/output) DOUBLE PRECISION array, dimension (LDAB,N) +* On entry, the matrix A in band storage, in rows KL+1 to +* 2*KL+KU+1; rows 1 to KL of the array need not be set. +* The j-th column of A is stored in the j-th column of the +* array AB as follows: +* AB(kl+ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(m,j+kl) +* +* On exit, details of the factorization: U is stored as an +* upper triangular band matrix with KL+KU superdiagonals in +* rows 1 to KL+KU+1, and the multipliers used during the +* factorization are stored in rows KL+KU+2 to 2*KL+KU+1. +* See below for further details. +* +* LDAB (input) INTEGER +* The leading dimension of the array AB. LDAB >= 2*KL+KU+1. +* +* IPIV (output) INTEGER array, dimension (min(M,N)) +* The pivot indices; for 1 <= i <= min(M,N), row i of the +* matrix was interchanged with row IPIV(i). +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument had an illegal value +* > 0: if INFO = +i, U(i,i) is exactly zero. The factorization +* has been completed, but the factor U is exactly +* singular, and division by zero will occur if it is used +* to solve a system of equations. +* +* Further Details +* =============== +* +* The band storage scheme is illustrated by the following example, when +* M = N = 6, KL = 2, KU = 1: +* +* On entry: On exit: +* +* * * * + + + * * * u14 u25 u36 +* * * + + + + * * u13 u24 u35 u46 +* * a12 a23 a34 a45 a56 * u12 u23 u34 u45 u56 +* a11 a22 a33 a44 a55 a66 u11 u22 u33 u44 u55 u66 +* a21 a32 a43 a54 a65 * m21 m32 m43 m54 m65 * +* a31 a42 a53 a64 * * m31 m42 m53 m64 * * +* +* Array elements marked * are not used by the routine; elements marked +* + need not be set on entry, but are required by the routine to store +* elements of U, because of fill-in resulting from the row +* interchanges. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER I, J, JP, JU, KM, KV +* .. +* .. External Functions .. + INTEGER IDAMAX + EXTERNAL IDAMAX +* .. +* .. External Subroutines .. + EXTERNAL DGER, DSCAL, DSWAP, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. Executable Statements .. +* +* KV is the number of superdiagonals in the factor U, allowing for +* fill-in. +* + KV = KU + KL +* +* Test the input parameters. +* + INFO = 0 + IF( M.LT.0 ) THEN + INFO = -1 + ELSE IF( N.LT.0 ) THEN + INFO = -2 + ELSE IF( KL.LT.0 ) THEN + INFO = -3 + ELSE IF( KU.LT.0 ) THEN + INFO = -4 + ELSE IF( LDAB.LT.KL+KV+1 ) THEN + INFO = -6 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DGBTF2', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( M.EQ.0 .OR. N.EQ.0 ) + $ RETURN +* +* Gaussian elimination with partial pivoting +* +* Set fill-in elements in columns KU+2 to KV to zero. +* + DO 20 J = KU + 2, MIN( KV, N ) + DO 10 I = KV - J + 2, KL + AB( I, J ) = ZERO + 10 CONTINUE + 20 CONTINUE +* +* JU is the index of the last column affected by the current stage +* of the factorization. +* + JU = 1 +* + DO 40 J = 1, MIN( M, N ) +* +* Set fill-in elements in column J+KV to zero. +* + IF( J+KV.LE.N ) THEN + DO 30 I = 1, KL + AB( I, J+KV ) = ZERO + 30 CONTINUE + END IF +* +* Find pivot and test for singularity. KM is the number of +* subdiagonal elements in the current column. +* + KM = MIN( KL, M-J ) + JP = IDAMAX( KM+1, AB( KV+1, J ), 1 ) + IPIV( J ) = JP + J - 1 + IF( AB( KV+JP, J ).NE.ZERO ) THEN + JU = MAX( JU, MIN( J+KU+JP-1, N ) ) +* +* Apply interchange to columns J to JU. +* + IF( JP.NE.1 ) + $ CALL DSWAP( JU-J+1, AB( KV+JP, J ), LDAB-1, + $ AB( KV+1, J ), LDAB-1 ) +* + IF( KM.GT.0 ) THEN +* +* Compute multipliers. +* + CALL DSCAL( KM, ONE / AB( KV+1, J ), AB( KV+2, J ), 1 ) +* +* Update trailing submatrix within the band. +* + IF( JU.GT.J ) + $ CALL DGER( KM, JU-J, -ONE, AB( KV+2, J ), 1, + $ AB( KV, J+1 ), LDAB-1, AB( KV+1, J+1 ), + $ LDAB-1 ) + END IF + ELSE +* +* If pivot is zero, set INFO to the index of the pivot +* unless a zero pivot has already been found. +* + IF( INFO.EQ.0 ) + $ INFO = J + END IF + 40 CONTINUE + RETURN +* +* End of DGBTF2 +* + END diff --git a/ext/lapack/dgbtrf.f b/ext/lapack/dgbtrf.f new file mode 100755 index 000000000..c6e3d0a9c --- /dev/null +++ b/ext/lapack/dgbtrf.f @@ -0,0 +1,442 @@ + SUBROUTINE DGBTRF( M, N, KL, KU, AB, LDAB, IPIV, INFO ) +* +* -- LAPACK routine (version 3.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* February 29, 1992 +* +* .. Scalar Arguments .. + INTEGER INFO, KL, KU, LDAB, M, N +* .. +* .. Array Arguments .. + INTEGER IPIV( * ) + DOUBLE PRECISION AB( LDAB, * ) +* .. +* +* Purpose +* ======= +* +* DGBTRF computes an LU factorization of a real m-by-n band matrix A +* using partial pivoting with row interchanges. +* +* This is the blocked version of the algorithm, calling Level 3 BLAS. +* +* Arguments +* ========= +* +* M (input) INTEGER +* The number of rows of the matrix A. M >= 0. +* +* N (input) INTEGER +* The number of columns of the matrix A. N >= 0. +* +* KL (input) INTEGER +* The number of subdiagonals within the band of A. KL >= 0. +* +* KU (input) INTEGER +* The number of superdiagonals within the band of A. KU >= 0. +* +* AB (input/output) DOUBLE PRECISION array, dimension (LDAB,N) +* On entry, the matrix A in band storage, in rows KL+1 to +* 2*KL+KU+1; rows 1 to KL of the array need not be set. +* The j-th column of A is stored in the j-th column of the +* array AB as follows: +* AB(kl+ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(m,j+kl) +* +* On exit, details of the factorization: U is stored as an +* upper triangular band matrix with KL+KU superdiagonals in +* rows 1 to KL+KU+1, and the multipliers used during the +* factorization are stored in rows KL+KU+2 to 2*KL+KU+1. +* See below for further details. +* +* LDAB (input) INTEGER +* The leading dimension of the array AB. LDAB >= 2*KL+KU+1. +* +* IPIV (output) INTEGER array, dimension (min(M,N)) +* The pivot indices; for 1 <= i <= min(M,N), row i of the +* matrix was interchanged with row IPIV(i). +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument had an illegal value +* > 0: if INFO = +i, U(i,i) is exactly zero. The factorization +* has been completed, but the factor U is exactly +* singular, and division by zero will occur if it is used +* to solve a system of equations. +* +* Further Details +* =============== +* +* The band storage scheme is illustrated by the following example, when +* M = N = 6, KL = 2, KU = 1: +* +* On entry: On exit: +* +* * * * + + + * * * u14 u25 u36 +* * * + + + + * * u13 u24 u35 u46 +* * a12 a23 a34 a45 a56 * u12 u23 u34 u45 u56 +* a11 a22 a33 a44 a55 a66 u11 u22 u33 u44 u55 u66 +* a21 a32 a43 a54 a65 * m21 m32 m43 m54 m65 * +* a31 a42 a53 a64 * * m31 m42 m53 m64 * * +* +* Array elements marked * are not used by the routine; elements marked +* + need not be set on entry, but are required by the routine to store +* elements of U because of fill-in resulting from the row interchanges. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) + INTEGER NBMAX, LDWORK + PARAMETER ( NBMAX = 64, LDWORK = NBMAX+1 ) +* .. +* .. Local Scalars .. + INTEGER I, I2, I3, II, IP, J, J2, J3, JB, JJ, JM, JP, + $ JU, K2, KM, KV, NB, NW + DOUBLE PRECISION TEMP +* .. +* .. Local Arrays .. + DOUBLE PRECISION WORK13( LDWORK, NBMAX ), + $ WORK31( LDWORK, NBMAX ) +* .. +* .. External Functions .. + INTEGER IDAMAX, ILAENV + EXTERNAL IDAMAX, ILAENV +* .. +* .. External Subroutines .. + EXTERNAL DCOPY, DGBTF2, DGEMM, DGER, DLASWP, DSCAL, + $ DSWAP, DTRSM, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. Executable Statements .. +* +* KV is the number of superdiagonals in the factor U, allowing for +* fill-in +* + KV = KU + KL +* +* Test the input parameters. +* + INFO = 0 + IF( M.LT.0 ) THEN + INFO = -1 + ELSE IF( N.LT.0 ) THEN + INFO = -2 + ELSE IF( KL.LT.0 ) THEN + INFO = -3 + ELSE IF( KU.LT.0 ) THEN + INFO = -4 + ELSE IF( LDAB.LT.KL+KV+1 ) THEN + INFO = -6 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DGBTRF', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( M.EQ.0 .OR. N.EQ.0 ) + $ RETURN +* +* Determine the block size for this environment +* + NB = ILAENV( 1, 'DGBTRF', ' ', M, N, KL, KU ) +* +* The block size must not exceed the limit set by the size of the +* local arrays WORK13 and WORK31. +* + NB = MIN( NB, NBMAX ) +* + IF( NB.LE.1 .OR. NB.GT.KL ) THEN +* +* Use unblocked code +* + CALL DGBTF2( M, N, KL, KU, AB, LDAB, IPIV, INFO ) + ELSE +* +* Use blocked code +* +* Zero the superdiagonal elements of the work array WORK13 +* + DO 20 J = 1, NB + DO 10 I = 1, J - 1 + WORK13( I, J ) = ZERO + 10 CONTINUE + 20 CONTINUE +* +* Zero the subdiagonal elements of the work array WORK31 +* + DO 40 J = 1, NB + DO 30 I = J + 1, NB + WORK31( I, J ) = ZERO + 30 CONTINUE + 40 CONTINUE +* +* Gaussian elimination with partial pivoting +* +* Set fill-in elements in columns KU+2 to KV to zero +* + DO 60 J = KU + 2, MIN( KV, N ) + DO 50 I = KV - J + 2, KL + AB( I, J ) = ZERO + 50 CONTINUE + 60 CONTINUE +* +* JU is the index of the last column affected by the current +* stage of the factorization +* + JU = 1 +* + DO 180 J = 1, MIN( M, N ), NB + JB = MIN( NB, MIN( M, N )-J+1 ) +* +* The active part of the matrix is partitioned +* +* A11 A12 A13 +* A21 A22 A23 +* A31 A32 A33 +* +* Here A11, A21 and A31 denote the current block of JB columns +* which is about to be factorized. The number of rows in the +* partitioning are JB, I2, I3 respectively, and the numbers +* of columns are JB, J2, J3. The superdiagonal elements of A13 +* and the subdiagonal elements of A31 lie outside the band. +* + I2 = MIN( KL-JB, M-J-JB+1 ) + I3 = MIN( JB, M-J-KL+1 ) +* +* J2 and J3 are computed after JU has been updated. +* +* Factorize the current block of JB columns +* + DO 80 JJ = J, J + JB - 1 +* +* Set fill-in elements in column JJ+KV to zero +* + IF( JJ+KV.LE.N ) THEN + DO 70 I = 1, KL + AB( I, JJ+KV ) = ZERO + 70 CONTINUE + END IF +* +* Find pivot and test for singularity. KM is the number of +* subdiagonal elements in the current column. +* + KM = MIN( KL, M-JJ ) + JP = IDAMAX( KM+1, AB( KV+1, JJ ), 1 ) + IPIV( JJ ) = JP + JJ - J + IF( AB( KV+JP, JJ ).NE.ZERO ) THEN + JU = MAX( JU, MIN( JJ+KU+JP-1, N ) ) + IF( JP.NE.1 ) THEN +* +* Apply interchange to columns J to J+JB-1 +* + IF( JP+JJ-1.LT.J+KL ) THEN +* + CALL DSWAP( JB, AB( KV+1+JJ-J, J ), LDAB-1, + $ AB( KV+JP+JJ-J, J ), LDAB-1 ) + ELSE +* +* The interchange affects columns J to JJ-1 of A31 +* which are stored in the work array WORK31 +* + CALL DSWAP( JJ-J, AB( KV+1+JJ-J, J ), LDAB-1, + $ WORK31( JP+JJ-J-KL, 1 ), LDWORK ) + CALL DSWAP( J+JB-JJ, AB( KV+1, JJ ), LDAB-1, + $ AB( KV+JP, JJ ), LDAB-1 ) + END IF + END IF +* +* Compute multipliers +* + CALL DSCAL( KM, ONE / AB( KV+1, JJ ), AB( KV+2, JJ ), + $ 1 ) +* +* Update trailing submatrix within the band and within +* the current block. JM is the index of the last column +* which needs to be updated. +* + JM = MIN( JU, J+JB-1 ) + IF( JM.GT.JJ ) + $ CALL DGER( KM, JM-JJ, -ONE, AB( KV+2, JJ ), 1, + $ AB( KV, JJ+1 ), LDAB-1, + $ AB( KV+1, JJ+1 ), LDAB-1 ) + ELSE +* +* If pivot is zero, set INFO to the index of the pivot +* unless a zero pivot has already been found. +* + IF( INFO.EQ.0 ) + $ INFO = JJ + END IF +* +* Copy current column of A31 into the work array WORK31 +* + NW = MIN( JJ-J+1, I3 ) + IF( NW.GT.0 ) + $ CALL DCOPY( NW, AB( KV+KL+1-JJ+J, JJ ), 1, + $ WORK31( 1, JJ-J+1 ), 1 ) + 80 CONTINUE + IF( J+JB.LE.N ) THEN +* +* Apply the row interchanges to the other blocks. +* + J2 = MIN( JU-J+1, KV ) - JB + J3 = MAX( 0, JU-J-KV+1 ) +* +* Use DLASWP to apply the row interchanges to A12, A22, and +* A32. +* + CALL DLASWP( J2, AB( KV+1-JB, J+JB ), LDAB-1, 1, JB, + $ IPIV( J ), 1 ) +* +* Adjust the pivot indices. +* + DO 90 I = J, J + JB - 1 + IPIV( I ) = IPIV( I ) + J - 1 + 90 CONTINUE +* +* Apply the row interchanges to A13, A23, and A33 +* columnwise. +* + K2 = J - 1 + JB + J2 + DO 110 I = 1, J3 + JJ = K2 + I + DO 100 II = J + I - 1, J + JB - 1 + IP = IPIV( II ) + IF( IP.NE.II ) THEN + TEMP = AB( KV+1+II-JJ, JJ ) + AB( KV+1+II-JJ, JJ ) = AB( KV+1+IP-JJ, JJ ) + AB( KV+1+IP-JJ, JJ ) = TEMP + END IF + 100 CONTINUE + 110 CONTINUE +* +* Update the relevant part of the trailing submatrix +* + IF( J2.GT.0 ) THEN +* +* Update A12 +* + CALL DTRSM( 'Left', 'Lower', 'No transpose', 'Unit', + $ JB, J2, ONE, AB( KV+1, J ), LDAB-1, + $ AB( KV+1-JB, J+JB ), LDAB-1 ) +* + IF( I2.GT.0 ) THEN +* +* Update A22 +* + CALL DGEMM( 'No transpose', 'No transpose', I2, J2, + $ JB, -ONE, AB( KV+1+JB, J ), LDAB-1, + $ AB( KV+1-JB, J+JB ), LDAB-1, ONE, + $ AB( KV+1, J+JB ), LDAB-1 ) + END IF +* + IF( I3.GT.0 ) THEN +* +* Update A32 +* + CALL DGEMM( 'No transpose', 'No transpose', I3, J2, + $ JB, -ONE, WORK31, LDWORK, + $ AB( KV+1-JB, J+JB ), LDAB-1, ONE, + $ AB( KV+KL+1-JB, J+JB ), LDAB-1 ) + END IF + END IF +* + IF( J3.GT.0 ) THEN +* +* Copy the lower triangle of A13 into the work array +* WORK13 +* + DO 130 JJ = 1, J3 + DO 120 II = JJ, JB + WORK13( II, JJ ) = AB( II-JJ+1, JJ+J+KV-1 ) + 120 CONTINUE + 130 CONTINUE +* +* Update A13 in the work array +* + CALL DTRSM( 'Left', 'Lower', 'No transpose', 'Unit', + $ JB, J3, ONE, AB( KV+1, J ), LDAB-1, + $ WORK13, LDWORK ) +* + IF( I2.GT.0 ) THEN +* +* Update A23 +* + CALL DGEMM( 'No transpose', 'No transpose', I2, J3, + $ JB, -ONE, AB( KV+1+JB, J ), LDAB-1, + $ WORK13, LDWORK, ONE, AB( 1+JB, J+KV ), + $ LDAB-1 ) + END IF +* + IF( I3.GT.0 ) THEN +* +* Update A33 +* + CALL DGEMM( 'No transpose', 'No transpose', I3, J3, + $ JB, -ONE, WORK31, LDWORK, WORK13, + $ LDWORK, ONE, AB( 1+KL, J+KV ), LDAB-1 ) + END IF +* +* Copy the lower triangle of A13 back into place +* + DO 150 JJ = 1, J3 + DO 140 II = JJ, JB + AB( II-JJ+1, JJ+J+KV-1 ) = WORK13( II, JJ ) + 140 CONTINUE + 150 CONTINUE + END IF + ELSE +* +* Adjust the pivot indices. +* + DO 160 I = J, J + JB - 1 + IPIV( I ) = IPIV( I ) + J - 1 + 160 CONTINUE + END IF +* +* Partially undo the interchanges in the current block to +* restore the upper triangular form of A31 and copy the upper +* triangle of A31 back into place +* + DO 170 JJ = J + JB - 1, J, -1 + JP = IPIV( JJ ) - JJ + 1 + IF( JP.NE.1 ) THEN +* +* Apply interchange to columns J to JJ-1 +* + IF( JP+JJ-1.LT.J+KL ) THEN +* +* The interchange does not affect A31 +* + CALL DSWAP( JJ-J, AB( KV+1+JJ-J, J ), LDAB-1, + $ AB( KV+JP+JJ-J, J ), LDAB-1 ) + ELSE +* +* The interchange does affect A31 +* + CALL DSWAP( JJ-J, AB( KV+1+JJ-J, J ), LDAB-1, + $ WORK31( JP+JJ-J-KL, 1 ), LDWORK ) + END IF + END IF +* +* Copy the current column of A31 back into place +* + NW = MIN( I3, JJ-J+1 ) + IF( NW.GT.0 ) + $ CALL DCOPY( NW, WORK31( 1, JJ-J+1 ), 1, + $ AB( KV+KL+1-JJ+J, JJ ), 1 ) + 170 CONTINUE + 180 CONTINUE + END IF +* + RETURN +* +* End of DGBTRF +* + END diff --git a/ext/lapack/dgbtrs.f b/ext/lapack/dgbtrs.f new file mode 100755 index 000000000..26fdf91eb --- /dev/null +++ b/ext/lapack/dgbtrs.f @@ -0,0 +1,187 @@ + SUBROUTINE DGBTRS( TRANS, N, KL, KU, NRHS, AB, LDAB, IPIV, B, LDB, + $ INFO ) +* +* -- LAPACK routine (version 3.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* March 31, 1993 +* +* .. Scalar Arguments .. + CHARACTER TRANS + INTEGER INFO, KL, KU, LDAB, LDB, N, NRHS +* .. +* .. Array Arguments .. + INTEGER IPIV( * ) + DOUBLE PRECISION AB( LDAB, * ), B( LDB, * ) +* .. +* +* Purpose +* ======= +* +* DGBTRS solves a system of linear equations +* A * X = B or A' * X = B +* with a general band matrix A using the LU factorization computed +* by DGBTRF. +* +* Arguments +* ========= +* +* TRANS (input) CHARACTER*1 +* Specifies the form of the system of equations. +* = 'N': A * X = B (No transpose) +* = 'T': A'* X = B (Transpose) +* = 'C': A'* X = B (Conjugate transpose = Transpose) +* +* N (input) INTEGER +* The order of the matrix A. N >= 0. +* +* KL (input) INTEGER +* The number of subdiagonals within the band of A. KL >= 0. +* +* KU (input) INTEGER +* The number of superdiagonals within the band of A. KU >= 0. +* +* NRHS (input) INTEGER +* The number of right hand sides, i.e., the number of columns +* of the matrix B. NRHS >= 0. +* +* AB (input) DOUBLE PRECISION array, dimension (LDAB,N) +* Details of the LU factorization of the band matrix A, as +* computed by DGBTRF. U is stored as an upper triangular band +* matrix with KL+KU superdiagonals in rows 1 to KL+KU+1, and +* the multipliers used during the factorization are stored in +* rows KL+KU+2 to 2*KL+KU+1. +* +* LDAB (input) INTEGER +* The leading dimension of the array AB. LDAB >= 2*KL+KU+1. +* +* IPIV (input) INTEGER array, dimension (N) +* The pivot indices; for 1 <= i <= N, row i of the matrix was +* interchanged with row IPIV(i). +* +* B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS) +* On entry, the right hand side matrix B. +* On exit, the solution matrix X. +* +* LDB (input) INTEGER +* The leading dimension of the array B. LDB >= max(1,N). +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument had an illegal value +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D+0 ) +* .. +* .. Local Scalars .. + LOGICAL LNOTI, NOTRAN + INTEGER I, J, KD, L, LM +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. External Subroutines .. + EXTERNAL DGEMV, DGER, DSWAP, DTBSV, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + NOTRAN = LSAME( TRANS, 'N' ) + IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT. + $ LSAME( TRANS, 'C' ) ) THEN + INFO = -1 + ELSE IF( N.LT.0 ) THEN + INFO = -2 + ELSE IF( KL.LT.0 ) THEN + INFO = -3 + ELSE IF( KU.LT.0 ) THEN + INFO = -4 + ELSE IF( NRHS.LT.0 ) THEN + INFO = -5 + ELSE IF( LDAB.LT.( 2*KL+KU+1 ) ) THEN + INFO = -7 + ELSE IF( LDB.LT.MAX( 1, N ) ) THEN + INFO = -10 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DGBTRS', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( N.EQ.0 .OR. NRHS.EQ.0 ) + $ RETURN +* + KD = KU + KL + 1 + LNOTI = KL.GT.0 +* + IF( NOTRAN ) THEN +* +* Solve A*X = B. +* +* Solve L*X = B, overwriting B with X. +* +* L is represented as a product of permutations and unit lower +* triangular matrices L = P(1) * L(1) * ... * P(n-1) * L(n-1), +* where each transformation L(i) is a rank-one modification of +* the identity matrix. +* + IF( LNOTI ) THEN + DO 10 J = 1, N - 1 + LM = MIN( KL, N-J ) + L = IPIV( J ) + IF( L.NE.J ) + $ CALL DSWAP( NRHS, B( L, 1 ), LDB, B( J, 1 ), LDB ) + CALL DGER( LM, NRHS, -ONE, AB( KD+1, J ), 1, B( J, 1 ), + $ LDB, B( J+1, 1 ), LDB ) + 10 CONTINUE + END IF +* + DO 20 I = 1, NRHS +* +* Solve U*X = B, overwriting B with X. +* + CALL DTBSV( 'Upper', 'No transpose', 'Non-unit', N, KL+KU, + $ AB, LDAB, B( 1, I ), 1 ) + 20 CONTINUE +* + ELSE +* +* Solve A'*X = B. +* + DO 30 I = 1, NRHS +* +* Solve U'*X = B, overwriting B with X. +* + CALL DTBSV( 'Upper', 'Transpose', 'Non-unit', N, KL+KU, AB, + $ LDAB, B( 1, I ), 1 ) + 30 CONTINUE +* +* Solve L'*X = B, overwriting B with X. +* + IF( LNOTI ) THEN + DO 40 J = N - 1, 1, -1 + LM = MIN( KL, N-J ) + CALL DGEMV( 'Transpose', LM, NRHS, -ONE, B( J+1, 1 ), + $ LDB, AB( KD+1, J ), 1, ONE, B( J, 1 ), LDB ) + L = IPIV( J ) + IF( L.NE.J ) + $ CALL DSWAP( NRHS, B( L, 1 ), LDB, B( J, 1 ), LDB ) + 40 CONTINUE + END IF + END IF + RETURN +* +* End of DGBTRS +* + END diff --git a/ext/lapack/dgebd2.f b/ext/lapack/dgebd2.f new file mode 100755 index 000000000..0bdac2d24 --- /dev/null +++ b/ext/lapack/dgebd2.f @@ -0,0 +1,238 @@ + SUBROUTINE DGEBD2( M, N, A, LDA, D, E, TAUQ, TAUP, WORK, INFO ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* February 29, 1992 +* +* .. Scalar Arguments .. + INTEGER INFO, LDA, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), D( * ), E( * ), TAUP( * ), + $ TAUQ( * ), WORK( * ) +* .. +* +* Purpose +* ======= +* +* DGEBD2 reduces a real general m by n matrix A to upper or lower +* bidiagonal form B by an orthogonal transformation: Q' * A * P = B. +* +* If m >= n, B is upper bidiagonal; if m < n, B is lower bidiagonal. +* +* Arguments +* ========= +* +* M (input) INTEGER +* The number of rows in the matrix A. M >= 0. +* +* N (input) INTEGER +* The number of columns in the matrix A. N >= 0. +* +* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) +* On entry, the m by n general matrix to be reduced. +* On exit, +* if m >= n, the diagonal and the first superdiagonal are +* overwritten with the upper bidiagonal matrix B; the +* elements below the diagonal, with the array TAUQ, represent +* the orthogonal matrix Q as a product of elementary +* reflectors, and the elements above the first superdiagonal, +* with the array TAUP, represent the orthogonal matrix P as +* a product of elementary reflectors; +* if m < n, the diagonal and the first subdiagonal are +* overwritten with the lower bidiagonal matrix B; the +* elements below the first subdiagonal, with the array TAUQ, +* represent the orthogonal matrix Q as a product of +* elementary reflectors, and the elements above the diagonal, +* with the array TAUP, represent the orthogonal matrix P as +* a product of elementary reflectors. +* See Further Details. +* +* LDA (input) INTEGER +* The leading dimension of the array A. LDA >= max(1,M). +* +* D (output) DOUBLE PRECISION array, dimension (min(M,N)) +* The diagonal elements of the bidiagonal matrix B: +* D(i) = A(i,i). +* +* E (output) DOUBLE PRECISION array, dimension (min(M,N)-1) +* The off-diagonal elements of the bidiagonal matrix B: +* if m >= n, E(i) = A(i,i+1) for i = 1,2,...,n-1; +* if m < n, E(i) = A(i+1,i) for i = 1,2,...,m-1. +* +* TAUQ (output) DOUBLE PRECISION array dimension (min(M,N)) +* The scalar factors of the elementary reflectors which +* represent the orthogonal matrix Q. See Further Details. +* +* TAUP (output) DOUBLE PRECISION array, dimension (min(M,N)) +* The scalar factors of the elementary reflectors which +* represent the orthogonal matrix P. See Further Details. +* +* WORK (workspace) DOUBLE PRECISION array, dimension (max(M,N)) +* +* INFO (output) INTEGER +* = 0: successful exit. +* < 0: if INFO = -i, the i-th argument had an illegal value. +* +* Further Details +* =============== +* +* The matrices Q and P are represented as products of elementary +* reflectors: +* +* If m >= n, +* +* Q = H(1) H(2) . . . H(n) and P = G(1) G(2) . . . G(n-1) +* +* Each H(i) and G(i) has the form: +* +* H(i) = I - tauq * v * v' and G(i) = I - taup * u * u' +* +* where tauq and taup are real scalars, and v and u are real vectors; +* v(1:i-1) = 0, v(i) = 1, and v(i+1:m) is stored on exit in A(i+1:m,i); +* u(1:i) = 0, u(i+1) = 1, and u(i+2:n) is stored on exit in A(i,i+2:n); +* tauq is stored in TAUQ(i) and taup in TAUP(i). +* +* If m < n, +* +* Q = H(1) H(2) . . . H(m-1) and P = G(1) G(2) . . . G(m) +* +* Each H(i) and G(i) has the form: +* +* H(i) = I - tauq * v * v' and G(i) = I - taup * u * u' +* +* where tauq and taup are real scalars, and v and u are real vectors; +* v(1:i) = 0, v(i+1) = 1, and v(i+2:m) is stored on exit in A(i+2:m,i); +* u(1:i-1) = 0, u(i) = 1, and u(i+1:n) is stored on exit in A(i,i+1:n); +* tauq is stored in TAUQ(i) and taup in TAUP(i). +* +* The contents of A on exit are illustrated by the following examples: +* +* m = 6 and n = 5 (m > n): m = 5 and n = 6 (m < n): +* +* ( d e u1 u1 u1 ) ( d u1 u1 u1 u1 u1 ) +* ( v1 d e u2 u2 ) ( e d u2 u2 u2 u2 ) +* ( v1 v2 d e u3 ) ( v1 e d u3 u3 u3 ) +* ( v1 v2 v3 d e ) ( v1 v2 e d u4 u4 ) +* ( v1 v2 v3 v4 d ) ( v1 v2 v3 e d u5 ) +* ( v1 v2 v3 v4 v5 ) +* +* where d and e denote diagonal and off-diagonal elements of B, vi +* denotes an element of the vector defining H(i), and ui an element of +* the vector defining G(i). +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO, ONE + PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER I +* .. +* .. External Subroutines .. + EXTERNAL DLARF, DLARFG, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. Executable Statements .. +* +* Test the input parameters +* + INFO = 0 + IF( M.LT.0 ) THEN + INFO = -1 + ELSE IF( N.LT.0 ) THEN + INFO = -2 + ELSE IF( LDA.LT.MAX( 1, M ) ) THEN + INFO = -4 + END IF + IF( INFO.LT.0 ) THEN + CALL XERBLA( 'DGEBD2', -INFO ) + RETURN + END IF +* + IF( M.GE.N ) THEN +* +* Reduce to upper bidiagonal form +* + DO 10 I = 1, N +* +* Generate elementary reflector H(i) to annihilate A(i+1:m,i) +* + CALL DLARFG( M-I+1, A( I, I ), A( MIN( I+1, M ), I ), 1, + $ TAUQ( I ) ) + D( I ) = A( I, I ) + A( I, I ) = ONE +* +* Apply H(i) to A(i:m,i+1:n) from the left +* + CALL DLARF( 'Left', M-I+1, N-I, A( I, I ), 1, TAUQ( I ), + $ A( I, I+1 ), LDA, WORK ) + A( I, I ) = D( I ) +* + IF( I.LT.N ) THEN +* +* Generate elementary reflector G(i) to annihilate +* A(i,i+2:n) +* + CALL DLARFG( N-I, A( I, I+1 ), A( I, MIN( I+2, N ) ), + $ LDA, TAUP( I ) ) + E( I ) = A( I, I+1 ) + A( I, I+1 ) = ONE +* +* Apply G(i) to A(i+1:m,i+1:n) from the right +* + CALL DLARF( 'Right', M-I, N-I, A( I, I+1 ), LDA, + $ TAUP( I ), A( I+1, I+1 ), LDA, WORK ) + A( I, I+1 ) = E( I ) + ELSE + TAUP( I ) = ZERO + END IF + 10 CONTINUE + ELSE +* +* Reduce to lower bidiagonal form +* + DO 20 I = 1, M +* +* Generate elementary reflector G(i) to annihilate A(i,i+1:n) +* + CALL DLARFG( N-I+1, A( I, I ), A( I, MIN( I+1, N ) ), LDA, + $ TAUP( I ) ) + D( I ) = A( I, I ) + A( I, I ) = ONE +* +* Apply G(i) to A(i+1:m,i:n) from the right +* + CALL DLARF( 'Right', M-I, N-I+1, A( I, I ), LDA, TAUP( I ), + $ A( MIN( I+1, M ), I ), LDA, WORK ) + A( I, I ) = D( I ) +* + IF( I.LT.M ) THEN +* +* Generate elementary reflector H(i) to annihilate +* A(i+2:m,i) +* + CALL DLARFG( M-I, A( I+1, I ), A( MIN( I+2, M ), I ), 1, + $ TAUQ( I ) ) + E( I ) = A( I+1, I ) + A( I+1, I ) = ONE +* +* Apply H(i) to A(i+1:m,i+1:n) from the left +* + CALL DLARF( 'Left', M-I, N-I, A( I+1, I ), 1, TAUQ( I ), + $ A( I+1, I+1 ), LDA, WORK ) + A( I+1, I ) = E( I ) + ELSE + TAUQ( I ) = ZERO + END IF + 20 CONTINUE + END IF + RETURN +* +* End of DGEBD2 +* + END diff --git a/ext/lapack/dgebrd.f b/ext/lapack/dgebrd.f new file mode 100755 index 000000000..5ccaed3f5 --- /dev/null +++ b/ext/lapack/dgebrd.f @@ -0,0 +1,258 @@ + SUBROUTINE DGEBRD( M, N, A, LDA, D, E, TAUQ, TAUP, WORK, LWORK, + $ INFO ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + INTEGER INFO, LDA, LWORK, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), D( * ), E( * ), TAUP( * ), + $ TAUQ( * ), WORK( LWORK ) +* .. +* +* Purpose +* ======= +* +* DGEBRD reduces a general real M-by-N matrix A to upper or lower +* bidiagonal form B by an orthogonal transformation: Q**T * A * P = B. +* +* If m >= n, B is upper bidiagonal; if m < n, B is lower bidiagonal. +* +* Arguments +* ========= +* +* M (input) INTEGER +* The number of rows in the matrix A. M >= 0. +* +* N (input) INTEGER +* The number of columns in the matrix A. N >= 0. +* +* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) +* On entry, the M-by-N general matrix to be reduced. +* On exit, +* if m >= n, the diagonal and the first superdiagonal are +* overwritten with the upper bidiagonal matrix B; the +* elements below the diagonal, with the array TAUQ, represent +* the orthogonal matrix Q as a product of elementary +* reflectors, and the elements above the first superdiagonal, +* with the array TAUP, represent the orthogonal matrix P as +* a product of elementary reflectors; +* if m < n, the diagonal and the first subdiagonal are +* overwritten with the lower bidiagonal matrix B; the +* elements below the first subdiagonal, with the array TAUQ, +* represent the orthogonal matrix Q as a product of +* elementary reflectors, and the elements above the diagonal, +* with the array TAUP, represent the orthogonal matrix P as +* a product of elementary reflectors. +* See Further Details. +* +* LDA (input) INTEGER +* The leading dimension of the array A. LDA >= max(1,M). +* +* D (output) DOUBLE PRECISION array, dimension (min(M,N)) +* The diagonal elements of the bidiagonal matrix B: +* D(i) = A(i,i). +* +* E (output) DOUBLE PRECISION array, dimension (min(M,N)-1) +* The off-diagonal elements of the bidiagonal matrix B: +* if m >= n, E(i) = A(i,i+1) for i = 1,2,...,n-1; +* if m < n, E(i) = A(i+1,i) for i = 1,2,...,m-1. +* +* TAUQ (output) DOUBLE PRECISION array dimension (min(M,N)) +* The scalar factors of the elementary reflectors which +* represent the orthogonal matrix Q. See Further Details. +* +* TAUP (output) DOUBLE PRECISION array, dimension (min(M,N)) +* The scalar factors of the elementary reflectors which +* represent the orthogonal matrix P. See Further Details. +* +* WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK) +* On exit, if INFO = 0, WORK(1) returns the optimal LWORK. +* +* LWORK (input) INTEGER +* The length of the array WORK. LWORK >= max(1,M,N). +* For optimum performance LWORK >= (M+N)*NB, where NB +* is the optimal blocksize. +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument had an illegal value. +* +* Further Details +* =============== +* +* The matrices Q and P are represented as products of elementary +* reflectors: +* +* If m >= n, +* +* Q = H(1) H(2) . . . H(n) and P = G(1) G(2) . . . G(n-1) +* +* Each H(i) and G(i) has the form: +* +* H(i) = I - tauq * v * v' and G(i) = I - taup * u * u' +* +* where tauq and taup are real scalars, and v and u are real vectors; +* v(1:i-1) = 0, v(i) = 1, and v(i+1:m) is stored on exit in A(i+1:m,i); +* u(1:i) = 0, u(i+1) = 1, and u(i+2:n) is stored on exit in A(i,i+2:n); +* tauq is stored in TAUQ(i) and taup in TAUP(i). +* +* If m < n, +* +* Q = H(1) H(2) . . . H(m-1) and P = G(1) G(2) . . . G(m) +* +* Each H(i) and G(i) has the form: +* +* H(i) = I - tauq * v * v' and G(i) = I - taup * u * u' +* +* where tauq and taup are real scalars, and v and u are real vectors; +* v(1:i) = 0, v(i+1) = 1, and v(i+2:m) is stored on exit in A(i+2:m,i); +* u(1:i-1) = 0, u(i) = 1, and u(i+1:n) is stored on exit in A(i,i+1:n); +* tauq is stored in TAUQ(i) and taup in TAUP(i). +* +* The contents of A on exit are illustrated by the following examples: +* +* m = 6 and n = 5 (m > n): m = 5 and n = 6 (m < n): +* +* ( d e u1 u1 u1 ) ( d u1 u1 u1 u1 u1 ) +* ( v1 d e u2 u2 ) ( e d u2 u2 u2 u2 ) +* ( v1 v2 d e u3 ) ( v1 e d u3 u3 u3 ) +* ( v1 v2 v3 d e ) ( v1 v2 e d u4 u4 ) +* ( v1 v2 v3 v4 d ) ( v1 v2 v3 e d u5 ) +* ( v1 v2 v3 v4 v5 ) +* +* where d and e denote diagonal and off-diagonal elements of B, vi +* denotes an element of the vector defining H(i), and ui an element of +* the vector defining G(i). +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER I, IINFO, J, LDWRKX, LDWRKY, MINMN, NB, NBMIN, + $ NX + DOUBLE PRECISION WS +* .. +* .. External Subroutines .. + EXTERNAL DGEBD2, DGEMM, DLABRD, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. External Functions .. + INTEGER ILAENV + EXTERNAL ILAENV +* .. +* .. Executable Statements .. +* +* Test the input parameters +* + INFO = 0 + IF( M.LT.0 ) THEN + INFO = -1 + ELSE IF( N.LT.0 ) THEN + INFO = -2 + ELSE IF( LDA.LT.MAX( 1, M ) ) THEN + INFO = -4 + ELSE IF( LWORK.LT.MAX( 1, M, N ) ) THEN + INFO = -10 + END IF + IF( INFO.LT.0 ) THEN + CALL XERBLA( 'DGEBRD', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + MINMN = MIN( M, N ) + IF( MINMN.EQ.0 ) THEN + WORK( 1 ) = 1 + RETURN + END IF +* + WS = MAX( M, N ) + LDWRKX = M + LDWRKY = N +* +* Set the block size NB and the crossover point NX. +* + NB = MAX( 1, ILAENV( 1, 'DGEBRD', ' ', M, N, -1, -1 ) ) +* + IF( NB.GT.1 .AND. NB.LT.MINMN ) THEN +* +* Determine when to switch from blocked to unblocked code. +* + NX = MAX( NB, ILAENV( 3, 'DGEBRD', ' ', M, N, -1, -1 ) ) + IF( NX.LT.MINMN ) THEN + WS = ( M+N )*NB + IF( LWORK.LT.WS ) THEN +* +* Not enough work space for the optimal NB, consider using +* a smaller block size. +* + NBMIN = ILAENV( 2, 'DGEBRD', ' ', M, N, -1, -1 ) + IF( LWORK.GE.( M+N )*NBMIN ) THEN + NB = LWORK / ( M+N ) + ELSE + NB = 1 + NX = MINMN + END IF + END IF + END IF + ELSE + NX = MINMN + END IF +* + DO 30 I = 1, MINMN - NX, NB +* +* Reduce rows and columns i:i+nb-1 to bidiagonal form and return +* the matrices X and Y which are needed to update the unreduced +* part of the matrix +* + CALL DLABRD( M-I+1, N-I+1, NB, A( I, I ), LDA, D( I ), E( I ), + $ TAUQ( I ), TAUP( I ), WORK, LDWRKX, + $ WORK( LDWRKX*NB+1 ), LDWRKY ) +* +* Update the trailing submatrix A(i+nb:m,i+nb:n), using an update +* of the form A := A - V*Y' - X*U' +* + CALL DGEMM( 'No transpose', 'Transpose', M-I-NB+1, N-I-NB+1, + $ NB, -ONE, A( I+NB, I ), LDA, + $ WORK( LDWRKX*NB+NB+1 ), LDWRKY, ONE, + $ A( I+NB, I+NB ), LDA ) + CALL DGEMM( 'No transpose', 'No transpose', M-I-NB+1, N-I-NB+1, + $ NB, -ONE, WORK( NB+1 ), LDWRKX, A( I, I+NB ), LDA, + $ ONE, A( I+NB, I+NB ), LDA ) +* +* Copy diagonal and off-diagonal elements of B back into A +* + IF( M.GE.N ) THEN + DO 10 J = I, I + NB - 1 + A( J, J ) = D( J ) + A( J, J+1 ) = E( J ) + 10 CONTINUE + ELSE + DO 20 J = I, I + NB - 1 + A( J, J ) = D( J ) + A( J+1, J ) = E( J ) + 20 CONTINUE + END IF + 30 CONTINUE +* +* Use unblocked code to reduce the remainder of the matrix +* + CALL DGEBD2( M-I+1, N-I+1, A( I, I ), LDA, D( I ), E( I ), + $ TAUQ( I ), TAUP( I ), WORK, IINFO ) + WORK( 1 ) = WS + RETURN +* +* End of DGEBRD +* + END diff --git a/ext/lapack/dgelq2.f b/ext/lapack/dgelq2.f new file mode 100755 index 000000000..699a70cfe --- /dev/null +++ b/ext/lapack/dgelq2.f @@ -0,0 +1,122 @@ + SUBROUTINE DGELQ2( M, N, A, LDA, TAU, WORK, INFO ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* February 29, 1992 +* +* .. Scalar Arguments .. + INTEGER INFO, LDA, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * ) +* .. +* +* Purpose +* ======= +* +* DGELQ2 computes an LQ factorization of a real m by n matrix A: +* A = L * Q. +* +* Arguments +* ========= +* +* M (input) INTEGER +* The number of rows of the matrix A. M >= 0. +* +* N (input) INTEGER +* The number of columns of the matrix A. N >= 0. +* +* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) +* On entry, the m by n matrix A. +* On exit, the elements on and below the diagonal of the array +* contain the m by min(m,n) lower trapezoidal matrix L (L is +* lower triangular if m <= n); the elements above the diagonal, +* with the array TAU, represent the orthogonal matrix Q as a +* product of elementary reflectors (see Further Details). +* +* LDA (input) INTEGER +* The leading dimension of the array A. LDA >= max(1,M). +* +* TAU (output) DOUBLE PRECISION array, dimension (min(M,N)) +* The scalar factors of the elementary reflectors (see Further +* Details). +* +* WORK (workspace) DOUBLE PRECISION array, dimension (M) +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument had an illegal value +* +* Further Details +* =============== +* +* The matrix Q is represented as a product of elementary reflectors +* +* Q = H(k) . . . H(2) H(1), where k = min(m,n). +* +* Each H(i) has the form +* +* H(i) = I - tau * v * v' +* +* where tau is a real scalar, and v is a real vector with +* v(1:i-1) = 0 and v(i) = 1; v(i+1:n) is stored on exit in A(i,i+1:n), +* and tau in TAU(i). +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER I, K + DOUBLE PRECISION AII +* .. +* .. External Subroutines .. + EXTERNAL DLARF, DLARFG, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 + IF( M.LT.0 ) THEN + INFO = -1 + ELSE IF( N.LT.0 ) THEN + INFO = -2 + ELSE IF( LDA.LT.MAX( 1, M ) ) THEN + INFO = -4 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DGELQ2', -INFO ) + RETURN + END IF +* + K = MIN( M, N ) +* + DO 10 I = 1, K +* +* Generate elementary reflector H(i) to annihilate A(i,i+1:n) +* + CALL DLARFG( N-I+1, A( I, I ), A( I, MIN( I+1, N ) ), LDA, + $ TAU( I ) ) + IF( I.LT.M ) THEN +* +* Apply H(i) to A(i+1:m,i:n) from the right +* + AII = A( I, I ) + A( I, I ) = ONE + CALL DLARF( 'Right', M-I, N-I+1, A( I, I ), LDA, TAU( I ), + $ A( I+1, I ), LDA, WORK ) + A( I, I ) = AII + END IF + 10 CONTINUE + RETURN +* +* End of DGELQ2 +* + END diff --git a/ext/lapack/dgelqf.f b/ext/lapack/dgelqf.f new file mode 100755 index 000000000..0910606a8 --- /dev/null +++ b/ext/lapack/dgelqf.f @@ -0,0 +1,186 @@ + SUBROUTINE DGELQF( M, N, A, LDA, TAU, WORK, LWORK, INFO ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + INTEGER INFO, LDA, LWORK, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( LWORK ) +* .. +* +* Purpose +* ======= +* +* DGELQF computes an LQ factorization of a real M-by-N matrix A: +* A = L * Q. +* +* Arguments +* ========= +* +* M (input) INTEGER +* The number of rows of the matrix A. M >= 0. +* +* N (input) INTEGER +* The number of columns of the matrix A. N >= 0. +* +* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) +* On entry, the M-by-N matrix A. +* On exit, the elements on and below the diagonal of the array +* contain the m-by-min(m,n) lower trapezoidal matrix L (L is +* lower triangular if m <= n); the elements above the diagonal, +* with the array TAU, represent the orthogonal matrix Q as a +* product of elementary reflectors (see Further Details). +* +* LDA (input) INTEGER +* The leading dimension of the array A. LDA >= max(1,M). +* +* TAU (output) DOUBLE PRECISION array, dimension (min(M,N)) +* The scalar factors of the elementary reflectors (see Further +* Details). +* +* WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK) +* On exit, if INFO = 0, WORK(1) returns the optimal LWORK. +* +* LWORK (input) INTEGER +* The dimension of the array WORK. LWORK >= max(1,M). +* For optimum performance LWORK >= M*NB, where NB is the +* optimal blocksize. +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument had an illegal value +* +* Further Details +* =============== +* +* The matrix Q is represented as a product of elementary reflectors +* +* Q = H(k) . . . H(2) H(1), where k = min(m,n). +* +* Each H(i) has the form +* +* H(i) = I - tau * v * v' +* +* where tau is a real scalar, and v is a real vector with +* v(1:i-1) = 0 and v(i) = 1; v(i+1:n) is stored on exit in A(i,i+1:n), +* and tau in TAU(i). +* +* ===================================================================== +* +* .. Local Scalars .. + INTEGER I, IB, IINFO, IWS, K, LDWORK, NB, NBMIN, NX +* .. +* .. External Subroutines .. + EXTERNAL DGELQ2, DLARFB, DLARFT, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. External Functions .. + INTEGER ILAENV + EXTERNAL ILAENV +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 + IF( M.LT.0 ) THEN + INFO = -1 + ELSE IF( N.LT.0 ) THEN + INFO = -2 + ELSE IF( LDA.LT.MAX( 1, M ) ) THEN + INFO = -4 + ELSE IF( LWORK.LT.MAX( 1, M ) ) THEN + INFO = -7 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DGELQF', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + K = MIN( M, N ) + IF( K.EQ.0 ) THEN + WORK( 1 ) = 1 + RETURN + END IF +* +* Determine the block size. +* + NB = ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 ) + NBMIN = 2 + NX = 0 + IWS = M + IF( NB.GT.1 .AND. NB.LT.K ) THEN +* +* Determine when to cross over from blocked to unblocked code. +* + NX = MAX( 0, ILAENV( 3, 'DGELQF', ' ', M, N, -1, -1 ) ) + IF( NX.LT.K ) THEN +* +* Determine if workspace is large enough for blocked code. +* + LDWORK = M + IWS = LDWORK*NB + IF( LWORK.LT.IWS ) THEN +* +* Not enough workspace to use optimal NB: reduce NB and +* determine the minimum value of NB. +* + NB = LWORK / LDWORK + NBMIN = MAX( 2, ILAENV( 2, 'DGELQF', ' ', M, N, -1, + $ -1 ) ) + END IF + END IF + END IF +* + IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN +* +* Use blocked code initially +* + DO 10 I = 1, K - NX, NB + IB = MIN( K-I+1, NB ) +* +* Compute the LQ factorization of the current block +* A(i:i+ib-1,i:n) +* + CALL DGELQ2( IB, N-I+1, A( I, I ), LDA, TAU( I ), WORK, + $ IINFO ) + IF( I+IB.LE.M ) THEN +* +* Form the triangular factor of the block reflector +* H = H(i) H(i+1) . . . H(i+ib-1) +* + CALL DLARFT( 'Forward', 'Rowwise', N-I+1, IB, A( I, I ), + $ LDA, TAU( I ), WORK, LDWORK ) +* +* Apply H to A(i+ib:m,i:n) from the right +* + CALL DLARFB( 'Right', 'No transpose', 'Forward', + $ 'Rowwise', M-I-IB+1, N-I+1, IB, A( I, I ), + $ LDA, WORK, LDWORK, A( I+IB, I ), LDA, + $ WORK( IB+1 ), LDWORK ) + END IF + 10 CONTINUE + ELSE + I = 1 + END IF +* +* Use unblocked code to factor the last or only block. +* + IF( I.LE.K ) + $ CALL DGELQ2( M-I+1, N-I+1, A( I, I ), LDA, TAU( I ), WORK, + $ IINFO ) +* + WORK( 1 ) = IWS + RETURN +* +* End of DGELQF +* + END diff --git a/ext/lapack/dgelss.f b/ext/lapack/dgelss.f new file mode 100755 index 000000000..36c3bb489 --- /dev/null +++ b/ext/lapack/dgelss.f @@ -0,0 +1,604 @@ + SUBROUTINE DGELSS( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK, + $ WORK, LWORK, INFO ) +* +* -- LAPACK driver routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK + DOUBLE PRECISION RCOND +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), B( LDB, * ), S( * ), WORK( * ) +* .. +* +* Purpose +* ======= +* +* DGELSS computes the minimum norm solution to a real linear least +* squares problem: +* +* Minimize 2-norm(| b - A*x |). +* +* using the singular value decomposition (SVD) of A. A is an M-by-N +* matrix which may be rank-deficient. +* +* Several right hand side vectors b and solution vectors x can be +* handled in a single call; they are stored as the columns of the +* M-by-NRHS right hand side matrix B and the N-by-NRHS solution matrix +* X. +* +* The effective rank of A is determined by treating as zero those +* singular values which are less than RCOND times the largest singular +* value. +* +* Arguments +* ========= +* +* M (input) INTEGER +* The number of rows of the matrix A. M >= 0. +* +* N (input) INTEGER +* The number of columns of the matrix A. N >= 0. +* +* NRHS (input) INTEGER +* The number of right hand sides, i.e., the number of columns +* of the matrices B and X. NRHS >= 0. +* +* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) +* On entry, the M-by-N matrix A. +* On exit, the first min(m,n) rows of A are overwritten with +* its right singular vectors, stored rowwise. +* +* LDA (input) INTEGER +* The leading dimension of the array A. LDA >= max(1,M). +* +* B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS) +* On entry, the M-by-NRHS right hand side matrix B. +* On exit, B is overwritten by the N-by-NRHS solution +* matrix X. If m >= n and RANK = n, the residual +* sum-of-squares for the solution in the i-th column is given +* by the sum of squares of elements n+1:m in that column. +* +* LDB (input) INTEGER +* The leading dimension of the array B. LDB >= max(1,max(M,N)). +* +* S (output) DOUBLE PRECISION array, dimension (min(M,N)) +* The singular values of A in decreasing order. +* The condition number of A in the 2-norm = S(1)/S(min(m,n)). +* +* RCOND (input) DOUBLE PRECISION +* RCOND is used to determine the effective rank of A. +* Singular values S(i) <= RCOND*S(1) are treated as zero. +* If RCOND < 0, machine precision is used instead. +* +* RANK (output) INTEGER +* The effective rank of A, i.e., the number of singular values +* which are greater than RCOND*S(1). +* +* WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK) +* On exit, if INFO = 0, WORK(1) returns the optimal LWORK. +* +* LWORK (input) INTEGER +* The dimension of the array WORK. LWORK >= 1, and also: +* LWORK >= 3*min(M,N) + max( 2*min(M,N), max(M,N), NRHS ) +* For good performance, LWORK should generally be larger. +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument had an illegal value. +* > 0: the algorithm for computing the SVD failed to converge; +* if INFO = i, i off-diagonal elements of an intermediate +* bidiagonal form did not converge to zero. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO, ONE + PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 ) +* .. +* .. Local Scalars .. + INTEGER BDSPAC, BL, CHUNK, I, IASCL, IBSCL, IE, IL, + $ ITAU, ITAUP, ITAUQ, IWORK, LDWORK, MAXMN, + $ MAXWRK, MINMN, MINWRK, MM, MNTHR + DOUBLE PRECISION ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM, THR +* .. +* .. Local Arrays .. + DOUBLE PRECISION VDUM( 1 ) +* .. +* .. External Subroutines .. + EXTERNAL DBDSQR, DCOPY, DGEBRD, DGELQF, DGEMM, DGEMV, + $ DGEQRF, DLABAD, DLACPY, DLASCL, DLASET, DORGBR, + $ DORMBR, DORMLQ, DORMQR, DRSCL, XERBLA +* .. +* .. External Functions .. + INTEGER ILAENV + DOUBLE PRECISION DLAMCH, DLANGE + EXTERNAL ILAENV, DLAMCH, DLANGE +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 + MINMN = MIN( M, N ) + MAXMN = MAX( M, N ) + MNTHR = ILAENV( 6, 'DGELSS', ' ', M, N, NRHS, -1 ) + IF( M.LT.0 ) THEN + INFO = -1 + ELSE IF( N.LT.0 ) THEN + INFO = -2 + ELSE IF( NRHS.LT.0 ) THEN + INFO = -3 + ELSE IF( LDA.LT.MAX( 1, M ) ) THEN + INFO = -5 + ELSE IF( LDB.LT.MAX( 1, MAXMN ) ) THEN + INFO = -7 + END IF +* +* Compute workspace +* (Note: Comments in the code beginning "Workspace:" describe the +* minimal amount of workspace needed at that point in the code, +* as well as the preferred amount for good performance. +* NB refers to the optimal block size for the immediately +* following subroutine, as returned by ILAENV.) +* + MINWRK = 1 + IF( INFO.EQ.0 .AND. LWORK.GE.1 ) THEN + MAXWRK = 0 + MM = M + IF( M.GE.N .AND. M.GE.MNTHR ) THEN +* +* Path 1a - overdetermined, with many more rows than columns +* + MM = N + MAXWRK = MAX( MAXWRK, N+N*ILAENV( 1, 'DGEQRF', ' ', M, N, + $ -1, -1 ) ) + MAXWRK = MAX( MAXWRK, N+NRHS* + $ ILAENV( 1, 'DORMQR', 'LT', M, NRHS, N, -1 ) ) + END IF + IF( M.GE.N ) THEN +* +* Path 1 - overdetermined or exactly determined +* +* Compute workspace neede for DBDSQR +* + BDSPAC = MAX( 1, 5*N-4 ) + MAXWRK = MAX( MAXWRK, 3*N+( MM+N )* + $ ILAENV( 1, 'DGEBRD', ' ', MM, N, -1, -1 ) ) + MAXWRK = MAX( MAXWRK, 3*N+NRHS* + $ ILAENV( 1, 'DORMBR', 'QLT', MM, NRHS, N, -1 ) ) + MAXWRK = MAX( MAXWRK, 3*N+( N-1 )* + $ ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) ) + MAXWRK = MAX( MAXWRK, BDSPAC ) + MAXWRK = MAX( MAXWRK, N*NRHS ) + MINWRK = MAX( 3*N+MM, 3*N+NRHS, BDSPAC ) + MAXWRK = MAX( MINWRK, MAXWRK ) + + END IF + IF( N.GT.M ) THEN +* +* Compute workspace neede for DBDSQR +* + BDSPAC = MAX( 1, 5*M-4 ) + MINWRK = MAX( 3*M+NRHS, 3*M+N, BDSPAC ) + IF( N.GE.MNTHR ) THEN +* +* Path 2a - underdetermined, with many more columns +* than rows +* + MAXWRK = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 ) + MAXWRK = MAX( MAXWRK, M*M+4*M+2*M* + $ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) ) + MAXWRK = MAX( MAXWRK, M*M+4*M+NRHS* + $ ILAENV( 1, 'DORMBR', 'QLT', M, NRHS, M, -1 ) ) + MAXWRK = MAX( MAXWRK, M*M+4*M+( M-1 )* + $ ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) ) + MAXWRK = MAX( MAXWRK, M*M+M+BDSPAC ) + IF( NRHS.GT.1 ) THEN + MAXWRK = MAX( MAXWRK, M*M+M+M*NRHS ) + ELSE + MAXWRK = MAX( MAXWRK, M*M+2*M ) + END IF + MAXWRK = MAX( MAXWRK, M+NRHS* + $ ILAENV( 1, 'DORMLQ', 'LT', N, NRHS, M, -1 ) ) + ELSE +* +* Path 2 - underdetermined +* + MAXWRK = 3*M + ( N+M )*ILAENV( 1, 'DGEBRD', ' ', M, N, + $ -1, -1 ) + MAXWRK = MAX( MAXWRK, 3*M+NRHS* + $ ILAENV( 1, 'DORMBR', 'QLT', M, NRHS, M, -1 ) ) + MAXWRK = MAX( MAXWRK, 3*M+M* + $ ILAENV( 1, 'DORGBR', 'P', M, N, M, -1 ) ) + MAXWRK = MAX( MAXWRK, BDSPAC ) + MAXWRK = MAX( MAXWRK, N*NRHS ) + END IF + END IF + MAXWRK = MAX( MINWRK, MAXWRK ) + WORK( 1 ) = MAXWRK + END IF +* + MINWRK = MAX( MINWRK, 1 ) + IF( LWORK.LT.MINWRK ) + $ INFO = -12 + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DGELSS', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( M.EQ.0 .OR. N.EQ.0 ) THEN + RANK = 0 + RETURN + END IF +* +* Get machine parameters +* + EPS = DLAMCH( 'P' ) + SFMIN = DLAMCH( 'S' ) + SMLNUM = SFMIN / EPS + BIGNUM = ONE / SMLNUM + CALL DLABAD( SMLNUM, BIGNUM ) +* +* Scale A if max element outside range [SMLNUM,BIGNUM] +* + ANRM = DLANGE( 'M', M, N, A, LDA, WORK ) + IASCL = 0 + IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN +* +* Scale matrix norm up to SMLNUM +* + CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO ) + IASCL = 1 + ELSE IF( ANRM.GT.BIGNUM ) THEN +* +* Scale matrix norm down to BIGNUM +* + CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO ) + IASCL = 2 + ELSE IF( ANRM.EQ.ZERO ) THEN +* +* Matrix all zero. Return zero solution. +* + CALL DLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB ) + CALL DLASET( 'F', MINMN, 1, ZERO, ZERO, S, 1 ) + RANK = 0 + GO TO 70 + END IF +* +* Scale B if max element outside range [SMLNUM,BIGNUM] +* + BNRM = DLANGE( 'M', M, NRHS, B, LDB, WORK ) + IBSCL = 0 + IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN +* +* Scale matrix norm up to SMLNUM +* + CALL DLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO ) + IBSCL = 1 + ELSE IF( BNRM.GT.BIGNUM ) THEN +* +* Scale matrix norm down to BIGNUM +* + CALL DLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO ) + IBSCL = 2 + END IF +* +* Overdetermined case +* + IF( M.GE.N ) THEN +* +* Path 1 - overdetermined or exactly determined +* + MM = M + IF( M.GE.MNTHR ) THEN +* +* Path 1a - overdetermined, with many more rows than columns +* + MM = N + ITAU = 1 + IWORK = ITAU + N +* +* Compute A=Q*R +* (Workspace: need 2*N, prefer N+N*NB) +* + CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ), + $ LWORK-IWORK+1, INFO ) +* +* Multiply B by transpose(Q) +* (Workspace: need N+NRHS, prefer N+NRHS*NB) +* + CALL DORMQR( 'L', 'T', M, NRHS, N, A, LDA, WORK( ITAU ), B, + $ LDB, WORK( IWORK ), LWORK-IWORK+1, INFO ) +* +* Zero out below R +* + IF( N.GT.1 ) + $ CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA ) + END IF +* + IE = 1 + ITAUQ = IE + N + ITAUP = ITAUQ + N + IWORK = ITAUP + N +* +* Bidiagonalize R in A +* (Workspace: need 3*N+MM, prefer 3*N+(MM+N)*NB) +* + CALL DGEBRD( MM, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ), + $ WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1, + $ INFO ) +* +* Multiply B by transpose of left bidiagonalizing vectors of R +* (Workspace: need 3*N+NRHS, prefer 3*N+NRHS*NB) +* + CALL DORMBR( 'Q', 'L', 'T', MM, NRHS, N, A, LDA, WORK( ITAUQ ), + $ B, LDB, WORK( IWORK ), LWORK-IWORK+1, INFO ) +* +* Generate right bidiagonalizing vectors of R in A +* (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB) +* + CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ), + $ WORK( IWORK ), LWORK-IWORK+1, INFO ) + IWORK = IE + N +* +* Perform bidiagonal QR iteration +* multiply B by transpose of left singular vectors +* compute right singular vectors in A +* (Workspace: need BDSPAC) +* + CALL DBDSQR( 'U', N, N, 0, NRHS, S, WORK( IE ), A, LDA, VDUM, + $ 1, B, LDB, WORK( IWORK ), INFO ) + IF( INFO.NE.0 ) + $ GO TO 70 +* +* Multiply B by reciprocals of singular values +* + THR = MAX( RCOND*S( 1 ), SFMIN ) + IF( RCOND.LT.ZERO ) + $ THR = MAX( EPS*S( 1 ), SFMIN ) + RANK = 0 + DO 10 I = 1, N + IF( S( I ).GT.THR ) THEN + CALL DRSCL( NRHS, S( I ), B( I, 1 ), LDB ) + RANK = RANK + 1 + ELSE + CALL DLASET( 'F', 1, NRHS, ZERO, ZERO, B( I, 1 ), LDB ) + END IF + 10 CONTINUE +* +* Multiply B by right singular vectors +* (Workspace: need N, prefer N*NRHS) +* + IF( LWORK.GE.LDB*NRHS .AND. NRHS.GT.1 ) THEN + CALL DGEMM( 'T', 'N', N, NRHS, N, ONE, A, LDA, B, LDB, ZERO, + $ WORK, LDB ) + CALL DLACPY( 'G', N, NRHS, WORK, LDB, B, LDB ) + ELSE IF( NRHS.GT.1 ) THEN + CHUNK = LWORK / N + DO 20 I = 1, NRHS, CHUNK + BL = MIN( NRHS-I+1, CHUNK ) + CALL DGEMM( 'T', 'N', N, BL, N, ONE, A, LDA, B, LDB, + $ ZERO, WORK, N ) + CALL DLACPY( 'G', N, BL, WORK, N, B, LDB ) + 20 CONTINUE + ELSE + CALL DGEMV( 'T', N, N, ONE, A, LDA, B, 1, ZERO, WORK, 1 ) + CALL DCOPY( N, WORK, 1, B, 1 ) + END IF +* + ELSE IF( N.GE.MNTHR .AND. LWORK.GE.4*M+M*M+ + $ MAX( M, 2*M-4, NRHS, N-3*M ) ) THEN +* +* Path 2a - underdetermined, with many more columns than rows +* and sufficient workspace for an efficient algorithm +* + LDWORK = M + IF( LWORK.GE.MAX( 4*M+M*LDA+MAX( M, 2*M-4, NRHS, N-3*M ), + $ M*LDA+M+M*NRHS ) )LDWORK = LDA + ITAU = 1 + IWORK = M + 1 +* +* Compute A=L*Q +* (Workspace: need 2*M, prefer M+M*NB) +* + CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ), + $ LWORK-IWORK+1, INFO ) + IL = IWORK +* +* Copy L to WORK(IL), zeroing out above it +* + CALL DLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWORK ) + CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, WORK( IL+LDWORK ), + $ LDWORK ) + IE = IL + LDWORK*M + ITAUQ = IE + M + ITAUP = ITAUQ + M + IWORK = ITAUP + M +* +* Bidiagonalize L in WORK(IL) +* (Workspace: need M*M+5*M, prefer M*M+4*M+2*M*NB) +* + CALL DGEBRD( M, M, WORK( IL ), LDWORK, S, WORK( IE ), + $ WORK( ITAUQ ), WORK( ITAUP ), WORK( IWORK ), + $ LWORK-IWORK+1, INFO ) +* +* Multiply B by transpose of left bidiagonalizing vectors of L +* (Workspace: need M*M+4*M+NRHS, prefer M*M+4*M+NRHS*NB) +* + CALL DORMBR( 'Q', 'L', 'T', M, NRHS, M, WORK( IL ), LDWORK, + $ WORK( ITAUQ ), B, LDB, WORK( IWORK ), + $ LWORK-IWORK+1, INFO ) +* +* Generate right bidiagonalizing vectors of R in WORK(IL) +* (Workspace: need M*M+5*M-1, prefer M*M+4*M+(M-1)*NB) +* + CALL DORGBR( 'P', M, M, M, WORK( IL ), LDWORK, WORK( ITAUP ), + $ WORK( IWORK ), LWORK-IWORK+1, INFO ) + IWORK = IE + M +* +* Perform bidiagonal QR iteration, +* computing right singular vectors of L in WORK(IL) and +* multiplying B by transpose of left singular vectors +* (Workspace: need M*M+M+BDSPAC) +* + CALL DBDSQR( 'U', M, M, 0, NRHS, S, WORK( IE ), WORK( IL ), + $ LDWORK, A, LDA, B, LDB, WORK( IWORK ), INFO ) + IF( INFO.NE.0 ) + $ GO TO 70 +* +* Multiply B by reciprocals of singular values +* + THR = MAX( RCOND*S( 1 ), SFMIN ) + IF( RCOND.LT.ZERO ) + $ THR = MAX( EPS*S( 1 ), SFMIN ) + RANK = 0 + DO 30 I = 1, M + IF( S( I ).GT.THR ) THEN + CALL DRSCL( NRHS, S( I ), B( I, 1 ), LDB ) + RANK = RANK + 1 + ELSE + CALL DLASET( 'F', 1, NRHS, ZERO, ZERO, B( I, 1 ), LDB ) + END IF + 30 CONTINUE + IWORK = IE +* +* Multiply B by right singular vectors of L in WORK(IL) +* (Workspace: need M*M+2*M, prefer M*M+M+M*NRHS) +* + IF( LWORK.GE.LDB*NRHS+IWORK-1 .AND. NRHS.GT.1 ) THEN + CALL DGEMM( 'T', 'N', M, NRHS, M, ONE, WORK( IL ), LDWORK, + $ B, LDB, ZERO, WORK( IWORK ), LDB ) + CALL DLACPY( 'G', M, NRHS, WORK( IWORK ), LDB, B, LDB ) + ELSE IF( NRHS.GT.1 ) THEN + CHUNK = ( LWORK-IWORK+1 ) / M + DO 40 I = 1, NRHS, CHUNK + BL = MIN( NRHS-I+1, CHUNK ) + CALL DGEMM( 'T', 'N', M, BL, M, ONE, WORK( IL ), LDWORK, + $ B( 1, I ), LDB, ZERO, WORK( IWORK ), N ) + CALL DLACPY( 'G', M, BL, WORK( IWORK ), N, B, LDB ) + 40 CONTINUE + ELSE + CALL DGEMV( 'T', M, M, ONE, WORK( IL ), LDWORK, B( 1, 1 ), + $ 1, ZERO, WORK( IWORK ), 1 ) + CALL DCOPY( M, WORK( IWORK ), 1, B( 1, 1 ), 1 ) + END IF +* +* Zero out below first M rows of B +* + CALL DLASET( 'F', N-M, NRHS, ZERO, ZERO, B( M+1, 1 ), LDB ) + IWORK = ITAU + M +* +* Multiply transpose(Q) by B +* (Workspace: need M+NRHS, prefer M+NRHS*NB) +* + CALL DORMLQ( 'L', 'T', N, NRHS, M, A, LDA, WORK( ITAU ), B, + $ LDB, WORK( IWORK ), LWORK-IWORK+1, INFO ) +* + ELSE +* +* Path 2 - remaining underdetermined cases +* + IE = 1 + ITAUQ = IE + M + ITAUP = ITAUQ + M + IWORK = ITAUP + M +* +* Bidiagonalize A +* (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB) +* + CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ), + $ WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1, + $ INFO ) +* +* Multiply B by transpose of left bidiagonalizing vectors +* (Workspace: need 3*M+NRHS, prefer 3*M+NRHS*NB) +* + CALL DORMBR( 'Q', 'L', 'T', M, NRHS, N, A, LDA, WORK( ITAUQ ), + $ B, LDB, WORK( IWORK ), LWORK-IWORK+1, INFO ) +* +* Generate right bidiagonalizing vectors in A +* (Workspace: need 4*M, prefer 3*M+M*NB) +* + CALL DORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ), + $ WORK( IWORK ), LWORK-IWORK+1, INFO ) + IWORK = IE + M +* +* Perform bidiagonal QR iteration, +* computing right singular vectors of A in A and +* multiplying B by transpose of left singular vectors +* (Workspace: need BDSPAC) +* + CALL DBDSQR( 'L', M, N, 0, NRHS, S, WORK( IE ), A, LDA, VDUM, + $ 1, B, LDB, WORK( IWORK ), INFO ) + IF( INFO.NE.0 ) + $ GO TO 70 +* +* Multiply B by reciprocals of singular values +* + THR = MAX( RCOND*S( 1 ), SFMIN ) + IF( RCOND.LT.ZERO ) + $ THR = MAX( EPS*S( 1 ), SFMIN ) + RANK = 0 + DO 50 I = 1, M + IF( S( I ).GT.THR ) THEN + CALL DRSCL( NRHS, S( I ), B( I, 1 ), LDB ) + RANK = RANK + 1 + ELSE + CALL DLASET( 'F', 1, NRHS, ZERO, ZERO, B( I, 1 ), LDB ) + END IF + 50 CONTINUE +* +* Multiply B by right singular vectors of A +* (Workspace: need N, prefer N*NRHS) +* + IF( LWORK.GE.LDB*NRHS .AND. NRHS.GT.1 ) THEN + CALL DGEMM( 'T', 'N', N, NRHS, M, ONE, A, LDA, B, LDB, ZERO, + $ WORK, LDB ) + CALL DLACPY( 'F', N, NRHS, WORK, LDB, B, LDB ) + ELSE IF( NRHS.GT.1 ) THEN + CHUNK = LWORK / N + DO 60 I = 1, NRHS, CHUNK + BL = MIN( NRHS-I+1, CHUNK ) + CALL DGEMM( 'T', 'N', N, BL, M, ONE, A, LDA, B( 1, I ), + $ LDB, ZERO, WORK, N ) + CALL DLACPY( 'F', N, BL, WORK, N, B( 1, I ), LDB ) + 60 CONTINUE + ELSE + CALL DGEMV( 'T', M, N, ONE, A, LDA, B, 1, ZERO, WORK, 1 ) + CALL DCOPY( N, WORK, 1, B, 1 ) + END IF + END IF +* +* Undo scaling +* + IF( IASCL.EQ.1 ) THEN + CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO ) + CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN, + $ INFO ) + ELSE IF( IASCL.EQ.2 ) THEN + CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO ) + CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN, + $ INFO ) + END IF + IF( IBSCL.EQ.1 ) THEN + CALL DLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO ) + ELSE IF( IBSCL.EQ.2 ) THEN + CALL DLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO ) + END IF +* + 70 CONTINUE + WORK( 1 ) = MAXWRK + RETURN +* +* End of DGELSS +* + END diff --git a/ext/lapack/dgeqr2.f b/ext/lapack/dgeqr2.f new file mode 100755 index 000000000..9dc6435c5 --- /dev/null +++ b/ext/lapack/dgeqr2.f @@ -0,0 +1,122 @@ + SUBROUTINE DGEQR2( M, N, A, LDA, TAU, WORK, INFO ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* February 29, 1992 +* +* .. Scalar Arguments .. + INTEGER INFO, LDA, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * ) +* .. +* +* Purpose +* ======= +* +* DGEQR2 computes a QR factorization of a real m by n matrix A: +* A = Q * R. +* +* Arguments +* ========= +* +* M (input) INTEGER +* The number of rows of the matrix A. M >= 0. +* +* N (input) INTEGER +* The number of columns of the matrix A. N >= 0. +* +* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) +* On entry, the m by n matrix A. +* On exit, the elements on and above the diagonal of the array +* contain the min(m,n) by n upper trapezoidal matrix R (R is +* upper triangular if m >= n); the elements below the diagonal, +* with the array TAU, represent the orthogonal matrix Q as a +* product of elementary reflectors (see Further Details). +* +* LDA (input) INTEGER +* The leading dimension of the array A. LDA >= max(1,M). +* +* TAU (output) DOUBLE PRECISION array, dimension (min(M,N)) +* The scalar factors of the elementary reflectors (see Further +* Details). +* +* WORK (workspace) DOUBLE PRECISION array, dimension (N) +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument had an illegal value +* +* Further Details +* =============== +* +* The matrix Q is represented as a product of elementary reflectors +* +* Q = H(1) H(2) . . . H(k), where k = min(m,n). +* +* Each H(i) has the form +* +* H(i) = I - tau * v * v' +* +* where tau is a real scalar, and v is a real vector with +* v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i), +* and tau in TAU(i). +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER I, K + DOUBLE PRECISION AII +* .. +* .. External Subroutines .. + EXTERNAL DLARF, DLARFG, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 + IF( M.LT.0 ) THEN + INFO = -1 + ELSE IF( N.LT.0 ) THEN + INFO = -2 + ELSE IF( LDA.LT.MAX( 1, M ) ) THEN + INFO = -4 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DGEQR2', -INFO ) + RETURN + END IF +* + K = MIN( M, N ) +* + DO 10 I = 1, K +* +* Generate elementary reflector H(i) to annihilate A(i+1:m,i) +* + CALL DLARFG( M-I+1, A( I, I ), A( MIN( I+1, M ), I ), 1, + $ TAU( I ) ) + IF( I.LT.N ) THEN +* +* Apply H(i) to A(i:m,i+1:n) from the left +* + AII = A( I, I ) + A( I, I ) = ONE + CALL DLARF( 'Left', M-I+1, N-I, A( I, I ), 1, TAU( I ), + $ A( I, I+1 ), LDA, WORK ) + A( I, I ) = AII + END IF + 10 CONTINUE + RETURN +* +* End of DGEQR2 +* + END diff --git a/ext/lapack/dgeqrf.f b/ext/lapack/dgeqrf.f new file mode 100755 index 000000000..90aeae8ad --- /dev/null +++ b/ext/lapack/dgeqrf.f @@ -0,0 +1,187 @@ + SUBROUTINE DGEQRF( M, N, A, LDA, TAU, WORK, LWORK, INFO ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + INTEGER INFO, LDA, LWORK, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( LWORK ) +* .. +* +* Purpose +* ======= +* +* DGEQRF computes a QR factorization of a real M-by-N matrix A: +* A = Q * R. +* +* Arguments +* ========= +* +* M (input) INTEGER +* The number of rows of the matrix A. M >= 0. +* +* N (input) INTEGER +* The number of columns of the matrix A. N >= 0. +* +* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) +* On entry, the M-by-N matrix A. +* On exit, the elements on and above the diagonal of the array +* contain the min(M,N)-by-N upper trapezoidal matrix R (R is +* upper triangular if m >= n); the elements below the diagonal, +* with the array TAU, represent the orthogonal matrix Q as a +* product of min(m,n) elementary reflectors (see Further +* Details). +* +* LDA (input) INTEGER +* The leading dimension of the array A. LDA >= max(1,M). +* +* TAU (output) DOUBLE PRECISION array, dimension (min(M,N)) +* The scalar factors of the elementary reflectors (see Further +* Details). +* +* WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK) +* On exit, if INFO = 0, WORK(1) returns the optimal LWORK. +* +* LWORK (input) INTEGER +* The dimension of the array WORK. LWORK >= max(1,N). +* For optimum performance LWORK >= N*NB, where NB is +* the optimal blocksize. +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument had an illegal value +* +* Further Details +* =============== +* +* The matrix Q is represented as a product of elementary reflectors +* +* Q = H(1) H(2) . . . H(k), where k = min(m,n). +* +* Each H(i) has the form +* +* H(i) = I - tau * v * v' +* +* where tau is a real scalar, and v is a real vector with +* v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i), +* and tau in TAU(i). +* +* ===================================================================== +* +* .. Local Scalars .. + INTEGER I, IB, IINFO, IWS, K, LDWORK, NB, NBMIN, NX +* .. +* .. External Subroutines .. + EXTERNAL DGEQR2, DLARFB, DLARFT, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. External Functions .. + INTEGER ILAENV + EXTERNAL ILAENV +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 + IF( M.LT.0 ) THEN + INFO = -1 + ELSE IF( N.LT.0 ) THEN + INFO = -2 + ELSE IF( LDA.LT.MAX( 1, M ) ) THEN + INFO = -4 + ELSE IF( LWORK.LT.MAX( 1, N ) ) THEN + INFO = -7 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DGEQRF', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + K = MIN( M, N ) + IF( K.EQ.0 ) THEN + WORK( 1 ) = 1 + RETURN + END IF +* +* Determine the block size. +* + NB = ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 ) + NBMIN = 2 + NX = 0 + IWS = N + IF( NB.GT.1 .AND. NB.LT.K ) THEN +* +* Determine when to cross over from blocked to unblocked code. +* + NX = MAX( 0, ILAENV( 3, 'DGEQRF', ' ', M, N, -1, -1 ) ) + IF( NX.LT.K ) THEN +* +* Determine if workspace is large enough for blocked code. +* + LDWORK = N + IWS = LDWORK*NB + IF( LWORK.LT.IWS ) THEN +* +* Not enough workspace to use optimal NB: reduce NB and +* determine the minimum value of NB. +* + NB = LWORK / LDWORK + NBMIN = MAX( 2, ILAENV( 2, 'DGEQRF', ' ', M, N, -1, + $ -1 ) ) + END IF + END IF + END IF +* + IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN +* +* Use blocked code initially +* + DO 10 I = 1, K - NX, NB + IB = MIN( K-I+1, NB ) +* +* Compute the QR factorization of the current block +* A(i:m,i:i+ib-1) +* + CALL DGEQR2( M-I+1, IB, A( I, I ), LDA, TAU( I ), WORK, + $ IINFO ) + IF( I+IB.LE.N ) THEN +* +* Form the triangular factor of the block reflector +* H = H(i) H(i+1) . . . H(i+ib-1) +* + CALL DLARFT( 'Forward', 'Columnwise', M-I+1, IB, + $ A( I, I ), LDA, TAU( I ), WORK, LDWORK ) +* +* Apply H' to A(i:m,i+ib:n) from the left +* + CALL DLARFB( 'Left', 'Transpose', 'Forward', + $ 'Columnwise', M-I+1, N-I-IB+1, IB, + $ A( I, I ), LDA, WORK, LDWORK, A( I, I+IB ), + $ LDA, WORK( IB+1 ), LDWORK ) + END IF + 10 CONTINUE + ELSE + I = 1 + END IF +* +* Use unblocked code to factor the last or only block. +* + IF( I.LE.K ) + $ CALL DGEQR2( M-I+1, N-I+1, A( I, I ), LDA, TAU( I ), WORK, + $ IINFO ) +* + WORK( 1 ) = IWS + RETURN +* +* End of DGEQRF +* + END diff --git a/ext/lapack/dgetf2.f b/ext/lapack/dgetf2.f new file mode 100755 index 000000000..27610c487 --- /dev/null +++ b/ext/lapack/dgetf2.f @@ -0,0 +1,135 @@ + SUBROUTINE DGETF2( M, N, A, LDA, IPIV, INFO ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* June 30, 1992 +* +* .. Scalar Arguments .. + INTEGER INFO, LDA, M, N +* .. +* .. Array Arguments .. + INTEGER IPIV( * ) + DOUBLE PRECISION A( LDA, * ) +* .. +* +* Purpose +* ======= +* +* DGETF2 computes an LU factorization of a general m-by-n matrix A +* using partial pivoting with row interchanges. +* +* The factorization has the form +* A = P * L * U +* where P is a permutation matrix, L is lower triangular with unit +* diagonal elements (lower trapezoidal if m > n), and U is upper +* triangular (upper trapezoidal if m < n). +* +* This is the right-looking Level 2 BLAS version of the algorithm. +* +* Arguments +* ========= +* +* M (input) INTEGER +* The number of rows of the matrix A. M >= 0. +* +* N (input) INTEGER +* The number of columns of the matrix A. N >= 0. +* +* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) +* On entry, the m by n matrix to be factored. +* On exit, the factors L and U from the factorization +* A = P*L*U; the unit diagonal elements of L are not stored. +* +* LDA (input) INTEGER +* The leading dimension of the array A. LDA >= max(1,M). +* +* IPIV (output) INTEGER array, dimension (min(M,N)) +* The pivot indices; for 1 <= i <= min(M,N), row i of the +* matrix was interchanged with row IPIV(i). +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -k, the k-th argument had an illegal value +* > 0: if INFO = k, U(k,k) is exactly zero. The factorization +* has been completed, but the factor U is exactly +* singular, and division by zero will occur if it is used +* to solve a system of equations. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER J, JP +* .. +* .. External Functions .. + INTEGER IDAMAX + EXTERNAL IDAMAX +* .. +* .. External Subroutines .. + EXTERNAL DGER, DSCAL, DSWAP, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + IF( M.LT.0 ) THEN + INFO = -1 + ELSE IF( N.LT.0 ) THEN + INFO = -2 + ELSE IF( LDA.LT.MAX( 1, M ) ) THEN + INFO = -4 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DGETF2', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( M.EQ.0 .OR. N.EQ.0 ) + $ RETURN +* + DO 10 J = 1, MIN( M, N ) +* +* Find pivot and test for singularity. +* + JP = J - 1 + IDAMAX( M-J+1, A( J, J ), 1 ) + IPIV( J ) = JP + IF( A( JP, J ).NE.ZERO ) THEN +* +* Apply the interchange to columns 1:N. +* + IF( JP.NE.J ) + $ CALL DSWAP( N, A( J, 1 ), LDA, A( JP, 1 ), LDA ) +* +* Compute elements J+1:M of J-th column. +* + IF( J.LT.M ) + $ CALL DSCAL( M-J, ONE / A( J, J ), A( J+1, J ), 1 ) +* + ELSE IF( INFO.EQ.0 ) THEN +* + INFO = J + END IF +* + IF( J.LT.MIN( M, N ) ) THEN +* +* Update trailing submatrix. +* + CALL DGER( M-J, N-J, -ONE, A( J+1, J ), 1, A( J, J+1 ), LDA, + $ A( J+1, J+1 ), LDA ) + END IF + 10 CONTINUE + RETURN +* +* End of DGETF2 +* + END diff --git a/ext/lapack/dgetrf.f b/ext/lapack/dgetrf.f new file mode 100755 index 000000000..7c7fbf22c --- /dev/null +++ b/ext/lapack/dgetrf.f @@ -0,0 +1,160 @@ + SUBROUTINE DGETRF( M, N, A, LDA, IPIV, INFO ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* March 31, 1993 +* +* .. Scalar Arguments .. + INTEGER INFO, LDA, M, N +* .. +* .. Array Arguments .. + INTEGER IPIV( * ) + DOUBLE PRECISION A( LDA, * ) +* .. +* +* Purpose +* ======= +* +* DGETRF computes an LU factorization of a general M-by-N matrix A +* using partial pivoting with row interchanges. +* +* The factorization has the form +* A = P * L * U +* where P is a permutation matrix, L is lower triangular with unit +* diagonal elements (lower trapezoidal if m > n), and U is upper +* triangular (upper trapezoidal if m < n). +* +* This is the right-looking Level 3 BLAS version of the algorithm. +* +* Arguments +* ========= +* +* M (input) INTEGER +* The number of rows of the matrix A. M >= 0. +* +* N (input) INTEGER +* The number of columns of the matrix A. N >= 0. +* +* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) +* On entry, the M-by-N matrix to be factored. +* On exit, the factors L and U from the factorization +* A = P*L*U; the unit diagonal elements of L are not stored. +* +* LDA (input) INTEGER +* The leading dimension of the array A. LDA >= max(1,M). +* +* IPIV (output) INTEGER array, dimension (min(M,N)) +* The pivot indices; for 1 <= i <= min(M,N), row i of the +* matrix was interchanged with row IPIV(i). +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument had an illegal value +* > 0: if INFO = i, U(i,i) is exactly zero. The factorization +* has been completed, but the factor U is exactly +* singular, and division by zero will occur if it is used +* to solve a system of equations. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER I, IINFO, J, JB, NB +* .. +* .. External Subroutines .. + EXTERNAL DGEMM, DGETF2, DLASWP, DTRSM, XERBLA +* .. +* .. External Functions .. + INTEGER ILAENV + EXTERNAL ILAENV +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + IF( M.LT.0 ) THEN + INFO = -1 + ELSE IF( N.LT.0 ) THEN + INFO = -2 + ELSE IF( LDA.LT.MAX( 1, M ) ) THEN + INFO = -4 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DGETRF', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( M.EQ.0 .OR. N.EQ.0 ) + $ RETURN +* +* Determine the block size for this environment. +* + NB = ILAENV( 1, 'DGETRF', ' ', M, N, -1, -1 ) + IF( NB.LE.1 .OR. NB.GE.MIN( M, N ) ) THEN +* +* Use unblocked code. +* + CALL DGETF2( M, N, A, LDA, IPIV, INFO ) + ELSE +* +* Use blocked code. +* + DO 20 J = 1, MIN( M, N ), NB + JB = MIN( MIN( M, N )-J+1, NB ) +* +* Factor diagonal and subdiagonal blocks and test for exact +* singularity. +* + CALL DGETF2( M-J+1, JB, A( J, J ), LDA, IPIV( J ), IINFO ) +* +* Adjust INFO and the pivot indices. +* + IF( INFO.EQ.0 .AND. IINFO.GT.0 ) + $ INFO = IINFO + J - 1 + DO 10 I = J, MIN( M, J+JB-1 ) + IPIV( I ) = J - 1 + IPIV( I ) + 10 CONTINUE +* +* Apply interchanges to columns 1:J-1. +* + CALL DLASWP( J-1, A, LDA, J, J+JB-1, IPIV, 1 ) +* + IF( J+JB.LE.N ) THEN +* +* Apply interchanges to columns J+JB:N. +* + CALL DLASWP( N-J-JB+1, A( 1, J+JB ), LDA, J, J+JB-1, + $ IPIV, 1 ) +* +* Compute block row of U. +* + CALL DTRSM( 'Left', 'Lower', 'No transpose', 'Unit', JB, + $ N-J-JB+1, ONE, A( J, J ), LDA, A( J, J+JB ), + $ LDA ) + IF( J+JB.LE.M ) THEN +* +* Update trailing submatrix. +* + CALL DGEMM( 'No transpose', 'No transpose', M-J-JB+1, + $ N-J-JB+1, JB, -ONE, A( J+JB, J ), LDA, + $ A( J, J+JB ), LDA, ONE, A( J+JB, J+JB ), + $ LDA ) + END IF + END IF + 20 CONTINUE + END IF + RETURN +* +* End of DGETRF +* + END diff --git a/ext/lapack/dgetri.f b/ext/lapack/dgetri.f new file mode 100755 index 000000000..efe21b7a0 --- /dev/null +++ b/ext/lapack/dgetri.f @@ -0,0 +1,801 @@ + SUBROUTINE DGETRI( N, A, LDA, IPIV, WORK, LWORK, INFO ) +* +* -- LAPACK routine (version 3.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* June 30, 1999 +* +* .. Scalar Arguments .. + INTEGER INFO, LDA, LWORK, N +* .. +* .. Array Arguments .. + INTEGER IPIV( * ) + DOUBLE PRECISION A( LDA, * ), WORK( * ) +* .. +* +* Purpose +* ======= +* +* DGETRI computes the inverse of a matrix using the LU factorization +* computed by DGETRF. +* +* This method inverts U and then computes inv(A) by solving the system +* inv(A)*L = inv(U) for inv(A). +* +* Arguments +* ========= +* +* N (input) INTEGER +* The order of the matrix A. N >= 0. +* +* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) +* On entry, the factors L and U from the factorization +* A = P*L*U as computed by DGETRF. +* On exit, if INFO = 0, the inverse of the original matrix A. +* +* LDA (input) INTEGER +* The leading dimension of the array A. LDA >= max(1,N). +* +* IPIV (input) INTEGER array, dimension (N) +* The pivot indices from DGETRF; for 1<=i<=N, row i of the +* matrix was interchanged with row IPIV(i). +* +* WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK) +* On exit, if INFO=0, then WORK(1) returns the optimal LWORK. +* +* LWORK (input) INTEGER +* The dimension of the array WORK. LWORK >= max(1,N). +* For optimal performance LWORK >= N*NB, where NB is +* the optimal blocksize returned by ILAENV. +* +* If LWORK = -1, then a workspace query is assumed; the routine +* only calculates the optimal size of the WORK array, returns +* this value as the first entry of the WORK array, and no error +* message related to LWORK is issued by XERBLA. +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument had an illegal value +* > 0: if INFO = i, U(i,i) is exactly zero; the matrix is +* singular and its inverse could not be computed. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO, ONE + PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 ) +* .. +* .. Local Scalars .. + LOGICAL LQUERY + INTEGER I, IWS, J, JB, JJ, JP, LDWORK, LWKOPT, NB, + $ NBMIN, NN +* .. +* .. External Functions .. + INTEGER ILAENV + EXTERNAL ILAENV +* .. +* .. External Subroutines .. + EXTERNAL DGEMM, DGEMV, DSWAP, DTRSM, DTRTRI, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + NB = ILAENV( 1, 'DGETRI', ' ', N, -1, -1, -1 ) + LWKOPT = N*NB + WORK( 1 ) = LWKOPT + LQUERY = ( LWORK.EQ.-1 ) + IF( N.LT.0 ) THEN + INFO = -1 + ELSE IF( LDA.LT.MAX( 1, N ) ) THEN + INFO = -3 + ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN + INFO = -6 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DGETRI', -INFO ) + RETURN + ELSE IF( LQUERY ) THEN + RETURN + END IF +* +* Quick return if possible +* + IF( N.EQ.0 ) + $ RETURN +* +* Form inv(U). If INFO > 0 from DTRTRI, then U is singular, +* and the inverse is not computed. +* + CALL DTRTRI( 'Upper', 'Non-unit', N, A, LDA, INFO ) + IF( INFO.GT.0 ) + $ RETURN +* + NBMIN = 2 + LDWORK = N + IF( NB.GT.1 .AND. NB.LT.N ) THEN + IWS = MAX( LDWORK*NB, 1 ) + IF( LWORK.LT.IWS ) THEN + NB = LWORK / LDWORK + NBMIN = MAX( 2, ILAENV( 2, 'DGETRI', ' ', N, -1, -1, -1 ) ) + END IF + ELSE + IWS = N + END IF +* +* Solve the equation inv(A)*L = inv(U) for inv(A). +* + IF( NB.LT.NBMIN .OR. NB.GE.N ) THEN +* +* Use unblocked code. +* + DO 20 J = N, 1, -1 +* +* Copy current column of L to WORK and replace with zeros. +* + DO 10 I = J + 1, N + WORK( I ) = A( I, J ) + A( I, J ) = ZERO + 10 CONTINUE +* +* Compute current column of inv(A). +* + IF( J.LT.N ) + $ CALL DGEMV( 'No transpose', N, N-J, -ONE, A( 1, J+1 ), + $ LDA, WORK( J+1 ), 1, ONE, A( 1, J ), 1 ) + 20 CONTINUE + ELSE +* +* Use blocked code. +* + NN = ( ( N-1 ) / NB )*NB + 1 + DO 50 J = NN, 1, -NB + JB = MIN( NB, N-J+1 ) +* +* Copy current block column of L to WORK and replace with +* zeros. +* + DO 40 JJ = J, J + JB - 1 + DO 30 I = JJ + 1, N + WORK( I+( JJ-J )*LDWORK ) = A( I, JJ ) + A( I, JJ ) = ZERO + 30 CONTINUE + 40 CONTINUE +* +* Compute current block column of inv(A). +* + IF( J+JB.LE.N ) + $ CALL DGEMM( 'No transpose', 'No transpose', N, JB, + $ N-J-JB+1, -ONE, A( 1, J+JB ), LDA, + $ WORK( J+JB ), LDWORK, ONE, A( 1, J ), LDA ) + CALL DTRSM( 'Right', 'Lower', 'No transpose', 'Unit', N, JB, + $ ONE, WORK( J ), LDWORK, A( 1, J ), LDA ) + 50 CONTINUE + END IF +* +* Apply column interchanges. +* + DO 60 J = N - 1, 1, -1 + JP = IPIV( J ) + IF( JP.NE.J ) + $ CALL DSWAP( N, A( 1, J ), 1, A( 1, JP ), 1 ) + 60 CONTINUE +* + WORK( 1 ) = IWS + RETURN +* +* End of DGETRI +* + END + SUBROUTINE DTRTI2( UPLO, DIAG, N, A, LDA, INFO ) +* +* -- LAPACK routine (version 3.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* February 29, 1992 +* +* .. Scalar Arguments .. + CHARACTER DIAG, UPLO + INTEGER INFO, LDA, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ) +* .. +* +* Purpose +* ======= +* +* DTRTI2 computes the inverse of a real upper or lower triangular +* matrix. +* +* This is the Level 2 BLAS version of the algorithm. +* +* Arguments +* ========= +* +* UPLO (input) CHARACTER*1 +* Specifies whether the matrix A is upper or lower triangular. +* = 'U': Upper triangular +* = 'L': Lower triangular +* +* DIAG (input) CHARACTER*1 +* Specifies whether or not the matrix A is unit triangular. +* = 'N': Non-unit triangular +* = 'U': Unit triangular +* +* N (input) INTEGER +* The order of the matrix A. N >= 0. +* +* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) +* On entry, the triangular matrix A. If UPLO = 'U', the +* leading n by n upper triangular part of the array A contains +* the upper triangular matrix, and the strictly lower +* triangular part of A is not referenced. If UPLO = 'L', the +* leading n by n lower triangular part of the array A contains +* the lower triangular matrix, and the strictly upper +* triangular part of A is not referenced. If DIAG = 'U', the +* diagonal elements of A are also not referenced and are +* assumed to be 1. +* +* On exit, the (triangular) inverse of the original matrix, in +* the same storage format. +* +* LDA (input) INTEGER +* The leading dimension of the array A. LDA >= max(1,N). +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -k, the k-th argument had an illegal value +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D+0 ) +* .. +* .. Local Scalars .. + LOGICAL NOUNIT, UPPER + INTEGER J + DOUBLE PRECISION AJJ +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. External Subroutines .. + EXTERNAL DSCAL, DTRMV, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + UPPER = LSAME( UPLO, 'U' ) + NOUNIT = LSAME( DIAG, 'N' ) + IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN + INFO = -1 + ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN + INFO = -2 + ELSE IF( N.LT.0 ) THEN + INFO = -3 + ELSE IF( LDA.LT.MAX( 1, N ) ) THEN + INFO = -5 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DTRTI2', -INFO ) + RETURN + END IF +* + IF( UPPER ) THEN +* +* Compute inverse of upper triangular matrix. +* + DO 10 J = 1, N + IF( NOUNIT ) THEN + A( J, J ) = ONE / A( J, J ) + AJJ = -A( J, J ) + ELSE + AJJ = -ONE + END IF +* +* Compute elements 1:j-1 of j-th column. +* + CALL DTRMV( 'Upper', 'No transpose', DIAG, J-1, A, LDA, + $ A( 1, J ), 1 ) + CALL DSCAL( J-1, AJJ, A( 1, J ), 1 ) + 10 CONTINUE + ELSE +* +* Compute inverse of lower triangular matrix. +* + DO 20 J = N, 1, -1 + IF( NOUNIT ) THEN + A( J, J ) = ONE / A( J, J ) + AJJ = -A( J, J ) + ELSE + AJJ = -ONE + END IF + IF( J.LT.N ) THEN +* +* Compute elements j+1:n of j-th column. +* + CALL DTRMV( 'Lower', 'No transpose', DIAG, N-J, + $ A( J+1, J+1 ), LDA, A( J+1, J ), 1 ) + CALL DSCAL( N-J, AJJ, A( J+1, J ), 1 ) + END IF + 20 CONTINUE + END IF +* + RETURN +* +* End of DTRTI2 +* + END + SUBROUTINE DTRTRI( UPLO, DIAG, N, A, LDA, INFO ) +* +* -- LAPACK routine (version 3.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* March 31, 1993 +* +* .. Scalar Arguments .. + CHARACTER DIAG, UPLO + INTEGER INFO, LDA, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ) +* .. +* +* Purpose +* ======= +* +* DTRTRI computes the inverse of a real upper or lower triangular +* matrix A. +* +* This is the Level 3 BLAS version of the algorithm. +* +* Arguments +* ========= +* +* UPLO (input) CHARACTER*1 +* = 'U': A is upper triangular; +* = 'L': A is lower triangular. +* +* DIAG (input) CHARACTER*1 +* = 'N': A is non-unit triangular; +* = 'U': A is unit triangular. +* +* N (input) INTEGER +* The order of the matrix A. N >= 0. +* +* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) +* On entry, the triangular matrix A. If UPLO = 'U', the +* leading N-by-N upper triangular part of the array A contains +* the upper triangular matrix, and the strictly lower +* triangular part of A is not referenced. If UPLO = 'L', the +* leading N-by-N lower triangular part of the array A contains +* the lower triangular matrix, and the strictly upper +* triangular part of A is not referenced. If DIAG = 'U', the +* diagonal elements of A are also not referenced and are +* assumed to be 1. +* On exit, the (triangular) inverse of the original matrix, in +* the same storage format. +* +* LDA (input) INTEGER +* The leading dimension of the array A. LDA >= max(1,N). +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument had an illegal value +* > 0: if INFO = i, A(i,i) is exactly zero. The triangular +* matrix is singular and its inverse can not be computed. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + LOGICAL NOUNIT, UPPER + INTEGER J, JB, NB, NN +* .. +* .. External Functions .. + LOGICAL LSAME + INTEGER ILAENV + EXTERNAL LSAME, ILAENV +* .. +* .. External Subroutines .. + EXTERNAL DTRMM, DTRSM, DTRTI2, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + UPPER = LSAME( UPLO, 'U' ) + NOUNIT = LSAME( DIAG, 'N' ) + IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN + INFO = -1 + ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN + INFO = -2 + ELSE IF( N.LT.0 ) THEN + INFO = -3 + ELSE IF( LDA.LT.MAX( 1, N ) ) THEN + INFO = -5 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DTRTRI', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( N.EQ.0 ) + $ RETURN +* +* Check for singularity if non-unit. +* + IF( NOUNIT ) THEN + DO 10 INFO = 1, N + IF( A( INFO, INFO ).EQ.ZERO ) + $ RETURN + 10 CONTINUE + INFO = 0 + END IF +* +* Determine the block size for this environment. +* + NB = ILAENV( 1, 'DTRTRI', UPLO // DIAG, N, -1, -1, -1 ) + IF( NB.LE.1 .OR. NB.GE.N ) THEN +* +* Use unblocked code +* + CALL DTRTI2( UPLO, DIAG, N, A, LDA, INFO ) + ELSE +* +* Use blocked code +* + IF( UPPER ) THEN +* +* Compute inverse of upper triangular matrix +* + DO 20 J = 1, N, NB + JB = MIN( NB, N-J+1 ) +* +* Compute rows 1:j-1 of current block column +* + CALL DTRMM( 'Left', 'Upper', 'No transpose', DIAG, J-1, + $ JB, ONE, A, LDA, A( 1, J ), LDA ) + CALL DTRSM( 'Right', 'Upper', 'No transpose', DIAG, J-1, + $ JB, -ONE, A( J, J ), LDA, A( 1, J ), LDA ) +* +* Compute inverse of current diagonal block +* + CALL DTRTI2( 'Upper', DIAG, JB, A( J, J ), LDA, INFO ) + 20 CONTINUE + ELSE +* +* Compute inverse of lower triangular matrix +* + NN = ( ( N-1 ) / NB )*NB + 1 + DO 30 J = NN, 1, -NB + JB = MIN( NB, N-J+1 ) + IF( J+JB.LE.N ) THEN +* +* Compute rows j+jb:n of current block column +* + CALL DTRMM( 'Left', 'Lower', 'No transpose', DIAG, + $ N-J-JB+1, JB, ONE, A( J+JB, J+JB ), LDA, + $ A( J+JB, J ), LDA ) + CALL DTRSM( 'Right', 'Lower', 'No transpose', DIAG, + $ N-J-JB+1, JB, -ONE, A( J, J ), LDA, + $ A( J+JB, J ), LDA ) + END IF +* +* Compute inverse of current diagonal block +* + CALL DTRTI2( 'Lower', DIAG, JB, A( J, J ), LDA, INFO ) + 30 CONTINUE + END IF + END IF +* + RETURN +* +* End of DTRTRI +* + END + INTEGER FUNCTION IEEECK( ISPEC, ZERO, ONE ) +* +* -- LAPACK auxiliary routine (version 3.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* June 30, 1998 +* +* .. Scalar Arguments .. + INTEGER ISPEC + REAL ONE, ZERO +* .. +* +* Purpose +* ======= +* +* IEEECK is called from the ILAENV to verify that Infinity and +* possibly NaN arithmetic is safe (i.e. will not trap). +* +* Arguments +* ========= +* +* ISPEC (input) INTEGER +* Specifies whether to test just for inifinity arithmetic +* or whether to test for infinity and NaN arithmetic. +* = 0: Verify infinity arithmetic only. +* = 1: Verify infinity and NaN arithmetic. +* +* ZERO (input) REAL +* Must contain the value 0.0 +* This is passed to prevent the compiler from optimizing +* away this code. +* +* ONE (input) REAL +* Must contain the value 1.0 +* This is passed to prevent the compiler from optimizing +* away this code. +* +* RETURN VALUE: INTEGER +* = 0: Arithmetic failed to produce the correct answers +* = 1: Arithmetic produced the correct answers +* +* .. Local Scalars .. + REAL NAN1, NAN2, NAN3, NAN4, NAN5, NAN6, NEGINF, + $ NEGZRO, NEWZRO, POSINF +* .. +* .. Executable Statements .. + IEEECK = 1 +* + POSINF = ONE / ZERO + IF( POSINF.LE.ONE ) THEN + IEEECK = 0 + RETURN + END IF +* + NEGINF = -ONE / ZERO + IF( NEGINF.GE.ZERO ) THEN + IEEECK = 0 + RETURN + END IF +* + NEGZRO = ONE / ( NEGINF+ONE ) + IF( NEGZRO.NE.ZERO ) THEN + IEEECK = 0 + RETURN + END IF +* + NEGINF = ONE / NEGZRO + IF( NEGINF.GE.ZERO ) THEN + IEEECK = 0 + RETURN + END IF +* + NEWZRO = NEGZRO + ZERO + IF( NEWZRO.NE.ZERO ) THEN + IEEECK = 0 + RETURN + END IF +* + POSINF = ONE / NEWZRO + IF( POSINF.LE.ONE ) THEN + IEEECK = 0 + RETURN + END IF +* + NEGINF = NEGINF*POSINF + IF( NEGINF.GE.ZERO ) THEN + IEEECK = 0 + RETURN + END IF +* + POSINF = POSINF*POSINF + IF( POSINF.LE.ONE ) THEN + IEEECK = 0 + RETURN + END IF +* +* +* +* +* Return if we were only asked to check infinity arithmetic +* + IF( ISPEC.EQ.0 ) + $ RETURN +* + NAN1 = POSINF + NEGINF +* + NAN2 = POSINF / NEGINF +* + NAN3 = POSINF / POSINF +* + NAN4 = POSINF*ZERO +* + NAN5 = NEGINF*NEGZRO +* + NAN6 = NAN5*0.0 +* + IF( NAN1.EQ.NAN1 ) THEN + IEEECK = 0 + RETURN + END IF +* + IF( NAN2.EQ.NAN2 ) THEN + IEEECK = 0 + RETURN + END IF +* + IF( NAN3.EQ.NAN3 ) THEN + IEEECK = 0 + RETURN + END IF +* + IF( NAN4.EQ.NAN4 ) THEN + IEEECK = 0 + RETURN + END IF +* + IF( NAN5.EQ.NAN5 ) THEN + IEEECK = 0 + RETURN + END IF +* + IF( NAN6.EQ.NAN6 ) THEN + IEEECK = 0 + RETURN + END IF +* + RETURN + END + +c END + +c LOGICAL FUNCTION LSAME( CA, CB ) +* +* -- LAPACK auxiliary routine (version 3.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. +c CHARACTER CA, CB +* .. +* +* Purpose +* ======= +* +* LSAME returns .TRUE. if CA is the same letter as CB regardless of +* case. +* +* Arguments +* ========= +* +* CA (input) CHARACTER*1 +* CB (input) CHARACTER*1 +* CA and CB specify the single characters to be compared. +* +* ===================================================================== +* +* .. Intrinsic Functions .. +c INTRINSIC ICHAR +* .. +* .. Local Scalars .. +c INTEGER INTA, INTB, ZCODE +* .. +* .. Executable Statements .. +* +* Test if the characters are equal +* +c LSAME = CA.EQ.CB +c IF( LSAME ) +c $ RETURN +* +* Now test for equivalence if both characters are alphabetic. +* +c ZCODE = ICHAR( 'Z' ) +* +* Use 'Z' rather than 'A' so that ASCII can be detected on Prime +* machines, on which ICHAR returns a value with bit 8 set. +* ICHAR('A') on Prime machines returns 193 which is the same as +* ICHAR('A') on an EBCDIC machine. +* +c INTA = ICHAR( CA ) +c INTB = ICHAR( CB ) +* +c IF( ZCODE.EQ.90 .OR. ZCODE.EQ.122 ) THEN +* +* ASCII is assumed - ZCODE is the ASCII code of either lower or +* upper case 'Z'. +* +c IF( INTA.GE.97 .AND. INTA.LE.122 ) INTA = INTA - 32 +c IF( INTB.GE.97 .AND. INTB.LE.122 ) INTB = INTB - 32 +* +c ELSE IF( ZCODE.EQ.233 .OR. ZCODE.EQ.169 ) THEN +* +* EBCDIC is assumed - ZCODE is the EBCDIC code of either lower or +* upper case 'Z'. +* +c IF( INTA.GE.129 .AND. INTA.LE.137 .OR. +c $ INTA.GE.145 .AND. INTA.LE.153 .OR. +c $ INTA.GE.162 .AND. INTA.LE.169 ) INTA = INTA + 64 +c IF( INTB.GE.129 .AND. INTB.LE.137 .OR. +c $ INTB.GE.145 .AND. INTB.LE.153 .OR. +c $ INTB.GE.162 .AND. INTB.LE.169 ) INTB = INTB + 64 +* +c ELSE IF( ZCODE.EQ.218 .OR. ZCODE.EQ.250 ) THEN +* +* ASCII is assumed, on Prime machines - ZCODE is the ASCII code +* plus 128 of either lower or upper case 'Z'. +* +c IF( INTA.GE.225 .AND. INTA.LE.250 ) INTA = INTA - 32 +c IF( INTB.GE.225 .AND. INTB.LE.250 ) INTB = INTB - 32 +c END IF +c LSAME = INTA.EQ.INTB +* +* RETURN +* +* End of LSAME +* +c END +c$$$ SUBROUTINE XERBLA( SRNAME, INFO ) +c$$$* +c$$$* -- LAPACK auxiliary routine (version 3.0) -- +c$$$* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +c$$$* Courant Institute, Argonne National Lab, and Rice University +c$$$* September 30, 1994 +c$$$* +c$$$* .. Scalar Arguments .. +c$$$ CHARACTER*6 SRNAME +c$$$ INTEGER INFO +c$$$* .. +c$$$* +c$$$* Purpose +c$$$* ======= +c$$$* +c$$$* XERBLA is an error handler for the LAPACK routines. +c$$$* It is called by an LAPACK routine if an input parameter has an +c$$$* invalid value. A message is printed and execution stops. +c$$$* +c$$$* Installers may consider modifying the STOP statement in order to +c$$$* call system-specific exception-handling facilities. +c$$$* +c$$$* Arguments +c$$$* ========= +c$$$* +c$$$* SRNAME (input) CHARACTER*6 +c$$$* The name of the routine which called XERBLA. +c$$$* +c$$$* INFO (input) INTEGER +c$$$* The position of the invalid parameter in the parameter list +c$$$* of the calling routine. +c$$$* +c$$$* ===================================================================== +c$$$* +c$$$* .. Executable Statements .. +c$$$* +c$$$ WRITE( *, FMT = 9999 )SRNAME, INFO +c$$$* +c$$$ STOP +c$$$* +c$$$ 9999 FORMAT( ' ** On entry to ', A6, ' parameter number ', I2, ' had ', +c$$$ $ 'an illegal value' ) +c$$$* +c$$$* End of XERBLA +c$$$* +c$$$ END \ No newline at end of file diff --git a/ext/lapack/dgetrs.f b/ext/lapack/dgetrs.f new file mode 100755 index 000000000..1d0db1e91 --- /dev/null +++ b/ext/lapack/dgetrs.f @@ -0,0 +1,150 @@ + SUBROUTINE DGETRS( TRANS, N, NRHS, A, LDA, IPIV, B, LDB, INFO ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* March 31, 1993 +* +* .. Scalar Arguments .. + CHARACTER TRANS + INTEGER INFO, LDA, LDB, N, NRHS +* .. +* .. Array Arguments .. + INTEGER IPIV( * ) + DOUBLE PRECISION A( LDA, * ), B( LDB, * ) +* .. +* +* Purpose +* ======= +* +* DGETRS solves a system of linear equations +* A * X = B or A' * X = B +* with a general N-by-N matrix A using the LU factorization computed +* by DGETRF. +* +* Arguments +* ========= +* +* TRANS (input) CHARACTER*1 +* Specifies the form of the system of equations: +* = 'N': A * X = B (No transpose) +* = 'T': A'* X = B (Transpose) +* = 'C': A'* X = B (Conjugate transpose = Transpose) +* +* N (input) INTEGER +* The order of the matrix A. N >= 0. +* +* NRHS (input) INTEGER +* The number of right hand sides, i.e., the number of columns +* of the matrix B. NRHS >= 0. +* +* A (input) DOUBLE PRECISION array, dimension (LDA,N) +* The factors L and U from the factorization A = P*L*U +* as computed by DGETRF. +* +* LDA (input) INTEGER +* The leading dimension of the array A. LDA >= max(1,N). +* +* IPIV (input) INTEGER array, dimension (N) +* The pivot indices from DGETRF; for 1<=i<=N, row i of the +* matrix was interchanged with row IPIV(i). +* +* B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS) +* On entry, the right hand side matrix B. +* On exit, the solution matrix X. +* +* LDB (input) INTEGER +* The leading dimension of the array B. LDB >= max(1,N). +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument had an illegal value +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D+0 ) +* .. +* .. Local Scalars .. + LOGICAL NOTRAN +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. External Subroutines .. + EXTERNAL DLASWP, DTRSM, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 + NOTRAN = LSAME( TRANS, 'N' ) + IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT. + $ LSAME( TRANS, 'C' ) ) THEN + INFO = -1 + ELSE IF( N.LT.0 ) THEN + INFO = -2 + ELSE IF( NRHS.LT.0 ) THEN + INFO = -3 + ELSE IF( LDA.LT.MAX( 1, N ) ) THEN + INFO = -5 + ELSE IF( LDB.LT.MAX( 1, N ) ) THEN + INFO = -8 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DGETRS', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( N.EQ.0 .OR. NRHS.EQ.0 ) + $ RETURN +* + IF( NOTRAN ) THEN +* +* Solve A * X = B. +* +* Apply row interchanges to the right hand sides. +* + CALL DLASWP( NRHS, B, LDB, 1, N, IPIV, 1 ) +* +* Solve L*X = B, overwriting B with X. +* + CALL DTRSM( 'Left', 'Lower', 'No transpose', 'Unit', N, NRHS, + $ ONE, A, LDA, B, LDB ) +* +* Solve U*X = B, overwriting B with X. +* + CALL DTRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', N, + $ NRHS, ONE, A, LDA, B, LDB ) + ELSE +* +* Solve A' * X = B. +* +* Solve U'*X = B, overwriting B with X. +* + CALL DTRSM( 'Left', 'Upper', 'Transpose', 'Non-unit', N, NRHS, + $ ONE, A, LDA, B, LDB ) +* +* Solve L'*X = B, overwriting B with X. +* + CALL DTRSM( 'Left', 'Lower', 'Transpose', 'Unit', N, NRHS, ONE, + $ A, LDA, B, LDB ) +* +* Apply row interchanges to the solution vectors. +* + CALL DLASWP( NRHS, B, LDB, 1, N, IPIV, -1 ) + END IF +* + RETURN +* +* End of DGETRS +* + END diff --git a/ext/lapack/dlabad.f b/ext/lapack/dlabad.f new file mode 100755 index 000000000..1f453d222 --- /dev/null +++ b/ext/lapack/dlabad.f @@ -0,0 +1,56 @@ + SUBROUTINE DLABAD( SMALL, LARGE ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* October 31, 1992 +* +* .. Scalar Arguments .. + DOUBLE PRECISION LARGE, SMALL +* .. +* +* Purpose +* ======= +* +* DLABAD takes as input the values computed by SLAMCH for underflow and +* overflow, and returns the square root of each of these values if the +* log of LARGE is sufficiently large. This subroutine is intended to +* identify machines with a large exponent range, such as the Crays, and +* redefine the underflow and overflow limits to be the square roots of +* the values computed by DLAMCH. This subroutine is needed because +* DLAMCH does not compensate for poor arithmetic in the upper half of +* the exponent range, as is found on a Cray. +* +* Arguments +* ========= +* +* SMALL (input/output) DOUBLE PRECISION +* On entry, the underflow threshold as computed by DLAMCH. +* On exit, if LOG10(LARGE) is sufficiently large, the square +* root of SMALL, otherwise unchanged. +* +* LARGE (input/output) DOUBLE PRECISION +* On entry, the overflow threshold as computed by DLAMCH. +* On exit, if LOG10(LARGE) is sufficiently large, the square +* root of LARGE, otherwise unchanged. +* +* ===================================================================== +* +* .. Intrinsic Functions .. + INTRINSIC LOG10, SQRT +* .. +* .. Executable Statements .. +* +* If it looks like we're on a Cray, take the square root of +* SMALL and LARGE to avoid overflow and underflow problems. +* + IF( LOG10( LARGE ).GT.2000.D0 ) THEN + SMALL = SQRT( SMALL ) + LARGE = SQRT( LARGE ) + END IF +* + RETURN +* +* End of DLABAD +* + END diff --git a/ext/lapack/dlabrd.f b/ext/lapack/dlabrd.f new file mode 100755 index 000000000..50d333af4 --- /dev/null +++ b/ext/lapack/dlabrd.f @@ -0,0 +1,291 @@ + SUBROUTINE DLABRD( M, N, NB, A, LDA, D, E, TAUQ, TAUP, X, LDX, Y, + $ LDY ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* February 29, 1992 +* +* .. Scalar Arguments .. + INTEGER LDA, LDX, LDY, M, N, NB +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), D( * ), E( * ), TAUP( * ), + $ TAUQ( * ), X( LDX, * ), Y( LDY, * ) +* .. +* +* Purpose +* ======= +* +* DLABRD reduces the first NB rows and columns of a real general +* m by n matrix A to upper or lower bidiagonal form by an orthogonal +* transformation Q' * A * P, and returns the matrices X and Y which +* are needed to apply the transformation to the unreduced part of A. +* +* If m >= n, A is reduced to upper bidiagonal form; if m < n, to lower +* bidiagonal form. +* +* This is an auxiliary routine called by DGEBRD +* +* Arguments +* ========= +* +* M (input) INTEGER +* The number of rows in the matrix A. +* +* N (input) INTEGER +* The number of columns in the matrix A. +* +* NB (input) INTEGER +* The number of leading rows and columns of A to be reduced. +* +* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) +* On entry, the m by n general matrix to be reduced. +* On exit, the first NB rows and columns of the matrix are +* overwritten; the rest of the array is unchanged. +* If m >= n, elements on and below the diagonal in the first NB +* columns, with the array TAUQ, represent the orthogonal +* matrix Q as a product of elementary reflectors; and +* elements above the diagonal in the first NB rows, with the +* array TAUP, represent the orthogonal matrix P as a product +* of elementary reflectors. +* If m < n, elements below the diagonal in the first NB +* columns, with the array TAUQ, represent the orthogonal +* matrix Q as a product of elementary reflectors, and +* elements on and above the diagonal in the first NB rows, +* with the array TAUP, represent the orthogonal matrix P as +* a product of elementary reflectors. +* See Further Details. +* +* LDA (input) INTEGER +* The leading dimension of the array A. LDA >= max(1,M). +* +* D (output) DOUBLE PRECISION array, dimension (NB) +* The diagonal elements of the first NB rows and columns of +* the reduced matrix. D(i) = A(i,i). +* +* E (output) DOUBLE PRECISION array, dimension (NB) +* The off-diagonal elements of the first NB rows and columns of +* the reduced matrix. +* +* TAUQ (output) DOUBLE PRECISION array dimension (NB) +* The scalar factors of the elementary reflectors which +* represent the orthogonal matrix Q. See Further Details. +* +* TAUP (output) DOUBLE PRECISION array, dimension (NB) +* The scalar factors of the elementary reflectors which +* represent the orthogonal matrix P. See Further Details. +* +* X (output) DOUBLE PRECISION array, dimension (LDX,NB) +* The m-by-nb matrix X required to update the unreduced part +* of A. +* +* LDX (input) INTEGER +* The leading dimension of the array X. LDX >= M. +* +* Y (output) DOUBLE PRECISION array, dimension (LDY,NB) +* The n-by-nb matrix Y required to update the unreduced part +* of A. +* +* LDY (output) INTEGER +* The leading dimension of the array Y. LDY >= N. +* +* Further Details +* =============== +* +* The matrices Q and P are represented as products of elementary +* reflectors: +* +* Q = H(1) H(2) . . . H(nb) and P = G(1) G(2) . . . G(nb) +* +* Each H(i) and G(i) has the form: +* +* H(i) = I - tauq * v * v' and G(i) = I - taup * u * u' +* +* where tauq and taup are real scalars, and v and u are real vectors. +* +* If m >= n, v(1:i-1) = 0, v(i) = 1, and v(i:m) is stored on exit in +* A(i:m,i); u(1:i) = 0, u(i+1) = 1, and u(i+1:n) is stored on exit in +* A(i,i+1:n); tauq is stored in TAUQ(i) and taup in TAUP(i). +* +* If m < n, v(1:i) = 0, v(i+1) = 1, and v(i+1:m) is stored on exit in +* A(i+2:m,i); u(1:i-1) = 0, u(i) = 1, and u(i:n) is stored on exit in +* A(i,i+1:n); tauq is stored in TAUQ(i) and taup in TAUP(i). +* +* The elements of the vectors v and u together form the m-by-nb matrix +* V and the nb-by-n matrix U' which are needed, with X and Y, to apply +* the transformation to the unreduced part of the matrix, using a block +* update of the form: A := A - V*Y' - X*U'. +* +* The contents of A on exit are illustrated by the following examples +* with nb = 2: +* +* m = 6 and n = 5 (m > n): m = 5 and n = 6 (m < n): +* +* ( 1 1 u1 u1 u1 ) ( 1 u1 u1 u1 u1 u1 ) +* ( v1 1 1 u2 u2 ) ( 1 1 u2 u2 u2 u2 ) +* ( v1 v2 a a a ) ( v1 1 a a a a ) +* ( v1 v2 a a a ) ( v1 v2 a a a a ) +* ( v1 v2 a a a ) ( v1 v2 a a a a ) +* ( v1 v2 a a a ) +* +* where a denotes an element of the original matrix which is unchanged, +* vi denotes an element of the vector defining H(i), and ui an element +* of the vector defining G(i). +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO, ONE + PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 ) +* .. +* .. Local Scalars .. + INTEGER I +* .. +* .. External Subroutines .. + EXTERNAL DGEMV, DLARFG, DSCAL +* .. +* .. Intrinsic Functions .. + INTRINSIC MIN +* .. +* .. Executable Statements .. +* +* Quick return if possible +* + IF( M.LE.0 .OR. N.LE.0 ) + $ RETURN +* + IF( M.GE.N ) THEN +* +* Reduce to upper bidiagonal form +* + DO 10 I = 1, NB +* +* Update A(i:m,i) +* + CALL DGEMV( 'No transpose', M-I+1, I-1, -ONE, A( I, 1 ), + $ LDA, Y( I, 1 ), LDY, ONE, A( I, I ), 1 ) + CALL DGEMV( 'No transpose', M-I+1, I-1, -ONE, X( I, 1 ), + $ LDX, A( 1, I ), 1, ONE, A( I, I ), 1 ) +* +* Generate reflection Q(i) to annihilate A(i+1:m,i) +* + CALL DLARFG( M-I+1, A( I, I ), A( MIN( I+1, M ), I ), 1, + $ TAUQ( I ) ) + D( I ) = A( I, I ) + IF( I.LT.N ) THEN + A( I, I ) = ONE +* +* Compute Y(i+1:n,i) +* + CALL DGEMV( 'Transpose', M-I+1, N-I, ONE, A( I, I+1 ), + $ LDA, A( I, I ), 1, ZERO, Y( I+1, I ), 1 ) + CALL DGEMV( 'Transpose', M-I+1, I-1, ONE, A( I, 1 ), LDA, + $ A( I, I ), 1, ZERO, Y( 1, I ), 1 ) + CALL DGEMV( 'No transpose', N-I, I-1, -ONE, Y( I+1, 1 ), + $ LDY, Y( 1, I ), 1, ONE, Y( I+1, I ), 1 ) + CALL DGEMV( 'Transpose', M-I+1, I-1, ONE, X( I, 1 ), LDX, + $ A( I, I ), 1, ZERO, Y( 1, I ), 1 ) + CALL DGEMV( 'Transpose', I-1, N-I, -ONE, A( 1, I+1 ), + $ LDA, Y( 1, I ), 1, ONE, Y( I+1, I ), 1 ) + CALL DSCAL( N-I, TAUQ( I ), Y( I+1, I ), 1 ) +* +* Update A(i,i+1:n) +* + CALL DGEMV( 'No transpose', N-I, I, -ONE, Y( I+1, 1 ), + $ LDY, A( I, 1 ), LDA, ONE, A( I, I+1 ), LDA ) + CALL DGEMV( 'Transpose', I-1, N-I, -ONE, A( 1, I+1 ), + $ LDA, X( I, 1 ), LDX, ONE, A( I, I+1 ), LDA ) +* +* Generate reflection P(i) to annihilate A(i,i+2:n) +* + CALL DLARFG( N-I, A( I, I+1 ), A( I, MIN( I+2, N ) ), + $ LDA, TAUP( I ) ) + E( I ) = A( I, I+1 ) + A( I, I+1 ) = ONE +* +* Compute X(i+1:m,i) +* + CALL DGEMV( 'No transpose', M-I, N-I, ONE, A( I+1, I+1 ), + $ LDA, A( I, I+1 ), LDA, ZERO, X( I+1, I ), 1 ) + CALL DGEMV( 'Transpose', N-I, I, ONE, Y( I+1, 1 ), LDY, + $ A( I, I+1 ), LDA, ZERO, X( 1, I ), 1 ) + CALL DGEMV( 'No transpose', M-I, I, -ONE, A( I+1, 1 ), + $ LDA, X( 1, I ), 1, ONE, X( I+1, I ), 1 ) + CALL DGEMV( 'No transpose', I-1, N-I, ONE, A( 1, I+1 ), + $ LDA, A( I, I+1 ), LDA, ZERO, X( 1, I ), 1 ) + CALL DGEMV( 'No transpose', M-I, I-1, -ONE, X( I+1, 1 ), + $ LDX, X( 1, I ), 1, ONE, X( I+1, I ), 1 ) + CALL DSCAL( M-I, TAUP( I ), X( I+1, I ), 1 ) + END IF + 10 CONTINUE + ELSE +* +* Reduce to lower bidiagonal form +* + DO 20 I = 1, NB +* +* Update A(i,i:n) +* + CALL DGEMV( 'No transpose', N-I+1, I-1, -ONE, Y( I, 1 ), + $ LDY, A( I, 1 ), LDA, ONE, A( I, I ), LDA ) + CALL DGEMV( 'Transpose', I-1, N-I+1, -ONE, A( 1, I ), LDA, + $ X( I, 1 ), LDX, ONE, A( I, I ), LDA ) +* +* Generate reflection P(i) to annihilate A(i,i+1:n) +* + CALL DLARFG( N-I+1, A( I, I ), A( I, MIN( I+1, N ) ), LDA, + $ TAUP( I ) ) + D( I ) = A( I, I ) + IF( I.LT.M ) THEN + A( I, I ) = ONE +* +* Compute X(i+1:m,i) +* + CALL DGEMV( 'No transpose', M-I, N-I+1, ONE, A( I+1, I ), + $ LDA, A( I, I ), LDA, ZERO, X( I+1, I ), 1 ) + CALL DGEMV( 'Transpose', N-I+1, I-1, ONE, Y( I, 1 ), LDY, + $ A( I, I ), LDA, ZERO, X( 1, I ), 1 ) + CALL DGEMV( 'No transpose', M-I, I-1, -ONE, A( I+1, 1 ), + $ LDA, X( 1, I ), 1, ONE, X( I+1, I ), 1 ) + CALL DGEMV( 'No transpose', I-1, N-I+1, ONE, A( 1, I ), + $ LDA, A( I, I ), LDA, ZERO, X( 1, I ), 1 ) + CALL DGEMV( 'No transpose', M-I, I-1, -ONE, X( I+1, 1 ), + $ LDX, X( 1, I ), 1, ONE, X( I+1, I ), 1 ) + CALL DSCAL( M-I, TAUP( I ), X( I+1, I ), 1 ) +* +* Update A(i+1:m,i) +* + CALL DGEMV( 'No transpose', M-I, I-1, -ONE, A( I+1, 1 ), + $ LDA, Y( I, 1 ), LDY, ONE, A( I+1, I ), 1 ) + CALL DGEMV( 'No transpose', M-I, I, -ONE, X( I+1, 1 ), + $ LDX, A( 1, I ), 1, ONE, A( I+1, I ), 1 ) +* +* Generate reflection Q(i) to annihilate A(i+2:m,i) +* + CALL DLARFG( M-I, A( I+1, I ), A( MIN( I+2, M ), I ), 1, + $ TAUQ( I ) ) + E( I ) = A( I+1, I ) + A( I+1, I ) = ONE +* +* Compute Y(i+1:n,i) +* + CALL DGEMV( 'Transpose', M-I, N-I, ONE, A( I+1, I+1 ), + $ LDA, A( I+1, I ), 1, ZERO, Y( I+1, I ), 1 ) + CALL DGEMV( 'Transpose', M-I, I-1, ONE, A( I+1, 1 ), LDA, + $ A( I+1, I ), 1, ZERO, Y( 1, I ), 1 ) + CALL DGEMV( 'No transpose', N-I, I-1, -ONE, Y( I+1, 1 ), + $ LDY, Y( 1, I ), 1, ONE, Y( I+1, I ), 1 ) + CALL DGEMV( 'Transpose', M-I, I, ONE, X( I+1, 1 ), LDX, + $ A( I+1, I ), 1, ZERO, Y( 1, I ), 1 ) + CALL DGEMV( 'Transpose', I, N-I, -ONE, A( 1, I+1 ), LDA, + $ Y( 1, I ), 1, ONE, Y( I+1, I ), 1 ) + CALL DSCAL( N-I, TAUQ( I ), Y( I+1, I ), 1 ) + END IF + 20 CONTINUE + END IF + RETURN +* +* End of DLABRD +* + END diff --git a/ext/lapack/dlacpy.f b/ext/lapack/dlacpy.f new file mode 100755 index 000000000..6820d45fb --- /dev/null +++ b/ext/lapack/dlacpy.f @@ -0,0 +1,88 @@ + SUBROUTINE DLACPY( UPLO, M, N, A, LDA, B, LDB ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* February 29, 1992 +* +* .. Scalar Arguments .. + CHARACTER UPLO + INTEGER LDA, LDB, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), B( LDB, * ) +* .. +* +* Purpose +* ======= +* +* DLACPY copies all or part of a two-dimensional matrix A to another +* matrix B. +* +* Arguments +* ========= +* +* UPLO (input) CHARACTER*1 +* Specifies the part of the matrix A to be copied to B. +* = 'U': Upper triangular part +* = 'L': Lower triangular part +* Otherwise: All of the matrix A +* +* M (input) INTEGER +* The number of rows of the matrix A. M >= 0. +* +* N (input) INTEGER +* The number of columns of the matrix A. N >= 0. +* +* A (input) DOUBLE PRECISION array, dimension (LDA,N) +* The m by n matrix A. If UPLO = 'U', only the upper triangle +* or trapezoid is accessed; if UPLO = 'L', only the lower +* triangle or trapezoid is accessed. +* +* LDA (input) INTEGER +* The leading dimension of the array A. LDA >= max(1,M). +* +* B (output) DOUBLE PRECISION array, dimension (LDB,N) +* On exit, B = A in the locations specified by UPLO. +* +* LDB (input) INTEGER +* The leading dimension of the array B. LDB >= max(1,M). +* +* ===================================================================== +* +* .. Local Scalars .. + INTEGER I, J +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. Intrinsic Functions .. + INTRINSIC MIN +* .. +* .. Executable Statements .. +* + IF( LSAME( UPLO, 'U' ) ) THEN + DO 20 J = 1, N + DO 10 I = 1, MIN( J, M ) + B( I, J ) = A( I, J ) + 10 CONTINUE + 20 CONTINUE + ELSE IF( LSAME( UPLO, 'L' ) ) THEN + DO 40 J = 1, N + DO 30 I = J, M + B( I, J ) = A( I, J ) + 30 CONTINUE + 40 CONTINUE + ELSE + DO 60 J = 1, N + DO 50 I = 1, M + B( I, J ) = A( I, J ) + 50 CONTINUE + 60 CONTINUE + END IF + RETURN +* +* End of DLACPY +* + END diff --git a/ext/lapack/dlamch.f b/ext/lapack/dlamch.f new file mode 100755 index 000000000..e293aa8c7 --- /dev/null +++ b/ext/lapack/dlamch.f @@ -0,0 +1,857 @@ + DOUBLE PRECISION FUNCTION DLAMCH( CMACH ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* October 31, 1992 +* +* .. Scalar Arguments .. + CHARACTER CMACH +* .. +* +* Purpose +* ======= +* +* DLAMCH determines double precision machine parameters. +* +* Arguments +* ========= +* +* CMACH (input) CHARACTER*1 +* Specifies the value to be returned by DLAMCH: +* = 'E' or 'e', DLAMCH := eps +* = 'S' or 's , DLAMCH := sfmin +* = 'B' or 'b', DLAMCH := base +* = 'P' or 'p', DLAMCH := eps*base +* = 'N' or 'n', DLAMCH := t +* = 'R' or 'r', DLAMCH := rnd +* = 'M' or 'm', DLAMCH := emin +* = 'U' or 'u', DLAMCH := rmin +* = 'L' or 'l', DLAMCH := emax +* = 'O' or 'o', DLAMCH := rmax +* +* where +* +* eps = relative machine precision +* sfmin = safe minimum, such that 1/sfmin does not overflow +* base = base of the machine +* prec = eps*base +* t = number of (base) digits in the mantissa +* rnd = 1.0 when rounding occurs in addition, 0.0 otherwise +* emin = minimum exponent before (gradual) underflow +* rmin = underflow threshold - base**(emin-1) +* emax = largest exponent before overflow +* rmax = overflow threshold - (base**emax)*(1-eps) +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + LOGICAL FIRST, LRND + INTEGER BETA, IMAX, IMIN, IT + DOUBLE PRECISION BASE, EMAX, EMIN, EPS, PREC, RMACH, RMAX, RMIN, + $ RND, SFMIN, SMALL, T +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. External Subroutines .. + EXTERNAL DLAMC2 +* .. +* .. Save statement .. + SAVE FIRST, EPS, SFMIN, BASE, T, RND, EMIN, RMIN, + $ EMAX, RMAX, PREC +* .. +* .. Data statements .. + DATA FIRST / .TRUE. / +* .. +* .. Executable Statements .. +* + IF( FIRST ) THEN + FIRST = .FALSE. + CALL DLAMC2( BETA, IT, LRND, EPS, IMIN, RMIN, IMAX, RMAX ) + BASE = BETA + T = IT + IF( LRND ) THEN + RND = ONE + EPS = ( BASE**( 1-IT ) ) / 2 + ELSE + RND = ZERO + EPS = BASE**( 1-IT ) + END IF + PREC = EPS*BASE + EMIN = IMIN + EMAX = IMAX + SFMIN = RMIN + SMALL = ONE / RMAX + IF( SMALL.GE.SFMIN ) THEN +* +* Use SMALL plus a bit, to avoid the possibility of rounding +* causing overflow when computing 1/sfmin. +* + SFMIN = SMALL*( ONE+EPS ) + END IF + END IF +* + IF( LSAME( CMACH, 'E' ) ) THEN + RMACH = EPS + ELSE IF( LSAME( CMACH, 'S' ) ) THEN + RMACH = SFMIN + ELSE IF( LSAME( CMACH, 'B' ) ) THEN + RMACH = BASE + ELSE IF( LSAME( CMACH, 'P' ) ) THEN + RMACH = PREC + ELSE IF( LSAME( CMACH, 'N' ) ) THEN + RMACH = T + ELSE IF( LSAME( CMACH, 'R' ) ) THEN + RMACH = RND + ELSE IF( LSAME( CMACH, 'M' ) ) THEN + RMACH = EMIN + ELSE IF( LSAME( CMACH, 'U' ) ) THEN + RMACH = RMIN + ELSE IF( LSAME( CMACH, 'L' ) ) THEN + RMACH = EMAX + ELSE IF( LSAME( CMACH, 'O' ) ) THEN + RMACH = RMAX + END IF +* + DLAMCH = RMACH + RETURN +* +* End of DLAMCH +* + END +* +************************************************************************ +* + SUBROUTINE DLAMC1( BETA, T, RND, IEEE1 ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* October 31, 1992 +* +* .. Scalar Arguments .. + LOGICAL IEEE1, RND + INTEGER BETA, T +* .. +* +* Purpose +* ======= +* +* DLAMC1 determines the machine parameters given by BETA, T, RND, and +* IEEE1. +* +* Arguments +* ========= +* +* BETA (output) INTEGER +* The base of the machine. +* +* T (output) INTEGER +* The number of ( BETA ) digits in the mantissa. +* +* RND (output) LOGICAL +* Specifies whether proper rounding ( RND = .TRUE. ) or +* chopping ( RND = .FALSE. ) occurs in addition. This may not +* be a reliable guide to the way in which the machine performs +* its arithmetic. +* +* IEEE1 (output) LOGICAL +* Specifies whether rounding appears to be done in the IEEE +* 'round to nearest' style. +* +* Further Details +* =============== +* +* The routine is based on the routine ENVRON by Malcolm and +* incorporates suggestions by Gentleman and Marovich. See +* +* Malcolm M. A. (1972) Algorithms to reveal properties of +* floating-point arithmetic. Comms. of the ACM, 15, 949-951. +* +* Gentleman W. M. and Marovich S. B. (1974) More on algorithms +* that reveal properties of floating point arithmetic units. +* Comms. of the ACM, 17, 276-277. +* +* ===================================================================== +* +* .. Local Scalars .. + LOGICAL FIRST, LIEEE1, LRND + INTEGER LBETA, LT + DOUBLE PRECISION A, B, C, F, ONE, QTR, SAVEC, T1, T2 +* .. +* .. External Functions .. + DOUBLE PRECISION DLAMC3 + EXTERNAL DLAMC3 +* .. +* .. Save statement .. + SAVE FIRST, LIEEE1, LBETA, LRND, LT +* .. +* .. Data statements .. + DATA FIRST / .TRUE. / +* .. +* .. Executable Statements .. +* + IF( FIRST ) THEN + FIRST = .FALSE. + ONE = 1 +* +* LBETA, LIEEE1, LT and LRND are the local values of BETA, +* IEEE1, T and RND. +* +* Throughout this routine we use the function DLAMC3 to ensure +* that relevant values are stored and not held in registers, or +* are not affected by optimizers. +* +* Compute a = 2.0**m with the smallest positive integer m such +* that +* +* fl( a + 1.0 ) = a. +* + A = 1 + C = 1 +* +*+ WHILE( C.EQ.ONE )LOOP + 10 CONTINUE + IF( C.EQ.ONE ) THEN + A = 2*A + C = DLAMC3( A, ONE ) + C = DLAMC3( C, -A ) + GO TO 10 + END IF +*+ END WHILE +* +* Now compute b = 2.0**m with the smallest positive integer m +* such that +* +* fl( a + b ) .gt. a. +* + B = 1 + C = DLAMC3( A, B ) +* +*+ WHILE( C.EQ.A )LOOP + 20 CONTINUE + IF( C.EQ.A ) THEN + B = 2*B + C = DLAMC3( A, B ) + GO TO 20 + END IF +*+ END WHILE +* +* Now compute the base. a and c are neighbouring floating point +* numbers in the interval ( beta**t, beta**( t + 1 ) ) and so +* their difference is beta. Adding 0.25 to c is to ensure that it +* is truncated to beta and not ( beta - 1 ). +* + QTR = ONE / 4 + SAVEC = C + C = DLAMC3( C, -A ) + LBETA = C + QTR +* +* Now determine whether rounding or chopping occurs, by adding a +* bit less than beta/2 and a bit more than beta/2 to a. +* + B = LBETA + F = DLAMC3( B / 2, -B / 100 ) + C = DLAMC3( F, A ) + IF( C.EQ.A ) THEN + LRND = .TRUE. + ELSE + LRND = .FALSE. + END IF + F = DLAMC3( B / 2, B / 100 ) + C = DLAMC3( F, A ) + IF( ( LRND ) .AND. ( C.EQ.A ) ) + $ LRND = .FALSE. +* +* Try and decide whether rounding is done in the IEEE 'round to +* nearest' style. B/2 is half a unit in the last place of the two +* numbers A and SAVEC. Furthermore, A is even, i.e. has last bit +* zero, and SAVEC is odd. Thus adding B/2 to A should not change +* A, but adding B/2 to SAVEC should change SAVEC. +* + T1 = DLAMC3( B / 2, A ) + T2 = DLAMC3( B / 2, SAVEC ) + LIEEE1 = ( T1.EQ.A ) .AND. ( T2.GT.SAVEC ) .AND. LRND +* +* Now find the mantissa, t. It should be the integer part of +* log to the base beta of a, however it is safer to determine t +* by powering. So we find t as the smallest positive integer for +* which +* +* fl( beta**t + 1.0 ) = 1.0. +* + LT = 0 + A = 1 + C = 1 +* +*+ WHILE( C.EQ.ONE )LOOP + 30 CONTINUE + IF( C.EQ.ONE ) THEN + LT = LT + 1 + A = A*LBETA + C = DLAMC3( A, ONE ) + C = DLAMC3( C, -A ) + GO TO 30 + END IF +*+ END WHILE +* + END IF +* + BETA = LBETA + T = LT + RND = LRND + IEEE1 = LIEEE1 + RETURN +* +* End of DLAMC1 +* + END +* +************************************************************************ +* + SUBROUTINE DLAMC2( BETA, T, RND, EPS, EMIN, RMIN, EMAX, RMAX ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* October 31, 1992 +* +* .. Scalar Arguments .. + LOGICAL RND + INTEGER BETA, EMAX, EMIN, T + DOUBLE PRECISION EPS, RMAX, RMIN +* .. +* +* Purpose +* ======= +* +* DLAMC2 determines the machine parameters specified in its argument +* list. +* +* Arguments +* ========= +* +* BETA (output) INTEGER +* The base of the machine. +* +* T (output) INTEGER +* The number of ( BETA ) digits in the mantissa. +* +* RND (output) LOGICAL +* Specifies whether proper rounding ( RND = .TRUE. ) or +* chopping ( RND = .FALSE. ) occurs in addition. This may not +* be a reliable guide to the way in which the machine performs +* its arithmetic. +* +* EPS (output) DOUBLE PRECISION +* The smallest positive number such that +* +* fl( 1.0 - EPS ) .LT. 1.0, +* +* where fl denotes the computed value. +* +* EMIN (output) INTEGER +* The minimum exponent before (gradual) underflow occurs. +* +* RMIN (output) DOUBLE PRECISION +* The smallest normalized number for the machine, given by +* BASE**( EMIN - 1 ), where BASE is the floating point value +* of BETA. +* +* EMAX (output) INTEGER +* The maximum exponent before overflow occurs. +* +* RMAX (output) DOUBLE PRECISION +* The largest positive number for the machine, given by +* BASE**EMAX * ( 1 - EPS ), where BASE is the floating point +* value of BETA. +* +* Further Details +* =============== +* +* The computation of EPS is based on a routine PARANOIA by +* W. Kahan of the University of California at Berkeley. +* +* ===================================================================== +* +* .. Local Scalars .. + LOGICAL FIRST, IEEE, IWARN, LIEEE1, LRND + INTEGER GNMIN, GPMIN, I, LBETA, LEMAX, LEMIN, LT, + $ NGNMIN, NGPMIN + DOUBLE PRECISION A, B, C, HALF, LEPS, LRMAX, LRMIN, ONE, RBASE, + $ SIXTH, SMALL, THIRD, TWO, ZERO +* .. +* .. External Functions .. + DOUBLE PRECISION DLAMC3 + EXTERNAL DLAMC3 +* .. +* .. External Subroutines .. + EXTERNAL DLAMC1, DLAMC4, DLAMC5 +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, MAX, MIN +* .. +* .. Save statement .. + SAVE FIRST, IWARN, LBETA, LEMAX, LEMIN, LEPS, LRMAX, + $ LRMIN, LT +* .. +* .. Data statements .. + DATA FIRST / .TRUE. / , IWARN / .FALSE. / +* .. +* .. Executable Statements .. +* + IF( FIRST ) THEN + FIRST = .FALSE. + ZERO = 0 + ONE = 1 + TWO = 2 +* +* LBETA, LT, LRND, LEPS, LEMIN and LRMIN are the local values of +* BETA, T, RND, EPS, EMIN and RMIN. +* +* Throughout this routine we use the function DLAMC3 to ensure +* that relevant values are stored and not held in registers, or +* are not affected by optimizers. +* +* DLAMC1 returns the parameters LBETA, LT, LRND and LIEEE1. +* + CALL DLAMC1( LBETA, LT, LRND, LIEEE1 ) +* +* Start to find EPS. +* + B = LBETA + A = B**( -LT ) + LEPS = A +* +* Try some tricks to see whether or not this is the correct EPS. +* + B = TWO / 3 + HALF = ONE / 2 + SIXTH = DLAMC3( B, -HALF ) + THIRD = DLAMC3( SIXTH, SIXTH ) + B = DLAMC3( THIRD, -HALF ) + B = DLAMC3( B, SIXTH ) + B = ABS( B ) + IF( B.LT.LEPS ) + $ B = LEPS +* + LEPS = 1 +* +*+ WHILE( ( LEPS.GT.B ).AND.( B.GT.ZERO ) )LOOP + 10 CONTINUE + IF( ( LEPS.GT.B ) .AND. ( B.GT.ZERO ) ) THEN + LEPS = B + C = DLAMC3( HALF*LEPS, ( TWO**5 )*( LEPS**2 ) ) + C = DLAMC3( HALF, -C ) + B = DLAMC3( HALF, C ) + C = DLAMC3( HALF, -B ) + B = DLAMC3( HALF, C ) + GO TO 10 + END IF +*+ END WHILE +* + IF( A.LT.LEPS ) + $ LEPS = A +* +* Computation of EPS complete. +* +* Now find EMIN. Let A = + or - 1, and + or - (1 + BASE**(-3)). +* Keep dividing A by BETA until (gradual) underflow occurs. This +* is detected when we cannot recover the previous A. +* + RBASE = ONE / LBETA + SMALL = ONE + DO 20 I = 1, 3 + SMALL = DLAMC3( SMALL*RBASE, ZERO ) + 20 CONTINUE + A = DLAMC3( ONE, SMALL ) + CALL DLAMC4( NGPMIN, ONE, LBETA ) + CALL DLAMC4( NGNMIN, -ONE, LBETA ) + CALL DLAMC4( GPMIN, A, LBETA ) + CALL DLAMC4( GNMIN, -A, LBETA ) + IEEE = .FALSE. +* + IF( ( NGPMIN.EQ.NGNMIN ) .AND. ( GPMIN.EQ.GNMIN ) ) THEN + IF( NGPMIN.EQ.GPMIN ) THEN + LEMIN = NGPMIN +* ( Non twos-complement machines, no gradual underflow; +* e.g., VAX ) + ELSE IF( ( GPMIN-NGPMIN ).EQ.3 ) THEN + LEMIN = NGPMIN - 1 + LT + IEEE = .TRUE. +* ( Non twos-complement machines, with gradual underflow; +* e.g., IEEE standard followers ) + ELSE + LEMIN = MIN( NGPMIN, GPMIN ) +* ( A guess; no known machine ) + IWARN = .TRUE. + END IF +* + ELSE IF( ( NGPMIN.EQ.GPMIN ) .AND. ( NGNMIN.EQ.GNMIN ) ) THEN + IF( ABS( NGPMIN-NGNMIN ).EQ.1 ) THEN + LEMIN = MAX( NGPMIN, NGNMIN ) +* ( Twos-complement machines, no gradual underflow; +* e.g., CYBER 205 ) + ELSE + LEMIN = MIN( NGPMIN, NGNMIN ) +* ( A guess; no known machine ) + IWARN = .TRUE. + END IF +* + ELSE IF( ( ABS( NGPMIN-NGNMIN ).EQ.1 ) .AND. + $ ( GPMIN.EQ.GNMIN ) ) THEN + IF( ( GPMIN-MIN( NGPMIN, NGNMIN ) ).EQ.3 ) THEN + LEMIN = MAX( NGPMIN, NGNMIN ) - 1 + LT +* ( Twos-complement machines with gradual underflow; +* no known machine ) + ELSE + LEMIN = MIN( NGPMIN, NGNMIN ) +* ( A guess; no known machine ) + IWARN = .TRUE. + END IF +* + ELSE + LEMIN = MIN( NGPMIN, NGNMIN, GPMIN, GNMIN ) +* ( A guess; no known machine ) + IWARN = .TRUE. + END IF +*** +* Comment out this if block if EMIN is ok + IF( IWARN ) THEN + FIRST = .TRUE. + WRITE( 6, FMT = 9999 )LEMIN + END IF +*** +* +* Assume IEEE arithmetic if we found denormalised numbers above, +* or if arithmetic seems to round in the IEEE style, determined +* in routine DLAMC1. A true IEEE machine should have both things +* true; however, faulty machines may have one or the other. +* + IEEE = IEEE .OR. LIEEE1 +* +* Compute RMIN by successive division by BETA. We could compute +* RMIN as BASE**( EMIN - 1 ), but some machines underflow during +* this computation. +* + LRMIN = 1 + DO 30 I = 1, 1 - LEMIN + LRMIN = DLAMC3( LRMIN*RBASE, ZERO ) + 30 CONTINUE +* +* Finally, call DLAMC5 to compute EMAX and RMAX. +* + CALL DLAMC5( LBETA, LT, LEMIN, IEEE, LEMAX, LRMAX ) + END IF +* + BETA = LBETA + T = LT + RND = LRND + EPS = LEPS + EMIN = LEMIN + RMIN = LRMIN + EMAX = LEMAX + RMAX = LRMAX +* + RETURN +* + 9999 FORMAT( / / ' WARNING. The value EMIN may be incorrect:-', + $ ' EMIN = ', I8, / + $ ' If, after inspection, the value EMIN looks', + $ ' acceptable please comment out ', + $ / ' the IF block as marked within the code of routine', + $ ' DLAMC2,', / ' otherwise supply EMIN explicitly.', / ) +* +* End of DLAMC2 +* + END +* +************************************************************************ +* + DOUBLE PRECISION FUNCTION DLAMC3( A, B ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* October 31, 1992 +* +* .. Scalar Arguments .. + DOUBLE PRECISION A, B +* .. +* +* Purpose +* ======= +* +* DLAMC3 is intended to force A and B to be stored prior to doing +* the addition of A and B , for use in situations where optimizers +* might hold one of these in a register. +* +* Arguments +* ========= +* +* A, B (input) DOUBLE PRECISION +* The values A and B. +* +* ===================================================================== +* +* .. Executable Statements .. +* + DLAMC3 = A + B +* + RETURN +* +* End of DLAMC3 +* + END +* +************************************************************************ +* + SUBROUTINE DLAMC4( EMIN, START, BASE ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* October 31, 1992 +* +* .. Scalar Arguments .. + INTEGER BASE, EMIN + DOUBLE PRECISION START +* .. +* +* Purpose +* ======= +* +* DLAMC4 is a service routine for DLAMC2. +* +* Arguments +* ========= +* +* EMIN (output) EMIN +* The minimum exponent before (gradual) underflow, computed by +* setting A = START and dividing by BASE until the previous A +* can not be recovered. +* +* START (input) DOUBLE PRECISION +* The starting point for determining EMIN. +* +* BASE (input) INTEGER +* The base of the machine. +* +* ===================================================================== +* +* .. Local Scalars .. + INTEGER I + DOUBLE PRECISION A, B1, B2, C1, C2, D1, D2, ONE, RBASE, ZERO +* .. +* .. External Functions .. + DOUBLE PRECISION DLAMC3 + EXTERNAL DLAMC3 +* .. +* .. Executable Statements .. +* + A = START + ONE = 1 + RBASE = ONE / BASE + ZERO = 0 + EMIN = 1 + B1 = DLAMC3( A*RBASE, ZERO ) + C1 = A + C2 = A + D1 = A + D2 = A +*+ WHILE( ( C1.EQ.A ).AND.( C2.EQ.A ).AND. +* $ ( D1.EQ.A ).AND.( D2.EQ.A ) )LOOP + 10 CONTINUE + IF( ( C1.EQ.A ) .AND. ( C2.EQ.A ) .AND. ( D1.EQ.A ) .AND. + $ ( D2.EQ.A ) ) THEN + EMIN = EMIN - 1 + A = B1 + B1 = DLAMC3( A / BASE, ZERO ) + C1 = DLAMC3( B1*BASE, ZERO ) + D1 = ZERO + DO 20 I = 1, BASE + D1 = D1 + B1 + 20 CONTINUE + B2 = DLAMC3( A*RBASE, ZERO ) + C2 = DLAMC3( B2 / RBASE, ZERO ) + D2 = ZERO + DO 30 I = 1, BASE + D2 = D2 + B2 + 30 CONTINUE + GO TO 10 + END IF +*+ END WHILE +* + RETURN +* +* End of DLAMC4 +* + END +* +************************************************************************ +* + SUBROUTINE DLAMC5( BETA, P, EMIN, IEEE, EMAX, RMAX ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* October 31, 1992 +* +* .. Scalar Arguments .. + LOGICAL IEEE + INTEGER BETA, EMAX, EMIN, P + DOUBLE PRECISION RMAX +* .. +* +* Purpose +* ======= +* +* DLAMC5 attempts to compute RMAX, the largest machine floating-point +* number, without overflow. It assumes that EMAX + abs(EMIN) sum +* approximately to a power of 2. It will fail on machines where this +* assumption does not hold, for example, the Cyber 205 (EMIN = -28625, +* EMAX = 28718). It will also fail if the value supplied for EMIN is +* too large (i.e. too close to zero), probably with overflow. +* +* Arguments +* ========= +* +* BETA (input) INTEGER +* The base of floating-point arithmetic. +* +* P (input) INTEGER +* The number of base BETA digits in the mantissa of a +* floating-point value. +* +* EMIN (input) INTEGER +* The minimum exponent before (gradual) underflow. +* +* IEEE (input) LOGICAL +* A logical flag specifying whether or not the arithmetic +* system is thought to comply with the IEEE standard. +* +* EMAX (output) INTEGER +* The largest exponent before overflow +* +* RMAX (output) DOUBLE PRECISION +* The largest machine floating-point number. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO, ONE + PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 ) +* .. +* .. Local Scalars .. + INTEGER EXBITS, EXPSUM, I, LEXP, NBITS, TRY, UEXP + DOUBLE PRECISION OLDY, RECBAS, Y, Z +* .. +* .. External Functions .. + DOUBLE PRECISION DLAMC3 + EXTERNAL DLAMC3 +* .. +* .. Intrinsic Functions .. + INTRINSIC MOD +* .. +* .. Executable Statements .. +* +* First compute LEXP and UEXP, two powers of 2 that bound +* abs(EMIN). We then assume that EMAX + abs(EMIN) will sum +* approximately to the bound that is closest to abs(EMIN). +* (EMAX is the exponent of the required number RMAX). +* + LEXP = 1 + EXBITS = 1 + 10 CONTINUE + TRY = LEXP*2 + IF( TRY.LE.( -EMIN ) ) THEN + LEXP = TRY + EXBITS = EXBITS + 1 + GO TO 10 + END IF + IF( LEXP.EQ.-EMIN ) THEN + UEXP = LEXP + ELSE + UEXP = TRY + EXBITS = EXBITS + 1 + END IF +* +* Now -LEXP is less than or equal to EMIN, and -UEXP is greater +* than or equal to EMIN. EXBITS is the number of bits needed to +* store the exponent. +* + IF( ( UEXP+EMIN ).GT.( -LEXP-EMIN ) ) THEN + EXPSUM = 2*LEXP + ELSE + EXPSUM = 2*UEXP + END IF +* +* EXPSUM is the exponent range, approximately equal to +* EMAX - EMIN + 1 . +* + EMAX = EXPSUM + EMIN - 1 + NBITS = 1 + EXBITS + P +* +* NBITS is the total number of bits needed to store a +* floating-point number. +* + IF( ( MOD( NBITS, 2 ).EQ.1 ) .AND. ( BETA.EQ.2 ) ) THEN +* +* Either there are an odd number of bits used to store a +* floating-point number, which is unlikely, or some bits are +* not used in the representation of numbers, which is possible, +* (e.g. Cray machines) or the mantissa has an implicit bit, +* (e.g. IEEE machines, Dec Vax machines), which is perhaps the +* most likely. We have to assume the last alternative. +* If this is true, then we need to reduce EMAX by one because +* there must be some way of representing zero in an implicit-bit +* system. On machines like Cray, we are reducing EMAX by one +* unnecessarily. +* + EMAX = EMAX - 1 + END IF +* + IF( IEEE ) THEN +* +* Assume we are on an IEEE machine which reserves one exponent +* for infinity and NaN. +* + EMAX = EMAX - 1 + END IF +* +* Now create RMAX, the largest machine number, which should +* be equal to (1.0 - BETA**(-P)) * BETA**EMAX . +* +* First compute 1.0 - BETA**(-P), being careful that the +* result is less than 1.0 . +* + RECBAS = ONE / BETA + Z = BETA - ONE + Y = ZERO + DO 20 I = 1, P + Z = Z*RECBAS + IF( Y.LT.ONE ) + $ OLDY = Y + Y = DLAMC3( Y, Z ) + 20 CONTINUE + IF( Y.GE.ONE ) + $ Y = OLDY +* +* Now multiply by BETA**EMAX to get RMAX. +* + DO 30 I = 1, EMAX + Y = DLAMC3( Y*BETA, ZERO ) + 30 CONTINUE +* + RMAX = Y + RETURN +* +* End of DLAMC5 +* + END diff --git a/ext/lapack/dlange.f b/ext/lapack/dlange.f new file mode 100755 index 000000000..0737f03ea --- /dev/null +++ b/ext/lapack/dlange.f @@ -0,0 +1,145 @@ + DOUBLE PRECISION FUNCTION DLANGE( NORM, M, N, A, LDA, WORK ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* October 31, 1992 +* +* .. Scalar Arguments .. + CHARACTER NORM + INTEGER LDA, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), WORK( * ) +* .. +* +* Purpose +* ======= +* +* DLANGE returns the value of the one norm, or the Frobenius norm, or +* the infinity norm, or the element of largest absolute value of a +* real matrix A. +* +* Description +* =========== +* +* DLANGE returns the value +* +* DLANGE = ( max(abs(A(i,j))), NORM = 'M' or 'm' +* ( +* ( norm1(A), NORM = '1', 'O' or 'o' +* ( +* ( normI(A), NORM = 'I' or 'i' +* ( +* ( normF(A), NORM = 'F', 'f', 'E' or 'e' +* +* where norm1 denotes the one norm of a matrix (maximum column sum), +* normI denotes the infinity norm of a matrix (maximum row sum) and +* normF denotes the Frobenius norm of a matrix (square root of sum of +* squares). Note that max(abs(A(i,j))) is not a matrix norm. +* +* Arguments +* ========= +* +* NORM (input) CHARACTER*1 +* Specifies the value to be returned in DLANGE as described +* above. +* +* M (input) INTEGER +* The number of rows of the matrix A. M >= 0. When M = 0, +* DLANGE is set to zero. +* +* N (input) INTEGER +* The number of columns of the matrix A. N >= 0. When N = 0, +* DLANGE is set to zero. +* +* A (input) DOUBLE PRECISION array, dimension (LDA,N) +* The m by n matrix A. +* +* LDA (input) INTEGER +* The leading dimension of the array A. LDA >= max(M,1). +* +* WORK (workspace) DOUBLE PRECISION array, dimension (LWORK), +* where LWORK >= M when NORM = 'I'; otherwise, WORK is not +* referenced. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER I, J + DOUBLE PRECISION SCALE, SUM, VALUE +* .. +* .. External Subroutines .. + EXTERNAL DLASSQ +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, MAX, MIN, SQRT +* .. +* .. Executable Statements .. +* + IF( MIN( M, N ).EQ.0 ) THEN + VALUE = ZERO + ELSE IF( LSAME( NORM, 'M' ) ) THEN +* +* Find max(abs(A(i,j))). +* + VALUE = ZERO + DO 20 J = 1, N + DO 10 I = 1, M + VALUE = MAX( VALUE, ABS( A( I, J ) ) ) + 10 CONTINUE + 20 CONTINUE + ELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN +* +* Find norm1(A). +* + VALUE = ZERO + DO 40 J = 1, N + SUM = ZERO + DO 30 I = 1, M + SUM = SUM + ABS( A( I, J ) ) + 30 CONTINUE + VALUE = MAX( VALUE, SUM ) + 40 CONTINUE + ELSE IF( LSAME( NORM, 'I' ) ) THEN +* +* Find normI(A). +* + DO 50 I = 1, M + WORK( I ) = ZERO + 50 CONTINUE + DO 70 J = 1, N + DO 60 I = 1, M + WORK( I ) = WORK( I ) + ABS( A( I, J ) ) + 60 CONTINUE + 70 CONTINUE + VALUE = ZERO + DO 80 I = 1, M + VALUE = MAX( VALUE, WORK( I ) ) + 80 CONTINUE + ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN +* +* Find normF(A). +* + SCALE = ZERO + SUM = ONE + DO 90 J = 1, N + CALL DLASSQ( M, A( 1, J ), 1, SCALE, SUM ) + 90 CONTINUE + VALUE = SCALE*SQRT( SUM ) + END IF +* + DLANGE = VALUE + RETURN +* +* End of DLANGE +* + END diff --git a/ext/lapack/dlapy2.f b/ext/lapack/dlapy2.f new file mode 100755 index 000000000..d38196132 --- /dev/null +++ b/ext/lapack/dlapy2.f @@ -0,0 +1,54 @@ + DOUBLE PRECISION FUNCTION DLAPY2( X, Y ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* October 31, 1992 +* +* .. Scalar Arguments .. + DOUBLE PRECISION X, Y +* .. +* +* Purpose +* ======= +* +* DLAPY2 returns sqrt(x**2+y**2), taking care not to cause unnecessary +* overflow. +* +* Arguments +* ========= +* +* X (input) DOUBLE PRECISION +* Y (input) DOUBLE PRECISION +* X and Y specify the values x and y. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D0 ) + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D0 ) +* .. +* .. Local Scalars .. + DOUBLE PRECISION W, XABS, YABS, Z +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, MAX, MIN, SQRT +* .. +* .. Executable Statements .. +* + XABS = ABS( X ) + YABS = ABS( Y ) + W = MAX( XABS, YABS ) + Z = MIN( XABS, YABS ) + IF( Z.EQ.ZERO ) THEN + DLAPY2 = W + ELSE + DLAPY2 = W*SQRT( ONE+( Z / W )**2 ) + END IF + RETURN +* +* End of DLAPY2 +* + END diff --git a/ext/lapack/dlarf.f b/ext/lapack/dlarf.f new file mode 100755 index 000000000..1bb357f9b --- /dev/null +++ b/ext/lapack/dlarf.f @@ -0,0 +1,116 @@ + SUBROUTINE DLARF( SIDE, M, N, V, INCV, TAU, C, LDC, WORK ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* February 29, 1992 +* +* .. Scalar Arguments .. + CHARACTER SIDE + INTEGER INCV, LDC, M, N + DOUBLE PRECISION TAU +* .. +* .. Array Arguments .. + DOUBLE PRECISION C( LDC, * ), V( * ), WORK( * ) +* .. +* +* Purpose +* ======= +* +* DLARF applies a real elementary reflector H to a real m by n matrix +* C, from either the left or the right. H is represented in the form +* +* H = I - tau * v * v' +* +* where tau is a real scalar and v is a real vector. +* +* If tau = 0, then H is taken to be the unit matrix. +* +* Arguments +* ========= +* +* SIDE (input) CHARACTER*1 +* = 'L': form H * C +* = 'R': form C * H +* +* M (input) INTEGER +* The number of rows of the matrix C. +* +* N (input) INTEGER +* The number of columns of the matrix C. +* +* V (input) DOUBLE PRECISION array, dimension +* (1 + (M-1)*abs(INCV)) if SIDE = 'L' +* or (1 + (N-1)*abs(INCV)) if SIDE = 'R' +* The vector v in the representation of H. V is not used if +* TAU = 0. +* +* INCV (input) INTEGER +* The increment between elements of v. INCV <> 0. +* +* TAU (input) DOUBLE PRECISION +* The value tau in the representation of H. +* +* C (input/output) DOUBLE PRECISION array, dimension (LDC,N) +* On entry, the m by n matrix C. +* On exit, C is overwritten by the matrix H * C if SIDE = 'L', +* or C * H if SIDE = 'R'. +* +* LDC (input) INTEGER +* The leading dimension of the array C. LDC >= max(1,M). +* +* WORK (workspace) DOUBLE PRECISION array, dimension +* (N) if SIDE = 'L' +* or (M) if SIDE = 'R' +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. External Subroutines .. + EXTERNAL DGEMV, DGER +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. Executable Statements .. +* + IF( LSAME( SIDE, 'L' ) ) THEN +* +* Form H * C +* + IF( TAU.NE.ZERO ) THEN +* +* w := C' * v +* + CALL DGEMV( 'Transpose', M, N, ONE, C, LDC, V, INCV, ZERO, + $ WORK, 1 ) +* +* C := C - v * w' +* + CALL DGER( M, N, -TAU, V, INCV, WORK, 1, C, LDC ) + END IF + ELSE +* +* Form C * H +* + IF( TAU.NE.ZERO ) THEN +* +* w := C * v +* + CALL DGEMV( 'No transpose', M, N, ONE, C, LDC, V, INCV, + $ ZERO, WORK, 1 ) +* +* C := C - w * v' +* + CALL DGER( M, N, -TAU, WORK, 1, V, INCV, C, LDC ) + END IF + END IF + RETURN +* +* End of DLARF +* + END diff --git a/ext/lapack/dlarfb.f b/ext/lapack/dlarfb.f new file mode 100755 index 000000000..4e4f18600 --- /dev/null +++ b/ext/lapack/dlarfb.f @@ -0,0 +1,588 @@ + SUBROUTINE DLARFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, V, LDV, + $ T, LDT, C, LDC, WORK, LDWORK ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* February 29, 1992 +* +* .. Scalar Arguments .. + CHARACTER DIRECT, SIDE, STOREV, TRANS + INTEGER K, LDC, LDT, LDV, LDWORK, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION C( LDC, * ), T( LDT, * ), V( LDV, * ), + $ WORK( LDWORK, * ) +* .. +* +* Purpose +* ======= +* +* DLARFB applies a real block reflector H or its transpose H' to a +* real m by n matrix C, from either the left or the right. +* +* Arguments +* ========= +* +* SIDE (input) CHARACTER*1 +* = 'L': apply H or H' from the Left +* = 'R': apply H or H' from the Right +* +* TRANS (input) CHARACTER*1 +* = 'N': apply H (No transpose) +* = 'T': apply H' (Transpose) +* +* DIRECT (input) CHARACTER*1 +* Indicates how H is formed from a product of elementary +* reflectors +* = 'F': H = H(1) H(2) . . . H(k) (Forward) +* = 'B': H = H(k) . . . H(2) H(1) (Backward) +* +* STOREV (input) CHARACTER*1 +* Indicates how the vectors which define the elementary +* reflectors are stored: +* = 'C': Columnwise +* = 'R': Rowwise +* +* M (input) INTEGER +* The number of rows of the matrix C. +* +* N (input) INTEGER +* The number of columns of the matrix C. +* +* K (input) INTEGER +* The order of the matrix T (= the number of elementary +* reflectors whose product defines the block reflector). +* +* V (input) DOUBLE PRECISION array, dimension +* (LDV,K) if STOREV = 'C' +* (LDV,M) if STOREV = 'R' and SIDE = 'L' +* (LDV,N) if STOREV = 'R' and SIDE = 'R' +* The matrix V. See further details. +* +* LDV (input) INTEGER +* The leading dimension of the array V. +* If STOREV = 'C' and SIDE = 'L', LDV >= max(1,M); +* if STOREV = 'C' and SIDE = 'R', LDV >= max(1,N); +* if STOREV = 'R', LDV >= K. +* +* T (input) DOUBLE PRECISION array, dimension (LDT,K) +* The triangular k by k matrix T in the representation of the +* block reflector. +* +* LDT (input) INTEGER +* The leading dimension of the array T. LDT >= K. +* +* C (input/output) DOUBLE PRECISION array, dimension (LDC,N) +* On entry, the m by n matrix C. +* On exit, C is overwritten by H*C or H'*C or C*H or C*H'. +* +* LDC (input) INTEGER +* The leading dimension of the array C. LDA >= max(1,M). +* +* WORK (workspace) DOUBLE PRECISION array, dimension (LDWORK,K) +* +* LDWORK (input) INTEGER +* The leading dimension of the array WORK. +* If SIDE = 'L', LDWORK >= max(1,N); +* if SIDE = 'R', LDWORK >= max(1,M). +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D+0 ) +* .. +* .. Local Scalars .. + CHARACTER TRANST + INTEGER I, J +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. External Subroutines .. + EXTERNAL DCOPY, DGEMM, DTRMM +* .. +* .. Executable Statements .. +* +* Quick return if possible +* + IF( M.LE.0 .OR. N.LE.0 ) + $ RETURN +* + IF( LSAME( TRANS, 'N' ) ) THEN + TRANST = 'T' + ELSE + TRANST = 'N' + END IF +* + IF( LSAME( STOREV, 'C' ) ) THEN +* + IF( LSAME( DIRECT, 'F' ) ) THEN +* +* Let V = ( V1 ) (first K rows) +* ( V2 ) +* where V1 is unit lower triangular. +* + IF( LSAME( SIDE, 'L' ) ) THEN +* +* Form H * C or H' * C where C = ( C1 ) +* ( C2 ) +* +* W := C' * V = (C1'*V1 + C2'*V2) (stored in WORK) +* +* W := C1' +* + DO 10 J = 1, K + CALL DCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 ) + 10 CONTINUE +* +* W := W * V1 +* + CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', N, + $ K, ONE, V, LDV, WORK, LDWORK ) + IF( M.GT.K ) THEN +* +* W := W + C2'*V2 +* + CALL DGEMM( 'Transpose', 'No transpose', N, K, M-K, + $ ONE, C( K+1, 1 ), LDC, V( K+1, 1 ), LDV, + $ ONE, WORK, LDWORK ) + END IF +* +* W := W * T' or W * T +* + CALL DTRMM( 'Right', 'Upper', TRANST, 'Non-unit', N, K, + $ ONE, T, LDT, WORK, LDWORK ) +* +* C := C - V * W' +* + IF( M.GT.K ) THEN +* +* C2 := C2 - V2 * W' +* + CALL DGEMM( 'No transpose', 'Transpose', M-K, N, K, + $ -ONE, V( K+1, 1 ), LDV, WORK, LDWORK, ONE, + $ C( K+1, 1 ), LDC ) + END IF +* +* W := W * V1' +* + CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', N, K, + $ ONE, V, LDV, WORK, LDWORK ) +* +* C1 := C1 - W' +* + DO 30 J = 1, K + DO 20 I = 1, N + C( J, I ) = C( J, I ) - WORK( I, J ) + 20 CONTINUE + 30 CONTINUE +* + ELSE IF( LSAME( SIDE, 'R' ) ) THEN +* +* Form C * H or C * H' where C = ( C1 C2 ) +* +* W := C * V = (C1*V1 + C2*V2) (stored in WORK) +* +* W := C1 +* + DO 40 J = 1, K + CALL DCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 ) + 40 CONTINUE +* +* W := W * V1 +* + CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', M, + $ K, ONE, V, LDV, WORK, LDWORK ) + IF( N.GT.K ) THEN +* +* W := W + C2 * V2 +* + CALL DGEMM( 'No transpose', 'No transpose', M, K, N-K, + $ ONE, C( 1, K+1 ), LDC, V( K+1, 1 ), LDV, + $ ONE, WORK, LDWORK ) + END IF +* +* W := W * T or W * T' +* + CALL DTRMM( 'Right', 'Upper', TRANS, 'Non-unit', M, K, + $ ONE, T, LDT, WORK, LDWORK ) +* +* C := C - W * V' +* + IF( N.GT.K ) THEN +* +* C2 := C2 - W * V2' +* + CALL DGEMM( 'No transpose', 'Transpose', M, N-K, K, + $ -ONE, WORK, LDWORK, V( K+1, 1 ), LDV, ONE, + $ C( 1, K+1 ), LDC ) + END IF +* +* W := W * V1' +* + CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', M, K, + $ ONE, V, LDV, WORK, LDWORK ) +* +* C1 := C1 - W +* + DO 60 J = 1, K + DO 50 I = 1, M + C( I, J ) = C( I, J ) - WORK( I, J ) + 50 CONTINUE + 60 CONTINUE + END IF +* + ELSE +* +* Let V = ( V1 ) +* ( V2 ) (last K rows) +* where V2 is unit upper triangular. +* + IF( LSAME( SIDE, 'L' ) ) THEN +* +* Form H * C or H' * C where C = ( C1 ) +* ( C2 ) +* +* W := C' * V = (C1'*V1 + C2'*V2) (stored in WORK) +* +* W := C2' +* + DO 70 J = 1, K + CALL DCOPY( N, C( M-K+J, 1 ), LDC, WORK( 1, J ), 1 ) + 70 CONTINUE +* +* W := W * V2 +* + CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', N, + $ K, ONE, V( M-K+1, 1 ), LDV, WORK, LDWORK ) + IF( M.GT.K ) THEN +* +* W := W + C1'*V1 +* + CALL DGEMM( 'Transpose', 'No transpose', N, K, M-K, + $ ONE, C, LDC, V, LDV, ONE, WORK, LDWORK ) + END IF +* +* W := W * T' or W * T +* + CALL DTRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K, + $ ONE, T, LDT, WORK, LDWORK ) +* +* C := C - V * W' +* + IF( M.GT.K ) THEN +* +* C1 := C1 - V1 * W' +* + CALL DGEMM( 'No transpose', 'Transpose', M-K, N, K, + $ -ONE, V, LDV, WORK, LDWORK, ONE, C, LDC ) + END IF +* +* W := W * V2' +* + CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', N, K, + $ ONE, V( M-K+1, 1 ), LDV, WORK, LDWORK ) +* +* C2 := C2 - W' +* + DO 90 J = 1, K + DO 80 I = 1, N + C( M-K+J, I ) = C( M-K+J, I ) - WORK( I, J ) + 80 CONTINUE + 90 CONTINUE +* + ELSE IF( LSAME( SIDE, 'R' ) ) THEN +* +* Form C * H or C * H' where C = ( C1 C2 ) +* +* W := C * V = (C1*V1 + C2*V2) (stored in WORK) +* +* W := C2 +* + DO 100 J = 1, K + CALL DCOPY( M, C( 1, N-K+J ), 1, WORK( 1, J ), 1 ) + 100 CONTINUE +* +* W := W * V2 +* + CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', M, + $ K, ONE, V( N-K+1, 1 ), LDV, WORK, LDWORK ) + IF( N.GT.K ) THEN +* +* W := W + C1 * V1 +* + CALL DGEMM( 'No transpose', 'No transpose', M, K, N-K, + $ ONE, C, LDC, V, LDV, ONE, WORK, LDWORK ) + END IF +* +* W := W * T or W * T' +* + CALL DTRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K, + $ ONE, T, LDT, WORK, LDWORK ) +* +* C := C - W * V' +* + IF( N.GT.K ) THEN +* +* C1 := C1 - W * V1' +* + CALL DGEMM( 'No transpose', 'Transpose', M, N-K, K, + $ -ONE, WORK, LDWORK, V, LDV, ONE, C, LDC ) + END IF +* +* W := W * V2' +* + CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', M, K, + $ ONE, V( N-K+1, 1 ), LDV, WORK, LDWORK ) +* +* C2 := C2 - W +* + DO 120 J = 1, K + DO 110 I = 1, M + C( I, N-K+J ) = C( I, N-K+J ) - WORK( I, J ) + 110 CONTINUE + 120 CONTINUE + END IF + END IF +* + ELSE IF( LSAME( STOREV, 'R' ) ) THEN +* + IF( LSAME( DIRECT, 'F' ) ) THEN +* +* Let V = ( V1 V2 ) (V1: first K columns) +* where V1 is unit upper triangular. +* + IF( LSAME( SIDE, 'L' ) ) THEN +* +* Form H * C or H' * C where C = ( C1 ) +* ( C2 ) +* +* W := C' * V' = (C1'*V1' + C2'*V2') (stored in WORK) +* +* W := C1' +* + DO 130 J = 1, K + CALL DCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 ) + 130 CONTINUE +* +* W := W * V1' +* + CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', N, K, + $ ONE, V, LDV, WORK, LDWORK ) + IF( M.GT.K ) THEN +* +* W := W + C2'*V2' +* + CALL DGEMM( 'Transpose', 'Transpose', N, K, M-K, ONE, + $ C( K+1, 1 ), LDC, V( 1, K+1 ), LDV, ONE, + $ WORK, LDWORK ) + END IF +* +* W := W * T' or W * T +* + CALL DTRMM( 'Right', 'Upper', TRANST, 'Non-unit', N, K, + $ ONE, T, LDT, WORK, LDWORK ) +* +* C := C - V' * W' +* + IF( M.GT.K ) THEN +* +* C2 := C2 - V2' * W' +* + CALL DGEMM( 'Transpose', 'Transpose', M-K, N, K, -ONE, + $ V( 1, K+1 ), LDV, WORK, LDWORK, ONE, + $ C( K+1, 1 ), LDC ) + END IF +* +* W := W * V1 +* + CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', N, + $ K, ONE, V, LDV, WORK, LDWORK ) +* +* C1 := C1 - W' +* + DO 150 J = 1, K + DO 140 I = 1, N + C( J, I ) = C( J, I ) - WORK( I, J ) + 140 CONTINUE + 150 CONTINUE +* + ELSE IF( LSAME( SIDE, 'R' ) ) THEN +* +* Form C * H or C * H' where C = ( C1 C2 ) +* +* W := C * V' = (C1*V1' + C2*V2') (stored in WORK) +* +* W := C1 +* + DO 160 J = 1, K + CALL DCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 ) + 160 CONTINUE +* +* W := W * V1' +* + CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', M, K, + $ ONE, V, LDV, WORK, LDWORK ) + IF( N.GT.K ) THEN +* +* W := W + C2 * V2' +* + CALL DGEMM( 'No transpose', 'Transpose', M, K, N-K, + $ ONE, C( 1, K+1 ), LDC, V( 1, K+1 ), LDV, + $ ONE, WORK, LDWORK ) + END IF +* +* W := W * T or W * T' +* + CALL DTRMM( 'Right', 'Upper', TRANS, 'Non-unit', M, K, + $ ONE, T, LDT, WORK, LDWORK ) +* +* C := C - W * V +* + IF( N.GT.K ) THEN +* +* C2 := C2 - W * V2 +* + CALL DGEMM( 'No transpose', 'No transpose', M, N-K, K, + $ -ONE, WORK, LDWORK, V( 1, K+1 ), LDV, ONE, + $ C( 1, K+1 ), LDC ) + END IF +* +* W := W * V1 +* + CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', M, + $ K, ONE, V, LDV, WORK, LDWORK ) +* +* C1 := C1 - W +* + DO 180 J = 1, K + DO 170 I = 1, M + C( I, J ) = C( I, J ) - WORK( I, J ) + 170 CONTINUE + 180 CONTINUE +* + END IF +* + ELSE +* +* Let V = ( V1 V2 ) (V2: last K columns) +* where V2 is unit lower triangular. +* + IF( LSAME( SIDE, 'L' ) ) THEN +* +* Form H * C or H' * C where C = ( C1 ) +* ( C2 ) +* +* W := C' * V' = (C1'*V1' + C2'*V2') (stored in WORK) +* +* W := C2' +* + DO 190 J = 1, K + CALL DCOPY( N, C( M-K+J, 1 ), LDC, WORK( 1, J ), 1 ) + 190 CONTINUE +* +* W := W * V2' +* + CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', N, K, + $ ONE, V( 1, M-K+1 ), LDV, WORK, LDWORK ) + IF( M.GT.K ) THEN +* +* W := W + C1'*V1' +* + CALL DGEMM( 'Transpose', 'Transpose', N, K, M-K, ONE, + $ C, LDC, V, LDV, ONE, WORK, LDWORK ) + END IF +* +* W := W * T' or W * T +* + CALL DTRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K, + $ ONE, T, LDT, WORK, LDWORK ) +* +* C := C - V' * W' +* + IF( M.GT.K ) THEN +* +* C1 := C1 - V1' * W' +* + CALL DGEMM( 'Transpose', 'Transpose', M-K, N, K, -ONE, + $ V, LDV, WORK, LDWORK, ONE, C, LDC ) + END IF +* +* W := W * V2 +* + CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', N, + $ K, ONE, V( 1, M-K+1 ), LDV, WORK, LDWORK ) +* +* C2 := C2 - W' +* + DO 210 J = 1, K + DO 200 I = 1, N + C( M-K+J, I ) = C( M-K+J, I ) - WORK( I, J ) + 200 CONTINUE + 210 CONTINUE +* + ELSE IF( LSAME( SIDE, 'R' ) ) THEN +* +* Form C * H or C * H' where C = ( C1 C2 ) +* +* W := C * V' = (C1*V1' + C2*V2') (stored in WORK) +* +* W := C2 +* + DO 220 J = 1, K + CALL DCOPY( M, C( 1, N-K+J ), 1, WORK( 1, J ), 1 ) + 220 CONTINUE +* +* W := W * V2' +* + CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', M, K, + $ ONE, V( 1, N-K+1 ), LDV, WORK, LDWORK ) + IF( N.GT.K ) THEN +* +* W := W + C1 * V1' +* + CALL DGEMM( 'No transpose', 'Transpose', M, K, N-K, + $ ONE, C, LDC, V, LDV, ONE, WORK, LDWORK ) + END IF +* +* W := W * T or W * T' +* + CALL DTRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K, + $ ONE, T, LDT, WORK, LDWORK ) +* +* C := C - W * V +* + IF( N.GT.K ) THEN +* +* C1 := C1 - W * V1 +* + CALL DGEMM( 'No transpose', 'No transpose', M, N-K, K, + $ -ONE, WORK, LDWORK, V, LDV, ONE, C, LDC ) + END IF +* +* W := W * V2 +* + CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', M, + $ K, ONE, V( 1, N-K+1 ), LDV, WORK, LDWORK ) +* +* C1 := C1 - W +* + DO 240 J = 1, K + DO 230 I = 1, M + C( I, N-K+J ) = C( I, N-K+J ) - WORK( I, J ) + 230 CONTINUE + 240 CONTINUE +* + END IF +* + END IF + END IF +* + RETURN +* +* End of DLARFB +* + END diff --git a/ext/lapack/dlarfg.f b/ext/lapack/dlarfg.f new file mode 100755 index 000000000..a8e64c1b9 --- /dev/null +++ b/ext/lapack/dlarfg.f @@ -0,0 +1,138 @@ + SUBROUTINE DLARFG( N, ALPHA, X, INCX, TAU ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + INTEGER INCX, N + DOUBLE PRECISION ALPHA, TAU +* .. +* .. Array Arguments .. + DOUBLE PRECISION X( * ) +* .. +* +* Purpose +* ======= +* +* DLARFG generates a real elementary reflector H of order n, such +* that +* +* H * ( alpha ) = ( beta ), H' * H = I. +* ( x ) ( 0 ) +* +* where alpha and beta are scalars, and x is an (n-1)-element real +* vector. H is represented in the form +* +* H = I - tau * ( 1 ) * ( 1 v' ) , +* ( v ) +* +* where tau is a real scalar and v is a real (n-1)-element +* vector. +* +* If the elements of x are all zero, then tau = 0 and H is taken to be +* the unit matrix. +* +* Otherwise 1 <= tau <= 2. +* +* Arguments +* ========= +* +* N (input) INTEGER +* The order of the elementary reflector. +* +* ALPHA (input/output) DOUBLE PRECISION +* On entry, the value alpha. +* On exit, it is overwritten with the value beta. +* +* X (input/output) DOUBLE PRECISION array, dimension +* (1+(N-2)*abs(INCX)) +* On entry, the vector x. +* On exit, it is overwritten with the vector v. +* +* INCX (input) INTEGER +* The increment between elements of X. INCX > 0. +* +* TAU (output) DOUBLE PRECISION +* The value tau. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER J, KNT + DOUBLE PRECISION BETA, RSAFMN, SAFMIN, XNORM +* .. +* .. External Functions .. + DOUBLE PRECISION DLAMCH, DLAPY2, DNRM2 + EXTERNAL DLAMCH, DLAPY2, DNRM2 +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, SIGN +* .. +* .. External Subroutines .. + EXTERNAL DSCAL +* .. +* .. Executable Statements .. +* + IF( N.LE.1 ) THEN + TAU = ZERO + RETURN + END IF +* + XNORM = DNRM2( N-1, X, INCX ) +* + IF( XNORM.EQ.ZERO ) THEN +* +* H = I +* + TAU = ZERO + ELSE +* +* general case +* + BETA = -SIGN( DLAPY2( ALPHA, XNORM ), ALPHA ) + SAFMIN = DLAMCH( 'S' ) / DLAMCH( 'E' ) + IF( ABS( BETA ).LT.SAFMIN ) THEN +* +* XNORM, BETA may be inaccurate; scale X and recompute them +* + RSAFMN = ONE / SAFMIN + KNT = 0 + 10 CONTINUE + KNT = KNT + 1 + CALL DSCAL( N-1, RSAFMN, X, INCX ) + BETA = BETA*RSAFMN + ALPHA = ALPHA*RSAFMN + IF( ABS( BETA ).LT.SAFMIN ) + $ GO TO 10 +* +* New BETA is at most 1, at least SAFMIN +* + XNORM = DNRM2( N-1, X, INCX ) + BETA = -SIGN( DLAPY2( ALPHA, XNORM ), ALPHA ) + TAU = ( BETA-ALPHA ) / BETA + CALL DSCAL( N-1, ONE / ( ALPHA-BETA ), X, INCX ) +* +* If ALPHA is subnormal, it may lose relative accuracy +* + ALPHA = BETA + DO 20 J = 1, KNT + ALPHA = ALPHA*SAFMIN + 20 CONTINUE + ELSE + TAU = ( BETA-ALPHA ) / BETA + CALL DSCAL( N-1, ONE / ( ALPHA-BETA ), X, INCX ) + ALPHA = BETA + END IF + END IF +* + RETURN +* +* End of DLARFG +* + END diff --git a/ext/lapack/dlarft.f b/ext/lapack/dlarft.f new file mode 100755 index 000000000..6035df482 --- /dev/null +++ b/ext/lapack/dlarft.f @@ -0,0 +1,218 @@ + SUBROUTINE DLARFT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* February 29, 1992 +* +* .. Scalar Arguments .. + CHARACTER DIRECT, STOREV + INTEGER K, LDT, LDV, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION T( LDT, * ), TAU( * ), V( LDV, * ) +* .. +* +* Purpose +* ======= +* +* DLARFT forms the triangular factor T of a real block reflector H +* of order n, which is defined as a product of k elementary reflectors. +* +* If DIRECT = 'F', H = H(1) H(2) . . . H(k) and T is upper triangular; +* +* If DIRECT = 'B', H = H(k) . . . H(2) H(1) and T is lower triangular. +* +* If STOREV = 'C', the vector which defines the elementary reflector +* H(i) is stored in the i-th column of the array V, and +* +* H = I - V * T * V' +* +* If STOREV = 'R', the vector which defines the elementary reflector +* H(i) is stored in the i-th row of the array V, and +* +* H = I - V' * T * V +* +* Arguments +* ========= +* +* DIRECT (input) CHARACTER*1 +* Specifies the order in which the elementary reflectors are +* multiplied to form the block reflector: +* = 'F': H = H(1) H(2) . . . H(k) (Forward) +* = 'B': H = H(k) . . . H(2) H(1) (Backward) +* +* STOREV (input) CHARACTER*1 +* Specifies how the vectors which define the elementary +* reflectors are stored (see also Further Details): +* = 'C': columnwise +* = 'R': rowwise +* +* N (input) INTEGER +* The order of the block reflector H. N >= 0. +* +* K (input) INTEGER +* The order of the triangular factor T (= the number of +* elementary reflectors). K >= 1. +* +* V (input/output) DOUBLE PRECISION array, dimension +* (LDV,K) if STOREV = 'C' +* (LDV,N) if STOREV = 'R' +* The matrix V. See further details. +* +* LDV (input) INTEGER +* The leading dimension of the array V. +* If STOREV = 'C', LDV >= max(1,N); if STOREV = 'R', LDV >= K. +* +* TAU (input) DOUBLE PRECISION array, dimension (K) +* TAU(i) must contain the scalar factor of the elementary +* reflector H(i). +* +* T (output) DOUBLE PRECISION array, dimension (LDT,K) +* The k by k triangular factor T of the block reflector. +* If DIRECT = 'F', T is upper triangular; if DIRECT = 'B', T is +* lower triangular. The rest of the array is not used. +* +* LDT (input) INTEGER +* The leading dimension of the array T. LDT >= K. +* +* Further Details +* =============== +* +* The shape of the matrix V and the storage of the vectors which define +* the H(i) is best illustrated by the following example with n = 5 and +* k = 3. The elements equal to 1 are not stored; the corresponding +* array elements are modified but restored on exit. The rest of the +* array is not used. +* +* DIRECT = 'F' and STOREV = 'C': DIRECT = 'F' and STOREV = 'R': +* +* V = ( 1 ) V = ( 1 v1 v1 v1 v1 ) +* ( v1 1 ) ( 1 v2 v2 v2 ) +* ( v1 v2 1 ) ( 1 v3 v3 ) +* ( v1 v2 v3 ) +* ( v1 v2 v3 ) +* +* DIRECT = 'B' and STOREV = 'C': DIRECT = 'B' and STOREV = 'R': +* +* V = ( v1 v2 v3 ) V = ( v1 v1 1 ) +* ( v1 v2 v3 ) ( v2 v2 v2 1 ) +* ( 1 v2 v3 ) ( v3 v3 v3 v3 1 ) +* ( 1 v3 ) +* ( 1 ) +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER I, J + DOUBLE PRECISION VII +* .. +* .. External Subroutines .. + EXTERNAL DGEMV, DTRMV +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. Executable Statements .. +* +* Quick return if possible +* + IF( N.EQ.0 ) + $ RETURN +* + IF( LSAME( DIRECT, 'F' ) ) THEN + DO 20 I = 1, K + IF( TAU( I ).EQ.ZERO ) THEN +* +* H(i) = I +* + DO 10 J = 1, I + T( J, I ) = ZERO + 10 CONTINUE + ELSE +* +* general case +* + VII = V( I, I ) + V( I, I ) = ONE + IF( LSAME( STOREV, 'C' ) ) THEN +* +* T(1:i-1,i) := - tau(i) * V(i:n,1:i-1)' * V(i:n,i) +* + CALL DGEMV( 'Transpose', N-I+1, I-1, -TAU( I ), + $ V( I, 1 ), LDV, V( I, I ), 1, ZERO, + $ T( 1, I ), 1 ) + ELSE +* +* T(1:i-1,i) := - tau(i) * V(1:i-1,i:n) * V(i,i:n)' +* + CALL DGEMV( 'No transpose', I-1, N-I+1, -TAU( I ), + $ V( 1, I ), LDV, V( I, I ), LDV, ZERO, + $ T( 1, I ), 1 ) + END IF + V( I, I ) = VII +* +* T(1:i-1,i) := T(1:i-1,1:i-1) * T(1:i-1,i) +* + CALL DTRMV( 'Upper', 'No transpose', 'Non-unit', I-1, T, + $ LDT, T( 1, I ), 1 ) + T( I, I ) = TAU( I ) + END IF + 20 CONTINUE + ELSE + DO 40 I = K, 1, -1 + IF( TAU( I ).EQ.ZERO ) THEN +* +* H(i) = I +* + DO 30 J = I, K + T( J, I ) = ZERO + 30 CONTINUE + ELSE +* +* general case +* + IF( I.LT.K ) THEN + IF( LSAME( STOREV, 'C' ) ) THEN + VII = V( N-K+I, I ) + V( N-K+I, I ) = ONE +* +* T(i+1:k,i) := +* - tau(i) * V(1:n-k+i,i+1:k)' * V(1:n-k+i,i) +* + CALL DGEMV( 'Transpose', N-K+I, K-I, -TAU( I ), + $ V( 1, I+1 ), LDV, V( 1, I ), 1, ZERO, + $ T( I+1, I ), 1 ) + V( N-K+I, I ) = VII + ELSE + VII = V( I, N-K+I ) + V( I, N-K+I ) = ONE +* +* T(i+1:k,i) := +* - tau(i) * V(i+1:k,1:n-k+i) * V(i,1:n-k+i)' +* + CALL DGEMV( 'No transpose', K-I, N-K+I, -TAU( I ), + $ V( I+1, 1 ), LDV, V( I, 1 ), LDV, ZERO, + $ T( I+1, I ), 1 ) + V( I, N-K+I ) = VII + END IF +* +* T(i+1:k,i) := T(i+1:k,i+1:k) * T(i+1:k,i) +* + CALL DTRMV( 'Lower', 'No transpose', 'Non-unit', K-I, + $ T( I+1, I+1 ), LDT, T( I+1, I ), 1 ) + END IF + T( I, I ) = TAU( I ) + END IF + 40 CONTINUE + END IF + RETURN +* +* End of DLARFT +* + END diff --git a/ext/lapack/dlartg.f b/ext/lapack/dlartg.f new file mode 100755 index 000000000..502f13eeb --- /dev/null +++ b/ext/lapack/dlartg.f @@ -0,0 +1,143 @@ + SUBROUTINE DLARTG( F, G, CS, SN, R ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + DOUBLE PRECISION CS, F, G, R, SN +* .. +* +* Purpose +* ======= +* +* DLARTG generate a plane rotation so that +* +* [ CS SN ] . [ F ] = [ R ] where CS**2 + SN**2 = 1. +* [ -SN CS ] [ G ] [ 0 ] +* +* This is a slower, more accurate version of the BLAS1 routine DROTG, +* with the following other differences: +* F and G are unchanged on return. +* If G=0, then CS=1 and SN=0. +* If F=0 and (G .ne. 0), then CS=0 and SN=1 without doing any +* floating point operations (saves work in DBDSQR when +* there are zeros on the diagonal). +* +* If F exceeds G in magnitude, CS will be positive. +* +* Arguments +* ========= +* +* F (input) DOUBLE PRECISION +* The first component of vector to be rotated. +* +* G (input) DOUBLE PRECISION +* The second component of vector to be rotated. +* +* CS (output) DOUBLE PRECISION +* The cosine of the rotation. +* +* SN (output) DOUBLE PRECISION +* The sine of the rotation. +* +* R (output) DOUBLE PRECISION +* The nonzero component of the rotated vector. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D0 ) + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D0 ) + DOUBLE PRECISION TWO + PARAMETER ( TWO = 2.0D0 ) +* .. +* .. Local Scalars .. + LOGICAL FIRST + INTEGER COUNT, I + DOUBLE PRECISION EPS, F1, G1, SAFMIN, SAFMN2, SAFMX2, SCALE +* .. +* .. External Functions .. + DOUBLE PRECISION DLAMCH + EXTERNAL DLAMCH +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, INT, LOG, MAX, SQRT +* .. +* .. Save statement .. + SAVE FIRST, SAFMX2, SAFMIN, SAFMN2 +* .. +* .. Data statements .. + DATA FIRST / .TRUE. / +* .. +* .. Executable Statements .. +* + IF( FIRST ) THEN + FIRST = .FALSE. + SAFMIN = DLAMCH( 'S' ) + EPS = DLAMCH( 'E' ) + SAFMN2 = DLAMCH( 'B' )**INT( LOG( SAFMIN / EPS ) / + $ LOG( DLAMCH( 'B' ) ) / TWO ) + SAFMX2 = ONE / SAFMN2 + END IF + IF( G.EQ.ZERO ) THEN + CS = ONE + SN = ZERO + R = F + ELSE IF( F.EQ.ZERO ) THEN + CS = ZERO + SN = ONE + R = G + ELSE + F1 = F + G1 = G + SCALE = MAX( ABS( F1 ), ABS( G1 ) ) + IF( SCALE.GE.SAFMX2 ) THEN + COUNT = 0 + 10 CONTINUE + COUNT = COUNT + 1 + F1 = F1*SAFMN2 + G1 = G1*SAFMN2 + SCALE = MAX( ABS( F1 ), ABS( G1 ) ) + IF( SCALE.GE.SAFMX2 ) + $ GO TO 10 + R = SQRT( F1**2+G1**2 ) + CS = F1 / R + SN = G1 / R + DO 20 I = 1, COUNT + R = R*SAFMX2 + 20 CONTINUE + ELSE IF( SCALE.LE.SAFMN2 ) THEN + COUNT = 0 + 30 CONTINUE + COUNT = COUNT + 1 + F1 = F1*SAFMX2 + G1 = G1*SAFMX2 + SCALE = MAX( ABS( F1 ), ABS( G1 ) ) + IF( SCALE.LE.SAFMN2 ) + $ GO TO 30 + R = SQRT( F1**2+G1**2 ) + CS = F1 / R + SN = G1 / R + DO 40 I = 1, COUNT + R = R*SAFMN2 + 40 CONTINUE + ELSE + R = SQRT( F1**2+G1**2 ) + CS = F1 / R + SN = G1 / R + END IF + IF( ABS( F ).GT.ABS( G ) .AND. CS.LT.ZERO ) THEN + CS = -CS + SN = -SN + R = -R + END IF + END IF + RETURN +* +* End of DLARTG +* + END diff --git a/ext/lapack/dlas2.f b/ext/lapack/dlas2.f new file mode 100755 index 000000000..ad2f337dc --- /dev/null +++ b/ext/lapack/dlas2.f @@ -0,0 +1,122 @@ + SUBROUTINE DLAS2( F, G, H, SSMIN, SSMAX ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + DOUBLE PRECISION F, G, H, SSMAX, SSMIN +* .. +* +* Purpose +* ======= +* +* DLAS2 computes the singular values of the 2-by-2 matrix +* [ F G ] +* [ 0 H ]. +* On return, SSMIN is the smaller singular value and SSMAX is the +* larger singular value. +* +* Arguments +* ========= +* +* F (input) DOUBLE PRECISION +* The (1,1) element of the 2-by-2 matrix. +* +* G (input) DOUBLE PRECISION +* The (1,2) element of the 2-by-2 matrix. +* +* H (input) DOUBLE PRECISION +* The (2,2) element of the 2-by-2 matrix. +* +* SSMIN (output) DOUBLE PRECISION +* The smaller singular value. +* +* SSMAX (output) DOUBLE PRECISION +* The larger singular value. +* +* Further Details +* =============== +* +* Barring over/underflow, all output quantities are correct to within +* a few units in the last place (ulps), even in the absence of a guard +* digit in addition/subtraction. +* +* In IEEE arithmetic, the code works correctly if one matrix element is +* infinite. +* +* Overflow will not occur unless the largest singular value itself +* overflows, or is within a few ulps of overflow. (On machines with +* partial overflow, like the Cray, overflow may occur if the largest +* singular value is within a factor of 2 of overflow.) +* +* Underflow is harmless if underflow is gradual. Otherwise, results +* may correspond to a matrix modified by perturbations of size near +* the underflow threshold. +* +* ==================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D0 ) + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D0 ) + DOUBLE PRECISION TWO + PARAMETER ( TWO = 2.0D0 ) +* .. +* .. Local Scalars .. + DOUBLE PRECISION AS, AT, AU, C, FA, FHMN, FHMX, GA, HA +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, MAX, MIN, SQRT +* .. +* .. Executable Statements .. +* + FA = ABS( F ) + GA = ABS( G ) + HA = ABS( H ) + FHMN = MIN( FA, HA ) + FHMX = MAX( FA, HA ) + IF( FHMN.EQ.ZERO ) THEN + SSMIN = ZERO + IF( FHMX.EQ.ZERO ) THEN + SSMAX = GA + ELSE + SSMAX = MAX( FHMX, GA )*SQRT( ONE+ + $ ( MIN( FHMX, GA ) / MAX( FHMX, GA ) )**2 ) + END IF + ELSE + IF( GA.LT.FHMX ) THEN + AS = ONE + FHMN / FHMX + AT = ( FHMX-FHMN ) / FHMX + AU = ( GA / FHMX )**2 + C = TWO / ( SQRT( AS*AS+AU )+SQRT( AT*AT+AU ) ) + SSMIN = FHMN*C + SSMAX = FHMX / C + ELSE + AU = FHMX / GA + IF( AU.EQ.ZERO ) THEN +* +* Avoid possible harmful underflow if exponent range +* asymmetric (true SSMIN may not underflow even if +* AU underflows) +* + SSMIN = ( FHMN*FHMX ) / GA + SSMAX = GA + ELSE + AS = ONE + FHMN / FHMX + AT = ( FHMX-FHMN ) / FHMX + C = ONE / ( SQRT( ONE+( AS*AU )**2 )+ + $ SQRT( ONE+( AT*AU )**2 ) ) + SSMIN = ( FHMN*C )*AU + SSMIN = SSMIN + SSMIN + SSMAX = GA / ( C+C ) + END IF + END IF + END IF + RETURN +* +* End of DLAS2 +* + END diff --git a/ext/lapack/dlascl.f b/ext/lapack/dlascl.f new file mode 100755 index 000000000..a4d53852e --- /dev/null +++ b/ext/lapack/dlascl.f @@ -0,0 +1,268 @@ + SUBROUTINE DLASCL( TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* February 29, 1992 +* +* .. Scalar Arguments .. + CHARACTER TYPE + INTEGER INFO, KL, KU, LDA, M, N + DOUBLE PRECISION CFROM, CTO +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ) +* .. +* +* Purpose +* ======= +* +* DLASCL multiplies the M by N real matrix A by the real scalar +* CTO/CFROM. This is done without over/underflow as long as the final +* result CTO*A(I,J)/CFROM does not over/underflow. TYPE specifies that +* A may be full, upper triangular, lower triangular, upper Hessenberg, +* or banded. +* +* Arguments +* ========= +* +* TYPE (input) CHARACTER*1 +* TYPE indices the storage type of the input matrix. +* = 'G': A is a full matrix. +* = 'L': A is a lower triangular matrix. +* = 'U': A is an upper triangular matrix. +* = 'H': A is an upper Hessenberg matrix. +* = 'B': A is a symmetric band matrix with lower bandwidth KL +* and upper bandwidth KU and with the only the lower +* half stored. +* = 'Q': A is a symmetric band matrix with lower bandwidth KL +* and upper bandwidth KU and with the only the upper +* half stored. +* = 'Z': A is a band matrix with lower bandwidth KL and upper +* bandwidth KU. +* +* KL (input) INTEGER +* The lower bandwidth of A. Referenced only if TYPE = 'B', +* 'Q' or 'Z'. +* +* KU (input) INTEGER +* The upper bandwidth of A. Referenced only if TYPE = 'B', +* 'Q' or 'Z'. +* +* CFROM (input) DOUBLE PRECISION +* CTO (input) DOUBLE PRECISION +* The matrix A is multiplied by CTO/CFROM. A(I,J) is computed +* without over/underflow if the final result CTO*A(I,J)/CFROM +* can be represented without over/underflow. CFROM must be +* nonzero. +* +* M (input) INTEGER +* The number of rows of the matrix A. M >= 0. +* +* N (input) INTEGER +* The number of columns of the matrix A. N >= 0. +* +* A (input/output) DOUBLE PRECISION array, dimension (LDA,M) +* The matrix to be multiplied by CTO/CFROM. See TYPE for the +* storage type. +* +* LDA (input) INTEGER +* The leading dimension of the array A. LDA >= max(1,M). +* +* INFO (output) INTEGER +* 0 - successful exit +* <0 - if INFO = -i, the i-th argument had an illegal value. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO, ONE + PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 ) +* .. +* .. Local Scalars .. + LOGICAL DONE + INTEGER I, ITYPE, J, K1, K2, K3, K4 + DOUBLE PRECISION BIGNUM, CFROM1, CFROMC, CTO1, CTOC, MUL, SMLNUM +* .. +* .. External Functions .. + LOGICAL LSAME + DOUBLE PRECISION DLAMCH + EXTERNAL LSAME, DLAMCH +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, MAX, MIN +* .. +* .. External Subroutines .. + EXTERNAL XERBLA +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 +* + IF( LSAME( TYPE, 'G' ) ) THEN + ITYPE = 0 + ELSE IF( LSAME( TYPE, 'L' ) ) THEN + ITYPE = 1 + ELSE IF( LSAME( TYPE, 'U' ) ) THEN + ITYPE = 2 + ELSE IF( LSAME( TYPE, 'H' ) ) THEN + ITYPE = 3 + ELSE IF( LSAME( TYPE, 'B' ) ) THEN + ITYPE = 4 + ELSE IF( LSAME( TYPE, 'Q' ) ) THEN + ITYPE = 5 + ELSE IF( LSAME( TYPE, 'Z' ) ) THEN + ITYPE = 6 + ELSE + ITYPE = -1 + END IF +* + IF( ITYPE.EQ.-1 ) THEN + INFO = -1 + ELSE IF( CFROM.EQ.ZERO ) THEN + INFO = -4 + ELSE IF( M.LT.0 ) THEN + INFO = -6 + ELSE IF( N.LT.0 .OR. ( ITYPE.EQ.4 .AND. N.NE.M ) .OR. + $ ( ITYPE.EQ.5 .AND. N.NE.M ) ) THEN + INFO = -7 + ELSE IF( ITYPE.LE.3 .AND. LDA.LT.MAX( 1, M ) ) THEN + INFO = -9 + ELSE IF( ITYPE.GE.4 ) THEN + IF( KL.LT.0 .OR. KL.GT.MAX( M-1, 0 ) ) THEN + INFO = -2 + ELSE IF( KU.LT.0 .OR. KU.GT.MAX( N-1, 0 ) .OR. + $ ( ( ITYPE.EQ.4 .OR. ITYPE.EQ.5 ) .AND. KL.NE.KU ) ) + $ THEN + INFO = -3 + ELSE IF( ( ITYPE.EQ.4 .AND. LDA.LT.KL+1 ) .OR. + $ ( ITYPE.EQ.5 .AND. LDA.LT.KU+1 ) .OR. + $ ( ITYPE.EQ.6 .AND. LDA.LT.2*KL+KU+1 ) ) THEN + INFO = -9 + END IF + END IF +* + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DLASCL', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( N.EQ.0 .OR. M.EQ.0 ) + $ RETURN +* +* Get machine parameters +* + SMLNUM = DLAMCH( 'S' ) + BIGNUM = ONE / SMLNUM +* + CFROMC = CFROM + CTOC = CTO +* + 10 CONTINUE + CFROM1 = CFROMC*SMLNUM + CTO1 = CTOC / BIGNUM + IF( ABS( CFROM1 ).GT.ABS( CTOC ) .AND. CTOC.NE.ZERO ) THEN + MUL = SMLNUM + DONE = .FALSE. + CFROMC = CFROM1 + ELSE IF( ABS( CTO1 ).GT.ABS( CFROMC ) ) THEN + MUL = BIGNUM + DONE = .FALSE. + CTOC = CTO1 + ELSE + MUL = CTOC / CFROMC + DONE = .TRUE. + END IF +* + IF( ITYPE.EQ.0 ) THEN +* +* Full matrix +* + DO 30 J = 1, N + DO 20 I = 1, M + A( I, J ) = A( I, J )*MUL + 20 CONTINUE + 30 CONTINUE +* + ELSE IF( ITYPE.EQ.1 ) THEN +* +* Lower triangular matrix +* + DO 50 J = 1, N + DO 40 I = J, M + A( I, J ) = A( I, J )*MUL + 40 CONTINUE + 50 CONTINUE +* + ELSE IF( ITYPE.EQ.2 ) THEN +* +* Upper triangular matrix +* + DO 70 J = 1, N + DO 60 I = 1, MIN( J, M ) + A( I, J ) = A( I, J )*MUL + 60 CONTINUE + 70 CONTINUE +* + ELSE IF( ITYPE.EQ.3 ) THEN +* +* Upper Hessenberg matrix +* + DO 90 J = 1, N + DO 80 I = 1, MIN( J+1, M ) + A( I, J ) = A( I, J )*MUL + 80 CONTINUE + 90 CONTINUE +* + ELSE IF( ITYPE.EQ.4 ) THEN +* +* Lower half of a symmetric band matrix +* + K3 = KL + 1 + K4 = N + 1 + DO 110 J = 1, N + DO 100 I = 1, MIN( K3, K4-J ) + A( I, J ) = A( I, J )*MUL + 100 CONTINUE + 110 CONTINUE +* + ELSE IF( ITYPE.EQ.5 ) THEN +* +* Upper half of a symmetric band matrix +* + K1 = KU + 2 + K3 = KU + 1 + DO 130 J = 1, N + DO 120 I = MAX( K1-J, 1 ), K3 + A( I, J ) = A( I, J )*MUL + 120 CONTINUE + 130 CONTINUE +* + ELSE IF( ITYPE.EQ.6 ) THEN +* +* Band matrix +* + K1 = KL + KU + 2 + K2 = KL + 1 + K3 = 2*KL + KU + 1 + K4 = KL + KU + 1 + M + DO 150 J = 1, N + DO 140 I = MAX( K1-J, K2 ), MIN( K3, K4-J ) + A( I, J ) = A( I, J )*MUL + 140 CONTINUE + 150 CONTINUE +* + END IF +* + IF( .NOT.DONE ) + $ GO TO 10 +* + RETURN +* +* End of DLASCL +* + END diff --git a/ext/lapack/dlaset.f b/ext/lapack/dlaset.f new file mode 100755 index 000000000..c086b6159 --- /dev/null +++ b/ext/lapack/dlaset.f @@ -0,0 +1,115 @@ + SUBROUTINE DLASET( UPLO, M, N, ALPHA, BETA, A, LDA ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* October 31, 1992 +* +* .. Scalar Arguments .. + CHARACTER UPLO + INTEGER LDA, M, N + DOUBLE PRECISION ALPHA, BETA +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ) +* .. +* +* Purpose +* ======= +* +* DLASET initializes an m-by-n matrix A to BETA on the diagonal and +* ALPHA on the offdiagonals. +* +* Arguments +* ========= +* +* UPLO (input) CHARACTER*1 +* Specifies the part of the matrix A to be set. +* = 'U': Upper triangular part is set; the strictly lower +* triangular part of A is not changed. +* = 'L': Lower triangular part is set; the strictly upper +* triangular part of A is not changed. +* Otherwise: All of the matrix A is set. +* +* M (input) INTEGER +* The number of rows of the matrix A. M >= 0. +* +* N (input) INTEGER +* The number of columns of the matrix A. N >= 0. +* +* ALPHA (input) DOUBLE PRECISION +* The constant to which the offdiagonal elements are to be set. +* +* BETA (input) DOUBLE PRECISION +* The constant to which the diagonal elements are to be set. +* +* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) +* On exit, the leading m-by-n submatrix of A is set as follows: +* +* if UPLO = 'U', A(i,j) = ALPHA, 1<=i<=j-1, 1<=j<=n, +* if UPLO = 'L', A(i,j) = ALPHA, j+1<=i<=m, 1<=j<=n, +* otherwise, A(i,j) = ALPHA, 1<=i<=m, 1<=j<=n, i.ne.j, +* +* and, for all UPLO, A(i,i) = BETA, 1<=i<=min(m,n). +* +* LDA (input) INTEGER +* The leading dimension of the array A. LDA >= max(1,M). +* +* ===================================================================== +* +* .. Local Scalars .. + INTEGER I, J +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. Intrinsic Functions .. + INTRINSIC MIN +* .. +* .. Executable Statements .. +* + IF( LSAME( UPLO, 'U' ) ) THEN +* +* Set the strictly upper triangular or trapezoidal part of the +* array to ALPHA. +* + DO 20 J = 2, N + DO 10 I = 1, MIN( J-1, M ) + A( I, J ) = ALPHA + 10 CONTINUE + 20 CONTINUE +* + ELSE IF( LSAME( UPLO, 'L' ) ) THEN +* +* Set the strictly lower triangular or trapezoidal part of the +* array to ALPHA. +* + DO 40 J = 1, MIN( M, N ) + DO 30 I = J + 1, M + A( I, J ) = ALPHA + 30 CONTINUE + 40 CONTINUE +* + ELSE +* +* Set the leading m-by-n submatrix to ALPHA. +* + DO 60 J = 1, N + DO 50 I = 1, M + A( I, J ) = ALPHA + 50 CONTINUE + 60 CONTINUE + END IF +* +* Set the first min(M,N) diagonal elements to BETA. +* + DO 70 I = 1, MIN( M, N ) + A( I, I ) = BETA + 70 CONTINUE +* + RETURN +* +* End of DLASET +* + END diff --git a/ext/lapack/dlasq1.f b/ext/lapack/dlasq1.f new file mode 100755 index 000000000..5614aabc7 --- /dev/null +++ b/ext/lapack/dlasq1.f @@ -0,0 +1,222 @@ + SUBROUTINE DLASQ1( N, D, E, WORK, INFO ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + INTEGER INFO, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION D( * ), E( * ), WORK( * ) +* .. +* +* Purpose +* ======= +* +* DLASQ1 computes the singular values of a real N-by-N bidiagonal +* matrix with diagonal D and off-diagonal E. The singular values are +* computed to high relative accuracy, barring over/underflow or +* denormalization. The algorithm is described in +* +* "Accurate singular values and differential qd algorithms," by +* K. V. Fernando and B. N. Parlett, +* Numer. Math., Vol-67, No. 2, pp. 191-230,1994. +* +* See also +* "Implementation of differential qd algorithms," by +* K. V. Fernando and B. N. Parlett, Technical Report, +* Department of Mathematics, University of California at Berkeley, +* 1994 (Under preparation). +* +* Arguments +* ========= +* +* N (input) INTEGER +* The number of rows and columns in the matrix. N >= 0. +* +* D (input/output) DOUBLE PRECISION array, dimension (N) +* On entry, D contains the diagonal elements of the +* bidiagonal matrix whose SVD is desired. On normal exit, +* D contains the singular values in decreasing order. +* +* E (input/output) DOUBLE PRECISION array, dimension (N) +* On entry, elements E(1:N-1) contain the off-diagonal elements +* of the bidiagonal matrix whose SVD is desired. +* On exit, E is overwritten. +* +* WORK (workspace) DOUBLE PRECISION array, dimension (2*N) +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument had an illegal value +* > 0: if INFO = i, the algorithm did not converge; i +* specifies how many superdiagonals did not converge. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION MEIGTH + PARAMETER ( MEIGTH = -0.125D0 ) + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D0 ) + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D0 ) + DOUBLE PRECISION TEN + PARAMETER ( TEN = 10.0D0 ) + DOUBLE PRECISION HUNDRD + PARAMETER ( HUNDRD = 100.0D0 ) + DOUBLE PRECISION TWO56 + PARAMETER ( TWO56 = 256.0D0 ) +* .. +* .. Local Scalars .. + LOGICAL RESTRT + INTEGER I, IERR, J, KE, KEND, M, NY + DOUBLE PRECISION DM, DX, EPS, SCL, SFMIN, SIG1, SIG2, SIGMN, + $ SIGMX, SMALL2, THRESH, TOL, TOL2, TOLMUL +* .. +* .. External Functions .. + DOUBLE PRECISION DLAMCH + EXTERNAL DLAMCH +* .. +* .. External Subroutines .. + EXTERNAL DCOPY, DLAS2, DLASCL, DLASQ2, DLASRT, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, DBLE, MAX, MIN, SQRT +* .. +* .. Executable Statements .. + INFO = 0 + IF( N.LT.0 ) THEN + INFO = -2 + CALL XERBLA( 'DLASQ1', -INFO ) + RETURN + ELSE IF( N.EQ.0 ) THEN + RETURN + ELSE IF( N.EQ.1 ) THEN + D( 1 ) = ABS( D( 1 ) ) + RETURN + ELSE IF( N.EQ.2 ) THEN + CALL DLAS2( D( 1 ), E( 1 ), D( 2 ), SIGMN, SIGMX ) + D( 1 ) = SIGMX + D( 2 ) = SIGMN + RETURN + END IF +* +* Estimate the largest singular value +* + SIGMX = ZERO + DO 10 I = 1, N - 1 + SIGMX = MAX( SIGMX, ABS( E( I ) ) ) + 10 CONTINUE +* +* Early return if sigmx is zero (matrix is already diagonal) +* + IF( SIGMX.EQ.ZERO ) + $ GO TO 70 +* + DO 20 I = 1, N + D( I ) = ABS( D( I ) ) + SIGMX = MAX( SIGMX, D( I ) ) + 20 CONTINUE +* +* Get machine parameters +* + EPS = DLAMCH( 'EPSILON' ) + SFMIN = DLAMCH( 'SAFE MINIMUM' ) +* +* Compute singular values to relative accuracy TOL +* It is assumed that tol**2 does not underflow. +* + TOLMUL = MAX( TEN, MIN( HUNDRD, EPS**( -MEIGTH ) ) ) + TOL = TOLMUL*EPS + TOL2 = TOL**2 +* + THRESH = SIGMX*SQRT( SFMIN )*TOL +* +* Scale matrix so the square of the largest element is +* 1 / ( 256 * SFMIN ) +* + SCL = SQRT( ONE / ( TWO56*SFMIN ) ) + SMALL2 = ONE / ( TWO56*TOLMUL**2 ) + CALL DCOPY( N, D, 1, WORK( 1 ), 1 ) + CALL DCOPY( N-1, E, 1, WORK( N+1 ), 1 ) + CALL DLASCL( 'G', 0, 0, SIGMX, SCL, N, 1, WORK( 1 ), N, IERR ) + CALL DLASCL( 'G', 0, 0, SIGMX, SCL, N-1, 1, WORK( N+1 ), N-1, + $ IERR ) +* +* Square D and E (the input for the qd algorithm) +* + DO 30 J = 1, 2*N - 1 + WORK( J ) = WORK( J )**2 + 30 CONTINUE +* +* Apply qd algorithm +* + M = 0 + E( N ) = ZERO + DX = WORK( 1 ) + DM = DX + KE = 0 + RESTRT = .FALSE. + DO 60 I = 1, N + IF( ABS( E( I ) ).LE.THRESH .OR. WORK( N+I ).LE.TOL2* + $ ( DM / DBLE( I-M ) ) ) THEN + NY = I - M + IF( NY.EQ.1 ) THEN + GO TO 50 + ELSE IF( NY.EQ.2 ) THEN + CALL DLAS2( D( M+1 ), E( M+1 ), D( M+2 ), SIG1, SIG2 ) + D( M+1 ) = SIG1 + D( M+2 ) = SIG2 + ELSE + KEND = KE + 1 - M + CALL DLASQ2( NY, D( M+1 ), E( M+1 ), WORK( M+1 ), + $ WORK( M+N+1 ), EPS, TOL2, SMALL2, DM, KEND, + $ INFO ) +* +* Return, INFO = number of unconverged superdiagonals +* + IF( INFO.NE.0 ) THEN + INFO = INFO + I + RETURN + END IF +* +* Undo scaling +* + DO 40 J = M + 1, M + NY + D( J ) = SQRT( D( J ) ) + 40 CONTINUE + CALL DLASCL( 'G', 0, 0, SCL, SIGMX, NY, 1, D( M+1 ), NY, + $ IERR ) + END IF + 50 CONTINUE + M = I + IF( I.NE.N ) THEN + DX = WORK( I+1 ) + DM = DX + KE = I + RESTRT = .TRUE. + END IF + END IF + IF( I.NE.N .AND. .NOT.RESTRT ) THEN + DX = WORK( I+1 )*( DX / ( DX+WORK( N+I ) ) ) + IF( DM.GT.DX ) THEN + DM = DX + KE = I + END IF + END IF + RESTRT = .FALSE. + 60 CONTINUE + KEND = KE + 1 +* +* Sort the singular values into decreasing order +* + 70 CONTINUE + CALL DLASRT( 'D', N, D, INFO ) + RETURN +* +* End of DLASQ1 +* + END diff --git a/ext/lapack/dlasq2.f b/ext/lapack/dlasq2.f new file mode 100755 index 000000000..14112a673 --- /dev/null +++ b/ext/lapack/dlasq2.f @@ -0,0 +1,268 @@ + SUBROUTINE DLASQ2( M, Q, E, QQ, EE, EPS, TOL2, SMALL2, SUP, KEND, + $ INFO ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + INTEGER INFO, KEND, M + DOUBLE PRECISION EPS, SMALL2, SUP, TOL2 +* .. +* .. Array Arguments .. + DOUBLE PRECISION E( * ), EE( * ), Q( * ), QQ( * ) +* .. +* +* Purpose +* ======= +* +* DLASQ2 computes the singular values of a real N-by-N unreduced +* bidiagonal matrix with squared diagonal elements in Q and +* squared off-diagonal elements in E. The singular values are +* computed to relative accuracy TOL, barring over/underflow or +* denormalization. +* +* Arguments +* ========= +* +* M (input) INTEGER +* The number of rows and columns in the matrix. M >= 0. +* +* Q (output) DOUBLE PRECISION array, dimension (M) +* On normal exit, contains the squared singular values. +* +* E (workspace) DOUBLE PRECISION array, dimension (M) +* +* QQ (input/output) DOUBLE PRECISION array, dimension (M) +* On entry, QQ contains the squared diagonal elements of the +* bidiagonal matrix whose SVD is desired. +* On exit, QQ is overwritten. +* +* EE (input/output) DOUBLE PRECISION array, dimension (M) +* On entry, EE(1:N-1) contains the squared off-diagonal +* elements of the bidiagonal matrix whose SVD is desired. +* On exit, EE is overwritten. +* +* EPS (input) DOUBLE PRECISION +* Machine epsilon. +* +* TOL2 (input) DOUBLE PRECISION +* Desired relative accuracy of computed eigenvalues +* as defined in DLASQ1. +* +* SMALL2 (input) DOUBLE PRECISION +* A threshold value as defined in DLASQ1. +* +* SUP (input/output) DOUBLE PRECISION +* Upper bound for the smallest eigenvalue. +* +* KEND (input/output) INTEGER +* Index where minimum d occurs. +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument had an illegal value +* > 0: if INFO = i, the algorithm did not converge; i +* specifies how many superdiagonals did not converge. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D+0 ) + DOUBLE PRECISION FOUR, HALF + PARAMETER ( FOUR = 4.0D+0, HALF = 0.5D+0 ) +* .. +* .. Local Scalars .. + INTEGER ICONV, IPHASE, ISP, N, OFF, OFF1 + DOUBLE PRECISION QEMAX, SIGMA, XINF, XX, YY +* .. +* .. External Subroutines .. + EXTERNAL DLASQ3 +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN, NINT, SQRT +* .. +* .. Executable Statements .. + N = M +* +* Set the default maximum number of iterations +* + OFF = 0 + OFF1 = OFF + 1 + SIGMA = ZERO + XINF = ZERO + ICONV = 0 + IPHASE = 2 +* +* Try deflation at the bottom +* +* 1x1 deflation +* + 10 CONTINUE + IF( N.LE.2 ) + $ GO TO 20 + IF( EE( N-1 ).LE.MAX( QQ( N ), XINF, SMALL2 )*TOL2 ) THEN + Q( N ) = QQ( N ) + N = N - 1 + IF( KEND.GT.N ) + $ KEND = N + SUP = MIN( QQ( N ), QQ( N-1 ) ) + GO TO 10 + END IF +* +* 2x2 deflation +* + IF( EE( N-2 ).LE.MAX( XINF, SMALL2, + $ ( QQ( N ) / ( QQ( N )+EE( N-1 )+QQ( N-1 ) ) )*QQ( N-1 ) )* + $ TOL2 ) THEN + QEMAX = MAX( QQ( N ), QQ( N-1 ), EE( N-1 ) ) + IF( QEMAX.NE.ZERO ) THEN + IF( QEMAX.EQ.QQ( N-1 ) ) THEN + XX = HALF*( QQ( N )+QQ( N-1 )+EE( N-1 )+QEMAX* + $ SQRT( ( ( QQ( N )-QQ( N-1 )+EE( N-1 ) ) / + $ QEMAX )**2+FOUR*EE( N-1 ) / QEMAX ) ) + ELSE IF( QEMAX.EQ.QQ( N ) ) THEN + XX = HALF*( QQ( N )+QQ( N-1 )+EE( N-1 )+QEMAX* + $ SQRT( ( ( QQ( N-1 )-QQ( N )+EE( N-1 ) ) / + $ QEMAX )**2+FOUR*EE( N-1 ) / QEMAX ) ) + ELSE + XX = HALF*( QQ( N )+QQ( N-1 )+EE( N-1 )+QEMAX* + $ SQRT( ( ( QQ( N )-QQ( N-1 )+EE( N-1 ) ) / + $ QEMAX )**2+FOUR*QQ( N-1 ) / QEMAX ) ) + END IF + YY = ( MAX( QQ( N ), QQ( N-1 ) ) / XX )* + $ MIN( QQ( N ), QQ( N-1 ) ) + ELSE + XX = ZERO + YY = ZERO + END IF + Q( N-1 ) = XX + Q( N ) = YY + N = N - 2 + IF( KEND.GT.N ) + $ KEND = N + SUP = QQ( N ) + GO TO 10 + END IF +* + 20 CONTINUE + IF( N.EQ.0 ) THEN +* +* The lower branch is finished +* + IF( OFF.EQ.0 ) THEN +* +* No upper branch; return to DLASQ1 +* + RETURN + ELSE +* +* Going back to upper branch +* + XINF = ZERO + IF( EE( OFF ).GT.ZERO ) THEN + ISP = NINT( EE( OFF ) ) + IPHASE = 1 + ELSE + ISP = -NINT( EE( OFF ) ) + IPHASE = 2 + END IF + SIGMA = E( OFF ) + N = OFF - ISP + 1 + OFF1 = ISP + OFF = OFF1 - 1 + IF( N.LE.2 ) + $ GO TO 20 + IF( IPHASE.EQ.1 ) THEN + SUP = MIN( Q( N+OFF ), Q( N-1+OFF ), Q( N-2+OFF ) ) + ELSE + SUP = MIN( QQ( N+OFF ), QQ( N-1+OFF ), QQ( N-2+OFF ) ) + END IF + KEND = 0 + ICONV = -3 + END IF + ELSE IF( N.EQ.1 ) THEN +* +* 1x1 Solver +* + IF( IPHASE.EQ.1 ) THEN + Q( OFF1 ) = Q( OFF1 ) + SIGMA + ELSE + Q( OFF1 ) = QQ( OFF1 ) + SIGMA + END IF + N = 0 + GO TO 20 +* +* 2x2 Solver +* + ELSE IF( N.EQ.2 ) THEN + IF( IPHASE.EQ.2 ) THEN + QEMAX = MAX( QQ( N+OFF ), QQ( N-1+OFF ), EE( N-1+OFF ) ) + IF( QEMAX.NE.ZERO ) THEN + IF( QEMAX.EQ.QQ( N-1+OFF ) ) THEN + XX = HALF*( QQ( N+OFF )+QQ( N-1+OFF )+EE( N-1+OFF )+ + $ QEMAX*SQRT( ( ( QQ( N+OFF )-QQ( N-1+OFF )+EE( N- + $ 1+OFF ) ) / QEMAX )**2+FOUR*EE( OFF+N-1 ) / + $ QEMAX ) ) + ELSE IF( QEMAX.EQ.QQ( N+OFF ) ) THEN + XX = HALF*( QQ( N+OFF )+QQ( N-1+OFF )+EE( N-1+OFF )+ + $ QEMAX*SQRT( ( ( QQ( N-1+OFF )-QQ( N+OFF )+EE( N- + $ 1+OFF ) ) / QEMAX )**2+FOUR*EE( N-1+OFF ) / + $ QEMAX ) ) + ELSE + XX = HALF*( QQ( N+OFF )+QQ( N-1+OFF )+EE( N-1+OFF )+ + $ QEMAX*SQRT( ( ( QQ( N+OFF )-QQ( N-1+OFF )+EE( N- + $ 1+OFF ) ) / QEMAX )**2+FOUR*QQ( N-1+OFF ) / + $ QEMAX ) ) + END IF + YY = ( MAX( QQ( N+OFF ), QQ( N-1+OFF ) ) / XX )* + $ MIN( QQ( N+OFF ), QQ( N-1+OFF ) ) + ELSE + XX = ZERO + YY = ZERO + END IF + ELSE + QEMAX = MAX( Q( N+OFF ), Q( N-1+OFF ), E( N-1+OFF ) ) + IF( QEMAX.NE.ZERO ) THEN + IF( QEMAX.EQ.Q( N-1+OFF ) ) THEN + XX = HALF*( Q( N+OFF )+Q( N-1+OFF )+E( N-1+OFF )+ + $ QEMAX*SQRT( ( ( Q( N+OFF )-Q( N-1+OFF )+E( N-1+ + $ OFF ) ) / QEMAX )**2+FOUR*E( N-1+OFF ) / + $ QEMAX ) ) + ELSE IF( QEMAX.EQ.Q( N+OFF ) ) THEN + XX = HALF*( Q( N+OFF )+Q( N-1+OFF )+E( N-1+OFF )+ + $ QEMAX*SQRT( ( ( Q( N-1+OFF )-Q( N+OFF )+E( N-1+ + $ OFF ) ) / QEMAX )**2+FOUR*E( N-1+OFF ) / + $ QEMAX ) ) + ELSE + XX = HALF*( Q( N+OFF )+Q( N-1+OFF )+E( N-1+OFF )+ + $ QEMAX*SQRT( ( ( Q( N+OFF )-Q( N-1+OFF )+E( N-1+ + $ OFF ) ) / QEMAX )**2+FOUR*Q( N-1+OFF ) / + $ QEMAX ) ) + END IF + YY = ( MAX( Q( N+OFF ), Q( N-1+OFF ) ) / XX )* + $ MIN( Q( N+OFF ), Q( N-1+OFF ) ) + ELSE + XX = ZERO + YY = ZERO + END IF + END IF + Q( N-1+OFF ) = SIGMA + XX + Q( N+OFF ) = YY + SIGMA + N = 0 + GO TO 20 + END IF + CALL DLASQ3( N, Q( OFF1 ), E( OFF1 ), QQ( OFF1 ), EE( OFF1 ), SUP, + $ SIGMA, KEND, OFF, IPHASE, ICONV, EPS, TOL2, SMALL2 ) + IF( SUP.LT.ZERO ) THEN + INFO = N + OFF + RETURN + END IF + OFF1 = OFF + 1 + GO TO 20 +* +* End of DLASQ2 +* + END diff --git a/ext/lapack/dlasq3.f b/ext/lapack/dlasq3.f new file mode 100755 index 000000000..03daaaf4c --- /dev/null +++ b/ext/lapack/dlasq3.f @@ -0,0 +1,820 @@ + SUBROUTINE DLASQ3( N, Q, E, QQ, EE, SUP, SIGMA, KEND, OFF, IPHASE, + $ ICONV, EPS, TOL2, SMALL2 ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + INTEGER ICONV, IPHASE, KEND, N, OFF + DOUBLE PRECISION EPS, SIGMA, SMALL2, SUP, TOL2 +* .. +* .. Array Arguments .. + DOUBLE PRECISION E( * ), EE( * ), Q( * ), QQ( * ) +* .. +* +* Purpose +* ======= +* +* DLASQ3 is the workhorse of the whole bidiagonal SVD algorithm. +* This can be described as the differential qd with shifts. +* +* Arguments +* ========= +* +* N (input/output) INTEGER +* On entry, N specifies the number of rows and columns +* in the matrix. N must be at least 3. +* On exit N is non-negative and less than the input value. +* +* Q (input/output) DOUBLE PRECISION array, dimension (N) +* Q array in ping (see IPHASE below) +* +* E (input/output) DOUBLE PRECISION array, dimension (N) +* E array in ping (see IPHASE below) +* +* QQ (input/output) DOUBLE PRECISION array, dimension (N) +* Q array in pong (see IPHASE below) +* +* EE (input/output) DOUBLE PRECISION array, dimension (N) +* E array in pong (see IPHASE below) +* +* SUP (input/output) DOUBLE PRECISION +* Upper bound for the smallest eigenvalue +* +* SIGMA (input/output) DOUBLE PRECISION +* Accumulated shift for the present submatrix +* +* KEND (input/output) INTEGER +* Index where minimum D(i) occurs in recurrence for +* splitting criterion +* +* OFF (input/output) INTEGER +* Offset for arrays +* +* IPHASE (input/output) INTEGER +* If IPHASE = 1 (ping) then data is in Q and E arrays +* If IPHASE = 2 (pong) then data is in QQ and EE arrays +* +* ICONV (input) INTEGER +* If ICONV = 0 a bottom part of a matrix (with a split) +* If ICONV =-3 a top part of a matrix (with a split) +* +* EPS (input) DOUBLE PRECISION +* Machine epsilon +* +* TOL2 (input) DOUBLE PRECISION +* Square of the relative tolerance TOL as defined in DLASQ1 +* +* SMALL2 (input) DOUBLE PRECISION +* A threshold value as defined in DLASQ1 +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) + INTEGER NPP + PARAMETER ( NPP = 32 ) + INTEGER IPP + PARAMETER ( IPP = 5 ) + DOUBLE PRECISION HALF, FOUR + PARAMETER ( HALF = 0.5D+0, FOUR = 4.0D+0 ) + INTEGER IFLMAX + PARAMETER ( IFLMAX = 2 ) +* .. +* .. Local Scalars .. + LOGICAL LDEF, LSPLIT + INTEGER I, IC, ICNT, IFL, IP, ISP, K1END, K2END, KE, + $ KS, MAXIT, N1, N2 + DOUBLE PRECISION D, DM, QEMAX, T1, TAU, TOLX, TOLY, TOLZ, XX, YY +* .. +* .. External Subroutines .. + EXTERNAL DCOPY, DLASQ4 +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, MAX, MIN, SQRT +* .. +* .. Executable Statements .. + ICNT = 0 + TAU = ZERO + DM = SUP + TOLX = SIGMA*TOL2 + TOLZ = MAX( SMALL2, SIGMA )*TOL2 +* +* Set maximum number of iterations +* + MAXIT = 100*N +* +* Flipping +* + IC = 2 + IF( N.GT.3 ) THEN + IF( IPHASE.EQ.1 ) THEN + DO 10 I = 1, N - 2 + IF( Q( I ).GT.Q( I+1 ) ) + $ IC = IC + 1 + IF( E( I ).GT.E( I+1 ) ) + $ IC = IC + 1 + 10 CONTINUE + IF( Q( N-1 ).GT.Q( N ) ) + $ IC = IC + 1 + IF( IC.LT.N ) THEN + CALL DCOPY( N, Q, 1, QQ, -1 ) + CALL DCOPY( N-1, E, 1, EE, -1 ) + IF( KEND.NE.0 ) + $ KEND = N - KEND + 1 + IPHASE = 2 + END IF + ELSE + DO 20 I = 1, N - 2 + IF( QQ( I ).GT.QQ( I+1 ) ) + $ IC = IC + 1 + IF( EE( I ).GT.EE( I+1 ) ) + $ IC = IC + 1 + 20 CONTINUE + IF( QQ( N-1 ).GT.QQ( N ) ) + $ IC = IC + 1 + IF( IC.LT.N ) THEN + CALL DCOPY( N, QQ, 1, Q, -1 ) + CALL DCOPY( N-1, EE, 1, E, -1 ) + IF( KEND.NE.0 ) + $ KEND = N - KEND + 1 + IPHASE = 1 + END IF + END IF + END IF + IF( ICONV.EQ.-3 ) THEN + IF( IPHASE.EQ.1 ) THEN + GO TO 180 + ELSE + GO TO 80 + END IF + END IF + IF( IPHASE.EQ.2 ) + $ GO TO 130 +* +* The ping section of the code +* + 30 CONTINUE + IFL = 0 +* +* Compute the shift +* + IF( KEND.EQ.0 .OR. SUP.EQ.ZERO ) THEN + TAU = ZERO + ELSE IF( ICNT.GT.0 .AND. DM.LE.TOLZ ) THEN + TAU = ZERO + ELSE + IP = MAX( IPP, N / NPP ) + N2 = 2*IP + 1 + IF( N2.GE.N ) THEN + N1 = 1 + N2 = N + ELSE IF( KEND+IP.GT.N ) THEN + N1 = N - 2*IP + ELSE IF( KEND-IP.LT.1 ) THEN + N1 = 1 + ELSE + N1 = KEND - IP + END IF + CALL DLASQ4( N2, Q( N1 ), E( N1 ), TAU, SUP ) + END IF + 40 CONTINUE + ICNT = ICNT + 1 + IF( ICNT.GT.MAXIT ) THEN + SUP = -ONE + RETURN + END IF + IF( TAU.EQ.ZERO ) THEN +* +* dqd algorithm +* + D = Q( 1 ) + DM = D + KE = 0 + DO 50 I = 1, N - 3 + QQ( I ) = D + E( I ) + D = ( D / QQ( I ) )*Q( I+1 ) + IF( DM.GT.D ) THEN + DM = D + KE = I + END IF + 50 CONTINUE + KE = KE + 1 +* +* Penultimate dqd step (in ping) +* + K2END = KE + QQ( N-2 ) = D + E( N-2 ) + D = ( D / QQ( N-2 ) )*Q( N-1 ) + IF( DM.GT.D ) THEN + DM = D + KE = N - 1 + END IF +* +* Final dqd step (in ping) +* + K1END = KE + QQ( N-1 ) = D + E( N-1 ) + D = ( D / QQ( N-1 ) )*Q( N ) + IF( DM.GT.D ) THEN + DM = D + KE = N + END IF + QQ( N ) = D + ELSE +* +* The dqds algorithm (in ping) +* + D = Q( 1 ) - TAU + DM = D + KE = 0 + IF( D.LT.ZERO ) + $ GO TO 120 + DO 60 I = 1, N - 3 + QQ( I ) = D + E( I ) + D = ( D / QQ( I ) )*Q( I+1 ) - TAU + IF( DM.GT.D ) THEN + DM = D + KE = I + IF( D.LT.ZERO ) + $ GO TO 120 + END IF + 60 CONTINUE + KE = KE + 1 +* +* Penultimate dqds step (in ping) +* + K2END = KE + QQ( N-2 ) = D + E( N-2 ) + D = ( D / QQ( N-2 ) )*Q( N-1 ) - TAU + IF( DM.GT.D ) THEN + DM = D + KE = N - 1 + IF( D.LT.ZERO ) + $ GO TO 120 + END IF +* +* Final dqds step (in ping) +* + K1END = KE + QQ( N-1 ) = D + E( N-1 ) + D = ( D / QQ( N-1 ) )*Q( N ) - TAU + IF( DM.GT.D ) THEN + DM = D + KE = N + END IF + QQ( N ) = D + END IF +* +* Convergence when QQ(N) is small (in ping) +* + IF( ABS( QQ( N ) ).LE.SIGMA*TOL2 ) THEN + QQ( N ) = ZERO + DM = ZERO + KE = N + END IF + IF( QQ( N ).LT.ZERO ) + $ GO TO 120 +* +* Non-negative qd array: Update the e's +* + DO 70 I = 1, N - 1 + EE( I ) = ( E( I ) / QQ( I ) )*Q( I+1 ) + 70 CONTINUE +* +* Updating sigma and iphase in ping +* + SIGMA = SIGMA + TAU + IPHASE = 2 + 80 CONTINUE + TOLX = SIGMA*TOL2 + TOLY = SIGMA*EPS + TOLZ = MAX( SIGMA, SMALL2 )*TOL2 +* +* Checking for deflation and convergence (in ping) +* + 90 CONTINUE + IF( N.LE.2 ) + $ RETURN +* +* Deflation: bottom 1x1 (in ping) +* + LDEF = .FALSE. + IF( EE( N-1 ).LE.TOLZ ) THEN + LDEF = .TRUE. + ELSE IF( SIGMA.GT.ZERO ) THEN + IF( EE( N-1 ).LE.EPS*( SIGMA+QQ( N ) ) ) THEN + IF( EE( N-1 )*( QQ( N ) / ( QQ( N )+SIGMA ) ).LE.TOL2* + $ ( QQ( N )+SIGMA ) ) THEN + LDEF = .TRUE. + END IF + END IF + ELSE + IF( EE( N-1 ).LE.QQ( N )*TOL2 ) THEN + LDEF = .TRUE. + END IF + END IF + IF( LDEF ) THEN + Q( N ) = QQ( N ) + SIGMA + N = N - 1 + ICONV = ICONV + 1 + GO TO 90 + END IF +* +* Deflation: bottom 2x2 (in ping) +* + LDEF = .FALSE. + IF( EE( N-2 ).LE.TOLZ ) THEN + LDEF = .TRUE. + ELSE IF( SIGMA.GT.ZERO ) THEN + T1 = SIGMA + EE( N-1 )*( SIGMA / ( SIGMA+QQ( N ) ) ) + IF( EE( N-2 )*( T1 / ( QQ( N-1 )+T1 ) ).LE.TOLY ) THEN + IF( EE( N-2 )*( QQ( N-1 ) / ( QQ( N-1 )+T1 ) ).LE.TOLX ) + $ THEN + LDEF = .TRUE. + END IF + END IF + ELSE + IF( EE( N-2 ).LE.( QQ( N ) / ( QQ( N )+EE( N-1 )+QQ( N-1 ) ) )* + $ QQ( N-1 )*TOL2 ) THEN + LDEF = .TRUE. + END IF + END IF + IF( LDEF ) THEN + QEMAX = MAX( QQ( N ), QQ( N-1 ), EE( N-1 ) ) + IF( QEMAX.NE.ZERO ) THEN + IF( QEMAX.EQ.QQ( N-1 ) ) THEN + XX = HALF*( QQ( N )+QQ( N-1 )+EE( N-1 )+QEMAX* + $ SQRT( ( ( QQ( N )-QQ( N-1 )+EE( N-1 ) ) / + $ QEMAX )**2+FOUR*EE( N-1 ) / QEMAX ) ) + ELSE IF( QEMAX.EQ.QQ( N ) ) THEN + XX = HALF*( QQ( N )+QQ( N-1 )+EE( N-1 )+QEMAX* + $ SQRT( ( ( QQ( N-1 )-QQ( N )+EE( N-1 ) ) / + $ QEMAX )**2+FOUR*EE( N-1 ) / QEMAX ) ) + ELSE + XX = HALF*( QQ( N )+QQ( N-1 )+EE( N-1 )+QEMAX* + $ SQRT( ( ( QQ( N )-QQ( N-1 )+EE( N-1 ) ) / + $ QEMAX )**2+FOUR*QQ( N-1 ) / QEMAX ) ) + END IF + YY = ( MAX( QQ( N ), QQ( N-1 ) ) / XX )* + $ MIN( QQ( N ), QQ( N-1 ) ) + ELSE + XX = ZERO + YY = ZERO + END IF + Q( N-1 ) = SIGMA + XX + Q( N ) = YY + SIGMA + N = N - 2 + ICONV = ICONV + 2 + GO TO 90 + END IF +* +* Updating bounds before going to pong +* + IF( ICONV.EQ.0 ) THEN + KEND = KE + SUP = MIN( DM, SUP-TAU ) + ELSE IF( ICONV.GT.0 ) THEN + SUP = MIN( QQ( N ), QQ( N-1 ), QQ( N-2 ), QQ( 1 ), QQ( 2 ), + $ QQ( 3 ) ) + IF( ICONV.EQ.1 ) THEN + KEND = K1END + ELSE IF( ICONV.EQ.2 ) THEN + KEND = K2END + ELSE + KEND = N + END IF + ICNT = 0 + MAXIT = 100*N + END IF +* +* Checking for splitting in ping +* + LSPLIT = .FALSE. + DO 100 KS = N - 3, 3, -1 + IF( EE( KS ).LE.TOLY ) THEN + IF( EE( KS )*( MIN( QQ( KS+1 ), + $ QQ( KS ) ) / ( MIN( QQ( KS+1 ), QQ( KS ) )+SIGMA ) ).LE. + $ TOLX ) THEN + LSPLIT = .TRUE. + GO TO 110 + END IF + END IF + 100 CONTINUE +* + KS = 2 + IF( EE( 2 ).LE.TOLZ ) THEN + LSPLIT = .TRUE. + ELSE IF( SIGMA.GT.ZERO ) THEN + T1 = SIGMA + EE( 1 )*( SIGMA / ( SIGMA+QQ( 1 ) ) ) + IF( EE( 2 )*( T1 / ( QQ( 1 )+T1 ) ).LE.TOLY ) THEN + IF( EE( 2 )*( QQ( 1 ) / ( QQ( 1 )+T1 ) ).LE.TOLX ) THEN + LSPLIT = .TRUE. + END IF + END IF + ELSE + IF( EE( 2 ).LE.( QQ( 1 ) / ( QQ( 1 )+EE( 1 )+QQ( 2 ) ) )* + $ QQ( 2 )*TOL2 ) THEN + LSPLIT = .TRUE. + END IF + END IF + IF( LSPLIT ) + $ GO TO 110 +* + KS = 1 + IF( EE( 1 ).LE.TOLZ ) THEN + LSPLIT = .TRUE. + ELSE IF( SIGMA.GT.ZERO ) THEN + IF( EE( 1 ).LE.EPS*( SIGMA+QQ( 1 ) ) ) THEN + IF( EE( 1 )*( QQ( 1 ) / ( QQ( 1 )+SIGMA ) ).LE.TOL2* + $ ( QQ( 1 )+SIGMA ) ) THEN + LSPLIT = .TRUE. + END IF + END IF + ELSE + IF( EE( 1 ).LE.QQ( 1 )*TOL2 ) THEN + LSPLIT = .TRUE. + END IF + END IF +* + 110 CONTINUE + IF( LSPLIT ) THEN + SUP = MIN( QQ( N ), QQ( N-1 ), QQ( N-2 ) ) + ISP = -( OFF+1 ) + OFF = OFF + KS + N = N - KS + KEND = MAX( 1, KEND-KS ) + E( KS ) = SIGMA + EE( KS ) = ISP + ICONV = 0 + RETURN + END IF +* +* Coincidence +* + IF( TAU.EQ.ZERO .AND. DM.LE.TOLZ .AND. KEND.NE.N .AND. ICONV.EQ. + $ 0 .AND. ICNT.GT.0 ) THEN + CALL DCOPY( N-KE, E( KE ), 1, QQ( KE ), 1 ) + QQ( N ) = ZERO + CALL DCOPY( N-KE, Q( KE+1 ), 1, EE( KE ), 1 ) + SUP = ZERO + END IF + ICONV = 0 + GO TO 130 +* +* A new shift when the previous failed (in ping) +* + 120 CONTINUE + IFL = IFL + 1 + SUP = TAU +* +* SUP is small or +* Too many bad shifts (ping) +* + IF( SUP.LE.TOLZ .OR. IFL.GE.IFLMAX ) THEN + TAU = ZERO + GO TO 40 +* +* The asymptotic shift (in ping) +* + ELSE + TAU = MAX( TAU+D, ZERO ) + IF( TAU.LE.TOLZ ) + $ TAU = ZERO + GO TO 40 + END IF +* +* the pong section of the code +* + 130 CONTINUE + IFL = 0 +* +* Compute the shift (in pong) +* + IF( KEND.EQ.0 .AND. SUP.EQ.ZERO ) THEN + TAU = ZERO + ELSE IF( ICNT.GT.0 .AND. DM.LE.TOLZ ) THEN + TAU = ZERO + ELSE + IP = MAX( IPP, N / NPP ) + N2 = 2*IP + 1 + IF( N2.GE.N ) THEN + N1 = 1 + N2 = N + ELSE IF( KEND+IP.GT.N ) THEN + N1 = N - 2*IP + ELSE IF( KEND-IP.LT.1 ) THEN + N1 = 1 + ELSE + N1 = KEND - IP + END IF + CALL DLASQ4( N2, QQ( N1 ), EE( N1 ), TAU, SUP ) + END IF + 140 CONTINUE + ICNT = ICNT + 1 + IF( ICNT.GT.MAXIT ) THEN + SUP = -SUP + RETURN + END IF + IF( TAU.EQ.ZERO ) THEN +* +* The dqd algorithm (in pong) +* + D = QQ( 1 ) + DM = D + KE = 0 + DO 150 I = 1, N - 3 + Q( I ) = D + EE( I ) + D = ( D / Q( I ) )*QQ( I+1 ) + IF( DM.GT.D ) THEN + DM = D + KE = I + END IF + 150 CONTINUE + KE = KE + 1 +* +* Penultimate dqd step (in pong) +* + K2END = KE + Q( N-2 ) = D + EE( N-2 ) + D = ( D / Q( N-2 ) )*QQ( N-1 ) + IF( DM.GT.D ) THEN + DM = D + KE = N - 1 + END IF +* +* Final dqd step (in pong) +* + K1END = KE + Q( N-1 ) = D + EE( N-1 ) + D = ( D / Q( N-1 ) )*QQ( N ) + IF( DM.GT.D ) THEN + DM = D + KE = N + END IF + Q( N ) = D + ELSE +* +* The dqds algorithm (in pong) +* + D = QQ( 1 ) - TAU + DM = D + KE = 0 + IF( D.LT.ZERO ) + $ GO TO 220 + DO 160 I = 1, N - 3 + Q( I ) = D + EE( I ) + D = ( D / Q( I ) )*QQ( I+1 ) - TAU + IF( DM.GT.D ) THEN + DM = D + KE = I + IF( D.LT.ZERO ) + $ GO TO 220 + END IF + 160 CONTINUE + KE = KE + 1 +* +* Penultimate dqds step (in pong) +* + K2END = KE + Q( N-2 ) = D + EE( N-2 ) + D = ( D / Q( N-2 ) )*QQ( N-1 ) - TAU + IF( DM.GT.D ) THEN + DM = D + KE = N - 1 + IF( D.LT.ZERO ) + $ GO TO 220 + END IF +* +* Final dqds step (in pong) +* + K1END = KE + Q( N-1 ) = D + EE( N-1 ) + D = ( D / Q( N-1 ) )*QQ( N ) - TAU + IF( DM.GT.D ) THEN + DM = D + KE = N + END IF + Q( N ) = D + END IF +* +* Convergence when is small (in pong) +* + IF( ABS( Q( N ) ).LE.SIGMA*TOL2 ) THEN + Q( N ) = ZERO + DM = ZERO + KE = N + END IF + IF( Q( N ).LT.ZERO ) + $ GO TO 220 +* +* Non-negative qd array: Update the e's +* + DO 170 I = 1, N - 1 + E( I ) = ( EE( I ) / Q( I ) )*QQ( I+1 ) + 170 CONTINUE +* +* Updating sigma and iphase in pong +* + SIGMA = SIGMA + TAU + 180 CONTINUE + IPHASE = 1 + TOLX = SIGMA*TOL2 + TOLY = SIGMA*EPS +* +* Checking for deflation and convergence (in pong) +* + 190 CONTINUE + IF( N.LE.2 ) + $ RETURN +* +* Deflation: bottom 1x1 (in pong) +* + LDEF = .FALSE. + IF( E( N-1 ).LE.TOLZ ) THEN + LDEF = .TRUE. + ELSE IF( SIGMA.GT.ZERO ) THEN + IF( E( N-1 ).LE.EPS*( SIGMA+Q( N ) ) ) THEN + IF( E( N-1 )*( Q( N ) / ( Q( N )+SIGMA ) ).LE.TOL2* + $ ( Q( N )+SIGMA ) ) THEN + LDEF = .TRUE. + END IF + END IF + ELSE + IF( E( N-1 ).LE.Q( N )*TOL2 ) THEN + LDEF = .TRUE. + END IF + END IF + IF( LDEF ) THEN + Q( N ) = Q( N ) + SIGMA + N = N - 1 + ICONV = ICONV + 1 + GO TO 190 + END IF +* +* Deflation: bottom 2x2 (in pong) +* + LDEF = .FALSE. + IF( E( N-2 ).LE.TOLZ ) THEN + LDEF = .TRUE. + ELSE IF( SIGMA.GT.ZERO ) THEN + T1 = SIGMA + E( N-1 )*( SIGMA / ( SIGMA+Q( N ) ) ) + IF( E( N-2 )*( T1 / ( Q( N-1 )+T1 ) ).LE.TOLY ) THEN + IF( E( N-2 )*( Q( N-1 ) / ( Q( N-1 )+T1 ) ).LE.TOLX ) THEN + LDEF = .TRUE. + END IF + END IF + ELSE + IF( E( N-2 ).LE.( Q( N ) / ( Q( N )+EE( N-1 )+Q( N-1 ) )*Q( N- + $ 1 ) )*TOL2 ) THEN + LDEF = .TRUE. + END IF + END IF + IF( LDEF ) THEN + QEMAX = MAX( Q( N ), Q( N-1 ), E( N-1 ) ) + IF( QEMAX.NE.ZERO ) THEN + IF( QEMAX.EQ.Q( N-1 ) ) THEN + XX = HALF*( Q( N )+Q( N-1 )+E( N-1 )+QEMAX* + $ SQRT( ( ( Q( N )-Q( N-1 )+E( N-1 ) ) / QEMAX )**2+ + $ FOUR*E( N-1 ) / QEMAX ) ) + ELSE IF( QEMAX.EQ.Q( N ) ) THEN + XX = HALF*( Q( N )+Q( N-1 )+E( N-1 )+QEMAX* + $ SQRT( ( ( Q( N-1 )-Q( N )+E( N-1 ) ) / QEMAX )**2+ + $ FOUR*E( N-1 ) / QEMAX ) ) + ELSE + XX = HALF*( Q( N )+Q( N-1 )+E( N-1 )+QEMAX* + $ SQRT( ( ( Q( N )-Q( N-1 )+E( N-1 ) ) / QEMAX )**2+ + $ FOUR*Q( N-1 ) / QEMAX ) ) + END IF + YY = ( MAX( Q( N ), Q( N-1 ) ) / XX )* + $ MIN( Q( N ), Q( N-1 ) ) + ELSE + XX = ZERO + YY = ZERO + END IF + Q( N-1 ) = SIGMA + XX + Q( N ) = YY + SIGMA + N = N - 2 + ICONV = ICONV + 2 + GO TO 190 + END IF +* +* Updating bounds before going to pong +* + IF( ICONV.EQ.0 ) THEN + KEND = KE + SUP = MIN( DM, SUP-TAU ) + ELSE IF( ICONV.GT.0 ) THEN + SUP = MIN( Q( N ), Q( N-1 ), Q( N-2 ), Q( 1 ), Q( 2 ), Q( 3 ) ) + IF( ICONV.EQ.1 ) THEN + KEND = K1END + ELSE IF( ICONV.EQ.2 ) THEN + KEND = K2END + ELSE + KEND = N + END IF + ICNT = 0 + MAXIT = 100*N + END IF +* +* Checking for splitting in pong +* + LSPLIT = .FALSE. + DO 200 KS = N - 3, 3, -1 + IF( E( KS ).LE.TOLY ) THEN + IF( E( KS )*( MIN( Q( KS+1 ), Q( KS ) ) / ( MIN( Q( KS+1 ), + $ Q( KS ) )+SIGMA ) ).LE.TOLX ) THEN + LSPLIT = .TRUE. + GO TO 210 + END IF + END IF + 200 CONTINUE +* + KS = 2 + IF( E( 2 ).LE.TOLZ ) THEN + LSPLIT = .TRUE. + ELSE IF( SIGMA.GT.ZERO ) THEN + T1 = SIGMA + E( 1 )*( SIGMA / ( SIGMA+Q( 1 ) ) ) + IF( E( 2 )*( T1 / ( Q( 1 )+T1 ) ).LE.TOLY ) THEN + IF( E( 2 )*( Q( 1 ) / ( Q( 1 )+T1 ) ).LE.TOLX ) THEN + LSPLIT = .TRUE. + END IF + END IF + ELSE + IF( E( 2 ).LE.( Q( 1 ) / ( Q( 1 )+E( 1 )+Q( 2 ) ) )*Q( 2 )* + $ TOL2 ) THEN + LSPLIT = .TRUE. + END IF + END IF + IF( LSPLIT ) + $ GO TO 210 +* + KS = 1 + IF( E( 1 ).LE.TOLZ ) THEN + LSPLIT = .TRUE. + ELSE IF( SIGMA.GT.ZERO ) THEN + IF( E( 1 ).LE.EPS*( SIGMA+Q( 1 ) ) ) THEN + IF( E( 1 )*( Q( 1 ) / ( Q( 1 )+SIGMA ) ).LE.TOL2* + $ ( Q( 1 )+SIGMA ) ) THEN + LSPLIT = .TRUE. + END IF + END IF + ELSE + IF( E( 1 ).LE.Q( 1 )*TOL2 ) THEN + LSPLIT = .TRUE. + END IF + END IF +* + 210 CONTINUE + IF( LSPLIT ) THEN + SUP = MIN( Q( N ), Q( N-1 ), Q( N-2 ) ) + ISP = OFF + 1 + OFF = OFF + KS + KEND = MAX( 1, KEND-KS ) + N = N - KS + E( KS ) = SIGMA + EE( KS ) = ISP + ICONV = 0 + RETURN + END IF +* +* Coincidence +* + IF( TAU.EQ.ZERO .AND. DM.LE.TOLZ .AND. KEND.NE.N .AND. ICONV.EQ. + $ 0 .AND. ICNT.GT.0 ) THEN + CALL DCOPY( N-KE, EE( KE ), 1, Q( KE ), 1 ) + Q( N ) = ZERO + CALL DCOPY( N-KE, QQ( KE+1 ), 1, E( KE ), 1 ) + SUP = ZERO + END IF + ICONV = 0 + GO TO 30 +* +* Computation of a new shift when the previous failed (in pong) +* + 220 CONTINUE + IFL = IFL + 1 + SUP = TAU +* +* SUP is small or +* Too many bad shifts (in pong) +* + IF( SUP.LE.TOLZ .OR. IFL.GE.IFLMAX ) THEN + TAU = ZERO + GO TO 140 +* +* The asymptotic shift (in pong) +* + ELSE + TAU = MAX( TAU+D, ZERO ) + IF( TAU.LE.TOLZ ) + $ TAU = ZERO + GO TO 140 + END IF +* +* End of DLASQ3 +* + END diff --git a/ext/lapack/dlasq4.f b/ext/lapack/dlasq4.f new file mode 100755 index 000000000..d410bae5d --- /dev/null +++ b/ext/lapack/dlasq4.f @@ -0,0 +1,103 @@ + SUBROUTINE DLASQ4( N, Q, E, TAU, SUP ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + INTEGER N + DOUBLE PRECISION SUP, TAU +* .. +* .. Array Arguments .. + DOUBLE PRECISION E( * ), Q( * ) +* .. +* +* Purpose +* ======= +* +* DLASQ4 estimates TAU, the smallest eigenvalue of a matrix. This +* routine improves the input value of SUP which is an upper bound +* for the smallest eigenvalue for this matrix . +* +* Arguments +* ========= +* +* N (input) INTEGER +* On entry, N specifies the number of rows and columns +* in the matrix. N must be at least 0. +* +* Q (input) DOUBLE PRECISION array, dimension (N) +* Q array +* +* E (input) DOUBLE PRECISION array, dimension (N) +* E array +* +* TAU (output) DOUBLE PRECISION +* Estimate of the shift +* +* SUP (input/output) DOUBLE PRECISION +* Upper bound for the smallest singular value +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D+0 ) + DOUBLE PRECISION BIS, BIS1 + PARAMETER ( BIS = 0.9999D+0, BIS1 = 0.7D+0 ) + INTEGER IFLMAX + PARAMETER ( IFLMAX = 5 ) +* .. +* .. Local Scalars .. + INTEGER I, IFL + DOUBLE PRECISION D, DM, XINF +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. Executable Statements .. + IFL = 1 + SUP = MIN( SUP, Q( 1 ), Q( 2 ), Q( 3 ), Q( N ), Q( N-1 ), + $ Q( N-2 ) ) + TAU = SUP*BIS + XINF = ZERO + 10 CONTINUE + IF( IFL.EQ.IFLMAX ) THEN + TAU = XINF + RETURN + END IF + D = Q( 1 ) - TAU + DM = D + DO 20 I = 1, N - 2 + D = ( D / ( D+E( I ) ) )*Q( I+1 ) - TAU + IF( DM.GT.D ) + $ DM = D + IF( D.LT.ZERO ) THEN + SUP = TAU + TAU = MAX( SUP*BIS1**IFL, D+TAU ) + IFL = IFL + 1 + GO TO 10 + END IF + 20 CONTINUE + D = ( D / ( D+E( N-1 ) ) )*Q( N ) - TAU + IF( DM.GT.D ) + $ DM = D + IF( D.LT.ZERO ) THEN + SUP = TAU + XINF = MAX( XINF, D+TAU ) + IF( SUP*BIS1**IFL.LE.XINF ) THEN + TAU = XINF + ELSE + TAU = SUP*BIS1**IFL + IFL = IFL + 1 + GO TO 10 + END IF + ELSE + SUP = MIN( SUP, DM+TAU ) + END IF + RETURN +* +* End of DLASQ4 +* + END diff --git a/ext/lapack/dlasr.f b/ext/lapack/dlasr.f new file mode 100755 index 000000000..9bf39ac70 --- /dev/null +++ b/ext/lapack/dlasr.f @@ -0,0 +1,325 @@ + SUBROUTINE DLASR( SIDE, PIVOT, DIRECT, M, N, C, S, A, LDA ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* October 31, 1992 +* +* .. Scalar Arguments .. + CHARACTER DIRECT, PIVOT, SIDE + INTEGER LDA, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), C( * ), S( * ) +* .. +* +* Purpose +* ======= +* +* DLASR performs the transformation +* +* A := P*A, when SIDE = 'L' or 'l' ( Left-hand side ) +* +* A := A*P', when SIDE = 'R' or 'r' ( Right-hand side ) +* +* where A is an m by n real matrix and P is an orthogonal matrix, +* consisting of a sequence of plane rotations determined by the +* parameters PIVOT and DIRECT as follows ( z = m when SIDE = 'L' or 'l' +* and z = n when SIDE = 'R' or 'r' ): +* +* When DIRECT = 'F' or 'f' ( Forward sequence ) then +* +* P = P( z - 1 )*...*P( 2 )*P( 1 ), +* +* and when DIRECT = 'B' or 'b' ( Backward sequence ) then +* +* P = P( 1 )*P( 2 )*...*P( z - 1 ), +* +* where P( k ) is a plane rotation matrix for the following planes: +* +* when PIVOT = 'V' or 'v' ( Variable pivot ), +* the plane ( k, k + 1 ) +* +* when PIVOT = 'T' or 't' ( Top pivot ), +* the plane ( 1, k + 1 ) +* +* when PIVOT = 'B' or 'b' ( Bottom pivot ), +* the plane ( k, z ) +* +* c( k ) and s( k ) must contain the cosine and sine that define the +* matrix P( k ). The two by two plane rotation part of the matrix +* P( k ), R( k ), is assumed to be of the form +* +* R( k ) = ( c( k ) s( k ) ). +* ( -s( k ) c( k ) ) +* +* This version vectorises across rows of the array A when SIDE = 'L'. +* +* Arguments +* ========= +* +* SIDE (input) CHARACTER*1 +* Specifies whether the plane rotation matrix P is applied to +* A on the left or the right. +* = 'L': Left, compute A := P*A +* = 'R': Right, compute A:= A*P' +* +* DIRECT (input) CHARACTER*1 +* Specifies whether P is a forward or backward sequence of +* plane rotations. +* = 'F': Forward, P = P( z - 1 )*...*P( 2 )*P( 1 ) +* = 'B': Backward, P = P( 1 )*P( 2 )*...*P( z - 1 ) +* +* PIVOT (input) CHARACTER*1 +* Specifies the plane for which P(k) is a plane rotation +* matrix. +* = 'V': Variable pivot, the plane (k,k+1) +* = 'T': Top pivot, the plane (1,k+1) +* = 'B': Bottom pivot, the plane (k,z) +* +* M (input) INTEGER +* The number of rows of the matrix A. If m <= 1, an immediate +* return is effected. +* +* N (input) INTEGER +* The number of columns of the matrix A. If n <= 1, an +* immediate return is effected. +* +* C, S (input) DOUBLE PRECISION arrays, dimension +* (M-1) if SIDE = 'L' +* (N-1) if SIDE = 'R' +* c(k) and s(k) contain the cosine and sine that define the +* matrix P(k). The two by two plane rotation part of the +* matrix P(k), R(k), is assumed to be of the form +* R( k ) = ( c( k ) s( k ) ). +* ( -s( k ) c( k ) ) +* +* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) +* The m by n matrix A. On exit, A is overwritten by P*A if +* SIDE = 'R' or by A*P' if SIDE = 'L'. +* +* LDA (input) INTEGER +* The leading dimension of the array A. LDA >= max(1,M). +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER I, INFO, J + DOUBLE PRECISION CTEMP, STEMP, TEMP +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. External Subroutines .. + EXTERNAL XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Executable Statements .. +* +* Test the input parameters +* + INFO = 0 + IF( .NOT.( LSAME( SIDE, 'L' ) .OR. LSAME( SIDE, 'R' ) ) ) THEN + INFO = 1 + ELSE IF( .NOT.( LSAME( PIVOT, 'V' ) .OR. LSAME( PIVOT, + $ 'T' ) .OR. LSAME( PIVOT, 'B' ) ) ) THEN + INFO = 2 + ELSE IF( .NOT.( LSAME( DIRECT, 'F' ) .OR. LSAME( DIRECT, 'B' ) ) ) + $ THEN + INFO = 3 + ELSE IF( M.LT.0 ) THEN + INFO = 4 + ELSE IF( N.LT.0 ) THEN + INFO = 5 + ELSE IF( LDA.LT.MAX( 1, M ) ) THEN + INFO = 9 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DLASR ', INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( ( M.EQ.0 ) .OR. ( N.EQ.0 ) ) + $ RETURN + IF( LSAME( SIDE, 'L' ) ) THEN +* +* Form P * A +* + IF( LSAME( PIVOT, 'V' ) ) THEN + IF( LSAME( DIRECT, 'F' ) ) THEN + DO 20 J = 1, M - 1 + CTEMP = C( J ) + STEMP = S( J ) + IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN + DO 10 I = 1, N + TEMP = A( J+1, I ) + A( J+1, I ) = CTEMP*TEMP - STEMP*A( J, I ) + A( J, I ) = STEMP*TEMP + CTEMP*A( J, I ) + 10 CONTINUE + END IF + 20 CONTINUE + ELSE IF( LSAME( DIRECT, 'B' ) ) THEN + DO 40 J = M - 1, 1, -1 + CTEMP = C( J ) + STEMP = S( J ) + IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN + DO 30 I = 1, N + TEMP = A( J+1, I ) + A( J+1, I ) = CTEMP*TEMP - STEMP*A( J, I ) + A( J, I ) = STEMP*TEMP + CTEMP*A( J, I ) + 30 CONTINUE + END IF + 40 CONTINUE + END IF + ELSE IF( LSAME( PIVOT, 'T' ) ) THEN + IF( LSAME( DIRECT, 'F' ) ) THEN + DO 60 J = 2, M + CTEMP = C( J-1 ) + STEMP = S( J-1 ) + IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN + DO 50 I = 1, N + TEMP = A( J, I ) + A( J, I ) = CTEMP*TEMP - STEMP*A( 1, I ) + A( 1, I ) = STEMP*TEMP + CTEMP*A( 1, I ) + 50 CONTINUE + END IF + 60 CONTINUE + ELSE IF( LSAME( DIRECT, 'B' ) ) THEN + DO 80 J = M, 2, -1 + CTEMP = C( J-1 ) + STEMP = S( J-1 ) + IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN + DO 70 I = 1, N + TEMP = A( J, I ) + A( J, I ) = CTEMP*TEMP - STEMP*A( 1, I ) + A( 1, I ) = STEMP*TEMP + CTEMP*A( 1, I ) + 70 CONTINUE + END IF + 80 CONTINUE + END IF + ELSE IF( LSAME( PIVOT, 'B' ) ) THEN + IF( LSAME( DIRECT, 'F' ) ) THEN + DO 100 J = 1, M - 1 + CTEMP = C( J ) + STEMP = S( J ) + IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN + DO 90 I = 1, N + TEMP = A( J, I ) + A( J, I ) = STEMP*A( M, I ) + CTEMP*TEMP + A( M, I ) = CTEMP*A( M, I ) - STEMP*TEMP + 90 CONTINUE + END IF + 100 CONTINUE + ELSE IF( LSAME( DIRECT, 'B' ) ) THEN + DO 120 J = M - 1, 1, -1 + CTEMP = C( J ) + STEMP = S( J ) + IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN + DO 110 I = 1, N + TEMP = A( J, I ) + A( J, I ) = STEMP*A( M, I ) + CTEMP*TEMP + A( M, I ) = CTEMP*A( M, I ) - STEMP*TEMP + 110 CONTINUE + END IF + 120 CONTINUE + END IF + END IF + ELSE IF( LSAME( SIDE, 'R' ) ) THEN +* +* Form A * P' +* + IF( LSAME( PIVOT, 'V' ) ) THEN + IF( LSAME( DIRECT, 'F' ) ) THEN + DO 140 J = 1, N - 1 + CTEMP = C( J ) + STEMP = S( J ) + IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN + DO 130 I = 1, M + TEMP = A( I, J+1 ) + A( I, J+1 ) = CTEMP*TEMP - STEMP*A( I, J ) + A( I, J ) = STEMP*TEMP + CTEMP*A( I, J ) + 130 CONTINUE + END IF + 140 CONTINUE + ELSE IF( LSAME( DIRECT, 'B' ) ) THEN + DO 160 J = N - 1, 1, -1 + CTEMP = C( J ) + STEMP = S( J ) + IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN + DO 150 I = 1, M + TEMP = A( I, J+1 ) + A( I, J+1 ) = CTEMP*TEMP - STEMP*A( I, J ) + A( I, J ) = STEMP*TEMP + CTEMP*A( I, J ) + 150 CONTINUE + END IF + 160 CONTINUE + END IF + ELSE IF( LSAME( PIVOT, 'T' ) ) THEN + IF( LSAME( DIRECT, 'F' ) ) THEN + DO 180 J = 2, N + CTEMP = C( J-1 ) + STEMP = S( J-1 ) + IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN + DO 170 I = 1, M + TEMP = A( I, J ) + A( I, J ) = CTEMP*TEMP - STEMP*A( I, 1 ) + A( I, 1 ) = STEMP*TEMP + CTEMP*A( I, 1 ) + 170 CONTINUE + END IF + 180 CONTINUE + ELSE IF( LSAME( DIRECT, 'B' ) ) THEN + DO 200 J = N, 2, -1 + CTEMP = C( J-1 ) + STEMP = S( J-1 ) + IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN + DO 190 I = 1, M + TEMP = A( I, J ) + A( I, J ) = CTEMP*TEMP - STEMP*A( I, 1 ) + A( I, 1 ) = STEMP*TEMP + CTEMP*A( I, 1 ) + 190 CONTINUE + END IF + 200 CONTINUE + END IF + ELSE IF( LSAME( PIVOT, 'B' ) ) THEN + IF( LSAME( DIRECT, 'F' ) ) THEN + DO 220 J = 1, N - 1 + CTEMP = C( J ) + STEMP = S( J ) + IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN + DO 210 I = 1, M + TEMP = A( I, J ) + A( I, J ) = STEMP*A( I, N ) + CTEMP*TEMP + A( I, N ) = CTEMP*A( I, N ) - STEMP*TEMP + 210 CONTINUE + END IF + 220 CONTINUE + ELSE IF( LSAME( DIRECT, 'B' ) ) THEN + DO 240 J = N - 1, 1, -1 + CTEMP = C( J ) + STEMP = S( J ) + IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN + DO 230 I = 1, M + TEMP = A( I, J ) + A( I, J ) = STEMP*A( I, N ) + CTEMP*TEMP + A( I, N ) = CTEMP*A( I, N ) - STEMP*TEMP + 230 CONTINUE + END IF + 240 CONTINUE + END IF + END IF + END IF +* + RETURN +* +* End of DLASR +* + END diff --git a/ext/lapack/dlasrt.f b/ext/lapack/dlasrt.f new file mode 100755 index 000000000..7b22eb3f1 --- /dev/null +++ b/ext/lapack/dlasrt.f @@ -0,0 +1,244 @@ + SUBROUTINE DLASRT( ID, N, D, INFO ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + CHARACTER ID + INTEGER INFO, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION D( * ) +* .. +* +* Purpose +* ======= +* +* Sort the numbers in D in increasing order (if ID = 'I') or +* in decreasing order (if ID = 'D' ). +* +* Use Quick Sort, reverting to Insertion sort on arrays of +* size <= 20. Dimension of STACK limits N to about 2**32. +* +* Arguments +* ========= +* +* ID (input) CHARACTER*1 +* = 'I': sort D in increasing order; +* = 'D': sort D in decreasing order. +* +* N (input) INTEGER +* The length of the array D. +* +* D (input/output) DOUBLE PRECISION array, dimension (N) +* On entry, the array to be sorted. +* On exit, D has been sorted into increasing order +* (D(1) <= ... <= D(N) ) or into decreasing order +* (D(1) >= ... >= D(N) ), depending on ID. +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument had an illegal value +* +* ===================================================================== +* +* .. Parameters .. + INTEGER SELECT + PARAMETER ( SELECT = 20 ) +* .. +* .. Local Scalars .. + INTEGER DIR, ENDD, I, J, START, STKPNT + DOUBLE PRECISION D1, D2, D3, DMNMX, TMP +* .. +* .. Local Arrays .. + INTEGER STACK( 2, 32 ) +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. External Subroutines .. + EXTERNAL XERBLA +* .. +* .. Executable Statements .. +* +* Test the input paramters. +* + INFO = 0 + DIR = -1 + IF( LSAME( ID, 'D' ) ) THEN + DIR = 0 + ELSE IF( LSAME( ID, 'I' ) ) THEN + DIR = 1 + END IF + IF( DIR.EQ.-1 ) THEN + INFO = -1 + ELSE IF( N.LT.0 ) THEN + INFO = -2 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DLASRT', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( N.LE.1 ) + $ RETURN +* + STKPNT = 1 + STACK( 1, 1 ) = 1 + STACK( 2, 1 ) = N + 10 CONTINUE + START = STACK( 1, STKPNT ) + ENDD = STACK( 2, STKPNT ) + STKPNT = STKPNT - 1 + IF( ENDD-START.LE.SELECT .AND. ENDD-START.GT.0 ) THEN +* +* Do Insertion sort on D( START:ENDD ) +* + IF( DIR.EQ.0 ) THEN +* +* Sort into decreasing order +* + DO 30 I = START + 1, ENDD + DO 20 J = I, START + 1, -1 + IF( D( J ).GT.D( J-1 ) ) THEN + DMNMX = D( J ) + D( J ) = D( J-1 ) + D( J-1 ) = DMNMX + ELSE + GO TO 30 + END IF + 20 CONTINUE + 30 CONTINUE +* + ELSE +* +* Sort into increasing order +* + DO 50 I = START + 1, ENDD + DO 40 J = I, START + 1, -1 + IF( D( J ).LT.D( J-1 ) ) THEN + DMNMX = D( J ) + D( J ) = D( J-1 ) + D( J-1 ) = DMNMX + ELSE + GO TO 50 + END IF + 40 CONTINUE + 50 CONTINUE +* + END IF +* + ELSE IF( ENDD-START.GT.SELECT ) THEN +* +* Partition D( START:ENDD ) and stack parts, largest one first +* +* Choose partition entry as median of 3 +* + D1 = D( START ) + D2 = D( ENDD ) + I = ( START+ENDD ) / 2 + D3 = D( I ) + IF( D1.LT.D2 ) THEN + IF( D3.LT.D1 ) THEN + DMNMX = D1 + ELSE IF( D3.LT.D2 ) THEN + DMNMX = D3 + ELSE + DMNMX = D2 + END IF + ELSE + IF( D3.LT.D2 ) THEN + DMNMX = D2 + ELSE IF( D3.LT.D1 ) THEN + DMNMX = D3 + ELSE + DMNMX = D1 + END IF + END IF +* + IF( DIR.EQ.0 ) THEN +* +* Sort into decreasing order +* + I = START - 1 + J = ENDD + 1 + 60 CONTINUE + 70 CONTINUE + J = J - 1 + IF( D( J ).LT.DMNMX ) + $ GO TO 70 + 80 CONTINUE + I = I + 1 + IF( D( I ).GT.DMNMX ) + $ GO TO 80 + IF( I.LT.J ) THEN + TMP = D( I ) + D( I ) = D( J ) + D( J ) = TMP + GO TO 60 + END IF + IF( J-START.GT.ENDD-J-1 ) THEN + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = START + STACK( 2, STKPNT ) = J + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = J + 1 + STACK( 2, STKPNT ) = ENDD + ELSE + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = J + 1 + STACK( 2, STKPNT ) = ENDD + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = START + STACK( 2, STKPNT ) = J + END IF + ELSE +* +* Sort into increasing order +* + I = START - 1 + J = ENDD + 1 + 90 CONTINUE + 100 CONTINUE + J = J - 1 + IF( D( J ).GT.DMNMX ) + $ GO TO 100 + 110 CONTINUE + I = I + 1 + IF( D( I ).LT.DMNMX ) + $ GO TO 110 + IF( I.LT.J ) THEN + TMP = D( I ) + D( I ) = D( J ) + D( J ) = TMP + GO TO 90 + END IF + IF( J-START.GT.ENDD-J-1 ) THEN + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = START + STACK( 2, STKPNT ) = J + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = J + 1 + STACK( 2, STKPNT ) = ENDD + ELSE + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = J + 1 + STACK( 2, STKPNT ) = ENDD + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = START + STACK( 2, STKPNT ) = J + END IF + END IF + END IF + IF( STKPNT.GT.0 ) + $ GO TO 10 + RETURN +* +* End of DLASRT +* + END diff --git a/ext/lapack/dlassq.f b/ext/lapack/dlassq.f new file mode 100755 index 000000000..9518d06ab --- /dev/null +++ b/ext/lapack/dlassq.f @@ -0,0 +1,89 @@ + SUBROUTINE DLASSQ( N, X, INCX, SCALE, SUMSQ ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* October 31, 1992 +* +* .. Scalar Arguments .. + INTEGER INCX, N + DOUBLE PRECISION SCALE, SUMSQ +* .. +* .. Array Arguments .. + DOUBLE PRECISION X( * ) +* .. +* +* Purpose +* ======= +* +* DLASSQ returns the values scl and smsq such that +* +* ( scl**2 )*smsq = x( 1 )**2 +...+ x( n )**2 + ( scale**2 )*sumsq, +* +* where x( i ) = X( 1 + ( i - 1 )*INCX ). The value of sumsq is +* assumed to be non-negative and scl returns the value +* +* scl = max( scale, abs( x( i ) ) ). +* +* scale and sumsq must be supplied in SCALE and SUMSQ and +* scl and smsq are overwritten on SCALE and SUMSQ respectively. +* +* The routine makes only one pass through the vector x. +* +* Arguments +* ========= +* +* N (input) INTEGER +* The number of elements to be used from the vector X. +* +* X (input) DOUBLE PRECISION +* The vector for which a scaled sum of squares is computed. +* x( i ) = X( 1 + ( i - 1 )*INCX ), 1 <= i <= n. +* +* INCX (input) INTEGER +* The increment between successive values of the vector X. +* INCX > 0. +* +* SCALE (input/output) DOUBLE PRECISION +* On entry, the value scale in the equation above. +* On exit, SCALE is overwritten with scl , the scaling factor +* for the sum of squares. +* +* SUMSQ (input/output) DOUBLE PRECISION +* On entry, the value sumsq in the equation above. +* On exit, SUMSQ is overwritten with smsq , the basic sum of +* squares from which scl has been factored out. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER IX + DOUBLE PRECISION ABSXI +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS +* .. +* .. Executable Statements .. +* + IF( N.GT.0 ) THEN + DO 10 IX = 1, 1 + ( N-1 )*INCX, INCX + IF( X( IX ).NE.ZERO ) THEN + ABSXI = ABS( X( IX ) ) + IF( SCALE.LT.ABSXI ) THEN + SUMSQ = 1 + SUMSQ*( SCALE / ABSXI )**2 + SCALE = ABSXI + ELSE + SUMSQ = SUMSQ + ( ABSXI / SCALE )**2 + END IF + END IF + 10 CONTINUE + END IF + RETURN +* +* End of DLASSQ +* + END diff --git a/ext/lapack/dlasv2.f b/ext/lapack/dlasv2.f new file mode 100755 index 000000000..0fc7835dc --- /dev/null +++ b/ext/lapack/dlasv2.f @@ -0,0 +1,250 @@ + SUBROUTINE DLASV2( F, G, H, SSMIN, SSMAX, SNR, CSR, SNL, CSL ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* October 31, 1992 +* +* .. Scalar Arguments .. + DOUBLE PRECISION CSL, CSR, F, G, H, SNL, SNR, SSMAX, SSMIN +* .. +* +* Purpose +* ======= +* +* DLASV2 computes the singular value decomposition of a 2-by-2 +* triangular matrix +* [ F G ] +* [ 0 H ]. +* On return, abs(SSMAX) is the larger singular value, abs(SSMIN) is the +* smaller singular value, and (CSL,SNL) and (CSR,SNR) are the left and +* right singular vectors for abs(SSMAX), giving the decomposition +* +* [ CSL SNL ] [ F G ] [ CSR -SNR ] = [ SSMAX 0 ] +* [-SNL CSL ] [ 0 H ] [ SNR CSR ] [ 0 SSMIN ]. +* +* Arguments +* ========= +* +* F (input) DOUBLE PRECISION +* The (1,1) element of the 2-by-2 matrix. +* +* G (input) DOUBLE PRECISION +* The (1,2) element of the 2-by-2 matrix. +* +* H (input) DOUBLE PRECISION +* The (2,2) element of the 2-by-2 matrix. +* +* SSMIN (output) DOUBLE PRECISION +* abs(SSMIN) is the smaller singular value. +* +* SSMAX (output) DOUBLE PRECISION +* abs(SSMAX) is the larger singular value. +* +* SNL (output) DOUBLE PRECISION +* CSL (output) DOUBLE PRECISION +* The vector (CSL, SNL) is a unit left singular vector for the +* singular value abs(SSMAX). +* +* SNR (output) DOUBLE PRECISION +* CSR (output) DOUBLE PRECISION +* The vector (CSR, SNR) is a unit right singular vector for the +* singular value abs(SSMAX). +* +* Further Details +* =============== +* +* Any input parameter may be aliased with any output parameter. +* +* Barring over/underflow and assuming a guard digit in subtraction, all +* output quantities are correct to within a few units in the last +* place (ulps). +* +* In IEEE arithmetic, the code works correctly if one matrix element is +* infinite. +* +* Overflow will not occur unless the largest singular value itself +* overflows or is within a few ulps of overflow. (On machines with +* partial overflow, like the Cray, overflow may occur if the largest +* singular value is within a factor of 2 of overflow.) +* +* Underflow is harmless if underflow is gradual. Otherwise, results +* may correspond to a matrix modified by perturbations of size near +* the underflow threshold. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D0 ) + DOUBLE PRECISION HALF + PARAMETER ( HALF = 0.5D0 ) + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D0 ) + DOUBLE PRECISION TWO + PARAMETER ( TWO = 2.0D0 ) + DOUBLE PRECISION FOUR + PARAMETER ( FOUR = 4.0D0 ) +* .. +* .. Local Scalars .. + LOGICAL GASMAL, SWAP + INTEGER PMAX + DOUBLE PRECISION A, CLT, CRT, D, FA, FT, GA, GT, HA, HT, L, M, + $ MM, R, S, SLT, SRT, T, TEMP, TSIGN, TT +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, SIGN, SQRT +* .. +* .. External Functions .. + DOUBLE PRECISION DLAMCH + EXTERNAL DLAMCH +* .. +* .. Executable Statements .. +* + FT = F + FA = ABS( FT ) + HT = H + HA = ABS( H ) +* +* PMAX points to the maximum absolute element of matrix +* PMAX = 1 if F largest in absolute values +* PMAX = 2 if G largest in absolute values +* PMAX = 3 if H largest in absolute values +* + PMAX = 1 + SWAP = ( HA.GT.FA ) + IF( SWAP ) THEN + PMAX = 3 + TEMP = FT + FT = HT + HT = TEMP + TEMP = FA + FA = HA + HA = TEMP +* +* Now FA .ge. HA +* + END IF + GT = G + GA = ABS( GT ) + IF( GA.EQ.ZERO ) THEN +* +* Diagonal matrix +* + SSMIN = HA + SSMAX = FA + CLT = ONE + CRT = ONE + SLT = ZERO + SRT = ZERO + ELSE + GASMAL = .TRUE. + IF( GA.GT.FA ) THEN + PMAX = 2 + IF( ( FA / GA ).LT.DLAMCH( 'EPS' ) ) THEN +* +* Case of very large GA +* + GASMAL = .FALSE. + SSMAX = GA + IF( HA.GT.ONE ) THEN + SSMIN = FA / ( GA / HA ) + ELSE + SSMIN = ( FA / GA )*HA + END IF + CLT = ONE + SLT = HT / GT + SRT = ONE + CRT = FT / GT + END IF + END IF + IF( GASMAL ) THEN +* +* Normal case +* + D = FA - HA + IF( D.EQ.FA ) THEN +* +* Copes with infinite F or H +* + L = ONE + ELSE + L = D / FA + END IF +* +* Note that 0 .le. L .le. 1 +* + M = GT / FT +* +* Note that abs(M) .le. 1/macheps +* + T = TWO - L +* +* Note that T .ge. 1 +* + MM = M*M + TT = T*T + S = SQRT( TT+MM ) +* +* Note that 1 .le. S .le. 1 + 1/macheps +* + IF( L.EQ.ZERO ) THEN + R = ABS( M ) + ELSE + R = SQRT( L*L+MM ) + END IF +* +* Note that 0 .le. R .le. 1 + 1/macheps +* + A = HALF*( S+R ) +* +* Note that 1 .le. A .le. 1 + abs(M) +* + SSMIN = HA / A + SSMAX = FA*A + IF( MM.EQ.ZERO ) THEN +* +* Note that M is very tiny +* + IF( L.EQ.ZERO ) THEN + T = SIGN( TWO, FT )*SIGN( ONE, GT ) + ELSE + T = GT / SIGN( D, FT ) + M / T + END IF + ELSE + T = ( M / ( S+T )+M / ( R+L ) )*( ONE+A ) + END IF + L = SQRT( T*T+FOUR ) + CRT = TWO / L + SRT = T / L + CLT = ( CRT+SRT*M ) / A + SLT = ( HT / FT )*SRT / A + END IF + END IF + IF( SWAP ) THEN + CSL = SRT + SNL = CRT + CSR = SLT + SNR = CLT + ELSE + CSL = CLT + SNL = SLT + CSR = CRT + SNR = SRT + END IF +* +* Correct signs of SSMAX and SSMIN +* + IF( PMAX.EQ.1 ) + $ TSIGN = SIGN( ONE, CSR )*SIGN( ONE, CSL )*SIGN( ONE, F ) + IF( PMAX.EQ.2 ) + $ TSIGN = SIGN( ONE, SNR )*SIGN( ONE, CSL )*SIGN( ONE, G ) + IF( PMAX.EQ.3 ) + $ TSIGN = SIGN( ONE, SNR )*SIGN( ONE, SNL )*SIGN( ONE, H ) + SSMAX = SIGN( SSMAX, TSIGN ) + SSMIN = SIGN( SSMIN, TSIGN*SIGN( ONE, F )*SIGN( ONE, H ) ) + RETURN +* +* End of DLASV2 +* + END diff --git a/ext/lapack/dlaswp.f b/ext/lapack/dlaswp.f new file mode 100755 index 000000000..99c0dda27 --- /dev/null +++ b/ext/lapack/dlaswp.f @@ -0,0 +1,120 @@ + SUBROUTINE DLASWP( N, A, LDA, K1, K2, IPIV, INCX ) +* +* -- LAPACK auxiliary routine (version 3.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* June 30, 1999 +* +* .. Scalar Arguments .. + INTEGER INCX, K1, K2, LDA, N +* .. +* .. Array Arguments .. + INTEGER IPIV( * ) + DOUBLE PRECISION A( LDA, * ) +* .. +* +* Purpose +* ======= +* +* DLASWP performs a series of row interchanges on the matrix A. +* One row interchange is initiated for each of rows K1 through K2 of A. +* +* Arguments +* ========= +* +* N (input) INTEGER +* The number of columns of the matrix A. +* +* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) +* On entry, the matrix of column dimension N to which the row +* interchanges will be applied. +* On exit, the permuted matrix. +* +* LDA (input) INTEGER +* The leading dimension of the array A. +* +* K1 (input) INTEGER +* The first element of IPIV for which a row interchange will +* be done. +* +* K2 (input) INTEGER +* The last element of IPIV for which a row interchange will +* be done. +* +* IPIV (input) INTEGER array, dimension (M*abs(INCX)) +* The vector of pivot indices. Only the elements in positions +* K1 through K2 of IPIV are accessed. +* IPIV(K) = L implies rows K and L are to be interchanged. +* +* INCX (input) INTEGER +* The increment between successive values of IPIV. If IPIV +* is negative, the pivots are applied in reverse order. +* +* Further Details +* =============== +* +* Modified by +* R. C. Whaley, Computer Science Dept., Univ. of Tenn., Knoxville, USA +* +* ===================================================================== +* +* .. Local Scalars .. + INTEGER I, I1, I2, INC, IP, IX, IX0, J, K, N32 + DOUBLE PRECISION TEMP +* .. +* .. Executable Statements .. +* +* Interchange row I with row IPIV(I) for each of rows K1 through K2. +* + IF( INCX.GT.0 ) THEN + IX0 = K1 + I1 = K1 + I2 = K2 + INC = 1 + ELSE IF( INCX.LT.0 ) THEN + IX0 = 1 + ( 1-K2 )*INCX + I1 = K2 + I2 = K1 + INC = -1 + ELSE + RETURN + END IF +* + N32 = ( N / 32 )*32 + IF( N32.NE.0 ) THEN + DO 30 J = 1, N32, 32 + IX = IX0 + DO 20 I = I1, I2, INC + IP = IPIV( IX ) + IF( IP.NE.I ) THEN + DO 10 K = J, J + 31 + TEMP = A( I, K ) + A( I, K ) = A( IP, K ) + A( IP, K ) = TEMP + 10 CONTINUE + END IF + IX = IX + INCX + 20 CONTINUE + 30 CONTINUE + END IF + IF( N32.NE.N ) THEN + N32 = N32 + 1 + IX = IX0 + DO 50 I = I1, I2, INC + IP = IPIV( IX ) + IF( IP.NE.I ) THEN + DO 40 K = N32, N + TEMP = A( I, K ) + A( I, K ) = A( IP, K ) + A( IP, K ) = TEMP + 40 CONTINUE + END IF + IX = IX + INCX + 50 CONTINUE + END IF +* + RETURN +* +* End of DLASWP +* + END diff --git a/ext/lapack/dorg2r.f b/ext/lapack/dorg2r.f new file mode 100755 index 000000000..8ecd83de6 --- /dev/null +++ b/ext/lapack/dorg2r.f @@ -0,0 +1,130 @@ + SUBROUTINE DORG2R( M, N, K, A, LDA, TAU, WORK, INFO ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* February 29, 1992 +* +* .. Scalar Arguments .. + INTEGER INFO, K, LDA, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * ) +* .. +* +* Purpose +* ======= +* +* DORG2R generates an m by n real matrix Q with orthonormal columns, +* which is defined as the first n columns of a product of k elementary +* reflectors of order m +* +* Q = H(1) H(2) . . . H(k) +* +* as returned by DGEQRF. +* +* Arguments +* ========= +* +* M (input) INTEGER +* The number of rows of the matrix Q. M >= 0. +* +* N (input) INTEGER +* The number of columns of the matrix Q. M >= N >= 0. +* +* K (input) INTEGER +* The number of elementary reflectors whose product defines the +* matrix Q. N >= K >= 0. +* +* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) +* On entry, the i-th column must contain the vector which +* defines the elementary reflector H(i), for i = 1,2,...,k, as +* returned by DGEQRF in the first k columns of its array +* argument A. +* On exit, the m-by-n matrix Q. +* +* LDA (input) INTEGER +* The first dimension of the array A. LDA >= max(1,M). +* +* TAU (input) DOUBLE PRECISION array, dimension (K) +* TAU(i) must contain the scalar factor of the elementary +* reflector H(i), as returned by DGEQRF. +* +* WORK (workspace) DOUBLE PRECISION array, dimension (N) +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument has an illegal value +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER I, J, L +* .. +* .. External Subroutines .. + EXTERNAL DLARF, DSCAL, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 + IF( M.LT.0 ) THEN + INFO = -1 + ELSE IF( N.LT.0 .OR. N.GT.M ) THEN + INFO = -2 + ELSE IF( K.LT.0 .OR. K.GT.N ) THEN + INFO = -3 + ELSE IF( LDA.LT.MAX( 1, M ) ) THEN + INFO = -5 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DORG2R', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( N.LE.0 ) + $ RETURN +* +* Initialise columns k+1:n to columns of the unit matrix +* + DO 20 J = K + 1, N + DO 10 L = 1, M + A( L, J ) = ZERO + 10 CONTINUE + A( J, J ) = ONE + 20 CONTINUE +* + DO 40 I = K, 1, -1 +* +* Apply H(i) to A(i:m,i:n) from the left +* + IF( I.LT.N ) THEN + A( I, I ) = ONE + CALL DLARF( 'Left', M-I+1, N-I, A( I, I ), 1, TAU( I ), + $ A( I, I+1 ), LDA, WORK ) + END IF + IF( I.LT.M ) + $ CALL DSCAL( M-I, -TAU( I ), A( I+1, I ), 1 ) + A( I, I ) = ONE - TAU( I ) +* +* Set A(1:i-1,i) to zero +* + DO 30 L = 1, I - 1 + A( L, I ) = ZERO + 30 CONTINUE + 40 CONTINUE + RETURN +* +* End of DORG2R +* + END diff --git a/ext/lapack/dorgbr.f b/ext/lapack/dorgbr.f new file mode 100755 index 000000000..ed8aa80ac --- /dev/null +++ b/ext/lapack/dorgbr.f @@ -0,0 +1,223 @@ + SUBROUTINE DORGBR( VECT, M, N, K, A, LDA, TAU, WORK, LWORK, INFO ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + CHARACTER VECT + INTEGER INFO, K, LDA, LWORK, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( LWORK ) +* .. +* +* Purpose +* ======= +* +* DORGBR generates one of the real orthogonal matrices Q or P**T +* determined by DGEBRD when reducing a real matrix A to bidiagonal +* form: A = Q * B * P**T. Q and P**T are defined as products of +* elementary reflectors H(i) or G(i) respectively. +* +* If VECT = 'Q', A is assumed to have been an M-by-K matrix, and Q +* is of order M: +* if m >= k, Q = H(1) H(2) . . . H(k) and DORGBR returns the first n +* columns of Q, where m >= n >= k; +* if m < k, Q = H(1) H(2) . . . H(m-1) and DORGBR returns Q as an +* M-by-M matrix. +* +* If VECT = 'P', A is assumed to have been a K-by-N matrix, and P**T +* is of order N: +* if k < n, P**T = G(k) . . . G(2) G(1) and DORGBR returns the first m +* rows of P**T, where n >= m >= k; +* if k >= n, P**T = G(n-1) . . . G(2) G(1) and DORGBR returns P**T as +* an N-by-N matrix. +* +* Arguments +* ========= +* +* VECT (input) CHARACTER*1 +* Specifies whether the matrix Q or the matrix P**T is +* required, as defined in the transformation applied by DGEBRD: +* = 'Q': generate Q; +* = 'P': generate P**T. +* +* M (input) INTEGER +* The number of rows of the matrix Q or P**T to be returned. +* M >= 0. +* +* N (input) INTEGER +* The number of columns of the matrix Q or P**T to be returned. +* N >= 0. +* If VECT = 'Q', M >= N >= min(M,K); +* if VECT = 'P', N >= M >= min(N,K). +* +* K (input) INTEGER +* If VECT = 'Q', the number of columns in the original M-by-K +* matrix reduced by DGEBRD. +* If VECT = 'P', the number of rows in the original K-by-N +* matrix reduced by DGEBRD. +* K >= 0. +* +* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) +* On entry, the vectors which define the elementary reflectors, +* as returned by DGEBRD. +* On exit, the M-by-N matrix Q or P**T. +* +* LDA (input) INTEGER +* The leading dimension of the array A. LDA >= max(1,M). +* +* TAU (input) DOUBLE PRECISION array, dimension +* (min(M,K)) if VECT = 'Q' +* (min(N,K)) if VECT = 'P' +* TAU(i) must contain the scalar factor of the elementary +* reflector H(i) or G(i), which determines Q or P**T, as +* returned by DGEBRD in its array argument TAUQ or TAUP. +* +* WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK) +* On exit, if INFO = 0, WORK(1) returns the optimal LWORK. +* +* LWORK (input) INTEGER +* The dimension of the array WORK. LWORK >= max(1,min(M,N)). +* For optimum performance LWORK >= min(M,N)*NB, where NB +* is the optimal blocksize. +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument had an illegal value +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO, ONE + PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 ) +* .. +* .. Local Scalars .. + LOGICAL WANTQ + INTEGER I, IINFO, J +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. External Subroutines .. + EXTERNAL DORGLQ, DORGQR, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 + WANTQ = LSAME( VECT, 'Q' ) + IF( .NOT.WANTQ .AND. .NOT.LSAME( VECT, 'P' ) ) THEN + INFO = -1 + ELSE IF( M.LT.0 ) THEN + INFO = -2 + ELSE IF( N.LT.0 .OR. ( WANTQ .AND. ( N.GT.M .OR. N.LT.MIN( M, + $ K ) ) ) .OR. ( .NOT.WANTQ .AND. ( M.GT.N .OR. M.LT. + $ MIN( N, K ) ) ) ) THEN + INFO = -3 + ELSE IF( K.LT.0 ) THEN + INFO = -4 + ELSE IF( LDA.LT.MAX( 1, M ) ) THEN + INFO = -6 + ELSE IF( LWORK.LT.MAX( 1, MIN( M, N ) ) ) THEN + INFO = -9 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DORGBR', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( M.EQ.0 .OR. N.EQ.0 ) THEN + WORK( 1 ) = 1 + RETURN + END IF +* + IF( WANTQ ) THEN +* +* Form Q, determined by a call to DGEBRD to reduce an m-by-k +* matrix +* + IF( M.GE.K ) THEN +* +* If m >= k, assume m >= n >= k +* + CALL DORGQR( M, N, K, A, LDA, TAU, WORK, LWORK, IINFO ) +* + ELSE +* +* If m < k, assume m = n +* +* Shift the vectors which define the elementary reflectors one +* column to the right, and set the first row and column of Q +* to those of the unit matrix +* + DO 20 J = M, 2, -1 + A( 1, J ) = ZERO + DO 10 I = J + 1, M + A( I, J ) = A( I, J-1 ) + 10 CONTINUE + 20 CONTINUE + A( 1, 1 ) = ONE + DO 30 I = 2, M + A( I, 1 ) = ZERO + 30 CONTINUE + IF( M.GT.1 ) THEN +* +* Form Q(2:m,2:m) +* + CALL DORGQR( M-1, M-1, M-1, A( 2, 2 ), LDA, TAU, WORK, + $ LWORK, IINFO ) + END IF + END IF + ELSE +* +* Form P', determined by a call to DGEBRD to reduce a k-by-n +* matrix +* + IF( K.LT.N ) THEN +* +* If k < n, assume k <= m <= n +* + CALL DORGLQ( M, N, K, A, LDA, TAU, WORK, LWORK, IINFO ) +* + ELSE +* +* If k >= n, assume m = n +* +* Shift the vectors which define the elementary reflectors one +* row downward, and set the first row and column of P' to +* those of the unit matrix +* + A( 1, 1 ) = ONE + DO 40 I = 2, N + A( I, 1 ) = ZERO + 40 CONTINUE + DO 60 J = 2, N + DO 50 I = J - 1, 2, -1 + A( I, J ) = A( I-1, J ) + 50 CONTINUE + A( 1, J ) = ZERO + 60 CONTINUE + IF( N.GT.1 ) THEN +* +* Form P'(2:n,2:n) +* + CALL DORGLQ( N-1, N-1, N-1, A( 2, 2 ), LDA, TAU, WORK, + $ LWORK, IINFO ) + END IF + END IF + END IF + RETURN +* +* End of DORGBR +* + END diff --git a/ext/lapack/dorgl2.f b/ext/lapack/dorgl2.f new file mode 100755 index 000000000..76274955d --- /dev/null +++ b/ext/lapack/dorgl2.f @@ -0,0 +1,134 @@ + SUBROUTINE DORGL2( M, N, K, A, LDA, TAU, WORK, INFO ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* February 29, 1992 +* +* .. Scalar Arguments .. + INTEGER INFO, K, LDA, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * ) +* .. +* +* Purpose +* ======= +* +* DORGL2 generates an m by n real matrix Q with orthonormal rows, +* which is defined as the first m rows of a product of k elementary +* reflectors of order n +* +* Q = H(k) . . . H(2) H(1) +* +* as returned by DGELQF. +* +* Arguments +* ========= +* +* M (input) INTEGER +* The number of rows of the matrix Q. M >= 0. +* +* N (input) INTEGER +* The number of columns of the matrix Q. N >= M. +* +* K (input) INTEGER +* The number of elementary reflectors whose product defines the +* matrix Q. M >= K >= 0. +* +* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) +* On entry, the i-th row must contain the vector which defines +* the elementary reflector H(i), for i = 1,2,...,k, as returned +* by DGELQF in the first k rows of its array argument A. +* On exit, the m-by-n matrix Q. +* +* LDA (input) INTEGER +* The first dimension of the array A. LDA >= max(1,M). +* +* TAU (input) DOUBLE PRECISION array, dimension (K) +* TAU(i) must contain the scalar factor of the elementary +* reflector H(i), as returned by DGELQF. +* +* WORK (workspace) DOUBLE PRECISION array, dimension (M) +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument has an illegal value +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER I, J, L +* .. +* .. External Subroutines .. + EXTERNAL DLARF, DSCAL, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 + IF( M.LT.0 ) THEN + INFO = -1 + ELSE IF( N.LT.M ) THEN + INFO = -2 + ELSE IF( K.LT.0 .OR. K.GT.M ) THEN + INFO = -3 + ELSE IF( LDA.LT.MAX( 1, M ) ) THEN + INFO = -5 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DORGL2', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( M.LE.0 ) + $ RETURN +* + IF( K.LT.M ) THEN +* +* Initialise rows k+1:m to rows of the unit matrix +* + DO 20 J = 1, N + DO 10 L = K + 1, M + A( L, J ) = ZERO + 10 CONTINUE + IF( J.GT.K .AND. J.LE.M ) + $ A( J, J ) = ONE + 20 CONTINUE + END IF +* + DO 40 I = K, 1, -1 +* +* Apply H(i) to A(i:m,i:n) from the right +* + IF( I.LT.N ) THEN + IF( I.LT.M ) THEN + A( I, I ) = ONE + CALL DLARF( 'Right', M-I, N-I+1, A( I, I ), LDA, + $ TAU( I ), A( I+1, I ), LDA, WORK ) + END IF + CALL DSCAL( N-I, -TAU( I ), A( I, I+1 ), LDA ) + END IF + A( I, I ) = ONE - TAU( I ) +* +* Set A(1:i-1,i) to zero +* + DO 30 L = 1, I - 1 + A( I, L ) = ZERO + 30 CONTINUE + 40 CONTINUE + RETURN +* +* End of DORGL2 +* + END diff --git a/ext/lapack/dorglq.f b/ext/lapack/dorglq.f new file mode 100755 index 000000000..a266be514 --- /dev/null +++ b/ext/lapack/dorglq.f @@ -0,0 +1,207 @@ + SUBROUTINE DORGLQ( M, N, K, A, LDA, TAU, WORK, LWORK, INFO ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + INTEGER INFO, K, LDA, LWORK, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( LWORK ) +* .. +* +* Purpose +* ======= +* +* DORGLQ generates an M-by-N real matrix Q with orthonormal rows, +* which is defined as the first M rows of a product of K elementary +* reflectors of order N +* +* Q = H(k) . . . H(2) H(1) +* +* as returned by DGELQF. +* +* Arguments +* ========= +* +* M (input) INTEGER +* The number of rows of the matrix Q. M >= 0. +* +* N (input) INTEGER +* The number of columns of the matrix Q. N >= M. +* +* K (input) INTEGER +* The number of elementary reflectors whose product defines the +* matrix Q. M >= K >= 0. +* +* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) +* On entry, the i-th row must contain the vector which defines +* the elementary reflector H(i), for i = 1,2,...,k, as returned +* by DGELQF in the first k rows of its array argument A. +* On exit, the M-by-N matrix Q. +* +* LDA (input) INTEGER +* The first dimension of the array A. LDA >= max(1,M). +* +* TAU (input) DOUBLE PRECISION array, dimension (K) +* TAU(i) must contain the scalar factor of the elementary +* reflector H(i), as returned by DGELQF. +* +* WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK) +* On exit, if INFO = 0, WORK(1) returns the optimal LWORK. +* +* LWORK (input) INTEGER +* The dimension of the array WORK. LWORK >= max(1,M). +* For optimum performance LWORK >= M*NB, where NB is +* the optimal blocksize. +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument has an illegal value +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER I, IB, IINFO, IWS, J, KI, KK, L, LDWORK, NB, + $ NBMIN, NX +* .. +* .. External Subroutines .. + EXTERNAL DLARFB, DLARFT, DORGL2, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. External Functions .. + INTEGER ILAENV + EXTERNAL ILAENV +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 + IF( M.LT.0 ) THEN + INFO = -1 + ELSE IF( N.LT.M ) THEN + INFO = -2 + ELSE IF( K.LT.0 .OR. K.GT.M ) THEN + INFO = -3 + ELSE IF( LDA.LT.MAX( 1, M ) ) THEN + INFO = -5 + ELSE IF( LWORK.LT.MAX( 1, M ) ) THEN + INFO = -8 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DORGLQ', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( M.LE.0 ) THEN + WORK( 1 ) = 1 + RETURN + END IF +* +* Determine the block size. +* + NB = ILAENV( 1, 'DORGLQ', ' ', M, N, K, -1 ) + NBMIN = 2 + NX = 0 + IWS = M + IF( NB.GT.1 .AND. NB.LT.K ) THEN +* +* Determine when to cross over from blocked to unblocked code. +* + NX = MAX( 0, ILAENV( 3, 'DORGLQ', ' ', M, N, K, -1 ) ) + IF( NX.LT.K ) THEN +* +* Determine if workspace is large enough for blocked code. +* + LDWORK = M + IWS = LDWORK*NB + IF( LWORK.LT.IWS ) THEN +* +* Not enough workspace to use optimal NB: reduce NB and +* determine the minimum value of NB. +* + NB = LWORK / LDWORK + NBMIN = MAX( 2, ILAENV( 2, 'DORGLQ', ' ', M, N, K, -1 ) ) + END IF + END IF + END IF +* + IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN +* +* Use blocked code after the last block. +* The first kk rows are handled by the block method. +* + KI = ( ( K-NX-1 ) / NB )*NB + KK = MIN( K, KI+NB ) +* +* Set A(kk+1:m,1:kk) to zero. +* + DO 20 J = 1, KK + DO 10 I = KK + 1, M + A( I, J ) = ZERO + 10 CONTINUE + 20 CONTINUE + ELSE + KK = 0 + END IF +* +* Use unblocked code for the last or only block. +* + IF( KK.LT.M ) + $ CALL DORGL2( M-KK, N-KK, K-KK, A( KK+1, KK+1 ), LDA, + $ TAU( KK+1 ), WORK, IINFO ) +* + IF( KK.GT.0 ) THEN +* +* Use blocked code +* + DO 50 I = KI + 1, 1, -NB + IB = MIN( NB, K-I+1 ) + IF( I+IB.LE.M ) THEN +* +* Form the triangular factor of the block reflector +* H = H(i) H(i+1) . . . H(i+ib-1) +* + CALL DLARFT( 'Forward', 'Rowwise', N-I+1, IB, A( I, I ), + $ LDA, TAU( I ), WORK, LDWORK ) +* +* Apply H' to A(i+ib:m,i:n) from the right +* + CALL DLARFB( 'Right', 'Transpose', 'Forward', 'Rowwise', + $ M-I-IB+1, N-I+1, IB, A( I, I ), LDA, WORK, + $ LDWORK, A( I+IB, I ), LDA, WORK( IB+1 ), + $ LDWORK ) + END IF +* +* Apply H' to columns i:n of current block +* + CALL DORGL2( IB, N-I+1, IB, A( I, I ), LDA, TAU( I ), WORK, + $ IINFO ) +* +* Set columns 1:i-1 of current block to zero +* + DO 40 J = 1, I - 1 + DO 30 L = I, I + IB - 1 + A( L, J ) = ZERO + 30 CONTINUE + 40 CONTINUE + 50 CONTINUE + END IF +* + WORK( 1 ) = IWS + RETURN +* +* End of DORGLQ +* + END diff --git a/ext/lapack/dorgqr.f b/ext/lapack/dorgqr.f new file mode 100755 index 000000000..c16ac6d83 --- /dev/null +++ b/ext/lapack/dorgqr.f @@ -0,0 +1,208 @@ + SUBROUTINE DORGQR( M, N, K, A, LDA, TAU, WORK, LWORK, INFO ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + INTEGER INFO, K, LDA, LWORK, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( LWORK ) +* .. +* +* Purpose +* ======= +* +* DORGQR generates an M-by-N real matrix Q with orthonormal columns, +* which is defined as the first N columns of a product of K elementary +* reflectors of order M +* +* Q = H(1) H(2) . . . H(k) +* +* as returned by DGEQRF. +* +* Arguments +* ========= +* +* M (input) INTEGER +* The number of rows of the matrix Q. M >= 0. +* +* N (input) INTEGER +* The number of columns of the matrix Q. M >= N >= 0. +* +* K (input) INTEGER +* The number of elementary reflectors whose product defines the +* matrix Q. N >= K >= 0. +* +* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) +* On entry, the i-th column must contain the vector which +* defines the elementary reflector H(i), for i = 1,2,...,k, as +* returned by DGEQRF in the first k columns of its array +* argument A. +* On exit, the M-by-N matrix Q. +* +* LDA (input) INTEGER +* The first dimension of the array A. LDA >= max(1,M). +* +* TAU (input) DOUBLE PRECISION array, dimension (K) +* TAU(i) must contain the scalar factor of the elementary +* reflector H(i), as returned by DGEQRF. +* +* WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK) +* On exit, if INFO = 0, WORK(1) returns the optimal LWORK. +* +* LWORK (input) INTEGER +* The dimension of the array WORK. LWORK >= max(1,N). +* For optimum performance LWORK >= N*NB, where NB is the +* optimal blocksize. +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument has an illegal value +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER I, IB, IINFO, IWS, J, KI, KK, L, LDWORK, NB, + $ NBMIN, NX +* .. +* .. External Subroutines .. + EXTERNAL DLARFB, DLARFT, DORG2R, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. External Functions .. + INTEGER ILAENV + EXTERNAL ILAENV +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 + IF( M.LT.0 ) THEN + INFO = -1 + ELSE IF( N.LT.0 .OR. N.GT.M ) THEN + INFO = -2 + ELSE IF( K.LT.0 .OR. K.GT.N ) THEN + INFO = -3 + ELSE IF( LDA.LT.MAX( 1, M ) ) THEN + INFO = -5 + ELSE IF( LWORK.LT.MAX( 1, N ) ) THEN + INFO = -8 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DORGQR', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( N.LE.0 ) THEN + WORK( 1 ) = 1 + RETURN + END IF +* +* Determine the block size. +* + NB = ILAENV( 1, 'DORGQR', ' ', M, N, K, -1 ) + NBMIN = 2 + NX = 0 + IWS = N + IF( NB.GT.1 .AND. NB.LT.K ) THEN +* +* Determine when to cross over from blocked to unblocked code. +* + NX = MAX( 0, ILAENV( 3, 'DORGQR', ' ', M, N, K, -1 ) ) + IF( NX.LT.K ) THEN +* +* Determine if workspace is large enough for blocked code. +* + LDWORK = N + IWS = LDWORK*NB + IF( LWORK.LT.IWS ) THEN +* +* Not enough workspace to use optimal NB: reduce NB and +* determine the minimum value of NB. +* + NB = LWORK / LDWORK + NBMIN = MAX( 2, ILAENV( 2, 'DORGQR', ' ', M, N, K, -1 ) ) + END IF + END IF + END IF +* + IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN +* +* Use blocked code after the last block. +* The first kk columns are handled by the block method. +* + KI = ( ( K-NX-1 ) / NB )*NB + KK = MIN( K, KI+NB ) +* +* Set A(1:kk,kk+1:n) to zero. +* + DO 20 J = KK + 1, N + DO 10 I = 1, KK + A( I, J ) = ZERO + 10 CONTINUE + 20 CONTINUE + ELSE + KK = 0 + END IF +* +* Use unblocked code for the last or only block. +* + IF( KK.LT.N ) + $ CALL DORG2R( M-KK, N-KK, K-KK, A( KK+1, KK+1 ), LDA, + $ TAU( KK+1 ), WORK, IINFO ) +* + IF( KK.GT.0 ) THEN +* +* Use blocked code +* + DO 50 I = KI + 1, 1, -NB + IB = MIN( NB, K-I+1 ) + IF( I+IB.LE.N ) THEN +* +* Form the triangular factor of the block reflector +* H = H(i) H(i+1) . . . H(i+ib-1) +* + CALL DLARFT( 'Forward', 'Columnwise', M-I+1, IB, + $ A( I, I ), LDA, TAU( I ), WORK, LDWORK ) +* +* Apply H to A(i:m,i+ib:n) from the left +* + CALL DLARFB( 'Left', 'No transpose', 'Forward', + $ 'Columnwise', M-I+1, N-I-IB+1, IB, + $ A( I, I ), LDA, WORK, LDWORK, A( I, I+IB ), + $ LDA, WORK( IB+1 ), LDWORK ) + END IF +* +* Apply H to rows i:m of current block +* + CALL DORG2R( M-I+1, IB, IB, A( I, I ), LDA, TAU( I ), WORK, + $ IINFO ) +* +* Set rows 1:i-1 of current block to zero +* + DO 40 J = I, I + IB - 1 + DO 30 L = 1, I - 1 + A( L, J ) = ZERO + 30 CONTINUE + 40 CONTINUE + 50 CONTINUE + END IF +* + WORK( 1 ) = IWS + RETURN +* +* End of DORGQR +* + END diff --git a/ext/lapack/dorm2r.f b/ext/lapack/dorm2r.f new file mode 100755 index 000000000..74dd845ef --- /dev/null +++ b/ext/lapack/dorm2r.f @@ -0,0 +1,198 @@ + SUBROUTINE DORM2R( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, + $ WORK, INFO ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* February 29, 1992 +* +* .. Scalar Arguments .. + CHARACTER SIDE, TRANS + INTEGER INFO, K, LDA, LDC, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * ) +* .. +* +* Purpose +* ======= +* +* DORM2R overwrites the general real m by n matrix C with +* +* Q * C if SIDE = 'L' and TRANS = 'N', or +* +* Q'* C if SIDE = 'L' and TRANS = 'T', or +* +* C * Q if SIDE = 'R' and TRANS = 'N', or +* +* C * Q' if SIDE = 'R' and TRANS = 'T', +* +* where Q is a real orthogonal matrix defined as the product of k +* elementary reflectors +* +* Q = H(1) H(2) . . . H(k) +* +* as returned by DGEQRF. Q is of order m if SIDE = 'L' and of order n +* if SIDE = 'R'. +* +* Arguments +* ========= +* +* SIDE (input) CHARACTER*1 +* = 'L': apply Q or Q' from the Left +* = 'R': apply Q or Q' from the Right +* +* TRANS (input) CHARACTER*1 +* = 'N': apply Q (No transpose) +* = 'T': apply Q' (Transpose) +* +* M (input) INTEGER +* The number of rows of the matrix C. M >= 0. +* +* N (input) INTEGER +* The number of columns of the matrix C. N >= 0. +* +* K (input) INTEGER +* The number of elementary reflectors whose product defines +* the matrix Q. +* If SIDE = 'L', M >= K >= 0; +* if SIDE = 'R', N >= K >= 0. +* +* A (input) DOUBLE PRECISION array, dimension (LDA,K) +* The i-th column must contain the vector which defines the +* elementary reflector H(i), for i = 1,2,...,k, as returned by +* DGEQRF in the first k columns of its array argument A. +* A is modified by the routine but restored on exit. +* +* LDA (input) INTEGER +* The leading dimension of the array A. +* If SIDE = 'L', LDA >= max(1,M); +* if SIDE = 'R', LDA >= max(1,N). +* +* TAU (input) DOUBLE PRECISION array, dimension (K) +* TAU(i) must contain the scalar factor of the elementary +* reflector H(i), as returned by DGEQRF. +* +* C (input/output) DOUBLE PRECISION array, dimension (LDC,N) +* On entry, the m by n matrix C. +* On exit, C is overwritten by Q*C or Q'*C or C*Q' or C*Q. +* +* LDC (input) INTEGER +* The leading dimension of the array C. LDC >= max(1,M). +* +* WORK (workspace) DOUBLE PRECISION array, dimension +* (N) if SIDE = 'L', +* (M) if SIDE = 'R' +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument had an illegal value +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D+0 ) +* .. +* .. Local Scalars .. + LOGICAL LEFT, NOTRAN + INTEGER I, I1, I2, I3, IC, JC, MI, NI, NQ + DOUBLE PRECISION AII +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. External Subroutines .. + EXTERNAL DLARF, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 + LEFT = LSAME( SIDE, 'L' ) + NOTRAN = LSAME( TRANS, 'N' ) +* +* NQ is the order of Q +* + IF( LEFT ) THEN + NQ = M + ELSE + NQ = N + END IF + IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN + INFO = -1 + ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN + INFO = -2 + ELSE IF( M.LT.0 ) THEN + INFO = -3 + ELSE IF( N.LT.0 ) THEN + INFO = -4 + ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN + INFO = -5 + ELSE IF( LDA.LT.MAX( 1, NQ ) ) THEN + INFO = -7 + ELSE IF( LDC.LT.MAX( 1, M ) ) THEN + INFO = -10 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DORM2R', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 ) + $ RETURN +* + IF( ( LEFT .AND. .NOT.NOTRAN ) .OR. ( .NOT.LEFT .AND. NOTRAN ) ) + $ THEN + I1 = 1 + I2 = K + I3 = 1 + ELSE + I1 = K + I2 = 1 + I3 = -1 + END IF +* + IF( LEFT ) THEN + NI = N + JC = 1 + ELSE + MI = M + IC = 1 + END IF +* + DO 10 I = I1, I2, I3 + IF( LEFT ) THEN +* +* H(i) is applied to C(i:m,1:n) +* + MI = M - I + 1 + IC = I + ELSE +* +* H(i) is applied to C(1:m,i:n) +* + NI = N - I + 1 + JC = I + END IF +* +* Apply H(i) +* + AII = A( I, I ) + A( I, I ) = ONE + CALL DLARF( SIDE, MI, NI, A( I, I ), 1, TAU( I ), C( IC, JC ), + $ LDC, WORK ) + A( I, I ) = AII + 10 CONTINUE + RETURN +* +* End of DORM2R +* + END diff --git a/ext/lapack/dormbr.f b/ext/lapack/dormbr.f new file mode 100755 index 000000000..5002fb511 --- /dev/null +++ b/ext/lapack/dormbr.f @@ -0,0 +1,250 @@ + SUBROUTINE DORMBR( VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C, + $ LDC, WORK, LWORK, INFO ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + CHARACTER SIDE, TRANS, VECT + INTEGER INFO, K, LDA, LDC, LWORK, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), + $ WORK( LWORK ) +* .. +* +* Purpose +* ======= +* +* If VECT = 'Q', DORMBR overwrites the general real M-by-N matrix C +* with +* SIDE = 'L' SIDE = 'R' +* TRANS = 'N': Q * C C * Q +* TRANS = 'T': Q**T * C C * Q**T +* +* If VECT = 'P', DORMBR overwrites the general real M-by-N matrix C +* with +* SIDE = 'L' SIDE = 'R' +* TRANS = 'N': P * C C * P +* TRANS = 'T': P**T * C C * P**T +* +* Here Q and P**T are the orthogonal matrices determined by DGEBRD when +* reducing a real matrix A to bidiagonal form: A = Q * B * P**T. Q and +* P**T are defined as products of elementary reflectors H(i) and G(i) +* respectively. +* +* Let nq = m if SIDE = 'L' and nq = n if SIDE = 'R'. Thus nq is the +* order of the orthogonal matrix Q or P**T that is applied. +* +* If VECT = 'Q', A is assumed to have been an NQ-by-K matrix: +* if nq >= k, Q = H(1) H(2) . . . H(k); +* if nq < k, Q = H(1) H(2) . . . H(nq-1). +* +* If VECT = 'P', A is assumed to have been a K-by-NQ matrix: +* if k < nq, P = G(1) G(2) . . . G(k); +* if k >= nq, P = G(1) G(2) . . . G(nq-1). +* +* Arguments +* ========= +* +* VECT (input) CHARACTER*1 +* = 'Q': apply Q or Q**T; +* = 'P': apply P or P**T. +* +* SIDE (input) CHARACTER*1 +* = 'L': apply Q, Q**T, P or P**T from the Left; +* = 'R': apply Q, Q**T, P or P**T from the Right. +* +* TRANS (input) CHARACTER*1 +* = 'N': No transpose, apply Q or P; +* = 'T': Transpose, apply Q**T or P**T. +* +* M (input) INTEGER +* The number of rows of the matrix C. M >= 0. +* +* N (input) INTEGER +* The number of columns of the matrix C. N >= 0. +* +* K (input) INTEGER +* If VECT = 'Q', the number of columns in the original +* matrix reduced by DGEBRD. +* If VECT = 'P', the number of rows in the original +* matrix reduced by DGEBRD. +* K >= 0. +* +* A (input) DOUBLE PRECISION array, dimension +* (LDA,min(nq,K)) if VECT = 'Q' +* (LDA,nq) if VECT = 'P' +* The vectors which define the elementary reflectors H(i) and +* G(i), whose products determine the matrices Q and P, as +* returned by DGEBRD. +* +* LDA (input) INTEGER +* The leading dimension of the array A. +* If VECT = 'Q', LDA >= max(1,nq); +* if VECT = 'P', LDA >= max(1,min(nq,K)). +* +* TAU (input) DOUBLE PRECISION array, dimension (min(nq,K)) +* TAU(i) must contain the scalar factor of the elementary +* reflector H(i) or G(i) which determines Q or P, as returned +* by DGEBRD in the array argument TAUQ or TAUP. +* +* C (input/output) DOUBLE PRECISION array, dimension (LDC,N) +* On entry, the M-by-N matrix C. +* On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q +* or P*C or P**T*C or C*P or C*P**T. +* +* LDC (input) INTEGER +* The leading dimension of the array C. LDC >= max(1,M). +* +* WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK) +* On exit, if INFO = 0, WORK(1) returns the optimal LWORK. +* +* LWORK (input) INTEGER +* The dimension of the array WORK. +* If SIDE = 'L', LWORK >= max(1,N); +* if SIDE = 'R', LWORK >= max(1,M). +* For optimum performance LWORK >= N*NB if SIDE = 'L', and +* LWORK >= M*NB if SIDE = 'R', where NB is the optimal +* blocksize. +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument had an illegal value +* +* ===================================================================== +* +* .. Local Scalars .. + LOGICAL APPLYQ, LEFT, NOTRAN + CHARACTER TRANST + INTEGER I1, I2, IINFO, MI, NI, NQ, NW +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. External Subroutines .. + EXTERNAL DORMLQ, DORMQR, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 + APPLYQ = LSAME( VECT, 'Q' ) + LEFT = LSAME( SIDE, 'L' ) + NOTRAN = LSAME( TRANS, 'N' ) +* +* NQ is the order of Q or P and NW is the minimum dimension of WORK +* + IF( LEFT ) THEN + NQ = M + NW = N + ELSE + NQ = N + NW = M + END IF + IF( .NOT.APPLYQ .AND. .NOT.LSAME( VECT, 'P' ) ) THEN + INFO = -1 + ELSE IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN + INFO = -2 + ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN + INFO = -3 + ELSE IF( M.LT.0 ) THEN + INFO = -4 + ELSE IF( N.LT.0 ) THEN + INFO = -5 + ELSE IF( K.LT.0 ) THEN + INFO = -6 + ELSE IF( ( APPLYQ .AND. LDA.LT.MAX( 1, NQ ) ) .OR. + $ ( .NOT.APPLYQ .AND. LDA.LT.MAX( 1, MIN( NQ, K ) ) ) ) + $ THEN + INFO = -8 + ELSE IF( LDC.LT.MAX( 1, M ) ) THEN + INFO = -11 + ELSE IF( LWORK.LT.MAX( 1, NW ) ) THEN + INFO = -13 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DORMBR', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + WORK( 1 ) = 1 + IF( M.EQ.0 .OR. N.EQ.0 ) + $ RETURN +* + IF( APPLYQ ) THEN +* +* Apply Q +* + IF( NQ.GE.K ) THEN +* +* Q was determined by a call to DGEBRD with nq >= k +* + CALL DORMQR( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, + $ WORK, LWORK, IINFO ) + ELSE IF( NQ.GT.1 ) THEN +* +* Q was determined by a call to DGEBRD with nq < k +* + IF( LEFT ) THEN + MI = M - 1 + NI = N + I1 = 2 + I2 = 1 + ELSE + MI = M + NI = N - 1 + I1 = 1 + I2 = 2 + END IF + CALL DORMQR( SIDE, TRANS, MI, NI, NQ-1, A( 2, 1 ), LDA, TAU, + $ C( I1, I2 ), LDC, WORK, LWORK, IINFO ) + END IF + ELSE +* +* Apply P +* + IF( NOTRAN ) THEN + TRANST = 'T' + ELSE + TRANST = 'N' + END IF + IF( NQ.GT.K ) THEN +* +* P was determined by a call to DGEBRD with nq > k +* + CALL DORMLQ( SIDE, TRANST, M, N, K, A, LDA, TAU, C, LDC, + $ WORK, LWORK, IINFO ) + ELSE IF( NQ.GT.1 ) THEN +* +* P was determined by a call to DGEBRD with nq <= k +* + IF( LEFT ) THEN + MI = M - 1 + NI = N + I1 = 2 + I2 = 1 + ELSE + MI = M + NI = N - 1 + I1 = 1 + I2 = 2 + END IF + CALL DORMLQ( SIDE, TRANST, MI, NI, NQ-1, A( 1, 2 ), LDA, + $ TAU, C( I1, I2 ), LDC, WORK, LWORK, IINFO ) + END IF + END IF + RETURN +* +* End of DORMBR +* + END diff --git a/ext/lapack/dorml2.f b/ext/lapack/dorml2.f new file mode 100755 index 000000000..bb789d864 --- /dev/null +++ b/ext/lapack/dorml2.f @@ -0,0 +1,198 @@ + SUBROUTINE DORML2( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, + $ WORK, INFO ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* February 29, 1992 +* +* .. Scalar Arguments .. + CHARACTER SIDE, TRANS + INTEGER INFO, K, LDA, LDC, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * ) +* .. +* +* Purpose +* ======= +* +* DORML2 overwrites the general real m by n matrix C with +* +* Q * C if SIDE = 'L' and TRANS = 'N', or +* +* Q'* C if SIDE = 'L' and TRANS = 'T', or +* +* C * Q if SIDE = 'R' and TRANS = 'N', or +* +* C * Q' if SIDE = 'R' and TRANS = 'T', +* +* where Q is a real orthogonal matrix defined as the product of k +* elementary reflectors +* +* Q = H(k) . . . H(2) H(1) +* +* as returned by DGELQF. Q is of order m if SIDE = 'L' and of order n +* if SIDE = 'R'. +* +* Arguments +* ========= +* +* SIDE (input) CHARACTER*1 +* = 'L': apply Q or Q' from the Left +* = 'R': apply Q or Q' from the Right +* +* TRANS (input) CHARACTER*1 +* = 'N': apply Q (No transpose) +* = 'T': apply Q' (Transpose) +* +* M (input) INTEGER +* The number of rows of the matrix C. M >= 0. +* +* N (input) INTEGER +* The number of columns of the matrix C. N >= 0. +* +* K (input) INTEGER +* The number of elementary reflectors whose product defines +* the matrix Q. +* If SIDE = 'L', M >= K >= 0; +* if SIDE = 'R', N >= K >= 0. +* +* A (input) DOUBLE PRECISION array, dimension +* (LDA,M) if SIDE = 'L', +* (LDA,N) if SIDE = 'R' +* The i-th row must contain the vector which defines the +* elementary reflector H(i), for i = 1,2,...,k, as returned by +* DGELQF in the first k rows of its array argument A. +* A is modified by the routine but restored on exit. +* +* LDA (input) INTEGER +* The leading dimension of the array A. LDA >= max(1,K). +* +* TAU (input) DOUBLE PRECISION array, dimension (K) +* TAU(i) must contain the scalar factor of the elementary +* reflector H(i), as returned by DGELQF. +* +* C (input/output) DOUBLE PRECISION array, dimension (LDC,N) +* On entry, the m by n matrix C. +* On exit, C is overwritten by Q*C or Q'*C or C*Q' or C*Q. +* +* LDC (input) INTEGER +* The leading dimension of the array C. LDC >= max(1,M). +* +* WORK (workspace) DOUBLE PRECISION array, dimension +* (N) if SIDE = 'L', +* (M) if SIDE = 'R' +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument had an illegal value +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D+0 ) +* .. +* .. Local Scalars .. + LOGICAL LEFT, NOTRAN + INTEGER I, I1, I2, I3, IC, JC, MI, NI, NQ + DOUBLE PRECISION AII +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. External Subroutines .. + EXTERNAL DLARF, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 + LEFT = LSAME( SIDE, 'L' ) + NOTRAN = LSAME( TRANS, 'N' ) +* +* NQ is the order of Q +* + IF( LEFT ) THEN + NQ = M + ELSE + NQ = N + END IF + IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN + INFO = -1 + ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN + INFO = -2 + ELSE IF( M.LT.0 ) THEN + INFO = -3 + ELSE IF( N.LT.0 ) THEN + INFO = -4 + ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN + INFO = -5 + ELSE IF( LDA.LT.MAX( 1, K ) ) THEN + INFO = -7 + ELSE IF( LDC.LT.MAX( 1, M ) ) THEN + INFO = -10 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DORML2', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 ) + $ RETURN +* + IF( ( LEFT .AND. NOTRAN ) .OR. ( .NOT.LEFT .AND. .NOT.NOTRAN ) ) + $ THEN + I1 = 1 + I2 = K + I3 = 1 + ELSE + I1 = K + I2 = 1 + I3 = -1 + END IF +* + IF( LEFT ) THEN + NI = N + JC = 1 + ELSE + MI = M + IC = 1 + END IF +* + DO 10 I = I1, I2, I3 + IF( LEFT ) THEN +* +* H(i) is applied to C(i:m,1:n) +* + MI = M - I + 1 + IC = I + ELSE +* +* H(i) is applied to C(1:m,i:n) +* + NI = N - I + 1 + JC = I + END IF +* +* Apply H(i) +* + AII = A( I, I ) + A( I, I ) = ONE + CALL DLARF( SIDE, MI, NI, A( I, I ), LDA, TAU( I ), + $ C( IC, JC ), LDC, WORK ) + A( I, I ) = AII + 10 CONTINUE + RETURN +* +* End of DORML2 +* + END diff --git a/ext/lapack/dormlq.f b/ext/lapack/dormlq.f new file mode 100755 index 000000000..cb5c9fae3 --- /dev/null +++ b/ext/lapack/dormlq.f @@ -0,0 +1,254 @@ + SUBROUTINE DORMLQ( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, + $ WORK, LWORK, INFO ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + CHARACTER SIDE, TRANS + INTEGER INFO, K, LDA, LDC, LWORK, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), + $ WORK( LWORK ) +* .. +* +* Purpose +* ======= +* +* DORMLQ overwrites the general real M-by-N matrix C with +* +* SIDE = 'L' SIDE = 'R' +* TRANS = 'N': Q * C C * Q +* TRANS = 'T': Q**T * C C * Q**T +* +* where Q is a real orthogonal matrix defined as the product of k +* elementary reflectors +* +* Q = H(k) . . . H(2) H(1) +* +* as returned by DGELQF. Q is of order M if SIDE = 'L' and of order N +* if SIDE = 'R'. +* +* Arguments +* ========= +* +* SIDE (input) CHARACTER*1 +* = 'L': apply Q or Q**T from the Left; +* = 'R': apply Q or Q**T from the Right. +* +* TRANS (input) CHARACTER*1 +* = 'N': No transpose, apply Q; +* = 'T': Transpose, apply Q**T. +* +* M (input) INTEGER +* The number of rows of the matrix C. M >= 0. +* +* N (input) INTEGER +* The number of columns of the matrix C. N >= 0. +* +* K (input) INTEGER +* The number of elementary reflectors whose product defines +* the matrix Q. +* If SIDE = 'L', M >= K >= 0; +* if SIDE = 'R', N >= K >= 0. +* +* A (input) DOUBLE PRECISION array, dimension +* (LDA,M) if SIDE = 'L', +* (LDA,N) if SIDE = 'R' +* The i-th row must contain the vector which defines the +* elementary reflector H(i), for i = 1,2,...,k, as returned by +* DGELQF in the first k rows of its array argument A. +* A is modified by the routine but restored on exit. +* +* LDA (input) INTEGER +* The leading dimension of the array A. LDA >= max(1,K). +* +* TAU (input) DOUBLE PRECISION array, dimension (K) +* TAU(i) must contain the scalar factor of the elementary +* reflector H(i), as returned by DGELQF. +* +* C (input/output) DOUBLE PRECISION array, dimension (LDC,N) +* On entry, the M-by-N matrix C. +* On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q. +* +* LDC (input) INTEGER +* The leading dimension of the array C. LDC >= max(1,M). +* +* WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK) +* On exit, if INFO = 0, WORK(1) returns the optimal LWORK. +* +* LWORK (input) INTEGER +* The dimension of the array WORK. +* If SIDE = 'L', LWORK >= max(1,N); +* if SIDE = 'R', LWORK >= max(1,M). +* For optimum performance LWORK >= N*NB if SIDE = 'L', and +* LWORK >= M*NB if SIDE = 'R', where NB is the optimal +* blocksize. +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument had an illegal value +* +* ===================================================================== +* +* .. Parameters .. + INTEGER NBMAX, LDT + PARAMETER ( NBMAX = 64, LDT = NBMAX+1 ) +* .. +* .. Local Scalars .. + LOGICAL LEFT, NOTRAN + CHARACTER TRANST + INTEGER I, I1, I2, I3, IB, IC, IINFO, IWS, JC, LDWORK, + $ MI, NB, NBMIN, NI, NQ, NW +* .. +* .. Local Arrays .. + DOUBLE PRECISION T( LDT, NBMAX ) +* .. +* .. External Functions .. + LOGICAL LSAME + INTEGER ILAENV + EXTERNAL LSAME, ILAENV +* .. +* .. External Subroutines .. + EXTERNAL DLARFB, DLARFT, DORML2, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 + LEFT = LSAME( SIDE, 'L' ) + NOTRAN = LSAME( TRANS, 'N' ) +* +* NQ is the order of Q and NW is the minimum dimension of WORK +* + IF( LEFT ) THEN + NQ = M + NW = N + ELSE + NQ = N + NW = M + END IF + IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN + INFO = -1 + ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN + INFO = -2 + ELSE IF( M.LT.0 ) THEN + INFO = -3 + ELSE IF( N.LT.0 ) THEN + INFO = -4 + ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN + INFO = -5 + ELSE IF( LDA.LT.MAX( 1, K ) ) THEN + INFO = -7 + ELSE IF( LDC.LT.MAX( 1, M ) ) THEN + INFO = -10 + ELSE IF( LWORK.LT.MAX( 1, NW ) ) THEN + INFO = -12 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DORMLQ', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 ) THEN + WORK( 1 ) = 1 + RETURN + END IF +* +* Determine the block size. NB may be at most NBMAX, where NBMAX +* is used to define the local array T. +* + NB = MIN( NBMAX, ILAENV( 1, 'DORMLQ', SIDE // TRANS, M, N, K, + $ -1 ) ) + NBMIN = 2 + LDWORK = NW + IF( NB.GT.1 .AND. NB.LT.K ) THEN + IWS = NW*NB + IF( LWORK.LT.IWS ) THEN + NB = LWORK / LDWORK + NBMIN = MAX( 2, ILAENV( 2, 'DORMLQ', SIDE // TRANS, M, N, K, + $ -1 ) ) + END IF + ELSE + IWS = NW + END IF +* + IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN +* +* Use unblocked code +* + CALL DORML2( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, + $ IINFO ) + ELSE +* +* Use blocked code +* + IF( ( LEFT .AND. NOTRAN ) .OR. + $ ( .NOT.LEFT .AND. .NOT.NOTRAN ) ) THEN + I1 = 1 + I2 = K + I3 = NB + ELSE + I1 = ( ( K-1 ) / NB )*NB + 1 + I2 = 1 + I3 = -NB + END IF +* + IF( LEFT ) THEN + NI = N + JC = 1 + ELSE + MI = M + IC = 1 + END IF +* + IF( NOTRAN ) THEN + TRANST = 'T' + ELSE + TRANST = 'N' + END IF +* + DO 10 I = I1, I2, I3 + IB = MIN( NB, K-I+1 ) +* +* Form the triangular factor of the block reflector +* H = H(i) H(i+1) . . . H(i+ib-1) +* + CALL DLARFT( 'Forward', 'Rowwise', NQ-I+1, IB, A( I, I ), + $ LDA, TAU( I ), T, LDT ) + IF( LEFT ) THEN +* +* H or H' is applied to C(i:m,1:n) +* + MI = M - I + 1 + IC = I + ELSE +* +* H or H' is applied to C(1:m,i:n) +* + NI = N - I + 1 + JC = I + END IF +* +* Apply H or H' +* + CALL DLARFB( SIDE, TRANST, 'Forward', 'Rowwise', MI, NI, IB, + $ A( I, I ), LDA, T, LDT, C( IC, JC ), LDC, WORK, + $ LDWORK ) + 10 CONTINUE + END IF + WORK( 1 ) = IWS + RETURN +* +* End of DORMLQ +* + END diff --git a/ext/lapack/dormqr.f b/ext/lapack/dormqr.f new file mode 100755 index 000000000..0700bcdbf --- /dev/null +++ b/ext/lapack/dormqr.f @@ -0,0 +1,247 @@ + SUBROUTINE DORMQR( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, + $ WORK, LWORK, INFO ) +* +* -- LAPACK routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + CHARACTER SIDE, TRANS + INTEGER INFO, K, LDA, LDC, LWORK, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), + $ WORK( LWORK ) +* .. +* +* Purpose +* ======= +* +* DORMQR overwrites the general real M-by-N matrix C with +* +* SIDE = 'L' SIDE = 'R' +* TRANS = 'N': Q * C C * Q +* TRANS = 'T': Q**T * C C * Q**T +* +* where Q is a real orthogonal matrix defined as the product of k +* elementary reflectors +* +* Q = H(1) H(2) . . . H(k) +* +* as returned by DGEQRF. Q is of order M if SIDE = 'L' and of order N +* if SIDE = 'R'. +* +* Arguments +* ========= +* +* SIDE (input) CHARACTER*1 +* = 'L': apply Q or Q**T from the Left; +* = 'R': apply Q or Q**T from the Right. +* +* TRANS (input) CHARACTER*1 +* = 'N': No transpose, apply Q; +* = 'T': Transpose, apply Q**T. +* +* M (input) INTEGER +* The number of rows of the matrix C. M >= 0. +* +* N (input) INTEGER +* The number of columns of the matrix C. N >= 0. +* +* K (input) INTEGER +* The number of elementary reflectors whose product defines +* the matrix Q. +* If SIDE = 'L', M >= K >= 0; +* if SIDE = 'R', N >= K >= 0. +* +* A (input) DOUBLE PRECISION array, dimension (LDA,K) +* The i-th column must contain the vector which defines the +* elementary reflector H(i), for i = 1,2,...,k, as returned by +* DGEQRF in the first k columns of its array argument A. +* A is modified by the routine but restored on exit. +* +* LDA (input) INTEGER +* The leading dimension of the array A. +* If SIDE = 'L', LDA >= max(1,M); +* if SIDE = 'R', LDA >= max(1,N). +* +* TAU (input) DOUBLE PRECISION array, dimension (K) +* TAU(i) must contain the scalar factor of the elementary +* reflector H(i), as returned by DGEQRF. +* +* C (input/output) DOUBLE PRECISION array, dimension (LDC,N) +* On entry, the M-by-N matrix C. +* On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q. +* +* LDC (input) INTEGER +* The leading dimension of the array C. LDC >= max(1,M). +* +* WORK (workspace/output) DOUBLE PRECISION array, dimension (LWORK) +* On exit, if INFO = 0, WORK(1) returns the optimal LWORK. +* +* LWORK (input) INTEGER +* The dimension of the array WORK. +* If SIDE = 'L', LWORK >= max(1,N); +* if SIDE = 'R', LWORK >= max(1,M). +* For optimum performance LWORK >= N*NB if SIDE = 'L', and +* LWORK >= M*NB if SIDE = 'R', where NB is the optimal +* blocksize. +* +* INFO (output) INTEGER +* = 0: successful exit +* < 0: if INFO = -i, the i-th argument had an illegal value +* +* ===================================================================== +* +* .. Parameters .. + INTEGER NBMAX, LDT + PARAMETER ( NBMAX = 64, LDT = NBMAX+1 ) +* .. +* .. Local Scalars .. + LOGICAL LEFT, NOTRAN + INTEGER I, I1, I2, I3, IB, IC, IINFO, IWS, JC, LDWORK, + $ MI, NB, NBMIN, NI, NQ, NW +* .. +* .. Local Arrays .. + DOUBLE PRECISION T( LDT, NBMAX ) +* .. +* .. External Functions .. + LOGICAL LSAME + INTEGER ILAENV + EXTERNAL LSAME, ILAENV +* .. +* .. External Subroutines .. + EXTERNAL DLARFB, DLARFT, DORM2R, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 + LEFT = LSAME( SIDE, 'L' ) + NOTRAN = LSAME( TRANS, 'N' ) +* +* NQ is the order of Q and NW is the minimum dimension of WORK +* + IF( LEFT ) THEN + NQ = M + NW = N + ELSE + NQ = N + NW = M + END IF + IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN + INFO = -1 + ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THEN + INFO = -2 + ELSE IF( M.LT.0 ) THEN + INFO = -3 + ELSE IF( N.LT.0 ) THEN + INFO = -4 + ELSE IF( K.LT.0 .OR. K.GT.NQ ) THEN + INFO = -5 + ELSE IF( LDA.LT.MAX( 1, NQ ) ) THEN + INFO = -7 + ELSE IF( LDC.LT.MAX( 1, M ) ) THEN + INFO = -10 + ELSE IF( LWORK.LT.MAX( 1, NW ) ) THEN + INFO = -12 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DORMQR', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 ) THEN + WORK( 1 ) = 1 + RETURN + END IF +* +* Determine the block size. NB may be at most NBMAX, where NBMAX +* is used to define the local array T. +* + NB = MIN( NBMAX, ILAENV( 1, 'DORMQR', SIDE // TRANS, M, N, K, + $ -1 ) ) + NBMIN = 2 + LDWORK = NW + IF( NB.GT.1 .AND. NB.LT.K ) THEN + IWS = NW*NB + IF( LWORK.LT.IWS ) THEN + NB = LWORK / LDWORK + NBMIN = MAX( 2, ILAENV( 2, 'DORMQR', SIDE // TRANS, M, N, K, + $ -1 ) ) + END IF + ELSE + IWS = NW + END IF +* + IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN +* +* Use unblocked code +* + CALL DORM2R( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, + $ IINFO ) + ELSE +* +* Use blocked code +* + IF( ( LEFT .AND. .NOT.NOTRAN ) .OR. + $ ( .NOT.LEFT .AND. NOTRAN ) ) THEN + I1 = 1 + I2 = K + I3 = NB + ELSE + I1 = ( ( K-1 ) / NB )*NB + 1 + I2 = 1 + I3 = -NB + END IF +* + IF( LEFT ) THEN + NI = N + JC = 1 + ELSE + MI = M + IC = 1 + END IF +* + DO 10 I = I1, I2, I3 + IB = MIN( NB, K-I+1 ) +* +* Form the triangular factor of the block reflector +* H = H(i) H(i+1) . . . H(i+ib-1) +* + CALL DLARFT( 'Forward', 'Columnwise', NQ-I+1, IB, A( I, I ), + $ LDA, TAU( I ), T, LDT ) + IF( LEFT ) THEN +* +* H or H' is applied to C(i:m,1:n) +* + MI = M - I + 1 + IC = I + ELSE +* +* H or H' is applied to C(1:m,i:n) +* + NI = N - I + 1 + JC = I + END IF +* +* Apply H or H' +* + CALL DLARFB( SIDE, TRANS, 'Forward', 'Columnwise', MI, NI, + $ IB, A( I, I ), LDA, T, LDT, C( IC, JC ), LDC, + $ WORK, LDWORK ) + 10 CONTINUE + END IF + WORK( 1 ) = IWS + RETURN +* +* End of DORMQR +* + END diff --git a/ext/lapack/drscl.f b/ext/lapack/drscl.f new file mode 100755 index 000000000..00628b300 --- /dev/null +++ b/ext/lapack/drscl.f @@ -0,0 +1,115 @@ + SUBROUTINE DRSCL( N, SA, SX, INCX ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + INTEGER INCX, N + DOUBLE PRECISION SA +* .. +* .. Array Arguments .. + DOUBLE PRECISION SX( * ) +* .. +* +* Purpose +* ======= +* +* DRSCL multiplies an n-element real vector x by the real scalar 1/a. +* This is done without overflow or underflow as long as +* the final result x/a does not overflow or underflow. +* +* Arguments +* ========= +* +* N (input) INTEGER +* The number of components of the vector x. +* +* SA (input) DOUBLE PRECISION +* The scalar a which is used to divide each component of x. +* SA must be >= 0, or the subroutine will divide by zero. +* +* SX (input/output) DOUBLE PRECISION array, dimension +* (1+(N-1)*abs(INCX)) +* The n-element vector x. +* +* INCX (input) INTEGER +* The increment between successive values of the vector SX. +* > 0: SX(1) = X(1) and SX(1+(i-1)*INCX) = x(i), 1< i<= n +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + LOGICAL DONE + DOUBLE PRECISION BIGNUM, CDEN, CDEN1, CNUM, CNUM1, MUL, SMLNUM +* .. +* .. External Functions .. + DOUBLE PRECISION DLAMCH + EXTERNAL DLAMCH +* .. +* .. External Subroutines .. + EXTERNAL DLABAD, DSCAL +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS +* .. +* .. Executable Statements .. +* +* Quick return if possible +* + IF( N.LE.0 ) + $ RETURN +* +* Get machine parameters +* + SMLNUM = DLAMCH( 'S' ) + BIGNUM = ONE / SMLNUM + CALL DLABAD( SMLNUM, BIGNUM ) +* +* Initialize the denominator to SA and the numerator to 1. +* + CDEN = SA + CNUM = ONE +* + 10 CONTINUE + CDEN1 = CDEN*SMLNUM + CNUM1 = CNUM / BIGNUM + IF( ABS( CDEN1 ).GT.ABS( CNUM ) .AND. CNUM.NE.ZERO ) THEN +* +* Pre-multiply X by SMLNUM if CDEN is large compared to CNUM. +* + MUL = SMLNUM + DONE = .FALSE. + CDEN = CDEN1 + ELSE IF( ABS( CNUM1 ).GT.ABS( CDEN ) ) THEN +* +* Pre-multiply X by BIGNUM if CDEN is small compared to CNUM. +* + MUL = BIGNUM + DONE = .FALSE. + CNUM = CNUM1 + ELSE +* +* Multiply X by CNUM / CDEN and return. +* + MUL = CNUM / CDEN + DONE = .TRUE. + END IF +* +* Scale the vector X by MUL +* + CALL DSCAL( N, MUL, SX, INCX ) +* + IF( .NOT.DONE ) + $ GO TO 10 +* + RETURN +* +* End of DRSCL +* + END diff --git a/ext/lapack/ilaenv.f b/ext/lapack/ilaenv.f new file mode 100755 index 000000000..e3d296a88 --- /dev/null +++ b/ext/lapack/ilaenv.f @@ -0,0 +1,506 @@ + INTEGER FUNCTION ILAENV( ISPEC, NAME, OPTS, N1, N2, N3, + $ N4 ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + CHARACTER*( * ) NAME, OPTS + INTEGER ISPEC, N1, N2, N3, N4 +* .. +* +* Purpose +* ======= +* +* ILAENV is called from the LAPACK routines to choose problem-dependent +* parameters for the local environment. See ISPEC for a description of +* the parameters. +* +* This version provides a set of parameters which should give good, +* but not optimal, performance on many of the currently available +* computers. Users are encouraged to modify this subroutine to set +* the tuning parameters for their particular machine using the option +* and problem size information in the arguments. +* +* This routine will not function correctly if it is converted to all +* lower case. Converting it to all upper case is allowed. +* +* Arguments +* ========= +* +* ISPEC (input) INTEGER +* Specifies the parameter to be returned as the value of +* ILAENV. +* = 1: the optimal blocksize; if this value is 1, an unblocked +* algorithm will give the best performance. +* = 2: the minimum block size for which the block routine +* should be used; if the usable block size is less than +* this value, an unblocked routine should be used. +* = 3: the crossover point (in a block routine, for N less +* than this value, an unblocked routine should be used) +* = 4: the number of shifts, used in the nonsymmetric +* eigenvalue routines +* = 5: the minimum column dimension for blocking to be used; +* rectangular blocks must have dimension at least k by m, +* where k is given by ILAENV(2,...) and m by ILAENV(5,...) +* = 6: the crossover point for the SVD (when reducing an m by n +* matrix to bidiagonal form, if max(m,n)/min(m,n) exceeds +* this value, a QR factorization is used first to reduce +* the matrix to a triangular form.) +* = 7: the number of processors +* = 8: the crossover point for the multishift QR and QZ methods +* for nonsymmetric eigenvalue problems. +* +* NAME (input) CHARACTER*(*) +* The name of the calling subroutine, in either upper case or +* lower case. +* +* OPTS (input) CHARACTER*(*) +* The character options to the subroutine NAME, concatenated +* into a single character string. For example, UPLO = 'U', +* TRANS = 'T', and DIAG = 'N' for a triangular routine would +* be specified as OPTS = 'UTN'. +* +* N1 (input) INTEGER +* N2 (input) INTEGER +* N3 (input) INTEGER +* N4 (input) INTEGER +* Problem dimensions for the subroutine NAME; these may not all +* be required. +* +* (ILAENV) (output) INTEGER +* >= 0: the value of the parameter specified by ISPEC +* < 0: if ILAENV = -k, the k-th argument had an illegal value. +* +* Further Details +* =============== +* +* The following conventions have been used when calling ILAENV from the +* LAPACK routines: +* 1) OPTS is a concatenation of all of the character options to +* subroutine NAME, in the same order that they appear in the +* argument list for NAME, even if they are not used in determining +* the value of the parameter specified by ISPEC. +* 2) The problem dimensions N1, N2, N3, N4 are specified in the order +* that they appear in the argument list for NAME. N1 is used +* first, N2 second, and so on, and unused problem dimensions are +* passed a value of -1. +* 3) The parameter value returned by ILAENV is checked for validity in +* the calling subroutine. For example, ILAENV is used to retrieve +* the optimal blocksize for STRTRI as follows: +* +* NB = ILAENV( 1, 'STRTRI', UPLO // DIAG, N, -1, -1, -1 ) +* IF( NB.LE.1 ) NB = MAX( 1, N ) +* +* ===================================================================== +* +* .. Local Scalars .. + LOGICAL CNAME, SNAME + CHARACTER*1 C1 + CHARACTER*2 C2, C4 + CHARACTER*3 C3 + CHARACTER*6 SUBNAM + INTEGER I, IC, IZ, NB, NBMIN, NX +* .. +* .. Intrinsic Functions .. + INTRINSIC CHAR, ICHAR, INT, MIN, REAL +* .. +* .. Executable Statements .. +* + GO TO ( 100, 100, 100, 400, 500, 600, 700, 800 ) ISPEC +* +* Invalid value for ISPEC +* + ILAENV = -1 + RETURN +* + 100 CONTINUE +* +* Convert NAME to upper case if the first character is lower case. +* + ILAENV = 1 + SUBNAM = NAME + IC = ICHAR( SUBNAM( 1:1 ) ) + IZ = ICHAR( 'Z' ) + IF( IZ.EQ.90 .OR. IZ.EQ.122 ) THEN +* +* ASCII character set +* + IF( IC.GE.97 .AND. IC.LE.122 ) THEN + SUBNAM( 1:1 ) = CHAR( IC-32 ) + DO 10 I = 2, 6 + IC = ICHAR( SUBNAM( I:I ) ) + IF( IC.GE.97 .AND. IC.LE.122 ) + $ SUBNAM( I:I ) = CHAR( IC-32 ) + 10 CONTINUE + END IF +* + ELSE IF( IZ.EQ.233 .OR. IZ.EQ.169 ) THEN +* +* EBCDIC character set +* + IF( ( IC.GE.129 .AND. IC.LE.137 ) .OR. + $ ( IC.GE.145 .AND. IC.LE.153 ) .OR. + $ ( IC.GE.162 .AND. IC.LE.169 ) ) THEN + SUBNAM( 1:1 ) = CHAR( IC+64 ) + DO 20 I = 2, 6 + IC = ICHAR( SUBNAM( I:I ) ) + IF( ( IC.GE.129 .AND. IC.LE.137 ) .OR. + $ ( IC.GE.145 .AND. IC.LE.153 ) .OR. + $ ( IC.GE.162 .AND. IC.LE.169 ) ) + $ SUBNAM( I:I ) = CHAR( IC+64 ) + 20 CONTINUE + END IF +* + ELSE IF( IZ.EQ.218 .OR. IZ.EQ.250 ) THEN +* +* Prime machines: ASCII+128 +* + IF( IC.GE.225 .AND. IC.LE.250 ) THEN + SUBNAM( 1:1 ) = CHAR( IC-32 ) + DO 30 I = 2, 6 + IC = ICHAR( SUBNAM( I:I ) ) + IF( IC.GE.225 .AND. IC.LE.250 ) + $ SUBNAM( I:I ) = CHAR( IC-32 ) + 30 CONTINUE + END IF + END IF +* + C1 = SUBNAM( 1:1 ) + SNAME = C1.EQ.'S' .OR. C1.EQ.'D' + CNAME = C1.EQ.'C' .OR. C1.EQ.'Z' + IF( .NOT.( CNAME .OR. SNAME ) ) + $ RETURN + C2 = SUBNAM( 2:3 ) + C3 = SUBNAM( 4:6 ) + C4 = C3( 2:3 ) +* + GO TO ( 110, 200, 300 ) ISPEC +* + 110 CONTINUE +* +* ISPEC = 1: block size +* +* In these examples, separate code is provided for setting NB for +* real and complex. We assume that NB will take the same value in +* single or double precision. +* + NB = 1 +* + IF( C2.EQ.'GE' ) THEN + IF( C3.EQ.'TRF' ) THEN + IF( SNAME ) THEN + NB = 64 + ELSE + NB = 64 + END IF + ELSE IF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR. + $ C3.EQ.'QLF' ) THEN + IF( SNAME ) THEN + NB = 32 + ELSE + NB = 32 + END IF + ELSE IF( C3.EQ.'HRD' ) THEN + IF( SNAME ) THEN + NB = 32 + ELSE + NB = 32 + END IF + ELSE IF( C3.EQ.'BRD' ) THEN + IF( SNAME ) THEN + NB = 32 + ELSE + NB = 32 + END IF + ELSE IF( C3.EQ.'TRI' ) THEN + IF( SNAME ) THEN + NB = 64 + ELSE + NB = 64 + END IF + END IF + ELSE IF( C2.EQ.'PO' ) THEN + IF( C3.EQ.'TRF' ) THEN + IF( SNAME ) THEN + NB = 64 + ELSE + NB = 64 + END IF + END IF + ELSE IF( C2.EQ.'SY' ) THEN + IF( C3.EQ.'TRF' ) THEN + IF( SNAME ) THEN + NB = 64 + ELSE + NB = 64 + END IF + ELSE IF( SNAME .AND. C3.EQ.'TRD' ) THEN + NB = 1 + ELSE IF( SNAME .AND. C3.EQ.'GST' ) THEN + NB = 64 + END IF + ELSE IF( CNAME .AND. C2.EQ.'HE' ) THEN + IF( C3.EQ.'TRF' ) THEN + NB = 64 + ELSE IF( C3.EQ.'TRD' ) THEN + NB = 1 + ELSE IF( C3.EQ.'GST' ) THEN + NB = 64 + END IF + ELSE IF( SNAME .AND. C2.EQ.'OR' ) THEN + IF( C3( 1:1 ).EQ.'G' ) THEN + IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. + $ C4.EQ.'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. + $ C4.EQ.'BR' ) THEN + NB = 32 + END IF + ELSE IF( C3( 1:1 ).EQ.'M' ) THEN + IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. + $ C4.EQ.'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. + $ C4.EQ.'BR' ) THEN + NB = 32 + END IF + END IF + ELSE IF( CNAME .AND. C2.EQ.'UN' ) THEN + IF( C3( 1:1 ).EQ.'G' ) THEN + IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. + $ C4.EQ.'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. + $ C4.EQ.'BR' ) THEN + NB = 32 + END IF + ELSE IF( C3( 1:1 ).EQ.'M' ) THEN + IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. + $ C4.EQ.'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. + $ C4.EQ.'BR' ) THEN + NB = 32 + END IF + END IF + ELSE IF( C2.EQ.'GB' ) THEN + IF( C3.EQ.'TRF' ) THEN + IF( SNAME ) THEN + IF( N4.LE.64 ) THEN + NB = 1 + ELSE + NB = 32 + END IF + ELSE + IF( N4.LE.64 ) THEN + NB = 1 + ELSE + NB = 32 + END IF + END IF + END IF + ELSE IF( C2.EQ.'PB' ) THEN + IF( C3.EQ.'TRF' ) THEN + IF( SNAME ) THEN + IF( N2.LE.64 ) THEN + NB = 1 + ELSE + NB = 32 + END IF + ELSE + IF( N2.LE.64 ) THEN + NB = 1 + ELSE + NB = 32 + END IF + END IF + END IF + ELSE IF( C2.EQ.'TR' ) THEN + IF( C3.EQ.'TRI' ) THEN + IF( SNAME ) THEN + NB = 64 + ELSE + NB = 64 + END IF + END IF + ELSE IF( C2.EQ.'LA' ) THEN + IF( C3.EQ.'UUM' ) THEN + IF( SNAME ) THEN + NB = 64 + ELSE + NB = 64 + END IF + END IF + ELSE IF( SNAME .AND. C2.EQ.'ST' ) THEN + IF( C3.EQ.'EBZ' ) THEN + NB = 1 + END IF + END IF + ILAENV = NB + RETURN +* + 200 CONTINUE +* +* ISPEC = 2: minimum block size +* + NBMIN = 2 + IF( C2.EQ.'GE' ) THEN + IF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR. + $ C3.EQ.'QLF' ) THEN + IF( SNAME ) THEN + NBMIN = 2 + ELSE + NBMIN = 2 + END IF + ELSE IF( C3.EQ.'HRD' ) THEN + IF( SNAME ) THEN + NBMIN = 2 + ELSE + NBMIN = 2 + END IF + ELSE IF( C3.EQ.'BRD' ) THEN + IF( SNAME ) THEN + NBMIN = 2 + ELSE + NBMIN = 2 + END IF + ELSE IF( C3.EQ.'TRI' ) THEN + IF( SNAME ) THEN + NBMIN = 2 + ELSE + NBMIN = 2 + END IF + END IF + ELSE IF( C2.EQ.'SY' ) THEN + IF( C3.EQ.'TRF' ) THEN + IF( SNAME ) THEN + NBMIN = 8 + ELSE + NBMIN = 8 + END IF + ELSE IF( SNAME .AND. C3.EQ.'TRD' ) THEN + NBMIN = 2 + END IF + ELSE IF( CNAME .AND. C2.EQ.'HE' ) THEN + IF( C3.EQ.'TRD' ) THEN + NBMIN = 2 + END IF + ELSE IF( SNAME .AND. C2.EQ.'OR' ) THEN + IF( C3( 1:1 ).EQ.'G' ) THEN + IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. + $ C4.EQ.'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. + $ C4.EQ.'BR' ) THEN + NBMIN = 2 + END IF + ELSE IF( C3( 1:1 ).EQ.'M' ) THEN + IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. + $ C4.EQ.'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. + $ C4.EQ.'BR' ) THEN + NBMIN = 2 + END IF + END IF + ELSE IF( CNAME .AND. C2.EQ.'UN' ) THEN + IF( C3( 1:1 ).EQ.'G' ) THEN + IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. + $ C4.EQ.'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. + $ C4.EQ.'BR' ) THEN + NBMIN = 2 + END IF + ELSE IF( C3( 1:1 ).EQ.'M' ) THEN + IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. + $ C4.EQ.'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. + $ C4.EQ.'BR' ) THEN + NBMIN = 2 + END IF + END IF + END IF + ILAENV = NBMIN + RETURN +* + 300 CONTINUE +* +* ISPEC = 3: crossover point +* + NX = 0 + IF( C2.EQ.'GE' ) THEN + IF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR. + $ C3.EQ.'QLF' ) THEN + IF( SNAME ) THEN + NX = 128 + ELSE + NX = 128 + END IF + ELSE IF( C3.EQ.'HRD' ) THEN + IF( SNAME ) THEN + NX = 128 + ELSE + NX = 128 + END IF + ELSE IF( C3.EQ.'BRD' ) THEN + IF( SNAME ) THEN + NX = 128 + ELSE + NX = 128 + END IF + END IF + ELSE IF( C2.EQ.'SY' ) THEN + IF( SNAME .AND. C3.EQ.'TRD' ) THEN + NX = 1 + END IF + ELSE IF( CNAME .AND. C2.EQ.'HE' ) THEN + IF( C3.EQ.'TRD' ) THEN + NX = 1 + END IF + ELSE IF( SNAME .AND. C2.EQ.'OR' ) THEN + IF( C3( 1:1 ).EQ.'G' ) THEN + IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. + $ C4.EQ.'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. + $ C4.EQ.'BR' ) THEN + NX = 128 + END IF + END IF + ELSE IF( CNAME .AND. C2.EQ.'UN' ) THEN + IF( C3( 1:1 ).EQ.'G' ) THEN + IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. + $ C4.EQ.'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. + $ C4.EQ.'BR' ) THEN + NX = 128 + END IF + END IF + END IF + ILAENV = NX + RETURN +* + 400 CONTINUE +* +* ISPEC = 4: number of shifts (used by xHSEQR) +* + ILAENV = 6 + RETURN +* + 500 CONTINUE +* +* ISPEC = 5: minimum column dimension (not used) +* + ILAENV = 2 + RETURN +* + 600 CONTINUE +* +* ISPEC = 6: crossover point for SVD (used by xGELSS and xGESVD) +* + ILAENV = INT( REAL( MIN( N1, N2 ) )*1.6E0 ) + RETURN +* + 700 CONTINUE +* +* ISPEC = 7: number of processors (not used) +* + ILAENV = 1 + RETURN +* + 800 CONTINUE +* +* ISPEC = 8: crossover point for multishift (used by xHSEQR) +* + ILAENV = 50 + RETURN +* +* End of ILAENV +* + END diff --git a/ext/lapack/lsame.f b/ext/lapack/lsame.f new file mode 100755 index 000000000..db133b544 --- /dev/null +++ b/ext/lapack/lsame.f @@ -0,0 +1,87 @@ + LOGICAL FUNCTION LSAME( CA, CB ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + CHARACTER CA, CB +* .. +* +* Purpose +* ======= +* +* LSAME returns .TRUE. if CA is the same letter as CB regardless of +* case. +* +* Arguments +* ========= +* +* CA (input) CHARACTER*1 +* CB (input) CHARACTER*1 +* CA and CB specify the single characters to be compared. +* +* ===================================================================== +* +* .. Intrinsic Functions .. + INTRINSIC ICHAR +* .. +* .. Local Scalars .. + INTEGER INTA, INTB, ZCODE +* .. +* .. Executable Statements .. +* +* Test if the characters are equal +* + LSAME = CA.EQ.CB + IF( LSAME ) + $ RETURN +* +* Now test for equivalence if both characters are alphabetic. +* + ZCODE = ICHAR( 'Z' ) +* +* Use 'Z' rather than 'A' so that ASCII can be detected on Prime +* machines, on which ICHAR returns a value with bit 8 set. +* ICHAR('A') on Prime machines returns 193 which is the same as +* ICHAR('A') on an EBCDIC machine. +* + INTA = ICHAR( CA ) + INTB = ICHAR( CB ) +* + IF( ZCODE.EQ.90 .OR. ZCODE.EQ.122 ) THEN +* +* ASCII is assumed - ZCODE is the ASCII code of either lower or +* upper case 'Z'. +* + IF( INTA.GE.97 .AND. INTA.LE.122 ) INTA = INTA - 32 + IF( INTB.GE.97 .AND. INTB.LE.122 ) INTB = INTB - 32 +* + ELSE IF( ZCODE.EQ.233 .OR. ZCODE.EQ.169 ) THEN +* +* EBCDIC is assumed - ZCODE is the EBCDIC code of either lower or +* upper case 'Z'. +* + IF( INTA.GE.129 .AND. INTA.LE.137 .OR. + $ INTA.GE.145 .AND. INTA.LE.153 .OR. + $ INTA.GE.162 .AND. INTA.LE.169 ) INTA = INTA + 64 + IF( INTB.GE.129 .AND. INTB.LE.137 .OR. + $ INTB.GE.145 .AND. INTB.LE.153 .OR. + $ INTB.GE.162 .AND. INTB.LE.169 ) INTB = INTB + 64 +* + ELSE IF( ZCODE.EQ.218 .OR. ZCODE.EQ.250 ) THEN +* +* ASCII is assumed, on Prime machines - ZCODE is the ASCII code +* plus 128 of either lower or upper case 'Z'. +* + IF( INTA.GE.225 .AND. INTA.LE.250 ) INTA = INTA - 32 + IF( INTB.GE.225 .AND. INTB.LE.250 ) INTB = INTB - 32 + END IF + LSAME = INTA.EQ.INTB +* +* RETURN +* +* End of LSAME +* + END diff --git a/ext/lapack/xerbla.f b/ext/lapack/xerbla.f new file mode 100755 index 000000000..618dfcf97 --- /dev/null +++ b/ext/lapack/xerbla.f @@ -0,0 +1,46 @@ + SUBROUTINE XERBLA( SRNAME, INFO ) +* +* -- LAPACK auxiliary routine (version 2.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + CHARACTER*6 SRNAME + INTEGER INFO +* .. +* +* Purpose +* ======= +* +* XERBLA is an error handler for the LAPACK routines. +* It is called by an LAPACK routine if an input parameter has an +* invalid value. A message is printed and execution stops. +* +* Installers may consider modifying the STOP statement in order to +* call system-specific exception-handling facilities. +* +* Arguments +* ========= +* +* SRNAME (input) CHARACTER*6 +* The name of the routine which called XERBLA. +* +* INFO (input) INTEGER +* The position of the invalid parameter in the parameter list +* of the calling routine. +* +* ===================================================================== +* +* .. Executable Statements .. +* + WRITE( *, FMT = 9999 )SRNAME, INFO +* + STOP +* + 9999 FORMAT( ' ** On entry to ', A6, ' parameter number ', I2, ' had ', + $ 'an illegal value' ) +* +* End of XERBLA +* + END diff --git a/ext/math/.cvsignore b/ext/math/.cvsignore new file mode 100644 index 000000000..f3c7a7c5d --- /dev/null +++ b/ext/math/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/ext/math/Makefile.in b/ext/math/Makefile.in new file mode 100755 index 000000000..d203cd0eb --- /dev/null +++ b/ext/math/Makefile.in @@ -0,0 +1,58 @@ +# +# $Source$ +# $Author$ +# $Revision$ +# $Date$ +# + +LIB = ./libctmath.a + +SUFFIXES= +SUFFIXES= .f .d .o + +F_FLAGS = @FFLAGS@ $(F77_FLAGS) + +OBJS = \ +mach.o \ +ddaspk.o \ +dgbefa.o \ +dgbsl.o \ +dgefa.o \ +dgesl.o \ +dp1vlu.o \ +dpcoef.o \ +dpolft.o \ +fdump.o \ +j4save.o \ +pcoef.o \ +polfit.o \ +pvalue.o \ +xercnt.o \ +xerhlt.o \ +xermsg.o \ +xerprn.o \ +xersve.o \ +xgetua.o + +SRCS = $(OBJS:.o=.cpp) + + +$(LIB): $(OBJS) + @ARCHIVE@ $(LIB) $(OBJS) > /dev/null + +.cpp.o: + @CXX@ -c $< @DEFS@ @CXXFLAGS@ $(INCLUDES) + +.f.o: + @F77@ -c $< $(F_FLAGS) + +clean: + $(RM) $(OBJS) $(LIB) + +depends: + echo '...' + + + + + diff --git a/ext/math/cblas.h b/ext/math/cblas.h new file mode 100755 index 000000000..8ca35aa1a --- /dev/null +++ b/ext/math/cblas.h @@ -0,0 +1,646 @@ +// -*- C++ -*- + +// ============================================= // +// die double-Versionen der BLAS Level 1 und 2 // +// ============================================= // + +#ifndef CBLAS1_H +// ============================================================================ + +// generate a plane rotation +void drotg( double *a, double *b, double *c, double *s ); + + +#if 0 +// generate a modified plane rotation +void drotmg( double *d1, double *d2, double *a, double b, double *param ); +#endif + +// apply a plane rotation +void drot( int n, double *x, int incx, double *y, int incy, double c, + double s ); + + +#if 0 +// apply a modified plane rotation +void drotm( int n, double *x, int incx, double *y, int incy, double *param ); +#endif + + +// x <=> y +void dswap( int n, double *x, int incx, double *y, int incy ); + + +// x <= a*x +void dscal( int n, double alpha, double *x, int incx ); + + +// y <= x +void dcopy( int n, const double *x, int incx, double *y, int incy ); + + +// y <= a*x+y +void daxpy( int n, double alpha, const double *x, int incx, double *y, + int incy ); + + +// dot <= x^T*y +double ddot( int n, const double *x, int incx, const double *y, int incy ); + + +// dnrm2 <= |x|_2 +double dnrm2( int n, const double *x, int incx ); + + +// asum <= |x|_1 +double dasum( int n, const double *x, int incx ); + + +// idamax <= first k such that |x_k| = max|x_i| +int idamax( int n, const double *x, int incx ); + +// ============================================================================ +#endif // CBLAS1_H + + +#ifndef CBLAS2_H +// ============================================================================ + + +enum MatrixTranspose { NoTranspose=0, Transpose=1, ConjugateTranspose=2 }; +enum MatrixTriangle { UpperTriangle=0, LowerTriangle=1 }; +enum MatrixUnitTriangular { UnitTriangular=0, NotUnitTriangular=1 }; + + +// ============================================================================ + + +// y <= alpha*A*x + beta*y, y <= alpha*A^T*x + beta*y, A-(m,n) +void dgemv( MatrixTranspose trans, int m, int n, double alpha, + const double *A, int ldA, const double *x, int incx, + double beta, double *y, int incy ); + + +// y <= alpha*A*x + beta*y, y <= alpha*A^T*x + beta*y, A-(m,n) +void dgbmv( MatrixTranspose trans, int m, int n, int kl, int ku, double alpha, + const double *A, int ldA, const double *x, int incx, double *beta, + double *y, int incy ); + + +// y <= alpha*A*x + beta*y +void dsymv( MatrixTriangle uplo, int n, double alpha, const double *A, int ldA, + const double *x, int incx, double beta, double *y, int incy ); + + +// y <= alpha*A*x + beta*y +void dsbmv( MatrixTriangle uplo, int n, int k, double alpha, double *A, + int ldA, const double *x, int incx, double beta, double *y, + int *incy ); + + +// y <= alpha*A*x + beta*y +void dspmv( MatrixTriangle uplo, int n, double alpha, const double *AP, + const double *x, int incx, double beta, double *y, int incy ); + + +// x <= A*x, x <= A^T*x +void dtrmv( MatrixTriangle uplo, MatrixTranspose trans, + MatrixUnitTriangular diag, int n, const double *A, int ldA, + double *x, int incx ); + + +// x <= A*x, x <= A^T*x +void dtbmv( MatrixTriangle uplo, MatrixTranspose trans, + MatrixUnitTriangular diag, int n, int k, const double *A, int ldA, + double *x, int incx ); + + +// x <= A*x, x <= A^T*x +void dtpmv( MatrixTriangle uplo, MatrixTranspose trans, + MatrixUnitTriangular diag, int n, int k, const double *AP, + double *x, int incx ); + + +// x <= A^{-1}*x, x <= A^{-T}*x +void dtrsv( MatrixTriangle uplo, MatrixTranspose trans, + MatrixUnitTriangular diag, int n, const double *A, int ldA, + double *x, int incx ); + + +// x <= A^{-1}*x, x <= A^{-T}*x +void dtbsv( MatrixTriangle uplo, MatrixTranspose trans, + MatrixUnitTriangular diag, int n, int k, const double *A, int ldA, + double *x, int incx ); + + +// x <= A^{-1}*x, x <= A^{-T}*x +void dtpsv( MatrixTriangle uplo, MatrixTranspose trans, + MatrixUnitTriangular diag, int n, int k, const double *AP, + double *x, int incx ); + + +// A <= alpha*x*y^T + A, A-(m,n) +void dger( int m, int n, double alpha, const double *x, int incx, + const double *y, int incy, double *A, int ldA ); + + +// A <= alpha*x*x^T + A +void dsyr( MatrixTriangle uplo, int n, double alpha, const double *x, + int incx, double *A, int ldA ); + + +// A <= alpha*x*x^T + A +void dspr( MatrixTriangle uplo, int n, double alpha, const double *x, + int incx, double *AP ); + + +// A <= alpha*x*y^T + alpha*y*x^T + A +void dsyr2( MatrixTriangle uplo, int n, double alpha, const double *x, + int incx, const double *y, int incy, double *A, int ldA ); + + +// A <= alpha*x*y^T + alpha*y*x^T + A +void dspr2( MatrixTriangle uplo, int n, double alpha, const double *x, + int incx, const double *y, int incy, double *AP ); + +// ============================================================================ +#endif // CBLAS2_H + + +#ifndef BLAS1_H +#define BLAS1_H +// ============================================================================ + +// generate a plane rotation +extern "C" +void drotg_( double *a, double *b, double *c, double *s ); + + +#if 0 +// generate a modified plane rotation +extern "C" +void drotmg_( double *d1, double *d2, double *a, double *b, double *param ); +#endif + + +// apply a plane rotation +extern "C" +void drot_( int *n, double *x, int *incx, double *y, int *incy, + double *c, double *s ); + + +#if 0 +// apply a modified plane rotation +extern "C" +void drotm_( int *n, double *x, int *incx, double *y, int *incy, + double *param ); +#endif + + +// x <=> y +extern "C" +void dswap_( const int *n, double *x, const int *incx, double *y, + const int *incy ); + +// x <= a*x +extern "C" +void dscal_( const int *n, const double *alpha, double *x, const int *incx ); + + +// y <= x +extern "C" +void dcopy_( const int *n, const double *x, const int *incx, double *y, + const int *incy ); + + +// y <= a*x+y +extern "C" +void daxpy_( const int *n, const double *alpha, const double *x, + const int *incx, double *y, const int *incy ); + + +// dot <= x^T*y +extern "C" +double ddot_( const int *n, const double *x, const int *incx, const double *y, + const int *incy ); + + +// dnrm2 <= |x|_2 +extern "C" +double dnrm2_( const int *n, const double *x, const int *incx ); + + +// asum <= |x|_1 +extern "C" +double dasum_( const int *n, const double *x, const int *incx ); + + +// idamax <= first k such that |x_k| = max|x_i| +extern "C" +int idamax_( const int *n, const double *x, const int *incx ); + + +// ============================================================================ +#endif // BLAS1_H + + + +#ifndef CBLAS1_H +#define CBLAS1_H +// ============================================================================ + + +#ifdef __linux__ // muss dnorm2 f"ur linux neu implementieren +# include +#endif + +inline +void drotg( double *a, double *b, double *c, double *s ) { + drotg_(a,b,c,s); +} + +#if 0 +inline +void drotmg( double *d1, double *d2, double *a, double b, double *param ) { + drotmg_(d1,d2,a,&b,param); +} +#endif + +inline +void drot( int n, double *x, int incx, double *y, int incy, double c, + double s ) { + drot_(&n,x,&incx,y,&incy,&c,&s); +} + +#if 0 +inline +void drotm( int n, double *x, int incx, double *y, int incy, double *param ) { + drotm_(&n,x,&incx,y,&incy,param); +} +#endif + +inline +void dswap( int n, double *x, int incx, double *y, int incy ) { + dswap_(&n,x,&incx,y,&incy); +} + +inline +void dscal( int n, double alpha, double *x, int incx ) { + int nn = n; + int incxx = incx; + double aa = alpha; + dscal_(&nn,&aa,x,&incxx); +} + +inline +void dcopy( int n, const double *x, int incx, double *y, int incy ) { + int nn = n; + int incxx = incx; + int incyy = incy; + dcopy_(&nn,x,&incxx,y,&incyy); +} + +inline +void daxpy( int n, double alpha, const double *x, int incx, double *y, + int incy ) { + double aa = alpha; + int incxx = incx; + int incyy = incy; + daxpy_(&n,&aa,x,&incxx,y,&incyy); +} + +inline +double ddot( int n, const double *x, int incx, const double *y, int incy ) { + int nn = n; + int incxx = incx; + int incyy = incy; + return ddot_(&nn,x,&incxx,y,&incyy); +} + +inline +double dnrm2( int n, const double *x, int incx ) { + int nn = n; + int incxx = incx; +#ifdef __linux__ // fehlerhafte Berechnung + double d=0.; + while ( nn-- ) + d+=(*x)*(*x), x+=incxx; + return sqrt(d); +#else // unter nicht-Linux korrekt + return dnrm2_(&nn,x,&incxx); +#endif +} + +inline +double dasum( int n, const double *x, int incx ) { + return dasum_(&n,x,&incx); +} + +inline +int idamax( int n, const double *x, int incx ) { + return idamax_(&n,x,&incx); +} + + +// ============================================================================ +#endif // CBLAS1_H + + +#ifndef BLAS2_H +#define BLAS2_H +// ============================================================================ + +// y <= alpha*A*x + beta*y, y <= alpha*A^T*x + beta*y, A-(m,n) +//extern "C" +//void dgemv_( const char *trans, const int *m, const int *n, +// const double *alpha, const double *A, const int *ldA, +// const double *x, const int *incx, +// const double *beta, double *y, const int *incy ); + + +// y <= alpha*A*x + beta*y, y <= alpha*A^T*x + beta*y, A-(m,n) +extern "C" +void dgbmv_( const char *trans, const int *m, const int *n, const int *kl, + const int *ku, const double *alpha, const double *A, + const int *ldA, const double *x, const int *incx, + const double *beta, double *y, const int *incy ); + + +// y <= alpha*A*x + beta*y +extern "C" +void dsymv_( const char *uplo, const int *n, const double *alpha, + const double *A, const int *ldA, const double *x, const int *incx, + const double *beta, double *y, const int *incy ); + + +// y <= alpha*A*x + beta*y +extern "C" +void dsbmv_( const char *uplo, const int *n, const int *k, const double *alpha, + const double *A, const int *ldA, const double *x, const int *incx, + const double *beta, double *y, const int *incy ); + + +// y <= alpha*A*x + beta*y +extern "C" +void dspmv_( const char *uplo, const int *n, const double *alpha, + const double *AP, const double *x, const int *incx, + const double *beta, double *y, const int *incy ); + + +// x <= A*x, x <= A^T*x +extern "C" +void dtrmv_( const char *uplo, const char *trans, const char *diag, + const int *n, const double *A, const int *ldA, + double *x, const int *incx ); + + +// x <= A*x, x <= A^T*x +extern "C" +void dtbmv_( const char *uplo, const char *trans, const char *diag, + const int *n, const int *k, const double *A, const int *ldA, + double *x, const int *incx ); + + +// x <= A*x, x <= A^T*x +extern "C" +void dtpmv_( const char *uplo, const char *trans, const char *diag, + const int *n, const double *AP, double *x, const int *incx ); + + +// x <= A^{-1}*x, x <= A^{-T}*x +extern "C" +void dtrsv_( const char *uplo, const char *trans, const char *diag, + const int *n, const double *A, const int *ldA, + double *x, const int *incx ); + + +// x <= A^{-1}*x, x <= A^{-T}*x +extern "C" +void dtbsv_( const char *uplo, const char *trans, const char *diag, + const int *n, const int *k, const double *A, const int *ldA, + double *x, const int *incx ); + + +// x <= A^{-1}*x, x <= A^{-T}*x +extern "C" +void dtpsv_( const char *uplo, const char *trans, const char *diag, + const int *n, const double *AP, double *x, const int *incx ); + + +// A <= alpha*x*y^T + A, A-(m,n) +extern "C" +void dger_( const int *m, const int *n, const double *alpha, const double *x, + const int *incx, const double *y, const int *incy, double *A, + const int *ldA ); + + +// A <= alpha*x*x^T + A +extern "C" +void dsyr_( const char *uplo, const int *n, const double *alpha, + const double *x, const int *incx, double *A, const int *ldA ); + + +// A <= alpha*x*x^T + A +extern "C" +void dspr_( const char *uplo, const int *n, const double *alpha, + const double *x, const int *incx, double *AP ); + + +// A <= alpha*x*y^T + alpha*y*x^T + A +extern "C" +void dsyr2_( const char *uplo, const int *n, const double *alpha, + const double *x, const int *incx, const double *y, + const int *incy, double *A, const int *ldA ); + + +// A <= alpha*x*y^T + alpha*y*x^T + A +extern "C" +void dspr2_( const char *uplo, const int *n, const double *alpha, + const double *x, const int *incx, const double *y, + const int *incy, double *AP ); + +// ============================================================================ +#endif // BLAS2_H + + +#ifndef CBLAS2_H +#define CBLAS2_H +// ============================================================================ + + +// y <= alpha*A*x + beta*y, y <= alpha*A^T*x + beta*y, A-(m,n) +inline +void dgemv( MatrixTranspose trans, int m, int n, double alpha, + const double *A, int ldA, const double *x, int incx, + double beta, double *y, int incy ) { + const char *T[3] = { "N", "T", 0 }; + int mm = m; + int nn = n; + double aa = alpha; + double bb = beta; + int ldaa = ldA; + int incxx = incx; + int incyy = incy; + dgemv_(T[(int)trans],&mm,&nn,&aa,A,&ldaa,x,&incxx,&bb,y,&incyy,1); +} + + +// y <= alpha*A*x + beta*y, y <= alpha*A^T*x + beta*y, A-(m,n) +inline +void dgbmv( MatrixTranspose trans, int m, int n, int kl, int ku, double alpha, + const double *A, int ldA, const double *x, int incx, double beta, + double *y, int incy ) { + const char *T[3] = { "N", "T" }; + dgbmv_(T[(int)trans],&m,&n,&kl,&ku,&alpha,A,&ldA,x,&incx,&beta,y,&incy); +} + +// y <= alpha*A*x + beta*y +inline +void dsymv( MatrixTriangle uplo, int n, double alpha, const double *A, int ldA, + const double *x, int incx, double beta, double *y, int incy ) { + const char *UL[2] = { "U", "L" }; + dsymv_(UL[(int)uplo],&n,&alpha,A,&ldA,x,&incx,&beta,y,&incy); +} + + +// y <= alpha*A*x + beta*y +inline +void dsbmv( MatrixTriangle uplo, int n, int k, double alpha, double *A, + int ldA, const double *x, int incx, double beta, double *y, + int incy ) { + const char *UL[2] = { "U", "L" }; + dsbmv_(UL[(int)uplo],&n,&k,&alpha,A,&ldA,x,&incx,&beta,y,&incy); +} + + +// y <= alpha*A*x + beta*y +inline +void dspmv( MatrixTriangle uplo, int n, double alpha, const double *AP, + const double *x, int incx, double beta, double *y, int incy ) { + const char *UL[2] = { "U", "L" }; + dspmv_(UL[(int)uplo],&n,&alpha,AP,x,&incx,&beta,y,&incy); +} + + +// x <= A*x, x <= A^T*x +inline +void dtrmv( MatrixTriangle uplo, MatrixTranspose trans, + MatrixUnitTriangular diag, int n, const double *A, int ldA, + double *x, int incx ) { + const char *UL[2] = { "U", "L" }; + const char *T[3] = { "N", "T", 0 }; + const char *D[2] = { "U", "N" }; + dtrmv_(UL[(int)uplo],T[(int)trans],D[(int)diag],&n,A,&ldA,x,&incx); +} + + +// x <= A*x, x <= A^T*x +inline +void dtbmv( MatrixTriangle uplo, MatrixTranspose trans, + MatrixUnitTriangular diag, int n, int k, const double *A, int ldA, + double *x, int incx ) { + const char *UL[2] = { "U", "L" }; + const char *T[3] = { "N", "T", 0 }; + const char *D[2] = { "U", "N" }; + dtbmv_(UL[(int)uplo],T[(int)trans],D[(int)diag],&n,&k,A,&ldA,x,&incx); +} + + +// x <= A*x, x <= A^T*x +inline +void dtpmv( MatrixTriangle uplo, MatrixTranspose trans, + MatrixUnitTriangular diag, int n, const double *AP, + double *x, int incx ) { + const char *UL[2] = { "U", "L" }; + const char *T[3] = { "N", "T", 0 }; + const char *D[2] = { "U", "N" }; + dtpmv_(UL[(int)uplo],T[(int)trans],D[(int)diag],&n,AP,x,&incx); +} + + +// x <= A^{-1}*x, x <= A^{-T}*x +inline +void dtrsv( MatrixTriangle uplo, MatrixTranspose trans, + MatrixUnitTriangular diag, int n, const double *A, int ldA, + double *x, int incx ) { + const char *UL[2] = { "U", "L" }; + const char *T[3] = { "N", "T", 0 }; + const char *D[2] = { "U", "N" }; + dtrsv_(UL[(int)uplo],T[(int)trans],D[(int)diag],&n,A,&ldA,x,&incx); +} + + +// x <= A^{-1}*x, x <= A^{-T}*x +inline +void dtbsv( MatrixTriangle uplo, MatrixTranspose trans, + MatrixUnitTriangular diag, int n, int k, const double *A, int ldA, + double *x, int incx ) { + const char *UL[2] = { "U", "L" }; + const char *T[3] = { "N", "T", 0 }; + const char *D[2] = { "U", "N" }; + dtbsv_(UL[(int)uplo],T[(int)trans],D[(int)diag],&n,&k,A,&ldA,x,&incx); +} + + +// x <= A^{-1}*x, x <= A^{-T}*x +inline +void dtpsv( MatrixTriangle uplo, MatrixTranspose trans, + MatrixUnitTriangular diag, int n, const double *AP, + double *x, int incx ) { + const char *UL[2] = { "U", "L" }; + const char *T[3] = { "N", "T", 0 }; + const char *D[2] = { "U", "N" }; + int nn = n; + int incxx = incx; + dtpsv_(UL[(int)uplo],T[(int)trans],D[(int)diag],&nn,AP,x,&incxx); +} + + +// A <= alpha*x*y^T + A, A-(m,n) +inline +void dger( int m, int n, double alpha, const double *x, int incx, + const double *y, int incy, double *A, int ldA ) { + dger_(&m,&n,&alpha,x,&incx,y,&incy,A,&ldA); +} + + +// A <= alpha*x*x^T + A +inline +void dsyr( MatrixTriangle uplo, int n, double alpha, const double *x, + int incx, double *A, int ldA ) { + const char *UL[2] = { "U", "L" }; + dsyr_(UL[(int)uplo],&n,&alpha,x,&incx,A,&ldA); +} + + +// A <= alpha*x*x^T + A +inline +void dspr( MatrixTriangle uplo, int n, double alpha, const double *x, + int incx, double *AP ) { + const char *UL[2] = { "U", "L" }; + dspr_(UL[(int)uplo],&n,&alpha,x,&incx,AP); +} + + +// A <= alpha*x*y^T + alpha*y*x^T + A +inline +void dsyr2( MatrixTriangle uplo, int n, double alpha, const double *x, + int incx, const double *y, int incy, double *A, int ldA ) { + const char *UL[2] = { "U", "L" }; + dsyr2_(UL[(int)uplo],&n,&alpha,x,&incx,y,&incy,A,&ldA); +} + + +// A <= alpha*x*y^T + alpha*y*x^T + A +inline +void dspr2( MatrixTriangle uplo, int n, double alpha, const double *x, + int incx, const double *y, int incy, double *AP ) { + const char *UL[2] = { "U", "L" }; + dspr2_(UL[(int)uplo],&n,&alpha,x,&incx,y,&incy,AP); +} + + +// ============================================================================ + + +#endif // CBLAS2_H diff --git a/ext/math/daux.f b/ext/math/daux.f new file mode 100755 index 000000000..08c8cc360 --- /dev/null +++ b/ext/math/daux.f @@ -0,0 +1,253 @@ +c DOUBLE PRECISION FUNCTION D1MACH (IDUM) +c INTEGER IDUM +cC----------------------------------------------------------------------- +cC THIS ROUTINE COMPUTES THE UNIT ROUNDOFF OF THE MACHINE IN DOUBLE +cC PRECISION. THIS IS DEFINED AS THE SMALLEST POSITIVE MACHINE NUMBER +cC U SUCH THAT 1.0D0 + U .NE. 1.0D0 (IN DOUBLE PRECISION). +cC----------------------------------------------------------------------- +c DOUBLE PRECISION U, COMP +c U = 1.0D0 +c 10 U = U*0.5D0 +c COMP = 1.0D0 + U +c IF (COMP .NE. 1.0D0) GO TO 10 +c D1MACH = U*2.0D0 +c RETURN +cC----------------------- END OF FUNCTION D1MACH ------------------------ +c END + +*DECK XERRWD + SUBROUTINE XERRWD (MSG, NMES, NERR, LEVEL, NI, I1, I2, NR, R1, R2) +C***BEGIN PROLOGUE XERRWD +C***SUBSIDIARY +C***PURPOSE Write error message with values. +C***LIBRARY MATHLIB +C***CATEGORY R3C +C***TYPE DOUBLE PRECISION (XERRWV-S, XERRWD-D) +C***AUTHOR Hindmarsh, Alan C., (LLNL) +C***DESCRIPTION +C +C Subroutines XERRWD, XSETF, XSETUN, and the function routine IXSAV, +C as given here, constitute a simplified version of the SLATEC error +C handling package. +C +C All arguments are input arguments. +C +C MSG = The message (character array). +C NMES = The length of MSG (number of characters). +C NERR = The error number (not used). +C LEVEL = The error level.. +C 0 or 1 means recoverable (control returns to caller). +C 2 means fatal (run is aborted--see note below). +C NI = Number of integers (0, 1, or 2) to be printed with message. +C I1,I2 = Integers to be printed, depending on NI. +C NR = Number of reals (0, 1, or 2) to be printed with message. +C R1,R2 = Reals to be printed, depending on NR. +C +C Note.. this routine is machine-dependent and specialized for use +C in limited context, in the following ways.. +C 1. The argument MSG is assumed to be of type CHARACTER, and +C the message is printed with a format of (1X,A). +C 2. The message is assumed to take only one line. +C Multi-line messages are generated by repeated calls. +C 3. If LEVEL = 2, control passes to the statement STOP +C to abort the run. This statement may be machine-dependent. +C 4. R1 and R2 are assumed to be in double precision and are printed +C in D21.13 format. +C +C***ROUTINES CALLED IXSAV +C***REVISION HISTORY (YYMMDD) +C 920831 DATE WRITTEN +C 921118 Replaced MFLGSV/LUNSAV by IXSAV. (ACH) +C 930329 Modified prologue to SLATEC format. (FNF) +C 930407 Changed MSG from CHARACTER*1 array to variable. (FNF) +C 930922 Minor cosmetic change. (FNF) +C***END PROLOGUE XERRWD +C +C*Internal Notes: +C +C For a different default logical unit number, IXSAV (or a subsidiary +C routine that it calls) will need to be modified. +C For a different run-abort command, change the statement following +C statement 100 at the end. +C----------------------------------------------------------------------- +C Subroutines called by XERRWD.. None +C Function routine called by XERRWD.. IXSAV +C----------------------------------------------------------------------- +C**End +C +C Declare arguments. +C + DOUBLE PRECISION R1, R2 + INTEGER NMES, NERR, LEVEL, NI, I1, I2, NR + CHARACTER*(*) MSG +C +C Declare local variables. +C + INTEGER LUNIT, IXSAV, MESFLG +C +C Get logical unit number and message print flag. +C +C***FIRST EXECUTABLE STATEMENT XERRWD + LUNIT = IXSAV (1, 0, .FALSE.) + MESFLG = IXSAV (2, 0, .FALSE.) + IF (MESFLG .EQ. 0) GO TO 100 +C +C Write the message. +C + WRITE (LUNIT,10) MSG + 10 FORMAT(1X,A) + IF (NI .EQ. 1) WRITE (LUNIT, 20) I1 + 20 FORMAT(6X,'In above message, I1 =',I10) + IF (NI .EQ. 2) WRITE (LUNIT, 30) I1,I2 + 30 FORMAT(6X,'In above message, I1 =',I10,3X,'I2 =',I10) + IF (NR .EQ. 1) WRITE (LUNIT, 40) R1 + 40 FORMAT(6X,'In above message, R1 =',D21.13) + IF (NR .EQ. 2) WRITE (LUNIT, 50) R1,R2 + 50 FORMAT(6X,'In above, R1 =',D21.13,3X,'R2 =',D21.13) +C +C Abort the run if LEVEL = 2. +C + 100 IF (LEVEL .NE. 2) RETURN + STOP +C----------------------- End of Subroutine XERRWD ---------------------- + END +*DECK XSETF + SUBROUTINE XSETF (MFLAG) +C***BEGIN PROLOGUE XSETF +C***PURPOSE Reset the error print control flag. +C***LIBRARY MATHLIB +C***CATEGORY R3A +C***TYPE ALL (XSETF-A) +C***KEYWORDS ERROR CONTROL +C***AUTHOR Hindmarsh, Alan C., (LLNL) +C***DESCRIPTION +C +C XSETF sets the error print control flag to MFLAG: +C MFLAG=1 means print all messages (the default). +C MFLAG=0 means no printing. +C +C***SEE ALSO XERMSG, XERRWD, XERRWV +C***REFERENCES (NONE) +C***ROUTINES CALLED IXSAV +C***REVISION HISTORY (YYMMDD) +C 921118 DATE WRITTEN +C 930329 Added SLATEC format prologue. (FNF) +C 930407 Corrected SEE ALSO section. (FNF) +C 930922 Made user-callable, and other cosmetic changes. (FNF) +C***END PROLOGUE XSETF +C +C Subroutines called by XSETF.. None +C Function routine called by XSETF.. IXSAV +C----------------------------------------------------------------------- +C**End + INTEGER MFLAG, JUNK, IXSAV +C +C***FIRST EXECUTABLE STATEMENT XSETF + IF (MFLAG .EQ. 0 .OR. MFLAG .EQ. 1) JUNK = IXSAV (2,MFLAG,.TRUE.) + RETURN +C----------------------- End of Subroutine XSETF ----------------------- + END +*DECK XSETUN + SUBROUTINE XSETUN (LUN) +C***BEGIN PROLOGUE XSETUN +C***PURPOSE Reset the logical unit number for error messages. +C***LIBRARY MATHLIB +C***CATEGORY R3B +C***TYPE ALL (XSETUN-A) +C***KEYWORDS ERROR CONTROL +C***DESCRIPTION +C +C XSETUN sets the logical unit number for error messages to LUN. +C +C***AUTHOR Hindmarsh, Alan C., (LLNL) +C***SEE ALSO XERMSG, XERRWD, XERRWV +C***REFERENCES (NONE) +C***ROUTINES CALLED IXSAV +C***REVISION HISTORY (YYMMDD) +C 921118 DATE WRITTEN +C 930329 Added SLATEC format prologue. (FNF) +C 930407 Corrected SEE ALSO section. (FNF) +C 930922 Made user-callable, and other cosmetic changes. (FNF) +C***END PROLOGUE XSETUN +C +C Subroutines called by XSETUN.. None +C Function routine called by XSETUN.. IXSAV +C----------------------------------------------------------------------- +C**End + INTEGER LUN, JUNK, IXSAV +C +C***FIRST EXECUTABLE STATEMENT XSETUN + IF (LUN .GT. 0) JUNK = IXSAV (1,LUN,.TRUE.) + RETURN +C----------------------- End of Subroutine XSETUN ---------------------- + END +*DECK IXSAV + INTEGER FUNCTION IXSAV (IPAR, IVALUE, ISET) +C***BEGIN PROLOGUE IXSAV +C***SUBSIDIARY +C***PURPOSE Save and recall error message control parameters. +C***LIBRARY MATHLIB +C***CATEGORY R3C +C***TYPE ALL (IXSAV-A) +C***AUTHOR Hindmarsh, Alan C., (LLNL) +C***DESCRIPTION +C +C IXSAV saves and recalls one of two error message parameters: +C LUNIT, the logical unit number to which messages are printed, and +C MESFLG, the message print flag. +C This is a modification of the SLATEC library routine J4SAVE. +C +C Saved local variables.. +C LUNIT = Logical unit number for messages. +C LUNDEF = Default logical unit number, data-loaded to 6 below +C (may be machine-dependent). +C MESFLG = Print control flag.. +C 1 means print all messages (the default). +C 0 means no printing. +C +C On input.. +C IPAR = Parameter indicator (1 for LUNIT, 2 for MESFLG). +C IVALUE = The value to be set for the parameter, if ISET = .TRUE. +C ISET = Logical flag to indicate whether to read or write. +C If ISET = .TRUE., the parameter will be given +C the value IVALUE. If ISET = .FALSE., the parameter +C will be unchanged, and IVALUE is a dummy argument. +C +C On return.. +C IXSAV = The (old) value of the parameter. +C +C***SEE ALSO XERMSG, XERRWD, XERRWV +C***ROUTINES CALLED NONE +C***REVISION HISTORY (YYMMDD) +C 921118 DATE WRITTEN +C 930329 Modified prologue to SLATEC format. (FNF) +C 941025 Minor modification re default unit number. (ACH) +C***END PROLOGUE IXSAV +C +C**End + LOGICAL ISET + INTEGER IPAR, IVALUE +C----------------------------------------------------------------------- + INTEGER LUNIT, LUNDEF, MESFLG +C----------------------------------------------------------------------- +C The following Fortran-77 declaration is to cause the values of the +C listed (local) variables to be saved between calls to this routine. +C----------------------------------------------------------------------- + SAVE LUNIT, LUNDEF, MESFLG + DATA LUNIT/-1/, LUNDEF/6/, MESFLG/1/ +C +C***FIRST EXECUTABLE STATEMENT IXSAV + IF (IPAR .EQ. 1) THEN + IF (LUNIT .EQ. -1) LUNIT = LUNDEF + IXSAV = LUNIT + IF (ISET) LUNIT = IVALUE + ENDIF +C + IF (IPAR .EQ. 2) THEN + IXSAV = MESFLG + IF (ISET) MESFLG = IVALUE + ENDIF +C + RETURN +C----------------------- End of Function IXSAV ------------------------- + END diff --git a/ext/math/ddaspk.f b/ext/math/ddaspk.f new file mode 100755 index 000000000..d7bd0be2f --- /dev/null +++ b/ext/math/ddaspk.f @@ -0,0 +1,6612 @@ + SUBROUTINE DDASPK (RES, NEQ, T, Y, YPRIME, TOUT, INFO, RTOL, ATOL, + * IDID, RWORK, LRW, IWORK, LIW, RPAR, IPAR, JAC, PSOL) +C +C***BEGIN PROLOGUE DDASPK +C***DATE WRITTEN 890101 (YYMMDD) +C***REVISION DATE 910624 (Added HMAX test at 525 in main driver.) +C***REVISION DATE 920929 (CJ in RES call, RES counter fix.) +C***REVISION DATE 921215 (Warnings on poor iteration performance) +C***REVISION DATE 921216 (NRMAX as optional input) +C***REVISION DATE 930315 (Name change: DDINI to DDINIT) +C***REVISION DATE 940822 (Replaced initial condition calculation) +C***REVISION DATE 941101 (Added linesearch in I.C. calculations) +C***REVISION DATE 941220 (Misc. corrections throughout) +C***REVISION DATE 950125 (Added DINVWT routine) +C***REVISION DATE 950714 (Misc. corrections throughout) +C***REVISION DATE 950802 (Default NRMAX = 5, based on tests.) +C***REVISION DATE 950808 (Optional error test added.) +C***REVISION DATE 950814 (Added I.C. constraints and INFO(14)) +C***REVISION DATE 950828 (Various minor corrections.) +C***REVISION DATE 951006 (Corrected WT scaling in DFNRMK.) +C***REVISION DATE 951030 (Corrected history update at end of DDASTP.) +C***REVISION DATE 960129 (Corrected RL bug in DLINSD, DLINSK.) +C***REVISION DATE 960301 (Added NONNEG to SAVE statement.) +C***REVISION DATE 000512 (Removed copyright notices.) +C***REVISION DATE 000622 (Corrected LWM value using NCPHI.) +C***REVISION DATE 000628 (Corrected I.C. stopping tests when index = 0.) +C***REVISION DATE 000628 (Fixed alpha test in I.C. calc., Krylov case.) +C***REVISION DATE 000628 (Improved restart in I.C. calc., Krylov case.) +C***REVISION DATE 000628 (Minor corrections throughout.) +C***REVISION DATE 000711 (Fixed Newton convergence test in DNSD, DNSK.) +C***REVISION DATE 000712 (Fixed tests on TN - TOUT below 420 and 440.) +C***CATEGORY NO. I1A2 +C***KEYWORDS DIFFERENTIAL/ALGEBRAIC, BACKWARD DIFFERENTIATION FORMULAS, +C IMPLICIT DIFFERENTIAL SYSTEMS, KRYLOV ITERATION +C***AUTHORS Linda R. Petzold, Peter N. Brown, Alan C. Hindmarsh, and +C Clement W. Ulrich +C Center for Computational Sciences & Engineering, L-316 +C Lawrence Livermore National Laboratory +C P.O. Box 808, +C Livermore, CA 94551 +C***PURPOSE This code solves a system of differential/algebraic +C equations of the form +C G(t,y,y') = 0 , +C using a combination of Backward Differentiation Formula +C (BDF) methods and a choice of two linear system solution +C methods: direct (dense or band) or Krylov (iterative). +C This version is in double precision. +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C *Usage: +C +C IMPLICIT DOUBLE PRECISION(A-H,O-Z) +C INTEGER NEQ, INFO(N), IDID, LRW, LIW, IWORK(LIW), IPAR(*) +C DOUBLE PRECISION T, Y(*), YPRIME(*), TOUT, RTOL(*), ATOL(*), +C RWORK(LRW), RPAR(*) +C EXTERNAL RES, JAC, PSOL +C +C CALL DDASPK (RES, NEQ, T, Y, YPRIME, TOUT, INFO, RTOL, ATOL, +C * IDID, RWORK, LRW, IWORK, LIW, RPAR, IPAR, JAC, PSOL) +C +C Quantities which may be altered by the code are: +C T, Y(*), YPRIME(*), INFO(1), RTOL, ATOL, IDID, RWORK(*), IWORK(*) +C +C +C *Arguments: +C +C RES:EXT This is the name of a subroutine which you +C provide to define the residual function G(t,y,y') +C of the differential/algebraic system. +C +C NEQ:IN This is the number of equations in the system. +C +C T:INOUT This is the current value of the independent +C variable. +C +C Y(*):INOUT This array contains the solution components at T. +C +C YPRIME(*):INOUT This array contains the derivatives of the solution +C components at T. +C +C TOUT:IN This is a point at which a solution is desired. +C +C INFO(N):IN This is an integer array used to communicate details +C of how the solution is to be carried out, such as +C tolerance type, matrix structure, step size and +C order limits, and choice of nonlinear system method. +C N must be at least 20. +C +C RTOL,ATOL:INOUT These quantities represent absolute and relative +C error tolerances (on local error) which you provide +C to indicate how accurately you wish the solution to +C be computed. You may choose them to be both scalars +C or else both arrays of length NEQ. +C +C IDID:OUT This integer scalar is an indicator reporting what +C the code did. You must monitor this variable to +C decide what action to take next. +C +C RWORK:WORK A real work array of length LRW which provides the +C code with needed storage space. +C +C LRW:IN The length of RWORK. +C +C IWORK:WORK An integer work array of length LIW which provides +C the code with needed storage space. +C +C LIW:IN The length of IWORK. +C +C RPAR,IPAR:IN These are real and integer parameter arrays which +C you can use for communication between your calling +C program and the RES, JAC, and PSOL subroutines. +C +C JAC:EXT This is the name of a subroutine which you may +C provide (optionally) for calculating Jacobian +C (partial derivative) data involved in solving linear +C systems within DDASPK. +C +C PSOL:EXT This is the name of a subroutine which you must +C provide for solving linear systems if you selected +C a Krylov method. The purpose of PSOL is to solve +C linear systems involving a left preconditioner P. +C +C *Overview +C +C The DDASPK solver uses the backward differentiation formulas of +C orders one through five to solve a system of the form G(t,y,y') = 0 +C for y = Y and y' = YPRIME. Values for Y and YPRIME at the initial +C time must be given as input. These values should be consistent, +C that is, if T, Y, YPRIME are the given initial values, they should +C satisfy G(T,Y,YPRIME) = 0. However, if consistent values are not +C known, in many cases you can have DDASPK solve for them -- see INFO(11). +C (This and other options are described in more detail below.) +C +C Normally, DDASPK solves the system from T to TOUT. It is easy to +C continue the solution to get results at additional TOUT. This is +C the interval mode of operation. Intermediate results can also be +C obtained easily by specifying INFO(3). +C +C On each step taken by DDASPK, a sequence of nonlinear algebraic +C systems arises. These are solved by one of two types of +C methods: +C * a Newton iteration with a direct method for the linear +C systems involved (INFO(12) = 0), or +C * a Newton iteration with a preconditioned Krylov iterative +C method for the linear systems involved (INFO(12) = 1). +C +C The direct method choices are dense and band matrix solvers, +C with either a user-supplied or an internal difference quotient +C Jacobian matrix, as specified by INFO(5) and INFO(6). +C In the band case, INFO(6) = 1, you must supply half-bandwidths +C in IWORK(1) and IWORK(2). +C +C The Krylov method is the Generalized Minimum Residual (GMRES) +C method, in either complete or incomplete form, and with +C scaling and preconditioning. The method is implemented +C in an algorithm called SPIGMR. Certain options in the Krylov +C method case are specified by INFO(13) and INFO(15). +C +C If the Krylov method is chosen, you may supply a pair of routines, +C JAC and PSOL, to apply preconditioning to the linear system. +C If the system is A*x = b, the matrix is A = dG/dY + CJ*dG/dYPRIME +C (of order NEQ). This system can then be preconditioned in the form +C (P-inverse)*A*x = (P-inverse)*b, with left preconditioner P. +C (DDASPK does not allow right preconditioning.) +C Then the Krylov method is applied to this altered, but equivalent, +C linear system, hopefully with much better performance than without +C preconditioning. (In addition, a diagonal scaling matrix based on +C the tolerances is also introduced into the altered system.) +C +C The JAC routine evaluates any data needed for solving systems +C with coefficient matrix P, and PSOL carries out that solution. +C In any case, in order to improve convergence, you should try to +C make P approximate the matrix A as much as possible, while keeping +C the system P*x = b reasonably easy and inexpensive to solve for x, +C given a vector b. +C +C +C *Description +C +C------INPUT - WHAT TO DO ON THE FIRST CALL TO DDASPK------------------- +C +C +C The first call of the code is defined to be the start of each new +C problem. Read through the descriptions of all the following items, +C provide sufficient storage space for designated arrays, set +C appropriate variables for the initialization of the problem, and +C give information about how you want the problem to be solved. +C +C +C RES -- Provide a subroutine of the form +C +C SUBROUTINE RES (T, Y, YPRIME, CJ, DELTA, IRES, RPAR, IPAR) +C +C to define the system of differential/algebraic +C equations which is to be solved. For the given values +C of T, Y and YPRIME, the subroutine should return +C the residual of the differential/algebraic system +C DELTA = G(T,Y,YPRIME) +C DELTA is a vector of length NEQ which is output from RES. +C +C Subroutine RES must not alter T, Y, YPRIME, or CJ. +C You must declare the name RES in an EXTERNAL +C statement in your program that calls DDASPK. +C You must dimension Y, YPRIME, and DELTA in RES. +C +C The input argument CJ can be ignored, or used to rescale +C constraint equations in the system (see Ref. 2, p. 145). +C Note: In this respect, DDASPK is not downward-compatible +C with DDASSL, which does not have the RES argument CJ. +C +C IRES is an integer flag which is always equal to zero +C on input. Subroutine RES should alter IRES only if it +C encounters an illegal value of Y or a stop condition. +C Set IRES = -1 if an input value is illegal, and DDASPK +C will try to solve the problem without getting IRES = -1. +C If IRES = -2, DDASPK will return control to the calling +C program with IDID = -11. +C +C RPAR and IPAR are real and integer parameter arrays which +C you can use for communication between your calling program +C and subroutine RES. They are not altered by DDASPK. If you +C do not need RPAR or IPAR, ignore these parameters by treat- +C ing them as dummy arguments. If you do choose to use them, +C dimension them in your calling program and in RES as arrays +C of appropriate length. +C +C NEQ -- Set it to the number of equations in the system (NEQ .GE. 1). +C +C T -- Set it to the initial point of the integration. (T must be +C a variable.) +C +C Y(*) -- Set this array to the initial values of the NEQ solution +C components at the initial point. You must dimension Y of +C length at least NEQ in your calling program. +C +C YPRIME(*) -- Set this array to the initial values of the NEQ first +C derivatives of the solution components at the initial +C point. You must dimension YPRIME at least NEQ in your +C calling program. +C +C TOUT - Set it to the first point at which a solution is desired. +C You cannot take TOUT = T. Integration either forward in T +C (TOUT .GT. T) or backward in T (TOUT .LT. T) is permitted. +C +C The code advances the solution from T to TOUT using step +C sizes which are automatically selected so as to achieve the +C desired accuracy. If you wish, the code will return with the +C solution and its derivative at intermediate steps (the +C intermediate-output mode) so that you can monitor them, +C but you still must provide TOUT in accord with the basic +C aim of the code. +C +C The first step taken by the code is a critical one because +C it must reflect how fast the solution changes near the +C initial point. The code automatically selects an initial +C step size which is practically always suitable for the +C problem. By using the fact that the code will not step past +C TOUT in the first step, you could, if necessary, restrict the +C length of the initial step. +C +C For some problems it may not be permissible to integrate +C past a point TSTOP, because a discontinuity occurs there +C or the solution or its derivative is not defined beyond +C TSTOP. When you have declared a TSTOP point (see INFO(4) +C and RWORK(1)), you have told the code not to integrate past +C TSTOP. In this case any tout beyond TSTOP is invalid input. +C +C INFO(*) - Use the INFO array to give the code more details about +C how you want your problem solved. This array should be +C dimensioned of length 20, though DDASPK uses only the +C first 15 entries. You must respond to all of the following +C items, which are arranged as questions. The simplest use +C of DDASPK corresponds to setting all entries of INFO to 0. +C +C INFO(1) - This parameter enables the code to initialize itself. +C You must set it to indicate the start of every new +C problem. +C +C **** Is this the first call for this problem ... +C yes - set INFO(1) = 0 +C no - not applicable here. +C See below for continuation calls. **** +C +C INFO(2) - How much accuracy you want of your solution +C is specified by the error tolerances RTOL and ATOL. +C The simplest use is to take them both to be scalars. +C To obtain more flexibility, they can both be arrays. +C The code must be told your choice. +C +C **** Are both error tolerances RTOL, ATOL scalars ... +C yes - set INFO(2) = 0 +C and input scalars for both RTOL and ATOL +C no - set INFO(2) = 1 +C and input arrays for both RTOL and ATOL **** +C +C INFO(3) - The code integrates from T in the direction of TOUT +C by steps. If you wish, it will return the computed +C solution and derivative at the next intermediate step +C (the intermediate-output mode) or TOUT, whichever comes +C first. This is a good way to proceed if you want to +C see the behavior of the solution. If you must have +C solutions at a great many specific TOUT points, this +C code will compute them efficiently. +C +C **** Do you want the solution only at +C TOUT (and not at the next intermediate step) ... +C yes - set INFO(3) = 0 +C no - set INFO(3) = 1 **** +C +C INFO(4) - To handle solutions at a great many specific +C values TOUT efficiently, this code may integrate past +C TOUT and interpolate to obtain the result at TOUT. +C Sometimes it is not possible to integrate beyond some +C point TSTOP because the equation changes there or it is +C not defined past TSTOP. Then you must tell the code +C this stop condition. +C +C **** Can the integration be carried out without any +C restrictions on the independent variable T ... +C yes - set INFO(4) = 0 +C no - set INFO(4) = 1 +C and define the stopping point TSTOP by +C setting RWORK(1) = TSTOP **** +C +C INFO(5) - used only when INFO(12) = 0 (direct methods). +C To solve differential/algebraic systems you may wish +C to use a matrix of partial derivatives of the +C system of differential equations. If you do not +C provide a subroutine to evaluate it analytically (see +C description of the item JAC in the call list), it will +C be approximated by numerical differencing in this code. +C Although it is less trouble for you to have the code +C compute partial derivatives by numerical differencing, +C the solution will be more reliable if you provide the +C derivatives via JAC. Usually numerical differencing is +C more costly than evaluating derivatives in JAC, but +C sometimes it is not - this depends on your problem. +C +C **** Do you want the code to evaluate the partial deriv- +C atives automatically by numerical differences ... +C yes - set INFO(5) = 0 +C no - set INFO(5) = 1 +C and provide subroutine JAC for evaluating the +C matrix of partial derivatives **** +C +C INFO(6) - used only when INFO(12) = 0 (direct methods). +C DDASPK will perform much better if the matrix of +C partial derivatives, dG/dY + CJ*dG/dYPRIME (here CJ is +C a scalar determined by DDASPK), is banded and the code +C is told this. In this case, the storage needed will be +C greatly reduced, numerical differencing will be performed +C much cheaper, and a number of important algorithms will +C execute much faster. The differential equation is said +C to have half-bandwidths ML (lower) and MU (upper) if +C equation i involves only unknowns Y(j) with +C i-ML .le. j .le. i+MU . +C For all i=1,2,...,NEQ. Thus, ML and MU are the widths +C of the lower and upper parts of the band, respectively, +C with the main diagonal being excluded. If you do not +C indicate that the equation has a banded matrix of partial +C derivatives the code works with a full matrix of NEQ**2 +C elements (stored in the conventional way). Computations +C with banded matrices cost less time and storage than with +C full matrices if 2*ML+MU .lt. NEQ. If you tell the +C code that the matrix of partial derivatives has a banded +C structure and you want to provide subroutine JAC to +C compute the partial derivatives, then you must be careful +C to store the elements of the matrix in the special form +C indicated in the description of JAC. +C +C **** Do you want to solve the problem using a full (dense) +C matrix (and not a special banded structure) ... +C yes - set INFO(6) = 0 +C no - set INFO(6) = 1 +C and provide the lower (ML) and upper (MU) +C bandwidths by setting +C IWORK(1)=ML +C IWORK(2)=MU **** +C +C INFO(7) - You can specify a maximum (absolute value of) +C stepsize, so that the code will avoid passing over very +C large regions. +C +C **** Do you want the code to decide on its own the maximum +C stepsize ... +C yes - set INFO(7) = 0 +C no - set INFO(7) = 1 +C and define HMAX by setting +C RWORK(2) = HMAX **** +C +C INFO(8) - Differential/algebraic problems may occasionally +C suffer from severe scaling difficulties on the first +C step. If you know a great deal about the scaling of +C your problem, you can help to alleviate this problem +C by specifying an initial stepsize H0. +C +C **** Do you want the code to define its own initial +C stepsize ... +C yes - set INFO(8) = 0 +C no - set INFO(8) = 1 +C and define H0 by setting +C RWORK(3) = H0 **** +C +C INFO(9) - If storage is a severe problem, you can save some +C storage by restricting the maximum method order MAXORD. +C The default value is 5. For each order decrease below 5, +C the code requires NEQ fewer locations, but it is likely +C to be slower. In any case, you must have +C 1 .le. MAXORD .le. 5. +C **** Do you want the maximum order to default to 5 ... +C yes - set INFO(9) = 0 +C no - set INFO(9) = 1 +C and define MAXORD by setting +C IWORK(3) = MAXORD **** +C +C INFO(10) - If you know that certain components of the +C solutions to your equations are always nonnegative +C (or nonpositive), it may help to set this +C parameter. There are three options that are +C available: +C 1. To have constraint checking only in the initial +C condition calculation. +C 2. To enforce nonnegativity in Y during the integration. +C 3. To enforce both options 1 and 2. +C +C When selecting option 2 or 3, it is probably best to try the +C code without using this option first, and only use +C this option if that does not work very well. +C +C **** Do you want the code to solve the problem without +C invoking any special inequality constraints ... +C yes - set INFO(10) = 0 +C no - set INFO(10) = 1 to have option 1 enforced +C no - set INFO(10) = 2 to have option 2 enforced +C no - set INFO(10) = 3 to have option 3 enforced **** +C +C If you have specified INFO(10) = 1 or 3, then you +C will also need to identify how each component of Y +C in the initial condition calculation is constrained. +C You must set: +C IWORK(40+I) = +1 if Y(I) must be .GE. 0, +C IWORK(40+I) = +2 if Y(I) must be .GT. 0, +C IWORK(40+I) = -1 if Y(I) must be .LE. 0, while +C IWORK(40+I) = -2 if Y(I) must be .LT. 0, while +C IWORK(40+I) = 0 if Y(I) is not constrained. +C +C INFO(11) - DDASPK normally requires the initial T, Y, and +C YPRIME to be consistent. That is, you must have +C G(T,Y,YPRIME) = 0 at the initial T. If you do not know +C the initial conditions precisely, in some cases +C DDASPK may be able to compute it. +C +C Denoting the differential variables in Y by Y_d +C and the algebraic variables by Y_a, DDASPK can solve +C one of two initialization problems: +C 1. Given Y_d, calculate Y_a and Y'_d, or +C 2. Given Y', calculate Y. +C In either case, initial values for the given +C components are input, and initial guesses for +C the unknown components must also be provided as input. +C +C **** Are the initial T, Y, YPRIME consistent ... +C +C yes - set INFO(11) = 0 +C no - set INFO(11) = 1 to calculate option 1 above, +C or set INFO(11) = 2 to calculate option 2 **** +C +C If you have specified INFO(11) = 1, then you +C will also need to identify which are the +C differential and which are the algebraic +C components (algebraic components are components +C whose derivatives do not appear explicitly +C in the function G(T,Y,YPRIME)). You must set: +C IWORK(LID+I) = +1 if Y(I) is a differential variable +C IWORK(LID+I) = -1 if Y(I) is an algebraic variable, +C where LID = 40 if INFO(10) = 0 or 2 and LID = 40+NEQ +C if INFO(10) = 1 or 3. +C +C INFO(12) - Except for the addition of the RES argument CJ, +C DDASPK by default is downward-compatible with DDASSL, +C which uses only direct (dense or band) methods to solve +C the linear systems involved. You must set INFO(12) to +C indicate whether you want the direct methods or the +C Krylov iterative method. +C **** Do you want DDASPK to use standard direct methods +C (dense or band) or the Krylov (iterative) method ... +C direct methods - set INFO(12) = 0. +C Krylov method - set INFO(12) = 1, +C and check the settings of INFO(13) and INFO(15). +C +C INFO(13) - used when INFO(12) = 1 (Krylov methods). +C DDASPK uses scalars MAXL, KMP, NRMAX, and EPLI for the +C iterative solution of linear systems. INFO(13) allows +C you to override the default values of these parameters. +C These parameters and their defaults are as follows: +C MAXL = maximum number of iterations in the SPIGMR +C algorithm (MAXL .le. NEQ). The default is +C MAXL = MIN(5,NEQ). +C KMP = number of vectors on which orthogonalization is +C done in the SPIGMR algorithm. The default is +C KMP = MAXL, which corresponds to complete GMRES +C iteration, as opposed to the incomplete form. +C NRMAX = maximum number of restarts of the SPIGMR +C algorithm per nonlinear iteration. The default is +C NRMAX = 5. +C EPLI = convergence test constant in SPIGMR algorithm. +C The default is EPLI = 0.05. +C Note that the length of RWORK depends on both MAXL +C and KMP. See the definition of LRW below. +C **** Are MAXL, KMP, and EPLI to be given their +C default values ... +C yes - set INFO(13) = 0 +C no - set INFO(13) = 1, +C and set all of the following: +C IWORK(24) = MAXL (1 .le. MAXL .le. NEQ) +C IWORK(25) = KMP (1 .le. KMP .le. MAXL) +C IWORK(26) = NRMAX (NRMAX .ge. 0) +C RWORK(10) = EPLI (0 .lt. EPLI .lt. 1.0) **** +C +C INFO(14) - used with INFO(11) > 0 (initial condition +C calculation is requested). In this case, you may +C request control to be returned to the calling program +C immediately after the initial condition calculation, +C before proceeding to the integration of the system +C (e.g. to examine the computed Y and YPRIME). +C If this is done, and if the initialization succeeded +C (IDID = 4), you should reset INFO(11) to 0 for the +C next call, to prevent the solver from repeating the +C initialization (and to avoid an infinite loop). +C **** Do you want to proceed to the integration after +C the initial condition calculation is done ... +C yes - set INFO(14) = 0 +C no - set INFO(14) = 1 **** +C +C INFO(15) - used when INFO(12) = 1 (Krylov methods). +C When using preconditioning in the Krylov method, +C you must supply a subroutine, PSOL, which solves the +C associated linear systems using P. +C The usage of DDASPK is simpler if PSOL can carry out +C the solution without any prior calculation of data. +C However, if some partial derivative data is to be +C calculated in advance and used repeatedly in PSOL, +C then you must supply a JAC routine to do this, +C and set INFO(15) to indicate that JAC is to be called +C for this purpose. For example, P might be an +C approximation to a part of the matrix A which can be +C calculated and LU-factored for repeated solutions of +C the preconditioner system. The arrays WP and IWP +C (described under JAC and PSOL) can be used to +C communicate data between JAC and PSOL. +C **** Does PSOL operate with no prior preparation ... +C yes - set INFO(15) = 0 (no JAC routine) +C no - set INFO(15) = 1 +C and supply a JAC routine to evaluate and +C preprocess any required Jacobian data. **** +C +C INFO(16) - option to exclude algebraic variables from +C the error test. +C **** Do you wish to control errors locally on +C all the variables... +C yes - set INFO(16) = 0 +C no - set INFO(16) = 1 +C If you have specified INFO(16) = 1, then you +C will also need to identify which are the +C differential and which are the algebraic +C components (algebraic components are components +C whose derivatives do not appear explicitly +C in the function G(T,Y,YPRIME)). You must set: +C IWORK(LID+I) = +1 if Y(I) is a differential +C variable, and +C IWORK(LID+I) = -1 if Y(I) is an algebraic +C variable, +C where LID = 40 if INFO(10) = 0 or 2 and +C LID = 40 + NEQ if INFO(10) = 1 or 3. +C +C INFO(17) - used when INFO(11) > 0 (DDASPK is to do an +C initial condition calculation). +C DDASPK uses several heuristic control quantities in the +C initial condition calculation. They have default values, +C but can also be set by the user using INFO(17). +C These parameters and their defaults are as follows: +C MXNIT = maximum number of Newton iterations +C per Jacobian or preconditioner evaluation. +C The default is: +C MXNIT = 5 in the direct case (INFO(12) = 0), and +C MXNIT = 15 in the Krylov case (INFO(12) = 1). +C MXNJ = maximum number of Jacobian or preconditioner +C evaluations. The default is: +C MXNJ = 6 in the direct case (INFO(12) = 0), and +C MXNJ = 2 in the Krylov case (INFO(12) = 1). +C MXNH = maximum number of values of the artificial +C stepsize parameter H to be tried if INFO(11) = 1. +C The default is MXNH = 5. +C NOTE: the maximum number of Newton iterations +C allowed in all is MXNIT*MXNJ*MXNH if INFO(11) = 1, +C and MXNIT*MXNJ if INFO(11) = 2. +C LSOFF = flag to turn off the linesearch algorithm +C (LSOFF = 0 means linesearch is on, LSOFF = 1 means +C it is turned off). The default is LSOFF = 0. +C STPTOL = minimum scaled step in linesearch algorithm. +C The default is STPTOL = (unit roundoff)**(2/3). +C EPINIT = swing factor in the Newton iteration convergence +C test. The test is applied to the residual vector, +C premultiplied by the approximate Jacobian (in the +C direct case) or the preconditioner (in the Krylov +C case). For convergence, the weighted RMS norm of +C this vector (scaled by the error weights) must be +C less than EPINIT*EPCON, where EPCON = .33 is the +C analogous test constant used in the time steps. +C The default is EPINIT = .01. +C **** Are the initial condition heuristic controls to be +C given their default values... +C yes - set INFO(17) = 0 +C no - set INFO(17) = 1, +C and set all of the following: +C IWORK(32) = MXNIT (.GT. 0) +C IWORK(33) = MXNJ (.GT. 0) +C IWORK(34) = MXNH (.GT. 0) +C IWORK(35) = LSOFF ( = 0 or 1) +C RWORK(14) = STPTOL (.GT. 0.0) +C RWORK(15) = EPINIT (.GT. 0.0) **** +C +C INFO(18) - option to get extra printing in initial condition +C calculation. +C **** Do you wish to have extra printing... +C no - set INFO(18) = 0 +C yes - set INFO(18) = 1 for minimal printing, or +C set INFO(18) = 2 for full printing. +C If you have specified INFO(18) .ge. 1, data +C will be printed with the error handler routines. +C To print to a non-default unit number L, include +C the line CALL XSETUN(L) in your program. **** +C +C RTOL, ATOL -- You must assign relative (RTOL) and absolute (ATOL) +C error tolerances to tell the code how accurately you +C want the solution to be computed. They must be defined +C as variables because the code may change them. +C you have two choices -- +C Both RTOL and ATOL are scalars (INFO(2) = 0), or +C both RTOL and ATOL are vectors (INFO(2) = 1). +C In either case all components must be non-negative. +C +C The tolerances are used by the code in a local error +C test at each step which requires roughly that +C abs(local error in Y(i)) .le. EWT(i) , +C where EWT(i) = RTOL*abs(Y(i)) + ATOL is an error weight +C quantity, for each vector component. +C (More specifically, a root-mean-square norm is used to +C measure the size of vectors, and the error test uses the +C magnitude of the solution at the beginning of the step.) +C +C The true (global) error is the difference between the +C true solution of the initial value problem and the +C computed approximation. Practically all present day +C codes, including this one, control the local error at +C each step and do not even attempt to control the global +C error directly. +C +C Usually, but not always, the true accuracy of +C the computed Y is comparable to the error tolerances. +C This code will usually, but not always, deliver a more +C accurate solution if you reduce the tolerances and +C integrate again. By comparing two such solutions you +C can get a fairly reliable idea of the true error in the +C solution at the larger tolerances. +C +C Setting ATOL = 0. results in a pure relative error test +C on that component. Setting RTOL = 0. results in a pure +C absolute error test on that component. A mixed test +C with non-zero RTOL and ATOL corresponds roughly to a +C relative error test when the solution component is +C much bigger than ATOL and to an absolute error test +C when the solution component is smaller than the +C threshold ATOL. +C +C The code will not attempt to compute a solution at an +C accuracy unreasonable for the machine being used. It +C will advise you if you ask for too much accuracy and +C inform you as to the maximum accuracy it believes +C possible. +C +C RWORK(*) -- a real work array, which should be dimensioned in your +C calling program with a length equal to the value of +C LRW (or greater). +C +C LRW -- Set it to the declared length of the RWORK array. The +C minimum length depends on the options you have selected, +C given by a base value plus additional storage as described +C below. +C +C If INFO(12) = 0 (standard direct method), the base value is +C base = 50 + max(MAXORD+4,7)*NEQ. +C The default value is MAXORD = 5 (see INFO(9)). With the +C default MAXORD, base = 50 + 9*NEQ. +C Additional storage must be added to the base value for +C any or all of the following options: +C if INFO(6) = 0 (dense matrix), add NEQ**2 +C if INFO(6) = 1 (banded matrix), then +C if INFO(5) = 0, add (2*ML+MU+1)*NEQ + 2*(NEQ/(ML+MU+1)+1), +C if INFO(5) = 1, add (2*ML+MU+1)*NEQ, +C if INFO(16) = 1, add NEQ. +C +C If INFO(12) = 1 (Krylov method), the base value is +C base = 50 + (MAXORD+5)*NEQ + (MAXL+3+MIN0(1,MAXL-KMP))*NEQ + +C + (MAXL+3)*MAXL + 1 + LENWP. +C See PSOL for description of LENWP. The default values are: +C MAXORD = 5 (see INFO(9)), MAXL = min(5,NEQ) and KMP = MAXL +C (see INFO(13)). +C With the default values for MAXORD, MAXL and KMP, +C base = 91 + 18*NEQ + LENWP. +C Additional storage must be added to the base value for +C any or all of the following options: +C if INFO(16) = 1, add NEQ. +C +C +C IWORK(*) -- an integer work array, which should be dimensioned in +C your calling program with a length equal to the value +C of LIW (or greater). +C +C LIW -- Set it to the declared length of the IWORK array. The +C minimum length depends on the options you have selected, +C given by a base value plus additional storage as described +C below. +C +C If INFO(12) = 0 (standard direct method), the base value is +C base = 40 + NEQ. +C IF INFO(10) = 1 or 3, add NEQ to the base value. +C If INFO(11) = 1 or INFO(16) =1, add NEQ to the base value. +C +C If INFO(12) = 1 (Krylov method), the base value is +C base = 40 + LENIWP. +C See PSOL for description of LENIWP. +C IF INFO(10) = 1 or 3, add NEQ to the base value. +C If INFO(11) = 1 or INFO(16) = 1, add NEQ to the base value. +C +C +C RPAR, IPAR -- These are arrays of double precision and integer type, +C respectively, which are available for you to use +C for communication between your program that calls +C DDASPK and the RES subroutine (and the JAC and PSOL +C subroutines). They are not altered by DDASPK. +C If you do not need RPAR or IPAR, ignore these +C parameters by treating them as dummy arguments. +C If you do choose to use them, dimension them in +C your calling program and in RES (and in JAC and PSOL) +C as arrays of appropriate length. +C +C JAC -- This is the name of a routine that you may supply +C (optionally) that relates to the Jacobian matrix of the +C nonlinear system that the code must solve at each T step. +C The role of JAC (and its call sequence) depends on whether +C a direct (INFO(12) = 0) or Krylov (INFO(12) = 1) method +C is selected. +C +C **** INFO(12) = 0 (direct methods): +C If you are letting the code generate partial derivatives +C numerically (INFO(5) = 0), then JAC can be absent +C (or perhaps a dummy routine to satisfy the loader). +C Otherwise you must supply a JAC routine to compute +C the matrix A = dG/dY + CJ*dG/dYPRIME. It must have +C the form +C +C SUBROUTINE JAC (T, Y, YPRIME, PD, CJ, RPAR, IPAR) +C +C The JAC routine must dimension Y, YPRIME, and PD (and RPAR +C and IPAR if used). CJ is a scalar which is input to JAC. +C For the given values of T, Y, and YPRIME, the JAC routine +C must evaluate the nonzero elements of the matrix A, and +C store these values in the array PD. The elements of PD are +C set to zero before each call to JAC, so that only nonzero +C elements need to be defined. +C The way you store the elements into the PD array depends +C on the structure of the matrix indicated by INFO(6). +C *** INFO(6) = 0 (full or dense matrix) *** +C Give PD a first dimension of NEQ. When you evaluate the +C nonzero partial derivatives of equation i (i.e. of G(i)) +C with respect to component j (of Y and YPRIME), you must +C store the element in PD according to +C PD(i,j) = dG(i)/dY(j) + CJ*dG(i)/dYPRIME(j). +C *** INFO(6) = 1 (banded matrix with half-bandwidths ML, MU +C as described under INFO(6)) *** +C Give PD a first dimension of 2*ML+MU+1. When you +C evaluate the nonzero partial derivatives of equation i +C (i.e. of G(i)) with respect to component j (of Y and +C YPRIME), you must store the element in PD according to +C IROW = i - j + ML + MU + 1 +C PD(IROW,j) = dG(i)/dY(j) + CJ*dG(i)/dYPRIME(j). +C +C **** INFO(12) = 1 (Krylov method): +C If you are not calculating Jacobian data in advance for use +C in PSOL (INFO(15) = 0), JAC can be absent (or perhaps a +C dummy routine to satisfy the loader). Otherwise, you may +C supply a JAC routine to compute and preprocess any parts of +C of the Jacobian matrix A = dG/dY + CJ*dG/dYPRIME that are +C involved in the preconditioner matrix P. +C It is to have the form +C +C SUBROUTINE JAC (RES, IRES, NEQ, T, Y, YPRIME, REWT, SAVR, +C WK, H, CJ, WP, IWP, IER, RPAR, IPAR) +C +C The JAC routine must dimension Y, YPRIME, REWT, SAVR, WK, +C and (if used) WP, IWP, RPAR, and IPAR. +C The Y, YPRIME, and SAVR arrays contain the current values +C of Y, YPRIME, and the residual G, respectively. +C The array WK is work space of length NEQ. +C H is the step size. CJ is a scalar, input to JAC, that is +C normally proportional to 1/H. REWT is an array of +C reciprocal error weights, 1/EWT(i), where EWT(i) is +C RTOL*abs(Y(i)) + ATOL (unless you supplied routine DDAWTS +C instead), for use in JAC if needed. For example, if JAC +C computes difference quotient approximations to partial +C derivatives, the REWT array may be useful in setting the +C increments used. The JAC routine should do any +C factorization operations called for, in preparation for +C solving linear systems in PSOL. The matrix P should +C be an approximation to the Jacobian, +C A = dG/dY + CJ*dG/dYPRIME. +C +C WP and IWP are real and integer work arrays which you may +C use for communication between your JAC routine and your +C PSOL routine. These may be used to store elements of the +C preconditioner P, or related matrix data (such as factored +C forms). They are not altered by DDASPK. +C If you do not need WP or IWP, ignore these parameters by +C treating them as dummy arguments. If you do use them, +C dimension them appropriately in your JAC and PSOL routines. +C See the PSOL description for instructions on setting +C the lengths of WP and IWP. +C +C On return, JAC should set the error flag IER as follows.. +C IER = 0 if JAC was successful, +C IER .ne. 0 if JAC was unsuccessful (e.g. if Y or YPRIME +C was illegal, or a singular matrix is found). +C (If IER .ne. 0, a smaller stepsize will be tried.) +C IER = 0 on entry to JAC, so need be reset only on a failure. +C If RES is used within JAC, then a nonzero value of IRES will +C override any nonzero value of IER (see the RES description). +C +C Regardless of the method type, subroutine JAC must not +C alter T, Y(*), YPRIME(*), H, CJ, or REWT(*). +C You must declare the name JAC in an EXTERNAL statement in +C your program that calls DDASPK. +C +C PSOL -- This is the name of a routine you must supply if you have +C selected a Krylov method (INFO(12) = 1) with preconditioning. +C In the direct case (INFO(12) = 0), PSOL can be absent +C (a dummy routine may have to be supplied to satisfy the +C loader). Otherwise, you must provide a PSOL routine to +C solve linear systems arising from preconditioning. +C When supplied with INFO(12) = 1, the PSOL routine is to +C have the form +C +C SUBROUTINE PSOL (NEQ, T, Y, YPRIME, SAVR, WK, CJ, WGHT, +C WP, IWP, B, EPLIN, IER, RPAR, IPAR) +C +C The PSOL routine must solve linear systems of the form +C P*x = b where P is the left preconditioner matrix. +C +C The right-hand side vector b is in the B array on input, and +C PSOL must return the solution vector x in B. +C The Y, YPRIME, and SAVR arrays contain the current values +C of Y, YPRIME, and the residual G, respectively. +C +C Work space required by JAC and/or PSOL, and space for data to +C be communicated from JAC to PSOL is made available in the form +C of arrays WP and IWP, which are parts of the RWORK and IWORK +C arrays, respectively. The lengths of these real and integer +C work spaces WP and IWP must be supplied in LENWP and LENIWP, +C respectively, as follows.. +C IWORK(27) = LENWP = length of real work space WP +C IWORK(28) = LENIWP = length of integer work space IWP. +C +C WK is a work array of length NEQ for use by PSOL. +C CJ is a scalar, input to PSOL, that is normally proportional +C to 1/H (H = stepsize). If the old value of CJ +C (at the time of the last JAC call) is needed, it must have +C been saved by JAC in WP. +C +C WGHT is an array of weights, to be used if PSOL uses an +C iterative method and performs a convergence test. (In terms +C of the argument REWT to JAC, WGHT is REWT/sqrt(NEQ).) +C If PSOL uses an iterative method, it should use EPLIN +C (a heuristic parameter) as the bound on the weighted norm of +C the residual for the computed solution. Specifically, the +C residual vector R should satisfy +C SQRT (SUM ( (R(i)*WGHT(i))**2 ) ) .le. EPLIN +C +C PSOL must not alter NEQ, T, Y, YPRIME, SAVR, CJ, WGHT, EPLIN. +C +C On return, PSOL should set the error flag IER as follows.. +C IER = 0 if PSOL was successful, +C IER .lt. 0 if an unrecoverable error occurred, meaning +C control will be passed to the calling routine, +C IER .gt. 0 if a recoverable error occurred, meaning that +C the step will be retried with the same step size +C but with a call to JAC to update necessary data, +C unless the Jacobian data is current, in which case +C the step will be retried with a smaller step size. +C IER = 0 on entry to PSOL so need be reset only on a failure. +C +C You must declare the name PSOL in an EXTERNAL statement in +C your program that calls DDASPK. +C +C +C OPTIONALLY REPLACEABLE SUBROUTINE: +C +C DDASPK uses a weighted root-mean-square norm to measure the +C size of various error vectors. The weights used in this norm +C are set in the following subroutine: +C +C SUBROUTINE DDAWTS (NEQ, IWT, RTOL, ATOL, Y, EWT, RPAR, IPAR) +C DIMENSION RTOL(*), ATOL(*), Y(*), EWT(*), RPAR(*), IPAR(*) +C +C A DDAWTS routine has been included with DDASPK which sets the +C weights according to +C EWT(I) = RTOL*ABS(Y(I)) + ATOL +C in the case of scalar tolerances (IWT = 0) or +C EWT(I) = RTOL(I)*ABS(Y(I)) + ATOL(I) +C in the case of array tolerances (IWT = 1). (IWT is INFO(2).) +C In some special cases, it may be appropriate for you to define +C your own error weights by writing a subroutine DDAWTS to be +C called instead of the version supplied. However, this should +C be attempted only after careful thought and consideration. +C If you supply this routine, you may use the tolerances and Y +C as appropriate, but do not overwrite these variables. You +C may also use RPAR and IPAR to communicate data as appropriate. +C ***Note: Aside from the values of the weights, the choice of +C norm used in DDASPK (weighted root-mean-square) is not subject +C to replacement by the user. In this respect, DDASPK is not +C downward-compatible with the original DDASSL solver (in which +C the norm routine was optionally user-replaceable). +C +C +C------OUTPUT - AFTER ANY RETURN FROM DDASPK---------------------------- +C +C The principal aim of the code is to return a computed solution at +C T = TOUT, although it is also possible to obtain intermediate +C results along the way. To find out whether the code achieved its +C goal or if the integration process was interrupted before the task +C was completed, you must check the IDID parameter. +C +C +C T -- The output value of T is the point to which the solution +C was successfully advanced. +C +C Y(*) -- contains the computed solution approximation at T. +C +C YPRIME(*) -- contains the computed derivative approximation at T. +C +C IDID -- reports what the code did, described as follows: +C +C *** TASK COMPLETED *** +C Reported by positive values of IDID +C +C IDID = 1 -- a step was successfully taken in the +C intermediate-output mode. The code has not +C yet reached TOUT. +C +C IDID = 2 -- the integration to TSTOP was successfully +C completed (T = TSTOP) by stepping exactly to TSTOP. +C +C IDID = 3 -- the integration to TOUT was successfully +C completed (T = TOUT) by stepping past TOUT. +C Y(*) and YPRIME(*) are obtained by interpolation. +C +C IDID = 4 -- the initial condition calculation, with +C INFO(11) > 0, was successful, and INFO(14) = 1. +C No integration steps were taken, and the solution +C is not considered to have been started. +C +C *** TASK INTERRUPTED *** +C Reported by negative values of IDID +C +C IDID = -1 -- a large amount of work has been expended +C (about 500 steps). +C +C IDID = -2 -- the error tolerances are too stringent. +C +C IDID = -3 -- the local error test cannot be satisfied +C because you specified a zero component in ATOL +C and the corresponding computed solution component +C is zero. Thus, a pure relative error test is +C impossible for this component. +C +C IDID = -5 -- there were repeated failures in the evaluation +C or processing of the preconditioner (in JAC). +C +C IDID = -6 -- DDASPK had repeated error test failures on the +C last attempted step. +C +C IDID = -7 -- the nonlinear system solver in the time integration +C could not converge. +C +C IDID = -8 -- the matrix of partial derivatives appears +C to be singular (direct method). +C +C IDID = -9 -- the nonlinear system solver in the time integration +C failed to achieve convergence, and there were repeated +C error test failures in this step. +C +C IDID =-10 -- the nonlinear system solver in the time integration +C failed to achieve convergence because IRES was equal +C to -1. +C +C IDID =-11 -- IRES = -2 was encountered and control is +C being returned to the calling program. +C +C IDID =-12 -- DDASPK failed to compute the initial Y, YPRIME. +C +C IDID =-13 -- unrecoverable error encountered inside user's +C PSOL routine, and control is being returned to +C the calling program. +C +C IDID =-14 -- the Krylov linear system solver could not +C achieve convergence. +C +C IDID =-15,..,-32 -- Not applicable for this code. +C +C *** TASK TERMINATED *** +C reported by the value of IDID=-33 +C +C IDID = -33 -- the code has encountered trouble from which +C it cannot recover. A message is printed +C explaining the trouble and control is returned +C to the calling program. For example, this occurs +C when invalid input is detected. +C +C RTOL, ATOL -- these quantities remain unchanged except when +C IDID = -2. In this case, the error tolerances have been +C increased by the code to values which are estimated to +C be appropriate for continuing the integration. However, +C the reported solution at T was obtained using the input +C values of RTOL and ATOL. +C +C RWORK, IWORK -- contain information which is usually of no interest +C to the user but necessary for subsequent calls. +C However, you may be interested in the performance data +C listed below. These quantities are accessed in RWORK +C and IWORK but have internal mnemonic names, as follows.. +C +C RWORK(3)--contains H, the step size h to be attempted +C on the next step. +C +C RWORK(4)--contains TN, the current value of the +C independent variable, i.e. the farthest point +C integration has reached. This will differ +C from T if interpolation has been performed +C (IDID = 3). +C +C RWORK(7)--contains HOLD, the stepsize used on the last +C successful step. If INFO(11) = INFO(14) = 1, +C this contains the value of H used in the +C initial condition calculation. +C +C IWORK(7)--contains K, the order of the method to be +C attempted on the next step. +C +C IWORK(8)--contains KOLD, the order of the method used +C on the last step. +C +C IWORK(11)--contains NST, the number of steps (in T) +C taken so far. +C +C IWORK(12)--contains NRE, the number of calls to RES +C so far. +C +C IWORK(13)--contains NJE, the number of calls to JAC so +C far (Jacobian or preconditioner evaluations). +C +C IWORK(14)--contains NETF, the total number of error test +C failures so far. +C +C IWORK(15)--contains NCFN, the total number of nonlinear +C convergence failures so far (includes counts +C of singular iteration matrix or singular +C preconditioners). +C +C IWORK(16)--contains NCFL, the number of convergence +C failures of the linear iteration so far. +C +C IWORK(17)--contains LENIW, the length of IWORK actually +C required. This is defined on normal returns +C and on an illegal input return for +C insufficient storage. +C +C IWORK(18)--contains LENRW, the length of RWORK actually +C required. This is defined on normal returns +C and on an illegal input return for +C insufficient storage. +C +C IWORK(19)--contains NNI, the total number of nonlinear +C iterations so far (each of which calls a +C linear solver). +C +C IWORK(20)--contains NLI, the total number of linear +C (Krylov) iterations so far. +C +C IWORK(21)--contains NPS, the number of PSOL calls so +C far, for preconditioning solve operations or +C for solutions with the user-supplied method. +C +C Note: The various counters in IWORK do not include +C counts during a call made with INFO(11) > 0 and +C INFO(14) = 1. +C +C +C------INPUT - WHAT TO DO TO CONTINUE THE INTEGRATION ----------------- +C (CALLS AFTER THE FIRST) +C +C This code is organized so that subsequent calls to continue the +C integration involve little (if any) additional effort on your +C part. You must monitor the IDID parameter in order to determine +C what to do next. +C +C Recalling that the principal task of the code is to integrate +C from T to TOUT (the interval mode), usually all you will need +C to do is specify a new TOUT upon reaching the current TOUT. +C +C Do not alter any quantity not specifically permitted below. In +C particular do not alter NEQ, T, Y(*), YPRIME(*), RWORK(*), +C IWORK(*), or the differential equation in subroutine RES. Any +C such alteration constitutes a new problem and must be treated +C as such, i.e. you must start afresh. +C +C You cannot change from array to scalar error control or vice +C versa (INFO(2)), but you can change the size of the entries of +C RTOL or ATOL. Increasing a tolerance makes the equation easier +C to integrate. Decreasing a tolerance will make the equation +C harder to integrate and should generally be avoided. +C +C You can switch from the intermediate-output mode to the +C interval mode (INFO(3)) or vice versa at any time. +C +C If it has been necessary to prevent the integration from going +C past a point TSTOP (INFO(4), RWORK(1)), keep in mind that the +C code will not integrate to any TOUT beyond the currently +C specified TSTOP. Once TSTOP has been reached, you must change +C the value of TSTOP or set INFO(4) = 0. You may change INFO(4) +C or TSTOP at any time but you must supply the value of TSTOP in +C RWORK(1) whenever you set INFO(4) = 1. +C +C Do not change INFO(5), INFO(6), INFO(12-17) or their associated +C IWORK/RWORK locations unless you are going to restart the code. +C +C *** FOLLOWING A COMPLETED TASK *** +C +C If.. +C IDID = 1, call the code again to continue the integration +C another step in the direction of TOUT. +C +C IDID = 2 or 3, define a new TOUT and call the code again. +C TOUT must be different from T. You cannot change +C the direction of integration without restarting. +C +C IDID = 4, reset INFO(11) = 0 and call the code again to begin +C the integration. (If you leave INFO(11) > 0 and +C INFO(14) = 1, you may generate an infinite loop.) +C In this situation, the next call to DASPK is +C considered to be the first call for the problem, +C in that all initializations are done. +C +C *** FOLLOWING AN INTERRUPTED TASK *** +C +C To show the code that you realize the task was interrupted and +C that you want to continue, you must take appropriate action and +C set INFO(1) = 1. +C +C If.. +C IDID = -1, the code has taken about 500 steps. If you want to +C continue, set INFO(1) = 1 and call the code again. +C An additional 500 steps will be allowed. +C +C +C IDID = -2, the error tolerances RTOL, ATOL have been increased +C to values the code estimates appropriate for +C continuing. You may want to change them yourself. +C If you are sure you want to continue with relaxed +C error tolerances, set INFO(1) = 1 and call the code +C again. +C +C IDID = -3, a solution component is zero and you set the +C corresponding component of ATOL to zero. If you +C are sure you want to continue, you must first alter +C the error criterion to use positive values of ATOL +C for those components corresponding to zero solution +C components, then set INFO(1) = 1 and call the code +C again. +C +C IDID = -4 --- cannot occur with this code. +C +C IDID = -5, your JAC routine failed with the Krylov method. Check +C for errors in JAC and restart the integration. +C +C IDID = -6, repeated error test failures occurred on the last +C attempted step in DDASPK. A singularity in the +C solution may be present. If you are absolutely +C certain you want to continue, you should restart +C the integration. (Provide initial values of Y and +C YPRIME which are consistent.) +C +C IDID = -7, repeated convergence test failures occurred on the last +C attempted step in DDASPK. An inaccurate or ill- +C conditioned Jacobian or preconditioner may be the +C problem. If you are absolutely certain you want +C to continue, you should restart the integration. +C +C +C IDID = -8, the matrix of partial derivatives is singular, with +C the use of direct methods. Some of your equations +C may be redundant. DDASPK cannot solve the problem +C as stated. It is possible that the redundant +C equations could be removed, and then DDASPK could +C solve the problem. It is also possible that a +C solution to your problem either does not exist +C or is not unique. +C +C IDID = -9, DDASPK had multiple convergence test failures, preceded +C by multiple error test failures, on the last +C attempted step. It is possible that your problem is +C ill-posed and cannot be solved using this code. Or, +C there may be a discontinuity or a singularity in the +C solution. If you are absolutely certain you want to +C continue, you should restart the integration. +C +C IDID = -10, DDASPK had multiple convergence test failures +C because IRES was equal to -1. If you are +C absolutely certain you want to continue, you +C should restart the integration. +C +C IDID = -11, there was an unrecoverable error (IRES = -2) from RES +C inside the nonlinear system solver. Determine the +C cause before trying again. +C +C IDID = -12, DDASPK failed to compute the initial Y and YPRIME +C vectors. This could happen because the initial +C approximation to Y or YPRIME was not very good, or +C because no consistent values of these vectors exist. +C The problem could also be caused by an inaccurate or +C singular iteration matrix, or a poor preconditioner. +C +C IDID = -13, there was an unrecoverable error encountered inside +C your PSOL routine. Determine the cause before +C trying again. +C +C IDID = -14, the Krylov linear system solver failed to achieve +C convergence. This may be due to ill-conditioning +C in the iteration matrix, or a singularity in the +C preconditioner (if one is being used). +C Another possibility is that there is a better +C choice of Krylov parameters (see INFO(13)). +C Possibly the failure is caused by redundant equations +C in the system, or by inconsistent equations. +C In that case, reformulate the system to make it +C consistent and non-redundant. +C +C IDID = -15,..,-32 --- Cannot occur with this code. +C +C *** FOLLOWING A TERMINATED TASK *** +C +C If IDID = -33, you cannot continue the solution of this problem. +C An attempt to do so will result in your run being +C terminated. +C +C --------------------------------------------------------------------- +C +C***REFERENCES +C 1. L. R. Petzold, A Description of DASSL: A Differential/Algebraic +C System Solver, in Scientific Computing, R. S. Stepleman et al. +C (Eds.), North-Holland, Amsterdam, 1983, pp. 65-68. +C 2. K. E. Brenan, S. L. Campbell, and L. R. Petzold, Numerical +C Solution of Initial-Value Problems in Differential-Algebraic +C Equations, Elsevier, New York, 1989. +C 3. P. N. Brown and A. C. Hindmarsh, Reduced Storage Matrix Methods +C in Stiff ODE Systems, J. Applied Mathematics and Computation, +C 31 (1989), pp. 40-91. +C 4. P. N. Brown, A. C. Hindmarsh, and L. R. Petzold, Using Krylov +C Methods in the Solution of Large-Scale Differential-Algebraic +C Systems, SIAM J. Sci. Comp., 15 (1994), pp. 1467-1488. +C 5. P. N. Brown, A. C. Hindmarsh, and L. R. Petzold, Consistent +C Initial Condition Calculation for Differential-Algebraic +C Systems, SIAM J. Sci. Comp. 19 (1998), pp. 1495-1512. +C +C***ROUTINES CALLED +C +C The following are all the subordinate routines used by DDASPK. +C +C DDASIC computes consistent initial conditions. +C DYYPNW updates Y and YPRIME in linesearch for initial condition +C calculation. +C DDSTP carries out one step of the integration. +C DCNSTR/DCNST0 check the current solution for constraint violations. +C DDAWTS sets error weight quantities. +C DINVWT tests and inverts the error weights. +C DDATRP performs interpolation to get an output solution. +C DDWNRM computes the weighted root-mean-square norm of a vector. +C D1MACH provides the unit roundoff of the computer. +C XERRWD/XSETF/XSETUN/IXSAV is a package to handle error messages. +C DDASID nonlinear equation driver to initialize Y and YPRIME using +C direct linear system solver methods. Interfaces to Newton +C solver (direct case). +C DNSID solves the nonlinear system for unknown initial values by +C modified Newton iteration and direct linear system methods. +C DLINSD carries out linesearch algorithm for initial condition +C calculation (direct case). +C DFNRMD calculates weighted norm of preconditioned residual in +C initial condition calculation (direct case). +C DNEDD nonlinear equation driver for direct linear system solver +C methods. Interfaces to Newton solver (direct case). +C DMATD assembles the iteration matrix (direct case). +C DNSD solves the associated nonlinear system by modified +C Newton iteration and direct linear system methods. +C DSLVD interfaces to linear system solver (direct case). +C DDASIK nonlinear equation driver to initialize Y and YPRIME using +C Krylov iterative linear system methods. Interfaces to +C Newton solver (Krylov case). +C DNSIK solves the nonlinear system for unknown initial values by +C Newton iteration and Krylov iterative linear system methods. +C DLINSK carries out linesearch algorithm for initial condition +C calculation (Krylov case). +C DFNRMK calculates weighted norm of preconditioned residual in +C initial condition calculation (Krylov case). +C DNEDK nonlinear equation driver for iterative linear system solver +C methods. Interfaces to Newton solver (Krylov case). +C DNSK solves the associated nonlinear system by Inexact Newton +C iteration and (linear) Krylov iteration. +C DSLVK interfaces to linear system solver (Krylov case). +C DSPIGM solves a linear system by SPIGMR algorithm. +C DATV computes matrix-vector product in Krylov algorithm. +C DORTH performs orthogonalization of Krylov basis vectors. +C DHEQR performs QR factorization of Hessenberg matrix. +C DHELS finds least-squares solution of Hessenberg linear system. +C DGEFA, DGESL, DGBFA, DGBSL are LINPACK routines for solving +C linear systems (dense or band direct methods). +C DAXPY, DCOPY, DDOT, DNRM2, DSCAL are Basic Linear Algebra (BLAS) +C routines. +C +C The routines called directly by DDASPK are: +C DCNST0, DDAWTS, DINVWT, D1MACH, DDWNRM, DDASIC, DDATRP, DDSTP, +C XERRWD +C +C***END PROLOGUE DDASPK +C +C + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + LOGICAL DONE, LAVL, LCFN, LCFL, LWARN + DIMENSION Y(*),YPRIME(*) + DIMENSION INFO(20) + DIMENSION RWORK(LRW),IWORK(LIW) + DIMENSION RTOL(*),ATOL(*) + DIMENSION RPAR(*),IPAR(*) + CHARACTER MSG*80 + EXTERNAL RES, JAC, PSOL, DDASID, DDASIK, DNEDD, DNEDK +C +C Set pointers into IWORK. +C + PARAMETER (LML=1, LMU=2, LMTYPE=4, + * LIWM=1, LMXORD=3, LJCALC=5, LPHASE=6, LK=7, LKOLD=8, + * LNS=9, LNSTL=10, LNST=11, LNRE=12, LNJE=13, LETF=14, LNCFN=15, + * LNCFL=16, LNIW=17, LNRW=18, LNNI=19, LNLI=20, LNPS=21, + * LNPD=22, LMITER=23, LMAXL=24, LKMP=25, LNRMAX=26, LLNWP=27, + * LLNIWP=28, LLOCWP=29, LLCIWP=30, LKPRIN=31, + * LMXNIT=32, LMXNJ=33, LMXNH=34, LLSOFF=35, LICNS=41) +C +C Set pointers into RWORK. +C + PARAMETER (LTSTOP=1, LHMAX=2, LH=3, LTN=4, LCJ=5, LCJOLD=6, + * LHOLD=7, LS=8, LROUND=9, LEPLI=10, LSQRN=11, LRSQRN=12, + * LEPCON=13, LSTOL=14, LEPIN=15, + * LALPHA=21, LBETA=27, LGAMMA=33, LPSI=39, LSIGMA=45, LDELTA=51) +C + SAVE LID, LENID, NONNEG, NCPHI +C +C +C***FIRST EXECUTABLE STATEMENT DDASPK +C +C + IF(INFO(1).NE.0) GO TO 100 +C +C----------------------------------------------------------------------- +C This block is executed for the initial call only. +C It contains checking of inputs and initializations. +C----------------------------------------------------------------------- +C +C First check INFO array to make sure all elements of INFO +C Are within the proper range. (INFO(1) is checked later, because +C it must be tested on every call.) ITEMP holds the location +C within INFO which may be out of range. +C + DO 10 I=2,9 + ITEMP = I + IF (INFO(I) .NE. 0 .AND. INFO(I) .NE. 1) GO TO 701 + 10 CONTINUE + ITEMP = 10 + IF(INFO(10).LT.0 .OR. INFO(10).GT.3) GO TO 701 + ITEMP = 11 + IF(INFO(11).LT.0 .OR. INFO(11).GT.2) GO TO 701 + DO 15 I=12,17 + ITEMP = I + IF (INFO(I) .NE. 0 .AND. INFO(I) .NE. 1) GO TO 701 + 15 CONTINUE + ITEMP = 18 + IF(INFO(18).LT.0 .OR. INFO(18).GT.2) GO TO 701 + +C +C Check NEQ to see if it is positive. +C + IF (NEQ .LE. 0) GO TO 702 +C +C Check and compute maximum order. +C + MXORD=5 + IF (INFO(9) .NE. 0) THEN + MXORD=IWORK(LMXORD) + IF (MXORD .LT. 1 .OR. MXORD .GT. 5) GO TO 703 + ENDIF + IWORK(LMXORD)=MXORD +C +C Set and/or check inputs for constraint checking (INFO(10) .NE. 0). +C Set values for ICNFLG, NONNEG, and pointer LID. +C + ICNFLG = 0 + NONNEG = 0 + LID = LICNS + IF (INFO(10) .EQ. 0) GO TO 20 + IF (INFO(10) .EQ. 1) THEN + ICNFLG = 1 + NONNEG = 0 + LID = LICNS + NEQ + ELSEIF (INFO(10) .EQ. 2) THEN + ICNFLG = 0 + NONNEG = 1 + ELSE + ICNFLG = 1 + NONNEG = 1 + LID = LICNS + NEQ + ENDIF +C + 20 CONTINUE +C +C Set and/or check inputs for Krylov solver (INFO(12) .NE. 0). +C If indicated, set default values for MAXL, KMP, NRMAX, and EPLI. +C Otherwise, verify inputs required for iterative solver. +C + IF (INFO(12) .EQ. 0) GO TO 25 +C + IWORK(LMITER) = INFO(12) + IF (INFO(13) .EQ. 0) THEN + IWORK(LMAXL) = MIN(5,NEQ) + IWORK(LKMP) = IWORK(LMAXL) + IWORK(LNRMAX) = 5 + RWORK(LEPLI) = 0.05D0 + ELSE + IF(IWORK(LMAXL) .LT. 1 .OR. IWORK(LMAXL) .GT. NEQ) GO TO 720 + IF(IWORK(LKMP) .LT. 1 .OR. IWORK(LKMP) .GT. IWORK(LMAXL)) + 1 GO TO 721 + IF(IWORK(LNRMAX) .LT. 0) GO TO 722 + IF(RWORK(LEPLI).LE.0.0D0 .OR. RWORK(LEPLI).GE.1.0D0)GO TO 723 + ENDIF +C + 25 CONTINUE +C +C Set and/or check controls for the initial condition calculation +C (INFO(11) .GT. 0). If indicated, set default values. +C Otherwise, verify inputs required for iterative solver. +C + IF (INFO(11) .EQ. 0) GO TO 30 + IF (INFO(17) .EQ. 0) THEN + IWORK(LMXNIT) = 5 + IF (INFO(12) .GT. 0) IWORK(LMXNIT) = 15 + IWORK(LMXNJ) = 6 + IF (INFO(12) .GT. 0) IWORK(LMXNJ) = 2 + IWORK(LMXNH) = 5 + IWORK(LLSOFF) = 0 + RWORK(LEPIN) = 0.01D0 + ELSE + IF (IWORK(LMXNIT) .LE. 0) GO TO 725 + IF (IWORK(LMXNJ) .LE. 0) GO TO 725 + IF (IWORK(LMXNH) .LE. 0) GO TO 725 + LSOFF = IWORK(LLSOFF) + IF (LSOFF .LT. 0 .OR. LSOFF .GT. 1) GO TO 725 + IF (RWORK(LEPIN) .LE. 0.0D0) GO TO 725 + ENDIF +C + 30 CONTINUE +C +C Below is the computation and checking of the work array lengths +C LENIW and LENRW, using direct methods (INFO(12) = 0) or +C the Krylov methods (INFO(12) = 1). +C + LENIC = 0 + IF (INFO(10) .EQ. 1 .OR. INFO(10) .EQ. 3) LENIC = NEQ + LENID = 0 + IF (INFO(11) .EQ. 1 .OR. INFO(16) .EQ. 1) LENID = NEQ + IF (INFO(12) .EQ. 0) THEN +C +C Compute MTYPE, etc. Check ML and MU. +C + NCPHI = MAX(MXORD + 1, 4) + IF(INFO(6).EQ.0) THEN + LENPD = NEQ**2 + LENRW = 50 + (NCPHI+3)*NEQ + LENPD + IF(INFO(5).EQ.0) THEN + IWORK(LMTYPE)=2 + ELSE + IWORK(LMTYPE)=1 + ENDIF + ELSE + IF(IWORK(LML).LT.0.OR.IWORK(LML).GE.NEQ)GO TO 717 + IF(IWORK(LMU).LT.0.OR.IWORK(LMU).GE.NEQ)GO TO 718 + LENPD=(2*IWORK(LML)+IWORK(LMU)+1)*NEQ + IF(INFO(5).EQ.0) THEN + IWORK(LMTYPE)=5 + MBAND=IWORK(LML)+IWORK(LMU)+1 + MSAVE=(NEQ/MBAND)+1 + LENRW = 50 + (NCPHI+3)*NEQ + LENPD + 2*MSAVE + ELSE + IWORK(LMTYPE)=4 + LENRW = 50 + (NCPHI+3)*NEQ + LENPD + ENDIF + ENDIF +C +C Compute LENIW, LENWP, LENIWP. +C + LENIW = 40 + LENIC + LENID + NEQ + LENWP = 0 + LENIWP = 0 +C + ELSE IF (INFO(12) .EQ. 1) THEN + NCPHI = MXORD + 1 + MAXL = IWORK(LMAXL) + LENWP = IWORK(LLNWP) + LENIWP = IWORK(LLNIWP) + LENPD = (MAXL+3+MIN0(1,MAXL-IWORK(LKMP)))*NEQ + 1 + (MAXL+3)*MAXL + 1 + LENWP + LENRW = 50 + (MXORD+5)*NEQ + LENPD + LENIW = 40 + LENIC + LENID + LENIWP +C + ENDIF + IF(INFO(16) .NE. 0) LENRW = LENRW + NEQ +C +C Check lengths of RWORK and IWORK. +C + IWORK(LNIW)=LENIW + IWORK(LNRW)=LENRW + IWORK(LNPD)=LENPD + IWORK(LLOCWP) = LENPD-LENWP+1 + IF(LRW.LT.LENRW)GO TO 704 + IF(LIW.LT.LENIW)GO TO 705 +C +C Check ICNSTR for legality. +C + IF (LENIC .GT. 0) THEN + DO 40 I = 1,NEQ + ICI = IWORK(LICNS-1+I) + IF (ICI .LT. -2 .OR. ICI .GT. 2) GO TO 726 + 40 CONTINUE + ENDIF +C +C Check Y for consistency with constraints. +C + IF (LENIC .GT. 0) THEN + CALL DCNST0(NEQ,Y,IWORK(LICNS),IRET) + IF (IRET .NE. 0) GO TO 727 + ENDIF +C +C Check ID for legality and set INDEX = 0 or 1. +C + INDEX = 1 + IF (LENID .GT. 0) THEN + INDEX = 0 + DO 50 I = 1,NEQ + IDI = IWORK(LID-1+I) + IF (IDI .NE. 1 .AND. IDI .NE. -1) GO TO 724 + IF (IDI .EQ. -1) INDEX = 1 + 50 CONTINUE + ENDIF +C +C Check to see that TOUT is different from T. +C + IF(TOUT .EQ. T)GO TO 719 +C +C Check HMAX. +C + IF(INFO(7) .NE. 0) THEN + HMAX = RWORK(LHMAX) + IF (HMAX .LE. 0.0D0) GO TO 710 + ENDIF +C +C Initialize counters and other flags. +C + IWORK(LNST)=0 + IWORK(LNRE)=0 + IWORK(LNJE)=0 + IWORK(LETF)=0 + IWORK(LNCFN)=0 + IWORK(LNNI)=0 + IWORK(LNLI)=0 + IWORK(LNPS)=0 + IWORK(LNCFL)=0 + IWORK(LKPRIN)=INFO(18) + IDID=1 + GO TO 200 +C +C----------------------------------------------------------------------- +C This block is for continuation calls only. +C Here we check INFO(1), and if the last step was interrupted, +C we check whether appropriate action was taken. +C----------------------------------------------------------------------- +C +100 CONTINUE + IF(INFO(1).EQ.1)GO TO 110 + ITEMP = 1 + IF(INFO(1).NE.-1)GO TO 701 +C +C If we are here, the last step was interrupted by an error +C condition from DDSTP, and appropriate action was not taken. +C This is a fatal error. +C + MSG = 'DASPK-- THE LAST STEP TERMINATED WITH A NEGATIVE' + CALL XERRWD(MSG,49,201,0,0,0,0,0,0.0D0,0.0D0) + MSG = 'DASPK-- VALUE (=I1) OF IDID AND NO APPROPRIATE' + CALL XERRWD(MSG,47,202,0,1,IDID,0,0,0.0D0,0.0D0) + MSG = 'DASPK-- ACTION WAS TAKEN. RUN TERMINATED' + CALL XERRWD(MSG,41,203,1,0,0,0,0,0.0D0,0.0D0) + RETURN +110 CONTINUE +C +C----------------------------------------------------------------------- +C This block is executed on all calls. +C +C Counters are saved for later checks of performance. +C Then the error tolerance parameters are checked, and the +C work array pointers are set. +C----------------------------------------------------------------------- +C +200 CONTINUE +C +C Save counters for use later. +C + IWORK(LNSTL)=IWORK(LNST) + NLI0 = IWORK(LNLI) + NNI0 = IWORK(LNNI) + NCFN0 = IWORK(LNCFN) + NCFL0 = IWORK(LNCFL) + NWARN = 0 +C +C Check RTOL and ATOL. +C + NZFLG = 0 + RTOLI = RTOL(1) + ATOLI = ATOL(1) + DO 210 I=1,NEQ + IF (INFO(2) .EQ. 1) RTOLI = RTOL(I) + IF (INFO(2) .EQ. 1) ATOLI = ATOL(I) + IF (RTOLI .GT. 0.0D0 .OR. ATOLI .GT. 0.0D0) NZFLG = 1 + IF (RTOLI .LT. 0.0D0) GO TO 706 + IF (ATOLI .LT. 0.0D0) GO TO 707 +210 CONTINUE + IF (NZFLG .EQ. 0) GO TO 708 +C +C Set pointers to RWORK and IWORK segments. +C For direct methods, SAVR is not used. +C + IWORK(LLCIWP) = LID + LENID + LSAVR = LDELTA + IF (INFO(12) .NE. 0) LSAVR = LDELTA + NEQ + LE = LSAVR + NEQ + LWT = LE + NEQ + LVT = LWT + IF (INFO(16) .NE. 0) LVT = LWT + NEQ + LPHI = LVT + NEQ + LWM = LPHI + NCPHI*NEQ + IF (INFO(1) .EQ. 1) GO TO 400 +C +C----------------------------------------------------------------------- +C This block is executed on the initial call only. +C Set the initial step size, the error weight vector, and PHI. +C Compute unknown initial components of Y and YPRIME, if requested. +C----------------------------------------------------------------------- +C +300 CONTINUE + TN=T + IDID=1 +C +C Set error weight array WT and altered weight array VT. +C + CALL DDAWTS(NEQ,INFO(2),RTOL,ATOL,Y,RWORK(LWT),RPAR,IPAR) + CALL DINVWT(NEQ,RWORK(LWT),IER) + IF (IER .NE. 0) GO TO 713 + IF (INFO(16) .NE. 0) THEN + DO 305 I = 1, NEQ + 305 RWORK(LVT+I-1) = MAX(IWORK(LID+I-1),0)*RWORK(LWT+I-1) + ENDIF +C +C Compute unit roundoff and HMIN. +C + UROUND = D1MACH(4) + RWORK(LROUND) = UROUND + HMIN = 4.0D0*UROUND*MAX(ABS(T),ABS(TOUT)) +C +C Set/check STPTOL control for initial condition calculation. +C + IF (INFO(11) .NE. 0) THEN + IF( INFO(17) .EQ. 0) THEN + RWORK(LSTOL) = UROUND**.6667D0 + ELSE + IF (RWORK(LSTOL) .LE. 0.0D0) GO TO 725 + ENDIF + ENDIF +C +C Compute EPCON and square root of NEQ and its reciprocal, used +C inside iterative solver. +C + RWORK(LEPCON) = 0.33D0 + FLOATN = NEQ + RWORK(LSQRN) = SQRT(FLOATN) + RWORK(LRSQRN) = 1.D0/RWORK(LSQRN) +C +C Check initial interval to see that it is long enough. +C + TDIST = ABS(TOUT - T) + IF(TDIST .LT. HMIN) GO TO 714 +C +C Check H0, if this was input. +C + IF (INFO(8) .EQ. 0) GO TO 310 + H0 = RWORK(LH) + IF ((TOUT - T)*H0 .LT. 0.0D0) GO TO 711 + IF (H0 .EQ. 0.0D0) GO TO 712 + GO TO 320 +310 CONTINUE +C +C Compute initial stepsize, to be used by either +C DDSTP or DDASIC, depending on INFO(11). +C + H0 = 0.001D0*TDIST + YPNORM = DDWNRM(NEQ,YPRIME,RWORK(LVT),RPAR,IPAR) + IF (YPNORM .GT. 0.5D0/H0) H0 = 0.5D0/YPNORM + H0 = SIGN(H0,TOUT-T) +C +C Adjust H0 if necessary to meet HMAX bound. +C +320 IF (INFO(7) .EQ. 0) GO TO 330 + RH = ABS(H0)/RWORK(LHMAX) + IF (RH .GT. 1.0D0) H0 = H0/RH +C +C Check against TSTOP, if applicable. +C +330 IF (INFO(4) .EQ. 0) GO TO 340 + TSTOP = RWORK(LTSTOP) + write(*,*) 'tstop = ',tstop + IF ((TSTOP - T)*H0 .LT. 0.0D0) GO TO 715 + IF ((T + H0 - TSTOP)*H0 .GT. 0.0D0) H0 = TSTOP - T + IF ((TSTOP - TOUT)*H0 .LT. 0.0D0) GO TO 709 +C +340 IF (INFO(11) .EQ. 0) GO TO 370 +C +C Compute unknown components of initial Y and YPRIME, depending +C on INFO(11) and INFO(12). INFO(12) represents the nonlinear +C solver type (direct/Krylov). Pass the name of the specific +C nonlinear solver, depending on INFO(12). The location of the work +C arrays SAVR, YIC, YPIC, PWK also differ in the two cases. +C For use in stopping tests, pass TSCALE = TDIST if INDEX = 0. +C + NWT = 1 + EPCONI = RWORK(LEPIN)*RWORK(LEPCON) + TSCALE = 0.0D0 + IF (INDEX .EQ. 0) TSCALE = TDIST +350 IF (INFO(12) .EQ. 0) THEN + LYIC = LPHI + 2*NEQ + LYPIC = LYIC + NEQ + LPWK = LYPIC + CALL DDASIC(TN,Y,YPRIME,NEQ,INFO(11),IWORK(LID), + * RES,JAC,PSOL,H0,TSCALE,RWORK(LWT),NWT,IDID,RPAR,IPAR, + * RWORK(LPHI),RWORK(LSAVR),RWORK(LDELTA),RWORK(LE), + * RWORK(LYIC),RWORK(LYPIC),RWORK(LPWK),RWORK(LWM),IWORK(LIWM), + * RWORK(LROUND),RWORK(LEPLI),RWORK(LSQRN),RWORK(LRSQRN), + * EPCONI,RWORK(LSTOL),INFO(15),ICNFLG,IWORK(LICNS),DDASID) + ELSE IF (INFO(12) .EQ. 1) THEN + LYIC = LWM + LYPIC = LYIC + NEQ + LPWK = LYPIC + NEQ + CALL DDASIC(TN,Y,YPRIME,NEQ,INFO(11),IWORK(LID), + * RES,JAC,PSOL,H0,TSCALE,RWORK(LWT),NWT,IDID,RPAR,IPAR, + * RWORK(LPHI),RWORK(LSAVR),RWORK(LDELTA),RWORK(LE), + * RWORK(LYIC),RWORK(LYPIC),RWORK(LPWK),RWORK(LWM),IWORK(LIWM), + * RWORK(LROUND),RWORK(LEPLI),RWORK(LSQRN),RWORK(LRSQRN), + * EPCONI,RWORK(LSTOL),INFO(15),ICNFLG,IWORK(LICNS),DDASIK) + ENDIF +C + IF (IDID .LT. 0) GO TO 600 +C +C DDASIC was successful. If this was the first call to DDASIC, +C update the WT array (with the current Y) and call it again. +C + IF (NWT .EQ. 2) GO TO 355 + NWT = 2 + CALL DDAWTS(NEQ,INFO(2),RTOL,ATOL,Y,RWORK(LWT),RPAR,IPAR) + CALL DINVWT(NEQ,RWORK(LWT),IER) + IF (IER .NE. 0) GO TO 713 + GO TO 350 +C +C If INFO(14) = 1, return now with IDID = 4. +C +355 IF (INFO(14) .EQ. 1) THEN + IDID = 4 + H = H0 + IF (INFO(11) .EQ. 1) RWORK(LHOLD) = H0 + GO TO 590 + ENDIF +C +C Update the WT and VT arrays one more time, with the new Y. +C + CALL DDAWTS(NEQ,INFO(2),RTOL,ATOL,Y,RWORK(LWT),RPAR,IPAR) + CALL DINVWT(NEQ,RWORK(LWT),IER) + IF (IER .NE. 0) GO TO 713 + IF (INFO(16) .NE. 0) THEN + DO 357 I = 1, NEQ + 357 RWORK(LVT+I-1) = MAX(IWORK(LID+I-1),0)*RWORK(LWT+I-1) + ENDIF +C +C Reset the initial stepsize to be used by DDSTP. +C Use H0, if this was input. Otherwise, recompute H0, +C and adjust it if necessary to meet HMAX bound. +C + IF (INFO(8) .NE. 0) THEN + H0 = RWORK(LH) + GO TO 360 + ENDIF +C + H0 = 0.001D0*TDIST + YPNORM = DDWNRM(NEQ,YPRIME,RWORK(LVT),RPAR,IPAR) + IF (YPNORM .GT. 0.5D0/H0) H0 = 0.5D0/YPNORM + H0 = SIGN(H0,TOUT-T) +C +360 IF (INFO(7) .NE. 0) THEN + RH = ABS(H0)/RWORK(LHMAX) + IF (RH .GT. 1.0D0) H0 = H0/RH + ENDIF +C +C Check against TSTOP, if applicable. +C + IF (INFO(4) .NE. 0) THEN + TSTOP = RWORK(LTSTOP) + write(*,*) 'tstop = ',tstop + IF ((T + H0 - TSTOP)*H0 .GT. 0.0D0) H0 = TSTOP - T + ENDIF +C +C Load H and RWORK(LH) with H0. +C +370 H = H0 + RWORK(LH) = H +C +C Load Y and H*YPRIME into PHI(*,1) and PHI(*,2). +C + ITEMP = LPHI + NEQ + DO 380 I = 1,NEQ + RWORK(LPHI + I - 1) = Y(I) +380 RWORK(ITEMP + I - 1) = H*YPRIME(I) +C + GO TO 500 +C +C----------------------------------------------------------------------- +C This block is for continuation calls only. +C Its purpose is to check stop conditions before taking a step. +C Adjust H if necessary to meet HMAX bound. +C----------------------------------------------------------------------- +C +400 CONTINUE + UROUND=RWORK(LROUND) + DONE = .FALSE. + TN=RWORK(LTN) + H=RWORK(LH) + IF(INFO(7) .EQ. 0) GO TO 410 + RH = ABS(H)/RWORK(LHMAX) + IF(RH .GT. 1.0D0) H = H/RH +410 CONTINUE + IF(T .EQ. TOUT) GO TO 719 + IF((T - TOUT)*H .GT. 0.0D0) GO TO 711 + IF(INFO(4) .EQ. 1) GO TO 430 + IF(INFO(3) .EQ. 1) GO TO 420 + IF((TN-TOUT)*H.LT.0.0D0)GO TO 490 + CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD), + * RWORK(LPHI),RWORK(LPSI)) + T=TOUT + IDID = 3 + DONE = .TRUE. + GO TO 490 +420 IF((TN-T)*H .LE. 0.0D0) GO TO 490 + IF((TN - TOUT)*H .GE. 0.0D0) GO TO 425 + CALL DDATRP(TN,TN,Y,YPRIME,NEQ,IWORK(LKOLD), + * RWORK(LPHI),RWORK(LPSI)) + T = TN + IDID = 1 + DONE = .TRUE. + GO TO 490 +425 CONTINUE + CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD), + * RWORK(LPHI),RWORK(LPSI)) + T = TOUT + IDID = 3 + DONE = .TRUE. + GO TO 490 +430 IF(INFO(3) .EQ. 1) GO TO 440 + TSTOP=RWORK(LTSTOP) + write(*,*) 'tstop = ',tstop + IF((TN-TSTOP)*H.GT.0.0D0) GO TO 715 + IF((TSTOP-TOUT)*H.LT.0.0D0)GO TO 709 + IF((TN-TOUT)*H.LT.0.0D0)GO TO 450 + CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD), + * RWORK(LPHI),RWORK(LPSI)) + T=TOUT + IDID = 3 + DONE = .TRUE. + GO TO 490 +440 TSTOP = RWORK(LTSTOP) + write(*,*) 'tstop = ',tstop + IF((TN-TSTOP)*H .GT. 0.0D0) GO TO 715 + IF((TSTOP-TOUT)*H .LT. 0.0D0) GO TO 709 + IF((TN-T)*H .LE. 0.0D0) GO TO 450 + IF((TN - TOUT)*H .GE. 0.0D0) GO TO 445 + CALL DDATRP(TN,TN,Y,YPRIME,NEQ,IWORK(LKOLD), + * RWORK(LPHI),RWORK(LPSI)) + T = TN + IDID = 1 + DONE = .TRUE. + GO TO 490 +445 CONTINUE + CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ,IWORK(LKOLD), + * RWORK(LPHI),RWORK(LPSI)) + T = TOUT + IDID = 3 + DONE = .TRUE. + GO TO 490 +450 CONTINUE +C +C Check whether we are within roundoff of TSTOP. +C + IF(ABS(TN-TSTOP).GT.100.0D0*UROUND* + * (ABS(TN)+ABS(H)))GO TO 460 + CALL DDATRP(TN,TSTOP,Y,YPRIME,NEQ,IWORK(LKOLD), + * RWORK(LPHI),RWORK(LPSI)) + IDID=2 + T=TSTOP + DONE = .TRUE. + GO TO 490 +460 TNEXT=TN+H + IF((TNEXT-TSTOP)*H.LE.0.0D0)GO TO 490 + H=TSTOP-TN + RWORK(LH)=H +C +490 IF (DONE) GO TO 590 +C +C----------------------------------------------------------------------- +C The next block contains the call to the one-step integrator DDSTP. +C This is a looping point for the integration steps. +C Check for too many steps. +C Check for poor Newton/Krylov performance. +C Update WT. Check for too much accuracy requested. +C Compute minimum stepsize. +C----------------------------------------------------------------------- +C +500 CONTINUE +C +C Check for too many steps. +C + IF((IWORK(LNST)-IWORK(LNSTL)).LT.500) GO TO 505 + IDID=-1 + GO TO 527 +C +C Check for poor Newton/Krylov performance. +C +505 IF (INFO(12) .EQ. 0) GO TO 510 + NSTD = IWORK(LNST) - IWORK(LNSTL) + NNID = IWORK(LNNI) - NNI0 + IF (NSTD .LT. 10 .OR. NNID .EQ. 0) GO TO 510 + AVLIN = REAL(IWORK(LNLI) - NLI0)/REAL(NNID) + RCFN = REAL(IWORK(LNCFN) - NCFN0)/REAL(NSTD) + RCFL = REAL(IWORK(LNCFL) - NCFL0)/REAL(NNID) + FMAXL = IWORK(LMAXL) + LAVL = AVLIN .GT. FMAXL + LCFN = RCFN .GT. 0.9D0 + LCFL = RCFL .GT. 0.9D0 + LWARN = LAVL .OR. LCFN .OR. LCFL + IF (.NOT.LWARN) GO TO 510 + NWARN = NWARN + 1 + IF (NWARN .GT. 10) GO TO 510 + IF (LAVL) THEN + MSG = 'DASPK-- Warning. Poor iterative algorithm performance ' + CALL XERRWD (MSG, 56, 501, 0, 0, 0, 0, 0, 0.0D0, 0.0D0) + MSG = ' at T = R1. Average no. of linear iterations = R2 ' + CALL XERRWD (MSG, 56, 501, 0, 0, 0, 0, 2, TN, AVLIN) + ENDIF + IF (LCFN) THEN + MSG = 'DASPK-- Warning. Poor iterative algorithm performance ' + CALL XERRWD (MSG, 56, 502, 0, 0, 0, 0, 0, 0.0D0, 0.0D0) + MSG = ' at T = R1. Nonlinear convergence failure rate = R2' + CALL XERRWD (MSG, 56, 502, 0, 0, 0, 0, 2, TN, RCFN) + ENDIF + IF (LCFL) THEN + MSG = 'DASPK-- Warning. Poor iterative algorithm performance ' + CALL XERRWD (MSG, 56, 503, 0, 0, 0, 0, 0, 0.0D0, 0.0D0) + MSG = ' at T = R1. Linear convergence failure rate = R2 ' + CALL XERRWD (MSG, 56, 503, 0, 0, 0, 0, 2, TN, RCFL) + ENDIF +C +C Update WT and VT, if this is not the first call. +C +510 CALL DDAWTS(NEQ,INFO(2),RTOL,ATOL,RWORK(LPHI),RWORK(LWT), + * RPAR,IPAR) + CALL DINVWT(NEQ,RWORK(LWT),IER) + IF (IER .NE. 0) THEN + IDID = -3 + GO TO 527 + ENDIF + IF (INFO(16) .NE. 0) THEN + DO 515 I = 1, NEQ + 515 RWORK(LVT+I-1) = MAX(IWORK(LID+I-1),0)*RWORK(LWT+I-1) + ENDIF +C +C Test for too much accuracy requested. +C + R = DDWNRM(NEQ,RWORK(LPHI),RWORK(LWT),RPAR,IPAR)*100.0D0*UROUND + IF (R .LE. 1.0D0) GO TO 525 +C +C Multiply RTOL and ATOL by R and return. +C + IF(INFO(2).EQ.1)GO TO 523 + RTOL(1)=R*RTOL(1) + ATOL(1)=R*ATOL(1) + IDID=-2 + GO TO 527 +523 DO 524 I=1,NEQ + RTOL(I)=R*RTOL(I) +524 ATOL(I)=R*ATOL(I) + IDID=-2 + GO TO 527 +525 CONTINUE +C +C Compute minimum stepsize. +C + HMIN=4.0D0*UROUND*MAX(ABS(TN),ABS(TOUT)) +C +C Test H vs. HMAX + IF (INFO(7) .NE. 0) THEN + RH = ABS(H)/RWORK(LHMAX) + IF (RH .GT. 1.0D0) H = H/RH + ENDIF +C +C Call the one-step integrator. +C Note that INFO(12) represents the nonlinear solver type. +C Pass the required nonlinear solver, depending upon INFO(12). +C + IF (INFO(12) .EQ. 0) THEN + CALL DDSTP(TN,Y,YPRIME,NEQ, + * RES,JAC,PSOL,H,RWORK(LWT),RWORK(LVT),INFO(1),IDID,RPAR,IPAR, + * RWORK(LPHI),RWORK(LSAVR),RWORK(LDELTA),RWORK(LE), + * RWORK(LWM),IWORK(LIWM), + * RWORK(LALPHA),RWORK(LBETA),RWORK(LGAMMA), + * RWORK(LPSI),RWORK(LSIGMA), + * RWORK(LCJ),RWORK(LCJOLD),RWORK(LHOLD),RWORK(LS),HMIN, + * RWORK(LROUND), RWORK(LEPLI),RWORK(LSQRN),RWORK(LRSQRN), + * RWORK(LEPCON), IWORK(LPHASE),IWORK(LJCALC),INFO(15), + * IWORK(LK), IWORK(LKOLD),IWORK(LNS),NONNEG,INFO(12), + * DNEDD) + ELSE IF (INFO(12) .EQ. 1) THEN + CALL DDSTP(TN,Y,YPRIME,NEQ, + * RES,JAC,PSOL,H,RWORK(LWT),RWORK(LVT),INFO(1),IDID,RPAR,IPAR, + * RWORK(LPHI),RWORK(LSAVR),RWORK(LDELTA),RWORK(LE), + * RWORK(LWM),IWORK(LIWM), + * RWORK(LALPHA),RWORK(LBETA),RWORK(LGAMMA), + * RWORK(LPSI),RWORK(LSIGMA), + * RWORK(LCJ),RWORK(LCJOLD),RWORK(LHOLD),RWORK(LS),HMIN, + * RWORK(LROUND), RWORK(LEPLI),RWORK(LSQRN),RWORK(LRSQRN), + * RWORK(LEPCON), IWORK(LPHASE),IWORK(LJCALC),INFO(15), + * IWORK(LK), IWORK(LKOLD),IWORK(LNS),NONNEG,INFO(12), + * DNEDK) + ENDIF +C +527 IF(IDID.LT.0)GO TO 600 +C +C----------------------------------------------------------------------- +C This block handles the case of a successful return from DDSTP +C (IDID=1). Test for stop conditions. +C----------------------------------------------------------------------- +C + IF(INFO(4).NE.0)GO TO 540 + IF(INFO(3).NE.0)GO TO 530 + IF((TN-TOUT)*H.LT.0.0D0)GO TO 500 + CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ, + * IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI)) + IDID=3 + T=TOUT + GO TO 580 +530 IF((TN-TOUT)*H.GE.0.0D0)GO TO 535 + T=TN + IDID=1 + GO TO 580 +535 CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ, + * IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI)) + IDID=3 + T=TOUT + GO TO 580 +540 IF(INFO(3).NE.0)GO TO 550 + IF((TN-TOUT)*H.LT.0.0D0)GO TO 542 + CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ, + * IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI)) + T=TOUT + IDID=3 + GO TO 580 +542 IF(ABS(TN-TSTOP).LE.100.0D0*UROUND* + * (ABS(TN)+ABS(H)))GO TO 545 + TNEXT=TN+H + IF((TNEXT-TSTOP)*H.LE.0.0D0)GO TO 500 + H=TSTOP-TN + GO TO 500 +545 CALL DDATRP(TN,TSTOP,Y,YPRIME,NEQ, + * IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI)) + IDID=2 + T=TSTOP + GO TO 580 +550 IF((TN-TOUT)*H.GE.0.0D0)GO TO 555 + IF(ABS(TN-TSTOP).LE.100.0D0*UROUND*(ABS(TN)+ABS(H)))GO TO 552 + T=TN + IDID=1 + GO TO 580 +552 CALL DDATRP(TN,TSTOP,Y,YPRIME,NEQ, + * IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI)) + IDID=2 + T=TSTOP + GO TO 580 +555 CALL DDATRP(TN,TOUT,Y,YPRIME,NEQ, + * IWORK(LKOLD),RWORK(LPHI),RWORK(LPSI)) + T=TOUT + IDID=3 +580 CONTINUE +C +C----------------------------------------------------------------------- +C All successful returns from DDASPK are made from this block. +C----------------------------------------------------------------------- +C +590 CONTINUE + RWORK(LTN)=TN + RWORK(LH)=H + RETURN +C +C----------------------------------------------------------------------- +C This block handles all unsuccessful returns other than for +C illegal input. +C----------------------------------------------------------------------- +C +600 CONTINUE + ITEMP = -IDID + GO TO (610,620,630,700,655,640,650,660,670,675, + * 680,685,690,695), ITEMP +C +C The maximum number of steps was taken before +C reaching tout. +C +610 MSG = 'DASPK-- AT CURRENT T (=R1) 500 STEPS' + CALL XERRWD(MSG,38,610,0,0,0,0,1,TN,0.0D0) + MSG = 'DASPK-- TAKEN ON THIS CALL BEFORE REACHING TOUT' + CALL XERRWD(MSG,48,611,0,0,0,0,0,0.0D0,0.0D0) + GO TO 700 +C +C Too much accuracy for machine precision. +C +620 MSG = 'DASPK-- AT T (=R1) TOO MUCH ACCURACY REQUESTED' + CALL XERRWD(MSG,47,620,0,0,0,0,1,TN,0.0D0) + MSG = 'DASPK-- FOR PRECISION OF MACHINE. RTOL AND ATOL' + CALL XERRWD(MSG,48,621,0,0,0,0,0,0.0D0,0.0D0) + MSG = 'DASPK-- WERE INCREASED TO APPROPRIATE VALUES' + CALL XERRWD(MSG,45,622,0,0,0,0,0,0.0D0,0.0D0) + GO TO 700 +C +C WT(I) .LE. 0.0D0 for some I (not at start of problem). +C +630 MSG = 'DASPK-- AT T (=R1) SOME ELEMENT OF WT' + CALL XERRWD(MSG,38,630,0,0,0,0,1,TN,0.0D0) + MSG = 'DASPK-- HAS BECOME .LE. 0.0' + CALL XERRWD(MSG,28,631,0,0,0,0,0,0.0D0,0.0D0) + GO TO 700 +C +C Error test failed repeatedly or with H=HMIN. +C +640 MSG = 'DASPK-- AT T (=R1) AND STEPSIZE H (=R2) THE' + CALL XERRWD(MSG,44,640,0,0,0,0,2,TN,H) + MSG='DASPK-- ERROR TEST FAILED REPEATEDLY OR WITH ABS(H)=HMIN' + CALL XERRWD(MSG,57,641,0,0,0,0,0,0.0D0,0.0D0) + GO TO 700 +C +C Nonlinear solver failed to converge repeatedly or with H=HMIN. +C +650 MSG = 'DASPK-- AT T (=R1) AND STEPSIZE H (=R2) THE' + CALL XERRWD(MSG,44,650,0,0,0,0,2,TN,H) + MSG = 'DASPK-- NONLINEAR SOLVER FAILED TO CONVERGE' + CALL XERRWD(MSG,44,651,0,0,0,0,0,0.0D0,0.0D0) + MSG = 'DASPK-- REPEATEDLY OR WITH ABS(H)=HMIN' + CALL XERRWD(MSG,40,652,0,0,0,0,0,0.0D0,0.0D0) + GO TO 700 +C +C The preconditioner had repeated failures. +C +655 MSG = 'DASPK-- AT T (=R1) AND STEPSIZE H (=R2) THE' + CALL XERRWD(MSG,44,655,0,0,0,0,2,TN,H) + MSG = 'DASPK-- PRECONDITIONER HAD REPEATED FAILURES.' + CALL XERRWD(MSG,46,656,0,0,0,0,0,0.0D0,0.0D0) + GO TO 700 +C +C The iteration matrix is singular. +C +660 MSG = 'DASPK-- AT T (=R1) AND STEPSIZE H (=R2) THE' + CALL XERRWD(MSG,44,660,0,0,0,0,2,TN,H) + MSG = 'DASPK-- ITERATION MATRIX IS SINGULAR.' + CALL XERRWD(MSG,38,661,0,0,0,0,0,0.0D0,0.0D0) + GO TO 700 +C +C Nonlinear system failure preceded by error test failures. +C +670 MSG = 'DASPK-- AT T (=R1) AND STEPSIZE H (=R2) THE' + CALL XERRWD(MSG,44,670,0,0,0,0,2,TN,H) + MSG = 'DASPK-- NONLINEAR SOLVER COULD NOT CONVERGE.' + CALL XERRWD(MSG,45,671,0,0,0,0,0,0.0D0,0.0D0) + MSG = 'DASPK-- ALSO, THE ERROR TEST FAILED REPEATEDLY.' + CALL XERRWD(MSG,49,672,0,0,0,0,0,0.0D0,0.0D0) + GO TO 700 +C +C Nonlinear system failure because IRES = -1. +C +675 MSG = 'DASPK-- AT T (=R1) AND STEPSIZE H (=R2) THE' + CALL XERRWD(MSG,44,675,0,0,0,0,2,TN,H) + MSG = 'DASPK-- NONLINEAR SYSTEM SOLVER COULD NOT CONVERGE' + CALL XERRWD(MSG,51,676,0,0,0,0,0,0.0D0,0.0D0) + MSG = 'DASPK-- BECAUSE IRES WAS EQUAL TO MINUS ONE' + CALL XERRWD(MSG,44,677,0,0,0,0,0,0.0D0,0.0D0) + GO TO 700 +C +C Failure because IRES = -2. +C +680 MSG = 'DASPK-- AT T (=R1) AND STEPSIZE H (=R2)' + CALL XERRWD(MSG,40,680,0,0,0,0,2,TN,H) + MSG = 'DASPK-- IRES WAS EQUAL TO MINUS TWO' + CALL XERRWD(MSG,36,681,0,0,0,0,0,0.0D0,0.0D0) + GO TO 700 +C +C Failed to compute initial YPRIME. +C +685 MSG = 'DASPK-- AT T (=R1) AND STEPSIZE H (=R2) THE' + CALL XERRWD(MSG,44,685,0,0,0,0,0,0.0D0,0.0D0) + MSG = 'DASPK-- INITIAL (Y,YPRIME) COULD NOT BE COMPUTED' + CALL XERRWD(MSG,49,686,0,0,0,0,2,TN,H0) + GO TO 700 +C +C Failure because IER was negative from PSOL. +C +690 MSG = 'DASPK-- AT T (=R1) AND STEPSIZE H (=R2)' + CALL XERRWD(MSG,40,690,0,0,0,0,2,TN,H) + MSG = 'DASPK-- IER WAS NEGATIVE FROM PSOL' + CALL XERRWD(MSG,35,691,0,0,0,0,0,0.0D0,0.0D0) + GO TO 700 +C +C Failure because the linear system solver could not converge. +C +695 MSG = 'DASPK-- AT T (=R1) AND STEPSIZE H (=R2) THE' + CALL XERRWD(MSG,44,695,0,0,0,0,2,TN,H) + MSG = 'DASPK-- LINEAR SYSTEM SOLVER COULD NOT CONVERGE.' + CALL XERRWD(MSG,50,696,0,0,0,0,0,0.0D0,0.0D0) + GO TO 700 +C +C +700 CONTINUE + INFO(1)=-1 + T=TN + RWORK(LTN)=TN + RWORK(LH)=H + RETURN +C +C----------------------------------------------------------------------- +C This block handles all error returns due to illegal input, +C as detected before calling DDSTP. +C First the error message routine is called. If this happens +C twice in succession, execution is terminated. +C----------------------------------------------------------------------- +C +701 MSG = 'DASPK-- ELEMENT (=I1) OF INFO VECTOR IS NOT VALID' + CALL XERRWD(MSG,50,1,0,1,ITEMP,0,0,0.0D0,0.0D0) + GO TO 750 +702 MSG = 'DASPK-- NEQ (=I1) .LE. 0' + CALL XERRWD(MSG,25,2,0,1,NEQ,0,0,0.0D0,0.0D0) + GO TO 750 +703 MSG = 'DASPK-- MAXORD (=I1) NOT IN RANGE' + CALL XERRWD(MSG,34,3,0,1,MXORD,0,0,0.0D0,0.0D0) + GO TO 750 +704 MSG='DASPK-- RWORK LENGTH NEEDED, LENRW (=I1), EXCEEDS LRW (=I2)' + CALL XERRWD(MSG,60,4,0,2,LENRW,LRW,0,0.0D0,0.0D0) + GO TO 750 +705 MSG='DASPK-- IWORK LENGTH NEEDED, LENIW (=I1), EXCEEDS LIW (=I2)' + CALL XERRWD(MSG,60,5,0,2,LENIW,LIW,0,0.0D0,0.0D0) + GO TO 750 +706 MSG = 'DASPK-- SOME ELEMENT OF RTOL IS .LT. 0' + CALL XERRWD(MSG,39,6,0,0,0,0,0,0.0D0,0.0D0) + GO TO 750 +707 MSG = 'DASPK-- SOME ELEMENT OF ATOL IS .LT. 0' + CALL XERRWD(MSG,39,7,0,0,0,0,0,0.0D0,0.0D0) + GO TO 750 +708 MSG = 'DASPK-- ALL ELEMENTS OF RTOL AND ATOL ARE ZERO' + CALL XERRWD(MSG,47,8,0,0,0,0,0,0.0D0,0.0D0) + GO TO 750 +709 MSG='DASPK-- INFO(4) = 1 AND TSTOP (=R1) BEHIND TOUT (=R2)' + CALL XERRWD(MSG,54,9,0,0,0,0,2,TSTOP,TOUT) + GO TO 750 +710 MSG = 'DASPK-- HMAX (=R1) .LT. 0.0' + CALL XERRWD(MSG,28,10,0,0,0,0,1,HMAX,0.0D0) + GO TO 750 +711 MSG = 'DASPK-- TOUT (=R1) BEHIND T (=R2)' + CALL XERRWD(MSG,34,11,0,0,0,0,2,TOUT,T) + GO TO 750 +712 MSG = 'DASPK-- INFO(8)=1 AND H0=0.0' + CALL XERRWD(MSG,29,12,0,0,0,0,0,0.0D0,0.0D0) + GO TO 750 +713 MSG = 'DASPK-- SOME ELEMENT OF WT IS .LE. 0.0' + CALL XERRWD(MSG,39,13,0,0,0,0,0,0.0D0,0.0D0) + GO TO 750 +714 MSG='DASPK-- TOUT (=R1) TOO CLOSE TO T (=R2) TO START INTEGRATION' + CALL XERRWD(MSG,60,14,0,0,0,0,2,TOUT,T) + GO TO 750 +715 MSG = 'DASPK-- INFO(4)=1 AND TSTOP (=R1) BEHIND T (=R2)' + CALL XERRWD(MSG,49,15,0,0,0,0,2,TSTOP,T) + GO TO 750 +717 MSG = 'DASPK-- ML (=I1) ILLEGAL. EITHER .LT. 0 OR .GT. NEQ' + CALL XERRWD(MSG,52,17,0,1,IWORK(LML),0,0,0.0D0,0.0D0) + GO TO 750 +718 MSG = 'DASPK-- MU (=I1) ILLEGAL. EITHER .LT. 0 OR .GT. NEQ' + CALL XERRWD(MSG,52,18,0,1,IWORK(LMU),0,0,0.0D0,0.0D0) + GO TO 750 +719 MSG = 'DASPK-- TOUT (=R1) IS EQUAL TO T (=R2)' + CALL XERRWD(MSG,39,19,0,0,0,0,2,TOUT,T) + GO TO 750 +720 MSG = 'DASPK-- MAXL (=I1) ILLEGAL. EITHER .LT. 1 OR .GT. NEQ' + CALL XERRWD(MSG,54,20,0,1,IWORK(LMAXL),0,0,0.0D0,0.0D0) + GO TO 750 +721 MSG = 'DASPK-- KMP (=I1) ILLEGAL. EITHER .LT. 1 OR .GT. MAXL' + CALL XERRWD(MSG,54,21,0,1,IWORK(LKMP),0,0,0.0D0,0.0D0) + GO TO 750 +722 MSG = 'DASPK-- NRMAX (=I1) ILLEGAL. .LT. 0' + CALL XERRWD(MSG,36,22,0,1,IWORK(LNRMAX),0,0,0.0D0,0.0D0) + GO TO 750 +723 MSG = 'DASPK-- EPLI (=R1) ILLEGAL. EITHER .LE. 0.D0 OR .GE. 1.D0' + CALL XERRWD(MSG,58,23,0,0,0,0,1,RWORK(LEPLI),0.0D0) + GO TO 750 +724 MSG = 'DASPK-- ILLEGAL IWORK VALUE FOR INFO(11) .NE. 0' + CALL XERRWD(MSG,48,24,0,0,0,0,0,0.0D0,0.0D0) + GO TO 750 +725 MSG = 'DASPK-- ONE OF THE INPUTS FOR INFO(17) = 1 IS ILLEGAL' + CALL XERRWD(MSG,54,25,0,0,0,0,0,0.0D0,0.0D0) + GO TO 750 +726 MSG = 'DASPK-- ILLEGAL IWORK VALUE FOR INFO(10) .NE. 0' + CALL XERRWD(MSG,48,26,0,0,0,0,0,0.0D0,0.0D0) + GO TO 750 +727 MSG = 'DASPK-- Y(I) AND IWORK(40+I) (I=I1) INCONSISTENT' + CALL XERRWD(MSG,49,27,0,1,IRET,0,0,0.0D0,0.0D0) + GO TO 750 +750 IF(INFO(1).EQ.-1) GO TO 760 + INFO(1)=-1 + IDID=-33 + RETURN +760 MSG = 'DASPK-- REPEATED OCCURRENCES OF ILLEGAL INPUT' + CALL XERRWD(MSG,46,701,0,0,0,0,0,0.0D0,0.0D0) +770 MSG = 'DASPK-- RUN TERMINATED. APPARENT INFINITE LOOP' + CALL XERRWD(MSG,47,702,1,0,0,0,0,0.0D0,0.0D0) + RETURN +C +C------END OF SUBROUTINE DDASPK----------------------------------------- + END + SUBROUTINE DDASIC (X, Y, YPRIME, NEQ, ICOPT, ID, RES, JAC, PSOL, + * H, TSCALE, WT, NIC, IDID, RPAR, IPAR, PHI, SAVR, DELTA, E, + * YIC, YPIC, PWK, WM, IWM, UROUND, EPLI, SQRTN, RSQRTN, + * EPCONI, STPTOL, JFLG, ICNFLG, ICNSTR, NLSIC) +C +C***BEGIN PROLOGUE DDASIC +C***REFER TO DDASPK +C***DATE WRITTEN 940628 (YYMMDD) +C***REVISION DATE 941206 (YYMMDD) +C***REVISION DATE 950714 (YYMMDD) +C***REVISION DATE 000628 TSCALE argument added. +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C DDASIC is a driver routine to compute consistent initial values +C for Y and YPRIME. There are two different options: +C Denoting the differential variables in Y by Y_d, and +C the algebraic variables by Y_a, the problem solved is either: +C 1. Given Y_d, calculate Y_a and Y_d', or +C 2. Given Y', calculate Y. +C In either case, initial values for the given components +C are input, and initial guesses for the unknown components +C must also be provided as input. +C +C The external routine NLSIC solves the resulting nonlinear system. +C +C The parameters represent +C +C X -- Independent variable. +C Y -- Solution vector at X. +C YPRIME -- Derivative of solution vector. +C NEQ -- Number of equations to be integrated. +C ICOPT -- Flag indicating initial condition option chosen. +C ICOPT = 1 for option 1 above. +C ICOPT = 2 for option 2. +C ID -- Array of dimension NEQ, which must be initialized +C if option 1 is chosen. +C ID(i) = +1 if Y_i is a differential variable, +C ID(i) = -1 if Y_i is an algebraic variable. +C RES -- External user-supplied subroutine to evaluate the +C residual. See RES description in DDASPK prologue. +C JAC -- External user-supplied routine to update Jacobian +C or preconditioner information in the nonlinear solver +C (optional). See JAC description in DDASPK prologue. +C PSOL -- External user-supplied routine to solve +C a linear system using preconditioning. +C See PSOL in DDASPK prologue. +C H -- Scaling factor in iteration matrix. DDASIC may +C reduce H to achieve convergence. +C TSCALE -- Scale factor in T, used for stopping tests if nonzero. +C WT -- Vector of weights for error criterion. +C NIC -- Input number of initial condition calculation call +C (= 1 or 2). +C IDID -- Completion code. See IDID in DDASPK prologue. +C RPAR,IPAR -- Real and integer parameter arrays that +C are used for communication between the +C calling program and external user routines. +C They are not altered by DNSK +C PHI -- Work space for DDASIC of length at least 2*NEQ. +C SAVR -- Work vector for DDASIC of length NEQ. +C DELTA -- Work vector for DDASIC of length NEQ. +C E -- Work vector for DDASIC of length NEQ. +C YIC,YPIC -- Work vectors for DDASIC, each of length NEQ. +C PWK -- Work vector for DDASIC of length NEQ. +C WM,IWM -- Real and integer arrays storing +C information required by the linear solver. +C EPCONI -- Test constant for Newton iteration convergence. +C ICNFLG -- Flag showing whether constraints on Y are to apply. +C ICNSTR -- Integer array of length NEQ with constraint types. +C +C The other parameters are for use internally by DDASIC. +C +C----------------------------------------------------------------------- +C***ROUTINES CALLED +C DCOPY, NLSIC +C +C***END PROLOGUE DDASIC +C +C + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + DIMENSION Y(*),YPRIME(*),ID(*),WT(*),PHI(NEQ,*) + DIMENSION SAVR(*),DELTA(*),E(*),YIC(*),YPIC(*),PWK(*) + DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*), ICNSTR(*) + EXTERNAL RES, JAC, PSOL, NLSIC +C + PARAMETER (LCFN=15) + PARAMETER (LMXNH=34) +C +C The following parameters are data-loaded here: +C RHCUT = factor by which H is reduced on retry of Newton solve. +C RATEMX = maximum convergence rate for which Newton iteration +C is considered converging. +C + SAVE RHCUT, RATEMX + DATA RHCUT/0.1D0/, RATEMX/0.8D0/ +C +C +C----------------------------------------------------------------------- +C BLOCK 1. +C Initializations. +C JSKIP is a flag set to 1 when NIC = 2 and NH = 1, to signal that +C the initial call to the JAC routine is to be skipped then. +C Save Y and YPRIME in PHI. Initialize IDID, NH, and CJ. +C----------------------------------------------------------------------- +C + MXNH = IWM(LMXNH) + IDID = 1 + NH = 1 + JSKIP = 0 + IF (NIC .EQ. 2) JSKIP = 1 + CALL DCOPY (NEQ, Y, 1, PHI(1,1), 1) + CALL DCOPY (NEQ, YPRIME, 1, PHI(1,2), 1) +C + IF (ICOPT .EQ. 2) THEN + CJ = 0.0D0 + ELSE + CJ = 1.0D0/H + ENDIF +C +C----------------------------------------------------------------------- +C BLOCK 2 +C Call the nonlinear system solver to obtain +C consistent initial values for Y and YPRIME. +C----------------------------------------------------------------------- +C + 200 CONTINUE + CALL NLSIC(X,Y,YPRIME,NEQ,ICOPT,ID,RES,JAC,PSOL,H,TSCALE,WT, + * JSKIP,RPAR,IPAR,SAVR,DELTA,E,YIC,YPIC,PWK,WM,IWM,CJ,UROUND, + * EPLI,SQRTN,RSQRTN,EPCONI,RATEMX,STPTOL,JFLG,ICNFLG,ICNSTR, + * IERNLS) +C + IF (IERNLS .EQ. 0) RETURN +C +C----------------------------------------------------------------------- +C BLOCK 3 +C The nonlinear solver was unsuccessful. Increment NCFN. +C Return with IDID = -12 if either +C IERNLS = -1: error is considered unrecoverable, +C ICOPT = 2: we are doing initialization problem type 2, or +C NH = MXNH: the maximum number of H values has been tried. +C Otherwise (problem 1 with IERNLS .GE. 1), reduce H and try again. +C If IERNLS > 1, restore Y and YPRIME to their original values. +C----------------------------------------------------------------------- +C + IWM(LCFN) = IWM(LCFN) + 1 + JSKIP = 0 +C + IF (IERNLS .EQ. -1) GO TO 350 + IF (ICOPT .EQ. 2) GO TO 350 + IF (NH .EQ. MXNH) GO TO 350 +C + NH = NH + 1 + H = H*RHCUT + CJ = 1.0D0/H +C + IF (IERNLS .EQ. 1) GO TO 200 +C + CALL DCOPY (NEQ, PHI(1,1), 1, Y, 1) + CALL DCOPY (NEQ, PHI(1,2), 1, YPRIME, 1) + GO TO 200 +C + 350 IDID = -12 + RETURN +C +C------END OF SUBROUTINE DDASIC----------------------------------------- + END + SUBROUTINE DYYPNW (NEQ, Y, YPRIME, CJ, RL, P, ICOPT, ID, + * YNEW, YPNEW) +C +C***BEGIN PROLOGUE DYYPNW +C***REFER TO DLINSK +C***DATE WRITTEN 940830 (YYMMDD) +C +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C DYYPNW calculates the new (Y,YPRIME) pair needed in the +C linesearch algorithm based on the current lambda value. It is +C called by DLINSK and DLINSD. Based on the ICOPT and ID values, +C the corresponding entry in Y or YPRIME is updated. +C +C In addition to the parameters described in the calling programs, +C the parameters represent +C +C P -- Array of length NEQ that contains the current +C approximate Newton step. +C RL -- Scalar containing the current lambda value. +C YNEW -- Array of length NEQ containing the updated Y vector. +C YPNEW -- Array of length NEQ containing the updated YPRIME +C vector. +C----------------------------------------------------------------------- +C +C***ROUTINES CALLED (NONE) +C +C***END PROLOGUE DYYPNW +C +C + IMPLICIT DOUBLE PRECISION (A-H,O-Z) + DIMENSION Y(*), YPRIME(*), YNEW(*), YPNEW(*), ID(*), P(*) +C + IF (ICOPT .EQ. 1) THEN + DO 10 I=1,NEQ + IF(ID(I) .LT. 0) THEN + YNEW(I) = Y(I) - RL*P(I) + YPNEW(I) = YPRIME(I) + ELSE + YNEW(I) = Y(I) + YPNEW(I) = YPRIME(I) - RL*CJ*P(I) + ENDIF + 10 CONTINUE + ELSE + DO 20 I = 1,NEQ + YNEW(I) = Y(I) - RL*P(I) + YPNEW(I) = YPRIME(I) + 20 CONTINUE + ENDIF + RETURN +C----------------------- END OF SUBROUTINE DYYPNW ---------------------- + END + SUBROUTINE DDSTP(X,Y,YPRIME,NEQ,RES,JAC,PSOL,H,WT,VT, + * JSTART,IDID,RPAR,IPAR,PHI,SAVR,DELTA,E,WM,IWM, + * ALPHA,BETA,GAMMA,PSI,SIGMA,CJ,CJOLD,HOLD,S,HMIN,UROUND, + * EPLI,SQRTN,RSQRTN,EPCON,IPHASE,JCALC,JFLG,K,KOLD,NS,NONNEG, + * NTYPE,NLS) +C +C***BEGIN PROLOGUE DDSTP +C***REFER TO DDASPK +C***DATE WRITTEN 890101 (YYMMDD) +C***REVISION DATE 900926 (YYMMDD) +C***REVISION DATE 940909 (YYMMDD) (Reset PSI(1), PHI(*,2) at 690) +C +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C DDSTP solves a system of differential/algebraic equations of +C the form G(X,Y,YPRIME) = 0, for one step (normally from X to X+H). +C +C The methods used are modified divided difference, fixed leading +C coefficient forms of backward differentiation formulas. +C The code adjusts the stepsize and order to control the local error +C per step. +C +C +C The parameters represent +C X -- Independent variable. +C Y -- Solution vector at X. +C YPRIME -- Derivative of solution vector +C after successful step. +C NEQ -- Number of equations to be integrated. +C RES -- External user-supplied subroutine +C to evaluate the residual. See RES description +C in DDASPK prologue. +C JAC -- External user-supplied routine to update +C Jacobian or preconditioner information in the +C nonlinear solver. See JAC description in DDASPK +C prologue. +C PSOL -- External user-supplied routine to solve +C a linear system using preconditioning. +C (This is optional). See PSOL in DDASPK prologue. +C H -- Appropriate step size for next step. +C Normally determined by the code. +C WT -- Vector of weights for error criterion used in Newton test. +C VT -- Masked vector of weights used in error test. +C JSTART -- Integer variable set 0 for +C first step, 1 otherwise. +C IDID -- Completion code returned from the nonlinear solver. +C See IDID description in DDASPK prologue. +C RPAR,IPAR -- Real and integer parameter arrays that +C are used for communication between the +C calling program and external user routines. +C They are not altered by DNSK +C PHI -- Array of divided differences used by +C DDSTP. The length is NEQ*(K+1), where +C K is the maximum order. +C SAVR -- Work vector for DDSTP of length NEQ. +C DELTA,E -- Work vectors for DDSTP of length NEQ. +C WM,IWM -- Real and integer arrays storing +C information required by the linear solver. +C +C The other parameters are information +C which is needed internally by DDSTP to +C continue from step to step. +C +C----------------------------------------------------------------------- +C***ROUTINES CALLED +C NLS, DDWNRM, DDATRP +C +C***END PROLOGUE DDSTP +C +C + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + DIMENSION Y(*),YPRIME(*),WT(*),VT(*) + DIMENSION PHI(NEQ,*),SAVR(*),DELTA(*),E(*) + DIMENSION WM(*),IWM(*) + DIMENSION PSI(*),ALPHA(*),BETA(*),GAMMA(*),SIGMA(*) + DIMENSION RPAR(*),IPAR(*) + EXTERNAL RES, JAC, PSOL, NLS +C + PARAMETER (LMXORD=3) + PARAMETER (LNST=11, LETF=14, LCFN=15) +C +C +C----------------------------------------------------------------------- +C BLOCK 1. +C Initialize. On the first call, set +C the order to 1 and initialize +C other variables. +C----------------------------------------------------------------------- +C +C Initializations for all calls +C + XOLD=X + NCF=0 + NEF=0 + IF(JSTART .NE. 0) GO TO 120 +C +C If this is the first step, perform +C other initializations +C + K=1 + KOLD=0 + HOLD=0.0D0 + PSI(1)=H + CJ = 1.D0/H + IPHASE = 0 + NS=0 +120 CONTINUE +C +C +C +C +C +C----------------------------------------------------------------------- +C BLOCK 2 +C Compute coefficients of formulas for +C this step. +C----------------------------------------------------------------------- +200 CONTINUE + KP1=K+1 + KP2=K+2 + KM1=K-1 + IF(H.NE.HOLD.OR.K .NE. KOLD) NS = 0 + NS=MIN0(NS+1,KOLD+2) + NSP1=NS+1 + IF(KP1 .LT. NS)GO TO 230 +C + BETA(1)=1.0D0 + ALPHA(1)=1.0D0 + TEMP1=H + GAMMA(1)=0.0D0 + SIGMA(1)=1.0D0 + DO 210 I=2,KP1 + TEMP2=PSI(I-1) + PSI(I-1)=TEMP1 + BETA(I)=BETA(I-1)*PSI(I-1)/TEMP2 + TEMP1=TEMP2+H + ALPHA(I)=H/TEMP1 + SIGMA(I)=(I-1)*SIGMA(I-1)*ALPHA(I) + GAMMA(I)=GAMMA(I-1)+ALPHA(I-1)/H +210 CONTINUE + PSI(KP1)=TEMP1 +230 CONTINUE +C +C Compute ALPHAS, ALPHA0 +C + ALPHAS = 0.0D0 + ALPHA0 = 0.0D0 + DO 240 I = 1,K + ALPHAS = ALPHAS - 1.0D0/I + ALPHA0 = ALPHA0 - ALPHA(I) +240 CONTINUE +C +C Compute leading coefficient CJ +C + CJLAST = CJ + CJ = -ALPHAS/H +C +C Compute variable stepsize error coefficient CK +C + CK = ABS(ALPHA(KP1) + ALPHAS - ALPHA0) + CK = MAX(CK,ALPHA(KP1)) +C +C Change PHI to PHI STAR +C + IF(KP1 .LT. NSP1) GO TO 280 + DO 270 J=NSP1,KP1 + DO 260 I=1,NEQ +260 PHI(I,J)=BETA(J)*PHI(I,J) +270 CONTINUE +280 CONTINUE +C +C Update time +C + X=X+H +C +C Initialize IDID to 1 +C + IDID = 1 +C +C +C +C +C +C----------------------------------------------------------------------- +C BLOCK 3 +C Call the nonlinear system solver to obtain the solution and +C derivative. +C----------------------------------------------------------------------- +C + CALL NLS(X,Y,YPRIME,NEQ, + * RES,JAC,PSOL,H,WT,JSTART,IDID,RPAR,IPAR,PHI,GAMMA, + * SAVR,DELTA,E,WM,IWM,CJ,CJOLD,CJLAST,S, + * UROUND,EPLI,SQRTN,RSQRTN,EPCON,JCALC,JFLG,KP1, + * NONNEG,NTYPE,IERNLS) +C + IF(IERNLS .NE. 0)GO TO 600 +C +C +C +C +C +C----------------------------------------------------------------------- +C BLOCK 4 +C Estimate the errors at orders K,K-1,K-2 +C as if constant stepsize was used. Estimate +C the local error at order K and test +C whether the current step is successful. +C----------------------------------------------------------------------- +C +C Estimate errors at orders K,K-1,K-2 +C + ENORM = DDWNRM(NEQ,E,VT,RPAR,IPAR) + ERK = SIGMA(K+1)*ENORM + TERK = (K+1)*ERK + EST = ERK + KNEW=K + IF(K .EQ. 1)GO TO 430 + DO 405 I = 1,NEQ +405 DELTA(I) = PHI(I,KP1) + E(I) + ERKM1=SIGMA(K)*DDWNRM(NEQ,DELTA,VT,RPAR,IPAR) + TERKM1 = K*ERKM1 + IF(K .GT. 2)GO TO 410 + IF(TERKM1 .LE. 0.5*TERK)GO TO 420 + GO TO 430 +410 CONTINUE + DO 415 I = 1,NEQ +415 DELTA(I) = PHI(I,K) + DELTA(I) + ERKM2=SIGMA(K-1)*DDWNRM(NEQ,DELTA,VT,RPAR,IPAR) + TERKM2 = (K-1)*ERKM2 + IF(MAX(TERKM1,TERKM2).GT.TERK)GO TO 430 +C +C Lower the order +C +420 CONTINUE + KNEW=K-1 + EST = ERKM1 +C +C +C Calculate the local error for the current step +C to see if the step was successful +C +430 CONTINUE + ERR = CK * ENORM + IF(ERR .GT. 1.0D0)GO TO 600 +C +C +C +C +C +C----------------------------------------------------------------------- +C BLOCK 5 +C The step is successful. Determine +C the best order and stepsize for +C the next step. Update the differences +C for the next step. +C----------------------------------------------------------------------- + IDID=1 + IWM(LNST)=IWM(LNST)+1 + KDIFF=K-KOLD + KOLD=K + HOLD=H +C +C +C Estimate the error at order K+1 unless +C already decided to lower order, or +C already using maximum order, or +C stepsize not constant, or +C order raised in previous step +C + IF(KNEW.EQ.KM1.OR.K.EQ.IWM(LMXORD))IPHASE=1 + IF(IPHASE .EQ. 0)GO TO 545 + IF(KNEW.EQ.KM1)GO TO 540 + IF(K.EQ.IWM(LMXORD)) GO TO 550 + IF(KP1.GE.NS.OR.KDIFF.EQ.1)GO TO 550 + DO 510 I=1,NEQ +510 DELTA(I)=E(I)-PHI(I,KP2) + ERKP1 = (1.0D0/(K+2))*DDWNRM(NEQ,DELTA,VT,RPAR,IPAR) + TERKP1 = (K+2)*ERKP1 + IF(K.GT.1)GO TO 520 + IF(TERKP1.GE.0.5D0*TERK)GO TO 550 + GO TO 530 +520 IF(TERKM1.LE.MIN(TERK,TERKP1))GO TO 540 + IF(TERKP1.GE.TERK.OR.K.EQ.IWM(LMXORD))GO TO 550 +C +C Raise order +C +530 K=KP1 + EST = ERKP1 + GO TO 550 +C +C Lower order +C +540 K=KM1 + EST = ERKM1 + GO TO 550 +C +C If IPHASE = 0, increase order by one and multiply stepsize by +C factor two +C +545 K = KP1 + HNEW = H*2.0D0 + H = HNEW + GO TO 575 +C +C +C Determine the appropriate stepsize for +C the next step. +C +550 HNEW=H + TEMP2=K+1 + R=(2.0D0*EST+0.0001D0)**(-1.0D0/TEMP2) + IF(R .LT. 2.0D0) GO TO 555 + HNEW = 2.0D0*H + GO TO 560 +555 IF(R .GT. 1.0D0) GO TO 560 + R = MAX(0.5D0,MIN(0.9D0,R)) + HNEW = H*R +560 H=HNEW +C +C +C Update differences for next step +C +575 CONTINUE + IF(KOLD.EQ.IWM(LMXORD))GO TO 585 + DO 580 I=1,NEQ +580 PHI(I,KP2)=E(I) +585 CONTINUE + DO 590 I=1,NEQ +590 PHI(I,KP1)=PHI(I,KP1)+E(I) + DO 595 J1=2,KP1 + J=KP1-J1+1 + DO 595 I=1,NEQ +595 PHI(I,J)=PHI(I,J)+PHI(I,J+1) + JSTART = 1 + RETURN +C +C +C +C +C +C----------------------------------------------------------------------- +C BLOCK 6 +C The step is unsuccessful. Restore X,PSI,PHI +C Determine appropriate stepsize for +C continuing the integration, or exit with +C an error flag if there have been many +C failures. +C----------------------------------------------------------------------- +600 IPHASE = 1 +C +C Restore X,PHI,PSI +C + X=XOLD + IF(KP1.LT.NSP1)GO TO 630 + DO 620 J=NSP1,KP1 + TEMP1=1.0D0/BETA(J) + DO 610 I=1,NEQ +610 PHI(I,J)=TEMP1*PHI(I,J) +620 CONTINUE +630 CONTINUE + DO 640 I=2,KP1 +640 PSI(I-1)=PSI(I)-H +C +C +C Test whether failure is due to nonlinear solver +C or error test +C + IF(IERNLS .EQ. 0)GO TO 660 + IWM(LCFN)=IWM(LCFN)+1 +C +C +C The nonlinear solver failed to converge. +C Determine the cause of the failure and take appropriate action. +C If IERNLS .LT. 0, then return. Otherwise, reduce the stepsize +C and try again, unless too many failures have occurred. +C + IF (IERNLS .LT. 0) GO TO 675 + NCF = NCF + 1 + R = 0.25D0 + H = H*R + IF (NCF .LT. 10 .AND. ABS(H) .GE. HMIN) GO TO 690 + IF (IDID .EQ. 1) IDID = -7 + IF (NEF .GE. 3) IDID = -9 + GO TO 675 +C +C +C The nonlinear solver converged, and the cause +C of the failure was the error estimate +C exceeding the tolerance. +C +660 NEF=NEF+1 + IWM(LETF)=IWM(LETF)+1 + IF (NEF .GT. 1) GO TO 665 +C +C On first error test failure, keep current order or lower +C order by one. Compute new stepsize based on differences +C of the solution. +C + K = KNEW + TEMP2 = K + 1 + R = 0.90D0*(2.0D0*EST+0.0001D0)**(-1.0D0/TEMP2) + R = MAX(0.25D0,MIN(0.9D0,R)) + H = H*R + IF (ABS(H) .GE. HMIN) GO TO 690 + IDID = -6 + GO TO 675 +C +C On second error test failure, use the current order or +C decrease order by one. Reduce the stepsize by a factor of +C one quarter. +C +665 IF (NEF .GT. 2) GO TO 670 + K = KNEW + R = 0.25D0 + H = R*H + IF (ABS(H) .GE. HMIN) GO TO 690 + IDID = -6 + GO TO 675 +C +C On third and subsequent error test failures, set the order to +C one, and reduce the stepsize by a factor of one quarter. +C +670 K = 1 + R = 0.25D0 + H = R*H + IF (ABS(H) .GE. HMIN) GO TO 690 + IDID = -6 + GO TO 675 +C +C +C +C +C For all crashes, restore Y to its last value, +C interpolate to find YPRIME at last X, and return. +C +C Before returning, verify that the user has not set +C IDID to a nonnegative value. If the user has set IDID +C to a nonnegative value, then reset IDID to be -7, indicating +C a failure in the nonlinear system solver. +C +675 CONTINUE + CALL DDATRP(X,X,Y,YPRIME,NEQ,K,PHI,PSI) + JSTART = 1 + IF (IDID .GE. 0) IDID = -7 + RETURN +C +C +C Go back and try this step again. +C If this is the first step, reset PSI(1) and rescale PHI(*,2). +C +690 IF (KOLD .EQ. 0) THEN + PSI(1) = H + DO 695 I = 1,NEQ +695 PHI(I,2) = R*PHI(I,2) + ENDIF + GO TO 200 +C +C------END OF SUBROUTINE DDSTP------------------------------------------ + END + SUBROUTINE DCNSTR (NEQ, Y, YNEW, ICNSTR, TAU, RLX, IRET, IVAR) +C +C***BEGIN PROLOGUE DCNSTR +C***DATE WRITTEN 950808 (YYMMDD) +C***REVISION DATE 950814 (YYMMDD) +C +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C This subroutine checks for constraint violations in the proposed +C new approximate solution YNEW. +C If a constraint violation occurs, then a new step length, TAU, +C is calculated, and this value is to be given to the linesearch routine +C to calculate a new approximate solution YNEW. +C +C On entry: +C +C NEQ -- size of the nonlinear system, and the length of arrays +C Y, YNEW and ICNSTR. +C +C Y -- real array containing the current approximate y. +C +C YNEW -- real array containing the new approximate y. +C +C ICNSTR -- INTEGER array of length NEQ containing flags indicating +C which entries in YNEW are to be constrained. +C if ICNSTR(I) = 2, then YNEW(I) must be .GT. 0, +C if ICNSTR(I) = 1, then YNEW(I) must be .GE. 0, +C if ICNSTR(I) = -1, then YNEW(I) must be .LE. 0, while +C if ICNSTR(I) = -2, then YNEW(I) must be .LT. 0, while +C if ICNSTR(I) = 0, then YNEW(I) is not constrained. +C +C RLX -- real scalar restricting update, if ICNSTR(I) = 2 or -2, +C to ABS( (YNEW-Y)/Y ) < FAC2*RLX in component I. +C +C TAU -- the current size of the step length for the linesearch. +C +C On return +C +C TAU -- the adjusted size of the step length if a constraint +C violation occurred (otherwise, it is unchanged). it is +C the step length to give to the linesearch routine. +C +C IRET -- output flag. +C IRET=0 means that YNEW satisfied all constraints. +C IRET=1 means that YNEW failed to satisfy all the +C constraints, and a new linesearch step +C must be computed. +C +C IVAR -- index of variable causing constraint to be violated. +C +C----------------------------------------------------------------------- + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + DIMENSION Y(NEQ), YNEW(NEQ), ICNSTR(NEQ) + SAVE FAC, FAC2, ZERO + DATA FAC /0.6D0/, FAC2 /0.9D0/, ZERO/0.0D0/ +C----------------------------------------------------------------------- +C Check constraints for proposed new step YNEW. If a constraint has +C been violated, then calculate a new step length, TAU, to be +C used in the linesearch routine. +C----------------------------------------------------------------------- + IRET = 0 + RDYMX = ZERO + IVAR = 0 + DO 100 I = 1,NEQ +C + IF (ICNSTR(I) .EQ. 2) THEN + RDY = ABS( (YNEW(I)-Y(I))/Y(I) ) + IF (RDY .GT. RDYMX) THEN + RDYMX = RDY + IVAR = I + ENDIF + IF (YNEW(I) .LE. ZERO) THEN + TAU = FAC*TAU + IVAR = I + IRET = 1 + RETURN + ENDIF +C + ELSEIF (ICNSTR(I) .EQ. 1) THEN + IF (YNEW(I) .LT. ZERO) THEN + TAU = FAC*TAU + IVAR = I + IRET = 1 + RETURN + ENDIF +C + ELSEIF (ICNSTR(I) .EQ. -1) THEN + IF (YNEW(I) .GT. ZERO) THEN + TAU = FAC*TAU + IVAR = I + IRET = 1 + RETURN + ENDIF +C + ELSEIF (ICNSTR(I) .EQ. -2) THEN + RDY = ABS( (YNEW(I)-Y(I))/Y(I) ) + IF (RDY .GT. RDYMX) THEN + RDYMX = RDY + IVAR = I + ENDIF + IF (YNEW(I) .GE. ZERO) THEN + TAU = FAC*TAU + IVAR = I + IRET = 1 + RETURN + ENDIF +C + ENDIF + 100 CONTINUE + + IF(RDYMX .GE. RLX) THEN + TAU = FAC2*TAU*RLX/RDYMX + IRET = 1 + ENDIF +C + RETURN +C----------------------- END OF SUBROUTINE DCNSTR ---------------------- + END + SUBROUTINE DCNST0 (NEQ, Y, ICNSTR, IRET) +C +C***BEGIN PROLOGUE DCNST0 +C***DATE WRITTEN 950808 (YYMMDD) +C***REVISION DATE 950808 (YYMMDD) +C +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C This subroutine checks for constraint violations in the initial +C approximate solution u. +C +C On entry +C +C NEQ -- size of the nonlinear system, and the length of arrays +C Y and ICNSTR. +C +C Y -- real array containing the initial approximate root. +C +C ICNSTR -- INTEGER array of length NEQ containing flags indicating +C which entries in Y are to be constrained. +C if ICNSTR(I) = 2, then Y(I) must be .GT. 0, +C if ICNSTR(I) = 1, then Y(I) must be .GE. 0, +C if ICNSTR(I) = -1, then Y(I) must be .LE. 0, while +C if ICNSTR(I) = -2, then Y(I) must be .LT. 0, while +C if ICNSTR(I) = 0, then Y(I) is not constrained. +C +C On return +C +C IRET -- output flag. +C IRET=0 means that u satisfied all constraints. +C IRET.NE.0 means that Y(IRET) failed to satisfy its +C constraint. +C +C----------------------------------------------------------------------- + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + DIMENSION Y(NEQ), ICNSTR(NEQ) + SAVE ZERO + DATA ZERO/0.D0/ +C----------------------------------------------------------------------- +C Check constraints for initial Y. If a constraint has been violated, +C set IRET = I to signal an error return to calling routine. +C----------------------------------------------------------------------- + IRET = 0 + DO 100 I = 1,NEQ + IF (ICNSTR(I) .EQ. 2) THEN + IF (Y(I) .LE. ZERO) THEN + IRET = I + RETURN + ENDIF + ELSEIF (ICNSTR(I) .EQ. 1) THEN + IF (Y(I) .LT. ZERO) THEN + IRET = I + RETURN + ENDIF + ELSEIF (ICNSTR(I) .EQ. -1) THEN + IF (Y(I) .GT. ZERO) THEN + IRET = I + RETURN + ENDIF + ELSEIF (ICNSTR(I) .EQ. -2) THEN + IF (Y(I) .GE. ZERO) THEN + IRET = I + RETURN + ENDIF + ENDIF + 100 CONTINUE + RETURN +C----------------------- END OF SUBROUTINE DCNST0 ---------------------- + END + SUBROUTINE DDAWTS(NEQ,IWT,RTOL,ATOL,Y,WT,RPAR,IPAR) +C +C***BEGIN PROLOGUE DDAWTS +C***REFER TO DDASPK +C***ROUTINES CALLED (NONE) +C***DATE WRITTEN 890101 (YYMMDD) +C***REVISION DATE 900926 (YYMMDD) +C***END PROLOGUE DDAWTS +C----------------------------------------------------------------------- +C This subroutine sets the error weight vector, +C WT, according to WT(I)=RTOL(I)*ABS(Y(I))+ATOL(I), +C I = 1 to NEQ. +C RTOL and ATOL are scalars if IWT = 0, +C and vectors if IWT = 1. +C----------------------------------------------------------------------- +C + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + DIMENSION RTOL(*),ATOL(*),Y(*),WT(*) + DIMENSION RPAR(*),IPAR(*) + RTOLI=RTOL(1) + ATOLI=ATOL(1) + DO 20 I=1,NEQ + IF (IWT .EQ.0) GO TO 10 + RTOLI=RTOL(I) + ATOLI=ATOL(I) +10 WT(I)=RTOLI*ABS(Y(I))+ATOLI +20 CONTINUE + RETURN +C +C------END OF SUBROUTINE DDAWTS----------------------------------------- + END + SUBROUTINE DINVWT(NEQ,WT,IER) +C +C***BEGIN PROLOGUE DINVWT +C***REFER TO DDASPK +C***ROUTINES CALLED (NONE) +C***DATE WRITTEN 950125 (YYMMDD) +C***END PROLOGUE DINVWT +C----------------------------------------------------------------------- +C This subroutine checks the error weight vector WT, of length NEQ, +C for components that are .le. 0, and if none are found, it +C inverts the WT(I) in place. This replaces division operations +C with multiplications in all norm evaluations. +C IER is returned as 0 if all WT(I) were found positive, +C and the first I with WT(I) .le. 0.0 otherwise. +C----------------------------------------------------------------------- +C + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + DIMENSION WT(*) +C + DO 10 I = 1,NEQ + IF (WT(I) .LE. 0.0D0) GO TO 30 + 10 CONTINUE + DO 20 I = 1,NEQ + 20 WT(I) = 1.0D0/WT(I) + IER = 0 + RETURN +C + 30 IER = I + RETURN +C +C------END OF SUBROUTINE DINVWT----------------------------------------- + END + SUBROUTINE DDATRP(X,XOUT,YOUT,YPOUT,NEQ,KOLD,PHI,PSI) +C +C***BEGIN PROLOGUE DDATRP +C***REFER TO DDASPK +C***ROUTINES CALLED (NONE) +C***DATE WRITTEN 890101 (YYMMDD) +C***REVISION DATE 900926 (YYMMDD) +C***END PROLOGUE DDATRP +C +C----------------------------------------------------------------------- +C The methods in subroutine DDSTP use polynomials +C to approximate the solution. DDATRP approximates the +C solution and its derivative at time XOUT by evaluating +C one of these polynomials, and its derivative, there. +C Information defining this polynomial is passed from +C DDSTP, so DDATRP cannot be used alone. +C +C The parameters are +C +C X The current time in the integration. +C XOUT The time at which the solution is desired. +C YOUT The interpolated approximation to Y at XOUT. +C (This is output.) +C YPOUT The interpolated approximation to YPRIME at XOUT. +C (This is output.) +C NEQ Number of equations. +C KOLD Order used on last successful step. +C PHI Array of scaled divided differences of Y. +C PSI Array of past stepsize history. +C----------------------------------------------------------------------- +C + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + DIMENSION YOUT(*),YPOUT(*) + DIMENSION PHI(NEQ,*),PSI(*) + KOLDP1=KOLD+1 + TEMP1=XOUT-X + DO 10 I=1,NEQ + YOUT(I)=PHI(I,1) +10 YPOUT(I)=0.0D0 + C=1.0D0 + D=0.0D0 + GAMMA=TEMP1/PSI(1) + DO 30 J=2,KOLDP1 + D=D*GAMMA+C/PSI(J-1) + C=C*GAMMA + GAMMA=(TEMP1+PSI(J-1))/PSI(J) + DO 20 I=1,NEQ + YOUT(I)=YOUT(I)+C*PHI(I,J) +20 YPOUT(I)=YPOUT(I)+D*PHI(I,J) +30 CONTINUE + RETURN +C +C------END OF SUBROUTINE DDATRP----------------------------------------- + END + DOUBLE PRECISION FUNCTION DDWNRM(NEQ,V,RWT,RPAR,IPAR) +C +C***BEGIN PROLOGUE DDWNRM +C***ROUTINES CALLED (NONE) +C***DATE WRITTEN 890101 (YYMMDD) +C***REVISION DATE 900926 (YYMMDD) +C***END PROLOGUE DDWNRM +C----------------------------------------------------------------------- +C This function routine computes the weighted +C root-mean-square norm of the vector of length +C NEQ contained in the array V, with reciprocal weights +C contained in the array RWT of length NEQ. +C DDWNRM=SQRT((1/NEQ)*SUM(V(I)*RWT(I))**2) +C----------------------------------------------------------------------- +C + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + DIMENSION V(*),RWT(*) + DIMENSION RPAR(*),IPAR(*) + DDWNRM = 0.0D0 + VMAX = 0.0D0 + DO 10 I = 1,NEQ + IF(ABS(V(I)*RWT(I)) .GT. VMAX) VMAX = ABS(V(I)*RWT(I)) +10 CONTINUE + IF(VMAX .LE. 0.0D0) GO TO 30 + SUM = 0.0D0 + DO 20 I = 1,NEQ +20 SUM = SUM + ((V(I)*RWT(I))/VMAX)**2 + DDWNRM = VMAX*SQRT(SUM/NEQ) +30 CONTINUE + RETURN +C +C------END OF FUNCTION DDWNRM------------------------------------------- + END + SUBROUTINE DDASID(X,Y,YPRIME,NEQ,ICOPT,ID,RES,JACD,PDUM,H,TSCALE, + * WT,JSDUM,RPAR,IPAR,DUMSVR,DELTA,R,YIC,YPIC,DUMPWK,WM,IWM,CJ, + * UROUND,DUME,DUMS,DUMR,EPCON,RATEMX,STPTOL,JFDUM, + * ICNFLG,ICNSTR,IERNLS) +C +C***BEGIN PROLOGUE DDASID +C***REFER TO DDASPK +C***DATE WRITTEN 940701 (YYMMDD) +C***REVISION DATE 950808 (YYMMDD) +C***REVISION DATE 951110 Removed unreachable block 390. +C***REVISION DATE 000628 TSCALE argument added. +C +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C +C DDASID solves a nonlinear system of algebraic equations of the +C form G(X,Y,YPRIME) = 0 for the unknown parts of Y and YPRIME in +C the initial conditions. +C +C The method used is a modified Newton scheme. +C +C The parameters represent +C +C X -- Independent variable. +C Y -- Solution vector. +C YPRIME -- Derivative of solution vector. +C NEQ -- Number of unknowns. +C ICOPT -- Initial condition option chosen (1 or 2). +C ID -- Array of dimension NEQ, which must be initialized +C if ICOPT = 1. See DDASIC. +C RES -- External user-supplied subroutine to evaluate the +C residual. See RES description in DDASPK prologue. +C JACD -- External user-supplied routine to evaluate the +C Jacobian. See JAC description for the case +C INFO(12) = 0 in the DDASPK prologue. +C PDUM -- Dummy argument. +C H -- Scaling factor for this initial condition calc. +C TSCALE -- Scale factor in T, used for stopping tests if nonzero. +C WT -- Vector of weights for error criterion. +C JSDUM -- Dummy argument. +C RPAR,IPAR -- Real and integer arrays used for communication +C between the calling program and external user +C routines. They are not altered within DASPK. +C DUMSVR -- Dummy argument. +C DELTA -- Work vector for NLS of length NEQ. +C R -- Work vector for NLS of length NEQ. +C YIC,YPIC -- Work vectors for NLS, each of length NEQ. +C DUMPWK -- Dummy argument. +C WM,IWM -- Real and integer arrays storing matrix information +C such as the matrix of partial derivatives, +C permutation vector, and various other information. +C CJ -- Matrix parameter = 1/H (ICOPT = 1) or 0 (ICOPT = 2). +C UROUND -- Unit roundoff. +C DUME -- Dummy argument. +C DUMS -- Dummy argument. +C DUMR -- Dummy argument. +C EPCON -- Tolerance to test for convergence of the Newton +C iteration. +C RATEMX -- Maximum convergence rate for which Newton iteration +C is considered converging. +C JFDUM -- Dummy argument. +C STPTOL -- Tolerance used in calculating the minimum lambda +C value allowed. +C ICNFLG -- Integer scalar. If nonzero, then constraint +C violations in the proposed new approximate solution +C will be checked for, and the maximum step length +C will be adjusted accordingly. +C ICNSTR -- Integer array of length NEQ containing flags for +C checking constraints. +C IERNLS -- Error flag for nonlinear solver. +C 0 ==> nonlinear solver converged. +C 1,2 ==> recoverable error inside nonlinear solver. +C 1 => retry with current Y, YPRIME +C 2 => retry with original Y, YPRIME +C -1 ==> unrecoverable error in nonlinear solver. +C +C All variables with "DUM" in their names are dummy variables +C which are not used in this routine. +C +C----------------------------------------------------------------------- +C +C***ROUTINES CALLED +C RES, DMATD, DNSID +C +C***END PROLOGUE DDASID +C +C + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + DIMENSION Y(*),YPRIME(*),ID(*),WT(*),ICNSTR(*) + DIMENSION DELTA(*),R(*),YIC(*),YPIC(*) + DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*) + EXTERNAL RES, JACD +C + PARAMETER (LNRE=12, LNJE=13, LMXNIT=32, LMXNJ=33) +C +C +C Perform initializations. +C + MXNIT = IWM(LMXNIT) + MXNJ = IWM(LMXNJ) + IERNLS = 0 + NJ = 0 +C +C Call RES to initialize DELTA. +C + IRES = 0 + IWM(LNRE) = IWM(LNRE) + 1 + CALL RES(X,Y,YPRIME,CJ,DELTA,IRES,RPAR,IPAR) + IF (IRES .LT. 0) GO TO 370 +C +C Looping point for updating the Jacobian. +C +300 CONTINUE +C +C Initialize all error flags to zero. +C + IERJ = 0 + IRES = 0 + IERNEW = 0 +C +C Reevaluate the iteration matrix, J = dG/dY + CJ*dG/dYPRIME, +C where G(X,Y,YPRIME) = 0. +C + NJ = NJ + 1 + IWM(LNJE)=IWM(LNJE)+1 + CALL DMATD(NEQ,X,Y,YPRIME,DELTA,CJ,H,IERJ,WT,R, + * WM,IWM,RES,IRES,UROUND,JACD,RPAR,IPAR) + IF (IRES .LT. 0 .OR. IERJ .NE. 0) GO TO 370 +C +C Call the nonlinear Newton solver for up to MXNIT iterations. +C + CALL DNSID(X,Y,YPRIME,NEQ,ICOPT,ID,RES,WT,RPAR,IPAR,DELTA,R, + * YIC,YPIC,WM,IWM,CJ,TSCALE,EPCON,RATEMX,MXNIT,STPTOL, + * ICNFLG,ICNSTR,IERNEW) +C + IF (IERNEW .EQ. 1 .AND. NJ .LT. MXNJ) THEN +C +C MXNIT iterations were done, the convergence rate is < 1, +C and the number of Jacobian evaluations is less than MXNJ. +C Call RES, reevaluate the Jacobian, and try again. +C + IWM(LNRE)=IWM(LNRE)+1 + CALL RES(X,Y,YPRIME,CJ,DELTA,IRES,RPAR,IPAR) + IF (IRES .LT. 0) GO TO 370 + GO TO 300 + ENDIF +C + IF (IERNEW .NE. 0) GO TO 380 + + RETURN +C +C +C Unsuccessful exits from nonlinear solver. +C Compute IERNLS accordingly. +C +370 IERNLS = 2 + IF (IRES .LE. -2) IERNLS = -1 + RETURN +C +380 IERNLS = MIN(IERNEW,2) + RETURN +C +C------END OF SUBROUTINE DDASID----------------------------------------- + END + SUBROUTINE DNSID(X,Y,YPRIME,NEQ,ICOPT,ID,RES,WT,RPAR,IPAR, + * DELTA,R,YIC,YPIC,WM,IWM,CJ,TSCALE,EPCON,RATEMX,MAXIT,STPTOL, + * ICNFLG,ICNSTR,IERNEW) +C +C***BEGIN PROLOGUE DNSID +C***REFER TO DDASPK +C***DATE WRITTEN 940701 (YYMMDD) +C***REVISION DATE 950713 (YYMMDD) +C***REVISION DATE 000628 TSCALE argument added. +C +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C DNSID solves a nonlinear system of algebraic equations of the +C form G(X,Y,YPRIME) = 0 for the unknown parts of Y and YPRIME +C in the initial conditions. +C +C The method used is a modified Newton scheme. +C +C The parameters represent +C +C X -- Independent variable. +C Y -- Solution vector. +C YPRIME -- Derivative of solution vector. +C NEQ -- Number of unknowns. +C ICOPT -- Initial condition option chosen (1 or 2). +C ID -- Array of dimension NEQ, which must be initialized +C if ICOPT = 1. See DDASIC. +C RES -- External user-supplied subroutine to evaluate the +C residual. See RES description in DDASPK prologue. +C WT -- Vector of weights for error criterion. +C RPAR,IPAR -- Real and integer arrays used for communication +C between the calling program and external user +C routines. They are not altered within DASPK. +C DELTA -- Residual vector on entry, and work vector of +C length NEQ for DNSID. +C WM,IWM -- Real and integer arrays storing matrix information +C such as the matrix of partial derivatives, +C permutation vector, and various other information. +C CJ -- Matrix parameter = 1/H (ICOPT = 1) or 0 (ICOPT = 2). +C TSCALE -- Scale factor in T, used for stopping tests if nonzero. +C R -- Array of length NEQ used as workspace by the +C linesearch routine DLINSD. +C YIC,YPIC -- Work vectors for DLINSD, each of length NEQ. +C EPCON -- Tolerance to test for convergence of the Newton +C iteration. +C RATEMX -- Maximum convergence rate for which Newton iteration +C is considered converging. +C MAXIT -- Maximum allowed number of Newton iterations. +C STPTOL -- Tolerance used in calculating the minimum lambda +C value allowed. +C ICNFLG -- Integer scalar. If nonzero, then constraint +C violations in the proposed new approximate solution +C will be checked for, and the maximum step length +C will be adjusted accordingly. +C ICNSTR -- Integer array of length NEQ containing flags for +C checking constraints. +C IERNEW -- Error flag for Newton iteration. +C 0 ==> Newton iteration converged. +C 1 ==> failed to converge, but RATE .le. RATEMX. +C 2 ==> failed to converge, RATE .gt. RATEMX. +C 3 ==> other recoverable error (IRES = -1, or +C linesearch failed). +C -1 ==> unrecoverable error (IRES = -2). +C +C----------------------------------------------------------------------- +C +C***ROUTINES CALLED +C DSLVD, DDWNRM, DLINSD, DCOPY +C +C***END PROLOGUE DNSID +C +C + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + DIMENSION Y(*),YPRIME(*),WT(*),R(*) + DIMENSION ID(*),DELTA(*), YIC(*), YPIC(*) + DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*) + DIMENSION ICNSTR(*) + EXTERNAL RES +C + PARAMETER (LNNI=19, LLSOFF=35) +C +C +C Initializations. M is the Newton iteration counter. +C + LSOFF = IWM(LLSOFF) + M = 0 + RATE = 1.0D0 + RLX = 0.4D0 +C +C Compute a new step vector DELTA by back-substitution. +C + CALL DSLVD (NEQ, DELTA, WM, IWM) +C +C Get norm of DELTA. Return now if norm(DELTA) .le. EPCON. +C + DELNRM = DDWNRM(NEQ,DELTA,WT,RPAR,IPAR) + FNRM = DELNRM + IF (TSCALE .GT. 0.0D0) FNRM = FNRM*TSCALE*ABS(CJ) + IF (FNRM .LE. EPCON) RETURN +C +C Newton iteration loop. +C + 300 CONTINUE + IWM(LNNI) = IWM(LNNI) + 1 +C +C Call linesearch routine for global strategy and set RATE +C + OLDFNM = FNRM +C + CALL DLINSD (NEQ, Y, X, YPRIME, CJ, TSCALE, DELTA, DELNRM, WT, + * LSOFF, STPTOL, IRET, RES, IRES, WM, IWM, FNRM, ICOPT, + * ID, R, YIC, YPIC, ICNFLG, ICNSTR, RLX, RPAR, IPAR) +C + RATE = FNRM/OLDFNM +C +C Check for error condition from linesearch. + IF (IRET .NE. 0) GO TO 390 +C +C Test for convergence of the iteration, and return or loop. +C + IF (FNRM .LE. EPCON) RETURN +C +C The iteration has not yet converged. Update M. +C Test whether the maximum number of iterations have been tried. +C + M = M + 1 + IF (M .GE. MAXIT) GO TO 380 +C +C Copy the residual to DELTA and its norm to DELNRM, and loop for +C another iteration. +C + CALL DCOPY (NEQ, R, 1, DELTA, 1) + DELNRM = FNRM + GO TO 300 +C +C The maximum number of iterations was done. Set IERNEW and return. +C + 380 IF (RATE .LE. RATEMX) THEN + IERNEW = 1 + ELSE + IERNEW = 2 + ENDIF + RETURN +C + 390 IF (IRES .LE. -2) THEN + IERNEW = -1 + ELSE + IERNEW = 3 + ENDIF + RETURN +C +C +C------END OF SUBROUTINE DNSID------------------------------------------ + END + SUBROUTINE DLINSD (NEQ, Y, T, YPRIME, CJ, TSCALE, P, PNRM, WT, + * LSOFF, STPTOL, IRET, RES, IRES, WM, IWM, + * FNRM, ICOPT, ID, R, YNEW, YPNEW, ICNFLG, + * ICNSTR, RLX, RPAR, IPAR) +C +C***BEGIN PROLOGUE DLINSD +C***REFER TO DNSID +C***DATE WRITTEN 941025 (YYMMDD) +C***REVISION DATE 941215 (YYMMDD) +C***REVISION DATE 960129 Moved line RL = ONE to top block. +C***REVISION DATE 000628 TSCALE argument added. +C +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C DLINSD uses a linesearch algorithm to calculate a new (Y,YPRIME) +C pair (YNEW,YPNEW) such that +C +C f(YNEW,YPNEW) .le. (1 - 2*ALPHA*RL)*f(Y,YPRIME) , +C +C where 0 < RL <= 1. Here, f(y,y') is defined as +C +C f(y,y') = (1/2)*norm( (J-inverse)*G(t,y,y') )**2 , +C +C where norm() is the weighted RMS vector norm, G is the DAE +C system residual function, and J is the system iteration matrix +C (Jacobian). +C +C In addition to the parameters defined elsewhere, we have +C +C TSCALE -- Scale factor in T, used for stopping tests if nonzero. +C P -- Approximate Newton step used in backtracking. +C PNRM -- Weighted RMS norm of P. +C LSOFF -- Flag showing whether the linesearch algorithm is +C to be invoked. 0 means do the linesearch, and +C 1 means turn off linesearch. +C STPTOL -- Tolerance used in calculating the minimum lambda +C value allowed. +C ICNFLG -- Integer scalar. If nonzero, then constraint violations +C in the proposed new approximate solution will be +C checked for, and the maximum step length will be +C adjusted accordingly. +C ICNSTR -- Integer array of length NEQ containing flags for +C checking constraints. +C RLX -- Real scalar restricting update size in DCNSTR. +C YNEW -- Array of length NEQ used to hold the new Y in +C performing the linesearch. +C YPNEW -- Array of length NEQ used to hold the new YPRIME in +C performing the linesearch. +C Y -- Array of length NEQ containing the new Y (i.e.,=YNEW). +C YPRIME -- Array of length NEQ containing the new YPRIME +C (i.e.,=YPNEW). +C FNRM -- Real scalar containing SQRT(2*f(Y,YPRIME)) for the +C current (Y,YPRIME) on input and output. +C R -- Work array of length NEQ, containing the scaled +C residual (J-inverse)*G(t,y,y') on return. +C IRET -- Return flag. +C IRET=0 means that a satisfactory (Y,YPRIME) was found. +C IRET=1 means that the routine failed to find a new +C (Y,YPRIME) that was sufficiently distinct from +C the current (Y,YPRIME) pair. +C IRET=2 means IRES .ne. 0 from RES. +C----------------------------------------------------------------------- +C +C***ROUTINES CALLED +C DFNRMD, DYYPNW, DCNSTR, DCOPY, XERRWD +C +C***END PROLOGUE DLINSD +C + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + EXTERNAL RES + DIMENSION Y(*), YPRIME(*), WT(*), R(*), ID(*) + DIMENSION WM(*), IWM(*) + DIMENSION YNEW(*), YPNEW(*), P(*), ICNSTR(*) + DIMENSION RPAR(*), IPAR(*) + CHARACTER MSG*80 +C + PARAMETER (LNRE=12, LKPRIN=31) +C + SAVE ALPHA, ONE, TWO + DATA ALPHA/1.0D-4/, ONE/1.0D0/, TWO/2.0D0/ +C + KPRIN=IWM(LKPRIN) +C + F1NRM = (FNRM*FNRM)/TWO + RATIO = ONE + IF (KPRIN .GE. 2) THEN + MSG = '------ IN ROUTINE DLINSD-- PNRM = (R1)' + CALL XERRWD(MSG, 38, 901, 0, 0, 0, 0, 1, PNRM, 0.0D0) + ENDIF + TAU = PNRM + RL = ONE +C----------------------------------------------------------------------- +C Check for violations of the constraints, if any are imposed. +C If any violations are found, the step vector P is rescaled, and the +C constraint check is repeated, until no violations are found. +C----------------------------------------------------------------------- + IF (ICNFLG .NE. 0) THEN + 10 CONTINUE + CALL DYYPNW (NEQ,Y,YPRIME,CJ,RL,P,ICOPT,ID,YNEW,YPNEW) + CALL DCNSTR (NEQ, Y, YNEW, ICNSTR, TAU, RLX, IRET, IVAR) + IF (IRET .EQ. 1) THEN + RATIO1 = TAU/PNRM + RATIO = RATIO*RATIO1 + DO 20 I = 1,NEQ + 20 P(I) = P(I)*RATIO1 + PNRM = TAU + IF (KPRIN .GE. 2) THEN + MSG = '------ CONSTRAINT VIOL., PNRM = (R1), INDEX = (I1)' + CALL XERRWD(MSG, 50, 902, 0, 1, IVAR, 0, 1, PNRM, 0.0D0) + ENDIF + IF (PNRM .LE. STPTOL) THEN + IRET = 1 + RETURN + ENDIF + GO TO 10 + ENDIF + ENDIF +C + SLPI = (-TWO*F1NRM)*RATIO + RLMIN = STPTOL/PNRM + IF (LSOFF .EQ. 0 .AND. KPRIN .GE. 2) THEN + MSG = '------ MIN. LAMBDA = (R1)' + CALL XERRWD(MSG, 25, 903, 0, 0, 0, 0, 1, RLMIN, 0.0D0) + ENDIF +C----------------------------------------------------------------------- +C Begin iteration to find RL value satisfying alpha-condition. +C If RL becomes less than RLMIN, then terminate with IRET = 1. +C----------------------------------------------------------------------- + 100 CONTINUE + CALL DYYPNW (NEQ,Y,YPRIME,CJ,RL,P,ICOPT,ID,YNEW,YPNEW) + CALL DFNRMD (NEQ, YNEW, T, YPNEW, R, CJ, TSCALE, WT, RES, IRES, + * FNRMP, WM, IWM, RPAR, IPAR) + IWM(LNRE) = IWM(LNRE) + 1 + IF (IRES .NE. 0) THEN + IRET = 2 + RETURN + ENDIF + IF (LSOFF .EQ. 1) GO TO 150 +C + F1NRMP = FNRMP*FNRMP/TWO + IF (KPRIN .GE. 2) THEN + MSG = '------ LAMBDA = (R1)' + CALL XERRWD(MSG, 20, 904, 0, 0, 0, 0, 1, RL, 0.0D0) + MSG = '------ NORM(F1) = (R1), NORM(F1NEW) = (R2)' + CALL XERRWD(MSG, 43, 905, 0, 0, 0, 0, 2, F1NRM, F1NRMP) + ENDIF + IF (F1NRMP .GT. F1NRM + ALPHA*SLPI*RL) GO TO 200 +C----------------------------------------------------------------------- +C Alpha-condition is satisfied, or linesearch is turned off. +C Copy YNEW,YPNEW to Y,YPRIME and return. +C----------------------------------------------------------------------- + 150 IRET = 0 + CALL DCOPY (NEQ, YNEW, 1, Y, 1) + CALL DCOPY (NEQ, YPNEW, 1, YPRIME, 1) + FNRM = FNRMP + IF (KPRIN .GE. 1) THEN + MSG = '------ LEAVING ROUTINE DLINSD, FNRM = (R1)' + CALL XERRWD(MSG, 42, 906, 0, 0, 0, 0, 1, FNRM, 0.0D0) + ENDIF + RETURN +C----------------------------------------------------------------------- +C Alpha-condition not satisfied. Perform backtrack to compute new RL +C value. If no satisfactory YNEW,YPNEW can be found sufficiently +C distinct from Y,YPRIME, then return IRET = 1. +C----------------------------------------------------------------------- + 200 CONTINUE + IF (RL .LT. RLMIN) THEN + IRET = 1 + RETURN + ENDIF +C + RL = RL/TWO + GO TO 100 +C +C----------------------- END OF SUBROUTINE DLINSD ---------------------- + END + SUBROUTINE DFNRMD (NEQ, Y, T, YPRIME, R, CJ, TSCALE, WT, + * RES, IRES, FNORM, WM, IWM, RPAR, IPAR) +C +C***BEGIN PROLOGUE DFNRMD +C***REFER TO DLINSD +C***DATE WRITTEN 941025 (YYMMDD) +C***REVISION DATE 000628 TSCALE argument added. +C +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C DFNRMD calculates the scaled preconditioned norm of the nonlinear +C function used in the nonlinear iteration for obtaining consistent +C initial conditions. Specifically, DFNRMD calculates the weighted +C root-mean-square norm of the vector (J-inverse)*G(T,Y,YPRIME), +C where J is the Jacobian matrix. +C +C In addition to the parameters described in the calling program +C DLINSD, the parameters represent +C +C R -- Array of length NEQ that contains +C (J-inverse)*G(T,Y,YPRIME) on return. +C TSCALE -- Scale factor in T, used for stopping tests if nonzero. +C FNORM -- Scalar containing the weighted norm of R on return. +C----------------------------------------------------------------------- +C +C***ROUTINES CALLED +C RES, DSLVD, DDWNRM +C +C***END PROLOGUE DFNRMD +C +C + IMPLICIT DOUBLE PRECISION (A-H,O-Z) + EXTERNAL RES + DIMENSION Y(*), YPRIME(*), WT(*), R(*) + DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*) +C----------------------------------------------------------------------- +C Call RES routine. +C----------------------------------------------------------------------- + IRES = 0 + CALL RES(T,Y,YPRIME,CJ,R,IRES,RPAR,IPAR) + IF (IRES .LT. 0) RETURN +C----------------------------------------------------------------------- +C Apply inverse of Jacobian to vector R. +C----------------------------------------------------------------------- + CALL DSLVD(NEQ,R,WM,IWM) +C----------------------------------------------------------------------- +C Calculate norm of R. +C----------------------------------------------------------------------- + FNORM = DDWNRM(NEQ,R,WT,RPAR,IPAR) + IF (TSCALE .GT. 0.0D0) FNORM = FNORM*TSCALE*ABS(CJ) +C + RETURN +C----------------------- END OF SUBROUTINE DFNRMD ---------------------- + END + SUBROUTINE DNEDD(X,Y,YPRIME,NEQ,RES,JACD,PDUM,H,WT, + * JSTART,IDID,RPAR,IPAR,PHI,GAMMA,DUMSVR,DELTA,E, + * WM,IWM,CJ,CJOLD,CJLAST,S,UROUND,DUME,DUMS,DUMR, + * EPCON,JCALC,JFDUM,KP1,NONNEG,NTYPE,IERNLS) +C +C***BEGIN PROLOGUE DNEDD +C***REFER TO DDASPK +C***DATE WRITTEN 891219 (YYMMDD) +C***REVISION DATE 900926 (YYMMDD) +C +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C DNEDD solves a nonlinear system of +C algebraic equations of the form +C G(X,Y,YPRIME) = 0 for the unknown Y. +C +C The method used is a modified Newton scheme. +C +C The parameters represent +C +C X -- Independent variable. +C Y -- Solution vector. +C YPRIME -- Derivative of solution vector. +C NEQ -- Number of unknowns. +C RES -- External user-supplied subroutine +C to evaluate the residual. See RES description +C in DDASPK prologue. +C JACD -- External user-supplied routine to evaluate the +C Jacobian. See JAC description for the case +C INFO(12) = 0 in the DDASPK prologue. +C PDUM -- Dummy argument. +C H -- Appropriate step size for next step. +C WT -- Vector of weights for error criterion. +C JSTART -- Indicates first call to this routine. +C If JSTART = 0, then this is the first call, +C otherwise it is not. +C IDID -- Completion flag, output by DNEDD. +C See IDID description in DDASPK prologue. +C RPAR,IPAR -- Real and integer arrays used for communication +C between the calling program and external user +C routines. They are not altered within DASPK. +C PHI -- Array of divided differences used by +C DNEDD. The length is NEQ*(K+1),where +C K is the maximum order. +C GAMMA -- Array used to predict Y and YPRIME. The length +C is MAXORD+1 where MAXORD is the maximum order. +C DUMSVR -- Dummy argument. +C DELTA -- Work vector for NLS of length NEQ. +C E -- Error accumulation vector for NLS of length NEQ. +C WM,IWM -- Real and integer arrays storing +C matrix information such as the matrix +C of partial derivatives, permutation +C vector, and various other information. +C CJ -- Parameter always proportional to 1/H. +C CJOLD -- Saves the value of CJ as of the last call to DMATD. +C Accounts for changes in CJ needed to +C decide whether to call DMATD. +C CJLAST -- Previous value of CJ. +C S -- A scalar determined by the approximate rate +C of convergence of the Newton iteration and used +C in the convergence test for the Newton iteration. +C +C If RATE is defined to be an estimate of the +C rate of convergence of the Newton iteration, +C then S = RATE/(1.D0-RATE). +C +C The closer RATE is to 0., the faster the Newton +C iteration is converging; the closer RATE is to 1., +C the slower the Newton iteration is converging. +C +C On the first Newton iteration with an up-dated +C preconditioner S = 100.D0, Thus the initial +C RATE of convergence is approximately 1. +C +C S is preserved from call to call so that the rate +C estimate from a previous step can be applied to +C the current step. +C UROUND -- Unit roundoff. +C DUME -- Dummy argument. +C DUMS -- Dummy argument. +C DUMR -- Dummy argument. +C EPCON -- Tolerance to test for convergence of the Newton +C iteration. +C JCALC -- Flag used to determine when to update +C the Jacobian matrix. In general: +C +C JCALC = -1 ==> Call the DMATD routine to update +C the Jacobian matrix. +C JCALC = 0 ==> Jacobian matrix is up-to-date. +C JCALC = 1 ==> Jacobian matrix is out-dated, +C but DMATD will not be called unless +C JCALC is set to -1. +C JFDUM -- Dummy argument. +C KP1 -- The current order(K) + 1; updated across calls. +C NONNEG -- Flag to determine nonnegativity constraints. +C NTYPE -- Identification code for the NLS routine. +C 0 ==> modified Newton; direct solver. +C IERNLS -- Error flag for nonlinear solver. +C 0 ==> nonlinear solver converged. +C 1 ==> recoverable error inside nonlinear solver. +C -1 ==> unrecoverable error inside nonlinear solver. +C +C All variables with "DUM" in their names are dummy variables +C which are not used in this routine. +C +C Following is a list and description of local variables which +C may not have an obvious usage. They are listed in roughly the +C order they occur in this subroutine. +C +C The following group of variables are passed as arguments to +C the Newton iteration solver. They are explained in greater detail +C in DNSD: +C TOLNEW, MULDEL, MAXIT, IERNEW +C +C IERTYP -- Flag which tells whether this subroutine is correct. +C 0 ==> correct subroutine. +C 1 ==> incorrect subroutine. +C +C----------------------------------------------------------------------- +C***ROUTINES CALLED +C DDWNRM, RES, DMATD, DNSD +C +C***END PROLOGUE DNEDD +C +C + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + DIMENSION Y(*),YPRIME(*),WT(*) + DIMENSION DELTA(*),E(*) + DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*) + DIMENSION PHI(NEQ,*),GAMMA(*) + EXTERNAL RES, JACD +C + PARAMETER (LNRE=12, LNJE=13) +C + SAVE MULDEL, MAXIT, XRATE + DATA MULDEL/1/, MAXIT/4/, XRATE/0.25D0/ +C +C Verify that this is the correct subroutine. +C + IERTYP = 0 + IF (NTYPE .NE. 0) THEN + IERTYP = 1 + GO TO 380 + ENDIF +C +C If this is the first step, perform initializations. +C + IF (JSTART .EQ. 0) THEN + CJOLD = CJ + JCALC = -1 + ENDIF +C +C Perform all other initializations. +C + IERNLS = 0 +C +C Decide whether new Jacobian is needed. +C + TEMP1 = (1.0D0 - XRATE)/(1.0D0 + XRATE) + TEMP2 = 1.0D0/TEMP1 + IF (CJ/CJOLD .LT. TEMP1 .OR. CJ/CJOLD .GT. TEMP2) JCALC = -1 + IF (CJ .NE. CJLAST) S = 100.D0 +C +C----------------------------------------------------------------------- +C Entry point for updating the Jacobian with current +C stepsize. +C----------------------------------------------------------------------- +300 CONTINUE +C +C Initialize all error flags to zero. +C + IERJ = 0 + IRES = 0 + IERNEW = 0 +C +C Predict the solution and derivative and compute the tolerance +C for the Newton iteration. +C + DO 310 I=1,NEQ + Y(I)=PHI(I,1) +310 YPRIME(I)=0.0D0 + DO 330 J=2,KP1 + DO 320 I=1,NEQ + Y(I)=Y(I)+PHI(I,J) +320 YPRIME(I)=YPRIME(I)+GAMMA(J)*PHI(I,J) +330 CONTINUE + PNORM = DDWNRM (NEQ,Y,WT,RPAR,IPAR) + TOLNEW = 100.D0*UROUND*PNORM +C +C Call RES to initialize DELTA. +C + IWM(LNRE)=IWM(LNRE)+1 + CALL RES(X,Y,YPRIME,CJ,DELTA,IRES,RPAR,IPAR) + IF (IRES .LT. 0) GO TO 380 +C +C If indicated, reevaluate the iteration matrix +C J = dG/dY + CJ*dG/dYPRIME (where G(X,Y,YPRIME)=0). +C Set JCALC to 0 as an indicator that this has been done. +C + IF(JCALC .EQ. -1) THEN + IWM(LNJE)=IWM(LNJE)+1 + JCALC=0 + CALL DMATD(NEQ,X,Y,YPRIME,DELTA,CJ,H,IERJ,WT,E,WM,IWM, + * RES,IRES,UROUND,JACD,RPAR,IPAR) + CJOLD=CJ + S = 100.D0 + IF (IRES .LT. 0) GO TO 380 + IF(IERJ .NE. 0)GO TO 380 + ENDIF +C +C Call the nonlinear Newton solver. +C + TEMP1 = 2.0D0/(1.0D0 + CJ/CJOLD) + CALL DNSD(X,Y,YPRIME,NEQ,RES,PDUM,WT,RPAR,IPAR,DUMSVR, + * DELTA,E,WM,IWM,CJ,DUMS,DUMR,DUME,EPCON,S,TEMP1, + * TOLNEW,MULDEL,MAXIT,IRES,IDUM,IERNEW) +C + IF (IERNEW .GT. 0 .AND. JCALC .NE. 0) THEN +C +C The Newton iteration had a recoverable failure with an old +C iteration matrix. Retry the step with a new iteration matrix. +C + JCALC = -1 + GO TO 300 + ENDIF +C + IF (IERNEW .NE. 0) GO TO 380 +C +C The Newton iteration has converged. If nonnegativity of +C solution is required, set the solution nonnegative, if the +C perturbation to do it is small enough. If the change is too +C large, then consider the corrector iteration to have failed. +C +375 IF(NONNEG .EQ. 0) GO TO 390 + DO 377 I = 1,NEQ +377 DELTA(I) = MIN(Y(I),0.0D0) + DELNRM = DDWNRM(NEQ,DELTA,WT,RPAR,IPAR) + IF(DELNRM .GT. EPCON) GO TO 380 + DO 378 I = 1,NEQ +378 E(I) = E(I) - DELTA(I) + GO TO 390 +C +C +C Exits from nonlinear solver. +C No convergence with current iteration +C matrix, or singular iteration matrix. +C Compute IERNLS and IDID accordingly. +C +380 CONTINUE + IF (IRES .LE. -2 .OR. IERTYP .NE. 0) THEN + IERNLS = -1 + IF (IRES .LE. -2) IDID = -11 + IF (IERTYP .NE. 0) IDID = -15 + ELSE + IERNLS = 1 + IF (IRES .LT. 0) IDID = -10 + IF (IERJ .NE. 0) IDID = -8 + ENDIF +C +390 JCALC = 1 + RETURN +C +C------END OF SUBROUTINE DNEDD------------------------------------------ + END + SUBROUTINE DNSD(X,Y,YPRIME,NEQ,RES,PDUM,WT,RPAR,IPAR, + * DUMSVR,DELTA,E,WM,IWM,CJ,DUMS,DUMR,DUME,EPCON, + * S,CONFAC,TOLNEW,MULDEL,MAXIT,IRES,IDUM,IERNEW) +C +C***BEGIN PROLOGUE DNSD +C***REFER TO DDASPK +C***DATE WRITTEN 891219 (YYMMDD) +C***REVISION DATE 900926 (YYMMDD) +C***REVISION DATE 950126 (YYMMDD) +C***REVISION DATE 000711 (YYMMDD) +C +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C DNSD solves a nonlinear system of +C algebraic equations of the form +C G(X,Y,YPRIME) = 0 for the unknown Y. +C +C The method used is a modified Newton scheme. +C +C The parameters represent +C +C X -- Independent variable. +C Y -- Solution vector. +C YPRIME -- Derivative of solution vector. +C NEQ -- Number of unknowns. +C RES -- External user-supplied subroutine +C to evaluate the residual. See RES description +C in DDASPK prologue. +C PDUM -- Dummy argument. +C WT -- Vector of weights for error criterion. +C RPAR,IPAR -- Real and integer arrays used for communication +C between the calling program and external user +C routines. They are not altered within DASPK. +C DUMSVR -- Dummy argument. +C DELTA -- Work vector for DNSD of length NEQ. +C E -- Error accumulation vector for DNSD of length NEQ. +C WM,IWM -- Real and integer arrays storing +C matrix information such as the matrix +C of partial derivatives, permutation +C vector, and various other information. +C CJ -- Parameter always proportional to 1/H (step size). +C DUMS -- Dummy argument. +C DUMR -- Dummy argument. +C DUME -- Dummy argument. +C EPCON -- Tolerance to test for convergence of the Newton +C iteration. +C S -- Used for error convergence tests. +C In the Newton iteration: S = RATE/(1 - RATE), +C where RATE is the estimated rate of convergence +C of the Newton iteration. +C The calling routine passes the initial value +C of S to the Newton iteration. +C CONFAC -- A residual scale factor to improve convergence. +C TOLNEW -- Tolerance on the norm of Newton correction in +C alternative Newton convergence test. +C MULDEL -- A flag indicating whether or not to multiply +C DELTA by CONFAC. +C 0 ==> do not scale DELTA by CONFAC. +C 1 ==> scale DELTA by CONFAC. +C MAXIT -- Maximum allowed number of Newton iterations. +C IRES -- Error flag returned from RES. See RES description +C in DDASPK prologue. If IRES = -1, then IERNEW +C will be set to 1. +C If IRES < -1, then IERNEW will be set to -1. +C IDUM -- Dummy argument. +C IERNEW -- Error flag for Newton iteration. +C 0 ==> Newton iteration converged. +C 1 ==> recoverable error inside Newton iteration. +C -1 ==> unrecoverable error inside Newton iteration. +C +C All arguments with "DUM" in their names are dummy arguments +C which are not used in this routine. +C----------------------------------------------------------------------- +C +C***ROUTINES CALLED +C DSLVD, DDWNRM, RES +C +C***END PROLOGUE DNSD +C +C + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + DIMENSION Y(*),YPRIME(*),WT(*),DELTA(*),E(*) + DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*) + EXTERNAL RES +C + PARAMETER (LNRE=12, LNNI=19) +C +C Initialize Newton counter M and accumulation vector E. +C + M = 0 + DO 100 I=1,NEQ +100 E(I)=0.0D0 +C +C Corrector loop. +C +300 CONTINUE + IWM(LNNI) = IWM(LNNI) + 1 +C +C If necessary, multiply residual by convergence factor. +C + IF (MULDEL .EQ. 1) THEN + DO 320 I = 1,NEQ +320 DELTA(I) = DELTA(I) * CONFAC + ENDIF +C +C Compute a new iterate (back-substitution). +C Store the correction in DELTA. +C + CALL DSLVD(NEQ,DELTA,WM,IWM) +C +C Update Y, E, and YPRIME. +C + DO 340 I=1,NEQ + Y(I)=Y(I)-DELTA(I) + E(I)=E(I)-DELTA(I) +340 YPRIME(I)=YPRIME(I)-CJ*DELTA(I) +C +C Test for convergence of the iteration. +C + DELNRM=DDWNRM(NEQ,DELTA,WT,RPAR,IPAR) + IF (M .EQ. 0) THEN + OLDNRM = DELNRM + IF (DELNRM .LE. TOLNEW) GO TO 370 + ELSE + RATE = (DELNRM/OLDNRM)**(1.0D0/M) + IF (RATE .GT. 0.9D0) GO TO 380 + S = RATE/(1.0D0 - RATE) + ENDIF + IF (S*DELNRM .LE. EPCON) GO TO 370 +C +C The corrector has not yet converged. +C Update M and test whether the +C maximum number of iterations have +C been tried. +C + M=M+1 + IF(M.GE.MAXIT) GO TO 380 +C +C Evaluate the residual, +C and go back to do another iteration. +C + IWM(LNRE)=IWM(LNRE)+1 + CALL RES(X,Y,YPRIME,CJ,DELTA,IRES,RPAR,IPAR) + IF (IRES .LT. 0) GO TO 380 + GO TO 300 +C +C The iteration has converged. +C +370 RETURN +C +C The iteration has not converged. Set IERNEW appropriately. +C +380 CONTINUE + IF (IRES .LE. -2 ) THEN + IERNEW = -1 + ELSE + IERNEW = 1 + ENDIF + RETURN +C +C +C------END OF SUBROUTINE DNSD------------------------------------------- + END + SUBROUTINE DMATD(NEQ,X,Y,YPRIME,DELTA,CJ,H,IER,EWT,E, + * WM,IWM,RES,IRES,UROUND,JACD,RPAR,IPAR) +C +C***BEGIN PROLOGUE DMATD +C***REFER TO DDASPK +C***DATE WRITTEN 890101 (YYMMDD) +C***REVISION DATE 900926 (YYMMDD) +C***REVISION DATE 940701 (YYMMDD) (new LIPVT) +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C This routine computes the iteration matrix +C J = dG/dY+CJ*dG/dYPRIME (where G(X,Y,YPRIME)=0). +C Here J is computed by: +C the user-supplied routine JACD if IWM(MTYPE) is 1 or 4, or +C by numerical difference quotients if IWM(MTYPE) is 2 or 5. +C +C The parameters have the following meanings. +C X = Independent variable. +C Y = Array containing predicted values. +C YPRIME = Array containing predicted derivatives. +C DELTA = Residual evaluated at (X,Y,YPRIME). +C (Used only if IWM(MTYPE)=2 or 5). +C CJ = Scalar parameter defining iteration matrix. +C H = Current stepsize in integration. +C IER = Variable which is .NE. 0 if iteration matrix +C is singular, and 0 otherwise. +C EWT = Vector of error weights for computing norms. +C E = Work space (temporary) of length NEQ. +C WM = Real work space for matrices. On output +C it contains the LU decomposition +C of the iteration matrix. +C IWM = Integer work space containing +C matrix information. +C RES = External user-supplied subroutine +C to evaluate the residual. See RES description +C in DDASPK prologue. +C IRES = Flag which is equal to zero if no illegal values +C in RES, and less than zero otherwise. (If IRES +C is less than zero, the matrix was not completed). +C In this case (if IRES .LT. 0), then IER = 0. +C UROUND = The unit roundoff error of the machine being used. +C JACD = Name of the external user-supplied routine +C to evaluate the iteration matrix. (This routine +C is only used if IWM(MTYPE) is 1 or 4) +C See JAC description for the case INFO(12) = 0 +C in DDASPK prologue. +C RPAR,IPAR= Real and integer parameter arrays that +C are used for communication between the +C calling program and external user routines. +C They are not altered by DMATD. +C----------------------------------------------------------------------- +C***ROUTINES CALLED +C JACD, RES, DGEFA, DGBFA +C +C***END PROLOGUE DMATD +C +C + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + DIMENSION Y(*),YPRIME(*),DELTA(*),EWT(*),E(*) + DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*) + EXTERNAL RES, JACD +C + PARAMETER (LML=1, LMU=2, LMTYPE=4, LNRE=12, LNPD=22, LLCIWP=30) +C + LIPVT = IWM(LLCIWP) + IER = 0 + MTYPE=IWM(LMTYPE) + GO TO (100,200,300,400,500),MTYPE +C +C +C Dense user-supplied matrix. +C +100 LENPD=IWM(LNPD) + DO 110 I=1,LENPD +110 WM(I)=0.0D0 + CALL JACD(X,Y,YPRIME,WM,CJ,RPAR,IPAR) + GO TO 230 +C +C +C Dense finite-difference-generated matrix. +C +200 IRES=0 + NROW=0 + SQUR = SQRT(UROUND) + DO 210 I=1,NEQ + DEL=SQUR*MAX(ABS(Y(I)),ABS(H*YPRIME(I)), + * ABS(1.D0/EWT(I))) + DEL=SIGN(DEL,H*YPRIME(I)) + DEL=(Y(I)+DEL)-Y(I) + YSAVE=Y(I) + YPSAVE=YPRIME(I) + Y(I)=Y(I)+DEL + YPRIME(I)=YPRIME(I)+CJ*DEL + IWM(LNRE)=IWM(LNRE)+1 + CALL RES(X,Y,YPRIME,CJ,E,IRES,RPAR,IPAR) + IF (IRES .LT. 0) RETURN + DELINV=1.0D0/DEL + DO 220 L=1,NEQ +220 WM(NROW+L)=(E(L)-DELTA(L))*DELINV + NROW=NROW+NEQ + Y(I)=YSAVE + YPRIME(I)=YPSAVE +210 CONTINUE +C +C +C Do dense-matrix LU decomposition on J. +C +230 CALL DGEFA(WM,NEQ,NEQ,IWM(LIPVT),IER) + RETURN +C +C +C Dummy section for IWM(MTYPE)=3. +C +300 RETURN +C +C +C Banded user-supplied matrix. +C +400 LENPD=IWM(LNPD) + DO 410 I=1,LENPD +410 WM(I)=0.0D0 + CALL JACD(X,Y,YPRIME,WM,CJ,RPAR,IPAR) + MEBAND=2*IWM(LML)+IWM(LMU)+1 + GO TO 550 +C +C +C Banded finite-difference-generated matrix. +C +500 MBAND=IWM(LML)+IWM(LMU)+1 + MBA=MIN0(MBAND,NEQ) + MEBAND=MBAND+IWM(LML) + MEB1=MEBAND-1 + MSAVE=(NEQ/MBAND)+1 + ISAVE=IWM(LNPD) + IPSAVE=ISAVE+MSAVE + IRES=0 + SQUR=SQRT(UROUND) + DO 540 J=1,MBA + DO 510 N=J,NEQ,MBAND + K= (N-J)/MBAND + 1 + WM(ISAVE+K)=Y(N) + WM(IPSAVE+K)=YPRIME(N) + DEL=SQUR*MAX(ABS(Y(N)),ABS(H*YPRIME(N)), + * ABS(1.D0/EWT(N))) + DEL=SIGN(DEL,H*YPRIME(N)) + DEL=(Y(N)+DEL)-Y(N) + Y(N)=Y(N)+DEL +510 YPRIME(N)=YPRIME(N)+CJ*DEL + IWM(LNRE)=IWM(LNRE)+1 + CALL RES(X,Y,YPRIME,CJ,E,IRES,RPAR,IPAR) + IF (IRES .LT. 0) RETURN + DO 530 N=J,NEQ,MBAND + K= (N-J)/MBAND + 1 + Y(N)=WM(ISAVE+K) + YPRIME(N)=WM(IPSAVE+K) + DEL=SQUR*MAX(ABS(Y(N)),ABS(H*YPRIME(N)), + * ABS(1.D0/EWT(N))) + DEL=SIGN(DEL,H*YPRIME(N)) + DEL=(Y(N)+DEL)-Y(N) + DELINV=1.0D0/DEL + I1=MAX0(1,(N-IWM(LMU))) + I2=MIN0(NEQ,(N+IWM(LML))) + II=N*MEB1-IWM(LML) + DO 520 I=I1,I2 +520 WM(II+I)=(E(I)-DELTA(I))*DELINV +530 CONTINUE +540 CONTINUE +C +C +C Do LU decomposition of banded J. +C +550 CALL DGBFA (WM,MEBAND,NEQ,IWM(LML),IWM(LMU),IWM(LIPVT),IER) + RETURN +C +C------END OF SUBROUTINE DMATD------------------------------------------ + END + SUBROUTINE DSLVD(NEQ,DELTA,WM,IWM) +C +C***BEGIN PROLOGUE DSLVD +C***REFER TO DDASPK +C***DATE WRITTEN 890101 (YYMMDD) +C***REVISION DATE 900926 (YYMMDD) +C***REVISION DATE 940701 (YYMMDD) (new LIPVT) +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C This routine manages the solution of the linear +C system arising in the Newton iteration. +C Real matrix information and real temporary storage +C is stored in the array WM. +C Integer matrix information is stored in the array IWM. +C For a dense matrix, the LINPACK routine DGESL is called. +C For a banded matrix, the LINPACK routine DGBSL is called. +C----------------------------------------------------------------------- +C***ROUTINES CALLED +C DGESL, DGBSL +C +C***END PROLOGUE DSLVD +C +C + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + DIMENSION DELTA(*),WM(*),IWM(*) +C + PARAMETER (LML=1, LMU=2, LMTYPE=4, LLCIWP=30) +C + LIPVT = IWM(LLCIWP) + MTYPE=IWM(LMTYPE) + GO TO(100,100,300,400,400),MTYPE +C +C Dense matrix. +C +100 CALL DGESL(WM,NEQ,NEQ,IWM(LIPVT),DELTA,0) + RETURN +C +C Dummy section for MTYPE=3. +C +300 CONTINUE + RETURN +C +C Banded matrix. +C +400 MEBAND=2*IWM(LML)+IWM(LMU)+1 + CALL DGBSL(WM,MEBAND,NEQ,IWM(LML), + * IWM(LMU),IWM(LIPVT),DELTA,0) + RETURN +C +C------END OF SUBROUTINE DSLVD------------------------------------------ + END + SUBROUTINE DDASIK(X,Y,YPRIME,NEQ,ICOPT,ID,RES,JACK,PSOL,H,TSCALE, + * WT,JSKIP,RPAR,IPAR,SAVR,DELTA,R,YIC,YPIC,PWK,WM,IWM,CJ,UROUND, + * EPLI,SQRTN,RSQRTN,EPCON,RATEMX,STPTOL,JFLG, + * ICNFLG,ICNSTR,IERNLS) +C +C***BEGIN PROLOGUE DDASIK +C***REFER TO DDASPK +C***DATE WRITTEN 941026 (YYMMDD) +C***REVISION DATE 950808 (YYMMDD) +C***REVISION DATE 951110 Removed unreachable block 390. +C***REVISION DATE 000628 TSCALE argument added. +C +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C +C DDASIK solves a nonlinear system of algebraic equations of the +C form G(X,Y,YPRIME) = 0 for the unknown parts of Y and YPRIME in +C the initial conditions. +C +C An initial value for Y and initial guess for YPRIME are input. +C +C The method used is a Newton scheme with Krylov iteration and a +C linesearch algorithm. +C +C The parameters represent +C +C X -- Independent variable. +C Y -- Solution vector at x. +C YPRIME -- Derivative of solution vector. +C NEQ -- Number of equations to be integrated. +C ICOPT -- Initial condition option chosen (1 or 2). +C ID -- Array of dimension NEQ, which must be initialized +C if ICOPT = 1. See DDASIC. +C RES -- External user-supplied subroutine +C to evaluate the residual. See RES description +C in DDASPK prologue. +C JACK -- External user-supplied routine to update +C the preconditioner. (This is optional). +C See JAC description for the case +C INFO(12) = 1 in the DDASPK prologue. +C PSOL -- External user-supplied routine to solve +C a linear system using preconditioning. +C (This is optional). See explanation inside DDASPK. +C H -- Scaling factor for this initial condition calc. +C TSCALE -- Scale factor in T, used for stopping tests if nonzero. +C WT -- Vector of weights for error criterion. +C JSKIP -- input flag to signal if initial JAC call is to be +C skipped. 1 => skip the call, 0 => do not skip call. +C RPAR,IPAR -- Real and integer arrays used for communication +C between the calling program and external user +C routines. They are not altered within DASPK. +C SAVR -- Work vector for DDASIK of length NEQ. +C DELTA -- Work vector for DDASIK of length NEQ. +C R -- Work vector for DDASIK of length NEQ. +C YIC,YPIC -- Work vectors for DDASIK, each of length NEQ. +C PWK -- Work vector for DDASIK of length NEQ. +C WM,IWM -- Real and integer arrays storing +C matrix information for linear system +C solvers, and various other information. +C CJ -- Matrix parameter = 1/H (ICOPT = 1) or 0 (ICOPT = 2). +C UROUND -- Unit roundoff. Not used here. +C EPLI -- convergence test constant. +C See DDASPK prologue for more details. +C SQRTN -- Square root of NEQ. +C RSQRTN -- reciprical of square root of NEQ. +C EPCON -- Tolerance to test for convergence of the Newton +C iteration. +C RATEMX -- Maximum convergence rate for which Newton iteration +C is considered converging. +C JFLG -- Flag showing whether a Jacobian routine is supplied. +C ICNFLG -- Integer scalar. If nonzero, then constraint +C violations in the proposed new approximate solution +C will be checked for, and the maximum step length +C will be adjusted accordingly. +C ICNSTR -- Integer array of length NEQ containing flags for +C checking constraints. +C IERNLS -- Error flag for nonlinear solver. +C 0 ==> nonlinear solver converged. +C 1,2 ==> recoverable error inside nonlinear solver. +C 1 => retry with current Y, YPRIME +C 2 => retry with original Y, YPRIME +C -1 ==> unrecoverable error in nonlinear solver. +C +C----------------------------------------------------------------------- +C +C***ROUTINES CALLED +C RES, JACK, DNSIK, DCOPY +C +C***END PROLOGUE DDASIK +C +C + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + DIMENSION Y(*),YPRIME(*),ID(*),WT(*),ICNSTR(*) + DIMENSION SAVR(*),DELTA(*),R(*),YIC(*),YPIC(*),PWK(*) + DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*) + EXTERNAL RES, JACK, PSOL +C + PARAMETER (LNRE=12, LNJE=13, LLOCWP=29, LLCIWP=30) + PARAMETER (LMXNIT=32, LMXNJ=33) +C +C +C Perform initializations. +C + LWP = IWM(LLOCWP) + LIWP = IWM(LLCIWP) + MXNIT = IWM(LMXNIT) + MXNJ = IWM(LMXNJ) + IERNLS = 0 + NJ = 0 + EPLIN = EPLI*EPCON +C +C Call RES to initialize DELTA. +C + IRES = 0 + IWM(LNRE) = IWM(LNRE) + 1 + CALL RES(X,Y,YPRIME,CJ,DELTA,IRES,RPAR,IPAR) + IF (IRES .LT. 0) GO TO 370 +C +C Looping point for updating the preconditioner. +C + 300 CONTINUE +C +C Initialize all error flags to zero. +C + IERPJ = 0 + IRES = 0 + IERNEW = 0 +C +C If a Jacobian routine was supplied, call it. +C + IF (JFLG .EQ. 1 .AND. JSKIP .EQ. 0) THEN + NJ = NJ + 1 + IWM(LNJE)=IWM(LNJE)+1 + CALL JACK (RES, IRES, NEQ, X, Y, YPRIME, WT, DELTA, R, H, CJ, + * WM(LWP), IWM(LIWP), IERPJ, RPAR, IPAR) + IF (IRES .LT. 0 .OR. IERPJ .NE. 0) GO TO 370 + ENDIF + JSKIP = 0 +C +C Call the nonlinear Newton solver for up to MXNIT iterations. +C + CALL DNSIK(X,Y,YPRIME,NEQ,ICOPT,ID,RES,PSOL,WT,RPAR,IPAR, + * SAVR,DELTA,R,YIC,YPIC,PWK,WM,IWM,CJ,TSCALE,SQRTN,RSQRTN, + * EPLIN,EPCON,RATEMX,MXNIT,STPTOL,ICNFLG,ICNSTR,IERNEW) +C + IF (IERNEW .EQ. 1 .AND. NJ .LT. MXNJ .AND. JFLG .EQ. 1) THEN +C +C Up to MXNIT iterations were done, the convergence rate is < 1, +C a Jacobian routine is supplied, and the number of JACK calls +C is less than MXNJ. +C Copy the residual SAVR to DELTA, call JACK, and try again. +C + CALL DCOPY (NEQ, SAVR, 1, DELTA, 1) + GO TO 300 + ENDIF +C + IF (IERNEW .NE. 0) GO TO 380 + RETURN +C +C +C Unsuccessful exits from nonlinear solver. +C Set IERNLS accordingly. +C + 370 IERNLS = 2 + IF (IRES .LE. -2) IERNLS = -1 + RETURN +C + 380 IERNLS = MIN(IERNEW,2) + RETURN +C +C----------------------- END OF SUBROUTINE DDASIK----------------------- + END + SUBROUTINE DNSIK(X,Y,YPRIME,NEQ,ICOPT,ID,RES,PSOL,WT,RPAR,IPAR, + * SAVR,DELTA,R,YIC,YPIC,PWK,WM,IWM,CJ,TSCALE,SQRTN,RSQRTN,EPLIN, + * EPCON,RATEMX,MAXIT,STPTOL,ICNFLG,ICNSTR,IERNEW) +C +C***BEGIN PROLOGUE DNSIK +C***REFER TO DDASPK +C***DATE WRITTEN 940701 (YYMMDD) +C***REVISION DATE 950714 (YYMMDD) +C***REVISION DATE 000628 TSCALE argument added. +C***REVISION DATE 000628 Added criterion for IERNEW = 1 return. +C +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C DNSIK solves a nonlinear system of algebraic equations of the +C form G(X,Y,YPRIME) = 0 for the unknown parts of Y and YPRIME in +C the initial conditions. +C +C The method used is a Newton scheme combined with a linesearch +C algorithm, using Krylov iterative linear system methods. +C +C The parameters represent +C +C X -- Independent variable. +C Y -- Solution vector. +C YPRIME -- Derivative of solution vector. +C NEQ -- Number of unknowns. +C ICOPT -- Initial condition option chosen (1 or 2). +C ID -- Array of dimension NEQ, which must be initialized +C if ICOPT = 1. See DDASIC. +C RES -- External user-supplied subroutine +C to evaluate the residual. See RES description +C in DDASPK prologue. +C PSOL -- External user-supplied routine to solve +C a linear system using preconditioning. +C See explanation inside DDASPK. +C WT -- Vector of weights for error criterion. +C RPAR,IPAR -- Real and integer arrays used for communication +C between the calling program and external user +C routines. They are not altered within DASPK. +C SAVR -- Work vector for DNSIK of length NEQ. +C DELTA -- Residual vector on entry, and work vector of +C length NEQ for DNSIK. +C R -- Work vector for DNSIK of length NEQ. +C YIC,YPIC -- Work vectors for DNSIK, each of length NEQ. +C PWK -- Work vector for DNSIK of length NEQ. +C WM,IWM -- Real and integer arrays storing +C matrix information such as the matrix +C of partial derivatives, permutation +C vector, and various other information. +C CJ -- Matrix parameter = 1/H (ICOPT = 1) or 0 (ICOPT = 2). +C TSCALE -- Scale factor in T, used for stopping tests if nonzero. +C SQRTN -- Square root of NEQ. +C RSQRTN -- reciprical of square root of NEQ. +C EPLIN -- Tolerance for linear system solver. +C EPCON -- Tolerance to test for convergence of the Newton +C iteration. +C RATEMX -- Maximum convergence rate for which Newton iteration +C is considered converging. +C MAXIT -- Maximum allowed number of Newton iterations. +C STPTOL -- Tolerance used in calculating the minimum lambda +C value allowed. +C ICNFLG -- Integer scalar. If nonzero, then constraint +C violations in the proposed new approximate solution +C will be checked for, and the maximum step length +C will be adjusted accordingly. +C ICNSTR -- Integer array of length NEQ containing flags for +C checking constraints. +C IERNEW -- Error flag for Newton iteration. +C 0 ==> Newton iteration converged. +C 1 ==> failed to converge, but RATE .lt. 1, or the +C residual norm was reduced by a factor of .1. +C 2 ==> failed to converge, RATE .gt. RATEMX. +C 3 ==> other recoverable error. +C -1 ==> unrecoverable error inside Newton iteration. +C----------------------------------------------------------------------- +C +C***ROUTINES CALLED +C DFNRMK, DSLVK, DDWNRM, DLINSK, DCOPY +C +C***END PROLOGUE DNSIK +C +C + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + DIMENSION Y(*),YPRIME(*),WT(*),ID(*),DELTA(*),R(*),SAVR(*) + DIMENSION YIC(*),YPIC(*),PWK(*),WM(*),IWM(*), RPAR(*),IPAR(*) + DIMENSION ICNSTR(*) + EXTERNAL RES, PSOL +C + PARAMETER (LNNI=19, LNPS=21, LLOCWP=29, LLCIWP=30) + PARAMETER (LLSOFF=35, LSTOL=14) +C +C +C Initializations. M is the Newton iteration counter. +C + LSOFF = IWM(LLSOFF) + M = 0 + RATE = 1.0D0 + LWP = IWM(LLOCWP) + LIWP = IWM(LLCIWP) + RLX = 0.4D0 +C +C Save residual in SAVR. +C + CALL DCOPY (NEQ, DELTA, 1, SAVR, 1) +C +C Compute norm of (P-inverse)*(residual). +C + CALL DFNRMK (NEQ, Y, X, YPRIME, SAVR, R, CJ, TSCALE, WT, + * SQRTN, RSQRTN, RES, IRES, PSOL, 1, IER, FNRM, EPLIN, + * WM(LWP), IWM(LIWP), PWK, RPAR, IPAR) + IWM(LNPS) = IWM(LNPS) + 1 + IF (IER .NE. 0) THEN + IERNEW = 3 + RETURN + ENDIF +C +C Return now if residual norm is .le. EPCON. +C + IF (FNRM .LE. EPCON) RETURN +C +C Newton iteration loop. +C + FNRM0 = FNRM +300 CONTINUE + IWM(LNNI) = IWM(LNNI) + 1 +C +C Compute a new step vector DELTA. +C + CALL DSLVK (NEQ, Y, X, YPRIME, SAVR, DELTA, WT, WM, IWM, + * RES, IRES, PSOL, IERSL, CJ, EPLIN, SQRTN, RSQRTN, RHOK, + * RPAR, IPAR) + IF (IRES .NE. 0 .OR. IERSL .NE. 0) GO TO 390 +C +C Get norm of DELTA. Return now if DELTA is zero. +C + DELNRM = DDWNRM(NEQ,DELTA,WT,RPAR,IPAR) + IF (DELNRM .EQ. 0.0D0) RETURN +C +C Call linesearch routine for global strategy and set RATE. +C + OLDFNM = FNRM +C + CALL DLINSK (NEQ, Y, X, YPRIME, SAVR, CJ, TSCALE, DELTA, DELNRM, + * WT, SQRTN, RSQRTN, LSOFF, STPTOL, IRET, RES, IRES, PSOL, + * WM, IWM, RHOK, FNRM, ICOPT, ID, WM(LWP), IWM(LIWP), R, EPLIN, + * YIC, YPIC, PWK, ICNFLG, ICNSTR, RLX, RPAR, IPAR) +C + RATE = FNRM/OLDFNM +C +C Check for error condition from linesearch. + IF (IRET .NE. 0) GO TO 390 +C +C Test for convergence of the iteration, and return or loop. +C + IF (FNRM .LE. EPCON) RETURN +C +C The iteration has not yet converged. Update M. +C Test whether the maximum number of iterations have been tried. +C + M = M + 1 + IF(M .GE. MAXIT) GO TO 380 +C +C Copy the residual SAVR to DELTA and loop for another iteration. +C + CALL DCOPY (NEQ, SAVR, 1, DELTA, 1) + GO TO 300 +C +C The maximum number of iterations was done. Set IERNEW and return. +C +380 IF (RATE .LE. RATEMX .OR. FNRM .LE. 0.1D0*FNRM0) THEN + IERNEW = 1 + ELSE + IERNEW = 2 + ENDIF + RETURN +C +390 IF (IRES .LE. -2 .OR. IERSL .LT. 0) THEN + IERNEW = -1 + ELSE + IERNEW = 3 + IF (IRES .EQ. 0 .AND. IERSL .EQ. 1 .AND. M .GE. 2 + 1 .AND. RATE .LT. 1.0D0) IERNEW = 1 + ENDIF + RETURN +C +C +C----------------------- END OF SUBROUTINE DNSIK------------------------ + END + SUBROUTINE DLINSK (NEQ, Y, T, YPRIME, SAVR, CJ, TSCALE, P, PNRM, + * WT, SQRTN, RSQRTN, LSOFF, STPTOL, IRET, RES, IRES, PSOL, + * WM, IWM, RHOK, FNRM, ICOPT, ID, WP, IWP, R, EPLIN, YNEW, YPNEW, + * PWK, ICNFLG, ICNSTR, RLX, RPAR, IPAR) +C +C***BEGIN PROLOGUE DLINSK +C***REFER TO DNSIK +C***DATE WRITTEN 940830 (YYMMDD) +C***REVISION DATE 951006 (Arguments SQRTN, RSQRTN added.) +C***REVISION DATE 960129 Moved line RL = ONE to top block. +C***REVISION DATE 000628 TSCALE argument added. +C***REVISION DATE 000628 RHOK*RHOK term removed in alpha test. +C +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C DLINSK uses a linesearch algorithm to calculate a new (Y,YPRIME) +C pair (YNEW,YPNEW) such that +C +C f(YNEW,YPNEW) .le. (1 - 2*ALPHA*RL)*f(Y,YPRIME) +C +C where 0 < RL <= 1, and RHOK is the scaled preconditioned norm of +C the final residual vector in the Krylov iteration. +C Here, f(y,y') is defined as +C +C f(y,y') = (1/2)*norm( (P-inverse)*G(t,y,y') )**2 , +C +C where norm() is the weighted RMS vector norm, G is the DAE +C system residual function, and P is the preconditioner used +C in the Krylov iteration. +C +C In addition to the parameters defined elsewhere, we have +C +C SAVR -- Work array of length NEQ, containing the residual +C vector G(t,y,y') on return. +C TSCALE -- Scale factor in T, used for stopping tests if nonzero. +C P -- Approximate Newton step used in backtracking. +C PNRM -- Weighted RMS norm of P. +C LSOFF -- Flag showing whether the linesearch algorithm is +C to be invoked. 0 means do the linesearch, +C 1 means turn off linesearch. +C STPTOL -- Tolerance used in calculating the minimum lambda +C value allowed. +C ICNFLG -- Integer scalar. If nonzero, then constraint violations +C in the proposed new approximate solution will be +C checked for, and the maximum step length will be +C adjusted accordingly. +C ICNSTR -- Integer array of length NEQ containing flags for +C checking constraints. +C RHOK -- Weighted norm of preconditioned Krylov residual. +C RLX -- Real scalar restricting update size in DCNSTR. +C YNEW -- Array of length NEQ used to hold the new Y in +C performing the linesearch. +C YPNEW -- Array of length NEQ used to hold the new YPRIME in +C performing the linesearch. +C PWK -- Work vector of length NEQ for use in PSOL. +C Y -- Array of length NEQ containing the new Y (i.e.,=YNEW). +C YPRIME -- Array of length NEQ containing the new YPRIME +C (i.e.,=YPNEW). +C FNRM -- Real scalar containing SQRT(2*f(Y,YPRIME)) for the +C current (Y,YPRIME) on input and output. +C R -- Work space length NEQ for residual vector. +C IRET -- Return flag. +C IRET=0 means that a satisfactory (Y,YPRIME) was found. +C IRET=1 means that the routine failed to find a new +C (Y,YPRIME) that was sufficiently distinct from +C the current (Y,YPRIME) pair. +C IRET=2 means a failure in RES or PSOL. +C----------------------------------------------------------------------- +C +C***ROUTINES CALLED +C DFNRMK, DYYPNW, DCNSTR, DCOPY, XERRWD +C +C***END PROLOGUE DLINSK +C + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + EXTERNAL RES, PSOL + DIMENSION Y(*), YPRIME(*), P(*), WT(*), SAVR(*), R(*), ID(*) + DIMENSION WM(*), IWM(*), YNEW(*), YPNEW(*), PWK(*), ICNSTR(*) + DIMENSION WP(*), IWP(*), RPAR(*), IPAR(*) + CHARACTER MSG*80 +C + PARAMETER (LNRE=12, LNPS=21, LKPRIN=31) +C + SAVE ALPHA, ONE, TWO + DATA ALPHA/1.0D-4/, ONE/1.0D0/, TWO/2.0D0/ +C + KPRIN=IWM(LKPRIN) + F1NRM = (FNRM*FNRM)/TWO + RATIO = ONE +C + IF (KPRIN .GE. 2) THEN + MSG = '------ IN ROUTINE DLINSK-- PNRM = (R1)' + CALL XERRWD(MSG, 38, 921, 0, 0, 0, 0, 1, PNRM, 0.0D0) + ENDIF + TAU = PNRM + RL = ONE +C----------------------------------------------------------------------- +C Check for violations of the constraints, if any are imposed. +C If any violations are found, the step vector P is rescaled, and the +C constraint check is repeated, until no violations are found. +C----------------------------------------------------------------------- + IF (ICNFLG .NE. 0) THEN + 10 CONTINUE + CALL DYYPNW (NEQ,Y,YPRIME,CJ,RL,P,ICOPT,ID,YNEW,YPNEW) + CALL DCNSTR (NEQ, Y, YNEW, ICNSTR, TAU, RLX, IRET, IVAR) + IF (IRET .EQ. 1) THEN + RATIO1 = TAU/PNRM + RATIO = RATIO*RATIO1 + DO 20 I = 1,NEQ + 20 P(I) = P(I)*RATIO1 + PNRM = TAU + IF (KPRIN .GE. 2) THEN + MSG = '------ CONSTRAINT VIOL., PNRM = (R1), INDEX = (I1)' + CALL XERRWD(MSG, 50, 922, 0, 1, IVAR, 0, 1, PNRM, 0.0D0) + ENDIF + IF (PNRM .LE. STPTOL) THEN + IRET = 1 + RETURN + ENDIF + GO TO 10 + ENDIF + ENDIF +C + SLPI = -TWO*F1NRM*RATIO + RLMIN = STPTOL/PNRM + IF (LSOFF .EQ. 0 .AND. KPRIN .GE. 2) THEN + MSG = '------ MIN. LAMBDA = (R1)' + CALL XERRWD(MSG, 25, 923, 0, 0, 0, 0, 1, RLMIN, 0.0D0) + ENDIF +C----------------------------------------------------------------------- +C Begin iteration to find RL value satisfying alpha-condition. +C Update YNEW and YPNEW, then compute norm of new scaled residual and +C perform alpha condition test. +C----------------------------------------------------------------------- + 100 CONTINUE + CALL DYYPNW (NEQ,Y,YPRIME,CJ,RL,P,ICOPT,ID,YNEW,YPNEW) + CALL DFNRMK (NEQ, YNEW, T, YPNEW, SAVR, R, CJ, TSCALE, WT, + * SQRTN, RSQRTN, RES, IRES, PSOL, 0, IER, FNRMP, EPLIN, + * WP, IWP, PWK, RPAR, IPAR) + IWM(LNRE) = IWM(LNRE) + 1 + IF (IRES .GE. 0) IWM(LNPS) = IWM(LNPS) + 1 + IF (IRES .NE. 0 .OR. IER .NE. 0) THEN + IRET = 2 + RETURN + ENDIF + IF (LSOFF .EQ. 1) GO TO 150 +C + F1NRMP = FNRMP*FNRMP/TWO + IF (KPRIN .GE. 2) THEN + MSG = '------ LAMBDA = (R1)' + CALL XERRWD(MSG, 20, 924, 0, 0, 0, 0, 1, RL, 0.0D0) + MSG = '------ NORM(F1) = (R1), NORM(F1NEW) = (R2)' + CALL XERRWD(MSG, 43, 925, 0, 0, 0, 0, 2, F1NRM, F1NRMP) + ENDIF + IF (F1NRMP .GT. F1NRM + ALPHA*SLPI*RL) GO TO 200 +C----------------------------------------------------------------------- +C Alpha-condition is satisfied, or linesearch is turned off. +C Copy YNEW,YPNEW to Y,YPRIME and return. +C----------------------------------------------------------------------- + 150 IRET = 0 + CALL DCOPY(NEQ, YNEW, 1, Y, 1) + CALL DCOPY(NEQ, YPNEW, 1, YPRIME, 1) + FNRM = FNRMP + IF (KPRIN .GE. 1) THEN + MSG = '------ LEAVING ROUTINE DLINSK, FNRM = (R1)' + CALL XERRWD(MSG, 42, 926, 0, 0, 0, 0, 1, FNRM, 0.0D0) + ENDIF + RETURN +C----------------------------------------------------------------------- +C Alpha-condition not satisfied. Perform backtrack to compute new RL +C value. If RL is less than RLMIN, i.e. no satisfactory YNEW,YPNEW can +C be found sufficiently distinct from Y,YPRIME, then return IRET = 1. +C----------------------------------------------------------------------- + 200 CONTINUE + IF (RL .LT. RLMIN) THEN + IRET = 1 + RETURN + ENDIF +C + RL = RL/TWO + GO TO 100 +C +C----------------------- END OF SUBROUTINE DLINSK ---------------------- + END + SUBROUTINE DFNRMK (NEQ, Y, T, YPRIME, SAVR, R, CJ, TSCALE, WT, + * SQRTN, RSQRTN, RES, IRES, PSOL, IRIN, IER, + * FNORM, EPLIN, WP, IWP, PWK, RPAR, IPAR) +C +C***BEGIN PROLOGUE DFNRMK +C***REFER TO DLINSK +C***DATE WRITTEN 940830 (YYMMDD) +C***REVISION DATE 951006 (SQRTN, RSQRTN, and scaling of WT added.) +C***REVISION DATE 000628 TSCALE argument added. +C +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C DFNRMK calculates the scaled preconditioned norm of the nonlinear +C function used in the nonlinear iteration for obtaining consistent +C initial conditions. Specifically, DFNRMK calculates the weighted +C root-mean-square norm of the vector (P-inverse)*G(T,Y,YPRIME), +C where P is the preconditioner matrix. +C +C In addition to the parameters described in the calling program +C DLINSK, the parameters represent +C +C TSCALE -- Scale factor in T, used for stopping tests if nonzero. +C IRIN -- Flag showing whether the current residual vector is +C input in SAVR. 1 means it is, 0 means it is not. +C R -- Array of length NEQ that contains +C (P-inverse)*G(T,Y,YPRIME) on return. +C FNORM -- Scalar containing the weighted norm of R on return. +C----------------------------------------------------------------------- +C +C***ROUTINES CALLED +C RES, DCOPY, DSCAL, PSOL, DDWNRM +C +C***END PROLOGUE DFNRMK +C +C + IMPLICIT DOUBLE PRECISION (A-H,O-Z) + EXTERNAL RES, PSOL + DIMENSION Y(*), YPRIME(*), WT(*), SAVR(*), R(*), PWK(*) + DIMENSION WP(*), IWP(*), RPAR(*), IPAR(*) +C----------------------------------------------------------------------- +C Call RES routine if IRIN = 0. +C----------------------------------------------------------------------- + IF (IRIN .EQ. 0) THEN + IRES = 0 + CALL RES (T, Y, YPRIME, CJ, SAVR, IRES, RPAR, IPAR) + IF (IRES .LT. 0) RETURN + ENDIF +C----------------------------------------------------------------------- +C Apply inverse of left preconditioner to vector R. +C First scale WT array by 1/sqrt(N), and undo scaling afterward. +C----------------------------------------------------------------------- + CALL DCOPY(NEQ, SAVR, 1, R, 1) + CALL DSCAL (NEQ, RSQRTN, WT, 1) + IER = 0 + CALL PSOL (NEQ, T, Y, YPRIME, SAVR, PWK, CJ, WT, WP, IWP, + * R, EPLIN, IER, RPAR, IPAR) + CALL DSCAL (NEQ, SQRTN, WT, 1) + IF (IER .NE. 0) RETURN +C----------------------------------------------------------------------- +C Calculate norm of R. +C----------------------------------------------------------------------- + FNORM = DDWNRM (NEQ, R, WT, RPAR, IPAR) + IF (TSCALE .GT. 0.0D0) FNORM = FNORM*TSCALE*ABS(CJ) +C + RETURN +C----------------------- END OF SUBROUTINE DFNRMK ---------------------- + END + SUBROUTINE DNEDK(X,Y,YPRIME,NEQ,RES,JACK,PSOL, + * H,WT,JSTART,IDID,RPAR,IPAR,PHI,GAMMA,SAVR,DELTA,E, + * WM,IWM,CJ,CJOLD,CJLAST,S,UROUND,EPLI,SQRTN,RSQRTN, + * EPCON,JCALC,JFLG,KP1,NONNEG,NTYPE,IERNLS) +C +C***BEGIN PROLOGUE DNEDK +C***REFER TO DDASPK +C***DATE WRITTEN 891219 (YYMMDD) +C***REVISION DATE 900926 (YYMMDD) +C***REVISION DATE 940701 (YYMMDD) +C +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C DNEDK solves a nonlinear system of +C algebraic equations of the form +C G(X,Y,YPRIME) = 0 for the unknown Y. +C +C The method used is a matrix-free Newton scheme. +C +C The parameters represent +C X -- Independent variable. +C Y -- Solution vector at x. +C YPRIME -- Derivative of solution vector +C after successful step. +C NEQ -- Number of equations to be integrated. +C RES -- External user-supplied subroutine +C to evaluate the residual. See RES description +C in DDASPK prologue. +C JACK -- External user-supplied routine to update +C the preconditioner. (This is optional). +C See JAC description for the case +C INFO(12) = 1 in the DDASPK prologue. +C PSOL -- External user-supplied routine to solve +C a linear system using preconditioning. +C (This is optional). See explanation inside DDASPK. +C H -- Appropriate step size for this step. +C WT -- Vector of weights for error criterion. +C JSTART -- Indicates first call to this routine. +C If JSTART = 0, then this is the first call, +C otherwise it is not. +C IDID -- Completion flag, output by DNEDK. +C See IDID description in DDASPK prologue. +C RPAR,IPAR -- Real and integer arrays used for communication +C between the calling program and external user +C routines. They are not altered within DASPK. +C PHI -- Array of divided differences used by +C DNEDK. The length is NEQ*(K+1), where +C K is the maximum order. +C GAMMA -- Array used to predict Y and YPRIME. The length +C is K+1, where K is the maximum order. +C SAVR -- Work vector for DNEDK of length NEQ. +C DELTA -- Work vector for DNEDK of length NEQ. +C E -- Error accumulation vector for DNEDK of length NEQ. +C WM,IWM -- Real and integer arrays storing +C matrix information for linear system +C solvers, and various other information. +C CJ -- Parameter always proportional to 1/H. +C CJOLD -- Saves the value of CJ as of the last call to DITMD. +C Accounts for changes in CJ needed to +C decide whether to call DITMD. +C CJLAST -- Previous value of CJ. +C S -- A scalar determined by the approximate rate +C of convergence of the Newton iteration and used +C in the convergence test for the Newton iteration. +C +C If RATE is defined to be an estimate of the +C rate of convergence of the Newton iteration, +C then S = RATE/(1.D0-RATE). +C +C The closer RATE is to 0., the faster the Newton +C iteration is converging; the closer RATE is to 1., +C the slower the Newton iteration is converging. +C +C On the first Newton iteration with an up-dated +C preconditioner S = 100.D0, Thus the initial +C RATE of convergence is approximately 1. +C +C S is preserved from call to call so that the rate +C estimate from a previous step can be applied to +C the current step. +C UROUND -- Unit roundoff. Not used here. +C EPLI -- convergence test constant. +C See DDASPK prologue for more details. +C SQRTN -- Square root of NEQ. +C RSQRTN -- reciprical of square root of NEQ. +C EPCON -- Tolerance to test for convergence of the Newton +C iteration. +C JCALC -- Flag used to determine when to update +C the Jacobian matrix. In general: +C +C JCALC = -1 ==> Call the DITMD routine to update +C the Jacobian matrix. +C JCALC = 0 ==> Jacobian matrix is up-to-date. +C JCALC = 1 ==> Jacobian matrix is out-dated, +C but DITMD will not be called unless +C JCALC is set to -1. +C JFLG -- Flag showing whether a Jacobian routine is supplied. +C KP1 -- The current order + 1; updated across calls. +C NONNEG -- Flag to determine nonnegativity constraints. +C NTYPE -- Identification code for the DNEDK routine. +C 1 ==> modified Newton; iterative linear solver. +C 2 ==> modified Newton; user-supplied linear solver. +C IERNLS -- Error flag for nonlinear solver. +C 0 ==> nonlinear solver converged. +C 1 ==> recoverable error inside non-linear solver. +C -1 ==> unrecoverable error inside non-linear solver. +C +C The following group of variables are passed as arguments to +C the Newton iteration solver. They are explained in greater detail +C in DNSK: +C TOLNEW, MULDEL, MAXIT, IERNEW +C +C IERTYP -- Flag which tells whether this subroutine is correct. +C 0 ==> correct subroutine. +C 1 ==> incorrect subroutine. +C +C----------------------------------------------------------------------- +C***ROUTINES CALLED +C RES, JACK, DDWNRM, DNSK +C +C***END PROLOGUE DNEDK +C +C + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + DIMENSION Y(*),YPRIME(*),WT(*) + DIMENSION PHI(NEQ,*),SAVR(*),DELTA(*),E(*) + DIMENSION WM(*),IWM(*) + DIMENSION GAMMA(*),RPAR(*),IPAR(*) + EXTERNAL RES, JACK, PSOL +C + PARAMETER (LNRE=12, LNJE=13, LLOCWP=29, LLCIWP=30) +C + SAVE MULDEL, MAXIT, XRATE + DATA MULDEL/0/, MAXIT/4/, XRATE/0.25D0/ +C +C Verify that this is the correct subroutine. +C + IERTYP = 0 + IF (NTYPE .NE. 1) THEN + IERTYP = 1 + GO TO 380 + ENDIF +C +C If this is the first step, perform initializations. +C + IF (JSTART .EQ. 0) THEN + CJOLD = CJ + JCALC = -1 + S = 100.D0 + ENDIF +C +C Perform all other initializations. +C + IERNLS = 0 + LWP = IWM(LLOCWP) + LIWP = IWM(LLCIWP) +C +C Decide whether to update the preconditioner. +C + IF (JFLG .NE. 0) THEN + TEMP1 = (1.0D0 - XRATE)/(1.0D0 + XRATE) + TEMP2 = 1.0D0/TEMP1 + IF (CJ/CJOLD .LT. TEMP1 .OR. CJ/CJOLD .GT. TEMP2) JCALC = -1 + IF (CJ .NE. CJLAST) S = 100.D0 + ELSE + JCALC = 0 + ENDIF +C +C Looping point for updating preconditioner with current stepsize. +C +300 CONTINUE +C +C Initialize all error flags to zero. +C + IERPJ = 0 + IRES = 0 + IERSL = 0 + IERNEW = 0 +C +C Predict the solution and derivative and compute the tolerance +C for the Newton iteration. +C + DO 310 I=1,NEQ + Y(I)=PHI(I,1) +310 YPRIME(I)=0.0D0 + DO 330 J=2,KP1 + DO 320 I=1,NEQ + Y(I)=Y(I)+PHI(I,J) +320 YPRIME(I)=YPRIME(I)+GAMMA(J)*PHI(I,J) +330 CONTINUE + EPLIN = EPLI*EPCON + TOLNEW = EPLIN +C +C Call RES to initialize DELTA. +C + IWM(LNRE)=IWM(LNRE)+1 + CALL RES(X,Y,YPRIME,CJ,DELTA,IRES,RPAR,IPAR) + IF (IRES .LT. 0) GO TO 380 +C +C +C If indicated, update the preconditioner. +C Set JCALC to 0 as an indicator that this has been done. +C + IF(JCALC .EQ. -1)THEN + IWM(LNJE) = IWM(LNJE) + 1 + JCALC=0 + CALL JACK (RES, IRES, NEQ, X, Y, YPRIME, WT, DELTA, E, H, CJ, + * WM(LWP), IWM(LIWP), IERPJ, RPAR, IPAR) + CJOLD=CJ + S = 100.D0 + IF (IRES .LT. 0) GO TO 380 + IF (IERPJ .NE. 0) GO TO 380 + ENDIF +C +C Call the nonlinear Newton solver. +C + CALL DNSK(X,Y,YPRIME,NEQ,RES,PSOL,WT,RPAR,IPAR,SAVR, + * DELTA,E,WM,IWM,CJ,SQRTN,RSQRTN,EPLIN,EPCON, + * S,TEMP1,TOLNEW,MULDEL,MAXIT,IRES,IERSL,IERNEW) +C + IF (IERNEW .GT. 0 .AND. JCALC .NE. 0) THEN +C +C The Newton iteration had a recoverable failure with an old +C preconditioner. Retry the step with a new preconditioner. +C + JCALC = -1 + GO TO 300 + ENDIF +C + IF (IERNEW .NE. 0) GO TO 380 +C +C The Newton iteration has converged. If nonnegativity of +C solution is required, set the solution nonnegative, if the +C perturbation to do it is small enough. If the change is too +C large, then consider the corrector iteration to have failed. +C + IF(NONNEG .EQ. 0) GO TO 390 + DO 360 I = 1,NEQ + 360 DELTA(I) = MIN(Y(I),0.0D0) + DELNRM = DDWNRM(NEQ,DELTA,WT,RPAR,IPAR) + IF(DELNRM .GT. EPCON) GO TO 380 + DO 370 I = 1,NEQ + 370 E(I) = E(I) - DELTA(I) + GO TO 390 +C +C +C Exits from nonlinear solver. +C No convergence with current preconditioner. +C Compute IERNLS and IDID accordingly. +C +380 CONTINUE + IF (IRES .LE. -2 .OR. IERSL .LT. 0 .OR. IERTYP .NE. 0) THEN + IERNLS = -1 + IF (IRES .LE. -2) IDID = -11 + IF (IERSL .LT. 0) IDID = -13 + IF (IERTYP .NE. 0) IDID = -15 + ELSE + IERNLS = 1 + IF (IRES .EQ. -1) IDID = -10 + IF (IERPJ .NE. 0) IDID = -5 + IF (IERSL .GT. 0) IDID = -14 + ENDIF +C +C +390 JCALC = 1 + RETURN +C +C------END OF SUBROUTINE DNEDK------------------------------------------ + END + SUBROUTINE DNSK(X,Y,YPRIME,NEQ,RES,PSOL,WT,RPAR,IPAR, + * SAVR,DELTA,E,WM,IWM,CJ,SQRTN,RSQRTN,EPLIN,EPCON, + * S,CONFAC,TOLNEW,MULDEL,MAXIT,IRES,IERSL,IERNEW) +C +C***BEGIN PROLOGUE DNSK +C***REFER TO DDASPK +C***DATE WRITTEN 891219 (YYMMDD) +C***REVISION DATE 900926 (YYMMDD) +C***REVISION DATE 950126 (YYMMDD) +C***REVISION DATE 000711 (YYMMDD) +C +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C DNSK solves a nonlinear system of +C algebraic equations of the form +C G(X,Y,YPRIME) = 0 for the unknown Y. +C +C The method used is a modified Newton scheme. +C +C The parameters represent +C +C X -- Independent variable. +C Y -- Solution vector. +C YPRIME -- Derivative of solution vector. +C NEQ -- Number of unknowns. +C RES -- External user-supplied subroutine +C to evaluate the residual. See RES description +C in DDASPK prologue. +C PSOL -- External user-supplied routine to solve +C a linear system using preconditioning. +C See explanation inside DDASPK. +C WT -- Vector of weights for error criterion. +C RPAR,IPAR -- Real and integer arrays used for communication +C between the calling program and external user +C routines. They are not altered within DASPK. +C SAVR -- Work vector for DNSK of length NEQ. +C DELTA -- Work vector for DNSK of length NEQ. +C E -- Error accumulation vector for DNSK of length NEQ. +C WM,IWM -- Real and integer arrays storing +C matrix information such as the matrix +C of partial derivatives, permutation +C vector, and various other information. +C CJ -- Parameter always proportional to 1/H (step size). +C SQRTN -- Square root of NEQ. +C RSQRTN -- reciprical of square root of NEQ. +C EPLIN -- Tolerance for linear system solver. +C EPCON -- Tolerance to test for convergence of the Newton +C iteration. +C S -- Used for error convergence tests. +C In the Newton iteration: S = RATE/(1.D0-RATE), +C where RATE is the estimated rate of convergence +C of the Newton iteration. +C +C The closer RATE is to 0., the faster the Newton +C iteration is converging; the closer RATE is to 1., +C the slower the Newton iteration is converging. +C +C The calling routine sends the initial value +C of S to the Newton iteration. +C CONFAC -- A residual scale factor to improve convergence. +C TOLNEW -- Tolerance on the norm of Newton correction in +C alternative Newton convergence test. +C MULDEL -- A flag indicating whether or not to multiply +C DELTA by CONFAC. +C 0 ==> do not scale DELTA by CONFAC. +C 1 ==> scale DELTA by CONFAC. +C MAXIT -- Maximum allowed number of Newton iterations. +C IRES -- Error flag returned from RES. See RES description +C in DDASPK prologue. If IRES = -1, then IERNEW +C will be set to 1. +C If IRES < -1, then IERNEW will be set to -1. +C IERSL -- Error flag for linear system solver. +C See IERSL description in subroutine DSLVK. +C If IERSL = 1, then IERNEW will be set to 1. +C If IERSL < 0, then IERNEW will be set to -1. +C IERNEW -- Error flag for Newton iteration. +C 0 ==> Newton iteration converged. +C 1 ==> recoverable error inside Newton iteration. +C -1 ==> unrecoverable error inside Newton iteration. +C----------------------------------------------------------------------- +C +C***ROUTINES CALLED +C RES, DSLVK, DDWNRM +C +C***END PROLOGUE DNSK +C +C + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + DIMENSION Y(*),YPRIME(*),WT(*),DELTA(*),E(*),SAVR(*) + DIMENSION WM(*),IWM(*), RPAR(*),IPAR(*) + EXTERNAL RES, PSOL +C + PARAMETER (LNNI=19, LNRE=12) +C +C Initialize Newton counter M and accumulation vector E. +C + M = 0 + DO 100 I=1,NEQ +100 E(I) = 0.0D0 +C +C Corrector loop. +C +300 CONTINUE + IWM(LNNI) = IWM(LNNI) + 1 +C +C If necessary, multiply residual by convergence factor. +C + IF (MULDEL .EQ. 1) THEN + DO 320 I = 1,NEQ +320 DELTA(I) = DELTA(I) * CONFAC + ENDIF +C +C Save residual in SAVR. +C + DO 340 I = 1,NEQ +340 SAVR(I) = DELTA(I) +C +C Compute a new iterate. Store the correction in DELTA. +C + CALL DSLVK (NEQ, Y, X, YPRIME, SAVR, DELTA, WT, WM, IWM, + * RES, IRES, PSOL, IERSL, CJ, EPLIN, SQRTN, RSQRTN, RHOK, + * RPAR, IPAR) + IF (IRES .NE. 0 .OR. IERSL .NE. 0) GO TO 380 +C +C Update Y, E, and YPRIME. +C + DO 360 I=1,NEQ + Y(I) = Y(I) - DELTA(I) + E(I) = E(I) - DELTA(I) +360 YPRIME(I) = YPRIME(I) - CJ*DELTA(I) +C +C Test for convergence of the iteration. +C + DELNRM = DDWNRM(NEQ,DELTA,WT,RPAR,IPAR) + IF (M .EQ. 0) THEN + OLDNRM = DELNRM + IF (DELNRM .LE. TOLNEW) GO TO 370 + ELSE + RATE = (DELNRM/OLDNRM)**(1.0D0/M) + IF (RATE .GT. 0.9D0) GO TO 380 + S = RATE/(1.0D0 - RATE) + ENDIF + IF (S*DELNRM .LE. EPCON) GO TO 370 +C +C The corrector has not yet converged. Update M and test whether +C the maximum number of iterations have been tried. +C + M = M + 1 + IF (M .GE. MAXIT) GO TO 380 +C +C Evaluate the residual, and go back to do another iteration. +C + IWM(LNRE) = IWM(LNRE) + 1 + CALL RES(X,Y,YPRIME,CJ,DELTA,IRES,RPAR,IPAR) + IF (IRES .LT. 0) GO TO 380 + GO TO 300 +C +C The iteration has converged. +C +370 RETURN +C +C The iteration has not converged. Set IERNEW appropriately. +C +380 CONTINUE + IF (IRES .LE. -2 .OR. IERSL .LT. 0) THEN + IERNEW = -1 + ELSE + IERNEW = 1 + ENDIF + RETURN +C +C +C------END OF SUBROUTINE DNSK------------------------------------------- + END + SUBROUTINE DSLVK (NEQ, Y, TN, YPRIME, SAVR, X, EWT, WM, IWM, + * RES, IRES, PSOL, IERSL, CJ, EPLIN, SQRTN, RSQRTN, RHOK, + * RPAR, IPAR) +C +C***BEGIN PROLOGUE DSLVK +C***REFER TO DDASPK +C***DATE WRITTEN 890101 (YYMMDD) +C***REVISION DATE 900926 (YYMMDD) +C***REVISION DATE 940928 Removed MNEWT and added RHOK in call list. +C +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C DSLVK uses a restart algorithm and interfaces to DSPIGM for +C the solution of the linear system arising from a Newton iteration. +C +C In addition to variables described elsewhere, +C communication with DSLVK uses the following variables.. +C WM = Real work space containing data for the algorithm +C (Krylov basis vectors, Hessenberg matrix, etc.). +C IWM = Integer work space containing data for the algorithm. +C X = The right-hand side vector on input, and the solution vector +C on output, of length NEQ. +C IRES = Error flag from RES. +C IERSL = Output flag .. +C IERSL = 0 means no trouble occurred (or user RES routine +C returned IRES < 0) +C IERSL = 1 means the iterative method failed to converge +C (DSPIGM returned IFLAG > 0.) +C IERSL = -1 means there was a nonrecoverable error in the +C iterative solver, and an error exit will occur. +C----------------------------------------------------------------------- +C***ROUTINES CALLED +C DSCAL, DCOPY, DSPIGM +C +C***END PROLOGUE DSLVK +C + INTEGER NEQ, IWM, IRES, IERSL, IPAR + DOUBLE PRECISION Y, TN, YPRIME, SAVR, X, EWT, WM, CJ, EPLIN, + 1 SQRTN, RSQRTN, RHOK, RPAR + DIMENSION Y(*), YPRIME(*), SAVR(*), X(*), EWT(*), + 1 WM(*), IWM(*), RPAR(*), IPAR(*) +C + INTEGER IFLAG, IRST, NRSTS, NRMAX, LR, LDL, LHES, LGMR, LQ, LV, + 1 LWK, LZ, MAXLP1, NPSL + INTEGER NLI, NPS, NCFL, NRE, MAXL, KMP, MITER + EXTERNAL RES, PSOL +C + PARAMETER (LNRE=12, LNCFL=16, LNLI=20, LNPS=21) + PARAMETER (LLOCWP=29, LLCIWP=30) + PARAMETER (LMITER=23, LMAXL=24, LKMP=25, LNRMAX=26) +C +C----------------------------------------------------------------------- +C IRST is set to 1, to indicate restarting is in effect. +C NRMAX is the maximum number of restarts. +C----------------------------------------------------------------------- + DATA IRST/1/ +C + LIWP = IWM(LLCIWP) + NLI = IWM(LNLI) + NPS = IWM(LNPS) + NCFL = IWM(LNCFL) + NRE = IWM(LNRE) + LWP = IWM(LLOCWP) + MAXL = IWM(LMAXL) + KMP = IWM(LKMP) + NRMAX = IWM(LNRMAX) + MITER = IWM(LMITER) + IERSL = 0 + IRES = 0 +C----------------------------------------------------------------------- +C Use a restarting strategy to solve the linear system +C P*X = -F. Parse the work vector, and perform initializations. +C Note that zero is the initial guess for X. +C----------------------------------------------------------------------- + MAXLP1 = MAXL + 1 + LV = 1 + LR = LV + NEQ*MAXL + LHES = LR + NEQ + 1 + LQ = LHES + MAXL*MAXLP1 + LWK = LQ + 2*MAXL + LDL = LWK + MIN0(1,MAXL-KMP)*NEQ + LZ = LDL + NEQ + CALL DSCAL (NEQ, RSQRTN, EWT, 1) + CALL DCOPY (NEQ, X, 1, WM(LR), 1) + DO 110 I = 1,NEQ + 110 X(I) = 0.D0 +C----------------------------------------------------------------------- +C Top of loop for the restart algorithm. Initial pass approximates +C X and sets up a transformed system to perform subsequent restarts +C to update X. NRSTS is initialized to -1, because restarting +C does not occur until after the first pass. +C Update NRSTS; conditionally copy DL to R; call the DSPIGM +C algorithm to solve A*Z = R; updated counters; update X with +C the residual solution. +C Note: if convergence is not achieved after NRMAX restarts, +C then the linear solver is considered to have failed. +C----------------------------------------------------------------------- + NRSTS = -1 + 115 CONTINUE + NRSTS = NRSTS + 1 + IF (NRSTS .GT. 0) CALL DCOPY (NEQ, WM(LDL), 1, WM(LR),1) + CALL DSPIGM (NEQ, TN, Y, YPRIME, SAVR, WM(LR), EWT, MAXL, MAXLP1, + 1 KMP, EPLIN, CJ, RES, IRES, NRES, PSOL, NPSL, WM(LZ), WM(LV), + 2 WM(LHES), WM(LQ), LGMR, WM(LWP), IWM(LIWP), WM(LWK), + 3 WM(LDL), RHOK, IFLAG, IRST, NRSTS, RPAR, IPAR) + NLI = NLI + LGMR + NPS = NPS + NPSL + NRE = NRE + NRES + DO 120 I = 1,NEQ + 120 X(I) = X(I) + WM(LZ+I-1) + IF ((IFLAG .EQ. 1) .AND. (NRSTS .LT. NRMAX) .AND. (IRES .EQ. 0)) + 1 GO TO 115 +C----------------------------------------------------------------------- +C The restart scheme is finished. Test IRES and IFLAG to see if +C convergence was not achieved, and set flags accordingly. +C----------------------------------------------------------------------- + IF (IRES .LT. 0) THEN + NCFL = NCFL + 1 + ELSE IF (IFLAG .NE. 0) THEN + NCFL = NCFL + 1 + IF (IFLAG .GT. 0) IERSL = 1 + IF (IFLAG .LT. 0) IERSL = -1 + ENDIF +C----------------------------------------------------------------------- +C Update IWM with counters, rescale EWT, and return. +C----------------------------------------------------------------------- + IWM(LNLI) = NLI + IWM(LNPS) = NPS + IWM(LNCFL) = NCFL + IWM(LNRE) = NRE + CALL DSCAL (NEQ, SQRTN, EWT, 1) + RETURN +C +C------END OF SUBROUTINE DSLVK------------------------------------------ + END + SUBROUTINE DSPIGM (NEQ, TN, Y, YPRIME, SAVR, R, WGHT, MAXL, + * MAXLP1, KMP, EPLIN, CJ, RES, IRES, NRE, PSOL, NPSL, Z, V, + * HES, Q, LGMR, WP, IWP, WK, DL, RHOK, IFLAG, IRST, NRSTS, + * RPAR, IPAR) +C +C***BEGIN PROLOGUE DSPIGM +C***DATE WRITTEN 890101 (YYMMDD) +C***REVISION DATE 900926 (YYMMDD) +C***REVISION DATE 940927 Removed MNEWT and added RHOK in call list. +C +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C This routine solves the linear system A * Z = R using a scaled +C preconditioned version of the generalized minimum residual method. +C An initial guess of Z = 0 is assumed. +C +C On entry +C +C NEQ = Problem size, passed to PSOL. +C +C TN = Current Value of T. +C +C Y = Array Containing current dependent variable vector. +C +C YPRIME = Array Containing current first derivative of Y. +C +C SAVR = Array containing current value of G(T,Y,YPRIME). +C +C R = The right hand side of the system A*Z = R. +C R is also used as work space when computing +C the final approximation and will therefore be +C destroyed. +C (R is the same as V(*,MAXL+1) in the call to DSPIGM.) +C +C WGHT = The vector of length NEQ containing the nonzero +C elements of the diagonal scaling matrix. +C +C MAXL = The maximum allowable order of the matrix H. +C +C MAXLP1 = MAXL + 1, used for dynamic dimensioning of HES. +C +C KMP = The number of previous vectors the new vector, VNEW, +C must be made orthogonal to. (KMP .LE. MAXL.) +C +C EPLIN = Tolerance on residuals R-A*Z in weighted rms norm. +C +C CJ = Scalar proportional to current value of +C 1/(step size H). +C +C WK = Real work array used by routine DATV and PSOL. +C +C DL = Real work array used for calculation of the residual +C norm RHO when the method is incomplete (KMP.LT.MAXL) +C and/or when using restarting. +C +C WP = Real work array used by preconditioner PSOL. +C +C IWP = Integer work array used by preconditioner PSOL. +C +C IRST = Method flag indicating if restarting is being +C performed. IRST .GT. 0 means restarting is active, +C while IRST = 0 means restarting is not being used. +C +C NRSTS = Counter for the number of restarts on the current +C call to DSPIGM. If NRSTS .GT. 0, then the residual +C R is already scaled, and so scaling of R is not +C necessary. +C +C +C On Return +C +C Z = The final computed approximation to the solution +C of the system A*Z = R. +C +C LGMR = The number of iterations performed and +C the current order of the upper Hessenberg +C matrix HES. +C +C NRE = The number of calls to RES (i.e. DATV) +C +C NPSL = The number of calls to PSOL. +C +C V = The neq by (LGMR+1) array containing the LGMR +C orthogonal vectors V(*,1) to V(*,LGMR). +C +C HES = The upper triangular factor of the QR decomposition +C of the (LGMR+1) by LGMR upper Hessenberg matrix whose +C entries are the scaled inner-products of A*V(*,I) +C and V(*,K). +C +C Q = Real array of length 2*MAXL containing the components +C of the givens rotations used in the QR decomposition +C of HES. It is loaded in DHEQR and used in DHELS. +C +C IRES = Error flag from RES. +C +C DL = Scaled preconditioned residual, +C (D-inverse)*(P-inverse)*(R-A*Z). Only loaded when +C performing restarts of the Krylov iteration. +C +C RHOK = Weighted norm of final preconditioned residual. +C +C IFLAG = Integer error flag.. +C 0 Means convergence in LGMR iterations, LGMR.LE.MAXL. +C 1 Means the convergence test did not pass in MAXL +C iterations, but the new residual norm (RHO) is +C .LT. the old residual norm (RNRM), and so Z is +C computed. +C 2 Means the convergence test did not pass in MAXL +C iterations, new residual norm (RHO) .GE. old residual +C norm (RNRM), and the initial guess, Z = 0, is +C returned. +C 3 Means there was a recoverable error in PSOL +C caused by the preconditioner being out of date. +C -1 Means there was an unrecoverable error in PSOL. +C +C----------------------------------------------------------------------- +C***ROUTINES CALLED +C PSOL, DNRM2, DSCAL, DATV, DORTH, DHEQR, DCOPY, DHELS, DAXPY +C +C***END PROLOGUE DSPIGM +C + INTEGER NEQ,MAXL,MAXLP1,KMP,IRES,NRE,NPSL,LGMR,IWP, + 1 IFLAG,IRST,NRSTS,IPAR + DOUBLE PRECISION TN,Y,YPRIME,SAVR,R,WGHT,EPLIN,CJ,Z,V,HES,Q,WP,WK, + 1 DL,RHOK,RPAR + DIMENSION Y(*), YPRIME(*), SAVR(*), R(*), WGHT(*), Z(*), + 1 V(NEQ,*), HES(MAXLP1,*), Q(*), WP(*), IWP(*), WK(*), DL(*), + 2 RPAR(*), IPAR(*) + INTEGER I, IER, INFO, IP1, I2, J, K, LL, LLP1 + DOUBLE PRECISION RNRM,C,DLNRM,PROD,RHO,S,SNORMW,DNRM2,TEM + EXTERNAL RES, PSOL +C + IER = 0 + IFLAG = 0 + LGMR = 0 + NPSL = 0 + NRE = 0 +C----------------------------------------------------------------------- +C The initial guess for Z is 0. The initial residual is therefore +C the vector R. Initialize Z to 0. +C----------------------------------------------------------------------- + DO 10 I = 1,NEQ + 10 Z(I) = 0.0D0 +C----------------------------------------------------------------------- +C Apply inverse of left preconditioner to vector R if NRSTS .EQ. 0. +C Form V(*,1), the scaled preconditioned right hand side. +C----------------------------------------------------------------------- + IF (NRSTS .EQ. 0) THEN + CALL PSOL (NEQ, TN, Y, YPRIME, SAVR, WK, CJ, WGHT, WP, IWP, + 1 R, EPLIN, IER, RPAR, IPAR) + NPSL = 1 + IF (IER .NE. 0) GO TO 300 + DO 30 I = 1,NEQ + 30 V(I,1) = R(I)*WGHT(I) + ELSE + DO 35 I = 1,NEQ + 35 V(I,1) = R(I) + ENDIF +C----------------------------------------------------------------------- +C Calculate norm of scaled vector V(*,1) and normalize it +C If, however, the norm of V(*,1) (i.e. the norm of the preconditioned +C residual) is .le. EPLIN, then return with Z=0. +C----------------------------------------------------------------------- + RNRM = DNRM2 (NEQ, V, 1) + IF (RNRM .LE. EPLIN) THEN + RHOK = RNRM + RETURN + ENDIF + TEM = 1.0D0/RNRM + CALL DSCAL (NEQ, TEM, V(1,1), 1) +C----------------------------------------------------------------------- +C Zero out the HES array. +C----------------------------------------------------------------------- + DO 65 J = 1,MAXL + DO 60 I = 1,MAXLP1 + 60 HES(I,J) = 0.0D0 + 65 CONTINUE +C----------------------------------------------------------------------- +C Main loop to compute the vectors V(*,2) to V(*,MAXL). +C The running product PROD is needed for the convergence test. +C----------------------------------------------------------------------- + PROD = 1.0D0 + DO 90 LL = 1,MAXL + LGMR = LL +C----------------------------------------------------------------------- +C Call routine DATV to compute VNEW = ABAR*V(LL), where ABAR is +C the matrix A with scaling and inverse preconditioner factors applied. +C Call routine DORTH to orthogonalize the new vector VNEW = V(*,LL+1). +C call routine DHEQR to update the factors of HES. +C----------------------------------------------------------------------- + CALL DATV (NEQ, Y, TN, YPRIME, SAVR, V(1,LL), WGHT, Z, + 1 RES, IRES, PSOL, V(1,LL+1), WK, WP, IWP, CJ, EPLIN, + 1 IER, NRE, NPSL, RPAR, IPAR) + IF (IRES .LT. 0) RETURN + IF (IER .NE. 0) GO TO 300 + CALL DORTH (V(1,LL+1), V, HES, NEQ, LL, MAXLP1, KMP, SNORMW) + HES(LL+1,LL) = SNORMW + CALL DHEQR (HES, MAXLP1, LL, Q, INFO, LL) + IF (INFO .EQ. LL) GO TO 120 +C----------------------------------------------------------------------- +C Update RHO, the estimate of the norm of the residual R - A*ZL. +C If KMP .LT. MAXL, then the vectors V(*,1),...,V(*,LL+1) are not +C necessarily orthogonal for LL .GT. KMP. The vector DL must then +C be computed, and its norm used in the calculation of RHO. +C----------------------------------------------------------------------- + PROD = PROD*Q(2*LL) + RHO = ABS(PROD*RNRM) + IF ((LL.GT.KMP) .AND. (KMP.LT.MAXL)) THEN + IF (LL .EQ. KMP+1) THEN + CALL DCOPY (NEQ, V(1,1), 1, DL, 1) + DO 75 I = 1,KMP + IP1 = I + 1 + I2 = I*2 + S = Q(I2) + C = Q(I2-1) + DO 70 K = 1,NEQ + 70 DL(K) = S*DL(K) + C*V(K,IP1) + 75 CONTINUE + ENDIF + S = Q(2*LL) + C = Q(2*LL-1)/SNORMW + LLP1 = LL + 1 + DO 80 K = 1,NEQ + 80 DL(K) = S*DL(K) + C*V(K,LLP1) + DLNRM = DNRM2 (NEQ, DL, 1) + RHO = RHO*DLNRM + ENDIF +C----------------------------------------------------------------------- +C Test for convergence. If passed, compute approximation ZL. +C If failed and LL .LT. MAXL, then continue iterating. +C----------------------------------------------------------------------- + IF (RHO .LE. EPLIN) GO TO 200 + IF (LL .EQ. MAXL) GO TO 100 +C----------------------------------------------------------------------- +C Rescale so that the norm of V(1,LL+1) is one. +C----------------------------------------------------------------------- + TEM = 1.0D0/SNORMW + CALL DSCAL (NEQ, TEM, V(1,LL+1), 1) + 90 CONTINUE + 100 CONTINUE + IF (RHO .LT. RNRM) GO TO 150 + 120 CONTINUE + IFLAG = 2 + DO 130 I = 1,NEQ + 130 Z(I) = 0.D0 + RETURN + 150 IFLAG = 1 +C----------------------------------------------------------------------- +C The tolerance was not met, but the residual norm was reduced. +C If performing restarting (IRST .gt. 0) calculate the residual vector +C RL and store it in the DL array. If the incomplete version is +C being used (KMP .lt. MAXL) then DL has already been calculated. +C----------------------------------------------------------------------- + IF (IRST .GT. 0) THEN + IF (KMP .EQ. MAXL) THEN +C +C Calculate DL from the V(I)'s. +C + CALL DCOPY (NEQ, V(1,1), 1, DL, 1) + MAXLM1 = MAXL - 1 + DO 175 I = 1,MAXLM1 + IP1 = I + 1 + I2 = I*2 + S = Q(I2) + C = Q(I2-1) + DO 170 K = 1,NEQ + 170 DL(K) = S*DL(K) + C*V(K,IP1) + 175 CONTINUE + S = Q(2*MAXL) + C = Q(2*MAXL-1)/SNORMW + DO 180 K = 1,NEQ + 180 DL(K) = S*DL(K) + C*V(K,MAXLP1) + ENDIF +C +C Scale DL by RNRM*PROD to obtain the residual RL. +C + TEM = RNRM*PROD + CALL DSCAL(NEQ, TEM, DL, 1) + ENDIF +C----------------------------------------------------------------------- +C Compute the approximation ZL to the solution. +C Since the vector Z was used as work space, and the initial guess +C of the Newton correction is zero, Z must be reset to zero. +C----------------------------------------------------------------------- + 200 CONTINUE + LL = LGMR + LLP1 = LL + 1 + DO 210 K = 1,LLP1 + 210 R(K) = 0.0D0 + R(1) = RNRM + CALL DHELS (HES, MAXLP1, LL, Q, R) + DO 220 K = 1,NEQ + 220 Z(K) = 0.0D0 + DO 230 I = 1,LL + CALL DAXPY (NEQ, R(I), V(1,I), 1, Z, 1) + 230 CONTINUE + DO 240 I = 1,NEQ + 240 Z(I) = Z(I)/WGHT(I) +C Load RHO into RHOK. + RHOK = RHO + RETURN +C----------------------------------------------------------------------- +C This block handles error returns forced by routine PSOL. +C----------------------------------------------------------------------- + 300 CONTINUE + IF (IER .LT. 0) IFLAG = -1 + IF (IER .GT. 0) IFLAG = 3 +C + RETURN +C +C------END OF SUBROUTINE DSPIGM----------------------------------------- + END + SUBROUTINE DATV (NEQ, Y, TN, YPRIME, SAVR, V, WGHT, YPTEM, RES, + * IRES, PSOL, Z, VTEM, WP, IWP, CJ, EPLIN, IER, NRE, NPSL, + * RPAR,IPAR) +C +C***BEGIN PROLOGUE DATV +C***DATE WRITTEN 890101 (YYMMDD) +C***REVISION DATE 900926 (YYMMDD) +C +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C This routine computes the product +C +C Z = (D-inverse)*(P-inverse)*(dF/dY)*(D*V), +C +C where F(Y) = G(T, Y, CJ*(Y-A)), CJ is a scalar proportional to 1/H, +C and A involves the past history of Y. The quantity CJ*(Y-A) is +C an approximation to the first derivative of Y and is stored +C in the array YPRIME. Note that dF/dY = dG/dY + CJ*dG/dYPRIME. +C +C D is a diagonal scaling matrix, and P is the left preconditioning +C matrix. V is assumed to have L2 norm equal to 1. +C The product is stored in Z and is computed by means of a +C difference quotient, a call to RES, and one call to PSOL. +C +C On entry +C +C NEQ = Problem size, passed to RES and PSOL. +C +C Y = Array containing current dependent variable vector. +C +C YPRIME = Array containing current first derivative of y. +C +C SAVR = Array containing current value of G(T,Y,YPRIME). +C +C V = Real array of length NEQ (can be the same array as Z). +C +C WGHT = Array of length NEQ containing scale factors. +C 1/WGHT(I) are the diagonal elements of the matrix D. +C +C YPTEM = Work array of length NEQ. +C +C VTEM = Work array of length NEQ used to store the +C unscaled version of V. +C +C WP = Real work array used by preconditioner PSOL. +C +C IWP = Integer work array used by preconditioner PSOL. +C +C CJ = Scalar proportional to current value of +C 1/(step size H). +C +C +C On return +C +C Z = Array of length NEQ containing desired scaled +C matrix-vector product. +C +C IRES = Error flag from RES. +C +C IER = Error flag from PSOL. +C +C NRE = The number of calls to RES. +C +C NPSL = The number of calls to PSOL. +C +C----------------------------------------------------------------------- +C***ROUTINES CALLED +C RES, PSOL +C +C***END PROLOGUE DATV +C + INTEGER NEQ, IRES, IWP, IER, NRE, NPSL, IPAR + DOUBLE PRECISION Y, TN, YPRIME, SAVR, V, WGHT, YPTEM, Z, VTEM, + 1 WP, CJ, RPAR + DIMENSION Y(*), YPRIME(*), SAVR(*), V(*), WGHT(*), YPTEM(*), + 1 Z(*), VTEM(*), WP(*), IWP(*), RPAR(*), IPAR(*) + INTEGER I + DOUBLE PRECISION EPLIN + EXTERNAL RES, PSOL +C + IRES = 0 +C----------------------------------------------------------------------- +C Set VTEM = D * V. +C----------------------------------------------------------------------- + DO 10 I = 1,NEQ + 10 VTEM(I) = V(I)/WGHT(I) + IER = 0 +C----------------------------------------------------------------------- +C Store Y in Z and increment Z by VTEM. +C Store YPRIME in YPTEM and increment YPTEM by VTEM*CJ. +C----------------------------------------------------------------------- + DO 20 I = 1,NEQ + YPTEM(I) = YPRIME(I) + VTEM(I)*CJ + 20 Z(I) = Y(I) + VTEM(I) +C----------------------------------------------------------------------- +C Call RES with incremented Y, YPRIME arguments +C stored in Z, YPTEM. VTEM is overwritten with new residual. +C----------------------------------------------------------------------- + CONTINUE + CALL RES(TN,Z,YPTEM,CJ,VTEM,IRES,RPAR,IPAR) + NRE = NRE + 1 + IF (IRES .LT. 0) RETURN +C----------------------------------------------------------------------- +C Set Z = (dF/dY) * VBAR using difference quotient. +C (VBAR is old value of VTEM before calling RES) +C----------------------------------------------------------------------- + DO 70 I = 1,NEQ + 70 Z(I) = VTEM(I) - SAVR(I) +C----------------------------------------------------------------------- +C Apply inverse of left preconditioner to Z. +C----------------------------------------------------------------------- + CALL PSOL (NEQ, TN, Y, YPRIME, SAVR, YPTEM, CJ, WGHT, WP, IWP, + 1 Z, EPLIN, IER, RPAR, IPAR) + NPSL = NPSL + 1 + IF (IER .NE. 0) RETURN +C----------------------------------------------------------------------- +C Apply D-inverse to Z and return. +C----------------------------------------------------------------------- + DO 90 I = 1,NEQ + 90 Z(I) = Z(I)*WGHT(I) + RETURN +C +C------END OF SUBROUTINE DATV------------------------------------------- + END + SUBROUTINE DORTH (VNEW, V, HES, N, LL, LDHES, KMP, SNORMW) +C +C***BEGIN PROLOGUE DORTH +C***DATE WRITTEN 890101 (YYMMDD) +C***REVISION DATE 900926 (YYMMDD) +C +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C This routine orthogonalizes the vector VNEW against the previous +C KMP vectors in the V array. It uses a modified Gram-Schmidt +C orthogonalization procedure with conditional reorthogonalization. +C +C On entry +C +C VNEW = The vector of length N containing a scaled product +C OF The Jacobian and the vector V(*,LL). +C +C V = The N x LL array containing the previous LL +C orthogonal vectors V(*,1) to V(*,LL). +C +C HES = An LL x LL upper Hessenberg matrix containing, +C in HES(I,K), K.LT.LL, scaled inner products of +C A*V(*,K) and V(*,I). +C +C LDHES = The leading dimension of the HES array. +C +C N = The order of the matrix A, and the length of VNEW. +C +C LL = The current order of the matrix HES. +C +C KMP = The number of previous vectors the new vector VNEW +C must be made orthogonal to (KMP .LE. MAXL). +C +C +C On return +C +C VNEW = The new vector orthogonal to V(*,I0), +C where I0 = MAX(1, LL-KMP+1). +C +C HES = Upper Hessenberg matrix with column LL filled in with +C scaled inner products of A*V(*,LL) and V(*,I). +C +C SNORMW = L-2 norm of VNEW. +C +C----------------------------------------------------------------------- +C***ROUTINES CALLED +C DDOT, DNRM2, DAXPY +C +C***END PROLOGUE DORTH +C + INTEGER N, LL, LDHES, KMP + DOUBLE PRECISION VNEW, V, HES, SNORMW + DIMENSION VNEW(*), V(N,*), HES(LDHES,*) + INTEGER I, I0 + DOUBLE PRECISION ARG, DDOT, DNRM2, SUMDSQ, TEM, VNRM +C +C----------------------------------------------------------------------- +C Get norm of unaltered VNEW for later use. +C----------------------------------------------------------------------- + VNRM = DNRM2 (N, VNEW, 1) +C----------------------------------------------------------------------- +C Do Modified Gram-Schmidt on VNEW = A*V(LL). +C Scaled inner products give new column of HES. +C Projections of earlier vectors are subtracted from VNEW. +C----------------------------------------------------------------------- + I0 = MAX0(1,LL-KMP+1) + DO 10 I = I0,LL + HES(I,LL) = DDOT (N, V(1,I), 1, VNEW, 1) + TEM = -HES(I,LL) + CALL DAXPY (N, TEM, V(1,I), 1, VNEW, 1) + 10 CONTINUE +C----------------------------------------------------------------------- +C Compute SNORMW = norm of VNEW. +C If VNEW is small compared to its input value (in norm), then +C Reorthogonalize VNEW to V(*,1) through V(*,LL). +C Correct if relative correction exceeds 1000*(unit roundoff). +C Finally, correct SNORMW using the dot products involved. +C----------------------------------------------------------------------- + SNORMW = DNRM2 (N, VNEW, 1) + IF (VNRM + 0.001D0*SNORMW .NE. VNRM) RETURN + SUMDSQ = 0.0D0 + DO 30 I = I0,LL + TEM = -DDOT (N, V(1,I), 1, VNEW, 1) + IF (HES(I,LL) + 0.001D0*TEM .EQ. HES(I,LL)) GO TO 30 + HES(I,LL) = HES(I,LL) - TEM + CALL DAXPY (N, TEM, V(1,I), 1, VNEW, 1) + SUMDSQ = SUMDSQ + TEM**2 + 30 CONTINUE + IF (SUMDSQ .EQ. 0.0D0) RETURN + ARG = MAX(0.0D0,SNORMW**2 - SUMDSQ) + SNORMW = SQRT(ARG) + RETURN +C +C------END OF SUBROUTINE DORTH------------------------------------------ + END + SUBROUTINE DHEQR (A, LDA, N, Q, INFO, IJOB) +C +C***BEGIN PROLOGUE DHEQR +C***DATE WRITTEN 890101 (YYMMDD) +C***REVISION DATE 900926 (YYMMDD) +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C This routine performs a QR decomposition of an upper +C Hessenberg matrix A. There are two options available: +C +C (1) performing a fresh decomposition +C (2) updating the QR factors by adding a row and A +C column to the matrix A. +C +C DHEQR decomposes an upper Hessenberg matrix by using Givens +C rotations. +C +C On entry +C +C A DOUBLE PRECISION(LDA, N) +C The matrix to be decomposed. +C +C LDA INTEGER +C The leading dimension of the array A. +C +C N INTEGER +C A is an (N+1) by N Hessenberg matrix. +C +C IJOB INTEGER +C = 1 Means that a fresh decomposition of the +C matrix A is desired. +C .GE. 2 Means that the current decomposition of A +C will be updated by the addition of a row +C and a column. +C On return +C +C A The upper triangular matrix R. +C The factorization can be written Q*A = R, where +C Q is a product of Givens rotations and R is upper +C triangular. +C +C Q DOUBLE PRECISION(2*N) +C The factors C and S of each Givens rotation used +C in decomposing A. +C +C INFO INTEGER +C = 0 normal value. +C = K If A(K,K) .EQ. 0.0. This is not an error +C condition for this subroutine, but it does +C indicate that DHELS will divide by zero +C if called. +C +C Modification of LINPACK. +C Peter Brown, Lawrence Livermore Natl. Lab. +C +C----------------------------------------------------------------------- +C***ROUTINES CALLED (NONE) +C +C***END PROLOGUE DHEQR +C + INTEGER LDA, N, INFO, IJOB + DOUBLE PRECISION A(LDA,*), Q(*) + INTEGER I, IQ, J, K, KM1, KP1, NM1 + DOUBLE PRECISION C, S, T, T1, T2 +C + IF (IJOB .GT. 1) GO TO 70 +C----------------------------------------------------------------------- +C A new factorization is desired. +C----------------------------------------------------------------------- +C +C QR decomposition without pivoting. +C + INFO = 0 + DO 60 K = 1, N + KM1 = K - 1 + KP1 = K + 1 +C +C Compute Kth column of R. +C First, multiply the Kth column of A by the previous +C K-1 Givens rotations. +C + IF (KM1 .LT. 1) GO TO 20 + DO 10 J = 1, KM1 + I = 2*(J-1) + 1 + T1 = A(J,K) + T2 = A(J+1,K) + C = Q(I) + S = Q(I+1) + A(J,K) = C*T1 - S*T2 + A(J+1,K) = S*T1 + C*T2 + 10 CONTINUE +C +C Compute Givens components C and S. +C + 20 CONTINUE + IQ = 2*KM1 + 1 + T1 = A(K,K) + T2 = A(KP1,K) + IF (T2 .NE. 0.0D0) GO TO 30 + C = 1.0D0 + S = 0.0D0 + GO TO 50 + 30 CONTINUE + IF (ABS(T2) .LT. ABS(T1)) GO TO 40 + T = T1/T2 + S = -1.0D0/SQRT(1.0D0+T*T) + C = -S*T + GO TO 50 + 40 CONTINUE + T = T2/T1 + C = 1.0D0/SQRT(1.0D0+T*T) + S = -C*T + 50 CONTINUE + Q(IQ) = C + Q(IQ+1) = S + A(K,K) = C*T1 - S*T2 + IF (A(K,K) .EQ. 0.0D0) INFO = K + 60 CONTINUE + RETURN +C----------------------------------------------------------------------- +C The old factorization of A will be updated. A row and a column +C has been added to the matrix A. +C N by N-1 is now the old size of the matrix. +C----------------------------------------------------------------------- + 70 CONTINUE + NM1 = N - 1 +C----------------------------------------------------------------------- +C Multiply the new column by the N previous Givens rotations. +C----------------------------------------------------------------------- + DO 100 K = 1,NM1 + I = 2*(K-1) + 1 + T1 = A(K,N) + T2 = A(K+1,N) + C = Q(I) + S = Q(I+1) + A(K,N) = C*T1 - S*T2 + A(K+1,N) = S*T1 + C*T2 + 100 CONTINUE +C----------------------------------------------------------------------- +C Complete update of decomposition by forming last Givens rotation, +C and multiplying it times the column vector (A(N,N),A(NP1,N)). +C----------------------------------------------------------------------- + INFO = 0 + T1 = A(N,N) + T2 = A(N+1,N) + IF (T2 .NE. 0.0D0) GO TO 110 + C = 1.0D0 + S = 0.0D0 + GO TO 130 + 110 CONTINUE + IF (ABS(T2) .LT. ABS(T1)) GO TO 120 + T = T1/T2 + S = -1.0D0/SQRT(1.0D0+T*T) + C = -S*T + GO TO 130 + 120 CONTINUE + T = T2/T1 + C = 1.0D0/SQRT(1.0D0+T*T) + S = -C*T + 130 CONTINUE + IQ = 2*N - 1 + Q(IQ) = C + Q(IQ+1) = S + A(N,N) = C*T1 - S*T2 + IF (A(N,N) .EQ. 0.0D0) INFO = N + RETURN +C +C------END OF SUBROUTINE DHEQR------------------------------------------ + END + SUBROUTINE DHELS (A, LDA, N, Q, B) +C +C***BEGIN PROLOGUE DHELS +C***DATE WRITTEN 890101 (YYMMDD) +C***REVISION DATE 900926 (YYMMDD) +C +C +C----------------------------------------------------------------------- +C***DESCRIPTION +C +C This is similar to the LINPACK routine DGESL except that +C A is an upper Hessenberg matrix. +C +C DHELS solves the least squares problem +C +C MIN (B-A*X,B-A*X) +C +C using the factors computed by DHEQR. +C +C On entry +C +C A DOUBLE PRECISION (LDA, N) +C The output from DHEQR which contains the upper +C triangular factor R in the QR decomposition of A. +C +C LDA INTEGER +C The leading dimension of the array A . +C +C N INTEGER +C A is originally an (N+1) by N matrix. +C +C Q DOUBLE PRECISION(2*N) +C The coefficients of the N givens rotations +C used in the QR factorization of A. +C +C B DOUBLE PRECISION(N+1) +C The right hand side vector. +C +C +C On return +C +C B The solution vector X. +C +C +C Modification of LINPACK. +C Peter Brown, Lawrence Livermore Natl. Lab. +C +C----------------------------------------------------------------------- +C***ROUTINES CALLED +C DAXPY +C +C***END PROLOGUE DHELS +C + INTEGER LDA, N + DOUBLE PRECISION A(LDA,*), B(*), Q(*) + INTEGER IQ, K, KB, KP1 + DOUBLE PRECISION C, S, T, T1, T2 +C +C Minimize (B-A*X,B-A*X). +C First form Q*B. +C + DO 20 K = 1, N + KP1 = K + 1 + IQ = 2*(K-1) + 1 + C = Q(IQ) + S = Q(IQ+1) + T1 = B(K) + T2 = B(KP1) + B(K) = C*T1 - S*T2 + B(KP1) = S*T1 + C*T2 + 20 CONTINUE +C +C Now solve R*X = Q*B. +C + DO 40 KB = 1, N + K = N + 1 - KB + B(K) = B(K)/A(K,K) + T = -B(K) + CALL DAXPY (K-1, T, A(1,K), 1, B(1), 1) + 40 CONTINUE + RETURN +C +C------END OF SUBROUTINE DHELS------------------------------------------ + END diff --git a/ext/math/dgbefa.f b/ext/math/dgbefa.f new file mode 100644 index 000000000..c26e6f579 --- /dev/null +++ b/ext/math/dgbefa.f @@ -0,0 +1,174 @@ + subroutine dgbfa(abd,lda,n,ml,mu,ipvt,info) + integer lda,n,ml,mu,ipvt(1),info + double precision abd(lda,1) +c +c dgbfa factors a double precision band matrix by elimination. +c +c dgbfa is usually called by dgbco, but it can be called +c directly with a saving in time if rcond is not needed. +c +c on entry +c +c abd double precision(lda, n) +c contains the matrix in band storage. the columns +c of the matrix are stored in the columns of abd and +c the diagonals of the matrix are stored in rows +c ml+1 through 2*ml+mu+1 of abd . +c see the comments below for details. +c +c lda integer +c the leading dimension of the array abd . +c lda must be .ge. 2*ml + mu + 1 . +c +c n integer +c the order of the original matrix. +c +c ml integer +c number of diagonals below the main diagonal. +c 0 .le. ml .lt. n . +c +c mu integer +c number of diagonals above the main diagonal. +c 0 .le. mu .lt. n . +c more efficient if ml .le. mu . +c on return +c +c abd an upper triangular matrix in band storage and +c the multipliers which were used to obtain it. +c the factorization can be written a = l*u where +c l is a product of permutation and unit lower +c triangular matrices and u is upper triangular. +c +c ipvt integer(n) +c an integer vector of pivot indices. +c +c info integer +c = 0 normal value. +c = k if u(k,k) .eq. 0.0 . this is not an error +c condition for this subroutine, but it does +c indicate that dgbsl will divide by zero if +c called. use rcond in dgbco for a reliable +c indication of singularity. +c +c band storage +c +c if a is a band matrix, the following program segment +c will set up the input. +c +c ml = (band width below the diagonal) +c mu = (band width above the diagonal) +c m = ml + mu + 1 +c do 20 j = 1, n +c i1 = max0(1, j-mu) +c i2 = min0(n, j+ml) +c do 10 i = i1, i2 +c k = i - j + m +c abd(k,j) = a(i,j) +c 10 continue +c 20 continue +c +c this uses rows ml+1 through 2*ml+mu+1 of abd . +c in addition, the first ml rows in abd are used for +c elements generated during the triangularization. +c the total number of rows needed in abd is 2*ml+mu+1 . +c the ml+mu by ml+mu upper left triangle and the +c ml by ml lower right triangle are not referenced. +c +c linpack. this version dated 08/14/78 . +c cleve moler, university of new mexico, argonne national lab. +c +c subroutines and functions +c +c blas daxpy,dscal,idamax +c fortran max0,min0 +c +c internal variables +c + double precision t + integer i,idamax,i0,j,ju,jz,j0,j1,k,kp1,l,lm,m,mm,nm1 +c +c + m = ml + mu + 1 + info = 0 +c +c zero initial fill-in columns +c + j0 = mu + 2 + j1 = min0(n,m) - 1 + if (j1 .lt. j0) go to 30 + do 20 jz = j0, j1 + i0 = m + 1 - jz + do 10 i = i0, ml + abd(i,jz) = 0.0d0 + 10 continue + 20 continue + 30 continue + jz = j1 + ju = 0 +c +c gaussian elimination with partial pivoting +c + nm1 = n - 1 + if (nm1 .lt. 1) go to 130 + do 120 k = 1, nm1 + kp1 = k + 1 +c +c zero next fill-in column +c + jz = jz + 1 + if (jz .gt. n) go to 50 + if (ml .lt. 1) go to 50 + do 40 i = 1, ml + abd(i,jz) = 0.0d0 + 40 continue + 50 continue +c +c find l = pivot index +c + lm = min0(ml,n-k) + l = idamax(lm+1,abd(m,k),1) + m - 1 + ipvt(k) = l + k - m +c +c zero pivot implies this column already triangularized +c + if (abd(l,k) .eq. 0.0d0) go to 100 +c +c interchange if necessary +c + if (l .eq. m) go to 60 + t = abd(l,k) + abd(l,k) = abd(m,k) + abd(m,k) = t + 60 continue +c +c compute multipliers +c + t = -1.0d0/abd(m,k) + call dscal(lm,t,abd(m+1,k),1) +c +c row elimination with column indexing +c + ju = min0(max0(ju,mu+ipvt(k)),n) + mm = m + if (ju .lt. kp1) go to 90 + do 80 j = kp1, ju + l = l - 1 + mm = mm - 1 + t = abd(l,j) + if (l .eq. mm) go to 70 + abd(l,j) = abd(mm,j) + abd(mm,j) = t + 70 continue + call daxpy(lm,t,abd(m+1,k),1,abd(mm+1,j),1) + 80 continue + 90 continue + go to 110 + 100 continue + info = k + 110 continue + 120 continue + 130 continue + ipvt(n) = n + if (abd(m,n) .eq. 0.0d0) info = n + return + end diff --git a/ext/math/dgbsl.f b/ext/math/dgbsl.f new file mode 100644 index 000000000..1b1b6ed54 --- /dev/null +++ b/ext/math/dgbsl.f @@ -0,0 +1,135 @@ + subroutine dgbsl(abd,lda,n,ml,mu,ipvt,b,job) + integer lda,n,ml,mu,ipvt(1),job + double precision abd(lda,1),b(1) +c +c dgbsl solves the double precision band system +c a * x = b or trans(a) * x = b +c using the factors computed by dgbco or dgbfa. +c +c on entry +c +c abd double precision(lda, n) +c the output from dgbco or dgbfa. +c +c lda integer +c the leading dimension of the array abd . +c +c n integer +c the order of the original matrix. +c +c ml integer +c number of diagonals below the main diagonal. +c +c mu integer +c number of diagonals above the main diagonal. +c +c ipvt integer(n) +c the pivot vector from dgbco or dgbfa. +c +c b double precision(n) +c the right hand side vector. +c +c job integer +c = 0 to solve a*x = b , +c = nonzero to solve trans(a)*x = b , where +c trans(a) is the transpose. +c +c on return +c +c b the solution vector x . +c +c error condition +c +c a division by zero will occur if the input factor contains a +c zero on the diagonal. technically this indicates singularity +c but it is often caused by improper arguments or improper +c setting of lda . it will not occur if the subroutines are +c called correctly and if dgbco has set rcond .gt. 0.0 +c or dgbfa has set info .eq. 0 . +c +c to compute inverse(a) * c where c is a matrix +c with p columns +c call dgbco(abd,lda,n,ml,mu,ipvt,rcond,z) +c if (rcond is too small) go to ... +c do 10 j = 1, p +c call dgbsl(abd,lda,n,ml,mu,ipvt,c(1,j),0) +c 10 continue +c +c linpack. this version dated 08/14/78 . +c cleve moler, university of new mexico, argonne national lab. +c +c subroutines and functions +c +c blas daxpy,ddot +c fortran min0 +c +c internal variables +c + double precision ddot,t + integer k,kb,l,la,lb,lm,m,nm1 +c + m = mu + ml + 1 + nm1 = n - 1 + if (job .ne. 0) go to 50 +c +c job = 0 , solve a * x = b +c first solve l*y = b +c + if (ml .eq. 0) go to 30 + if (nm1 .lt. 1) go to 30 + do 20 k = 1, nm1 + lm = min0(ml,n-k) + l = ipvt(k) + t = b(l) + if (l .eq. k) go to 10 + b(l) = b(k) + b(k) = t + 10 continue + call daxpy(lm,t,abd(m+1,k),1,b(k+1),1) + 20 continue + 30 continue +c +c now solve u*x = y +c + do 40 kb = 1, n + k = n + 1 - kb + b(k) = b(k)/abd(m,k) + lm = min0(k,m) - 1 + la = m - lm + lb = k - lm + t = -b(k) + call daxpy(lm,t,abd(la,k),1,b(lb),1) + 40 continue + go to 100 + 50 continue +c +c job = nonzero, solve trans(a) * x = b +c first solve trans(u)*y = b +c + do 60 k = 1, n + lm = min0(k,m) - 1 + la = m - lm + lb = k - lm + t = ddot(lm,abd(la,k),1,b(lb),1) + b(k) = (b(k) - t)/abd(m,k) + 60 continue +c +c now solve trans(l)*x = y +c + if (ml .eq. 0) go to 90 + if (nm1 .lt. 1) go to 90 + do 80 kb = 1, nm1 + k = n - kb + lm = min0(ml,n-k) + b(k) = b(k) + ddot(lm,abd(m+1,k),1,b(k+1),1) + l = ipvt(k) + if (l .eq. k) go to 70 + t = b(l) + b(l) = b(k) + b(k) = t + 70 continue + 80 continue + 90 continue + 100 continue + return + end diff --git a/ext/math/dgefa.f b/ext/math/dgefa.f new file mode 100644 index 000000000..14f266a9c --- /dev/null +++ b/ext/math/dgefa.f @@ -0,0 +1,104 @@ + + subroutine dgefa(a,lda,n,ipvt,info) + integer lda,n,ipvt(1),info + double precision a(lda,1) +c +c dgefa factors a double precision matrix by gaussian elimination. +c +c dgefa is usually called by dgeco, but it can be called +c directly with a saving in time if rcond is not needed. +c (time for dgeco) = (1 + 9/n)*(time for dgefa) . +c +c on entry +c +c a double precision(lda, n) +c the matrix to be factored. +c +c lda integer +c the leading dimension of the array a . +c +c n integer +c the order of the matrix a . +c +c on return +c +c a an upper triangular matrix and the multipliers +c which were used to obtain it. +c the factorization can be written a = l*u where +c l is a product of permutation and unit lower +c triangular matrices and u is upper triangular. +c +c ipvt integer(n) +c an integer vector of pivot indices. +c +c info integer +c = 0 normal value. +c = k if u(k,k) .eq. 0.0 . this is not an error +c condition for this subroutine, but it does +c indicate that dgesl or dgedi will divide by zero +c if called. use rcond in dgeco for a reliable +c indication of singularity. +c +c linpack. this version dated 08/14/78 . +c cleve moler, university of new mexico, argonne national lab. +c +c subroutines and functions +c +c blas daxpy,dscal,idamax +c +c internal variables +c + double precision t + integer idamax,j,k,kp1,l,nm1 +c +c +c gaussian elimination with partial pivoting +c + info = 0 + nm1 = n - 1 + if (nm1 .lt. 1) go to 70 + do 60 k = 1, nm1 + kp1 = k + 1 +c +c find l = pivot index +c + l = idamax(n-k+1,a(k,k),1) + k - 1 + ipvt(k) = l +c +c zero pivot implies this column already triangularized +c + if (a(l,k) .eq. 0.0d0) go to 40 +c +c interchange if necessary +c + if (l .eq. k) go to 10 + t = a(l,k) + a(l,k) = a(k,k) + a(k,k) = t + 10 continue +c +c compute multipliers +c + t = -1.0d0/a(k,k) + call dscal(n-k,t,a(k+1,k),1) +c +c row elimination with column indexing +c + do 30 j = kp1, n + t = a(l,j) + if (l .eq. k) go to 20 + a(l,j) = a(k,j) + a(k,j) = t + 20 continue + call daxpy(n-k,t,a(k+1,k),1,a(k+1,j),1) + 30 continue + go to 50 + 40 continue + info = k + 50 continue + 60 continue + 70 continue + ipvt(n) = n + if (a(n,n) .eq. 0.0d0) info = n + return + end diff --git a/ext/math/dgesl.f b/ext/math/dgesl.f new file mode 100644 index 000000000..093fa5182 --- /dev/null +++ b/ext/math/dgesl.f @@ -0,0 +1,117 @@ + subroutine dgesl(a,lda,n,ipvt,b,job) + integer lda,n,ipvt(1),job + double precision a(lda,1),b(1) +c +c dgesl solves the double precision system +c a * x = b or trans(a) * x = b +c using the factors computed by dgeco or dgefa. +c +c on entry +c +c a double precision(lda, n) +c the output from dgeco or dgefa. +c +c lda integer +c the leading dimension of the array a . +c +c n integer +c the order of the matrix a . +c +c ipvt integer(n) +c the pivot vector from dgeco or dgefa. +c +c b double precision(n) +c the right hand side vector. +c +c job integer +c = 0 to solve a*x = b , +c = nonzero to solve trans(a)*x = b where +c trans(a) is the transpose. +c +c on return +c +c b the solution vector x . +c +c error condition +c +c a division by zero will occur if the input factor contains a +c zero on the diagonal. technically this indicates singularity +c but it is often caused by improper arguments or improper +c setting of lda . it will not occur if the subroutines are +c called correctly and if dgeco has set rcond .gt. 0.0 +c or dgefa has set info .eq. 0 . +c +c to compute inverse(a) * c where c is a matrix +c with p columns +c call dgeco(a,lda,n,ipvt,rcond,z) +c if (rcond is too small) go to ... +c do 10 j = 1, p +c call dgesl(a,lda,n,ipvt,c(1,j),0) +c 10 continue +c +c linpack. this version dated 08/14/78 . +c cleve moler, university of new mexico, argonne national lab. +c +c subroutines and functions +c +c blas daxpy,ddot +c +c internal variables +c + double precision ddot,t + integer k,kb,l,nm1 +c + nm1 = n - 1 + if (job .ne. 0) go to 50 +c +c job = 0 , solve a * x = b +c first solve l*y = b +c + if (nm1 .lt. 1) go to 30 + do 20 k = 1, nm1 + l = ipvt(k) + t = b(l) + if (l .eq. k) go to 10 + b(l) = b(k) + b(k) = t + 10 continue + call daxpy(n-k,t,a(k+1,k),1,b(k+1),1) + 20 continue + 30 continue +c +c now solve u*x = y +c + do 40 kb = 1, n + k = n + 1 - kb + b(k) = b(k)/a(k,k) + t = -b(k) + call daxpy(k-1,t,a(1,k),1,b(1),1) + 40 continue + go to 100 + 50 continue +c +c job = nonzero, solve trans(a) * x = b +c first solve trans(u)*y = b +c + do 60 k = 1, n + t = ddot(k-1,a(1,k),1,b(1),1) + b(k) = (b(k) - t)/a(k,k) + 60 continue +c +c now solve trans(l)*x = y +c + if (nm1 .lt. 1) go to 90 + do 80 kb = 1, nm1 + k = n - kb + b(k) = b(k) + ddot(n-k,a(k+1,k),1,b(k+1),1) + l = ipvt(k) + if (l .eq. k) go to 70 + t = b(l) + b(l) = b(k) + b(k) = t + 70 continue + 80 continue + 90 continue + 100 continue + return + end diff --git a/ext/math/dp1vlu.f b/ext/math/dp1vlu.f new file mode 100644 index 000000000..1af92d209 --- /dev/null +++ b/ext/math/dp1vlu.f @@ -0,0 +1,151 @@ +*DECK DP1VLU + SUBROUTINE DP1VLU (L, NDER, X, YFIT, YP, A) +C***BEGIN PROLOGUE DP1VLU +C***PURPOSE Use the coefficients generated by DPOLFT to evaluate the +C polynomial fit of degree L, along with the first NDER of +C its derivatives, at a specified point. +C***LIBRARY SLATEC +C***CATEGORY K6 +C***TYPE DOUBLE PRECISION (PVALUE-S, DP1VLU-D) +C***KEYWORDS CURVE FITTING, LEAST SQUARES, POLYNOMIAL APPROXIMATION +C***AUTHOR Shampine, L. F., (SNLA) +C Davenport, S. M., (SNLA) +C***DESCRIPTION +C +C Abstract +C +C The subroutine DP1VLU uses the coefficients generated by DPOLFT +C to evaluate the polynomial fit of degree L , along with the first +C NDER of its derivatives, at a specified point. Computationally +C stable recurrence relations are used to perform this task. +C +C The parameters for DP1VLU are +C +C Input -- ALL TYPE REAL variables are DOUBLE PRECISION +C L - the degree of polynomial to be evaluated. L may be +C any non-negative integer which is less than or equal +C to NDEG , the highest degree polynomial provided +C by DPOLFT . +C NDER - the number of derivatives to be evaluated. NDER +C may be 0 or any positive value. If NDER is less +C than 0, it will be treated as 0. +C X - the argument at which the polynomial and its +C derivatives are to be evaluated. +C A - work and output array containing values from last +C call to DPOLFT . +C +C Output -- ALL TYPE REAL variables are DOUBLE PRECISION +C YFIT - value of the fitting polynomial of degree L at X +C YP - array containing the first through NDER derivatives +C of the polynomial of degree L . YP must be +C dimensioned at least NDER in the calling program. +C +C***REFERENCES L. F. Shampine, S. M. Davenport and R. E. Huddleston, +C Curve fitting by polynomials in one variable, Report +C SLA-74-0270, Sandia Laboratories, June 1974. +C***ROUTINES CALLED XERMSG +C***REVISION HISTORY (YYMMDD) +C 740601 DATE WRITTEN +C 890531 Changed all specific intrinsics to generic. (WRB) +C 890911 Removed unnecessary intrinsics. (WRB) +C 891006 Cosmetic changes to prologue. (WRB) +C 891006 REVISION DATE from Version 3.2 +C 891214 Prologue converted to Version 4.0 format. (BAB) +C 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ) +C 900510 Convert XERRWV calls to XERMSG calls. (RWC) +C 920501 Reformatted the REFERENCES section. (WRB) +C***END PROLOGUE DP1VLU + IMPLICIT DOUBLE PRECISION (A-H,O-Z) + INTEGER I,IC,ILO,IN,INP1,IUP,K1,K1I,K2,K3,K3P1,K3PN,K4,K4P1,K4PN, + * KC,L,LM1,LP1,MAXORD,N,NDER,NDO,NDP1,NORD + DOUBLE PRECISION A(*),CC,DIF,VAL,X,YFIT,YP(*) + CHARACTER*8 XERN1, XERN2 +C***FIRST EXECUTABLE STATEMENT DP1VLU + IF (L .LT. 0) GO TO 12 + NDO = MAX(NDER,0) + NDO = MIN(NDO,L) + MAXORD = A(1) + 0.5D0 + K1 = MAXORD + 1 + K2 = K1 + MAXORD + K3 = K2 + MAXORD + 2 + NORD = A(K3) + 0.5D0 + IF (L .GT. NORD) GO TO 11 + K4 = K3 + L + 1 + IF (NDER .LT. 1) GO TO 2 + DO 1 I = 1,NDER + 1 YP(I) = 0.0D0 + 2 IF (L .GE. 2) GO TO 4 + IF (L .EQ. 1) GO TO 3 +C +C L IS 0 +C + VAL = A(K2+1) + GO TO 10 +C +C L IS 1 +C + 3 CC = A(K2+2) + VAL = A(K2+1) + (X-A(2))*CC + IF (NDER .GE. 1) YP(1) = CC + GO TO 10 +C +C L IS GREATER THAN 1 +C + 4 NDP1 = NDO + 1 + K3P1 = K3 + 1 + K4P1 = K4 + 1 + LP1 = L + 1 + LM1 = L - 1 + ILO = K3 + 3 + IUP = K4 + NDP1 + DO 5 I = ILO,IUP + 5 A(I) = 0.0D0 + DIF = X - A(LP1) + KC = K2 + LP1 + A(K4P1) = A(KC) + A(K3P1) = A(KC-1) + DIF*A(K4P1) + A(K3+2) = A(K4P1) +C +C EVALUATE RECURRENCE RELATIONS FOR FUNCTION VALUE AND DERIVATIVES +C + DO 9 I = 1,LM1 + IN = L - I + INP1 = IN + 1 + K1I = K1 + INP1 + IC = K2 + IN + DIF = X - A(INP1) + VAL = A(IC) + DIF*A(K3P1) - A(K1I)*A(K4P1) + IF (NDO .LE. 0) GO TO 8 + DO 6 N = 1,NDO + K3PN = K3P1 + N + K4PN = K4P1 + N + 6 YP(N) = DIF*A(K3PN) + N*A(K3PN-1) - A(K1I)*A(K4PN) +C +C SAVE VALUES NEEDED FOR NEXT EVALUATION OF RECURRENCE RELATIONS +C + DO 7 N = 1,NDO + K3PN = K3P1 + N + K4PN = K4P1 + N + A(K4PN) = A(K3PN) + 7 A(K3PN) = YP(N) + 8 A(K4P1) = A(K3P1) + 9 A(K3P1) = VAL +C +C NORMAL RETURN OR ABORT DUE TO ERROR +C + 10 YFIT = VAL + RETURN +C + 11 WRITE (XERN1, '(I8)') L + WRITE (XERN2, '(I8)') NORD + CALL XERMSG ('SLATEC', 'DP1VLU', + * 'THE ORDER OF POLYNOMIAL EVALUATION, L = ' // XERN1 // + * ' REQUESTED EXCEEDS THE HIGHEST ORDER FIT, NORD = ' // XERN2 // + * ', COMPUTED BY DPOLFT -- EXECUTION TERMINATED.', 8, 2) + RETURN +C + 12 CALL XERMSG ('SLATEC', 'DP1VLU', + + 'INVALID INPUT PARAMETER. ORDER OF POLYNOMIAL EVALUATION ' // + + 'REQUESTED IS NEGATIVE.', 2, 2) + RETURN + END diff --git a/ext/math/dpcoef.f b/ext/math/dpcoef.f new file mode 100644 index 000000000..074a3426f --- /dev/null +++ b/ext/math/dpcoef.f @@ -0,0 +1,78 @@ +*DECK DPCOEF + SUBROUTINE DPCOEF (L, C, TC, A) +C***BEGIN PROLOGUE DPCOEF +C***PURPOSE Convert the DPOLFT coefficients to Taylor series form. +C***LIBRARY SLATEC +C***CATEGORY K1A1A2 +C***TYPE DOUBLE PRECISION (PCOEF-S, DPCOEF-D) +C***KEYWORDS CURVE FITTING, DATA FITTING, LEAST SQUARES, POLYNOMIAL FIT +C***AUTHOR Shampine, L. F., (SNLA) +C Davenport, S. M., (SNLA) +C***DESCRIPTION +C +C Abstract +C +C DPOLFT computes the least squares polynomial fit of degree L as +C a sum of orthogonal polynomials. DPCOEF changes this fit to its +C Taylor expansion about any point C , i.e. writes the polynomial +C as a sum of powers of (X-C). Taking C=0. gives the polynomial +C in powers of X, but a suitable non-zero C often leads to +C polynomials which are better scaled and more accurately evaluated. +C +C The parameters for DPCOEF are +C +C INPUT -- All TYPE REAL variables are DOUBLE PRECISION +C L - Indicates the degree of polynomial to be changed to +C its Taylor expansion. To obtain the Taylor +C coefficients in reverse order, input L as the +C negative of the degree desired. The absolute value +C of L must be less than or equal to NDEG, the highest +C degree polynomial fitted by DPOLFT . +C C - The point about which the Taylor expansion is to be +C made. +C A - Work and output array containing values from last +C call to DPOLFT . +C +C OUTPUT -- All TYPE REAL variables are DOUBLE PRECISION +C TC - Vector containing the first LL+1 Taylor coefficients +C where LL=ABS(L). If L.GT.0 , the coefficients are +C in the usual Taylor series order, i.e. +C P(X) = TC(1) + TC(2)*(X-C) + ... + TC(N+1)*(X-C)**N +C If L .LT. 0, the coefficients are in reverse order, +C i.e. +C P(X) = TC(1)*(X-C)**N + ... + TC(N)*(X-C) + TC(N+1) +C +C***REFERENCES L. F. Shampine, S. M. Davenport and R. E. Huddleston, +C Curve fitting by polynomials in one variable, Report +C SLA-74-0270, Sandia Laboratories, June 1974. +C***ROUTINES CALLED DP1VLU +C***REVISION HISTORY (YYMMDD) +C 740601 DATE WRITTEN +C 890531 Changed all specific intrinsics to generic. (WRB) +C 891006 Cosmetic changes to prologue. (WRB) +C 891006 REVISION DATE from Version 3.2 +C 891214 Prologue converted to Version 4.0 format. (BAB) +C 920501 Reformatted the REFERENCES section. (WRB) +C***END PROLOGUE DPCOEF +C + INTEGER I,L,LL,LLP1,LLP2,NEW,NR + DOUBLE PRECISION A(*),C,FAC,SAVE,TC(*) +C***FIRST EXECUTABLE STATEMENT DPCOEF + LL = ABS(L) + LLP1 = LL + 1 + CALL DP1VLU (LL,LL,C,TC(1),TC(2),A) + IF (LL .LT. 2) GO TO 2 + FAC = 1.0D0 + DO 1 I = 3,LLP1 + FAC = FAC*(I-1) + 1 TC(I) = TC(I)/FAC + 2 IF (L .GE. 0) GO TO 4 + NR = LLP1/2 + LLP2 = LL + 2 + DO 3 I = 1,NR + SAVE = TC(I) + NEW = LLP2 - I + TC(I) = TC(NEW) + 3 TC(NEW) = SAVE + 4 RETURN + END diff --git a/ext/math/dpolft.f b/ext/math/dpolft.f new file mode 100644 index 000000000..36e29467d --- /dev/null +++ b/ext/math/dpolft.f @@ -0,0 +1,364 @@ +*DECK DPOLFT + SUBROUTINE DPOLFT (N, X, Y, W, MAXDEG, NDEG, EPS, R, IERR, A) +C***BEGIN PROLOGUE DPOLFT +C***PURPOSE Fit discrete data in a least squares sense by polynomials +C in one variable. +C***LIBRARY SLATEC +C***CATEGORY K1A1A2 +C***TYPE DOUBLE PRECISION (POLFIT-S, DPOLFT-D) +C***KEYWORDS CURVE FITTING, DATA FITTING, LEAST SQUARES, POLYNOMIAL FIT +C***AUTHOR Shampine, L. F., (SNLA) +C Davenport, S. M., (SNLA) +C Huddleston, R. E., (SNLL) +C***DESCRIPTION +C +C Abstract +C +C Given a collection of points X(I) and a set of values Y(I) which +C correspond to some function or measurement at each of the X(I), +C subroutine DPOLFT computes the weighted least-squares polynomial +C fits of all degrees up to some degree either specified by the user +C or determined by the routine. The fits thus obtained are in +C orthogonal polynomial form. Subroutine DP1VLU may then be +C called to evaluate the fitted polynomials and any of their +C derivatives at any point. The subroutine DPCOEF may be used to +C express the polynomial fits as powers of (X-C) for any specified +C point C. +C +C The parameters for DPOLFT are +C +C Input -- All TYPE REAL variables are DOUBLE PRECISION +C N - the number of data points. The arrays X, Y and W +C must be dimensioned at least N (N .GE. 1). +C X - array of values of the independent variable. These +C values may appear in any order and need not all be +C distinct. +C Y - array of corresponding function values. +C W - array of positive values to be used as weights. If +C W(1) is negative, DPOLFT will set all the weights +C to 1.0, which means unweighted least squares error +C will be minimized. To minimize relative error, the +C user should set the weights to: W(I) = 1.0/Y(I)**2, +C I = 1,...,N . +C MAXDEG - maximum degree to be allowed for polynomial fit. +C MAXDEG may be any non-negative integer less than N. +C Note -- MAXDEG cannot be equal to N-1 when a +C statistical test is to be used for degree selection, +C i.e., when input value of EPS is negative. +C EPS - specifies the criterion to be used in determining +C the degree of fit to be computed. +C (1) If EPS is input negative, DPOLFT chooses the +C degree based on a statistical F test of +C significance. One of three possible +C significance levels will be used: .01, .05 or +C .10. If EPS=-1.0 , the routine will +C automatically select one of these levels based +C on the number of data points and the maximum +C degree to be considered. If EPS is input as +C -.01, -.05, or -.10, a significance level of +C .01, .05, or .10, respectively, will be used. +C (2) If EPS is set to 0., DPOLFT computes the +C polynomials of degrees 0 through MAXDEG . +C (3) If EPS is input positive, EPS is the RMS +C error tolerance which must be satisfied by the +C fitted polynomial. DPOLFT will increase the +C degree of fit until this criterion is met or +C until the maximum degree is reached. +C +C Output -- All TYPE REAL variables are DOUBLE PRECISION +C NDEG - degree of the highest degree fit computed. +C EPS - RMS error of the polynomial of degree NDEG . +C R - vector of dimension at least NDEG containing values +C of the fit of degree NDEG at each of the X(I) . +C Except when the statistical test is used, these +C values are more accurate than results from subroutine +C DP1VLU normally are. +C IERR - error flag with the following possible values. +C 1 -- indicates normal execution, i.e., either +C (1) the input value of EPS was negative, and the +C computed polynomial fit of degree NDEG +C satisfies the specified F test, or +C (2) the input value of EPS was 0., and the fits of +C all degrees up to MAXDEG are complete, or +C (3) the input value of EPS was positive, and the +C polynomial of degree NDEG satisfies the RMS +C error requirement. +C 2 -- invalid input parameter. At least one of the input +C parameters has an illegal value and must be corrected +C before DPOLFT can proceed. Valid input results +C when the following restrictions are observed +C N .GE. 1 +C 0 .LE. MAXDEG .LE. N-1 for EPS .GE. 0. +C 0 .LE. MAXDEG .LE. N-2 for EPS .LT. 0. +C W(1)=-1.0 or W(I) .GT. 0., I=1,...,N . +C 3 -- cannot satisfy the RMS error requirement with a +C polynomial of degree no greater than MAXDEG . Best +C fit found is of degree MAXDEG . +C 4 -- cannot satisfy the test for significance using +C current value of MAXDEG . Statistically, the +C best fit found is of order NORD . (In this case, +C NDEG will have one of the values: MAXDEG-2, +C MAXDEG-1, or MAXDEG). Using a higher value of +C MAXDEG may result in passing the test. +C A - work and output array having at least 3N+3MAXDEG+3 +C locations +C +C Note - DPOLFT calculates all fits of degrees up to and including +C NDEG . Any or all of these fits can be evaluated or +C expressed as powers of (X-C) using DP1VLU and DPCOEF +C after just one call to DPOLFT . +C +C***REFERENCES L. F. Shampine, S. M. Davenport and R. E. Huddleston, +C Curve fitting by polynomials in one variable, Report +C SLA-74-0270, Sandia Laboratories, June 1974. +C***ROUTINES CALLED DP1VLU, XERMSG +C***REVISION HISTORY (YYMMDD) +C 740601 DATE WRITTEN +C 890531 Changed all specific intrinsics to generic. (WRB) +C 891006 Cosmetic changes to prologue. (WRB) +C 891006 REVISION DATE from Version 3.2 +C 891214 Prologue converted to Version 4.0 format. (BAB) +C 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ) +C 900911 Added variable YP to DOUBLE PRECISION declaration. (WRB) +C 920501 Reformatted the REFERENCES section. (WRB) +C 920527 Corrected erroneous statements in DESCRIPTION. (WRB) +C***END PROLOGUE DPOLFT + INTEGER I,IDEGF,IERR,J,JP1,JPAS,K1,K1PJ,K2,K2PJ,K3,K3PI,K4, + * K4PI,K5,K5PI,KSIG,M,MAXDEG,MOP1,NDEG,NDER,NFAIL + DOUBLE PRECISION TEMD1,TEMD2 + DOUBLE PRECISION A(*),DEGF,DEN,EPS,ETST,F,FCRIT,R(*),SIG,SIGJ, + * SIGJM1,SIGPAS,TEMP,X(*),XM,Y(*),YP,W(*),W1,W11 + DOUBLE PRECISION CO(4,3) + SAVE CO + DATA CO(1,1), CO(2,1), CO(3,1), CO(4,1), CO(1,2), CO(2,2), + 1 CO(3,2), CO(4,2), CO(1,3), CO(2,3), CO(3,3), + 2 CO(4,3)/-13.086850D0,-2.4648165D0,-3.3846535D0,-1.2973162D0, + 3 -3.3381146D0,-1.7812271D0,-3.2578406D0,-1.6589279D0, + 4 -1.6282703D0,-1.3152745D0,-3.2640179D0,-1.9829776D0/ +C***FIRST EXECUTABLE STATEMENT DPOLFT + +c write(*,*) 'DPOLFT n = ',n +c do ii = 1,n +c write(*,*) x(ii), y(ii), w(ii) +c end do +c write(*,*) ' maxdeg, eps = ',maxdeg,eps + + M = ABS(N) + IF (M .EQ. 0) GO TO 30 + IF (MAXDEG .LT. 0) GO TO 30 + A(1) = MAXDEG + MOP1 = MAXDEG + 1 + IF (M .LT. MOP1) GO TO 30 + IF (EPS .LT. 0.0D0 .AND. M .EQ. MOP1) GO TO 30 + XM = M + ETST = EPS*EPS*XM + IF (W(1) .LT. 0.0D0) GO TO 2 + DO 1 I = 1,M + IF (W(I) .LE. 0.0D0) GO TO 30 + 1 CONTINUE + GO TO 4 + 2 DO 3 I = 1,M + 3 W(I) = 1.0D0 + 4 IF (EPS .GE. 0.0D0) GO TO 8 +C +C DETERMINE SIGNIFICANCE LEVEL INDEX TO BE USED IN STATISTICAL TEST FOR +C CHOOSING DEGREE OF POLYNOMIAL FIT +C + IF (EPS .GT. (-.55D0)) GO TO 5 + IDEGF = M - MAXDEG - 1 + KSIG = 1 + IF (IDEGF .LT. 10) KSIG = 2 + IF (IDEGF .LT. 5) KSIG = 3 + GO TO 8 + 5 KSIG = 1 + IF (EPS .LT. (-.03D0)) KSIG = 2 + IF (EPS .LT. (-.07D0)) KSIG = 3 +C +C INITIALIZE INDEXES AND COEFFICIENTS FOR FITTING +C + 8 K1 = MAXDEG + 1 + K2 = K1 + MAXDEG + K3 = K2 + MAXDEG + 2 + K4 = K3 + M + K5 = K4 + M + DO 9 I = 2,K4 + 9 A(I) = 0.0D0 + W11 = 0.0D0 + IF (N .LT. 0) GO TO 11 +C +C UNCONSTRAINED CASE +C + DO 10 I = 1,M + K4PI = K4 + I + A(K4PI) = 1.0D0 + 10 W11 = W11 + W(I) + GO TO 13 +C +C CONSTRAINED CASE +C + 11 DO 12 I = 1,M + K4PI = K4 + I + 12 W11 = W11 + W(I)*A(K4PI)**2 +C +C COMPUTE FIT OF DEGREE ZERO +C + 13 TEMD1 = 0.0D0 + DO 14 I = 1,M + K4PI = K4 + I + TEMD1 = TEMD1 + W(I)*Y(I)*A(K4PI) + 14 CONTINUE + TEMD1 = TEMD1/W11 + A(K2+1) = TEMD1 + SIGJ = 0.0D0 + DO 15 I = 1,M + K4PI = K4 + I + K5PI = K5 + I + TEMD2 = TEMD1*A(K4PI) + R(I) = TEMD2 + A(K5PI) = TEMD2 - R(I) + 15 SIGJ = SIGJ + W(I)*((Y(I)-R(I)) - A(K5PI))**2 + J = 0 +C +C SEE IF POLYNOMIAL OF DEGREE 0 SATISFIES THE DEGREE SELECTION CRITERION +C + IF (EPS) 24,26,27 +C +C INCREMENT DEGREE +C + 16 J = J + 1 + JP1 = J + 1 + K1PJ = K1 + J + K2PJ = K2 + J + SIGJM1 = SIGJ +C +C COMPUTE NEW B COEFFICIENT EXCEPT WHEN J = 1 +C + IF (J .GT. 1) A(K1PJ) = W11/W1 +C +C COMPUTE NEW A COEFFICIENT +C + TEMD1 = 0.0D0 + DO 18 I = 1,M + K4PI = K4 + I + TEMD2 = A(K4PI) + TEMD1 = TEMD1 + X(I)*W(I)*TEMD2*TEMD2 + 18 CONTINUE + A(JP1) = TEMD1/W11 +C +C EVALUATE ORTHOGONAL POLYNOMIAL AT DATA POINTS +C + W1 = W11 + W11 = 0.0D0 + DO 19 I = 1,M + K3PI = K3 + I + K4PI = K4 + I + TEMP = A(K3PI) + A(K3PI) = A(K4PI) + A(K4PI) = (X(I)-A(JP1))*A(K3PI) - A(K1PJ)*TEMP + 19 W11 = W11 + W(I)*A(K4PI)**2 +C +C GET NEW ORTHOGONAL POLYNOMIAL COEFFICIENT USING PARTIAL DOUBLE +C PRECISION +C + TEMD1 = 0.0D0 + DO 20 I = 1,M + K4PI = K4 + I + K5PI = K5 + I + TEMD2 = W(I)*((Y(I)-R(I))-A(K5PI))*A(K4PI) + 20 TEMD1 = TEMD1 + TEMD2 + TEMD1 = TEMD1/W11 + A(K2PJ+1) = TEMD1 +C +C UPDATE POLYNOMIAL EVALUATIONS AT EACH OF THE DATA POINTS, AND +C ACCUMULATE SUM OF SQUARES OF ERRORS. THE POLYNOMIAL EVALUATIONS ARE +C COMPUTED AND STORED IN EXTENDED PRECISION. FOR THE I-TH DATA POINT, +C THE MOST SIGNIFICANT BITS ARE STORED IN R(I) , AND THE LEAST +C SIGNIFICANT BITS ARE IN A(K5PI) . +C + SIGJ = 0.0D0 + DO 21 I = 1,M + K4PI = K4 + I + K5PI = K5 + I + TEMD2 = R(I) + A(K5PI) + TEMD1*A(K4PI) + R(I) = TEMD2 + A(K5PI) = TEMD2 - R(I) + 21 SIGJ = SIGJ + W(I)*((Y(I)-R(I)) - A(K5PI))**2 +C +C SEE IF DEGREE SELECTION CRITERION HAS BEEN SATISFIED OR IF DEGREE +C MAXDEG HAS BEEN REACHED +C + IF (EPS) 23,26,27 +C +C COMPUTE F STATISTICS (INPUT EPS .LT. 0.) +C + 23 IF (SIGJ .EQ. 0.0D0) GO TO 29 + DEGF = M - J - 1 + DEN = (CO(4,KSIG)*DEGF + 1.0D0)*DEGF + FCRIT = (((CO(3,KSIG)*DEGF) + CO(2,KSIG))*DEGF + CO(1,KSIG))/DEN + FCRIT = FCRIT*FCRIT + F = (SIGJM1 - SIGJ)*DEGF/SIGJ + IF (F .LT. FCRIT) GO TO 25 +C +C POLYNOMIAL OF DEGREE J SATISFIES F TEST +C + 24 SIGPAS = SIGJ + JPAS = J + NFAIL = 0 + IF (MAXDEG .EQ. J) GO TO 32 + GO TO 16 +C +C POLYNOMIAL OF DEGREE J FAILS F TEST. IF THERE HAVE BEEN THREE +C SUCCESSIVE FAILURES, A STATISTICALLY BEST DEGREE HAS BEEN FOUND. +C + 25 NFAIL = NFAIL + 1 + IF (NFAIL .GE. 3) GO TO 29 + IF (MAXDEG .EQ. J) GO TO 32 + GO TO 16 +C +C RAISE THE DEGREE IF DEGREE MAXDEG HAS NOT YET BEEN REACHED (INPUT +C EPS = 0.) +C + 26 IF (MAXDEG .EQ. J) GO TO 28 + GO TO 16 +C +C SEE IF RMS ERROR CRITERION IS SATISFIED (INPUT EPS .GT. 0.) +C + 27 IF (SIGJ .LE. ETST) GO TO 28 + IF (MAXDEG .EQ. J) GO TO 31 + GO TO 16 +C +C RETURNS +C + 28 IERR = 1 + NDEG = J + SIG = SIGJ + GO TO 33 + 29 IERR = 1 + NDEG = JPAS + SIG = SIGPAS + GO TO 33 + 30 IERR = 2 + CALL XERMSG ('SLATEC', 'DPOLFT', 'INVALID INPUT PARAMETER.', 2, + + 1) + GO TO 37 + 31 IERR = 3 + NDEG = MAXDEG + SIG = SIGJ + GO TO 33 + 32 IERR = 4 + NDEG = JPAS + SIG = SIGPAS +C + 33 A(K3) = NDEG +C +C WHEN STATISTICAL TEST HAS BEEN USED, EVALUATE THE BEST POLYNOMIAL AT +C ALL THE DATA POINTS IF R DOES NOT ALREADY CONTAIN THESE VALUES +C + IF(EPS .GE. 0.0 .OR. NDEG .EQ. MAXDEG) GO TO 36 + NDER = 0 + DO 35 I = 1,M + CALL DP1VLU (NDEG,NDER,X(I),R(I),YP,A) + 35 CONTINUE + 36 EPS = SQRT(SIG/XM) + 37 RETURN + END diff --git a/ext/math/fdump.f b/ext/math/fdump.f new file mode 100644 index 000000000..562de1015 --- /dev/null +++ b/ext/math/fdump.f @@ -0,0 +1,70 @@ +*DECK FDUMP + SUBROUTINE FDUMP +C***BEGIN PROLOGUE FDUMP +C***PURPOSE Symbolic dump (should be locally written). +C***LIBRARY SLATEC (XERMSG) +C***CATEGORY R3 +C***TYPE ALL (FDUMP-A) +C***KEYWORDS ERROR, XERMSG +C***AUTHOR Jones, R. E., (SNLA) +C***DESCRIPTION +C +C ***Note*** Machine Dependent Routine +C FDUMP is intended to be replaced by a locally written +C version which produces a symbolic dump. Failing this, +C it should be replaced by a version which prints the +C subprogram nesting list. Note that this dump must be +C printed on each of up to five files, as indicated by the +C XGETUA routine. See XSETUA and XGETUA for details. +C +C Written by Ron Jones, with SLATEC Common Math Library Subcommittee +C +C***REFERENCES (NONE) +C***ROUTINES CALLED (NONE) +C***REVISION HISTORY (YYMMDD) +C 790801 DATE WRITTEN +C 861211 REVISION DATE from Version 3.2 +C 891214 Prologue converted to Version 4.0 format. (BAB) +C***END PROLOGUE FDUMP +C***FIRST EXECUTABLE STATEMENT FDUMP + RETURN + END + integer function isamax(n,sx,incx) +c +c finds the index of element having max. absolute value. +c jack dongarra, linpack, 3/11/78. +c modified 3/93 to return if incx .le. 0. +c + real sx(1),smax + integer i,incx,ix,n +c + isamax = 0 + if( n.lt.1 .or. incx.le.0 ) return + isamax = 1 + if(n.eq.1)return + if(incx.eq.1)go to 20 +c +c code for increment not equal to 1 +c + ix = 1 + smax = abs(sx(1)) + ix = ix + incx + do 10 i = 2,n + if(abs(sx(ix)).le.smax) go to 5 + isamax = i + smax = abs(sx(ix)) + 5 ix = ix + incx + 10 continue + return +c +c code for increment equal to 1 +c + 20 smax = abs(sx(1)) + do 30 i = 2,n + if(abs(sx(i)).le.smax) go to 30 + isamax = i + smax = abs(sx(i)) + 30 continue + return + end + diff --git a/ext/math/gmres.h b/ext/math/gmres.h new file mode 100755 index 000000000..1f6a044d5 --- /dev/null +++ b/ext/math/gmres.h @@ -0,0 +1,144 @@ +// -*- C++ -*- + +#ifndef GMRES_BLAS_H +#define GMRES_BLAS_H + +// ============================================================================ +// +// GMRES nach Saad, Schultz +// GMRES: a generalized minimal residual algorithm for solving nonsymmetric +// linear systems +// SIAM J Sci Stat Comput 7, 856-869 (1986) +// +// ---------------------------- +// Christian Badura, Mai 1998 +// +// ============================================================================ + + +template< class Matrix > +inline int +gmres( int m, int N, const Matrix &A, const doublereal *b, doublereal *x, doublereal eps ); + + +template< class Matrix > +inline int +gmres( int m, int N, const Matrix &A, const doublereal *b, doublereal *x, doublereal eps, + bool detailed ); + + +// ============================================================================ + +// #include "../../Cantera/src/blas.h" + +#include "cblas.h" +#include "../../Cantera/src/ctlapack.h" +using namespace Cantera; + +template< class Matrix > +inline int +gmres( int m, int n, const Matrix &A, const doublereal *b, doublereal *x, doublereal eps, + bool detailed ) { + if ( n<=0 ) + return -1; + typedef doublereal *doublerealP; + doublereal *V = new doublereal[n*(m+1)]; + doublereal *U = new doublereal[m*(m+1)/2]; + doublereal *r = new doublereal[n]; + doublereal *y = new doublereal[m+1]; + doublereal *c = new doublereal[m]; + doublereal *s = new doublereal[m]; + doublereal **v = new doublerealP[m+1]; + for ( int i=0; i<=m; ++i ) v[i]=V+i*n; + int its=-1; + { + doublereal beta, h, rd, dd, nrm2b; + int j, io, uij, u0j; + nrm2b=dnrm2(n,b,1); + cout << " norm = " << nrm2b << endl; + io=0; + do { // "aussere Iteration + ++io; + //mult(A,x,r); + A.mult(x,r); + daxpy(n,-1.,b,1,r,1); + beta=dnrm2(n,r,1); + dcopy(n,r,1,v[0],1); + dscal(n,1./beta,v[0],1); + + y[0]=beta; + j=0; + uij=0; + do { // innere Iteration j=0,...,m-1 + u0j=uij; + //mult(A,v[j],v[j+1]); + A.mult(v[j],v[j+1]); + + ct_dgemv(ctlapack::ColMajor, ctlapack::Transpose, n, j+1, 1.0, V, n, v[j+1], 1, 0.0, U+u0j, 1); + ct_dgemv(ctlapack::ColMajor, ctlapack::NoTranspose, n, j+1, -1.0, V, n, U+u0j, 1, 1.0, v[j+1], 1); + + //dgemv(Transpose,n,j+1,1.,V,n,v[j+1],1,0.,U+u0j,1); + //dgemv(NoTranspose,n,j+1,-1.,V,n,U+u0j,1,1.,v[j+1],1); + + h=dnrm2(n,v[j+1],1); + + dscal(n,1./h,v[j+1],1); + + for ( int i=0; i=eps*nrm2b ); + { // minimiere bzgl Y + dtpsv(UpperTriangle,NoTranspose,NotUnitTriangular,j,U,y,1); + // korrigiere X + dgemv(NoTranspose,n,j,-1.,V,n,y,1,1.,x,1); + } + } while ( fabs(y[j])>=eps*nrm2b ); + + // R"uckgabe: Zahl der inneren Iterationen + its = m*(io-1)+j; + } + + delete[] V; + delete[] U; + delete[] r; + delete[] y; + delete[] c; + delete[] s; + delete[] v; + return its; +} + + +// ============================================================================ + + +template< class Matrix > +inline int +gmres( int m, int n, const Matrix &A, const doublereal *b, doublereal *x, doublereal eps ){ + return gmres(m,n,A,b,x,eps,false); +} + +// ============================================================================ + + +#endif // GMRES_BLAS_H diff --git a/ext/math/idamax.f b/ext/math/idamax.f new file mode 100755 index 000000000..eb0de47a7 --- /dev/null +++ b/ext/math/idamax.f @@ -0,0 +1,39 @@ + + integer function idamax(n,dx,incx) +c +c finds the index of element having max. absolute value. +c jack dongarra, linpack, 3/11/78. +c modified 3/93 to return if incx .le. 0. +c + double precision dx(1),dmax + integer i,incx,ix,n +c + idamax = 0 + if( n.lt.1 .or. incx.le.0 ) return + idamax = 1 + if(n.eq.1)return + if(incx.eq.1)go to 20 +c +c code for increment not equal to 1 +c + ix = 1 + dmax = dabs(dx(1)) + ix = ix + incx + do 10 i = 2,n + if(dabs(dx(ix)).le.dmax) go to 5 + idamax = i + dmax = dabs(dx(ix)) + 5 ix = ix + incx + 10 continue + return +c +c code for increment equal to 1 +c + 20 dmax = dabs(dx(1)) + do 30 i = 2,n + if(dabs(dx(i)).le.dmax) go to 30 + idamax = i + dmax = dabs(dx(i)) + 30 continue + return + end diff --git a/ext/math/j4save.f b/ext/math/j4save.f new file mode 100644 index 000000000..6ec799ba1 --- /dev/null +++ b/ext/math/j4save.f @@ -0,0 +1,65 @@ +*DECK J4SAVE + FUNCTION J4SAVE (IWHICH, IVALUE, ISET) +C***BEGIN PROLOGUE J4SAVE +C***SUBSIDIARY +C***PURPOSE Save or recall global variables needed by error +C handling routines. +C***LIBRARY SLATEC (XERROR) +C***TYPE INTEGER (J4SAVE-I) +C***KEYWORDS ERROR MESSAGES, ERROR NUMBER, RECALL, SAVE, XERROR +C***AUTHOR Jones, R. E., (SNLA) +C***DESCRIPTION +C +C Abstract +C J4SAVE saves and recalls several global variables needed +C by the library error handling routines. +C +C Description of Parameters +C --Input-- +C IWHICH - Index of item desired. +C = 1 Refers to current error number. +C = 2 Refers to current error control flag. +C = 3 Refers to current unit number to which error +C messages are to be sent. (0 means use standard.) +C = 4 Refers to the maximum number of times any +C message is to be printed (as set by XERMAX). +C = 5 Refers to the total number of units to which +C each error message is to be written. +C = 6 Refers to the 2nd unit for error messages +C = 7 Refers to the 3rd unit for error messages +C = 8 Refers to the 4th unit for error messages +C = 9 Refers to the 5th unit for error messages +C IVALUE - The value to be set for the IWHICH-th parameter, +C if ISET is .TRUE. . +C ISET - If ISET=.TRUE., the IWHICH-th parameter will BE +C given the value, IVALUE. If ISET=.FALSE., the +C IWHICH-th parameter will be unchanged, and IVALUE +C is a dummy parameter. +C --Output-- +C The (old) value of the IWHICH-th parameter will be returned +C in the function value, J4SAVE. +C +C***SEE ALSO XERMSG +C***REFERENCES R. E. Jones and D. K. Kahaner, XERROR, the SLATEC +C Error-handling Package, SAND82-0800, Sandia +C Laboratories, 1982. +C***ROUTINES CALLED (NONE) +C***REVISION HISTORY (YYMMDD) +C 790801 DATE WRITTEN +C 891214 Prologue converted to Version 4.0 format. (BAB) +C 900205 Minor modifications to prologue. (WRB) +C 900402 Added TYPE section. (WRB) +C 910411 Added KEYWORDS section. (WRB) +C 920501 Reformatted the REFERENCES section. (WRB) +C***END PROLOGUE J4SAVE + LOGICAL ISET + INTEGER IPARAM(9) + SAVE IPARAM + DATA IPARAM(1),IPARAM(2),IPARAM(3),IPARAM(4)/0,2,0,10/ + DATA IPARAM(5)/1/ + DATA IPARAM(6),IPARAM(7),IPARAM(8),IPARAM(9)/0,0,0,0/ +C***FIRST EXECUTABLE STATEMENT J4SAVE + J4SAVE = IPARAM(IWHICH) + IF (ISET) IPARAM(IWHICH) = IVALUE + RETURN + END diff --git a/ext/math/mach.cpp b/ext/math/mach.cpp new file mode 100755 index 000000000..00aed4894 --- /dev/null +++ b/ext/math/mach.cpp @@ -0,0 +1,56 @@ + + /* Standard C source for D1MACH -- remove the * in column 1 */ +#include +#include +#include +#include +#include + +extern "C" { + +double d1mach_(long *i) +{ + switch(*i){ + case 1: return DBL_MIN; + case 2: return DBL_MAX; + case 3: return DBL_EPSILON/FLT_RADIX; + case 4: return DBL_EPSILON; + case 5: return log10((double)FLT_RADIX); + } + fprintf(stderr, "invalid argument: d1mach(%ld)\n", *i); + exit(1); + return 0; /* some compilers demand return values */ +} + +double d1mach(long *i) {return d1mach_(i);} + + +long i1mach_(long *i) +{ + switch(*i){ + case 1: return 5; /* standard input */ + case 2: return 6; /* standard output */ + case 3: return 7; /* standard punch */ + case 4: return 0; /* standard error */ + case 5: return 32; /* bits per integer */ + case 6: return sizeof(int); + case 7: return 2; /* base for integers */ + case 8: return 31; /* digits of integer base */ + case 9: return LONG_MAX; + case 10: return FLT_RADIX; + case 11: return FLT_MANT_DIG; + case 12: return FLT_MIN_EXP; + case 13: return FLT_MAX_EXP; + case 14: return DBL_MANT_DIG; + case 15: return DBL_MIN_EXP; + case 16: return DBL_MAX_EXP; + } + fprintf(stderr, "invalid argument: i1mach(%ld)\n", *i); + exit(1); + return 0; /* some compilers demand return values */ +} + +long i1mach(long *i) { return i1mach_(i); } + +} + diff --git a/ext/math/mkl_cblas.h b/ext/math/mkl_cblas.h new file mode 100755 index 000000000..dc5b45a71 --- /dev/null +++ b/ext/math/mkl_cblas.h @@ -0,0 +1,644 @@ +/* +// INTEL CORPORATION PROPRIETARY INFORMATION +// This software is supplied under the terms of a license agreement or +// nondisclosure agreement with Intel Corporation and may not be copied +// or disclosed except in accordance with the terms of that agreement. +// Copyright 1999, 2000 Intel Corporation. All Rights Reserved. +// +// File : mkl_cblas.h +// Purpose : MKL CBLAS interface +// Author : Shemyakin Andrey +*/ + +#ifndef __MKL_CBLAS_H__ +#define __MKL_CBLAS_H__ +#include + +#ifdef __cplusplus +extern "C" { /* Assume C declarations for C++ */ +#endif /* __cplusplus */ + +/* + * Enumerated and derived types + */ +#define CBLAS_INDEX size_t /* this may vary between platforms */ + +typedef enum {CblasRowMajor=101, CblasColMajor=102} CBLAS_ORDER; +typedef enum {CblasNoTrans=111, CblasTrans=112, CblasConjTrans=113} CBLAS_TRANSPOSE; +typedef enum {CblasUpper=121, CblasLower=122} CBLAS_UPLO; +typedef enum {CblasNonUnit=131, CblasUnit=132} CBLAS_DIAG; +typedef enum {CblasLeft=141, CblasRight=142} CBLAS_SIDE; + +/* + * =========================================================================== + * Prototypes for level 1 BLAS functions (complex are recast as routines) + * =========================================================================== + */ + +float cblas_sdot(const int N, const float *X, const int incX, + const float *Y, const int incY); +float cblas_sdoti(const int N, const float *X, const int *indx, + const float *Y); +double cblas_ddot(const int N, const double *X, const int incX, + const double *Y, const int incY); +double cblas_ddoti(const int N, const double *X, const int *indx, + const double *Y); + +/* + * Functions having prefixes Z and C only + */ +void cblas_cdotu_sub(const int N, const void *X, const int incX, + const void *Y, const int incY, void *dotu); +void cblas_cdotui_sub(const int N, const void *X, const int *indx, + const void *Y, void *dotui); +void cblas_cdotc_sub(const int N, const void *X, const int incX, + const void *Y, const int incY, void *dotc); +void cblas_cdotci_sub(const int N, const void *X, const int *indx, + const void *Y, void *dotui); + +void cblas_zdotu_sub(const int N, const void *X, const int incX, + const void *Y, const int incY, void *dotu); +void cblas_zdotui_sub(const int N, const void *X, const int *indx, + const void *Y, void *dotui); +void cblas_zdotc_sub(const int N, const void *X, const int incX, + const void *Y, const int incY, void *dotc); +void cblas_zdotci_sub(const int N, const void *X, const int *indx, + const void *Y, void *dotui); + + +/* + * Functions having prefixes S D SC DZ + */ +float cblas_snrm2(const int N, const float *X, const int incX); +float cblas_sasum(const int N, const float *X, const int incX); + +double cblas_dnrm2(const int N, const double *X, const int incX); +double cblas_dasum(const int N, const double *X, const int incX); + +float cblas_scnrm2(const int N, const void *X, const int incX); +float cblas_scasum(const int N, const void *X, const int incX); + +double cblas_dznrm2(const int N, const void *X, const int incX); +double cblas_dzasum(const int N, const void *X, const int incX); + + +/* + * Functions having standard 4 prefixes (S D C Z) + */ +CBLAS_INDEX cblas_isamax(const int N, const float *X, const int incX); +CBLAS_INDEX cblas_idamax(const int N, const double *X, const int incX); +CBLAS_INDEX cblas_icamax(const int N, const void *X, const int incX); +CBLAS_INDEX cblas_izamax(const int N, const void *X, const int incX); +CBLAS_INDEX cblas_isamin(const int N, const float *X, const int incX); +CBLAS_INDEX cblas_idamin(const int N, const double *X, const int incX); +CBLAS_INDEX cblas_icamin(const int N, const void *X, const int incX); +CBLAS_INDEX cblas_izamin(const int N, const void *X, const int incX); + +/* + * =========================================================================== + * Prototypes for level 1 BLAS routines + * =========================================================================== + */ + +/* + * Routines with standard 4 prefixes (s, d, c, z) + */ +void cblas_sswap(const int N, float *X, const int incX, + float *Y, const int incY); +void cblas_scopy(const int N, const float *X, const int incX, + float *Y, const int incY); +void cblas_saxpy(const int N, const float alpha, const float *X, + const int incX, float *Y, const int incY); +void cblas_saxpyi(const int N, const float alpha, const float *X, + const int *indx, float *Y); +void cblas_sgthr(const int N, const float *Y, float *X, + const int *indx); +void cblas_sgthrz(const int N, float *Y, float *X, + const int *indx); +void cblas_ssctr(const int N, const float *X, const int *indx, + float *Y); +void cblas_srotg(float *a, float *b, float *c, float *s); + +void cblas_dswap(const int N, double *X, const int incX, + double *Y, const int incY); +void cblas_dcopy(const int N, const double *X, const int incX, + double *Y, const int incY); +void cblas_daxpy(const int N, const double alpha, const double *X, + const int incX, double *Y, const int incY); +void cblas_daxpyi(const int N, const double alpha, const double *X, + const int *indx, double *Y); +void cblas_dgthr(const int N, const double *Y, double *X, + const int *indx); +void cblas_dgthrz(const int N, double *Y, double *X, + const int *indx); +void cblas_dsctr(const int N, const double *X, const int *indx, + double *Y); +void cblas_drotg(double *a, double *b, double *c, double *s); + +void cblas_cswap(const int N, void *X, const int incX, + void *Y, const int incY); +void cblas_ccopy(const int N, const void *X, const int incX, + void *Y, const int incY); +void cblas_caxpy(const int N, const void *alpha, const void *X, + const int incX, void *Y, const int incY); +void cblas_caxpyi(const int N, const void *alpha, const void *X, + const int *indx, void *Y); +void cblas_cgthr(const int N, const void *Y, void *X, + const int *indx); +void cblas_cgthrz(const int N, void *Y, void *X, + const int *indx); +void cblas_csctr(const int N, const void *X, const int *indx, + void *Y); +void cblas_crotg(void *a, const void *b, float *c, void *s); + +void cblas_zswap(const int N, void *X, const int incX, + void *Y, const int incY); +void cblas_zcopy(const int N, const void *X, const int incX, + void *Y, const int incY); +void cblas_zaxpy(const int N, const void *alpha, const void *X, + const int incX, void *Y, const int incY); +void cblas_zaxpyi(const int N, const void *alpha, const void *X, + const int *indx, void *Y); +void cblas_zgthr(const int N, const void *Y, void *X, + const int *indx); +void cblas_zgthrz(const int N, void *Y, void *X, + const int *indx); +void cblas_zsctr(const int N, const void *X, const int *indx, + void *Y); +void cblas_zrotg(void *a, const void *b, double *c, void *s); + +/* + * Routines with S and D prefix only + */ +void cblas_srotmg(float *d1, float *d2, float *b1, const float *b2, float *P); +void cblas_srot(const int N, float *X, const int incX, + float *Y, const int incY, const float c, const float s); +void cblas_sroti(const int N, float *X, const int *indx, + float *Y, const float c, const float s); +void cblas_srotm(const int N, float *X, const int incX, + float *Y, const int incY, const float *P); + +void cblas_drotmg(double *d1, double *d2, double *b1, const double *b2, double *P); +void cblas_drot(const int N, double *X, const int incX, + double *Y, const int incY, const double c, const double s); +void cblas_drotm(const int N, double *X, const int incX, + double *Y, const int incY, const double *P); +void cblas_droti(const int N, double *X, const int *indx, + double *Y, const double c, const double s); + +/* + * Routines with CS and ZD prefix only + */ +void cblas_csrot(const int N, void *X, const int incX, + void *Y, const int incY, const float c, const float s); +void cblas_zdrot(const int N, void *X, const int incX, + void *Y, const int incY, const double c, const double s); + +/* + * Routines with S D C Z CS and ZD prefixes + */ +void cblas_sscal(const int N, const float alpha, float *X, const int incX); +void cblas_dscal(const int N, const double alpha, double *X, const int incX); +void cblas_cscal(const int N, const void *alpha, void *X, const int incX); +void cblas_zscal(const int N, const void *alpha, void *X, const int incX); +void cblas_csscal(const int N, const float alpha, void *X, const int incX); +void cblas_zdscal(const int N, const double alpha, void *X, const int incX); + +/* + * =========================================================================== + * Prototypes for level 2 BLAS + * =========================================================================== + */ + +/* + * Routines with standard 4 prefixes (S, D, C, Z) + */ +void cblas_sgemv(const CBLAS_ORDER order, + const CBLAS_TRANSPOSE TransA, const int M, const int N, + const float alpha, const float *A, const int lda, + const float *X, const int incX, const float beta, + float *Y, const int incY); +void cblas_sgbmv(const CBLAS_ORDER order, + const CBLAS_TRANSPOSE TransA, const int M, const int N, + const int KL, const int KU, const float alpha, + const float *A, const int lda, const float *X, + const int incX, const float beta, float *Y, const int incY); +void cblas_strmv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const float *A, const int lda, + float *X, const int incX); +void cblas_stbmv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const int K, const float *A, const int lda, + float *X, const int incX); +void cblas_stpmv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const float *Ap, float *X, const int incX); +void cblas_strsv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const float *A, const int lda, float *X, + const int incX); +void cblas_stbsv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const int K, const float *A, const int lda, + float *X, const int incX); +void cblas_stpsv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const float *Ap, float *X, const int incX); + +void cblas_dgemv(const CBLAS_ORDER order, + const CBLAS_TRANSPOSE TransA, const int M, const int N, + const double alpha, const double *A, const int lda, + const double *X, const int incX, const double beta, + double *Y, const int incY); +void cblas_dgbmv(const CBLAS_ORDER order, + const CBLAS_TRANSPOSE TransA, const int M, const int N, + const int KL, const int KU, const double alpha, + const double *A, const int lda, const double *X, + const int incX, const double beta, double *Y, const int incY); +void cblas_dtrmv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const double *A, const int lda, + double *X, const int incX); +void cblas_dtbmv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const int K, const double *A, const int lda, + double *X, const int incX); +void cblas_dtpmv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const double *Ap, double *X, const int incX); +void cblas_dtrsv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const double *A, const int lda, double *X, + const int incX); +void cblas_dtbsv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const int K, const double *A, const int lda, + double *X, const int incX); +void cblas_dtpsv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const double *Ap, double *X, const int incX); + +void cblas_cgemv(const CBLAS_ORDER order, + const CBLAS_TRANSPOSE TransA, const int M, const int N, + const void *alpha, const void *A, const int lda, + const void *X, const int incX, const void *beta, + void *Y, const int incY); +void cblas_cgbmv(const CBLAS_ORDER order, + const CBLAS_TRANSPOSE TransA, const int M, const int N, + const int KL, const int KU, const void *alpha, + const void *A, const int lda, const void *X, + const int incX, const void *beta, void *Y, const int incY); +void cblas_ctrmv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const void *A, const int lda, + void *X, const int incX); +void cblas_ctbmv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const int K, const void *A, const int lda, + void *X, const int incX); +void cblas_ctpmv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const void *Ap, void *X, const int incX); +void cblas_ctrsv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const void *A, const int lda, void *X, + const int incX); +void cblas_ctbsv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const int K, const void *A, const int lda, + void *X, const int incX); +void cblas_ctpsv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const void *Ap, void *X, const int incX); + +void cblas_zgemv(const CBLAS_ORDER order, + const CBLAS_TRANSPOSE TransA, const int M, const int N, + const void *alpha, const void *A, const int lda, + const void *X, const int incX, const void *beta, + void *Y, const int incY); +void cblas_zgbmv(const CBLAS_ORDER order, + const CBLAS_TRANSPOSE TransA, const int M, const int N, + const int KL, const int KU, const void *alpha, + const void *A, const int lda, const void *X, + const int incX, const void *beta, void *Y, const int incY); +void cblas_ztrmv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const void *A, const int lda, + void *X, const int incX); +void cblas_ztbmv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const int K, const void *A, const int lda, + void *X, const int incX); +void cblas_ztpmv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const void *Ap, void *X, const int incX); +void cblas_ztrsv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const void *A, const int lda, void *X, + const int incX); +void cblas_ztbsv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const int K, const void *A, const int lda, + void *X, const int incX); +void cblas_ztpsv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE TransA, const CBLAS_DIAG Diag, + const int N, const void *Ap, void *X, const int incX); + + +/* + * Routines with S and D prefixes only + */ +void cblas_ssymv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const float alpha, const float *A, + const int lda, const float *X, const int incX, + const float beta, float *Y, const int incY); +void cblas_ssbmv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const int K, const float alpha, const float *A, + const int lda, const float *X, const int incX, + const float beta, float *Y, const int incY); +void cblas_sspmv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const float alpha, const float *Ap, + const float *X, const int incX, + const float beta, float *Y, const int incY); +void cblas_sger(const CBLAS_ORDER order, const int M, const int N, + const float alpha, const float *X, const int incX, + const float *Y, const int incY, float *A, const int lda); +void cblas_ssyr(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const float alpha, const float *X, + const int incX, float *A, const int lda); +void cblas_sspr(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const float alpha, const float *X, + const int incX, float *Ap); +void cblas_ssyr2(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const float alpha, const float *X, + const int incX, const float *Y, const int incY, float *A, + const int lda); +void cblas_sspr2(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const float alpha, const float *X, + const int incX, const float *Y, const int incY, float *A); + +void cblas_dsymv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const double alpha, const double *A, + const int lda, const double *X, const int incX, + const double beta, double *Y, const int incY); +void cblas_dsbmv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const int K, const double alpha, const double *A, + const int lda, const double *X, const int incX, + const double beta, double *Y, const int incY); +void cblas_dspmv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const double alpha, const double *Ap, + const double *X, const int incX, + const double beta, double *Y, const int incY); +void cblas_dger(const CBLAS_ORDER order, const int M, const int N, + const double alpha, const double *X, const int incX, + const double *Y, const int incY, double *A, const int lda); +void cblas_dsyr(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const double alpha, const double *X, + const int incX, double *A, const int lda); +void cblas_dspr(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const double alpha, const double *X, + const int incX, double *Ap); +void cblas_dsyr2(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const double alpha, const double *X, + const int incX, const double *Y, const int incY, double *A, + const int lda); +void cblas_dspr2(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const double alpha, const double *X, + const int incX, const double *Y, const int incY, double *A); + + +/* + * Routines with C and Z prefixes only + */ +void cblas_chemv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const void *alpha, const void *A, + const int lda, const void *X, const int incX, + const void *beta, void *Y, const int incY); +void cblas_chbmv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const int K, const void *alpha, const void *A, + const int lda, const void *X, const int incX, + const void *beta, void *Y, const int incY); +void cblas_chpmv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const void *alpha, const void *Ap, + const void *X, const int incX, + const void *beta, void *Y, const int incY); +void cblas_cgeru(const CBLAS_ORDER order, const int M, const int N, + const void *alpha, const void *X, const int incX, + const void *Y, const int incY, void *A, const int lda); +void cblas_cgerc(const CBLAS_ORDER order, const int M, const int N, + const void *alpha, const void *X, const int incX, + const void *Y, const int incY, void *A, const int lda); +void cblas_cher(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const float alpha, const void *X, const int incX, + void *A, const int lda); +void cblas_chpr(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const float alpha, const void *X, + const int incX, void *A); +void cblas_cher2(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, const int N, + const void *alpha, const void *X, const int incX, + const void *Y, const int incY, void *A, const int lda); +void cblas_chpr2(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, const int N, + const void *alpha, const void *X, const int incX, + const void *Y, const int incY, void *Ap); + +void cblas_zhemv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const void *alpha, const void *A, + const int lda, const void *X, const int incX, + const void *beta, void *Y, const int incY); +void cblas_zhbmv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const int K, const void *alpha, const void *A, + const int lda, const void *X, const int incX, + const void *beta, void *Y, const int incY); +void cblas_zhpmv(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const void *alpha, const void *Ap, + const void *X, const int incX, + const void *beta, void *Y, const int incY); +void cblas_zgeru(const CBLAS_ORDER order, const int M, const int N, + const void *alpha, const void *X, const int incX, + const void *Y, const int incY, void *A, const int lda); +void cblas_zgerc(const CBLAS_ORDER order, const int M, const int N, + const void *alpha, const void *X, const int incX, + const void *Y, const int incY, void *A, const int lda); +void cblas_zher(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const double alpha, const void *X, const int incX, + void *A, const int lda); +void cblas_zhpr(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, + const int N, const double alpha, const void *X, + const int incX, void *A); +void cblas_zher2(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, const int N, + const void *alpha, const void *X, const int incX, + const void *Y, const int incY, void *A, const int lda); +void cblas_zhpr2(const CBLAS_ORDER order, const CBLAS_UPLO Uplo, const int N, + const void *alpha, const void *X, const int incX, + const void *Y, const int incY, void *Ap); + +/* + * =========================================================================== + * Prototypes for level 3 BLAS + * =========================================================================== + */ + +/* + * Routines with standard 4 prefixes (S, D, C, Z) + */ +void cblas_sgemm(const CBLAS_ORDER Order, const CBLAS_TRANSPOSE TransA, + const CBLAS_TRANSPOSE TransB, const int M, const int N, + const int K, const float alpha, const float *A, + const int lda, const float *B, const int ldb, + const float beta, float *C, const int ldc); +void cblas_ssymm(const CBLAS_ORDER Order, const CBLAS_SIDE Side, + const CBLAS_UPLO Uplo, const int M, const int N, + const float alpha, const float *A, const int lda, + const float *B, const int ldb, const float beta, + float *C, const int ldc); +void cblas_ssyrk(const CBLAS_ORDER Order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE Trans, const int N, const int K, + const float alpha, const float *A, const int lda, + const float beta, float *C, const int ldc); +void cblas_ssyr2k(const CBLAS_ORDER Order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE Trans, const int N, const int K, + const float alpha, const float *A, const int lda, + const float *B, const int ldb, const float beta, + float *C, const int ldc); +void cblas_strmm(const CBLAS_ORDER Order, const CBLAS_SIDE Side, + const CBLAS_UPLO Uplo, const CBLAS_TRANSPOSE TransA, + const CBLAS_DIAG Diag, const int M, const int N, + const float alpha, const float *A, const int lda, + float *B, const int ldb); +void cblas_strsm(const CBLAS_ORDER Order, const CBLAS_SIDE Side, + const CBLAS_UPLO Uplo, const CBLAS_TRANSPOSE TransA, + const CBLAS_DIAG Diag, const int M, const int N, + const float alpha, const float *A, const int lda, + float *B, const int ldb); + +void cblas_dgemm(const CBLAS_ORDER Order, const CBLAS_TRANSPOSE TransA, + const CBLAS_TRANSPOSE TransB, const int M, const int N, + const int K, const double alpha, const double *A, + const int lda, const double *B, const int ldb, + const double beta, double *C, const int ldc); +void cblas_dsymm(const CBLAS_ORDER Order, const CBLAS_SIDE Side, + const CBLAS_UPLO Uplo, const int M, const int N, + const double alpha, const double *A, const int lda, + const double *B, const int ldb, const double beta, + double *C, const int ldc); +void cblas_dsyrk(const CBLAS_ORDER Order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE Trans, const int N, const int K, + const double alpha, const double *A, const int lda, + const double beta, double *C, const int ldc); +void cblas_dsyr2k(const CBLAS_ORDER Order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE Trans, const int N, const int K, + const double alpha, const double *A, const int lda, + const double *B, const int ldb, const double beta, + double *C, const int ldc); +void cblas_dtrmm(const CBLAS_ORDER Order, const CBLAS_SIDE Side, + const CBLAS_UPLO Uplo, const CBLAS_TRANSPOSE TransA, + const CBLAS_DIAG Diag, const int M, const int N, + const double alpha, const double *A, const int lda, + double *B, const int ldb); +void cblas_dtrsm(const CBLAS_ORDER Order, const CBLAS_SIDE Side, + const CBLAS_UPLO Uplo, const CBLAS_TRANSPOSE TransA, + const CBLAS_DIAG Diag, const int M, const int N, + const double alpha, const double *A, const int lda, + double *B, const int ldb); + +void cblas_cgemm(const CBLAS_ORDER Order, const CBLAS_TRANSPOSE TransA, + const CBLAS_TRANSPOSE TransB, const int M, const int N, + const int K, const void *alpha, const void *A, + const int lda, const void *B, const int ldb, + const void *beta, void *C, const int ldc); +void cblas_csymm(const CBLAS_ORDER Order, const CBLAS_SIDE Side, + const CBLAS_UPLO Uplo, const int M, const int N, + const void *alpha, const void *A, const int lda, + const void *B, const int ldb, const void *beta, + void *C, const int ldc); +void cblas_csyrk(const CBLAS_ORDER Order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE Trans, const int N, const int K, + const void *alpha, const void *A, const int lda, + const void *beta, void *C, const int ldc); +void cblas_csyr2k(const CBLAS_ORDER Order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE Trans, const int N, const int K, + const void *alpha, const void *A, const int lda, + const void *B, const int ldb, const void *beta, + void *C, const int ldc); +void cblas_ctrmm(const CBLAS_ORDER Order, const CBLAS_SIDE Side, + const CBLAS_UPLO Uplo, const CBLAS_TRANSPOSE TransA, + const CBLAS_DIAG Diag, const int M, const int N, + const void *alpha, const void *A, const int lda, + void *B, const int ldb); +void cblas_ctrsm(const CBLAS_ORDER Order, const CBLAS_SIDE Side, + const CBLAS_UPLO Uplo, const CBLAS_TRANSPOSE TransA, + const CBLAS_DIAG Diag, const int M, const int N, + const void *alpha, const void *A, const int lda, + void *B, const int ldb); + +void cblas_zgemm(const CBLAS_ORDER Order, const CBLAS_TRANSPOSE TransA, + const CBLAS_TRANSPOSE TransB, const int M, const int N, + const int K, const void *alpha, const void *A, + const int lda, const void *B, const int ldb, + const void *beta, void *C, const int ldc); +void cblas_zsymm(const CBLAS_ORDER Order, const CBLAS_SIDE Side, + const CBLAS_UPLO Uplo, const int M, const int N, + const void *alpha, const void *A, const int lda, + const void *B, const int ldb, const void *beta, + void *C, const int ldc); +void cblas_zsyrk(const CBLAS_ORDER Order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE Trans, const int N, const int K, + const void *alpha, const void *A, const int lda, + const void *beta, void *C, const int ldc); +void cblas_zsyr2k(const CBLAS_ORDER Order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE Trans, const int N, const int K, + const void *alpha, const void *A, const int lda, + const void *B, const int ldb, const void *beta, + void *C, const int ldc); +void cblas_ztrmm(const CBLAS_ORDER Order, const CBLAS_SIDE Side, + const CBLAS_UPLO Uplo, const CBLAS_TRANSPOSE TransA, + const CBLAS_DIAG Diag, const int M, const int N, + const void *alpha, const void *A, const int lda, + void *B, const int ldb); +void cblas_ztrsm(const CBLAS_ORDER Order, const CBLAS_SIDE Side, + const CBLAS_UPLO Uplo, const CBLAS_TRANSPOSE TransA, + const CBLAS_DIAG Diag, const int M, const int N, + const void *alpha, const void *A, const int lda, + void *B, const int ldb); + + +/* + * Routines with prefixes C and Z only + */ +void cblas_chemm(const CBLAS_ORDER Order, const CBLAS_SIDE Side, + const CBLAS_UPLO Uplo, const int M, const int N, + const void *alpha, const void *A, const int lda, + const void *B, const int ldb, const void *beta, + void *C, const int ldc); +void cblas_cherk(const CBLAS_ORDER Order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE Trans, const int N, const int K, + const float alpha, const void *A, const int lda, + const float beta, void *C, const int ldc); +void cblas_cher2k(const CBLAS_ORDER Order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE Trans, const int N, const int K, + const void *alpha, const void *A, const int lda, + const void *B, const int ldb, const float beta, + void *C, const int ldc); + +void cblas_zhemm(const CBLAS_ORDER Order, const CBLAS_SIDE Side, + const CBLAS_UPLO Uplo, const int M, const int N, + const void *alpha, const void *A, const int lda, + const void *B, const int ldb, const void *beta, + void *C, const int ldc); +void cblas_zherk(const CBLAS_ORDER Order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE Trans, const int N, const int K, + const double alpha, const void *A, const int lda, + const double beta, void *C, const int ldc); +void cblas_zher2k(const CBLAS_ORDER Order, const CBLAS_UPLO Uplo, + const CBLAS_TRANSPOSE Trans, const int N, const int K, + const void *alpha, const void *A, const int lda, + const void *B, const int ldb, const double beta, + void *C, const int ldc); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __MKL_CBLAS_H__ */ diff --git a/ext/math/pcoef.f b/ext/math/pcoef.f new file mode 100644 index 000000000..28fe548ff --- /dev/null +++ b/ext/math/pcoef.f @@ -0,0 +1,712 @@ +*DECK PCOEF + SUBROUTINE PCOEF (L, C, TC, A) +C***BEGIN PROLOGUE PCOEF +C***PURPOSE Convert the POLFIT coefficients to Taylor series form. +C***LIBRARY SLATEC +C***CATEGORY K1A1A2 +C***TYPE SINGLE PRECISION (PCOEF-S, DPCOEF-D) +C***KEYWORDS CURVE FITTING, DATA FITTING, LEAST SQUARES, POLYNOMIAL FIT +C***AUTHOR Shampine, L. F., (SNLA) +C Davenport, S. M., (SNLA) +C***DESCRIPTION +C +C Written BY L. F. Shampine and S. M. Davenport. +C +C Abstract +C +C POLFIT computes the least squares polynomial fit of degree L as +C a sum of orthogonal polynomials. PCOEF changes this fit to its +C Taylor expansion about any point C , i.e. writes the polynomial +C as a sum of powers of (X-C). Taking C=0. gives the polynomial +C in powers of X, but a suitable non-zero C often leads to +C polynomials which are better scaled and more accurately evaluated. +C +C The parameters for PCOEF are +C +C INPUT -- +C L - Indicates the degree of polynomial to be changed to +C its Taylor expansion. To obtain the Taylor +C coefficients in reverse order, input L as the +C negative of the degree desired. The absolute value +C of L must be less than or equal to NDEG, the highest +C degree polynomial fitted by POLFIT . +C C - The point about which the Taylor expansion is to be +C made. +C A - Work and output array containing values from last +C call to POLFIT . +C +C OUTPUT -- +C TC - Vector containing the first LL+1 Taylor coefficients +C where LL=ABS(L). If L.GT.0 , the coefficients are +C in the usual Taylor series order, i.e. +C P(X) = TC(1) + TC(2)*(X-C) + ... + TC(N+1)*(X-C)**N +C If L .LT. 0, the coefficients are in reverse order, +C i.e. +C P(X) = TC(1)*(X-C)**N + ... + TC(N)*(X-C) + TC(N+1) +C +C***REFERENCES L. F. Shampine, S. M. Davenport and R. E. Huddleston, +C Curve fitting by polynomials in one variable, Report +C SLA-74-0270, Sandia Laboratories, June 1974. +C***ROUTINES CALLED PVALUE +C***REVISION HISTORY (YYMMDD) +C 740601 DATE WRITTEN +C 890531 Changed all specific intrinsics to generic. (WRB) +C 890531 REVISION DATE from Version 3.2 +C 891214 Prologue converted to Version 4.0 format. (BAB) +C 920501 Reformatted the REFERENCES section. (WRB) +C***END PROLOGUE PCOEF +C + DIMENSION A(*), TC(*) +C***FIRST EXECUTABLE STATEMENT PCOEF + LL = ABS(L) + LLP1 = LL + 1 + CALL PVALUE (LL,LL,C,TC(1),TC(2),A) + IF (LL .LT. 2) GO TO 2 + FAC = 1.0 + DO 1 I = 3,LLP1 + FAC = FAC*(I-1) + 1 TC(I) = TC(I)/FAC + 2 IF (L .GE. 0) GO TO 4 + NR = LLP1/2 + LLP2 = LL + 2 + DO 3 I = 1,NR + SAVE = TC(I) + NEW = LLP2 - I + TC(I) = TC(NEW) + 3 TC(NEW) = SAVE + 4 RETURN + END +c$$$ +c$$$ subroutine dscal(n,da,dx,incx) +c$$$c +c$$$c scales a vector by a constant. +c$$$c uses unrolled loops for increment equal to one. +c$$$c jack dongarra, linpack, 3/11/78. +c$$$c modified 3/93 to return if incx .le. 0. +c$$$c +c$$$ double precision da,dx(1) +c$$$ integer i,incx,m,mp1,n,nincx +c$$$c +c$$$ if( n.le.0 .or. incx.le.0 )return +c$$$ if(incx.eq.1)go to 20 +c$$$c +c$$$c code for increment not equal to 1 +c$$$c +c$$$ nincx = n*incx +c$$$ do 10 i = 1,nincx,incx +c$$$ dx(i) = da*dx(i) +c$$$ 10 continue +c$$$ return +c$$$c +c$$$c code for increment equal to 1 +c$$$c +c$$$c +c$$$c clean-up loop +c$$$c +c$$$ 20 m = mod(n,5) +c$$$ if( m .eq. 0 ) go to 40 +c$$$ do 30 i = 1,m +c$$$ dx(i) = da*dx(i) +c$$$ 30 continue +c$$$ if( n .lt. 5 ) return +c$$$ 40 mp1 = m + 1 +c$$$ do 50 i = mp1,n,5 +c$$$ dx(i) = da*dx(i) +c$$$ dx(i + 1) = da*dx(i + 1) +c$$$ dx(i + 2) = da*dx(i + 2) +c$$$ dx(i + 3) = da*dx(i + 3) +c$$$ dx(i + 4) = da*dx(i + 4) +c$$$ 50 continue +c$$$ return +c$$$ end + + subroutine dgbco(abd,lda,n,ml,mu,ipvt,rcond,z) + integer lda,n,ml,mu,ipvt(1) + double precision abd(lda,1),z(1) + double precision rcond +c +c dgbco factors a double precision band matrix by gaussian +c elimination and estimates the condition of the matrix. +c +c if rcond is not needed, dgbfa is slightly faster. +c to solve a*x = b , follow dgbco by dgbsl. +c to compute inverse(a)*c , follow dgbco by dgbsl. +c to compute determinant(a) , follow dgbco by dgbdi. +c +c on entry +c +c abd double precision(lda, n) +c contains the matrix in band storage. the columns +c of the matrix are stored in the columns of abd and +c the diagonals of the matrix are stored in rows +c ml+1 through 2*ml+mu+1 of abd . +c see the comments below for details. +c +c lda integer +c the leading dimension of the array abd . +c lda must be .ge. 2*ml + mu + 1 . +c +c n integer +c the order of the original matrix. +c +c ml integer +c number of diagonals below the main diagonal. +c 0 .le. ml .lt. n . +c +c mu integer +c number of diagonals above the main diagonal. +c 0 .le. mu .lt. n . +c more efficient if ml .le. mu . +c +c on return +c +c abd an upper triangular matrix in band storage and +c the multipliers which were used to obtain it. +c the factorization can be written a = l*u where +c l is a product of permutation and unit lower +c triangular matrices and u is upper triangular. +c +c ipvt integer(n) +c an integer vector of pivot indices. +c +c rcond double precision +c an estimate of the reciprocal condition of a . +c for the system a*x = b , relative perturbations +c in a and b of size epsilon may cause +c relative perturbations in x of size epsilon/rcond . +c if rcond is so small that the logical expression +c 1.0 + rcond .eq. 1.0 +c is true, then a may be singular to working +c precision. in particular, rcond is zero if +c exact singularity is detected or the estimate +c underflows. +c +c z double precision(n) +c a work vector whose contents are usually unimportant. +c if a is close to a singular matrix, then z is +c an approximate null vector in the sense that +c norm(a*z) = rcond*norm(a)*norm(z) . +c +c band storage +c +c if a is a band matrix, the following program segment +c will set up the input. +c +c ml = (band width below the diagonal) +c mu = (band width above the diagonal) +c m = ml + mu + 1 +c do 20 j = 1, n +c i1 = max0(1, j-mu) +c i2 = min0(n, j+ml) +c do 10 i = i1, i2 +c k = i - j + m +c abd(k,j) = a(i,j) +c 10 continue +c 20 continue +c +c this uses rows ml+1 through 2*ml+mu+1 of abd . +c in addition, the first ml rows in abd are used for +c elements generated during the triangularization. +c the total number of rows needed in abd is 2*ml+mu+1 . +c the ml+mu by ml+mu upper left triangle and the +c ml by ml lower right triangle are not referenced. +c +c example.. if the original matrix is +c +c 11 12 13 0 0 0 +c 21 22 23 24 0 0 +c 0 32 33 34 35 0 +c 0 0 43 44 45 46 +c 0 0 0 54 55 56 +c 0 0 0 0 65 66 +c +c then n = 6, ml = 1, mu = 2, lda .ge. 5 and abd should contain +c +c * * * + + + , * = not used +c * * 13 24 35 46 , + = used for pivoting +c * 12 23 34 45 56 +c 11 22 33 44 55 66 +c 21 32 43 54 65 * +c +c linpack. this version dated 08/14/78 . +c cleve moler, university of new mexico, argonne national lab. +c +c subroutines and functions +c +c linpack dgbfa +c blas daxpy,ddot,dscal,dasum +c fortran dabs,dmax1,max0,min0,dsign +c +c internal variables +c + double precision ddot,ek,t,wk,wkm + double precision anorm,s,dasum,sm,ynorm + integer is,info,j,ju,k,kb,kp1,l,la,lm,lz,m,mm +c +c +c compute 1-norm of a +c + anorm = 0.0d0 + l = ml + 1 + is = l + mu + do 10 j = 1, n + anorm = dmax1(anorm,dasum(l,abd(is,j),1)) + if (is .gt. ml + 1) is = is - 1 + if (j .le. mu) l = l + 1 + if (j .ge. n - ml) l = l - 1 + 10 continue +c +c factor +c + call dgbfa(abd,lda,n,ml,mu,ipvt,info) +c +c rcond = 1/(norm(a)*(estimate of norm(inverse(a)))) . +c estimate = norm(z)/norm(y) where a*z = y and trans(a)*y = e . +c trans(a) is the transpose of a . the components of e are +c chosen to cause maximum local growth in the elements of w where +c trans(u)*w = e . the vectors are frequently rescaled to avoid +c overflow. +c +c solve trans(u)*w = e +c + ek = 1.0d0 + do 20 j = 1, n + z(j) = 0.0d0 + 20 continue + m = ml + mu + 1 + ju = 0 + do 100 k = 1, n + if (z(k) .ne. 0.0d0) ek = dsign(ek,-z(k)) + if (dabs(ek-z(k)) .le. dabs(abd(m,k))) go to 30 + s = dabs(abd(m,k))/dabs(ek-z(k)) + call dscal(n,s,z,1) + ek = s*ek + 30 continue + wk = ek - z(k) + wkm = -ek - z(k) + s = dabs(wk) + sm = dabs(wkm) + if (abd(m,k) .eq. 0.0d0) go to 40 + wk = wk/abd(m,k) + wkm = wkm/abd(m,k) + go to 50 + 40 continue + wk = 1.0d0 + wkm = 1.0d0 + 50 continue + kp1 = k + 1 + ju = min0(max0(ju,mu+ipvt(k)),n) + mm = m + if (kp1 .gt. ju) go to 90 + do 60 j = kp1, ju + mm = mm - 1 + sm = sm + dabs(z(j)+wkm*abd(mm,j)) + z(j) = z(j) + wk*abd(mm,j) + s = s + dabs(z(j)) + 60 continue + if (s .ge. sm) go to 80 + t = wkm - wk + wk = wkm + mm = m + do 70 j = kp1, ju + mm = mm - 1 + z(j) = z(j) + t*abd(mm,j) + 70 continue + 80 continue + 90 continue + z(k) = wk + 100 continue + s = 1.0d0/dasum(n,z,1) + call dscal(n,s,z,1) +c +c solve trans(l)*y = w +c + do 120 kb = 1, n + k = n + 1 - kb + lm = min0(ml,n-k) + if (k .lt. n) z(k) = z(k) + ddot(lm,abd(m+1,k),1,z(k+1),1) + if (dabs(z(k)) .le. 1.0d0) go to 110 + s = 1.0d0/dabs(z(k)) + call dscal(n,s,z,1) + 110 continue + l = ipvt(k) + t = z(l) + z(l) = z(k) + z(k) = t + 120 continue + s = 1.0d0/dasum(n,z,1) + call dscal(n,s,z,1) +c + ynorm = 1.0d0 +c +c solve l*v = y +c + do 140 k = 1, n + l = ipvt(k) + t = z(l) + z(l) = z(k) + z(k) = t + lm = min0(ml,n-k) + if (k .lt. n) call daxpy(lm,t,abd(m+1,k),1,z(k+1),1) + if (dabs(z(k)) .le. 1.0d0) go to 130 + s = 1.0d0/dabs(z(k)) + call dscal(n,s,z,1) + ynorm = s*ynorm + 130 continue + 140 continue + s = 1.0d0/dasum(n,z,1) + call dscal(n,s,z,1) + ynorm = s*ynorm +c +c solve u*z = w +c + do 160 kb = 1, n + k = n + 1 - kb + if (dabs(z(k)) .le. dabs(abd(m,k))) go to 150 + s = dabs(abd(m,k))/dabs(z(k)) + call dscal(n,s,z,1) + ynorm = s*ynorm + 150 continue + if (abd(m,k) .ne. 0.0d0) z(k) = z(k)/abd(m,k) + if (abd(m,k) .eq. 0.0d0) z(k) = 1.0d0 + lm = min0(k,m) - 1 + la = m - lm + lz = k - lm + t = -z(k) + call daxpy(lm,t,abd(la,k),1,z(lz),1) + 160 continue +c make znorm = 1.0 + s = 1.0d0/dasum(n,z,1) + call dscal(n,s,z,1) + ynorm = s*ynorm +c + if (anorm .ne. 0.0d0) rcond = ynorm/anorm + if (anorm .eq. 0.0d0) rcond = 0.0d0 + return + end + + subroutine dgeco(a,lda,n,ipvt,rcond,z) + integer lda,n,ipvt(1) + double precision a(lda,1),z(1) + double precision rcond +c +c dgeco factors a double precision matrix by gaussian elimination +c and estimates the condition of the matrix. +c +c if rcond is not needed, dgefa is slightly faster. +c to solve a*x = b , follow dgeco by dgesl. +c to compute inverse(a)*c , follow dgeco by dgesl. +c to compute determinant(a) , follow dgeco by dgedi. +c to compute inverse(a) , follow dgeco by dgedi. +c +c on entry +c +c a double precision(lda, n) +c the matrix to be factored. +c +c lda integer +c the leading dimension of the array a . +c +c n integer +c the order of the matrix a . +c +c on return +c +c a an upper triangular matrix and the multipliers +c which were used to obtain it. +c the factorization can be written a = l*u where +c l is a product of permutation and unit lower +c triangular matrices and u is upper triangular. +c +c ipvt integer(n) +c an integer vector of pivot indices. +c +c rcond double precision +c an estimate of the reciprocal condition of a . +c for the system a*x = b , relative perturbations +c in a and b of size epsilon may cause +c relative perturbations in x of size epsilon/rcond . +c if rcond is so small that the logical expression +c 1.0 + rcond .eq. 1.0 +c is true, then a may be singular to working +c precision. in particular, rcond is zero if +c exact singularity is detected or the estimate +c underflows. +c +c z double precision(n) +c a work vector whose contents are usually unimportant. +c if a is close to a singular matrix, then z is +c an approximate null vector in the sense that +c norm(a*z) = rcond*norm(a)*norm(z) . +c +c linpack. this version dated 08/14/78 . +c cleve moler, university of new mexico, argonne national lab. +c +c subroutines and functions +c +c linpack dgefa +c blas daxpy,ddot,dscal,dasum +c fortran dabs,dmax1,dsign +c +c internal variables +c + double precision ddot,ek,t,wk,wkm + double precision anorm,s,dasum,sm,ynorm + integer info,j,k,kb,kp1,l +c +c +c compute 1-norm of a +c + anorm = 0.0d0 + do 10 j = 1, n + anorm = dmax1(anorm,dasum(n,a(1,j),1)) + 10 continue +c +c factor +c + call dgefa(a,lda,n,ipvt,info) +c +c rcond = 1/(norm(a)*(estimate of norm(inverse(a)))) . +c estimate = norm(z)/norm(y) where a*z = y and trans(a)*y = e . +c trans(a) is the transpose of a . the components of e are +c chosen to cause maximum local growth in the elements of w where +c trans(u)*w = e . the vectors are frequently rescaled to avoid +c overflow. +c +c solve trans(u)*w = e +c + ek = 1.0d0 + do 20 j = 1, n + z(j) = 0.0d0 + 20 continue + do 100 k = 1, n + if (z(k) .ne. 0.0d0) ek = dsign(ek,-z(k)) + if (dabs(ek-z(k)) .le. dabs(a(k,k))) go to 30 + s = dabs(a(k,k))/dabs(ek-z(k)) + call dscal(n,s,z,1) + ek = s*ek + 30 continue + wk = ek - z(k) + wkm = -ek - z(k) + s = dabs(wk) + sm = dabs(wkm) + if (a(k,k) .eq. 0.0d0) go to 40 + wk = wk/a(k,k) + wkm = wkm/a(k,k) + go to 50 + 40 continue + wk = 1.0d0 + wkm = 1.0d0 + 50 continue + kp1 = k + 1 + if (kp1 .gt. n) go to 90 + do 60 j = kp1, n + sm = sm + dabs(z(j)+wkm*a(k,j)) + z(j) = z(j) + wk*a(k,j) + s = s + dabs(z(j)) + 60 continue + if (s .ge. sm) go to 80 + t = wkm - wk + wk = wkm + do 70 j = kp1, n + z(j) = z(j) + t*a(k,j) + 70 continue + 80 continue + 90 continue + z(k) = wk + 100 continue + s = 1.0d0/dasum(n,z,1) + call dscal(n,s,z,1) +c +c solve trans(l)*y = w +c + do 120 kb = 1, n + k = n + 1 - kb + if (k .lt. n) z(k) = z(k) + ddot(n-k,a(k+1,k),1,z(k+1),1) + if (dabs(z(k)) .le. 1.0d0) go to 110 + s = 1.0d0/dabs(z(k)) + call dscal(n,s,z,1) + 110 continue + l = ipvt(k) + t = z(l) + z(l) = z(k) + z(k) = t + 120 continue + s = 1.0d0/dasum(n,z,1) + call dscal(n,s,z,1) +c + ynorm = 1.0d0 +c +c solve l*v = y +c + do 140 k = 1, n + l = ipvt(k) + t = z(l) + z(l) = z(k) + z(k) = t + if (k .lt. n) call daxpy(n-k,t,a(k+1,k),1,z(k+1),1) + if (dabs(z(k)) .le. 1.0d0) go to 130 + s = 1.0d0/dabs(z(k)) + call dscal(n,s,z,1) + ynorm = s*ynorm + 130 continue + 140 continue + s = 1.0d0/dasum(n,z,1) + call dscal(n,s,z,1) + ynorm = s*ynorm +c +c solve u*z = v +c + do 160 kb = 1, n + k = n + 1 - kb + if (dabs(z(k)) .le. dabs(a(k,k))) go to 150 + s = dabs(a(k,k))/dabs(z(k)) + call dscal(n,s,z,1) + ynorm = s*ynorm + 150 continue + if (a(k,k) .ne. 0.0d0) z(k) = z(k)/a(k,k) + if (a(k,k) .eq. 0.0d0) z(k) = 1.0d0 + t = -z(k) + call daxpy(k-1,t,a(1,k),1,z(1),1) + 160 continue +c make znorm = 1.0 + s = 1.0d0/dasum(n,z,1) + call dscal(n,s,z,1) + ynorm = s*ynorm +c + if (anorm .ne. 0.0d0) rcond = ynorm/anorm + if (anorm .eq. 0.0d0) rcond = 0.0d0 + return + end + + + subroutine dgedi(a,lda,n,ipvt,det,work,job) + integer lda,n,ipvt(1),job + double precision a(lda,1),det(2),work(1) +c +c dgedi computes the determinant and inverse of a matrix +c using the factors computed by dgeco or dgefa. +c +c on entry +c +c a double precision(lda, n) +c the output from dgeco or dgefa. +c +c lda integer +c the leading dimension of the array a . +c +c n integer +c the order of the matrix a . +c +c ipvt integer(n) +c the pivot vector from dgeco or dgefa. +c +c work double precision(n) +c work vector. contents destroyed. +c +c job integer +c = 11 both determinant and inverse. +c = 01 inverse only. +c = 10 determinant only. +c +c on return +c +c a inverse of original matrix if requested. +c otherwise unchanged. +c +c det double precision(2) +c determinant of original matrix if requested. +c otherwise not referenced. +c determinant = det(1) * 10.0**det(2) +c with 1.0 .le. dabs(det(1)) .lt. 10.0 +c or det(1) .eq. 0.0 . +c +c error condition +c +c a division by zero will occur if the input factor contains +c a zero on the diagonal and the inverse is requested. +c it will not occur if the subroutines are called correctly +c and if dgeco has set rcond .gt. 0.0 or dgefa has set +c info .eq. 0 . +c +c linpack. this version dated 08/14/78 . +c cleve moler, university of new mexico, argonne national lab. +c +c subroutines and functions +c +c blas daxpy,dscal,dswap +c fortran dabs,mod +c +c internal variables +c + double precision t + double precision ten + integer i,j,k,kb,kp1,l,nm1 +c +c +c compute determinant +c + if (job/10 .eq. 0) go to 70 + det(1) = 1.0d0 + det(2) = 0.0d0 + ten = 10.0d0 + do 50 i = 1, n + if (ipvt(i) .ne. i) det(1) = -det(1) + det(1) = a(i,i)*det(1) +c ...exit + if (det(1) .eq. 0.0d0) go to 60 + 10 if (dabs(det(1)) .ge. 1.0d0) go to 20 + det(1) = ten*det(1) + det(2) = det(2) - 1.0d0 + go to 10 + 20 continue + 30 if (dabs(det(1)) .lt. ten) go to 40 + det(1) = det(1)/ten + det(2) = det(2) + 1.0d0 + go to 30 + 40 continue + 50 continue + 60 continue + 70 continue +c +c compute inverse(u) +c + if (mod(job,10) .eq. 0) go to 150 + do 100 k = 1, n + a(k,k) = 1.0d0/a(k,k) + t = -a(k,k) + call dscal(k-1,t,a(1,k),1) + kp1 = k + 1 + if (n .lt. kp1) go to 90 + do 80 j = kp1, n + t = a(k,j) + a(k,j) = 0.0d0 + call daxpy(k,t,a(1,k),1,a(1,j),1) + 80 continue + 90 continue + 100 continue +c +c form inverse(u)*inverse(l) +c + nm1 = n - 1 + if (nm1 .lt. 1) go to 140 + do 130 kb = 1, nm1 + k = n - kb + kp1 = k + 1 + do 110 i = kp1, n + work(i) = a(i,k) + a(i,k) = 0.0d0 + 110 continue + do 120 j = kp1, n + t = work(j) + call daxpy(n,t,a(1,j),1,a(1,k),1) + 120 continue + l = ipvt(k) + if (l .ne. k) call dswap(n,a(1,k),1,a(1,l),1) + 130 continue + 140 continue + 150 continue + return + end + + diff --git a/ext/math/polfit.f b/ext/math/polfit.f new file mode 100644 index 000000000..12427b1ed --- /dev/null +++ b/ext/math/polfit.f @@ -0,0 +1,352 @@ +*DECK POLFIT + SUBROUTINE POLFIT (N, X, Y, W, MAXDEG, NDEG, EPS, R, IERR, A) +C***BEGIN PROLOGUE POLFIT +C***PURPOSE Fit discrete data in a least squares sense by polynomials +C in one variable. +C***LIBRARY SLATEC +C***CATEGORY K1A1A2 +C***TYPE SINGLE PRECISION (POLFIT-S, DPOLFT-D) +C***KEYWORDS CURVE FITTING, DATA FITTING, LEAST SQUARES, POLYNOMIAL FIT +C***AUTHOR Shampine, L. F., (SNLA) +C Davenport, S. M., (SNLA) +C Huddleston, R. E., (SNLL) +C***DESCRIPTION +C +C Abstract +C +C Given a collection of points X(I) and a set of values Y(I) which +C correspond to some function or measurement at each of the X(I), +C subroutine POLFIT computes the weighted least-squares polynomial +C fits of all degrees up to some degree either specified by the user +C or determined by the routine. The fits thus obtained are in +C orthogonal polynomial form. Subroutine PVALUE may then be +C called to evaluate the fitted polynomials and any of their +C derivatives at any point. The subroutine PCOEF may be used to +C express the polynomial fits as powers of (X-C) for any specified +C point C. +C +C The parameters for POLFIT are +C +C Input -- +C N - the number of data points. The arrays X, Y and W +C must be dimensioned at least N (N .GE. 1). +C X - array of values of the independent variable. These +C values may appear in any order and need not all be +C distinct. +C Y - array of corresponding function values. +C W - array of positive values to be used as weights. If +C W(1) is negative, POLFIT will set all the weights +C to 1.0, which means unweighted least squares error +C will be minimized. To minimize relative error, the +C user should set the weights to: W(I) = 1.0/Y(I)**2, +C I = 1,...,N . +C MAXDEG - maximum degree to be allowed for polynomial fit. +C MAXDEG may be any non-negative integer less than N. +C Note -- MAXDEG cannot be equal to N-1 when a +C statistical test is to be used for degree selection, +C i.e., when input value of EPS is negative. +C EPS - specifies the criterion to be used in determining +C the degree of fit to be computed. +C (1) If EPS is input negative, POLFIT chooses the +C degree based on a statistical F test of +C significance. One of three possible +C significance levels will be used: .01, .05 or +C .10. If EPS=-1.0 , the routine will +C automatically select one of these levels based +C on the number of data points and the maximum +C degree to be considered. If EPS is input as +C -.01, -.05, or -.10, a significance level of +C .01, .05, or .10, respectively, will be used. +C (2) If EPS is set to 0., POLFIT computes the +C polynomials of degrees 0 through MAXDEG . +C (3) If EPS is input positive, EPS is the RMS +C error tolerance which must be satisfied by the +C fitted polynomial. POLFIT will increase the +C degree of fit until this criterion is met or +C until the maximum degree is reached. +C +C Output -- +C NDEG - degree of the highest degree fit computed. +C EPS - RMS error of the polynomial of degree NDEG . +C R - vector of dimension at least NDEG containing values +C of the fit of degree NDEG at each of the X(I) . +C Except when the statistical test is used, these +C values are more accurate than results from subroutine +C PVALUE normally are. +C IERR - error flag with the following possible values. +C 1 -- indicates normal execution, i.e., either +C (1) the input value of EPS was negative, and the +C computed polynomial fit of degree NDEG +C satisfies the specified F test, or +C (2) the input value of EPS was 0., and the fits of +C all degrees up to MAXDEG are complete, or +C (3) the input value of EPS was positive, and the +C polynomial of degree NDEG satisfies the RMS +C error requirement. +C 2 -- invalid input parameter. At least one of the input +C parameters has an illegal value and must be corrected +C before POLFIT can proceed. Valid input results +C when the following restrictions are observed +C N .GE. 1 +C 0 .LE. MAXDEG .LE. N-1 for EPS .GE. 0. +C 0 .LE. MAXDEG .LE. N-2 for EPS .LT. 0. +C W(1)=-1.0 or W(I) .GT. 0., I=1,...,N . +C 3 -- cannot satisfy the RMS error requirement with a +C polynomial of degree no greater than MAXDEG . Best +C fit found is of degree MAXDEG . +C 4 -- cannot satisfy the test for significance using +C current value of MAXDEG . Statistically, the +C best fit found is of order NORD . (In this case, +C NDEG will have one of the values: MAXDEG-2, +C MAXDEG-1, or MAXDEG). Using a higher value of +C MAXDEG may result in passing the test. +C A - work and output array having at least 3N+3MAXDEG+3 +C locations +C +C Note - POLFIT calculates all fits of degrees up to and including +C NDEG . Any or all of these fits can be evaluated or +C expressed as powers of (X-C) using PVALUE and PCOEF +C after just one call to POLFIT . +C +C***REFERENCES L. F. Shampine, S. M. Davenport and R. E. Huddleston, +C Curve fitting by polynomials in one variable, Report +C SLA-74-0270, Sandia Laboratories, June 1974. +C***ROUTINES CALLED PVALUE, XERMSG +C***REVISION HISTORY (YYMMDD) +C 740601 DATE WRITTEN +C 890531 Changed all specific intrinsics to generic. (WRB) +C 890531 REVISION DATE from Version 3.2 +C 891214 Prologue converted to Version 4.0 format. (BAB) +C 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ) +C 920501 Reformatted the REFERENCES section. (WRB) +C 920527 Corrected erroneous statements in DESCRIPTION. (WRB) +C***END PROLOGUE POLFIT + DOUBLE PRECISION TEMD1,TEMD2 + DIMENSION X(*), Y(*), W(*), R(*), A(*) + DIMENSION CO(4,3) + SAVE CO + DATA CO(1,1), CO(2,1), CO(3,1), CO(4,1), CO(1,2), CO(2,2), + 1 CO(3,2), CO(4,2), CO(1,3), CO(2,3), CO(3,3), + 2 CO(4,3)/-13.086850,-2.4648165,-3.3846535,-1.2973162, + 3 -3.3381146,-1.7812271,-3.2578406,-1.6589279, + 4 -1.6282703,-1.3152745,-3.2640179,-1.9829776/ +C***FIRST EXECUTABLE STATEMENT POLFIT + M = ABS(N) + IF (M .EQ. 0) GO TO 30 + IF (MAXDEG .LT. 0) GO TO 30 + A(1) = MAXDEG + MOP1 = MAXDEG + 1 + IF (M .LT. MOP1) GO TO 30 + IF (EPS .LT. 0.0 .AND. M .EQ. MOP1) GO TO 30 + XM = M + ETST = EPS*EPS*XM + IF (W(1) .LT. 0.0) GO TO 2 + DO 1 I = 1,M + IF (W(I) .LE. 0.0) GO TO 30 + 1 CONTINUE + GO TO 4 + 2 DO 3 I = 1,M + 3 W(I) = 1.0 + 4 IF (EPS .GE. 0.0) GO TO 8 +C +C DETERMINE SIGNIFICANCE LEVEL INDEX TO BE USED IN STATISTICAL TEST FOR +C CHOOSING DEGREE OF POLYNOMIAL FIT +C + IF (EPS .GT. (-.55)) GO TO 5 + IDEGF = M - MAXDEG - 1 + KSIG = 1 + IF (IDEGF .LT. 10) KSIG = 2 + IF (IDEGF .LT. 5) KSIG = 3 + GO TO 8 + 5 KSIG = 1 + IF (EPS .LT. (-.03)) KSIG = 2 + IF (EPS .LT. (-.07)) KSIG = 3 +C +C INITIALIZE INDEXES AND COEFFICIENTS FOR FITTING +C + 8 K1 = MAXDEG + 1 + K2 = K1 + MAXDEG + K3 = K2 + MAXDEG + 2 + K4 = K3 + M + K5 = K4 + M + DO 9 I = 2,K4 + 9 A(I) = 0.0 + W11 = 0.0 + IF (N .LT. 0) GO TO 11 +C +C UNCONSTRAINED CASE +C + DO 10 I = 1,M + K4PI = K4 + I + A(K4PI) = 1.0 + 10 W11 = W11 + W(I) + GO TO 13 +C +C CONSTRAINED CASE +C + 11 DO 12 I = 1,M + K4PI = K4 + I + 12 W11 = W11 + W(I)*A(K4PI)**2 +C +C COMPUTE FIT OF DEGREE ZERO +C + 13 TEMD1 = 0.0D0 + DO 14 I = 1,M + K4PI = K4 + I + TEMD1 = TEMD1 + DBLE(W(I))*DBLE(Y(I))*DBLE(A(K4PI)) + 14 CONTINUE + TEMD1 = TEMD1/DBLE(W11) + A(K2+1) = TEMD1 + SIGJ = 0.0 + DO 15 I = 1,M + K4PI = K4 + I + K5PI = K5 + I + TEMD2 = TEMD1*DBLE(A(K4PI)) + R(I) = TEMD2 + A(K5PI) = TEMD2 - DBLE(R(I)) + 15 SIGJ = SIGJ + W(I)*((Y(I)-R(I)) - A(K5PI))**2 + J = 0 +C +C SEE IF POLYNOMIAL OF DEGREE 0 SATISFIES THE DEGREE SELECTION CRITERION +C + IF (EPS) 24,26,27 +C +C INCREMENT DEGREE +C + 16 J = J + 1 + JP1 = J + 1 + K1PJ = K1 + J + K2PJ = K2 + J + SIGJM1 = SIGJ +C +C COMPUTE NEW B COEFFICIENT EXCEPT WHEN J = 1 +C + IF (J .GT. 1) A(K1PJ) = W11/W1 +C +C COMPUTE NEW A COEFFICIENT +C + TEMD1 = 0.0D0 + DO 18 I = 1,M + K4PI = K4 + I + TEMD2 = A(K4PI) + TEMD1 = TEMD1 + DBLE(X(I))*DBLE(W(I))*TEMD2*TEMD2 + 18 CONTINUE + A(JP1) = TEMD1/DBLE(W11) +C +C EVALUATE ORTHOGONAL POLYNOMIAL AT DATA POINTS +C + W1 = W11 + W11 = 0.0 + DO 19 I = 1,M + K3PI = K3 + I + K4PI = K4 + I + TEMP = A(K3PI) + A(K3PI) = A(K4PI) + A(K4PI) = (X(I)-A(JP1))*A(K3PI) - A(K1PJ)*TEMP + 19 W11 = W11 + W(I)*A(K4PI)**2 +C +C GET NEW ORTHOGONAL POLYNOMIAL COEFFICIENT USING PARTIAL DOUBLE +C PRECISION +C + TEMD1 = 0.0D0 + DO 20 I = 1,M + K4PI = K4 + I + K5PI = K5 + I + TEMD2 = DBLE(W(I))*DBLE((Y(I)-R(I))-A(K5PI))*DBLE(A(K4PI)) + 20 TEMD1 = TEMD1 + TEMD2 + TEMD1 = TEMD1/DBLE(W11) + A(K2PJ+1) = TEMD1 +C +C UPDATE POLYNOMIAL EVALUATIONS AT EACH OF THE DATA POINTS, AND +C ACCUMULATE SUM OF SQUARES OF ERRORS. THE POLYNOMIAL EVALUATIONS ARE +C COMPUTED AND STORED IN EXTENDED PRECISION. FOR THE I-TH DATA POINT, +C THE MOST SIGNIFICANT BITS ARE STORED IN R(I) , AND THE LEAST +C SIGNIFICANT BITS ARE IN A(K5PI) . +C + SIGJ = 0.0 + DO 21 I = 1,M + K4PI = K4 + I + K5PI = K5 + I + TEMD2 = DBLE(R(I)) + DBLE(A(K5PI)) + TEMD1*DBLE(A(K4PI)) + R(I) = TEMD2 + A(K5PI) = TEMD2 - DBLE(R(I)) + 21 SIGJ = SIGJ + W(I)*((Y(I)-R(I)) - A(K5PI))**2 +C +C SEE IF DEGREE SELECTION CRITERION HAS BEEN SATISFIED OR IF DEGREE +C MAXDEG HAS BEEN REACHED +C + IF (EPS) 23,26,27 +C +C COMPUTE F STATISTICS (INPUT EPS .LT. 0.) +C + 23 IF (SIGJ .EQ. 0.0) GO TO 29 + DEGF = M - J - 1 + DEN = (CO(4,KSIG)*DEGF + 1.0)*DEGF + FCRIT = (((CO(3,KSIG)*DEGF) + CO(2,KSIG))*DEGF + CO(1,KSIG))/DEN + FCRIT = FCRIT*FCRIT + F = (SIGJM1 - SIGJ)*DEGF/SIGJ + IF (F .LT. FCRIT) GO TO 25 +C +C POLYNOMIAL OF DEGREE J SATISFIES F TEST +C + 24 SIGPAS = SIGJ + JPAS = J + NFAIL = 0 + IF (MAXDEG .EQ. J) GO TO 32 + GO TO 16 +C +C POLYNOMIAL OF DEGREE J FAILS F TEST. IF THERE HAVE BEEN THREE +C SUCCESSIVE FAILURES, A STATISTICALLY BEST DEGREE HAS BEEN FOUND. +C + 25 NFAIL = NFAIL + 1 + IF (NFAIL .GE. 3) GO TO 29 + IF (MAXDEG .EQ. J) GO TO 32 + GO TO 16 +C +C RAISE THE DEGREE IF DEGREE MAXDEG HAS NOT YET BEEN REACHED (INPUT +C EPS = 0.) +C + 26 IF (MAXDEG .EQ. J) GO TO 28 + GO TO 16 +C +C SEE IF RMS ERROR CRITERION IS SATISFIED (INPUT EPS .GT. 0.) +C + 27 IF (SIGJ .LE. ETST) GO TO 28 + IF (MAXDEG .EQ. J) GO TO 31 + GO TO 16 +C +C RETURNS +C + 28 IERR = 1 + NDEG = J + SIG = SIGJ + GO TO 33 + 29 IERR = 1 + NDEG = JPAS + SIG = SIGPAS + GO TO 33 + 30 IERR = 2 + CALL XERMSG ('SLATEC', 'POLFIT', 'INVALID INPUT PARAMETER.', 2, + + 1) + GO TO 37 + 31 IERR = 3 + NDEG = MAXDEG + SIG = SIGJ + GO TO 33 + 32 IERR = 4 + NDEG = JPAS + SIG = SIGPAS +C + 33 A(K3) = NDEG +C +C WHEN STATISTICAL TEST HAS BEEN USED, EVALUATE THE BEST POLYNOMIAL AT +C ALL THE DATA POINTS IF R DOES NOT ALREADY CONTAIN THESE VALUES +C + IF(EPS .GE. 0.0 .OR. NDEG .EQ. MAXDEG) GO TO 36 + NDER = 0 + DO 35 I = 1,M + CALL PVALUE (NDEG,NDER,X(I),R(I),YP,A) + 35 CONTINUE + 36 EPS = SQRT(SIG/XM) + 37 RETURN + END diff --git a/ext/math/pvalue.f b/ext/math/pvalue.f new file mode 100644 index 000000000..d20cb7862 --- /dev/null +++ b/ext/math/pvalue.f @@ -0,0 +1,148 @@ +*DECK PVALUE + SUBROUTINE PVALUE (L, NDER, X, YFIT, YP, A) +C***BEGIN PROLOGUE PVALUE +C***PURPOSE Use the coefficients generated by POLFIT to evaluate the +C polynomial fit of degree L, along with the first NDER of +C its derivatives, at a specified point. +C***LIBRARY SLATEC +C***CATEGORY K6 +C***TYPE SINGLE PRECISION (PVALUE-S, DP1VLU-D) +C***KEYWORDS CURVE FITTING, LEAST SQUARES, POLYNOMIAL APPROXIMATION +C***AUTHOR Shampine, L. F., (SNLA) +C Davenport, S. M., (SNLA) +C***DESCRIPTION +C +C Written by L. F. Shampine and S. M. Davenport. +C +C Abstract +C +C The subroutine PVALUE uses the coefficients generated by POLFIT +C to evaluate the polynomial fit of degree L , along with the first +C NDER of its derivatives, at a specified point. Computationally +C stable recurrence relations are used to perform this task. +C +C The parameters for PVALUE are +C +C Input -- +C L - the degree of polynomial to be evaluated. L may be +C any non-negative integer which is less than or equal +C to NDEG , the highest degree polynomial provided +C by POLFIT . +C NDER - the number of derivatives to be evaluated. NDER +C may be 0 or any positive value. If NDER is less +C than 0, it will be treated as 0. +C X - the argument at which the polynomial and its +C derivatives are to be evaluated. +C A - work and output array containing values from last +C call to POLFIT . +C +C Output -- +C YFIT - value of the fitting polynomial of degree L at X +C YP - array containing the first through NDER derivatives +C of the polynomial of degree L . YP must be +C dimensioned at least NDER in the calling program. +C +C***REFERENCES L. F. Shampine, S. M. Davenport and R. E. Huddleston, +C Curve fitting by polynomials in one variable, Report +C SLA-74-0270, Sandia Laboratories, June 1974. +C***ROUTINES CALLED XERMSG +C***REVISION HISTORY (YYMMDD) +C 740601 DATE WRITTEN +C 890531 Changed all specific intrinsics to generic. (WRB) +C 890531 REVISION DATE from Version 3.2 +C 891214 Prologue converted to Version 4.0 format. (BAB) +C 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ) +C 900510 Convert XERRWV calls to XERMSG calls. (RWC) +C 920501 Reformatted the REFERENCES section. (WRB) +C***END PROLOGUE PVALUE + DIMENSION YP(*),A(*) + CHARACTER*8 XERN1, XERN2 +C***FIRST EXECUTABLE STATEMENT PVALUE + IF (L .LT. 0) GO TO 12 + NDO = MAX(NDER,0) + NDO = MIN(NDO,L) + MAXORD = A(1) + 0.5 + K1 = MAXORD + 1 + K2 = K1 + MAXORD + K3 = K2 + MAXORD + 2 + NORD = A(K3) + 0.5 + IF (L .GT. NORD) GO TO 11 + K4 = K3 + L + 1 + IF (NDER .LT. 1) GO TO 2 + DO 1 I = 1,NDER + 1 YP(I) = 0.0 + 2 IF (L .GE. 2) GO TO 4 + IF (L .EQ. 1) GO TO 3 +C +C L IS 0 +C + VAL = A(K2+1) + GO TO 10 +C +C L IS 1 +C + 3 CC = A(K2+2) + VAL = A(K2+1) + (X-A(2))*CC + IF (NDER .GE. 1) YP(1) = CC + GO TO 10 +C +C L IS GREATER THAN 1 +C + 4 NDP1 = NDO + 1 + K3P1 = K3 + 1 + K4P1 = K4 + 1 + LP1 = L + 1 + LM1 = L - 1 + ILO = K3 + 3 + IUP = K4 + NDP1 + DO 5 I = ILO,IUP + 5 A(I) = 0.0 + DIF = X - A(LP1) + KC = K2 + LP1 + A(K4P1) = A(KC) + A(K3P1) = A(KC-1) + DIF*A(K4P1) + A(K3+2) = A(K4P1) +C +C EVALUATE RECURRENCE RELATIONS FOR FUNCTION VALUE AND DERIVATIVES +C + DO 9 I = 1,LM1 + IN = L - I + INP1 = IN + 1 + K1I = K1 + INP1 + IC = K2 + IN + DIF = X - A(INP1) + VAL = A(IC) + DIF*A(K3P1) - A(K1I)*A(K4P1) + IF (NDO .LE. 0) GO TO 8 + DO 6 N = 1,NDO + K3PN = K3P1 + N + K4PN = K4P1 + N + 6 YP(N) = DIF*A(K3PN) + N*A(K3PN-1) - A(K1I)*A(K4PN) +C +C SAVE VALUES NEEDED FOR NEXT EVALUATION OF RECURRENCE RELATIONS +C + DO 7 N = 1,NDO + K3PN = K3P1 + N + K4PN = K4P1 + N + A(K4PN) = A(K3PN) + 7 A(K3PN) = YP(N) + 8 A(K4P1) = A(K3P1) + 9 A(K3P1) = VAL +C +C NORMAL RETURN OR ABORT DUE TO ERROR +C + 10 YFIT = VAL + RETURN +C + 11 WRITE (XERN1, '(I8)') L + WRITE (XERN2, '(I8)') NORD + CALL XERMSG ('SLATEC', 'PVALUE', + * 'THE ORDER OF POLYNOMIAL EVALUATION, L = ' // XERN1 // + * ' REQUESTED EXCEEDS THE HIGHEST ORDER FIT, NORD = ' // XERN2 // + * ', COMPUTED BY POLFIT -- EXECUTION TERMINATED.', 8, 2) + RETURN +C + 12 CALL XERMSG ('SLATEC', 'PVALUE', + + 'INVALID INPUT PARAMETER. ORDER OF POLYNOMIAL EVALUATION ' // + + 'REQUESTED IS NEGATIVE -- EXECUTION TERMINATED.', 2, 2) + RETURN + END diff --git a/ext/math/xercnt.f b/ext/math/xercnt.f new file mode 100644 index 000000000..06c82ab18 --- /dev/null +++ b/ext/math/xercnt.f @@ -0,0 +1,60 @@ +*DECK XERCNT + SUBROUTINE XERCNT (LIBRAR, SUBROU, MESSG, NERR, LEVEL, KONTRL) +C***BEGIN PROLOGUE XERCNT +C***SUBSIDIARY +C***PURPOSE Allow user control over handling of errors. +C***LIBRARY SLATEC (XERROR) +C***CATEGORY R3C +C***TYPE ALL (XERCNT-A) +C***KEYWORDS ERROR, XERROR +C***AUTHOR Jones, R. E., (SNLA) +C***DESCRIPTION +C +C Abstract +C Allows user control over handling of individual errors. +C Just after each message is recorded, but before it is +C processed any further (i.e., before it is printed or +C a decision to abort is made), a call is made to XERCNT. +C If the user has provided his own version of XERCNT, he +C can then override the value of KONTROL used in processing +C this message by redefining its value. +C KONTRL may be set to any value from -2 to 2. +C The meanings for KONTRL are the same as in XSETF, except +C that the value of KONTRL changes only for this message. +C If KONTRL is set to a value outside the range from -2 to 2, +C it will be moved back into that range. +C +C Description of Parameters +C +C --Input-- +C LIBRAR - the library that the routine is in. +C SUBROU - the subroutine that XERMSG is being called from +C MESSG - the first 20 characters of the error message. +C NERR - same as in the call to XERMSG. +C LEVEL - same as in the call to XERMSG. +C KONTRL - the current value of the control flag as set +C by a call to XSETF. +C +C --Output-- +C KONTRL - the new value of KONTRL. If KONTRL is not +C defined, it will remain at its original value. +C This changed value of control affects only +C the current occurrence of the current message. +C +C***REFERENCES R. E. Jones and D. K. Kahaner, XERROR, the SLATEC +C Error-handling Package, SAND82-0800, Sandia +C Laboratories, 1982. +C***ROUTINES CALLED (NONE) +C***REVISION HISTORY (YYMMDD) +C 790801 DATE WRITTEN +C 861211 REVISION DATE from Version 3.2 +C 891214 Prologue converted to Version 4.0 format. (BAB) +C 900206 Routine changed from user-callable to subsidiary. (WRB) +C 900510 Changed calling sequence to include LIBRARY and SUBROUTINE +C names, changed routine name from XERCTL to XERCNT. (RWC) +C 920501 Reformatted the REFERENCES section. (WRB) +C***END PROLOGUE XERCNT + CHARACTER*(*) LIBRAR, SUBROU, MESSG +C***FIRST EXECUTABLE STATEMENT XERCNT + RETURN + END diff --git a/ext/math/xerhlt.f b/ext/math/xerhlt.f new file mode 100644 index 000000000..052092940 --- /dev/null +++ b/ext/math/xerhlt.f @@ -0,0 +1,40 @@ +*DECK XERHLT + SUBROUTINE XERHLT (MESSG) +C***BEGIN PROLOGUE XERHLT +C***SUBSIDIARY +C***PURPOSE Abort program execution and print error message. +C***LIBRARY SLATEC (XERROR) +C***CATEGORY R3C +C***TYPE ALL (XERHLT-A) +C***KEYWORDS ABORT PROGRAM EXECUTION, ERROR, XERROR +C***AUTHOR Jones, R. E., (SNLA) +C***DESCRIPTION +C +C Abstract +C ***Note*** machine dependent routine +C XERHLT aborts the execution of the program. +C The error message causing the abort is given in the calling +C sequence, in case one needs it for printing on a dayfile, +C for example. +C +C Description of Parameters +C MESSG is as in XERMSG. +C +C***REFERENCES R. E. Jones and D. K. Kahaner, XERROR, the SLATEC +C Error-handling Package, SAND82-0800, Sandia +C Laboratories, 1982. +C***ROUTINES CALLED (NONE) +C***REVISION HISTORY (YYMMDD) +C 790801 DATE WRITTEN +C 861211 REVISION DATE from Version 3.2 +C 891214 Prologue converted to Version 4.0 format. (BAB) +C 900206 Routine changed from user-callable to subsidiary. (WRB) +C 900510 Changed calling sequence to delete length of character +C and changed routine name from XERABT to XERHLT. (RWC) +C 920501 Reformatted the REFERENCES section. (WRB) +C***END PROLOGUE XERHLT + CHARACTER*(*) MESSG +C***FIRST EXECUTABLE STATEMENT XERHLT + write(*,*) 'stopping...' + STOP + END diff --git a/ext/math/xermsg.f b/ext/math/xermsg.f new file mode 100755 index 000000000..46c83ec07 --- /dev/null +++ b/ext/math/xermsg.f @@ -0,0 +1,364 @@ +*DECK XERMSG + SUBROUTINE XERMSG (LIBRAR, SUBROU, MESSG, NERR, LEVEL) +C***BEGIN PROLOGUE XERMSG +C***PURPOSE Process error messages for SLATEC and other libraries. +C***LIBRARY SLATEC (XERROR) +C***CATEGORY R3C +C***TYPE ALL (XERMSG-A) +C***KEYWORDS ERROR MESSAGE, XERROR +C***AUTHOR Fong, Kirby, (NMFECC at LLNL) +C***DESCRIPTION +C +C XERMSG processes a diagnostic message in a manner determined by the +C value of LEVEL and the current value of the library error control +C flag, KONTRL. See subroutine XSETF for details. +C +C LIBRAR A character constant (or character variable) with the name +C of the library. This will be 'SLATEC' for the SLATEC +C Common Math Library. The error handling package is +C general enough to be used by many libraries +C simultaneously, so it is desirable for the routine that +C detects and reports an error to identify the library name +C as well as the routine name. +C +C SUBROU A character constant (or character variable) with the name +C of the routine that detected the error. Usually it is the +C name of the routine that is calling XERMSG. There are +C some instances where a user callable library routine calls +C lower level subsidiary routines where the error is +C detected. In such cases it may be more informative to +C supply the name of the routine the user called rather than +C the name of the subsidiary routine that detected the +C error. +C +C MESSG A character constant (or character variable) with the text +C of the error or warning message. In the example below, +C the message is a character constant that contains a +C generic message. +C +C CALL XERMSG ('SLATEC', 'MMPY', +C *'THE ORDER OF THE MATRIX EXCEEDS THE ROW DIMENSION', +C *3, 1) +C +C It is possible (and is sometimes desirable) to generate a +C specific message--e.g., one that contains actual numeric +C values. Specific numeric values can be converted into +C character strings using formatted WRITE statements into +C character variables. This is called standard Fortran +C internal file I/O and is exemplified in the first three +C lines of the following example. You can also catenate +C substrings of characters to construct the error message. +C Here is an example showing the use of both writing to +C an internal file and catenating character strings. +C +C CHARACTER*5 CHARN, CHARL +C WRITE (CHARN,10) N +C WRITE (CHARL,10) LDA +C 10 FORMAT(I5) +C CALL XERMSG ('SLATEC', 'MMPY', 'THE ORDER'//CHARN// +C * ' OF THE MATRIX EXCEEDS ITS ROW DIMENSION OF'// +C * CHARL, 3, 1) +C +C There are two subtleties worth mentioning. One is that +C the // for character catenation is used to construct the +C error message so that no single character constant is +C continued to the next line. This avoids confusion as to +C whether there are trailing blanks at the end of the line. +C The second is that by catenating the parts of the message +C as an actual argument rather than encoding the entire +C message into one large character variable, we avoid +C having to know how long the message will be in order to +C declare an adequate length for that large character +C variable. XERMSG calls XERPRN to print the message using +C multiple lines if necessary. If the message is very long, +C XERPRN will break it into pieces of 72 characters (as +C requested by XERMSG) for printing on multiple lines. +C Also, XERMSG asks XERPRN to prefix each line with ' * ' +C so that the total line length could be 76 characters. +C Note also that XERPRN scans the error message backwards +C to ignore trailing blanks. Another feature is that +C the substring '$$' is treated as a new line sentinel +C by XERPRN. If you want to construct a multiline +C message without having to count out multiples of 72 +C characters, just use '$$' as a separator. '$$' +C obviously must occur within 72 characters of the +C start of each line to have its intended effect since +C XERPRN is asked to wrap around at 72 characters in +C addition to looking for '$$'. +C +C NERR An integer value that is chosen by the library routine's +C author. It must be in the range -99 to 999 (three +C printable digits). Each distinct error should have its +C own error number. These error numbers should be described +C in the machine readable documentation for the routine. +C The error numbers need be unique only within each routine, +C so it is reasonable for each routine to start enumerating +C errors from 1 and proceeding to the next integer. +C +C LEVEL An integer value in the range 0 to 2 that indicates the +C level (severity) of the error. Their meanings are +C +C -1 A warning message. This is used if it is not clear +C that there really is an error, but the user's attention +C may be needed. An attempt is made to only print this +C message once. +C +C 0 A warning message. This is used if it is not clear +C that there really is an error, but the user's attention +C may be needed. +C +C 1 A recoverable error. This is used even if the error is +C so serious that the routine cannot return any useful +C answer. If the user has told the error package to +C return after recoverable errors, then XERMSG will +C return to the Library routine which can then return to +C the user's routine. The user may also permit the error +C package to terminate the program upon encountering a +C recoverable error. +C +C 2 A fatal error. XERMSG will not return to its caller +C after it receives a fatal error. This level should +C hardly ever be used; it is much better to allow the +C user a chance to recover. An example of one of the few +C cases in which it is permissible to declare a level 2 +C error is a reverse communication Library routine that +C is likely to be called repeatedly until it integrates +C across some interval. If there is a serious error in +C the input such that another step cannot be taken and +C the Library routine is called again without the input +C error having been corrected by the caller, the Library +C routine will probably be called forever with improper +C input. In this case, it is reasonable to declare the +C error to be fatal. +C +C Each of the arguments to XERMSG is input; none will be modified by +C XERMSG. A routine may make multiple calls to XERMSG with warning +C level messages; however, after a call to XERMSG with a recoverable +C error, the routine should return to the user. Do not try to call +C XERMSG with a second recoverable error after the first recoverable +C error because the error package saves the error number. The user +C can retrieve this error number by calling another entry point in +C the error handling package and then clear the error number when +C recovering from the error. Calling XERMSG in succession causes the +C old error number to be overwritten by the latest error number. +C This is considered harmless for error numbers associated with +C warning messages but must not be done for error numbers of serious +C errors. After a call to XERMSG with a recoverable error, the user +C must be given a chance to call NUMXER or XERCLR to retrieve or +C clear the error number. +C***REFERENCES R. E. Jones and D. K. Kahaner, XERROR, the SLATEC +C Error-handling Package, SAND82-0800, Sandia +C Laboratories, 1982. +C***ROUTINES CALLED FDUMP, J4SAVE, XERCNT, XERHLT, XERPRN, XERSVE +C***REVISION HISTORY (YYMMDD) +C 880101 DATE WRITTEN +C 880621 REVISED AS DIRECTED AT SLATEC CML MEETING OF FEBRUARY 1988. +C THERE ARE TWO BASIC CHANGES. +C 1. A NEW ROUTINE, XERPRN, IS USED INSTEAD OF XERPRT TO +C PRINT MESSAGES. THIS ROUTINE WILL BREAK LONG MESSAGES +C INTO PIECES FOR PRINTING ON MULTIPLE LINES. '$$' IS +C ACCEPTED AS A NEW LINE SENTINEL. A PREFIX CAN BE +C ADDED TO EACH LINE TO BE PRINTED. XERMSG USES EITHER +C ' ***' OR ' * ' AND LONG MESSAGES ARE BROKEN EVERY +C 72 CHARACTERS (AT MOST) SO THAT THE MAXIMUM LINE +C LENGTH OUTPUT CAN NOW BE AS GREAT AS 76. +C 2. THE TEXT OF ALL MESSAGES IS NOW IN UPPER CASE SINCE THE +C FORTRAN STANDARD DOCUMENT DOES NOT ADMIT THE EXISTENCE +C OF LOWER CASE. +C 880708 REVISED AFTER THE SLATEC CML MEETING OF JUNE 29 AND 30. +C THE PRINCIPAL CHANGES ARE +C 1. CLARIFY COMMENTS IN THE PROLOGUES +C 2. RENAME XRPRNT TO XERPRN +C 3. REWORK HANDLING OF '$$' IN XERPRN TO HANDLE BLANK LINES +C SIMILAR TO THE WAY FORMAT STATEMENTS HANDLE THE / +C CHARACTER FOR NEW RECORDS. +C 890706 REVISED WITH THE HELP OF FRED FRITSCH AND REG CLEMENS TO +C CLEAN UP THE CODING. +C 890721 REVISED TO USE NEW FEATURE IN XERPRN TO COUNT CHARACTERS IN +C PREFIX. +C 891013 REVISED TO CORRECT COMMENTS. +C 891214 Prologue converted to Version 4.0 format. (WRB) +C 900510 Changed test on NERR to be -9999999 < NERR < 99999999, but +C NERR .ne. 0, and on LEVEL to be -2 < LEVEL < 3. Added +C LEVEL=-1 logic, changed calls to XERSAV to XERSVE, and +C XERCTL to XERCNT. (RWC) +C 920501 Reformatted the REFERENCES section. (WRB) +C***END PROLOGUE XERMSG + CHARACTER*(*) LIBRAR, SUBROU, MESSG + CHARACTER*8 XLIBR, XSUBR + CHARACTER*72 TEMP + CHARACTER*20 LFIRST +C***FIRST EXECUTABLE STATEMENT XERMSG + LKNTRL = J4SAVE (2, 0, .FALSE.) + MAXMES = J4SAVE (4, 0, .FALSE.) +C +C LKNTRL IS A LOCAL COPY OF THE CONTROL FLAG KONTRL. +C MAXMES IS THE MAXIMUM NUMBER OF TIMES ANY PARTICULAR MESSAGE +C SHOULD BE PRINTED. +C +C WE PRINT A FATAL ERROR MESSAGE AND TERMINATE FOR AN ERROR IN +C CALLING XERMSG. THE ERROR NUMBER SHOULD BE POSITIVE, +C AND THE LEVEL SHOULD BE BETWEEN 0 AND 2. +C + IF (NERR.LT.-9999999 .OR. NERR.GT.99999999 .OR. NERR.EQ.0 .OR. + * LEVEL.LT.-1 .OR. LEVEL.GT.2) THEN + CALL XERPRN (' ***', -1, 'FATAL ERROR IN...$$ ' // + * 'XERMSG -- INVALID ERROR NUMBER OR LEVEL$$ '// + * 'JOB ABORT DUE TO FATAL ERROR.', 72) + CALL XERSVE (' ', ' ', ' ', 0, 0, 0, KDUMMY) + CALL XERHLT (' ***XERMSG -- INVALID INPUT') + RETURN + ENDIF +C +C RECORD THE MESSAGE. +C + I = J4SAVE (1, NERR, .TRUE.) + CALL XERSVE (LIBRAR, SUBROU, MESSG, 1, NERR, LEVEL, KOUNT) +C +C HANDLE PRINT-ONCE WARNING MESSAGES. +C + IF (LEVEL.EQ.-1 .AND. KOUNT.GT.1) RETURN +C +C ALLOW TEMPORARY USER OVERRIDE OF THE CONTROL FLAG. +C + XLIBR = LIBRAR + XSUBR = SUBROU + LFIRST = MESSG + LERR = NERR + LLEVEL = LEVEL + CALL XERCNT (XLIBR, XSUBR, LFIRST, LERR, LLEVEL, LKNTRL) +C + LKNTRL = MAX(-2, MIN(2,LKNTRL)) + MKNTRL = ABS(LKNTRL) +C +C SKIP PRINTING IF THE CONTROL FLAG VALUE AS RESET IN XERCNT IS +C ZERO AND THE ERROR IS NOT FATAL. +C + IF (LEVEL.LT.2 .AND. LKNTRL.EQ.0) GO TO 30 + IF (LEVEL.EQ.0 .AND. KOUNT.GT.MAXMES) GO TO 30 + IF (LEVEL.EQ.1 .AND. KOUNT.GT.MAXMES .AND. MKNTRL.EQ.1) GO TO 30 + IF (LEVEL.EQ.2 .AND. KOUNT.GT.MAX(1,MAXMES)) GO TO 30 +C +C ANNOUNCE THE NAMES OF THE LIBRARY AND SUBROUTINE BY BUILDING A +C MESSAGE IN CHARACTER VARIABLE TEMP (NOT EXCEEDING 66 CHARACTERS) +C AND SENDING IT OUT VIA XERPRN. PRINT ONLY IF CONTROL FLAG +C IS NOT ZERO. +C + IF (LKNTRL .NE. 0) THEN + TEMP(1:21) = 'MESSAGE FROM ROUTINE ' + I = MIN(LEN(SUBROU), 16) + TEMP(22:21+I) = SUBROU(1:I) + TEMP(22+I:33+I) = ' IN LIBRARY ' + LTEMP = 33 + I + I = MIN(LEN(LIBRAR), 16) + TEMP(LTEMP+1:LTEMP+I) = LIBRAR (1:I) + TEMP(LTEMP+I+1:LTEMP+I+1) = '.' + LTEMP = LTEMP + I + 1 + CALL XERPRN (' ***', -1, TEMP(1:LTEMP), 72) + ENDIF +C +C IF LKNTRL IS POSITIVE, PRINT AN INTRODUCTORY LINE BEFORE +C PRINTING THE MESSAGE. THE INTRODUCTORY LINE TELLS THE CHOICE +C FROM EACH OF THE FOLLOWING THREE OPTIONS. +C 1. LEVEL OF THE MESSAGE +C 'INFORMATIVE MESSAGE' +C 'POTENTIALLY RECOVERABLE ERROR' +C 'FATAL ERROR' +C 2. WHETHER CONTROL FLAG WILL ALLOW PROGRAM TO CONTINUE +C 'PROG CONTINUES' +C 'PROG ABORTED' +C 3. WHETHER OR NOT A TRACEBACK WAS REQUESTED. (THE TRACEBACK +C MAY NOT BE IMPLEMENTED AT SOME SITES, SO THIS ONLY TELLS +C WHAT WAS REQUESTED, NOT WHAT WAS DELIVERED.) +C 'TRACEBACK REQUESTED' +C 'TRACEBACK NOT REQUESTED' +C NOTICE THAT THE LINE INCLUDING FOUR PREFIX CHARACTERS WILL NOT +C EXCEED 74 CHARACTERS. +C WE SKIP THE NEXT BLOCK IF THE INTRODUCTORY LINE IS NOT NEEDED. +C + IF (LKNTRL .GT. 0) THEN +C +C THE FIRST PART OF THE MESSAGE TELLS ABOUT THE LEVEL. +C + IF (LEVEL .LE. 0) THEN + TEMP(1:20) = 'INFORMATIVE MESSAGE,' + LTEMP = 20 + ELSEIF (LEVEL .EQ. 1) THEN + TEMP(1:30) = 'POTENTIALLY RECOVERABLE ERROR,' + LTEMP = 30 + ELSE + TEMP(1:12) = 'FATAL ERROR,' + LTEMP = 12 + ENDIF +C +C THEN WHETHER THE PROGRAM WILL CONTINUE. +C + IF ((MKNTRL.EQ.2 .AND. LEVEL.GE.1) .OR. + * (MKNTRL.EQ.1 .AND. LEVEL.EQ.2)) THEN + TEMP(LTEMP+1:LTEMP+14) = ' PROG ABORTED,' + LTEMP = LTEMP + 14 + ELSE + TEMP(LTEMP+1:LTEMP+16) = ' PROG CONTINUES,' + LTEMP = LTEMP + 16 + ENDIF +C +C FINALLY TELL WHETHER THERE SHOULD BE A TRACEBACK. +C + IF (LKNTRL .GT. 0) THEN + TEMP(LTEMP+1:LTEMP+20) = ' TRACEBACK REQUESTED' + LTEMP = LTEMP + 20 + ELSE + TEMP(LTEMP+1:LTEMP+24) = ' TRACEBACK NOT REQUESTED' + LTEMP = LTEMP + 24 + ENDIF + CALL XERPRN (' ***', -1, TEMP(1:LTEMP), 72) + ENDIF +C +C NOW SEND OUT THE MESSAGE. +C + CALL XERPRN (' * ', -1, MESSG, 72) +C +C IF LKNTRL IS POSITIVE, WRITE THE ERROR NUMBER AND REQUEST A +C TRACEBACK. +C + IF (LKNTRL .GT. 0) THEN + WRITE (TEMP, '(''ERROR NUMBER = '', I8)') NERR + DO 10 I=16,22 + IF (TEMP(I:I) .NE. ' ') GO TO 20 + 10 CONTINUE +C + 20 CALL XERPRN (' * ', -1, TEMP(1:15) // TEMP(I:23), 72) + CALL FDUMP + ENDIF +C +C IF LKNTRL IS NOT ZERO, PRINT A BLANK LINE AND AN END OF MESSAGE. +C + IF (LKNTRL .NE. 0) THEN + CALL XERPRN (' * ', -1, ' ', 72) + CALL XERPRN (' ***', -1, 'END OF MESSAGE', 72) + CALL XERPRN (' ', 0, ' ', 72) + ENDIF +C +C IF THE ERROR IS NOT FATAL OR THE ERROR IS RECOVERABLE AND THE +C CONTROL FLAG IS SET FOR RECOVERY, THEN RETURN. +C + 30 IF (LEVEL.LE.0 .OR. (LEVEL.EQ.1 .AND. MKNTRL.LE.1)) RETURN +C +C THE PROGRAM WILL BE STOPPED DUE TO AN UNRECOVERED ERROR OR A +C FATAL ERROR. PRINT THE REASON FOR THE ABORT AND THE ERROR +C SUMMARY IF THE CONTROL FLAG AND THE MAXIMUM ERROR COUNT PERMIT. +C + IF (LKNTRL.GT.0 .AND. KOUNT.LT.MAX(1,MAXMES)) THEN + IF (LEVEL .EQ. 1) THEN + CALL XERPRN + * (' ***', -1, 'JOB ABORT DUE TO UNRECOVERED ERROR.', 72) + ELSE + CALL XERPRN(' ***', -1, 'JOB ABORT DUE TO FATAL ERROR.', 72) + ENDIF + CALL XERSVE (' ', ' ', ' ', -1, 0, 0, KDUMMY) + CALL XERHLT (' ') + ELSE + CALL XERHLT (MESSG) + ENDIF + RETURN + END diff --git a/ext/math/xerprn.f b/ext/math/xerprn.f new file mode 100644 index 000000000..97eedf480 --- /dev/null +++ b/ext/math/xerprn.f @@ -0,0 +1,228 @@ +*DECK XERPRN + SUBROUTINE XERPRN (PREFIX, NPREF, MESSG, NWRAP) +C***BEGIN PROLOGUE XERPRN +C***SUBSIDIARY +C***PURPOSE Print error messages processed by XERMSG. +C***LIBRARY SLATEC (XERROR) +C***CATEGORY R3C +C***TYPE ALL (XERPRN-A) +C***KEYWORDS ERROR MESSAGES, PRINTING, XERROR +C***AUTHOR Fong, Kirby, (NMFECC at LLNL) +C***DESCRIPTION +C +C This routine sends one or more lines to each of the (up to five) +C logical units to which error messages are to be sent. This routine +C is called several times by XERMSG, sometimes with a single line to +C print and sometimes with a (potentially very long) message that may +C wrap around into multiple lines. +C +C PREFIX Input argument of type CHARACTER. This argument contains +C characters to be put at the beginning of each line before +C the body of the message. No more than 16 characters of +C PREFIX will be used. +C +C NPREF Input argument of type INTEGER. This argument is the number +C of characters to use from PREFIX. If it is negative, the +C intrinsic function LEN is used to determine its length. If +C it is zero, PREFIX is not used. If it exceeds 16 or if +C LEN(PREFIX) exceeds 16, only the first 16 characters will be +C used. If NPREF is positive and the length of PREFIX is less +C than NPREF, a copy of PREFIX extended with blanks to length +C NPREF will be used. +C +C MESSG Input argument of type CHARACTER. This is the text of a +C message to be printed. If it is a long message, it will be +C broken into pieces for printing on multiple lines. Each line +C will start with the appropriate prefix and be followed by a +C piece of the message. NWRAP is the number of characters per +C piece; that is, after each NWRAP characters, we break and +C start a new line. In addition the characters '$$' embedded +C in MESSG are a sentinel for a new line. The counting of +C characters up to NWRAP starts over for each new line. The +C value of NWRAP typically used by XERMSG is 72 since many +C older error messages in the SLATEC Library are laid out to +C rely on wrap-around every 72 characters. +C +C NWRAP Input argument of type INTEGER. This gives the maximum size +C piece into which to break MESSG for printing on multiple +C lines. An embedded '$$' ends a line, and the count restarts +C at the following character. If a line break does not occur +C on a blank (it would split a word) that word is moved to the +C next line. Values of NWRAP less than 16 will be treated as +C 16. Values of NWRAP greater than 132 will be treated as 132. +C The actual line length will be NPREF + NWRAP after NPREF has +C been adjusted to fall between 0 and 16 and NWRAP has been +C adjusted to fall between 16 and 132. +C +C***REFERENCES R. E. Jones and D. K. Kahaner, XERROR, the SLATEC +C Error-handling Package, SAND82-0800, Sandia +C Laboratories, 1982. +C***ROUTINES CALLED I1MACH, XGETUA +C***REVISION HISTORY (YYMMDD) +C 880621 DATE WRITTEN +C 880708 REVISED AFTER THE SLATEC CML SUBCOMMITTEE MEETING OF +C JUNE 29 AND 30 TO CHANGE THE NAME TO XERPRN AND TO REWORK +C THE HANDLING OF THE NEW LINE SENTINEL TO BEHAVE LIKE THE +C SLASH CHARACTER IN FORMAT STATEMENTS. +C 890706 REVISED WITH THE HELP OF FRED FRITSCH AND REG CLEMENS TO +C STREAMLINE THE CODING AND FIX A BUG THAT CAUSED EXTRA BLANK +C LINES TO BE PRINTED. +C 890721 REVISED TO ADD A NEW FEATURE. A NEGATIVE VALUE OF NPREF +C CAUSES LEN(PREFIX) TO BE USED AS THE LENGTH. +C 891013 REVISED TO CORRECT ERROR IN CALCULATING PREFIX LENGTH. +C 891214 Prologue converted to Version 4.0 format. (WRB) +C 900510 Added code to break messages between words. (RWC) +C 920501 Reformatted the REFERENCES section. (WRB) +C***END PROLOGUE XERPRN + CHARACTER*(*) PREFIX, MESSG + INTEGER NPREF, NWRAP + CHARACTER*148 CBUFF + INTEGER IU(5), NUNIT + CHARACTER*2 NEWLIN + PARAMETER (NEWLIN = '$$') +C***FIRST EXECUTABLE STATEMENT XERPRN + CALL XGETUA(IU,NUNIT) +C +C A ZERO VALUE FOR A LOGICAL UNIT NUMBER MEANS TO USE THE STANDARD +C ERROR MESSAGE UNIT INSTEAD. I1MACH(4) RETRIEVES THE STANDARD +C ERROR MESSAGE UNIT. +C + N = I1MACH(4) + DO 10 I=1,NUNIT + IF (IU(I) .EQ. 0) IU(I) = N + 10 CONTINUE +C +C LPREF IS THE LENGTH OF THE PREFIX. THE PREFIX IS PLACED AT THE +C BEGINNING OF CBUFF, THE CHARACTER BUFFER, AND KEPT THERE DURING +C THE REST OF THIS ROUTINE. +C + IF ( NPREF .LT. 0 ) THEN + LPREF = LEN(PREFIX) + ELSE + LPREF = NPREF + ENDIF + LPREF = MIN(16, LPREF) + IF (LPREF .NE. 0) CBUFF(1:LPREF) = PREFIX +C +C LWRAP IS THE MAXIMUM NUMBER OF CHARACTERS WE WANT TO TAKE AT ONE +C TIME FROM MESSG TO PRINT ON ONE LINE. +C + LWRAP = MAX(16, MIN(132, NWRAP)) +C +C SET LENMSG TO THE LENGTH OF MESSG, IGNORE ANY TRAILING BLANKS. +C + LENMSG = LEN(MESSG) + N = LENMSG + DO 20 I=1,N + IF (MESSG(LENMSG:LENMSG) .NE. ' ') GO TO 30 + LENMSG = LENMSG - 1 + 20 CONTINUE + 30 CONTINUE +C +C IF THE MESSAGE IS ALL BLANKS, THEN PRINT ONE BLANK LINE. +C + IF (LENMSG .EQ. 0) THEN + CBUFF(LPREF+1:LPREF+1) = ' ' + DO 40 I=1,NUNIT + WRITE(IU(I), '(A)') CBUFF(1:LPREF+1) + 40 CONTINUE + RETURN + ENDIF +C +C SET NEXTC TO THE POSITION IN MESSG WHERE THE NEXT SUBSTRING +C STARTS. FROM THIS POSITION WE SCAN FOR THE NEW LINE SENTINEL. +C WHEN NEXTC EXCEEDS LENMSG, THERE IS NO MORE TO PRINT. +C WE LOOP BACK TO LABEL 50 UNTIL ALL PIECES HAVE BEEN PRINTED. +C +C WE LOOK FOR THE NEXT OCCURRENCE OF THE NEW LINE SENTINEL. THE +C INDEX INTRINSIC FUNCTION RETURNS ZERO IF THERE IS NO OCCURRENCE +C OR IF THE LENGTH OF THE FIRST ARGUMENT IS LESS THAN THE LENGTH +C OF THE SECOND ARGUMENT. +C +C THERE ARE SEVERAL CASES WHICH SHOULD BE CHECKED FOR IN THE +C FOLLOWING ORDER. WE ARE ATTEMPTING TO SET LPIECE TO THE NUMBER +C OF CHARACTERS THAT SHOULD BE TAKEN FROM MESSG STARTING AT +C POSITION NEXTC. +C +C LPIECE .EQ. 0 THE NEW LINE SENTINEL DOES NOT OCCUR IN THE +C REMAINDER OF THE CHARACTER STRING. LPIECE +C SHOULD BE SET TO LWRAP OR LENMSG+1-NEXTC, +C WHICHEVER IS LESS. +C +C LPIECE .EQ. 1 THE NEW LINE SENTINEL STARTS AT MESSG(NEXTC: +C NEXTC). LPIECE IS EFFECTIVELY ZERO, AND WE +C PRINT NOTHING TO AVOID PRODUCING UNNECESSARY +C BLANK LINES. THIS TAKES CARE OF THE SITUATION +C WHERE THE LIBRARY ROUTINE HAS A MESSAGE OF +C EXACTLY 72 CHARACTERS FOLLOWED BY A NEW LINE +C SENTINEL FOLLOWED BY MORE CHARACTERS. NEXTC +C SHOULD BE INCREMENTED BY 2. +C +C LPIECE .GT. LWRAP+1 REDUCE LPIECE TO LWRAP. +C +C ELSE THIS LAST CASE MEANS 2 .LE. LPIECE .LE. LWRAP+1 +C RESET LPIECE = LPIECE-1. NOTE THAT THIS +C PROPERLY HANDLES THE END CASE WHERE LPIECE .EQ. +C LWRAP+1. THAT IS, THE SENTINEL FALLS EXACTLY +C AT THE END OF A LINE. +C + NEXTC = 1 + 50 LPIECE = INDEX(MESSG(NEXTC:LENMSG), NEWLIN) + IF (LPIECE .EQ. 0) THEN +C +C THERE WAS NO NEW LINE SENTINEL FOUND. +C + IDELTA = 0 + LPIECE = MIN(LWRAP, LENMSG+1-NEXTC) + IF (LPIECE .LT. LENMSG+1-NEXTC) THEN + DO 52 I=LPIECE+1,2,-1 + IF (MESSG(NEXTC+I-1:NEXTC+I-1) .EQ. ' ') THEN + LPIECE = I-1 + IDELTA = 1 + GOTO 54 + ENDIF + 52 CONTINUE + ENDIF + 54 CBUFF(LPREF+1:LPREF+LPIECE) = MESSG(NEXTC:NEXTC+LPIECE-1) + NEXTC = NEXTC + LPIECE + IDELTA + ELSEIF (LPIECE .EQ. 1) THEN +C +C WE HAVE A NEW LINE SENTINEL AT MESSG(NEXTC:NEXTC+1). +C DON'T PRINT A BLANK LINE. +C + NEXTC = NEXTC + 2 + GO TO 50 + ELSEIF (LPIECE .GT. LWRAP+1) THEN +C +C LPIECE SHOULD BE SET DOWN TO LWRAP. +C + IDELTA = 0 + LPIECE = LWRAP + DO 56 I=LPIECE+1,2,-1 + IF (MESSG(NEXTC+I-1:NEXTC+I-1) .EQ. ' ') THEN + LPIECE = I-1 + IDELTA = 1 + GOTO 58 + ENDIF + 56 CONTINUE + 58 CBUFF(LPREF+1:LPREF+LPIECE) = MESSG(NEXTC:NEXTC+LPIECE-1) + NEXTC = NEXTC + LPIECE + IDELTA + ELSE +C +C IF WE ARRIVE HERE, IT MEANS 2 .LE. LPIECE .LE. LWRAP+1. +C WE SHOULD DECREMENT LPIECE BY ONE. +C + LPIECE = LPIECE - 1 + CBUFF(LPREF+1:LPREF+LPIECE) = MESSG(NEXTC:NEXTC+LPIECE-1) + NEXTC = NEXTC + LPIECE + 2 + ENDIF +C +C PRINT +C + DO 60 I=1,NUNIT + WRITE(IU(I), '(A)') CBUFF(1:LPREF+LPIECE) + 60 CONTINUE +C + IF (NEXTC .LE. LENMSG) GO TO 50 + RETURN + END diff --git a/ext/math/xersve.f b/ext/math/xersve.f new file mode 100644 index 000000000..6bd2a4f7a --- /dev/null +++ b/ext/math/xersve.f @@ -0,0 +1,155 @@ +*DECK XERSVE + SUBROUTINE XERSVE (LIBRAR, SUBROU, MESSG, KFLAG, NERR, LEVEL, + + ICOUNT) +C***BEGIN PROLOGUE XERSVE +C***SUBSIDIARY +C***PURPOSE Record that an error has occurred. +C***LIBRARY SLATEC (XERROR) +C***CATEGORY R3 +C***TYPE ALL (XERSVE-A) +C***KEYWORDS ERROR, XERROR +C***AUTHOR Jones, R. E., (SNLA) +C***DESCRIPTION +C +C *Usage: +C +C INTEGER KFLAG, NERR, LEVEL, ICOUNT +C CHARACTER * (len) LIBRAR, SUBROU, MESSG +C +C CALL XERSVE (LIBRAR, SUBROU, MESSG, KFLAG, NERR, LEVEL, ICOUNT) +C +C *Arguments: +C +C LIBRAR :IN is the library that the message is from. +C SUBROU :IN is the subroutine that the message is from. +C MESSG :IN is the message to be saved. +C KFLAG :IN indicates the action to be performed. +C when KFLAG > 0, the message in MESSG is saved. +C when KFLAG=0 the tables will be dumped and +C cleared. +C when KFLAG < 0, the tables will be dumped and +C not cleared. +C NERR :IN is the error number. +C LEVEL :IN is the error severity. +C ICOUNT :OUT the number of times this message has been seen, +C or zero if the table has overflowed and does not +C contain this message specifically. When KFLAG=0, +C ICOUNT will not be altered. +C +C *Description: +C +C Record that this error occurred and possibly dump and clear the +C tables. +C +C***REFERENCES R. E. Jones and D. K. Kahaner, XERROR, the SLATEC +C Error-handling Package, SAND82-0800, Sandia +C Laboratories, 1982. +C***ROUTINES CALLED I1MACH, XGETUA +C***REVISION HISTORY (YYMMDD) +C 800319 DATE WRITTEN +C 861211 REVISION DATE from Version 3.2 +C 891214 Prologue converted to Version 4.0 format. (BAB) +C 900413 Routine modified to remove reference to KFLAG. (WRB) +C 900510 Changed to add LIBRARY NAME and SUBROUTINE to calling +C sequence, use IF-THEN-ELSE, make number of saved entries +C easily changeable, changed routine name from XERSAV to +C XERSVE. (RWC) +C 910626 Added LIBTAB and SUBTAB to SAVE statement. (BKS) +C 920501 Reformatted the REFERENCES section. (WRB) +C***END PROLOGUE XERSVE + PARAMETER (LENTAB=10) + INTEGER LUN(5) + CHARACTER*(*) LIBRAR, SUBROU, MESSG + CHARACTER*8 LIBTAB(LENTAB), SUBTAB(LENTAB), LIB, SUB + CHARACTER*20 MESTAB(LENTAB), MES + DIMENSION NERTAB(LENTAB), LEVTAB(LENTAB), KOUNT(LENTAB) + SAVE LIBTAB, SUBTAB, MESTAB, NERTAB, LEVTAB, KOUNT, KOUNTX, NMSG + DATA KOUNTX/0/, NMSG/0/ +C***FIRST EXECUTABLE STATEMENT XERSVE +C + IF (KFLAG.LE.0) THEN +C +C Dump the table. +C + IF (NMSG.EQ.0) RETURN +C +C Print to each unit. +C + CALL XGETUA (LUN, NUNIT) + DO 20 KUNIT = 1,NUNIT + IUNIT = LUN(KUNIT) + IF (IUNIT.EQ.0) IUNIT = I1MACH(4) +C +C Print the table header. +C + WRITE (IUNIT,9000) +C +C Print body of table. +C + DO 10 I = 1,NMSG + WRITE (IUNIT,9010) LIBTAB(I), SUBTAB(I), MESTAB(I), + * NERTAB(I),LEVTAB(I),KOUNT(I) + 10 CONTINUE +C +C Print number of other errors. +C + IF (KOUNTX.NE.0) WRITE (IUNIT,9020) KOUNTX + WRITE (IUNIT,9030) + 20 CONTINUE +C +C Clear the error tables. +C + IF (KFLAG.EQ.0) THEN + NMSG = 0 + KOUNTX = 0 + ENDIF + ELSE +C +C PROCESS A MESSAGE... +C SEARCH FOR THIS MESSG, OR ELSE AN EMPTY SLOT FOR THIS MESSG, +C OR ELSE DETERMINE THAT THE ERROR TABLE IS FULL. +C + LIB = LIBRAR + SUB = SUBROU + MES = MESSG + DO 30 I = 1,NMSG + IF (LIB.EQ.LIBTAB(I) .AND. SUB.EQ.SUBTAB(I) .AND. + * MES.EQ.MESTAB(I) .AND. NERR.EQ.NERTAB(I) .AND. + * LEVEL.EQ.LEVTAB(I)) THEN + KOUNT(I) = KOUNT(I) + 1 + ICOUNT = KOUNT(I) + RETURN + ENDIF + 30 CONTINUE +C + IF (NMSG.LT.LENTAB) THEN +C +C Empty slot found for new message. +C + NMSG = NMSG + 1 + LIBTAB(I) = LIB + SUBTAB(I) = SUB + MESTAB(I) = MES + NERTAB(I) = NERR + LEVTAB(I) = LEVEL + KOUNT (I) = 1 + ICOUNT = 1 + ELSE +C +C Table is full. +C + KOUNTX = KOUNTX+1 + ICOUNT = 0 + ENDIF + ENDIF + RETURN +C +C Formats. +C + 9000 FORMAT ('0 ERROR MESSAGE SUMMARY' / + + ' LIBRARY SUBROUTINE MESSAGE START NERR', + + ' LEVEL COUNT') + 9010 FORMAT (1X,A,3X,A,3X,A,3I10) + 9020 FORMAT ('0OTHER ERRORS NOT INDIVIDUALLY TABULATED = ', I10) + 9030 FORMAT (1X) + END diff --git a/ext/math/xgetua.f b/ext/math/xgetua.f new file mode 100644 index 000000000..2e7db0212 --- /dev/null +++ b/ext/math/xgetua.f @@ -0,0 +1,51 @@ +*DECK XGETUA + SUBROUTINE XGETUA (IUNITA, N) +C***BEGIN PROLOGUE XGETUA +C***PURPOSE Return unit number(s) to which error messages are being +C sent. +C***LIBRARY SLATEC (XERROR) +C***CATEGORY R3C +C***TYPE ALL (XGETUA-A) +C***KEYWORDS ERROR, XERROR +C***AUTHOR Jones, R. E., (SNLA) +C***DESCRIPTION +C +C Abstract +C XGETUA may be called to determine the unit number or numbers +C to which error messages are being sent. +C These unit numbers may have been set by a call to XSETUN, +C or a call to XSETUA, or may be a default value. +C +C Description of Parameters +C --Output-- +C IUNIT - an array of one to five unit numbers, depending +C on the value of N. A value of zero refers to the +C default unit, as defined by the I1MACH machine +C constant routine. Only IUNIT(1),...,IUNIT(N) are +C defined by XGETUA. The values of IUNIT(N+1),..., +C IUNIT(5) are not defined (for N .LT. 5) or altered +C in any way by XGETUA. +C N - the number of units to which copies of the +C error messages are being sent. N will be in the +C range from 1 to 5. +C +C***REFERENCES R. E. Jones and D. K. Kahaner, XERROR, the SLATEC +C Error-handling Package, SAND82-0800, Sandia +C Laboratories, 1982. +C***ROUTINES CALLED J4SAVE +C***REVISION HISTORY (YYMMDD) +C 790801 DATE WRITTEN +C 861211 REVISION DATE from Version 3.2 +C 891214 Prologue converted to Version 4.0 format. (BAB) +C 920501 Reformatted the REFERENCES section. (WRB) +C***END PROLOGUE XGETUA + DIMENSION IUNITA(5) +C***FIRST EXECUTABLE STATEMENT XGETUA + N = J4SAVE(5,0,.FALSE.) + DO 30 I=1,N + INDEX = I+4 + IF (I.EQ.1) INDEX = 3 + IUNITA(I) = J4SAVE(INDEX,0,.FALSE.) + 30 CONTINUE + RETURN + END diff --git a/ext/recipes/.cvsignore b/ext/recipes/.cvsignore new file mode 100644 index 000000000..550bd25cd --- /dev/null +++ b/ext/recipes/.cvsignore @@ -0,0 +1,2 @@ +Makefile + diff --git a/ext/recipes/Makefile.in b/ext/recipes/Makefile.in new file mode 100755 index 000000000..582721266 --- /dev/null +++ b/ext/recipes/Makefile.in @@ -0,0 +1,33 @@ +# $License$ +# +#/bin/sh + +LIB = ./librecipes.a + +SUFFIXES= +SUFFIXES= .f .d .o + +F_FLAGS = @FFLAGS@ $(F77_FLAGS) + +OBJS = simp1.o simp2.o simp3.o simplx.o +#splie2.o splin2.o spline.o splint.o +SRCS = $(OBJS:.o=.cpp) + + +all: $(LIB) + +$(LIB): $(OBJS) + @ARCHIVE@ $(LIB) $(OBJS) > /dev/null + +.f.o: + @F77@ -c $< $(F77_INCLUDES) $(F_FLAGS) + +clean: + $(RM) $(OBJS) $(LIB) + + +#include $(DEPENDS) + + + + diff --git a/ext/recipes/simp1.f b/ext/recipes/simp1.f new file mode 100755 index 000000000..7d77f8f83 --- /dev/null +++ b/ext/recipes/simp1.f @@ -0,0 +1,19 @@ + SUBROUTINE SIMP1(A,MP,NP,MM,LL,NLL,IABF,KP,BMAX) + implicit double precision (a-h,o-z) + DIMENSION A(MP,NP),LL(NP) + KP=LL(1) + BMAX=A(MM+1,KP+1) + IF(NLL.LT.2)RETURN + DO 11 K=2,NLL + IF(IABF.EQ.0)THEN + TEST=A(MM+1,LL(K)+1)-BMAX + ELSE + TEST=ABS(A(MM+1,LL(K)+1))-ABS(BMAX) + ENDIF + IF(TEST.GT.0.)THEN + BMAX=A(MM+1,LL(K)+1) + KP=LL(K) + ENDIF +11 CONTINUE + RETURN + END diff --git a/ext/recipes/simp2.f b/ext/recipes/simp2.f new file mode 100755 index 000000000..3398858de --- /dev/null +++ b/ext/recipes/simp2.f @@ -0,0 +1,32 @@ + SUBROUTINE SIMP2(A,M,N,MP,NP,L2,NL2,IP,KP,Q1) + implicit double precision (a-h,o-z) + PARAMETER (EPS=1.d-6) + DIMENSION A(MP,NP),L2(MP) + IP=0 + IF(NL2.LT.1)RETURN + DO 11 I=1,NL2 + IF(A(L2(I)+1,KP+1).LT.-EPS)GO TO 2 +11 CONTINUE + RETURN +2 Q1=-A(L2(I)+1,1)/A(L2(I)+1,KP+1) + IP=L2(I) + IF(I+1.GT.NL2)RETURN + DO 13 I=I+1,NL2 + II=L2(I) + IF(A(II+1,KP+1).LT.-EPS)THEN + Q=-A(II+1,1)/A(II+1,KP+1) + IF(Q.LT.Q1)THEN + IP=II + Q1=Q + ELSE IF (Q.EQ.Q1) THEN + DO 12 K=1,N + QP=-A(IP+1,K+1)/A(IP+1,KP+1) + Q0=-A(II+1,K+1)/A(II+1,KP+1) + IF(Q0.NE.QP)GO TO 6 +12 CONTINUE +6 IF(Q0.LT.QP)IP=II + ENDIF + ENDIF +13 CONTINUE + RETURN + END diff --git a/ext/recipes/simp3.f b/ext/recipes/simp3.f new file mode 100755 index 000000000..27832c8e9 --- /dev/null +++ b/ext/recipes/simp3.f @@ -0,0 +1,22 @@ + SUBROUTINE SIMP3(A,MP,NP,I1,K1,IP,KP) + implicit double precision (a-h,o-z) + DIMENSION A(MP,NP) + PIV=1.d0/A(IP+1,KP+1) + IF(I1.GE.0)THEN + DO 12 II=1,I1+1 + IF(II-1.NE.IP)THEN + A(II,KP+1)=A(II,KP+1)*PIV + DO 11 KK=1,K1+1 + IF(KK-1.NE.KP)THEN + A(II,KK)=A(II,KK)-A(IP+1,KK)*A(II,KP+1) + ENDIF +11 CONTINUE + ENDIF +12 CONTINUE + ENDIF + DO 13 KK=1,K1+1 + IF(KK-1.NE.KP)A(IP+1,KK)=-A(IP+1,KK)*PIV +13 CONTINUE + A(IP+1,KP+1)=PIV + RETURN + END diff --git a/ext/recipes/simplx.f b/ext/recipes/simplx.f new file mode 100755 index 000000000..caf31aac8 --- /dev/null +++ b/ext/recipes/simplx.f @@ -0,0 +1,99 @@ + SUBROUTINE SIMPLX(A,M,N,MP,NP,M1,M2,M3,ICASE,IZROV,IPOSV) + implicit double precision (a-h,o-z) + PARAMETER(MMAX=1000,EPS=1.d-6) + DIMENSION A(MP,NP),IZROV(N),IPOSV(M),L1(MMAX),L2(MMAX),L3(MMAX) + IF(M.NE.M1+M2+M3)PAUSE 'Bad input constraint counts.' + NL1=N + DO 11 K=1,N + L1(K)=K + IZROV(K)=K +11 CONTINUE + NL2=M + DO 12 I=1,M + IF(A(I+1,1).LT.0.d0) then +c write(*,*) 'The A matrix input to SIMPLX is invalid.' + PAUSE 'Bad input tableau.' + end if + L2(I)=I + IPOSV(I)=N+I +12 CONTINUE + DO 13 I=1,M2 + L3(I)=1 +13 CONTINUE + IR=0 + IF(M2+M3.EQ.0)GO TO 30 + IR=1 + DO 15 K=1,N+1 + Q1=0. + DO 14 I=M1+1,M + Q1=Q1+A(I+1,K) +14 CONTINUE + A(M+2,K)=-Q1 +15 CONTINUE +10 CALL SIMP1(A,MP,NP,M+1,L1,NL1,0,KP,BMAX) + IF(BMAX.LE.EPS.AND.A(M+2,1).LT.-EPS)THEN + ICASE=-1 + RETURN + ELSE IF(BMAX.LE.EPS.AND.A(M+2,1).LE.EPS)THEN + M12=M1+M2+1 + IF(M12.LE.M)THEN + DO 16 IP=M12,M + IF(IPOSV(IP).EQ.IP+N)THEN + CALL SIMP1(A,MP,NP,IP,L1,NL1,1,KP,BMAX) + IF(BMAX.GT.0.)GO TO 1 + ENDIF +16 CONTINUE + ENDIF + IR=0 + M12=M12-1 + IF(M1+1.GT.M12)GO TO 30 + DO 18 I=M1+1,M12 + IF(L3(I-M1).EQ.1)THEN + DO 17 K=1,N+1 + A(I+1,K)=-A(I+1,K) +17 CONTINUE + ENDIF +18 CONTINUE + GO TO 30 + ENDIF + CALL SIMP2(A,M,N,MP,NP,L2,NL2,IP,KP,Q1) + IF(IP.EQ.0)THEN + ICASE=-1 + RETURN + ENDIF +1 CALL SIMP3(A,MP,NP,M+1,N,IP,KP) + IF(IPOSV(IP).GE.N+M1+M2+1)THEN + DO 19 K=1,NL1 + IF(L1(K).EQ.KP)GO TO 2 +19 CONTINUE +2 NL1=NL1-1 + DO 21 IS=K,NL1 + L1(IS)=L1(IS+1) +21 CONTINUE + ELSE + IF(IPOSV(IP).LT.N+M1+1)GO TO 20 + KH=IPOSV(IP)-M1-N + IF(L3(KH).EQ.0)GO TO 20 + L3(KH)=0 + ENDIF + A(M+2,KP+1)=A(M+2,KP+1)+1. + DO 22 I=1,M+2 + A(I,KP+1)=-A(I,KP+1) +22 CONTINUE +20 IS=IZROV(KP) + IZROV(KP)=IPOSV(IP) + IPOSV(IP)=IS + IF(IR.NE.0)GO TO 10 +30 CALL SIMP1(A,MP,NP,0,L1,NL1,0,KP,BMAX) + IF(BMAX.LE.0.)THEN + ICASE=0 + RETURN + ENDIF + CALL SIMP2(A,M,N,MP,NP,L2,NL2,IP,KP,Q1) + IF(IP.EQ.0)THEN + ICASE=1 + RETURN + ENDIF + CALL SIMP3(A,MP,NP,M,N,IP,KP) + GO TO 20 + END diff --git a/ext/recipes/splie2.f b/ext/recipes/splie2.f new file mode 100755 index 000000000..aa39503e5 --- /dev/null +++ b/ext/recipes/splie2.f @@ -0,0 +1,15 @@ + SUBROUTINE SPLIE2(X1A,X2A,YA,M,N,Y2A) + implicit double precision (a-h,o-z) + PARAMETER (NN=100) + DIMENSION X1A(M),X2A(N),YA(M,N),Y2A(M,N),YTMP(NN),Y2TMP(NN) + DO 13 J=1,M + DO 11 K=1,N + YTMP(K)=YA(J,K) +11 CONTINUE + CALL SPLINE(X2A,YTMP,N,1.D30,1.D30,Y2TMP) + DO 12 K=1,N + Y2A(J,K)=Y2TMP(K) +12 CONTINUE +13 CONTINUE + RETURN + END diff --git a/ext/recipes/splin2.f b/ext/recipes/splin2.f new file mode 100755 index 000000000..6f24906f4 --- /dev/null +++ b/ext/recipes/splin2.f @@ -0,0 +1,16 @@ + SUBROUTINE SPLIN2(X1A,X2A,YA,Y2A,M,N,X1,X2,Y) + implicit double precision (a-h,o-z) + PARAMETER (NN=100) + DIMENSION X1A(M),X2A(N),YA(M,N),Y2A(M,N),YTMP(NN), + $ Y2TMP(NN),YYTMP(NN) + DO 12 J=1,M + DO 11 K=1,N + YTMP(K)=YA(J,K) + Y2TMP(K)=Y2A(J,K) +11 CONTINUE + CALL SPLINT(X2A,YTMP,Y2TMP,N,X2,YYTMP(J)) +12 CONTINUE + CALL SPLINE(X1A,YYTMP,M,1.d30,1.d30,Y2TMP) + CALL SPLINT(X1A,YYTMP,Y2TMP,M,X1,Y) + RETURN + END diff --git a/ext/recipes/spline.f b/ext/recipes/spline.f new file mode 100755 index 000000000..c0a5ed03e --- /dev/null +++ b/ext/recipes/spline.f @@ -0,0 +1,31 @@ + SUBROUTINE SPLINE(X,Y,N,YP1,YPN,Y2) + implicit double precision (a-h,o-z) + PARAMETER (NMAX=100) + DIMENSION X(N),Y(N),Y2(N),U(NMAX) + IF (YP1.GT..99D30) THEN + Y2(1)=0. + U(1)=0. + ELSE + Y2(1)=-0.5d0 + U(1)=(3.d0/(X(2)-X(1)))*((Y(2)-Y(1))/(X(2)-X(1))-YP1) + ENDIF + DO 11 I=2,N-1 + SIG=(X(I)-X(I-1))/(X(I+1)-X(I-1)) + P=SIG*Y2(I-1)+2.d0 + Y2(I)=(SIG-1.)/P + U(I)=(6.d0*((Y(I+1)-Y(I))/(X(I+1)-X(I))-(Y(I)-Y(I-1)) + * /(X(I)-X(I-1)))/(X(I+1)-X(I-1))-SIG*U(I-1))/P +11 CONTINUE + IF (YPN.GT..99d30) THEN + QN=0.d0 + UN=0.d0 + ELSE + QN=0.5d0 + UN=(3.d0/(X(N)-X(N-1)))*(YPN-(Y(N)-Y(N-1))/(X(N)-X(N-1))) + ENDIF + Y2(N)=(UN-QN*U(N-1))/(QN*Y2(N-1)+1.d0) + DO 12 K=N-1,1,-1 + Y2(K)=Y2(K)*Y2(K+1)+U(K) +12 CONTINUE + RETURN + END diff --git a/ext/recipes/splint.f b/ext/recipes/splint.f new file mode 100755 index 000000000..fb8b1ba28 --- /dev/null +++ b/ext/recipes/splint.f @@ -0,0 +1,22 @@ + SUBROUTINE SPLINT(XA,YA,Y2A,N,X,Y) + implicit double precision (a-h,o-z) + DIMENSION XA(N),YA(N),Y2A(N) + KLO=1 + KHI=N +1 IF (KHI-KLO.GT.1) THEN + K=(KHI+KLO)/2 + IF(XA(K).GT.X)THEN + KHI=K + ELSE + KLO=K + ENDIF + GOTO 1 + ENDIF + H=XA(KHI)-XA(KLO) + IF (H.EQ.0.) PAUSE 'Bad XA input.' + A=(XA(KHI)-X)/H + B=(X-XA(KLO))/H + Y=A*YA(KLO)+B*YA(KHI)+ + * ((A**3-A)*Y2A(KLO)+(B**3-B)*Y2A(KHI))*(H**2)/6.d0 + RETURN + END diff --git a/ext/tpx/.cvsignore b/ext/tpx/.cvsignore new file mode 100644 index 000000000..550bd25cd --- /dev/null +++ b/ext/tpx/.cvsignore @@ -0,0 +1,2 @@ +Makefile + diff --git a/ext/tpx/.depends b/ext/tpx/.depends new file mode 100755 index 000000000..8d1c8b69c --- /dev/null +++ b/ext/tpx/.depends @@ -0,0 +1 @@ + diff --git a/ext/tpx/CFluid.cpp b/ext/tpx/CFluid.cpp new file mode 100755 index 000000000..59ea2136c --- /dev/null +++ b/ext/tpx/CFluid.cpp @@ -0,0 +1,6 @@ +// +#include "CFluid.h" + +double CFluid::u_ni() { + return 1.0; + } \ No newline at end of file diff --git a/ext/tpx/CFluid.h b/ext/tpx/CFluid.h new file mode 100755 index 000000000..2af95d533 --- /dev/null +++ b/ext/tpx/CFluid.h @@ -0,0 +1,75 @@ +#ifndef CFLUID_H +#define CFLUID_H + +#include "sub.h" +#include "ck_gas.h" + +#include +#include + +// custom fluid base class + +class CFluid : public Substance { + +public: + + CFluid(char *name, double MWt, int kmx, double *xmoles) + { + ig = new ck_gas(kmx, xmoles); + T = Undef; + Rho = Undef; + Mw = MWt; + CName = new char(strlen(name)+1); + strcpy(CName,name); + } + + + ~CFluid() { + delete ig; + } + + double R(){ + return 8314.3/Mw; + } + + double MolWt() { + return Mw; + } + + double Tmin() { + return ig->Tmin(); + } + + double Tmax() { + return ig->Tmax(); + } + + char * name() { + return CName; + } + + char * formula() { + return "doda"; + } + +//protected: + + double Mw; + ck_gas* ig; + char* CName; + + virtual double u_ni()=0; + virtual double s_ni()=0; + + double up(){ + ig->Set(TP,T,101325.0); + return ig->u() + u_ni(); + } + + double sp(){ + ig->Set(TP,T,101325.0); + return ig->s() + s_ni(); + } + +}; +#endif // ! CFLUID \ No newline at end of file diff --git a/ext/tpx/CGas.cpp b/ext/tpx/CGas.cpp new file mode 100755 index 000000000..e69de29bb diff --git a/ext/tpx/CLK.cpp b/ext/tpx/CLK.cpp new file mode 100755 index 000000000..349274bfc --- /dev/null +++ b/ext/tpx/CLK.cpp @@ -0,0 +1,117 @@ +// Lee-Kesler equation of state for use with custom fluids + +#include "CLK.h" +#include + +const double b[2][4] = {{0.1181193, 0.265728, 0.154790, 0.030323}, + {0.2026579, 0.331511, 0.027655, 0.203488}}; +const double c[2][4] = {{0.0236744, 0.0186984, 0.0, 0.042724}, + {0.0313385, 0.0503618, 0.016901, 0.041577}}; +const double d[2][2] = {{1.55488e-5, 6.23689e-5},{4.8736e-5, 0.740336e-5}}; +const double beta[2] = {0.65392, 1.226}; +const double gamma[2] = {0.060167, 0.03754}; + +//--------------------------- member functions ------------------ + +double CLK::W(int n, double egrho, double Gamma) { + return (n == 0 ? (1.0 - egrho)/(2.0*Gamma) : + (n*W(n-1, egrho, Gamma) - 0.5*pow(Rho,2*n)*egrho)/Gamma); +} + +double CLK::u_ni(){ + return -R()*T*T*I()/Tcr; // + u_0(T) +} + +double CLK::s_ni() { + const double Pref = 101325.0; + double rgas = R(); + return rgas*(log(Pref/(Rho*rgas*T)) - (T/Tcr)*I() - J()); // + s^0(T,p_0) +} + +double CLK::I() { // \int_0^\rho_r (1/\rho_r)(dZ/dT_r) d\rho_r + double Bp, Cp, Dp; + double rtr = Tcr/T; + double rtr2 = rtr*rtr; + double rvr = 8314.3*Tcr*Rho/(Pcr*Mw); // 1/v_r^\prime + double rvr2 = rvr*rvr; + double egrho; + + egrho = exp(-gamma[Isr]*rvr2); + Bp = rtr2*b[Isr][1] + 2.0*rtr*rtr2*b[Isr][2] + 3.0*rtr2*rtr2*b[Isr][3]; + Cp = rtr2*c[Isr][1] - 3.0*c[Isr][2]*rtr2*rtr2; + Dp = -d[Isr][1]*rtr2; + double r = Bp*rvr + 0.5*rvr2*Cp + 0.2*pow(rvr,5)*Dp + - 3.0*c[Isr][3]*rtr2*rtr2*(beta[Isr]*W(0,egrho,gamma[Isr]) + + gamma[Isr]*W(1,egrho,gamma[Isr])); + return r; +} + +double CLK::J() { // \int_0^\rho_r (1/\rho_r)(Z - 1) d\rho_r + double BB, CC, DD; + double rtr = Tcr/T; + double rtr2 = rtr*rtr; + double rvr = 8314.3*Tcr*Rho/(Pcr*Mw); // 1/v_r^\prime + double rvr2 = rvr*rvr; + double egrho; + + egrho = exp(-gamma[Isr]*rvr2); + BB = b[Isr][0] - rtr*(b[Isr][1] + + rtr*(b[Isr][2] + rtr*b[Isr][3])); + CC = c[Isr][0] - rtr*(c[Isr][1] - c[Isr][2]*rtr*rtr); + DD = d[Isr][0] + d[Isr][1]*rtr; + double r = BB*rvr + 0.5*rvr2*CC + 0.2*pow(rvr,5)*DD + + c[Isr][3]*rtr2*rtr*(beta[Isr]*W(0,egrho,gamma[Isr]) + + gamma[Isr]*W(1,egrho,gamma[Isr])); + return r; +} + +double CLK::z() { + double zz, rvr2, BB, CC, DD, EE; + double rtr = Tcr/T; // 1/T_r + double rvr = Rho*8314.3*Tcr/(Pcr*Mw); + rvr2 = rvr*rvr; + BB = b[Isr][0] - rtr*(b[Isr][1] + + rtr*(b[Isr][2] + rtr*b[Isr][3])); + CC = c[Isr][0] - rtr*(c[Isr][1] - c[Isr][2]*rtr*rtr); + DD = d[Isr][0] + d[Isr][1]*rtr; + EE = exp(-gamma[Isr]*rvr2); + + zz = 1.0 + BB*rvr + CC*rvr2 + DD*pow(rvr,5) + + c[Isr][3]*pow(rtr,3)*rvr2* + (beta[Isr] + gamma[Isr]*rvr2)*EE; + return zz; +} + + +double CLK::Pp() { + return 8314.3*z()*Rho*T/Mw; +} + +double CLK::Psat(){ + double tr = 1.0 - Tcr/T; + double lpr; + + if (Isr == 0) + lpr = 5.395743797*tr + 0.05524287*tr*tr + 0.06853005*tr*tr*tr; + else + lpr = 7.259961465*tr - 0.549206092*tr*tr + 0.177581752*tr*tr*tr; + return Pcr*exp(lpr); +} + +double CLK::ldens(){ + double x = 1.0 - T/Tcr; + + double rho_r; + if (Isr == 0) + rho_r = 5.2307 + 15.16*x - 21.9778*x*x + 18.767*x*x*x; + else { + rho_r = 6.166930606 + 17.42866964*x - 18.62589833*x*x + 11.73957224*x*x*x; + rho_r *= 1.0; + } + return Pcr*rho_r*Mw/(8314.3*Tcr); +} + +double CLK::Tcrit() {return Tcr;} +double CLK::Pcrit() {return Pcr;} +double CLK::Vcrit() {return 0.2901*R()*Tcr/Pcr;} +char * CLK::formula() {return "---";} diff --git a/ext/tpx/CLK.h b/ext/tpx/CLK.h new file mode 100755 index 000000000..6bcff6dd3 --- /dev/null +++ b/ext/tpx/CLK.h @@ -0,0 +1,49 @@ +#ifndef CLK_H +#define CLK_H + +#include "CFluid.h" + +#include + +// custom Lee-Kesler fluid class + +class CLK : public CFluid { + +public: + + CLK(char* name, double tcrit, double pcrit, int itype, double MWt, int kmx, double *xmoles) : + CFluid(name, MWt, kmx, xmoles) + { + Tcr = tcrit; + Pcr = pcrit; + Isr = itype; + } + + ~CLK(){} + + double Tcrit(); + double Pcrit(); + double Vcrit(); + char * formula(); + +//protected: + + double Tcr; + double Pcr; + int Isr; + + double u_ni(); + double s_ni(); + double Pp(); + double z(); + + double Psat(); + double ldens(); + +private: + double W(int n, double egrho, double gamma); + double I(); + double J(); + +}; +#endif // ! CLK \ No newline at end of file diff --git a/ext/tpx/HFC134a.cpp b/ext/tpx/HFC134a.cpp new file mode 100755 index 000000000..53025acbe --- /dev/null +++ b/ext/tpx/HFC134a.cpp @@ -0,0 +1,172 @@ +// HFC134a + +#include "HFC134a.h" +#include + +const double + M = 102.032, + Tmn = 170.0, + Tmx = 455.0, + Tc = 374.18, + Pc = 4056290.0, + Roc = 508.0, + R = 81.48885644; + +const double a134[] = { + 0.5586817e-1, + 0.4982230, + 0.2458698e-1, + 0.8570145e-3, + 0.4788584e-3, + -0.1800808e1, + 0.2671641, + -0.4781652e-1, + 0.1423987e-1, + 0.3324062, + -0.7485907e-2, + 0.1017263e-3, + -0.5184567, + -0.8692288e-1, + 0.2057144, + -0.5000457e-2, + 0.4603262e-3, + -0.3497836e-2, + 0.6995038e-2, + -0.1452184e-1, + -0.1285458e-3 +}; + +const double t134[] = { + -0.5, 0.0, 0.0, 0.0, 1.5, 1.5, 2.0, 2.0, 1.0, 3.0, 5.0, + 1.0, 5.0, 5.0, 6.0, 10.0, 10.0, 10.0, 18.0, 22.0, 50.0 +}; + +const int d134[] = { + 2, 1, 3, 6, 6, 1, 1, 2, 5, 2, 2, + 4, 1, 4, 1, 2, 4, 1, 5, 3, 10 +}; + +const double b134[] = { + -1.019535, + 9.047135, + -1.629789, + -9.723916, + -3.927170 +}; + +double HFC134a::fp() { + double sum1 = 0.0, sum2 = 0.0, sum3 = 0.0, + sum4 = 0.0, sum5 = 0.0; + double tau = Tc/T; + double delta = Rho/Roc; + + double phi0 = b134[0] + b134[1]*tau + b134[2]*log(tau) + + log(delta) + b134[3]/sqrt(tau) + b134[4]*pow(tau,-0.75); + int i; + for (i = 0; i<8; i++) + sum1 += a134[i]*pow(tau,t134[i])*pow(delta,d134[i]); + for (i = 8; i<11; i++) + sum2 += a134[i]*pow(tau,t134[i])*pow(delta,d134[i]); + for (i = 11; i<17; i++) + sum3 += a134[i]*pow(tau,t134[i])*pow(delta,d134[i]); + for (i = 17; i<20; i++) + sum4 += a134[i]*pow(tau,t134[i])*pow(delta,d134[i]); + sum5 = a134[20]*pow(tau,t134[20])*pow(delta,d134[20]); + double phir = sum1 + exp(-delta)*sum2 + exp(-delta*delta)*sum3 + + exp(-delta*delta*delta)*sum4 + + exp(-delta*delta*delta*delta)*sum5; + return R*T*(phir + phi0); +} + +double HFC134a::up() { + double sum1 = 0.0, sum2 = 0.0, sum3 = 0.0, + sum4 = 0.0, sum5 = 0.0; + double tau = Tc/T; + double delta = Rho/Roc; + + double phi0t = b134[1]*tau + b134[2] + - 0.5*b134[3]*pow(tau,-0.5) - 0.75*b134[4]*pow(tau,-0.75); + int i; + for (i = 0; i<8; i++) + sum1 += a134[i]*t134[i]*pow(tau,t134[i])*pow(delta,d134[i]); + for (i = 8; i<11; i++) + sum2 += a134[i]*t134[i]*pow(tau,t134[i])*pow(delta,d134[i]); + for (i = 11; i<17; i++) + sum3 += a134[i]*t134[i]*pow(tau,t134[i])*pow(delta,d134[i]); + for (i = 17; i<20; i++) + sum4 += a134[i]*t134[i]*pow(tau,t134[i])*pow(delta,d134[i]); + sum5 = a134[20]*t134[20]*pow(tau,t134[20])*pow(delta,d134[20]); + double phirt = sum1 + exp(-delta)*sum2 + exp(-delta*delta)*sum3 + + exp(-delta*delta*delta)*sum4 + + exp(-delta*delta*delta*delta)*sum5; + return R*T*(phirt + phi0t); + } + +double HFC134a::Pp(){ + double sum1 = 0.0, sum2 = 0.0, sum3 = 0.0, + sum4 = 0.0, sum5 = 0.0; + double tau = Tc/T; + double delta = Rho/Roc; + + double phi0d = 1.0/delta; + + int i; + for (i = 0; i<8; i++) + sum1 += a134[i]*pow(tau,t134[i])*d134[i]*pow(delta,d134[i]-1); + for (i = 8; i<11; i++) + sum2 += a134[i]*pow(tau,t134[i])*(d134[i] - delta)*pow(delta,d134[i]-1); + sum2 *= exp(-delta); + double dk = delta*delta; + for (i = 11; i<17; i++) + sum3 += a134[i]*pow(tau,t134[i])*(d134[i] - 2.0*dk)*pow(delta,d134[i]-1); + sum3 *= exp(-dk); + dk *= delta; + for (i = 17; i<20; i++) + sum4 += a134[i]*pow(tau,t134[i])*(d134[i] - 3.0*dk)*pow(delta,d134[i]-1); + sum4 *= exp(-dk); + dk *= delta; + sum5 = a134[20]*pow(tau,t134[20])*(d134[20] - 4.0*dk)*pow(delta,d134[20]-1); + sum5 *= exp(-dk); + double phird = sum1 + sum2 + sum3 + sum4 + sum5; + return R*T*delta*delta*Roc*(phird + phi0d); + } + + +double HFC134a::Psat(){ + if ((T < Tmn) || (T > Tc)) set_Err(TempError); + double x1 = T/Tc; + double x2 = 1.0 - x1; + double f = -7.686556*x2 + 2.311791*pow(x2,1.5) + - 2.039554*x2*x2 - 3.583758*pow(x2,4); + return Pc*exp(f/x1); + } + +/* +double HFC134a::dPsatdT(){ + if ((T < Tmn) || (T > Tc)) set_Err(TempError); + double x1 = T/Tc; + double x2 = 1.0 - x1; + double f = -7.686556*x2 + 2.311791*pow(x2,1.5) + - 2.039554*x2*x2 - 3.583758*pow(x2,4); + double fp = -7.686556 + 1.5*2.311791*pow(x2,0.5) + - 2.0*2.039554*x2 - 4.0*3.583758*pow(x2,3); + return -Pc*exp(f/x1)*(fp/T + f/(x1*T)); + } +*/ + +double HFC134a::ldens(){ + if ((T < Tmn) || (T > Tc)) set_Err(TempError); + double x1 = T/Tc; + double x2 = 1.0 - x1; + return 518.2 + 884.13*pow(x2,1.0/3.0) + 485.84*pow(x2,2.0/3.0) + + 193.29*pow(x2,10.0/3.0); +} + + double HFC134a::Tcrit() {return 374.21;} + double HFC134a::Pcrit() {return 4059280.0;} + double HFC134a::Vcrit() {return 1.0/511.95;} + double HFC134a::Tmin() {return Tmn;} + double HFC134a::Tmax() {return Tmx;} + char * HFC134a::name() {return "HFC-134a";} + char * HFC134a::formula() {return "C2F4H2";} + double HFC134a::MolWt() {return M;} diff --git a/ext/tpx/HFC134a.h b/ext/tpx/HFC134a.h new file mode 100755 index 000000000..4a291a683 --- /dev/null +++ b/ext/tpx/HFC134a.h @@ -0,0 +1,31 @@ +#ifndef HFC134_H +#define HFC134_H + +#include "sub.h" + +class HFC134a : public Substance{ +public: + HFC134a(){} + ~HFC134a(){} + + double MolWt(); + double Tcrit(); + double Pcrit(); + double Vcrit(); + double Tmin(); + double Tmax(); + char * name(); + char * formula(); + + double Pp(); + double fp(); + double up(); + double sp() + { return (up() - fp())/T; } + double Psat(); +// double dPsatdT(); +private: + double ldens(); + }; +#endif // ! HFC134_H + diff --git a/ext/tpx/Hydrogen.cpp b/ext/tpx/Hydrogen.cpp new file mode 100755 index 000000000..693acec86 --- /dev/null +++ b/ext/tpx/Hydrogen.cpp @@ -0,0 +1,258 @@ +// Hydrogen + +#include "Hydrogen.h" +#include + +namespace tpx { + +static const double + M = 2.0159, + Tmn = 13.8, + Tmx = 5000.0, + Tc = 32.938, + Pc = 1.2838e6, + Roc= 31.36, + To = 13.8, + Tt = 13.8, + Pt = 7042.09, + R = 4124.299539, + Gamma = 1.008854772e-3, + u0 = 308901.4703, + s0 = 7759.186436, + T1 = 35, + T2 = 400, + alpha = 1.5814454428, //to be used with psat + alpha1 = .3479; //to be used with ldens + +static const double Ahydro[] = + { 1.150470519352900e1, 1.055427998826072e3, -1.270685949968568e4, + 7.287844527295619e4, -7.448780703363973e5, 2.328994151810363e-1, + -1.635308393739296e1, 3.730678064960389e3, 6.299667723184813e5, + 1.210920358305697e-3, 1.753651095884817, -1.367022988058101e2, + -6.869936641299885e-3, 3.644494201750974e-2, -2.559784772600182, + -4.038855202905836e-4, 1.485396303520942e-6, 4.243613981060742e-4, + -2.307910113586888e-6, -6.082192173879582e5, -1.961080967486886e6, + -5.786932854076408e2, 2.799129504191752e4, -2.381566558300913e-1, + 8.918796032452872e-1, -6.985739539036644e-5, -7.339554179182899e-3, + -5.597033440289980e-9, 8.842130160884514e-8, -2.655507264539047e-12, + -4.544474518140164e-12, 9.818775257001922e-11 }; +static const double Dhydro[]= + { 4.8645813003e1, -3.4779278180e1, 4.0776538192e2, + -1.1719787304e3, 1.6213924400e3, -1.1531096683e3, 3.3825492039e2 }; +static const double Fhydro[]= + { 3.05300134164, 2.80810925813, -6.55461216567e-1, 1.59514439374 }; +static const double Ghydro[]= + { 6.1934792e3, 2.9490437e2, -1.5401979e3, -4.9176101e3, + 6.8957165e4, -2.2282185e5, 3.7990059e5, -3.7094216e5, 2.1326792e5, + -7.1519411e4, 1.2971743e4, -9.8533014e2, 1.0434776e4, + -3.9144179e2, 5.8277696e2, 6.5409163e2, -1.8728847e2 }; + +double hydrogen::C(int i, double rt, double rt2) { + switch(i) { + case 0 : + return Ahydro[0] * T + Ahydro[1] * sqrt(T) + Ahydro[2] + (Ahydro[3] + Ahydro[4] * rt) * rt; + case 1 : + return Ahydro[5] * T + Ahydro[6] + rt * (Ahydro[7] + Ahydro[8] * rt); + case 2 : + return Ahydro[9] * T + Ahydro[10] + Ahydro[11] * rt; + case 3 : + return Ahydro[12]; + case 4 : + return rt*(Ahydro[13] + Ahydro[14]*rt); + case 5 : + return Ahydro[15]*rt; + case 6 : + return rt*(Ahydro[16] + Ahydro[17]*rt); + case 7 : + return Ahydro[18]*rt2; + case 8 : + return rt2*(Ahydro[19] + Ahydro[20]*rt); + case 9 : + return rt2*(Ahydro[21] + Ahydro[22]*rt2); + case 10 : + return rt2*(Ahydro[23] + Ahydro[24]*rt); + case 11 : + return rt2*(Ahydro[25] + Ahydro[26]*rt2); + case 12 : + return rt2*(Ahydro[27] + Ahydro[28]*rt); + case 13 : + return rt2*(Ahydro[29] + Ahydro[30]*rt + Ahydro[31]*rt2); + default : + return 0.0; + } + } + +double hydrogen::Cprime(int i, double rt, double rt2, double rt3) { + switch(i) { + case 0 : + return Ahydro[0] + 0.5*Ahydro[1]/sqrt(T) - (Ahydro[3] + 2.0*Ahydro[4]*rt)*rt2; + case 1 : + return Ahydro[5] - rt2*(Ahydro[7] + 2.0*Ahydro[8]*rt); + case 2 : + return Ahydro[9] - Ahydro[11]*rt2; + case 3 : + return 0.0; + case 4 : + return -rt2*(Ahydro[13] + 2.0*Ahydro[14]*rt); + case 5 : + return -Ahydro[15]*rt2; + case 6 : + return -rt2*(Ahydro[16] + 2.0*Ahydro[17]*rt); + case 7 : + return -2.0*Ahydro[18]*rt3; + case 8 : + return -rt3*(2.0*Ahydro[19] + 3.0*Ahydro[20]*rt); + case 9 : + return -rt3*(2.0*Ahydro[21] + 4.0*Ahydro[22]*rt2); + case 10 : + return -rt3*(2.0*Ahydro[23] + 3.0*Ahydro[24]*rt); + case 11 : + return -rt3*(2.0*Ahydro[25] + 4.0*Ahydro[26]*rt2); + case 12 : + return -rt3*(2.0*Ahydro[27] + 3.0*Ahydro[28]*rt); + case 13 : + return -rt3*(2.0*Ahydro[29] + 3.0*Ahydro[30]*rt + 4.0*Ahydro[31]*rt2); + default : + return 0.0; + } + } + +double hydrogen::W(int n, double egrho) { + return (n == 0 ? (1.0 - egrho)/(2.0*Gamma) : + (n*W(n-1, egrho) - 0.5*pow(Rho,2*n)*egrho)/Gamma); + } + +double hydrogen::H(int i, double egrho) { + return (i < 8 ? pow(Rho,i+2) : pow(Rho,2*i-13)*egrho); + } + +double hydrogen::I(int i, double egrho) { + return (i < 8 ? pow(Rho,i+1)/double(i+1) : W(i-8, egrho)); + } + +double hydrogen::icv(int i, double x, double xlg) { + return (i == 0 ? x - 1 : x*pow(xlg,i) - i*icv(i-1,x,xlg)); + } + +double hydrogen::up(){ + double rt = 1.0/T; + double rt2 = rt*rt; + double rt3 = rt*rt2; + double egrho = exp(-Gamma*Rho*Rho); + double x, xlg; + double sum = u0; + double sum2, sum3; + for (int i=0; i<14; i++) + sum += (C(i, rt, rt2) - T*Cprime(i, rt, rt2, rt3))*I(i, egrho); + +// add \int c_{v,0} term + + if (T <= T1) { + sum2 = Ghydro[0]*T; + } + else { + if (T < T2) + x = T/T1; + else + x = T2/T1; + xlg = log(x); + int i; + for (i=0, sum2=0.0; i<12; i++) + sum2 += Ghydro[i]*icv(i, x, xlg); + sum2 *= T1; + sum2 += Ghydro[0]*T1; + if (T > T2) { + x = T/T2; + xlg = log(x); + for (i=0, sum3=0.0; i<5; i++) + sum3 += Ghydro[i+12]*icv(i, x, xlg); + sum3 *= T2; + sum2 += sum3; + } + } + sum += sum2 + m_energy_offset; + return sum; + } + +double hydrogen::sp() { + double rt = 1.0/T; + double rt2 = rt*rt; + double rt3 = rt*rt2; + double egrho = exp(-Gamma*Rho*Rho); + double x, xlg; + double sum = s0 - R*log(Rho); + double sum2, sum3; + for (int i=0; i<14; i++) + sum -= Cprime(i, rt, rt2, rt3)*I(i, egrho); + +// add \int c_{v,0}/T term + + if (T <= T1) + sum2 = Ghydro[0]*log(T); + else { + if (T < T2) + x = T/T1; + else + x = T2/T1; + xlg = log(x); + int i; + for (i=0, sum2 = 0.0; i<12; i++) + sum2 += Ghydro[i]*pow(xlg, i+1)/(i+1); + sum2 += Ghydro[0]*log(T1); + if (T > T2) { + x = T/T2; + xlg = log(x); + for (i=0, sum3=0.0; i<5; i++) + sum3 += Ghydro[i+12]*pow(xlg,i+1)/(i+1); + sum2 += sum3; + } + } + sum += sum2 + m_entropy_offset; + return sum; + } + +double hydrogen::Pp(){ + double rt = 1.0/T; + double rt2 = rt*rt; + double rt3 = rt*rt2; + double egrho = exp(-Gamma*Rho*Rho); + + double P = Rho*R*T; + for(int i=0; i<14; i++) + P += C(i, rt, rt2)*H(i, egrho); + return P; + } + +//equation D4 +double hydrogen::ldens(){ +if ((T < Tmn) || (T > Tc)) set_Err(TempError); +double x=1-T/Tc; +double sum, term; +int i; +for(i=1, sum=0; i<=6; i++) + sum+=Dhydro[i]*pow(x, 1+double(i-1)/3.0); +term = sum+Roc+Dhydro[0]*pow(x,alpha1); +return term; +} + + +//equation s3 +double hydrogen::Psat(){ +double x = (1.0 - Tt/T)/(1.0 - Tt/Tc); +double result; +if ((T < Tmn) || (T > Tc)) set_Err(TempError); +result = Fhydro[0]*x + Fhydro[1]*x*x + Fhydro[2]*x*x*x + + Fhydro[3]*x*pow(1-x, alpha); +return exp(result)*Pt; +} + + double hydrogen::Tcrit() {return Tc;} + double hydrogen::Pcrit() {return Pc;} + double hydrogen::Vcrit() {return 1.0/Roc;} + double hydrogen::Tmin() {return Tmn;} + double hydrogen::Tmax() {return Tmx;} + char * hydrogen::name() {return "hydrogen";} + char * hydrogen::formula() {return "H2";} + double hydrogen::MolWt() {return M;} + +} diff --git a/ext/tpx/Hydrogen.h b/ext/tpx/Hydrogen.h new file mode 100755 index 000000000..65d3a1af1 --- /dev/null +++ b/ext/tpx/Hydrogen.h @@ -0,0 +1,39 @@ +#ifndef TPX_HYDROGEN_H +#define TPX_HYDROGEN_H + +#include "Sub.h" + +namespace tpx { + +class hydrogen : public Substance{ +public: + hydrogen(){} + virtual ~hydrogen() {} + + double MolWt(); + double Tcrit(); + double Pcrit(); + double Vcrit(); + double Tmin(); + double Tmax(); + char * name(); + char * formula(); + + double Pp(); + double up(); + double sp(); + double Psat(); + +private: + double ldens(); + double C(int i, double rt, double rt2); + double Cprime(int i, double rt, double rt2, double rt3); + double I(int i, double egrho); + double H(int i, double egrho); + double W(int i, double egrho); + double icv(int i, double x, double xlg); + }; + +} + +#endif // ! HYDROGEN_H diff --git a/ext/tpx/Makefile.in b/ext/tpx/Makefile.in new file mode 100755 index 000000000..9a1f0e9b0 --- /dev/null +++ b/ext/tpx/Makefile.in @@ -0,0 +1,43 @@ +#/bin/sh + +SUFFIXES= +SUFFIXES= .cpp .d .o + +OBJDIR = . + +CXX_FLAGS = @CXXFLAGS@ $(CXX_OPT) + +COBJS = Methane.o Nitrogen.o Oxygen.o Water.o Hydrogen.o Sub.o utils.o + +FOBJS = + +CXX_LIBS = @LIBS@ +CXX_INCLUDES = -I../include +TPLIB = ./libtpx.a + +DEPENDS = $(COBJS:.o=.d) + +all: $(TPLIB) + +%.d: + g++ -MM $(CXX_INCLUDES) $*.cpp > $*.d + +.cpp.o: + @CXX@ -c $< @DEFS@ $(CXX_FLAGS) $(CXX_INCLUDES) + +.f.o: + @F77@ -c $< $(F77_FLAGS) + +$(TPLIB): $(COBJS) $(FOBJS) + @ARCHIVE@ $(TPLIB) $(COBJS) $(FOBJS) > /dev/null + +clean: + $(RM) $(COBJS) $(FOBJS) *~ + +depends: $(DEPENDS) + cat *.d > .depends + $(RM) $(DEPENDS) + +include .depends + + diff --git a/ext/tpx/Methane.cpp b/ext/tpx/Methane.cpp new file mode 100755 index 000000000..383af185e --- /dev/null +++ b/ext/tpx/Methane.cpp @@ -0,0 +1,212 @@ +// Methane + +#include "Methane.h" +#include +#include +using namespace std; + +namespace tpx { + +static const double + M = 16.04996, + Tmn = 90.68, + Tmx = 1700.0, + Tc = 190.555, + Pc = 4.5988e6, + Roc= 160.43, + To = 90.68, + Tt = 90.68, + Pt=11743.5675, + R = 5.18253475866e2, + Gamma=3.72992471469e-5, + alpha = 1.5, //Used with Psat + alpha1 = .36, //used with ldens; + Rot=451.562, + beta=2009.152, + u0 = 357696.0858, + s0 = -1918.035071; + +static const double Ameth[] = + { -7.25929210183, 4.13766054566e2, -6.32167316855e3, + 3.34015577724e5, -1.68253379982e7, 1.87884851902e-2, -1.18673201223e1, + 2.09062618015e3, -4.07532656958e5, -5.73917603241e-5,4.37711441593e-2, + -4.38766500673, 1.13524630779e-5, -5.07028240949e-5, 2.28002199522e-2, + 9.25611329590e-9, 1.33865662546e-10, -1.65439044196e-7, 1.81030980110e-10, + 5.45753645958e5, -3.63192281933e7, 4.81463473761, 1.56633022620e5, + 7.89977010972e-5, 1.39993881210e-2, -1.70656092212e-11, -4.55256623445e-5, + -2.29314170748e-14,8.31548197665e-12, 6.84673626259e-20, + -4.70845544152e-17, 5.21465091383e-16 }; + +static const double Dmeth[]= + { -1.78860165e-1, 4.83847500e-2, -1.84898700e-2 }; + +static const double Fmeth[]= + { 4.77748580, 1.76065363, -5.67888940e-1, 1.32786231 }; + +static const double Gmeth[]= + { 1.34740610e3, 1.35512060e2, -2.93910458e1, 2.12774600, 2.44656600e3 }; + +// double rt, rt2, rt3, egrho; + +double methane::C(int i, double rt, double rt2) { + switch(i) { + case 0 : + return Ameth[0] * T + Ameth[1] * sqrt(T) + Ameth[2] + (Ameth[3] + Ameth[4] * rt) * rt; + case 1 : + return Ameth[5] * T + Ameth[6] + rt * (Ameth[7] + Ameth[8] * rt); + case 2 : + return Ameth[9] * T + Ameth[10] + Ameth[11] * rt; + case 3 : + return Ameth[12]; + case 4 : + return rt*(Ameth[13] + Ameth[14]*rt); + case 5 : + return Ameth[15]*rt; + case 6 : + return rt*(Ameth[16] + Ameth[17]*rt); + case 7 : + return Ameth[18]*rt2; + case 8 : + return rt2*(Ameth[19] + Ameth[20]*rt); + case 9 : + return rt2*(Ameth[21] + Ameth[22]*rt2); + case 10 : + return rt2*(Ameth[23] + Ameth[24]*rt); + case 11 : + return rt2*(Ameth[25] + Ameth[26]*rt2); + case 12 : + return rt2*(Ameth[27] + Ameth[28]*rt); + case 13 : + return rt2*(Ameth[29] + Ameth[30]*rt + Ameth[31]*rt2); + default : + return 0.0; + } + } + +double methane::Cprime(int i, double rt, double rt2, double rt3) { + switch(i) { + case 0 : + return Ameth[0] + 0.5*Ameth[1]/sqrt(T) - (Ameth[3] + 2.0*Ameth[4]*rt)*rt2; + case 1 : + return Ameth[5] - rt2*(Ameth[7] + 2.0*Ameth[8]*rt); + case 2 : + return Ameth[9] - Ameth[11]*rt2; + case 3 : + return 0.0; + case 4 : + return -rt2*(Ameth[13] + 2.0*Ameth[14]*rt); + case 5 : + return -Ameth[15]*rt2; + case 6 : + return -rt2*(Ameth[16] + 2.0*Ameth[17]*rt); + case 7 : + return -2.0*Ameth[18]*rt3; + case 8 : + return -rt3*(2.0*Ameth[19] + 3.0*Ameth[20]*rt); + case 9 : + return -rt3*(2.0*Ameth[21] + 4.0*Ameth[22]*rt2); + case 10 : + return -rt3*(2.0*Ameth[23] + 3.0*Ameth[24]*rt); + case 11 : + return -rt3*(2.0*Ameth[25] + 4.0*Ameth[26]*rt2); + case 12 : + return -rt3*(2.0*Ameth[27] + 3.0*Ameth[28]*rt); + case 13 : + return -rt3*(2.0*Ameth[29] + 3.0*Ameth[30]*rt + 4.0*Ameth[31]*rt2); + default : + return 0.0; + } + } + +double methane::W(int n, double egrho) { + return (n == 0 ? (1.0 - egrho)/(2.0*Gamma) : + (n*W(n-1, egrho) - 0.5*pow(Rho,2*n)*egrho)/Gamma); + } + +double methane::H(int i, double egrho) { + return (i < 8 ? pow(Rho,i+2) : pow(Rho,2*i-13)*egrho); + } + +double methane::I(int i, double egrho) { + return (i < 8 ? pow(Rho,i+1)/double(i+1) : W(i-8, egrho)); + } + +double methane::up(){ + double rt = 1.0/T; + double rt2 = rt*rt; + double rt3 = rt*rt2; + double egrho = exp(-Gamma*Rho*Rho); + double t3 = pow(T,1.0/3.0); + + double sum = 0.0; + for (int i=0; i<14; i++) + sum += (C(i, rt, rt2) - T*Cprime(i, rt, rt2, rt3))*I(i, egrho); + + sum += T*(Gmeth[0] + 0.75*Gmeth[1]*t3 + 0.6*Gmeth[2]*t3*t3 + 0.5*Gmeth[3]*T) + + Gmeth[4]*beta/(exp(beta*rt) - 1.0) + u0; + return sum + m_energy_offset; + } + +double methane::sp() { + double rt = 1.0/T; + double rt2 = rt*rt; + double rt3 = rt*rt2; + double egrho = exp(-Gamma*Rho*Rho); + double t3 = pow(T,1.0/3.0); + double sum = 0.0; + sum = s0 - R*log(Rho); + for (int i=0; i<14; i++) + sum -= Cprime(i, rt, rt2, rt3)*I(i, egrho); + sum += Gmeth[0]*log(T) + 3.0*Gmeth[1]*t3 + 1.5*Gmeth[2]*t3*t3 + Gmeth[3]*T + + Gmeth[4]*(beta*rt + beta*rt/(exp(beta*rt) - 1.0) + - log(exp(beta*rt) - 1.0)); + return sum + m_entropy_offset; + } + +double methane::Pp(){ + double rt = 1.0/T; + double rt2 = rt*rt; + double egrho = exp(-Gamma*Rho*Rho); + + double P = Rho*R*T; + for(int i=0; i<14; i++) + P += C(i, rt, rt2)*H(i, egrho); + return P; + } + +//equation s3 +double methane::Psat(){ +double x = (1.0 - Tt/T)/(1.0 - Tt/Tc); +double result; +if ((T < Tmn) || (T > Tc)) set_Err(TempError); +result = Fmeth[0]*x + Fmeth[1]*x*x + Fmeth[2]*x*x*x + + Fmeth[3]*x*pow(1-x, alpha); +return exp(result)*Pt; +} + + +//equation D3 +double methane::ldens(){ +double result; +double sum; +double w; +if ((T < Tmn) || (T > Tc)) set_Err(TempError); +w = (Tc - T)/(Tc - Tt); +sum = Dmeth[0]*(1.0 - pow(w, 2.0/3.0)) + Dmeth[1]*(1.0 - pow(w, 4.0/3.0)) + + Dmeth[2]*(1.0 - pow(w, 2)); +result = pow(w,alpha1)*exp(sum); +result *= (Rot-Roc); +result += Roc; +return result; +} + + double methane::Tcrit() {return Tc;} + double methane::Pcrit() {return Pc;} + double methane::Vcrit() {return 1.0/Roc;} + double methane::Tmin() {return Tmn;} + double methane::Tmax() {return Tmx;} + char * methane::name() {return "methane";} + char * methane::formula() {return "CH4";} + double methane::MolWt() {return M;} + +} diff --git a/ext/tpx/Methane.h b/ext/tpx/Methane.h new file mode 100755 index 000000000..8923b77bd --- /dev/null +++ b/ext/tpx/Methane.h @@ -0,0 +1,36 @@ +#ifndef TPX_METHANE_H +#define TPX_METHANE_H + +#include "Sub.h" + +namespace tpx { + + class methane : public Substance{ + public: + methane(){} + virtual ~methane() {} + + double MolWt(); + double Tcrit(); + double Pcrit(); + double Vcrit(); + double Tmin(); + double Tmax(); + char * name(); + char * formula(); + + double Pp(); + double up(); + double sp(); + double Psat(); + + private: + double ldens(); + double C(int i, double rt, double rt2); + double Cprime(int i, double rt, double rt2, double rt3); + double I(int i, double egrho); + double H(int i, double egrho); + double W(int i, double egrho); + }; +} +#endif // ! METHANE_H diff --git a/ext/tpx/Nitrogen.cpp b/ext/tpx/Nitrogen.cpp new file mode 100755 index 000000000..b628b9e58 --- /dev/null +++ b/ext/tpx/Nitrogen.cpp @@ -0,0 +1,221 @@ +// Nitrogen + +#include "Nitrogen.h" +#include +#include +using namespace std; + +namespace tpx { + + + static const double M = 28.01348, + Tmn = 63.15, + Tmx = 2000.0, + Tc = 126.200, + Pc = 3.4e6, + Roc = 314.03, + To = 63.15, + R = 2.96790515164171e2, + Gamma = 7.13602531283233e-6, + alpha = 1.95, + beta = 3353.40610, + u0 = 150877.551, + s0 = 214.9352518; + + + static const double Ann[] = { + 1.75889959256970e-1, 1.38197604384933e1, -3.14918412133921e2, + 4.40300150239380e3, -5.45358971644916e5, 4.84413320182919e-4, + -5.18964416491365e-2, 6.57265859197103e-4 ,8.51299771713314e4 , + 1.33459405162578e-8, 3.83381319826746e-4, -8.35421151028455e-2, + 2.84874912286101e-7, + -2.38296116270360e-7, -1.48321912935764e-4, 5.62605853190540e-10, + -2.98201050924595e-13, 9.85319087685241e-11, -1.92002176056468e-14, + -7.82250103373122e4, -5.51801778744598e5, -5.72781957607352e-1, + 3.25760529488327e2, -1.34659309828737e-6, -1.92036423064911e-5, + -3.94564337674524e-12,-2.44388245328965e-9, -1.50970602460077e-18, + 1.25854885346038e-16,-8.34271144923969e-24, -1.17299202018417e-22, + 9.06544823455730e-22 + }; + + static const double Fnn[]= + { 8.3944094440e3, -1.8785191705e3, -7.2822291650, + 1.0228509660e-2, 5.5560638250e-4, + -5.9445446620e-6, 2.7154339320e-8, + -4.8795359040e-11, 5.0953608240e2 }; + + static const double Dnn[] = + { 3.1402991e2, 4.4111015e2, 9.4622994e2 , + -2.9067111e3, 4.4785979e3, -2.2746914e3 }; + + static const double Gnn[] = + { -2.18203473713518e5, 1.01573580096247e4, -1.65504721657240e2, + 7.43175999190430e2, -5.14605623546025e-3, + 5.18347156760489e-6, -1.05922170493616e-9, 2.98389393363817e2 }; + + + //equation P4 + double nitrogen::C(int i, double rt, double rt2) { + switch(i) { + case 0 : + return Ann[0] * T + Ann[1] * sqrt(T) + + Ann[2] + (Ann[3] + Ann[4] * rt) * rt; + case 1 : + return Ann[5] * T + Ann[6] + rt * (Ann[7] + Ann[8] * rt); + case 2 : + return Ann[9] * T + Ann[10] + Ann[11] * rt; + case 3 : + return Ann[12]; + case 4 : + return rt*(Ann[13] + Ann[14]*rt); + case 5 : + return Ann[15]*rt; + case 6 : + return rt*(Ann[16] + Ann[17]*rt); + case 7 : + return Ann[18]*rt2; + case 8 : + return rt2*(Ann[19] + Ann[20]*rt); + case 9 : + return rt2*(Ann[21] + Ann[22]*rt2); + case 10 : + return rt2*(Ann[23] + Ann[24]*rt); + case 11 : + return rt2*(Ann[25] + Ann[26]*rt2); + case 12 : + return rt2*(Ann[27] + Ann[28]*rt); + case 13 : + return rt2*(Ann[29] + Ann[30]*rt + Ann[31]*rt2); + default : + return 0.0; + } + } + + double nitrogen::Cprime(int i, double rt, double rt2, double rt3) { + switch(i) { + case 0 : + return Ann[0] + 0.5*Ann[1]/sqrt(T) - (Ann[3] + 2.0*Ann[4]*rt)*rt2; + case 1 : + return Ann[5] - rt2*(Ann[7] + 2.0*Ann[8]*rt); + case 2 : + return Ann[9] - Ann[11]*rt2; + case 3 : + return 0.0; + case 4 : + return -rt2*(Ann[13] + 2.0*Ann[14]*rt); + case 5 : + return -Ann[15]*rt2; + case 6 : + return -rt2*(Ann[16] + 2.0*Ann[17]*rt); + case 7 : + return -2.0*Ann[18]*rt3; + case 8 : + return -rt3*(2.0*Ann[19] + 3.0*Ann[20]*rt); + case 9 : + return -rt3*(2.0*Ann[21] + 4.0*Ann[22]*rt2); + case 10 : + return -rt3*(2.0*Ann[23] + 3.0*Ann[24]*rt); + case 11 : + return -rt3*(2.0*Ann[25] + 4.0*Ann[26]*rt2); + case 12 : + return -rt3*(2.0*Ann[27] + 3.0*Ann[28]*rt); + case 13 : + return -rt3*(2.0*Ann[29] + 3.0*Ann[30]*rt + 4.0*Ann[31]*rt2); + default : + return 0.0; + } + } + + double nitrogen::W(int n, double egrho) { + return (n == 0 ? (1.0 - egrho)/(2.0*Gamma) : + (n*W(n-1, egrho) - 0.5*pow(Rho,2*n)*egrho)/Gamma); + } + + double nitrogen::H(int i, double egrho) { + return (i < 8 ? pow(Rho,i+2) : pow(Rho,2*i-13)*egrho); + } + + double nitrogen::I(int i, double egrho) { + return (i < 8 ? pow(Rho,i+1)/double(i+1) : W(i-8, egrho)); + } + + double nitrogen::up(){ + double rt = 1.0/T; + double rt2 = rt*rt; + double rt3 = rt*rt2; + double egrho = exp(-Gamma*Rho*Rho); + + double sum = 0.0; + for (int i=0; i<14; i++) + sum += (C(i,rt,rt2) - T*Cprime(i,rt,rt2,rt3))*I(i,egrho); + + sum += (((0.25*Gnn[6]*T + Gnn[5]/3.0)*T + + 0.5*Gnn[4])*T + Gnn[3])*T + Gnn[2]*log(T) + - (Gnn[1] + 0.5*Gnn[0]*rt)*rt + + Gnn[7]*beta/(exp(beta*rt) - 1.0) + u0 + + m_energy_offset; + + return sum; + } + + + double nitrogen::sp() { + double rt = 1.0/T; + double rt2 = rt*rt; + double rt3 = rt*rt2; + double egrho = exp(-Gamma*Rho*Rho); + + double sum = 0.0; + sum = s0 + m_entropy_offset - R*log(Rho); + for (int i=0; i<14; i++) + sum -= Cprime(i,rt,rt2,rt3)*I(i,egrho); + + sum += (((Gnn[6]/3.0)*T + 0.5*Gnn[5])*T + Gnn[4])*T + Gnn[3]*log(T) + -((Gnn[0]*rt/3.0 + 0.5*Gnn[1])*rt + Gnn[2])*rt + + Gnn[7]*(beta*rt + beta*rt/(exp(beta*rt) - 1.0) + - log(exp(beta*rt) - 1.0)); + return sum; + } + + double nitrogen::Pp(){ + double rt = 1.0/T; + double rt2 = rt*rt; + double egrho = exp(-Gamma*Rho*Rho); + + double P = Rho*R*T; + for(int i=0; i<14; i++) + P += C(i,rt,rt2)*H(i,egrho); + return P; + } + + //equation s4 + double nitrogen::Psat(){ + double lnp; + int i; + if ((T < Tmn) || (T > Tc)) set_Err(TempError); + for (i=0, lnp=0; i<=7;i++){ + if (i==3) lnp+=Fnn[i]*pow(Tc-T, alpha); + else lnp+=Fnn[i]*pow(T,i-1); + } + lnp+=Fnn[8]*log(T); + return exp(lnp); + } + + //equation D2 + double nitrogen::ldens(){ + double xx=1-T/Tc, sum=0; + if ((T < Tmn) || (T > Tc)) set_Err(TempError); + for(int i=0;i<=5;i++) + sum+=Dnn[i]*pow(xx,double(i)/3.0); + return sum; + } + + double nitrogen::Tcrit() {return Tc;} + double nitrogen::Pcrit() {return Pc;} + double nitrogen::Vcrit() {return 1.0/Roc;} + double nitrogen::Tmin() {return Tmn;} + double nitrogen::Tmax() {return Tmx;} + char * nitrogen::name() {return "nitrogen";} + char * nitrogen::formula() {return "N2";} + double nitrogen::MolWt() {return M;} +} diff --git a/ext/tpx/Nitrogen.h b/ext/tpx/Nitrogen.h new file mode 100755 index 000000000..20013c560 --- /dev/null +++ b/ext/tpx/Nitrogen.h @@ -0,0 +1,41 @@ + +#ifndef TPX_NITROGEN_H +#define TPX_NITROGEN_H + +#include "Sub.h" + +namespace tpx { + + class nitrogen : public Substance{ + public: + nitrogen() {} + virtual ~nitrogen() {} + + double MolWt(); + double Tcrit(); + double Pcrit(); + double Vcrit(); + double Tmin(); + double Tmax(); + char * name(); + char * formula(); + + double Pp(); + double up(); + double sp(); + double Psat(); + + private: + + double ldens(); + double C(int i, double rt, double rt2); + double Cprime(int i, double rt, double rt2, double rt3); + double I(int i, double egrho); + double H(int i, double egrho); + double W(int i, double egrho); + }; + +} + +#endif // ! TPX_NITROGEN_H + diff --git a/ext/tpx/Oxygen.cpp b/ext/tpx/Oxygen.cpp new file mode 100755 index 000000000..3e6744470 --- /dev/null +++ b/ext/tpx/Oxygen.cpp @@ -0,0 +1,211 @@ +// Oxygen + +#include "Oxygen.h" +#include + +namespace tpx { + +static const double + M = 31.9994, + Tmn = 54.34, + Tmx = 2000.0, + Tc = 154.581, + Pc = 5.0429e6, + Roc = 436.15, + To = 54.34, + R = 2.59820853437877e2, + Gamma = 5.46895508389297e-6, + alpha = 1.91576, + beta = 2239.18105, + u0 = 198884.2435, + s0 = 668.542976; + +static const double Aoxy[] = + { -4.26396872798684e-1, 3.48334938784107e1, -5.77516910418738e2, + 2.40961751553325e4, -1.23332307855543e6, 3.73585286319658e-4, + -1.70178244046465e-1 ,-3.33226903068473e-4, 8.61334799901291e3, + -6.80394661057309e-7, 7.09583347162704e-4, -5.73905688255053e-2, + -1.92123080811409e-7, 3.11764722329504e-8, -8.09463854745591e-6, + -2.22562296356501e-11, 9.18401045361994e-15, 5.75758417511114e-12, + -2.10752269644774e-15, 3.62884761272184e3, -1.23317754317110e6, + -5.03800414800672e-2, 3.30686173177055e2, -5.26259633964252e-8 , + 5.53075442383100e-6, -2.71042853363688e-13, -1.65732450675251e-9 , + -5.82711196409204e-20, 4.42953322148281e-17 ,-2.95529679136244e-25, + -1.92361786708846e-23, 9.43758410350413e-23 }; + +static const double Foxy[] = + { -5.581932039e2, -1.0966262185e2, -8.3456211630e-2, + 2.6603644330e-3, 1.6875023830e-5, -2.1262477120e-7, + 9.5741096780e-10, -1.6617640450e-12, 2.7545605710e1 }; + +static const double Doxy[] = + { 4.3615175e2, 7.5897189e2, -4.2576866e2, 2.3487106e3, -3.0474660e3, 1.4850169e3 }; + +static const double Goxy[] = + { -1.29442711174062e6, 5.98231747005341e4, -8.97850772730944e2, + 6.55236176900400e2, -1.13131252131570e-2, + 3.4981070244228e-6, 4.21065222886885e-9, 2.67997030050139e2 }; + +//equation P4 + + double oxygen::C(int i, double rt, double rt2) { + switch(i) { + case 0 : + return Aoxy[0] * T + Aoxy[1] * sqrt(T) + Aoxy[2] + (Aoxy[3] + Aoxy[4] * rt) * rt; + case 1 : + return Aoxy[5] * T + Aoxy[6] + rt * (Aoxy[7] + Aoxy[8] * rt); + case 2 : + return Aoxy[9] * T + Aoxy[10] + Aoxy[11] * rt; + case 3 : + return Aoxy[12]; + case 4 : + return rt*(Aoxy[13] + Aoxy[14]*rt); + case 5 : + return Aoxy[15]*rt; + case 6 : + return rt*(Aoxy[16] + Aoxy[17]*rt); + case 7 : + return Aoxy[18]*rt2; + case 8 : + return rt2*(Aoxy[19] + Aoxy[20]*rt); + case 9 : + return rt2*(Aoxy[21] + Aoxy[22]*rt2); + case 10 : + return rt2*(Aoxy[23] + Aoxy[24]*rt); + case 11 : + return rt2*(Aoxy[25] + Aoxy[26]*rt2); + case 12 : + return rt2*(Aoxy[27] + Aoxy[28]*rt); + case 13 : + return rt2*(Aoxy[29] + Aoxy[30]*rt + Aoxy[31]*rt2); + default : + return 0.0; + } + } + + double oxygen::Cprime(int i, double rt, double rt2, double rt3) { + switch(i) { + case 0 : + return Aoxy[0] + 0.5*Aoxy[1]/sqrt(T) - (Aoxy[3] + 2.0*Aoxy[4]*rt)*rt2; + case 1 : + return Aoxy[5] - rt2*(Aoxy[7] + 2.0*Aoxy[8]*rt); + case 2 : + return Aoxy[9] - Aoxy[11]*rt2; + case 3 : + return 0.0; + case 4 : + return -rt2*(Aoxy[13] + 2.0*Aoxy[14]*rt); + case 5 : + return -Aoxy[15]*rt2; + case 6 : + return -rt2*(Aoxy[16] + 2.0*Aoxy[17]*rt); + case 7 : + return -2.0*Aoxy[18]*rt3; + case 8 : + return -rt3*(2.0*Aoxy[19] + 3.0*Aoxy[20]*rt); + case 9 : + return -rt3*(2.0*Aoxy[21] + 4.0*Aoxy[22]*rt2); + case 10 : + return -rt3*(2.0*Aoxy[23] + 3.0*Aoxy[24]*rt); + case 11 : + return -rt3*(2.0*Aoxy[25] + 4.0*Aoxy[26]*rt2); + case 12 : + return -rt3*(2.0*Aoxy[27] + 3.0*Aoxy[28]*rt); + case 13 : + return -rt3*(2.0*Aoxy[29] + 3.0*Aoxy[30]*rt + 4.0*Aoxy[31]*rt2); + default : + return 0.0; + } + } + +double oxygen::W(int n, double egrho) { + return (n == 0 ? (1.0 - egrho)/(2.0*Gamma) : + (n*W(n-1, egrho) - 0.5*pow(Rho,2*n)*egrho)/Gamma); + } + +double oxygen::H(int i, double egrho) { + return (i < 8 ? pow(Rho,i+2) : pow(Rho,2*i-13)*egrho); + } + +double oxygen::I(int i, double egrho) { + return (i < 8 ? pow(Rho,i+1)/double(i+1) : W(i-8, egrho)); + } + +double oxygen::up(){ + double rt = 1.0/T; + double rt2 = rt*rt; + double rt3 = rt*rt2; + double egrho = exp(-Gamma*Rho*Rho); + + double sum = 0.0; + for (int i=0; i<14; i++) + sum += (C(i,rt,rt2) - T*Cprime(i,rt,rt2,rt3))*I(i,egrho); + + sum += (((0.25*Goxy[6]*T + Goxy[5]/3.0)*T + 0.5*Goxy[4])*T + Goxy[3])*T + Goxy[2]*log(T) + - (Goxy[1] + 0.5*Goxy[0]*rt)*rt + Goxy[7]*beta/(exp(beta*rt) - 1.0) + u0; + + return sum + m_energy_offset; + } + +double oxygen::sp() { + double rt = 1.0/T; + double rt2 = rt*rt; + double rt3 = rt*rt2; + double egrho = exp(-Gamma*Rho*Rho); + + double sum = 0.0; + sum = s0 - R*log(Rho); + for (int i=0; i<14; i++) + sum -= Cprime(i,rt,rt2,rt3)*I(i,egrho); + + sum += (((Goxy[6]/3.0)*T + 0.5*Goxy[5])*T + Goxy[4])*T + Goxy[3]*log(T) + -((Goxy[0]*rt/3.0 + 0.5*Goxy[1])*rt + Goxy[2])*rt + + Goxy[7]*(beta*rt + beta*rt/(exp(beta*rt) - 1.0) + - log(exp(beta*rt) - 1.0)); + return sum + m_entropy_offset; + } + +double oxygen::Pp(){ + double rt = 1.0/T; + double rt2 = rt*rt; + double rt3 = rt*rt2; + double egrho = exp(-Gamma*Rho*Rho); + + double P = Rho*R*T; + for(int i=0; i<14; i++) + P += C(i,rt,rt2)*H(i,egrho); + return P; + } + +//equation s4 +double oxygen::Psat(){ + double lnp; + int i; + if ((T < Tmn) || (T > Tc)) set_Err(TempError); + for (i=0, lnp=0; i<=7;i++){ + if (i==3) lnp+=Foxy[i]*pow(Tc-T, alpha); + else lnp+=Foxy[i]*pow(T,i-1); + } + lnp+=Foxy[8]*log(T); + return exp(lnp); + } + +//equation D2 +double oxygen::ldens(){ + double xx=1-T/Tc, sum=0; + if ((T < Tmn) || (T > Tc)) set_Err(TempError); + for(int i=0;i<=5;i++) + sum+=Doxy[i]*pow(xx,double(i)/3.0); + return sum; +} + + double oxygen::Tcrit() {return Tc;} + double oxygen::Pcrit() {return Pc;} + double oxygen::Vcrit() {return 1.0/Roc;} + double oxygen::Tmin() {return Tmn;} + double oxygen::Tmax() {return Tmx;} + char * oxygen::name() {return "oxygen";} + char * oxygen::formula() {return "O2";} + double oxygen::MolWt() {return M;} + +} diff --git a/ext/tpx/Oxygen.h b/ext/tpx/Oxygen.h new file mode 100755 index 000000000..fc8d1c7e2 --- /dev/null +++ b/ext/tpx/Oxygen.h @@ -0,0 +1,38 @@ +#ifndef TPX_OXYGEN_H +#define TPX_OXYGEN_H + +#include "Sub.h" + +namespace tpx { + +class oxygen : public Substance{ +public: + oxygen(){} + virtual ~oxygen() {} + + double MolWt(); + double Tcrit(); + double Pcrit(); + double Vcrit(); + double Tmin(); + double Tmax(); + char * name(); + char * formula(); + + double Pp(); + double up(); + double sp(); + double Psat(); + +private: + double ldens(); + double C(int i, double rt, double rt2); + double Cprime(int i, double rt, double rt2, double rt3); + double I(int i, double egrho); + double H(int i, double egrho); + double W(int i, double egrho); + }; + +} +#endif // ! OXYGEN_H + diff --git a/ext/tpx/Sub.cpp b/ext/tpx/Sub.cpp new file mode 100755 index 000000000..c85c618a9 --- /dev/null +++ b/ext/tpx/Sub.cpp @@ -0,0 +1,583 @@ +/* + * The Substance class + * D. Goodwin, Caltech Nov. 1996 + */ +#include "Sub.h" +#include +#include + +namespace tpx { + + string errorMsg(int flag) { + switch(flag) { + case NoConverge: return "no convergence"; + case GenError: return "general error"; + case InvalidInput: return "invalid input"; + case TempError: return "temperature error"; + case PresError: return "pressure error"; + default: return "(unknown error)"; + } + } + + //-------------- Public Member Functions -------------- + + // Pressure + double Substance::P() { + double ppp = (TwoPhase() ? Ps() : Pp()); + return (Err ? Undef : ppp); + } + + const double DeltaT = 0.000001; + + // dPs/dT + double Substance::dPsdT() { + double ps1, tsave, dpdt; + tsave = T; + ps1 = Ps(); + set_T(T + DeltaT); + dpdt = (Ps() - ps1)/DeltaT; + set_T(tsave); + return (Err ? Undef : dpdt); + } + + // TwoPhase() true if liquid/vapor mixture + + int Substance::TwoPhase() { + if (T >= Tcrit()) return 0; + update_sat(); + return ((Rho < Rhf) && (Rho > Rhv) ? 1 : 0); +} + + // x() calculates the vapor fraction. + // If T >= Tcrit, 0 is returned for v < Vcrit; 1 otherwise. + + double Substance::x() { + double xx, vv, vl; + if (T >= Tcrit()) + return (1.0/Rho < Vcrit() ? 0.0 : 1.0); + else { + update_sat(); + if (Rho <= Rhv) + xx = 1.0; + else if (Rho >= Rhf) + xx = 0.0; + else { + vv = 1.0/Rhv; + vl = 1.0/Rhf; + xx = (1.0/Rho - vl)/(vv - vl); + } + return (Err ? Undef : xx); + } + } + + double Substance::Tsat(double p) { + double Tsave, p_here, dp, dt, dpdt, dta, + dtm, tsat; + if (Err || (p <= 0.0) || (p > Pcrit())) { + set_Err(PresError); + return Undef; + } + int LoopCount = 0; + double tol = 1.e-6*p; + Tsave = T; + if (T < Tmin()) T = 0.5*(Tcrit() - Tmin()); + do { + if (Err) break; + if (T > Tcrit()) T = Tcrit() - 0.001; + if (T < Tmin()) T = Tmin() + 0.001; + p_here = Ps(); + dpdt = dPsdT(); + dp = p - p_here; + dt = dp/dpdt; + dta = fabs(dt); + dtm = 0.1*T; + if (dta > dtm) dt = dt*dtm/dta; + T = T + dt; + LoopCount++; + if (LoopCount > 100) { + T = Tsave; + set_Err(NoConverge); + return Undef; + } + } while (fabs(dp) > tol); + tsat = T; + T = Tsave; + return (Err ? Undef : tsat); + } + + + // absolute tolerances + + double TolAbsH = 0.01; // J/kg + double TolAbsU = 0.01; + double TolAbsS = 1.e-5; + double TolAbsP = 0.000; // Pa + double TolAbsV = 1.e-7; + double TolAbsT = 1.e-3; + double TolRel = 3.e-6; + + void Substance::Set(int XY, double x0, double y0) { + double temp; + + clear_Err(); // clear error flag + + /* if inverted (PT) switch order and change sign of XY (TP = -PT) */ + if (XY < 0) { + double tmp = x0; + x0 = y0; + y0 = tmp; + XY *= -1; + } + + switch(XY) { + case TV: + set_T(x0); set_v(y0); break; + + case HP: + if (Lever(Pgiven, y0, x0, EvalH)) return; + set_xy(EvalH, EvalP, x0, y0, TolAbsH, TolAbsP, TolRel, TolRel); + break; + + case SP: + if (Lever(Pgiven, y0, x0, EvalS)) return; + set_xy(EvalS, EvalP, x0, y0, TolAbsS, TolAbsP, TolRel, TolRel); + break; + + case PV: + if (Lever(Pgiven, x0, y0, EvalV)) return; + set_xy(EvalP, EvalV, x0, y0, TolAbsP, TolAbsV, TolRel, TolRel); + break; + + case TP: + if (x0 < Tcrit()) { + set_T(x0); + if (y0 < Ps()) { + Set(TX, x0, Vapor); + } + else { + Set(TX, x0, Liquid); + } + } + else + set_T(x0); + set_xy(EvalT, EvalP, x0, y0, TolAbsT, TolAbsP, TolRel, TolRel); + break; + + case UV: + set_xy(EvalU, EvalV, x0, y0, TolAbsU, TolAbsV, TolRel, TolRel); + break; + + case ST: + if (Lever(Tgiven, y0, x0, EvalS)) return; + set_xy(EvalS, EvalT, x0, y0, TolAbsS, TolAbsT, TolRel, TolRel); + break; + + case SV: + set_xy(EvalS, EvalV, x0, y0, TolAbsS, TolAbsV, TolRel, TolRel); + break; + + case UP: + if (Lever(Pgiven, y0, x0, EvalU)) return; + set_xy(EvalU, EvalP, x0, y0, TolAbsU, TolAbsP, TolRel, TolRel); + break; + + case VH: + set_xy(EvalV, EvalH, x0, y0, TolAbsV, TolAbsH, TolRel, TolRel); + break; + + case TH: + set_xy(EvalT, EvalH, x0, y0, TolAbsT, TolAbsH, TolRel, TolRel); + break; + + case SH: + set_xy(EvalS, EvalH, x0, y0, TolAbsS, TolAbsH, TolRel, TolRel); + break; + + case PX: + temp = Tsat(x0); + if ((y0 >= 0.0) && (y0 <= 1.0) && (temp < Tcrit())) { + set_T(temp); + update_sat(); + Rho = 1.0/((1.0 - y0)/Rhf + y0/Rhv); + } + else + set_Err(InvalidInput); + break; + + case TX: + if ((y0 >= 0.0) && (y0 <= 1.0) && (x0 < Tcrit())) { + set_T(x0); + update_sat(); + Rho = 1.0/((1.0 - y0)/Rhf + y0/Rhv); + } + else { + set_Err(InvalidInput); + } + break; + + default: + set_Err(InvalidInput); + } + if (Err) { + T = Undef; + Rho = Undef; + Tslast = Undef; + Rhf = Undef; + Rhv = Undef; + } + } + + //------------------ Protected and Private Functions ------------------- + + void Substance::set_Rho(double r0) { + if (r0 > 0.0) { + Rho = r0; + } + else + set_Err(InvalidInput); + } + + void Substance::set_T(double t0) { + if ((t0 >= Tmin()) && (t0 <= Tmax())) { + T = t0; + } + else { + set_Err(TempError); + } + } + + void Substance::set_v(double v0) { + if (v0 > 0) { + Rho = 1.0/v0; + } + else + set_Err(InvalidInput); + } + + double Substance::Ps() { + if (T < Tmin() || T > Tcrit()) { + set_Err(TempError); + return Undef; + } + update_sat(); + return Pst; + } + + // update saturated liquid and vapor densities and saturation pressure + + void Substance::Set_meta(double phase, double pp) { + if (phase == Liquid) + Rho = ldens(); // trial value = liquid dens + else + Rho = pp*MolWt()/(8314.0*T); // trial value = ideal gas + set_TPp(T, pp); + } + + void Substance::update_sat() { + if ((T != Tslast) && (T < Tcrit())) { + double Rho_save = Rho; + double gf, gv, dg, dp, dlp, psold; + + double pp = Psat(); + double lps = log(pp); + + // trial value = Psat from correlation + int i; + + for (i = 0; i<20; i++) { + + Rho = ldens(); // trial value = liquid density + set_TPp(T,pp); + Rhf = Rho; // sat liquid density + gf = hp() - T*sp(); + Rho = pp*MolWt()/(8314.0*T); // trial value = ideal gas + set_TPp(T,pp); + Rhv = Rho; // sat vapor density + gv = hp() - T*sp(); + dg = gv - gf; + + if (fabs(dg) < 0.001) break; + dp = dg/(1.0/Rhv - 1.0/Rhf); + psold = pp; + + if (fabs(dp) > pp) { + dlp = dg/(pp*(1.0/Rhv - 1.0/Rhf)); + lps -= dlp; + pp = exp(lps); + } + else + pp -= dp; + } + if (i >= 20) { + Pst = Undef; + Rhv = Undef; + Rhf = Undef; + Tslast = Undef; + set_Err(NoConverge); + } + else { + Pst = pp; + Tslast = T; + } + Rho = Rho_save; + } + } + + double Substance::vprop(int ijob) { + switch (ijob) { + case EvalH: return hp(); + case EvalS: return sp(); + case EvalU: return up(); + case EvalV: return vp(); + case EvalP: return Pp(); + default: return Undef; + } + } + + int Substance::Lever(int itp, double sat, double val, int ifunc) { + /* + * uses lever rule to set state in the dome. Returns 1 if in dome, + * 0 if not, in which case state not set. + */ + double Valf, Valg, Tsave, Rhosave, xx, vv, psat; + Tsave = T; + Rhosave = Rho; + if (itp == Tgiven) { + if (sat >= Tcrit()) return 0; + set_T(sat); + psat = Ps(); + } + else if (itp == Pgiven) { + if (sat >= Pcrit()) return 0; + psat = sat; + T = Tsat(psat); + } + else { + set_Err(GenError); + return GenError; + } + Set(TX, T, Vapor); + Valg = vprop(ifunc); + Set(TX, T, Liquid); + Valf = vprop(ifunc); + if (Err) + return Err; + else if ((val >= Valf) && (val <= Valg)) { + xx = (val - Valf)/(Valg - Valf); + vv = (1.0 - xx)/Rhf + xx/Rhv; + set_v(vv); + return 1; + } + else { + T = Tsave; + Rho = Rhosave; + return 0; + } + } + + + void Substance::set_xy(int ifx, int ify, double X, double Y, + double atx, double aty, + double rtx, double rty) { + + double v_here, t_here, dv, dt, dxdt, dydt, dxdv, dydv, + det, x_here, y_here, dvm, dtm, dva, dta; + double Xa, Ya, err_x, err_y; + double dvs1 = 2.0*Vcrit(); + double dvs2 = 0.7*Vcrit(); + int LoopCount = 0; + + double v_save = 1.0/Rho; + double t_save = T; + + if (Err) return; + + if ((T == Undef) && (Rho == Undef)) { // new object, try to pick + Set(TV,Tcrit()*1.1,Vcrit()*1.1); // "reasonable" starting point + t_here = T; + v_here = 1.0/Rho; + } + else { + v_here = v_save; + t_here = t_save; + } + + Xa = fabs(X); + Ya = fabs(Y); + + + // loop + do { + if (Err) break; + x_here = prop(ifx); + y_here = prop(ify); + err_x = fabs(X - x_here); + err_y = fabs(Y - y_here); + if ((err_x < atx + rtx*Xa) && (err_y < aty + rty*Ya)) break; + + /* perturb t */ + dt = 0.001*t_here; + if (t_here + dt > Tmax()) + dt *= -1.0; + + /* perturb v */ + dv = 0.001*v_here; + if (v_here <= Vcrit()) dv *= -1.0; + + /* derivatives with respect to T */ + Set(TV, t_here + dt, v_here); + dxdt = (prop(ifx) - x_here)/dt; + dydt = (prop(ify) - y_here)/dt; + + /* derivatives with respect to v */ + Set(TV, t_here, v_here + dv); + dxdv = (prop(ifx) - x_here)/dv; + dydv = (prop(ify) - y_here)/dv; + + det = dxdt*dydv - dydt*dxdv; + dt = ((X - x_here)*dydv - (Y - y_here)*dxdv)/det; + dv = ((Y - y_here)*dxdt - (X - x_here)*dydt)/det; + + dvm = 0.2*v_here; + if (v_here < dvs1) dvm *= 0.5; + if (v_here < dvs2) dvm *= 0.5; + dtm = 0.1*t_here; + dva = fabs(dv); + dta = fabs(dt); + if (dva > dvm) dv *= dvm/dva; + if (dta > dtm) dt *= dtm/dta; + v_here += dv; + t_here += dt; + if (t_here >= Tmax()) + t_here = Tmax() - 0.001; + else if (t_here <= Tmin()) + t_here = Tmin() + 0.001; + if (v_here <= 0.0) + v_here = 0.0001; + Set(TV, t_here, v_here); + LoopCount++; + if (LoopCount > 200) { + set_Err(NoConverge); + break; + } + } while(1); + } + + + double Substance::prop(int ijob) { + double xx, pp, lp, vp, Rho_save; + if (ijob == EvalP) return P(); + if (ijob == EvalT) return T; + xx = x(); + if ((xx > 0.0) && (xx < 1.0)) { + Rho_save = Rho; + Rho = Rhv; + vp = vprop(ijob); + Rho = Rhf; + lp = vprop(ijob); + pp = (1.0 - xx)*lp + xx*vp; + Rho = Rho_save; + return pp; + } + else + return vprop(ijob); + } + + int kbr; + const double ErrP = 1.e-7; + const double Big = 1.e30; + + double Vmin, Vmax, Pmin, Pmax, dvs1, dvs2, dpdv, dvbf, dv, dva, dvm, + dt, v_here, P_here, vt; + + void Substance::BracketSlope(double Pressure) { + if (kbr == 0) { + dv = (v_here < Vcrit() ? -0.05*v_here : 0.2*v_here); + if (Vmin > 0.0) + dv = 0.2*v_here; + if (Vmax < Big) + dv = -0.05*v_here; + } + else { + double dpdv = (Pmax - Pmin)/(Vmax - Vmin); + v_here = Vmax; + P_here = Pmax; + dv = dvbf*(Pressure - P_here)/dpdv; + dvbf = 0.5*dvbf; + } + } + + void Substance::set_TPp(double Temp, double Pressure) { + kbr = 0; + dvbf = 1.0; + Vmin = 0.0; + Vmax = Big; + Pmin = Big; + Pmax = 0.0; + dvs1 = 2.0*Vcrit(); + dvs2 = 0.7*Vcrit(); + int LoopCount = 0; + + double v_save = 1.0/Rho; + set_T(Temp); + v_here = vp(); + + // loop + + while(P_here = Pp(), fabs(Pressure - P_here) >= ErrP*Pressure) { + if (P_here < 0.0) + BracketSlope(Pressure); + else { + dv = 0.001*v_here; + if (v_here <= Vcrit()) dv *= -1.0; + Set(TV, Temp, v_here+dv); + dpdv = (Pp() - P_here)/dv; + if (dpdv > 0.0) { + BracketSlope(Pressure); + } + else { + if ((P_here > Pressure) && (v_here > Vmin)) + Vmin = v_here; + else if ((P_here < Pressure) && (v_here < Vmax)) + Vmax = v_here; + if (v_here == Vmin) Pmin = P_here; + if (v_here == Vmax) Pmax = P_here; + if (Vmin >= Vmax) + set_Err(GenError); + else if ((Vmin > 0.0) && (Vmax < Big)) kbr = 1; + dvbf = 1.0; + if (dpdv == 0.0) { + dvbf = 0.5; + BracketSlope(Pressure); + } + else { + dv = (Pressure - P_here)/dpdv; + } + } + } + dvm = 0.2*v_here; + if (v_here < dvs1) dvm *= 0.5; + if (v_here < dvs2) dvm *= 0.5; + if (kbr != 0) { + vt = v_here + dv; + if ((vt < Vmin) || (vt > Vmax)) + dv = Vmin + (Pressure - Pmin)*(Vmax - Vmin)/(Pmax - Pmin) - v_here; + } + dva = fabs(dv); + if (dva > dvm) dv *= dvm/dva; + v_here += dv; + if (dv == 0.0) { + set_Err(NoConverge); + return; + } + Set(TV, Temp, v_here); + LoopCount++; + if (LoopCount > 100) { + Set(TV, Temp, v_save); + set_Err(NoConverge); + return; + } + } + Set(TV, Temp,v_here); + } +} diff --git a/ext/tpx/Sub.h b/ext/tpx/Sub.h new file mode 100755 index 000000000..c0c0d78d7 --- /dev/null +++ b/ext/tpx/Sub.h @@ -0,0 +1,217 @@ +/* + * This is the base substance class from which all substances are derived + * + * Kate Talmazan: SURF -- July, 1995 + * original implementation of this class and all derived classes from + * formulas given in TPSI. Implementation of P(Rho, T), cv0(T), ldens(T), + * and Psat(T) for all substances in TPSI.f + * + * Dave Goodwin: Fall, 1996 + * functions for u, h, s, f, g; + * functions to set state + * error handling + * documentation + * + * Sept., 2001: minor modifications to use with Cantera + * + */ + +#ifndef TPX_SUB_H +#define TPX_SUB_H + +#include +#include +using namespace std; + +namespace tpx { + + const double OneAtm = 1.01325e5; + const double Liquid = 0.0; + const double Vapor = 1.0; + + const int TV = 12, HP = 34, SP = 54, PV = 42, TP = 14, UV = 62, + ST = 51, SV = 52, UP = 64, VH = 23, TH = 13, SH = 53, + PX = 47, TX = 17; + + const int VT = -12, PH = -34, PS = -54, VP = -42, PT = -14, VU = -62, + TS = -51, VS = -52, PU = -64, HV = -23, HT = -13, HS = -53, + XP = -47, XT = -17; + + const int NoConverge = -900; + const int GenError = -901; + const int InvalidInput = -902; + const int TempError = -800; + const int PresError = -801; + const int CKError = -802; + + + const int Pgiven = 0, Tgiven = 1; + + const int EvalH = 3; const int EvalS = 5; + const int EvalU = 6; const int EvalV = 2; const int EvalP = 4; + const int EvalT = 1; const int EvalX = 7; const int EvalF = 8; + const int EvalG = 9; const int EvalC = 10; + const int EvalM = 11; const int EvalN = 12; const int EvalMW = 13; + const int EvalEA = 14; + const int EvalCdot = 15; const int EvalDdot = 16; const int EvalWdot = 17; + const int EvalTchem = 18; const int EvalRgas = 19; + + const double Undef = 999.1234; + + string errorMsg(int flag); + + class Substance { + public: + Substance() { + T = Undef; + Rho = Undef; + Tslast = Undef; + Rhf = Undef; + Rhv = Undef; + Pst = Undef; + Err = 0; + m_energy_offset = 0.0; + m_entropy_offset = 0.0; + } + virtual ~Substance(){} + + void setStdState(double h0 = 0.0, double s0 = 0.0, + double t0 = 298.15, double p0 = 1.01325e5) { + Set(TP, t0, p0); + double hoff = h0 - h(); + double soff = s0 - s(); + m_entropy_offset = soff; + m_energy_offset = hoff; + } + + // information about a substance: + + virtual double MolWt()=0; // molecular weight, kg/kmol + virtual double Tcrit()=0; // critical temperature, K + virtual double Pcrit()=0; // critical pressure, Pa + virtual double Vcrit()=0; // critical specific vol, m^3/kg + virtual double Tmin()=0; // min. temp for which equations valid + virtual double Tmax()=0; // max. temp for which equations valid + virtual char * name() = 0; // name + virtual char * formula() = 0; // chemical formula + + // properties: + + double P(); // pressure, Pa + double Temp() {return T;} // temperature, K + double v() // specific vol, m^3/kg + {return prop(EvalV);} + double u() // int. energy, J/kg + {return prop(EvalU);} + double h() // enthalpy, J/kg + {return prop(EvalH);} + double s() // entropy, J/kg/K + {return prop(EvalS);} + double f() // Helmholz function, J/kg + {return u() - T*s();} + double g() // Gibbs function, J/kg + {return h() - T*s();} + + virtual double cv() { + double Tsave = T, dt = 1.e-4*T; + set_T(Tsave - dt); + double s1 = s(); + set_T(Tsave + dt); + double s2 = s(); + set_T(Tsave); + return T*(s2 - s1)/(2.0*dt); + } + + virtual double cp() { + double Tsave = T, dt = 1.e-4*T; + double p0 = P(); + Set(TP, Tsave - dt, p0); + double s1 = s(); + Set(TP, Tsave + dt, p0); + double s2 = s(); + Set(TP, Tsave, p0); + return T*(s2 - s1)/(2.0*dt); + } + + virtual double thermExpCoeff() { + double Tsave = T, dt = 1.e-4*T; + double p0 = P(); + Set(TP, Tsave - dt, p0); + double v1 = v(); + Set(TP, Tsave + dt, p0); + double v2 = v(); + Set(TP, Tsave, p0); + return (v2 - v1)/((v2 + v1)*dt); + } + + + // saturation properties + + double Ps(); + virtual double dPsdT(); // d(Psat)/dT, Pa/K + double Tsat(double p); // saturation temp at p + double x(); // vapor mass fraction + int TwoPhase(); // =1 if vapor/liquid, 0 otherwise + virtual double Pp()=0; + double hp() {return up() + Pp()/Rho;} + double gp() {return hp() - T*sp();} + + double prop(int ijob); + void set_TPp(double t0, double p0); // set T and P + + + // functions to set or change state: + + void Set(int XY, double x0, double y0); + void Set_meta(double phase, double pp); + + int Error() { + return Err; + } + + + protected: + + double T, Rho; + double Tslast, Rhf, Rhv; + double Pst; + int Err; + double m_energy_offset; + double m_entropy_offset; + + // virtual double Xm(int k) { return 1.0;} + //virtual int Species() { return 1;} + + virtual double ldens()=0; + virtual double Psat()=0; // saturation pressure, Pa + virtual double up()=0; + virtual double sp()=0; + virtual int ideal(){return 0;} // added 9/2/98; default is false + double vp() {return 1.0/Rho;} + int Lever(int itp, double sat, double val, int ifunc); + void update_sat(); + + void set_Err(int ErrFlag) { + if (!Err) Err = ErrFlag; + } + void clear_Err() {Err = 0;} + + +private: + void set_Rho(double r0); + void set_T(double t0); + void set_v(double v0); + void BracketSlope(double p); + double lprop(int ijob); + double vprop(int ijob); + void set_xy(int if1, int if2, double X, double Y, + double atx, double aty, double rtx, double rty); + }; + + void Error(char *message, int flag, double val=Undef); + void Mess(char *message); + +} + + +#endif diff --git a/ext/tpx/Water.cpp b/ext/tpx/Water.cpp new file mode 100755 index 000000000..b60ebdf08 --- /dev/null +++ b/ext/tpx/Water.cpp @@ -0,0 +1,177 @@ +// water + +#include "Water.h" +#include +#include + +namespace tpx { + +static const double Tmn=273.16; +static const double Tmx=1600.0; +static const double M=18.016; +static const double Tc=647.286; +static const double Pc=22.089e6; +static const double Roc=317.0; +static const double To=273.16; +static const double R=461.51; +static const double E=4.8E-3; +static const double Ta=1000.0; +static const double tauc=1.544912; +static const double Tp=338.15; +static const double aww=0.01; +static const double Roa1=634.0; +static const double Roaj=1000.0; +static const double u0=2375470.875; +static const double s0=6697.356635; + +static const double A[10][7]={{2.9492937E-2,-5.1985860E-3, + 6.8335354E-3,-1.5641040E-4, + -6.3972405E-3, -3.9661401E-3, -6.9048554E-4}, + {-1.3213917E-4,7.7779182E-6, -2.6149751E-5,-7.2546108E-7, + 2.6409282E-5, 1.5453061E-5,2.7407416E-6}, + {2.7464632E-7,-3.3301902E-8,6.5326396E-8,-9.2734289E-9, + -4.7740374E-8,-2.9142470E-8,-5.1028070E-9}, + {-3.6093828E-10, -1.6254622E-11, -2.6181978E-11, 4.3125840E-12, + 5.6323130E-11, 2.9568796E-11,3.9636085E-12}, + {3.4218431E-13, -1.7731074E-13,0,0,0,0,0}, + {-2.4450042E-16, 1.2748742E-16,0,0,0,0,0}, + {1.5518535E-19, 1.3746153E-19,0,0,0,0,0}, + {5.9728487E-24,1.5597836E-22, 0,0,0,0,0}, + {-4.1030848E-1, 3.3731180E-1, -1.3746678E-1, 6.7874983E-3, + 1.3687317E-1, 7.984797E-2, 1.3041253E-2}, + {-4.1605860E-4, -2.0988866E-4,-7.3396848E-4,1.0401717E-5, + 6.4581880E-4, 3.9917570E-4, 7.1531353E-5}}; + +static const double F[]={-7.4192420, 2.9721E-1,-1.155286E-1,8.685635E-3, + 1.0940980E-3, -4.39993E-3, 2.5206580E-3, -5.2186840E-4}; + +static const double D[]={3.6711257,-2.8512396E1,2.2265240E2,-8.8243852E2, + 2.0002765E3,-2.6122557E3,1.8297674E3,-5.3350520E2}; + +static const double G[]={4.6E4,1.011249E3,8.3893E-1,-2.19989E-4,2.466619E-7, + -9.704700E-11}; + +static const double taua[] = {1.544912, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5}; + +inline double water::C(int i) { + double tau = Ta/T; + return (i == 0 ? R*T : R*T*(tau - tauc)*pow(tau - taua[i],i-1)); + } + +inline double water::Cprime(int i) { + double tau = Ta/T; + return (i == 0 ? R : (i == 1 ? -R*tauc : + -R*pow(tau - taua[i],i-2)*(tauc*(tau - taua[i]) + + (i-1)*tau*(tau - tauc)))); + } + +inline double water::I(int j) { + double factor, sum, rho_aj; + rho_aj = (j == 0 ? Roa1 : Roaj); + sum = 0.0; + factor = Rho - rho_aj; + for(int i=7; i>0; i--) { + sum += A[i][j]; + sum *= factor; + } + sum += A[0][j]; + sum += (exp(-E*Rho)*(A[8][j] + A[9][j]*Rho)); + return Rho*sum; + } + +inline double water::H(int j) { + double factor, sum, rho_aj; + rho_aj = (j == 0 ? Roa1 : Roaj); + sum = 0.0; + factor = Rho - rho_aj; + for(int i=6; i>0; i--) { + sum += (A[i][j] + Rho*(i+1)*A[i+1][j]); + sum *= factor; + } + sum += (A[0][j] + Rho*A[1][j]); + sum += (exp(-E*Rho)*((1.0 - Rho*E)*A[8][j] + + Rho*(2.0 - Rho*E)*A[9][j])); + sum += A[7][j]*pow(factor,7); + return Rho*Rho*sum; + } + +double water::up() { + double sum = 0.0; + int i; + for (i=0; i<7; i++) + sum += (C(i) - T*Cprime(i))*I(i); + for (i=1; i<6; i++) + sum += G[i]*(pow(T,i) - pow(To,i))/double(i); + sum += G[0]*log(T/To) + u0; + return sum + m_energy_offset; + } + +double water::sp() { + double sum = 0.0; + int i; + for (i=2; i<6; i++) + sum += G[i]*(pow(T,i-1) - pow(To,i-1))/double(i-1); + sum += G[1]*log(T/To); + sum -= G[0]*(1.0/T - 1.0/To); + sum += s0 - R*log(Rho); + for (i=0; i<7; i++) + sum -= Cprime(i)*I(i); + return sum + m_entropy_offset; + } + +double water::Pp(){ + double P = Rho*R*T; + for(int i=0; i<7; i++) + P += C(i)*H(i); + return P; + } + +double water::Psat(){ + double log, sum=0,P; + if ((T < Tmn) || (T > Tc)) + set_Err(TempError); // Error("water::Psat",TempError,T); + for (int i=1;i<=8;i++) + sum += F[i-1]*pow(aww*(T-Tp),double(i-1)); // DGG mod + log = (Tc/T-1)*sum; + P=exp(log)*Pc; + return P; +} + +/* +double water::dPsatdT(){ + double log, sum1=0, sum2=0; + int i; + if ((T < Tmn) || (T > Tc)) + set_Err(TempError); // Error("water::dPsatdT",TempError,T); + for (i=1;i<=8;i++) + sum1 += F[i-1]*pow(a*(T-Tp),double(i-1)); + for (i=2;i<=8;i++) + sum2 += F[i-1]*a*(i-1)*pow(a*(T-Tp),double(i-2)); + log = (Tc/T-1)*sum2 - Tc*sum1/(T*T); + return log*Psat(); +} +*/ + +double water::ldens(){ + double sum=0; + int i; + if ((T < Tmn) || (T >= Tc)) + set_Err(TempError); // Error("water::ldens",TempError,T); + for(i=0;i<=8;i++) + sum+=D[i-1]*pow(1.0 - T/Tc, double(i)/3.0); + double density = Roc*(1+sum); + return density; +} + +double water::Tcrit() {return Tc;} +double water::Pcrit() {return Pc;} +double water::Vcrit() {return 1.0/Roc;} +double water::Tmin() {return Tmn;} +double water::Tmax() {return Tmx;} +char * water::name() {return "water";} +char * water::formula() {return "H2O";} +double water::MolWt() {return M;} + +} + + diff --git a/ext/tpx/Water.h b/ext/tpx/Water.h new file mode 100755 index 000000000..0465d11d9 --- /dev/null +++ b/ext/tpx/Water.h @@ -0,0 +1,38 @@ +#ifndef TPX_WATER_H +#define TPX_WATER_H + +#include "Sub.h" + +namespace tpx { + +class water : public Substance{ +public: + water() {} + ~water() {} + + double MolWt(); + double Tcrit(); + double Pcrit(); + double Vcrit(); + double Tmin(); + double Tmax(); + char * name(); + char * formula(); + + double Pp(); + double up(); + double sp(); + double Psat(); + double dPsatdT(); + +private: + double ldens(); + double C(int i); + double Cprime(int i); + double I(int i); + double H(int i); +}; + +} +#endif // ! WATER_H + diff --git a/ext/tpx/ck_gas.cpp b/ext/tpx/ck_gas.cpp new file mode 100755 index 000000000..3445817a3 --- /dev/null +++ b/ext/tpx/ck_gas.cpp @@ -0,0 +1,26 @@ +// Chemkin ideal gas mixture + +#include "ck_gas.h" +#include + +double ck_gas::up(){ + return ckprop(2, T, Rho, xm); // + h_0(T) +} + +double ck_gas::sp() {return ckprop(3, T, Rho, xm);} + + +double ck_gas::Pp() { + return ckprop(1, T, Rho, xm); +} + +double ck_gas::MolWt() {return ckprop(0, T, Rho, xm);} + +double ck_gas::Cdot(int ks) {return chem(T, Rho, ks, xm, 1);} + +double ck_gas::Ddot(int ks) {return chem(T, Rho, ks, xm, 2);} + +double ck_gas::Wdot(int ks) {return chem(T, Rho, ks, xm, 3);} + +double ck_gas::Tchem(int ks) {return chem(T, Rho, ks, xm, 4);} + diff --git a/ext/tpx/ck_gas.h b/ext/tpx/ck_gas.h new file mode 100755 index 000000000..eae3314e5 --- /dev/null +++ b/ext/tpx/ck_gas.h @@ -0,0 +1,85 @@ +#ifndef CK_GAS_H +#define CK_GAS_H + +#include "sub.h" + +#include + +extern "C" { + __declspec(dllimport) double __stdcall + ckprop(int ijob, double temp, double dens, double *xmole); + + __declspec(dllimport) int __stdcall ckspecies(); + + __declspec(dllimport) double __stdcall + chem(double temp, double dens, int ks, double *xmole, int ijob); +} + +class ck_gas : public Substance{ +public: + + ck_gas() { + kk = ckspecies(); + if (kk > 0) { + T = 300.; + Rho = 0.001; + xm = new double[kk]; + } + } + + + ck_gas(int ki, double *xmoles) + { + kk = ckspecies(); + if (kk > 0 && kk == ki) { + T = 300.; + Rho = 1.; + xm = new double[kk]; + double sum=0.0; + for (int i = 0; i + +double ideal::up(){ + + } + +double ideal::sp() { + + +double ideal::Pp(){ + + +//equation s3 +double ideal::Psat(){ + +} + + +//equation D3 +double ideal::ldens(){ + +} + + double methane::Tcrit() {return 0.0;} + double methane::Pcrit() {return 0.0;} + double methane::Vcrit() {return 0.0;} + double methane::Tmin() {return Tmn;} + double methane::Tmax() {return Tmx;} + char * methane::name() {return "ideal gas";} + char * methane::formula() {return "--";} + double methane::MolWt() {return M;} \ No newline at end of file diff --git a/ext/tpx/lk.cpp b/ext/tpx/lk.cpp new file mode 100755 index 000000000..a5756bd33 --- /dev/null +++ b/ext/tpx/lk.cpp @@ -0,0 +1,131 @@ +// Lee-Kesler equation of state + +#include "lk.h" +#include + +const double b[2][4] = {{0.1181193, 0.265728, 0.154790, 0.030323}, + {0.2026579, 0.331511, 0.027655, 0.203488}}; +const double c[2][4] = {{0.0236744, 0.0186984, 0.0, 0.042724}, + {0.0313385, 0.0503618, 0.016901, 0.041577}}; +const double d[2][2] = {{1.55488e-5, 6.23689e-5},{4.8736e-5, 0.740336e-5}}; +const double beta[2] = {0.65392, 1.226}; +const double gamma[2] = {0.060167, 0.03754}; + +//--------------------------- member functions ------------------ + +double lk::W(int n, double egrho, double Gamma) { + return (n == 0 ? (1.0 - egrho)/(2.0*Gamma) : + (n*W(n-1, egrho, Gamma) - 0.5*pow(Rho,2*n)*egrho)/Gamma); +} + +double lk::up(){ + return -(8314.3/Mw)*T*(1.0 + T*I()/Tcr); // + h_0(T) +} + +double lk::hdep(){ + double tr = T/Tcr; + return tr*tr*I() + (1.0 - z())*tr; +} + +double lk::sdep(){ + double tr = T/Tcr; + return tr*I() + J() - log(z()); +} + +double lk::sp() { + const double Pref = 101325.0; + double rgas = 8314.3/Mw; + return rgas*(log(Pref/(Rho*rgas*T)) - (T/Tcr)*I() - J()); // + s^0(T,p_0) +} + +double lk::I() { // \int_0^\rho_r (1/\rho_r)(dZ/dT_r) d\rho_r + double Bp, Cp, Dp; + double rtr = Tcr/T; + double rtr2 = rtr*rtr; + double rvr = 8314.3*Tcr*Rho/(Pcr*Mw); // 1/v_r^\prime + double rvr2 = rvr*rvr; + double egrho; + + egrho = exp(-gamma[Isr]*rvr2); + Bp = rtr2*b[Isr][1] + 2.0*rtr*rtr2*b[Isr][2] + 3.0*rtr2*rtr2*b[Isr][3]; + Cp = rtr2*c[Isr][1] - 3.0*c[Isr][2]*rtr2*rtr2; + Dp = -d[Isr][1]*rtr2; + double r = Bp*rvr + 0.5*rvr2*Cp + 0.2*pow(rvr,5)*Dp + - 3.0*c[Isr][3]*rtr2*rtr2*(beta[Isr]*W(0,egrho,gamma[Isr]) + + gamma[Isr]*W(1,egrho,gamma[Isr])); + return r; +} + +double lk::J() { // \int_0^\rho_r (1/\rho_r)(Z - 1) d\rho_r + double BB, CC, DD; + double rtr = Tcr/T; + double rtr2 = rtr*rtr; + double rvr = 8314.3*Tcr*Rho/(Pcr*Mw); // 1/v_r^\prime + double rvr2 = rvr*rvr; + double egrho; + + egrho = exp(-gamma[Isr]*rvr2); + BB = b[Isr][0] - rtr*(b[Isr][1] + + rtr*(b[Isr][2] + rtr*b[Isr][3])); + CC = c[Isr][0] - rtr*(c[Isr][1] - c[Isr][2]*rtr*rtr); + DD = d[Isr][0] + d[Isr][1]*rtr; + double r = BB*rvr + 0.5*rvr2*CC + 0.2*pow(rvr,5)*DD + + c[Isr][3]*rtr2*rtr*(beta[Isr]*W(0,egrho,gamma[Isr]) + + gamma[Isr]*W(1,egrho,gamma[Isr])); + return r; +} + +double lk::z() { + double zz, rvr2, BB, CC, DD, EE; + double rtr = Tcr/T; // 1/T_r + double rvr = Rho*8314.3*Tcr/(Pcr*Mw); + rvr2 = rvr*rvr; + BB = b[Isr][0] - rtr*(b[Isr][1] + + rtr*(b[Isr][2] + rtr*b[Isr][3])); + CC = c[Isr][0] - rtr*(c[Isr][1] - c[Isr][2]*rtr*rtr); + DD = d[Isr][0] + d[Isr][1]*rtr; + EE = exp(-gamma[Isr]*rvr2); + + zz = 1.0 + BB*rvr + CC*rvr2 + DD*pow(rvr,5) + + c[Isr][3]*pow(rtr,3)*rvr2* + (beta[Isr] + gamma[Isr]*rvr2)*EE; + return zz; +} + + +double lk::Pp() { + return 8314.3*z()*Rho*T/Mw; +} + +double lk::Psat(){ + double tr = 1.0 - Tcr/T; + double lpr; + + if (Isr == 0) + lpr = 5.395743797*tr + 0.05524287*tr*tr + 0.06853005*tr*tr*tr; + else + lpr = 7.259961465*tr - 0.549206092*tr*tr + 0.177581752*tr*tr*tr; + return Pcr*exp(lpr); +} + +double lk::ldens(){ + double x = 1.0 - T/Tcr; + // for simple fluid + double rho_r; + if (Isr == 0) + rho_r = 5.2307 + 15.16*x - 21.9778*x*x + 18.767*x*x*x; + else { + rho_r = 6.166930606 + 17.42866964*x - 18.62589833*x*x + 11.73957224*x*x*x; + rho_r *= 1.0; + } + return Pcr*rho_r*Mw/(8314.3*Tcr); +} + +double lk::Tcrit() {return Tcr;} +double lk::Pcrit() {return Pcr;} +double lk::Vcrit() {return 0.2901*8314.3*Tcr/(Pcr*Mw);} +double lk::Tmin() {return -100.0;} +double lk::Tmax() {return 10000.0;} +char * lk::name() {return "Lee-Kesler";} +char * lk::formula() {return "---";} +double lk::MolWt() {return Mw;} diff --git a/ext/tpx/lk.h b/ext/tpx/lk.h new file mode 100755 index 000000000..b5bdd6826 --- /dev/null +++ b/ext/tpx/lk.h @@ -0,0 +1,44 @@ +#ifndef LK_H +#define LK_H + +#include "sub.h" + +class lk : public Substance{ +public: + lk(double tc = 1.0, double pc = 1.0, double wt = 1.0, int itype = 0) + { + Tcr = tc; + Pcr = pc; + Mw = wt; + Isr = itype; // simple fluid or reference + }; + ~lk() {}; + + double MolWt(); + double Tcrit(); + double Pcrit(); + double Vcrit(); + double Tmin(); + double Tmax(); + char * name(); + char * formula(); + + double Pp(); + double up(); + double sp(); + double Psat(); + double z(); + double hdep(); + double sdep(); + double ldens(); + +protected: + double Tcr, Pcr, Mw; + int Isr; + +private: + double W(int n, double egrho, double gamma); + double I(); + double J(); +}; +#endif // ! LK_H diff --git a/ext/tpx/lkw.cpp b/ext/tpx/lkw.cpp new file mode 100755 index 000000000..e46672c39 --- /dev/null +++ b/ext/tpx/lkw.cpp @@ -0,0 +1,80 @@ +// Lee-Kesler equation of state + +#include "lkw.h" +#include + +const double omega_ref = 0.3978; + +//--------------------------- member functions ------------------ + +double lkw::z(double Temp, double Pres) { + T = Temp; + f0.Set(TP,Temp,Pres); + f1.Set(TP,Temp,Pres); + if (Temp < Tcrit() && f0.x() != f1.x()) { // need to find Psat + if (Pres >= Ps()) { //liquid + f0.Set_meta(Liquid,Pres); + f1.Set_meta(Liquid,Pres); + } + else { + f0.Set_meta(Vapor,Pres); + f1.Set_meta(Vapor,Pres); + } + } + double z0 = f0.z(); + double zz = z0 + (f1.z() - z0)*Acent/omega_ref; + return zz; +} + + +double lkw::Ps() { + +// start with linear estimate of Psat + double p0 = f0.Psat(); + double pse = p0 + (f1.Psat() - p0)/omega_ref; + double lps = log(pse); + double zf, zv; +// loop until g_f = g_v + for (int i = 0; i<20; i++) { + + f0.Set_meta(Liquid,pse); // set both to liquid + f1.Set_meta(Liquid,pse); + double gf = f0.gp() + (f1.gp() - f0.gp())/omega_ref; + zf = f0.z() + (f1.z() - f0.z())/omega_ref; + + f0.Set_meta(Vapor,pse); // set both to vapor + f1.Set_meta(Vapor,pse); + double gv = f0.gp() + (f1.gp() - f0.gp())/omega_ref; + zv = f0.z() + (f1.z() - f0.z())/omega_ref; + + double gfv = gv - gf; + double dlp = gfv*Mw/(8314.3*T*(zv - zf)); + lps -= dlp; + pse = exp(lps); + if (fabs(gfv) < 0.001) break; + } + if (i >= 20) { + Pst = Undefined; + Rhv = Undefined; + Rhf = Undefined; + Tslast = Undefined; + set_Err(NoConverge); + } + else { + Pst = pse; + Tslast = T; + Rhv = pse*Mw/(zv*8314.3*T); + Rhf = pse*Mw/(zf*8314.3*T); + } + return Pst; +} +/* +double lk::Tcrit() {return Tcr;} +double lk::Pcrit() {return Pcr;} +double lk::Vcrit() {return 0.2901*8314.3*Tcr/(Pcr*Mw);} +double lk::Tmin() {return -100.0;} +double lk::Tmax() {return 10000.0;} +char * lk::name() {return "Lee-Kesler";} +char * lk::formula() {return "---";} +double lk::MolWt() {return Mw;} +*/ diff --git a/ext/tpx/lkw.h b/ext/tpx/lkw.h new file mode 100755 index 000000000..09ceb7c2b --- /dev/null +++ b/ext/tpx/lkw.h @@ -0,0 +1,49 @@ +#ifndef LKW_H +#define LKW_H + +#include "lk.h" + +class lkw { +public: + lkw(double tc = 1.0, double pc = 1.0, double wt = 8314.3, double omega = 0.0) + { + Tcr = tc; + Pcr = pc; + Mw = wt; + Acent = omega; + T = Undefined; + Pressure = Undefined; + }; + ~lkw() {}; +/* + double MolWt(); + double Tcrit(); + double Pcrit(); + double Vcrit(); + double Tmin(); + double Tmax(); + char * name(); + char * formula(); +*/ + double Ps(); +// double Pp(); +// double up(); +// double sp(); +// double Psat(); + double z(double tstar, double pstar); +// double hdep(); +// double sdep(); +// double ldens(); + +protected: + double Tcr, Pcr, Mw; + double Acent; + double Pressure; + double T, Rho, Rhov, Rhof; + lk f0; //(1.0, 1.0, 8314.3, 0); + lk f1; //(1.0, 1.0, 8314.3, 1); + +private: + +}; +#endif // ! LKW_H diff --git a/ext/tpx/mix.h b/ext/tpx/mix.h new file mode 100755 index 000000000..47f70a72d --- /dev/null +++ b/ext/tpx/mix.h @@ -0,0 +1,63 @@ + + +class fluid { +public: + + mix() { + kk = ckspecies(); + if (kk > 0) { + T = 300.; + Rho = 0.001; + xm = new double[kk]; + } + } + + + ck_gas(int ki, double *xmoles) + { + kk = ckspecies(); + if (kk > 0 && kk == ki) { + T = 300.; + Rho = 1.; + xm = new double[kk]; + double sum=0.0; + for (int i = 0; iTcrit();} + double Pcrit() {return fl->Pcrit();} + double Vcrit() {return fl->Vcrit();} + double Tmin() {return fl->Tmin();} + double Tmax() {return fl->Tmax();} + char * name() {return "Gas mixture";} + char * formula() {return "Chemkin";} + double Pp(); + double up(); + double sp(); + int ideal() { return 1;} + + double Psat() { return 0.0; } + double ldens() { return 1.e6; } + +protected: + Substance *fl; + int kk; + double *xm; + +}; +#endif // ! CK_GAS diff --git a/ext/tpx/subs.h b/ext/tpx/subs.h new file mode 100755 index 000000000..639f5f41f --- /dev/null +++ b/ext/tpx/subs.h @@ -0,0 +1,12 @@ +#ifndef TPX_SUBS_H +#define TPX_SUBS_H + +// #include "HFC134a.h" +#include "Hydrogen.h" +#include "Methane.h" +#include "Nitrogen.h" +#include "Oxygen.h" +#include "Water.h" +// #include "lk.h" + +#endif diff --git a/ext/tpx/utils.cpp b/ext/tpx/utils.cpp new file mode 100755 index 000000000..ef6d90ea7 --- /dev/null +++ b/ext/tpx/utils.cpp @@ -0,0 +1,24 @@ +#include "subs.h" +#include "utils.h" + +namespace tpx { + + +Substance * GetSub(int isub) { + if (isub == 0) + return new water(); + if (isub == 1) + return new nitrogen(); + else if (isub == 2) + return new methane; + else if (isub == 3) + return new hydrogen; + else if (isub == 4) + return new oxygen; +// else if (isub == 5) +// return new HFC134a; + else + return 0; + } + +} diff --git a/ext/tpx/utils.h b/ext/tpx/utils.h new file mode 100755 index 000000000..31eb42df2 --- /dev/null +++ b/ext/tpx/utils.h @@ -0,0 +1,8 @@ +#ifndef TPX_UTILS_H +#define TPX_UTILS_H + +namespace tpx { + Substance * GetSub(int isub); +} + +#endif diff --git a/include/Cantera.h b/include/Cantera.h new file mode 100755 index 000000000..7b46d75b8 --- /dev/null +++ b/include/Cantera.h @@ -0,0 +1,25 @@ + +#ifndef CANTERA_H_INCL +#define CANTERA_H_INCL + +namespace std{} +using namespace std; + +// definitions +#include "kernel/ct_defs.h" + +// the Application class and associated functions +#include "kernel/global.h" + +// the CanteraError exception class +#include "kernel/ctexceptions.h" + +using namespace Cantera; + +#endif + + + + + + diff --git a/include/IdealGasMix.h b/include/IdealGasMix.h new file mode 100644 index 000000000..d0b81fbcf --- /dev/null +++ b/include/IdealGasMix.h @@ -0,0 +1,55 @@ +#ifndef CXX_IDEALGASMIX +#define CXX_IDEALGASMIX + +#include + +#include "kernel/IdealGasPhase.h" +#include "kernel/GasKinetics.h" +#include "kernel/importCTML.h" + +namespace Cantera { + + class IdealGasMix : + public IdealGasPhase, public GasKinetics + { + public: + IdealGasMix(string infile, string id="") : m_ok(false), m_r(0) { + string path = findInputFile(infile); + ifstream fin(path.c_str()); + if (!fin) { + throw CanteraError("IdealGasMix","could not open " + +path+" for reading."); + } + + m_r = new XML_Node("-"); + m_r->build(fin); + m_ok = buildSolutionFromXML(*m_r, id, "phase", this, this); + if (!m_ok) throw CanteraError("IdealGasMix", + "buildSolutionFromXML returned false"); + } + + + IdealGasMix(XML_Node& root, string id) : m_ok(false), m_r(0) { + m_ok = buildSolutionFromXML(root, id, "phase", this, this); + } + + virtual ~IdealGasMix() {} + + bool operator!() { return !m_ok;} + bool ready() { return m_ok; } + friend ostream& operator<<(ostream& s, IdealGasMix& mix) { + string r = report(mix, true); + s << r; + return s; + } + + protected: + bool m_ok; + XML_Node* m_r; + + private: + }; +} + + +#endif diff --git a/include/README b/include/README new file mode 100644 index 000000000..2e1f83170 --- /dev/null +++ b/include/README @@ -0,0 +1,5 @@ + +The header files in this directory are for use in C++ application +programs that use Cantera. The header files for the Cantera kernel are +in subdirectory kernel, but it should rarely be necessary to include +these directly in user programs. diff --git a/include/config.h b/include/config.h new file mode 100755 index 000000000..b891e9df9 --- /dev/null +++ b/include/config.h @@ -0,0 +1,59 @@ +/* ../config.h. Generated automatically by configure. */ +// +// Run the 'configure' script to generate 'config.h' from this input file. +// +#ifndef CT_CONFIG_H +#define CT_CONFIG_H + + +//------------------------ Fortran settings -------------------// + + +// define types doublereal, integer, and ftnlen to match the +// corresponding Fortran data types on your system. The defaults +// are OK for most systems + +typedef double doublereal; // Fortran double precision +typedef int integer; // Fortran integer +typedef int ftnlen; // Fortran hidden string length type + + +// Fortran compilers pass character strings in argument lists by +// adding a hidden argement with the length of the string. Some +// compilers add the hidden length argument immediately after the +// CHARACTER variable being passed, while others put all of the hidden +// length arguments at the end of the argument list. Define this if +// the lengths are at the end of the argument list. This is usually the +// case for most unix Fortran compilers, but is (by default) false for +// Visual Fortran under Windows. +#define STRING_LEN_AT_END + + +// Define this if Fortran adds a trailing underscore to names in object files. +// For linux and most unix systems, this is the case. +#define FTN_TRAILING_UNDERSCORE + + +//-------- LAPACK / BLAS --------- + +// Define if you are using LAPACK and BLAS from the Intel Math Kernel +// Library +/* #undef HAVE_INTEL_MKL */ + +#define LAPACK_FTN_STRING_LEN_AT_END 1 +#define LAPACK_NAMES_LOWERCASE 1 +#define LAPACK_FTN_TRAILING_UNDERSCORE 1 + + +//--------- Cantera -------------- + + +//--------- CKReader ------------- + + + +//--------- CtLib ---------------- + + + +#endif diff --git a/include/core.h b/include/core.h new file mode 100644 index 000000000..d18d4d64e --- /dev/null +++ b/include/core.h @@ -0,0 +1,9 @@ +#ifndef CT_CORE_H +#define CT_CORE_H + +#include "kernel/ThermoPhase.h" +#include "kernel/Kinetics.h" +#include "kernel/ctml.h" + +#endif + diff --git a/include/ctml.h b/include/ctml.h new file mode 100755 index 000000000..75d861098 --- /dev/null +++ b/include/ctml.h @@ -0,0 +1,92 @@ +/** + * @file ctml.h + * + * CTML ("Cantera Markup Language") is the variant of XML that Cantera uses + * to store data. These functions read and write it. + * + * see also: importCTML, ck2ctml. + */ + + +/* $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2002 California Institute of Technology + + + +#ifndef CT_CTML_H +#define CT_CTML_H + +#include "ct_defs.h" +#include "xml.h" +using namespace Cantera; + +namespace ctml { + + bool isBuiltin(string nm); + + void addBool(XML_Node& node, + string title, + bool val); + + void addInteger(XML_Node& node, + string title, + int val, + string units="", + string type=""); + + void addFloat(XML_Node& node, + string title, + doublereal val, + string units="", + string type="", + doublereal minval = Undef, + doublereal maxval = Undef); + + void addIntegerArray(XML_Node& node, + string title, + int n, + const int* vals, + string units="", + string type="", + doublereal minval=Undef, + doublereal maxval=Undef); + + void addFloatArray(XML_Node& node, + string title, + int n, + const double* vals, + string units="", + string type="", + doublereal minval = Undef, + doublereal maxval = Undef); + + void addString(XML_Node& node, + string title, + string val, + string type=""); + + void getFloatArray(XML_Node& node, + vector_fp& v, bool convert=true); + + void getStringArray(XML_Node& node, vector& v); + void getMap(XML_Node& node, map& m); + void getPairs(XML_Node& node, vector& key, vector& val); + + void getIntegers(XML_Node& node, map& v); + void getFloats(XML_Node& node, map& v, bool convert=true); + doublereal getFloat(XML_Node& parent, string name, string type=""); + void getStrings(XML_Node& node, map& v); + void getFunction(XML_Node& node, string& type, doublereal& xmin, + doublereal& xmax, vector_fp& coeffs); + XML_Node* getByTitle(XML_Node& node, string title); + void getString(XML_Node& node, string title, string& val, + string& type); + + string getString(XML_Node& parent, string name); +} + +#endif diff --git a/include/equilibrium.h b/include/equilibrium.h new file mode 100755 index 000000000..efe63d9dd --- /dev/null +++ b/include/equilibrium.h @@ -0,0 +1,9 @@ +/* + * header file providing support for chemical equilibrium. + */ +#ifndef CT_EQUIL_INCL +#define CT_EQUIL_INCL +#include "kernel/ChemEquil.h" +#endif + + diff --git a/include/fortran/ctfdevmod.f b/include/fortran/ctfdevmod.f new file mode 100755 index 000000000..e56d0dec3 --- /dev/null +++ b/include/fortran/ctfdevmod.f @@ -0,0 +1,241 @@ +! ------------------------------------------------------------------------ +! +! Copyright 2002 California Institute of Technology +! +! Version 1.2.0.1 +! Mon Jan 7 07:13:18 2002 +! This file generated automatically. +! Fortran 90 module implementing Cantera class FlowDev +! ------------------------------------------------------------------------ + module ctfdev + use cttypes + + use ctreactor + interface + + integer function cfdev_newmfc() +!DEC$ attributes c, reference :: cfdev_newmfc +!DEC$ attributes alias:'_cfdev_newmfc_' :: cfdev_newmfc +!DEC$ attributes dllimport :: cfdev_newmfc + end function + + integer function cfdev_newpc() +!DEC$ attributes c, reference :: cfdev_newpc +!DEC$ attributes alias:'_cfdev_newpc_' :: cfdev_newpc +!DEC$ attributes dllimport :: cfdev_newpc + end function + + subroutine cfdev_delete(i) +!DEC$ attributes c, reference :: cfdev_delete +!DEC$ attributes alias:'_cfdev_delete_' :: cfdev_delete +!DEC$ attributes dllimport :: cfdev_delete + integer, intent(in) :: i + end subroutine + + subroutine cfdev_setspnt(flowDev, setpnt) +!DEC$ attributes c, reference :: cfdev_setspnt +!DEC$ attributes alias: '_cfdev_setspnt_' :: cfdev_setspnt +!DEC$ attributes dllimport :: cfdev_setspnt + type(Flowdev), intent(inout) :: flowDev + double precision, intent(in) :: setpnt + end subroutine + + + subroutine cfdev_install(flowDev_hndl, up_hndl, down_hndl) +!DEC$ attributes c, reference :: cfdev_install +!DEC$ attributes alias: '_cfdev_install_' :: cfdev_install +!DEC$ attributes dllimport :: cfdev_install + integer, intent(inout) :: flowDev_hndl + integer, intent(inout) :: up_hndl + integer, intent(inout) :: down_hndl + end subroutine + type(Reactor) function cfdev_upstream(flowDev) +!DEC$ attributes c, reference :: cfdev_upstream +!DEC$ attributes alias: '_cfdev_upstream_' :: cfdev_upstream +!DEC$ attributes dllimport :: cfdev_upstream + type(Flowdev), intent(inout) :: flowDev + end function + + type(Reactor) function cfdev_downstream(flowDev) +!DEC$ attributes c, reference :: cfdev_downstream +!DEC$ attributes alias: '_cfdev_downstream_' :: cfdev_downstream +!DEC$ attributes dllimport :: cfdev_downstream + type(Flowdev), intent(inout) :: flowDev + end function + + double precision function cfdev_mfrate(flowDev) +!DEC$ attributes c, reference :: cfdev_mfrate +!DEC$ attributes alias: '_cfdev_mfrate_' :: cfdev_mfrate +!DEC$ attributes dllimport :: cfdev_mfrate + type(Flowdev), intent(inout) :: flowDev + end function + + subroutine cfdev_update(flowDev) +!DEC$ attributes c, reference :: cfdev_update +!DEC$ attributes alias: '_cfdev_update_' :: cfdev_update +!DEC$ attributes dllimport :: cfdev_update + type(Flowdev), intent(inout) :: flowDev + end subroutine + + subroutine cfdev_reset(flowDev) +!DEC$ attributes c, reference :: cfdev_reset +!DEC$ attributes alias: '_cfdev_reset_' :: cfdev_reset +!DEC$ attributes dllimport :: cfdev_reset + type(Flowdev), intent(inout) :: flowDev + end subroutine + + integer function cfdev_ready(flowDev) +!DEC$ attributes c, reference :: cfdev_ready +!DEC$ attributes alias: '_cfdev_ready_' :: cfdev_ready +!DEC$ attributes dllimport :: cfdev_ready + type(Flowdev), intent(inout) :: flowDev + end function + + + integer function cfdev_setGains(flowDev_hndl, n, gains) +!DEC$ attributes c, reference :: cfdev_setGains +!DEC$ attributes alias: '_cfdev_setgains_' :: cfdev_setGains +!DEC$ attributes dllimport :: cfdev_setGains + integer, intent(inout) :: flowDev_hndl + integer, intent(in) :: n + double precision, intent(in) :: gains(n) + end function + + integer function cfdev_getGains(flowDev_hndl, n, gains) +!DEC$ attributes c, reference :: cfdev_getGains +!DEC$ attributes alias: '_cfdev_getgains_' :: cfdev_getGains +!DEC$ attributes dllimport :: cfdev_getGains + integer, intent(inout) :: flowDev_hndl + integer, intent(in) :: n + double precision, intent(out) :: gains(n) + end function + double precision function cfdev_maxError(flowDev) +!DEC$ attributes c, reference :: cfdev_maxError +!DEC$ attributes alias: '_cfdev_maxerror_' :: cfdev_maxError +!DEC$ attributes dllimport :: cfdev_maxError + type(Flowdev), intent(inout) :: flowDev + end function + + end interface + integer, parameter :: MassFlowController_Type = constant: requested text line not found.D + integer, parameter :: PressureController_Type = constant: requested text line not found.D + contains + + type(Flowdev) function MassFlowController() + type(Flowdev) mfc + mfc%hndl = cfdev_newmfc() + mfc%type = MassFlowController_Type; + MassFlowController = mfc + return + end function + + type(Flowdev) function PressureController() + type(Flowdev) pc + pc%hndl = cfdev_newpc() + pc%type = PressureController_Type; + PressureController = pc + return + end function + + subroutine fdev_copy(dest, src) + type (Flowdev), intent(out) :: dest + type (Flowdev), intent(in) :: src + call reac_copy(dest%upstream, src%upstream) + call reac_copy(dest%downstream, src%downstream) + dest%hndl = src%hndl + dest%type = src%type + end subroutine +! +! setSetpoint +! + subroutine fdev_setspnt(self, flowDev, setpnt) + type(FlowDev), intent(inout) :: self + type(Flowdev), intent(inout) :: flowDev + double precision, intent(in) :: setpnt + call cfdev_setspnt(self%hndl, flowDev, setpnt) + return + end subroutine + + subroutine fdev_install(object, upstream, downstream) + type(Flowdev), intent(inout) :: object + type(Reactor), intent(inout) :: upstream + type(Reactor), intent(inout) :: downstream + call cfdev_install(object%hndl, upstream%hndl, + & downstream%hndl) + call reac_copy(object%upstream, upstream) + call reac_copy(object%downstream, downstream) + return + end subroutine + + type(Reactor) function fdev_upstream(object) + type(Flowdev), intent(in) :: object + call reac_copy(fdev_upstream, object%upstream) + end function + + type(Reactor) function fdev_downstream(object) + type(Flowdev), intent(in) :: object + call reac_copy(fdev_downstream, object%downstream) + end function +! +! massFlowRate +! + double precision function fdev_mfrate(self, flowDev) + type(FlowDev), intent(inout) :: self + type(Flowdev), intent(inout) :: flowDev + fdev_mfrate=cfdev_mfrate(self%hndl, flowDev) + return + end function +! +! update +! + subroutine fdev_update(self, flowDev) + type(FlowDev), intent(inout) :: self + type(Flowdev), intent(inout) :: flowDev + call cfdev_update(self%hndl, flowDev) + return + end subroutine +! +! reset +! + subroutine fdev_reset(self, flowDev) + type(FlowDev), intent(inout) :: self + type(Flowdev), intent(inout) :: flowDev + call cfdev_reset(self%hndl, flowDev) + return + end subroutine + + logical function fdev_ready(object) + type(Flowdev), intent(inout) :: object + if (cfdev_ready(object%hndl) .gt. 0) then + fdev_ready = .true. + else + fdev_ready = .false. + end if + return + end function + + subroutine fdev_setGains(flowDev, gains) + type(Flowdev), intent(inout) :: flowDev + double precision, intent(in) :: gains(4) + iok = cfdev_setGains(flowDev%hndl, 4, gains) + if (iok .eq. 0) write(*,*) 'error setting gains!' + return + end subroutine + + subroutine fdev_getGains(flowDev, gains) + type(Flowdev), intent(inout) :: flowDev + double precision, intent(out) :: gains(4) + iok = cfdev_getGains(flowDev%hndl, 4, gains) + if (iok .eq. 0) write(*,*) 'error getting gains!' + return + end subroutine +! +! maxError +! + double precision function fdev_maxError(self, flowDev) + type(FlowDev), intent(inout) :: self + type(Flowdev), intent(inout) :: flowDev + fdev_maxError=cfdev_maxError(self%hndl, flowDev) + return + end function + end module diff --git a/include/fortran/ctkineticsmod.f b/include/fortran/ctkineticsmod.f new file mode 100755 index 000000000..f08d8e1f2 --- /dev/null +++ b/include/fortran/ctkineticsmod.f @@ -0,0 +1,205 @@ + module ctkinetics + + use ctmixture + + + use ctmixture + interface + subroutine ckin_getrxnstr(mix_hndl, i, rxnString) +!DEC$ attributes c, reference :: ckin_getrxnstr +!DEC$ attributes alias: '_ckin_getrxnstr_' :: ckin_getrxnstr +!DEC$ attributes dllimport :: ckin_getrxnstr + integer, intent(in) :: mix_hndl + integer, intent(in) :: i + character*(*), intent(out) :: rxnString + end subroutine + + double precision function ckin_rstoich(mix_hndl, k, i) +!DEC$ attributes c, reference :: ckin_rstoich +!DEC$ attributes alias: '_ckin_rstoich_' :: ckin_rstoich +!DEC$ attributes dllimport :: ckin_rstoich + integer, intent(in) :: mix_hndl + integer, intent(in) :: k + integer, intent(in) :: i + end function + + double precision function ckin_pstoich(mix_hndl, k, i) +!DEC$ attributes c, reference :: ckin_pstoich +!DEC$ attributes alias: '_ckin_pstoich_' :: ckin_pstoich +!DEC$ attributes dllimport :: ckin_pstoich + integer, intent(in) :: mix_hndl + integer, intent(in) :: k + integer, intent(in) :: i + end function + + double precision function ckin_nstoich(mix_hndl, k, i) +!DEC$ attributes c, reference :: ckin_nstoich +!DEC$ attributes alias: '_ckin_nstoich_' :: ckin_nstoich +!DEC$ attributes dllimport :: ckin_nstoich + integer, intent(in) :: mix_hndl + integer, intent(in) :: k + integer, intent(in) :: i + end function + + subroutine ckin_get_fwdrop(mix_hndl, fwdrop) +!DEC$ attributes c, reference :: ckin_get_fwdrop +!DEC$ attributes alias: '_ckin_get_fwdrop_' :: ckin_get_fwdrop +!DEC$ attributes dllimport :: ckin_get_fwdrop + integer, intent(in) :: mix_hndl + double precision, intent(out) :: fwdrop(*) + end subroutine + + subroutine ckin_get_revrop(mix_hndl, revrop) +!DEC$ attributes c, reference :: ckin_get_revrop +!DEC$ attributes alias: '_ckin_get_revrop_' :: ckin_get_revrop +!DEC$ attributes dllimport :: ckin_get_revrop + integer, intent(in) :: mix_hndl + double precision, intent(out) :: revrop(*) + end subroutine + + subroutine ckin_get_netrop(mix_hndl, netrop) +!DEC$ attributes c, reference :: ckin_get_netrop +!DEC$ attributes alias: '_ckin_get_netrop_' :: ckin_get_netrop +!DEC$ attributes dllimport :: ckin_get_netrop + integer, intent(in) :: mix_hndl + double precision, intent(out) :: netrop(*) + end subroutine + + subroutine ckin_get_kc(mix_hndl, kc) +!DEC$ attributes c, reference :: ckin_get_kc +!DEC$ attributes alias: '_ckin_get_kc_' :: ckin_get_kc +!DEC$ attributes dllimport :: ckin_get_kc + integer, intent(in) :: mix_hndl + double precision, intent(out) :: kc(*) + end subroutine + + subroutine ckin_get_cdot(mix_hndl, cdot) +!DEC$ attributes c, reference :: ckin_get_cdot +!DEC$ attributes alias: '_ckin_get_cdot_' :: ckin_get_cdot +!DEC$ attributes dllimport :: ckin_get_cdot + integer, intent(in) :: mix_hndl + double precision, intent(out) :: cdot(*) + end subroutine + + subroutine ckin_get_ddot(mix_hndl, ddot) +!DEC$ attributes c, reference :: ckin_get_ddot +!DEC$ attributes alias: '_ckin_get_ddot_' :: ckin_get_ddot +!DEC$ attributes dllimport :: ckin_get_ddot + integer, intent(in) :: mix_hndl + double precision, intent(out) :: ddot(*) + end subroutine + + subroutine ckin_get_wdot(mix_hndl, wdot) +!DEC$ attributes c, reference :: ckin_get_wdot +!DEC$ attributes alias: '_ckin_get_wdot_' :: ckin_get_wdot +!DEC$ attributes dllimport :: ckin_get_wdot + integer, intent(in) :: mix_hndl + double precision, intent(out) :: wdot(*) + end subroutine + + end interface + contains +! +! getReactionString +! + subroutine kin_getrxnstr(mix, i, rxnString) + type(mixture_t), intent(in) :: mix + integer, intent(in) :: i + character*(*), intent(out) :: rxnString + call ckin_getrxnstr(mix%hndl, i, rxnString) + return + end subroutine +! +! reactantStoichCoeff +! + double precision function kin_rstoich(mix, k, i) + type(mixture_t), intent(in) :: mix + integer, intent(in) :: k + integer, intent(in) :: i + kin_rstoich=ckin_rstoich(mix%hndl, k, i) + return + end function +! +! productStoichCoeff +! + double precision function kin_pstoich(mix, k, i) + type(mixture_t), intent(in) :: mix + integer, intent(in) :: k + integer, intent(in) :: i + kin_pstoich=ckin_pstoich(mix%hndl, k, i) + return + end function +! +! netStoichCoeff +! + double precision function kin_nstoich(mix, k, i) + type(mixture_t), intent(in) :: mix + integer, intent(in) :: k + integer, intent(in) :: i + kin_nstoich=ckin_nstoich(mix%hndl, k, i) + return + end function +! +! getFwdRatesOfProgress +! + subroutine kin_get_fwdrop(mix, fwdrop) + type(mixture_t), intent(in) :: mix + double precision, intent(out) :: fwdrop(mix%nrxn) + call ckin_get_fwdrop(mix%hndl, fwdrop) + return + end subroutine +! +! getRevRatesOfProgress +! + subroutine kin_get_revrop(mix, revrop) + type(mixture_t), intent(in) :: mix + double precision, intent(out) :: revrop(mix%nrxn) + call ckin_get_revrop(mix%hndl, revrop) + return + end subroutine +! +! getNetRatesOfProgress +! + subroutine kin_get_netrop(mix, netrop) + type(mixture_t), intent(in) :: mix + double precision, intent(out) :: netrop(mix%nrxn) + call ckin_get_netrop(mix%hndl, netrop) + return + end subroutine +! +! getEquilibriumConstants +! + subroutine kin_get_kc(mix, kc) + type(mixture_t), intent(in) :: mix + double precision, intent(out) :: kc(mix%nsp) + call ckin_get_kc(mix%hndl, kc) + return + end subroutine +! +! getCreationRates +! + subroutine kin_get_cdot(mix, cdot) + type(mixture_t), intent(in) :: mix + double precision, intent(out) :: cdot(mix%nsp) + call ckin_get_cdot(mix%hndl, cdot) + return + end subroutine +! +! getDestructionRates +! + subroutine kin_get_ddot(mix, ddot) + type(mixture_t), intent(in) :: mix + double precision, intent(out) :: ddot(mix%nsp) + call ckin_get_ddot(mix%hndl, ddot) + return + end subroutine +! +! getNetProductionRates +! + subroutine kin_get_wdot(mix, wdot) + type(mixture_t), intent(in) :: mix + double precision, intent(out) :: wdot(mix%nsp) + call ckin_get_wdot(mix%hndl, wdot) + return + end subroutine + end module diff --git a/include/fortran/ctmixturemod.f b/include/fortran/ctmixturemod.f new file mode 100755 index 000000000..c0a1301b8 --- /dev/null +++ b/include/fortran/ctmixturemod.f @@ -0,0 +1,1874 @@ +! ------------------------------------------------------------------------ +! +! Copyright 2002 California Institute of Technology +! +! Version 1.2.0.1 +! Mon Jan 7 07:13:18 2002 +! This file generated automatically. +! Fortran 90 module implementing Cantera class Mixture +! ------------------------------------------------------------------------ + module ctmixture + use cttypes + interface + + integer function cmix_newmixture() +!DEC$ attributes alias:'_cmix_newmixture_' :: cmix_newmixture +!DEC$ attributes c, reference :: cmix_newmixture + end function + + integer function cmix_newidealgas() +!DEC$ attributes alias:'_cmix_newidealgas_' :: cmix_newidealgas +!DEC$ attributes c, reference :: cmix_newidealgas + end function cmix_newidealgas + + integer function cmix_import(i, inputfile, thermofile, ivalidate) +!DEC$ attributes c, reference, alias:'_cmix_import_' :: cmix_import + character*(*), intent(in) :: inputfile, thermofile + integer, intent(in) :: ivalidate + end function cmix_import + + integer function cmix_newsub(i) +!DEC$ attributes alias:'_cmix_newsub_' :: cmix_newsub +!DEC$ attributes c, reference :: cmix_newsub + integer, intent(in) :: i + end function + type(Mixture) function cmix_CKGas(inputFile, thermoFile, iValidate) +!DEC$ attributes c, reference :: cmix_CKGas +!DEC$ attributes alias: '_cmix_ckgas_' :: cmix_CKGas +!DEC$ attributes dllimport :: cmix_CKGas + character*(*), intent(in) :: inputFile + character*(*), intent(in) :: thermoFile + integer, intent(in) :: iValidate + end function + + type(Mixture) function cmix_GRIMech30() +!DEC$ attributes c, reference :: cmix_GRIMech30 +!DEC$ attributes alias: '_cmix_grimech30_' :: cmix_GRIMech30 +!DEC$ attributes dllimport :: cmix_GRIMech30 + end function + + type(Mixture) function cmix_Water() +!DEC$ attributes c, reference :: cmix_Water +!DEC$ attributes alias: '_cmix_water_' :: cmix_Water +!DEC$ attributes dllimport :: cmix_Water + end function + + type(Mixture) function cmix_Nitrogen() +!DEC$ attributes c, reference :: cmix_Nitrogen +!DEC$ attributes alias: '_cmix_nitrogen_' :: cmix_Nitrogen +!DEC$ attributes dllimport :: cmix_Nitrogen + end function + + type(Mixture) function cmix_Methane() +!DEC$ attributes c, reference :: cmix_Methane +!DEC$ attributes alias: '_cmix_methane_' :: cmix_Methane +!DEC$ attributes dllimport :: cmix_Methane + end function + + type(Mixture) function cmix_Hydrogen() +!DEC$ attributes c, reference :: cmix_Hydrogen +!DEC$ attributes alias: '_cmix_hydrogen_' :: cmix_Hydrogen +!DEC$ attributes dllimport :: cmix_Hydrogen + end function + + type(Mixture) function cmix_Oxygen() +!DEC$ attributes c, reference :: cmix_Oxygen +!DEC$ attributes alias: '_cmix_oxygen_' :: cmix_Oxygen +!DEC$ attributes dllimport :: cmix_Oxygen + end function + + subroutine cmix_delete() +!DEC$ attributes c, reference :: cmix_delete +!DEC$ attributes alias: '_cmix_delete_' :: cmix_delete +!DEC$ attributes dllimport :: cmix_delete + end subroutine + + logical function cmix_ready() +!DEC$ attributes c, reference :: cmix_ready +!DEC$ attributes alias: '_cmix_ready_' :: cmix_ready +!DEC$ attributes dllimport :: cmix_ready + end function + + subroutine cmix_saveState(state) +!DEC$ attributes c, reference :: cmix_saveState +!DEC$ attributes alias: '_cmix_savestate_' :: cmix_saveState +!DEC$ attributes dllimport :: cmix_saveState + double precision, intent(out) :: state(*) + end subroutine + + subroutine cmix_restoreState(state) +!DEC$ attributes c, reference :: cmix_restoreState +!DEC$ attributes alias: '_cmix_restorestate_' :: cmix_restoreState +!DEC$ attributes dllimport :: cmix_restoreState + double precision, intent(out) :: state(*) + end subroutine + + integer function cmix_nElements() +!DEC$ attributes c, reference :: cmix_nElements +!DEC$ attributes alias: '_cmix_nelements_' :: cmix_nElements +!DEC$ attributes dllimport :: cmix_nElements + end function + + integer function cmix_nSpecies() +!DEC$ attributes c, reference :: cmix_nSpecies +!DEC$ attributes alias: '_cmix_nspecies_' :: cmix_nSpecies +!DEC$ attributes dllimport :: cmix_nSpecies + end function + + integer function cmix_nReactions() +!DEC$ attributes c, reference :: cmix_nReactions +!DEC$ attributes alias: '_cmix_nreactions_' :: cmix_nReactions +!DEC$ attributes dllimport :: cmix_nReactions + end function + + subroutine cmix_addElement(name, atomicWt) +!DEC$ attributes c, reference :: cmix_addElement +!DEC$ attributes alias: '_cmix_addelement_' :: cmix_addElement +!DEC$ attributes dllimport :: cmix_addElement + character*(*), intent(in) :: name + double precision, intent(in) :: atomicWt + end subroutine + + + subroutine cmix_getename(i, m, ename) +!DEC$ attributes c, reference, alias:'_cmix_getename_' :: cmix_getename + integer, intent(in) :: i, m + character*(*), intent(out) :: ename + end subroutine + integer function cmix_eindex(name) +!DEC$ attributes c, reference :: cmix_eindex +!DEC$ attributes alias: '_cmix_eindex_' :: cmix_eindex +!DEC$ attributes dllimport :: cmix_eindex + character*(*), intent(in) :: name + end function + + double precision function cmix_atwt(m) +!DEC$ attributes c, reference :: cmix_atwt +!DEC$ attributes alias: '_cmix_atwt_' :: cmix_atwt +!DEC$ attributes dllimport :: cmix_atwt + integer, intent(in) :: m + end function + + double precision function cmix_nAtoms(k, m) +!DEC$ attributes c, reference :: cmix_nAtoms +!DEC$ attributes alias: '_cmix_natoms_' :: cmix_nAtoms +!DEC$ attributes dllimport :: cmix_nAtoms + integer, intent(in) :: k + integer, intent(in) :: m + end function + + double precision function cmix_charge(k) +!DEC$ attributes c, reference :: cmix_charge +!DEC$ attributes alias: '_cmix_charge_' :: cmix_charge +!DEC$ attributes dllimport :: cmix_charge + integer, intent(in) :: k + end function + + integer function cmix_speciesIndex(name) +!DEC$ attributes c, reference :: cmix_speciesIndex +!DEC$ attributes alias: '_cmix_speciesindex_' :: cmix_speciesIndex +!DEC$ attributes dllimport :: cmix_speciesIndex + character*(*), intent(in) :: name + end function + + + subroutine cmix_getspnm(i, k, sname) +!DEC$ attributes c, reference, alias:'_cmix_getspnm_' :: cmix_getspnm + integer, intent(in) :: i, k + character*(*), intent(out) :: sname + end subroutine + double precision function cmix_molwt(k) +!DEC$ attributes c, reference :: cmix_molwt +!DEC$ attributes alias: '_cmix_molwt_' :: cmix_molwt +!DEC$ attributes dllimport :: cmix_molwt + integer, intent(in) :: k + end function + + subroutine cmix_gmolwts(molWts) +!DEC$ attributes c, reference :: cmix_gmolwts +!DEC$ attributes alias: '_cmix_gmolwts_' :: cmix_gmolwts +!DEC$ attributes dllimport :: cmix_gmolwts + double precision, intent(out) :: molWts(*) + end subroutine + + subroutine cmix_setx(moleFracs) +!DEC$ attributes c, reference :: cmix_setx +!DEC$ attributes alias: '_cmix_setx_' :: cmix_setx +!DEC$ attributes dllimport :: cmix_setx + double precision, intent(in) :: moleFracs(*) + end subroutine + + subroutine cmix_sxnonorm(moleFracs) +!DEC$ attributes c, reference :: cmix_sxnonorm +!DEC$ attributes alias: '_cmix_sxnonorm_' :: cmix_sxnonorm +!DEC$ attributes dllimport :: cmix_sxnonorm + double precision, intent(in) :: moleFracs(*) + end subroutine + + subroutine cmix_sety(massFracs) +!DEC$ attributes c, reference :: cmix_sety +!DEC$ attributes alias: '_cmix_sety_' :: cmix_sety +!DEC$ attributes dllimport :: cmix_sety + double precision, intent(in) :: massFracs(*) + end subroutine + + subroutine cmix_synonorm(y) +!DEC$ attributes c, reference :: cmix_synonorm +!DEC$ attributes alias: '_cmix_synonorm_' :: cmix_synonorm +!DEC$ attributes dllimport :: cmix_synonorm + double precision, intent(in) :: y(*) + end subroutine + + subroutine cmix_sconc(conc) +!DEC$ attributes c, reference :: cmix_sconc +!DEC$ attributes alias: '_cmix_sconc_' :: cmix_sconc +!DEC$ attributes dllimport :: cmix_sconc + double precision, intent(in) :: conc(*) + end subroutine + + double precision function cmix_xbyname(name) +!DEC$ attributes c, reference :: cmix_xbyname +!DEC$ attributes alias: '_cmix_xbyname_' :: cmix_xbyname +!DEC$ attributes dllimport :: cmix_xbyname + character*(*), intent(in) :: name + end function + + double precision function cmix_ybyname(name) +!DEC$ attributes c, reference :: cmix_ybyname +!DEC$ attributes alias: '_cmix_ybyname_' :: cmix_ybyname +!DEC$ attributes dllimport :: cmix_ybyname + character*(*), intent(in) :: name + end function + + subroutine cmix_getx(moleFracs) +!DEC$ attributes c, reference :: cmix_getx +!DEC$ attributes alias: '_cmix_getx_' :: cmix_getx +!DEC$ attributes dllimport :: cmix_getx + double precision, intent(inout) :: moleFracs(*) + end subroutine + + subroutine cmix_gety(massFracs) +!DEC$ attributes c, reference :: cmix_gety +!DEC$ attributes alias: '_cmix_gety_' :: cmix_gety +!DEC$ attributes dllimport :: cmix_gety + double precision, intent(inout) :: massFracs(*) + end subroutine + + subroutine cmix_getconc(concentrations) +!DEC$ attributes c, reference :: cmix_getconc +!DEC$ attributes alias: '_cmix_getconc_' :: cmix_getconc +!DEC$ attributes dllimport :: cmix_getconc + double precision, intent(inout) :: concentrations(*) + end subroutine + + double precision function cmix_mean_X(Q) +!DEC$ attributes c, reference :: cmix_mean_X +!DEC$ attributes alias: '_cmix_mean_x_' :: cmix_mean_X +!DEC$ attributes dllimport :: cmix_mean_X + double precision, intent(in) :: Q(*) + end function + + double precision function cmix_mean_Y(Q) +!DEC$ attributes c, reference :: cmix_mean_Y +!DEC$ attributes alias: '_cmix_mean_y_' :: cmix_mean_Y +!DEC$ attributes dllimport :: cmix_mean_Y + double precision, intent(in) :: Q(*) + end function + + double precision function cmix_meanmw() +!DEC$ attributes c, reference :: cmix_meanmw +!DEC$ attributes alias: '_cmix_meanmw_' :: cmix_meanmw +!DEC$ attributes dllimport :: cmix_meanmw + end function + + double precision function cmix_sum_xlogQ(Q) +!DEC$ attributes c, reference :: cmix_sum_xlogQ +!DEC$ attributes alias: '_cmix_sum_xlogq_' :: cmix_sum_xlogQ +!DEC$ attributes dllimport :: cmix_sum_xlogQ + double precision, intent(out) :: Q(*) + end function + + subroutine cmix_setTPXarray(t, p, moleFracs) +!DEC$ attributes c, reference :: cmix_setTPXarray +!DEC$ attributes alias: '_cmix_settpxarray_' :: cmix_setTPXarray +!DEC$ attributes dllimport :: cmix_setTPXarray + double precision, intent(in) :: t + double precision, intent(in) :: p + double precision, intent(in) :: moleFracs(*) + end subroutine + + subroutine cmix_setTPXstr(t, p, moleFracs) +!DEC$ attributes c, reference :: cmix_setTPXstr +!DEC$ attributes alias: '_cmix_settpxstr_' :: cmix_setTPXstr +!DEC$ attributes dllimport :: cmix_setTPXstr + double precision, intent(in) :: t + double precision, intent(in) :: p + character*(*), intent(in) :: moleFracs + end subroutine + + subroutine cmix_setTPYarray(t, p, massFracs) +!DEC$ attributes c, reference :: cmix_setTPYarray +!DEC$ attributes alias: '_cmix_settpyarray_' :: cmix_setTPYarray +!DEC$ attributes dllimport :: cmix_setTPYarray + double precision, intent(in) :: t + double precision, intent(in) :: p + double precision, intent(in) :: massFracs(*) + end subroutine + + subroutine cmix_setTPYstr(t, p, massFracs) +!DEC$ attributes c, reference :: cmix_setTPYstr +!DEC$ attributes alias: '_cmix_settpystr_' :: cmix_setTPYstr +!DEC$ attributes dllimport :: cmix_setTPYstr + double precision, intent(in) :: t + double precision, intent(in) :: p + character*(*), intent(in) :: massFracs + end subroutine + + subroutine cmix_setState_TRX(t, density, moleFracs) +!DEC$ attributes c, reference :: cmix_setState_TRX +!DEC$ attributes alias: '_cmix_setstate_trx_' :: cmix_setState_TRX +!DEC$ attributes dllimport :: cmix_setState_TRX + double precision, intent(in) :: t + double precision, intent(in) :: density + double precision, intent(in) :: moleFracs(*) + end subroutine + + subroutine cmix_setState_TRY(t, density, massFracs) +!DEC$ attributes c, reference :: cmix_setState_TRY +!DEC$ attributes alias: '_cmix_setstate_try_' :: cmix_setState_TRY +!DEC$ attributes dllimport :: cmix_setState_TRY + double precision, intent(in) :: t + double precision, intent(in) :: density + double precision, intent(in) :: massFracs(*) + end subroutine + + subroutine cmix_settemp(temp) +!DEC$ attributes c, reference :: cmix_settemp +!DEC$ attributes alias: '_cmix_settemp_' :: cmix_settemp +!DEC$ attributes dllimport :: cmix_settemp + double precision, intent(in) :: temp + end subroutine + + subroutine cmix_setDensity(density) +!DEC$ attributes c, reference :: cmix_setDensity +!DEC$ attributes alias: '_cmix_setdensity_' :: cmix_setDensity +!DEC$ attributes dllimport :: cmix_setDensity + double precision, intent(in) :: density + end subroutine + + subroutine cmix_setState_TP(t, p) +!DEC$ attributes c, reference :: cmix_setState_TP +!DEC$ attributes alias: '_cmix_setstate_tp_' :: cmix_setState_TP +!DEC$ attributes dllimport :: cmix_setState_TP + double precision, intent(in) :: t + double precision, intent(in) :: p + end subroutine + + subroutine cmix_setState_PX(p, x) +!DEC$ attributes c, reference :: cmix_setState_PX +!DEC$ attributes alias: '_cmix_setstate_px_' :: cmix_setState_PX +!DEC$ attributes dllimport :: cmix_setState_PX + double precision, intent(in) :: p + double precision, intent(in) :: x(*) + end subroutine + + subroutine cmix_setState_PY(p, massFracs) +!DEC$ attributes c, reference :: cmix_setState_PY +!DEC$ attributes alias: '_cmix_setstate_py_' :: cmix_setState_PY +!DEC$ attributes dllimport :: cmix_setState_PY + double precision, intent(in) :: p + double precision, intent(in) :: massFracs(*) + end subroutine + + subroutine cmix_setPressure(p) +!DEC$ attributes c, reference :: cmix_setPressure +!DEC$ attributes alias: '_cmix_setpressure_' :: cmix_setPressure +!DEC$ attributes dllimport :: cmix_setPressure + double precision, intent(in) :: p + end subroutine + + subroutine cmix_setState_TR(t, rho) +!DEC$ attributes c, reference :: cmix_setState_TR +!DEC$ attributes alias: '_cmix_setstate_tr_' :: cmix_setState_TR +!DEC$ attributes dllimport :: cmix_setState_TR + double precision, intent(in) :: t + double precision, intent(in) :: rho + end subroutine + + subroutine cmix_setState_TX(t, moleFracs) +!DEC$ attributes c, reference :: cmix_setState_TX +!DEC$ attributes alias: '_cmix_setstate_tx_' :: cmix_setState_TX +!DEC$ attributes dllimport :: cmix_setState_TX + double precision, intent(in) :: t + double precision, intent(inout) :: moleFracs(*) + end subroutine + + subroutine cmix_setState_TY(t, massFracs) +!DEC$ attributes c, reference :: cmix_setState_TY +!DEC$ attributes alias: '_cmix_setstate_ty_' :: cmix_setState_TY +!DEC$ attributes dllimport :: cmix_setState_TY + double precision, intent(in) :: t + double precision, intent(in) :: massFracs(*) + end subroutine + + subroutine cmix_setState_RX(density, moleFracs) +!DEC$ attributes c, reference :: cmix_setState_RX +!DEC$ attributes alias: '_cmix_setstate_rx_' :: cmix_setState_RX +!DEC$ attributes dllimport :: cmix_setState_RX + double precision, intent(in) :: density + double precision, intent(in) :: moleFracs(*) + end subroutine + + subroutine cmix_setState_RY(density, y) +!DEC$ attributes c, reference :: cmix_setState_RY +!DEC$ attributes alias: '_cmix_setstate_ry_' :: cmix_setState_RY +!DEC$ attributes dllimport :: cmix_setState_RY + double precision, intent(in) :: density + double precision, intent(in) :: y(*) + end subroutine + + subroutine cmix_setState_HP(t, p) +!DEC$ attributes c, reference :: cmix_setState_HP +!DEC$ attributes alias: '_cmix_setstate_hp_' :: cmix_setState_HP +!DEC$ attributes dllimport :: cmix_setState_HP + double precision, intent(in) :: t + double precision, intent(in) :: p + end subroutine + + subroutine cmix_setState_UV(t, p) +!DEC$ attributes c, reference :: cmix_setState_UV +!DEC$ attributes alias: '_cmix_setstate_uv_' :: cmix_setState_UV +!DEC$ attributes dllimport :: cmix_setState_UV + double precision, intent(in) :: t + double precision, intent(in) :: p + end subroutine + + subroutine cmix_setState_SP(t, p) +!DEC$ attributes c, reference :: cmix_setState_SP +!DEC$ attributes alias: '_cmix_setstate_sp_' :: cmix_setState_SP +!DEC$ attributes dllimport :: cmix_setState_SP + double precision, intent(in) :: t + double precision, intent(in) :: p + end subroutine + + subroutine cmix_setState_SV(t, p) +!DEC$ attributes c, reference :: cmix_setState_SV +!DEC$ attributes alias: '_cmix_setstate_sv_' :: cmix_setState_SV +!DEC$ attributes dllimport :: cmix_setState_SV + double precision, intent(in) :: t + double precision, intent(in) :: p + end subroutine + + subroutine cmix_gh_rt(h_RT) +!DEC$ attributes c, reference :: cmix_gh_rt +!DEC$ attributes alias: '_cmix_gh_rt_' :: cmix_gh_rt +!DEC$ attributes dllimport :: cmix_gh_rt + double precision, intent(out) :: h_RT(*) + end subroutine + + subroutine cmix_ggibbs_rt(g_RT) +!DEC$ attributes c, reference :: cmix_ggibbs_rt +!DEC$ attributes alias: '_cmix_ggibbs_rt_' :: cmix_ggibbs_rt +!DEC$ attributes dllimport :: cmix_ggibbs_rt + double precision, intent(out) :: g_RT(*) + end subroutine + + subroutine cmix_gcp_r(cp_R) +!DEC$ attributes c, reference :: cmix_gcp_r +!DEC$ attributes alias: '_cmix_gcp_r_' :: cmix_gcp_r +!DEC$ attributes dllimport :: cmix_gcp_r + double precision, intent(out) :: cp_R(*) + end subroutine + + subroutine cmix_gs_r(s_R) +!DEC$ attributes c, reference :: cmix_gs_r +!DEC$ attributes alias: '_cmix_gs_r_' :: cmix_gs_r +!DEC$ attributes dllimport :: cmix_gs_r + double precision, intent(out) :: s_R(*) + end subroutine + + double precision function cmix_minTemp() +!DEC$ attributes c, reference :: cmix_minTemp +!DEC$ attributes alias: '_cmix_mintemp_' :: cmix_minTemp +!DEC$ attributes dllimport :: cmix_minTemp + end function + + double precision function cmix_maxTemp() +!DEC$ attributes c, reference :: cmix_maxTemp +!DEC$ attributes alias: '_cmix_maxtemp_' :: cmix_maxTemp +!DEC$ attributes dllimport :: cmix_maxTemp + end function + + double precision function cmix_refp() +!DEC$ attributes c, reference :: cmix_refp +!DEC$ attributes alias: '_cmix_refp_' :: cmix_refp +!DEC$ attributes dllimport :: cmix_refp + end function + + double precision function cmix_temperature() +!DEC$ attributes c, reference :: cmix_temperature +!DEC$ attributes alias: '_cmix_temperature_' :: cmix_temperature +!DEC$ attributes dllimport :: cmix_temperature + end function + + double precision function cmix_density() +!DEC$ attributes c, reference :: cmix_density +!DEC$ attributes alias: '_cmix_density_' :: cmix_density +!DEC$ attributes dllimport :: cmix_density + end function + + double precision function cmix_moldens() +!DEC$ attributes c, reference :: cmix_moldens +!DEC$ attributes alias: '_cmix_moldens_' :: cmix_moldens +!DEC$ attributes dllimport :: cmix_moldens + end function + + double precision function cmix_pressure() +!DEC$ attributes c, reference :: cmix_pressure +!DEC$ attributes alias: '_cmix_pressure_' :: cmix_pressure +!DEC$ attributes dllimport :: cmix_pressure + end function + + double precision function cmix_enthalpy_mole() +!DEC$ attributes c, reference :: cmix_enthalpy_mole +!DEC$ attributes alias: '_cmix_enthalpy_mole_' :: cmix_enthalpy_mole +!DEC$ attributes dllimport :: cmix_enthalpy_mole + end function + + double precision function cmix_umole() +!DEC$ attributes c, reference :: cmix_umole +!DEC$ attributes alias: '_cmix_umole_' :: cmix_umole +!DEC$ attributes dllimport :: cmix_umole + end function + + double precision function cmix_entropy_mole() +!DEC$ attributes c, reference :: cmix_entropy_mole +!DEC$ attributes alias: '_cmix_entropy_mole_' :: cmix_entropy_mole +!DEC$ attributes dllimport :: cmix_entropy_mole + end function + + double precision function cmix_gibbs_mole() +!DEC$ attributes c, reference :: cmix_gibbs_mole +!DEC$ attributes alias: '_cmix_gibbs_mole_' :: cmix_gibbs_mole +!DEC$ attributes dllimport :: cmix_gibbs_mole + end function + + double precision function cmix_cp_mole() +!DEC$ attributes c, reference :: cmix_cp_mole +!DEC$ attributes alias: '_cmix_cp_mole_' :: cmix_cp_mole +!DEC$ attributes dllimport :: cmix_cp_mole + end function + + double precision function cmix_cv_mole() +!DEC$ attributes c, reference :: cmix_cv_mole +!DEC$ attributes alias: '_cmix_cv_mole_' :: cmix_cv_mole +!DEC$ attributes dllimport :: cmix_cv_mole + end function + + subroutine cmix_gchempot(mu) +!DEC$ attributes c, reference :: cmix_gchempot +!DEC$ attributes alias: '_cmix_gchempot_' :: cmix_gchempot +!DEC$ attributes dllimport :: cmix_gchempot + double precision, intent(out) :: mu(*) + end subroutine + + double precision function cmix_enthalpy_mass() +!DEC$ attributes c, reference :: cmix_enthalpy_mass +!DEC$ attributes alias: '_cmix_enthalpy_mass_' :: cmix_enthalpy_mass +!DEC$ attributes dllimport :: cmix_enthalpy_mass + end function + + double precision function cmix_umass() +!DEC$ attributes c, reference :: cmix_umass +!DEC$ attributes alias: '_cmix_umass_' :: cmix_umass +!DEC$ attributes dllimport :: cmix_umass + end function + + double precision function cmix_entropy_mass() +!DEC$ attributes c, reference :: cmix_entropy_mass +!DEC$ attributes alias: '_cmix_entropy_mass_' :: cmix_entropy_mass +!DEC$ attributes dllimport :: cmix_entropy_mass + end function + + double precision function cmix_gibbs_mass() +!DEC$ attributes c, reference :: cmix_gibbs_mass +!DEC$ attributes alias: '_cmix_gibbs_mass_' :: cmix_gibbs_mass +!DEC$ attributes dllimport :: cmix_gibbs_mass + end function + + double precision function cmix_cp_mass() +!DEC$ attributes c, reference :: cmix_cp_mass +!DEC$ attributes alias: '_cmix_cp_mass_' :: cmix_cp_mass +!DEC$ attributes dllimport :: cmix_cp_mass + end function + + double precision function cmix_cv_mass() +!DEC$ attributes c, reference :: cmix_cv_mass +!DEC$ attributes alias: '_cmix_cv_mass_' :: cmix_cv_mass +!DEC$ attributes dllimport :: cmix_cv_mass + end function + + subroutine cmix_setpe_k(k, pe) +!DEC$ attributes c, reference :: cmix_setpe_k +!DEC$ attributes alias: '_cmix_setpe_k_' :: cmix_setpe_k +!DEC$ attributes dllimport :: cmix_setpe_k + integer, intent(in) :: k + double precision, intent(in) :: pe + end subroutine + + double precision function cmix_pe(k) +!DEC$ attributes c, reference :: cmix_pe +!DEC$ attributes alias: '_cmix_pe_' :: cmix_pe +!DEC$ attributes dllimport :: cmix_pe + integer, intent(in) :: k + end function + + double precision function cmix_crittemp() +!DEC$ attributes c, reference :: cmix_crittemp +!DEC$ attributes alias: '_cmix_crittemp_' :: cmix_crittemp +!DEC$ attributes dllimport :: cmix_crittemp + end function + + double precision function cmix_critpres() +!DEC$ attributes c, reference :: cmix_critpres +!DEC$ attributes alias: '_cmix_critpres_' :: cmix_critpres +!DEC$ attributes dllimport :: cmix_critpres + end function + + double precision function cmix_sattemp(p) +!DEC$ attributes c, reference :: cmix_sattemp +!DEC$ attributes alias: '_cmix_sattemp_' :: cmix_sattemp +!DEC$ attributes dllimport :: cmix_sattemp + double precision, intent(in) :: p + end function + + double precision function cmix_satpres(t) +!DEC$ attributes c, reference :: cmix_satpres +!DEC$ attributes alias: '_cmix_satpres_' :: cmix_satpres +!DEC$ attributes dllimport :: cmix_satpres + double precision, intent(in) :: t + end function + + type(EOS) function cmix_get_eos() +!DEC$ attributes c, reference :: cmix_get_eos +!DEC$ attributes alias: '_cmix_get_eos_' :: cmix_get_eos +!DEC$ attributes dllimport :: cmix_get_eos + end function + + subroutine cmix_set_eos(eos) +!DEC$ attributes c, reference :: cmix_set_eos +!DEC$ attributes alias: '_cmix_set_eos_' :: cmix_set_eos +!DEC$ attributes dllimport :: cmix_set_eos + type(EOS), intent(inout) :: eos + end subroutine + + subroutine cmix_equilib(propPair) +!DEC$ attributes c, reference :: cmix_equilib +!DEC$ attributes alias: '_cmix_equilib_' :: cmix_equilib +!DEC$ attributes dllimport :: cmix_equilib + character*(*), intent(in) :: propPair + end subroutine + + subroutine cmix_set_trans(transportMgr) +!DEC$ attributes c, reference :: cmix_set_trans +!DEC$ attributes alias: '_cmix_set_trans_' :: cmix_set_trans +!DEC$ attributes dllimport :: cmix_set_trans + type(Transport), intent(inout) :: transportMgr + end subroutine + + type(Transport) function cmix_transportMgr() +!DEC$ attributes c, reference :: cmix_transportMgr +!DEC$ attributes alias: '_cmix_transportmgr_' :: cmix_transportMgr +!DEC$ attributes dllimport :: cmix_transportMgr + end function + + double precision function cmix_visc() +!DEC$ attributes c, reference :: cmix_visc +!DEC$ attributes alias: '_cmix_visc_' :: cmix_visc +!DEC$ attributes dllimport :: cmix_visc + end function + + subroutine cmix_gspvisc(visc) +!DEC$ attributes c, reference :: cmix_gspvisc +!DEC$ attributes alias: '_cmix_gspvisc_' :: cmix_gspvisc +!DEC$ attributes dllimport :: cmix_gspvisc + double precision, intent(inout) :: visc(*) + end subroutine + + + subroutine ctrans_gflux(mix_hndl, ndim, ldx, grad_X, + & grad_T, ldf, fluxes) +!DEC$ attributes c, reference :: ctrans_gflux +!DEC$ attributes alias: '_ctrans_gflux_' :: ctrans_gflux +!DEC$ attributes dllimport :: ctrans_gflux + integer, intent(in) :: mix_hndl + integer, intent(in) :: ndim + integer, intent(in) :: ldx + double precision, intent(inout) :: grad_X(ldx,*) + double precision, intent(in) :: grad_T(*) + integer, intent(in) :: ldf + double precision, intent(out) :: fluxes(ldf,*) + end subroutine + subroutine cmix_gmultidiff(ldim, multiDiff) +!DEC$ attributes c, reference :: cmix_gmultidiff +!DEC$ attributes alias: '_cmix_gmultidiff_' :: cmix_gmultidiff +!DEC$ attributes dllimport :: cmix_gmultidiff + integer, intent(in) :: ldim + double precision, intent(in) :: multiDiff(ldim, *) + end subroutine + + double precision function cmix_tcon() +!DEC$ attributes c, reference :: cmix_tcon +!DEC$ attributes alias: '_cmix_tcon_' :: cmix_tcon +!DEC$ attributes dllimport :: cmix_tcon + end function + + subroutine cmix_gtdiff(dt) +!DEC$ attributes c, reference :: cmix_gtdiff +!DEC$ attributes alias: '_cmix_gtdiff_' :: cmix_gtdiff +!DEC$ attributes dllimport :: cmix_gtdiff + double precision, intent(out) :: dt(*) + end subroutine + + subroutine cmix_getrxnstr(i, rxnString) +!DEC$ attributes c, reference :: cmix_getrxnstr +!DEC$ attributes alias: '_cmix_getrxnstr_' :: cmix_getrxnstr +!DEC$ attributes dllimport :: cmix_getrxnstr + integer, intent(in) :: i + character*(*), intent(out) :: rxnString + end subroutine + + double precision function cmix_rstoich(k, i) +!DEC$ attributes c, reference :: cmix_rstoich +!DEC$ attributes alias: '_cmix_rstoich_' :: cmix_rstoich +!DEC$ attributes dllimport :: cmix_rstoich + integer, intent(in) :: k + integer, intent(in) :: i + end function + + double precision function cmix_pstoich(k, i) +!DEC$ attributes c, reference :: cmix_pstoich +!DEC$ attributes alias: '_cmix_pstoich_' :: cmix_pstoich +!DEC$ attributes dllimport :: cmix_pstoich + integer, intent(in) :: k + integer, intent(in) :: i + end function + + double precision function cmix_nstoich(k, i) +!DEC$ attributes c, reference :: cmix_nstoich +!DEC$ attributes alias: '_cmix_nstoich_' :: cmix_nstoich +!DEC$ attributes dllimport :: cmix_nstoich + integer, intent(in) :: k + integer, intent(in) :: i + end function + + subroutine cmix_get_fwdrop(fwdrop) +!DEC$ attributes c, reference :: cmix_get_fwdrop +!DEC$ attributes alias: '_cmix_get_fwdrop_' :: cmix_get_fwdrop +!DEC$ attributes dllimport :: cmix_get_fwdrop + double precision, intent(out) :: fwdrop(*) + end subroutine + + subroutine cmix_get_revrop(revrop) +!DEC$ attributes c, reference :: cmix_get_revrop +!DEC$ attributes alias: '_cmix_get_revrop_' :: cmix_get_revrop +!DEC$ attributes dllimport :: cmix_get_revrop + double precision, intent(out) :: revrop(*) + end subroutine + + subroutine cmix_get_netrop(netrop) +!DEC$ attributes c, reference :: cmix_get_netrop +!DEC$ attributes alias: '_cmix_get_netrop_' :: cmix_get_netrop +!DEC$ attributes dllimport :: cmix_get_netrop + double precision, intent(out) :: netrop(*) + end subroutine + + subroutine cmix_get_kc(kc) +!DEC$ attributes c, reference :: cmix_get_kc +!DEC$ attributes alias: '_cmix_get_kc_' :: cmix_get_kc +!DEC$ attributes dllimport :: cmix_get_kc + double precision, intent(out) :: kc(*) + end subroutine + + subroutine cmix_get_cdot(cdot) +!DEC$ attributes c, reference :: cmix_get_cdot +!DEC$ attributes alias: '_cmix_get_cdot_' :: cmix_get_cdot +!DEC$ attributes dllimport :: cmix_get_cdot + double precision, intent(out) :: cdot(*) + end subroutine + + subroutine cmix_get_ddot(ddot) +!DEC$ attributes c, reference :: cmix_get_ddot +!DEC$ attributes alias: '_cmix_get_ddot_' :: cmix_get_ddot +!DEC$ attributes dllimport :: cmix_get_ddot + double precision, intent(out) :: ddot(*) + end subroutine + + subroutine cmix_get_wdot(wdot) +!DEC$ attributes c, reference :: cmix_get_wdot +!DEC$ attributes alias: '_cmix_get_wdot_' :: cmix_get_wdot +!DEC$ attributes dllimport :: cmix_get_wdot + double precision, intent(out) :: wdot(*) + end subroutine + + end interface + contains + + type (Mixture) function CKGas(inputfile, thermofile, & + & ivalidate) + character*(*), intent(in), optional :: inputfile + character*(*), intent(in), optional :: thermofile + integer, intent(in), optional :: ivalidate + type (Mixture) :: mix + mix%hndl = cmix_newidealgas() + if (present(inputfile)) then + if (present(thermofile)) then + if (present(ivalidate)) then + call importCK(mix, inputfile, thermofile, ivalidate) + else + call importCK(mix, inputfile, thermofile) + end if + else + call importCK(mix, inputfile) + end if + end if + CKGas = mix + end function CKGas + + type(Mixture) function GRIMech30() + type(Mixture) :: mix + mix = CKGas('gri30.inp') + GRIMech30 = mix + return + end function + + subroutine importCK(mix, inputfile, thermofile, ivalidate) + type (Mixture), intent(inout) :: mix + character*(*), intent(in) :: inputfile + character*(*), intent(in), optional :: thermofile + integer, intent(in), optional :: ivalidate + character*1 th + integer iv, iok + th = '' + iv = 0 + if (present(thermofile) .and. present(ivalidate)) then + iok = cmix_import(mix%hndl, inputfile, thermofile, ivalidate) + else if (present(thermofile)) then + iok = cmix_import(mix%hndl, inputfile, thermofile, iv) + else + iok = cmix_import(mix%hndl, inputfile, th, iv) + end if + if (iok .lt. 0) then + mix%nel = 0 + mix%nsp = 0 + mix%nrxn = 0 + else + mix%nel = mix_nElements(mix) + mix%nsp = mix_nSpecies(mix) + mix%nrxn = mix_nReactions(mix) + end if + end subroutine importCK + + type(Mixture) function PureSub(i) + type(Mixture) :: mix + mix%hndl = cmix_newsub(i) + mix%nel = cmix_nElements(mix%hndl) + mix%nsp = 1 + mix%nrxn = 0 + ! mix%model = -1; + PureSub = mix + return + end function + + type(Mixture) function Water() + Water = PureSub(0) + return + end function + + type(Mixture) function Nitrogen() + Nitrogen = PureSub(1) + return + end function + + type(Mixture) function Methane() + Methane = PureSub(2) + return + end function + + type(Mixture) function Hydrogen() + Hydrogen = PureSub(3) + return + end function + + type(Mixture) function Oxygen() + Oxygen = PureSub(4) + return + end function + subroutine mix_delete(mix) + type (Mixture), intent(inout) :: mix + if (mix%hndl .ne. 0) then + call cmix_delete(mix%hndl) + mix%nel = 0 + mix%nsp = 0 + mix%nrxn = 0 + mix%hndl = 0 + end if + end subroutine + + logical function mix_ready(mix) + type (Mixture), intent(in) :: mix + if (mix%hndl .eq. 0 .or. mix%nel .eq. 0) then + mix_ready = .false. + else + mix_ready = .true. + end if + return + end function + + subroutine mix_copy(dest, src) + type (Mixture), intent(out) :: dest + type (Mixture), intent(in) :: src + dest%nel = src%nel + dest%nsp = src%nsp + dest%nrxn = src%nrxn + dest%hndl = src%hndl + !call incref(src%hndl) + end subroutine +! +! saveState +! + subroutine mix_saveState(self, state) + type(Mixture), intent(in) :: self + double precision, intent(out) :: state(state%nsp + 2) + call cmix_saveState(self%hndl, state) + return + end subroutine +! +! restoreState +! + subroutine mix_restoreState(self, state) + type(Mixture), intent(inout) :: self + double precision, intent(out) :: state(state%nsp + 2) + call cmix_restoreState(self%hndl, state) + return + end subroutine +! +! nElements +! + integer function mix_nElements(self) + type(Mixture), intent(in) :: self + mix_nElements=cmix_nElements(self%hndl) + return + end function +! +! nSpecies +! + integer function mix_nSpecies(self) + type(Mixture), intent(in) :: self + mix_nSpecies=cmix_nSpecies(self%hndl) + return + end function +! +! nReactions +! + integer function mix_nReactions(self) + type(Mixture), intent(inout) :: self + mix_nReactions=cmix_nReactions(self%hndl) + return + end function + + type (Mixture) function Mixture() + type(Mixture) mix + mix%hndl = cmix_newmixture() + Mixture = mix + end function +! +! addElement +! + subroutine mix_addElement(self, name, atomicWt) + type(Mixture), intent(inout) :: self + character*(*), intent(in) :: name + double precision, intent(in) :: atomicWt + call cmix_addElement(self%hndl, name, atomicWt) + return + end subroutine + + subroutine mix_getElementNames(mix, enames) + type(Mixture), intent(in) :: mix + character*(*), intent(out) :: enames(mix%nel) + do i = 1, mix%nel + call cmix_getename(mix%hndl, i, enames(i)) + end do + end subroutine + + integer function mix_eindex(mix, name) + type(Mixture), intent(in) :: mix + character*(*), intent(in) :: name ! element name + mix_eindex = cmix_eindex(mix%hndl, name) + end function +! +! atomicWeight +! + double precision function mix_atwt(self, m) + type(Mixture), intent(inout) :: self + integer, intent(in) :: m + mix_atwt=cmix_atwt(self%hndl, m) + return + end function +! +! nAtoms +! + double precision function mix_nAtoms(self, k, m) + type(Mixture), intent(inout) :: self + integer, intent(in) :: k + integer, intent(in) :: m + mix_nAtoms=cmix_nAtoms(self%hndl, k, m) + return + end function +! +! charge +! + double precision function mix_charge(self, k) + type(Mixture), intent(inout) :: self + integer, intent(in) :: k + mix_charge=cmix_charge(self%hndl, k) + return + end function +! +! speciesIndex +! + integer function mix_speciesIndex(self, name) + type(Mixture), intent(inout) :: self + character*(*), intent(in) :: name + mix_speciesIndex=cmix_speciesIndex(self%hndl, name) + return + end function + + subroutine mix_getspnm(mix, snames) + type(Mixture), intent(in) :: mix + character*(*), intent(out) :: snames(mix%nsp) + do i = 1, mix%nsp + call cmix_getspnm(mix%hndl, i, snames(i)) + end do + end subroutine +! +! molecularWeight +! + double precision function mix_molwt(self, k) + type(Mixture), intent(inout) :: self + integer, intent(in) :: k + mix_molwt=cmix_molwt(self%hndl, k) + return + end function +! +! getMolecularWeights +! + subroutine mix_gmolwts(self, molWts) + type(Mixture), intent(inout) :: self + double precision, intent(out) :: molWts(molWts%nsp) + call cmix_gmolwts(self%hndl, molWts) + return + end subroutine +! +! setMoleFractions +! + subroutine mix_setx(self, moleFracs) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: moleFracs(moleFracs%nsp) + call cmix_setx(self%hndl, moleFracs) + return + end subroutine +! +! setMoleFractions_NoNorm +! + subroutine mix_sxnonorm(self, moleFracs) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: moleFracs(moleFracs%nsp) + call cmix_sxnonorm(self%hndl, moleFracs) + return + end subroutine +! +! setMassFractions +! + subroutine mix_sety(self, massFracs) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: massFracs(massFracs%nsp) + call cmix_sety(self%hndl, massFracs) + return + end subroutine +! +! setMassFractions_NoNorm +! + subroutine mix_synonorm(self, y) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: y(y%nsp) + call cmix_synonorm(self%hndl, y) + return + end subroutine +! +! setConcentrations +! + subroutine mix_sconc(self, conc) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: conc(conc%nsp) + call cmix_sconc(self%hndl, conc) + return + end subroutine +! +! moleFraction +! + double precision function mix_xbyname(self, name) + type(Mixture), intent(inout) :: self + character*(*), intent(in) :: name + mix_xbyname=cmix_xbyname(self%hndl, name) + return + end function +! +! massFraction +! + double precision function mix_ybyname(self, name) + type(Mixture), intent(inout) :: self + character*(*), intent(in) :: name + mix_ybyname=cmix_ybyname(self%hndl, name) + return + end function +! +! getMoleFractions +! + subroutine mix_getx(self, moleFracs) + type(Mixture), intent(inout) :: self + double precision, intent(inout) :: moleFracs(moleFracs%nsp) + call cmix_getx(self%hndl, moleFracs) + return + end subroutine +! +! getMassFractions +! + subroutine mix_gety(self, massFracs) + type(Mixture), intent(inout) :: self + double precision, intent(inout) :: massFracs(massFracs%nsp) + call cmix_gety(self%hndl, massFracs) + return + end subroutine +! +! getConcentrations +! + subroutine mix_getconc(self, concentrations) + type(Mixture), intent(inout) :: self + double precision, intent(inout) :: concentrations(concentrations%nsp) + call cmix_getconc(self%hndl, concentrations) + return + end subroutine +! +! mean_X +! + double precision function mix_mean_X(self, Q) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: Q(Q%nsp) + mix_mean_X=cmix_mean_X(self%hndl, Q) + return + end function +! +! mean_Y +! + double precision function mix_mean_Y(self, Q) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: Q(Q%nsp) + mix_mean_Y=cmix_mean_Y(self%hndl, Q) + return + end function +! +! meanMolecularWeight +! + double precision function mix_meanmw(self) + type(Mixture), intent(inout) :: self + mix_meanmw=cmix_meanmw(self%hndl) + return + end function +! +! sum_xlogQ +! + double precision function mix_sum_xlogQ(self, Q) + type(Mixture), intent(inout) :: self + double precision, intent(out) :: Q(Q%nsp) + mix_sum_xlogQ=cmix_sum_xlogQ(self%hndl, Q) + return + end function +! +! setState_TPX +! + subroutine mix_setTPXarray(self, t, p, moleFracs) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: t + double precision, intent(in) :: p + double precision, intent(in) :: moleFracs(t%nsp) + call cmix_setTPXarray(self%hndl, t, p, moleFracs) + return + end subroutine +! +! setState_TPX +! + subroutine mix_setTPXstr(self, t, p, moleFracs) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: t + double precision, intent(in) :: p + character*(*), intent(in) :: moleFracs + call cmix_setTPXstr(self%hndl, t, p, moleFracs) + return + end subroutine +! +! setState_TPY +! + subroutine mix_setTPYarray(self, t, p, massFracs) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: t + double precision, intent(in) :: p + double precision, intent(in) :: massFracs(t%nsp) + call cmix_setTPYarray(self%hndl, t, p, massFracs) + return + end subroutine +! +! setState_TPY +! + subroutine mix_setTPYstr(self, t, p, massFracs) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: t + double precision, intent(in) :: p + character*(*), intent(in) :: massFracs + call cmix_setTPYstr(self%hndl, t, p, massFracs) + return + end subroutine +! +! setState_TRX +! + subroutine mix_setState_TRX(self, t, density, moleFracs) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: t + double precision, intent(in) :: density + double precision, intent(in) :: moleFracs(t%nsp) + call cmix_setState_TRX(self%hndl, t, density, moleFracs) + return + end subroutine +! +! setState_TRY +! + subroutine mix_setState_TRY(self, t, density, massFracs) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: t + double precision, intent(in) :: density + double precision, intent(in) :: massFracs(t%nsp) + call cmix_setState_TRY(self%hndl, t, density, massFracs) + return + end subroutine +! +! setTemperature +! + subroutine mix_settemp(self, temp) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: temp + call cmix_settemp(self%hndl, temp) + return + end subroutine +! +! setDensity +! + subroutine mix_setDensity(self, density) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: density + call cmix_setDensity(self%hndl, density) + return + end subroutine +! +! setState_TP +! + subroutine mix_setState_TP(self, t, p) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: t + double precision, intent(in) :: p + call cmix_setState_TP(self%hndl, t, p) + return + end subroutine +! +! setState_PX +! + subroutine mix_setState_PX(self, p, x) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: p + double precision, intent(in) :: x(p%nsp) + call cmix_setState_PX(self%hndl, p, x) + return + end subroutine +! +! setState_PY +! + subroutine mix_setState_PY(self, p, massFracs) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: p + double precision, intent(in) :: massFracs(p%nsp) + call cmix_setState_PY(self%hndl, p, massFracs) + return + end subroutine +! +! setPressure +! + subroutine mix_setPressure(self, p) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: p + call cmix_setPressure(self%hndl, p) + return + end subroutine +! +! setState_TR +! + subroutine mix_setState_TR(self, t, rho) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: t + double precision, intent(in) :: rho + call cmix_setState_TR(self%hndl, t, rho) + return + end subroutine +! +! setState_TX +! + subroutine mix_setState_TX(self, t, moleFracs) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: t + double precision, intent(inout) :: moleFracs(t%nsp) + call cmix_setState_TX(self%hndl, t, moleFracs) + return + end subroutine +! +! setState_TY +! + subroutine mix_setState_TY(self, t, massFracs) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: t + double precision, intent(in) :: massFracs(t%nsp) + call cmix_setState_TY(self%hndl, t, massFracs) + return + end subroutine +! +! setState_RX +! + subroutine mix_setState_RX(self, density, moleFracs) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: density + double precision, intent(in) :: moleFracs(density%nsp) + call cmix_setState_RX(self%hndl, density, moleFracs) + return + end subroutine +! +! setState_RY +! + subroutine mix_setState_RY(self, density, y) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: density + double precision, intent(in) :: y(density%nsp) + call cmix_setState_RY(self%hndl, density, y) + return + end subroutine +! +! setState_HP +! + subroutine mix_setState_HP(self, t, p) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: t + double precision, intent(in) :: p + call cmix_setState_HP(self%hndl, t, p) + return + end subroutine +! +! setState_UV +! + subroutine mix_setState_UV(self, t, p) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: t + double precision, intent(in) :: p + call cmix_setState_UV(self%hndl, t, p) + return + end subroutine +! +! setState_SP +! + subroutine mix_setState_SP(self, t, p) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: t + double precision, intent(in) :: p + call cmix_setState_SP(self%hndl, t, p) + return + end subroutine +! +! setState_SV +! + subroutine mix_setState_SV(self, t, p) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: t + double precision, intent(in) :: p + call cmix_setState_SV(self%hndl, t, p) + return + end subroutine +! +! getEnthalpy_RT +! + subroutine mix_gh_rt(self, h_RT) + type(Mixture), intent(inout) :: self + double precision, intent(out) :: h_RT(h_RT%nsp) + call cmix_gh_rt(self%hndl, h_RT) + return + end subroutine +! +! getGibbs_RT +! + subroutine mix_ggibbs_rt(self, g_RT) + type(Mixture), intent(inout) :: self + double precision, intent(out) :: g_RT(g_RT%nsp) + call cmix_ggibbs_rt(self%hndl, g_RT) + return + end subroutine +! +! getCp_R +! + subroutine mix_gcp_r(self, cp_R) + type(Mixture), intent(inout) :: self + double precision, intent(out) :: cp_R(cp_R%nsp) + call cmix_gcp_r(self%hndl, cp_R) + return + end subroutine +! +! getEntropy_R +! + subroutine mix_gs_r(self, s_R) + type(Mixture), intent(inout) :: self + double precision, intent(out) :: s_R(s_R%nsp) + call cmix_gs_r(self%hndl, s_R) + return + end subroutine +! +! minTemp +! + double precision function mix_minTemp(self) + type(Mixture), intent(inout) :: self + mix_minTemp=cmix_minTemp(self%hndl) + return + end function +! +! maxTemp +! + double precision function mix_maxTemp(self) + type(Mixture), intent(inout) :: self + mix_maxTemp=cmix_maxTemp(self%hndl) + return + end function +! +! refPressure +! + double precision function mix_refp(self) + type(Mixture), intent(inout) :: self + mix_refp=cmix_refp(self%hndl) + return + end function +! +! temperature +! + double precision function mix_temperature(self) + type(Mixture), intent(inout) :: self + mix_temperature=cmix_temperature(self%hndl) + return + end function +! +! density +! + double precision function mix_density(self) + type(Mixture), intent(inout) :: self + mix_density=cmix_density(self%hndl) + return + end function +! +! molarDensity +! + double precision function mix_moldens(self) + type(Mixture), intent(inout) :: self + mix_moldens=cmix_moldens(self%hndl) + return + end function +! +! pressure +! + double precision function mix_pressure(self) + type(Mixture), intent(inout) :: self + mix_pressure=cmix_pressure(self%hndl) + return + end function +! +! enthalpy_mole +! + double precision function mix_enthalpy_mole(self) + type(Mixture), intent(inout) :: self + mix_enthalpy_mole=cmix_enthalpy_mole(self%hndl) + return + end function +! +! intEnergy_mole +! + double precision function mix_umole(self) + type(Mixture), intent(inout) :: self + mix_umole=cmix_umole(self%hndl) + return + end function +! +! entropy_mole +! + double precision function mix_entropy_mole(self) + type(Mixture), intent(inout) :: self + mix_entropy_mole=cmix_entropy_mole(self%hndl) + return + end function +! +! gibbs_mole +! + double precision function mix_gibbs_mole(self) + type(Mixture), intent(inout) :: self + mix_gibbs_mole=cmix_gibbs_mole(self%hndl) + return + end function +! +! cp_mole +! + double precision function mix_cp_mole(self) + type(Mixture), intent(inout) :: self + mix_cp_mole=cmix_cp_mole(self%hndl) + return + end function +! +! cv_mole +! + double precision function mix_cv_mole(self) + type(Mixture), intent(inout) :: self + mix_cv_mole=cmix_cv_mole(self%hndl) + return + end function +! +! getChemPotentials_RT +! + subroutine mix_gchempot(self, mu) + type(Mixture), intent(inout) :: self + double precision, intent(out) :: mu(mu%nsp) + call cmix_gchempot(self%hndl, mu) + return + end subroutine +! +! enthalpy_mass +! + double precision function mix_enthalpy_mass(self) + type(Mixture), intent(inout) :: self + mix_enthalpy_mass=cmix_enthalpy_mass(self%hndl) + return + end function +! +! intEnergy_mass +! + double precision function mix_umass(self) + type(Mixture), intent(inout) :: self + mix_umass=cmix_umass(self%hndl) + return + end function +! +! entropy_mass +! + double precision function mix_entropy_mass(self) + type(Mixture), intent(inout) :: self + mix_entropy_mass=cmix_entropy_mass(self%hndl) + return + end function +! +! gibbs_mass +! + double precision function mix_gibbs_mass(self) + type(Mixture), intent(inout) :: self + mix_gibbs_mass=cmix_gibbs_mass(self%hndl) + return + end function +! +! cp_mass +! + double precision function mix_cp_mass(self) + type(Mixture), intent(inout) :: self + mix_cp_mass=cmix_cp_mass(self%hndl) + return + end function +! +! cv_mass +! + double precision function mix_cv_mass(self) + type(Mixture), intent(inout) :: self + mix_cv_mass=cmix_cv_mass(self%hndl) + return + end function +! +! setPotentialEnergy +! + subroutine mix_setpe_k(self, k, pe) + type(Mixture), intent(inout) :: self + integer, intent(in) :: k + double precision, intent(in) :: pe + call cmix_setpe_k(self%hndl, k, pe) + return + end subroutine +! +! potentialEnergy +! + double precision function mix_pe(self, k) + type(Mixture), intent(inout) :: self + integer, intent(in) :: k + mix_pe=cmix_pe(self%hndl, k) + return + end function +! +! critTemperature +! + double precision function mix_crittemp(self) + type(Mixture), intent(inout) :: self + mix_crittemp=cmix_crittemp(self%hndl) + return + end function +! +! critPressure +! + double precision function mix_critpres(self) + type(Mixture), intent(inout) :: self + mix_critpres=cmix_critpres(self%hndl) + return + end function +! +! satTemperature +! + double precision function mix_sattemp(self, p) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: p + mix_sattemp=cmix_sattemp(self%hndl, p) + return + end function +! +! satPressure +! + double precision function mix_satpres(self, t) + type(Mixture), intent(inout) :: self + double precision, intent(in) :: t + mix_satpres=cmix_satpres(self%hndl, t) + return + end function + + type(EOS) function thrm_get_eos(mix) + type(Mixture), intent(inout) :: mix + type(EOS) e + e%hndl = cthrm_get_eos(mix%hndl) + thrm_get_eos = e + return + end function +! +! setEquationOfState +! + subroutine mix_set_eos(self, eos) + type(Mixture), intent(inout) :: self + type(EOS), intent(inout) :: eos + call cmix_set_eos(self%hndl, eos%hndl) + return + end subroutine +! +! equilibrate +! + subroutine mix_equilib(self, propPair) + type(Mixture), intent(inout) :: self + character*(*), intent(in) :: propPair + call cmix_equilib(self%hndl, propPair) + return + end subroutine + + subroutine trans_set_trans(self, transportMgr) + type(Mixture), intent(inout) :: self + type(Transport), intent(inout) :: transportMgr + call ctrans_set_trans(self%hndl, transportMgr%hndl) + return + end subroutine + + type(Transport) function trans_transportMgr(self) + type(Mixture), intent(inout) :: self + type(Transport) tr + tr%hndl = ctrans_transportmgr(self%hndl) + tr%ierr = 0 + trans_transportMgr = tr + return + end function +! +! viscosity +! + double precision function mix_visc(self) + type(Mixture), intent(inout) :: self + mix_visc=cmix_visc(self%hndl) + return + end function +! +! getSpeciesViscosities +! + subroutine mix_gspvisc(self, visc) + type(Mixture), intent(inout) :: self + double precision, intent(inout) :: visc(visc%nsp) + call cmix_gspvisc(self%hndl, visc) + return + end subroutine + +! +! getSpeciesFluxes +! + subroutine trans_gflux(mix, ndim, grad_X, grad_T, fluxes) + type(Mixture), intent(in) :: mix + integer, intent(in) :: ndim + double precision, intent(inout) :: grad_X(:,:) + double precision, intent(in) :: grad_T(:) + double precision, intent(out) :: fluxes(:,:) + ldx = size(grad_X, dim=1) + ldf = size(fluxes, dim=1) + if (ldx .lt. mix%nsp .or. ldf .lt. mix%nsp) then + write(*,*) '### Error in getSpeciesFluxes ###' + write(*,*) 'An array is too small.' + write(*,*) 'minimum array sizes:' + write(*,*) ' grad_X(',mix%nsp,',',ndim,')' + write(*,*) ' grad_T(',ndim,')' + write(*,*) ' fluxes(',mix%nsp,',',ndim,')' + stop + end if + call ctrans_gflux(mix%hndl, ndim, ldx, grad_X, + & grad_T, ldf, fluxes) + return + end subroutine +! +! getMultiDiffCoeffs +! + subroutine mix_gmultidiff(self, ldim, multiDiff) + type(Mixture), intent(inout) :: self + integer, intent(in) :: ldim + double precision, intent(in) :: multiDiff(ldim, ldim%nsp) + call cmix_gmultidiff(self%hndl, ldim, multiDiff) + return + end subroutine +! +! thermalConductivity +! + double precision function mix_tcon(self) + type(Mixture), intent(inout) :: self + mix_tcon=cmix_tcon(self%hndl) + return + end function +! +! getThermalDiffCoeffs +! + subroutine mix_gtdiff(self, dt) + type(Mixture), intent(inout) :: self + double precision, intent(out) :: dt(dt%nsp) + call cmix_gtdiff(self%hndl, dt) + return + end subroutine +! +! getReactionString +! + subroutine mix_getrxnstr(self, i, rxnString) + type(Mixture), intent(inout) :: self + integer, intent(in) :: i + character*(*), intent(out) :: rxnString + call cmix_getrxnstr(self%hndl, i, rxnString) + return + end subroutine +! +! reactantStoichCoeff +! + double precision function mix_rstoich(self, k, i) + type(Mixture), intent(inout) :: self + integer, intent(in) :: k + integer, intent(in) :: i + mix_rstoich=cmix_rstoich(self%hndl, k, i) + return + end function +! +! productStoichCoeff +! + double precision function mix_pstoich(self, k, i) + type(Mixture), intent(inout) :: self + integer, intent(in) :: k + integer, intent(in) :: i + mix_pstoich=cmix_pstoich(self%hndl, k, i) + return + end function +! +! netStoichCoeff +! + double precision function mix_nstoich(self, k, i) + type(Mixture), intent(inout) :: self + integer, intent(in) :: k + integer, intent(in) :: i + mix_nstoich=cmix_nstoich(self%hndl, k, i) + return + end function +! +! getFwdRatesOfProgress +! + subroutine mix_get_fwdrop(self, fwdrop) + type(Mixture), intent(inout) :: self + double precision, intent(out) :: fwdrop(fwdrop%nrxn) + call cmix_get_fwdrop(self%hndl, fwdrop) + return + end subroutine +! +! getRevRatesOfProgress +! + subroutine mix_get_revrop(self, revrop) + type(Mixture), intent(inout) :: self + double precision, intent(out) :: revrop(revrop%nrxn) + call cmix_get_revrop(self%hndl, revrop) + return + end subroutine +! +! getNetRatesOfProgress +! + subroutine mix_get_netrop(self, netrop) + type(Mixture), intent(inout) :: self + double precision, intent(out) :: netrop(netrop%nrxn) + call cmix_get_netrop(self%hndl, netrop) + return + end subroutine +! +! getEquilibriumConstants +! + subroutine mix_get_kc(self, kc) + type(Mixture), intent(inout) :: self + double precision, intent(out) :: kc(kc%nsp) + call cmix_get_kc(self%hndl, kc) + return + end subroutine +! +! getCreationRates +! + subroutine mix_get_cdot(self, cdot) + type(Mixture), intent(inout) :: self + double precision, intent(out) :: cdot(cdot%nsp) + call cmix_get_cdot(self%hndl, cdot) + return + end subroutine +! +! getDestructionRates +! + subroutine mix_get_ddot(self, ddot) + type(Mixture), intent(inout) :: self + double precision, intent(out) :: ddot(ddot%nsp) + call cmix_get_ddot(self%hndl, ddot) + return + end subroutine +! +! getNetProductionRates +! + subroutine mix_get_wdot(self, wdot) + type(Mixture), intent(inout) :: self + double precision, intent(out) :: wdot(wdot%nsp) + call cmix_get_wdot(self%hndl, wdot) + return + end subroutine + end module diff --git a/include/fortran/ctmod.f b/include/fortran/ctmod.f new file mode 100755 index 000000000..87dcabbc8 --- /dev/null +++ b/include/fortran/ctmod.f @@ -0,0 +1,582 @@ +! ------------------------------------------------------------------------ +! +! Copyright 2002 California Institute of Technology +! +! Version 1.2.0.1 +! Mon Jan 7 07:13:18 2002 +! This file generated automatically. +! Cantera Fortran 90 Interface module +! ------------------------------------------------------------------------ + + module Cantera + + use cttypes + use ctmixture + use cttransport + use ctthermo + use ctreactor + use ctfdev + use ctutils + + double precision, parameter :: OneAtm = 1.01325D5 + double precision, parameter :: Avogadro = 6.022136736D23 + double precision, parameter :: GasConstant = 8314.0D0 + double precision, parameter :: StefanBoltz = 5.67D-8 + + interface assignment (=) + module procedure mix_copy + module procedure reac_copy + end interface + + interface addDirectory + module procedure util_addDirectory + end interface + + interface addElement + module procedure mix_addElement + end interface + + interface advance + module procedure reac_advance + end interface + + interface atomicWeight + module procedure mix_atwt + end interface + + interface charge + module procedure mix_charge + end interface + + interface contents + module procedure reac_contents + end interface + + interface copy + module procedure mix_copy + module procedure reac_copy + module procedure fdev_copy + end interface + + interface cp_mass + module procedure mix_cp_mass + end interface + + interface cp_mole + module procedure mix_cp_mole + end interface + + interface critPressure + module procedure mix_critpres + end interface + + interface critTemperature + module procedure mix_crittemp + end interface + + interface cv_mass + module procedure mix_cv_mass + end interface + + interface cv_mole + module procedure mix_cv_mole + end interface + + interface delete + module procedure mix_delete + module procedure trans_delete + end interface + + interface density + module procedure mix_density + module procedure reac_density + end interface + + interface disableChemistry + module procedure reac_chemoff + end interface + + interface downstream + module procedure fdev_downstream + end interface + + interface elementIndex + module procedure mix_eindex + end interface + + interface enableChemistry + module procedure reac_chemon + end interface + + interface enthalpy_mass + module procedure mix_enthalpy_mass + module procedure reac_enthalpy_mass + end interface + + interface enthalpy_mole + module procedure mix_enthalpy_mole + end interface + + interface entropy_mass + module procedure mix_entropy_mass + end interface + + interface entropy_mole + module procedure mix_entropy_mole + end interface + + interface equationOfState + module procedure mix_get_eos + end interface + + interface equilibrate + module procedure mix_equilib + end interface + + interface getChemPotentials_RT + module procedure mix_gchempot + end interface + + interface getConcentrations + module procedure mix_getconc + end interface + + interface getCp_R + module procedure mix_gcp_r + end interface + + interface getCreationRates + module procedure mix_get_cdot + end interface + + interface getDestructionRates + module procedure mix_get_ddot + end interface + + interface getElementNames + module procedure mix_getElementNames + end interface + + interface getEnthalpy_RT + module procedure mix_gh_rt + end interface + + interface getEntropy_R + module procedure mix_gs_r + end interface + + interface getEquilibriumConstants + module procedure mix_get_kc + end interface + + interface getFwdRatesOfProgress + module procedure mix_get_fwdrop + end interface + + interface getGains + module procedure fdev_getGains + end interface + + interface getGibbs_RT + module procedure mix_ggibbs_rt + end interface + + interface getMassFractions + module procedure mix_gety + end interface + + interface getMoleFractions + module procedure mix_getx + end interface + + interface getMolecularWeights + module procedure mix_gmolwts + end interface + + interface getMultiDiffCoeffs + module procedure mix_gmultidiff + end interface + + interface getNetProductionRates + module procedure mix_get_wdot + end interface + + interface getNetRatesOfProgress + module procedure mix_get_netrop + end interface + + interface getReactionString + module procedure mix_getrxnstr + end interface + + interface getRevRatesOfProgress + module procedure mix_get_revrop + end interface + + interface getSpeciesFluxes + module procedure mix_gflux + end interface + + interface getSpeciesNames + module procedure mix_getspnm + end interface + + interface getSpeciesViscosities + module procedure mix_gspvisc + end interface + + interface getThermalDiffCoeffs + module procedure mix_gtdiff + end interface + + interface gibbs_mass + module procedure mix_gibbs_mass + end interface + + interface gibbs_mole + module procedure mix_gibbs_mole + end interface + + interface install + module procedure fdev_install + end interface + + interface intEnergy_mass + module procedure mix_umass + module procedure reac_umass + end interface + + interface intEnergy_mole + module procedure mix_umole + end interface + + interface mass + module procedure reac_mass + end interface + + interface massFlowRate + module procedure fdev_mfrate + end interface + + interface massFraction + module procedure mix_ybyname + end interface + + interface maxError + module procedure fdev_maxError + end interface + + interface maxTemp + module procedure mix_maxTemp + end interface + + interface meanMolecularWeight + module procedure mix_meanmw + end interface + + interface mean_X + module procedure mix_mean_X + end interface + + interface mean_Y + module procedure mix_mean_Y + end interface + + interface minTemp + module procedure mix_minTemp + end interface + + interface molarDensity + module procedure mix_moldens + end interface + + interface moleFraction + module procedure mix_xbyname + end interface + + interface molecularWeight + module procedure mix_molwt + end interface + + interface nAtoms + module procedure mix_nAtoms + end interface + + interface nElements + module procedure mix_nElements + end interface + + interface nReactions + module procedure mix_nReactions + end interface + + interface nSpecies + module procedure mix_nSpecies + end interface + + interface netStoichCoeff + module procedure mix_nstoich + end interface + + interface potentialEnergy + module procedure mix_pe + end interface + + interface pressure + module procedure mix_pressure + module procedure reac_pressure + end interface + + interface printSummary + module procedure util_printSummary + end interface + + interface productStoichCoeff + module procedure mix_pstoich + end interface + + interface reactantStoichCoeff + module procedure mix_rstoich + end interface + + interface ready + module procedure mix_ready + module procedure fdev_ready + end interface + + interface refPressure + module procedure mix_refp + end interface + + interface reset + module procedure fdev_reset + end interface + + interface residenceTime + module procedure reac_residenceTime + end interface + + interface restoreState + module procedure mix_restoreState + end interface + + interface satPressure + module procedure mix_satpres + end interface + + interface satTemperature + module procedure mix_sattemp + end interface + + interface saveState + module procedure mix_saveState + end interface + + interface setArea + module procedure reac_setArea + end interface + + interface setConcentrations + module procedure mix_sconc + end interface + + interface setDensity + module procedure mix_setDensity + end interface + + interface setEmissivity + module procedure reac_setEmissivity + end interface + + interface setEquationOfState + module procedure mix_set_eos + end interface + + interface setExtPressure + module procedure reac_setepr + end interface + + interface setExtRadTemp + module procedure reac_setExtRadTemp + end interface + + interface setExtTemp + module procedure reac_setExtTemp + end interface + + interface setGains + module procedure fdev_setGains + end interface + + interface setHeatTransferCoeff + module procedure reac_seth + end interface + + interface setInitialTime + module procedure reac_setitm + end interface + + interface setInitialVolume + module procedure reac_setivol + end interface + + interface setMassFractions + module procedure mix_sety + end interface + + interface setMassFractions_NoNorm + module procedure mix_synonorm + end interface + + interface setMaxStep + module procedure reac_setMaxStep + end interface + + interface setMixture + module procedure reac_insmix + end interface + + interface setMoleFractions + module procedure mix_setx + end interface + + interface setMoleFractions_NoNorm + module procedure mix_sxnonorm + end interface + + interface setOptions + module procedure trans_setopt + end interface + + interface setPotentialEnergy + module procedure mix_setpe_k + end interface + + interface setPressure + module procedure mix_setPressure + end interface + + interface setSetpoint + module procedure fdev_setspnt + end interface + + interface setState_HP + module procedure mix_setState_HP + end interface + + interface setState_PX + module procedure mix_setState_PX + end interface + + interface setState_PY + module procedure mix_setState_PY + end interface + + interface setState_RX + module procedure mix_setState_RX + end interface + + interface setState_RY + module procedure mix_setState_RY + end interface + + interface setState_SP + module procedure mix_setState_SP + end interface + + interface setState_SV + module procedure mix_setState_SV + end interface + + interface setState_TP + module procedure mix_setState_TP + end interface + + interface setState_TPX + module procedure mix_setTPXstr + module procedure mix_setTPXarray + end interface + + interface setState_TPY + module procedure mix_setTPYstr + module procedure mix_setTPYarray + end interface + + interface setState_TR + module procedure mix_setState_TR + end interface + + interface setState_TRX + module procedure mix_setState_TRX + end interface + + interface setState_TRY + module procedure mix_setState_TRY + end interface + + interface setState_TX + module procedure mix_setState_TX + end interface + + interface setState_TY + module procedure mix_setState_TY + end interface + + interface setState_UV + module procedure mix_setState_UV + end interface + + interface setTemperature + module procedure mix_settemp + end interface + + interface setTransport + module procedure mix_set_trans + end interface + + interface setVDotCoeff + module procedure reac_setVDotCoeff + end interface + + interface speciesIndex + module procedure mix_speciesIndex + end interface + + interface sum_xlogQ + module procedure mix_sum_xlogQ + end interface + + interface temperature + module procedure mix_temperature + module procedure reac_temperature + end interface + + interface thermalConductivity + module procedure mix_tcon + end interface + + interface time + module procedure reac_time + end interface + + interface transportMgr + module procedure mix_transportMgr + end interface + + interface update + module procedure fdev_update + end interface + + interface upstream + module procedure fdev_upstream + end interface + + interface viscosity + module procedure mix_visc + end interface + + interface volume + module procedure reac_volume + end interface + + end module diff --git a/include/fortran/ctreactormod.f b/include/fortran/ctreactormod.f new file mode 100755 index 000000000..2fe994207 --- /dev/null +++ b/include/fortran/ctreactormod.f @@ -0,0 +1,468 @@ +! ------------------------------------------------------------------------ +! +! Copyright 2002 California Institute of Technology +! +! Version 1.2.0.1 +! Mon Jan 7 07:13:18 2002 +! This file generated automatically. +! Fortran 90 module implementing Cantera class Reactor +! ------------------------------------------------------------------------ + module ctreactor + use cttypes + interface + + integer function creac_newreactor() +!DEC$ attributes c, reference :: creac_newreactor +!DEC$ attributes alias:'_creac_newreactor_' :: creac_newreactor +!DEC$ attributes dllimport :: creac_newreactor + end function creac_newreactor + + integer function creac_newreservoir() +!DEC$ attributes c, reference :: creac_newreservoir +!DEC$ attributes alias:'_creac_newreservoir_' :: creac_newreservoir +!DEC$ attributes dllimport :: creac_newreservoir + end function creac_newreservoir + type(Reactor) function creac_StirredReactor() +!DEC$ attributes c, reference :: creac_StirredReactor +!DEC$ attributes alias: '_creac_stirredreactor_' :: creac_StirredReactor +!DEC$ attributes dllimport :: creac_StirredReactor + end function + + type(Reactor) function creac_Reservoir() +!DEC$ attributes c, reference :: creac_Reservoir +!DEC$ attributes alias: '_creac_reservoir_' :: creac_Reservoir +!DEC$ attributes dllimport :: creac_Reservoir + end function + + subroutine creac_setivol(reac, vol) +!DEC$ attributes c, reference :: creac_setivol +!DEC$ attributes alias: '_creac_setivol_' :: creac_setivol +!DEC$ attributes dllimport :: creac_setivol + type(Reactor), intent(inout) :: reac + double precision, intent(in) :: vol + end subroutine + + subroutine creac_setitm(reac, time) +!DEC$ attributes c, reference :: creac_setitm +!DEC$ attributes alias: '_creac_setitm_' :: creac_setitm +!DEC$ attributes dllimport :: creac_setitm + type(Reactor), intent(inout) :: reac + double precision, intent(in) :: time + end subroutine + + subroutine creac_setMaxStep(reac, maxstep) +!DEC$ attributes c, reference :: creac_setMaxStep +!DEC$ attributes alias: '_creac_setmaxstep_' :: creac_setMaxStep +!DEC$ attributes dllimport :: creac_setMaxStep + type(Reactor), intent(inout) :: reac + double precision, intent(in) :: maxstep + end subroutine + + subroutine creac_setArea(reac, area) +!DEC$ attributes c, reference :: creac_setArea +!DEC$ attributes alias: '_creac_setarea_' :: creac_setArea +!DEC$ attributes dllimport :: creac_setArea + type(Reactor), intent(inout) :: reac + double precision, intent(in) :: area + end subroutine + + subroutine creac_setExtTemp(reac, ts) +!DEC$ attributes c, reference :: creac_setExtTemp +!DEC$ attributes alias: '_creac_setexttemp_' :: creac_setExtTemp +!DEC$ attributes dllimport :: creac_setExtTemp + type(Reactor), intent(inout) :: reac + double precision, intent(in) :: ts + end subroutine + + subroutine creac_setExtRadTemp(reac, trad) +!DEC$ attributes c, reference :: creac_setExtRadTemp +!DEC$ attributes alias: '_creac_setextradtemp_' :: creac_setExtRadTemp +!DEC$ attributes dllimport :: creac_setExtRadTemp + type(Reactor), intent(inout) :: reac + double precision, intent(in) :: trad + end subroutine + + subroutine creac_seth(reac, h) +!DEC$ attributes c, reference :: creac_seth +!DEC$ attributes alias: '_creac_seth_' :: creac_seth +!DEC$ attributes dllimport :: creac_seth + type(Reactor), intent(inout) :: reac + double precision, intent(in) :: h + end subroutine + + subroutine creac_setVDotCoeff(reac, k) +!DEC$ attributes c, reference :: creac_setVDotCoeff +!DEC$ attributes alias: '_creac_setvdotcoeff_' :: creac_setVDotCoeff +!DEC$ attributes dllimport :: creac_setVDotCoeff + type(Reactor), intent(inout) :: reac + double precision, intent(in) :: k + end subroutine + + subroutine creac_setEmissivity(reac, emis) +!DEC$ attributes c, reference :: creac_setEmissivity +!DEC$ attributes alias: '_creac_setemissivity_' :: creac_setEmissivity +!DEC$ attributes dllimport :: creac_setEmissivity + type(Reactor), intent(inout) :: reac + double precision, intent(in) :: emis + end subroutine + + subroutine creac_setepr(reac, p0) +!DEC$ attributes c, reference :: creac_setepr +!DEC$ attributes alias: '_creac_setepr_' :: creac_setepr +!DEC$ attributes dllimport :: creac_setepr + type(Reactor), intent(inout) :: reac + double precision, intent(in) :: p0 + end subroutine + + subroutine creac_insmix(reac, mix) +!DEC$ attributes c, reference :: creac_insmix +!DEC$ attributes alias: '_creac_insmix_' :: creac_insmix +!DEC$ attributes dllimport :: creac_insmix + type(Reactor), intent(inout) :: reac + type(Mixture), intent(inout) :: mix + end subroutine + + type(Mixture) function creac_contents(reac) +!DEC$ attributes c, reference :: creac_contents +!DEC$ attributes alias: '_creac_contents_' :: creac_contents +!DEC$ attributes dllimport :: creac_contents + type(Reactor), intent(inout) :: reac + end function + + subroutine creac_advance(reac, time) +!DEC$ attributes c, reference :: creac_advance +!DEC$ attributes alias: '_creac_advance_' :: creac_advance +!DEC$ attributes dllimport :: creac_advance + type(Reactor), intent(inout) :: reac + double precision, intent(in) :: time + end subroutine + + double precision function creac_residenceTime(reac) +!DEC$ attributes c, reference :: creac_residenceTime +!DEC$ attributes alias: '_creac_residencetime_' :: creac_residenceTime +!DEC$ attributes dllimport :: creac_residenceTime + type(Reactor), intent(inout) :: reac + end function + + double precision function creac_time(reac) +!DEC$ attributes c, reference :: creac_time +!DEC$ attributes alias: '_creac_time_' :: creac_time +!DEC$ attributes dllimport :: creac_time + type(Reactor), intent(inout) :: reac + end function + + double precision function creac_volume(reac) +!DEC$ attributes c, reference :: creac_volume +!DEC$ attributes alias: '_creac_volume_' :: creac_volume +!DEC$ attributes dllimport :: creac_volume + type(Reactor), intent(inout) :: reac + end function + + double precision function creac_density(reac) +!DEC$ attributes c, reference :: creac_density +!DEC$ attributes alias: '_creac_density_' :: creac_density +!DEC$ attributes dllimport :: creac_density + type(Reactor), intent(inout) :: reac + end function + + double precision function creac_temperature(reac) +!DEC$ attributes c, reference :: creac_temperature +!DEC$ attributes alias: '_creac_temperature_' :: creac_temperature +!DEC$ attributes dllimport :: creac_temperature + type(Reactor), intent(inout) :: reac + end function + + double precision function creac_enthalpy_mass(reac) +!DEC$ attributes c, reference :: creac_enthalpy_mass +!DEC$ attributes alias: '_creac_enthalpy_mass_' :: creac_enthalpy_mass +!DEC$ attributes dllimport :: creac_enthalpy_mass + type(Reactor), intent(inout) :: reac + end function + + double precision function creac_umass(reac) +!DEC$ attributes c, reference :: creac_umass +!DEC$ attributes alias: '_creac_umass_' :: creac_umass +!DEC$ attributes dllimport :: creac_umass + type(Reactor), intent(inout) :: reac + end function + + double precision function creac_pressure(reac) +!DEC$ attributes c, reference :: creac_pressure +!DEC$ attributes alias: '_creac_pressure_' :: creac_pressure +!DEC$ attributes dllimport :: creac_pressure + type(Reactor), intent(inout) :: reac + end function + + double precision function creac_mass(reac) +!DEC$ attributes c, reference :: creac_mass +!DEC$ attributes alias: '_creac_mass_' :: creac_mass +!DEC$ attributes dllimport :: creac_mass + type(Reactor), intent(inout) :: reac + end function + + subroutine creac_chemon(reac) +!DEC$ attributes c, reference :: creac_chemon +!DEC$ attributes alias: '_creac_chemon_' :: creac_chemon +!DEC$ attributes dllimport :: creac_chemon + type(Reactor), intent(inout) :: reac + end subroutine + + subroutine creac_chemoff(reac) +!DEC$ attributes c, reference :: creac_chemoff +!DEC$ attributes alias: '_creac_chemoff_' :: creac_chemoff +!DEC$ attributes dllimport :: creac_chemoff + type(Reactor), intent(inout) :: reac + end subroutine + + end interface + contains + + type(Reactor) function StirredReactor() + type(Reactor) :: reac + reac%hndl = creac_newreactor() + StirredReactor = reac + return + end function + + type(Reactor) function Reservoir() + type(Reactor) :: r + r%hndl = creac_newreservoir() + Reservoir = r + return + end function + + subroutine reac_copy(dest, src) + type (Reactor), intent(out) :: dest + type (Reactor), intent(in) :: src + call mix_copy(dest%mix, src%mix) + dest%hndl = src%hndl + end subroutine +! +! setInitialVolume +! + subroutine reac_setivol(self, reac, vol) + type(Reactor), intent(inout) :: self + type(Reactor), intent(inout) :: reac + double precision, intent(in) :: vol + call creac_setivol(self%hndl, reac%hndl, vol) + return + end subroutine +! +! setInitialTime +! + subroutine reac_setitm(self, reac, time) + type(Reactor), intent(inout) :: self + type(Reactor), intent(inout) :: reac + double precision, intent(in) :: time + call creac_setitm(self%hndl, reac%hndl, time) + return + end subroutine +! +! setMaxStep +! + subroutine reac_setMaxStep(self, reac, maxstep) + type(Reactor), intent(inout) :: self + type(Reactor), intent(inout) :: reac + double precision, intent(in) :: maxstep + call creac_setMaxStep(self%hndl, reac%hndl, maxstep) + return + end subroutine +! +! setArea +! + subroutine reac_setArea(self, reac, area) + type(Reactor), intent(inout) :: self + type(Reactor), intent(inout) :: reac + double precision, intent(in) :: area + call creac_setArea(self%hndl, reac%hndl, area) + return + end subroutine +! +! setExtTemp +! + subroutine reac_setExtTemp(self, reac, ts) + type(Reactor), intent(inout) :: self + type(Reactor), intent(inout) :: reac + double precision, intent(in) :: ts + call creac_setExtTemp(self%hndl, reac%hndl, ts) + return + end subroutine +! +! setExtRadTemp +! + subroutine reac_setExtRadTemp(self, reac, trad) + type(Reactor), intent(inout) :: self + type(Reactor), intent(inout) :: reac + double precision, intent(in) :: trad + call creac_setExtRadTemp(self%hndl, reac%hndl, trad) + return + end subroutine +! +! setHeatTransferCoeff +! + subroutine reac_seth(self, reac, h) + type(Reactor), intent(inout) :: self + type(Reactor), intent(inout) :: reac + double precision, intent(in) :: h + call creac_seth(self%hndl, reac%hndl, h) + return + end subroutine +! +! setVDotCoeff +! + subroutine reac_setVDotCoeff(self, reac, k) + type(Reactor), intent(inout) :: self + type(Reactor), intent(inout) :: reac + double precision, intent(in) :: k + call creac_setVDotCoeff(self%hndl, reac%hndl, k) + return + end subroutine +! +! setEmissivity +! + subroutine reac_setEmissivity(self, reac, emis) + type(Reactor), intent(inout) :: self + type(Reactor), intent(inout) :: reac + double precision, intent(in) :: emis + call creac_setEmissivity(self%hndl, reac%hndl, emis) + return + end subroutine +! +! setExtPressure +! + subroutine reac_setepr(self, reac, p0) + type(Reactor), intent(inout) :: self + type(Reactor), intent(inout) :: reac + double precision, intent(in) :: p0 + call creac_setepr(self%hndl, reac%hndl, p0) + return + end subroutine + + subroutine reac_insmix(reac, mix) + type(Reactor), intent(inout) :: reac + type(Mixture), intent(inout) :: mix + call creac_insmix(reac%hndl, mix%hndl) + reac%mix = mix + return + end subroutine + +! +! contents +! + type(Mixture) function reac_contents(reac) + type(Reactor), intent(inout) :: reac + type(Mixture) mix + mix%hndl = creac_contents(reac%hndl) + reac_contents = mix + return + end function +! +! advance +! + subroutine reac_advance(self, reac, time) + type(Reactor), intent(inout) :: self + type(Reactor), intent(inout) :: reac + double precision, intent(in) :: time + call creac_advance(self%hndl, reac%hndl, time) + return + end subroutine +! +! residenceTime +! + double precision function reac_residenceTime(self, reac) + type(Reactor), intent(inout) :: self + type(Reactor), intent(inout) :: reac + reac_residenceTime=creac_residenceTime(self%hndl, reac%hndl) + return + end function +! +! time +! + double precision function reac_time(self, reac) + type(Reactor), intent(inout) :: self + type(Reactor), intent(inout) :: reac + reac_time=creac_time(self%hndl, reac%hndl) + return + end function +! +! volume +! + double precision function reac_volume(self, reac) + type(Reactor), intent(inout) :: self + type(Reactor), intent(inout) :: reac + reac_volume=creac_volume(self%hndl, reac%hndl) + return + end function +! +! density +! + double precision function reac_density(self, reac) + type(Reactor), intent(inout) :: self + type(Reactor), intent(inout) :: reac + reac_density=creac_density(self%hndl, reac%hndl) + return + end function +! +! temperature +! + double precision function reac_temperature(self, reac) + type(Reactor), intent(inout) :: self + type(Reactor), intent(inout) :: reac + reac_temperature=creac_temperature(self%hndl, reac%hndl) + return + end function +! +! enthalpy_mass +! + double precision function reac_enthalpy_mass(self, reac) + type(Reactor), intent(inout) :: self + type(Reactor), intent(inout) :: reac + reac_enthalpy_mass=creac_enthalpy_mass(self%hndl, reac%hndl) + return + end function +! +! intEnergy_mass +! + double precision function reac_umass(self, reac) + type(Reactor), intent(inout) :: self + type(Reactor), intent(inout) :: reac + reac_umass=creac_umass(self%hndl, reac%hndl) + return + end function +! +! pressure +! + double precision function reac_pressure(self, reac) + type(Reactor), intent(inout) :: self + type(Reactor), intent(inout) :: reac + reac_pressure=creac_pressure(self%hndl, reac%hndl) + return + end function +! +! mass +! + double precision function reac_mass(self, reac) + type(Reactor), intent(inout) :: self + type(Reactor), intent(inout) :: reac + reac_mass=creac_mass(self%hndl, reac%hndl) + return + end function +! +! enableChemistry +! + subroutine reac_chemon(self, reac) + type(Reactor), intent(inout) :: self + type(Reactor), intent(inout) :: reac + call creac_chemon(self%hndl, reac%hndl) + return + end subroutine +! +! disableChemistry +! + subroutine reac_chemoff(self, reac) + type(Reactor), intent(inout) :: self + type(Reactor), intent(inout) :: reac + call creac_chemoff(self%hndl, reac%hndl) + return + end subroutine + end module diff --git a/include/fortran/ctthermomod.f b/include/fortran/ctthermomod.f new file mode 100755 index 000000000..728f28f37 --- /dev/null +++ b/include/fortran/ctthermomod.f @@ -0,0 +1,12 @@ +! ------------------------------------------------------------------------ +! +! Copyright 2002 California Institute of Technology +! +! Version 1.2.0.1 +! Mon Jan 7 07:13:18 2002 +! This file generated automatically. +! Fortran 90 module implementing Cantera class EOS +! ------------------------------------------------------------------------ + module ctthermo + use cttypes + end module diff --git a/include/fortran/cttransportmod.f b/include/fortran/cttransportmod.f new file mode 100755 index 000000000..dd1b179ff --- /dev/null +++ b/include/fortran/cttransportmod.f @@ -0,0 +1,108 @@ +! ------------------------------------------------------------------------ +! +! Copyright 2002 California Institute of Technology +! +! Version 1.2.0.1 +! Mon Jan 7 07:13:18 2002 +! This file generated automatically. +! Fortran 90 module implementing Cantera class Transport +! ------------------------------------------------------------------------ + module cttransport + use cttypes + interface + + integer function ctrans_Transport(mix_hndl, + & type, trans_db, logLevel) +!DEC$ attributes c, reference :: ctrans_Transport +!DEC$ attributes alias: '_ctrans_transport_' :: ctrans_Transport +!DEC$ attributes dllimport :: ctrans_Transport + integer, intent(inout) :: mix_hndl + integer, intent(in) :: type + character*(*), intent(in) :: trans_db + integer, intent(in) :: logLevel + end function + subroutine ctrans_delete(transportMgr) +!DEC$ attributes c, reference :: ctrans_delete +!DEC$ attributes alias: '_ctrans_delete_' :: ctrans_delete +!DEC$ attributes dllimport :: ctrans_delete + type(Transport), intent(inout) :: transportMgr + end subroutine + + + subroutine ctrans_setopt(itr, ijob, + & iopt, dopt) +!DEC$ attributes c, reference :: ctrans_setopt +!DEC$ attributes alias: '_ctrans_setopt_' :: ctrans_setopt +!DEC$ attributes dllimport :: ctrans_setopt + integer, intent(inout) :: itr + integer, intent(in) :: ijob + integer, intent(in) :: iopt + double precision, intent(in) :: dopt + end subroutine + end interface + contains + + type(Transport) function MultiTransport(mix, + & trans_db, logLevel) + type(Mixture), intent(inout) :: mix + character*(*), intent(in) :: trans_db + integer, intent(in) :: logLevel + type(Transport) tr + tr%hndl=ctrans_transport(mix%hndl, + & Multicomponent, trans_db, logLevel) + tr%ierr = 0 + MultiTransport = tr + return + end function + + + type(Transport) function MixTransport(mix, + & trans_db, logLevel) + type(Mixture), intent(inout) :: mix + character*(*), intent(in) :: trans_db + integer, intent(in) :: logLevel + type(Transport) tr + tr%hndl=ctrans_transport(mix%hndl, + & MixtureAveraged, trans_db, logLevel) + tr%ierr = 0 + MixTransport = tr + return + end function + + + subroutine trans_delete(transportMgr) + type(Transport), intent(inout) :: transportMgr + call ctrans_delete(transportMgr%hndl) + transportMgr%hndl = 0 + transportMgr%ierr = 0 + return + end subroutine + + subroutine trans_setopt(tr, linearSolver, GMRES_m, GMRES_eps) + implicit double precision (a-h,o-z) + type(Transport), intent(inout) :: tr + character*(*), intent(in), optional :: linearSolver + integer, intent(in), optional :: GMRES_m + double precision, intent(in), optional :: GMRES_eps + itr = tr%hndl + dummy = -1.d0 + idummy = -1 + if (present(linearSolver)) then + meth = 2 + if (linearSolver .eq. 'GMRES') meth = 1 + ijob = 0 + write(*,*) 'setting lin solver' + call ctrans_setopt(itr,ijob, meth, dummy) + write(*,*) 'ret from setting lin solver' + end if + if (present(GMRES_m)) then + ijob = 1 + call ctrans_setopt(itr,ijob, GMRES_m, dummy) + end if + if (present(GMRES_eps)) then + ijob = 2 + call ctrans_setopt(itr,ijob, idummy, GMRES_eps) + end if + return + end subroutine + end module diff --git a/include/fortran/ctutilsmod.f b/include/fortran/ctutilsmod.f new file mode 100755 index 000000000..2a5d7eabb --- /dev/null +++ b/include/fortran/ctutilsmod.f @@ -0,0 +1,57 @@ +! ------------------------------------------------------------------------ +! +! Copyright 2002 California Institute of Technology +! +! Version 1.2.0.1 +! Mon Jan 7 07:13:18 2002 +! This file generated automatically. +! Fortran 90 module implementing Cantera class Utils +! ------------------------------------------------------------------------ + module ctutils + use cttypes + interface + + subroutine cutil_report(mix_hndl, n, txt) +!DEC$ attributes c, reference :: cutil_report +!DEC$ attributes alias: '_cutil_report_' :: cutil_report +!DEC$ attributes dllimport :: cutil_report + integer, intent(in) :: mix_hndl + integer, intent(in) :: n + character*(*), intent(out) :: txt + end subroutine + subroutine cutil_addDirectory(dirname) +!DEC$ attributes c, reference :: cutil_addDirectory +!DEC$ attributes alias: '_cutil_adddirectory_' :: cutil_addDirectory +!DEC$ attributes dllimport :: cutil_addDirectory + character*(*), intent(in) :: dirname + end subroutine + + end interface + contains + + subroutine util_printSummary(mix, lu) + type(Mixture), intent(in) :: mix + integer, intent(in) :: lu + character*4000 txt + n = 4000 + call cutil_report(mix%hndl, n, txt) + istrt = 1 + ifin = 100 + do i = 1,40 + write(lu,'(a$)') txt(istrt:ifin) + istrt = i*100 + 1 + ifin = istrt + 99 + if (ifin .gt. n) ifin = n + if (istrt .ge. n) return + end do + return + end subroutine +! +! addDirectory +! + subroutine util_addDirectory(dirname) + character*(*), intent(in) :: dirname + call cutil_addDirectory(dirname) + return + end subroutine + end module diff --git a/include/ftn_defs.h b/include/ftn_defs.h new file mode 100755 index 000000000..fca0c3fb6 --- /dev/null +++ b/include/ftn_defs.h @@ -0,0 +1,20 @@ + +#ifndef CT_FTNDEFS_H +#define CT_FTNDEFS_H + +// These definitions are required for Fortran/C mixed-language programming. + + +// Fortran compilers pass character strings in argument lists by +// adding a hidden argement with the length of the string. Some +// compilers add the hidden length argument immediately after the +// CHARACTER variable being passed, while others put all of the hidden +// length arguments at the end of the argument list. Define this if +// the lengths are at the end of the argument list. +#define STRING_LEN_AT_END + +// Define this if Fortran adds a trailing underscore to names in object files. +// For linux and most unix systems, this is the case. +#define FTN_TRAILING_UNDERSCORE + +#endif diff --git a/include/integrators.h b/include/integrators.h new file mode 100755 index 000000000..60f34716c --- /dev/null +++ b/include/integrators.h @@ -0,0 +1,6 @@ +#ifndef CT_INTEG_H_INCL +#define CT_INTEG_H_INCL + +#include "kernel/CVode.h" + +#endif diff --git a/include/kinetics.h b/include/kinetics.h new file mode 100644 index 000000000..99c995213 --- /dev/null +++ b/include/kinetics.h @@ -0,0 +1,320 @@ +/** + * @file Kinetics.h + * + * $Author$ + * $Revision$ + * $Date$ + */ + +// Copyright 2001 California Institute of Technology + +/** + * @defgroup kineticsGroup Kinetics + */ + +#ifndef CT_KINETICS_H +#define CT_KINETICS_H + +#include "ctexceptions.h" +//#include "Phase.h" +#include "ThermoPhase.h" + +namespace Cantera { + + class ReactionData; + + /** + * Public interface for kinetics managers. This class serves as a + * base class to derive 'kinetics managers', which are classes + * that manage homogeneous chemistry within one phase. + */ + class Kinetics { + + public: + + // typedefs + typedef ThermoPhase thermo_t; + + /// Constructor. + Kinetics() : m_ii(0), m_thermo(0), m_index(-1) {} + Kinetics(thermo_t* thermo) + : m_ii(0), m_index(-1) { + if (thermo) { + m_start.push_back(0); + m_thermo.push_back(thermo); + } + } + + /// Destructor. Does nothing. + virtual ~Kinetics() {} // delete m_xml; } + + int index(){ return m_index; } + void setIndex(int index) { m_index = index; } + + //XML_Node& xml() { return *m_xml; } + + /// Identifies subclass. + virtual int type() { return 0; } + + int start(int n) { return m_start[n]; } + + /// Number of reactions + int nReactions() const {return m_ii;} + + /// Number of species + int nTotalSpecies() const { + int n=0, np; + np = nPhases(); + for (int p = 0; p < np; p++) n += thermo(p).nSpecies(); + return n; + } + + /** + * Stoichiometric coefficient of species k as a reactant in + * reaction i. + */ + virtual doublereal reactantStoichCoeff(int k, int i) const { + err("reactantStoichCoeff"); + return -1.0; + } + + /** + * Stoichiometric coefficient of species k as a product in + * reaction i. + */ + virtual doublereal productStoichCoeff(int k, int i) const { + err("productStoichCoeff"); + return -1.0; + } + + + /** + * Returns a read-only reference to the vector of reactant + * index numbers for reaction i. + */ + virtual const vector_int& reactants(int i) const { + return m_reactants[i]; + } + virtual const vector_int& products(int i) const { + return m_products[i]; + } + + /** + * Flag specifying the type of reaction. The legal values and + * their meaning are specific to the particular kinetics + * manager. + */ + virtual int reactionType(int i) const { + err("reactionType"); + return -1; + } + + /** + * @name Reaction Rates Of Progress + */ + //@{ + + /** + * Forward rates of progress. + * Return the forward rates of progress in array fwdROP, which + * must be dimensioned at least as large as the total number + * of reactions. + */ + virtual void getFwdRatesOfProgress(doublereal* fwdROP) { + err("getFwdRatesOfProgress"); + } + + /** + * Reverse rates of progress. + * Return the reverse rates of progress in array revROP, which + * must be dimensioned at least as large as the total number + * of reactions. + */ + virtual void getRevRatesOfProgress(doublereal* revROP) { + err("getRevRatesOfProgress"); + } + + /** + * Net rates of progress. Return the net (forward - reverse) + * rates of progress in array netROP, which must be + * dimensioned at least as large as the total number of + * reactions. + */ + virtual void getNetRatesOfProgress(doublereal* netROP) { + err("getNetRatesOfProgress"); + } + + /** + * True if reaction i has been declared to be reversible. If + * isReversible(i) is false, then the reverse rate of progress + * for reaction i is always zero. + */ + virtual bool isReversible(int i){return false;} + + /** + * Species creation rates [kmol/m^3]. Return the species + * creation rates in array cdot, which must be + * dimensioned at least as large as the total number of + * species. + * + */ + virtual void getCreationRates(doublereal* cdot) { + err("getCreationRates"); + } + + /** + * Species destruction rates [kmol/m^3]. Return the species + * destruction rates in array ddot, which must be + * dimensioned at least as large as the total number of + * species. + * + */ + virtual void getDestructionRates(doublereal* ddot) { + err("getDestructionRates"); + } + + /** + * Species net production rates [kmol/m^3]. Return the species + * net production rates (creation - destruction) in array + * wdot, which must be dimensioned at least as large as the + * total number of species. + */ + virtual void getNetProductionRates(doublereal* wdot) { + err("getNetProductionRates"); + } + + /** + * Equilibrium constants. Return the equilibrium constants of + * the reactions in concentration units in array kc, which + * must be dimensioned at least as large as the total number + * of reactions. + */ + virtual void getEquilibriumConstants(doublereal* kc) { + err("getEquilibriumConstants"); + } + //@} + + + /** + * @name Reaction Mechanism Construction + */ + //@{ + + + /** + * Get the nth Phase object. + */ + //phase_t& phase(int n=0) { return *m_phase[n]; } + //const phase_t& phase(int n=0) const { return *m_phase[n]; } + int nPhases() const { return m_thermo.size(); } + int phaseIndex(string ph) { return m_phaseindex[ph] - 1; } + + /** + * Add a phase. + */ + void addPhase(thermo_t& thermo) { + if (m_thermo.size() > 0) { + m_start.push_back(m_start.back() + + m_thermo.back()->nSpecies()); + } + else { + m_start.push_back(0); + } + m_thermo.push_back(&thermo); + m_phaseindex[m_thermo.back()->id()] = nPhases(); + } + thermo_t& thermo(int n=0) { return *m_thermo[n]; } + const thermo_t& thermo(int n=0) const { return *m_thermo[n]; } + thermo_t& phase(int n=0) { return *m_thermo[n]; } + const thermo_t& phase(int n=0) const { return *m_thermo[n]; } + + int speciesIndex(int k, int n) { + return m_start[n] + k; + } + + int speciesIndex(string nm, string ph = "") { + int np = m_thermo.size(); + int k; + string id; + for (int n = 0; n < np; n++) { + id = thermo(n).id(); + if (ph == id) { + k = thermo(n).speciesIndex(nm); + if (k < 0) return -1; + return k + m_start[n]; + } + else if (ph == "") { + k = thermo(n).speciesIndex(nm); + if (k >= 0) return k + m_start[n]; + } + } + return -2; + } + + /** + * Prepare to add reactions. + */ + virtual void init() {err("init");} + + /// Finished adding reactions. Prepare for use. + virtual void finalize() {err("finalize");} + + virtual void addReaction(const ReactionData& r) {err("addReaction");} + + virtual string reactionString(int i) const { + err("reactionString"); return ""; + } + + + virtual const vector& reactantGroups(int i) + { err("reactantGroups"); return m_dummygroups; } + + virtual const vector& productGroups(int i) + { err("productGroups"); return m_dummygroups; } + + /** + * @name Altering Reaction Rates + * + * These methods alter reaction rates. They are designed + * primarily for carrying out sensitivity analysis. + */ + //@{ + + /// The current value of the multiplier for reaction i. + doublereal multiplier(int i) const {return m_perturb[i];} + + /// Set the multiplier for reaction i to f. + void setMultiplier(int i, doublereal f) {m_perturb[i] = f;} + + //@} + + void incrementRxnCount() { m_ii++; m_perturb.push_back(1.0); } + + virtual bool ready() const {return false;} + + protected: + + int m_ii; + vector_fp m_perturb; + vector m_reactants; + vector m_products; + vector m_thermo; + vector_int m_start; + // XML_Node* m_xml; + map m_phaseindex; + int m_index; + + private: + + vector m_dummygroups; + void err(string m) const { + throw CanteraError("Kinetics::"+m,"Base class method called."); + } + }; + + typedef Kinetics kinetics_t; +} + + + +#endif diff --git a/include/numerics.h b/include/numerics.h new file mode 100755 index 000000000..79422ec7c --- /dev/null +++ b/include/numerics.h @@ -0,0 +1,7 @@ +#ifndef CT_NUM_H_INCL +#define CT_NUM_H_INCL + +#include "kernel/DenseMatrix.h" +#include "kernel/BandMatrix.h" + +#endif diff --git a/include/onedim.h b/include/onedim.h new file mode 100755 index 000000000..2da496a20 --- /dev/null +++ b/include/onedim.h @@ -0,0 +1,10 @@ +#ifndef CT_INCL_ONEDIM_H +#define CT_INCL_ONEDIM_H + +#include "oneD/OneDim.h" +#include "oneD/Resid1D.h" +#include "oneD/Inlet1D.h" +#include "oneD/MultiNewton.h" +#include "oneD/MultiJac.h" +#endif + diff --git a/include/surface.h b/include/surface.h new file mode 100755 index 000000000..c530b61ab --- /dev/null +++ b/include/surface.h @@ -0,0 +1,7 @@ +#ifndef CT_SURFACE_INCL +#define CT_SURFACE_INCL + +#include "SurfPhase.h" +#include "InterfaceKinetics.h" + +#endif diff --git a/include/transport.h b/include/transport.h new file mode 100755 index 000000000..d12c1f82f --- /dev/null +++ b/include/transport.h @@ -0,0 +1,5 @@ +#ifndef CT_TRANSPORT_INCL +#define CT_TRANSPORT_INCL + +#include "kernel/TransportFactory.h" +#endif diff --git a/lib/README b/lib/README new file mode 100755 index 000000000..8d1c8b69c --- /dev/null +++ b/lib/README @@ -0,0 +1 @@ + diff --git a/test_problems/.cvsignore b/test_problems/.cvsignore new file mode 100644 index 000000000..f3c7a7c5d --- /dev/null +++ b/test_problems/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/test_problems/Makefile.in b/test_problems/Makefile.in new file mode 100644 index 000000000..9367536b3 --- /dev/null +++ b/test_problems/Makefile.in @@ -0,0 +1,19 @@ +# +# $Revision$ +# $Author$ +# $Date$ +# +# +all: + cd cxx_ex; @MAKE@ all + cd silane_equil; @MAKE@ all + +test: + cd cxx_ex; @MAKE@ test + cd silane_equil; @MAKE@ test + +clean: + $(RM) *.*~ + cd cxx_ex; @MAKE@ clean + cd silane_equil; @MAKE@ clean + diff --git a/test_problems/cxx_ex/.cvsignore b/test_problems/cxx_ex/.cvsignore new file mode 100644 index 000000000..4b36763ce --- /dev/null +++ b/test_problems/cxx_ex/.cvsignore @@ -0,0 +1,26 @@ +rp1.dot +transport_log.xml +gri30mod.xml +rp1.dot +kin1_test.out +kin2_test.out +tr2_test.out +tr1_test.out +csvCode.txt +tr1.csv +tr1.dat +tr2.csv +tr2.dat +kin1.csv +kin1.dat +kin2.csv +kin2.dat +rp1.log +cxx_examples.out +eq1.csv +eq1.dat +eq1_test.out +gri30.log +gri30mod.log +silane.log +Makefile diff --git a/test_problems/cxx_ex/Makefile.in b/test_problems/cxx_ex/Makefile.in new file mode 100644 index 000000000..182c9adf7 --- /dev/null +++ b/test_problems/cxx_ex/Makefile.in @@ -0,0 +1,14 @@ +# +# $Revision$ +# $Author$ +# $Date$ +# +# +all: + +test: + ./runtest + +clean: + ../../bin/rm_cvsignore + diff --git a/test_problems/cxx_ex/eq1_blessed.csv b/test_problems/cxx_ex/eq1_blessed.csv new file mode 100644 index 000000000..2b2bc1595 --- /dev/null +++ b/test_problems/cxx_ex/eq1_blessed.csv @@ -0,0 +1,52 @@ +equilibrium example 1: chemical equilibrium, +Temperature (K),Pressure (Pa),H2,H,HE,SIH4,SI,SIH,SIH2,SIH3,H3SISIH,SI2H6,H2SISIH2,SI3H8,SI2,SI3, +500,1013.25,0.990105,6.9225e-20,0,0.00988999,2.85e-30,7.59018e-27,2.16775e-18,9.50995e-15,1.19385e-20,5.47294e-06,7.20832e-16,1.68372e-08,7.06689e-35,6.05703e-31, +550,1013.25,0.990107,8.39173e-18,0,0.00988537,2.93158e-26,1.74857e-23,4.12009e-16,3.58281e-13,2.94715e-18,7.76233e-06,6.00235e-14,3.07329e-08,7.94497e-30,1.01105e-25, +600,1013.25,0.99011,4.59846e-16,0,0.00987973,6.56406e-23,1.1196e-20,3.28532e-14,7.39942e-12,2.9573e-16,1.0551e-05,2.44419e-12,5.23844e-08,1.31738e-25,2.37085e-21, +650,1013.25,0.990113,1.36753e-14,0,0.00987304,4.53129e-20,2.66923e-18,1.34014e-12,9.61251e-11,1.4786e-14,1.38472e-05,5.71582e-11,8.43058e-08,4.97644e-22,1.21548e-17, +700,1013.25,0.990117,2.51508e-13,0,0.00986531,1.23752e-17,2.92171e-16,3.22361e-11,8.66801e-10,4.26347e-13,1.76469e-05,8.61712e-10,1.2922e-07,5.85041e-19,1.87242e-14, +750,1013.25,0.990121,3.14828e-12,0,0.00985652,1.60631e-15,1.71291e-14,5.07653e-10,5.83303e-09,7.89677e-12,2.19361e-05,9.12135e-09,1.89953e-07,2.69338e-16,1.09597e-11, +800,1013.25,0.990126,2.8822e-11,0,0.00984661,1.13756e-13,6.03964e-13,5.66211e-09,3.09314e-08,1.01907e-10,2.66926e-05,7.23036e-08,2.69321e-07,5.77313e-14,2.90994e-09, +850,1013.25,0.990133,2.03886e-10,0,0.00983381,4.88502e-12,1.39955e-11,4.75004e-08,1.34733e-07,9.75016e-10,3.18773e-05,4.50879e-07,3.69846e-07,6.57804e-12,4.01455e-07, +900,1013.25,0.990202,1.16323e-09,0,0.00972611,1.36836e-10,2.26273e-10,3.11194e-07,4.93324e-07,7.12604e-09,3.67512e-05,2.25625e-06,4.80046e-07,4.33643e-10,3.11136e-05, +950,1013.25,0.991639,5.54015e-09,0,0.00758746,2.12005e-09,2.14315e-09,1.31439e-06,1.23994e-06,2.6164e-08,2.59638e-05,5.91151e-06,2.97724e-07,1.13305e-08,0.00073897, +1000,1013.25,0.994482,2.26318e-08,0,0.00335921,1.37735e-08,8.94034e-09,2.65302e-06,1.57126e-06,2.57714e-08,5.82849e-06,4.30336e-06,3.29534e-08,6.48787e-08,0.002144, +1050,1013.25,0.995879,8.09393e-08,0,0.00128017,5.95912e-08,2.58725e-08,3.97909e-06,1.54702e-06,1.60895e-08,1.05991e-06,2.04589e-06,2.73477e-09,2.07469e-07,0.0028321, +1100,1013.25,0.9964,2.58081e-07,0,0.00050292,2.13527e-07,6.42538e-08,5.43589e-06,1.4422e-06,9.38801e-09,1.84489e-07,9.32777e-07,2.06004e-10,5.14431e-07,0.00308841, +1150,1013.25,0.996594,7.44849e-07,0,0.000211036,6.73792e-07,1.44979e-07,7.10734e-06,1.33123e-06,5.56522e-09,3.63312e-08,4.41827e-07,1.86342e-11,1.13997e-06,0.00318374, +1200,1013.25,0.996668,1.97019e-06,0,9.48056e-05,1.92164e-06,3.03874e-07,9.03543e-06,1.23092e-06,3.41459e-09,8.13761e-09,2.20875e-07,2.04041e-12,2.33627e-06,0.00322027, +1250,1013.25,0.996694,4.8262e-06,0,4.53755e-05,5.02943e-06,5.98801e-07,1.12424e-05,1.14363e-06,2.17335e-09,2.05453e-09,1.16524e-07,2.66869e-13,4.49787e-06,0.00323331, +1300,1013.25,0.996695,1.10454e-05,0,2.29939e-05,1.22122e-05,1.11842e-06,1.37394e-05,1.06817e-06,1.43185e-09,5.77841e-10,6.46007e-08,4.09675e-14,8.20997e-06,0.00323483, +1350,1013.25,0.996674,2.37957e-05,0,1.22616e-05,2.77457e-05,1.99222e-06,1.65285e-05,1.00261e-06,9.73063e-10,1.78949e-10,3.74434e-08,7.25473e-15,1.42979e-05,0.00322789, +1400,1013.25,0.996626,4.8567e-05,0,6.84153e-06,5.93904e-05,3.40084e-06,1.96017e-05,9.45013e-07,6.79523e-10,6.03614e-11,2.25707e-08,1.45826e-15,2.38664e-05,0.00321116, +1450,1013.25,0.996533,9.44319e-05,0,3.97302e-06,0.000120441,5.58475e-06,2.29368e-05,8.93513e-07,4.85642e-10,2.19531e-11,1.40746e-08,3.2774e-16,3.83073e-05,0.00318009, +1500,1013.25,0.996367,0.000175757,0,2.38908e-06,0.000232412,8.84741e-06,2.64891e-05,8.46282e-07,3.53609e-10,8.52492e-12,9.02885e-09,8.11683e-17,5.9232e-05,0.00312669, +1550,1013.25,0.996084,0.000314437,0,1.47993e-06,0.00042809,1.35456e-05,3.01791e-05,8.01401e-07,2.60927e-10,3.49981e-12,5.92151e-09,2.18277e-17,8.8254e-05,0.00303895, +1600,1013.25,0.995621,0.000542701,0,9.39194e-07,0.000754014,2.00544e-05,3.38731e-05,7.56738e-07,1.93846e-10,1.50289e-12,3.94112e-09,6.27344e-18,0.000126501,0.00290049, +1650,1013.25,0.994891,0.000906523,0,6.06771e-07,0.00127017,2.86852e-05,3.73563e-05,7.09825e-07,1.43737e-10,6.66829e-13,2.63706e-09,1.89209e-18,0.000173692,0.00269129, +1700,1013.25,0.993789,0.00146961,0,3.96005e-07,0.00204246,3.95271e-05,4.03005e-05,6.57796e-07,1.05125e-10,3.01139e-13,1.75193e-09,5.85549e-19,0.000226654,0.0023914, +1750,1013.25,0.992199,0.00231792,0,2.58509e-07,0.00312028,5.21779e-05,4.22337e-05,5.97483e-07,7.45875e-11,1.35745e-13,1.13593e-09,1.80607e-19,0.000277434,0.00198969, +1800,1013.25,0.990024,0.00356471,0,1.66601e-07,0.00449063,6.53777e-05,4.25469e-05,5.2596e-07,5.01583e-11,5.95221e-14,7.01943e-10,5.34191e-20,0.000312201,0.00150023, +1850,1013.25,0.987216,0.00535598,0,1.04289e-07,0.00601415,7.67562e-05,4.06311e-05,4.42163e-07,3.10226e-11,2.4581e-14,4.00971e-10,1.44356e-20,0.00031427,0.000981666, +1900,1013.25,0.983785,0.00787629,0,6.24504e-08,0.00740782,8.34042e-05,3.62969e-05,3.50094e-07,1.71531e-11,9.27492e-15,2.05721e-10,3.40567e-21,0.000275706,0.000534995, +1950,1013.25,0.97968,0.0113543,0,3.56863e-08,0.00839874,8.39029e-05,3.0314e-05,2.60762e-07,8.45472e-12,3.1826e-15,9.44924e-11,6.96616e-22,0.000210662,0.000242166, +2000,1013.25,0.974637,0.0160666,0,1.98026e-08,0.00894948,7.97393e-05,2.41312e-05,1.86159e-07,3.85561e-12,1.02886e-15,4.03158e-11,1.30286e-22,0.000145858,9.64624e-05, +2050,1013.25,0.968227,0.0223401,0,1.09242e-08,0.00920773,7.3503e-05,1.87805e-05,1.30569e-07,1.70924e-12,3.28618e-16,1.67825e-11,2.39341e-23,9.6403e-05,3.65063e-05, +2100,1013.25,0.959977,0.0305521,0,6.07949e-09,0.00931299,6.68668e-05,1.45271e-05,9.14042e-08,7.60319e-13,1.06849e-16,7.03384e-12,4.5181e-24,6.29445e-05,1.38006e-05, +2150,1013.25,0.949413,0.0411287,0,3.4315e-09,0.0093397,6.05128e-05,1.12483e-05,6.42802e-08,3.43859e-13,3.57725e-17,3.00664e-12,8.91836e-25,4.12399e-05,5.32852e-06, +2200,1013.25,0.93605,0.0545367,0,1.96534e-09,0.00932034,5.46385e-05,8.73688e-06,4.54802e-08,1.58626e-13,1.23517e-17,1.31476e-12,1.84583e-25,2.72685e-05,2.11718e-06, +2250,1013.25,0.919385,0.0712713,0,1.14021e-09,0.00926811,4.92608e-05,6.80727e-06,3.23523e-08,7.45671e-14,4.38689e-18,5.8744e-13,3.99132e-26,1.82243e-05,8.66774e-07, +2300,1013.25,0.898914,0.0918354,0,6.6832e-10,0.00918794,4.43389e-05,5.31511e-06,2.31e-08,3.56199e-14,1.59556e-18,2.67391e-13,8.96084e-27,1.23082e-05,3.65196e-07, +2350,1013.25,0.874155,0.116712,0,3.94536e-10,0.00908125,3.98194e-05,4.15299e-06,1.65209e-08,1.72287e-14,5.91169e-19,1.23527e-13,2.07329e-27,8.39273e-06,1.58003e-07, +2400,1013.25,0.844683,0.146324,0,2.33798e-10,0.00894803,3.56522e-05,3.24198e-06,1.18073e-08,8.40432e-15,2.21868e-19,5.76793e-14,4.90432e-28,5.77111e-06,7.00206e-08, +2450,1013.25,0.81018,0.180994,0,1.38589e-10,0.00878793,3.17959e-05,2.52406e-06,8.41161e-09,4.11761e-15,8.38512e-20,2.71055e-14,1.17629e-28,3.99688e-06,3.1702e-08, +2500,1013.25,0.770482,0.220884,0,8.18853e-11,0.00860087,2.82194e-05,1.95636e-06,5.95817e-09,2.01773e-15,3.17233e-20,1.27645e-14,2.83693e-29,2.78467e-06,1.46284e-08, +2550,1013.25,0.725639,0.265945,0,4.80534e-11,0.00838756,2.49016e-05,1.50691e-06,4.18546e-09,9.84875e-16,1.19441e-20,5.99824e-15,6.82382e-30,1.9497e-06,6.86476e-09, +2600,1013.25,0.675965,0.315861,0,2.79118e-11,0.00814983,2.18304e-05,1.15156e-06,2.90872e-09,4.77004e-16,4.45032e-21,2.80155e-15,1.62429e-30,1.37077e-06,3.27061e-09, +2650,1013.25,0.622081,0.370007,0,1.59955e-11,0.00789088,1.90008e-05,8.71768e-07,1.99532e-09,2.2845e-16,1.6325e-21,1.29595e-15,3.79894e-31,9.67332e-07,1.58016e-09, +2700,1013.25,0.564929,0.427438,0,9.01862e-12,0.00761545,1.6413e-05,6.52995e-07,1.34848e-09,1.07885e-16,5.86967e-22,5.92006e-16,8.67754e-32,6.85167e-07,7.73814e-10, +2750,1013.25,0.505754,0.486901,0,4.99175e-12,0.00732969,1.40693e-05,4.83585e-07,8.96581e-10,5.01395e-17,2.0616e-22,2.66514e-16,1.92698e-32,4.87349e-07,3.84209e-10, +2800,1013.25,0.446036,0.54691,0,2.70851e-12,0.00704088,1.19716e-05,3.53979e-07,5.86035e-10,2.29117e-17,7.059e-23,1.18127e-16,4.14907e-33,3.48454e-07,1.93632e-10, +2850,1013.25,0.387376,0.605856,0,1.44014e-12,0.00675687,1.0119e-05,2.56197e-07,3.76593e-10,1.02979e-17,2.3554e-23,5.15626e-17,8.65856e-34,2.50818e-07,9.92364e-11, +2900,1013.25,0.331344,0.662162,0,7.50923e-13,0.00648535,8.50563e-06,1.83524e-07,2.38147e-10,4.56003e-18,7.66971e-24,2.22007e-17,1.75494e-34,1.82083e-07,5.18424e-11, +2950,1013.25,0.279313,0.714446,0,3.84707e-13,0.00623307,7.11992e-06,1.30324e-07,1.48468e-10,1.9951e-18,2.44495e-24,9.45512e-18,3.47006e-35,1.33572e-07,2.76783e-11, diff --git a/test_problems/cxx_ex/eq1_blessed.dat b/test_problems/cxx_ex/eq1_blessed.dat new file mode 100644 index 000000000..753bc4f1c --- /dev/null +++ b/test_problems/cxx_ex/eq1_blessed.dat @@ -0,0 +1,71 @@ +TITLE = "equilibrium example 1: chemical equilibrium" +VARIABLES = +"Temperature (K)" +"Pressure (Pa)" +"H2" +"H" +"HE" +"SIH4" +"SI" +"SIH" +"SIH2" +"SIH3" +"H3SISIH" +"SI2H6" +"H2SISIH2" +"SI3H8" +"SI2" +"SI3" +ZONE T="zone1" + I=50,J=1,K=1,F=POINT +DT=( SINGLE SINGLE SINGLE SINGLE SINGLE SINGLE SINGLE SINGLE SINGLE SINGLE SINGLE SINGLE SINGLE SINGLE SINGLE SINGLE ) +500 1013.25 0.990105 6.9225e-20 0 0.00988999 2.85e-30 7.59018e-27 2.16775e-18 9.50995e-15 1.19385e-20 5.47294e-06 7.20832e-16 1.68372e-08 7.06689e-35 6.05703e-31 +550 1013.25 0.990107 8.39173e-18 0 0.00988537 2.93158e-26 1.74857e-23 4.12009e-16 3.58281e-13 2.94715e-18 7.76233e-06 6.00235e-14 3.07329e-08 7.94497e-30 1.01105e-25 +600 1013.25 0.99011 4.59846e-16 0 0.00987973 6.56406e-23 1.1196e-20 3.28532e-14 7.39942e-12 2.9573e-16 1.0551e-05 2.44419e-12 5.23844e-08 1.31738e-25 2.37085e-21 +650 1013.25 0.990113 1.36753e-14 0 0.00987304 4.53129e-20 2.66923e-18 1.34014e-12 9.61251e-11 1.4786e-14 1.38472e-05 5.71582e-11 8.43058e-08 4.97644e-22 1.21548e-17 +700 1013.25 0.990117 2.51508e-13 0 0.00986531 1.23752e-17 2.92171e-16 3.22361e-11 8.66801e-10 4.26347e-13 1.76469e-05 8.61712e-10 1.2922e-07 5.85041e-19 1.87242e-14 +750 1013.25 0.990121 3.14828e-12 0 0.00985652 1.60631e-15 1.71291e-14 5.07653e-10 5.83303e-09 7.89677e-12 2.19361e-05 9.12135e-09 1.89953e-07 2.69338e-16 1.09597e-11 +800 1013.25 0.990126 2.8822e-11 0 0.00984661 1.13756e-13 6.03964e-13 5.66211e-09 3.09314e-08 1.01907e-10 2.66926e-05 7.23036e-08 2.69321e-07 5.77313e-14 2.90994e-09 +850 1013.25 0.990133 2.03886e-10 0 0.00983381 4.88502e-12 1.39955e-11 4.75004e-08 1.34733e-07 9.75016e-10 3.18773e-05 4.50879e-07 3.69846e-07 6.57804e-12 4.01455e-07 +900 1013.25 0.990202 1.16323e-09 0 0.00972611 1.36836e-10 2.26273e-10 3.11194e-07 4.93324e-07 7.12604e-09 3.67512e-05 2.25625e-06 4.80046e-07 4.33643e-10 3.11136e-05 +950 1013.25 0.991639 5.54015e-09 0 0.00758746 2.12005e-09 2.14315e-09 1.31439e-06 1.23994e-06 2.6164e-08 2.59638e-05 5.91151e-06 2.97724e-07 1.13305e-08 0.00073897 +1000 1013.25 0.994482 2.26318e-08 0 0.00335921 1.37735e-08 8.94034e-09 2.65302e-06 1.57126e-06 2.57714e-08 5.82849e-06 4.30336e-06 3.29534e-08 6.48787e-08 0.002144 +1050 1013.25 0.995879 8.09393e-08 0 0.00128017 5.95912e-08 2.58725e-08 3.97909e-06 1.54702e-06 1.60895e-08 1.05991e-06 2.04589e-06 2.73477e-09 2.07469e-07 0.0028321 +1100 1013.25 0.9964 2.58081e-07 0 0.00050292 2.13527e-07 6.42538e-08 5.43589e-06 1.4422e-06 9.38801e-09 1.84489e-07 9.32777e-07 2.06004e-10 5.14431e-07 0.00308841 +1150 1013.25 0.996594 7.44849e-07 0 0.000211036 6.73792e-07 1.44979e-07 7.10734e-06 1.33123e-06 5.56522e-09 3.63312e-08 4.41827e-07 1.86342e-11 1.13997e-06 0.00318374 +1200 1013.25 0.996668 1.97019e-06 0 9.48056e-05 1.92164e-06 3.03874e-07 9.03543e-06 1.23092e-06 3.41459e-09 8.13761e-09 2.20875e-07 2.04041e-12 2.33627e-06 0.00322027 +1250 1013.25 0.996694 4.8262e-06 0 4.53755e-05 5.02943e-06 5.98801e-07 1.12424e-05 1.14363e-06 2.17335e-09 2.05453e-09 1.16524e-07 2.66869e-13 4.49787e-06 0.00323331 +1300 1013.25 0.996695 1.10454e-05 0 2.29939e-05 1.22122e-05 1.11842e-06 1.37394e-05 1.06817e-06 1.43185e-09 5.77841e-10 6.46007e-08 4.09675e-14 8.20997e-06 0.00323483 +1350 1013.25 0.996674 2.37957e-05 0 1.22616e-05 2.77457e-05 1.99222e-06 1.65285e-05 1.00261e-06 9.73063e-10 1.78949e-10 3.74434e-08 7.25473e-15 1.42979e-05 0.00322789 +1400 1013.25 0.996626 4.8567e-05 0 6.84153e-06 5.93904e-05 3.40084e-06 1.96017e-05 9.45013e-07 6.79523e-10 6.03614e-11 2.25707e-08 1.45826e-15 2.38664e-05 0.00321116 +1450 1013.25 0.996533 9.44319e-05 0 3.97302e-06 0.000120441 5.58475e-06 2.29368e-05 8.93513e-07 4.85642e-10 2.19531e-11 1.40746e-08 3.2774e-16 3.83073e-05 0.00318009 +1500 1013.25 0.996367 0.000175757 0 2.38908e-06 0.000232412 8.84741e-06 2.64891e-05 8.46282e-07 3.53609e-10 8.52492e-12 9.02885e-09 8.11683e-17 5.9232e-05 0.00312669 +1550 1013.25 0.996084 0.000314437 0 1.47993e-06 0.00042809 1.35456e-05 3.01791e-05 8.01401e-07 2.60927e-10 3.49981e-12 5.92151e-09 2.18277e-17 8.8254e-05 0.00303895 +1600 1013.25 0.995621 0.000542701 0 9.39194e-07 0.000754014 2.00544e-05 3.38731e-05 7.56738e-07 1.93846e-10 1.50289e-12 3.94112e-09 6.27344e-18 0.000126501 0.00290049 +1650 1013.25 0.994891 0.000906523 0 6.06771e-07 0.00127017 2.86852e-05 3.73563e-05 7.09825e-07 1.43737e-10 6.66829e-13 2.63706e-09 1.89209e-18 0.000173692 0.00269129 +1700 1013.25 0.993789 0.00146961 0 3.96005e-07 0.00204246 3.95271e-05 4.03005e-05 6.57796e-07 1.05125e-10 3.01139e-13 1.75193e-09 5.85549e-19 0.000226654 0.0023914 +1750 1013.25 0.992199 0.00231792 0 2.58509e-07 0.00312028 5.21779e-05 4.22337e-05 5.97483e-07 7.45875e-11 1.35745e-13 1.13593e-09 1.80607e-19 0.000277434 0.00198969 +1800 1013.25 0.990024 0.00356471 0 1.66601e-07 0.00449063 6.53777e-05 4.25469e-05 5.2596e-07 5.01583e-11 5.95221e-14 7.01943e-10 5.34191e-20 0.000312201 0.00150023 +1850 1013.25 0.987216 0.00535598 0 1.04289e-07 0.00601415 7.67562e-05 4.06311e-05 4.42163e-07 3.10226e-11 2.4581e-14 4.00971e-10 1.44356e-20 0.00031427 0.000981666 +1900 1013.25 0.983785 0.00787629 0 6.24504e-08 0.00740782 8.34042e-05 3.62969e-05 3.50094e-07 1.71531e-11 9.27492e-15 2.05721e-10 3.40567e-21 0.000275706 0.000534995 +1950 1013.25 0.97968 0.0113543 0 3.56863e-08 0.00839874 8.39029e-05 3.0314e-05 2.60762e-07 8.45472e-12 3.1826e-15 9.44924e-11 6.96616e-22 0.000210662 0.000242166 +2000 1013.25 0.974637 0.0160666 0 1.98026e-08 0.00894948 7.97393e-05 2.41312e-05 1.86159e-07 3.85561e-12 1.02886e-15 4.03158e-11 1.30286e-22 0.000145858 9.64624e-05 +2050 1013.25 0.968227 0.0223401 0 1.09242e-08 0.00920773 7.3503e-05 1.87805e-05 1.30569e-07 1.70924e-12 3.28618e-16 1.67825e-11 2.39341e-23 9.6403e-05 3.65063e-05 +2100 1013.25 0.959977 0.0305521 0 6.07949e-09 0.00931299 6.68668e-05 1.45271e-05 9.14042e-08 7.60319e-13 1.06849e-16 7.03384e-12 4.5181e-24 6.29445e-05 1.38006e-05 +2150 1013.25 0.949413 0.0411287 0 3.4315e-09 0.0093397 6.05128e-05 1.12483e-05 6.42802e-08 3.43859e-13 3.57725e-17 3.00664e-12 8.91836e-25 4.12399e-05 5.32852e-06 +2200 1013.25 0.93605 0.0545367 0 1.96534e-09 0.00932034 5.46385e-05 8.73688e-06 4.54802e-08 1.58626e-13 1.23517e-17 1.31476e-12 1.84583e-25 2.72685e-05 2.11718e-06 +2250 1013.25 0.919385 0.0712713 0 1.14021e-09 0.00926811 4.92608e-05 6.80727e-06 3.23523e-08 7.45671e-14 4.38689e-18 5.8744e-13 3.99132e-26 1.82243e-05 8.66774e-07 +2300 1013.25 0.898914 0.0918354 0 6.6832e-10 0.00918794 4.43389e-05 5.31511e-06 2.31e-08 3.56199e-14 1.59556e-18 2.67391e-13 8.96084e-27 1.23082e-05 3.65196e-07 +2350 1013.25 0.874155 0.116712 0 3.94536e-10 0.00908125 3.98194e-05 4.15299e-06 1.65209e-08 1.72287e-14 5.91169e-19 1.23527e-13 2.07329e-27 8.39273e-06 1.58003e-07 +2400 1013.25 0.844683 0.146324 0 2.33798e-10 0.00894803 3.56522e-05 3.24198e-06 1.18073e-08 8.40432e-15 2.21868e-19 5.76793e-14 4.90432e-28 5.77111e-06 7.00206e-08 +2450 1013.25 0.81018 0.180994 0 1.38589e-10 0.00878793 3.17959e-05 2.52406e-06 8.41161e-09 4.11761e-15 8.38512e-20 2.71055e-14 1.17629e-28 3.99688e-06 3.1702e-08 +2500 1013.25 0.770482 0.220884 0 8.18853e-11 0.00860087 2.82194e-05 1.95636e-06 5.95817e-09 2.01773e-15 3.17233e-20 1.27645e-14 2.83693e-29 2.78467e-06 1.46284e-08 +2550 1013.25 0.725639 0.265945 0 4.80534e-11 0.00838756 2.49016e-05 1.50691e-06 4.18546e-09 9.84875e-16 1.19441e-20 5.99824e-15 6.82382e-30 1.9497e-06 6.86476e-09 +2600 1013.25 0.675965 0.315861 0 2.79118e-11 0.00814983 2.18304e-05 1.15156e-06 2.90872e-09 4.77004e-16 4.45032e-21 2.80155e-15 1.62429e-30 1.37077e-06 3.27061e-09 +2650 1013.25 0.622081 0.370007 0 1.59955e-11 0.00789088 1.90008e-05 8.71768e-07 1.99532e-09 2.2845e-16 1.6325e-21 1.29595e-15 3.79894e-31 9.67332e-07 1.58016e-09 +2700 1013.25 0.564929 0.427438 0 9.01862e-12 0.00761545 1.6413e-05 6.52995e-07 1.34848e-09 1.07885e-16 5.86967e-22 5.92006e-16 8.67754e-32 6.85167e-07 7.73814e-10 +2750 1013.25 0.505754 0.486901 0 4.99175e-12 0.00732969 1.40693e-05 4.83585e-07 8.96581e-10 5.01395e-17 2.0616e-22 2.66514e-16 1.92698e-32 4.87349e-07 3.84209e-10 +2800 1013.25 0.446036 0.54691 0 2.70851e-12 0.00704088 1.19716e-05 3.53979e-07 5.86035e-10 2.29117e-17 7.059e-23 1.18127e-16 4.14907e-33 3.48454e-07 1.93632e-10 +2850 1013.25 0.387376 0.605856 0 1.44014e-12 0.00675687 1.0119e-05 2.56197e-07 3.76593e-10 1.02979e-17 2.3554e-23 5.15626e-17 8.65856e-34 2.50818e-07 9.92364e-11 +2900 1013.25 0.331344 0.662162 0 7.50923e-13 0.00648535 8.50563e-06 1.83524e-07 2.38147e-10 4.56003e-18 7.66971e-24 2.22007e-17 1.75494e-34 1.82083e-07 5.18424e-11 +2950 1013.25 0.279313 0.714446 0 3.84707e-13 0.00623307 7.11992e-06 1.30324e-07 1.48468e-10 1.9951e-18 2.44495e-24 9.45512e-18 3.47006e-35 1.33572e-07 2.76783e-11 diff --git a/test_problems/cxx_ex/gri30.inp b/test_problems/cxx_ex/gri30.inp new file mode 100644 index 000000000..11f4ab71b --- /dev/null +++ b/test_problems/cxx_ex/gri30.inp @@ -0,0 +1,661 @@ +! GRI-Mech Version 3.0 3/12/99 CHEMKIN-II format +! See README30 file at anonymous FTP site unix.sri.com, directory gri; +! WorldWideWeb home page http://www.me.berkeley.edu/gri_mech/ or +! through http://www.gri.org , under 'Basic Research', +! for additional information, contacts, and disclaimer +ELEMENTS +O H C N AR +END +SPECIES +H2 H O O2 OH H2O HO2 H2O2 +C CH CH2 CH2(S) CH3 CH4 CO CO2 +HCO CH2O CH2OH CH3O CH3OH C2H C2H2 C2H3 +C2H4 C2H5 C2H6 HCCO CH2CO HCCOH N NH +NH2 NH3 NNH NO NO2 N2O HNO CN +HCN H2CN HCNN HCNO HOCN HNCO NCO N2 +AR C3H7 C3H8 CH2CHO CH3CHO +END +THERMO ALL + 300.000 1000.000 5000.000 +O L 1/90O 1 00 00 00G 200.000 3500.000 1000.000 1 + 2.56942078E+00-8.59741137E-05 4.19484589E-08-1.00177799E-11 1.22833691E-15 2 + 2.92175791E+04 4.78433864E+00 3.16826710E+00-3.27931884E-03 6.64306396E-06 3 +-6.12806624E-09 2.11265971E-12 2.91222592E+04 2.05193346E+00 4 +O2 TPIS89O 2 00 00 00G 200.000 3500.000 1000.000 1 + 3.28253784E+00 1.48308754E-03-7.57966669E-07 2.09470555E-10-2.16717794E-14 2 +-1.08845772E+03 5.45323129E+00 3.78245636E+00-2.99673416E-03 9.84730201E-06 3 +-9.68129509E-09 3.24372837E-12-1.06394356E+03 3.65767573E+00 4 +H L 7/88H 1 00 00 00G 200.000 3500.000 1000.000 1 + 2.50000001E+00-2.30842973E-11 1.61561948E-14-4.73515235E-18 4.98197357E-22 2 + 2.54736599E+04-4.46682914E-01 2.50000000E+00 7.05332819E-13-1.99591964E-15 3 + 2.30081632E-18-9.27732332E-22 2.54736599E+04-4.46682853E-01 4 +H2 TPIS78H 2 00 00 00G 200.000 3500.000 1000.000 1 + 3.33727920E+00-4.94024731E-05 4.99456778E-07-1.79566394E-10 2.00255376E-14 2 +-9.50158922E+02-3.20502331E+00 2.34433112E+00 7.98052075E-03-1.94781510E-05 3 + 2.01572094E-08-7.37611761E-12-9.17935173E+02 6.83010238E-01 4 +OH RUS 78O 1H 1 00 00G 200.000 3500.000 1000.000 1 + 3.09288767E+00 5.48429716E-04 1.26505228E-07-8.79461556E-11 1.17412376E-14 2 + 3.85865700E+03 4.47669610E+00 3.99201543E+00-2.40131752E-03 4.61793841E-06 3 +-3.88113333E-09 1.36411470E-12 3.61508056E+03-1.03925458E-01 4 +H2O L 8/89H 2O 1 00 00G 200.000 3500.000 1000.000 1 + 3.03399249E+00 2.17691804E-03-1.64072518E-07-9.70419870E-11 1.68200992E-14 2 +-3.00042971E+04 4.96677010E+00 4.19864056E+00-2.03643410E-03 6.52040211E-06 3 +-5.48797062E-09 1.77197817E-12-3.02937267E+04-8.49032208E-01 4 +HO2 L 5/89H 1O 2 00 00G 200.000 3500.000 1000.000 1 + 4.01721090E+00 2.23982013E-03-6.33658150E-07 1.14246370E-10-1.07908535E-14 2 + 1.11856713E+02 3.78510215E+00 4.30179801E+00-4.74912051E-03 2.11582891E-05 3 +-2.42763894E-08 9.29225124E-12 2.94808040E+02 3.71666245E+00 4 +H2O2 L 7/88H 2O 2 00 00G 200.000 3500.000 1000.000 1 + 4.16500285E+00 4.90831694E-03-1.90139225E-06 3.71185986E-10-2.87908305E-14 2 +-1.78617877E+04 2.91615662E+00 4.27611269E+00-5.42822417E-04 1.67335701E-05 3 +-2.15770813E-08 8.62454363E-12-1.77025821E+04 3.43505074E+00 4 +C L11/88C 1 00 00 00G 200.000 3500.000 1000.000 1 + 2.49266888E+00 4.79889284E-05-7.24335020E-08 3.74291029E-11-4.87277893E-15 2 + 8.54512953E+04 4.80150373E+00 2.55423955E+00-3.21537724E-04 7.33792245E-07 3 +-7.32234889E-10 2.66521446E-13 8.54438832E+04 4.53130848E+00 4 +CH TPIS79C 1H 1 00 00G 200.000 3500.000 1000.000 1 + 2.87846473E+00 9.70913681E-04 1.44445655E-07-1.30687849E-10 1.76079383E-14 2 + 7.10124364E+04 5.48497999E+00 3.48981665E+00 3.23835541E-04-1.68899065E-06 3 + 3.16217327E-09-1.40609067E-12 7.07972934E+04 2.08401108E+00 4 +CH2 L S/93C 1H 2 00 00G 200.000 3500.000 1000.000 1 + 2.87410113E+00 3.65639292E-03-1.40894597E-06 2.60179549E-10-1.87727567E-14 2 + 4.62636040E+04 6.17119324E+00 3.76267867E+00 9.68872143E-04 2.79489841E-06 3 +-3.85091153E-09 1.68741719E-12 4.60040401E+04 1.56253185E+00 4 +CH2(S) L S/93C 1H 2 00 00G 200.000 3500.000 1000.000 1 + 2.29203842E+00 4.65588637E-03-2.01191947E-06 4.17906000E-10-3.39716365E-14 2 + 5.09259997E+04 8.62650169E+00 4.19860411E+00-2.36661419E-03 8.23296220E-06 3 +-6.68815981E-09 1.94314737E-12 5.04968163E+04-7.69118967E-01 4 +CH3 L11/89C 1H 3 00 00G 200.000 3500.000 1000.000 1 + 2.28571772E+00 7.23990037E-03-2.98714348E-06 5.95684644E-10-4.67154394E-14 2 + 1.67755843E+04 8.48007179E+00 3.67359040E+00 2.01095175E-03 5.73021856E-06 3 +-6.87117425E-09 2.54385734E-12 1.64449988E+04 1.60456433E+00 4 +CH4 L 8/88C 1H 4 00 00G 200.000 3500.000 1000.000 1 + 7.48514950E-02 1.33909467E-02-5.73285809E-06 1.22292535E-09-1.01815230E-13 2 +-9.46834459E+03 1.84373180E+01 5.14987613E+00-1.36709788E-02 4.91800599E-05 3 +-4.84743026E-08 1.66693956E-11-1.02466476E+04-4.64130376E+00 4 +CO TPIS79C 1O 1 00 00G 200.000 3500.000 1000.000 1 + 2.71518561E+00 2.06252743E-03-9.98825771E-07 2.30053008E-10-2.03647716E-14 2 +-1.41518724E+04 7.81868772E+00 3.57953347E+00-6.10353680E-04 1.01681433E-06 3 + 9.07005884E-10-9.04424499E-13-1.43440860E+04 3.50840928E+00 4 +CO2 L 7/88C 1O 2 00 00G 200.000 3500.000 1000.000 1 + 3.85746029E+00 4.41437026E-03-2.21481404E-06 5.23490188E-10-4.72084164E-14 2 +-4.87591660E+04 2.27163806E+00 2.35677352E+00 8.98459677E-03-7.12356269E-06 3 + 2.45919022E-09-1.43699548E-13-4.83719697E+04 9.90105222E+00 4 +HCO L12/89H 1C 1O 1 00G 200.000 3500.000 1000.000 1 + 2.77217438E+00 4.95695526E-03-2.48445613E-06 5.89161778E-10-5.33508711E-14 2 + 4.01191815E+03 9.79834492E+00 4.22118584E+00-3.24392532E-03 1.37799446E-05 3 +-1.33144093E-08 4.33768865E-12 3.83956496E+03 3.39437243E+00 4 +CH2O L 8/88H 2C 1O 1 00G 200.000 3500.000 1000.000 1 + 1.76069008E+00 9.20000082E-03-4.42258813E-06 1.00641212E-09-8.83855640E-14 2 +-1.39958323E+04 1.36563230E+01 4.79372315E+00-9.90833369E-03 3.73220008E-05 3 +-3.79285261E-08 1.31772652E-11-1.43089567E+04 6.02812900E-01 4 +CH2OH GUNL93C 1H 3O 1 00G 200.000 3500.000 1000.000 1 + 3.69266569E+00 8.64576797E-03-3.75101120E-06 7.87234636E-10-6.48554201E-14 2 +-3.24250627E+03 5.81043215E+00 3.86388918E+00 5.59672304E-03 5.93271791E-06 3 +-1.04532012E-08 4.36967278E-12-3.19391367E+03 5.47302243E+00 4 +CH3O 121686C 1H 3O 1 G 0300.00 3000.00 1000.000 1 + 0.03770799E+02 0.07871497E-01-0.02656384E-04 0.03944431E-08-0.02112616E-12 2 + 0.12783252E+03 0.02929575E+02 0.02106204E+02 0.07216595E-01 0.05338472E-04 3 +-0.07377636E-07 0.02075610E-10 0.09786011E+04 0.13152177E+02 4 +CH3OH L 8/88C 1H 4O 1 00G 200.000 3500.000 1000.000 1 + 1.78970791E+00 1.40938292E-02-6.36500835E-06 1.38171085E-09-1.17060220E-13 2 +-2.53748747E+04 1.45023623E+01 5.71539582E+00-1.52309129E-02 6.52441155E-05 3 +-7.10806889E-08 2.61352698E-11-2.56427656E+04-1.50409823E+00 4 +C2H L 1/91C 2H 1 00 00G 200.000 3500.000 1000.000 1 + 3.16780652E+00 4.75221902E-03-1.83787077E-06 3.04190252E-10-1.77232770E-14 2 + 6.71210650E+04 6.63589475E+00 2.88965733E+00 1.34099611E-02-2.84769501E-05 3 + 2.94791045E-08-1.09331511E-11 6.68393932E+04 6.22296438E+00 4 +C2H2 L 1/91C 2H 2 00 00G 200.000 3500.000 1000.000 1 + 4.14756964E+00 5.96166664E-03-2.37294852E-06 4.67412171E-10-3.61235213E-14 2 + 2.59359992E+04-1.23028121E+00 8.08681094E-01 2.33615629E-02-3.55171815E-05 3 + 2.80152437E-08-8.50072974E-12 2.64289807E+04 1.39397051E+01 4 +C2H3 L 2/92C 2H 3 00 00G 200.000 3500.000 1000.000 1 + 3.01672400E+00 1.03302292E-02-4.68082349E-06 1.01763288E-09-8.62607041E-14 2 + 3.46128739E+04 7.78732378E+00 3.21246645E+00 1.51479162E-03 2.59209412E-05 3 +-3.57657847E-08 1.47150873E-11 3.48598468E+04 8.51054025E+00 4 +C2H4 L 1/91C 2H 4 00 00G 200.000 3500.000 1000.000 1 + 2.03611116E+00 1.46454151E-02-6.71077915E-06 1.47222923E-09-1.25706061E-13 2 + 4.93988614E+03 1.03053693E+01 3.95920148E+00-7.57052247E-03 5.70990292E-05 3 +-6.91588753E-08 2.69884373E-11 5.08977593E+03 4.09733096E+00 4 +C2H5 L12/92C 2H 5 00 00G 200.000 3500.000 1000.000 1 + 1.95465642E+00 1.73972722E-02-7.98206668E-06 1.75217689E-09-1.49641576E-13 2 + 1.28575200E+04 1.34624343E+01 4.30646568E+00-4.18658892E-03 4.97142807E-05 3 +-5.99126606E-08 2.30509004E-11 1.28416265E+04 4.70720924E+00 4 +C2H6 L 8/88C 2H 6 00 00G 200.000 3500.000 1000.000 1 + 1.07188150E+00 2.16852677E-02-1.00256067E-05 2.21412001E-09-1.90002890E-13 2 +-1.14263932E+04 1.51156107E+01 4.29142492E+00-5.50154270E-03 5.99438288E-05 3 +-7.08466285E-08 2.68685771E-11-1.15222055E+04 2.66682316E+00 4 +CH2CO L 5/90C 2H 2O 1 00G 200.000 3500.000 1000.000 1 + 4.51129732E+00 9.00359745E-03-4.16939635E-06 9.23345882E-10-7.94838201E-14 2 +-7.55105311E+03 6.32247205E-01 2.13583630E+00 1.81188721E-02-1.73947474E-05 3 + 9.34397568E-09-2.01457615E-12-7.04291804E+03 1.22156480E+01 4 +HCCO SRIC91H 1C 2O 1 G 0300.00 4000.00 1000.000 1 + 0.56282058E+01 0.40853401E-02-0.15934547E-05 0.28626052E-09-0.19407832E-13 2 + 0.19327215E+05-0.39302595E+01 0.22517214E+01 0.17655021E-01-0.23729101E-04 3 + 0.17275759E-07-0.50664811E-11 0.20059449E+05 0.12490417E+02 4 +HCCOH SRI91C 2O 1H 20 0G 300.000 5000.000 1000.000 1 + 0.59238291E+01 0.67923600E-02-0.25658564E-05 0.44987841E-09-0.29940101E-13 2 + 0.72646260E+04-0.76017742E+01 0.12423733E+01 0.31072201E-01-0.50866864E-04 3 + 0.43137131E-07-0.14014594E-10 0.80316143E+04 0.13874319E+02 4 +H2CN 41687H 2C 1N 1 G 0300.00 4000.000 1000.000 1 + 0.52097030E+01 0.29692911E-02-0.28555891E-06-0.16355500E-09 0.30432589E-13 2 + 0.27677109E+05-0.44444780E+01 0.28516610E+01 0.56952331E-02 0.10711400E-05 3 +-0.16226120E-08-0.23511081E-12 0.28637820E+05 0.89927511E+01 4 +HCN GRI/98H 1C 1N 1 0G 200.000 6000.000 1000.000 1 + 0.38022392E+01 0.31464228E-02-0.10632185E-05 0.16619757E-09-0.97997570E-14 2 + 0.14407292E+05 0.15754601E+01 0.22589886E+01 0.10051170E-01-0.13351763E-04 3 + 0.10092349E-07-0.30089028E-11 0.14712633E+05 0.89164419E+01 4 +HNO And93 H 1N 1O 1 0G 200.000 6000.000 1000.000 1 + 0.29792509E+01 0.34944059E-02-0.78549778E-06 0.57479594E-10-0.19335916E-15 2 + 0.11750582E+05 0.86063728E+01 0.45334916E+01-0.56696171E-02 0.18473207E-04 3 +-0.17137094E-07 0.55454573E-11 0.11548297E+05 0.17498417E+01 4 +N L 6/88N 1 0 0 0G 200.000 6000.000 1000.000 1 + 0.24159429E+01 0.17489065E-03-0.11902369E-06 0.30226245E-10-0.20360982E-14 2 + 0.56133773E+05 0.46496096E+01 0.25000000E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.56104637E+05 0.41939087E+01 4 +NNH T07/93N 2H 1 00 00G 200.000 6000.000 1000.000 1 + 0.37667544E+01 0.28915082E-02-0.10416620E-05 0.16842594E-09-0.10091896E-13 2 + 0.28650697E+05 0.44705067E+01 0.43446927E+01-0.48497072E-02 0.20059459E-04 3 +-0.21726464E-07 0.79469539E-11 0.28791973E+05 0.29779410E+01 4 +N2O L 7/88N 2O 1 0 0G 200.000 6000.000 1000.000 1 + 0.48230729E+01 0.26270251E-02-0.95850874E-06 0.16000712E-09-0.97752303E-14 2 + 0.80734048E+04-0.22017207E+01 0.22571502E+01 0.11304728E-01-0.13671319E-04 3 + 0.96819806E-08-0.29307182E-11 0.87417744E+04 0.10757992E+02 4 +NH And94 N 1H 1 0 0G 200.000 6000.000 1000.000 1 + 0.27836928E+01 0.13298430E-02-0.42478047E-06 0.78348501E-10-0.55044470E-14 2 + 0.42120848E+05 0.57407799E+01 0.34929085E+01 0.31179198E-03-0.14890484E-05 3 + 0.24816442E-08-0.10356967E-11 0.41880629E+05 0.18483278E+01 4 +NH2 And89 N 1H 2 0 0G 200.000 6000.000 1000.000 1 + 0.28347421E+01 0.32073082E-02-0.93390804E-06 0.13702953E-09-0.79206144E-14 2 + 0.22171957E+05 0.65204163E+01 0.42040029E+01-0.21061385E-02 0.71068348E-05 3 +-0.56115197E-08 0.16440717E-11 0.21885910E+05-0.14184248E+00 4 +NH3 J 6/77N 1H 3 0 0G 200.000 6000.000 1000.000 1 + 0.26344521E+01 0.56662560E-02-0.17278676E-05 0.23867161E-09-0.12578786E-13 2 +-0.65446958E+04 0.65662928E+01 0.42860274E+01-0.46605230E-02 0.21718513E-04 3 +-0.22808887E-07 0.82638046E-11-0.67417285E+04-0.62537277E+00 4 +NO RUS 78N 1O 1 0 0G 200.000 6000.000 1000.000 1 + 0.32606056E+01 0.11911043E-02-0.42917048E-06 0.69457669E-10-0.40336099E-14 2 + 0.99209746E+04 0.63693027E+01 0.42184763E+01-0.46389760E-02 0.11041022E-04 3 +-0.93361354E-08 0.28035770E-11 0.98446230E+04 0.22808464E+01 4 +NO2 L 7/88N 1O 2 0 0G 200.000 6000.000 1000.000 1 + 0.48847542E+01 0.21723956E-02-0.82806906E-06 0.15747510E-09-0.10510895E-13 2 + 0.23164983E+04-0.11741695E+00 0.39440312E+01-0.15854290E-02 0.16657812E-04 3 +-0.20475426E-07 0.78350564E-11 0.28966179E+04 0.63119917E+01 4 +HCNO BDEA94H 1N 1C 1O 1G 300.000 5000.000 1382.000 1 + 6.59860456E+00 3.02778626E-03-1.07704346E-06 1.71666528E-10-1.01439391E-14 2 + 1.79661339E+04-1.03306599E+01 2.64727989E+00 1.27505342E-02-1.04794236E-05 3 + 4.41432836E-09-7.57521466E-13 1.92990252E+04 1.07332972E+01 4 +HOCN BDEA94H 1N 1C 1O 1G 300.000 5000.000 1368.000 1 + 5.89784885E+00 3.16789393E-03-1.11801064E-06 1.77243144E-10-1.04339177E-14 2 +-3.70653331E+03-6.18167825E+00 3.78604952E+00 6.88667922E-03-3.21487864E-06 3 + 5.17195767E-10 1.19360788E-14-2.82698400E+03 5.63292162E+00 4 +HNCO BDEA94H 1N 1C 1O 1G 300.000 5000.000 1478.000 1 + 6.22395134E+00 3.17864004E-03-1.09378755E-06 1.70735163E-10-9.95021955E-15 2 +-1.66599344E+04-8.38224741E+00 3.63096317E+00 7.30282357E-03-2.28050003E-06 3 +-6.61271298E-10 3.62235752E-13-1.55873636E+04 6.19457727E+00 4 +NCO EA 93 N 1C 1O 1 0G 200.000 6000.000 1000.000 1 + 0.51521845E+01 0.23051761E-02-0.88033153E-06 0.14789098E-09-0.90977996E-14 2 + 0.14004123E+05-0.25442660E+01 0.28269308E+01 0.88051688E-02-0.83866134E-05 3 + 0.48016964E-08-0.13313595E-11 0.14682477E+05 0.95504646E+01 4 +CN HBH92 C 1N 1 0 0G 200.000 6000.000 1000.000 1 + 0.37459805E+01 0.43450775E-04 0.29705984E-06-0.68651806E-10 0.44134173E-14 2 + 0.51536188E+05 0.27867601E+01 0.36129351E+01-0.95551327E-03 0.21442977E-05 3 +-0.31516323E-09-0.46430356E-12 0.51708340E+05 0.39804995E+01 4 +HCNN SRI/94C 1N 2H 10 0G 300.000 5000.000 1000.000 1 + 0.58946362E+01 0.39895959E-02-0.15982380E-05 0.29249395E-09-0.20094686E-13 2 + 0.53452941E+05-0.51030502E+01 0.25243194E+01 0.15960619E-01-0.18816354E-04 3 + 0.12125540E-07-0.32357378E-11 0.54261984E+05 0.11675870E+02 4 +N2 121286N 2 G 300.000 5000.000 1000.000 1 + 0.02926640E+02 0.14879768E-02-0.05684760E-05 0.10097038E-09-0.06753351E-13 2 +-0.09227977E+04 0.05980528E+02 0.03298677E+02 0.14082404E-02-0.03963222E-04 3 + 0.05641515E-07-0.02444854E-10-0.10208999E+04 0.03950372E+02 4 +AR 120186AR 1 G 300.000 5000.000 1000.000 1 + 0.02500000E+02 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-0.07453750E+04 0.04366000E+02 0.02500000E+02 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-0.07453750E+04 0.04366000E+02 4 +C3H8 L 4/85C 3H 8 0 0G 300.000 5000.000 1000.00 1 + 0.75341368E+01 0.18872239E-01-0.62718491E-05 0.91475649E-09-0.47838069E-13 2 +-0.16467516E+05-0.17892349E+02 0.93355381E+00 0.26424579E-01 0.61059727E-05 3 +-0.21977499E-07 0.95149253E-11-0.13958520E+05 0.19201691E+02 4 +C3H7 L 9/84C 3H 7 0 0G 300.000 5000.000 1000.00 1 + 0.77026987E+01 0.16044203E-01-0.52833220E-05 0.76298590E-09-0.39392284E-13 2 + 0.82984336E+04-0.15480180E+02 0.10515518E+01 0.25991980E-01 0.23800540E-05 3 +-0.19609569E-07 0.93732470E-11 0.10631863E+05 0.21122559E+02 4 +CH3CHO L 8/88C 2H 4O 1 0G 200.000 6000.000 1000.00 1 + 0.54041108E+01 0.11723059E-01-0.42263137E-05 0.68372451E-09-0.40984863E-13 2 +-0.22593122E+05-0.34807917E+01 0.47294595E+01-0.31932858E-02 0.47534921E-04 3 +-0.57458611E-07 0.21931112E-10-0.21572878E+05 0.41030159E+01 4 +CH2CHO SAND86O 1H 3C 2 G 300.00 5000.00 1000.00 1 + 0.05975670E+02 0.08130591E-01-0.02743624E-04 0.04070304E-08-0.02176017E-12 2 + 0.04903218E+04-0.05045251E+02 0.03409062E+02 0.10738574E-01 0.01891492E-04 3 +-0.07158583E-07 0.02867385E-10 0.15214766E+04 0.09558290E+02 4 +END +REACTIONS +2O+M<=>O2+M 1.200E+17 -1.000 .00 +H2/ 2.40/ H2O/15.40/ CH4/ 2.00/ CO/ 1.75/ CO2/ 3.60/ C2H6/ 3.00/ AR/ .83/ +O+H+M<=>OH+M 5.000E+17 -1.000 .00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +O+H2<=>H+OH 3.870E+04 2.700 6260.00 +O+HO2<=>OH+O2 2.000E+13 .000 .00 +O+H2O2<=>OH+HO2 9.630E+06 2.000 4000.00 +O+CH<=>H+CO 5.700E+13 .000 .00 +O+CH2<=>H+HCO 8.000E+13 .000 .00 +O+CH2(S)<=>H2+CO 1.500E+13 .000 .00 +O+CH2(S)<=>H+HCO 1.500E+13 .000 .00 +O+CH3<=>H+CH2O 5.060E+13 .000 .00 +O+CH4<=>OH+CH3 1.020E+09 1.500 8600.00 +O+CO(+M)<=>CO2(+M) 1.800E+10 .000 2385.00 + LOW/ 6.020E+14 .000 3000.00/ +H2/2.00/ O2/6.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/3.50/ C2H6/3.00/ AR/ .50/ +O+HCO<=>OH+CO 3.000E+13 .000 .00 +O+HCO<=>H+CO2 3.000E+13 .000 .00 +O+CH2O<=>OH+HCO 3.900E+13 .000 3540.00 +O+CH2OH<=>OH+CH2O 1.000E+13 .000 .00 +O+CH3O<=>OH+CH2O 1.000E+13 .000 .00 +O+CH3OH<=>OH+CH2OH 3.880E+05 2.500 3100.00 +O+CH3OH<=>OH+CH3O 1.300E+05 2.500 5000.00 +O+C2H<=>CH+CO 5.000E+13 .000 .00 +O+C2H2<=>H+HCCO 1.350E+07 2.000 1900.00 +O+C2H2<=>OH+C2H 4.600E+19 -1.410 28950.00 +O+C2H2<=>CO+CH2 6.940E+06 2.000 1900.00 +O+C2H3<=>H+CH2CO 3.000E+13 .000 .00 +O+C2H4<=>CH3+HCO 1.250E+07 1.830 220.00 +O+C2H5<=>CH3+CH2O 2.240E+13 .000 .00 +O+C2H6<=>OH+C2H5 8.980E+07 1.920 5690.00 +O+HCCO<=>H+2CO 1.000E+14 .000 .00 +O+CH2CO<=>OH+HCCO 1.000E+13 .000 8000.00 +O+CH2CO<=>CH2+CO2 1.750E+12 .000 1350.00 +O2+CO<=>O+CO2 2.500E+12 .000 47800.00 +O2+CH2O<=>HO2+HCO 1.000E+14 .000 40000.00 +H+O2+M<=>HO2+M 2.800E+18 -.860 .00 +O2/ .00/ H2O/ .00/ CO/ .75/ CO2/1.50/ C2H6/1.50/ N2/ .00/ AR/ .00/ +H+2O2<=>HO2+O2 2.080E+19 -1.240 .00 +H+O2+H2O<=>HO2+H2O 11.26E+18 -.760 .00 +H+O2+N2<=>HO2+N2 2.600E+19 -1.240 .00 +H+O2+AR<=>HO2+AR 7.000E+17 -.800 .00 +H+O2<=>O+OH 2.650E+16 -.6707 17041.00 +2H+M<=>H2+M 1.000E+18 -1.000 .00 +H2/ .00/ H2O/ .00/ CH4/2.00/ CO2/ .00/ C2H6/3.00/ AR/ .63/ +2H+H2<=>2H2 9.000E+16 -.600 .00 +2H+H2O<=>H2+H2O 6.000E+19 -1.250 .00 +2H+CO2<=>H2+CO2 5.500E+20 -2.000 .00 +H+OH+M<=>H2O+M 2.200E+22 -2.000 .00 +H2/ .73/ H2O/3.65/ CH4/2.00/ C2H6/3.00/ AR/ .38/ +H+HO2<=>O+H2O 3.970E+12 .000 671.00 +H+HO2<=>O2+H2 4.480E+13 .000 1068.00 +H+HO2<=>2OH 0.840E+14 .000 635.00 +H+H2O2<=>HO2+H2 1.210E+07 2.000 5200.00 +H+H2O2<=>OH+H2O 1.000E+13 .000 3600.00 +H+CH<=>C+H2 1.650E+14 .000 .00 +H+CH2(+M)<=>CH3(+M) 6.000E+14 .000 .00 + LOW / 1.040E+26 -2.760 1600.00/ + TROE/ .5620 91.00 5836.00 8552.00/ +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+CH2(S)<=>CH+H2 3.000E+13 .000 .00 +H+CH3(+M)<=>CH4(+M) 13.90E+15 -.534 536.00 + LOW / 2.620E+33 -4.760 2440.00/ + TROE/ .7830 74.00 2941.00 6964.00 / +H2/2.00/ H2O/6.00/ CH4/3.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+CH4<=>CH3+H2 6.600E+08 1.620 10840.00 +H+HCO(+M)<=>CH2O(+M) 1.090E+12 .480 -260.00 + LOW / 2.470E+24 -2.570 425.00/ + TROE/ .7824 271.00 2755.00 6570.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+HCO<=>H2+CO 7.340E+13 .000 .00 +H+CH2O(+M)<=>CH2OH(+M) 5.400E+11 .454 3600.00 + LOW / 1.270E+32 -4.820 6530.00/ + TROE/ .7187 103.00 1291.00 4160.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +H+CH2O(+M)<=>CH3O(+M) 5.400E+11 .454 2600.00 + LOW / 2.200E+30 -4.800 5560.00/ + TROE/ .7580 94.00 1555.00 4200.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +H+CH2O<=>HCO+H2 5.740E+07 1.900 2742.00 +H+CH2OH(+M)<=>CH3OH(+M) 1.055E+12 .500 86.00 + LOW / 4.360E+31 -4.650 5080.00/ + TROE/ .600 100.00 90000.0 10000.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +H+CH2OH<=>H2+CH2O 2.000E+13 .000 .00 +H+CH2OH<=>OH+CH3 1.650E+11 .650 -284.00 +H+CH2OH<=>CH2(S)+H2O 3.280E+13 -.090 610.00 +H+CH3O(+M)<=>CH3OH(+M) 2.430E+12 .515 50.00 + LOW / 4.660E+41 -7.440 14080.0/ + TROE/ .700 100.00 90000.0 10000.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +H+CH3O<=>H+CH2OH 4.150E+07 1.630 1924.00 +H+CH3O<=>H2+CH2O 2.000E+13 .000 .00 +H+CH3O<=>OH+CH3 1.500E+12 .500 -110.00 +H+CH3O<=>CH2(S)+H2O 2.620E+14 -.230 1070.00 +H+CH3OH<=>CH2OH+H2 1.700E+07 2.100 4870.00 +H+CH3OH<=>CH3O+H2 4.200E+06 2.100 4870.00 +H+C2H(+M)<=>C2H2(+M) 1.000E+17 -1.000 .00 + LOW / 3.750E+33 -4.800 1900.00/ + TROE/ .6464 132.00 1315.00 5566.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C2H2(+M)<=>C2H3(+M) 5.600E+12 .000 2400.00 + LOW / 3.800E+40 -7.270 7220.00/ + TROE/ .7507 98.50 1302.00 4167.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C2H3(+M)<=>C2H4(+M) 6.080E+12 .270 280.00 + LOW / 1.400E+30 -3.860 3320.00/ + TROE/ .7820 207.50 2663.00 6095.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C2H3<=>H2+C2H2 3.000E+13 .000 .00 +H+C2H4(+M)<=>C2H5(+M) 0.540E+12 .454 1820.00 + LOW / 0.600E+42 -7.620 6970.00/ + TROE/ .9753 210.00 984.00 4374.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C2H4<=>C2H3+H2 1.325E+06 2.530 12240.00 +H+C2H5(+M)<=>C2H6(+M) 5.210E+17 -.990 1580.00 + LOW / 1.990E+41 -7.080 6685.00/ + TROE/ .8422 125.00 2219.00 6882.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C2H5<=>H2+C2H4 2.000E+12 .000 .00 +H+C2H6<=>C2H5+H2 1.150E+08 1.900 7530.00 +H+HCCO<=>CH2(S)+CO 1.000E+14 .000 .00 +H+CH2CO<=>HCCO+H2 5.000E+13 .000 8000.00 +H+CH2CO<=>CH3+CO 1.130E+13 .000 3428.00 +H+HCCOH<=>H+CH2CO 1.000E+13 .000 .00 +H2+CO(+M)<=>CH2O(+M) 4.300E+07 1.500 79600.00 + LOW / 5.070E+27 -3.420 84350.00/ + TROE/ .9320 197.00 1540.00 10300.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +OH+H2<=>H+H2O 2.160E+08 1.510 3430.00 +2OH(+M)<=>H2O2(+M) 7.400E+13 -.370 .00 + LOW / 2.300E+18 -.900 -1700.00/ + TROE/ .7346 94.00 1756.00 5182.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +2OH<=>O+H2O 3.570E+04 2.400 -2110.00 +OH+HO2<=>O2+H2O 1.450E+13 .000 -500.00 + DUPLICATE +OH+H2O2<=>HO2+H2O 2.000E+12 .000 427.00 + DUPLICATE +OH+H2O2<=>HO2+H2O 1.700E+18 .000 29410.00 + DUPLICATE +OH+C<=>H+CO 5.000E+13 .000 .00 +OH+CH<=>H+HCO 3.000E+13 .000 .00 +OH+CH2<=>H+CH2O 2.000E+13 .000 .00 +OH+CH2<=>CH+H2O 1.130E+07 2.000 3000.00 +OH+CH2(S)<=>H+CH2O 3.000E+13 .000 .00 +OH+CH3(+M)<=>CH3OH(+M) 2.790E+18 -1.430 1330.00 + LOW / 4.000E+36 -5.920 3140.00/ + TROE/ .4120 195.0 5900.00 6394.00/ +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +OH+CH3<=>CH2+H2O 5.600E+07 1.600 5420.00 +OH+CH3<=>CH2(S)+H2O 6.440E+17 -1.340 1417.00 +OH+CH4<=>CH3+H2O 1.000E+08 1.600 3120.00 +OH+CO<=>H+CO2 4.760E+07 1.228 70.00 +OH+HCO<=>H2O+CO 5.000E+13 .000 .00 +OH+CH2O<=>HCO+H2O 3.430E+09 1.180 -447.00 +OH+CH2OH<=>H2O+CH2O 5.000E+12 .000 .00 +OH+CH3O<=>H2O+CH2O 5.000E+12 .000 .00 +OH+CH3OH<=>CH2OH+H2O 1.440E+06 2.000 -840.00 +OH+CH3OH<=>CH3O+H2O 6.300E+06 2.000 1500.00 +OH+C2H<=>H+HCCO 2.000E+13 .000 .00 +OH+C2H2<=>H+CH2CO 2.180E-04 4.500 -1000.00 +OH+C2H2<=>H+HCCOH 5.040E+05 2.300 13500.00 +OH+C2H2<=>C2H+H2O 3.370E+07 2.000 14000.00 +OH+C2H2<=>CH3+CO 4.830E-04 4.000 -2000.00 +OH+C2H3<=>H2O+C2H2 5.000E+12 .000 .00 +OH+C2H4<=>C2H3+H2O 3.600E+06 2.000 2500.00 +OH+C2H6<=>C2H5+H2O 3.540E+06 2.120 870.00 +OH+CH2CO<=>HCCO+H2O 7.500E+12 .000 2000.00 +2HO2<=>O2+H2O2 1.300E+11 .000 -1630.00 + DUPLICATE +2HO2<=>O2+H2O2 4.200E+14 .000 12000.00 + DUPLICATE +HO2+CH2<=>OH+CH2O 2.000E+13 .000 .00 +HO2+CH3<=>O2+CH4 1.000E+12 .000 .00 +HO2+CH3<=>OH+CH3O 3.780E+13 .000 .00 +HO2+CO<=>OH+CO2 1.500E+14 .000 23600.00 +HO2+CH2O<=>HCO+H2O2 5.600E+06 2.000 12000.00 +C+O2<=>O+CO 5.800E+13 .000 576.00 +C+CH2<=>H+C2H 5.000E+13 .000 .00 +C+CH3<=>H+C2H2 5.000E+13 .000 .00 +CH+O2<=>O+HCO 6.710E+13 .000 .00 +CH+H2<=>H+CH2 1.080E+14 .000 3110.00 +CH+H2O<=>H+CH2O 5.710E+12 .000 -755.00 +CH+CH2<=>H+C2H2 4.000E+13 .000 .00 +CH+CH3<=>H+C2H3 3.000E+13 .000 .00 +CH+CH4<=>H+C2H4 6.000E+13 .000 .00 +CH+CO(+M)<=>HCCO(+M) 5.000E+13 .000 .00 + LOW / 2.690E+28 -3.740 1936.00/ + TROE/ .5757 237.00 1652.00 5069.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +CH+CO2<=>HCO+CO 1.900E+14 .000 15792.00 +CH+CH2O<=>H+CH2CO 9.460E+13 .000 -515.00 +CH+HCCO<=>CO+C2H2 5.000E+13 .000 .00 +CH2+O2=>OH+H+CO 5.000E+12 .000 1500.00 +CH2+H2<=>H+CH3 5.000E+05 2.000 7230.00 +2CH2<=>H2+C2H2 1.600E+15 .000 11944.00 +CH2+CH3<=>H+C2H4 4.000E+13 .000 .00 +CH2+CH4<=>2CH3 2.460E+06 2.000 8270.00 +CH2+CO(+M)<=>CH2CO(+M) 8.100E+11 .500 4510.00 + LOW / 2.690E+33 -5.110 7095.00/ + TROE/ .5907 275.00 1226.00 5185.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +CH2+HCCO<=>C2H3+CO 3.000E+13 .000 .00 +CH2(S)+N2<=>CH2+N2 1.500E+13 .000 600.00 +CH2(S)+AR<=>CH2+AR 9.000E+12 .000 600.00 +CH2(S)+O2<=>H+OH+CO 2.800E+13 .000 .00 +CH2(S)+O2<=>CO+H2O 1.200E+13 .000 .00 +CH2(S)+H2<=>CH3+H 7.000E+13 .000 .00 +CH2(S)+H2O(+M)<=>CH3OH(+M) 4.820E+17 -1.160 1145.00 + LOW / 1.880E+38 -6.360 5040.00/ + TROE/ .6027 208.00 3922.00 10180.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +CH2(S)+H2O<=>CH2+H2O 3.000E+13 .000 .00 +CH2(S)+CH3<=>H+C2H4 1.200E+13 .000 -570.00 +CH2(S)+CH4<=>2CH3 1.600E+13 .000 -570.00 +CH2(S)+CO<=>CH2+CO 9.000E+12 .000 .00 +CH2(S)+CO2<=>CH2+CO2 7.000E+12 .000 .00 +CH2(S)+CO2<=>CO+CH2O 1.400E+13 .000 .00 +CH2(S)+C2H6<=>CH3+C2H5 4.000E+13 .000 -550.00 +CH3+O2<=>O+CH3O 3.560E+13 .000 30480.00 +CH3+O2<=>OH+CH2O 2.310E+12 .000 20315.00 +CH3+H2O2<=>HO2+CH4 2.450E+04 2.470 5180.00 +2CH3(+M)<=>C2H6(+M) 6.770E+16 -1.180 654.00 + LOW / 3.400E+41 -7.030 2762.00/ + TROE/ .6190 73.20 1180.00 9999.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +2CH3<=>H+C2H5 6.840E+12 .100 10600.00 +CH3+HCO<=>CH4+CO 2.648E+13 .000 .00 +CH3+CH2O<=>HCO+CH4 3.320E+03 2.810 5860.00 +CH3+CH3OH<=>CH2OH+CH4 3.000E+07 1.500 9940.00 +CH3+CH3OH<=>CH3O+CH4 1.000E+07 1.500 9940.00 +CH3+C2H4<=>C2H3+CH4 2.270E+05 2.000 9200.00 +CH3+C2H6<=>C2H5+CH4 6.140E+06 1.740 10450.00 +HCO+H2O<=>H+CO+H2O 1.500E+18 -1.000 17000.00 +HCO+M<=>H+CO+M 1.870E+17 -1.000 17000.00 +H2/2.00/ H2O/ .00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +HCO+O2<=>HO2+CO 13.45E+12 .000 400.00 +CH2OH+O2<=>HO2+CH2O 1.800E+13 .000 900.00 +CH3O+O2<=>HO2+CH2O 4.280E-13 7.600 -3530.00 +C2H+O2<=>HCO+CO 1.000E+13 .000 -755.00 +C2H+H2<=>H+C2H2 5.680E+10 0.900 1993.00 +C2H3+O2<=>HCO+CH2O 4.580E+16 -1.390 1015.00 +C2H4(+M)<=>H2+C2H2(+M) 8.000E+12 .440 86770.00 + LOW / 1.580E+51 -9.300 97800.00/ + TROE/ .7345 180.00 1035.00 5417.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +C2H5+O2<=>HO2+C2H4 8.400E+11 .000 3875.00 +HCCO+O2<=>OH+2CO 3.200E+12 .000 854.00 +2HCCO<=>2CO+C2H2 1.000E+13 .000 .00 +N+NO<=>N2+O 2.700E+13 .000 355.00 +N+O2<=>NO+O 9.000E+09 1.000 6500.00 +N+OH<=>NO+H 3.360E+13 .000 385.00 +N2O+O<=>N2+O2 1.400E+12 .000 10810.00 +N2O+O<=>2NO 2.900E+13 .000 23150.00 +N2O+H<=>N2+OH 3.870E+14 .000 18880.00 +N2O+OH<=>N2+HO2 2.000E+12 .000 21060.00 +N2O(+M)<=>N2+O(+M) 7.910E+10 .000 56020.00 + LOW / 6.370E+14 .000 56640.00/ +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .625/ +HO2+NO<=>NO2+OH 2.110E+12 .000 -480.00 +NO+O+M<=>NO2+M 1.060E+20 -1.410 .00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +NO2+O<=>NO+O2 3.900E+12 .000 -240.00 +NO2+H<=>NO+OH 1.320E+14 .000 360.00 +NH+O<=>NO+H 4.000E+13 .000 .00 +NH+H<=>N+H2 3.200E+13 .000 330.00 +NH+OH<=>HNO+H 2.000E+13 .000 .00 +NH+OH<=>N+H2O 2.000E+09 1.200 .00 +NH+O2<=>HNO+O 4.610E+05 2.000 6500.00 +NH+O2<=>NO+OH 1.280E+06 1.500 100.00 +NH+N<=>N2+H 1.500E+13 .000 .00 +NH+H2O<=>HNO+H2 2.000E+13 .000 13850.00 +NH+NO<=>N2+OH 2.160E+13 -.230 .00 +NH+NO<=>N2O+H 3.650E+14 -.450 .00 +NH2+O<=>OH+NH 3.000E+12 .000 .00 +NH2+O<=>H+HNO 3.900E+13 .000 .00 +NH2+H<=>NH+H2 4.000E+13 .000 3650.00 +NH2+OH<=>NH+H2O 9.000E+07 1.500 -460.00 +NNH<=>N2+H 3.300E+08 .000 .00 +NNH+M<=>N2+H+M 1.300E+14 -.110 4980.00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +NNH+O2<=>HO2+N2 5.000E+12 .000 .00 +NNH+O<=>OH+N2 2.500E+13 .000 .00 +NNH+O<=>NH+NO 7.000E+13 .000 .00 +NNH+H<=>H2+N2 5.000E+13 .000 .00 +NNH+OH<=>H2O+N2 2.000E+13 .000 .00 +NNH+CH3<=>CH4+N2 2.500E+13 .000 .00 +H+NO+M<=>HNO+M 4.480E+19 -1.320 740.00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +HNO+O<=>NO+OH 2.500E+13 .000 .00 +HNO+H<=>H2+NO 9.000E+11 .720 660.00 +HNO+OH<=>NO+H2O 1.300E+07 1.900 -950.00 +HNO+O2<=>HO2+NO 1.000E+13 .000 13000.00 +CN+O<=>CO+N 7.700E+13 .000 .00 +CN+OH<=>NCO+H 4.000E+13 .000 .00 +CN+H2O<=>HCN+OH 8.000E+12 .000 7460.00 +CN+O2<=>NCO+O 6.140E+12 .000 -440.00 +CN+H2<=>HCN+H 2.950E+05 2.450 2240.00 +NCO+O<=>NO+CO 2.350E+13 .000 .00 +NCO+H<=>NH+CO 5.400E+13 .000 .00 +NCO+OH<=>NO+H+CO 0.250E+13 .000 .00 +NCO+N<=>N2+CO 2.000E+13 .000 .00 +NCO+O2<=>NO+CO2 2.000E+12 .000 20000.00 +NCO+M<=>N+CO+M 3.100E+14 .000 54050.00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +NCO+NO<=>N2O+CO 1.900E+17 -1.520 740.00 +NCO+NO<=>N2+CO2 3.800E+18 -2.000 800.00 +HCN+M<=>H+CN+M 1.040E+29 -3.300 126600.00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +HCN+O<=>NCO+H 2.030E+04 2.640 4980.00 +HCN+O<=>NH+CO 5.070E+03 2.640 4980.00 +HCN+O<=>CN+OH 3.910E+09 1.580 26600.00 +HCN+OH<=>HOCN+H 1.100E+06 2.030 13370.00 +HCN+OH<=>HNCO+H 4.400E+03 2.260 6400.00 +HCN+OH<=>NH2+CO 1.600E+02 2.560 9000.00 +H+HCN(+M)<=>H2CN(+M) 3.300E+13 .000 .00 + LOW / 1.400E+26 -3.400 1900.00/ +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H2CN+N<=>N2+CH2 6.000E+13 .000 400.00 +C+N2<=>CN+N 6.300E+13 .000 46020.00 +CH+N2<=>HCN+N 3.120E+09 0.880 20130.00 +CH+N2(+M)<=>HCNN(+M) 3.100E+12 .150 .00 + LOW / 1.300E+25 -3.160 740.00/ + TROE/ .6670 235.00 2117.00 4536.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ 1.0/ +CH2+N2<=>HCN+NH 1.000E+13 .000 74000.00 +CH2(S)+N2<=>NH+HCN 1.000E+11 .000 65000.00 +C+NO<=>CN+O 1.900E+13 .000 .00 +C+NO<=>CO+N 2.900E+13 .000 .00 +CH+NO<=>HCN+O 4.100E+13 .000 .00 +CH+NO<=>H+NCO 1.620E+13 .000 .00 +CH+NO<=>N+HCO 2.460E+13 .000 .00 +CH2+NO<=>H+HNCO 3.100E+17 -1.380 1270.00 +CH2+NO<=>OH+HCN 2.900E+14 -.690 760.00 +CH2+NO<=>H+HCNO 3.800E+13 -.360 580.00 +CH2(S)+NO<=>H+HNCO 3.100E+17 -1.380 1270.00 +CH2(S)+NO<=>OH+HCN 2.900E+14 -.690 760.00 +CH2(S)+NO<=>H+HCNO 3.800E+13 -.360 580.00 +CH3+NO<=>HCN+H2O 9.600E+13 .000 28800.00 +CH3+NO<=>H2CN+OH 1.000E+12 .000 21750.00 +HCNN+O<=>CO+H+N2 2.200E+13 .000 .00 +HCNN+O<=>HCN+NO 2.000E+12 .000 .00 +HCNN+O2<=>O+HCO+N2 1.200E+13 .000 .00 +HCNN+OH<=>H+HCO+N2 1.200E+13 .000 .00 +HCNN+H<=>CH2+N2 1.000E+14 .000 .00 +HNCO+O<=>NH+CO2 9.800E+07 1.410 8500.00 +HNCO+O<=>HNO+CO 1.500E+08 1.570 44000.00 +HNCO+O<=>NCO+OH 2.200E+06 2.110 11400.00 +HNCO+H<=>NH2+CO 2.250E+07 1.700 3800.00 +HNCO+H<=>H2+NCO 1.050E+05 2.500 13300.00 +HNCO+OH<=>NCO+H2O 3.300E+07 1.500 3600.00 +HNCO+OH<=>NH2+CO2 3.300E+06 1.500 3600.00 +HNCO+M<=>NH+CO+M 1.180E+16 .000 84720.00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +HCNO+H<=>H+HNCO 2.100E+15 -.690 2850.00 +HCNO+H<=>OH+HCN 2.700E+11 .180 2120.00 +HCNO+H<=>NH2+CO 1.700E+14 -.750 2890.00 +HOCN+H<=>H+HNCO 2.000E+07 2.000 2000.00 +HCCO+NO<=>HCNO+CO 0.900E+13 .000 .00 +CH3+N<=>H2CN+H 6.100E+14 -.310 290.00 +CH3+N<=>HCN+H2 3.700E+12 .150 -90.00 +NH3+H<=>NH2+H2 5.400E+05 2.400 9915.00 +NH3+OH<=>NH2+H2O 5.000E+07 1.600 955.00 +NH3+O<=>NH2+OH 9.400E+06 1.940 6460.00 +NH+CO2<=>HNO+CO 1.000E+13 .000 14350.00 +CN+NO2<=>NCO+NO 6.160E+15 -0.752 345.00 +NCO+NO2<=>N2O+CO2 3.250E+12 .000 -705.00 +N+CO2<=>NO+CO 3.000E+12 .000 11300.00 +O+CH3=>H+H2+CO 3.370E+13 .000 .00 +O+C2H4<=>H+CH2CHO 6.700E+06 1.830 220.00 +O+C2H5<=>H+CH3CHO 1.096E+14 .000 .00 +OH+HO2<=>O2+H2O 0.500E+16 .000 17330.00 + DUPLICATE +OH+CH3=>H2+CH2O 8.000E+09 .500 -1755.00 +CH+H2(+M)<=>CH3(+M) 1.970E+12 .430 -370.00 + LOW/ 4.820E+25 -2.80 590.0 / + TROE/ .578 122.0 2535.0 9365.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +CH2+O2=>2H+CO2 5.800E+12 .000 1500.00 +CH2+O2<=>O+CH2O 2.400E+12 .000 1500.00 +CH2+CH2=>2H+C2H2 2.000E+14 .000 10989.00 +CH2(S)+H2O=>H2+CH2O 6.820E+10 .250 -935.00 +C2H3+O2<=>O+CH2CHO 3.030E+11 .290 11.00 +C2H3+O2<=>HO2+C2H2 1.337E+06 1.610 -384.00 +O+CH3CHO<=>OH+CH2CHO 5.840E+12 .000 1808.00 +O+CH3CHO=>OH+CH3+CO 5.840E+12 .000 1808.00 +O2+CH3CHO=>HO2+CH3+CO 3.010E+13 .000 39150.00 +H+CH3CHO<=>CH2CHO+H2 2.050E+09 1.160 2405.00 +H+CH3CHO=>CH3+H2+CO 2.050E+09 1.160 2405.00 +OH+CH3CHO=>CH3+H2O+CO 2.343E+10 0.730 -1113.00 +HO2+CH3CHO=>CH3+H2O2+CO 3.010E+12 .000 11923.00 +CH3+CH3CHO=>CH3+CH4+CO 2.720E+06 1.770 5920.00 +H+CH2CO(+M)<=>CH2CHO(+M) 4.865E+11 0.422 -1755.00 + LOW/ 1.012E+42 -7.63 3854.0/ + TROE/ 0.465 201.0 1773.0 5333.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +O+CH2CHO=>H+CH2+CO2 1.500E+14 .000 .00 +O2+CH2CHO=>OH+CO+CH2O 1.810E+10 .000 .00 +O2+CH2CHO=>OH+2HCO 2.350E+10 .000 .00 +H+CH2CHO<=>CH3+HCO 2.200E+13 .000 .00 +H+CH2CHO<=>CH2CO+H2 1.100E+13 .000 .00 +OH+CH2CHO<=>H2O+CH2CO 1.200E+13 .000 .00 +OH+CH2CHO<=>HCO+CH2OH 3.010E+13 .000 .00 +CH3+C2H5(+M)<=>C3H8(+M) .9430E+13 .000 .00 + LOW/ 2.710E+74 -16.82 13065.0 / + TROE/ .1527 291.0 2742.0 7748.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +O+C3H8<=>OH+C3H7 1.930E+05 2.680 3716.00 +H+C3H8<=>C3H7+H2 1.320E+06 2.540 6756.00 +OH+C3H8<=>C3H7+H2O 3.160E+07 1.800 934.00 +C3H7+H2O2<=>HO2+C3H8 3.780E+02 2.720 1500.00 +CH3+C3H8<=>C3H7+CH4 0.903E+00 3.650 7154.00 +CH3+C2H4(+M)<=>C3H7(+M) 2.550E+06 1.600 5700.00 + LOW/ 3.00E+63 -14.6 18170./ + TROE/ .1894 277.0 8748.0 7891.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +O+C3H7<=>C2H5+CH2O 9.640E+13 .000 .00 +H+C3H7(+M)<=>C3H8(+M) 3.613E+13 .000 .00 + LOW/ 4.420E+61 -13.545 11357.0/ + TROE/ .315 369.0 3285.0 6667.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C3H7<=>CH3+C2H5 4.060E+06 2.190 890.00 +OH+C3H7<=>C2H5+CH2OH 2.410E+13 .000 .00 +HO2+C3H7<=>O2+C3H8 2.550E+10 0.255 -943.00 +HO2+C3H7=>OH+C2H5+CH2O 2.410E+13 .000 .00 +CH3+C3H7<=>2C2H5 1.927E+13 -0.320 .00 +END diff --git a/test_problems/cxx_ex/gri30.xml b/test_problems/cxx_ex/gri30.xml new file mode 100644 index 000000000..da7da5613 --- /dev/null +++ b/test_problems/cxx_ex/gri30.xml @@ -0,0 +1,4877 @@ + + + + + + + + + 300 + 1 + H2:1.0 + + + O H C N Ar + + H2 H O O2 OH H2O HO2 H2O2 C CH + CH2 CH2(S) CH3 CH4 CO CO2 HCO CH2O CH2OH CH3O + CH3OH C2H C2H2 C2H3 C2H4 C2H5 C2H6 HCCO CH2CO HCCOH + N NH NH2 NH3 NNH NO NO2 N2O HNO CN + HCN H2CN HCNN HCNO HOCN HNCO NCO N2 AR C3H7 + C3H8 CH2CHO CH3CHO + + + + + + + + + + + + 300 + 1 + H2:1.0 + + + O H C N Ar + + H2 H O O2 OH H2O HO2 H2O2 C CH + CH2 CH2(S) CH3 CH4 CO CO2 HCO CH2O CH2OH CH3O + CH3OH C2H C2H2 C2H3 C2H4 C2H5 C2H6 HCCO CH2CO HCCOH + N NH NH2 NH3 NNH NO NO2 N2O HNO CN + HCN H2CN HCNN HCNO HOCN HNCO NCO N2 AR C3H7 + C3H8 CH2CHO CH3CHO + + + + + + + + + + + + + + TPIS78 + H:2 + + + + 2.344331120E+000, 7.980520750E-003, -1.947815100E-005, + 2.015720940E-008, -7.376117610E-012, -9.179351730E+002, + 6.830102380E-001 + + + 3.337279200E+000, -4.940247310E-005, 4.994567780E-007, + -1.795663940E-010, 2.002553760E-014, -9.501589220E+002, + -3.205023310E+000 + + + + + linear + 3.800000000E+001 + 2.920000000E+000 + 7.900000000E-001 + 2.800000000E+002 + + + + + + L 7/88 + H:1 + + + + 2.500000000E+000, 7.053328190E-013, -1.995919640E-015, + 2.300816320E-018, -9.277323320E-022, 2.547365990E+004, + -4.466828530E-001 + + + 2.500000010E+000, -2.308429730E-011, 1.615619480E-014, + -4.735152350E-018, 4.981973570E-022, 2.547365990E+004, + -4.466829140E-001 + + + + + atom + 1.450000000E+002 + 2.050000000E+000 + + + + + + L 1/90 + O:1 + + + + 3.168267100E+000, -3.279318840E-003, 6.643063960E-006, + -6.128066240E-009, 2.112659710E-012, 2.912225920E+004, + 2.051933460E+000 + + + 2.569420780E+000, -8.597411370E-005, 4.194845890E-008, + -1.001777990E-011, 1.228336910E-015, 2.921757910E+004, + 4.784338640E+000 + + + + + atom + 8.000000000E+001 + 2.750000000E+000 + + + + + + TPIS89 + O:2 + + + + 3.782456360E+000, -2.996734160E-003, 9.847302010E-006, + -9.681295090E-009, 3.243728370E-012, -1.063943560E+003, + 3.657675730E+000 + + + 3.282537840E+000, 1.483087540E-003, -7.579666690E-007, + 2.094705550E-010, -2.167177940E-014, -1.088457720E+003, + 5.453231290E+000 + + + + + linear + 1.074000000E+002 + 3.458000000E+000 + 1.600000000E+000 + 3.800000000E+000 + + + + + + RUS 78 + O:1 H:1 + + + + 3.992015430E+000, -2.401317520E-003, 4.617938410E-006, + -3.881133330E-009, 1.364114700E-012, 3.615080560E+003, + -1.039254580E-001 + + + 3.092887670E+000, 5.484297160E-004, 1.265052280E-007, + -8.794615560E-011, 1.174123760E-014, 3.858657000E+003, + 4.476696100E+000 + + + + + linear + 8.000000000E+001 + 2.750000000E+000 + + + + + + L 8/89 + H:2 O:1 + + + + 4.198640560E+000, -2.036434100E-003, 6.520402110E-006, + -5.487970620E-009, 1.771978170E-012, -3.029372670E+004, + -8.490322080E-001 + + + 3.033992490E+000, 2.176918040E-003, -1.640725180E-007, + -9.704198700E-011, 1.682009920E-014, -3.000429710E+004, + 4.966770100E+000 + + + + + nonlinear + 5.724000000E+002 + 2.605000000E+000 + 1.844000000E+000 + 4.000000000E+000 + + + + + + L 5/89 + H:1 O:2 + + + + 4.301798010E+000, -4.749120510E-003, 2.115828910E-005, + -2.427638940E-008, 9.292251240E-012, 2.948080400E+002, + 3.716662450E+000 + + + 4.017210900E+000, 2.239820130E-003, -6.336581500E-007, + 1.142463700E-010, -1.079085350E-014, 1.118567130E+002, + 3.785102150E+000 + + + + + nonlinear + 1.074000000E+002 + 3.458000000E+000 + 1.000000000E+000 + + + + + + L 7/88 + H:2 O:2 + + + + 4.276112690E+000, -5.428224170E-004, 1.673357010E-005, + -2.157708130E-008, 8.624543630E-012, -1.770258210E+004, + 3.435050740E+000 + + + 4.165002850E+000, 4.908316940E-003, -1.901392250E-006, + 3.711859860E-010, -2.879083050E-014, -1.786178770E+004, + 2.916156620E+000 + + + + + nonlinear + 1.074000000E+002 + 3.458000000E+000 + 3.800000000E+000 + + + + + + L11/88 + C:1 + + + + 2.554239550E+000, -3.215377240E-004, 7.337922450E-007, + -7.322348890E-010, 2.665214460E-013, 8.544388320E+004, + 4.531308480E+000 + + + 2.492668880E+000, 4.798892840E-005, -7.243350200E-008, + 3.742910290E-011, -4.872778930E-015, 8.545129530E+004, + 4.801503730E+000 + + + + + atom + 7.140000000E+001 + 3.298000000E+000 + + + + + + TPIS79 + C:1 H:1 + + + + 3.489816650E+000, 3.238355410E-004, -1.688990650E-006, + 3.162173270E-009, -1.406090670E-012, 7.079729340E+004, + 2.084011080E+000 + + + 2.878464730E+000, 9.709136810E-004, 1.444456550E-007, + -1.306878490E-010, 1.760793830E-014, 7.101243640E+004, + 5.484979990E+000 + + + + + linear + 8.000000000E+001 + 2.750000000E+000 + + + + + + L S/93 + C:1 H:2 + + + + 3.762678670E+000, 9.688721430E-004, 2.794898410E-006, + -3.850911530E-009, 1.687417190E-012, 4.600404010E+004, + 1.562531850E+000 + + + 2.874101130E+000, 3.656392920E-003, -1.408945970E-006, + 2.601795490E-010, -1.877275670E-014, 4.626360400E+004, + 6.171193240E+000 + + + + + linear + 1.440000000E+002 + 3.800000000E+000 + + + + + + L S/93 + C:1 H:2 + + + + 4.198604110E+000, -2.366614190E-003, 8.232962200E-006, + -6.688159810E-009, 1.943147370E-012, 5.049681630E+004, + -7.691189670E-001 + + + 2.292038420E+000, 4.655886370E-003, -2.011919470E-006, + 4.179060000E-010, -3.397163650E-014, 5.092599970E+004, + 8.626501690E+000 + + + + + linear + 1.440000000E+002 + 3.800000000E+000 + + + + + + L11/89 + C:1 H:3 + + + + 3.673590400E+000, 2.010951750E-003, 5.730218560E-006, + -6.871174250E-009, 2.543857340E-012, 1.644499880E+004, + 1.604564330E+000 + + + 2.285717720E+000, 7.239900370E-003, -2.987143480E-006, + 5.956846440E-010, -4.671543940E-014, 1.677558430E+004, + 8.480071790E+000 + + + + + linear + 1.440000000E+002 + 3.800000000E+000 + + + + + + L 8/88 + C:1 H:4 + + + + 5.149876130E+000, -1.367097880E-002, 4.918005990E-005, + -4.847430260E-008, 1.666939560E-011, -1.024664760E+004, + -4.641303760E+000 + + + 7.485149500E-002, 1.339094670E-002, -5.732858090E-006, + 1.222925350E-009, -1.018152300E-013, -9.468344590E+003, + 1.843731800E+001 + + + + + nonlinear + 1.414000000E+002 + 3.746000000E+000 + 2.600000000E+000 + 1.300000000E+001 + + + + + + TPIS79 + C:1 O:1 + + + + 3.579533470E+000, -6.103536800E-004, 1.016814330E-006, + 9.070058840E-010, -9.044244990E-013, -1.434408600E+004, + 3.508409280E+000 + + + 2.715185610E+000, 2.062527430E-003, -9.988257710E-007, + 2.300530080E-010, -2.036477160E-014, -1.415187240E+004, + 7.818687720E+000 + + + + + linear + 9.810000000E+001 + 3.650000000E+000 + 1.950000000E+000 + 1.800000000E+000 + + + + + + L 7/88 + C:1 O:2 + + + + 2.356773520E+000, 8.984596770E-003, -7.123562690E-006, + 2.459190220E-009, -1.436995480E-013, -4.837196970E+004, + 9.901052220E+000 + + + 3.857460290E+000, 4.414370260E-003, -2.214814040E-006, + 5.234901880E-010, -4.720841640E-014, -4.875916600E+004, + 2.271638060E+000 + + + + + linear + 2.440000000E+002 + 3.763000000E+000 + 2.650000000E+000 + 2.100000000E+000 + + + + + + L12/89 + H:1 C:1 O:1 + + + + 4.221185840E+000, -3.243925320E-003, 1.377994460E-005, + -1.331440930E-008, 4.337688650E-012, 3.839564960E+003, + 3.394372430E+000 + + + 2.772174380E+000, 4.956955260E-003, -2.484456130E-006, + 5.891617780E-010, -5.335087110E-014, 4.011918150E+003, + 9.798344920E+000 + + + + + nonlinear + 4.980000000E+002 + 3.590000000E+000 + + + + + + L 8/88 + H:2 C:1 O:1 + + + + 4.793723150E+000, -9.908333690E-003, 3.732200080E-005, + -3.792852610E-008, 1.317726520E-011, -1.430895670E+004, + 6.028129000E-001 + + + 1.760690080E+000, 9.200000820E-003, -4.422588130E-006, + 1.006412120E-009, -8.838556400E-014, -1.399583230E+004, + 1.365632300E+001 + + + + + nonlinear + 4.980000000E+002 + 3.590000000E+000 + 2.000000000E+000 + + + + + + GUNL93 + C:1 H:3 O:1 + + + + 3.863889180E+000, 5.596723040E-003, 5.932717910E-006, + -1.045320120E-008, 4.369672780E-012, -3.193913670E+003, + 5.473022430E+000 + + + 3.692665690E+000, 8.645767970E-003, -3.751011200E-006, + 7.872346360E-010, -6.485542010E-014, -3.242506270E+003, + 5.810432150E+000 + + + + + nonlinear + 4.170000000E+002 + 3.690000000E+000 + 1.700000000E+000 + 2.000000000E+000 + + + + + + 121686 + C:1 H:3 O:1 + + + + 2.106204000E+000, 7.216595000E-003, 5.338472000E-006, + -7.377636000E-009, 2.075610000E-012, 9.786011000E+002, + 1.315217700E+001 + + + 3.770799000E+000, 7.871497000E-003, -2.656384000E-006, + 3.944431000E-010, -2.112616000E-014, 1.278325200E+002, + 2.929575000E+000 + + + + + nonlinear + 4.170000000E+002 + 3.690000000E+000 + 1.700000000E+000 + 2.000000000E+000 + + + + + + L 8/88 + C:1 H:4 O:1 + + + + 5.715395820E+000, -1.523091290E-002, 6.524411550E-005, + -7.108068890E-008, 2.613526980E-011, -2.564276560E+004, + -1.504098230E+000 + + + 1.789707910E+000, 1.409382920E-002, -6.365008350E-006, + 1.381710850E-009, -1.170602200E-013, -2.537487470E+004, + 1.450236230E+001 + + + + + nonlinear + 4.818000000E+002 + 3.626000000E+000 + 1.000000000E+000 + + + + + + L 1/91 + C:2 H:1 + + + + 2.889657330E+000, 1.340996110E-002, -2.847695010E-005, + 2.947910450E-008, -1.093315110E-011, 6.683939320E+004, + 6.222964380E+000 + + + 3.167806520E+000, 4.752219020E-003, -1.837870770E-006, + 3.041902520E-010, -1.772327700E-014, 6.712106500E+004, + 6.635894750E+000 + + + + + linear + 2.090000000E+002 + 4.100000000E+000 + 2.500000000E+000 + + + + + + L 1/91 + C:2 H:2 + + + + 8.086810940E-001, 2.336156290E-002, -3.551718150E-005, + 2.801524370E-008, -8.500729740E-012, 2.642898070E+004, + 1.393970510E+001 + + + 4.147569640E+000, 5.961666640E-003, -2.372948520E-006, + 4.674121710E-010, -3.612352130E-014, 2.593599920E+004, + -1.230281210E+000 + + + + + linear + 2.090000000E+002 + 4.100000000E+000 + 2.500000000E+000 + + + + + + L 2/92 + C:2 H:3 + + + + 3.212466450E+000, 1.514791620E-003, 2.592094120E-005, + -3.576578470E-008, 1.471508730E-011, 3.485984680E+004, + 8.510540250E+000 + + + 3.016724000E+000, 1.033022920E-002, -4.680823490E-006, + 1.017632880E-009, -8.626070410E-014, 3.461287390E+004, + 7.787323780E+000 + + + + + nonlinear + 2.090000000E+002 + 4.100000000E+000 + 1.000000000E+000 + + + + + + L 1/91 + C:2 H:4 + + + + 3.959201480E+000, -7.570522470E-003, 5.709902920E-005, + -6.915887530E-008, 2.698843730E-011, 5.089775930E+003, + 4.097330960E+000 + + + 2.036111160E+000, 1.464541510E-002, -6.710779150E-006, + 1.472229230E-009, -1.257060610E-013, 4.939886140E+003, + 1.030536930E+001 + + + + + nonlinear + 2.808000000E+002 + 3.971000000E+000 + 1.500000000E+000 + + + + + + L12/92 + C:2 H:5 + + + + 4.306465680E+000, -4.186588920E-003, 4.971428070E-005, + -5.991266060E-008, 2.305090040E-011, 1.284162650E+004, + 4.707209240E+000 + + + 1.954656420E+000, 1.739727220E-002, -7.982066680E-006, + 1.752176890E-009, -1.496415760E-013, 1.285752000E+004, + 1.346243430E+001 + + + + + nonlinear + 2.523000000E+002 + 4.302000000E+000 + 1.500000000E+000 + + + + + + L 8/88 + C:2 H:6 + + + + 4.291424920E+000, -5.501542700E-003, 5.994382880E-005, + -7.084662850E-008, 2.686857710E-011, -1.152220550E+004, + 2.666823160E+000 + + + 1.071881500E+000, 2.168526770E-002, -1.002560670E-005, + 2.214120010E-009, -1.900028900E-013, -1.142639320E+004, + 1.511561070E+001 + + + + + nonlinear + 2.523000000E+002 + 4.302000000E+000 + 1.500000000E+000 + + + + + + SRIC91 + H:1 C:2 O:1 + + + + 2.251721400E+000, 1.765502100E-002, -2.372910100E-005, + 1.727575900E-008, -5.066481100E-012, 2.005944900E+004, + 1.249041700E+001 + + + 5.628205800E+000, 4.085340100E-003, -1.593454700E-006, + 2.862605200E-010, -1.940783200E-014, 1.932721500E+004, + -3.930259500E+000 + + + + + nonlinear + 1.500000000E+002 + 2.500000000E+000 + 1.000000000E+000 + + + + + + L 5/90 + C:2 H:2 O:1 + + + + 2.135836300E+000, 1.811887210E-002, -1.739474740E-005, + 9.343975680E-009, -2.014576150E-012, -7.042918040E+003, + 1.221564800E+001 + + + 4.511297320E+000, 9.003597450E-003, -4.169396350E-006, + 9.233458820E-010, -7.948382010E-014, -7.551053110E+003, + 6.322472050E-001 + + + + + nonlinear + 4.360000000E+002 + 3.970000000E+000 + 2.000000000E+000 + + + + + + SRI91 + C:2 O:1 H:2 + + + + 1.242373300E+000, 3.107220100E-002, -5.086686400E-005, + 4.313713100E-008, -1.401459400E-011, 8.031614300E+003, + 1.387431900E+001 + + + 5.923829100E+000, 6.792360000E-003, -2.565856400E-006, + 4.498784100E-010, -2.994010100E-014, 7.264626000E+003, + -7.601774200E+000 + + + + + nonlinear + 4.360000000E+002 + 3.970000000E+000 + 2.000000000E+000 + + + + + + L 6/88 + N:1 + + + + 2.500000000E+000, 0.000000000E+000, 0.000000000E+000, + 0.000000000E+000, 0.000000000E+000, 5.610463700E+004, + 4.193908700E+000 + + + 2.415942900E+000, 1.748906500E-004, -1.190236900E-007, + 3.022624500E-011, -2.036098200E-015, 5.613377300E+004, + 4.649609600E+000 + + + + + atom + 7.140000000E+001 + 3.298000000E+000 + + + + + + And94 + N:1 H:1 + + + + 3.492908500E+000, 3.117919800E-004, -1.489048400E-006, + 2.481644200E-009, -1.035696700E-012, 4.188062900E+004, + 1.848327800E+000 + + + 2.783692800E+000, 1.329843000E-003, -4.247804700E-007, + 7.834850100E-011, -5.504447000E-015, 4.212084800E+004, + 5.740779900E+000 + + + + + linear + 8.000000000E+001 + 2.650000000E+000 + 4.000000000E+000 + + + + + + And89 + N:1 H:2 + + + + 4.204002900E+000, -2.106138500E-003, 7.106834800E-006, + -5.611519700E-009, 1.644071700E-012, 2.188591000E+004, + -1.418424800E-001 + + + 2.834742100E+000, 3.207308200E-003, -9.339080400E-007, + 1.370295300E-010, -7.920614400E-015, 2.217195700E+004, + 6.520416300E+000 + + + + + nonlinear + 8.000000000E+001 + 2.650000000E+000 + 2.260000000E+000 + 4.000000000E+000 + + + + + + J 6/77 + N:1 H:3 + + + + 4.286027400E+000, -4.660523000E-003, 2.171851300E-005, + -2.280888700E-008, 8.263804600E-012, -6.741728500E+003, + -6.253727700E-001 + + + 2.634452100E+000, 5.666256000E-003, -1.727867600E-006, + 2.386716100E-010, -1.257878600E-014, -6.544695800E+003, + 6.566292800E+000 + + + + + nonlinear + 4.810000000E+002 + 2.920000000E+000 + 1.470000000E+000 + 1.000000000E+001 + + + + + + T07/93 + N:2 H:1 + + + + 4.344692700E+000, -4.849707200E-003, 2.005945900E-005, + -2.172646400E-008, 7.946953900E-012, 2.879197300E+004, + 2.977941000E+000 + + + 3.766754400E+000, 2.891508200E-003, -1.041662000E-006, + 1.684259400E-010, -1.009189600E-014, 2.865069700E+004, + 4.470506700E+000 + + + + + nonlinear + 7.140000000E+001 + 3.798000000E+000 + 1.000000000E+000 + + + + + + RUS 78 + N:1 O:1 + + + + 4.218476300E+000, -4.638976000E-003, 1.104102200E-005, + -9.336135400E-009, 2.803577000E-012, 9.844623000E+003, + 2.280846400E+000 + + + 3.260605600E+000, 1.191104300E-003, -4.291704800E-007, + 6.945766900E-011, -4.033609900E-015, 9.920974600E+003, + 6.369302700E+000 + + + + + linear + 9.753000000E+001 + 3.621000000E+000 + 1.760000000E+000 + 4.000000000E+000 + + + + + + L 7/88 + N:1 O:2 + + + + 3.944031200E+000, -1.585429000E-003, 1.665781200E-005, + -2.047542600E-008, 7.835056400E-012, 2.896617900E+003, + 6.311991700E+000 + + + 4.884754200E+000, 2.172395600E-003, -8.280690600E-007, + 1.574751000E-010, -1.051089500E-014, 2.316498300E+003, + -1.174169500E-001 + + + + + nonlinear + 2.000000000E+002 + 3.500000000E+000 + 1.000000000E+000 + + + + + + L 7/88 + N:2 O:1 + + + + 2.257150200E+000, 1.130472800E-002, -1.367131900E-005, + 9.681980600E-009, -2.930718200E-012, 8.741774400E+003, + 1.075799200E+001 + + + 4.823072900E+000, 2.627025100E-003, -9.585087400E-007, + 1.600071200E-010, -9.775230300E-015, 8.073404800E+003, + -2.201720700E+000 + + + + + linear + 2.324000000E+002 + 3.828000000E+000 + 1.000000000E+000 + + + + + + And93 + H:1 N:1 O:1 + + + + 4.533491600E+000, -5.669617100E-003, 1.847320700E-005, + -1.713709400E-008, 5.545457300E-012, 1.154829700E+004, + 1.749841700E+000 + + + 2.979250900E+000, 3.494405900E-003, -7.854977800E-007, + 5.747959400E-011, -1.933591600E-016, 1.175058200E+004, + 8.606372800E+000 + + + + + nonlinear + 1.167000000E+002 + 3.492000000E+000 + 1.000000000E+000 + + + + + + HBH92 + C:1 N:1 + + + + 3.612935100E+000, -9.555132700E-004, 2.144297700E-006, + -3.151632300E-010, -4.643035600E-013, 5.170834000E+004, + 3.980499500E+000 + + + 3.745980500E+000, 4.345077500E-005, 2.970598400E-007, + -6.865180600E-011, 4.413417300E-015, 5.153618800E+004, + 2.786760100E+000 + + + + + linear + 7.500000000E+001 + 3.856000000E+000 + 1.000000000E+000 + + + + + + GRI/98 + H:1 C:1 N:1 + + + + 2.258988600E+000, 1.005117000E-002, -1.335176300E-005, + 1.009234900E-008, -3.008902800E-012, 1.471263300E+004, + 8.916441900E+000 + + + 3.802239200E+000, 3.146422800E-003, -1.063218500E-006, + 1.661975700E-010, -9.799757000E-015, 1.440729200E+004, + 1.575460100E+000 + + + + + linear + 5.690000000E+002 + 3.630000000E+000 + 1.000000000E+000 + + + + + + 41687 + H:2 C:1 N:1 + + + + 2.851661000E+000, 5.695233100E-003, 1.071140000E-006, + -1.622612000E-009, -2.351108100E-013, 2.863782000E+004, + 8.992751100E+000 + + + 5.209703000E+000, 2.969291100E-003, -2.855589100E-007, + -1.635550000E-010, 3.043258900E-014, 2.767710900E+004, + -4.444478000E+000 + + + + + linear + 5.690000000E+002 + 3.630000000E+000 + 1.000000000E+000 + + + + + + SRI/94 + C:1 N:2 H:1 + + + + 2.524319400E+000, 1.596061900E-002, -1.881635400E-005, + 1.212554000E-008, -3.235737800E-012, 5.426198400E+004, + 1.167587000E+001 + + + 5.894636200E+000, 3.989595900E-003, -1.598238000E-006, + 2.924939500E-010, -2.009468600E-014, 5.345294100E+004, + -5.103050200E+000 + + + + + nonlinear + 1.500000000E+002 + 2.500000000E+000 + 1.000000000E+000 + + + + + + BDEA94 + H:1 N:1 C:1 O:1 + + + + 2.647279890E+000, 1.275053420E-002, -1.047942360E-005, + 4.414328360E-009, -7.575214660E-013, 1.929902520E+004, + 1.073329720E+001 + + + 6.598604560E+000, 3.027786260E-003, -1.077043460E-006, + 1.716665280E-010, -1.014393910E-014, 1.796613390E+004, + -1.033065990E+001 + + + + + nonlinear + 2.324000000E+002 + 3.828000000E+000 + 1.000000000E+000 + + + + + + BDEA94 + H:1 N:1 C:1 O:1 + + + + 3.786049520E+000, 6.886679220E-003, -3.214878640E-006, + 5.171957670E-010, 1.193607880E-014, -2.826984000E+003, + 5.632921620E+000 + + + 5.897848850E+000, 3.167893930E-003, -1.118010640E-006, + 1.772431440E-010, -1.043391770E-014, -3.706533310E+003, + -6.181678250E+000 + + + + + nonlinear + 2.324000000E+002 + 3.828000000E+000 + 1.000000000E+000 + + + + + + BDEA94 + H:1 N:1 C:1 O:1 + + + + 3.630963170E+000, 7.302823570E-003, -2.280500030E-006, + -6.612712980E-010, 3.622357520E-013, -1.558736360E+004, + 6.194577270E+000 + + + 6.223951340E+000, 3.178640040E-003, -1.093787550E-006, + 1.707351630E-010, -9.950219550E-015, -1.665993440E+004, + -8.382247410E+000 + + + + + nonlinear + 2.324000000E+002 + 3.828000000E+000 + 1.000000000E+000 + + + + + + EA 93 + N:1 C:1 O:1 + + + + 2.826930800E+000, 8.805168800E-003, -8.386613400E-006, + 4.801696400E-009, -1.331359500E-012, 1.468247700E+004, + 9.550464600E+000 + + + 5.152184500E+000, 2.305176100E-003, -8.803315300E-007, + 1.478909800E-010, -9.097799600E-015, 1.400412300E+004, + -2.544266000E+000 + + + + + linear + 2.324000000E+002 + 3.828000000E+000 + 1.000000000E+000 + + + + + + 121286 + N:2 + + + + 3.298677000E+000, 1.408240400E-003, -3.963222000E-006, + 5.641515000E-009, -2.444854000E-012, -1.020899900E+003, + 3.950372000E+000 + + + 2.926640000E+000, 1.487976800E-003, -5.684760000E-007, + 1.009703800E-010, -6.753351000E-015, -9.227977000E+002, + 5.980528000E+000 + + + + + linear + 9.753000000E+001 + 3.621000000E+000 + 1.760000000E+000 + 4.000000000E+000 + + + + + + 120186 + Ar:1 + + + + 2.500000000E+000, 0.000000000E+000, 0.000000000E+000, + 0.000000000E+000, 0.000000000E+000, -7.453750000E+002, + 4.366000000E+000 + + + 2.500000000E+000, 0.000000000E+000, 0.000000000E+000, + 0.000000000E+000, 0.000000000E+000, -7.453750000E+002, + 4.366000000E+000 + + + + + atom + 1.365000000E+002 + 3.330000000E+000 + + + + + + L 9/84 + C:3 H:7 + + + + 1.051551800E+000, 2.599198000E-002, 2.380054000E-006, + -1.960956900E-008, 9.373247000E-012, 1.063186300E+004, + 2.112255900E+001 + + + 7.702698700E+000, 1.604420300E-002, -5.283322000E-006, + 7.629859000E-010, -3.939228400E-014, 8.298433600E+003, + -1.548018000E+001 + + + + + nonlinear + 2.668000000E+002 + 4.982000000E+000 + 1.000000000E+000 + + + + + + L 4/85 + C:3 H:8 + + + + 9.335538100E-001, 2.642457900E-002, 6.105972700E-006, + -2.197749900E-008, 9.514925300E-012, -1.395852000E+004, + 1.920169100E+001 + + + 7.534136800E+000, 1.887223900E-002, -6.271849100E-006, + 9.147564900E-010, -4.783806900E-014, -1.646751600E+004, + -1.789234900E+001 + + + + + nonlinear + 2.668000000E+002 + 4.982000000E+000 + 1.000000000E+000 + + + + + + SAND86 + O:1 H:3 C:2 + + + + 3.409062000E+000, 1.073857400E-002, 1.891492000E-006, + -7.158583000E-009, 2.867385000E-012, 1.521476600E+003, + 9.558290000E+000 + + + 5.975670000E+000, 8.130591000E-003, -2.743624000E-006, + 4.070304000E-010, -2.176017000E-014, 4.903218000E+002, + -5.045251000E+000 + + + + + nonlinear + 4.360000000E+002 + 3.970000000E+000 + 2.000000000E+000 + + + + + + L 8/88 + C:2 H:4 O:1 + + + + 4.729459500E+000, -3.193285800E-003, 4.753492100E-005, + -5.745861100E-008, 2.193111200E-011, -2.157287800E+004, + 4.103015900E+000 + + + 5.404110800E+000, 1.172305900E-002, -4.226313700E-006, + 6.837245100E-010, -4.098486300E-014, -2.259312200E+004, + -3.480791700E+000 + + + + + nonlinear + 4.360000000E+002 + 3.970000000E+000 + 2.000000000E+000 + + + + + + + + + + 2 O + M [=] O2 + M + O:2 + O2:1 + + 1.2e+017 -1 0 + + AR:0.83 C2H6:3 CH4:2 CO:1.75 CO2:3.6 H2:2.4 H2O:15.4 + + + + + + + O + H + M [=] OH + M + O:1 H:1 + OH:1 + + 5e+017 -1 0 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + O + H2 [=] H + OH + O:1 H2:1 + H:1 OH:1 + + 38700 2.7 6260 + + + + + + O + HO2 [=] OH + O2 + O:1 HO2:1 + OH:1 O2:1 + + 2e+013 0 0 + + + + + + O + H2O2 [=] OH + HO2 + O:1 H2O2:1 + OH:1 HO2:1 + + 9.63e+006 2 4000 + + + + + + O + CH [=] H + CO + O:1 CH:1 + H:1 CO:1 + + 5.7e+013 0 0 + + + + + + O + CH2 [=] H + HCO + O:1 CH2:1 + H:1 HCO:1 + + 8e+013 0 0 + + + + + + O + CH2(S) [=] H2 + CO + O:1 CH2(S):1 + H2:1 CO:1 + + 1.5e+013 0 0 + + + + + + O + CH2(S) [=] H + HCO + O:1 CH2(S):1 + H:1 HCO:1 + + 1.5e+013 0 0 + + + + + + O + CH3 [=] H + CH2O + O:1 CH3:1 + H:1 CH2O:1 + + 5.06e+013 0 0 + + + + + + O + CH4 [=] OH + CH3 + O:1 CH4:1 + OH:1 CH3:1 + + 1.02e+009 1.5 8600 + + + + + + O + CO (+ M) [=] CO2 (+ M) + O:1 CO:1 + CO2:1 + + 1.8e+010 0 2385 + 6.02e+014 0 3000 + + + AR:0.5 C2H6:3 CH4:2 CO:1.5 CO2:3.5 H2:2 H2O:6 O2:6 + + + + + + + O + HCO [=] OH + CO + O:1 HCO:1 + OH:1 CO:1 + + 3e+013 0 0 + + + + + + O + HCO [=] H + CO2 + O:1 HCO:1 + H:1 CO2:1 + + 3e+013 0 0 + + + + + + O + CH2O [=] OH + HCO + O:1 CH2O:1 + OH:1 HCO:1 + + 3.9e+013 0 3540 + + + + + + O + CH2OH [=] OH + CH2O + O:1 CH2OH:1 + OH:1 CH2O:1 + + 1e+013 0 0 + + + + + + O + CH3O [=] OH + CH2O + O:1 CH3O:1 + OH:1 CH2O:1 + + 1e+013 0 0 + + + + + + O + CH3OH [=] OH + CH2OH + O:1 CH3OH:1 + OH:1 CH2OH:1 + + 388000 2.5 3100 + + + + + + O + CH3OH [=] OH + CH3O + O:1 CH3OH:1 + OH:1 CH3O:1 + + 130000 2.5 5000 + + + + + + O + C2H [=] CH + CO + O:1 C2H:1 + CH:1 CO:1 + + 5e+013 0 0 + + + + + + O + C2H2 [=] H + HCCO + O:1 C2H2:1 + H:1 HCCO:1 + + 1.35e+007 2 1900 + + + + + + O + C2H2 [=] OH + C2H + O:1 C2H2:1 + OH:1 C2H:1 + + 4.6e+019 -1.41 28950 + + + + + + O + C2H2 [=] CO + CH2 + O:1 C2H2:1 + CO:1 CH2:1 + + 6.94e+006 2 1900 + + + + + + O + C2H3 [=] H + CH2CO + O:1 C2H3:1 + H:1 CH2CO:1 + + 3e+013 0 0 + + + + + + O + C2H4 [=] CH3 + HCO + O:1 C2H4:1 + CH3:1 HCO:1 + + 1.25e+007 1.83 220 + + + + + + O + C2H5 [=] CH3 + CH2O + O:1 C2H5:1 + CH3:1 CH2O:1 + + 2.24e+013 0 0 + + + + + + O + C2H6 [=] OH + C2H5 + O:1 C2H6:1 + OH:1 C2H5:1 + + 8.98e+007 1.92 5690 + + + + + + O + HCCO [=] H + 2 CO + O:1 HCCO:1 + H:1 CO:2 + + 1e+014 0 0 + + + + + + O + CH2CO [=] OH + HCCO + O:1 CH2CO:1 + OH:1 HCCO:1 + + 1e+013 0 8000 + + + + + + O + CH2CO [=] CH2 + CO2 + O:1 CH2CO:1 + CH2:1 CO2:1 + + 1.75e+012 0 1350 + + + + + + O2 + CO [=] O + CO2 + O2:1 CO:1 + O:1 CO2:1 + + 2.5e+012 0 47800 + + + + + + O2 + CH2O [=] HO2 + HCO + O2:1 CH2O:1 + HO2:1 HCO:1 + + 1e+014 0 40000 + + + + + + H + O2 + M [=] HO2 + M + H:1 O2:1 + HO2:1 + + 2.8e+018 -0.86 0 + + AR:0 C2H6:1.5 CO:0.75 CO2:1.5 H2O:0 N2:0 O2:0 + + + + + + + H + 2 O2 [=] HO2 + O2 + H:1 O2:2 + HO2:1 O2:1 + + 2.08e+019 -1.24 0 + + + + + + H + O2 + H2O [=] HO2 + H2O + H:1 O2:1 H2O:1 + HO2:1 H2O:1 + + 1.126e+019 -0.76 0 + + + + + + H + O2 + N2 [=] HO2 + N2 + H:1 O2:1 N2:1 + HO2:1 N2:1 + + 2.6e+019 -1.24 0 + + + + + + H + O2 + AR [=] HO2 + AR + H:1 O2:1 AR:1 + HO2:1 AR:1 + + 7e+017 -0.8 0 + + + + + + H + O2 [=] O + OH + H:1 O2:1 + O:1 OH:1 + + 2.65e+016 -0.6707 17041 + + + + + + 2 H + M [=] H2 + M + H:2 + H2:1 + + 1e+018 -1 0 + + AR:0.63 C2H6:3 CH4:2 CO2:0 H2:0 H2O:0 + + + + + + + 2 H + H2 [=] 2 H2 + H:2 H2:1 + H2:2 + + 9e+016 -0.6 0 + + + + + + 2 H + H2O [=] H2 + H2O + H:2 H2O:1 + H2:1 H2O:1 + + 6e+019 -1.25 0 + + + + + + 2 H + CO2 [=] H2 + CO2 + H:2 CO2:1 + H2:1 CO2:1 + + 5.5e+020 -2 0 + + + + + + H + OH + M [=] H2O + M + H:1 OH:1 + H2O:1 + + 2.2e+022 -2 0 + + AR:0.38 C2H6:3 CH4:2 H2:0.73 H2O:3.65 + + + + + + + H + HO2 [=] O + H2O + H:1 HO2:1 + O:1 H2O:1 + + 3.97e+012 0 671 + + + + + + H + HO2 [=] O2 + H2 + H:1 HO2:1 + O2:1 H2:1 + + 4.48e+013 0 1068 + + + + + + H + HO2 [=] 2 OH + H:1 HO2:1 + OH:2 + + 8.4e+013 0 635 + + + + + + H + H2O2 [=] HO2 + H2 + H:1 H2O2:1 + HO2:1 H2:1 + + 1.21e+007 2 5200 + + + + + + H + H2O2 [=] OH + H2O + H:1 H2O2:1 + OH:1 H2O:1 + + 1e+013 0 3600 + + + + + + H + CH [=] C + H2 + H:1 CH:1 + C:1 H2:1 + + 1.65e+014 0 0 + + + + + + H + CH2 (+ M) [=] CH3 (+ M) + H:1 CH2:1 + CH3:1 + + 6e+014 0 0 + 1.04e+026 -2.76 1600 + 0.562 91 5836 8552 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + CH2(S) [=] CH + H2 + H:1 CH2(S):1 + CH:1 H2:1 + + 3e+013 0 0 + + + + + + H + CH3 (+ M) [=] CH4 (+ M) + H:1 CH3:1 + CH4:1 + + 1.39e+016 -0.534 536 + 2.62e+033 -4.76 2440 + 0.783 74 2941 6964 + + AR:0.7 C2H6:3 CH4:3 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + CH4 [=] CH3 + H2 + H:1 CH4:1 + CH3:1 H2:1 + + 6.6e+008 1.62 10840 + + + + + + H + HCO (+ M) [=] CH2O (+ M) + H:1 HCO:1 + CH2O:1 + + 1.09e+012 0.48 -260 + 2.47e+024 -2.57 425 + 0.7824 271 2755 6570 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + HCO [=] H2 + CO + H:1 HCO:1 + H2:1 CO:1 + + 7.34e+013 0 0 + + + + + + H + CH2O (+ M) [=] CH2OH (+ M) + H:1 CH2O:1 + CH2OH:1 + + 5.4e+011 0.454 3600 + 1.27e+032 -4.82 6530 + 0.7187 103 1291 4160 + + C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + CH2O (+ M) [=] CH3O (+ M) + H:1 CH2O:1 + CH3O:1 + + 5.4e+011 0.454 2600 + 2.2e+030 -4.8 5560 + 0.758 94 1555 4200 + + C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + CH2O [=] HCO + H2 + H:1 CH2O:1 + HCO:1 H2:1 + + 5.74e+007 1.9 2742 + + + + + + H + CH2OH (+ M) [=] CH3OH (+ M) + H:1 CH2OH:1 + CH3OH:1 + + 1.055e+012 0.5 86 + 4.36e+031 -4.65 5080 + 0.6 100 90000 10000 + + C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + CH2OH [=] H2 + CH2O + H:1 CH2OH:1 + H2:1 CH2O:1 + + 2e+013 0 0 + + + + + + H + CH2OH [=] OH + CH3 + H:1 CH2OH:1 + OH:1 CH3:1 + + 1.65e+011 0.65 -284 + + + + + + H + CH2OH [=] CH2(S) + H2O + H:1 CH2OH:1 + CH2(S):1 H2O:1 + + 3.28e+013 -0.09 610 + + + + + + H + CH3O (+ M) [=] CH3OH (+ M) + H:1 CH3O:1 + CH3OH:1 + + 2.43e+012 0.515 50 + 4.66e+041 -7.44 14080 + 0.7 100 90000 10000 + + C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + CH3O [=] H + CH2OH + H:1 CH3O:1 + H:1 CH2OH:1 + + 4.15e+007 1.63 1924 + + + + + + H + CH3O [=] H2 + CH2O + H:1 CH3O:1 + H2:1 CH2O:1 + + 2e+013 0 0 + + + + + + H + CH3O [=] OH + CH3 + H:1 CH3O:1 + OH:1 CH3:1 + + 1.5e+012 0.5 -110 + + + + + + H + CH3O [=] CH2(S) + H2O + H:1 CH3O:1 + CH2(S):1 H2O:1 + + 2.62e+014 -0.23 1070 + + + + + + H + CH3OH [=] CH2OH + H2 + H:1 CH3OH:1 + CH2OH:1 H2:1 + + 1.7e+007 2.1 4870 + + + + + + H + CH3OH [=] CH3O + H2 + H:1 CH3OH:1 + CH3O:1 H2:1 + + 4.2e+006 2.1 4870 + + + + + + H + C2H (+ M) [=] C2H2 (+ M) + H:1 C2H:1 + C2H2:1 + + 1e+017 -1 0 + 3.75e+033 -4.8 1900 + 0.6464 132 1315 5566 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + C2H2 (+ M) [=] C2H3 (+ M) + H:1 C2H2:1 + C2H3:1 + + 5.6e+012 0 2400 + 3.8e+040 -7.27 7220 + 0.7507 98.5 1302 4167 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + C2H3 (+ M) [=] C2H4 (+ M) + H:1 C2H3:1 + C2H4:1 + + 6.08e+012 0.27 280 + 1.4e+030 -3.86 3320 + 0.782 207.5 2663 6095 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + C2H3 [=] H2 + C2H2 + H:1 C2H3:1 + H2:1 C2H2:1 + + 3e+013 0 0 + + + + + + H + C2H4 (+ M) [=] C2H5 (+ M) + H:1 C2H4:1 + C2H5:1 + + 5.4e+011 0.454 1820 + 6e+041 -7.62 6970 + 0.9753 210 984 4374 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + C2H4 [=] C2H3 + H2 + H:1 C2H4:1 + C2H3:1 H2:1 + + 1.325e+006 2.53 12240 + + + + + + H + C2H5 (+ M) [=] C2H6 (+ M) + H:1 C2H5:1 + C2H6:1 + + 5.21e+017 -0.99 1580 + 1.99e+041 -7.08 6685 + 0.8422 125 2219 6882 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + C2H5 [=] H2 + C2H4 + H:1 C2H5:1 + H2:1 C2H4:1 + + 2e+012 0 0 + + + + + + H + C2H6 [=] C2H5 + H2 + H:1 C2H6:1 + C2H5:1 H2:1 + + 1.15e+008 1.9 7530 + + + + + + H + HCCO [=] CH2(S) + CO + H:1 HCCO:1 + CH2(S):1 CO:1 + + 1e+014 0 0 + + + + + + H + CH2CO [=] HCCO + H2 + H:1 CH2CO:1 + HCCO:1 H2:1 + + 5e+013 0 8000 + + + + + + H + CH2CO [=] CH3 + CO + H:1 CH2CO:1 + CH3:1 CO:1 + + 1.13e+013 0 3428 + + + + + + H + HCCOH [=] H + CH2CO + H:1 HCCOH:1 + H:1 CH2CO:1 + + 1e+013 0 0 + + + + + + H2 + CO (+ M) [=] CH2O (+ M) + H2:1 CO:1 + CH2O:1 + + 4.3e+007 1.5 79600 + 5.07e+027 -3.42 84350 + 0.932 197 1540 10300 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + OH + H2 [=] H + H2O + OH:1 H2:1 + H:1 H2O:1 + + 2.16e+008 1.51 3430 + + + + + + 2 OH (+ M) [=] H2O2 (+ M) + OH:2 + H2O2:1 + + 7.4e+013 -0.37 0 + 2.3e+018 -0.9 -1700 + 0.7346 94 1756 5182 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + 2 OH [=] O + H2O + OH:2 + O:1 H2O:1 + + 35700 2.4 -2110 + + + + + + OH + HO2 [=] O2 + H2O + OH:1 HO2:1 + O2:1 H2O:1 + + 1.45e+013 0 -500 + + idtag_rxn_287 + + + + + OH + H2O2 [=] HO2 + H2O + OH:1 H2O2:1 + HO2:1 H2O:1 + + 2e+012 0 427 + + idtag_rxn_89 + + + + + OH + H2O2 [=] HO2 + H2O + OH:1 H2O2:1 + HO2:1 H2O:1 + + 1.7e+018 0 29410 + + idtag_rxn_88 + + + + + OH + C [=] H + CO + OH:1 C:1 + H:1 CO:1 + + 5e+013 0 0 + + + + + + OH + CH [=] H + HCO + OH:1 CH:1 + H:1 HCO:1 + + 3e+013 0 0 + + + + + + OH + CH2 [=] H + CH2O + OH:1 CH2:1 + H:1 CH2O:1 + + 2e+013 0 0 + + + + + + OH + CH2 [=] CH + H2O + OH:1 CH2:1 + CH:1 H2O:1 + + 1.13e+007 2 3000 + + + + + + OH + CH2(S) [=] H + CH2O + OH:1 CH2(S):1 + H:1 CH2O:1 + + 3e+013 0 0 + + + + + + OH + CH3 (+ M) [=] CH3OH (+ M) + OH:1 CH3:1 + CH3OH:1 + + 2.79e+018 -1.43 1330 + 4e+036 -5.92 3140 + 0.412 195 5900 6394 + + C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + OH + CH3 [=] CH2 + H2O + OH:1 CH3:1 + CH2:1 H2O:1 + + 5.6e+007 1.6 5420 + + + + + + OH + CH3 [=] CH2(S) + H2O + OH:1 CH3:1 + CH2(S):1 H2O:1 + + 6.44e+017 -1.34 1417 + + + + + + OH + CH4 [=] CH3 + H2O + OH:1 CH4:1 + CH3:1 H2O:1 + + 1e+008 1.6 3120 + + + + + + OH + CO [=] H + CO2 + OH:1 CO:1 + H:1 CO2:1 + + 4.76e+007 1.228 70 + + + + + + OH + HCO [=] H2O + CO + OH:1 HCO:1 + H2O:1 CO:1 + + 5e+013 0 0 + + + + + + OH + CH2O [=] HCO + H2O + OH:1 CH2O:1 + HCO:1 H2O:1 + + 3.43e+009 1.18 -447 + + + + + + OH + CH2OH [=] H2O + CH2O + OH:1 CH2OH:1 + H2O:1 CH2O:1 + + 5e+012 0 0 + + + + + + OH + CH3O [=] H2O + CH2O + OH:1 CH3O:1 + H2O:1 CH2O:1 + + 5e+012 0 0 + + + + + + OH + CH3OH [=] CH2OH + H2O + OH:1 CH3OH:1 + CH2OH:1 H2O:1 + + 1.44e+006 2 -840 + + + + + + OH + CH3OH [=] CH3O + H2O + OH:1 CH3OH:1 + CH3O:1 H2O:1 + + 6.3e+006 2 1500 + + + + + + OH + C2H [=] H + HCCO + OH:1 C2H:1 + H:1 HCCO:1 + + 2e+013 0 0 + + + + + + OH + C2H2 [=] H + CH2CO + OH:1 C2H2:1 + H:1 CH2CO:1 + + 0.000218 4.5 -1000 + + + + + + OH + C2H2 [=] H + HCCOH + OH:1 C2H2:1 + H:1 HCCOH:1 + + 504000 2.3 13500 + + + + + + OH + C2H2 [=] C2H + H2O + OH:1 C2H2:1 + C2H:1 H2O:1 + + 3.37e+007 2 14000 + + + + + + OH + C2H2 [=] CH3 + CO + OH:1 C2H2:1 + CH3:1 CO:1 + + 0.000483 4 -2000 + + + + + + OH + C2H3 [=] H2O + C2H2 + OH:1 C2H3:1 + H2O:1 C2H2:1 + + 5e+012 0 0 + + + + + + OH + C2H4 [=] C2H3 + H2O + OH:1 C2H4:1 + C2H3:1 H2O:1 + + 3.6e+006 2 2500 + + + + + + OH + C2H6 [=] C2H5 + H2O + OH:1 C2H6:1 + C2H5:1 H2O:1 + + 3.54e+006 2.12 870 + + + + + + OH + CH2CO [=] HCCO + H2O + OH:1 CH2CO:1 + HCCO:1 H2O:1 + + 7.5e+012 0 2000 + + + + + + 2 HO2 [=] O2 + H2O2 + HO2:2 + O2:1 H2O2:1 + + 1.3e+011 0 -1630 + + idtag_rxn_116 + + + + + 2 HO2 [=] O2 + H2O2 + HO2:2 + O2:1 H2O2:1 + + 4.2e+014 0 12000 + + idtag_rxn_115 + + + + + HO2 + CH2 [=] OH + CH2O + HO2:1 CH2:1 + OH:1 CH2O:1 + + 2e+013 0 0 + + + + + + HO2 + CH3 [=] O2 + CH4 + HO2:1 CH3:1 + O2:1 CH4:1 + + 1e+012 0 0 + + + + + + HO2 + CH3 [=] OH + CH3O + HO2:1 CH3:1 + OH:1 CH3O:1 + + 3.78e+013 0 0 + + + + + + HO2 + CO [=] OH + CO2 + HO2:1 CO:1 + OH:1 CO2:1 + + 1.5e+014 0 23600 + + + + + + HO2 + CH2O [=] HCO + H2O2 + HO2:1 CH2O:1 + HCO:1 H2O2:1 + + 5.6e+006 2 12000 + + + + + + C + O2 [=] O + CO + C:1 O2:1 + O:1 CO:1 + + 5.8e+013 0 576 + + + + + + C + CH2 [=] H + C2H + C:1 CH2:1 + H:1 C2H:1 + + 5e+013 0 0 + + + + + + C + CH3 [=] H + C2H2 + C:1 CH3:1 + H:1 C2H2:1 + + 5e+013 0 0 + + + + + + CH + O2 [=] O + HCO + CH:1 O2:1 + O:1 HCO:1 + + 6.71e+013 0 0 + + + + + + CH + H2 [=] H + CH2 + CH:1 H2:1 + H:1 CH2:1 + + 1.08e+014 0 3110 + + + + + + CH + H2O [=] H + CH2O + CH:1 H2O:1 + H:1 CH2O:1 + + 5.71e+012 0 -755 + + + + + + CH + CH2 [=] H + C2H2 + CH:1 CH2:1 + H:1 C2H2:1 + + 4e+013 0 0 + + + + + + CH + CH3 [=] H + C2H3 + CH:1 CH3:1 + H:1 C2H3:1 + + 3e+013 0 0 + + + + + + CH + CH4 [=] H + C2H4 + CH:1 CH4:1 + H:1 C2H4:1 + + 6e+013 0 0 + + + + + + CH + CO (+ M) [=] HCCO (+ M) + CH:1 CO:1 + HCCO:1 + + 5e+013 0 0 + 2.69e+028 -3.74 1936 + 0.5757 237 1652 5069 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + CH + CO2 [=] HCO + CO + CH:1 CO2:1 + HCO:1 CO:1 + + 1.9e+014 0 15792 + + + + + + CH + CH2O [=] H + CH2CO + CH:1 CH2O:1 + H:1 CH2CO:1 + + 9.46e+013 0 -515 + + + + + + CH + HCCO [=] CO + C2H2 + CH:1 HCCO:1 + CO:1 C2H2:1 + + 5e+013 0 0 + + + + + + CH2 + O2 =] OH + H + CO + CH2:1 O2:1 + OH:1 H:1 CO:1 + + 5e+012 0 1500 + + + + + + CH2 + H2 [=] H + CH3 + CH2:1 H2:1 + H:1 CH3:1 + + 500000 2 7230 + + + + + + 2 CH2 [=] H2 + C2H2 + CH2:2 + H2:1 C2H2:1 + + 1.6e+015 0 11944 + + + + + + CH2 + CH3 [=] H + C2H4 + CH2:1 CH3:1 + H:1 C2H4:1 + + 4e+013 0 0 + + + + + + CH2 + CH4 [=] 2 CH3 + CH2:1 CH4:1 + CH3:2 + + 2.46e+006 2 8270 + + + + + + CH2 + CO (+ M) [=] CH2CO (+ M) + CH2:1 CO:1 + CH2CO:1 + + 8.1e+011 0.5 4510 + 2.69e+033 -5.11 7095 + 0.5907 275 1226 5185 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + CH2 + HCCO [=] C2H3 + CO + CH2:1 HCCO:1 + C2H3:1 CO:1 + + 3e+013 0 0 + + + + + + CH2(S) + N2 [=] CH2 + N2 + CH2(S):1 N2:1 + CH2:1 N2:1 + + 1.5e+013 0 600 + + + + + + CH2(S) + AR [=] CH2 + AR + CH2(S):1 AR:1 + CH2:1 AR:1 + + 9e+012 0 600 + + + + + + CH2(S) + O2 [=] H + OH + CO + CH2(S):1 O2:1 + H:1 OH:1 CO:1 + + 2.8e+013 0 0 + + + + + + CH2(S) + O2 [=] CO + H2O + CH2(S):1 O2:1 + CO:1 H2O:1 + + 1.2e+013 0 0 + + + + + + CH2(S) + H2 [=] CH3 + H + CH2(S):1 H2:1 + CH3:1 H:1 + + 7e+013 0 0 + + + + + + CH2(S) + H2O (+ M) [=] CH3OH (+ M) + CH2(S):1 H2O:1 + CH3OH:1 + + 4.82e+017 -1.16 1145 + 1.88e+038 -6.36 5040 + 0.6027 208 3922 10180 + + C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + CH2(S) + H2O [=] CH2 + H2O + CH2(S):1 H2O:1 + CH2:1 H2O:1 + + 3e+013 0 0 + + + + + + CH2(S) + CH3 [=] H + C2H4 + CH2(S):1 CH3:1 + H:1 C2H4:1 + + 1.2e+013 0 -570 + + + + + + CH2(S) + CH4 [=] 2 CH3 + CH2(S):1 CH4:1 + CH3:2 + + 1.6e+013 0 -570 + + + + + + CH2(S) + CO [=] CH2 + CO + CH2(S):1 CO:1 + CH2:1 CO:1 + + 9e+012 0 0 + + + + + + CH2(S) + CO2 [=] CH2 + CO2 + CH2(S):1 CO2:1 + CH2:1 CO2:1 + + 7e+012 0 0 + + + + + + CH2(S) + CO2 [=] CO + CH2O + CH2(S):1 CO2:1 + CO:1 CH2O:1 + + 1.4e+013 0 0 + + + + + + CH2(S) + C2H6 [=] CH3 + C2H5 + CH2(S):1 C2H6:1 + CH3:1 C2H5:1 + + 4e+013 0 -550 + + + + + + CH3 + O2 [=] O + CH3O + CH3:1 O2:1 + O:1 CH3O:1 + + 3.56e+013 0 30480 + + + + + + CH3 + O2 [=] OH + CH2O + CH3:1 O2:1 + OH:1 CH2O:1 + + 2.31e+012 0 20315 + + + + + + CH3 + H2O2 [=] HO2 + CH4 + CH3:1 H2O2:1 + HO2:1 CH4:1 + + 24500 2.47 5180 + + + + + + 2 CH3 (+ M) [=] C2H6 (+ M) + CH3:2 + C2H6:1 + + 6.77e+016 -1.18 654 + 3.4e+041 -7.03 2762 + 0.619 73.2 1180 9999 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + 2 CH3 [=] H + C2H5 + CH3:2 + H:1 C2H5:1 + + 6.84e+012 0.1 10600 + + + + + + CH3 + HCO [=] CH4 + CO + CH3:1 HCO:1 + CH4:1 CO:1 + + 2.648e+013 0 0 + + + + + + CH3 + CH2O [=] HCO + CH4 + CH3:1 CH2O:1 + HCO:1 CH4:1 + + 3320 2.81 5860 + + + + + + CH3 + CH3OH [=] CH2OH + CH4 + CH3:1 CH3OH:1 + CH2OH:1 CH4:1 + + 3e+007 1.5 9940 + + + + + + CH3 + CH3OH [=] CH3O + CH4 + CH3:1 CH3OH:1 + CH3O:1 CH4:1 + + 1e+007 1.5 9940 + + + + + + CH3 + C2H4 [=] C2H3 + CH4 + CH3:1 C2H4:1 + C2H3:1 CH4:1 + + 227000 2 9200 + + + + + + CH3 + C2H6 [=] C2H5 + CH4 + CH3:1 C2H6:1 + C2H5:1 CH4:1 + + 6.14e+006 1.74 10450 + + + + + + HCO + H2O [=] H + CO + H2O + HCO:1 H2O:1 + H:1 CO:1 H2O:1 + + 1.5e+018 -1 17000 + + + + + + HCO + M [=] H + CO + M + HCO:1 + H:1 CO:1 + + 1.87e+017 -1 17000 + + C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:0 + + + + + + + HCO + O2 [=] HO2 + CO + HCO:1 O2:1 + HO2:1 CO:1 + + 1.345e+013 0 400 + + + + + + CH2OH + O2 [=] HO2 + CH2O + CH2OH:1 O2:1 + HO2:1 CH2O:1 + + 1.8e+013 0 900 + + + + + + CH3O + O2 [=] HO2 + CH2O + CH3O:1 O2:1 + HO2:1 CH2O:1 + + 4.28e-013 7.6 -3530 + + + + + + C2H + O2 [=] HCO + CO + C2H:1 O2:1 + HCO:1 CO:1 + + 1e+013 0 -755 + + + + + + C2H + H2 [=] H + C2H2 + C2H:1 H2:1 + H:1 C2H2:1 + + 5.68e+010 0.9 1993 + + + + + + C2H3 + O2 [=] HCO + CH2O + C2H3:1 O2:1 + HCO:1 CH2O:1 + + 4.58e+016 -1.39 1015 + + + + + + C2H4 (+ M) [=] H2 + C2H2 (+ M) + C2H4:1 + H2:1 C2H2:1 + + 8e+012 0.44 86770 + 1.58e+051 -9.3 97800 + 0.7345 180 1035 5417 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + C2H5 + O2 [=] HO2 + C2H4 + C2H5:1 O2:1 + HO2:1 C2H4:1 + + 8.4e+011 0 3875 + + + + + + HCCO + O2 [=] OH + 2 CO + HCCO:1 O2:1 + OH:1 CO:2 + + 3.2e+012 0 854 + + + + + + 2 HCCO [=] 2 CO + C2H2 + HCCO:2 + CO:2 C2H2:1 + + 1e+013 0 0 + + + + + + N + NO [=] N2 + O + N:1 NO:1 + N2:1 O:1 + + 2.7e+013 0 355 + + + + + + N + O2 [=] NO + O + N:1 O2:1 + NO:1 O:1 + + 9e+009 1 6500 + + + + + + N + OH [=] NO + H + N:1 OH:1 + NO:1 H:1 + + 3.36e+013 0 385 + + + + + + N2O + O [=] N2 + O2 + N2O:1 O:1 + N2:1 O2:1 + + 1.4e+012 0 10810 + + + + + + N2O + O [=] 2 NO + N2O:1 O:1 + NO:2 + + 2.9e+013 0 23150 + + + + + + N2O + H [=] N2 + OH + N2O:1 H:1 + N2:1 OH:1 + + 3.87e+014 0 18880 + + + + + + N2O + OH [=] N2 + HO2 + N2O:1 OH:1 + N2:1 HO2:1 + + 2e+012 0 21060 + + + + + + N2O (+ M) [=] N2 + O (+ M) + N2O:1 + N2:1 O:1 + + 7.91e+010 0 56020 + 6.37e+014 0 56640 + + + AR:0.625 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + HO2 + NO [=] NO2 + OH + HO2:1 NO:1 + NO2:1 OH:1 + + 2.11e+012 0 -480 + + + + + + NO + O + M [=] NO2 + M + NO:1 O:1 + NO2:1 + + 1.06e+020 -1.41 0 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + NO2 + O [=] NO + O2 + NO2:1 O:1 + NO:1 O2:1 + + 3.9e+012 0 -240 + + + + + + NO2 + H [=] NO + OH + NO2:1 H:1 + NO:1 OH:1 + + 1.32e+014 0 360 + + + + + + NH + O [=] NO + H + NH:1 O:1 + NO:1 H:1 + + 4e+013 0 0 + + + + + + NH + H [=] N + H2 + NH:1 H:1 + N:1 H2:1 + + 3.2e+013 0 330 + + + + + + NH + OH [=] HNO + H + NH:1 OH:1 + HNO:1 H:1 + + 2e+013 0 0 + + + + + + NH + OH [=] N + H2O + NH:1 OH:1 + N:1 H2O:1 + + 2e+009 1.2 0 + + + + + + NH + O2 [=] HNO + O + NH:1 O2:1 + HNO:1 O:1 + + 461000 2 6500 + + + + + + NH + O2 [=] NO + OH + NH:1 O2:1 + NO:1 OH:1 + + 1.28e+006 1.5 100 + + + + + + NH + N [=] N2 + H + NH:1 N:1 + N2:1 H:1 + + 1.5e+013 0 0 + + + + + + NH + H2O [=] HNO + H2 + NH:1 H2O:1 + HNO:1 H2:1 + + 2e+013 0 13850 + + + + + + NH + NO [=] N2 + OH + NH:1 NO:1 + N2:1 OH:1 + + 2.16e+013 -0.23 0 + + + + + + NH + NO [=] N2O + H + NH:1 NO:1 + N2O:1 H:1 + + 3.65e+014 -0.45 0 + + + + + + NH2 + O [=] OH + NH + NH2:1 O:1 + OH:1 NH:1 + + 3e+012 0 0 + + + + + + NH2 + O [=] H + HNO + NH2:1 O:1 + H:1 HNO:1 + + 3.9e+013 0 0 + + + + + + NH2 + H [=] NH + H2 + NH2:1 H:1 + NH:1 H2:1 + + 4e+013 0 3650 + + + + + + NH2 + OH [=] NH + H2O + NH2:1 OH:1 + NH:1 H2O:1 + + 9e+007 1.5 -460 + + + + + + NNH [=] N2 + H + NNH:1 + N2:1 H:1 + + 3.3e+008 0 0 + + + + + + NNH + M [=] N2 + H + M + NNH:1 + N2:1 H:1 + + 1.3e+014 -0.11 4980 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + NNH + O2 [=] HO2 + N2 + NNH:1 O2:1 + HO2:1 N2:1 + + 5e+012 0 0 + + + + + + NNH + O [=] OH + N2 + NNH:1 O:1 + OH:1 N2:1 + + 2.5e+013 0 0 + + + + + + NNH + O [=] NH + NO + NNH:1 O:1 + NH:1 NO:1 + + 7e+013 0 0 + + + + + + NNH + H [=] H2 + N2 + NNH:1 H:1 + H2:1 N2:1 + + 5e+013 0 0 + + + + + + NNH + OH [=] H2O + N2 + NNH:1 OH:1 + H2O:1 N2:1 + + 2e+013 0 0 + + + + + + NNH + CH3 [=] CH4 + N2 + NNH:1 CH3:1 + CH4:1 N2:1 + + 2.5e+013 0 0 + + + + + + H + NO + M [=] HNO + M + H:1 NO:1 + HNO:1 + + 4.48e+019 -1.32 740 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + HNO + O [=] NO + OH + HNO:1 O:1 + NO:1 OH:1 + + 2.5e+013 0 0 + + + + + + HNO + H [=] H2 + NO + HNO:1 H:1 + H2:1 NO:1 + + 9e+011 0.72 660 + + + + + + HNO + OH [=] NO + H2O + HNO:1 OH:1 + NO:1 H2O:1 + + 1.3e+007 1.9 -950 + + + + + + HNO + O2 [=] HO2 + NO + HNO:1 O2:1 + HO2:1 NO:1 + + 1e+013 0 13000 + + + + + + CN + O [=] CO + N + CN:1 O:1 + CO:1 N:1 + + 7.7e+013 0 0 + + + + + + CN + OH [=] NCO + H + CN:1 OH:1 + NCO:1 H:1 + + 4e+013 0 0 + + + + + + CN + H2O [=] HCN + OH + CN:1 H2O:1 + HCN:1 OH:1 + + 8e+012 0 7460 + + + + + + CN + O2 [=] NCO + O + CN:1 O2:1 + NCO:1 O:1 + + 6.14e+012 0 -440 + + + + + + CN + H2 [=] HCN + H + CN:1 H2:1 + HCN:1 H:1 + + 295000 2.45 2240 + + + + + + NCO + O [=] NO + CO + NCO:1 O:1 + NO:1 CO:1 + + 2.35e+013 0 0 + + + + + + NCO + H [=] NH + CO + NCO:1 H:1 + NH:1 CO:1 + + 5.4e+013 0 0 + + + + + + NCO + OH [=] NO + H + CO + NCO:1 OH:1 + NO:1 H:1 CO:1 + + 2.5e+012 0 0 + + + + + + NCO + N [=] N2 + CO + NCO:1 N:1 + N2:1 CO:1 + + 2e+013 0 0 + + + + + + NCO + O2 [=] NO + CO2 + NCO:1 O2:1 + NO:1 CO2:1 + + 2e+012 0 20000 + + + + + + NCO + M [=] N + CO + M + NCO:1 + N:1 CO:1 + + 3.1e+014 0 54050 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + NCO + NO [=] N2O + CO + NCO:1 NO:1 + N2O:1 CO:1 + + 1.9e+017 -1.52 740 + + + + + + NCO + NO [=] N2 + CO2 + NCO:1 NO:1 + N2:1 CO2:1 + + 3.8e+018 -2 800 + + + + + + HCN + M [=] H + CN + M + HCN:1 + H:1 CN:1 + + 1.04e+029 -3.3 126600 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + HCN + O [=] NCO + H + HCN:1 O:1 + NCO:1 H:1 + + 20300 2.64 4980 + + + + + + HCN + O [=] NH + CO + HCN:1 O:1 + NH:1 CO:1 + + 5070 2.64 4980 + + + + + + HCN + O [=] CN + OH + HCN:1 O:1 + CN:1 OH:1 + + 3.91e+009 1.58 26600 + + + + + + HCN + OH [=] HOCN + H + HCN:1 OH:1 + HOCN:1 H:1 + + 1.1e+006 2.03 13370 + + + + + + HCN + OH [=] HNCO + H + HCN:1 OH:1 + HNCO:1 H:1 + + 4400 2.26 6400 + + + + + + HCN + OH [=] NH2 + CO + HCN:1 OH:1 + NH2:1 CO:1 + + 160 2.56 9000 + + + + + + H + HCN (+ M) [=] H2CN (+ M) + H:1 HCN:1 + H2CN:1 + + 3.3e+013 0 0 + 1.4e+026 -3.4 1900 + + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H2CN + N [=] N2 + CH2 + H2CN:1 N:1 + N2:1 CH2:1 + + 6e+013 0 400 + + + + + + C + N2 [=] CN + N + C:1 N2:1 + CN:1 N:1 + + 6.3e+013 0 46020 + + + + + + CH + N2 [=] HCN + N + CH:1 N2:1 + HCN:1 N:1 + + 3.12e+009 0.88 20130 + + + + + + CH + N2 (+ M) [=] HCNN (+ M) + CH:1 N2:1 + HCNN:1 + + 3.1e+012 0.15 0 + 1.3e+025 -3.16 740 + 0.667 235 2117 4536 + + AR:1 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + CH2 + N2 [=] HCN + NH + CH2:1 N2:1 + HCN:1 NH:1 + + 1e+013 0 74000 + + + + + + CH2(S) + N2 [=] NH + HCN + CH2(S):1 N2:1 + NH:1 HCN:1 + + 1e+011 0 65000 + + + + + + C + NO [=] CN + O + C:1 NO:1 + CN:1 O:1 + + 1.9e+013 0 0 + + + + + + C + NO [=] CO + N + C:1 NO:1 + CO:1 N:1 + + 2.9e+013 0 0 + + + + + + CH + NO [=] HCN + O + CH:1 NO:1 + HCN:1 O:1 + + 4.1e+013 0 0 + + + + + + CH + NO [=] H + NCO + CH:1 NO:1 + H:1 NCO:1 + + 1.62e+013 0 0 + + + + + + CH + NO [=] N + HCO + CH:1 NO:1 + N:1 HCO:1 + + 2.46e+013 0 0 + + + + + + CH2 + NO [=] H + HNCO + CH2:1 NO:1 + H:1 HNCO:1 + + 3.1e+017 -1.38 1270 + + + + + + CH2 + NO [=] OH + HCN + CH2:1 NO:1 + OH:1 HCN:1 + + 2.9e+014 -0.69 760 + + + + + + CH2 + NO [=] H + HCNO + CH2:1 NO:1 + H:1 HCNO:1 + + 3.8e+013 -0.36 580 + + + + + + CH2(S) + NO [=] H + HNCO + CH2(S):1 NO:1 + H:1 HNCO:1 + + 3.1e+017 -1.38 1270 + + + + + + CH2(S) + NO [=] OH + HCN + CH2(S):1 NO:1 + OH:1 HCN:1 + + 2.9e+014 -0.69 760 + + + + + + CH2(S) + NO [=] H + HCNO + CH2(S):1 NO:1 + H:1 HCNO:1 + + 3.8e+013 -0.36 580 + + + + + + CH3 + NO [=] HCN + H2O + CH3:1 NO:1 + HCN:1 H2O:1 + + 9.6e+013 0 28800 + + + + + + CH3 + NO [=] H2CN + OH + CH3:1 NO:1 + H2CN:1 OH:1 + + 1e+012 0 21750 + + + + + + HCNN + O [=] CO + H + N2 + HCNN:1 O:1 + CO:1 H:1 N2:1 + + 2.2e+013 0 0 + + + + + + HCNN + O [=] HCN + NO + HCNN:1 O:1 + HCN:1 NO:1 + + 2e+012 0 0 + + + + + + HCNN + O2 [=] O + HCO + N2 + HCNN:1 O2:1 + O:1 HCO:1 N2:1 + + 1.2e+013 0 0 + + + + + + HCNN + OH [=] H + HCO + N2 + HCNN:1 OH:1 + H:1 HCO:1 N2:1 + + 1.2e+013 0 0 + + + + + + HCNN + H [=] CH2 + N2 + HCNN:1 H:1 + CH2:1 N2:1 + + 1e+014 0 0 + + + + + + HNCO + O [=] NH + CO2 + HNCO:1 O:1 + NH:1 CO2:1 + + 9.8e+007 1.41 8500 + + + + + + HNCO + O [=] HNO + CO + HNCO:1 O:1 + HNO:1 CO:1 + + 1.5e+008 1.57 44000 + + + + + + HNCO + O [=] NCO + OH + HNCO:1 O:1 + NCO:1 OH:1 + + 2.2e+006 2.11 11400 + + + + + + HNCO + H [=] NH2 + CO + HNCO:1 H:1 + NH2:1 CO:1 + + 2.25e+007 1.7 3800 + + + + + + HNCO + H [=] H2 + NCO + HNCO:1 H:1 + H2:1 NCO:1 + + 105000 2.5 13300 + + + + + + HNCO + OH [=] NCO + H2O + HNCO:1 OH:1 + NCO:1 H2O:1 + + 3.3e+007 1.5 3600 + + + + + + HNCO + OH [=] NH2 + CO2 + HNCO:1 OH:1 + NH2:1 CO2:1 + + 3.3e+006 1.5 3600 + + + + + + HNCO + M [=] NH + CO + M + HNCO:1 + NH:1 CO:1 + + 1.18e+016 0 84720 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + HCNO + H [=] H + HNCO + HCNO:1 H:1 + H:1 HNCO:1 + + 2.1e+015 -0.69 2850 + + + + + + HCNO + H [=] OH + HCN + HCNO:1 H:1 + OH:1 HCN:1 + + 2.7e+011 0.18 2120 + + + + + + HCNO + H [=] NH2 + CO + HCNO:1 H:1 + NH2:1 CO:1 + + 1.7e+014 -0.75 2890 + + + + + + HOCN + H [=] H + HNCO + HOCN:1 H:1 + H:1 HNCO:1 + + 2e+007 2 2000 + + + + + + HCCO + NO [=] HCNO + CO + HCCO:1 NO:1 + HCNO:1 CO:1 + + 9e+012 0 0 + + + + + + CH3 + N [=] H2CN + H + CH3:1 N:1 + H2CN:1 H:1 + + 6.1e+014 -0.31 290 + + + + + + CH3 + N [=] HCN + H2 + CH3:1 N:1 + HCN:1 H2:1 + + 3.7e+012 0.15 -90 + + + + + + NH3 + H [=] NH2 + H2 + NH3:1 H:1 + NH2:1 H2:1 + + 540000 2.4 9915 + + + + + + NH3 + OH [=] NH2 + H2O + NH3:1 OH:1 + NH2:1 H2O:1 + + 5e+007 1.6 955 + + + + + + NH3 + O [=] NH2 + OH + NH3:1 O:1 + NH2:1 OH:1 + + 9.4e+006 1.94 6460 + + + + + + NH + CO2 [=] HNO + CO + NH:1 CO2:1 + HNO:1 CO:1 + + 1e+013 0 14350 + + + + + + CN + NO2 [=] NCO + NO + CN:1 NO2:1 + NCO:1 NO:1 + + 6.16e+015 -0.752 345 + + + + + + NCO + NO2 [=] N2O + CO2 + NCO:1 NO2:1 + N2O:1 CO2:1 + + 3.25e+012 0 -705 + + + + + + N + CO2 [=] NO + CO + N:1 CO2:1 + NO:1 CO:1 + + 3e+012 0 11300 + + + + + + O + CH3 =] H + H2 + CO + O:1 CH3:1 + H:1 H2:1 CO:1 + + 3.37e+013 0 0 + + + + + + O + C2H4 [=] H + CH2CHO + O:1 C2H4:1 + H:1 CH2CHO:1 + + 6.7e+006 1.83 220 + + + + + + O + C2H5 [=] H + CH3CHO + O:1 C2H5:1 + H:1 CH3CHO:1 + + 1.096e+014 0 0 + + + + + + OH + HO2 [=] O2 + H2O + OH:1 HO2:1 + O2:1 H2O:1 + + 5e+015 0 17330 + + idtag_rxn_87 + + + + + OH + CH3 =] H2 + CH2O + OH:1 CH3:1 + H2:1 CH2O:1 + + 8e+009 0.5 -1755 + + + + + + CH + H2 (+ M) [=] CH3 (+ M) + CH:1 H2:1 + CH3:1 + + 1.97e+012 0.43 -370 + 4.82e+025 -2.8 590 + 0.578 122 2535 9365 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + CH2 + O2 =] 2 H + CO2 + CH2:1 O2:1 + H:2 CO2:1 + + 5.8e+012 0 1500 + + + + + + CH2 + O2 [=] O + CH2O + CH2:1 O2:1 + O:1 CH2O:1 + + 2.4e+012 0 1500 + + + + + + CH2 + CH2 =] 2 H + C2H2 + CH2:1 CH2:1 + H:2 C2H2:1 + + 2e+014 0 10989 + + + + + + CH2(S) + H2O =] H2 + CH2O + CH2(S):1 H2O:1 + H2:1 CH2O:1 + + 6.82e+010 0.25 -935 + + + + + + C2H3 + O2 [=] O + CH2CHO + C2H3:1 O2:1 + O:1 CH2CHO:1 + + 3.03e+011 0.29 11 + + + + + + C2H3 + O2 [=] HO2 + C2H2 + C2H3:1 O2:1 + HO2:1 C2H2:1 + + 1.337e+006 1.61 -384 + + + + + + O + CH3CHO [=] OH + CH2CHO + O:1 CH3CHO:1 + OH:1 CH2CHO:1 + + 5.84e+012 0 1808 + + + + + + O + CH3CHO =] OH + CH3 + CO + O:1 CH3CHO:1 + OH:1 CH3:1 CO:1 + + 5.84e+012 0 1808 + + + + + + O2 + CH3CHO =] HO2 + CH3 + CO + O2:1 CH3CHO:1 + HO2:1 CH3:1 CO:1 + + 3.01e+013 0 39150 + + + + + + H + CH3CHO [=] CH2CHO + H2 + H:1 CH3CHO:1 + CH2CHO:1 H2:1 + + 2.05e+009 1.16 2405 + + + + + + H + CH3CHO =] CH3 + H2 + CO + H:1 CH3CHO:1 + CH3:1 H2:1 CO:1 + + 2.05e+009 1.16 2405 + + + + + + OH + CH3CHO =] CH3 + H2O + CO + OH:1 CH3CHO:1 + CH3:1 H2O:1 CO:1 + + 2.343e+010 0.73 -1113 + + + + + + HO2 + CH3CHO =] CH3 + H2O2 + CO + HO2:1 CH3CHO:1 + CH3:1 H2O2:1 CO:1 + + 3.01e+012 0 11923 + + + + + + CH3 + CH3CHO =] CH3 + CH4 + CO + CH3:1 CH3CHO:1 + CH3:1 CH4:1 CO:1 + + 2.72e+006 1.77 5920 + + + + + + H + CH2CO (+ M) [=] CH2CHO (+ M) + H:1 CH2CO:1 + CH2CHO:1 + + 4.865e+011 0.422 -1755 + 1.012e+042 -7.63 3854 + 0.465 201 1773 5333 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + O + CH2CHO =] H + CH2 + CO2 + O:1 CH2CHO:1 + H:1 CH2:1 CO2:1 + + 1.5e+014 0 0 + + + + + + O2 + CH2CHO =] OH + CO + CH2O + O2:1 CH2CHO:1 + OH:1 CO:1 CH2O:1 + + 1.81e+010 0 0 + + + + + + O2 + CH2CHO =] OH + 2 HCO + O2:1 CH2CHO:1 + OH:1 HCO:2 + + 2.35e+010 0 0 + + + + + + H + CH2CHO [=] CH3 + HCO + H:1 CH2CHO:1 + CH3:1 HCO:1 + + 2.2e+013 0 0 + + + + + + H + CH2CHO [=] CH2CO + H2 + H:1 CH2CHO:1 + CH2CO:1 H2:1 + + 1.1e+013 0 0 + + + + + + OH + CH2CHO [=] H2O + CH2CO + OH:1 CH2CHO:1 + H2O:1 CH2CO:1 + + 1.2e+013 0 0 + + + + + + OH + CH2CHO [=] HCO + CH2OH + OH:1 CH2CHO:1 + HCO:1 CH2OH:1 + + 3.01e+013 0 0 + + + + + + CH3 + C2H5 (+ M) [=] C3H8 (+ M) + CH3:1 C2H5:1 + C3H8:1 + + 9.43e+012 0 0 + 2.71e+074 -16.82 13065 + 0.1527 291 2742 7748 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + O + C3H8 [=] OH + C3H7 + O:1 C3H8:1 + OH:1 C3H7:1 + + 193000 2.68 3716 + + + + + + H + C3H8 [=] C3H7 + H2 + H:1 C3H8:1 + C3H7:1 H2:1 + + 1.32e+006 2.54 6756 + + + + + + OH + C3H8 [=] C3H7 + H2O + OH:1 C3H8:1 + C3H7:1 H2O:1 + + 3.16e+007 1.8 934 + + + + + + C3H7 + H2O2 [=] HO2 + C3H8 + C3H7:1 H2O2:1 + HO2:1 C3H8:1 + + 378 2.72 1500 + + + + + + CH3 + C3H8 [=] C3H7 + CH4 + CH3:1 C3H8:1 + C3H7:1 CH4:1 + + 0.903 3.65 7154 + + + + + + CH3 + C2H4 (+ M) [=] C3H7 (+ M) + CH3:1 C2H4:1 + C3H7:1 + + 2.55e+006 1.6 5700 + 3e+063 -14.6 18170 + 0.1894 277 8748 7891 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + O + C3H7 [=] C2H5 + CH2O + O:1 C3H7:1 + C2H5:1 CH2O:1 + + 9.64e+013 0 0 + + + + + + H + C3H7 (+ M) [=] C3H8 (+ M) + H:1 C3H7:1 + C3H8:1 + + 3.613e+013 0 0 + 4.42e+061 -13.545 11357 + 0.315 369 3285 6667 + + AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 + + + + + + + H + C3H7 [=] CH3 + C2H5 + H:1 C3H7:1 + CH3:1 C2H5:1 + + 4.06e+006 2.19 890 + + + + + + OH + C3H7 [=] C2H5 + CH2OH + OH:1 C3H7:1 + C2H5:1 CH2OH:1 + + 2.41e+013 0 0 + + + + + + HO2 + C3H7 [=] O2 + C3H8 + HO2:1 C3H7:1 + O2:1 C3H8:1 + + 2.55e+010 0.255 -943 + + + + + + HO2 + C3H7 =] OH + C2H5 + CH2O + HO2:1 C3H7:1 + OH:1 C2H5:1 CH2O:1 + + 2.41e+013 0 0 + + + + + + CH3 + C3H7 [=] 2 C2H5 + CH3:1 C3H7:1 + C2H5:2 + + 1.927e+013 -0.32 0 + + + + \ No newline at end of file diff --git a/test_problems/cxx_ex/gri30_tran.dat b/test_problems/cxx_ex/gri30_tran.dat new file mode 100644 index 000000000..c79ad37bd --- /dev/null +++ b/test_problems/cxx_ex/gri30_tran.dat @@ -0,0 +1,110 @@ +AR 0 136.500 3.330 0.000 0.000 0.000 +C 0 71.400 3.298 0.000 0.000 0.000 ! * +C2 1 97.530 3.621 0.000 1.760 4.000 +C2O 1 232.400 3.828 0.000 0.000 1.000 ! * +CN2 1 232.400 3.828 0.000 0.000 1.000 ! OIS +C2H 1 209.000 4.100 0.000 0.000 2.500 +C2H2 1 209.000 4.100 0.000 0.000 2.500 +C2H2OH 2 224.700 4.162 0.000 0.000 1.000 ! * +C2H3 2 209.000 4.100 0.000 0.000 1.000 ! * +C2H4 2 280.800 3.971 0.000 0.000 1.500 +C2H5 2 252.300 4.302 0.000 0.000 1.500 +C2H6 2 252.300 4.302 0.000 0.000 1.500 +C2N 1 232.400 3.828 0.000 0.000 1.000 ! OIS +C2N2 1 349.000 4.361 0.000 0.000 1.000 ! OIS +C3H2 2 209.000 4.100 0.000 0.000 1.000 ! * +C3H4 1 252.000 4.760 0.000 0.000 1.000 +C3H6 2 266.800 4.982 0.000 0.000 1.000 +C3H7 2 266.800 4.982 0.000 0.000 1.000 +C4H6 2 357.000 5.180 0.000 0.000 1.000 +I*C3H7 2 266.800 4.982 0.000 0.000 1.000 +N*C3H7 2 266.800 4.982 0.000 0.000 1.000 +C3H8 2 266.800 4.982 0.000 0.000 1.000 +C4H 1 357.000 5.180 0.000 0.000 1.000 +C4H2 1 357.000 5.180 0.000 0.000 1.000 +C4H2OH 2 224.700 4.162 0.000 0.000 1.000 ! * +C4H8 2 357.000 5.176 0.000 0.000 1.000 +C4H9 2 357.000 5.176 0.000 0.000 1.000 +I*C4H9 2 357.000 5.176 0.000 0.000 1.000 +C5H2 1 357.000 5.180 0.000 0.000 1.000 +C5H3 1 357.000 5.180 0.000 0.000 1.000 +C6H2 1 357.000 5.180 0.000 0.000 1.000 +C6H5 2 412.300 5.349 0.000 0.000 1.000 ! JAM +C6H5O 2 450.000 5.500 0.000 0.000 1.000 ! JAM +C5H5OH 2 450.000 5.500 0.000 0.000 1.000 ! JAM +C6H6 2 412.300 5.349 0.000 0.000 1.000 ! SVE +C6H7 2 412.300 5.349 0.000 0.000 1.000 ! JAM +CH 1 80.000 2.750 0.000 0.000 0.000 +CH2 1 144.000 3.800 0.000 0.000 0.000 +CH2(S) 1 144.000 3.800 0.000 0.000 0.000 +CH2* 1 144.000 3.800 0.000 0.000 0.000 +CH2CHCCH 2 357.000 5.180 0.000 0.000 1.000 ! JAM +CH2CHCCH2 2 357.000 5.180 0.000 0.000 1.000 ! JAM +CH2CHCH2 2 260.000 4.850 0.000 0.000 1.000 ! JAM +CH2CHCHCH 2 357.000 5.180 0.000 0.000 1.000 ! JAM +CH2CHCHCH2 2 357.000 5.180 0.000 0.000 1.000 ! JAM +CH2CO 2 436.000 3.970 0.000 0.000 2.000 +CH2O 2 498.000 3.590 0.000 0.000 2.000 +CH2OH 2 417.000 3.690 1.700 0.000 2.000 +CH3 1 144.000 3.800 0.000 0.000 0.000 +CH3CC 2 252.000 4.760 0.000 0.000 1.000 ! JAM +CH3CCCH2 2 357.000 5.180 0.000 0.000 1.000 ! JAM +CH3CCCH3 2 357.000 5.180 0.000 0.000 1.000 ! JAM +CH3CCH2 2 260.000 4.850 0.000 0.000 1.000 ! JAM +CH3CHCH 2 260.000 4.850 0.000 0.000 1.000 ! JAM +CH3CH2CCH 2 357.000 5.180 0.000 0.000 1.000 ! JAM +CH3CHO 2 436.000 3.970 0.000 0.000 2.000 +CH2CHO 2 436.000 3.970 0.000 0.000 2.000 +CH3CO 2 436.000 3.970 0.000 0.000 2.000 +CH3O 2 417.000 3.690 1.700 0.000 2.000 +CH3OH 2 481.800 3.626 0.000 0.000 1.000 ! SVE +CH4 2 141.400 3.746 0.000 2.600 13.000 +CH4O 2 417.000 3.690 1.700 0.000 2.000 +CN 1 75.000 3.856 0.000 0.000 1.000 ! OIS +CNC 1 232.400 3.828 0.000 0.000 1.000 ! OIS +CNN 1 232.400 3.828 0.000 0.000 1.000 ! OIS +CO 1 98.100 3.650 0.000 1.950 1.800 +CO2 1 244.000 3.763 0.000 2.650 2.100 +H 0 145.000 2.050 0.000 0.000 0.000 +H2C4O 2 357.000 5.180 0.000 0.000 1.000 ! JAM +H2 1 38.000 2.920 0.000 0.790 280.000 +H2CCCCH 2 357.000 5.180 0.000 0.000 1.000 ! JAM +H2CCCCH2 2 357.000 5.180 0.000 0.000 1.000 ! JAM +H2CCCH 2 252.000 4.760 0.000 0.000 1.000 ! JAM +H2CN 1 569.000 3.630 0.000 0.000 1.000 ! os/jm +H2NO 2 116.700 3.492 0.000 0.000 1.000 ! JAM +H2O 2 572.400 2.605 1.844 0.000 4.000 +H2O2 2 107.400 3.458 0.000 0.000 3.800 +HC2N2 1 349.000 4.361 0.000 0.000 1.000 ! OIS +HCCHCCH 2 357.000 5.180 0.000 0.000 1.000 ! JAM +HCCO 2 150.000 2.500 0.000 0.000 1.000 ! * +HCNN 2 150.000 2.500 0.000 0.000 1.000 ! * +HCCOH 2 436.000 3.970 0.000 0.000 2.000 +HCN 1 569.000 3.630 0.000 0.000 1.000 ! OIS +HCO 2 498.000 3.590 0.000 0.000 0.000 +HE 0 10.200 2.576 0.000 0.000 0.000 ! * +HCNO 2 232.400 3.828 0.000 0.000 1.000 ! JAM +HOCN 2 232.400 3.828 0.000 0.000 1.000 ! JAM +HNCO 2 232.400 3.828 0.000 0.000 1.000 ! OIS +HNNO 2 232.400 3.828 0.000 0.000 1.000 ! * +HNO 2 116.700 3.492 0.000 0.000 1.000 ! * +HNOH 2 116.700 3.492 0.000 0.000 1.000 ! JAM +HO2 2 107.400 3.458 0.000 0.000 1.000 ! * +N 0 71.400 3.298 0.000 0.000 0.000 ! * +N2 1 97.530 3.621 0.000 1.760 4.000 +N2H2 2 71.400 3.798 0.000 0.000 1.000 ! * +N2H3 2 200.000 3.900 0.000 0.000 1.000 ! * +N2H4 2 205.000 4.230 0.000 4.260 1.500 +N2O 1 232.400 3.828 0.000 0.000 1.000 ! * +NCN 1 232.400 3.828 0.000 0.000 1.000 ! OIS +NCO 1 232.400 3.828 0.000 0.000 1.000 ! OIS +NH 1 80.000 2.650 0.000 0.000 4.000 +NH2 2 80.000 2.650 0.000 2.260 4.000 +NH3 2 481.000 2.920 1.470 0.000 10.000 +NNH 2 71.400 3.798 0.000 0.000 1.000 ! * +NO 1 97.530 3.621 0.000 1.760 4.000 +NCNO 2 232.400 3.828 0.000 0.000 1.000 ! OIS +NO2 2 200.000 3.500 0.000 0.000 1.000 ! * +O 0 80.000 2.750 0.000 0.000 0.000 +O2 1 107.400 3.458 0.000 1.600 3.800 +OH 1 80.000 2.750 0.000 0.000 0.000 diff --git a/test_problems/cxx_ex/gri30mod.inp b/test_problems/cxx_ex/gri30mod.inp new file mode 100644 index 000000000..4c364b032 --- /dev/null +++ b/test_problems/cxx_ex/gri30mod.inp @@ -0,0 +1,692 @@ +! GRI-Mech Version 3.0 3/12/99 CHEMKIN-II format +! See README30 file at anonymous FTP site unix.sri.com, directory gri; +! WorldWideWeb home page http://www.me.berkeley.edu/gri_mech/ or +! through http://www.gri.org , under 'Basic Research', +! for additional information, contacts, and disclaimer +ELEMENTS +O H C N AR +END +SPECIES +H2 H O O2 OH H2O HO2 H2O2 +C CH CH2 CH2(S) CH3 CH4 CO CO2 +HCO CH2O CH2OH CH3O CH3OH C2H C2H2 C2H3 +C2H4 C2H5 C2H6 HCCO CH2CO HCCOH N NH +NH2 NH3 NNH NO NO2 N2O HNO CN +HCN H2CN HCNN HCNO HOCN HNCO NCO N2 +AR C3H7 C3H8 CH2CHO CH3CHO +END +THERMO ALL + 300.000 1000.000 5000.000 +O L 1/90O 1 00 00 00G 200.000 3500.000 1000.000 1 + 2.56942078E+00-8.59741137E-05 4.19484589E-08-1.00177799E-11 1.22833691E-15 2 + 2.92175791E+04 4.78433864E+00 3.16826710E+00-3.27931884E-03 6.64306396E-06 3 +-6.12806624E-09 2.11265971E-12 2.91222592E+04 2.05193346E+00 4 +O2 TPIS89O 2 00 00 00G 200.000 3500.000 1000.000 1 + 3.28253784E+00 1.48308754E-03-7.57966669E-07 2.09470555E-10-2.16717794E-14 2 +-1.08845772E+03 5.45323129E+00 3.78245636E+00-2.99673416E-03 9.84730201E-06 3 +-9.68129509E-09 3.24372837E-12-1.06394356E+03 3.65767573E+00 4 +H L 7/88H 1 00 00 00G 200.000 3500.000 1000.000 1 + 2.50000001E+00-2.30842973E-11 1.61561948E-14-4.73515235E-18 4.98197357E-22 2 + 2.54736599E+04-4.46682914E-01 2.50000000E+00 7.05332819E-13-1.99591964E-15 3 + 2.30081632E-18-9.27732332E-22 2.54736599E+04-4.46682853E-01 4 +H2 TPIS78H 2 00 00 00G 200.000 3500.000 1000.000 1 + 3.33727920E+00-4.94024731E-05 4.99456778E-07-1.79566394E-10 2.00255376E-14 2 +-9.50158922E+02-3.20502331E+00 2.34433112E+00 7.98052075E-03-1.94781510E-05 3 + 2.01572094E-08-7.37611761E-12-9.17935173E+02 6.83010238E-01 4 +OH RUS 78O 1H 1 00 00G 200.000 3500.000 1000.000 1 + 3.09288767E+00 5.48429716E-04 1.26505228E-07-8.79461556E-11 1.17412376E-14 2 + 3.85865700E+03 4.47669610E+00 3.99201543E+00-2.40131752E-03 4.61793841E-06 3 +-3.88113333E-09 1.36411470E-12 3.61508056E+03-1.03925458E-01 4 +H2O L 8/89H 2O 1 00 00G 200.000 3500.000 1000.000 1 + 3.03399249E+00 2.17691804E-03-1.64072518E-07-9.70419870E-11 1.68200992E-14 2 +-3.00042971E+04 4.96677010E+00 4.19864056E+00-2.03643410E-03 6.52040211E-06 3 +-5.48797062E-09 1.77197817E-12-3.02937267E+04-8.49032208E-01 4 +HO2 L 5/89H 1O 2 00 00G 200.000 3500.000 1000.000 1 + 4.01721090E+00 2.23982013E-03-6.33658150E-07 1.14246370E-10-1.07908535E-14 2 + 1.11856713E+02 3.78510215E+00 4.30179801E+00-4.74912051E-03 2.11582891E-05 3 +-2.42763894E-08 9.29225124E-12 2.94808040E+02 3.71666245E+00 4 +H2O2 L 7/88H 2O 2 00 00G 200.000 3500.000 1000.000 1 + 4.16500285E+00 4.90831694E-03-1.90139225E-06 3.71185986E-10-2.87908305E-14 2 +-1.78617877E+04 2.91615662E+00 4.27611269E+00-5.42822417E-04 1.67335701E-05 3 +-2.15770813E-08 8.62454363E-12-1.77025821E+04 3.43505074E+00 4 +C L11/88C 1 00 00 00G 200.000 3500.000 1000.000 1 + 2.49266888E+00 4.79889284E-05-7.24335020E-08 3.74291029E-11-4.87277893E-15 2 + 8.54512953E+04 4.80150373E+00 2.55423955E+00-3.21537724E-04 7.33792245E-07 3 +-7.32234889E-10 2.66521446E-13 8.54438832E+04 4.53130848E+00 4 +CH TPIS79C 1H 1 00 00G 200.000 3500.000 1000.000 1 + 2.87846473E+00 9.70913681E-04 1.44445655E-07-1.30687849E-10 1.76079383E-14 2 + 7.10124364E+04 5.48497999E+00 3.48981665E+00 3.23835541E-04-1.68899065E-06 3 + 3.16217327E-09-1.40609067E-12 7.07972934E+04 2.08401108E+00 4 +CH2 L S/93C 1H 2 00 00G 200.000 3500.000 1000.000 1 + 2.87410113E+00 3.65639292E-03-1.40894597E-06 2.60179549E-10-1.87727567E-14 2 + 4.62636040E+04 6.17119324E+00 3.76267867E+00 9.68872143E-04 2.79489841E-06 3 +-3.85091153E-09 1.68741719E-12 4.60040401E+04 1.56253185E+00 4 +CH2(S) L S/93C 1H 2 00 00G 200.000 3500.000 1000.000 1 + 2.29203842E+00 4.65588637E-03-2.01191947E-06 4.17906000E-10-3.39716365E-14 2 + 5.09259997E+04 8.62650169E+00 4.19860411E+00-2.36661419E-03 8.23296220E-06 3 +-6.68815981E-09 1.94314737E-12 5.04968163E+04-7.69118967E-01 4 +CH3 L11/89C 1H 3 00 00G 200.000 3500.000 1000.000 1 + 2.28571772E+00 7.23990037E-03-2.98714348E-06 5.95684644E-10-4.67154394E-14 2 + 1.67755843E+04 8.48007179E+00 3.67359040E+00 2.01095175E-03 5.73021856E-06 3 +-6.87117425E-09 2.54385734E-12 1.64449988E+04 1.60456433E+00 4 +CH4 L 8/88C 1H 4 00 00G 200.000 3500.000 1000.000 1 + 7.48514950E-02 1.33909467E-02-5.73285809E-06 1.22292535E-09-1.01815230E-13 2 +-9.46834459E+03 1.84373180E+01 5.14987613E+00-1.36709788E-02 4.91800599E-05 3 +-4.84743026E-08 1.66693956E-11-1.02466476E+04-4.64130376E+00 4 +CO TPIS79C 1O 1 00 00G 200.000 3500.000 1000.000 1 + 2.71518561E+00 2.06252743E-03-9.98825771E-07 2.30053008E-10-2.03647716E-14 2 +-1.41518724E+04 7.81868772E+00 3.57953347E+00-6.10353680E-04 1.01681433E-06 3 + 9.07005884E-10-9.04424499E-13-1.43440860E+04 3.50840928E+00 4 +CO2 L 7/88C 1O 2 00 00G 200.000 3500.000 1000.000 1 + 3.85746029E+00 4.41437026E-03-2.21481404E-06 5.23490188E-10-4.72084164E-14 2 +-4.87591660E+04 2.27163806E+00 2.35677352E+00 8.98459677E-03-7.12356269E-06 3 + 2.45919022E-09-1.43699548E-13-4.83719697E+04 9.90105222E+00 4 +HCO L12/89H 1C 1O 1 00G 200.000 3500.000 1000.000 1 + 2.77217438E+00 4.95695526E-03-2.48445613E-06 5.89161778E-10-5.33508711E-14 2 + 4.01191815E+03 9.79834492E+00 4.22118584E+00-3.24392532E-03 1.37799446E-05 3 +-1.33144093E-08 4.33768865E-12 3.83956496E+03 3.39437243E+00 4 +CH2O L 8/88H 2C 1O 1 00G 200.000 3500.000 1000.000 1 + 1.76069008E+00 9.20000082E-03-4.42258813E-06 1.00641212E-09-8.83855640E-14 2 +-1.39958323E+04 1.36563230E+01 4.79372315E+00-9.90833369E-03 3.73220008E-05 3 +-3.79285261E-08 1.31772652E-11-1.43089567E+04 6.02812900E-01 4 +CH2OH GUNL93C 1H 3O 1 00G 200.000 3500.000 1000.000 1 + 3.69266569E+00 8.64576797E-03-3.75101120E-06 7.87234636E-10-6.48554201E-14 2 +-3.24250627E+03 5.81043215E+00 3.86388918E+00 5.59672304E-03 5.93271791E-06 3 +-1.04532012E-08 4.36967278E-12-3.19391367E+03 5.47302243E+00 4 +CH3O 121686C 1H 3O 1 G 0300.00 3000.00 1000.000 1 + 0.03770799E+02 0.07871497E-01-0.02656384E-04 0.03944431E-08-0.02112616E-12 2 + 0.12783252E+03 0.02929575E+02 0.02106204E+02 0.07216595E-01 0.05338472E-04 3 +-0.07377636E-07 0.02075610E-10 0.09786011E+04 0.13152177E+02 4 +CH3OH L 8/88C 1H 4O 1 00G 200.000 3500.000 1000.000 1 + 1.78970791E+00 1.40938292E-02-6.36500835E-06 1.38171085E-09-1.17060220E-13 2 +-2.53748747E+04 1.45023623E+01 5.71539582E+00-1.52309129E-02 6.52441155E-05 3 +-7.10806889E-08 2.61352698E-11-2.56427656E+04-1.50409823E+00 4 +C2H L 1/91C 2H 1 00 00G 200.000 3500.000 1000.000 1 + 3.16780652E+00 4.75221902E-03-1.83787077E-06 3.04190252E-10-1.77232770E-14 2 + 6.71210650E+04 6.63589475E+00 2.88965733E+00 1.34099611E-02-2.84769501E-05 3 + 2.94791045E-08-1.09331511E-11 6.68393932E+04 6.22296438E+00 4 +C2H2 L 1/91C 2H 2 00 00G 200.000 3500.000 1000.000 1 + 4.14756964E+00 5.96166664E-03-2.37294852E-06 4.67412171E-10-3.61235213E-14 2 + 2.59359992E+04-1.23028121E+00 8.08681094E-01 2.33615629E-02-3.55171815E-05 3 + 2.80152437E-08-8.50072974E-12 2.64289807E+04 1.39397051E+01 4 +C2H3 L 2/92C 2H 3 00 00G 200.000 3500.000 1000.000 1 + 3.01672400E+00 1.03302292E-02-4.68082349E-06 1.01763288E-09-8.62607041E-14 2 + 3.46128739E+04 7.78732378E+00 3.21246645E+00 1.51479162E-03 2.59209412E-05 3 +-3.57657847E-08 1.47150873E-11 3.48598468E+04 8.51054025E+00 4 +C2H4 L 1/91C 2H 4 00 00G 200.000 3500.000 1000.000 1 + 2.03611116E+00 1.46454151E-02-6.71077915E-06 1.47222923E-09-1.25706061E-13 2 + 4.93988614E+03 1.03053693E+01 3.95920148E+00-7.57052247E-03 5.70990292E-05 3 +-6.91588753E-08 2.69884373E-11 5.08977593E+03 4.09733096E+00 4 +C2H5 L12/92C 2H 5 00 00G 200.000 3500.000 1000.000 1 + 1.95465642E+00 1.73972722E-02-7.98206668E-06 1.75217689E-09-1.49641576E-13 2 + 1.28575200E+04 1.34624343E+01 4.30646568E+00-4.18658892E-03 4.97142807E-05 3 +-5.99126606E-08 2.30509004E-11 1.28416265E+04 4.70720924E+00 4 +C2H6 L 8/88C 2H 6 00 00G 200.000 3500.000 1000.000 1 + 1.07188150E+00 2.16852677E-02-1.00256067E-05 2.21412001E-09-1.90002890E-13 2 +-1.14263932E+04 1.51156107E+01 4.29142492E+00-5.50154270E-03 5.99438288E-05 3 +-7.08466285E-08 2.68685771E-11-1.15222055E+04 2.66682316E+00 4 +CH2CO L 5/90C 2H 2O 1 00G 200.000 3500.000 1000.000 1 + 4.51129732E+00 9.00359745E-03-4.16939635E-06 9.23345882E-10-7.94838201E-14 2 +-7.55105311E+03 6.32247205E-01 2.13583630E+00 1.81188721E-02-1.73947474E-05 3 + 9.34397568E-09-2.01457615E-12-7.04291804E+03 1.22156480E+01 4 +HCCO SRIC91H 1C 2O 1 G 0300.00 4000.00 1000.000 1 + 0.56282058E+01 0.40853401E-02-0.15934547E-05 0.28626052E-09-0.19407832E-13 2 + 0.19327215E+05-0.39302595E+01 0.22517214E+01 0.17655021E-01-0.23729101E-04 3 + 0.17275759E-07-0.50664811E-11 0.20059449E+05 0.12490417E+02 4 +HCCOH SRI91C 2O 1H 20 0G 300.000 5000.000 1000.000 1 + 0.59238291E+01 0.67923600E-02-0.25658564E-05 0.44987841E-09-0.29940101E-13 2 + 0.72646260E+04-0.76017742E+01 0.12423733E+01 0.31072201E-01-0.50866864E-04 3 + 0.43137131E-07-0.14014594E-10 0.80316143E+04 0.13874319E+02 4 +H2CN 41687H 2C 1N 1 G 0300.00 4000.000 1000.000 1 + 0.52097030E+01 0.29692911E-02-0.28555891E-06-0.16355500E-09 0.30432589E-13 2 + 0.27677109E+05-0.44444780E+01 0.28516610E+01 0.56952331E-02 0.10711400E-05 3 +-0.16226120E-08-0.23511081E-12 0.28637820E+05 0.89927511E+01 4 +HCN GRI/98H 1C 1N 1 0G 200.000 6000.000 1000.000 1 + 0.38022392E+01 0.31464228E-02-0.10632185E-05 0.16619757E-09-0.97997570E-14 2 + 0.14407292E+05 0.15754601E+01 0.22589886E+01 0.10051170E-01-0.13351763E-04 3 + 0.10092349E-07-0.30089028E-11 0.14712633E+05 0.89164419E+01 4 +HNO And93 H 1N 1O 1 0G 200.000 6000.000 1000.000 1 + 0.29792509E+01 0.34944059E-02-0.78549778E-06 0.57479594E-10-0.19335916E-15 2 + 0.11750582E+05 0.86063728E+01 0.45334916E+01-0.56696171E-02 0.18473207E-04 3 +-0.17137094E-07 0.55454573E-11 0.11548297E+05 0.17498417E+01 4 +N L 6/88N 1 0 0 0G 200.000 6000.000 1000.000 1 + 0.24159429E+01 0.17489065E-03-0.11902369E-06 0.30226245E-10-0.20360982E-14 2 + 0.56133773E+05 0.46496096E+01 0.25000000E+01 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00 0.56104637E+05 0.41939087E+01 4 +NNH T07/93N 2H 1 00 00G 200.000 6000.000 1000.000 1 + 0.37667544E+01 0.28915082E-02-0.10416620E-05 0.16842594E-09-0.10091896E-13 2 + 0.28650697E+05 0.44705067E+01 0.43446927E+01-0.48497072E-02 0.20059459E-04 3 +-0.21726464E-07 0.79469539E-11 0.28791973E+05 0.29779410E+01 4 +N2O L 7/88N 2O 1 0 0G 200.000 6000.000 1000.000 1 + 0.48230729E+01 0.26270251E-02-0.95850874E-06 0.16000712E-09-0.97752303E-14 2 + 0.80734048E+04-0.22017207E+01 0.22571502E+01 0.11304728E-01-0.13671319E-04 3 + 0.96819806E-08-0.29307182E-11 0.87417744E+04 0.10757992E+02 4 +NH And94 N 1H 1 0 0G 200.000 6000.000 1000.000 1 + 0.27836928E+01 0.13298430E-02-0.42478047E-06 0.78348501E-10-0.55044470E-14 2 + 0.42120848E+05 0.57407799E+01 0.34929085E+01 0.31179198E-03-0.14890484E-05 3 + 0.24816442E-08-0.10356967E-11 0.41880629E+05 0.18483278E+01 4 +NH2 And89 N 1H 2 0 0G 200.000 6000.000 1000.000 1 + 0.28347421E+01 0.32073082E-02-0.93390804E-06 0.13702953E-09-0.79206144E-14 2 + 0.22171957E+05 0.65204163E+01 0.42040029E+01-0.21061385E-02 0.71068348E-05 3 +-0.56115197E-08 0.16440717E-11 0.21885910E+05-0.14184248E+00 4 +NH3 J 6/77N 1H 3 0 0G 200.000 6000.000 1000.000 1 + 0.26344521E+01 0.56662560E-02-0.17278676E-05 0.23867161E-09-0.12578786E-13 2 +-0.65446958E+04 0.65662928E+01 0.42860274E+01-0.46605230E-02 0.21718513E-04 3 +-0.22808887E-07 0.82638046E-11-0.67417285E+04-0.62537277E+00 4 +NO RUS 78N 1O 1 0 0G 200.000 6000.000 1000.000 1 + 0.32606056E+01 0.11911043E-02-0.42917048E-06 0.69457669E-10-0.40336099E-14 2 + 0.99209746E+04 0.63693027E+01 0.42184763E+01-0.46389760E-02 0.11041022E-04 3 +-0.93361354E-08 0.28035770E-11 0.98446230E+04 0.22808464E+01 4 +NO2 L 7/88N 1O 2 0 0G 200.000 6000.000 1000.000 1 + 0.48847542E+01 0.21723956E-02-0.82806906E-06 0.15747510E-09-0.10510895E-13 2 + 0.23164983E+04-0.11741695E+00 0.39440312E+01-0.15854290E-02 0.16657812E-04 3 +-0.20475426E-07 0.78350564E-11 0.28966179E+04 0.63119917E+01 4 +HCNO BDEA94H 1N 1C 1O 1G 300.000 5000.000 1382.000 1 + 6.59860456E+00 3.02778626E-03-1.07704346E-06 1.71666528E-10-1.01439391E-14 2 + 1.79661339E+04-1.03306599E+01 2.64727989E+00 1.27505342E-02-1.04794236E-05 3 + 4.41432836E-09-7.57521466E-13 1.92990252E+04 1.07332972E+01 4 +HOCN BDEA94H 1N 1C 1O 1G 300.000 5000.000 1368.000 1 + 5.89784885E+00 3.16789393E-03-1.11801064E-06 1.77243144E-10-1.04339177E-14 2 +-3.70653331E+03-6.18167825E+00 3.78604952E+00 6.88667922E-03-3.21487864E-06 3 + 5.17195767E-10 1.19360788E-14-2.82698400E+03 5.63292162E+00 4 +HNCO BDEA94H 1N 1C 1O 1G 300.000 5000.000 1478.000 1 + 6.22395134E+00 3.17864004E-03-1.09378755E-06 1.70735163E-10-9.95021955E-15 2 +-1.66599344E+04-8.38224741E+00 3.63096317E+00 7.30282357E-03-2.28050003E-06 3 +-6.61271298E-10 3.62235752E-13-1.55873636E+04 6.19457727E+00 4 +NCO EA 93 N 1C 1O 1 0G 200.000 6000.000 1000.000 1 + 0.51521845E+01 0.23051761E-02-0.88033153E-06 0.14789098E-09-0.90977996E-14 2 + 0.14004123E+05-0.25442660E+01 0.28269308E+01 0.88051688E-02-0.83866134E-05 3 + 0.48016964E-08-0.13313595E-11 0.14682477E+05 0.95504646E+01 4 +CN HBH92 C 1N 1 0 0G 200.000 6000.000 1000.000 1 + 0.37459805E+01 0.43450775E-04 0.29705984E-06-0.68651806E-10 0.44134173E-14 2 + 0.51536188E+05 0.27867601E+01 0.36129351E+01-0.95551327E-03 0.21442977E-05 3 +-0.31516323E-09-0.46430356E-12 0.51708340E+05 0.39804995E+01 4 +HCNN SRI/94C 1N 2H 10 0G 300.000 5000.000 1000.000 1 + 0.58946362E+01 0.39895959E-02-0.15982380E-05 0.29249395E-09-0.20094686E-13 2 + 0.53452941E+05-0.51030502E+01 0.25243194E+01 0.15960619E-01-0.18816354E-04 3 + 0.12125540E-07-0.32357378E-11 0.54261984E+05 0.11675870E+02 4 +N2 121286N 2 G 300.000 5000.000 1000.000 1 + 0.02926640E+02 0.14879768E-02-0.05684760E-05 0.10097038E-09-0.06753351E-13 2 +-0.09227977E+04 0.05980528E+02 0.03298677E+02 0.14082404E-02-0.03963222E-04 3 + 0.05641515E-07-0.02444854E-10-0.10208999E+04 0.03950372E+02 4 +AR 120186AR 1 G 300.000 5000.000 1000.000 1 + 0.02500000E+02 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-0.07453750E+04 0.04366000E+02 0.02500000E+02 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-0.07453750E+04 0.04366000E+02 4 +C3H8 L 4/85C 3H 8 0 0G 300.000 5000.000 1000.00 1 + 0.75341368E+01 0.18872239E-01-0.62718491E-05 0.91475649E-09-0.47838069E-13 2 +-0.16467516E+05-0.17892349E+02 0.93355381E+00 0.26424579E-01 0.61059727E-05 3 +-0.21977499E-07 0.95149253E-11-0.13958520E+05 0.19201691E+02 4 +C3H7 L 9/84C 3H 7 0 0G 300.000 5000.000 1000.00 1 + 0.77026987E+01 0.16044203E-01-0.52833220E-05 0.76298590E-09-0.39392284E-13 2 + 0.82984336E+04-0.15480180E+02 0.10515518E+01 0.25991980E-01 0.23800540E-05 3 +-0.19609569E-07 0.93732470E-11 0.10631863E+05 0.21122559E+02 4 +CH3CHO L 8/88C 2H 4O 1 0G 200.000 6000.000 1000.00 1 + 0.54041108E+01 0.11723059E-01-0.42263137E-05 0.68372451E-09-0.40984863E-13 2 +-0.22593122E+05-0.34807917E+01 0.47294595E+01-0.31932858E-02 0.47534921E-04 3 +-0.57458611E-07 0.21931112E-10-0.21572878E+05 0.41030159E+01 4 +CH2CHO SAND86O 1H 3C 2 G 300.00 5000.00 1000.00 1 + 0.05975670E+02 0.08130591E-01-0.02743624E-04 0.04070304E-08-0.02176017E-12 2 + 0.04903218E+04-0.05045251E+02 0.03409062E+02 0.10738574E-01 0.01891492E-04 3 +-0.07158583E-07 0.02867385E-10 0.15214766E+04 0.09558290E+02 4 +END +REACTIONS +2O+M<=>O2+M 1.200E+17 -1.000 .00 +H2/ 2.40/ H2O/15.40/ CH4/ 2.00/ CO/ 1.75/ CO2/ 3.60/ C2H6/ 3.00/ AR/ .83/ +O+H+M<=>OH+M 5.000E+17 -1.000 .00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +O+H2<=>H+OH 3.870E+04 2.700 6260.00 +O+HO2<=>OH+O2 2.000E+13 .000 .00 +!% (O) + (H)(O2) = (O)(H) + (O2) +O+H2O2<=>OH+HO2 9.630E+06 2.000 4000.00 +O+CH<=>H+CO 5.700E+13 .000 .00 +O+CH2<=>H+HCO 8.000E+13 .000 .00 +O+CH2(S)<=>H2+CO 1.500E+13 .000 .00 +O+CH2(S)<=>H+HCO 1.500E+13 .000 .00 +O+CH3<=>H+CH2O 5.060E+13 .000 .00 +O+CH4<=>OH+CH3 1.020E+09 1.500 8600.00 +O+CO(+M)<=>CO2(+M) 1.800E+10 .000 2385.00 + LOW/ 6.020E+14 .000 3000.00/ +H2/2.00/ O2/6.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/3.50/ C2H6/3.00/ AR/ .50/ +O+HCO<=>OH+CO 3.000E+13 .000 .00 +O+HCO<=>H+CO2 3.000E+13 .000 .00 +O+CH2O<=>OH+HCO 3.900E+13 .000 3540.00 +O+CH2OH<=>OH+CH2O 1.000E+13 .000 .00 +O+CH3O<=>OH+CH2O 1.000E+13 .000 .00 +O+CH3OH<=>OH+CH2OH 3.880E+05 2.500 3100.00 +O+CH3OH<=>OH+CH3O 1.300E+05 2.500 5000.00 +O+C2H<=>CH+CO 5.000E+13 .000 .00 +O+C2H2<=>H+HCCO 1.350E+07 2.000 1900.00 +O+C2H2<=>OH+C2H 4.600E+19 -1.410 28950.00 +O+C2H2<=>CO+CH2 6.940E+06 2.000 1900.00 +O+C2H3<=>H+CH2CO 3.000E+13 .000 .00 +O+C2H4<=>CH3+HCO 1.250E+07 1.830 220.00 +O+C2H5<=>CH3+CH2O 2.240E+13 .000 .00 +O+C2H6<=>OH+C2H5 8.980E+07 1.920 5690.00 +O+HCCO<=>H+2CO 1.000E+14 .000 .00 +!% (O) + (H)(C)(C-O) = (H) + (C)(O) + (C-O) +O+CH2CO<=>OH+HCCO 1.000E+13 .000 8000.00 +O+CH2CO<=>CH2+CO2 1.750E+12 .000 1350.00 +O2+CO<=>O+CO2 2.500E+12 .000 47800.00 +O2+CH2O<=>HO2+HCO 1.000E+14 .000 40000.00 +H+O2+M<=>HO2+M 2.800E+18 -.860 .00 +O2/ .00/ H2O/ .00/ CO/ .75/ CO2/1.50/ C2H6/1.50/ N2/ .00/ AR/ .00/ +H+2O2<=>HO2+O2 2.080E+19 -1.240 .00 +H+O2+H2O<=>HO2+H2O 11.26E+18 -.760 .00 +H+O2+N2<=>HO2+N2 2.600E+19 -1.240 .00 +H+O2+AR<=>HO2+AR 7.000E+17 -.800 .00 +H+O2<=>O+OH 2.650E+16 -.6707 17041.00 +2H+M<=>H2+M 1.000E+18 -1.000 .00 +H2/ .00/ H2O/ .00/ CH4/2.00/ CO2/ .00/ C2H6/3.00/ AR/ .63/ +2H+H2<=>2H2 9.000E+16 -.600 .00 +2H+H2O<=>H2+H2O 6.000E+19 -1.250 .00 +2H+CO2<=>H2+CO2 5.500E+20 -2.000 .00 +H+OH+M<=>H2O+M 2.200E+22 -2.000 .00 +H2/ .73/ H2O/3.65/ CH4/2.00/ C2H6/3.00/ AR/ .38/ +H+HO2<=>O+H2O 3.970E+12 .000 671.00 +H+HO2<=>O2+H2 4.480E+13 .000 1068.00 +H+HO2<=>2OH 0.840E+14 .000 635.00 +H+H2O2<=>HO2+H2 1.210E+07 2.000 5200.00 +H+H2O2<=>OH+H2O 1.000E+13 .000 3600.00 +!% (H) + (O-H)(O-H) = (H)(O-H) + (O-H) +H+CH<=>C+H2 1.650E+14 .000 .00 +H+CH2(+M)<=>CH3(+M) 6.000E+14 .000 .00 + LOW / 1.040E+26 -2.760 1600.00/ + TROE/ .5620 91.00 5836.00 8552.00/ +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+CH2(S)<=>CH+H2 3.000E+13 .000 .00 +H+CH3(+M)<=>CH4(+M) 13.90E+15 -.534 536.00 + LOW / 2.620E+33 -4.760 2440.00/ + TROE/ .7830 74.00 2941.00 6964.00 / +H2/2.00/ H2O/6.00/ CH4/3.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+CH4<=>CH3+H2 6.600E+08 1.620 10840.00 +H+HCO(+M)<=>CH2O(+M) 1.090E+12 .480 -260.00 + LOW / 2.470E+24 -2.570 425.00/ + TROE/ .7824 271.00 2755.00 6570.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+HCO<=>H2+CO 7.340E+13 .000 .00 +H+CH2O(+M)<=>CH2OH(+M) 5.400E+11 .454 3600.00 + LOW / 1.270E+32 -4.820 6530.00/ + TROE/ .7187 103.00 1291.00 4160.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +H+CH2O(+M)<=>CH3O(+M) 5.400E+11 .454 2600.00 + LOW / 2.200E+30 -4.800 5560.00/ + TROE/ .7580 94.00 1555.00 4200.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +H+CH2O<=>HCO+H2 5.740E+07 1.900 2742.00 +H+CH2OH(+M)<=>CH3OH(+M) 1.055E+12 .500 86.00 + LOW / 4.360E+31 -4.650 5080.00/ + TROE/ .600 100.00 90000.0 10000.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +H+CH2OH<=>H2+CH2O 2.000E+13 .000 .00 +H+CH2OH<=>OH+CH3 1.650E+11 .650 -284.00 +!% (H) + (H2-C)(O-H) = (H)(H2-C) + (O-H) +H+CH2OH<=>CH2(S)+H2O 3.280E+13 -.090 610.00 +H+CH3O(+M)<=>CH3OH(+M) 2.430E+12 .515 50.00 + LOW / 4.660E+41 -7.440 14080.0/ + TROE/ .700 100.00 90000.0 10000.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +H+CH3O<=>H+CH2OH 4.150E+07 1.630 1924.00 +H+CH3O<=>H2+CH2O 2.000E+13 .000 .00 +H+CH3O<=>OH+CH3 1.500E+12 .500 -110.00 +H+CH3O<=>CH2(S)+H2O 2.620E+14 -.230 1070.00 +H+CH3OH<=>CH2OH+H2 1.700E+07 2.100 4870.00 +H+CH3OH<=>CH3O+H2 4.200E+06 2.100 4870.00 +H+C2H(+M)<=>C2H2(+M) 1.000E+17 -1.000 .00 + LOW / 3.750E+33 -4.800 1900.00/ + TROE/ .6464 132.00 1315.00 5566.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C2H2(+M)<=>C2H3(+M) 5.600E+12 .000 2400.00 + LOW / 3.800E+40 -7.270 7220.00/ + TROE/ .7507 98.50 1302.00 4167.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C2H3(+M)<=>C2H4(+M) 6.080E+12 .270 280.00 + LOW / 1.400E+30 -3.860 3320.00/ + TROE/ .7820 207.50 2663.00 6095.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C2H3<=>H2+C2H2 3.000E+13 .000 .00 +H+C2H4(+M)<=>C2H5(+M) 0.540E+12 .454 1820.00 + LOW / 0.600E+42 -7.620 6970.00/ + TROE/ .9753 210.00 984.00 4374.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C2H4<=>C2H3+H2 1.325E+06 2.530 12240.00 +H+C2H5(+M)<=>C2H6(+M) 5.210E+17 -.990 1580.00 + LOW / 1.990E+41 -7.080 6685.00/ + TROE/ .8422 125.00 2219.00 6882.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C2H5<=>H2+C2H4 2.000E+12 .000 .00 +H+C2H6<=>C2H5+H2 1.150E+08 1.900 7530.00 +H+HCCO<=>CH2(S)+CO 1.000E+14 .000 .00 +H+CH2CO<=>HCCO+H2 5.000E+13 .000 8000.00 +H+CH2CO<=>CH3+CO 1.130E+13 .000 3428.00 +H+HCCOH<=>H+CH2CO 1.000E+13 .000 .00 +H2+CO(+M)<=>CH2O(+M) 4.300E+07 1.500 79600.00 + LOW / 5.070E+27 -3.420 84350.00/ + TROE/ .9320 197.00 1540.00 10300.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +OH+H2<=>H+H2O 2.160E+08 1.510 3430.00 +2OH(+M)<=>H2O2(+M) 7.400E+13 -.370 .00 + LOW / 2.300E+18 -.900 -1700.00/ + TROE/ .7346 94.00 1756.00 5182.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +2OH<=>O+H2O 3.570E+04 2.400 -2110.00 +OH+HO2<=>O2+H2O 1.450E+13 .000 -500.00 + DUPLICATE +OH+H2O2<=>HO2+H2O 2.000E+12 .000 427.00 + DUPLICATE +OH+H2O2<=>HO2+H2O 1.700E+18 .000 29410.00 + DUPLICATE +OH+C<=>H+CO 5.000E+13 .000 .00 +OH+CH<=>H+HCO 3.000E+13 .000 .00 +OH+CH2<=>H+CH2O 2.000E+13 .000 .00 +OH+CH2<=>CH+H2O 1.130E+07 2.000 3000.00 +OH+CH2(S)<=>H+CH2O 3.000E+13 .000 .00 +OH+CH3(+M)<=>CH3OH(+M) 2.790E+18 -1.430 1330.00 + LOW / 4.000E+36 -5.920 3140.00/ + TROE/ .4120 195.0 5900.00 6394.00/ +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +OH+CH3<=>CH2+H2O 5.600E+07 1.600 5420.00 +OH+CH3<=>CH2(S)+H2O 6.440E+17 -1.340 1417.00 +OH+CH4<=>CH3+H2O 1.000E+08 1.600 3120.00 +OH+CO<=>H+CO2 4.760E+07 1.228 70.00 +OH+HCO<=>H2O+CO 5.000E+13 .000 .00 +OH+CH2O<=>HCO+H2O 3.430E+09 1.180 -447.00 +OH+CH2OH<=>H2O+CH2O 5.000E+12 .000 .00 +OH+CH3O<=>H2O+CH2O 5.000E+12 .000 .00 +OH+CH3OH<=>CH2OH+H2O 1.440E+06 2.000 -840.00 +OH+CH3OH<=>CH3O+H2O 6.300E+06 2.000 1500.00 +OH+C2H<=>H+HCCO 2.000E+13 .000 .00 +OH+C2H2<=>H+CH2CO 2.180E-04 4.500 -1000.00 +OH+C2H2<=>H+HCCOH 5.040E+05 2.300 13500.00 +OH+C2H2<=>C2H+H2O 3.370E+07 2.000 14000.00 +OH+C2H2<=>CH3+CO 4.830E-04 4.000 -2000.00 +OH+C2H3<=>H2O+C2H2 5.000E+12 .000 .00 +OH+C2H4<=>C2H3+H2O 3.600E+06 2.000 2500.00 +OH+C2H6<=>C2H5+H2O 3.540E+06 2.120 870.00 +OH+CH2CO<=>HCCO+H2O 7.500E+12 .000 2000.00 +2HO2<=>O2+H2O2 1.300E+11 .000 -1630.00 + DUPLICATE +2HO2<=>O2+H2O2 4.200E+14 .000 12000.00 + DUPLICATE +HO2+CH2<=>OH+CH2O 2.000E+13 .000 .00 +HO2+CH3<=>O2+CH4 1.000E+12 .000 .00 +HO2+CH3<=>OH+CH3O 3.780E+13 .000 .00 +HO2+CO<=>OH+CO2 1.500E+14 .000 23600.00 +HO2+CH2O<=>HCO+H2O2 5.600E+06 2.000 12000.00 +C+O2<=>O+CO 5.800E+13 .000 576.00 +C+CH2<=>H+C2H 5.000E+13 .000 .00 +C+CH3<=>H+C2H2 5.000E+13 .000 .00 +CH+O2<=>O+HCO 6.710E+13 .000 .00 +CH+H2<=>H+CH2 1.080E+14 .000 3110.00 +CH+H2O<=>H+CH2O 5.710E+12 .000 -755.00 +CH+CH2<=>H+C2H2 4.000E+13 .000 .00 +!% (H-C) + (H-C)(H) = (H-C)(H-C) + (H) ! uncertain +CH+CH3<=>H+C2H3 3.000E+13 .000 .00 +!% (H-C) + (H2-C)(H) = (H-C)(H2-C) + (H) ! uncertain +CH+CH4<=>H+C2H4 6.000E+13 .000 .00 +!% (H-C) + (H3-C)(H) = (H-C)(H3-C) + (H) ! uncertain +CH+CO(+M)<=>HCCO(+M) 5.000E+13 .000 .00 + LOW / 2.690E+28 -3.740 1936.00/ + TROE/ .5757 237.00 1652.00 5069.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +CH+CO2<=>HCO+CO 1.900E+14 .000 15792.00 +CH+CH2O<=>H+CH2CO 9.460E+13 .000 -515.00 +!% (O-H2-C) + (C)(H) = (O-H2-C)(C) + (H) ! uncertain +CH+HCCO<=>CO+C2H2 5.000E+13 .000 .00 +CH2+O2=>OH+H+CO 5.000E+12 .000 1500.00 +CH2+H2<=>H+CH3 5.000E+05 2.000 7230.00 +2CH2<=>H2+C2H2 1.600E+15 .000 11944.00 +CH2+CH3<=>H+C2H4 4.000E+13 .000 .00 +!% (H2-C) + (H2-C)(H) = (H2-C)(H2-C) + (H) +CH2+CH4<=>2CH3 2.460E+06 2.000 8270.00 +CH2+CO(+M)<=>CH2CO(+M) 8.100E+11 .500 4510.00 + LOW / 2.690E+33 -5.110 7095.00/ + TROE/ .5907 275.00 1226.00 5185.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +CH2+HCCO<=>C2H3+CO 3.000E+13 .000 .00 +CH2(S)+N2<=>CH2+N2 1.500E+13 .000 600.00 +CH2(S)+AR<=>CH2+AR 9.000E+12 .000 600.00 +CH2(S)+O2<=>H+OH+CO 2.800E+13 .000 .00 +CH2(S)+O2<=>CO+H2O 1.200E+13 .000 .00 +CH2(S)+H2<=>CH3+H 7.000E+13 .000 .00 +CH2(S)+H2O(+M)<=>CH3OH(+M) 4.820E+17 -1.160 1145.00 + LOW / 1.880E+38 -6.360 5040.00/ + TROE/ .6027 208.00 3922.00 10180.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +CH2(S)+H2O<=>CH2+H2O 3.000E+13 .000 .00 +CH2(S)+CH3<=>H+C2H4 1.200E+13 .000 -570.00 +CH2(S)+CH4<=>2CH3 1.600E+13 .000 -570.00 +!% (H2-C) + (H2-C)(H) = (H2-C)(H2-C) + (H) +CH2(S)+CO<=>CH2+CO 9.000E+12 .000 .00 +CH2(S)+CO2<=>CH2+CO2 7.000E+12 .000 .00 +CH2(S)+CO2<=>CO+CH2O 1.400E+13 .000 .00 +CH2(S)+C2H6<=>CH3+C2H5 4.000E+13 .000 -550.00 +CH3+O2<=>O+CH3O 3.560E+13 .000 30480.00 +CH3+O2<=>OH+CH2O 2.310E+12 .000 20315.00 +CH3+H2O2<=>HO2+CH4 2.450E+04 2.470 5180.00 +2CH3(+M)<=>C2H6(+M) 6.770E+16 -1.180 654.00 + LOW / 3.400E+41 -7.030 2762.00/ + TROE/ .6190 73.20 1180.00 9999.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +2CH3<=>H+C2H5 6.840E+12 .100 10600.00 +CH3+HCO<=>CH4+CO 2.648E+13 .000 .00 +CH3+CH2O<=>HCO+CH4 3.320E+03 2.810 5860.00 +CH3+CH3OH<=>CH2OH+CH4 3.000E+07 1.500 9940.00 +CH3+CH3OH<=>CH3O+CH4 1.000E+07 1.500 9940.00 +CH3+C2H4<=>C2H3+CH4 2.270E+05 2.000 9200.00 +CH3+C2H6<=>C2H5+CH4 6.140E+06 1.740 10450.00 +HCO+H2O<=>H+CO+H2O 1.500E+18 -1.000 17000.00 +HCO+M<=>H+CO+M 1.870E+17 -1.000 17000.00 +H2/2.00/ H2O/ .00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ +HCO+O2<=>HO2+CO 13.45E+12 .000 400.00 +CH2OH+O2<=>HO2+CH2O 1.800E+13 .000 900.00 +CH3O+O2<=>HO2+CH2O 4.280E-13 7.600 -3530.00 +C2H+O2<=>HCO+CO 1.000E+13 .000 -755.00 +C2H+H2<=>H+C2H2 5.680E+10 0.900 1993.00 +C2H3+O2<=>HCO+CH2O 4.580E+16 -1.390 1015.00 +C2H4(+M)<=>H2+C2H2(+M) 8.000E+12 .440 86770.00 + LOW / 1.580E+51 -9.300 97800.00/ + TROE/ .7345 180.00 1035.00 5417.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +C2H5+O2<=>HO2+C2H4 8.400E+11 .000 3875.00 +HCCO+O2<=>OH+2CO 3.200E+12 .000 854.00 +!% (H)(C)(C-O) + (O)(O) = (O)(H) + (C)(O) + (C-O) +2HCCO<=>2CO+C2H2 1.000E+13 .000 .00 +!% (H-C)(C-O) + (H-C)(C-O) = (C-O) + (C-O) + (H-C)(H-C) +N+NO<=>N2+O 2.700E+13 .000 355.00 +N+O2<=>NO+O 9.000E+09 1.000 6500.00 +N+OH<=>NO+H 3.360E+13 .000 385.00 +N2O+O<=>N2+O2 1.400E+12 .000 10810.00 +N2O+O<=>2NO 2.900E+13 .000 23150.00 +N2O+H<=>N2+OH 3.870E+14 .000 18880.00 +N2O+OH<=>N2+HO2 2.000E+12 .000 21060.00 +N2O(+M)<=>N2+O(+M) 7.910E+10 .000 56020.00 + LOW / 6.370E+14 .000 56640.00/ +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .625/ +HO2+NO<=>NO2+OH 2.110E+12 .000 -480.00 +NO+O+M<=>NO2+M 1.060E+20 -1.410 .00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +NO2+O<=>NO+O2 3.900E+12 .000 -240.00 +NO2+H<=>NO+OH 1.320E+14 .000 360.00 +NH+O<=>NO+H 4.000E+13 .000 .00 +NH+H<=>N+H2 3.200E+13 .000 330.00 +NH+OH<=>HNO+H 2.000E+13 .000 .00 +NH+OH<=>N+H2O 2.000E+09 1.200 .00 +NH+O2<=>HNO+O 4.610E+05 2.000 6500.00 +NH+O2<=>NO+OH 1.280E+06 1.500 100.00 +NH+N<=>N2+H 1.500E+13 .000 .00 +NH+H2O<=>HNO+H2 2.000E+13 .000 13850.00 +NH+NO<=>N2+OH 2.160E+13 -.230 .00 +NH+NO<=>N2O+H 3.650E+14 -.450 .00 +NH2+O<=>OH+NH 3.000E+12 .000 .00 +NH2+O<=>H+HNO 3.900E+13 .000 .00 +NH2+H<=>NH+H2 4.000E+13 .000 3650.00 +NH2+OH<=>NH+H2O 9.000E+07 1.500 -460.00 +NNH<=>N2+H 3.300E+08 .000 .00 +NNH+M<=>N2+H+M 1.300E+14 -.110 4980.00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +NNH+O2<=>HO2+N2 5.000E+12 .000 .00 +NNH+O<=>OH+N2 2.500E+13 .000 .00 +NNH+O<=>NH+NO 7.000E+13 .000 .00 +NNH+H<=>H2+N2 5.000E+13 .000 .00 +NNH+OH<=>H2O+N2 2.000E+13 .000 .00 +NNH+CH3<=>CH4+N2 2.500E+13 .000 .00 +H+NO+M<=>HNO+M 4.480E+19 -1.320 740.00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +HNO+O<=>NO+OH 2.500E+13 .000 .00 +HNO+H<=>H2+NO 9.000E+11 .720 660.00 +HNO+OH<=>NO+H2O 1.300E+07 1.900 -950.00 +HNO+O2<=>HO2+NO 1.000E+13 .000 13000.00 +CN+O<=>CO+N 7.700E+13 .000 .00 +CN+OH<=>NCO+H 4.000E+13 .000 .00 +CN+H2O<=>HCN+OH 8.000E+12 .000 7460.00 +CN+O2<=>NCO+O 6.140E+12 .000 -440.00 +CN+H2<=>HCN+H 2.950E+05 2.450 2240.00 +NCO+O<=>NO+CO 2.350E+13 .000 .00 +!% (O) + (N)(O-C) = (O)(N) + (O-C) +NCO+H<=>NH+CO 5.400E+13 .000 .00 +NCO+OH<=>NO+H+CO 0.250E+13 .000 .00 +!% (N)(C-O) + (O)(H) = (N)(O) + (C-O) + (H) +NCO+N<=>N2+CO 2.000E+13 .000 .00 +NCO+O2<=>NO+CO2 2.000E+12 .000 20000.00 +NCO+M<=>N+CO+M 3.100E+14 .000 54050.00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +NCO+NO<=>N2O+CO 1.900E+17 -1.520 740.00 +NCO+NO<=>N2+CO2 3.800E+18 -2.000 800.00 +HCN+M<=>H+CN+M 1.040E+29 -3.300 126600.00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +HCN+O<=>NCO+H 2.030E+04 2.640 4980.00 +HCN+O<=>NH+CO 5.070E+03 2.640 4980.00 +HCN+O<=>CN+OH 3.910E+09 1.580 26600.00 +HCN+OH<=>HOCN+H 1.100E+06 2.030 13370.00 +!% (O-H) + (C-N)(H) = (O-H)(C-N) + (H) +HCN+OH<=>HNCO+H 4.400E+03 2.260 6400.00 +!% (H-C-N) + (O)(H) = (H-C-N)(O) + (H) +HCN+OH<=>NH2+CO 1.600E+02 2.560 9000.00 +H+HCN(+M)<=>H2CN(+M) 3.300E+13 .000 .00 + LOW / 1.400E+26 -3.400 1900.00/ +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H2CN+N<=>N2+CH2 6.000E+13 .000 400.00 +C+N2<=>CN+N 6.300E+13 .000 46020.00 +CH+N2<=>HCN+N 3.120E+09 0.880 20130.00 +CH+N2(+M)<=>HCNN(+M) 3.100E+12 .150 .00 + LOW / 1.300E+25 -3.160 740.00/ + TROE/ .6670 235.00 2117.00 4536.00 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ 1.0/ +CH2+N2<=>HCN+NH 1.000E+13 .000 74000.00 +CH2(S)+N2<=>NH+HCN 1.000E+11 .000 65000.00 +C+NO<=>CN+O 1.900E+13 .000 .00 +C+NO<=>CO+N 2.900E+13 .000 .00 +CH+NO<=>HCN+O 4.100E+13 .000 .00 +CH+NO<=>H+NCO 1.620E+13 .000 .00 +CH+NO<=>N+HCO 2.460E+13 .000 .00 +CH2+NO<=>H+HNCO 3.100E+17 -1.380 1270.00 +CH2+NO<=>OH+HCN 2.900E+14 -.690 760.00 +CH2+NO<=>H+HCNO 3.800E+13 -.360 580.00 +CH2(S)+NO<=>H+HNCO 3.100E+17 -1.380 1270.00 +CH2(S)+NO<=>OH+HCN 2.900E+14 -.690 760.00 +CH2(S)+NO<=>H+HCNO 3.800E+13 -.360 580.00 +CH3+NO<=>HCN+H2O 9.600E+13 .000 28800.00 +CH3+NO<=>H2CN+OH 1.000E+12 .000 21750.00 +HCNN+O<=>CO+H+N2 2.200E+13 .000 .00 +HCNN+O<=>HCN+NO 2.000E+12 .000 .00 +HCNN+O2<=>O+HCO+N2 1.200E+13 .000 .00 +HCNN+OH<=>H+HCO+N2 1.200E+13 .000 .00 +!% (H)(C)(N2) + (O-H) = (H) + (C)(O-H) + (N2) +HCNN+H<=>CH2+N2 1.000E+14 .000 .00 +HNCO+O<=>NH+CO2 9.800E+07 1.410 8500.00 +HNCO+O<=>HNO+CO 1.500E+08 1.570 44000.00 +!% (O) + (H-N)(O-C) = (O)(H-N) + (O-C) +HNCO+O<=>NCO+OH 2.200E+06 2.110 11400.00 +HNCO+H<=>NH2+CO 2.250E+07 1.700 3800.00 +HNCO+H<=>H2+NCO 1.050E+05 2.500 13300.00 +HNCO+OH<=>NCO+H2O 3.300E+07 1.500 3600.00 +HNCO+OH<=>NH2+CO2 3.300E+06 1.500 3600.00 +HNCO+M<=>NH+CO+M 1.180E+16 .000 84720.00 +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +HCNO+H<=>H+HNCO 2.100E+15 -.690 2850.00 +HCNO+H<=>OH+HCN 2.700E+11 .180 2120.00 +!% (H) + (C-N)(O-H) = (H)(C-N) + (O-H) +HCNO+H<=>NH2+CO 1.700E+14 -.750 2890.00 +HOCN+H<=>H+HNCO 2.000E+07 2.000 2000.00 +HCCO+NO<=>HCNO+CO 0.900E+13 .000 .00 +CH3+N<=>H2CN+H 6.100E+14 -.310 290.00 +CH3+N<=>HCN+H2 3.700E+12 .150 -90.00 +NH3+H<=>NH2+H2 5.400E+05 2.400 9915.00 +NH3+OH<=>NH2+H2O 5.000E+07 1.600 955.00 +NH3+O<=>NH2+OH 9.400E+06 1.940 6460.00 +NH+CO2<=>HNO+CO 1.000E+13 .000 14350.00 +CN+NO2<=>NCO+NO 6.160E+15 -0.752 345.00 +NCO+NO2<=>N2O+CO2 3.250E+12 .000 -705.00 +!% (N)(C-O) + (N-O)(O) = (N)(N-O) + (C-O)(O) +N+CO2<=>NO+CO 3.000E+12 .000 11300.00 +O+CH3=>H+H2+CO 3.370E+13 .000 .00 +O+C2H4<=>H+CH2CHO 6.700E+06 1.830 220.00 +O+C2H5<=>H+CH3CHO 1.096E+14 .000 .00 +OH+HO2<=>O2+H2O 0.500E+16 .000 17330.00 + DUPLICATE +OH+CH3=>H2+CH2O 8.000E+09 .500 -1755.00 +CH+H2(+M)<=>CH3(+M) 1.970E+12 .430 -370.00 + LOW/ 4.820E+25 -2.80 590.0 / + TROE/ .578 122.0 2535.0 9365.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +CH2+O2=>2H+CO2 5.800E+12 .000 1500.00 +CH2+O2<=>O+CH2O 2.400E+12 .000 1500.00 +CH2+CH2=>2H+C2H2 2.000E+14 .000 10989.00 +!% (H)(C-H) + (H)(C-H) = (H) + (H) + (C-H)(C-H) +CH2(S)+H2O=>H2+CH2O 6.820E+10 .250 -935.00 +C2H3+O2<=>O+CH2CHO 3.030E+11 .290 11.00 +C2H3+O2<=>HO2+C2H2 1.337E+06 1.610 -384.00 +O+CH3CHO<=>OH+CH2CHO 5.840E+12 .000 1808.00 +O+CH3CHO=>OH+CH3+CO 5.840E+12 .000 1808.00 +!% (O) + (C-H3)(C-O)(H) = (H)(O) + (C-O) + (C-H3) +O2+CH3CHO=>HO2+CH3+CO 3.010E+13 .000 39150.00 +!% (O2) + (C-H3)(C-O)(H) = (H)(O2) + (C-O) + (C-H3) +H+CH3CHO<=>CH2CHO+H2 2.050E+09 1.160 2405.00 +H+CH3CHO=>CH3+H2+CO 2.050E+09 1.160 2405.00 +!% (H) + (C-H3)(H)(C-O) = (H)(H) + (C-O) + (C-H3) +OH+CH3CHO=>CH3+H2O+CO 2.343E+10 0.730 -1113.00 +!% (O-H) + (C-H3)(H)(C-O) = (H)(O-H) + (C-O) + (C-H3) +HO2+CH3CHO=>CH3+H2O2+CO 3.010E+12 .000 11923.00 +!% (O-H2) + (C-H3)(H)(C-O) = (H)(O-H2) + (C-O) + (C-H3) +CH3+CH3CHO=>CH3+CH4+CO 2.720E+06 1.770 5920.00 +!% (C-H3) + (C-H3)(H)(C-O) = (H)(C-H3) + (C-O) + (C-H3) +H+CH2CO(+M)<=>CH2CHO(+M) 4.865E+11 0.422 -1755.00 + LOW/ 1.012E+42 -7.63 3854.0/ + TROE/ 0.465 201.0 1773.0 5333.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +O+CH2CHO=>H+CH2+CO2 1.500E+14 .000 .00 +O2+CH2CHO=>OH+CO+CH2O 1.810E+10 .000 .00 +!% (O)(O) + (C-H2)(C-O)(H) = (O)(H) + (C-H2)(O) + (C-O) +O2+CH2CHO=>OH+2HCO 2.350E+10 .000 .00 +!% (O)(O) + (C-H)(C-H-O)(H) = (O)(H) + (C-H)(O) + (C-H-O) +H+CH2CHO<=>CH3+HCO 2.200E+13 .000 .00 +H+CH2CHO<=>CH2CO+H2 1.100E+13 .000 .00 +OH+CH2CHO<=>H2O+CH2CO 1.200E+13 .000 .00 +OH+CH2CHO<=>HCO+CH2OH 3.010E+13 .000 .00 +!% (O-H) + (H2-C)(O-H-C) = (O-H)(H2-C) + (O-H-C) +CH3+C2H5(+M)<=>C3H8(+M) .9430E+13 .000 .00 + LOW/ 2.710E+74 -16.82 13065.0 / + TROE/ .1527 291.0 2742.0 7748.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +O+C3H8<=>OH+C3H7 1.930E+05 2.680 3716.00 +H+C3H8<=>C3H7+H2 1.320E+06 2.540 6756.00 +OH+C3H8<=>C3H7+H2O 3.160E+07 1.800 934.00 +C3H7+H2O2<=>HO2+C3H8 3.780E+02 2.720 1500.00 +CH3+C3H8<=>C3H7+CH4 0.903E+00 3.650 7154.00 +CH3+C2H4(+M)<=>C3H7(+M) 2.550E+06 1.600 5700.00 + LOW/ 3.00E+63 -14.6 18170./ + TROE/ .1894 277.0 8748.0 7891.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +O+C3H7<=>C2H5+CH2O 9.640E+13 .000 .00 +H+C3H7(+M)<=>C3H8(+M) 3.613E+13 .000 .00 + LOW/ 4.420E+61 -13.545 11357.0/ + TROE/ .315 369.0 3285.0 6667.0 / +H2/2.00/ H2O/6.00/ CH4/2.00/ CO/1.50/ CO2/2.00/ C2H6/3.00/ AR/ .70/ +H+C3H7<=>CH3+C2H5 4.060E+06 2.190 890.00 +OH+C3H7<=>C2H5+CH2OH 2.410E+13 .000 .00 +HO2+C3H7<=>O2+C3H8 2.550E+10 0.255 -943.00 +HO2+C3H7=>OH+C2H5+CH2O 2.410E+13 .000 .00 +!% (O-H)(O) + (C2-H5)(C-H2) = (O-H) + (C2-H5) + (O)(C-H2) +CH3+C3H7<=>2C2H5 1.927E+13 -0.320 .00 +END diff --git a/test_problems/cxx_ex/kin1_blessed.csv b/test_problems/cxx_ex/kin1_blessed.csv new file mode 100644 index 000000000..90037bacd --- /dev/null +++ b/test_problems/cxx_ex/kin1_blessed.csv @@ -0,0 +1,103 @@ +kinetics example 1: constant-pressure ignition, +time (s),Temperature (K),Density (kg/m3),Pressure (Pa),H2,H,O,O2,OH,H2O,HO2,H2O2,C,CH,CH2,CH2(S),CH3,CH4,CO,CO2,HCO,CH2O,CH2OH,CH3O,CH3OH,C2H,C2H2,C2H3,C2H4,C2H5,C2H6,HCCO,CH2CO,HCCOH,N,NH,NH2,NH3,NNH,NO,NO2,N2O,HNO,CN,HCN,H2CN,HCNN,HCNO,HOCN,HNCO,NCO,N2,AR,C3H7,C3H8,CH2CHO,CH3CHO, +0,1001,0.257563,101325,0.285714,0,0,0.142857,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +1e-05,1001,0.257563,101325,0.285714,3.17627e-10,3.12622e-11,0.142857,1.06695e-11,2.13732e-10,4.83489e-10,4.75677e-13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9.85744e-25,6.33719e-24,2.67865e-25,1.11697e-25,1.05358e-16,1.43658e-23,4.24023e-31,1.36753e-17,3.18539e-25,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +2e-05,1001,0.257563,101325,0.285714,7.97668e-10,8.41326e-11,0.142857,2.79936e-11,1.06413e-09,1.41961e-09,2.51148e-12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.95209e-24,6.61853e-23,4.16091e-24,3.51597e-24,2.64619e-16,1.49797e-22,2.29124e-29,7.11593e-17,4.9457e-24,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +3e-05,1001,0.257563,101325,0.285714,1.53824e-09,1.65683e-10,0.142857,5.47182e-11,2.90024e-09,3.05218e-09,7.37752e-12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5.98655e-24,3.00836e-22,2.199e-23,2.69808e-23,5.10316e-16,7.24125e-22,3.18297e-28,1.97003e-16,2.61308e-23,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +4e-05,1001,0.257563,101325,0.285714,2.68113e-09,2.9153e-10,0.142857,9.59611e-11,6.25717e-09,5.75882e-09,1.70313e-11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.06695e-23,1.01119e-21,7.94713e-23,1.22546e-22,8.89485e-16,2.58359e-21,2.55007e-27,4.2858e-16,9.44222e-23,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +5e-05,1001,0.257563,101325,0.285714,4.44535e-09,4.85788e-10,0.142857,1.5963e-10,1.19616e-08,1.01228e-08,3.44949e-11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.79012e-23,2.94213e-21,2.4049e-22,4.30242e-22,1.47479e-15,7.88225e-21,1.53953e-26,8.23625e-16,2.85708e-22,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +6e-05,1001,0.257563,101325,0.285714,7.16923e-09,7.85709e-10,0.142857,2.5794e-10,2.12905e-08,1.70447e-08,6.44364e-11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.90785e-23,7.91366e-21,6.61716e-22,1.30693e-21,2.37849e-15,2.19603e-20,7.83713e-26,1.4713e-15,7.86091e-22,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +7e-05,1001,0.257563,101325,0.285714,1.13754e-08,1.24883e-09,0.142857,4.09772e-10,3.62166e-08,2.79153e-08,1.14073e-10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4.63866e-23,2.0336e-20,1.7238e-21,3.6383e-21,3.77395e-15,5.7867e-20,3.5798e-25,2.50931e-15,2.04772e-21,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +8e-05,1001,0.257563,101325,0.285714,1.78714e-08,1.96407e-09,0.142857,6.44319e-10,5.97881e-08,4.48819e-08,1.94576e-10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7.3302e-23,5.08369e-20,4.34563e-21,9.5898e-21,5.92911e-15,1.47211e-19,1.52308e-24,4.15037e-15,5.16203e-21,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +9e-05,1001,0.257563,101325,0.285714,2.79054e-08,3.06883e-09,0.142857,1.00675e-09,9.6717e-08,7.126e-08,3.23261e-10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.15575e-22,1.24941e-19,1.07364e-20,2.44086e-20,9.25804e-15,3.66147e-19,6.18108e-24,6.72309e-15,1.27529e-20,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +0.0001,1001,0.257563,101325,0.285714,4.34074e-08,4.7756e-09,0.142857,1.56701e-09,1.54291e-07,1.12168e-07,5.27033e-10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.83494e-22,3.03823e-19,2.61941e-20,6.07394e-20,1.44011e-14,8.97557e-19,2.42997e-23,1.07352e-14,3.11124e-20,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +0.00011,1001,0.257563,101325,0.285714,6.73643e-08,7.41316e-09,0.142857,2.43365e-09,2.43789e-07,1.75507e-07,8.47834e-10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.98169e-22,7.33968e-19,6.34082e-20,1.48954e-19,2.23492e-14,2.17982e-18,9.35106e-23,1.69718e-14,7.53087e-20,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +0.00012,1001,0.257563,101325,0.285714,1.04403e-07,1.14908e-08,0.142857,3.77543e-09,3.82695e-07,2.73469e-07,1.35138e-09,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5.11511e-22,1.76604e-18,1.52757e-19,3.61866e-19,3.46376e-14,5.26294e-18,3.54727e-22,2.66465e-14,1.81407e-19,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +0.00013,1001,0.257563,101325,0.285714,1.61706e-07,1.77988e-08,0.142856,5.85581e-09,5.98155e-07,4.24863e-07,2.14141e-09,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9.75246e-22,4.24e-18,3.66983e-19,8.73906e-19,5.3649e-14,1.2662e-17,1.33283e-21,4.16386e-14,4.35746e-19,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +0.00014,1001.01,0.257562,101325,0.285713,2.50448e-07,2.75666e-08,0.142856,9.08846e-09,9.3245e-07,6.58686e-07,3.38352e-09,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.18936e-21,1.01705e-17,8.80469e-19,2.10297e-18,8.30914e-14,3.04067e-17,4.97656e-21,6.48599e-14,1.04519e-18,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +0.00015,1001.01,0.257562,101325,0.285712,3.88091e-07,4.27142e-08,0.142856,1.41283e-08,1.45173e-06,1.0196e-06,5.34626e-09,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5.91597e-21,2.44018e-17,2.11209e-18,5.05123e-18,1.28758e-13,7.29809e-17,1.85068e-20,1.00832e-13,2.50632e-18,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +0.00016,1001.01,0.25756,101325,0.285711,6.021e-07,6.62596e-08,0.142855,2.20263e-08,2.26022e-06,1.57631e-06,8.47484e-09,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.85885e-20,5.86299e-17,5.07154e-18,1.21268e-17,1.99764e-13,1.75291e-16,6.86517e-20,1.56599e-13,6.01468e-18,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +0.00017,1001.02,0.257559,101325,0.28571,9.36057e-07,1.02986e-07,0.142853,3.44988e-08,3.52384e-06,2.43423e-06,1.3529e-08,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6.41869e-20,1.41275e-16,1.22061e-17,2.9137e-17,3.10569e-13,4.21916e-16,2.54396e-19,2.4318e-13,1.44632e-17,0,0,0,0,0,0,0,0,0.57143,0,0,0,0,0, +0.00018,1001.03,0.257557,101325,0.285707,1.46008e-06,1.60579e-07,0.142851,5.44251e-08,5.51071e-06,3.75451e-06,2.1852e-08,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.33638e-19,3.42056e-16,2.94968e-17,7.01653e-17,4.84447e-13,1.01949e-15,9.42675e-19,3.77933e-13,3.49032e-17,0,0,0,0,0,0,0,0,0.571431,0,0,0,0,0, +0.00019,1001.05,0.257553,101325,0.285703,2.28947e-06,2.51645e-07,0.142848,8.68167e-08,8.66412e-06,5.78182e-06,3.59183e-08,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8.78711e-19,8.34606e-16,7.17528e-17,1.69666e-16,7.59674e-13,2.47933e-15,3.49679e-18,5.88503e-13,8.47197e-17,0,0,0,0,0,0,0,0,0.571432,0,0,0,0,0, +0.0002,1001.07,0.257546,101325,0.285697,3.61919e-06,3.97439e-07,0.142842,1.40806e-07,1.37401e-05,8.88363e-06,6.04744e-08,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.39841e-18,2.06108e-15,1.76359e-16,4.1307e-16,1.20099e-12,6.09181e-15,1.3e-17,9.19605e-13,2.0752e-16,0,0,0,0,0,0,0,0,0.571434,0,0,0,0,0, +0.00021,1001.12,0.257536,101325,0.285686,5.79253e-06,6.35228e-07,0.142834,2.34036e-07,2.20844e-05,1.36001e-05,1.04954e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.35845e-17,5.1848e-15,4.40443e-16,1.01655e-15,1.92246e-12,1.52105e-14,4.85016e-17,1.44526e-12,5.15453e-16,0,0,0,0,0,0,0,0,0.571437,0,0,0,0,0, +0.00022,1001.2,0.257518,101325,0.285669,9.44657e-06,1.03382e-06,0.142821,4.02924e-07,3.62268e-05,2.06917e-05,1.88534e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5.68606e-17,1.34142e-14,1.12706e-15,2.54391e-15,3.13591e-12,3.89426e-14,1.81831e-16,2.29215e-12,1.30745e-15,0,0,0,0,0,0,0,0,0.571442,0,0,0,0,0, +0.00023,1001.34,0.257486,101325,0.28564,1.58427e-05,1.72868e-06,0.142799,7.28153e-07,6.12487e-05,3.11291e-05,3.50154e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.54566e-16,3.6195e-14,2.99151e-15,6.53216e-15,5.2614e-12,1.03662e-13,6.85294e-16,3.68742e-12,3.42026e-15,0,0,0,0,0,0,0,0,0.57145,0,0,0,0,0, +0.00024,1001.6,0.257424,101325,0.285586,2.76683e-05,3.00677e-06,0.142763,1.40057e-06,0.000108124,4.58403e-05,6.65493e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.25627e-15,1.03818e-13,8.3776e-15,1.74415e-14,9.19601e-12,2.93031e-13,2.58865e-15,6.06394e-12,9.34502e-15,0,0,0,0,0,0,0,0,0.571464,0,0,0,0,0, +0.00025,1002.14,0.257298,101325,0.285482,5.10782e-05,5.523e-06,0.142701,2.89119e-06,0.000202206,6.47325e-05,1.26267e-06,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7.08917e-15,3.23792e-13,2.52762e-14,4.93354e-14,1.70041e-11,9.07167e-13,9.66842e-15,1.03113e-11,2.70061e-14,0,0,0,0,0,0,0,0,0.571489,0,0,0,0,0, +0.00026,1003.3,0.257022,101325,0.285266,0.000100928,1.08607e-05,0.142587,6.34489e-06,0.000404436,8.44131e-05,2.28456e-06,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4.71436e-14,1.11655e-12,8.35911e-14,1.51094e-13,3.37166e-11,3.19862e-12,3.43345e-14,1.84146e-11,8.27155e-14,0,0,0,0,0,0,0,0,0.571538,0,0,0,0,0, +0.00027,1005.91,0.2564,101325,0.284793,0.000213524,2.29337e-05,0.14236,1.43161e-05,0.000859008,9.72006e-05,3.69065e-06,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.65978e-13,4.20088e-12,3.00303e-13,5.07517e-13,7.18903e-11,1.32906e-11,1.0784e-13,3.51494e-11,2.60092e-13,0,0,0,0,0,0,0,0,0.571636,0,0,0,0,0, +0.00028,1011.8,0.255003,101325,0.283716,0.000479461,5.16975e-05,0.141866,3.27363e-05,0.00189858,0.000100065,5.02704e-06,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.08733e-12,1.62322e-11,1.09852e-12,1.8263e-12,1.64269e-10,6.5523e-11,2.92684e-13,7.28477e-11,7.7993e-13,0,0,0,0,0,0,0,0,0.571851,0,0,0,0,0, +0.00029,1025.48,0.251817,101325,0.281099,0.00116946,0.000127636,0.140681,8.03388e-05,0.00439353,9.88063e-05,5.52085e-06,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.69351e-11,6.17277e-11,3.72545e-12,6.56884e-12,4.16852e-10,3.85896e-10,7.69646e-13,1.68372e-10,2.20108e-12,0,0,0,0,0,0,0,0,0.572345,0,0,0,0,0, +0.0003,1061.02,0.243926,101325,0.273486,0.00346169,0.00039005,0.13728,0.000242689,0.0114205,9.46671e-05,4.08676e-06,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.82543e-10,2.6175e-10,1.1677e-11,2.24242e-11,1.35938e-09,3.09806e-09,2.22243e-12,4.8143e-10,7.37048e-12,0,0,0,0,0,0,0,0,0.57362,0,0,0,0,0, +0.00031,1189.8,0.219251,101325,0.235004,0.0183154,0.00230461,0.120495,0.00148364,0.0441399,8.18148e-05,2.03204e-06,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7.09155e-09,2.25495e-09,4.87412e-11,7.75897e-11,9.61106e-09,6.64437e-08,1.19293e-11,2.79156e-09,6.34857e-11,0,0,0,0,0,0,0,0,0.578173,0,0,0,0,0, +0.00032,1695.88,0.159037,101325,0.0543443,0.0830764,0.0198516,0.0340543,0.0157593,0.195112,2.18404e-05,1.90628e-06,-5.9596e-34,1.58834e-34,-2.26046e-34,-1.08834e-34,-5.04796e-33,-1.84653e-32,-1.52518e-27,-2.87382e-28,-1.82175e-32,-1.82013e-33,-3.93904e-35,-2.97807e-36,-3.62626e-35,5.68452e-55,9.24344e-53,1.68551e-53,4.97719e-53,2.23926e-52,1.17444e-53,6.94067e-54,6.82659e-53,7.87984e-56,1.55721e-07,3.19372e-08,2.21274e-10,5.37364e-11,8.64915e-08,7.91623e-06,7.26124e-10,5.40556e-08,2.19398e-09,-1.85099e-35,-4.47727e-33,-1.93384e-36,-2.03829e-37,-2.38306e-38,-1.25433e-36,-3.7902e-35,-3.02195e-35,0.59777,0,-1.35528e-74,1.16289e-75,1.3966e-54,1.67074e-53, +0.00033,1941.08,0.141711,101325,0.0544586,0.0595977,0.0168636,0.0285277,0.0205885,0.210273,1.37397e-05,7.60772e-07,-3.77499e-33,-1.47998e-33,-1.46211e-33,-6.12863e-34,-1.15695e-32,-1.5333e-33,-1.10714e-27,-7.08074e-28,-1.28617e-32,-8.28171e-33,-3.8874e-34,-9.49847e-36,-8.73955e-35,-1.68153e-34,-1.13149e-32,8.98418e-34,4.06244e-33,-2.40765e-33,-2.38205e-34,-1.33722e-33,-6.52791e-33,-3.07696e-35,9.14783e-08,2.95407e-08,4.99549e-10,1.54434e-10,7.91234e-08,2.29924e-05,1.89548e-09,6.34692e-08,3.85039e-09,-7.79241e-36,-8.55743e-34,-1.17551e-37,-5.65716e-37,-9.24256e-38,-6.71544e-37,-2.12836e-35,-1.25074e-35,0.609653,0,-1.29408e-54,-8.1243e-56,2.21742e-34,3.56702e-33, +0.00034,2075.61,0.133985,101325,0.0534066,0.0478093,0.0145174,0.0257508,0.0224831,0.219629,1.05404e-05,4.95065e-07,6.39475e-36,-2.21352e-34,-1.21534e-34,-6.45179e-36,-6.75849e-35,8.27724e-35,-8.99504e-28,-7.86318e-28,-5.31444e-33,-2.06396e-34,-4.7931e-36,-8.40636e-38,-7.49791e-37,-4.33827e-42,-3.92412e-40,1.70201e-41,7.59415e-41,2.58166e-41,-1.22175e-43,2.07009e-41,-2.01989e-40,7.27768e-44,7.45024e-08,2.58461e-08,6.95261e-10,2.50339e-10,7.08025e-08,3.44077e-05,2.76363e-09,6.72805e-08,4.5365e-09,7.93046e-35,7.41064e-33,4.10115e-37,-1.85078e-38,-1.91233e-38,9.86138e-36,3.45428e-34,1.44477e-34,0.616358,0,-5.52585e-62,-3.29045e-64,2.07902e-42,1.57633e-41, +0.00035,2167.33,0.129281,101325,0.0519792,0.0403395,0.0127812,0.0238169,0.0233524,0.22668,8.71298e-06,3.86802e-07,-9.00472e-38,-3.43596e-38,9.15184e-39,5.76149e-40,-1.92886e-39,-1.98591e-39,-9.16365e-28,-7.82162e-28,-4.3078e-33,-1.17798e-35,-1.67862e-39,-2.69987e-41,-7.57548e-41,1.03065e-46,1.0272e-44,1.92524e-45,1.41929e-46,-2.77879e-44,7.34365e-47,-5.4392e-45,3.88994e-45,6.73391e-47,7.34297e-08,2.29438e-08,8.41216e-10,3.38626e-10,6.3871e-08,4.42921e-05,3.60196e-09,7.10571e-08,4.96565e-09,5.53494e-37,4.32701e-35,1.52267e-39,1.93006e-42,-6.20603e-42,7.98338e-38,2.40194e-36,9.39653e-37,0.620997,0,1.68974e-65,1.71486e-67,1.96631e-46,2.61334e-45, +0.00036,2236.04,0.126018,101325,0.0505124,0.0350565,0.0114374,0.022335,0.0237357,0.232354,7.53109e-06,3.30438e-07,4.19286e-33,2.79866e-33,3.76598e-33,2.0792e-34,1.02963e-33,-5.74434e-35,-1.26706e-27,-9.68093e-28,-3.91335e-33,3.07525e-33,4.59127e-35,1.45019e-36,6.24287e-37,5.57809e-50,3.33355e-48,-9.1773e-48,-2.12235e-47,-1.63363e-47,-1.90345e-49,-6.09995e-48,7.42321e-48,-1.4064e-49,7.94741e-08,2.08404e-08,9.63129e-10,4.24049e-10,5.81534e-08,5.37348e-05,4.51354e-09,7.53156e-08,5.33438e-09,-3.34713e-34,-2.58668e-32,-6.50467e-37,-3.51544e-38,-1.13355e-37,-6.3364e-35,-2.31276e-33,-6.31089e-34,0.624507,0,6.01958e-66,1.34816e-67,-2.71833e-49,-4.67892e-48, +0.00037,2290.36,0.123581,101325,0.0491009,0.031077,0.0103618,0.0211378,0.0238564,0.237095,6.7158e-06,2.97127e-07,4.87121e-36,-3.83192e-36,-9.24756e-36,-4.58089e-37,-7.83841e-36,1.6389e-37,-1.21625e-27,-1.02895e-27,-4.2056e-33,-1.99525e-35,-3.87276e-37,-1.27961e-38,-1.48162e-39,1.5764e-51,-3.9731e-50,2.24961e-49,5.75867e-49,2.77062e-49,6.72499e-51,-1.8918e-50,1.4466e-49,-2.35602e-51,8.90386e-08,1.93979e-08,1.07766e-09,5.11671e-10,5.33841e-08,6.3298e-05,5.54908e-09,8.01951e-08,5.71786e-09,-2.67004e-36,-1.84049e-34,-3.5677e-39,-8.01619e-40,-1.766e-38,-5.34537e-37,-2.10577e-35,-6.08963e-36,0.627301,0,-5.14333e-68,-1.36748e-69,1.51853e-51,-5.63042e-51, +0.00038,2334.81,0.121673,101325,0.0477734,0.0279536,0.00947942,0.0201378,0.0238246,0.241152,6.13089e-06,2.76066e-07,-2.83702e-38,1.8745e-38,2.01851e-38,1.21734e-39,1.29377e-38,6.39936e-39,-1.20203e-27,-1.05141e-27,-3.67546e-33,-1.5129e-35,-9.09154e-40,-6.89494e-42,6.64221e-42,-1.87788e-52,-6.51621e-51,-3.76882e-52,-1.30485e-51,-2.46647e-51,-2.09116e-53,-1.1519e-51,2.52065e-52,-8.85982e-53,1.00326e-07,1.84859e-08,1.19564e-09,6.06055e-10,4.93544e-08,7.32683e-05,6.73686e-09,8.56996e-08,6.14826e-09,-3.08127e-38,-1.81898e-36,-2.79693e-41,-6.66465e-44,-6.30641e-41,-8.979e-39,-1.48193e-36,-3.50687e-37,0.629599,0,1.27943e-70,2.00855e-72,-7.82678e-54,-7.45241e-53, +0.00039,2372.07,0.120131,101325,0.0465366,0.0254305,0.00874199,0.0192833,0.023701,0.244683,5.70008e-06,2.62343e-07,-6.27997e-40,-2.43427e-40,-2.39877e-40,-4.37898e-41,-9.5624e-40,-1.27522e-40,-1.19301e-27,-1.06738e-27,-3.27573e-33,-1.50537e-35,-1.13303e-39,-1.79518e-41,-2.22731e-41,-1.65649e-55,-7.79262e-54,4.74391e-55,9.40309e-55,3.31801e-55,9.75756e-57,-8.84874e-55,-6.90912e-54,3.50831e-56,1.12346e-07,1.79976e-08,1.32403e-09,7.1104e-10,4.59107e-08,8.37809e-05,8.09288e-09,9.17738e-08,6.63941e-09,-1.5106e-38,-7.12735e-37,-8.97392e-42,-4.19318e-44,-1.12012e-42,-6.37584e-39,-1.60002e-36,-3.60447e-37,0.631534,0,5.98198e-74,2.07636e-75,1.65544e-56,3.31823e-56, +0.0004,2403.87,0.118853,101325,0.045389,0.0233484,0.00811681,0.0185412,0.0235216,0.247792,5.37672e-06,2.53392e-07,-6.81108e-40,-2.56859e-40,-2.86633e-40,-4.21003e-41,-9.1366e-40,-1.18927e-40,-1.18416e-27,-1.08217e-27,-2.95497e-33,-1.49599e-35,-9.9774e-40,-1.60675e-41,-2.10968e-41,-2.99281e-55,-7.83238e-54,3.48344e-55,1.24369e-54,1.43896e-54,2.17623e-56,-1.76594e-53,-1.49782e-54,-1.35517e-54,1.2452e-07,1.78476e-08,1.4671e-09,8.29684e-10,4.29393e-08,9.48849e-05,9.62505e-09,9.83352e-08,7.19628e-09,-1.76631e-38,-8.23413e-37,-8.81229e-42,-4.18919e-44,-1.60643e-42,-8.18384e-39,-1.91801e-36,-4.17516e-37,0.63319,0,-3.34108e-73,-1.15297e-74,9.38937e-58,-3.04727e-55, +0.00041,2431.36,0.117777,101325,0.0443263,0.0216023,0.00758078,0.0178888,0.0233089,0.250555,5.13049e-06,2.4773e-07,-7.80969e-40,-2.64947e-40,-2.75051e-40,-3.75797e-41,-7.98978e-40,-1.08823e-40,-1.17498e-27,-1.09651e-27,-2.69169e-33,-1.48566e-35,-8.87326e-40,-1.44373e-41,-1.99412e-41,6.11333e-56,1.40774e-54,-7.50561e-55,-2.58652e-54,-2.49141e-54,-4.23021e-56,1.55883e-53,1.71846e-54,1.80103e-55,1.36502e-07,1.79669e-08,1.6272e-09,9.64253e-10,4.03553e-08,0.00010658,1.13353e-08,1.05289e-07,7.81923e-09,-2.07103e-38,-9.6317e-37,-8.93474e-42,-4.23652e-44,-2.18178e-42,-1.0406e-38,-2.28877e-36,-4.81516e-37,0.634626,0,-1.02247e-73,-3.52096e-75,-7.82012e-57,5.34047e-55, +0.00042,2455.37,0.116857,101325,0.0433433,0.0201192,0.00711706,0.0173102,0.0230777,0.253026,4.94082e-06,2.44421e-07,-8.75731e-40,-2.7844e-40,-2.85576e-40,-3.5668e-41,-7.76799e-40,-1.08236e-40,-1.16561e-27,-1.1104e-27,-2.47262e-33,-1.47465e-35,-7.9957e-40,-1.31966e-41,-1.90793e-41,-1.14474e-57,-5.07593e-55,1.44184e-54,3.24858e-54,-2.50864e-55,1.91221e-56,-1.27268e-53,-2.60726e-54,2.40469e-55,1.48088e-07,1.82996e-08,1.80525e-09,1.11624e-09,3.80934e-08,0.00011884,1.32209e-08,1.12539e-07,8.50604e-09,-2.40465e-38,-1.11931e-36,-9.14602e-42,-4.31463e-44,-2.92097e-42,-1.30272e-38,-2.71439e-36,-5.52326e-37,0.635882,0,6.6402e-74,2.49604e-75,1.223e-56,-1.80498e-55, +0.00043,2476.51,0.116063,101325,0.0424345,0.0188468,0.00671299,0.0167934,0.0228378,0.255248,4.79328e-06,2.42837e-07,-9.76018e-40,-2.92816e-40,-2.92008e-40,-3.40046e-41,-7.50681e-40,-1.07151e-40,-1.15623e-27,-1.12377e-27,-2.28847e-33,-1.46336e-35,-7.27069e-40,-1.21578e-41,-1.83094e-41,-2.57666e-55,-8.99055e-54,1.01939e-54,4.2855e-54,1.30434e-54,6.29342e-56,-2.64887e-53,5.91747e-56,-1.03393e-55,1.59159e-07,1.87996e-08,2.00109e-09,1.28642e-09,3.61031e-08,0.000131622,1.52752e-08,1.19989e-07,9.25297e-09,-2.7665e-38,-1.29204e-36,-9.42442e-42,-4.36943e-44,-3.81142e-42,-1.6075e-38,-3.19754e-36,-6.30038e-37,0.636989,0,-4.35149e-74,-1.62376e-75,3.76316e-57,-2.89673e-55, +0.00044,2495.22,0.115371,101325,0.0415948,0.0177463,0.00635881,0.0163294,0.0225961,0.257253,4.67748e-06,2.4253e-07,1.01948e-30,6.7974e-33,-1.34993e-32,-5.67108e-33,-1.90374e-31,-1.17202e-32,-1.12843e-27,-1.13536e-27,-2.29227e-32,-7.47455e-32,-3.13272e-33,-1.24747e-34,-6.38327e-34,-2.19484e-51,-8.02974e-50,-1.71954e-51,-4.73747e-51,-4.73731e-51,-6.78487e-52,-1.09626e-50,-5.02151e-51,-1.18985e-51,1.69652e-07,1.94292e-08,2.21378e-09,1.47489e-09,3.43439e-08,0.000144878,1.74888e-08,1.27548e-07,1.00554e-08,1.66745e-33,1.80254e-32,1.29921e-37,4.12787e-36,-1.4777e-35,1.5542e-34,2.25258e-33,1.64331e-33,0.637971,0,-1.57531e-72,-3.13733e-74,-1.26973e-52,-4.64101e-51, +0.00045,2511.88,0.114764,101325,0.0408195,0.016788,0.00604687,0.0159111,0.0223571,0.259068,4.58583e-06,2.43172e-07,5.2084e-29,1.60189e-30,1.03954e-30,6.00492e-32,6.68418e-31,9.97708e-32,3.28884e-28,-1.87193e-27,7.48598e-31,1.62916e-30,2.34564e-32,8.59246e-34,2.25815e-33,-6.89187e-51,-2.51291e-49,5.64488e-53,2.59171e-52,-6.16816e-53,-2.76038e-53,-2.97243e-50,-6.08713e-51,-2.78446e-51,1.7954e-07,2.01568e-08,2.44183e-09,1.68113e-09,3.27834e-08,0.000158558,1.98503e-08,1.35134e-07,1.09084e-08,1.33817e-31,3.03285e-30,1.89254e-35,1.65688e-34,1.61206e-33,1.78404e-32,5.27258e-31,1.99216e-31,0.638846,0,-8.97028e-73,-2.61256e-74,-5.20374e-54,-7.54063e-53, +0.00046,2526.76,0.114229,101325,0.0401039,0.0159491,0.00577101,0.0155328,0.0221241,0.260714,4.51267e-06,2.44513e-07,-1.79993e-30,8.9413e-31,2.96887e-30,4.64941e-31,2.66436e-29,1.48092e-30,-1.75626e-28,-2.16419e-27,1.14881e-31,2.18435e-30,8.75747e-32,3.31745e-33,-3.80555e-32,-7.8271e-50,-2.83914e-48,-1.89821e-50,-5.28218e-50,-5.36525e-50,-7.17502e-51,-3.938e-49,-1.37958e-49,-4.31927e-50,1.8882e-07,2.09565e-08,2.68333e-09,1.90414e-09,3.1395e-08,0.000172611,2.23465e-08,1.42671e-07,1.18065e-08,2.58568e-32,1.44958e-30,5.39699e-35,3.53879e-35,5.24032e-33,8.91391e-33,2.53089e-31,6.68611e-32,0.639627,0,-3.45405e-72,-5.76231e-74,-1.27928e-51,-4.65737e-50, +0.00047,2540.1,0.113755,101325,0.0394441,0.0152112,0.00552626,0.0151898,0.0218993,0.262209,4.45376e-06,2.46359e-07,-4.95921e-29,-6.06619e-30,-1.85572e-29,-7.90565e-31,-6.43808e-29,-3.01909e-29,1.56173e-27,-4.68205e-28,-5.00029e-30,-7.92448e-31,-2.70607e-30,-7.68881e-32,2.81323e-31,1.00777e-48,3.62506e-47,2.80149e-49,8.26959e-49,6.63103e-49,6.2672e-50,5.29219e-48,1.90498e-48,7.18069e-49,1.97509e-07,2.1807e-08,2.93618e-09,2.14248e-09,3.01565e-08,0.000186992,2.49638e-08,1.50094e-07,1.27446e-08,-3.17152e-31,-4.07724e-30,-6.11203e-34,-9.40696e-34,-9.30166e-32,-1.3611e-32,-3.66944e-31,-2.35267e-31,0.640328,0,-1.06201e-70,-1.57693e-72,1.13461e-50,5.36546e-49, +0.00048,2552.08,0.113334,101325,0.038836,0.0145598,0.0053085,0.0148783,0.0216842,0.263569,4.4059e-06,2.48558e-07,-1.3384e-30,-2.67793e-30,-1.4363e-29,-2.61828e-30,1.10099e-29,-3.09776e-29,6.66907e-28,2.12205e-28,-7.5773e-30,-7.5281e-29,-3.25687e-31,-7.48575e-32,-6.51161e-31,2.59009e-48,9.18525e-47,5.34442e-49,2.00288e-48,5.04576e-49,-2.71812e-50,1.64253e-47,6.27735e-48,3.82608e-48,2.05628e-07,2.26906e-08,3.19811e-09,2.3944e-09,2.90495e-08,0.000201656,2.7688e-08,1.57347e-07,1.37174e-08,-2.01464e-31,-1.00809e-29,1.12178e-34,-4.80262e-34,-3.00804e-31,-1.06646e-31,-2.03099e-30,-5.64969e-31,0.640958,0,-1.34702e-69,-3.17622e-71,-7.12752e-51,2.88549e-49, +0.00049,2562.86,0.112958,101325,0.0382762,0.0139828,0.0051143,0.0145949,0.0214798,0.264806,4.36664e-06,2.50991e-07,1.01774e-30,-2.90564e-30,-2.56067e-29,-2.39636e-30,-1.09405e-28,-3.52991e-29,6.40319e-28,3.50235e-28,1.7976e-30,-2.37314e-29,-2.372e-30,-1.1688e-31,-3.98877e-31,1.73655e-48,6.38828e-47,8.60952e-49,3.52158e-48,1.3204e-48,5.17716e-50,5.5508e-48,-3.78378e-49,3.15588e-48,2.1321e-07,2.35931e-08,3.46689e-09,2.65793e-09,2.80584e-08,0.000216564,3.05053e-08,1.64384e-07,1.47201e-08,2.36315e-32,1.56348e-30,-3.68594e-34,-3.56012e-34,-5.30303e-32,5.29945e-32,1.59674e-31,2.70021e-32,0.641524,0,-2.32167e-69,-7.83995e-71,-1.89936e-51,-9.10561e-50, +0.0005,2572.58,0.112622,101325,0.0377613,0.0134704,0.00494075,0.0143369,0.0212865,0.265933,4.3341e-06,2.53563e-07,-4.8927e-30,4.26454e-31,3.44062e-30,2.52719e-31,4.62776e-30,3.11025e-32,3.71969e-28,4.05209e-28,1.33716e-30,2.7831e-29,1.3808e-31,1.26702e-32,7.24998e-32,1.47794e-49,5.25207e-48,-4.5229e-51,5.10041e-49,1.09818e-48,1.95292e-50,8.96062e-49,1.84681e-48,-6.51957e-48,2.20289e-07,2.45031e-08,3.74035e-09,2.93096e-09,2.71695e-08,0.000231682,3.34022e-08,1.71166e-07,1.57479e-08,-3.6281e-32,1.8828e-31,1.94933e-35,6.86072e-35,1.55892e-32,7.32982e-33,9.40025e-32,2.97597e-32,0.642034,0,1.04705e-69,8.70963e-71,3.15197e-52,-2.09972e-49, +0.00051,2581.35,0.112321,101325,0.037288,0.0130142,0.00478539,0.0141017,0.0211045,0.266959,4.30687e-06,2.56199e-07,9.44332e-31,5.62176e-32,1.78333e-31,1.39973e-32,-1.98296e-31,-4.32288e-30,4.31874e-28,4.35467e-28,-1.73484e-31,-6.71415e-31,8.34981e-32,-5.49495e-33,-4.41727e-33,-3.42353e-51,-1.14501e-49,1.28875e-51,-7.32361e-52,3.96604e-52,-1.19228e-52,-2.07016e-50,4.40253e-51,-2.39303e-51,2.26901e-07,2.54113e-08,4.01642e-09,3.21134e-09,2.63715e-08,0.000246977,3.63662e-08,1.77664e-07,1.67967e-08,3.28302e-33,1.28384e-31,-1.26809e-35,1.94246e-35,6.71688e-34,1.02531e-33,2.45748e-32,4.86634e-33,0.642495,0,-3.34704e-72,-6.84229e-74,6.51193e-54,-1.97093e-52, +0.00052,2589.27,0.112051,101325,0.0368534,0.0126072,0.00464611,0.0138873,0.0209339,0.267894,4.28382e-06,2.58842e-07,5.10775e-30,-1.67665e-30,-5.94809e-31,-4.08674e-32,5.80525e-30,6.33244e-31,5.15784e-28,5.55621e-28,-2.4654e-31,1.92999e-30,-8.39241e-31,-1.82565e-32,-2.9255e-32,-3.16287e-50,-1.14364e-48,-4.15826e-51,-1.227e-50,-2.62279e-50,-3.13879e-51,-1.18446e-49,-2.00609e-50,-1.32669e-50,2.33083e-07,2.63106e-08,4.29322e-09,3.49694e-09,2.56541e-08,0.000262422,3.93856e-08,1.83858e-07,1.78626e-08,1.20412e-32,-4.70274e-32,1.30351e-34,-2.782e-34,-7.49547e-33,-5.08203e-34,1.74928e-32,-5.52322e-33,0.64291,0,-4.28712e-72,4.29994e-74,-4.17309e-52,-1.29673e-50, +0.00053,2596.44,0.111809,101325,0.0364548,0.0122436,0.00452108,0.0136917,0.0207745,0.268746,4.26411e-06,2.61448e-07,-1.53938e-29,2.25795e-29,5.26313e-30,1.34055e-30,5.85977e-29,-3.18661e-29,5.97783e-28,6.22657e-28,7.74216e-31,-4.63889e-30,-4.60076e-30,-2.481e-32,-1.01605e-31,2.04859e-49,7.30367e-48,1.5575e-50,3.79971e-50,2.65435e-50,4.0128e-51,1.21686e-48,4.64021e-49,1.60848e-49,2.3887e-07,2.71957e-08,4.56909e-09,3.78573e-09,2.50087e-08,0.000277993,4.24497e-08,1.89733e-07,1.8942e-08,4.41465e-32,3.27067e-30,3.83061e-34,1.51197e-33,-5.22745e-32,1.55557e-32,1.2791e-31,1.12574e-31,0.643285,0,7.23583e-72,1.70469e-73,1.34703e-51,6.4252e-50, +0.00054,2602.91,0.111591,101325,0.0360894,0.0119181,0.0044087,0.0135131,0.0206259,0.269522,4.24708e-06,2.63984e-07,1.85574e-29,-1.50123e-29,-1.45941e-29,-6.26077e-31,-4.91134e-29,1.50083e-30,7.28748e-28,6.91874e-28,-9.46825e-31,-2.50539e-30,1.97675e-31,-3.60799e-32,3.2498e-32,-7.58111e-51,-5.97473e-49,4.50912e-50,1.44143e-49,1.36662e-49,1.06116e-50,-3.65192e-49,-2.1613e-49,-1.38135e-49,2.44297e-07,2.80625e-08,4.84256e-09,4.07582e-09,2.44276e-08,0.000293668,4.5549e-08,1.95281e-07,2.00318e-08,9.11338e-32,3.07119e-31,-3.62266e-34,-7.70977e-34,-4.26888e-33,2.51397e-32,1.41535e-30,2.75745e-32,0.643624,0,-2.81449e-72,-6.05086e-74,1.92801e-51,6.25648e-50, +0.00055,2608.77,0.111394,101325,0.0357549,0.0116265,0.0043076,0.0133501,0.0204878,0.270228,4.23221e-06,2.66424e-07,-7.58204e-30,1.65272e-30,1.56029e-29,1.15567e-30,4.12464e-30,1.93917e-30,8.95105e-28,8.1529e-28,7.87543e-31,1.27928e-29,1.09383e-30,3.24088e-32,1.20135e-31,-4.22261e-49,-1.65419e-47,-8.20377e-50,-3.41889e-49,-1.45881e-49,-8.39243e-52,-2.16752e-48,-6.18733e-49,-4.09474e-49,2.49397e-07,2.8908e-08,5.11236e-09,4.36544e-09,2.3904e-08,0.000309429,4.86751e-08,2.005e-07,2.11294e-08,-8.99987e-32,2.44149e-30,-3.60176e-35,3.79072e-34,1.54098e-31,8.11419e-32,1.31784e-31,9.49381e-32,0.64393,0,6.00693e-71,1.40221e-72,7.41069e-52,-4.52563e-50, +0.00056,2614.08,0.111217,101325,0.0354488,0.0113648,0.00421656,0.0132013,0.0203598,0.270871,4.21911e-06,2.68753e-07,-2.79256e-29,4.50947e-30,1.41506e-29,9.75839e-31,7.37244e-29,1.97944e-29,4.63884e-28,8.63028e-28,-8.18675e-31,4.08671e-30,1.4128e-30,5.60336e-32,6.68019e-32,3.54284e-49,1.46673e-47,-5.9899e-50,-1.93913e-49,-2.03536e-49,-8.82263e-51,3.03428e-48,1.2182e-48,1.46528e-48,2.542e-07,2.97305e-08,5.37747e-09,4.65309e-09,2.34319e-08,0.000325261,5.18204e-08,2.05391e-07,2.22322e-08,-2.36962e-31,-2.16423e-30,3.0969e-34,4.63861e-35,-2.07796e-31,-1.46494e-31,-1.297e-30,-7.83059e-32,0.644207,0,-2.76768e-71,-2.10005e-72,-6.32516e-52,-7.89298e-50, +0.00057,2618.88,0.111058,101325,0.0351691,0.0111297,0.0041345,0.0130654,0.0202412,0.271457,4.20746e-06,2.70959e-07,2.66518e-29,-1.06137e-31,-3.77447e-29,-3.29018e-30,-1.01595e-28,-3.35704e-29,4.1052e-28,6.2936e-28,-1.66239e-30,-3.23609e-29,-2.35658e-30,-1.08683e-31,-3.69947e-31,4.42813e-49,1.82616e-47,2.06528e-49,1.03262e-48,4.64752e-49,1.17898e-50,3.05152e-49,-2.06886e-49,-1.27143e-48,2.58735e-07,3.05286e-08,5.63706e-09,4.93738e-09,2.30059e-08,0.000341149,5.49787e-08,2.09961e-07,2.33384e-08,3.47061e-31,-1.21467e-30,-3.7456e-34,-3.73714e-34,-6.3381e-32,2.38454e-32,-3.40913e-31,-7.83229e-32,0.644457,0,-1.63457e-70,-3.52017e-72,-1.8278e-51,1.47634e-50, +0.00058,2623.23,0.110914,101325,0.0349136,0.0109184,0.00406048,0.0129413,0.0201316,0.27199,4.19702e-06,2.73036e-07,1.74765e-29,-8.73586e-30,1.85617e-29,2.28543e-30,5.92918e-29,3.01654e-29,1.77799e-28,4.50088e-28,1.6449e-30,3.70286e-29,1.47658e-30,7.25898e-32,4.17959e-31,-1.56103e-48,-6.53886e-47,-1.71943e-49,-1.09103e-48,-2.42712e-49,-5.36439e-51,-7.79143e-48,-2.65471e-48,-3.08862e-48,2.63028e-07,3.1302e-08,5.89047e-09,5.21721e-09,2.26215e-08,0.000357083,5.81444e-08,2.14218e-07,2.44461e-08,-1.59693e-32,-6.46427e-30,1.23883e-34,1.66899e-34,5.6445e-31,1.57541e-31,1.9734e-31,-3.34999e-31,0.644683,0,3.81601e-70,1.60356e-71,1.27024e-51,2.20768e-49, +0.00059,2627.17,0.110784,101325,0.0346804,0.0107283,0.00399367,0.0128279,0.0200305,0.272475,4.1876e-06,2.7498e-07,-4.70416e-29,-7.55686e-30,3.92765e-29,2.97863e-30,7.95564e-29,2.32776e-29,1.39337e-28,4.75745e-28,-3.87293e-30,6.38058e-30,1.57466e-30,8.77766e-32,2.17544e-31,1.35332e-48,5.62755e-47,-1.73041e-49,-9.96855e-49,-6.39099e-49,-1.52889e-50,1.29113e-47,4.4694e-48,1.19674e-47,2.67102e-07,3.20504e-08,6.13725e-09,5.49162e-09,2.22744e-08,0.000373051,6.13128e-08,2.18172e-07,2.55538e-08,-7.92096e-31,1.35787e-30,3.76002e-34,-8.99706e-35,-6.86846e-31,-3.18097e-31,1.52803e-30,7.95958e-32,0.644887,0,-1.32235e-70,-1.48041e-71,3.77994e-51,-1.56413e-49, +0.0006,2630.73,0.110667,101325,0.0344678,0.0105571,0.00393332,0.0127242,0.0199372,0.272916,4.17904e-06,2.76792e-07,-8.90484e-30,2.77716e-29,-7.04229e-29,-6.20342e-30,-2.49747e-28,-8.7313e-29,7.38483e-28,3.77959e-28,6.93303e-30,-4.6563e-29,-4.60843e-30,-2.69438e-31,-1.03792e-30,6.26384e-49,3.01504e-47,5.82104e-49,3.89789e-48,1.48065e-48,3.75914e-50,-1.04842e-47,-2.60355e-48,-1.69787e-47,2.7098e-07,3.27743e-08,6.37705e-09,5.75987e-09,2.19608e-08,0.000389045,6.44801e-08,2.21836e-07,2.66604e-08,5.72124e-31,1.62059e-29,-1.31595e-33,-2.82546e-34,5.48222e-32,3.59066e-31,-3.15732e-30,7.56442e-31,0.645071,0,-7.67708e-70,-2.30469e-71,-5.79406e-51,-5.38491e-49, +0.00061,2633.96,0.110561,101325,0.034274,0.0104028,0.00387877,0.0126295,0.0198514,0.273316,4.17122e-06,2.78473e-07,7.24022e-29,1.30603e-29,-2.8923e-29,-2.15836e-30,7.57858e-29,6.06395e-29,1.73968e-29,3.99765e-28,4.09197e-30,2.68127e-29,5.15372e-31,5.64022e-32,4.52287e-31,-3.30727e-48,-1.51305e-46,-4.11732e-50,-9.13773e-49,1.33478e-49,-1.16145e-51,-1.48816e-47,-3.86115e-48,-2.99799e-47,2.74681e-07,3.34742e-08,6.60969e-09,6.02137e-09,2.16774e-08,0.000405058,6.7643e-08,2.25224e-07,2.77649e-08,2.0044e-30,2.08076e-29,4.85163e-34,3.64611e-34,-1.50254e-31,5.7162e-31,1.5689e-30,1.02052e-30,0.645237,0,1.64521e-69,9.8009e-71,-7.23053e-51,9.66873e-49, +0.00062,2636.89,0.110465,101325,0.0340976,0.0102638,0.00382944,0.0125429,0.0197724,0.273681,4.16404e-06,2.80028e-07,-1.43309e-29,-4.15082e-29,4.50353e-29,3.58777e-30,2.09583e-29,-4.7306e-29,4.67324e-28,4.0224e-28,-1.15399e-29,-4.31118e-29,1.10249e-30,5.27578e-32,4.14483e-32,5.34255e-48,2.30143e-46,-2.55601e-49,-1.62312e-48,-1.06405e-48,-2.12305e-50,3.46429e-47,9.52486e-48,7.48939e-47,2.78222e-07,3.41509e-08,6.83509e-09,6.27573e-09,2.14211e-08,0.000421083,7.07989e-08,2.28351e-07,2.88664e-08,-1.59613e-30,-3.3662e-29,3.09556e-34,-7.98196e-34,-3.97144e-31,-1.05427e-30,5.05496e-30,-1.58673e-30,0.645387,0,-2.05268e-69,-1.37476e-70,8.97306e-51,-1.13319e-48, +0.00063,2639.54,0.110379,101325,0.033937,0.0101383,0.00378479,0.0124638,0.0196997,0.274012,4.15742e-06,2.81461e-07,-9.56331e-29,-1.47033e-29,2.52685e-29,2.98691e-30,-1.85799e-28,-1.11623e-28,8.87286e-28,4.40166e-28,1.49612e-30,4.28744e-30,-1.12046e-30,-1.51894e-31,-1.11007e-30,5.81126e-49,5.2201e-47,3.07719e-49,4.63239e-48,1.296e-48,3.4404e-50,-3.53732e-47,-6.85323e-48,-9.8422e-48,2.81621e-07,3.48054e-08,7.05327e-09,6.52266e-09,2.11894e-08,0.000437116,7.39456e-08,2.31231e-07,2.99643e-08,-3.05424e-30,-1.52019e-29,-1.43955e-33,-3.82178e-34,4.356e-31,8.77527e-31,-3.94241e-30,-1.18113e-30,0.645522,0,-3.59769e-69,-1.98099e-70,9.7249e-51,-1.74107e-48, +0.00064,2641.94,0.110301,101325,0.0337911,0.010025,0.00374436,0.0123914,0.019633,0.274313,4.15129e-06,2.82778e-07,3.95182e-29,6.45373e-29,-2.05933e-29,-2.1706e-30,3.46999e-28,2.61857e-28,-3.51115e-28,5.43907e-28,1.21719e-29,7.32811e-29,3.13635e-30,2.81819e-31,1.79431e-30,-4.2216e-48,-2.08342e-46,-8.47939e-49,-7.427e-48,-1.75049e-48,-4.61201e-50,7.29625e-47,1.33841e-47,-4.95895e-47,2.84892e-07,3.54388e-08,7.26431e-09,6.76202e-09,2.09798e-08,0.00045315,7.70813e-08,2.3388e-07,3.10581e-08,3.30513e-30,3.04602e-29,1.60189e-33,1.78429e-33,-6.20878e-31,-2.14128e-30,-1.61056e-29,1.77584e-30,0.645644,0,9.88097e-69,5.71605e-70,-1.54153e-50,5.17745e-48, +0.00065,2644.11,0.110231,101325,0.0336584,0.00992276,0.00370773,0.0123251,0.0195717,0.274586,4.14559e-06,2.83985e-07,2.18414e-28,-7.99228e-29,-8.14287e-29,-7.24021e-30,-3.8553e-28,-3.10044e-28,1.51979e-27,5.50646e-28,-2.03124e-29,-2.89452e-28,-6.57612e-30,-3.52223e-31,-1.28693e-30,9.77473e-48,4.32867e-46,9.42377e-49,4.41592e-48,4.01386e-49,1.71527e-50,-9.77233e-47,-2.49108e-47,2.37072e-46,2.88046e-07,3.60521e-08,7.46838e-09,6.99376e-09,2.07901e-08,0.000469184,8.02049e-08,2.36313e-07,3.21474e-08,1.2681e-30,-1.41169e-28,-9.92741e-34,-2.70707e-33,1.83511e-30,-9.23236e-32,1.88136e-31,-6.07391e-30,0.645754,0,-1.63988e-68,-9.82999e-70,3.19729e-50,-8.68292e-48, +0.00066,2646.07,0.110167,101325,0.0335379,0.00983037,0.00367453,0.0122644,0.0195154,0.274835,4.14028e-06,2.85088e-07,5.11239e-30,-1.53247e-30,-7.75094e-30,-8.21823e-31,-3.28985e-29,-9.67936e-30,4.11871e-28,5.30602e-28,-5.20967e-30,-2.0067e-29,-8.61956e-31,-2.38343e-32,-1.28996e-32,-2.59911e-48,-9.72742e-47,-1.63968e-49,-9.29396e-49,-3.18476e-49,-1.60157e-50,-1.08757e-47,-9.08256e-48,9.04273e-48,2.91097e-07,3.66464e-08,7.66568e-09,7.21794e-09,2.06184e-08,0.000485212,8.33152e-08,2.38544e-07,3.3232e-08,2.83189e-31,8.78225e-30,-6.16683e-35,-1.62786e-34,-5.69989e-32,-3.24813e-31,9.87514e-30,1.20009e-30,0.645852,0,1.72417e-69,4.63179e-71,-1.28868e-50,-5.54269e-49, +0.00067,2647.85,0.110109,101325,0.0334286,0.00974687,0.0036444,0.0122088,0.0194637,0.27506,4.13531e-06,2.86095e-07,-1.5112e-29,-1.84119e-30,-6.87628e-30,-9.02202e-31,-3.92607e-29,-2.48317e-29,1.30042e-28,4.5659e-28,-2.91735e-30,-1.48486e-29,-8.45404e-31,-3.43881e-32,-7.62577e-32,2.80195e-47,1.01492e-45,6.10058e-49,7.51351e-49,-4.30158e-49,1.45706e-51,1.67641e-46,4.2172e-47,3.21948e-47,2.94054e-07,3.7223e-08,7.85645e-09,7.43466e-09,2.0463e-08,0.000501233,8.64115e-08,2.40588e-07,3.43115e-08,3.59197e-31,1.97522e-29,-2.89747e-35,-8.40064e-35,-3.21441e-31,2.442e-31,2.44744e-30,7.46026e-31,0.645941,0,8.88026e-68,2.06448e-69,1.63817e-50,4.36646e-49, +0.00068,2649.46,0.110057,101325,0.0333294,0.00967138,0.00361706,0.0121579,0.0194163,0.275264,4.13066e-06,2.87011e-07,-6.84169e-29,-2.36745e-30,-1.03614e-30,-3.58e-32,2.94771e-30,2.59792e-30,-1.64052e-27,-1.82056e-28,-1.9766e-30,-9.94517e-30,-4.63217e-32,1.99962e-33,5.24545e-33,-7.11421e-48,-2.84767e-46,-4.3895e-49,-1.46621e-48,-1.16231e-48,-7.2993e-50,-3.79588e-47,-1.49161e-47,-9.23336e-48,2.96927e-07,3.77829e-08,8.04096e-09,7.64411e-09,2.03222e-08,0.000517243,8.94933e-08,2.42458e-07,3.5386e-08,-1.12782e-32,6.73639e-30,5.53004e-35,-8.01197e-34,-3.91426e-32,1.32754e-31,3.26402e-30,3.08116e-31,0.646021,0,-8.16387e-69,-4.03276e-70,-1.6724e-50,-7.6626e-49, +0.00069,2650.92,0.11001,101325,0.0332395,0.00960309,0.00359223,0.0121112,0.0193727,0.27545,4.12628e-06,2.87842e-07,1.8524e-28,6.27672e-30,4.56642e-30,2.61919e-31,1.87904e-30,-3.01998e-31,-3.13761e-27,-2.18018e-27,2.10559e-30,5.17578e-30,6.51183e-32,3.32014e-33,8.80241e-33,2.68677e-48,1.06523e-46,1.51424e-49,5.51637e-49,2.72814e-49,1.11188e-50,1.54378e-47,6.81678e-48,4.56997e-48,2.99724e-07,3.83273e-08,8.2195e-09,7.84652e-09,2.01947e-08,0.000533241,9.25603e-08,2.44168e-07,3.64554e-08,3.04109e-31,5.20659e-30,5.19077e-36,2.97518e-34,4.80127e-32,8.01574e-32,8.93354e-31,5.4021e-31,0.646093,0,-1.00099e-68,-1.95088e-70,3.09927e-51,1.77903e-49, +0.0007,2652.24,0.109968,101325,0.0331581,0.00954132,0.00356967,0.0120683,0.0193328,0.275619,4.12216e-06,2.88596e-07,-2.27138e-28,-8.27071e-30,-6.91307e-30,-4.30347e-31,-5.36102e-30,-7.84251e-31,-1.99876e-27,-1.98649e-27,-4.91175e-30,-1.90237e-29,-1.72674e-31,-5.47699e-33,-1.56731e-32,1.82968e-49,4.93917e-48,-2.62298e-50,-9.39024e-50,1.58921e-50,2.4633e-51,-1.48711e-48,-2.00626e-48,-9.03007e-49,3.02452e-07,3.88571e-08,8.39237e-09,8.04215e-09,2.00791e-08,0.000549225,9.56122e-08,2.4573e-07,3.75197e-08,-1.12585e-30,-4.34002e-30,-3.99873e-35,-7.60656e-34,-2.16849e-32,4.76124e-33,1.18725e-30,-6.81927e-31,0.646157,0,3.97088e-69,1.56588e-70,-6.46068e-52,-4.89574e-50, +0.00071,2653.43,0.10993,101325,0.0330843,0.0094854,0.00354915,0.0120289,0.019296,0.275771,4.11826e-06,2.89278e-07,3.46195e-29,1.00229e-30,4.54431e-31,1.01821e-32,-1.05493e-30,-5.19889e-31,-6.16565e-27,-3.26228e-27,-3.18973e-31,-1.88993e-30,-1.89597e-32,-2.17931e-33,-4.26311e-33,2.05274e-48,7.79655e-47,5.81602e-50,1.93759e-49,7.73721e-50,3.76561e-51,1.31225e-47,5.79874e-48,2.98014e-48,3.05118e-07,3.93735e-08,8.55988e-09,8.23128e-09,1.99744e-08,0.000565193,9.8649e-08,2.47155e-07,3.85788e-08,-3.79358e-32,-2.10217e-29,-5.61249e-35,3.574e-35,-6.64924e-32,-2.29826e-31,-6.83077e-30,-1.05004e-30,0.646214,0,-2.72776e-69,-7.82434e-71,1.42574e-51,7.15847e-50, +0.00072,2654.51,0.109895,101325,0.0330176,0.00943478,0.00353048,0.0119927,0.0192623,0.27591,4.11457e-06,2.89893e-07,-1.45325e-29,-6.58563e-31,-6.37826e-31,-3.74801e-32,-2.8926e-31,6.3634e-32,-6.2701e-27,-5.13016e-27,-2.59015e-31,-9.09576e-31,-1.20421e-32,-3.81357e-34,-8.33928e-34,-1.27105e-48,-4.60081e-47,-2.57271e-50,-5.64923e-50,4.23999e-51,2.6325e-52,-9.31274e-48,-4.69326e-48,-1.74702e-48,3.07728e-07,3.98772e-08,8.72231e-09,8.4142e-09,1.98794e-08,0.000581144,1.01671e-07,2.48455e-07,3.96329e-08,-2.88097e-32,3.37447e-30,8.6682e-36,-6.52269e-35,2.89445e-32,4.14793e-32,8.40366e-31,1.01313e-31,0.646266,0,2.83383e-70,1.43041e-71,-9.70184e-52,-4.2152e-50, +0.00073,2655.48,0.109864,101325,0.0329573,0.00938894,0.00351348,0.0119593,0.0192313,0.276036,4.11107e-06,2.90447e-07,-1.2583e-29,-4.41169e-31,-3.33116e-31,-2.5225e-32,-6.64711e-31,-2.19873e-31,-5.50186e-27,-6.13623e-27,-1.82373e-31,-5.09248e-31,-1.16981e-32,-5.29196e-34,-1.2955e-33,3.04318e-49,9.86033e-48,1.07802e-50,3.10898e-50,-6.72502e-51,-5.94498e-52,2.17294e-48,7.05358e-49,5.26202e-49,3.10287e-07,4.03693e-08,8.88e-09,8.59125e-09,1.97933e-08,0.000597077,1.04678e-07,2.49639e-07,4.0682e-08,2.22315e-32,2.55539e-30,1.97277e-37,-5.52562e-35,1.10776e-32,3.58188e-32,2.06523e-30,1.95728e-31,0.646312,0,-5.45816e-70,-2.37316e-71,2.53849e-52,1.14592e-50, +0.00074,2656.36,0.109836,101325,0.0329028,0.00934741,0.00349798,0.0119286,0.0192028,0.27615,4.10775e-06,2.90945e-07,-7.13878e-29,-2.27756e-30,-1.07212e-30,-4.96014e-32,3.36214e-31,2.36039e-31,-7.47683e-27,-6.39903e-27,-3.40258e-31,1.94841e-30,2.39489e-32,8.43262e-34,4.79435e-33,-2.63083e-48,-1.04348e-46,-8.91361e-50,-3.23375e-49,-1.91962e-49,-9.4821e-51,-1.32256e-47,-4.83511e-48,-3.75557e-48,3.12801e-07,4.08506e-08,9.03322e-09,8.76273e-09,1.97152e-08,0.00061299,1.0767e-07,2.50719e-07,4.17262e-08,1.71301e-31,5.19575e-31,3.0487e-35,-1.53327e-34,3.00168e-32,-1.60483e-32,-3.82034e-31,2.15973e-31,0.646353,0,2.83066e-69,7.28576e-71,-2.11114e-51,-7.89612e-50, +0.00075,2657.16,0.109811,101325,0.0328535,0.00930978,0.00348385,0.0119003,0.0191766,0.276253,4.10458e-06,2.91391e-07,-5.62684e-29,-2.35698e-30,-2.62348e-30,-1.79369e-31,-3.01396e-30,-5.83602e-31,-1.03465e-26,-7.68589e-27,-7.35931e-33,-1.96944e-30,-8.64516e-32,-4.23699e-33,-1.47311e-32,8.8558e-49,3.07871e-47,3.0719e-50,1.02145e-49,9.43363e-50,4.67414e-51,1.01156e-48,1.90317e-49,1.82815e-49,3.15272e-07,4.13219e-08,9.18225e-09,8.92896e-09,1.96444e-08,0.000628883,1.10648e-07,2.51701e-07,4.27657e-08,-6.49124e-31,-1.30236e-29,-7.73551e-35,-1.15453e-34,-2.04281e-32,-1.22423e-31,-3.66839e-30,-1.05938e-30,0.646389,0,-6.56058e-70,-2.83759e-72,1.10322e-51,1.69468e-50, +0.00076,2657.88,0.109788,101325,0.0328091,0.00927567,0.00347095,0.0118741,0.0191524,0.276347,4.10155e-06,2.9179e-07,3.30779e-29,1.45521e-30,1.52735e-30,9.98784e-32,1.10494e-30,5.8084e-32,-9.20245e-27,-9.44727e-27,8.81419e-31,4.34811e-30,2.71109e-32,3.28023e-33,7.88045e-33,4.93302e-49,2.7874e-47,2.59557e-50,1.28602e-49,3.09608e-50,8.78134e-52,5.05308e-48,2.34149e-48,2.75581e-48,3.17705e-07,4.17839e-08,9.32737e-09,9.09024e-09,1.958e-08,0.000644756,1.13611e-07,2.52595e-07,4.38006e-08,1.12817e-30,2.14119e-29,7.80635e-35,1.69042e-34,4.68892e-32,1.92665e-31,3.68553e-30,1.24341e-30,0.646421,0,-1.84935e-69,-6.96708e-71,9.24628e-53,4.15992e-50, +0.00077,2658.53,0.109767,101325,0.0327691,0.00924474,0.00345917,0.0118499,0.0191301,0.276431,4.09865e-06,2.92146e-07,-2.1884e-29,-1.16285e-30,-1.23433e-30,-8.04109e-32,-5.93324e-31,8.08353e-32,-8.47016e-27,-1.0187e-26,-1.14337e-31,-4.58637e-31,-1.39793e-32,-5.49588e-34,-3.1184e-33,-7.1136e-49,-4.04138e-47,-4.78917e-50,-2.36155e-49,-9.28511e-50,-2.98376e-51,-5.31167e-48,-2.33103e-48,-3.49919e-48,3.20103e-07,4.22374e-08,9.46884e-09,9.24689e-09,1.95217e-08,0.000660607,1.16561e-07,2.53409e-07,4.4831e-08,-7.04359e-31,1.86392e-30,-1.10857e-35,-4.03584e-35,4.00237e-32,1.13659e-31,3.62877e-30,-7.09595e-32,0.64645,0,3.18093e-69,1.04684e-70,-9.38862e-53,-3.85685e-50, +0.00078,2659.11,0.109748,101325,0.0327331,0.00921669,0.0034484,0.0118275,0.0191095,0.276508,4.09587e-06,2.92463e-07,2.60418e-29,1.37532e-30,1.06535e-30,6.22104e-32,-3.4557e-31,-3.82899e-31,-7.62124e-27,-1.00884e-26,5.58494e-31,2.17194e-30,1.6285e-32,4.11517e-34,-2.22905e-33,1.7676e-48,8.84548e-47,8.46314e-50,3.76928e-49,1.91962e-49,7.6532e-51,1.07533e-47,4.37618e-48,4.83427e-48,3.22469e-07,4.26829e-08,9.60693e-09,9.39922e-09,1.94686e-08,0.000676436,1.19497e-07,2.54148e-07,4.58571e-08,8.86816e-31,-2.92747e-30,3.81279e-35,1.68813e-34,-7.25469e-32,-2.24807e-31,-3.75415e-30,2.21653e-31,0.646475,0,-3.54435e-69,-1.00987e-70,8.85919e-52,8.01546e-50, +0.00079,2659.64,0.109732,101325,0.0327006,0.00919125,0.00343854,0.0118067,0.0190905,0.276578,4.0932e-06,2.92743e-07,-1.1058e-29,-6.15179e-31,-5.76378e-31,-3.59101e-32,2.21724e-32,1.19265e-31,-7.49375e-27,-9.77891e-27,-9.35887e-32,-6.93974e-31,-8.59593e-33,-2.0387e-34,4.03784e-34,-5.24476e-51,-1.10295e-47,-1.68743e-50,-1.28534e-49,-7.69266e-50,-2.59645e-51,1.69545e-49,5.02342e-49,-1.41561e-48,3.24807e-07,4.31211e-08,9.74187e-09,9.54749e-09,1.94205e-08,0.000692242,1.22419e-07,2.54821e-07,4.6879e-08,-3.28487e-31,8.35457e-30,7.22044e-36,-7.68432e-35,-2.00464e-32,1.56513e-31,1.09635e-30,8.80902e-32,0.646497,0,1.80175e-69,5.09596e-71,4.50074e-52,-6.83031e-51, +0.0008,2660.12,0.109717,101325,0.0326715,0.00916816,0.00342951,0.0117873,0.019073,0.276641,4.09063e-06,2.92991e-07,1.33439e-29,1.03763e-31,-1.0556e-30,-9.06e-32,-2.1092e-30,-4.06932e-31,-7.10577e-27,-9.51599e-27,6.54138e-31,-3.1357e-31,-5.39303e-32,-1.76232e-33,-8.10547e-33,1.51373e-48,5.57305e-47,-1.46802e-51,-1.23378e-49,2.45774e-50,4.11709e-51,8.57204e-48,2.87428e-48,-2.22749e-48,3.27117e-07,4.35525e-08,9.87386e-09,9.69198e-09,1.93767e-08,0.000708025,1.25329e-07,2.55433e-07,4.78968e-08,-5.05119e-31,-1.39132e-29,-2.10241e-35,-9.75086e-35,-5.12653e-32,-1.00792e-31,-1.73192e-30,-8.4419e-31,0.646516,0,4.69481e-69,1.84943e-70,1.75797e-51,6.16569e-50, +0.00081,2660.55,0.109703,101325,0.0326453,0.0091472,0.00342122,0.0117693,0.0190567,0.276698,4.08815e-06,2.93208e-07,2.20778e-29,1.00403e-30,1.58485e-30,1.1331e-31,2.1031e-30,3.99085e-31,-6.1342e-27,-9.04562e-27,1.09603e-31,1.97837e-30,5.59815e-32,2.15158e-33,7.17679e-33,-9.38564e-49,-3.68303e-47,-1.3004e-50,3.51677e-50,-4.11551e-50,-3.8409e-51,-4.7647e-48,-1.33992e-48,1.47353e-48,3.29403e-07,4.39776e-08,1.00031e-08,9.83295e-09,1.93369e-08,0.000723785,1.28227e-07,2.55988e-07,4.89106e-08,2.31752e-31,-3.26853e-30,-1.59662e-35,2.27554e-34,1.91738e-32,-5.86756e-32,-2.07426e-30,-2.52948e-32,0.646533,0,-3.11397e-69,-1.31087e-70,-1.28715e-51,-4.8286e-50, +0.00082,2660.94,0.109691,101325,0.0326219,0.00912816,0.00341361,0.0117525,0.0190416,0.27675,4.08575e-06,2.93399e-07,-1.32675e-29,-5.22567e-31,-2.20941e-31,-5.67049e-33,7.70654e-31,3.54885e-31,-6.11392e-27,-8.35842e-27,1.59623e-32,5.53338e-32,1.15685e-32,1.01034e-33,2.77609e-33,-1.23724e-48,-5.30131e-47,-4.13966e-50,-1.49102e-49,-8.44378e-50,-3.80588e-51,-7.58553e-48,-3.28662e-48,-1.77414e-48,3.31667e-07,4.43969e-08,1.01299e-08,9.97064e-09,1.93007e-08,0.000739521,1.31112e-07,2.56493e-07,4.99207e-08,-3.16917e-32,6.87473e-30,1.52358e-35,9.22015e-36,7.61111e-32,1.3526e-31,1.61155e-30,1.81965e-31,0.646548,0,2.7066e-70,-1.39677e-71,-9.06186e-52,-6.17816e-50, +0.00083,2661.28,0.10968,101325,0.0326008,0.00911087,0.00340661,0.0117369,0.0190276,0.276797,4.08343e-06,2.93564e-07,1.28528e-29,5.90581e-31,5.56908e-31,3.46835e-32,-1.2858e-31,-2.24258e-31,-6.35307e-27,-8.24144e-27,6.68226e-32,2.42831e-31,2.17735e-33,-1.31823e-34,-6.8722e-34,6.06013e-49,3.20375e-47,4.38618e-50,2.14362e-49,1.0069e-49,3.736e-51,3.08988e-48,1.38278e-48,2.44025e-48,3.3391e-07,4.48109e-08,1.02543e-08,1.01053e-08,1.92678e-08,0.000755233,1.33986e-07,2.56952e-07,5.09271e-08,2.45597e-31,4.92327e-30,1.85994e-35,-1.20059e-35,1.06223e-32,-3.45474e-32,1.48908e-30,3.37144e-31,0.64656,0,-1.82022e-69,-4.12279e-71,1.66971e-52,3.91811e-50, +0.00084,2661.6,0.10967,101325,0.0325821,0.00909516,0.00340017,0.0117222,0.0190145,0.276839,4.08118e-06,2.93707e-07,-2.79589e-29,-9.52573e-31,-3.58733e-31,-1.29346e-32,8.24303e-31,3.68964e-31,-7.01044e-27,-8.52454e-27,-1.78696e-31,2.07499e-31,3.84696e-33,6.49499e-34,3.57191e-33,-1.34004e-48,-6.02463e-47,-5.19213e-50,-2.00461e-49,-1.30905e-49,-5.86566e-51,-7.47153e-48,-2.55962e-48,-1.70041e-48,3.36133e-07,4.52198e-08,1.03765e-08,1.02371e-08,1.92378e-08,0.00077092,1.36848e-07,2.57369e-07,5.193e-08,1.90386e-31,6.83753e-30,2.33711e-35,-2.51495e-35,5.55275e-32,1.08323e-31,1.39424e-30,3.01356e-31,0.646571,0,7.72006e-71,-3.6884e-71,-8.29393e-52,-6.31694e-50, +0.00085,2661.88,0.109662,101325,0.0325653,0.00908088,0.00339423,0.0117084,0.0190024,0.276877,4.07899e-06,2.9383e-07,-4.15425e-30,-4.50166e-31,-1.13627e-30,-8.62156e-32,-1.86994e-30,-3.77892e-31,-7.48969e-27,-8.81836e-27,5.56184e-32,-9.47601e-31,-3.37593e-32,-1.6395e-33,-5.59876e-33,8.49843e-49,3.27021e-47,9.60142e-51,-2.85479e-50,4.82838e-50,3.65237e-51,4.57322e-48,1.14269e-48,-1.23244e-48,3.38338e-07,4.56241e-08,1.04967e-08,1.03663e-08,1.92105e-08,0.000786583,1.39699e-07,2.57748e-07,5.29294e-08,-7.0501e-31,-1.38219e-29,-5.41195e-35,2.17289e-35,-3.67713e-32,-9.04953e-32,-2.74815e-30,-8.81861e-31,0.64658,0,2.46303e-69,1.11435e-70,1.00393e-51,4.15656e-50, +0.00086,2662.13,0.109654,101325,0.0325504,0.00906789,0.00338875,0.0116955,0.018991,0.276912,4.07686e-06,2.93934e-07,5.48757e-29,2.37444e-30,2.5268e-30,1.6777e-31,1.92446e-30,9.84354e-32,-6.06693e-27,-8.75435e-27,7.4146e-31,3.36522e-30,6.26449e-32,2.28109e-33,4.55182e-33,4.0474e-49,2.8274e-47,5.6441e-50,3.28749e-49,1.11813e-49,2.63389e-51,2.29647e-48,1.55571e-48,4.22317e-48,3.40527e-07,4.60241e-08,1.0615e-08,1.04931e-08,1.91856e-08,0.000802221,1.42539e-07,2.58093e-07,5.39256e-08,9.89244e-31,1.15214e-29,5.61846e-35,9.34729e-35,-1.44249e-32,-4.42846e-32,1.38597e-30,1.0175e-30,0.646587,0,-3.97157e-69,-1.21373e-70,-5.05713e-52,1.97586e-50, +0.00087,2662.36,0.109647,101325,0.0325372,0.00905607,0.00338368,0.0116833,0.0189804,0.276943,4.07478e-06,2.94021e-07,-4.22963e-30,-2.79902e-31,5.53157e-32,1.40859e-32,1.79185e-30,7.69929e-31,-4.70771e-27,-8.01927e-27,1.21083e-31,6.0039e-31,2.83045e-32,1.79973e-33,6.76169e-33,-1.70258e-48,-8.24995e-47,-8.60172e-50,-3.96756e-49,-2.05156e-49,-8.1493e-51,-9.8006e-48,-3.87364e-48,-4.17528e-48,3.427e-07,4.64201e-08,1.07316e-08,1.06176e-08,1.9163e-08,0.000817833,1.45368e-07,2.58406e-07,5.49186e-08,-2.48534e-31,1.28931e-29,2.18766e-36,-6.52214e-35,1.06719e-31,3.1556e-31,5.38263e-30,3.74929e-31,0.646593,0,2.17135e-69,2.29082e-71,-6.96205e-52,-8.60912e-50, +0.00088,2662.56,0.109641,101325,0.0325254,0.00904531,0.00337898,0.0116718,0.0189705,0.276972,4.07275e-06,2.94092e-07,-1.7103e-29,-8.41734e-31,-1.40734e-30,-1.05038e-31,-2.31343e-30,-5.17842e-31,-5.45486e-27,-7.35655e-27,-2.63536e-31,-2.24298e-30,-4.95584e-32,-2.08039e-33,-5.98519e-33,9.76212e-49,3.8447e-47,8.6972e-51,-3.03665e-50,4.12907e-50,3.19967e-51,6.01295e-48,1.88918e-48,-8.59898e-49,3.44859e-07,4.68125e-08,1.08466e-08,1.074e-08,1.91423e-08,0.000833421,1.48187e-07,2.58691e-07,5.59084e-08,-6.84783e-31,-2.24754e-29,-4.65215e-35,-5.76199e-35,-5.69305e-32,-2.08428e-31,-5.19596e-30,-1.25444e-30,0.646598,0,2.33798e-69,1.05856e-70,1.09259e-51,5.76966e-50, +0.00089,2662.74,0.109635,101325,0.0325151,0.00903552,0.00337462,0.0116609,0.0189611,0.276997,4.07076e-06,2.9415e-07,3.19981e-30,1.5284e-31,2.52715e-31,1.96659e-32,5.69511e-31,1.5201e-31,-5.72852e-27,-7.22693e-27,9.01614e-32,5.7173e-31,1.49481e-32,4.79802e-34,1.63245e-33,-2.08338e-49,-1.00773e-47,-3.35682e-51,-2.15726e-50,-2.108e-50,-9.72197e-52,-1.19041e-48,-2.81955e-49,-2.47859e-49,3.47003e-07,4.72013e-08,1.09602e-08,1.08605e-08,1.91234e-08,0.000848982,1.50997e-07,2.5895e-07,5.68953e-08,-7.55933e-32,-6.33373e-30,-1.83935e-35,2.36557e-35,-1.24865e-32,-7.05926e-32,-3.12188e-30,-3.68967e-31,0.646601,0,-9.10722e-71,-1.08457e-71,-6.39156e-53,-1.40509e-50, +0.0009,2662.9,0.10963,101325,0.032506,0.00902659,0.00337056,0.0116505,0.0189523,0.27702,4.06882e-06,2.94195e-07,6.80126e-30,-1.49196e-31,-1.31595e-30,-1.06553e-31,-2.4896e-30,-5.27682e-31,-5.05041e-27,-7.17555e-27,2.21535e-33,-2.13246e-30,-5.57064e-32,-2.49891e-33,-6.7952e-33,1.9156e-48,7.43582e-47,3.21159e-50,3.95226e-51,7.19901e-50,5.07358e-51,1.15024e-47,3.87356e-48,-1.10122e-48,3.49135e-07,4.75869e-08,1.10723e-08,1.09792e-08,1.91061e-08,0.000864519,1.53796e-07,2.59185e-07,5.78792e-08,-1.27127e-30,-2.41222e-29,-9.14274e-35,-6.38455e-37,-1.26983e-31,-1.25614e-31,-4.64191e-30,-1.57389e-30,0.646604,0,3.6333e-69,1.73349e-70,1.80517e-51,8.69828e-50, +0.00091,2663.05,0.109626,101325,0.032498,0.00901845,0.00336679,0.0116407,0.018944,0.277041,4.06691e-06,2.94229e-07,2.62282e-29,1.21053e-30,1.4653e-30,9.72727e-32,7.61717e-31,-1.48602e-31,-4.07723e-27,-6.65647e-27,4.439e-31,2.29846e-30,3.21188e-32,1.17283e-33,1.62915e-33,3.50948e-49,2.28417e-47,3.31713e-50,2.21409e-49,7.43533e-50,2.31898e-51,2.75985e-48,1.67546e-48,3.87453e-48,3.51255e-07,4.79696e-08,1.11831e-08,1.10963e-08,1.90904e-08,0.000880029,1.56586e-07,2.594e-07,5.88603e-08,7.35675e-31,-6.64385e-30,3.94252e-35,1.07736e-34,-9.65981e-32,-3.06105e-31,-4.56271e-30,1.44321e-31,0.646605,0,-3.03371e-69,-1.10601e-70,-2.14829e-52,2.7108e-50, +0.00092,2663.17,0.109622,101325,0.032491,0.00901103,0.00336327,0.0116314,0.0189362,0.27706,4.06504e-06,2.94252e-07,-3.67678e-29,-1.3173e-30,-4.28964e-31,-9.30415e-33,1.77235e-30,7.74485e-31,-4.84962e-27,-6.13831e-27,-3.5167e-31,2.37379e-31,1.75467e-32,1.50146e-33,6.09524e-33,-2.34294e-48,-1.06513e-46,-7.56811e-50,-2.95811e-49,-1.79358e-49,-8.88671e-51,-1.48041e-47,-5.65132e-48,-3.70555e-48,3.53364e-07,4.83494e-08,1.12928e-08,1.12118e-08,1.90759e-08,0.000895513,1.59367e-07,2.59595e-07,5.98387e-08,-1.28172e-32,1.68186e-29,-6.7033e-36,-5.33745e-35,1.72498e-31,3.02278e-31,4.48725e-30,4.79649e-31,0.646606,0,-4.59737e-71,-5.15173e-71,-1.47354e-51,-1.26936e-49, +0.00093,2663.29,0.109619,101325,0.032485,0.00900425,0.00335997,0.0116224,0.0189287,0.277077,4.06319e-06,2.94265e-07,-2.83039e-29,-1.46494e-30,-2.60612e-30,-1.91016e-31,-3.67804e-30,-6.65815e-31,-6.33199e-27,-6.39885e-27,-3.88153e-31,-3.83736e-30,-8.19325e-32,-3.45764e-33,-9.80105e-33,1.59907e-48,6.17674e-47,9.89699e-51,-9.58203e-50,4.18839e-50,4.77781e-51,9.58996e-48,2.68451e-48,-2.74554e-48,3.55461e-07,4.87266e-08,1.14014e-08,1.13259e-08,1.90627e-08,0.000910972,1.62139e-07,2.59773e-07,6.08145e-08,-1.43131e-30,-2.24735e-29,-6.37858e-35,-5.66017e-35,-2.98903e-32,1.80429e-32,-2.34771e-30,-1.6108e-30,0.646606,0,4.64307e-69,2.09086e-70,1.69104e-51,6.85779e-50, +0.00094,2663.39,0.109616,101325,0.0324798,0.00899806,0.00335688,0.0116139,0.0189217,0.277093,4.06138e-06,2.94271e-07,1.95058e-29,8.21843e-31,1.38577e-30,9.90017e-32,2.0297e-30,4.31232e-31,-6.23099e-27,-7.06819e-27,1.52916e-31,1.87156e-30,4.67134e-32,1.88708e-33,5.27435e-33,-1.15812e-48,-4.92436e-47,-3.1604e-50,-5.71154e-50,-7.00889e-50,-4.32064e-51,-6.50429e-48,-2.01702e-48,5.12903e-49,3.57548e-07,4.91013e-08,1.15089e-08,1.14386e-08,1.90506e-08,0.000926404,1.64902e-07,2.59936e-07,6.17876e-08,4.18769e-31,-2.30301e-30,7.83101e-36,5.81172e-35,4.70756e-32,-1.43301e-31,-1.80969e-30,9.62761e-32,0.646605,0,-1.97603e-69,-1.05323e-70,-1.11229e-51,-5.52022e-50, +0.00095,2663.48,0.109613,101325,0.0324753,0.00899241,0.00335399,0.0116057,0.018915,0.277106,4.05959e-06,2.94268e-07,-5.01311e-30,-2.44442e-31,-9.97358e-32,6.76315e-33,1.73233e-30,8.45448e-31,-5.1493e-27,-7.28418e-27,5.67615e-32,2.57031e-31,3.0005e-32,1.61869e-33,4.4824e-33,-2.135e-48,-9.38066e-47,-6.74848e-50,-3.07342e-49,-1.23995e-49,-4.76815e-51,-1.379e-47,-6.41971e-48,-5.34342e-48,3.59625e-07,4.94736e-08,1.16155e-08,1.15502e-08,1.90395e-08,0.000941809,1.67657e-07,2.60084e-07,6.27582e-08,4.1463e-32,3.12743e-29,6.94906e-35,3.97542e-35,2.8098e-31,5.09977e-31,1.01794e-29,1.24832e-30,0.646604,0,1.89022e-69,4.35146e-71,-8.93918e-52,-9.48741e-50, +0.00096,2663.55,0.109611,101325,0.0324716,0.00898723,0.00335126,0.0115978,0.0189086,0.277119,4.05783e-06,2.94258e-07,6.57676e-29,2.28372e-30,1.26706e-30,5.62532e-32,-1.44398e-30,-8.29171e-31,-3.37364e-27,-6.58511e-27,5.24499e-31,1.12831e-30,-1.68888e-32,-1.38851e-33,-4.72372e-33,2.87346e-48,1.23821e-46,8.82924e-50,3.7025e-49,1.8306e-49,7.484e-51,1.7327e-47,7.28635e-48,4.89274e-48,3.61693e-07,4.98438e-08,1.17212e-08,1.16606e-08,1.90293e-08,0.000957188,1.70403e-07,2.60219e-07,6.37263e-08,1.23787e-32,-1.09758e-29,-6.99265e-35,9.58147e-35,-1.35346e-31,-9.26331e-32,1.74121e-31,-1.67726e-31,0.646602,0,-1.07713e-69,1.24709e-71,1.42068e-51,1.21231e-49, +0.00097,2663.62,0.109609,101325,0.0324685,0.00898248,0.00334868,0.0115902,0.0189024,0.27713,4.05609e-06,2.94243e-07,-2.26973e-29,1.75541e-33,1.39851e-30,1.31212e-31,3.34416e-30,6.8153e-31,-2.12968e-27,-5.19431e-27,4.69417e-31,3.18527e-30,1.07928e-31,4.56454e-33,9.6496e-33,-1.59909e-48,-4.48009e-47,3.157e-51,5.6222e-50,-1.00645e-50,7.00316e-52,-7.1737e-48,-2.39987e-48,2.55511e-48,3.63751e-07,5.02119e-08,1.1826e-08,1.17699e-08,1.90199e-08,0.000972541,1.73141e-07,2.60343e-07,6.4692e-08,2.39079e-30,3.64331e-29,3.08771e-34,1.40649e-34,-8.55337e-32,-4.54662e-32,9.79527e-31,2.59899e-30,0.6466,0,-1.92381e-69,-1.13703e-70,-6.97199e-52,-1.36068e-50, +0.00098,2663.68,0.109607,101325,0.0324659,0.00897814,0.00334625,0.0115828,0.0188966,0.27714,4.05437e-06,2.94221e-07,-1.5719e-29,-5.67545e-31,-8.60044e-31,-6.04705e-32,-1.39156e-30,-2.92963e-31,-2.91886e-27,-4.27605e-27,-2.001e-31,-1.50023e-30,-3.87746e-32,-1.43807e-33,-4.97792e-33,3.55259e-49,1.66748e-47,1.52494e-50,2.83096e-50,4.5697e-50,3.31364e-51,1.71164e-48,2.02437e-49,-1.15911e-48,3.65801e-07,5.0578e-08,1.19301e-08,1.18783e-08,1.90113e-08,0.000987866,1.75871e-07,2.60457e-07,6.56554e-08,3.63063e-31,2.42664e-29,5.83091e-35,-7.49397e-35,-1.12614e-32,4.03635e-31,6.51386e-30,1.08753e-30,0.646597,0,9.26482e-70,5.12988e-71,8.27649e-52,3.30543e-50, +0.00099,2663.73,0.109606,101325,0.0324639,0.00897415,0.00334394,0.0115757,0.0188909,0.277149,4.05267e-06,2.94194e-07,-4.95798e-29,-1.14524e-30,-3.68666e-31,-9.95081e-33,-9.57159e-31,-6.21641e-31,-4.88599e-27,-4.52051e-27,-1.42765e-31,-1.71561e-31,-6.33856e-33,4.251e-34,-3.39135e-33,6.77795e-49,4.95805e-47,6.3023e-50,2.76868e-49,1.21226e-49,7.08574e-51,6.35142e-48,3.16935e-48,4.25986e-48,3.67842e-07,5.09423e-08,1.20335e-08,1.19858e-08,1.90033e-08,0.00100317,1.78593e-07,2.60561e-07,6.66164e-08,1.74386e-30,1.61961e-29,1.84013e-34,-1.79802e-35,-6.80105e-32,7.36244e-33,3.41273e-30,1.67134e-30,0.646594,0,-1.68039e-69,-5.94746e-71,8.43383e-52,8.47194e-50, +0.001,2663.78,0.109605,101325,0.0324623,0.00897049,0.00334175,0.0115688,0.0188855,0.277157,4.05098e-06,2.94163e-07,6.17408e-29,1.22826e-30,4.61979e-31,1.28814e-32,1.37108e-30,7.14696e-31,-4.53302e-27,-5.25624e-27,1.67944e-31,7.86693e-31,1.76819e-33,-1.6948e-34,5.21861e-33,-5.48513e-49,-5.0882e-47,-7.20192e-50,-2.66192e-49,-1.58106e-49,-1.07005e-50,-6.52041e-48,-2.99886e-48,-2.34087e-48,3.69875e-07,5.13048e-08,1.21361e-08,1.20924e-08,1.8996e-08,0.00101844,1.81307e-07,2.60657e-07,6.75752e-08,-2.46518e-30,-1.2474e-29,-2.44284e-34,-3.72353e-35,5.59446e-32,-4.93761e-32,-8.29482e-31,-1.79833e-30,0.64659,0,4.11638e-70,3.22152e-72,-1.63531e-51,-1.10973e-49, diff --git a/test_problems/cxx_ex/kin2_blessed.csv b/test_problems/cxx_ex/kin2_blessed.csv new file mode 100644 index 000000000..292f99f6a --- /dev/null +++ b/test_problems/cxx_ex/kin2_blessed.csv @@ -0,0 +1,103 @@ +kinetics example 1: constant-pressure ignition, +time (s),Temperature (K),Density (kg/m3),Pressure (Pa),H2,H,O,O2,OH,H2O,HO2,H2O2,C,CH,CH2,CH2(S),CH3,CH4,CO,CO2,HCO,CH2O,CH2OH,CH3O,CH3OH,C2H,C2H2,C2H3,C2H4,C2H5,C2H6,HCCO,CH2CO,HCCOH,N,NH,NH2,NH3,NNH,NO,NO2,N2O,HNO,CN,HCN,H2CN,HCNN,HCNO,HOCN,HNCO,NCO,N2,AR,C3H7,C3H8,CH2CHO,CH3CHO, +0,1001,0.257563,101325,0.285714,0,0,0.142857,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +1e-05,1001,0.257563,101325,0.285714,3.17572e-10,3.12552e-11,0.142857,1.06677e-11,2.13646e-10,4.83425e-10,4.75605e-13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9.85506e-25,6.33287e-24,2.67638e-25,1.11544e-25,1.0534e-16,1.43565e-23,4.23203e-31,1.36696e-17,3.18286e-25,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +2e-05,1001,0.257563,101325,0.285714,7.97697e-10,8.41371e-11,0.142857,2.79961e-11,1.06404e-09,1.41952e-09,2.51119e-12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.95227e-24,6.61754e-23,4.15905e-24,3.51136e-24,2.64629e-16,1.49743e-22,2.28029e-29,7.1153e-17,4.94375e-24,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +3e-05,1001,0.257563,101325,0.285714,1.53836e-09,1.657e-10,0.142857,5.47255e-11,2.90027e-09,3.05213e-09,7.37692e-12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5.98725e-24,3.00802e-22,2.19824e-23,2.69521e-23,5.10354e-16,7.23862e-22,3.16763e-28,1.97004e-16,2.61231e-23,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +4e-05,1001,0.257563,101325,0.285714,2.68144e-09,2.91571e-10,0.142857,9.5978e-11,6.25765e-09,5.75898e-09,1.70309e-11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.06713e-23,1.01145e-21,7.94868e-23,1.22536e-22,8.89589e-16,2.58398e-21,2.5501e-27,4.28612e-16,9.44455e-23,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +5e-05,1001,0.257563,101325,0.285714,4.44607e-09,4.85879e-10,0.142857,1.59665e-10,1.19631e-08,1.01235e-08,3.44956e-11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.79049e-23,2.94321e-21,2.4057e-22,4.30371e-22,1.47503e-15,7.885e-21,1.54078e-26,8.23725e-16,2.85817e-22,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +6e-05,1001,0.257563,101325,0.285714,7.17071e-09,7.85891e-10,0.142857,2.58008e-10,2.12941e-08,1.70466e-08,6.44402e-11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.90859e-23,7.91725e-21,6.61994e-22,1.30754e-21,2.37897e-15,2.19705e-20,7.84514e-26,1.47154e-15,7.86461e-22,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +7e-05,1001,0.257563,101325,0.285714,1.13783e-08,1.24918e-09,0.142857,4.09901e-10,3.62241e-08,2.79195e-08,1.14084e-10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4.64006e-23,2.03465e-20,1.72461e-21,3.64015e-21,3.77492e-15,5.78973e-20,3.58305e-25,2.50982e-15,2.04878e-21,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +8e-05,1001,0.257563,101325,0.285714,1.7877e-08,1.96473e-09,0.142857,6.44557e-10,5.98029e-08,4.48905e-08,1.946e-10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7.33282e-23,5.08666e-20,4.34783e-21,9.59446e-21,5.93095e-15,1.47292e-19,1.52408e-24,4.15138e-15,5.1649e-21,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +9e-05,1001,0.257563,101325,0.285714,2.79156e-08,3.07003e-09,0.142857,1.00717e-09,9.67452e-08,7.12769e-08,3.23313e-10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.15623e-22,1.25026e-19,1.07427e-20,2.44208e-20,9.26142e-15,3.6637e-19,6.18491e-24,6.72502e-15,1.2761e-20,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +0.0001,1001,0.257563,101325,0.285714,4.34256e-08,4.77772e-09,0.142857,1.56776e-09,1.54343e-07,1.122e-07,5.27139e-10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.83583e-22,3.04063e-19,2.62123e-20,6.07745e-20,1.44071e-14,8.98188e-19,2.43178e-23,1.07388e-14,3.11356e-20,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +0.00011,1001,0.257563,101325,0.285714,6.73962e-08,7.41685e-09,0.142857,2.43494e-09,2.43884e-07,1.75566e-07,8.4804e-10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.98341e-22,7.34625e-19,6.34589e-20,1.49052e-19,2.23598e-14,2.18156e-18,9.35903e-23,1.69782e-14,7.53727e-20,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +0.00012,1001,0.257563,101325,0.285714,1.04459e-07,1.14972e-08,0.142857,3.77765e-09,3.82863e-07,2.73575e-07,1.35177e-09,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5.11884e-22,1.76782e-18,1.52895e-19,3.6214e-19,3.4656e-14,5.26769e-18,3.55084e-22,2.66581e-14,1.81581e-19,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +0.00013,1001,0.257563,101325,0.285714,1.61801e-07,1.78097e-08,0.142856,5.85959e-09,5.98449e-07,4.2505e-07,2.14213e-09,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9.76194e-22,4.24473e-18,3.67357e-19,8.7466e-19,5.36805e-14,1.26748e-17,1.33439e-21,4.16587e-14,4.36212e-19,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +0.00014,1001.01,0.257562,101325,0.285713,2.50609e-07,2.7585e-08,0.142856,9.09485e-09,9.32958e-07,6.59011e-07,3.38484e-09,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.19224e-21,1.0183e-17,8.81466e-19,2.10502e-18,8.31448e-14,3.04408e-17,4.98318e-21,6.48948e-14,1.04643e-18,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +0.00015,1001.01,0.257562,101325,0.285712,3.88365e-07,4.27454e-08,0.142856,1.41391e-08,1.4526e-06,1.02016e-06,5.34866e-09,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5.92605e-21,2.44347e-17,2.11472e-18,5.05668e-18,1.28849e-13,7.30709e-17,1.85338e-20,1.00892e-13,2.50956e-18,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +0.00016,1001.01,0.257561,101325,0.285711,6.02555e-07,6.63111e-08,0.142855,2.20443e-08,2.26171e-06,1.57726e-06,8.47916e-09,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.86261e-20,5.87158e-17,5.07848e-18,1.21414e-17,1.99914e-13,1.75529e-16,6.87706e-20,1.567e-13,6.02323e-18,0,0,0,0,0,0,0,0,0.571429,0,0,0,0,0, +0.00017,1001.02,0.257559,101325,0.28571,9.36813e-07,1.03072e-07,0.142853,3.45292e-08,3.52635e-06,2.43583e-06,1.35368e-08,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6.43339e-20,1.41497e-16,1.22242e-17,2.91759e-17,3.1082e-13,4.2254e-16,2.54897e-19,2.4335e-13,1.44854e-17,0,0,0,0,0,0,0,0,0.57143,0,0,0,0,0, +0.00018,1001.03,0.257557,101325,0.285707,1.46138e-06,1.60725e-07,0.142851,5.4478e-08,5.51502e-06,3.75715e-06,2.18666e-08,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.34236e-19,3.42643e-16,2.95447e-17,7.02687e-17,4.84879e-13,1.02113e-15,9.44742e-19,3.78222e-13,3.49613e-17,0,0,0,0,0,0,0,0,0.571431,0,0,0,0,0, +0.00019,1001.05,0.257553,101325,0.285703,2.29167e-06,2.51893e-07,0.142848,8.69081e-08,8.67153e-06,5.78622e-06,3.59458e-08,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8.81176e-19,8.36162e-16,7.18796e-17,1.6994e-16,7.60404e-13,2.4837e-15,3.50519e-18,5.88991e-13,8.48733e-17,0,0,0,0,0,0,0,0,0.571432,0,0,0,0,0, +0.0002,1001.08,0.257546,101325,0.285697,3.62293e-06,3.97859e-07,0.142842,1.40968e-07,1.3753e-05,8.89086e-06,6.05276e-08,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.40871e-18,2.06521e-15,1.76696e-16,4.13796e-16,1.20223e-12,6.10344e-15,1.30338e-17,9.20428e-13,2.07925e-16,0,0,0,0,0,0,0,0,0.571434,0,0,0,0,0, +0.00021,1001.12,0.257536,101325,0.285686,5.79903e-06,6.35954e-07,0.142834,2.34333e-07,2.21071e-05,1.36117e-05,1.05061e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.3629e-17,5.19603e-15,4.41351e-16,1.01848e-15,1.92462e-12,1.52419e-14,4.86366e-17,1.44666e-12,5.16534e-16,0,0,0,0,0,0,0,0,0.571437,0,0,0,0,0, +0.00022,1001.2,0.257518,101325,0.285669,9.45822e-06,1.03512e-06,0.142821,4.035e-07,3.62683e-05,2.07102e-05,1.88753e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5.70636e-17,1.34458e-14,1.12959e-15,2.54916e-15,3.13979e-12,3.90304e-14,1.8237e-16,2.29456e-12,1.31041e-15,0,0,0,0,0,0,0,0,0.571442,0,0,0,0,0, +0.00023,1001.34,0.257486,101325,0.28564,1.58644e-05,1.73108e-06,0.142799,7.29335e-07,6.13278e-05,3.11574e-05,3.5061e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.55567e-16,3.62888e-14,2.99887e-15,6.54688e-15,5.26863e-12,1.03919e-13,6.87444e-16,3.69166e-12,3.42869e-15,0,0,0,0,0,0,0,0,0.57145,0,0,0,0,0, +0.00024,1001.6,0.257424,101325,0.285586,2.77111e-05,3.01146e-06,0.142763,1.40317e-06,0.000108284,4.58808e-05,6.66431e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.26178e-15,1.04118e-13,8.40047e-15,1.74849e-14,9.21029e-12,2.93847e-13,2.59717e-15,6.07169e-12,9.37023e-15,0,0,0,0,0,0,0,0,0.571464,0,0,0,0,0, +0.00025,1002.14,0.257297,101325,0.285481,5.11684e-05,5.53281e-06,0.142701,2.89727e-06,0.000202552,6.47827e-05,1.26447e-06,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7.12427e-15,3.2484e-13,2.53535e-14,4.94723e-14,1.70343e-11,9.10057e-13,9.70107e-15,1.03262e-11,2.7086e-14,0,0,0,0,0,0,0,0,0.571489,0,0,0,0,0, +0.00026,1003.3,0.257021,101325,0.285265,0.000101131,1.08827e-05,0.142586,6.35942e-06,0.000405226,8.44574e-05,2.28749e-06,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4.74057e-14,1.12058e-12,8.38762e-14,1.51566e-13,3.37849e-11,3.21046e-12,3.44473e-14,1.84451e-11,8.29789e-14,0,0,0,0,0,0,0,0,0.571538,0,0,0,0,0, +0.00027,1005.92,0.256397,101325,0.284791,0.000214002,2.29856e-05,0.142359,1.43501e-05,0.000860856,9.72169e-05,3.69407e-06,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.68193e-13,4.21716e-12,3.01405e-13,5.09275e-13,7.20534e-11,1.33475e-11,1.08158e-13,3.52167e-11,2.60937e-13,0,0,0,0,0,0,0,0,0.571637,0,0,0,0,0, +0.00028,1011.82,0.254997,101325,0.283711,0.000480639,5.18269e-05,0.141864,3.28186e-05,0.00190296,0.000100061,5.02916e-06,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.10678e-12,1.6296e-11,1.10254e-12,1.83299e-12,1.64685e-10,6.5842e-11,2.93484e-13,7.301e-11,7.82338e-13,0,0,0,0,0,0,0,0,0.571852,0,0,0,0,0, +0.00029,1025.54,0.251803,101325,0.281087,0.00117279,0.000128009,0.140676,8.05722e-05,0.00440474,9.87955e-05,5.51906e-06,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.71124e-11,6.1975e-11,3.73816e-12,6.59266e-12,4.18109e-10,3.88044e-10,7.7185e-13,1.68824e-10,2.208e-12,0,0,0,0,0,0,0,0,0.572347,0,0,0,0,0, +0.0003,1061.19,0.243889,101325,0.273446,0.0034748,0.000391595,0.137262,0.000243648,0.0114567,9.46444e-05,4.07821e-06,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.84747e-10,2.63027e-10,1.17173e-11,2.25037e-11,1.36514e-09,3.11998e-09,2.23029e-12,4.83218e-10,7.40308e-12,0,0,0,0,0,0,0,0,0.573627,0,0,0,0,0, +0.00031,1190.6,0.219114,101325,0.234708,0.0184409,0.00232202,0.120367,0.00149549,0.0443813,8.17356e-05,2.03613e-06,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7.18166e-09,2.27554e-09,4.90213e-11,7.78763e-11,9.69202e-09,6.72944e-08,1.20253e-11,2.81388e-09,6.41095e-11,0,0,0,0,0,0,0,0,0.578201,0,0,0,0,0, +0.00032,1696.99,0.158947,101325,0.0543234,0.0829776,0.0198496,0.0340137,0.0157854,0.195196,2.17873e-05,1.89831e-06,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.55442e-07,3.19519e-08,2.22172e-10,5.39503e-11,8.64966e-08,7.96932e-06,7.30725e-10,5.41603e-08,2.20265e-09,0,0,0,0,0,0,0,0,0.597823,0,0,0,0,0, +0.00033,1941.59,0.14168,101325,0.0544569,0.0595515,0.0168553,0.0285173,0.0205968,0.210306,1.37262e-05,7.59436e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9.13846e-08,2.95289e-08,5.00238e-10,1.54734e-10,7.90968e-08,2.30306e-05,1.89833e-09,6.34811e-08,3.85319e-09,0,0,0,0,0,0,0,0,0.609678,0,0,0,0,0, +0.00034,2075.94,0.133967,101325,0.0534026,0.047782,0.0145114,0.025744,0.0224869,0.219653,1.05333e-05,4.94598e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7.44822e-08,2.5836e-08,6.95749e-10,2.5061e-10,7.07796e-08,3.44388e-05,2.76613e-09,6.72905e-08,4.53795e-09,0,0,0,0,0,0,0,0,0.616374,0,0,0,0,0, +0.00035,2167.57,0.12927,101325,0.0519748,0.040321,0.0127767,0.0238119,0.0233541,0.226699,8.70856e-06,3.86577e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7.34397e-08,2.29362e-08,8.41599e-10,3.3888e-10,6.38522e-08,4.43207e-05,3.60458e-09,7.10681e-08,4.96671e-09,0,0,0,0,0,0,0,0,0.621009,0,0,0,0,0, +0.00036,2236.22,0.126009,101325,0.0505081,0.0350429,0.0114338,0.022331,0.0237364,0.23237,7.52808e-06,3.3031e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7.94988e-08,2.0835e-08,9.63468e-10,4.24302e-10,5.81377e-08,5.37632e-05,4.51647e-09,7.53283e-08,5.33541e-09,0,0,0,0,0,0,0,0,0.624516,0,0,0,0,0, +0.00037,2290.5,0.123574,101325,0.0490968,0.0310665,0.0103589,0.0211346,0.0238565,0.237108,6.71365e-06,2.97047e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8.90706e-08,1.93943e-08,1.078e-09,5.11938e-10,5.3371e-08,6.33273e-05,5.55245e-09,8.02097e-08,5.71898e-09,0,0,0,0,0,0,0,0,0.627308,0,0,0,0,0, +0.00038,2334.93,0.121668,101325,0.0477695,0.0279452,0.009477,0.0201351,0.0238244,0.241163,6.12931e-06,2.76014e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.00362e-07,1.84837e-08,1.196e-09,6.06348e-10,4.93433e-08,7.32991e-05,6.74073e-09,8.5716e-08,6.14955e-09,0,0,0,0,0,0,0,0,0.629605,0,0,0,0,0, +0.00039,2372.18,0.120126,101325,0.046533,0.0254236,0.00873995,0.0192809,0.0237005,0.244693,5.69888e-06,2.62308e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.12383e-07,1.79966e-08,1.32443e-09,7.1137e-10,4.59011e-08,8.38134e-05,8.09727e-09,9.17918e-08,6.64089e-09,0,0,0,0,0,0,0,0,0.631539,0,0,0,0,0, +0.0004,2403.96,0.11885,101325,0.0453857,0.0233427,0.00811507,0.0185391,0.023521,0.247801,5.3758e-06,2.53369e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.24556e-07,1.78475e-08,1.46755e-09,8.3006e-10,4.2931e-08,9.49193e-05,9.62999e-09,9.83545e-08,7.19797e-09,0,0,0,0,0,0,0,0,0.633195,0,0,0,0,0, +0.00041,2431.44,0.117774,101325,0.0443233,0.0215975,0.00757928,0.017887,0.0233082,0.250563,5.12978e-06,2.47716e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.36538e-07,1.79676e-08,1.6277e-09,9.6468e-10,4.0348e-08,0.000106617,1.13408e-08,1.0531e-07,7.82112e-09,0,0,0,0,0,0,0,0,0.63463,0,0,0,0,0, +0.00042,2455.44,0.116855,101325,0.0433404,0.0201151,0.00711576,0.0173085,0.023077,0.253033,4.94026e-06,2.44413e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.48123e-07,1.83008e-08,1.8058e-09,1.11673e-09,3.8087e-08,0.000118878,1.32269e-08,1.1256e-07,8.50811e-09,0,0,0,0,0,0,0,0,0.635885,0,0,0,0,0, +0.00043,2476.57,0.116061,101325,0.0424319,0.0188433,0.00671185,0.0167919,0.0228371,0.255254,4.79283e-06,2.42832e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.59192e-07,1.88014e-08,2.0017e-09,1.28696e-09,3.60974e-08,0.000131662,1.52817e-08,1.2001e-07,9.25522e-09,0,0,0,0,0,0,0,0,0.636992,0,0,0,0,0, +0.00044,2495.28,0.115369,101325,0.0415924,0.0177432,0.00635781,0.0163281,0.0225954,0.257259,4.67712e-06,2.42529e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.69682e-07,1.94312e-08,2.21445e-09,1.47548e-09,3.43389e-08,0.000144919,1.74958e-08,1.2757e-07,1.00579e-08,0,0,0,0,0,0,0,0,0.637974,0,0,0,0,0, +0.00045,2511.93,0.114763,101325,0.0408172,0.0167853,0.00604598,0.0159099,0.0223564,0.259073,4.58553e-06,2.43173e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.79568e-07,2.01591e-08,2.44254e-09,1.68178e-09,3.27789e-08,0.0001586,1.98577e-08,1.35155e-07,1.09109e-08,0,0,0,0,0,0,0,0,0.638848,0,0,0,0,0, +0.00046,2526.81,0.114228,101325,0.0401019,0.0159467,0.00577023,0.0155317,0.0221234,0.260719,4.51242e-06,2.44516e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.88847e-07,2.09591e-08,2.68409e-09,1.90484e-09,3.1391e-08,0.000172654,2.23543e-08,1.42692e-07,1.18092e-08,0,0,0,0,0,0,0,0,0.63963,0,0,0,0,0, +0.00047,2540.14,0.113754,101325,0.0394422,0.0152091,0.00552556,0.0151888,0.0218987,0.262213,4.45356e-06,2.46364e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1.97533e-07,2.18097e-08,2.93696e-09,2.14323e-09,3.0153e-08,0.000187036,2.4972e-08,1.50115e-07,1.27474e-08,0,0,0,0,0,0,0,0,0.64033,0,0,0,0,0, +0.00048,2552.11,0.113333,101325,0.0388343,0.0145579,0.00530788,0.0148774,0.0216836,0.263573,4.40573e-06,2.48564e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.05651e-07,2.26934e-08,3.19892e-09,2.39519e-09,2.90464e-08,0.000201701,2.76965e-08,1.57368e-07,1.37203e-08,0,0,0,0,0,0,0,0,0.640959,0,0,0,0,0, +0.00049,2562.89,0.112957,101325,0.0382746,0.0139811,0.00511374,0.0145941,0.0214792,0.26481,4.3665e-06,2.50998e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.13232e-07,2.3596e-08,3.46773e-09,2.65875e-09,2.80555e-08,0.00021661,3.0514e-08,1.64403e-07,1.47231e-08,0,0,0,0,0,0,0,0,0.641526,0,0,0,0,0, +0.0005,2572.61,0.112621,101325,0.0377598,0.0134689,0.00494025,0.0143362,0.0212859,0.265936,4.33398e-06,2.5357e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.20309e-07,2.45059e-08,3.74119e-09,2.93181e-09,2.7167e-08,0.000231728,3.34112e-08,1.71184e-07,1.5751e-08,0,0,0,0,0,0,0,0,0.642036,0,0,0,0,0, +0.00051,2581.38,0.11232,101325,0.0372866,0.0130129,0.00478494,0.0141011,0.021104,0.266962,4.30676e-06,2.56206e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.2692e-07,2.54141e-08,4.01727e-09,3.21221e-09,2.63692e-08,0.000247024,3.63754e-08,1.77682e-07,1.67999e-08,0,0,0,0,0,0,0,0,0.642496,0,0,0,0,0, +0.00052,2589.3,0.112051,101325,0.0368522,0.012606,0.00464571,0.0138867,0.0209334,0.267897,4.28373e-06,2.58849e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.331e-07,2.63135e-08,4.29408e-09,3.49783e-09,2.5652e-08,0.000262469,3.93949e-08,1.83875e-07,1.78658e-08,0,0,0,0,0,0,0,0,0.642911,0,0,0,0,0, +0.00053,2596.46,0.111808,101325,0.0364536,0.0122425,0.00452071,0.0136911,0.020774,0.268749,4.26403e-06,2.61455e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.38886e-07,2.71985e-08,4.56995e-09,3.78663e-09,2.50069e-08,0.00027804,4.24592e-08,1.89749e-07,1.89452e-08,0,0,0,0,0,0,0,0,0.643286,0,0,0,0,0, +0.00054,2602.93,0.11159,101325,0.0360884,0.0119172,0.00440838,0.0135126,0.0206255,0.269524,4.24701e-06,2.6399e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.44312e-07,2.80652e-08,4.8434e-09,4.07672e-09,2.44259e-08,0.000293716,4.55586e-08,1.95296e-07,2.00351e-08,0,0,0,0,0,0,0,0,0.643625,0,0,0,0,0, +0.00055,2608.79,0.111394,101325,0.0357539,0.0116256,0.00430731,0.0133497,0.0204874,0.27023,4.23215e-06,2.66431e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.49411e-07,2.89107e-08,5.1132e-09,4.36635e-09,2.39025e-08,0.000309477,4.86847e-08,2.00514e-07,2.11327e-08,0,0,0,0,0,0,0,0,0.643931,0,0,0,0,0, +0.00056,2614.09,0.111217,101325,0.0354479,0.011364,0.00421629,0.0132009,0.0203594,0.270873,4.21905e-06,2.6876e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.54214e-07,2.97331e-08,5.3783e-09,4.65398e-09,2.34305e-08,0.000325309,5.18301e-08,2.05404e-07,2.22356e-08,0,0,0,0,0,0,0,0,0.644208,0,0,0,0,0, +0.00057,2618.9,0.111057,101325,0.0351682,0.0111291,0.00413426,0.013065,0.0202408,0.271459,4.20741e-06,2.70965e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.58748e-07,3.05312e-08,5.63787e-09,4.93827e-09,2.30047e-08,0.000341198,5.49884e-08,2.09973e-07,2.33417e-08,0,0,0,0,0,0,0,0,0.644458,0,0,0,0,0, +0.00058,2623.24,0.110914,101325,0.0349128,0.0109178,0.00406027,0.0129409,0.0201313,0.271991,4.19698e-06,2.73041e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.6304e-07,3.13045e-08,5.89127e-09,5.21808e-09,2.26204e-08,0.000357131,5.8154e-08,2.14229e-07,2.44494e-08,0,0,0,0,0,0,0,0,0.644683,0,0,0,0,0, +0.00059,2627.18,0.110784,101325,0.0346797,0.0107277,0.00399348,0.0128275,0.0200302,0.272476,4.18756e-06,2.74985e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.67113e-07,3.20528e-08,6.13802e-09,5.49248e-09,2.22734e-08,0.000373099,6.13225e-08,2.18182e-07,2.55572e-08,0,0,0,0,0,0,0,0,0.644887,0,0,0,0,0, +0.0006,2630.75,0.110667,101325,0.0344671,0.0105566,0.00393315,0.0127239,0.0199369,0.272917,4.17901e-06,2.76797e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.70991e-07,3.27766e-08,6.37781e-09,5.76071e-09,2.19599e-08,0.000389093,6.44898e-08,2.21845e-07,2.66638e-08,0,0,0,0,0,0,0,0,0.645071,0,0,0,0,0, +0.00061,2633.97,0.110561,101325,0.0342734,0.0104024,0.00387862,0.0126292,0.0198511,0.273318,4.17119e-06,2.78478e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.74691e-07,3.34765e-08,6.61043e-09,6.0222e-09,2.16765e-08,0.000405106,6.76527e-08,2.25233e-07,2.77683e-08,0,0,0,0,0,0,0,0,0.645237,0,0,0,0,0, +0.00062,2636.9,0.110465,101325,0.0340971,0.0102633,0.0038293,0.0125427,0.0197721,0.273682,4.16401e-06,2.80032e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.78232e-07,3.41532e-08,6.83581e-09,6.27653e-09,2.14204e-08,0.000421132,7.08085e-08,2.28359e-07,2.88698e-08,0,0,0,0,0,0,0,0,0.645387,0,0,0,0,0, +0.00063,2639.55,0.110379,101325,0.0339366,0.0101379,0.00378466,0.0124635,0.0196995,0.274013,4.15739e-06,2.81465e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.81631e-07,3.48076e-08,7.05397e-09,6.52345e-09,2.11887e-08,0.000437164,7.39552e-08,2.31238e-07,2.99677e-08,0,0,0,0,0,0,0,0,0.645522,0,0,0,0,0, +0.00064,2641.94,0.110301,101325,0.0337906,0.0100247,0.00374425,0.0123911,0.0196328,0.274314,4.15126e-06,2.82781e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.84901e-07,3.54409e-08,7.26499e-09,6.76278e-09,2.09792e-08,0.000453199,7.70909e-08,2.33887e-07,3.10615e-08,0,0,0,0,0,0,0,0,0.645644,0,0,0,0,0, +0.00065,2644.11,0.11023,101325,0.033658,0.00992246,0.00370763,0.0123249,0.0195715,0.274587,4.14557e-06,2.83988e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.88055e-07,3.60542e-08,7.46904e-09,6.9945e-09,2.07896e-08,0.000469232,8.02144e-08,2.36319e-07,3.21508e-08,0,0,0,0,0,0,0,0,0.645754,0,0,0,0,0, +0.00066,2646.08,0.110167,101325,0.0335376,0.0098301,0.00367443,0.0122642,0.0195152,0.274835,4.14026e-06,2.85091e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.91105e-07,3.66485e-08,7.66632e-09,7.21866e-09,2.06179e-08,0.000485261,8.33247e-08,2.38549e-07,3.32353e-08,0,0,0,0,0,0,0,0,0.645853,0,0,0,0,0, +0.00067,2647.86,0.110109,101325,0.0334283,0.00974663,0.00364431,0.0122087,0.0194636,0.275061,4.13529e-06,2.86097e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.94062e-07,3.7225e-08,7.85707e-09,7.43536e-09,2.04625e-08,0.000501281,8.6421e-08,2.40593e-07,3.43149e-08,0,0,0,0,0,0,0,0,0.645942,0,0,0,0,0, +0.00068,2649.47,0.110057,101325,0.0333291,0.00967115,0.00361698,0.0121577,0.0194161,0.275265,4.13064e-06,2.87013e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.96935e-07,3.77849e-08,8.04156e-09,7.64479e-09,2.03218e-08,0.000517292,8.95027e-08,2.42462e-07,3.53894e-08,0,0,0,0,0,0,0,0,0.646021,0,0,0,0,0, +0.00069,2650.92,0.11001,101325,0.0332392,0.00960289,0.00359216,0.012111,0.0193726,0.275451,4.12626e-06,2.87844e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2.99731e-07,3.83292e-08,8.22009e-09,7.84718e-09,2.01943e-08,0.00053329,9.25696e-08,2.44172e-07,3.64587e-08,0,0,0,0,0,0,0,0,0.646093,0,0,0,0,0, +0.0007,2652.24,0.109968,101325,0.0331578,0.00954113,0.0035696,0.0120681,0.0193326,0.275619,4.12214e-06,2.88598e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.02459e-07,3.8859e-08,8.39294e-09,8.04279e-09,2.00788e-08,0.000549273,9.56215e-08,2.45733e-07,3.75229e-08,0,0,0,0,0,0,0,0,0.646157,0,0,0,0,0, +0.00071,2653.43,0.10993,101325,0.0330841,0.00948523,0.00354909,0.0120288,0.0192959,0.275772,4.11824e-06,2.8928e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.05125e-07,3.93752e-08,8.56043e-09,8.23189e-09,1.99741e-08,0.000565241,9.86583e-08,2.47157e-07,3.8582e-08,0,0,0,0,0,0,0,0,0.646215,0,0,0,0,0, +0.00072,2654.51,0.109895,101325,0.0330174,0.00943463,0.00353042,0.0119925,0.0192622,0.27591,4.11456e-06,2.89895e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.07735e-07,3.9879e-08,8.72285e-09,8.4148e-09,1.98791e-08,0.000581192,1.0168e-07,2.48457e-07,3.96361e-08,0,0,0,0,0,0,0,0,0.646266,0,0,0,0,0, +0.00073,2655.49,0.109864,101325,0.0329571,0.0093888,0.00351342,0.0119592,0.0192312,0.276036,4.11106e-06,2.90448e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.10294e-07,4.0371e-08,8.88052e-09,8.59183e-09,1.97931e-08,0.000597125,1.04687e-07,2.49641e-07,4.06852e-08,0,0,0,0,0,0,0,0,0.646312,0,0,0,0,0, +0.00074,2656.37,0.109836,101325,0.0329026,0.00934728,0.00349793,0.0119285,0.0192027,0.27615,4.10773e-06,2.90946e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.12807e-07,4.08523e-08,9.03372e-09,8.76329e-09,1.9715e-08,0.000613038,1.07679e-07,2.5072e-07,4.17294e-08,0,0,0,0,0,0,0,0,0.646353,0,0,0,0,0, +0.00075,2657.16,0.10981,101325,0.0328534,0.00930966,0.00348381,0.0119002,0.0191765,0.276253,4.10456e-06,2.91392e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.15278e-07,4.13236e-08,9.18274e-09,8.92951e-09,1.96441e-08,0.000628932,1.10657e-07,2.51702e-07,4.27689e-08,0,0,0,0,0,0,0,0,0.646389,0,0,0,0,0, +0.00076,2657.88,0.109788,101325,0.032809,0.00927556,0.00347091,0.011874,0.0191523,0.276347,4.10153e-06,2.91791e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.17711e-07,4.17856e-08,9.32786e-09,9.09078e-09,1.95798e-08,0.000644804,1.1362e-07,2.52596e-07,4.38038e-08,0,0,0,0,0,0,0,0,0.646421,0,0,0,0,0, +0.00077,2658.53,0.109767,101325,0.032769,0.00924464,0.00345913,0.0118498,0.01913,0.276432,4.09864e-06,2.92147e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.20109e-07,4.2239e-08,9.46933e-09,9.24743e-09,1.95215e-08,0.000660655,1.1657e-07,2.53409e-07,4.48342e-08,0,0,0,0,0,0,0,0,0.64645,0,0,0,0,0, +0.00078,2659.12,0.109748,101325,0.0327329,0.0092166,0.00344836,0.0118274,0.0191095,0.276509,4.09586e-06,2.92463e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.22475e-07,4.26845e-08,9.60741e-09,9.39974e-09,1.94685e-08,0.000676484,1.19506e-07,2.54149e-07,4.58603e-08,0,0,0,0,0,0,0,0,0.646475,0,0,0,0,0, +0.00079,2659.64,0.109732,101325,0.0327005,0.00919117,0.00343851,0.0118066,0.0190905,0.276578,4.09319e-06,2.92744e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.24812e-07,4.31227e-08,9.74233e-09,9.548e-09,1.94203e-08,0.00069229,1.22428e-07,2.54822e-07,4.68821e-08,0,0,0,0,0,0,0,0,0.646497,0,0,0,0,0, +0.0008,2660.12,0.109717,101325,0.0326714,0.00916808,0.00342948,0.0117873,0.0190729,0.276641,4.09062e-06,2.92991e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.27123e-07,4.35541e-08,9.87432e-09,9.69248e-09,1.93765e-08,0.000708073,1.25338e-07,2.55433e-07,4.78999e-08,0,0,0,0,0,0,0,0,0.646516,0,0,0,0,0, +0.00081,2660.55,0.109703,101325,0.0326452,0.00914713,0.00342119,0.0117693,0.0190566,0.276698,4.08814e-06,2.93209e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.29409e-07,4.39792e-08,1.00036e-08,9.83344e-09,1.93368e-08,0.000723833,1.28236e-07,2.55988e-07,4.89138e-08,0,0,0,0,0,0,0,0,0.646533,0,0,0,0,0, +0.00082,2660.94,0.109691,101325,0.0326218,0.0091281,0.00341359,0.0117525,0.0190415,0.27675,4.08574e-06,2.93399e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.31673e-07,4.43985e-08,1.01303e-08,9.97112e-09,1.93006e-08,0.000739568,1.31121e-07,2.56493e-07,4.99239e-08,0,0,0,0,0,0,0,0,0.646548,0,0,0,0,0, +0.00083,2661.29,0.10968,101325,0.0326008,0.00911081,0.00340659,0.0117368,0.0190275,0.276797,4.08342e-06,2.93565e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.33915e-07,4.48124e-08,1.02547e-08,1.01058e-08,1.92677e-08,0.00075528,1.33994e-07,2.56952e-07,5.09303e-08,0,0,0,0,0,0,0,0,0.64656,0,0,0,0,0, +0.00084,2661.6,0.10967,101325,0.032582,0.00909511,0.00340015,0.0117221,0.0190145,0.276839,4.08117e-06,2.93708e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.36138e-07,4.52213e-08,1.03769e-08,1.02376e-08,1.92377e-08,0.000770967,1.36856e-07,2.57369e-07,5.19331e-08,0,0,0,0,0,0,0,0,0.646571,0,0,0,0,0, +0.00085,2661.88,0.109662,101325,0.0325653,0.00908083,0.00339421,0.0117084,0.0190023,0.276877,4.07898e-06,2.9383e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.38344e-07,4.56256e-08,1.04971e-08,1.03668e-08,1.92104e-08,0.00078663,1.39707e-07,2.57748e-07,5.29326e-08,0,0,0,0,0,0,0,0,0.64658,0,0,0,0,0, +0.00086,2662.13,0.109654,101325,0.0325504,0.00906785,0.00338873,0.0116954,0.018991,0.276912,4.07685e-06,2.93934e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.40533e-07,4.60256e-08,1.06154e-08,1.04935e-08,1.91855e-08,0.000802268,1.42547e-07,2.58092e-07,5.39287e-08,0,0,0,0,0,0,0,0,0.646587,0,0,0,0,0, +0.00087,2662.36,0.109647,101325,0.0325371,0.00905603,0.00338366,0.0116832,0.0189804,0.276943,4.07477e-06,2.94021e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.42706e-07,4.64216e-08,1.07321e-08,1.0618e-08,1.91629e-08,0.00081788,1.45377e-07,2.58405e-07,5.49216e-08,0,0,0,0,0,0,0,0,0.646593,0,0,0,0,0, +0.00088,2662.56,0.109641,101325,0.0325254,0.00904528,0.00337896,0.0116717,0.0189704,0.276972,4.07274e-06,2.94092e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.44864e-07,4.68139e-08,1.0847e-08,1.07405e-08,1.91422e-08,0.000833468,1.48196e-07,2.5869e-07,5.59115e-08,0,0,0,0,0,0,0,0,0.646598,0,0,0,0,0, +0.00089,2662.74,0.109635,101325,0.032515,0.00903549,0.0033746,0.0116608,0.0189611,0.276997,4.07076e-06,2.9415e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.47009e-07,4.72028e-08,1.09606e-08,1.0861e-08,1.91233e-08,0.000849029,1.51005e-07,2.58949e-07,5.68983e-08,0,0,0,0,0,0,0,0,0.646601,0,0,0,0,0, +0.0009,2662.9,0.10963,101325,0.0325059,0.00902656,0.00337055,0.0116505,0.0189523,0.277021,4.06881e-06,2.94195e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.49141e-07,4.75884e-08,1.10727e-08,1.09797e-08,1.91061e-08,0.000864566,1.53805e-07,2.59184e-07,5.78823e-08,0,0,0,0,0,0,0,0,0.646604,0,0,0,0,0, +0.00091,2663.05,0.109626,101325,0.032498,0.00901843,0.00336678,0.0116407,0.018944,0.277041,4.0669e-06,2.94229e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.51261e-07,4.7971e-08,1.11835e-08,1.10967e-08,1.90903e-08,0.000880076,1.56595e-07,2.59399e-07,5.88634e-08,0,0,0,0,0,0,0,0,0.646605,0,0,0,0,0, +0.00092,2663.17,0.109622,101325,0.032491,0.00901101,0.00336326,0.0116313,0.0189361,0.27706,4.06503e-06,2.94252e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.53369e-07,4.83508e-08,1.12932e-08,1.12122e-08,1.90759e-08,0.00089556,1.59376e-07,2.59594e-07,5.98418e-08,0,0,0,0,0,0,0,0,0.646606,0,0,0,0,0, +0.00093,2663.29,0.109619,101325,0.032485,0.00900423,0.00335996,0.0116224,0.0189287,0.277077,4.06319e-06,2.94265e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.55466e-07,4.8728e-08,1.14018e-08,1.13263e-08,1.90627e-08,0.000911018,1.62148e-07,2.59772e-07,6.08175e-08,0,0,0,0,0,0,0,0,0.646606,0,0,0,0,0, +0.00094,2663.39,0.109616,101325,0.0324798,0.00899804,0.00335687,0.0116138,0.0189217,0.277093,4.06137e-06,2.94271e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.57553e-07,4.91026e-08,1.15093e-08,1.1439e-08,1.90506e-08,0.00092645,1.64911e-07,2.59935e-07,6.17906e-08,0,0,0,0,0,0,0,0,0.646605,0,0,0,0,0, +0.00095,2663.48,0.109613,101325,0.0324753,0.00899239,0.00335398,0.0116056,0.018915,0.277106,4.05959e-06,2.94268e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.5963e-07,4.9475e-08,1.16159e-08,1.15506e-08,1.90395e-08,0.000941856,1.67665e-07,2.60083e-07,6.27612e-08,0,0,0,0,0,0,0,0,0.646604,0,0,0,0,0, +0.00096,2663.55,0.109611,101325,0.0324716,0.00898721,0.00335125,0.0115977,0.0189086,0.277119,4.05782e-06,2.94258e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.61698e-07,4.98452e-08,1.17215e-08,1.1661e-08,1.90293e-08,0.000957235,1.70411e-07,2.60218e-07,6.37293e-08,0,0,0,0,0,0,0,0,0.646602,0,0,0,0,0, +0.00097,2663.62,0.109609,101325,0.0324685,0.00898247,0.00334867,0.0115901,0.0189024,0.27713,4.05608e-06,2.94243e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.63756e-07,5.02133e-08,1.18264e-08,1.17703e-08,1.90199e-08,0.000972587,1.73149e-07,2.60342e-07,6.4695e-08,0,0,0,0,0,0,0,0,0.6466,0,0,0,0,0, +0.00098,2663.68,0.109607,101325,0.0324659,0.00897812,0.00334624,0.0115828,0.0188966,0.27714,4.05436e-06,2.94221e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.65806e-07,5.05794e-08,1.19305e-08,1.18787e-08,1.90113e-08,0.000987912,1.75879e-07,2.60456e-07,6.56584e-08,0,0,0,0,0,0,0,0,0.646597,0,0,0,0,0, +0.00099,2663.73,0.109606,101325,0.0324639,0.00897414,0.00334393,0.0115757,0.0188909,0.277149,4.05266e-06,2.94194e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.67847e-07,5.09437e-08,1.20338e-08,1.19861e-08,1.90033e-08,0.00100321,1.78601e-07,2.6056e-07,6.66194e-08,0,0,0,0,0,0,0,0,0.646594,0,0,0,0,0, +0.001,2663.78,0.109605,101325,0.0324623,0.00897047,0.00334174,0.0115688,0.0188855,0.277157,4.05098e-06,2.94163e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3.6988e-07,5.13062e-08,1.21365e-08,1.20928e-08,1.89959e-08,0.00101848,1.81315e-07,2.60656e-07,6.75782e-08,0,0,0,0,0,0,0,0,0.64659,0,0,0,0,0, diff --git a/test_problems/cxx_ex/runtest b/test_problems/cxx_ex/runtest new file mode 100755 index 000000000..05527bd59 --- /dev/null +++ b/test_problems/cxx_ex/runtest @@ -0,0 +1,121 @@ +#!/bin/sh +# +# + +temp_success="1" +/bin/rm -f eq1.csv tr1.csv tr2.csv kin1.csv kin2.csv + +################################################################# +# +################################################################# + +CANTERA_BIN=${CANTERA_BIN:=../../bin} +$CANTERA_BIN/cxx_examples > cxx_examples.out +retnStat=$? +if [ $retnStat != "0" ] +then + temp_success="0" + echo "cxx_examples returned with bad status, $retnStat, check output" +fi + +################################################################# +# +################################################################# + +$CANTERA_BIN/csvdiff eq1.csv eq1_blessed.csv > eq1_test.out +retnStat=$? +if [ $retnStat = "1" ] +then + echo "successful csv comparison on eq1 test" +else + echo "unsuccessful csv comparison on eq1 test" + echo "FAILED" > csvCode.txt + temp_success="0" +fi + +################################################################# +# +################################################################# + +$CANTERA_BIN/csvdiff tr1.csv tr1_blessed.csv > tr1_test.out +retnStat=$? +if [ $retnStat = "1" ] +then + echo "successful csv comparison on tr1 test" + if [ $temp_success = "1" ] + then + echo "PASSED" > csvCode.txt + fi +else + echo "unsuccessful csv comparison on tr1 test" + echo "FAILED" > csvCode.txt + temp_success="0" +fi + +################################################################# +# +################################################################# + +$CANTERA_BIN/csvdiff tr2.csv tr2_blessed.csv > tr2_test.out +retnStat=$? +if [ $retnStat = "1" ] +then + echo "successful csv comparison on tr2 test" + if [ $temp_success = "1" ] + then + echo "PASSED" > csvCode.txt + fi +else + echo "unsuccessful csv comparison on tr2 test" + echo "FAILED" > csvCode.txt + temp_success="0" +fi + +################################################################# +# +################################################################# + +$CANTERA_BIN/csvdiff kin1.csv kin1_blessed.csv > kin1_test.out +retnStat=$? +if [ $retnStat = "1" ] +then + echo "successful csv comparison on kin1 test" + if [ $temp_success = "1" ] + then + echo "PASSED" > csvCode.txt + fi +else + echo "unsuccessful csv comparison on kin1 test" + echo "FAILED" > csvCode.txt + temp_success="0" +fi + +################################################################# +# +################################################################# + +$CANTERA_BIN/csvdiff kin2.csv kin2_blessed.csv > kin2_test.out +retnStat=$? +if [ $retnStat = "1" ] +then + echo "successful csv comparison on kin2 test" + if [ $temp_success = "1" ] + then + echo "PASSED" > csvCode.txt + fi +else + echo "unsuccessful csv comparison on kin2 test" + echo "FAILED" > csvCode.txt + temp_success="0" +fi +if [ $temp_success = "1" ] +then + echo 'cxx_examples csv test PASSED!' +else + echo 'cxx_examples csv test FAILED!' +fi + +################################################################# +# +################################################################# + diff --git a/test_problems/cxx_ex/silane.inp b/test_problems/cxx_ex/silane.inp new file mode 100644 index 000000000..efe972bd8 --- /dev/null +++ b/test_problems/cxx_ex/silane.inp @@ -0,0 +1,108 @@ +ELEMENTS +SI H HE +END +SPECIES +H2 H HE SIH4 SI SIH SIH2 SIH3 +H3SISIH +SI2H6 H2SISIH2 +SI3H8 +SI2 SI3 +END +THERMO ALL + 300.000 1000.000 5000.000 +HE 120186HE 1 G 0300.00 5000.00 1000.00 1 + 0.02500000E+02 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 +-0.07453750E+04 0.09153489E+01 0.02500000E+02 0.00000000E+00 0.00000000E+00 3 + 0.00000000E+00 0.00000000E+00-0.07453750E+04 0.09153488E+01 4 +SIH 121986SI 1H 1 G 0300.00 2000.00 1000.00 1 + 0.03110430E+02 0.01094946E-01 0.02898629E-06-0.02745104E-08 0.07051799E-12 2 + 0.04516898E+06 0.04193487E+02 0.03836010E+02-0.02702657E-01 0.06849070E-04 3 +-0.05424184E-07 0.01472131E-10 0.04507593E+06 0.09350778E+01 4 +SIH2 42489SI 1H 2 G 0300.00 3000.00 1000.00 1 + 0.04142390E+02 0.02150191E-01-0.02190730E-05-0.02073725E-08 0.04741018E-12 2 + 0.03110484E+06 0.02930745E+01 0.03475092E+02 0.02139338E-01 0.07672306E-05 3 + 0.05217668E-08-0.09898824E-11 0.03147397E+06 0.04436585E+02 4 +SIH3 42489SI 1H 3 G 0300.00 3000.00 1000.00 1 + 0.05015906E+02 0.03732750E-01-0.03609053E-05-0.03729193E-08 0.08468490E-12 2 + 0.02190233E+06-0.04291368E+02 0.02946733E+02 0.06466764E-01 0.05991653E-05 3 +-0.02218413E-07 0.03052670E-11 0.02270173E+06 0.07347948E+02 4 +H3SISIH 111191H 4SI 2 G 0300.00 4000.00 1500.00 1 + 0.01127202E+03 0.02538145E-01-0.02998472E-05-0.09465367E-09 0.01855053E-12 2 + 0.03297169E+06-0.03264598E+03 0.03698707E+02 0.01870180E+00-0.01430704E-03 3 + 0.06005836E-07-0.01116293E-10 0.03590825E+06 0.08825191E+02 4 +H2SISIH2 42489SI 2H 4 G 0300.00 3000.00 1000.00 1 + 0.08986817E+02 0.05405047E-01-0.05214022E-05-0.05313742E-08 0.01188727E-11 2 + 0.02832748E+06-0.02004478E+03 0.05133186E+02 0.01252855E+00-0.04620421E-05 3 +-0.06606075E-07 0.02864345E-10 0.02956915E+06 0.07605133E+01 4 +SIH4 90784SI 1H 4 0 0G 300.000 2000.000 1 + 0.79359380E+00 0.17671899E-01-0.11398009E-04 0.35992604E-08-0.45241571E-12 2 + 0.31982127E+04 0.15242257E+02 0.14516404E+01 0.13987363E-01-0.42345639E-05 3 +-0.23606142E-08 0.13712089E-11 0.31134105E+04 0.12321855E+02 4 +SI2H6 90784SI 2H 6 0 0G 300.000 2000.000 1 + 0.34074936E+01 0.27206479E-01-0.17713204E-04 0.56391177E-08 -.71378682E-12 2 + 0.75321842E+04 0.61321754E+01 0.67347983E+00 0.40931531E-01 -.44841255E-04 3 + 0.29952232E-07-0.89010854E-11 0.79327875E+04 0.18627403E+02 4 +SI2 90784SI 2 0 0 0G 300.000 2000.000 1 + 0.41446779E+01 0.65234677E-03-0.50108520E-06 0.18062843E-09 -.25161111E-13 2 + 0.69694707E+05 0.38627366E+01 0.29671976E+01 0.63119558E-02 -.10970790E-04 3 + 0.89278680E-08-0.27873689E-11 0.69870738E+05 0.92789503E+01 4 +SI3H8 90784SI 3H 8 0 0G 300.000 2000.000 1 + 0.60933341E+01 0.36580112E-01-0.23892361E-04 0.76271932E-08 -.96769384E-12 2 + 0.11297205E+05-0.27475654E+01 0.77196846E+00 0.63442740E-01 -.76726109E-04 3 + 0.54543715E-07-0.16611729E-10 0.12071263E+05 0.21532507E+02 4 +SI J 3/67SI 1 0 0 0G 300.000 5000.000 1 + 0.26506014E+01-0.35763852E-03 0.29592293E-06-0.72804829E-10 0.57963329E-14 2 + 0.53437054E+05 0.52204057E+01 0.31793537E+01-0.27646992E-02 0.44784038E-05 3 +-0.32833177E-08 0.91213631E-12 0.53339032E+05 0.27273204E+01 4 +SI3 J 3/67SI 3 0 0 0G 300.000 5000.000 1 + 0.74213360E+01-0.11709948E-03 0.89820775E-07 0.71935964E-11-0.25670837E-14 2 + 0.74146699E+05-0.10365274E+02 0.45979129E+01 0.10715274E-01-0.16100422E-04 3 + 0.10969207E-07-0.27832875E-11 0.74766324E+05 0.34421671E+01 4 +H L 7/88H 1 00 00 00G 200.000 3500.000 1000.000 1 + 2.50000001E+00-2.30842973E-11 1.61561948E-14-4.73515235E-18 4.98197357E-22 2 + 2.54736599E+04-4.46682914E-01 2.50000000E+00 7.05332819E-13-1.99591964E-15 3 + 2.30081632E-18-9.27732332E-22 2.54736599E+04-4.46682853E-01 4 +H2 TPIS78H 2 00 00 00G 200.000 3500.000 1000.000 1 + 3.33727920E+00-4.94024731E-05 4.99456778E-07-1.79566394E-10 2.00255376E-14 2 +-9.50158922E+02-3.20502331E+00 2.34433112E+00 7.98052075E-03-1.94781510E-05 3 + 2.01572094E-08-7.37611761E-12-9.17935173E+02 6.83010238E-01 4 +END +REACTIONS +SIH4 + H = SIH3 + H2 7.8e14 0.0 2260. ! Roth +SIH4 + M = SIH3 + H + M 3.91e15 0.0 89356. ! 94TAK/MOM tst calc +SIH3 + H = SIH2 + H2 7.8e14 0.0 2260. ! assume same as SIH4 +SI + SI + M = SI2 + M 2.47e16 0.0 1178.0 ! 90MAR/RAF +SIH4 + SIH2 = H3SISIH + H2 1.3E13 0.0 0.0 ! R8 +SIH + H2 = SIH2 + H 4.8E14 0.0 23.64 ! R11 +SIH + SIH4 = H3SISIH + H 1.6E14 0.0 0.0 ! R12 +SI + H2 = SIH + H 1.5E15 0.0 31.8 ! R13 +! +SIH4(+M)=SIH2+H2(+M) 0.3119E+10 1.669 54710. ! R1 + LOW / 0.5214E30 -3.545 57550./ + TROE / -0.4984 888.3 209.4 2760./ + SIH4/4./ SI2H6/4./ ! HF(SiH2)=64.3, anh_inc.16b, beta(Ar,300) = 0.25 fit from 300 to 1200K + +H3SISIH(+M)=H2SISIH2(+M) 0.254E+14 -0.2239 5381.000 ! A6 + LOW / 0.1099E34 -5.765 9152. / + TROE / -0.4202 214.5 103. 136.3 / + SIH4/4./ SI2H6/4./ +! +! RRKM fits 3/18/93 by MEC +SI3H8(+M)=SIH4+H3SISIH(+M) 3.73E+12 0.992 50850.000 + LOW / 4.36E76 -17.26 59303. / + TROE / 0.4157 365.3 3102. 9.724 / + SIH4/4./ SI2H6/4./ +SI3H8(+M)=SIH2+SI2H6(+M) 6.97E+12 0.9691 52677.000 + LOW / 1.73E69 -15.07 60491. / + TROE / -3.47E-5 442.0 2412. 128.3 / + SIH4/4./ SI2H6/4./ +SI2H6(+M)=H2+H3SISIH(+M) 9.086E+9 1.834 54197.000 + LOW / 1.945E44 -7.772 59023. / + TROE / -0.1224 793.3 2400. 11.39 / + SIH4/4./ SI2H6/4./ + +SI2H6(+M)=SIH4+SIH2(+M) 1.81E+10 1.747 50203.000 ! A3 + LOW / 5.09E53 -10.37 56034. / + TROE / 4.375E-5 438.5 2726. 438.2 / + SIH4/4./ SI2H6/4./ +END diff --git a/test_problems/cxx_ex/silane.xml b/test_problems/cxx_ex/silane.xml new file mode 100644 index 000000000..a64f8192a --- /dev/null +++ b/test_problems/cxx_ex/silane.xml @@ -0,0 +1,480 @@ + + + + + + + 300 + 1 + H2:1.0 + + + Si H He + + H2 H HE SIH4 SI SIH SIH2 SIH3 H3SISIH SI2H6 + H2SISIH2 SI3H8 SI2 SI3 + + + + + + + + + + + + + TPIS78 + H:2 + + + + 2.344331120E+00, 7.980520750E-03, -1.947815100E-05, + 2.015720940E-08, -7.376117610E-12, -9.179351730E+02, + 6.830102380E-01 + + + 3.337279200E+00, -4.940247310E-05, 4.994567780E-07, + -1.795663940E-10, 2.002553760E-14, -9.501589220E+02, + -3.205023310E+00 + + + + + + + + L 7/88 + H:1 + + + + 2.500000000E+00, 7.053328190E-13, -1.995919640E-15, + 2.300816320E-18, -9.277323320E-22, 2.547365990E+04, + -4.466828530E-01 + + + 2.500000010E+00, -2.308429730E-11, 1.615619480E-14, + -4.735152350E-18, 4.981973570E-22, 2.547365990E+04, + -4.466829140E-01 + + + + + + + + 120186 + He:1 + + + + 2.500000000E+00, 0.000000000E+00, 0.000000000E+00, + 0.000000000E+00, 0.000000000E+00, -7.453750000E+02, + 9.153488000E-01 + + + 2.500000000E+00, 0.000000000E+00, 0.000000000E+00, + 0.000000000E+00, 0.000000000E+00, -7.453750000E+02, + 9.153489000E-01 + + + + + + + + 90784 + Si:1 H:4 + + + + 1.451640400E+00, 1.398736300E-02, -4.234563900E-06, + -2.360614200E-09, 1.371208900E-12, 3.113410500E+03, + 1.232185500E+01 + + + 7.935938000E-01, 1.767189900E-02, -1.139800900E-05, + 3.599260400E-09, -4.524157100E-13, 3.198212700E+03, + 1.524225700E+01 + + + + + + + + J 3/67 + Si:1 + + + + 3.179353700E+00, -2.764699200E-03, 4.478403800E-06, + -3.283317700E-09, 9.121363100E-13, 5.333903200E+04, + 2.727320400E+00 + + + 2.650601400E+00, -3.576385200E-04, 2.959229300E-07, + -7.280482900E-11, 5.796332900E-15, 5.343705400E+04, + 5.220405700E+00 + + + + + + + + 121986 + Si:1 H:1 + + + + 3.836010000E+00, -2.702657000E-03, 6.849070000E-06, + -5.424184000E-09, 1.472131000E-12, 4.507593000E+04, + 9.350778000E-01 + + + 3.110430000E+00, 1.094946000E-03, 2.898629000E-08, + -2.745104000E-10, 7.051799000E-14, 4.516898000E+04, + 4.193487000E+00 + + + + + + + + 42489 + Si:1 H:2 + + + + 3.475092000E+00, 2.139338000E-03, 7.672306000E-07, + 5.217668000E-10, -9.898824000E-13, 3.147397000E+04, + 4.436585000E+00 + + + 4.142390000E+00, 2.150191000E-03, -2.190730000E-07, + -2.073725000E-10, 4.741018000E-14, 3.110484000E+04, + 2.930745000E-01 + + + + + + + + 42489 + Si:1 H:3 + + + + 2.946733000E+00, 6.466764000E-03, 5.991653000E-07, + -2.218413000E-09, 3.052670000E-13, 2.270173000E+04, + 7.347948000E+00 + + + 5.015906000E+00, 3.732750000E-03, -3.609053000E-07, + -3.729193000E-10, 8.468490000E-14, 2.190233000E+04, + -4.291368000E+00 + + + + + + + + 111191 + H:4 Si:2 + + + + 3.698707000E+00, 1.870180000E-02, -1.430704000E-05, + 6.005836000E-09, -1.116293000E-12, 3.590825000E+04, + 8.825191000E+00 + + + 1.127202000E+01, 2.538145000E-03, -2.998472000E-07, + -9.465367000E-11, 1.855053000E-14, 3.297169000E+04, + -3.264598000E+01 + + + + + + + + 90784 + Si:2 H:6 + + + + 6.734798300E-01, 4.093153100E-02, -4.484125500E-05, + 2.995223200E-08, -8.901085400E-12, 7.932787500E+03, + 1.862740300E+01 + + + 3.407493600E+00, 2.720647900E-02, -1.771320400E-05, + 5.639117700E-09, -7.137868200E-13, 7.532184200E+03, + 6.132175400E+00 + + + + + + + + 42489 + Si:2 H:4 + + + + 5.133186000E+00, 1.252855000E-02, -4.620421000E-07, + -6.606075000E-09, 2.864345000E-12, 2.956915000E+04, + 7.605133000E-01 + + + 8.986817000E+00, 5.405047000E-03, -5.214022000E-07, + -5.313742000E-10, 1.188727000E-13, 2.832748000E+04, + -2.004478000E+01 + + + + + + + + 90784 + Si:3 H:8 + + + + 7.719684600E-01, 6.344274000E-02, -7.672610900E-05, + 5.454371500E-08, -1.661172900E-11, 1.207126300E+04, + 2.153250700E+01 + + + 6.093334100E+00, 3.658011200E-02, -2.389236100E-05, + 7.627193200E-09, -9.676938400E-13, 1.129720500E+04, + -2.747565400E+00 + + + + + + + + 90784 + Si:2 + + + + 2.967197600E+00, 6.311955800E-03, -1.097079000E-05, + 8.927868000E-09, -2.787368900E-12, 6.987073800E+04, + 9.278950300E+00 + + + 4.144677900E+00, 6.523467700E-04, -5.010852000E-07, + 1.806284300E-10, -2.516111100E-14, 6.969470700E+04, + 3.862736600E+00 + + + + + + + + J 3/67 + Si:3 + + + + 4.597912900E+00, 1.071527400E-02, -1.610042200E-05, + 1.096920700E-08, -2.783287500E-12, 7.476632400E+04, + 3.442167100E+00 + + + 7.421336000E+00, -1.170994800E-04, 8.982077500E-08, + 7.193596400E-12, -2.567083700E-15, 7.414669900E+04, + -1.036527400E+01 + + + + + + + + + + + + SIH4 + H [=] SIH3 + H2 + SIH4:1 H:1 + SIH3:1 H2:1 + + 7.8e+14 0 2260 + + + + + + SIH4 + M [=] SIH3 + H + M + SIH4:1 + SIH3:1 H:1 + + 3.91e+15 0 89356 + + + + + + SIH3 + H [=] SIH2 + H2 + SIH3:1 H:1 + SIH2:1 H2:1 + + 7.8e+14 0 2260 + + + + + + SI + SI + M [=] SI2 + M + SI:1 SI:1 + SI2:1 + + 2.47e+16 0 1178 + + + + + + SIH4 + SIH2 [=] H3SISIH + H2 + SIH4:1 SIH2:1 + H3SISIH:1 H2:1 + + 1.3e+13 0 0 + + + + + + SIH + H2 [=] SIH2 + H + SIH:1 H2:1 + SIH2:1 H:1 + + 4.8e+14 0 23.64 + + + + + + SIH + SIH4 [=] H3SISIH + H + SIH:1 SIH4:1 + H3SISIH:1 H:1 + + 1.6e+14 0 0 + + + + + + SI + H2 [=] SIH + H + SI:1 H2:1 + SIH:1 H:1 + + 1.5e+15 0 31.8 + + + + + + SIH4 (+ M) [=] SIH2 + H2 (+ M) + SIH4:1 + SIH2:1 H2:1 + + 3.119e+09 1.669 54710 + 5.214e+29 -3.545 57550 + -0.4984 888.3 209.4 2760 + + SI2H6:4 SIH4:4 + + + + + + + H3SISIH (+ M) [=] H2SISIH2 (+ M) + H3SISIH:1 + H2SISIH2:1 + + 2.54e+13 -0.2239 5381 + 1.099e+33 -5.765 9152 + -0.4202 214.5 103 136.3 + + SI2H6:4 SIH4:4 + + + + + + + SI3H8 (+ M) [=] SIH4 + H3SISIH (+ M) + SI3H8:1 + SIH4:1 H3SISIH:1 + + 3.73e+12 0.992 50850 + 4.36e+76 -17.26 59303 + 0.4157 365.3 3102 9.724 + + SI2H6:4 SIH4:4 + + + + + + + SI3H8 (+ M) [=] SIH2 + SI2H6 (+ M) + SI3H8:1 + SIH2:1 SI2H6:1 + + 6.97e+12 0.9691 52677 + 1.73e+69 -15.07 60491 + -3.47e-05 442 2412 128.3 + + SI2H6:4 SIH4:4 + + + + + + + SI2H6 (+ M) [=] H2 + H3SISIH (+ M) + SI2H6:1 + H2:1 H3SISIH:1 + + 9.086e+09 1.834 54197 + 1.945e+44 -7.772 59023 + -0.1224 793.3 2400 11.39 + + SI2H6:4 SIH4:4 + + + + + + + SI2H6 (+ M) [=] SIH4 + SIH2 (+ M) + SI2H6:1 + SIH4:1 SIH2:1 + + 1.81e+10 1.747 50203 + 5.09e+53 -10.37 56034 + 4.375e-05 438.5 2726 438.2 + + SI2H6:4 SIH4:4 + + + + + \ No newline at end of file diff --git a/test_problems/cxx_ex/tr1_blessed.csv b/test_problems/cxx_ex/tr1_blessed.csv new file mode 100644 index 000000000..991c0367f --- /dev/null +++ b/test_problems/cxx_ex/tr1_blessed.csv @@ -0,0 +1,22 @@ +transport example 1: mixture-averaged transport properties, +Temperature (K),Viscosity (),Thermal Conductivity (W/m-K),H2,H,O,O2,OH,H2O,HO2,H2O2,C,CH,CH2,CH2(S),CH3,CH4,CO,CO2,HCO,CH2O,CH2OH,CH3O,CH3OH,C2H,C2H2,C2H3,C2H4,C2H5,C2H6,HCCO,CH2CO,HCCOH,N,NH,NH2,NH3,NNH,NO,NO2,N2O,HNO,CN,HCN,H2CN,HCNN,HCNO,HOCN,HNCO,NCO,N2,AR,C3H7,C3H8,CH2CHO,CH3CHO, +500,1.43776e-05,0.228556,0.000429327,0.000239426,0.000107173,7.8381e-05,0.000106516,8.80214e-05,7.82252e-05,7.80776e-05,9.34227e-05,0.000109604,7.38842e-05,7.38842e-05,7.3335e-05,5.39485e-05,7.5303e-05,6.45785e-05,6.38125e-05,6.36596e-05,6.28513e-05,6.28513e-05,6.2987e-05,6.18838e-05,6.16991e-05,6.15264e-05,6.15504e-05,5.67296e-05,5.65971e-05,0.000102396,5.68551e-05,5.68551e-05,9.1789e-05,0.000111673,0.000110918,8.22406e-05,7.40448e-05,7.56334e-05,7.11939e-05,6.3723e-05,7.71217e-05,7.30656e-05,6.2224e-05,6.2056e-05,0.000102396,6.37984e-05,6.37984e-05,6.37984e-05,6.38786e-05,7.59941e-05,7.85967e-05,4.61899e-05,4.61349e-05,5.67829e-05,5.67138e-05, +600,1.62366e-05,0.262276,0.000583079,0.000325714,0.000145484,0.000106554,0.000144595,0.000121967,0.000106343,0.000106143,0.000126753,0.000148778,0.000100581,0.000100581,9.98354e-05,7.32687e-05,0.00010232,8.82959e-05,8.79208e-05,8.77118e-05,8.65072e-05,8.65072e-05,8.67503e-05,8.44819e-05,8.42309e-05,8.39964e-05,8.42498e-05,7.75732e-05,7.7393e-05,0.00013949,7.82131e-05,7.82131e-05,0.000124541,0.000151592,0.000150569,0.000113435,0.000100477,0.000102768,9.71809e-05,8.70881e-05,0.000104887,9.91647e-05,8.5883e-05,8.56529e-05,0.000139489,8.71906e-05,8.71906e-05,8.71906e-05,8.72997e-05,0.000103256,0.000106997,6.3199e-05,6.31242e-05,7.81146e-05,7.80202e-05, +700,1.79776e-05,0.295035,0.000754466,0.000421922,0.000188195,0.000137965,0.000187046,0.000160052,0.000137692,0.000137434,0.000163911,0.000192449,0.000130349,0.000130349,0.000129386,9.48049e-05,0.000132441,0.000114766,0.000114897,0.000114625,0.000112966,0.000112966,0.000113336,0.000109694,0.000109369,0.000109065,0.000109591,0.000100837,0.000100603,0.000180858,0.000102097,0.000102097,0.000161053,0.000196095,0.000194773,0.000148355,0.000129945,0.000133019,0.000126173,0.000113162,0.000135844,0.000128261,0.000112377,0.000112078,0.000180857,0.000113295,0.000113295,0.000113295,0.000113436,0.000133651,0.000138665,8.21859e-05,8.20892e-05,0.000101969,0.000101847, +800,1.96251e-05,0.32732,0.000942554,0.000527517,0.000235072,0.000172441,0.000233639,0.000202005,0.000172101,0.000171778,0.000204694,0.000240382,0.000163025,0.000163025,0.000161821,0.00011844,0.000165501,0.000143833,0.000144565,0.000144225,0.000142057,0.000142057,0.000142572,0.000137373,0.000136968,0.000136588,0.000137424,0.000126383,0.000126091,0.000226267,0.000128354,0.000128354,0.000201129,0.000244939,0.00024329,0.00018677,0.000162288,0.000166223,0.000158003,0.000141793,0.000169822,0.000160195,0.000141528,0.000141153,0.000226266,0.000141959,0.000141959,0.000141959,0.000142135,0.00016701,0.000173426,0.000103038,0.000102917,0.000128194,0.000128041, +900,2.11961e-05,0.359382,0.00114659,0.000642066,0.000285928,0.000209841,0.000284186,0.000247612,0.000209428,0.000209036,0.00024894,0.000292382,0.000198471,0.000198471,0.000197008,0.000144078,0.000201365,0.000175372,0.000176783,0.000176369,0.000173644,0.000173644,0.000174319,0.000167404,0.00016691,0.000166449,0.000167625,0.000154101,0.000153747,0.000275529,0.000156863,0.000156863,0.000244606,0.000297929,0.000295924,0.000228495,0.000197376,0.000202243,0.000192536,0.000172857,0.000206683,0.000194841,0.000173195,0.000172738,0.000275528,0.000173058,0.000173058,0.000173058,0.000173273,0.000203201,0.000211135,0.000125664,0.000125517,0.000156668,0.000156481, +1000,2.27027e-05,0.391342,0.00136592,0.000765208,0.000340604,0.000250049,0.00033853,0.000296697,0.000249556,0.000249089,0.00029651,0.000348288,0.000236577,0.000236577,0.000234835,0.00017164,0.000239922,0.000209277,0.000211438,0.000210943,0.000207616,0.000207616,0.000208466,0.000199687,0.000199099,0.000198549,0.000200095,0.0001839,0.000183478,0.000328486,0.000187523,0.000187523,0.000291351,0.000354899,0.000352512,0.000273379,0.000235101,0.000240967,0.000229659,0.000206252,0.000246309,0.000232089,0.000207262,0.000206716,0.000328484,0.000206492,0.000206492,0.000206492,0.000206748,0.000242107,0.000251673,0.000149989,0.000149814,0.00018729,0.000187067, +1100,2.41542e-05,0.423243,0.00160003,0.000896635,0.000398964,0.000292963,0.000396536,0.000349116,0.000292386,0.00029184,0.000347287,0.000407962,0.000277246,0.000277246,0.000275205,0.000201057,0.000281076,0.000245463,0.000248431,0.000247851,0.000243879,0.000243879,0.000244916,0.00023414,0.000233451,0.000232808,0.000234749,0.000215703,0.000215208,0.000385004,0.000220249,0.000220249,0.000341246,0.000415708,0.000412912,0.000321293,0.000275368,0.000282299,0.000269279,0.000241892,0.000288602,0.000271847,0.000243631,0.000242991,0.000385002,0.000242173,0.000242173,0.000242173,0.000242473,0.000283634,0.000294939,0.00017595,0.000175744,0.000219976,0.000219715, +1200,2.55577e-05,0.455088,0.00184842,0.00103608,0.00046089,0.000338496,0.000458085,0.000404743,0.00033783,0.000337199,0.000401168,0.000471281,0.000320396,0.000320396,0.000318038,0.00023227,0.000324742,0.000283851,0.00028768,0.00028701,0.000282352,0.000282352,0.00028359,0.000270692,0.000269896,0.000269153,0.000271512,0.000249442,0.00024887,0.000444968,0.00025497,0.00025497,0.00039419,0.000480232,0.000477003,0.000372131,0.000318097,0.000326155,0.000311311,0.000279703,0.000333477,0.000314035,0.00028222,0.00028148,0.000444966,0.000280028,0.000280028,0.000280028,0.000280374,0.000327697,0.000340843,0.000203491,0.000203254,0.000254655,0.000254353, +1300,2.69188e-05,0.486859,0.00211069,0.0011833,0.000526277,0.000386572,0.000523075,0.000463473,0.000385811,0.000385091,0.000458061,0.000538139,0.000365952,0.000365952,0.00036326,0.000265226,0.000370846,0.000324377,0.000329114,0.000328348,0.000322966,0.000322966,0.000324415,0.00030928,0.000308371,0.000307522,0.000310322,0.000285059,0.000284405,0.000508275,0.000291623,0.000291623,0.000450095,0.000548362,0.000544676,0.000425799,0.000363213,0.00037246,0.000355685,0.000319618,0.000380855,0.000358581,0.000322958,0.000322112,0.000508273,0.00031999,0.00031999,0.00031999,0.000320385,0.00037422,0.000389307,0.000232565,0.000232294,0.000291263,0.000290918, +1400,2.82421e-05,0.518527,0.00238645,0.0013381,0.000595031,0.000437121,0.000591411,0.000525214,0.000436261,0.000435446,0.000517884,0.000608441,0.000413849,0.000413849,0.000410806,0.000299878,0.000419324,0.000366981,0.000372671,0.000371804,0.000365661,0.000365661,0.000367332,0.000349848,0.000348821,0.000347861,0.000351122,0.000322502,0.000321764,0.000574834,0.000330154,0.000330154,0.00050888,0.000620001,0.000615834,0.000482215,0.000410654,0.000421148,0.000402336,0.000361582,0.000430671,0.000405421,0.000365783,0.000364825,0.000574832,0.000362001,0.000362001,0.000362001,0.000362448,0.000423138,0.000440263,0.00026313,0.000262824,0.000329747,0.000329356, +1500,2.95314e-05,0.55006,0.00267538,0.00150027,0.000667068,0.000490081,0.00066301,0.000589883,0.000489117,0.000488204,0.000580565,0.000682099,0.000464029,0.000464029,0.000460618,0.000336184,0.000470114,0.000411611,0.000418293,0.000417322,0.000410381,0.000410381,0.000412285,0.000392346,0.000391195,0.000390119,0.00039386,0.000361726,0.000360898,0.000644564,0.000370512,0.000370512,0.000570472,0.00069506,0.00069039,0.000541308,0.000460361,0.000472159,0.000451207,0.00040554,0.000482863,0.000454498,0.000410638,0.000409565,0.000644562,0.000406011,0.000406011,0.000406011,0.000406511,0.000474389,0.000493648,0.000295148,0.000294805,0.000370056,0.000369619, +1600,3.07899e-05,0.581426,0.00297716,0.00166965,0.00074231,0.000545396,0.000737796,0.00065741,0.000544324,0.000543308,0.000646037,0.000759036,0.000516439,0.000516439,0.000512643,0.000374105,0.000523164,0.000458218,0.000465933,0.000464852,0.000457079,0.000457079,0.000459226,0.00043673,0.000435449,0.000434251,0.000438492,0.000402688,0.000401766,0.000717391,0.000412656,0.000412656,0.000634806,0.00077346,0.000768263,0.000603012,0.00051228,0.000525439,0.000502246,0.000451448,0.000537374,0.000505759,0.000457477,0.000456282,0.000717389,0.000451972,0.000451972,0.000451972,0.000452529,0.000527921,0.000549404,0.000328584,0.000328202,0.000412148,0.000411662, +1700,3.20202e-05,0.612593,0.00329152,0.00184609,0.000820688,0.000603014,0.000815697,0.00072773,0.000601829,0.000600706,0.000714237,0.000839178,0.000571029,0.000571029,0.000566833,0.000413607,0.000578423,0.000506761,0.000515546,0.00051435,0.00050571,0.00050571,0.000508111,0.000482958,0.000481541,0.000480218,0.000484975,0.000445351,0.000444332,0.000793247,0.000456546,0.000456546,0.000701821,0.000855126,0.000849382,0.00066727,0.000566362,0.000580938,0.000555406,0.000499262,0.000594155,0.000559156,0.000506254,0.000504932,0.000793244,0.000499841,0.000499841,0.000499841,0.000500457,0.000583682,0.00060748,0.000363409,0.000362986,0.000455984,0.000455446, +1800,3.32245e-05,0.643534,0.00361819,0.00202943,0.000902137,0.000662889,0.000896651,0.000800786,0.000661585,0.000660351,0.00078511,0.000922461,0.000627756,0.000627756,0.000623143,0.000454656,0.000635846,0.0005572,0.000567091,0.000565776,0.000556236,0.000556236,0.0005589,0.000530992,0.000529435,0.00052798,0.000533273,0.000489679,0.000488559,0.000872071,0.000502145,0.000502145,0.000771463,0.000939992,0.000933678,0.00073403,0.000622564,0.000638611,0.000610643,0.000548944,0.000653159,0.000614646,0.00055693,0.000555477,0.000872068,0.00054958,0.00054958,0.00054958,0.000550257,0.000641626,0.000667829,0.000399592,0.000399128,0.000501528,0.000500936, +1900,3.4405e-05,0.674221,0.00395694,0.00221954,0.000986596,0.000724975,0.000980596,0.000876526,0.00072355,0.0007222,0.000858602,0.00100882,0.000686577,0.000686577,0.000681533,0.000497222,0.00069539,0.000609498,0.000620531,0.000619093,0.000608621,0.000608621,0.000611556,0.000580798,0.000579096,0.000577504,0.000583351,0.000535642,0.000534417,0.000953804,0.000549421,0.000549421,0.000843678,0.001028,0.00102109,0.000803244,0.000680843,0.000698414,0.000667919,0.000600458,0.000714343,0.000672187,0.000609469,0.000607879,0.000953801,0.000601153,0.000601153,0.000601153,0.000601894,0.000701712,0.000730407,0.000437109,0.000436601,0.000548746,0.000548099, +2000,3.55633e-05,0.704631,0.00430754,0.0024163,0.00107401,0.000789232,0.00106748,0.000954902,0.00078768,0.000786211,0.000934666,0.0010982,0.000747455,0.000747455,0.000741964,0.000541278,0.000757017,0.000663622,0.000675833,0.000674267,0.00066283,0.00066283,0.000666047,0.000632344,0.000630491,0.000628758,0.000635175,0.000583209,0.000581875,0.00103839,0.000598345,0.000598345,0.000918421,0.00111908,0.00111156,0.00087487,0.000741162,0.000760308,0.000727194,0.00065377,0.000777665,0.00073174,0.000663838,0.000662107,0.00103839,0.000654527,0.000654527,0.000654527,0.000655333,0.000763898,0.000795171,0.000475935,0.000475382,0.00059761,0.000596906, +2100,3.67009e-05,0.734744,0.00466978,0.00261959,0.00116432,0.000855622,0.00115724,0.00103587,0.00085394,0.000852347,0.00101325,0.00119055,0.000810354,0.000810354,0.000804401,0.000586797,0.00082069,0.000719541,0.000732966,0.000731268,0.000718835,0.000718835,0.000722342,0.0006856,0.000683591,0.000681713,0.000688718,0.000632353,0.000630908,0.00112579,0.000648889,0.000648889,0.000995644,0.00121318,0.00120503,0.000948867,0.000803482,0.000824258,0.000788437,0.000708851,0.000843089,0.000793271,0.000720007,0.000718131,0.00112579,0.000709671,0.000709671,0.000709671,0.000710545,0.000828149,0.000862086,0.000516049,0.000515449,0.000648092,0.000647328, +2200,3.78192e-05,0.764541,0.00504348,0.00282931,0.00125749,0.000924109,0.00124985,0.0011194,0.000922293,0.000920572,0.00109433,0.00128582,0.000875239,0.000875239,0.00086881,0.000633755,0.000886374,0.000777225,0.000791901,0.000790067,0.000776606,0.000776606,0.000780413,0.000740538,0.000738368,0.00073634,0.000743951,0.00068305,0.000681488,0.00121595,0.000701028,0.000701028,0.00107531,0.00131026,0.00130146,0.0010252,0.000867772,0.000890227,0.000851613,0.00076567,0.00091058,0.000856745,0.000777948,0.000775922,0.00121595,0.000766557,0.000766557,0.000766557,0.000767501,0.00089443,0.000931114,0.000557429,0.000556781,0.000700167,0.000699342, +2300,3.89193e-05,0.794007,0.00542844,0.00304534,0.00135347,0.000994659,0.00134524,0.00120544,0.000992705,0.000990853,0.00117784,0.00138395,0.000942081,0.000942081,0.000935161,0.000682128,0.000954037,0.000836648,0.000852612,0.000850638,0.000836117,0.000836117,0.000840233,0.000797133,0.000794797,0.000792614,0.000800847,0.000735274,0.000733593,0.00130883,0.000754736,0.000754736,0.00115737,0.00141026,0.00140079,0.00110383,0.000933998,0.000958184,0.000916694,0.000824203,0.000980105,0.000922132,0.000837636,0.000835455,0.00130882,0.000825157,0.000825157,0.000825157,0.000826173,0.000962708,0.00100222,0.000600056,0.000599359,0.00075381,0.000752922, +2400,4.00024e-05,0.823127,0.00582449,0.00326761,0.00145221,0.00106724,0.00144338,0.00129397,0.00106514,0.00106316,0.00126376,0.00148492,0.00101085,0.00101085,0.00100342,0.000731895,0.00102365,0.000897785,0.000915074,0.000912956,0.000897344,0.000897344,0.000901779,0.000855358,0.000852852,0.00085051,0.000859384,0.000789004,0.000787201,0.00140438,0.000809994,0.000809994,0.0012418,0.00151314,0.00150298,0.00118473,0.00100213,0.0010281,0.000983652,0.000884423,0.00105163,0.000989402,0.000899047,0.000896707,0.00140438,0.000885447,0.000885447,0.000885447,0.000886537,0.00103295,0.00107538,0.000643911,0.000643164,0.000809,0.000808047, diff --git a/test_problems/cxx_ex/tr2_blessed.csv b/test_problems/cxx_ex/tr2_blessed.csv new file mode 100644 index 000000000..303279663 --- /dev/null +++ b/test_problems/cxx_ex/tr2_blessed.csv @@ -0,0 +1,22 @@ +transport example 2: multicomponent transport properties, +Temperature (K),Viscosity (),Thermal Conductivity (W/m-K),H2,H,O,O2,OH,H2O,HO2,H2O2,C,CH,CH2,CH2(S),CH3,CH4,CO,CO2,HCO,CH2O,CH2OH,CH3O,CH3OH,C2H,C2H2,C2H3,C2H4,C2H5,C2H6,HCCO,CH2CO,HCCOH,N,NH,NH2,NH3,NNH,NO,NO2,N2O,HNO,CN,HCN,H2CN,HCNN,HCNO,HOCN,HNCO,NCO,N2,AR,C3H7,C3H8,CH2CHO,CH3CHO, +500,1.98056e-05,0.07687,-5.33027e-07,-7.8082e-10,-3.50978e-13,9.38259e-13,-1.4448e-10,-1.78489e-08,1.26597e-15,3.37197e-15,-1.0344e-22,-3.1922e-22,-9.15646e-21,-3.56147e-22,-1.51857e-18,-1.80541e-17,1.09292e-07,1.05538e-07,1.78123e-14,8.86788e-15,1.53119e-19,2.06585e-21,6.47243e-19,-4.52659e-24,4.81244e-21,7.86539e-23,1.0777e-22,6.14337e-23,-6.37326e-23,9.76316e-22,3.19134e-20,1.02059e-22,-3.26831e-16,-1.5677e-15,-1.11946e-14,7.53722e-14,1.20744e-15,1.11116e-11,6.00297e-17,6.0286e-16,2.23163e-15,1.55642e-18,9.23862e-15,1.60665e-20,-1.83063e-23,2.79987e-21,9.71852e-17,6.15798e-14,4.51865e-17,3.36959e-07,-3.56766e-24,3.07839e-23,1.63445e-23,1.36909e-23,-3.53149e-23, +600,2.35286e-05,0.0913361,-6.6322e-07,-1.05508e-09,-4.90104e-13,1.20968e-12,-2.08101e-10,-5.02538e-08,1.62453e-15,4.34495e-15,-7.53448e-23,-6.81606e-22,-1.73169e-20,-7.27893e-22,-3.60996e-18,-5.9211e-17,1.3785e-07,1.52447e-07,2.84349e-14,1.42433e-14,2.62919e-19,3.49885e-21,1.03936e-18,-6.17971e-24,6.23391e-21,-1.02152e-23,-1.05487e-22,-5.14686e-23,-1.30546e-22,1.22876e-21,5.09193e-20,-3.0445e-23,-4.50233e-16,-2.15844e-15,-1.75636e-14,-9.90534e-14,1.50364e-15,1.41526e-11,8.34319e-17,8.54822e-16,2.86028e-15,1.91445e-18,1.53905e-14,2.69348e-20,-3.02148e-23,3.9476e-21,1.37595e-16,8.71838e-14,6.38986e-17,4.24424e-07,-1.03362e-22,-8.18642e-23,-5.86701e-23,1.06592e-22,-2.84165e-23, +700,2.71418e-05,0.105981,-7.82768e-07,-1.32026e-09,-6.14454e-13,1.48902e-12,-2.64095e-10,-1.00926e-07,1.98752e-15,5.32989e-15,-2.78247e-22,-7.48769e-22,-2.50098e-20,-1.17496e-21,-5.61305e-18,-9.85937e-17,1.67502e-07,2.02395e-07,4.0335e-14,2.02955e-14,3.85151e-19,5.1566e-21,1.47905e-18,3.10137e-23,7.79079e-21,9.28703e-23,-1.05231e-22,6.90103e-24,1.66604e-24,1.57532e-21,7.25188e-20,-3.84757e-23,-5.60722e-16,-2.69216e-15,-2.35727e-14,-3.27883e-13,1.80313e-15,1.72862e-11,1.07596e-16,1.11783e-15,3.49961e-15,2.28284e-18,2.24092e-14,3.95457e-20,5.65641e-23,5.00405e-21,1.7976e-16,1.13902e-13,8.34308e-17,5.15364e-07,-2.21754e-23,-1.17637e-22,-5.26044e-23,7.40866e-23,6.96413e-23, +800,3.0644e-05,0.120968,-8.92989e-07,-1.57332e-09,-7.2449e-13,1.77165e-12,-3.12771e-10,-1.6514e-07,2.34977e-15,6.31197e-15,-1.15464e-22,-8.09926e-22,-3.21451e-20,-1.52833e-21,-7.4525e-18,-1.34459e-16,1.97794e-07,2.53841e-07,5.30371e-14,2.67776e-14,5.15682e-19,6.90309e-21,1.94842e-18,3.64222e-23,9.50557e-21,-1.55665e-22,8.7511e-24,-8.74328e-23,4.08936e-23,1.92329e-21,9.55029e-20,-8.32307e-23,-6.58902e-16,-3.17011e-15,-2.91036e-14,-5.89908e-13,2.10187e-15,2.04626e-11,1.3194e-16,1.38472e-15,4.14075e-15,2.65628e-18,2.99942e-14,5.30678e-20,2.8192e-23,6.44466e-21,2.22543e-16,1.41012e-13,1.03258e-16,6.08358e-07,1.21474e-22,1.38467e-22,1.06549e-22,1.43836e-23,5.02413e-23, +900,3.40391e-05,0.136207,-9.95275e-07,-1.8135e-09,-8.21942e-13,2.05407e-12,-3.55085e-10,-2.3885e-07,2.70761e-15,7.28132e-15,-3.03734e-22,-9.02915e-22,-3.88031e-20,-1.86523e-21,-9.10695e-18,-1.66286e-16,2.2833e-07,3.05775e-07,6.62129e-14,3.35165e-14,6.5092e-19,8.62773e-21,2.43467e-18,4.00871e-23,1.10095e-20,-2.07061e-22,1.89495e-22,-1.40198e-22,-9.6052e-23,2.28034e-21,1.19305e-19,6.37458e-23,-7.4636e-16,-3.59859e-15,-3.41481e-14,-8.69846e-13,2.3968e-15,2.36422e-11,1.56099e-16,1.65099e-15,4.77717e-15,3.02972e-18,3.79348e-14,6.72104e-20,-6.77221e-23,7.4953e-21,2.6523e-16,1.68064e-13,1.2305e-16,7.02165e-07,-5.55244e-23,8.15057e-23,3.13589e-24,-5.98458e-23,2.16082e-22, +1000,3.73332e-05,0.151267,-1.09089e-06,-2.04114e-09,-9.08824e-13,2.33376e-12,-3.92124e-10,-3.18835e-07,3.05848e-15,8.23169e-15,-3.42971e-22,-1.13212e-21,-4.50974e-20,-2.04172e-21,-1.05796e-17,-1.94149e-16,2.58794e-07,3.57537e-07,7.96355e-14,4.03919e-14,7.88898e-19,1.05254e-20,2.92925e-18,5.49389e-23,1.28169e-20,-4.91006e-23,1.56107e-23,9.12473e-23,-7.00299e-25,2.70289e-21,1.42979e-19,-9.57164e-23,-8.2487e-16,-3.98513e-15,-3.8745e-14,-1.15706e-12,2.68575e-15,2.67954e-11,1.79853e-16,1.91388e-15,5.40422e-15,3.4e-18,4.60829e-14,8.15757e-20,2.36009e-24,8.5681e-21,3.07381e-16,1.94776e-13,1.42601e-16,7.95798e-07,-8.18382e-23,4.20758e-23,-4.5491e-23,-5.513e-23,8.36359e-23, +1100,4.05327e-05,0.166854,-1.18089e-06,-2.25704e-09,-9.87054e-13,2.60899e-12,-4.24893e-10,-4.02616e-07,3.40133e-15,9.1594e-15,-3.10883e-22,-1.30087e-21,-5.05711e-20,-2.29779e-21,-1.18872e-17,-2.18384e-16,2.88944e-07,4.08706e-07,9.31476e-14,4.73197e-14,9.28301e-19,1.23253e-20,3.42594e-18,-2.19958e-23,1.44195e-20,2.01204e-22,1.03781e-22,9.10917e-23,-4.42891e-23,2.89407e-21,1.66865e-19,7.32682e-23,-8.96096e-16,-4.33696e-15,-4.29496e-14,-1.44428e-12,2.96761e-15,2.99012e-11,2.03085e-16,2.17174e-15,6.01885e-15,3.76398e-18,5.43342e-14,9.64238e-20,2.41737e-22,9.93507e-21,3.48732e-16,2.20982e-13,1.6179e-16,8.8851e-07,-2.48592e-22,-7.21669e-25,-7.50122e-24,1.72786e-22,-2.49799e-23, +1200,4.36437e-05,0.18247,-1.26618e-06,-2.4622e-09,-1.05832e-12,2.87859e-12,-4.54282e-10,-4.88315e-07,3.73518e-15,1.00624e-14,-4.07335e-23,-1.12281e-21,-5.54927e-20,-2.74966e-21,-1.30489e-17,-2.39435e-16,3.18608e-07,4.59014e-07,1.0664e-13,5.42416e-14,1.06788e-18,1.42181e-20,3.92102e-18,-2.32594e-22,1.61402e-20,-1.72091e-22,-3.23317e-23,-1.10324e-22,-2.48087e-23,3.1415e-21,1.9057e-19,-1.73548e-22,-9.61485e-16,-4.66051e-15,-4.682e-14,-1.72666e-12,3.24145e-15,3.2945e-11,2.25721e-16,2.42362e-15,6.61928e-15,4.11948e-18,6.26155e-14,1.11167e-19,5.962e-23,1.09385e-20,3.89131e-16,2.46585e-13,1.80544e-16,9.79755e-07,-1.01249e-22,-5.44604e-23,-5.08637e-25,-6.33291e-23,-6.14223e-23, +1300,4.6672e-05,0.198086,-1.34747e-06,-2.65764e-09,-1.12405e-12,3.14178e-12,-4.81045e-10,-5.7453e-07,4.05962e-15,1.09396e-14,-1.53224e-22,-1.43887e-21,-5.9868e-20,-3.14963e-21,-1.4086e-17,-2.57761e-16,3.4766e-07,5.08298e-07,1.20038e-13,6.11168e-14,1.20711e-18,1.60684e-20,4.41183e-18,-2.55029e-23,1.73345e-20,-4.971e-23,1.62736e-22,-3.246e-22,-1.25416e-22,3.73039e-21,2.13868e-19,5.33253e-23,-1.02226e-15,-4.96127e-15,-5.04108e-14,-2.00103e-12,3.50683e-15,3.5917e-11,2.47731e-16,2.66903e-15,7.20441e-15,4.46581e-18,7.08747e-14,1.2572e-19,-5.46216e-23,1.20696e-20,4.285e-16,2.71536e-13,1.98825e-16,1.06914e-06,-1.07041e-22,-7.32825e-23,3.28712e-23,1.86189e-22,7.86632e-23, +1400,4.96231e-05,0.213676,-1.42534e-06,-2.84432e-09,-1.18544e-12,3.39811e-12,-5.05804e-10,-6.60224e-07,4.37454e-15,1.17908e-14,-2.16378e-22,-1.32409e-21,-6.44283e-20,-3.43114e-21,-1.50177e-17,-2.73803e-16,3.76015e-07,5.56462e-07,1.33289e-13,6.79175e-14,1.34547e-18,1.78841e-20,4.89624e-18,-7.71696e-23,1.90125e-20,-1.72056e-22,-1.20035e-22,-1.02342e-22,2.92026e-22,3.8586e-21,2.36673e-19,1.2967e-22,-1.07941e-15,-5.24382e-15,-5.37708e-14,-2.26543e-12,3.76358e-15,3.88109e-11,2.69109e-16,2.90777e-15,7.77365e-15,4.80224e-18,7.90751e-14,1.40424e-19,1.17532e-22,1.30231e-20,4.66809e-16,2.95815e-13,2.16618e-16,1.1564e-06,-2.10027e-22,-3.27508e-23,2.56784e-22,-8.12992e-23,-1.18057e-22, +1500,5.25017e-05,0.229211,-1.50028e-06,-3.02316e-09,-1.24346e-12,3.64732e-12,-5.29065e-10,-7.44643e-07,4.67999e-15,1.26163e-14,-1.65038e-22,-1.64429e-21,-6.77662e-20,-3.54723e-21,-1.58622e-17,-2.87962e-16,4.03618e-07,6.03461e-07,1.46358e-13,7.46246e-14,1.4822e-18,1.97195e-20,5.37244e-18,1.92544e-22,2.08143e-20,4.71972e-23,1.65494e-22,-1.30394e-22,-1.35006e-23,4.34607e-21,2.59355e-19,1.09453e-22,-1.13377e-15,-5.51192e-15,-5.69421e-14,-2.51872e-12,4.01174e-15,4.16233e-11,2.89861e-16,3.13986e-15,8.32683e-15,5.12828e-18,8.7191e-14,1.54698e-19,-1.76085e-22,1.44754e-20,5.04055e-16,3.1942e-13,2.33922e-16,1.24135e-06,-4.73049e-23,2.32795e-23,4.61374e-24,-9.38698e-23,1.28782e-22, +1600,5.53124e-05,0.244663,-1.57267e-06,-3.19498e-09,-1.29889e-12,3.88932e-12,-5.51233e-10,-8.27245e-07,4.97613e-15,1.34166e-14,-9.83031e-23,-1.74514e-21,-7.11506e-20,-3.65047e-21,-1.66347e-17,-3.00593e-16,4.30437e-07,6.49281e-07,1.59222e-13,8.12256e-14,1.61779e-18,2.13698e-20,5.84058e-18,-5.3929e-23,2.22608e-20,-2.79122e-22,-3.25657e-22,-7.81147e-23,7.17816e-23,4.72652e-21,2.81215e-19,2.83012e-22,-1.18597e-15,-5.76865e-15,-5.99602e-14,-2.76034e-12,4.25142e-15,4.43526e-11,3.10006e-16,3.36541e-15,8.86402e-15,5.44316e-18,9.52047e-14,1.69261e-19,2.76693e-22,1.52758e-20,5.40257e-16,3.42363e-13,2.50745e-16,1.3239e-06,-2.94598e-22,1.5619e-23,7.73143e-23,-2.41668e-22,1.6071e-22, +1700,5.8059e-05,0.260005,-1.64284e-06,-3.36049e-09,-1.35236e-12,4.12413e-12,-5.72631e-10,-9.07655e-07,5.26324e-15,1.41925e-14,-7.57991e-22,-1.35934e-21,-7.46575e-20,-3.8389e-21,-1.73499e-17,-3.12007e-16,4.56455e-07,6.93928e-07,1.71866e-13,8.77128e-14,1.75204e-18,2.33103e-20,6.29979e-18,1.56134e-22,2.3638e-20,1.30284e-22,-6.01519e-23,-7.75369e-23,-3.23044e-22,4.43756e-21,3.02845e-19,2.82522e-22,-1.23656e-15,-6.01648e-15,-6.2855e-14,-2.99016e-12,4.48288e-15,4.69986e-11,3.29566e-16,3.58462e-15,9.38546e-15,5.74783e-18,1.03104e-13,1.83094e-19,5.15099e-23,1.63444e-20,5.75444e-16,3.64662e-13,2.67099e-16,1.404e-06,3.01593e-23,-5.98474e-23,-5.39333e-24,-1.17116e-22,2.38202e-22, +1800,6.07452e-05,0.275211,-1.71104e-06,-3.52035e-09,-1.40438e-12,4.35186e-12,-5.93513e-10,-9.85619e-07,5.5416e-15,1.49448e-14,-3.20064e-22,-2.12078e-21,-7.819e-20,-3.76194e-21,-1.80194e-17,-3.2247e-16,4.8167e-07,7.37424e-07,1.84281e-13,9.40815e-14,1.88406e-18,2.51944e-20,6.74988e-18,-1.58717e-22,2.53121e-20,-1.15461e-22,-2.1808e-23,-1.64003e-22,5.24761e-22,4.59237e-21,3.23556e-19,9.17491e-23,-1.28592e-15,-6.25741e-15,-6.56511e-14,-3.20831e-12,4.70641e-15,4.95623e-11,3.48566e-16,3.79772e-15,9.89153e-15,6.0413e-18,1.10882e-13,1.96625e-19,-5.37348e-23,1.71898e-20,6.09653e-16,3.86343e-13,2.83002e-16,1.48163e-06,5.79365e-23,3.83343e-22,-2.69282e-22,2.21794e-22,2.32889e-22, +1900,6.33742e-05,0.290257,-1.77748e-06,-3.67513e-09,-1.45535e-12,4.57266e-12,-6.14079e-10,-1.06098e-06,5.81156e-15,1.56744e-14,-4.97789e-22,-1.51362e-21,-8.08752e-20,-4.05508e-21,-1.86538e-17,-3.32211e-16,5.06091e-07,7.79798e-07,1.96465e-13,1.0033e-13,2.01473e-18,2.66805e-20,7.19129e-18,1.74588e-22,2.66349e-20,1.43051e-22,4.20064e-22,-1.2705e-22,-4.87791e-22,5.16695e-21,3.44218e-19,-5.42045e-23,-1.33439e-15,-6.49304e-15,-6.83686e-14,-3.41512e-12,4.92234e-15,5.20453e-11,3.67032e-16,4.00497e-15,1.03827e-14,6.32541e-18,1.18533e-13,2.10878e-19,-4.73457e-23,1.80698e-20,6.42926e-16,4.0743e-13,2.98473e-16,1.55681e-06,-9.65808e-23,2.87469e-22,2.30011e-23,-2.44505e-23,-2.30239e-22, +2000,6.59491e-05,0.305123,-1.84235e-06,-3.82533e-09,-1.50557e-12,4.78674e-12,-6.34478e-10,-1.13366e-06,6.07346e-15,1.63823e-14,-1.69661e-22,-1.52662e-21,-8.3792e-20,-4.07118e-21,-1.92614e-17,-3.41423e-16,5.29732e-07,8.21087e-07,2.08415e-13,1.06457e-13,2.14281e-18,2.85625e-20,7.62337e-18,1.37527e-22,2.73581e-20,-3.0509e-22,3.12772e-22,7.44479e-23,2.86178e-22,5.86294e-21,3.64656e-19,-2.31904e-22,-1.38221e-15,-6.72461e-15,-7.1024e-14,-3.61105e-12,5.13104e-15,5.44499e-11,3.8499e-16,4.20664e-15,1.08594e-14,6.59852e-18,1.26055e-13,2.2393e-19,1.14684e-22,1.93177e-20,6.75306e-16,4.2795e-13,3.13529e-16,1.6296e-06,-3.4512e-22,2.04966e-22,1.67769e-23,4.47973e-23,-2.09694e-22, +2100,6.84727e-05,0.31979,-1.9058e-06,-3.9714e-09,-1.55528e-12,4.99432e-12,-6.54824e-10,-1.20362e-06,6.32766e-15,1.70696e-14,-2.83818e-22,-1.15835e-21,-8.64317e-20,-4.26804e-21,-1.98499e-17,-3.50269e-16,5.52613e-07,8.61329e-07,2.20134e-13,1.12464e-13,2.26928e-18,3.0015e-20,8.04594e-18,1.34892e-22,2.90703e-20,8.73816e-23,-4.89995e-23,-1.47702e-22,-8.44545e-23,5.47954e-21,3.84032e-19,-3.18455e-22,-1.42956e-15,-6.9531e-15,-7.36302e-14,-3.79664e-12,5.3329e-15,5.67786e-11,4.02465e-16,4.40299e-15,1.13223e-14,6.86343e-18,1.33446e-13,2.3691e-19,-9.15641e-23,1.99965e-20,7.06833e-16,4.4793e-13,3.28191e-16,1.70005e-06,-4.40514e-22,2.23463e-22,-7.8415e-23,4.70901e-23,-3.29228e-22, +2200,7.09473e-05,0.334244,-1.96795e-06,-4.11372e-09,-1.60467e-12,5.19565e-12,-6.75198e-10,-1.27087e-06,6.57451e-15,1.77372e-14,-2.1582e-22,-2.02339e-21,-8.95431e-20,-4.43156e-21,-2.0425e-17,-3.58887e-16,5.74759e-07,9.00565e-07,2.31625e-13,1.18353e-13,2.39399e-18,3.22187e-20,8.46046e-18,9.36183e-23,3.05117e-20,-4.41794e-22,2.30728e-23,-5.23158e-22,4.62102e-22,6.1905e-21,4.02573e-19,-1.64631e-23,-1.47657e-15,-7.17925e-15,-7.61976e-14,-3.97248e-12,5.52832e-15,5.90345e-11,4.19484e-16,4.5943e-15,1.17719e-14,7.11871e-18,1.40709e-13,2.4973e-19,-3.76384e-22,2.11793e-20,7.3755e-16,4.67397e-13,3.42477e-16,1.76823e-06,-3.61181e-22,-2.39175e-22,-5.35107e-22,3.43767e-22,9.88597e-24, +2300,7.33753e-05,0.348473,-2.02891e-06,-4.25265e-09,-1.65384e-12,5.39098e-12,-6.95657e-10,-1.33547e-06,6.81437e-15,1.83861e-14,-7.62609e-22,-2.07138e-21,-9.22317e-20,-4.28584e-21,-2.09919e-17,-3.6739e-16,5.96197e-07,9.38834e-07,2.42891e-13,1.24125e-13,2.51668e-18,3.30938e-20,8.86627e-18,1.6014e-22,3.18897e-20,-7.30802e-23,4.69082e-22,2.38072e-22,3.03489e-23,6.65659e-21,4.21864e-19,-6.68676e-24,-1.52334e-15,-7.40363e-15,-7.87343e-14,-4.13919e-12,5.7177e-15,6.12205e-11,4.3607e-16,4.7808e-15,1.22087e-14,7.36542e-18,1.47842e-13,2.62247e-19,1.4635e-22,2.14775e-20,7.67495e-16,4.86375e-13,3.56406e-16,1.83424e-06,1.46239e-22,9.49141e-24,-2.1144e-22,2.20668e-22,3.15872e-22, +2400,7.57589e-05,0.362469,-2.08878e-06,-4.38848e-09,-1.70291e-12,5.58059e-12,-7.16235e-10,-1.39748e-06,7.04759e-15,1.90172e-14,-5.9334e-22,-1.95228e-21,-9.46564e-20,-4.25217e-21,-2.15563e-17,-3.75872e-16,6.16956e-07,9.76177e-07,2.53937e-13,1.29784e-13,2.63743e-18,3.47156e-20,9.26276e-18,6.44891e-23,3.32708e-20,-5.17476e-22,-1.47786e-22,-1.18318e-22,-1.36222e-22,6.48502e-21,4.39483e-19,1.21582e-22,-1.56991e-15,-7.62662e-15,-8.12461e-14,-4.29738e-12,5.90146e-15,6.33399e-11,4.52244e-16,4.96274e-15,1.26333e-14,7.60425e-18,1.54849e-13,2.74831e-19,2.76199e-23,2.22422e-20,7.96709e-16,5.04889e-13,3.69994e-16,1.89816e-06,2.95712e-22,1.67048e-22,-1.71146e-22,-3.99122e-23,4.01209e-22, diff --git a/test_problems/silane_equil/.cvsignore b/test_problems/silane_equil/.cvsignore new file mode 100644 index 000000000..07ef4aa00 --- /dev/null +++ b/test_problems/silane_equil/.cvsignore @@ -0,0 +1,4 @@ +Makefile +diff_test.out +output.txt +silane_equil diff --git a/test_problems/silane_equil/Makefile.in b/test_problems/silane_equil/Makefile.in new file mode 100644 index 000000000..09a7f8c1a --- /dev/null +++ b/test_problems/silane_equil/Makefile.in @@ -0,0 +1,82 @@ +#!/bin/sh + +############################################################################ +# +# Makefile to compile and link a C++ application to +# Cantera. +# +############################################################################# + +# the name of the executable program to be created +PROG_NAME = silane_equil + +# the object files to be linked together. List those generated from Fortran +# and from C/C++ separately +OBJS = silane_equil.o + +# additional flags to be passed to the linker. If your program +# requires other external libraries, put them here +LINK_OPTIONS = + +############################################################################# + +# Fortran libraries +FORT_LIBS = @FLIBS@ + +# the C++ compiler +CXX = @CXX@ + +# C++ compile flags +CXX_FLAGS = @CXXFLAGS@ + +# external libraries +EXT_LIBS = @LOCAL_LIBS@ + +# Ending C++ linking libraries +LCXX_END_LIBS = @LCXX_END_LIBS@ + +# the directory where the Cantera libraries are located +CANTERA_LIBDIR=@ctroot@/lib + +# required Cantera libraries +CANTERA_LIBS = -lcantera + +# the directory where Cantera include files may be found. +CANTERA_INCDIR=@ctroot@/include + +# flags passed to the C++ compiler/linker for the linking step +LCXX_FLAGS = -L$(CANTERA_LIBDIR) @CXXFLAGS@ + +# how to compile C++ source files to object files +.@CXX_EXT@.@OBJ_EXT@: + $(CXX) -c $< -I$(CANTERA_INCDIR) $(CXX_FLAGS) + +PROGRAM = $(PROG_NAME)$(EXE_EXT) + +all: $(PROGRAM) + +$(PROGRAM): $(OBJS) $(CANTERA_LIBDIR)/libcantera.a + $(CXX) -o $(PROGRAM) $(OBJS) $(LCXX_FLAGS) $(CANTERA_LIBS) \ + $(LINK_OPTIONS) $(EXT_LIBS) @LIBS@ $(FORT_LIBS) \ + $(LCXX_END_LIBS) + +test: + @MAKE@ $(PROGRAM) + ./runtest +clean: + $(RM) $(OBJS) $(PROGRAM) + ../../bin/rm_cvsignore + + + + + + + + + + + + + + diff --git a/test_problems/silane_equil/output_blessed.txt b/test_problems/silane_equil/output_blessed.txt new file mode 100644 index 000000000..e62b7cdea --- /dev/null +++ b/test_problems/silane_equil/output_blessed.txt @@ -0,0 +1,32 @@ + + temperature 2000 K + pressure 100 Pa + density 1.33178e-05 kg/m^3 + mean mol. weight 2.21449 amu + + 1 kg 1 kmol + ----------- ------------ + enthalpy 3.03214e+07 6.715e+07 J + internal energy 2.28127e+07 5.052e+07 J + entropy 111330 2.465e+05 J/K + Gibbs function -1.92339e+08 -4.259e+08 J + heat capacity c_p 15110 3.346e+04 J/K + heat capacity c_v 11355.7 2.515e+04 J/K + + X Y + ------------- ------------ + H2 9.402287e-01 8.559021e-01 + H 5.023175e-02 2.286330e-02 + HE 0.000000e+00 0.000000e+00 + SIH4 1.904176e-10 2.761668e-09 + SI 9.493714e-03 1.204049e-01 + SIH 2.610042e-05 3.429007e-04 + SIH2 2.437203e-06 3.312867e-05 + SIH3 5.801418e-09 8.149868e-08 + H3SISIH 3.881514e-15 1.055221e-13 + SI2H6 9.861394e-20 2.770670e-18 + H2SISIH2 4.058658e-14 1.103379e-12 + SI3H8 1.244730e-28 5.189160e-27 + SI2 1.619905e-05 4.108919e-04 + SI3 1.121605e-06 4.267458e-05 + diff --git a/test_problems/silane_equil/runtest b/test_problems/silane_equil/runtest new file mode 100755 index 000000000..30c55e4e1 --- /dev/null +++ b/test_problems/silane_equil/runtest @@ -0,0 +1,32 @@ +#!/bin/sh +# +# + +temp_success="1" +/bin/rm -f eq1.csv tr1.csv tr2.csv kin1.csv kin2.csv + +################################################################# +# +################################################################# + +CANTERA_BIN=${CANTERA_BIN:=../../bin} +silane_equil > output.txt +retnStat=$? +if [ $retnStat != "0" ] +then + temp_success="0" + echo "silane_equil returned with bad status, $retnStat, check output" +fi + + +diff output.txt output_blessed.txt > diff_test.out +retnStat=$? +if [ $retnStat = "0" ] +then + echo "successful diff comparison on silane_equil test" +else + echo "unsuccessful diff comparison on silane_equil test" + echo "FAILED" > csvCode.txt + temp_success="0" +fi + diff --git a/test_problems/silane_equil/silane.xml b/test_problems/silane_equil/silane.xml new file mode 100644 index 000000000..a64f8192a --- /dev/null +++ b/test_problems/silane_equil/silane.xml @@ -0,0 +1,480 @@ + + + + + + + 300 + 1 + H2:1.0 + + + Si H He + + H2 H HE SIH4 SI SIH SIH2 SIH3 H3SISIH SI2H6 + H2SISIH2 SI3H8 SI2 SI3 + + + + + + + + + + + + + TPIS78 + H:2 + + + + 2.344331120E+00, 7.980520750E-03, -1.947815100E-05, + 2.015720940E-08, -7.376117610E-12, -9.179351730E+02, + 6.830102380E-01 + + + 3.337279200E+00, -4.940247310E-05, 4.994567780E-07, + -1.795663940E-10, 2.002553760E-14, -9.501589220E+02, + -3.205023310E+00 + + + + + + + + L 7/88 + H:1 + + + + 2.500000000E+00, 7.053328190E-13, -1.995919640E-15, + 2.300816320E-18, -9.277323320E-22, 2.547365990E+04, + -4.466828530E-01 + + + 2.500000010E+00, -2.308429730E-11, 1.615619480E-14, + -4.735152350E-18, 4.981973570E-22, 2.547365990E+04, + -4.466829140E-01 + + + + + + + + 120186 + He:1 + + + + 2.500000000E+00, 0.000000000E+00, 0.000000000E+00, + 0.000000000E+00, 0.000000000E+00, -7.453750000E+02, + 9.153488000E-01 + + + 2.500000000E+00, 0.000000000E+00, 0.000000000E+00, + 0.000000000E+00, 0.000000000E+00, -7.453750000E+02, + 9.153489000E-01 + + + + + + + + 90784 + Si:1 H:4 + + + + 1.451640400E+00, 1.398736300E-02, -4.234563900E-06, + -2.360614200E-09, 1.371208900E-12, 3.113410500E+03, + 1.232185500E+01 + + + 7.935938000E-01, 1.767189900E-02, -1.139800900E-05, + 3.599260400E-09, -4.524157100E-13, 3.198212700E+03, + 1.524225700E+01 + + + + + + + + J 3/67 + Si:1 + + + + 3.179353700E+00, -2.764699200E-03, 4.478403800E-06, + -3.283317700E-09, 9.121363100E-13, 5.333903200E+04, + 2.727320400E+00 + + + 2.650601400E+00, -3.576385200E-04, 2.959229300E-07, + -7.280482900E-11, 5.796332900E-15, 5.343705400E+04, + 5.220405700E+00 + + + + + + + + 121986 + Si:1 H:1 + + + + 3.836010000E+00, -2.702657000E-03, 6.849070000E-06, + -5.424184000E-09, 1.472131000E-12, 4.507593000E+04, + 9.350778000E-01 + + + 3.110430000E+00, 1.094946000E-03, 2.898629000E-08, + -2.745104000E-10, 7.051799000E-14, 4.516898000E+04, + 4.193487000E+00 + + + + + + + + 42489 + Si:1 H:2 + + + + 3.475092000E+00, 2.139338000E-03, 7.672306000E-07, + 5.217668000E-10, -9.898824000E-13, 3.147397000E+04, + 4.436585000E+00 + + + 4.142390000E+00, 2.150191000E-03, -2.190730000E-07, + -2.073725000E-10, 4.741018000E-14, 3.110484000E+04, + 2.930745000E-01 + + + + + + + + 42489 + Si:1 H:3 + + + + 2.946733000E+00, 6.466764000E-03, 5.991653000E-07, + -2.218413000E-09, 3.052670000E-13, 2.270173000E+04, + 7.347948000E+00 + + + 5.015906000E+00, 3.732750000E-03, -3.609053000E-07, + -3.729193000E-10, 8.468490000E-14, 2.190233000E+04, + -4.291368000E+00 + + + + + + + + 111191 + H:4 Si:2 + + + + 3.698707000E+00, 1.870180000E-02, -1.430704000E-05, + 6.005836000E-09, -1.116293000E-12, 3.590825000E+04, + 8.825191000E+00 + + + 1.127202000E+01, 2.538145000E-03, -2.998472000E-07, + -9.465367000E-11, 1.855053000E-14, 3.297169000E+04, + -3.264598000E+01 + + + + + + + + 90784 + Si:2 H:6 + + + + 6.734798300E-01, 4.093153100E-02, -4.484125500E-05, + 2.995223200E-08, -8.901085400E-12, 7.932787500E+03, + 1.862740300E+01 + + + 3.407493600E+00, 2.720647900E-02, -1.771320400E-05, + 5.639117700E-09, -7.137868200E-13, 7.532184200E+03, + 6.132175400E+00 + + + + + + + + 42489 + Si:2 H:4 + + + + 5.133186000E+00, 1.252855000E-02, -4.620421000E-07, + -6.606075000E-09, 2.864345000E-12, 2.956915000E+04, + 7.605133000E-01 + + + 8.986817000E+00, 5.405047000E-03, -5.214022000E-07, + -5.313742000E-10, 1.188727000E-13, 2.832748000E+04, + -2.004478000E+01 + + + + + + + + 90784 + Si:3 H:8 + + + + 7.719684600E-01, 6.344274000E-02, -7.672610900E-05, + 5.454371500E-08, -1.661172900E-11, 1.207126300E+04, + 2.153250700E+01 + + + 6.093334100E+00, 3.658011200E-02, -2.389236100E-05, + 7.627193200E-09, -9.676938400E-13, 1.129720500E+04, + -2.747565400E+00 + + + + + + + + 90784 + Si:2 + + + + 2.967197600E+00, 6.311955800E-03, -1.097079000E-05, + 8.927868000E-09, -2.787368900E-12, 6.987073800E+04, + 9.278950300E+00 + + + 4.144677900E+00, 6.523467700E-04, -5.010852000E-07, + 1.806284300E-10, -2.516111100E-14, 6.969470700E+04, + 3.862736600E+00 + + + + + + + + J 3/67 + Si:3 + + + + 4.597912900E+00, 1.071527400E-02, -1.610042200E-05, + 1.096920700E-08, -2.783287500E-12, 7.476632400E+04, + 3.442167100E+00 + + + 7.421336000E+00, -1.170994800E-04, 8.982077500E-08, + 7.193596400E-12, -2.567083700E-15, 7.414669900E+04, + -1.036527400E+01 + + + + + + + + + + + + SIH4 + H [=] SIH3 + H2 + SIH4:1 H:1 + SIH3:1 H2:1 + + 7.8e+14 0 2260 + + + + + + SIH4 + M [=] SIH3 + H + M + SIH4:1 + SIH3:1 H:1 + + 3.91e+15 0 89356 + + + + + + SIH3 + H [=] SIH2 + H2 + SIH3:1 H:1 + SIH2:1 H2:1 + + 7.8e+14 0 2260 + + + + + + SI + SI + M [=] SI2 + M + SI:1 SI:1 + SI2:1 + + 2.47e+16 0 1178 + + + + + + SIH4 + SIH2 [=] H3SISIH + H2 + SIH4:1 SIH2:1 + H3SISIH:1 H2:1 + + 1.3e+13 0 0 + + + + + + SIH + H2 [=] SIH2 + H + SIH:1 H2:1 + SIH2:1 H:1 + + 4.8e+14 0 23.64 + + + + + + SIH + SIH4 [=] H3SISIH + H + SIH:1 SIH4:1 + H3SISIH:1 H:1 + + 1.6e+14 0 0 + + + + + + SI + H2 [=] SIH + H + SI:1 H2:1 + SIH:1 H:1 + + 1.5e+15 0 31.8 + + + + + + SIH4 (+ M) [=] SIH2 + H2 (+ M) + SIH4:1 + SIH2:1 H2:1 + + 3.119e+09 1.669 54710 + 5.214e+29 -3.545 57550 + -0.4984 888.3 209.4 2760 + + SI2H6:4 SIH4:4 + + + + + + + H3SISIH (+ M) [=] H2SISIH2 (+ M) + H3SISIH:1 + H2SISIH2:1 + + 2.54e+13 -0.2239 5381 + 1.099e+33 -5.765 9152 + -0.4202 214.5 103 136.3 + + SI2H6:4 SIH4:4 + + + + + + + SI3H8 (+ M) [=] SIH4 + H3SISIH (+ M) + SI3H8:1 + SIH4:1 H3SISIH:1 + + 3.73e+12 0.992 50850 + 4.36e+76 -17.26 59303 + 0.4157 365.3 3102 9.724 + + SI2H6:4 SIH4:4 + + + + + + + SI3H8 (+ M) [=] SIH2 + SI2H6 (+ M) + SI3H8:1 + SIH2:1 SI2H6:1 + + 6.97e+12 0.9691 52677 + 1.73e+69 -15.07 60491 + -3.47e-05 442 2412 128.3 + + SI2H6:4 SIH4:4 + + + + + + + SI2H6 (+ M) [=] H2 + H3SISIH (+ M) + SI2H6:1 + H2:1 H3SISIH:1 + + 9.086e+09 1.834 54197 + 1.945e+44 -7.772 59023 + -0.1224 793.3 2400 11.39 + + SI2H6:4 SIH4:4 + + + + + + + SI2H6 (+ M) [=] SIH4 + SIH2 (+ M) + SI2H6:1 + SIH4:1 SIH2:1 + + 1.81e+10 1.747 50203 + 5.09e+53 -10.37 56034 + 4.375e-05 438.5 2726 438.2 + + SI2H6:4 SIH4:4 + + + + + \ No newline at end of file diff --git a/test_problems/silane_equil/silane_equil.cpp b/test_problems/silane_equil/silane_equil.cpp new file mode 100644 index 000000000..4c74b1540 --- /dev/null +++ b/test_problems/silane_equil/silane_equil.cpp @@ -0,0 +1,28 @@ + +/* + * $Author$ + * $Date$ + * $Revision$ + * + * Copyright 2002 California Institute of Technology + * + */ + +//#include "Cantera.h" +#include "IdealGasMix.h" +#include "ChemEquil.h" + +int main(int argc, char **argv) { + try { + IdealGasMix g("silane.xml"); + g.setState_TPX(2000.0, 100.0, "SIH4:0.01, H2:0.99"); + equilibrate(g, TP); + printSummary(g, cout); + return 0; + } + catch (CanteraError) { + showErrors(cerr); + cerr << "program terminating." << endl; + return -1; + } +} diff --git a/tools/.cvsignore b/tools/.cvsignore new file mode 100644 index 000000000..550bd25cd --- /dev/null +++ b/tools/.cvsignore @@ -0,0 +1,2 @@ +Makefile + diff --git a/tools/Makefile.in b/tools/Makefile.in new file mode 100644 index 000000000..32c8b48e0 --- /dev/null +++ b/tools/Makefile.in @@ -0,0 +1,22 @@ +# +# $Revision$ +# $Author$ +# $Date$ +# +all: kernel + +kernel: + cd src; @MAKE@ + cd testtools; @MAKE@ + +clean: + $(RM) *.*~ + cd src; @MAKE@ clean + cd testtools; @MAKE@ clean + +docs: + cd doxygen/Cantera; doxygen Cantera.cfg + +depends: + cd src; @MAKE@ depends + cd testtools; @MAKE@ depends diff --git a/tools/bin/ctupdate.py b/tools/bin/ctupdate.py new file mode 100644 index 000000000..36d7311b8 --- /dev/null +++ b/tools/bin/ctupdate.py @@ -0,0 +1,758 @@ +######################################################################## +# +# Cantera installation / upgrade utility. +# +# Download this file, save it as ctupdate.py, and process it with python +# to install Cantera or update an existing installation. +# +######################################################################### + + +""" + usage: python ctupdate.py + + valid options are: + --help print this message + --force update everything, whether it needs it or not + --src compile/install from source code + --bin do a binary installation + --[no]python [don't] install the Cantera Python interface + --[no]matlab [don't] install the Cantera Matlab toolbox + + This script installs Cantera or updates an existing installation. + Both Windows and linux/unix installations are supported. It + installs from binaries on Windows, and builds everything from the + source code on all non-Windows platforms. + + If you are updating and have more than one Python interpreter + installed, be sure to run this script using the interpreter + you use with Cantera. On linux systems, this may be 'python2.' + +""" + +import urllib +import os +import sys +import time + +v = float(sys.version[:3]) +if v < 2.0: + print """ + +### ERROR ### + +This script must be run with python version 2.0 or greater. +This is version """+sys.version+""". +""" + if sys.platform[:5] == 'linux': + print """On many linux systems, python 2.x is installed as 'python2'. +""" + + sys.exit(-1) + + + +# +# definitions +# +_CTINFO_FILE = 'http://www.cantera.org/cantera_dist/etc/_ctinfo.py' + + +# +# set these to zero to skip installation of Python and Matlab components +# +install_python_module = 1 +install_matlab_toolbox = 1 + + +# +# global variables +# +_instdir = '--' # installation directory +_srcdir = '--' # directory where downloaded files go +force_update = 0 # force updating if nonzero + +_updates = [] +_reason = [] # +_num = 0 +_bininstall = -1 +_new_python = 0 + +_options = {} +_local = {} +_srv = {} + + +def read_options(): + """Read local configuration information.""" + optionfile = get_options_fname() + if not os.access(optionfile,os.F_OK): + return + f = open(optionfile) + lines = f.readlines() + for line in lines: + if line: + w = line.split()+['null','null'] + if w[1][-1] == '\n': + v = w[1][:-1] + else: + v = w[1] + _local[w[0]] = v + _options[w[0]] = v + + +def get_options_fname(): + + # if the OS is Windows, store the config file in + # C:\Documents and Settings\\Application Data + if sys.platform == 'win32': + appdata = os.getenv('APPDATA') + if not appdata: + print """ + Application Data directory cannot be found, because + environment variable APPDATA is not set. + """ + sys.exit(-1) + + home = appdata+os.sep+'cantera' + if not os.access(home,os.F_OK): + os.makedirs(home) + + # otherwise, look for environment variable 'HOME' to determine + # the home directory + else: + home = os.getenv('HOME') + + # if HOME is not set, then look in the current working directory. + if not home: + home = os.getcwd() + + optionfile = home+os.sep+'.ctupdate' + return optionfile + + + +def write_options(): + """ + Save configuration options. + """ + optionfile = get_options_fname() + f = open(optionfile,'w') + lines = [] + for k in _options.keys(): + if k: + if type(_options[k]) == types.StringType: + lines.append(k+' '+_options[k]+'\n') + else: + lines.append(k+' '+`_options[k]`+'\n') + f.writelines(lines) + f.close() + + +def ask(msg, options, deflt, helpmsg=''): + """ + Prompt for input. + options -- string listing the possible answers + deflt -- default response + helpmsg -- message printed if 'h' is input. + """ + print msg, + if options: + print '['+options+'] ', + if deflt: + print '('+deflt+') ', + ans = sys.stdin.readline()[:-1] + if ans == 'q' or ans == 'quit': + sys.exit(0) + elif ans == 'h': + print helpmsg + ans = ask(msg, options, deflt) + + if not ans: return deflt + else: return ans + + + +def report(prog, blocks, size): + """Print dots and percent completed during file download.""" + global _num + sys.stdout.write('.') + _num = _num + 1 + if 20*(prog/20) == prog: sys.stdout.write('%5.1f' % + ((100.0)*prog*blocks/size,)+'%') + + +def check_write(): + """ + Check to see if the Python library directory is writable. + """ + prefix = sys.prefix + return os.access(prefix+'/lib',os.W_OK) + + +def pycmd(): + """ + Return the location of the Python interpreter used to run Cantera, + or if this cannot be found, then return the string 'python'. + """ + if _options.has_key('pycmd'): + return _options['pycmd'] + else: + return 'python' + + +def get_srcdir(): + + """ Enter the directory where the installation files downloaded + from the web should be put. Once the installation is complete, any + files in this directory may be deleted. (But if you are building + from the source code, you might want to keep them, since the + source code is not copied to the installation directory.) """ + + global _srcdir + if _srcdir <> '--': + return _srcdir + + if _local.has_key('download_dir'): + d = _local['download_dir'] + else: + try: + d = os.getenv('HOME') + except: + d = os.getcwd() + + dir = ask('Download directory:','|q|h',d, + get_srcdir.__doc__) + + dir = os.path.expanduser(dir) + _srcdir = os.path.abspath(dir) + if not os.access(_srcdir,os.F_OK): + a = ask('Directory '+_srcdir+' does not exist. Create it?','y/n/q/h','y') + if a == 'y': + os.makedirs(_srcdir) + os.chdir(_srcdir) + _options['download_dir'] = _srcdir + return _srcdir + + +def get_instdir(): + + """ Enter the root directory under which binary executables, + library files, etc., should be installed. If you are doing a + system-wide install and have write-access to the /usr partition, + just press . Otherwise, enter the name of an existing + directory you have write access to. In this case, subdirectories + bin, lib, cantera, etc. will be created in this directory if they + don't already exist. """ + + global _instdir + if _instdir <> '--': + return _instdir + if _local.has_key('install_dir'): + d = _local['install_dir'] + else: + d = '' + dir = ask('Installation directory:','|q|h',d,get_instdir.__doc__) + ndir = dir + try: + if dir <> '' and dir[0] == '~': + ndir = os.getenv('HOME')+dir[1:] + except: + ndir = dir + _instdir = os.path.abspath(ndir) + _options['install_dir'] = _instdir + return _instdir + + + +def get_python(): + """ + Download the version of Python Cantera requires. + """ + global _new_python + _new_python = 1 + server = _ctinfo_srv.server + + if platform == 'win32': + path = _ctinfo_srv.WinPythonPath + urllib.urlretrieve(server+path,'installPython.exe',report) + _install_script.write('installPython.exe\n') + _options['pycmd'] = 'python' + + elif _bininstall == 0: + _prefix = get_instdir() + path = _ctinfo_srv.SrcPythonPath + urllib.urlretrieve(server+path,'python.tar.gz',report) + + _install_script.write('gunzip python.tar.gz\ntar xvf python.tar\n') + _install_script.write('cd '+_ctinfo_srv.SrcPythonDir+'\n') + if _prefix: + _install_script.write('./configure --prefix='+_prefix + +' --exec-prefix='+_prefix+'\n') + else: + _install_script.write('./configure\n') + _install_script.write('make\nmake install\ncd ..\n\n') + if _prefix: + _options['pycmd'] = _prefix+'/bin/python' + else: + _options['pycmd'] = 'python' + _options['python_version'] = _srv['python_version'] + + + +def get_graphviz(): + """Download graphviz.""" + server = _ctinfo_srv.server + + _options['dot_version'] = _srv['dot_version'] + + if platform == 'win32' and _bininstall == 1: + path = _ctinfo_srv.WinGraphvizPath + urllib.urlretrieve(server+path,'installGraphviz.exe',report) + _install_script.write('installGraphviz.exe\n') + + elif _bininstall == 0: + _prefix = get_instdir() + path = _ctinfo_srv.SrcGraphvizPath + urllib.urlretrieve(server+path,'graphviz.tar.gz',report) + + _install_script.write('gunzip graphviz.tar.gz\ntar xvf graphviz.tar\n') + _install_script.write('cd '+_ctinfo_srv.SrcGraphvizDir+'\n') + if _prefix: + _install_script.write('./configure --prefix='+_prefix + +' --exec-prefix='+_prefix+'\n') + else: + _install_script.write('./configure\n') + _install_script.write('make\nmake install\ncd ..\n\n') + + +def get_numeric(): + """Download the version of Numeric Cantera requires.""" + server = _ctinfo_srv.server + + if platform == 'win32' and _bininstall == 1: + path = _ctinfo_srv.WinNumericPath + urllib.urlretrieve(server+path,'installNumeric.exe',report) + _install_script.write('installNumeric.exe\n') + else: + path = _ctinfo_srv.SrcNumericPath + urllib.urlretrieve(server+path,'numeric.tar.gz',report) + + _install_script.write('gunzip numeric.tar.gz\ntar xvf numeric.tar\n') + _install_script.write('cd '+_ctinfo_srv.SrcNumericDir+'\n') + _install_script.write(pycmd()+' setup.py install\ncd ..\n\n') + + +def get_ct(): + """Download cantera.""" + server = _ctinfo_srv.server + _options['cantera'] = _srv['cantera'] + + if platform == 'win32' and _bininstall == 1: + path = _ctinfo_srv.WinCanteraPath + urllib.urlretrieve(server+path,'Cantera13.msi',report) + _install_script.write('Cantera13.msi\n') + _install_script.write('Cantera13.msi\n') + path = _ctinfo_srv.WinCanteraPyPath + urllib.urlretrieve(server+path,'installCanteraPy.exe',report) + _install_script.write('installCanteraPy.exe\n') + + elif _bininstall == 0: + _prefix = get_instdir() + path = _ctinfo_srv.SrcCanteraPath + urllib.urlretrieve(server+path,'cantera.tar.gz',report) + + _install_script.write('gunzip cantera.tar.gz\ntar xvf cantera-1.3.tar\n') + _install_script.write('cd '+_ctinfo_srv.SrcCanteraDir+'\n') + _install_script.write('PYTHON_CMD='+pycmd()+'; export PYTHON_CMD\n') + if install_matlab_toolbox == 0: + _install_script.write('BUILD_MATLAB_TOOLBOX="n"; export BUILD_MATLAB_TOOLBOX\n') + if install_python_module == 0: + _install_script.write('BUILD_PYTHON_INTERFACE="n"; export BUILD_PYTHON_INTERFACE\n') + if _prefix: + _install_script.write('configure --prefix='+_prefix + +' --exec-prefix='+_prefix+'\n') + else: + _install_script.write('configure\n') + _install_script.write('make\nmake install\ncd ..\n\n\n') + + + +def check_python(): + py_update_reason = '' + v = sys.version_info + vsrv =_ctinfo_srv.PythonVersion + _srv['python_version'] = vsrv + + need_upgrade = 0 + if _bininstall and (v[0] <> vsrv[0] or v[1] <> vsrv[1]): + py_update_reason = """ + Binary installs of Cantera requires Python version + """+`vsrv[0]`+'.'+`vsrv[1]`+""", but this is version """+`v[0]`+'.'+`v[1]`+""". + While any Python version 2.x can be used if you build Cantera + from the source, binary installs require that the Python + version matches that used when the binary distribution was + created. """ + need_upgrade = 1 + + elif not check_write(): + + py_update_reason = """ + You do not have write access to the library directory + associated with this Python executable + ("""+sys.prefix+"""/lib), and so the Python packages Cantera, + Numeric, and MixMaster can't be installed. + + Options: + + a) quit and re-run this script as super-user (unix) + or Administrator (Windows); or + + b) use this script to install a local version of Python + in a directory where you have write access + (won't work on Windows); or + + c) install only the Matlab and/or C++ components. + + """ + need_upgrade = 1 + + + elif force_update: + need_upgrade = 1 + py_update_reason = '\nforced update\n' + + if need_upgrade: + _updates.append(('Python '+`vsrv[0]`+'.'+`vsrv[1]`,get_python)) + _reason.append(py_update_reason) + return need_upgrade + + +def check_numeric(): + if platform == 'win32' and _bininstall == 1: + nv = _ctinfo_srv.WinNumericVersion + else: + nv = _ctinfo_srv.SrcNumericVersion + + num_update_reason = '--' + + try: + import Numeric + v = Numeric.__version__ + if _bininstall and v <> nv: + num_update_reason = """ + + Binary installs of Cantera requires Numeric (NumPy) version + """+nv+""", but this system has version """+v+""". While any + version can be used if you build Cantera from the source, + binary installs require that the version matches that used + when the binary distribution was created. + """ + + except: + num_update_reason = """ + The Cantera Python package requires the 'Numeric Extensions for + Python' package ('Numeric'), but it is not installed on this + system. + """ + + if force_update and num_update_reason == '--': + num_update_reason = '\nForced update.\n' + + if num_update_reason <> '--': + _updates.append(('Numeric Extensions for Python '+nv,get_numeric)) + _reason.append(num_update_reason) + return 1 + else: + return 0 + + + + + + +print """ + Cantera Installation / Upgrade Utility + version 1.0 + + type 'h' for help, or 'q' to quit +""" + + +platform = sys.platform +read_options() + +# +# process command-line arguments +# +args = sys.argv +nargs = len(args) + +if nargs >= 2: + for n in range(nargs): + if args[n] == '--force': + force_update = 1 + elif args[n] == '--help': + print __doc__ + sys.exit(0) + elif args[n] == '--src': + _bininstall = 0 + elif args[n] == '--python': + install_python_module = 1 + elif args[n] == '--nopython': + install_python_module = 0 + elif args[n] == '--matlab': + install_matlab_toolbox = 1 + elif args[n] == '--nomatlab': + install_matlab_toolbox = 0 + +_options['build_python'] = install_python_module +_options['build_matlab'] = install_matlab_toolbox + + +# open the install script files. +if sys.platform == 'win32' and _bininstall < 0: + _bininstall = 1 + _install_script = open('install.bat','w') + _install_script.write("""@echo off +REM run this script to install or update Cantera. +""") +else: + _bininstall = 0 + _install_script = open('install.sh','w') + _install_script.write("""#!/bin/sh +# run this script to install or update Cantera. +""") + +print 'checking for updates...' + +# get the information file from the server. This contains information about +# the versions on the server. +urllib.urlretrieve(_CTINFO_FILE, '_ctinfo_srv.py') +import _ctinfo_srv + + +######################################################################### + + +_thisdir = os.getcwd() + + +_files = [] + + +################################################################## +# +# check the Python version +# +################################################################## + +if install_python_module: + need_update = check_python() + if need_update: + install_python_module = 0 + + +################################################################## +# +# install/update Numeric +# +################################################################## + +if install_python_module: + check_numeric() + + +################################################################## +# +# install/update Graphviz +# +################################################################## + + +if install_python_module: + if platform == 'win32' and _bininstall == 1: + gv = _ctinfo_srv.WinGraphvizVersion + else: + gv = _ctinfo_srv.SrcGraphvizVersion + _srv['dot_version'] = gv + graphviz_update_reason = '--' + need_dot = 0 + dot_update_reason = '--' + v = '' + if _local.has_key('dot_version'): + v = _local['dot_version'] + else: + err = os.system('dot -V') + if err == 0: + print """ + Dot is installed, but the local configuration file + does not contain version information. + """ + v = ask('Enter dot version:','','','') + _options['dot_version'] = v + + if v <> '': + if v <> gv: + need_dot = 1 + dot_update_reason = """ + A newer version of 'dot' is available. + Installed dot version: """+v+""", + Latest dot version: """+gv+""" + """ + else: + need_dot = 1 + dot_update_reason = """ + Dot is not installed. + """ + + if force_update and dot_update_reason == '--': + need_dot = 1 + dot_update_reason = '\nforced update\n' + + if need_dot == 1: + _updates.append(('Graphviz version '+gv, get_graphviz)) + _reason.append(dot_update_reason) + + + +################################################################## +# +# install/update Cantera +# +################################################################## +import types +ct_update_reason = 'none' + +if _local.has_key('cantera'): + v = float(_local['cantera']) +else: + v = 0.0 +srvv = float(_ctinfo_srv.CanteraDate) +_srv['cantera'] = `srvv` +if v <> 0.0 and (abs(v - srvv) > 1.0): + ct_update_reason = """ + A newer version of Cantera is available. + Installed version date: """+time.ctime(v)+""" + Latest version date: """+time.ctime(srvv) + _updates.append(('Cantera',get_ct)) + _reason.append(ct_update_reason) +elif v == 0: + ct_update_reason = """ + Cantera is not installed, or version information can't be found. + """ + _updates.append(('Cantera',get_ct)) + _reason.append(ct_update_reason) +elif force_update: + ct_update_reason = '\nforced update\n' + _updates.append(('Cantera',get_ct)) + _reason.append(ct_update_reason) +#except: +# _updates.append(('Cantera',get_ct)) + + + +urllib.urlcleanup() +os.remove('_ctinfo_srv.pyc') + +ninst = len(_updates) + +if ninst > 0: + print '\n'+`ninst`+' update(s) found.\n' + + i = 0 + for u in _updates: + i = i + 1 + print '--------------------------------------------------------\n' + print ' ['+`i`+'] '+u[0] + '\nReason for update: '+_reason[i-1] + + + print '----------------------------------------------------------\n' + print ' The following packages will be downloaded and installed:' + + a = '' + print + _selected = [' ']*ninst + while a <> 'q': + print + i = 0 + for u in _updates: + i = i + 1 + print _selected[i-1]+' ['+`i`+'] '+u[0] + + a = '' + print + print """ + Enter 'a' to select all packages, or enter a package number. + Press to begin download. + """ + a = ask('Package:','1-'+`i`+'/a/h/q','') + if a == '': + break + if a == 'a': + for n in range(ninst): + _selected[n] = '*' + else: + #try: + nt = int(a) + if nt > 0 and nt <= ninst: + if _selected[nt-1] == '*': + _selected[nt-1] = ' ' + else: + _selected[nt-1] = '*' + #except: + # pass + + if _srcdir == '--': + print '\n\n' + srcdir = get_srcdir() + if srcdir: _install_script.write('cd '+srcdir+'\n') + if _bininstall == 0: + instdir = get_instdir() + + + n = 0 + for u in _updates: + n = n + 1 + if _selected[n-1] == '*': + print 'downloading '+u[0] + _num = 0 + u[1]() + print 'done.\n\n' + + + _install_script.close() + write_options() + + hlp = """ + The shell script 'install.sh' must be run to install the packages + downloaded. If you answer 'y' or hit , this script will + be run now. If you enter 'n' or 'q', nothing will be installed, but you + can later run 'install.sh' yourself to install the packages. + """ + a = ask('Install the downloaded packages?','y/n/h/q','y',hlp) + if a == 'y': + if _new_python > 0: + print """ + +************************ NOTE *************************************** + +You are installing a new Python interpreter. After the installation +finishes, you need to run this script again with the new interpreter +in order to set up the Cantera Python interface. + +********************************************************************* + +""" + os.chdir(_thisdir) + if sys.platform == 'win32': + os.execl('install.bat','install.bat') + else: + os.execl('/bin/sh','/bin/sh','install.sh') +else: + write_options() + print 'Cantera is up to date.' + + + + diff --git a/tools/bin/finish_install.py b/tools/bin/finish_install.py new file mode 100644 index 000000000..ea277ea8a --- /dev/null +++ b/tools/bin/finish_install.py @@ -0,0 +1,48 @@ +import sys, os +prefix = sys.argv[1] +pycmd = sys.argv[2] +if prefix == '-': prefix = '/usr/local' + +bindir = prefix+'/bin' +libdir = prefix+'/lib/cantera' +hdrdir = prefix+'/include/cantera' + +f = open(prefix+'/cantera/cantera_init','w') +f.write('#!/bin/sh\n') +libpath = os.getenv('LD_LIBRARY_PATH') +if libpath: + f.write('LD_LIBRARY_PATH='+libdir+':'+libpath+'\n') +else: + f.write('LD_LIBRARY_PATH='+libdir+'\n') +f.write('PATH='+bindir+':$PATH\n') +f.write('PYTHON_CMD='+pycmd+'\n') +if pycmd <> 'python': + f.write('alias ctpython='+pycmd+'\n') +f.close() + +f = open(bindir+'/mixmaster.py','w') +f.write("""from MixMaster import MixMaster +MixMaster() +""") +f.close() + +print """ + +Cantera has been successfully installed. + +File locations: + + applications """+bindir+""" + library files """+libdir+""" + C++ headers """+hdrdir+""" + demos """+prefix+"""/cantera/demos + data files """+prefix+"""/cantera/data + + A shell script 'cantera_init' has been written that configures the + environment for Cantera. It may be found in + """+prefix+"""/cantera. It is recommended that you run this script + before using Cantera, or include its contents in your shell login + script. + """ + + diff --git a/tools/export b/tools/export new file mode 100755 index 000000000..cca0bfbfd --- /dev/null +++ b/tools/export @@ -0,0 +1,17 @@ +#!/bin/sh + +version = cantera1.1b +export_dir = $2 +echo $export_dir + +#if (test -d $(export_dir)/$version); then rm -r $(export_dir)/$version; fi +#cd $(export_dir); cvs export -D 1/01/10 cantera-1.1 +# rm -r $(export_dir)/cantera-1.1/*/tests +# rm -r $(export_dir)/cantera-1.1/*/test +# rm -r $(export_dir)/cantera-1.1/*/doc +# mkdir $(export_dir)/cantera-1.1/lib + + + + + diff --git a/tools/src/.cvsignore b/tools/src/.cvsignore new file mode 100644 index 000000000..199f584f1 --- /dev/null +++ b/tools/src/.cvsignore @@ -0,0 +1,2 @@ +Makefile +sample.mak diff --git a/tools/src/Makefile.in b/tools/src/Makefile.in new file mode 100755 index 000000000..60ffe65e7 --- /dev/null +++ b/tools/src/Makefile.in @@ -0,0 +1,40 @@ +#/bin/sh + +LIBDIR = @ctroot@/lib +INCDIR = -I@ctroot@/Cantera/src +BINDIR = @ctroot@/bin +build_ck = @BUILD_CK@ + +LCXX_FLAGS = -L@ctroot@/lib @CXXFLAGS@ +LOCAL_LIBS = -lcantera @math_libs@ @LAPACK_LIBRARY@ @BLAS_LIBRARY@ + +LCXX_END_LIBS = @LCXX_END_LIBS@ +OBJS = ctsetup.o ck2ctml.o + +DEPENDS = $(OBJS:.o=.d) + +.cpp.o: + @CXX@ -c $< @DEFS@ $(INCDIR) @CXXFLAGS@ $(CXX_FLAGS) + +all: $(BINDIR)/ctmkmf $(BINDIR)/ck2ctml + +$(BINDIR)/ctmkmf: ctmkmf.o + @CXX@ -o $(BINDIR)/ctmkmf ctmkmf.o $(LCXX_FLAGS) $(LOCAL_LIBS) \ + $(LCXX_END_LIBS) + +$(BINDIR)/ck2ctml: ck2ctml.o + @CXX@ -o $(BINDIR)/ck2ctml ck2ctml.o $(LCXX_FLAGS) -lconverters $(LOCAL_LIBS) \ + $(LCXX_END_LIBS) +clean: + $(RM) *.o *.*~ + +%.d: + @CXX@ -MM $(INCDIR) @CXXFLAGS@ $(CXX_FLAGS) $*.cpp > $*.d + +depends: $(DEPENDS) + cat *.d &> .depends + $(RM) $(DEPENDS) + +ifeq ((test -e .depends),0) +include .depends +endif diff --git a/tools/src/ck2ctml.cpp b/tools/src/ck2ctml.cpp new file mode 100755 index 000000000..1f4a059d8 --- /dev/null +++ b/tools/src/ck2ctml.cpp @@ -0,0 +1,77 @@ +/** + * @file ck2ctml.cpp + * + * Program to convert CK-format reaction mechanism files to CTML format. + * + */ +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include +#include +using namespace std; + +#include "converters/ck2ctml.h" + +using namespace ctml; + +int showHelp() { + cout << "\nck2ckml: convert a CK-format reaction mechanism file to CTML.\n" + << "\n D. G. Goodwin, Caltech \n" + << " Version 1.0, August 2002.\n\n" + << endl; + cout << "options:" << endl; + cout << " -i \n" + << " -o \n" + << " -t \n" + << " -tr \n" + << " -id \n"; + return 0; +} + +int main(int argc, char** argv) { + string infile="chem.inp", dbfile="", trfile="", logfile, outfile=""; + string idtag = "gas"; + // ckr::CKReader r; + //r.validate = true; + int i=1; + if (argc == 1) return showHelp(); + + while (i < argc) { + string arg = string(argv[i]); + if (i < argc-1) { + if (arg == "-i") { + infile = argv[i+1]; + ++i; + } + else if (arg == "-o") { + outfile = argv[i+1]; + ++i; + } + else if (arg == "-t") { + dbfile = argv[i+1]; + ++i; + } + else if (arg == "-tr") { + trfile = argv[i+1]; + ++i; + } + else if (arg == "-id") { + idtag = argv[i+1]; + } + } + else if (arg == "-h" || argc < 3) { + return showHelp(); + } + ++i; + } + + int ierr = convert_ck(infile.c_str(), dbfile.c_str(), trfile.c_str(), + outfile.c_str(), idtag.c_str()); + if (ierr < 0) { + showErrors(cerr); + } + return ierr; +} diff --git a/tools/src/ck2ctml.dsp b/tools/src/ck2ctml.dsp new file mode 100755 index 000000000..bb63f853b --- /dev/null +++ b/tools/src/ck2ctml.dsp @@ -0,0 +1,108 @@ +# Microsoft Developer Studio Project File - Name="ck2ctml" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=ck2ctml - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "ck2ctml.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "ck2ctml.mak" CFG="ck2ctml - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "ck2ctml - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "ck2ctml - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +F90=df.exe +RSC=rc.exe + +!IF "$(CFG)" == "ck2ctml - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE F90 /compile_only /nologo /warn:nofileopt +# ADD F90 /assume:underscore /compile_only /iface:nomixed_str_len_arg /iface:cref /libs:static /math_library:fast /names:lowercase /nologo /warn:nofileopt /module:"" +# SUBTRACT F90 /threads +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib /nologo /subsystem:console /machine:I386 /out:"../../bin/ck2ctml.exe" /libpath:"c:/users/dgg/dv/cantera-1.2/lib" + +!ELSEIF "$(CFG)" == "ck2ctml - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE F90 /check:bounds /compile_only /debug:full /nologo /traceback /warn:argument_checking /warn:nofileopt +# ADD F90 /assume:underscore /check:bounds /compile_only /debug:full /iface:nomixed_str_len_arg /iface:cref /libs:dll /names:lowercase /nologo /threads /traceback /warn:argument_checking /warn:nofileopt /module:"" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "c:/users/dgg/dv/cantera-1.2/include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib cantera_d.lib ckreader_d.lib ctmath_d.lib ctlapack_d.lib ctblas_d.lib cvode_d.lib recipes_d.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../../bin/ck2ctml.exe" /pdbtype:sept /libpath:"c:/users/dgg/dv/cantera-1.2/lib" + +!ENDIF + +# Begin Target + +# Name "ck2ctml - Win32 Release" +# Name "ck2ctml - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;f90;for;f;fpp" +# Begin Source File + +SOURCE=.\ck2ctml.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/tools/src/ctlibsample.mak.in b/tools/src/ctlibsample.mak.in new file mode 100755 index 000000000..7d8f973dc --- /dev/null +++ b/tools/src/ctlibsample.mak.in @@ -0,0 +1,82 @@ +#!/bin/sh + +############################################################################ +# +# Makefile to compile and link a Fortran application to CtLib. +# +############################################################################# + +# the name of the executable program to be created +PROG_NAME = __PROGRAM__ + +# the object files to be linked together. List those generated from Fortran +# and from C/C++ separately +OBJS = __OBJS__ + +# additional flags to be passed to the linker. If your program +# requires other external libraries, put them here +LINK_OPTIONS = + +# if your program also calls Chemkin, set this to be the command-line +# string to link to CKLIB. +#CHEMKIN_LIB = -lchemkin +#CHEMKIN_LIB = cklib.o +CHEMKIN_LIB = + +# other external libraries that might be needed +EXT_LIBS = -lcvode -lrecipes @LAPACK_LIBRARY@ @BLAS_LIBRARY@ + +############################################################################# + +# the Fortran compiler +FORT = @F77@ + +# Fortran compile flags +FORT_FLAGS = @FFLAGS@ + +# Fortran libraries +FORT_LIBS = @FLIBS@ + +# the C++ compiler +CXX = @CXX@ + +# C++ compile flags +CXX_FLAGS = @CXXFLAGS@ + + +#------ you probably don't have to change anything below this line ----- + + +# the directory where the Cantera libraries are located +CANTERA_LIBDIR=@CANTERA_LIBDIR@ + +# required Cantera libraries +CANTERA_LIBS = -lct -lcantera -lckreader + +# the directory where Cantera include files may be found. +CANTERA_INCDIR=@CANTERA_INCDIR@ + +# flags passed to the C++ compiler/linker for the linking step +LCXX_FLAGS = -L$(CANTERA_LIBDIR) @CXXFLAGS@ + +# how to compile C++ source files to object files +.@CXX_EXT@.@OBJ_EXT@: + $(CXX) -c $< -I$(CANTERA_INCDIR) $(CXX_FLAGS) + +# how to compile Fortran source files to object files +.@F77_EXT@.@OBJ_EXT@: + $(FORT) -c $< $(FORT_FLAGS) + +all: $(PROG_NAME) + +$(PROG_NAME): $(OBJS) + $(CXX) -o $(PROG_NAME) $(OBJS) $(LCXX_FLAGS) $(CANTERA_LIBS) $(LINK_OPTIONS) $(CHEMKIN_LIB) $(EXT_LIBS) @LIBS@ $(FORT_LIBS) + +clean: + $(RM) $(OBJS) $(PROGRAM) + + + + + + diff --git a/tools/src/ctsetup.cpp b/tools/src/ctsetup.cpp new file mode 100755 index 000000000..7fa03619a --- /dev/null +++ b/tools/src/ctsetup.cpp @@ -0,0 +1,228 @@ +/** + * @file makedsp.cpp + * + * Write a Visual Studio Project File with settings for Cantera. This + * program writes a project file to build a console application only. + * + */ + +// copyright 2001 California Institute of Technology + + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include +#include +#include +using namespace std; + +void write_prog(string fname); + +int write_dsp(string ctroot, string projdir, string projname) { + + char buf[500]; + for (int j = 0; j < 500; j++) buf[j] = ' '; + string line; + + +#ifdef CVF + ifstream proto((ctroot+"/tools/src/protocvf.dsp").c_str()); + if (!proto) { + cout << "Error: file protocvf.dsp not found in " << ctroot << "/tools/src" << endl; + return 1; + } +#else + ifstream proto((ctroot+"/tools/src/protocxx.dsp").c_str()); + if (!proto) { + cout << "Error: file protocxx.dsp not found in " + << ctroot << "/tools/src" << endl; + return 1; + } +#endif + + string fname, progname; + if (projdir != "." && projdir != "'.'") { + fname = projdir+"\\"+projname+".dsp"; + progname = projdir+"\\"+projname+".cpp"; + } + else { + fname = string(projname)+".dsp"; + progname = string(projname)+".cpp"; + } + ofstream fout(fname.c_str()); + while (!proto.eof()) { + proto.getline( buf,500); + line = buf; + int i; + while (i = line.find("__PROJECT__"), i >=0) { + line.replace(i,11,projname); + } + while (i = line.find("__CTROOT__"), i >=0) { + line.replace(i,10,ctroot); + } + fout << line << endl; + } + proto.close(); + fout.close(); + + // if main program file doesn't exist, create a prototype + ifstream fprog(progname.c_str()); + bool wrote_prog = false; + if (!fprog) { + write_prog(progname); + wrote_prog = true; + } + else + fprog.close(); + + cout << "created Developer Studio project file " + << fname; + if (wrote_prog) + cout << " and main program file " << progname; + cout << endl; + return 0; +} + + + +int write_mak(string ctroot, string projdir, string projname) { + + char buf[500]; + for (int j = 0; j < 500; j++) buf[j] = ' '; + string line, objs; + + + ifstream proto((ctroot+"/tools/src/sample.mak").c_str()); + if (!proto) { + cout << "Error: file sample.mak not found in " + << ctroot << "/tools/src" << endl; + return 1; + } + + string fname, progname; + if (projdir != "." && projdir != "'.'") { + fname = projdir+"/"+projname+".mak"; + progname = projdir+"/"+projname+".cpp"; + } + else { + fname = string(projname)+".mak"; + progname = string(projname)+".cpp"; + } + + objs = string(projname)+".o"; + + ofstream fout(fname.c_str()); + while (!proto.eof()) { + proto.getline( buf,500); + line = buf; + int i; + while (i = line.find("__PROGRAM__"), i >=0) { + line.replace(i,11,projname); + } + while (i = line.find("__CTROOT__"), i >=0) { + line.replace(i,10,ctroot); + } + while (i = line.find("__OBJS__"), i >=0) { + line.replace(i,10,objs); + } + fout << line << endl; + } + proto.close(); + fout.close(); + cout << "Makefile = " << fname << endl; + + // if main program file doesn't exist, create a prototype + ifstream fprog(progname.c_str()); + bool wrote_prog = false; + if (!fprog) { + write_prog(progname); + wrote_prog = true; + } + else + fprog.close(); + + cout << "created Makefile " + << fname; + if (wrote_prog) + cout << " and main program file " << progname; + cout << endl; + return 0; +} + + +int main() { + + char buf[500]; + for (int j = 0; j < 500; j++) buf[j] = ' '; + string line, projname, projdir, ctroot; + + // prompt for the project name + cout << "Project name: "; + cin >> projname; + + // prompt for the output directory + cout << "Project directory (enter '.' for local directory): "; + cin >> projdir; + + // get the Cantera root directory either from environment + // variable CANTERA_ROOT (if set) or from user input + + const char* ctr; + int iroot = 0; + ctr = getenv("WIN_CANTERA_ROOT"); + if (ctr == 0) { + ctr = getenv("CANTERA_ROOT"); + iroot = 1; + } + if (ctr != 0) { + ctroot = ctr; + cout << "\nCantera root directory: " << ctroot; + cout << (iroot == 1 ? " (CANTERA_ROOT)" : " (WIN_CANTERA_ROOT)") << endl << endl; + } + else { + iroot = -1; + cout << "Cantera root directory: "; + cin >> ctroot; + } + + int itype; + cout << "Output type:\n" + << " 1 Unix Makefile\n" + << " 2 Visual Studio project file\n" + << "Output type:"; + cin >> itype; + if (itype == 1) write_mak(ctroot, projdir, projname); + else if (itype == 2) write_dsp(ctroot, projdir, projname); + + return 0; +} + + + +void write_prog(string fname) { + + ofstream f(fname.c_str()); + f << endl + << "#include \"Cantera.h\"" << endl + << "// include additional header files here if needed" << endl + << endl + << "int main(int argc, char** argv) {" << endl + << " try {" << endl + << " // your code goes here" << endl + << " return 0;" << endl + << " }" << endl + << " catch (CanteraError) {" << endl + << " showErrors(cerr);" << endl + << " cerr << \"program terminating.\" << endl;" << endl + << " return -1;" << endl + << " }" << endl + << "}" << endl; + f.close(); +} + + + + diff --git a/tools/src/ctsetup.in b/tools/src/ctsetup.in new file mode 100755 index 000000000..21808b4a7 --- /dev/null +++ b/tools/src/ctsetup.in @@ -0,0 +1,38 @@ +#!/bin/sh + +# complain if no program name was given +if test $# = 0; then +echo 'usage: ctsetup ' +exit 0 +fi + +# +# make the Makefile +# + +for t in "$@"; do +if test $t = -fort; then + status=fort; +elif test $t = -f90; then + status=f90; +elif test $t = -cxx; then + status=cxx +else + objs=$objs' '$t'.o'; +fi +done + +TOOLS_DIR=@CANTERA_ROOT@/tools + +echo 'creating '$1'.mak...' +cat > .sedscript < ./$1.mak + +rm -f .sedscript + + + + diff --git a/tools/src/ctwin b/tools/src/ctwin new file mode 100755 index 000000000..7e957b342 --- /dev/null +++ b/tools/src/ctwin @@ -0,0 +1,80 @@ +#!/bin/sh + +# complain if no program name was given +if test $# = 0; then +echo 'usage: ctsetup ' +exit 0 +fi + +# +# make the Makefile +# + +for t in "$@"; do +if test $t = -fort; then + status=fort; +elif test $t = -cxx; then + status=cxx +else + objs=$objs" $t.@OBJ_EXT@" +fi +done + +TOOLS_DIR=@CANTERA_ROOT@/tools + + +if test $1 = -ctlib; then +USE_CTLIB=1 +else +USE_CTLIB=0 +fi + +if test $USE_CTLIB = 1; then +echo 'creating '$2'.mak...' +objs=$objs" drive-$2.@OBJ_EXT@" +cat > .sedscript < ./$2.mak + +sub=$2_ + +echo 'creating C++ driver program...' +cat > drive-$2.cpp << EOF + +/* + * driver program for Fortran subroutine $2 + */ + +#include + +extern "C" { + int $sub(); +} + +main() { + try { + $sub(); + } + catch (...) { + cerr << "an error occurred." << endl; + } +} +EOF + +else +echo 'creating '$1'.mak...' +cat > .sedscript < ./$1.mak +fi + +rm -f .sedscript + + + + diff --git a/tools/src/makedsp.cpp b/tools/src/makedsp.cpp new file mode 100755 index 000000000..86bb16775 --- /dev/null +++ b/tools/src/makedsp.cpp @@ -0,0 +1,81 @@ +/** + * @file makedsp.cpp + * + * Write a Win32 Visual Studio Project File with settings for Cantera + * + */ + +// copyright (c) 2001 California Institute of Technology + + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include +#include +#include +using namespace std; + +int main() { + + char buf[500]; + for (int j = 0; j < 500; j++) buf[j] = ' '; + string line, projname, ctroot; + + // prompt for the project name + cout << "Project name: "; + cin >> projname; + + + // get the Cantera root directory either from environment + // variable CANTERA_ROOT (if set) or from user input + + const char* ctr; + int iroot = 0; + ctr = getenv("WIN_CANTERA_ROOT"); + if (ctr == 0) { + ctr = getenv("CANTERA_ROOT"); + iroot = 1; + } + if (ctr != 0) { + ctroot = ctr; + cout << "\nCantera root directory: " << ctroot; + cout << (iroot == 1 ? " (CANTERA_ROOT)" : " (WIN_CANTERA_ROOT)") << endl << endl; + } + else { + iroot = -1; + cout << "Cantera root directory: "; + cin >> ctroot; + } + + ifstream proto((ctroot+"/tools/src/proto.dsp").c_str()); + if (!proto) { + cout << "Error: file proto.dsp not found in " << ctroot << "/tools/src" << endl; + return 1; + } + + ofstream fout((projname+".dsp").c_str()); + while (!proto.eof()) { + proto.getline( buf,500); + line = buf; + int i; + while (i = line.find("__PROTO__"), i >=0) { + line.replace(i,9,projname); + } + while (i = line.find("__CANTERAROOT__"), i >=0) { + line.replace(i,15,ctroot); + } + fout << line << endl; + } + proto.close(); + fout.close(); + + cout << "created Visual Studio project file " << projname << ".dsp" << endl; + return 0; +} + + + + diff --git a/tools/src/newdsp.cpp b/tools/src/newdsp.cpp new file mode 100755 index 000000000..c48ff4219 --- /dev/null +++ b/tools/src/newdsp.cpp @@ -0,0 +1,140 @@ +/** + * @file makedsp.cpp + * + * Write a Visual Studio Project File with settings for Cantera. This + * program writes a project file to build a console application only. + * + */ + +// copyright 2001 California Institute of Technology + + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include +#include +#include +using namespace std; + +void write_prog(string fname); + +int main() { + + char buf[500]; + for (int j = 0; j < 500; j++) buf[j] = ' '; + string line, projname, projdir, ctroot; + + // prompt for the project name + cout << "Project name: "; + cin >> projname; + + // prompt for the output directory + cout << "Project directory (enter '.' for local directory): "; + cin >> projdir; + + // get the Cantera root directory either from environment + // variable CANTERA_ROOT (if set) or from user input + + const char* ctr; + int iroot = 0; + ctr = getenv("WIN_CANTERA_ROOT"); + if (ctr == 0) { + ctr = getenv("CANTERA_ROOT"); + iroot = 1; + } + if (ctr != 0) { + ctroot = ctr; + cout << "\nCantera root directory: " << ctroot; + cout << (iroot == 1 ? " (CANTERA_ROOT)" : " (WIN_CANTERA_ROOT)") << endl << endl; + } + else { + iroot = -1; + cout << "Cantera root directory: "; + cin >> ctroot; + } + +#ifdef CVF + ifstream proto((ctroot+"/tools/src/protocvf.dsp").c_str()); + if (!proto) { + cout << "Error: file protocvf.dsp not found in " << ctroot << "/tools/src" << endl; + return 1; + } +#else + ifstream proto((ctroot+"/tools/src/protocxx.dsp").c_str()); + if (!proto) { + cout << "Error: file protocxx.dsp not found in " + << ctroot << "/tools/src" << endl; + return 1; + } +#endif + + string fname, progname; + if (projdir != "." && projdir != "'.'") { + fname = projdir+"\\"+projname+".dsp"; + progname = projdir+"\\"+projname+".cpp"; + } + else { + fname = string(projname)+".dsp"; + progname = string(projname)+".cpp"; + } + ofstream fout(fname.c_str()); + while (!proto.eof()) { + proto.getline( buf,500); + line = buf; + int i; + while (i = line.find("__PROJECT__"), i >=0) { + line.replace(i,11,projname); + } + while (i = line.find("__CTROOT__"), i >=0) { + line.replace(i,10,ctroot); + } + fout << line << endl; + } + proto.close(); + fout.close(); + + // if main program file doesn't exist, create a prototype + ifstream fprog(progname.c_str()); + bool wrote_prog = false; + if (!fprog) { + write_prog(progname); + wrote_prog = true; + } + else + fprog.close(); + + cout << "created Developer Studio project file " + << fname; + if (wrote_prog) + cout << " and main program file " << progname; + cout << endl; + return 0; +} + +void write_prog(string fname) { + + ofstream f(fname.c_str()); + f << endl + << "#include \"Cantera.h\"" << endl + << "// include additional header files here if needed" << endl + << endl + << "int main(int argc, char** argv) {" << endl + << " try {" << endl + << " // your code goes here" << endl + << " return 0;" << endl + << " }" << endl + << " catch (CanteraError) {" << endl + << " Application::showErrors(cerr);" << endl + << " cerr << \"program terminating.\" << endl;" << endl + << " return -1;" << endl + << " }" << endl + << "}" << endl; + f.close(); +} + + + + diff --git a/tools/src/proto.dsp b/tools/src/proto.dsp new file mode 100755 index 000000000..dad645923 --- /dev/null +++ b/tools/src/proto.dsp @@ -0,0 +1,103 @@ +# Microsoft Developer Studio Project File - Name="__PROTO__" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=__PROTO__ - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "__PROTO__.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "__PROTO__.mak" CFG="__PROTO__ - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "__PROTO__ - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "__PROTO__ - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +F90=df.exe +RSC=rc.exe + +!IF "$(CFG)" == "__PROTO__ - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE F90 /compile_only /nologo /warn:nofileopt +# ADD F90 /assume:underscore /compile_only /iface:nomixed_str_len_arg /iface:cref /libs:dll /names:lowercase /nologo /threads /warn:nofileopt +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "__CANTERAROOT__/include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib cantera.lib ckreader.lib ctlib.lib ctlapack.lib ctblas.lib cvode.lib recipes.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib cantera.lib ckreader.lib ctlib.lib ctlapack.lib ctblas.lib cvode.lib recipes.lib /nologo /subsystem:console /machine:I386 /out:"__PROTO__.exe" /libpath:"__CANTERAROOT__/lib" + +!ELSEIF "$(CFG)" == "__PROTO__ - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE F90 /check:bounds /compile_only /debug:full /nologo /traceback /warn:argument_checking /warn:nofileopt +# ADD F90 /assume:underscore /check:bounds /compile_only /debug:full /iface:nomixed_str_len_arg /iface:cref /libs:dll /names:lowercase /nologo /reentrancy:threaded /traceback /warn:argument_checking /warn:nofileopt +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MD /W3 /Gm /GX /ZI /Od /I "__CANTERAROOT__/include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib cantera.lib ckreader.lib ctlib.lib ctlapack.lib ctblas.lib cvode.lib recipes.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib cantera.lib ckreader.lib ctlib.lib ctlapack.lib ctblas.lib cvode.lib recipes.lib /nologo /subsystem:console /debug /machine:I386 /out:"__PROTO__.exe" /pdbtype:sept /libpath:"__CANTERAROOT__/lib" + +!ENDIF + +# Begin Target + +# Name "__PROTO__ - Win32 Release" +# Name "__PROTO__ - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;f90;for;f;fpp" +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/tools/src/protocvf.dsp b/tools/src/protocvf.dsp new file mode 100755 index 000000000..3fcd08795 --- /dev/null +++ b/tools/src/protocvf.dsp @@ -0,0 +1,103 @@ +# Microsoft Developer Studio Project File - Name="__PROJECT__" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=__PROJECT__ - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "__PROJECT__.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "__PROJECT__.mak" CFG="__PROJECT__ - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "__PROJECT__ - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "__PROJECT__ - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +F90=df.exe +RSC=rc.exe + +!IF "$(CFG)" == "__PROJECT__ - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE F90 /compile_only /nologo /warn:nofileopt +# ADD F90 /compile_only /include:"__CTROOT__\include\fortran\" /libs:dll /math_library:fast /nologo /threads /warn:nofileopt /module:"" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ctf.lib modules.lib /nologo /subsystem:console /machine:I386 /libpath:"__CTROOT__/lib" + +!ELSEIF "$(CFG)" == "__PROJECT__ - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE F90 /check:bounds /compile_only /debug:full /nologo /traceback /warn:argument_checking /warn:nofileopt +# ADD F90 /check:bounds /compile_only /debug:full /include:"__CTROOT__\include\fortran\" /libs:dll /nologo /threads /traceback /warn:argument_checking /warn:nofileopt /module:"" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ctf.lib modules.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /pdbtype:sept /libpath:"__CTROOT__/lib" + +!ENDIF + +# Begin Target + +# Name "__PROJECT__ - Win32 Release" +# Name "__PROJECT__ - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;f90;for;f;fpp" +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/tools/src/protocxx.cpp b/tools/src/protocxx.cpp new file mode 100755 index 000000000..9e91a007e --- /dev/null +++ b/tools/src/protocxx.cpp @@ -0,0 +1,13 @@ + +#include "Cantera.h" +// include additional header files here if needed + +main(int argc, char** argv) { + try { + // your code goes here + } + catch (CanteraError) { + showErrors(cerr); + cerr << "program terminating." << endl; + } +} diff --git a/tools/src/protocxx.dsp b/tools/src/protocxx.dsp new file mode 100755 index 000000000..5398d9766 --- /dev/null +++ b/tools/src/protocxx.dsp @@ -0,0 +1,108 @@ +# Microsoft Developer Studio Project File - Name="__PROJECT__" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=__PROJECT__ - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "__PROJECT__.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "__PROJECT__.mak" CFG="__PROJECT__ - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "__PROJECT__ - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "__PROJECT__ - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +F90=df.exe +RSC=rc.exe + +!IF "$(CFG)" == "__PROJECT__ - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE F90 /compile_only /nologo /warn:nofileopt +# ADD F90 /assume:underscore /compile_only /iface:nomixed_str_len_arg /iface:cref /libs:dll /math_library:fast /names:lowercase /nologo /threads /warn:nofileopt /module:"" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "__CTROOT__/include" /I "__CTROOT__/Cantera/src" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# SUBTRACT CPP /Z +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib cantera.lib ckreader.lib ctmath.lib ctlapack.lib ctblas.lib cvode.lib recipes.lib /nologo /subsystem:console /machine:I386 /libpath:"__CTROOT__/lib" + +!ELSEIF "$(CFG)" == "__PROJECT__ - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE F90 /check:bounds /compile_only /debug:full /nologo /traceback /warn:argument_checking /warn:nofileopt +# ADD F90 /assume:underscore /check:bounds /compile_only /debug:full /iface:nomixed_str_len_arg /iface:cref /libs:dll /names:lowercase /nologo /threads /traceback /warn:argument_checking /warn:nofileopt /module:"" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MD /W3 /Gm /GX /ZI /Od /I "__CTROOT__/include" /I "__CTROOT__/Cantera/src" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib cantera.lib ckreader.lib ctmath.lib ctlapack.lib ctblas.lib cvode.lib recipes.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /pdbtype:sept /libpath:"__CTROOT__/lib" + +!ENDIF + +# Begin Target + +# Name "__PROJECT__ - Win32 Release" +# Name "__PROJECT__ - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;f90;for;f;fpp" +# Begin Source File + +SOURCE=.\__PROJECT__.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/tools/src/sample.mak.in b/tools/src/sample.mak.in new file mode 100755 index 000000000..23b989e43 --- /dev/null +++ b/tools/src/sample.mak.in @@ -0,0 +1,96 @@ +#!/bin/sh + +############################################################################ +# +# Makefile to compile and link a C++ or Fortran application to +# Cantera. +# +############################################################################# + +# the name of the executable program to be created +PROG_NAME = __PROGRAM__ + +# the object files to be linked together. +OBJS = __OBJS__ + +# additional flags to be passed to the linker. If your program +# requires other external libraries, put them here +LINK_OPTIONS = + + +############################################################################# + +# the Fortran compiler +FORT = @F77@ + +# Fortran compile flags +FORT_FLAGS = @FFLAGS@ + +# Fortran libraries +FORT_LIBS = @FLIBS@ + +# the C++ compiler +CXX = @CXX@ + +# C++ compile flags +CXX_FLAGS = @CXXFLAGS@ + +# external libraries +EXT_LIBS = @LOCAL_LIBS@ + + + +#------ you probably don't have to change anything below this line ----- + + +# the directory where the Cantera libraries are located +CANTERA_LIBDIR=@CANTERA_LIBDIR@ + +# required Cantera libraries +CANTERA_LIBS = + +# the directory where Cantera include files may be found. +CANTERA_INCDIR=@CANTERA_INCDIR@ + +# flags passed to the C++ compiler/linker for the linking step +LCXX_FLAGS = -L$(CANTERA_LIBDIR) @CXXFLAGS@ + +# how to compile C++ source files to object files +.@CXX_EXT@.@OBJ_EXT@: + $(CXX) -c $< -I$(CANTERA_INCDIR) $(CXX_FLAGS) + +# how to compile Fortran source files to object files +.@F77_EXT@.@OBJ_EXT@: + $(FORT) -c $< $(FORT_FLAGS) + +PROGRAM = $(PROG_NAME)$(EXE_EXT) + +DEPENDS = $(OBJS:.o=.d) + +all: $(PROGRAM) + +$(PROGRAM): $(OBJS) + $(CXX) -o $(PROGRAM) $(OBJS) $(LCXX_FLAGS) $(CANTERA_LIBS) $(LINK_OPTIONS) $(EXT_LIBS) @LIBS@ $(FORT_LIBS) + +%.d: + g++ -MM $*.cpp > $*.d + +clean: + $(RM) $(OBJS) $(PROGRAM) + +depends: $(DEPENDS) + cat *.d > .depends + $(RM) $(DEPENDS) + +TAGS: + etags *.h *.cpp + +ifeq ($(wildcard .depends), .depends) +include .depends +endif + + + + + + diff --git a/tools/src/sample_f90.mak.in b/tools/src/sample_f90.mak.in new file mode 100755 index 000000000..166cb3981 --- /dev/null +++ b/tools/src/sample_f90.mak.in @@ -0,0 +1,90 @@ +#!/bin/sh + +############################################################################ +# +# Makefile to compile and link a Fortran 90 application to +# Cantera. +# +############################################################################# + +# the name of the executable program to be created +PROG_NAME = __PROGRAM__ + +# the object files to be linked together. List those generated from Fortran +# and from C/C++ separately +OBJS = __OBJS__ + +# additional flags to be passed to the linker. If your program +# requires other external libraries, put them here +LINK_OPTIONS = + + +############################################################################# + +# the Fortran compiler +FORT = @F90@ + +# Fortran compile flags +FORT_FLAGS = @FFLAGS@ + +# Fortran libraries +FORT_LIBS = @FLIBS@ + +# the C++ compiler +CXX = @CXX@ + +# C++ compile flags +CXX_FLAGS = @CXXFLAGS@ + +# external libraries +EXT_LIBS = -lcvode -lrecipes @LAPACK_LIBRARY@ @BLAS_LIBRARY@ + +#------ you probably don't have to change anything below this line ----- + +# Fortran module directory +FTN_MODULE_DIR = @CANTERA_ROOT@/Cantera/fortran + +# Cantera modules +CT_MODULES = $(FTN_MODULE_DIR)/ctmixturemod.f \ + $(FTN_MODULE_DIR)/ctreactormod.f \ + $(FTN_MODULE_DIR)/ctfdevmod.f \ + $(FTN_MODULE_DIR)/ctmod.f + +# the directory where the Cantera libraries are located +CANTERA_LIBDIR=@CANTERA_LIBDIR@ + +# required Cantera libraries +CANTERA_LIBS = -lctf -lcantera -lckreader + +# the directory where Cantera include files may be found. +CANTERA_INCDIR=@CANTERA_INCDIR@ + +# flags passed to the C++ compiler/linker for the linking step +LCXX_FLAGS = -L$(CANTERA_LIBDIR) @CXXFLAGS@ + +# how to compile C++ source files to object files +.@CXX_EXT@.@OBJ_EXT@: + $(CXX) -c $< -I$(CANTERA_INCDIR) $(CXX_FLAGS) + +# how to compile Fortran source files to object files +.@F77_EXT@.@OBJ_EXT@: + $(FORT) -c $< $(FORT_FLAGS) + +.@F90_EXT@.@OBJ_EXT@: + $(FORT) -c $< $(FORT_FLAGS) + +PROGRAM = $(PROG_NAME)$(EXE_EXT) + +all: $(PROGRAM) + +$(PROGRAM): $(OBJS) + $(FORT) -o $(PROGRAM) $(CT_MODULES) $(OBJS) $(LF90_FLAGS) $(CANTERA_LIBS) $(LINK_OPTIONS) $(EXT_LIBS) @LIBS@ + +clean: + $(RM) $(OBJS) $(PROGRAM) + + + + + + diff --git a/tools/src/validate.cpp b/tools/src/validate.cpp new file mode 100755 index 000000000..ca1944445 --- /dev/null +++ b/tools/src/validate.cpp @@ -0,0 +1,45 @@ +/** + * @file validate.cpp + * validate a CK-format reaction mechanism file + */ + +// Copyright 2001 California Institute of Technology + +#include +#include "Cantera.h" +#include "IdealGasMix.h" +#include +using namespace Cantera; + +int main(int argc, char** args) { + + try { + IdealGasMix gas; + char* infile = 0; + char* dbfile = 0; + bool ok = true; + if (argc == 1 || argc > 3) { + cout << "usage: validate " << endl; + return 0; + } + else if (argc == 2) { + infile = args[1]; + ok = gas.import(string(infile),"",true); + } + else if (argc == 3) { + infile = args[1]; + dbfile = args[2]; + ok = gas.import(string(infile),string(dbfile),true); + } + showErrors(cerr); + if (!ok) + cerr << infile << " contains errors" << endl; + else + cout << infile << " is valid." << endl; + return int(!ok); + } + catch (...) { + cerr << "exception raised." << endl; + showErrors(cerr); + } +} diff --git a/tools/templates/f77/demo.f b/tools/templates/f77/demo.f new file mode 100644 index 000000000..11f530631 --- /dev/null +++ b/tools/templates/f77/demo.f @@ -0,0 +1,24 @@ +c +c Replace this sample main program with your program +c +c This program uses functions defined in demo_ftnlib.cpp. +c + program demo + implicit double precision (a-h,o-z) + parameter (MAXSP = 20, MAXRXNS = 100) + double precision x(MAXSP), y(MAXSP), wdot(MAXRXNS) +c + call readmechanism('h2o2.xml','') + t = 1200.0 + p = 101325.0 + call setState_TPX_String(t, p, 'H2:2, O2:1') + write(*,*) ' **** Test Program ****' + write(*,10) temperature(), pressure(), density(), + $ enthalpy_mole(), entropy_mole(), cp_mole() + 10 format(//'Temperature:',g14.5,' K'/'Pressure:',g14.5,' Pa' + $ /'Density:',g14.5,' kg/m**3'//) +c + stop + end + + diff --git a/tools/templates/f77/demo_ftnlib.cpp b/tools/templates/f77/demo_ftnlib.cpp new file mode 100644 index 000000000..5a92c43c5 --- /dev/null +++ b/tools/templates/f77/demo_ftnlib.cpp @@ -0,0 +1,190 @@ +/*! + A simple Fortran 77 interface + + This file is an example of how to write an interface to use Cantera + in Fortran 77 programs. The basic idea is to store pointers to + Cantera objects in global storage, and then create Fortran-callable + functions that access the objects through the pointers. + + This particular example defines functions that return thermodynamic + properties and kinetic rates for reacting ideal gas mixtures. Only a + single pointer to an IdealGasMix object is stored, so only one + reaction mechanism may be used at any one time in the application. + + The functions defined here are ones commonly needed in application + programs that simulate gas-phase combustion or similar processes. + You may find that you can use this library without modification. If + you need to access additional capabilities of Cantera from Fortran, + you can use this file as a guide. Also take a look at the Fortran 77 + examples in the demos/f77 subdirectory within the directory where + Cantera is installed. + + */ + +// add any other Cantera header files you need here +#include "IdealGasMix.h" +#include "equilibrium.h" + + +// store a pointer to an IdealGasMix object. The object itself will +// be created by the call to init_. +static IdealGasMix* _gas = 0; + + + +extern "C" { + + /// This is the Fortran main program + extern int MAIN__(); + + + /** + * Read in a reaction mechanism file and create an IdealGasMix + * object. The file may be in Chemkin-compatible format or in + * CTML. The name of a thermodynamic database may be supplied as a + * second argument. If none is required, enter an empty string as + * the second argument. + */ + void readmechanism_(char* file, char* thermo, + ftnlen lenfile, ftnlen lenthermo) { + string fin = string(file, lenfile); + string fth = string(thermo, lenthermo); + if (_gas) delete _gas; + _gas = new IdealGasMix(fin, fth); + } + + /// integer function nElements() + integer nelements_() { return _gas->nElements(); } + + /// integer function nSpecies() + integer nspecies_() { return _gas->nSpecies(); } + + /// integer function nReactions() + integer nreactions_() { return _gas->nReactions(); } + + + //-------------- setting the state ---------------------------- + + // subroutine setState_TPX(T, P, X) + void setstate_tpx_(doublereal* T, doublereal* P, doublereal* X) { + _gas->setState_TPX(*T, *P, X); + } + + /// subroutine setState_TPX_AsString(T, P, X) + void setstate_tpx_asstring_(doublereal* T, doublereal* P, + char* X, ftnlen lenx) { + _gas->setState_TPX(*T, *P, string(X, lenx)); + } + + + //-------------- thermodynamic properties ---------------------- + + /// Temperature (K) + doublereal temperature_() { + return _gas->temperature(); + } + + /// Pressure (Pa) + doublereal pressure_() { + return _gas->pressure(); + } + + /// Density (kg/m^3) + doublereal density_() { + return _gas->density(); + } + + /// Mean molar mass (kg/kmol). + doublereal meanmolarmass_() { + return _gas->meanMolecularWeight(); + } + + /// Molar enthalpy (J/kmol) + doublereal enthalpy_mole_() { + return _gas->enthalpy_mole(); + } + + /// Molar internal energy (J/kmol) + doublereal intenergy_mole_() { + return _gas->intEnergy_mole(); + } + + /// Molar entropy (J/kmol-K) + doublereal entropy_mole_() { + return _gas->entropy_mole(); + } + + /// Molar heat capacity at constant P (J/kmol-K) + doublereal cp_mole_() { + return _gas->cp_mole(); + } + + /// Molar Gibbs function (J/kmol) + doublereal gibbs_mole_() { + return _gas->gibbs_mole(); + } + + doublereal enthalpy_mass_() { + return _gas->enthalpy_mole(); + } + + doublereal intenergy_mass_() { + return _gas->intEnergy_mole(); + } + + doublereal entropy_mass_() { + return _gas->entropy_mole(); + } + + doublereal cp_mass_() { + return _gas->cp_mole(); + } + + doublereal gibbs_mass_() { + return _gas->gibbs_mole(); + } + + + void equilibrate_(integer* opt) { + int option = *opt; + equilibrate(*_gas, option); + } + + + //---------------- kinetics ------------------------- + + void getreactioneqn_(integer* i, char* eqn, ftnlen n) { + int irxn = *i - 1; + fill(eqn, eqn + n, ' '); + string e = _gas->reactionString(irxn); + unsigned int nmx = (e.size() > n ? n : e.size()); + copy(e.begin(), e.begin()+nmx, eqn); + } + + void getnetproductionrates_(doublereal* wdot) { + _gas->getNetProductionRates(wdot); + } + + void getnetratesofprogress_(doublereal* q) { + _gas->getNetRatesOfProgress(q); + } +} + + +/** + * This C++ main program simply calls the Fortran main program. + */ +int main() { + try { + return MAIN__(); + } + catch (CanteraError) { + showErrors(cerr); + return -1; + } + catch (...) { + cout << "An exception was trapped. Program terminating." << endl; + return -1; + } +} + diff --git a/tools/templates/f77/sample.mak.in b/tools/templates/f77/sample.mak.in new file mode 100644 index 000000000..d9e39dc18 --- /dev/null +++ b/tools/templates/f77/sample.mak.in @@ -0,0 +1,99 @@ +#!/bin/sh + +# This Makefile builds a Fortran 77 application that uses Cantera. By +# default, the main program file is 'demo.f,' which prints out some +# properties of a reacting gas mixture. It uses the library +# 'demo_ftnlib.cpp,' which contains Fortran-callable functions that +# are implemented with C++ calls to Cantera. + +# To build program 'demo', simply type 'make', or 'make -f ' if this file is named something other than 'Makefile.' + +# Once you have verified that the demo runs, edit this file to replace +# object file 'demo.o' with your own object file or files. You may +# continue to use 'demo_ftnlib' if it serves your needs, or else +# replace it with a different interface library. + + +#------------------------ edit this block --------------------------------- + +# the name of the executable program to be created +PROG_NAME = demo + +# the object files to be linked together. +OBJS = demo.o demo_ftnlib.o + +# additional flags to be passed to the linker. If your program +# requires other external libraries, put them here +LINK_OPTIONS = + +#--------------------------------------------------------------------------- +# You probably don't need to edit anything below. + + +# the Fortran compiler +FORT = @F77@ + +# Fortran compile flags +FORT_FLAGS = @FFLAGS@ + +# Fortran libraries +FORT_LIBS = @FLIBS@ + +# the C++ compiler +CXX = @CXX@ + +# C++ compile flags +CXX_FLAGS = @CXXFLAGS@ + +# external libraries +EXT_LIBS = @LOCAL_LIBS@ + +# the directory where the Cantera libraries are located +CANTERA_LIBDIR=@CANTERA_LIBDIR@ + +# the directory where Cantera include files may be found. +CANTERA_INCDIR=@CANTERA_INCDIR@ + +# flags passed to the C++ compiler/linker for the linking step +LCXX_FLAGS = -L$(CANTERA_LIBDIR) @CXXFLAGS@ + +# how to compile C++ source files to object files +.@CXX_EXT@.@OBJ_EXT@: + $(CXX) -c $< -I$(CANTERA_INCDIR) $(CXX_FLAGS) + +# how to compile Fortran source files to object files +.@F77_EXT@.@OBJ_EXT@: + $(FORT) -c $< $(FORT_FLAGS) + +PROGRAM = $(PROG_NAME)$(EXE_EXT) + +DEPENDS = $(OBJS:.o=.d) + +all: $(PROGRAM) + +$(PROGRAM): $(OBJS) + $(CXX) -o $(PROGRAM) $(OBJS) $(LCXX_FLAGS) $(CANTERA_LIBS) $(LINK_OPTIONS) $(EXT_LIBS) @LIBS@ $(FORT_LIBS) + +%.d: + g++ -MM $*.cpp > $*.d + +clean: + $(RM) $(OBJS) $(PROGRAM) + +depends: $(DEPENDS) + cat *.d > .depends + $(RM) $(DEPENDS) + +TAGS: + etags *.h *.cpp + +ifeq ($(wildcard .depends), .depends) +include .depends +endif + + + + + + diff --git a/tools/testtools/.cvsignore b/tools/testtools/.cvsignore new file mode 100644 index 000000000..96db0f094 --- /dev/null +++ b/tools/testtools/.cvsignore @@ -0,0 +1,4 @@ +*.csv +.depends +Makefile +csvdiff diff --git a/tools/testtools/Makefile.in b/tools/testtools/Makefile.in new file mode 100644 index 000000000..a74ee239c --- /dev/null +++ b/tools/testtools/Makefile.in @@ -0,0 +1,42 @@ +#/bin/sh + +LIBDIR = @ctroot@/lib +INCDIR = @ctroot@/include +BINDIR = @ctroot@/bin +build_ck = @BUILD_CK@ + +LCXX_FLAGS = -L$(LIBDIR) @CXXFLAGS@ +LOCAL_LIBS = -lcantera -lckreader @math_libs@ @LAPACK_LIBRARY@ @BLAS_LIBRARY@ + +LCXX_END_LIBS = @LCXX_END_LIBS@ + +OBJS = mdp_allo.o csvdiff.o tok_input_util.o +DEPENDS = $(OBJS:.o=.d) + +# Optimization is turned off (-O0) because a strange interal compiler +# error results when using g++ 3.0 on Mac OS X. Optimization should +# not be needed here anyway. + +.cpp.o: + @CXX@ -c $< @DEFS@ -I$(INCDIR) @CXXFLAGS@ $(CXX_FLAGS) -O0 + +all: csvdiff + cp csvdiff ../../bin + +csvdiff: mdp_allo.o csvdiff.o tok_input_util.o + @CXX@ -o csvdiff mdp_allo.o csvdiff.o tok_input_util.o \ + $(LCXX_FLAGS) $(LCXX_END_LIBS) + +clean: + $(RM) *.o *.*~ csvdiff + +%.d: + @CXX@ -MM -I$(INCDIR) @CXXFLAGS@ $(CXX_FLAGS) $*.cpp > $*.d + +depends: $(DEPENDS) + cat *.d &> .depends + $(RM) $(DEPENDS) + +ifeq ($(wildcard .depends), .depends) +include .depends +endif diff --git a/tools/testtools/csvdiff.cpp b/tools/testtools/csvdiff.cpp new file mode 100644 index 000000000..b4eb04d05 --- /dev/null +++ b/tools/testtools/csvdiff.cpp @@ -0,0 +1,723 @@ +/*==================================================================== + * ------------------------ + * | CVS File Information | + * ------------------------ + * $RCSfile$ + * $Author$ + * $Date$ + * $Revision$ + * $Name$ + *====================================================================*/ +/* + * + * csvdiff File1.csv File2.csv + * + * Compares the variable values in two Excell formatted + * comma separated files. + * The comparison is done using a weighted norm basis. + * + * The two files should be basically equal. However, File1.csv is + * taken as the reference file, that has precedence, when there is + * something to be decided upon. + * + * Arguments: + * -h = prints this usage information + * + * Shell Return Values + * 1 = Comparison was successful + * 0 = One or more nodal values failed the comparison + * -1 = Apples to oranges, the files can not even be compared against + * one another. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "mdp_allo.h" +#include "tok_input_util.h" + +#ifndef TRUE +# define TRUE 1 +# define FALSE 0 +#endif + +#ifndef MAX +# define MAX(x,y) (( (x) > (y) ) ? (x) : (y)) +#endif +#ifndef MIN +# define MIN(x,y) (( (x) < (y) ) ? (x) : (y)) +#endif + +int Debug_Flag = TRUE; +double grtol = 1.0E-3; +double gatol = 1.0E-9; + +/* + * First iteration towards getting this variable + */ +int Max_Input_Str_Ln = MAX_INPUT_STR_LN; + +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ + +static int diff_double(double d1, double d2, double rtol, double atol) + +/* + * Compares 2 doubles. If they are not within tolerance, then this + * function returns true. + */ +{ + if (fabs(d1-d2) > (atol + rtol * 0.5 * (fabs(d1) + fabs(d2)))) return 1; + return 0; +} + +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ + +static double calc_rdiff(double d1, double d2, double rtol, double atol) + +/* + * Calculates the relative difference using a fuzzy comparison + */ + +{ + double rhs, lhs; + rhs = fabs(d1-d2); + lhs = atol + rtol * 0.5 * (fabs(d1) + fabs(d2)); + return (rhs/lhs); +} + +/*****************************************************************************/ +/* + * breakStrCommas(): + * This routine will break a character string into stringlets according + * to the placement of commas. The commas are replaced by null + * characters. + * + * Argument: + * str => original string. On exit, this string will have beent + * altered. + * strlets -> Vector of pointers to char *. The vector has a size + * larger than or equal to maxPieces. + * maxPieces -> largest number of pieces to divide the string into. + * + * Return: + * This returns the number of pieces that the string is actually + * broken up into. + */ + +static int breakStrCommas(char *str, char **strlets, int maxPieces) +{ + int numbreaks = 0; + if (strlets) { + strlets[0] = str; + if (str) { + char *cptr = str; + char *cetn = NULL; + do { + cetn = strchr(cptr, (int) ','); + if (cetn) { + numbreaks++; + cptr = cetn + 1; + strlets[numbreaks] = cptr; + *cetn = '\0'; + } + } while (cetn && (numbreaks < (maxPieces - 1))); + } + } + return numbreaks + 1; +} + +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ +#define LT_NULLLINE 0 +#define LT_TITLELINE 1 +#define LT_COLTITLE 2 +#define LT_DATALINE 3 +/* + * get_sizes() + * + * This routine obtains the sizes of the various elements of the file + * by parsing the file. + * (HKM: Note, this file could use some work. However, it's always + * going to be heuristic) + * + * Arguments: + * + * fp = File pointer + * nTitleLines = Number of title lines + * nColTitleLines = Number of column title lines + * nCol = Number of columns -> basically equal to the + * number of variabless + * nDataRows = Number of rows of data in the file + * + */ + +static void get_sizes(FILE *fp, int &nTitleLines, int &nColTitleLines, + int &nCol, int &nDataRows) +{ + int nScanLinesMAX = 100; + int nScanLines = nScanLinesMAX; + int retn, i, j; + int nLines = 0; + int maxCommas = 0; + TOKEN fieldToken; + char *scanLine = mdp_alloc_char_1(MAX_INPUT_STR_LN+1, '\0'); + int *numCommas = mdp_alloc_int_1(nScanLinesMAX, -1); + + /* + * Rewind the file + */ + rewind(fp); + /* + * Read the scan lines + */ + for (i = 0; i < nScanLinesMAX; i++) { + retn = read_line(fp, scanLine, 0); + if (retn == -1) { + nScanLines = i; + break; + } + /* + * Strip a trailing comma from the scanline - + * -> These are not significant + */ + int ccount = strlen(scanLine); + if (ccount > 0) { + if (scanLine[ccount-1] == ',') scanLine[ccount-1] = '\0'; + } + /* + * Count the number of commas in the line + */ + char *cptr = scanLine; + char *cetn = NULL; + numCommas[i] = 0; + do { + cetn = strchr(cptr, (int) ','); + if (cetn) { + numCommas[i]++; + cptr = cetn + 1; + } + } while (cetn); + if (i > 1) { + if ( maxCommas < numCommas[i]) maxCommas = numCommas[i]; + } + } + /* + * set a preliminary value of nCol + */ + nCol = maxCommas + 1; + char **strlets = (char **) mdp_alloc_ptr_1(maxCommas+1); + + int doingLineType = LT_TITLELINE; + rewind(fp); + for (i = 0; i < nScanLines; i++) { + retn = read_line(fp, scanLine, 0); + /* + * Strip a trailing comma from the scanline - + * -> These are not significant + */ + int ccount = strlen(scanLine); + if (ccount > 0) { + if (scanLine[ccount-1] == ',') scanLine[ccount-1] = '\0'; + } + int ncolsFound = breakStrCommas(scanLine, strlets, nCol); + + if (doingLineType == LT_TITLELINE) { + if (numCommas[i] == maxCommas) { + doingLineType = LT_COLTITLE; + nTitleLines = i; + } + } + + if (doingLineType == LT_COLTITLE) { + int goodDataLine = TRUE; + int rerr = FALSE; + for (j = 0; j < ncolsFound; j++) { + char *fieldStr = strlets[j]; + fillTokStruct(&fieldToken, fieldStr); + if (fieldToken.ntokes != 1) { + goodDataLine = FALSE; + break; + } + (void) tok_to_double(&fieldToken, DBL_MAX, + -DBL_MAX, 0.0, &rerr); + if (rerr) { + goodDataLine = FALSE; + break; + } + } + if (goodDataLine) { + doingLineType = LT_DATALINE; + } + nColTitleLines = i - nTitleLines; + } + if (doingLineType == LT_DATALINE) break; + } + + + /* + * Count the total number of lines in the file + */ + if (doingLineType == LT_DATALINE) { + for (i = nColTitleLines + nTitleLines; ; i++) { + retn = read_line(fp, scanLine, 0); + if (retn == -1) { + nLines = i+1; + nDataRows = i - nColTitleLines - nTitleLines + 1; + break; + } + /* + * Strip a trailing comma from the scanline - + * -> These are not significant + */ + int ccount = strlen(scanLine); + if (ccount > 0) { + if (scanLine[ccount-1] == ',') scanLine[ccount-1] = '\0'; + } + int ncolsFound = breakStrCommas(scanLine, strlets, nCol); + int goodDataLine = TRUE; + int rerr = FALSE; + for (j = 0; j < ncolsFound; j++) { + char *fieldStr = strlets[j]; + fillTokStruct(&fieldToken, fieldStr); + if (fieldToken.ntokes != 1) { + goodDataLine = FALSE; + break; + } + (void) tok_to_double(&fieldToken, DBL_MAX, + -DBL_MAX, 0.0, &rerr); + if (rerr) { + goodDataLine = FALSE; + break; + } + } + if (! goodDataLine) { + doingLineType = LT_NULLLINE; + nDataRows = i - nColTitleLines - nTitleLines + 1; + break; + } + } + } + mdp_safe_free((void **) &strlets); + mdp_safe_free((void **) &scanLine); + mdp_safe_free((void **) &numCommas); + return; +} + +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ + +static void +read_title(FILE *fp, char ***title, int nTitleLines) +{ + int retn; + *title = (char **) mdp_alloc_ptr_1(nTitleLines); + char *scanLine = mdp_alloc_char_1(Max_Input_Str_Ln + 1, '\0'); + for (int i = 0; i < nTitleLines ; i++) { + retn = read_line(fp, scanLine, 0); + if (retn >= 0) { + /* + * Strip a trailing comma from the scanline - + * -> These are not significant + */ + int ccount = strlen(scanLine); + if (ccount > 0) { + if (scanLine[ccount-1] == ',') scanLine[ccount-1] = '\0'; + } + *title[i] = mdp_copy_string(scanLine); + } + } + mdp_safe_free((void **) &scanLine); +} + +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ + +static void +read_colTitle(FILE *fp, char ****ColMLNames_ptr, int nColTitleLines, int nCol) +{ + int retn, j; + *ColMLNames_ptr = (char ***) mdp_alloc_ptr_1(nCol); + char ***ColMLNames = *ColMLNames_ptr; + char *scanLine = mdp_alloc_char_1(Max_Input_Str_Ln + 1, '\0'); + char **strlets = (char **) mdp_alloc_ptr_1(nCol+1); + for (int i = 0; i < nColTitleLines ; i++) { + retn = read_line(fp, scanLine, 0); + if (retn >= 0) { + /* + * Strip a trailing comma from the scanline - + * -> These are not significant + */ + int ccount = strlen(scanLine); + if (ccount > 0) { + if (scanLine[ccount-1] == ',') scanLine[ccount-1] = '\0'; + } + int ncolsFound = breakStrCommas(scanLine, strlets, nCol); + ColMLNames[i] = mdp_alloc_VecFixedStrings(nCol, MAX_TOKEN_STR_LN+1); + for (j = 0; j < ncolsFound; j++) { + strcpy(ColMLNames[i][j], strlets[j]); + } + } + } + mdp_safe_free((void **) &scanLine); + mdp_safe_free((void **) &strlets); +} + +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ + +static double get_atol(const double *values, const int nvals, + const double atol) +{ + int i; + double sum = 0.0, retn; + if (nvals <= 0) return gatol; + for (i = 0; i < nvals; i++) { + retn = values[i]; + sum += retn * retn; + } + sum /= nvals; + retn = sqrt(sum); + return ((retn + 1.0) * atol); +} + +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ + +static void +read_values(FILE *fp, double **NVValues, int nCol, int nDataRows) +{ + char **strlets = (char **) mdp_alloc_ptr_1(nCol+1); + char *scanLine = mdp_alloc_char_1(Max_Input_Str_Ln + 1, '\0'); + TOKEN fieldToken; + double value; + int retn, j; + for (int i = 0; i < nDataRows; i++) { + retn = read_line(fp, scanLine, 0); + if (retn == -1) { + break; + } + /* + * Strip a trailing comma from the scanline - + * -> These are not significant + */ + int ccount = strlen(scanLine); + if (ccount > 0) { + if (scanLine[ccount-1] == ',') scanLine[ccount-1] = '\0'; + } + int ncolsFound = breakStrCommas(scanLine, strlets, nCol); + int goodDataLine = TRUE; + int rerr = FALSE; + for (j = 0; j < ncolsFound; j++) { + char *fieldStr = strlets[j]; + fillTokStruct(&fieldToken, fieldStr); + if (fieldToken.ntokes != 1) { + goodDataLine = FALSE; + break; + } + value = tok_to_double(&fieldToken, DBL_MAX, + -DBL_MAX, 0.0, &rerr); + if (rerr) { + goodDataLine = FALSE; + break; + } + NVValues[j][i] = value; + } + if (! goodDataLine) { + break; + } + } + mdp_safe_free((void **) &strlets); + mdp_safe_free((void **) &scanLine); +} +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ + +static void print_usage() { + printf("\t\n"); + printf(" csvdiff [-h] File1.csv File2.csv\n"); + printf("\t\n"); + printf("\tCompares the variable values in two Excell formatted " + "comma separated files.\n"); + printf("\tThe comparison is done using a weighted norm basis.\n"); + printf("\t\n"); + printf("\tThe two files should be basically equal. However, File1.csv is\n"); + printf("\ttaken as the reference file, that has precedence, when there is\n"); + printf("\tsomething to be decided upon.\n"); + printf("\t\n"); + printf("\t Arguments:\n"); + printf("\t -h = Usage info\n"); + printf("\t\n"); + printf("\t Shell Return Values:\n"); + printf("\t 1 = Comparison was successful\n"); + printf("\t 0 = One or more nodal values failed the comparison\n"); + printf("\t -1 = Apples to oranges, the files can not even be compared against\n"); + printf("\t one another.\n"); + printf("\t\n"); +} +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ + +int main(int argc, char *argv[]) + + /* + * main driver for csvdiff. + */ +{ + int opt_let; + char *fileName1=NULL, *fileName2=NULL; /* Names of the csv files */ + FILE *fp1=NULL, *fp2=NULL; + int nTitleLines1, nTitleLines2; + int nColTitleLines1, nColTitleLines2; + int nCol1, nCol2, nColMAX, nColcomparisons; + int nDataRows1, nDataRows2; + char **title1, **title2; + int **compColList = NULL; + char ***ColMLNames1 = NULL, ***ColMLNames2 = NULL; + char **ColNames1 = NULL, **ColNames2 = NULL; + double **NVValues1 = NULL, **NVValues2 = NULL; + double *curVarValues1, *curVarValues2; + int mixed_var = 0; + int i, j, ndiff, jmax, i1, i2, k, found; + double max_diff, rel_diff; + int testPassed = 1; + double atol_j; + + /********************** BEGIN EXECUTION ************************************/ + + /* + * Interpret command line arguments + */ + /* Loop over each command line option */ + while((opt_let = getopt(argc, argv, "h")) != EOF) { + + /* case over the option letter */ + switch(opt_let) { + + case 'h': + /* Usage info was requested */ + print_usage(); + exit(0); + + default: + /* Default case. Error on unknown argument. */ + fprintf(stderr, "ERROR in command line usuage:\n"); + print_usage(); + return 0; + } /* End "switch(opt_let)" */ + + } /* End "while((opt_let=getopt(argc, argv, "i")) != EOF)" */ + if (optind != argc-2) { + print_usage(); + exit(-1); + } else { + fileName1 = argv[argc-2]; + fileName2 = argv[argc-1]; + } + + /* + * Print Out Header + */ + printf("\n"); + printf("----------------------------------------------------------\n"); + printf("csvdiff: CSVFile comparison utility program\n"); + printf(" Version $Revision$\n"); + printf(" Harry K. Moffat Div. 9114 Sandia National Labs\n"); + printf(" \n"); + printf(" First CSV File = %s\n", fileName1); + printf(" Second CSV file = %s\n", fileName2); + printf("----------------------------------------------------------\n"); + printf("\n"); + + /* + * Open up the two ascii Files #1 and #2 + */ + if (!(fp1 = fopen(fileName1, "r"))) { + fprintf(stderr,"Error opening up file1, %s\n", fileName1); + exit(-1); + } + if (!(fp2 = fopen(fileName2, "r"))) { + fprintf(stderr, "Error opening up file2, %s\n", fileName2); + exit(-1); + } + + /* + * Obtain the size of the problem information: Compare between files. + */ + + get_sizes(fp1, nTitleLines1, nColTitleLines1, nCol1, nDataRows1); + + get_sizes(fp2, nTitleLines2, nColTitleLines2, nCol2, nDataRows2); + + + if (nTitleLines1 != nTitleLines2) { + printf("Number o Title Lines differ:, %d %d\n",nTitleLines1, nTitleLines2); + } else if (Debug_Flag) { + printf("Number of Title Lines in each file = %d\n", nTitleLines1); + } + if (nColTitleLines1 != nColTitleLines2) { + printf("Number of Column title lines differ:, %d %d\n", nColTitleLines1, + nColTitleLines2); + } else if (Debug_Flag) { + printf("Number of column title lines in each file = %d\n", nColTitleLines1); + } + + /* + * Right now, if the number of data rows differ, we will punt. + * Maybe later we can do something more significant + */ + if (nDataRows1 != nDataRows2) { + printf("Number of Data rows in file1, %d, is different than file2, %d\n", + nDataRows1, nDataRows2); + exit(-1); + } + + rewind(fp1); + rewind(fp2); + read_title(fp1, &title1, nTitleLines1); + read_title(fp2, &title2, nTitleLines2); + + if (strcmp(title1[0], title2[0]) != 0) { + printf("Titles differ:\n\t\"%s\"\n\t\"%s\"\n", title1[0], title2[0]); + } else if (Debug_Flag) { + printf("Title for each file: \"%s\"\n", title1[0]); + } + + /* + * Get the number of column variables in each file + */ + + mixed_var = FALSE; + if (nCol1 != nCol2) { + printf("Number of column variables differ:, %d %d\n", + nCol1, nCol2); + mixed_var = TRUE; + } else if (Debug_Flag) { + printf("Number of column variables in both files = %d\n", + nCol1); + } + + /* + * Read the names of the column variables + */ + read_colTitle(fp1, &ColMLNames1, nColTitleLines1, nCol1); + read_colTitle(fp2, &ColMLNames2, nColTitleLines2, nCol2); + ColNames1 = ColMLNames1[0]; + ColNames2 = ColMLNames2[0]; + + /* + * Do a Comparison of the names to find the maximum number + * of matches. + */ + nColMAX = MAX(nCol1, nCol2); + + compColList = mdp_alloc_int_2(nColMAX, 2, -1); + nColcomparisons = 0; + for (i = 0; i < nCol1; i++) { + found = FALSE; + for (j = 0; j < nCol2; j++) { + if (!strcmp(ColNames1[i], ColNames2[j])) { + compColList[nColcomparisons][0] = i; + compColList[nColcomparisons][1] = j; + nColcomparisons++; + found = TRUE; + if (i != j) mixed_var = 1; + break; + } + } + if (!found) { + printf("csvdiff WARNING Variable %s (%d) in first file not found" + " in second file\n", ColNames1[i], i); + } + } + for (j = 0; j < nCol2; j++) { + found = FALSE; + for (i = 0; i < nColcomparisons; i++) { + if (compColList[i][1] == j) found = TRUE; + } + if (! found) { + printf("csvdiff WARNING Variable %s (%d) in second file " + "not found in first file\n", + ColNames2[j], j); + } + } + + /* + * Allocate storage for the column variables + */ + NVValues1 = mdp_alloc_dbl_2(nCol1, nDataRows1, 0.0); + NVValues2 = mdp_alloc_dbl_2(nCol2, nDataRows2, 0.0); + + /* + * Read in the values to the arrays + */ + read_values(fp1, NVValues1, nCol1, nDataRows1); + read_values(fp2, NVValues2, nCol2, nDataRows2); + + /* + * Compare the solutions in each file + */ + + for (k = 0; k < nColcomparisons; k++) { + + i1 = compColList[k][0]; + i2 = compColList[k][1]; + curVarValues1 = NVValues1[i1]; + curVarValues2 = NVValues2[i2]; + max_diff = 0.0; + ndiff = 0; + atol_j = get_atol(curVarValues1, nDataRows1, gatol); + atol_j = MAX(atol_j, get_atol(curVarValues2, nDataRows2, gatol)); + for (j = 0; j < nDataRows1; j++) { + if (diff_double(curVarValues1[j], curVarValues2[j], grtol, atol_j)) { + ndiff++; + rel_diff = calc_rdiff((double) curVarValues1[j], + (double) curVarValues2[j], grtol, atol_j); + if (rel_diff > max_diff) { + jmax = j; + max_diff = rel_diff; + } + if (ndiff < 10) { + printf("\tColumn variable %s at data row %d ", ColNames1[i1], j); + printf(" differ: %g %g\n", curVarValues1[j], + curVarValues2[j]); + } + } + } + + /* + * Print out final results of nodal variable test + */ + + if (ndiff > 0) { + printf( + "Column variable %s failed comparison test for %d occurances\n", + ColNames1[i1], ndiff); + printf(" Largest difference was at data row %d ", jmax); + printf(": %g %g\n", curVarValues1[jmax], curVarValues2[jmax]); + testPassed = 0; + } else if (Debug_Flag) { + printf("Column variable %s passed\n", ColNames1[i1]); + } + } + + + return(testPassed); + +} /************END of main() *************************************************/ +/*****************************************************************************/ diff --git a/tools/testtools/mdp_allo.cpp b/tools/testtools/mdp_allo.cpp new file mode 100644 index 000000000..7acbf94ce --- /dev/null +++ b/tools/testtools/mdp_allo.cpp @@ -0,0 +1,1454 @@ +/* +****************************************************************************** +* $RCSfile$ +* $Author$ +* $Date$ +* $Revision$ +* $Name$ +****************************************************************************** +*/ + +#include +#include +#include + +#include +#include + +#include "mdp_allo.h" + +/* + * Allocate global storage for 2 debugging ints that are used in IO of + * error information. + */ +#ifdef MDP_MPDEBUGIO +int MDP_MP_Nprocs = 1; +int MDP_MP_myproc = 0; +#endif +/* + * Error Handling + * 7 print and exit + * 6 exit + * 5 print and create a divide by zero for stack trace analysis. + * 4 create a divide by zero for stack trace analysis. + * 3 print a message and throw the bad_alloc exception. + * 2 throw the bad_alloc exception and be quite + * 1 print a message and return from package with the NULL pointer + * 0 Keep completely silent about the matter and return with + * a null pointer. + * + * -> Right now, the only way to change this option is to right here + */ +int MDP_ALLO_errorOption = 3; + +#ifndef MIN +# define MIN(x,y) (( (x) < (y) ) ? (x) : (y)) +#endif +#ifndef MAX +# define MAX(x,y) (( (x) > (y) ) ? (x) : (y)) +#endif + +#define MDP_ALLOC_INTERFACE_ERROR -230346 + +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +static void mdp_alloc_eh(const char *rname, int bytes) + + /************************************************************************* + * + * mdp_alloc_eh: + * + * Error Handling + * 7 print and exit + * 6 exit + * 5 print and create a divide by zero for stack trace analysis. + * 4 create a divide by zero for stack trace analysis. + * 3 print a message and throw the bad_alloc exception. + * 2 throw the bad_alloc exception and be quite + * 1 print a message and return from package with the NULL pointer + * 0 Keep completely silent about the matter and return with + * a null pointer. + **************************************************************************/ +{ + double cd = 0.0; + static char mesg[64]; + if (bytes == MDP_ALLOC_INTERFACE_ERROR) { +#ifdef MDP_MPDEBUGIO + sprintf(mesg,"MDP_ALLOC Interface ERROR P_%d: %s", MDP_MP_my_proc, + rname); +#else + sprintf(mesg,"MDP_ALLOC Interface ERROR: %s", rname); +#endif + } else { + sprintf(mesg,"%s ERROR: out of memory while mallocing %d bytes", + rname, bytes); + } + if (MDP_ALLO_errorOption % 2 == 1) { + fprintf(stderr, "\n%s", mesg); +#ifdef MDP_MPDEBUGIO + if (MDP_MP_Nprocs > 1) { + fprintf(stderr,": proc = %d\n", MDP_MP_myproc); + } else { + fprintf(stderr,"\n"); + } +#else + fprintf(stderr,"\n"); +#endif + } + fflush(stderr); + if (MDP_ALLO_errorOption == 2 || MDP_ALLO_errorOption == 3) { + throw std::bad_alloc(); + } + if (MDP_ALLO_errorOption == 4 || MDP_ALLO_errorOption == 5) cd = 1.0 / cd; + if (MDP_ALLO_errorOption > 5) exit(-1); +} + +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +static void mdp_alloc_eh2(const char * rname) + + /************************************************************************* + * + * mdp_alloc_eh2: + * + * Second Level Error Handling + * This routine is used at the second level. + * It will be triggered after mdp_allo_eh() has + * been triggered. Thus, it only needs to deal with 1 -> print mess + * + * 3 create a divide by zero for stack trace analysis. + * 2 or above -> + * 1 print a message and return with the NULL pointer + * 0 Keep completely silent about the matter. + **************************************************************************/ +{ + if (MDP_ALLO_errorOption == 1) { + fprintf(stderr,"%s ERROR: returning with null pointer", rname); +#ifdef MDP_MPDEBUGIO + if (MDP_MP_Nprocs > 1) { + fprintf(stderr,": proc = %d", MDP_MP_myproc); + } +#endif + fprintf(stderr,"\n"); + } +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +#define Fprintf (void) fprintf + +/****************************************************************************/ +#ifndef HAVE_ARRAY_ALLOC +/****************************************************************************/ +static double *smalloc(size_t n); + +/***************************************************************************** + * + * Dynamic Allocation of Multidimensional Arrays + *---------------------------------------------------------------------------- + * + * Example Usage: + * + * typedef struct + * { int bus1; + * int bus2; + * int dest; + * } POINT; + * + * POINT **points, corner; + * + * points = (POINT **) array_alloc (2, x, y, sizeof(POINT)); + * ^ ^ ^ + * | | | + * number of dimensions--+ | | + * | | + * first dimension max----+ | + * | + * second dimension max------+ + * + * (points may be now be used as if it were declared + * POINT points[x][y]) + * + * This particular version is limited to dimensions of 3 or less. + * + * corner = points[2][3]; (refer to the structure as you would any array) + * + * free (points); (frees the entire structure in one fell swoop) + * + ****************************************************************************/ +/***************************************************************************** +* The following section is a commented section containing +* an example main code: +****************************************************************************** +*double *array_alloc(); +*main() +*{ +* int ***temp; +* int *temp2; +* int i, j, k; +* int il, jl, kl; +* +* malloc_debug(2); +* il = 2; +* jl = 3; +* kl = 3; +* temp = (int ***) array_alloc(3,il,jl,kl,sizeof(int)); +* for (i=0; i 4) { + Fprintf(stderr, + "mdp_array_alloc ERROR: number of dimensions, %d, is > 4\n", + numdim); + return NULL; + } + + dim[0].index = va_arg(va, int); + + if (dim[0].index <= 0) { +#ifdef DEBUG + Fprintf(stderr, "WARNING: mdp_array_alloc called with first " + "dimension <= 0, %d\n\twill return the nil pointer\n", + (int) (dim[0].index)); +#endif + return((double *) NULL); + } + + dim[0].total = dim[0].index; + dim[0].size = sizeof(void *); + dim[0].off = 0; + for (i = 1; i < numdim; i++) { + dim[i].index = va_arg(va, int); + if (dim[i].index <= 0) { + Fprintf(stderr, + "WARNING: mdp_array_alloc called with dimension %d <= 0, " + "%d\n", i+1, (int) (dim[i].index)); + Fprintf(stderr, "\twill return the nil pointer\n"); + return((double *) NULL); + } + dim[i].total = dim[i-1].total * dim[i].index; + dim[i].size = sizeof(void *); + dim[i].off = dim[i-1].off + dim[i-1].total * dim[i-1].size; + } + + dim[numdim-1].size = va_arg(va, int); + va_end(va); + + /* + * Round up the last offset value so data is properly aligned. + */ + + dim[numdim-1].off = dim[numdim-1].size * + ((dim[numdim-1].off+dim[numdim-1].size-1)/dim[numdim-1].size); + + total = dim[numdim-1].off + dim[numdim-1].total * dim[numdim-1].size; + + dfield = (double *) smalloc((size_t) total); + field = (char *) dfield; + + for (i = 0; i < numdim - 1; i++) { + ptr = (char **) (field + dim[i].off); + data = (char *) (field + dim[i+1].off); + for (j = 0; j < dim[i].total; j++) { + ptr[j] = data + j * dim[i+1].size * dim[i+1].index; + } + } + + return dfield; +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +static double *smalloc(size_t n) + + /************************************************************************** + * smalloc: safe version of malloc + * + * This version of smalloc assigns space in even chunks of 8 bytes only + **************************************************************************/ +{ +#ifdef MDP_MEMDEBUG + static int firsttime = 1; + FILE *file; +#endif + double *pntr; + if (n < 0) { + Fprintf(stderr, "smalloc ERROR: Non-positive argument. (%d)\n", n); + return NULL; + } + else if (n == 0) pntr = NULL; + else { + n = ((n - 1) / 8); + n = (n + 1) * 8; + pntr = (double *) malloc((size_t) n); + } + if (pntr == NULL && n != 0) { + Fprintf(stderr, "smalloc : Out of space - number of bytes " + "requested = %d\n", n); + } +#ifdef MDP_MEMDEBUG + if (firsttime) { + firsttime = 0; + file = fopen("memops.txt", "w"); + } else { + file = fopen("memops.txt", "a"); + } + Fprintf(file, "%x %d malloc\n", pntr, n); + if ( (int) pntr == 0x00000001) { + Fprintf(stderr, "FOUND IT!\n"); + exit(-1); + } + fclose(file); +#endif + return pntr; +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +void mdp_safe_free (void **ptr) + + /************************************************************************* + * + * mdp_safe_free(): + * + * This version of free calls the system's free function + * with maximum error checking. It also doesn't call free if ptr is + * the NULL pointer already. + * It will then set the freed pointer to NULL. Thus, a convention may + * be established wherein all pointers that can be malloced can be + * set to NULL if they are not malloced. + **************************************************************************/ +{ +#ifdef MDP_MEMDEBUG + FILE *file; +#endif + if (ptr == NULL) { + mdp_alloc_eh("mdp_safe_free: handle is NULL", MDP_ALLOC_INTERFACE_ERROR); + } + if (*ptr != NULL) { +#ifdef MDP_MEMDEBUG + file = fopen("memops.txt", "a"); + Fprintf(file, "%x free\n", *ptr); + fflush(file); + if ( (int) *ptr == 0x00000001) { + Fprintf(stderr, "FOUND IT!\n"); + exit(-1); + } + fclose(file); +#endif + free(*ptr); + /* + * Set the value of ptr to NULL, so that further references + * to it will be flagged. + */ + *ptr = NULL; + } +} +/****************************************************************************/ +#endif +/***************************************************************************** +* +* Wrapper Functions +* -------------------- +* +* The function definitions below are wrappers around array_alloc for +* common operations. The following principles are followed: +* +* Argument dimensions le 0 are increased to 1 before calling array_alloc. +* Thus, something is always malloced during a call. The reason for this is +* that it minimizes the number of special cases in the calling program. +* +* A pointer to something else other than NULL indicates that that pointer +* has been previously malloced. Thus, it can be freed. Note, after a free +* operation, this package always sets the pointer to NULL before returning. +* +* "safe_alloc" routines try to free the pointer if nonNULL, before calling +* the base alloc_int_#() routines. +* +* The regular routines always initialize the previously malloced space. +* +*****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +int *mdp_alloc_int_1(int nvalues, const int val) + + /************************************************************************** + * + * mdp_alloc_int_1: + * + * Allocate and initialize a one dimensional array of integers. + * + * Input + * ------- + * nvalues = Length of the array + * val = intialization value + * Return + * ------ + * Pointer to the intialized integer array + * Failures are indicated by returning the NULL pointer. + **************************************************************************/ +{ + int *array; + if (nvalues <= 0) nvalues = 1; + array= (int *) mdp_array_alloc(1, nvalues, sizeof(int)); + if (array != NULL) { + if (val != MDP_INT_NOINIT) { + if (val == 0) { + (void) memset(array, 0, sizeof(int)*nvalues); + } else { + for (int i = 0; i < nvalues; i++) array[i] = val; + } + } + } else { + mdp_alloc_eh("mdp_alloc_int_1", nvalues * sizeof(int)); + } + return array; +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +void mdp_safe_alloc_int_1(int **array_hdl, int nvalues, const int val) + + /************************************************************************* + * + * mdp_safe_alloc_int_1: + * + * Allocates and/or initializse a one dimensional array of integers. + * + * Input + * ------- + * *array_hdl = Previous value of pointer. If non-NULL will try + * to free the memory at this address. + * nvalues = Length of the array + * val = intialization value + * Output + * ------ + * *array_hdl = This value is initialized to the correct address + * of the array. + * A NULL value in the position indicates an error. + **************************************************************************/ +{ + if (array_hdl == NULL) { + mdp_alloc_eh("mdp_safe_alloc_int_1: handle is NULL", + MDP_ALLOC_INTERFACE_ERROR); + return; + } + if (*array_hdl != NULL) mdp_safe_free((void **) array_hdl); + *array_hdl = mdp_alloc_int_1(nvalues, val); + if (*array_hdl == NULL) mdp_alloc_eh2("mdp_safe_alloc_int_1"); +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +void +mdp_realloc_int_1(int **array_hdl, int new_length, int old_length, + const int defval) + + /************************************************************************* + * + * mdp_realloc_int_1_(array_hdl, new_num_ptrs, old_num_ptrs); + * + * Reallocates a one dimensional array of ints. + * This routine always allocates space for at least one int. + * Calls the smalloc() routine to ensure that all malloc + * calls go through one location. This routine will then copy + * the pertinent information from the old array to the + * new array. + * + * Input + * ------- + * array_hdl = Pointer to the global variable that + * holds the old and (eventually new) + * address of the array of integers to be reallocated + * new_length = Length of the array + * old_length = Length of the old array + **************************************************************************/ +{ + if (new_length == old_length) return; + if (new_length <= 0) { +#ifdef MDP_MPDEBUGIO + fprintf(stderr, + "Warning: mdp_realloc_int_1 P_%d: called with n = %d ", + MDP_MP_myproc, new_length); +#else + fprintf(stderr, + "Warning: mdp_realloc_int_1: called with n = %d ", + new_length); +#endif + new_length = 1; + } + if (old_length < 0) old_length = 0; + if (new_length == old_length) return; + size_t bytenum = new_length * sizeof(int); + int *array = (int *) smalloc(bytenum); + if (array != NULL) { + if (*array_hdl) { + if (old_length > 0) bytenum = sizeof(int) * old_length; + else bytenum = 0; + if (new_length < old_length) bytenum = sizeof(int) * new_length; + (void) memcpy((void *) array, (void *) *array_hdl, bytenum); + mdp_safe_free((void **) array_hdl); + } else { + old_length = 0; + } + *array_hdl = array; + if ((defval != MDP_INT_NOINIT) && (new_length > old_length)) { + if (defval == 0) { + bytenum = sizeof(int) * (new_length - old_length); + (void) memset((void *)(array+old_length), 0, bytenum); + } else { + for (int i = old_length; i < new_length; i++) { + array[i] = defval; + } + } + } + } else { + mdp_alloc_eh("mdp_realloc_int_1", bytenum); + } +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +int **mdp_alloc_int_2(int ndim1, int ndim2, const int val) + + /************************************************************************* + * + * mdp_alloc_int_2: + * + * Allocate and initialize a two dimensional array of ints. + * + * Input + * ------- + * ndim1 = Length of the first dimension of the array + * ndim2 = Length of the second dimension of the array + * val = intialization value + * Return + * ------ + * Pointer to the intialized integer array + * Failures are indicated by returning the NULL pointer. + **************************************************************************/ +{ + int i; + int **array, *dptr; + if (ndim1 <= 0) ndim1 = 1; + if (ndim2 <= 0) ndim2 = 1; + array = (int **) mdp_array_alloc(2, ndim1, ndim2, sizeof(int)); + if (array != NULL) { + if (val != MDP_INT_NOINIT) { + if (val == 0) { + (void) memset((void *) array[0], 0, ndim1 * ndim2 * sizeof(int)); + } else { + dptr = &(array[0][0]); + for (i = 0; i < ndim1 * ndim2; i++) dptr[i] = val; + } + } + } else { + mdp_alloc_eh("mdp_alloc_int_2", + sizeof(int) * ndim1 * ndim2 + + ndim1 * sizeof(void *)); + } + return array; +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +double *mdp_alloc_dbl_1(int nvalues, const double val) + + /************************************************************************* + * + * mdp_alloc_dbl_1: + * + * Allocate and initialize a one dimensional array of doubles. + * + * Input + * ------- + * nvalues = Length of the array + * val = intialization value + * Return + * ------ + * Pointer to the intialized integer array + * Failures are indicated by returning the NULL pointer. + **************************************************************************/ +{ + int i; + double *array; + if (nvalues <= 0) nvalues = 1; + array = (double *) mdp_array_alloc(1, nvalues, sizeof(double)); + if (array != NULL) { + if (val != MDP_DBL_NOINIT) { + if (val == 0.0) { + (void) memset((void *) array, 0, nvalues * sizeof(double)); + } else { + for (i = 0; i < nvalues; i++) array[i] = val; + } + } + } else { + mdp_alloc_eh("mdp_alloc_dbl_1", nvalues * sizeof(double)); + } + return array; +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +void mdp_safe_alloc_dbl_1(double **array_hdl, int nvalues, const double val) + + /************************************************************************* + * + * mdp_safe_alloc_dbl_1: + * + * Allocates and/or initializse a one dimensional array of doubles. + * + * Input + * ------- + * *array_hdl = Previous value of pointer. If non-NULL will try + * to free the memory at this address. + * nvalues = Length of the array + * val = intialization value + * Output + * ------ + * *array_hdl = This value is initialized to the correct address + * of the array. + * A NULL value in the position indicates an error. + **************************************************************************/ +{ + if (array_hdl == NULL) { + mdp_alloc_eh("mdp_safe_alloc_dbl_1: handle is NULL", + MDP_ALLOC_INTERFACE_ERROR); + return; + } + if (*array_hdl != NULL) mdp_safe_free((void **) array_hdl); + *array_hdl = mdp_alloc_dbl_1(nvalues, val); + if (*array_hdl == NULL) mdp_alloc_eh2("mdp_safe_alloc_dbl_1"); +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +void mdp_realloc_dbl_1(double **array_hdl, int new_length, + int old_length, const double defval) + + /************************************************************************* + * + * mdp_realloc_dbl_1_(array_hdl, new_num_ptrs, old_num_ptrs); + * + * Reallocates a one dimensional array of doubles. + * This routine always allocates space for at least one dbl. + * Calls the smalloc() routine to ensure that all malloc + * calls go through one location. This routine will then copy + * the pertinent information from the old array to the + * new array. + * + * Input + * ------- + * array_hdl = Pointer to the global variable that + * holds the old and (eventually new) + * address of the array of doubles to be reallocated + * new_length = Length of the array + * old_length = Length of the old array + **************************************************************************/ +{ + if (new_length == old_length) return; + if (new_length <= 0) { +#ifdef MDP_MPDEBUGIO + fprintf(stderr, "Warning: mdp_realloc_dbl_1 P_%d: called with n = %d ", + MDP_MP_myproc, new_length); +#else + fprintf(stderr, "Warning: mdp_realloc_dbl_1: called with n = %d ", + new_length); +#endif + new_length = 1; + } + if (old_length < 0) old_length = 0; + if (new_length == old_length) return; + size_t bytenum = new_length * sizeof(double); + double *array = (double *) smalloc(bytenum); + if (array != NULL) { + if (*array_hdl) { + if (old_length > 0) bytenum = sizeof(double) * old_length; + else bytenum = 0; + if (new_length < old_length) bytenum = sizeof(double) * new_length; + (void) memcpy((void *) array, (void *) *array_hdl, bytenum); + mdp_safe_free((void **) array_hdl); + } else { + old_length = 0; + } + *array_hdl = array; + if ((defval != MDP_DBL_NOINIT) && (new_length > old_length)) { + if (defval == 0) { + bytenum = sizeof(double) * (new_length - old_length); + (void) memset((void *)(array+old_length), 0, bytenum); + } else { + for (int i = old_length; i < new_length; i++) { + array[i] = defval; + } + } + } + } else { + mdp_alloc_eh("mdp_realloc_dbl_1", bytenum); + } +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +char *mdp_alloc_char_1(int nvalues, const char val) + + /************************************************************************* + * + * mdp_alloc_char_1: + * + * Allocate and initialize a one dimensional array of characters. + * + * Input + * ------- + * nvalues = Length of the array + * val = intialization value + * Return + * ------ + * Pointer to the intialized character array + * Failures are indicated by returning the NULL pointer. + **************************************************************************/ +{ + int i; + char *array; + if (nvalues <= 0) nvalues = 1; + array = (char *) mdp_array_alloc(1, nvalues, sizeof(char)); + if (array != NULL) { + for (i = 0; i < nvalues; i++) array[i] = val; + } else { + mdp_alloc_eh("mdp_alloc_char_1", nvalues * sizeof(char)); + } + return array; +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +void mdp_safe_alloc_char_1(char **array_hdl, int nvalues, const char val) + + /************************************************************************* + * + * mdp_safe_alloc_char_1: + * + * Allocates and/or initializse a one dimensional array of characters. + * + * Input + * ------- + * array_hdl = Previous value of pointer. If non-NULL will try + * to free the memory at this address. + * nvalues = Length of the array + * val = intialization value + * Output + * ------ + * *array_hdl = This value is initialized to the correct address + * of the array. + * A NULL value in the position indicates an error. + **************************************************************************/ +{ + if (array_hdl == NULL) { + mdp_alloc_eh("mdp_safe_alloc_char_1: handle is NULL", + MDP_ALLOC_INTERFACE_ERROR); + return; + } + if (*array_hdl != NULL) mdp_safe_free((void **) array_hdl); + *array_hdl = mdp_alloc_char_1(nvalues, val); + if (*array_hdl == NULL) mdp_alloc_eh2("mdp_safe_alloc_char_1"); +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +double **mdp_alloc_dbl_2(int ndim1, int ndim2, const double val) + + /************************************************************************* + * + * mdp_alloc_dbl_2: + * + * Allocate and initialize a two dimensional array of doubles. + * + * Input + * ------- + * ndim1 = Length of the first dimension of the array + * ndim2 = Length of the second dimension of the array + * val = intialization value + * Return + * ------ + * Pointer to the intialized integer array + * Failures are indicated by returning the NULL pointer. + **************************************************************************/ +{ + int i; + double **array, *dptr; + if (ndim1 <= 0) ndim1 = 1; + if (ndim2 <= 0) ndim2 = 1; + array = (double **) mdp_array_alloc(2, ndim1, ndim2, sizeof(double)); + if (array != NULL) { + if (val != MDP_DBL_NOINIT) { + if (val == 0.0) { + (void) memset((void *) array[0], 0, ndim1*ndim2 * sizeof(double)); + } else { + dptr = &(array[0][0]); + for (i = 0; i < ndim1*ndim2; i++) dptr[i] = val; + } + } + } else { + mdp_alloc_eh("mdp_alloc_dbl_2", + sizeof(double) * ndim1 * ndim2 + + ndim1 * sizeof(void *)); + } + return array; +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +void mdp_safe_alloc_dbl_2(double ***array_hdl, int ndim1, int ndim2, + const double val) + + /************************************************************************* + * + * mdp_safe_alloc_dbl_2: + * + * Allocate and initialize a two dimensional array of doubles. + * + * Input + * ------- + * *array_hdl = Previous value of pointer. If non-NULL will try + * to free the memory at this address. + * ndim1 = Length of the array + * ndim2 = Length of inner loop of the array + * val = intialization value + * Return + * ------ + * *array_hdl = This value is initialized to the correct address + * of the array. + * A NULL value in the position indicates an error. + **************************************************************************/ +{ + if (array_hdl == NULL) { + mdp_alloc_eh("mdp_safe_alloc_dbl_2: handle is NULL", + MDP_ALLOC_INTERFACE_ERROR); + return; + } + if (*array_hdl != NULL) mdp_safe_free((void **) array_hdl); + *array_hdl = mdp_alloc_dbl_2(ndim1, ndim2, val); + if (*array_hdl == NULL) mdp_alloc_eh2("mdp_safe_alloc_dbl_2"); +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +void mdp_realloc_dbl_2(double ***array_hdl, int ndim1, int ndim2, + int ndim1Old, int ndim2Old, const double val) + + /************************************************************************* + * + * mdp_realloc_dbl_2: + * + * mdp_realloc_dbl_2(array_hdl, int ndim1, int ndim2, + * int ndim1Old, int ndim2Old, const double val) + * + * Reallocates a two dimensional array of doubles. + * This routine will then copy the pertinent information from + * the old array to the new array. + * + * If both old dimensions are set to zero or less, then this routine + * will free the old memory before mallocing the new memory. This may + * be a benefit for extremely large mallocs. + * In all other cases, the new and the old malloced arrays will + * exist for a short time together. + * + * Input + * ------- + * array_hdl = Pointer to the global variable that + * holds the old and (eventually new) + * address of the array of doubles to be reallocated + * ndim1 = First dimension of the new array + * ndim2 = Second dimension of the new array + * ndim1Old = First dimension of the old array + * ndim2Old = Second dimension of the old array + * val = Default fill value. + **************************************************************************/ +{ + if (ndim1 <= 0) ndim1 = 1; + if (ndim2 <= 0) ndim2 = 1; + ndim1Old = MAX(ndim1Old, 0); + ndim2Old = MAX(ndim2Old, 0); + /* + * One way to do it, if old information isn't needed. In this algorithm + * the arrays are never malloced at the same time. + */ + if ((*array_hdl == NULL) || (ndim1Old <= 0 && ndim2Old <= 0)) { + mdp_safe_free((void **) array_hdl); + *array_hdl = mdp_alloc_dbl_2(ndim1, ndim2, val); + if (*array_hdl == NULL) mdp_alloc_eh2("mdp_realloc_dbl_2"); + } + /* + * Other way to do when old information is available and needed + */ + else { + double **array_old = *array_hdl; + *array_hdl = (double **) mdp_array_alloc(2, ndim1, ndim2, sizeof(double)); + if (*array_hdl == NULL) { + mdp_alloc_eh2("mdp_realloc_dbl_2"); + } else { + /* + * Now, let's initialize the arrays + */ + int ndim1Min = MIN(ndim1, ndim1Old); + int ndim2Min = MIN(ndim2, ndim2Old); + double **array_new = *array_hdl; + /* + * When the second dimensions are equal, we can copy blocks + * using the very efficient bit moving kernels. + */ + if (ndim2 == ndim2Old) { + size_t sz = ndim1Min * ndim2 * sizeof(double); + (void) memcpy((void *) array_new[0], (void *) array_old[0], sz); + } + /* + * If the second dimensions aren't equal, then we have to + * break up the bit operations even more + */ + else { + size_t sz = ndim2Min * sizeof(double); + size_t sz2 = (ndim2 - ndim2Min) * sizeof(double); + for (int i = 0; i < ndim1Min; i++) { + (void) memcpy((void *) array_new[i], (void *) array_old[i], sz); + if (ndim2 > ndim2Min && val != MDP_DBL_NOINIT) { + if (val == 0.0) { + (void) memset((void *) (array_new[i] + ndim2Min), 0, sz2); + } else { + double *dptr = array_new[i]; + for (int j = ndim2Min; j < ndim2; j++) dptr[j] = val; + } + } + } + } + /* + * finish up initializing the rest of the array + */ + if (ndim1 > ndim1Min && val != MDP_DBL_NOINIT) { + if (val == 0.0) { + size_t sz = (ndim1 - ndim1Min) * ndim2 * sizeof(double); + (void) memset((void *) array_new[ndim1Min], 0, sz); + } else { + double *dptr = array_new[ndim1Min]; + int num = (ndim1 - ndim1Min) * ndim2; + for (int i = 0; i < num; i++) { + dptr[i] = val; + } + } + } + /* + * Free the old array + */ + mdp_safe_free((void **) &array_old); + } + } +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +char **mdp_alloc_VecFixedStrings(int numStrings, int lenString) + + /************************************************************************* + * + * mdp_alloc_VecFixedStrings: + * + * Allocate and initialize a vector of fixed-length + * strings. Each string is initialized to the NULL string. + * + * Input + * ------- + * numStrings = Number of strings + * lenString = Length of each string including the trailing null + * character + * Return + * ------ + * This value is initialized to the correct address of the array. + * A NULL value in the position indicates an error. + **************************************************************************/ +{ + int i; + char **array; + if (numStrings <= 0) numStrings = 1; + if (lenString <= 0) lenString = 1; + array = (char **) mdp_array_alloc(2, numStrings, lenString, sizeof(char)); + if (array != NULL) { + for (i = 0; i < numStrings; i++) array[i][0] = '\0'; + } else { + mdp_alloc_eh("mdp_alloc_VecFixedStrings", + sizeof(char) * numStrings * lenString + + numStrings * sizeof(void *)); + } + return array; +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +void mdp_realloc_VecFixedStrings(char ***array_hdl, int numStrings, + int numOldStrings, int lenString) + + /************************************************************************* + * + * mdp_realloc_VecFixedStrings: + * + * Reallocate and initialize a vector of fixed-length + * strings. Each new string is initialized to the NULL string. + * old strings are copied. + * + * Input + * ------- + * ***array_hdl = The pointer to the char ** location holding + * the data to be reallocated. + * numStrings = Number of strings + * numOldStrings = Number of old strings + * lenString = Length of each string including the trailing null + * character + **************************************************************************/ +{ + int i; + char **array, **ao; + if (numStrings <= 0) numStrings = 1; + if (numStrings == numOldStrings) return; + if (lenString <= 0) lenString = 1; + array = (char **) mdp_array_alloc(2, numStrings, lenString, sizeof(char)); + if (array != NULL) { + int len = MIN(numStrings, numOldStrings); + ao = *array_hdl; + if (ao) { + for (i = 0; i < len; i++) { + strncpy(array[i], ao[i], lenString); + } + } + if (numStrings > numOldStrings) { + for (i = numOldStrings; i < numStrings; i++) array[i][0] = '\0'; + } + mdp_safe_free((void **) array_hdl); + *array_hdl = array; + + } else { + mdp_alloc_eh("mdp_realloc_VecFixedStrings", + sizeof(char) * numStrings * lenString + + numStrings * sizeof(void *)); + } +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +void mdp_safe_alloc_VecFixedStrings(char ***array_hdl, + int numStrings, int lenString) + + /************************************************************************* + * + * mdp_safe_alloc_VecFixedStrings + * + * Allocate and initialize an array of strings of fixed length + * + * Input + * ------- + * *array_hdl = Previous value of pointer. If non-NULL will try + * to free the memory at this address. + * numStrings = Number of strings + * lenString = Length of each string including the trailing null + * character + * Output + * ------ + * *array_hdl = This value is initialized to the correct address + * of the array. + * A NULL value in the position indicates an error. + **************************************************************************/ +{ + if (array_hdl == NULL) { + mdp_alloc_eh("mdp_safe_alloc_VecFixedStrings: handle is NULL", + MDP_ALLOC_INTERFACE_ERROR); + return; + } + if (*array_hdl != NULL) mdp_safe_free((void **) array_hdl); + *array_hdl = mdp_alloc_VecFixedStrings(numStrings, lenString); + if (*array_hdl == NULL) + mdp_alloc_eh2("mdp_safe_alloc_VecFixedStrings"); +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +C16_NAME *mdp_alloc_C16_NAME_1(int numStrings, const int init) + + /************************************************************************** + * + * mdp_alloc_C16_NAME_1: + * + * Allocate and initialize a vector of fixed-length + * strings of type C16_NAME + * + * Input + * ------- + * numStrings = Number of strings + * init = If true, this routine initializes the space to the + * space character. + * Return + * ------ + * This value is initialized to the correct address of the array. + * A NULL value in the position indicates an error. + **************************************************************************/ +{ + int i, j; + char *c_ptr; + if (numStrings <= 0) numStrings = 1; + C16_NAME *array = (C16_NAME *) mdp_array_alloc(1, numStrings, sizeof(C16_NAME)); + if (array != NULL) { + if (init) { + for (i = 0; i < numStrings; i++) { + c_ptr = (char *) (array + i); + for (j = 0; j < (int) sizeof(C16_NAME); j++) c_ptr[j] = ' '; + } + } + } else { + mdp_alloc_eh("mdp_alloc_C16_NAME_1", + sizeof(C16_NAME) * numStrings); + } + return array; +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +void mdp_safe_alloc_C16_NAME_1(C16_NAME **array_hdl, int numStrings, + const int init) + + /************************************************************************* + * + * mdp_safe_alloc_C16_NAME_1: + * + * Allocate and initialize a vector of fixed-length + * strings of type C16_NAME + * + * Input + * ------- + * *array_hdl = Previous value of pointer. If non-NULL will try + * to free the memory at this address. + * numStrings = Number of strings + * init = If true, this routine initializes the space to the + * space character. + * Output + * ------ + * *array_hdl = This value is initialized to the correct address + * of the array. + * A NULL value in the position indicates an error. + **************************************************************************/ +{ + if (array_hdl == NULL) { + mdp_alloc_eh("mdp_safe_alloc_C16_NAME_1: handle is NULL", + MDP_ALLOC_INTERFACE_ERROR); + return; + } + if (*array_hdl != NULL) mdp_safe_free((void **) array_hdl); + *array_hdl = mdp_alloc_C16_NAME_1(numStrings, init); + if (*array_hdl == NULL) mdp_alloc_eh2("mdp_safe_alloc_C16_NAME_1"); +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +void **mdp_alloc_ptr_1(int numPointers) + + /************************************************************************* + * + * mdp_alloc_ptr_1: + * + * Allocate and initialize a vector of pointers + * of type pointer to void. All pointers are initialized to the NULL + * value. + * + * Input + * ------- + * numPointers = Number of pointers + * Return + * ------ + * This value is initialized to the correct address of the vector. + * A NULL value in the position indicates an error. + **************************************************************************/ +{ + int i; + void **array; + if (numPointers <= 0) numPointers = 1; + array = (void **) mdp_array_alloc(1, numPointers, sizeof(void *)); + if (array != NULL) { + for (i = 0; i < numPointers; i++) { + array[i] = NULL; + } + } else { + mdp_alloc_eh("mdp_alloc_ptr_1", + sizeof(void *) * numPointers); + } + return array; +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +void mdp_safe_alloc_ptr_1(void ***array_hdl, int numPointers) + + /************************************************************************** + * + * mdp_safe_alloc_ptr_1: + * + * Allocate and initialize a vector of pointers + * of type pointer to void. All pointers are initialized to the NULL + * value. + * + * Input + * ------- + * *array_hdl = Previous value of pointer. If non-NULL will try + * to free the memory at this address. + * numPointers = Number of pointers + * Output + * ------ + * *array_hdl = This value is initialized to the correct address + * of the array. + * A NULL value in the position indicates an error. + **************************************************************************/ +{ + if (array_hdl == NULL) { + mdp_alloc_eh("mdp_safe_alloc_ptr_1: handle is NULL", + MDP_ALLOC_INTERFACE_ERROR); + return; + } + if (*array_hdl != NULL) mdp_safe_free((void **) array_hdl); + *array_hdl = mdp_alloc_ptr_1(numPointers); + if (*array_hdl == NULL) mdp_alloc_eh2("mdp_safe_alloc_ptr_1"); +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +void mdp_realloc_ptr_1(void ***array_hdl, int numLen, int numOldLen) + + /************************************************************************* + * + * mdp_realloc__ptr_1: + * + * Reallocate and initialize a vector of pointers + * Each new pointer is initialized to NULL. + * old Pointers are copied. + * + * Input + * ------- + * ***array_hdl = The pointer to the char ** location holding + * the data to be reallocated. + * numLen = Number of strings + * numOldLen = Number of old strings + **************************************************************************/ +{ + if (array_hdl == NULL) { + mdp_alloc_eh("mdp_safe_alloc_ptr_1: handle is NULL", + MDP_ALLOC_INTERFACE_ERROR); + return; + } + if (numLen <= 0) numLen = 1; + if (numOldLen < 0) numOldLen = 0; + if (numLen == numOldLen) return; + size_t bytenum = sizeof(void *) * numLen; + void **array = (void **) smalloc(bytenum); + if (array != NULL) { + int len = MIN(numLen, numOldLen); + if (*array_hdl) { + void **ao = *array_hdl; + for (int i = 0; i < len; i++) array[i] = ao[i]; + } else { + numOldLen = 0; + } + if (numLen > numOldLen) { + bytenum = sizeof(void *) * (numLen - numOldLen); + (void) memset((void *) (array + numOldLen), 0, bytenum); + } + mdp_safe_free((void **) array_hdl); + *array_hdl = array; + } else { + mdp_alloc_eh("mdp_realloc_ptr_1", sizeof(void *) * numLen); + } +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +char *mdp_copy_C16_NAME_to_string(const C16_NAME copyFrom) + + /************************************************************************* + * + * mdp_copy_C16_NAME_to_string: + * + * Allocates space for and copies a C16_NAME + * + * Input + * ------- + * copyFrom = C16_NAME string (note, this doesn't necessarily have + * to be null terminate. This is the reason for this + * subroutine. + * If NULL is supplied, then nothing is malloced and + * a NULL value is returned. + * Return + * ------ + * This value is initialized to the correct address of the array. + * A NULL value in the position either indicates an error, or + * that the original pointer to the string was NULL. + **************************************************************************/ +{ + /* + * This routine creates a temporary string with a null terminator at the + * end (assured). Then it uses mdp_copy_string() to do the work + */ + C16_NAME_STR tmpString; + if (copyFrom == NULL) return NULL; + tmpString[sizeof(C16_NAME)] = '\0'; + (void) strncpy(tmpString, copyFrom, sizeof(C16_NAME)); + return mdp_copy_string(tmpString); +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +char *mdp_copy_string(const char *copyFrom) + + /************************************************************************* + * + * mdp_copy_string: + * + * Allocates space for and copies a string + * + * Input + * ------- + * copyFrom = null terminated string. If NULL is supplied, then + * nothing is malloced and a NULL value is returned. + * Return + * ------ + * This value is initialized to the correct address of the array. + * A NULL value in the position either indicates an error, or + * that the original pointer to the string was NULL. + **************************************************************************/ +{ + char *cptr; + if (copyFrom == NULL) return NULL; + cptr = (char *) mdp_array_alloc(1, strlen(copyFrom) + 1, sizeof(char)); + if (cptr != NULL) { + (void) strcpy(cptr, copyFrom); + } else { + mdp_alloc_eh("mdp_copy_string", sizeof(char) * (strlen(copyFrom) + 1)); + } + return cptr; +} +/****************************************************************************/ +/****************************************************************************/ +/****************************************************************************/ + +void mdp_safe_copy_string(char **string_hdl, const char *copyFrom) + + /************************************************************************* + * + * mdp_safe_copy_string: + * + * Allocates space for and copies a string + * + * Input + * ------- + * *string_hdl = Previous value of pointer. If non-NULL will try + * to free the memory at this address. + * *copyFrom = String to be copied + * Output + * ------ + * *string_hdl = Pointer to the copied string + * A NULL value in the position indicates an error. + **************************************************************************/ +{ + if (string_hdl == NULL) { + mdp_alloc_eh("mdp_safe_copy_string: string_hdl is NULL", + MDP_ALLOC_INTERFACE_ERROR); + return; + } + if (*string_hdl != NULL) mdp_safe_free((void **) string_hdl); + if (copyFrom == NULL) { + *string_hdl = NULL; + return; + } + *string_hdl = mdp_copy_string(copyFrom); + if (*string_hdl == NULL) { + mdp_alloc_eh2("mdp_safe_copy_string"); + } + return; +} +/****************************************************************************/ +/* END of mdp_allo.cpp */ +/****************************************************************************/ diff --git a/tools/testtools/mdp_allo.h b/tools/testtools/mdp_allo.h new file mode 100644 index 000000000..bf12cfa96 --- /dev/null +++ b/tools/testtools/mdp_allo.h @@ -0,0 +1,101 @@ +/*==================================================================== + * ------------------------ + * | CVS File Information | + * ------------------------ + * + * $RCSfile$ + * + * $Author$ + * + * $Date$ + * + * $Revision$ + * + * $Name$ + *====================================================================*/ +#ifndef MDP_ALLO_H +#define MDP_ALLO_H + +/*****************************************************************************/ +/* +* If we have array_alloc() from another Sandia program, we will not use +* the one from this mdp_array_alloc. Instead we will redefine the names +*/ + +#ifdef HAVE_ARRAY_ALLOC +# define mdp_array_alloc array_alloc +# define mdp_safe_free safe_free +#endif + +/* + * These are a poor man's way of specifying whether a value should be + * initialized. These are seldom used numbers whic + * $Name$ + *====================h can be used in place + * of real ints and dbls to indicate that initialization shouldn't take + * place. + */ +#define MDP_INT_NOINIT -68361 +#define MDP_DBL_NOINIT -1.241E11 + + +#ifndef _C16_NAME_DEF +# define _C16_NAME_DEF + typedef char C16_NAME[16]; /* Character array used for fortran names */ + typedef char C16_NAME_STR[17]; +#endif +/*****************************************************************************/ +/* + * Externals that should be set by the calling program. + * These are only used for debugging purposes. + */ +#ifdef MDP_MPDEBUGIO +extern int MDP_MP_Nprocs; +extern int MDP_MP_myproc; +#endif +/*****************************************************************************/ + +#define mdp_alloc_struct(x, num) (x *) mdp_array_alloc(1, (num), sizeof(x)) + + +/* function declarations for dynamic array allocation */ + +extern double *mdp_array_alloc(int numdim, ...); +extern void mdp_safe_free(void **); + +extern int *mdp_alloc_int_1(int, const int); +extern void mdp_safe_alloc_int_1(int **, int, const int); +extern void mdp_realloc_int_1(int **, int, int, + const int defval = MDP_INT_NOINIT); +extern int **mdp_alloc_int_2(int, int, const int); + +extern double *mdp_alloc_dbl_1(int, const double); +extern void mdp_safe_alloc_dbl_1(double **, int, const double); +extern void mdp_realloc_dbl_1(double **, int, int, const double); +extern void mdp_realloc_dbl_2(double ***, int, int, int, int, + const double); + +extern char *mdp_alloc_char_1(int, const char); +extern void mdp_safe_alloc_char_1(char **, int, const char); +extern char **mdp_alloc_VecFixedStrings(int, int); +extern void mdp_safe_alloc_VecFixedStrings(char ***, int, int); +extern void mdp_realloc_VecFixedStrings(char ***, int, int, int); + +extern double **mdp_alloc_dbl_2(int, int, const double); +extern void mdp_safe_alloc_dbl_2(double ***, int, int, + const double = MDP_DBL_NOINIT); + +extern C16_NAME *mdp_alloc_C16_NAME_1(int, const int); +extern void mdp_safe_alloc_C16_NAME_1(C16_NAME **, int, const int); + +extern void **mdp_alloc_ptr_1(int); +extern void mdp_safe_alloc_ptr_1(void ***, int); +extern void mdp_realloc_ptr_1(void ***, int, int); +extern char *mdp_copy_C16_NAME_to_string(const C16_NAME); +extern char *mdp_copy_string(const char *); +extern void mdp_safe_copy_string(char **, const char *); + +/*****************************************************************************/ +#endif +/*****************************************************************************/ + diff --git a/tools/testtools/tok_input_util.cpp b/tools/testtools/tok_input_util.cpp new file mode 100644 index 000000000..0361f939a --- /dev/null +++ b/tools/testtools/tok_input_util.cpp @@ -0,0 +1,1570 @@ +/*==================================================================== + * ------------------------ + * | CVS File Information | + * ------------------------ + * + * $RCSfile$ + * + * $Author$ + * + * $Date$ + * + * $Revision$ + * Symbolic $Name$ + * + * $Id$ + * $Source$ + * + *====================================================================*/ + +#ifndef lint +static char const rcsid[] = + "$Id$"; +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "tok_input_util.h" + +static char DEFAULT_STR[8] = "default"; +static char DELIMITERS[8] = " \t\n\f\r\v"; /* Defn of white space in isspace() + - Used in tokenizing lines */ +static char COM_CHAR = '!'; /* This is used as a comment character */ +static char COM_CHAR2 = '#'; /* This is used as a 2nd comment character */ +static char KEY_CHAR = '='; /* This is used to separate the key_string + from the rest of the line */ +static int PrintInputFile = TRUE; /* Used to turn on and off the + printing of the input file */ + +/*************** R O U T I N E S I N T H E F I L E ******************* +* +* NAME TYPE CALLED_BY +*-------------------------------------------------------------------- +* get_next_keyLine BOOLEAN extern +* tok_to_int int extern +* str_to_int int extern, tok_to_int +* tok_to_double double extern +* str_to_double double extern,tok_to_double +* tok_to_boolean BOOLEAN extern +* str_to_boolean BOOLEAN extern,tok_to_boolean +* tok_to_string char * extern +* +* +* scan_for_int int extern +* scan_for_double double extern +* scan_for_string char * extern +* scan_for_boolean BOOLEAN extern +* scan_for_line int extern +* read_line int scan_for_line, +* get_next_keyLine +* interpret_int static BOOLEAN str_to_int + others +* interpret_boolean static BOOLEAN str_to_boolean +* interpret_double static BOOLEAN str_to_double +* strip int read_input_file, +* look_for, +* get_next_keyLine +* read_string static void scan_for_line +* stokenize int fillTokStruct +* outofbnds static BOOLEAN all +* strmatch BOOLEAN extern, toktokmatch +* strstrmatch BOOLEAN extern +* strtokmatch BOOLEAN extern +* toktokmatch BOOLEAN extern, strtokmatch +* strstrmatch +* fillTokStruct void extern, strtokmatch +* strstrmatch, +* get_next_keyLine +* copyTokStruct void extern +* +******************************************************************************/ +/* +* Definitions of static functions: +*/ + +static BOOLEAN outofbnds(const double, const double, const double ); +static BOOLEAN interpret_boolean(const char *, int *, const int); +static BOOLEAN interpret_int (const char *, int *, const int, const int, + const int); +static BOOLEAN interpret_double (const char *, double *, const double, + const double, const double); + + +/************ Member Functions for the TOKEN Structure ********************/ + +TOKEN::TOKEN(void) : + orig_str(0), + tok_str(0), + ntokes(0) +{ + orig_str = copy_string(""); + tok_str = copy_string(""); + tok_ptr[0] = orig_str; +} + + +TOKEN::TOKEN(const char *str) : + orig_str(0), + tok_str(0), + ntokes(0) +{ + if (str == NULL) { + orig_str = copy_string(""); + tok_str = copy_string(""); + tok_ptr[0] = orig_str; + ntokes = 0; + } else { + orig_str = copy_string(str); + tok_str = copy_string(str); + ntokes = stokenize(tok_str, DELIMITERS, tok_ptr, MAXTOKENS); + } +} + +TOKEN::~TOKEN() +{ + if (orig_str) free(orig_str); + orig_str = NULL; + if (tok_str) free(tok_str); + tok_str = NULL; +} + +/**************************************************************************/ + +BOOLEAN get_next_keyLine(FILE *ifp, TOKEN *keyLineTok, TOKEN *keyArgTok) + /* + * This routine reads the input file to obtain the next line of + * uncommented + * data. The results are returned in two TOKEN structures. keyLineTok + * contains the key Line (everything before the first equals sign). + * keyArgTok contains everything after the equals sign. + * Note - Either keyLineTok or keyArgTok may be the null token + * (but not both) + * + * The definition of a token structure, given in .h file, + * is as follows: + * + * struct TOKEN { + * char orig_str[MAX_INPUT_STR_LN + 1]; + * char tok_str[MAX_INPUT_STR_LN + 1]; + * char *tok_ptr[MAXTOKENS]; + * int ntokes; + * }; + * mdp_allo.h + * orig_str Contains the original string, unmodified. + * tok_str Contains a modified version of the string, + * whose positions + * are pointed to by tok_ptr[i] values. It is usually not + * referenced directly. + * tok_ptr[i] Contains the i_th token of the original string. This + * is a stripped character string. 0 <=i <= i-1 + * ntokes Number of tokens in the string. + * + * + * Comments are denoted by either '!' or '#'. + * Everything after the comment character on a + * line is stripped first. The comment character can occur + * anywhere in the line. + * + * Arguments to the keyLine are denoted by everything after a + * '=' character on the line. + * + * Example: + * --------------------------------------------------------------- + * ! Jack and Jill went up the hill to fetch a pale of water + * ! Jack by nimble, Jack be swift; Jack jump over the candle stick + * + * The meaning of life is = 36.243 24 136 Not even ! close + * ----------------------------------------------------------------- + * + * Then, the routine would return (amongst other things): + * keyLineTok->orig_str = "The meaning of life is" + * keyArgTok->orig_str = "36.243 24 36 Not even" + * keyArgTok->ntokes = 5 + * keyArgTok->tok_ptr[0] = "36.243" + * keyArgTok->tok_ptr[1] = "24" + * keyArgTok->tok_ptr[2] = "136" + * keyArgTok->tok_ptr[3] = "Not" + * keyArgTok->tok_ptr[4] = "Even" + * + * The function returns TRUE if there is a next line to process. + * It returns false if an EOF is encountered. + */ +{ + int retn_value, i; + char save_input[MAX_INPUT_STR_LN + 1]; + char *token_start = NULL; + + /* + * Check the arguments to the routine. This routine needs to be + * supplied with valid pointers to files and spaces for storage + * of its output in the return tokens. + */ + if (ifp == NULL || keyLineTok == NULL || keyArgTok == NULL) { + fprintf(stderr, "get_next_keyLine ERROR, arguments are bad\n"); + return(FALSE); + } + + /* + * Read a chunk of text, either up to a newline from the file pointer, + * ifp. If an EOF occurs, return without changing the input structure + */ + do_it_again: + do { + if ((retn_value = read_string(ifp, save_input, '\n')) < 0) { + return(FALSE); + } + if (PrintInputFile) { + if (retn_value <=0) printf ("%s\n", save_input); + else printf ("%s", save_input); + } + for (i = 0; i < (int) strlen(save_input); i++) { + if (save_input[i] == COM_CHAR || save_input[i] == COM_CHAR2) { + save_input[i] = '\0'; + break; + } + } + } while (strip(save_input) == 0); + + /* + * Discover whether there are arguments in the line + * and then separate the line into two + */ + + for (i = 0; i < (int) strlen(save_input); i++) { + if (save_input[i] == KEY_CHAR) { + save_input[i] = '\0'; + token_start = save_input + i + 1; + break; + } + } + + /* + * Strip the two strings of leading and trailing white space. + * If both strings are now the null string (because the line + * consisted of a single '=' character for example), + * go back and get a new line. + */ + + i = strip(token_start); + if (!strip(save_input)) if (!i) goto do_it_again; + + /* + * Now that we have two strings representing the Key String and + * associated arguments, process them into TOKEN structures. + * Note - if token_start still points to NULL, then fillTokStruct + * will fill keyArgTok with a "null token". + */ + + fillTokStruct(keyLineTok, save_input); + fillTokStruct(keyArgTok, token_start); + return (TRUE); +} +/**************************************************************************/ +/**************************************************************************/ +/**************************************************************************/ + +int tok_to_int(const TOKEN *tokPtr, const int maxVal, const int minVal, + const int defaultVal, BOOLEAN *error) +/* + * Interprets the first string of a TOKEN structure as an int. + * Returns the interpreted value as the return value. + * AnErrors condition is created if more than one token is found + * in the struct TOKEN. + * Bounds checking is done on the value before returning. Value + * must be between the maxVal and minVal; it can equal the max or min + * value. + * + * Certain ascii strings are checked for first (case is insignificant): + * + * String Retn_Value (defined in + * --------- -------------- + * INT_MAX, max, all INT_MAX + * INT_MIN INT_MIN + * N/A, Not Available INT_MIN + * default or "" defaultVal + * + * A default may be specified on the command line. The absence of a + * default may also be specified by setting devault_value to + * NO_DEFAULT_INT. + * + * If there is an error, *error is set to TRUE. *error isn't touched + * if there isn't an error. + */ +{ + if (tokPtr->ntokes == 0) + return(str_to_int(DEFAULT_STR, maxVal, minVal, defaultVal, error)); + else if (tokPtr->ntokes > 1) { + (void) fprintf(stderr, "ERROR: tok_to_int, ntokes > 1: %s\n", + tokPtr->orig_str); + *error = TRUE; + } + return(str_to_int(tokPtr->tok_ptr[0], maxVal, minVal, defaultVal, error)); +} +/**************************************************************************/ +/**************************************************************************/ +/**************************************************************************/ + +int str_to_int(const char *int_string, const int maxVal, const int minVal, + const int defaultVal, BOOLEAN *error) +/* + * Interprets a stripped character string as an integer. + * Bounds checking is done on the value before returning. Value + * must be between the max and min; it can equal the max or min value. + * + * Certain ascii strings are checked for first (case is insignificant): + * + * String Retn_Value (defined in + * --------- -------------- + * INT_MAX, max, all INT_MAX + * INT_MIN INT_MIN + * N/A, Not Available INT_MIN + * default default_value + * + * A default may be specified on the command line. The absence of a + * default may also be specified by setting devault_value to + * NO_DEFAULT_INT. + * + * If there is an error, *error is set to TRUE. *error isn't touched + * if there isn't an error. + */ +{ + int retn_value, check = FALSE; + double LmaxVal, LminVal; + if (defaultVal == NO_DEFAULT_INT) check = TRUE; + if (interpret_int(int_string, &retn_value, maxVal, minVal, defaultVal)) { + if (check) { + if (retn_value == NO_DEFAULT_INT) { + (void) fprintf(stderr, + "ERROR: str_to_int: Default not allowed\n"); + *error = TRUE; + } + } + if (maxVal < INT_MAX) LmaxVal = (double) maxVal + 0.01; + else LmaxVal = (double) maxVal; + if (minVal > INT_MIN) LminVal = (double) minVal - 0.01; + else LminVal = (double) minVal; + if (outofbnds((double) retn_value, LmaxVal, LminVal)) { + fprintf(stderr, + "ERROR: str_to_int outofbnds:\n\t\"%s\"\n", + int_string); + fprintf(stderr,"\tmax = %d, min = %d\n", maxVal, minVal); + *error = TRUE; + } + } else + *error = TRUE; + return (retn_value); +} +/**************************************************************************/ +/**************************************************************************/ +/**************************************************************************/ + +double tok_to_double(const TOKEN * tokPtr, const double maxVal, + const double minVal, const double defaultVal, + BOOLEAN *error) +/* + * Interprets the first string of a TOKEN structure as a double. + * Returns the interpreted value as the return value. + * Errors conditions are created if more than one token is found. + * + * Bounds checking is then done on the value before returning. Value + * must be between the max and min; it can equal the max or min. + * + * Useful values for bounds (specified in : + * DBL_MAX = largest legitimate value of a double ~ 2.0E-308 + * -DBL_MAX = smallest legitimate value of a double ~ 2.0E-308 + * DBL_EPSILON = smallest value of a double that can be added to one + * and produce a different number. ~ 2.0E-16 + * DBL_MIN = smallest value of a double ~ 2.0E-308 + * For example: + * If 0.0 is not a legitimate number for value, set min = DBL_MIN + * If value>=0.0 is legitimate, set min = 0.0 + * if value<=100., set max = 100. + * If no range checking is required, set max = DBL_MAX, min = -DBL_MAX + * + * Certain ascii strings are checked for first (case is insignificant): + * + * Token_String Retn_Value ( specified in + * --------- --------------------------------------- + * FLT_MAX, all FLT_MAX + * DBL_MAX, max DBL_MAX + * N/A -DBL_MAX + * default or "" default_value + * small, DBL_MIN DBL_MIN + * DBL_EPSILON DBL_EPSILON + * + * A default may be specified by either specifying the value as + * "default" or by the absense of any tokens in the TOKEN struct. + * The absence of a default may also be specified by setting the + * value of default_value to NO_DEFAULT_DOUBLE. + * + * If there is an error, *error is set to TRUE. *error isn't touched + * if there isn't an error. + */ +{ + if (tokPtr->ntokes == 0) + return(str_to_double(DEFAULT_STR, maxVal, minVal, defaultVal, error)); + else if (tokPtr->ntokes > 1) { + (void) fprintf(stderr, "ERROR: tok_to_double, ntokes > 1: %s\n", + tokPtr->orig_str); + *error = TRUE; + } + return(str_to_double(tokPtr->tok_ptr[0], maxVal, minVal, defaultVal, error)); +} +/**************************************************************************/ +/**************************************************************************/ +/**************************************************************************/ + +double str_to_double(const char *dbl_string, const double maxVal, + const double minVal, const double defaultVal, + BOOLEAN *error) +/* + * Interprets a stripped character string as a double. Returns the + * interpreted value as the return value. + * + * Bounds checking is then done on the value before returning. Value + * must be between the max and min; it can equal the max or min. + * + * Useful values for bounds (specified in : + * DBL_MAX = largest legitimate value of a double ~ 2.0E-308 + * -DBL_MAX = smallest legitimate value of a double ~ 2.0E-308 + * DBL_EPSILON = smallest value of a double that can be added to one + * and produce a different number. ~ 2.0E-16 + * DBL_MIN = smallest value of a double ~ 2.0E-308 + * For example: + * If 0.0 is not a legitimate number for value, set min = DBL_MIN + * If value>=0.0 is legitimate, set min = 0.0 + * if value<=100., set max = 100. + * If no range checking is required, set max = DBL_MAX, min = -DBL_MAX + * + * Certain ascii strings are checked for first (case is insignificant): + * + * String Retn_Value ( specified in + * --------- --------------------------------------- + * FLT_MAX, all FLT_MAX + * DBL_MAX, max DBL_MAX + * N/A -DBL_MAX + * default default_value + * small, DBL_MIN DBL_MIN + * DBL_EPSILON DBL_EPSILON + * + * A default may be specified. The absence of a + * default may also be specified by setting the value of default_value + * to NO_DEFAULT_DOUBLE. + * + * If there is an error, *error is set to TRUE. *error isn't touched + * if there isn't an error. + */ +{ + double retn_value; + int check = FALSE; + if (defaultVal == NO_DEFAULT_DOUBLE) check = TRUE; + if (interpret_double(dbl_string, &retn_value, maxVal, minVal, defaultVal)) { + if (check) + if (retn_value == NO_DEFAULT_DOUBLE) { + (void) fprintf(stderr, + "ERROR: keyLine_double: Default not allowed\n"); + *error = TRUE; + } + if (outofbnds(retn_value, maxVal, minVal)) { + (void) fprintf(stderr, "ERROR: keyLine_double outofbnds:\n\t\"%s\"\n", + dbl_string); + (void) fprintf(stderr,"\tmax = %e, min = %e\n", maxVal, minVal); + *error = TRUE; + } + } else + *error = TRUE; + return (retn_value); +} +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ + +BOOLEAN tok_to_boolean(const TOKEN *tokPtr, const int default_value, + BOOLEAN *error) + /* + * Interprets the first string of a TOKEN structure as a BOOLEAN. + * (i.e., TRUE or FALSE). Returns the interpreted value as the + * return value. + * Errors conditions are created if more than one token is found. + * + * The following character strings are interpreted + * (case doesn't matter): + * + * TRUE = "YES", "TRUE", "T", "Y" + * FALSE = "NO, "FALSE", "N", "F" + * default_value = "DEFAULT" or "" + * + * A default may be specified on the command line. The absence of a + * default may also be specified by using the value of NO_DEFAULT_INT. + * If tokPtr contains no tokens, this routine will try to use the + * default value. + * + * If there is an error, *error is set to TRUE. *error isn't touched + * if there isn't an error. + */ +{ + if (tokPtr->ntokes == 0) + return(str_to_boolean(DEFAULT_STR, default_value, error)); + else if (tokPtr->ntokes > 1) { + (void) fprintf(stderr, "ERROR: tok_to_boolean, ntokes > 1: %s\n", + tokPtr->orig_str); + *error = TRUE; + } + return(str_to_boolean(tokPtr->tok_ptr[0], default_value, error)); +} +/******************************************************************************/ +/******************************************************************************/ +/******************************************************************************/ + +BOOLEAN str_to_boolean(const char *string, const int default_value, + BOOLEAN *error) + /* + * Interprets a stripped character string as a BOOLEAN value + * (i.e., TRUE or FALSE). It returns that value as the return value. + * + * The following character strings are interpreted + * (case doesn't matter): + * + * TRUE = "YES", "TRUE", "T", "Y" + * FALSE = "NO, "FALSE", "N", "F" + * default_value = "DEFAULT" + * + * A default may be specified on the command line. The absence of a + * default may also be specified by using the value of NO_DEFAULT_INT. + * + * If there is an error, *error is set to TRUE. *error isn't touched + * if there isn't an error. + */ +{ + int retn_value; + if (interpret_boolean(string, &retn_value, default_value)) { + if (retn_value == NO_DEFAULT_BOOLEAN) { + (void) fprintf(stderr, + "ERROR: keyLine_boolean: Default not allowed\n"); + *error = TRUE; + } + } else + *error = TRUE; + return ((BOOLEAN) retn_value); +} +/**************************************************************************/ +/**************************************************************************/ +/**************************************************************************/ + +char *tok_to_string(const TOKEN *tokPtr, const int maxTok, + const int minTok, const char *defaultVal, BOOLEAN *error) +/* + * Interprets the arguments in a TOKEN structure as a string. + * It mallocs new space for the string, are returns the pointer to it. + * The number of tokens in the string is checked before returning. + * The value must be between the maxTok and minTok; it can equal the + * max or min value. + * + * Certain ascii strings are checked for first (case is insignificant): + * + * String Retn_Value + * --------- -------------- + * default or "" defaultVal + * + * A default may be specified on the command line. The absence of a + * default may also be specified by setting devault_value to + * NO_DEFAULT_INT. + * + * If there is an error, *error is set to TRUE. *error isn't touched + * if there isn't an error. + */ +{ + char *str; + if (tokPtr->ntokes == 0) + str = str_to_string(DEFAULT_STR, defaultVal, error); + else + str = str_to_string(tokPtr->orig_str, defaultVal, error); + if (outofbnds((double) tokPtr->ntokes, (double) maxTok, + (double) minTok)) { + (void) fprintf(stderr, "ERROR: tok_to_String:\n\t\"%s\"\n", + tokPtr->orig_str); + (void) fprintf(stderr,"\tmaxTok = %d, minTok = %d\n", maxTok, minTok); + *error = TRUE; + } + return (str); +} +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ + +char *str_to_string(const char *str, const char *defaultVal, + BOOLEAN *error) +/* + * Interprets the argument string as a string. + * It mallocs new space for the string, are returns the pointer to it. + * + * Certain ascii strings are checked for first (case is insignificant): + * + * String Retn_Value + * --------- -------------- + * default defaultVal + * + * A default may be specified on the command line. The absence of a + * default may also be specified by setting devault_value to + * NO_DEFAULT_INT. + * + * If there is an error, *error is set to TRUE. *error isn't touched + * if there isn't an error. + */ +{ + if (str == NULL) { + *error = TRUE; + (void) fprintf(stderr,"ERROR str_to_string: str is uninialized\n"); + return(NULL); + } + if (strmatch(str, DEFAULT_STR)) { + if (strmatch(defaultVal, NO_DEFAULT_STR)) { + *error = TRUE; + (void) fprintf(stderr,"ERROR str_to_string: no default allowed\n"); + return(copy_string(NO_DEFAULT_STR)); + } else + return(copy_string(defaultVal)); + } + return(copy_string(str)); +} +/**************************************************************************/ +/**************************************************************************/ +/**************************************************************************/ + +int scan_for_int(FILE *ifp, const char *str, const int maxVal, + const int minVal) +/* + * Scans the file for a line matching string. Then, interprets + * everything after the equals sign as a single integer. + * Bounds checking is done on the value before returning. Value + * must be between the max and min; it can equal the max or min value. + * + * Certain ascii strings are checked for first (case is insignificant): + * + * String Retn_Value + * --------- -------------- + * INT_MAX, max, all INT_MAX + * INT_MIN, default INT_MIN + * N/A, Not Available INT_MIN + * + * Because this is a fixed format input file routine, errors are + * handled by terminally exiting the program. + */ +{ + int retn_value, defaultVal = INT_MIN; + char *tok_ptr[2]; + char input[MAX_INPUT_STR_LN + 1]; + if (scan_for_line(ifp, str, input, KEY_CHAR, PrintInputFile) < 0) + exit(-1); + if (stokenize(input, DELIMITERS, tok_ptr, 2) == 1) { + if (interpret_int(tok_ptr[0], &retn_value, + maxVal, minVal, defaultVal)) { + if (outofbnds((double) retn_value, (double) maxVal, + (double) minVal)) { + fprintf(stderr, + "ERROR: scan_for_int outofbnds:\n\t\"%s\"\n",str); + fprintf(stderr,"\tmax = %d, min = %d\n", maxVal, minVal); + exit(-1); + } else + return(retn_value); + } + } + fprintf(stderr, "ERROR while processing line, \"%s\"\n", str); + exit(-1); /*NOTREACHED*/ +} +/**************************************************************************/ +/**************************************************************************/ +/**************************************************************************/ + +BOOLEAN scan_for_boolean(FILE *ifp, const char *string) +/* + * Scans the file for a line matching string. Then, interprets + * everything after the equals sign as a single boolean value + * + * Because this is a fixed format input file routine, errors are + * handled by terminally exiting the program. + */ +{ + int ret_value; + char *tok_ptr[2]; + char input[MAX_INPUT_STR_LN + 1]; + if (scan_for_line(ifp, string, input, KEY_CHAR, PrintInputFile) < 0) exit(-1); + if (stokenize(input, DELIMITERS, tok_ptr, 2) == 1) { + if (interpret_boolean(tok_ptr[0], &ret_value, NO_DEFAULT_BOOLEAN)) { + if (ret_value == NO_DEFAULT_BOOLEAN) { + (void) fprintf(stderr, "scan_for_boolean: default not allowed\n"); + exit (-1); + } + return((BOOLEAN) ret_value); + } + } + (void) fprintf(stderr, "scan_for_boolean: ERROR on line \"%s\"\n", string); + exit (-1); /*NOTREACHED*/ +} +/******************************************************************************/ +/******************************************************************************/ +/******************************************************************************/ + +double scan_for_double(FILE *ifp, const char *string, const double maxVal, + const double minVal) +/* + * Scans the file for a line matching string. Then, interprets + * everything after the equals sign as a single floating point number. + * Bounds checking is then done on the value before returning. Value + * must be between the max and min; it can equal the max or min. + * + * Useful values for bounds: + * DBL_MAX = largest legitimate value of a double ~ 2.0E-308 + * -DBL_MAX = smallest legitimate value of a double ~ 2.0E-308 + * DBL_EPSILON = smallest value of a double that can be added to one + * and produce a different number. ~ 2.0E-16 + * DBL_MIN = smallest value of a double ~ 2.0E-308 + * For example: + * If 0.0 is not a legitimate number for value, set min = DBL_MIN + * If value>=0.0 is legitimate, set min = 0.0 + * if value<=100., set max = 100. + * If no range checking is required, set max = DBL_MAX, min = -DBL_MAX + * + * Certain ascii strings are checked for first (case is insignificant): + * + * String Retn_Value + * --------- -------------- + * FLT_MAX, all FLT_MAX + * DBL_MAX, max DBL_MAX + * N/A, default -DBL_MAX + * small, DBL_MIN DBL_MIN + * DBL_EPSILON DBL_EPSILON + * + * Because this is a fixed format input file routine, errors are + * handled by terminally exiting the program. + */ +{ + double retn_value; + char *tok_ptr[2]; + char input[MAX_INPUT_STR_LN + 1]; + if (scan_for_line(ifp, string, input, KEY_CHAR, TRUE) < 0) exit(-1); + if (stokenize(input, DELIMITERS, tok_ptr, 2) > 0) { + if (interpret_double(tok_ptr[0], &retn_value, maxVal, minVal, + NO_DEFAULT_DOUBLE)) { + if (retn_value == NO_DEFAULT_DOUBLE) { + (void) fprintf(stderr, + "ERROR: scan_for_double has no default\n"); + exit(-1); + } + if (outofbnds(retn_value, maxVal, minVal)) { + (void) fprintf(stderr, + "ERROR: scan_for_double outofbnds:\n \"%s = %e\"\n", + string, retn_value); + (void) fprintf(stderr,"\tmax = %e, min = %e\n", maxVal, minVal); + exit(-1); + } else + return(retn_value); + } + } + (void) fprintf(stderr, "ERROR scan_for_double: \"%s\"\n", string); + exit(-1); /*NOTREACHED*/ +} +/******************************************************************************/ +/******************************************************************************/ +/******************************************************************************/ + +char *scan_for_string(FILE *ifp, const char *string, const int maxVal, + const int minVal) +/* + * Scans the file for a line matching string. Then, interprets + * everything after the equals sign as string to be returned. + * Storage for the resulting string is malloced, and the address + * of the string is returned. + * The string is returned stripped of leading and trailing white space, + * and of comments. + * + * Length checking is then done on the number of characters returned. + * + * Because this is a fixed format input file routine, errors are + * handled by terminally exiting the program. + */ +{ + int len; + char input[MAX_INPUT_STR_LN + 1]; + if (scan_for_line(ifp, string, input, KEY_CHAR, PrintInputFile) < 0) + exit(-1); + len = strlen(input); + if (outofbnds((double) len, (double) maxVal, (double) minVal)) { + (void) fprintf(stderr, + "ERROR: scan_for_string string length: \"%s = %s\"\n", string, input); + (void) fprintf(stderr, "\tlength max = %d, min = %d\n", maxVal, minVal); + exit(-1); + } + return (copy_string(input)); +} +/**************************************************************************/ +/**************************************************************************/ +/**************************************************************************/ + +int scan_for_line(FILE *ifp, const char *str, char input[], + const char ch_term, const int print_flag) + /* + * Scan the input file (reading in strings according to + * 'read_string(ifp,)' + * specifications) until the character pattern in 'string' is matched. + * Returns all of the characters after the termination character in + * a null-character terminated string, + * + * Parameter list: + * + * ifp == pointer to file "input" + * string == contains string pattern to be matched. + * input == buffer array to hold characters that are read in. + * On output, it contains the return character string + * ch_term== Termination character. When scanning a line of input + * is read until either a newline, the 'ch' termination + * character is read, or the end-of-file is read. + * + * Output: + * This function returns the number of characters in the string + * input, + * excluding the null character. Error conditions are currently + * handled by returning with negative return values. + */ +{ + int retn_value, i; + BOOLEAN found = FALSE; + char match_string[MAX_INPUT_STR_LN+1], + save_input[MAX_INPUT_STR_LN+1]; + static const char *ename = "ERROR scan_for_line: "; + + /* + * Error test the input match string + */ + + if (strlen(str) > MAX_INPUT_STR_LN) { + fprintf(stderr,"%sMatch string is too long:\n\t%s\n", + ename, str); + return(-1); + } + + /* + * Make it an error to have the comment indicator in a + * match string + */ + + for (i = 0; i < (int) strlen(str); i++) { + if (str[i] == COM_CHAR || str[i] == COM_CHAR2) { + fprintf(stderr, "%s Comment in match string\n\t%s\n", + ename, str); + return(-1); + } + } + + /* + * Strip the string of leading and trailing white space + */ + + if ((retn_value = strip(strcpy(match_string, str))) <= 0) { + fprintf(stderr, "%sMatch string is white space: \"%s\"\n", + ename, str); + return(-1); + } + + /* + * Start the search for the string + */ + + do + { + /* + * Read a chunk of text, either up to a newline or to the + * character ch_term, from the file pointer, ifp. + */ + + if ((retn_value = read_string(ifp, save_input, ch_term)) < 0) { + fprintf (stderr, + "%sEOF found in input file while searching for:\n", ename); + fprintf (stderr, "\t\"%s\"\n", match_string); + return(retn_value); + } + + /* + * copy the string just read to the output string, and the + * strip it of leading and trailing white space, and comments. + * Then, compare the stripped input string with the stripped + * match_string + */ + + strcpy(input, save_input); + if (strip(input) > 0) + found = strmatch(input, match_string); + + /* + * If requested print the line, including comments, on standard output. + * Use the retn_value from read_string to test whether a \n needs to + * be written. + */ + + if (print_flag) { + if (found) printf ("->\t"); + if (retn_value == 0) + printf("%s\n", save_input); + else + printf("%s%c", save_input, ch_term); + } + + /* + * Read and print the rest of the line, if we are in the middle of it. + */ + + if (retn_value > 0) { + if ((retn_value = read_line(ifp, input, print_flag)) < 0) { + fprintf(stderr, + "ERROR, EOF found in input file while reading line:\n"); + fprintf(stderr, "%s %c\n", str, ch_term); + return(retn_value); + } + } + else + input[0] = '\0'; + } while (!found); + return (retn_value); +} +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ + +int read_line(FILE *ifp, char input[], const int print_flag) + + /* + * read_line: + * + * Reads a line of input. The line is + * printed to standard output, if print_flag is true. + * The line is returned in the character + * string pointed to by input. Leading and trailing white spaces are + * stripped from the line. + * The number of characters, excluding the null character, is + * returned, except when read_string encounters an error condition + * (negative return values). Then, the error condition is returned. + */ +{ + int retn_value; + + /* + * read the file up to the next new line, read_string will return + * a 0 for a success, and a negative value for failure + */ + + retn_value = read_string(ifp, input, '\n'); + + /* + * Print out the line before stripping it of comments and white space + */ + + if (print_flag) printf ("%s\n", input); + + /* + * Strip the return line of comments and leading/trailing white space + * Use the function strip to return the number of characters remaining + */ + + if (retn_value == 0) return (strip(input)); + + /* + * If an error condition occurred in read_string, return the error + * condition value instead of the character count + */ + + (void) strip(input); + return (retn_value); +} +/**************************************************************************/ +/**************************************************************************/ +/**************************************************************************/ + +int read_string(FILE *ifp, char string[], const char ch) + /* + * This routine reads the standard input until encountering + * the end-of-file, a newline, the character 'ch' or until + * MAX_INPUT_STR_LN characters are read. The inputted characters + * are read into 'string'. + * If an EOF occurs, -1 is returned. + * If a line is longer than MAX_INPUT_STR_LN, a -2 is returned + * and an error message is written to standard error. + * string[] will be returned null-terminated with the + * first MAX_INPUT_STR_LN of the line. + * Upon successful completion with the read terminated by the + * character 'ch', the number of characters read plus 1 for the + * null character at the end of the string is returned. If the + * read is terminated by '\n', a 0 is returned, even if ch = '\n' + * + * + * Parameter list: + * + * ifp == pointer to file "input" + * string == On output, 'string' contains the characters read + * from the input stream. However, the termination character + * or the newline character is not included + * ch == Additional Termination character. That is, input function + * stops when 'ch' or '\n' is read. + */ +{ + int i = 0, rtn_value, new_ch; + + /* + * Read from the file, until termination conditions occur + * The order in the while statement is important. + */ + while( (i < MAX_INPUT_STR_LN ) + && ((new_ch = getc(ifp)) != ch ) + && ( new_ch != '\n') + && ( new_ch != EOF )) string[i++] = new_ch; + + /* + * Check for termination conditions + */ + if (new_ch == EOF) { + rtn_value = -1; + } + else if (i == MAX_INPUT_STR_LN) { + fprintf(stderr, + "read_string ERROR: Maxed line character count, %d," + " before finding (%c)\n", MAX_INPUT_STR_LN, ch); + rtn_value = -2; + } + else if (new_ch == '\n') + rtn_value = 0; + else + rtn_value = i + 1; + + /* + * Make sure the string is null terminated and return + */ + string[i] = '\0'; + return (rtn_value); +} +/**************************************************************************/ + +static BOOLEAN interpret_boolean(const char *token, int *ret_value, + const int default_value) + /* + * This routine interprets a string token to be either true or false + * and then returns the appropriate answer as an int value in the + * variable ret_value. It is int because the default value may not + * be only 0 or 1 + */ +{ + /* lower_case (token); */ + if (token[0] == '\0') + *ret_value = default_value; + else if (strlen(token) == 1) { + switch (token[0]) { + case 't': + case 'y': + *ret_value = TRUE; break; + case 'f': + case 'n': + *ret_value = FALSE; break; + default: + return (FALSE); + } + } else { + if (strmatch(token,"true") || strmatch(token,"yes")) + *ret_value = TRUE; + else if (strmatch(token,"false") || strmatch(token,"no")) + *ret_value = FALSE; + else if (strmatch(token,DEFAULT_STR) == 0) { + *ret_value = default_value; + } else { + return (FALSE); + } + } + return (TRUE); +} +/**************************************************************************/ + +static BOOLEAN interpret_int(const char *token, int *retn_value, + const int maxVal, const int minVal, + const int defaultVal) + /* + * This routine interprets a string token to be an integer + * and then returns the appropriate answer as an int value in the + * variable ret_value. + * Errors are indicated by returning FALSE. Success is indicated + * by returning TRUE. + * + * Certain ascii strings are checked for first (case is insignificant): + * + * String Retn_Value + * --------- -------------- + * INT_MAX, all INT_MAX + * INT_MIN INT_MIN + * max maxVal + * min minVal + * default defaultVal + * NULL string defaultVal + * N/A, Not_Available INT_MIN + */ +{ + int retn; + + /* + * Allow a few key ascii phrases in place of an actual int + */ + + /* lower_case(token); */ + if (token[0] == '\0') + *retn_value = defaultVal; + else if ((strmatch(token,"all")) || strmatch(token,"int_max") ) + *retn_value = INT_MAX; + else if (strmatch(token,"int_min")) + *retn_value = INT_MIN; + else if (strmatch(token,"max")) + *retn_value = maxVal; + else if (strmatch(token,"min")) + *retn_value = minVal; + else if (strmatch(token,DEFAULT_STR)) + *retn_value = defaultVal; + else if (strmatch(token,"n/a") || strmatch(token,"not_available")) + *retn_value = INT_MIN; + else { + if ((retn = sscanf(token, "%d", retn_value)) != 1) { + *retn_value = retn; + return (FALSE); + } + } + return (TRUE); +} +/******************************************************************************/ +/******************************************************************************/ +/******************************************************************************/ + +static BOOLEAN interpret_double(const char *token, double *retn_value, + const double maxVal, const double minVal, + const double defaultVal) + /* + * This routine interprets a string token to be a double + * and then returns the appropriate answer as a double value in the + * variable retn_value. + * The function itself returns TRUE if successful or FALSE if unsuccessful + * + * + * Certain ascii strings are checked for first (case is insignificant): + * + * String Retn_Value + * --------- -------------- + * FLT_MAX, all FLT_MAX + * FLT_MIN FLT_MIN + * DBL_MAX DBL_MAX + * max maxVal + * min minVal + * default defaultVal + * NULL string defaultVal + * N/A -DBL_MAX + * small, DBL_MIN DBL_MIN + * DBL_EPSILON DBL_EPSILON + * + * DBL_MAX = largest legitimate value of a double ~ 2.0E-308 + * -DBL_MAX = smallest legitimate value of a double ~ - 2.0E-308 + * DBL_EPSILON = smallest value of a double that can be added to one + * and produce a different number. ~ 2.0E-16 + * DBL_MIN = tiniest value of a double ~ 2.0E-308 + */ +{ + int retn; + float retn_float; + + /* + * Allow a few key ascii phrases in place of an actual float + */ + + /* lower_case(token); */ + if (token[0] == '\0') + *retn_value = defaultVal; + else if ((strmatch(token,"all")) || strmatch(token,"flt_max")) + *retn_value = FLT_MAX; + else if (strmatch(token,"flt_min")) + *retn_value = FLT_MIN; + else if (strmatch(token,"dbl_max")) + *retn_value = DBL_MAX; + else if (strmatch(token,"max")) + *retn_value = maxVal; + else if (strmatch(token,"min")) + *retn_value = minVal; + else if (strmatch(token,"n/a")) + *retn_value = -DBL_MAX; + else if (strmatch(token, DEFAULT_STR)) + *retn_value = defaultVal; + else if (strmatch(token,"small") || strmatch(token,"dbl_min")) + *retn_value = DBL_MIN; + else if (strmatch(token,"dbl_epsilon")) + *retn_value = DBL_EPSILON; + else { + if ((retn = sscanf(token, "%e", &retn_float)) != 1) { + *retn_value = (double) retn; + return (FALSE); + } else + *retn_value = (double) retn_float; + } + return(TRUE); +} +/******************************************************************************/ +/******************************************************************************/ +/******************************************************************************/ + +int strip(char str[]) + /* + * This routine strips off blanks and tabs (only leading and trailing + * characters) in 'str'. On return, it returns the number of + * characters still included in the string (excluding the null character). + * + * Comments are excluded -> All instances of the comment character, '!', + * are replaced by '\0' thereby terminating + * the string + * + * Parameter list: + * + * str == On output 'str' contains the same characters as on + * input except the leading and trailing white space and + * comments have been removed. + */ +{ + int i = 0, j = 0; + char ch; + + /* + * Quick Returns + */ + + if ((str == NULL) || (str[0] == '\0')) return (0); + + /* Find first non-space character character */ + + while(((ch = str[i]) != '\0') && isspace(ch)) i++; + + /* + * Move real part of str to the front by copying the string + * - Comments are handled here, by terminating the copy at the + * first comment indicator, and inserting the null character at + * that point. + */ + + while ( (ch = str[j+i]) != '\0' && + (ch != COM_CHAR) && + (ch != COM_CHAR2) ) { + str[j] = ch; + j++; + } + str[j] = '\0'; + j--; + + /* Remove trailing white space by inserting a null character */ + + while( (j != -1 ) && isspace(str[j])) j--; + j++; + str[j] = '\0'; + return (j); +} +/**************************************************************************/ +/**************************************************************************/ +/**************************************************************************/ + +void lower_case(char str[]) + /* + * lower_case: + * Translates a string delimited by a NULL character + * to lower case. There is no error checking in this version. + * Relies on stlib function, tolower. + */ +{ + int i; + for (i = 0; i < (int) strlen(str); i++) { +# if defined(_INCLUDE_XOPEN_SOURCE) && ! defined(__lint) + str[i] = _tolower((str[i])); +# else + str[i] = tolower(str[i]); +# endif + } +} +/******************************************************************************/ +/******************************************************************************/ +/******************************************************************************/ + +char *TokToStrng (const TOKEN *keyptr) + /* + * TokToStrng: + * Mallocs a new character string and copies + * the tokens character string to it, appending all tokens together + * into a single string separated by a single space character. + * It returns the pointer to the new string; + * The new string should be freed when no longer needed. + */ +{ + int i; + if (!keyptr) return NULL; + if (!keyptr->orig_str) return NULL; + int iln = strlen(keyptr->orig_str) + 1 + keyptr->ntokes; + char *fstr = (char *) malloc(iln * sizeof(char)); + + char *const*str = &(keyptr->tok_ptr[0]); + for (i = 0, fstr[0]= '\0'; i < (keyptr->ntokes - 1); i++, str++) { + (void) strcat(strcat(fstr, *str), " "); + } + return(strcat(fstr, *str)); +} +/******************************************************************************/ +/******************************************************************************/ +/******************************************************************************/ + +int stokenize(char *string, const char *delimiters, char *tok_ptr[], + const int max_tokens) + /* + * stokenize + * + * This function will break up a string into its respective "tokens". + * It returns the number of tokens found. See the strtok(3) man page. + * + * input + * ---------- + * string - String to be tokenized. Note, that the string is + * changed by this procedure. Null characters are + * put between each symbol. + * delimiters - String containing a list of delimiters. + * The example below covers 'white space' + * e.g., char *delimiters = " \t\n"; + * max_tokens - Maximum number of tokens to be found + * + * output + * ----------- + * tok_ptr - Vector of pointers to strings, that contain the input + * string's tokens + */ +{ + int i = 0; + if (string == NULL) { + tok_ptr[0] = NULL; + return 0; + } + if (strlen(string) == 0) { + tok_ptr[0] = string; + return 0; + } + if ( (tok_ptr[0] = strtok(string, delimiters)) != NULL) { + do { + if ( (++i) == max_tokens) break; + } while ( (tok_ptr[i] = strtok(NULL, delimiters)) != NULL); + } + return (i); +} +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ + +static BOOLEAN outofbnds(const double value, const double maxVal, + const double minVal) +/* + * This routine checks the bounds of a single double value. + * If it is inside or on the bounds, it returns false. + * If it is outside the bounds, it returns true. + */ +{ + if ((value <= maxVal) && (value >= minVal)) return (FALSE); + return(TRUE); +} +/****************************************************************************** + * + * strmatch(): + * + * This routine checks whether one string is the same as another. + * Upper case is transformed into lower case before the comparison is done. + * Thus, case doesn't matter in the comparison. However, white space + * does matter in this comparison. + * If they are, it returns true + * If they aren't, it returns false + */ +BOOLEAN strmatch(const char *s1, const char *s2) +{ + while (*s1 != '\0') { +# if defined (_INCLUDE_XOPEN_SOURCE) && ! defined(__lint) + if (_tolower((*s1++)) != _tolower((*s2++))) return (FALSE); +# else + if (tolower(*s1) != tolower(*s2)) return (FALSE); + s1++; s2++; +# endif + } + if (*s2 != '\0') return (FALSE); + return (TRUE); +} + +/***************************************************************************** + * + * strstrmatch(): + * + * This routine checks whether two strings are the same modulo differences + * in their white space + */ +BOOLEAN strstrmatch(const char *s1, const char*s2) +{ + struct TOKEN tmpKeyStruct1, tmpKeyStruct2; + fillTokStruct(&tmpKeyStruct1, s1); + fillTokStruct(&tmpKeyStruct2, s2); + return (toktokmatch(&tmpKeyStruct2, &tmpKeyStruct1)); +} + +/******************************************************************************* + * + * strtokmatch(): + * + * This routine checks whether a string matches the string contained in + * the tokens of a keyLineStr. + * White space and case are ignored. + * If they are, it returns true + * If they aren't, it returns false + */ +BOOLEAN strtokmatch(const TOKEN *keyptr, const char*s2) +{ + struct TOKEN tmpKeyStruct; + fillTokStruct(&tmpKeyStruct, s2); + return (toktokmatch(keyptr, &tmpKeyStruct)); +} + +/************************************************************************** + * + * toktokmatch() + * + * This routine checks whether two TOKEN structures contain the + * same data up to differences in white space. + * Case is ignored as well, as strmatch is called. + */ +BOOLEAN toktokmatch(const TOKEN *keyptr1, const TOKEN *keyptr2) +{ + int i = keyptr1->ntokes; + if (i != keyptr2->ntokes) return FALSE; + while (i > 0) { + i--; + if (!strmatch(keyptr1->tok_ptr[i], keyptr2->tok_ptr[i])) return FALSE; + } + return TRUE; +} + +/**************************************************************************/ +/* + * fillTokStruct() + * + * Fill in a keyLineStruct with a string. Use the defn of white space + * at the start of the file to tokenize the string, storring it in the + * TOKEN structure. + */ +void fillTokStruct(TOKEN *keyptr1, const char *s2) +{ + if (keyptr1 == NULL) return; + if (keyptr1->orig_str) free(keyptr1->orig_str); + if (keyptr1->tok_str) free(keyptr1->tok_str); + if (s2 == NULL) { + keyptr1->orig_str = copy_string(""); + keyptr1->tok_str = copy_string(""); + keyptr1->ntokes = 0; + keyptr1->tok_ptr[0] = keyptr1->orig_str; + return; + } + keyptr1->orig_str = copy_string(s2); + keyptr1->tok_str = copy_string(s2); + keyptr1->ntokes = stokenize(keyptr1->tok_str, DELIMITERS, keyptr1->tok_ptr, + MAXTOKENS); +} + +/****************************************************************************** + * + * copyTokStruct(): + * + * Copies the information stored in keyptr2 into keyptr1 + */ +void copyTokStruct(TOKEN *keyptr1, const TOKEN *keyptr2) +{ + if (keyptr1 == NULL) return; + if (keyptr2 == NULL) return; + if (keyptr1->orig_str) free(keyptr1->orig_str); + if (keyptr1->tok_str) free(keyptr1->tok_str); + if (keyptr2->orig_str == NULL) { + keyptr1->orig_str = copy_string(""); + keyptr1->tok_str = copy_string(""); + keyptr1->ntokes = 0; + keyptr1->tok_ptr[0] = keyptr1->orig_str; + return; + } + keyptr1->orig_str = copy_string(keyptr2->orig_str); + keyptr1->tok_str = copy_string(keyptr2->orig_str); + keyptr1->ntokes = stokenize(keyptr1->tok_str, DELIMITERS, keyptr1->tok_ptr, + MAXTOKENS); +} + +/****************************************************************************** + * + * in_char_list(): + * + * Finds a match of one string against a list of strings. Returns + * the position that the first match occurred. + * If no match occurred, returns -1. + * The comparisons ignore differences in white space. + */ +int in_char_list(const char * const str1, const char ** const list, + int num_list) +{ + int i; + for (i = 0; i < num_list; i++) if (strstrmatch(str1, list[i])) return(i); + return (-1); +} +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ + +char *copy_string(const char *string) + /* + * copy_string: + * Mallocs a new character string and copies the old string to it + * + * NOTE: Memory leak may result if the calling program doesn't free + * the malloced space + */ +{ + char *new_string; + new_string = (char *) malloc(strlen(string)+1); + if (new_string == NULL) { + (void) fprintf(stderr, "copy_string ERROR: malloc returned NULL"); + } else { + (void) strcpy(new_string, string); + } + return (new_string); +} + +/****************************************************************************** + * + * strip_item_from_token (): + * + * Change the token by taking eliminating the iword'th token from the token + * structure and reformulating the token expression + */ +void strip_item_from_token(int iword, TOKEN *tok) +{ + if (!tok) return; + if (iword < 0 || iword > tok->ntokes) return; + int ioffset = tok->tok_ptr[iword] - tok->tok_str; + int ilength = strlen(tok->tok_ptr[iword]); + int i = ioffset; + int j = ioffset + ilength; + if (j <= (int) strlen(tok->orig_str)) { + while(tok->orig_str[j] != '\0') { + tok->orig_str[i] = tok->orig_str[j]; + i++; + j++; + } + tok->orig_str[i] = '\0'; + } + strcpy(tok->tok_str, tok->orig_str); + tok->ntokes = stokenize(tok->tok_str, DELIMITERS, tok->tok_ptr, + MAXTOKENS); +} + +/*****************************************************************************/ diff --git a/tools/testtools/tok_input_util.h b/tools/testtools/tok_input_util.h new file mode 100644 index 000000000..187dbe706 --- /dev/null +++ b/tools/testtools/tok_input_util.h @@ -0,0 +1,113 @@ +/*==================================================================== + * ------------------------ + * | CVS File Information | + * ------------------------ + * + * $RCSfile$ + * + * $Author$ + * + * $Date$ + * + * $Revision$ + * Symbolic $Name$ + * + * $Id$ + * $Source$ + * + * + *====================================================================*/ + +#ifndef TOK_INPUT_UTIL_H +#define TOK_INPUT_UTIL_H + +#include "stdio.h" + +#ifndef MAX_INPUT_STR_LN +#define MAX_INPUT_STR_LN 16100 +#endif +#ifndef MAX_TOKEN_STR_LN +#define MAX_TOKEN_STR_LN 255 +#endif +#ifndef MAXTOKENS +#define MAXTOKENS 20 +#endif + +#ifndef TRUE +# define TRUE 1 +# define FALSE 0 +#endif + +#ifndef BOOLEAN +# define BOOLEAN int +#endif + +/**************************************************************************/ +/* TOKEN structure: + * This structure is used to parse strings. The original string is + * tokenized into a set of tokens via separation wrt white space. + * Both the tokens and the original + * string are storred within the structure + */ + +struct TOKEN { + char *orig_str; + char *tok_str; + char *tok_ptr[MAXTOKENS]; + int ntokes; + TOKEN(void); + ~TOKEN(); + TOKEN(const char *str); +}; + + +#define NO_DEFAULT_INT -68361 +#define NO_DEFAULT_BOOLEAN NO_DEFAULT_INT +#define NO_DEFAULT_DOUBLE -1.241E+11 +#define NO_DEFAULT_STR "NO_DEFAULT" + + +/**************************************************************************/ +/* Prototypes for routines tok_input_util.c */ +/**************************************************************************/ + +extern BOOLEAN get_next_keyLine(FILE *, TOKEN *, TOKEN *); +extern int tok_to_int (const TOKEN *, const int, const int, + const int, BOOLEAN *); +extern int str_to_int (const char *, const int, const int, + const int, BOOLEAN *); +extern double tok_to_double (const TOKEN *, const double, const double, + const double, BOOLEAN *); +extern double str_to_double (const char *, const double, const double, + const double, BOOLEAN *); +extern BOOLEAN tok_to_boolean(const TOKEN *, const int, BOOLEAN *); +extern BOOLEAN str_to_boolean(const char *, const int, BOOLEAN *); +extern char *tok_to_string (const TOKEN *, const int, const int, + const char *, BOOLEAN *); +extern char *str_to_string (const char *, const char *, BOOLEAN *); +extern int scan_for_int(FILE *, const char *, const int, const int); +extern double scan_for_double(FILE *, const char *, const double, + const double); +extern char *scan_for_string(FILE *, const char *, const int, const int); +extern BOOLEAN scan_for_boolean(FILE *, const char *); +extern int scan_for_line(FILE *, const char *, char [], const char, + const int); +extern int read_line(FILE *, char [], const int); +extern int read_string(FILE *, char [], const char); +extern int strip(char []); +extern void lower_case(char []); +extern char *TokToStrng(const TOKEN *); +extern int stokenize(char *, const char *, char *[], const int); +extern BOOLEAN strmatch(const char *, const char*); +extern BOOLEAN strstrmatch(const char *, const char*); +extern BOOLEAN strtokmatch(const TOKEN *, const char *); +extern BOOLEAN toktokmatch(const TOKEN *, const TOKEN *); +extern void fillTokStruct(TOKEN *, const char *); +extern void copyTokStruct(TOKEN *, const TOKEN *); +extern int in_char_list(const char * const, const char ** const, int); +extern char *copy_string(const char *); +extern void strip_item_from_token(int, TOKEN *); +/**************************************************************************/ +#endif /* END OF TOK_INPUT_UTIL_H */ +/**************************************************************************/ +