示例#1
0
 def get_band_gap(self):
     '''Compute the band gap from the DOS'''
     dosdata = self.get_dos()
     if type(dosdata) == type(None):
         return None  # cannot find DOS
     else:
         energy = dosdata.conditions.scalars
         dos = dosdata.scalars
         step_size = energy[1].value - energy[0].value
         not_found = True
         l = 0
         bot = 10**3
         top = -10**3
         while not_found and l < len(dos):
             # iterate through the data
             e = float(energy[l].value)
             dens = float(dos[l].value)
             # note: dos already shifted by efermi
             if e < 0 and dens > 1e-3:
                 bot = e
             elif e > 0 and dens > 1e-3:
                 top = e
                 not_found = False
             l += 1
         if top < bot:
             raise Exception('Algorithm failed to find the band gap')
         elif top - bot < step_size * 2:
             return Property(scalars=[Scalar(value=0)], units='eV')
         else:
             bandgap = float(top - bot)
             return Property(scalars=[Scalar(value=round(bandgap, 3))],
                             units='eV')
示例#2
0
    def get_dos(self):
        '''Find the total DOS shifted by the Fermi energy'''
        # find the dos file
        fildos = ''
        for f in self._files:
            with open(f, 'r') as fp:
                first_line = next(fp)
                if "E (eV)" in first_line and "Int dos(E)" in first_line:
                    fildos = f
                    ndoscol = len(next(fp).split())-2 # number of spin channels
                    fp.close()
                    break
                fp.close()
        if not fildos:
            return None # cannot find DOS

        # get the Fermi energy
        line = self._get_line('the Fermi energy is', self.outputf)
        efermi = float(line.split('is')[-1].split()[0])

        # grab the DOS
        energy = [] ; dos = []
        fp = open(fildos, 'r')
        next(fp) # comment line
        for line in fp:
            ls = line.split()
            energy.append(Scalar(value=float(ls[0])-efermi))
            dos.append(Scalar(value=sum([float(i) for i in ls[1:1+ndoscol]])))
        return Property(scalars=dos, units='number of states per unit cell', conditions=Value(name='energy', scalars=energy, units='eV'))
示例#3
0
def test_full_round_robin():
    pif = System(properties=[
        Property(
            name="foo",
            scalars=[Scalar(value=np.float32(2.4)),
                     Scalar(value=np.int64(2))]),
        Property(name="bar", scalars=[Scalar(value=2.4),
                                      Scalar(value=2)]),
        Property(name="spam", files=[FileReference(relative_path="/tmp/file")])
    ],
                 preparation=[
                     ProcessStep(name="processed",
                                 details=[
                                     Value(name="temp",
                                           scalars=[Scalar(value=1.0)])
                                 ])
                 ],
                 contacts=[Person(name=Name(family="Einstein"))])

    pif2 = loads(dumps(pif))
    assert pif2.as_dictionary() == pif.as_dictionary(
    ), "PIF contents are not the same"
    assert pif.properties[0].scalars[0].value == pif2.properties[0].scalars[
        0].value
    assert pif.properties[1].scalars[0].value == pif2.properties[1].scalars[
        0].value
    assert pif.properties[2].files[0].relative_path == pif2.properties[
        2].files[0].relative_path
    assert pif.preparation[0].details[0].scalars[0].value == pif2.preparation[
        0].details[0].scalars[0].value
    assert pif.contacts[0].name.family == pif2.contacts[0].name.family
示例#4
0
 def get_vdW_settings(self):
     '''Determine the vdW type if using vdW xc functional or correction
     scheme from the input otherwise'''
     xc = self.get_xc_functional().scalars[0].value
     if 'vdw' in xc.lower():  # vdW xc functional
         return Value(scalars=[Scalar(value=xc)])
     else:
         # look for vdw_corr in input
         vdW_dict = {
             'xdm': 'Becke-Johnson XDM',
             'ts': 'Tkatchenko-Scheffler',
             'ts-vdw': 'Tkatchenko-Scheffler',
             'tkatchenko-scheffler': 'Tkatchenko-Scheffler',
             'grimme-d2': 'Grimme D2',
             'dft-d': 'Grimme D2'
         }
         if self._get_line('vdw_corr',
                           self.inputf,
                           return_string=False,
                           case_sens=False):
             line = self._get_line('vdw_corr',
                                   self.inputf,
                                   return_string=True,
                                   case_sens=False)
             vdwkey = str(
                 line.split('=')[-1].replace("'", "").replace(
                     ',', '').lower().rstrip())
             return Value(scalars=[Scalar(value=vdW_dict[vdwkey])])
         return None
