Projection of nonlinear expressions onto associated Quadrature spaces

Dear community,

When studying the von Mises plasticity example by @bleyerj, I noticed the definition and usage of the local_project(v, V, u=None) function:

def local_project(v, V, u=None):
    dv = TrialFunction(V)
    v_ = TestFunction(V)
    a_proj = inner(dv, v_)*dxm
    b_proj = inner(v, v_)*dxm
    solver = LocalSolver(a_proj, b_proj)
    if u is None:
        u = Function(V)
        return u

In the code, after doing consitutive updates by function

ppos = lambda x: (x+abs(x))/2.
def proj_sig(deps, old_sig, old_p):
    sig_n = as_3D_tensor(old_sig)
    sig_elas = sig_n + sigma(deps)
    s = dev(sig_elas)
    sig_eq = sqrt(3/2.*inner(s, s))
    f_elas = sig_eq - sig0 - H*old_p
    dp = ppos(f_elas)/(3*mu+H)
    n_elas = s/sig_eq*ppos(f_elas)/f_elas
    beta = 3*mu*dp/sig_eq
    new_sig = sig_elas-beta*s
    return as_vector([new_sig[0, 0], new_sig[1, 1], new_sig[2, 2], new_sig[0, 1]]), \
           as_vector([n_elas[0, 0], n_elas[1, 1], n_elas[2, 2], n_elas[0, 1]]), \
           beta, dp

local_projects are performed on the returned values sig_, n_elas_, beta_, and dp_.

sig_, n_elas_, beta_, dp_ = proj_sig(deps, sig_old, p)
local_project(sig_, W, sig)
local_project(n_elas_, W, n_elas)
local_project(beta_, W0, beta)

In the example, it states that “The consitutive update defined earlier will perform nonlinear operations on the stress and strain tensors. These nonlinear expressions must then be projected back onto the associated Quadrature spaces.” I don’t quite understand this statement. I tried to output the values of the functions on quadrature points pre-projection and post-projection, and they were the same. However, If I delete the projection and simply change the names of sig_, n_elas_, beta_ to sig, n_elas, and beta, the NR-Loop no longer show quadratic convergence (very slow).

Any insights?

I have been encountering slow convergence of NR-Loop of my implementation of the effective stress function algorithm. I have examined the code very carefully and didn’t have a clue on what went wrong. I wonder whether I have done some improper projections, or missed some projections.

Thank you!