// File: /workspace/github_cpp_makefile_star2_O3/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 0x8204(%rip), %rdi      # 0xb208
movb $0x1, %al
callq 0x2030
movsd 0x10(%r13), %xmm0
subsd 0x8(%r13), %xmm0
andpd 0x81c1(%rip), %xmm0     # 0xb1e0
cvtsi2sdl (%r13), %xmm1
divsd %xmm1, %xmm0
movapd %xmm0, 0x10(%rsp)
leaq 0x81e2(%rip), %rdi      # 0xb218
movb $0x1, %al
callq 0x2030
movapd 0x10(%rsp), %xmm1
divsd (%rsp), %xmm1
mulsd 0x50(%r13), %xmm1
cmpl $0x0, (%rbx)
jns 0x305b
mulsd 0x81a5(%rip), %xmm1     # 0xb200
movsd (%r14), %xmm0
leaq 0x81bf(%rip), %rdi      # 0xb226
movapd %xmm1, (%rsp)
movb $0x2, %al
callq 0x2030
addq $0x60, %r13
leaq 0x81c4(%rip), %rsi      # 0xb242
movq %r13, %rdi
callq 0x2090
testl %eax, %eax
je 0x3143
leaq 0x81c0(%rip), %rsi      # 0xb255
movq %r13, %rdi
callq 0x2090
testl %eax, %eax
je 0x3143
movl (%r15), %edx
cmpl $0x3, %edx
jl 0x3201
decl %edx
movq (%rbp), %rax
movq (%r12), %rcx
movapd 0x812d(%rip), %xmm0     # 0xb1f0
xorpd (%rsp), %xmm0
divsd 0x10(%rsp), %xmm0
shlq $0x3, %rdx
leaq (%rdx,%rdx,2), %rdx
movl $0x18, %esi
movq -0x18(%rax,%rsi), %rdi
movq (%rax,%rsi), %r8
movsd (%r8), %xmm1
subsd (%rdi), %xmm1
movq (%rcx,%rsi), %r9
mulsd %xmm0, %xmm1
addsd (%r9), %xmm1
movsd %xmm1, (%r9)
movsd 0x8(%r8), %xmm1
subsd 0x8(%rdi), %xmm1
mulsd %xmm0, %xmm1
addsd 0x8(%r9), %xmm1
movsd %xmm1, 0x8(%r9)
movsd 0x10(%r8), %xmm1
subsd 0x10(%rdi), %xmm1
mulsd %xmm0, %xmm1
addsd 0x10(%r9), %xmm1
movsd %xmm1, 0x10(%r9)
addq $0x18, %rsi
cmpq %rsi, %rdx
jne 0x30db
jmp 0x3201
leaq 0x811c(%rip), %rdi      # 0xb266
callq 0x2290
movl (%r15), %edx
cmpl $0x5, %edx
jl 0x31f5
addl $-0x2, %edx
movq (%rbp), %rax
movq (%r12), %rcx
movapd 0x8082(%rip), %xmm0     # 0xb1f0
xorpd (%rsp), %xmm0
divsd 0x10(%rsp), %xmm0
leaq (%rdx,%rdx,2), %rdx
leaq -0x30(,%rdx,8), %rdx
xorl %esi, %esi
movq (%rax,%rsi), %rdi
movq 0x18(%rax,%rsi), %r8
movsd (%r8), %xmm1
subsd (%rdi), %xmm1
ucomisd %xmm1, %xmm1
jp 0x3320
movq 0x30(%rcx,%rsi), %r9
mulsd %xmm0, %xmm1
addsd (%r9), %xmm1
movsd %xmm1, (%r9)
movsd 0x8(%r8), %xmm1
subsd 0x8(%rdi), %xmm1
mulsd %xmm0, %xmm1
addsd 0x8(%r9), %xmm1
movsd %xmm1, 0x8(%r9)
movsd 0x10(%r8), %xmm1
subsd 0x10(%rdi), %xmm1
mulsd %xmm0, %xmm1
addsd 0x10(%r9), %xmm1
movsd %xmm1, 0x10(%r9)
addq $0x18, %rsi
cmpq %rsi, %rdx
jne 0x3187
leaq 0x80a0(%rip), %rdi      # 0xb29c
callq 0x2290
leaq 0x803a(%rip), %rsi      # 0xb242
movq %r13, %rdi
callq 0x2090
testl %eax, %eax
je 0x3247
leaq 0x803a(%rip), %rsi      # 0xb255
movq %r13, %rdi
callq 0x2090
testl %eax, %eax
je 0x3247
movslq (%r15), %rax
movq (%r12), %rcx
leaq (%rax,%rax,2), %rdx
leaq (%rcx,%rdx,8), %rax
addq $-0x30, %rax
leaq (%rcx,%rdx,8), %rcx
addq $-0x18, %rcx
jmp 0x32ca
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
leaq (%rax,%rax,2), %rdx
leaq -0x48(%rcx,%rdx,8), %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)
leaq (%rcx,%rdx,8), %rcx
addq $-0x30, %rcx
movapd (%rsp), %xmm1
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
addsd %xmm1, %xmm0
movsd %xmm0, (%r14)
incl (%rbx)
leaq 0x7f1e(%rip), %rdi      # 0xb226
movb $0x2, %al
callq 0x2030
xorl %eax, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x7f5e(%rip), %rdi      # 0xb285
callq 0x2290
movl $0x1, %eax
jmp 0x3311
nop