示例#1
0
def _read_g09(name):
    """
    A method for reading in the output of g09 single point calculations to
    get the atomic positions with forces.  Further, energy is also returned.

    **Parameters**

        name: *str*
            The name of the g09 simulation in questions.

    **Returns**

        new_energy: *float*
            The energy of the system in Hartree (Ha).
        new_atoms: *list,* :class:`structures.Atom`
            A list of atoms with the forces attached in units of Hartree per
            Angstrom (Ha/Ang).
    """
    result = g09.parse_atoms(name,
                             check_convergence=False,
                             parse_all=False)
    if not result:
        raise Exception('parse_atoms failed')
    new_energy, new_atoms = result

    for a in new_atoms:
        a.fx = units.convert('Ha/Bohr', 'Ha/Ang', a.fx)
        a.fy = units.convert('Ha/Bohr', 'Ha/Ang', a.fy)
        a.fz = units.convert('Ha/Bohr', 'Ha/Ang', a.fz)

    return new_energy, new_atoms
示例#2
0
    def getData(self, unit=None):
        """Return all of the data in the channel, converting it if a type is specified."""
        if unit is None: # No conversion needed
            return self.data

        if self.valueType in (list, tuple):
            return [[units.convert(d, self.unit, unit) for d in p] for p in self.data]
        # If the data type isn't a list, it should be a scalar
        return [units.convert(p, self.unit, unit) for p in self.data]
示例#3
0
def g09_results(NEB, step_to_use, i, state):
    """
    A method for reading in the output of Gaussian09 single point calculations
    for NEB calculations. This will both (a) assign forces to the atoms stored
    in state and (b) return the energy and atoms.

    **Parameters**

        NEB: :class:`NEB`
            An NEB container holding the main NEB simulation
        step_to_use: *int*
            Which iteration in the NEB sequence the output to be read in is on.
        i: *int*
            The index corresponding to which image on the frame is to be
            simulated.
        state: *list,* :class:`structures.Atom`
            A list of atoms describing the image on the frame associated with
            index *i*.

    **Returns**

        new_energy: *float*
            The energy of the system in Hartree (Ha).
        new_atoms: *list,* :class:`structures.Atom`
            A list of atoms with the forces attached in units of Hartree per
            Angstrom (Ha/Ang).
    """
    result = g09.parse_atoms('%s-%d-%d' % (NEB.name, step_to_use, i),
                             check_convergence=False,
                             parse_all=False)
    if not result:
        raise Exception('parse_atoms failed')
    new_energy, new_atoms = result

    # Check if coordinates are aligned properly between state and new_atoms
    def check_atom_coords(atoms1, atoms2, precision=1e-6):
        for a1, a2 in zip(atoms1, atoms2):
            if (abs(a1.x - a2.x) > precision or abs(a1.y - a2.y) > precision
                    or abs(a1.z - a2.z) > precision):
                print i, 'atoms not in same frame:', a1.x, a1.y, a1.z,
                print 'vs', a2.x, a2.y, a2.z
                print abs(a1.x - a2.x), abs(a1.y - a2.y), abs(a1.z - a2.z)
                exit()

    if i != 0 and i != len(NEB.states) - 1:
        check_atom_coords(state, new_atoms)
        for a, b in zip(state, new_atoms):
            b.fx = units.convert('Ha/Bohr', 'Ha/Ang', b.fx)
            b.fy = units.convert('Ha/Bohr', 'Ha/Ang', b.fy)
            b.fz = units.convert('Ha/Bohr', 'Ha/Ang', b.fz)
            a.fx = b.fx
            a.fy = b.fy
            a.fz = b.fz

    return new_energy, new_atoms
示例#4
0
    def getCSV(self, pref=None, exclude=[], excludeGrains=[]):
        """Returns a string that contains a CSV of the simulated data. Preferences can be passed in to set units that
        the values will be converted to. All log channels are included unless their names are in the include
        argument. """
        out = ''
        outUnits = {}
        for chan in self.channels:
            if chan in exclude:
                continue
            # Get unit from preferences
            if pref is not None:
                outUnits[chan] = pref.getUnit(self.channels[chan].unit)
            else:
                outUnits[chan] = self.channels[chan].unit
            # Add title for column
            if self.channels[chan].valueType in (float, int):
                out += self.channels[chan].name
                if outUnits[chan] != '':
                    out += '(' + outUnits[chan] + ')'
                out += ','
            elif self.channels[chan].valueType in (list, tuple):
                for grain in range(1, len(self.channels[chan].getLast()) + 1):
                    if grain - 1 not in excludeGrains:
                        out += self.channels[chan].name + '('
                        out += 'G' + str(grain)
                        if outUnits[chan] != '':
                            out += ';' + outUnits[chan]
                        out += '),'

        out = out[:-1] # Remove the last comma
        out += '\n'

        places = 5
        for ind, time in enumerate(self.channels['time'].getData()):
            out += str(round(time, places)) + ','
            for chan in self.channels:
                if chan in exclude:
                    continue
                if chan != 'time':
                    if self.channels[chan].valueType in (float, int):
                        orig = self.channels[chan].getPoint(ind)
                        conv = units.convert(orig, self.channels[chan].unit, outUnits[chan])
                        rounded = round(conv, places)
                        out += str(rounded) + ','
                    elif self.channels[chan].valueType in (list, tuple):
                        for gid, grainVal in enumerate(self.channels[chan].getPoint(ind)):
                            if gid not in excludeGrains:
                                conv = round(units.convert(grainVal, self.channels[chan].unit, outUnits[chan]), places)
                                out += str(conv) + ','

            out = out[:-1] # Remove the last comma
            out += '\n'

        return out
示例#5
0
    def get_basic(self, name=None, unit=None):
        """ Gets the value under the given name converting it into the given unit, if possible.

            For example:
            -- self.get_basic('x', 'km') will return the value of x in kilometers.
            -- self.get_basic('longitude', 'deg') will return the longitude angle in degrees.
        """
        if name in self._cart_names:
            # Cartesian coordinate
            i = self._cart_names.index(name)
            return units.convert(self._cart_unit[i], unit, self._cart[i])
        elif name in self._cart_names_pm:
            # Cartesian velocity
            i = self._cart_names_pm.index(name)
            return units.convert(self._cart_unit_pm[i], unit, self._cart_pm[i])

        elif name in self._longitude_names:
            return units.convert(self._sph_unit[0], unit, self._sph[0])
        elif name in self._longitude_names_pm:
            return units.convert(self._sph_unit_pm[0], unit, self._sph_pm[0])

        elif name in self._latitude_names:
            return units.convert(self._sph_unit[1], unit, self._sph[1])
        elif name in self._latitude_names_pm:
            return units.convert(self._sph_unit_pm[1], unit, self._sph_pm[1])

        elif name in self._dist_names:
            return units.convert(self._sph_unit[2], unit, self._sph[2])
        elif name in self._dist_names_pm:
            return units.convert(self._sph_unit_pm[2], unit, self._sph_pm[2])

        else:
            raise Exception("Name not recognized: %s" % name)
