// File: /workspace/github_cpp_makefile_star2_O2/bauerj4[P]Riemann1D/src/FiniteVolume.cpp
// Function: FVUpdate(std::vector<std::vector<double, std::allocator<double>>, std::allocator<std::vector<double, std::allocator<double>>>>&, std::vector<std::vector<double, std::allocator<double>>, std::allocator<std::vector<double, std::allocator<double>>>>&, mesh_t&, context_t&, double&, double, int&)
int FVUpdate(vector<vector<double> > &conserved, vector<vector<double> > &fluxes,
	     mesh_t &mesh, context_t &RiemannContext, double &current_time, double smax, int &iteration)
{

  //double reduction_const = 1.e-1;
  printf("smax = %10.10f\n",smax);
  double dx = fabs(RiemannContext.X1 - RiemannContext.X0)/RiemannContext.MESH_RESOLUTION;
  printf("dx = %10.10f\n", dx);
  double dt = dx/smax * RiemannContext.CFL_NUMBER;
  // printf("dt = %10.10f\n", dt);

  if (iteration < 0)
    {
      dt = 0.2 * dt;
    }
  printf("t + dt = %10.10f + %10.10f\n", current_time, dt);


  if(RiemannContext.SOLUTION_METHOD == "HLLC_FLUX_SUPERBEE" ||
     RiemannContext.SOLUTION_METHOD == "HLLC_FLUX_MINBEE")
    {
      printf("Updating conserved quantities \n");
      for(int i = 2; i < mesh.NCells - 2; i++)
        {
	  //printf("Updating conserved %d.\n",i+1);

	  if ((fluxes[i-1][0] - fluxes[i-2][0]) != (fluxes[i-1][0] - fluxes[i-2][0]))
	    {
	      printf("ERROR: FLUXES ARE NAN.\n");
	      return 1;
	    }
	  conserved[i][0] -= dt/dx * (fluxes[i-1][0] - fluxes[i-2][0]);
	  conserved[i][1] -= dt/dx * (fluxes[i-1][1] - fluxes[i-2][1]);
	  conserved[i][2] -= dt/dx * (fluxes[i-1][2] - fluxes[i-2][2]);

	    
        }
      printf("Conserved quantities updated.\n");
    }

  else
    {
      for(int i = 1; i < mesh.NCells - 1; i++)
	{
	  conserved[i][0] -= dt/dx * (fluxes[i][0] - fluxes[i-1][0]);
	  conserved[i][1] -= dt/dx * (fluxes[i][1] - fluxes[i-1][1]);
	  conserved[i][2] -= dt/dx * (fluxes[i][2] - fluxes[i-1][2]);
	}
    }
  
  //SPECIFY BCS FOR GHOST CELLS
  if(RiemannContext.SOLUTION_METHOD == "HLLC_FLUX_SUPERBEE" || 
     RiemannContext.SOLUTION_METHOD == "HLLC_FLUX_MINBEE")
    {

      conserved[0][0] = conserved[2][0];
      conserved[0][1] = conserved[2][1];
      conserved[0][2] = conserved[2][2];

      conserved[1][0] = conserved[3][0];
      conserved[1][1] = conserved[3][1];
      conserved[1][2] = conserved[3][2];


      conserved[mesh.NCells - 1][0] = conserved[mesh.NCells- 4][0];
      conserved[mesh.NCells - 1][1] = conserved[mesh.NCells- 4][1];
      conserved[mesh.NCells - 1][2] = conserved[mesh.NCells- 4][2];

      conserved[mesh.NCells - 2][0] = conserved[mesh.NCells- 3][0];
      conserved[mesh.NCells - 2][1] = conserved[mesh.NCells- 3][1];
      conserved[mesh.NCells - 2][2] = conserved[mesh.NCells- 3][2];
    }

  else
    {
      conserved[mesh.NCells - 1][0] = conserved[mesh.NCells- 2][0];
      conserved[mesh.NCells - 1][1] = conserved[mesh.NCells- 2][1];
      conserved[mesh.NCells - 1][2] = conserved[mesh.NCells- 2][2];
    }
  current_time +=  dt;
  iteration++;
    
  printf("t + dt = %10.10f + %10.10f\n", current_time, dt);
  return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %r9, %rbx
movsd %xmm0, (%rsp)
movq %r8, %r14
movq %rcx, %r13
movq %rdx, %r15
movq %rsi, %rbp
movq %rdi, %r12
leaq 0x736c(%rip), %rdi      # 0xa208
movb $0x1, %al
callq 0x2030
movsd 0x10(%r13), %xmm0
subsd 0x8(%r13), %xmm0
andpd 0x7329(%rip), %xmm0     # 0xa1e0
cvtsi2sdl (%r13), %xmm1
divsd %xmm1, %xmm0
movapd %xmm0, 0x10(%rsp)
leaq 0x734a(%rip), %rdi      # 0xa218
movb $0x1, %al
callq 0x2030
movapd 0x10(%rsp), %xmm1
divsd (%rsp), %xmm1
mulsd 0x50(%r13), %xmm1
cmpl $0x0, (%rbx)
jns 0x2ef3
mulsd 0x730d(%rip), %xmm1     # 0xa200
movsd (%r14), %xmm0
leaq 0x7327(%rip), %rdi      # 0xa226
movapd %xmm1, (%rsp)
movb $0x2, %al
callq 0x2030
addq $0x60, %r13
leaq 0x732c(%rip), %rsi      # 0xa242
movq %r13, %rdi
callq 0x2b6b
testb %al, %al
jne 0x2f39
leaq 0x732c(%rip), %rsi      # 0xa255
movq %r13, %rdi
callq 0x2b6b
testb %al, %al
je 0x30b6
leaq 0x7326(%rip), %rdi      # 0xa266
callq 0x22b0
movslq (%r15), %rax
addq $-0x2, %rax
movq (%rbp), %rcx
movq (%r12), %rdx
movapd 0x7294(%rip), %xmm0     # 0xa1f0
xorpd (%rsp), %xmm0
divsd 0x10(%rsp), %xmm0
pushq $0x2
popq %rsi
xorl %edi, %edi
cmpq %rax, %rsi
jge 0x2fe2
movq (%rcx,%rdi), %r8
movq 0x18(%rcx,%rdi), %r9
movsd (%r9), %xmm1
subsd (%r8), %xmm1
ucomisd %xmm1, %xmm1
jp 0x30a2
movq 0x30(%rdx,%rdi), %r10
mulsd %xmm0, %xmm1
addsd (%r10), %xmm1
movsd %xmm1, (%r10)
movsd 0x8(%r9), %xmm1
subsd 0x8(%r8), %xmm1
mulsd %xmm0, %xmm1
addsd 0x8(%r10), %xmm1
movsd %xmm1, 0x8(%r10)
movsd 0x10(%r9), %xmm1
subsd 0x10(%r8), %xmm1
mulsd %xmm0, %xmm1
addsd 0x10(%r10), %xmm1
movsd %xmm1, 0x10(%r10)
incq %rsi
addq $0x18, %rdi
jmp 0x2f6c
leaq 0x72b3(%rip), %rdi      # 0xa29c
callq 0x22b0
leaq 0x724d(%rip), %rsi      # 0xa242
movq %r13, %rdi
callq 0x2b6b
testb %al, %al
jne 0x3018
leaq 0x724d(%rip), %rsi      # 0xa255
movq %r13, %rdi
callq 0x2b6b
testb %al, %al
je 0x314c
movq (%r12), %rcx
movq (%rcx), %rax
movq 0x30(%rcx), %rdx
movsd (%rdx), %xmm0
movsd %xmm0, (%rax)
movsd 0x8(%rdx), %xmm0
movsd %xmm0, 0x8(%rax)
movsd 0x10(%rdx), %xmm0
movsd %xmm0, 0x10(%rax)
movq 0x18(%rcx), %rax
movq 0x48(%rcx), %rdx
movsd (%rdx), %xmm0
movsd %xmm0, (%rax)
movsd 0x8(%rdx), %xmm0
movsd %xmm0, 0x8(%rax)
movsd 0x10(%rdx), %xmm0
movsd %xmm0, 0x10(%rax)
movslq (%r15), %rax
imulq $0x18, %rax, %rdx
leaq (%rcx,%rdx), %rax
addq $-0x48, %rax
movq -0x18(%rax), %rsi
movq 0x30(%rax), %rdi
movsd (%rsi), %xmm0
movsd %xmm0, (%rdi)
movsd 0x8(%rsi), %xmm0
movsd %xmm0, 0x8(%rdi)
movsd 0x10(%rsi), %xmm0
movsd %xmm0, 0x10(%rdi)
addq %rdx, %rcx
addq $-0x30, %rcx
jmp 0x3166
leaq 0x71dc(%rip), %rdi      # 0xa285
callq 0x22b0
pushq $0x1
popq %rax
jmp 0x31ad
movslq (%r15), %rax
decq %rax
movq (%rbp), %rcx
movq (%r12), %rdx
movapd 0x7124(%rip), %xmm0     # 0xa1f0
xorpd (%rsp), %xmm0
divsd 0x10(%rsp), %xmm0
pushq $0x1
popq %rsi
pushq $0x18
popq %rdi
cmpq %rax, %rsi
jge 0x2fee
movq -0x18(%rcx,%rdi), %r8
movq (%rcx,%rdi), %r9
movsd (%r9), %xmm1
subsd (%r8), %xmm1
movq (%rdx,%rdi), %r10
mulsd %xmm0, %xmm1
addsd (%r10), %xmm1
movsd %xmm1, (%r10)
movsd 0x8(%r9), %xmm1
subsd 0x8(%r8), %xmm1
mulsd %xmm0, %xmm1
addsd 0x8(%r10), %xmm1
movsd %xmm1, 0x8(%r10)
movsd 0x10(%r9), %xmm1
subsd 0x10(%r8), %xmm1
mulsd %xmm0, %xmm1
addsd 0x10(%r10), %xmm1
movsd %xmm1, 0x10(%r10)
incq %rsi
addq $0x18, %rdi
jmp 0x30dd
movslq (%r15), %rax
movq (%r12), %rcx
imulq $0x18, %rax, %rdx
leaq (%rcx,%rdx), %rax
addq $-0x30, %rax
addq %rdx, %rcx
addq $-0x18, %rcx
movq (%rax), %rax
movsd (%rax), %xmm0
movq (%rcx), %rcx
movsd %xmm0, (%rcx)
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x8(%rcx)
movsd 0x10(%rax), %xmm0
movsd %xmm0, 0x10(%rcx)
movsd (%r14), %xmm0
movapd (%rsp), %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, (%r14)
incl (%rbx)
leaq 0x7082(%rip), %rdi      # 0xa226
movb $0x2, %al
callq 0x2030
xorl %eax, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq