Assigning linear combination of functions

Issue #85 resolved
Miguel Rodriguez created an issue

I am using all versions (dolfin, dolfin_adjoint, and libadjoint) 2016.2.0.

I am solving a time-dependent solid mechanics problem in which I use the Newmark integration scheme. According to the discussion here, I should avoid using the following code, which is found in the FEniCS book:

def update_book(u, u0, v0, a0, beta, gamma, dt):
    u_vec, u0_vec = u.vector(), u0.vector()
    v0_vec, a0_vec = v0.vector(), a0.vector()

    a_vec = 1.0/(beta*dt**2)*(u_vec - u0_vec - v0_vec*dt) \
                              - (1.0/(2.0*beta) - 1.0)*a0_vec
    v_vec = dt*((1.0 - gamma)*a0_vec + gamma*a_vec) + v0_vec

    v0.vector()[:], a0.vector()[:] = v_vec, a_vec
    u0.vector()[:] = u_vec

since the updates to these function objects are not annotated correctly due to the use of v0.vector()[:] = .... Thus, I tried this code:

def update(u, u0, v0, a0, beta, gamma, dt, annotate=False):

    a = 1.0/(beta*dt**2)*(u - u0 - v0*dt) \
        - (1.0/(2.0*beta) - 1.0)*a0
    v = dt*((1.0 - gamma)*a0 + gamma*a) + v0

    v0.assign(v, annotate=annotate)
    a0.assign(a, annotate=annotate)
    u0.assign(u, annotate=annotate)

This gives the following error when annotate=True:

AttributeError: 'MultiIndex' object has no attribute 'free_indices'

Furthermore, when I do use the update function with annotate=False, the problem does not converge after several time steps. However, the problem converges just fine with update_book. What is happening?

Note: this issue does not appear at all if the function objects are of type dolfin.Function instead of dolfin_adjoint.Function.

Comments (3)

  1. Miguel Rodriguez reporter

    I fixed the issue of the problem not converging when annotate=False by realizing that values of functions were not being updated in the right order (also had to change scalars to floats). The fix was to change the update function as such:

    def update(u, u0, v0, a0, beta1, gamma1, dt1, V, annotate=False):
        a = da.Function(V, annotate=False)
        v = da.Function(V, annotate=False)
    
        beta = float(beta1)
        gamma = float(gamma1)
        dt = float(dt1)
    
        a_temp = 1.0/(beta*dt**2)*(u - u0 - v0*dt) \
                 - (1.0/(2.0*beta) - 1.0)*a0
        a.assign(a_temp, annotate=False)
    
        v_temp = dt*((1.0 - gamma)*a0 + gamma*a) + v0
        v.assign(v_temp, annotate=False)
    
        v0.assign(v, annotate=annotate)
        a0.assign(a, annotate=annotate)
        u0.assign(u, annotate=annotate)
    

    Nevertheless, the above AttributeError is still raised when annotate=True.

  2. Miguel Rodriguez reporter

    Not entirely sure what happened between making the changes mentioned above to updateand now, but it seems to work fine now.

  3. Log in to comment