예제 #1
0
    def ncface_values(self, ifaces=None, irs=None, gtypes=None, **kwargs):

        if not self.isDerived: self.set_funcs()
        ndim = self.gfr.FESpace().GetMesh().Dimension()

        d = mfem.DenseMatrix()
        p = mfem.DenseMatrix()
        data = []

        def get_method(gf, ndim):
            if gf is None: return None
            if ndim == 3:
                return gf.GetFaceVectorValues
            elif ndim == 2:
                return gf.GetVectorValues
            else:
                assert False, "ndim = 1 has no face"

        getvalr = get_method(self.gfr, ndim)
        getvali = get_method(self.gfi, ndim)

        for i, gtype, in zip(ifaces, gtypes):
            ir = irs[gtype]
            getvalr(i, 2, ir, d, p)  # side = 2 (automatic?)
            v = d.GetDataArray().copy()

            if getvali is not None:
                getvali(i, 2, ir, d, p)
                vi = d.GetDataArray().copy()
                v = v + 1j * vi
            data.append(v)
        ret = np.hstack(data).transpose()
        return ret
예제 #2
0
def run_test():
    m = mfem.DenseMatrix(3, 3)
    m.Assign(np.arange(9.).reshape(3, 3))
    m.Print()
    print(np.arange(9.).reshape(3, 3))

    x = np.zeros(5) + 1
    y = np.zeros(5) + 2
    z = np.zeros(5) + 3
    mm = mfem.DenseMatrix(3, 5)
    mm.Assign(np.vstack([x, y, z]))
    mm.Print()
    mfem.Vector(mm.GetData(), 15).Print()
예제 #3
0
 def __init__(self, lambda_, mu_, si=0, sj=0):
     super(StressCoefficient, self).__init__(0)
     self.lam = lambda_   # coefficient
     self.mu  = mu_       # coefficient
     self.si  = si ; self.sj = sj     # component
     self.u  = None   # displacement GridFunction
     self.grad = mfem.DenseMatrix()
예제 #4
0
 def get_vshape(fes, k1, idx):
     tr1 = fes.GetBdrElementTransformation(k1)
     el = fes.GetBE(k1)
     nodes1 = el.GetNodes()
     m = mfem.DenseMatrix(nodes1.GetNPoints(), tr1.GetSpaceDim())
     tr1.SetIntPoint(nodes1.IntPoint(idx))
     el.CalcVShape(tr1, m)
     return m.GetDataArray()[idx, :]
예제 #5
0
 def __init__(self, coeff, S, direction, ref_point, pml_width, order, inv):
     self.coeffs = coeff
     self.direction = direction
     self.ref_p = ref_point
     self.pml_width = pml_width
     self.S = S
     self.order = order
     self.inv = inv
     self.K = mfem.DenseMatrix(self.width, self.height)
     super(LinearPML, self).__init__(coeff)
예제 #6
0
 def get_vshape_all(fes, k1):
     tr1 = fes.GetBdrElementTransformation(k1)
     el = fes.GetBE(k1)
     nodes1 = el.GetNodes()
     m = mfem.DenseMatrix(nodes1.GetNPoints(), tr1.GetSpaceDim())
     shape = []
     for idx in range(nodes1.GetNPoints()):
         tr1.SetIntPoint(nodes1.IntPoint(idx))
         el.CalcVShape(tr1, m)
         shape.append(m.GetDataArray()[idx, :].copy())
     return np.stack(shape)
예제 #7
0
 def __init__(self, coeff, slice1, slice2):
     CC_Vector.__init__(self, coeff)
     self.K = mfem.DenseMatrix(coeff.width, coeff.height)
     self.slice1 = slice1
     self.slice2 = slice2
     if len(slice1) == 1 and len(slice2) > 1:
         self._vdim = len(slice2)
     elif len(slice2) == 1 and len(slice1) > 1:
         self._vdim = len(slice1)
     else:
         assert False, "SliceVector output should be a vector" + \
             str(slice1) + "/" + str(slice2)
예제 #8
0
파일: pmesh.py 프로젝트: tomstitt/PyMFEM
    def FindPoints(self, pp, warn=True, inv_trans=None):
        r"""count, element_id, integration_points = FindPoints(points, warn=True, int_trans=None)"""
        import numpy as np
        import mfem.par as mfem

        pp = np.array(pp, copy=False, dtype=float).transpose()
        M = mfem.DenseMatrix(pp.shape[0], pp.shape[1])
        M.Assign(pp)
        elem_ids = mfem.intArray()
        int_points = mfem.IntegrationPointArray()
        count = _mesh.Mesh_FindPoints(self, M, elem_ids, int_points, warn,
                                      inv_trans)
        elem_ids = elem_ids.ToList()
        return count, elem_ids, int_points
예제 #9
0
def get_vshape(fes, ibdr, mode='Bdr'):
    mesh = fes.GetMesh()

    GetTrans = getattr(fes, methods[mode]['Transformation'])
    GetElement = getattr(fes, methods[mode]['Element'])
    GetVDofs = getattr(fes, methods[mode]['VDofs'])
    GetVDofTrans = getattr(fes, methods[mode]['VDofTransformation'])

    ret = [None]*len(ibdr)
    if len(ibdr) == 0:
        return ret

    # this is to make sure that IntegraitonPoint in Eltrans is
    # set once...
    tr1 = GetTrans(0)
    el = GetElement(0)
    nodes1 = el.GetNodes()
    doftrans = GetVDofTrans(0)
    tr1.SetIntPoint(nodes1.IntPoint(0))

    v0 = mfem.Vector(tr1.GetSpaceDim())

    use_weight = True
    for iii, k1 in enumerate(ibdr):
        tr1 = GetTrans(k1)
        el = GetElement(k1)
        nodes1 = el.GetNodes()
        doftrans = GetVDofTrans(k1)

        m = mfem.DenseMatrix(nodes1.GetNPoints(),
                             tr1.GetSpaceDim())
        shape = [None]*nodes1.GetNPoints()

        vv = mfem.Vector(nodes1.GetNPoints())

        for idx in range(len(shape)):
            tr1.SetIntPoint(nodes1.IntPoint(idx))
            el.CalcVShape(tr1, m)

            if doftrans is not None:
                vv.Assign(0.0)
                vv[idx] = 1
                doftrans.InvTransformPrimal(vv)
                m.MultTranspose(vv, v0)
                shape[idx] = v0.GetDataArray().copy()
            else:
                shape[idx] = m.GetDataArray()[idx, :].copy()
        ret[iii] = shape
    return ret
예제 #10
0
def do_findpoints(mesh, *args):
    sdim = mesh.SpaceDimension()
    
    shape = args[0].shape
    size= len(args[0].flatten())
    ptx = np.vstack([t.flatten() for t in args]).transpose().flatten()
    
    ptx2 = mfem.Vector(ptx)
    point_mat = mfem.DenseMatrix(ptx2.GetData(), size, sdim)
    elem_id = mfem.intArray()
    ips = mfem.IntegrationPointArray()
        
    num_found = mesh.FindPoints(point_mat, elem_id, ips, True)
    elem_id = np.array(elem_id.ToList())
    return v, elem_id, ips
