Пример #1
0
    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()
Пример #2
0
    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()