示例#1
0
    def matrix_assembly(self, size=32, degree=1, dim=2, fs='scalar'):
        with self.timed_region('mesh'):
            mesh = make_mesh[dim](size)
        with self.timed_region('setup'):
            FS = {'scalar': FunctionSpace, 'vector': VectorFunctionSpace}[fs]
            V = FS(mesh, "Lagrange", degree)

            # Define boundary condition
            bc = DirichletBC(V, 0.0, [3, 4])

            # Define variational problem
            u = TrialFunction(V)
            v = TestFunction(V)
            a = inner(grad(u), grad(v))*dx

        with self.timed_region('assembly'):
            A = assemble(a)
            A.M
        with self.timed_region('reassembly'):
            A = assemble(a, tensor=A)
            A.M
        # Clear sparsity cache
        A.M.sparsity.dsets[0].set._cache.clear()
        with self.timed_region('assembly bcs'):
            A = assemble(a, bcs=bc)
            A.M
        with self.timed_region('reassembly bcs'):
            A = assemble(a, tensor=A, bcs=bc)
            A.M
        for task, timer in get_timers(reset=True).items():
            self.register_timing(task, timer.total)
示例#2
0
    def explosive_source(self, T=0.01, h=2.5, explicit=True):
        self.series['h'] = h
        self.series['T'] = T
        self.series['explicit'] = explicit

        self.explosive_source_lf4(T=T, h=h, explicit=explicit, output=False)

        for task, timer in get_timers(reset=True).items():
            self.register_timing(task, timer.total)
示例#3
0
    def assembly(self, size=32, degree=1, dim=2, fs='scalar'):
        with self.timed_region('mesh'):
            mesh = make_mesh[dim](size)
        with self.timed_region('setup'):
            FS = {'scalar': FunctionSpace, 'vector': VectorFunctionSpace}[fs]
            V = FS(mesh, 'CG', degree)
            Q = FunctionSpace(mesh, 'CG', degree)

            # Define variational problem
            u = TrialFunction(V)
            v = TestFunction(V)
            mass = inner(u, v)
            laplace = inner(grad(u), grad(v))
            f = Function(Q).assign(1.0)
            g = Function(Q).assign(1.0)
            h = Function(Q).assign(1.0)
            A = assemble(mass * dx)

        with self.timed_region('mass premult 0'):
            assemble(mass * dx, tensor=A)
            A.M
        with self.timed_region('mass premult 1'):
            assemble(f * mass * dx, tensor=A)
            A.M
        with self.timed_region('mass premult 2'):
            assemble(g * f * mass * dx, tensor=A)
            A.M
        with self.timed_region('mass premult 3'):
            assemble(h * g * f * mass * dx, tensor=A)
            A.M
        with self.timed_region('laplace premult 0'):
            assemble(laplace * dx, tensor=A)
            A.M
        with self.timed_region('laplace premult 1'):
            assemble(f * laplace * dx, tensor=A)
            A.M
        with self.timed_region('laplace premult 2'):
            assemble(g * f * laplace * dx, tensor=A)
            A.M
        with self.timed_region('laplace premult 3'):
            assemble(h * g * f * laplace * dx, tensor=A)
            A.M
        with self.timed_region('helmholtz premult 0'):
            assemble((mass + laplace) * dx, tensor=A)
            A.M
        with self.timed_region('helmholtz premult 1'):
            assemble(f * (mass + laplace) * dx, tensor=A)
            A.M
        with self.timed_region('helmholtz premult 2'):
            assemble(g * f * (mass + laplace) * dx, tensor=A)
            A.M
        with self.timed_region('helmholtz premult 3'):
            assemble(h * g * f * (mass + laplace) * dx, tensor=A)
            A.M
        for task, timer in get_timers(reset=True).items():
            self.register_timing(task, timer.total)
    def assembly(self, size=32, degree=1, dim=2, fs='scalar'):
        with self.timed_region('mesh'):
            mesh = make_mesh[dim](size)
        with self.timed_region('setup'):
            FS = {'scalar': FunctionSpace, 'vector': VectorFunctionSpace}[fs]
            V = FS(mesh, 'CG', degree)
            Q = FunctionSpace(mesh, 'CG', degree)

            # Define variational problem
            u = TrialFunction(V)
            v = TestFunction(V)
            mass = inner(u, v)
            laplace = inner(grad(u), grad(v))
            f = Function(Q).assign(1.0)
            g = Function(Q).assign(1.0)
            h = Function(Q).assign(1.0)
            A = assemble(mass*dx)

        with self.timed_region('mass premult 0'):
            assemble(mass*dx, tensor=A)
            A.M
        with self.timed_region('mass premult 1'):
            assemble(f*mass*dx, tensor=A)
            A.M
        with self.timed_region('mass premult 2'):
            assemble(g*f*mass*dx, tensor=A)
            A.M
        with self.timed_region('mass premult 3'):
            assemble(h*g*f*mass*dx, tensor=A)
            A.M
        with self.timed_region('laplace premult 0'):
            assemble(laplace*dx, tensor=A)
            A.M
        with self.timed_region('laplace premult 1'):
            assemble(f*laplace*dx, tensor=A)
            A.M
        with self.timed_region('laplace premult 2'):
            assemble(g*f*laplace*dx, tensor=A)
            A.M
        with self.timed_region('laplace premult 3'):
            assemble(h*g*f*laplace*dx, tensor=A)
            A.M
        with self.timed_region('helmholtz premult 0'):
            assemble((mass+laplace)*dx, tensor=A)
            A.M
        with self.timed_region('helmholtz premult 1'):
            assemble(f*(mass+laplace)*dx, tensor=A)
            A.M
        with self.timed_region('helmholtz premult 2'):
            assemble(g*f*(mass+laplace)*dx, tensor=A)
            A.M
        with self.timed_region('helmholtz premult 3'):
            assemble(h*g*f*(mass+laplace)*dx, tensor=A)
            A.M
        for task, timer in get_timers(reset=True).items():
            self.register_timing(task, timer.total)
    def forms(self, q=1, p=1, dim=3, max_nf=3, form='mass', dump_kernel=False):
        mesh = meshes[dim]
        A = assemble(eval(form)(q, p, dim, mesh))

        for nf in range(max_nf + 1):
            f = eval(form)(q, p, dim, mesh, nf)
            with self.timed_region('nf %d' % nf):
                assemble(f, tensor=A)
                A.M
            if dump_kernel:
                for i, k in enumerate(f._kernels):
                    with open('kernels/f_%s%d_q%d_p%d_dim%d_nf%d.c' % (form, i, q, p, dim, nf), 'w') as fil:
                        fil.write(k[-1].code)
        t = get_timers(reset=True)
        task = 'Assemble cells'
        self.register_timing(task, t[task].total)
