def viscoElasticUpdater_bgvel(t, y, wdict):
    #interior function for incompressible background flow only
    #split up long vector into individual sections (force pts, Lagrangian pts, stress components)
    pdict = wdict['pdict']
    N = pdict['N']
    M = pdict['M']
    l2 = np.reshape(y[range(2 * N * M)], (N * M, 2))
    l3 = np.reshape(l2, (N, M, 2))
    P2 = np.reshape(y[(2 * N * M):], (N * M, 2, 2))
    P3 = np.reshape(P2, (N, M, 2, 2))
    #calculate tensor derivative
    Pd = pdict['beta'] * SD2D.tensorDiv(P3, pdict['gridspc'], N, M)
    Pd = np.reshape(Pd, (N * M, 2))
    #calculate deformation matrix and its inverse
    F = SD2D.vectorGrad(l3, pdict['gridspc'], N, M)
    F = np.reshape(F, (N * M, 2, 2))
    #calculate new velocities at all points of interest
    ub, gradub = wdict['myVelocity'](pdict, l2)
    lt0 = pdict['gridspc']**2 * CM.matmult(pdict['eps_grid'], pdict['mu'], l2,
                                           l2, Pd)
    # reshape the velocities on the grid
    lt3 = np.reshape(lt0, (N, M, 2))
    lt = ub + lt0
    #    calculate new stress time derivatives
    gradlt = SD2D.vectorGrad(lt3, pdict['gridspc'], N, M)
    gradlt = np.reshape(gradlt, (N * M, 2, 2))
    Pt = CM.stressDeriv(pdict['Wi'], gradub, gradlt, F, P2)
    #    gradlt = pdict['gridspc']**2*CM.derivop(pdict['eps_grid'],pdict['mu'],l2,l2,Pd,F) #grad(Stokeslet) method
    #    Finv = CM.matinv2x2(F) #first grad(u) method
    #    Pt = np.zeros((N*M,2,2)) #first grad(u) method
    #    for j in range(N*M):
    #        Pt[j,:,:] = np.dot(gradub[j,:,:],P2[j,:,:]) + np.dot(np.dot(gradlt[j,:,:],Finv[j,:,:]),P2[j,:,:]) - (1./pdict['Wi'])*(P2[j,:,:] - Finv[j,:,:].transpose())
    return np.append(lt, Pt.flatten())
def calcState_dets(r,t0,regridding,regriddict,alldetflag=1):
    regridflag = False
    addptsflag = False
    StateNow = {}
    StateNow['t'] = r.t
    wdict = r.f_params[0]
    pdict=wdict['pdict']
    try:
        N = pdict['N']
        M = pdict['M']
    except:
        N = 0
        M = 0
    Q = len(r.y) - 2*N*M - 4*N*M
    adarray=np.zeros((N,M))
    if N == 0: #stokes flow without markers
        StateNow['fpts']=r.y
    elif Q < 0: #stokes flow with markers
        StateNow['fpts']=r.y[:2*N*M]
        l3D = np.reshape(r.y[-2*N*M:],(N,M,2))
        StateNow['l']=l3D
        if alldetflag:
            F = SD2D.vectorGrad(l3D,pdict['gridspc'],N,M)            
            for j in range(N):
                for k in range(M):
                    Fs = F[j,k,:,:]
                    gdet = np.linalg.det(Fs)
                    adarray[j,k] = gdet
            StateNow['alldets']=adarray
    elif Q >= 0: #viscoelastic flow
        StateNow['fpts']=r.y[:Q]
        l3D = np.reshape(r.y[range(Q,Q+2*N*M)],(N,M,2))
        StateNow['l']=l3D
        F = SD2D.vectorGrad(l3D,pdict['gridspc'],N,M)            
        Ptemp = np.reshape(r.y[(Q+2*N*M):],(N,M,2,2))
        Stemp = np.zeros((N,M,2,2))
        tr = np.zeros((N,M))
        for j in range(N):
            for k in range(M):
                Fs = F[j,k,:,:]
                if alldetflag or (regriddict['detcrit'] != None):
                    gdet = np.linalg.det(Fs)
                    adarray[j,k] = gdet
                Ps = Ptemp[j,k,:,:]
                Stemp[j,k,:,:]=np.dot(Ps,Fs.transpose())
                tr[j,k] = Stemp[j,k,0,0] + Stemp[j,k,1,1]
        StateNow['S']=Stemp
        StateNow['Strace']=tr
        if alldetflag:
            StateNow['alldets']=adarray 
        if regridding:
            if regriddict['timecrit'] != None:
                regridflag, addptsflag = regridFlagFixedTime(r.t,t0,regriddict['timecrit'],regriddict['addpts'])
            elif regriddict['edgecrit'] != None:
                regridflag, addptsflag = regridFlagAdaptiveCloseToEdge(tr,N,M,regriddict['edgecrit'],regriddict['addpts'])
            elif regriddict['detcrit'] != None:
                regridflag, addptsflag = regridFlagAdaptiveDistortedDet(adarray,regriddict['detcrit'],regriddict['addpts'])
            else:
                print('Warning: No regridding algorithm specified. Regridding ignored.')
    return StateNow, regridflag, addptsflag