示例#6
0
    def get_basic(self, name=None, unit=None):
        """ Gets the value under the given name converting it into the given unit, if possible.

            For example:
            -- self.get_basic('x', 'km') will return the value of x in kilometers.
            -- self.get_basic('longitude', 'deg') will return the longitude angle in degrees.
        """
        if name in self._cart_names:
            # Cartesian coordinate
            i = self._cart_names.index(name)
            return units.convert(self._cart_unit[i], unit, self._cart[i])
        elif name in self._cart_names_pm:
            # Cartesian velocity
            i = self._cart_names_pm.index(name)
            return units.convert(self._cart_unit_pm[i], unit, self._cart_pm[i])

        elif name in self._longitude_names:
            return units.convert(self._sph_unit[0], unit, self._sph[0])
        elif name in self._longitude_names_pm:
            return units.convert(self._sph_unit_pm[0], unit, self._sph_pm[0])

        elif name in self._latitude_names:
            return units.convert(self._sph_unit[1], unit, self._sph[1])
        elif name in self._latitude_names_pm:
            return units.convert(self._sph_unit_pm[1], unit, self._sph_pm[1])

        elif name in self._dist_names:
            return units.convert(self._sph_unit[2], unit, self._sph[2])
        elif name in self._dist_names_pm:
            return units.convert(self._sph_unit_pm[2], unit, self._sph_pm[2])

        else:
            raise Exception("Name not recognized: %s" % name)
示例#7
0
def method_CLANCELOT(opt_method="LBFGS"):
    from files import read_xyz, write_xyz
    import neb
    from units import convert, convert_energy

    FPTR = "./../xyz/CNH_HCN.xyz"
    frames = read_xyz(FPTR)
    route = '! HF-3c'

    if RIGID_ROTATION:
        is_on = "ON"
    else:
        is_on = "OFF"

    print("\nRUNNING CLANCELOT SIMULATION WITH RIGID_ROTATION %s...\n" % is_on)

    run_name = 'CNH_HCN_c_' + opt_method
    new_opt_params = {
        'step_size': ALPHA,
        'step_size_adjustment': 0.5,
        'max_step': MAX_STEP,
        'linesearch': 'backtrack',
        'accelerate': True,
        'reset_step_size': 5,
        'g_rms': convert("eV/Ang", "Ha/Ang", 0.03),
        'g_max': convert("eV/Ang", "Ha/Ang", FMAX)
    }

    opt = neb.NEB(run_name,
                  frames,
                  route,
                  k=convert_energy("eV", "Ha", 0.1),
                  opt=opt_method,
                  new_opt_params=new_opt_params)
    output = opt.optimize()
    frames = output[-1]

    write_xyz(frames, "CNH_HCN_opt_%s" % opt_method)

    print("\nDONE WITH CLANCELOT SIMULATION...\n")
示例#8
0
文件: calc.py 项目: isomer/calc
	def getValue(self,symtab):
		# Ok, we have to convert everything to be in the same units.
		lhs = self.lhs.eval(symtab)
		rhs = self.rhs.eval(symtab)

		if rhs.getUnit(symtab)==None:
			# If the rhs has no unit, we pretend it's in the
			# same unit.  People are lazy, and the alternative
			# is to raise an error, which just infuriates users
			pass
		else:
			# Ok, the rhs has a unit, we need to convert it to
			# be the same as the left
			rhs=units.convert(rhs,rhs.getUnit(symtab),lhs.getUnit(symtab))
		a=Value(eval("(lhs.getValue(symtab) "+self.op+" rhs.getValue(symtab))"),lhs.getUnit(symtab))
		return a
示例#9
0
def parse_nutrition(data):
    logger.debug('parsing {}'.format(data['name']))
    nutrients = {}
    required = list(NUTRI_NAMES.keys())
    for n in data['nutrients']:
        id = str(n['nutrient_id'])
        name = NUTRI_NAMES.get(id)
        if name is None:
            logger.debug('skipping {} ({})'.format(id, n['name']))
            continue
        required.remove(id)

        # standardize units for nutrients
        # all nutrient measurements are per 100g
        # we convert to 1g
        qty = (float(n['value']) / 100, n['unit'])
        std_unit = STANDARD_UNITS[name]
        qty = units.convert(qty, std_unit)

        # merge
        if name in nutrients:
            nutrients[name]['value'] += qty[0]
        else:
            nutrients[name] = {'value': qty[0], 'unit': std_unit}

    # assume non-specified nutrients are 0
    for id in required:
        name = NUTRI_NAMES[id]
        if name not in nutrients:
            std_unit = STANDARD_UNITS[name]
            nutrients[name] = {'value': 0, 'unit': std_unit}

    # measurement conversions seem to be identical
    # for all nutrients
    conversions = []
    for m in data['nutrients'][0]['measures']:
        c = [(m['eqv'], m['eunit']), (m['qty'], m['label'])]
        conversions.append(c)

    return {
        'id': data['ndbno'],
        'name': data['name'],
        'unit': data['ru'],  # reporting unit
        'nutrients': nutrients,
        'conversions': conversions
    }
示例#10
0
    def getValue(self, symtab):
        # Ok, we have to convert everything to be in the same units.
        lhs = self.lhs.eval(symtab)
        rhs = self.rhs.eval(symtab)

        if rhs.getUnit(symtab) == None:
            # If the rhs has no unit, we pretend it's in the
            # same unit.  People are lazy, and the alternative
            # is to raise an error, which just infuriates users
            pass
        else:
            # Ok, the rhs has a unit, we need to convert it to
            # be the same as the left
            rhs = units.convert(rhs, rhs.getUnit(symtab), lhs.getUnit(symtab))
        a = Value(
            eval("(lhs.getValue(symtab) " + self.op +
                 " rhs.getValue(symtab))"), lhs.getUnit(symtab))
        return a
