Example #1
0
def SchemeNonlinear(u, x, f, bc):
    coef, offsets = Selling.Decomposition(D(x))
    du = bc.DiffCentered(u, offsets)
    d2u = bc.Diff2(u, offsets)
    p = lp.dot_AV(lp.inverse(D(x)), np.sum(coef * du * offsets, axis=1))
    return np.where(
        bc.interior,
        -1 / 2 * lp.dot_VV(omega(x), p)**2 - lp.dot_VV(coef, d2u) - f,
        u - bc.grid_values,
    )
Example #2
0
def SchemeLinear(u, x, f, bc):
    coef, offsets = Selling.Decomposition(D(x))

    # coef_min = np.min(coef)
    # offsets_norm2 = lp.dot_VV(offsets, offsets)
    # offsets_max2 = np.max(np.where(coef < 1e-13, 0, offsets_norm2))
    # print(f"h: {bc.gridscale}, c: {coef_min}, e2: {offsets_max2}")

    du = bc.DiffCentered(u, offsets)
    d2u = bc.Diff2(u, offsets)
    return np.where(
        bc.interior,
        -lp.dot_VAV(omega(x), lp.inverse(D(x)),
                    np.sum(coef * du * offsets, axis=1)) -
        lp.dot_VV(coef, d2u) - f,
        u - bc.grid_values,
    )
Example #3
0
def ConstrainedMaximize(Q, l, m):
    dim = l.shape[0]
    if dim == 1:
        return (l[0] + np.sqrt(Q[0, 0])) / m[0]

    # Discard infinite values, handled afterwards
    pos_bad = l.min(axis=0) == -np.inf
    L = l.copy()
    L[:, pos_bad] = 0

    # Solve the quadratic equation
    A = lp.inverse(Q)
    lAl = lp.dot_VAV(L, A, L)
    lAm = lp.dot_VAV(L, A, m)
    mAm = lp.dot_VAV(m, A, m)

    delta = lAm**2 - (lAl - 1.) * mAm
    pos_bad = np.logical_or(pos_bad, delta <= 0)
    delta[pos_bad] = 1.

    mu = (lAm + np.sqrt(delta)) / mAm

    # Check the positivity
    #    v = dot_AV(A,mu*m-L)
    rm_ad = np.array
    v = lp.dot_AV(rm_ad(A), rm_ad(mu) * rm_ad(m) - rm_ad(L))
    pos_bad = np.logical_or(pos_bad, np.any(v < 0, axis=0))

    result = mu
    result[pos_bad] = -np.inf

    # Solve the lower dimensional sub-problems
    # We could restrict to the bad positions, and avoid repeating computations
    for i in range(dim):
        axes = np.full((dim), True)
        axes[i] = False
        res = ConstrainedMaximize(Q[axes][:, axes], l[axes], m[axes])
        result = np.maximum(result, res)
    return result