Esempio n. 1
0
    def getConectivity(self, mol):
        size =len(mol.get_positions())
        dRef = ct.refBonds(mol)
        bondMat = ct.bondMatrix(dRef,mol)
        bondList = []
        angleList = []
        angleListTemp = []
        dihedralList = []
        LJList=[]
        fullBonds = []
        #Loop through bond matrix and add any bonds to the list
        for i in range(0,size):
            bondedToAtom = []
            for j in range(i,size):
                if bondMat[i][j] == 1.0:
                    K,re_eq = self.getBondParams(i,j,self.types)
                    bondList.append((i,j,K,re_eq))
                    bondedToAtom.append(j)
            fullBonds.append(bondedToAtom)

        #Loop through bond matrix and add any angles to the list
        #Must be a cleverer way to do this
        for i in range(0,size):
            for j in range(0,size):
                for k in range(0,size):
                    if bondMat[i][j] == 1.0 and (bondMat[j][k] == 1.0) and i != k:
                        if self.types[i] != self.types[k]:
                            a,b = self.types[i],self.types[k]
                        else:
                            a,b = i,k
                        if a <= b:
                            K,theta_eq = self.getAngleParams(i,j,k,self.types)
                            angleList.append((i,j,k,K,theta_eq))
                        if a > b:
                            K,theta_eq = self.getAngleParams(k,j,i,self.types)
                            angleList.append((k,j,i,K,theta_eq))
                        angleList = self.f7(angleList)
        for i in range(0,size):
            sigma,epsilon = self.getLJParams(i,self.types)
            LJList.append((sigma,epsilon))
        #Loop through bond matrix and add any dihedral to the list
        for i in range(0,size):
            for j in range(i,size):
                for k in range(0,size):
                    for l in range(0,size):
                        if bondMat[i][j] == 1.0 and bondMat[j][k] == 1.0 and bondMat[k][l] == 1.0 and self.noDuplicates([i,j,k,l]):
                            a,b = self.types[i],self.types[l]
                            if a > b:
                                V1,V2,V3 = self.getDihedralParams(l,k,j,i,self.types)
                            elif a <= b:
                                V1, V2, V3 = self.getDihedralParams(i, j, k, l, self.types)
                            if V1 != 0 or V2 != 0 or V3 != 0:
                                dihedralList.append((i,j,k,l,V1,V2,V3))
        return bondList,angleList,dihedralList,LJList
Esempio n. 2
0
 def ReactionType(self, mol):
     oldbonds = np.count_nonzero(self.C)
     self.dRef = CT.refBonds(mol)
     self.C = CT.bondMatrix(self.dRef, mol)
     newbonds = np.count_nonzero(self.C)
     if oldbonds > newbonds:
         reacType = 'Dissociation'
     if oldbonds < newbonds:
         reacType = 'Association'
     if oldbonds == newbonds:
         reacType = 'Isomerisation'
     return reacType
Esempio n. 3
0
 def __init__(self, species, xyz):
     self.species = species
     # Get reference bonds
     self.dRef = ct.refBonds(species)
     self.dratio = self.dRef
     # Create bonding matrix
     self.bondMat = ct.bondMatrix(self.species, self.dRef, xyz, self.dratio)
     self.criteriaMet = False
     self.breakingBond = (0,0)
     self.makingBond = (0,0)
     self.bondMatTemp = self.bondMat
     self.secondCriteriaMet = False
     self.secondBreakingBond = (0,0)
     self.secondMakingBond = (0,0)