예제 #11
0
def get_vshape(fes, ibdr, mode='Bdr'):
    mesh = fes.GetMesh()

    GetTrans = getattr(fes, methods[mode]['Transformation'])
    GetElement = getattr(fes, methods[mode]['Element'])
    GetVDofs = getattr(fes, methods[mode]['VDofs'])

    ret = [None] * len(ibdr)
    for iii, k1 in enumerate(ibdr):
        tr1 = GetTrans(k1)
        el = GetElement(k1)
        nodes1 = el.GetNodes()
        m = mfem.DenseMatrix(nodes1.GetNPoints(), tr1.GetSpaceDim())
        shape = [None] * nodes1.GetNPoints()
        for idx in range(len(shape)):
            tr1.SetIntPoint(nodes1.IntPoint(idx))
            el.CalcVShape(tr1, m)
            shape[idx] = m.GetDataArray()[idx, :].copy()
        ret[iii] = shape
    return ret
예제 #12
0
 def __init__(self, coeff, slice1, slice2):
     CC_Scalar.__init__(self, coeff)
     self.K = mfem.DenseMatrix(coeff.width, coeff.height)
     self.slice1 = slice1
     self.slice2 = slice2
예제 #13
0
    def ncface_values(self, ifaces=None, irs=None, gtypes=None, **kwargs):
        if not self.isDerived: self.set_funcs()

        name = self.gfr.FESpace().FEColl().Name()
        ndim = self.gfr.FESpace().GetMesh().Dimension()

        isVector = False
        if (name.startswith('RT') or name.startswith('ND')):
            d = mfem.DenseMatrix()
            p = mfem.DenseMatrix()
            isVector = True
        else:
            d = mfem.Vector()
            p = mfem.DenseMatrix()
        data = []

        def get_method(gf, ndim, isVector):
            if gf is None: return None
            if ndim == 3:
                if isVector:
                    return gf.GetFaceVectorValues
                elif gf.VectorDim() > 1:

                    def func(i, side, ir, vals, tr, in_gf=gf):
                        in_gf.GetFaceValues(i,
                                            side,
                                            ir,
                                            vals,
                                            tr,
                                            vdim=self.comp)

                    return func
                else:
                    return gf.GetFaceValues
            elif ndim == 2:
                if isVector:

                    def func(i, side, ir, vals, tr, in_gf=gf):
                        in_gf.GetVectorValues(i, ir, vals, tr)

                    return func
                elif gf.VectorDim() > 1:

                    def func(i, side, ir, vals, tr, in_gf=gf):
                        in_gf.GetValues(i, ir, vals, tr, vdim=self.comp - 1)

                    return func
                else:

                    def func(i, side, ir, vals, tr, in_gf=gf):
                        in_gf.GetValues(i, ir, vals, tr)
                        return

                    return func
            else:
                assert False, "ndim = 1 has no face"
            return None

        getvalr = get_method(self.gfr, ndim, isVector)
        getvali = get_method(self.gfi, ndim, isVector)

        for i, gtype, in zip(ifaces, gtypes):
            ir = irs[gtype]
            getvalr(i, 2, ir, d, p)  # side = 2 (automatic?)
            v = d.GetDataArray().copy()
            if isVector: v = v[self.comp - 1, :]

            if getvali is not None:
                getvali(i, 2, ir, d, p)  # side = 2 (automatic?)
                vi = d.GetDataArray().copy()
                if isVector: vi = vi[self.comp - 1, :]
                v = v + 1j * vi
            data.append(v)
        data = np.hstack(data)
        return data
예제 #14
0
 def __init__(self, model, x):
     self.x = x
     self.model = model
     self.J = mfem.DenseMatrix()
     mfem.PyCoefficient.__init__(self)
예제 #15
0
    def preprocess_geometry(self, battrs, emesh_idx=0, decimate=1):
        # we will ignore deciamte for a moment

        mesh = self.mesh()[emesh_idx]
        self.battrs = battrs
        self.knowns = WKD()
        self.iverts = []
        self.ifaces = []

        if mesh.Dimension() == 3:

            def f1(ibele):
                iface, o = mesh.GetBdrElementFace(ibele)
                e1 = mesh.GetFaceElementTransformations(iface).Elem1No
                return mesh.GetAttribute(e1)

            def f2(ibele):
                iface, o = mesh.GetBdrElementFace(ibele)
                e2 = mesh.GetFaceElementTransformations(iface).Elem2No
                if e2 >= 0:
                    return mesh.GetAttribute(e2)
                else:
                    return -1

            getface = mesh.GetBdrElementFace
            gettrans = mesh.GetBdrElementTransformation
            getarray = mesh.GetBdrArray
            getelement = mesh.GetBdrElement
            getbasegeom = mesh.GetBdrElementBaseGeometry
            getvertices = mesh.GetBdrElementVertices
            getattr1 = f1
            getattr2 = f2

        elif mesh.Dimension() == 2:

            def getface(x):
                return (x, 1)

            gettrans = mesh.GetElementTransformation
            getarray = mesh.GetDomainArray
            getelement = mesh.GetElement
            getbasegeom = mesh.GetElementBaseGeometry
            getvertices = mesh.GetElementVertices
            getattr1 = mesh.GetAttribute

            def getattr2(x):
                return -1
        else:
            assert False, "NCFace Evaluator is not supported for this dimension"

        x = [getarray(battr) for battr in battrs]
        if np.sum([len(xx) for xx in x]) == 0:
            return

        ibdrs = np.hstack(x).astype(int).flatten()
        self.ibeles = np.array(ibdrs)

        ptx = []
        data = []
        ridx = []
        ifaces = []
        self.gtypes = np.zeros(len(self.ibeles), dtype=int)
        self.elattr1 = np.zeros(len(self.ibeles), dtype=int)
        self.elattr2 = np.zeros(len(self.ibeles), dtype=int)

        self.irs = {}

        gtype_st = -1
        nele = 0

        p = mfem.DenseMatrix()

        for k, i in enumerate(self.ibeles):
            verts = getvertices(i)
            gtype = getbasegeom(i)
            iface, ort = getface(i)
            #Trs = mesh.GetFaceElementTransformations(iface)

            if gtype != gtype_st:
                RefG = GR.Refine(gtype, self.refine)
                ir = RefG.RefPts
                npt = ir.GetNPoints()
                ele0 = np.array(RefG.RefGeoms.ToList()).reshape(-1, len(verts))
                gtype_st = gtype
                self.irs[gtype] = ir

                # we handle quad as two triangles to handle mixed element case
                ele = []
                for eee in ele0:
                    if len(eee) == 3:
                        ele.append(eee)
                    elif len(eee) == 4:
                        x = eee[:-1]
                        y = np.array([eee[0], eee[2], eee[3]])
                        ele.extend([x, y])
                ele = np.array(ele)

            if mesh.Dimension() == 3:
                eir = mfem.IntegrationRule(ir.GetNPoints())
                fi = mesh.GetBdrFace(i)
                Transf = mesh.GetFaceElementTransformations(fi)
                Transf.Loc1.Transform(ir, eir)
                Transf.Elem1.Transform(eir, p)
                pt = p.GetDataArray().copy().transpose()
            elif mesh.Dimension() == 2:
                T = gettrans(i)
                T.Transform(ir, p)
                pt = p.GetDataArray().copy().transpose()
                #pt = np.vstack([T.Transform(ir.IntPoint(j)) for j in range(npt)])

            ptx.append(pt)

            ridx.append(ele + nele)
            nele = nele + ir.GetNPoints()
            ifaces.append(iface)
            self.gtypes[k] = gtype

            self.elattr1[k] = getattr1(i)
            self.elattr2[k] = getattr2(i)

        self.ptx = np.vstack(ptx)
        self.ridx = np.vstack(ridx)
        self.ifaces = np.hstack(ifaces)

        self.emesh_idx = emesh_idx