示例#6
0
    def eigenmode(self,
                  dim=3,
                  N=3,
                  degree=1,
                  dt=0.125,
                  T=2.0,
                  solver='explicit',
                  opt=2):
        self.series['np'] = op2.MPI.comm.size
        self.series['dim'] = dim
        self.series['size'] = N
        self.series['T'] = T
        self.series['solver'] = solver
        self.series['opt'] = opt
        self.series['degree'] = degree

        # If dt is supressed (<0) Infer it based on Courant number
        if dt < 0:
            # Courant number of 0.5: (dx*C)/Vp
            dt = 0.5 * (1.0 / N) / (2.0**(degree - 1))
        self.series['dt'] = dt

        parameters["coffee"]["O3"] = opt >= 3
        parameters["coffee"]["O4"] = opt >= 4

        if dim == 2:
            eigen = Eigenmode2DLF4(N, degree, dt, solver=solver, output=False)
            u1, s1 = eigen.eigenmode2d(T=T)
        elif dim == 3:
            eigen = Eigenmode3DLF4(N, degree, dt, solver=solver, output=False)
            u1, s1 = eigen.eigenmode3d(T=T)

        for task, timer in get_timers(reset=True).items():
            self.register_timing(task, timer.total)

        self.meta['dofs'] = op2.MPI.comm.allreduce(eigen.elastic.S.dof_count,
                                                   op=mpi4py.MPI.SUM)
        try:
            with self.timed_region('compute_error'):
                u_error, s_error = eigen.eigenmode_error(u1, s1)
                self.meta['u_error'] = u_error
                self.meta['s_error'] = s_error
        except RuntimeError:
            print "WARNING: Couldn't establish error norm"
            self.meta['u_error'] = 'NaN'
            self.meta['s_error'] = 'NaN'
    def forms(self, q=1, p=1, dim=3, max_nf=3, form='mass', dump_kernel=False):
        mesh = meshes[dim]
        A = assemble(eval(form)(q, p, dim, mesh))

        for nf in range(max_nf + 1):
            f = eval(form)(q, p, dim, mesh, nf)
            with self.timed_region('nf %d' % nf):
                assemble(f, tensor=A)
                A.M
            if dump_kernel:
                for i, k in enumerate(f._kernels):
                    with open(
                            'kernels/f_%s%d_q%d_p%d_dim%d_nf%d.c' %
                        (form, i, q, p, dim, nf), 'w') as fil:
                        fil.write(k[-1].code)
        t = get_timers(reset=True)
        task = 'Assemble cells'
        self.register_timing(task, t[task].total)
