// File: bauerj4[P]Riemann1D/src/Mesh.cpp
// Function: ConstructMesh(mesh_t&, context_t&)
int ConstructMesh(mesh_t &mesh, context_t &RiemannContext)
{
  double leftBound = RiemannContext.X0;
  double rightBound = RiemannContext.X1;
  double discontinuityPosition = RiemannContext.INITIAL_DISCONTINUITY;
  double leftDensity = RiemannContext.RHO_L;
  double rightDensity = RiemannContext.RHO_R;
  double leftPressure = RiemannContext.P_L;
  double rightPressure = RiemannContext.P_R;
  double leftVelocity = RiemannContext.U_L;
  double rightVelocity = RiemannContext.U_R;

  // construct bin values
  if (RiemannContext.SOLUTION_METHOD == "HLLC_FLUX_SUPERBEE" ||
      RiemannContext.SOLUTION_METHOD == "HLLC_FLUX_MINBEE")
    {
      printf("Second order mesh.\n");
      mesh.NCells = RiemannContext.MESH_RESOLUTION + 4;
    }
  else
    {
      mesh.NCells = RiemannContext.MESH_RESOLUTION + 2; // For boundaries
    }
  double cellWidth = (rightBound - leftBound) / ((double) (RiemannContext.MESH_RESOLUTION));

  // Construct mesh and find the index best place on the Mesh to split 
  double  density[mesh.NCells];
  double  velocity[mesh.NCells];
  double  pressure[mesh.NCells];
  double  positions[mesh.NCells];
  double difference = rightBound - leftBound + 1.; // Initial difference can't be physical
  int indexOfDiscontinuity = mesh.NCells;
  /*
  for (int i = 1; i < mesh.NCells - 1; i++)
    {
      positions[i] = ((double) i - 1) * cellWidth;
      if (fabs(positions[i] - RiemannContext.INITIAL_DISCONTINUITY) < difference)
	{
	  indexOfDiscontinuity = i;
	}
      //printf("The difference is %10.10f\n", difference);

      difference = fabs(positions[i] - RiemannContext.INITIAL_DISCONTINUITY);
    }
  */
  if (RiemannContext.SOLUTION_METHOD == "HLLC_FLUX_SUPERBEE" ||
      RiemannContext.SOLUTION_METHOD == "HLLC_FLUX_MINBEE")
    {

      for (int i = 2; i < mesh.NCells - 2; i++)
	{
	  positions[i] = ((double) i - 2) * cellWidth;
	  if (fabs(positions[i] - RiemannContext.INITIAL_DISCONTINUITY) < difference)
	    {
	      indexOfDiscontinuity = i;
	    }
	  //printf("The difference is %10.10f\n", difference);                                                                                        

	  difference = fabs(positions[i] - RiemannContext.INITIAL_DISCONTINUITY);
	}

      printf("Setting second order positions...\n");
      positions[0] = positions[2] - 2. * cellWidth;
      positions[1] = positions[2] - cellWidth;
      positions[mesh.NCells - 2] = positions[mesh.NCells - 3] + cellWidth;
      positions[mesh.NCells - 1] = positions[mesh.NCells - 3] + 2. * cellWidth;
    }

  else
    {
      for (int i = 1; i < mesh.NCells - 1; i++)
	{
	  positions[i] = ((double) i - 1) * cellWidth;
	  if (fabs(positions[i] - RiemannContext.INITIAL_DISCONTINUITY) < difference)
	    {
	      indexOfDiscontinuity = i ;
	    }
	  //printf("The difference is %10.10f\n", difference);                                                                                        

	  difference = fabs(positions[i] - RiemannContext.INITIAL_DISCONTINUITY);
	}

      
      positions[0] = positions[1] - cellWidth;
      positions[mesh.NCells - 1] = positions[mesh.NCells - 2] + cellWidth;
    }
  //printf("THE MESH HAS %d CELLS.\n", mesh.NCells);
  
  //printf("The discontinuity position is %d\n",indexOfDiscontinuity);
  for (int i = 0; i < mesh.NCells; i++)
    {
      if (i <= indexOfDiscontinuity)
	{
	  density[i] = leftDensity;
	  pressure[i] = leftPressure;
	  velocity[i] = leftVelocity;
	}

      else
	{
	  density[i] = rightDensity;
	  pressure[i] = rightPressure;
	  velocity[i] = rightVelocity;
	}
    }
  
  mesh.FirstMeshElement = (double*)calloc(mesh.NCells, sizeof(double));//positions;
  mesh.FirstDensityElement = (double*)calloc(mesh.NCells, sizeof(double));//density;
  mesh.FirstPressureElement = (double*)calloc(mesh.NCells, sizeof(double));//pressure;
  mesh.FirstVelocityElement = (double*)calloc(mesh.NCells, sizeof(double));//velocity;

  
  for (int k = 0; k < mesh.NCells; k++)
    {
      /* printf("%10.10f, %10.10f, %10.10f, %10.10f\n", mesh.FirstMeshElement[k], mesh.FirstDensityElement[k], 
	     mesh.FirstPressureElement[k], mesh.FirstVelocityElement[k]);
      */
      mesh.FirstMeshElement[k] = positions[k];
      mesh.FirstDensityElement[k] = density[k];
      mesh.FirstPressureElement[k] = pressure[k];
      mesh.FirstVelocityElement[k] = velocity[k];
    }
  
  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movsd 0x8(%rax), %xmm0
movsd %xmm0, -0x18(%rbp)
movq -0x10(%rbp), %rax
movsd 0x10(%rax), %xmm0
movsd %xmm0, -0x20(%rbp)
movq -0x10(%rbp), %rax
movsd 0x48(%rax), %xmm0
movsd %xmm0, -0x28(%rbp)
movq -0x10(%rbp), %rax
movsd 0x18(%rax), %xmm0
movsd %xmm0, -0x30(%rbp)
movq -0x10(%rbp), %rax
movsd 0x20(%rax), %xmm0
movsd %xmm0, -0x38(%rbp)
movq -0x10(%rbp), %rax
movsd 0x38(%rax), %xmm0
movsd %xmm0, -0x40(%rbp)
movq -0x10(%rbp), %rax
movsd 0x40(%rax), %xmm0
movsd %xmm0, -0x48(%rbp)
movq -0x10(%rbp), %rax
movsd 0x28(%rax), %xmm0
movsd %xmm0, -0x50(%rbp)
movq -0x10(%rbp), %rax
movsd 0x30(%rax), %xmm0
movsd %xmm0, -0x58(%rbp)
movq -0x10(%rbp), %rdi
addq $0x60, %rdi
leaq 0x27d2(%rip), %rsi      # 0x18232
callq 0x3260
testb $0x1, %al
jne 0x15a83
movq -0x10(%rbp), %rdi
addq $0x60, %rdi
leaq 0x27cd(%rip), %rsi      # 0x18245
callq 0x3260
testb $0x1, %al
jne 0x15a83
jmp 0x15aa2
leaq 0x2b15(%rip), %rdi      # 0x1859f
movb $0x0, %al
callq 0x2040
movq -0x10(%rbp), %rax
movl (%rax), %ecx
addl $0x4, %ecx
movq -0x8(%rbp), %rax
movl %ecx, (%rax)
jmp 0x15ab1
movq -0x10(%rbp), %rax
movl (%rax), %ecx
addl $0x2, %ecx
movq -0x8(%rbp), %rax
movl %ecx, (%rax)
movsd -0x20(%rbp), %xmm0
movsd -0x18(%rbp), %xmm1
subsd %xmm1, %xmm0
movq -0x10(%rbp), %rax
cvtsi2sdl (%rax), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x60(%rbp)
movq -0x8(%rbp), %rax
movl (%rax), %eax
movq %rsp, %rcx
movq %rcx, -0x68(%rbp)
leaq 0xf(,%rax,8), %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0xc8(%rbp)
movq %rcx, %rsp
movq %rax, -0x70(%rbp)
movq -0x8(%rbp), %rax
movl (%rax), %eax
leaq 0xf(,%rax,8), %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0xc0(%rbp)
movq %rcx, %rsp
movq %rax, -0x78(%rbp)
movq -0x8(%rbp), %rax
movl (%rax), %eax
leaq 0xf(,%rax,8), %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0xb8(%rbp)
movq %rcx, %rsp
movq %rax, -0x80(%rbp)
movq -0x8(%rbp), %rax
movl (%rax), %eax
leaq 0xf(,%rax,8), %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0xb0(%rbp)
movq %rcx, %rsp
movq %rax, -0x88(%rbp)
movsd -0x20(%rbp), %xmm0
subsd -0x18(%rbp), %xmm0
movsd 0x272c(%rip), %xmm1     # 0x182b0
addsd %xmm1, %xmm0
movsd %xmm0, -0x90(%rbp)
movq -0x8(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x94(%rbp)
movq -0x10(%rbp), %rdi
addq $0x60, %rdi
leaq 0x2687(%rip), %rsi      # 0x18232
callq 0x3260
testb $0x1, %al
jne 0x15bd1
movq -0x10(%rbp), %rdi
addq $0x60, %rdi
leaq 0x2682(%rip), %rsi      # 0x18245
callq 0x3260
testb $0x1, %al
jne 0x15bd1
jmp 0x15d30
movl $0x2, -0x98(%rbp)
movl -0x98(%rbp), %eax
movq -0x8(%rbp), %rcx
movl (%rcx), %ecx
subl $0x2, %ecx
cmpl %ecx, %eax
jge 0x15c9b
movq -0xb0(%rbp), %rax
cvtsi2sdl -0x98(%rbp), %xmm0
movsd 0x26af(%rip), %xmm1     # 0x182b8
subsd %xmm1, %xmm0
mulsd -0x60(%rbp), %xmm0
movslq -0x98(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movslq -0x98(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm1
movq -0x10(%rbp), %rax
subsd 0x48(%rax), %xmm1
movaps 0x25a6(%rip), %xmm0     # 0x181e0
pand %xmm0, %xmm1
movsd -0x90(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x15c58
movl -0x98(%rbp), %eax
movl %eax, -0x94(%rbp)
movq -0xb0(%rbp), %rax
movslq -0x98(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x10(%rbp), %rax
subsd 0x48(%rax), %xmm0
movaps 0x2565(%rip), %xmm1     # 0x181e0
pand %xmm1, %xmm0
movsd %xmm0, -0x90(%rbp)
movl -0x98(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x98(%rbp)
jmp 0x15bdb
leaq 0x2911(%rip), %rdi      # 0x185b3
movb $0x0, %al
callq 0x2040
movq -0xb0(%rbp), %rax
movsd 0x10(%rax), %xmm0
movsd -0x60(%rbp), %xmm1
addsd %xmm1, %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, (%rax)
movsd 0x10(%rax), %xmm0
subsd -0x60(%rbp), %xmm0
movsd %xmm0, 0x8(%rax)
movq -0x8(%rbp), %rcx
movl (%rcx), %ecx
subl $0x3, %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
addsd -0x60(%rbp), %xmm0
movq -0x8(%rbp), %rcx
movl (%rcx), %ecx
subl $0x2, %ecx
movslq %ecx, %rcx
movsd %xmm0, (%rax,%rcx,8)
movq -0x8(%rbp), %rcx
movl (%rcx), %ecx
subl $0x3, %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm1
movsd -0x60(%rbp), %xmm0
addsd %xmm0, %xmm0
addsd %xmm1, %xmm0
movq -0x8(%rbp), %rcx
movl (%rcx), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movsd %xmm0, (%rax,%rcx,8)
jmp 0x15e36
movl $0x1, -0x9c(%rbp)
movl -0x9c(%rbp), %eax
movq -0x8(%rbp), %rcx
movl (%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x15dfa
movq -0xb0(%rbp), %rax
cvtsi2sdl -0x9c(%rbp), %xmm0
movsd 0x2548(%rip), %xmm1     # 0x182b0
subsd %xmm1, %xmm0
mulsd -0x60(%rbp), %xmm0
movslq -0x9c(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movslq -0x9c(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm1
movq -0x10(%rbp), %rax
subsd 0x48(%rax), %xmm1
movaps 0x2447(%rip), %xmm0     # 0x181e0
pand %xmm0, %xmm1
movsd -0x90(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x15db7
movl -0x9c(%rbp), %eax
movl %eax, -0x94(%rbp)
movq -0xb0(%rbp), %rax
movslq -0x9c(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x10(%rbp), %rax
subsd 0x48(%rax), %xmm0
movaps 0x2406(%rip), %xmm1     # 0x181e0
pand %xmm1, %xmm0
movsd %xmm0, -0x90(%rbp)
movl -0x9c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x9c(%rbp)
jmp 0x15d3a
movq -0xb0(%rbp), %rax
movsd 0x8(%rax), %xmm0
subsd -0x60(%rbp), %xmm0
movsd %xmm0, (%rax)
movq -0x8(%rbp), %rcx
movl (%rcx), %ecx
subl $0x2, %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
addsd -0x60(%rbp), %xmm0
movq -0x8(%rbp), %rcx
movl (%rcx), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movsd %xmm0, (%rax,%rcx,8)
movl $0x0, -0xa0(%rbp)
movl -0xa0(%rbp), %eax
movq -0x8(%rbp), %rcx
cmpl (%rcx), %eax
jge 0x15f08
movl -0xa0(%rbp), %eax
cmpl -0x94(%rbp), %eax
jg 0x15eaa
movq -0xc0(%rbp), %rax
movq -0xb8(%rbp), %rcx
movq -0xc8(%rbp), %rdx
movsd -0x30(%rbp), %xmm0
movslq -0xa0(%rbp), %rsi
movsd %xmm0, (%rdx,%rsi,8)
movsd -0x40(%rbp), %xmm0
movslq -0xa0(%rbp), %rdx
movsd %xmm0, (%rcx,%rdx,8)
movsd -0x50(%rbp), %xmm0
movslq -0xa0(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
jmp 0x15ef2
movq -0xc0(%rbp), %rax
movq -0xb8(%rbp), %rcx
movq -0xc8(%rbp), %rdx
movsd -0x38(%rbp), %xmm0
movslq -0xa0(%rbp), %rsi
movsd %xmm0, (%rdx,%rsi,8)
movsd -0x48(%rbp), %xmm0
movslq -0xa0(%rbp), %rdx
movsd %xmm0, (%rcx,%rdx,8)
movsd -0x58(%rbp), %xmm0
movslq -0xa0(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
jmp 0x15ef4
movl -0xa0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa0(%rbp)
jmp 0x15e40
movq -0x8(%rbp), %rax
movslq (%rax), %rdi
movl $0x8, %esi
callq 0x2160
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x8(%rbp), %rax
movslq (%rax), %rdi
movl $0x8, %esi
callq 0x2160
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x8(%rbp), %rax
movslq (%rax), %rdi
movl $0x8, %esi
callq 0x2160
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x8(%rbp), %rax
movslq (%rax), %rdi
movl $0x8, %esi
callq 0x2160
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x20(%rax)
movl $0x0, -0xa4(%rbp)
movl -0xa4(%rbp), %eax
movq -0x8(%rbp), %rcx
cmpl (%rcx), %eax
jge 0x16044
movq -0xc0(%rbp), %rax
movq -0xb8(%rbp), %rcx
movq -0xc8(%rbp), %rdx
movq -0xb0(%rbp), %rsi
movslq -0xa4(%rbp), %rdi
movsd (%rsi,%rdi,8), %xmm0
movq -0x8(%rbp), %rsi
movq 0x8(%rsi), %rsi
movslq -0xa4(%rbp), %rdi
movsd %xmm0, (%rsi,%rdi,8)
movslq -0xa4(%rbp), %rsi
movsd (%rdx,%rsi,8), %xmm0
movq -0x8(%rbp), %rdx
movq 0x10(%rdx), %rdx
movslq -0xa4(%rbp), %rsi
movsd %xmm0, (%rdx,%rsi,8)
movslq -0xa4(%rbp), %rdx
movsd (%rcx,%rdx,8), %xmm0
movq -0x8(%rbp), %rcx
movq 0x18(%rcx), %rcx
movslq -0xa4(%rbp), %rdx
movsd %xmm0, (%rcx,%rdx,8)
movslq -0xa4(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movslq -0xa4(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0xa4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa4(%rbp)
jmp 0x15f82
movq -0x68(%rbp), %rax
movq %rax, %rsp
xorl %eax, %eax
movq %rbp, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)