// File: /workspace/github_cpp_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %rsi, %r14
movq %rdi, %rbx
movsd 0x8(%rsi), %xmm0
movsd %xmm0, -0x38(%rbp)
movsd 0x10(%rsi), %xmm0
movsd %xmm0, -0x30(%rbp)
movsd 0x18(%rsi), %xmm0
movsd %xmm0, -0x78(%rbp)
movsd 0x20(%rsi), %xmm0
movsd %xmm0, -0x70(%rbp)
movsd 0x38(%rsi), %xmm0
movsd %xmm0, -0x68(%rbp)
movsd 0x40(%rsi), %xmm0
movsd %xmm0, -0x60(%rbp)
movsd 0x28(%rsi), %xmm0
movsd %xmm0, -0x58(%rbp)
movsd 0x30(%rsi), %xmm0
movsd %xmm0, -0x50(%rbp)
leaq 0x60(%rsi), %r15
leaq 0x1d9c(%rip), %rsi      # 0xa242
movq %r15, %rdi
callq 0x2b6b
testb %al, %al
jne 0x84c5
leaq 0x1d9c(%rip), %rsi      # 0xa255
movq %r15, %rdi
callq 0x2b6b
testb %al, %al
je 0x84d5
leaq 0x2135(%rip), %rdi      # 0xa601
callq 0x22b0
pushq $0x4
jmp 0x84d7
pushq $0x2
popq %r12
movl (%r14), %eax
addl %eax, %r12d
movl %r12d, (%rbx)
movsd -0x30(%rbp), %xmm2
subsd -0x38(%rbp), %xmm2
cvtsi2sd %eax, %xmm0
movapd %xmm2, %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, -0x40(%rbp)
leaq 0xf(,%r12,8), %rax
andq $-0x10, %rax
movq %rsp, %rcx
subq %rax, %rcx
movq %rcx, -0x38(%rbp)
movq %rcx, %rsp
movq %rsp, %rcx
subq %rax, %rcx
movq %rcx, -0x88(%rbp)
movq %rcx, %rsp
movq %rsp, %rcx
subq %rax, %rcx
movq %rcx, -0x80(%rbp)
movq %rcx, %rsp
movq %rsp, %r13
subq %rax, %r13
movq %r13, %rsp
addsd 0x1d7c(%rip), %xmm2     # 0xa2c0
movsd %xmm2, -0x30(%rbp)
leaq 0x1cf2(%rip), %rsi      # 0xa242
movq %r15, %rdi
callq 0x2b6b
testb %al, %al
jne 0x8573
leaq 0x1cf2(%rip), %rsi      # 0xa255
movq %r15, %rdi
callq 0x2b6b
testb %al, %al
je 0x8640
movslq (%rbx), %rax
addq $-0x2, %rax
movsd 0x48(%r14), %xmm0
xorl %ecx, %ecx
movapd 0x1c56(%rip), %xmm1     # 0xa1e0
movsd -0x40(%rbp), %xmm3
movsd -0x30(%rbp), %xmm4
leaq 0x2(%rcx), %rdx
cmpq %rax, %rdx
jge 0x85c7
cvtsi2sd %ecx, %xmm2
mulsd %xmm3, %xmm2
movsd %xmm2, 0x10(%r13,%rcx,8)
subsd %xmm0, %xmm2
andpd %xmm1, %xmm2
ucomisd %xmm2, %xmm4
jbe 0x85be
leal 0x2(%rcx), %r12d
incq %rcx
movapd %xmm2, %xmm4
jmp 0x8594
leaq 0x2046(%rip), %rdi      # 0xa614
callq 0x22b0
movsd 0x10(%r13), %xmm1
movsd -0x40(%rbp), %xmm3
movapd %xmm3, %xmm0
addsd %xmm3, %xmm0
movapd %xmm1, %xmm2
subsd %xmm0, %xmm2
movsd %xmm2, (%r13)
subsd %xmm3, %xmm1
movsd %xmm1, 0x8(%r13)
movq %rbx, %r15
movl (%rbx), %eax
movslq %eax, %rcx
movsd -0x18(%r13,%rcx,8), %xmm1
addsd %xmm1, %xmm3
movsd %xmm3, -0x10(%r13,%rcx,8)
addsd %xmm1, %xmm0
movsd -0x78(%rbp), %xmm3
movsd -0x70(%rbp), %xmm4
movsd -0x68(%rbp), %xmm5
movsd -0x60(%rbp), %xmm6
movsd -0x58(%rbp), %xmm7
movsd -0x50(%rbp), %xmm8
jmp 0x86df
movl (%rbx), %eax
movslq %eax, %rcx
leaq -0x1(%rcx), %rdx
movsd 0x48(%r14), %xmm0
xorl %edi, %edi
movapd 0x1b87(%rip), %xmm1     # 0xa1e0
movsd -0x78(%rbp), %xmm3
movsd -0x70(%rbp), %xmm4
movsd -0x68(%rbp), %xmm5
movsd -0x60(%rbp), %xmm6
movsd -0x58(%rbp), %xmm7
movsd -0x50(%rbp), %xmm8
movsd -0x40(%rbp), %xmm9
movsd -0x30(%rbp), %xmm10
leaq 0x1(%rdi), %rsi
cmpq %rdx, %rsi
jge 0x86bf
cvtsi2sd %edi, %xmm2
mulsd %xmm9, %xmm2
movsd %xmm2, 0x8(%r13,%rdi,8)
subsd %xmm0, %xmm2
andpd %xmm1, %xmm2
ucomisd %xmm2, %xmm10
movl %esi, %r8d
ja 0x86b2
movl %r12d, %r8d
movq %rsi, %rdi
movapd %xmm2, %xmm10
movl %r8d, %r12d
jmp 0x8684
movq %rbx, %r15
movsd 0x8(%r13), %xmm0
subsd %xmm9, %xmm0
movsd %xmm0, (%r13)
addsd -0x10(%r13,%rcx,8), %xmm9
movapd %xmm9, %xmm0
movsd %xmm0, -0x8(%r13,%rcx,8)
movslq %r12d, %rcx
xorl %edx, %edx
testl %eax, %eax
movl $0x0, %ebx
cmovgl %eax, %ebx
movq -0x38(%rbp), %rsi
movq -0x88(%rbp), %rdi
movq -0x80(%rbp), %r8
cmpq %rdx, %rbx
je 0x873c
movapd %xmm4, %xmm0
movapd %xmm6, %xmm1
movapd %xmm8, %xmm2
cmpq %rcx, %rdx
jg 0x8727
movapd %xmm3, %xmm0
movapd %xmm5, %xmm1
movapd %xmm7, %xmm2
movsd %xmm0, (%rsi,%rdx,8)
movsd %xmm1, (%r8,%rdx,8)
movsd %xmm2, (%rdi,%rdx,8)
incq %rdx
jmp 0x8704
movslq %eax, %r12
movq %r12, -0x30(%rbp)
pushq $0x8
popq %rsi
movq %r12, %rdi
callq 0x2130
movq %rax, %r14
movq %r15, -0x48(%rbp)
movq %rax, 0x8(%r15)
movq %r12, %rdi
pushq $0x8
popq %rsi
callq 0x2130
movq %rax, %r15
movq -0x48(%rbp), %rax
movq %r15, 0x10(%rax)
movq %r12, %rdi
pushq $0x8
popq %rsi
callq 0x2130
movq %rax, %r12
movq -0x48(%rbp), %rax
movq %r12, 0x18(%rax)
movq -0x30(%rbp), %rdi
pushq $0x8
popq %rsi
callq 0x2130
movq -0x80(%rbp), %rdi
movq -0x88(%rbp), %rsi
movq -0x38(%rbp), %rdx
movq -0x48(%rbp), %rcx
movq %rax, 0x20(%rcx)
xorl %ecx, %ecx
cmpq %rcx, %rbx
je 0x87e1
movsd (%r13,%rcx,8), %xmm0
movsd %xmm0, (%r14,%rcx,8)
movsd (%rdx,%rcx,8), %xmm0
movsd %xmm0, (%r15,%rcx,8)
movsd (%rdi,%rcx,8), %xmm0
movsd %xmm0, (%r12,%rcx,8)
movsd (%rsi,%rcx,8), %xmm0
movsd %xmm0, (%rax,%rcx,8)
incq %rcx
jmp 0x87aa
xorl %eax, %eax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq