public ThermoData generateSolvThermoData(ChemGraph p_chemGraph) { double r_solute = p_chemGraph.getRadius(); double r_solvent; r_solvent = 3.498 * Math.pow( 10, -10); // 3.311; // Manually assigned solvent radius [=] meter // Calculated using Connolly solvent excluded volume from Chem3dPro double r_cavity = r_solute + r_solvent; // Cavity radius [=] Angstrom double rho; rho = 0.00309 * Math.pow( 10, 30); // 0.00381; // number density of solvent [=] // molecules/Angstrom^3 Value here is for decane using density =0.73 g/cm3 double parameter_y = (88 / 21) * rho * Math.pow(r_solvent, 3); // Parameter y from Ashcraft Thesis Refer pg no. 60 double parameter_ymod = parameter_y / (1 - parameter_y); // parameter_ymod= y/(1-y) Defined for convenience double R = 8.314; // Gas constant units J/mol K double T = 298; // Standard state temperature // Definitions of K0, K1 and K2 correspond to those for K0', K1' and K2' respectively from // Ashcraft's Thesis double K0 = -R * (-Math.log(1 - parameter_y) + (4.5 * Math.pow(parameter_ymod, 2))); double K1 = (R * 0.5 / r_solvent) * ((6 * parameter_ymod) + (18 * Math.pow(parameter_ymod, 2))); double K2 = -(R * 0.25 / Math.pow(r_solvent, 2)) * ((12 * parameter_ymod) + (18 * Math.pow(parameter_ymod, 2))); // Basic definition of entropy change of solvation from Ashcfrat's Thesis double deltaS0; deltaS0 = K0 + (K1 * r_cavity) + (K2 * Math.pow(r_cavity, 2)); // Generation of Abraham Solute Parameters AbramData result_Abraham = new AbramData(); result_Abraham = p_chemGraph.getAbramData(); // Solute descriptors from the Abraham Model double S = result_Abraham.S; double B = result_Abraham.B; double E = result_Abraham.E; double L = result_Abraham.L; double A = result_Abraham.A; // Manually specified solvent descriptors (constants here are for decane) double c = 0.156; // -0.12; double s = 0; // 0.56; double b = 0; // 0.7; double e = -0.143; // -0.2; double l = 0.989; // 0.94; double a = 0; // 3.56; double logK = c + s * S + b * B + e * E + l * L + a * A; // Implementation of Abraham Model double deltaG0_octanol = -8.314 * 298 * logK; // System.out.println("The free energy of solvation in octanol at 298K w/o reference state // corrections = " + deltaG0_octanol +" J/mol for " ); // Calculation of enthalpy change of solvation using the data obtained above double deltaH0 = deltaG0_octanol + (T * deltaS0); deltaS0 = deltaS0 / 4.18; // unit conversion from J/mol to cal/mol deltaH0 = deltaH0 / 4180; // unit conversion from J/mol to kcal/mol // Generation of Gas Phase data to add to the solution phase quantities ThermoData solvationCorrection = new ThermoData( deltaH0, deltaS0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, "Solvation correction"); // Now, solvationCorrection contains solution phase estimates of CORRECTION TO H298, S298 and // all the gas phase heat capacities. // Assuming the solution phase heat capcities to be the same as that in the gas phase we wouls // now want to pass on this // modified version of result to the kinetics codes. This might require reading in a keyword // from the condition.txt file. // Exactly how this will be done is yet to be figured out. return solvationCorrection; // #] }
// ## 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; // #] }
public AbrahamGAValue getABGroup(ChemGraph p_chemGraph) { // #[ operation getGAGroup(ChemGraph) AbramData result_abram = new AbramData(); Graph g = p_chemGraph.getGraph(); HashMap oldCentralNode = (HashMap) (p_chemGraph.getCentralNode()).clone(); // satuate radical site int max_radNum_molecule = ChemGraph.getMAX_RADICAL_NUM(); int max_radNum_atom = Math.min(8, max_radNum_molecule); int[] idArray = new int[max_radNum_molecule]; Atom[] atomArray = new Atom[max_radNum_molecule]; Node[][] newnode = new Node[max_radNum_molecule][max_radNum_atom]; int radicalSite = 0; Iterator iter = p_chemGraph.getNodeList(); FreeElectron satuated = FreeElectron.make("0"); while (iter.hasNext()) { Node node = (Node) iter.next(); Atom atom = (Atom) node.getElement(); if (atom.isRadical()) { radicalSite++; // save the old radical atom idArray[radicalSite - 1] = node.getID().intValue(); atomArray[radicalSite - 1] = atom; // new a satuated atom and replace the old one Atom newAtom = new Atom(atom.getChemElement(), satuated); node.setElement(newAtom); node.updateFeElement(); } } // add H to satuate chem graph Atom H = Atom.make(ChemElement.make("H"), satuated); Bond S = Bond.make("S"); for (int i = 0; i < radicalSite; i++) { Node node = p_chemGraph.getNodeAt(idArray[i]); Atom atom = atomArray[i]; int HNum = atom.getRadicalNumber(); for (int j = 0; j < HNum; j++) { newnode[i][j] = g.addNode(H); g.addArcBetween(node, S, newnode[i][j]); } node.updateFgElement(); } // find all the thermo groups iter = p_chemGraph.getNodeList(); while (iter.hasNext()) { Node node = (Node) iter.next(); Atom atom = (Atom) node.getElement(); if (!(atom.getType().equals("H"))) { if (!atom.isRadical()) { p_chemGraph.resetThermoSite(node); AbrahamGAValue thisAbrahamValue = thermoLibrary.findAbrahamGroup(p_chemGraph); if (thisAbrahamValue == null) { System.err.println("Abraham group not found: " + node.getID()); } else { // System.out.println(node.getID() + " " + thisGAValue.getName()+ " // "+thisGAValue.toString()); result_abram.plus(thisAbrahamValue); } } else { System.err.println("Error: Radical detected after satuation!"); } } } // // find the BDE for all radical groups // for (int i=0; i<radicalSite; i++) { // int id = idArray[i]; // Node node = g.getNodeAt(id); // Atom old = (Atom)node.getElement(); // node.setElement(atomArray[i]); // node.updateFeElement(); // // // get rid of the extra H at ith site // int HNum = atomArray[i].getRadicalNumber(); // for (int j=0;j<HNum;j++) { // g.removeNode(newnode[i][j]); // } // node.updateFgElement(); // // p_chemGraph.resetThermoSite(node); // ThermoGAValue thisGAValue = thermoLibrary.findRadicalGroup(p_chemGraph); // if (thisGAValue == null) { // System.err.println("Radical group not found: " + node.getID()); // } // else { // //System.out.println(node.getID() + " radical correction: " + // thisGAValue.getName() + " "+thisGAValue.toString()); // result.plus(thisGAValue); // } // // //recover the satuated site for next radical site calculation // node.setElement(old); // node.updateFeElement(); // for (int j=0;j<HNum;j++) { // newnode[i][j] = g.addNode(H); // g.addArcBetween(node,S,newnode[i][j]); // } // node.updateFgElement(); // // } // // // recover the chem graph structure // // recover the radical // for (int i=0; i<radicalSite; i++) { // int id = idArray[i]; // Node node = g.getNodeAt(id); // node.setElement(atomArray[i]); // node.updateFeElement(); // int HNum = atomArray[i].getRadicalNumber(); // //get rid of extra H // for (int j=0;j<HNum;j++) { // g.removeNode(newnode[i][j]); // } // node.updateFgElement(); // } // // // substrate the enthalphy of H from the result // int rad_number = p_chemGraph.getRadicalNumber(); // ThermoGAValue enthalpy_H = new ThermoGAValue(ENTHALPY_HYDROGEN * rad_number, // 0,0,0,0,0,0,0,0,0,0,0,null); // result.minus(enthalpy_H); // // // make the symmetric number correction to entropy // // if (p_chemGraph.isAcyclic()){ // int sigma = p_chemGraph.getSymmetryNumber(); // ThermoGAValue symmtryNumberCorrection = new // ThermoGAValue(0,GasConstant.getCalMolK()*Math.log(sigma),0,0,0,0,0,0,0,0,0,0,null); // result.minus(symmtryNumberCorrection); // } p_chemGraph.setCentralNode(oldCentralNode); return result_abram; // #] }