Skip to content

Commit

Permalink
Merged pc-patch (pull request #108)
Browse files Browse the repository at this point in the history
* pc-patch:
  PC: wrap up new PCPatch functionality
  • Loading branch information
wence- committed Sep 27, 2018
2 parents c4d3330 + 6c06920 commit 6040602
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 8 deletions.
89 changes: 81 additions & 8 deletions src/PETSc/PC.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class PCType(object):
KACZMARZ = S_(PCKACZMARZ)
TELESCOPE = S_(PCTELESCOPE)
LMVM = S_(PCLMVM)
PATCH = S_(PCPATCH)

class PCSide(object):
# native
Expand Down Expand Up @@ -103,21 +104,28 @@ class PCFieldSplitSchurFactType(object):
UPPER = PC_FIELDSPLIT_SCHUR_FACT_UPPER
FULL = PC_FIELDSPLIT_SCHUR_FACT_FULL

class PCPatchConstructType(object):
STAR = PC_PATCH_STAR
VANKA = PC_PATCH_VANKA
USER = PC_PATCH_USER
PYTHON = PC_PATCH_PYTHON

# --------------------------------------------------------------------

cdef class PC(Object):

Type = PCType
Side = PCSide

ASMType = PCASMType
GASMType = PCGASMType
MGType = PCMGType
MGCycleType = PCMGCycleType
GAMGType = PCGAMGType
CompositeType = PCCompositeType
SchurFactType = PCFieldSplitSchurFactType
SchurPreType = PCFieldSplitSchurPreType
ASMType = PCASMType
GASMType = PCGASMType
MGType = PCMGType
MGCycleType = PCMGCycleType
GAMGType = PCGAMGType
CompositeType = PCCompositeType
SchurFactType = PCFieldSplitSchurFactType
SchurPreType = PCFieldSplitSchurPreType
PatchConstructType = PCPatchConstructType

# --- xxx ---

Expand Down Expand Up @@ -644,6 +652,70 @@ cdef class PC(Object):
for i from 0 <= i < n: cisfields[i] = (<IS?>isfields[i]).iset
CHKERR( PCBDDCSetDofsSplittingLocal(self.pc, <PetscInt>n, cisfields) )

# --- Patch ---
def setPatchCellNumbering(self, Section sec not None):
CHKERR( PCPatchSetCellNumbering(self.pc, sec.sec) )

def setPatchDiscretisationInfo(self, dms, bs,
cellNodeMaps,
subspaceOffsets,
ghostBcNodes,
globalBcNodes):
cdef PetscInt numSubSpaces
cdef PetscInt numGhostBcs, numGlobalBcs
cdef PetscInt *nodesPerCell = NULL
cdef const_PetscInt **ccellNodeMaps = NULL
cdef PetscDM *cdms = NULL
cdef PetscInt *cbs = NULL
cdef PetscInt *csubspaceOffsets = NULL
cdef PetscInt *cghostBcNodes = NULL
cdef PetscInt *cglobalBcNodes = NULL
cdef PetscInt i

bs = iarray_i(bs, &numSubSpaces, &cbs)
ghostBcNodes = iarray_i(ghostBcNodes, &numGhostBcs, &cghostBcNodes)
globalBcNodes = iarray_i(globalBcNodes, &numGlobalBcs, &cglobalBcNodes)
subspaceOffsets = iarray_i(subspaceOffsets, NULL, &csubspaceOffsets)

CHKERR( PetscMalloc(<size_t>numSubSpaces*sizeof(PetscInt), &nodesPerCell) )
CHKERR( PetscMalloc(<size_t>numSubSpaces*sizeof(PetscDM), &cdms) )
CHKERR( PetscMalloc(<size_t>numSubSpaces*sizeof(PetscInt*), &ccellNodeMaps) )
for i in range(numSubSpaces):
cdms[i] = (<DM?>dms[i]).dm
_, nodes = asarray(cellNodeMaps[i]).shape
cellNodeMaps[i] = iarray_i(cellNodeMaps[i], NULL, <PetscInt**>&(ccellNodeMaps[i]))
nodesPerCell[i] = asInt(nodes)

# TODO: refactor on the PETSc side to take ISes?
CHKERR( PCPatchSetDiscretisationInfo(self.pc, numSubSpaces,
cdms, cbs, nodesPerCell,
ccellNodeMaps, csubspaceOffsets,
numGhostBcs, cghostBcNodes,
numGlobalBcs, cglobalBcNodes) )
CHKERR( PetscFree(nodesPerCell) )
CHKERR( PetscFree(cdms) )
CHKERR( PetscFree(ccellNodeMaps) )

def setPatchComputeOperator(self, operator, args=None, kargs=None):
if args is None: args = ()
if kargs is None: kargs = {}
context = (operator, args, kargs)
self.set_attr("__patch_compute_operator__", context)
CHKERR( PCPatchSetComputeOperator(self.pc, PCPatch_ComputeOperator, <void*>context) )

def setPatchConstructType(self, typ, operator=None, args=None, kargs=None):
if args is None: args = ()
if kargs is None: kargs = {}

if typ in {PC.PatchConstructType.PYTHON, PC.PatchConstructType.USER} and operator is None:
raise ValueError("Must provide operator for USER or PYTHON type")
if operator is not None:
context = (operator, args, kargs)
else:
context = None
self.set_attr("__patch_construction_operator__", context)
CHKERR( PCPatchSetConstructType(self.pc, typ, PCPatch_UserConstructOperator, <void*>context) )

# --------------------------------------------------------------------

del PCType
Expand All @@ -656,5 +728,6 @@ del PCGAMGType
del PCCompositeType
del PCFieldSplitSchurPreType
del PCFieldSplitSchurFactType
del PCPatchConstructType

# --------------------------------------------------------------------
73 changes: 73 additions & 0 deletions src/PETSc/petscpc.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ cdef extern from * nogil:
PetscPCType PCKACZMARZ
PetscPCType PCTELESCOPE
PetscPCType PCLMVM
PetscPCType PCPATCH

ctypedef enum PetscPCSide "PCSide":
PC_SIDE_DEFAULT
Expand Down Expand Up @@ -100,6 +101,12 @@ cdef extern from * nogil:
PC_FIELDSPLIT_SCHUR_FACT_UPPER
PC_FIELDSPLIT_SCHUR_FACT_FULL

ctypedef enum PetscPCPatchConstructType "PCPatchConstructType":
PC_PATCH_STAR
PC_PATCH_VANKA
PC_PATCH_USER
PC_PATCH_PYTHON

int PCCreate(MPI_Comm,PetscPC*)
int PCDestroy(PetscPC*)
int PCView(PetscPC,PetscViewer)
Expand Down Expand Up @@ -233,6 +240,24 @@ cdef extern from * nogil:
int PCBDDCSetDofsSplitting(PetscPC,PetscInt,PetscIS[])
int PCBDDCSetDofsSplittingLocal(PetscPC,PetscInt,PetscIS[])

# --- Patch ---
ctypedef int (*PetscPCPatchComputeOperator)(PetscPC,
PetscInt,
PetscMat,
PetscIS,
PetscInt,
const_PetscInt*,
void*) except PETSC_ERR_PYTHON
ctypedef int (*PetscPCPatchConstructOperator)(PetscPC,
PetscInt*,
PetscIS**,
PetscIS*,
void*) except PETSC_ERR_PYTHON
int PCPatchSetCellNumbering(PetscPC, PetscSection)
int PCPatchSetDiscretisationInfo(PetscPC, PetscInt, PetscDM*, PetscInt*, PetscInt*, const_PetscInt**, const_PetscInt*, PetscInt, const_PetscInt*, PetscInt, const_PetscInt*)
int PCPatchSetComputeOperator(PetscPC, PetscPCPatchComputeOperator, void*)
int PCPatchSetConstructType(PetscPC, PetscPCPatchConstructType, PetscPCPatchConstructOperator, void*)

# --------------------------------------------------------------------

cdef extern from "libpetsc4py.h":
Expand All @@ -242,3 +267,51 @@ cdef extern from "libpetsc4py.h":
int PCPythonSetType(PetscPC,char[])

# --------------------------------------------------------------------

cdef inline PC ref_PC(PetscPC pc):
cdef PC ob = <PC> PC()
ob.pc = pc
PetscINCREF(ob.obj)
return ob

cdef int PCPatch_ComputeOperator(
PetscPC pc,
PetscInt point,
PetscMat mat,
PetscIS cells,
PetscInt ndof,
const_PetscInt *dofmap,
void *ctx) except PETSC_ERR_PYTHON with gil:
cdef Mat Mat = ref_Mat(mat)
cdef PC Pc = ref_PC(pc)
cdef IS Is = ref_IS(cells)
cdef object context = Pc.get_attr("__patch_compute_operator__")
if context is None and ctx != NULL: context = <object>ctx
assert context is not None and type(context) is tuple
(op, args, kargs) = context
pydofs = asarray(<PetscInt[:ndof]>dofmap)
op(Pc, toInt(point), Mat, Is, pydofs, *args, **kargs)
return 0


cdef int PCPatch_UserConstructOperator(
PetscPC pc,
PetscInt *n,
PetscIS **userIS,
PetscIS *userIterationSet,
void *ctx) except PETSC_ERR_PYTHON with gil:
cdef PC Pc = ref_PC(pc)
cdef PetscInt i
cdef object context = Pc.get_attr("__patch_construction_operator__")
if context is None and ctx != NULL: context = <object>ctx
assert context is not None and type(context) is tuple
(op, args, kargs) = context
(patches, iterationSet) = op(Pc, *args, **kargs)
n[0] = len(patches)
CHKERR(PetscMalloc(<size_t>n[0]*sizeof(PetscIS), userIS))
for i in range(n[0]):
userIS[0][i] = (<IS?>patches[i]).iset
PetscINCREF(<PetscObject*>&(userIS[0][i]))
userIterationSet[0] = (<IS?>iterationSet).iset
PetscINCREF(<PetscObject*>&(userIterationSet[0]))
return 0

0 comments on commit 6040602

Please sign in to comment.