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)
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))
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)
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
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]
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
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)
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
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])
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
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
# 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]:
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))
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))
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
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()))
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)
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"
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
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]
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