示例#1
0
 def FromSystem(selfClass,
                system,
                electronicState1,
                electronicState2,
                method="GP"):
     """Constructor given a system."""
     # . Basic setup.
     system.electronicState = electronicState1
     self = super(SEAMObjectiveFunction, selfClass).FromSystem(system)
     self.method = method
     # . Define the first system.
     self.system1 = self.system
     # . Define the second system without coordinates.
     coordinates3 = self.system1.coordinates3
     symmetryParameters = self.system1.symmetryParameters
     self.system1.coordinates3 = None
     self.system1.symmetryParameters = None
     self.system2 = Clone(self.system1)
     self.system2.electronicState = electronicState2
     # . Reset the coordinates for both systems so that they are the same.
     self.system1.coordinates3 = coordinates3
     self.system2.coordinates3 = coordinates3
     if symmetryParameters is not None:
         self.system1.symmetryParameters = symmetryParameters
         self.system2.symmetryParameters = symmetryParameters
     # . Allocate space.
     self.g1 = Real1DArray.WithExtent(len(self))
     self.g2 = Real1DArray.WithExtent(len(self))
     # . Finish up.
     return self
 def AddLinearConstraint ( self, constraint ):
     """Add a linear constraint."""
     if len ( constraint ) != self.nvariables: raise ValueError ( "Invalid linear constraint length." )
     # . Orthogonalize to existing constraints.
     if self.linearVectors is not None:
         constraint = Clone ( constraint )
         self.linearVectors.ProjectOutOfArray ( constraint )
     # . Check to see if the constraint is valid.
     cnorm2 = constraint.Norm2 ( )
     if cnorm2 > 1.0e-10:
         constraint.Scale ( 1.0 / cnorm2 )
         # . Allocate space for new constraints.
         ncolumns = 1
         if self.linearVectors is not None: ncolumns += self.linearVectors.columns
         newconstraints = Real2DArray.WithExtents ( len ( constraint ), ncolumns )
         # . Copy over constraints.
         if self.linearVectors is not None:
             for r in range ( self.linearVectors.rows ):
                 for c in range ( self.linearVectors.columns ):
                     newconstraints[r,c] = self.linearVectors[r,c]
         for r in range ( len ( constraint ) ): newconstraints[r,ncolumns-1] = constraint[r]
         self.linearVectors = newconstraints
         # . Determine the linear scalars.
         self.linearScalars = Real1DArray.WithExtent ( self.linearVectors.columns )
         reference          = Real1DArray.WithExtent ( self.linearVectors.rows    )
         if self.rtReference is None: self.system.coordinates3.CopyToArray ( reference )
         else:                        self.rtReference.CopyToArray ( reference )
         self.linearVectors.VectorMultiply ( reference, self.linearScalars, 1.0, 0.0, transpose = True )
         # . Reset the number of degrees of freedom.
         self.degreesOfFreedom = self.nvariables - len ( self.linearScalars )
示例#3
0
def WHAM_Bootstrapping(paths, **keywordArguments):
    """Solve the WHAM equations and estimate errors using bootstrapping."""
    # . Get specific options.
    options = dict(keywordArguments)
    log = options.get("log", logFile)
    minimizer = options.pop("minimizerFunction",
                            WHAM_ConjugateGradientMinimize)
    resamples = options.pop("resamples", _Default_Resamples)
    # . Initial minimization - it must succeed to proceed.
    results = minimizer(paths, **dict(options))
    if results["Converged"]:
        # . Reset options for resampling.
        options["handler"] = results.pop("Handler")
        options["histogram"] = Clone(results.pop("Unreduced Histogram"))
        options["log"] = None
        # . Resampling minimizations.
        pmfs = []
        for r in range(resamples):
            localResults = minimizer(paths, **dict(options))
            if localResults["Converged"]: pmfs.append(localResults.pop("PMF"))
        # . Process results.
        numberOfResamples = len(pmfs)
        results.update({
            "Number Of Resamples": numberOfResamples,
            "PMFs": pmfs
        })
        if numberOfResamples > 1:
            # . Gather some counters.
            lowerIndex = int(math.ceil(
                0.5 * _Alpha * float(numberOfResamples))) - 1
            upperIndex = int(
                math.floor(
                    (1.0 - 0.5 * _Alpha) * float(numberOfResamples))) - 1
            # . Do statistics.
            originalPMF = results["PMF"]
            lowerLimit = Real1DArray.WithExtent(len(originalPMF))
            standardError = Real1DArray.WithExtent(len(originalPMF))
            upperLimit = Real1DArray.WithExtent(len(originalPMF))
            work = Real1DArray.WithExtent(numberOfResamples)
            for b in range(len(originalPMF)):
                for (r, pmf) in enumerate(pmfs):
                    work[r] = pmf[b]
                work.Sort()
                m = originalPMF[b]
                lowerLimit[b] = 2.0 * m - work[upperIndex]
                upperLimit[b] = 2.0 * m - work[lowerIndex]
                standardError[b] = Statistics(work).standardDeviation
            # . Printing.
            data = (("Standard Error", standardError),
                    ("Lower 95% Confidence Interval", lowerLimit),
                    ("Upper 95% Confidence Interval", upperLimit))
            _BootstrappingSummary(results["Histogram"], log, numberOfResamples,
                                  originalPMF, standardError, lowerLimit,
                                  upperLimit)
            # . Finish up.
            for (key, value) in data:
                results[key] = value
    return results
示例#4
0
 def Initialize(self,
                pressure=_Default_Pressure,
                temperature=_Default_Temperature):
     """Create the arrays needed for the WHAM equations."""
     # . Initialization.
     handler = self.handler
     histogram = self.histogram
     if (handler is not None) and (histogram is not None):
         p0 = pressure * UNITS_PRESSURE_ATMOSPHERES_TO_KILOJOULES_PER_MOLE
         t0 = temperature * CONSTANT_MOLAR_GAS * 1.0e-3
         # . Gather pressures and temperatures.
         pressures = []
         temperatures = []
         for (p, t) in zip(handler.pressures, handler.temperatures):
             if p is None: p = pressure
             if t is None: t = temperature
             pressures.append(
                 p * UNITS_PRESSURE_ATMOSPHERES_TO_KILOJOULES_PER_MOLE)
             temperatures.append(t * CONSTANT_MOLAR_GAS * 1.0e-3)
         # . Create c which in the most general case is Exp ( - ( (Bj - B0) * U_i + (Bj*Pj - B0*P0) * V_i + Bj * SC_ji ) ).
         c = Real2DArray.WithExtents(handler.numberOfWindows,
                                     histogram.bins)
         c.Set(0.0)
         for (i, midPoint) in enumerate(histogram.BinMidPointIterator()):
             # . Energy.
             if handler.hasEnergy:
                 e = midPoint.pop(0)
                 for (j, tj) in enumerate(temperatures):
                     c[j, i] += e * (1.0 / tj - 1.0 / t0)
             # . Volume.
             if handler.hasVolume:
                 v = midPoint.pop(0)
                 for (j, pj) in enumerate(pressures):
                     c[j, i] += v * (pj / tj - p0 / t0)
             # . Soft constraints.
             for (j, tj) in enumerate(temperatures):
                 for (s, model) in zip(midPoint, handler.energyModels[j]):
                     c[j, i] += model.Energy(s)[0] / tj
         c.Scale(-1.0)
         c.Exp()
         # . Create the points arrays.
         m = Real1DArray.WithExtent(histogram.bins)
         m.Set(0.0)
         n = Real1DArray.WithExtent(handler.numberOfWindows)
         n.Set(0.0)
         for (i, v) in enumerate(histogram.counts):
             m[i] = float(v)
         for (i, v) in enumerate(handler.windowPoints):
             n[i] = float(v)
         # . Save all.
         self.pointsPerBin = m
         self.pointsPerWindow = n
         self.pressure = pressure
         self.temperature = temperature
         self.temperatureFactor = t0
         self.weightMatrix = c
