def _csSpherical_q2x(self, Q, deriv = 0, out = None, var = None): # Use adf routines to compute derivatives # q = dfun.X2adf(Q, deriv, var) # q[0] is r, q[1] = theta, q[2] = phi if self.angle == 'rad': sintheta = adf.sin(q[1]) costheta = adf.cos(q[1]) sinphi = adf.sin(q[2]) cosphi = adf.cos(q[2]) else: # degree deg2rad = np.pi/180.0 sintheta = adf.sin(deg2rad * q[1]) costheta = adf.cos(deg2rad * q[1]) sinphi = adf.sin(deg2rad * q[2]) cosphi = adf.cos(deg2rad * q[2]) r = q[0] x = r * sintheta * cosphi y = r * sintheta * sinphi z = r * costheta return dfun.adf2array([x,y,z], out)
def _Lx(self, X, deriv = 0, out = None, var = None): """ basis evaluation function Use recursion relations for generalized Laguerre polynomials """ nd,nvar = dfun.ndnvar(deriv, var, self.nx) if out is None: base_shape = X.shape[1:] out = np.ndarray( (nd, self.nf) + base_shape, dtype = X.dtype) # Create adf object for theta x = dfun.X2adf(X,deriv,var)[0] # Calculate Laguerre polynomials # with generic algebra L = _laguerre_gen(x, self.alpha, self.nmax) # Convert adf objects to a single # derivative array dfun.adf2array(L, out) return out
def _ftheta(self, X, deriv = 0, out = None, var = None): """ basis evaluation function Use recursion relations for associated Legendre polynomials. """ nd,nvar = dfun.ndnvar(deriv, var, self.nx) if out is None: base_shape = X.shape[1:] out = np.ndarray( (nd, self.nf) + base_shape, dtype = X.dtype) # Create adf object for theta theta = dfun.X2adf(X, deriv, var)[0] m = abs(self.m) # |m| sinm = adf.powi(adf.sin(theta), m) cos = adf.cos(theta) # Calculate Legendre polynomials # with generic algebra F = _leg_gen(sinm, cos, m, np.max(self.l)) # Convert adf objects to a single # derivative array dfun.adf2array(F, out) return out
def _monomial(self, X, deriv = 0, out = None, var = None): """ evaluation function """ nd,nvar = dfun.ndnvar(deriv, var, self.nx) if out is None: base_shape = X.shape[1:] out = np.ndarray( (nd, self.nf) + base_shape, dtype = X.dtype) x = dfun.X2adf(X, deriv, var) res = adf.powi(x[0], self.pows[0]) for i in range(1, self.nx): res = res * adf.powi(x[i], self.pows[i]) dfun.adf2array([res], out) return out
def _csPolar_q2x(self, Q, deriv = 0, out = None, var = None): # Use adf routines to compute derivatives # q = dfun.X2adf(Q, deriv, var) # q[0] is r, q[1] = phi (in deg or rad) if self.angle == 'rad': x = q[0] * adf.cos(q[1]) y = q[0] * adf.sin(q[1]) else: # degree deg2rad = np.pi/180.0 x = q[0] * adf.cos(deg2rad * q[1]) y = q[0] * adf.sin(deg2rad * q[1]) return dfun.adf2array([x,y], out)
def _Rr(self, X, deriv = 0, out = None, var = None): """ basis evaluation function Use generic algebra evaluation function """ nd,nvar = dfun.ndnvar(deriv, var, self.nx) if out is None: base_shape = X.shape[1:] out = np.ndarray( (nd, self.nf) + base_shape, dtype = X.dtype) # Create adf object for theta r = dfun.X2adf(X,deriv,var)[0] expar2 = adf.exp(-0.5 * self.alpha * (r*r)) # Calculate radial wavefunctions R = _radialHO_gen(r, expar2, self.nmax, self.ell, self.d, self.alpha) # Convert adf objects to a single # derivative array dfun.adf2array(R, out) return out
def _Philm(self, X, deriv = 0, out = None, var = None): # Setup nd,nvar = dfun.ndnvar(deriv, var, self.nx) if out is None: base_shape = X.shape[1:] out = np.ndarray( (nd, self.nf) + base_shape, dtype = X.dtype) # Make adf objects for theta and phi x = dfun.X2adf(X, deriv, var) theta = x[0] phi = x[1] ######################################### # # Calculate F and f factors first # sinth = adf.sin(theta) costh = adf.cos(theta) lmax = np.max(self.l) # Calculate the associated Legendre factors Flm = [] amuni = np.unique(abs(self.m)) # list of unique |m| for aM in amuni: # Order aM = |M| sinM = adf.powi(sinth, aM) # Calculate F^M up to l <= lmax Flm.append(_leg_gen(sinM, costh, aM, lmax)) #Flm is now a nested list # Calculate the phi factors smuni = np.unique(self.m) # list of unique signed m fm = [] for sM in smuni: if sM == 0: fm.append(adf.const_like(1/np.sqrt(2*np.pi), phi)) elif sM < 0: fm.append(1/np.sqrt(np.pi) * adf.sin(abs(sM) * phi)) else: #sM > 0 fm.append(1/np.sqrt(np.pi) * adf.cos(sM * phi)) # ############################################## ########################################### # Now calculate the list of real spherical harmonics Phi = [] for i in range(self.nf): l = self.l[i] m = self.m[i] # signed m # Gather the associated Legendre polynomial (theta factor) aM_idx = np.where(amuni == abs(m))[0][0] l_idx = l - abs(m) F_i = Flm[aM_idx][l_idx] # Gather the sine/cosine (phi factor) sM_idx = np.where(smuni == m)[0][0] f_i = fm[sM_idx] # Add their product to the list of functions Phi.append(F_i * f_i) # ########################################### # Convert the list to a single # DFun derivative array dfun.adf2array(Phi, out) # and return return out
def _chinell(self, X, deriv = 0, out = None, var = None): # Setup nd,nvar = dfun.ndnvar(deriv, var, self.nx) if out is None: base_shape = X.shape[1:] out = np.ndarray( (nd, self.nf) + base_shape, dtype = X.dtype) # Make adf objects for theta and phi x = dfun.X2adf(X, deriv, var) r = x[0] # Cylindrical radius phi = x[1] if self._rad else x[1] * np.pi/180.0 # Angular coordinate ######################################### # # Calculate R and f factors first # # Calculate the radial wavefunctions Rnell = [] abs_ell_uni = np.unique(abs(self.ell)) # list of unique |ell| expar2 = adf.exp(-0.5 * self.alpha * (r*r)) # The exponential radial factor for aELL in abs_ell_uni: nmax = round(np.floor(self.vmax - aELL) / 2) Rnell.append(_radialHO_gen(r, expar2, nmax, aELL, 2, self.alpha)) # Calculate the phi factors, f_ell(phi) sig_ell_uni = np.unique(self.ell) # list of unique signed ell fell = [] if self._rad: # Normalization assuming radians for sELL in sig_ell_uni: if sELL == 0: fell.append(adf.const_like(1/np.sqrt(2*np.pi), phi)) elif sELL < 0: fell.append(1/np.sqrt(np.pi) * adf.sin(abs(sELL) * phi)) else: #sELL > 0 fell.append(1/np.sqrt(np.pi) * adf.cos(sELL * phi)) else: # Normalization for degrees for sELL in sig_ell_uni: if sELL == 0: fell.append(adf.const_like(1/np.sqrt(360.00), phi)) elif sELL < 0: fell.append(1/np.sqrt(180.0) * adf.sin(abs(sELL) * phi)) else: #sELL > 0 fell.append(1/np.sqrt(180.0) * adf.cos(sELL * phi)) # ############################################## ########################################### # Now calculate the list of real 2-D HO wavefunctions chi = [] for i in range(self.nf): ell = self.ell[i] n = self.n[i] # Gather the radial factor abs_ELL_idx = np.where(abs_ell_uni == abs(ell))[0][0] R_i = Rnell[abs_ELL_idx][n] # Gather the angular factor sig_ELL_idx = np.where(sig_ell_uni == ell)[0][0] f_i = fell[sig_ELL_idx] # Add their product to the list of functions chi.append(R_i * f_i) # ########################################### # Convert the list to a single # DFun derivative array dfun.adf2array(chi, out) # and return return out