from firedrake import *
from firedrake.utils import cached_property

from abc import ABCMeta, abstractproperty


class Problem(object):

    __metaclass__ = ABCMeta

    def __init__(self, N=None, degree=None, dimension=None,
                 quadrilaterals=False):
        super(Problem, self).__init__()

        self.degree = degree
        self.N = N
        self.dim = dimension
        self.quads = quadrilaterals

    @property
    def comm(self):
        return self.mesh.comm

    @cached_property
    def mesh(self):
        if self.dim == 2:
            return UnitSquareMesh(self.N, self.N, quadrilateral=self.quads)
        else:
            assert self.dim == 3
            if self.quads:
                base = UnitSquareMesh(self.N, self.N, quadrilateral=self.quads)
                return ExtrudedMesh(base, self.N, layer_height=1.0/self.N)
            else:
                return UnitCubeMesh(self.N, self.N, self.N)

    @abstractproperty
    def name(self):
        pass

    @abstractproperty
    def function_space(self):
        pass

    @abstractproperty
    def u(self):
        pass

    @abstractproperty
    def a(self):
        pass

    @abstractproperty
    def L(self):
        pass

    @abstractproperty
    def bcs(self):
        pass

    @cached_property
    def analytic_solution(self):
        x = SpatialCoordinate(self.mesh)
        if self.dim == 2:
            return exp(sin(3*pi*x[0])*sin(3*pi*x[1]))
        else:
            assert self.dim == 3
            return exp(sin(3*pi*x[0])*sin(3*pi*x[1])*sin(3*pi*x[2]))

    def solver(self, parameters=None):

        problem = LinearVariationalProblem(self.a, self.L, self.u,
                                           bcs=self.bcs)
        solver = LinearVariationalSolver(problem, solver_parameters=parameters)

        return solver

    @abstractproperty
    def output(self):
        pass

    @abstractproperty
    def err(self):
        pass

    @abstractproperty
    def true_err(self):
        pass

    @abstractproperty
    def sol(self):
        pass

@@ -1406,34 +1406,32 @@
  return exp(sin(
-3*
 pi*x%5B0%5D)*sin(3*p
@@ -1419,34 +1419,32 @@
 in(pi*x%5B0%5D)*sin(
-3*
 pi*x%5B1%5D))%0A      
@@ -1507,26 +1507,24 @@
 urn exp(sin(
-3*
 pi*x%5B0%5D)*sin
@@ -1520,26 +1520,24 @@
 i*x%5B0%5D)*sin(
-3*
 pi*x%5B1%5D)*sin
@@ -1541,10 +1541,8 @@
 sin(
-3*
 pi*x

Change analytic solution