def calculate_transition_probabilities(self): """ Updating the Macro Atom computations """ macro_atom_data = self.atom_data.macro_atom_data if not hasattr(self, 'beta_sobolevs'): self.beta_sobolevs = np.zeros_like(self.tau_sobolevs.values) if not self.beta_sobolevs_precalculated: macro_atom.calculate_beta_sobolev(self.tau_sobolevs.values.ravel(order='F'), self.beta_sobolevs.ravel(order='F')) transition_probabilities = (macro_atom_data.transition_probability.values[np.newaxis].T * self.beta_sobolevs.take(self.atom_data.macro_atom_data.lines_idx.values.astype(int), axis=0, mode='raise')).copy('F') transition_up_filter = (macro_atom_data.transition_type == 1).values macro_atom_transition_up_filter = macro_atom_data.lines_idx.values[transition_up_filter] j_blues = self.j_blues.values.take(macro_atom_transition_up_filter, axis=0, mode='raise') macro_stimulated_emission = self.stimulated_emission_factor.take(macro_atom_transition_up_filter, axis=0, mode='raise') transition_probabilities[transition_up_filter] *= j_blues * macro_stimulated_emission #Normalizing the probabilities block_references = np.hstack((self.atom_data.macro_atom_references.block_references, len(macro_atom_data))) macro_atom.normalize_transition_probabilities(transition_probabilities, block_references) return pd.DataFrame(transition_probabilities, index=macro_atom_data.transition_line_id, columns=self.tau_sobolevs.columns)
def calculate(self, tau_sobolevs): if getattr(self, 'beta_sobolev', None) is None: beta_sobolev = np.zeros_like(tau_sobolevs.values) else: beta_sobolev = self.beta_sobolev macro_atom.calculate_beta_sobolev( tau_sobolevs.values.ravel(order='F'), beta_sobolev.ravel(order='F')) return beta_sobolev
def calculate_nlte_level_populations(self): """ Calculating the NLTE level populations for specific ions """ if not hasattr(self, 'beta_sobolevs'): self.beta_sobolevs = np.zeros_like(self.tau_sobolevs.values) macro_atom.calculate_beta_sobolev(self.tau_sobolevs.values.ravel(order='F'), self.beta_sobolevs.ravel(order='F')) self.beta_sobolevs_precalculated = True if self.nlte_config.get('coronal_approximation', False): beta_sobolevs = np.ones_like(self.beta_sobolevs) j_blues = np.zeros_like(self.j_blues) else: beta_sobolevs = self.beta_sobolevs j_blues = self.j_blues.values if self.nlte_config.get('classical_nebular', False): print "setting classical nebular = True" beta_sobolevs = np.ones_like(self.beta_sobolevs) for species in self.nlte_config.species: logger.info('Calculating rates for species %s', species) number_of_levels = self.atom_data.levels.energy.ix[species].count() level_populations = self.level_populations.ix[species].values lnl = self.atom_data.nlte_data.lines_level_number_lower[species] lnu = self.atom_data.nlte_data.lines_level_number_upper[species] lines_index = self.atom_data.nlte_data.lines_idx[species] A_uls = self.atom_data.nlte_data.A_uls[species] B_uls = self.atom_data.nlte_data.B_uls[species] B_lus = self.atom_data.nlte_data.B_lus[species] r_lu_index = lnu * number_of_levels + lnl r_ul_index = lnl * number_of_levels + lnu r_ul_matrix = np.zeros((number_of_levels, number_of_levels, len(self.t_rads)), dtype=np.float64) r_ul_matrix_reshaped = r_ul_matrix.reshape((number_of_levels**2, len(self.t_rads))) r_ul_matrix_reshaped[r_ul_index] = A_uls[np.newaxis].T r_ul_matrix_reshaped[r_ul_index] *= beta_sobolevs[lines_index] stimulated_emission_matrix = np.zeros_like(r_ul_matrix) stimulated_emission_matrix.reshape((number_of_levels**2, len(self.t_rads)))[r_lu_index] = self.stimulated_emission_factor[lines_index] r_lu_matrix = np.zeros_like(r_ul_matrix) r_lu_matrix_reshaped = r_lu_matrix.reshape((number_of_levels**2, len(self.t_rads))) r_lu_matrix_reshaped[r_lu_index] = B_lus[np.newaxis].T * j_blues[lines_index] * beta_sobolevs[lines_index] r_lu_matrix *= stimulated_emission_matrix collision_matrix = self.atom_data.nlte_data.get_collision_matrix(species, self.t_electrons) * \ self.electron_densities.values rates_matrix = r_lu_matrix + r_ul_matrix + collision_matrix for i in xrange(number_of_levels): rates_matrix[i, i] = -rates_matrix[:, i].sum(axis=0) rates_matrix[0, :, :] = 1.0 x = np.zeros(rates_matrix.shape[0]) x[0] = 1.0 for i in xrange(len(self.t_rads)): relative_level_populations = np.linalg.solve(rates_matrix[:, :, i], x) self.level_populations[i].ix[species] = relative_level_populations * self.ion_populations[i].ix[species] return
def calculate_nlte_level_populations(self): """ Calculating the NLTE level populations for specific ions """ if not hasattr(self, 'beta_sobolevs'): self.beta_sobolevs = np.zeros_like(self.tau_sobolevs.values) macro_atom.calculate_beta_sobolev(self.tau_sobolevs.values.ravel(order='F'), self.beta_sobolevs.ravel(order='F')) self.beta_sobolevs_precalculated = True if self.nlte_config.get('coronal_approximation', False): beta_sobolevs = np.ones_like(self.beta_sobolevs) j_blues = np.zeros_like(self.j_blues) logger.info('using coronal approximation = setting beta_sobolevs to 1 AND j_blues to 0') else: beta_sobolevs = self.beta_sobolevs j_blues = self.j_blues.values if self.nlte_config.get('classical_nebular', False): logger.info('using Classical Nebular = setting beta_sobolevs to 1') beta_sobolevs = np.ones_like(self.beta_sobolevs) for species in self.nlte_config.species: logger.info('Calculating rates for species %s', species) number_of_levels = self.atom_data.levels.energy.ix[species].count() level_populations = self.level_populations.ix[species].values lnl = self.atom_data.nlte_data.lines_level_number_lower[species] lnu = self.atom_data.nlte_data.lines_level_number_upper[species] lines_index = self.atom_data.nlte_data.lines_idx[species] A_uls = self.atom_data.nlte_data.A_uls[species] B_uls = self.atom_data.nlte_data.B_uls[species] B_lus = self.atom_data.nlte_data.B_lus[species] r_lu_index = lnu * number_of_levels + lnl r_ul_index = lnl * number_of_levels + lnu r_ul_matrix = np.zeros((number_of_levels, number_of_levels, len(self.t_rads)), dtype=np.float64) r_ul_matrix_reshaped = r_ul_matrix.reshape((number_of_levels**2, len(self.t_rads))) r_ul_matrix_reshaped[r_ul_index] = A_uls[np.newaxis].T + B_uls[np.newaxis].T * j_blues[lines_index] r_ul_matrix_reshaped[r_ul_index] *= beta_sobolevs[lines_index] r_lu_matrix = np.zeros_like(r_ul_matrix) r_lu_matrix_reshaped = r_lu_matrix.reshape((number_of_levels**2, len(self.t_rads))) r_lu_matrix_reshaped[r_lu_index] = B_lus[np.newaxis].T * j_blues[lines_index] * beta_sobolevs[lines_index] collision_matrix = self.atom_data.nlte_data.get_collision_matrix(species, self.t_electrons) * \ self.electron_densities.values rates_matrix = r_lu_matrix + r_ul_matrix + collision_matrix for i in xrange(number_of_levels): rates_matrix[i, i] = -rates_matrix[:, i].sum(axis=0) rates_matrix[0, :, :] = 1.0 x = np.zeros(rates_matrix.shape[0]) x[0] = 1.0 for i in xrange(len(self.t_rads)): relative_level_populations = np.linalg.solve(rates_matrix[:, :, i], x) self.level_populations[i].ix[species] = relative_level_populations * self.ion_populations[i].ix[species] return