Ejemplo n.º 1
0
class DeformStructureTransformation(AbstractTransformation):
    """
    This transformation deforms a structure by a deformation gradient matrix

    Args:
        deformation (array): deformation gradient for the transformation
    """
    def __init__(self, deformation=((1, 0, 0), (0, 1, 0), (0, 0, 1))):
        self._deform = Deformation(deformation)
        self.deformation = self._deform.tolist()

    def apply_transformation(self, structure):
        return self._deform.apply_to_structure(structure)

    def __str__(self):
        return "DeformStructureTransformation : " + \
            "Deformation = {}".format(str(self.deformation))

    def __repr__(self):
        return self.__str__()

    @property
    def inverse(self):
        return DeformStructureTransformation(self._deform.inv())

    @property
    def is_one_to_many(self):
        return False
Ejemplo n.º 2
0
class DeformStructureTransformation(AbstractTransformation):
    """
    This transformation deforms a structure by a deformation gradient matrix

    Args:
        deformation (array): deformation gradient for the transformation
    """

    def __init__(self, deformation=((1, 0, 0), (0, 1, 0), (0, 0, 1))):
        self._deform = Deformation(deformation)
        self.deformation = self._deform.tolist()

    def apply_transformation(self, structure):
        return self._deform.apply_to_structure(structure)

    def __str__(self):
        return "DeformStructureTransformation : " + \
            "Deformation = {}".format(str(self.deformation))

    def __repr__(self):
        return self.__str__()

    @property
    def inverse(self):
        return DeformStructureTransformation(self._deform.inv())

    @property
    def is_one_to_many(self):
        return False
Ejemplo n.º 3
0
class DeformStructureTransformation(AbstractTransformation):
    """
    This transformation deforms a structure by a deformation gradient matrix

    Args:
        deformation (array): deformation gradient for the transformation
    """

    def __init__(self, deformation):

        self.deformation = Deformation(deformation)

    def apply_transformation(self, structure):
        return self.deformation.apply_to_structure(structure)

    def __str__(self):
        return "DeformStructureTransformation : " + \
            "Deformation = {}".format(str(self.deformation.tolist()))

    def __repr__(self):
        return self.__str__()

    @property
    def inverse(self):
        return DeformStructureTransformation(self.deformation.inv())

    @property
    def is_one_to_many(self):
        return False

    def as_dict(self):
        return {"name": self.__class__.__name__, "version": __version__,
                "init_args": {"deformation": self.deformation.tolist()},
                "@module": self.__class__.__module__,
                "@class": self.__class__.__name__}
Ejemplo n.º 4
0
class DeformationTest(PymatgenTest):
    def setUp(self):
        self.norm_defo = Deformation.from_index_amount((0, 0), 0.02)
        self.ind_defo = Deformation.from_index_amount((0, 1), 0.02)
        self.non_ind_defo = Deformation([[1.0, 0.02, 0.02], [0.0, 1.0, 0.0],
                                         [0.0, 0.0, 1.0]])
        lattice = Lattice([[3.8401979337, 0.00, 0.00],
                           [1.9200989668, 3.3257101909, 0.00],
                           [0.00, -2.2171384943, 3.1355090603]])
        self.structure = Structure(lattice, ["Si", "Si"],
                                   [[0, 0, 0], [0.75, 0.5, 0.75]])

    def test_properties(self):
        # green_lagrange_strain
        self.assertArrayAlmostEqual(
            self.ind_defo.green_lagrange_strain,
            [[0., 0.01, 0.], [0.01, 0.0002, 0.], [0., 0., 0.]])
        self.assertArrayAlmostEqual(
            self.non_ind_defo.green_lagrange_strain,
            [[0., 0.01, 0.01], [0.01, 0.0002, 0.0002], [0.01, 0.0002, 0.0002]])

    def test_independence(self):
        self.assertFalse(self.non_ind_defo.is_independent())
        self.assertEqual(self.ind_defo.get_perturbed_indices()[0], (0, 1))

    def test_apply_to_structure(self):
        strained_norm = self.norm_defo.apply_to_structure(self.structure)
        strained_ind = self.ind_defo.apply_to_structure(self.structure)
        strained_non = self.non_ind_defo.apply_to_structure(self.structure)
        # Check lattices
        self.assertArrayAlmostEqual(
            strained_norm.lattice.matrix,
            [[3.9170018886, 0, 0], [1.958500946136, 3.32571019, 0],
             [0, -2.21713849, 3.13550906]])
        self.assertArrayAlmostEqual(
            strained_ind.lattice.matrix,
            [[3.84019793, 0, 0], [1.9866132, 3.32571019, 0],
             [-0.04434277, -2.21713849, 3.13550906]])
        self.assertArrayAlmostEqual(
            strained_non.lattice.matrix,
            [[3.84019793, 0, 0], [1.9866132, 3.3257102, 0],
             [0.0183674, -2.21713849, 3.13550906]])
        # Check coordinates
        self.assertArrayAlmostEqual(strained_norm.sites[1].coords,
                                    [3.91700189, 1.224e-06, 2.3516318])
        self.assertArrayAlmostEqual(strained_ind.sites[1].coords,
                                    [3.84019793, 1.224e-6, 2.3516318])
        self.assertArrayAlmostEqual(strained_non.sites[1].coords,
                                    [3.8872306, 1.224e-6, 2.3516318])

        # Check convention for applying transformation
        for vec, defo_vec in zip(self.structure.lattice.matrix,
                                 strained_non.lattice.matrix):
            new_vec = np.dot(self.non_ind_defo, np.transpose(vec))
            self.assertArrayAlmostEqual(new_vec, defo_vec)
        for coord, defo_coord in zip(self.structure.cart_coords,
                                     strained_non.cart_coords):
            new_coord = np.dot(self.non_ind_defo, np.transpose(coord))
            self.assertArrayAlmostEqual(new_coord, defo_coord)
