def build_model(self, model, **kwargs): """ Adds the subset model to the parent model. Parameters ---------- model : DataModelDict.DataModelDict The record content (after root element) to add content to. kwargs : any Any options to pass on to dict_insert that specify where the subset content gets added to in the parent model. """ # Check that one of the tolerances is set if self.energytolerance == 0.0 and self.forcetolerance == 0.0: raise ValueError('energytolerance and forcetolerance cannot both be 0.0') # Build paths if needed if 'calculation' not in model: model['calculation'] = DM() if 'run-parameter' not in model['calculation']: model['calculation']['run-parameter'] = DM() # Save values run_params = model['calculation']['run-parameter'] run_params[f'{self.modelprefix}energytolerance'] = self.energytolerance run_params[f'{self.modelprefix}forcetolerance'] = uc.model(self.forcetolerance, self.parent.units.force_unit) run_params[f'{self.modelprefix}maxiterations'] = self.maxiterations run_params[f'{self.modelprefix}maxevaluations'] = self.maxevaluations run_params[f'{self.modelprefix}maxatommotion'] = uc.model(self.maxatommotion, self.parent.units.length_unit)
def build_model(self): """ Generates and returns model content based on the values set to object. """ # Build universal content model = super().build_model() calc = model[self.modelroot] # Build subset content self.commands.build_model(calc, after='atomman-version') self.potential.build_model(calc, after='calculation') self.system.build_model(calc, after='potential-LAMMPS') self.defect.build_model(calc, after='system-info') self.minimize.build_model(calc) self.elastic.build_model(calc) # Build calculation-specific content if 'calculation' not in calc: calc['calculation'] = DM() if 'run-parameter' not in calc['calculation']: calc['calculation']['run-parameter'] = DM() run_params = calc['calculation']['run-parameter'] run_params['dislocation_boundaryshape'] = self.boundaryshape run_params['dislocation_boundarywidth'] = self.boundarywidth run_params['dislocation_boundaryscale'] = self.boundaryscale run_params['annealtemperature'] = self.annealtemperature run_params['annealsteps'] = self.annealsteps # Build results if self.status == 'finished': calc['base-system'] = DM() calc['base-system']['artifact'] = DM() calc['base-system']['artifact']['file'] = self.dumpfile_base calc['base-system']['artifact']['format'] = 'atom_dump' calc['base-system']['symbols'] = self.symbols_base calc['defect-system'] = DM() calc['defect-system']['artifact'] = DM() calc['defect-system']['artifact']['file'] = self.dumpfile_defect calc['defect-system']['artifact']['format'] = 'atom_dump' calc['defect-system']['symbols'] = self.symbols_defect calc['defect-system']['potential-energy'] = uc.model( self.potential_energy_defect, self.units.energy_unit) calc['elastic-solution'] = elsol = DM() elsol['pre-ln-factor'] = uc.model( self.preln, f"{self.units.energy_unit}/{self.units.length_unit}") elsol['K-tensor'] = uc.model(self.K_tensor, self.units.pressure_unit) self._set_model(model) return model
def model(self, length_unit='Å', energyperarea_unit='eV/Å^2', pressure_unit='GPa', include_gamma=False): """ Generate a data model for the object. Parameters ---------- length_unit : str, optional The unit of length to save values as. Default is 'Å'. energyperarea_unit : str, optional The unit of energy per area to save fault energy values as. Only used if the gamma surface information is included. Default value is 'eV/Å^2'. pressure_unit : str, optional The unit of pressure to save values as. Default is 'GPa'. include_gamma : bool, optional Flag indicating if the gamma surface data is to be included. Default value is False. Returns ------- DataModelDict The data model containing all input parameters and the current disregistry vectors. """ model = DM() model['semidiscrete-variational-Peierls-Nabarro'] = sdpn = DM() sdpn['parameter'] = params = DM() params['transform'] = uc.model(self.transform, None) params['K_tensor'] = uc.model(self.K_tensor, pressure_unit) params['tau'] = uc.model(self.tau, pressure_unit) params['alpha'] = uc.model(self.alpha, pressure_unit + '/' + length_unit) params['beta'] = uc.model(self.beta, pressure_unit + '*' + length_unit) params['cdiffelastic'] = self.cdiffelastic params['cdiffsurface'] = self.cdiffsurface params['cdiffstress'] = self.cdiffstress params['cutofflongrange'] = uc.model(self.cutofflongrange, length_unit) params['burgers'] = uc.model(self.burgers, length_unit) params['fullstress'] = self.fullstress params['min_method'] = self.min_method params['min_options'] = self.min_options if len(self.min_kwargs) > 0: params['min_kwargs'] = self.min_kwargs if include_gamma is True: sdpn['generalized-stacking-fault'] = self.gamma.model( length_unit=length_unit, energyperarea_unit=energyperarea_unit) sdpn['solution'] = solution = DM() solution['x'] = uc.model(self.x, length_unit) solution['disregistry'] = uc.model(self.disregistry, length_unit) return model
def build_model(self): """ Generates and returns model content based on the values set to object. """ # Build universal content model = super().build_model() calc = model[self.modelroot] # Build subset content self.commands.build_model(calc, after='atomman-version') self.potential.build_model(calc, after='calculation') self.system.build_model(calc, after='potential-LAMMPS') self.defect.build_model(calc, after='system-info') self.minimize.build_model(calc) # Build calculation-specific content if 'calculation' not in calc: calc['calculation'] = DM() if 'run-parameter' not in calc['calculation']: calc['calculation']['run-parameter'] = DM() run_params = calc['calculation']['run-parameter'] run_params['stackingfault_a1'] = self.a1 run_params['stackingfault_a2'] = self.a2 # Build results if self.status == 'finished': calc['defect-free-system'] = DM() calc['defect-free-system']['artifact'] = DM() calc['defect-free-system']['artifact']['file'] = self.dumpfile_base calc['defect-free-system']['artifact']['format'] = 'atom_dump' calc['defect-free-system']['symbols'] = self.system.ucell.symbols calc['defect-free-system']['potential-energy'] = uc.model( self.potential_energy_base, self.units.energy_unit) calc['defect-system'] = DM() calc['defect-system']['artifact'] = DM() calc['defect-system']['artifact']['file'] = self.dumpfile_defect calc['defect-system']['artifact']['format'] = 'atom_dump' calc['defect-system']['symbols'] = self.system.ucell.symbols calc['defect-system']['potential-energy'] = uc.model( self.potential_energy_defect, self.units.energy_unit) # Save the stacking fault energy energy_per_area_unit = f'{self.units.energy_unit}/{self.units.length_unit}^2' calc['stacking-fault-energy'] = uc.model(self.gsf_energy, energy_per_area_unit) # Save the plane separation calc['plane-separation'] = uc.model(self.gsf_displacement, self.units.length_unit) self._set_model(model) return model
def build_model(self): """ Generates and returns model content based on the values set to object. """ # Build universal content model = super().build_model() calc = model[self.modelroot] # Build subset content self.commands.build_model(calc, after='atomman-version') self.potential.build_model(calc, after='calculation') self.system.build_model(calc, after='potential-LAMMPS') self.system_mods.build_model(calc) self.defect.build_model(calc, after='system-info') self.minimize.build_model(calc) # Build results if self.status == 'finished': calc['defect-free-system'] = DM() calc['defect-free-system']['artifact'] = DM() calc['defect-free-system']['artifact']['file'] = self.dumpfile_base calc['defect-free-system']['artifact']['format'] = 'atom_dump' calc['defect-free-system']['symbols'] = self.symbols_base calc['defect-free-system']['potential-energy'] = uc.model( self.potential_energy_base, self.units.energy_unit) calc['defect-system'] = DM() calc['defect-system']['artifact'] = DM() calc['defect-system']['artifact']['file'] = self.dumpfile_defect calc['defect-system']['artifact']['format'] = 'atom_dump' calc['defect-system']['symbols'] = self.symbols_defect calc['defect-system']['potential-energy'] = uc.model( self.potential_energy_defect, self.units.energy_unit) # Save the calculation results calc['cohesive-energy'] = uc.model(self.potential_energy, self.units.energy_unit) calc['number-of-atoms'] = self.natoms_defect calc['defect-formation-energy'] = uc.model(self.formation_energy, self.units.energy_unit) calc['defect-elastic-dipole-tensor'] = uc.model( self.dipole_tensor, self.units.energy_unit) # Save the reconfiguration checks calc['reconfiguration-check'] = r_c = DM() r_c['has_reconfigured'] = self.has_reconfigured r_c['centrosummation'] = self.centrosummation.tolist() if self.__position_shift is not None: r_c['position_shift'] = self.position_shift.tolist() if self.__db_vect_shift is not None: r_c['db_vect_shift'] = self.db_vect_shift.tolist() self._set_model(model) return model
def buildcontent(self, script, input_dict, results_dict=None): """ Builds a data model of the specified record style based on input (and results) parameters. Parameters ---------- script : str The name of the calculation script used. input_dict : dict Dictionary of all input parameter terms. results_dict : dict, optional Dictionary containing any results produced by the calculation. Returns ------- DataModelDict Data model consistent with the record's schema format. Raises ------ AttributeError If buildcontent is not defined for record style. """ # Build universal content super().buildcontent(script, input_dict, results_dict=results_dict) # Load content after root calc = self.content[self.contentroot] # Assign calculation-specific run parameters calc['calculation']['run-parameter'] = run_params = DM() run_params['minimum_r'] = uc.model(input_dict['minimum_r'], input_dict['length_unit']) run_params['maximum_r'] = uc.model(input_dict['maximum_r'], input_dict['length_unit']) run_params['number_of_steps_r'] = input_dict['number_of_steps_r'] # Copy over potential data model info subset('lammps_potential').buildcontent(calc, input_dict, results_dict=results_dict) # Save info on system file loaded calc['system-info'] = DM() calc['system-info']['symbol'] = input_dict['symbols'] # Save results if results_dict is None: calc['status'] = 'not calculated' else: calc['diatom-energy-relation'] = DM() calc['diatom-energy-relation']['r'] = uc.model(results_dict['r_values'], input_dict['length_unit']) calc['diatom-energy-relation']['potential-energy'] = uc.model(results_dict['energy_values'], input_dict['energy_unit'])
def buildcontent(self, input_dict): """ Builds a data model of the specified record style based on input (and results) parameters. Parameters ---------- input_dict : dict Dictionary of all input parameter terms. Returns ------- DataModelDict Data model consistent with the record's schema format. Raises ------ AttributeError If buildcontent is not defined for record style. """ # Create the root of the DataModelDict output = DM() output[self.contentroot] = crystal = DM() # Assign uuid crystal['key'] = input_dict['key'] # Specify source method crystal['method'] = input_dict['method'] crystal['standing'] = input_dict.get('standing', 'good') # Copy over potential data model info subset('lammps_potential').buildcontent(crystal, input_dict) # Save info on system files loaded crystal['system-info'] = DM() crystal['system-info']['family'] = input_dict['family'] crystal['system-info']['parent_key'] = input_dict['parent_key'] system_model = input_dict['ucell'].dump('system_model', box_unit=input_dict['length_unit']) crystal['atomic-system'] = system_model['atomic-system'] # Save potential and cohesive energy values crystal['potential-energy'] = uc.model(input_dict['E_pot'], input_dict['energy_unit']) crystal['cohesive-energy'] = uc.model(input_dict['E_coh'], input_dict['energy_unit']) self.content = output
def test_scalar_model(self): unit = 'mJ/s^2' v = 1234.214 value = uc.set_in_units(v, unit) model = uc.model(value, unit) value2 = uc.value_unit(model) assert pytest.approx(value, value2)
def test_vector_model(self): unit = 'mJ/s^2' v = np.array([1234.214, 346.23]) value = uc.set_in_units(v, unit) model = uc.model(value, unit) value2 = uc.value_unit(model) assert np.allclose(value, value2)
def test_tensor_model(self): unit = 'mJ/s^2' v = np.array([[1234.214, 346.23], [109.124, 235.781]]) value = uc.set_in_units(v, unit) model = uc.model(value, unit) value2 = uc.value_unit(model) assert np.allclose(value, value2)
def model(self, prop_name=None, unit=None, prop_unit=None): """ Generates a data model for the Atoms object. Parameters ---------- prop_name : list, optional The Atoms properties to include. If neither prop_name nor prop_unit are given, all system properties will be included. unit : list, optional Lists the units for each prop_name as stored in the table. For a value of None, no conversion will be performed for that property. If neither unit nor prop_units given, pos will be given in Angstroms and all other values will not be converted. prop_unit : dict, optional dictionary where the keys are the property keys to include, and the values are units to use. If neither unit nor prop_units given, pos will be given in Angstroms and all other values will not be converted. Returns ------- DataModelDict.DataModelDict A JSON/XML data model for the current Atoms object. """ # Set prop_unit if needed if prop_unit is None: if prop_name is None: prop_name = self.prop() if unit is None: unit = [None for i in range(len(prop_name))] if len(unit) != len(prop_name): raise ValueError('') prop_unit = {} for p, u in zip(prop_name, unit): prop_unit[p] = u elif prop_name is not None or unit is not None: raise ValueError( 'prop_unit cannot be given with prop_name or unit') # Set default pos unit if 'pos' in prop_unit and prop_unit['pos'] is None: prop_unit['pos'] = 'angstrom' # Generate DataModelDict model = DM() model['atoms'] = DM() model['atoms']['natoms'] = self.natoms for prop in prop_unit: unit = prop_unit.get(prop, None) propmodel = DM() propmodel['name'] = prop propmodel['data'] = uc.model(self.prop(prop), unit) model['atoms'].append('property', propmodel) return model
def buildcontent(self, record_model, input_dict, results_dict=None): """ Converts the structured content to a simpler dictionary. Parameters ---------- record_model : DataModelDict.DataModelDict The record content (after root element) to add content to. input_dict : dict Dictionary of all input parameter terms. results_dict : dict, optional Dictionary containing any results produced by the calculation. """ # Set prefixes prefix = self.prefix modelprefix = prefix.replace('_', '-') # Extract values keymap = self.keymap force_unit = input_dict.get(keymap['force_unit'], input_dict['force_unit']) length_unit = input_dict.get(keymap['length_unit'], input_dict['length_unit']) etol = input_dict[keymap['energytolerance']] ftol = input_dict[keymap['forcetolerance']] maxiter = input_dict[keymap['maxiterations']] maxeval = input_dict[keymap['maxevaluations']] dmax = input_dict[keymap['maxatommotion']] # Build paths if needed if 'calculation' not in record_model: record_model['calculation'] = DM() if 'run-parameter' not in record_model['calculation']: record_model['calculation']['run-parameter'] = DM() run_params = record_model['calculation']['run-parameter'] # Save values run_params[f'{modelprefix}energytolerance'] = etol run_params[f'{modelprefix}forcetolerance'] = uc.model( ftol, f'{force_unit}') run_params[f'{modelprefix}maxiterations'] = maxiter run_params[f'{modelprefix}maxevaluations'] = maxeval run_params[f'{modelprefix}maxatommotion'] = uc.model(dmax, length_unit)
def build_model(self): """ Generates and returns model content based on the values set to object. """ # Build universal content model = super().build_model() calc = model[self.modelroot] # Build subset content self.commands.build_model(calc, after='atomman-version') self.potential.build_model(calc, after='calculation') self.system.build_model(calc, after='potential-LAMMPS') self.defect.build_model(calc, after='system-info') self.minimize.build_model(calc) # Build results if self.status == 'finished': calc['defect-free-system'] = DM() calc['defect-free-system']['artifact'] = DM() calc['defect-free-system']['artifact']['file'] = self.dumpfile_base calc['defect-free-system']['artifact']['format'] = 'atom_dump' calc['defect-free-system']['symbols'] = self.system.ucell.symbols calc['defect-free-system']['potential-energy'] = uc.model(self.potential_energy_base, self.units.energy_unit) calc['defect-system'] = DM() calc['defect-system']['artifact'] = DM() calc['defect-system']['artifact']['file'] = self.dumpfile_defect calc['defect-system']['artifact']['format'] = 'atom_dump' calc['defect-system']['symbols'] = self.system.ucell.symbols calc['defect-system']['potential-energy'] = uc.model(self.potential_energy_defect, self.units.energy_unit) # Save the cohesive energy calc['cohesive-energy'] = uc.model(self.potential_energy, self.units.energy_unit) # Save the free surface energy energy_per_area_unit = f'{self.units.energy_unit}/{self.units.length_unit}^2' calc['free-surface-energy'] = uc.model(self.surface_energy, energy_per_area_unit) self._set_model(model) return model
def build_model(self): """ Generates and returns model content based on the values set to object. """ if len(self.symbols) is None: raise ValueError('symbols not set') # Build universal content model = super().build_model() calc = model[self.modelroot] # Build subset content self.commands.build_model(calc, after='atomman-version') self.potential.build_model(calc, after='calculation') # Build calculation-specific content if 'calculation' not in calc: calc['calculation'] = DM() if 'run-parameter' not in calc['calculation']: calc['calculation']['run-parameter'] = DM() calc['calculation']['run-parameter'] = run_params = DM() run_params['minimum_r'] = uc.model(self.minimum_r, self.units.length_unit) run_params['maximum_r'] = uc.model(self.maximum_r, self.units.length_unit) run_params['number_of_steps_r'] = self.number_of_steps_r run_params['minimum_theta'] = self.minimum_theta run_params['maximum_theta'] = self.maximum_theta run_params['number_of_steps_theta'] = self.number_of_steps_theta dict_insert(calc, 'system-info', DM(), after='potential-LAMMPS') calc['system-info']['symbol'] = self.symbols # Build results if self.status == 'finished': calc['results'] = results = DM() results['file'] = self.results_file results['length_unit'] = self.results_length_unit results['energy_unit'] = self.results_energy_unit self._set_model(model) return model
def model(self, length_unit='angstrom', energy_unit='eV', pressure_unit='GPa', include_gamma=False): """ Generate a data model for the object. Parameters ---------- length_unit : str The unit of length to save values as. Default is 'angstrom'. energy_unit : str The unit of energy to save values as. Default is 'eV'. pressure_unit : str The unit of pressure to save values as. Default is 'GPa'. include_gamma : bool Flag indicating if the gamma surface data is to be included. Default value is False. """ model = DM() model['semidiscrete-variational-Peierls-Nabarro'] = sdpn = DM() sdpn['parameter'] = params = DM() params['axes'] = uc.model(self.__axes, None) params['K_tensor'] = uc.model(self.__K_tensor, pressure_unit) params['tau'] = uc.model(self.__tau, pressure_unit) params['alpha'] = uc.model(self.__alpha, pressure_unit+'/'+length_unit) params['beta'] = uc.model(self.__beta, pressure_unit+'*'+length_unit) params['cdiffelastic'] = self.cdiffelastic params['cdiffsurface'] = self.cdiffsurface params['cdiffstress'] = self.cdiffstress params['cutofflongrange'] = uc.model(self.__cutofflongrange, length_unit) params['burgers'] = uc.model(self.__burgers, length_unit) params['fullstress'] = self.fullstress params['min_method'] = self.min_method params['min_options'] = self.min_options if include_gamma is True: sdpn['generalized-stacking-fault'] = self.__gamma.model( length_unit=length_unit, energy_unit=energy_unit, pressure_unit=pressure_unit) sdpn['solution'] = solution = DM() solution['x'] = uc.model(self.__x, length_unit) solution['disregistry'] = uc.model(self.__disregistry, length_unit) return model
def model(self, length_unit='angstrom', energy_unit='eV', pressure_unit='GPa', include_gamma=False): """ Generate a data model for the object. Parameters ---------- length_unit : str The unit of length to save values as. Default is 'angstrom'. energy_unit : str The unit of energy to save values as. Default is 'eV'. pressure_unit : str The unit of pressure to save values as. Default is 'GPa'. include_gamma : bool Flag indicating if the gamma surface data is to be included. Default value is False. """ model = DM() model['semidiscrete-variational-Peierls-Nabarro'] = sdpn = DM() sdpn['parameter'] = params = DM() params['axes'] = uc.model(self.__axes, None) params['K_tensor'] = uc.model(self.__K_tensor, pressure_unit) params['tau'] = uc.model(self.__tau, pressure_unit) params['alpha'] = uc.model(self.__alpha, pressure_unit+'/'+length_unit) params['beta'] = uc.model(self.__beta, pressure_unit+'*'+length_unit) params['cdiffelastic'] = self.cdiffelastic params['cdiffsurface'] = self.cdiffsurface params['cdiffstress'] = self.cdiffstress params['cutofflongrange'] = uc.model(self.__cutofflongrange, length_unit) params['burgers'] = uc.model(self.__burgers, length_unit) params['fullstress'] = self.fullstress params['min_method'] = self.min_method params['min_options'] = self.min_options if include_gamma is True: sdpn['generalized-stacking-fault'] = self.__gamma.model( length_unit=length_unit, energy_unit=energy_unit, pressure_unit=pressure_unit) sdpn['solution'] = solution = DM() solution['x'] = uc.model(self.__x, length_unit) solution['disregistry'] = uc.model(self.__disregistry, length_unit) return model
def build_model(self): """ Generates and returns model content based on the values set to object. """ # Build universal content model = super().build_model() calc = model[self.modelroot] # Build subset content self.commands.build_model(calc, after='atomman-version') self.potential.build_model(calc, after='calculation') self.system.build_model(calc, after='potential-LAMMPS') self.system_mods.build_model(calc) # Build calculation-specific content if 'calculation' not in calc: calc['calculation'] = DM() if 'run-parameter' not in calc['calculation']: calc['calculation']['run-parameter'] = DM() run_params = calc['calculation']['run-parameter'] run_params['minimum_r'] = uc.model(self.minimum_r, self.units.length_unit) run_params['maximum_r'] = uc.model(self.maximum_r, self.units.length_unit) run_params['number_of_steps_r'] = self.number_of_steps_r # Build results if self.status == 'finished': calc['cohesive-energy-relation'] = scan = DM() scan['r'] = uc.model(self.r_values, self.units.length_unit) scan['a'] = uc.model(self.a_values, self.units.length_unit) scan['cohesive-energy'] = uc.model(self.energy_values, self.units.energy_unit) for cell in self.min_cells: system_model = cell.dump('system_model', box_unit=self.units.length_unit) calc.append('minimum-atomic-system', system_model['atomic-system']) self._set_model(model) return model
def buildcontent(self, script, input_dict, results_dict=None): """ Builds a data model of the specified record style based on input (and results) parameters. Parameters ---------- script : str The name of the calculation script used. input_dict : dict Dictionary of all input parameter terms. results_dict : dict, optional Dictionary containing any results produced by the calculation. Returns ------- DataModelDict Data model consistent with the record's schema format. Raises ------ AttributeError If buildcontent is not defined for record style. """ # Build universal content super().buildcontent(script, input_dict, results_dict=results_dict) # Load content after root calc = self.content[self.contentroot] calc['calculation']['run-parameter'] = run_params = DM() # Copy over sizemults (rotations and shifts) subset('atomman_systemmanipulate').buildcontent( calc, input_dict, results_dict=results_dict) run_params['displacementdistance'] = uc.model( input_dict['displacementdistance'], input_dict['length_unit']) run_params['symmetryprecision'] = input_dict['symmetryprecision'] # Copy over potential data model info subset('lammps_potential').buildcontent(calc, input_dict, results_dict=results_dict) # Save info on system file loaded subset('atomman_systemload').buildcontent(calc, input_dict, results_dict=results_dict) if results_dict is None: calc['status'] = 'not calculated' else: pass
def build_model(self): """ Generates and returns model content based on the values set to object. """ # Build universal content model = super().build_model() calc = model[self.modelroot] # Build subset content self.commands.build_model(calc, after='atomman-version') self.potential.build_model(calc, after='calculation') self.system.build_model(calc, after='potential-LAMMPS') self.system_mods.build_model(calc) self.minimize.build_model(calc) # Build calculation-specific content if 'calculation' not in calc: calc['calculation'] = DM() if 'run-parameter' not in calc['calculation']: calc['calculation']['run-parameter'] = DM() run_params = calc['calculation']['run-parameter'] run_params['strain-range'] = self.strainrange # Build results if self.status == 'finished': cij = DM() cij['Cij'] = uc.model(self.raw_Cij_negative, self.units.pressure_unit) calc.append('raw-elastic-constants', cij) cij = DM() cij['Cij'] = uc.model(self.raw_Cij_positive, self.units.pressure_unit) calc.append('raw-elastic-constants', cij) calc['elastic-constants'] = DM() calc['elastic-constants']['Cij'] = uc.model(self.C.Cij, self.units.pressure_unit) self._set_model(model) return model
def model(self, model=None, length_unit='angstrom'): """ Reads or generates a data model for the box. Parameters ---------- model : str or DataModelDict, optional JSON/XML formatted data, or path to file containing said data. If not given, then a model for the current box will be returned. length_unit : str, optional Unit of length to save box values in if data model is to be generated. Default value is 'angstrom'. Returns ------- DataModelDict.DataModelDict A JSON/XML equivalent data model for the box. Returned if model is not given """ # Set values if model given if model is not None: # Find box element model = DM(model).find('box') avect = uc.value_unit(model['avect']) bvect = uc.value_unit(model['bvect']) cvect = uc.value_unit(model['cvect']) origin = uc.value_unit(model['origin']) self.set(avect=avect, bvect=bvect, cvect=cvect, origin=origin) # Return DataModelDict if model not given else: model = DM() model['box'] = DM() model['box']['avect'] = uc.model(self.avect, length_unit) model['box']['bvect'] = uc.model(self.bvect, length_unit) model['box']['cvect'] = uc.model(self.cvect, length_unit) model['box']['origin']= uc.model(self.origin, length_unit) return model
def build_model(self, model, **kwargs): """ Adds the subset model to the parent model. Parameters ---------- model : DataModelDict.DataModelDict The record content (after root element) to add content to. kwargs : any Any options to pass on to dict_insert that specify where the subset content gets added to in the parent model. """ # Save defect parameters model[self.modelroot] = surf = DM() surf['key'] = self.key surf['id'] = self.id surf['system-family'] = self.family surf['calculation-parameter'] = cp = DM() if len(self.hkl) == 3: cp['hkl'] = f'{self.hkl[0]} {self.hkl[1]} {self.hkl[2]}' else: cp['hkl'] = f'{self.hkl[0]} {self.hkl[1]} {self.hkl[2]} {self.hkl[3]}' cp['shiftindex'] = str(self.shiftindex) if len(self.a1vect_uvw) == 3: cp['a1vect_uvw'] = f'{self.a1vect_uvw[0]} {self.a1vect_uvw[1]} {self.a1vect_uvw[2]}' else: cp['a1vect_uvw'] = f'{self.a1vect_uvw[0]} {self.a1vect_uvw[1]} {self.a1vect_uvw[2]} {self.a1vect_uvw[3]}' if len(self.a2vect_uvw) == 3: cp['a2vect_uvw'] = f'{self.a2vect_uvw[0]} {self.a2vect_uvw[1]} {self.a2vect_uvw[2]}' else: cp['a2vect_uvw'] = f'{self.a2vect_uvw[0]} {self.a2vect_uvw[1]} {self.a2vect_uvw[2]} {self.a2vect_uvw[3]}' cp['cutboxvector'] = self.cutboxvector cp['faultpos_rel'] = str(self.faultpos_rel) cp['cellsetting'] = self.cellsetting # Build paths if needed if 'calculation' not in model: model['calculation'] = DM() if 'run-parameter' not in model['calculation']: model['calculation']['run-parameter'] = DM() run_params = model['calculation']['run-parameter'] run_params[f'{self.modelprefix}size-multipliers'] = DM() run_params[f'{self.modelprefix}size-multipliers']['a'] = sorted( [0, self.sizemults[0]]) run_params[f'{self.modelprefix}size-multipliers']['b'] = sorted( [0, self.sizemults[1]]) run_params[f'{self.modelprefix}size-multipliers']['c'] = sorted( [0, self.sizemults[2]]) run_params[f'{self.modelprefix}minimum-width'] = uc.model( self.minwidth, self.parent.units.length_unit)
def build_model(self, length_unit='angstrom', energyperarea_unit='mJ/m^2', stress_unit='GPa'): sp = DM() sp['direction'] = self.direction if self.error is None: sp['minimum-energy-path'] = uc.model(self.coord, length_unit) sp['unstable-fault-energy-mep'] = uc.model(self.usf_mep, energyperarea_unit) sp['unstable-fault-energy-unrelaxed-path'] = uc.model( self.usf_urp, energyperarea_unit) sp['ideal-shear-stress-mep'] = uc.model(self.shear_mep, stress_unit) sp['ideal-shear-stress-unrelaxed-path'] = uc.model( self.shear_urp, stress_unit) else: sp['error'] = self.error return sp
def model(self, model=None, unit=None, crystal_system='triclinic'): """ Return or set DataModelDict representation of the elastic constants. Parameters ---------- model : DataModelDict, string, or file-like object, optional Data model containing exactly one 'elastic-constants' branch to read. unit : str, optional Units or pressure to save values in when building a data model. Default value is None (no conversion). crystal_system : str, optional Indicates the crystal system representation to normalize by. Default value is 'triclinic', i.e. no normalization. Returns ------- DataModelDict If model is not given as a parameter. """ # Set values if model given if model is not None: # Find elastic-constants element model = DM(model).find('elastic-constants') # Read in values try: # New format self.Cij = uc.value_unit(model['Cij']) except: # Old format c_dict = {} for C in model['C']: key = 'C' + C['ij'][0] + C['ij'][2] c_dict[key] = uc.value_unit(C['stiffness']) self.Cij = ElasticConstants(**c_dict).Cij # Return DataModelDict if model not given else: normCij = self.normalized_as(crystal_system).Cij model = DM() model['elastic-constants'] = DM() model['elastic-constants']['Cij'] = uc.model(normCij, unit) return model
def model(self, model=None, unit=None, crystal_system='triclinic'): """ Return or set DataModelDict representation of the elastic constants. Parameters ---------- model : DataModelDict, string, or file-like object, optional Data model containing exactly one 'elastic-constants' branch to read. unit : str, optional Units or pressure to save values in when building a data model. Default value is None (no conversion). crystal_system : str, optional Indicates the crystal system representation to normalize by. Default value is 'triclinic', i.e. no normalization. Returns ------- DataModelDict If model is not given as a parameter. """ # Set values if model given if model is not None: # Find elastic-constants element model = DM(model).find('elastic-constants') # Read in values try: # New format self.Cij = uc.value_unit(model['Cij']) except: # Old format c_dict = {} for C in model['C']: key = 'C' + C['ij'][0] + C['ij'][2] c_dict[key] = uc.value_unit(C['stiffness']) self.Cij = ElasticConstants(**c_dict).Cij # Return DataModelDict if model not given else: normCij = self.normalized_as(crystal_system).Cij model = DM() model['elastic-constants'] = DM() model['elastic-constants']['Cij'] = uc.model(normCij, unit) return model
def buildcontent(self, input_dict, results_dict=None): """ Builds a data model of the specified record style based on input (and results) parameters. Parameters ---------- input_dict : dict Dictionary of all input parameter terms. results_dict : dict, optional Dictionary containing any results produced by the calculation. Returns ------- DataModelDict Data model consistent with the record's schema format. Raises ------ AttributeError If buildcontent is not defined for record style. """ # Build universal content super().buildcontent(input_dict, results_dict=results_dict) # Load content after root calc = self.content[self.contentroot] # Copy over potential data model info subset('lammps_potential').buildcontent(calc, input_dict, results_dict=results_dict) # Save results if results_dict is None: calc['status'] = 'not calculated' else: for symbol in results_dict['energy']: value = DM() value['symbol'] = symbol value['energy'] = uc.model(results_dict['energy'][symbol], input_dict['energy_unit']) calc.append('isolated-atom-energy', value)
def build_model(self): """ Generates and returns model content based on the values set to object. """ # Build universal content model = super().build_model() calc = model[self.modelroot] # Build subset content self.commands.build_model(calc, after='atomman-version') self.potential.build_model(calc, after='calculation') self.system.build_model(calc, after='potential-LAMMPS') # Build results if self.status == 'finished': # Save the final cohesive energy calc['potential-energy'] = uc.model(self.potential_energy, self.units.energy_unit, None) self._set_model(model) return model
def build_model(self): """ Generates and returns model content based on the values set to object. """ # Build universal content model = super().build_model() calc = model[self.modelroot] # Build subset content self.commands.build_model(calc, after='atomman-version') self.potential.build_model(calc, after='calculation') # Build calculation-specific content # Build results if self.status == 'finished': for symbol, energy in self.isolated_atom_energy.items(): isoatom = DM() isoatom['symbol'] = symbol isoatom['energy'] = uc.model(energy, self.units.energy_unit) calc.append('isolated-atom-energy', isoatom) self._set_model(model) return model
def buildcontent(self, script, input_dict, results_dict=None): """ Builds a data model of the specified record style based on input (and results) parameters. Parameters ---------- script : str The name of the calculation script used. input_dict : dict Dictionary of all input parameter terms. results_dict : dict, optional Dictionary containing any results produced by the calculation. Returns ------- DataModelDict Data model consistent with the record's schema format. Raises ------ AttributeError If buildcontent is not defined for record style. """ # Create the root of the DataModelDict output = DM() output[self.contentroot] = calc = DM() # Assign uuid calc['key'] = input_dict['calc_key'] # Save calculation parameters calc['calculation'] = DM() calc['calculation']['iprPy-version'] = iprPy_version calc['calculation']['atomman-version'] = am.__version__ calc['calculation']['script'] = script calc['calculation']['run-parameter'] = run_params = DM() run_params['halfwidth'] = uc.model(input_dict['halfwidth'], input_dict['length_unit']) x = pn_arctan_disregistry(xmax=input_dict['xmax'], xnum=input_dict['xnum'], xstep=input_dict['xstep'])[0] run_params['xmax'] = x.max() run_params['xnum'] = len(x) run_params['xstep'] = x[1]-x[0] run_params['min_cycles'] = input_dict['minimize_numcycles'] # Save info on system file loaded calc['system-info'] = DM() calc['system-info']['family'] = input_dict['family'] calc['system-info']['artifact'] = DM() calc['system-info']['artifact']['file'] = input_dict['load_file'] calc['system-info']['artifact']['format'] = input_dict['load_style'] calc['system-info']['artifact']['load_options'] = input_dict['load_options'] calc['system-info']['symbol'] = input_dict['symbols'] #Save defect parameters calc['dislocation-monopole'] = disl = DM() if input_dict['dislocation_model'] is not None: disl['key'] = input_dict['dislocation_model']['key'] disl['id'] = input_dict['dislocation_model']['id'] disl['character'] = input_dict['dislocation_model']['character'] disl['Burgers-vector'] = input_dict['dislocation_model']['Burgers-vector'] disl['slip-plane'] = input_dict['dislocation_model']['slip-plane'] disl['line-direction'] = input_dict['dislocation_model']['line-direction'] disl['system-family'] = input_dict['family'] disl['calculation-parameter'] = cp = DM() cp['a_uvw'] = input_dict['a_uvw'] cp['b_uvw'] = input_dict['b_uvw'] cp['c_uvw'] = input_dict['c_uvw'] cp['atomshift'] = input_dict['atomshift'] cp['burgersvector'] = input_dict['dislocation_burgersvector'] calc['gamma-surface'] = DM() calc['gamma-surface']['calc_key'] = os.path.splitext( os.path.basename( input_dict['gammasurface_file']))[0] calc['stress-state'] = uc.model(input_dict['tau'], input_dict['pressure_unit']) if results_dict is None: calc['status'] = 'not calculated' # Fill in model input parameters calc['semidiscrete-variational-Peierls-Nabarro'] = sdvpn = DM() sdvpn['parameter'] = params = DM() params['tau'] = uc.model(input_dict['tau'], input_dict['pressure_unit']) params['alpha'] = uc.model(input_dict['alpha'], input_dict['pressure_unit'] + '/' + input_dict['length_unit']) params['beta'] = uc.model(input_dict['beta'], input_dict['pressure_unit'] + '*' + input_dict['length_unit']) params['cdiffelastic'] = input_dict['cdiffelastic'] params['cdiffsurface'] = input_dict['cdiffsurface'] params['cdiffstress'] = input_dict['cdiffstress'] params['cutofflongrange'] = uc.model(input_dict['cutofflongrange'], input_dict['length_unit']) params['fullstress'] = input_dict['fullstress'] params['min_method'] = input_dict['minimize_style'] params['min_options'] = input_dict['minimize_options'] else: c_model = input_dict['C'].model(unit=input_dict['pressure_unit']) calc['elastic-constants'] = c_model['elastic-constants'] pnsolution = results_dict['SDVPN_solution'] pnmodel = pnsolution.model(length_unit=input_dict['length_unit'], energy_unit=input_dict['energy_unit'], pressure_unit=input_dict['pressure_unit'], include_gamma=False) calc['semidiscrete-variational-Peierls-Nabarro'] = pnmodel['semidiscrete-variational-Peierls-Nabarro'] e_per_l_unit = input_dict['energy_unit'] + '/' + input_dict['length_unit'] calc['misfit-energy'] = uc.model(pnsolution.misfit_energy(), e_per_l_unit) calc['elastic-energy'] = uc.model(pnsolution.elastic_energy(), e_per_l_unit) calc['long-range-energy'] = uc.model(pnsolution.longrange_energy(), e_per_l_unit) calc['stress-energy'] = uc.model(pnsolution.stress_energy(), e_per_l_unit) calc['surface-energy'] = uc.model(pnsolution.surface_energy(), e_per_l_unit) calc['nonlocal-energy'] = uc.model(pnsolution.nonlocal_energy(), e_per_l_unit) calc['total-energy'] = uc.model(pnsolution.total_energy(), e_per_l_unit) calc['total-energy-per-cycle'] = uc.model(results_dict['minimization_energies'], e_per_l_unit) self.content = output
def buildcontent(self, script, input_dict, results_dict=None): """ Builds a data model of the specified record style based on input (and results) parameters. Parameters ---------- script : str The name of the calculation script used. input_dict : dict Dictionary of all input parameter terms. results_dict : dict, optional Dictionary containing any results produced by the calculation. Returns ------- DataModelDict Data model consistent with the record's schema format. Raises ------ AttributeError If buildcontent is not defined for record style. """ # Create the root of the DataModelDict output = DM() output[self.contentroot] = calc = DM() # Assign uuid calc['key'] = input_dict['calc_key'] # Save calculation parameters calc['calculation'] = DM() calc['calculation']['iprPy-version'] = iprPy_version calc['calculation']['atomman-version'] = am.__version__ calc['calculation']['LAMMPS-version'] = input_dict['lammps_version'] calc['calculation']['script'] = script calc['calculation']['run-parameter'] = run_params = DM() run_params['size-multipliers'] = DM() run_params['size-multipliers']['a'] = list(input_dict['sizemults'][0]) run_params['size-multipliers']['b'] = list(input_dict['sizemults'][1]) run_params['size-multipliers']['c'] = list(input_dict['sizemults'][2]) run_params['energytolerance'] = input_dict['energytolerance'] run_params['forcetolerance'] = uc.model(input_dict['forcetolerance'], input_dict['energy_unit'] + '/' + input_dict['length_unit']) run_params['maxiterations'] = input_dict['maxiterations'] run_params['maxevaluations'] = input_dict['maxevaluations'] run_params['maxatommotion'] = uc.model(input_dict['maxatommotion'], input_dict['length_unit']) run_params['dislocation_boundarywidth'] = input_dict['boundarywidth'] run_params['dislocation_boundaryshape'] = input_dict['boundaryshape'] run_params['annealtemperature'] = input_dict['annealtemperature'] # Copy over potential data model info calc['potential-LAMMPS'] = DM() calc['potential-LAMMPS']['key'] = input_dict['potential'].key calc['potential-LAMMPS']['id'] = input_dict['potential'].id calc['potential-LAMMPS']['potential'] = DM() calc['potential-LAMMPS']['potential']['key'] = input_dict['potential'].potkey calc['potential-LAMMPS']['potential']['id'] = input_dict['potential'].potid # Save info on system file loaded calc['system-info'] = DM() calc['system-info']['family'] = input_dict['family'] calc['system-info']['artifact'] = DM() calc['system-info']['artifact']['file'] = input_dict['load_file'] calc['system-info']['artifact']['format'] = input_dict['load_style'] calc['system-info']['artifact']['load_options'] = input_dict['load_options'] calc['system-info']['symbol'] = input_dict['symbols'] #Save defect parameters calc['dislocation-monopole'] = disl = DM() if input_dict['dislocation_model'] is not None: disl['key'] = input_dict['dislocation_model']['key'] disl['id'] = input_dict['dislocation_model']['id'] disl['character'] = input_dict['dislocation_model']['character'] disl['Burgers-vector'] = input_dict['dislocation_model']['Burgers-vector'] disl['slip-plane'] = input_dict['dislocation_model']['slip-plane'] disl['line-direction'] = input_dict['dislocation_model']['line-direction'] disl['system-family'] = input_dict.get('dislocation_family', input_dict['family']) disl['calculation-parameter'] = cp = DM() cp['stroh_m'] = input_dict['dislocation_stroh_m'] cp['stroh_n'] = input_dict['dislocation_stroh_n'] cp['lineboxvector'] = input_dict['dislocation_lineboxvector'] cp['a_uvw'] = input_dict['a_uvw'] cp['b_uvw'] = input_dict['b_uvw'] cp['c_uvw'] = input_dict['c_uvw'] cp['atomshift'] = input_dict['atomshift'] cp['burgersvector'] = input_dict['dislocation_burgersvector'] if results_dict is None: calc['status'] = 'not calculated' else: c_model = input_dict['C'].model(unit=input_dict['pressure_unit']) calc['elastic-constants'] = c_model['elastic-constants'] calc['base-system'] = DM() calc['base-system']['artifact'] = DM() calc['base-system']['artifact']['file'] = results_dict['dumpfile_base'] calc['base-system']['artifact']['format'] = 'atom_dump' calc['base-system']['symbols'] = results_dict['symbols_base'] calc['defect-system'] = DM() calc['defect-system']['artifact'] = DM() calc['defect-system']['artifact']['file'] = results_dict['dumpfile_disl'] calc['defect-system']['artifact']['format'] = 'atom_dump' calc['defect-system']['symbols'] = results_dict['symbols_disl'] calc['defect-system']['potential-energy'] = uc.model(results_dict['E_total_disl'], input_dict['energy_unit']) calc['Stroh-pre-ln-factor'] = uc.model(results_dict['Stroh_preln'], input_dict['energy_unit'] + '/' + input_dict['length_unit']) calc['Stroh-K-tensor'] = uc.model(results_dict['Stroh_K_tensor'], input_dict['pressure_unit']) self.content = output
def buildcontent(self, script, input_dict, results_dict=None): """ Builds a data model of the specified record style based on input (and results) parameters. Parameters ---------- script : str The name of the calculation script used. input_dict : dict Dictionary of all input parameter terms. results_dict : dict, optional Dictionary containing any results produced by the calculation. Returns ------- DataModelDict Data model consistent with the record's schema format. Raises ------ AttributeError If buildcontent is not defined for record style. """ # Create the root of the DataModelDict output = DM() output[self.contentroot] = calc = DM() # Assign uuid calc['key'] = input_dict['calc_key'] # Save calculation parameters calc['calculation'] = DM() calc['calculation']['iprPy-version'] = iprPy_version calc['calculation']['atomman-version'] = am.__version__ calc['calculation']['LAMMPS-version'] = input_dict['lammps_version'] calc['calculation']['script'] = script calc['calculation']['run-parameter'] = run_params = DM() run_params['size-multipliers'] = DM() run_params['size-multipliers']['a'] = list(input_dict['sizemults'][0]) run_params['size-multipliers']['b'] = list(input_dict['sizemults'][1]) run_params['size-multipliers']['c'] = list(input_dict['sizemults'][2]) run_params['thermosteps'] = input_dict['thermosteps'] run_params['dumpsteps'] = input_dict['dumpsteps'] run_params['runsteps'] = input_dict['runsteps'] run_params['equilsteps'] = input_dict['equilsteps'] run_params['randomseed'] = input_dict['randomseed'] # Copy over potential data model info calc['potential-LAMMPS'] = DM() calc['potential-LAMMPS']['key'] = input_dict['potential'].key calc['potential-LAMMPS']['id'] = input_dict['potential'].id calc['potential-LAMMPS']['potential'] = DM() calc['potential-LAMMPS']['potential']['key'] = input_dict['potential'].potkey calc['potential-LAMMPS']['potential']['id'] = input_dict['potential'].potid # Save info on system file loaded calc['system-info'] = DM() calc['system-info']['family'] = input_dict['family'] calc['system-info']['artifact'] = DM() calc['system-info']['artifact']['file'] = input_dict['load_file'] calc['system-info']['artifact']['format'] = input_dict['load_style'] calc['system-info']['artifact']['load_options'] = input_dict['load_options'] calc['system-info']['symbol'] = input_dict['symbols'] # Save defined phase-state info calc['phase-state'] = DM() calc['phase-state']['temperature'] = uc.model(input_dict['temperature'], 'K') # Save defect parameters calc['point-defect'] = ptd = DM() if input_dict['pointdefect_model'] is not None: ptd['key'] = input_dict['pointdefect_model']['key'] ptd['id'] = input_dict['pointdefect_model']['id'] ptd['system-family'] = input_dict.get('pointdefect_family', input_dict['family']) ptd['calculation-parameter'] = input_dict['calculation_params'] if results_dict is None: calc['status'] = 'not calculated' else: # Save measured phase state info calc['measured-phase-state'] = mps = DM() mps['temperature'] = uc.model(results_dict.get('temp', 0.0), 'K', results_dict.get('temp_std', None)) mps['pressure-xx'] = uc.model(results_dict['pxx'], input_dict['pressure_unit'], results_dict['pxx_std']) mps['pressure-yy'] = uc.model(results_dict['pyy'], input_dict['pressure_unit'], results_dict['pyy_std']) mps['pressure-zz'] = uc.model(results_dict['pzz'], input_dict['pressure_unit'], results_dict['pzz_std']) mps['potential-energy'] = uc.model(results_dict['Epot'], input_dict['pressure_unit'], results_dict['Epot_std']) # Save the calculation results calc['diffusion-rate'] = dr = DM() diffusion_unit = input_dict['length_unit'] + '^2/s' dr['total'] = uc.model(results_dict['d'], diffusion_unit) dr['x-direction'] = uc.model(results_dict['dx'], diffusion_unit) dr['y-direction'] = uc.model(results_dict['dy'], diffusion_unit) dr['z-direction'] = uc.model(results_dict['dz'], diffusion_unit) calc['number-of-atoms'] = results_dict['natoms'] self.content = output
def buildcontent(self, script, input_dict, results_dict=None): """ Builds a data model of the specified record style based on input (and results) parameters. Parameters ---------- script : str The name of the calculation script used. input_dict : dict Dictionary of all input parameter terms. results_dict : dict, optional Dictionary containing any results produced by the calculation. Returns ------- DataModelDict Data model consistent with the record's schema format. Raises ------ AttributeError If buildcontent is not defined for record style. """ # Create the root of the DataModelDict output = DM() output[self.contentroot] = calc = DM() # Assign uuid calc['key'] = input_dict['calc_key'] # Save calculation parameters calc['calculation'] = DM() calc['calculation']['iprPy-version'] = iprPy_version calc['calculation']['atomman-version'] = am.__version__ calc['calculation']['LAMMPS-version'] = input_dict['lammps_version'] calc['calculation']['script'] = script calc['calculation']['run-parameter'] = run_params = DM() run_params['size-multipliers'] = DM() run_params['size-multipliers']['a'] = list(input_dict['sizemults'][0]) run_params['size-multipliers']['b'] = list(input_dict['sizemults'][1]) run_params['size-multipliers']['c'] = list(input_dict['sizemults'][2]) run_params['strain-range'] = input_dict['strainrange'] # Copy over potential data model info calc['potential-LAMMPS'] = DM() calc['potential-LAMMPS']['key'] = input_dict['potential'].key calc['potential-LAMMPS']['id'] = input_dict['potential'].id calc['potential-LAMMPS']['potential'] = DM() calc['potential-LAMMPS']['potential']['key'] = input_dict['potential'].potkey calc['potential-LAMMPS']['potential']['id'] = input_dict['potential'].potid # Save info on system file loaded calc['system-info'] = DM() calc['system-info']['family'] = input_dict['family'] calc['system-info']['artifact'] = DM() calc['system-info']['artifact']['file'] = input_dict['load_file'] calc['system-info']['artifact']['format'] = input_dict['load_style'] calc['system-info']['artifact']['load_options'] = input_dict['load_options'] calc['system-info']['symbol'] = input_dict['symbols'] # Save phase-state info calc['phase-state'] = DM() calc['phase-state']['temperature'] = uc.model(input_dict['temperature'], 'K') calc['phase-state']['pressure-xx'] = uc.model(input_dict['pressure_xx'], input_dict['pressure_unit']) calc['phase-state']['pressure-yy'] = uc.model(input_dict['pressure_yy'], input_dict['pressure_unit']) calc['phase-state']['pressure-zz'] = uc.model(input_dict['pressure_zz'], input_dict['pressure_unit']) calc['phase-state']['pressure-xy'] = uc.model(input_dict['pressure_xy'], input_dict['pressure_unit']) calc['phase-state']['pressure-xz'] = uc.model(input_dict['pressure_xz'], input_dict['pressure_unit']) calc['phase-state']['pressure-yz'] = uc.model(input_dict['pressure_yz'], input_dict['pressure_unit']) if results_dict is None: calc['status'] = 'not calculated' else: # Save info on initial and final configuration files calc['initial-system'] = DM() calc['initial-system']['artifact'] = DM() calc['initial-system']['artifact']['file'] = results_dict['dumpfile_initial'] calc['initial-system']['artifact']['format'] = 'atom_dump' calc['initial-system']['symbols'] = results_dict['symbols_initial'] calc['final-system'] = DM() calc['final-system']['artifact'] = DM() calc['final-system']['artifact']['file'] = results_dict['dumpfile_final'] calc['final-system']['artifact']['format'] = 'atom_dump' calc['final-system']['symbols'] = results_dict['symbols_final'] # Save measured box parameter info calc['measured-box-parameter'] = mbp = DM() lx = results_dict['lx'] / (input_dict['sizemults'][0][1] - input_dict['sizemults'][0][0]) ly = results_dict['ly'] / (input_dict['sizemults'][1][1] - input_dict['sizemults'][1][0]) lz = results_dict['lz'] / (input_dict['sizemults'][2][1] - input_dict['sizemults'][2][0]) xy = results_dict['xy'] / (input_dict['sizemults'][1][1] - input_dict['sizemults'][1][0]) xz = results_dict['xz'] / (input_dict['sizemults'][2][1] - input_dict['sizemults'][2][0]) yz = results_dict['yz'] / (input_dict['sizemults'][2][1] - input_dict['sizemults'][2][0]) mbp['lx'] = uc.model(lx, input_dict['length_unit']) mbp['ly'] = uc.model(ly, input_dict['length_unit']) mbp['lz'] = uc.model(lz, input_dict['length_unit']) mbp['xy'] = uc.model(xy, input_dict['length_unit']) mbp['xz'] = uc.model(xz, input_dict['length_unit']) mbp['yz'] = uc.model(yz, input_dict['length_unit']) # Save measured phase-state info calc['measured-phase-state'] = mps = DM() mps['temperature'] = uc.model(results_dict.get('temp', 0.0), 'K') mps['pressure-xx'] = uc.model(results_dict['measured_pxx'], input_dict['pressure_unit']) mps['pressure-yy'] = uc.model(results_dict['measured_pyy'], input_dict['pressure_unit']) mps['pressure-zz'] = uc.model(results_dict['measured_pzz'], input_dict['pressure_unit']) mps['pressure-xy'] = uc.model(results_dict['measured_pxy'], input_dict['pressure_unit']) mps['pressure-xz'] = uc.model(results_dict['measured_pxz'], input_dict['pressure_unit']) mps['pressure-yz'] = uc.model(results_dict['measured_pyz'], input_dict['pressure_unit']) # Save the final cohesive energy calc['cohesive-energy'] = uc.model(results_dict['E_coh'], input_dict['energy_unit'], results_dict.get('E_coh_std', None)) self.content = output
def buildcontent(self, script, input_dict, results_dict=None): """ Builds a data model of the specified record style based on input (and results) parameters. Parameters ---------- script : str The name of the calculation script used. input_dict : dict Dictionary of all input parameter terms. results_dict : dict, optional Dictionary containing any results produced by the calculation. Returns ------- DataModelDict Data model consistent with the record's schema format. Raises ------ AttributeError If buildcontent is not defined for record style. """ # Create the root of the DataModelDict output = DM() output[self.contentroot] = calc = DM() # Assign uuid calc['key'] = input_dict['calc_key'] # Save calculation parameters calc['calculation'] = DM() calc['calculation']['iprPy-version'] = iprPy_version calc['calculation']['atomman-version'] = am.__version__ calc['calculation']['LAMMPS-version'] = input_dict['lammps_version'] calc['calculation']['script'] = script calc['calculation']['run-parameter'] = run_params = DM() run_params['size-multipliers'] = DM() run_params['size-multipliers']['a'] = list(input_dict['sizemults'][0]) run_params['size-multipliers']['b'] = list(input_dict['sizemults'][1]) run_params['size-multipliers']['c'] = list(input_dict['sizemults'][2]) run_params['energytolerance'] = input_dict['energytolerance'] run_params['forcetolerance'] = uc.model( input_dict['forcetolerance'], input_dict['energy_unit'] + '/' + input_dict['length_unit']) run_params['maxiterations'] = input_dict['maxiterations'] run_params['maxevaluations'] = input_dict['maxevaluations'] run_params['maxatommotion'] = uc.model(input_dict['maxatommotion'], input_dict['length_unit']) # Copy over potential data model info calc['potential-LAMMPS'] = DM() calc['potential-LAMMPS']['key'] = input_dict['potential'].key calc['potential-LAMMPS']['id'] = input_dict['potential'].id calc['potential-LAMMPS']['potential'] = DM() calc['potential-LAMMPS']['potential']['key'] = input_dict[ 'potential'].potkey calc['potential-LAMMPS']['potential']['id'] = input_dict[ 'potential'].potid # Save info on system file loaded calc['system-info'] = DM() calc['system-info']['family'] = input_dict['family'] calc['system-info']['artifact'] = DM() calc['system-info']['artifact']['file'] = input_dict['load_file'] calc['system-info']['artifact']['format'] = input_dict['load_style'] calc['system-info']['artifact']['load_options'] = input_dict[ 'load_options'] calc['system-info']['symbol'] = input_dict['symbols'] #Save defect parameters calc['free-surface'] = surf = DM() if input_dict['surface_model'] is not None: surf['key'] = input_dict['surface_model']['key'] surf['id'] = input_dict['surface_model']['id'] surf['system-family'] = input_dict.get('surface_family', input_dict['family']) surf['calculation-parameter'] = cp = DM() cp['a_uvw'] = input_dict['a_uvw'] cp['b_uvw'] = input_dict['b_uvw'] cp['c_uvw'] = input_dict['c_uvw'] cp['atomshift'] = input_dict['atomshift'] cp['cutboxvector'] = input_dict['surface_cutboxvector'] if results_dict is None: calc['status'] = 'not calculated' else: calc['defect-free-system'] = DM() calc['defect-free-system']['artifact'] = DM() calc['defect-free-system']['artifact']['file'] = results_dict[ 'dumpfile_base'] calc['defect-free-system']['artifact']['format'] = 'atom_dump' calc['defect-free-system']['symbols'] = input_dict['symbols'] calc['defect-free-system']['potential-energy'] = uc.model( results_dict['E_total_base'], input_dict['energy_unit']) calc['defect-system'] = DM() calc['defect-system']['artifact'] = DM() calc['defect-system']['artifact']['file'] = results_dict[ 'dumpfile_surf'] calc['defect-system']['artifact']['format'] = 'atom_dump' calc['defect-system']['symbols'] = input_dict['symbols'] calc['defect-system']['potential-energy'] = uc.model( results_dict['E_total_surf'], input_dict['energy_unit']) # Save the cohesive energy calc['cohesive-energy'] = uc.model(results_dict['E_coh'], input_dict['energy_unit']) # Save the free surface energy calc['free-surface-energy'] = uc.model( results_dict['E_surf_f'], input_dict['energy_unit'] + '/' + input_dict['length_unit'] + '^2') self.content = output
def build_model(self): """ Generates and returns model content based on the values set to object. """ # Build universal content model = super().build_model() calc = model[self.modelroot] # Build subset content self.commands.build_model(calc, after='atomman-version') self.potential.build_model(calc, after='calculation') self.system.build_model(calc, after='potential-LAMMPS') self.system_mods.build_model(calc) # Build calculation-specific content if 'calculation' not in calc: calc['calculation'] = DM() if 'run-parameter' not in calc['calculation']: calc['calculation']['run-parameter'] = DM() run_params = calc['calculation']['run-parameter'] run_params['displacementdistance'] = uc.model(self.displacementdistance, self.units.length_unit) run_params['symmetryprecision'] = self.symmetryprecision run_params['strainrange'] = self.strainrange run_params['numstrains'] = self.numstrains # Build results if self.status == 'finished': calc['band-structure'] = DM() for qpoints in self.bandstructure['qpoints']: calc['band-structure'].append('qpoints', uc.model(qpoints)) for distances in self.bandstructure['distances']: calc['band-structure'].append('distances', uc.model(distances)) for frequencies in self.bandstructure['frequencies']: calc['band-structure'].append('frequencies', uc.model(frequencies)) calc['density-of-states'] = DM() calc['density-of-states']['frequency'] = uc.model(self.dos['frequency'], 'THz') calc['density-of-states']['total_dos'] = uc.model(self.dos['total_dos']) calc['density-of-states']['projected_dos'] = uc.model(self.dos['projected_dos']) calc['thermal-properties'] = DM() calc['thermal-properties']['temperature'] = uc.model(self.thermal['temperature'], 'K') calc['thermal-properties']['Helmholtz'] = uc.model(self.thermal['Helmholtz'], 'eV') calc['thermal-properties']['entropy'] = uc.model(self.thermal['entropy'], 'J/K/mol') calc['thermal-properties']['heat_capacity_v'] = uc.model(self.thermal['heat_capacity_v'], 'J/K/mol') # Add qha results if self.__volumescan is not None: calc['thermal-properties']['volume'] = uc.model(self.thermal['volume'], 'angstrom^3') calc['thermal-properties']['thermal_expansion'] = uc.model(self.thermal['thermal_expansion']) calc['thermal-properties']['Gibbs'] = uc.model(self.thermal['Gibbs'], 'eV') calc['thermal-properties']['bulk_modulus'] = uc.model(self.thermal['bulk_modulus'], 'GPa') calc['thermal-properties']['heat_capacity_p_numerical'] = uc.model(self.thermal['heat_capacity_p_numerical'], 'J/K/mol') calc['thermal-properties']['heat_capacity_p_polyfit'] = uc.model(self.thermal['heat_capacity_p_polyfit'], 'J/K/mol') calc['thermal-properties']['gruneisen'] = uc.model(self.thermal['gruneisen']) calc['volume-scan'] = DM() calc['volume-scan']['volume'] = uc.model(self.volumescan['volume'], 'angstrom^3') calc['volume-scan']['strain'] = uc.model(self.volumescan['strain']) calc['volume-scan']['energy'] = uc.model(self.volumescan['energy'], 'eV') calc['E0'] = uc.model(self.E0, 'eV') calc['B0'] = uc.model(self.B0, 'GPa') calc['B0prime'] = uc.model(self.B0prime, 'GPa') calc['V0'] = uc.model(self.V0, 'angstrom^3') self._set_model(model) return model
def buildcontent(self, input_dict, results_dict=None): """ Builds a data model of the specified record style based on input (and results) parameters. Parameters ---------- input_dict : dict Dictionary of all input parameter terms. results_dict : dict, optional Dictionary containing any results produced by the calculation. Returns ------- DataModelDict Data model consistent with the record's schema format. Raises ------ AttributeError If buildcontent is not defined for record style. """ # Build universal content super().buildcontent(input_dict, results_dict=results_dict) # Load content after root calc = self.content[self.contentroot] calc['calculation']['run-parameter'] = run_params = DM() # Copy over sizemults (rotations and shifts) subset('atomman_systemmanipulate').buildcontent( calc, input_dict, results_dict=results_dict) run_params['strain-range'] = input_dict['strainrange'] # Copy over minimization parameters subset('lammps_minimize').buildcontent(calc, input_dict, results_dict=results_dict) # Copy over potential data model info subset('lammps_potential').buildcontent(calc, input_dict, results_dict=results_dict) # Save info on system file loaded subset('atomman_systemload').buildcontent(calc, input_dict, results_dict=results_dict) if results_dict is None: calc['status'] = 'not calculated' else: cij = DM() cij['Cij'] = uc.model(results_dict['raw_cij_negative'], 'GPa') calc.append('raw-elastic-constants', cij) cij = DM() cij['Cij'] = uc.model(results_dict['raw_cij_positive'], 'GPa') calc.append('raw-elastic-constants', cij) calc['elastic-constants'] = DM() calc['elastic-constants']['Cij'] = uc.model( results_dict['C'].Cij, 'GPa')
def buildcontent(self, script, input_dict, results_dict=None): """ Builds a data model of the specified record style based on input (and results) parameters. Parameters ---------- script : str The name of the calculation script used. input_dict : dict Dictionary of all input parameter terms. results_dict : dict, optional Dictionary containing any results produced by the calculation. Returns ------- DataModelDict Data model consistent with the record's schema format. Raises ------ AttributeError If buildcontent is not defined for record style. """ # Create the root of the DataModelDict output = DM() output[self.contentroot] = calc = DM() # Assign uuid calc['key'] = input_dict['calc_key'] # Save calculation parameters calc['calculation'] = DM() calc['calculation']['iprPy-version'] = iprPy_version calc['calculation']['atomman-version'] = am.__version__ calc['calculation']['LAMMPS-version'] = input_dict['lammps_version'] calc['calculation']['script'] = script calc['calculation']['run-parameter'] = run_params = DM() run_params['size-multipliers'] = DM() run_params['size-multipliers']['a'] = list(input_dict['sizemults'][0]) run_params['size-multipliers']['b'] = list(input_dict['sizemults'][1]) run_params['size-multipliers']['c'] = list(input_dict['sizemults'][2]) run_params['energytolerance'] = input_dict['energytolerance'] run_params['forcetolerance'] = uc.model(input_dict['forcetolerance'], input_dict['energy_unit']+'/'+input_dict['length_unit']) run_params['maxiterations'] = input_dict['maxiterations'] run_params['maxevaluations'] = input_dict['maxevaluations'] run_params['maxatommotion'] = uc.model(input_dict['maxatommotion'], input_dict['length_unit']) # Copy over potential data model info calc['potential-LAMMPS'] = DM() calc['potential-LAMMPS']['key'] = input_dict['potential'].key calc['potential-LAMMPS']['id'] = input_dict['potential'].id calc['potential-LAMMPS']['potential'] = DM() calc['potential-LAMMPS']['potential']['key'] = input_dict['potential'].potkey calc['potential-LAMMPS']['potential']['id'] = input_dict['potential'].potid # Save info on system file loaded calc['system-info'] = DM() calc['system-info']['family'] = input_dict['family'] calc['system-info']['artifact'] = DM() calc['system-info']['artifact']['file'] = input_dict['load_file'] calc['system-info']['artifact']['format'] = input_dict['load_style'] calc['system-info']['artifact']['load_options'] = input_dict['load_options'] calc['system-info']['symbol'] = input_dict['symbols'] #Save defect parameters calc['free-surface'] = surf = DM() if input_dict['surface_model'] is not None: surf['key'] = input_dict['surface_model']['key'] surf['id'] = input_dict['surface_model']['id'] surf['system-family'] = input_dict.get('surface_family', input_dict['family']) surf['calculation-parameter'] = cp = DM() cp['a_uvw'] = input_dict['a_uvw'] cp['b_uvw'] = input_dict['b_uvw'] cp['c_uvw'] = input_dict['c_uvw'] cp['atomshift'] = input_dict['atomshift'] cp['cutboxvector'] = input_dict['surface_cutboxvector'] if results_dict is None: calc['status'] = 'not calculated' else: calc['defect-free-system'] = DM() calc['defect-free-system']['artifact'] = DM() calc['defect-free-system']['artifact']['file'] = results_dict['dumpfile_base'] calc['defect-free-system']['artifact']['format'] = 'atom_dump' calc['defect-free-system']['symbols'] = input_dict['symbols'] calc['defect-free-system']['potential-energy'] = uc.model(results_dict['E_total_base'], input_dict['energy_unit']) calc['defect-system'] = DM() calc['defect-system']['artifact'] = DM() calc['defect-system']['artifact']['file'] = results_dict['dumpfile_surf'] calc['defect-system']['artifact']['format'] = 'atom_dump' calc['defect-system']['symbols'] = input_dict['symbols'] calc['defect-system']['potential-energy'] = uc.model(results_dict['E_total_surf'], input_dict['energy_unit']) # Save the cohesive energy calc['cohesive-energy'] = uc.model(results_dict['E_coh'], input_dict['energy_unit']) # Save the free surface energy calc['free-surface-energy'] = uc.model(results_dict['E_surf_f'], input_dict['energy_unit']+'/'+input_dict['length_unit']+'^2') self.content = output
def buildcontent(self, script, input_dict, results_dict=None): """ Builds a data model of the specified record style based on input (and results) parameters. Parameters ---------- script : str The name of the calculation script used. input_dict : dict Dictionary of all input parameter terms. results_dict : dict, optional Dictionary containing any results produced by the calculation. Returns ------- DataModelDict Data model consistent with the record's schema format. Raises ------ AttributeError If buildcontent is not defined for record style. """ # Create the root of the DataModelDict output = DM() output[self.contentroot] = calc = DM() # Assign uuid calc['key'] = input_dict['calc_key'] # Save calculation parameters calc['calculation'] = DM() calc['calculation']['iprPy-version'] = iprPy_version calc['calculation']['atomman-version'] = am.__version__ calc['calculation']['script'] = script calc['calculation']['run-parameter'] = run_params = DM() run_params['halfwidth'] = uc.model(input_dict['halfwidth'], input_dict['length_unit']) x, idisreg = pn_arctan_disregistry(xmax=input_dict['xmax'], xnum=input_dict['xnum'], xstep=input_dict['xstep']) run_params['xmax'] = x.max() run_params['xnum'] = len(x) run_params['xstep'] = x[1] - x[0] # Save info on system file loaded calc['system-info'] = DM() calc['system-info']['family'] = input_dict['family'] calc['system-info']['artifact'] = DM() calc['system-info']['artifact']['file'] = input_dict['load_file'] calc['system-info']['artifact']['format'] = input_dict['load_style'] calc['system-info']['artifact']['load_options'] = input_dict[ 'load_options'] calc['system-info']['symbol'] = input_dict['symbols'] #Save defect parameters calc['dislocation-monopole'] = disl = DM() if input_dict['dislocation_model'] is not None: disl['key'] = input_dict['dislocation_model']['key'] disl['id'] = input_dict['dislocation_model']['id'] disl['character'] = input_dict['dislocation_model']['character'] disl['Burgers-vector'] = input_dict['dislocation_model'][ 'Burgers-vector'] disl['slip-plane'] = input_dict['dislocation_model']['slip-plane'] disl['line-direction'] = input_dict['dislocation_model'][ 'line-direction'] disl['system-family'] = input_dict['family'] disl['calculation-parameter'] = cp = DM() cp['x_axis'] = input_dict['x_axis'] cp['y_axis'] = input_dict['y_axis'] cp['z_axis'] = input_dict['z_axis'] cp['atomshift'] = input_dict['atomshift'] cp['burgersvector'] = input_dict['dislocation_burgersvector'] calc['gamma-surface'] = DM() calc['gamma-surface']['calc_key'] = os.path.splitext( os.path.basename(input_dict['gammasurface_file']))[0] calc['stress-state'] = uc.model(input_dict['tau'], input_dict['pressure_unit']) if results_dict is None: calc['status'] = 'not calculated' # Fill in model input parameters calc['semidiscrete-variational-Peierls-Nabarro'] = sdvpn = DM() sdvpn['parameter'] = params = DM() params['tau'] = uc.model(input_dict['tau'], input_dict['pressure_unit']) params['alpha'] = uc.model( input_dict['alpha'], input_dict['pressure_unit'] + '/' + input_dict['length_unit']) params['beta'] = uc.model( input_dict['beta'], input_dict['pressure_unit'] + '*' + input_dict['length_unit']) params['cdiffelastic'] = input_dict['cdiffelastic'] params['cdiffsurface'] = input_dict['cdiffsurface'] params['cdiffstress'] = input_dict['cdiffstress'] params['cutofflongrange'] = uc.model(input_dict['cutofflongrange'], input_dict['length_unit']) params['fullstress'] = input_dict['fullstress'] params['min_method'] = input_dict['minimize_style'] params['min_options'] = input_dict['minimize_options'] else: c_model = input_dict['C'].model(unit=input_dict['pressure_unit']) calc['elastic-constants'] = c_model['elastic-constants'] pnsolution = results_dict['SDVPN_solution'] pnmodel = pnsolution.model( length_unit=input_dict['length_unit'], energy_unit=input_dict['energy_unit'], pressure_unit=input_dict['pressure_unit'], include_gamma=False) calc['semidiscrete-variational-Peierls-Nabarro'] = pnmodel[ 'semidiscrete-variational-Peierls-Nabarro'] e_per_l_unit = input_dict['energy_unit'] + '/' + input_dict[ 'length_unit'] calc['misfit-energy'] = uc.model(pnsolution.misfit_energy(), e_per_l_unit) calc['elastic-energy'] = uc.model(pnsolution.elastic_energy(), e_per_l_unit) calc['long-range-energy'] = uc.model(pnsolution.longrange_energy(), e_per_l_unit) calc['stress-energy'] = uc.model(pnsolution.stress_energy(), e_per_l_unit) calc['surface-energy'] = uc.model(pnsolution.surface_energy(), e_per_l_unit) calc['nonlocal-energy'] = uc.model(pnsolution.nonlocal_energy(), e_per_l_unit) calc['total-energy'] = uc.model(pnsolution.total_energy(), e_per_l_unit) self.content = output
def buildcontent(self, script, input_dict, results_dict=None): """ Builds a data model of the specified record style based on input (and results) parameters. Parameters ---------- script : str The name of the calculation script used. input_dict : dict Dictionary of all input parameter terms. results_dict : dict, optional Dictionary containing any results produced by the calculation. Returns ------- DataModelDict Data model consistent with the record's schema format. Raises ------ AttributeError If buildcontent is not defined for record style. """ # Create the root of the DataModelDict output = DM() output[self.contentroot] = calc = DM() # Assign uuid calc['key'] = input_dict['calc_key'] # Save calculation parameters calc['calculation'] = DM() calc['calculation']['iprPy-version'] = iprPy_version calc['calculation']['atomman-version'] = am.__version__ calc['calculation']['LAMMPS-version'] = input_dict['lammps_version'] calc['calculation']['script'] = script calc['calculation']['run-parameter'] = run_params = DM() run_params['size-multipliers'] = DM() run_params['size-multipliers']['a'] = list(input_dict['sizemults'][0]) run_params['size-multipliers']['b'] = list(input_dict['sizemults'][1]) run_params['size-multipliers']['c'] = list(input_dict['sizemults'][2]) run_params['strain-range'] = input_dict['strainrange'] run_params['energytolerance'] = input_dict['energytolerance'] run_params['forcetolerance'] = uc.model(input_dict['forcetolerance'], input_dict['energy_unit'] + '/' + input_dict['length_unit']) run_params['maxiterations'] = input_dict['maxiterations'] run_params['maxevaluations'] = input_dict['maxevaluations'] run_params['maxatommotion'] = uc.model(input_dict['maxatommotion'], input_dict['length_unit']) # Copy over potential data model info calc['potential-LAMMPS'] = DM() calc['potential-LAMMPS']['key'] = input_dict['potential'].key calc['potential-LAMMPS']['id'] = input_dict['potential'].id calc['potential-LAMMPS']['potential'] = DM() calc['potential-LAMMPS']['potential']['key'] = input_dict['potential'].potkey calc['potential-LAMMPS']['potential']['id'] = input_dict['potential'].potid # Save info on system file loaded calc['system-info'] = DM() calc['system-info']['family'] = input_dict['family'] calc['system-info']['artifact'] = DM() calc['system-info']['artifact']['file'] = input_dict['load_file'] calc['system-info']['artifact']['format'] = input_dict['load_style'] calc['system-info']['artifact']['load_options'] = input_dict['load_options'] calc['system-info']['symbol'] = input_dict['symbols'] if results_dict is None: calc['status'] = 'not calculated' else: cij = DM() cij['Cij'] = uc.model(results_dict['raw_cij_negative'], 'GPa') calc.append('raw-elastic-constants', cij) cij = DM() cij['Cij'] = uc.model(results_dict['raw_cij_positive'], 'GPa') calc.append('raw-elastic-constants', cij) calc['elastic-constants'] = DM() calc['elastic-constants']['Cij'] = uc.model(results_dict['C'].Cij, 'GPa') self.content = output
def dump(system, **kwargs): """ Return a DataModelDict 'cell' representation of the system. Parameters ---------- system : atomman.System The system to generate the data model for. f : str or file-like object, optional File path or file-like object to write the content to. If not given, then the content is returned as a DataModelDict. format : str, optional File format 'xml' or 'json' to save the content as if f is given. If f is a filename, then the format will be automatically inferred from f's extension. If format is not given and cannot be inferred, then it will be set to 'json'. indent : int or None, optional Indentation option to use for XML/JSON content if f is given. A value of None (default) will add no line separatations or indentations. box_unit : str, optional Length unit to use for the box. Default value is 'angstrom'. symbols : list, optional list of atom-model symbols corresponding to the atom types. If not given, will use system.symbols. elements : list, optional list of element tags corresponding to the atom types. prop_units : dict, optional dictionary where the keys are the property keys to include, and the values are units to use. If not given, only the positions in scaled units are included. a_std : float, optional Standard deviation of a lattice constant to include if available. b_std : float, optional Standard deviation of b lattice constant to include if available. c_std : float, optional Standard deviation of c lattice constant to include if available. Returns ------- DataModelDict A 'cell' data model of the system. """ # Set default values box_unit = kwargs.get('box_unit', 'angstrom') indent = kwargs.get('indent', None) symbols = kwargs.get('symbols', system.symbols) if isinstance(symbols, stringtype): symbols = [symbols] assert len(symbols) == system.natypes, 'Number of symbols does not match number of atom types' elements = kwargs.get('elements', [None for i in range(system.natypes)]) if not isinstance(elements, list): elements = [elements] assert len(elements) == system.natypes, 'Number of elements does not match number of atom types' prop_units = kwargs.get('prop_units', {}) if 'pos' not in prop_units: prop_units['pos'] = 'scaled' # Extract system values a = system.box.a b = system.box.b c = system.box.c alpha = system.box.alpha beta = system.box.beta gamma = system.box.gamma # Check for box standard deviations if 'a_std' in kwargs and 'b_std' in kwargs and 'c_std' in kwargs: errors = True a_std = kwargs['a_std'] b_std = kwargs['b_std'] c_std = kwargs['c_std'] else: errors = False a_std = None b_std = None c_std = None # Initialize DataModelDict model = DM() model['cell'] = cell = DM() # Test crystal family c_family = identifyfamily(system.box) if c_family is None: c_family = 'triclinic' cell[c_family] = DM() if c_family == 'cubic': a_ave = (a + b + c) / 3 if errors is True: a_std_ave = (a_std + b_std + c_std) / 3 else: a_std_ave = None cell[c_family]['a'] = uc.model(a_ave, box_unit, error=a_std_ave) elif c_family == 'tetragonal': a_ave = (a + b) / 2 if errors is True: a_std_ave = (a_std + b_std) / 2 else: a_std_ave = None cell[c_family]['a'] = uc.model(a_ave, box_unit, error=a_std_ave) cell[c_family]['c'] = uc.model(c, box_unit, error=c_std) elif c_family == 'orthorhombic': cell[c_family]['a'] = uc.model(a, box_unit, error=a_std) cell[c_family]['b'] = uc.model(b, box_unit, error=b_std) cell[c_family]['c'] = uc.model(c, box_unit, error=c_std) elif c_family == 'hexagonal': a_ave = (a + b) / 2 if errors is True: a_std_ave = (a_std + b_std) / 2 else: a_std_ave = None cell[c_family]['a'] = uc.model(a_ave, box_unit, error=a_std_ave) cell[c_family]['c'] = uc.model(c, box_unit, error=c_std) elif c_family == 'rhombohedral': a_ave = (a + b + c) / 3 alpha_ave = (alpha + beta + gamma) / 3 if errors is True: a_std_ave = (a_std + b_std + c_std) / 3 else: a_std_ave = None cell[c_family]['a'] = uc.model(a_ave, box_unit, error=a_std_ave) cell[c_family]['alpha'] = alpha_ave elif c_family == 'monoclinic': cell[c_family]['a'] = uc.model(a, box_unit, error=a_std) cell[c_family]['b'] = uc.model(b, box_unit, error=b_std) cell[c_family]['c'] = uc.model(c, box_unit, error=c_std) cell[c_family]['beta'] = beta elif c_family == 'triclinic': cell[c_family]['a'] = uc.model(a, box_unit, error=a_std) cell[c_family]['b'] = uc.model(b, box_unit, error=b_std) cell[c_family]['c'] = uc.model(c, box_unit, error=c_std) cell[c_family]['alpha'] = alpha cell[c_family]['beta'] = beta cell[c_family]['gamma'] = gamma else: raise ValueError('Unknown crystal family') atype = system.atoms.atype aindex = atype - 1 # Build list of atoms and per-atom properties for i in range(system.natoms): atom = DM() atom['component'] = int(atype[i]) symbol = symbols[aindex[i]] if symbol is not None: atom['symbol'] = symbol element = elements[aindex[i]] if element is not None: atom['element'] = element atom['position'] = DM() if prop_units['pos'] == 'scaled': atom['position']['value'] = list(system.atoms_prop(a_id=i, key='pos', scale=True)) else: atom['position']['value'] = list(uc.get_in_units(system.atoms.pos[i], prop_units['pos'])) atom['position']['unit'] = prop_units['pos'] for key, unit in iteritems(prop_units): if key != 'pos' and key != 'atype': value = system.atoms.view[key][i] prop = DM() prop['name'] = key prop.update(uc.model(value, unit)) atom.append('property', prop) model.append('atom', atom) model = DM([('atomic-system', model)]) # Return DataModelDict or str if 'f' not in kwargs: if 'format' not in kwargs: return model elif kwargs['format'].lower() == 'xml': return model.xml(indent=indent) elif kwargs['format'].lower() == 'json': return model.json(indent=indent) # Write to file else: f = kwargs['f'] if 'format' not in kwargs: try: format = os.path.splitext(f)[1][1:] except: format = 'json' else: format = kwargs['format'] if hasattr(f, 'write'): if format.lower() == 'xml': return model.xml(fp=f, indent=indent) elif format.lower() == 'json': return model.json(fp=f, indent=indent) else: with open(f, 'w') as fp: if format.lower() == 'xml': return model.xml(fp=fp, indent=indent) elif format.lower() == 'json': return model.json(fp=fp, indent=indent) return
def buildcontent(self, script, input_dict, results_dict=None): """ Builds a data model of the specified record style based on input (and results) parameters. Parameters ---------- script : str The name of the calculation script used. input_dict : dict Dictionary of all input parameter terms. results_dict : dict, optional Dictionary containing any results produced by the calculation. Returns ------- DataModelDict Data model consistent with the record's schema format. Raises ------ AttributeError If buildcontent is not defined for record style. """ # Create the root of the DataModelDict output = DM() output[self.contentroot] = calc = DM() # Assign uuid calc['key'] = input_dict['calc_key'] # Save calculation parameters calc['calculation'] = DM() calc['calculation']['iprPy-version'] = iprPy_version calc['calculation']['atomman-version'] = am.__version__ calc['calculation']['LAMMPS-version'] = input_dict['lammps_version'] calc['calculation']['script'] = script calc['calculation']['run-parameter'] = run_params = DM() run_params['size-multipliers'] = DM() run_params['size-multipliers']['a'] = list(input_dict['sizemults'][0]) run_params['size-multipliers']['b'] = list(input_dict['sizemults'][1]) run_params['size-multipliers']['c'] = list(input_dict['sizemults'][2]) run_params['thermosteps'] = input_dict['thermosteps'] run_params['dumpsteps'] = input_dict['dumpsteps'] run_params['runsteps'] = input_dict['runsteps'] run_params['equilsteps'] = input_dict['equilsteps'] run_params['randomseed'] = input_dict['randomseed'] # Copy over potential data model info calc['potential-LAMMPS'] = DM() calc['potential-LAMMPS']['key'] = input_dict['potential'].key calc['potential-LAMMPS']['id'] = input_dict['potential'].id calc['potential-LAMMPS']['potential'] = DM() calc['potential-LAMMPS']['potential']['key'] = input_dict[ 'potential'].potkey calc['potential-LAMMPS']['potential']['id'] = input_dict[ 'potential'].potid # Save info on system file loaded calc['system-info'] = DM() calc['system-info']['family'] = input_dict['family'] calc['system-info']['artifact'] = DM() calc['system-info']['artifact']['file'] = input_dict['load_file'] calc['system-info']['artifact']['format'] = input_dict['load_style'] calc['system-info']['artifact']['load_options'] = input_dict[ 'load_options'] calc['system-info']['symbol'] = input_dict['symbols'] # Save defined phase-state info calc['phase-state'] = DM() calc['phase-state']['temperature'] = uc.model( input_dict['temperature'], 'K') # Save defect parameters calc['point-defect'] = ptd = DM() if input_dict['pointdefect_model'] is not None: ptd['key'] = input_dict['pointdefect_model']['key'] ptd['id'] = input_dict['pointdefect_model']['id'] ptd['system-family'] = input_dict.get('pointdefect_family', input_dict['family']) ptd['calculation-parameter'] = input_dict['calculation_params'] if results_dict is None: calc['status'] = 'not calculated' else: # Save measured phase state info calc['measured-phase-state'] = mps = DM() mps['temperature'] = uc.model(results_dict.get('temp', 0.0), 'K', results_dict.get('temp_std', None)) mps['pressure-xx'] = uc.model(results_dict['pxx'], input_dict['pressure_unit'], results_dict['pxx_std']) mps['pressure-yy'] = uc.model(results_dict['pyy'], input_dict['pressure_unit'], results_dict['pyy_std']) mps['pressure-zz'] = uc.model(results_dict['pzz'], input_dict['pressure_unit'], results_dict['pzz_std']) mps['potential-energy'] = uc.model(results_dict['Epot'], input_dict['pressure_unit'], results_dict['Epot_std']) # Save the calculation results calc['diffusion-rate'] = dr = DM() diffusion_unit = input_dict['length_unit'] + '^2/s' dr['total'] = uc.model(results_dict['d'], diffusion_unit) dr['x-direction'] = uc.model(results_dict['dx'], diffusion_unit) dr['y-direction'] = uc.model(results_dict['dy'], diffusion_unit) dr['z-direction'] = uc.model(results_dict['dz'], diffusion_unit) calc['number-of-atoms'] = results_dict['natoms'] self.content = output