def viscoElasticUpdater_bgvel(t,y,wdict):
    #interior function for incompressible background flow only
    #split up long vector into individual sections (force pts, Lagrangian pts, stress components)
    pdict = wdict['pdict']
    N = pdict['N']
    M = pdict['M']
    l2 = np.reshape(y[range(2*N*M)],(N*M,2))
    l3 = np.reshape(l2,(N,M,2))
    P2 = np.reshape(y[(2*N*M):],(N*M,2,2))
    P3 = np.reshape(P2,(N,M,2,2))
    #calculate tensor derivative
    Pd = pdict['beta']*SD2D.tensorDiv(P3,pdict['gridspc'],N,M)
    Pd = np.reshape(Pd,(N*M,2))
    #calculate deformation matrix and its inverse
    F = SD2D.vectorGrad(l3,pdict['gridspc'],N,M)
    F = np.reshape(F,(N*M,2,2))
    #calculate new velocities at all points of interest
    ub, gradub = wdict['myVelocity'](pdict,l2)
    lt0 = pdict['gridspc']**2*CM.matmult(pdict['eps_grid'],pdict['mu'],l2,l2,Pd) 
    # reshape the velocities on the grid
    lt3 = np.reshape(lt0,(N,M,2)) 
    lt = ub + lt0
#    calculate new stress time derivatives
    gradlt = SD2D.vectorGrad(lt3,pdict['gridspc'],N,M)   
    gradlt = np.reshape(gradlt,(N*M,2,2))
    Pt = CM.stressDeriv(pdict['Wi'],gradub,gradlt,F,P2)
#    gradlt = pdict['gridspc']**2*CM.derivop(pdict['eps_grid'],pdict['mu'],l2,l2,Pd,F) #grad(Stokeslet) method
#    Finv = CM.matinv2x2(F) #first grad(u) method
#    Pt = np.zeros((N*M,2,2)) #first grad(u) method
#    for j in range(N*M):
#        Pt[j,:,:] = np.dot(gradub[j,:,:],P2[j,:,:]) + np.dot(np.dot(gradlt[j,:,:],Finv[j,:,:]),P2[j,:,:]) - (1./pdict['Wi'])*(P2[j,:,:] - Finv[j,:,:].transpose())        
    return np.append(lt,Pt.flatten())
def simresults(basename, basedir):
    '''Retrieve approximate solution from saved output'''
    mydict = fileops.loadPickle(basename=basename, basedir=basedir)
    l = mydict['l']
    S = mydict['S']
    F = []
    Finv = []
    P = []
    N = l[0].shape[0]
    M = l[0].shape[1]
    for k in range(len(mydict['t'])):
        Ft = SD2D.vectorGrad(l[k], mydict['pdict']['gridspc'], N, M)
        Ftemp = np.reshape(Ft, (N * M, 2, 2))
        Ftinv = CM.matinv2x2(Ftemp)
        Ftinv = np.reshape(Ftinv, (N, M, 2, 2))
        F.append(Ft.copy())
        Finv.append(Ftinv.copy())
        stress = np.zeros((N, M, 2, 2))
        for j in range(N):
            for m in range(M):
                stress[j,
                       m, :, :] = S[k][j,
                                       m, :, :] * Ftinv[j,
                                                        m, :, :].transpose()
        P.append(stress.copy())
    return l, P, S, F, Finv, mydict