示例#11
0
文件: rest.py 项目: garretlh/nimbus
    def get_tnc_packet(self, record):
        """Form the TNC2 packet used by CWOP."""

        # Preamble to the TNC packet:
        _prefix = "%s>APRS,TCPIP*:" % (self.station,)

        # Time:
        _time_tt = time.gmtime(record['dateTime'])
        _time_str = time.strftime("@%d%H%Mz", _time_tt)

        # Position:
        _lat_str = latlon_string(self.latitude,
                                                     ('N', 'S'), 'lat')
        _lon_str = latlon_string(self.longitude,
                                                     ('E', 'W'), 'lon')
        _latlon_str = '%s%s%s/%s%s%s' % (_lat_str + _lon_str)

        # Wind and temperature
        _wt_list = []
        for _obs_type in ['windDir', 'windSpeed', 'windGust', 'outTemp']:
            _v = record.get(_obs_type)
            _wt_list.append("%03d" % _v if _v is not None else '...')
        _wt_str = "_%s/%sg%st%s" % tuple(_wt_list)

        # Rain
        _rain_list = []
        for _obs_type in ['hourRain', 'rain24', 'dayRain']:
            _v = record.get(_obs_type)
            _rain_list.append("%03d" % (_v * 100.0) if _v is not None else '...')
        _rain_str = "r%sp%sP%s" % tuple(_rain_list)

        # Barometer:
        _baro = record.get('altimeter')
        if _baro is None:
            _baro_str = "b....."
        else:
            # While everything else in the CWOP protocol is in US Customary,
            # they want the barometer in millibars.
            _new_baro = convert(_baro, 'inHg', 'mbar')
            _baro_str = "b%05d" % (_new_baro * 10.0)

        # Humidity:
        _humidity = record.get('outHumidity')
        if _humidity is None:
            _humid_str = "h.."
        else:
            _humid_str = ("h%02d" % _humidity) if _humidity < 100.0 else "h00"

        # Radiation:
        _radiation = record.get('radiation')
        if _radiation is None:
            _radiation_str = ""
        elif _radiation < 1000.0:
            _radiation_str = "L%03d" % _radiation
        elif _radiation < 2000.0:
            _radiation_str = "l%03d" % (_radiation - 1000)
        else:
            _radiation_str = ""

        # Station equipment
        _equipment_str = ".nimbus-%s" % self.station_type
        
        _tnc_packet = ''.join([_prefix, _time_str, _latlon_str, _wt_str,
                               _rain_str, _baro_str, _humid_str,
                               _radiation_str, _equipment_str, "\r\n"])

        return _tnc_packet
示例#12
0
    def calculate(self, coords):
        self.calls_to_calculate += 1

        # Update coordinates in states. This won't change anything on
        # the first run through, but will on subsequent ones
        coord_count = 0
        for s in self.states[1:-1]:
            for a in s:
                a.x, a.y, a.z = coords[coord_count:coord_count + 3]
                coord_count += 3

        # Start DFT jobs
        running_jobs = []
        for i, state in enumerate(self.states):
            if (i == 0 or i == len(self.states) - 1) and self.step > 0:
                # No need to calculate anything for first and last states
                # after the first step
                pass
            else:
                running_jobs.append(
                    self.start_job(self, i, state, self.charge, self.procs,
                                   self.queue, self.initial_guess,
                                   self.extra_section, self.mem,
                                   self.priority))
        # Wait for jobs to finish
        for j in running_jobs:
            j.wait()

        # Get forces and energies from DFT calculations
        energies = []
        for i, state in enumerate(self.states):
            # State 0 and state N-1 don't change, so just use result
            # from self.step == 0
            if (i == 0 or i == len(self.states) - 1):
                step_to_use = 0
            else:
                step_to_use = self.step

            new_energy, new_atoms = self.get_results(self, step_to_use, i,
                                                     state)
            energies.append(new_energy)

        # V = potential energy from DFT. energies = V+springs
        V = copy.deepcopy(energies)

        # In climbing image ANEB, after a few iterations we take the highest
        # energy image and use that.
        if self.ci_ANEB and self.ci_img is None and self.step > self.ci_N:
            self.ci_img = V.index(max(V))
            if self.ci_img in [0, len(self.states) - 1]:
                raise Exception("CI found endpoint. Is your band correct?")

        # Get positions in a flat array
        def get_positions(image):
            pos = np.array([np.empty([3]) for j in image])
            for j, atom in enumerate(image):
                if j not in self.spring_atoms:
                    continue
                pos[j] = np.array([atom.x, atom.y, atom.z])
            return pos.flatten()

        # Add spring forces to atoms
        for i in range(1, len(self.states) - 1):
            a = get_positions(self.states[i - 1])
            b = get_positions(self.states[i])
            c = get_positions(self.states[i + 1])

            real_force = np.array([np.empty([3]) for j in self.states[i]])
            for j, atom in enumerate(self.states[i]):
                if j not in self.spring_atoms:
                    continue
                real_force[j] = np.array([atom.fx, atom.fy, atom.fz])
            real_force = real_force.flatten()

            # Find tangent
            tplus = c - b
            tminus = b - a
            dVmin = min(abs(V[i + 1] - V[i]), abs(V[i - 1] - V[i]))
            dVmax = max(abs(V[i + 1] - V[i]), abs(V[i - 1] - V[i]))

            if V[i + 1] > V[i] and V[i] > V[i - 1]:
                tangent = tplus.copy()
            elif V[i + 1] < V[i] and V[i] < V[i - 1]:
                tangent = tminus.copy()
            elif V[i + 1] > V[i - 1]:
                tangent = tplus * dVmax + tminus * dVmin
            else:
                tangent = tplus * dVmin + tminus * dVmax

            # Normalize tangent
            tangent_norm = np.sqrt(np.vdot(tangent, tangent))
            if tangent_norm != 0:
                tangent /= tangent_norm

            F_spring_parallel = self.k[i - 1] * (
                np.linalg.norm(tplus) - np.linalg.norm(tminus)) * tangent

            F_real_perpendicular = real_force -\
                (np.vdot(real_force, tangent) * tangent)

            # Set ANEB forces
            # Note, in climbing image we have the formula:
            #    F = F_real - 2*F_real*tau*tau
            # Vs the normal:
            #    F = F_spring_parallel + F_real_perpendicular
            if self.ci_img is not None and i == self.ci_img:
                forces = real_force - 2.0 * np.vdot(real_force,
                                                    tangent) * tangent
            else:
                forces = F_spring_parallel + F_real_perpendicular
            forces = forces.reshape((-1, 3))
            for j, atom in enumerate(self.states[i]):
                if j not in self.spring_atoms:
                    continue
                atom.fx, atom.fy, atom.fz = forces[j]

        # Remove net translation forces from the gradient
        if self.fit_rigid:
            net_translation_force = []
            for state in self.states[1:-1]:
                net_force = np.zeros(3)
                for a in state:
                    net_force += (a.fx, a.fy, a.fz)
                net_trans = np.sqrt((net_force**2).sum()) / len(state)
                net_translation_force.append(net_trans)
                for a in state:
                    a.fx -= net_force[0] / len(state)
                    a.fy -= net_force[1] / len(state)
                    a.fz -= net_force[2] / len(state)
            max_translation_force = units.convert("Ha/Ang", "eV/Ang",
                                                  max(net_translation_force))
        else:
            max_translation_force = 0

        # Set gradient
        self.gradient = []
        for state in self.states[1:-1]:
            for a in state:
                # Gradient of self.error
                self.gradient += [-a.fx, -a.fy, -a.fz]

        # Calculate RMS Force and Max force
        force_mags = [(a.fx**2 + a.fy**2 + a.fz**2)**0.5
                      for state in self.states[1:-1] for a in state]
        RMS_force = geometry.rms(force_mags)
        self.RMS_force = RMS_force
        MAX_force = max(force_mags)
        self.MAX_force = MAX_force

        # Print data
        V = V[:1] + [
            units.convert_energy("Ha", "kT_300", e - V[0]) for e in V[1:]
        ]
        MAX_energy = max(V)
        if self.prv_RMS is None or self.prv_RMS > RMS_force:
            rms = print_helper.color_set(
                float("%.4f" % units.convert_energy("Ha", "eV", RMS_force)),
                'GREEN')
        else:
            rms = print_helper.color_set(
                float("%.4f" % units.convert_energy("Ha", "eV", RMS_force)),
                'RED')
        if self.prv_MAX is None or self.prv_MAX > MAX_force:
            max_f = print_helper.color_set(
                float("%.4f" % units.convert_energy("Ha", "eV", MAX_force)),
                'GREEN')
        else:
            max_f = print_helper.color_set(
                float("%.4f" % units.convert_energy("Ha", "eV", MAX_force)),
                'RED')
        if self.prv_MAX_E is None or self.prv_MAX_E > MAX_energy:
            max_e = print_helper.color_set(float("%.1f" % MAX_energy), 'GREEN')
        else:
            max_e = print_helper.color_set(float("%.1f" % MAX_energy), 'RED')
        if self.step == 0:
            print("Step\tRMS_F (eV/Ang)\tMAX_F (eV/Ang)\tMAX_E (kT_300)\
\tMAX Translational Force (eV/Ang)\tEnergies (kT_300)\n----")
        print("%d\t%s\t\t%s\t\t%s\t\t%.4f" %
              (self.step, rms, max_f, max_e, max_translation_force)),

        print '    \t\t\t\t', '%7.5g +'\
              % V[0], ('%5.1f ' * len(V[1:])) % tuple(V[1:])

        self.energy_gaps = [V[1]] + [y - x for y, x in zip(V[2:], V[1:-1])]

        sys.stdout.flush()

        if self.prv_RMS is None:
            self.prv_RMS = RMS_force
        self.prv_RMS = min(RMS_force, self.prv_RMS)

        if self.prv_MAX is None:
            self.prv_MAX = MAX_force
        self.prv_MAX = min(MAX_force, self.prv_MAX)

        if self.prv_MAX_E is None:
            self.prv_MAX_E = MAX_energy
        self.prv_MAX_E = min(MAX_energy, self.prv_MAX_E)

        # Set error
        self.error = RMS_force

        # Increment step
        self.step += 1

        if self.callback is not None:
            self.callback(self.states)