示例#8
0
    def poisson(self,
                size=32,
                degree=1,
                dim=3,
                preassemble=True,
                weak=False,
                print_norm=True,
                verbose=False,
                measure_overhead=False,
                pc='hypre',
                strong_threshold=0.75,
                agg_nl=2,
                max_levels=25):
        if weak:
            self.series['weak'] = size
            size = int((size * op2.MPI.comm.size)**(1. / dim))
            self.meta['size'] = size
        else:
            self.series['size'] = size
        self.series['degree'] = degree
        self.meta['cells'] = 6 * size**dim
        self.meta['vertices'] = (size + 1)**dim
        params = {
            'ksp_type': 'cg',
            'pc_type': pc,
            'pc_hypre_type': 'boomeramg',
            'pc_hypre_boomeramg_strong_threshold': strong_threshold,
            'pc_hypre_boomeramg_agg_nl': agg_nl,
            'pc_hypre_boomeramg_max_levels': max_levels,
            'ksp_rtol': 1e-6,
            'ksp_atol': 1e-15
        }
        if verbose:
            params['pc_hypre_boomeramg_print_statistics'] = True
            params['ksp_view'] = True
            params['ksp_monitor'] = True
        t_, mesh = self.make_mesh(size, dim)
        self.register_timing('mesh', t_)
        with self.timed_region('setup'):
            V = FunctionSpace(mesh, "Lagrange", degree)
            if verbose:
                print '[%d]' % op2.MPI.comm.rank, 'DOFs:', V.dof_dset.size

            # Define boundary condition
            bc = DirichletBC(V, 0.0, [3, 4])

            # Define variational problem
            u = TrialFunction(V)
            v = TestFunction(V)
            f = Function(V).interpolate(Expression(initial[dim]))
            f.dat.data_ro
            a = inner(grad(u), grad(v)) * dx
            L = f * v * dx

            # Compute solution
            u = Function(V)
        if measure_overhead:
            print "Matrix assembly overhead:", self.lhs_ffc_overhead(a, bc)
            print "RHS assembly overhead:", self.rhs_ffc_overhead(L, bc)
            return
        if preassemble:
            with self.timed_region('matrix assembly'):
                A = assemble(a, bcs=bc)
                A.M
            self.meta['dofs'] = A.M.handle.sizes[0][1]
            with self.timed_region('rhs assembly'):
                b = assemble(L)
                bc.apply(b)
                b.dat.data_ro
            with self.timed_region('solve'):
                solve(A, u, b, solver_parameters=params)
                u.dat.data_ro
        else:
            with self.timed_region('solve'):
                solve(a == L, u, bcs=[bc], solver_parameters=params)
                u.dat.data_ro

        # Analytical solution
        a = Function(V).interpolate(Expression(analytical[dim]))
        l2 = sqrt(assemble(dot(u - a, u - a) * dx))
        if print_norm and op2.MPI.comm.rank == 0:
            print 'L2 error norm:', l2
        for task, timer in get_timers(reset=True).items():
            self.register_timing(task, timer.total)