Ejemplo n.º 5
0
class DeformationTest(PymatgenTest):
    def setUp(self):
        self.norm_defo = Deformation.from_index_amount((0, 0), 0.02)
        self.ind_defo = Deformation.from_index_amount((0, 1), 0.02)
        self.non_ind_defo = Deformation([[1.0, 0.02, 0.02],
                                         [0.0, 1.0, 0.0],
                                         [0.0, 0.0, 1.0]])
        lattice = Lattice([[3.8401979337, 0.00, 0.00],
                           [1.9200989668, 3.3257101909, 0.00],
                           [0.00, -2.2171384943, 3.1355090603]])
        self.structure = Structure(lattice, ["Si", "Si"], [[0, 0, 0],
                                                           [0.75, 0.5, 0.75]])

    def test_properties(self):
        # green_lagrange_strain
        self.assertArrayAlmostEqual(self.ind_defo.green_lagrange_strain,
                                    [[0., 0.01, 0.],
                                     [0.01, 0.0002, 0.],
                                     [0., 0., 0.]])
        self.assertArrayAlmostEqual(self.non_ind_defo.green_lagrange_strain,
                                    [[0., 0.01, 0.01],
                                     [0.01, 0.0002, 0.0002],
                                     [0.01, 0.0002, 0.0002]])

    def test_check_independent(self):
        self.assertRaises(ValueError, self.non_ind_defo.check_independent)
        self.assertEqual(self.ind_defo.check_independent(), (0, 1))

    def test_apply_to_structure(self):
        strained_norm = self.norm_defo.apply_to_structure(self.structure)
        strained_ind = self.ind_defo.apply_to_structure(self.structure)
        strained_non = self.non_ind_defo.apply_to_structure(self.structure)
        # Check lattices
        self.assertArrayAlmostEqual(strained_norm.lattice.matrix,
                                    [[3.9170018886, 0, 0],
                                     [1.958500946136, 3.32571019, 0],
                                     [0, -2.21713849, 3.13550906]])
        self.assertArrayAlmostEqual(strained_ind.lattice.matrix,
                                    [[3.84019793, 0.07680396, 0],
                                     [1.92009897, 3.36411217, 0],
                                     [0, -2.21713849, 3.13550906]])
        self.assertArrayAlmostEqual(strained_non.lattice.matrix,
                                    [[3.84019793, 0.07680396, 0.07680396],
                                     [1.92009897, 3.36411217, 0.0384019794],
                                     [0, -2.21713849, 3.13550906]])
        # Check coordinates
        self.assertArrayAlmostEqual(strained_norm.sites[1].coords,
                                    [3.91700189, 1.224e-06, 2.3516318])
        self.assertArrayAlmostEqual(strained_ind.sites[1].coords,
                                    [3.84019793, 0.07680518, 2.3516318])
        self.assertArrayAlmostEqual(strained_non.sites[1].coords,
                                    [3.84019793, 0.07680518, 2.42843575])
