def load_model(self, model, name=None): """ Loads record contents from a given model. Parameters ---------- model : str or DataModelDict The model contents of the record to load. name : str, optional The name to assign to the record. Often inferred from other attributes if not given. """ # Load universal and subset content super().load_model(model, name=name) calc = self.model[self.modelroot] # Load calculation-specific content run_params = calc['calculation']['run-parameter'] self.strainrange = run_params['strain-range'] # Load results if self.status == 'finished': self.__raw_Cij_negative = uc.value_unit(calc['raw-elastic-constants'][0]['Cij']) self.__raw_Cij_positive = uc.value_unit(calc['raw-elastic-constants'][1]['Cij']) Cij = uc.value_unit(calc['elastic-constants']['Cij']) self.__C = am.ElasticConstants(Cij=Cij)
def load_model(self, model, name=None): """ Loads record contents from a given model. Parameters ---------- model : str or DataModelDict The model contents of the record to load. name : str, optional The name to assign to the record. Often inferred from other attributes if not given. """ # Load universal and subset content super().load_model(model, name=name) calc = self.model[self.modelroot] # Load calculation-specific content run_params = calc['calculation']['run-parameter'] self.minimum_r = uc.value_unit(run_params['minimum_r']) self.maximum_r = uc.value_unit(run_params['maximum_r']) self.number_of_steps_r = run_params['number_of_steps_r'] # Load results if self.status == 'finished': scan = calc['cohesive-energy-relation'] self.r_values = uc.value_unit(scan['r']) self.a_values = uc.value_unit(scan['a']) self.energy_values = uc.value_unit(scan['cohesive-energy']) self.min_cells = [] for cell in calc.aslist('minimum-atomic-system'): self.min_cells.append(DM([('atomic-system', cell)]))
def load_model(self, model, name=None): """ Loads record contents from a given model. Parameters ---------- model : str or DataModelDict The model contents of the record to load. name : str, optional The name to assign to the record. Often inferred from other attributes if not given. """ # Load universal and subset content super().load_model(model, name=name) calc = self.model[self.modelroot] # Load calculation-specific content run_params = calc['calculation']['run-parameter'] self.minimum_r = uc.value_unit(run_params['minimum_r']) self.maximum_r = uc.value_unit(run_params['maximum_r']) self.number_of_steps_r = run_params['number_of_steps_r'] self.symbols = calc['system-info']['symbol'] # Load results if self.status == 'finished': scan = calc['diatom-energy-relation'] self.r_values = uc.value_unit(scan['r']) self.energy_values = uc.value_unit(scan['potential-energy'])
def load_model(self, model, name=None): """ Loads record contents from a given model. Parameters ---------- model : str or DataModelDict The model contents of the record to load. name : str, optional The name to assign to the record. Often inferred from other attributes if not given. """ # Load universal and subset content super().load_model(model, name=name) calc = self.model[self.modelroot] # Load results if self.status == 'finished': self.__dumpfile_base = calc['defect-free-system']['artifact']['file'] self.__potential_energy_base = uc.value_unit(calc['defect-free-system']['potential-energy']) self.__dumpfile_defect= calc['defect-system']['artifact']['file'] self.__potential_energy_defect = uc.value_unit(calc['defect-system']['potential-energy']) self.__potential_energy = uc.value_unit(calc['cohesive-energy']) self.__surface_energy = uc.value_unit(calc['free-surface-energy'])
def load_model(self, model, name=None): """ Loads record contents from a given model. Parameters ---------- model : str or DataModelDict The model contents of the record to load. name : str, optional The name to assign to the record. Often inferred from other attributes if not given. """ # Load universal and subset content super().load_model(model, name=name) calc = self.model[self.modelroot] # Load calculation-specific content run_params = calc['calculation']['run-parameter'] self.a1 = run_params['stackingfault_a1'] self.a2 = run_params['stackingfault_a2'] # Load results if self.status == 'finished': self.__dumpfile_base = calc['defect-free-system']['artifact'][ 'file'] self.__potential_energy_base = uc.value_unit( calc['defect-free-system']['potential-energy']) self.__dumpfile_defect = calc['defect-system']['artifact']['file'] self.__potential_energy_defect = uc.value_unit( calc['defect-system']['potential-energy']) self.__gsf_energy = uc.value_unit(calc['stacking-fault-energy']) self.__gsf_displacement = uc.value_unit(calc['plane-separation'])
def todict(self, record_model, params, full=True, flat=False): """ Converts the structured content to a simpler dictionary. Parameters ---------- record_model : DataModelDict.DataModelDict The record content (after root element) to interpret. params : dict The dictionary to add the interpreted content to full : bool, optional Flag used by the calculation records. A True value will include terms for both the calculation's input and results, while a value of False will only include input terms (Default is True). flat : bool, optional Flag affecting the format of the dictionary terms. If True, the dictionary terms are limited to having only str, int, and float values, which is useful for comparisons. If False, the term values can be of any data type, which is convenient for analysis. (Default is False). """ prefix = self.prefix modelprefix = prefix.replace('_', '-') run_params = record_model['calculation']['run-parameter'] params[f'{prefix}energytolerance'] = run_params[ f'{modelprefix}energytolerance'] params[f'{prefix}forcetolerance'] = uc.value_unit( run_params[f'{modelprefix}forcetolerance']) params[f'{prefix}maxiterations'] = run_params[ f'{modelprefix}maxiterations'] params[f'{prefix}maxevaluations'] = run_params[ f'{modelprefix}maxevaluations'] params[f'{prefix}maxatommotion'] = uc.value_unit( run_params[f'{modelprefix}maxatommotion'])
def todict(self, full=True, flat=False): """ Converts the structured content to a simpler dictionary. Parameters ---------- full : bool, optional Flag used by the calculation records. A True value will include terms for both the calculation's input and results, while a value of False will only include input terms (Default is True). flat : bool, optional Flag affecting the format of the dictionary terms. If True, the dictionary terms are limited to having only str, int, and float values, which is useful for comparisons. If False, the term values can be of any data type, which is convenient for analysis. (Default is False). Returns ------- dict A dictionary representation of the record's content. """ # Extract universal content params = super().todict(full=full, flat=flat) calc = self.content[self.contentroot] params['minimum_r'] = uc.value_unit( calc['calculation']['run-parameter']['minimum_r']) params['maximum_r'] = uc.value_unit( calc['calculation']['run-parameter']['maximum_r']) params['number_of_steps_r'] = calc['calculation']['run-parameter'][ 'number_of_steps_r'] # Extract potential info subset('lammps_potential').todict(calc, params, full=full, flat=flat) # Extract system info subset('atomman_systemload').todict(calc, params, full=full, flat=flat) subset('atomman_systemmanipulate').todict(calc, params, full=full, flat=flat) params['number_min_states'] = len(calc.aslist('minimum-atomic-system')) if params['status'] == 'not calculated': params['number_min_states'] = 1 if full is True and params['status'] == 'finished': if flat is False: plot = calc['cohesive-energy-relation'] er_plot = {} er_plot['r'] = uc.value_unit(plot['r']) er_plot['a'] = uc.value_unit(plot['a']) er_plot['E_coh'] = uc.value_unit(plot['cohesive-energy']) params['e_vs_r_plot'] = pd.DataFrame(er_plot) return params
def load(self, model, gamma=None): """ Load solution from a data model. Parameters ---------- model : str or DataModelDict The semi-discrete-Peierls-Nabarro data model to load. gamma : atomman.defect.GammaSurface, optional The gamma surface to use. If not given, will check to see if the content is inside model. Raises ------ ValueError If the gamma surface information is not given and it is not found in model. """ # Identify model element try: sdpn = DM(model).find('semidiscrete-variational-Peierls-Nabarro') except: sdpn = DM(model).find('semi-discrete-Peierls-Nabarro') # Load calculation parameters params = sdpn['parameter'] try: self.__transform = uc.value_unit(params['transform']) except: self.__transform = uc.value_unit(params['axes']) self.__K_tensor = uc.value_unit(params['K_tensor']) self.__burgers = uc.value_unit(params['burgers']) self.tau = uc.value_unit(params['tau']) self.alpha = uc.value_unit(params['alpha']) self.beta = uc.value_unit(params['beta']) self.cutofflongrange = uc.value_unit(params['cutofflongrange']) self.fullstress = params['fullstress'] self.cdiffelastic = params['cdiffelastic'] self.cdiffsurface = params['cdiffsurface'] self.cdiffstress = params['cdiffstress'] self.min_method = params['min_method'] self.min_options = params['min_options'] self.min_kwargs = params.get('min_kwargs', None) # Load gamma if gamma is None: try: gamma = GammaSurface(model) except: raise ValueError('No gamma surface in model or given!') elif not isinstance(gamma, GammaSurface): gamma = GammaSurface(gamma) self.__gamma = gamma # Load calculation solution solution = sdpn['solution'] self.x = uc.value_unit(solution['x']) self.disregistry = uc.value_unit(solution['disregistry'])
def todict(self, full=True, flat=False): """ Converts the structured content to a simpler dictionary. Parameters ---------- full : bool, optional Flag used by the calculation records. A True value will include terms for both the calculation's input and results, while a value of False will only include input terms (Default is True). flat : bool, optional Flag affecting the format of the dictionary terms. If True, the dictionary terms are limited to having only str, int, and float values, which is useful for comparisons. If False, the term values can be of any data type, which is convenient for analysis. (Default is False). Returns ------- dict A dictionary representation of the record's content. """ # Extract universal content params = super().todict(full=full, flat=flat) calc = self.content[self.contentroot] # Extract calculation-specific run parameters params['minimum_r'] = uc.value_unit(calc['calculation']['run-parameter']['minimum_r']) params['maximum_r'] = uc.value_unit(calc['calculation']['run-parameter']['maximum_r']) params['number_of_steps_r'] = calc['calculation']['run-parameter']['number_of_steps_r'] # Extract potential info subset('lammps_potential').todict(calc, params, full=full, flat=flat) # Extract symbols info symbols = aslist(calc['system-info']['symbol']) if flat is True: params['symbols'] = ' '.join(symbols) else: params['symbols'] = symbols # Set calculation status params['status'] = calc.get('status', 'finished') params['error'] = calc.get('error', np.nan) # Extract results if full is True and params['status'] == 'finished': if flat is False: plot = calc['diatom-energy-relation'] da_plot = {} da_plot['r'] = uc.value_unit(plot['r']) da_plot['energy'] = uc.value_unit(plot['potential-energy']) params['diatom_plot'] = pd.DataFrame(da_plot) return params
def todict(self, full=True, flat=False): """ Converts the structured content to a simpler dictionary. Parameters ---------- full : bool, optional Flag used by the calculation records. A True value will include terms for both the calculation's input and results, while a value of False will only include input terms (Default is True). flat : bool, optional Flag affecting the format of the dictionary terms. If True, the dictionary terms are limited to having only str, int, and float values, which is useful for comparisons. If False, the term values can be of any data type, which is convenient for analysis. (Default is False). Returns ------- dict A dictionary representation of the record's content. """ # Fetch universal record params params = super().todict(full=full, flat=flat) crystal = self.content[self.contentroot] params['method'] = crystal['method'] params['standing'] = crystal.get('standing', 'good') # Extract potential info subset('lammps_potential').todict(crystal, params, full=full, flat=flat) params['family'] = crystal['system-info']['family'] params['parent_key'] = crystal['system-info']['parent_key'] ucell = am.load('system_model', self.content, key='atomic-system') params['composition'] = ucell.composition #print('potential-energy' in crystal) if 'potential-energy' in crystal: params['E_pot'] = uc.value_unit(crystal['potential-energy']) params['E_coh'] = uc.value_unit(crystal['cohesive-energy']) else: params['E_coh'] = params['E_pot'] = uc.value_unit(crystal['cohesive-energy']) if flat is True: params['symbols'] = list(ucell.symbols) params['a'] = ucell.box.a params['b'] = ucell.box.b params['c'] = ucell.box.c params['alpha'] = ucell.box.alpha params['beta'] = ucell.box.beta params['gamma'] = ucell.box.gamma params['natoms'] = ucell.natoms else: params['ucell'] = ucell return params
def todict(self, full=True, flat=False): """ Converts the structured content to a simpler dictionary. Parameters ---------- full : bool, optional Flag used by the calculation records. A True value will include terms for both the calculation's input and results, while a value of False will only include input terms (Default is True). flat : bool, optional Flag affecting the format of the dictionary terms. If True, the dictionary terms are limited to having only str, int, and float values, which is useful for comparisons. If False, the term values can be of any data type, which is convenient for analysis. (Default is False). Returns ------- dict A dictionary representation of the record's content. """ # Extract universal content params = super().todict(full=full, flat=flat) calc = self.content[self.contentroot] # Extract minimization info subset('lammps_minimize').todict(calc, params, full=full, flat=flat) params['shiftfraction1'] = calc['calculation']['run-parameter'][ 'stackingfault_shiftfraction1'] params['shiftfraction2'] = calc['calculation']['run-parameter'][ 'stackingfault_shiftfraction2'] # Extract potential info subset('lammps_potential').todict(calc, params, full=full, flat=flat) # Extract system info subset('atomman_systemload').todict(calc, params, full=full, flat=flat) subset('atomman_systemmanipulate').todict(calc, params, full=full, flat=flat) subset('stackingfault').todict(calc, params, full=full, flat=flat) params['shiftvector1'] = calc['stacking-fault'][ 'calculation-parameter']['shiftvector1'] params['shiftvector2'] = calc['stacking-fault'][ 'calculation-parameter']['shiftvector2'] if full is True and params['status'] == 'finished': params['gamma_sf'] = uc.value_unit(calc['stacking-fault-energy']) params['delta_disp_sf'] = uc.value_unit(calc['plane-separation']) return params
def load_model(self, model): """Loads subset attributes from an existing model.""" run_params = model['calculation']['run-parameter'] self.energytolerance = run_params[f'{self.modelprefix}energytolerance'] self.forcetolerance = uc.value_unit(run_params[f'{self.modelprefix}forcetolerance']) self.maxiterations = run_params[f'{self.modelprefix}maxiterations'] self.maxevaluations = run_params[f'{self.modelprefix}maxevaluations'] self.maxatommotion = uc.value_unit(run_params[f'{self.modelprefix}maxatommotion'])
def todict(self, full=True, flat=False): """ Converts the structured content to a simpler dictionary. Parameters ---------- full : bool, optional Flag used by the calculation records. A True value will include terms for both the calculation's input and results, while a value of False will only include input terms (Default is True). flat : bool, optional Flag affecting the format of the dictionary terms. If True, the dictionary terms are limited to having only str, int, and float values, which is useful for comparisons. If False, the term values can be of any data type, which is convenient for analysis. (Default is False). Returns ------- dict A dictionary representation of the record's content. """ # Extract universal content params = super().todict(full=full, flat=flat) calc = self.content[self.contentroot] # Extract minimization info subset('lammps_minimize').todict(calc, params, full=full, flat=flat) # Extract potential info subset('lammps_potential').todict(calc, params, full=full, flat=flat) # Extract system info subset('atomman_systemload').todict(calc, params, full=full, flat=flat) subset('atomman_systemmanipulate').todict(calc, params, full=full, flat=flat) subset('pointdefect').todict(calc, params, full=full, flat=flat) if full is True and params['status'] == 'finished': params['E_f'] = uc.value_unit(calc['defect-formation-energy']) params['pij'] = uc.value_unit(calc['defect-elastic-dipole-tensor']) params['natoms'] = calc['number-of-atoms'] r_c = calc['reconfiguration-check'] params['reconfigured'] = r_c['has_reconfigured'] if flat is False: params['centrosummation'] = r_c['centrosummation'] params['position_shift'] = r_c.get('position_shift', np.nan) params['db_vect_shift'] = r_c.get('db_vect_shift', np.nan) return params
def todict(record, full=True): model = DM(record) calc = model['calculation-cohesive-energy-relation'] params = {} params['calc_key'] = calc['key'] params['calc_script'] = calc['calculation']['script'] params['minimum_r'] = uc.value_unit( calc['calculation']['run-parameter']['minimum_r']) params['maximum_r'] = uc.value_unit( calc['calculation']['run-parameter']['maximum_r']) params['number_of_steps_r'] = calc['calculation']['run-parameter'][ 'number_of_steps_r'] params['sizemults'] = calc['calculation']['run-parameter'][ 'size-multipliers'] params['sizemults'] = np.array([ params['sizemults']['a'], params['sizemults']['b'], params['sizemults']['c'] ]) params['potential_key'] = calc['potential']['key'] params['potential_id'] = calc['potential']['id'] params['load'] = '%s %s' % (calc['system-info']['artifact']['format'], calc['system-info']['artifact']['file']) params['prototype'] = calc['system-info']['artifact']['family'] params['symbols'] = aslist(calc['system-info']['symbols']) if full is True: if 'error' in calc: params['status'] = calc['status'] params['error'] = calc['error'] params['e_vs_r_plot'] = np.nan params['number_min_states'] = 0 elif 'status' in calc: params['status'] = calc['status'] params['error'] = np.nan params['e_vs_r_plot'] = np.nan params['number_min_states'] = 1 else: params['status'] = np.nan params['error'] = np.nan plot = calc['cohesive-energy-relation'] params['e_vs_r_plot'] = pd.DataFrame({ 'r': uc.value_unit(plot['r']), 'a': uc.value_unit(plot['a']), 'E_coh': uc.value_unit(plot['cohesive-energy']) }) params['number_min_states'] = len( calc.aslist('minimum-atomic-system')) return params
def todict(self, full=True, flat=False): """ Converts the structured content to a simpler dictionary. Parameters ---------- full : bool, optional Flag used by the calculation records. A True value will include terms for both the calculation's input and results, while a value of False will only include input terms (Default is True). flat : bool, optional Flag affecting the format of the dictionary terms. If True, the dictionary terms are limited to having only str, int, and float values, which is useful for comparisons. If False, the term values can be of any data type, which is convenient for analysis. (Default is False). Returns ------- dict A dictionary representation of the record's content. """ # Extract universal content params = super().todict(full=full, flat=flat) calc = self.content[self.contentroot] params['thermosteps']= calc['calculation']['run-parameter']['thermosteps'] params['dumpsteps'] = calc['calculation']['run-parameter']['dumpsteps'] params['runsteps'] = calc['calculation']['run-parameter']['runsteps'] params['randomseed'] = calc['calculation']['run-parameter']['randomseed'] params['boundarywidth'] = uc.value_unit(calc['calculation']['run-parameter']['boundarywidth']) params['rigidboundaries'] = calc['calculation']['run-parameter']['rigidboundaries'] params['stress_xz'] = uc.value_unit(calc['calculation']['run-parameter']['stress-xz']) params['stress_yz'] = uc.value_unit(calc['calculation']['run-parameter']['stress-yz']) # Extract potential info subset('lammps_potential').todict(calc, params, full=full, flat=flat) # Extract system info subset('atomman_systemload').todict(calc, params, full=full, flat=flat) params['temperature'] = uc.value_unit(calc['phase-state']['temperature']) if full is True and params['status'] == 'finished': params['strainrate_xz'] = uc.value_unit(calc['strain-rate-xz']) params['strainrate_yz'] = uc.value_unit(calc['strain-rate-yz']) if flat is True: pass else: plot = calc['strain-rate-relation'] sr_plot = {} sr_plot['t'] = uc.value_unit(plot['time']) sr_plot['strain_xz'] = uc.value_unit(plot['strain-xz']) sr_plot['strain_yz'] = uc.value_unit(plot['strain-yz']) params['strain_vs_time_plot'] = pd.DataFrame(sr_plot) return params
def test_model(self): box = am.Box.cubic(5.42) model = box.model() assert np.allclose(uc.value_unit(model['box']['avect']), np.array([5.42, 0.0, 0.0])) assert np.allclose(uc.value_unit(model['box']['bvect']), np.array([0.0, 5.42, 0.0])) assert np.allclose(uc.value_unit(model['box']['cvect']), np.array([0.0, 0.0, 5.42])) assert np.allclose(uc.value_unit(model['box']['origin']), np.array([0.0, 0.0, 0.0])) box = am.Box(model=model) assert np.allclose(box.vects, np.array([[5.42, 0.0, 0.0], [0.0, 5.42, 0.0], [0.0, 0.0, 5.42]]))
def load_model(self, model, name=None): """ Loads record contents from a given model. Parameters ---------- model : str or DataModelDict The model contents of the record to load. name : str, optional The name to assign to the record. Often inferred from other attributes if not given. """ # Load universal and subset content super().load_model(model, name=name) calc = self.model[self.modelroot] # Load results if self.status == 'finished': self.__dumpfile_base = calc['defect-free-system']['artifact'][ 'file'] self.__symbols_base = calc['defect-free-system']['symbols'] self.__potential_energy_base = uc.value_unit( calc['defect-free-system']['potential-energy']) self.__natoms_base = None self.__dumpfile_defect = calc['defect-system']['artifact']['file'] self.__symbols_defect = calc['defect-system']['symbols'] self.__potential_energy_defect = uc.value_unit( calc['defect-system']['potential-energy']) self.__natoms_defect = calc['number-of-atoms'] self.__potential_energy = uc.value_unit(calc['cohesive-energy']) self.__formation_energy = uc.value_unit( calc['defect-formation-energy']) self.__dipole_tensor = uc.value_unit( calc['defect-elastic-dipole-tensor']) # Save the reconfiguration checks r_c = calc['reconfiguration-check'] self.__has_reconfigured = r_c['has_reconfigured'] self.__centrosummation = np.array(r_c['centrosummation']) if 'position_shift' in r_c: self.__position_shift = np.array(r_c['position_shift']) else: self.__position_shift = None if 'db_vect_shift' in r_c: self.__db_vect_shift = np.array(r_c['db_vect_shift']) else: self.__db_vect_shift = None
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 todict(self, full=True, flat=False): """ Converts the structured content to a simpler dictionary. Parameters ---------- full : bool, optional Flag used by the calculation records. A True value will include terms for both the calculation's input and results, while a value of False will only include input terms (Default is True). flat : bool, optional Flag affecting the format of the dictionary terms. If True, the dictionary terms are limited to having only str, int, and float values, which is useful for comparisons. If False, the term values can be of any data type, which is convenient for analysis. (Default is False). Returns ------- dict A dictionary representation of the record's content. """ # Extract universal content params = super().todict(full=full, flat=flat) calc = self.content[self.contentroot] # Extract potential info subset('lammps_potential').todict(calc, params, full=full, flat=flat) # Set calculation status params['status'] = calc.get('status', 'finished') params['error'] = calc.get('error', np.nan) # Extract results if full is True and params['status'] == 'finished': if flat is True: for value in calc.aslist('isolated-atom-energy'): params[value['symbol']] = uc.value_unit(value['energy']) if flat is False: params['energy'] = {} for value in calc.aslist('isolated-atom-energy'): params['energy'][value['symbol']] = uc.value_unit( value['energy']) return params
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 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_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 todict(record, full=True, flat=False): model = DM(record) calc = model['calculation-grain-boundary-search'] params = {} params['calc_key'] = calc['key'] params['calc_script'] = calc['calculation']['script'] params['potential_key'] = calc['potential']['key'] params['potential_id'] = calc['potential']['id'] params['symbols'] = aslist(calc['system-info']['symbols']) params['x_axis_1'] = calc['grain-1']['crystallographic-axes']['x-axis'] params['y_axis_1'] = calc['grain-1']['crystallographic-axes']['y-axis'] params['z_axis_1'] = calc['grain-1']['crystallographic-axes']['z-axis'] params['x_axis_2'] = calc['grain-2']['crystallographic-axes']['x-axis'] params['y_axis_2'] = calc['grain-2']['crystallographic-axes']['y-axis'] params['z_axis_2'] = calc['grain-2']['crystallographic-axes']['z-axis'] params['status'] = calc.get('status', 'finished') if full is True: if params['status'] == 'error': params['error'] = calc['error'] elif params['status'] == 'not calculated': pass else: params['E_gb'] = uc.value_unit(calc['lowest-energy']['E_gb']) return params
def todict(record, full=True): model = DM(record) calc = model['calculation-grain-boundary-search'] params = {} params['calc_key'] = calc['key'] params['calc_script'] = calc['calculation']['script'] params['potential_key'] = calc['potential']['key'] params['potential_id'] = calc['potential']['id'] params['symbols'] = aslist(calc['system-info']['symbols']) params['x_axis_1'] = calc['grain-1']['crystallographic-axes']['x-axis'] params['y_axis_1'] = calc['grain-1']['crystallographic-axes']['y-axis'] params['z_axis_1'] = calc['grain-1']['crystallographic-axes']['z-axis'] params['x_axis_2'] = calc['grain-2']['crystallographic-axes']['x-axis'] params['y_axis_2'] = calc['grain-2']['crystallographic-axes']['y-axis'] params['z_axis_2'] = calc['grain-2']['crystallographic-axes']['z-axis'] if full is True: if 'error' in calc: params['status'] = calc['status'] params['error'] = calc['error'] params['E_gb'] = np.nan elif 'status' in calc: params['status'] = calc['status'] params['error'] = np.nan params['E_gb'] = np.nan else: params['status'] = np.nan params['error'] = np.nan params['E_gb'] = uc.value_unit(calc['lowest-energy']['E_gb']) return params
def load_model(self, model): """Loads subset attributes from an existing model.""" sf = model[self.modelroot] self.__model = None self.__param_file = None self.key = sf['key'] self.id = sf['id'] self.family = sf['system-family'] cp = sf['calculation-parameter'] self.hkl = cp['hkl'] self.a1vect_uvw = cp['a1vect_uvw'] self.a2vect_uvw = cp['a2vect_uvw'] self.shiftindex = int(cp['shiftindex']) self.cutboxvector = cp['cutboxvector'] self.faultpos_rel = float(cp['faultpos_rel']) self.cellsetting = cp['cellsetting'] run_params = model['calculation']['run-parameter'] a_mult = run_params[f'{self.modelprefix}size-multipliers']['a'][1] b_mult = run_params[f'{self.modelprefix}size-multipliers']['b'][1] c_mult = run_params[f'{self.modelprefix}size-multipliers']['c'][1] self.sizemults = [a_mult, b_mult, c_mult] self.minwidth = uc.value_unit( run_params[f'{self.modelprefix}minimum-width'])
def load(self, model, gamma=None): """ Load solution from a data model. Parameters ---------- model : str or DataModelDict The semi-discrete-Peierls-Nabarro data model to load. gamma : atomman.defect.GammaSurface The gamma surface to use. """ # Identify model element try: sdpn = DM(model).find('semidiscrete-variational-Peierls-Nabarro') except: sdpn = DM(model).find('semi-discrete-Peierls-Nabarro') # Load calculation parameters params = sdpn['parameter'] self.__axes = uc.value_unit(params['axes']) self.__K_tensor = uc.value_unit(params['K_tensor']) self.__tau = uc.value_unit(params['tau']) self.__alpha = uc.value_unit(params['alpha']) if not isinstance(self.__alpha, list): self.__alpha = [self.__alpha] self.__beta = uc.value_unit(params['beta']) self.__cutofflongrange = uc.value_unit(params['cutofflongrange']) self.__burgers = uc.value_unit(params['burgers']) self.__fullstress = params['fullstress'] self.__cdiffelastic = params['cdiffelastic'] self.__cdiffsurface = params['cdiffsurface'] self.__cdiffstress = params['cdiffstress'] self.__min_method = params['min_method'] self.__min_options = params['min_options'] # Load gamma if gamma is None: try: gamma = GammaSurface(model) except: raise ValueError('No gamma surface in model or given!') elif not isinstance(gamma, GammaSurface): gamma = GammaSurface(gamma) self.__gamma = gamma # Load calculation solution solution = sdpn['solution'] self.__x = uc.value_unit(solution['x']) self.__disregistry = uc.value_unit(solution['disregistry'])
def __init__(self, sp): self.__direction = sp['direction'] self.__error = sp.get('error', None) if self.__error is None: self.__coord = uc.value_unit(sp['minimum-energy-path']) #self.__path = self.gamma.path(self.coord) self.__usf_mep = uc.value_unit(sp['unstable-fault-energy-mep']) self.__usf_urp = uc.value_unit( sp['unstable-fault-energy-unrelaxed-path']) self.__shear_mep = uc.value_unit(sp['ideal-shear-stress-mep']) self.__shear_urp = uc.value_unit( sp['ideal-shear-stress-unrelaxed-path']) else: self.__coord = None #self.__path = None self.__usf_mep = None self.__usf_urp = None self.__shear_mep = None self.__shear_urp = None
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 load_model(self, model, name=None): """ Loads record contents from a given model. Parameters ---------- model : str or DataModelDict The model contents of the record to load. name : str, optional The name to assign to the record. Often inferred from other attributes if not given. """ # Load universal and subset content super().load_model(model, name=name) calc = self.model[self.modelroot] # Load calculation-specific content run_params = calc['calculation']['run-parameter'] self.minimum_r = uc.value_unit(run_params['minimum_r']) self.maximum_r = uc.value_unit(run_params['maximum_r']) self.number_of_steps_r = run_params['number_of_steps_r'] self.minimum_theta = run_params['minimum_theta'] self.maximum_theta = run_params['maximum_theta'] self.number_of_steps_theta = run_params['number_of_steps_theta'] self.symbols = calc['system-info']['symbol'] # Load results if self.status == 'finished': self.cluster = am.cluster.BondAngleMap(rmin=self.minimum_r, rmax=self.maximum_r, rnum=self.number_of_steps_r, thetamin=self.minimum_theta, thetamax=self.maximum_theta, thetanum=self.number_of_steps_theta, symbols=self.symbols) self.results_file = calc['calculation']['results']['file'] self.results_length_unit = calc['calculation']['results']['length_unit'] self.results_energy_unit = calc['calculation']['results']['energy_unit']
def load_model(self, model, name=None): """ Loads record contents from a given model. Parameters ---------- model : str or DataModelDict The model contents of the record to load. name : str, optional The name to assign to the record. Often inferred from other attributes if not given. """ # Load universal and subset content super().load_model(model, name=name) calc = self.model[self.modelroot] # Load calculation-specific content run_params = calc['calculation']['run-parameter'] self.boundaryshape = run_params['dislocation_boundaryshape'] self.boundarywidth = run_params['dislocation_boundarywidth'] self.boundaryscale = run_params['dislocation_boundaryscale'] self.annealtemperature = run_params['annealtemperature'] self.annealsteps = run_params['annealsteps'] # Load results if self.status == 'finished': self.__dumpfile_base = calc['base-system']['artifact']['file'] self.__symbols_base = calc['base-system']['symbols'] self.__dumpfile_defect = calc['defect-system']['artifact']['file'] self.__symbols_defect = calc['defect-system']['symbols'] self.__potential_energy_defect = uc.value_unit( calc['defect-system']['potential-energy']) elsol = calc['elastic-solution'] self.__preln = uc.value_unit(elsol['pre-ln-factor']) self.__K_tensor = uc.value_unit(elsol['K-tensor'])
def model(self, **kwargs): """ Return or set DataModelDict representation of the elastic constants. Keyword Arguments: model -- string or file-like object of json/xml model or DataModelDict. unit -- units to give values in. Default is None. crystal_system -- crystal system representation. Default is triclinic. If model is given, then model is converted into a DataModelDict and the elastic constants are read in if the model contains exactly one 'elastic-constants' branch. If model is not given, then a DataModelDict for the elastic constants is constructed. The values included will depend on the crystal system, and will be converted to the specified units. """ #Set values if model given if 'model' in kwargs: assert len(kwargs) == 1, 'no keyword arguments supported with model reading' model = DM(kwargs['model']).find('elastic-constants') 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: unit = kwargs.pop('unit', None) crystal_system = kwargs.pop('crystal_system', 'triclinic') assert len(kwargs) == 0, 'Invalid arguments' model = DM() model['elastic-constants'] = DM() model['elastic-constants']['C'] = C = [] c = uc.get_in_units(self.Cij, unit) c_dict = DM() if crystal_system == 'cubic': c_dict['1 1'] = (c[0,0] + c[1,1] + c[2,2]) / 3 c_dict['1 2'] = (c[0,1] + c[0,2] + c[1,2]) / 3 c_dict['4 4'] = (c[3,3] + c[4,4] + c[5,5]) / 3 elif crystal_system == 'hexagonal': c_dict['1 1'] = (c[0,0] + c[1,1]) / 2 c_dict['3 3'] = c[2,2] c_dict['1 2'] = (c[0,1] + (c[0,0] - 2*c[5,5])) / 2 c_dict['1 3'] = (c[0,2] + c[1,2]) / 2 c_dict['4 4'] = (c[3,3] + c[4,4]) / 2 elif crystal_system == 'tetragonal': c_dict['1 1'] = (c[0,0] + c[1,1]) / 2 c_dict['3 3'] = c[2,2] c_dict['1 2'] = c[0,1] c_dict['1 3'] = (c[0,2] + c[1,2]) / 2 c_dict['1 6'] = (c[0,5] - c[1,5]) / 2 c_dict['4 4'] = (c[3,3] + c[4,4]) / 2 c_dict['6 6'] = c[5,5] elif crystal_system == 'orthorhombic': c_dict['1 1'] = c[0,0] c_dict['2 2'] = c[1,1] c_dict['3 3'] = c[2,2] c_dict['1 2'] = c[0,1] c_dict['1 3'] = c[0,2] c_dict['2 3'] = c[1,2] c_dict['4 4'] = c[3,3] c_dict['5 5'] = c[4,4] c_dict['6 6'] = c[5,5] else: c_dict['1 1'] = c[0,0] c_dict['1 2'] = c[0,1] c_dict['1 3'] = c[0,2] c_dict['1 4'] = c[0,3] c_dict['1 5'] = c[0,4] c_dict['1 6'] = c[0,5] c_dict['2 2'] = c[1,1] c_dict['2 3'] = c[1,2] c_dict['2 4'] = c[1,3] c_dict['2 5'] = c[1,4] c_dict['2 6'] = c[1,5] c_dict['3 3'] = c[2,2] c_dict['3 4'] = c[2,3] c_dict['3 5'] = c[2,4] c_dict['3 6'] = c[2,5] c_dict['4 4'] = c[3,3] c_dict['4 5'] = c[3,4] c_dict['4 6'] = c[3,5] c_dict['5 5'] = c[4,4] c_dict['5 6'] = c[4,5] c_dict['6 6'] = c[5,5] for ij, value in c_dict.iteritems(): C.append(DM([('stiffness', DM([ ('value', value), ('unit', unit) ])), ('ij', ij) ]) ) return model
def load(model, symbols=None, key='atomic-system', index=0): """ Read in a data model containing a crystal structure. Parameters ---------- model : str, file-like object or DataModelDict The data model to read. symbols : tuple, optional Allows the list of element symbols to be assigned during loading. key : str, optional The key identifying the root element for the system definition. Default value is 'atomic-system'. index : int, optional. If the full model has multiple key entries, the index specifies which to access. Default value is 0 (first, or only entry). Returns ------- system : atomman.System The system object associated with the data model. """ # Pull system model out of data model using key and index a_sys = DM(model).finds(key) if len(a_sys) == 0: raise KeyError(key + ' not found in model') try: a_sys = a_sys[index] except: raise IndexError('Invalid index ' + str(index) + ' for model key ' + key) # Extract crystal system and box values c_system = list(a_sys['cell'].keys())[0] cell = a_sys['cell'][c_system] if c_system == 'cubic': a = b = c = uc.value_unit(cell['a']) alpha = beta = gamma = 90.0 elif c_system == 'hexagonal': a = b = uc.value_unit(cell['a']) c = uc.value_unit(cell['c']) alpha = beta = 90.0 gamma = 120.0 elif c_system == 'tetragonal': a = b = uc.value_unit(cell['a']) c = uc.value_unit(cell['c']) alpha = beta = gamma = 90.0 elif c_system == 'trigonal' or c_system == 'rhombohedral': a = b = c = uc.value_unit(cell['a']) alpha = beta = gamma = cell['alpha'] elif c_system == 'orthorhombic': a = uc.value_unit(cell['a']) b = uc.value_unit(cell['b']) c = uc.value_unit(cell['c']) alpha = beta = gamma = 90.0 elif c_system == 'monoclinic': a = uc.value_unit(cell['a']) b = uc.value_unit(cell['b']) c = uc.value_unit(cell['c']) alpha = gamma = 90.0 beta = cell['beta'] elif c_system == 'triclinic': a = uc.value_unit(cell['a']) b = uc.value_unit(cell['b']) c = uc.value_unit(cell['c']) alpha = cell['alpha'] beta = cell['beta'] gamma = cell['gamma'] box = Box(a=a, b=b, c=c, alpha=alpha, beta=beta, gamma=gamma) # Count atypes and generate list of symbols if given atoms = [] scale = None all_atypes = np.array(a_sys.finds('component')) all_symbols = np.array(a_sys.finds('symbol')) all_elements = np.array(a_sys.finds('element')) if len(all_atypes) == 0: if len(all_symbols) != 0: lsymbols, atypes = np.unique(all_symbols, return_inverse=True) elif len(all_elements) != 0: lsymbols, atypes = np.unique(all_elements, return_inverse=True) else: raise ValueError('No atom components, symbols or elements listed') else: atypes = all_atypes lsymbols = [None for i in range(max(all_atypes))] if len(all_elements) != 0 and len(all_symbols) == 0: all_symbols = all_elements if len(all_symbols) != 0: assert len(all_symbols) == len(atypes) sym_dict = {} for atype, symbol in zip(atypes, all_symbols): if atype not in sym_dict: sym_dict[atype] = symbol else: assert sym_dict[atype] == symbol for atype, symbol in iteritems(sym_dict): lsymbols[atype-1] = symbol # Use lsymbols if symbols parameter is not given. if symbols is None: symbols = lsymbols # Read per-atom properties natoms = len(atypes) prop = OrderedDict() prop['atype'] = atypes prop['pos'] = np.zeros((natoms, 3), dtype='float64') count = 0 pos_units = [] for atom in a_sys.iteraslist('atom'): # Read in pos for atom and unit info prop['pos'][count] = uc.value_unit(atom['position']) pos_units.append(atom['position'].get('unit', None)) # Add other per-atom properties for property in atom.iteraslist('property'): if property['name'] not in prop: value = uc.value_unit(property) shape = (natoms, ) + value.shape prop[property['name']] = np.zeros(shape, dtype=value.dtype) prop[property['name']][count] = uc.value_unit(property) count += 1 pos_unit = np.unique(pos_units) assert len(pos_unit) == 1, 'Mixed units for positions' if pos_unit[0] == 'scaled': scale=True else: scale=False atoms = Atoms(**prop) system = System(box=box, atoms=atoms, scale=scale, symbols=symbols) return system
def todict(self, full=True, flat=False): """ Converts the structured content to a simpler dictionary. Parameters ---------- full : bool, optional Flag used by the calculation records. A True value will include terms for both the calculation's input and results, while a value of False will only include input terms (Default is True). flat : bool, optional Flag affecting the format of the dictionary terms. If True, the dictionary terms are limited to having only str, int, and float values, which is useful for comparisons. If False, the term values can be of any data type, which is convenient for analysis. (Default is False). Returns ------- dict A dictionary representation of the record's content. """ calc = self.content[self.contentroot] params = {} params['key'] = calc['key'] params['script'] = calc['calculation']['script'] params['iprPy_version'] = calc['calculation']['iprPy-version'] params['LAMMPS_version'] = calc['calculation']['LAMMPS-version'] params['energytolerance']= calc['calculation']['run-parameter']['energytolerance'] params['forcetolerance'] = calc['calculation']['run-parameter']['forcetolerance'] params['maxiterations'] = calc['calculation']['run-parameter']['maxiterations'] params['maxevaluations'] = calc['calculation']['run-parameter']['maxevaluations'] params['maxatommotion'] = calc['calculation']['run-parameter']['maxatommotion'] sizemults = calc['calculation']['run-parameter']['size-multipliers'] params['potential_LAMMPS_key'] = calc['potential-LAMMPS']['key'] params['potential_LAMMPS_id'] = calc['potential-LAMMPS']['id'] params['potential_key'] = calc['potential-LAMMPS']['potential']['key'] params['potential_id'] = calc['potential-LAMMPS']['potential']['id'] params['load_file'] = calc['system-info']['artifact']['file'] params['load_style'] = calc['system-info']['artifact']['format'] params['load_options'] = calc['system-info']['artifact']['load_options'] params['family'] = calc['system-info']['family'] symbols = aslist(calc['system-info']['symbol']) params['surface_key'] = calc['free-surface']['key'] params['surface_id'] = calc['free-surface']['id'] if flat is True: params['a_mult1'] = sizemults['a'][0] params['a_mult2'] = sizemults['a'][1] params['b_mult1'] = sizemults['b'][0] params['b_mult2'] = sizemults['b'][1] params['c_mult1'] = sizemults['c'][0] params['c_mult2'] = sizemults['c'][1] params['symbols'] = ' '.join(symbols) else: params['sizemults'] = np.array([sizemults['a'], sizemults['b'], sizemults['c']]) params['symbols'] = symbols params['status'] = calc.get('status', 'finished') params['error'] = calc.get('error', np.nan) if full is True and params['status'] == 'finished': params['E_coh'] = uc.value_unit(calc['cohesive-energy']) params['gamma_fs'] = uc.value_unit(calc['free-surface-energy']) return params
def todict(self, full=True, flat=False): """ Converts the structured content to a simpler dictionary. Parameters ---------- full : bool, optional Flag used by the calculation records. A True value will include terms for both the calculation's input and results, while a value of False will only include input terms (Default is True). flat : bool, optional Flag affecting the format of the dictionary terms. If True, the dictionary terms are limited to having only str, int, and float values, which is useful for comparisons. If False, the term values can be of any data type, which is convenient for analysis. (Default is False). Returns ------- dict A dictionary representation of the record's content. """ calc = self.content[self.contentroot] params = {} params['key'] = calc['key'] params['script'] = calc['calculation']['script'] params['iprPy_version'] = calc['calculation']['iprPy-version'] params['LAMMPS_version'] = calc['calculation']['LAMMPS-version'] params['strainrange'] = calc['calculation']['run-parameter']['strain-range'] sizemults = calc['calculation']['run-parameter']['size-multipliers'] params['potential_LAMMPS_key'] = calc['potential-LAMMPS']['key'] params['potential_LAMMPS_id'] = calc['potential-LAMMPS']['id'] params['potential_key'] = calc['potential-LAMMPS']['potential']['key'] params['potential_id'] = calc['potential-LAMMPS']['potential']['id'] params['load_file'] = calc['system-info']['artifact']['file'] params['load_style'] = calc['system-info']['artifact']['format'] params['load_options'] = calc['system-info']['artifact']['load_options'] params['family'] = calc['system-info']['family'] symbols = aslist(calc['system-info']['symbol']) if flat is True: params['a_mult1'] = sizemults['a'][0] params['a_mult2'] = sizemults['a'][1] params['b_mult1'] = sizemults['b'][0] params['b_mult2'] = sizemults['b'][1] params['c_mult1'] = sizemults['c'][0] params['c_mult2'] = sizemults['c'][1] params['symbols'] = ' '.join(symbols) else: params['sizemults'] = np.array([sizemults['a'], sizemults['b'], sizemults['c']]) params['symbols'] = symbols params['status'] = calc.get('status', 'finished') params['error'] = calc.get('error', np.nan) if full is True and params['status'] == 'finished': cij = uc.value_unit(calc['elastic-constants']['Cij']) if flat is True: params['C11'] = cij[0,0] params['C12'] = cij[0,1] params['C13'] = cij[0,2] params['C14'] = cij[0,3] params['C15'] = cij[0,4] params['C16'] = cij[0,5] params['C22'] = cij[1,1] params['C23'] = cij[1,2] params['C24'] = cij[1,3] params['C25'] = cij[1,4] params['C26'] = cij[1,5] params['C33'] = cij[2,2] params['C34'] = cij[2,3] params['C35'] = cij[2,4] params['C36'] = cij[2,5] params['C44'] = cij[3,3] params['C45'] = cij[3,4] params['C46'] = cij[3,5] params['C55'] = cij[4,4] params['C56'] = cij[4,5] params['C66'] = cij[5,5] else: params['raw_cij_negative'] = uc.value_unit(calc['raw-elastic-constants'][0]['Cij']) params['raw_cij_positive'] = uc.value_unit(calc['raw-elastic-constants'][1]['Cij']) params['C'] = am.ElasticConstants(Cij=cij) return params
def todict(self, full=True, flat=False): """ Converts the structured content to a simpler dictionary. Parameters ---------- full : bool, optional Flag used by the calculation records. A True value will include terms for both the calculation's input and results, while a value of False will only include input terms (Default is True). flat : bool, optional Flag affecting the format of the dictionary terms. If True, the dictionary terms are limited to having only str, int, and float values, which is useful for comparisons. If False, the term values can be of any data type, which is convenient for analysis. (Default is False). Returns ------- dict A dictionary representation of the record's content. """ calc = self.content[self.contentroot] params = {} params['key'] = calc['key'] params['script'] = calc['calculation']['script'] params['iprPy_version'] = calc['calculation']['iprPy-version'] params['LAMMPS_version'] = calc['calculation']['LAMMPS-version'] params['thermosteps']= calc['calculation']['run-parameter']['thermosteps'] params['runsteps'] = calc['calculation']['run-parameter']['runsteps'] params['randomseed'] = calc['calculation']['run-parameter']['randomseed'] sizemults = calc['calculation']['run-parameter']['size-multipliers'] params['potential_LAMMPS_key'] = calc['potential-LAMMPS']['key'] params['potential_LAMMPS_id'] = calc['potential-LAMMPS']['id'] params['potential_key'] = calc['potential-LAMMPS']['potential']['key'] params['potential_id'] = calc['potential-LAMMPS']['potential']['id'] params['load_file'] = calc['system-info']['artifact']['file'] params['load_style'] = calc['system-info']['artifact']['format'] params['load_options'] = calc['system-info']['artifact']['load_options'] params['family'] = calc['system-info']['family'] symbols = aslist(calc['system-info']['symbol']) params['pointdefect_key'] = calc['point-defect']['key'] params['pointdefect_id'] = calc['point-defect']['id'] params['temperature'] = uc.value_unit(calc['phase-state']['temperature']) if flat is True: params['a_mult1'] = sizemults['a'][0] params['a_mult2'] = sizemults['a'][1] params['b_mult1'] = sizemults['b'][0] params['b_mult2'] = sizemults['b'][1] params['c_mult1'] = sizemults['c'][0] params['c_mult2'] = sizemults['c'][1] params['symbols'] = ' '.join(symbols) else: params['sizemults'] = np.array([sizemults['a'], sizemults['b'], sizemults['c']]) params['symbols'] = symbols params['status'] = calc.get('status', 'finished') params['error'] = calc.get('error', np.nan) if full is True and params['status'] == 'finished': params['measured_temperature'] = uc.value_unit(calc['measured-phase-state']['temperature']) params['measured_pressure_xx'] = uc.value_unit(calc['measured-phase-state']['pressure-xx']) params['measured_pressure_xx_std'] = uc.error_unit(calc['measured-phase-state']['pressure-xx']) params['measured_pressure_yy'] = uc.value_unit(calc['measured-phase-state']['pressure-yy']) params['measured_pressure_yy_std'] = uc.error_unit(calc['measured-phase-state']['pressure-yy']) params['measured_pressure_zz'] = uc.value_unit(calc['measured-phase-state']['pressure-zz']) params['measured_pressure_zz_std'] = uc.error_unit(calc['measured-phase-state']['pressure-zz']) params['measured_potential_energy'] = uc.value_unit(calc['measured-phase-state']['potential-energy']) params['measured_potential_energy_std'] = uc.error_unit(calc['measured-phase-state']['potential-energy']) params['d'] = uc.value_unit(calc['diffusion-rate']['total']) params['dx'] = uc.value_unit(calc['diffusion-rate']['x-direction']) params['dy'] = uc.value_unit(calc['diffusion-rate']['y-direction']) params['dz'] = uc.value_unit(calc['diffusion-rate']['z-direction']) params['natoms'] = calc['number-of-atoms'] return params
def todict(self, full=True, flat=False): """ Converts the structured content to a simpler dictionary. Parameters ---------- full : bool, optional Flag used by the calculation records. A True value will include terms for both the calculation's input and results, while a value of False will only include input terms (Default is True). flat : bool, optional Flag affecting the format of the dictionary terms. If True, the dictionary terms are limited to having only str, int, and float values, which is useful for comparisons. If False, the term values can be of any data type, which is convenient for analysis. (Default is False). Returns ------- dict A dictionary representation of the record's content. """ calc = self.content[self.contentroot] params = {} params['key'] = calc['key'] params['script'] = calc['calculation']['script'] params['iprPy_version'] = calc['calculation']['iprPy-version'] params['atomman_version'] = calc['calculation']['atomman-version'] rp = calc['calculation']['run-parameter'] params['halfwidth'] = uc.value_unit(rp['halfwidth']) params['xmax'] = rp['xmax'] params['xnum'] = rp['xnum'] params['xstep'] = rp['xstep'] params['load_file'] = calc['system-info']['artifact']['file'] params['load_style'] = calc['system-info']['artifact']['format'] params['load_options'] = calc['system-info']['artifact']['load_options'] params['family'] = calc['system-info']['family'] symbols = aslist(calc['system-info']['symbol']) params['dislocation_key'] = calc['dislocation-monopole']['key'] params['dislocation_id'] = calc['dislocation-monopole']['id'] params['gammasurface_calc_key'] = calc['gamma-surface']['calc_key'] pnp = calc['semidiscrete-variational-Peierls-Nabarro']['parameter'] try: K_tensor = uc.value_unit(pnp['K_tensor']) except: K_tensor = np.nan tau = uc.value_unit(pnp['tau']) alpha = uc.value_unit(pnp['alpha']) beta = uc.value_unit(pnp['beta']) params['cdiffelastic'] = pnp['cdiffelastic'] params['cdiffsurface'] = pnp['cdiffsurface'] params['cdiffstress'] = pnp['cdiffstress'] params['cutofflongrange'] = uc.value_unit(pnp['cutofflongrange']) params['fullstress'] = pnp['fullstress'] params['min_method'] = pnp['min_method'] params['min_options'] = pnp['min_options'] if flat is True: params['symbols'] = ' '.join(symbols) for i in range(3): for j in range(i,3): try: params['K'+str(i+1)+str(j+1)] = K_tensor[i,j] except: params['K'+str(i+1)+str(j+1)] = np.nan params['tau'+str(i+1)+str(j+1)] = tau[i,j] params['beta'+str(i+1)+str(j+1)] = beta[i,j] if not isinstance(alpha, list): alpha = [alpha] for i in range(len(alpha)): params['alpha'+str(i+1)] = alpha[i] else: params['symbols'] = symbols params['K_tensor'] = K_tensor params['tau'] = tau params['alpha'] = alpha params['beta'] = beta params['status'] = calc.get('status', 'finished') if full is True: if params['status'] == 'error': params['error'] = calc['error'] elif params['status'] == 'not calculated': pass else: if flat is True: pass else: try: params['C'] = am.ElasticConstants(model=calc) except: params['C'] = np.nan if True: params['SDVPN_model'] = DM() params['SDVPN_model']['semidiscrete-variational-Peierls-Nabarro'] = calc.find('semidiscrete-variational-Peierls-Nabarro') else: params['SDVPN_model'] = np.nan return params
def todict(self, full=True, flat=False): """ Converts the structured content to a simpler dictionary. Parameters ---------- full : bool, optional Flag used by the calculation records. A True value will include terms for both the calculation's input and results, while a value of False will only include input terms (Default is True). flat : bool, optional Flag affecting the format of the dictionary terms. If True, the dictionary terms are limited to having only str, int, and float values, which is useful for comparisons. If False, the term values can be of any data type, which is convenient for analysis. (Default is False). Returns ------- dict A dictionary representation of the record's content. """ calc = self.content[self.contentroot] params = {} params['key'] = calc['key'] params['script'] = calc['calculation']['script'] params['iprPy_version'] = calc['calculation']['iprPy-version'] params['LAMMPS_version'] = calc['calculation']['LAMMPS-version'] params['energytolerance']= calc['calculation']['run-parameter']['energytolerance'] params['forcetolerance'] = calc['calculation']['run-parameter']['forcetolerance'] params['maxiterations'] = calc['calculation']['run-parameter']['maxiterations'] params['maxevaluations'] = calc['calculation']['run-parameter']['maxevaluations'] params['maxatommotion'] = calc['calculation']['run-parameter']['maxatommotion'] params['annealtemperature'] = calc['calculation']['run-parameter']['annealtemperature'] sizemults = calc['calculation']['run-parameter']['size-multipliers'] params['potential_LAMMPS_key'] = calc['potential-LAMMPS']['key'] params['potential_LAMMPS_id'] = calc['potential-LAMMPS']['id'] params['potential_key'] = calc['potential-LAMMPS']['potential']['key'] params['potential_id'] = calc['potential-LAMMPS']['potential']['id'] params['load_file'] = calc['system-info']['artifact']['file'] params['load_style'] = calc['system-info']['artifact']['format'] params['load_options'] = calc['system-info']['artifact']['load_options'] params['family'] = calc['system-info']['family'] symbols = aslist(calc['system-info']['symbol']) params['dislocation_key'] = calc['dislocation-monopole']['key'] params['dislocation_id'] = calc['dislocation-monopole']['id'] if flat is True: params['a_mult1'] = sizemults['a'][0] params['a_mult2'] = sizemults['a'][1] params['b_mult1'] = sizemults['b'][0] params['b_mult2'] = sizemults['b'][1] params['c_mult1'] = sizemults['c'][0] params['c_mult2'] = sizemults['c'][1] params['symbols'] = ' '.join(symbols) else: params['sizemults'] = np.array([sizemults['a'], sizemults['b'], sizemults['c']]) params['symbols'] = symbols params['status'] = calc.get('status', 'finished') params['error'] = calc.get('error', np.nan) K_tensor = uc.value_unit(calc['Stroh-K-tensor']) if full is True and params['status'] == 'finished': params['preln'] = uc.value_unit(calc['Stroh-pre-ln-factor']) if flat is True: for C in calc['elastic-constants'].aslist('C'): params['C'+str(C['ij'][0])+str(C['ij'][2])] = uc.value_unit(C['stiffness']) params['K11'] = K_tensor[0,0] params['K12'] = K_tensor[0,1] params['K13'] = K_tensor[0,2] params['K22'] = K_tensor[1,1] params['K23'] = K_tensor[1,2] params['K33'] = K_tensor[2,2] else: try: params['C'] = am.ElasticConstants(model=calc) except: params['C'] = 'Invalid' params['K_tensor'] = K_tensor return params
def load(model, key='atomic-system', index=0): """Read in a data model containing a crystal-structure and return a System unit cell.""" if isinstance(model, (str, unicode)) and os.path.isfile(model): with open(model) as f: model = f.read() #Pull system model out of data model using key and index a_sys = DataModelDict(model).finds(key) if len(a_sys) == 0: raise KeyError(key + ' not found in model') try: a_sys = a_sys[index] except: raise IndexError('Invalid index ' + str(index) + ' for model key ' + key) #identify the crystal system c_system = a_sys['cell'].keys()[0] cell = a_sys['cell'][c_system] if c_system == 'cubic': a = b = c = uc.value_unit(cell['a']) alpha = beta = gamma = 90.0 elif c_system == 'hexagonal': a = b = uc.value_unit(cell['a']) c = uc.value_unit(cell['c']) alpha = beta = 90.0 gamma = 120.0 elif c_system == 'tetragonal': a = b = uc.value_unit(cell['a']) c = uc.value_unit(cell['c']) alpha = beta = gamma = 90.0 elif c_system == 'trigonal' or c_system == 'rhombohedral': a = b = c = uc.value_unit(cell['a']) alpha = beta = gamma = cell['alpha'] elif c_system == 'orthorhombic': a = uc.value_unit(cell['a']) b = uc.value_unit(cell['b']) c = uc.value_unit(cell['c']) alpha = beta = gamma = 90.0 elif c_system == 'monoclinic': a = uc.value_unit(cell['a']) b = uc.value_unit(cell['b']) c = uc.value_unit(cell['c']) alpha = gamma = 90.0 beta = cell['beta'] elif c_system == 'triclinic': a = uc.value_unit(cell['a']) b = uc.value_unit(cell['b']) c = uc.value_unit(cell['c']) alpha = cell['alpha'] beta = cell['beta'] gamma = cell['gamma'] box = am.Box(a=a, b=b, c=c, alpha=alpha, beta=beta, gamma=gamma) #create list of atoms and list of elements atoms = [] scale = None prop = DataModelDict() all_atypes = np.array(a_sys.finds('component')) all_symbols = np.array(a_sys.finds('symbol')) all_elements = np.array(a_sys.finds('element')) if len(all_atypes) == 0: if len(all_symbols) != 0: symbols, atypes = np.unique(all_symbols, return_inverse) elif len(all_elements) != 0: symbols, atypes = np.unique(all_elements, return_inverse) else: raise ValueError('No atom components, symbols or elements listed') else: atypes = all_atypes symbols = [None for i in xrange(max(all_atypes))] if len(all_elements) != 0 and len(all_symbols) == 0: all_symbols = all_elements if len(all_symbols) != 0: assert len(all_symbols) == len(atypes) sym_dict = {} for atype, symbol in zip(atypes, all_symbols): if atype not in sym_dict: sym_dict[atype] = symbol else: assert sym_dict[atype] == symbol for atype, symbol in sym_dict.iteritems(): symbols[atype-1] = symbol prop['atype'] = atypes prop['pos'] = np.zeros((len(prop['atype']), 3), dtype='float64') count = 0 pos_units = [] for atom in a_sys.iteraslist('atom'): #read in pos for atom and unit info prop['pos'][count] = uc.value_unit(atom['position']) pos_units.append(atom['position'].get('unit', None)) #Add per-atom properties for property in atom.iteraslist('property'): if property['name'] not in prop: value = uc.value_unit(property) prop[property['name']] = np.zeros((len(prop['atype']), len(value)), dtype=value.dtype) prop[property['name']][count] = uc.value_unit(property) count += 1 pos_unit = np.unique(pos_units) assert len(pos_unit) == 1, 'Mixed units for positions' if pos_unit[0] == 'scaled': scale=True else: scale=False atoms = am.Atoms(natoms=len(prop['atype']), prop=prop) system = am.System(box=box, atoms=atoms, scale=scale) return system, symbols