示例#13
0
    def __init__(self, precalculate=True, **kwargs):
        # Input units
        units_all = kwargs.pop('unit')

        # Set internal units. We store angles in rad, distances in pc, velocities in km/s and angular
        # velocities in rad/s
        self._sph_unit = ['rad', 'rad', 'pc']
        self._cart_unit = ['pc', 'pc', 'pc']
        self._sph_unit_pm = ['rad/s', 'rad/s', 'km/s']
        self._cart_unit_pm = ['km/s', 'km/s', 'km/s']

        if all(cart_name in kwargs for cart_name in self._cart_names):
            # Cartesian coordinates
            self._cart = [kwargs.pop('x'), kwargs.pop('y'), kwargs.pop('z')]

            # Transform cartesian coordinates to km
            self._cart[0] = units.convert(units_all[:3][0], self._cart_unit[0], self._cart[0])
            self._cart[1] = units.convert(units_all[:3][1], self._cart_unit[1], self._cart[1])
            self._cart[2] = units.convert(units_all[:3][2], self._cart_unit[2], self._cart[2])

            if all(cart_name_pm in kwargs for cart_name_pm in self._cart_names_pm):
                # Cartesian velocities
                self._cart_pm = [kwargs.pop('xdot'), kwargs.pop('ydot'), kwargs.pop('zdot')]

                # Transform cartesian velocities to km/s
                self._cart_pm[0] = units.convert(units_all[3:][0], self._cart_unit_pm[0], self._cart_pm[0])
                self._cart_pm[1] = units.convert(units_all[3:][1], self._cart_unit_pm[1], self._cart_pm[1])
                self._cart_pm[2] = units.convert(units_all[3:][2], self._cart_unit_pm[2], self._cart_pm[2])

                self._pm = True

        elif any(latitude in kwargs for latitude in self._latitude_names) and any(longitude in kwargs for longitude in self._longitude_names) and any(dist in kwargs for dist in self._dist_names):
            # Spherical coordinates names
            long_name = next(longitude for longitude in self._longitude_names if longitude in kwargs)
            lat_name = next(latitude for latitude in self._latitude_names if latitude in kwargs)
            dist_name = next(dist for dist in self._dist_names if dist in kwargs)

            # Spherical coordinates
            self._sph = [kwargs.pop(long_name), kwargs.pop(lat_name), kwargs.pop(dist_name)]
            aux_sph_unit = units_all[:3]

            # Convert angles to rad and distance to km
            self._sph[0] = units.convert(aux_sph_unit[0], self._sph_unit[0], self._sph[0])
            self._sph[1] = units.convert(aux_sph_unit[1], self._sph_unit[1], self._sph[1])
            self._sph[2] = units.convert(aux_sph_unit[2], self._sph_unit[2], self._sph[2])

            if any(latitude_pm in kwargs for latitude_pm in self._latitude_names_pm) and any(longitude_pm in kwargs for longitude_pm in self._longitude_names_pm) and any(radvel in kwargs for radvel in self._dist_names_pm):
                # Spherical proper motions names
                long_name_pm = next(longitude_pm for longitude_pm in self._longitude_names_pm if longitude_pm in kwargs)
                lat_name_pm = next(latitude_pm for latitude_pm in self._latitude_names_pm if latitude_pm in kwargs)
                dist_name_pm = next(radvel for radvel in self._dist_names_pm if radvel in kwargs)

                # Spherical proper motions
                self._sph_pm = [kwargs.pop(long_name_pm), kwargs.pop(lat_name_pm), kwargs.pop(dist_name_pm)]
                aux_sph_unit_pm = units_all[3:]

                # Convert proper motions to rad/s and radial velocity to km/s
                self._sph_pm[0] = units.convert(aux_sph_unit_pm[0], self._sph_unit_pm[0], self._sph_pm[0])
                self._sph_pm[1] = units.convert(aux_sph_unit_pm[1], self._sph_unit_pm[1], self._sph_pm[1])
                self._sph_pm[2] = units.convert(aux_sph_unit_pm[2], self._sph_unit_pm[2], self._sph_pm[2])

                self._pm = True

        else:
            raise Exception("%s initialized with insufficient or inconsistent data: %s" % (self._name.title(), kwargs))

        if precalculate:
            # Work out cartesian or spherical right now
            self._calculate_other_coordinates()