示例#5
0
 def Allocate(self):
     """Allocate arrays."""
     if (self.handler is not None) and (self.histogram is not None):
         self.energies = Real1DArray.WithExtent(
             self.handler.numberOfWindows)
         self.energies.Set(1.0)
         self.probabilities = Real1DArray.WithExtent(self.histogram.bins)
         self.probabilities.Set(1.0)
         self.workE = Real1DArray.WithExtent(self.handler.numberOfWindows)
         self.workE.Set(0.0)
         self.workP = Real1DArray.WithExtent(self.histogram.bins)
         self.workP.Set(0.0)
         self.histogram.Normalize(self.probabilities)
示例#6
0
 def AtomicCharges(self,
                   qcChargeModel=None,
                   qcAtomsOnly=False,
                   spinDensities=False):
     """Calculate the partial charges for the atoms."""
     charges = None
     if self.energyModel is not None:
         em = self.energyModel
         if (em.mmModel is not None) and (not qcAtomsOnly):
             if spinDensities:
                 charges = Real1DArray.WithExtent(em.mmAtoms.size)
                 charges.Set(0.0e+00)
             else:
                 charges = em.mmAtoms.AtomicCharges()
         if em.qcModel is not None:
             qccharges = em.qcModel.AtomicCharges(
                 self.configuration,
                 chargeModel=qcChargeModel,
                 spinDensities=spinDensities)
             if charges is None:
                 charges = qccharges
             else:
                 for (index, q) in zip(em.qcAtoms, qccharges):
                     charges[index] += q
     return charges
    def VelocitiesAssign ( self, temperature, normalDeviateGenerator = None ):
        """Set up the velocities for the system at a particular temperature.

        If |temperature| is None the velocities must already exist.
        """
        # . Check for an existing set of velocities of the correct size.
        velocities = self.system.configuration.__dict__.get ( "velocities", None )
        QASSIGN = ( velocities is None ) or ( ( velocities is not None ) and ( len ( velocities ) != self.nvariables ) )
        # . Assign velocities.
        if QASSIGN:
            if temperature is None:
                raise ValueError ( "Velocities need to be assigned for the system but a temperature has not been specified." )
            else:
                # . Get the generator.
                if normalDeviateGenerator is None:
                    normalDeviateGenerator = NormalDeviateGenerator.WithRandomNumberGenerator ( RandomNumberGenerator.WithRandomSeed ( ) )
                # . Get the velocities.
                sigma      = _MS_TO_APS * math.sqrt ( CONSTANT_BOLTZMANN * temperature / CONSTANT_ATOMIC_MASS )
                velocities = Real1DArray.WithExtent ( self.NumberOfVariables ( ) )
                normalDeviateGenerator.NextStandardDeviates ( velocities )
                velocities.Scale ( ( sigma ) )
                self.system.configuration.velocities = velocities
        # . Project out linear constraints.
        if self.linearVectors is not None: self.linearVectors.ProjectOutOfArray ( velocities )
        # . Scale velocities if necessary (even for assigned velocities).
        if temperature is not None:
            ( ke, tactual ) = self.Temperature ( velocities )
            velocities.Scale ( math.sqrt ( temperature / tactual ) )
示例#8
0
 def ParseAtomSection(self):
     """Parse the ATOM section."""
     if hasattr(self, "natoms"):
         atomicCharges = Real1DArray.WithExtent(self.natoms)
         atomicCharges.Set(0.0)
         atomicNumbers = []
         atomNames = []
         xyz = Coordinates3.WithExtent(self.natoms)
         xyz.Set(0.0)
         for i in range(self.natoms):
             items = self.GetTokens(converters=[
                 int, None, float, float, float, None, None, None, float
             ])
             if len(items) < 6:
                 self.Warning("Invalid ATOM line.", True)
             else:
                 atomicNumber = PeriodicTable.AtomicNumber(items[1])
                 if atomicNumber <= 0:
                     atomicNumber = self.AtomicNumberFromAtomType(items[5])
                 atomicNumbers.append(atomicNumber)
                 atomNames.append(items[1])
                 xyz[i, 0] = items[2]
                 xyz[i, 1] = items[3]
                 xyz[i, 2] = items[4]
                 if len(items) >= 9: atomicCharges[i] = items[8]
         self.atomicCharges = atomicCharges
         self.atomicNumbers = atomicNumbers
         self.atomNames = atomNames
         self.xyz = xyz
     else:
         self.Warning("Unknown number of atoms in molecule.", True)
 def PathSummary ( self, log = logFile ):
     """Output a path summary."""
     if LogFileActive ( log ):
         # . Calculate all data for the current path.
         variables = Real1DArray.WithExtent ( self.NumberOfVariables ( ) )
         self.VariablesGet ( variables )
         self.Function ( variables )
         # . Get the energies of the first and last structures.
         self.energies[0:0] = [ self.objectiveFunction.Function ( self.x0 ) ]
         self.energies.append ( self.objectiveFunction.Function ( self.xn ) )
         # . Modify the distance lists.
         self.distances1.append ( None )
         self.distances2.extend ( [ None, None ] )
         # . Output.
         table  = log.GetTable ( columns = [ 10, 20, 20, 20 ] )
         table.Start   ( )
         table.Title   ( "Path Summary" )
         table.Heading ( "Structure"    )
         table.Heading ( "Energy"       )
         table.Heading ( "Dist(i,i+1)"  )
         table.Heading ( "Dist(i,i+2)"  )
         for ( i, ( e, d1, d2 ) ) in enumerate ( zip ( self.energies, self.distances1, self.distances2 ) ):
             table.Entry ( "{:d}"  .format ( i ) )
             table.Entry ( "{:.3f}".format ( e ) )
             if d1 is None: table.Entry ( "" )
             else:          table.Entry ( "{:.3f}".format ( d1 ) )
             if d2 is None: table.Entry ( "" )
             else:          table.Entry ( "{:.3f}".format ( d2 ) )
         table.Stop ( )
 def VariablesAllocate ( self ):
     """Return a variables object of the correct size."""
     if self.NumberOfVariables ( ) > 0:
         variables = Real1DArray.WithExtent ( self.NumberOfVariables ( ) )
         variables.Set ( 0.0 )
         return variables
     else:
         return None
 def VariablesAllocate ( self ):
     """Return an object to hold the variables."""
     if self.NumberOfVariables ( ) > 0:
         variables = Real1DArray.WithExtent ( self.NumberOfVariables ( ) )
         variables.Set ( 0.0 )
         return variables
     else:
         return None
