def assemble(self, *args, **kwargs): engine = self._engine() direction = kwargs.pop("direction", 0) self.process_kwargs(engine, kwargs) x = args[0] y = args[1] if len(args)>1 else 0 z = args[2] if len(args)>2 else 0 sdim = self.fes1.GetMesh().SpaceDimension() if direction == 0: if sdim == 3: d = mfem.DeltaCoefficient(x, y, z, 1) elif sdim == 2: d = mfem.DeltaCoefficient(x, y, 1) elif sdim == 1: d = mfem.DeltaCoefficient(x, 1) else: assert False, "unsupported dimension" intg = mfem.DomainLFIntegrator(d) else: dir = mfem.Vector(direction) if sdim == 3: d = mfem.VectorDeltaCoefficient(dir, x, y, z, 1) elif sdim == 2: d = mfem.VectorDeltaCoefficient(dir, x, y, 1) elif sdim == 1: d = mfem.VectorDeltaCoefficient(dir,x, 1) else: assert False, "unsupported dimension" if self.fes1.FEColl().Name().startswith('ND'): intg = mfem.VectorFEDomainLFIntegrator(d) elif self.fes1.FEColl().Name().startswith('RT'): intg = mfem.VectorFEDomainLFIntegrator(d) else: intg = mfem.VectorDomainLFIntegrator(d) lf1 = engine.new_lf(self.fes1) lf1.AddDomainIntegrator(intg) lf1.Assemble() from mfem.common.chypre import LF2PyVec, PyVec2PyMat, MfemVec2PyVec v1 = MfemVec2PyVec(engine.b2B(lf1), None) v1 = PyVec2PyMat(v1) if not self._transpose: v1 = v1.transpose() return v1
def add_delta_contribution(obj, engine, a, real = True, is_trans=False, is_conj=False): self = obj c = self.vt_coeff.make_value_or_expression(self) if isinstance(c, str): c = [c] if real: dprint1("Add "+self.integrator+ " delta (real)" + str(self._sel_index), "c", c) else: dprint1("Add "+self.integrator+ " delta(imag)" + str(self._sel_index), "c", c) cotype = self.coeff_type[0] if self.get_root_phys().vdim > 1: dim = self.get_root_phys().vdim else: el_name = self.get_root_phys().element dim = self.get_root_phys().geom_dim sdim = self.get_root_phys().geom_dim integrator = getattr(mfem, self.integrator) adder = a.AddDomainIntegrator for pos in self.pos_value: args = list(pos[:sdim]) if cotype == 'S': for b in self.itg_choice(): if b[0] == self.integrator: break if not "S*2" in b[3]: if real: args.append(float(np.array(c[0])[0].real)) else: args.append(float(np.array(c[0])[0].imag)) if args[-1] != 0: d = mfem.DeltaCoefficient(*args) adder(integrator(d)) else: # so far this is only for an elastic integrator if real: args.append(float(np.array(c[0])[0].real)) else: args.append(float(np.array(c[0])[0].imag)) d1 = mfem.DeltaCoefficient(*args) if real: args.append(float(np.array(c[0])[1].real)) else: args.append(float(np.array(c[0])[1].imag)) d2 = mfem.DeltaCoefficient(*args) adder(integrator(d1, d2)) elif cotype == 'V': if real: direction = np.array(c[0]).real else: direction = np.array(c[0]).imag args.append(1.0) dir = mfem.Vector(direction) d = mfem.VectorDeltaCoefficient(dir, *args) adder(integrator(d)) else: assert False, "M and D are not supported for delta coefficient"
def assemble(self, *args, **kwargs): engine = self._engine() direction = kwargs.pop("direction", None) weight = kwargs.pop("weight", 1.0) weight = np.atleast_1d(weight) do_sum = kwargs.pop("sum", False) info1 = engine.get_fes_info(self.fes1) sdim = info1['sdim'] vdim = info1['vdim'] if (info1['element'].startswith('ND') or info1['element'].startswith('RT')): vdim = sdim if vdim > 1: if direction is None: direction = [0]*vdim direction[0] = 1 direction = np.atleast_1d(direction).astype(float, copy=False) direction = direction.reshape(-1, sdim) self.process_kwargs(engine, kwargs) pts = np.array(args[0], copy = False).reshape(-1, sdim) from mfem.common.chypre import LF2PyVec, PyVec2PyMat, MfemVec2PyVec, HStackPyVec vecs = [] for k, pt in enumerate(pts): w = float(weight[0] if len(weight) == 1 else weight[k]) if vdim == 1: if sdim == 3: x, y, z = pt d = mfem.DeltaCoefficient(x, y, z, w) elif sdim == 2: x, y = pt print("DeltaCoefficient call", type(x), type(y), type(x)) d = mfem.DeltaCoefficient(x, y, w) elif sdim == 1: x = pt d = mfem.DeltaCoefficient(x, w) else: assert False, "unsupported dimension" intg = mfem.DomainLFIntegrator(d) else: dir = direction[0] if len(direction) == 1 else direction[k] dd = mfem.Vector(dir) if sdim == 3: x, y, z = pt d = mfem.VectorDeltaCoefficient(dd, x, y, z, w) elif sdim == 2: x, y = pt d = mfem.VectorDeltaCoefficient(dd, x, y, w) elif sdim == 1: x = pt d = mfem.VectorDeltaCoefficient(dd,x, w) else: assert False, "unsupported dimension" if self.fes1.FEColl().Name().startswith('ND'): intg = mfem.VectorFEDomainLFIntegrator(d) elif self.fes1.FEColl().Name().startswith('RT'): intg = mfem.VectorFEDomainLFIntegrator(d) else: intg = mfem.VectorDomainLFIntegrator(d) if do_sum: if k == 0: lf1 = engine.new_lf(self.fes1) lf1.AddDomainIntegrator(intg) else: lf1 = engine.new_lf(self.fes1) lf1.AddDomainIntegrator(intg) lf1.Assemble() vecs.append(LF2PyVec(lf1)) if do_sum: lf1.Assemble() v1 = MfemVec2PyVec(engine.b2B(lf1), None) v1 = PyVec2PyMat(v1) else: v1 = HStackPyVec(vecs) if not self._transpose: v1 = v1.transpose() return v1
def add_delta_contribution(obj, engine, a, real=True, is_trans=False, is_conj=False): self = obj c = self.vt_coeff.make_value_or_expression(self)[0] if isinstance(c, str): c = [c] if real: dprint1( "Add " + self.integrator + " delta (real)" + str(self._sel_index), "c", c) else: dprint1( "Add " + self.integrator + " delta (imag)" + str(self._sel_index), "c", c) cotype = self.coeff_type[0] if self.get_root_phys().vdim > 1: dim = self.get_root_phys().vdim else: el_name = self.get_root_phys().element dim = self.get_root_phys().geom_dim sdim = self.get_root_phys().geom_dim integrator = getattr(mfem, self.integrator) adder = a.AddDomainIntegrator for pos in self.pos_value: args = list(pos[:sdim]) if cotype == 'S': for b in self.itg_choice(): if b[0] == self.integrator: break if not "S*2" in b[3]: if isinstance(c[0], str): c_coeff = None #c_coeff = SCoeff(c[0], self.get_root_phys().ind_vars, # self._local_ns, self._global_ns, # real = real, conj=is_conj) value = eval(c[0], self._global_ns, self._local_ns) dprint1("time dependent delta", value) args.append(float(value)) else: c_coeff = None if real: args.append(float(np.array(c)[0].real)) else: args.append(float(np.array(c)[0].imag)) if args[-1] != 0: d = mfem.DeltaCoefficient(*args) if c_coeff is not None: assert False, "This option needs update of PyMFEM" d2 = mfem.ProductCoefficient(c_coeff, d) d2._linked_c = (c_coeff, d) adder(integrator(d2)) else: adder(integrator(d)) else: # so far this is only for an elastic integrator if real: args.append(float(np.array(c)[0].real)) else: args.append(float(np.array(c)[0].imag)) d1 = mfem.DeltaCoefficient(*args) if real: args.append(float(np.array(c)[1].real)) else: args.append(float(np.array(c)[1].imag)) d2 = mfem.DeltaCoefficient(*args) adder(integrator(d1, d2)) elif cotype == 'V': if real: direction = np.array(c).real else: direction = np.array(c).imag args.append(1.0) dir = mfem.Vector(direction) d = mfem.VectorDeltaCoefficient(dir, *args) adder(integrator(d)) else: assert False, "M and D are not supported for delta coefficient"