def test_condition():
    """Test that conditions are flattened and added"""
    condition = Value(name="spam", scalars=[Scalar(value="eggs")])
    sys = System(properties=[
        Property(name="foo", scalars=[Scalar(value="bar")], conditions=[condition])
    ])
    user_data = _to_user_defined(sys)
    assert user_data["spam"] == "eggs"
示例#6
0
def test_property_list():
    """Test that a property with a list of scalars gets pulled out"""
    sys = System(properties=[
        Property(name="foo",
                 scalars=[Scalar(
                     value="spam"), Scalar(value="eggs")])
    ])
    user_data = _to_user_defined(sys)
    assert user_data["foo"] == ["spam", "eggs"]
示例#7
0
def test_property_vector():
    """Test that a vector gets pulled out"""
    sys = System(properties=[
        Property(name="foo",
                 units="bar",
                 vectors=[[Scalar(
                     value="spam"), Scalar(value="eggs")]])
    ])
    user_data = _to_user_defined(sys)
    assert user_data["foo_bar"] == ["spam", "eggs"]
示例#8
0
 def get_stresses(self):
     '''Determine the stress tensor from the output'''
     if "stress" not in self.settings:
         return None
     wrapped = [[Scalar(value=x) for x in y]
                for y in self.settings["stress"]]
     return Property(matrices=[wrapped],
                     units=self.settings["stress units"])
示例#9
0
文件: base.py 项目: nitin0301/pif-dft
    def get_number_of_atoms(self):
        """Get the number of atoms in the calculated structure.

        Returns: Property, where number of atoms is a scalar.
        """
        strc = self.get_output_structure()
        if not strc:
            return None
        return Property(scalars=[Scalar(value=len(strc))], units="/unit cell")
示例#10
0
    def is_converged(self):
        '''Whether the calculation has converged
        
        Returns: Property where "scalar" is a boolean indicating
        '''

        # Check for cached result
        if self._converged is None:
            self._converged = self._is_converged()
        return Property(scalars=[Scalar(value=self._converged)])
示例#11
0
def test_add_datacite():
    data_pif = System(
        properties=[Property(name="Foo", scalars=[Scalar(value="bar")])])
    dc = {
        "identifier": {
            "identifier": "000.000",
            "identifierType": "DOI"
        },
        "title":
        "The joy of the PIF",
        "publisher":
        "Ether",
        "publicationYear":
        "2014",
        "creators": [{
            "creatorName": "Kyle Michel",
            "affiliations": ["Berklee", "NW"]
        }]
    }
    res = add_datacite(data_pif, dc)
    assert res.properties[0].scalars[0].value == "bar"
    assert res.references[0].doi == "000.000"

    data_pif2 = System(
        properties=[Property(name="Foo", scalars=[Scalar(value="bar")])])
    dc2 = {
        "title":
        "The joy of the PIF",
        "publisher":
        "Ether",
        "publicationYear":
        "2014",
        "creators": [{
            "creatorName": "Kyle Michel",
            "affiliations": ["Berklee", "NW"]
        }]
    }
    res2 = add_datacite(data_pif2, dc2)
    assert res2.properties[0].scalars[0].value == "bar"
    assert res2.references[0].doi is None
示例#12
0
 def get_pp_name(self):
     '''Determine the pseudopotential names from the output'''
     ppnames = []
     # Find the number of atom types
     natomtypes = int(self._get_line('number of atomic types', self.outputf).split()[5])
     # Find the pseudopotential names
     with open(self.outputf) as fp:
         for line in fp:
             if "PseudoPot. #" in line:
                 ppnames.append(Scalar(value=next(fp).split('/')[-1].rstrip()))
                 if len(ppnames) == natomtypes:
                     return Value(scalars=ppnames)
         raise Exception('Could not find %i pseudopotential names'%natomtypes)
示例#13
0
 def get_cutoff_energy(self):
     if not self._label:
         self._get_label()
     # Open up the label.txt file
     fp = open(os.path.join(self._directory, self._label + '.out'), 'r')
     foundecho = False 
     # Look for ecut after the occurence of "echo values of preprocessed input variables"
     for line in fp:
         if "echo values of preprocessed input variables" in line:
             foundecho = True
         if "ecut" in line and foundecho:
             words = line.split()
             return Value(scalars=[Scalar(value=float(words[1]))], units=words[2])
     # Error handling: ecut not found
     raise Exception('ecut not found')
