// File: /workspace/github_cpp_makefile_star2_O2/dfrodriguezp[P]PiCM-cpp/functions.cc
// Function: potential(std::vector<std::valarray<double>, std::allocator<std::valarray<double>>> const&, double const&, double const&, unsigned int const&, unsigned int const&)
VecArr potential(const VecArr &rho, const Real &dx, const Real &dy,
                 const Int &Nx, const Int &Ny)
{
    Complex rho_k[Nx][Ny];

    for (Int i = 0; i < Nx; ++i)
    {
        for (Int j = 0; j < Ny; ++j)
        {
            rho_k[i][j] = rho[i][j];
        }
    }

    CArray f(Nx);
    CArray g(Ny);

    for (Int i = 0; i < Nx; ++i)
    {
        for (Int j = 0; j < Ny; ++j)
        {
            g[j] = rho_k[i][j];
        }
        fft(g);
        for (Int j = 0; j < Ny; ++j)
        {
            rho_k[i][j] = g[j];
        }
    }

    for (Int j = 0; j < Ny; ++j)
    {
        for (Int i = 0; i < Nx; ++i)
        {
            f[i] = rho_k[i][j];
        }
        fft(f);
        for (Int i = 0; i < Nx; ++i)
        {
            rho_k[i][j] = f[i];
        }
    }

    Complex phi_k[Nx][Ny];

    for (Int i = 0; i < Nx; ++i)
    {
        for (Int j = 0; j < Ny; ++j)
        {
            phi_k[i][j] = rho_k[i][j];
        }
    }

    Complex i(0.0, 1.0);
    Complex Wx = std::exp(2.0 * std::acos(-1.0) * i / Real(Nx));
    Complex Wy = std::exp(2.0 * std::acos(-1.0) * i / Real(Ny));
    Complex Wn = 1.0;
    Complex Wm = 1.0;
    Real dx_2 = dx * dx;
    Real dy_2 = dy * dy;

    for (Int n = 0; n < Nx; ++n)
    {
        for (Int m = 0; m < Ny; ++m)
        {
            Complex denom = dy_2 * (2.0 - Wn - 1.0 / Wn) + dx_2 * (2.0 - Wm - 1.0 / Wm);
            if (denom != 0.0)
            {
                phi_k[n][m] *= (dx_2 * dy_2) / denom;
            }
            Wm *= Wy;
        }
        Wn *= Wx;
    }

    for (Int i = 0; i < Nx; ++i)
    {
        for (Int j = 0; j < Ny; ++j)
        {
            g[j] = phi_k[i][j];
        }
        ifft(g);
        for (Int j = 0; j < Ny; ++j)
        {
            phi_k[i][j] = g[j];
        }
    }

    for (Int j = 0; j < Ny; ++j)
    {
        for (Int i = 0; i < Nx; ++i)
        {
            f[i] = phi_k[i][j];
        }
        ifft(f);
        for (Int i = 0; i < Nx; ++i)
        {
            phi_k[i][j] = f[i];
        }
    }

    VecArr phi = valarraysVector(Nx, Ny);
    for (Int i = 0; i < Nx; ++i)
    {
        for (Int j = 0; j < Ny; ++j)
        {
            phi[i][j] = std::real(phi_k[i][j]);
        }
    }

    return phi;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x138, %rsp            # imm = 0x138
movq %r8, %r14
movq %rcx, -0x68(%rbp)
movq %rdx, -0xb0(%rbp)
movq %rsi, %r15
movq %rdi, -0xb8(%rbp)
movl (%r8), %ebx
movq %r9, -0x38(%rbp)
movl (%r9), %r12d
movq %r12, %rax
imulq %rbx, %rax
movq %rax, %rdx
shlq $0x4, %rdx
movq %rsp, %r13
subq %rdx, %r13
movq %r13, %rsp
testq %rax, %rax
je 0x64fc
movq %r13, %rdi
xorl %esi, %esi
callq 0x2130
movq (%r15), %rax
leaq (,%r12,8), %rcx
leaq 0x8(%r13), %rdx
shlq $0x4, %r12
xorl %esi, %esi
cmpq %rbx, %rsi
je 0x654f
movq %rsi, %rdi
shlq $0x4, %rdi
addq %rax, %rdi
addq $0x8, %rdi
xorl %r8d, %r8d
cmpq %r8, %rcx
je 0x6547
movq (%rdi), %r9
movsd (%r9,%r8), %xmm0
movsd %xmm0, -0x8(%rdx,%r8,2)
andq $0x0, (%rdx,%r8,2)
addq $0x8, %r8
jmp 0x6527
incq %rsi
addq %r12, %rdx
jmp 0x6511
movq %r14, -0x30(%rbp)
leaq -0x58(%rbp), %rdi
movq %rbx, %rsi
callq 0x77a2
movq -0x38(%rbp), %rax
movl (%rax), %esi
leaq -0x48(%rbp), %rdi
callq 0x77a2
xorl %r14d, %r14d
leaq -0x48(%rbp), %rbx
movq %r13, %r15
movq -0x30(%rbp), %rax
movl (%rax), %eax
cmpq %rax, %r14
jae 0x65e0
xorl %eax, %eax
xorl %ecx, %ecx
movq -0x38(%rbp), %rdx
movl (%rdx), %edx
cmpq %rdx, %rcx
jae 0x65aa
movq -0x40(%rbp), %rdx
movupd (%r15,%rax), %xmm0
movupd %xmm0, (%rdx,%rax)
incq %rcx
addq $0x10, %rax
jmp 0x6587
movq %rbx, %rdi
callq 0x5dec
movq -0x38(%rbp), %rax
movl (%rax), %eax
movq -0x40(%rbp), %rcx
shlq $0x4, %rax
xorl %edx, %edx
cmpq %rdx, %rax
je 0x65d8
movupd (%rcx,%rdx), %xmm0
movupd %xmm0, (%r15,%rdx)
addq $0x10, %rdx
jmp 0x65c2
incq %r14
addq %r12, %r15
jmp 0x6578
xorl %r15d, %r15d
movq %r13, %rbx
movq -0x38(%rbp), %rcx
movl (%rcx), %r14d
cmpq %r14, %r15
jae 0x665c
xorl %ecx, %ecx
movq %rbx, %rdx
xorl %esi, %esi
movq -0x30(%rbp), %r14
movl %eax, %eax
cmpq %rax, %rsi
jae 0x6620
movq -0x50(%rbp), %rax
movupd (%rdx), %xmm0
movupd %xmm0, (%rax,%rcx)
incq %rsi
movl (%r14), %eax
addq %r12, %rdx
addq $0x10, %rcx
jmp 0x65fd
leaq -0x58(%rbp), %rdi
callq 0x5dec
movl (%r14), %eax
movq -0x50(%rbp), %rcx
movq %rax, %rdx
shlq $0x4, %rdx
movq %rbx, %rsi
xorl %edi, %edi
cmpq %rdi, %rdx
je 0x6653
movupd (%rcx,%rdi), %xmm0
movupd %xmm0, (%rsi)
addq $0x10, %rdi
addq %r12, %rsi
jmp 0x663c
incq %r15
addq $0x10, %rbx
jmp 0x65e6
movl %eax, %ebx
movq %rbx, %rax
imulq %r14, %rax
movq %rax, %rdx
shlq $0x4, %rdx
movq %rsp, %r15
subq %rdx, %r15
movq %r15, %rsp
testq %rax, %rax
je 0x6684
movq %r15, %rdi
xorl %esi, %esi
callq 0x2130
shlq $0x4, %r14
xorl %eax, %eax
movq %r15, %rcx
cmpq %rbx, %rax
je 0x66b4
xorl %edx, %edx
cmpq %rdx, %r14
je 0x66a9
movaps (%r13,%rdx), %xmm0
movaps %xmm0, (%rcx,%rdx)
addq $0x10, %rdx
jmp 0x6694
incq %rax
addq %r12, %r13
addq %r14, %rcx
jmp 0x668d
cvtsi2sd %rbx, %xmm0
unpcklpd %xmm0, %xmm0            # xmm0 = xmm0[0,0]
xorpd %xmm1, %xmm1
movhpd 0x2db7(%rip), %xmm1     # xmm1 = xmm1[0],mem[0]
movapd %xmm1, -0xa0(%rbp)
divpd %xmm0, %xmm1
leaq -0xf0(%rbp), %rdi
movapd %xmm1, (%rdi)
callq 0x77de
movsd %xmm0, -0x100(%rbp)
movsd %xmm1, -0xf8(%rbp)
movq -0x38(%rbp), %rax
movl (%rax), %eax
cvtsi2sd %rax, %xmm0
unpcklpd %xmm0, %xmm0            # xmm0 = xmm0[0,0]
movapd -0xa0(%rbp), %xmm1
divpd %xmm0, %xmm1
leaq -0x80(%rbp), %rdi
movapd %xmm1, (%rdi)
callq 0x77de
leaq -0xf0(%rbp), %rax
movsd %xmm0, (%rax)
movsd %xmm1, 0x8(%rax)
movsd 0x28db(%rip), %xmm0     # 0x9010
leaq -0x80(%rbp), %rax
movaps %xmm0, (%rax)
leaq -0xe0(%rbp), %r12
movaps %xmm0, (%r12)
movq -0xb0(%rbp), %rax
movsd (%rax), %xmm0
movq -0x68(%rbp), %rax
movhpd (%rax), %xmm0           # xmm0 = xmm0[0],mem[0]
mulpd %xmm0, %xmm0
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
mulsd %xmm0, %xmm1
movapd %xmm1, -0x110(%rbp)
movapd %xmm0, -0x130(%rbp)
shufpd $0x1, %xmm0, %xmm0      # xmm0 = xmm0[1,0]
movapd %xmm0, -0x120(%rbp)
xorl %ecx, %ecx
movabsq $0x3ff0000000000000, %r13 # imm = 0x3FF0000000000000
movq %r15, -0x60(%rbp)
movq -0x30(%rbp), %rax
movl (%rax), %eax
cmpq %rax, %rcx
jae 0x6949
movq %rcx, -0xc8(%rbp)
movq %r15, -0xc0(%rbp)
xorl %ebx, %ebx
movq -0x38(%rbp), %rax
movl (%rax), %eax
cmpq %rax, %rbx
jae 0x6920
movsd -0x80(%rbp), %xmm0
movsd %xmm0, -0x68(%rbp)
movsd -0x78(%rbp), %xmm0
movapd %xmm0, -0xb0(%rbp)
movq %r13, -0x90(%rbp)
leaq -0x90(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x77ec
movapd %xmm1, -0x150(%rbp)
movapd %xmm0, -0xa0(%rbp)
movsd -0xe0(%rbp), %xmm0
movsd %xmm0, -0xd0(%rbp)
movsd -0xd8(%rbp), %xmm0
movapd %xmm0, -0x140(%rbp)
movq %r13, -0x70(%rbp)
leaq -0x70(%rbp), %rdi
movq %r12, %rsi
callq 0x77ec
movsd 0x2c4c(%rip), %xmm3     # 0x9488
movapd %xmm3, %xmm2
subsd -0xd0(%rbp), %xmm2
movapd 0x2c60(%rip), %xmm4     # 0x94b0
movapd -0x140(%rbp), %xmm6
xorpd %xmm4, %xmm6
movapd -0xb0(%rbp), %xmm5
xorpd %xmm4, %xmm5
unpcklpd %xmm5, %xmm2            # xmm2 = xmm2[0],xmm5[0]
subsd -0x68(%rbp), %xmm3
unpcklpd %xmm6, %xmm3            # xmm3 = xmm3[0],xmm6[0]
unpcklpd -0x150(%rbp), %xmm0     # xmm0 = xmm0[0],mem[0]
subpd %xmm0, %xmm2
movapd -0xa0(%rbp), %xmm0
unpcklpd %xmm1, %xmm0            # xmm0 = xmm0[0],xmm1[0]
subpd %xmm0, %xmm3
mulpd -0x120(%rbp), %xmm3
mulpd -0x130(%rbp), %xmm2
addpd %xmm3, %xmm2
movapd %xmm2, -0x160(%rbp)
ucomisd 0x277b(%rip), %xmm2     # 0x9030
jne 0x68c9
jp 0x68c9
unpckhpd %xmm2, %xmm2            # xmm2 = xmm2[1,1]
ucomisd 0x276b(%rip), %xmm2     # 0x9030
jne 0x68c9
jnp 0x6905
movapd -0x110(%rbp), %xmm0
movsd %xmm0, -0x70(%rbp)
leaq -0x70(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0x77ec
movsd %xmm0, -0x90(%rbp)
movsd %xmm1, -0x88(%rbp)
movq %r15, %rdi
leaq -0x90(%rbp), %rsi
callq 0x7818
movq %r12, %rdi
leaq -0xf0(%rbp), %rsi
callq 0x7818
incq %rbx
addq $0x10, %r15
jmp 0x67b7
leaq -0x80(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0x7818
movq -0xc8(%rbp), %rcx
incq %rcx
movq -0xc0(%rbp), %r15
addq %r14, %r15
jmp 0x6798
xorl %r15d, %r15d
leaq -0x48(%rbp), %rbx
movq -0x60(%rbp), %r12
movq -0x38(%rbp), %r13
movl %eax, %ecx
cmpq %rcx, %r15
jae 0x69be
xorl %eax, %eax
xorl %ecx, %ecx
movl (%r13), %edx
cmpq %rdx, %rcx
jae 0x6984
movq -0x40(%rbp), %rdx
movupd (%r12,%rax), %xmm0
movupd %xmm0, (%rdx,%rax)
incq %rcx
addq $0x10, %rax
jmp 0x6963
movq %rbx, %rdi
callq 0x5f77
movl (%r13), %eax
movq -0x40(%rbp), %rcx
shlq $0x4, %rax
xorl %edx, %edx
cmpq %rdx, %rax
je 0x69b0
movupd (%rcx,%rdx), %xmm0
movupd %xmm0, (%r12,%rdx)
addq $0x10, %rdx
jmp 0x699a
incq %r15
movq -0x30(%rbp), %rax
movl (%rax), %eax
addq %r14, %r12
jmp 0x6958
xorl %r15d, %r15d
leaq -0x58(%rbp), %rbx
movq -0x60(%rbp), %r12
movl (%r13), %ecx
cmpq %rcx, %r15
jae 0x6a3d
xorl %ecx, %ecx
movq %r12, %rdx
xorl %esi, %esi
movl %eax, %eax
cmpq %rax, %rsi
jae 0x69ff
movq -0x50(%rbp), %rax
movupd (%rdx), %xmm0
movupd %xmm0, (%rax,%rcx)
incq %rsi
movq -0x30(%rbp), %rax
movl (%rax), %eax
addq %r14, %rdx
addq $0x10, %rcx
jmp 0x69d9
movq %rbx, %rdi
callq 0x5f77
movq -0x30(%rbp), %rax
movl (%rax), %eax
movq -0x50(%rbp), %rcx
movq %rax, %rdx
shlq $0x4, %rdx
movq %r12, %rsi
xorl %edi, %edi
cmpq %rdi, %rdx
je 0x6a34
movupd (%rcx,%rdi), %xmm0
movupd %xmm0, (%rsi)
addq $0x10, %rdi
addq %r14, %rsi
jmp 0x6a1d
incq %r15
addq $0x10, %r12
jmp 0x69c9
movq -0xb8(%rbp), %rbx
movq %rbx, %rdi
movq -0x30(%rbp), %r15
movq %r15, %rsi
movq %r13, %rdx
callq 0x60c5
movl (%r15), %eax
movl (%r13), %ecx
shlq $0x3, %rcx
xorl %edx, %edx
movq -0x60(%rbp), %r9
cmpq %rax, %rdx
je 0x6aa1
movq (%rbx), %rsi
movq %rdx, %rdi
shlq $0x4, %rdi
addq %rdi, %rsi
addq $0x8, %rsi
xorl %edi, %edi
cmpq %rdi, %rcx
je 0x6a99
movsd (%r9,%rdi,2), %xmm0
movq (%rsi), %r8
movsd %xmm0, (%r8,%rdi)
addq $0x8, %rdi
jmp 0x6a7f
incq %rdx
addq %r14, %r9
jmp 0x6a67
movq -0x40(%rbp), %rdi
callq 0x2230
movq -0x50(%rbp), %rdi
callq 0x2230
movq %rbx, %rax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x6adc
jmp 0x6adc
jmp 0x6adc
movq %rax, %rbx
jmp 0x6ae8
jmp 0x6adc
jmp 0x6adc
jmp 0x6adc
jmp 0x6adc
jmp 0x6adc
jmp 0x6adc
movq %rax, %rbx
movq -0x40(%rbp), %rdi
callq 0x2230
movq -0x50(%rbp), %rdi
callq 0x2230
movq %rbx, %rdi
callq 0x2430