示例#14
0
    def calculate(self, coords):
        self.calls_to_calculate += 1

        # Update coordinates in states. This won't change anything on
        # the first run through, but will on subsequent ones
        coord_count = 0
        for s in self.states[1:-1]:
            for a in s:
                a.x, a.y, a.z = coords[coord_count:coord_count + 3]
                coord_count += 3

        # Start DFT jobs
        running_jobs = []
        if self.initialize == True:
            # Run a single point calculation to determine energies before main curve-smoothing begins
            for i, state in enumerate(self.states):
                running_jobs.append(
                    self.start_job(self, i, state, self.charge, self.procs,
                                   self.queue, self.initial_guess,
                                   self.extra_section, self.mem,
                                   self.priority))
        else:
            # Once initialization is complete, run main spline_NEB simulation for curve smoothing
            for i, state in enumerate(self.states):
                if (i == 0 or i == self.peak
                        or i == len(self.states) - 1) and self.step > 0:
                    # No need to calculate anything for first and last states
                    # after the first step
                    pass
                else:
                    running_jobs.append(
                        self.start_job(self, i, state, self.charge, self.procs,
                                       self.queue, self.initial_guess,
                                       self.extra_section, self.mem,
                                       self.priority))
        # Wait for jobs to finish
        for j in running_jobs:
            j.wait()

        # Get forces and energies from DFT calculations
        energies = []
        for i, state in enumerate(self.states):
            # State 0 and state N-1 don't change, so just use result
            # from self.step == 0
            if (i == 0 or i == self.peak or i == len(self.states) - 1):
                step_to_use = 0
            else:
                step_to_use = self.step

            new_energy, new_atoms = self.get_results(self, step_to_use, i,
                                                     state)
            energies.append(new_energy)

        # V = potential energy from DFT. energies = V+springs
        V = copy.deepcopy(energies)

        # Get positions in a flat array
        def get_positions(image):
            pos = np.array([np.empty([3]) for j in image])
            for j, atom in enumerate(image):
                if j not in self.spring_atoms:
                    continue
                pos[j] = np.array([atom.x, atom.y, atom.z])
            return pos.flatten()

        if self.initialize == True:
            # During initialization phase, use single point energies previously calculated to
            # determine highest energy frame (peak) and generate spring constants between frames
            # Peak of reaction coordinate is highest energy frame
            self.peak = energies.index(max(energies))

            #Calculate spring constants for smoothing curve
            d_before = np.linalg.norm(
                get_positions(self.states[self.peak]) -
                get_positions(self.states[0]))
            d_after = np.linalg.norm(
                get_positions(self.states[self.peak]) -
                get_positions(self.states[-1]))

            l_before = -d_before**2 / np.log(self.gamma)
            l_after = -d_after**2 / np.log(self.gamma)

            x1, x2 = [], []
            for i in range(self.peak):
                v = (get_positions(self.states[i]) +
                     get_positions(self.states[i+1])) / 2.0 - \
                     get_positions(self.states[0])
                x1.append(np.linalg.norm(v))

            for i in range(self.peak, len(self.states) - 1):
                v = (get_positions(self.states[i]) +
                     get_positions(self.states[i+1])) / 2.0 - \
                     get_positions(self.states[0])
                x2.append(np.linalg.norm(v))

            for x in x1:
                self.k.append(self.k_max *
                              exp(-((x - d_before)**2) / l_before))
            for x in x2:
                self.k.append(self.k_max * exp(-((x - d_after)**2) / l_after))

        # Add spring forces to atoms
        for i in range(1, len(self.states) - 1):
            if i == self.peak:
                # Set NEB forces at peak to 0
                for j, atom in enumerate(self.states[i]):
                    if j not in self.spring_atoms:
                        continue
                    atom.fx, atom.fy, atom.fz = [0, 0, 0]
            else:
                a = get_positions(self.states[i - 1])
                b = get_positions(self.states[i])
                c = get_positions(self.states[i + 1])

                real_force = np.array([np.empty([3]) for j in self.states[i]])
                for j, atom in enumerate(self.states[i]):
                    if j not in self.spring_atoms:
                        continue
                    real_force[j] = np.array([atom.fx, atom.fy, atom.fz])
                real_force = real_force.flatten()

                # Find tangent
                tplus = c - b
                tminus = b - a
                dVmin = min(abs(V[i + 1] - V[i]), abs(V[i - 1] - V[i]))
                dVmax = max(abs(V[i + 1] - V[i]), abs(V[i - 1] - V[i]))

                if V[i + 1] > V[i] and V[i] > V[i - 1]:
                    tangent = tplus.copy()
                elif V[i + 1] < V[i] and V[i] < V[i - 1]:
                    tangent = tminus.copy()
                elif V[i + 1] > V[i - 1]:
                    tangent = tplus * dVmax + tminus * dVmin
                else:
                    tangent = tplus * dVmin + tminus * dVmax

                # Normalize tangent
                tangent_norm = np.sqrt(np.vdot(tangent, tangent))
                if tangent_norm != 0:
                    tangent /= tangent_norm