예제 #16
0
def hcurln(fes1,
           fes2,
           coeff,
           is_complex=False,
           bdr='all',
           orderinc=1,
           verbose=False):

    mat, rstart = get_empty_map(fes2, fes1, is_complex=is_complex)
    mat2, rstart = get_empty_map(fes2, fes1, is_complex=is_complex)

    from petram.helper.element_map import map_element

    name_fes1 = fes1.FEColl().Name()[:2]
    name_fes2 = fes2.FEColl().Name()[:2]

    if verbose:
        if myid == 0:
            dprint1("fes", name_fes1, name_fes2)

    mesh1 = fes1.GetMesh()
    mesh2 = fes2.GetMesh()

    mesh2.Print("/home/shiraiwa/part.mesh")

    if verbose:
        if myid == 0:
            dprint1("NE", mesh1.GetNE(), mesh2.GetNE())
    elmap, elmap_r = map_element(mesh1, mesh2, bdr, map_bdr=True)

    sdim1 = mesh1.SpaceDimension()
    sdim2 = mesh1.SpaceDimension()
    dim1 = mesh1.Dimension()
    dim2 = mesh2.Dimension()

    shape1 = mfem.DenseMatrix()
    shape2 = mfem.Vector()
    ip = mfem.IntegrationPoint()
    nor = mfem.Vector(sdim1)

    if USE_PARALLEL:
        # this is global TrueDoF (offset is not subtracted)
        P = fes1.Dof_TrueDof_Matrix()
        P1mat = ToScipyCoo(P).tocsr()
        #VDoFtoGTDoF1 = P.indices
        #P = fes2.Dof_TrueDof_Matrix()
        #P = ToScipyCoo(P).tocsr()
        #VDoFtoGTDoF2 = P.indices
        #P2mat = P

    vdofs1_senddata = []

    shared_data = []

    el2_2_node = {}
    el2_2_el1 = {}

    for d in elmap_r:
        for x in list(elmap_r[d]):
            el2_2_node[x] = d
        for x in list(elmap_r[d]):
            el2_2_el1[x] = elmap_r[d][x]

    # working for fes2
    # find boundary element on mesh1 using mesh2 boundary
    el2_arr = [list() for x in range(nprc)]
    el1_arr = [list() for x in range(nprc)]
    fe2o_arr = [list() for x in range(nprc)]
    for i_el in range(fes2.GetNE()):
        attr = fes2.GetAttribute(i_el)
        if bdr != 'all' and not attr in bdr:
            continue
        el1_arr[el2_2_node[i_el]].append(el2_2_el1[i_el])
        el2_arr[el2_2_node[i_el]].append(i_el)
        fe2 = fes2.GetFE(i_el)
        fe2o_arr[el2_2_node[i_el]].append(fe2.GetOrder())

    if USE_PARALLEL:
        el1_arr = alltoall_vector(el1_arr, int)  # transfer to mesh1 owners

    # working for fes1
    # find elemet order on mesh1
    fe1o_arr = [list() for x in range(nprc)]
    i_fe1_arr = [list() for x in range(nprc)]
    rank = 0
    for rank, i_bdrs in enumerate(el1_arr):
        for i_bdr in i_bdrs:
            iface = mesh1.GetBdrElementEdgeIndex(i_bdr)
            transs = mesh1.GetFaceElementTransformations(iface)
            i_el1 = transs.Elem1No
            assert transs.Elem2No == -1, "boundary must be exterior for this operator"
            fe1 = fes1.GetFE(i_el1)
            fe1o_arr[rank].append(fe1.GetOrder())
            i_fe1_arr[rank].append(i_el1)
        rank = rank + 1

    if USE_PARALLEL:
        fe1o_arr = alltoall_vector(fe1o_arr, int)  # transfer to mesh2

    # working for fes2
    locnor_arr = [list() for x in range(nprc)]
    data2_arr = [list() for x in range(nprc)]
    verbose1 = verbose
    for rank, i_el2s in enumerate(el2_arr):
        for i_el2, fe1o in zip(i_el2s, fe1o_arr[rank]):
            eltrans = fes2.GetElementTransformation(i_el2)
            fe2 = fes2.GetFE(i_el2)
            nd2 = fe2.GetDof()
            ir = get_rule(fe1o,
                          fe2,
                          eltrans,
                          orderinc=orderinc,
                          verbose=verbose1)
            verbose1 = False
            shape2.SetSize(nd2)
            data2 = []
            locnors = []
            for jj in range(ir.GetNPoints()):
                ip1 = ir.IntPoint(jj)
                eltrans.SetIntPoint(ip1)
                w = eltrans.Weight() * ip1.weight
                mfem.CalcOrtho(eltrans.Jacobian(), nor)
                nor2 = nor.GetDataArray() / np.linalg.norm(nor.GetDataArray())
                fe2.CalcShape(ip1, shape2)

                if dim2 == 1:
                    d = np.array([ip1.x] + list(eltrans.Transform(ip1)) +
                                 list(nor2))
                    locnors.append(d)
                elif dim2 == 2:
                    d = np.array([ip1.x, ip1.y] +
                                 list(eltrans.Transform(ip1)) + list(nor2))

                    locnors.append(d)
                else:
                    assert False, "boundary mesh must be dim=1 or 2"
                data2.append(w * shape2.GetDataArray().copy())

            #   np.vstack(locnors).shape = (#Npoints, dim2+sdim2*2)
            #   np.vstack(data2).shape = (#Npoints, #NDoF2)
            #print("size here", np.vstack(locnors).shape, np.vstack(data2).shape)

            locnor_arr[rank].append(np.vstack(locnors))
            data2_arr[rank].append(np.vstack(data2))

    if USE_PARALLEL:
        locnor_arr = alltoall_vectorv(locnor_arr, float)  # transfer to mesh1

    ll = dim2 + 2 * sdim2

    vdofs1_arr = [list() for x in range(nprc)]
    data1_arr = [list() for x in range(nprc)]

    # space to compute the coefficient
    MV = [mfem.Vector(sdim1), mfem.DenseMatrix(sdim1, sdim1)]

    max_misalignment = -np.inf
    for rank, i_fe1s in enumerate(i_fe1_arr):
        locnorss = locnor_arr[rank]

        sign_dict = {}

        for k, i_fe1 in enumerate(i_fe1s):
            fe1 = fes1.GetFE(i_fe1)
            nd1 = fe1.GetDof()
            eltrans = fes1.GetElementTransformation(i_fe1)
            doftrans = fes1.GetElementDofTransformation(i_fe1)
            #ctr = eval_element_center(fe1, eltrans)

            locnors2 = locnorss[k]
            shape1.SetSize(nd1, sdim1)
            vdofs1 = fes1.GetElementVDofs(i_fe1)

            dof_sign1 = np.array([
                [1 if vv >= 0 else -1 for vv in vdofs1],
            ])
            vdofs1 = [-1 - x if x < 0 else x for x in vdofs1]

            mat_doftrans = get_inv_doftrans(doftrans, dof_sign1)

            if USE_PARALLEL:
                #  After DofTransformation is introduced we can not use GetGlobalTDofNumber, because
                #  element local DoF could be linked with two TrueDoFs in neighber processes
                #  We construct submatrix of Prolongation to construct element matrix
                #  in TrueDof space

                vv1 = [
                    P1mat.indices[P1mat.indptr[ii]:P1mat.indptr[ii + 1]]
                    for ii in vdofs1
                ]
                vv3 = [
                    P1mat.data[P1mat.indptr[ii]:P1mat.indptr[ii + 1]]
                    for ii in vdofs1
                ]
                ngtof = np.sum([len(x) for x in vv3])
                sub_p = np.zeros((nd1, ngtof))
                k1 = 0
                k2 = 0
                for gtofs, weights in zip(vv1, vv3):
                    for g, w in zip(gtofs, weights):
                        sub_p[k1, k2] = w
                        k2 = k2 + 1
                    k1 = k1 + 1

                vdofs1 = np.hstack(vv1).flatten()
                mat_doftrans = mat_doftrans.dot(sub_p)

            res, misalignment = map_ir(fe1, eltrans, coeff, shape1, dim2,
                                       sdim2, locnors2, dof_sign1,
                                       mat_doftrans, MV)

            vdofs1_arr[rank].append(np.array(vdofs1))
            data1_arr[rank].append(res)

            max_misalignment = np.max([max_misalignment, np.max(misalignment)])
            # res.shape = (#Npoints, #DoF1)

    if USE_PARALLEL:
        vdofs1_arr = alltoall_vectorv(vdofs1_arr, int)  # transfer to mesh2
        if is_complex:
            data1_arr = alltoall_vectorv(data1_arr,
                                         complex)  # transfer to mesh2
        else:
            data1_arr = alltoall_vectorv(data1_arr, float)  # transfer to mesh2
        max_misalignment = np.max(
            MPI.COMM_WORLD.gather(max_misalignment, root=0))
    dprint1("Max misalignment: ", max_misalignment)

    shared_data = []

    for rank, i_el2s in enumerate(el2_arr):
        for k, i_el2 in enumerate(i_el2s):
            vdofs1 = vdofs1_arr[rank][k]

            fe2 = fes2.GetFE(i_el2)
            eltrans2 = fes2.GetElementTransformation(i_el2)
            vdofs2 = fes2.GetElementVDofs(i_el2)
            vdofs2 = [-1 - x if x < 0 else x for x in vdofs2]

            d1 = data1_arr[rank][k]
            d2 = data2_arr[rank][k]

            mm = d2.transpose().dot(d1)

            if USE_PARALLEL:
                # prepare data for not-owned DoFs, which will be shared later
                vdofs22 = [fes2.GetLocalTDofNumber(ii) for ii in vdofs2]
                vdofs22g = [fes2.GetGlobalTDofNumber(ii) for ii in vdofs2]

                kkk = 0
                for v2, v2g in zip(vdofs22, vdofs22g):
                    if v2 < 0:
                        shared_data.append([v2g, mm[kkk, :], vdofs1])
                    kkk = kkk + 1
            else:
                vdofs22 = vdofs2

            for i, ltdof2 in enumerate(vdofs22):
                if ltdof2 < 0:
                    continue
                for j, gtdof1 in enumerate(vdofs1):
                    mat[ltdof2, gtdof1] = mat[ltdof2, gtdof1] + mm[i, j]

    if USE_PARALLEL:
        #nicePrint("shared data", shared_data)
        for source_id in range(nprc):
            data = comm.bcast(shared_data, root=source_id)
            myoffset = fes2.GetMyTDofOffset()
            for v2g, elmat, vdofs1 in data:
                if v2g >= myoffset and v2g < myoffset + mat.shape[0]:
                    i = v2g - myoffset
                    for j, gtdof1 in enumerate(vdofs1):
                        mat[i, gtdof1] = mat[i, gtdof1] + elmat[j]
                    #mat[i, vdofs1] = mat[i, vdofs1] + elmat

    from scipy.sparse import coo_matrix, csr_matrix

    if USE_PARALLEL:
        if is_complex:
            m1 = csr_matrix(mat.real, dtype=float)
            m2 = csr_matrix(mat.imag, dtype=float)
        else:
            m1 = csr_matrix(mat.real, dtype=float)
            m2 = None
        from mfem.common.chypre import CHypreMat

        start_col = fes1.GetMyTDofOffset()
        end_col = fes1.GetMyTDofOffset() + fes1.GetTrueVSize()
        col_starts = [start_col, end_col, mat.shape[1]]
        M = CHypreMat(m1, m2, col_starts=col_starts)
    else:
        from petram.helper.block_matrix import convert_to_ScipyCoo
        M = convert_to_ScipyCoo(coo_matrix(mat, dtype=mat.dtype))

    return M
