コード例 #1
0
ファイル: test_high_level.py プロジェクト: sdurve/sfepy
    def test_solving(self):
        from sfepy.base.base import IndexedStruct
        from sfepy.fem \
             import FieldVariable, Material, ProblemDefinition, \
                    Function, Equation, Equations, Integral
        from sfepy.fem.conditions import Conditions, EssentialBC
        from sfepy.terms import Term
        from sfepy.solvers.ls import ScipyDirect
        from sfepy.solvers.nls import Newton

        u = FieldVariable('u', 'unknown', self.field, self.dim)
        v = FieldVariable('v', 'test', self.field, self.dim,
                          primary_var_name='u')

        m = Material('m', lam=1.0, mu=1.0)
        f = Material('f', val=[[0.02], [0.01]])

        bc_fun = Function('fix_u_fun', fix_u_fun,
                          extra_args={'extra_arg' : 'hello'})

        fix_u = EssentialBC('fix_u', self.gamma1, {'u.all' : bc_fun})
        shift_u = EssentialBC('shift_u', self.gamma2, {'u.0' : 0.1})

        integral = Integral('i', order=3)

        t1 = Term.new('dw_lin_elastic_iso(m.lam, m.mu, v, u)',
                      integral, self.omega, m=m, v=v, u=u)

        t2 = Term.new('dw_volume_lvf(f.val, v)', integral, self.omega, f=f, v=v)

        eq = Equation('balance', t1 + t2)
        eqs = Equations([eq])

        ls = ScipyDirect({})

        nls_status = IndexedStruct()
        nls = Newton({}, lin_solver=ls, status=nls_status)

        pb = ProblemDefinition('elasticity', equations=eqs, nls=nls, ls=ls)
        ## pb.save_regions_as_groups('regions')

        pb.time_update(ebcs=Conditions([fix_u, shift_u]))

        state = pb.solve()

        name = op.join(self.options.out_dir, 'test_high_level_solving.vtk')
        pb.save_state(name, state)

        ok = nls_status.condition == 0
        if not ok:
            self.report('solver did not converge!')

        _ok = state.has_ebc()
        if not _ok:
            self.report('EBCs violated!')

        ok = ok and _ok

        return ok
コード例 #2
0
    def set_solvers_instances(self, ls=None, nls=None):
        """
        Set the instances of linear and nonlinear solvers that will be
        used in `Problem.solve()` call.
        """
        if (ls is not None) and (nls is not None):
            if not (nls.lin_solver is ls):
                raise ValueError('linear solver not used in nonlinear!')

        self.solvers = Struct(name='solvers', ls=ls, nls=nls)
        if nls is not None:
            self.nls_status = get_default(nls.status, IndexedStruct())
コード例 #3
0
    def solve_step(self, ts, nls, vec, prestep_fun):
        """
        Solve a single time step.
        """
        status = IndexedStruct(n_iter=0, condition=0)
        while 1:
            vect = nls(vec, status=status)

            is_break = self.adapt_time_step(ts, status, self.adt, self.context,
                                            verbose=self.verbose)

            if is_break:
                break

            prestep_fun(ts, vec)

        return vect
コード例 #4
0
    def test_input(self):
        import numpy as nm
        from sfepy.applications import solve_pde

        self.report('solving %s...' % self.conf.input_name)

        status = IndexedStruct(nls_status=NLSStatus(conditions=[]))

        solve_pde(self.test_conf,
                  self.solver_options,
                  status=status,
                  output_dir=self.options.out_dir,
                  step_hook=self.step_hook,
                  post_process_hook=self.post_process_hook,
                  post_process_hook_final=self.post_process_hook_final)
        self.report('%s solved' % self.conf.input_name)

        ok = self.check_conditions(nm.array(status.nls_status.conditions))

        return ok
コード例 #5
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)