import numpy as np
from genx.core.custom_logging import iprint

_ctype=np.complex128

def refl(kj, kjm1):
    return (kj+kjm1)/2/kjm1

def ass_X_test(k_b, k_u, k_l, dd_u, dd_l,
               sigma, sigma_l, sigma_u, dtype=_ctype):
    ''' Just a simpler version of ass_X to locate an error somewhere...
    '''
    k_jm1_b=k_b[..., 1:]
    k_j_b=k_b[..., :-1]
    k_jm1_l=k_l[..., 1:]
    k_j_u=k_u[..., :-1]
    sigma_jm1_l=sigma_l[..., 1:]
    sigma_j_b=sigma[..., :-1]
    sigma_j_u=sigma_u[..., :-1]
    dd_jm1_l=dd_l[..., 1:]
    dd_j_u=dd_u[..., :-1]

    iprint(dd_j_u, dd_jm1_l)

    # Reflectivites
    r_j_b=refl(k_j_b, k_j_u)
    # print 'r_j_b', r_j_b
    r_jm1_l=refl(k_jm1_l, k_jm1_b)
    # print 'r_jm1_l', r_jm1_l
    r_j_u=refl(k_j_u, k_jm1_l)
    # print 'r_j_u', r_j_u
    p_jm1_l=np.exp(-1.0J*dd_jm1_l*k_jm1_l)
    p_j_u=np.exp(-1.0J*dd_j_u*k_j_u)

    # Defining the X matrix
    X=np.empty((2, 2)+k_j_b.shape, dtype=dtype)

    X[0, 0]=p_jm1_l*r_j_u*p_j_u
    X[0, 1]=-(p_jm1_l*r_j_u-p_jm1_l)/p_j_u
    X[1, 0]=-((r_j_u-1)*p_j_u)/p_jm1_l
    X[1, 1]=r_j_u/(p_jm1_l*p_j_u)

    return X

