// File: shuwenyue[P]MD_code_cell_list/particle.cpp
// Function: particle::verlet(double, double, double, std::vector<vec3<double>, std::allocator<vec3<double>>>)
double particle::verlet(double dt, double NParticles, double BoxLength, vector<double3> forceV)
{
	// define variable: total velocities in each direction, total velocity^2, new positions, particle velocities
    double totalVx = 0;
    double totalVy = 0;
    double totalVz = 0;
    double totalV2 = 0;
    double newX = 0;
    double newY = 0;
    double newZ = 0;
    double velocityx = 0;
    double velocityy = 0;
    double velocityz = 0;
    
    // define objects to use functions in other classes 
    force forceObj;
	box boxObj;

	// loop through all particles to determine new positions
    for (int a = 0; a < NParticles; a++)
    {
		// calculate new position coordinates from verlet algorithm
        newX = 2 * positionVector[a].x - positionPrevVector[a].x + dt*dt * forceV[a].x;
        newY = 2 * positionVector[a].y - positionPrevVector[a].y + dt*dt * forceV[a].y;
        newZ = 2 * positionVector[a].z - positionPrevVector[a].z + dt*dt * forceV[a].z;

		// periodic boundary conditions
		newX = boxObj.pbc(newX,BoxLength);
		newY = boxObj.pbc(newY,BoxLength);
		newZ = boxObj.pbc(newZ,BoxLength);

        // calculate new velocity from verlet algorithm
        velocityx = (boxObj.boundaries(newX - positionPrevVector[a].x,BoxLength))/(2*dt);
        velocityy = (boxObj.boundaries(newY - positionPrevVector[a].y,BoxLength))/(2*dt);
        velocityz = (boxObj.boundaries(newZ - positionPrevVector[a].z,BoxLength))/(2*dt);

        // velocity center of mass
        //totalVx = totalVx + velocityx;
        //totalVy = totalVy + velocityy;
        //totalVz = totalVz + velocityz;
        
        // use velocity^2 to calculate total kinetic energy
        totalV2 = totalV2 + velocityx*velocityx + velocityy*velocityy + velocityz*velocityz;

		// define new positions as current positions, current positions as previous positions
        positionPrevVector[a].x = positionVector[a].x;
        positionPrevVector[a].y = positionVector[a].y;
        positionPrevVector[a].z = positionVector[a].z;
        positionVector[a].x = boxObj.pbc(newX,BoxLength);
        positionVector[a].y = boxObj.pbc(newY,BoxLength);
        positionVector[a].z = boxObj.pbc(newZ,BoxLength);
    }
    
	// return total velocity^2
    return totalV2;
}

