예제 #1
0
def subdomain_interpolate(pairs, V, reduce='last'):
    '''(f, chi), V -> Function fh in V such that fh|chi is f'''
    array = lambda f: f.vector().get_local()
    fs, chis = zip(*pairs)
    
    fs = np.column_stack([array(interpolate(f, V)) for f in fs])
    x = np.column_stack([array(interpolate(Expression('x[%d]' % i, degree=1), V)) for i in range(V.mesh().geometry().dim())])

    chis = [CompiledSubDomain(chi, tol=1E-10) for chi in chis]
    is_masked = np.column_stack([map(lambda xi, chi=chi: not chi.inside(xi, False), x) for chi in chis])

    fs = mask.masked_array(fs, is_masked)

    if reduce == 'avg':
        values = np.mean(fs, axis=1)
    elif reduce == 'max':
        values = np.choose(np.argmax(fs, axis=1), fs.T)
    elif reduce == 'min':
        values = np.choose(np.argmin(fs, axis=1), fs.T)
    elif reduce == 'first':
        choice = [row.tolist().index(False) for row in is_masked]
        values = np.choose(choice, fs.T)
    elif reduce == 'last':
        choice = np.array([row[::-1].tolist().index(False) for row in is_masked], dtype=int)
        nsubs = len(chis)
        values = np.choose(nsubs-1-choice, fs.T)        
    else:
        raise ValueError

    fh = Function(V)
    fh.vector().set_local(values)

    return fh
예제 #2
0
def deactivate_cells(surfaces, volumes, ncells_x, ncells_y):
    '''The tile dimension is 0.1 x 0.025 x 0.025
    If the grid is
      oooooo
      oxxxxo
      oxxxxo
      oooooo
    I want to deactive o
    '''

    front = 0.025
    back = (ncells_y-1)*0.025
    left = 0.1
    right = (ncells_x-1)*0.1
    # Marking the boundary guys
    in_layer = CompiledSubDomain('x[0] > right || x[0] < left || x[1] > back || x[1] < front',
                                 left=left,
                                 right=right,
                                 front=front,
                                 back=back)
        
    predicate = lambda c: in_layer.inside(c.midpoint().array(), False)
    # Mark by only midpoint check
    bdry_cells = deactivate_volumes(volumes, tag=1, predicate=predicate)

    # Set the layer to 2 
    volumes.array()[bdry_cells] = 2
    # Now we have created a difference between layer and interior
    # Collect exterior ports of vol1 as surfaces between (1, 2)
    ext_ports = interfaces_between(volumes,
                                   ext_tag=1,
                                   tagged_cells=bdry_cells,
                                   int_tag=2,
                                   with_true_bdry=False)
    # Get all the facets in 2
    two_points = all_facets_of(mesh, bdry_cells, volumes, 2)
    # If I remove from them the ports I can safely kill of the remaining
    # facet; i.e. make them exterior
    surfaces.array()[list(set(two_points) - set(ext_ports))] = 0
    
    # Do that for volumes as well
    volumes.array()[bdry_cells] = 2

    return surfaces, volumes
예제 #3
0
def create_dirichlet_conditions(values, boundaries, function_spaces):
    """Create Dirichlet boundary conditions for given boundary values,
    boundaries and function space."""

    # Check that the size matches
    if len(values) != len(boundaries):
        error(
            "The number of Dirichlet values does not match the number of Dirichlet boundaries."
        )
    if len(values) != len(function_spaces):
        error(
            "The number of Dirichlet values does not match the number of function spaces."
        )
    if len(boundaries) != len(function_spaces):
        error(
            "The number of Dirichlet boundaries  does not match the number of function spaces."
        )

    info("Creating %d Dirichlet boundary condition(s)." % len(values))

    # Create Dirichlet conditions
    bcs = []
    for (i, value) in enumerate(values):

        # Get current boundary
        boundary = boundaries[i]
        function_space = function_spaces[i]

        # Case 0: boundary is a string
        if isinstance(boundary, str):
            boundary = CompiledSubDomain(boundary)
            bc = DirichletBC(function_space, value, boundary)

        # Case 1: boundary is a SubDomain
        elif isinstance(boundary, SubDomain):
            bc = DirichletBC(function_space, value, boundary)

        # Case 2: boundary is defined by a MeshFunction

        elif isinstance(boundary, tuple):
            mesh_function, index = boundary
            bc = DirichletBC(function_space, value, mesh_function, index)

        # Unhandled case
        else:
            error(
                "Unhandled boundary specification for boundary condition. "
                "Expecting a string, a SubDomain or a (MeshFunction, int) tuple."
            )

        bcs.append(bc)

    return bcs