def ass_X_interfacelayer4(k_b, k_u, k_l, dd_u, dd_l,
                          sigma, sigma_l, sigma_u, dtype=_ctype):
    '''Function that creates a interfacelayer at the top and bottom
    of the layer. with correlated roughness for the interface layers and the
    additional roughness of sigma_l and sigma_u.
    The subscripts b, l and u reffers to bulk, lower and upper respectively.

    v 0.4
    '''
    # print dd_l, dd_u
    # Variables definitions that goes into the expressions:
    k_jm1_b=k_b[..., 1:]
    k_j_b=k_b[..., :-1]
    k_jm1_l=k_l[..., 1:]
    k_j_u=k_u[..., :-1]
    sigma_jm1_l=sigma_l[..., 1:]
    sigma_j_b=sigma[..., :-1]
    sigma_j_u=sigma_u[..., :-1]
    dd_jm1_l=dd_l[..., 1:]
    dd_j_u=dd_u[..., :-1]

    # Reflectivites
    r_j_b=refl(k_j_b, k_j_u)
    r_jm1_l=refl(k_jm1_l, k_jm1_b)
    r_j=refl(k_j_u, k_jm1_l)
    p_jm1_l=np.exp(-1.0J*dd_jm1_l*k_jm1_l)
    p_j_u=np.exp(-1.0J*dd_j_u*k_j_u)
    # p_j_b = np.exp(-1.0J*dd_j_b*k_j_b)

    # Defining the X matrix
    X=np.empty((2, 2)+k_j_b.shape, dtype=dtype)

    tmp1=k_jm1_b**2
    tmp2=sigma_jm1_l**2
    tmp3=-(tmp1*tmp2)/2
    tmp4=-k_jm1_b*tmp2*k_jm1_l
    tmp5=-(tmp2*k_jm1_l**2)/2
    tmp6=sigma_j_b**2
    tmp7=-(tmp1*tmp6)/2
    tmp8=k_j_b**2
    tmp9=-(tmp6*tmp8)/2
    tmp10=sigma_j_u**2
    tmp11=-(tmp8*tmp10)/2
    tmp12=-k_j_b*tmp10*k_j_u
    tmp13=-(tmp10*k_j_u**2)/2
    tmp14=np.exp(tmp13+tmp12+tmp11+tmp9+tmp7+tmp5+tmp4+tmp3)
    tmp15=1/p_jm1_l
    tmp16=1/p_j_u
    tmp17=2*k_jm1_b*tmp2*k_jm1_l
    tmp18=k_jm1_b*tmp6*k_j_b
    tmp21=np.exp(tmp18)
    tmp19=np.exp(tmp17)*tmp21
    tmp20=p_jm1_l**2
    # tmp21=np.exp(tmp18)
    tmp22=-tmp21
    tmp23=2*k_j_b*tmp10*k_j_u
    # tmp24=np.exp(tmp23+tmp18)
    # tmp24=np.exp(tmp23)*tmp21
    # tmp25=np.exp(tmp23+tmp18+tmp17)
    tmp26=p_j_u**2
    # tmp27=np.exp(tmp13+tmp12+tmp11+tmp9-k_jm1_b*tmp6*k_j_b+tmp7+tmp5+tmp4+tmp3)
    tmp27=tmp14/tmp21
    tmp28=np.exp(tmp17)
    # tmp29=np.exp(tmp23+tmp17)
    tmp30=np.exp(tmp23)
    tmp29=tmp28*tmp30
    tmp24=tmp30*tmp21
    tmp25=tmp30*tmp19
    tmp31=-tmp20
    tmp32=tmp21*tmp20
    tmp33=-tmp21*tmp20
    tmp34=tmp24*tmp20

    X[0, 0]=tmp14*tmp15*tmp16*(((((tmp25*tmp20+tmp24)*r_jm1_l-tmp24)*r_j-tmp24*r_jm1_l+tmp24)*tmp26+(
                (tmp19*tmp20+tmp21)*r_jm1_l+tmp22)*r_j-tmp19*tmp20*r_jm1_l)*r_j_b+(
                                           (tmp22-tmp19*tmp20)*r_jm1_l+tmp21)*r_j+tmp19*tmp20*r_jm1_l)

    X[0, 1]=-tmp27*tmp15*tmp16*(((((tmp28*tmp20+1)*r_jm1_l-1)*r_j-r_jm1_l+1)*tmp26+(
                (tmp29*tmp20+tmp30)*r_jm1_l-tmp30)*r_j-tmp29*tmp20*r_jm1_l)*r_j_b+(
                                            ((-tmp28*tmp20-1)*r_jm1_l+1)*r_j+r_jm1_l-1)*tmp26)

    X[1, 0]=-tmp27*tmp15*tmp16*(((((tmp30*tmp20+tmp29)*r_jm1_l-tmp30*tmp20)*r_j-tmp29*r_jm1_l)*tmp26+(
                (tmp20+tmp28)*r_jm1_l+tmp31)*r_j-tmp20*r_jm1_l+tmp20)*r_j_b+(
                                            (tmp31-tmp28)*r_jm1_l+tmp20)*r_j+tmp20*r_jm1_l+tmp31)

    X[1, 1]=tmp14*tmp15*tmp16*(((((tmp32+tmp19)*r_jm1_l+tmp33)*r_j-tmp19*r_jm1_l)*tmp26+(
                (tmp34+tmp25)*r_jm1_l-tmp24*tmp20)*r_j-tmp24*tmp20*r_jm1_l+tmp34)*r_j_b+(
                                           ((tmp33-tmp19)*r_jm1_l+tmp32)*r_j+tmp19*r_jm1_l)*tmp26)

    return X