// Assembly:
subq $0x218, %rsp            # imm = 0x218
movq %rsi, 0xe8(%rsp)
movq %rdi, 0x210(%rsp)
movsd %xmm0, 0x208(%rsp)
movsd %xmm1, 0x200(%rsp)
movsd %xmm2, 0x1f8(%rsp)
movq %rsi, 0x1f0(%rsp)
movq 0x210(%rsp), %rax
movq %rax, 0xf0(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x1e8(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x1e0(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x1d8(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x1d0(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x1c8(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x1c0(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x1b8(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x1b0(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x1a8(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x1a0(%rsp)
leaq 0x110(%rsp), %rdi
callq 0x3160
movl $0x0, 0x108(%rsp)
cvtsi2sdl 0x108(%rsp), %xmm1
movsd 0x200(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x4ff7
movq 0xf0(%rsp), %rdi
addq $0x18, %rdi
movq %rdi, 0xb8(%rsp)
movslq 0x108(%rsp), %rsi
callq 0x3350
movq 0xf0(%rsp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, 0x88(%rsp)
addq $0x30, %rdi
movq %rdi, 0xc0(%rsp)
movslq 0x108(%rsp), %rsi
callq 0x3350
movsd 0x88(%rsp), %xmm0
movq 0xe8(%rsp), %rdi
movsd (%rax), %xmm1
addsd %xmm0, %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, 0x98(%rsp)
movsd 0x208(%rsp), %xmm0
mulsd %xmm0, %xmm0
movsd %xmm0, 0x90(%rsp)
movslq 0x108(%rsp), %rsi
callq 0x3350
movsd 0x90(%rsp), %xmm0
movsd 0x98(%rsp), %xmm1
movq 0xb8(%rsp), %rdi
movsd (%rax), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x1c8(%rsp)
movslq 0x108(%rsp), %rsi
callq 0x3350
movq 0xc0(%rsp), %rdi
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0xa0(%rsp)
movslq 0x108(%rsp), %rsi
callq 0x3350
movsd 0xa0(%rsp), %xmm0
movq 0xe8(%rsp), %rdi
movsd 0x8(%rax), %xmm1
addsd %xmm0, %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, 0xb0(%rsp)
movsd 0x208(%rsp), %xmm0
mulsd %xmm0, %xmm0
movsd %xmm0, 0xa8(%rsp)
movslq 0x108(%rsp), %rsi
callq 0x3350
movsd 0xa8(%rsp), %xmm0
movsd 0xb0(%rsp), %xmm1
movq 0xb8(%rsp), %rdi
movsd 0x8(%rax), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x1c0(%rsp)
movslq 0x108(%rsp), %rsi
callq 0x3350
movq 0xc0(%rsp), %rdi
movsd 0x10(%rax), %xmm0
movsd %xmm0, 0xc8(%rsp)
movslq 0x108(%rsp), %rsi
callq 0x3350
movsd 0xc8(%rsp), %xmm0
movq 0xe8(%rsp), %rdi
movsd 0x10(%rax), %xmm1
addsd %xmm0, %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, 0xd8(%rsp)
movsd 0x208(%rsp), %xmm0
mulsd %xmm0, %xmm0
movsd %xmm0, 0xd0(%rsp)
movslq 0x108(%rsp), %rsi
callq 0x3350
movsd 0xd0(%rsp), %xmm0
movsd 0xd8(%rsp), %xmm1
movsd 0x10(%rax), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x1b8(%rsp)
movsd 0x1c8(%rsp), %xmm0
movsd 0x1f8(%rsp), %xmm1
leaq 0x10f(%rsp), %rdi
callq 0x89a0
movsd %xmm0, 0xe0(%rsp)
jmp 0x4bf3
movsd 0xe0(%rsp), %xmm0
movsd %xmm0, 0x1c8(%rsp)
movsd 0x1c0(%rsp), %xmm0
movsd 0x1f8(%rsp), %xmm1
leaq 0x10f(%rsp), %rdi
callq 0x89a0
movsd %xmm0, 0x80(%rsp)
jmp 0x4c2f
movsd 0x80(%rsp), %xmm0
movsd %xmm0, 0x1c0(%rsp)
movsd 0x1b8(%rsp), %xmm0
movsd 0x1f8(%rsp), %xmm1
leaq 0x10f(%rsp), %rdi
callq 0x89a0
movsd %xmm0, 0x78(%rsp)
jmp 0x4c68
movq 0xf0(%rsp), %rdi
movsd 0x78(%rsp), %xmm0
movsd %xmm0, 0x1b8(%rsp)
movsd 0x1c8(%rsp), %xmm0
movsd %xmm0, 0x68(%rsp)
addq $0x30, %rdi
movslq 0x108(%rsp), %rsi
callq 0x3350
movsd 0x68(%rsp), %xmm0
movsd (%rax), %xmm1
subsd %xmm1, %xmm0
movsd 0x1f8(%rsp), %xmm1
leaq 0x10f(%rsp), %rdi
callq 0x8900
movsd %xmm0, 0x70(%rsp)
jmp 0x4ccb
movq 0xf0(%rsp), %rdi
movsd 0x70(%rsp), %xmm0
movsd 0x208(%rsp), %xmm1
addsd %xmm1, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x1b0(%rsp)
movsd 0x1c0(%rsp), %xmm0
movsd %xmm0, 0x58(%rsp)
addq $0x30, %rdi
movslq 0x108(%rsp), %rsi
callq 0x3350
movsd 0x58(%rsp), %xmm0
movsd 0x8(%rax), %xmm1
subsd %xmm1, %xmm0
movsd 0x1f8(%rsp), %xmm1
leaq 0x10f(%rsp), %rdi
callq 0x8900
movsd %xmm0, 0x60(%rsp)
jmp 0x4d40
movq 0xf0(%rsp), %rdi
movsd 0x60(%rsp), %xmm0
movsd 0x208(%rsp), %xmm1
addsd %xmm1, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x1a8(%rsp)
movsd 0x1b8(%rsp), %xmm0
movsd %xmm0, 0x48(%rsp)
addq $0x30, %rdi
movslq 0x108(%rsp), %rsi
callq 0x3350
movsd 0x48(%rsp), %xmm0
movsd 0x10(%rax), %xmm1
subsd %xmm1, %xmm0
movsd 0x1f8(%rsp), %xmm1
leaq 0x10f(%rsp), %rdi
callq 0x8900
movsd %xmm0, 0x50(%rsp)
jmp 0x4db5
movq 0xf0(%rsp), %rdi
movsd 0x50(%rsp), %xmm0
movsd 0x208(%rsp), %xmm1
addsd %xmm1, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x1a0(%rsp)
movsd 0x1d0(%rsp), %xmm1
movsd 0x1b0(%rsp), %xmm0
mulsd %xmm0, %xmm0
addsd %xmm1, %xmm0
movsd 0x1a8(%rsp), %xmm1
mulsd %xmm1, %xmm1
addsd %xmm0, %xmm1
movsd 0x1a0(%rsp), %xmm0
mulsd %xmm0, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x1d0(%rsp)
addq $0x18, %rdi
movq %rdi, 0x28(%rsp)
movslq 0x108(%rsp), %rsi
callq 0x3350
movq 0xf0(%rsp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
addq $0x30, %rdi
movq %rdi, 0x30(%rsp)
movslq 0x108(%rsp), %rsi
callq 0x3350
movsd 0x18(%rsp), %xmm0
movq 0x28(%rsp), %rdi
movsd %xmm0, (%rax)
movslq 0x108(%rsp), %rsi
callq 0x3350
movq 0x30(%rsp), %rdi
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
movslq 0x108(%rsp), %rsi
callq 0x3350
movsd 0x20(%rsp), %xmm0
movq 0x28(%rsp), %rdi
movsd %xmm0, 0x8(%rax)
movslq 0x108(%rsp), %rsi
callq 0x3350
movq 0x30(%rsp), %rdi
movsd 0x10(%rax), %xmm0
movsd %xmm0, 0x38(%rsp)
movslq 0x108(%rsp), %rsi
callq 0x3350
movsd 0x38(%rsp), %xmm0
movsd %xmm0, 0x10(%rax)
movsd 0x1c8(%rsp), %xmm0
movsd 0x1f8(%rsp), %xmm1
leaq 0x10f(%rsp), %rdi
callq 0x89a0
movsd %xmm0, 0x40(%rsp)
jmp 0x4f05
movq 0xf0(%rsp), %rdi
addq $0x18, %rdi
movslq 0x108(%rsp), %rsi
callq 0x3350
movsd 0x40(%rsp), %xmm0
movsd %xmm0, (%rax)
movsd 0x1c0(%rsp), %xmm0
movsd 0x1f8(%rsp), %xmm1
leaq 0x10f(%rsp), %rdi
callq 0x89a0
movsd %xmm0, 0x10(%rsp)
jmp 0x4f4f
movq 0xf0(%rsp), %rdi
addq $0x18, %rdi
movslq 0x108(%rsp), %rsi
callq 0x3350
movsd 0x10(%rsp), %xmm0
movsd %xmm0, 0x8(%rax)
movsd 0x1b8(%rsp), %xmm0
movsd 0x1f8(%rsp), %xmm1
leaq 0x10f(%rsp), %rdi
callq 0x89a0
movsd %xmm0, 0x8(%rsp)
jmp 0x4f9a
movq 0xf0(%rsp), %rdi
addq $0x18, %rdi
movslq 0x108(%rsp), %rsi
callq 0x3350
movsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x10(%rax)
movl 0x108(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x108(%rsp)
jmp 0x499a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x100(%rsp)
movl %eax, 0xfc(%rsp)
leaq 0x110(%rsp), %rdi
callq 0x3370
jmp 0x501f
movsd 0x1d0(%rsp), %xmm0
movsd %xmm0, (%rsp)
leaq 0x110(%rsp), %rdi
callq 0x3370
movsd (%rsp), %xmm0
addq $0x218, %rsp            # imm = 0x218
retq
movq 0x100(%rsp), %rdi
callq 0x21f0
nopl (%rax)