def main(): #Compute atom densities atm_perc = [0.99,0.01] rho = [19.86, 2.1] Na = 0.60221 #in atoms-cm^2/(mol-b) M = [239,12.01] atm_dens = [rho[i]*Na/M[i]*atm_perc[i] for i in range(len(rho))] #Process data # nd = NuclearData(["../crossx/Pu239_618gp_Pu239.cx","../crossx/h-fg_618gp_h-1.cx"],atm_dens=atm_dens) nd = NuclearData(["../crossx/Pu239_70gp_Pu239.cx","../crossx/cnat_70gp_cnat.cx"],atm_dens=atm_dens) # nd = NuclearData(["../crossx/Pu239_12gp_Pu239.cx","../crossx/h-fg_12gp_h-1.cx"],atm_dens=atm_dens) radius = findCriticalRadius(nd,verbosity=-1,keff=0.95) N = nd.n_groups #Compute keff keff, phi_fund = solveInfMedKeff(nd,radius=radius) print("Keff for this system is: ",keff) #Eigenvectors for forward and adjoint problems alphas, eig_vecs, L = solveInfMedForward(nd,return_matrix=True,radius=radius, sparse_matrix=True,verbosity=1) alphas_a, eig_vecs_a, L_a = solveInfMedAdjoint(nd,return_matrix=True,radius=radius) #Plot some eigenfunctions according to their alpha eigenvalues sorted_alphas = sorted(alphas, key=lambda x: np.real(x), reverse=True) alphas = list(alphas) alpha_keys = [alphas.index(i) for i in sorted_alphas] print_num = 3 # plotMultipleEigenvectors(nd, alpha_keys, alphas, eig_vecs, num=print_num, # title="Forward Eigenvectors for %d groups" % nd.n_groups) plt.semilogx(nd.groupCenters(), (phi_fund)/sum(phi_fund),"--k" ,label=r"$k_{eff}$ Fundamental Mode") plt.legend(loc='best') plt.savefig('for_eigs_c01_'+str(nd.n_groups)+'.pdf',bbox_inches='tight') plt.figure() sorted_alphas_a = sorted(alphas_a, key=lambda x: np.real(x), reverse=True) alphas_a = list(alphas_a) alpha_keys_a = [alphas_a.index(i) for i in sorted_alphas_a] # plotMultipleEigenvectors(nd, alpha_keys_a, alphas_a, eig_vecs_a, num=print_num, # title="Adjoint Eigenvectors for %d groups" % nd.n_groups) plt.legend(loc='best') plt.savefig('adj_eigs_c01_'+str(nd.n_groups)+'.pdf',bbox_inches='tight') #================================================= #Compute expansion coefficients for simple system N = nd.n_groups np.random.seed(10) source = 'delta' #options are delta or constant # q = np.random.uniform(0.8,1.2,size=N) # q = np.ones(N) #Delta in energy q = np.zeros(N) for n in range(N): ei = nd.group_edges if ei[n] > 14.1 and ei[n+1] < 14.1: idx = n break q[idx] = 1.0E3 # q = np.zeros(N) # q[0] = 1 # q = eig_vecs[:,np.argmax(alphas)]/nd.speed #Populate with a single mode #Index in adjoint alphas list corresponding to forward alpha eigenvalue fw_to_adj = getAlphaMap(alphas,alphas_a) #Compute source coupling coefficients q_n coeff = np.zeros(N,dtype=np.complex_) for n in range(N): try: norm = np.dot(eig_vecs_a[:,fw_to_adj[n]].conj(),eig_vecs[:,n]/nd.speed.astype(np.complex)) coeff[n] = np.dot(eig_vecs_a[:,fw_to_adj[n]].conj(),q)/norm except: raise ValueError("Didn't find matching alphas in adjoint") exit() #Check out orthogonality # for i in range(4): # for j in range(N): # print("Checking Orthogonality",i,j,np.dot(eig_vecs_a[:,i].conj()*nd.inv_speed,eig_vecs[:,j])) #Perform time dependent forward solve ts = np.logspace(-1,2,num=5) errs = [] counts = [] for t in ts: #Compute expanded solution sol_exp = lambda t: sum(computeExpansionFunction(n,t,alphas,coeff,eig_vecs,source=source) for n in range(N)) # phi_for, dyn_alpha, times = solveInfMedTimeDependent(nd,np.zeros(N),10000,t,q=q,source=source,radius=radius, # verbosity=-1,dyn_alpha=True) phi_exp = sol_exp(t) #See what solution looks like with only fundamental mode # n_max = np.argmax(np.real(alphas)) # phi_fund = computeExpansionFunction(n_max,t,alphas,coeff,eig_vecs,source=source) #Determine solution based on largest expansion coefficients expans_funcs = [computeExpansionCoeff(i,t,alphas,coeff,source=source) for i in range(len(alphas))] time_coeff = [computeTimeCoeff(i,t,alphas,source=source) for i in range(N)] #If complex, we want doulbe the real part to count because corresponding complex #conjugate will cancel out the imaginary part expans_funcs_sort = [] for i in expans_funcs: if np.imag(np.abs(i)) > 0: expans_funcs_sort.append(np.real(i)) else: expans_funcs_sort.append(i) sorted_funcs = sorted(expans_funcs_sort, key=lambda x: np.abs(x), reverse=True) sorted_idxs = [expans_funcs_sort.index(i) for i in sorted_funcs] sorted_funcs = [expans_funcs[i] for i in sorted_idxs] #Plot the dynamic alpha # plt.figure() # xplot = [i+1 for i in range(len(alphas))] # plt.plot(times[1:-1],dyn_alpha[1:-1],"-",linewidth=1.2,label=r'Dynamic $\alpha(t)$') # plt.plot([times[1],times[-1]],[alphas[n_max],alphas[n_max]],'k--', label=r"Dominant Static $\alpha$") # plt.xlabel("$t$ (sh)") # plt.ylabel(r"$\alpha$ (sh$^{-1}$)") # plt.legend(loc='best') # plt.savefig('dyn_alpha_%.2f.pdf' % keff,bbox_inches='tight') #Truncate sorted_funcs array for plotting # coupling_number = 3 # sorted_funcs_plot = sorted_funcs[0:coupling_number] # # alpha_keys_plot = [expans_funcs.index(i) for i in sorted_funcs_plot] # alpha_keys_a = [fw_to_adj[i] for i in alpha_keys_plot] # # plotMultipleEigenvectors(nd, alpha_keys_plot, alphas, eig_vecs, num=coupling_number, # title="Strongest Coupling Forward Eigenvectors for %d groups" % nd.n_groups) # plt.savefig('strong_for_c01_14_'+str(nd.n_groups)+'.pdf',bbox_inches='tight') # plotMultipleEigenvectors(nd, alpha_keys_a, alphas_a, eig_vecs, num=coupling_number, # title="Strongest Coupling Adjoint Eigenvectors for %d groups" % nd.n_groups) # plt.legend(loc='best') # plt.savefig('strong_adj_c01_14_'+str(nd.n_groups)+'.pdf',bbox_inches='tight') #Plot the coefficients in normalized formats norm_qn = np.array([np.abs(coeff[i]) for i in sorted_idxs]) norm_An = [np.abs(np.real(expans_funcs[i]))/sum(np.abs(np.real(expans_funcs))) for i in sorted_idxs] norm_time_coeff = [time_coeff[i] for i in sorted_idxs] norm_qn /= sum(norm_qn) #What does dynamic alpha tell us? Plot on same scale #dyn_coeff = np.exp(dyn_alpha[-1]*t)/(sum(norm_time_coeff)) norm_time_coeff /= sum(norm_time_coeff) # f = plt.figure() # ax = f.add_subplot(111) # xplot = [i+1 for i in range(len(alphas))] # ax.plot(xplot,norm_An,"o",label="$\hat A_n(t)$") # ax.plot(xplot,norm_qn,"^",label="$\hat q_n$") # ax.plot(xplot,norm_time_coeff,"*",label="$\hat T(t)$") # ax.plot([xplot[0],xplot[-1]],[dyn_coeff,dyn_coeff],"-k",label=r"$\exp(\alpha_{dyn}t)$") # ax.set_yscale('symlog',linthreshy=1.e-4) # plt.xlabel("Mode $n$") # plt.ylabel("Normalize Coefficients") # plt.legend(loc='best') # plt.savefig("coeff50_14.pdf",bbox_inches='tight') #Determine percentage of coefficients to get 99% of the expansion min_sum = 0.99 summ = 0 n_modes = len(norm_An) #defualt to all the modes for i in norm_An: summ += i if summ > min_sum: n_modes = norm_An.index(i)+1 break coupled_keys = [sorted_idxs[i] for i in range(n_modes)] #If coupled_keys are imaginary, make sure compelx conj is also in list strong_alphas = [alphas[i] for i in coupled_keys] for i in coupled_keys: if np.abs(np.imag(alphas[i])) > 0: if alphas[i].conj() not in strong_alphas: coupled_keys.append(alphas.index(alphas[i].conj())) sol_coupled = lambda t: sum(computeExpansionFunction(n,t,alphas,coeff,eig_vecs,source=source) for n in coupled_keys) phi_exp = sol_exp(t) phi_coupled = sol_coupled(t) #Compute the L2 error err = np.linalg.norm(phi_exp - phi_coupled)/np.linalg.norm(phi_exp) errs.append(err) counts.append(n_modes) #Plot the solutions at time t plt.figure() plt.semilogx(nd.groupCenters(),phi_exp,"+:",label="Expansion $t=$%s sh" % str(t)) # plt.semilogx(nd.groupCenters(),phi_for,"x:",label="Forward $t=$%s sh" % str(t)) # plt.semilogx(nd.groupCenters(),phi_fund,"-",label="Dominant Mode Only $t=$%s sh" % str(t)) plt.semilogx(nd.groupCenters(),phi_coupled,"--",label="Strongest %i Modes $t=$%s sh" % (n_modes,str(t))) plt.xlabel("$E_g$ (MeV)") plt.ylabel("$\phi_g$ (n-cm$^{-2}$ sh$^{-1}$)") plt.legend(loc='best') # plt.savefig('comp_t50sh_14.pdf',bbox_inches='tight') plt.show(block=True) print(ts) print(errs) print(counts) #plot the eigenvalues plt.figure() plt.grid() plt.scatter(np.array(alphas).real,np.array(alphas).imag,c='r',marker='o') plt.xlabel(r'Re [$\alpha$] sh$^{-1}$') plt.ylabel(r'Im [$\alpha$] sh$^{-1}$') plt.show(block=True)
eigsN = (1 - 1.0 / eigsN) / dt return eigsN, vsN, u #Compute atom densities pct_c = 1e-6 #0.01 atm_perc = [1 - pct_c, pct_c] rho = [19.86, 2.1] Na = 0.60221 #in atoms-cm^2/(mol-b) M = [239, 12.01] atm_dens = [rho[i] * Na / M[i] * atm_perc[i] for i in range(len(rho))] #Process data # nd = NuclearData(["../crossx/Pu239_618gp_Pu239.cx","../crossx/h-fg_618gp_h-1.cx"],atm_dens=atm_dens) nd = NuclearData( ["./crossx/Pu239_12gp_Pu239.cx", "./crossx/cnat_12gp_cnat.cx"], atm_dens=atm_dens) metal_data = NuclearData( ["./crossx/Pu239_12gp_Pu239.cx", "./crossx/cnat_12gp_cnat.cx"], atm_dens=atm_dens) metal_data.scat_mat[0] = np.transpose(metal_data.scat_mat[0]) pct_c = 1 - 1e-6 atm_perc = [1 - pct_c, pct_c] c_dens = [rho[i] * Na / M[i] * atm_perc[i] for i in range(len(rho))] print(c_dens) refl = NuclearData( ["./crossx/Pu239_12gp_Pu239.cx", "./crossx/cnat_12gp_cnat.cx"], atm_dens=c_dens) refl.scat_mat[0] = np.transpose(refl.scat_mat[0])
def main(): #Process data nd = NuclearData(["../crossx/81group.cx"],[1.0],ignore_format=True) nd.scat_mat = dict() mat = np.zeros((nd.n_groups,nd.n_groups)) for i in range(nd.n_groups): for j in range((nd.n_groups)): if (j == i-1): mat[i,j] = 100. nd.scat_mat[0] = mat alphas, eig_vecs, A = solveInfMedForward(nd, return_matrix=True) alphas_a, eig_vecs_a = solveInfMedAdjoint(nd) print("Adjoint alpha eigenvalues: ",alphas_a) print("Adjoint eigen vectors: ",eig_vecs_a) print("Forward alpha eigenvalues: ",alphas) print("Forward eigen vectors: ",eig_vecs) #Analytic eigenvalues fun = lambda g: -nd.sig_cap[g]*nd.speed[g] + nd.scat_mat[0][g+1][g]*( nd.nubar**(1./nd.n_groups)*np.exp(2j*np.pi*g/nd.n_groups) - 1)*nd.speed[g] analytic = np.array([fun(g) for g in range((nd.n_groups)) if g < nd.n_groups-1]) #plot eigenvalues plt.figure() plt.grid() plt.scatter(alphas_a.real,alphas_a.imag,c='b',label="Adjoint",facecolors='none') plt.scatter(alphas.real,alphas.imag,c='r',marker='+',label="Forward") plt.scatter(analytic.real,analytic.imag,marker='x',label="Analytic") plt.xlabel(r'Re [$\alpha$] s$^{-1}$') plt.ylabel(r'Im [$\alpha$] s$^{-1}$') plt.axis('equal') plt.legend() plt.savefig('inf81_alpha.pdf',bbox_inces='tight') # #Check out that the eigenvalue problem is satisfied before orthogonalization # for i in range(eig_vecs.shape[0]): # print("Checking equation satisfication",np.linalg.norm(np.dot(A,eig_vecs[:,i]) - # np.dot(alphas[i],eig_vecs[:,i]))) # # N = eig_vecs.shape[0] # for i in range(N): # for j in range(N): # print("Orthogonalization against adjoint vecs",i,j,np.dot(eig_vecs_a[:,i].conj(),eig_vecs[:,j])) #Check orthonormality # if not all(abs(np.dot(np.conj(eig_vecs[:,i]),eig_vecs[:,j])/np.dot(np.conj(eig_vecs[:,i]),eig_vecs[:,i])) # < 1.E-13 for i in range(eig_vecs.shape[0]) for j in # range(eig_vecs.shape[0]) if i != j): # raise ValueError("Eigenvalues are not orthogonal with complex inner product") #Check out that the eigenvalue problem is still satisfied with the orthogonal matrices #Compute keff keff = solveInfMedKeff(nd) print("Keff for this system is: ",keff) #Compute expansion coefficients for simple system N = nd.n_groups src = 'delta' # src = 'constant' q = np.zeros(N,dtype=np.complex_) q[0] = 5.E4 fw_to_adj = getAlphaMap(alphas,alpha_a) #Expand the coefficients coeff = np.zeros(N,dtype=np.complex_) for n in range(N): norm = np.dot(eig_vecs_a[:,fw_to_adj[n]].conj(),eig_vecs[:,n]/nd.speed) coeff[n] = np.dot(eig_vecs_a[:,fw_to_adj[n]].conj(),q)/norm # print("Norm",norm,"Coeff",coeff[n]) t = 0.7 phi_for = solveInfMedTimeDependent(nd,np.zeros(N),1000,t,q=q,source=src, verbosity=-1) sol_new = lambda t: sum(computeExpansionFunction(n,t,alphas,coeff,eig_vecs,source=src) for n in range(N)) #Fundamental mode n_max = np.argmax(np.real(alphas)) sol_fund = lambda t: computeExpansionFunction(n_max,t,alphas,coeff,eig_vecs) #Plot the solution at time t groups = np.array([81 - i for i in range(81)]) f, ax = plt.subplots(1,1) ax.semilogy(groups, sol_new(t),label='Expansion') ax.semilogy(groups, sol_fund(t),label='Fundamental Only') ax.semilogy(groups, phi_for, label="Forward") plt.xlabel("$E_g$ MeV") plt.ylabel("$\phi_g$ n-cm$^{-2}$ s$^{-1} $") ax.set_ylim([0.10,100000]) plt.legend() print(sol_new(t)) plt.show(block=True)