def ass_X_interfacelayer3(k_b, k_u, k_l, dd_u, dd_l,
                          sigma, sigma_l, sigma_u, dtype=_ctype):
    '''Function that creates a interfacelayer at the top and bottom
    of the layer. with correlated roughness for the interface layers and the
    additional roughness of sigma_l and sigma_u.
    The subscripts b, l and u reffers to bulk, lower and upper respectively.

    v 0.3
    '''

    # Variables definitions that goes into the expressions:
    k_jm1_b=k_b[..., 1:]
    k_j_b=k_b[..., :-1]
    k_jm1_l=k_l[..., 1:]
    k_j_u=k_u[..., :-1]
    sigma_jm1_l=sigma_l[..., 1:]
    sigma_j_b=sigma[..., :-1]
    sigma_j_u=sigma_u[..., :-1]
    dd_jm1_l=dd_l[..., 1:]
    dd_j_u=dd_u[..., :-1]

    iprint(dd_j_u, dd_jm1_l)

    # Reflectivites
    r_j_b=refl(k_j_b, k_j_u)
    iprint('r_j_b', r_j_b)
    r_jm1_l=refl(k_jm1_l, k_jm1_b)
    iprint('r_jm1_l', r_jm1_l)
    r_j_u=refl(k_j_u, k_jm1_l)
    iprint('r_j_u', r_j_u)
    p_jm1_l=np.exp(-1.0J*dd_jm1_l*k_jm1_l)
    p_j_u=np.exp(-1.0J*dd_j_u*k_j_u)
    # p_j_b = np.exp(-1.0J*dd_j_b*k_j_b)

    # Defining the X matrix
    X=np.empty((2, 2)+k_j_b.shape, dtype=dtype)

    tmp1=k_jm1_b**2
    tmp2=sigma_jm1_l**2
    tmp3=-(tmp1*tmp2)/2
    tmp4=k_jm1_b*tmp2*k_jm1_l
    tmp5=-(tmp2*k_jm1_l**2)/2
    tmp6=sigma_j_b**2
    tmp7=-(tmp1*tmp6)/2
    tmp8=k_jm1_b*tmp6*k_j_b
    tmp9=k_j_b**2
    tmp10=-(tmp6*tmp9)/2
    tmp11=sigma_j_u**2
    tmp12=-(tmp9*tmp11)/2
    tmp13=-k_j_b*tmp11*k_j_u
    tmp14=-(tmp11*k_j_u**2)/2
    tmp15=np.exp(tmp14+tmp13+tmp12+tmp10+tmp8+tmp7+tmp5+tmp4+tmp3)
    tmp16=1/p_j_u
    tmp17=-k_jm1_b*tmp2*k_jm1_l
    tmp18=np.exp(tmp14+tmp13+tmp12+tmp10+tmp8+tmp7+tmp5+tmp17+tmp3)
    tmp19=1/p_jm1_l
    tmp20=k_j_b*tmp11*k_j_u
    tmp21=np.exp(tmp14+tmp20+tmp12+tmp10+tmp8+tmp7+tmp5+tmp17+tmp3)
    tmp22=np.exp(tmp14+tmp20+tmp12+tmp10+tmp8+tmp7+tmp5+tmp4+tmp3)
    tmp23=-k_jm1_b*tmp6*k_j_b
    tmp24=np.exp(tmp14+tmp13+tmp12+tmp10+tmp23+tmp7+tmp5+tmp17+tmp3)
    tmp25=np.exp(tmp14+tmp13+tmp12+tmp10+tmp23+tmp7+tmp5+tmp4+tmp3)
    tmp26=np.exp(tmp14+tmp20+tmp12+tmp10+tmp23+tmp7+tmp5+tmp4+tmp3)
    tmp27=np.exp(tmp14+tmp20+tmp12+tmp10+tmp23+tmp7+tmp5+tmp17+tmp3)

    X[
        0, 0]=tmp22*p_jm1_l*r_jm1_l*r_j_b*p_j_u*r_j_u+tmp21*tmp19*r_jm1_l*r_j_b*p_j_u*r_j_u-tmp21*tmp19*r_j_b*p_j_u*r_j_u-tmp21*tmp19*r_jm1_l*p_j_u*r_j_u+tmp21*tmp19*p_j_u*r_j_u+tmp15*p_jm1_l*r_jm1_l*r_j_b*tmp16*r_j_u+tmp18*tmp19*r_jm1_l*r_j_b*tmp16*r_j_u-tmp18*tmp19*r_j_b*tmp16*r_j_u-tmp15*p_jm1_l*r_jm1_l*tmp16*r_j_u-tmp15*p_jm1_l*r_jm1_l*r_j_b*tmp16-tmp18*tmp19*r_jm1_l*r_j_b*tmp16+tmp18*tmp19*r_j_b*tmp16+tmp15*p_jm1_l*r_jm1_l*tmp16

    X[
        0, 1]=-tmp25*p_jm1_l*r_jm1_l*r_j_b*p_j_u*r_j_u-tmp24*tmp19*r_jm1_l*r_j_b*p_j_u*r_j_u+tmp24*tmp19*r_j_b*p_j_u*r_j_u+tmp24*tmp19*r_jm1_l*p_j_u*r_j_u-tmp24*tmp19*p_j_u*r_j_u-tmp26*p_jm1_l*r_jm1_l*r_j_b*tmp16*r_j_u-tmp27*tmp19*r_jm1_l*r_j_b*tmp16*r_j_u+tmp27*tmp19*r_j_b*tmp16*r_j_u+tmp26*p_jm1_l*r_jm1_l*tmp16*r_j_u+tmp25*p_jm1_l*r_jm1_l*r_j_b*p_j_u+tmp24*tmp19*r_jm1_l*r_j_b*p_j_u-tmp24*tmp19*r_j_b*p_j_u-tmp24*tmp19*r_jm1_l*p_j_u+tmp24*tmp19*p_j_u

    X[
        1, 0]=-tmp27*p_jm1_l*r_jm1_l*r_j_b*p_j_u*r_j_u-tmp26*tmp19*r_jm1_l*r_j_b*p_j_u*r_j_u+tmp27*p_jm1_l*r_j_b*p_j_u*r_j_u+tmp26*tmp19*r_jm1_l*p_j_u*r_j_u-tmp24*p_jm1_l*r_jm1_l*r_j_b*tmp16*r_j_u-tmp25*tmp19*r_jm1_l*r_j_b*tmp16*r_j_u+tmp24*p_jm1_l*r_j_b*tmp16*r_j_u+tmp24*p_jm1_l*r_jm1_l*tmp16*r_j_u-tmp24*p_jm1_l*tmp16*r_j_u+tmp24*p_jm1_l*r_jm1_l*r_j_b*tmp16+tmp25*tmp19*r_jm1_l*r_j_b*tmp16-tmp24*p_jm1_l*r_j_b*tmp16-tmp24*p_jm1_l*r_jm1_l*tmp16+tmp24*p_jm1_l*tmp16

    X[
        1, 1]=tmp18*p_jm1_l*r_jm1_l*r_j_b*p_j_u*r_j_u+tmp15*tmp19*r_jm1_l*r_j_b*p_j_u*r_j_u-tmp18*p_jm1_l*r_j_b*p_j_u*r_j_u-tmp15*tmp19*r_jm1_l*p_j_u*r_j_u+tmp21*p_jm1_l*r_jm1_l*r_j_b*tmp16*r_j_u+tmp22*tmp19*r_jm1_l*r_j_b*tmp16*r_j_u-tmp21*p_jm1_l*r_j_b*tmp16*r_j_u-tmp21*p_jm1_l*r_jm1_l*tmp16*r_j_u+tmp21*p_jm1_l*tmp16*r_j_u-tmp18*p_jm1_l*r_jm1_l*r_j_b*p_j_u-tmp15*tmp19*r_jm1_l*r_j_b*p_j_u+tmp18*p_jm1_l*r_j_b*p_j_u+tmp15*tmp19*r_jm1_l*p_j_u

    return X

