public static String writeChemkinPdepReactions(ReactionSystem rs) { // #[ operation writeChemkinReactions(ReactionModel) StringBuilder result = new StringBuilder(); result.append("REACTIONS KCAL/MOLE\n"); LinkedList rList = new LinkedList(); LinkedList troeList = new LinkedList(); LinkedList tbrList = new LinkedList(); LinkedList duplicates = new LinkedList(); LinkedList lindeList = new LinkedList(); if (rs.dynamicSimulator instanceof JDASPK) { rList = ((JDASPK) rs.dynamicSimulator).rList; troeList = ((JDASPK) rs.dynamicSimulator).troeList; tbrList = ((JDASPK) rs.dynamicSimulator).thirdBodyList; duplicates = ((JDASPK) rs.dynamicSimulator).duplicates; lindeList = ((JDASPK) rs.dynamicSimulator).lindemannList; } else if (rs.dynamicSimulator instanceof JDASSL) { rList = ((JDASSL) rs.dynamicSimulator).rList; troeList = ((JDASSL) rs.dynamicSimulator).troeList; tbrList = ((JDASSL) rs.dynamicSimulator).thirdBodyList; duplicates = ((JDASSL) rs.dynamicSimulator).duplicates; lindeList = ((JDASSL) rs.dynamicSimulator).lindemannList; } for (Iterator iter = rList.iterator(); iter.hasNext(); ) { Reaction r = (Reaction) iter.next(); // 10/26/07 gmagoon: changed to avoid use of Global.temperature; I am using // getPresentTemperature for the time being; it is possible that // getInitialStatus.getTemperature or something similar may be more appropriate result.append(r.toChemkinString(rs.getPresentTemperature()) + "\n"); // result.append(r.toChemkinString(Global.temperature)+"\n"); } for (Iterator iter = troeList.iterator(); iter.hasNext(); ) { Reaction r = (Reaction) iter.next(); result.append(r.toChemkinString(rs.getPresentTemperature()) + "\n"); // result.append(r.toChemkinString(Global.temperature)+"\n"); } for (Iterator iter = tbrList.iterator(); iter.hasNext(); ) { Reaction r = (Reaction) iter.next(); result.append(r.toChemkinString(rs.getPresentTemperature()) + "\n"); // result.append(r.toChemkinString(Global.temperature)+"\n"); } for (Iterator iter = duplicates.iterator(); iter.hasNext(); ) { Reaction r = (Reaction) iter.next(); result.append(r.toChemkinString(rs.getPresentTemperature()) + "\n\tDUP\n"); // result.append(r.toChemkinString(Global.temperature)+"\n\tDUP\n"); } for (Iterator iter = lindeList.iterator(); iter.hasNext(); ) { Reaction r = (Reaction) iter.next(); result.append(r.toChemkinString(rs.getPresentTemperature()) + "\n"); } result.append("END\n"); return result.toString(); // #] }
public static String writeGridOfRateCoeffs(ReactionModel p_reactionModel) { StringBuilder result = new StringBuilder(); LinkedList pDepList = new LinkedList(); CoreEdgeReactionModel cerm = (CoreEdgeReactionModel) p_reactionModel; for (Iterator iter = PDepNetwork.getNetworks().iterator(); iter.hasNext(); ) { PDepNetwork pdn = (PDepNetwork) iter.next(); for (ListIterator pdniter = pdn.getNetReactions().listIterator(); pdniter.hasNext(); ) { PDepReaction rxn = (PDepReaction) pdniter.next(); if (cerm.categorizeReaction(rxn) != 1) continue; // check if this reaction is not already in the list and also check if this reaction has a // reverse reaction // which is already present in the list. if (rxn.getReverseReaction() == null) rxn.generateReverseReaction(); if (!rxn.reactantEqualsProduct() && !pDepList.contains(rxn) && !pDepList.contains(rxn.getReverseReaction())) { pDepList.add(rxn); } } } Temperature[] tempsUsedInFame = PDepRateConstant.getTemperatures(); int numTemps = tempsUsedInFame.length; Pressure[] pressUsedInFame = PDepRateConstant.getPressures(); int numPress = pressUsedInFame.length; for (int i = 0; i < numTemps; i++) { for (int j = 0; j < numPress; j++) { result.append( "T=" + tempsUsedInFame[i].getK() + "K,P=" + pressUsedInFame[j].getBar() + "bar\t"); } result.append("\n"); } result.append("\n"); for (Iterator iter = pDepList.iterator(); iter.hasNext(); ) { PDepReaction r = (PDepReaction) iter.next(); result.append(r.toString() + "\n"); double[][] rates = new double[numTemps][numPress]; rates = r.getPDepRate().getRateConstants(); for (int i = 0; i < numTemps; i++) { for (int j = 0; j < numPress; j++) { result.append(rates[i][j] + "\t"); } result.append("\n"); } result.append("\n"); } return result.toString(); }
// ## operation generateReverseForBackwardReaction() private TemplateReaction generateReverseForBackwardReaction(Structure fs, Structure fsSp) { // #[ operation generateReverseForBackwardReaction() // we need to only generate reverse reaction for backward reaction, so that we wont be stuck // into a self loop. if (!this.isBackward()) { return null; } ReactionTemplate fRT = getReactionTemplate(); ReactionTemplate rRT = null; if (fRT.isForward()) { return null; } else if (fRT.isNeutral()) { rRT = fRT; } else if (fRT.isBackward()) { rRT = fRT.getReverseReactionTemplate(); } else { throw new InvalidReactionTemplateDirectionException(); // Structure fs = getStructure(); } LinkedList freactant = fs.getReactantList(); LinkedList fproduct = fs.getProductList(); Structure rs = new Structure(fproduct, freactant, -1 * this.getDirection()); Structure rsSp = new Structure(fsSp.products, fsSp.reactants, -1 * this.getDirection()); // If it's in the reverse ReactionTemplate.reactionDictionaryByStructure then just return that // one. TemplateReaction rr = rRT.getReactionFromStructure(rsSp); if (rr != null) { rr.setReverseReaction(this); return rr; } int rNum = fproduct.size(); Kinetics[] k = rRT.findReverseRateConstant(rs); // If that didnt work, what to do.... if (k == null && rRT.name.equals("R_Recombination")) { ChemGraph cg = ((ChemGraph) fproduct.get(0)); Graph g = cg.getGraph(); Node n = (Node) g.getCentralNodeAt(2); if (n == null) { cg = ((ChemGraph) fproduct.get(1)); g = cg.getGraph(); n = (Node) g.getCentralNodeAt(2); } g.clearCentralNode(); g.setCentralNode(1, n); k = rRT.findRateConstant(rs); } else if (k == null && rRT.name.equals("H_Abstraction")) { ChemGraph cg1 = ((ChemGraph) fproduct.get(0)); Graph g1 = cg1.getGraph(); Node n3 = (Node) g1.getCentralNodeAt(3); if (n3 == null) { cg1 = ((ChemGraph) fproduct.get(1)); g1 = cg1.getGraph(); n3 = (Node) g1.getCentralNodeAt(3); Node n2 = (Node) g1.getCentralNodeAt(2); g1.clearCentralNode(); g1.setCentralNode(1, n3); g1.setCentralNode(2, n2); ChemGraph cg2 = ((ChemGraph) fproduct.get(0)); Graph g2 = cg2.getGraph(); Node n1 = (Node) g2.getCentralNodeAt(1); g2.clearCentralNode(); g2.setCentralNode(3, n1); } else { Node n2 = (Node) g1.getCentralNodeAt(2); g1.clearCentralNode(); g1.setCentralNode(1, n3); g1.setCentralNode(2, n2); ChemGraph cg2 = ((ChemGraph) fproduct.get(1)); Graph g2 = cg2.getGraph(); Node n1 = (Node) g2.getCentralNodeAt(1); g2.clearCentralNode(); g2.setCentralNode(3, n1); } k = rRT.findRateConstant(rs); } /* * Added by MRH on 27-Aug-2009 This hard-coding is necessary for rxn family templates that are labeled * "thermo_consistence". After the chemgraphs are mutated, the central nodes for the products are not correct * (see example below). These hard-coded portions are necessary for RMG to find Kinetics for the structure. * Example: CH4 + H CH4 1 *1 C 0 {2,S} {3,S} {4,S} {5,S} 2 *2 H 0 {1,S} 3 H 0 {1,S} 4 H 0 {1,S} 5 H 0 {1,S} H 1 * *3 H 1 After RMG has "reactChemGraph" and "mutate" the chemgraphs of the reactants, the products would look * as such: prod1 1 *1 C 1 {2,S} {3,S} {4,S} 2 H 0 {1,S} 3 H 0 {1,S} 4 H 0 {1,S} prod2 1 *3 H 0 {2,S} 2 *2 H 0 * {1,S} Assuming the reaction as written (CH4+H=CH3+H2) is endothermic at 298K, RMG will label this structure * as direction=-1 (backward). When attempting to find Kinetics for the backward reaction, RMG will try to match * the prod1 graph against the generic graphs X_H and Y_rad_birad. It cannot match Y_rad_birad (because there is * no *3 node) and it cannot match X_H (because there is no *2 node). Thus, a "null" Kinetics will be returned * from the findReverseRateConstant call. We then relabel the central nodes on prod1 and prod2 and attempt to * get Kinetics for this structure. I am adding the following bit of code to work with the new reaction family * Aaron Vandeputte is adding to RMG: "". */ else if (k == null && rRT.name.equals("intra_substitutionS_isomerization")) { ChemGraph cg1 = ((ChemGraph) fproduct.get(0)); Graph g1 = cg1.getGraph(); Node n1 = (Node) g1.getCentralNodeAt(1); Node n2 = (Node) g1.getCentralNodeAt(2); Node n3 = (Node) g1.getCentralNodeAt(3); Node n4 = (Node) g1.getCentralNodeAt(4); Node n5 = (Node) g1.getCentralNodeAt(5); Node n6 = (Node) g1.getCentralNodeAt(6); Node n7 = (Node) g1.getCentralNodeAt(7); g1.clearCentralNode(); g1.setCentralNode(1, n1); g1.setCentralNode(2, n3); g1.setCentralNode(3, n2); if (n7 != null) { g1.setCentralNode(7, n4); g1.setCentralNode(6, n5); g1.setCentralNode(5, n6); g1.setCentralNode(4, n7); } else if (n6 != null) { g1.setCentralNode(6, n4); g1.setCentralNode(5, n5); g1.setCentralNode(4, n6); } else if (n5 != null) { g1.setCentralNode(5, n4); g1.setCentralNode(4, n5); } else if (n4 != null) g1.setCentralNode(4, n4); k = rRT.findRateConstant(rs); } // Adding another elseif statement for Aaron Vandeputte rxn family // RMG expects to find *1 and *2 in the same ChemGraph (for this rxn family) // but will instead find *1 and *3 in the same ChemGraph (if we've reached this far) // Need to switch *2 and *3 else if (k == null && (rRT.name.equals("substitutionS") || rRT.name.equals("Substitution_O"))) { ChemGraph cg1 = ((ChemGraph) fproduct.get(0)); ChemGraph cg2 = ((ChemGraph) fproduct.get(1)); Graph g1 = cg1.getGraph(); Graph g2 = cg2.getGraph(); Node n3 = (Node) g1.getCentralNodeAt(3); if (n3 == null) { // Switch the identities of cg1/g1 and cg2/g2 cg1 = ((ChemGraph) fproduct.get(1)); g1 = cg1.getGraph(); cg2 = ((ChemGraph) fproduct.get(0)); g2 = cg2.getGraph(); n3 = (Node) g1.getCentralNodeAt(3); } Node n1 = (Node) g1.getCentralNodeAt(1); g1.clearCentralNode(); g1.setCentralNode(2, n3); g1.setCentralNode(1, n1); Node n2 = (Node) g2.getCentralNodeAt(2); g2.clearCentralNode(); g2.setCentralNode(3, n2); k = rRT.findRateConstant(rs); } else if (k == null && rRT.name.equals("intra_H_migration")) { ChemGraph cg = ((ChemGraph) fproduct.get(0)); Graph g = cg.getGraph(); // Current max is 8 identified nodes Node n1 = (Node) g.getCentralNodeAt(1); Node n2 = (Node) g.getCentralNodeAt(2); Node n3 = (Node) g.getCentralNodeAt(3); Node n4 = (Node) g.getCentralNodeAt(4); Node n5 = (Node) g.getCentralNodeAt(5); Node n6 = (Node) g.getCentralNodeAt(6); Node n7 = (Node) g.getCentralNodeAt(7); Node n8 = (Node) g.getCentralNodeAt(8); g.clearCentralNode(); // Swap the locations of the central nodes 1 and 2 g.setCentralNode(1, n2); g.setCentralNode(2, n1); // Retain the location of the central node at 3 g.setCentralNode(3, n3); if (n8 != null) { g.setCentralNode(4, n5); g.setCentralNode(5, n4); g.setCentralNode(6, n8); g.setCentralNode(7, n7); g.setCentralNode(8, n6); } else if (n7 != null) { g.setCentralNode(4, n5); g.setCentralNode(5, n4); g.setCentralNode(6, n7); g.setCentralNode(7, n6); } else if (n6 != null) { g.setCentralNode(4, n5); g.setCentralNode(5, n4); g.setCentralNode(6, n6); } else if (n5 != null) { // Swap the locations of the central nodes 4 and 5, if node 5 exists g.setCentralNode(4, n5); g.setCentralNode(5, n4); } else if (n4 != null) { // if only central node 4 exists, retain that location g.setCentralNode(4, n4); } k = rRT.findRateConstant(rs); // rr = rRT.calculateForwardRateConstant(cg, rs); // if (!rr.isForward()) { // String err = "Backward:" // + structure.toString() // + String.valueOf(structure // .calculateKeq(new Temperature(298, "K"))) // + '\n'; // err = err // + "Forward:" // + rr.structure.toString() // + String.valueOf(rr.structure // .calculateKeq(new Temperature(298, "K"))); // throw new InvalidReactionDirectionException(err); // } // rr.setReverseReaction(this); // rRT.addReaction(rr); // return rr; } else if (k == null && rRT.name.equals("H_shift_cyclopentadiene")) { ChemGraph cg = ((ChemGraph) fproduct.get(0)); Graph g = cg.getGraph(); // Current max is 6 identified nodes Node n1 = (Node) g.getCentralNodeAt(1); Node n2 = (Node) g.getCentralNodeAt(2); Node n3 = (Node) g.getCentralNodeAt(3); Node n4 = (Node) g.getCentralNodeAt(4); Node n5 = (Node) g.getCentralNodeAt(5); Node n6 = (Node) g.getCentralNodeAt(6); g.clearCentralNode(); // Swap the locations of the central nodes 1 to 6 g.setCentralNode(1, n2); g.setCentralNode(2, n1); g.setCentralNode(3, n5); g.setCentralNode(4, n4); g.setCentralNode(5, n3); g.setCentralNode(6, n6); k = rRT.findRateConstant(rs); } if (k == null) { Logger.error( "Couldn't find the rate constant for reaction: " + rs.toChemkinString(true) + " with " + rRT.name); // System.exit(0); return null; } rr = new TemplateReaction(rsSp, k, rRT); if (!rr.isForward()) { String err = "Backward:" + structure.toString() + String.valueOf(structure.calculateKeq(new Temperature(298, "K"))) + '\n'; err = err + "Forward:" + rr.structure.toString() + String.valueOf(rr.structure.calculateKeq(new Temperature(298, "K"))); throw new InvalidReactionDirectionException(err); } rr.setReverseReaction(this); rRT.addReaction(rr); return rr; // #] }
// ## operation writeChemkinReactions(ReactionModel) public static String writeChemkinPdepReactions( ReactionModel p_reactionModel, SystemSnapshot p_beginStatus) { // #[ operation writeChemkinReactions(ReactionModel) StringBuilder result = new StringBuilder(); // result.append("REACTIONS KCAL/MOLE\n"); String reactionHeader = ""; String units4Ea = ArrheniusKinetics.getEaUnits(); if (units4Ea.equals("cal/mol")) reactionHeader = "CAL/MOL\t"; else if (units4Ea.equals("kcal/mol")) reactionHeader = "KCAL/MOL\t"; else if (units4Ea.equals("J/mol")) reactionHeader = "JOULES/MOL\t"; else if (units4Ea.equals("kJ/mol")) reactionHeader = "KJOULES/MOL\t"; else if (units4Ea.equals("Kelvins")) reactionHeader = "KELVINS\t"; String units4A = ArrheniusKinetics.getAUnits(); if (units4A.equals("moles")) reactionHeader += "MOLES\n"; else if (units4A.equals("molecules")) reactionHeader += "MOLECULES\n"; result.append("REACTIONS\t" + reactionHeader); LinkedList pDepList = new LinkedList(); LinkedList nonPDepList = new LinkedList(); LinkedList duplicates = new LinkedList(); CoreEdgeReactionModel cerm = (CoreEdgeReactionModel) p_reactionModel; // first get troe and thirdbodyreactions for (Iterator iter = cerm.getReactionSet().iterator(); iter.hasNext(); ) { Reaction r = (Reaction) iter.next(); /* * 1Jul2009-MRH: * Added extra set of parenthesis. Before, if the rxn was reverse but an instance of * TROEReaction, it would also be added to the pDepList, resulting in RMG reporting * both rxns (forward and reverse) in the chem.inp file, w/o a DUP tag. Furthermore, * both rxns were given the same set of Arrhenius parameters. Running this in * Chemkin-v4.1.1 resulted in an error. */ if (r.isForward() && (r instanceof ThirdBodyReaction || r instanceof TROEReaction || r instanceof LindemannReaction)) { pDepList.add(r); } } for (Iterator iter = PDepNetwork.getNetworks().iterator(); iter.hasNext(); ) { PDepNetwork pdn = (PDepNetwork) iter.next(); for (ListIterator pdniter = pdn.getNetReactions().listIterator(); pdniter.hasNext(); ) { PDepReaction rxn = (PDepReaction) pdniter.next(); if (cerm.categorizeReaction(rxn) != 1) continue; // check if this reaction is not already in the list and also check if this reaction has a // reverse reaction // which is already present in the list. if (rxn.getReverseReaction() == null) rxn.generateReverseReaction(); if (!rxn.reactantEqualsProduct() && !pDepList.contains(rxn) && !pDepList.contains(rxn.getReverseReaction())) { pDepList.add(rxn); } } } LinkedList removeReactions = new LinkedList(); for (Iterator iter = p_reactionModel.getReactionSet().iterator(); iter.hasNext(); ) { Reaction r = (Reaction) iter.next(); boolean presentInPDep = false; if (r.isForward() && !(r instanceof ThirdBodyReaction) && !(r instanceof TROEReaction) && !(r instanceof LindemannReaction)) { Iterator r_iter = pDepList.iterator(); while (r_iter.hasNext()) { Reaction pDepr = (Reaction) r_iter.next(); if (pDepr.equals(r)) { // removeReactions.add(pDepr); // duplicates.add(pDepr); // if (!r.hasAdditionalKinetics()){ // duplicates.add(r); // presentInPDep = true; // } presentInPDep = true; nonPDepList.add(r); } } if (!presentInPDep) nonPDepList.add(r); } } for (Iterator iter = removeReactions.iterator(); iter.hasNext(); ) { Reaction r = (Reaction) iter.next(); pDepList.remove(r); } for (Iterator iter = pDepList.iterator(); iter.hasNext(); ) { Reaction r = (Reaction) iter.next(); // 6Jul2009-MRH: // Pass both system temperature and pressure to function toChemkinString. // The only PDepKineticsModel that uses the passed pressure is RATE result.append( r.toChemkinString(p_beginStatus.getTemperature(), p_beginStatus.getPressure()) + "\n"); // 10/26/07 gmagoon: eliminating use of Global.temperature; **** I use // beginStatus here, which may or may not be appropriate // result.append(r.toChemkinString(Global.temperature)+"\n"); } for (Iterator iter = nonPDepList.iterator(); iter.hasNext(); ) { Reaction r = (Reaction) iter.next(); result.append( r.toChemkinString(p_beginStatus.getTemperature(), p_beginStatus.getPressure()) + "\n"); // result.append(r.toChemkinString(Global.temperature)+"\n"); } for (Iterator iter = duplicates.iterator(); iter.hasNext(); ) { Reaction r = (Reaction) iter.next(); result.append( r.toChemkinString(p_beginStatus.getTemperature(), p_beginStatus.getPressure()) + "\n\tDUP\n"); // result.append(r.toChemkinString(Global.temperature)+"\n\tDUP\n"); } result.append("END\n"); return result.toString(); // #] }