示例#12
0
    def Setup ( selfClass, qcAtoms, electronicState, nbState, job, scratch, deleteJobFiles = False, useRandomJob = False, useRandomScratch = False ):
        """Set up a state given the relevant data."""
        self = selfClass ( )
        # . QC atoms.
        # . Basic attributes.
        self.charge          = electronicState.charge
        self.multiplicity    = electronicState.multiplicity
        self.numberOfQCAtoms = len ( qcAtoms )
        # . File paths.
        if useRandomJob: job = RandomString ( )
        if useRandomScratch:
            self.scratchPath = os.path.join ( scratch, RandomString ( ) )
            if not os.path.exists ( self.scratchPath ): os.mkdir ( self.scratchPath )
            self.jobPath     = os.path.join ( self.scratchPath, job )
        else:
            self.scratchPath = None
            self.jobPath     = os.path.join ( scratch, job )
        self.engradPath = self.jobPath + ".engrad"
        self.inputPath  = self.jobPath + ".inp"
        self.outputPath = self.jobPath + ".log"
	self.pcgradPath = self.jobPath + ".pcgrad"
	self.pcPath     = self.jobPath + ".pc"
        # . Options.
        self.deleteJobFiles = deleteJobFiles
        # . Symbols.
        atomicNumbers = qcAtoms.GetAtomicNumbers ( )
        self.symbols  = []
        for i in atomicNumbers:
            self.symbols.append ( PeriodicTable.Symbol ( i ) )
        # . Array attributes.
        self.qcCoordinates3  = Coordinates3.WithExtent ( self.numberOfQCAtoms ) ; self.qcCoordinates3.Set  ( 0.0 )
        self.dipole          = Vector3.Null ( )
        self.qcGradients3    = Coordinates3.WithExtent ( self.numberOfQCAtoms ) ; self.qcGradients3.Set    ( 0.0 )
        self.chelpgCharges   = Real1DArray.WithExtent  ( self.numberOfQCAtoms ) ; self.chelpgCharges.Set   ( 0.0 )
        self.lowdinCharges   = Real1DArray.WithExtent  ( self.numberOfQCAtoms ) ; self.lowdinCharges.Set   ( 0.0 )
        self.lowdinSpins     = Real1DArray.WithExtent  ( self.numberOfQCAtoms ) ; self.lowdinSpins.Set     ( 0.0 )
        self.mullikenCharges = Real1DArray.WithExtent  ( self.numberOfQCAtoms ) ; self.mullikenCharges.Set ( 0.0 )
        self.mullikenSpins   = Real1DArray.WithExtent  ( self.numberOfQCAtoms ) ; self.mullikenSpins.Set   ( 0.0 )
        # . Orbital data.
        self.H**O            = -1
        self.LUMO            = -1
        self.orbitalEnergies = []
        # . NB state.
        self.nbState = nbState
        return self
示例#13
0
 def FromOptions(selfClass,
                 alphas,
                 gradientsAlpha,
                 hessianAlpha,
                 minimumCoefficient,
                 numberOfSets=1):
     """Constructor from options."""
     self = selfClass()
     self.alphas = alphas
     self.gradientsAlpha = gradientsAlpha
     self.hessianAlpha = hessianAlpha
     self.minimumCoefficient = minimumCoefficient
     self.numberOfSets = numberOfSets
     self.numberOfVariables = len(self.alphas)
     self.numberOfVariablesPerSet = self.numberOfVariables // self.numberOfSets
     self.work = Real1DArray.WithExtent(self.numberOfVariables)
     self.workA = Real1DArray.WithExtent(self.numberOfVariables)
     self.workS = Real1DArray.WithExtent(self.numberOfVariables)
     self.workT = Real1DArray.WithExtent(self.numberOfVariables)
     return self
def CovarianceMatrix(*arguments, **keywordArguments):
    """Calculate the covariance matrix for selected particles."""

    # . Initialization.
    covariance = None

    # . Get the trajectory and associated system data.
    (system, trajectories) = _GetSystemAndTrajectoriesFromArguments(*arguments)

    # . Get the selection and the size of the problem.
    selection = keywordArguments.pop("selection", None)
    if selection is None:
        selection = Selection.FromIterable(range(len(system.atoms)))
    n = 3 * len(selection)

    # . Get the average positions.
    averagePositions = keywordArguments.pop("averagePositions", None)
    if averagePositions is None:
        averagePositions = AveragePositions(trajectories, selection=selection)
    _CheckForUnknownOptions(keywordArguments)

    # . Continue processing.
    if (n > 0) and (averagePositions is not None):

        # . Allocate space.
        covariance = SymmetricMatrix.WithExtent(n)
        covariance.Set(0.0)
        displacement = Real1DArray.WithExtent(n)
        displacement.Set(0.0)

        # . Loop over trajectory frames.
        numberFrames = 0
        for trajectory in trajectories:
            trajectory.ReadHeader()
            while trajectory.RestoreOwnerData():
                frame = system.coordinates3
                for (p, i) in enumerate(selection):
                    displacement[3 * p] = frame[i, 0] - averagePositions[p, 0]
                    displacement[3 * p +
                                 1] = frame[i, 1] - averagePositions[p, 1]
                    displacement[3 * p +
                                 2] = frame[i, 2] - averagePositions[p, 2]
                for i in range(n):
                    dI = displacement[i]
                    for j in range(i + 1):
                        covariance[i, j] += (dI * displacement[j])
            trajectory.ReadFooter()
            trajectory.Close()
            numberFrames += len(trajectory)

        # . Scale.
        if numberFrames > 0: covariance.Scale(1.0 / float(numberFrames))

    return covariance
示例#15
0
 def GetPMF(self):
     """Calculate the PMF."""
     if (self.reducedHistogram is not None) and (self.reducedProbabilities
                                                 is not None):
         pmf = Real1DArray.WithExtent(self.reducedHistogram.bins)
         pmf.Set(0.0)
         self.reducedProbabilities.CopyTo(pmf)
         pmf.Ln()
         pmf.Scale(-self.temperatureFactor)
         v = min(pmf)
         pmf.AddScalar(-v)
         self.pmf = pmf
