コード例 #1
0
ファイル: solves.py プロジェクト: pdelab/pyeafe
def assert_solves(
    mesh: Mesh,
    diffusion: Coefficient,
    convection: Optional[Coefficient],
    reaction: Optional[Coefficient],
    source: Coefficient,
    exact: Coefficient,
    l2_tol: Optional[float] = 1.0e-8,
    h1_tol: Optional[float] = 1.0e-6,
):
    eafe_matrix = eafe_assemble(mesh, diffusion, convection, reaction)

    pw_linears = FunctionSpace(mesh, "Lagrange", 1)
    test_function = TestFunction(pw_linears)
    rhs_vector = assemble(source * test_function * dx)

    bc = DirichletBC(pw_linears, exact, lambda _, on_bndry: on_bndry)
    bc.apply(eafe_matrix, rhs_vector)

    solution = Function(pw_linears)
    solver = LUSolver(eafe_matrix, "default")
    solver.parameters["symmetric"] = False
    solver.solve(solution.vector(), rhs_vector)

    l2_err: float = errornorm(exact, solution, "l2", 3)
    assert l2_err <= l2_tol, f"L2 error too large: {l2_err} > {l2_tol}"

    h1_err: float = errornorm(exact, solution, "H1", 3)
    assert h1_err <= h1_tol, f"H1 error too large: {h1_err} > {h1_tol}"
コード例 #2
0
    def app_pverr(tcur):
        cdatstr = get_dtstr(t=tcur, **dtstrdct)
        vp = np.load(cdatstr + '.npy')
        v, p = expand_vp_dolfunc(PrP, vp=vp)

        # vpref = np.load(cdatstrref + '.npy')
        # vref, pref = expand_vp_dolfunc(PrP, vp=vpref)
        vref = np.load(vdref[tcur] + '.npy')
        pref = np.load(pdref[tcur] + '.npy')
        # vpref = np.vstack([vref, pref])
        vreff, preff = expand_vp_dolfunc(PrP, vc=vref, pc=pref)
        # vdiff, pdiff = expand_vp_dolfunc(PrP, vc=vp[:Nv]-vref,
        #                                  pc=vp[Nv:]-pref)
        # prtrial = snu.get_pfromv(v=vref, **snsedict)
        # vrtrial, prtrial = expand_vp_dolfunc(PrP, vc=vref, pc=prtrial)
        # print 'pref', dolfin.norm(preff)
        # print 'p', dolfin.norm(p)
        # print 'p(v)', dolfin.norm(ptrial)
        # print 'p(vref){0}\n'.format(dolfin.norm(prtrial))

        elv.append(dolfin.errornorm(v, vreff))
        elp.append(dolfin.errornorm(p, preff))
        # elv.append(dolfin.norm(vdiff))
        # elp.append(dolfin.norm(pdiff))
        cres = J*vp[:Nv]-fpbc
        mpires = (Mpfac.solve(cres.flatten())).reshape((cres.size, 1))
        ncres = np.sqrt(np.dot(cres.T, mpires))[0][0]
        # ncres = np.sqrt(np.dot(cres.T, MP*cres))[0][0]
        # routine from time_int_schemes seems buggy for CR or 'g not 0'
        # ncres = comp_cont_error(v, fpbc, PrP.Q)
        elc.append(ncres)
コード例 #3
0
ファイル: test_stokes.py プロジェクト: nschloe/flow
def compute_error(problem, mesh_size):
    mesh = problem.mesh_generator(mesh_size)

    u = problem.solution['u']
    u_sol = Expression((ccode(u['value'][0]), ccode(u['value'][1])),
                       degree=u['degree'])

    p = problem.solution['p']
    p_sol = Expression(ccode(p['value']), degree=p['degree'])

    f = Expression(
        (ccode(problem.f['value'][0]), ccode(problem.f['value'][1])),
        degree=problem.f['degree'])

    W = VectorElement('Lagrange', mesh.ufl_cell(), 2)
    P = FiniteElement('Lagrange', mesh.ufl_cell(), 1)
    WP = FunctionSpace(mesh, W * P)

    # Get Dirichlet boundary conditions
    u_bcs = DirichletBC(WP.sub(0), u_sol, 'on_boundary')
    p_bcs = DirichletBC(WP.sub(1), p_sol, 'on_boundary')

    u_approx, p_approx = flow.stokes.solve(WP,
                                           bcs=[u_bcs, p_bcs],
                                           mu=problem.mu,
                                           f=f,
                                           verbose=True,
                                           tol=1.0e-12)

    # compute errors
    u_error = errornorm(u_sol, u_approx)
    p_error = errornorm(p_sol, p_approx)
    return mesh.hmax(), u_error, p_error
コード例 #4
0
 def compute_err(self, is_tent, velocity, t):
     if self.doErrControl:
         er_list_L2 = self.listDict['u2L2' if is_tent else 'u_L2']['list']
         er_list_H1 = self.listDict['u2H1' if is_tent else 'u_H1']['list']
         self.tc.start('errorV')
         # assemble is faster than errornorm
         errorL2_sq = assemble(inner(velocity - self.solution, velocity - self.solution) * dx)
         errorH1seminorm_sq = assemble(inner(grad(velocity - self.solution), grad(velocity - self.solution)) * dx)
         info('  H1 seminorm error: %f' % sqrt(errorH1seminorm_sq))
         errorL2 = sqrt(errorL2_sq)
         errorH1 = sqrt(errorL2_sq + errorH1seminorm_sq)
         info("  Relative L2 error in velocity = %f" % (errorL2 / self.analytic_v_norm_L2))
         self.last_error = errorH1 / self.analytic_v_norm_H1
         self.last_status_functional = self.last_error
         info("  Relative H1 error in velocity = %f" % self.last_error)
         er_list_L2.append(errorL2)
         er_list_H1.append(errorH1)
         self.tc.end('errorV')
         if self.testErrControl:
             er_list_test_H1 = self.listDict['u2H1test' if is_tent else 'u_H1test']['list']
             er_list_test_L2 = self.listDict['u2L2test' if is_tent else 'u_L2test']['list']
             self.tc.start('errorVtest')
             er_list_test_L2.append(errornorm(velocity, self.solution, norm_type='L2', degree_rise=0))
             er_list_test_H1.append(errornorm(velocity, self.solution, norm_type='H1', degree_rise=0))
             self.tc.end('errorVtest')
         # stopping criteria for detecting diverging solution
         if self.last_error > self.divergence_treshold:
             raise RuntimeError('STOPPED: Failed divergence test!')
コード例 #5
0
def main(N, dt, T, theta=0.5):
    """Run bidomain MMA."""

    # Exact solutions
    u_exact_str = "-cos(pi*x[0])*cos(pi*x[1])*sin(t)/2.0"
    v_exact_str = "cos(pi*x[0])*cos(pi*x[1])*sin(t)"
    s_exact_str = "-cos(pi*x[0])*cos(pi*x[1])*cos(t)"

    # Source term
    ac_str = "cos(t)*cos(pi*x[0])*cos(pi*x[1]) + pow(pi, 2)*cos(pi*x[0])*cos(pi*x[1])*sin(t)"
    ac_str += " - " + s_exact_str

    # Create data
    mesh = df.UnitSquareMesh(N, N)
    time = df.Constant(0.0)

    # We choose the FHN parameters such that s=1 and I_s=v
    model = SimpleODEModel()
    model.set_initial_conditions(V=0,
                                 S=df.Expression(s_exact_str, degree=5,
                                                 t=0))  # Set initial condition

    ps = SplittingSolver.default_parameters()
    ps["pde_solver"] = "bidomain"
    ps["theta"] = theta
    # ps["CardiacODESolver"]["scheme"] = "RK4"
    ps["BidomainSolver"]["linear_solver_type"] = "direct"
    ps["BidomainSolver"]["use_avg_u_constraint"] = True
    ps["BidomainSolver"]["Chi"] = 1.0
    ps["BidomainSolver"]["Cm"] = 1.0
    ps["apply_stimulus_current_to_pde"] = True

    stimulus = df.Expression(ac_str, t=time, dt=dt, degree=5)
    M_i = 1.0
    M_e = 1.0
    heart = xalbrain.Model(mesh, time, M_i, M_e, model, stimulus)
    splittingsolver = SplittingSolver(heart, parameters=ps)

    # Define exact solution (Note: v is returned at end of time
    # interval(s), u is computed at somewhere in the time interval
    # depending on theta)

    v_exact = df.Expression(v_exact_str, t=T, degree=3)
    u_exact = df.Expression(u_exact_str, t=T - (1. - theta) * dt, degree=3)

    pde_vs_, pde_vs, vur = splittingsolver.solution_fields()
    pde_vs_.assign(model.initial_conditions())

    solutions = splittingsolver.solve(0, T, dt)
    for (t0, t1), (vs_, vs, vur) in solutions:
        pass

    # Compute errors
    v = vs.split(deepcopy=True)[0]
    u = vur.split(deepcopy=True)[1]
    v_error = df.errornorm(v_exact, v, "L2", degree_rise=2)
    u_error = df.errornorm(u_exact, u, "L2", degree_rise=2)
    return v_error, u_error, mesh.hmin(), dt, T
コード例 #6
0
    def test_superposition_dirichlet_boundary_conditions(self):
        nx, ny = 31, 31
        degree = 2
        kappa = dla.Constant(3)
        xl, xr, yb, yt = 0.25, 1.25, 0.25, 1.25

        sols = []
        mesh = dla.RectangleMesh(dl.Point(xl, yb), dl.Point(xr, yt), nx, ny)
        function_space = dl.FunctionSpace(mesh, "Lagrange", degree)
        for ii in range(4):
            boundary_conditions =\
                get_dirichlet_boundary_conditions_from_expression(
                    get_exact_solution(mesh, degree, True), xl, xr, yb, yt)
            for jj in range(4):
                if jj != ii:
                    boundary_conditions[jj] = [
                        'dirichlet', boundary_conditions[jj][1], 0
                    ]
            sol = run_steady_state_model(
                function_space,
                kappa,
                dla.Constant(0.0),
                boundary_conditions=boundary_conditions)
            sols.append(sol)

        sol = run_steady_state_model(function_space,
                                     kappa,
                                     get_forcing(kappa, mesh, degree, True),
                                     boundary_conditions=None)
        sols.append(sol)

        superposition_sol = sols[0]
        for ii in range(1, len(sols)):
            superposition_sol += sols[ii]
        # pp=dl.plot(superposition_sol)
        #plt.colorbar(pp); plt.show()
        superposition_sol = dla.project(superposition_sol, function_space)

        boundary_conditions = get_dirichlet_boundary_conditions_from_expression(
            get_exact_solution(mesh, degree, True), xl, xr, yb, yt)
        sol = run_steady_state_model(function_space,
                                     kappa,
                                     get_forcing(kappa, mesh, degree, True),
                                     boundary_conditions=boundary_conditions)
        # plt.figure()
        # pp=dl.plot(sol-superposition_sol)
        #plt.colorbar(pp); plt.show()

        exact_sol = get_exact_solution(mesh, degree, True)
        error = dl.errornorm(exact_sol, sol, mesh=mesh)
        print('Error', error)
        assert error <= 1e-4

        error = dl.errornorm(superposition_sol, sol, mesh=mesh)
        print('error', error)
        assert error < 1e-14
コード例 #7
0
def compute_errornorms(v, div_v, p, p_ref):
    deg = v.ufl_element().degree()

    v_ref = df.Expression(("0.0", "0.0"), degree=deg + 3)
    v_errL2 = df.errornorm(v_ref, v, norm_type="L2")
    v_errH10 = df.errornorm(v_ref, v, norm_type="H10")

    #div_errL2 = df.assemble(div_v * div_v * df.dx) ** 0.5
    div_ref = df.Expression("0.0", degree=deg + 3)
    div_errL2 = df.errornorm(div_ref, div_v, norm_type="L2")

    p_errL2 = df.errornorm(p_ref, p, norm_type="L2")

    return v_errL2, v_errH10, div_errL2, p_errL2
コード例 #8
0
def main(N: int, dt: float, T: float, theta: float) -> Tuple[float, float, float, float]:
    """Set up solver and return errors and mesh size."""
    mesh = UnitSquareMesh(N, N)
    time = Constant(0.0)
    ac_str = "(8*pi*pi*lam*sin(t) + (lam + 1)*cos(t))*cos(2*pi*x[0])*cos(2*pi*x[1])/(lam + 1)"
    stimulus = Expression(ac_str, t=time, lam=Constant(1), degree=3)
    M_i = Constant(1.0)
    # Set up solver
    parameters = BasicMonodomainSolver.default_parameters()
    parameters["theta"] = theta
    solver = BasicMonodomainSolver(mesh, time, M_i, I_s=stimulus, parameters=parameters)

    v_exact  = Expression("sin(t)*cos(2*pi*x[0])*cos(2*pi*x[1])", t=T, degree=3)

    # Define initial conditions
    v_, v = solver.solution_fields()

    # Solve
    solutions = solver.solve(0, T, dt)
    for interval, fields in solutions:
        continue

    # Compute errors
    v_error = errornorm(v_exact, v, "L2", degree_rise=2)
    return v_error, mesh.hmin(), dt, T
コード例 #9
0
    def test_quadratic_solution(self):
        dt = 0.01
        t = 0
        final_time = 2
        nx, ny = 2, 2
        degree = 2
        alpha, beta = 3, 1.2
        kappa = dla.Constant(1)
        mesh = dla.RectangleMesh(dl.Point(0, 0), dl.Point(1, 1), nx, ny)
        function_space = dl.FunctionSpace(mesh, "Lagrange", degree)

        boundary_conditions = get_dirichlet_boundary_conditions_from_expression(
            get_quadratic_exact_solution(alpha, beta, mesh, degree), 0, 1, 0,
            1)
        sol = run_model(function_space,
                        kappa,
                        get_quadratic_solution_forcing(alpha, beta, mesh,
                                                       degree),
                        get_quadratic_exact_solution(alpha, beta, mesh,
                                                     degree),
                        dt,
                        final_time,
                        boundary_conditions=boundary_conditions)  # ,
        # exact_sol=get_quadratic_exact_solution(alpha,beta,mesh,degree))

        exact_sol = get_quadratic_exact_solution(alpha, beta, mesh, degree)
        exact_sol.t = final_time
        error = dl.errornorm(exact_sol, sol, mesh=mesh)
        print('Error', error)
        assert error <= 3e-14