# Set NEB forces
                forces = (self.k[i] * np.linalg.norm(tplus) -
                          self.k[i - 1] * np.linalg.norm(tminus)) * tangent
                forces = forces.reshape((-1, 3))
                for j, atom in enumerate(self.states[i]):
                    if j not in self.spring_atoms:
                        continue
                    atom.fx, atom.fy, atom.fz = forces[j]

        # Remove net translation forces from the gradient
        if self.fit_rigid:
            net_translation_force = []
            for state in self.states[1:-1]:
                net_force = np.zeros(3)
                for a in state:
                    net_force += (a.fx, a.fy, a.fz)
                net_trans = np.sqrt((net_force**2).sum()) / len(state)
                net_translation_force.append(net_trans)
                for a in state:
                    a.fx -= net_force[0] / len(state)
                    a.fy -= net_force[1] / len(state)
                    a.fz -= net_force[2] / len(state)
            max_translation_force = units.convert("Ha/Ang", "eV/Ang",
                                                  max(net_translation_force))
        else:
            max_translation_force = 0

        # Set gradient
        self.gradient = []
        for state in self.states[1:-1]:
            for a in state:
                # Gradient of self.error
                self.gradient += [-a.fx, -a.fy, -a.fz]

        # Calculate RMS Force and Max force
        force_mags = [(a.fx**2 + a.fy**2 + a.fz**2)**0.5
                      for state in self.states[1:-1] for a in state]
        RMS_force = geometry.rms(force_mags)
        self.RMS_force = RMS_force
        MAX_force = max(force_mags)
        self.MAX_force = MAX_force

        # Print data
        V = V[:1] + [
            units.convert_energy("Ha", "kT_300", e - V[0]) for e in V[1:]
        ]
        MAX_energy = max(V)
        if self.prv_RMS is None or self.prv_RMS > RMS_force:
            rms = print_helper.color_set(
                float("%.4f" % units.convert_energy("Ha", "eV", RMS_force)),
                'GREEN')
        else:
            rms = print_helper.color_set(
                float("%.4f" % units.convert_energy("Ha", "eV", RMS_force)),
                'RED')
        if self.prv_MAX is None or self.prv_MAX > MAX_force:
            max_f = print_helper.color_set(
                float("%.4f" % units.convert_energy("Ha", "eV", MAX_force)),
                'GREEN')
        else:
            max_f = print_helper.color_set(
                float("%.4f" % units.convert_energy("Ha", "eV", MAX_force)),
                'RED')
        if self.prv_MAX_E is None or self.prv_MAX_E > MAX_energy:
            max_e = print_helper.color_set(float("%.1f" % MAX_energy), 'GREEN')
        else:
            max_e = print_helper.color_set(float("%.1f" % MAX_energy), 'RED')
        if self.step == 0 and self.initialize == False:
            print("Step\tRMS_F (eV/Ang)\tMAX_F (eV/Ang)\tMAX_E (kT_300)\
\tMAX Translational Force (eV/Ang)\tEnergies (kT_300)\n----")
        print("%d\t%s\t\t%s\t\t%s\t\t%.4f" %
              (self.step, rms, max_f, max_e, max_translation_force)),

        print '    \t\t\t\t', '%7.5g +'\
              % V[0], ('%5.1f ' * len(V[1:])) % tuple(V[1:])

        sys.stdout.flush()

        if self.prv_RMS is None:
            self.prv_RMS = RMS_force
        self.prv_RMS = min(RMS_force, self.prv_RMS)

        if self.prv_MAX is None:
            self.prv_MAX = MAX_force
        self.prv_MAX = min(MAX_force, self.prv_MAX)

        if self.prv_MAX_E is None:
            self.prv_MAX_E = MAX_energy
        self.prv_MAX_E = min(MAX_energy, self.prv_MAX_E)

        # Set error
        self.error = RMS_force

        # Increment step
        self.step += 1

        # End initialization phase
        self.initialize = False

        if self.callback is not None:
            self.callback(self.states)
示例#15
0
 def dispFormat(self, unit):
     return str(round(units.convert(self.value, self.unit, unit),
                      6)) + ' ' + unit
示例#16
0
def engrad_read(input_file, force='Ha/Bohr', pos='Bohr'):
    """
    General read in of all possible data from an Orca engrad file
    (.orca.engrad).

    **Parameters**

        input_file: *str*
            Orca .orca.engrad file to be parsed.
        force: *str, optional*
            Units you want force to be returned in.
        pos: *str, optional*
            Units you want position to be returned in.

    **Returns**

        atoms: *list,* :class:`structures.Atom`
            A list of the final atomic state, with forces appended
            to each atom.
        energy: *float*
            The total energy of this simulation.
    """
    if not input_file.endswith('.engrad'):
        input_file = 'orca/%s/%s.orca.engrad' % (input_file, input_file)
    if not os.path.isfile(input_file):
        raise IOError("No engrad file %s exists in %s. \
Please run simulation with grad=True." % (input_file, os.getcwd()))

    data = open(input_file, 'r').read().split('\n')
    count, grad, atoms = 0, [], []
    i = -1
    while i < len(data):
        i += 1
        line = data[i]
        if len(line) < 1:
            continue
        if line.strip()[0] == '#':
            continue
        if count == 0:
            num_atoms = int(line.strip())
            count += 1
        elif count == 1:
            # Get energy
            energy = float(line.strip())
            count += 1
        elif count == 2:
            # Get gradient
            for j in range(num_atoms):
                for k in range(3):
                    grad.append(float(data[i + k].strip()))
                i += 3
            count += 1
        elif count == 3:
            # Get atom coordinates
            k = 0
            for j in range(num_atoms):
                tmp = data[i].split()
                atoms.append(structures.Atom(tmp[0],
                                             units.convert_dist('Bohr',
                                                                pos,
                                                                float(tmp[1])
                                                                ),
                                             units.convert_dist('Bohr',
                                                                pos,
                                                                float(tmp[2])
                                                                ),
                                             units.convert_dist('Bohr',
                                                                pos,
                                                                float(tmp[3])
                                                                )
                                             )
                             )
                atoms[-1].fx = units.convert('Ha/Bohr', force, -grad[k])
                atoms[-1].fy = units.convert('Ha/Bohr', force, -grad[k + 1])
                atoms[-1].fz = units.convert('Ha/Bohr', force, -grad[k + 2])
                i += 1
                k += 3
            break

    return atoms, energy
示例#17
0
文件: calc.py 项目: ondrocks/nutrimix
import yaml
import numpy as np
from colorama import Fore
from mix import CON_NUTRI
from units import convert
from util import sum_quantity_key
from usda import lookup_nutrition, STANDARD_UNITS

