Beispiel #1
0
def plot_sliced(geo, **params):
    tol = 1e-5
    class Back(dolfin.SubDomain):
        def inside(self, x, on_boundary):
            return x[1] >= -tol
    back = dolfin.CellFunction("size_t", geo.mesh, 0)
    Back().mark(back, 1)
    submesh = dolfin.SubMesh(geo.mesh, back, 1)
    #plot(submesh)
    bb = geo.mesh.bounding_box_tree()
    subsub = dolfin.CellFunction("size_t", submesh, 0)
    sub = geo.subdomains
    for cell in dolfin.cells(submesh):
        iparent = bb.compute_first_entity_collision(cell.midpoint())
        subsub[cell] = sub[int(iparent)]
    plot_params = dict(title="sliced geometry with subdomains",
                       elevate=-90., **params)
    dolfin.plot(subsub, **plot_params)
Beispiel #2
0
 def test_mark(self):
     mark_value = 3
     desired_edgecells = np.ones(self.mesh.num_cells()) * mark_value
     # All except last tet are edge-connected to the boundary for
     # the inscribed tet mesh
     desired_edgecells[-1] = 0
     cell_fn = dolfin.CellFunction('uint', self.mesh)
     self.DUT.mark(cell_fn, mark_value)
     self.assertTrue(np.all(cell_fn.array() == desired_edgecells))
Beispiel #3
0
def plot_sliced_mesh(geo, **kwargs):
    tol = 1e-5
    class Back(dolfin.SubDomain):
        def inside(self, x, on_boundary):
            return x[1] >= -tol
    back = dolfin.CellFunction("size_t", geo.mesh, 0)
    Back().mark(back, 1)
    submesh = dolfin.SubMesh(geo.mesh, back, 1)
    dolfin.plot(submesh, **kwargs)
Beispiel #4
0
def load_h5_mesh(fname):
    mesh = df.Mesh()
    comm = mesh.mpi_comm()
    hdf = df.HDF5File(comm, fname, "r")
    hdf.read(mesh, "/mesh", False)
    subdomains = df.CellFunction("size_t", mesh)
    hdf.read(subdomains, "/subdomains")
    boundaries = df.FacetFunction("size_t", mesh)
    hdf.read(boundaries, "/boundaries")
    return mesh, boundaries, comm
