def write_dolfin_mesh(mesh, basename, cell_function=None, cell_coeff=None, facet_function=None, transform=None): real_dirname = os.path.dirname(basename) sa_utils.makedirs_norace(real_dirname) real_basename = os.path.basename(basename) mesh.init() basedim = mesh.geometry().dim() num_vertices = mesh.num_vertices() num_cells = mesh.num_cells() num_facets = mesh.num_facets() h5_file = h5py.File(basename + '.h5', 'w') if transform is None: h5_file.create_dataset('/vertices', (num_vertices, basedim), data=mesh.coordinates(), compression=my_compression) else: h5_file.create_dataset('/vertices', (num_vertices, basedim), data=transform(mesh.coordinates()), compression=my_compression) h5_file.create_dataset('/cells', (num_cells, basedim + 1), data=np.array(mesh.cells(), dtype=np.uintp), compression=my_compression) h5_file.create_dataset('/facets', (num_facets, basedim), data=np.array( [facet.entities(0) for facet in facets(mesh)], dtype=np.uintp), compression=my_compression) if cell_function is not None: h5_file.create_dataset('/cell_function', (num_cells, 1), data=cell_function.array(), compression=my_compression) if cell_coeff is not None: h5_file.create_dataset('/cell_coeff', (num_cells, 1), data=cell_coeff.array(), compression=my_compression) if facet_function is not None: h5_file.create_dataset('/facet_function', (num_facets, 1), data=facet_function.array(), compression=my_compression) h5_file.close() del h5_file cells_string = r'' if cell_function is not None: cells_string += r""" <Attribute Name = "cell_function" AttributeType = "Scalar" Center = "Cell"> <DataItem Format = "HDF" Dimensions = "{:d} 1">{:s}.h5:/cell_function</DataItem> </Attribute>""".format(num_cells, real_basename) if cell_coeff is not None: cells_string += r""" <Attribute Name = "cell_coeff" AttributeType = "Scalar" Center = "Cell"> <DataItem Format = "HDF" Dimensions = "{:d} 1">{:s}.h5:/cell_coeff</DataItem> </Attribute>""".format(num_cells, real_basename) cell_file = open(basename + '_cells.xdmf', 'w') cell_file.write(r"""<?xml version = "1.0"?> <Xdmf Version = "2.0" xmlns:xi = "http://www.w3.org/2001/XInclude"> <Domain> <Grid Name = "cells" GridType = "Uniform"> <Topology NumberOfElements = "{:d}" TopologyType = "{:s}"> <DataItem Format = "HDF" Dimensions = "{:d} {:d}">{:s}.h5:/cells</DataItem> </Topology> <Geometry GeometryType = "{:s}"> <DataItem Format = "HDF" Dimensions = "{:d} {:d}">{:s}.h5:/vertices</DataItem> </Geometry>{:s} </Grid> </Domain> </Xdmf>""".format(num_cells, 'Tetrahedron' if basedim == 3 else 'Triangle', num_cells, basedim + 1, real_basename, "XYZ" if basedim == 3 else "XY", num_vertices, basedim, real_basename, cells_string)) cell_file.close() del cell_file if facet_function is None: facets_string = r'' else: facets_string = r""" <Attribute Name = "facet_function" AttributeType = "Scalar" Center = "Cell"> <DataItem Format = "HDF" Dimensions = "{:d} 1">{:s}.h5:/facet_function</DataItem> </Attribute>""".format(num_facets, real_basename) facet_file = open(basename + '_facets.xdmf', 'w') facet_file.write(r"""<?xml version = "1.0"?> <Xdmf Version = "2.0" xmlns:xi = "http://www.w3.org/2001/XInclude"> <Domain> <Grid Name = "facets" GridType = "Uniform"> <Topology NumberOfElements = "{:d}" TopologyType = "{:s}"> <DataItem Format = "HDF" Dimensions = "{:d} {:d}">{:s}.h5:/facets</DataItem> </Topology> <Geometry GeometryType = "{:s}"> <DataItem Format = "HDF" Dimensions = "{:d} {:d}">{:s}.h5:/vertices</DataItem> </Geometry>{:s} </Grid> </Domain> </Xdmf>""".format( num_facets, 'Triangle' if basedim == 3 else 'PolyLine" NodesPerElement = "2', num_facets, basedim, real_basename, "XYZ" if basedim == 3 else "XY", num_vertices, basedim, real_basename, facets_string)) facet_file.close() del facet_file print('written [' + basename + '] mesh and markers')
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
def write_dolfin_vector_cg1(basename, vector_functions, scale_to_one=False): print('write_dolfin_vector_cg1({:s})'.format(basename)) real_dirname = os.path.dirname(basename) sa_utils.makedirs_norace(real_dirname) real_basename = os.path.basename(basename) mesh = vector_functions[0].function_space().mesh() mesh.init() basedim = mesh.geometry().dim() num_vertices = mesh.num_vertices() num_cells = mesh.num_cells() h5_file = h5py.File(basename + '.h5', 'w') h5_vertices = h5_file.create_dataset('/vertices', (num_vertices, basedim), data=mesh.coordinates(), compression=my_compression) h5_cells = h5_file.create_dataset('/cells', (num_cells, basedim + 1), data=np.array(mesh.cells(), dtype=np.uintp), compression=my_compression) h5_grp = h5_file.create_group('/vector') num = len(vector_functions) index_map = vertex_to_dof_map(vector_functions[0].function_space()) if scale_to_one: for ii, uu in enumerate(vector_functions): data = uu.vector()[index_map] umin = np.min(data) umax = np.max(data) if umax < -umin: data /= -umin elif 0 < umax: data /= umax h5_grp.create_dataset('{:d}'.format(ii), (num_vertices * basedim, ), data=data, compression=my_compression) else: for ii, uu in enumerate(vector_functions): h5_grp.create_dataset('{:d}'.format(ii), (num_vertices * basedim, ), data=uu.vector()[index_map], compression=my_compression) h5_file.close() vector_file = open(basename + '.xdmf', 'w') string = r"""<?xml version = "1.0"?> <Xdmf Version = "2.0" xmlns:xi = "http://www.w3.org/2001/XInclude"> <Domain> <Grid Name = "cells" GridType = "Uniform"> <Topology NumberOfElements = "{:d}" TopologyType = "{:s}"> <DataItem Format = "HDF" Dimensions = "{:d} {:d}">{:s}.h5:/cells</DataItem> </Topology> <Geometry GeometryType = "{:s}"> <DataItem Format = "HDF" Dimensions = "{:d} {:d}">{:s}.h5:/vertices</DataItem> </Geometry> </Grid>""".format(num_cells, 'Tetrahedron' if basedim == 3 else 'Triangle', num_cells, basedim + 1, real_basename, "XYZ" if basedim == 3 else "XY", num_vertices, basedim, real_basename) string += """ <Grid Name = "vector" GridType = "Collection" CollectionType = "Temporal"> <Time TimeType = "List"> <DataItem Format = "XML" Dimensions = "{:d}"> """.format(num) for ii in range(num): string += " {:d}".format(ii) string += r""" </DataItem> </Time>""" for ii in range(num): string += r""" <Grid Name = "grid_{:d}" GridType = "Uniform"> <Topology NumberOfElements = "{:d}" TopologyType = "{:s}"> <DataItem Format = "HDF" Dimensions = "{:d} {:d}">{:s}.h5:/cells</DataItem> </Topology> <Geometry GeometryType = "{:s}"> <DataItem Format = "HDF" Dimensions = "{:d} {:d}">{:s}.h5:/vertices</DataItem> </Geometry>""".format( ii, num_cells, 'Tetrahedron' if basedim == 3 else 'Triangle', num_cells, basedim + 1, real_basename, "XYZ" if basedim == 3 else "XY", num_vertices, basedim, real_basename) for jj in range(basedim): string += r""" <Attribute Name = "u_{:d}" AttributeType = "Scalar" Center = "Node"> <DataItem ItemType = "HyperSlab" Dimensions = "{:d}"> <DataItem Dimensions = "3 1" Format = "XML"> {:d} {:d} {:d} </DataItem> <DataItem Format = "HDF" Dimensions = "{:d}">{:s}.h5:/vector/{:d}</DataItem> </DataItem> </Attribute>""".format(jj, num_vertices, jj, basedim, num_vertices, num_vertices * basedim, real_basename, ii) string += r""" </Grid>""" string += r""" </Grid> </Domain> </Xdmf>""" vector_file.write(string) vector_file.close() print( 'write_dolfin_vector_cg1({:s}) written [{:d}] vector functions'.format( basename, num))
def create_patches(mesh, mf, alpha=1.25, beta=2.0, patch_h=60., prefix='anisotropic', logger=None): if logger is None: info = print else: info = logger.info global_array = mf.array() patch_numbers = np.array(np.ceil(high_array/patch_h), dtype=int) patch_total = np.prod(patch_numbers) patch_fill = int(np.log(patch_total)/np.log(10.))+1 patch_hs = high_array/patch_numbers patch_extended = patch_hs*alpha patch_inner = patch_extended*0.5 info('Creating patches, numbers '+str(patch_numbers)+', hs '+str(patch_hs)+', total ['+str(patch_total)+']') 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') dirname = prefix+'/'+prefix+'_0_patches/0' sa_utils.makedirs_norace(dirname) global_V0 = FunctionSpace(mesh, 'DG', 0) u0 = Function(global_V0) u0.vector().set_local(mf.array()) info('DG function created') def mesh_patch(kk, jj, ii, count, qq): patch_z = patch_hs[2]*(kk+0.5) patch_y = patch_hs[1]*(jj+0.5) patch_x = patch_hs[0]*(ii+0.5) patch_name = dirname+'/patch_'+str(count).zfill(patch_fill) ext_name = patch_name+'_2.0' center = np.array([patch_x, patch_y, patch_z]) extended = AutoSubDomain(lambda xx, on_boundary: (np.abs(xx - center) < patch_extended+myeps).all()) extended_mesh = SubMesh(mesh, extended) del extended info('['+str(count)+'] cut out') inner = AutoSubDomain(lambda xx, on_boundary: (np.abs(xx - center) < patch_inner+myeps).all()) inner_marker = MeshFunction('bool', extended_mesh, 3, False) inner.mark(inner_marker, True) extended_mesh = refine(extended_mesh, inner_marker) del inner_marker info('['+str(count)+'] refined') mf = MeshFunction('size_t', extended_mesh, 3, 1) mf.rename('cell_function', 'label') inner.mark(mf, 0) info('['+str(count)+'] cell function refined') local_V0 = FunctionSpace(extended_mesh, 'DG', 0) v0 = interpolate(u0, local_V0) coefficient = MeshFunction('double', extended_mesh, 3, 0) coefficient.set_values(v0.vector().array()) info('['+str(count)+'] extended phi created') nodes = extended_mesh.coordinates() low = np.min(nodes, axis=0) high = np.max(nodes, axis=0) extended_left = AutoSubDomain(lambda xx, on_boundary: on_boundary and near(xx[0], low[0], eps=(high[0]-low[0])*myeps)) extended_right = AutoSubDomain(lambda xx, on_boundary: on_boundary and near(xx[0], high[0], eps=(high[0]-low[0])*myeps)) extended_front = AutoSubDomain(lambda xx, on_boundary: on_boundary and near(xx[1], low[1], eps=(high[1]-low[1])*myeps)) extended_back = AutoSubDomain(lambda xx, on_boundary: on_boundary and near(xx[1], high[1], eps=(high[1]-low[1])*myeps)) extended_bottom = AutoSubDomain(lambda xx, on_boundary: on_boundary and near(xx[2], low[2], eps=(high[2]-low[2])*myeps)) extended_top = AutoSubDomain(lambda xx, on_boundary: on_boundary and near(xx[2], high[2], eps=(high[2]-low[2])*myeps)) del nodes facets = MeshFunction('size_t', extended_mesh, 2, 0) extended_left.mark(facets, 7); extended_right.mark(facets, 8) extended_front.mark(facets, 9); extended_back.mark(facets, 10) extended_bottom.mark(facets, 11); extended_top.mark(facets, 12) del extended_left, extended_right, extended_front, extended_back, extended_bottom, extended_top left.mark(facets, 1); right.mark(facets, 2) front.mark(facets, 3); back.mark(facets, 4) bottom.mark(facets, 5); top.mark(facets, 6) bottom_in.mark(facets, 101); top_in.mark(facets, 102) bottom_out.mark(facets, 103); top_out.mark(facets, 104) info('['+str(count)+'] extended facets created') sa_hdf5.write_dolfin_mesh(extended_mesh, ext_name, cell_function=mf, cell_coeff=coefficient, facet_function=facets) # inner_mesh = SubMesh(extended_mesh, inner) # del inner, extended_mesh # File(patch_name+'.xml') << inner_mesh # mesh_file = XDMFFile(comm, patch_name+'.xdmf') # mesh_file.write(inner_mesh) del facets, low, high, coefficient, v0, local_V0, mf, inner, extended_mesh, center, ext_name, patch_name, patch_x, patch_y, patch_z count += 1 info('['+str(count)+'] finished') gc.collect() qq.put(None) old = sa_utils.get_time() out_q = multiprocessing.Queue() processes = [] count = 0 for kk in range(patch_numbers[2]): for jj in range(patch_numbers[1]): for ii in range(patch_numbers[0]): processes.append(multiprocessing.Process(target=mesh_patch, args=(kk, jj, ii, count, out_q))) count += 1 pt_length = len(processes) block = multiprocessing.cpu_count() block_low = 0; block_high = np.min([block, pt_length]) while(block_low < block_high): for kk in range(block_low, block_high): processes[kk].start() for kk in range(block_low, block_high): out_q.get() for kk in range(block_low, block_high): processes[kk].join() processes[kk] = None logger.info('['+str(kk)+'] joined') block_low = block_high block_high = np.min([block_high+block, pt_length]) new = sa_utils.get_time() info('[{:d}] patches meshed with [{:d}] cpus in [{:s}]'.format(count,block,sa_utils.human_time(new-old))) info('Finished creating patches') del info