예제 #17
0
def convolve2d(fes1,
               fes2,
               kernel=delta,
               support=None,
               orderinc=5,
               is_complex=False,
               trial_domain='all',
               test_domain='all',
               verbose=False,
               coeff=None):
    '''
    fill linear operator for convolution
    \int phi_test(x) func(x-x') phi_trial(x') dx
    
    Genralized version to multi-dim
    test/trial
        ScalarFE, ScalarFE   : func is scalar
        VectorFE, ScalarFE   : func is vector (vertical)
        ScalarFE, VectorFE   : func is vector (horizontal)
        VectorFE, VectorFE   : func matrix
    '''
    mat, rstart = get_empty_map(fes2, fes1, is_complex=is_complex)

    if fes1.GetNE() == 0:
        assert False, "FESpace does not have element"
    eltrans1 = fes1.GetElementTransformation(0)
    ir = get_rule(fes1.GetFE(0), fes2.GetFE(0), eltrans1, orderinc, verbose)

    name_fes1 = fes1.FEColl().Name()[:2]
    name_fes2 = fes2.FEColl().Name()[:2]

    sdim = fes1.GetMesh().SpaceDimension()
    if name_fes1 in ['RT', 'ND']:
        shape1 = mfem.DenseMatrix()
        vdim1 = fes1.GetMesh().SpaceDimension()
    else:
        shape1 = mfem.Vector()
        vdim1 = 1
    if name_fes2 in ['RT', 'ND']:
        shape2 = mfem.DenseMatrix()
        vdim2 = fes1.GetMesh().SpaceDimension()
    else:
        shape2 = mfem.Vector()
        vdim1 = 1

    #nicePrint("shape", mat.shape, fes2.GetNE(), fes1.GetNE())

    # communication strategy
    #   (1) x2 (ir points on test space) is collected in each nodes
    #   (2) x2 is send to other nodes
    #   (3) each nodes compute \int f(x2-x1) phi(x1)
    #   (4) non-zero results of (3) and global index should be send back

    # Step (1, 2)
    if verbose:
        dprint1("Step 1,2")
    x2_arr = []
    i2_arr = []

    ptx = mfem.DenseMatrix(ir.GetNPoints(), sdim)

    attrs1 = fes2.GetMesh().GetAttributeArray()
    attrs2 = fes2.GetMesh().GetAttributeArray()

    for i in range(fes2.GetNE()):  # scan test space
        if test_domain != 'all':
            if not attrs1[i] in test_domain: continue
        eltrans = fes2.GetElementTransformation(i)
        eltrans.Transform(ir, ptx)
        x2_arr.append(ptx.GetDataArray().copy().transpose())
        i2_arr.append(i)

    if support is not None:
        supports = np.array([support(np.mean(xxx, 0)) for xxx in x2_arr])
    else:
        supports = -np.ones(len(x2_arr))

    if len(i2_arr) > 0:
        ptx_x2 = np.stack(x2_arr)
        i2_arr = np.hstack(i2_arr)
    else:
        ptx_x2 = np.array([[[]]])
        i2_arr = np.array([])

    #nicePrint("x2 shape", ptx_x2.shape)
    if USE_PARALLEL:
        ## note: we could implement more advanced alg. to reduce
        ## the amount of data exchange..
        x2_all = comm.allgather(ptx_x2)
        i2_all = comm.allgather(i2_arr)
        s_all = comm.allgather(supports)
    else:
        x2_all = [ptx_x2]
        i2_all = [i2_arr]
        s_all = [supports]
    #nicePrint("x2_all shape", supports.shape, len(x2_all), [tmp.shape for tmp in x2_all])

    if USE_PARALLEL:
        #this is global TrueDoF (offset is not subtracted)
        P = fes1.Dof_TrueDof_Matrix()
        P = ToScipyCoo(P).tocsr()
        VDoFtoGTDoF1 = P.indices
        P = fes2.Dof_TrueDof_Matrix()
        P = ToScipyCoo(P).tocsr()
        VDoFtoGTDoF2 = P.indices

    # Step 3
    if verbose:
        dprint1("Step 3")
    vdofs1_senddata = []
    elmats_senddata = []

    for knode1 in range(len(x2_all)):
        #dprint1("new knode1", myid, knode1)

        x2_onenode = x2_all[knode1]
        i2_onenode = i2_all[knode1]
        s_onenode = s_all[knode1]

        elmats_all = []
        vdofs1_all = []

        # collect vdofs
        for j in range(fes1.GetNE()):
            local_vdofs = fes1.GetElementVDofs(j)
            local_vdofs = [vv if vv >= 0 else -1 - vv for vv in local_vdofs]
            if USE_PARALLEL:
                subvdofs2 = [VDoFtoGTDoF1[i] for i in local_vdofs]
                vdofs1_all.append(subvdofs2)
            else:
                vdofs1_all.append(local_vdofs)

        #if myid == 0:
        #    pr = profile_start()

        for i, x2s, su in zip(i2_onenode, x2_onenode,
                              s_onenode):  # loop over fes2
            nd2 = len(x2s)
            #nicePrint("x2s", i, x2s.shape, x2s)
            elmats = []
            for j in range(fes1.GetNE()):

                if trial_domain != 'all':
                    if not attrs1[j] in trial_domain: continue

                # collect integration
                fe1 = fes1.GetFE(j)
                nd1 = fe1.GetDof()
                eltrans = fes1.GetElementTransformation(j)
                dof_sign1 = np.array(
                    [1 if vv >= 0 else -1 for vv in fes1.GetElementVDofs(j)])

                if name_fes1 in ['RT', 'ND']:
                    shape1.SetSize(nd1, vdim1)
                else:
                    shape1.SetSize(nd1)
                elmat = np.zeros((nd2, vdim2, nd1), dtype=mat.dtype)
                tmp_int = np.zeros((vdim2, nd1), dtype=mat.dtype).squeeze()

                #if myid == 0: print("fes1 idx", j)

                dataset = []
                shapes = []
                for jj in range(ir.GetNPoints()):
                    ip1 = ir.IntPoint(jj)
                    eltrans.SetIntPoint(ip1)
                    x1 = eltrans.Transform(ip1)
                    if name_fes1 in ['RT', 'ND']:
                        fe1.CalcVShape(eltrans, shape1)
                    else:
                        fe1.CalcShape(ip1, shape1)
                    w = eltrans.Weight() * ip1.weight
                    ss = shape1.GetDataArray().copy()

                    if len(ss.shape) > 1:
                        #dof_sign1 = dof_sign1.reshape(-1, 1)
                        ss = np.transpose(ss)
                    ss = ss * dof_sign1
                    dataset.append((x1, w, ss))

                has_contribution = False
                for kkk, x2 in enumerate(x2s):
                    tmp_int *= 0.0
                    has_contribution2 = False
                    for x1, w, shape_arr in dataset:
                        s = np.sqrt(np.sum((x1 - x2)**2))
                        if su >= 0 and s > su:
                            continue

                        val = kernel(x2 - x1, (x2 + x1) / 2.0, w=w)
                        if val is None:
                            continue
                        if coeff is not None:
                            val = val * coeff((x2 + x1) / 2.0)

                        tmp_int += np.dot(val, shape_arr) * w
                        has_contribution2 = True

                    if has_contribution2:
                        elmat[kkk, ...] = tmp_int
                        has_contribution = True
                if has_contribution:
                    elmats.append((j, elmat))

            #if myid == 0:
            #    pr.dump_stats("/home/shiraiwa/test.prf")
            #    profile_stop(pr)
            #    assert False, "hoge"
            #    pr = profile_start()
            if len(elmats) > 0:
                elmats_all.append((i, elmats))

        vdofs1_senddata.append(vdofs1_all)
        elmats_senddata.append(elmats_all)

        # send this information to knodes;
        '''
        if USE_PARALLEL:
            #nicePrint(vdofs1_all)
            #nicePrint("elmats", [len(x) for x in elmats_all])
            if myid == knode1:
                vdofs1_data = comm.gather(vdofs1_all, root=knode1)
                elmats_data = comm.gather(elmats_all, root=knode1)
            else:
                _ = comm.gather(vdofs1_all, root=knode1)
                _ = comm.gather(elmats_all, root=knode1)
        else:
            vdofs1_data = [vdofs1_all,]
            elmats_data = [elmats_all,]
        '''
    if USE_PARALLEL:
        knode1 = 0
        for vdofs1_all, elmats_all in zip(vdofs1_senddata, elmats_senddata):
            if myid == knode1:
                vdofs1_data = comm.gather(vdofs1_all, root=knode1)
                elmats_data = comm.gather(elmats_all, root=knode1)
            else:
                _ = comm.gather(vdofs1_all, root=knode1)
                _ = comm.gather(elmats_all, root=knode1)
            knode1 = knode1 + 1
    else:
        vdofs1_data = vdofs1_senddata
        elmats_data = elmats_senddata

    # Step 4
    if verbose:
        dprint1("Step 4")
    shared_data = []
    mpi_rank = 0
    for vdofs1, elmats_all in zip(vdofs1_data,
                                  elmats_data):  # loop over MPI nodes
        #nicePrint("len elmats", len(elmats_all))
        #for i, elmats in enumerate(elmats_all):  # corresponds to loop over fes2

        if verbose:
            coupling = [len(elmats) for i, elmats in elmats_all]
            nicePrint("Element coupling for rank/count", mpi_rank,
                      len(coupling))
            nicePrint("   Average :",
                      (0 if len(coupling) == 0 else np.mean(coupling)))
            nicePrint("   Max/Min :",
                      (0 if len(coupling) == 0 else np.max(coupling)),
                      (0 if len(coupling) == 0 else np.min(coupling)))
            mpi_rank += 1

        for i, elmats in elmats_all:  # corresponds to loop over fes2
            vdofs2 = fes2.GetElementVDofs(i)
            dof_sign2 = np.array([
                [1 if vv >= 0 else -1 for vv in vdofs2],
            ]).transpose()
            vdofs2 = [-1 - x if x < 0 else x for x in vdofs2]

            fe2 = fes2.GetFE(i)
            nd2 = fe2.GetDof()

            if name_fes2 in ['RT', 'ND']:
                shape2.SetSize(nd2, vdim2)
            else:
                shape2.SetSize(nd2)

            eltrans = fes2.GetElementTransformation(i)

            #for j, elmat in enumerate(elmats):
            for j, elmat in elmats:
                #print(vdofs1[j], elmat.shape)
                #if elmat is None:
                #    continue

                mm = np.zeros((len(vdofs2), len(vdofs1[j])), dtype=float)

                for ii in range(ir.GetNPoints()):
                    ip2 = ir.IntPoint(ii)
                    eltrans.SetIntPoint(ip2)
                    ww = eltrans.Weight() * ip2.weight

                    if name_fes2 in ['RT', 'ND']:
                        fe2.CalcVShape(eltrans, shape2)
                    else:
                        fe2.CalcShape(ip2, shape2)

                    shape2 *= ww
                    ss = shape2.GetDataArray().reshape(-1, vdim2)
                    ss = ss * dof_sign2

                    tmp_int = elmat[ii, ...].reshape(vdim1, -1)
                    tmp = np.dot(ss, tmp_int)
                    mm = mm + tmp

                # preapre shared data
                if USE_PARALLEL:
                    vdofs22 = [fes2.GetLocalTDofNumber(ii) for ii in vdofs2]
                    vdofs22g = [VDoFtoGTDoF2[ii] for ii in vdofs2]
                    kkk = 0
                    #for v2, v2g in zip(vdofs22, vdofs22g):
                    for v2, v2g in zip(vdofs22, vdofs22g):
                        if v2 < 0:
                            shared_data.append([v2g, mm[kkk, :], vdofs1[j]])
                        kkk = kkk + 1

                # merge contribution to final mat
                for k, vv in enumerate(vdofs1[j]):
                    try:
                        if USE_PARALLEL:
                            mmm = mm[np.where(np.array(vdofs22) >= 0)[0], :]
                            vdofs222 = [x for x in vdofs22 if x >= 0]
                        else:
                            vdofs222 = vdofs2
                            mmm = mm
                        #if myid == 1:
                        #    print("check here", vdofs2, vdofs22, vdofs222)
                        #print(mmm[:, [k]])
                        tmp = mat[vdofs222, vv] + mmm[:, [k]]
                        mat[vdofs222, vv] = tmp.flatten()

                    except:
                        import traceback
                        print("error", myid)
                        #print(vdofs1, vdofs22, vdofs222, mmm.shape, k)
                        traceback.print_exc()

    if USE_PARALLEL:
        for source_id in range(nprc):
            data = comm.bcast(shared_data, root=source_id)
            myoffset = fes2.GetMyTDofOffset()
            for v2g, elmat, vdofs1 in data:
                if v2g >= myoffset and v2g < myoffset + mat.shape[0]:
                    i = v2g - myoffset
                    #print("procesising this", myid, i, v2g, elmat, vdofs1)
                    mat[i, vdofs1] = mat[i, vdofs1] + elmat

    from scipy.sparse import coo_matrix, csr_matrix

    if USE_PARALLEL:
        if is_complex:
            m1 = csr_matrix(mat.real, dtype=float)
            m2 = csr_matrix(mat.imag, dtype=float)
        else:
            m1 = csr_matrix(mat.real, dtype=float)
            m2 = None
        from mfem.common.chypre import CHypreMat
        start_col = fes1.GetMyTDofOffset()
        end_col = fes1.GetMyTDofOffset() + fes1.GetTrueVSize()
        col_starts = [start_col, end_col, mat.shape[1]]
        M = CHypreMat(m1, m2, col_starts=col_starts)
    else:
        from petram.helper.block_matrix import convert_to_ScipyCoo

        M = convert_to_ScipyCoo(coo_matrix(mat, dtype=mat.dtype))

    return M
