Beispiel #1
0
    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
Beispiel #2
0
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"
Beispiel #3
0
    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
Beispiel #4
0
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"