Esempio n. 4
0
 def del_constraint(self, mol):
     if self.boundHit == "lower":
         n = self.boxList[self.box].lower.norm
     elif self.boundHit == "upper":
         n = self.boxList[self.box].upper.norm
     elif self.boundHit == "path":
         if self.pathNode == (len(self.path) - 1) or self.pathNode == len(
                 self.path):
             segmentStart = self.path[self.pathNode - 1][0]
             segmentEnd = self.path[self.pathNode][0]
             # Total path distance up to current segment
             TotalDistance = self.path[self.pathNode][1]
         else:
             segmentStart = self.path[self.pathNode][0]
             segmentEnd = self.path[self.pathNode + 1][0]
             # Total path distance up to current segment
             TotalDistance = self.path[self.pathNode][1]
         # Projection along linear segment only
         SegDistance = self.s[2] - TotalDistance
         # Get vector for and length of linear segment
         vec = segmentEnd - segmentStart
         length = np.linalg.norm(vec)
         # finally get distance of projected point along vec
         plength = segmentStart + ((SegDistance / length) * vec)
         perpendicularPath = (self.s[0] - plength)
         n = perpendicularPath / np.linalg.norm(perpendicularPath)
     self.del_phi = ct.genBXDDel(mol, self.s[0], self.sInd, n)
     return self.del_phi
Esempio n. 5
0
 def Update(self, xyz):
     self.bondMatTemp = ct.bondMatrix(self.species, self.dRef, xyz)
     atom1 = 0
     atom2 = 0
     atom3 = 0
     for i in self.species.size:
         bond = 0.0
         nonBond = 100.0
         for j in self.species.size:
             if self.bondMat[i][j] == 1.0 and self.dratio > bond:
                 bond = self.dratio
                 atom1 = i
                 atom2 = j
             if self.bondMat[i][j] == 0.0 and self.dratio[i][j] < nonBond:
                 nonBond = self.dratio[i][j]
                 atom3 = j
         if bond > nonBond:
             if self.criteriaMet is False:
                 self.criteriaMet = True
                 self.makingBond = (atom1,atom3)
                 self.breakingBond = (atom1,atom2)
             else:
                 self.secondCriteriaMet = True
                 self.secondMakingBond = (atom1, atom3)
                 self.secondBreakingBond = (atom1, atom2)
Esempio n. 6
0
 def convertToS(self, mol, activeS):
     # First get S
     S = ct.getDistMatrix(mol, activeS)
     if self.sInd == 0:
         self.sInd = S[1]
         self.reac = S[0]
     try:
         Snorm, project, node, dist = ct.projectPointOnPath(
             S[0], self.path, self.pathType,
             self.boxList[self.box].lower.norm,
             self.boxList[self.box].lower.D, self.reac, self.pathNode,
             self.reverse)
     except:
         Snorm = 0
         project = 0
         node = False
         dist = 0
     return S[0], Snorm, project, node, dist
Esempio n. 7
0
 def convertStoBound(self, s1, s2):
     if self.fixToPath == False:
         b = self.convertStoBoundGeneral(s1, s2)
     else:
         s1vec = ct.projectPointOnPath(s1, self.path, self.pathType,
                                       self.boxList[self.box].lower.norm,
                                       self.boxList[self.box].lower.D,
                                       self.reac, self.pathNode,
                                       self.reverse)
         s2vec = ct.projectPointOnPath(s2, self.path, self.pathType,
                                       self.boxList[self.box].lower.norm,
                                       self.boxList[self.box].lower.D,
                                       self.reac, self.pathNode,
                                       self.reverse)
         if self.reverse:
             b = self.convertStoBoundOnPath(s1vec[1], s1vec[2], s1)
         else:
             b = self.convertStoBoundOnPath(s2vec[1], s2vec[2], s2)
     return b
Esempio n. 8
0
 def ReactionType(self, xyz):
     oldbonds = np.count_nonzero(self.bondMat)
     self.bondMat = ct.bondMatrix(self.species,self.dref, xyz)
     newbonds = np.count_nonzero(self.bondMat)
     if oldbonds > newbonds:
         reacType = 'Dissociation'
     if oldbonds < newbonds:
         reacType = 'Association'
     if oldbonds == newbonds:
         reacType = 'Isomerisation'
     return reacType