예제 #18
0
def convolve1d(fes1,
               fes2,
               kernel=delta,
               support=None,
               orderinc=5,
               is_complex=False,
               trial_domain='all',
               test_domain='all',
               verbose=False,
               coeff=None):
    '''
    fill linear operator for convolution
    \int phi_test(x) func(x-x') phi_trial(x') dx
    '''
    mat, rstart = get_empty_map(fes2, fes1, is_complex=is_complex)

    eltrans1 = fes1.GetElementTransformation(0)
    ir = get_rule(fes1.GetFE(0), fes2.GetFE(0), eltrans1, orderinc, verbose)

    shape1 = mfem.Vector()
    shape2 = mfem.Vector()

    #nicePrint("shape", mat.shape, fes2.GetNE(), fes1.GetNE())

    # communication strategy
    #   (1) x2 (ir points on test space) is collected in each nodes
    #   (2) x2 is send to other nodes
    #   (3) each nodes compute \int f(x2-x1) phi(x1)
    #   (4) non-zero results of (3) and global index should be send back

    # Step (1, 2)
    if verbose:
        dprint1("Step 1,2")
    x2_arr = []
    i2_arr = []

    ptx = mfem.DenseMatrix(ir.GetNPoints(), 1)

    attrs1 = fes2.GetMesh().GetAttributeArray()
    attrs2 = fes2.GetMesh().GetAttributeArray()

    for i in range(fes2.GetNE()):  # scan test space
        if test_domain != 'all':
            if not attrs1[i] in test_domain: continue
        eltrans = fes2.GetElementTransformation(i)
        eltrans.Transform(ir, ptx)
        x2_arr.append(ptx.GetDataArray().copy())
        i2_arr.append(i)
    if len(i2_arr) > 0:
        ptx_x2 = np.vstack(x2_arr)
        i2_arr = np.hstack(i2_arr)
    else:
        ptx_x2 = np.array([[]])
        i2_arr = np.array([])

    #nicePrint("x2 shape", ptx_x2.shape)
    if USE_PARALLEL:
        ## note: we could implement more advanced alg. to reduce
        ## the amount of data exchange..
        x2_all = comm.allgather(ptx_x2)
        i2_all = comm.allgather(i2_arr)
    else:
        x2_all = [ptx_x2]
        i2_all = [i2_arr]
    #nicePrint("x2_all shape", x2_all.shape)

    if USE_PARALLEL:
        #this is global TrueDoF (offset is not subtracted)
        P = fes1.Dof_TrueDof_Matrix()
        P = ToScipyCoo(P).tocsr()
        VDoFtoGTDoF1 = P.indices
        P = fes2.Dof_TrueDof_Matrix()
        P = ToScipyCoo(P).tocsr()
        VDoFtoGTDoF2 = P.indices

    # Step 3
    if verbose:
        dprint1("Step 3")
    vdofs1_senddata = []
    elmats_senddata = []

    for knode1 in range(len(x2_all)):
        x2_onenode = x2_all[knode1]
        i2_onenode = i2_all[knode1]
        elmats_all = []
        vdofs1_all = []

        # collect vdofs
        for j in range(fes1.GetNE()):
            local_vdofs = fes1.GetElementVDofs(j)
            if USE_PARALLEL:
                subvdofs2 = [VDoFtoGTDoF1[i] for i in local_vdofs]
                vdofs1_all.append(subvdofs2)
            else:
                vdofs1_all.append(local_vdofs)

        for i, x2s in zip(i2_onenode, x2_onenode):  # loop over fes2
            nd2 = len(x2s)
            #nicePrint(x2s)
            elmats = []
            for j in range(fes1.GetNE()):
                if trial_domain != 'all':
                    if not attrs1[j] in trial_domain: continue

                # collect integration
                fe1 = fes1.GetFE(j)
                nd1 = fe1.GetDof()
                shape1.SetSize(nd1)
                eltrans = fes1.GetElementTransformation(j)

                tmp_int = np.zeros(shape1.Size(), dtype=mat.dtype)
                elmat = np.zeros((nd2, nd1), dtype=mat.dtype)

                #if myid == 0: print("fes1 idx", j)

                dataset = []
                for jj in range(ir.GetNPoints()):
                    ip1 = ir.IntPoint(jj)
                    eltrans.SetIntPoint(ip1)
                    x1 = eltrans.Transform(ip1)[0]
                    fe1.CalcShape(ip1, shape1)
                    w = eltrans.Weight() * ip1.weight
                    dataset.append((x1, w, shape1.GetDataArray().copy()))

                has_contribution = False
                for kkk, x2 in enumerate(x2s):
                    tmp_int *= 0.0

                    for x1, w, shape_arr in dataset:
                        if support is not None:
                            s = support((x1 + x2) / 2.0)
                            if np.abs(x1 - x2) > s:
                                continue

                        has_contribution = True
                        #if myid == 0: print("check here", x1, x2)
                        val = kernel(x2 - x1, (x2 + x1) / 2.0, w=w)
                        if coeff is not None:
                            val = val * coeff((x2 + x1) / 2.0)

                        #shape_arr *= w*val
                        tmp_int += shape_arr * w * val
                    elmat[kkk, :] = tmp_int

                if has_contribution:
                    elmats.append((j, elmat))
                #print(elmats)
            if len(elmats) > 0:
                elmats_all.append((i, elmats))

        vdofs1_senddata.append(vdofs1_all)
        elmats_senddata.append(elmats_all)

        # send this information to knodes;
        '''
        if USE_PARALLEL:
            #nicePrint(vdofs1_all)
            #nicePrint("elmats", [len(x) for x in elmats_all])
            if myid == knode1:
                vdofs1_data = comm.gather(vdofs1_all, root=knode1)
                elmats_data = comm.gather(elmats_all, root=knode1)
            else:
                _ = comm.gather(vdofs1_all, root=knode1)
                _ = comm.gather(elmats_all, root=knode1)
        else:
            vdofs1_data = [vdofs1_all,]
            elmats_data = [elmats_all,]
        '''
    if USE_PARALLEL:
        knode1 = 0
        for vdofs1_all, elmats_all in zip(vdofs1_senddata, elmats_senddata):
            if myid == knode1:
                vdofs1_data = comm.gather(vdofs1_all, root=knode1)
                elmats_data = comm.gather(elmats_all, root=knode1)
            else:
                _ = comm.gather(vdofs1_all, root=knode1)
                _ = comm.gather(elmats_all, root=knode1)
            knode1 = knode1 + 1
    else:
        vdofs1_data = vdofs1_senddata
        elmats_data = elmats_senddata

    # Step 4
    if verbose:
        dprint1("Step 4")
    shared_data = []
    mpi_rank = 0
    for vdofs1, elmats_all in zip(vdofs1_data,
                                  elmats_data):  # loop over MPI nodes
        #nicePrint("len elmats", len(elmats_all))
        #for i, elmats in enumerate(elmats_all):  # corresponds to loop over fes2

        if verbose:
            coupling = [len(elmats) for i, elmats in elmats_all]
            nicePrint("Element coupling for rank", mpi_rank)
            nicePrint("   Average :",
                      (0 if len(coupling) == 0 else np.mean(coupling)))
            nicePrint("   Max/Min :",
                      (0 if len(coupling) == 0 else np.max(coupling)),
                      (0 if len(coupling) == 0 else np.min(coupling)))
            mpi_rank += 1

        for i, elmats in elmats_all:  # corresponds to loop over fes2
            vdofs2 = fes2.GetElementVDofs(i)
            fe2 = fes2.GetFE(i)
            nd2 = fe2.GetDof()
            shape2.SetSize(nd2)

            eltrans = fes2.GetElementTransformation(i)

            #for j, elmat in enumerate(elmats):
            for j, elmat in elmats:
                #print(vdofs1[j], elmat.shape)
                #if elmat is None:
                #    continue

                mm = np.zeros((len(vdofs2), len(vdofs1[j])), dtype=float)

                for ii in range(ir.GetNPoints()):
                    ip2 = ir.IntPoint(ii)
                    eltrans.SetIntPoint(ip2)
                    ww = eltrans.Weight() * ip2.weight
                    fe2.CalcShape(ip2, shape2)
                    shape2 *= ww

                    tmp_int = elmat[ii, :]
                    tmp = np.dot(
                        np.atleast_2d(shape2.GetDataArray()).transpose(),
                        np.atleast_2d(tmp_int))
                    mm = mm + tmp
                    #print("check here", myid, mm.shape, tmp.shape)

                # merge contribution to final mat
                if USE_PARALLEL:
                    vdofs22 = [fes2.GetLocalTDofNumber(ii) for ii in vdofs2]
                    vdofs22g = [VDoFtoGTDoF2[ii] for ii in vdofs2]
                    kkk = 0
                    for v2, v2g in zip(vdofs22, vdofs22g):
                        if v2 < 0:
                            shared_data.append([v2g, mm[kkk, :], vdofs1[j]])
                        kkk = kkk + 1

                for k, vv in enumerate(vdofs1[j]):
                    try:
                        if USE_PARALLEL:
                            mmm = mm[np.where(np.array(vdofs22) >= 0)[0], :]
                            vdofs222 = [x for x in vdofs22 if x >= 0]
                        else:
                            vdofs222 = vdofs2
                            mmm = mm
                        #if myid == 1:
                        #    print("check here", vdofs2, vdofs22, vdofs222)
                        #print(mmm[:, [k]])
                        tmp = mat[vdofs222, vv] + mmm[:, [k]]
                        mat[vdofs222, vv] = tmp.flatten()
                    except:
                        import traceback
                        print("error", myid)
                        #print(vdofs1, vdofs22, vdofs222, mmm.shape, k)
                        traceback.print_exc()

    if USE_PARALLEL:
        for source_id in range(nprc):
            data = comm.bcast(shared_data, root=source_id)
            myoffset = fes2.GetMyTDofOffset()
            for v2g, elmat, vdofs1 in data:
                if v2g >= myoffset and v2g < myoffset + mat.shape[0]:
                    i = v2g - myoffset
                    #print("procesising this", myid, i, v2g, elmat, vdofs1)
                    mat[i, vdofs1] = mat[i, vdofs1] + elmat

    from scipy.sparse import coo_matrix, csr_matrix

    if USE_PARALLEL:
        if is_complex:
            m1 = csr_matrix(mat.real, dtype=float)
            m2 = csr_matrix(mat.imag, dtype=float)
        else:
            m1 = csr_matrix(mat.real, dtype=float)
            m2 = None
        from mfem.common.chypre import CHypreMat
        start_col = fes1.GetMyTDofOffset()
        end_col = fes1.GetMyTDofOffset() + fes1.GetTrueVSize()
        col_starts = [start_col, end_col, mat.shape[1]]
        M = CHypreMat(m1, m2, col_starts=col_starts)
        #print("mat", M)
    else:
        from petram.helper.block_matrix import convert_to_ScipyCoo

        M = convert_to_ScipyCoo(coo_matrix(mat, dtype=mat.dtype))

    return M