コード例 #10
0
ファイル: test_bcs.py プロジェクト: jakobes/Ocellaris
def debug_phi_plot(phi, phia, phih, plotname, compare_historical=False, **plotargs):
    """
    Only used while developing the tests, left here in case more tests are
    added that need some debug plotting as well
    """
    diff = phia.copy(deepcopy=True)
    diff.vector().axpy(-1, phih.vector())
    diff.vector().apply('insert')

    na = dolfin.norm(phia)
    nh = dolfin.norm(phih)
    nd = dolfin.norm(diff)
    nd2 = dolfin.errornorm(phi, phih)

    from matplotlib import pyplot

    pyplot.figure(figsize=(10, 20))

    pyplot.subplot(311)
    c = dolfin.plot(phia, **plotargs)
    pyplot.colorbar(c)
    pyplot.title('Analytical (norm: %g)' % na)

    pyplot.subplot(312)
    c = dolfin.plot(phih, **plotargs)
    pyplot.colorbar(c)
    pyplot.title('Numerical (norm: %g)' % nh)

    pyplot.subplot(313)
    c = dolfin.plot(diff, **plotargs)
    pyplot.colorbar(c)
    pyplot.title('Diff (norm: %g, errornorm: %g, rel: %g)' % (nd, nd2, nd2 / na))

    pyplot.tight_layout()
    pyplot.savefig(plotname)
    pyplot.close()

    if not compare_historical:
        return
    hist_file = plotname + '.npy'

    comm = phih.function_space().mesh().mpi_comm()
    mpi_size = dolfin.MPI.size(comm)
    if mpi_size != 1:
        return

    import os

    arr = phih.vector().get_local()
    if not os.path.isfile(hist_file):
        numpy.save(hist_file, arr)
        return

    hist = numpy.load(hist_file)
    print('hist', hist[:5])
    print('arr ', arr[:5])
    print('diff', (hist - arr)[:5])
    print('maxabs', abs(hist - arr).max())

    assert abs(hist - arr).max() < 1e-12
コード例 #11
0
    def test_cosine_solution_robin_boundary_conditions(self):
        dt = 0.05
        t = 0
        final_time = 1
        nx, ny = 31, 31
        degree = 2
        kappa = dla.Constant(3)

        mesh = dla.RectangleMesh(dl.Point(0, 0), dl.Point(1, 1), nx, ny)
        function_space = dl.FunctionSpace(mesh, "Lagrange", degree)
        # bc : kappa * grad u.dot(n)+alpha*u=beta
        alpha = 1
        from functools import partial
        expression = partial(get_gradu_dot_n, kappa, alpha, mesh, degree)
        boundary_conditions = get_robin_boundary_conditions_from_expression(
            expression, dla.Constant(alpha))

        sol = run_model(function_space,
                        kappa,
                        get_forcing(kappa, mesh, degree),
                        get_exact_solution(mesh, degree),
                        dt,
                        final_time,
                        boundary_conditions=boundary_conditions,
                        second_order_timestepping=True,
                        exact_sol=None)

        exact_sol = get_exact_solution(mesh, degree)
        exact_sol.t = final_time
        error = dl.errornorm(exact_sol, sol, mesh=mesh)
        print('Error', error)
        assert error <= 1e-4
コード例 #12
0
    def test_quadratic_diffusion_dirichlet_boundary_conditions(self):
        """
        du/dt = div((1+u**2)*grad(u))+f   in the unit square.
            u = u_D on the boundary.
        """
        nx, ny, degree = 21, 21, 2
        mesh = dla.RectangleMesh(dl.Point(0, 0), dl.Point(1, 1), nx, ny)
        function_space = dl.FunctionSpace(mesh, "Lagrange", degree)

        bndry_obj = get_2d_unit_square_mesh_boundaries()
        boundary_conditions = get_dirichlet_boundary_conditions_from_expression(
            get_quadratic_diffusion_exact_solution(mesh, degree), 0, 1, 0, 1)
        forcing = get_diffusion_forcing(
            quadratic_diffusion, get_quadratic_diffusion_exact_solution_sympy,
            mesh, degree)

        options = {'time_step': 0.05, 'final_time': 1,
                   'forcing': forcing,
                   'boundary_conditions': boundary_conditions,
                   'second_order_timestepping': True,
                   'init_condition': get_quadratic_diffusion_exact_solution(
                       mesh, degree), 'nonlinear_diffusion':
                   quadratic_diffusion}
        sol = run_model(function_space, **options)

        exact_sol = get_quadratic_diffusion_exact_solution(mesh, degree)
        exact_sol.t = options['final_time']
        error = dl.errornorm(exact_sol, sol, mesh=mesh)
        print('Abs. Error', error)
        assert error <= 8e-5
コード例 #13
0
ファイル: test_bdm.py プロジェクト: TormodLandet/Ocellaris
def test_bdm_identity_transform(gdim):
    N = 5
    k = 2

    # Create mesh and define a divergence free field
    if gdim == 2:
        mesh = dolfin.UnitSquareMesh(N, N)
        field = ['-sin(pi*x[1])*cos(pi*x[0])', 'sin(pi*x[0])*cos(pi*x[1])']
    elif gdim == 3:
        mesh = dolfin.UnitCubeMesh(N, N, N)
        field = [
            '-sin(pi*x[0])*cos(pi*x[1])*sin(pi*x[2])',
            'sin(pi*x[0])*cos(pi*x[1])*sin(pi*x[2])',
            '-cos(pi*x[2])*cos(pi*(x[0]-x[1]))',
        ]

    V = dolfin.FunctionSpace(mesh, 'DG', k)
    u = dolfin.as_vector([dolfin.Function(V) for _ in range(gdim)])
    a = dolfin.as_vector([dolfin.Function(V) for _ in range(gdim)])

    # Make a divergence free field
    for i, cpp in enumerate(field):
        ei = dolfin.Expression(cpp, degree=k)
        u[i].interpolate(ei)
        a[i].assign(u[i])

    # Run the projection into BDM and then assign this to u
    bdm = VelocityBDMProjection(simulation=Simulation(), w=u, use_bcs=False)
    bdm.run()

    # Check the changes made
    for ui, ai in zip(u, a):
        error = dolfin.errornorm(ai, ui, degree_rise=0)
        assert error < 1e-15
コード例 #14
0
    def test_constant_diffusion_dirichlet_boundary_conditions(self):
        kappa = 3
        nx, ny, degree = 31, 31, 2
        mesh = dla.RectangleMesh(dl.Point(0, 0), dl.Point(1, 1), nx, ny)
        function_space = dl.FunctionSpace(mesh, "Lagrange", degree)

        def constant_diffusion(u):
            return dla.Constant(kappa)

        boundary_conditions = get_dirichlet_boundary_conditions_from_expression(
            get_advec_exact_solution(mesh, degree), 0, 1, 0, 1)

        nlsparam = dict()

        options = {'time_step': 0.05, 'final_time': 1,
                   'forcing': get_advec_forcing(kappa, mesh, degree),
                   'boundary_conditions': boundary_conditions,
                   'second_order_timestepping': True,
                   'init_condition': get_advec_exact_solution(mesh, degree),
                   'nlsparam': nlsparam,
                   'nonlinear_diffusion': constant_diffusion}
        sol = run_model(function_space, **options)

        exact_sol = get_advec_exact_solution(mesh, degree)
        exact_sol.t = options['final_time']
        error = dl.errornorm(exact_sol, sol, mesh=mesh)
        print('Abs. Error', error)
        assert error <= 1e-4
コード例 #15
0
ファイル: _test_helmholtz.py プロジェクト: jezgillen/pyapprox
    def test_dirichlet_boundary(self):
        frequency=50
        omega = 2.*np.pi*frequency
        c1,c2 = [343.4,6320]
        gamma=8.4e-4
        
        kappa = omega/c1

        Nx, Ny = [21,21]
        Lx,Ly=[1,1]

        # create function space
        mesh = dl.RectangleMesh(dl.Point(0., 0.), dl.Point(Lx, Ly), Nx, Ny)
        degree=1
        P1=dl.FiniteElement('Lagrange',mesh.ufl_cell(),degree)
        element=dl.MixedElement([P1,P1])
        function_space=dl.FunctionSpace(mesh,element)
        
        boundary_conditions=None
        kappa=dl.Constant(kappa)
        # do not pass element=function_space.ufl_element()
        # as want forcing to be a scalar pass degree instead
        forcing=[
            Forcing(kappa,'real',degree=function_space.ufl_element().degree()),
            Forcing(kappa,'imag',degree=function_space.ufl_element().degree())]

        p=run_model(kappa,forcing,function_space,boundary_conditions)
        error = dl.errornorm(
            ExactSolution(kappa,element=function_space.ufl_element()),p)
        print('Error',error)
        assert error<=3e-2
コード例 #16
0
def verify_function_slice(func_slice, u, cpp_2d, expected_area):
    u_2D = func_slice.get_slice(u)

    # The 2D solution we want to obtain
    analytical = dolfin.Expression(cpp_2d, degree=2 + 3)

    comm = dolfin.MPI.comm_world
    if comm.rank == 0:
        error = dolfin.errornorm(analytical, u_2D)
        mesh = func_slice.slice_function_space.mesh()
        area = dolfin.assemble(1 * dolfin.dx(domain=mesh))

        if True:
            import matplotlib

            matplotlib.use('Agg')
            from matplotlib import pyplot

            fig = pyplot.figure()
            dolfin.plot(u_2D)
            pyplot.gca().view_init(90, 270)
            pyplot.gca().set_proj_type('ortho')
            pyplot.gca().set_xlabel('x')
            pyplot.gca().set_ylabel('y')
            fig.savefig('test_func_slice.png')
    else:
        error = 0.0
        area = 0.0

    assert dolfin.MPI.max(comm, error) < 0.015
    area = dolfin.MPI.sum(comm, area)
    assert abs(area - expected_area) < 1e-8
コード例 #17
0
    def test_cosine_solution_dirichlet_boundary_conditions(self):
        dt = 0.05
        t = 0
        final_time = 1
        nx, ny = 31, 31
        degree = 2
        kappa = dla.Constant(3)

        mesh = dla.RectangleMesh(dl.Point(0, 0), dl.Point(1, 1), nx, ny)
        function_space = dl.FunctionSpace(mesh, "Lagrange", degree)
        boundary_conditions = get_dirichlet_boundary_conditions_from_expression(
            get_exact_solution(mesh, degree), 0, 1, 0, 1)
        sol = run_model(function_space,
                        kappa,
                        get_forcing(kappa, mesh, degree),
                        get_exact_solution(mesh, degree),
                        dt,
                        final_time,
                        boundary_conditions=boundary_conditions,
                        second_order_timestepping=True,
                        exact_sol=None)

        exact_sol = get_exact_solution(mesh, degree)
        exact_sol.t = final_time
        error = dl.errornorm(exact_sol, sol, mesh=mesh)
        print('Error', error)
        assert error <= 1e-4
コード例 #18
0
ファイル: _test_helmholtz.py プロジェクト: jezgillen/pyapprox
    def test_robin_boundary(self):
        frequency=50
        omega = 2.*np.pi*frequency
        c1,c2 = [343.4,6320]
        gamma=8.4e-4
        
        kappa = omega/c1
        alpha=kappa*gamma

        Nx, Ny = 21,21; Lx, Ly = 1,1

        mesh = dl.RectangleMesh(dl.Point(0., 0.), dl.Point(Lx, Ly), Nx, Ny)
        degree=1
        P1=dl.FiniteElement('Lagrange',mesh.ufl_cell(),degree)
        element=dl.MixedElement([P1,P1])
        function_space=dl.FunctionSpace(mesh,element)
        
        boundary_conditions=get_robin_bndry_conditions(
            kappa,alpha,function_space)
        kappa=dl.Constant(kappa)
        forcing=[
            Forcing(kappa,'real',degree=function_space.ufl_element().degree()),
            Forcing(kappa,'imag',degree=function_space.ufl_element().degree())]
        
        p=run_model(kappa,forcing,function_space,boundary_conditions)
        error = dl.errornorm(
            ExactSolution(kappa,element=function_space.ufl_element()),p,)
        print('Error',error)
        assert error<=3e-2
コード例 #19
0
def err_est_fun(mesh_name2, hol_cyl, T_sol1, T_sol2, deg_choice2, hol_cyl2,
                count_it):
    '''
    Error estimate.
    '''
    #comm1 = MPI.COMM_WORLD

    #rank1 = comm1.Get_rank()

    #e1 = sqrt(int_Omega (T - T_ex)**2. dx)/sqrt(int_Omega T**2. dx)
    #do.assemble yields integration
    e1 = do.sqrt(do.assemble(pow(T_sol2 - T_sol1, 2.) * do.dx(domain = hol_cyl))) / \
         do.sqrt(do.assemble(pow(T_sol1, 2.) * do.dx(domain = hol_cyl)))

    #sometimes e1 does not work properly (it might be unstable) -> e2
    #the degree of piecewise polynomials used to approximate T_th and T...
    #...will be the degree of T + degree_rise
    e2 = do.errornorm(T_sol1, T_sol2, norm_type = 'l2', degree_rise = 2, mesh = hol_cyl2) / \
         do.sqrt(do.assemble(pow(T_sol1, 2.) * do.dx(domain = hol_cyl)))

    print 'err: count_t = {}, error_1 = {}, error_2 = {}'.format(
        count_it, e1, e2)

    #print 'rank = ', rank1, ',
    print 'max(T_sol) = ', max(T_sol2.vector().array())
    #print 'rank = ', rank1, ',
    print 'min(T_sol) = ', min(T_sol2.vector().array()), '\n'

    return e1, e2
コード例 #20
0
ファイル: steady_cylinder.py プロジェクト: j-hr/projection
 def save_pressure(self, is_tent, pressure):
     super(Problem, self).save_pressure(is_tent, pressure)
     self.tc.start('computePG')
     # Report pressure gradient
     p_in = assemble((1.0/self.area) * pressure * self.dsIn)
     p_out = assemble((1.0/self.area) * pressure * self.dsOut)
     computed_gradient = (p_in - p_out)/20.0
     # 20.0 is a length of a pipe NT should depend on mesh length (implement through metadata or function of mesh)
     self.tc.end('computePG')
     self.tc.start('errorP')
     error = errornorm(self.sol_p, pressure, norm_type="l2", degree_rise=0)
     self.listDict['p2' if is_tent else 'p']['list'].append(error)
     print("Normalized pressure error norm:", error/self.p_normalization_factor[0])
     self.listDict['pg2' if is_tent else 'pg']['list'].append(computed_gradient)
     if not is_tent:
         self.listDict['apg']['list'].append(self.analytic_gradient)
     self.listDict['pgE2' if is_tent else 'pgE']['list'].append(computed_gradient-self.analytic_gradient)
     self.listDict['pgEA2' if is_tent else 'pgEA']['list'].append(abs(computed_gradient-self.analytic_gradient))
     self.tc.end('errorP')
     if self.doSaveDiff:
         sol_pg_expr = Expression(("0", "0", "pg"), pg=self.analytic_gradient / self.pg_normalization_factor[0])
         # sol_pg = interpolate(sol_pg_expr, self.pgSpace)
         # plot(sol_p, title="sol")
         # plot(pressure, title="p")
         # plot(pressure - sol_p, interactive=True, title="diff")
         # exit()
         self.pFunction.assign(pressure-self.sol_p)
         self.fileDict['p2D' if is_tent else 'pD']['file'] << self.pFunction