# import logging; logging.basicConfig(level=logging.DEBUG)
ingredients = yaml.load(open('shake.yaml', 'r'))
nutritions = [lookup_nutrition(i['id']) for i in ingredients]
for i, n in zip(ingredients, nutritions):
    i.update(n)

mix = np.array([convert(i['qty'], 'g')[0] for i in ingredients])
for k, v in CON_NUTRI.items():
    amt = sum_quantity_key(ingredients, mix, 'nutrients.{}.value'.format(k))
    off_by = amt - v[0]
    percent = amt / v[0] * 100
    if off_by >= 0:
        pre = Fore.GREEN
    else:
        pre = Fore.RED
    off_by = pre + '{}{:.2f}{}'.format('+' if off_by > 0 else '', off_by,
                                       STANDARD_UNITS[k]) + Fore.RESET
    percent = pre + '{:.1f}%'.format(percent) + Fore.RESET
    print('{: >20} {: >12} {: >12} {: <22} {: >20}'.format(
        k, '{:.2f}{}'.format(v[0], STANDARD_UNITS[k]),
        '{:.2f}{}'.format(amt, STANDARD_UNITS[k]), off_by, percent))
示例#18
0
# cube root of the atomic volume, to have an estimate for
# the for the distance between atoms in the solid. (d)
# Repeat the calculations for uranium. 

# The volume of 1 mol of iron is obtained by dividing the molar mass of iron
# by the density of iron.

volume_1mol_fe = Fe().molar_mass / Fe().density #cm^3

print '2) a) The volume of 1 mol of iron is %.2f' % volume_1mol_fe, 'cm^3.'

# The volume of one atom of iron is obtained by dividing the molar mass of iron
# by Avogadro's constant and dividing this by the density of iron.

volume_1atom_fe = Fe().molar_mass / Particle().N_A / Fe().density #cm^3
volume_1atom_fe = units.convert(volume_1atom_fe, 'centi', 'base', 3) #m^3

print '   b) The volume of 1 atom of iron is %.2e' % volume_1atom_fe, 'm^3.'

atom_distance_fe = volume_1atom_fe ** (1.0 / 3.0) #m
atom_distance_fe = units.convert(atom_distance_fe, 'base', 'nano', 1) #nm

print '   c) The distance between atoms is %.3f' % atom_distance_fe, 'nm.'

volume_1mol_u = U().molar_mass / U().density #cm^3
volume_1atom_u = U().molar_mass / Particle().N_A / U().density #cm^3
volume_1atom_u = units.convert(volume_1atom_u, 'centi', 'base', 3) #m^3
atom_distance_u = volume_1atom_u ** (1.0 / 3.0) #m
atom_distance_u = units.convert(atom_distance_u, 'base', 'nano', 1) #nm

print '   d) The volume of 1 mol of uranium is %.1f' % volume_1mol_u, 'cm^3.'
示例#19
0
    def __init__(self, precalculate=True, **kwargs):
        # Input units
        units_all = kwargs.pop('unit')

        # Set internal units. We store angles in rad, distances in pc, velocities in km/s and angular
        # velocities in rad/s
        self._sph_unit = ['rad', 'rad', 'pc']
        self._cart_unit = ['pc', 'pc', 'pc']
        self._sph_unit_pm = ['rad/s', 'rad/s', 'km/s']
        self._cart_unit_pm = ['km/s', 'km/s', 'km/s']

        if all(cart_name in kwargs for cart_name in self._cart_names):
            # Cartesian coordinates
            self._cart = [kwargs.pop('x'), kwargs.pop('y'), kwargs.pop('z')]

            # Transform cartesian coordinates to km
            self._cart[0] = units.convert(units_all[:3][0], self._cart_unit[0],
                                          self._cart[0])
            self._cart[1] = units.convert(units_all[:3][1], self._cart_unit[1],
                                          self._cart[1])
            self._cart[2] = units.convert(units_all[:3][2], self._cart_unit[2],
                                          self._cart[2])

            if all(cart_name_pm in kwargs
                   for cart_name_pm in self._cart_names_pm):
                # Cartesian velocities
                self._cart_pm = [
                    kwargs.pop('xdot'),
                    kwargs.pop('ydot'),
                    kwargs.pop('zdot')
                ]

                # Transform cartesian velocities to km/s
                self._cart_pm[0] = units.convert(units_all[3:][0],
                                                 self._cart_unit_pm[0],
                                                 self._cart_pm[0])
                self._cart_pm[1] = units.convert(units_all[3:][1],
                                                 self._cart_unit_pm[1],
                                                 self._cart_pm[1])
                self._cart_pm[2] = units.convert(units_all[3:][2],
                                                 self._cart_unit_pm[2],
                                                 self._cart_pm[2])

                self._pm = True

        elif any(latitude in kwargs
                 for latitude in self._latitude_names) and any(
                     longitude in kwargs
                     for longitude in self._longitude_names) and any(
                         dist in kwargs for dist in self._dist_names):
            # Spherical coordinates names
            long_name = next(longitude for longitude in self._longitude_names
                             if longitude in kwargs)
            lat_name = next(latitude for latitude in self._latitude_names
                            if latitude in kwargs)
            dist_name = next(dist for dist in self._dist_names
                             if dist in kwargs)

            # Spherical coordinates
            self._sph = [
                kwargs.pop(long_name),
                kwargs.pop(lat_name),
                kwargs.pop(dist_name)
            ]
            aux_sph_unit = units_all[:3]

            # Convert angles to rad and distance to km
            self._sph[0] = units.convert(aux_sph_unit[0], self._sph_unit[0],
                                         self._sph[0])
            self._sph[1] = units.convert(aux_sph_unit[1], self._sph_unit[1],
                                         self._sph[1])
            self._sph[2] = units.convert(aux_sph_unit[2], self._sph_unit[2],
                                         self._sph[2])

            if any(latitude_pm in kwargs
                   for latitude_pm in self._latitude_names_pm) and any(
                       longitude_pm in kwargs
                       for longitude_pm in self._longitude_names_pm) and any(
                           radvel in kwargs for radvel in self._dist_names_pm):
                # Spherical proper motions names
                long_name_pm = next(
                    longitude_pm for longitude_pm in self._longitude_names_pm
                    if longitude_pm in kwargs)
                lat_name_pm = next(latitude_pm
                                   for latitude_pm in self._latitude_names_pm
                                   if latitude_pm in kwargs)
                dist_name_pm = next(radvel for radvel in self._dist_names_pm
                                    if radvel in kwargs)

                # Spherical proper motions
                self._sph_pm = [
                    kwargs.pop(long_name_pm),
                    kwargs.pop(lat_name_pm),
                    kwargs.pop(dist_name_pm)
                ]
                aux_sph_unit_pm = units_all[3:]

                # Convert proper motions to rad/s and radial velocity to km/s
                self._sph_pm[0] = units.convert(aux_sph_unit_pm[0],
                                                self._sph_unit_pm[0],
                                                self._sph_pm[0])
                self._sph_pm[1] = units.convert(aux_sph_unit_pm[1],
                                                self._sph_unit_pm[1],
                                                self._sph_pm[1])
                self._sph_pm[2] = units.convert(aux_sph_unit_pm[2],
                                                self._sph_unit_pm[2],
                                                self._sph_pm[2])

                self._pm = True

        else:
            raise Exception(
                "%s initialized with insufficient or inconsistent data: %s" %
                (self._name.title(), kwargs))

        if precalculate:
            # Work out cartesian or spherical right now
            self._calculate_other_coordinates()