def viscoElasticUpdater_force(t, y, wdict):
    #interior function for force pts only
    #split up long vector into individual sections (force pts, Lagrangian pts, stress components)
    pdict = wdict['pdict']
    pdict['forcedict']['t'] = t
    N = pdict['N']
    M = pdict['M']
    Q = len(y) / 2 - N * M - 2 * N * M
    fpts = np.reshape(y[:2 * Q], (Q, 2))
    l2 = np.reshape(y[range(2 * Q, 2 * Q + 2 * N * M)], (N * M, 2))
    l3 = np.reshape(l2, (N, M, 2))
    allpts = np.reshape(
        y[:2 * Q + 2 * N * M],
        (Q + N * M, 2))  # both force points and Lagrangian points
    P2 = np.reshape(y[(2 * Q + 2 * N * M):], (N * M, 2, 2))
    P3 = np.reshape(P2, (N, M, 2, 2))
    #calculate tensor derivative
    Pd = pdict['beta'] * SD2D.tensorDiv(P3, pdict['gridspc'], N, M)
    Pd = np.reshape(Pd, (N * M, 2))
    #calculate spring forces
    f = wdict['myForces'](fpts, **pdict['forcedict'])
    #calculate new velocities at all points of interest (Lagrangian points and force points)
    lt = pdict['gridspc']**2 * CM.matmult(
        pdict['eps_grid'], pdict['mu'], allpts, l2, Pd) + CM.matmult(
            pdict['eps_obj'], pdict['mu'], allpts, fpts, f)
    # reshape the velocities on the grid
    lt3 = np.reshape(lt[2 * Q:], (N, M, 2))
    #calculate deformation matrix and its inverse
    F = SD2D.vectorGrad(l3, pdict['gridspc'], N, M)
    F = np.reshape(F, (N * M, 2, 2))
    #calculate new stress time derivatives
    #    gradlt = pdict['gridspc']**2*CM.derivop(pdict['eps_grid'],pdict['mu'],l2,l2,Pd,F) + CM.derivop(pdict['eps_obj'],pdict['mu'],l2,fpts,f,F)   #grad(Stokeslet) method
    gradlt = SD2D.vectorGrad(lt3, pdict['gridspc'], N, M)
    gradlt = np.reshape(gradlt, (N * M, 2, 2))
    gradub = np.zeros(gradlt.shape)
    #    Finv = CM.matinv2x2(F)   # first grad(u) method
    #    Pt = np.zeros((N*M,2,2))
    #    for j in range(N*M):
    #        Pt[j,:,:] = np.dot(np.dot(gradlt[j,:,:],Finv[j,:,:]),P2[j,:,:]) - (1./pdict['Wi'])*(P2[j,:,:] - Finv[j,:,:].transpose())
    Pt = CM.stressDeriv(pdict['Wi'], gradub, gradlt, F, P2)
    return np.append(lt, Pt.flatten())
def viscoElasticUpdater_force(t,y,wdict):
    #interior function for force pts only
    #split up long vector into individual sections (force pts, Lagrangian pts, stress components)
    pdict = wdict['pdict']
    pdict['forcedict']['t'] = t
    N = pdict['N']
    M = pdict['M']
    Q = len(y)/2 - N*M - 2*N*M
    fpts = np.reshape(y[:2*Q],(Q,2))
    l2 = np.reshape(y[range(2*Q,2*Q+2*N*M)],(N*M,2))
    l3 = np.reshape(l2,(N,M,2))
    allpts = np.reshape(y[:2*Q+2*N*M],(Q+N*M,2)) # both force points and Lagrangian points
    P2 = np.reshape(y[(2*Q+2*N*M):],(N*M,2,2))
    P3 = np.reshape(P2,(N,M,2,2))
    #calculate tensor derivative
    Pd = pdict['beta']*SD2D.tensorDiv(P3,pdict['gridspc'],N,M)
    Pd = np.reshape(Pd,(N*M,2))
    #calculate spring forces
    f = wdict['myForces'](fpts,**pdict['forcedict'])
    #calculate new velocities at all points of interest (Lagrangian points and force points)
    lt = pdict['gridspc']**2*CM.matmult(pdict['eps_grid'],pdict['mu'],allpts,l2,Pd) + CM.matmult(pdict['eps_obj'],pdict['mu'],allpts,fpts,f)
    # reshape the velocities on the grid
    lt3 = np.reshape(lt[2*Q:],(N,M,2)) 
    #calculate deformation matrix and its inverse
    F = SD2D.vectorGrad(l3,pdict['gridspc'],N,M)
    F = np.reshape(F,(N*M,2,2))
    #calculate new stress time derivatives
