Пример #1
0
    def assemble(self, *args, **kwargs):
        engine = self._engine()        
        self.process_kwargs(engine, kwargs)
        if len(args)>0: self._sel_mode = args[0]
        if len(args)>1: self._sel = args[1]

        trans1 = kwargs.pop("trans",   None)     # transformation of fes1 (or both)
        trans2 = kwargs.pop("srctrans", trans1)  # transformation of fes2
        srcsel = kwargs.pop("src", self._ssel)    # source idx
        tol    = kwargs.pop("tol", 1e-5)         # projectio tolerance

        dim1 = self.fes1.GetMesh().Dimension()
        dim2 = self.fes2.GetMesh().Dimension()

        projmode = ""
        if dim2 == 3:
           if self.sel_mode == "domain":
               projmode = "volume"
           elif self.sel_mode == "boundary":
               projmode = "surface"
        elif dim2 == 2:
           if self.sel_mode == "domain":
               projmode = "surface"
           elif self.sel_mode == "boundary":
               projmode = "edge"
        elif dim2 == 1:
           if self.sel_mode == "domain":
               projmode = "edge"
           elif self.sel_mode == "boundary":
               projmode = "vertex"
        assert projmode != "", "unknow projection mode"
        if self._sel == 'all' and self._ssel == 'all':
            if self.sel_mode == "domain":
                if dim1 == dim2:
                    idx1 = np.unique(self.fes1.GetMesh().GetAttributeArray())
                elif dim1 == dim2+1:
                    idx1 = np.unique(self.fes1.GetMesh().GetBdrAttributeArray())
                else:
                    assert False, "unsupported mode"
                idx2 = np.unique(self.fes2.GetMesh().GetAttributeArray()) 
            else:
                idx1 = np.unique(self.fes1.GetMesh().GetBdrAttributeArray())
                idx2 = np.unique(self.fes2.GetMesh().GetBdrAttributeArray())

            if use_parallel:
                idx1 = list(idx1)
                idx2 = list(idx2)
                idx1 = list(set(sum(comm.allgather(idx1),[])))
                idx2 = list(set(sum(comm.allgather(idx2),[])))
            idx = np.intersect1d(idx1, idx2)
            idx1 = list(idx)
            idx2 = list(idx)
            
        elif self._ssel == 'all':
            if self.sel_mode == "domain":
                idx2 = np.unique(self.fes2.GetMesh().GetAttributeArray())
            else:
                idx2 = np.unique(self.fes2.GetMesh().GetBdrAttributeArray())
            idx1 = self._sel
            idx2 = list(idx2)            
            if use_parallel:
                idx2 =  list(set(sum(comm.allgather(idx2),[])))

            
        elif self._sel == 'all':
            if self.sel_mode == "domain":
                idx1 = np.unique(self.fes1.GetMesh().GetAttributeArray())
            else:
                idx1 = np.unique(self.fes1.GetMesh().GetBdrAttributeArray())

            idx1 = list(idx1)
            if use_parallel:
                idx1 =  list(set(sum(comm.allgather(idx1),[])))
            idx2 = srcsel
            
        else:
            idx1 = self._sel
            idx2 = srcsel
            
        if use_parallel:
            # we may not need this?
            idx1 =  list(set(sum(comm.allgather(idx1),[])))
            idx2 =  list(set(sum(comm.allgather(idx2),[])))

        dprint1("projection index ", idx1, idx2)
        
        from petram.helper.dof_map import notrans

        sdim1 = self.fes1.GetMesh().SpaceDimension()
        sdim2 = self.fes2.GetMesh().SpaceDimension()        

        lns = {}
        if trans1 is not None:
            if sdim1 == 3:
                trans1= ['def trans1(xyz):',
                         '    import numpy as np',
                         '    x = xyz[0]; y=xyz[1]; z=xyz[2]',
                         '    return np.array(['+trans1+'])']
            elif sdim1 == 2:
                trans1= ['def trans1(xyz):',
                         '    import numpy as np',
                         '    x = xyz[0]; y=xyz[1]',
                         '    return np.array(['+trans1+'])']
            else: # sdim1 == 3  
                trans1= ['def trans1(xyz):',
                         '    import numpy as np',
                         '    x = xyz[0]',
                         '    return np.array(['+trans1+'])']
            exec '\n'.join(trans1) in self._global_ns, lns
            trans1 = lns['trans1']            
        else:
            trans1 = notrans
            
        if trans2 is not None:
            if sdim2 == 3:
                trans2 = ['def trans2(xyz):',
                         '    import numpy as np',
                         '    x = xyz[0]; y=xyz[1]; z=xyz[2]',
                         '    return np.array(['+trans2+'])']
            elif sdim2 == 2:
                trans2 = ['def trans2(xyz):',
                         '    import numpy as np',
                         '    x = xyz[0]; y=xyz[1]',
                         '    return np.array(['+trans2+'])']
            else: # sdim1 == 3  
                trans2 = ['def trans2(xyz):',
                         '    import numpy as np',
                         '    x = xyz[0]',
                         '    return np.array(['+trans2+'])']

            trans2 = lns['trans2']                    
        else:
            trans2 = notrans
                  


        from petram.helper.dof_map import projection_matrix as pm
        # matrix to transfer unknown from trail to test
        M, row, col = pm(idx2, idx1, self.fes2, [], fes2=self.fes1,
                         trans1=trans2, trans2=trans1,
                         mode=projmode, tol=tol, filldiag=False)
        return M
