Пример #1
0
    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)
Пример #2
0
    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)
Пример #3
0
    def runConvergenceTest(self, time_stepper):

        # transient options
        dt_start = 0.01  # time step size
        t_start = 0.0  # start time
        t_end = 0.1  # end time

        # constant cross section values
        sig_s = 1.0
        sig_a = 2.0

        # boundary fluxes
        psi_left = 0.0
        psi_right = 0.0

        # compute exact scalar flux solution
        def exactScalarFlux(x):
            return t_end * sin(pi * x) + 2.0 * t_end * sin(pi * (1.0 - x))

        # create symbolic expressions for MMS solution
        x, t, alpha = sym.symbols('x t alpha')
        psim = 2 * t * sym.sin(sym.pi * (1 - x))
        psip = t * sym.sin(sym.pi * x)

        # number of elements
        n_elems = 10

        # number of refinement cycles
        n_cycles = 5

        # initialize lists for mesh size and L1 error for each cycle
        max_dx = list()
        L1_error = list()

        # print header
        if __name__ == '__main__':
            print('\n%s:' % time_stepper)

        # 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, 1.0)
            # append max dx for this cycle to list
            max_dx.append(mesh.max_dx)

            # radiation BC
            rad_BC = RadBC(mesh,
                           "dirichlet",
                           psi_left=psi_left,
                           psi_right=psi_right)

            # compute uniform 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)]

            # create source function handles
            psim_src, psip_src = createMMSSourceFunctionsRadOnly(
                psim=psim, psip=psip, sigma_s_value=sig_s, sigma_a_value=sig_a)

            # IC
            n_dofs = mesh.n_elems * 4
            rad_IC = Radiation(np.zeros(n_dofs))

            # if run standalone, then be verbose
            if __name__ == '__main__':
                verbosity = 2
            else:
                verbosity = 0

            # run transient
            rad_new = runLinearTransient(mesh=mesh,
                                         time_stepper=time_stepper,
                                         dt_option='constant',
                                         dt_constant=dt_start,
                                         t_start=t_start,
                                         t_end=t_end,
                                         rad_BC=rad_BC,
                                         cross_sects=cross_sects,
                                         rad_IC=rad_IC,
                                         psim_src=psim_src,
                                         psip_src=psip_src,
                                         verbosity=verbosity)

            # compute L1 error
            L1_error.append(\
               computeL1ErrorLD(mesh, rad_new.phi, exactScalarFlux))

            # double number of elements for next cycle
            n_elems *= 2

        # compute convergence rates
        rates = computeConvergenceRates(max_dx, L1_error)

        # print convergence table if not being run in suite
        if __name__ == '__main__':
            printConvergenceTable(max_dx,
                                  L1_error,
                                  rates=rates,
                                  dx_desc='dx',
                                  err_desc='L1')

        # check that final rate is approximately 2nd order
        self.assert_(rates[n_cycles - 2] > 1.95)
Пример #4
0
    def test_RadTransientBDF2(self):

        # create uniform mesh
        mesh = Mesh(50, 5.0)

        # compute uniform cross sections
        sig_s = 1.0
        sig_a = 2.0
        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
        dt = 0.1  # time step size
        t_start = 0.0  # start time
        t_end = 10.0  # end time
        time_stepper = 'BDF2'  # time-stepper

        # boundary fluxes
        psi_left = 2.5
        psi_right = 2.2
        rad_BC = RadBC(mesh,
                       "dirichlet",
                       psi_left=psi_left,
                       psi_right=psi_right)

        # create source function handles
        psim_src = lambda x, t: 2.4
        psip_src = lambda x, t: 2.4

        # IC
        n_dofs = mesh.n_elems * 4
        rad_IC = Radiation(np.zeros(n_dofs))

        # if run standalone, then be verbose
        if __name__ == '__main__':
            verbosity = 2
        else:
            verbosity = 0

        # run transient
        rad_new = runLinearTransient(mesh=mesh,
                                     time_stepper=time_stepper,
                                     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,
                                     psim_src=psim_src,
                                     psip_src=psip_src,
                                     verbosity=verbosity)

        # compute the steady-state solution
        Q = computeRadiationExtraneousSource(psim_src, psip_src, mesh, t_start)
        rad_ss = radiationSolveSS(mesh, cross_sects, Q, rad_BC=rad_BC)

        # compute difference of transient and steady-state scalar flux
        phi_diff = [
            tuple(map(operator.sub, rad_new.phi[i], rad_ss.phi[i]))
            for i in xrange(len(rad_new.phi))
        ]

        # compute discrete L1 norm of difference
        L1_norm_diff = computeDiscreteL1Norm(phi_diff)

        # assert that solution has converged to steady-state
        n_decimal_places = 12
        self.assertAlmostEqual(L1_norm_diff, 0.0, n_decimal_places)

        # plot solutions if run standalone
        if __name__ == "__main__":
            plotScalarFlux(mesh,
                           rad_new.psim,
                           rad_new.psip,
                           scalar_flux_exact=rad_ss.phi,
                           exact_data_continuous=False)