コード例 #21
0
 def save_pressure(self, is_tent, pressure):
     super(Problem, self).save_pressure(is_tent, pressure)
     self.tc.start('computePG')
     # Report pressure gradient
     p_in = assemble((1.0 / self.area) * pressure * self.dsIn)
     p_out = assemble((1.0 / self.area) * pressure * self.dsOut)
     computed_gradient = (p_in - p_out) / 20.0
     # 20.0 is a length of a pipe NT should depend on mesh length (implement through metadata or function of mesh)
     self.tc.end('computePG')
     self.tc.start('errorP')
     error = errornorm(self.sol_p, pressure, norm_type="l2", degree_rise=0)
     self.listDict['p2' if is_tent else 'p']['list'].append(error)
     print("Normalized pressure error norm:",
           error / self.p_normalization_factor[0])
     self.listDict['pg2' if is_tent else 'pg']['list'].append(
         computed_gradient)
     if not is_tent:
         self.listDict['apg']['list'].append(self.analytic_gradient)
     self.listDict['pgE2' if is_tent else 'pgE']['list'].append(
         computed_gradient - self.analytic_gradient)
     self.listDict['pgEA2' if is_tent else 'pgEA']['list'].append(
         abs(computed_gradient - self.analytic_gradient))
     self.tc.end('errorP')
     if self.doSaveDiff:
         sol_pg_expr = Expression(
             ("0", "0", "pg"),
             pg=self.analytic_gradient / self.pg_normalization_factor[0])
         # sol_pg = interpolate(sol_pg_expr, self.pgSpace)
         # plot(sol_p, title="sol")
         # plot(pressure, title="p")
         # plot(pressure - sol_p, interactive=True, title="diff")
         # exit()
         self.pFunction.assign(pressure - self.sol_p)
         self.fileDict['p2D' if is_tent else 'pD']['file'] << self.pFunction
コード例 #22
0
def main(solver, N: int, dt: float, T: float, theta: float) -> Tuple[float, float, float, float]:
    """Run monodomain MMS."""
    mesh = UnitSquareMesh(N, N)
    time = Constant(0.0)
    lam = Constant(1.0)
    cell_model = NoCellModel()

    ac_str = "(8*pi*pi*lam*sin(t) + (lam + 1)*cos(t))*cos(2*pi*x[0])*cos(2*pi*x[1])/(lam + 1)"
    stimulus = Expression(ac_str, t=time, lam=lam, degree=3)

    parameters = solver.default_parameters()
    _solver = solver(mesh, time, 1.0, I_s=stimulus, parameters=parameters)

    vs0 = Function(_solver.V)
    vs_, vs = _solver.solution_fields()
    vs_.assign(vs0)

    for timestep, (v_, v) in _solver.solve(0, T, dt):
        continue

    v_exact = Expression(
        "sin(t)*cos(2*pi*x[0])*cos(2*pi*x[1])",
        t=T,
        degree=3
    )

    # compute errors
    # v, s = vs.split(deepcopy=True)
    v_error = errornorm(v_exact, v, "L2", degree_rise=2)
    return (v_error, mesh.hmin(), dt, T)
コード例 #23
0
def compute_errors(u_e, u):
    """Compute various measures of the error u - u_e, where
    u is a finite element Function and u_e is an Expression.

    Adapted from https://fenicsproject.org/pub/tutorial/html/._ftut1020.html
    """
    print('u_e', u_e.ufl_element().degree())
    # Get function space
    V = u.function_space()

    # Explicit computation of L2 norm
    error = (u - u_e)**2 * dl.dx
    E1 = np.sqrt(abs(dla.assemble(error)))

    # Explicit interpolation of u_e onto the same space as u
    u_e_ = dla.interpolate(u_e, V)
    error = (u - u_e_)**2 * dl.dx
    E2 = np.sqrt(abs(dla.assemble(error)))

    # Explicit interpolation of u_e to higher-order elements.
    # u will also be interpolated to the space Ve before integration
    Ve = dl.FunctionSpace(V.mesh(), 'P', 5)
    u_e_ = dla.interpolate(u_e, Ve)
    error = (u - u_e)**2 * dl.dx
    E3 = np.sqrt(abs(dla.assemble(error)))

    # Infinity norm based on nodal values
    u_e_ = dla.interpolate(u_e, V)
    E4 = abs(u_e_.vector().get_local() - u.vector().get_local()).max()

    # L2 norm
    E5 = dl.errornorm(u_e, u, norm_type='L2', degree_rise=3)

    # H1 seminorm
    E6 = dl.errornorm(u_e, u, norm_type='H10', degree_rise=3)

    # Collect error measures in a dictionary with self-explanatory keys
    errors = {
        'u - u_e': E1,
        'u - interpolate(u_e, V)': E2,
        'interpolate(u, Ve) - interpolate(u_e, Ve)': E3,
        'infinity norm (of dofs)': E4,
        'L2 norm': E5,
        'H10 seminorm': E6
    }

    return errors
コード例 #24
0
def compvperror(reffemp=None, vref=None, pref=None,
                curfemp=None, vcur=None, pcur=None):
    try:
        verf, perf = dts.expand_vp_dolfunc(vc=vref-vcur, pc=pref-pcur,
                                           zerodiribcs=True, **reffemp)
        verr = dolfin.norm(verf)
        perr = dolfin.norm(perf)
        # vreff, preff = dts.expand_vp_dolfunc(vc=vref, pc=pref, **reffemp)
        # vcurf, pcurf = dts.expand_vp_dolfunc(vc=vcur, pc=pcur, **curfemp)
        # verr = dolfin.norm(vreff - vcurf)
        # perr = dolfin.norm(preff - pcurf)
    except ValueError:  # obviously not the same FEM spaces
        vreff, preff = dts.expand_vp_dolfunc(vc=vref, pc=pref, **reffemp)
        vcurf, pcurf = dts.expand_vp_dolfunc(vc=vcur, pc=pcur, **curfemp)
        verr = dolfin.errornorm(vreff, vcurf)
        perr = dolfin.errornorm(preff, pcurf)
    return verr, perr
コード例 #25
0
def main(N: int, dt: float, T: float,
         theta: float) -> Tuple[float, float, float, float, float]:
    """Run bidomain MMA."""
    # Create data
    mesh = UnitSquareMesh(N, N)
    time = Constant(0.0)
    ac_str = "cos(t)*cos(2*pi*x[0])*cos(2*pi*x[1]) + 4*pi*pi*cos(2*pi*x[0])*cos(2*pi*x[1])*sin(t)"
    stimulus = Expression(ac_str, t=time, degree=5)
    M_i = 1.
    M_e = 1.0

    # Set-up solver
    parameters = BidomainSolver.default_parameters()
    parameters["theta"] = theta
    parameters["linear_solver_type"] = "direct"
    parameters["use_avg_u_constraint"] = True
    parameters["Chi"] = 1.0
    parameters["Cm"] = 1.0
    solver = BidomainSolver(mesh,
                            time,
                            M_i,
                            M_e,
                            I_s=stimulus,
                            parameters=parameters)

    # Define exact solution (Note: v is returned at end of time
    # interval(s), u is computed at somewhere in the time interval
    # depending on theta)
    v_exact = Expression("cos(2*pi*x[0])*cos(2*pi*x[1])*sin(t)", t=T, degree=3)
    u_exact = Expression("-cos(2*pi*x[0])*cos(2*pi*x[1])*sin(t)/2.0",
                         t=T - (1. - theta) * dt,
                         degree=3)

    # Define initial condition(s)
    v_, vu = solver.solution_fields()

    # Solve
    solutions = solver.solve(0, T, dt)
    for interval, fields in solutions:
        continue

    # Compute errors
    v, u = vu.split(deepcopy=True)[:2]
    v_error = errornorm(v_exact, v, "L2", degree_rise=2)
    u_error = errornorm(u_exact, u, "L2", degree_rise=2)
    return v_error, u_error, mesh.hmin(), dt, T
コード例 #26
0
def _check_space_order(problem, method):
    mesh_generator, solution, weak_F = problem()

    # Translate data into FEniCS expressions.
    fenics_sol = Expression(smp.prining.ccode(solution['value']),
                            degree=solution['degree'],
                            t=0.0
                            )

    # Create initial solution.
    theta0 = Expression(fenics_sol.cppcode,
                        degree=solution['degree'],
                        t=0.0,
                        cell=triangle
                        )

    # Estimate the error component in space.
    # Leave out too rough discretizations to avoid showing spurious errors.
    N = [2 ** k for k in range(2, 8)]
    dt = 1.0e-8
    Err = []
    H = []
    for n in N:
        mesh = mesh_generator(n)
        H.append(MPI.max(mesh.hmax()))
        V = FunctionSpace(mesh, 'CG', 3)
        # Create boundary conditions.
        fenics_sol.t = dt
        #bcs = DirichletBC(V, fenics_sol, 'on_boundary')
        # Create initial state.
        theta_approx = method(V,
                              weak_F,
                              theta0,
                              0.0, dt,
                              bcs=[solution],
                              tol=1.0e-12,
                              verbose=True
                              )
        # Compute the error.
        fenics_sol.t = dt
        Err.append(errornorm(fenics_sol, theta_approx)
                   / norm(fenics_sol, mesh=mesh)
                   )
        print('n: %d    error: %e' % (n, Err[-1]))

    from matplotlib import pyplot as pp
    # Compare with order 1, 2, 3 curves.
    for o in [2, 3, 4]:
        pp.loglog([H[0], H[-1]],
                  [Err[0], Err[0] * (H[-1] / H[0]) ** o],
                  color='0.5'
                  )
    # Finally, the actual data.
    pp.loglog(H, Err, '-o')
    pp.xlabel('h_max')
    pp.ylabel('||u-u_h|| / ||u||')
    pp.show()
    return
コード例 #27
0
ファイル: tools.py プロジェクト: BartoszJaroszkowski/FEISol
def error_calc(v, v_e, mesh, mesh_name, save_dir='errors.json'):
    try:
        with open(save_dir, 'r') as f:
            errors = json.load(f)
    except FileNotFoundError:
        errors = {}
    new_errors = {}
    v_e.t = 0.0
    v_int = interpolate(v_e, FunctionSpace(mesh, 'CG', 1))
    new_errors['Linf'] = norm(v.vector() - v_int.vector(), 'linf')
    new_errors['L2'] = errornorm(v_e, v, mesh=mesh, degree_rise=3)
    new_errors['H1'] = errornorm(v_e,
                                 v,
                                 norm_type='H1',
                                 mesh=mesh,
                                 degree_rise=3)
    errors[mesh_name] = new_errors
    with open(save_dir, 'w') as f:
        json.dump(errors, f)
コード例 #28
0
def _compute_errors(problem, mesh_sizes):
    mesh_generator, solution, f, cell_type = problem()

    max_degree = 20

    if solution['degree'] > max_degree:
        warnings.warn(('Expression degree (%r) > maximum degree (%d). '
                       'Truncating.')
                      % (solution['degree'], max_degree)
                      )
        degree = 20
    else:
        degree = solution['degree']

    sol = Expression((smp.printing.ccode(solution['value'][0]),
                      smp.printing.ccode(solution['value'][1])),
                     t=0.0,
                     degree=degree,
                     cell=cell_type
                     )

    errors = numpy.empty(len(mesh_sizes))
    hmax = numpy.empty(len(mesh_sizes))
    for k, mesh_size in enumerate(mesh_sizes):
        mesh, dx, ds = mesh_generator(mesh_size)
        hmax[k] = MPI.max(mpi_comm_world(), mesh.hmax())
        V = FunctionSpace(mesh, 'CG', 1)
        # TODO don't hardcode Mu, Sigma, ...
        phi_approx = mcyl.solve_maxwell(V, dx,
                                        Mu={0: 1.0},
                                        Sigma={0: 1.0},
                                        omega=1.0,
                                        f_list=[{0: f['value']}],
                                        convections={},
                                        tol=1.0e-12,
                                        bcs=None,
                                        compute_residuals=False,
                                        verbose=False
                                        )
        #plot(sol0, mesh=mesh, title='sol')
        #plot(phi_approx[0][0], title='approx')
        ##plot(fenics_sol - theta_approx, title='diff')
        #interactive()
        #exit()
        #
        errors[k] = errornorm(sol, phi_approx[0])

    # Compute the numerical order of convergence.
    order = numpy.empty(len(errors) - 1)
    for i in range(len(errors) - 1):
        order[i] = numpy.log(errors[i + 1] / errors[i]) \
            / numpy.log(hmax[i + 1] / hmax[i])

    return errors, order, hmax
コード例 #29
0
def _check_spatial_order(problem, method):
    mesh_generator, solution, weak_F = problem()

    # Translate data into FEniCS expressions.
    fenics_sol = Expression(sympy.printing.ccode(solution['value']),
                            degree=solution['degree'],
                            t=0.0)

    # Create initial solution.
    theta0 = Expression(fenics_sol.cppcode,
                        degree=solution['degree'],
                        t=0.0,
                        cell=triangle)

    # Estimate the error component in space.
    # Leave out too rough discretizations to avoid showing spurious errors.
    N = [2**k for k in range(2, 8)]
    dt = 1.0e-8
    Err = []
    H = []
    for n in N:
        mesh = mesh_generator(n)
        H.append(MPI.max(mesh.hmax()))
        V = FunctionSpace(mesh, 'CG', 5)
        # Create boundary conditions.
        fenics_sol.t = dt
        # bcs = DirichletBC(V, fenics_sol, 'on_boundary')
        # Create initial state.
        theta_approx = method(V,
                              weak_F,
                              theta0,
                              0.0,
                              dt,
                              bcs=[solution],
                              tol=1.0e-12,
                              verbose=True)
        # Compute the error.
        fenics_sol.t = dt
        Err.append(
            errornorm(fenics_sol, theta_approx) / norm(fenics_sol, mesh=mesh))
        print('n: %d    error: %e' % (n, Err[-1]))

    # Plot order curves for comparison.
    for order in [2, 3, 4]:
        plt.loglog([H[0], H[-1]], [Err[0], Err[0] * (H[-1] / H[0])**order],
                   color='0.5')
    # Finally, the actual data.
    plt.loglog(H, Err, '-o')
    plt.xlabel('h_max')
    plt.ylabel('||u-u_h|| / ||u||')
    plt.show()
    return
コード例 #30
0
def _compute_time_errors(problem, method, mesh_sizes, Dt, plot_error=False):
    mesh_generator, solution, ProblemClass, cell_type = problem()
    # Translate data into FEniCS expressions.
    fenics_sol = Expression(smp.printing.ccode(solution['value']),
                            degree=solution['degree'],
                            t=0.0,
                            cell=cell_type
                            )
    # Compute the problem
    errors = {'theta': numpy.empty((len(mesh_sizes), len(Dt)))}
    # Create initial state.
    # Deepcopy the expression into theta0. Specify the cell to allow for
    # more involved operations with it (e.g., grad()).
    theta0 = Expression(fenics_sol.cppcode,
                        degree=solution['degree'],
                        t=0.0,
                        cell=cell_type
                        )
    for k, mesh_size in enumerate(mesh_sizes):
        mesh = mesh_generator(mesh_size)
        V = FunctionSpace(mesh, 'CG', 1)
        theta_approx = Function(V)
        theta0p = project(theta0, V)
        stepper = method(ProblemClass(V))
        if plot_error:
            error = Function(V)
        for j, dt in enumerate(Dt):
            # TODO We are facing a little bit of a problem here, being the
            # fact that the time stepper only accept elements from V as u0.
            # In principle, though, this isn't necessary or required. We
            # could allow for arbitrary expressions here, but then the API
            # would need changing for problem.lhs(t, u).
            # Think about this.
            stepper.step(theta_approx, theta0p,
                         0.0, dt,
                         tol=1.0e-12,
                         verbose=False
                         )
            fenics_sol.t = dt
            #
            # NOTE
            # When using errornorm(), it is quite likely to see a good part
            # of the error being due to the spatial discretization.  Some
            # analyses "get rid" of this effect by (sometimes implicitly)
            # projecting the exact solution onto the discrete function
            # space.
            errors['theta'][k][j] = errornorm(fenics_sol, theta_approx)
            if plot_error:
                error.assign(project(fenics_sol - theta_approx, V))
                plot(error, title='error (dt=%e)' % dt)
                interactive()
    return errors, stepper.name, stepper.order
