from abc import ABCMeta, abstractmethod

class Advection(object):
    """
    Base class for advection schemes for dcore.

    :arg state: x :class:`.State` object.
    """
    __metaclass__ = ABCMeta

    def __init__(self, state):
        self.state = state
    
    @abstractmethod
    def apply(self, x, x_out):
        """
        Function takes x as input, computes F(x) and returns x_out
        as output.

        :arg x: :class:`.Function` object, the input Function.
        :arg x_out: :class:`.Function` object, the output Function.
        """
        pass    

class NoAdvection(Advection):
    """
    An non-advection scheme that does nothing.
    """

    def __init__(self, state):
        self.state = state

        #create a ubar field even though we don't use it.
        self.ubar = Function(state.V1)

    def apply(self, x_in, x_out):

        x_out.assign(x_in)

class LinearAdvection(Advection):
    """
    An advection scheme that uses the linearised background state 
    in evaluation of the advection term.
    """

    def __init__(self, state, vertical_only = False):
        self.state = state
        self.ubar = Function(state.V1)



@@ -131,18 +131,16 @@
 g state:
- x
  :class:
@@ -894,32 +894,35 @@
  LinearAdvection
+_Vt
 (Advection):%0A   
@@ -1036,137 +1036,2276 @@
 term
-.%0A    %22%22%22%0A%0A    def __init__(self, state, vertical_only = False):%0A        self.state = state%0A        self.ubar = Function(state.V1)%0A%0A
+ for the Vt temperature space.%0A%0A    :arg state: :class:%60.State%60 object.%0A    :arg qbar: :class:%60.Function%60 object. The reference function that we %0A    are linearising around.%0A    :arg options: a PETSc options dictionary%0A    %22%22%22%0A%0A    def __init__(self, state, V, qbar, options = None):%0A        self.state = state%0A        self.ubar = Function(state.V1)%0A%0A        p = TestFunction(state.Vt)%0A        q = TrialFunction(state.Vt)%0A        %0A        dq = Function(Vt)%0A%0A        a = p*q*dx%0A        k = state.k #Upward pointing unit vector%0A        L = -p*dot(ubar,k)*dot(k,grad(qbar))*dx%0A%0A        aProblem = LinearVariationalProblem(a,L,dq)%0A        if options == None:%0A            options = %7B'ksp_type':'cg',%0A                       'pc_type':'bjacobi',%0A                       'sub_pc_type':'ilu'%7D%0A            %0A        self.solver = LinearVariationalSolver(aProblem,%0A                                              solver_parameters = options)%0A%0A    def apply(self, x_in, x_out):%0A        dt = self.state.dt%0A        self.solver.solve()%0A        x_out.assign(x_in + dt*dq)%0A%0A%0Aclass LinearAdvection_V3(Advection):%0A    %22%22%22%0A    An advection scheme that uses the linearised background state %0A    in evaluation of the advection term for the V3 DG space.%0A%0A    :arg state: :class:%60.State%60 object.%0A    :arg qbar: :class:%60.Function%60 object. The reference function that we %0A    are linearising around.%0A    :arg options: a PETSc options dictionary%0A    %22%22%22%0A%0A    def __init__(self, state, V, qbar, options = None):%0A        self.state = state%0A        self.ubar = Function(state.V1)%0A%0A        p = TestFunction(state.Vt)%0A        q = TrialFunction(state.Vt)%0A        %0A        dq = Function(Vt)%0A%0A        n = FacetNormals(state.mesh)%0A        %0A        a = p*q*dx%0A        L = dot(grad(p), ubar)*q*dx - jump(ubar*p, n)*avg(q)*(dS_v + dS_h)%0A%0A        aProblem = LinearVariationalProblem(a,L,dq)%0A        if options == None:%0A            options = %7B'ksp_type':'cg',%0A                       'pc_type':'bjacobi',%0A                       'sub_pc_type':'ilu'%7D%0A            %0A        self.solver = LinearVariationalSolver(aProblem,%0A                                              solver_parameters = options)%0A%0A    def apply(self, x_in, x_out):%0A        dt = self.state.dt%0A        self.solver.solve()%0A        x_out.assign(x_in + dt*dq)
 %0A

Make some linear advection methods.