Beispiel #5
0
    def __init__(self, box, nx, ny):
        """
        Constructor
        
        INPUTS:
        - box = [x_min, x_max, y_min, y_max]: the bounding box of the computational domain
        - nx, ny: number of elements in the horizontal (axial) and vertical (transversal) direction
        """
        self.box = box
        self.mesh = dl.UnitSquareMesh(nx, ny)

        grade = GradingFunctionLin(coordinate=1, cut_point=[.6, .7], slope=6)
        remap = Remap(box=box)

        self.mesh.move(grade)
        self.mesh.move(remap)

        class InletBoundary(dl.SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary and abs(x[0] - box[0]) < dl.DOLFIN_EPS

        class SymmetryBoundary(dl.SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary and abs(x[1] - box[2]) < dl.DOLFIN_EPS

        class FarfieldBoundary(dl.SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary and (abs(x[0] - box[1]) < dl.DOLFIN_EPS
                                        or abs(x[1] - box[3]) < dl.DOLFIN_EPS)

        self.boundary_parts = dl.FacetFunction("size_t", self.mesh)
        self.boundary_parts.set_all(0)

        Gamma_inlet = InletBoundary()
        Gamma_inlet.mark(self.boundary_parts, self.INLET)
        Gamma_axis = SymmetryBoundary()
        Gamma_axis.mark(self.boundary_parts, self.AXIS)
        Gamma_farfield = FarfieldBoundary()
        Gamma_farfield.mark(self.boundary_parts, self.FARFIELD)

        self.ds = dl.Measure("ds")[self.boundary_parts]

        class DNSDomain(dl.SubDomain):
            def inside(self, x, on_boundary):
                return x[0] < 20. + dl.DOLFIN_EPS

        self.domain_parts = dl.CellFunction("size_t", self.mesh)
        self.domain_parts.set_all(self.OUTSIDE)
        DNS_Domain = DNSDomain()
        DNS_Domain.mark(self.domain_parts, self.DNS)

        self.dx = dl.Measure("dx")[self.domain_parts]
    def __init__(self, mesh, x0, y0, x1, y1):
        #: A :class:`dolfin.Mesh` containing the mesh.
        self.mesh = mesh

        class Left(dolfin.SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary and dolfin.near(x[0], x0)

        class Right(dolfin.SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary and dolfin.near(x[0], x1)

        class Sides(dolfin.SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary and (dolfin.near(x[1], y0) or dolfin.near(x[1], y1))

        #NEW
        class TurbineArea(dolfin.SubDomain):
            def inside(self, x, on_boundary):
                return True if (x[0] <= 1250 and x[1] <= 650 and 750 <= x[0] and 350 <= x[1]) else False
        #NEW

        # Initialize sub-domain instances
        left = Left()
        right = Right()
        sides = Sides()
        turbine_area = TurbineArea()
        
        # Create facet markers
        #: A :class:`dolfin.FacetFunction` containing the surface markers.
        self.facet_ids = dolfin.FacetFunction('size_t', self.mesh)
        self.facet_ids.set_all(0)
        left.mark(self.facet_ids, 1)
        right.mark(self.facet_ids, 2)
        sides.mark(self.facet_ids, 3)
        #: A :class:`dolfin.Measure` for the facet parts.
        self._ds = dolfin.Measure('ds')[self.facet_ids]

        #: A :class:`dolfin.CellFunction` containing the area markers.
        self.cell_ids = dolfin.CellFunction("size_t", self.mesh)
        self.cell_ids.set_all(0)
        
        #NEW
        turbine_area.mark(self.cell_ids,1)
        #NEWa

        #: A :class:`dolfin.Measure` for the cell cell_ids.
        self._dx = dolfin.Measure("dx")[self.cell_ids]
Beispiel #7
0
 def __init__(self, function_space):
     self.function_space = V = function_space
     self.E_r = dolfin.Function(V)
     self.E_i = dolfin.Function(V)
     self.mur_function = None
     self.epsr_function = None
     ## Set CalcEMCalcEMFunctional to only integrate along a skin
     ## of elements connected to the boundary
     boundary_cells = Geometry.BoundaryEdgeCells(V.mesh())
     cell_domains = dolfin.CellFunction('uint', V.mesh())
     cell_domains.set_all(0)
     cell_region = 1
     boundary_cells.mark(cell_domains, cell_region)
     self.functional = CalcEMFunctional(V)
     self.functional.set_cell_domains(cell_domains, cell_region)
     self.k0_dirty = True
Beispiel #8
0
 def __init__(self, function_space, testing_space=None):
     self.function_space = function_space
     if testing_space is None:
         testing_space = function_space
     self.testing_space = testing_space
     self.functional = CalcEMFunctional(function_space, testing_space)
     self.testing_interpolator = SurfaceInterpolant(testing_space)
     self.cell_domains = dolfin.CellFunction('uint',
                                             self.function_space.mesh())
     self.cell_domains.set_all(0)
     self.cell_region = 1
     boundary_cells = Geometry.BoundaryEdgeCells(self.function_space.mesh())
     boundary_cells.mark(self.cell_domains, self.cell_region)
     self.surface_forms = SurfaceNTFFForms(self.function_space)
     self.testing_expression_gen = TransformTestingExpression()
     self.functional.set_cell_domains(self.cell_domains, self.cell_region)
Beispiel #9
0
    def constructPmlSubDomain(self):
        #-----------------------------------------------------------------------------------
        # Initialize mesh function for subdomains
        self.domains = df.CellFunction("size_t", self.mesh)
        self.domains.set_all(0)

        # create PML subdomain and mark elements therein as "1"
        PmlSD = PMLSubDomain(self.tDim, self.pmlOpt)
        PmlSD.mark(self.domains, 1)

        # Define new measures associated with the PMl domains
        self.dx = df.Measure("dx",
                             domain=self.mesh,
                             subdomain_data=self.domains)

        return
Beispiel #10
0
    def __init__(self):
        pyurdme.URDMEModel.__init__(self, name="simple_diffusion2")

        A = pyurdme.Species(name="A", diffusion_constant=0.1, dimension=2)
        B = pyurdme.Species(name="B", diffusion_constant=0.1, dimension=1)

        self.add_species([A, B])

        # Import a circle mesh
        self.mesh = pyurdme.URDMEMesh.read_dolfin_mesh("circle.xml")

        # A mesh function for the cells
        cell_function = dolfin.CellFunction("size_t", self.mesh)
        cell_function.set_all(1)

        # Create a mesh function over then edges of the mesh
        facet_function = dolfin.FacetFunction("size_t", self.mesh)
        facet_function.set_all(0)

        # Mark the boundary points
        membrane = Membrane()
        membrane.mark(facet_function, 2)

        membrane_patch = MembranePatch()
        membrane_patch.mark(facet_function, 3)

        self.add_subdomain(cell_function)
        self.add_subdomain(facet_function)

        k1 = pyurdme.Parameter(name="k1", expression=100.0)
        self.add_parameter([k1])

        R1 = pyurdme.Reaction(name="R1",
                              reactants={A: 1},
                              products={B: 1},
                              massaction=True,
                              rate=k1,
                              restrict_to=3)
        self.add_reaction([R1])

        # Restrict species B to the membrane subdomain
        self.restrict(species=B, subdomains=[2, 3])
        self.timespan(numpy.linspace(0, 1, 50))

        # Place the A molecules in the voxel nearest to the center of the square
        self.set_initial_condition_place_near({A: 10000}, point=[0, 0])
Beispiel #11
0
    def __init__(self, mat, method='RK2b', name='unnamed', pbc2d=None):
        self.material = mat
        self._m = mat._m
        self.m = self._m.vector().array()
        self.S1 = mat.S1
        self.S3 = mat.S3
        self.mesh = self.S1.mesh()

        self.dm_dt = np.zeros(self.m.shape)
        self.H_eff = np.zeros(self.m.shape)

        self.time_scale = 1e-9
        self.method = method
        self.pbc2d = pbc2d

        self.set_default_values()
        self.interactions.append(mat)

        if self.pbc2d:
            self.pbc2d = PeriodicBoundary2D(self.S3)

        self.name = name
        self.sanitized_name = helpers.clean_filename(name)

        self.logfilename = self.sanitized_name + '.log'
        self.ndtfilename = self.sanitized_name + '.ndt'

        helpers.start_logging_to_file(self.logfilename,
                                      mode='w',
                                      level=logging.DEBUG)
        self.scheduler = scheduler.Scheduler()

        self.domains = df.CellFunction("uint", self.mesh)
        self.domains.set_all(0)
        self.region_id = 0

        self.tablewriter = Tablewriter(self.ndtfilename, self, override=True)

        self.overwrite_pvd_files = False
        self.vtk_export_filename = self.sanitized_name + '.pvd'
        self.vtk_saver = VTKSaver(self.vtk_export_filename, overwrite=True)

        self.scheduler_shortcuts = {
            'save_ndt': LLB.save_ndt,
            'save_vtk': LLB.save_vtk,
        }
def analyse(m):
    # Create two subdomains (0 and 1).
    subdomains = df.CellFunction('size_t', m.function_space().mesh(), 0)
    for cell in df.cells(m.function_space().mesh()):
        cell_midpoint = cell.midpoint()
        if cell_midpoint.z() > 0:
            subdomains[cell] = 1
    dx = df.Measure('dx')[subdomains]

    # Populate dictionary.
    data = dict()
    data['average_total'] = average(m, dx('everywhere'))
    data['average_bottom'] = average(m, dx(0))
    data['average_top'] = average(m, dx(1))
    data['S_total'] = s_number(m, dx('everywhere'))
    data['S_bottom'] = s_number(m, dx(0))
    data['S_top'] = s_number(m, dx(1))

    return data
def refine_vo_fun(mes_ho):
    '''
    Refines huge cells.
    '''

    markers = do.CellFunction('bool', mes_ho)
    markers.set_all(False)

    avg_cell_volume = np.mean([cell.volume() for cell in do.cells(mes_ho)])

    for cell in do.cells(mes_ho):
        if cell.volume() > 5. * avg_cell_volume:
            #mark huge cells
            markers[cell] = True

    mes_ho_refined = do.refine(mes_ho, markers)

    print 'mean(cell_volume) = ', avg_cell_volume

    return mes_ho_refined
    def __init__(self, x0, y0, x1, y1, nx, ny):
        #: A :class:`dolfin.Mesh` containing the mesh.
        mpi_comm = dolfin.mpi_comm_world()
        self.mesh = dolfin.RectangleMesh(mpi_comm, dolfin.Point(x0, y0),
                                         dolfin.Point(x1, y1), nx, ny)

        class Left(dolfin.SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary and dolfin.near(x[0], x0)

        class Right(dolfin.SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary and dolfin.near(x[0], x1)

        class Sides(dolfin.SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary and (dolfin.near(x[1], y0)
                                        or dolfin.near(x[1], y1))

        # Initialize sub-domain instances
        left = Left()
        right = Right()
        sides = Sides()

        # Create facet markers
        #: A :class:`dolfin.FacetFunction` containing the surface markers.
        self.facet_ids = dolfin.FacetFunction('size_t', self.mesh)
        self.facet_ids.set_all(0)
        left.mark(self.facet_ids, 1)
        right.mark(self.facet_ids, 2)
        sides.mark(self.facet_ids, 3)
        #: A :class:`dolfin.Measure` for the facet parts.
        self._ds = dolfin.Measure('ds')[self.facet_ids]

        #: A :class:`dolfin.CellFunction` containing the area markers.
        self.cell_ids = dolfin.CellFunction("size_t", self.mesh)
        self.cell_ids.set_all(0)
        #: A :class:`dolfin.Measure` for the cell cell_ids.
        self._dx = dolfin.Measure("dx")[self.cell_ids]
def refine_bo_fun(mes_ho, boundary_name):
    '''
    Refines faces on a given boundary.
    '''
    geo_params_d = geo_fun()[1]

    #center of the cylinder base
    x_c = geo_params_d['x_0']
    y_c = geo_params_d['y_0']
    #z_c = geo_params_d['z_0']

    x_c_l = [geo_params_d['x_0_{}'.format(itera)] for itera in xrange(1)]
    y_c_l = [geo_params_d['y_0_{}'.format(itera)] for itera in xrange(1)]
    #z_c_l = [geo_params_d['z_0_{}'.format(itera)] for itera in xrange(4)]

    R_in = geo_params_d['R_in']
    R_ex = geo_params_d['R_ex']

    markers = do.CellFunction('bool', mes_ho)
    markers.set_all(False)

    for cell in do.cells(mes_ho):
        for facet in do.facets(cell):
            if 'outer' in boundary_name:
                if abs(((facet.midpoint()[0] - x_c)**2. +
                        (facet.midpoint()[1] - y_c)**2.)**.5 - R_ex) < 5e-2:
                    #mark cells with facet midpoints close to the outer boundary
                    markers[cell] = True
                    print 'refinement close to the outer boundary'
            elif 'inner' in boundary_name:
                if abs(((facet.midpoint()[0] - x_c_l[0]) ** 2. + \
                        (facet.midpoint()[1] - y_c_l[0]) ** 2.) ** .5 - R_in) < 1e-4:
                    #mark cells with facet midpoints close to the inner boundary
                    markers[cell] = True
                    print 'refinement close to the inner boundary'

    mes_ho_refined = do.refine(mes_ho, markers)

    return mes_ho_refined
Beispiel #16
0
    def apply_linear_refinement( self ):
        r"""
        Refine the mesh linearly: slice all cells between a radius linear\_start
        and a radius linear\_stop in half, for a number of times specified by linear\_refine.

        """
        
        for i in range( self.linear_refine ):
            cells = d.cells( self.mesh )
            cell_markers = d.CellFunction( "bool", self.mesh )
            cell_markers.set_all(False)
            for cell in cells:
                # slice cell if (1) it's large enough to be sliced and be resolvable within machine precision
                # (2) its left vertex is within the range specified by the user
                left = cell.get_vertex_coordinates()[0]
                divide = ( cell.circumradius > self.too_fine * d.DOLFIN_EPS ) and \
                        ( self.linear_start < left < self.linear_stop )        
                if divide :
                    cell_markers[cell] = True
                    
            self.mesh = d.refine( self.mesh, cell_markers )

        # how many points were added by linear refinement (if any)? Store the info
        self.linear_cells = len( self.mesh.coordinates() ) - 1 - self.num_cells
    def __init__(self, mesh, get_domain_id, m_vals, Ms, unit_length=1e-9):
        """
        `get_domain_id` is a function of the form (x, y, z) -> id which maps
        some point coordinates in the mesh to an integer identifying the domain
        which the point belongs to.

        """
        self.mesh = mesh
        self.get_domain_id = get_domain_id
        self.domain_ids = [get_domain_id(pt) for pt in mesh.coordinates()]
        self.Ms = Field(df.FunctionSpace(mesh, 'DG', 0), Ms)
        self.unit_length = unit_length
        #self.rtol = rtol

        domain_classes = {}
        for k in self.domain_ids:
            class DomainK(df.SubDomain):

                def inside(self, pt, on_boundary):
                    return get_domain_id(pt) == k
            domain_classes[k] = DomainK()
        domains = df.CellFunction("size_t", mesh)
        domains.set_all(0)
        for k, d in domain_classes.items():
            d.mark(domains, k)

        self.submeshes = [df.SubMesh(mesh, domains, i)
                          for i in self.domain_ids]
        self.dx = df.Measure("dx")[domains]

        def m_init(pt):
            return m_vals[self.get_domain_id(pt)]

        self.V = df.VectorFunctionSpace(mesh, 'CG', 1, dim=3)
        self.m = Field(self.V)
        self.m.set(m_init, normalised=True)
def create_patches(box=np.array([0, 0, 0, 1, 1, 1]),
                   patch_num=3,
                   patch_nums=None,
                   alpha=1.25,
                   beta=2.0,
                   max_resolution=0.5,
                   num=6,
                   create_inclusions=False,
                   skip_patches=[],
                   prefix='test',
                   logger=None,
                   ldomain=False,
                   corner_refine=3,
                   hole=False,
                   hole_radius=None,
                   layers=1,
                   max_refines=1,
                   elem_per_layer=3):
    if logger is not None:
        info = logger.info
    else:
        info = print

    basedim = 3
    low = box[:basedim].copy()
    high = box[basedim:].copy()
    lengths = high - low
    diameter = np.sqrt(lengths @ lengths)
    myeps = sa_utils.myeps * diameter
    center = (high + low) * .5
    info('low {:s}, high {:s}, lengths {:s}, center {:s}, diameter {:.2e}'.
         format(str(low), str(high), str(lengths), str(center), diameter))

    layer_bricks = []
    layer_hz = lengths[2] / layers
    layer_low = np.array(
        [low[0] - lengths[0], low[1] - lengths[1], low[2] - lengths[2]])
    layer_high = np.array(
        [low[0] + lengths[0], low[1] + lengths[1], low[2] + 2 * lengths[2]])
    for ii in range(layers - 1):
        for jj in range(1, elem_per_layer + 1):
            layer_bricks.append(
                OrthoBrick(
                    Pnt(*layer_low),
                    Pnt(low[0] + lengths[0], low[1] + lengths[1],
                        low[2] + (ii + jj * 1. / elem_per_layer) * layer_hz)))
        info('layer [{:d}/{:d}], {:s}, {:s}'.format(
            ii, layers, str(layer_low),
            str(
                np.array([
                    low[0] + lengths[0], low[1] + lengths[1],
                    low[2] + ii * layer_hz
                ]))))
    for jj in range(1, elem_per_layer):
        layer_bricks.append(
            OrthoBrick(
                Pnt(*layer_low),
                Pnt(
                    low[0] + lengths[0], low[1] + lengths[1], low[2] +
                    (layers - 1 + jj * 1. / elem_per_layer) * layer_hz)))
    layer_bricks.append(OrthoBrick(Pnt(*layer_low), Pnt(*layer_high)))
    sublayers = len(layer_bricks)
    info('layer [{:d}/{:d}], {:s}, {:s}'.format(layers, layers, str(layer_low),
                                                str(layer_high)))

    info('{:d} layers, {:d} sublayers, {:d} bricks'.format(
        layers, sublayers, len(layer_bricks)))

    bc_dict = dict()
    left = dolfin.AutoSubDomain(
        lambda xx, on: on and dolfin.near(xx[0], low[0], eps=myeps))
    bc_dict[1] = left
    right = dolfin.AutoSubDomain(
        lambda xx, on: on and dolfin.near(xx[0], high[0], eps=myeps))
    bc_dict[2] = right
    front = dolfin.AutoSubDomain(
        lambda xx, on: on and dolfin.near(xx[1], low[1], eps=myeps))
    bc_dict[3] = front
    back = dolfin.AutoSubDomain(
        lambda xx, on: on and dolfin.near(xx[1], high[1], eps=myeps))
    bc_dict[4] = back
    bottom = dolfin.AutoSubDomain(
        lambda xx, on: on and dolfin.near(xx[2], low[2], eps=myeps))
    bc_dict[5] = bottom
    top = dolfin.AutoSubDomain(
        lambda xx, on: on and dolfin.near(xx[2], high[2], eps=myeps))
    bc_dict[6] = top
    border = dolfin.AutoSubDomain(lambda xx, on: on)
    if ldomain:
        corner_lr = dolfin.AutoSubDomain(
            lambda xx, on: on and (xx >= center - myeps).all() and dolfin.near(
                xx[0], center[0], eps=myeps))
        bc_dict[7] = corner_lr
        corner_fb = dolfin.AutoSubDomain(
            lambda xx, on: on and (xx >= center - myeps).all() and dolfin.near(
                xx[1], center[1], eps=myeps))
        bc_dict[8] = corner_fb
        corner_bt = dolfin.AutoSubDomain(
            lambda xx, on: on and (xx >= center - myeps).all() and dolfin.near(
                xx[2], center[2], eps=myeps))
        bc_dict[9] = corner_bt
        corner_subdomains = []
        corner_close = 0.1 * diameter + myeps
        for ii in range(corner_refine):
            corner_subdomains.append(
                dolfin.AutoSubDomain(
                    (lambda what: lambda xx, on: np.sqrt(xx @ xx) < what
                     )(corner_close)))
            corner_close *= 0.5
    if create_inclusions and num:
        info('random inclusions')
        if num:
            number = num * num * num
            info('n = ' + str(number))
            inc_radius = 0.5 / num
            info('r = ' + str(inc_radius))
            nodes = []
            radii = []
            rnd_low = low - 0.5 * inc_radius
            rnd_high = high + 0.5 * inc_radius
            width = rnd_high - rnd_low
            while (len(nodes) < number):
                notok = True
                while (notok):
                    new = rnd.rand(3) * width + rnd_low
                    radius = (0.5 + rnd.rand()) * inc_radius
                    notok = False
                    for old, rr in zip(nodes, radii):
                        diff = new - old
                        if np.sqrt(diff.dot(diff)) < 1.3 * (radius + rr):
                            notok = True
                            break
                nodes.append(new.copy())
                radii.append(radius)
            nodes = np.array(nodes)
            radii = np.array(radii)
            info('found locations for ' + str(len(nodes)) + ' inclusions')
            np.savetxt(prefix + '/' + prefix + '_inclusions.csv',
                       np.hstack((nodes, radii.reshape(len(nodes), 1))),
                       fmt='%.15e',
                       delimiter=', ')
            del nodes, radii, number, inc_radius

    nohole_whole = OrthoBrick(Pnt(*low), Pnt(*high))
    if ldomain is True:
        nohole_whole = nohole_whole - OrthoBrick(
            Pnt(*center), Pnt(*(center + 2 * (high - center))))
    if num:
        data = np.loadtxt(prefix + '/' + prefix + '_inclusions.csv',
                          delimiter=', ')
        number = len(data)
    else:
        number = 0
    if number:
        nodes = data[:, :3]
        radii = data[:, 3]

        inclusions = Sphere(Pnt(*nodes[0]), radii[0])
        for kk in range(1, len(nodes)):
            inclusions += Sphere(Pnt(*nodes[kk]), radii[kk])
        nohole_matrix = nohole_whole - inclusions
        nohole_incs = nohole_whole * inclusions
    if hole_radius is not None:
        hole = True
    if hole:
        if hole_radius is None:
            hole_radius = lengths[1] / 9.
        near_hole = dolfin.AutoSubDomain(lambda xx, on: on and np.sqrt(
            (xx[0] - center[0]) * (xx[0] - center[0]) + (xx[1] - center[1]) *
            (xx[1] - center[1])) < hole_radius + 1e4 * myeps)
        bc_dict[10] = near_hole

    if patch_nums is None:
        hh = lengths[0] / float(patch_num)
        patch_nums = np.array(np.ceil(lengths / hh), dtype=int)
    hs = lengths / patch_nums
    hs_alpha = hs * alpha * 0.5
    hs_beta = hs_alpha * beta

    patches = []
    patches_ext = []
    for kk in range(patch_nums[2]):
        pt_z = low[0] + (0.5 + kk) * hs[2]
        for jj in range(patch_nums[1]):
            pt_y = low[1] + (0.5 + jj) * hs[1]
            for ii in range(patch_nums[0]):
                pt_x = low[2] + (0.5 + ii) * hs[0]
                pt_center = np.array([pt_x, pt_y, pt_z])
                pt_low = pt_center - hs_alpha
                if ldomain and (p_low >= center - myeps).all():
                    print('[{:d}, {:d}, {:d}] skipped'.format(ii, jj, kk))
                    continue

                patches.append(
                    OrthoBrick(Pnt(*(pt_center - hs_alpha)),
                               Pnt(*(pt_center + hs_alpha))))
                patches_ext.append(
                    OrthoBrick(Pnt(*(pt_center -
                                     hs_beta)), Pnt(*(pt_center + hs_beta))) -
                    patches[-1])
    patch_num = len(patches)
    print('[{:d}] patches total'.format(patch_num))
    patch_fill = int(np.log(patch_num) / np.log(10.)) + 1

    pt_low = dict()
    pt_high = dict()
    pt_inside = dict()

    info('Patch size computations')
    sa_utils.makedirs_norace(prefix + '/' + prefix + '_patch_descriptors')
    ff = open(prefix + '/' + prefix + '_patch_descriptors/0.csv', 'w')
    ff.write('idx, left, right, front, back, bottom, top\n')
    for kk in range(patch_num):
        info(str(kk + 1) + '/' + str(patch_num))
        geo = CSGeometry()
        geo.Add(nohole_whole * patches[kk])
        mesh = geo.GenerateMesh(maxh=max_resolution)
        del geo
        mesh.Export('tmp.msh', 'Gmsh2 Format')
        del mesh
        meshconvert.convert2xml('tmp.msh', 'tmp.xml')
        os.remove('tmp.msh')
        os.remove('tmp_facet_region.xml')
        os.remove('tmp_physical_region.xml')

        mesh = dolfin.Mesh('tmp.xml')
        os.remove('tmp.xml')
        nodes = mesh.coordinates()
        del mesh
        pt_low[kk] = np.min(nodes, axis=0)
        pt_high[kk] = np.max(nodes, axis=0)
        ff.write('%d, %.15e, %.15e, %.15e, %.15e, %.15e, %.15e\n' %
                 (kk, pt_low[kk][0], pt_high[kk][0], pt_low[kk][1],
                  pt_high[kk][1], pt_low[kk][2], pt_high[kk][2]))
        del nodes
        pt_inside[kk] = dolfin.AutoSubDomain(lambda xx, on: (pt_low[
            kk] - myeps <= xx).all() and (xx <= pt_high[kk] + myeps).all())
    ff.close()
    info('Patch size computations finished')

    hole_ratio = hole_radius / lengths[1]
    for ref in range(max_refines):
        info('Start meshing resolution {:d}/{:d}'.format(ref + 1, max_refines))
        res = max_resolution * 0.5**ref

        if hole:
            hole_maxh = res * hole_ratio
            #           hole_maxh = np.min([res*hole_ratio, lengths[2]/layers])
            if number:
                matrix = nohole_matrix - Cylinder(
                    Pnt(center[0], center[1], center[2] - diameter),
                    Pnt(center[0], center[1], center[2] + diameter),
                    hole_radius).maxh(hole_maxh)
                incs = nohole_matrix - Cylinder(
                    Pnt(center[0], center[1], center[2] - diameter),
                    Pnt(center[0], center[1], center[2] + diameter),
                    hole_radius).maxh(hole_maxh)
            else:
                whole = nohole_whole - Cylinder(
                    Pnt(center[0], center[1], center[2] - diameter),
                    Pnt(center[0], center[1], center[2] + diameter),
                    hole_radius).maxh(hole_maxh)

        dirname = '{:s}/{:s}_{:d}_patches/0/'.format(prefix, prefix, ref)
        sa_utils.makedirs_norace(dirname)

        basename = '{:s}/{:s}_{:d}'.format(prefix, prefix, ref)
        info('Global CSG')
        geo = CSGeometry()

        if number:
            geo.Add(matrix * layer_bricks[0])
            for ii in range(1, sublayers):
                geo.Add(matrix * (layer_bricks[ii] - layer_bricks[ii - 1]))
            geo.Add(incs * layer_bricks[0])
            for ii in range(1, sublayers):
                geo.Add(incs * (layer_bricks[ii] - layer_bricks[ii - 1]))
        else:
            geo.Add(whole * layer_bricks[0])
            for ii in range(1, sublayers):
                geo.Add(whole * (layer_bricks[ii] - layer_bricks[ii - 1]))
        info('Global CSG constructed')
        mesh = geo.GenerateMesh(maxh=res)
        info('Global surface meshed')
        del geo

        gc.collect()

        mesh.GenerateVolumeMesh()
        mesh.Export(basename + '.msh', 'Gmsh2 Format')
        meshconvert.convert2xml(basename + '.msh', basename + '.xml')
        del mesh
        os.remove(basename + '.msh')
        os.remove(basename + '_facet_region.xml')
        info('Global volume meshed')

        gc.collect()

        global_mesh = dolfin.Mesh(basename + '.xml')
        tmp_nodes = global_mesh.coordinates()
        tmp_low = np.min(tmp_nodes, axis=0)
        tmp_high = np.max(tmp_nodes, axis=0)
        info('global mesh: {:s}, {:s}, {:s}'.format(
            str(tmp_low), str(tmp_high), str(top.inside(tmp_high, True))))

        os.remove(basename + '.xml')
        info('Correcting cell markers')
        global_domains_tmp = dolfin.MeshFunction(
            'size_t', global_mesh, basename + '_physical_region.xml')
        os.remove(basename + '_physical_region.xml')
        global_domains_tmp.array()[:] -= np.min(global_domains_tmp.array())
        global_domains_tmp.array()[:] //= elem_per_layer
        global_domains = dolfin.MeshFunction('size_t', global_mesh, basedim, 0)
        if number:
            where = np.where(global_domains_tmp.array() < layers)
            global_domains.array(
            )[where] = 4 * global_domains_tmp.array()[where]
            where = np.where(layers <= global_domains_tmp.array())
            global_domains.array(
            )[where] = 4 * (global_domains_tmp.array()[where] - layers) + 1
            del where
        else:
            global_domains.array()[:] = 4 * global_domains_tmp.array()
        del global_domains_tmp
        if ldomain:
            for ii in range(corner_refine):
                mf = dolfin.CellFunction('bool', global_mesh, False)
                corner_subdomains[ii].mark(mf, True)
                global_mesh = dolfin.refine(global_mesh, mf)
                global_domains = dolfin.adapt(global_domains, global_mesh)
                del mf
        inside_fun = dolfin.MeshFunction('bool', global_mesh, basedim, True)
        global_mesh = dolfin.refine(global_mesh, inside_fun)
        global_domains = dolfin.adapt(global_domains, global_mesh)
        info('Correcting facet markers')
        global_facets = dolfin.MeshFunction('size_t', global_mesh, basedim - 1,
                                            0)
        for key in bc_dict:
            bc_dict[key].mark(global_facets, key)
        sa_hdf5.write_dolfin_mesh(global_mesh,
                                  basename,
                                  cell_function=global_domains,
                                  facet_function=global_facets)
        del global_facets, global_mesh, global_domains, basename

        gc.collect()

        for kk in range(patch_num):
            if kk in skip_patches:
                continue
            info(str(kk) + '/' + str(patch_num))
            basename = 'patch_' + str(kk).zfill(patch_fill)
            extname = basename + '_' + str(beta)

            info('    csg')
            geo = CSGeometry()
            if number:
                geo.Add(matrix * layer_bricks[0] * patches[kk])
                for ii in range(1, sublayers):
                    geo.Add(matrix *
                            (layer_bricks[ii] - layer_bricks[ii - 1]) *
                            patches[kk])
                geo.Add(incs * layer_bricks[0] * patches[kk])
                for ii in range(1, sublayers):
                    geo.Add(incs * (layer_bricks[ii] - layer_bricks[ii - 1]) *
                            patches[kk])
                geo.Add(matrix * layer_bricks[0] * patches_ext[kk])
                for ii in range(1, sublayers):
                    geo.Add(matrix *
                            (layer_bricks[ii] - layer_bricks[ii - 1]) *
                            patches_ext[kk])
                geo.Add(incs * layer_bricks[0] * patches_ext[kk])
                for ii in range(1, sublayers):
                    geo.Add(incs * (layer_bricks[ii] - layer_bricks[ii - 1]) *
                            patches_ext[kk])
            else:
                geo.Add(whole * layer_bricks[0] * patches[kk])
                for ii in range(1, sublayers):
                    geo.Add(whole * (layer_bricks[ii] - layer_bricks[ii - 1]) *
                            patches[kk])
                geo.Add(whole * layer_bricks[0] * patches_ext[kk])
                for ii in range(1, sublayers):
                    geo.Add(whole * (layer_bricks[ii] - layer_bricks[ii - 1]) *
                            patches_ext[kk])
            info('    csg done')
            mesh = geo.GenerateMesh(maxh=res)
            info('    surface meshed')
            del geo

            gc.collect()

            mesh.GenerateVolumeMesh()
            info('    volume meshed')
            mesh.Export(dirname + '/' + basename + '.msh', 'Gmsh2 Format')
            meshconvert.convert2xml(dirname + '/' + basename + '.msh',
                                    dirname + '/' + basename + '.xml')
            del mesh
            os.remove(dirname + '/' + basename + '.msh')
            os.remove(dirname + '/' + basename + '_facet_region.xml')

            gc.collect()

            ext_mesh = dolfin.Mesh(dirname + '/' + basename + '.xml')
            os.remove(dirname + '/' + basename + '.xml')
            info('    cell function')
            ext_domains_tmp = dolfin.MeshFunction(
                'size_t', ext_mesh,
                dirname + '/' + basename + '_physical_region.xml')
            os.remove(dirname + '/' + basename + '_physical_region.xml')
            ext_domains_tmp.array()[:] -= np.min(ext_domains_tmp.array())
            ext_domains_tmp.array()[:] //= elem_per_layer
            ext_domains = dolfin.MeshFunction('size_t', ext_mesh, basedim, 0)
            if number:
                where = np.where(ext_domains_tmp.array() < layers)
                ext_domains.array()[where] = 4 * ext_domains_tmp.array()[where]
                where = np.where(
                    layers <= ext_domains_tmp.array() < 2 * layers)
                ext_domains.array(
                )[where] = 4 * (ext_domains_tmp.array()[where] - layers) + 1
                where = np.where(
                    2 * layers <= ext_domains_tmp.array() < 3 * layers)
                ext_domains.array()[where] = 4 * (
                    ext_domains_tmp.array()[where] - 2 * layers) + 2
                where = np.where(3 * layers <= ext_domains_tmp.array())
                ext_domains.array()[where] = 4 * (
                    ext_domains_tmp.array()[where] - 3 * layers) + 3
                del where
            else:
                where = np.where(ext_domains_tmp.array() < layers)
                ext_domains.array()[where] = 4 * ext_domains_tmp.array()[where]
                where = np.where(layers <= ext_domains_tmp.array())
                ext_domains.array(
                )[where] = 4 * (ext_domains_tmp.array()[where] - layers) + 2
            del ext_domains_tmp
            if ldomain:
                for ii in range(corner_refine):
                    mf = dolfin.CellFunction('bool', ext_mesh, False)
                    corner_subdomains[ii].mark(mf, True)
                    ext_mesh = dolfin.refine(ext_mesh, mf)
                    ext_domains = dolfin.adapt(ext_domains, ext_mesh)
                    del mf
            inside_fun = dolfin.MeshFunction('bool', ext_mesh, basedim, False)
            pt_inside[kk].mark(inside_fun, True)
            ext_mesh = dolfin.refine(ext_mesh, inside_fun)
            del inside_fun
            ext_domains = dolfin.adapt(ext_domains, ext_mesh)
            info('    cell function done')

            pt_mesh = dolfin.SubMesh(ext_mesh, pt_inside[kk])

            pt_domains = dolfin.MeshFunction('size_t', pt_mesh, basedim, 0)
            tree = ext_mesh.bounding_box_tree()
            for cell in dolfin.cells(pt_mesh):
                global_index = tree.compute_first_entity_collision(
                    cell.midpoint())
                pt_domains[cell] = ext_domains[dolfin.Cell(
                    ext_mesh, global_index)]
            del tree

            pt_facets = dolfin.MeshFunction('size_t', pt_mesh, basedim - 1, 0)
            border.mark(pt_facets, 100)
            for key in bc_dict:
                bc_dict[key].mark(pt_facets, key)
            sa_hdf5.write_dolfin_mesh(pt_mesh,
                                      '{:s}/{:s}'.format(dirname, basename),
                                      cell_function=pt_domains,
                                      facet_function=pt_facets)

            tmp_nodes = ext_mesh.coordinates()
            tmp_low = np.min(tmp_nodes, axis=0)
            tmp_high = np.max(tmp_nodes, axis=0)
            is_part = (tmp_low > low + myeps).any() or (tmp_high <
                                                        high - myeps).any()
            del tmp_low, tmp_high, tmp_nodes
            info('patch [{:d}/{:d}], beta [{:.2e}] is real subdomain [{:}]'.
                 format(kk + 1, patch_num, beta, is_part))

            if is_part:
                vals = np.arange(1, 11)
            else:
                vals = np.unique(pt_facets.array())
                vals = vals[np.where(vals > 0)]
            patch_dict = dict()
            for key in bc_dict:
                if key in vals:
                    patch_dict[key] = bc_dict[key]
                else:
                    patch_dict[key] = dolfin.AutoSubDomain(
                        (lambda what: (lambda xx, on: bc_dict[what].inside(
                            xx, on) and pt_inside[kk].inside(xx, on)))(key))
            ext_facets = dolfin.MeshFunction('size_t', ext_mesh, basedim - 1,
                                             0)
            border.mark(ext_facets, 100)
            for key in patch_dict:
                patch_dict[key].mark(ext_facets, key)
            del patch_dict, vals
            sa_hdf5.write_dolfin_mesh(ext_mesh,
                                      dirname + '/' + basename + '_' +
                                      str(beta),
                                      cell_function=ext_domains,
                                      facet_function=ext_facets)
            del ext_mesh, ext_domains, ext_facets, pt_mesh, pt_domains, pt_facets

            gc.collect()

    del pt_low, pt_high, pt_inside
Beispiel #19
0
# In[126]:

domain = mshr.Circle(dolfin.Point(.0, .0), 1.0) - mshr.Rectangle(dolfin.Point(0.0, -1.0), dolfin.Point(1.0, 0.0))


# In[127]:

mesh = mshr.generate_mesh(domain, 10)


# In[128]:

refined_mesh = mesh
for r in [0.5, 0.25]:
    cell_markers = dolfin.CellFunction("bool", refined_mesh)
    cell_markers.set_all(False)
    for cell in dolfin.cells(refined_mesh):
        if cell.distance(dolfin.Point(.0, .0)) < r:
            cell_markers[cell] = True
    refined_mesh = dolfin.refine(refined_mesh, cell_markers)


# In[129]:

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4))
 
ax1.triplot(mesh_triangulation(mesh))
ax2.triplot(mesh_triangulation(refined_mesh))

for ax in [ax1, ax2]:
Beispiel #20
0
def test_compute_energy_in_regions(tmpdir):
    os.chdir(str(tmpdir))
    d = 30.0
    h1 = 5.0
    h2 = 10.0
    sep = 10.0
    maxh = 2.5
    RTOL = 5e-3  # depends on maxh
    unit_length = 1e-9

    Ms = 8e5
    H = 1e6

    mesh = pair_of_disks(d, d, h1, h2, sep, theta=0, maxh=maxh)
    S3 = df.VectorFunctionSpace(mesh, "CG", 1)

    # Create a mesh function for the two domains (each representing one disk),
    # where the regions are marked with '0' (first disk) and '1' (second disk).
    class Disk1(df.SubDomain):
        def inside(self, pt, on_boundary):
            x, y, z = pt
            return np.linalg.norm([x, y]) < 0.5 * (d + sep)

    class Disk2(df.SubDomain):
        def inside(self, pt, on_boundary):
            x, y, z = pt
            return np.linalg.norm([x, y, z]) > 0.5 * (d + sep)

    disk1 = Disk1()
    disk2 = Disk2()
    domains = df.CellFunction("size_t", mesh)
    domains.set_all(0)
    disk1.mark(domains, 1)
    disk2.mark(domains, 2)
    dx = df.Measure("dx")[domains]
    dx_disk_1 = dx(1)
    dx_disk_2 = dx(2)

    volume_1 = pi * (0.5 * d)**2 * h1 * unit_length**3  # volume of disk #1
    volume_2 = pi * (0.5 * d)**2 * h2 * unit_length**3  # volume of disk #2

    # E_aligned_1 = -mu0 * Ms * H * volume_1  # energy of disk #1 if m || H_ext
    # E_aligned_2 = -mu0 * Ms * H * volume_2  # energy of disk #2 if m || H_ext

    def check_energies(m=None, theta=None):
        """
        Helper function to compare the computed energy for a given
        magnetisation with an expected analytical value. The argument
        theta is the angle between the magnetisation vector and the
        x-axis.

        """
        # Exactly one of m, theta must be given
        assert ((m is None or theta is None)
                and not (m is None and theta is None))
        if m is None:
            if theta is None:
                raise ValueError("Exactly one of m, theta must be given.")
            theta_rad = theta * pi / 180.
            m = (cos(theta_rad), sin(theta_rad), 0)
        else:
            if theta != None:
                raise ValueError("Exactly one of m, theta must be given.")
        m = m / np.linalg.norm(m)
        m_field = Field(S3)
        m_field.set(df.Constant(m))
        H_ext = Zeeman(H * np.array([1, 0, 0]))
        H_ext.setup(m_field,
                    Field(df.FunctionSpace(mesh, 'DG', 0), Ms),
                    unit_length=unit_length)

        #E_analytical_1 = -mu0 * Ms * H * volume_1 * cos(theta_rad)
        E_analytical_1 = -mu0 * Ms * H * volume_1 * np.dot(m, [1, 0, 0])
        E_analytical_2 = -mu0 * Ms * H * volume_2 * np.dot(m, [1, 0, 0])
        E_analytical_total = E_analytical_1 + E_analytical_2

        E_computed_1 = H_ext.compute_energy(dx=dx_disk_1)
        E_computed_2 = H_ext.compute_energy(dx=dx_disk_2)
        E_computed_total = H_ext.compute_energy(dx=df.dx)

        # Check that the sum of the computed energies for disk #1 and #2 equals
        # the total computed energy
        assert np.allclose(E_computed_1 + E_computed_2,
                           E_computed_total,
                           atol=0,
                           rtol=1e-12)

        # Check that the computed energies are within the tolerance of the
        # analytical expressions
        assert np.allclose(E_computed_1, E_analytical_1, atol=0, rtol=RTOL)
        assert np.allclose(E_computed_2, E_analytical_2, atol=0, rtol=RTOL)
        assert np.allclose(E_computed_total,
                           E_analytical_total,
                           atol=0,
                           rtol=RTOL)
        #finmag.logger.debug("E_computed: {}".format(E_computed))
        #finmag.logger.debug("E_expected: {}".format(E_expected))
        #finmag.logger.debug("E_computed - E_expected: {}".format(E_computed - E_expected))

    # Check a bunch of energies
    for theta in [0, 20, 45, 60, 90, 144, 180]:
        check_energies(theta=theta)
        check_energies(theta=-theta)
    check_energies(m=(0, 0, 1))
    check_energies(m=(2, -3, -1))
Beispiel #21
0
    def __init__(self, model_name="mincde"):
        pyurdme.URDMEModel.__init__(self, model_name)

        # Species
        MinD_m = pyurdme.Species(name="MinD_m",
                                 diffusion_constant=1e-14,
                                 dimension=2)
        MinD_c_atp = pyurdme.Species(name="MinD_c_atp",
                                     diffusion_constant=2.5e-12,
                                     dimension=3)
        MinD_c_adp = pyurdme.Species(name="MinD_c_adp",
                                     diffusion_constant=2.5e-12,
                                     dimension=3)
        MinD_e = pyurdme.Species(name="MinD_e",
                                 diffusion_constant=2.5e-12,
                                 dimension=3)
        MinDE = pyurdme.Species(name="MinDE",
                                diffusion_constant=1e-14,
                                dimension=2)

        self.add_species([MinD_m, MinD_c_atp, MinD_c_adp, MinD_e, MinDE])

        # Make sure that we have the correct path to the mesh file even if we are not executing from the basedir.
        basedir = os.path.dirname(os.path.abspath(__file__))
        self.mesh = pyurdme.URDMEMesh.read_dolfin_mesh(basedir +
                                                       "/mesh/coli.xml")

        interior = dolfin.CellFunction("size_t", self.mesh)
        interior.set_all(1)
        boundary = dolfin.FacetFunction("size_t", self.mesh)
        boundary.set_all(0)

        # Mark the boundary points
        membrane = Membrane()
        membrane.mark(boundary, 2)

        self.add_subdomain(interior)
        self.add_subdomain(boundary)

        # Average mesh size to feed into the propensity functions
        h = self.mesh.get_mesh_size()
        self.add_data_function(MeshSize(self.mesh))

        # Parameters
        NA = pyurdme.Parameter(name="NA", expression=6.022e23)
        sigma_d = pyurdme.Parameter(name="sigma_d", expression=2.5e-8)
        sigma_dD = pyurdme.Parameter(name="sigma_dD", expression=0.0016e-18)
        sigma_e = pyurdme.Parameter(name="sigma_e", expression=0.093e-18)
        sigma_de = pyurdme.Parameter(name="sigma_de", expression=0.7)
        sigma_dt = pyurdme.Parameter(name="sigma_dt", expression=1.0)

        self.add_parameter(
            [NA, sigma_d, sigma_dD, sigma_e, sigma_de, sigma_dt])

        # List of Physical domain markers that match those in the  Gmsh .geo file.
        interior = [1]
        boundary = [2]

        # Reactions
        R1 = pyurdme.Reaction(
            name="R1",
            reactants={MinD_c_atp: 1},
            products={MinD_m: 1},
            propensity_function="MinD_c_atp*sigma_d/MeshSize",
            restrict_to=boundary)
        R2 = pyurdme.Reaction(name="R2",
                              reactants={
                                  MinD_c_atp: 1,
                                  MinD_m: 1
                              },
                              products={MinD_m: 2},
                              massaction=True,
                              rate=sigma_dD)
        R3 = pyurdme.Reaction(name="R3",
                              reactants={
                                  MinD_m: 1,
                                  MinD_e: 1
                              },
                              products={MinDE: 1},
                              massaction=True,
                              rate=sigma_e)
        R4 = pyurdme.Reaction(name="R4",
                              reactants={MinDE: 1},
                              products={
                                  MinD_c_adp: 1,
                                  MinD_e: 1
                              },
                              massaction=True,
                              rate=sigma_de)
        R5 = pyurdme.Reaction(name="R5",
                              reactants={MinD_c_adp: 1},
                              products={MinD_c_atp: 1},
                              massaction=True,
                              rate=sigma_dt)
        R6 = pyurdme.Reaction(name="R6",
                              reactants={
                                  MinDE: 1,
                                  MinD_c_atp: 1
                              },
                              products={
                                  MinD_m: 1,
                                  MinDE: 1
                              },
                              massaction=True,
                              rate=sigma_dD)

        self.add_reaction([R1, R2, R3, R4, R5, R6])

        # Restrict to boundary
        self.restrict(MinD_m, boundary)
        self.restrict(MinDE, boundary)

        # Distribute molecules over the mesh according to their initial values
        self.set_initial_condition_scatter({MinD_c_adp: 4500})
        self.set_initial_condition_scatter({MinD_e: 1575})

        self.timespan(range(500))
Beispiel #22
0
    def __init__(self, box, sponge, nx, ny):
        """
        Constructor
        
        INPUTS:
        - box = [x_min, x_max, y_min, y_max]: the bounding box of the computational domain
        - nx, ny: number of elements in the horizontal (axial) and vertical (transversal) direction
        """
        self.box = box
        self.mesh = dl.UnitSquareMesh(nx, ny)
        box_sponge = [box[0], box[1] + sponge[0], box[2], box[3] + sponge[1]]

        grade = GradingFunctionLin(coordinate=1, cut_point=[.6, .7], slope=6)
        remap = Remap(box=box_sponge)

        self.mesh.move(grade)
        self.mesh.move(remap)

        class InletBoundary(dl.SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary and abs(x[0] -
                                           box_sponge[0]) < dl.DOLFIN_EPS

        class SymmetryBoundary(dl.SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary and abs(x[1] -
                                           box_sponge[2]) < dl.DOLFIN_EPS

        class OutletBoundary(dl.SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary and abs(x[0] -
                                           box_sponge[1]) < dl.DOLFIN_EPS

        class TopBoundary(dl.SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary and abs(x[1] -
                                           box_sponge[3]) < dl.DOLFIN_EPS

        self.boundary_parts = dl.FacetFunction("size_t", self.mesh)
        self.boundary_parts.set_all(0)

        Gamma_inlet = InletBoundary()
        Gamma_inlet.mark(self.boundary_parts, self.INLET)
        Gamma_axis = SymmetryBoundary()
        Gamma_axis.mark(self.boundary_parts, self.AXIS)
        Gamma_outlet = OutletBoundary()
        Gamma_outlet.mark(self.boundary_parts, self.OUTLET)
        Gamma_top = TopBoundary()
        Gamma_top.mark(self.boundary_parts, self.TOP)

        self.ds = dl.Measure("ds")[self.boundary_parts]

        class PhysicalDomain(dl.SubDomain):
            def inside(self, x, on_boundary):
                return x[0] < box[1] + dl.DOLFIN_EPS and x[
                    1] < box[3] + dl.DOLFIN_EPS

        self.domain_parts = dl.CellFunction("size_t", self.mesh)
        self.domain_parts.set_all(self.SPONGE)

        P_Domain = PhysicalDomain()
        P_Domain.mark(self.domain_parts, self.PHYSICAL)

        self.dx = dl.Measure("dx")[self.domain_parts]

        self.xfun, self.yfun = dl.MeshCoordinates(self.mesh)
        self.x_start = dl.Constant(box[1] + .5 * sponge[0])
        self.x_width = dl.Constant(.5 * sponge[0])
        self.y_start = dl.Constant(box[3] + .5 * sponge[1])
        self.y_width = dl.Constant(.5 * sponge[1])

        self.s_x = dl.Constant(1.) + (
            (dl.Constant(100) / self.x_width) *
            dl.max_value(self.xfun - self.x_start, dl.Constant(0.)))**2
        self.s_y = dl.Constant(1.) + (
            (dl.Constant(100) / self.y_width) *
            dl.max_value(self.yfun - self.y_start, dl.Constant(0.)))**2
        self.sponge_fun = self.s_x * self.s_y
Beispiel #23
0
def test_restriction(tmpdir):
    """
    Create a mesh consisting of two separate regions and define a
    dolfin Function on it which is constant in either region.
    Then extract the two subfunctions corresponding to these regions
    and check that they are constant and their function vectors
    have the correct lengths.

    """
    os.chdir(str(tmpdir))
    sphere1 = Sphere(10, center=(-20, 0, 0), name="sphere1")
    sphere2 = Sphere(20, center=(+30, 0, 0), name="sphere2")

    mesh = (sphere1 + sphere2).create_mesh(maxh=5.0)

    class Sphere1(df.SubDomain):
        def inside(self, pt, on_boundary):
            return pt[0] < 0

    class Sphere2(df.SubDomain):
        def inside(self, pt, on_boundary):
            return pt[0] > 0

    region_markers = df.CellFunction('size_t', mesh)
    subdomain1 = Sphere1()
    subdomain2 = Sphere2()
    subdomain1.mark(region_markers, 1)
    subdomain2.mark(region_markers, 2)

    submesh1 = df.SubMesh(mesh, region_markers, 1)
    submesh2 = df.SubMesh(mesh, region_markers, 2)

    r1 = restriction(mesh, submesh1)
    r2 = restriction(mesh, submesh2)

    # Define a Python function which is constant in either subregion
    def fun_f(pt):
        return 42.0 if (pt[0] < 0) else 23.0

    # Convert the Python function to a dolfin.Function
    f = scalar_valued_function(fun_f, mesh)

    # Restrict the function to each of the subregions
    f1 = r1(f)
    f2 = r2(f)

    assert (np.allclose(f1.vector().array(), 42.0))
    assert (np.allclose(f2.vector().array(), 23.0))
    assert (len(f1.vector().array()) == submesh1.num_vertices())
    assert (len(f2.vector().array()) == submesh2.num_vertices())

    a = f.vector().array()
    a1 = r1(a)
    a2 = r2(a)
    assert (set(a) == set([23.0, 42.0]))
    assert (np.allclose(a1, 42.0))
    assert (np.allclose(a2, 23.0))
    assert (len(a1) == submesh1.num_vertices())
    assert (len(a2) == submesh2.num_vertices())

    # Check a multi-dimensional array, too
    b = np.concatenate([a, a])
    b.shape = (2, -1)
    b1 = r1(b)
    b2 = r2(b)
    assert (set(b.ravel()) == set([23.0, 42.0]))
    assert (np.allclose(b1, 42.0))
    assert (np.allclose(b2, 23.0))
    assert (b1.shape == (2, submesh1.num_vertices()))
    assert (b2.shape == (2, submesh2.num_vertices()))
Beispiel #24
0
import dolfin as df

# Create a unit cube mesh
mesh = df.UnitCubeMesh(10, 10, 10)

# Create a cell function to mark a region
# consisting of the left half of the mesh
region_markers = df.CellFunction('size_t', mesh)


class Domain(df.SubDomain):
    def inside(self, pt, on_boundary):
        return pt[0] <= 0.5


subdomain = Domain()
subdomain.mark(region_markers, 1)

# Create a restricted function space
restriction = df.Restriction(region_markers, 1)
V_restr = df.VectorFunctionSpace(mesh, 'CG', 1)  #, restriction=restriction)
Beispiel #25
0
def tic():
    _tstart_stack.append(time())


def toc(fmt="Elapsed: %s s"):
    print fmt % (time() - _tstart_stack.pop())


dl.set_log_active(False)
nx = 8
ny = 8
mesh = dl.UnitSquareMesh(nx, ny)

for i in range(0):
    cell_markers = dl.CellFunction("bool", mesh)
    cell_markers.set_all(False)
    for cell in dl.cells(mesh):
        if cell.midpoint()[1] < .75 and cell.midpoint(
        )[1] > .25 and cell.midpoint()[0] > .2 and cell.midpoint()[0] < .5:
            cell_markers[cell] = True

    cell_markers.set_all(True)

    mesh = dl.refine(mesh, cell_markers)

Vh = dl.FunctionSpace(mesh, 'Lagrange', 1)

#fname = "results_biLapl/samples.pvd"
fname = "results_Lapl/samples.pvd"
Beispiel #26
0
def calcs(fname):
    data = pickle.load(open(fname+'.pickle'))
    mesh = dolfin.Mesh(data['meshfile'])
    elen = np.array([e.length() for e in dolfin.edges(mesh)])
    ave_elen = np.average(elen)
    material_meshfn = dolfin.MeshFunction('uint', mesh, data['materialsfile'])
    V = dolfin.FunctionSpace(mesh, "Nedelec 1st kind H(curl)", data['order'])
    x = data['x']
    x_r = as_dolfin_vector(x.real)
    x_i = as_dolfin_vector(x.imag)
    E_r = dolfin.Function(V, x_r)
    E_i = dolfin.Function(V, x_i)
    k0 = 2*np.pi*data['freq']/c0

    n = V.cell().n

    ReS = (1/k0/Z0)*dolfin.dot(n, (dolfin.cross(E_r, -dolfin.curl(E_i)) +
                                   dolfin.cross(E_i, dolfin.curl(E_r))))*dolfin.ds
    energy_flux = dolfin.assemble(ReS)
    surface_flux = SurfaceFlux(V)
    surface_flux.set_dofs(x)
    surface_flux.set_k0(k0)
    energy_flux2 = surface_flux.calc_flux()
    assert(np.allclose(energy_flux, energy_flux2, rtol=1e-8, atol=1e-8))    

    def boundary(x, on_boundary):
        return on_boundary
    E_r_dirich = dolfin.DirichletBC(V, E_r, boundary)
    x_r_dirich = as_dolfin_vector(np.zeros(len(x)))
    E_r_dirich.apply(x_r_dirich)
    E_i_dirich = dolfin.DirichletBC(V, E_i, boundary)
    x_i_dirich = as_dolfin_vector(np.zeros(len(x)))
    E_i_dirich.apply(x_i_dirich)
    x_dirich = x_r_dirich.array() + 1j*x_i_dirich.array()

    emfunc = CalcEMFunctional(V)
    emfunc.set_k0(k0)
    cell_domains = dolfin.CellFunction('uint', mesh)
    cell_domains.set_all(0)
    cell_region = 1
    boundary_cells = Geometry.BoundaryEdgeCells(mesh)
    boundary_cells.mark(cell_domains, cell_region)
    emfunc.set_cell_domains(cell_domains, cell_region)

    emfunc.set_E_dofs(x)
    emfunc.set_g_dofs(1j*x_dirich.conjugate()/k0/Z0)
    var_energy_flux = emfunc.calc_functional().conjugate()
    var_surf_flux = VariationalSurfaceFlux(V)
    var_surf_flux.set_dofs(x)
    var_surf_flux.set_k0(k0)
    var_energy_flux2 = var_surf_flux.calc_flux()
    assert(np.allclose(var_energy_flux, var_energy_flux2, rtol=1e-8, atol=1e-8))

    complex_voltage = ComplexVoltageAlongLine(V)
    complex_voltage.set_dofs(x)

    volts = complex_voltage.calculate_voltage(*data['source_endpoints'])

    result = dict(h=ave_elen, order=order, volts=volts,
                  sflux=energy_flux, vflux=var_energy_flux)


    print 'source power: ', volts*data['I']
    print 'energy flux:      ', energy_flux
    print 'var energy flux: ', var_energy_flux

    # print '|'.join(str(s) for s in ('', volts*data['I'], energy_flux,
    #                                 var_energy_flux, ''))

    return result
    # Number of cells in the radial direction
    nz = 200

    mesh = df.RectangleMesh(Point(0, z_dom_min), Point(r_dom, z_dom_max), nr,
                            nz)

    # Define interior of quantum dot r^2+z^2<1 and z>0
    class QuantumDot(df.SubDomain):
        def inside(self, x, on_boundary):
            return df.between(x[0]**2 + x[1]**2,
                              (0, 1)) and df.between(x[1], (0, 1))

    quantumDot = QuantumDot()

    domains = df.CellFunction("size_t", mesh)
    domains.set_all(0)
    quantumDot.mark(domains, 1)

    V = df.FunctionSpace(mesh, "CG", 1)

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

    drdz = df.Measure("dx")[domains]
    r = df.Expression("x[0]")

    # Confining potential
    potential = df.Constant(100)

    # Partial derivatives of trial and test functions
Beispiel #28
0
    def compute_derrick(self):

        D = self.physics.D

        r = Expression('x[0]', degree=self.fem.func_degree)
        # r^(D-1)
        rD = Expression('pow(x[0],D-1)', D=D, degree=self.fem.func_degree)

        mu, M = Constant(self.physics.mu), Constant(self.physics.M)
        lam = Constant(self.physics.lam)
        mn = Constant(self.mn)

        r_values, Phi_values = get_values(self.Phi, output_mesh=True)

        # the numerical value of the potential energy goes below the machine precision on
        # its biggest component after some radius (at those radii the biggest component is the vacuum energy)
        # analytically, we know the integral over that and bigger radii should be close to 0
        # to avoid integrating numerical noise (and blowing it up by r^D) we restrict integration
        # on the submesh where the potential energy is resolved within machine precision

        # find radius at which potential energy drops below machine precision
        vacuum_energy = self.physics.mu**4 / (4. * self.physics.lam)
        eV = lam / 4. * self.Phi**4 - mu**2 / 2. * self.Phi**2 + Constant(
            vacuum_energy)
        eV_values = self.physics.lam / 4. * Phi_values**4 - self.physics.mu**2 / 2. * Phi_values**2 + vacuum_energy
        eV_idx_wrong = np.where(eV_values < d.DOLFIN_EPS * vacuum_energy)[0][0]
        eV_r_wrong = r_values[eV_idx_wrong]

        # define a submesh where the potential energy density is resolved
        class eV_Resolved(SubDomain):
            def inside(self, x, on_boundary):
                return x[0] < eV_r_wrong

        eV_resolved = eV_Resolved()
        eV_subdomain = d.CellFunction('size_t', self.fem.mesh.mesh)
        eV_subdomain.set_all(0)
        eV_resolved.mark(eV_subdomain, 1)
        eV_submesh = d.SubMesh(self.fem.mesh.mesh, eV_subdomain, 1)

        # integrate potential energy density
        E_V = d.assemble(eV * rD * dx(eV_submesh))
        E_V /= self.mn**D  # get physical distances - integral now has mass dimension 4 - D

        # kinetic energy - here we are limited by the machine precision on the gradient
        # the numerical value of the field is limited by the machine precision on the VEV, which
        # we are going to use as threshold
        eK_idx_wrong = np.where(
            abs(Phi_values - self.physics.Vev) < d.DOLFIN_EPS *
            self.physics.Vev)[0][0]
        eK_r_wrong = r_values[eK_idx_wrong]

        # define a submesh where the kinetic energy density is resolved
        class eK_Resolved(SubDomain):
            def inside(self, x, on_boundary):
                return x[0] < eK_r_wrong

        eK_resolved = eK_Resolved()
        eK_subdomain = d.CellFunction('size_t', self.fem.mesh.mesh)
        eK_subdomain.set_all(0)
        eK_resolved.mark(eK_subdomain, 1)
        eK_submesh = d.SubMesh(self.fem.mesh.mesh, eK_subdomain, 1)

        # integrate kinetic energy density
        eK = Constant(0.5) * self.grad_Phi**2
        E_K = d.assemble(eK * rD * dx(eK_submesh))
        E_K /= self.mn**D  # get physical distances - integral now has mass dimension 4 - D

        # matter coupling energy
        erho = self.source.rho / M * self.Phi
        E_rho = d.assemble(
            erho * rD *
            dx)  # rescaled rho, and so the integral, has mass dimension 4 - D

        # integral terms of Derrick's theorem
        derrick1 = (D - 2.) * E_K + D * (E_V + E_rho)
        derrick4 = 2. * (D - 2.) * E_K

        # non-integral terms of Derrick's theorem - these have mass dimension 4 - D
        derrick2 = self.source.Rho_bar * self.source.Rs**D * \
                   self.Phi(self.fem.mesh.rs) / self.physics.M
        derrick3 = self.source.Rho_bar * self.source.Rs**(D+1.) * \
                   self.grad_Phi(self.fem.mesh.rs) / self.physics.M

        self.derrick = [derrick1, derrick2, derrick3, derrick4]
Beispiel #29
0
    def create_mesh(self, mesh_input, plot_flag=False, plot_title=None):
        """Create a mesh according to the user's specifications.

           Mark the mesh with field and particle boundary-conditions.

        """

        fncName = '('+__file__+') ' + sys._getframe().f_code.co_name + '():\n'

        umi = mesh_input

#        print 'umi.cells_on_side = ', umi.cells_on_side

        xmin = umi.pmin.x()
        xmax = umi.pmax.x()
        ymin = umi.pmin.y()
        ymax = umi.pmax.y()
        zmin = umi.pmin.z()
        zmax = umi.pmax.z()

        # Options: 'left, 'right', 'left/right', 'crossed'
        diagonal = umi.diagonal

        # Boundary conditions for fields and particles
        fieldBoundaryDict = umi.field_boundary_dict
        particleBoundaryDict = umi.particle_boundary_dict
        particleSourceDict = umi.particle_source_dict

        plotTitle = plot_title

#        if umi.pmin.y() == umi.pmax.y() and umi.pmin.z() == umi.pmax.z():
        if ymin == ymax and zmin == zmax:
            # 1D mesh
            (nx,) = umi.cells_on_side # Need the comma to indicate a tuple
            mesh_df = df_m.IntervalMesh(nx, xmin, xmax)

            if plot_title is None: plotTitle = "X-mesh"
            # Name the mesh file that will be written below
            meshFileName = "X-mesh.pvd"

            # Field boundary conditions

            if fieldBoundaryDict is not None:
                #
                # Mark the Dirichlet-boundaries before transforming the mesh.
                #

                # Create a MeshFunction object that is defined on mesh facets (which
                # in this 1D case are cell vertices.)  The function has (size_t) value
                # of 0, 1, or 2 here.  These mark the mesh vertices where Dirichlet
                # conditions need to be set.  The boundary potentials corresponding to
                # these numbers are set later.

                # A 'boundary' by definition has dimension 1 less than the domain:
                fieldBoundaryMarker = df_m.MeshFunction('size_t', mesh_df, mesh_df.topology().dim()-1)

    #        print 'dim =', mesh_df.topology().dim()

                # Initialize all the facets with a default value of 0.
                # Then overwrite boundary facets that have Dirichlet BCs.
                fieldBoundaryMarker.set_all(0)

                # Create mesh subdomains Gamma_nnn that are the boundaries
                # (Could also do this later when the mesh has been stretched)
                Gamma_xmin = XBoundary_C(xmin) # Gamma_xmin is the lower X boundary
                Gamma_xmax = XBoundary_C(xmax) # Gamma_xmax is the upper X boundary

                # Assign integer IDs to the boundaries with Dirichlet
                # conditions.  Create a FacetFunction to store these values.
                xmin_indx = fieldBoundaryDict['xmin']
                xmax_indx = fieldBoundaryDict['xmax']
                Gamma_xmin.mark(fieldBoundaryMarker, xmin_indx) # Mark the lower
                                                                # X boundary
                                                                # with xmin_indx
                Gamma_xmax.mark(fieldBoundaryMarker, xmax_indx) # Mark the upper
                                                                # X boundary
                                                                # with xmax_indx
            else:
                fieldBoundaryMarker = None
            #   END:if fieldBoundaryDict is not None:

            if particleBoundaryDict is not None:
                # Mark the facets for particle boundary conditions
                # Create a MeshFunction object defined on the facets of this
                # mesh.  The function has a default (size_t) value of 0,
                # meaning 'no action needed'

                # A boundary has dimension 1 less than the domain:
                particleBoundaryMarker = df_m.MeshFunction('size_t', mesh_df, mesh_df.topology().dim()-1)
                # Initialize all mesh facets with a default value of 0.
                particleBoundaryMarker.set_all(0)
            else:
                particleBoundaryMarker = None
            #   END:if particleBoundaryDict is not None:

            if particleSourceDict is not None:
                # Mark the cells for particle source regions.
                # Create a MeshFunction object defined on the mesh cells
                # The function has a default (size_t) value of 0,
                # meaning 'no particle creation here'

                particleSourceMarker = df_m.CellFunction('size_t', mesh_df)
                particleSourceMarker.set_all(0)
                # Create mesh subdomains where particles are generated

                # There's one line below for each entry in the dictionary
                sourceX1 = SourceXrange(sourceX1min, sourceX1max)
                sourceX2 = SourceXrange(sourceX2min, sourceX2max)

                particleSourceDictInv = {v: k for k, v in particleSourceDict.items()}
                # Get the numerical value that identifies this source
                sourceX1_indx = int(particleSourceDictInv['sourceX1'])
                sourceX2_indx = int(particleSourceDictInv['sourceX2'])
                # Mark the cells in the source with this value
                sourceX1.mark(particleSourceMarker, sourceX1_indx)
                sourceX2.mark(particleSourceMarker, sourceX2_indx)
            else:
                particleSourceMarker = None
            #   END:if particleSourceDict is not None:

#        elif umi.pmin.z() == umi.pmax.z():
        elif zmin == zmax:
            # 2D mesh
            (nx, ny) = umi.cells_on_side

# v > 1.5:
#            if df_m.DOLFIN_VERSION_STRING > '1.5.0':
            if df_m.__version__ > '1.5.0':
                if diagonal is not None:
                    mesh_df = df_m.RectangleMesh(umi.pmin, umi.pmax, nx, ny, diagonal)
                else:
                    mesh_df = df_m.RectangleMesh(umi.pmin, umi.pmax, nx, ny)
            else:
# v = 1.5:
                mesh_df = df_m.RectangleMesh(umi.pmin[0], umi.pmin[1], umi.pmax[0], umi.pmax[1], nx, ny)

            if plot_title is None: plotTitle = "XY-mesh"
            # Name the mesh file that will be written below
            meshFileName = "XY-mesh.pvd"

            if fieldBoundaryDict is not None:
                error_msg = "Error in %s" % fncName
                sys.exit(error_msg)
            else:
                fieldBoundaryMarker = None

            if particleBoundaryDict is not None:
                # A boundary has dimension 1 less than the domain:
                particleBoundaryMarker = df_m.MeshFunction('size_t', mesh_df, mesh_df.topology().dim()-1)
                # Initialize all mesh facets with a default value of 0.
                particleBoundaryMarker.set_all(0)

                # Create mesh subdomains to apply boundary-conditions
                # There's one line below for each entry in the dictionary
                Gamma_xmin = XBoundary_C(xmin)
                Gamma_xmax = XBoundary_C(xmax)
                Gamma_ymin = YBoundary_C(ymin)
                Gamma_ymax = YBoundary_C(ymax)

#                print "particleBoundaryDict =", particleBoundaryDict

                # Mark these subdomains (boundaries) with non-zero size_t integers

                xmin_indx = particleBoundaryDict['xmin']
                xmax_indx = particleBoundaryDict['xmax']
                ymin_indx = particleBoundaryDict['ymin']
                ymax_indx = particleBoundaryDict['ymax']
                Gamma_xmin.mark(particleBoundaryMarker, xmin_indx)
                Gamma_xmax.mark(particleBoundaryMarker, xmax_indx)
                Gamma_ymin.mark(particleBoundaryMarker, ymin_indx)
                Gamma_ymax.mark(particleBoundaryMarker, ymax_indx)
            else:
                particleBoundaryMarker = None
#           END:if particleBoundaryDict is not None:

            if particleSourceDict is not None:
                error_msg = "Error in %s" % fncName
                sys.exit(error_msg)
            else:
                particleSourceMarker = None

#       END:elif zmin == zmax:

        else:
            # 3D mesh
            (nx, ny, nz) = umi.cells_on_side
# v > 1.5
            if df_m.__version__ > '1.5.0':
                mesh_df = df_m.BoxMesh(umi.pmin, umi.pmax, nx, ny, nz)
            else:
# v = 1.5:
                mesh_df = df_m.BoxMesh(umi.pmin[0], umi.pmin[1], umi.pmin[2], umi.pmax[0], umi.pmax[1], umi.pmax[2], nx, ny, nz)

            if plot_title is None: plotTitle = "XYZ-mesh"
            # Name the mesh file that will be written below
            meshFileName = "XYZ-mesh.pvd"

            if fieldBoundaryDict is not None:
                error_msg = "Error in %s" % fncName
                sys.exit(error_msg)
            else:
                fieldBoundaryMarker = None

            if particleBoundaryDict is not None:
            # A boundary has dimension 1 less than the domain:
                particleBoundaryMarker = df_m.MeshFunction('size_t', mesh_df, mesh_df.topology().dim()-1)
            # Initialize all mesh facets with a default value of 0.
                particleBoundaryMarker.set_all(0)
            else:
                particleBoundaryMarker = None

            if particleSourceDict is not None:
                error_msg = "Error in %s" % fncName
                sys.exit(error_msg)
            else:
                particleSourceMarker = None

#       END:if ymin == ymax and zmin == zmax:

        # Make a plot of the mesh, with non-zero values showing marked
        # boundaries
        if (plot_flag):
            df_m.plot(mesh_df, title=plotTitle)
# VTK:           df_m.plot(fieldBoundaryMarker, title='field boundary marks', axes=True)
            mplot_m.show()
#            yesno = raw_input("Just called show() in create_mesh")

#            df_m.plot(particleBoundaryMarker, title='particle boundary marks', axes=True)
#            df_m.interactive()

        # Write the mesh to a VTK file for plotting
        meshFile = df_m.File(meshFileName)
        meshFile << mesh_df

        # Save the class attributes
        self.mesh = mesh_df
        self.field_boundary_marker = fieldBoundaryMarker
        self.particle_boundary_marker = particleBoundaryMarker
        self.particle_source_marker = particleSourceMarker

        return