Esempio n. 9
0
def run(gl):
    #Read reactant definition
    if gl.StartType == 'file':
        Reac = read(gl.Start)
    elif gl.StartType == 'Smile':
        Reac = tl.getMolFromSmile(gl.Start)
    #Read product definition
    if gl.EndType == 'file':
        Prod= read(gl.End)
    elif gl.EndType == 'Smile':
        Prod = tl.getMolFromSmile(gl.End)

    #Set calculatiors
    #Reac = tl.setCalc(Reac,"DOS/", gl.trajMethod, gl.atomTypes)
    if gl.trajMethod == "openMM":
        Reac = tl.setCalc(Reac,"GenBXD/", gl.trajMethod, gl)
    else:
        Reac = tl.setCalc(Reac,"GenBXD/", gl.trajMethod, gl.trajLevel)
        Prod = tl.setCalc(Prod,"GenBXD/", gl.trajMethod, gl.trajLevel)
    # Partially minimise both reactant and product
    if gl.GenBXDrelax:
        min = BFGS(Reac)
        try:
            min.run(fmax=0.1, steps=20)
        except:
            min.run(fmax=0.1, steps=20)
        min2 = BFGS(Prod)
        try:
            min2.run(fmax=0.1, steps=20)
        except:
            min2.run(fmax=0.1, steps=20)

    # Get important interatomic distances
    if gl.CollectiveVarType == "changedBonds":
        cbs = ct.getChangedBonds2(Reac, Prod)
    elif gl.CollectiveVarType == "all":
        cbs = ct.getChangedBonds2(Reac, Prod)
    elif gl.CollectiveVarType == "specified":
        cbs = gl.CollectiveVar
    elif gl.CollectiveVarType == "file":
        cbs = gl.principalCoordinates

    #Get path to project along
    distPath = []
    totalPathLength = 0
    if gl.PathType == 'curve' or gl.PathType == 'gates':
        if gl.PathFile == 'none':
            Path = getPath(Reac,Prod,gl)
        else:
            Path = read(gl.PathFile,index=('::'+str(gl.pathStride)))

        distPath.append((ct.getDistMatrix(Path[0],cbs)[0],0))
        for i in range(1,len(Path)):
            l = np.linalg.norm(ct.getDistMatrix(Path[i],cbs)[0] - ct.getDistMatrix(Path[i-1], cbs)[0])
            totalPathLength += l
            distPath.append((ct.getDistMatrix(Path[i],cbs)[0],totalPathLength))
    elif gl.PathType == 'linear':
        distPath = ct.getDistMatrix(Prod,cbs)[0] - ct.getDistMatrix(Reac, cbs)[0]

    if gl.PathType == 'curve' or gl.PathType == 'gates':
        pathFile = open('reducedPath.txt','w')
        for p in distPath:
            pathFile.write('s = ' + str(p[0]) + '\n')
        pathFile.close()



    # initialise then run trajectory
    t = Trajectory.Trajectory(Reac,gl,os.getcwd(),0,False)
    t.runGenBXD(Reac,Prod,gl.maxHits,gl.maxAdapSteps,gl.PathType,distPath, cbs, gl.decorrelationSteps, gl.histogramBins,totalPathLength, gl.fixToPath, gl.pathDistCutOff,gl.epsilon)
Esempio n. 10
0
 def del_constraint(self, mol):
     self.del_phi = ct.getCOMdel(mol, self.activeS)
     return self.del_phi
Esempio n. 11
0
 def getS(self, mol):
     self.COM = ct.getCOMdist(mol, self.activeS)
     return (self.COM, self.COM, self.COM)
Esempio n. 12
0
 def reinitialise(self, xyz):
     self.bondMat = ct.bondMatrix(self.species, self.dRef, xyz)
     self.criteriaMet = False
     self.breakingBond = (0,0)
     self.makingBond = (0,0)
     self.secondCriteriaMet = False
Esempio n. 13
0
 def reinitialise(self, mol):
     self.dRef = CT.refBonds(mol)
     self.C = CT.bondMatrix(self.dRef, mol)
     self.transitionIdices = np.zeros(3)
Esempio n. 14
0
 def __init__(self, mol):
     self.dRef = CT.refBonds(mol)
     self.C = CT.bondMatrix(self.dRef, mol)
     self.transitionIndices = np.zeros(3)
     self.criteriaMet = False