예제 #4
0
def test_mpi_dependent_jiting():
    # FIXME: Not a proper unit test...
    from dolfin import (Expression, UnitSquareMesh, Function, TestFunction,
                        Form, FunctionSpace, dx, CompiledSubDomain,
                        SubSystemsManager)

    # Init petsc (needed to initalize petsc and slepc collectively on
    # all processes)
    SubSystemsManager.init_petsc()

    try:
        import mpi4py.MPI as mpi
    except ImportError:
        return

    try:
        import petsc4py.PETSc as petsc
    except ImportError:
        return

    # Set communicator and get process information
    comm = mpi.COMM_WORLD
    group = comm.Get_group()
    size = comm.Get_size()

    # Only consider parallel runs
    if size == 1:
        return

    rank = comm.Get_rank()
    group_comm_0 = petsc.Comm(comm.Create(group.Incl(range(1))))
    group_comm_1 = petsc.Comm(comm.Create(group.Incl(range(1, 2))))

    if size > 2:
        group_comm_2 = petsc.Comm(comm.Create(group.Incl(range(2, size))))

    if rank == 0:
        e = Expression("4", mpi_comm=group_comm_0, degree=0)

    elif rank == 1:
        e = Expression("5", mpi_comm=group_comm_1, degree=0)
        assert (e)
        domain = CompiledSubDomain("on_boundary",
                                   mpi_comm=group_comm_1,
                                   degree=0)
        assert (domain)

    else:
        mesh = UnitSquareMesh(group_comm_2, 2, 2)
        V = FunctionSpace(mesh, "P", 1)
        u = Function(V)
        v = TestFunction(V)
        Form(u * v * dx)
예제 #5
0
    def test_vertex_2d(self):
        mesh = UnitSquareMesh(8, 8)

        x = mesh.coordinates()
        min_ = np.min(x, axis=0)
        max_ = np.max(x, axis=0)

        tol = 1E-9  # The precision in gmsh isn't great, probably why DOLFIN's
        # periodic boundary computation is not working

        # Check x periodicity
        master = CompiledSubDomain('near(x[0], A, tol)', A=min_[0], tol=tol)
        slave = CompiledSubDomain('near(x[0], A, tol)', A=max_[0], tol=tol)

        shift_x = np.array([max_[0]-min_[0], 0])
        to_master = lambda x, shift=shift_x: x - shift

        error, mapping = compute_vertex_periodicity(mesh, master, slave, to_master)
        self.assertTrue(error < 10*tol)

        _, mapping = compute_entity_periodicity(1, mesh, master, slave, to_master)
        self.assertTrue(len(list(mapping.keys())) == 8)
예제 #6
0
파일: test_tile.py 프로젝트: MiroK/tieler
    def test_tiling(self):

        tile = UnitSquareMesh(2, 2)

        mf = MeshFunction('size_t', tile, tile.topology().dim() - 1, 0)
        CompiledSubDomain('near(x[0], 0.5) || near(x[1], 0.5)').mark(mf, 1)

        mesh_data = {}
        mesh_data = load_data(tile, mf, dim=1, data=mesh_data)

        mesh, mesh_data = TileMesh(tile, shape=(23, 13), mesh_data=mesh_data)
        f = mf_from_data(mesh, mesh_data)[1]

        self.assertTrue(
            np.linalg.norm(mesh.coordinates().min(axis=0) -
                           np.zeros(2)) < 1E-13)

        self.assertTrue(
            np.linalg.norm(mesh.coordinates().max(axis=0) -
                           np.array([23., 13.])) < 1E-13)

        self.assertTrue(23 * 13 * 4 == sum(1 for _ in SubsetIterator(f, 1)))
예제 #7
0
파일: tile.py 프로젝트: MiroK/tieler
def TileMesh(tile, shape, mesh_data={}, TOL=1E-9):
    '''
    [tile tile;
     tile tile;
     tile tile;
     tile tile]

    The shape is an ntuple describing the number of pieces put next 
    to each other in the i-th axis. mesh_data : (tdim, tag) -> [entities] 
    is the way to encode mesh data of the tile.
    '''
    # Sanity for glueing
    gdim = tile.geometry().dim()
    assert len(shape) <= gdim, (shape, gdim)
    # While evolve is general mesh writing is limited to simplices only (FIXME)
    # so we bail out early
    assert str(tile.ufl_cell()) in ('interval', 'triangle', 'tetrahedron')

    t = Timer('evolve')
    # Do nothing
    if all(v == 1 for v in shape): return tile, mesh_data

    # We want to evolve cells, vertices of the mesh using geometry information
    # and periodicity info
    x = tile.coordinates()
    min_x = np.min(x, axis=0)
    max_x = np.max(x, axis=0)
    shifts = max_x - min_x
    
    shifts_x = []  # Geometry
    vertex_mappings = []  # Periodicity
    # Compute geometrical shift for EVERY direction:
    for axis in range(len(shape)):
        shift = shifts[axis]
        # Vector to shift cell vertices
        shift_x = np.zeros(gdim); shift_x[axis] = shift
        shifts_x.append(shift_x)

        # Compute periodicity in the vertices
        to_master = lambda x, shift=shift_x: x - shift
        # Mapping facets
        master = CompiledSubDomain('near(x[i], A, tol)', i=axis, A=min_x[axis], tol=TOL)
        slave = CompiledSubDomain('near(x[i], A, tol)', i=axis, A=max_x[axis], tol=TOL)

        error, vertex_mapping = compute_vertex_periodicity(tile, master, slave, to_master)
        # Fail when exended direction is no periodic
        assert error < 10*TOL, error
        
        vertex_mappings.append(vertex_mapping)
    # The final piece of information is cells
    cells = np.empty((tile.num_cells(), tile.ufl_cell().num_vertices()), dtype='uintp')
    cells.ravel()[:] = tile.cells().flat
        
    # Evolve the mesh by tiling along the last direction in shape
    while shape:
        x, cells, vertex_mappings, shape = \
            evolve(x, cells, vertex_mappings, shape, shifts_x, mesh_data=mesh_data)
        
    info('\tEvolve took %g s ' % t.stop())

    # We evolve data but the mesh function is made out of it outside
    mesh = make_mesh(x, cells, tdim=tile.topology().dim(), gdim=gdim)

    return mesh, mesh_data
예제 #8
0
파일: utils.py 프로젝트: MiroK/emi-book-fem
def broken_norm(norm, subdomains, mesh=None):
    '''Eval norm on subdomains and combine'''
    # Subdomains can be string -> get compile
    if isinstance(first(subdomains), str):
        subdomains = [CompiledSubDomain(s, tol=1E-10) for s in subdomains]
        mesh = None

        def get_norm(u, uh):
            assert len(subdomains) == len(u)

            V = uh.function_space()
            mesh = V.mesh()
            cell_f = MeshFunction('size_t', mesh, mesh.topology().dim(), 0)

            error = 0
            for subd_i, u_i in zip(subdomains, u):
                cell_f.set_all(0)  # Reset!
                # Pick an edge
                subd_i.mark(cell_f, 1)
                mesh_i = SubMesh(mesh, cell_f, 1)
                # Edge local function space
                Vi = FunctionSpace(mesh_i, V.ufl_element())
                # The solution on it
                uh_i = interpolate(uh, Vi)
                # And the error there
                error_i = norm(u_i, uh_i)
                error += error_i**2
            error = sqrt(error)
            return error

        # Done
        return get_norm

    # CompiledSubDomain -> will be used to mark (go to base case)
    if hasattr(first(subdomains), 'mark'):
        return broken_norm(norm, subdomains, mesh=mesh)

    # Tuples of (tag, mesh_function)
    # Do some consistency checks; same mesh
    _, = set(first(p).mesh().id() for p in subdomains)
    mesh = first(first(subdomains)).mesh()
    # Cell functions ?
    _, = set(first(p).dim() for p in subdomains)
    dim = first(first(subdomains)).dim()

    assert mesh.topology().dim() == dim

    def get_norm(u, uh, mesh=mesh):
        assert len(subdomains) == len(u)

        V = uh.function_space()
        assert mesh.id() == V.mesh().id()

        error = 0
        # NOTE: u is tag -> solution
        for subd, tag in subdomains:
            mesh_i = SubMesh(mesh, subd, tag)
            # Edge local function space
            Vi = FunctionSpace(mesh_i, V.ufl_element())
            # The solution on it
            uh_i = interpolate(uh, Vi)
            # And the error there
            error_i = norm(u[tag], uh_i)
            error += error_i**2
        error = sqrt(error)
        return error

    # Done
    return get_norm