Пример #5
0
   def test_PureAbsorberProblem(self):

      # number of elements
      n_elems = 50
      # mesh
      L = 10.0       # domain length
      mesh = Mesh(n_elems,L)
   
      # physics data
      sig_t = 0.1    # total cross section
      sig_s = 0.0    # scattering cross section
      inc_minus = 10 # isotropic incoming angular flux for minus direction
      inc_plus  = 20 # isotropic incoming angular flux for plus  direction
      rad_BC    = RadBC(mesh, "dirichlet", psi_left=inc_plus, psi_right=inc_minus)
   
      # cross sections
      cross_sects = [(ConstantCrossSection(sig_s,sig_t),
                      ConstantCrossSection(sig_s,sig_t))
                      for i in xrange(n_elems)]
      # sources
      Q  = [0.0 for i in xrange(mesh.n_elems*4)]
   
      # compute LD solution
      rad = radiationSolveSS(mesh,
                             cross_sects,
                             Q,
                             rad_BC=rad_BC)
   
      # get continuous x-points
      xlist = makeContinuousXPoints(mesh)
   
      # exact solution functions
      def exactPsiMinus(x):
         return inc_minus*exp(-sig_t/mu["-"]*(x-L))
      def exactPsiPlus(x):
         return inc_plus *exp(-sig_t/mu["+"]*x)
      def exactScalarFlux(x):
         return exactPsiMinus(x) + exactPsiPlus(x)

      # compute exact solutions
      psim_exact = [exactPsiMinus(x) for x in xlist]
      psip_exact = [exactPsiPlus(x)  for x in xlist]
      exact_scalar_flux = [psi_m+psi_p for psi_m, psi_p
         in zip(psim_exact, psip_exact)]

      # plot solutions
      if __name__ == '__main__':
         plotAngularFlux(mesh, rad.psim, rad.psip,
            psi_minus_exact=psim_exact, psi_plus_exact=psip_exact)

      # compute L1 error
      L1_error = computeL1ErrorLD(mesh,rad.phi,exactScalarFlux)
   
      # compute L1 norm of exact solution to be used as normalization constant
      L1_norm_exact = quad(exactScalarFlux, 0.0, L)[0]

      # compute relative L1 error
      L1_relative_error = L1_error / L1_norm_exact

      # check that L1 error is small
      n_decimal_places = 3
      self.assertAlmostEqual(L1_relative_error,0.0,n_decimal_places)
Пример #6
0
    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)
Пример #7
0
    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)
Пример #8
0
    def test_SSConvergence(self):

        # physics data
        sig_a = 0.25  # absorption cross section
        sig_s = 0.75  # scattering cross section
        sig_t = sig_s + sig_a  # total cross section
        D = 1.0 / (3 * sig_t)  # diffusion coefficient
        L = sqrt(D / sig_a)  # diffusion length
        xL = 0.0  # left boundary of domain
        xR = 3.0  # right boundary of domain
        Q = 1.0  # isotropic source
        A = 2.4084787907  # constant used in exact solution function
        B = -2.7957606046  # constant used in exact solution function

        # function for exact scalar flux solution
        def exactScalarFlux(x):
            return A * sinh(x / L) + B * cosh(x / L) + Q * L * L / D

        # number of elements
        n_elems = 10

        # number of refinement cycles
        n_cycles = 5

        # initialize lists for mesh size and L1 error for each cycle
        max_dx = list()
        L1_error = list()

        # loop over refinement cycles
        for cycle in xrange(n_cycles):

            if __name__ == '__main__':
                print("Cycle %d of %d: n_elems = %d" %
                      (cycle + 1, n_cycles, n_elems))

            # mesh
            mesh = Mesh(n_elems, xR)
            # append max dx for this cycle to list
            max_dx.append(mesh.max_dx)

            # radiation BC
            rad_BC = RadBC(mesh, "dirichlet", psi_left=0.0, psi_right=0.0)

            # cross sections
            cross_sects = [(ConstantCrossSection(sig_s, sig_t),
                            ConstantCrossSection(sig_s, sig_t))
                           for i in xrange(n_elems)]

            # sources
            Q_iso = [(0.5 * Q) for i in xrange(mesh.n_elems * 4)]

            # compute LD solution
            rad = radiationSolveSS(mesh, cross_sects, Q_iso, rad_BC=rad_BC)

            # compute L1 error
            L1_error.append(\
               computeL1ErrorLD(mesh, rad.phi, exactScalarFlux))

            # double number of elements for next cycle
            n_elems *= 2

        # compute convergence rates
        rates = computeConvergenceRates(max_dx, L1_error)

        # print convergence table if not being run in suite
        if __name__ == '__main__':
            printConvergenceTable(max_dx,
                                  L1_error,
                                  rates=rates,
                                  dx_desc='dx',
                                  err_desc='L1')

        # check that final rate is approximately 2nd order
        self.assert_(rates[n_cycles - 2] > 1.95)
