def test_HydroUniformIC(self): # declare symbolic variables x, t, alpha = symbols('x t alpha') # create solution for thermodynamic state and flow field rho = sympify('1') u = sympify('1') E = sympify('10') # create solution for radiation field psim = sympify('0') psip = sympify('0') # numeric values alpha_value = 0.01 cv_value = 1.0 gamma_value = 1.4 sig_s = 0.0 sig_a = 0.0 # create MMS source functions rho_src, mom_src, E_src, psim_src, psip_src = createMMSSourceFunctionsHydroOnly( rho = rho, u = u, E = E, gamma_value = gamma_value, cv_value = cv_value, alpha_value = alpha_value, display_equations = False) # create functions for exact solutions substitutions = dict() substitutions['alpha'] = alpha_value rho = rho.subs(substitutions) u = u.subs(substitutions) mom = rho*u E = E.subs(substitutions) rho_f = lambdify((symbols('x'),symbols('t')), rho, "numpy") u_f = lambdify((symbols('x'),symbols('t')), u, "numpy") mom_f = lambdify((symbols('x'),symbols('t')), mom, "numpy") E_f = lambdify((symbols('x'),symbols('t')), E, "numpy") psim_f = lambdify((symbols('x'),symbols('t')), psim, "numpy") psip_f = lambdify((symbols('x'),symbols('t')), psip, "numpy") # spatial and temporal domains width = 1.0 t_start = 0.0 t_end = 0.005 dt_constant = 0.001 # create mesh n_elems = 20 mesh = Mesh(n_elems, width) # compute radiation BC; assumes BC is independent of time psi_left = psip_f(x=0.0, t=0.0) psi_right = psim_f(x=width, t=0.0) rad_BC = RadBC(mesh, "dirichlet", psi_left=psi_left, psi_right=psi_right) # compute radiation IC psi_IC = computeRadiationVector(psim_f, psip_f, mesh, t=0.0) rad_IC = Radiation(psi_IC) # compute hydro IC hydro_IC = computeAnalyticHydroSolution(mesh, t=0.0, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # create hydro BC hydro_BC = HydroBC(bc_type='dirichlet', mesh=mesh, rho_BC=rho_f, mom_BC=mom_f, erg_BC=E_f) # create cross sections cross_sects = [(ConstantCrossSection(sig_s, sig_s+sig_a), ConstantCrossSection(sig_s, sig_s+sig_a)) for i in xrange(mesh.n_elems)] # slope limiter option slope_limiter = "vanleer" # if run standalone, then be verbose if __name__ == '__main__': verbosity = 2 else: verbosity = 0 # run the rad-hydro transient rad_new, hydro_new = runNonlinearTransient( mesh = mesh, problem_type = 'rad_hydro', dt_option = 'constant', dt_constant = dt_constant, slope_limiter = slope_limiter, use_2_cycles = False, t_start = t_start, t_end = t_end, rad_BC = rad_BC, hydro_BC = hydro_BC, cross_sects = cross_sects, rad_IC = rad_IC, hydro_IC = hydro_IC, mom_src = mom_src, E_src = E_src, psim_src = psim_src, psip_src = psip_src, verbosity = verbosity) # number of decimal places to check n_decimal_places = 15 # check that states are all equal to the IC for i in xrange(n_elems): state = hydro_new[i] state_IC = hydro_IC[i] rho, mom, erg = state.getConservativeVariables() rho0, mom0, erg0 = state_IC.getConservativeVariables() self.assertAlmostEqual(rho, rho0, n_decimal_places) self.assertAlmostEqual(mom, mom0, n_decimal_places) self.assertAlmostEqual(erg, erg0, n_decimal_places)
def test_HydroMMS(self): # slope limiter: choices are: # none step minmod double-minmod superbee minbee vanleer slope_limiter = 'none' # number of elements in first cycle n_elems = 50 # number of refinement cycles n_cycles = 1 # end time t_end = 0.1 # choice of solutions for hydro hydro_case = "linear" # constant linear exponential # declare symbolic variables x, t, alpha = symbols('x t alpha') # create solution for thermodynamic state and flow field if hydro_case == "constant": rho = sympify('4.0') u = sympify('1.2') E = sympify('10.0') elif hydro_case == "linear": rho = 1 + x - t u = sympify('1') E = 5 + 5 * (x - 0.5)**2 elif hydro_case == "exponential": rho = exp(x + t) + 5 u = exp(-x) * sin(t) - 1 E = 10 * exp(x + t) else: raise NotImplementedError("Invalid hydro test case") # create solution for radiation field psim = sympify('0') psip = sympify('0') # numeric values alpha_value = 0.01 cv_value = 1.0 gamma_value = 1.4 sig_s = 1.0 sig_a = 0.0 # create MMS source functions rho_src, mom_src, E_src, psim_src, psip_src = createMMSSourceFunctionsHydroOnly( rho=rho, u=u, E=E, gamma_value=gamma_value, cv_value=cv_value, alpha_value=alpha_value, display_equations=False) # create functions for exact solutions substitutions = dict() substitutions['alpha'] = alpha_value rho = rho.subs(substitutions) u = u.subs(substitutions) mom = rho * u E = E.subs(substitutions) rho_f = lambdify((symbols('x'), symbols('t')), rho, "numpy") u_f = lambdify((symbols('x'), symbols('t')), u, "numpy") mom_f = lambdify((symbols('x'), symbols('t')), mom, "numpy") E_f = lambdify((symbols('x'), symbols('t')), E, "numpy") psim_f = lambdify((symbols('x'), symbols('t')), psim, "numpy") psip_f = lambdify((symbols('x'), symbols('t')), psip, "numpy") # spatial and temporal domains width = 1.0 # initialize lists for mesh size and L1 error for each cycle max_dx = list() err = list() # loop over refinement cycles for cycle in xrange(n_cycles): if __name__ == '__main__': print("\nCycle %d of %d: n_elems = %d" % (cycle + 1, n_cycles, n_elems)) # create uniform mesh mesh = Mesh(n_elems, width) # append max dx for this cycle to list max_dx.append(mesh.max_dx) # compute radiation IC psi_IC = computeRadiationVector(psim_f, psip_f, mesh, t=0.0) rad_IC = Radiation(psi_IC) #Make rad BC object with vacuum for hydro only rad_BC = RadBC(mesh, "vacuum") # compute hydro IC hydro_IC = computeAnalyticHydroSolution(mesh, t=0.0, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # create hydro BC hydro_BC = HydroBC(bc_type='dirichlet', mesh=mesh, rho_BC=rho_f, mom_BC=mom_f, erg_BC=E_f) # create cross sections cross_sects = [(ConstantCrossSection(sig_s, sig_s + sig_a), ConstantCrossSection(sig_s, sig_s + sig_a)) for i in xrange(mesh.n_elems)] # if run standalone, then be verbose if __name__ == '__main__': if n_cycles == 1: verbosity = 2 else: verbosity = 1 else: verbosity = 0 # run the rad-hydro transient rad_new, hydro_new = runNonlinearTransient( mesh=mesh, problem_type='rad_hydro', dt_option='CFL', CFL=0.5, slope_limiter=slope_limiter, time_stepper='BDF2', use_2_cycles=True, t_start=0.0, t_end=t_end, rad_BC=rad_BC, hydro_BC=hydro_BC, cross_sects=cross_sects, rad_IC=rad_IC, hydro_IC=hydro_IC, mom_src=mom_src, E_src=E_src, psim_src=psim_src, psip_src=psip_src, rho_src=rho_src, verbosity=verbosity, check_balance=False, rho_f=rho_f, u_f=u_f, E_f=E_f, gamma_value=gamma_value, cv_value=cv_value) # compute exact hydro solution hydro_exact = computeAnalyticHydroSolution(mesh, t=t_end, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # compute error err.append(computeHydroL2Error(hydro_new, hydro_exact)) # double number of elements for next cycle n_elems *= 2 # compute convergence rates rates = computeHydroConvergenceRates(max_dx, err) # print convergence table and plot if __name__ == '__main__': # print convergence table if n_cycles > 1: printHydroConvergenceTable(max_dx, err, rates=rates, dx_desc='dx', err_desc='L2') # plot hydro solution plotHydroSolutions(mesh, hydro_new, x_exact=mesh.getCellCenters(), exact=hydro_exact)
def test_RadHydroMMS(self): # declare symbolic variables x, t, alpha, c = symbols('x t alpha c') # numeric values alpha_value = 0.01 cv_value = 1.0 gamma_value = 1.4 sig_s = 1.0 sig_a = 1.0 # create solution for thermodynamic state and flow field # rho = sympify('4.0') # u = sympify('1.0') # E = sympify('10.0') rho = 2. + sin(2*pi*x+t) u = 2. + cos(2*pi*x-t) p = 2. + cos(2*pi*x+t) e = p/(rho*(gamma_value-1.)) E = 0.5*rho*u*u + rho*e # create solution for radiation field rad_scale = 50*c psim = rad_scale*(2*t*sin(pi*(1-x))+2+0.1*t) psip = rad_scale*(t*sin(pi*x)+2+0.1*t) # create MMS source functions rho_src, mom_src, E_src, psim_src, psip_src = createMMSSourceFunctionsRadHydro( rho = rho, u = u, E = E, psim = psim, psip = psip, sigma_s_value = sig_s, sigma_a_value = sig_a, gamma_value = gamma_value, cv_value = cv_value, alpha_value = alpha_value, display_equations = True) # create functions for exact solutions substitutions = dict() substitutions['alpha'] = alpha_value substitutions['c'] = GC.SPD_OF_LGT rho = rho.subs(substitutions) u = u.subs(substitutions) mom = rho*u E = E.subs(substitutions) psim = psim.subs(substitutions) psip = psip.subs(substitutions) rho_f = lambdify((symbols('x'),symbols('t')), rho, "numpy") u_f = lambdify((symbols('x'),symbols('t')), u, "numpy") mom_f = lambdify((symbols('x'),symbols('t')), mom, "numpy") E_f = lambdify((symbols('x'),symbols('t')), E, "numpy") psim_f = lambdify((symbols('x'),symbols('t')), psim, "numpy") psip_f = lambdify((symbols('x'),symbols('t')), psip, "numpy") # create uniform mesh n_elems = 50 width = 1.0 mesh = Mesh(n_elems, width) # compute radiation IC psi_IC = computeRadiationVector(psim_f, psip_f, mesh, t=0.0) rad_IC = Radiation(psi_IC) # create rad BC object rad_BC = RadBC(mesh, 'dirichlet',psip_BC=psip_f,psim_BC=psim_f) # compute hydro IC hydro_IC = computeAnalyticHydroSolution(mesh,t=0.0, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # create hydro BC hydro_BC = HydroBC(bc_type='periodic', mesh=mesh) # create cross sections cross_sects = [(ConstantCrossSection(sig_s, sig_s+sig_a), ConstantCrossSection(sig_s, sig_s+sig_a)) for i in xrange(mesh.n_elems)] # transient options t_start = 0.0 # t_end = 0.005 t_end = 0.02 # if run standalone, then be verbose if __name__ == '__main__': verbosity = 2 else: verbosity = 0 #slope limiter limiter = 'none' # run the rad-hydro transient rad_new, hydro_new = runNonlinearTransient( mesh = mesh, problem_type = 'rad_hydro', dt_option = 'CFL', CFL = 0.5, # dt_option = 'constant', # dt_constant = 0.0002, slope_limiter = limiter, time_stepper = 'BDF2', use_2_cycles = True, t_start = t_start, t_end = t_end, rad_BC = rad_BC, cross_sects = cross_sects, rad_IC = rad_IC, hydro_IC = hydro_IC, hydro_BC = hydro_BC, mom_src = mom_src, E_src = E_src, rho_src = rho_src, psim_src = psim_src, psip_src = psip_src, verbosity = verbosity, rho_f =rho_f, u_f = u_f, E_f = E_f, gamma_value = gamma_value, cv_value = cv_value, check_balance = True) # plot if __name__ == '__main__': # plot radiation solution # compute exact hydro solution hydro_exact = computeAnalyticHydroSolution(mesh, t=t_end, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # plot hydro solution plotHydroSolutions(mesh, hydro_new, x_exact=mesh.getCellCenters(),exact=hydro_exact) #plot exact and our E_r Er_exact_fn = 1./GC.SPD_OF_LGT*(psim + psip) Er_exact = [] x = mesh.getCellCenters() for xi in x: substitutions = {'x':xi, 't':t_end} Er_exact.append(Er_exact_fn.subs(substitutions)) plotRadErg(mesh, rad_new.E, exact_Er=Er_exact)
def test_RadHydroMMS(self): # declare symbolic variables x, t, alpha, c, a, mu = symbols('x t alpha c a mu') # number of refinement cycles n_cycles = 5 # number of elements in first cycle n_elems = 20 # We will increase sigma and nondimensional C as we decrease the mesh # size to ensure we stay in the diffusion limit # numeric values gamma_value = 5. / 3. cv_value = 0.14472799784454 # run for a fixed amount of time t_end = 2. * pi sig_s = 0.0 #Want material speeed to be a small fraction of speed of light #and radiation to be small relative to kinetic energy P = 0.001 # a_r T_inf^4/(rho_inf*u_inf^2) #Arbitrary ratio of pressure to density alpha_value = 0.5 #Arbitrary mach number well below the sound speed. The choice of gamma and #the cv value, as well as C and P constrain all other material reference #parameters, but we are free to choose the material velocity below the sound #speed to ensure no shocks are formed M = 0.9 cfl_value = 0.6 #but 2 time steps, so really like a CFL of 0.3 dt = [] dx = [] err = [] for cycle in range(n_cycles): #Keep ratio of and sig_a*dx constant, staying in diffusion limit C = sig_a = 100000. / 20 * n_elems # c/a_inf sig_t = sig_s + sig_a a_inf = GC.SPD_OF_LGT / C #These lines of code assume specified C_v T_inf = a_inf**2 / (gamma_value * (gamma_value - 1.) * cv_value) rho_inf = GC.RAD_CONSTANT * T_inf**4 / (P * a_inf**2) #Specify rho_inf and determine T_inf and Cv_value rho_inf = 1.0 #If we don't choose a reference density, then the specific heat values get ridiculous T_inf = pow(rho_inf * P * a_inf**2 / GC.RAD_CONSTANT, 0.25) #to set T_inf based on rho_inf, cv_value = a_inf**2 / (T_inf * gamma_value * (gamma_value - 1.) ) # to set c_v, if rho specified #Specify T_inf and solve for rho_inf and C_v value # T_inf = 1 # rho_inf = GC.RAD_CONSTANT*T_inf**4/(P*a_inf**2) # cv_value = a_inf**2/(T_inf*gamma_value*(gamma_value-1.)) # to set c_v, if rho specified #Same for all approachs p_inf = rho_inf * a_inf * a_inf print "The dimensionalization parameters are: " print " a_inf : ", a_inf print " T_inf : ", T_inf print " rho_inf : ", rho_inf print " p_inf : ", p_inf print " C_v : ", cv_value print " gamma : ", gamma_value # create solution for thermodynamic state and flow field rho = rho_inf * (2. + sin(x - t)) u = a_inf * M * 0.5 * (2. + cos(x - t)) p = alpha_value * p_inf * (2. + cos(x - t)) e = p / (rho * (gamma_value - 1.)) E = 0.5 * rho * u * u + rho * e # create solution for radiation field based on solution for F # that is the leading order diffusion limit solution T = e / cv_value Er = a * T**4 Fr = -1. / (3. * sig_t) * c * diff(Er, x) + sympify('4./3.') * Er * u #Form psi+ and psi- from Fr and Er psip = (Er * c * mu + Fr) / (2. * mu) psim = (Er * c * mu - Fr) / (2. * mu) # create functions for exact solutions substitutions = dict() substitutions['alpha'] = alpha_value substitutions['c'] = GC.SPD_OF_LGT substitutions['a'] = GC.RAD_CONSTANT substitutions['mu'] = RU.mu["+"] rho = rho.subs(substitutions) u = u.subs(substitutions) mom = rho * u E = E.subs(substitutions) psim = psim.subs(substitutions) psip = psip.subs(substitutions) T = T.subs(substitutions) rho_f = lambdify((symbols('x'), symbols('t')), rho, "numpy") u_f = lambdify((symbols('x'), symbols('t')), u, "numpy") mom_f = lambdify((symbols('x'), symbols('t')), mom, "numpy") E_f = lambdify((symbols('x'), symbols('t')), E, "numpy") psim_f = lambdify((symbols('x'), symbols('t')), psim, "numpy") psip_f = lambdify((symbols('x'), symbols('t')), psip, "numpy") T_f = lambdify((symbols('x'), symbols('t')), T, "numpy") Er = Er.subs(substitutions) Er = lambdify((symbols('x'), symbols('t')), Er, "numpy") #For reference create lambda as ratio of aT^4/rho--u^2 to check #P_f = lambda x,t: GC.RAD_CONSTANT*T_f(x,t)**4/(rho_f(x,t)*u_f(x,t)**2) #dx = 1./100. #x = -1.*dx #t=0.2 #for i in range(100): # x += dx # print "ratio:", P_f(x,t) # create MMS source functions rho_src, mom_src, E_src, psim_src, psip_src = createMMSSourceFunctionsRadHydro( rho=rho, u=u, E=E, psim=psim, psip=psip, sigma_s_value=sig_s, sigma_a_value=sig_a, gamma_value=gamma_value, cv_value=cv_value, alpha_value=alpha_value, display_equations=True) # mesh width = 2. * pi mesh = Mesh(n_elems, width) # compute hydro IC for the sake of computing initial time step size hydro_IC = computeAnalyticHydroSolution(mesh, t=0.0, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # compute the initial time step size according to CFL conditon (actually # half). We will then decrease this time step by the same factor as DX each # cycle if cycle == 0: sound_speed = [ sqrt(i.p * i.gamma / i.rho) + abs(i.u) for i in hydro_IC ] dt_vals = [ cfl_value * (mesh.elements[i].dx) / sound_speed[i] for i in xrange(len(hydro_IC)) ] dt_value = min(min(dt_vals), 0.5) #don't take too big of time step print "initial dt_value", dt_value #Adjust the end time to be an exact increment of dt_values print "old t_end: ", t_end print "new t_end: ", t_end print "This cycle's dt value: ", dt_value # create uniform mesh mesh = Mesh(n_elems, width) dt.append(dt_value) dx.append(mesh.getElement(0).dx) # compute radiation IC psi_IC = computeRadiationVector(psim_f, psip_f, mesh, t=0.0) rad_IC = Radiation(psi_IC) # create rad BC object rad_BC = RadBC(mesh, 'periodic') # compute hydro IC hydro_IC = computeAnalyticHydroSolution(mesh, t=0.0, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # Dimensionless parameters. These are all evaluated at peaks of trig # functions, very hard coded print "---------------------------------------------" print " Diffusion limit info:" print "---------------------------------------------" print "Size in mfp of cell", mesh.getElement(0).dx * sig_t print "Ratio of radiation energy to kinetic", Er(0.75, 0) / (rho_f( 0.25, 0) * u_f(0.0, 0)**2), GC.RAD_CONSTANT * T_inf**4 / ( rho_inf * a_inf**2) print "Ratio of speed of light to material sound speed", GC.SPD_OF_LGT / u_f( 0.0, 0), GC.SPD_OF_LGT / (a_inf) print "---------------------------------------------" # create hydro BC hydro_BC = HydroBC(bc_type='periodic', mesh=mesh) # create cross sections cross_sects = [(ConstantCrossSection(sig_s, sig_s + sig_a), ConstantCrossSection(sig_s, sig_s + sig_a)) for i in xrange(mesh.n_elems)] # transient options t_start = 0.0 # if run standalone, then be verbose if __name__ == '__main__': verbosity = 2 else: verbosity = 0 #slope limiter limiter = 'double-minmod' # run the rad-hydro transient rad_new, hydro_new = runNonlinearTransient( mesh=mesh, problem_type='rad_hydro', dt_option='constant', dt_constant=dt_value, slope_limiter=limiter, time_stepper='BDF2', use_2_cycles=True, t_start=t_start, t_end=t_end, rad_BC=rad_BC, cross_sects=cross_sects, rad_IC=rad_IC, hydro_IC=hydro_IC, hydro_BC=hydro_BC, mom_src=mom_src, E_src=E_src, rho_src=rho_src, psim_src=psim_src, psip_src=psip_src, verbosity=verbosity, rho_f=rho_f, u_f=u_f, E_f=E_f, gamma_value=gamma_value, cv_value=cv_value, check_balance=True) # compute exact hydro solution hydro_exact = computeAnalyticHydroSolution(mesh, t=t_end, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) rad_exact = computeAnalyticRadSolution(mesh, t_end, psim=psim_f, psip=psip_f) #Compute error err.append( computeHydroL2Error(hydro_new, hydro_exact, rad_new, rad_exact)) n_elems *= 2 dt_value *= 0.5 # compute convergence rates rates_dx = computeHydroConvergenceRates(dx, err) rates_dt = computeHydroConvergenceRates(dt, err) # print convergence table if n_cycles > 1: printHydroConvergenceTable(dx, err, rates=rates_dx, dx_desc='dx', err_desc='$L_2$') printHydroConvergenceTable(dt, err, rates=rates_dt, dx_desc='dt', err_desc='$L_2$') # plot if __name__ == '__main__': # compute exact hydro solution hydro_exact = computeAnalyticHydroSolution(mesh, t=t_end, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # plot hydro solution plotHydroSolutions(mesh, hydro_new, x_exact=mesh.getCellCenters(), exact=hydro_exact) #plot exact and our E_r Er_exact_fn = 1. / GC.SPD_OF_LGT * (psim + psip) Fr_exact_fn = (psip - psim) * RU.mu["+"] Er_exact = [] Fr_exact = [] psip_exact = [] psim_exact = [] x = mesh.getCellCenters() for xi in x: substitutions = {'x': xi, 't': t_end} Er_exact.append(Er_exact_fn.subs(substitutions)) Fr_exact.append(Fr_exact_fn.subs(substitutions)) psip_exact.append(psip_f(xi, t_end)) psim_exact.append(psim_f(xi, t_end)) plotRadErg(mesh, rad_new.E, Fr_edge=rad_new.F, exact_Er=Er_exact, exact_Fr=Fr_exact) plotS2Erg(mesh, rad_new.psim, rad_new.psip, exact_psim=psim_exact, exact_psip=psip_exact) plotTemperatures(mesh, rad_new.E, hydro_states=hydro_new, print_values=True) #Make a pickle to save the error tables from sys import argv pickname = "results/testRadHydroDiffMMS.pickle" if len(argv) > 2: if argv[1] == "-o": pickname = argv[2].strip() #Create dictionary of all the data big_dic = {"dx": dx} big_dic["dt"] = dt big_dic["Errors"] = err pickle.dump(big_dic, open(pickname, "w"))
def test_RadHydroMMS(self): # declare symbolic variables x, t, alpha, c = symbols('x t alpha c') #Cycles for time convergence n_cycles = 3 # numeric values alpha_value = 0.01 cv_value = 1.0 gamma_value = 1.4 sig_s = 1.0 sig_a = 1.0 sig_t = sig_s + sig_a # create solution for thermodynamic state and flow field rho = 2. + sin(2 * pi * x - t) u = 2. + cos(2 * pi * x - t) p = 0.5 * (2. + cos(2 * pi * x - t)) e = p / (rho * (gamma_value - 1.)) E = 0.5 * rho * u * u + rho * e rho = sympify('2') * sin(t / 4.) + 2. u = sympify('3') * sin(t / 4.) + 3. E = sympify('10') * sin(t / 4.) + 10. # create solution for radiation field based on solution for F # that is the leading order diffusion limit solution a = GC.RAD_CONSTANT c = GC.SPD_OF_LGT mu = RU.mu["+"] #Equilibrium diffusion solution Er = (2. + cos(2 * pi * x - t)) Fr = (2. + cos(2 * pi * x - t)) * c psip = (Er * c * mu + Fr) / (2. * mu) psim = (Er * c * mu - Fr) / (2. * mu) psip = sympify('10') * c + 1 * sin(t / 4.) psim = sympify('10') * c + 1 * cos(t / 4.) #Form psi+ and psi- from Fr and Er #psip = sympify('5.')*c #psim = sympify('5.')*c # create MMS source functions rho_src, mom_src, E_src, psim_src, psip_src = createMMSSourceFunctionsRadHydro( rho=rho, u=u, E=E, psim=psim, psip=psip, sigma_s_value=sig_s, sigma_a_value=sig_a, gamma_value=gamma_value, cv_value=cv_value, alpha_value=alpha_value, display_equations=True) # create functions for exact solutions substitutions = dict() substitutions['alpha'] = alpha_value substitutions['c'] = GC.SPD_OF_LGT rho = rho.subs(substitutions) u = u.subs(substitutions) mom = rho * u E = E.subs(substitutions) psim = psim.subs(substitutions) psip = psip.subs(substitutions) rho_f = lambdify((symbols('x'), symbols('t')), rho, "numpy") u_f = lambdify((symbols('x'), symbols('t')), u, "numpy") mom_f = lambdify((symbols('x'), symbols('t')), mom, "numpy") E_f = lambdify((symbols('x'), symbols('t')), E, "numpy") psim_f = lambdify((symbols('x'), symbols('t')), psim, "numpy") psip_f = lambdify((symbols('x'), symbols('t')), psip, "numpy") dt_value = 0.0001 dt = [] err = [] #Loop over cycles for time convergence for cycle in range(n_cycles): # create uniform mesh n_elems = 50 width = 1.0 mesh = Mesh(n_elems, width) #Store dt.append(dt_value) # compute radiation IC psi_IC = computeRadiationVector(psim_f, psip_f, mesh, t=0.0) rad_IC = Radiation(psi_IC) # create rad BC object rad_BC = RadBC(mesh, 'periodic') # compute hydro IC hydro_IC = computeAnalyticHydroSolution(mesh, t=0.0, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # create hydro BC hydro_BC = HydroBC(bc_type='periodic', mesh=mesh) # create cross sections cross_sects = [(ConstantCrossSection(sig_s, sig_s + sig_a), ConstantCrossSection(sig_s, sig_s + sig_a)) for i in xrange(mesh.n_elems)] # transient options t_start = 0.0 t_end = 0.001 # if run standalone, then be verbose if __name__ == '__main__': verbosity = 2 else: verbosity = 0 #slope limiter limiter = 'none' # run the rad-hydro transient rad_new, hydro_new = runNonlinearTransient( mesh=mesh, problem_type='rad_hydro', dt_option='constant', dt_constant=dt_value, slope_limiter=limiter, use_2_cycles=True, t_start=t_start, t_end=t_end, rad_BC=rad_BC, cross_sects=cross_sects, rad_IC=rad_IC, hydro_IC=hydro_IC, hydro_BC=hydro_BC, mom_src=mom_src, E_src=E_src, rho_src=rho_src, psim_src=psim_src, psip_src=psip_src, verbosity=verbosity, rho_f=rho_f, u_f=u_f, E_f=E_f, gamma_value=gamma_value, cv_value=cv_value, check_balance=True) # compute exact hydro solution hydro_exact = computeAnalyticHydroSolution(mesh, t=t_end, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) #Compute error err.append(computeHydroL2Error(hydro_new, hydro_exact)) dt_value /= 2. # compute convergence rates rates = computeHydroConvergenceRates(dt, err) # plot if __name__ == '__main__': # plot radiation solution # compute exact hydro solution hydro_exact = computeAnalyticHydroSolution(mesh, t=t_end, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # print convergence table if n_cycles > 1: printHydroConvergenceTable(dt, err, rates=rates, dx_desc='dt', err_desc='L2') # plot hydro solution plotHydroSolutions(mesh, hydro_new, x_exact=mesh.getCellCenters(), exact=hydro_exact) #plot exact and our E_r Er_exact_fn = 1. / GC.SPD_OF_LGT * (psim + psip) Fr_exact_fn = (psip - psim) * RU.mu["+"] Er_exact = [] Fr_exact = [] psip_exact = [] psim_exact = [] x = mesh.getCellCenters() for xi in x: substitutions = {'x': xi, 't': t_end} Er_exact.append(Er_exact_fn.subs(substitutions)) Fr_exact.append(Fr_exact_fn.subs(substitutions)) psip_exact.append(psip_f(xi, t_end)) psim_exact.append(psim_f(xi, t_end)) plotRadErg(mesh, rad_new.E, Fr_edge=rad_new.F, exact_Er=Er_exact, exact_Fr=Fr_exact) plotRadErg(mesh, rad_new.psim, rad_new.psip, exact_Er=psip_exact, exact_Fr=psim_exact)
def test_HydroUniformIC(self): # declare symbolic variables x, t, alpha = symbols('x t alpha') # create solution for thermodynamic state and flow field rho = sympify('1') u = sympify('1') E = sympify('10') # create solution for radiation field psim = sympify('0') psip = sympify('0') # numeric values alpha_value = 0.01 cv_value = 1.0 gamma_value = 1.4 sig_s = 0.0 sig_a = 0.0 # create MMS source functions rho_src, mom_src, E_src, psim_src, psip_src = createMMSSourceFunctionsHydroOnly( rho=rho, u=u, E=E, gamma_value=gamma_value, cv_value=cv_value, alpha_value=alpha_value, display_equations=False) # create functions for exact solutions substitutions = dict() substitutions['alpha'] = alpha_value rho = rho.subs(substitutions) u = u.subs(substitutions) mom = rho * u E = E.subs(substitutions) rho_f = lambdify((symbols('x'), symbols('t')), rho, "numpy") u_f = lambdify((symbols('x'), symbols('t')), u, "numpy") mom_f = lambdify((symbols('x'), symbols('t')), mom, "numpy") E_f = lambdify((symbols('x'), symbols('t')), E, "numpy") psim_f = lambdify((symbols('x'), symbols('t')), psim, "numpy") psip_f = lambdify((symbols('x'), symbols('t')), psip, "numpy") # spatial and temporal domains width = 1.0 t_start = 0.0 t_end = 0.005 dt_constant = 0.001 # create mesh n_elems = 20 mesh = Mesh(n_elems, width) # compute radiation BC; assumes BC is independent of time psi_left = psip_f(x=0.0, t=0.0) psi_right = psim_f(x=width, t=0.0) rad_BC = RadBC(mesh, "dirichlet", psi_left=psi_left, psi_right=psi_right) # compute radiation IC psi_IC = computeRadiationVector(psim_f, psip_f, mesh, t=0.0) rad_IC = Radiation(psi_IC) # compute hydro IC hydro_IC = computeAnalyticHydroSolution(mesh, t=0.0, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # create hydro BC hydro_BC = HydroBC(bc_type='dirichlet', mesh=mesh, rho_BC=rho_f, mom_BC=mom_f, erg_BC=E_f) # create cross sections cross_sects = [(ConstantCrossSection(sig_s, sig_s + sig_a), ConstantCrossSection(sig_s, sig_s + sig_a)) for i in xrange(mesh.n_elems)] # slope limiter option slope_limiter = "vanleer" # if run standalone, then be verbose if __name__ == '__main__': verbosity = 2 else: verbosity = 0 # run the rad-hydro transient rad_new, hydro_new = runNonlinearTransient(mesh=mesh, problem_type='rad_hydro', dt_option='constant', dt_constant=dt_constant, slope_limiter=slope_limiter, use_2_cycles=False, t_start=t_start, t_end=t_end, rad_BC=rad_BC, hydro_BC=hydro_BC, cross_sects=cross_sects, rad_IC=rad_IC, hydro_IC=hydro_IC, mom_src=mom_src, E_src=E_src, psim_src=psim_src, psip_src=psip_src, verbosity=verbosity) # number of decimal places to check n_decimal_places = 15 # check that states are all equal to the IC for i in xrange(n_elems): state = hydro_new[i] state_IC = hydro_IC[i] rho, mom, erg = state.getConservativeVariables() rho0, mom0, erg0 = state_IC.getConservativeVariables() self.assertAlmostEqual(rho, rho0, n_decimal_places) self.assertAlmostEqual(mom, mom0, n_decimal_places) self.assertAlmostEqual(erg, erg0, n_decimal_places)
def test_RadHydroShock(self): # test case test_case = "marcho3" # mach1.2 mach2 mach50 # create uniform mesh n_elems = 1000 width = 0.04 x_start = -0.02 mesh_center = x_start + 0.5 * width mesh = Mesh(n_elems, width, x_start=x_start) # slope limiter slope_limiter = "double-minmod" # gamma constant gam = 5.0 / 3.0 # material 1 and 2 properties: Table 6.1 sig_a1 = 390.71164263502122 sig_s1 = 853.14410158161809 - sig_a1 c_v1 = 0.12348 sig_a2 = sig_a1 sig_s2 = sig_s1 c_v2 = c_v1 if not (test_case == "mach2" or test_case == "marcho3"): raise NotImplementedError("All but mach2 and marcho3 shock may have wrong input"\ "values. Need to check Jarrod Ewards thesis, starting with Table 6.1") if test_case == "mach1.2": # Mach 1.2 problem: Table 6.2 # material 1 IC rho1 = 1.0 E1 = 2.2226400000000000e-02 u1 = 1.4055888445772469e-01 e1 = E1 / rho1 - 0.5 * u1 * u1 Erad_left = 1.372E-06 # material 2 IC rho2 = 1.2973213452231311 E2 = 2.6753570531538713e-002 u2 = 1.0834546504247138e-001 e2 = E2 / rho2 - 0.5 * u2 * u2 Erad_right = 2.7955320762182542e-06 # final time t_end = 0.5 # temperature plot filename test_filename = "radshock_mach1.2.pdf" # temperature plot exact solution filename exact_solution_filename = "mach1.2_exact_solution.csv" elif test_case == "mach2": # Mach 2 problem: Table 6.3 # material 1 IC rho1 = 1.0 E1 = 3.9788000000000004e-002 u1 = 2.3426480742954117e-001 e1 = E1 / rho1 - 0.5 * u1 * u1 T1 = e1 / c_v1 Erad_left = 1.372E-06 # material 2 IC rho2 = 2.2860748989303659e+000 E2 = 7.0649692950433357e-002 u2 = 1.0247468599526272e-001 e2 = E2 / rho2 - 0.5 * u2 * u2 T2 = e2 / c_v2 Erad_right = 2.5560936967521927e-005 print "rho", rho1, rho2 print "vel", u1, u2 print "Temperature", T1, T2 print "momentum", rho1 * u1, rho2 * u2 print "E", E1, E2 print "E_r", Erad_left, Erad_right print sig_a1, sig_s1 # final time t_end = 1.0 # temperature plot output filename test_filename = "radshock_mach2.pdf" # temperature plot exact solution filename exact_solution_filename = "marcho2_exact_solution.csv" elif test_case == "mach50": # Mach 50 problem: Table 6.4 raise NotImplementedError("Mach 50 test requires negativity monitoring," \ + "which is not yet implemented.") # material 1 IC rho1 = 1.0 E1 = 1.7162348000000001e+001 u1 = 5.8566201857385289e+000 e1 = E1 / rho1 - 0.5 * u1 * u1 Erad_left = 1.372E-06 # material 2 IC rho2 = 6.5189217901173153e+000 E2 = 9.5144308747326214e+000 u2 = 8.9840319830453630e-001 e2 = E2 / rho2 - 0.5 * u2 * u2 Erad_right = 7.3372623010289956e+001 # final time t_end = 1.5 # temperature plot filename test_filename = "radshock_mach50.pdf" # temperature plot exact solution filename exact_solution_filename = "mach50_exact_solution.csv" elif test_case == "marcho2": # material 1 IC rho1 = 1.0 u1 = 0.23426480742954117 T1 = 1.219999999999999973e-01 e1 = T1 * c_v2 E1 = 0.5 * rho1 * u1 * u1 + e1 * rho1 Erad_left = 3.039477120074432e-06 # material 2 IC rho2 = 2.286074898930029242 u2 = 0.10247468599526272 T2 = 2.534635394302977573e-01 e2 = T2 * c_v2 E2 = 0.5 * rho2 * u2 * u2 + e2 * rho2 Erad_right = 5.662673693907908e-05 print "rho", rho1, rho2 print "vel", u1, u2 print "Temperature", T1, T2 print "momentum", rho1 * u1, rho2 * u2 print "E", E1, E2 print "E_r", Erad_left, Erad_right # final time t_end = 0.10 # temperature plot filename test_filename = "radshock_mach50.pdf" # temperature plot exact solution filename exact_solution_filename = "marcho2_exact_solution.csv" elif test_case == "marcho1.05": # material 1 IC rho1 = 1.0 u1 = 0.1228902 T1 = 0.1 e1 = T1 * c_v2 E1 = 0.5 * rho1 * u1 * u1 + e1 * rho1 Erad_left = 1.372E-06 # material 2 IC rho2 = 1.0749588 u2 = rho1 * u1 / rho2 T2 = 0.1049454 e2 = T2 * c_v2 E2 = 0.5 * rho2 * u2 * u2 + e2 * rho2 Erad_right = 1.664211799256650E-06 print "rho", rho1, rho2 print "vel", u1, u2 print "Temperature", T1, T2 print "momentum", rho1 * u1, rho2 * u2 print "E", E1, E2 print "E_r", Erad_left, Erad_right # final time t_end = 1.0 # temperature plot filename test_filename = "radshock_mach50.pdf" # temperature plot exact solution filename exact_solution_filename = "marcho1.05_exact_solution.csv" exact_solution_filename = None elif test_case == "marcho3": #new c_v and pure absorber cross sections c_v1 = 0.221804 c_v2 = c_v1 sig_a1 = 577.3502692 sig_s1 = 0. sig_a2 = sig_a1 sig_s2 = sig_s1 # material 1 IC rho1 = 1.0 mom1 = 0.5192549757 u1 = mom1 / rho1 T1 = 0.1215601363 e1 = T1 * c_v1 E1 = 0.5 * rho1 * u1 * u1 + e1 * rho1 Erad_left = 2.995841442e-06 # material 2 IC rho2 = 3.002167609 u2 = rho1 * u1 / rho2 T2 = 0.4451426103 e2 = T2 * c_v2 E2 = 0.5 * rho2 * u2 * u2 + e2 * rho2 Erad_right = 0.0005387047241 print "rho", rho1, rho2 print "vel", u1, u2 print "Temperature", T1, T2 print "momentum", rho1 * u1, rho2 * u2 print "E", E1, E2 print "E_r", Erad_left, Erad_right # final time t_end = 1.0 # temperature plot filename test_filename = "radshock_marcho3.pdf" # temperature plot exact solution filename exact_solution_filename = None else: raise NotImplementedError("Invalid test case") # compute radiation BC; assumes BC is independent of time c = GC.SPD_OF_LGT psi_left = 0.5 * c * Erad_left psi_right = 0.5 * c * Erad_right #Create BC object rad_BC = RadBC(mesh, "dirichlet", psi_left=psi_left, psi_right=psi_right) # construct cross sections and hydro IC cross_sects = list() hydro_IC = list() psi_IC = list() for i in range(mesh.n_elems): if mesh.getElement(i).x_cent < mesh_center: # material 1 cross_sects.append( (ConstantCrossSection(sig_s1, sig_s1 + sig_a1), ConstantCrossSection(sig_s1, sig_s1 + sig_a1))) hydro_IC.append( HydroState(u=u1, rho=rho1, e=e1, spec_heat=c_v1, gamma=gam)) psi_IC += [psi_left for dof in range(4)] else: # material 2 cross_sects.append( (ConstantCrossSection(sig_s2, sig_a2 + sig_s2), ConstantCrossSection(sig_s2, sig_a2 + sig_s2))) hydro_IC.append( HydroState(u=u2, rho=rho2, e=e2, spec_heat=c_v2, gamma=gam)) psi_IC += [psi_right for dof in range(4)] #Smooth out the middle solution optionally, shouldnt need this n_smoothed = 0 state_l = hydro_IC[0] state_r = hydro_IC[-1] rho_l = state_l.rho rho_r = state_r.rho drho = rho_r - rho_l u_l = state_l.u u_r = state_r.u du = u_r - u_l e_l = state_l.e e_r = state_r.e de = e_r - e_l print "p", state_l.p, state_r.p print "mach number", state_l.u / state_l.getSoundSpeed( ), state_r.u / state_r.getSoundSpeed() #Scale idx = 0 if n_smoothed > 0: for i in range(mesh.n_elems / 2 - n_smoothed / 2 - 1, mesh.n_elems / 2 + n_smoothed / 2): rho = rho_l + drho * idx / n_smoothed u = rho_l * u_l / rho e = e_l + de * idx / n_smoothed idx += 1 E = 0.5 * rho * u * u + rho * e hydro_IC[i].updateState(rho, rho * u, E) # plot hydro initial conditions plotHydroSolutions(mesh, hydro_IC) rad_IC = Radiation(psi_IC) # create hydro BC hydro_BC = HydroBC(bc_type='fixed', mesh=mesh, state_L=state_l, state_R=state_r) hydro_BC = HydroBC(mesh=mesh, bc_type='reflective') # transient options t_start = 0.0 # if run standalone, then be verbose if __name__ == '__main__': verbosity = 2 else: verbosity = 0 # run the rad-hydro transient rad_new, hydro_new = runNonlinearTransient(mesh=mesh, problem_type='rad_hydro', dt_option='CFL', CFL=0.6, use_2_cycles=True, t_start=t_start, t_end=t_end, rad_BC=rad_BC, cross_sects=cross_sects, rad_IC=rad_IC, hydro_IC=hydro_IC, hydro_BC=hydro_BC, verbosity=verbosity, slope_limiter=slope_limiter, check_balance=False) # plot if __name__ == '__main__': # compute exact hydro solution hydro_exact = None # plot hydro solution plotHydroSolutions(mesh, hydro_new, exact=hydro_exact) # plot material and radiation temperatures plotTemperatures(mesh, rad_new.E, hydro_states=hydro_new, print_values=True, save=True, filename=test_filename, exact_solution_filename=exact_solution_filename) # plot angular fluxes plotS2Erg(mesh, rad_new.psim, rad_new.psip)
def test_RadHydroShock(self): # test case test_case = "marcho3" # mach1.2 mach2 mach50 # create uniform mesh n_elems = 1000 width = 0.04 x_start = -0.02 mesh_center = x_start + 0.5*width mesh = Mesh(n_elems, width, x_start=x_start) # slope limiter slope_limiter = "double-minmod" # gamma constant gam = 5.0/3.0 # material 1 and 2 properties: Table 6.1 sig_a1 = 390.71164263502122 sig_s1 = 853.14410158161809 -sig_a1 c_v1 = 0.12348 sig_a2 = sig_a1 sig_s2 = sig_s1 c_v2 = c_v1 if not (test_case == "mach2" or test_case == "marcho3"): raise NotImplementedError("All but mach2 and marcho3 shock may have wrong input"\ "values. Need to check Jarrod Ewards thesis, starting with Table 6.1") if test_case == "mach1.2": # Mach 1.2 problem: Table 6.2 # material 1 IC rho1 = 1.0 E1 = 2.2226400000000000e-02 u1 = 1.4055888445772469e-01 e1 = E1/rho1 - 0.5*u1*u1 Erad_left = 1.372E-06 # material 2 IC rho2 = 1.2973213452231311 E2 = 2.6753570531538713e-002 u2 = 1.0834546504247138e-001 e2 = E2/rho2 - 0.5*u2*u2 Erad_right = 2.7955320762182542e-06 # final time t_end = 0.5 # temperature plot filename test_filename = "radshock_mach1.2.pdf" # temperature plot exact solution filename exact_solution_filename = "mach1.2_exact_solution.csv" elif test_case == "mach2": # Mach 2 problem: Table 6.3 # material 1 IC rho1 = 1.0 E1 = 3.9788000000000004e-002 u1 = 2.3426480742954117e-001 e1 = E1/rho1 - 0.5*u1*u1 T1 = e1/c_v1 Erad_left = 1.372E-06 # material 2 IC rho2 = 2.2860748989303659e+000 E2 = 7.0649692950433357e-002 u2 = 1.0247468599526272e-001 e2 = E2/rho2 - 0.5*u2*u2 T2 = e2/c_v2 Erad_right = 2.5560936967521927e-005 print "rho", rho1, rho2 print "vel", u1, u2 print "Temperature", T1, T2 print "momentum", rho1*u1, rho2*u2 print "E",E1, E2 print "E_r",Erad_left, Erad_right print sig_a1, sig_s1 # final time t_end = 1.0 # temperature plot output filename test_filename = "radshock_mach2.pdf" # temperature plot exact solution filename exact_solution_filename = "marcho2_exact_solution.csv" elif test_case == "mach50": # Mach 50 problem: Table 6.4 raise NotImplementedError("Mach 50 test requires negativity monitoring," \ + "which is not yet implemented.") # material 1 IC rho1 = 1.0 E1 = 1.7162348000000001e+001 u1 = 5.8566201857385289e+000 e1 = E1/rho1 - 0.5*u1*u1 Erad_left = 1.372E-06 # material 2 IC rho2 = 6.5189217901173153e+000 E2 = 9.5144308747326214e+000 u2 = 8.9840319830453630e-001 e2 = E2/rho2 - 0.5*u2*u2 Erad_right = 7.3372623010289956e+001 # final time t_end = 1.5 # temperature plot filename test_filename = "radshock_mach50.pdf" # temperature plot exact solution filename exact_solution_filename = "mach50_exact_solution.csv" elif test_case == "marcho2": # material 1 IC rho1 = 1.0 u1 = 0.23426480742954117 T1 = 1.219999999999999973e-01 e1 = T1*c_v2 E1 = 0.5*rho1*u1*u1 + e1*rho1 Erad_left = 3.039477120074432e-06 # material 2 IC rho2 = 2.286074898930029242 u2 = 0.10247468599526272 T2 = 2.534635394302977573e-01 e2 = T2*c_v2 E2 = 0.5*rho2*u2*u2 + e2*rho2 Erad_right = 5.662673693907908e-05 print "rho", rho1, rho2 print "vel", u1, u2 print "Temperature", T1, T2 print "momentum", rho1*u1, rho2*u2 print "E",E1, E2 print "E_r",Erad_left, Erad_right # final time t_end = 0.10 # temperature plot filename test_filename = "radshock_mach50.pdf" # temperature plot exact solution filename exact_solution_filename = "marcho2_exact_solution.csv" elif test_case == "marcho1.05": # material 1 IC rho1 = 1.0 u1 = 0.1228902 T1 = 0.1 e1 = T1*c_v2 E1 = 0.5*rho1*u1*u1 + e1*rho1 Erad_left = 1.372E-06 # material 2 IC rho2 = 1.0749588 u2 = rho1*u1/rho2 T2 = 0.1049454 e2 = T2*c_v2 E2 = 0.5*rho2*u2*u2 + e2*rho2 Erad_right = 1.664211799256650E-06 print "rho", rho1, rho2 print "vel", u1, u2 print "Temperature", T1, T2 print "momentum", rho1*u1, rho2*u2 print "E",E1, E2 print "E_r",Erad_left, Erad_right # final time t_end = 1.0 # temperature plot filename test_filename = "radshock_mach50.pdf" # temperature plot exact solution filename exact_solution_filename = "marcho1.05_exact_solution.csv" exact_solution_filename = None elif test_case == "marcho3": #new c_v and pure absorber cross sections c_v1 = 0.221804 c_v2 = c_v1 sig_a1 = 577.3502692 sig_s1 = 0. sig_a2 = sig_a1 sig_s2 = sig_s1 # material 1 IC rho1 = 1.0 mom1 = 0.5192549757 u1 = mom1/rho1 T1 = 0.1215601363 e1 = T1*c_v1 E1 = 0.5*rho1*u1*u1 + e1*rho1 Erad_left = 2.995841442e-06 # material 2 IC rho2 = 3.002167609 u2 = rho1*u1/rho2 T2 = 0.4451426103 e2 = T2*c_v2 E2 = 0.5*rho2*u2*u2 + e2*rho2 Erad_right = 0.0005387047241 print "rho", rho1, rho2 print "vel", u1, u2 print "Temperature", T1, T2 print "momentum", rho1*u1, rho2*u2 print "E",E1, E2 print "E_r",Erad_left, Erad_right # final time t_end = 1.0 # temperature plot filename test_filename = "radshock_marcho3.pdf" # temperature plot exact solution filename exact_solution_filename = None else: raise NotImplementedError("Invalid test case") # compute radiation BC; assumes BC is independent of time c = GC.SPD_OF_LGT psi_left = 0.5*c*Erad_left psi_right = 0.5*c*Erad_right #Create BC object rad_BC = RadBC(mesh, "dirichlet", psi_left=psi_left, psi_right=psi_right) # construct cross sections and hydro IC cross_sects = list() hydro_IC = list() psi_IC = list() for i in range(mesh.n_elems): if mesh.getElement(i).x_cent < mesh_center: # material 1 cross_sects.append( (ConstantCrossSection(sig_s1, sig_s1+sig_a1), ConstantCrossSection(sig_s1, sig_s1+sig_a1)) ) hydro_IC.append( HydroState(u=u1,rho=rho1,e=e1,spec_heat=c_v1,gamma=gam)) psi_IC += [psi_left for dof in range(4)] else: # material 2 cross_sects.append((ConstantCrossSection(sig_s2, sig_a2+sig_s2), ConstantCrossSection(sig_s2, sig_a2+sig_s2))) hydro_IC.append( HydroState(u=u2,rho=rho2,e=e2,spec_heat=c_v2,gamma=gam)) psi_IC += [psi_right for dof in range(4)] #Smooth out the middle solution optionally, shouldnt need this n_smoothed = 0 state_l = hydro_IC[0] state_r = hydro_IC[-1] rho_l = state_l.rho rho_r = state_r.rho drho = rho_r - rho_l u_l = state_l.u u_r = state_r.u du = u_r - u_l e_l = state_l.e e_r = state_r.e de = e_r-e_l print "p", state_l.p, state_r.p print "mach number", state_l.u/state_l.getSoundSpeed(), state_r.u/state_r.getSoundSpeed() #Scale idx = 0 if n_smoothed > 0: for i in range(mesh.n_elems/2-n_smoothed/2-1,mesh.n_elems/2+n_smoothed/2): rho = rho_l + drho*idx/n_smoothed u = rho_l*u_l/rho e = e_l + de*idx/n_smoothed idx+=1 E = 0.5*rho*u*u + rho*e hydro_IC[i].updateState(rho, rho*u, E) # plot hydro initial conditions plotHydroSolutions(mesh, hydro_IC) rad_IC = Radiation(psi_IC) # create hydro BC hydro_BC = HydroBC(bc_type='fixed', mesh=mesh, state_L = state_l, state_R = state_r) hydro_BC = HydroBC(mesh=mesh,bc_type='reflective') # transient options t_start = 0.0 # if run standalone, then be verbose if __name__ == '__main__': verbosity = 2 else: verbosity = 0 # run the rad-hydro transient rad_new, hydro_new = runNonlinearTransient( mesh = mesh, problem_type = 'rad_hydro', dt_option = 'CFL', CFL = 0.6, use_2_cycles = True, t_start = t_start, t_end = t_end, rad_BC = rad_BC, cross_sects = cross_sects, rad_IC = rad_IC, hydro_IC = hydro_IC, hydro_BC = hydro_BC, verbosity = verbosity, slope_limiter = slope_limiter, check_balance=False) # plot if __name__ == '__main__': # compute exact hydro solution hydro_exact = None # plot hydro solution plotHydroSolutions(mesh, hydro_new, exact=hydro_exact) # plot material and radiation temperatures plotTemperatures(mesh, rad_new.E, hydro_states=hydro_new, print_values=True, save=True, filename=test_filename, exact_solution_filename=exact_solution_filename) # plot angular fluxes plotS2Erg(mesh, rad_new.psim, rad_new.psip)
def test_RadHydroMMS(self): # declare symbolic variables x, t, A, B, C, c, cv, gamma, mu, alpha = \ symbols('x t A B C c cv gamma mu alpha') #These constants, as well as cross sections and C_v, rho_ref #will set the material #and radiation to be small relative to kinetic energy Ctilde = 100. P = 0.1 #Arbitrary mach number well below the sound speed. The choice of gamma and #the cv value, as well as C and P constrain all other material reference #parameters, but we are free to choose the material velocity below the sound #speed to ensure no shocks are formed M = 0.9 cfl_value = 0.6 #but 2 time steps, so really like a CFL of 0.3 width = 2.0 * math.pi # numeric values gamma_value = 5. / 3. cv_value = 0.14472799784454 # number of refinement cycles n_cycles = 5 # number of elements in first cycle n_elems = 40 # transient options t_start = 0.0 t_end = 2.0 * math.pi / Ctilde # numeric values A_value = 1.0 B_value = 1.0 C_value = 1.0 alpha_value = 0.5 gamma_value = 5.0 / 3.0 sig_s_value = 0.0 sig_a_value = 1.0 # numeric values a_inf = GC.SPD_OF_LGT / Ctilde #T_inf = a_inf**2/(gamma_value*(gamma_value - 1.)*cv_value) #rho_inf = GC.RAD_CONSTANT*T_inf**4/(P*a_inf**2) rho_inf = 1.0 T_inf = pow(rho_inf * P * a_inf**2 / GC.RAD_CONSTANT, 0.25) #to set T_inf based on rho_inf, cv_value = a_inf**2 / (T_inf * gamma_value * (gamma_value - 1.) ) # to set c_v, if rho specified p_inf = rho_inf * a_inf * a_inf Er_inf = GC.RAD_CONSTANT * T_inf**4 # MMS solutions rho = rho_inf * A * (sin(B * x - C * t) + 2.) u = M * a_inf * 1. / (A * (sin(B * x - C * t) + 2.)) p = p_inf * A * alpha * (sin(B * x - C * t) + 2.) Er = alpha * (sin(B * x - Ctilde * C * t) + 2.) * Er_inf Fr = alpha * (sin(B * x - Ctilde * C * t) + 2.) * c * Er_inf #Er = 0.5*(sin(2*pi*x - 10.*t) + 2.)/c #Fr = 0.5*(sin(2*pi*x - 10.*t) + 2.) e = p / (rho * (gamma_value - 1.)) E = 0.5 * rho * u * u + rho * e print "The dimensionalization parameters are: " print " a_inf : ", a_inf print " T_inf : ", T_inf print " rho_inf : ", rho_inf print " p_inf : ", p_inf # derived solutions T = e / cv_value E = rho * (u * u / 2 + e) psip = (Er * c + Fr / mu) / 2 psim = (Er * c - Fr / mu) / 2 # create list of substitutions substitutions = dict() substitutions['A'] = A_value substitutions['B'] = B_value substitutions['C'] = C_value substitutions['c'] = GC.SPD_OF_LGT substitutions['cv'] = cv_value substitutions['gamma'] = gamma_value substitutions['mu'] = RU.mu["+"] substitutions['alpha'] = alpha_value # make substitutions rho = rho.subs(substitutions) u = u.subs(substitutions) mom = rho * u E = E.subs(substitutions) psim = psim.subs(substitutions) psip = psip.subs(substitutions) # create MMS source functions rho_src, mom_src, E_src, psim_src, psip_src = createMMSSourceFunctionsRadHydro( rho=rho, u=u, E=E, psim=psim, psip=psip, sigma_s_value=sig_s_value, sigma_a_value=sig_a_value, gamma_value=gamma_value, cv_value=cv_value, alpha_value=alpha_value, display_equations=True) # create functions for exact solutions rho_f = lambdify((symbols('x'), symbols('t')), rho, "numpy") u_f = lambdify((symbols('x'), symbols('t')), u, "numpy") mom_f = lambdify((symbols('x'), symbols('t')), mom, "numpy") E_f = lambdify((symbols('x'), symbols('t')), E, "numpy") psim_f = lambdify((symbols('x'), symbols('t')), psim, "numpy") psip_f = lambdify((symbols('x'), symbols('t')), psip, "numpy") dt = [] dx = [] err = [] for cycle in range(n_cycles): # create uniform mesh mesh = Mesh(n_elems, width) # compute radiation IC psi_IC = computeRadiationVector(psim_f, psip_f, mesh, t=0.0) rad_IC = Radiation(psi_IC) # create rad BC object rad_BC = RadBC(mesh, 'periodic') # compute hydro IC hydro_IC = computeAnalyticHydroSolution(mesh, t=0.0, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # create hydro BC hydro_BC = HydroBC(bc_type='periodic', mesh=mesh) # create cross sections cross_sects = [(ConstantCrossSection(sig_s_value, sig_s_value + sig_a_value), ConstantCrossSection(sig_s_value, sig_s_value + sig_a_value)) for i in xrange(mesh.n_elems)] # compute the initial time step size according to CFL conditon (actually # half). We will then decrease this time step by the same factor as DX each # cycle if cycle == 0: sound_speed = [ sqrt(i.p * i.gamma / i.rho) + abs(i.u) for i in hydro_IC ] dt_vals = [ cfl_value * (mesh.elements[i].dx) / sound_speed[i] for i in xrange(len(hydro_IC)) ] dt_value = min(dt_vals) print "dt_value for hydro: ", dt_value #Make sure not taking too large of step for radiation time scale period = 2. * math.pi / Ctilde dt_value = min(dt_value, period / 8.) print "initial dt_value", dt_value #Adjust the end time to be an exact increment of dt_values print "t_end: ", t_end print "This cycle's dt value: ", dt_value dt.append(dt_value) dx.append(mesh.getElement(0).dx) # if run standalone, then be verbose if __name__ == '__main__': verbosity = 2 else: verbosity = 0 #slope limiter limiter = 'double-minmod' # run the rad-hydro transient rad_new, hydro_new = runNonlinearTransient( mesh=mesh, problem_type='rad_hydro', dt_option='constant', dt_constant=dt_value, slope_limiter=limiter, time_stepper='BDF2', use_2_cycles=True, t_start=t_start, t_end=t_end, rad_BC=rad_BC, cross_sects=cross_sects, rad_IC=rad_IC, hydro_IC=hydro_IC, hydro_BC=hydro_BC, mom_src=mom_src, E_src=E_src, rho_src=rho_src, psim_src=psim_src, psip_src=psip_src, verbosity=verbosity, rho_f=rho_f, u_f=u_f, E_f=E_f, gamma_value=gamma_value, cv_value=cv_value, check_balance=False) # compute exact hydro solution hydro_exact = computeAnalyticHydroSolution(mesh, t=t_end, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) rad_exact = computeAnalyticRadSolution(mesh, t_end, psim=psim_f, psip=psip_f) #Compute error err.append( computeHydroL2Error(hydro_new, hydro_exact, rad_new, rad_exact)) n_elems *= 2 dt_value *= 0.5 # compute convergence rates rates_dx = computeHydroConvergenceRates(dx, err) rates_dt = computeHydroConvergenceRates(dt, err) # print convergence table if n_cycles > 1: printHydroConvergenceTable(dx, err, rates=rates_dx, dx_desc='dx', err_desc='$L_2$') printHydroConvergenceTable(dt, err, rates=rates_dt, dx_desc='dt', err_desc='$L_2$') # plot if __name__ == '__main__': # compute exact hydro solution hydro_exact = computeAnalyticHydroSolution(mesh, t=t_end, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # plot hydro solution plotHydroSolutions(mesh, hydro_new, x_exact=mesh.getCellCenters(), exact=hydro_exact) #plot exact and our E_r Er_exact_fn = 1. / GC.SPD_OF_LGT * (psim + psip) Fr_exact_fn = (psip - psim) * RU.mu["+"] Er_exact = [] Fr_exact = [] psip_exact = [] psim_exact = [] x = mesh.getCellCenters() for xi in x: substitutions = {'x': xi, 't': t_end} Er_exact.append(Er_exact_fn.subs(substitutions)) Fr_exact.append(Fr_exact_fn.subs(substitutions)) psip_exact.append(psip_f(xi, t_end)) psim_exact.append(psim_f(xi, t_end)) plotRadErg(mesh, rad_new.E, Fr_edge=rad_new.F, exact_Er=Er_exact, exact_Fr=Fr_exact) plotS2Erg(mesh, rad_new.psim, rad_new.psip, exact_psim=psim_exact, exact_psip=psip_exact) plotTemperatures(mesh, rad_new.E, hydro_states=hydro_new, print_values=True) #Make a pickle to save the error tables from sys import argv pickname = "results/testRadHydroStreamingMMSC100.pickle" if len(argv) > 2: if argv[1] == "-o": pickname = argv[2].strip() #Create dictionary of all the data big_dic = {"dx": dx} big_dic["dt"] = dt big_dic["Errors"] = err pickle.dump(big_dic, open(pickname, "w"))
def test_RadHydroMMS(self): # slope limiter: choices are: # none step minmod double-minmod superbee minbee vanleer slope_limiter = 'none' # number of elements n_elems = 50 # end time t_end = 0.1 # choice of solutions for hydro hydro_case = "linear" # constant linear exponential # choice of solutions for radiation rad_case = "zero" # zero constant sin # declare symbolic variables x, t, alpha, c = symbols('x t alpha c') # create solution for thermodynamic state and flow field if hydro_case == "constant": rho = sympify('4.0') u = sympify('1.2') E = sympify('10.0') elif hydro_case == "linear": rho = 1 + x - t u = sympify('1') E = 5 + 5*(x - 0.5)**2 elif hydro_case == "exponential": rho = exp(x+t)+5 u = exp(-x)*sin(t) - 1 E = 10*exp(x+t) else: raise NotImplementedError("Invalid hydro test case") # create solution for radiation field if rad_case == "zero": psim = sympify('0') psip = sympify('0') elif rad_case == "constant": psim = 50*c psip = 50*c elif rad_case == "sin": rad_scale = 50*c psim = rad_scale*2*t*sin(pi*(1-x))+10*c psip = rad_scale*t*sin(pi*x)+10*c else: raise NotImplementedError("Invalid radiation test case") # numeric values alpha_value = 0.01 cv_value = 1.0 gamma_value = 1.4 sig_s = 1.0 sig_a = 1.0 #sig_a = 0.0 # create MMS source functions rho_src, mom_src, E_src, psim_src, psip_src = createMMSSourceFunctionsRadHydro( rho = rho, u = u, E = E, psim = psim, psip = psip, sigma_s_value = sig_s, sigma_a_value = sig_a, gamma_value = gamma_value, cv_value = cv_value, alpha_value = alpha_value, display_equations = False) # create functions for exact solutions substitutions = dict() substitutions['alpha'] = alpha_value substitutions['c'] = GC.SPD_OF_LGT rho = rho.subs(substitutions) u = u.subs(substitutions) mom = rho*u E = E.subs(substitutions) psim = psim.subs(substitutions) psip = psip.subs(substitutions) rho_f = lambdify((symbols('x'),symbols('t')), rho, "numpy") u_f = lambdify((symbols('x'),symbols('t')), u, "numpy") mom_f = lambdify((symbols('x'),symbols('t')), mom, "numpy") E_f = lambdify((symbols('x'),symbols('t')), E, "numpy") psim_f = lambdify((symbols('x'),symbols('t')), psim, "numpy") psip_f = lambdify((symbols('x'),symbols('t')), psip, "numpy") # create uniform mesh width = 1.0 mesh = Mesh(n_elems, width) # compute radiation IC psi_IC = computeRadiationVector(psim_f, psip_f, mesh, t=0.0) rad_IC = Radiation(psi_IC) # compute radiation BC; assumes BC is independent of time psi_left = psip_f(x=0.0, t=0.0) psi_right = psim_f(x=width, t=0.0) #Create Radiation BC object rad_BC = RadBC(mesh, "dirichlet", psi_left=psi_left, psi_right=psi_right) # compute hydro IC hydro_IC = computeAnalyticHydroSolution(mesh,t=0.0, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # create hydro BC hydro_BC = HydroBC(bc_type='dirichlet', mesh=mesh, rho_BC=rho_f, mom_BC=mom_f, erg_BC=E_f) # create cross sections cross_sects = [(ConstantCrossSection(sig_s, sig_s+sig_a), ConstantCrossSection(sig_s, sig_s+sig_a)) for i in xrange(mesh.n_elems)] # if run standalone, then be verbose if __name__ == '__main__': verbosity = 2 else: verbosity = 0 # run the rad-hydro transient rad_new, hydro_new = runNonlinearTransient( mesh = mesh, problem_type = 'rad_hydro', dt_option = 'CFL', #dt_option = 'constant', CFL = 0.5, #dt_constant = 0.002, slope_limiter = slope_limiter, time_stepper = 'BDF2', use_2_cycles = True, t_start = 0.0, t_end = t_end, rad_BC = rad_BC, cross_sects = cross_sects, rad_IC = rad_IC, hydro_IC = hydro_IC, hydro_BC = hydro_BC, mom_src = mom_src, E_src = E_src, rho_src = rho_src, psim_src = psim_src, psip_src = psip_src, verbosity = verbosity, check_balance = False) # plot if __name__ == '__main__': # compute exact hydro solution hydro_exact = computeAnalyticHydroSolution(mesh, t=t_end, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # plot hydro solution plotHydroSolutions(mesh, hydro_new, x_exact=mesh.getCellCenters(), exact=hydro_exact) # compute exact radiation energy Er_exact_fn = 1./GC.SPD_OF_LGT*(psim + psip) Er_exact = [] x = mesh.getCellCenters() for xi in x: substitutions = {'x':xi, 't':t_end} Er_exact.append(Er_exact_fn.subs(substitutions)) # plot radiation energy plotRadErg(mesh, rad_new.E, exact_Er=Er_exact)
def test_HydroMMS(self): # number of elements in first cycle n_elems = 25 # number of refinement cycles n_cycles = 4 # spatial and temporal domains width = 1.0 t_start = 0.0 t_end = 0.02 # declare symbolic variables x, t, alpha = symbols('x t alpha') # physics parameters (floats, not sympy) alpha_value = 0.01 cv_value = 1.0 gamma_value = 1.4 sig_s = 0.0 sig_a = 0.0 # create solution for thermodynamic state and flow field # rho = sympify('4') # u = sympify('1.3') # E = sympify('10') rho = 2. + sin(2*pi*x) u = 2. + cos(2*pi*x) p = 2. + cos(2*pi*x) e = p/(rho*(gamma_value-1.)) E = 0.5*rho*u*u + rho*e # create solution for radiation field psim = sympify('0') psip = sympify('0') # create MMS source functions rho_src, mom_src, E_src, psim_src, psip_src = createMMSSourceFunctionsHydroOnly( rho = rho, u = u, E = E, gamma_value = gamma_value, cv_value = cv_value, alpha_value = alpha_value, display_equations = True) # create functions for exact solutions substitutions = dict() substitutions['alpha'] = alpha_value rho = rho.subs(substitutions) u = u.subs(substitutions) mom = rho*u E = E.subs(substitutions) rho_f = lambdify((symbols('x'),symbols('t')), rho, "numpy") u_f = lambdify((symbols('x'),symbols('t')), u, "numpy") mom_f = lambdify((symbols('x'),symbols('t')), mom, "numpy") E_f = lambdify((symbols('x'),symbols('t')), E, "numpy") psim_f = lambdify((symbols('x'),symbols('t')), psim, "numpy") psip_f = lambdify((symbols('x'),symbols('t')), psip, "numpy") # compute radiation BC; assumes BC is independent of time psi_left = psip_f(x=0.0, t=0.0) psi_right = psim_f(x=width, t=0.0) # initialize lists for mesh size and L1 error for each cycle max_dx = list() err = list() # loop over refinement cycles for cycle in xrange(n_cycles): if __name__ == '__main__': print("\nCycle %d of %d: n_elems = %d" % (cycle+1,n_cycles,n_elems)) # create uniform mesh mesh = Mesh(n_elems, width) # append max dx for this cycle to list max_dx.append(mesh.max_dx) # compute radiation IC psi_IC = computeRadiationVector(psim_f, psip_f, mesh, t=0.0) rad_IC = Radiation(psi_IC) # compute hydro IC hydro_IC = computeAnalyticHydroSolution(mesh, t=0.0, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # create hydro BC hydro_BC = HydroBC(bc_type='periodic', mesh=mesh) # create cross sections cross_sects = [(ConstantCrossSection(sig_s, sig_s+sig_a), ConstantCrossSection(sig_s, sig_s+sig_a)) for i in xrange(mesh.n_elems)] # slope limiter option slope_limiter = "none" # if run standalone, then be verbose if __name__ == '__main__': if n_cycles == 1: verbosity = 2 else: verbosity = 1 else: verbosity = 0 # run the rad-hydro transient rad_new, hydro_new = runNonlinearTransient( mesh = mesh, problem_type = 'rad_hydro', dt_option = 'CFL', CFL = 0.5, slope_limiter = slope_limiter, time_stepper = 'BDF2', use_2_cycles = True, t_start = t_start, t_end = t_end, psi_left = psi_left, psi_right = psi_right, hydro_BC = hydro_BC, cross_sects = cross_sects, rad_IC = rad_IC, hydro_IC = hydro_IC, mom_src = mom_src, E_src = E_src, psim_src = psim_src, psip_src = psip_src, rho_src = rho_src, verbosity = verbosity, check_balance = True, rho_f =rho_f, u_f = u_f, E_f = E_f, gamma_value = gamma_value, cv_value = cv_value ) # compute exact hydro solution hydro_exact = computeAnalyticHydroSolution(mesh, t=t_end, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # compute error err.append(computeHydroL2Error(hydro_new, hydro_exact)) # double number of elements for next cycle n_elems *= 2 # compute convergence rates rates = computeHydroConvergenceRates(max_dx,err) # print convergence table and plot if __name__ == '__main__': # print convergence table if n_cycles > 1: printHydroConvergenceTable(max_dx,err,rates=rates, dx_desc='dx',err_desc='L2') # plot hydro solution plotHydroSolutions(mesh, hydro_new, x_exact=mesh.getCellCenters(), exact=hydro_exact)
def test_HydroMMS(self): # number of elements in first cycle n_elems = 25 # number of refinement cycles n_cycles = 4 # spatial and temporal domains width = 1.0 t_start = 0.0 t_end = 0.02 # declare symbolic variables x, t, alpha = symbols('x t alpha') # physics parameters (floats, not sympy) alpha_value = 0.01 cv_value = 1.0 gamma_value = 1.4 sig_s = 0.0 sig_a = 0.0 # create solution for thermodynamic state and flow field # rho = sympify('4') # u = sympify('1.3') # E = sympify('10') rho = 2. + sin(2 * pi * x) u = 2. + cos(2 * pi * x) p = 2. + cos(2 * pi * x) e = p / (rho * (gamma_value - 1.)) E = 0.5 * rho * u * u + rho * e # create solution for radiation field psim = sympify('0') psip = sympify('0') # create MMS source functions rho_src, mom_src, E_src, psim_src, psip_src = createMMSSourceFunctionsHydroOnly( rho=rho, u=u, E=E, gamma_value=gamma_value, cv_value=cv_value, alpha_value=alpha_value, display_equations=True) # create functions for exact solutions substitutions = dict() substitutions['alpha'] = alpha_value rho = rho.subs(substitutions) u = u.subs(substitutions) mom = rho * u E = E.subs(substitutions) rho_f = lambdify((symbols('x'), symbols('t')), rho, "numpy") u_f = lambdify((symbols('x'), symbols('t')), u, "numpy") mom_f = lambdify((symbols('x'), symbols('t')), mom, "numpy") E_f = lambdify((symbols('x'), symbols('t')), E, "numpy") psim_f = lambdify((symbols('x'), symbols('t')), psim, "numpy") psip_f = lambdify((symbols('x'), symbols('t')), psip, "numpy") # compute radiation BC; assumes BC is independent of time psi_left = psip_f(x=0.0, t=0.0) psi_right = psim_f(x=width, t=0.0) # initialize lists for mesh size and L1 error for each cycle max_dx = list() err = list() # loop over refinement cycles for cycle in xrange(n_cycles): if __name__ == '__main__': print("\nCycle %d of %d: n_elems = %d" % (cycle + 1, n_cycles, n_elems)) # create uniform mesh mesh = Mesh(n_elems, width) # append max dx for this cycle to list max_dx.append(mesh.max_dx) # compute radiation IC psi_IC = computeRadiationVector(psim_f, psip_f, mesh, t=0.0) rad_IC = Radiation(psi_IC) # compute hydro IC hydro_IC = computeAnalyticHydroSolution(mesh, t=0.0, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # create hydro BC hydro_BC = HydroBC(bc_type='periodic', mesh=mesh) # create cross sections cross_sects = [(ConstantCrossSection(sig_s, sig_s + sig_a), ConstantCrossSection(sig_s, sig_s + sig_a)) for i in xrange(mesh.n_elems)] # slope limiter option slope_limiter = "none" # if run standalone, then be verbose if __name__ == '__main__': if n_cycles == 1: verbosity = 2 else: verbosity = 1 else: verbosity = 0 # run the rad-hydro transient rad_new, hydro_new = runNonlinearTransient( mesh=mesh, problem_type='rad_hydro', dt_option='CFL', CFL=0.5, slope_limiter=slope_limiter, time_stepper='BDF2', use_2_cycles=True, t_start=t_start, t_end=t_end, psi_left=psi_left, psi_right=psi_right, hydro_BC=hydro_BC, cross_sects=cross_sects, rad_IC=rad_IC, hydro_IC=hydro_IC, mom_src=mom_src, E_src=E_src, psim_src=psim_src, psip_src=psip_src, rho_src=rho_src, verbosity=verbosity, check_balance=True, rho_f=rho_f, u_f=u_f, E_f=E_f, gamma_value=gamma_value, cv_value=cv_value) # compute exact hydro solution hydro_exact = computeAnalyticHydroSolution(mesh, t=t_end, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # compute error err.append(computeHydroL2Error(hydro_new, hydro_exact)) # double number of elements for next cycle n_elems *= 2 # compute convergence rates rates = computeHydroConvergenceRates(max_dx, err) # print convergence table and plot if __name__ == '__main__': # print convergence table if n_cycles > 1: printHydroConvergenceTable(max_dx, err, rates=rates, dx_desc='dx', err_desc='L2') # plot hydro solution plotHydroSolutions(mesh, hydro_new, x_exact=mesh.getCellCenters(), exact=hydro_exact)
def test_Hydro(self): # create mesh n_elems = 100 width = 1.0 mesh = Mesh(n_elems,width) x_diaphragm = 0.3 # time step size and transient start and end times CFL = 0.5 t_start = 0.0 t_end = 0.2 # slope limiter slope_limiter = "vanleer" # constant properties sig_s = 1.0 # arbitrary sig_a = 0.0 # set to zero to ensure no emission sig_t = sig_s + sig_a c_v = 3.0 # arbitrary gam = 1.4 # hydro IC values for left half of domain rhoL = 1.0 uL = 0.75 pL = 1.0 # hydro IC values for right half of domain rhoR = 0.125 uR = 0.0 pR = 0.1 # compute left and right internal energies eL = pL/(rhoL*(gam - 1.0)) eR = pR/(rhoR*(gam - 1.0)) # construct cross sections and hydro IC cross_sects = list() hydro_IC = list() for i in range(mesh.n_elems): # cross section is constant cross_sects.append( (ConstantCrossSection(sig_s, sig_t), ConstantCrossSection(sig_s, sig_t)) ) # IC for left half of domain if mesh.getElement(i).x_cent < x_diaphragm: hydro_IC.append( HydroState(u=uL,rho=rhoL,e=eL,gamma=gam,spec_heat=c_v) ) # IC for right half of domain else: hydro_IC.append( HydroState(u=uR,rho=rhoR,e=eR,gamma=gam,spec_heat=c_v) ) # create hydro BC hydro_BC = HydroBC(bc_type='reflective', mesh=mesh) # initialize radiation to zero solution to give pure hydrodynamics rad_IC = Radiation([0.0 for i in range(n_elems*4)]) psi_left = 0.0 psi_right = 0.0 rad_BC = RadBC(mesh, "dirichlet", psi_left=psi_left, psi_right=psi_right) # if run standalone, then be verbose if __name__ == '__main__': verbosity = 2 else: verbosity = 0 # run transient rad_new, hydro_new = runNonlinearTransient( mesh = mesh, time_stepper = 'BE', problem_type = 'rad_hydro', dt_option = 'CFL', CFL = 0.5, use_2_cycles = True, t_start = t_start, t_end = t_end, rad_BC = rad_BC, cross_sects = cross_sects, rad_IC = rad_IC, hydro_IC = hydro_IC, hydro_BC = hydro_BC, slope_limiter = slope_limiter, verbosity = verbosity, check_balance= True) # plot solutions if run standalone if __name__ == "__main__": # get exact solutions #get the exact values f = open('exact_testHydro.txt', 'r') x_e = [] u_e = [] p_e = [] rho_e = [] e_e = [] for line in f: if len(line.split())==1: t = line.split() else: data = line.split() x_e.append(float(data[0])) u_e.append(float(data[1])) p_e.append(float(data[2])) rho_e.append(float(data[4])) e_e.append(float(data[3])) hydro_exact = [] for i in range(len(x_e)): hydro_exact.append(HydroState(u=u_e[i],rho=rho_e[i],e=e_e[i],gamma=gam,spec_heat=c_v) ) plotHydroSolutions(mesh, hydro_new,x_exact=x_e,exact=hydro_exact)
def test_RadHydroMMS(self): # declare symbolic variables x, t, alpha, c = symbols('x t alpha c') # numeric values alpha_value = 0.01 cv_value = 1.0 gamma_value = 1.4 sig_s = 1.0 sig_a = 1.0 # create solution for thermodynamic state and flow field # rho = sympify('4.0') # u = sympify('1.0') # E = sympify('10.0') rho = 2. + sin(2 * pi * x + t) u = 2. + cos(2 * pi * x - t) p = 2. + cos(2 * pi * x + t) e = p / (rho * (gamma_value - 1.)) E = 0.5 * rho * u * u + rho * e # create solution for radiation field rad_scale = 50 * c psim = rad_scale * (2 * t * sin(pi * (1 - x)) + 2 + 0.1 * t) psip = rad_scale * (t * sin(pi * x) + 2 + 0.1 * t) # create MMS source functions rho_src, mom_src, E_src, psim_src, psip_src = createMMSSourceFunctionsRadHydro( rho=rho, u=u, E=E, psim=psim, psip=psip, sigma_s_value=sig_s, sigma_a_value=sig_a, gamma_value=gamma_value, cv_value=cv_value, alpha_value=alpha_value, display_equations=True) # create functions for exact solutions substitutions = dict() substitutions['alpha'] = alpha_value substitutions['c'] = GC.SPD_OF_LGT rho = rho.subs(substitutions) u = u.subs(substitutions) mom = rho * u E = E.subs(substitutions) psim = psim.subs(substitutions) psip = psip.subs(substitutions) rho_f = lambdify((symbols('x'), symbols('t')), rho, "numpy") u_f = lambdify((symbols('x'), symbols('t')), u, "numpy") mom_f = lambdify((symbols('x'), symbols('t')), mom, "numpy") E_f = lambdify((symbols('x'), symbols('t')), E, "numpy") psim_f = lambdify((symbols('x'), symbols('t')), psim, "numpy") psip_f = lambdify((symbols('x'), symbols('t')), psip, "numpy") # create uniform mesh n_elems = 50 width = 1.0 mesh = Mesh(n_elems, width) # compute radiation IC psi_IC = computeRadiationVector(psim_f, psip_f, mesh, t=0.0) rad_IC = Radiation(psi_IC) # create rad BC object rad_BC = RadBC(mesh, 'dirichlet', psip_BC=psip_f, psim_BC=psim_f) # compute hydro IC hydro_IC = computeAnalyticHydroSolution(mesh, t=0.0, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # create hydro BC hydro_BC = HydroBC(bc_type='periodic', mesh=mesh) # create cross sections cross_sects = [(ConstantCrossSection(sig_s, sig_s + sig_a), ConstantCrossSection(sig_s, sig_s + sig_a)) for i in xrange(mesh.n_elems)] # transient options t_start = 0.0 # t_end = 0.005 t_end = 0.02 # if run standalone, then be verbose if __name__ == '__main__': verbosity = 2 else: verbosity = 0 #slope limiter limiter = 'none' # run the rad-hydro transient rad_new, hydro_new = runNonlinearTransient( mesh=mesh, problem_type='rad_hydro', dt_option='CFL', CFL=0.5, # dt_option = 'constant', # dt_constant = 0.0002, slope_limiter=limiter, time_stepper='BDF2', use_2_cycles=True, t_start=t_start, t_end=t_end, rad_BC=rad_BC, cross_sects=cross_sects, rad_IC=rad_IC, hydro_IC=hydro_IC, hydro_BC=hydro_BC, mom_src=mom_src, E_src=E_src, rho_src=rho_src, psim_src=psim_src, psip_src=psip_src, verbosity=verbosity, rho_f=rho_f, u_f=u_f, E_f=E_f, gamma_value=gamma_value, cv_value=cv_value, check_balance=True) # plot if __name__ == '__main__': # plot radiation solution # compute exact hydro solution hydro_exact = computeAnalyticHydroSolution(mesh, t=t_end, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # plot hydro solution plotHydroSolutions(mesh, hydro_new, x_exact=mesh.getCellCenters(), exact=hydro_exact) #plot exact and our E_r Er_exact_fn = 1. / GC.SPD_OF_LGT * (psim + psip) Er_exact = [] x = mesh.getCellCenters() for xi in x: substitutions = {'x': xi, 't': t_end} Er_exact.append(Er_exact_fn.subs(substitutions)) plotRadErg(mesh, rad_new.E, exact_Er=Er_exact)
def test_TRTBE(self): # create mesh n_elems = 200 mesh = Mesh(n_elems, 1.) # time step size and transient start and end times dt = 0.001 t_start = 0.0 #t_end = 0.01 t_end = 0.1 # initialize temperature T_init = 0.05 T_l = 0.5 T_r = 0.05 # gamma constant gam = 1.4 # material 1 properties and IC sig_s1 = 0.0 sig_a1 = 0.2 c_v1 = convSpecHeatErgsEvToJksKev(1.E+12) rho1 = 0.01 e1 = T_init * c_v1 # material 2 properties and IC sig_s2 = 0.0 sig_a2 = 2000. c_v2 = c_v1 rho2 = 10. e2 = T_init * c_v2 # construct cross sections and hydro IC cross_sects = list() hydro_IC = list() for i in range(mesh.n_elems): if mesh.getElement(i).x_cent < 0.5: # material 1 cross_sects.append( (ConstantCrossSection(sig_s1, sig_s1 + sig_a1), ConstantCrossSection(sig_s1, sig_s1 + sig_a1))) hydro_IC.append( HydroState(u=0, rho=rho1, e=e1, spec_heat=c_v1, gamma=gam)) else: # material 2 cross_sects.append( (ConstantCrossSection(sig_s2, sig_a2 + sig_s2), ConstantCrossSection(sig_s2, sig_a2 + sig_s2))) hydro_IC.append( HydroState(u=0, rho=rho2, e=e2, spec_heat=c_v2, gamma=gam)) # create hydro BC hydro_BC = HydroBC(bc_type='reflective', mesh=mesh) # initialize radiation to equilibrium solution psi_left = computeEquivIntensity(T_l) psi_right = computeEquivIntensity(T_r) rad_IC = Radiation([psi_right for i in range(n_elems * 4)]) rad_BC = RadBC(mesh, "dirichlet", psi_left=psi_left, psi_right=psi_right) # time-stepper time_stepper = "BDF2" # if run standalone, then be verbose if __name__ == '__main__': verbosity = 2 else: verbosity = 0 # run transient rad_new, hydro_new = runNonlinearTransient(mesh=mesh, time_stepper=time_stepper, problem_type='rad_mat', dt_option='constant', dt_constant=dt, t_start=t_start, t_end=t_end, rad_BC=rad_BC, cross_sects=cross_sects, rad_IC=rad_IC, hydro_IC=hydro_IC, hydro_BC=hydro_BC, verbosity=verbosity, check_balance=True) # plot solutions if run standalone if __name__ == "__main__": plotTemperatures(mesh, rad_new.E, hydro_states=hydro_new, print_values=False)
def test_RadHydroMMS(self): # slope limiter: choices are: # none step minmod double-minmod superbee minbee vanleer slope_limiter = 'none' # number of elements n_elems = 50 # end time t_end = 0.1 # choice of solutions for hydro hydro_case = "linear" # constant linear exponential # choice of solutions for radiation rad_case = "zero" # zero constant sin # declare symbolic variables x, t, alpha, c = symbols('x t alpha c') # create solution for thermodynamic state and flow field if hydro_case == "constant": rho = sympify('4.0') u = sympify('1.2') E = sympify('10.0') elif hydro_case == "linear": rho = 1 + x - t u = sympify('1') E = 5 + 5 * (x - 0.5)**2 elif hydro_case == "exponential": rho = exp(x + t) + 5 u = exp(-x) * sin(t) - 1 E = 10 * exp(x + t) else: raise NotImplementedError("Invalid hydro test case") # create solution for radiation field if rad_case == "zero": psim = sympify('0') psip = sympify('0') elif rad_case == "constant": psim = 50 * c psip = 50 * c elif rad_case == "sin": rad_scale = 50 * c psim = rad_scale * 2 * t * sin(pi * (1 - x)) + 10 * c psip = rad_scale * t * sin(pi * x) + 10 * c else: raise NotImplementedError("Invalid radiation test case") # numeric values alpha_value = 0.01 cv_value = 1.0 gamma_value = 1.4 sig_s = 1.0 sig_a = 1.0 #sig_a = 0.0 # create MMS source functions rho_src, mom_src, E_src, psim_src, psip_src = createMMSSourceFunctionsRadHydro( rho=rho, u=u, E=E, psim=psim, psip=psip, sigma_s_value=sig_s, sigma_a_value=sig_a, gamma_value=gamma_value, cv_value=cv_value, alpha_value=alpha_value, display_equations=False) # create functions for exact solutions substitutions = dict() substitutions['alpha'] = alpha_value substitutions['c'] = GC.SPD_OF_LGT rho = rho.subs(substitutions) u = u.subs(substitutions) mom = rho * u E = E.subs(substitutions) psim = psim.subs(substitutions) psip = psip.subs(substitutions) rho_f = lambdify((symbols('x'), symbols('t')), rho, "numpy") u_f = lambdify((symbols('x'), symbols('t')), u, "numpy") mom_f = lambdify((symbols('x'), symbols('t')), mom, "numpy") E_f = lambdify((symbols('x'), symbols('t')), E, "numpy") psim_f = lambdify((symbols('x'), symbols('t')), psim, "numpy") psip_f = lambdify((symbols('x'), symbols('t')), psip, "numpy") # create uniform mesh width = 1.0 mesh = Mesh(n_elems, width) # compute radiation IC psi_IC = computeRadiationVector(psim_f, psip_f, mesh, t=0.0) rad_IC = Radiation(psi_IC) # compute radiation BC; assumes BC is independent of time psi_left = psip_f(x=0.0, t=0.0) psi_right = psim_f(x=width, t=0.0) #Create Radiation BC object rad_BC = RadBC(mesh, "dirichlet", psi_left=psi_left, psi_right=psi_right) # compute hydro IC hydro_IC = computeAnalyticHydroSolution(mesh, t=0.0, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # create hydro BC hydro_BC = HydroBC(bc_type='dirichlet', mesh=mesh, rho_BC=rho_f, mom_BC=mom_f, erg_BC=E_f) # create cross sections cross_sects = [(ConstantCrossSection(sig_s, sig_s + sig_a), ConstantCrossSection(sig_s, sig_s + sig_a)) for i in xrange(mesh.n_elems)] # if run standalone, then be verbose if __name__ == '__main__': verbosity = 2 else: verbosity = 0 # run the rad-hydro transient rad_new, hydro_new = runNonlinearTransient( mesh=mesh, problem_type='rad_hydro', dt_option='CFL', #dt_option = 'constant', CFL=0.5, #dt_constant = 0.002, slope_limiter=slope_limiter, time_stepper='BDF2', use_2_cycles=True, t_start=0.0, t_end=t_end, rad_BC=rad_BC, cross_sects=cross_sects, rad_IC=rad_IC, hydro_IC=hydro_IC, hydro_BC=hydro_BC, mom_src=mom_src, E_src=E_src, rho_src=rho_src, psim_src=psim_src, psip_src=psip_src, verbosity=verbosity, check_balance=False) # plot if __name__ == '__main__': # compute exact hydro solution hydro_exact = computeAnalyticHydroSolution(mesh, t=t_end, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # plot hydro solution plotHydroSolutions(mesh, hydro_new, x_exact=mesh.getCellCenters(), exact=hydro_exact) # compute exact radiation energy Er_exact_fn = 1. / GC.SPD_OF_LGT * (psim + psip) Er_exact = [] x = mesh.getCellCenters() for xi in x: substitutions = {'x': xi, 't': t_end} Er_exact.append(Er_exact_fn.subs(substitutions)) # plot radiation energy plotRadErg(mesh, rad_new.E, exact_Er=Er_exact)
def test_RadHydroMMS(self): # declare symbolic variables x, t, alpha, c, a, mu = symbols('x t alpha c a mu') # number of refinement cycles n_cycles = 5 # number of elements in first cycle n_elems = 20 # We will increase sigma and nondimensional C as we decrease the mesh # size to ensure we stay in the diffusion limit # numeric values gamma_value = 5./3. cv_value = 0.14472799784454 # run for a fixed amount of time t_end = 2.*pi sig_s = 0.0 #Want material speeed to be a small fraction of speed of light #and radiation to be small relative to kinetic energy P = 0.001 # a_r T_inf^4/(rho_inf*u_inf^2) #Arbitrary ratio of pressure to density alpha_value = 0.5 #Arbitrary mach number well below the sound speed. The choice of gamma and #the cv value, as well as C and P constrain all other material reference #parameters, but we are free to choose the material velocity below the sound #speed to ensure no shocks are formed M = 0.9 cfl_value = 0.6 #but 2 time steps, so really like a CFL of 0.3 dt = [] dx = [] err = [] for cycle in range(n_cycles): #Keep ratio of and sig_a*dx constant, staying in diffusion limit C = sig_a = 100000./20*n_elems # c/a_inf sig_t = sig_s + sig_a a_inf = GC.SPD_OF_LGT/C #These lines of code assume specified C_v T_inf = a_inf**2/(gamma_value*(gamma_value-1.)*cv_value) rho_inf = GC.RAD_CONSTANT*T_inf**4/(P*a_inf**2) #Specify rho_inf and determine T_inf and Cv_value rho_inf = 1.0 #If we don't choose a reference density, then the specific heat values get ridiculous T_inf = pow(rho_inf*P*a_inf**2/GC.RAD_CONSTANT,0.25) #to set T_inf based on rho_inf, cv_value = a_inf**2/(T_inf*gamma_value*(gamma_value-1.)) # to set c_v, if rho specified #Specify T_inf and solve for rho_inf and C_v value # T_inf = 1 # rho_inf = GC.RAD_CONSTANT*T_inf**4/(P*a_inf**2) # cv_value = a_inf**2/(T_inf*gamma_value*(gamma_value-1.)) # to set c_v, if rho specified #Same for all approachs p_inf = rho_inf*a_inf*a_inf print "The dimensionalization parameters are: " print " a_inf : ", a_inf print " T_inf : ", T_inf print " rho_inf : ", rho_inf print " p_inf : ", p_inf print " C_v : ", cv_value print " gamma : ", gamma_value # create solution for thermodynamic state and flow field rho = rho_inf*(2. + sin(x-t)) u = a_inf*M*0.5*(2. + cos(x-t)) p = alpha_value*p_inf*(2. + cos(x-t)) e = p/(rho*(gamma_value-1.)) E = 0.5*rho*u*u + rho*e # create solution for radiation field based on solution for F # that is the leading order diffusion limit solution T = e/cv_value Er = a*T**4 Fr = -1./(3.*sig_t)*c*diff(Er,x) + sympify('4./3.')*Er*u #Form psi+ and psi- from Fr and Er psip = (Er*c*mu + Fr)/(2.*mu) psim = (Er*c*mu - Fr)/(2.*mu) # create functions for exact solutions substitutions = dict() substitutions['alpha'] = alpha_value substitutions['c'] = GC.SPD_OF_LGT substitutions['a'] = GC.RAD_CONSTANT substitutions['mu'] = RU.mu["+"] rho = rho.subs(substitutions) u = u.subs(substitutions) mom = rho*u E = E.subs(substitutions) psim = psim.subs(substitutions) psip = psip.subs(substitutions) T = T.subs(substitutions) rho_f = lambdify((symbols('x'),symbols('t')), rho, "numpy") u_f = lambdify((symbols('x'),symbols('t')), u, "numpy") mom_f = lambdify((symbols('x'),symbols('t')), mom, "numpy") E_f = lambdify((symbols('x'),symbols('t')), E, "numpy") psim_f = lambdify((symbols('x'),symbols('t')), psim, "numpy") psip_f = lambdify((symbols('x'),symbols('t')), psip, "numpy") T_f = lambdify((symbols('x'),symbols('t')), T, "numpy") Er = Er.subs(substitutions) Er = lambdify((symbols('x'),symbols('t')), Er, "numpy") #For reference create lambda as ratio of aT^4/rho--u^2 to check #P_f = lambda x,t: GC.RAD_CONSTANT*T_f(x,t)**4/(rho_f(x,t)*u_f(x,t)**2) #dx = 1./100. #x = -1.*dx #t=0.2 #for i in range(100): # x += dx # print "ratio:", P_f(x,t) # create MMS source functions rho_src, mom_src, E_src, psim_src, psip_src = createMMSSourceFunctionsRadHydro( rho = rho, u = u, E = E, psim = psim, psip = psip, sigma_s_value = sig_s, sigma_a_value = sig_a, gamma_value = gamma_value, cv_value = cv_value, alpha_value = alpha_value, display_equations = True) # mesh width = 2.*pi mesh = Mesh(n_elems,width) # compute hydro IC for the sake of computing initial time step size hydro_IC = computeAnalyticHydroSolution(mesh,t=0.0, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # compute the initial time step size according to CFL conditon (actually # half). We will then decrease this time step by the same factor as DX each # cycle if cycle == 0: sound_speed = [sqrt(i.p * i.gamma / i.rho) + abs(i.u) for i in hydro_IC] dt_vals = [cfl_value*(mesh.elements[i].dx)/sound_speed[i] for i in xrange(len(hydro_IC))] dt_value = min(min(dt_vals),0.5) #don't take too big of time step print "initial dt_value", dt_value #Adjust the end time to be an exact increment of dt_values print "old t_end: ", t_end print "new t_end: ", t_end print "This cycle's dt value: ", dt_value # create uniform mesh mesh = Mesh(n_elems, width) dt.append(dt_value) dx.append(mesh.getElement(0).dx) # compute radiation IC psi_IC = computeRadiationVector(psim_f, psip_f, mesh, t=0.0) rad_IC = Radiation(psi_IC) # create rad BC object rad_BC = RadBC(mesh, 'periodic') # compute hydro IC hydro_IC = computeAnalyticHydroSolution(mesh,t=0.0, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # Dimensionless parameters. These are all evaluated at peaks of trig # functions, very hard coded print "---------------------------------------------" print " Diffusion limit info:" print "---------------------------------------------" print "Size in mfp of cell", mesh.getElement(0).dx*sig_t print "Ratio of radiation energy to kinetic", Er(0.75,0)/(rho_f(0.25,0)*u_f(0.0,0)**2), GC.RAD_CONSTANT*T_inf**4/(rho_inf*a_inf**2) print "Ratio of speed of light to material sound speed", GC.SPD_OF_LGT/u_f(0.0,0), GC.SPD_OF_LGT/(a_inf) print "---------------------------------------------" # create hydro BC hydro_BC = HydroBC(bc_type='periodic', mesh=mesh) # create cross sections cross_sects = [(ConstantCrossSection(sig_s, sig_s+sig_a), ConstantCrossSection(sig_s, sig_s+sig_a)) for i in xrange(mesh.n_elems)] # transient options t_start = 0.0 # if run standalone, then be verbose if __name__ == '__main__': verbosity = 2 else: verbosity = 0 #slope limiter limiter = 'double-minmod' # run the rad-hydro transient rad_new, hydro_new = runNonlinearTransient( mesh = mesh, problem_type = 'rad_hydro', dt_option = 'constant', dt_constant = dt_value, slope_limiter = limiter, time_stepper = 'BDF2', use_2_cycles = True, t_start = t_start, t_end = t_end, rad_BC = rad_BC, cross_sects = cross_sects, rad_IC = rad_IC, hydro_IC = hydro_IC, hydro_BC = hydro_BC, mom_src = mom_src, E_src = E_src, rho_src = rho_src, psim_src = psim_src, psip_src = psip_src, verbosity = verbosity, rho_f =rho_f, u_f = u_f, E_f = E_f, gamma_value = gamma_value, cv_value = cv_value, check_balance = True) # compute exact hydro solution hydro_exact = computeAnalyticHydroSolution(mesh, t=t_end, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) rad_exact = computeAnalyticRadSolution(mesh, t_end,psim=psim_f,psip=psip_f) #Compute error err.append(computeHydroL2Error(hydro_new, hydro_exact, rad_new, rad_exact )) n_elems *= 2 dt_value *= 0.5 # compute convergence rates rates_dx = computeHydroConvergenceRates(dx,err) rates_dt = computeHydroConvergenceRates(dt,err) # print convergence table if n_cycles > 1: printHydroConvergenceTable(dx,err,rates=rates_dx, dx_desc='dx',err_desc='$L_2$') printHydroConvergenceTable(dt,err,rates=rates_dt, dx_desc='dt',err_desc='$L_2$') # plot if __name__ == '__main__': # compute exact hydro solution hydro_exact = computeAnalyticHydroSolution(mesh, t=t_end, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # plot hydro solution plotHydroSolutions(mesh, hydro_new, x_exact=mesh.getCellCenters(),exact=hydro_exact) #plot exact and our E_r Er_exact_fn = 1./GC.SPD_OF_LGT*(psim + psip) Fr_exact_fn = (psip - psim)*RU.mu["+"] Er_exact = [] Fr_exact = [] psip_exact = [] psim_exact = [] x = mesh.getCellCenters() for xi in x: substitutions = {'x':xi, 't':t_end} Er_exact.append(Er_exact_fn.subs(substitutions)) Fr_exact.append(Fr_exact_fn.subs(substitutions)) psip_exact.append(psip_f(xi,t_end)) psim_exact.append(psim_f(xi,t_end)) plotRadErg(mesh, rad_new.E, Fr_edge=rad_new.F, exact_Er=Er_exact, exact_Fr = Fr_exact) plotS2Erg(mesh, rad_new.psim, rad_new.psip, exact_psim=psim_exact, exact_psip=psip_exact) plotTemperatures(mesh, rad_new.E, hydro_states=hydro_new, print_values=True) #Make a pickle to save the error tables from sys import argv pickname = "results/testRadHydroDiffMMS.pickle" if len(argv) > 2: if argv[1] == "-o": pickname = argv[2].strip() #Create dictionary of all the data big_dic = {"dx": dx} big_dic["dt"] = dt big_dic["Errors"] = err pickle.dump( big_dic, open( pickname, "w") )
def test_RadHydroMMS(self): # declare symbolic variables x, t, A, B, C, c, cv, gamma, mu, alpha = \ symbols('x t A B C c cv gamma mu alpha') #These constants, as well as cross sections and C_v, rho_ref #will set the material #and radiation to be small relative to kinetic energy Ctilde = 100. P = 0.1 #Arbitrary mach number well below the sound speed. The choice of gamma and #the cv value, as well as C and P constrain all other material reference #parameters, but we are free to choose the material velocity below the sound #speed to ensure no shocks are formed M = 0.9 cfl_value = 0.6 #but 2 time steps, so really like a CFL of 0.3 width = 2.0*math.pi # numeric values gamma_value = 5./3. cv_value = 0.14472799784454 # number of refinement cycles n_cycles = 5 # number of elements in first cycle n_elems = 40 # transient options t_start = 0.0 t_end = 2.0*math.pi/Ctilde # numeric values A_value = 1.0 B_value = 1.0 C_value = 1.0 alpha_value = 0.5 gamma_value = 5.0/3.0 sig_s_value = 0.0 sig_a_value = 1.0 # numeric values a_inf = GC.SPD_OF_LGT/Ctilde #T_inf = a_inf**2/(gamma_value*(gamma_value - 1.)*cv_value) #rho_inf = GC.RAD_CONSTANT*T_inf**4/(P*a_inf**2) rho_inf = 1.0 T_inf = pow(rho_inf*P*a_inf**2/GC.RAD_CONSTANT,0.25) #to set T_inf based on rho_inf, cv_value = a_inf**2/(T_inf*gamma_value*(gamma_value-1.)) # to set c_v, if rho specified p_inf = rho_inf*a_inf*a_inf Er_inf = GC.RAD_CONSTANT*T_inf**4 # MMS solutions rho = rho_inf*A*(sin(B*x-C*t)+2.) u = M*a_inf*1./(A*(sin(B*x-C*t)+2.)) p = p_inf*A*alpha*(sin(B*x-C*t)+2.) Er = alpha*(sin(B*x-Ctilde*C*t)+2.)*Er_inf Fr = alpha*(sin(B*x-Ctilde*C*t)+2.)*c*Er_inf #Er = 0.5*(sin(2*pi*x - 10.*t) + 2.)/c #Fr = 0.5*(sin(2*pi*x - 10.*t) + 2.) e = p/(rho*(gamma_value-1.)) E = 0.5*rho*u*u + rho*e print "The dimensionalization parameters are: " print " a_inf : ", a_inf print " T_inf : ", T_inf print " rho_inf : ", rho_inf print " p_inf : ", p_inf # derived solutions T = e/cv_value E = rho*(u*u/2 + e) psip = (Er*c + Fr/mu)/2 psim = (Er*c - Fr/mu)/2 # create list of substitutions substitutions = dict() substitutions['A'] = A_value substitutions['B'] = B_value substitutions['C'] = C_value substitutions['c'] = GC.SPD_OF_LGT substitutions['cv'] = cv_value substitutions['gamma'] = gamma_value substitutions['mu'] = RU.mu["+"] substitutions['alpha'] = alpha_value # make substitutions rho = rho.subs(substitutions) u = u.subs(substitutions) mom = rho*u E = E.subs(substitutions) psim = psim.subs(substitutions) psip = psip.subs(substitutions) # create MMS source functions rho_src, mom_src, E_src, psim_src, psip_src = createMMSSourceFunctionsRadHydro( rho = rho, u = u, E = E, psim = psim, psip = psip, sigma_s_value = sig_s_value, sigma_a_value = sig_a_value, gamma_value = gamma_value, cv_value = cv_value, alpha_value = alpha_value, display_equations = True) # create functions for exact solutions rho_f = lambdify((symbols('x'),symbols('t')), rho, "numpy") u_f = lambdify((symbols('x'),symbols('t')), u, "numpy") mom_f = lambdify((symbols('x'),symbols('t')), mom, "numpy") E_f = lambdify((symbols('x'),symbols('t')), E, "numpy") psim_f = lambdify((symbols('x'),symbols('t')), psim, "numpy") psip_f = lambdify((symbols('x'),symbols('t')), psip, "numpy") dt = [] dx = [] err = [] for cycle in range(n_cycles): # create uniform mesh mesh = Mesh(n_elems, width) # compute radiation IC psi_IC = computeRadiationVector(psim_f, psip_f, mesh, t=0.0) rad_IC = Radiation(psi_IC) # create rad BC object rad_BC = RadBC(mesh, 'periodic') # compute hydro IC hydro_IC = computeAnalyticHydroSolution(mesh,t=0.0, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # create hydro BC hydro_BC = HydroBC(bc_type='periodic', mesh=mesh) # create cross sections cross_sects = [(ConstantCrossSection(sig_s_value, sig_s_value+sig_a_value), ConstantCrossSection(sig_s_value, sig_s_value+sig_a_value)) for i in xrange(mesh.n_elems)] # compute the initial time step size according to CFL conditon (actually # half). We will then decrease this time step by the same factor as DX each # cycle if cycle == 0: sound_speed = [sqrt(i.p * i.gamma / i.rho) + abs(i.u) for i in hydro_IC] dt_vals = [cfl_value*(mesh.elements[i].dx)/sound_speed[i] for i in xrange(len(hydro_IC))] dt_value = min(dt_vals) print "dt_value for hydro: ", dt_value #Make sure not taking too large of step for radiation time scale period = 2.*math.pi/Ctilde dt_value = min(dt_value, period/8.) print "initial dt_value", dt_value #Adjust the end time to be an exact increment of dt_values print "t_end: ", t_end print "This cycle's dt value: ", dt_value dt.append(dt_value) dx.append(mesh.getElement(0).dx) # if run standalone, then be verbose if __name__ == '__main__': verbosity = 2 else: verbosity = 0 #slope limiter limiter = 'double-minmod' # run the rad-hydro transient rad_new, hydro_new = runNonlinearTransient( mesh = mesh, problem_type = 'rad_hydro', dt_option = 'constant', dt_constant = dt_value, slope_limiter = limiter, time_stepper = 'BDF2', use_2_cycles = True, t_start = t_start, t_end = t_end, rad_BC = rad_BC, cross_sects = cross_sects, rad_IC = rad_IC, hydro_IC = hydro_IC, hydro_BC = hydro_BC, mom_src = mom_src, E_src = E_src, rho_src = rho_src, psim_src = psim_src, psip_src = psip_src, verbosity = verbosity, rho_f = rho_f, u_f = u_f, E_f = E_f, gamma_value = gamma_value, cv_value = cv_value, check_balance = False) # compute exact hydro solution hydro_exact = computeAnalyticHydroSolution(mesh, t=t_end, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) rad_exact = computeAnalyticRadSolution(mesh, t_end,psim=psim_f,psip=psip_f) #Compute error err.append(computeHydroL2Error(hydro_new, hydro_exact, rad_new, rad_exact )) n_elems *= 2 dt_value *= 0.5 # compute convergence rates rates_dx = computeHydroConvergenceRates(dx,err) rates_dt = computeHydroConvergenceRates(dt,err) # print convergence table if n_cycles > 1: printHydroConvergenceTable(dx,err,rates=rates_dx, dx_desc='dx',err_desc='$L_2$') printHydroConvergenceTable(dt,err,rates=rates_dt, dx_desc='dt',err_desc='$L_2$') # plot if __name__ == '__main__': # compute exact hydro solution hydro_exact = computeAnalyticHydroSolution(mesh, t=t_end, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # plot hydro solution plotHydroSolutions(mesh, hydro_new, x_exact=mesh.getCellCenters(),exact=hydro_exact) #plot exact and our E_r Er_exact_fn = 1./GC.SPD_OF_LGT*(psim + psip) Fr_exact_fn = (psip - psim)*RU.mu["+"] Er_exact = [] Fr_exact = [] psip_exact = [] psim_exact = [] x = mesh.getCellCenters() for xi in x: substitutions = {'x':xi, 't':t_end} Er_exact.append(Er_exact_fn.subs(substitutions)) Fr_exact.append(Fr_exact_fn.subs(substitutions)) psip_exact.append(psip_f(xi,t_end)) psim_exact.append(psim_f(xi,t_end)) plotRadErg(mesh, rad_new.E, Fr_edge=rad_new.F, exact_Er=Er_exact, exact_Fr = Fr_exact) plotS2Erg(mesh, rad_new.psim, rad_new.psip, exact_psim=psim_exact, exact_psip=psip_exact) plotTemperatures(mesh, rad_new.E, hydro_states=hydro_new, print_values=True) #Make a pickle to save the error tables from sys import argv pickname = "results/testRadHydroStreamingMMSC100.pickle" if len(argv) > 2: if argv[1] == "-o": pickname = argv[2].strip() #Create dictionary of all the data big_dic = {"dx": dx} big_dic["dt"] = dt big_dic["Errors"] = err pickle.dump( big_dic, open( pickname, "w") )
def test_TRTBE(self): # create mesh n_elems = 200 mesh = Mesh(n_elems,1.) # time step size and transient start and end times dt = 0.001 t_start = 0.0 #t_end = 0.01 t_end = 0.1 # initialize temperature T_init = 0.05 T_l = 0.5 T_r = 0.05 # gamma constant gam = 1.4 # material 1 properties and IC sig_s1 = 0.0 sig_a1 = 0.2 c_v1 = convSpecHeatErgsEvToJksKev(1.E+12) rho1 = 0.01 e1 = T_init*c_v1 # material 2 properties and IC sig_s2 = 0.0 sig_a2 = 2000. c_v2 = c_v1 rho2 = 10. e2 = T_init*c_v2 # construct cross sections and hydro IC cross_sects = list() hydro_IC = list() for i in range(mesh.n_elems): if mesh.getElement(i).x_cent < 0.5: # material 1 cross_sects.append( (ConstantCrossSection(sig_s1, sig_s1+sig_a1), ConstantCrossSection(sig_s1, sig_s1+sig_a1)) ) hydro_IC.append( HydroState(u=0,rho=rho1,e=e1,spec_heat=c_v1,gamma=gam)) else: # material 2 cross_sects.append((ConstantCrossSection(sig_s2, sig_a2+sig_s2), ConstantCrossSection(sig_s2, sig_a2+sig_s2))) hydro_IC.append( HydroState(u=0,rho=rho2,e=e2,spec_heat=c_v2,gamma=gam)) # create hydro BC hydro_BC = HydroBC(bc_type='reflective', mesh=mesh) # initialize radiation to equilibrium solution psi_left = computeEquivIntensity(T_l) psi_right = computeEquivIntensity(T_r) rad_IC = Radiation([psi_right for i in range(n_elems*4)]) rad_BC = RadBC(mesh, "dirichlet", psi_left=psi_left, psi_right=psi_right) # time-stepper time_stepper = "BDF2" # if run standalone, then be verbose if __name__ == '__main__': verbosity = 2 else: verbosity = 0 # run transient rad_new, hydro_new = runNonlinearTransient( mesh = mesh, time_stepper = time_stepper, problem_type = 'rad_mat', dt_option = 'constant', dt_constant = dt, t_start = t_start, t_end = t_end, rad_BC = rad_BC, cross_sects = cross_sects, rad_IC = rad_IC, hydro_IC = hydro_IC, hydro_BC = hydro_BC, verbosity = verbosity, check_balance = True) # plot solutions if run standalone if __name__ == "__main__": plotTemperatures(mesh, rad_new.E, hydro_states=hydro_new, print_values=False)
def test_TRTBE(self): # create mesh n_elems = 200 mesh = Mesh(n_elems, 2.) # time step size and transient start and end times dt = 0.001 t_start = 0. t_end = 5.0 # initialize temperature T_init = 2.5E-05 T_l = 0.150 T_r = T_init # gamma constant gam = 1.4 # material 1 properties and IC sig_s1 = 0.0 sig_a1 = 0.001 c_v1 = convSpecHeatErgsEvToJksKev(1.3784E+11) rho1 = 1.0 e1 = T_init * c_v1 # construct cross sections and hydro IC cross_sects = list() hydro_IC = list() for i in range(mesh.n_elems): hydro_IC.append( HydroState(u=0, rho=rho1, e=e1, spec_heat=c_v1, gamma=gam)) cross_sects.append((InvCubedCrossX(sig_s1, hydro_IC[-1], scale_coeff=0.001), InvCubedCrossX(sig_s1, hydro_IC[-1], scale_coeff=0.001))) # create hydro BC hydro_BC = HydroBC(bc_type='reflective', mesh=mesh) # initialize radiation to equilibrium solution psi_left = computeEquivIntensity(T_l) psi_right = computeEquivIntensity(T_r) rad_IC = Radiation([psi_right for i in range(n_elems * 4)]) # time-stepper time_stepper = "CN" # if run standalone, then be verbose if __name__ == '__main__': verbosity = 2 else: verbosity = 0 # run transient rad_new, hydro_new = runNonlinearTransient(mesh=mesh, time_stepper=time_stepper, problem_type='rad_mat', dt_option='constant', dt_constant=dt, t_start=t_start, t_end=t_end, psi_left=psi_left, psi_right=psi_right, cross_sects=cross_sects, rad_IC=rad_IC, hydro_IC=hydro_IC, hydro_BC=hydro_BC, verbosity=verbosity, check_balance=True) # plot solutions if run standalone if __name__ == "__main__": plotTemperatures(mesh, rad_new.E, hydro_states=hydro_new, print_values=True)
def test_RadHydroMMS(self): # declare symbolic variables x, t, alpha, c = symbols('x t alpha c') #Cycles for time convergence n_cycles = 3 # numeric values alpha_value = 0.01 cv_value = 1.0 gamma_value = 1.4 sig_s = 1.0 sig_a = 1.0 sig_t = sig_s + sig_a # create solution for thermodynamic state and flow field rho = 2. + sin(2*pi*x-t) u = 2. + cos(2*pi*x-t) p = 0.5*(2. + cos(2*pi*x-t)) e = p/(rho*(gamma_value-1.)) E = 0.5*rho*u*u + rho*e rho = sympify('2')*sin(t/4.)+2. u = sympify('3')*sin(t/4.)+3. E = sympify('10')*sin(t/4.)+10. # create solution for radiation field based on solution for F # that is the leading order diffusion limit solution a = GC.RAD_CONSTANT c = GC.SPD_OF_LGT mu = RU.mu["+"] #Equilibrium diffusion solution Er = (2.+cos(2*pi*x-t)) Fr = (2.+cos(2*pi*x-t))*c psip = (Er*c*mu + Fr)/(2.*mu) psim = (Er*c*mu - Fr)/(2.*mu) psip = sympify('10')*c+1*sin(t/4.) psim = sympify('10')*c+1*cos(t/4.) #Form psi+ and psi- from Fr and Er #psip = sympify('5.')*c #psim = sympify('5.')*c # create MMS source functions rho_src, mom_src, E_src, psim_src, psip_src = createMMSSourceFunctionsRadHydro( rho = rho, u = u, E = E, psim = psim, psip = psip, sigma_s_value = sig_s, sigma_a_value = sig_a, gamma_value = gamma_value, cv_value = cv_value, alpha_value = alpha_value, display_equations = True) # create functions for exact solutions substitutions = dict() substitutions['alpha'] = alpha_value substitutions['c'] = GC.SPD_OF_LGT rho = rho.subs(substitutions) u = u.subs(substitutions) mom = rho*u E = E.subs(substitutions) psim = psim.subs(substitutions) psip = psip.subs(substitutions) rho_f = lambdify((symbols('x'),symbols('t')), rho, "numpy") u_f = lambdify((symbols('x'),symbols('t')), u, "numpy") mom_f = lambdify((symbols('x'),symbols('t')), mom, "numpy") E_f = lambdify((symbols('x'),symbols('t')), E, "numpy") psim_f = lambdify((symbols('x'),symbols('t')), psim, "numpy") psip_f = lambdify((symbols('x'),symbols('t')), psip, "numpy") dt_value = 0.0001 dt = [] err = [] #Loop over cycles for time convergence for cycle in range(n_cycles): # create uniform mesh n_elems = 50 width = 1.0 mesh = Mesh(n_elems, width) #Store dt.append(dt_value) # compute radiation IC psi_IC = computeRadiationVector(psim_f, psip_f, mesh, t=0.0) rad_IC = Radiation(psi_IC) # create rad BC object rad_BC = RadBC(mesh, 'periodic') # compute hydro IC hydro_IC = computeAnalyticHydroSolution(mesh,t=0.0, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # create hydro BC hydro_BC = HydroBC(bc_type='periodic', mesh=mesh) # create cross sections cross_sects = [(ConstantCrossSection(sig_s, sig_s+sig_a), ConstantCrossSection(sig_s, sig_s+sig_a)) for i in xrange(mesh.n_elems)] # transient options t_start = 0.0 t_end = 0.001 # if run standalone, then be verbose if __name__ == '__main__': verbosity = 2 else: verbosity = 0 #slope limiter limiter = 'none' # run the rad-hydro transient rad_new, hydro_new = runNonlinearTransient( mesh = mesh, problem_type = 'rad_hydro', dt_option = 'constant', dt_constant = dt_value, slope_limiter = limiter, use_2_cycles = True, t_start = t_start, t_end = t_end, rad_BC = rad_BC, cross_sects = cross_sects, rad_IC = rad_IC, hydro_IC = hydro_IC, hydro_BC = hydro_BC, mom_src = mom_src, E_src = E_src, rho_src = rho_src, psim_src = psim_src, psip_src = psip_src, verbosity = verbosity, rho_f =rho_f, u_f = u_f, E_f = E_f, gamma_value = gamma_value, cv_value = cv_value, check_balance = True) # compute exact hydro solution hydro_exact = computeAnalyticHydroSolution(mesh, t=t_end, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) #Compute error err.append(computeHydroL2Error(hydro_new, hydro_exact)) dt_value /= 2. # compute convergence rates rates = computeHydroConvergenceRates(dt,err) # plot if __name__ == '__main__': # plot radiation solution # compute exact hydro solution hydro_exact = computeAnalyticHydroSolution(mesh, t=t_end, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # print convergence table if n_cycles > 1: printHydroConvergenceTable(dt,err,rates=rates, dx_desc='dt',err_desc='L2') # plot hydro solution plotHydroSolutions(mesh, hydro_new, x_exact=mesh.getCellCenters(), exact=hydro_exact) #plot exact and our E_r Er_exact_fn = 1./GC.SPD_OF_LGT*(psim + psip) Fr_exact_fn = (psip - psim)*RU.mu["+"] Er_exact = [] Fr_exact = [] psip_exact = [] psim_exact = [] x = mesh.getCellCenters() for xi in x: substitutions = {'x':xi, 't':t_end} Er_exact.append(Er_exact_fn.subs(substitutions)) Fr_exact.append(Fr_exact_fn.subs(substitutions)) psip_exact.append(psip_f(xi,t_end)) psim_exact.append(psim_f(xi,t_end)) plotRadErg(mesh, rad_new.E, Fr_edge=rad_new.F, exact_Er=Er_exact, exact_Fr = Fr_exact) plotRadErg(mesh, rad_new.psim, rad_new.psip, exact_Er=psip_exact, exact_Fr=psim_exact)
def test_HydroMMS(self): # slope limiter: choices are: # none step minmod double-minmod superbee minbee vanleer slope_limiter = 'none' # number of elements in first cycle n_elems = 50 # number of refinement cycles n_cycles = 1 # end time t_end = 0.1 # choice of solutions for hydro hydro_case = "linear" # constant linear exponential # declare symbolic variables x, t, alpha = symbols('x t alpha') # create solution for thermodynamic state and flow field if hydro_case == "constant": rho = sympify('4.0') u = sympify('1.2') E = sympify('10.0') elif hydro_case == "linear": rho = 1 + x - t u = sympify('1') E = 5 + 5*(x - 0.5)**2 elif hydro_case == "exponential": rho = exp(x+t)+5 u = exp(-x)*sin(t) - 1 E = 10*exp(x+t) else: raise NotImplementedError("Invalid hydro test case") # create solution for radiation field psim = sympify('0') psip = sympify('0') # numeric values alpha_value = 0.01 cv_value = 1.0 gamma_value = 1.4 sig_s = 1.0 sig_a = 0.0 # create MMS source functions rho_src, mom_src, E_src, psim_src, psip_src = createMMSSourceFunctionsHydroOnly( rho = rho, u = u, E = E, gamma_value = gamma_value, cv_value = cv_value, alpha_value = alpha_value, display_equations = False) # create functions for exact solutions substitutions = dict() substitutions['alpha'] = alpha_value rho = rho.subs(substitutions) u = u.subs(substitutions) mom = rho*u E = E.subs(substitutions) rho_f = lambdify((symbols('x'),symbols('t')), rho, "numpy") u_f = lambdify((symbols('x'),symbols('t')), u, "numpy") mom_f = lambdify((symbols('x'),symbols('t')), mom, "numpy") E_f = lambdify((symbols('x'),symbols('t')), E, "numpy") psim_f = lambdify((symbols('x'),symbols('t')), psim, "numpy") psip_f = lambdify((symbols('x'),symbols('t')), psip, "numpy") # spatial and temporal domains width = 1.0 # initialize lists for mesh size and L1 error for each cycle max_dx = list() err = list() # loop over refinement cycles for cycle in xrange(n_cycles): if __name__ == '__main__': print("\nCycle %d of %d: n_elems = %d" % (cycle+1,n_cycles,n_elems)) # create uniform mesh mesh = Mesh(n_elems, width) # append max dx for this cycle to list max_dx.append(mesh.max_dx) # compute radiation IC psi_IC = computeRadiationVector(psim_f, psip_f, mesh, t=0.0) rad_IC = Radiation(psi_IC) #Make rad BC object with vacuum for hydro only rad_BC = RadBC(mesh, "vacuum") # compute hydro IC hydro_IC = computeAnalyticHydroSolution(mesh, t=0.0, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # create hydro BC hydro_BC = HydroBC(bc_type='dirichlet', mesh=mesh, rho_BC=rho_f, mom_BC=mom_f, erg_BC=E_f) # create cross sections cross_sects = [(ConstantCrossSection(sig_s, sig_s+sig_a), ConstantCrossSection(sig_s, sig_s+sig_a)) for i in xrange(mesh.n_elems)] # if run standalone, then be verbose if __name__ == '__main__': if n_cycles == 1: verbosity = 2 else: verbosity = 1 else: verbosity = 0 # run the rad-hydro transient rad_new, hydro_new = runNonlinearTransient( mesh = mesh, problem_type = 'rad_hydro', dt_option = 'CFL', CFL = 0.5, slope_limiter = slope_limiter, time_stepper = 'BDF2', use_2_cycles = True, t_start = 0.0, t_end = t_end, rad_BC = rad_BC, hydro_BC = hydro_BC, cross_sects = cross_sects, rad_IC = rad_IC, hydro_IC = hydro_IC, mom_src = mom_src, E_src = E_src, psim_src = psim_src, psip_src = psip_src, rho_src = rho_src, verbosity = verbosity, check_balance = False, rho_f = rho_f, u_f = u_f, E_f = E_f, gamma_value = gamma_value, cv_value = cv_value ) # compute exact hydro solution hydro_exact = computeAnalyticHydroSolution(mesh, t=t_end, rho=rho_f, u=u_f, E=E_f, cv=cv_value, gamma=gamma_value) # compute error err.append(computeHydroL2Error(hydro_new, hydro_exact)) # double number of elements for next cycle n_elems *= 2 # compute convergence rates rates = computeHydroConvergenceRates(max_dx,err) # print convergence table and plot if __name__ == '__main__': # print convergence table if n_cycles > 1: printHydroConvergenceTable(max_dx,err,rates=rates, dx_desc='dx',err_desc='L2') # plot hydro solution plotHydroSolutions(mesh, hydro_new, x_exact=mesh.getCellCenters(), exact=hydro_exact)
def test_RadHydroShock(self): # create uniform mesh n_elems = 500 width = 0.04 x_start = -0.02 mesh_center = x_start + 0.5 * width mesh = Mesh(n_elems, width, x_start=x_start) # slope limiter slope_limiter = "double-minmod" # gamma constant gam = 5.0 / 3.0 # material 1 and 2 properties; T_ref = 0.1 #keV reference unshocked, upstream, ambient, equilibrium sig_a1 = 577.35 sig_s1 = 0.0 c_v1 = 0.14472799784454 sig_a2 = sig_a1 sig_s2 = sig_s1 c_v2 = c_v1 #Read in Jim's nondimensional results to set preshock and postshock dimensional mach_number = "1.2" #Choices are 2.0, 1.2, 3.0, 5.0 filename = 'analytic_shock_solutions/data_for_M%s.pickle' % mach_number f = open(filename, 'r') data = pickle.load(f) f.close() #compute scalings based on an assumed density and reference temperature dp = getDimensParams(T_ref=T_ref, rho_ref=1.0, C_v=c_v1, gamma=gam) print data #Scale non-dimensional values into dimensional results rho1 = data['Density'][0] * dp['rho'] u1 = data['Speed'][0] * dp['a'] #velocity times reference sound speed Erad1 = data['Er'][0] * dp['Er'] T1 = data['Tm'][0] * dp["Tm"] e1 = T1 * c_v1 E1 = rho1 * (e1 + 0.5 * u1 * u1) # material 2 IC rho2 = data['Density'][-1] * dp['rho'] u2 = data['Speed'][-1] * dp['a'] #velocity times reference sound speed Erad2 = data['Er'][-1] * dp['Er'] T2 = data['Tm'][-1] * T_ref e2 = T2 * c_v2 E2 = rho2 * (e2 + 0.5 * u2 * u2) print r"$\rho$ & %0.8e & %0.8e & g cm$^{-3}$ \\" % (rho1, rho2) print r"$u$ & %0.8e & %0.8e & cm sh$^{-1}$ \\" % (u1, u2) print r"$T$ & %0.8e & %0.8e & keV \\" % (T1, T2) print r"$E$ & %0.8e & %0.8e & Jks cm$^{-3}$\\" % (E1, E2) print r"$E_r$ & %0.8e & %0.8e & Jks cm$^{-3}$ \\" % (Erad1, Erad2) print r"$F_r$ & %0.8e & %0.8e & Jks cm$^{-2}$ s$^{-1}$ \\" % (0.0, 0.0) print r"vel", u1, "&", u2 print "Temperature", T1, "&", T2 print "momentum", rho1 * u1, "&", rho2 * u2 print "E", E1, "&", E2 print "E_r", Erad1, "&", Erad2 print sig_a1, sig_s1 exit() # material 1 IC # final time t_end = 0.8 # temperature plot filename test_filename = "radshock_mach_" + re.search( "M(\d\.\d)", filename).group(1) + ".pdf" # compute radiation BC; assumes BC is independent of time c = GC.SPD_OF_LGT psi_left = 0.5 * c * Erad1 psi_right = 0.5 * c * Erad2 #Create BC object rad_BC = RadBC(mesh, "dirichlet", psi_left=psi_left, psi_right=psi_right) # construct cross sections and hydro IC cross_sects = list() hydro_IC = list() psi_IC = list() for i in range(mesh.n_elems): if mesh.getElement(i).x_cent < mesh_center: # material 1 cross_sects.append( (ConstantCrossSection(sig_s1, sig_s1 + sig_a1), ConstantCrossSection(sig_s1, sig_s1 + sig_a1))) hydro_IC.append( HydroState(u=u1, rho=rho1, e=e1, spec_heat=c_v1, gamma=gam)) psi_IC += [psi_left for dof in range(4)] else: # material 2 cross_sects.append( (ConstantCrossSection(sig_s2, sig_a2 + sig_s2), ConstantCrossSection(sig_s2, sig_a2 + sig_s2))) hydro_IC.append( HydroState(u=u2, rho=rho2, e=e2, spec_heat=c_v2, gamma=gam)) psi_IC += [psi_right for dof in range(4)] #Convert pickle data to dimensional form data['Density'] *= dp['rho'] data['Speed'] *= dp['a'] data['Er'] *= dp['Er'] data['Tm'] *= dp['Tm'] x_anal = data['x'] #If desired initialize the solutions to analytic result (ish) analytic_IC = False if analytic_IC: hydro_IC = list() psi_IC = list() for i in range(mesh.n_elems): #Determine which analytic x is closest to cell center xcent = mesh.getElement(i).x_cent min_dist = 9001. idx = -1 for j in range(len(x_anal)): if abs(xcent - x_anal[j]) < min_dist: min_dist = abs(xcent - x_anal[j]) idx = j #Create state based on these values, noting that the pickle has already #been dimensionalized rho1 = data['Density'][idx] u1 = data['Speed'][idx] #velocity times reference sound speed Erad1 = data['Er'][idx] T1 = data['Tm'][idx] e1 = T1 * c_v1 E1 = rho1 * (e1 + 0.5 * u1 * u1) psi_left = 0.5 * c * Erad1 hydro_IC.append( HydroState(u=u1, rho=rho1, e=e1, spec_heat=c_v1, gamma=gam)) psi_IC += [psi_left for dof in range(4)] #Smooth out the middle solution optionally, shouldnt need this n_smoothed = 0 state_l = hydro_IC[0] state_r = hydro_IC[-1] rho_l = state_l.rho rho_r = state_r.rho drho = rho_r - rho_l u_l = state_l.u u_r = state_r.u du = u_r - u_l e_l = state_l.e e_r = state_r.e de = e_r - e_l print "p", state_l.p, state_r.p print "mach number", state_l.u / state_l.getSoundSpeed( ), state_r.u / state_r.getSoundSpeed() #Scale idx = 0 if n_smoothed > 0: for i in range(mesh.n_elems / 2 - n_smoothed / 2 - 1, mesh.n_elems / 2 + n_smoothed / 2): rho = rho_l + drho * idx / n_smoothed u = rho_l * u_l / rho e = e_l + de * idx / n_smoothed idx += 1 E = 0.5 * rho * u * u + rho * e hydro_IC[i].updateState(rho, rho * u, E) # plot hydro initial conditions plotHydroSolutions(mesh, hydro_IC) rad_IC = Radiation(psi_IC) # create hydro BC hydro_BC = HydroBC(bc_type='fixed', mesh=mesh, state_L=state_l, state_R=state_r) #Forcing to reflective? Maybe this is the problem hydro_BC = HydroBC(mesh=mesh, bc_type='reflective') # transient options t_start = 0.0 # if run standalone, then be verbose if __name__ == '__main__': verbosity = 2 else: verbosity = 0 # run the rad-hydro transient rad_new, hydro_new = runNonlinearTransient(mesh=mesh, problem_type='rad_hydro', dt_option='CFL', CFL=0.6, use_2_cycles=True, t_start=t_start, t_end=t_end, rad_BC=rad_BC, cross_sects=cross_sects, rad_IC=rad_IC, hydro_IC=hydro_IC, hydro_BC=hydro_BC, verbosity=verbosity, slope_limiter=slope_limiter, check_balance=False) # plot if __name__ == '__main__': # compute exact hydro solution hydro_exact = None # plot hydro solution plotHydroSolutions(mesh, hydro_new, exact=hydro_exact, pickle_dic=data) # plot material and radiation temperatures Tr_exact, Tm_exact = plotTemperatures(mesh, rad_new.E, hydro_states=hydro_new, print_values=True, save=True, filename=test_filename, pickle_dic=data) # plot angular fluxes plotS2Erg(mesh, rad_new.psim, rad_new.psip) #Make a pickle to save the error tables pickname = "results/testJimsShock_M%s_%ielems.pickle" % ( mach_number, n_elems) #Create dictionary of all the data big_dic = {} big_dic["hydro"] = hydro_new big_dic["hydro_exact"] = hydro_exact big_dic["rad"] = rad_new big_dic["Tr_exact"] = Tr_exact big_dic["Tm_exact"] = Tm_exact pickle.dump(big_dic, open(pickname, "w"))
def test_RadHydroShock(self): # create uniform mesh n_elems = 500 width = 0.04 x_start = -0.02 mesh_center = x_start + 0.5*width mesh = Mesh(n_elems, width, x_start=x_start) # slope limiter slope_limiter = "double-minmod" # gamma constant gam = 5.0/3.0 # material 1 and 2 properties; T_ref = 0.1 #keV reference unshocked, upstream, ambient, equilibrium sig_a1 = 577.35 sig_s1 = 0.0 c_v1 = 0.14472799784454 sig_a2 = sig_a1 sig_s2 = sig_s1 c_v2 = c_v1 #Read in Jim's nondimensional results to set preshock and postshock dimensional mach_number = "1.2" #Choices are 2.0, 1.2, 3.0, 5.0 filename = 'analytic_shock_solutions/data_for_M%s.pickle' % mach_number f = open(filename,'r') data = pickle.load(f) f.close() #compute scalings based on an assumed density and reference temperature dp =getDimensParams(T_ref=T_ref, rho_ref=1.0, C_v=c_v1, gamma=gam) print data #Scale non-dimensional values into dimensional results rho1 = data['Density'][0]*dp['rho'] u1 = data['Speed'][0]*dp['a'] #velocity times reference sound speed Erad1 = data['Er'][0]*dp['Er'] T1 = data['Tm'][0]*dp["Tm"] e1 = T1*c_v1 E1 = rho1*(e1 + 0.5*u1*u1) # material 2 IC rho2 = data['Density'][-1]*dp['rho'] u2 = data['Speed'][-1]*dp['a'] #velocity times reference sound speed Erad2 = data['Er'][-1]*dp['Er'] T2 = data['Tm'][-1]*T_ref e2 = T2*c_v2 E2 = rho2*(e2 + 0.5*u2*u2) print r"$\rho$ & %0.8e & %0.8e & g cm$^{-3}$ \\" % (rho1, rho2) print r"$u$ & %0.8e & %0.8e & cm sh$^{-1}$ \\" % (u1, u2) print r"$T$ & %0.8e & %0.8e & keV \\" % (T1,T2) print r"$E$ & %0.8e & %0.8e & Jks cm$^{-3}$\\" % (E1,E2) print r"$E_r$ & %0.8e & %0.8e & Jks cm$^{-3}$ \\" % (Erad1, Erad2) print r"$F_r$ & %0.8e & %0.8e & Jks cm$^{-2}$ s$^{-1}$ \\" %(0.0,0.0) print r"vel", u1, "&", u2 print "Temperature", T1,"&", T2 print "momentum", rho1*u1,"&", rho2*u2 print "E",E1,"&", E2 print "E_r",Erad1, "&", Erad2 print sig_a1, sig_s1 exit() # material 1 IC # final time t_end = 0.8 # temperature plot filename test_filename = "radshock_mach_"+re.search("M(\d\.\d)",filename).group(1)+".pdf" # compute radiation BC; assumes BC is independent of time c = GC.SPD_OF_LGT psi_left = 0.5*c*Erad1 psi_right = 0.5*c*Erad2 #Create BC object rad_BC = RadBC(mesh, "dirichlet", psi_left=psi_left, psi_right=psi_right) # construct cross sections and hydro IC cross_sects = list() hydro_IC = list() psi_IC = list() for i in range(mesh.n_elems): if mesh.getElement(i).x_cent < mesh_center: # material 1 cross_sects.append( (ConstantCrossSection(sig_s1, sig_s1+sig_a1), ConstantCrossSection(sig_s1, sig_s1+sig_a1)) ) hydro_IC.append( HydroState(u=u1,rho=rho1,e=e1,spec_heat=c_v1,gamma=gam)) psi_IC += [psi_left for dof in range(4)] else: # material 2 cross_sects.append((ConstantCrossSection(sig_s2, sig_a2+sig_s2), ConstantCrossSection(sig_s2, sig_a2+sig_s2))) hydro_IC.append( HydroState(u=u2,rho=rho2,e=e2,spec_heat=c_v2,gamma=gam)) psi_IC += [psi_right for dof in range(4)] #Convert pickle data to dimensional form data['Density'] *= dp['rho'] data['Speed'] *= dp['a'] data['Er'] *= dp['Er'] data['Tm'] *= dp['Tm'] x_anal = data['x'] #If desired initialize the solutions to analytic result (ish) analytic_IC = False if analytic_IC: hydro_IC = list() psi_IC = list() for i in range(mesh.n_elems): #Determine which analytic x is closest to cell center xcent = mesh.getElement(i).x_cent min_dist = 9001. idx = -1 for j in range(len(x_anal)): if abs(xcent - x_anal[j]) < min_dist: min_dist = abs(xcent - x_anal[j]) idx = j #Create state based on these values, noting that the pickle has already #been dimensionalized rho1 = data['Density'][idx] u1 = data['Speed'][idx] #velocity times reference sound speed Erad1 = data['Er'][idx] T1 = data['Tm'][idx] e1 = T1*c_v1 E1 = rho1*(e1 + 0.5*u1*u1) psi_left = 0.5*c*Erad1 hydro_IC.append( HydroState(u=u1,rho=rho1,e=e1,spec_heat=c_v1,gamma=gam)) psi_IC += [psi_left for dof in range(4)] #Smooth out the middle solution optionally, shouldnt need this n_smoothed = 0 state_l = hydro_IC[0] state_r = hydro_IC[-1] rho_l = state_l.rho rho_r = state_r.rho drho = rho_r - rho_l u_l = state_l.u u_r = state_r.u du = u_r - u_l e_l = state_l.e e_r = state_r.e de = e_r-e_l print "p", state_l.p, state_r.p print "mach number", state_l.u/state_l.getSoundSpeed(), state_r.u/state_r.getSoundSpeed() #Scale idx = 0 if n_smoothed > 0: for i in range(mesh.n_elems/2-n_smoothed/2-1,mesh.n_elems/2+n_smoothed/2): rho = rho_l + drho*idx/n_smoothed u = rho_l*u_l/rho e = e_l + de*idx/n_smoothed idx+=1 E = 0.5*rho*u*u + rho*e hydro_IC[i].updateState(rho, rho*u, E) # plot hydro initial conditions plotHydroSolutions(mesh, hydro_IC) rad_IC = Radiation(psi_IC) # create hydro BC hydro_BC = HydroBC(bc_type='fixed', mesh=mesh, state_L = state_l, state_R = state_r) #Forcing to reflective? Maybe this is the problem hydro_BC = HydroBC(mesh=mesh,bc_type='reflective') # transient options t_start = 0.0 # if run standalone, then be verbose if __name__ == '__main__': verbosity = 2 else: verbosity = 0 # run the rad-hydro transient rad_new, hydro_new = runNonlinearTransient( mesh = mesh, problem_type = 'rad_hydro', dt_option = 'CFL', CFL = 0.6, use_2_cycles = True, t_start = t_start, t_end = t_end, rad_BC = rad_BC, cross_sects = cross_sects, rad_IC = rad_IC, hydro_IC = hydro_IC, hydro_BC = hydro_BC, verbosity = verbosity, slope_limiter = slope_limiter, check_balance=False) # plot if __name__ == '__main__': # compute exact hydro solution hydro_exact = None # plot hydro solution plotHydroSolutions(mesh, hydro_new, exact=hydro_exact, pickle_dic=data) # plot material and radiation temperatures Tr_exact, Tm_exact = plotTemperatures(mesh, rad_new.E, hydro_states=hydro_new, print_values=True, save=True, filename=test_filename, pickle_dic=data) # plot angular fluxes plotS2Erg(mesh, rad_new.psim, rad_new.psip) #Make a pickle to save the error tables pickname = "results/testJimsShock_M%s_%ielems.pickle" % (mach_number,n_elems) #Create dictionary of all the data big_dic = { } big_dic["hydro"] = hydro_new big_dic["hydro_exact"] = hydro_exact big_dic["rad"] = rad_new big_dic["Tr_exact"] = Tr_exact big_dic["Tm_exact"] = Tm_exact pickle.dump( big_dic, open( pickname, "w") )