示例#9
0
    def wave(self, scale=1.0, lump_mass=True, N=100, save=False, weak=False,
             verbose=False, measure_overhead=False):
        if weak:
            self.series['weak'] = scale
            scale = round(scale/sqrt(op2.MPI.comm.size), 3)
            self.meta['scale'] = scale
        else:
            self.series['scale'] = scale
        self.meta['cells'] = cells[scale]
        self.meta['vertices'] = vertices[scale]
        if measure_overhead:
            mesh = UnitSquareMesh(1, 1)
        else:
            t_, mesh = self.make_mesh(scale)
            self.register_timing('mesh', t_)
        with self.timed_region('setup'):
            V = FunctionSpace(mesh, 'Lagrange', 1)
            total_dofs = np.zeros(1, dtype=int)
            op2.MPI.comm.Allreduce(np.array([V.dof_dset.size], dtype=int), total_dofs)
            self.meta['dofs'] = total_dofs[0]
            if verbose:
                print '[%d]' % op2.MPI.comm.rank, 'DOFs:', V.dof_dset.size
            p = Function(V)
            phi = Function(V, name="phi")

            u = TrialFunction(V)
            v = TestFunction(V)

            bcval = Constant(0.0)
            bc = DirichletBC(V, bcval, 1)

            if lump_mass:
                Ml = assemble(1.0 / assemble(v*dx))

            dt = 0.001 * scale
            dtc = Constant(dt)
            t = 0.0

            rhs = inner(grad(v), grad(phi)) * dx

            if save:
                outfile = File("vtk/firedrake_wave_%s.pvd" % scale)
                outfile << phi

        b = assemble(rhs)
        dphi = 0.5 * dtc * p
        dp = dtc * Ml * b
        if measure_overhead:
            repeats = 1000
            tic('phi')
            for _ in range(repeats):
                phi -= dphi
                phi.dat.data_ro
            phi_overhead = N*toc('phi')/repeats
            print "phi overhead:", phi_overhead
            tic('p')
            for _ in range(repeats):
                bcval.assign(sin(2*pi*5*_*dt))
                assemble(rhs, tensor=b)
                p += dp
                bc.apply(p)
                p.dat.data_ro
            p_overhead = N*toc('p')/repeats
            print "p overhead:", p_overhead
            return phi_overhead, p_overhead
        with self.timed_region('timestepping'):
            while t < N*dt:
                bcval.assign(sin(2*pi*5*t))

                with self.timed_region('phi'):
                    phi -= dphi
                    phi.dat.data_ro

                with self.timed_region('p'):
                    if lump_mass:
                        assemble(rhs, tensor=b)
                        p += dp
                        bc.apply(p)
                        p.dat.data_ro
                    else:
                        solve(u * v * dx == v * p * dx + dtc * rhs,
                              p, bcs=bc, solver_parameters={'ksp_type': 'cg',
                                                            'pc_type': 'sor',
                                                            'pc_sor_symmetric': True})

                with self.timed_region('phi'):
                    phi -= dphi
                    phi.dat.data_ro

                t += dt
                if save:
                    outfile << phi
        for task, timer in get_timers(reset=True).items():
            self.register_timing(task, timer.total)
    def advection_diffusion(self, size=64, degree=1, dim=2, verbose=False,
                            dt=0.0001, T=0.01, Tend=0.011, diffusivity=0.1,
                            advection=True, diffusion=True, weak=False,
                            print_norm=False, preassemble=True, pc='hypre',
                            strong_threshold=0.25, agg_nl=2, max_levels=25):
        if weak:
            size = int((1e4*op2.MPI.comm.size)**(1./dim))
            self.meta['size'] = size
        else:
            self.series['size'] = size
        self.meta['cells'] = (2 if dim == 2 else 6)*size**dim
        self.meta['dofs'] = (size+1)**dim
        adv_params = {'ksp_type': 'cg',
                      'pc_type': 'jacobi',
                      'ksp_rtol': 1e-6,
                      'ksp_atol': 1e-15}
        diff_params = {'ksp_type': 'cg',
                       'pc_type': pc,
                       'pc_hypre_type': 'boomeramg',
                       'pc_hypre_boomeramg_strong_threshold': strong_threshold,
                       'pc_hypre_boomeramg_agg_nl': agg_nl,
                       'pc_hypre_boomeramg_max_levels': max_levels,
                       'ksp_rtol': 1e-6,
                       'ksp_atol': 1e-15}
        if verbose:
            diff_params['pc_hypre_boomeramg_print_statistics'] = True
            diff_params['ksp_view'] = True
            diff_params['ksp_monitor'] = True
            adv_params['ksp_view'] = True
            adv_params['ksp_monitor'] = True
        t_, mesh = self.make_mesh(size, dim)
        self.register_timing('mesh', t_)

        with self.timed_region('setup'):
            V = FunctionSpace(mesh, "CG", degree)
            if verbose:
                print '[%d]' % op2.MPI.comm.rank, 'DOFs:', V.dof_dset.size
            U = VectorFunctionSpace(mesh, "CG", degree)

            p = TrialFunction(V)
            q = TestFunction(V)
            t = Function(V)
            u = Function(U)

            adv = p * q * dx
            adv_rhs = (q * t + dt * dot(grad(q), u) * t) * dx

            d = -dt * diffusivity * dot(grad(q), grad(p)) * dx

            diff = adv - 0.5 * d
            diff_rhs = action(adv + 0.5 * d, t)

            # Set initial condition:
            # A*(e^(-r^2/(4*D*T)) / (4*pi*D*T))
            # with normalisation A = 0.1, diffusivity D = 0.1
            r2 = "(pow(x[0]-(0.45+%(T)f), 2.0) + pow(x[1]-0.5, 2.0))"
            fexpr = "0.1 * (exp(-" + r2 + "/(0.4*%(T)f)) / (0.4*pi*%(T)f))"
            t.interpolate(Expression(fexpr % {'T': T}))
            u.interpolate(Expression((1.0, 0.0)))
            t.dat.data_ro
            u.dat.data_ro

        if preassemble:
            if advection:
                with self.timed_region('advection matrix'):
                    A = assemble(adv)
                    A.M
            if diffusion:
                with self.timed_region('diffusion matrix'):
                    D = assemble(diff)
                    D.M

        with self.timed_region('timestepping'):
            while T < Tend:

                # Advection
                if advection:
                    if preassemble:
                        with self.timed_region('advection RHS'):
                            b = assemble(adv_rhs)
                            b.dat.data_ro
                        with self.timed_region('advection solve'):
                            solve(A, t, b, solver_parameters=adv_params)
                    else:
                        solve(adv == adv_rhs, t, solver_parameters=adv_params)

                # Diffusion
                if diffusion:
                    if preassemble:
                        with self.timed_region('diffusion RHS'):
                            b = assemble(diff_rhs)
                            b.dat.data_ro
                        with self.timed_region('diffusion solve'):
                            solve(D, t, b, solver_parameters=diff_params)
                    else:
                        solve(diff == diff_rhs, t, solver_parameters=diff_params)

                T = T + dt

        # Analytical solution
        a = Function(V).interpolate(Expression(fexpr % {'T': T}))
        l2 = sqrt(assemble(dot(t - a, t - a) * dx))
        if print_norm and op2.MPI.comm.rank == 0:
            print 'L2 error norm:', l2
        for task, timer in get_timers(reset=True).items():
            self.register_timing(task, timer.total)
