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
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