def compute_all_freqs(t, ws, hamming_p=1, nintvec=10, force_cartesian=False): """ Compute the fundamental frequencies and amplitudes for all specified orbits. This assumes that all orbits have the same geometry as the first orbit in the orbit array. That is, (if ``force_cartesian`` is ``False``) if the first orbit is a tube orbit, it assumes all orbits are tubes. Parameters ---------- t : array_like ws : array_like hamming_p : int (optional) nintvec : int (optional) force_cartesian : bool (optional) Returns ------- freqs : :class:`numpy.ndarray` amps : :class:`numpy.ndarray` """ # classify parent orbit circ = gd.classify_orbit(ws[:,0]) is_tube = np.any(circ) allfreqs = [] allamps = [] for i in range(ws.shape[1]): ww = ws[:,i] if is_tube and not force_cartesian: # need to flip coordinates until circulation is around z axis new_ws = gd.align_circulation_with_z(ww, circ) new_ws = gc.cartesian_to_poincare_polar(new_ws) else: new_ws = ww fs = [(new_ws[:,j] + 1j*new_ws[:,j+ws.shape[-1]//2]) for j in range(ws.shape[-1]//2)] sf = SuperFreq(t, p=hamming_p) try: freqs,d,ixs = sf.find_fundamental_frequencies(fs, nintvec=nintvec) except: allfreqs.append([np.nan,np.nan,np.nan]) allamps.append([np.nan,np.nan,np.nan]) continue allfreqs.append(freqs.tolist()) allamps.append(d['|A|'][ixs].tolist()) allfreqs = np.array(allfreqs) allamps = np.array(allamps) return allfreqs, allamps
def run(self, w0, H): c = self.config # return dict result = self._empty_result # get timestep and nsteps for integration try: dt, nsteps = estimate_dt_n_steps( w0, H, n_periods=c.n_periods, n_steps_per_period=c.n_steps_per_period, func=np.nanmin, Integrator=gi.DOPRI853Integrator) except RuntimeError: result['error_code'] = 2 return result except: result['error_code'] = 9 return result # integrate orbit logger.debug("Integrating orbit with dt={0}, nsteps={1}".format( dt, nsteps)) try: orbit = H.integrate_orbit(w0, dt=dt, n_steps=nsteps, Integrator=gi.DOPRI853Integrator, Integrator_kwargs=dict(atol=1E-11)) except RuntimeError: # ODE integration failed logger.warning("Orbit integration failed.") dEmax = 1E10 else: logger.debug( 'Orbit integrated successfully, checking energy conservation...' ) # check energy conservation for the orbit E = orbit.energy() dEmax = np.max(np.abs((E[1:] - E[0]) / E[0])) logger.debug('max(∆E) = {0:.2e}'.format(dEmax)) if dEmax > c.energy_tolerance: result['error_code'] = 4 result['dE_max'] = dEmax return result # start finding the frequencies -- do first half then second half sf1 = SuperFreq(orbit.t[:nsteps // 2 + 1].value, p=c.hamming_p) sf2 = SuperFreq(orbit.t[nsteps // 2:].value, p=c.hamming_p) # classify orbit full orbit circ = orbit.circulation() is_tube = np.any(circ) # define slices for first and second parts sl1 = slice(None, nsteps // 2 + 1) sl2 = slice(nsteps // 2, None) if is_tube and not c.force_cartesian: # first need to flip coordinates so that circulation is around z axis new_orbit = orbit.align_circulation_with_z(circ) fs1 = orbit_to_poincare_polar(new_orbit[sl1]) fs2 = orbit_to_poincare_polar(new_orbit[sl2]) else: # box ws = orbit.w() fs1 = [(ws[j, sl1] + 1j * ws[j + 3, sl1]) for j in range(3)] fs2 = [(ws[j, sl2] + 1j * ws[j + 3, sl2]) for j in range(3)] logger.debug("Running SuperFreq on the orbits") try: freqs1, d1, ixs1 = sf1.find_fundamental_frequencies( fs1, nintvec=c.n_intvec) freqs2, d2, ixs2 = sf2.find_fundamental_frequencies( fs2, nintvec=c.n_intvec) except: result['error_code'] = 5 return result result['freqs'] = np.vstack((freqs1, freqs2)) result['dE_max'] = dEmax result['is_tube'] = float(is_tube) result['dt'] = float(dt) result['nsteps'] = nsteps result['amps'] = np.vstack((d1['|A|'][ixs1], d2['|A|'][ixs2])) result['success'] = True result['error_code'] = 1 return result
def run(cls, w0, **kwargs): c = dict() for k in cls.config_defaults.keys(): if k not in kwargs: c[k] = cls.config_defaults[k] else: c[k] = kwargs[k] # return dict result = dict() # get timestep and nsteps for integration binary_period = 2*np.pi # Omega = 1 dt = binary_period / c['nsteps_per_period'] nsteps = c['nperiods'] * c['nsteps_per_period'] # integrate orbit logger.debug("Integrating orbit with dt={0}, nsteps={1}".format(dt, nsteps)) try: t = np.linspace(0., c['nperiods']*binary_period, nsteps) t,ws = dop853_integrate_r3bp(np.atleast_2d(w0).copy(), t, c['q'], c['ecc'], c['nu'], atol=1E-11, rtol=1E-10, nmax=0) except RuntimeError: # ODE integration failed logger.warning("Orbit integration failed.") dEmax = 1E10 else: logger.debug('Orbit integrated successfully, checking energy conservation...') # check Jacobi energy conservation for the orbit E = 2*r3bp_potential(ws[:,0,:3].copy(), c['q'], c['ecc'], c['nu']) \ - (ws[:,0,3]**2 + ws[:,0,4]**2 + ws[:,0,5]**2) dE = np.abs(E[1:] - E[0]) dEmax = dE.max() / np.abs(E[0]) logger.debug('max(∆E) = {0:.2e}'.format(dEmax)) if dEmax > c['energy_tolerance']: logger.warning("Failed due to energy conservation check.") result['freqs'] = np.ones((2,2))*np.nan result['success'] = False result['error_code'] = 2 result['dE_max'] = dEmax return result # start finding the frequencies -- do first half then second half sf1 = SuperFreq(t[:nsteps//2+1], p=c['hamming_p']) sf2 = SuperFreq(t[nsteps//2:], p=c['hamming_p']) # define slices for first and second parts sl1 = slice(None,nsteps//2+1) sl2 = slice(nsteps//2,None) # TODO: the 2's below should change if we do the full 3d problem if c['force_cartesian']: fs1 = [(ws[sl1,0,j] + 1j*ws[sl1,0,j+3]) for j in range(2)] fs2 = [(ws[sl2,0,j] + 1j*ws[sl2,0,j+3]) for j in range(2)] else: # use Poincare polars # first need to flip coordinates so that circulation is around z axis new_ws = gc.cartesian_to_poincare_polar(ws) fs1 = [(new_ws[sl1,j] + 1j*new_ws[sl1,j+3]) for j in range(2)] fs2 = [(new_ws[sl2,j] + 1j*new_ws[sl2,j+3]) for j in range(2)] logger.debug("Running SuperFreq on the orbits") try: freqs1,d1,ixs1 = sf1.find_fundamental_frequencies(fs1, nintvec=c['nintvec']) freqs2,d2,ixs2 = sf2.find_fundamental_frequencies(fs2, nintvec=c['nintvec']) except: result['freqs'] = np.ones((2,2))*np.nan result['success'] = False result['error_code'] = 3 return result result['freqs'] = np.vstack((freqs1, freqs2)) result['dE_max'] = dEmax result['dt'] = float(dt) result['nsteps'] = nsteps result['amps'] = np.vstack((d1['|A|'][ixs1], d2['|A|'][ixs2])) result['success'] = True result['error_code'] = 0 return result
def run(cls, w0, potential, **kwargs): c = dict() for k in cls.config_defaults.keys(): if k not in kwargs: c[k] = cls.config_defaults[k] else: c[k] = kwargs[k] # return dict result = dict() # get timestep and nsteps for integration try: dt, nsteps = estimate_dt_nsteps(w0.copy(), potential, c['nperiods'], c['nsteps_per_period']) except RuntimeError: logger.warning("Failed to integrate orbit when estimating dt,nsteps") result['freqs'] = np.ones((2,3))*np.nan result['success'] = False result['error_code'] = 1 return result except: logger.warning("Unexpected failure!") result['freqs'] = np.ones((2,3))*np.nan result['success'] = False result['error_code'] = 4 return result # integrate orbit logger.debug("Integrating orbit with dt={0}, nsteps={1}".format(dt, nsteps)) try: t,ws = potential.integrate_orbit(w0.copy(), dt=dt, nsteps=nsteps, Integrator=gi.DOPRI853Integrator, Integrator_kwargs=dict(atol=1E-11)) except RuntimeError: # ODE integration failed logger.warning("Orbit integration failed.") dEmax = 1E10 else: logger.debug('Orbit integrated successfully, checking energy conservation...') # check energy conservation for the orbit E = potential.total_energy(ws[:,0,:3].copy(), ws[:,0,3:].copy()) dE = np.abs(E[1:] - E[0]) dEmax = dE.max() / np.abs(E[0]) logger.debug('max(∆E) = {0:.2e}'.format(dEmax)) if dEmax > c['energy_tolerance']: logger.warning("Failed due to energy conservation check.") result['freqs'] = np.ones((2,3))*np.nan result['success'] = False result['error_code'] = 2 result['dE_max'] = dEmax return result # start finding the frequencies -- do first half then second half sf1 = SuperFreq(t[:nsteps//2+1], p=c['hamming_p']) sf2 = SuperFreq(t[nsteps//2:], p=c['hamming_p']) # classify orbit full orbit circ = gd.classify_orbit(ws) is_tube = np.any(circ) # define slices for first and second parts sl1 = slice(None,nsteps//2+1) sl2 = slice(nsteps//2,None) if is_tube and not c['force_cartesian']: # first need to flip coordinates so that circulation is around z axis new_ws = gd.align_circulation_with_z(ws, circ) new_ws = gc.cartesian_to_poincare_polar(new_ws) fs1 = [(new_ws[sl1,j] + 1j*new_ws[sl1,j+3]) for j in range(3)] fs2 = [(new_ws[sl2,j] + 1j*new_ws[sl2,j+3]) for j in range(3)] else: # box fs1 = [(ws[sl1,0,j] + 1j*ws[sl1,0,j+3]) for j in range(3)] fs2 = [(ws[sl2,0,j] + 1j*ws[sl2,0,j+3]) for j in range(3)] logger.debug("Running SuperFreq on the orbits") try: freqs1,d1,ixs1 = sf1.find_fundamental_frequencies(fs1, nintvec=c['nintvec']) freqs2,d2,ixs2 = sf2.find_fundamental_frequencies(fs2, nintvec=c['nintvec']) except: result['freqs'] = np.ones((2,3))*np.nan result['success'] = False result['error_code'] = 3 return result result['freqs'] = np.vstack((freqs1, freqs2)) result['dE_max'] = dEmax result['is_tube'] = float(is_tube) result['dt'] = float(dt) result['nsteps'] = nsteps result['amps'] = np.vstack((d1['|A|'][ixs1], d2['|A|'][ixs2])) result['success'] = True result['error_code'] = 0 return result
def run(cls, w0, potential, **kwargs): c = dict() for k in cls.config_defaults.keys(): if k not in kwargs: c[k] = cls.config_defaults[k] else: c[k] = kwargs[k] # container for return result = dict() # automatically estimate dt, nsteps try: dt, nsteps = estimate_dt_nsteps(w0.copy(), potential, c['total_nperiods'], c['nsteps_per_period']) except RuntimeError: logger.warning("Failed to integrate orbit when estimating dt,nsteps") result['freqs'] = np.nan result['success'] = False result['error_code'] = 1 return result logger.debug("Integrating orbit with dt={0}, nsteps={1}".format(dt, nsteps)) try: t,ws = potential.integrate_orbit(w0.copy(), dt=dt, nsteps=nsteps, Integrator=gi.DOPRI853Integrator, Integrator_kwargs=dict(atol=1E-11)) except RuntimeError: # ODE integration failed logger.warning("Orbit integration failed.") dEmax = 1E10 else: logger.debug('Orbit integrated successfully, checking energy conservation...') # check energy conservation for the orbit E = potential.total_energy(ws[:,0,:3].copy(), ws[:,0,3:].copy()) dE = np.abs(E[1:] - E[0]) dEmax = dE.max() / np.abs(E[0]) logger.debug('max(∆E) = {0:.2e}'.format(dEmax)) if dEmax > c['energy_tolerance']: logger.warning("Failed due to energy conservation check.") result['freqs'] = np.nan result['success'] = False result['error_code'] = 2 return result # windowing properties - convert from period to steps window_width = int(c['window_width'] * c['nsteps_per_period']) window_stride = int(c['window_stride'] * c['nsteps_per_period']) # classify orbit full orbit circ = gd.classify_orbit(ws[:,0]) is_tube = np.any(circ) logger.debug("Running SuperFreq on each window:") allfreqs = [] allamps = [] for (i1,i2),ww in rolling_window(ws[:,0], window_size=window_width, stride=window_stride, return_idx=True): if i2 >= nsteps: break logger.debug("Window: {0}:{1}".format(i1,i2)) if is_tube and not c['force_cartesian']: # need to flip coordinates until circulation is around z axis new_ws = gd.align_circulation_with_z(ww, circ) new_ws = gc.cartesian_to_poincare_polar(new_ws) else: new_ws = ww fs = [(new_ws[:,j] + 1j*new_ws[:,j+3]) for j in range(3)] naff = SuperFreq(t[i1:i2], p=c['hamming_p']) try: freqs,d,ixs = naff.find_fundamental_frequencies(fs, nintvec=c['nintvec']) except: result['freqs'] = np.nan result['success'] = False result['error_code'] = 3 return result allfreqs.append(freqs.tolist()) allamps.append(d['|A|'][ixs].tolist()) allfreqs = np.array(allfreqs) allamps = np.array(allamps) result['freqs'] = allfreqs result['amps'] = allamps result['dE_max'] = dEmax result['dt'] = float(dt) result['nsteps'] = nsteps result['is_tube'] = is_tube result['success'] = True result['error_code'] = 0 return result
# -*- coding: utf-8 -*- """ Created on Sun May 17 15:31:44 2020 @author: BrianTCook """ import numpy as np import glob import matplotlib.pyplot as plt from superfreq import SuperFreq, find_frequencies datadir_AMUSE = '/Users/BrianTCook/Desktop/Thesis/second_project_gcs/Enbid-2.0/AMUSE_data/' t = np.linspace(0., 100., 51) #0 to 100 Myr only saving every 2 Myr sf = SuperFreq(t) logN_max = 6 simulation_tags = [2**i for i in range(1, logN_max + 1)] plt.rc('text', usetex=True) plt.rc('font', family='serif') plt.figure() nstars_clusterzero = 1096 nstars_clusterone = 300 end_index = nstars_clusterzero + nstars_clusterone for i, tag in enumerate(simulation_tags):