Ejemplo n.º 6
0
 def apply(self, structure, strength_multiplier=1.):
     deformation = Deformation(
         np.eye(3) + strength_multiplier * self.deformation_matrix)
     new_structure = deformation.apply_to_structure(structure)
     # move positions
     if self.pos_displacement_matrices is not None:
         for idx, mat in self.pos_displacement_matrices:
             new_structure.translate_sites(
                 indices=[idx],
                 # use original cartesian positions
                 vector=strength_multiplier *
                 np.dot(mat, structure.cart_coords[idx]),
                 frac_coords=False)
     return new_structure
Ejemplo n.º 7
0
class DeformationTest(PymatgenTest):
    def setUp(self):
        self.norm_defo = Deformation.from_index_amount((0, 0), 0.02)
        self.ind_defo = Deformation.from_index_amount((0, 1), 0.02)
        self.non_ind_defo = Deformation([[1.0, 0.02, 0.02], [0.0, 1.0, 0.0],
                                         [0.0, 0.0, 1.0]])
        lattice = Lattice([[3.8401979337, 0.00, 0.00],
                           [1.9200989668, 3.3257101909, 0.00],
                           [0.00, -2.2171384943, 3.1355090603]])
        self.structure = Structure(lattice, ["Si", "Si"],
                                   [[0, 0, 0], [0.75, 0.5, 0.75]])

    def test_properties(self):
        # green_lagrange_strain
        self.assertArrayAlmostEqual(
            self.ind_defo.green_lagrange_strain,
            [[0., 0.01, 0.], [0.01, 0.0002, 0.], [0., 0., 0.]])
        self.assertArrayAlmostEqual(
            self.non_ind_defo.green_lagrange_strain,
            [[0., 0.01, 0.01], [0.01, 0.0002, 0.0002], [0.01, 0.0002, 0.0002]])

    def test_check_independent(self):
        self.assertRaises(ValueError, self.non_ind_defo.check_independent)
        self.assertEqual(self.ind_defo.check_independent(), (0, 1))

    def test_apply_to_structure(self):
        strained_norm = self.norm_defo.apply_to_structure(self.structure)
        strained_ind = self.ind_defo.apply_to_structure(self.structure)
        strained_non = self.non_ind_defo.apply_to_structure(self.structure)
        # Check lattices
        self.assertArrayAlmostEqual(
            strained_norm.lattice.matrix,
            [[3.9170018886, 0, 0], [1.958500946136, 3.32571019, 0],
             [0, -2.21713849, 3.13550906]])
        self.assertArrayAlmostEqual(
            strained_ind.lattice.matrix,
            [[3.84019793, 0.07680396, 0], [1.92009897, 3.36411217, 0],
             [0, -2.21713849, 3.13550906]])
        self.assertArrayAlmostEqual(strained_non.lattice.matrix,
                                    [[3.84019793, 0.07680396, 0.07680396],
                                     [1.92009897, 3.36411217, 0.0384019794],
                                     [0, -2.21713849, 3.13550906]])
        # Check coordinates
        self.assertArrayAlmostEqual(strained_norm.sites[1].coords,
                                    [3.91700189, 1.224e-06, 2.3516318])
        self.assertArrayAlmostEqual(strained_ind.sites[1].coords,
                                    [3.84019793, 0.07680518, 2.3516318])
        self.assertArrayAlmostEqual(strained_non.sites[1].coords,
                                    [3.84019793, 0.07680518, 2.42843575])
Ejemplo n.º 8
0
class DeformStructureTransformation(AbstractTransformation):
    """
    This transformation deforms a structure by a deformation gradient matrix
    """

    def __init__(self, deformation=((1, 0, 0), (0, 1, 0), (0, 0, 1))):
        """
        Args:
            deformation (array): deformation gradient for the transformation
        """
        self._deform = Deformation(deformation)
        self.deformation = self._deform.tolist()

    def apply_transformation(self, structure):
        """
        Apply the transformation.

        Args:
            structure (Structure): Input Structure

        Returns:
            Deformed Structure.
        """
        return self._deform.apply_to_structure(structure)

    def __str__(self):
        return f"DeformStructureTransformation : Deformation = {self.deformation}"

    def __repr__(self):
        return self.__str__()

    @property
    def inverse(self):
        """
        Returns:
            Inverse Transformation.
        """
        return DeformStructureTransformation(self._deform.inv)

    @property
    def is_one_to_many(self):
        """
        Returns: False
        """
        return False
