def IntegratorNL1D(V, P, C_V, C_P, probeReadFinishBe, probeReadStartAf): i = 1 V.tempVarPol, V.tempTempVarE, V.tempVarE, V.tempTempVarPol, V.polarisationCurr, V.Ex, V.Dx, V.Hy = BaseFDTD11.FieldInit( V, P) #Not necessary? V.UpHyMat, V.UpExMat = BaseFDTD11.EmptySpaceCalc(V, P) # move these into bc manager, call bc manager from here C_V = BaseFDTD11.CPML_FieldInit(V, P, C_V, C_P) C_V = boundCondManager(V, P, C_V, C_P) lamCont, lamDisc, diff, V.plasmaFreqE, fix = gStab.spatialStab( P.timeSteps, P.Nz, P.dz, P.freq_in, P.delT, V.plasmaFreqE, V.omega_0E, V.gammaE) Exs, Hys = SourceManager(V, P, C_V, C_P) #Exs = Sig_Mod(V,P, Exs) #Hys = Sig_Mod(V,P, Hys, AmpMod = 1/P.CharImp) for counts in range(0, P.timeSteps): #if i == 1: #V.tempTempVarPol, V.tempVarPol, V.tempVarE, V.tempTempVarE, V.tempTempVarHy, V.tempVarHy, V.tempTempVarJx, V.tempVarJx, C_V.tempTempVarPsiEx, C_V.tempVarPsiEx, C_V.tempTempVarPsiHy, C_V.tempVarPsiHy = BaseFDTD11.ADE_TempPolCurr(V,P, C_V, C_P) #V.polarisationCurr = BaseFDTD11.ADE_PolarisationCurrent_Ex(V, P, C_V, C_P, counts) V.Ex = BaseFDTD11.ADE_ExUpdate(V, P, C_V, C_P, counts) # V.Jx = BaseFDTD11.ADE_JxUpdate(V,P, C_V, C_P) if P.CPMLXp == True or P.CPMLXm == True: # Go into cpml field updates to choose x+ and x- C_V.psi_Ex, V.Ex = BaseFDTD11.CPML_Psi_e_Update(V, P, C_V, C_P) V.Ex[P.nzsrc] += Exs[counts] / P.courantNo if P.TFSF == True: V.Hy[P.nzsrc - 1] -= Hys[counts] / P.courantNo V.Dx = BaseFDTD11.ADE_DxUpdate(V, P, C_V, C_P) # Linear bit # V.Ex =BaseFDTD11.ADE_ExCreate(V, P, C_V, C_P) V.Acubic = BaseFDTD11.AcubicFinder(V, P) if not counts % 50: print(counts) V.Ex = BaseFDTD11.NonLinExUpdate(V, P) V.Hy = BaseFDTD11.ADE_HyUpdate(V, P, C_V, C_P) if P.CPMLXp == True or P.CPMLXm == True: C_V.psi_Hy, V.Hy = BaseFDTD11.CPML_Psi_m_Update(V, P, C_V, C_P) if counts > 0: if counts % P.vidInterval == 0: if i == 1: V.Ex_History = vidMake(V, P, C_V, C_P, counts, V.Ex, whichField="Ex") V.Port1, V.Port2 = probeSim(V, P, C_V, C_P, counts, nonlinear=True) return V.Ex, V.Hy, Exs, Hys, C_V.psi_Ex, C_V.psi_Hy, V.x1ColBe, V.x1ColAf
def TimeIter(A, B, UnP1A, UnP1B, Xn, V, P, C_V, C_P): Exs, Hys = BF.SmoothTurnOn(V, P) print("MOR Time stepping...") for jj in range(P.timeSteps): print("Timestepping, step number: ", jj) UnP1A, UnP1B, B = BAndSourceVector(V, P, C_V, C_P) UnP1A[P.nzsrc] = Hys[jj] / P.CharImp UnP1B[P.nzsrc - 1] = -Exs[jj] UnP1 = np.block([UnP1A, UnP1B]) #UnP1 = sparse.csc_matrix(UnP1) B = sparse.csc_matrix(B) #Xn = sparse.csc_matrix(Xn) XnP1 = np.zeros(2 * P.Nz + 2) #XnP1 = sparse.csc_matrix(XnP1) if jj == 0: XnP1 = A @ Xn.T XnP1 += B @ UnP1.T elif jj > 0: XnP1 = A @ XnP1.T XnP1 += B @ UnP1.T # XnP1 = XnP1.todense() for ii in range(len(V.Ex)): V.Ex[ii] = XnP1[ii] V.Hy[ii] = XnP1[ii + len(V.Ex)] V.Ex_History[jj] = V.Ex Xn = XnP1 return B, V.Ex, V.Ex_History, V.Hy, UnP1, Xn
def boundCondManager(V, P, C_V, C_P): # in here we set up boundary conditions, if cpml, call relevant cpml stuff, # or call other boundary condition update funcs. # if no B.Cs needed, set dummy var arrays as ones. #integrators call this to set up boundary conditions and call appropriate #features. switch case? if P.CPMLXp or P.CPMLXm: C_V.sigma_Ex, C_V.sigma_Hy, C_V.alpha_Ex, C_V.alpha_Hy, C_V.kappa_Ex, C_V.kappa_Hy = BaseFDTD11.CPML_ScalingCalc( V, P, C_V, C_P) C_V.beX, C_V.ceX = BaseFDTD11.CPML_Ex_RC_Define(V, P, C_V, C_P) C_V.bmY, C_V.cmY = BaseFDTD11.CPML_HY_RC_Define(V, P, C_V, C_P) C_V.eLoss_CPML, C_V.Ca, C_V.Cb, C_V.Cc = BaseFDTD11.CPML_Ex_Update_Coef( V, P, C_V, C_P) C_V.mLoss_CPML, C_V.C1, C_V.C2, C_V.C3 = BaseFDTD11.CPML_Hy_Update_Coef( V, P, C_V, C_P) C_V.den_Exdz, C_V.den_Hydz = BaseFDTD11.denominators(V, P, C_V, C_P) return C_V
def SourceManager(V, P, C_V, C_P): ## boolean fed into argument which chooses source to use and creates appropiately. if P.SineCont == True: Exs, Hys1 = BaseFDTD11.SmoothTurnOn(V, P) Exp, Hyp1 = np.zeros(P.timeSteps), np.zeros(P.timeSteps) if P.nonLinMed: tempfreq = P.freq_in pumpFreq = tempfreq * 0.8 Exp, Hyp1 = BaseFDTD11.SmoothTurnOn(V, P, tempfreq=pumpFreq) Exp = np.asarray(Exp) * P.courantNo Hyp1 = np.asarray(Hyp1) * P.courantNo Exp *= 0.1 Hyp1 *= 0.01 Exs = np.asarray(Exs) * P.courantNo + Exp Hys1 = np.asarray(Hys1) * P.courantNo + Hyp1 #breakpoint() if P.TFSF == True: Hys1 = Hys1 * (1 / P.CharImp) return Exs, Hys1 # #if SineCont == True #run SineCont function with no of repeatsm time +interval between if P.Gaussian == True: # Generate Exs and use Exs = BaseFDTD11.Gaussian(V, P) Hys = np.zeros(len(Exs)) if P.TFSF == True: Hys = BaseFDTD11.Gaussian(V, P) #plt.plot(Exs) # Width and other components should be defaulted in construct of sourcemanager # source manager changes the source point then returns whole field #if Ricker == True # Ricker func in basefdtd11. return Exs, Hys return [], []
def results(V, P, C_V, C_P, time_Vec, RefCo=False, FFT=False, AnalRefCo=False, attenRead=False): valM = np.zeros(len(V.x1Atten)) attenCo = np.zeros(len(valM)) if attenRead == True: sig_pow, sample_freq, val = transH.RefTester(V, P, V.x1ColBe, 1) for i in range(len(V.x1Atten)): valM[i] = transH.RefTester(V, P, V.x1Atten[i], 1, mul=True) attenCo[i] = valM[i] / val #breakpoint() return attenCo elif RefCo == True: #transm, sig_fft1, sig_fft2, sample_freq, timePadded = sig_pow, sample_freq, val = transH.RefTester(V, P, V.x1ColBe, 1) sig2_pow, sample_freq, val2 = transH.RefTester(V, P, V.x1ColAf, 1) #breakpoint() reflectCo = val2 / val #plt.plot(sample_freq,sig_fft) # plt.plot(sample_freq,abs(sig_fft2)) #breakpoint() #reflectCo = transH.ReflectionCalc(P, V, sample_freq, sig_pow, sig2_pow) return reflectCo elif AnalRefCo == True: analReflectCo = BaseFDTD11.AnalyticalReflectionE(V, P) return analReflectCo return "results ran to end"
def IntegratorLinLor1D(V, P, C_V, C_P, probeReadFinishBe, probeReadStartAf): for i in range(0, 2): V.tempVarPol, V.tempTempVarE, V.tempVarE, V.tempTempVarPol, V.polarisationCurr, V.Ex, V.Dx, V.Hy = BaseFDTD11.FieldInit( V, P) V.UpHyMat, V.UpExMat = BaseFDTD11.EmptySpaceCalc(V, P) # move these into bc manager, call bc manager from here C_V = BaseFDTD11.CPML_FieldInit(V, P, C_V, C_P) C_V = boundCondManager(V, P, C_V, C_P) lamCont, lamDisc, diff, V.plasmaFreqE, fix = gStab.spatialStab( P.timeSteps, P.Nz, P.dz, P.freq_in, P.delT, V.plasmaFreqE, V.omega_0E, V.gammaE) Exs, Hys = SourceManager(V, P, C_V, C_P) tauIn = 1 / (P.freq_in / 5) #Exs = Sig_Mod(V,P, Exs,tau =tauIn) # Hys = Sig_Mod(V,P, Hys, AmpMod = 1/P.CharImp, tau = tauIn) #gStab.vonNeumannAnalysis(V,P,C_V,C_P) V.test = 0 for counts in range(0, P.timeSteps): if i == 1: V.tempTempVarPol, V.tempVarPol, V.tempVarE, V.tempTempVarE, V.tempTempVarHy, V.tempVarHy, V.tempTempVarJx, V.tempVarJx, C_V.tempTempVarPsiEx, C_V.tempVarPsiEx, C_V.tempTempVarPsiHy, C_V.tempVarPsiHy = BaseFDTD11.ADE_TempPolCurr( V, P, C_V, C_P) V.polarisationCurr = BaseFDTD11.ADE_PolarisationCurrent_Ex( V, P, C_V, C_P, counts) V.Ex = BaseFDTD11.ADE_ExUpdate(V, P, C_V, C_P, counts) # V.Jx = BaseFDTD11.ADE_JxUpdate(V,P, C_V, C_P) if P.CPMLXp == True or P.CPMLXm == True: # Go into cpml field updates to choose x+ and x- C_V.psi_Ex, V.Ex = BaseFDTD11.CPML_Psi_e_Update(V, P, C_V, C_P) V.Ex[P.nzsrc] += Exs[counts] / P.courantNo if P.TFSF == True: V.Hy[P.nzsrc - 1] -= Hys[counts] / P.courantNo V.Dx = BaseFDTD11.ADE_DxUpdate(V, P, C_V, C_P) V.Ex = BaseFDTD11.ADE_ExCreate(V, P, C_V, C_P) V.Hy = BaseFDTD11.ADE_HyUpdate(V, P, C_V, C_P) if P.CPMLXp == True or P.CPMLXm == True: C_V.psi_Hy, V.Hy = BaseFDTD11.CPML_Psi_m_Update(V, P, C_V, C_P) #V.Ex = BaseFDTD11.MUR1DEx(V, P, C_V, C_P) #C_V.psi_Ex, V.Ex = BaseFDTD11.CPML_Psi_e_Update(V,P, C_V, C_P) # V.Ex = BaseFDTD11.MUR1DEx(V, P, C_V, C_P) """ Re write probes to not require Ex_History. Re write History to be optional and be taken in interval steps Re write probes into a different function Create transmission probes and attenuation probes. Spatial dispersion plot alongside looping parameters Function which plots epsilon, mu, refractive index etc with loop Rigorous reflection and transmission probe timings. Beer's law vs attenuation plot clean up redundant code, split big functions into smaller ones, split scripts into multiple scripts. Prepare for nonlinear ade (Harmonics, then resonance tuning Manley-Rowe verification, resonance tuning verification?) Prepare for 2D, (Extra update fields, plots, dispersion checks, 2D checks angles stuff, geometry designer) Simple charged particle distribution evolution. 25th Jan? should free space pre-reflection be running Dx? Maybe just call free space integrator once? """ if counts > 0: # MOVE TO FUNCTION if counts % P.vidInterval == 0: if i == 1: V.Ex_History = vidMake(V, P, C_V, C_P, counts, V.Ex, whichField="Ex") # option to not store history, and even when storing, only store in #intervals if i == 0: if counts <= P.timeSteps - 1: if counts <= probeReadFinishBe: V.x1ColBe = probeSim(V, P, C_V, C_P, counts, V.Ex[P.x1Loc]) #change this from Ex history elif i == 1: if counts <= P.timeSteps - 1: if counts >= probeReadStartAf: V.x1ColAf = probeSim(V, P, C_V, C_P, counts, V.Ex[P.x2Loc], af=True) if P.atten == True: V.x1Atten = probeSim(V, P, C_V, C_P, counts, V.Ex[P.x2Loc], attenRead=True) return V.Ex, V.Hy, Exs, Hys, C_V.psi_Ex, C_V.psi_Hy, V.x1ColBe, V.x1ColAf
def IntegratorFreeSpace1D(V, P, C_V, C_P, probeReadFinishBe, probeReadStartAf): for i in range(0, 2): V.tempVarPol, V.tempTempVarE, V.tempVarE, V.tempTempVarPol, V.polarisationCurr, V.Ex, V.Dx, V.Hy = BaseFDTD11.FieldInit( V, P) #analReflectCo, dispPhaseVel, realV = BaseFDTD11.AnalyticalReflectionE(V,P) V.UpHyMat, V.UpExMat = BaseFDTD11.EmptySpaceCalc(V, P) V.epsilon, V.mu, V.UpExHcompsCo, V.UpExSelf, V.UpHyEcompsCo, V.UpHySelf = BaseFDTD11.Material( V, P) V.UpHyMat, V.UpExMat = BaseFDTD11.UpdateCoef(V, P) # move these into bc manager, call bc manager from here C_V = BaseFDTD11.CPML_FieldInit(V, P, C_V, C_P) C_V = boundCondManager(V, P, C_V, C_P) # PROBABLY BETTER TO RUN THIS IN LINEAR DISP INTEGRATOR #lamCont, lamDisc, diff, V.plasmaFreqE, fix = gStab.spatialStab(P.timeSteps,P.Nz,P.dz, P.freq_in, P.delT, V.plasmaFreqE, V.omega_0E, V.gammaE) Exs, Hys = SourceManager(V, P, C_V, C_P) tauIn = 1 / (P.freq_in / 5) Exs = Sig_Mod(V, P, Exs, tau=tauIn) Hys = Sig_Mod(V, P, Hys, AmpMod=1 / P.CharImp, tau=tauIn) #gStab.vonNeumannAnalysis(V,P,C_V,C_P) if P.julia: V, P, C_V, C_P = JH.Jul_Integrator_Prep(V, P, C_V, C_P, Exs, Hys, i) else: for counts in range(0, P.timeSteps): #if counts%(int(P.timeSteps/10)) == 0: # print("timestep progress:", counts, "/", P.timeSteps) V.Ex = BaseFDTD11.ADE_ExUpdate(V, P, C_V, C_P, counts) if P.CPMLXp or P.CPMLXm: # Go into cpml field updates to choose x+ and x- C_V.psi_Ex, V.Ex = BaseFDTD11.CPML_Psi_e_Update( V, P, C_V, C_P) ## SOURCE MANAGER COMES IN HERE V.Ex[P.nzsrc] += Exs[counts] / P.courantNo if P.TFSF == True: V.Hy[P.nzsrc - 1] -= Hys[counts] / P.courantNo #### V.Hy = BaseFDTD11.ADE_HyUpdate(V, P, C_V, C_P) if P.CPMLXp or P.CPMLXm: C_V.psi_Hy, V.Hy = BaseFDTD11.CPML_Psi_m_Update( V, P, C_V, C_P) ################## # V.tempTempVarPol, V.tempVarPol, V.tempVarE, V.tempTempVarE, V.tempTempVarHy, V.tempVarHy, V.tempTempVarJx, V.tempVarJx, C_V.tempTempVarPsiEx, C_V.tempVarPsiEx, C_V.tempTempVarPsiHy, C_V.tempVarPsiHy = BaseFDTD11.ADE_TempPolCurr(V,P, C_V, C_P) #V.Ex = BaseFDTD11.MUR1DEx(V, P, C_V, C_P) ######################### if counts > 0: if counts % P.vidInterval == 0: if i == 1: V.Ex_History = vidMake(V, P, C_V, C_P, counts, V.Ex, whichField="Ex") # option to not store history, and even when storing, only store in #intervals if i == 0: if counts <= P.timeSteps - 1: if counts <= probeReadFinishBe: V.x1ColBe = probeSim(V, P, C_V, C_P, counts, V.Ex[P.x1Loc]) #change this from Ex history elif i == 1: if counts <= P.timeSteps - 1: if counts >= probeReadStartAf: V.x1ColAf = probeSim(V, P, C_V, C_P, counts, V.Ex[P.x2Loc], af=True) if P.atten == True: V.x1Atten = probeSim(V, P, C_V, C_P, counts, V.Ex[P.x2Loc], attenRead=True) #FDdata, FDXaxis, FDdataPow = gft(V,P, C_V, C_P, V.x1ColBe) # freq dom stuff for reflection return V.Ex, V.Hy, Exs, Hys, C_V.psi_Ex, C_V.psi_Hy, V.x1ColBe, V.x1ColAf #Do I need to return C_V?
def solnDenecker(R, F, A, UnP1A, UnP1B, Xn, V, P, C_V, C_P, Kop, Kopt, De, Dh, pulseInit=True): checkLine = "inspect.currentframe().f_back.f_lineno" # I use this in an eval expression to write the current code line into a #console print out when debugging delayMOR = P.delayMOR Exs, Hys = BF.SmoothTurnOn(V, P) # breakpoint() print("MOR Time stepping...") if R.shape != (2 * P.Nz + 2, 2 * P.Nz + 2): print("R is wrong shape") sys.exit() if F.shape != (2 * P.Nz + 2, 2 * P.Nz + 2): print("F is wrong shape") sys.exit() # XnP1 = np.zeros(2 * P.Nz + 2) k = int(len(Xn) * 0.5) XnP1_red = np.zeros(k) XnP1 = XnP1.reshape(len(XnP1), 1) XnP1_red = XnP1_red.reshape(len(XnP1_red), 1) ratio = len(XnP1) / k #Q, H, k, Xn_red, XnP1_red, Q_sp = MORViaSPRIM(Xn, XnP1, 2*P.Nz+2,R, k, F, P, V, C_V, C_P) summer = (R + F) winter = (R - F) tic = time.perf_counter() summerInv = luInvert(summer) toc = time.perf_counter() ### CONDITION NUMBER EFFECTS ACCURACY OF INVERSION! print("LUinvert time: ", toc - tic) print("conditions numbers of summer, winter: ", np.linalg.cond(summer.todense()), np.linalg.cond(winter.todense())) #summer = vonNeumannAnalysisMOR(V, P, C_V, C_P, summer, "summer") #winter = vonNeumannAnalysisMOR(V, P, C_V, C_P, winter, "winter") #summer = sparse.csc_matrix(summer) if (sparse.issparse(winter)): winter = winter.todense() winter = np.asmatrix(winter) B = BGenerator(P) B = sparse.csc_matrix(B) In = np.identity(len(winter)) M = In M = sparse.csc_matrix(M) M2 = In M2 = sparse.csc_matrix(M2) s0 = 2 * np.pi * P.freq_in M = luInvert(s0 * In - summerInv @ winter, "M") #M2 = luInvert((s0*In -winter).conj().T, "M2") if sparse.issparse(M): M = M.todense() #M = np.asarray(M, dtype = np.complex128) #M2 = M2.todense() #M2 = np.asarray(M2, dtype = np.complex128) """ for jj in range(int(P.freq_in),int(P.freq_in)): s0 = 2*np.pi*jj M2= M2@(luInvert((s0*In).conj().T-winter.conj().T)) M2 = M2.todense() M2 = np.asarray(M2, dtype = np.float64) """ v0 = np.random.randint(5, size=(len(winter), k)) #*(1+1j) # v0 = v0.astype(np.complex128) v2 = np.random.randint(5, size=(len(winter), k)) #*(1+1j) # v2 = v2.astype(np.complex128) v0, RR = np.linalg.qr( v0) # if matix is complex returns unitary, normalise it... #v0 = v0/np.linalg.norm(v0) print(type(v0)) #print(type(v2)) #v2, R2 = np.linalg.qr(v2) #v2 = v2/np.linalg.norm(v2) # v0 = M@v0 # ? #v2 = M2@v2 # EAVars = EA(k, len(v0)) #breakpoint() print("Starting Arnoldi process................") tic = time.perf_counter() V_sp, RR = ExampleArnoldi(M, v0, k) #breakpoint() #V_sp, RR = np.linalg.qr(V_sp) orth = V_sp.T.conj() @ V_sp check = np.allclose(orth, np.identity(len(orth)), atol=1e-2) print(check, " = orthornormal check.") if check == False: print("first ten diagonal terms of orth:", np.diag(orth)[:10]) print(np.linalg.norm(V_sp), " norm of V_sp") #V_sp, R = np.linalg.qr(V_sp) #V_sp = V_sp/np.linalg.norm(V_sp) print(np.linalg.matrix_rank(V_sp, tol=1e-4), "/", V_sp.shape[1], "MATRIX RANK ") #V_sp = np.block([np.real(V_sp[:int(len(V_sp)/2)]), np.imag(V_sp[int(len(V_sp)/2):])]) toc = time.perf_counter() print("FINISHED ARNOLDI in: ", toc - tic) V_sp_UL = V_sp[:int(len(V_sp) / 2), :k] V_sp_UR = np.zeros((int(len(V_sp) / 2), k)) V_sp_LL = np.zeros((int(len(V_sp) / 2), k)) V_sp_LR = V_sp[int(len(V_sp) / 2):, :k] V_sp = np.block([[V_sp_UL, V_sp_UR], [V_sp_LL, V_sp_LR]]) if V_sp_UL.shape != V_sp_UR.shape or V_sp_LL.shape != V_sp_LR.shape or V_sp_LL.shape != V_sp_UR.shape: print("shapes of blocks for SPRIM partition not the same: ", V_sp_UL.shape, V_sp_UR.shape, V_sp_LL.shape, V_sp_LR.shape) sys.exit() # """ bob = V_sp.T@summer@V_sp bob2 = V_sp@bob@V_sp.T avgDiag = np.average(np.diag(bob2)) for i in range(bob2.shape[0]): for j in range(bob2.shape[1]): if abs(bob2[i,j]) <= abs(avgDiag)/5: bob2[i,j] = 0 factor = np.average(np.diag(summer.todense()) /np.average(np.diag(bob2))) bob2 = bob2*factor bob3 = np.real(bob2) # breakpoint() V_sp = np.hstack((np.real(V_sp), np.imag(V_sp))) # modify = 1/V_sp[0,0] print("V_sp: ", V_sp[:4,:4]) # V_sp*= modify #W_sp = np.hstack((np.real(W_sp), np.imag(W_sp))) V_sp_UL = V_sp[:int(len(V_sp)/2),:k] V_sp_UR = np.zeros((int(len(V_sp)/2), k)) V_sp_LL = np.zeros((int(len(V_sp)/2), k)) V_sp_LR = V_sp[int(len(V_sp)/2):,:k] V_sp = np.block([[V_sp_UL, V_sp_UR],[V_sp_LL, V_sp_LR]]) if V_sp_UL.shape !=V_sp_UR.shape or V_sp_LL.shape != V_sp_LR.shape or V_sp_LL.shape != V_sp_UR .shape: print("shapes of blocks for SPRIM partition not the same: ", V_sp_UL.shape, V_sp_UR.shape, V_sp_LL.shape, V_sp_LR.shape) sys.exit() if V_sp.shape[0] != P.Nz+2: print(V_sp.shape, " V_sp shape", P.Nz, " P.Nz") #check structure preservation # take top half of V_sp and W_sp print("Dimensions of V_sp should match Xn, Shape V vs Xn: ", V_sp.shape, Xn.shape) #breakpoint() #SPRIM PARTITION: #V_sp = # breakpoint() #V_sp, R = np.linalg.qr(V_sp)# # print("Performing Orthonormal tests") # check = np.allclose(V_sp.T @ V_sp, np.eye(V_sp.shape[1]), rtol =1e-1) # print(" ortho check: ", check) """ V_spt = V_sp.T # breakpoint() # M = sparse.csc_matrix(M) #A_red = M#Q_spt@M@Q_sp #winter_red = V_sp.T@winter@V_sp #summer_red = V_sp.T@summer@V_sp #print("condition numbers before preconditioning: ", np.linalg.cond(summer_red), np.linalg.cond(winter_red)) Vnorm = np.linalg.norm(V_sp) V_sp, rrr = np.linalg.qr(V_sp) V_sp *= Vnorm R_red = V_sp.T @ R @ V_sp F_red = V_sp.T @ F @ V_sp Kop_red_R = R_red[:int(len(R_red) / 2), int(len(R_red) / 2):] De_red_R = R_red[:int(len(R_red) / 2), :int(len(R_red) / 2)] Dh_red_R = R_red[int(len(R_red) / 2):, int(len(R_red) / 2):] #V_sp_LR.T@Dh@V_sp_LR Kop_red_pert = singularVDPertPreExpan(P, De_red_R, Dh_red_R, Kop_red_R) R_red[len(Kop_red_R):, :len(Kop_red_R)] = Kop_red_pert.T R_red[:len(Kop_red_R), len(Kop_red_R):] = Kop_red_pert # R_red[] # structure preservation preserves algebraic operations? XnP1_red = V_sp.T @ XnP1 winter_red = R_red - F_red summer_red = R_red + F_red summerJac = np.linalg.pinv(np.diag(np.diag(summer_red))) print("shape winter: ", winter.shape) #sumJac = np.linalg.inv(np.diag(np.diag(summer_red))) ## summer_red is badly conditioned? #winter_red = V_spt@winter@V_sp #summer_red = V_spt@summer@V_sp #A_red = sparse.csc_matrix(A_red) #if (sparse.issparse(A_red)): # A_red = A_red.todense() #print("Eigenvalue decomp...") #breakpoint() #winter_red= np.real(eigenvalueDecomp(winter_red)) #summer_red =np.real(eigenvalueDecomp(summer_red)) #AA, BB, CC, DD= eigenvalueDecomp(summer_red) # Inv AA @ summer_red should give I? #summer_red = AA@summer_red #AA, BB, CC, DD= eigenvalueDecomp(winter_red) #winter_red = AA@winter_red #check shapes of projection matrices #print("condition numbers reduced after preconditioning: ", np.linalg.cond(sumJac@summer_red), np.linalg.cond(winter_red)) #print("V_spt shape: ", V_spt.shape) # breakpoint() wl = len(winter_red) winter_red = sparse.csc_matrix(winter_red) # summer_red_inv = luInvert(summer_red, "summer_red") # summer_red_inv_spar = sparse.csc_matrix(summer_red_inv) summer_red_sparse = sparse.csc_matrix(summerJac @ summer_red) # comboBreaker = summer_red_inv_spar@winter_red ## H, HeigValsDiag, HeigVecsInv, HeigVecs = eigenvalueDecomp(comboBreaker) # summer_inv_Full = luInvert(summer) #comboBreakerFull =summer_inv_Full@winter #HF, HeigValsDiagF, HeigVecsInvF, HeigVecsF = eigenvalueDecomp(comboBreakerFull) # A_red = summer_red_inv@winter_red # summer_red = sparse.csc_matrix(summer_red) #B_a_red = Q_spt@inv@Q_sp interval = int(P.timeSteps / 10) # # sos = sig.butter(21, 0.01, output='sos') Spla = sparse.linalg.spilu(summer_red) lam = lambda x: Spla.solve(x) if sparse.issparse(summer_red): summer_red = summer_red.todense() MM = sparse.linalg.LinearOperator(summer_red.shape, lam) for jj in range(0, P.timeSteps): if jj % interval == 0: print("Timestepping, step number: ", jj, "/ ", P.timeSteps) # y = y.reshape(len(y),1) #XnP1 = sparse.linalg.spsolve((R+F), y) #XnP1 = sparse.csc_matrix(XnP1) UnP1A, UnP1B = SourceVector(V, P, C_V, C_P) #if B.shape != (2*P.Nz+2, 2*P.Nz+2): # print("B is wrong shape") # sys.exit() # UnP1A[:] = ((Hys[jj])/P.courantNo)*P.CharImp UnP1B[:] = ((Exs[jj]) / P.courantNo) UnP1 = np.block([UnP1A, UnP1B]) UnP1 = UnP1.reshape(len(UnP1), 1) UnP1_red = V_sp.T @ UnP1 #Q_spt@UnP1 UnP1_red = UnP1_red.reshape(len(UnP1_red), 1) # UnP1_red = sparse.csr_matrix(UnP1_red) #B = sparse.csr_matrix(B) #move out of bandsourvect print(B.shape) # breakpoint() B_red = V_sp.T @ B @ V_sp B_red = sparse.csc_matrix(B_red) In_red = np.identity(wl) In_red_sp = sparse.csc_matrix(In_red) if (pulseInit == False) or (pulseInit == True and jj >= delayMOR): #breakpoint() #print("shape of B_red: ", B_red.shape) # breakpoint() XnP1_red = XnP1_red.reshape(len(XnP1_red), 1) XnP1_red = sparse.csc_matrix(XnP1_red) #XnP1_red = summer_red_inv_spar@(winter_red@XnP1_red +B_red@UnP1_red) #breakpoint() y1 = winter_red @ XnP1_red + B_red @ UnP1_red #y1Full = V_spt@y1*100 #print(np.average(np.abs(y1)), " y1") # print("y shape if first before solve: " ,y.shape) #XnP1 = A@XnP1 + B@UnP1 #breakpoint() y1 = sparse.csr_matrix(y1) # breakpoint() # XnP1_red = summer_red_inv@y1 #breakpoint() # print("shapes of y1, summer_red: ", y1.shape, summer_red.shape) XnP1_red, info = sparse.linalg.gmres(summer_red, y1.todense(), x0=XnP1_red.todense(), atol=1e-4, M=MM, maxiter=250) if info != 0: print("iterations: ", info) #fig, ax = plt.subplots() XnP1 = (V_sp @ XnP1_red) #breakpoint() # XnP1 = sig.sosfiltfilt(sos, smooth(np.asarray([XnP1]).ravel(),1000, window = 'flat')) # print("Avg, min, max: ", np.average(np.abs(XnP1)), np.min(np.abs(XnP1)), np.max(np.abs(XnP1))) # np.min should return zero especially early on # print("SUM OFFFFFFFF: ", np.sum(XnP1)) checkNan(XnP1, eval(checkLine), jj) if (np.max(np.abs(XnP1)) * ratio <= 1e-8) and jj >= 30: print(np.average(np.abs(XnP1)), " Average val of XnP1", eval(checkLine)) sys.exit() if (np.average(np.abs(XnP1)) >= 1e2): print(np.average(np.abs(XnP1)), " Average val of XnP1", eval(checkLine)) plt.plot(XnP1) sys.exit() #print("first if") # check dimensions v_sp etc if jj % 25 == 0: print("Iteration of timeStep in MOR: ", jj, "/ ", P.timeSteps) #XnP1 = (V_sp@XnP1_red) #XnP1 = sig.sosfiltfilt(sos, smooth(np.asarray([XnP1]).ravel(),50, window = 'flat')) #XnP1 = XnP1*ratio**2 XnP1 = XnP1.reshape(len(XnP1), 1) XnP1_fin = np.real(XnP1) # breakpoint() elif pulseInit == True and jj < delayMOR: print("FOM pulse init stage: ", jj) XnP1 = sparse.csc_matrix(XnP1) y = winter @ XnP1 + B @ UnP1 # XnP1 = HeigValsDiagF@XnP1 + HeigVecsInvF@summer_inv_Full@B@UnP1 #breakpoint() if sparse.issparse(y): y = y.todense() #XnP1 = A@XnP1 + B@UnP1 #breakpoint() #y = sparse.csc_matrix(y) #print("y ", np.average(np.abs(y.todense()))) # print("second elif") #XnP1 = sparse.linalg.spsolve(summer, y) Spla1 = sparse.linalg.spilu(sparse.csc_matrix(summer)) lam1 = lambda x: Spla1.solve(x) if sparse.issparse(summer): summer = summer.todense() MM1 = sparse.linalg.LinearOperator(summer.shape, lam1) # print("shapes of y1, summer_red: ", y1.shape, summer_red.shape) XnP1, info = sparse.linalg.lgmres(summer, y, x0=XnP1.todense(), atol=1e-4, M=MM1, maxiter=50) if info != 0: print("iterations: ", info) checkNan(XnP1, eval(checkLine), jj) #print("Avg, min, max: ", np.average(np.abs(XnP1)), np.min(np.abs(XnP1)), np.max(np.abs(XnP1))) XnP1_red = V_sp.T @ XnP1 #print("Avg, max XnP1_red: ", np.average(np.abs(XnP1_red)), np.max(abs(XnP1_red))) # print("SUM OF XnP1 FOM: ", np.sum(XnP1)) #XnP1 = HeigVecsF@XnP1 # XnP1 = sig.sosfiltfilt(sos, smooth(np.asarray([XnP1]).ravel(),1000, window = 'flat')) XnP1 = XnP1.reshape(len(XnP1), 1) if (np.average(np.abs(XnP1)) >= 1e2): print(np.average(np.abs(XnP1)), " Average val of XnP1", eval(checkLine)) plt.plot(XnP1) sys.exit() XnP1_fin = np.real(XnP1) # Add in float var to move np.real XnP1 to prevent stdout discarding imag for ii in range(len(V.Ex) - 1): if sparse.issparse(XnP1): XnP1_fin = XnP1_fin.todense() # maybe don't discard imaginary part, use just real part for vid #breakpoint() V.Ex[ii] = XnP1_fin[ii][0] * ratio V.Hy[ii] = XnP1_fin[ii + len(V.Ex)][0] V.Ex_History[jj] = V.Ex return V.Ex, V.Ex_History, V.Hy, UnP1