Пример #9
0
    def test_PureScatteringProblem(self):

        # physics data
        sig_a = 0.0  # absorption cross section
        sig_s = 1.0  # scattering cross section
        sig_t = sig_s + sig_a  # total cross section
        xL = 0.0  # left boundary of domain
        width = 100.0  # domain width
        xR = xL + width  # right boundary of domain
        inc_j_minus = 1  # incoming minus direction half-range current
        inc_j_plus = 3  # incoming plus  direction half-range current
        Q = 1.0  # isotropic source
        D = 1.0 / (3 * sig_t)  # diffusion coefficient

        # number of elements
        n_elems = 50
        # mesh
        mesh = Mesh(n_elems, width, xL)

        # radiation BC
        rad_BC = RadBC(mesh,
                       "dirichlet",
                       psi_left=2 * inc_j_plus,
                       psi_right=2 * inc_j_minus)

        # cross sections
        cross_sects = [(ConstantCrossSection(sig_s, sig_t),
                        ConstantCrossSection(sig_s, sig_t))
                       for i in xrange(n_elems)]
        # sources
        Q_src = [0.5 * Q for i in xrange(mesh.n_elems * 4)]

        # compute LD solution
        rad = radiationSolveSS(mesh, cross_sects, Q_src, rad_BC=rad_BC)

        # get continuous x-points
        xlist = makeContinuousXPoints(mesh)

        # function for the exact scalar flux solution
        def exactScalarFlux(x):
            return Q / (2 * D) * (2 * D * xR + xR * x - x * x)

        # compute exact scalar flux solution
        scalar_flux_exact = [exactScalarFlux(x) for x in xlist]

        # plot solutions
        if __name__ == '__main__':
            plotScalarFlux(mesh,
                           rad.psim,
                           rad.psip,
                           scalar_flux_exact=scalar_flux_exact)

        # compute L1 error
        L1_error = computeL1ErrorLD(mesh, rad.phi, exactScalarFlux)

        # compute L1 norm of exact solution to be used as normalization constant
        L1_norm_exact = quad(exactScalarFlux, xL, xR)[0]

        # compute relative L1 error
        L1_relative_error = L1_error / L1_norm_exact

        # check that L1 error is small
        n_decimal_places = 2
        self.assertAlmostEqual(L1_relative_error, 0.0, n_decimal_places)
Пример #10
0
    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"))
Пример #11
0
    def test_TransientSourceCN(self):

        # number of decimal places to test
        n_decimal_places = 11

        # create mesh
        n_elems = 5
        mesh = Mesh(n_elems, random())

        # compute uniform cross sections
        cross_sects = [(ConstantCrossSection(random(), random()),
                        ConstantCrossSection(random(), random()))
                       for i in xrange(mesh.n_elems)]

        # time step size and c*dt
        dt = random()
        c_dt = GC.SPD_OF_LGT * dt

        # boundary fluxes
        psi_left = random()
        psi_right = random()
        rad_BC = RadBC(mesh,
                       "dirichlet",
                       psi_left=psi_left,
                       psi_right=psi_right)

        # create the steady-state source
        n = 4 * mesh.n_elems
        Q = np.zeros(n)
        for i in xrange(mesh.n_elems):
            Q[getIndex(i, "L", "+")] = random()
            Q[getIndex(i, "R", "+")] = random()
            Q[getIndex(i, "L", "-")] = random()
            Q[getIndex(i, "R", "-")] = random()

        # compute the steady-state solution
        rad_ss = radiationSolveSS(mesh, cross_sects, Q, rad_BC=rad_BC)

        # time-stepper
        time_stepper = "CN"

        # compute the transient source
        Q_tr = computeRadiationSource(mesh=mesh,
                                      time_stepper=time_stepper,
                                      problem_type='rad_only',
                                      dt=dt,
                                      rad_BC=rad_BC,
                                      cx_old=cross_sects,
                                      rad_old=rad_ss,
                                      Qpsi_old=Q,
                                      Qpsi_new=Q)

        # loop over elements and test that sources are what they should be
        for i in xrange(mesh.n_elems):
            iLm = getIndex(i, "L", "-")
            iLp = getIndex(i, "L", "+")
            iRm = getIndex(i, "R", "-")
            iRp = getIndex(i, "R", "+")
            QiLm_expected = rad_ss.psim[i][0] / c_dt + 0.5 * Q[iLm]
            QiLp_expected = rad_ss.psip[i][0] / c_dt + 0.5 * Q[iLp]
            QiRm_expected = rad_ss.psim[i][1] / c_dt + 0.5 * Q[iRm]
            QiRp_expected = rad_ss.psip[i][1] / c_dt + 0.5 * Q[iRp]
            self.assertAlmostEqual(Q_tr[iLm], QiLm_expected, n_decimal_places)
            self.assertAlmostEqual(Q_tr[iLp], QiLp_expected, n_decimal_places)
            self.assertAlmostEqual(Q_tr[iRm], QiRm_expected, n_decimal_places)
            self.assertAlmostEqual(Q_tr[iRp], QiRp_expected, n_decimal_places)
Пример #12
0
   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)
Пример #13
0
    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)
Пример #14
0
    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"))
Пример #15
0
    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)
Пример #16
0
    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"))
Пример #17
0
    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)