def set_opt_params(self, **kwargs): """ Set the parameters that will be optimized. One or more parameters can be set. Each argument is for one parameter, where the argument name is the parameter name, the value of the argument is the settings(including initial value, fix flag, lower bound, and upper bound). The value of the argument should be a list of list, where each inner list is for one component of the parameter, which can contain 1, 2, or 3 elements. See `~kliff.model.model.Model.read_opt_params()` for the options of the elements. Example: instance.set(A=[['DEFAULT'], [2.0, 1.0, 3.0]], B=[[1.0, 'FIX'], [2.0, 'INF', 3.0]]) """ self.opt_params.set(**kwargs) # update kim internal model param (note, set_one will update model_params) for name, _ in kwargs.items(): p_idx = self.model_params[name].index for c_idx, v in enumerate(self.model_params[name].value): try: self.kim_model.set_parameter(p_idx, c_idx, v) except RuntimeError: raise kimpy.KimPyError( "Calling `kim_model.set_parameter()` failed.") try: self.kim_model.clear_then_refresh() except RuntimeError: raise kimpy.KimPyError( "Calling `kim_model.clear_then_refresh()` failed.") # reset influence distance in case it changes self.init_influence_distance()
def names_for_collection(collection, collections): for it in ( kimpy.collection_item_type.modelDriver, kimpy.collection_item_type.portableModel, kimpy.collection_item_type.simulatorModel, ): try: extent = collections.cache_list_of_item_names_by_collection_and_type( collection, it ) except RuntimeError: msg = 'Calling "collections.' msg += 'cache_list_of_item_names_by_collection_and_type" failed.' raise kimpy.KimPyError(msg) print('{}:{}:'.format(str(collection), str(it))) for i in range(extent): try: name = collections.get_item_name_by_collection_and_type(i) except RuntimeError: msg = 'Calling "collections.' msg += 'get_item_name_by_collection_and_type" for index = ' msg += '{} failed.'.format(i) raise kimpy.KimPyError(msg) print(' ', name)
def init_supported_species(self) -> Dict[str, int]: species = {} try: num_kim_species = kimpy.species_name.get_number_of_species_names() except RuntimeError: raise kimpy.KimPyError( "Calling `kimpy.species_name.get_number_of_species_names()` failed." ) for i in range(num_kim_species): try: species_name = kimpy.species_name.get_species_name(i) except RuntimeError: raise kimpy.KimPyError( "Calling `kimpy.species_name.get_species_name()` failed.") try: supported, code = self.kim_model.get_species_support_and_code( species_name) except RuntimeError: raise kimpy.KimPyError( "Calling `kim_model.get_species_support_and_code()` failed." ) if supported: species[str(species_name)] = code return species
def get_kim_model_params(self) -> Dict[str, Parameter]: """ Inquire the KIM model to get all the parameters. Returns: {name, parameter}, all parameters in a kim model. """ try: num_params = self.kim_model.get_number_of_parameters() except RuntimeError: raise kimpy.KimPyError( "Calling `kim_model.get_number_of_parameters()` failed.") params = dict() for i in range(num_params): try: ( dtype, extent, name, description, ) = self.kim_model.get_parameter_metadata(i) except RuntimeError: raise kimpy.KimPyError( "Calling `kim_model.get_parameter_metadata()` failed.") values = [] for j in range(extent): if str(dtype) == "Double": try: val = self.kim_model.get_parameter_double(i, j) except RuntimeError: raise kimpy.KimPyError( "Calling `kim_model.get_parameter_double()` failed." ) values.append(val) elif str(dtype) == "Int": try: val = self.kim_model.get_parameter_int(i, j) except RuntimeError: raise kimpy.KimPyError( "Calling `kim_model.get_parameter_int()` failed.") values.append(val) else: # should never reach here KIMModelError( f"get unexpected parameter data type `{dtype}`") params[name] = Parameter(value=values, index=i) return params
def update_model_params(self, params: Sequence[float]): """ Update optimizing parameters (a sequence used by the optimizer) to the kim model. """ # update from opt params to model params # TODO, in super().update_model_params(), we have parameter relation set, # these parameters need to be updated here as well. However, in general # we do not know how parameters are modified in parameter_relation, # and it seems the only hope is to keep a copy of parameters and do some # comparison to check which are modified and then set them. super().update_model_params(params) # update from model params to kim params n = self.get_num_opt_params() for i in range(n): _, value, p_idx, c_idx = self.get_opt_param_name_value_and_indices( i) try: self.kim_model.set_parameter(p_idx, c_idx, value) except RuntimeError: raise kimpy.KimPyError( "Calling `kim_model.set_parameter()` failed.") # refresh model self.kim_model.clear_then_refresh() if get_log_level() == "DEBUG": params = self.get_kim_model_params() s = "" for name, p in params.items(): s += f"\nname: {name}\n" s += str(p.as_dict()) logger.debug(s)
def test_main(): N = kimpy.compute_argument_name.get_number_of_compute_argument_names() assert N == 9 all_instances = [] for i in range(N): try: inst = kimpy.compute_argument_name.get_compute_argument_name(i) except RuntimeError: msg = 'Calling "kimpy.compute_argument_name.' msg += 'get_compute_argument_name" failed.' raise kimpy.KimPyError(msg) assert inst == attributes[i] assert str(inst) == str_names[i] all_instances.append(inst) try: dtype = kimpy.compute_argument_name.get_compute_argument_data_type( inst) except RuntimeError: msg = 'Calling "kimpy.compute_argument_name.' msg += 'get_compute_argument_data_type" failed.' raise kimpy.KimPyError(msg) assert dtype == data_types[i] # test operator overloading for i in range(N): assert all_instances[i] == all_instances[i] for j in range(i + 1, N): assert all_instances[i] != all_instances[j] # test known for inst in all_instances: assert inst.known() # test out of bound capture_out_of_bound_error = False try: inst = kimpy.compute_argument_name.get_compute_argument_name(N) except RuntimeError: capture_out_of_bound_error = True assert capture_out_of_bound_error
def _init_neigh(self): # create neighbor list try: neigh = nl.create() except RuntimeError: raise kimpy.KimPyError("Calling `nl.create()` failed.") # register get neigh callback try: self.kim_ca.set_callback_pointer( kimpy.compute_callback_name.GetNeighborList, nl.get_neigh_kim(), neigh) except RuntimeError: raise kimpy.KimPyError( "Calling `kim_ca.set_callback_pointer()` failed.") self.neigh = neigh
def create_a_kim_compute_argument(self): """ Create a compute argument for the KIM model. """ try: kim_ca = self.kim_model.compute_arguments_create() except RuntimeError: raise kimpy.KimPyError( "Calling `kim_model.compute_arguments_create()` failed.") return kim_ca
def test_main(): version = kimpy.sem_ver.get_sem_ver() try: is_less_than = kimpy.sem_ver.is_less_than('2.0.1', '2.1.0') except RuntimeError: msg = 'Calling "kimpy.sem_ver.is_less_than" failed.' raise kimpy.KimPyError(msg) assert is_less_than == 1 try: version_related = kimpy.sem_ver.parse_sem_ver(version) except RuntimeError: msg = 'Calling "kimpy.sem_ver.parse_sem_ver" failed.' raise kimpy.KimPyError(msg) version_rebuilt_1 = '{}.{}.{}{}+{}'.format(*version_related) version_rebuilt_2 = '{}.{}.{}-{}+{}'.format(*version_related) assert version in (version_rebuilt_1, version_rebuilt_2)
def set_one_opt_param(self, name: str, settings: List[List[Any]]): """ Set one parameter that will be optimized. The name of the parameter should be given as the first entry of a list (or tuple), and then each data line should be given in in a list. Args: name: name of a fitting parameter settings: initial value, flag to fix a parameter, lower and upper bounds of a parameter. Example: name = 'param_A' settings = [['default', 0, 20], [2.0, 'fix'], [2.2, 'inf', 3.3]] instance.set_one(name, settings) """ self.opt_params.set_one(name, settings) # update kim internal model param (note, set_one will update model_params) p_idx = self.model_params[name].index for c_idx, v in enumerate(self.model_params[name].value): try: self.kim_model.set_parameter(p_idx, c_idx, v) except RuntimeError: raise kimpy.KimPyError( "Calling `kim_model.set_parameter()` failed.") try: self.kim_model.clear_then_refresh() except RuntimeError: raise kimpy.KimPyError( "Calling `kim_model.clear_then_refresh()` failed.") # reset influence distance in case it changes self.init_influence_distance()
def compute(self, kim_model): try: kim_model.compute(self.kim_ca) except RuntimeError: raise kimpy.KimPyError("Calling `kim_model.compute()` failed.") if self.compute_energy: self.results["energy"] = self.energy[0] if self.compute_forces: forces = assemble_forces(self.forces, self.num_contributing_particles, self.padding_image_of) self.results["forces"] = forces if self.compute_stress: volume = self.conf.get_volume() stress = assemble_stress(self.coords, self.forces, volume) self.results["stress"] = stress
def _create_kim_model(model_name: str): """ Create a new kim model. """ try: units_accepted, model = kimpy.model.create( kimpy.numbering.zeroBased, kimpy.length_unit.A, kimpy.energy_unit.eV, kimpy.charge_unit.e, kimpy.temperature_unit.K, kimpy.time_unit.ps, model_name, ) except RuntimeError: raise kimpy.KimPyError("Calling `kimpy.model.create()` failed.") if not units_accepted: KIMModelError("requested units not accepted in kimpy.model.create") return model
def get_neigh(data, cutoffs, neighbor_list_index, particle_number): error = 0 # we only support one neighbor list rcut = data['cutoff'] if len(cutoffs) != 1 or cutoffs[0] > rcut: error = 1 if neighbor_list_index != 0: error = 1 # invalid id number_of_particles = data['num_particles'] if particle_number >= number_of_particles or particle_number < 0: error = 1 if error == 1: raise kimpy.KimPyError('Calling "get_neigh" failed.') neighbors = data['neighbors'][particle_number] return (neighbors, error)
def _get_implemented_property(self): """ Get implemented property of model. """ # check compute arguments try: kim_can = kimpy.compute_argument_name N = kim_can.get_number_of_compute_argument_names() except RuntimeError: raise kimpy.KimPyError( "Calling `kim_can.get_number_of_compute_argument_names()` failed." ) for i in range(N): try: name = kim_can.get_compute_argument_name(i) except RuntimeError: raise kimpy.KimPyError( "Calling `kim_can.get_compute_argument_name()` failed.") # dtype = kim_can.get_compute_argument_data_type(name) try: support_status = self.kim_ca.get_argument_support_status(name) except RuntimeError: raise kimpy.KimPyError( "Calling `kim_ca.get_argument_support_status()` failed.") # calculator can only handle energy and forces if support_status == kimpy.support_status.required: if name != kim_can.partialEnergy and name != kim_can.partialForces: KIMModelError( f"Unsupported required ComputeArgument `{name}`") # supported property if name == kim_can.partialEnergy: self.implemented_property.append("energy") elif name == kim_can.partialForces: self.implemented_property.append("forces") self.implemented_property.append("stress") # check compute callbacks kim_ccn = kimpy.compute_callback_name try: num_callbacks = kim_ccn.get_number_of_compute_callback_names() except RuntimeError: raise kimpy.KimPyError( "Calling `kim_ccn.get_number_of_compute_callback_names()` failed." ) for i in range(num_callbacks): try: name = kim_ccn.get_compute_callback_name(i) except RuntimeError: raise kimpy.KimPyError( "Calling `kim_ccn.get_compute_callback_name()` failed.") try: support_status = self.kim_ca.get_callback_support_status(name) except RuntimeError: raise kimpy.KimPyError( "Calling `kim_ca.get_callback_support_status()` failed.") # calculator only provides get_neigh if support_status == kimpy.support_status.required: if name != kim_ccn.GetNeighborList: KIMModelError( f"Unsupported required ComputeCallback `{name}`")
def example_main(): try: collections = kimpy.collections.create() except RuntimeError: msg = 'Calling "kimpy.collections.create" failed.' raise kimpy.KimPyError(msg) project, semver = collections.get_project_name_and_sem_ver() print('Project: {}'.format(project)) print('semVer: {}'.format(semver)) for it in ( kimpy.collection_item_type.modelDriver, kimpy.collection_item_type.portableModel, kimpy.collection_item_type.simulatorModel, ): try: name = collections.get_environment_variable_name(it) except RuntimeError: msg = 'Calling "collections.get_environment_variable_name" failed.' raise kimpy.KimPyError(msg) print('{} env name:{}'.format(str(it), name)) name, value = collections.get_configuration_file_environment_variable() print('config file env name: {}'.format(name)) print('config file env value: {}'.format(value)) filename = collections.get_configuration_file_name() print('config file name: {}'.format(filename)) for kc in ( kimpy.collection.system, kimpy.collection.user, kimpy.collection.environmentVariable, kimpy.collection.currentWorkingDirectory, ): dirs_for_collection(kc, collections) for kc in ( kimpy.collection.system, kimpy.collection.user, kimpy.collection.environmentVariable, kimpy.collection.currentWorkingDirectory, ): names_for_collection(kc, collections) for it in ( kimpy.collection_item_type.modelDriver, kimpy.collection_item_type.portableModel, kimpy.collection_item_type.simulatorModel, ): try: extent = collections.cache_list_of_item_names_by_type(it) except RuntimeError: msg = 'Calling "collections.' msg += 'cache_list_of_item_names_by_type" failed.' raise kimpy.KimPyError(msg) print('{}:'.format(str(it))) for i in range(extent): try: name = collections.get_item_name_by_type(i) except RuntimeError: msg = 'Calling "collections.get_item_name_by_type" ' msg += 'for index = {} failed.'.format(i) raise kimpy.KimPyError(msg) print(' {}'.format(name)) try: filename, collection = collections.get_item_library_file_name_and_collection( kimpy.collection_item_type.simulatorModel, 'Sim_LAMMPS_LJcut_AkersonElliott_Alchemy_PbAu', ) except RuntimeError: msg = 'Calling "collections.' msg += 'get_item_library_file_name_and_collection" failed.' raise kimpy.KimPyError(msg) msg = 'Simulator Model Sim_LAMMPS_LJcut_AkersonElliott_Alchemy_PbAu ' msg += 'has library name "{}" and is part of the '.format(filename) msg += '"{}" collection'.format(str(collection)) print(msg) try: extent = collections.cache_list_of_item_metadata_files( kimpy.collection_item_type.simulatorModel, "Sim_LAMMPS_LJcut_AkersonElliott_Alchemy_PbAu", ) except RuntimeError: msg = 'Calling "collections.' msg += 'cache_list_of_item_metadata_files" failed.' raise kimpy.KimPyError(msg) for i in range(extent): try: ( file_name, file_length, file_raw_data, avail_as_str, file_str, ) = collections.get_item_metadata_file(i) except RuntimeError: msg = 'Calling "collections.get_item_metadata_file" ' msg += 'for index = {} failed.'.format(i) raise kimpy.KimPyError(msg) msg = 'Metadata file {} ({}) '.format(i, file_name) msg += 'is of length {}'.format(file_length) print(msg) print(file_str)
def example_main(): modelname = 'Sim_LAMMPS_LJcut_AkersonElliott_Alchemy_PbAu' try: sm = kimpy.simulator_model.create(modelname) except RuntimeError: msg = 'Calling "kimpy.simulator_model.create" failed.' raise kimpy.KimPyError(msg) name, version = sm.get_simulator_name_and_version() print('Simulator name: {}'.format(name)) print('Simulator version: {}'.format(version)) extent = sm.get_number_of_supported_species() print('Simulator supports {} species.'.format(extent)) for i in range(extent): try: species = sm.get_supported_species(i) except RuntimeError: msg = 'Calling "sm.get_supported_species" for ' msg += 'index = {} failed.'.format(i) raise kimpy.KimPyError(msg) print('{} {}'.format(i, species)) try: sm.add_template_map('atom-type-sym-list', 'Pb Pb Au Pb') except RuntimeError: raise kimpy.KimPyError('Calling "sm.add_template_map" failed.') sm.close_template_map() number_fields = sm.get_number_of_simulator_fields() print('Simulator model has {} fields.'.format(number_fields)) for i in range(number_fields): try: extent, field_name = sm.get_simulator_field_metadata(i) except RuntimeError: msg = 'Calling "sm.get_simulator_field_metadata" for ' msg += 'fieldIndex = {} failed.'.format(i) raise kimpy.KimPyError(msg) print('Field {} is {} and has lines: {}'.format(i, field_name, extent)) for j in range(extent): try: field_line = sm.get_simulator_field_line(i, j) except RuntimeError: msg = 'Calling "sm.get_simulator_field_line" for ' msg += 'fieldIndex = {} & lineIndex = '.format(i) msg += '{} failed.'.format(j) raise kimpy.KimPyError(msg) print(' ', field_line) dirname = sm.get_parameter_file_directory_name() print('Simulator model parameter directory name is:', dirname) specname = sm.get_specification_file_name() print('Simulator model specification file name is:', specname) fname = join(dirname, specname) with open(fname, 'r') as f: print(f.read()) num_param_files = sm.get_number_of_parameter_files() print('Simulator model has {} parameter files.'.format(num_param_files)) for i in range(num_param_files): try: paramname = sm.get_parameter_file_name(i) except RuntimeError: msg = 'Calling "sm.get_parameter_file_name" for ' msg += 'index = {} failed.'.format(i) raise kimpy.KimPyError(msg) print('Parameter file {} has name: {}'.format(i, paramname)) fname = join(dirname, paramname) with open(fname, 'r') as f: print(f.read())
def _update_neigh(self, influence_distance: float): """ Update neighbor list and model input. """ # inquire information from conf cell = np.asarray(self.conf.cell, dtype=np.double) PBC = np.asarray(self.conf.PBC, dtype=np.intc) contributing_coords = np.asarray(self.conf.coords, dtype=np.double) contributing_species = self.conf.species num_contributing = self.conf.get_num_atoms() self.num_contributing_particles = num_contributing # species support and code unique_species = list(set(contributing_species)) species_map = dict() for s in unique_species: if s in self.supported_species: species_map[s] = self.supported_species[s] else: KIMModelError(f"species `{s}` not supported by model") contributing_species_code = np.array( [species_map[s] for s in contributing_species], dtype=np.intc) if any(PBC): # need padding atoms try: ( padding_coords, padding_species_code, self.padding_image_of, ) = nl.create_paddings( influence_distance, cell, PBC, contributing_coords, contributing_species_code, ) except RuntimeError: raise kimpy.KimPyError( "Calling `nl.create_paddings()` failed.") num_padding = padding_species_code.size self.num_particles = np.array([num_contributing + num_padding], dtype=np.intc) tmp = np.concatenate((contributing_coords, padding_coords)) self.coords = np.asarray(tmp, dtype=np.double) tmp = np.concatenate( (contributing_species_code, padding_species_code)) self.species_code = np.asarray(tmp, dtype=np.intc) self.particle_contributing = np.ones(self.num_particles[0], dtype=np.intc) self.particle_contributing[num_contributing:] = 0 # for now, create neigh for all atoms, including paddings need_neigh = np.ones(self.num_particles[0], dtype=np.intc) else: # do not need padding atoms self.padding_image_of = np.array([]) self.num_particles = np.array([num_contributing], dtype=np.intc) self.coords = np.array(contributing_coords, dtype=np.double) self.species_code = np.array(contributing_species_code, dtype=np.intc) self.particle_contributing = np.ones(num_contributing, dtype=np.intc) need_neigh = self.particle_contributing try: self.neigh.build( self.coords, influence_distance, np.asarray([influence_distance], dtype=np.double), need_neigh, ) except RuntimeError: raise kimpy.KimPyError("Calling `neigh.build()` failed.")
def _register_data(self, compute_energy=True, compute_forces=True): """ Register model input and output data in KIM API. """ # check whether model support energy and forces kim_can = kimpy.compute_argument_name if compute_energy: name = kim_can.partialEnergy try: support_status = self.kim_ca.get_argument_support_status(name) except RuntimeError: raise kimpy.KimPyError( "Calling `kim_ca.get_argument_support_status()` failed.") if not (support_status == kimpy.support_status.required or support_status == kimpy.support_status.optional): KIMModelError("Energy not supported by model") if compute_forces: name = kim_can.partialForces try: support_status = self.kim_ca.get_argument_support_status(name) except RuntimeError: raise kimpy.KimPyError( "Calling `kim_ca.get_argument_support_status()` failed.") if not (support_status == kimpy.support_status.required or support_status == kimpy.support_status.optional): KIMModelError("Forces not supported by model") # register argument try: self.kim_ca.set_argument_pointer(kim_can.numberOfParticles, self.num_particles) self.kim_ca.set_argument_pointer(kim_can.particleSpeciesCodes, self.species_code) self.kim_ca.set_argument_pointer(kim_can.particleContributing, self.particle_contributing) self.kim_ca.set_argument_pointer(kim_can.coordinates, self.coords) except RuntimeError: raise kimpy.KimPyError( "Calling `kim_ca.set_argument_pointer()` failed.") if compute_energy: self.energy = np.array([0.0], dtype=np.double) try: self.kim_ca.set_argument_pointer(kim_can.partialEnergy, self.energy) except RuntimeError: raise kimpy.KimPyError( "Calling `kim_ca.set_argument_pointer()` failed.") else: self.energy = None try: self.kim_ca.set_argument_null_pointer(kim_can.partialEnergy) except RuntimeError: raise kimpy.KimPyError( "Calling `kim_ca.set_argument_null_pointer()` failed.") if compute_forces: self.forces = np.zeros([self.num_particles[0], 3], dtype=np.double) try: self.kim_ca.set_argument_pointer(kim_can.partialForces, self.forces) except RuntimeError: raise kimpy.KimPyError( "Calling `kim_ca.set_argument_pointer()` failed.") else: self.forces = None try: self.kim_ca.set_argument_null_pointer(kim_can.partialForces) except RuntimeError: raise kimpy.KimPyError( "Calling `kim_ca.set_argument_null_pointer()` failed.")
def test_main(): modelname = 'ex_model_Ar_P_Morse' # modelname = 'Three_Body_Stillinger_Weber_Si__MO_405512056662_004' # modelname = 'LennardJones612_Universal__MO_826355984548_002' print() print('=' * 80) print('Matching results for KIM model:', modelname) print() # create model try: requestedUnitsAccepted, kim_model = kimpy.model.create( kimpy.numbering.zeroBased, kimpy.length_unit.A, kimpy.energy_unit.eV, kimpy.charge_unit.e, kimpy.temperature_unit.K, kimpy.time_unit.ps, modelname, ) except RuntimeError: raise kimpy.KimPyError('Calling "kimpy.model.create" failed.') if not requestedUnitsAccepted: msg = 'requested units not accepted in kimpy.model.create' raise kimpy.KimPyError(msg) # units l_unit, e_unit, c_unit, te_unit, ti_unit = kim_model.get_units() print('Length unit is:', str(l_unit)) print('Energy unit is:', str(e_unit)) print('Charge unit is:', str(c_unit)) print('Temperature unit is:', str(te_unit)) print('Time unit is:', str(ti_unit)) print() # create compute arguments try: compute_arguments = kim_model.compute_arguments_create() except RuntimeError: msg = 'Calling "kim_model.compute_arguments_create" failed.' raise kimpy.KimPyError(msg) # check compute arguments num_compute_arguments = ( kimpy.compute_argument_name.get_number_of_compute_argument_names()) print('Number of compute_arguments:', num_compute_arguments) for i in range(num_compute_arguments): try: name = kimpy.compute_argument_name.get_compute_argument_name(i) except RuntimeError: msg = 'Calling "kimpy.compute_argument_name.' msg += 'get_compute_argument_name" for index = ' msg += '{} failed.'.format(i) raise kimpy.KimPyError(msg) try: dtype = kimpy.compute_argument_name.get_compute_argument_data_type( name) except RuntimeError: msg = 'Calling "kimpy.compute_argument_name.' msg += 'get_compute_argument_data_type" for computeArgumentName = ' msg += '{} failed.'.format(name) raise kimpy.KimPyError(msg) try: support_status = compute_arguments.get_argument_support_status( name) except RuntimeError: msg = 'Calling "compute_arguments.get_argument_support_status" ' msg += 'for computeArgumentName = {} failed.'.format(name) raise kimpy.KimPyError(msg) n_space_1 = 21 - len(str(name)) n_space_2 = 7 - len(str(dtype)) print('Compute Argument name "{}" '.format(name) + ' ' * n_space_1 + 'is of type "{}" '.format(dtype) + ' ' * n_space_2 + 'and has support status "{}".'.format(support_status)) # can only handle energy and force as a required arg if support_status == kimpy.support_status.required: if name not in ( kimpy.compute_argument_name.partialEnergy, kimpy.compute_argument_name.partialForces, ): msg = 'Unsupported required ComputeArgumentName = ' msg += '{}'.format(name) raise kimpy.KimPyError(msg) # must have energy and forces if name in ( kimpy.compute_argument_name.partialEnergy, kimpy.compute_argument_name.partialForces, ): if support_status not in ( kimpy.support_status.required, kimpy.support_status.optional, ): raise kimpy.KimPyError('Energy or forces not available') print() # check compute callbacks num_callbacks = kimpy.compute_callback_name.get_number_of_compute_callback_names( ) print('Number of callbacks:', num_callbacks) for i in range(num_callbacks): try: name = kimpy.compute_callback_name.get_compute_callback_name(i) except RuntimeError: msg = 'Calling "kimpy.compute_callback_name.' msg += 'get_compute_callback_name" for index = ' msg += '{} failed.'.format(i) raise kimpy.KimPyError(msg) try: support_status = compute_arguments.get_callback_support_status( name) except RuntimeError: msg = 'Calling "compute_arguments.get_callback_support_status" ' msg += 'for computeArgumentName = {} failed.'.format(name) raise kimpy.KimPyError(msg) n_space = 18 - len(str(name)) print('Compute callback "{}"'.format(name) + ' ' * n_space + 'has support status "{}".'.format(support_status)) # cannot handle any "required" callbacks if support_status == kimpy.support_status.required: raise kimpy.KimPyError('Unsupported required ComputeCallback') print() # parameter num_params = kim_model.get_number_of_parameters() print('Number of parameters:', num_params) print() for i in range(num_params): try: dtype, extent, name, description = kim_model.get_parameter_metadata( i) except RuntimeError: msg = 'Calling "kim_model.get_parameter_metadata" ' msg += 'for parameterIndex = {} failed.'.format(i) raise kimpy.KimPyError(msg) print('Parameter No.', i) print(' data type:', dtype) print(' extent:', extent) print(' name:', name) print(' description:', description) print() # register argument argon = create_fcc_argon() coords = np.asarray(argon.get_positions(), dtype=np.double) N = coords.shape[0] print('Number of particles:', N) forces = np.zeros((N, 3), dtype=np.double) energy = np.array([0.0], dtype=np.double) num_particles = np.array([N], dtype=np.intc) species_code = np.zeros(num_particles, dtype=np.intc) particle_contributing = np.zeros(num_particles, dtype=np.intc) try: compute_arguments.set_argument_pointer( kimpy.compute_argument_name.numberOfParticles, num_particles) except RuntimeError: msg = 'Calling "compute_arguments.set_argument_pointer" failed.' raise kimpy.KimPyError(msg) try: compute_arguments.set_argument_pointer( kimpy.compute_argument_name.particleSpeciesCodes, species_code) except RuntimeError: msg = 'Calling "compute_arguments.set_argument_pointer" failed.' raise kimpy.KimPyError(msg) try: compute_arguments.set_argument_pointer( kimpy.compute_argument_name.particleContributing, particle_contributing) except RuntimeError: msg = 'Calling "compute_arguments.set_argument_pointer" failed.' raise kimpy.KimPyError(msg) try: compute_arguments.set_argument_pointer( kimpy.compute_argument_name.coordinates, coords) except RuntimeError: msg = 'Calling "compute_arguments.set_argument_pointer" failed.' raise kimpy.KimPyError(msg) try: compute_arguments.set_argument_pointer( kimpy.compute_argument_name.partialEnergy, energy) except RuntimeError: msg = 'Calling "compute_arguments.set_argument_pointer" failed.' raise kimpy.KimPyError(msg) try: compute_arguments.set_argument_pointer( kimpy.compute_argument_name.partialForces, forces) except RuntimeError: msg = 'Calling "compute_arguments.set_argument_pointer" failed.' raise kimpy.KimPyError(msg) # neighbor list neigh = dict() # register get neigh callback try: compute_arguments.set_callback( kimpy.compute_callback_name.GetNeighborList, get_neigh, neigh) except RuntimeError: msg = 'Calling "compute_arguments.set_callback" failed.' raise kimpy.KimPyError(msg) # influence distance and cutoff of model model_influence_dist = kim_model.get_influence_distance() print('Model influence distance:', model_influence_dist) ( model_cutoffs, padding_not_require_neigh_hints, ) = kim_model.get_neighbor_list_cutoffs_and_hints() print('Model cutoffs:', model_cutoffs) print('Model padding neighbors hints:', padding_not_require_neigh_hints) print() # species support and code try: species_support, code = kim_model.get_species_support_and_code( kimpy.species_name.Ar) except RuntimeError: msg = 'Calling "kim_model.get_species_support_and_code" failed.' raise kimpy.KimPyError(msg) if not species_support: msg = 'Ar species is not supported by this model.' raise kimpy.KimPyError(msg) print('Species Ar is supported and its code is:', code) print() # setup particle species species_code[:] = code # setup particleContributing particle_contributing[:] = 1 # compute energy and force for different structures alat = 5.26 min_alat = 0.8 * 5.26 max_alat = 1.2 * 5.26 inc_alat = 0.025 * alat all_alat = np.arange(min_alat, max_alat, inc_alat) print('=' * 80) print('Result for KIM model:', modelname) print() print(' energy force norm lattice spacing') print() for a in all_alat: argon = create_fcc_argon(a) # NOTE should not change coords address np.copyto(coords, argon.get_positions()) # NOTE safe to change content of neigh create_neigh(coords, model_influence_dist, neigh) try: kim_model.compute(compute_arguments) except RuntimeError: raise kimpy.KimPyError('Calling "kim_model.compute" failed.') print('{:18.10e} {:18.10e} {:18.10e}'.format(energy[0], np.linalg.norm(forces), a)) try: present, required = kim_model.is_routine_present( kimpy.model_routine_name.WriteParameterizedModel) except RuntimeError: msg = 'Calling "kim_model.is_routine_present" failed.' raise kimpy.KimPyError(msg) if present: try: kim_model.write_parameterized_model('.', 'Morse_Ar') except RuntimeError: msg = 'Calling "kim_model.write_parameterized_model" failed.' raise kimpy.KimPyError(msg) try: os.remove('Morse_Ar.params') os.remove('CMakeLists.txt') os.remove('kim.log') except: pass
def test_main(): model_name = 'LennardJones612_UniversalShifted__MO_959249795837_003' # create model try: requested_units_accepted, kim_model = kimpy.model.create( kimpy.numbering.zeroBased, kimpy.length_unit.A, kimpy.energy_unit.eV, kimpy.charge_unit.e, kimpy.temperature_unit.K, kimpy.time_unit.ps, model_name, ) except RuntimeError: raise kimpy.KimPyError('Calling "kimpy.model.create" failed.') if not requested_units_accepted: msg = 'requested units not accepted in kimpy.model.create' raise kimpy.KimPyError(msg) # create compute arguments try: compute_arguments = kim_model.compute_arguments_create() except RuntimeError: msg = 'Calling "kim_model.compute_arguments_create" failed.' raise kimpy.KimPyError(msg) # register argument argon = get_argon_dimer() coords = np.asarray(argon.get_positions(), dtype=np.double) N = coords.shape[0] forces = np.zeros((N, 3), dtype=np.double) energy = np.array([0.0], dtype=np.double) num_particles = np.array([N], dtype=np.intc) species_code = np.zeros(num_particles, dtype=np.intc) particle_contributing = np.zeros(num_particles, dtype=np.intc) try: compute_arguments.set_argument_pointer( kimpy.compute_argument_name.numberOfParticles, num_particles) except RuntimeError: msg = 'Calling "compute_argument.set_argument_pointer" failed.' raise kimpy.KimPyError(msg) try: compute_arguments.set_argument_pointer( kimpy.compute_argument_name.particleSpeciesCodes, species_code) except RuntimeError: msg = 'Calling "compute_argument.set_argument_pointer" failed.' raise kimpy.KimPyError(msg) try: compute_arguments.set_argument_pointer( kimpy.compute_argument_name.particleContributing, particle_contributing) except RuntimeError: msg = 'Calling "compute_argument.set_argument_pointer" failed.' raise kimpy.KimPyError(msg) try: compute_arguments.set_argument_pointer( kimpy.compute_argument_name.coordinates, coords) except RuntimeError: msg = 'Calling "compute_argument.set_argument_pointer" failed.' raise kimpy.KimPyError(msg) try: compute_arguments.set_argument_pointer( kimpy.compute_argument_name.partialEnergy, energy) except RuntimeError: msg = 'Calling "compute_argument.set_argument_pointer" failed.' raise kimpy.KimPyError(msg) try: compute_arguments.set_argument_pointer( kimpy.compute_argument_name.partialForces, forces) except RuntimeError: msg = 'Calling "compute_argument.set_argument_pointer" failed.' raise kimpy.KimPyError(msg) # species support and code try: species_support, code = kim_model.get_species_support_and_code( kimpy.species_name.Ar) except RuntimeError: msg = 'Calling "kim_model.get_species_support_and_code" failed.' raise kimpy.KimPyError(msg) if not species_support: msg = 'Ar species is not supported by this model.' raise kimpy.KimPyError(msg) # setup particle species species_code[:] = code # setup particleContributing particle_contributing[:] = 1 # register callbacks try: compute_arguments.set_callback( kimpy.compute_callback_name.GetNeighborList, get_neigh, neigh_data) except RuntimeError: msg = 'Calling "compute_arguments.set_callback" failed.' raise kimpy.KimPyError(msg) try: compute_arguments.set_callback( kimpy.compute_callback_name.ProcessDEDrTerm, process_dEdr, dEdr_data) except RuntimeError: msg = 'Calling "compute_arguments.set_callback" failed.' raise kimpy.KimPyError(msg) try: compute_arguments.set_callback( kimpy.compute_callback_name.ProcessD2EDr2Term, process_d2Edr2, d2Edr2_data) except RuntimeError: msg = 'Calling "compute_arguments.set_callback" failed.' raise kimpy.KimPyError(msg) # 1st call of compute try: kim_model.compute(compute_arguments) except RuntimeError: msg = 'Calling "kim_model.compute" failed the 1st time.' raise kimpy.KimPyError(msg) # 2nd call of compute neigh_data['key'] = 2 dEdr_data['key'] = 2 d2Edr2_data['key'] = 2 try: kim_model.compute(compute_arguments) except RuntimeError: msg = 'Calling "kim_model.compute" failed the 2nd time.' raise kimpy.KimPyError(msg) # check callback can modify local data assert neigh_data['key'] == 3 assert neigh_data['new_key'] == 1 assert dEdr_data['key'] == 3 assert dEdr_data['new_key'] == 1 assert d2Edr2_data['key'] == 3 assert d2Edr2_data['new_key'] == 1