Ejemplo n.º 9
0
class DeformationTest(PymatgenTest):
    def setUp(self):
        self.norm_defo = Deformation.from_index_amount((0, 0), 0.02)
        self.ind_defo = Deformation.from_index_amount((0, 1), 0.02)
        self.non_ind_defo = Deformation([[1.0, 0.02, 0.02],
                                         [0.0, 1.0, 0.0],
                                         [0.0, 0.0, 1.0]])
        lattice = Lattice([[3.8401979337, 0.00, 0.00],
                           [1.9200989668, 3.3257101909, 0.00],
                           [0.00, -2.2171384943, 3.1355090603]])
        self.structure = Structure(lattice, ["Si", "Si"], [[0, 0, 0],
                                                           [0.75, 0.5, 0.75]])

    def test_properties(self):
        # green_lagrange_strain
        self.assertArrayAlmostEqual(self.ind_defo.green_lagrange_strain,
                                    [[0., 0.01, 0.],
                                     [0.01, 0.0002, 0.],
                                     [0., 0., 0.]])
        self.assertArrayAlmostEqual(self.non_ind_defo.green_lagrange_strain,
                                    [[0., 0.01, 0.01],
                                     [0.01, 0.0002, 0.0002],
                                     [0.01, 0.0002, 0.0002]])

    def test_independence(self):
        self.assertFalse(self.non_ind_defo.is_independent())
        self.assertEqual(self.ind_defo.get_perturbed_indices()[0], (0, 1))

    def test_apply_to_structure(self):
        strained_norm = self.norm_defo.apply_to_structure(self.structure)
        strained_ind = self.ind_defo.apply_to_structure(self.structure)
        strained_non = self.non_ind_defo.apply_to_structure(self.structure)
        # Check lattices
        self.assertArrayAlmostEqual(strained_norm.lattice.matrix,
                                    [[3.9170018886, 0, 0],
                                     [1.958500946136, 3.32571019, 0],
                                     [0, -2.21713849, 3.13550906]])
        self.assertArrayAlmostEqual(strained_ind.lattice.matrix,
                                    [[3.84019793, 0, 0],
                                     [1.9866132, 3.32571019, 0],
                                     [-0.04434277, -2.21713849, 3.13550906]])
        self.assertArrayAlmostEqual(strained_non.lattice.matrix,
                                    [[3.84019793, 0, 0],
                                     [1.9866132, 3.3257102, 0],
                                     [0.0183674, -2.21713849, 3.13550906]])
        # Check coordinates
        self.assertArrayAlmostEqual(strained_norm.sites[1].coords,
                                    [3.91700189, 1.224e-06, 2.3516318])
        self.assertArrayAlmostEqual(strained_ind.sites[1].coords,
                                    [3.84019793, 1.224e-6, 2.3516318])
        self.assertArrayAlmostEqual(strained_non.sites[1].coords,
                                    [3.8872306, 1.224e-6, 2.3516318])

        # Check convention for applying transformation
        for vec, defo_vec in zip(self.structure.lattice.matrix,
                strained_non.lattice.matrix):
            new_vec = np.dot(self.non_ind_defo, np.transpose(vec))
            self.assertArrayAlmostEqual(new_vec, defo_vec)
        for coord, defo_coord in zip(self.structure.cart_coords, strained_non.cart_coords):
            new_coord = np.dot(self.non_ind_defo, np.transpose(coord))
            self.assertArrayAlmostEqual(new_coord, defo_coord)