コード例 #31
0
def end_hook(x_, t, field_to_subspace, concentration_init,
             concentration_init_dev, surface_tension, interface_thickness,
             pf_init, pf_mobility_coeff, solutes, density, permittivity,
             viscosity, enable_NS, enable_PF, enable_EC, testing, **namespace):
    if testing:
        exprs = reference(**vars())

        output = "Final error norms:"
        for field in ["u", "phi", "c_p", "c_m", "V"]:
            f = df.project(x_[field], field_to_subspace[field].collapse())
            f_ref = exprs[field]
            output += " {} = {:e}".format(field, df.errornorm(f_ref, f, "L2"))
        info(output)
コード例 #32
0
 def ErrorCalculation(exact_sol,numerical_sol):
     #interpolate on the mesh
     es = df.interpolate(exact_sol,my_function_space_cls.V.sub(0).collapse())
     ns = df.interpolate(numerical_sol,my_function_space_cls.V.sub(0).collapse())
     #compute values at the vertex
     err_linf = np.max(np.abs(es.compute_vertex_values()- ns.compute_vertex_values()))
     #err_l2 = np.linalg.norm(es.compute_vertex_values()-ns.compute_vertex_values())
     err_l2 = df.errornorm(es,ns,"L2")#fenics inbuilt norm calculator
     max_l2= np.linalg.norm(es.compute_vertex_values())
     max_linf = np.max(np.abs(es.compute_vertex_values())) or 1
     normalised_err_l2= err_l2/max_linf
     normalised_err_linf = err_linf/max_linf
     return  normalised_err_l2, normalised_err_linf
コード例 #33
0
def main(solver, N: int, dt: float, T: float,
         theta: float) -> Tuple[float, float, float, float, float]:
    # Create cardiac model
    mesh = UnitSquareMesh(N, N)
    time = Constant(0.0)
    cell_model = NoCellModel()

    ac_str = "cos(t)*cos(2*pi*x[0])*cos(2*pi*x[1]) + 4*pow(pi, 2)*cos(2*pi*x[0])*cos(2*pi*x[1])*sin(t)"
    stimulus = Expression(ac_str, t=time, degree=5)

    ps = solver.default_parameters()
    ps["Chi"] = 1.0
    ps["Cm"] = 1.0
    _solver = solver(mesh, time, 1.0, 1.0, stimulus, parameters=ps)

    # Define exact solution (Note: v is returned at end of time
    # interval(s), u is computed at somewhere in the time interval
    # depending on theta)

    v_exact = Expression("cos(2*pi*x[0])*cos(2*pi*x[1])*sin(t)", t=T, degree=5)
    u_exact = Expression("-cos(2*pi*x[0])*cos(2*pi*x[1])*sin(t)/2.0",
                         t=T - (1 - theta) * dt,
                         degree=5)

    # Define initial condition(s)
    vs0 = Function(_solver.V)
    vs_, *_ = _solver.solution_fields()
    vs_.assign(vs0)

    # Solve
    for _, (vs_, vur) in _solver.solve(0, T, dt):
        continue

    # Compute errors
    v, u, *_ = vur.split(deepcopy=True)
    v_error = errornorm(v_exact, v, "L2", degree_rise=5)
    u_error = errornorm(u_exact, u, "L2", degree_rise=5)
    return v_error, u_error, mesh.hmin(), dt, T
コード例 #34
0
def _compute_errors(problem, mesh_sizes):
    mesh_generator, solution, f, cell_type = problem()

    if solution["degree"] > MAX_DEGREE:
        warnings.warn(
            "Expression degree ({}) > maximum degree ({}). Truncating.".format(
                solution["degree"], MAX_DEGREE))
        degree = MAX_DEGREE
    else:
        degree = solution["degree"]

    sol = Expression(
        (helpers.ccode(
            solution["value"][0]), helpers.ccode(solution["value"][1])),
        t=0.0,
        degree=degree,
        cell=cell_type,
    )

    errors = numpy.empty(len(mesh_sizes))
    hmax = numpy.empty(len(mesh_sizes))
    for k, mesh_size in enumerate(mesh_sizes):
        mesh, dx, _ = mesh_generator(mesh_size)
        hmax[k] = MPI.max(mpi_comm_world(), mesh.hmax())
        V = FunctionSpace(mesh, "CG", 1)
        # TODO don't hardcode Mu, Sigma, ...
        phi_approx = maxwell.solve(
            V,
            dx,
            Mu={0: 1.0},
            Sigma={0: 1.0},
            omega=1.0,
            f_list=[{
                0: f["value"]
            }],
            f_degree=f["degree"],
            convections={},
            tol=1.0e-12,
            bcs=None,
            verbose=False,
        )
        # plot(sol0, mesh=mesh, title='sol')
        # plot(phi_approx[0][0], title='approx')
        # #plot(fenics_sol - theta_approx, title='diff')
        # interactive()
        # exit()
        #
        errors[k] = errornorm(sol, phi_approx[0])

    return errors, hmax
コード例 #35
0
    def test_unconstrained_newton_solver(self):
        L, nelem = 1, 201

        mesh = dl.IntervalMesh(nelem, -L, L)
        Vh = dl.FunctionSpace(mesh, "CG", 2)

        forcing = dl.Constant(1)

        dirichlet_bcs = [dl.DirichletBC(Vh, dl.Constant(0.0), on_any_boundary)]
        bc0 = dl.DirichletBC(Vh, dl.Constant(0.0), on_any_boundary)

        uh = dl.TrialFunction(Vh)
        vh = dl.TestFunction(Vh)
        F = dl.inner((1 + uh**2) * dl.grad(uh),
                     dl.grad(vh)) * dl.dx - forcing * vh * dl.dx
        u = dl.Function(Vh)
        F = dl.action(F, u)
        parameters = {
            "symmetric": True,
            "newton_solver": {
                # "relative_tolerance": 1e-8,
                "report": True,
                "linear_solver": "cg",
                "preconditioner": "petsc_amg"
            }
        }
        dl.solve(F == 0, u, dirichlet_bcs, solver_parameters=parameters)
        # dl.plot(uh)
        # plt.show()

        u_newton = dl.Function(Vh)
        F = dl.inner((1 + uh**2) * dl.grad(uh),
                     dl.grad(vh)) * dl.dx - forcing * vh * dl.dx
        F = dl.action(F, u_newton)
        # Compute Jacobian
        J = dl.derivative(F, u_newton, uh)
        unconstrained_newton_solve(
            F,
            J,
            u_newton,
            dirichlet_bcs=dirichlet_bcs,
            bc0=bc0,
            # linear_solver='PETScLU',opts=dict())
            linear_solver=None,
            opts=dict())
        error = dl.errornorm(u, u_newton, mesh=mesh)
        assert error < 1e-15
コード例 #36
0
 def save_pressure(self, is_tent, pressure):
     super(Problem, self).save_pressure(is_tent, pressure)
     self.tc.start('computePG')
     # Report pressure gradient
     p_in = assemble((1.0/self.area) * pressure * self.dsIn)
     p_out = assemble((1.0/self.area) * pressure * self.dsOut)
     computed_gradient = (p_out - p_in)/20.0
     # 20.0 is a length of a pipe NT should depend on mesh length (implement throuhg metadata or function of mesh)
     self.tc.end('computePG')
     self.tc.start('analyticP')
     analytic_gradient = womersleyBC.analytic_pressure_grad(self.factor, self.actual_time)
     analytic_pressure = womersleyBC.analytic_pressure(self.factor, self.actual_time)
     self.sol_p = interpolate(analytic_pressure, self.pSpace)  # NT move to update_time
     if not is_tent:
         self.last_analytic_pressure_norm = norm(self.sol_p, norm_type='L2')
         self.listDict['ap_norm']['list'].append(self.last_analytic_pressure_norm)
     self.tc.end('analyticP')
     self.tc.start('errorP')
     error = errornorm(self.sol_p, pressure, norm_type="l2", degree_rise=0)
     self.listDict['p2' if is_tent else 'p']['list'].append(error)
     print("Normalized pressure error norm:", error/self.p_normalization_factor[0])
     self.listDict['pg2' if is_tent else 'pg']['list'].append(computed_gradient)
     if not is_tent:
         self.listDict['apg']['list'].append(analytic_gradient)
     self.listDict['pgE2' if is_tent else 'pgE']['list'].append(computed_gradient-analytic_gradient)
     self.listDict['pgEA2' if is_tent else 'pgEA']['list'].append(abs(computed_gradient-analytic_gradient))
     if self.isWholeSecond:
         for key in (['pgE2', 'p2'] if is_tent else ['pgE', 'p']):
             self.listDict[key]['slist'].append(
                 sqrt(sum([i*i for i in self.listDict[key]['list'][self.N0:self.N1]])/self.stepsInSecond))
     self.tc.end('errorP')
     if self.doSaveDiff:
         sol_pg_expr = Expression(("0", "0", "pg"), pg=analytic_gradient / self.pg_normalization_factor[0])
         # sol_pg = interpolate(sol_pg_expr, self.pgSpace)
         # plot(sol_p, title="sol")
         # plot(pressure, title="p")
         # plot(pressure - sol_p, interactive=True, title="diff")
         # exit()
         self.pFunction.assign(pressure-self.sol_p)
         self.fileDict['p2D' if is_tent else 'pD']['file'] << self.pFunction
コード例 #37
0
    def test_outopa_workingconfig(self):
        """ The innerproducts that assemble the output operator

        are accurately sampled for this parameter set (NV=25, NY=5)"""

        NV = 25 
        NY = 5

        mesh = dolfin.UnitSquareMesh(NV, NV)
        V = dolfin.VectorFunctionSpace(mesh, "CG", 2)

        exv = dolfin.Expression(('1', '1'))
        testv = dolfin.interpolate(exv, V)

        odcoo = dict(xmin=0.45,
                     xmax=0.55,
                     ymin=0.6,
                     ymax=0.8)

        # check the C
        MyC, My = cou.get_mout_opa(odcoo=odcoo, V=V, NY=NY, NV=NV)

        # signal space
        ymesh = dolfin.IntervalMesh(NY - 1, odcoo['ymin'], odcoo['ymax'])

        Y = dolfin.FunctionSpace(ymesh, 'CG', 1)

        y1 = dolfin.Function(Y)
        y2 = dolfin.Function(Y)

        testvi = testv.vector().array()
        testy = spsla.spsolve(My, MyC * testvi)

        y1 = dolfin.Expression('1')
        y1 = dolfin.interpolate(y1, Y)

        y2 = dolfin.Function(Y)
        y2.vector().set_local(testy[NY:])

        self.assertTrue(dolfin.errornorm(y2, y1) < 1e-14)
コード例 #38
0
def _compute_errors(problem, mesh_sizes, stabilization):
    mesh_generator, solution, f, cell_type, kappa, rho, cp, conv = problem()

    if solution["degree"] > MAX_DEGREE:
        warnings.warn(
            "Expression degree ({}) > maximum degree ({}). Truncating.".format(
                solution["degree"], MAX_DEGREE
            )
        )
        degree = MAX_DEGREE
    else:
        degree = solution["degree"]

    sol = Expression(
        helpers.ccode(solution["value"]), t=0.0, degree=degree, cell=cell_type
    )

    errors = numpy.empty(len(mesh_sizes))
    hmax = numpy.empty(len(mesh_sizes))
    for k, mesh_size in enumerate(mesh_sizes):
        mesh = mesh_generator(mesh_size)
        hmax[k] = MPI.max(mpi_comm_world(), mesh.hmax())
        Q = FunctionSpace(mesh, "CG", 1)
        prob = heat.Heat(
            Q,
            kappa=kappa,
            rho=rho,
            cp=cp,
            convection=conv,
            source=f["value"],
            dirichlet_bcs=[DirichletBC(Q, 0.0, "on_boundary")],
            stabilization=stabilization,
        )
        phi_approx = prob.solve_stationary()
        errors[k] = errornorm(sol, phi_approx)

    return errors, hmax
コード例 #39
0
ファイル: playground.py プロジェクト: lelou6666/pySDC
    description['transfer_params'] = tparams

    # quickly generate block of steps
    MS = mp.generate_steps(num_procs,sparams,description)

    # setup parameters "in time"
    t0 = MS[0].levels[0].prob.t0
    dt = 0.5
    Tend = 8*dt

    # get initial values on finest level
    P = MS[0].levels[0].prob
    uinit = P.u_exact(t0)

    # call main function to get things done...
    uend,stats = mp.run_pfasst(MS,u0=uinit,t0=t0,dt=dt,Tend=Tend)

    # df.plot(uend.values,interactive=True)

    # compute exact solution and compare
    uex = P.u_exact(Tend)

    print('(classical) error at time %s: %s' %(Tend,abs(uex-uend)/abs(uex)))


    uex = df.Expression('sin(a*x[0]) * cos(t)',a=np.pi,t=Tend)
    print('(fenics-style) error at time %s: %s' %(Tend,df.errornorm(uex,uend.values)))

    extract_stats = grep_stats(stats,iter=-1,type='residual')
    sortedlist_stats = sort_stats(extract_stats,sortby='step')
    print(extract_stats,sortedlist_stats)