示例#11
0
    def navier_stokes(self,
                      scale=1.0,
                      T=0.1,
                      preassemble=True,
                      save=False,
                      weak=False,
                      compute_norms=False):
        if weak:
            self.series['weak'] = scale
            scale = round(scale / sqrt(op2.MPI.comm.size), 3)
            self.meta['scale'] = scale
        else:
            self.series['scale'] = scale
        self.meta['cells'] = cells[scale]
        self.meta['vertices'] = vertices[scale]
        t_, mesh = self.make_mesh(scale)
        self.register_timing('mesh', t_)

        with self.timed_region('setup'):
            # Define function spaces (P2-P1)
            V = VectorFunctionSpace(mesh, "Lagrange", 2)
            Q = FunctionSpace(mesh, "Lagrange", 1)

            # Define trial and test functions
            u = TrialFunction(V)
            p = TrialFunction(Q)
            v = TestFunction(V)
            q = TestFunction(Q)

            # Set parameter values
            dt = 0.01
            nu = 0.01

            # Define time-dependent pressure boundary condition
            p_in = Constant(0.0)

            # Define boundary conditions
            noslip = DirichletBC(V, Constant((0.0, 0.0)), (1, 3, 4, 6))
            inflow = DirichletBC(Q, p_in, 5)
            outflow = DirichletBC(Q, 0, 2)
            bcu = [noslip]
            bcp = [inflow, outflow]

            # Create functions
            u0 = Function(V)
            u1 = Function(V)
            p1 = Function(Q)

            # Define coefficients
            k = Constant(dt)
            f = Constant((0, 0))

            # Tentative velocity step
            F1 = (1/k)*inner(u - u0, v)*dx + inner(grad(u0)*u0, v)*dx + \
                nu*inner(grad(u), grad(v))*dx - inner(f, v)*dx
            a1 = lhs(F1)
            L1 = rhs(F1)

            # Pressure update
            a2 = inner(grad(p), grad(q)) * dx
            L2 = -(1 / k) * div(u1) * q * dx

            # Velocity update
            a3 = inner(u, v) * dx
            L3 = inner(u1, v) * dx - k * inner(grad(p1), v) * dx

        if preassemble:
            with self.timed_region('matrix assembly'):
                # Assemble matrices
                A1 = assemble(a1, bcs=bcu)
                A2 = assemble(a2, bcs=bcp)
                A3 = assemble(a3, bcs=bcu)
                A1.M
                A2.M
                A3.M

        if save:
            # Create files for storing solution
            ufile = File("vtk/firedrake_velocity.pvd")
            pfile = File("vtk/firedrake_pressure.pvd")

        vparams = {
            'ksp_type': 'gmres',
            'pc_type': 'bjacobi',
            'sub_pc_type': 'ilu',
            'ksp_rtol': 1e-6,
            'ksp_atol': 1e-15
        }
        pparams = {
            'ksp_type': 'cg',
            'pc_type': 'bjacobi',
            'sub_pc_type': 'ilu',
            'ksp_rtol': 1e-6,
            'ksp_atol': 1e-15
        }

        with self.timed_region('timestepping'):
            # Time-stepping
            t = dt
            while t < T + 1e-14:
                # Update pressure boundary condition
                p_in.assign(sin(3.0 * t))

                # Compute tentative velocity step
                info("Computing tentative velocity")
                if preassemble:
                    with self.timed_region('tentative velocity RHS'):
                        b1 = assemble(L1)
                        [bc.apply(A1, b1) for bc in bcu]
                        b1.dat.data_ro
                    with self.timed_region('tentative velocity solve'):
                        solve(A1, u1, b1, solver_parameters=vparams)
                        u1.dat.data_ro
                else:
                    with self.timed_region('tentative velocity solve'):
                        solve(a1 == L1, u1, bcs=bcu, solver_parameters=vparams)
                        u1.dat.data_ro

                # Pressure correction
                info("Computing pressure correction")
                if preassemble:
                    with self.timed_region('pressure correction RHS'):
                        b2 = assemble(L2)
                        [bc.apply(A2, b2) for bc in bcp]
                        b2.dat.data_ro
                    with self.timed_region('pressure correction solve'):
                        solve(A2, p1, b2, solver_parameters=pparams)
                        p1.dat.data_ro
                else:
                    with self.timed_region('pressure correction solve'):
                        solve(a2 == L2, p1, bcs=bcp, solver_parameters=pparams)
                        p1.dat.data_ro

                # Velocity correction
                info("Computing velocity correction")
                if preassemble:
                    with self.timed_region('velocity correction RHS'):
                        b3 = assemble(L3)
                        [bc.apply(A3, b3) for bc in bcu]
                        b3.dat.data_ro
                    with self.timed_region('velocity correction solve'):
                        solve(A3, u1, b3, solver_parameters=vparams)
                        u1.dat.data_ro
                else:
                    with self.timed_region('velocity correction solve'):
                        solve(a3 == L3, u1, bcs=bcu, solver_parameters=vparams)
                        u1.dat.data_ro

                if save:
                    # Save to file
                    ufile << u1
                    pfile << p1

                if compute_norms:
                    nu1, np1 = norm(u1), norm(p1)
                    if op2.MPI.comm.rank == 0:
                        print t, 'u1:', nu1, 'p1:', np1

                # Move to next time step
                u0.assign(u1)
                t += dt
        for task, timer in get_timers(reset=True).items():
            self.register_timing(task, timer.total)