예제 #9
0
Created on Thu Feb 13 21:49:47 2020

@author: alexanderniewiarowski
"""

from dolfin import Constant, CompiledSubDomain, DirichletBC

try:
    from dolfin_adjoint import *
    ADJOINT = True
except ModuleNotFoundError:
    ADJOINT = False


# UNIT INTERVAL MESH BOUNDARIES
bd_all_1D = CompiledSubDomain("near(x[0], 0) || near(x[0], 1)")
bd_x_mid_1D = CompiledSubDomain("near(x[0], 0.5)")


# UNIT SQUARE MESH BOUNDARIES
bd_all = CompiledSubDomain("on_boundary")

# left and right
bd_x = CompiledSubDomain("(near(x[0], 0) && on_boundary) || (near(x[0], 1) && on_boundary)")

# bottom and top
bd_y = CompiledSubDomain("(near(x[1], 0) && on_boundary) || (near(x[1], 1) && on_boundary)")

# x=0.5
bd_x_mid = CompiledSubDomain("near(x[0], 0.5)")
def bottom_boundary(x, on_boundary):
    return on_boundary and near(x[1], 0.0)


def top_boundary(x, on_boundary):
    return on_boundary and near(x[1], 15.0E-3)


################################### FE part ###################################

P1 = FiniteElement('P', 'triangle', 2)
element = MixedElement([P1, P1, P1])
ME = FunctionSpace(mesh, element)

subdomain = CompiledSubDomain(
    '(pow((x[0] - 7.5E-3), 2) + pow((x[1] - 7.5E-3), 2)) <= pow(2.5E-3, 2)')
subdomains = MeshFunction("size_t", mesh, 2)
subdomains.set_all(0)
subdomain.mark(subdomains, 1)

fc = Constant(2.0)  # FCD
V0_r = FunctionSpace(mesh, 'DG', 0)
fc_function = Function(V0_r)
fc_val = [0.0, fc]

help = np.asarray(subdomains.array(), dtype=np.int32)
fc_function.vector()[:] = np.choose(help, fc_val)
zeroth = plot(fc_function, title="Fixed charge density, $c^f$")
plt.colorbar(zeroth)
plot(fc_function)
plt.xlim(0.0, 0.015)
예제 #11
0
    comm, [Point(0.0, 0.0, 0.0), Point(float(lmbdax), 1.0, float(lmbdaz))],
    [nx, ny, nz], CellType.Type.tetrahedron)

# Shift the mesh to line up with the initial step function condition
scale = db * (1.0 - db)
shift = Expression(("0.0", "x[1]*(H - x[1])/S*A*cos(pi/Lx*x[0])*cos(pi/Lz*x[2])", "0.0"),
                   A=0.02, Lx=lmbdax, Lz=lmbdaz, H=1.0, S=scale, degree=4)

V = VectorFunctionSpace(mesh, "CG", 1)
displacement = interpolate(shift, V)
ALE.move(mesh, displacement)

# Entrainment functional measures
de = 1
cf = MeshFunction("size_t", mesh, mesh.topology().dim(), 0)
CompiledSubDomain("x[1] > db - DOLFIN_EPS", db=db).mark(cf, de)
dx = Measure("dx", subdomain_data=cf)

# Setup particles
pres = 25
x = RandomBox(Point(xmin, ymin, zmin), Point(xmax, ymax, zmax)).generate([pres, pres, pres])
s = np.zeros((len(x), 1), dtype=np.float_)

# Interpolate initial function onto particles, index slot 1
property_idx = 1
ptcls = particles(x, [s], mesh)

# Define the variational (projection problem)
k = 1
W_e = FiniteElement("DG", mesh.ufl_cell(), k)
T_e = FiniteElement("DG", mesh.ufl_cell(), 0)
예제 #12
0
            if found:
                ch_values[entity] = p_values[p_entity]
                break
            
    return child_f

# -------------------------------------------------------------------

if __name__ == '__main__':
    from dolfin import (CompiledSubDomain, DomainBoundary, SubsetIterator,
                        UnitSquareMesh, Facet)
    from xii import EmbeddedMesh

    mesh = UnitSquareMesh(4, 4)
    surfaces = MeshFunction('size_t', mesh, 2, 0)
    CompiledSubDomain('x[0] > 0.5-DOLFIN_EPS').mark(surfaces, 1)

    # What should be trasfered
    f = MeshFunction('size_t', mesh, 1, 0)
    DomainBoundary().mark(f, 1)
    CompiledSubDomain('near(x[0], 0.5)').mark(f, 1)
    # Assign funky colors
    for i, e in enumerate(SubsetIterator(f, 1), 1): f[e] = i

    ch_mesh = EmbeddedMesh(surfaces, 1)
    ch_f = transfer_markers(ch_mesh, f)

    # Every color in child is found in parent and we get the midpoint right
    p_values, ch_values = list(f.array()), list(ch_f.array())

    for ch_value in set(ch_f.array()) - set((0, )):
def left_boundary(x, on_boundary):
    return on_boundary and near(x[0], 0.0)
def right_boundary(x, on_boundary):
    return on_boundary and near(x[0], 15.0e-3)
def bottom_boundary(x, on_boundary):
    return on_boundary and near(x[1], 0.0)
def top_boundary(x, on_boundary):
    return on_boundary and near(x[1], 15.0e-3) 

################################### FE part ###################################   
    
P1 = FiniteElement('P', 'triangle', 2)
element = MixedElement([P1, P1, P1])
ME = FunctionSpace(mesh, element)

subdomain = CompiledSubDomain("x[0] >= 5.0e-3 && x[0] <= 10.0e-3 && x[1] >= 5.0e-3 && x[1] <= 10.0e-3")
subdomains = MeshFunction("size_t", mesh, 2)
subdomains.set_all(0)        
subdomain.mark(subdomains, 1)

fc = Constant(2.0) # FCD
V0_r = FunctionSpace(mesh, 'DG', 0)
fc_function = Function(V0_r)
fc_val = [0.0, fc]

help = np.asarray(subdomains.array(), dtype = np.int32)
fc_function.vector()[:] = np.choose(help, fc_val)
zeroth = plot(fc_function, title = "Fixed charge density, $c^f$")
plt.colorbar(zeroth)
plot(fc_function)
plt.xlim(0.0, 0.015)
예제 #14
0
            f.write(options)  # Options and alpha go as comments
            f.write('# %s\n' % alpha_str)

        print RED % (header % str(alpha))

        wh, mms_data = analyze(module, (args.case0, args.ncases), alpha, args.norm, logfile)

        if args.plot:
            out = './plots/wh_%s_%s' % (problem, alpha_str)
            out = '_'.join([out, '%dsub.pvd'])
            out = os.path.join(savedir, out)

            eout = './plots/w_%s_%s' % (problem, alpha_str)
            eout = '_'.join([eout, '%dsub.pvd'])
            eout = os.path.join(savedir, eout)

            mesh = wh[0].function_space().mesh()
            facet_f = MeshFunction('size_t', mesh, mesh.topology().dim()-1, 0)
            CompiledSubDomain('near(x[0], 0)').mark(facet_f, 1)
            CompiledSubDomain('near(x[1], 0)').mark(facet_f, 2)
            CompiledSubDomain('near(x[0], 1)').mark(facet_f, 3)
            CompiledSubDomain('near(x[1], 1)').mark(facet_f, 4)

            ds_ = Measure('ds', domain=mesh, subdomain_data=facet_f)
            n = FacetNormal(mesh)
            for i, (whi, whi_true) in enumerate(zip(wh, mms_data.solution)):
                whi.rename('f', '0')
                #whi.vector().zero()
                
                File(out % i) << whi
예제 #15
0
    def model(self, parameters=None, logger=None):
        def format(arr):
            return np.array(arr)

        # Setup parameters, logger
        self.set_parameters(parameters)
        self.set_logger(logger)

        # Get parameters
        parameters = self.get_parameters()

        #SS#if not parameters.get('simulate'):
        #SS#	return

        # Setup data
        self.set_data(reset=True)
        self.set_observables(reset=True)

        # Show simulation settings
        self.get_logger()('\n\t'.join([
            'Simulating:', *[
                '%s : %r' % (param, parameters[param] if not isinstance(
                    parameters[param], dict) else list(parameters[param]))
                for param in
                ['fields', 'num_elem', 'N', 'dt', 'D', 'alpha', 'tol']
            ]
        ]))

        # Data mesh
        mesh = IntervalMesh(MPI.comm_world, parameters['num_elem'],
                            parameters['L_0'], parameters['L_1'])

        # Fields
        V = {}
        W = {}
        fields_n = {}
        fields = {}
        w = {}
        fields_0 = {}
        potential = {}
        potential_derivative = {}
        bcs = {}
        R = {}
        J = {}
        # v2d_vector = {}
        observables = {}
        for field in parameters['fields']:

            # Define functions
            V[field] = {}
            w[field] = {}
            for space in parameters['spaces']:
                V[field][space] = getattr(
                    dolfin, parameters['spaces'][space]['type'])(
                        mesh, parameters['spaces'][space]['family'],
                        parameters['spaces'][space]['degree'])
                w[field][space] = TestFunction(V[field][space])

            space = V[field][parameters['fields'][field]['space']]
            test = w[field][parameters['fields'][field]['space']]

            fields_n[field] = Function(space, name='%sn' % (field))
            fields[field] = Function(space, name=field)

            # Inital condition
            fields_0[field] = Expression(
                parameters['fields'][field]['initial'],
                element=space.ufl_element())
            fields_n[field] = project(fields_0[field], space)
            fields[field].assign(fields_n[field])

            # Define potential
            if parameters['potential'].get('kwargs') is None:
                parameters['potential']['kwargs'] = {}
            for k in parameters['potential']['kwargs']:
                if parameters['potential']['kwargs'][k] is None:
                    parameters['potential']['kwargs'][k] = fields[k]

            potential[field] = Expression(
                parameters['potential']['expression'],
                degree=parameters['potential']['degree'],
                **parameters['potential']['kwargs'])
            potential_derivative[field] = Expression(
                parameters['potential']['derivative'],
                degree=parameters['potential']['degree'] - 1,
                **parameters['potential']['kwargs'])

            #Subdomain for defining Positive grain
            sub_domains = MeshFunction('size_t', mesh,
                                       mesh.topology().dim(), 0)

            #BC condition
            bcs[field] = []
            if parameters['fields'][field]['bcs'] == 'dirichlet':
                BC_l = CompiledSubDomain('near(x[0], side) && on_boundary',
                                         side=parameters['L_0'])
                BC_r = CompiledSubDomain('near(x[0], side) && on_boundary',
                                         side=parameters['L_1'])
                bcl = DirichletBC(V, fields_n[field], BC_l)
                bcr = DirichletBC(V, fields_n[field], BC_r)
                bcs[field].extend([bcl, bcr])
            elif parameters['fields'][field]['bcs'] == 'neumann':
                bcs[field].extend([])

            # Residual and Jacobian
            R[field] = (
                ((fields[field] - fields_n[field]) / parameters['dt'] * test *
                 dx) +
                (inner(parameters['D'] * grad(test), grad(fields[field])) * dx)
                + (parameters['alpha'] * potential_derivative[field] * test *
                   dx))

            J[field] = derivative(R[field], fields[field])

            # Observables
            observables[field] = {}

        files = {
            'xdmf': XDMFFile(MPI.comm_world,
                             self.get_paths()['xdmf']),
            'hdf5': HDF5File(MPI.comm_world,
                             self.get_paths()['hdf5'], 'w'),
        }

        files['hdf5'].write(mesh, '/mesh')
        eps = lambda n, key, field, observables, tol: (
            n == 0) or (abs(observables[key]['total_energy'][n] - observables[
                key]['total_energy'][n - 1]) /
                        (observables[key]['total_energy'][0]) > tol)
        flag = {field: True for field in parameters['fields']}
        tol = {
            field: parameters['tol'][field] if isinstance(
                parameters['tol'], dict) else parameters['tol']
            for field in parameters['fields']
        }
        phases = {'p': 1, 'm': 2}
        n = 0
        problem = {}
        solver = {}
        while (n < parameters['N']
               and any([flag[field] for field in parameters['fields']])):

            self.get_logger()('Time: %d' % (n))

            for field in parameters['fields']:

                if not flag[field]:
                    continue

                # Solve
                problem[field] = NonlinearVariationalProblem(
                    R[field], fields[field], bcs[field], J[field])
                solver[field] = NonlinearVariationalSolver(problem[field])
                solver[field].solve()

                # Get field array
                array = assemble(
                    (1 / CellVolume(mesh)) *
                    inner(fields[field], w[field]['Z']) * dx).get_local()

                # Observables
                observables[field]['Time'] = parameters['dt'] * n

                # observables[field]['energy_density'] = format(0.5*dot(grad(fields[field]),grad(fields[field]))*dx)
                observables[field]['gradient_energy'] = format(
                    assemble(0.5 *
                             dot(grad(fields[field]), grad(fields[field])) *
                             dx(domain=mesh)))
                observables[field]['landau_energy'] = format(
                    assemble(potential[field] * dx(domain=mesh)))
                observables[field]['diffusion_energy'] = format(
                    assemble(
                        project(
                            div(project(grad(fields[field]), V[field]['W'])),
                            V[field]['Z']) * dx(domain=mesh))
                )  #Diffusion part of chemical potential
                observables[field]['spinodal_energy'] = format(
                    assemble(
                        potential_derivative[field] *
                        dx(domain=mesh)))  #Spinodal part of chemical potential

                observables[field]['total_energy'] = parameters[
                    'D'] * observables[field]['gradient_energy'] + parameters[
                        'alpha'] * observables[field]['landau_energy']
                observables[field]['chi'] = parameters['alpha'] * observables[
                    field]['diffusion_energy'] - parameters['D'] * observables[
                        field]['spinodal_energy']

                # Phase observables
                sub_domains.set_all(0)
                sub_domains.array()[:] = np.where(array > 0.0, phases['p'],
                                                  phases['m'])

                phases_dxp = Measure('dx',
                                     domain=mesh,
                                     subdomain_data=sub_domains)
                for phase in phases:
                    dxp = phases_dxp(phases[phase])

                    observables[field]['Phi_0%s' % (phase)] = format(
                        assemble(1 * dxp))
                    observables[field]['Phi_1%s' % (phase)] = format(
                        assemble(fields[field] * dxp))
                    observables[field]['Phi_2%s' % (phase)] = format(
                        assemble(fields[field] * fields[field] * dxp))
                    observables[field]['Phi_3%s' % (phase)] = format(
                        assemble(fields[field] * fields[field] *
                                 fields[field] * dxp))
                    observables[field]['Phi_4%s' % (phase)] = format(
                        assemble(fields[field] * fields[field] *
                                 fields[field] * fields[field] * dxp))
                    observables[field]['Phi_5%s' % (phase)] = format(
                        assemble(fields[field] * fields[field] *
                                 fields[field] * fields[field] *
                                 fields[field] * dxp))

                    observables[field]['gradient_energy_%s' %
                                       (phase)] = format(
                                           assemble(
                                               0.5 *
                                               dot(grad(fields[field]),
                                                   grad(fields[field])) * dxp))
                    observables[field]['landau_energy_%s' % (phase)] = format(
                        assemble(potential[field] * dxp))
                    observables[field][
                        'total_energy_%s' %
                        (phase)] = parameters['D'] * observables[field][
                            'gradient_energy_%s' %
                            (phase)] + parameters['alpha'] * observables[
                                field]['landau_energy_%s' % (phase)]

                    observables[field][
                        'diffusion_energy_%s' % (phase)] = format(
                            assemble(
                                project(
                                    div(
                                        project(grad(fields[field]),
                                                V[field]['W'])), V[field]['Z'])
                                * dxp))  #Diffusion part of chemical potential
                    observables[field][
                        'spinodal_energy_%s' % (phase)] = format(
                            assemble(
                                potential_derivative[field] *
                                dxp))  #Spinodal part of chemical potential

                    observables[field][
                        'chi_%s' %
                        (phase)] = parameters['alpha'] * observables[field][
                            'spinodal_energy_%s' %
                            (phase)] - parameters['D'] * observables[field][
                                'diffusion_energy_%s' % (phase)]

                files['hdf5'].write(fields[field], '/%s' % (field), n)
                files['xdmf'].write(fields[field], n)

                fields_n[field].assign(fields[field])

                self.set_data({field: array})
                self.set_observables({field: observables[field]})

                flag[field] = eps(n, field, fields[field],
                                  self.get_observables(), tol[field])

            n += 1

        for file in files:
            files[file].close()

        return