def __init__(self, nxs, bcs, name='singleblockmesh', coords=None, coordelem=None, procsizes=None): assert (len(nxs) == len(bcs)) self.ndim = len(nxs) self.nxs = nxs self.bcs = bcs self._name = name self._blist = [] self.bdirecs = [] self.extruded = False for i, bc in enumerate(bcs): if bc == 'periodic': self._blist.append(PETSc.DM.BoundaryType.PERIODIC) else: self._blist.append(PETSc.DM.BoundaryType.NONE) # GHOSTED # THIS WORKS FOR ALL THE UTILITY MESHES SO FAR # MIGHT NEED SOMETHING MORE GENERAL IN THE FUTURE? if i == 0: direc = 'x' if i == 1: direc = 'y' if i == 2: direc = 'z' self.bdirecs.append(direc + '-') self.bdirecs.append(direc + '+') # generate mesh if not (procsizes is None): self.cell_da = PETSc.DMDA().create( dim=self.ndim, dof=1, sizes=nxs, boundary_type=self._blist, stencil_type=PETSc.DMDA.StencilType.BOX, stencil_width=1, proc_sizes=procsizes) else: self.cell_da = PETSc.DMDA().create( dim=self.ndim, dof=1, sizes=nxs, boundary_type=self._blist, stencil_type=PETSc.DMDA.StencilType.BOX, stencil_width=1) if coords is None: if (coordelem is None): if len(nxs) == 1: if bcs[0] == 'nonperiodic': celem = FiniteElement("CG", interval, 1, variant='feec') else: celem = FiniteElement("DG", interval, 1, variant='feec') if len(nxs) == 2: if bcs[0] == 'nonperiodic' and bcs[1] == 'nonperiodic': celem = FiniteElement("Q", quadrilateral, 1, variant='feec') else: celem = FiniteElement("DQ", quadrilateral, 1, variant='feec') if len(nxs) == 3: if bcs[0] == 'nonperiodic' and bcs[ 1] == 'nonperiodic' and bcs[2] == 'nonperiodic': celem = FiniteElement("Q", hexahedron, 1, variant='feec') else: celem = FiniteElement("DQ", hexahedron, 1, variant='feec') else: # ADD SANITY CHECKS ON COORDINATE ELEMENT HERE celem = coordelem else: celem = coords.function_space()._uflelement.sub_elements()[0] vcelem = VectorElement(celem, dim=self.ndim) self._celem = celem self._vcelem = vcelem Mesh.__init__(self, self._vcelem) # construct and set coordsvec coordsspace = FunctionSpace(self, self._vcelem) self.coordinates = Function(coordsspace, name='coords') if coords is None: coordsdm = coordsspace.get_da(0) coordsarr = coordsdm.getVecArray(self.coordinates._vector)[:] newcoords = create_reference_domain_coordinates( self.cell_da, celem) if len(nxs) == 1: coordsarr[:] = np.squeeze(newcoords[:]) else: coordsarr[:] = newcoords[:] else: coords._vector.copy(result=self.coordinates._vector) self.coordinates.scatter()
def __init__(self, nxs, bcs, name='singleblockmesh', coordelem=None): assert (len(nxs) == len(bcs)) self.ndim = len(nxs) self.nxs = [ nxs, ] self.bcs = bcs self.npatches = 1 self.patchlist = [] self._name = name self._blist = [] for bc in bcs: if bc == 'periodic': self._blist.append(PETSc.DM.BoundaryType.PERIODIC) else: self._blist.append(PETSc.DM.BoundaryType.GHOSTED) bdx = 0 bdy = 0 bdz = 0 edgex_nxs = list(nxs) if (bcs[0] == 'nonperiodic'): edgex_nxs[0] = edgex_nxs[0] + 1 bdx = 1 if self.ndim >= 2: edgey_nxs = list(nxs) if (bcs[1] == 'nonperiodic'): edgey_nxs[1] = edgey_nxs[1] + 1 bdy = 1 if self.ndim >= 3: edgez_nxs = list(nxs) if (bcs[2] == 'nonperiodic'): edgez_nxs[2] = edgez_nxs[2] + 1 bdz = 1 # generate mesh cell_da = PETSc.DMDA().create() #THIS SHOULD REALLY BE AN OPTIONS PREFIX THING TO MESH... #MAIN THING IS THE ABILITY TO CONTROL DECOMPOSITION AT COMMAND LINE #BUT WE WANT TO BE ABLE TO IGNORE DECOMPOSITION WHEN RUNNING WITH A SINGLE PROCESSOR #WHICH ALLOWS THE SAME OPTIONS LIST TO BE USED TO RUN SOMETHING IN PARALLEL, AND THEN DO PLOTTING IN SERIAL! if PETSc.COMM_WORLD.size > 1: #this allows the same options list to be used to run something in parallel, but then plot it in serial! cell_da.setOptionsPrefix(self._name + '0_') cell_da.setFromOptions() ############# cell_da.setDim(self.ndim) cell_da.setDof(1) cell_da.setSizes(nxs) cell_da.setBoundaryType(self._blist) cell_da.setStencil(PETSc.DMDA.StencilType.BOX, 1) cell_da.setUp() #print self.cell_da.getProcSizes() edgex_da = PETSc.DMDA().create(dim=self.ndim, dof=1, sizes=edgex_nxs, proc_sizes=cell_da.getProcSizes(), boundary_type=self._blist, stencil_type=PETSc.DMDA.StencilType.BOX, stencil_width=1, setup=False) #THIS IS AN UGLY HACK NEEDED BECAUSE OWNERSHIP RANGES ARGUMENT TO petc4py DMDA_CREATE is BROKEN decompfunction(cell_da, edgex_da, self.ndim, 1, 1, 1, bdx, 0, 0) edgex_da.setUp() if self.ndim >= 2: edgey_da = PETSc.DMDA().create( dim=self.ndim, dof=1, sizes=edgey_nxs, proc_sizes=cell_da.getProcSizes(), boundary_type=self._blist, stencil_type=PETSc.DMDA.StencilType.BOX, stencil_width=1, setup=False) #THIS IS AN UGLY HACK NEEDED BECAUSE OWNERSHIP RANGES ARGUMENT TO petc4py DMDA_CREATE is BROKEN decompfunction(cell_da, edgey_da, self.ndim, 1, 1, 1, 0, bdy, 0) edgey_da.setUp() if self.ndim >= 3: edgez_da = PETSc.DMDA().create( dim=self.ndim, dof=1, sizes=edgez_nxs, proc_sizes=cell_da.getProcSizes(), boundary_type=self._blist, stencil_type=PETSc.DMDA.StencilType.BOX, stencil_width=1, setup=False) #THIS IS AN UGLY HACK NEEDED BECAUSE OWNERSHIP RANGES ARGUMENT TO petc4py DMDA_CREATE is BROKEN decompfunction(cell_da, edgez_da, self.ndim, 1, 1, 1, 0, 0, bdz) edgez_da.setUp() self._cell_das = [ cell_da, ] self._edgex_das = [ edgex_da, ] self._edgex_nxs = [ edgex_nxs, ] if self.ndim >= 2: self._edgey_das = [ edgey_da, ] self._edgey_nxs = [ edgey_nxs, ] if self.ndim >= 3: self._edgez_das = [ edgez_da, ] self._edgez_nxs = [ edgez_nxs, ] #ADD ACTUAL COORDINATE FUNCTION INITIALIZATION HERE #construct coordelem #FIX THIS- SHOULD USE H1 FOR NON-PERIODIC! #Use DG for periodic boundaries to avoid wrapping issues h1elem = FiniteElement("CG", interval, 1) #1 dof per element = linear l2elem = FiniteElement("DG", interval, 1) #2 dofs per element = linear elemlist = [] dxs = [] pxs = [] lxs = [] for i in range(len(nxs)): dxs.append(2.) pxs.append(0.) lxs.append(2. * nxs[i]) #if bcs[i] == 'periodic': elemlist.append(l2elem) #else: # elemlist.append(h1elem) celem = TensorProductElement(*elemlist) if len(nxs) == 1: celem = elemlist[0] if not (coordelem == None): celem = coordelem celem = VectorElement(celem, dim=self.ndim) Mesh.__init__(self, celem) #THIS BREAKS FOR COORDELEM NOT DG1... #construct and set coordsvec coordsspace = FunctionSpace(self, celem) self.coordinates = Function(coordsspace, name='coords') localnxs = self.get_local_nxny(0) newcoords = create_uniform_nodal_coords(self.get_cell_da(0), nxs, pxs, lxs, dxs, bcs, localnxs) coordsdm = coordsspace.get_da(0, 0) coordsarr = coordsdm.getVecArray(self.coordinates._vector)[:] if len(pxs) == 1: coordsarr[:] = np.squeeze(newcoords[:]) else: coordsarr[:] = newcoords[:] self.coordinates.scatter()