def _GetHardSphereRadii(atoms):
    """Get the hard-sphere radii for the atoms."""
    hsradii = Real1DArray.WithExtent(len(atoms))
    hsradii.Set(0.0)
    atomicNumbers = atoms.GetItemAttributes("atomicNumber")
    for (i, atomicNumber) in enumerate(atomicNumbers):
        try:
            hsradii[i] = _HSRADII[atomicNumber]
        except:
            raise KeyError("Hard-sphere radius for element " +
                           PeriodicTable.Symbol(atomicNumber) + " unknown.")
    return hsradii
 def DefineWeights ( self ):
     """Define atom weights - use masses by default."""
     self.atomWeights = self.system.atoms.GetItemAttributes ( "mass" )
     if self.nvariables > 0:
         self.variableWeights = Real1DArray.WithExtent ( self.nvariables )
         self.variableWeights.Set ( 0.0 )
         if self.freeAtoms is None: indices = range ( len ( self.system.atoms ) )
         else:                      indices = self.freeAtoms
         n = 0
         for iatom in indices:
             w = math.sqrt ( self.atomWeights[iatom] )
             for j in range ( 3 ):
                 self.variableWeights[n] = w
                 n += 1
 def FindMaxima(self, computeStructures=False):
     """Find maxima along the path."""
     if self.imageSpline is not None:
         if self.functionSplineA is None: self.BuildFunctionSplines()
         self.maximaA = self.functionSplineA.FindMaxima()
         self.maximaI = self.functionSplineI.FindMaxima()
         if computeStructures:
             structures = []
             for (s, fs) in self.maximaI:
                 v = Real1DArray.WithExtent(
                     self.imageSpline.NumberOfSplines())
                 v.Set(0.0)
                 self.imageSpline.Evaluate(s, f=v)
                 structures.append((s, fs, v))
             self.maximaIStructures = structures
示例#19
0
 def WriteBlock(self):
     """Write a block of data."""
     if self.current > 0:
         # . The following is a fudge until slicing is handled properly.
         if self.current == self.blockSize: outdata = self.data
         else:
             outdata = Real1DArray.WithExtent(self.current * self.rank)
             for i in range(len(outdata)):
                 outdata[i] = self.data[i]
         Pickle(
             os.path.join(
                 self.path,
                 _BlockPrefix + "{:d}".format(self.blocks) + _BlockPostfix),
             outdata)
         # . This is what it should be.
         #            Pickle ( os.path.join ( self.path, _BlockPrefix + "{:d}".format ( self.blocks ) + _BlockPostfix, self.data[0:self.current*self.rank] )
         self.blocks += 1
         self.current = 0
示例#20
0
 def WriteHeader(self, pressure=None, temperature=None):
     """Write the trajectory header."""
     # . Check for soft constraints.
     self.hasSoftConstraints = hasattr(
         self.owner.energyModel, "softConstraints") and (len(
             self.owner.energyModel.softConstraints) > 0)
     # . Check the volume option.
     self.hasVolume = self.hasVolume and hasattr(self.owner, "symmetry")
     # . Check that there will be data on the trajectory.
     if not (self.hasPotentialEnergy or self.hasSoftConstraints
             or self.hasVolume):
         raise ValueError("A soft-constraint trajectory contains no data.")
     # . Initialization.
     labels = []
     models = []
     # . Potential energy and volume.
     if self.hasPotentialEnergy: labels.append("Potential Energy")
     if self.hasVolume: labels.append("Volume")
     # . Soft constraints.
     if self.hasSoftConstraints:
         self.softConstraintLabels = sorted(
             self.owner.energyModel.softConstraints)
         for label in self.softConstraintLabels:
             models.append(
                 self.owner.energyModel.softConstraints[label].energyModel)
         labels.extend(self.softConstraintLabels)
     # . Set up the header.
     header = {
         "labels": labels,
         "hasPotentialEnergy": self.hasPotentialEnergy,
         "hasVolume": self.hasVolume,
         "softConstraintEnergyModels": models
     }
     # . Optional information.
     if pressure is not None: header["pressure"] = pressure
     if temperature is not None: header["temperature"] = temperature
     # . Write out.
     Pickle(os.path.join(self.path, _HeaderName + _BlockPostfix), header)
     # . Setup the block for output.
     self.rank = len(labels)
     self.data = Real1DArray.WithExtent(self.rank * self.blockSize)
