Пример #1
0
def generate_elastic_workflow(structure, tags=None):
    """
    Generates a standard production workflow.

    Notes:
        Uses a primitive structure transformed into
        the conventional basis (for equivalent deformations).

        Adds the "minimal" category to the minimal portion
        of the workflow necessary to generate the elastic tensor,
        and the "minimal_full_stencil" category to the portion that
        includes all of the strain stencil, but is symmetrically complete
    """
    if tags == None:
        tags = []
    # transform the structure
    ieee_rot = Tensor.get_ieee_rotation(structure)
    if not SquareTensor(ieee_rot).is_rotation(tol=0.005):
        raise ValueError(
            "Rotation matrix does not satisfy rotation conditions")
    symm_op = SymmOp.from_rotation_and_translation(ieee_rot)
    ieee_structure = structure.copy()
    ieee_structure.apply_operation(symm_op)

    # construct workflow
    wf = wf_elastic_constant(ieee_structure)

    # Set categories, starting with optimization
    opt_fws = get_fws_and_tasks(wf, fw_name_constraint="optimization")
    wf.fws[opt_fws[0][0]].spec['elastic_category'] = "minimal"

    # find minimal set of fireworks using symmetry reduction
    fws_by_strain = {
        Strain(fw.tasks[-1]['pass_dict']['strain']): n
        for n, fw in enumerate(wf.fws) if 'deformation' in fw.name
    }
    unique_tensors = symmetry_reduce(list(fws_by_strain.keys()),
                                     ieee_structure)
    for unique_tensor in unique_tensors:
        fw_index = get_tkd_value(fws_by_strain, unique_tensor)
        if np.isclose(unique_tensor, 0.005).any():
            wf.fws[fw_index].spec['elastic_category'] = "minimal"
        else:
            wf.fws[fw_index].spec['elastic_category'] = "minimal_full_stencil"

    # Add tags
    if tags:
        wf = add_tags(wf, tags)

    wf = add_modify_incar(wf)
    priority = 500 - structure.num_sites
    wf = add_priority(wf, priority)
    for fw in wf.fws:
        if fw.spec.get('elastic_category') == 'minimal':
            fw.spec['_priority'] += 2000
        elif fw.spec.get('elastic_category') == 'minimal_full_stencil':
            fw.spec['_priority'] += 1000
    return wf
Пример #2
0
    def setUp(self):
        super().setUp()
        self.tf_loc = os.path.join(ref_dir, "elastic_wf")
        self.struct_si = PymatgenTest.get_structure("Si")
        self.struct_si = SpacegroupAnalyzer(
            self.struct_si
        ).get_conventional_standard_structure()
        self.opt_struct = Structure.from_file(
            os.path.join(self.tf_loc, "1", "inputs", "POSCAR")
        )

        # Base WF
        self.base_wf = get_wf(
            self.struct_si, "optimize_only.yaml", params=[{"db_file": ">>db_file<<"}]
        )
        self.base_wf.append_wf(
            get_wf_elastic_constant(
                self.struct_si,
                db_file=">>db_file<<",
                stencils=[[0.01]] * 3 + [[0.03]] * 3,
                copy_vasp_outputs=True,
            ),
            self.base_wf.leaf_fw_ids,
        )
        self.base_wf_noopt = get_wf_elastic_constant(
            self.opt_struct,
            stencils=[[0.01]] * 3 + [[0.03]] * 3,
            copy_vasp_outputs=False,
            sym_reduce=False,
            db_file=">>db_file<<",
        )
        ec_incar_update = {"incar_update": {"EDIFF": 1e-6, "ENCUT": 700}}
        self.base_wf = add_modify_incar(self.base_wf, ec_incar_update)
        self.base_wf_noopt = add_modify_incar(self.base_wf_noopt, ec_incar_update)

        # Full preset WF
        self.preset_wf = wf_elastic_constant(self.struct_si)

        # Minimal WF
        self.minimal_wf = wf_elastic_constant_minimal(self.opt_struct)
        self.minimal_wf = add_modify_incar(self.minimal_wf, ec_incar_update)

        # TOEC WF (minimal)
        self.toec_wf = wf_elastic_constant_minimal(self.struct_si, order=3)
        self.toec_wf = add_modify_incar(self.toec_wf, ec_incar_update)
        toec_data = loadfn(os.path.join(self.tf_loc, "toec_data.json"))
        # Rather than run entire workflow, preload the spec to test the analysis
        toec_analysis = Firework(
            [
                ElasticTensorToDb(
                    structure=self.struct_si, order=3, db_file=">>db_file<<"
                )
            ],
            spec={"deformation_tasks": toec_data["deformation_tasks"]},
        )
        self.toec_analysis = Workflow([toec_analysis])
        # Check 4th order to see if constructed correctly
        self.foec_wf = wf_elastic_constant_minimal(self.struct_si, order=4)
    def setUpClass(cls):
        if not SETTINGS.get("VASP_PSP_DIR"):
            SETTINGS["VASP_PSP_DIR"] = os.path.join(module_dir, "..", "..", "tests", "reference_files")
            print('This system is not set up to run VASP jobs. '
                  'Please set VASP_PSP_DIR variable in your ~/.pmgrc.yaml file.')

        cls.struct_si = SpacegroupAnalyzer(
                PymatgenTest.get_structure("Si")).get_conventional_standard_structure()
        cls.scratch_dir = os.path.join(module_dir, "scratch")
        cls.elastic_config = {"norm_deformations":[0.01],
                              "shear_deformations":[0.03],
                              "vasp_cmd": ">>vasp_cmd<<", "db_file": ">>db_file<<"}
        cls.wf = wf_elastic_constant(cls.struct_si, cls.elastic_config)
