def surface_weight(refine, gtype):
    if (refine, gtype) in globals()['weight']:
        return globals()['weight'][(refine, gtype)]
    
    quad_v = [[0, 0], [1, 0], [1, 1], [0, 3]]
    quad_e = [[0, 1, 2, 3]]
    tri_v =   [[0, 0], [1, 0], [0, 1]]
    tri_e = [[0, 1, 2,]]
    seg_v =   [[0,], [1, ],]
    seg_e = [[0, 1,]]

    if gtype == mfem.Geometry.TRIANGLE:
        mesh = mfem.Mesh(2, 3, 1, 0, 2)
        for j in range(3):
            mesh.AddVertex(tri_v[j])
        for j in range(1):
            mesh.AddTri(tri_e[j], 11)
        mesh.FinalizeTriMesh(1,1, True)

    elif gtype == mfem.Geometry.SQUARE:
        mesh = mfem.Mesh(2, 4, 1, 0, 2)
        for j in range(4):
            mesh.AddVertex(quad_v[j])
        for j in range(1):
            mesh.AddQuad(quad_e[j], 11)
        mesh.FinalizeQuadMesh(1,1, True)
    elif gtype == mfem.Geometry.SEGMENT:
        mesh = mfem.Mesh(1, 2, 1, 0, 1)
        for j in range(2):
            mesh.AddVertex(seg_v[j])
        for j in range(1):
            seg = mfem.Segment(seg_e[j], j+1)
            mesh.AddElement(seg)
            seg.thisown = False        
            mesh.FinalizeTopology()         
            mesh.Finalize(False, False)

    fec_type = mfem.H1_FECollection
    fe_coll = fec_type(1, 2)
    fes = mfem.FiniteElementSpace(mesh, fe_coll, 2)
    el = fes.GetFE(0)
    npt = Geom.GetVertices(gtype).GetNPoints()
    RefG = GR.Refine(gtype, refine)

    shape = mfem.Vector(el.GetDof())              
    ir = RefG.RefPts

    shapes =[]
    for i in range(ir.GetNPoints()):
        el.CalcShape(ir.IntPoint(i), shape)
        shapes.append(shape.GetDataArray().copy())
        
    w = np.vstack(shapes)
    globals()['weight'][(refine, gtype)] = w

    return w
def refine_surface_data(mesh, ibele, val, idx, refine):

    if mesh.Dimension() == 3:
        getarray = mesh.GetBdrArray
        gettrans = mesh.GetBdrElementTransformation
        getelement = mesh.GetBdrElement
        getbasegeom = mesh.GetBdrElementBaseGeometry
        getvertices = mesh.GetBdrElementVertices
    elif mesh.Dimension() == 2:
        getarray = mesh.GetDomainArray
        gettrans = mesh.GetElementTransformation        
        getelement = mesh.GetElement
        getbasegeom = mesh.GetElementBaseGeometry
        getvertices = mesh.GetElementVertices
    else:
        assert False, "BdrNodal Evaluator is not supported for this dimension"


    ptx = []
    data = []
    ridx = []

    nele = 0
    gtype_st = -1    
    sdim = mesh.SpaceDimension()

    for k, i in enumerate(ibele):
        gtype = getbasegeom(i)
        verts = getvertices(i)

        if gtype != gtype_st:
            RefG = GR.Refine(gtype, 3)
            ir = RefG.RefPts
            npt = ir.GetNPoints()
            ele = np.array(RefG.RefGeoms.ToList()).reshape(-1, len(verts))
            w = surface_weight(refine, gtype)
            gtype_st = gtype

        T = gettrans(i)
        pt = np.vstack([T.Transform(ir.IntPoint(j)) for j in range(npt)])
        ptx.append(pt)
        d = val[idx[k]]
        data.append(np.dot(w, d))
        ridx.append(ele + nele)
        nele = nele + ir.GetNPoints()
        
    ptx = np.vstack(ptx)
    data = np.hstack(data)
    ridx = np.vstack(ridx)
    return ptx, data, ridx
Esempio n. 3
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:
            getface = mesh.GetBdrElementFace
            gettrans = mesh.GetBdrElementTransformation
            getarray = mesh.GetBdrArray
            getelement = mesh.GetBdrElement
            getbasegeom = mesh.GetBdrElementBaseGeometry
            getvertices = mesh.GetBdrElementVertices
            getattr1 = lambda x: mesh.GetFaceElementTransformations(x).Elem1No
            getattr2 = lambda x: mesh.GetFaceElementTransformations(x).Elem2No

        elif mesh.Dimension() == 2:
            getface = lambda x: (x, 1)
            gettrans = mesh.GetElementTransformation
            getarray = mesh.GetDomainArray
            getelement = mesh.GetElement
            getbasegeom = mesh.GetElementBaseGeometry
            getvertices = mesh.GetElementVertices
            getattr1 = mesh.GetAttribute
            getattr2 = lambda x: -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

        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()
                ele = np.array(RefG.RefGeoms.ToList()).reshape(-1, len(verts))
                gtype_st = gtype
                self.irs[gtype] = ir

            T = gettrans(i)
            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
Esempio n. 4
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