Example #1
0
def main(argv=None):
    options = parse_args(argv=argv)

    # vvvvvvvvvvvvvvvv #
    approx_order = 2
    # ^^^^^^^^^^^^^^^^ #

    # Setup output names
    outputs_folder = options.output_dir

    domain_name = "domain_1D"
    problem_name = "iburgers_1D"
    output_folder = pjoin(outputs_folder, problem_name, str(approx_order))
    output_format = "vtk"
    save_timestn = 100
    clear_folder(pjoin(output_folder, "*." + output_format))
    configure_output({
        'output_screen':
        True,
        'output_log_name':
        pjoin(output_folder, f"last_run_{problem_name}_{approx_order}.txt")
    })

    # ------------
    # | Get mesh |
    # ------------
    X1 = 0.
    XN = 1.
    n_nod = 100
    n_el = n_nod - 1
    mesh = get_gen_1D_mesh_hook(X1, XN, n_nod).read(None)

    # -----------------------------
    # | Create problem components |
    # -----------------------------

    integral = Integral('i', order=approx_order * 2)
    domain = FEDomain(domain_name, mesh)
    omega = domain.create_region('Omega', 'all')
    left = domain.create_region('Gamma1', 'vertices in x == %.10f' % X1,
                                'vertex')
    right = domain.create_region('Gamma2', 'vertices in x == %.10f' % XN,
                                 'vertex')
    field = DGField('dgfu',
                    nm.float64,
                    'scalar',
                    omega,
                    approx_order=approx_order)

    u = FieldVariable('u', 'unknown', field, history=1)
    v = FieldVariable('v', 'test', field, primary_var_name='u')

    MassT = Term.new('dw_dot(v, u)', integral, omega, u=u, v=v)

    velo = nm.array(1.0)

    def adv_fun(u):
        vu = velo.T * u[..., None]
        return vu

    def adv_fun_d(u):
        v1 = velo.T * nm.ones(u.shape + (1, ))
        return v1

    burg_velo = velo.T / nm.linalg.norm(velo)

    def burg_fun(u):
        vu = burg_velo * u[..., None]**2
        return vu

    def burg_fun_d(u):
        v1 = 2 * burg_velo * u[..., None]
        return v1

    StiffT = Term.new('dw_ns_dot_grad_s(fun, fun_d, u[-1], v)',
                      integral,
                      omega,
                      u=u,
                      v=v,
                      fun=burg_fun,
                      fun_d=burg_fun_d)

    # alpha = Material('alpha', val=[.0])
    # FluxT = AdvectDGFluxTerm("adv_lf_flux(a.val, v, u)", "a.val, v,  u[-1]",
    #                          integral, omega, u=u, v=v, a=a, alpha=alpha)

    FluxT = Term.new('dw_dg_nonlinear_laxfrie_flux(fun, fun_d, v, u[-1])',
                     integral,
                     omega,
                     u=u,
                     v=v,
                     fun=burg_fun,
                     fun_d=burg_fun_d)

    eq = Equation('balance', MassT - StiffT + FluxT)
    eqs = Equations([eq])

    # ------------------------------
    # | Create boundary conditions |
    # ------------------------------
    left_fix_u = EssentialBC('left_fix_u', left, {'u.all': 1.0})
    right_fix_u = EssentialBC('right_fix_u', right, {'u.all': 0.0})

    # ----------------------------
    # | Create initial condition |
    # ----------------------------
    def ghump(x):
        """
        Nice gaussian.
        """
        return nm.exp(-200 * x**2)

    def ic_wrap(x, ic=None):
        return ghump(x - .3)

    ic_fun = Function('ic_fun', ic_wrap)
    ics = InitialCondition('ic', omega, {'u.0': ic_fun})

    # ------------------
    # | Create problem |
    # ------------------
    pb = Problem(problem_name,
                 equations=eqs,
                 conf=Struct(options={"save_times": save_timestn},
                             ics={},
                             ebcs={},
                             epbcs={},
                             lcbcs={},
                             materials={}),
                 active_only=False)
    pb.setup_output(output_dir=output_folder, output_format=output_format)
    pb.set_ics(Conditions([ics]))

    # ------------------
    # | Create limiter |
    # ------------------
    limiter = MomentLimiter1D

    # ---------------------------
    # | Set time discretization |
    # ---------------------------
    CFL = .2
    max_velo = nm.max(nm.abs(velo))
    t0 = 0
    t1 = .2
    dx = nm.min(mesh.cmesh.get_volumes(1))
    dt = dx / max_velo * CFL / (2 * approx_order + 1)
    tn = int(nm.ceil((t1 - t0) / dt))
    dtdx = dt / dx

    # ------------------
    # | Create solver |
    # ------------------
    ls = ScipyDirect({})
    nls_status = IndexedStruct()
    nls = Newton({'is_linear': True}, lin_solver=ls, status=nls_status)

    tss_conf = {
        't0': t0,
        't1': t1,
        'n_step': tn,
        'limiters': {
            "dgfu": limiter
        }
    }

    tss = TVDRK3StepSolver(tss_conf, nls=nls, context=pb, verbose=True)

    # ---------
    # | Solve |
    # ---------
    pb.set_solver(tss)
    state_end = pb.solve()

    output("Solved equation \n\n\t\t u_t - div(f(u))) = 0\n")
    output(f"With IC: {ic_fun.name}")
    # output("and EBCs: {}".format(pb.ebcs.names))
    # output("and EPBCS: {}".format(pb.epbcs.names))
    output("-------------------------------------")
    output(f"Approximation order is {approx_order}")
    output(f"Space divided into {mesh.n_el} cells, " +
           f"{len(mesh.coors)} steps, step size is {dx}")
    output(f"Time divided into {tn - 1} nodes, {tn} steps, step size is {dt}")
    output(f"CFL coefficient was {CFL} and " +
           f"order correction {1 / (2 * approx_order + 1)}")
    output(f"Courant number c = max(abs(u)) * dt/dx = {max_velo * dtdx}")
    output("------------------------------------------")
    output(f"Time stepping solver is {tss.name}")
    output(f"Limiter used: {limiter.name}")
    output("======================================")

    # ----------
    # | Plot 1D|
    # ----------
    if options.plot:
        load_and_plot_fun(output_folder, domain_name, t0, t1,
                          min(tn, save_timestn), ic_fun)
Example #2
0
ic_fun = Function('ic_fun', ic_wrap)
ics = InitialCondition('ic', omega, {'u.0': ic_fun})

# ------------------
# | Create problem |
# ------------------
pb = Problem(problem_name,
             equations=eqs,
             conf=Struct(options={"save_times": save_timestn},
                         ics={},
                         ebcs={},
                         epbcs={},
                         lcbcs={},
                         materials={}),
             active_only=False)
pb.setup_output(output_dir=output_folder, output_format=output_format)
pb.set_ics(Conditions([ics]))

# ------------------
# | Create limiter |
# ------------------
limiter = MomentLimiter1D

# ---------------------------
# | Set time discretization |
# ---------------------------
CFL = .2
max_velo = nm.max(nm.abs(velo))
t0 = 0
t1 = .2
dx = nm.min(mesh.cmesh.get_volumes(1))