コード例 #40
0
def halfexp_euler_nseind2(Mc, MP, Ac, BTc, Bc, fvbc, fpbc, PrP, TsP,
                          vp_init=None):
    """halfexplicit euler for the NSE in index 2 formulation
    """
    #
    #
    # Basic Eqn:
    #
    # 1/dt*M  -B.T    q+       1/dt*M*qc - K(qc) + fc
    #    B        * pc   =   g
    #
    #

    Nts, t0, tE, dt, Nv = init_time_stepping(PrP, TsP)

    tcur = t0

    MFac = dt
    CFac = 1  # /dt
    # PFac = -1  # -1 for symmetry (if CFac==1)
    PFacI = -1./dt

    dtstrdct = dict(prefix=TsP.svdatapath, method=2, N=PrP.N,
                    tolcor=TsP.TolCorB,
                    nu=PrP.nu, Nts=TsP.Nts, tol=TsP.linatol, te=TsP.tE)
    cdatstr = get_dtstr(t=t0, **dtstrdct)
    try:
        np.load(cdatstr + '.npy')
        print 'loaded data from ', cdatstr, ' ...'
    except IOError:
        np.save(cdatstr, vp_init)
        print 'saving to ', cdatstr, ' ...'

    v, p = expand_vp_dolfunc(PrP, vp=vp_init, vc=None, pc=None)
    TsP.UpFiles.u_file << v, tcur
    TsP.UpFiles.p_file << p, tcur
    Bcc, BTcc, MPc, fpbcc, vp_init, Npc = pinthep(Bc, BTc, MP, fpbc,
                                                  vp_init, PrP.Pdof)

    IterAv = MFac*sps.hstack([1.0/dt*Mc + Ac, PFacI*(-1)*BTcc])
    IterAp = CFac*sps.hstack([Bcc, sps.csr_matrix((Npc, Npc))])
    IterA = sps.vstack([IterAv, IterAp])
    if TsP.linatol == 0:
        IterAfac = spsla.factorized(IterA)

    vp_old = vp_init
    vp_old = np.vstack([vp_init[:Nv], 1./PFacI*vp_init[Nv:]])
    vp_oldold = vp_old
    ContiRes, VelEr, PEr, TolCorL = [], [], [], []

    # Mvp = sps.csr_matrix(sps.block_diag((Mc, MPc)))
    # Mvp = sps.eye(Mc.shape[0] + MPc.shape[0])
    # Mvp = None

    # M matrix for the minres routine
    # M accounts for the FEM discretization

    Mcfac = spsla.splu(Mc)
    MPcfac = spsla.splu(MPc)

    def _MInv(vp):
        # v, p = vp[:Nv, ], vp[Nv:, ]
        # lsv = krypy.linsys.LinearSystem(Mc, v, self_adjoint=True)
        # lsp = krypy.linsys.LinearSystem(MPc, p, self_adjoint=True)
        # Mv = (krypy.linsys.Cg(lsv, tol=1e-14)).xk
        # Mp = (krypy.linsys.Cg(lsp, tol=1e-14)).xk
        v, p = vp[:Nv, ], vp[Nv:, ]
        Mv = np.atleast_2d(Mcfac.solve(v.flatten())).T
        Mp = np.atleast_2d(MPcfac.solve(p.flatten())).T
        return np.vstack([Mv, Mp])

    MInv = spsla.LinearOperator(
        (Nv + Npc,
         Nv + Npc),
        matvec=_MInv,
        dtype=np.float32)

    def ind2_ip(vp1, vp2):
        """

        for applying the fem inner product
        """
        v1, v2 = vp1[:Nv, ], vp2[:Nv, ]
        p1, p2 = vp1[Nv:, ], vp2[Nv:, ]
        return mass_fem_ip(v1, v2, Mcfac) + mass_fem_ip(p1, p2, MPcfac)

    inikryupd = TsP.inikryupd
    iniiterfac = TsP.iniiterfac  # the first krylov step needs more maxiter

    for etap in range(1, TsP.NOutPutPts + 1):
        for i in range(Nts / TsP.NOutPutPts):
            cdatstr = get_dtstr(t=tcur+dt, **dtstrdct)
            try:
                vp_next = np.load(cdatstr + '.npy')
                print 'loaded data from ', cdatstr, ' ...'
                vp_next = np.vstack([vp_next[:Nv], 1./PFacI*vp_next[Nv:]])
                vp_oldold = vp_old
                vp_old = vp_next
                if tcur == dt+dt:
                    iniiterfac = 1  # fac only in the first Krylov Call
            except IOError:
                print 'computing data for ', cdatstr, ' ...'
                ConV = dts.get_convvec(u0_dolfun=v, V=PrP.V)
                CurFv = dts.get_curfv(PrP.V, PrP.fv, PrP.invinds, tcur)

                Iterrhs = np.vstack([MFac*1.0/dt*Mc*vp_old[:Nv, ],
                                     np.zeros((Npc, 1))]) +\
                    np.vstack([MFac*(fvbc + CurFv - ConV[PrP.invinds, ]),
                               CFac*fpbcc])

                if TsP.linatol == 0:
                    # ,vp_old,tol=TsP.linatol)
                    vp_new = IterAfac(Iterrhs.flatten())
                    # vp_new = spsla.spsolve(IterA, Iterrhs)
                    vp_old = np.atleast_2d(vp_new).T
                    TolCor = 0

                else:
                    if inikryupd and tcur == t0:
                        print '\n1st step direct solve to initialize krylov\n'
                        vp_new = spsla.spsolve(IterA, Iterrhs)
                        vp_old = np.atleast_2d(vp_new).T
                        TolCor = 0
                        inikryupd = False  # only once !!
                    else:
                        if TsP.TolCorB:
                            NormRhsInd2 = \
                                np.sqrt(ind2_ip(Iterrhs, Iterrhs))[0][0]
                            TolCor = 1.0 / np.max([NormRhsInd2, 1])
                        else:
                            TolCor = 1.0

                        curls = krypy.linsys.LinearSystem(IterA, Iterrhs,
                                                          M=MInv)

                        tstart = time.time()

                        # extrapolating the initial value
                        upv = (vp_old - vp_oldold)

                        ret = krypy.linsys.\
                            RestartedGmres(curls, x0=vp_old + upv,
                                           tol=TolCor*TsP.linatol,
                                           maxiter=iniiterfac*TsP.MaxIter,
                                           max_restarts=100)

                        # ret = krypy.linsys.\
                        #     Minres(curls, maxiter=20*TsP.MaxIter,
                        #            x0=vp_old + upv, tol=TolCor*TsP.linatol)
                        tend = time.time()
                        vp_oldold = vp_old
                        vp_old = ret.xk

                        print ('Needed {0} of max {4}*{1} iterations: ' +
                               'final relres = {2}\n TolCor was {3}').\
                            format(len(ret.resnorms), TsP.MaxIter,
                                   ret.resnorms[-1], TolCor, iniiterfac)
                        print 'Elapsed time {0}'.format(tend - tstart)
                        iniiterfac = 1  # fac only in the first Krylov Call

                np.save(cdatstr, np.vstack([vp_old[:Nv],
                                            PFacI*vp_old[Nv:]]))

            vc = vp_old[:Nv, ]
            print 'Norm of current v: ', np.linalg.norm(vc)
            pc = PFacI*vp_old[Nv:, ]

            v, p = expand_vp_dolfunc(PrP, vp=None, vc=vc, pc=pc)

            tcur += dt

            # the errors
            vCur, pCur = PrP.v, PrP.p
            try:
                vCur.t = tcur
                pCur.t = tcur - dt

                ContiRes.append(comp_cont_error(v, fpbc, PrP.Q))
                VelEr.append(errornorm(vCur, v))
                PEr.append(errornorm(pCur, p))
                TolCorL.append(TolCor)
            except AttributeError:
                ContiRes.append(0)
                VelEr.append(0)
                PEr.append(0)
                TolCorL.append(0)

        print '%d of %d time steps completed ' % (etap*Nts/TsP.NOutPutPts, Nts)

        if TsP.ParaviewOutput:
            TsP.UpFiles.u_file << v, tcur
            TsP.UpFiles.p_file << p, tcur

    TsP.Residuals.ContiRes.append(ContiRes)
    TsP.Residuals.VelEr.append(VelEr)
    TsP.Residuals.PEr.append(PEr)
    TsP.TolCor.append(TolCorL)

    return