示例#21
0
 def ParseCharges(self):
     """Parse charges from a charge analysis."""
     if (self.natoms > 0):
         nall = self.natoms + len(self.dummies)
         q = Real1DArray.WithExtent(self.natoms)
         q.Set(0.0)
         i = -1
         n = -1
         for iblock in range((nall + 4) // 5):
             self.GetLine()  # Blank line.
             self.GetLine()  # Atom heading.
             line = self.GetLine()
             tokens = line[7:].split()
             for token in tokens:
                 n += 1
                 if n not in self.dummies:
                     i += 1
                     q[i] = float(token)
         return q
     else:
         return None
示例#22
0
 def GetItemAttributes(self,
                       attributeLabel,
                       asDictionary=False,
                       selection=None):
     """Return a sequence of item attributes."""
     # . Initialization.
     data = None
     if (attributeLabel
             in Atom.defaultAttributes) or (attributeLabel
                                            in Element.defaultAttributes):
         if selection is None: indices = range(len(self))
         else: indices = selection
         if indices is not None:
             # . Use a dictionary for non-default values only.
             if asDictionary:
                 data = {}
                 if attributeLabel in Atom.defaultAttributes:
                     defaultValue = Atom.defaultAttributes[attributeLabel]
                 else:
                     defaultValue = Element.defaultAttributes[
                         attributeLabel]
                 for i in indices:
                     value = getattr(self[i], attributeLabel)
                     if value != defaultValue: data[i] = value
             # . Use a sequence for all values.
             else:
                 attribute = getattr(self[0], attributeLabel)
                 # . Float attribute.
                 if isinstance(attribute, (float)):
                     data = Real1DArray.WithExtent(len(indices))
                     for (i, index) in enumerate(indices):
                         data[i] = getattr(self[index], attributeLabel)
                 # . Other attribute.
                 else:
                     data = []
                     for i in indices:
                         data.append(getattr(self[i], attributeLabel))
     return data
 def __init__ ( self, system, trajectory, **keywordArguments ):
     """Constructor."""
     # . Set defaults for all options.
     for ( key, value ) in self.__class__.attributes.iteritems ( ): setattr ( self, key, value )
     # . Set values of keyword arguments.
     for ( key, value ) in keywordArguments.iteritems ( ): setattr ( self, key, value )
     # . Define the system geometry object function.
     self.objectiveFunction = SystemGeometryObjectiveFunction.FromSystem ( system )
     # . Define the trajectory - a check should be made here to ensure that the trajectory is a direct access one with coordinates!
     # . Reading and writing the header/footer is not required but maybe should be included for completeness?
     self.trajectory = trajectory
     # . Get some scratch space.
     self.g  = Real1DArray.WithExtent ( self.objectiveFunction.NumberOfVariables ( ) )
     self.gd = Real1DArray.WithExtent ( self.objectiveFunction.NumberOfVariables ( ) + self.NumberOfVariables ( ) )
     self.x  = Real1DArray.WithExtent ( self.objectiveFunction.NumberOfVariables ( ) )
     self.x0 = Real1DArray.WithExtent ( self.objectiveFunction.NumberOfVariables ( ) )
     self.xn = Real1DArray.WithExtent ( self.objectiveFunction.NumberOfVariables ( ) )
     self.y  = Real1DArray.WithExtent ( self.objectiveFunction.NumberOfVariables ( ) )
     self.g.Set  ( 0.0 )
     self.gd.Set ( 0.0 )
     self.x.Set  ( 0.0 )
     self.x0.Set ( 0.0 )
     self.xn.Set ( 0.0 )
     self.y.Set  ( 0.0 )
     # . Get the first structure on the trajectory.
     self.trajectory.RestoreOwnerData ( index = 0 )
     self.objectiveFunction.VariablesGet ( self.x0 )
     # . Make the first structure the reference structure.
     # . It is assumed that the remaining structures on the trajectory are already
     # . orientated with respect to this one. This is the case for trajectories
     # . from linear-interpolation or expansion or previous SAW calculations but
     # . may not be otherwise.
     if self.removeRotationTranslation: self.objectiveFunction.RemoveRotationTranslation ( reference = self.objectiveFunction.system.coordinates3 )
     # . Get the last structure on the trajectory.
     self.trajectory.RestoreOwnerData ( index = self.trajectory.frames - 1 )
     self.objectiveFunction.VariablesGet ( self.xn )
     self.trajectories = []
def CoordinateFluctuations(*arguments, **keywordArguments):
    """Calculate the coordinate fluctuations for selected particles."""

    # . Initialization.
    fluctuations = None

    # . Get the trajectory and associated system data.
    (system, trajectories) = _GetSystemAndTrajectoriesFromArguments(*arguments)

    # . Get the selection and the size of the problem.
    selection = keywordArguments.pop("selection", None)
    if selection is None:
        selection = Selection.FromIterable(range(len(system.atoms)))
    n = len(selection)

    # . Get the average positions.
    averagePositions = keywordArguments.pop("averagePositions", None)
    if averagePositions is None:
        averagePositions = AveragePositions(trajectories, selection=selection)

    # . Various other options.
    anisotropic = keywordArguments.pop("anisotropic", False)
    asBFactors = keywordArguments.pop("asBFactors", False)
    _CheckForUnknownOptions(keywordArguments)

    # . Continue processing.
    if (n > 0) and (averagePositions is not None):

        # . Allocate space.
        displacement = Coordinates3.WithExtent(n)
        if anisotropic: fluctuations = Real2DArray.WithExtents(n, 6)
        else: fluctuations = Real1DArray.WithExtent(n)
        displacement.Set(0.0)
        fluctuations.Set(0.0)

        # . Loop over trajectory frames.
        numberFrames = 0
        for trajectory in trajectories:
            trajectory.ReadHeader()
            while trajectory.RestoreOwnerData():
                frame = system.coordinates3
                if anisotropic:
                    for (p, i) in enumerate(selection):
                        dx = frame[i, 0] - averagePositions[p, 0]
                        dy = frame[i, 1] - averagePositions[p, 1]
                        dz = frame[i, 2] - averagePositions[p, 2]
                        fluctuations[p, 0] += dx * dx
                        fluctuations[p, 1] += dy * dx
                        fluctuations[p, 2] += dy * dy
                        fluctuations[p, 3] += dz * dx
                        fluctuations[p, 4] += dz * dy
                        fluctuations[p, 5] += dz * dz
                else:
                    for (p, i) in enumerate(selection):
                        fluctuations[p] += ( ( frame[i,0] - averagePositions[p,0] )**2 + \
                                             ( frame[i,1] - averagePositions[p,1] )**2 + \
                                             ( frame[i,2] - averagePositions[p,2] )**2 )
            trajectory.ReadFooter()
            trajectory.Close()
            numberFrames += len(trajectory)

        # . Scale.
        if numberFrames > 0: fluctuations.Scale(1.0 / float(numberFrames))

        # . Convert to B-factors if necessary.
        if asBFactors:
            conversionFactor = 8.0 * math.pi**2
            if not anisotropic: conversionFactor /= 3.0
            fluctuations.Scale(conversionFactor)

    # . Finish up.
    return fluctuations
示例#25
0
def JaguarBondOrders(infile,
                     outfile,
                     bondOrdertolerance=_DEFAULTBONDORDERTOLERANCE,
                     chargetolerance=_DEFAULTCHARGETOLERANCE,
                     log=logFile,
                     QCROSS=False):
    """Calculate bond orders given Jaguar input and output files."""

    # . Parse the input file.
    infile = JaguarInputFileReader(infile)
    infile.Parse()
    infile.Summary(log=logFile)

    # . Parse the output file.
    outfile = JaguarOutputFileReader(outfile)
    outfile.Parse()
    outfile.Summary(log=logFile)

    # . Get data from the files.
    # . Input.
    atomicNumbersi = getattr(infile, "atomicNumbers", None)
    coordinates3 = getattr(infile, "coordinates3", None)
    orbitalsets = getattr(infile, "orbitalsets", None)

    # . Output.
    atomicNumberso = getattr(outfile, "atomicNumbers", None)
    nfunctions = getattr(outfile, "nfunctions", None)
    overlap = getattr(outfile, "overlap", None)

    # . Check for coordinates.
    if coordinates3 is None:
        raise ValueError("The coordinate data is missing from the input file.")

    # . Check the orbital data.
    QOK = (orbitalsets is not None) and (len(orbitalsets) > 0)
    if QOK:
        if (len(orbitalsets) == 1) and ("" in orbitalsets):
            spinDensitiesRESTRICTED = True
        elif (len(orbitalsets)
              == 2) and ("alpha" in orbitalsets) and ("beta" in orbitalsets):
            spinDensitiesRESTRICTED = False
        else:
            QOK = False
    if not QOK: raise ValueError("Invalid orbital data on input file.")
    if spinDensitiesRESTRICTED: nbasisi = infile.orbitalsets[""][1]
    else: nbasisi = infile.orbitalsets["alpha"][1]

    # . Check the overlap.
    if (overlap is None):
        raise ValueError("The overlap matrix is missing from the output file.")
    nbasiso = overlap.Dimension()

    # . Check the array giving the number of functions per atom.
    #    print nfunctions, len ( nfunctions ), len ( atomicNumberso ), sum ( nfunctions ), nbasiso
    if (nfunctions is None) or (len(nfunctions) != len(atomicNumberso) or
                                (sum(nfunctions) != nbasiso)):
        raise ValueError(
            "Basis function data on the output file is missing or invalid.")

    # . Create the function index array.
    findices = []
    first = 0
    last = 0
    for f in nfunctions:
        last += f
        findices.append((first, last))
        first += f

    # . Check for compatibility between the data.
    QOK = (atomicNumbersi is not None) and (atomicNumberso is not None) and (
        len(atomicNumbersi) == len(atomicNumberso)) and (nbasisi == nbasiso)
    if QOK:
        for (i, j) in zip(atomicNumbersi, atomicNumberso):
            if i != j:
                QOK = False
                break
    if not QOK:
        raise ValueError(
            "The systems on the input and output files are incompatible.")

    # . Set the keys for the calculation.
    if spinDensitiesRESTRICTED: keys = [""]
    else: keys = ["alpha", "beta"]

    # . Get the densities multiplied by the overlap.
    ps = {}
    for key in keys:
        p = _MakeDensity(orbitalsets[key])
        #        p.Print ( title = "**1**" )
        result = Real2DArray.WithExtents(nbasisi, nbasisi)
        result.Set(999.0)
        p.PostMultiply(overlap, result)
        #        overlap.Print ( title = "**2**" )
        #        result.Print ( title = "**3**" )
        ps[key] = result
#    f = STOP
# . Scale ps correctly for the spin-restricted case.
    if spinDensitiesRESTRICTED: ps[""].Scale(2.0)

    # . If cross terms are not required condense the ps matrices.
    if (not QCROSS) and (not spinDensitiesRESTRICTED):
        tps = ps.pop(keys[0])
        for key in keys[1:]:
            tps.AddScaledMatrix(1.0, ps[key])
        ps = {"": tps}
        keys = [""]

    # . Get the bond-orders.
    bondOrders = {}
    for key1 in keys:
        for key2 in keys:
            bondOrders[(key1, key2)] = _MakeBondOrders(ps[key1], ps[key2],
                                                       findices)

    # . Make the total bond-order if necessary.
    bokeys = bondOrders.keys()
    if len(bokeys) > 1:
        bokeys.sort()
        tbo = Clone(bondOrders[bokeys[0]])
        for key in bokeys[1:]:
            tbo.AddScaledMatrix(1.0, bondOrders[key])
        tkey = ("", "")
        bokeys.append(tkey)
        bondOrders[tkey] = tbo

    # . Compute the electronic contribution to the Mulliken charges.
    qmulliken = Real1DArray.WithExtent(len(atomicNumbersi))
    qmulliken.Set(0.0)
    for key in keys:
        _MakeElectronicMullikenCharges(ps[key], findices, qmulliken)

    # . Determine atom valencies.
    free = Real1DArray.WithExtent(len(atomicNumbersi))
    free.Set(0.0)
    valencies = Real1DArray.WithExtent(len(atomicNumbersi))
    valencies.Set(0.0)
    tbo = bondOrders[("", "")]
    for i in range(len(atomicNumbersi)):
        valencies[i] = (-2.0 * qmulliken[i]) - tbo[i, i]
        totalbo = 0.0
        for j in range(len(atomicNumbersi)):
            totalbo += tbo[i, j]
        free[i] = (-2.0 * qmulliken[i]) - totalbo

    # . Add in the core contributions to the Mulliken charges.
    for (i, q) in enumerate(atomicNumbersi):
        qmulliken[i] += float(q)
    if outfile.QECP:
        for (i, q) in enumerate(outfile.ecpelectrons):
            qmulliken[i] -= float(q)

    # . Output the results.
    if LogFileActive(log):

        # . Get the spin label.
        if spinDensitiesRESTRICTED: spinlabel = "Spin Restricted"
        else: spinlabel = "Spin Unrestricted"

        # . Create the atom names.
        atomnames = []
        for (i, n) in enumerate(atomicNumbersi):
            atomnames.append(PeriodicTable.Symbol(n, index=i + 1))

        # . Atom data.
        columns = [10, 20, 20, 20]
        if not spinDensitiesRESTRICTED: columns.append(20)
        table = log.GetTable(columns=columns)
        table.Start()
        table.Title("Atom Data (" + spinlabel + ")")
        table.Heading("Atom")
        table.Heading("Charge")
        table.Heading("Self Bond Order")
        table.Heading("Valence")
        if not spinDensitiesRESTRICTED: table.Heading("Free Valence")
        for (i, ni) in enumerate(atomnames):
            table.Entry(ni)
            table.Entry("{:.3f}".format(qmulliken[i]))
            table.Entry("{:.3f}".format(tbo[i, i]))
            table.Entry("{:.3f}".format(valencies[i]))
            if not spinDensitiesRESTRICTED:
                table.Entry("{:.3f}".format(free[i]))
        table.Stop()

        # . Bond orders.
        for key in bokeys:
            orders = bondOrders[key]
            table = log.GetTable(columns=[10, 10, 20, 20])
            table.Start()
            if key == ("", ""): table.Title("Total Bond Orders")
            else:
                table.Title(key[0].title() + "/" + key[1].title() +
                            " Bond Orders")
            table.Heading("Atom 1")
            table.Heading("Atom 2")
            table.Heading("Order")
            table.Heading("Distance")
            for (i, ni) in enumerate(atomnames):
                for (j, nj) in enumerate(atomnames[0:i]):
                    b = orders[i, j]
                    if math.fabs(b) > bondOrdertolerance:
                        table.Entry(ni)
                        table.Entry(nj)
                        table.Entry("{:.3f}".format(b))
                        table.Entry("{:.3f}".format(coordinates3.Distance(
                            i, j)))
            table.Stop()

        # . Checks on the calculation.
        # . Free valence.
        if spinDensitiesRESTRICTED:
            deviation = free.AbsoluteMaximum()
            if deviation > chargetolerance:
                log.Paragraph(
                    "Warning: the largest deviation between the free valence values and zero is {:.3f}."
                    .format(deviation))

        # . Total charge.
        deviation = math.fabs(qmulliken.Sum() - float(infile.charge))
        if deviation > chargetolerance:
            log.Paragraph(
                "Warning: the total charge deviates from the formal charge by {:.3f}."
                .format(deviation))

        # . Check for a valid reference set of Mulliken charges.
        qreference = getattr(outfile, "qmulliken", None)
        if (qreference is not None) and (len(qreference)
                                         == len(atomicNumbersi)):
            qmulliken.AddScaledArray(-1.0, qreference)
            deviation = qmulliken.AbsoluteMaximum()
            if deviation > chargetolerance:
                log.Paragraph(
                    "Warning: the largest deviation between calculated and read Mulliken charges is {:.3f}."
                    .format(deviation))

    # . Finish up.
    return bondOrders
示例#26
0
def QuasiHarmonic_SystemGeometry(system,
                                 log=logFile,
                                 modify=None,
                                 temperature=300.0,
                                 title="Quasi-Harmonic Frequencies (cm^(-1))",
                                 trajectories=None):
    """Determine the quasi-harmonic modes for a system."""

    # . Initialization.
    state = None

    # . Determine if any atoms are fixed.
    hc = system.hardConstraints
    if (hc is not None) and (hc.fixedAtoms
                             is not None) and (len(hc.fixedAtoms) > 0):
        fixedAtoms = hc.fixedAtoms
    else:
        fixedAtoms = None

    # . Get the covariance matrix.
    covariance = CovarianceMatrix(trajectories, selection=fixedAtoms)

    # . Proceed with the analysis.
    if covariance is not None:

        # . Get some options.
        if modify is None: modopt = None
        else: modopt = modify.upper()

        # . Mass-weight the covariance matrix.
        # . Weights are square roots of masses.
        of = SystemGeometryObjectiveFunction.FromSystem(system)
        of.DefineWeights()
        n = of.NumberOfVariables()
        for i in range(n):
            wI = of.variableWeights[i]
            for j in range(i + 1):
                wJ = of.variableWeights[j]
                covariance[i, j] *= (wI * wJ)

        # . Get the mass-weighted rotation-translation vectors and count their number.
        of.RemoveRotationTranslation()
        if of.linearScalars is None: nrtmodes = 0
        else: nrtmodes = len(of.linearScalars)

        # . Modify the Hessian.
        if modopt in _MODIFYOPTIONS:
            if modopt == "PROJECT":
                covariance.ProjectOutVectors(of.linearVectors)
            elif modopt == "RAISE":
                covariance.Raise(of.linearVectors, 0.0)

        # . Diagonalization.
        eigenValues = Real1DArray.WithExtent(n)
        eigenValues.Set(0.0)
        eigenVectors = Real2DArray.WithExtents(n, n)
        eigenVectors.Set(0.0)
        covariance.Diagonalize(eigenValues, eigenVectors)

        # . Convert eigenvalues to frequencies.
        conversionFactor = math.sqrt(_TO_KJMOL * temperature) * _TO_WAVENUMBERS
        numberZero = 0
        for (i, e) in enumerate(eigenValues):
            eAbs = math.fabs(e)
            if eAbs <= _QHTolerance:
                f = 0.0
                numberZero += 1
            else:
                f = math.sqrt(1.0 / eAbs) * conversionFactor
                if e < 0.0: f *= -1.0
            eigenValues[i] = f

        # . Un-mass-weight the modes.
        for r in range(n):
            w = 1.0 / of.variableWeights[r]
            for c in range(n):
                eigenVectors[r, c] *= w

        # . Reverse in place (excluding zero modes).
        temporary = Real1DArray.WithExtent(n)
        for i in range((n - numberZero) // 2):
            # . Indices.
            lower = i + numberZero
            upper = n - i - 1
            # . Eigenvalues.
            e = eigenValues[upper]
            eigenValues[upper] = eigenValues[lower]
            eigenValues[lower] = e
            # . Eigenvectors.
            for j in range(n):
                temporary[j] = eigenVectors[j, upper]
            for j in range(n):
                eigenVectors[j, upper] = eigenVectors[j, lower]
            for j in range(n):
                eigenVectors[j, lower] = temporary[j]

        # . Do some printing.
        if LogFileActive(log):
            table = log.GetTable(columns=_NFREQUENCYCOLUMNS *
                                 [_FREQUENCYWIDTHS])
            table.Start()
            table.Title(title)
            for f in eigenValues:
                table.Entry(_FREQUENCYFORMAT.format(f))
            table.Stop()

        # . Save all data.
        state = NormalModeState(dimension=n,
                                freeAtoms=of.freeAtoms,
                                frequencies=eigenValues,
                                modes=eigenVectors,
                                nrtmodes=nrtmodes,
                                weights=of.variableWeights)
        system.configuration.SetTemporaryAttribute("qhState", state)

    # . Finish up.
    return state
示例#27
0
def NormalModes_SystemGeometry(system,
                               hessian=None,
                               log=logFile,
                               modify=None,
                               title="Harmonic Frequencies (cm^(-1))"):
    """Determine the normal modes for a system."""

    # . Get some options.
    if modify is None: modopt = None
    else: modopt = modify.upper()

    # . Get the Hessian with mass-weighting.
    of = SystemGeometryObjectiveFunction.FromSystem(system)
    of.DefineWeights()
    n = of.NumberOfVariables()
    if hessian is None:
        x = Real1DArray.WithExtent(n)
        x.Set(0.0)
        of.VariablesGet(x)
        hessian = of.NumericalHessian(x)

    # . Get the mass-weighted rotation-translation vectors and count their number.
    of.RemoveRotationTranslation()
    if of.linearScalars is None: nrtmodes = 0
    else: nrtmodes = len(of.linearScalars)

    # . Modify the Hessian.
    if modopt in _MODIFYOPTIONS:
        if modopt == "PROJECT": hessian.ProjectOutVectors(of.linearVectors)
        elif modopt == "RAISE":
            hessian.Raise(of.linearVectors, _RAISEEIGENVALUE)

    # . Diagonalization.
    # . Maybe should save hessian here as it is destroyed by the diagonalization.
    eigenvalues = Real1DArray.WithExtent(n)
    eigenvalues.Set(0.0)
    eigenvectors = Real2DArray.WithExtents(n, n)
    eigenvectors.Set(0.0)
    hessian.Diagonalize(eigenvalues, eigenvectors)

    # . Convert eigenvalues to frequencies.
    for (i, e) in enumerate(eigenvalues):
        f = math.sqrt(math.fabs(e)) * _TO_WAVENUMBERS
        if e < 0.0: f *= -1.0
        eigenvalues[i] = f

    # . Un-mass-weight the modes.
    for r in range(n):
        w = 1.0 / of.variableWeights[r]
        for c in range(n):
            eigenvectors[r, c] *= w

    # . Do some printing.
    if LogFileActive(log):
        table = log.GetTable(columns=_NFREQUENCYCOLUMNS * [_FREQUENCYWIDTHS])
        table.Start()
        table.Title(title)
        for f in eigenvalues:
            table.Entry(_FREQUENCYFORMAT.format(f))
        table.Stop()

    # . Save all data.
    state = NormalModeState(dimension=n,
                            freeAtoms=of.freeAtoms,
                            frequencies=eigenvalues,
                            modes=eigenvectors,
                            nrtmodes=nrtmodes,
                            weights=of.variableWeights)
    system.configuration.SetTemporaryAttribute("nmState", state)

    # . Finish up.
    return state
示例#28
0
def GrowingStringInitialPath(system, npoints, point0, pointn, path,
                             **keywordArguments):
    """Use a \"growing string\" method for generating an initial path."""

    # . Get some options.
    log = keywordArguments.pop("log", logFile)
    sequence = keywordArguments.pop("sequence", "Forward").lower()

    # . Get the number of points.
    npoints = max(npoints, 2)

    # . Check for fixed atoms.
    QFIXED = (system.hardConstraints is not None) and (
        system.hardConstraints.NumberOfFixedAtoms() > 0)

    # . Save the current system coordinates.
    temporary = Clone(system.coordinates3)

    # . Create the trajectory and write the first frame.
    trajectory = SystemGeometryTrajectory(path, system, mode="w")
    trajectory.WriteFrame(point0, frame=0)

    # . Get the first and last energies.
    energies = {}
    point0.CopyTo(system.coordinates3)
    energies[0] = system.Energy(log=log)
    pointn.CopyTo(system.coordinates3)
    if not QFIXED: system.coordinates3.Superimpose(point0)
    energies[npoints - 1] = system.Energy(log=log)

    # . Save the last point.
    trajectory.WriteFrame(system.coordinates3, frame=npoints - 1)

    # . Generate intermediate points.
    if npoints > 2:

        # . Set up the optimizer.
        algorithm = keywordArguments.pop("optimizer", LBFGSMinimizer)
        options = dict(_MinimizerOptions)
        options.update(keywordArguments)
        optimizer = algorithm(**options)
        optimizer.Summary(log=log)

        # . Set up the objective function.
        of = SystemGeometryObjectiveFunction.FromSystem(system)

        # . Get variables for the first and last points and the tangent constraint.
        first = Real1DArray.WithExtent(of.nvariables)
        last = Real1DArray.WithExtent(of.nvariables)
        tangent = Real1DArray.WithExtent(of.nvariables)

        # . Save the last point (given it is already in system.coordinates3).
        of.VariablesGet(last)

        # . Save the first point.
        point0.CopyTo(system.coordinates3)
        of.VariablesGet(first)

        # . Generate the sequence over which iterations are to occur.
        sequenceData = []
        if sequence == "alternate":
            for i in range((npoints - 2) // 2):
                sequenceData.append(
                    (first, last, i + 1, npoints - 2 - (2 * i)))
                sequenceData.append(
                    (last, first, npoints - 2 - i, npoints - 2 - (2 * i + 1)))
            if (npoints - 2) % 2 != 0:
                sequenceData.append((first, last, (npoints - 2) // 2 + 1, 1))
        elif sequence == "backward":
            for i in range(npoints - 2):
                sequenceData.append(
                    (last, first, npoints - 2 - i, npoints - 2 - i))
        elif sequence == "forward":
            for i in range(npoints - 2):
                sequenceData.append((first, last, i + 1, npoints - 2 - i))
        else:
            raise ArgumentError("Unknown sequence option - " + sequence + ".")

        # . Loop over points.
        for (start, stop, index, remainder) in sequenceData:

            # . Get the new point to optimize and the tangent constraint.
            stop.CopyTo(tangent)
            tangent.AddScaledArray(-1.0, start)
            start.AddScaledArray(1.0 / float(remainder + 1), tangent)
            tangent.Normalize()

            # . Set up the object function.
            of.RemoveRotationTranslation(reference=point0)
            of.AddLinearConstraint(tangent)
            of.VariablesPut(start)

            # . Minimize and save the point.
            optimizer.Iterate(of, log=log)
            of.VariablesGet(start)
            energies[index] = system.Energy(log=log)
            trajectory.WriteFrame(system.coordinates3, frame=index)

    # . Finish up.
    system.coordinates3 = temporary
    trajectory.Close()

    # . Output.
    if LogFileActive(log):
        table = log.GetTable(columns=[30, 20])
        table.Start()
        table.Title("Growing String Structure Energies")
        table.Heading("Structure")
        table.Heading("Energy")
        keys = energies.keys()
        keys.sort()
        for key in keys:
            table.Entry(repr(key))
            table.Entry("{:.3f}".format(energies[key]))
        table.Stop()
示例#29
0
 def VariablesAllocate(self):
     """Return an object to hold the variables."""
     variables = Real1DArray.WithExtent(self.numberOfVariables)
     variables.Set(0.0)
     return variables
示例#30
0
 def ParseGuessSection(self, line):
     """Parse the guess section."""
     # . Get the terminator as the opening character of the current line.
     terminator = line[0:1]
     # . Get the guess basis.
     words = line.split(None, 1)
     if len(words) > 1:
         tokens = words[1].split("=", 1)
         if (len(tokens) > 1) and (tokens[0] == "basgss"):
             guessbasis = tokens[1].strip()
     # . Initialization.
     coefficients = None
     nbasis = None
     orbitals = None
     orbitalsets = {}
     key = ""
     nwarnings0 = self.nwarnings
     # . Loop until an end of section is reached
     while True:
         items = self.GetTokens()
         # . The end found.
         if (len(items) == 1) and (items[0] == terminator):
             break
         # . An orbital set header.
         elif (len(items) > 2) and (items[-2]
                                    == "Molecular") and (items[-1]
                                                         == "Orbitals"):
             key = " ".join(items[0:-2])
             orbitals = None
         # . An orbital line.
         elif ("Orbital" in items):
             # . Orbital data.
             if "Energy" in items:
                 energy = float(items[items.index("Energy") + 1])
             else:
                 energy = 0.0
             if "Occupation" in items:
                 occupancy = float(items[items.index("Occupation") + 1])
             else:
                 occupancy = 0.0
             if (nbasis is None) and (coefficients is not None):
                 nbasis = len(coefficients)
             coefficients = []
             # . Orbital set data.
             if orbitals is None: orbitals = []
             orbitals.append((energy, occupancy, coefficients))
             # . Orbital collection data.
             if key is not None:
                 if key in orbitalsets:
                     self.Warning("Orbital sets with duplicate names.",
                                  False)
                 else:
                     orbitalsets[key] = orbitals
                     key = None
         # . A coefficient line.
         elif (len(items) > 0) and (coefficients is not None):
             for item in items:
                 coefficients.append(float(item))
             if (nbasis is not None) and (len(coefficients) > nbasis):
                 self.Warning(
                     "There are orbitals with differing numbers of coefficients.",
                     False)
         # . Other lines.
         else:
             self.Warning("Unable to interpret guess section line.", False)
     # . Save the data if there have been no warnings.
     if (nwarnings0 == self.nwarnings) and (nbasis is not None):
         # . Initialization.
         self.orbitalsets = {}
         # . Process each of the orbital sets in turn.
         for (key, orbitals) in orbitalsets.iteritems():
             norbitals = len(orbitals)
             energies = Real1DArray.WithExtent(norbitals)
             occupancies = Real1DArray.WithExtent(norbitals)
             vectors = Real2DArray.WithExtents(nbasis, norbitals)
             for (i, (energy, occupancy,
                      coefficients)) in enumerate(orbitals):
                 energies[i] = energy
                 occupancies[i] = occupancy
                 for (j, v) in enumerate(coefficients):
                     vectors[j, i] = v
             self.orbitalsets[key.lower()] = (norbitals, nbasis, energies,
                                              occupancies, vectors)