示例#14
0
 def get_KPPRA(self):
     '''Determine the no. of k-points in the BZ (from the input) times the
     no. of atoms (from the output)'''
     # Find the no. of k-points
     fp = open(os.path.join(self._directory, self.inputf)).readlines()
     for l, ll in enumerate(fp):
         if "K_POINTS" in ll:
             # determine the type of input
             if len(ll.split()) > 1:
                 if "gamma" in ll.split()[1].lower():
                     ktype = 'gamma'
                 elif "automatic" in ll.split()[1].lower():
                     ktype = 'automatic'
                 else:
                     ktype = ''
             else:
                 ktype = ''
             if ktype == 'gamma':
                 # gamma point:
                 # K_POINTS {gamma}
                 nk = 1
             elif ktype == 'automatic':
                 # automatic:
                 # K_POINTS automatic
                 #  12 12 1 0 0 0
                 line = [int(i) for i in fp[l + 1].split()[0:3]]
                 nk = line[0] * line[1] * line[2]
             else:
                 # manual:
                 # K_POINTS
                 #  3
                 #  0.125  0.125  0.0  1.0
                 #  0.125  0.375  0.0  2.0
                 #  0.375  0.375  0.0  1.0
                 nk = 0
                 for k in range(int(fp[l + 1].split()[0])):
                     nk += int(float(fp[l + 2 + k].split()[3]))
             # Find the no. of atoms
             natoms = int(
                 self._get_line('number of atoms/cell',
                                self.outputf).split()[4])
             return Value(scalars=[Scalar(value=nk * natoms)])
     fp.close()
     raise Exception(
         '%s not found in %s' %
         ('KPOINTS', os.path.join(self._directory, self.inputf)))
示例#15
0
 def get_forces(self):
     if "forces" not in self.settings:
         return None
     wrapped = [[Scalar(value=x) for x in y]
                for y in self.settings['forces']]
     return Property(vectors=wrapped, units=self.settings['force units'])
示例#16
0
 def get_positions(self):
     strc = self.get_output_structure()
     raw = strc.positions.tolist()
     wrapped = [[Scalar(value=x) for x in y] for y in raw]
     return Property(vectors=wrapped)
示例#17
0
 def get_density(self):
     """Compute the density from the output structure"""
     strc = self.get_output_structure()
     density = sum(strc.get_masses()) / strc.get_volume() * 1.660539040
     return Property(scalars=[Scalar(value=density)], units="g/(cm^3)")
示例#18
0
 def get_final_volume(self):
     vols_n_units = self.get_list_of_volumes_n_units()
     if not vols_n_units:
         return None
     v, u = self._convert_to_cubic_ang(vols_n_units[-1][0], vols_n_units[-1][1])
     return Property(scalars=[Scalar(value=v)], units=u)
示例#19
0
 def get_xc_functional(self):
     '''Determine the xc functional from the output'''
     return Value(scalars=[
         Scalar(value=" ".join(self.settings["exchange-correlation"]))
     ])
示例#20
0
def test_property_value():
    """Test that a simple property gets pulled out"""
    sys = System(
        properties=[Property(name="foo", scalars=[Scalar(value="bar")])])
    user_data = _to_user_defined(sys)
    assert user_data["foo"] == "bar"
示例#21
0
test_pif1 = ChemicalSystem(
    uid="0",
    chemical_formula="CH4",
    names=["methane", "natural gas"],
    contacts=[
        Person(name=Name(given="Albert", family="Einstein"), orcid="123456"),
        Person(name=Name(given="Adam", family="Min"), email="*****@*****.**")
    ],
    references=[
        Reference(doi="doi", authors=[Name(given="Captain", family="Marvel")])
    ],
    licenses=[License(url="url")],
    tags=["too long", "didn't read"],
    properties=[
        Property(name="foo", scalars=[Scalar(value="bar")]),
        Property(name="spam", scalrs=[Scalar(value="eggs")])
    ])
test_pif2 = ChemicalSystem(uid="0",
                           composition=[
                               Composition(element="H"),
                               Composition(element="S"),
                               Composition(element="O")
                           ],
                           references=[])


@pytest.mark.skipif("CITRINATION_API_KEY" not in environ,
                    reason="No API key available")
def test_query_to_mdf_records():
    """Big integration test to make sure everything is working"""
示例#22
0
 def get_cutoff_energy(self):
     '''Determine the cutoff energy from the output'''
     return Value(
         scalars=[Scalar(value=self.settings["kinetic-energy cutoff"])],
         units=self.settings['kinetic-energy cutoff units'])
示例#23
0
 def get_total_force(self):
     if "total force" not in self.settings:
         return None
     return Property(scalars=[Scalar(value=self.settings['total force'])],
                     units=self.settings['force units'])
示例#24
0
 def _get_key_with_units(self, key):
     if key not in self.settings:
         return None
     return Property(scalars=[Scalar(value=self.settings[key])],
                     units=self.settings["{} units".format(key)])