コード例 #41
0
ファイル: crucible.py プロジェクト: garethcmurphy/maelstrom
    def __init__(self):
        import os
        from dolfin import Mesh, MeshFunction, SubMesh, SubDomain, \
            FacetFunction, DirichletBC, dot, grad, FunctionSpace, \
            MixedFunctionSpace, Expression, FacetNormal, pi, Function, \
            Constant, TestFunction, MPI, mpi_comm_world, File
        import numpy
        import warnings

        from maelstrom import heat_cylindrical as cyl_heat
        from maelstrom import materials_database as md

        GMSH_EPS = 1.0e-15

        current_path = os.path.dirname(os.path.realpath(__file__))
        base = os.path.join(
            current_path,
            '../../meshes/2d/crucible-with-coils'
            )
        self.mesh = Mesh(base + '.xml')
        self.subdomains = MeshFunction('size_t',
                                       self.mesh,
                                       base + '_physical_region.xml'
                                       )

        self.subdomain_materials = {
            1: md.get_material('porcelain'),
            2: md.get_material('argon'),
            3: md.get_material('GaAs (solid)'),
            4: md.get_material('GaAs (liquid)'),
            27: md.get_material('air')
            }

        # coils
        for k in range(5, 27):
            self.subdomain_materials[k] = md.get_material('graphite EK90')

        # Define the subdomains which together form a single coil.
        self.coil_domains = [
            [5, 6, 7, 8, 9],
            [10, 11, 12, 13, 14],
            [15, 16, 17, 18, 19],
            [20, 21, 22, 23],
            [24, 25, 26]
            ]

        self.wpi = 4
        # http://fenicsproject.org/qa/2026/submesh-workaround-for-parallel-computation
        submesh_parallel_bug_fixed = False
        if submesh_parallel_bug_fixed:
            submesh_workpiece = SubMesh(self.mesh, self.subdomains, self.wpi)
        else:
            # To get the mesh in parallel, we need to read it in from a file.
            # Writing out can only happen in serial mode, though. :/
            base = os.path.join(current_path,
                                '../../meshes/2d/crucible-with-coils-submesh'
                                )
            filename = base + '.xml'
            if not os.path.isfile(filename):
                warnings.warn(
                    'Submesh file \'%s\' does not exist. Creating... '
                    % filename
                    )
                if MPI.size(mpi_comm_world()) > 1:
                    raise RuntimeError(
                        'Can only write submesh in serial mode.'
                        )
                submesh_workpiece = \
                    SubMesh(self.mesh, self.subdomains, self.wpi)
                output_stream = File(filename)
                output_stream << submesh_workpiece
            # Read the mesh
            submesh_workpiece = Mesh(base + '.xml')

        coords = submesh_workpiece.coordinates()
        ymin = min(coords[:, 1])
        ymax = max(coords[:, 1])

        # Find the top right point.
        k = numpy.argmax(numpy.sum(coords, 1))
        topright = coords[k, :]

        # Initialize mesh function for boundary domains
        class Left(SubDomain):
            def inside(self, x, on_boundary):
                # Explicitly exclude the lowest and the highest point of the
                # symmetry axis.
                # It is necessary for the consistency of the pressure-Poisson
                # system in the Navier-Stokes solver that the velocity is
                # exactly 0 at the boundary r>0. Hence, at the corner points
                # (r=0, melt-crucible, melt-crystal) we must enforce u=0
                # already and cannot have a component in z-direction.
                return on_boundary \
                    and x[0] < GMSH_EPS \
                    and x[1] < ymax - GMSH_EPS \
                    and x[1] > ymin + GMSH_EPS

        class Crucible(SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary \
                    and ((x[0] > GMSH_EPS and x[1] < ymax - GMSH_EPS)
                         or (x[0] > topright[0] - GMSH_EPS
                             and x[1] > topright[1] - GMSH_EPS)
                         or (x[0] < GMSH_EPS and x[1] < ymin + GMSH_EPS)
                         )

        # At the top right part (boundary melt--gas), slip is allowed, so only
        # n.u=0 is enforced. Very weirdly, the PPE is consistent if and only if
        # the end points of UpperRight are in UpperRight. This contrasts
        # Left(), where the end points must NOT belong to Left().  Judging from
        # the experiments, these settings do the right thing.
        # TODO try to better understand the PPE system/dolfin's boundary
        # settings
        class Upper(SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary \
                    and x[1] > ymax - GMSH_EPS

        class UpperRight(SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary \
                    and x[1] > ymax - GMSH_EPS \
                    and x[0] > 0.038 - GMSH_EPS

        # The crystal boundary is taken to reach up to 0.038 where the
        # Dirichlet boundary data is about the melting point of the crystal,
        # 1511K. This setting gives pretty acceptable results when there is no
        # convection except the one induced by buoyancy. Is there is any more
        # stirring going on, though, the end point of the crystal with its
        # fixed temperature of 1511K might be the hottest point globally. This
        # looks rather unphysical.
        # TODO check out alternatives
        class UpperLeft(SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary \
                    and x[1] > ymax - GMSH_EPS \
                    and x[0] < 0.038 + GMSH_EPS

        left = Left()
        crucible = Crucible()
        upper_left = UpperLeft()
        upper_right = UpperRight()

        self.wp_boundaries = FacetFunction('size_t', submesh_workpiece)
        self.wp_boundaries.set_all(0)
        left.mark(self.wp_boundaries, 1)
        crucible.mark(self.wp_boundaries, 2)
        upper_right.mark(self.wp_boundaries, 3)
        upper_left.mark(self.wp_boundaries, 4)

        if DEBUG:
            from dolfin import plot, interactive
            plot(self.wp_boundaries, title='Boundaries')
            interactive()

        submesh_boundary_indices = {
            'left': 1,
            'crucible': 2,
            'upper right': 3,
            'upper left': 4
            }

        # Boundary conditions for the velocity.
        #
        # [1] Incompressible flow and the finite element method; volume two;
        #     Isothermal Laminar Flow;
        #     P.M. Gresho, R.L. Sani;
        #
        # For the choice of function space, [1] says:
        #     "In 2D, the triangular elements P_2^+P_1 and P_2^+P_{-1} are very
        #      good [...]. [...] If you wish to avoid bubble functions on
        #      triangular elements, P_2P_1 is not bad, and P_2(P_1+P_0) is even
        #      better [...]."
        #
        # It turns out that adding the bubble space significantly hampers the
        # convergence of the Stokes solver and also considerably increases the
        # time it takes to construct the Jacobian matrix of the Navier--Stokes
        # problem if no optimization is applied.
        V = FunctionSpace(submesh_workpiece, 'CG', 2)
        with_bubbles = False
        if with_bubbles:
            V += FunctionSpace(submesh_workpiece, 'B', 3)
        self.W = MixedFunctionSpace([V, V, V])

        self.u_bcs = [
            DirichletBC(self.W,
                        Expression(
                            ('0.0', '0.0', '-2*pi*x[0] * 5.0/60.0'),
                            degree=1
                            ),
                        #(0.0, 0.0, 0.0),
                        crucible),
            DirichletBC(self.W.sub(0), 0.0, left),
            DirichletBC(self.W.sub(2), 0.0, left),
            # Make sure that u[2] is 0 at r=0.
            DirichletBC(self.W,
                        Expression(
                            ('0.0', '0.0', '2*pi*x[0] * 5.0/60.0'),
                            degree=1
                            ),
                        upper_left),
            DirichletBC(self.W.sub(1), 0.0, upper_right),
            ]
        self.p_bcs = []

        self.P = FunctionSpace(submesh_workpiece, 'CG', 1)

        # Boundary conditions for heat equation.
        self.Q = FunctionSpace(submesh_workpiece, 'CG', 2)
        # Dirichlet.
        # This is a bit of a tough call since the boundary conditions need to
        # be read from a Tecplot file here.
        import tecplot_reader
        filename = os.path.join(
            os.path.dirname(os.path.realpath(__file__)),
            'data/crucible-boundary.dat'
            )
        data = tecplot_reader.read(filename)
        RZ = numpy.c_[data['ZONE T']['node data']['r'],
                      data['ZONE T']['node data']['z']
                      ]
        T_vals = data['ZONE T']['node data']['temp. [K]']

        class TecplotDirichletBC(Expression):
            # TODO specify degree
            def eval(self, value, x):
                # Find on which edge x sits, and raise exception if it doesn't.
                edge_found = False
                for edge in data['ZONE T']['element data']:
                    # Given a point X and an edge X0--X1,
                    #
                    #     (1 - theta) X0 + theta X1,
                    #
                    # the minimum distance is assumed for
                    #
                    #    argmin_theta ||(1-theta) X0  + theta X1 - X||^2
                    #    = <X1 - X0, X - X0> / ||X1 - X0||^2.
                    #
                    # If the distance is 0 and 0<=theta<=1, we found the edge.
                    #
                    # Note that edges are 1-based in Tecplot.
                    X0 = RZ[edge[0] - 1]
                    X1 = RZ[edge[1] - 1]
                    theta = numpy.dot(X1-X0, x-X0) / numpy.dot(X1-X0, X1-X0)
                    diff = (1.0-theta)*X0 + theta*X1 - x
                    if numpy.dot(diff, diff) < 1.0e-10 and \
                            0.0 <= theta and theta <= 1.0:
                        # Linear interpolation of the temperature value.
                        value[0] = (1.0-theta) * T_vals[edge[0]-1] \
                                 + theta       * T_vals[edge[1]-1]
                        edge_found = True
                        break
                # This class is supposed to be used for Dirichlet boundary
                # conditions. For some reason, FEniCS also evaluates
                # DirichletBC objects at coordinates which do not sit on the
                # boundary, see
                # <http://fenicsproject.org/qa/1033/dirichletbc-expressions-evaluated-away-from-the-boundary>.
                # The assigned values have no meaning though, so not assigning
                # values[0] here is okay.
                #
                #from matplotlib import pyplot as pp
                #pp.plot(x[0], x[1], 'xg')
                if not edge_found:
                    value[0] = 0.0
                    warnings.warn('Coordinate (%e, %e) doesn\'t sit on edge.'
                                  % (x[0], x[1]))
                    #pp.plot(RZ[:, 0], RZ[:, 1], '.k')
                    #pp.plot(x[0], x[1], 'xr')
                    #pp.show()
                    #raise RuntimeError('Input coordinate '
                    #                   '%r is not on boundary.' % x)
                return

        tecplot_dbc = TecplotDirichletBC()
        self.theta_bcs_d = [
            DirichletBC(self.Q, tecplot_dbc, upper_left)
            ]
        theta_bcs_d_strict = [
            DirichletBC(self.Q, tecplot_dbc, upper_right),
            DirichletBC(self.Q, tecplot_dbc, crucible),
            DirichletBC(self.Q, tecplot_dbc, upper_left)
            ]

        # Neumann
        dTdr_vals = data['ZONE T']['node data']['dTempdx [K/m]']
        dTdz_vals = data['ZONE T']['node data']['dTempdz [K/m]']

        class TecplotNeumannBC(Expression):
            # TODO specify degree
            def eval(self, value, x):
                # Same problem as above: This expression is not only evaluated
                # at boundaries.
                for edge in data['ZONE T']['element data']:
                    X0 = RZ[edge[0] - 1]
                    X1 = RZ[edge[1] - 1]
                    theta = numpy.dot(X1-X0, x-X0) / numpy.dot(X1-X0, X1-X0)
                    dist = numpy.linalg.norm((1-theta)*X0 + theta*X1 - x)
                    if dist < 1.0e-5 and 0.0 <= theta and theta <= 1.0:
                        value[0] = (1-theta) * dTdr_vals[edge[0]-1] \
                            + theta * dTdr_vals[edge[1]-1]
                        value[1] = (1-theta) * dTdz_vals[edge[0]-1] \
                            + theta * dTdz_vals[edge[1]-1]
                        break
                return

            def value_shape(self):
                return (2,)

        tecplot_nbc = TecplotNeumannBC()
        n = FacetNormal(self.Q.mesh())
        self.theta_bcs_n = {
            submesh_boundary_indices['upper right']: dot(n, tecplot_nbc),
            submesh_boundary_indices['crucible']: dot(n, tecplot_nbc)
            }
        self.theta_bcs_r = {}

        # It seems that the boundary conditions from above are inconsistent in
        # that solving with Dirichlet overall and mixed Dirichlet-Neumann give
        # different results; the value *cannot* correspond to one solution.
        # From looking at the solutions, the pure Dirichlet setting appears
        # correct, so extract the Neumann values directly from that solution.
        zeta = TestFunction(self.Q)

        theta_reference = Function(self.Q, name='temperature (Dirichlet)')
        theta_reference.vector()[:] = 0.0

        # Solve the *quasilinear* PDE (coefficients may depend on theta).
        # This is to avoid setting a fixed temperature for the coefficients.

        # Get material parameters
        wp_material = self.subdomain_materials[self.wpi]
        if isinstance(wp_material.specific_heat_capacity, float):
            cp = wp_material.specific_heat_capacity
        else:
            cp = wp_material.specific_heat_capacity(theta_reference)
        if isinstance(wp_material.density, float):
            rho = wp_material.density
        else:
            rho = wp_material.density(theta_reference)
        if isinstance(wp_material.thermal_conductivity, float):
            k = wp_material.thermal_conductivity
        else:
            k = wp_material.thermal_conductivity(theta_reference)

        reference_problem = cyl_heat.HeatCylindrical(
            self.Q, theta_reference,
            zeta,
            b=Constant((0.0, 0.0, 0.0)),
            kappa=k,
            rho=rho,
            cp=cp,
            source=Constant(0.0),
            dirichlet_bcs=theta_bcs_d_strict
            )

        from dolfin import solve
        solve(reference_problem.F0 == 0,
              theta_reference,
              bcs=theta_bcs_d_strict
              )

        # Create equivalent boundary conditions from theta_reference. This
        # makes sure that the potentially expensive Expression evaluation in
        # theta_bcs_* is replaced by something reasonably cheap.
        for k, bc in enumerate(self.theta_bcs_d):
            self.theta_bcs_d[k] = DirichletBC(bc.function_space(),
                                              theta_reference,
                                              bc.domain_args[0]
                                              )
        # Adapt Neumann conditions.
        n = FacetNormal(self.Q.mesh())
        for k in self.theta_bcs_n:
            self.theta_bcs_n[k] = dot(n, grad(theta_reference))

        if DEBUG:
            # Solve the heat equation with the mixed Dirichlet-Neumann
            # boundary conditions and compare it to the Dirichlet-only
            # solution.
            theta_new = Function(
                self.Q,
                name='temperature (Neumann + Dirichlet)'
                )
            from dolfin import Measure
            ds_workpiece = Measure('ds')[self.wp_boundaries]
            problem_new = cyl_heat.HeatCylindrical(
                self.Q, theta_new,
                zeta,
                b=Constant((0.0, 0.0, 0.0)),
                kappa=k,
                rho=rho,
                cp=cp,
                source=Constant(0.0),
                dirichlet_bcs=self.theta_bcs_d,
                neumann_bcs=self.theta_bcs_n,
                ds=ds_workpiece
                )

            from dolfin import solve
            solve(problem_new.F0 == 0,
                  theta_new,
                  bcs=problem_new.dirichlet_bcs
                  )
            from dolfin import plot, interactive, errornorm
            print('||theta_new - theta_ref|| = %e'
                  % errornorm(theta_new, theta_reference)
                  )
            plot(theta_reference)
            plot(theta_new)
            plot(
                theta_reference - theta_new,
                title='theta_ref - theta_new'
                )
            interactive()

        #omega = 2 * pi * 10.0e3
        self.omega = 2 * pi * 300.0

        return
コード例 #42
0
ファイル: test_fenics_operator.py プロジェクト: SpuqTeam/spuq
def teXXXst_fenics_vector():
#    quad_degree = 13
#    dolfin.parameters["form_compiler"]["quadrature_degree"] = quad_degree
    pi = 3.14159265358979323
    k1, k2 = 2, 3
    EV = pi * pi * (k1 * k1 + k2 * k2)
    N = 11
    degree = 1
    mesh = UnitSquare(N, N)
    fs = FunctionSpace(mesh, "CG", degree)
    ex = Expression("A*sin(k1*pi*x[0])*sin(k2*pi*x[1])", k1=k1, k2=k2, A=1.0)

    x = FEniCSVector(interpolate(ex, fs))
#    print "x.coeff", x.coeffs.array()

    ex.A = EV
    b_ex = assemble_rhs(ex, fs)
    bexg = interpolate(ex, fs)

#    print b_ex.array()
#    print b_ex.array() / (2 * pi * pi * x.coeffs.array())

    Afe = assemble_lhs(Expression('1'), fs)

    # apply discrete operator on (interpolated) x
    A = FEniCSOperator(Afe, x.basis)
    b = A * x

    # evaluate solution for eigenfunction rhs
    if False:
        b_num = Function(fs)
        solve(A, b_num.vector(), b_ex)
        bnv = A * b_num.vector()
        b3 = Function(fs, bnv / EV)

    np.set_printoptions(threshold='nan', suppress=True)
    print b.coeffs.array()
    print np.abs((b_ex.array() - b.coeffs.array()) / np.max(b_ex.array()))
    print np.max(np.abs((b_ex.array() - b.coeffs.array()) / np.max(b_ex.array())))
    #print b_ex.array() / (M * interpolate(ex1, fs).vector()).array()

#    #assert_array_almost_equal(b.coeffs, b_ex.coeffs)


    b2 = Function(fs, b_ex.copy())
    bg = Function(fs, b_ex.copy())
    b2g = Function(fs, b_ex.copy())
    G = assemble_gramian(x.basis)
    dolfin.solve(G, bg.vector(), b.coeffs)
    dolfin.solve(G, b2g.vector(), b2.vector())


#    # compute eigenpairs numerically
#    eigensolver = evaluate_evp(FEniCSBasis(fs))
#    # Extract largest (first) eigenpair
#    r, c, rx, cx = eigensolver.get_eigenpair(0)    
#    print "Largest eigenvalue: ", r    
#    # Initialize function and assign eigenvector
#    ef0 = Function(fs)
#    ef0.vector()[:] = rx

    if False:
        # export
        out_b = dolfin.File(__name__ + "_b.pvd", "compressed")
        out_b << b._fefunc
        out_b_ex = dolfin.File(__name__ + "_b_ex.pvd", "compressed")
        out_b_ex << b2
        out_b_num = dolfin.File(__name__ + "_b_num.pvd", "compressed")
        out_b_num << b_num


    #dolfin.plot(x._fefunc, title="interpolant x", rescale=False, axes=True, legend=True)
    dolfin.plot(bg, title="b", rescale=False, axes=True, legend=True)
    dolfin.plot(b2g, title="b_ex (ass/G)", rescale=False, axes=True, legend=True)
    dolfin.plot(bexg, title="b_ex (dir)", rescale=False, axes=True, legend=True)
    #dolfin.plot(b_num, title="b_num", rescale=False, axes=True, legend=True)
#    dolfin.plot(b3, title="M*b_num", rescale=False, axes=True, legend=True)
    #dolfin.plot(ef0, title="ef0", rescale=False, axes=True, legend=True)
    print dolfin.errornorm(u=b._fefunc, uh=b2) #, norm_type, degree, mesh)
    dolfin.interactive()
コード例 #43
0
ファイル: helpers.py プロジェクト: nschloe/maelstrom
def compute_time_errors(problem, MethodClass, mesh_sizes, Dt):

    mesh_generator, solution, f, mu, rho, cell_type = problem()

    # Compute the problem
    errors = {
        "u": numpy.empty((len(mesh_sizes), len(Dt))),
        "p": numpy.empty((len(mesh_sizes), len(Dt))),
    }
    for k, mesh_size in enumerate(mesh_sizes):
        info("")
        info("")
        with Message("Computing for mesh size {}...".format(mesh_size)):
            mesh = mesh_generator(mesh_size)

            # Define all expression with `domain`, see
            # <https://bitbucket.org/fenics-project/ufl/issues/96>.
            #
            # Translate data into FEniCS expressions.
            sol_u = Expression(
                (ccode(solution["u"]["value"][0]), ccode(solution["u"]["value"][1])),
                degree=_truncate_degree(solution["u"]["degree"]),
                t=0.0,
                domain=mesh,
            )
            sol_p = Expression(
                ccode(solution["p"]["value"]),
                degree=_truncate_degree(solution["p"]["degree"]),
                t=0.0,
                domain=mesh,
            )

            fenics_rhs0 = Expression(
                (ccode(f["value"][0]), ccode(f["value"][1])),
                degree=_truncate_degree(f["degree"]),
                t=0.0,
                mu=mu,
                rho=rho,
                domain=mesh,
            )
            # Deep-copy expression to be able to provide f0, f1 for the
            # Dirichlet boundary conditions later on.
            fenics_rhs1 = Expression(
                fenics_rhs0.cppcode,
                degree=_truncate_degree(f["degree"]),
                t=0.0,
                mu=mu,
                rho=rho,
                domain=mesh,
            )
            # Create initial states.
            W = VectorFunctionSpace(mesh, "CG", 2)
            P = FunctionSpace(mesh, "CG", 1)
            p0 = Expression(
                sol_p.cppcode,
                degree=_truncate_degree(solution["p"]["degree"]),
                t=0.0,
                domain=mesh,
            )

            mesh_area = assemble(1.0 * dx(mesh))
            method = MethodClass(
                time_step_method="backward euler",
                # time_step_method='crank-nicolson',
                # stabilization=None
                # stabilization='SUPG'
            )
            u1 = Function(W)
            p1 = Function(P)
            err_p = Function(P)
            divu1 = Function(P)
            for j, dt in enumerate(Dt):
                # Prepare previous states for multistepping.
                u = {
                    0: Expression(
                        sol_u.cppcode,
                        degree=_truncate_degree(solution["u"]["degree"]),
                        t=0.0,
                        cell=cell_type,
                    )
                }
                sol_u.t = dt
                u_bcs = [DirichletBC(W, sol_u, "on_boundary")]
                sol_p.t = dt
                # p_bcs = [DirichletBC(P, sol_p, 'on_boundary')]
                p_bcs = []
                fenics_rhs0.t = 0.0
                fenics_rhs1.t = dt
                u1, p1 = method.step(
                    Constant(dt),
                    u,
                    p0,
                    W,
                    P,
                    u_bcs,
                    p_bcs,
                    Constant(rho),
                    Constant(mu),
                    f={0: fenics_rhs0, 1: fenics_rhs1},
                    verbose=False,
                    tol=1.0e-10,
                )

                sol_u.t = dt
                sol_p.t = dt
                errors["u"][k][j] = errornorm(sol_u, u1)
                # The pressure is only determined up to a constant which makes
                # it a bit harder to define what the error is. For our
                # purposes, choose an alpha_0\in\R such that
                #
                #    alpha0 = argmin ||e - alpha||^2
                #
                # with  e := sol_p - p.
                # This alpha0 is unique and explicitly given by
                #
                #     alpha0 = 1/(2|Omega|) \int (e + e*)
                #            = 1/|Omega| \int Re(e),
                #
                # i.e., the mean error in \Omega.
                alpha = +assemble(sol_p * dx(mesh)) - assemble(p1 * dx(mesh))
                alpha /= mesh_area
                # We would like to perform
                #     p1 += alpha.
                # To avoid creating a temporary function every time, assume
                # that p1 lives in a function space where the coefficients
                # represent actual function values. This is true for CG
                # elements, for example. In that case, we can just add any
                # number to the vector of p1.
                p1.vector()[:] += alpha
                errors["p"][k][j] = errornorm(sol_p, p1)

                show_plots = False
                if show_plots:
                    plot(p1, title="p1", mesh=mesh)
                    plot(sol_p, title="sol_p", mesh=mesh)
                    err_p.vector()[:] = p1.vector()
                    sol_interp = interpolate(sol_p, P)
                    err_p.vector()[:] -= sol_interp.vector()
                    # plot(sol_p - p1, title='p1 - sol_p', mesh=mesh)
                    plot(err_p, title="p1 - sol_p", mesh=mesh)
                    # r = SpatialCoordinate(mesh)[0]
                    # divu1 = 1 / r * (r * u1[0]).dx(0) + u1[1].dx(1)
                    divu1.assign(project(u1[0].dx(0) + u1[1].dx(1), P))
                    plot(divu1, title="div(u1)")
    return errors
コード例 #44
0
ファイル: helpers.py プロジェクト: garethcmurphy/maelstrom
def compute_time_errors(problem, MethodClass, mesh_sizes, Dt):

    mesh_generator, solution, f, mu, rho, cell_type = problem()
    # Translate data into FEniCS expressions.
    sol_u = Expression((smp.printing.ccode(solution['u']['value'][0]),
                        smp.printing.ccode(solution['u']['value'][1])
                        ),
                       degree=_truncate_degree(solution['u']['degree']),
                       t=0.0,
                       cell=cell_type
                       )
    sol_p = Expression(smp.printing.ccode(solution['p']['value']),
                       degree=_truncate_degree(solution['p']['degree']),
                       t=0.0,
                       cell=cell_type
                       )

    fenics_rhs0 = Expression((smp.printing.ccode(f['value'][0]),
                              smp.printing.ccode(f['value'][1])
                              ),
                             degree=_truncate_degree(f['degree']),
                             t=0.0,
                             mu=mu, rho=rho,
                             cell=cell_type
                             )
    # Deep-copy expression to be able to provide f0, f1 for the Dirichlet-
    # boundary conditions later on.
    fenics_rhs1 = Expression(fenics_rhs0.cppcode,
                             degree=_truncate_degree(f['degree']),
                             t=0.0,
                             mu=mu, rho=rho,
                             cell=cell_type
                             )
    # Create initial states.
    p0 = Expression(
        sol_p.cppcode,
        degree=_truncate_degree(solution['p']['degree']),
        t=0.0,
        cell=cell_type
        )

    # Compute the problem
    errors = {'u': numpy.empty((len(mesh_sizes), len(Dt))),
              'p': numpy.empty((len(mesh_sizes), len(Dt)))
              }
    for k, mesh_size in enumerate(mesh_sizes):
        info('')
        info('')
        with Message('Computing for mesh size %r...' % mesh_size):
            mesh = mesh_generator(mesh_size)
            mesh_area = assemble(1.0 * dx(mesh))
            W = VectorFunctionSpace(mesh, 'CG', 2)
            P = FunctionSpace(mesh, 'CG', 1)
            method = MethodClass(W, P,
                                 rho, mu,
                                 theta=1.0,
                                 #theta=0.5,
                                 stabilization=None
                                 #stabilization='SUPG'
                                 )
            u1 = Function(W)
            p1 = Function(P)
            err_p = Function(P)
            divu1 = Function(P)
            for j, dt in enumerate(Dt):
                # Prepare previous states for multistepping.
                u = [Expression(
                    sol_u.cppcode,
                    degree=_truncate_degree(solution['u']['degree']),
                    t=0.0,
                    cell=cell_type
                    ),
                    # Expression(
                    #sol_u.cppcode,
                    #degree=_truncate_degree(solution['u']['degree']),
                    #t=0.5*dt,
                    #cell=cell_type
                    #)
                    ]
                sol_u.t = dt
                u_bcs = [DirichletBC(W, sol_u, 'on_boundary')]
                sol_p.t = dt
                #p_bcs = [DirichletBC(P, sol_p, 'on_boundary')]
                p_bcs = []
                fenics_rhs0.t = 0.0
                fenics_rhs1.t = dt
                method.step(dt,
                            u1, p1,
                            u, p0,
                            u_bcs=u_bcs, p_bcs=p_bcs,
                            f0=fenics_rhs0, f1=fenics_rhs1,
                            verbose=False,
                            tol=1.0e-10
                            )
                sol_u.t = dt
                sol_p.t = dt
                errors['u'][k][j] = errornorm(sol_u, u1)
                # The pressure is only determined up to a constant which makes
                # it a bit harder to define what the error is. For our
                # purposes, choose an alpha_0\in\R such that
                #
                #    alpha0 = argmin ||e - alpha||^2
                #
                # with  e := sol_p - p.
                # This alpha0 is unique and explicitly given by
                #
                #     alpha0 = 1/(2|Omega|) \int (e + e*)
                #            = 1/|Omega| \int Re(e),
                #
                # i.e., the mean error in \Omega.
                alpha = assemble(sol_p * dx(mesh)) \
                    - assemble(p1 * dx(mesh))
                alpha /= mesh_area
                # We would like to perform
                #     p1 += alpha.
                # To avoid creating a temporary function every time, assume
                # that p1 lives in a function space where the coefficients
                # represent actual function values. This is true for CG
                # elements, for example. In that case, we can just add any
                # number to the vector of p1.
                p1.vector()[:] += alpha
                errors['p'][k][j] = errornorm(sol_p, p1)

                show_plots = False
                if show_plots:
                    plot(p1, title='p1', mesh=mesh)
                    plot(sol_p, title='sol_p', mesh=mesh)
                    err_p.vector()[:] = p1.vector()
                    sol_interp = interpolate(sol_p, P)
                    err_p.vector()[:] -= sol_interp.vector()
                    #plot(sol_p - p1, title='p1 - sol_p', mesh=mesh)
                    plot(err_p, title='p1 - sol_p', mesh=mesh)
                    #r = Expression('x[0]', degree=1, cell=triangle)
                    #divu1 = 1 / r * (r * u1[0]).dx(0) + u1[1].dx(1)
                    divu1.assign(project(u1[0].dx(0) + u1[1].dx(1), P))
                    plot(divu1, title='div(u1)')
                    interactive()
    return errors
コード例 #45
0
ファイル: common.py プロジェクト: HomaiRS/fenics_ii
                       # Error
                       ['e_(u%d)=%.2E[%.2f]' % (i, e, r)  
                        for i, (e, r) in enumerate(zip(error, rate))] +
                       # Unknowns
                       ['#(%d)=%d' % p for p in enumerate(ndofs)] +
                       # Total
                       ['#(all)=%d' % sum(ndofs)] +
                       # Rnorm
                       ['|r|_l2=%g' % r_norm] +
                       ['niters=%d' % niters])
        # Screen
        print GREEN % msg
        # Log
        if path:
            with open(path, 'a') as f: f.write(msg + '\n')

        error0, mesh_size0 = error, mesh_size
        memory.append(np.r_[mesh_size, error])

        
# Two arg norms
H1_norm = lambda u, uh, m=None: errornorm(u, uh, 'H1', degree_rise=2, mesh=m)
H10_norm = lambda u, uh, m=None: errornorm(u, uh, 'H10', degree_rise=2, mesh=m)
L2_norm = lambda u, uh, m=None: errornorm(u, uh, 'L2', degree_rise=2, mesh=m)
Hdiv_norm = lambda u, uh, m=None: errornorm(u, uh, 'Hdiv', degree_rise=2, mesh=m)
Hdiv0_norm = lambda u, uh, m=None: errornorm(u, uh, 'Hdiv0', degree_rise=2, mesh=m)
Hcurl_norm = lambda u, uh, m=None: errornorm(u, uh, 'Hcurl', degree_rise=2, mesh=m)
Hcurl0_norm = lambda u, uh, m=None: errornorm(u, uh, 'Hcurl0', degree_rise=2, mesh=m)

linf_norm = lambda u, uh: np.linalg.norm(u - uh.vector().get_local())
コード例 #46
0
def halfexp_euler_smarminex(MSme, ASme, BSme, MP, FvbcSme, FpbcSme, B2BoolInv,
                            PrP, TsP, vp_init=None, qqpq_init=None,
                            saveallres=True):
    """ halfexplicit euler for the NSE in index 1 formulation

    """

    Nts, t0, tE, trange, Nv = init_time_stepping(PrP, TsP)
    tcur = t0
    # remove the p - freedom
    BSme, BTSme, MPc, FpbcSmeC, vp_init, Npc\
        = pinthep(BSme, BSme.T, MP, FpbcSme, vp_init, PrP.Pdof)

    # split the coeffs
    B1Sme = BSme[:, :-Npc]
    B2Sme = BSme[:, -Npc:]

    M1Sme = MSme[:, :-Npc]
    M2Sme = MSme[:, -Npc:]

    A1Sme = ASme[:, :-Npc]
    A2Sme = ASme[:, -Npc:]

    # The matrix to be solved in every time step
    #
    # 		1/dt*M11    M12  -B2'  0        q1
    # 		1/dt*M21    M22  -B1'  0        tq2
    # 		1/dt*B1     B2   0     0  *   p     = rhs
    # 		     B1     0    0     B2 	    q2
    #
    # cf. preprint
    # if A is there - we need to treat it implicitly
    #
    # 		1/dt*M11+A11    M12  -B2'  A12        q1
    # 		1/dt*M21+A21    M22  -B1'  A22        tq2
    # 		1/dt*B1         B2   0       0    *   p     = rhs
    # 		     B1         0    0       B2 	  q2
    #

    MFac = 1
    # Weights for the 'conti' eqns to balance the residuals
    WC = 0.5
    WCD = 0.5
    PFac = 1  # dt/WCD
    PFacI = 1  # WCD/dt

    # rescale q1
    q1facI = 1.

    DT = (tE-t0)/(trange.size-1)  # TODO: non uniform meshes !!!
    IterA1 = MFac*sps.hstack([q1facI*(1.0/DT*M1Sme + A1Sme), M2Sme,
                              -PFacI*BSme.T, A2Sme])
    IterA2 = WCD*sps.hstack([q1facI*(1.0/DT*B1Sme), B2Sme,
                             sps.csr_matrix((Npc, 2*Npc))])
    IterA3 = WC*sps.hstack([q1facI*B1Sme, sps.csr_matrix((Npc, 2*Npc)), B2Sme])

    IterA = sps.vstack([IterA1, IterA2, IterA3])

    if TsP.linatol == 0:
        IterAfac = spsla.factorized(IterA)

    # Preconditioning ...
    #
    if TsP.SadPtPrec:
        MLump = np.atleast_2d(MSme.diagonal()).T
        MLump2 = MLump[-Npc:, ]
        MLumpI = 1. / MLump
        # MLumpI1 = MLumpI[:-(Np - 1), ]
        # MLumpI2 = MLumpI[-(Np - 1):, ]
        B2SmeTfac = spsla.splu(B2Sme.T)
        B2Smefac = spsla.splu(B2Sme)

        def PrecByB2(qqpq):
            qq = MLumpI*qqpq[:Nv, ]

            p = qqpq[Nv:-Npc, ]
            p = B2Smefac.solve(p.flatten())
            p = MLump2*np.atleast_2d(p).T
            # p = spsla.spsolve(B2Sme.T, p)
            p = B2SmeTfac.solve(p.flatten())
            p = np.atleast_2d(p).T

            q2 = qqpq[-Npc:, ]
            # q2 = spsla.spsolve(B2Sme, q2)
            q2 = B2Smefac.solve(q2.flatten())
            q2 = np.atleast_2d(q2).T

            return np.vstack([np.vstack([qq, -p]), q2])

        MGmr = spsla.LinearOperator(
            (Nv + 2*Npc,
             Nv + 2*Npc),
            matvec=PrecByB2,
            dtype=np.float32)
        TsP.Ml = MGmr

    Mcfac = spsla.splu(MSme)
    MPcfac = spsla.splu(MPc)

    def _MInvInd1(qqpq):
        qq = qqpq[:Nv, ]
        p = qqpq[Nv:-Npc, ]
        q2 = qqpq[-Npc:, ]
        miqq = np.atleast_2d(Mcfac.solve(qq.flatten())).T
        mip = np.atleast_2d(MPcfac.solve(p.flatten())).T
        miq2 = np.atleast_2d(MPcfac.solve(q2.flatten())).T
        return np.vstack([miqq, mip, miq2])

    # MInvInd1 = spsla.LinearOperator((Nv + 2*Npc, Nv + 2*Npc),
    #                                 matvec=_MInvInd1, dtype=np.float32)

    def smamin_prec_fem_ip(qqpq1, qqpq2, retparts=False):
        """ M ip for the preconditioned residuals

        """
        if retparts:
            return (np.dot(qqpq1[:Nv, ].T.conj(), MSme*qqpq2[:Nv, ]),
                    np.dot(qqpq1[Nv:-Npc, ].T.conj(), MPc*qqpq2[Nv:-Npc, ]),
                    np.dot(qqpq1[-Npc:, ].T.conj(), MPc*qqpq2[-Npc:, ]))
        else:
            return np.dot(qqpq1[:Nv, ].T.conj(), MSme*qqpq2[:Nv, ]) + \
                np.dot(qqpq1[Nv:-Npc, ].T.conj(), MPc*qqpq2[Nv:-Npc, ]) + \
                np.dot(qqpq1[-Npc:, ].T.conj(), MPc*qqpq2[-Npc:, ])

    def smamin_fem_ip(qqpq1, qqpq2, Mv, Mp, Nv, Npc, dt=1.):
        """ M^-1 ip for the extended system

        """
        return mass_fem_ip(qqpq1[:Nv, ], qqpq2[:Nv, ], Mv) + \
            dt*mass_fem_ip(qqpq1[Nv:-Npc, ], qqpq2[Nv:-Npc, ], Mp) + \
            mass_fem_ip(qqpq1[-Npc:, ], qqpq2[-Npc:, ], Mp)

    v, p = expand_vp_dolfunc(PrP, vp=vp_init, vc=None, pc=None, pdof=PrP.Pdof)
    TsP.UpFiles.u_file << v, tcur
    TsP.UpFiles.p_file << p, tcur

    dtstrdct = dict(prefix=TsP.svdatapath, method=1, N=PrP.N,
                    tolcor=TsP.TolCorB,
                    nu=PrP.nu, Nts=TsP.Nts, tol=TsP.linatol, te=TsP.tE)
    cdatstr = get_dtstr(t=t0, **dtstrdct)
    try:
        np.load(cdatstr + '.npy')
        print 'loaded data from ', cdatstr, ' ...'
    except IOError:
        np.save(cdatstr, vp_init)
        print 'saving to ', cdatstr, ' ...'

    vp_old = np.copy(vp_init)
    q1_old = 1./q1facI*vp_init[~B2BoolInv, ]
    q2_old = vp_init[B2BoolInv, ]

    if qqpq_init is None and TsP.linatol > 0:
        # initial value for tq2
        ConV, CurFv = get_conv_curfv_rearr(v, PrP, tcur, B2BoolInv)
        tq2_old = spsla.spsolve(M2Sme[-Npc:, :], CurFv[-Npc:, ])
        # tq2_old = MLumpI2*CurFv[-(Np-1):,]
        tq2_old = np.atleast_2d(tq2_old).T
        # state vector of the smaminex system : [ q1^+, tq2^c, p^c, q2^+]
        qqpq_old = np.zeros((Nv + 2*Npc, 1))
        qqpq_old[:Nv - Npc, ] = q1_old
        qqpq_old[Nv - Npc:Nv, ] = tq2_old
        qqpq_old[Nv:Nv + Npc, ] = PFac*vp_old[Nv:, ]
        qqpq_old[Nv + Npc:, ] = q2_old
    else:
        qqpq_old = qqpq_init

    qqpq_oldold = qqpq_old

    ContiRes, VelEr, PEr, TolCorL = [], [], [], []
    MomRes, DContiRes = [], []

    # compute 1st time step by direct solve to initialize the krylov upd scheme
    inikryupd = TsP.inikryupd
    iniiterfac = TsP.iniiterfac  # the first krylov step needs more maxiter

    for etap in range(1, TsP.NOutPutPts + 1):
        for i in range(Nts / TsP.NOutPutPts):
            idx = (etap-1)*(Nts/TsP.NOutPutPts) + i
            tnext = trange[idx+1]
            cdatstr = get_dtstr(t=tnext, **dtstrdct)
            DT = tnext - tcur
            try:
                qqpq_next = np.load(cdatstr + '_qqpq' + '.npy')
                print 'loaded data from ', cdatstr, ' ...'
                qqpq_oldold = qqpq_old
                qqpq_old = qqpq_next
                TolCor = 'n.a.'
                if i == 2:
                    iniiterfac = 1  # fac only in the first Krylov Call

                # Reconstruct data of the iterative solution
                if TsP.linatol > 0 and (TsP.TolCorB or saveallres):
                    ConV, CurFv = get_conv_curfv_rearr(v, PrP, tcur, B2BoolInv)
                    gdot = np.zeros((Npc, 1))  # TODO: implement \dot g
                    Iterrhs = 1.0 / DT*np.vstack([MFac*M1Sme*q1_old,
                                                  WCD*B1Sme*q1_old]) +\
                        np.vstack([MFac*(FvbcSme + CurFv - ConV), WCD*gdot])
                    Iterrhs = np.vstack([Iterrhs, WC*FpbcSmeC])
                    if TsP.TolCorB:
                        NormRhsInd1 = np.sqrt(
                            smamin_fem_ip(Iterrhs, Iterrhs, Mcfac, MPcfac,
                                          Nv, Npc, dt=np.sqrt(DT)))[0][0]
                        TolCor = 1.0 / np.max([NormRhsInd1, 1])
                    else:
                        TolCor = 1.0

            except IOError:
                print 'computing data for ', cdatstr, ' ...'

                # set up right hand side
                ConV, CurFv = get_conv_curfv_rearr(v, PrP, tcur, B2BoolInv)
                gdot = np.zeros((Npc, 1))  # TODO: implement \dot g
                Iterrhs = 1.0 / DT*np.vstack([MFac*M1Sme*q1_old,
                                              WCD*B1Sme*q1_old]) +\
                    np.vstack([MFac*(FvbcSme + CurFv - ConV), WCD*gdot])
                Iterrhs = np.vstack([Iterrhs, WC*FpbcSmeC])

                if TsP.linatol == 0:
                    # q1_tq2_p_q2_new = spsla.spsolve(IterA, Iterrhs)
                    q1_tq2_p_q2_new = IterAfac(Iterrhs.flatten())
                    qqpq_old = np.atleast_2d(q1_tq2_p_q2_new).T
                    TolCor = 0
                else:
                    # Norm of rhs of index-1 formulation
                    # used to correct the relative residual
                    # such that the absolute residual stays constant
                    if TsP.TolCorB:
                        NormRhsInd1 = np.sqrt(
                            smamin_fem_ip(Iterrhs, Iterrhs, MSme, MPc,
                                          Nv, Npc, dt=np.sqrt(DT)))[0][0]
                        TolCor = 1.0 / np.max([NormRhsInd1, 1])
                    else:
                        TolCor = 1.0

                    if inikryupd and tcur == t0:
                        print '\n1st step direct solve to initialize krylov\n'
                        q1_tq2_p_q2_new = spsla.spsolve(IterA, Iterrhs)
                        qqpq_oldold = qqpq_old
                        qqpq_old = np.atleast_2d(q1_tq2_p_q2_new).T
                        TolCor = 0
                        inikryupd = False  # only once !!
                    else:
                        cls = krypy.linsys.\
                            LinearSystem(IterA, Iterrhs, Ml=MGmr,
                                         ip_B=smamin_prec_fem_ip)

                        tstart = time.time()
                        # extrapolating the initial value
                        qqqp_pv = (qqpq_old - qqpq_oldold)

                        q1_tq2_p_q2_new = krypy.linsys.\
                            RestartedGmres(cls, x0=qqpq_old+qqqp_pv,
                                           tol=TolCor*TsP.linatol,
                                           maxiter=iniiterfac*TsP.MaxIter,
                                           max_restarts=100)

                        qqpq_oldold = qqpq_old
                        qqpq_old = np.atleast_2d(q1_tq2_p_q2_new.xk)
                        tend = time.time()
                        print ('Needed {0} of max {4}*{1} iterations: ' +
                               'final relres = {2}\n TolCor was {3}').\
                            format(len(q1_tq2_p_q2_new.resnorms), TsP.MaxIter,
                                   q1_tq2_p_q2_new.resnorms[-1], TolCor,
                                   iniiterfac)
                        print 'Elapsed time {0}'.format(tend - tstart)
                        iniiterfac = 1  # fac only in the first Krylov Call

                np.save(cdatstr + '_qqpq', qqpq_old)

            q1_old = q1facI*qqpq_old[:Nv - Npc, ]
            q2_old = qqpq_old[-Npc:, ]

            # Extract the 'actual' velocity and pressure
            vc = np.zeros((Nv, 1))
            vc[~B2BoolInv, ] = q1_old
            vc[B2BoolInv, ] = q2_old
            # print np.linalg.norm(vc)

            pc = PFacI*qqpq_old[Nv:Nv + Npc, ]

            v, p = expand_vp_dolfunc(PrP, vp=None, vc=vc, pc=pc,
                                     pdof=PrP.Pdof)

            cdatstr = get_dtstr(t=tnext, **dtstrdct)
            np.save(cdatstr, np.vstack([vc, pc]))

            # the errors and residuals
            # ContiRes.append(comp_cont_error(v, FpbcSme, PrP.Q))
            TolCorL.append(TolCor)
            ContiRes.append(0)  # troubles with fenics 1.5
            try:
                vCur, pCur = PrP.v, PrP.p
                vCur.t = tnext
                pCur.t = tcur
                VelEr.append(errornorm(vCur, v))
                PEr.append(errornorm(pCur, p))
            except AttributeError:
                VelEr.append(0)
                PEr.append(0)

            if saveallres:
                res = IterA*qqpq_old - Iterrhs
                (mr, mcd, mc) = smamin_prec_fem_ip(res, res, retparts=True)
                MomRes.append(np.sqrt(mr)[0][0])
                DContiRes.append(np.sqrt(mcd)[0][0])
                ContiRes[-1] = np.sqrt(mc)[0][0]
                # print 'Res is dconti: ', np.sqrt(mcd)[0][0]
                # print 'Res is conti: ', np.sqrt(mc)[0][0]
                # print 'Res is moment: ', np.sqrt(mr+mc+mcd)[0][0]

            if i + etap == 1 and TsP.SaveIniVal:
                from scipy.io import savemat
                dname = 'IniValSmaMinN%s' % Nv
                savemat(dname, {'qqpq_old': qqpq_old})
            tcur = tnext

        print '%d of %d time steps completed ' % (etap*Nts/TsP.NOutPutPts, Nts)
        print 'DEBUG: idx={0}'.format(idx)

        if TsP.ParaviewOutput:
            TsP.UpFiles.u_file << v, tcur
            TsP.UpFiles.p_file << p, tcur

    TsP.Residuals.VelEr.append(VelEr)
    TsP.Residuals.PEr.append(PEr)
    TsP.TolCor.append(TolCorL)
    TsP.Residuals.ContiRes.append(ContiRes)
    if saveallres:
        TsP.Residuals.MomRes.append(MomRes)
        TsP.Residuals.DContiRes.append(DContiRes)

    return
コード例 #47
0
def run_mc(w, err, pde):
    import time
    from dolfin import norm
    
    # create reference mesh and function space
    projection_basis = get_projection_basis(mesh0, maxh=min(w[Multiindex()].basis.minh / 4, MC_HMAX))
    logger.debug("hmin of mi[0] = %s, reference mesh = (%s, %s)", w[Multiindex()].basis.minh, projection_basis.minh, projection_basis.maxh)

    # get realization of coefficient field
    err_L2, err_H1 = 0, 0
    for i in range(MC_N):
        logger.info("---- MC Iteration %i/%i ----", i + 1 , MC_N)
        RV_samples = coeff_field.sample_rvs()
        logger.debug("-- RV_samples: %s", [RV_samples[j] for j in range(w.max_order)])
        t1 = time.time()
        sample_sol_param = compute_parametric_sample_solution(RV_samples, coeff_field, w, projection_basis)
        t2 = time.time()
        sample_sol_direct = compute_direct_sample_solution(pde, RV_samples, coeff_field, A, 2 * w.max_order, projection_basis)
        t3 = time.time()
        cerr_L2 = errornorm(sample_sol_param._fefunc, sample_sol_direct._fefunc, "L2")
        cerr_H1 = errornorm(sample_sol_param._fefunc, sample_sol_direct._fefunc, "H1")
        logger.debug("-- current error L2 = %s    H1 = %s", cerr_L2, cerr_H1)
        err_L2 += 1.0 / MC_N * cerr_L2
        err_H1 += 1.0 / MC_N * cerr_H1
        
        if i + 1 == MC_N:
            # error function
            errf = sample_sol_param - sample_sol_direct
            
            # deterministic part
            sample_sol_direct_a0 = compute_direct_sample_solution(pde, RV_samples, coeff_field, A, 0, projection_basis)
            L2_a0 = errornorm(sample_sol_param._fefunc, sample_sol_direct_a0._fefunc, "L2")
            H1_a0 = errornorm(sample_sol_param._fefunc, sample_sol_direct_a0._fefunc, "H1")
            logger.info("-- DETERMINISTIC error L2 = %s    H1 = %s", L2_a0, H1_a0)

            # stochastic part
            sample_sol_direct_am = sample_sol_direct - sample_sol_direct_a0
#            L2_am = errornorm(sample_sol_param._fefunc, sample_sol_direct_am._fefunc, "L2")
#            H1_am = errornorm(sample_sol_param._fefunc, sample_sol_direct_am._fefunc, "H1")
            logger.info("-- STOCHASTIC norm L2 = %s    H1 = %s", sample_sol_direct_am.norm("L2"), sample_sol_direct_am.norm("H1"))

            if MC_PLOT:
                sample_sol_param.plot(title="param")
                sample_sol_direct.plot(title="direct")
                errf.plot(title="|param-direct| error")
                sample_sol_direct_am.plot(title="direct stochastic part")
                fc = get_coeff_realisation(RV_samples, coeff_field, w.max_order, projection_basis)
                fc.plot(title="coeff")


                sol_variance = compute_solution_variance(coeff_field, w, projection_basis)
                sol_variance.plot(title="sol variance")
                interactive()

                #coeff_variance = compute_solution_variance(coeff_field, w0, proj_basis)
                #sol_variance.plot(title="variance")
            
        t4 = time.time()
        logger.info("TIMING: param: %s, direct %s, error %s", t2 - t1, t3 - t2, t4 - t3)

    logger.info("MC Error: L2: %s, H1: %s", err_L2, err_H1)
    err.append((err_L2, err_H1))
コード例 #48
0
ファイル: stokes_heat.py プロジェクト: nschloe/maelstrom
def solve_fixed_point(
        mesh,
        W_element, P_element, Q_element,
        u0, p0, theta0,
        kappa, rho, mu, cp,
        g, extra_force,
        heat_source,
        u_bcs, p_bcs,
        theta_dirichlet_bcs,
        theta_neumann_bcs,
        my_dx, my_ds,
        max_iter,
        tol
        ):
    # Solve the coupled heat-Stokes equation approximately. Do this
    # iteratively by solving the heat equation, then solving Stokes with the
    # updated heat, the heat equation with the updated velocity and so forth
    # until the change is 'small'.
    WP = FunctionSpace(mesh, MixedElement([W_element, P_element]))
    Q = FunctionSpace(mesh, Q_element)
    # Initialize functions.
    up0 = Function(WP)
    u0, p0 = up0.split()

    theta1 = Function(Q)
    for _ in range(max_iter):
        heat_problem = heat.Heat(
            Q,
            kappa=kappa,
            rho=rho(theta0),
            cp=cp,
            convection=u0,
            source=heat_source,
            dirichlet_bcs=theta_dirichlet_bcs,
            neumann_bcs=theta_neumann_bcs,
            my_dx=my_dx,
            my_ds=my_ds
            )

        theta1.assign(heat_problem.solve_stationary())

        # Solve problem for velocity, pressure.
        f = rho(theta0) * g  # coupling
        if extra_force:
            f += as_vector((extra_force[0], extra_force[1], 0.0))
        # up1 = up0.copy()
        stokes.stokes_solve(
            up0,
            mu,
            u_bcs, p_bcs,
            f,
            my_dx=my_dx,
            tol=1.0e-10,
            verbose=False,
            maxiter=1000
            )

        # from dolfin import plot
        # plot(u0)
        # plot(theta0)

        theta_diff = errornorm(theta0, theta1)
        info('||theta - theta0|| = {:e}'.format(theta_diff))
        # info('||u - u0||         = {:e}'.format(u_diff))
        # info('||p - p0||         = {:e}'.format(p_diff))
        # diff = theta_diff + u_diff + p_diff
        diff = theta_diff
        info('sum = {:e}'.format(diff))

        # # Show the iterates.
        # plot(theta0, title='theta0')
        # plot(u0, title='u0')
        # interactive()
        # #exit()
        if diff < tol:
            break

        theta0.assign(theta1)

    # Create a *deep* copy of u0, p0, to be able to deal with them as
    # actually separate entities.
    u0, p0 = up0.split(deepcopy=True)
    return u0, p0, theta0