Ejemplo n.º 10
0
def write_vasp_inputs(Str,
                      VASPDir,
                      functional='PBE',
                      num_kpoints=25,
                      additional_vasp_settings=None,
                      strain=((1.01, 0, 0), (0, 1.05, 0), (0, 0, 1.03))):
    # This is a somewhat strange input set. Essentially the matgen input set (PBE+U), but with tigher
    # convergence.
    # This is also a somewhat outdated and convoluted way to generate VASP inputs but it should work fine.
    # These changes to the default input set give much better results.
    # Do not increaes the EDIFF to make it converge faster!!!
    # If convergence is too slow, reduce the K-points
    # This is still using PBE+U with matgen U values though. Need to use MITCompatibility (after the run)
    # to apply oxygen corrections and such.
    # In other expansions that rely on SCAN or HSE, the corrections are different - no O correction for example
    # In additional_vasp_settings, you can add to, or modify the default VASPsettings.
    VASPSettings = {
        "ALGO": 'VeryFast',
        "ISYM": 0,
        "ISMEAR": 0,
        "EDIFF": 1e-6,
        "NELM": 400,
        "NSW": 1000,
        "EDIFFG": -0.02,
        'LVTOT': False,
        'LWAVE': False,
        'LCHARG': False,
        'NELMDL': -6,
        'NELMIN': 8,
        'LSCALU': False,
        'NPAR': 2,
        'NSIM': 2,
        'POTIM': 0.25,
        'LDAU': True
    }

    if additional_vasp_settings:
        for key in additional_vasp_settings:
            VASPSettings[key] = additional_vasp_settings[key]
            print('Changed {} setting to {}.'.format(
                key, additional_vasp_settings[key]))

    if not os.path.isdir(VASPDir): os.mkdir(VASPDir)

    # Joggle the lattice to help symmetry broken relaxation. You may turn it off by setting strain=None
    if strain:
        deformation = Deformation(strain)
        defStr = deformation.apply_to_structure(Str)

    #Str=Structure(StrainedLatt,Species,FracCoords,to_unit_cell=False,coords_are_cartesian=False);
    VIO = MITRelaxSet(defStr, potcar_functional=functional)
    VIO.user_incar_settings = VASPSettings
    VIO.incar.write_file(os.path.join(VASPDir, 'INCAR'))
    VIO.poscar.write_file(os.path.join(VASPDir, 'POSCAR'))
    Kpoints.automatic(num_kpoints).write_file(os.path.join(VASPDir, 'KPOINTS'))
    # Use PAW_PBE pseudopotentials, cannot use PBE_52, this does not exist on ginar!
    # NOTE: For the POTCARs to work, you need to set up the VASP pseudopotential directory as per the
    # pymatgen instructions, and set the path to them in .pmgrc.yaml located in your home folder.
    # The pymatgen website has instuctrions for how to do this.
    POTSyms = VIO.potcar_symbols
    for i, Sym in enumerate(POTSyms):
        if Sym == 'Zr': POTSyms[i] = 'Zr_sv'
    Potcar(POTSyms,
           functional=functional).write_file(os.path.join(VASPDir, 'POTCAR'))
