Example #1
0
# A time vector, noting 1600sps is used.
tt = np.linspace(0, 32*10/1600, 32*10, endpoint=False)

# A phase comparison vector. This should be the idea output.
pt = np.concatenate((((2*np.pi*50.0*tt+np.pi) % (2*np.pi) - np.pi),(2*np.pi*ft*tt+np.pi) % (2*np.pi) - np.pi))

# The test input vector
yt =  np.concatenate((mag*np.cos(2*np.pi*50*tt) + dc_offset, mag*np.cos(2*np.pi*ft*tt) + dc_offset))

# Re-define tt to extend the full length.
tt = np.linspace(0, 2*32*10/1600, 2*32*10, endpoint=False)
step_time = (32*10)/1600 # used for drawing a line of the plots

# Create and run the filter, noting increasing the number of iterations
# will reduce the LES filter settling time at the cost of higher computation time.
les = LES(iterations=1)
les_out = les.run_les(yt)


# Visualisation of the output
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, sharex=True, sharey=False)
fig.suptitle('LES Freq Step Test', fontsize=16)

# Plots have the LES generated lines wider so the correct lines is overlayed and visable.
# Plot the phases
ax1.plot(tt, les_out[1], linewidth=3)
ax1.plot(tt, pt)
ax1.set_title('Phase (rad)')
ax1.axvline(x=step_time, ls='--', c='red')

