コード例 #1
0
    def IndicatorSmoothed(self, lsets, eps=0.03):
        """
        Indicator CoefficientFunction, indicating the eps-region around
        the instances' region (codim>0). We assume that the level sets
        are approximately signed distance functions in the eps region of
        the zero set. 

        Parameters
        ----------
        lsets : tuple(ngsolve.CoefficientFunctions)
            The set of level set functions defining the region.
        eps : float
            The distance around the sub-domain which is indicated
            (default eps=0.01).

        Returns
        -------
        CoefficientFunction
            1 in the region of distance eps around the sub-domain, 0 
            else.
        """

        if self.codim == 0:
            print("Warning: IndicatorSmothed is not intended for codim==0! "
                  "Please use the Indicator method")
            return self.Indicator(lsets)

        def gf_abs(gf):
            return IfPos(gf, gf, -gf)

        ind_combined = CoefficientFunction(0)
        for dtt in self.as_list:
            ind = CoefficientFunction(1)
            ind_cut = CoefficientFunction(1)

            for i, dt in enumerate(dtt):
                if dt == IF:
                    ind *= IfPos(gf_abs(lsets[i]) - eps, 0, 1)
                elif dt == POS:
                    ind_cut *= IfPos(lsets[i] - eps, 1, 0)
                elif dt == NEG:
                    ind_cut *= IfPos(-lsets[i] + eps, 1, 0)

            ind_combined += ind * ind_cut
            del ind, ind_cut

        ind_leveled = IfPos(ind_combined, 1, 0)

        del ind_combined
        return ind_leveled
コード例 #2
0
def DrawDiscontinuous_std(StdDraw, levelset, fneg, fpos, *args, **kwargs):
    def StdDrawWithDummyScene(cf, *args, **kwargs):
        StdDraw(cf, *args, **kwargs)
        return dummy_scene

    if "deformation" in kwargs and StdDraw.__module__ == "ngsolve.solve":
        args2 = list(args[:])
        args2[1] = "deformation_" + args[1]
        StdDraw(kwargs["deformation"], *tuple(args2), **kwargs)
        visoptions.deformation = 1
    if not "sd" in kwargs:
        kwargs["sd"] = 5

    return StdDrawWithDummyScene(IfPos(levelset, fpos, fneg), *args, **kwargs)
コード例 #3
0
    def Indicator(self, lsets):
        """
        Indicator CoefficientFunction for a DomainTypeArray of codim=0.

        Parameters
        ----------
        lsets : tuple(ngsolve.CoefficientFunctions)
            The set of level set functions with respect to which the
            instances' region is defined.

        Returns
        -------
        CoefficientFunction
            1 in the region on interest, 0 else.
        """

        if self.codim != 0:
            print("Warning: Indicator is not intended for codim > 0! "
                  "Please use the IndicatorSmoothed method")
            return self.IndicatorSmoothed(lsets)

        ind_combined = CoefficientFunction(0)
        for dtt in self.as_list:
            ind = CoefficientFunction(1)
            for i, dt in enumerate(dtt):
                if dt == POS:
                    ind *= IfPos(lsets[i], 1, 0)
                elif dt == NEG:
                    ind *= IfPos(-lsets[i], 1, 0)

            ind_combined += ind
            del ind

        ind_leveled = IfPos(ind_combined, 1, 0)
        del ind_combined

        return ind_leveled
コード例 #4
0
def tanh(
    x: Union[int, float, Parameter, CoefficientFunction]
) -> Union[float, CoefficientFunction]:
    """
    Function that implements the hyperbolic tangent in a way that's compatible with NGSolve
    Parameter and Coefficient objects.

    Args:
        x: The value to evaluate tanh at.

    Return:
        ~: tanh(x)
    """

    # Deal with some math overflow problems
    if type(x) is Parameter or type(x) is CoefficientFunction:
        # Added to ensure that the tanh calculation does not return nan
        x_adj = IfPos(x - 350, 350, x)
    else:  # float or int
        if x > 350:
            x_adj = 350
        else:
            x_adj = x
    return (exp(2 * x_adj) - 1.0) / (exp(2 * x_adj) + 1.0)
コード例 #5
0
 def gf_abs(gf):
     return IfPos(gf, gf, -gf)
コード例 #6
0
def Heat1DFEM(N=8,
              order=1,
              k1=1,
              k2=1,
              Q1=0,
              Q2=10,
              boundary_condition_left="Robin",
              boundary_condition_right="Dirichlet",
              value_left=0,
              value_right=1,
              q_value_left=0,
              q_value_right=1,
              r_value_left=0,
              r_value_right=1,
              intervalsize=0.14):
    if (boundary_condition_left == "Neumann" or
        (boundary_condition_left == "Robin" and r_value_left == 0)) and (
            boundary_condition_right == "Neumann" or
            (boundary_condition_right == "Robin" and r_value_right == 0)):
        print("Temperatur ist nicht eindeutig bestimmt.")
        #return
    mesh1D = Mesh1D(N, interval=(0, intervalsize))
    dbnds = []
    if boundary_condition_left == "Dirichlet":
        dbnds.append(1)
        # print(True)
    if boundary_condition_right == "Dirichlet":
        dbnds.append(2)

    fes = H1(mesh1D, order=order, dirichlet=dbnds)
    gf = GridFunction(fes)

    if boundary_condition_left == "Dirichlet":
        gf.vec[0] = value_left

    if boundary_condition_right == "Dirichlet":
        gf.vec[N] = value_right

    Q = IfPos(X - 0.5 * intervalsize, Q2, Q1)
    k = IfPos(X - 0.5 * intervalsize, k2, k1)

    u, v = fes.TnT()
    a = BilinearForm(fes)
    a += SymbolicBFI(k * grad(u) * grad(v))
    if boundary_condition_left == "Robin":
        a += SymbolicBFI(r_value_left * u * v,
                         definedon=mesh1D.Boundaries("left"))
    if boundary_condition_right == "Robin":
        a += SymbolicBFI(r_value_right * u * v,
                         definedon=mesh1D.Boundaries("right"))
    a.Assemble()
    f = LinearForm(fes)
    f += SymbolicLFI(Q * v)
    f.Assemble()
    if boundary_condition_left == "Neumann":
        f.vec[0] += q_value_left
    elif boundary_condition_left == "Robin":
        f.vec[0] += r_value_left * value_left
    if boundary_condition_right == "Neumann":
        f.vec[N] += q_value_right
    elif boundary_condition_right == "Robin":
        f.vec[N] += r_value_right * value_right

    f.vec.data -= a.mat * gf.vec
    gf.vec.data += a.mat.Inverse(fes.FreeDofs()) * f.vec
    Draw1D(mesh1D, [(gf, "u_h")], n_p=5 * order**2)