Esempio n. 15
0
def runNormal(p):
    try:
        #If additional atoms have been added then update baseline dictionary
        #This only occurs when an extra bimolecular channel is added
        if len(p) > 6:
            print("correcting baseline for bi reaction")
            sym = "".join(p[6].get_chemical_symbols())
            TotSym = "".join(p[0].CombReac.get_chemical_symbols())
            print(str(sym) + " " + str(TotSym))
            base = p[0].energyDictionary[TotSym]
            p[0].energyDictionary[TotSym + sym] = p[0].TempBiEne(p[6]) + base
            print(str(base))
        # Run Trajectory
        p[1].runTrajectory()
        print('trajectory done')
        print(p[1].productGeom)
        # Geom opt part
        # Optimise Product
        p[0].optProd(p[1].productGeom, False)

        #Get prod Name and create directory
        prodpath = p[2] + '/' + str(p[0].ProdName)

        #Get the indicies of the bonds which have either formed or broken over the course of the reaction
        changedBonds = CT.getChangedBonds(p[0].CombReac, p[0].CombProd)
        print('changesBonds ' + str(changedBonds))
        print(str(p[0].ProdName))
        # Check the reaction product is not the orriginal reactant
        if p[0].ProdName != p[0].ReacName:

            # Make Directory for product
            if not os.path.exists(prodpath):
                os.makedirs(prodpath)
                p[0].printProd(prodpath)

                # TS optimisation
                try:
                    p[0].optTSpoint(changedBonds, prodpath, p[1].MolList,
                                    p[1].TSpoint, 0)
                except:
                    # If TS opt fails for some reason, assume barrierless
                    print('Couldnt opt TS at trans point')
                    p[0].barrierlessReaction = True

                printTS2 = False
                printXML = True

                if p[0].TScorrect != True:
                    # See whether a dynamical path calculation or an NEB calculation has been specified to refine TS
                    if p[5].printDynPath == True:
                        try:
                            p[0].optDynPath(changedBonds, prodpath,
                                            p[1].MolList, p[1].TSpoint)
                        except:
                            print("DynPath failed")
                    elif p[5].printNEB == True:
                        try:
                            p[0].optNEB(changedBonds, prodpath,
                                        p[1].changePoints, p[1].MolList)
                        except:
                            print("NEB failed")
                    if p[0].TS2correct == True:
                        printTS2 = True

                # check whether there is an alternate product
                #if p[0].checkAltProd == True and p[0].is_IntermediateProd == True:
                #    p[0].optProd(p[1].productGeom, True)

                # Check some criteria before printing to xml
                # if Isomerisation check there is a TS
                if p[0].is_bimol_prod == False and p[
                        0].is_bimol_reac == False and p[
                            0].barrierlessReaction == True:
                    p[0].barrierlessReaction = False
                    printXML = True

                #Then check barrier isnt ridiculous
                if (((p[0].forwardBarrier - p[0].reactantEnergy) * 96.45) >
                        500):
                    printXML = False
                    print('channel barrier too large')

                # Finally check that the product isnt higher in energy than the reactant in case of ILT
                if p[0].is_bimol_reac == True and p[
                        0].barrierlessReaction == True and p[
                            0].reactantEnergy < p[0].productEnergy:
                    printXML = False

                if printXML == True:
                    try:
                        io.writeTSXML(p[0], p[3])
                        io.writeTSXML(p[0], p[3].replace('.xml', 'Full.xml'))
                    except:
                        print('Couldnt print TS1')

                    if printTS2 == True:
                        try:
                            io.writeTSXML2(p[0], p[3])
                            io.writeTSXML2(p[0],
                                           p[3].replace('.xml', 'Full.xml'))
                        except:
                            print('Couldnt print TS2')

                    tmppath = p[3].replace('/MESMER/mestemplate.xml', '/')
                    tmppath = tmppath + p[0].ProdName

                    data = open(('MechanismData.txt'), "a")
                    data.write('Reactant = ' + str(p[0].ReacName) +
                               ' Product = ' + str(p[0].ProdName) +
                               ' BarrierHeight = ' +
                               str((p[0].forwardBarrier -
                                    p[0].reactantEnergy) * 96.45) + '\n')

                    if not os.path.exists(tmppath):
                        io.writeMinXML(p[0], p[3], False, False)
                        if p[0].is_bimol_prod == True:
                            io.writeMinXML(p[0], p[3], False, True)
                    if not os.path.exists(tmppath + "/" + p[0].ReacName):
                        io.writeReactionXML(p[0], p[3], printTS2)
                        io.writeReactionXML(p[0],
                                            p[3].replace('.xml',
                                                         'Full.xml'), printTS2)

        if (p[5].InitialBi == True):
            p[0].re_init_bi(p[5].cartesians, p[5].species)
        else:
            p[0].re_init(p[2])
        return p[0], p[1]
    except:
        if (p[5].InitialBi == True):
            p[0].re_init_bi(p[5].cartesians, p[5].species)
        else:
            p[0].re_init(p[2])
        return p[0], p[1]