def ass_X_interfacelayer(k_b, k_u, k_l, dd_u, dd_l,
                         sigma, sigma_l, sigma_u, dtype=_ctype):
    '''Function that creates a interfacelayer at the top and bottom
    of the layer. with correlated roughness for the interface layers and the
    additional roughness of sigma_l and sigma_u.
    The subscripts b, l and u reffers to bulk, lower and upper respectively.

    v 0.2
    '''
    iprint(dd_l, dd_u)
    # Variables definitions that goes into the expressions:
    k_jm1_b=k_b[..., 1:]
    k_j_b=k_b[..., :-1]
    k_jm1_l=k_l[..., 1:]
    k_j_u=k_u[..., :-1]
    sigma_jm1_l=sigma_l[..., 1:]
    sigma_j_b=sigma[..., :-1]
    sigma_j_u=sigma_u[..., :-1]
    dd_jm1_l=dd_l[..., 1:]
    dd_j_u=dd_u[..., :-1]

    # Reflectivites
    r_j_b=refl(k_j_b, k_j_u)
    r_jm1_l=refl(k_jm1_l, k_jm1_b)
    r_j_u=refl(k_j_u, k_jm1_l)
    p_jm1_l=np.exp(-1.0J*dd_jm1_l*k_jm1_b)
    p_j_u=np.exp(-1.0J*dd_j_u*k_j_u)
    # p_j_b = np.exp(-1.0J*dd_j_b*k_j_b)

    # Defining the X matrix
    X=np.empty((2, 2)+k_j_b.shape, dtype=dtype)

    tmp1=k_jm1_b**2
    tmp2=sigma_jm1_l**2
    tmp3=-(tmp1*tmp2)/2
    tmp4=-k_jm1_b*tmp2*k_jm1_l
    tmp5=-(tmp2*k_jm1_l**2)/2
    tmp6=sigma_j_b**2
    tmp7=-(tmp1*tmp6)/2
    tmp8=k_j_b**2
    tmp9=-(tmp6*tmp8)/2
    tmp10=sigma_j_u**2
    tmp11=-(tmp8*tmp10)/2
    tmp12=-k_j_b*tmp10*k_j_u
    tmp13=-(tmp10*k_j_u**2)/2
    tmp14=np.exp(tmp13+tmp12+tmp11+tmp9+tmp7+tmp5+tmp4+tmp3)
    tmp15=1/p_jm1_l
    tmp16=1/p_j_u
    tmp17=2*k_jm1_b*tmp2*k_jm1_l
    tmp18=k_jm1_b*tmp6*k_j_b
    tmp21=np.exp(tmp18)
    tmp19=np.exp(tmp17)*tmp21
    tmp20=p_jm1_l**2
    # tmp21=np.exp(tmp18)
    tmp22=-tmp21
    tmp23=2*k_j_b*tmp10*k_j_u
    # tmp24=np.exp(tmp23+tmp18)
    # tmp24=np.exp(tmp23)*tmp21
    # tmp25=np.exp(tmp23+tmp18+tmp17)
    tmp26=p_j_u**2
    # tmp27=np.exp(tmp13+tmp12+tmp11+tmp9-k_jm1_b*tmp6*k_j_b+tmp7+tmp5+tmp4+tmp3)
    tmp27=tmp14/tmp21
    tmp28=np.exp(tmp17)
    # tmp29=np.exp(tmp23+tmp17)
    tmp30=np.exp(tmp23)
    tmp29=tmp28*tmp30
    tmp24=tmp30*tmp21
    tmp25=tmp30*tmp19
    tmp31=-tmp20
    tmp32=tmp21*tmp20
    tmp33=-tmp21*tmp20
    tmp34=tmp24*tmp20

    X[0, 0]=tmp14*tmp15*tmp16*(((((tmp25*tmp20+tmp24)*r_jm1_l-tmp24)*r_j_b-tmp24*r_jm1_l+tmp24)*tmp26+(
                (tmp19*tmp20+tmp21)*r_jm1_l+tmp22)*r_j_b-tmp19*tmp20*r_jm1_l)*r_j_u+(
                                           (tmp22-tmp19*tmp20)*r_jm1_l+tmp21)*r_j_b+tmp19*tmp20*r_jm1_l)

    X[0, 1]=-tmp27*tmp15*tmp16*(((((tmp28*tmp20+1)*r_jm1_l-1)*r_j_b-r_jm1_l+1)*tmp26+(
                (tmp29*tmp20+tmp30)*r_jm1_l-tmp30)*r_j_b-tmp29*tmp20*r_jm1_l)*r_j_u+(
                                            ((-tmp28*tmp20-1)*r_jm1_l+1)*r_j_b+r_jm1_l-1)*tmp26)

    X[1, 0]=-tmp27*tmp15*tmp16*(((((tmp30*tmp20+tmp29)*r_jm1_l-tmp30*tmp20)*r_j_b-tmp29*r_jm1_l)*tmp26+(
                (tmp20+tmp28)*r_jm1_l+tmp31)*r_j_b-tmp20*r_jm1_l+tmp20)*r_j_u+(
                                            (tmp31-tmp28)*r_jm1_l+tmp20)*r_j_b+tmp20*r_jm1_l+tmp31)

    X[1, 1]=tmp14*tmp15*tmp16*(((((tmp32+tmp19)*r_jm1_l+tmp33)*r_j_b-tmp19*r_jm1_l)*tmp26+(
                (tmp34+tmp25)*r_jm1_l-tmp24*tmp20)*r_j_b-tmp24*tmp20*r_jm1_l+tmp34)*r_j_u+(
                                           ((tmp33-tmp19)*r_jm1_l+tmp32)*r_j_b+tmp19*r_jm1_l)*tmp26)

    return X