Пример #4
0
    def setUp(self):
        super(TestElasticWorkflow, self).setUp()
        self.tf_loc = os.path.join(ref_dir, 'elastic_wf')
        self.struct_si = PymatgenTest.get_structure("Si")
        self.struct_si = SpacegroupAnalyzer(
            self.struct_si).get_conventional_standard_structure()
        self.opt_struct = Structure.from_file(
            os.path.join(self.tf_loc, '1', 'inputs', 'POSCAR'))

        # Base WF
        self.base_wf = get_wf(self.struct_si,
                              "optimize_only.yaml",
                              params=[{
                                  "db_file": ">>db_file<<"
                              }])
        self.base_wf.append_wf(
            get_wf_elastic_constant(self.struct_si,
                                    db_file='>>db_file<<',
                                    stencils=[[0.01]] * 3 + [[0.03]] * 3,
                                    copy_vasp_outputs=True),
            self.base_wf.leaf_fw_ids)
        self.base_wf_noopt = get_wf_elastic_constant(self.opt_struct,
                                                     stencils=[[0.01]] * 3 +
                                                     [[0.03]] * 3,
                                                     copy_vasp_outputs=False,
                                                     sym_reduce=False,
                                                     db_file='>>db_file<<')
        ec_incar_update = {'incar_update': {'EDIFF': 1e-6, 'ENCUT': 700}}
        self.base_wf = add_modify_incar(self.base_wf, ec_incar_update)
        self.base_wf_noopt = add_modify_incar(self.base_wf_noopt,
                                              ec_incar_update)

        # Full preset WF
        self.preset_wf = wf_elastic_constant(self.struct_si)

        # Minimal WF
        self.minimal_wf = wf_elastic_constant_minimal(self.opt_struct)
        self.minimal_wf = add_modify_incar(self.minimal_wf, ec_incar_update)

        # TOEC WF (minimal)
        self.toec_wf = wf_elastic_constant_minimal(self.struct_si, order=3)
        self.toec_wf = add_modify_incar(self.toec_wf, ec_incar_update)
        toec_data = loadfn(os.path.join(self.tf_loc, 'toec_data.json'))
        # Rather than run entire workflow, preload the spec to test the analysis
        toec_analysis = Firework(
            [
                ElasticTensorToDb(
                    structure=self.struct_si, order=3, db_file=">>db_file<<")
            ],
            spec={"deformation_tasks": toec_data['deformation_tasks']})
        self.toec_analysis = Workflow([toec_analysis])
Пример #5
0
    def setUp(self):
        super(TestElasticWorkflow, self).setUp()
        self.tf_loc = os.path.join(ref_dir, 'elastic_wf')
        self.struct_si = PymatgenTest.get_structure("Si")
        self.struct_si = SpacegroupAnalyzer(self.struct_si).get_conventional_standard_structure()
        self.opt_struct = Structure.from_file(os.path.join(self.tf_loc, '1', 'inputs', 'POSCAR'))

        # Base WF
        self.base_wf = get_wf(self.struct_si, "optimize_only.yaml",
                              params=[{"db_file": ">>db_file<<"}])
        self.base_wf.append_wf(get_wf_elastic_constant(self.struct_si, db_file='>>db_file<<',
                                                       stencils=[[0.01]]*3 + [[0.03]]*3,
                                                       copy_vasp_outputs=True),
                               self.base_wf.leaf_fw_ids)
        self.base_wf_noopt = get_wf_elastic_constant(self.opt_struct, stencils=[[0.01]]*3 + [[0.03]]*3,
                                                     copy_vasp_outputs=False, sym_reduce=False,
                                                     db_file='>>db_file<<')
        ec_incar_update = {'incar_update': {'EDIFF': 1e-6, 'ENCUT': 700}}
        self.base_wf = add_modify_incar(self.base_wf, ec_incar_update)
        self.base_wf_noopt = add_modify_incar(self.base_wf_noopt, ec_incar_update)

        # Full preset WF
        self.preset_wf = wf_elastic_constant(self.struct_si)

        # Minimal WF
        self.minimal_wf = wf_elastic_constant_minimal(self.opt_struct)
        self.minimal_wf = add_modify_incar(self.minimal_wf, ec_incar_update)

        # TOEC WF (minimal)
        self.toec_wf = wf_elastic_constant_minimal(self.struct_si, order=3) 
        self.toec_wf = add_modify_incar(self.toec_wf, ec_incar_update)
        toec_data = loadfn(os.path.join(self.tf_loc, 'toec_data.json'))
        # Rather than run entire workflow, preload the spec to test the analysis
        toec_analysis = Firework([ElasticTensorToDb(structure=self.struct_si, order=3, 
                                                    db_file=">>db_file<<")], 
                                 spec={"deformation_tasks": toec_data['deformation_tasks']})
        self.toec_analysis = Workflow([toec_analysis])
        # Check 4th order to see if constructed correctly
        self.foec_wf = wf_elastic_constant_minimal(self.struct_si, order=4)