def apply_band_func_thunk(ms, band_func, which_band, eval_thunk): """ We need a special function to evaluate band functions, since band functions can either be a function of the band number or a thunk (function of no arguments, evaluated once per k-point). """ if get_num_args(band_func) == 1: if eval_thunk: band_func(ms) # evaluate thunks once per k-point else: band_func(ms, which_band)
def apply_band_func_thunk(ms, band_func, which_band, eval_thunk): """ We need a special function to evaluate band functions, since band functions can either be a function of the band number or a thunk (function of no arguments, evaluated once per k-point). """ if get_num_args(band_func) == 1: if eval_thunk: band_func(ms) # evaluate thunks once per k-point else: band_func(ms, which_band)
def run_parity(self, p, reset_fields, *band_functions): if self.random_fields and self.randomize_fields not in band_functions: band_functions.append(self.randomize_fields) start = time.time() self.all_freqs = np.zeros((len(self.k_points), self.num_bands)) self.band_range_data = [] init_time = time.time() print("Initializing eigensolver data") print("Computing {} bands with {} tolerance".format( self.num_bands, self.tolerance)) self.init_params(p, reset_fields) if isinstance(reset_fields, basestring): self.load_eigenvectors(reset_fields) print("{} k-points".format(len(self.k_points))) for kp in self.k_points: print(" {}".format(kp)) print("elapsed time for initialization: {}".format(time.time() - init_time)) # TODO: Split over multiple processes # k_split = list_split(self.k_points, self.k_split_num, self.k_split_index) k_split = (0, self.k_points) self.mode_solver.set_kpoint_index(k_split[0]) if self.num_bands > 0: for i, k in enumerate(k_split[1]): self.current_k = k solve_kpoint_time = time.time() self.mode_solver.solve_kpoint(k) self.iterations = self.mode_solver.get_iterations() print("elapsed time for k point: {}".format(time.time() - solve_kpoint_time)) self.freqs = self.get_freqs() self.all_freqs[i, :] = np.array(self.freqs) self.band_range_data = self.update_band_range_data( self.band_range_data, self.freqs, k) self.eigensolver_iters += [self.iterations / self.num_bands] for f in band_functions: num_args = get_num_args(f) if num_args == 1: f(self) elif num_args == 2: band = 1 while band <= self.num_bands: f(self, band) band += 1 else: raise ValueError( "Band function should take 1 or 2 arguments. " "The first must be a ModeSolver instance") if len(k_split[1]) > 1: self.output_band_range_data(self.band_range_data) self.gap_list = self.output_gaps(self.band_range_data) else: self.gap_list = [] end = time.time() - start print("total elapsed time for run: {}".format(end)) self.total_run_time += end self.eigensolver_flops = self.mode_solver.get_eigensolver_flops() self.parity = self.mode_solver.get_parity_string() print("done")
def run_parity(self, p, reset_fields, *band_functions): if self.random_fields and self.randomize_fields not in band_functions: band_functions.append(self.randomize_fields) start = time.time() self.all_freqs = np.zeros((len(self.k_points), self.num_bands)) self.band_range_data = [] init_time = time.time() print("Initializing eigensolver data") print("Computing {} bands with {} tolerance".format( self.num_bands, self.tolerance)) if type(self.default_material) is not mp.Medium and callable( self.default_material): # TODO: Support epsilon_function user materials like meep? self.default_material.eps = False self.mode_solver = mode_solver( self.num_bands, p, self.resolution, self.geometry_lattice, self.tolerance, self.mesh_size, self.default_material, self.geometry, True if reset_fields else False, self.deterministic, self.target_freq, self.dimensions, self.verbose, self.ensure_periodicity, self.eigensolver_flops, self.is_negative_epsilon_ok, self.epsilon_input_file, self.mu_input_file, self.force_mu, ) if isinstance(reset_fields, basestring): self.load_eigenvectors(reset_fields) print("{} k-points".format(len(self.k_points))) for kp in self.k_points: print(" {}".format(kp)) print("elapsed time for initialization: {}".format(time.time() - init_time)) # TODO: Split over multiple processes # k_split = list_split(self.k_points, self.k_split_num, self.k_split_index) k_split = (0, self.k_points) self.mode_solver.set_kpoint_index(k_split[0]) if k_split[0] == 0: self.output_epsilon() # output epsilon immediately for 1st k block if self.mode_solver.using_mu(): self.output_mu() # and mu too, if we have it if self.num_bands > 0: for i, k in enumerate(k_split[1]): self.current_k = k solve_kpoint_time = time.time() self.mode_solver.solve_kpoint(k) self.iterations = self.mode_solver.get_iterations() print("elapsed time for k point: {}".format(time.time() - solve_kpoint_time)) self.freqs = self.get_freqs() self.all_freqs[i, :] = np.array(self.freqs) self.band_range_data = self.update_band_range_data( self.band_range_data, self.freqs, k) self.eigensolver_iters += [self.iterations / self.num_bands] for f in band_functions: num_args = get_num_args(f) if num_args == 1: f(self) elif num_args == 2: band = 1 while band <= self.num_bands: f(self, band) band += 1 else: raise ValueError( "Band function should take 1 or 2 arguments. " "The first must be a ModeSolver instance") if len(k_split[1]) > 1: self.output_band_range_data(self.band_range_data) self.gap_list = self.output_gaps(self.band_range_data) else: self.gap_list = [] end = time.time() - start print("total elapsed time for run: {}".format(end)) self.total_run_time += end self.eigensolver_flops = self.mode_solver.get_eigensolver_flops() self.parity = self.mode_solver.get_parity_string() print("done")
def run_parity(self, p, reset_fields, *band_functions): if self.random_fields and self.randomize_fields not in band_functions: band_functions.append(self.randomize_fields) start = time.time() self.all_freqs = np.zeros((len(self.k_points), self.num_bands)) self.band_range_data = [] init_time = time.time() print("Initializing eigensolver data") print("Computing {} bands with {} tolerance".format(self.num_bands, self.tolerance)) self.init_params(p, reset_fields) if isinstance(reset_fields, basestring): self.load_eigenvectors(reset_fields) print("{} k-points".format(len(self.k_points))) for kp in self.k_points: print(" {}".format(kp)) print("elapsed time for initialization: {}".format(time.time() - init_time)) # TODO: Split over multiple processes # k_split = list_split(self.k_points, self.k_split_num, self.k_split_index) k_split = (0, self.k_points) self.mode_solver.set_kpoint_index(k_split[0]) if self.num_bands > 0: for i, k in enumerate(k_split[1]): self.current_k = k solve_kpoint_time = time.time() self.mode_solver.solve_kpoint(k) self.iterations = self.mode_solver.get_iterations() print("elapsed time for k point: {}".format(time.time() - solve_kpoint_time)) self.freqs = self.get_freqs() self.all_freqs[i, :] = np.array(self.freqs) self.band_range_data = self.update_band_range_data(self.band_range_data, self.freqs, k) self.eigensolver_iters += [self.iterations / self.num_bands] for f in band_functions: num_args = get_num_args(f) if num_args == 1: f(self) elif num_args == 2: band = 1 while band <= self.num_bands: f(self, band) band += 1 else: raise ValueError("Band function should take 1 or 2 arguments. " "The first must be a ModeSolver instance") if len(k_split[1]) > 1: self.output_band_range_data(self.band_range_data) self.gap_list = self.output_gaps(self.band_range_data) else: self.gap_list = [] end = time.time() - start print("total elapsed time for run: {}".format(end)) self.total_run_time += end self.eigensolver_flops = self.mode_solver.get_eigensolver_flops() self.parity = self.mode_solver.get_parity_string() print("done")