예제 #19
0
 def __init__(self, value):
     v = mfem.Vector(np.transpose(value).flatten())
     m = mfem.DenseMatrix(v.GetData(), value.shape[0], value.shape[1])       
     self.value = (v,m)
     mfem.MatrixConstantCoefficient.__init__(self, m)
예제 #20
0
def eval_shape(order = 1, refine = 5, elem_type = 0,
               fec = 'ND'):

    if fec == 'ND':
        fec_type = mfem.ND_FECollection
        if order < 1: assert False, "ND order is 1 and above"        
    elif fec == 'RT':
        fec_type = mfem.RT_FECollection
    elif fec == 'H1':
        fec_type = mfem.H1_FECollection
        if order < 1: assert False, "H1 order is 1 and above"
    elif fec == 'L2':
        fec_type = mfem.L2_FECollection
    else:
        assert False, "unknown basis"
        
    if elem_type == 0:
        Nvert = 3; Nelem = 1; spaceDim = 2
    elif elem_type == 1:    
        Nvert = 4; Nelem = 1; spaceDim = 2

    mesh = mfem.Mesh(2, Nvert, Nelem, 0, spaceDim)

    if elem_type == 0:
        tri_v = [[1.,  0.3 ], [0.,  1.,], [0, 0]]
        tri_e = [[0, 1, 2], ]
        for j in range(Nvert):
            mesh.AddVertex(tri_v[j])
        for j in range(Nelem):
            mesh.AddTriangle(tri_e[j], j+1)
        mesh.FinalizeTriMesh(1,1, True)
    else:
        quad_v = [[-1, -1.3, ], [+1, -1, ], [+1, +1, ], [-1, +1,]]
        quad_e = [[0, 1, 2, 3]]
        for j in range(Nvert):
            mesh.AddVertex(quad_v[j])
        for j in range(Nelem):
            mesh.AddQuad(quad_e[j], j+1)
        mesh.FinalizeQuadMesh(1,1, True)

    #mesh.PrintToFile('plot_basis.mesh', 8)

    fe_coll = fec_type(order, spaceDim)
    fespace = mfem.FiniteElementSpace(mesh, fe_coll)

    x = mfem.GridFunction(fespace)
    x.Assign(0.0)
    x[0] = 1.0

    idx = 0
    geom = mesh.GetElementBaseGeometry(idx)
    T = mesh.GetElementTransformation(idx)
    fe = fespace.GetFE(idx)
    fe_nd = fe.GetDof()

    ir = fe.GetNodes()
    npt = ir.GetNPoints()
    dof = np.vstack([T.Transform(ir.IntPoint(i)) for i in range(npt)])
    
    RefG = mfem.GlobGeometryRefiner.Refine(geom, refine, 1);
    ir = RefG.RefPts

    npt = ir.GetNPoints()
    ptx = np.vstack([T.Transform(ir.IntPoint(i)) for i in range(npt)])

    shape = []
    if fec == 'ND' or fec == 'RT':
        mat = mfem.DenseMatrix(fe_nd, spaceDim)
        shape_func = fe.CalcVShape
        for i in range(npt):
            ip = ir.IntPoint(i)
            T.SetIntPoint(ip)
            fe.CalcVShape(T, mat)
            shape.append(mat.GetDataArray().copy())
    else:
        vec = mfem.Vector(fe_nd)
        for i in range(npt):
            ip = ir.IntPoint(i)            
            fe.CalcShape(ip, vec)
            shape.append(vec.GetDataArray().copy())

    return dof, ptx, np.stack(shape)