#    gradlt = pdict['gridspc']**2*CM.derivop(pdict['eps_grid'],pdict['mu'],l2,l2,Pd,F) + CM.derivop(pdict['eps_obj'],pdict['mu'],l2,fpts,f,F)   #grad(Stokeslet) method
    gradlt = SD2D.vectorGrad(lt3,pdict['gridspc'],N,M)   
    gradlt = np.reshape(gradlt,(N*M,2,2))
    gradub = np.zeros(gradlt.shape)
#    Finv = CM.matinv2x2(F)   # first grad(u) method
#    Pt = np.zeros((N*M,2,2))
#    for j in range(N*M):
#        Pt[j,:,:] = np.dot(np.dot(gradlt[j,:,:],Finv[j,:,:]),P2[j,:,:]) - (1./pdict['Wi'])*(P2[j,:,:] - Finv[j,:,:].transpose())        
    Pt = CM.stressDeriv(pdict['Wi'],gradub,gradlt,F,P2)
    return np.append(lt,Pt.flatten())
def calcState_nodets(r, t0, regridding, regriddict, alldetflag=0):
    regridflag = False
    addptsflag = False
    StateNow = {}
    StateNow['t'] = r.t
    wdict = r.f_params[0]
    pdict = wdict['pdict']
    try:
        N = pdict['N']
        M = pdict['M']
    except:
        N = 0
        M = 0
    Q = len(r.y) - 2 * N * M - 4 * N * M
    if N == 0:  #stokes flow without markers
        StateNow['fpts'] = r.y
    elif Q < 0:  #stokes flow with markers
        StateNow['fpts'] = r.y[:2 * N * M]
        l3D = np.reshape(r.y[-2 * N * M:], (N, M, 2))
        StateNow['l'] = l3D
    elif Q >= 0:  #viscoelastic flow
        StateNow['fpts'] = r.y[:Q]
        l3D = np.reshape(r.y[range(Q, Q + 2 * N * M)], (N, M, 2))
        StateNow['l'] = l3D
        F = SD2D.vectorGrad(l3D, pdict['gridspc'], N, M)
        Ptemp = np.reshape(r.y[(Q + 2 * N * M):], (N, M, 2, 2))
        Stemp = np.zeros((N, M, 2, 2))
        tr = np.zeros((N, M))
        for j in range(N):
            for k in range(M):
                Fs = F[j, k, :, :]
                Ps = Ptemp[j, k, :, :]
                Stemp[j, k, :, :] = np.dot(Ps, Fs.transpose())
                tr[j, k] = Stemp[j, k, 0, 0] + Stemp[j, k, 1, 1]
        StateNow['S'] = Stemp
        StateNow['Strace'] = tr
        if regridding:
            if regriddict['timecrit'] != None:
                regridflag, addptsflag = regridFlagFixedTime(
                    r.t, t0, regriddict['timecrit'], regriddict['addpts'])
            elif regriddict['edgecrit'] != None:
                regridflag, addptsflag = regridFlagAdaptiveCloseToEdge(
                    tr, N, M, regriddict['edgecrit'], regriddict['addpts'])
            else:
                print(
                    'Warning: No regridding algorithm specified. Regridding ignored.'
                )
    return StateNow, regridflag, addptsflag
def simresults(basename, basedir):
    '''Retrieve approximate solution from saved output'''
    mydict = fileops.loadPickle(basename=basename, basedir=basedir)
    l = mydict['l']
    S=mydict['S']
    F=[]
    Finv=[]
    P=[]
    N = l[0].shape[0]
    M = l[0].shape[1]
    for k in range(len(mydict['t'])):
        Ft = SD2D.vectorGrad(l[k],mydict['pdict']['gridspc'],N,M)
        Ftemp = np.reshape(Ft,(N*M,2,2))
        Ftinv = CM.matinv2x2(Ftemp)
        Ftinv = np.reshape(Ftinv,(N,M,2,2))
        F.append(Ft.copy())
        Finv.append(Ftinv.copy())
        stress = np.zeros((N,M,2,2))
        for j in range(N):
            for m in range(M):
                stress[j,m,:,:] = S[k][j,m,:,:]*Ftinv[j,m,:,:].transpose()
        P.append(stress.copy())
    return l, P, S, F, Finv, mydict