示例#20
0
def read(input_file, atom_units="Ang"):
    """
    General read in of all possible data from a JDFTx output file.

    **Parameters**

        input_file: *str*
            JDFTx output file to be parsed.
        atom_units: *str, optional*
            What units you want coordinates to be converted to.

    **Returns**

        data: :class:`results.DFT_out`
            Generic DFT output object containing all parsed results.

    """
    # Check file exists, and open
    # Allow absolute paths as filenames
    if not input_file.startswith('/') and not os.path.isfile(input_file):
        input_path = 'jdftx/%s/%s.out' % (input_file, input_file)
    else:
        input_path = input_file
    if not os.path.isfile(input_path):
        raise IOError('Expected JDFTx output file does not exist at %s' %
                      (input_path))
        sys.exit()
    data = open(input_path, 'r').read()
    data_lines = data.splitlines()

    # Get coordinates
    section, frames, gradients = data, [], []
    s = "# Ionic positions in cartesian coordinates:"
    ss = "# Forces in Cartesian coordinates:"
    while s in section:
        section = section[section.find(s) + len(s):]
        atom_block = section[:section.find('\n\n')].split('\n')[1:]
        frame, gradient = [], []
        for i, line in enumerate(atom_block):
            a = line.split()
            frame.append(
                structures.Atom(a[1],
                                units.convert_dist("Bohr", atom_units,
                                                   float(a[2])),
                                units.convert_dist("Bohr", atom_units,
                                                   float(a[3])),
                                units.convert_dist("Bohr", atom_units,
                                                   float(a[4])),
                                index=i))
        frames.append(frame)

        # If we also have forces, read those in
        if ss in section:
            section = section[section.find(ss) + len(ss):]
            force_block = section[:section.find('\n\n')].split('\n')[1:]
            for i, line in enumerate(force_block):
                a = line.split()
                frames[-1][i].fx = units.convert("Ha/Bohr",
                                                 "Ha/%s" % atom_units,
                                                 float(a[2]))
                frames[-1][i].fy = units.convert("Ha/Bohr",
                                                 "Ha/%s" % atom_units,
                                                 float(a[3]))
                frames[-1][i].fz = units.convert("Ha/Bohr",
                                                 "Ha/%s" % atom_units,
                                                 float(a[4]))
                gradient.append(
                    [frames[-1][i].fx, frames[-1][i].fy, frames[-1][i].fz])
            gradients.append(gradient)

    atoms = None
    if frames:
        atoms = frames[-1]

    section, energies = data, []
    s = "IonicMinimize: Iter:"
    while s in section:
        section = section[section.find(s) + len(s):]
        energy = float(section.split("\n")[0].strip().split()[2])
        grad_k = float(section.split("\n")[0].strip().split()[4])
        energies.append(energy)
    convergence = None
    if len(energies) > 2:
        section = data[data.find("ionic-minimize"):]
        de_criteria = float(
            section[section.find("energyDiffThreshold"):].split(
                "\n")[0].strip().split()[1])
        k_criteria = float(section[section.find("knormThreshold"):].split("\n")
                           [0].strip().split()[1])
        de1 = abs(energies[-2] - energies[-3])
        de2 = abs(energies[-1] - energies[-2])
        convergence = [[
            "Change in Energy 1",
            "%.2e" % de1, de_criteria, ["NO", "YES"][de_criteria > de1]
        ],
                       [
                           "Change in Energy 2",
                           "%.2e" % de2, de_criteria,
                           ["NO", "YES"][de_criteria > de2]
                       ],
                       [
                           "K Norm",
                           "%.2e" % abs(grad_k), k_criteria,
                           ["NO", "YES"][k_criteria > abs(grad_k)]
                       ]]
        # convergence = [
        #     ["dE 1 (%.2e)" % de_criteria, "dE 2 (%.2e)" % de_criteria, "K Norm (%.2e)" % k_criteria],
        #     ["%.4e" % abs(energies[-2] - energies[-3]), "%.4e" % abs(energies[-1] - energies[-2]), "%.4e" % abs(grad_k)]
        # ]
    energy = None
    if energies:
        energy = energies[-1]

    converged = None
    finished = "Done!" in data
    if "IonicMinimize: Converged" in data:
        converged = True
    elif finished:
        converged = False

    time = None
    if "Duration:" in data:
        time = data[data.find("Duration:"):].split("\n")[0].split(
            "Duration:")[-1].strip()[:-1].split(":")
        # Time should be x-x:yy:zz.zz, thus: [x-x, yy, zz.zz]
        time = float(time[2]) + 60.0 * float(time[1]) + 3600.0 * float(
            time[0].split("-")[-1])

    data = results.DFT_out(input_file, 'jdftx')

    # data.route = route
    # data.extra_section = extra_section
    # data.charge_and_multiplicity = charge_and_multiplicity.strip()
    data.frames = frames
    data.atoms = atoms
    data.gradients = gradients
    data.energies = energies
    data.energy = energy
    # data.charges_MULLIKEN = charges_MULLIKEN
    # data.charges_LOEWDIN = charges_LOEWDIN
    # data.charges_CHELPG = charges_CHELPG
    # data.charges = copy.deepcopy(charges_MULLIKEN)
    # data.MBO = MBO
    data.convergence = convergence
    data.converged = converged
    data.time = time
    # data.bandgaps = bandgaps
    # data.bandgap = bandgap
    # data.orbitals = orbitals
    data.finished = finished
    # data.warnings = warnings

    return data