Пример #2
0
def simple_projection(fes1, fes2, sel_mode, tol=1e-5, old_mapping=False):
    mesh1 = fes1.GetMesh()
    mesh2 = fes1.GetMesh()
    dim1 = mesh1.Dimension()
    dim2 = mesh2.Dimension()

    projmode = ""
    if dim2 == 3:
        if sel_mode == "domain":
            projmode = "volume"
        elif sel_mode == "boundary":
            projmode = "surface"
    elif dim2 == 2:
        if sel_mode == "domain":
            projmode = "surface"
        elif sel_mode == "boundary":
            projmode = "edge"
    elif dim2 == 1:
        if sel_mode == "domain":
            projmode = "edge"
        elif sel_mode == "boundary":
            projmode = "vertex"
    assert projmode != "", "unknow projection mode"
    if sel_mode == "domain":
        if dim1 == dim2:
            idx1 = np.unique(mesh1.GetAttributeArray())
        elif dim1 == dim2 + 1:
            idx1 = np.unique(mesh1.GetBdrAttributeArray())
        else:
            assert False, "unsupported mode"
        idx2 = np.unique(mesh2.GetAttributeArray())
    else:
        if dim1 == dim2:
            idx1 = np.unique(mesh1.GetBdrAttributeArray())
        elif dim1 == dim2 - 1:
            idx1 = np.unique(mesh1.GetAttributeArray())
        idx2 = np.unique(mesh2.GetBdrAttributeArray())

    if use_parallel:
        idx1 = list(idx1)
        idx2 = list(idx2)
        idx1 = list(set(sum(comm.allgather(idx1), [])))
        idx2 = list(set(sum(comm.allgather(idx2), [])))
    idx = np.intersect1d(idx1, idx2)
    idx1 = list(idx)
    idx2 = list(idx)

    if use_parallel:
        # we may not need this?
        idx1 = list(set(sum(comm.allgather(idx1), [])))
        idx2 = list(set(sum(comm.allgather(idx2), [])))

    dprint1("projection index ", idx1, idx2)

    from petram.helper.dof_map import notrans

    sdim1 = mesh1.SpaceDimension()
    sdim2 = mesh2.SpaceDimension()

    trans1 = notrans
    trans2 = notrans

    from petram.helper.dof_map import projection_matrix as pm
    # matrix to transfer unknown from trail to test
    M, row, col = pm(idx2,
                     idx1,
                     fes2, [],
                     fes2=fes1,
                     trans1=trans2,
                     trans2=trans1,
                     mode=projmode,
                     tol=tol,
                     filldiag=False,
                     old_mapping=old_mapping)
    return M