示例#12
0
 def test_reset_timers(self):
     tic('test_reset')
     toc('test_reset')
     reset_timers()
     assert get_timers().keys() == []
示例#13
0
 def test_create(self):
     tic('create')
     toc('create')
     assert 'create' in get_timers().keys()
示例#14
0
 def test_create(self):
     tic('create')
     toc('create')
     assert 'create' in get_timers().keys()
示例#15
0
 def test_reset_timers(self):
     tic('test_reset')
     toc('test_reset')
     reset_timers()
     assert get_timers().keys() == []
    def poisson(self, size=32, degree=1, dim=3, preassemble=True, weak=False,
                print_norm=True, verbose=False, measure_overhead=False,
                pc='hypre', strong_threshold=0.75, agg_nl=2, max_levels=25):
        if weak:
            self.series['weak'] = size
            size = int((size*op2.MPI.comm.size)**(1./dim))
            self.meta['size'] = size
        else:
            self.series['size'] = size
        self.series['degree'] = degree
        self.meta['cells'] = 6*size**dim
        self.meta['vertices'] = (size+1)**dim
        params = {'ksp_type': 'cg',
                  'pc_type': pc,
                  'pc_hypre_type': 'boomeramg',
                  'pc_hypre_boomeramg_strong_threshold': strong_threshold,
                  'pc_hypre_boomeramg_agg_nl': agg_nl,
                  'pc_hypre_boomeramg_max_levels': max_levels,
                  'ksp_rtol': 1e-6,
                  'ksp_atol': 1e-15}
        if verbose:
            params['pc_hypre_boomeramg_print_statistics'] = True
            params['ksp_view'] = True
            params['ksp_monitor'] = True
        t_, mesh = self.make_mesh(size, dim)
        self.register_timing('mesh', t_)
        with self.timed_region('setup'):
            V = FunctionSpace(mesh, "Lagrange", degree)
            if verbose:
                print '[%d]' % op2.MPI.comm.rank, 'DOFs:', V.dof_dset.size

            # Define boundary condition
            bc = DirichletBC(V, 0.0, [3, 4])

            # Define variational problem
            u = TrialFunction(V)
            v = TestFunction(V)
            f = Function(V).interpolate(Expression(initial[dim]))
            f.dat.data_ro
            a = inner(grad(u), grad(v))*dx
            L = f*v*dx

            # Compute solution
            u = Function(V)
        if measure_overhead:
            print "Matrix assembly overhead:", self.lhs_ffc_overhead(a, bc)
            print "RHS assembly overhead:", self.rhs_ffc_overhead(L, bc)
            return
        if preassemble:
            with self.timed_region('matrix assembly'):
                A = assemble(a, bcs=bc)
                A.M
            self.meta['dofs'] = A.M.handle.sizes[0][1]
            with self.timed_region('rhs assembly'):
                b = assemble(L)
                bc.apply(b)
                b.dat.data_ro
            with self.timed_region('solve'):
                solve(A, u, b, solver_parameters=params)
                u.dat.data_ro
        else:
            with self.timed_region('solve'):
                solve(a == L, u, bcs=[bc], solver_parameters=params)
                u.dat.data_ro

        # Analytical solution
        a = Function(V).interpolate(Expression(analytical[dim]))
        l2 = sqrt(assemble(dot(u - a, u - a) * dx))
        if print_norm and op2.MPI.comm.rank == 0:
            print 'L2 error norm:', l2
        for task, timer in get_timers(reset=True).items():
            self.register_timing(task, timer.total)
    def navier_stokes(self, scale=1.0, T=0.1, preassemble=True, save=False,
                      weak=False, compute_norms=False):
        if weak:
            self.series['weak'] = scale
            scale = round(scale/sqrt(op2.MPI.comm.size), 3)
            self.meta['scale'] = scale
        else:
            self.series['scale'] = scale
        self.meta['cells'] = cells[scale]
        self.meta['vertices'] = vertices[scale]
        t_, mesh = self.make_mesh(scale)
        self.register_timing('mesh', t_)

        with self.timed_region('setup'):
            # Define function spaces (P2-P1)
            V = VectorFunctionSpace(mesh, "Lagrange", 2)
            Q = FunctionSpace(mesh, "Lagrange", 1)

            # Define trial and test functions
            u = TrialFunction(V)
            p = TrialFunction(Q)
            v = TestFunction(V)
            q = TestFunction(Q)

            # Set parameter values
            dt = 0.01
            nu = 0.01

            # Define time-dependent pressure boundary condition
            p_in = Constant(0.0)

            # Define boundary conditions
            noslip = DirichletBC(V, Constant((0.0, 0.0)), (1, 3, 4, 6))
            inflow = DirichletBC(Q, p_in, 5)
            outflow = DirichletBC(Q, 0, 2)
            bcu = [noslip]
            bcp = [inflow, outflow]

            # Create functions
            u0 = Function(V)
            u1 = Function(V)
            p1 = Function(Q)

            # Define coefficients
            k = Constant(dt)
            f = Constant((0, 0))

            # Tentative velocity step
            F1 = (1/k)*inner(u - u0, v)*dx + inner(grad(u0)*u0, v)*dx + \
                nu*inner(grad(u), grad(v))*dx - inner(f, v)*dx
            a1 = lhs(F1)
            L1 = rhs(F1)

            # Pressure update
            a2 = inner(grad(p), grad(q))*dx
            L2 = -(1/k)*div(u1)*q*dx

            # Velocity update
            a3 = inner(u, v)*dx
            L3 = inner(u1, v)*dx - k*inner(grad(p1), v)*dx

        if preassemble:
            with self.timed_region('matrix assembly'):
                # Assemble matrices
                A1 = assemble(a1, bcs=bcu)
                A2 = assemble(a2, bcs=bcp)
                A3 = assemble(a3, bcs=bcu)
                A1.M
                A2.M
                A3.M

        if save:
            # Create files for storing solution
            ufile = File("vtk/firedrake_velocity.pvd")
            pfile = File("vtk/firedrake_pressure.pvd")

        vparams = {'ksp_type': 'gmres',
                   'pc_type': 'bjacobi',
                   'sub_pc_type': 'ilu',
                   'ksp_rtol': 1e-6,
                   'ksp_atol': 1e-15}
        pparams = {'ksp_type': 'cg',
                   'pc_type': 'bjacobi',
                   'sub_pc_type': 'ilu',
                   'ksp_rtol': 1e-6,
                   'ksp_atol': 1e-15}

        with self.timed_region('timestepping'):
            # Time-stepping
            t = dt
            while t < T + 1e-14:
                # Update pressure boundary condition
                p_in.assign(sin(3.0*t))

                # Compute tentative velocity step
                info("Computing tentative velocity")
                if preassemble:
                    with self.timed_region('tentative velocity RHS'):
                        b1 = assemble(L1)
                        [bc.apply(A1, b1) for bc in bcu]
                        b1.dat.data_ro
                    with self.timed_region('tentative velocity solve'):
                        solve(A1, u1, b1, solver_parameters=vparams)
                        u1.dat.data_ro
                else:
                    with self.timed_region('tentative velocity solve'):
                        solve(a1 == L1, u1, bcs=bcu, solver_parameters=vparams)
                        u1.dat.data_ro

                # Pressure correction
                info("Computing pressure correction")
                if preassemble:
                    with self.timed_region('pressure correction RHS'):
                        b2 = assemble(L2)
                        [bc.apply(A2, b2) for bc in bcp]
                        b2.dat.data_ro
                    with self.timed_region('pressure correction solve'):
                        solve(A2, p1, b2, solver_parameters=pparams)
                        p1.dat.data_ro
                else:
                    with self.timed_region('pressure correction solve'):
                        solve(a2 == L2, p1, bcs=bcp, solver_parameters=pparams)
                        p1.dat.data_ro

                # Velocity correction
                info("Computing velocity correction")
                if preassemble:
                    with self.timed_region('velocity correction RHS'):
                        b3 = assemble(L3)
                        [bc.apply(A3, b3) for bc in bcu]
                        b3.dat.data_ro
                    with self.timed_region('velocity correction solve'):
                        solve(A3, u1, b3, solver_parameters=vparams)
                        u1.dat.data_ro
                else:
                    with self.timed_region('velocity correction solve'):
                        solve(a3 == L3, u1, bcs=bcu, solver_parameters=vparams)
                        u1.dat.data_ro

                if save:
                    # Save to file
                    ufile << u1
                    pfile << p1

                if compute_norms:
                    nu1, np1 = norm(u1), norm(p1)
                    if op2.MPI.comm.rank == 0:
                        print t, 'u1:', nu1, 'p1:', np1

                # Move to next time step
                u0.assign(u1)
                t += dt
        for task, timer in get_timers(reset=True).items():
            self.register_timing(task, timer.total)
