def make_preconditioner(self, A, name=None, parallel=False): name = self.Aname if name is None else name if self.gui.adv_mode: expr = self.gui.adv_prc gen = eval(expr, self.gui._global_ns) gen.set_param(A, name, self.engine, self.gui) M = gen() else: prcs_gui = dict(self.gui.preconditioners) #assert not self.gui.parent.is_complex(), "can not solve complex" if self.gui.parent.is_converted_from_complex( ) and not self.gui.merge_real_imag: name = sum([[n, n] for n in name], []) import petram.helper.preconditioners as prcs g = prcs.DiagonalPrcGen(opr=A, engine=self.engine, gui=self.gui, name=name) M = g() pc_block = {} for k, n in enumerate(name): prctxt = prcs_gui[n][1] if parallel else prcs_gui[n][0] if prctxt == "None": continue if prctxt.find("(") == -1: prctxt = prctxt + "()" prcargs = "(".join(prctxt.split("(")[-1:]) nn = prctxt.split("(")[0] if not n in pc_block: # make a new one dprint1(nn) try: blkgen = getattr(prcs, nn) except BaseException: if nn in self.gui._global_ns: blkgen = self.gui._global_ns[nn] else: raise blkgen.set_param(g, n) blk = eval("blkgen(" + prcargs) M.SetDiagonalBlock(k, blk) pc_block[n] = blk else: M.SetDiagonalBlock(k, pc_block[n]) return M
def make_preconditioner(self, A, parallel=False): if self.gui.adv_mode: expr = self.gui.adv_prc gen = eval(expr, self.gui._global_ns) gen.set_param(A, self.engine, self.gui) M = gen() else: prcs_gui = dict(self.gui.preconditioners) name = self.Aname assert not self.gui.parent.is_complex(), "can not solve complex" if self.gui.parent.is_converted_from_complex(): name = sum([[n, n] for n in name], []) import petram.helper.preconditioners as prcs g = prcs.DiagonalPrcGen(opr=A, engine=self.engine, gui=self.gui) M = g() for k, n in enumerate(name): prctxt = prcs_gui[n][1] if parallel else prcs_gui[n][0] if prctxt == "None": continue if prctxt.find("(") == -1: prctxt=prctxt+"()" prcargs = "(".join(prctxt.split("(")[-1:]) nn = prctxt.split("(")[0] try: blkgen = getattr(prcs, nn) except: if nn in self.gui._global_ns: blkgen = self.gui._global_ns[nn] else: raise blkgen.set_param(g, n) blk = eval("blkgen("+prcargs) M.SetDiagonalBlock(k, blk) return M
def prepare_solver(self, opr, engine): def get_operator_block(r, c): # if linked_op exists (= op is set from python). # try to get it # print(self.opr._linked_op) if hasattr(opr, "_linked_op"): try: return opr._linked_op[(r, c)] except KeyError: return None else: blk = opr.GetBlock(r, c) if use_parallel: return mfem.Opr2HypreParMat(blk) else: return mfem.Opr2SparseMat(blk) names = engine.masked_dep_var_names() if self.adv_mode: expr = self.adv_prc gen = eval(expr, self._global_ns) gen.set_param(A, names, engine, self) M = gen() else: prcs_gui = dict(self.preconditioners) ls_type = self.get_solve_root( ).get_linearsystem_type_from_modeltree() phys_real = self.get_solve_root().is_allphys_real() if ls_type == 'blk_interleave' and not phys_real: names = sum([[n, n] for n in names], []) import petram.helper.preconditioners as prcs g = prcs.DiagonalPrcGen(opr=opr, engine=engine, gui=self, name=names) M = g() pc_block = {} for k, n in enumerate(names): prctxt = prcs_gui[n][1] if use_parallel else prcs_gui[n][0] if prctxt == "None": continue if prctxt.find("(") == -1: prctxt = prctxt + "()" prcargs = "(".join(prctxt.split("(")[-1:]) nn = prctxt.split("(")[0] if not n in pc_block: # make a new one if not nn in self: try: blkgen = getattr(prcs, nn) except BaseException: if nn in self._global_ns: blkgen = self._global_ns[nn] else: raise blkgen.set_param(g, n) blk = eval("blkgen(" + prcargs) else: rr = engine.masked_dep_var_offset(n) cc = engine.masked_r_dep_var_offset(n) A = get_operator_block(rr, cc) blk = self[nn].prepare_solver(A, engine) M.SetDiagonalBlock(k, blk) pc_block[n] = blk else: M.SetDiagonalBlock(k, pc_block[n]) return M