# Plot the freqency
Example #2
0
    def solve(self, annotate=True):
        ''' Solve the shallow water equations '''

        ############################### Setting up the equations ###########################

        # Initialise solver settings
        if not type(self.problem) == SWProblem:
            raise TypeError("Do not know how to solve problem of type %s." %
                            type(self.problem))

        # Get parameters
        problem_params = self.problem.parameters
        solver_params = self.parameters
        farm = problem_params.tidal_farm
        if farm:
            turbine_friction = farm.friction_function

        # Performance settings
        parameters['form_compiler']['quadrature_degree'] = \
            solver_params.quadrature_degree
        parameters['form_compiler']['cpp_optimize_flags'] = \
            " ".join(solver_params.cpp_flags)
        parameters['form_compiler']['cpp_optimize'] = True
        parameters['form_compiler']['optimize'] = True

        # Get domain measures
        ds = problem_params.domain.ds
        dx = problem_params.domain.dx

        # Get the boundary normal direction
        n = FacetNormal(self.mesh)

        # Get temporal settings
        theta = Constant(problem_params.theta)
        dt = Constant(problem_params.dt)
        finish_time = Constant(problem_params.finish_time)
        t = Constant(problem_params.start_time)

        # Get equation settings
        g = problem_params.g
        h = problem_params.depth
        nu = problem_params.viscosity
        include_advection = problem_params.include_advection
        include_viscosity = problem_params.include_viscosity
        linear_divergence = problem_params.linear_divergence
        f_u = problem_params.f_u
        include_les = solver_params.les_model

        # Get boundary conditions
        bcs = problem_params.bcs

        # Get function spaces
        V, Q = self.V, self.Q
        dgu = "Discontinuous" in str(V)

        # Test and trial functions
        v = TestFunction(V)
        u = TrialFunction(V)
        q = TestFunction(Q)
        eta = TrialFunction(Q)

        # Functions
        u00 = Function(V)
        u0 = Function(V, name="u0")
        ut = Function(V)  # Tentative velocity
        u1 = Function(V, name="u")
        eta0 = Function(Q, name="eta0")
        eta1 = Function(Q, name="eta")

        # Large eddy model
        if include_les:
            les_V = FunctionSpace(problem_params.domain.mesh, "CG", 1)
            les = LES(les_V, u0,
                      solver_params.les_parameters['smagorinsky_coefficient'])
            eddy_viscosity = les.eddy_viscosity
            nu += eddy_viscosity
        else:
            eddy_viscosity = None

        # Define the water depth
        if linear_divergence:
            H = h
        else:
            H = eta0 + h

        if f_u is None:
            f_u = Constant((0, 0))

        # Bottom friction
        friction = problem_params.friction

        if farm:
            friction += Function(turbine_friction,
                                 name="turbine_friction",
                                 annotate=annotate)

        # Load initial conditions
        # Projection is necessary to obtain 2nd order convergence
        # FIXME: The problem should specify the ic for each component separately.
        u_ic = project(problem_params.initial_condition_u, self.V)
        u0.assign(u_ic, annotate=False)
        u00.assign(u_ic, annotate=False)
        eta_ic = project(problem_params.initial_condition_eta, self.Q)
        eta0.assign(eta_ic, annotate=False)
        eta1.assign(eta_ic, annotate=False)

        # Tentative velocity step
        u_mean = theta * u + (1. - theta) * u0
        u_bash = 3. / 2 * u0 - 1. / 2 * u00
        u_diff = u - u0
        norm_u0 = inner(u0, u0)**0.5
        F_u_tent = ((1 / dt) * inner(v, u_diff) * dx() +
                    inner(v,
                          grad(u_bash) * u_mean) * dx() +
                    g * inner(v, grad(eta0)) * dx() +
                    friction / H * norm_u0 * inner(u_mean, v) * dx -
                    inner(v, f_u) * dx())
        # Viscosity term
        if dgu:
            # Taken from http://maths.dur.ac.uk/~dma0mpj/summer_school/IPHO.pdf
            sigma = 1.  # Penalty parameter.
            # Set tau=-1 for SIPG, tau=0 for IIPG, and tau=1 for NIPG
            tau = 0.
            edgelen = FacetArea(self.mesh)('+')  # Facetarea is continuous, so
            # we can select either side
            alpha = sigma / edgelen

            F_u_tent += nu * inner(grad(v), grad(u_mean)) * dx()
            for d in range(2):
                F_u_tent += -nu * inner(avg(grad(u_mean[d])), jump(v[d],
                                                                   n)) * dS
                F_u_tent += -nu * tau * inner(avg(grad(v[d])), jump(u[d],
                                                                    n)) * dS
                F_u_tent += alpha * nu * inner(jump(u[d], n), jump(v[d],
                                                                   n)) * dS

        else:
            F_u_tent += nu * inner(grad(v), grad(u_mean)) * dx()

        a_u_tent = lhs(F_u_tent)
        L_u_tent = rhs(F_u_tent)

        # Pressure correction
        eta_diff = eta - eta0
        ut_mean = theta * ut + (1. - theta) * u0
        F_p_corr = (q * eta_diff + g * dt**2 * theta**2 * H *
                    inner(grad(q), grad(eta_diff))) * dx() + dt * q * div(
                        H * ut_mean) * dx()
        a_p_corr = lhs(F_p_corr)
        L_p_corr = rhs(F_p_corr)

        # Velocity correction
        eta_diff = eta1 - eta0
        a_u_corr = inner(v, u) * dx()
        L_u_corr = inner(v, ut) * dx() - dt * g * theta * inner(
            v, grad(eta_diff)) * dx()

        bcu, bceta = self._generate_strong_bcs(dgu)

        # Assemble matrices
        A_u_corr = assemble(a_u_corr)
        for bc in bcu:
            bc.apply(A_u_corr)
        a_u_corr_solver = LUSolver(A_u_corr)
        a_u_corr_solver.parameters["reuse_factorization"] = True

        if linear_divergence:
            A_p_corr = assemble(a_p_corr)
            for bc in bceta:
                bc.apply(A_p_corr)
            a_p_corr_solver = LUSolver(A_p_corr)
            a_p_corr_solver.parameters["reuse_factorization"] = True

        yield ({
            "time": t,
            "u": u0,
            "eta": eta0,
            "eddy_viscosity": eddy_viscosity,
            "is_final": self._finished(t, finish_time)
        })

        log(INFO, "Start of time loop")
        adjointer.time.start(t)
        timestep = 0

        # De/activate annotation
        annotate_orig = parameters["adjoint"]["stop_annotating"]
        parameters["adjoint"]["stop_annotating"] = not annotate

        while not self._finished(t, finish_time):
            # Update timestep
            timestep += 1
            t = Constant(t + dt)

            # Update bc's
            t_theta = Constant(t - (1.0 - theta) * dt)
            bcs.update_time(t, only_type=["strong_dirichlet"])
            bcs.update_time(t_theta, exclude_type=["strong_dirichlet"])

            # Update source term
            if f_u is not None:
                f_u.t = Constant(t_theta)

            if include_les:
                log(PROGRESS, "Compute eddy viscosity.")
                les.solve()

            # Compute tentative velocity step
            log(PROGRESS, "Solve for tentative velocity.")
            A_u_tent = assemble(a_u_tent)
            b = assemble(L_u_tent)
            for bc in bcu:
                bc.apply(A_u_tent, b)

            solve(A_u_tent, ut.vector(), b)

            # Pressure correction
            log(PROGRESS, "Solve for pressure correction.")
            b = assemble(L_p_corr)
            for bc in bceta:
                bc.apply(b)

            if linear_divergence:
                a_p_corr_solver.solve(eta1.vector(), b)
            else:
                A_p_corr = assemble(a_p_corr)
                for bc in bceta:
                    bc.apply(A_p_corr)
                solve(A_p_corr, eta1.vector(), b)

            # Velocity correction
            log(PROGRESS, "Solve for velocity update.")
            b = assemble(L_u_corr)
            for bc in bcu:
                bc.apply(b)

            a_u_corr_solver.solve(u1.vector(), b)

            # Rotate functions for next timestep
            u00.assign(u0)
            u0.assign(u1)
            eta0.assign(eta1)

            # Increase the adjoint timestep
            adj_inc_timestep(time=float(t),
                             finished=self._finished(t, finish_time))

            yield ({
                "time": t,
                "u": u0,
                "eta": eta0,
                "eddy_viscosity": eddy_viscosity,
                "is_final": self._finished(t, finish_time)
            })

        # Reset annotation flag
        parameters["adjoint"]["stop_annotating"] = annotate_orig

        log(INFO, "End of time loop.")