示例#18
0
 def test_reset(self):
     tic("test_reset")
     toc("test_reset")
     reset()
     assert get_timers().keys() == []
示例#19
0
 def test_create(self):
     tic("create")
     toc("create")
     assert "create" in get_timers().keys()
    def cahn_hilliard(self, size=96, steps=10, degree=1, pc='fieldsplit',
                      inner_ksp='preonly', ksp='gmres', maxit=1, weak=False,
                      measure_overhead=False, save=False, compute_norms=True,
                      verbose=False):
        if weak:
            self.series['weak'] = size
            size = int((size*op2.MPI.comm.size)**0.5)
            self.meta['size'] = size
        else:
            self.series['size'] = size
        self.meta['cells'] = 2*size**2
        self.meta['vertices'] = (size+1)**2
        params = {'pc_type': pc,
                  'ksp_type': ksp,
                  'snes_rtol': 1e-9,
                  'snes_atol': 1e-10,
                  'snes_stol': 1e-16,
                  'snes_linesearch_type': 'basic',
                  'snes_linesearch_max_it': 1,
                  'ksp_rtol': 1e-6,
                  'ksp_atol': 1e-15,
                  'pc_fieldsplit_type': 'schur',
                  'pc_fieldsplit_schur_factorization_type': 'lower',
                  'pc_fieldsplit_schur_precondition': 'user',
                  'fieldsplit_0_ksp_type': inner_ksp,
                  'fieldsplit_0_ksp_max_it': maxit,
                  'fieldsplit_0_pc_type': 'hypre',
                  'fieldsplit_1_ksp_type': inner_ksp,
                  'fieldsplit_1_ksp_max_it': maxit,
                  'fieldsplit_1_pc_type': 'mat'}
        if verbose:
            params['ksp_monitor'] = True
            params['snes_view'] = True
            params['snes_monitor'] = True

        t_, mesh = self.make_mesh(size)
        self.register_timing('mesh', t_)

        with self.timed_region('setup'):
            V = FunctionSpace(mesh, "Lagrange", degree)
            ME = V*V

            # Define trial and test functions
            du = TrialFunction(ME)
            q, v = TestFunctions(ME)

            # Define functions
            u = Function(ME)   # current solution
            u0 = Function(ME)  # solution from previous converged step

            # Split mixed functions
            dc, dmu = split(du)
            c, mu = split(u)
            c0, mu0 = split(u0)

            with self.timed_region('initial condition'):
                # Create intial conditions and interpolate
                init_code = "A[0] = 0.63 + 0.02*(0.5 - (double)random()/RAND_MAX);"
                user_code = """int __rank;
                MPI_Comm_rank(MPI_COMM_WORLD, &__rank);
                srandom(2 + __rank);"""
                par_loop(init_code, direct, {'A': (u[0], WRITE)},
                         headers=["#include <stdlib.h>"], user_code=user_code)
                u.dat.data_ro

            # Compute the chemical potential df/dc
            c = variable(c)
            f = 100*c**2*(1-c)**2
            dfdc = diff(f, c)

            mu_mid = (1.0-theta)*mu0 + theta*mu

            # Weak statement of the equations
            F0 = c*q*dx - c0*q*dx + dt*dot(grad(mu_mid), grad(q))*dx
            F1 = mu*v*dx - dfdc*v*dx - lmbda*dot(grad(c), grad(v))*dx
            F = F0 + F1

            # Compute directional derivative about u in the direction of du (Jacobian)
            J = derivative(F, u, du)

            problem = NonlinearVariationalProblem(F, u, J=J)
            solver = NonlinearVariationalSolver(problem, solver_parameters=params)

            if pc in ['fieldsplit', 'ilu']:
                sigma = 100
                # PC for the Schur complement solve
                trial = TrialFunction(V)
                test = TestFunction(V)
                mass = assemble(inner(trial, test)*dx).M.handle
                a = 1
                c = (dt * lmbda)/(1+dt * sigma)
                hats = assemble(sqrt(a) * inner(trial, test)*dx + sqrt(c)*inner(grad(trial), grad(test))*dx).M.handle

                from firedrake.petsc import PETSc
                ksp_hats = PETSc.KSP()
                ksp_hats.create()
                ksp_hats.setOperators(hats)
                opts = PETSc.Options()

                opts['ksp_type'] = inner_ksp
                opts['ksp_max_it'] = maxit
                opts['pc_type'] = 'hypre'
                ksp_hats.setFromOptions()

                class SchurInv(object):
                    def mult(self, mat, x, y):
                        tmp1 = y.duplicate()
                        tmp2 = y.duplicate()
                        ksp_hats.solve(x, tmp1)
                        mass.mult(tmp1, tmp2)
                        ksp_hats.solve(tmp2, y)

                pc_schur = PETSc.Mat()
                pc_schur.createPython(mass.getSizes(), SchurInv())
                pc_schur.setUp()
                pc = solver.snes.ksp.pc
                pc.setFieldSplitSchurPreType(PETSc.PC.SchurPreType.USER, pc_schur)

            # Output file
            if save:
                file = File("vtk/firedrake_cahn_hilliard_%d.pvd" % size)

        if measure_overhead:
            for _ in range(100):
                u0.assign(u)
                solver.solve()
            print "Assembly overhead:", timing("Assemble cells", total=False)
            print "Solver overhead:", timing("SNES solver execution", total=False)
            return
        with self.timed_region('timestepping'):
            for step in range(steps):
                with self.timed_region('timestep_%s' % step):
                    u0.assign(u)
                    solver.solve()
                if save:
                    file << (u.split()[0], step)
                if compute_norms:
                    nu = norm(u)
                    if op2.MPI.comm.rank == 0:
                        print step, 'L2(u):', nu
        for task, timer in get_timers(reset=True).items():
            self.register_timing(task, timer.total)