# GPE Parameters from Wouters hbar = ureg.hbar.to_base_units() # Note Wouters denotes the coefficient of |\psi| ^ 2 as \hbar * g. We denote it # as g. g_C = (0.015 * ureg.millielectron_volt * ureg.micrometer * ureg.micrometer) g_C = g_C.to_base_units().magnitude g_R = 0 gamma_C = (0.5 * ureg.millielectron_volt) / hbar gamma_C = gamma_C.to_base_units().magnitude gamma_R = 4.0 * gamma_C R = (0.05 * ureg.millielectron_volt * ureg.micrometer * ureg.micrometer) / hbar R = R.to_base_units().magnitude # Wouters does not provide m. Let us assume it is 10e-4 m_e m = 10e-4 woutersParams = Simulator.ParameterContainer(g_C=g_C, g_R=g_R, gamma_C=gamma_C, gamma_R=gamma_R, R=R, m=m) params = woutersParams.getGPEParams() # Pump parameters for small and large spots from Wouters # P0 are both in units of Pth P0_large = 2.0 P0_small = 8.0 sigma_large = (20.0 * ureg.micrometer).to_base_units().magnitude sigma_small = (2.0 * ureg.micrometer).to_base_units().magnitude # Make pumps largePump = UtilityFunctions.GaussianPump(sigma_large, P0_large, params['Pth']) largePumpFunction = largePump.scaledFunction(woutersParams.charL) smallPump = UtilityFunctions.GaussianPump(sigma_small, P0_small, params['Pth'])
def runIt(g_C, R, gamma_C, a, width, diffusionLength, rMiddle, P): """ Do a simulation, plot and save a diagnostic plot. """ if singleComp: ringParams = Simulator.ParameterContainer(g_C=g_C, g_R=2.0 * g_C, gamma_nl=gamma_nl, gamma_C=gamma_C, gamma_R=a * gamma_C, R=R, m=m, charL=charL, charT=charT) else: ringParams = Simulator.ParameterContainer(g_C=g_C, g_R=2.0 * g_C, gamma_C=gamma_C, gamma_R=a * gamma_C, R=R, m=m, charL=charL, charT=charT) params = ringParams.getGPEParams() print params Pth = params["Pth"] # --- Grid, associated quantities --- grid = Simulator.Grid(ringParams.charL, max_XY=max_XY_unscaled, N=N) sigma = grid.toPixels(diffusionLength) x, y = grid.getSpatialGrid() x_us, y_us = grid.getSpatialGrid(scaled=False) dx = grid.dx_scaled # Time to record spectrum to. This will ensure that we have a resolution of # at least 0.01 meV spectMax = int(5e-6 / grid.dx_unscaled) # Mask for collection of spectrum and energy. This will ensure that we only # collect from the center of the ring mask = x_us**2 + y_us**2 > (5e-6)**2 # --- Initial wavefunction --- # Gaussian in the middle of the trap psi0 = UtilityFunctions.GaussianPump(0.2*rMiddle, 0.1, 1, exponent=1.1).\ scaledFunction(ringParams.charL) pump = UtilityFunctions.AnnularPumpFlat(rMiddle, width, P, Pth, sigma=sigma) # Since we used Pth from params, the pump will be in units of # L_C^-2 * T_C^-1 pumpFunction = pump.scaledFunction(ringParams.charL) # P0 = np.max(pumpFunction(x, y)) # print P0 # stabParam = (P0 / params['Pth']) / ((params['g_R'] * params['gamma_C']) # / (params['g_C'] * # params['gamma_R'])) # print("Stability parameter %f (should be > 1)" % stabParam) numStabParam = (np.pi * dt) / dx**2 if numStabParam >= 0.8: print( "Warning, numerical stability parameter is %.4f \n Should be <1 " % numStabParam) print("Numerical Stability Parameter %f (should be < 1)" % ((np.pi * dt) / dx**2)) solver = Simulator.GPESolver(ringParams, dt, grid, pumpFunction=pumpFunction, psiInitial=psi0, REAL_DTYPE=np.float64, COMPLEX_DTYPE=np.complex128) solver.stepTo(T_MAX, stepsPerObservation=1000, spectStart=T_STABLE, normalized=False, spectLength=spectLength, printTime=False, collectionMask=mask, spectMax=spectMax) f = diagnosticPlot(solver) f.savefig("PScanSingle " + getPlotName(ringParams, P=P) + ".png", dpi=500) # f.savefig("testPlot" + ".png", dpi=600) # solver.save("testPlot", P=P) solver.save("PScanSingle " + getPlotName(ringParams.getOutputParams(), P=P), P=P) plt.close(f)
def runIt(g_C, R, width, rMiddle, P): """ Do a simulation, plot and save a diagnostic plot. """ # if rMiddle <= 10 * ureg.micrometer.to_base_units().magnitude: # N = 512 # else: # N = 1024 ringParams = Simulator.ParameterContainer(g_C=g_C, g_R=2.0 * g_C, gamma_C=gamma_C, gamma_R=a * gamma_C, R=R, m=m, charL=charL, charT=charT) # ringParams = Simulator.ParameterContainer(g_C=g_C, g_R=2.0*g_C, # gamma_C=gamma_C, # gamma_R=a*gamma_C, R=R, m=m) params = ringParams.getGPEParams() # params['charT'] = ringParams.charT P0 = P * params['Pth'] # Make Grid # grid = Simulator.Grid(ringParams.charL, max_XY=max_XY_unscaled, N=N) # grid = Simulator.Grid(ringParams.charL, max_XY=3.0 * (rMiddle + width), N=N) grid = Simulator.Grid(ringParams.charL, max_XY=2.0 * (rMiddle + width), N=N) sigma = grid.toPixels(diffusionLength) x, y = grid.getSpatialGrid() x_us, y_us = grid.getSpatialGrid(scaled=False) pump = UtilityFunctions.AnnularPumpFlat(rMiddle, width, P, params['Pth'], sigma=sigma) # pump = UtilityFunctions.AnnularPumpGaussian(rMiddle, P, params['Pth'], # sigma=width) # pump = UtilityFunctions.GaussianPump(rMiddle, P, params['Pth']) pumpFunction = pump.scaledFunction(ringParams.charL) P0 = np.max(pumpFunction(x, y)) stabParam = (P0 / params['Pth']) / ((params['g_R'] * params['gamma_C']) / (params['g_C'] * params['gamma_R'])) # Gaussian in the middle of the trap psi0 = UtilityFunctions.GaussianPump(0.2*rMiddle, 0.01, 1, exponent=1.1).\ scaledFunction(ringParams.charL) # psi0 = lambda x, y: 0.01 * pumpFunction(x, y) / P0 print("Stability parameter %f (should be > 1)" % stabParam) dx = grid.dx_scaled print("Numerical Stability Parameter %f (should be < 1)" % ((np.pi * dt) / dx**2)) print("P = %f" % P) print("Pth = %f" % params['Pth']) print("P0 = %f" % P0) print("P0/Pth = %f" % (P0 / params['Pth'])) solver = Simulator.GPESolver(params, dt, grid.getSpatialGrid(), grid.getKSquaredGrid(), pumpFunction, psiInitial=psi0, gpu=True) energyTimes, energy = solver.stepTo(T_MAX, stepsPerObservation=100) # solver.stepTo(T_MAX, stepsPerObservation=1000) f = diagnosticPlot(1e6 * x_us, 1e6 * y_us, solver, energyTimes, energy, pump.scaledFunction(charL=1e-6)) f.savefig("Snoke" + getPlotName(params, r=rMiddle, m=m, sigma=diffusionLength) + ".png", dpi=800) # f.savefig("testNew" + ".png", dpi=800) plt.close(f)
g_Cs = g_C * np.logspace(-3, 3, num=5) # gamma_Cs = gamma_C * np.logspace(-1, 1, num=3) Rs = R * np.logspace(-3, 3, num=5) r = (15 * ureg.micrometer).to_base_units().magnitude sigma = (10 * ureg.micrometer).to_base_units().magnitude hbar = hbar.to_base_units().magnitude charT = 1 / gamma_C # charL = 1 * np.sqrt(hbar / (2 * m * me * gamma_C)) charL = (0.5 * ureg.micrometer).to_base_units().magnitude ringParams = Simulator.ParameterContainer(g_C=g_C, g_R=g_R, gamma_C=gamma_C, gamma_R=gamma_R, R=R, m=m, charL=charL, charT=charT) params = ringParams.getGPEParams() P0 = 4.0 * params['Pth'] # pump = UtilityFunctions.AnnularPump(r, P0, sigma) # pumpFunction = pump.scaledFunction(ringParams.charL) # Make Grid grid = Simulator.Grid(ringParams.charL, max_XY=max_XY_unscaled, N=N) x, y = grid.getSpatialGrid() x_us, y_us = grid.getSpatialGrid(scaled=False) # solver = Simulator.GPESolver(params, dt, grid.getSpatialGrid(), # grid.getKSquaredGrid(), pumpFunction,
def loadGPESolver(f): """ Load a GPESolver based on the saved solver f """ from pycuda import gpuarray ur = UnitRegistry() gOutput = "millieV * micrometer**2" rOutput = "millieV * micrometer**2 * hbar**-1" gammaOutput = "picosecond ** -1" gammaNlOutput = "millieV * micrometer**2 * hbar**-1" mOutput = "electron_mass" charLOutput = "micrometer" charTOutput = "picosecond" if "gamma_nl" in f.attrs: singleComp = True g_C = ur.Quantity(f.attrs["g_C"], gOutput) g_R = ur.Quantity(f.attrs["g_R"], gOutput) gamma_C = ur.Quantity(f.attrs["gamma_C"], gammaOutput) gamma_R = ur.Quantity(f.attrs["gamma_R"], gammaOutput) R = ur.Quantity(f.attrs["R"], rOutput) m = ur.Quantity(f.attrs["m"], mOutput) charL = ur.Quantity(f.attrs["charL"], charLOutput) charT = ur.Quantity(f.attrs["charT"], charTOutput) if singleComp: gamma_nl = ur.Quantity(f.attrs["g_R"], gammaNlOutput) paramContainer = Simulator.ParameterContainer(g_C=g_C, g_R=g_R, R=R, gamma_C=gamma_C, gamma_R=gamma_R, gamma_nl=gamma_nl, m=m, charL=charL, charT=charT) else: paramContainer = Simulator.ParameterContainer(g_C=g_C, g_R=g_R, R=R, gamma_C=gamma_C, gamma_R=gamma_R, m=m, charL=charL, charT=charT) N = f["n"].shape[0] max_XY = f["x_ax"][-1] * charL grid = Simulator.Grid(charL.to_base_units().magnitude, N=N, max_XY=max_XY) gpeSolver = Simulator.GPESolver(paramContainer, 0.1, grid) if singleComp: assert gpeSolver.singleComp, "We've made a double comp solver\ even though we loaded a single one" gpeSolver.n = gpuarray.to_gpu( np.array(f["n"], dtype=gpeSolver.n.get().dtype)) gpeSolver.Pdt = gpuarray.to_gpu( np.array(f[u'Pdt:'], dtype=gpeSolver.Pdt.get().dtype)) gpeSolver.psi = gpuarray.to_gpu( np.array(f["psi"], dtype=gpeSolver.psi.get().dtype)) gpeSolver.spectStartStep = 0 gpeSolver.spectLength = 0 gpeSolver.spectEndStep = 0 if "energy" in f.keys(): gpeSolver.energy = np.array(f["energy"], dtype=gpeSolver.n.get().dtype) if "number" in f.keys(): gpeSolver.number = np.array(f["number"], dtype=gpeSolver.n.get().dtype) if "times" in f.keys(): gpeSolver.times = np.array(f["times"], dtype=gpeSolver.n.get().dtype) if "spectrum" in f.keys(): gpeSolver.spectrum = np.array(f["spectrum"], dtype=gpeSolver.psi.get().dtype) gpeSolver.omega_axis = np.array(f["omega_axis"], dtype=gpeSolver.n.get().dtype) return gpeSolver