Esempio n. 16
0
def run(glo):

    # Get path to current directory
    path = os.getcwd()

    #Check whether there is a directory for putting calcuation data in. If not create it
    if not os.path.exists(path + '/Raw'):
        os.mkdir(path + '/Raw')

    #Set restart bool for now
    glo.restart = True

    # Add system name to path
    syspath = path + '/' + glo.dirName

    #Make working directories for each core
    for i in range(0, glo.cores):
        if not os.path.exists(path + '/Raw/' + str(i)):
            os.mkdir(path + '/Raw/' + str(i))

    #Start counter which tracks the kinetic timescale
    mechanismRunTime = 0.0

    #Set reaction instance
    reacs = dict(
        ("reac_" + str(i), rxn.Reaction(glo.cartesians, glo.species, i, glo))
        for i in range(glo.cores))

    #Initialise Master Equation object
    me = MasterEq.MasterEq()

    # Open files for saving summary
    mainsumfile = open(('mainSummary.txt'), "a")

    while mechanismRunTime < glo.maxSimulationTime:

        # Minimise starting Geom and write summary xml for channel
        if reacs['reac_0'].have_reactant == False:
            outputs = []
            if __name__ == 'Main':
                arguments = []
                for i in range(0, glo.cores):
                    name = 'reac_' + str(i)
                    arguments.append(reacs[name])
                p = multiprocessing.Pool(glo.cores)
                results = p.map(minReac, arguments)
                outputs = [result for result in results]

            for i in range(0, glo.cores):
                name = 'reac_' + str(i)
                reacs[name] = outputs[i]

        else:
            for i in range(0, glo.cores):
                name = 'reac_' + str(i)
                reacs[name].have_reactant = False

        # Update path for new minima
        minpath = syspath + '/' + reacs['reac_0'].ReacName

        # Get smiles name for initial geom and create directory for first minimum
        if not os.path.exists(minpath):
            os.makedirs(minpath)

        #Copy MESMER file from mes folder
        MESpath = syspath + '/MESMER/'
        symb = "".join(reacs[name].CombReac.get_chemical_symbols())
        if reacs['reac_0'].energyDictionary[symb] == 0.0:
            for i in range(0, glo.cores):
                name = 'reac_' + str(i)
                d = {symb: reacs[name].reactantEnergy}
                reacs[name].energyDictionary.update(d)

        # If a MESMER file has not been created for the current minima then create one
        if not os.path.exists(MESpath):
            os.makedirs(MESpath)
            copyfile('mestemplate.xml', MESpath + 'mestemplate.xml')
            copyfile('mestemplate.xml', MESpath + 'mestemplateFull.xml')
            MESFullPath = MESpath + 'mestemplateFull.xml'
            MESpath = MESpath + 'mestemplate.xml'
            io.writeMinXML(reacs['reac_0'], MESpath, True, False)
            io.writeMinXML(reacs['reac_0'], MESFullPath, True, False)
            if reacs['reac_0'].is_bimol_reac == True:
                io.writeMinXML(reacs['reac_0'], MESpath, True, True)
                io.writeMinXML(reacs['reac_0'], MESFullPath, True, True)
            glo.restart = False
        else:
            MESFullPath = MESpath + 'mestemplateFull.xml'
            MESpath = MESpath + 'mestemplate.xml'

        # If this is a restart then need to find the next new product from the ME, otherwise start trajectories
        if glo.restart == False:
            # Open files for saving summary
            sumfile = open((minpath + '/summary.txt'), "w")

            reacs['reac_0'].printReac(minpath)
            for r in range(0, glo.ReactIters):
                tempPaths = dict(("tempPath_" + str(i),
                                  minpath + '/temp' + str(i) + '_' + str(r))
                                 for i in range(glo.cores))
                # Now set up tmp directory for each thread
                for i in range(0, glo.cores):
                    if not os.path.exists(tempPaths[('tempPath_' + str(i))]):
                        os.makedirs(tempPaths[('tempPath_' + str(i))])

                if r % 2 == 0:
                    glo.trajMethod = glo.trajMethod1
                    glo.trajLevel = glo.trajLevel1
                else:
                    glo.trajMethod = glo.trajMethod2
                    glo.trajLevel = glo.trajLevel2

                # If this is the first species and it is a bimolecular channel, then initialise a bimolecular trajectory
                # Otherwise initialise unimolecular trajectory at minima
                if glo.InitialBi == True:
                    trajs = dict(
                        ("traj_" + str(i),
                         Trajectory.Trajectory(
                             reacs[('reac_' +
                                    str(i))].CombReac, glo, tempPaths[(
                                        'tempPath_' + str(i))], str(i), True))
                        for i in range(glo.cores))
                else:
                    trajs = dict(
                        ("traj_" + str(i),
                         Trajectory.Trajectory(
                             reacs[('reac_' +
                                    str(i))].CombReac, glo, tempPaths[(
                                        'tempPath_' + str(i))], str(i), False))
                        for i in range(glo.cores))

                results2 = []
                outputs2 = []
                if __name__ == "Main":
                    arguments1 = []
                    arguments2 = []
                    for i in range(0, glo.cores):
                        name = 'reac_' + str(i)
                        name2 = 'traj_' + str(i)
                        arguments1.append(reacs[name])
                        arguments2.append(trajs[name2])
                    arguments = list(
                        zip(arguments1, arguments2,
                            [minpath] * glo.cores, [MESpath] * glo.cores,
                            range(glo.cores), [glo] * glo.cores))
                    p = multiprocessing.Pool(glo.cores)
                    results2 = p.map(runNormal, arguments)
                    outputs2 = [result for result in results2]

                for i in range(0, glo.cores):
                    name = 'reac_' + str(i)
                    reacs[name] = outputs2[i][0]
                    sumfile.write(
                        str(reacs[name].ProdName) + '_' +
                        str(reacs[name].biProdName) + '\t' +
                        str(reacs[name].forwardBarrier) + '\t' +
                        str(outputs2[i][1].numberOfSteps))
                    sumfile.flush()

            # run a master eqution to estimate the lifetime of the current species
            me.runTillReac(MESpath)
            me.newSpeciesFound = False

            # check whether there is a possible bimolecular rection for current intermediate
            if len(glo.BiList) > 0 and glo.InitialBi == False:
                for i in range(0, len(glo.BiList)):
                    baseXYZ = reacs['reac_0'].CombReac.get_chemical_symbols()
                    if me.time > (1 / float(glo.BiRates[i])):
                        print(
                            "assessing whether or not to look for bimolecular channel. Rate = "
                            + str(float(glo.BiRates[i])) +
                            "Mesmer reaction time = " + str(me.time))
                        glo.InitialBi = True
                        xyz = CT.get_bi_xyz(reacs['reac_0'].ReacName,
                                            glo.BiList[i])
                        spec = np.append(
                            baseXYZ,
                            np.array(glo.BiList[i].get_chemical_symbols()))
                        combinedMol = Atoms(symbols=spec, positions=xyz)
                        #Set reaction instance
                        for j in range(0, glo.cores):
                            name = 'reac_' + str(j)
                            d = {symb: reacs[name].reactantEnergy}
                            reacs[name].re_init_bi(xyz, spec)
                            biTrajs = dict(
                                ("traj_" + str(k),
                                 Trajectory.Trajectory(
                                     combinedMol, glo, tempPaths[(
                                         'tempPath_' + str(k))], str(k), True))
                                for k in range(glo.cores))
                            biTempPaths = dict(("tempPath_" + str(k),
                                                minpath + '/temp' + str(j))
                                               for k in range(glo.cores))
                        if __name__ == "Main":
                            arguments1 = []
                            arguments2 = []
                            for j in range(0, glo.cores):
                                name = 'reac_' + str(j)
                                name2 = 'traj_' + str(j)
                                biTrajs[name2].fragIdx = (len(baseXYZ),
                                                          len(xyz))
                                arguments1.append(reacs[name])
                                arguments2.append(biTrajs[name2])
                            arguments = list(
                                zip(arguments1, arguments2,
                                    [minpath] * glo.cores,
                                    [MESpath] * glo.cores, range(glo.cores),
                                    [glo] * glo.cores,
                                    [glo.BiList[i]] * glo.cores))
                            p = multiprocessing.Pool(glo.cores)
                            p.map(runNormal, arguments)
                            glo.InitialBi = False

            # Run ME from the given minimum. While loop until species formed is new
            sumfile.close()
            glo.restart = False
        glo.InitialBi = False
        while me.newSpeciesFound == False:
            me.runTillReac(MESpath)
            mechanismRunTime += me.time
            out = me.prodName + '     ' + str(mechanismRunTime) + '\n'
            me.visitedList.append(me.prodName)
            mainsumfile.write(out)
            mainsumfile.flush()
            if not os.path.exists(syspath + '/' + me.prodName):
                os.makedirs(syspath + '/' + me.prodName)
                for i in range(0, glo.cores):
                    if os.path.exists(syspath + '/' +
                                      reacs[('reac_' + str(i))].ReacName +
                                      '/' + me.prodName):
                        reacs[('reac_' + str(i))].newReac(
                            syspath + '/' +
                            reacs[('reac_' + str(i))].ReacName + '/' +
                            me.prodName, me.prodName, False)
                    else:
                        print("cant find path " + str(syspath + '/' + reacs[
                            ('reac_' + str(i))].ReacName + '/' + me.prodName))
                        try:
                            reacs[('reac_' + str(i))].newReac(
                                syspath + '/' + me.prodName, me.prodName, True)
                        except:
                            reacs[('reac_' + str(i))].newReacFromSMILE(
                                me.prodName)
                io.update_me_start(me.prodName, me.ene, MESpath)
                me.newSpeciesFound = True
            else:
                if me.repeated() == True:
                    me.equilCount += 1
                    if me.equilCount >= 20:
                        mainsumfile.write('lumping' + ' ' +
                                          str(reacs['reac_0'].ReacName) + ' ' +
                                          str(me.prodName) + '\n')
                        me.prodName = io.lumpSpecies(reacs['reac_0'].ReacName,
                                                     me.prodName, MESpath,
                                                     MESpath)
                        mainsumfile.flush()
                        me.equilCount = 1
                minpath = syspath + '/' + me.prodName
                for i in range(0, glo.cores):
                    if os.path.exists(syspath + '/' +
                                      reacs[('reac_' + str(i))].ReacName +
                                      '/' + me.prodName):
                        reacs[('reac_' + str(i))].newReac(
                            syspath + '/' +
                            reacs[('reac_' + str(i))].ReacName + '/' +
                            me.prodName, me.prodName, False)
                    else:
                        try:
                            reacs[('reac_' + str(i))].newReac(
                                syspath + '/' + me.prodName, me.prodName, True)
                        except:
                            reacs[('reac_' + str(i))].newReacFromSMILE(
                                me.prodName)
                io.update_me_start(me.prodName, me.ene, MESpath)

        me.newspeciesFound = False
        glo.restart = False

    mainsumfile.close()