def ass_X_interfacelayer1(k_b, k_u, k_l, dd_u, dd_l,
                          sigma, sigma_l, sigma_u, dtype=_ctype):
    '''Function that creates a interfacelayer at the top and bottom
    of the layer. with correlated roughness for the interface layers and the
    additional roughness of sigma_l and sigma_u.
    The subscripts b, l and u reffers to bulk, lower and upper respectively.

    v 0.1
    '''

    # Variables definitions that goes into the expressions:
    k_jm1_b=k_b[..., 1:]
    k_j_b=k_b[..., :-1]
    k_jm1_l=k_l[..., 1:]
    k_j_u=k_u[..., :-1]
    sigma_jm1_l=sigma_l[..., 1:]
    sigma_j_b=sigma[..., :-1]
    sigma_j_u=sigma_u[..., :-1]
    dd_jm1_l=dd_u[..., 1:]
    dd_j_u=dd_u[..., :-1]

    # Defining the X matrix
    X=np.empty((2, 2)+k_j_b.shape, dtype=dtype)

    # Temporary variables to ease the calculation
    tmp1=k_jm1_b*k_jm1_b
    tmp2=sigma_jm1_l*sigma_jm1_l
    tmp3=tmp1*tmp2
    tmp4=(2*k_jm1_b*tmp2+2*1.0J*dd_jm1_l)*k_jm1_l
    tmp5=k_jm1_l*k_jm1_l
    tmp6=tmp2*tmp5
    tmp7=sigma_j_b*sigma_j_b
    tmp8=tmp1*tmp7
    tmp9=k_j_b**2
    tmp10=tmp7*tmp9
    tmp11=sigma_j_u*sigma_j_u
    tmp12=tmp9*tmp11
    tmp13=(2*k_j_b*tmp11+2*1.0J*dd_j_u)*k_j_u
    tmp14=k_j_u*k_j_u
    tmp15=tmp11*tmp14
    tmp16=1/np.exp((tmp15+tmp13+tmp12+tmp10+tmp8+tmp6+tmp4+tmp3)/2)
    tmp17=1/k_jm1_b
    tmp18=1/k_jm1_l
    tmp19=1/k_j_u
    tmp20=np.exp(2*1.0J*dd_jm1_l*k_jm1_l)
    tmp21=-tmp20
    tmp22=np.exp(2*k_jm1_b*tmp2*k_jm1_l)
    tmp23=-tmp22
    tmp24=tmp23+tmp21
    tmp25=k_jm1_b*tmp7*k_j_b
    tmp26=2*1.0J*dd_j_u*k_j_u
    tmp27=np.exp(tmp26+tmp25)
    tmp28=tmp22+tmp20
    tmp29=2*k_j_b*tmp11*k_j_u
    tmp30=np.exp(tmp29+tmp25)
    tmp31=tmp28*tmp30
    tmp32=tmp31+tmp24*tmp27
    tmp33=tmp23+tmp20
    tmp34=tmp22+tmp21
    tmp35=tmp34*tmp30
    tmp36=tmp35+tmp33*tmp27
    tmp37=tmp31+tmp28*tmp27
    tmp38=tmp35+tmp34*tmp27
    tmp39=1/np.exp((tmp15+tmp13+tmp12+tmp10+2*k_jm1_b*tmp7*k_j_b+tmp8+tmp6+tmp4+tmp3)/2)
    tmp40=np.exp(tmp13)
    tmp41=tmp24*tmp40
    tmp42=tmp33*tmp40
    tmp43=tmp34*tmp40
    tmp44=tmp28*tmp40
    tmp45=np.exp(tmp4)
    tmp46=tmp45+1
    tmp47=np.exp(tmp26)
    tmp48=tmp46*tmp47
    tmp49=-tmp45
    tmp50=tmp49-1
    tmp51=np.exp(tmp29)
    tmp52=tmp50*tmp51
    tmp53=tmp45-1
    tmp54=tmp53*tmp47
    tmp55=tmp49+1
    tmp56=tmp55*tmp51
    tmp57=tmp50*tmp47
    tmp58=tmp55*tmp47
    tmp59=tmp53*tmp51
    tmp60=tmp46*tmp51
    tmp61=np.exp(tmp25)
    tmp62=np.exp(tmp13+tmp25)
    tmp63=tmp46*tmp62
    tmp64=tmp63+tmp50*tmp61
    tmp65=tmp53*tmp62
    tmp66=tmp65+tmp55*tmp61
    tmp67=tmp63+tmp46*tmp61
    tmp68=tmp65+tmp53*tmp61

    # Assembling the interface matrices
    X[0, 0]=(tmp16*tmp17*tmp18*tmp19*((tmp32*k_jm1_l+tmp36*k_jm1_b)*tmp14+(
                (tmp37*k_jm1_l+tmp38*k_jm1_b)*k_j_b+tmp38*tmp5+tmp37*k_jm1_b*k_jm1_l)*k_j_u+(
                                                  tmp36*tmp5+tmp32*k_jm1_b*k_jm1_l)*k_j_b))/8

    X[0, 1]=-(tmp39*tmp17*tmp18*tmp19*(((tmp44+tmp23+tmp21)*k_jm1_l+(tmp43+tmp23+tmp20)*k_jm1_b)*tmp14+(
                ((tmp44+tmp22+tmp20)*k_jm1_l+(tmp43+tmp22+tmp21)*k_jm1_b)*k_j_b+(tmp42+tmp23+tmp20)*tmp5+(
                    tmp41+tmp23+tmp21)*k_jm1_b*k_jm1_l)*k_j_u+((tmp42+tmp22+tmp21)*tmp5+(
                tmp41+tmp22+tmp20)*k_jm1_b*k_jm1_l)*k_j_b))/8

    X[1, 0]=-(tmp39*tmp17*tmp18*tmp19*(((tmp60+tmp57)*k_jm1_l+(tmp59+tmp58)*k_jm1_b)*tmp14+(
                ((tmp60+tmp48)*k_jm1_l+(tmp59+tmp54)*k_jm1_b)*k_j_b+(tmp56+tmp58)*tmp5+(
                    tmp52+tmp57)*k_jm1_b*k_jm1_l)*k_j_u+((tmp56+tmp54)*tmp5+(tmp52+tmp48)*k_jm1_b*k_jm1_l)*k_j_b))/8

    X[1, 1]=(tmp16*tmp17*tmp18*tmp19*((tmp64*k_jm1_l+tmp66*k_jm1_b)*tmp14+(
                (tmp67*k_jm1_l+tmp68*k_jm1_b)*k_j_b+tmp68*tmp5+tmp67*k_jm1_b*k_jm1_l)*k_j_u+(
                                                  tmp66*tmp5+tmp64*k_jm1_b*k_jm1_l)*k_j_b))/8

    return X