Ejemplo n.º 11
0
    def _load_data(self):
        """    
        This function parses existing vasp calculations, does mapping check, assigns charges and writes into the calc_data file 
        mentioned in previous functions. What we mean by mapping check here, is to see whether a deformed structure can be mapped
        into a supercell lattice and generates a set of correlation functions in clustersupercell.corr_from_structure.
        
        We plan to do modify corr_from_structure from using pymatgen.structurematcher to a grid matcher, which will ensure higher 
        acceptance for DFT calculations, but does not necessarily improve CE hamitonian, since some highly dipoled and deformed 
        structures might have poor DFT energy, and even SABOTAGE CE!
        """
        # Every key in self.calcdata['compositions'] is a composition, and each composition contains a list of dict entrees.
        # relaxed_structure, input_structure, magmoms, total_energy.

        _is_vasp_calc = lambda fs: 'POSCAR' in fs and 'INCAR' in fs and 'KPOINTS' in fs and 'POTCAR' in fs
        # Load VASP runs from given directories

        n_matched = 0
        n_inputs = 0
        new_unassigned_strs = []
        for root, dirs, files in os.walk(self.vaspdir):
            #A calculation directories has only 3 status:
            #accepted: calculation was successful, and already entered into calcdata.mson
            #falied: calculated but not successful, either aborted or can't be read into calcdata.mson
            #For these above two, we don't want to submit a calculation or post-process again.
            #not marked: calculation run not started or not finished yet. Since analyzer is always called
            #after runner, we don't need to worry that analyzer will find unmarked folders.

            if _is_vasp_calc(files) and (not 'accepted'
                                         in files) and (not 'failed' in files):
                print("Loading VASP run in {}".format(root))
                parent_root = os.path.join(*root.split(os.sep)[0:-1])
                parent_parent_root = os.path.join(*root.split(os.sep)[0:-2])
                with open(
                        os.path.join(parent_parent_root,
                                     'composition_by_site')) as compfile:
                    composition = json.load(compfile)
                    compstring = json.dumps(composition)

                if compstring not in self.calcdata['compositions']:
                    self.calcdata['compositions'][compstring] = []

                if not os.path.isfile(os.path.join(parent_root, 'matrix')):
                    print(
                        'Warning: matrix presave not found. Will autodetect supercell matrix using structure matcher,\
                           and will suffer from numerical errors!')
                    matrix = None
                else:
                    with open(os.path.join(parent_root, 'matrix')) as mat_file:
                        matrix = json.load(mat_file)
                #Check existence of output structure
                try:
                    relaxed_struct = Poscar.from_file(
                        os.path.join(root, 'CONTCAR')).structure
                except:
                    print('Entry {} CONTCAR can not be read. Skipping.'.format(
                        root))
                    open(os.path.join(root, 'failed'), 'a').close()
                    continue

                input_struct = Poscar.from_file(
                    os.path.join(parent_root, 'POSCAR')).structure

                #Check uniqueness
                strict_sm = StructureMatcher(stol=0.1,
                                             ltol=0.1,
                                             angle_tol=1,
                                             comparator=ElementComparator())
                _is_unique = True
                for entry in self.calcdata['compositions'][compstring]:
                    entry_struct = Structure.from_dict(
                        entry['relaxed_structure'])
                    if strict_sm.fit(entry_struct, relaxed_struct):
                        _is_unique = False
                        break
                if not _is_unique:
                    print('Entry {} alredy calculated before.'.format(root))
                    open(os.path.join(root, 'accepted'), 'a').close()
                    continue
                n_inputs += 1

                # Note: the input_struct here comes from the poscar in upper root, rather than fm.0, so
                # it is not deformed.

                # Rescale volume to that of unrelaxed structure, this will lead to a better mapping back.
                # I changed it to a rescaling tensor
                relaxed_lat_mat = np.matrix(relaxed_struct.lattice.matrix)
                input_lat_mat = np.matrix(input_struct.lattice.matrix)
                o2i_deformation = Deformation(input_lat_mat.T *
                                              relaxed_lat_mat.I.T)
                relaxed_deformed = o2i_deformation.apply_to_structure(
                    relaxed_struct)
                #print(relaxed_deformed,input_struct)

                # Assign oxidation states to Mn based on magnetic moments in OUTCAR, first check existence of OUTCAR
                try:
                    Out = Outcar(os.path.join(root, 'OUTCAR'))
                except:
                    print('Entry {} OUTCAR can not be read. Skipping.'.format(
                        root))
                    open(os.path.join(root, 'failed'), 'a').close()
                    continue

                # Get final energy from OSZICAR or Vasprun. Vasprun is better but OSZICAR is much
                # faster and works fine is you separately check for convergence, sanity of
                # magnetic moments, structure geometry
                with open(os.path.join(root, 'OUTCAR')) as outfile:
                    outcar_string = outfile.read()
                if 'reached required accuracy' not in outcar_string:
                    print(
                        'Entry {} did not converge to required accuracy. Skipping.'
                        .format(root))
                    open(os.path.join(root, 'failed'), 'a').close()
                    continue
                TotE = Oszicar(os.path.join(root, 'OSZICAR')).final_energy
                # Checking convergence
                Mag = []
                for SiteInd, Site in enumerate(relaxed_struct.sites):
                    Mag.append(np.abs(Out.magnetization[SiteInd]['tot']))

                new_entry = {}
                new_entry['input_structure'] = input_struct.as_dict()
                new_entry['relaxed_structure'] = relaxed_struct.as_dict()
                new_entry['relaxed_deformed'] = relaxed_deformed.as_dict()
                new_entry['total_energy'] = TotE
                new_entry['magmoms'] = Mag
                new_entry['matrix'] = matrix

                if os.path.isfile(os.path.join(parent_parent_root, 'axis')):
                    with open(os.path.join(parent_parent_root,
                                           'axis')) as axisfile:
                        axis = json.load(axisfile)
                    if 'axis' not in new_entry:
                        new_entry['axis'] = axis

                new_unassigned_strs.append((compstring, root, new_entry))

        if len(new_unassigned_strs) == 0:
            print('No new structures appeared. Calcdata will not be updated.')
            return

        #Charge assignment
        if self.is_charged_ce:
            relaxed_deformed_pool = []
            relaxed_strs_pool = []
            mags = []
            roots = []
            energies = []
            comps = []
            inputs = []
            mats = []
            if 'axis' in new_unassigned_strs[0][2]:
                axis = []
            for compstring, root, new_entry in new_unassigned_strs:
                # Out=Outcar(os.path.join(root,'OUTCAR'))
                Mag = new_entry['magmoms']
                relaxed_struct = Structure.from_dict(
                    new_entry['relaxed_structure'])
                relaxed_deformed = Structure.from_dict(
                    new_entry['relaxed_deformed'])
                # Throw out structures where oxidation states don't make charge balanced.

                mags.append(Mag)
                roots.append(root)
                relaxed_strs_pool.append(relaxed_struct)
                relaxed_deformed_pool.append(relaxed_deformed)
                comps.append(compstring)
                inputs.append(Structure.from_dict(
                    new_entry['input_structure']))
                energies.append(new_entry['total_energy'])
                mats.append(new_entry['matrix'])
                if 'axis' in new_entry:
                    axis.append(new_entry['axis'])

            CA = ChargeAssign(relaxed_strs_pool, mags, algo=self.assign_algo)
            relaxed_strs_assigned = CA.assigned_structures
            relaxed_deformed_assigned = CA.extend_assignments(
                relaxed_deformed_pool, mags)

            for i in range(len(inputs)):
                if relaxed_strs_assigned[
                        i] is not None and relaxed_deformed_assigned[
                            i] is not None:
                    # Checking whether structure can be mapped to corr function.
                    # This is out deformation tolerance.
                    try:
                        if mats[i] is not None:
                            cesup = self.ce.supercell_from_matrix(mats[i])
                            corr = cesup.corr_from_structure(
                                relaxed_deformed_assigned[i])
                        else:
                            corr = self.ce.corr_from_structure(
                                relaxed_deformed_assigned[i])
                    except:
                        print(
                            "Entry {} too far from original lattice. Skipping."
                            .format(roots[i]))
                        open(os.path.join(roots[i], 'failed'), 'a').close()
                        continue

                    assigned_entry = {}
                    assigned_entry['input_structure'] = inputs[i].as_dict()
                    assigned_entry[
                        'relaxed_structure'] = relaxed_strs_assigned[
                            i].as_dict()
                    assigned_entry[
                        'relaxed_deformed'] = relaxed_deformed_assigned[
                            i].as_dict()
                    assigned_entry['matrix'] = mats[i]
                    assigned_entry['total_energy'] = energies[i]
                    assigned_entry['magmoms'] = mags[i]
                    if 'axis' in new_unassigned_strs[0][2]:
                        assigned_entry['axis'] = axis[i]
                    self.calcdata['compositions'][comps[i]].append(
                        assigned_entry)
                    print('Entry {} accepted!'.format(roots[i]))
                    open(os.path.join(roots[i], 'accepted'), 'a').close()
                    n_matched += 1

                else:
                    print("Entry {} can not be assigned. Skipping.".format(
                        roots[i]))
                    open(os.path.join(roots[i], 'failed'), 'a').close()
                    continue
        else:
            print('Doing non charged ce.')
            for compstring, root, new_entry in new_unassigned_strs:
                # Checking whether structure can be mapped to corr function.
                # This is out deformation tolerance.
                try:
                    if new_entry['matrix'] is not None:
                        cesup = self.ce.supercell_from_matrix(
                            new_entry['matrix'])
                        corr = cesup.corr_from_structure(
                            Structure.from_dict(new_entry['relaxed_defromed']))
                    else:
                        corr = self.ce.corr_from_structure(
                            Structure.from_dict(new_entry['relaxed_defromed']))
                except:
                    print("Entry {} too far from original lattice. Skipping.".
                          format(root))
                    open(os.path.join(root, 'failed'), 'a').close()
                    continue

                self.calcdata['compositions'][compstring].append(new_entry)
                open(os.path.join(root, 'accepted'), 'a').close()
                n_matched += 1
        # Data already deduplicated!

        print(
            '{}/{} structures matched in this run. Parsed vasp data will be saved into {}.'
            .format(n_matched, n_inputs, self.calc_data_file))