def test_polarizationtodb(self): import bson import gzip reference_dir = os.path.abspath( os.path.join(ref_dir, "ferroelectric_wf")) with gzip.open(os.path.join(reference_dir, "tasks.bson.gz")) as f: coll_raw = f.read() coll = bson.decode_all(coll_raw) db = self.get_task_collection() for c in coll: db.insert(c) new_fw_spec = { '_fw_env': { "db_file": os.path.join(db_dir, "db.json") }, 'tags': ['wfid_1494203093.06934658'] } analysis = PolarizationToDb(db_file='>>db_file<<', name="_polarization_post_processing") analysis.run_task(new_fw_spec) # Check recovered change in polarization coll = self.get_task_collection("polarization_tasks") d = coll.find_one() self.assertAlmostEqual(d['polarization_change_norm'], 46.288752795325244)
def test_polarizationtodb(self): import bson import gzip reference_dir = os.path.abspath(os.path.join(ref_dir, "ferroelectric_wf")) with gzip.open(os.path.join(reference_dir, "tasks.bson.gz")) as f: coll_raw = f.read() coll = bson.decode_all(coll_raw) db = self.get_task_collection() for c in coll: db.insert(c) new_fw_spec = {'_fw_env': {"db_file": os.path.join(db_dir, "db.json")}, 'tags':['wfid_1494203093.06934658']} analysis = PolarizationToDb(db_file='>>db_file<<', name="_polarization_post_processing") analysis.run_task(new_fw_spec) # Check recovered change in polarization coll = self.get_task_collection("polarization_tasks") d = coll.find_one() self.assertAlmostEqual(d['polarization_change_norm'], 46.288752795325244, 5)
def get_wf_ferroelectric(polar_structure, nonpolar_structure, vasp_cmd="vasp", db_file=None, vasp_input_set_polar="MPStaticSet", vasp_input_set_nonpolar="MPStaticSet", relax=False, vasp_relax_input_set_polar=None, vasp_relax_input_set_nonpolar=None, nimages=9, hse=False, add_analysis_task=False, wfid=None, tags=None): """ Returns a workflow to calculate the spontaneous polarization of polar_structure using a nonpolar reference phase structure and linear interpolations between the polar and nonpolar structure. The nonpolar and polar structures must be in the same space group setting and atoms ordered such that a linear interpolation can be performed to create intermediate structures along the distortion. For example, to calculate the polarization of orthorhombic BaTiO3 (space group 38) using the cubic structure (space group 221) as the nonpolar reference phase, we must transform the cubic to the orthorhombic setting. This can be accomplished using Bilbao Crystallographic Server's Structure Relations tool. (http://www.cryst.ehu.es/cryst/rel.html) Args: polar_structure (Structure): polar structure of candidate ferroelectric nonpolar_structure (Structure): nonpolar reference structure in polar setting vasp_input_set_polar (DictVaspInputSet): VASP polar input set. Defaults to MPStaticSet. vasp_input_set_nonpolar (DictVaspInputSet): VASP nonpolar input set. Defaults to MPStaticSet. vasp_relax_input_set_polar (DictVaspInputSet): VASP polar input set. Defaults to MPRelaxSet. vasp_relax_input_set_nonpolar (DictVaspInputSet): VASP nonpolar input set. Defaults to MPRelaxSet. vasp_cmd (str): command to run db_file (str): path to file containing the database credentials. nimages: Number of interpolations calculated from polar to nonpolar structures, including the nonpolar. For example, nimages = 9 will calculate 8 interpolated structures. 8 interpolations + nonpolar = 9. add_analysis_task: Analyze polarization and energy trends as part of workflow. Default False. wfid (string): Unique worfklow id starting with "wfid_". If None this is atomatically generated (recommended). tags (list of strings): Additional tags to add such as identifiers for structures. Returns: """ wf = [] if wfid is None: wfid = 'wfid_' + get_a_unique_id() if tags is None: tags = [] if relax: polar_relax = OptimizeFW(structure=polar_structure, name="_polar_relaxation", vasp_cmd=vasp_cmd, db_file=db_file, vasp_input_set=vasp_relax_input_set_polar) nonpolar_relax = OptimizeFW( structure=nonpolar_structure, name="_nonpolar_relaxation", vasp_cmd=vasp_cmd, db_file=db_file, vasp_input_set=vasp_relax_input_set_nonpolar) wf.append(polar_relax) wf.append(nonpolar_relax) parents_polar = polar_relax parents_nonpolar = nonpolar_relax else: parents_polar = None parents_nonpolar = None # Run polarization calculation on polar structure. # Defuse workflow if polar structure is metallic. polar = LcalcpolFW(structure=polar_structure, name="_polar_polarization", static_name="_polar_static", parents=parents_polar, vasp_cmd=vasp_cmd, db_file=db_file, vasp_input_set=vasp_input_set_polar) # Run polarization calculation on nonpolar structure. # Defuse workflow if nonpolar structure is metallic. nonpolar = LcalcpolFW(structure=nonpolar_structure, name="_nonpolar_polarization", static_name="_nonpolar_static", parents=parents_nonpolar, vasp_cmd=vasp_cmd, db_file=db_file, vasp_input_set=vasp_input_set_nonpolar) # Interpolation polarization interpolation = [] # Interpolations start from one increment after polar and end prior to nonpolar. # The Structure.interpolate method adds an additional image for the nonpolar endpoint. # Defuse children fireworks if metallic. for i in range(1, nimages): # nonpolar_structure is being used as a dummy structure. # The structure will be replaced by the interpolated structure generated by # StaticInterpolatedFW. # Defuse workflow if interpolated structure is metallic. interpolation.append( LcalcpolFW(structure=polar_structure, name="_interpolation_{}_polarization".format(str(i)), static_name="_interpolation_{}_static".format(str(i)), vasp_cmd=vasp_cmd, db_file=db_file, vasp_input_set=vasp_input_set_polar, interpolate=True, start="_polar_static", end="_nonpolar_static", nimages=nimages, this_image=i, parents=[polar, nonpolar])) wf.append(polar) wf.append(nonpolar) wf += interpolation # Add FireTask that uses Polarization object to store spontaneous polarization information if add_analysis_task: fw_analysis = Firework(PolarizationToDb(db_file=db_file), parents=interpolation, name="_polarization_post_processing") wf.append(fw_analysis) # Run HSE band gap calculation if hse: # Run HSE calculation at band gap for polar calculation if polar structure is not metallic hse = HSEBSFW(structure=polar_structure, parents=polar, name="_polar_hse_gap", vasp_cmd=vasp_cmd, db_file=db_file, calc_loc="_polar_polarization") wf.append(hse) # Create Workflow task and add tags to workflow workflow = Workflow(wf) workflow = add_tags(workflow, [wfid] + tags) return workflow