def rf_saddle(self): ## finds the rf_saddle point near the desired expansion point and updates the expansion_position N = (self.expansion_order + 1)**2 # number of multipoles for expansion order = self.expansion_order Mj, Yj, scale = e.spher_harm_expansion(self.RF_potential, self.expansion_point, self.X, self.Y, self.Z, order) self.RF_multipole_expansion = Mj[0:N].T #regenerated field Vregen = e.spher_harm_cmp(Mj, Yj, scale, order) self.RF_potential_regenerated = Vregen.reshape( [self.nx, self.ny, self.nz]) [Xrf, Yrf, Zrf] = o.exact_saddle(self.RF_potential, self.X, self.Y, self.Z, 2, Z0=self.expansion_point[2]) [Irf, Jrf, Krf] = o.find_saddle(self.RF_potential, self.X, self.Y, self.Z, 2, Z0=self.expansion_point[2]) self.expansion_point = [Xrf, Yrf, Zrf] self.expansion_coords = [Irf, Jrf, Krf] return
def expand_potentials(self, expansion_point, order=3): ''' Computes a multipole expansion of every electrode around the specified value expansion_point. expansion_point: list [x0, y0, z0] of location to compute the fiel expansion order: int, order of the expansion to carry out returns: matrix of multipole expansions for each electrodes matrix[:, el] = multipole expansion vector for electrode el Also defines the class variable self.multipole_expansions ''' N = (order + 1)**2 # number of multipoles self.multipole_expansions = np.zeros((N, self.numElectrodes)) self.expansion_order = order X, Y, Z = self.X, self.Y, self.Z for el in range(self.numElectrodes): potential_grid = self.electrode_potentials[el] vec = spher_harm_expansion(potential_grid, expansion_point, X, Y, Z, order) self.multipole_expansions[:, el] = vec[0:N].T return self.multipole_expansions
def expand_potentials_spherHarm(self): ''' Computes a multipole expansion of every electrode around the specified value expansion_point to the specified order. Defines the class variables: (1) self.multipole_expansions [:, el] = multipole expansion vector for electrode el (2) self.regenerated potentials [:,el] = potentials regenerated from s.h. expansion ''' N = (self.expansion_order + 1)**2 # number of multipoles for expansion (might be less than for regeneration) order = max(self.expansion_order,self.regeneration_order) self.multipole_expansions = np.zeros((N, self.numElectrodes)) self.electrode_potentials_regenerated = np.zeros(np.array(self.electrode_potentials).shape) X, Y, Z = self.X, self.Y, self.Z for el in range(self.numElectrodes): #multipole expansion potential_grid = self.electrode_potentials[el] Mj,Yj,scale = e.spher_harm_expansion(potential_grid, self.expansion_point, X, Y, Z, order) self.multipole_expansions[:, el] = Mj[0:N].T #regenerated field Vregen = e.spher_harm_cmp(Mj,Yj,scale,self.regeneration_order) self.electrode_potentials_regenerated[el] = Vregen.reshape([self.nx,self.ny,self.nz]) if self.electrode_names[el] == 'RF': self.RF_multipole_expansion = Mj[0:N].T #self.RF_potential_regenerated = Vregen.reshape([self.nx,self.ny,self.nz]) return
def sum_of_e_field(r, V, X, Y, Z, exact_saddle=True): """V is a 3D matrix containing an electric potential and must solve Laplace's equation X,Y,Z are the vectors that define the grid in three directions r: center position for the spherical harmonic expansion Finds the weight of high order multipole terms compared to the weight of second order multipole terms in matrix V, when the center of the multipoles is at x0,y0,z0. Used by exact_saddle for 3-d saddle search. Note that order of outputs for spher_harm_exp are changed, but 1 to 3 should still be E field.""" x0, y0, z0 = r[0], r[1], r[2] c, c1, c2 = e.spher_harm_expansion(V, [x0, y0, z0], X, Y, Z, 3) s = c**2 f = sum(s[1:4]) / sum(s[4:9]) real_f = np.real(f[0]) return real_f
def expand_potentials_spherHarm(self, ROI=None): ''' ROI = region to expand the potential around. Computes a multipole expansion of every electrode around the specified value expansion_point to the specified order. Defines the class variables: (1) self.multipole_expansions [:, el] = multipole expansion vector for electrode el (2) self.regenerated potentials [:,el] = potentials regenerated from s.h. expansion The function returns the coefficients in the order:[C00 C10 C11c C11s ]' These correspond to the multipoles in cartesian coordinares: [c z -x -y (z^2-x^2/2-y^2/2) -6zx -6yz 6x^2-6y^2 12xy ... 1 2 3 4 5 6 7 8 9 ... Or in terms of the Littich thesis: M1 M3 M4 M2 M7 M8 M6 M9 M5 (Using the convention in G. Littich's master thesis (2011)) 0 1 2 3 4 5 6 7 8 (the ith component of Q matrix) ''' N = ( self.expansion_order + 1 )**2 # number of multipoles for expansion (might be less than for regeneration) order = self.expansion_order if ROI == None: self.nx_trunc = self.nx self.ny_trunc = self.ny self.nz_trunc = self.nz self.X_trunc = self.X self.Y_trunc = self.Y self.Z_trunc = self.Z else: self.X_trunc = self.X[self.expansion_coords[0] - ROI[0]:self.expansion_coords[0] + ROI[0]] self.Y_trunc = self.Y[self.expansion_coords[1] - ROI[1]:self.expansion_coords[1] + ROI[1]] self.Z_trunc = self.Z[self.expansion_coords[2] - ROI[2]:self.expansion_coords[2] + ROI[2]] self.nx_trunc = ROI[0] * 2 self.ny_trunc = ROI[1] * 2 self.nz_trunc = ROI[2] * 2 self.multipole_expansions = np.zeros((N, self.numElectrodes)) self.electrode_potentials_regenerated = np.zeros( [self.numElectrodes, self.nx_trunc, self.ny_trunc, self.nz_trunc]) for el in range(self.numElectrodes): #multipole expansion if ROI == None: potential_grid = self.electrode_potentials[el] else: potential_grid = self.electrode_potentials[el][ self.expansion_coords[0] - ROI[0]:self.expansion_coords[0] + ROI[0], self.expansion_coords[1] - ROI[1]:self.expansion_coords[1] + ROI[1], self.expansion_coords[2] - ROI[2]:self.expansion_coords[2] + ROI[2]] Mj, Yj, scale = e.spher_harm_expansion(potential_grid, self.expansion_point, self.X_trunc, self.Y_trunc, self.Z_trunc, order) self.multipole_expansions[:, el] = Mj[0:N].T #regenerated field Vregen = e.spher_harm_cmp(Mj, Yj, scale, order) self.electrode_potentials_regenerated[el] = Vregen.reshape( [self.nx_trunc, self.ny_trunc, self.nz_trunc]) if self.electrode_names[el] == 'RF': self.RF_multipole_expansion = Mj[0:N].T self.multipoles = Yj return