// File: /workspace/github_cpp_makefile_star2_O3/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 $0x58, %rsp
movq %rsi, %rbx
movq %rdi, -0x58(%rbp)
movsd 0x8(%rsi), %xmm0
movsd %xmm0, -0x60(%rbp)
movsd 0x10(%rsi), %xmm0
movsd %xmm0, -0x38(%rbp)
movsd 0x18(%rsi), %xmm0
movsd %xmm0, -0x50(%rbp)
movsd 0x20(%rsi), %xmm0
movsd %xmm0, -0x48(%rbp)
movsd 0x38(%rsi), %xmm0
movsd %xmm0, -0x40(%rbp)
movsd 0x40(%rsi), %xmm0
movsd %xmm0, -0x78(%rbp)
movsd 0x28(%rsi), %xmm0
movsd %xmm0, -0x70(%rbp)
movsd 0x30(%rsi), %xmm0
movsd %xmm0, -0x68(%rbp)
leaq 0x60(%rsi), %r15
leaq 0x19af(%rip), %rsi      # 0xb242
movq %r15, %rdi
callq 0x2090
testl %eax, %eax
je 0x98b8
leaq 0x19af(%rip), %rsi      # 0xb255
movq %r15, %rdi
callq 0x2090
movl $0x2, %r14d
testl %eax, %eax
jne 0x98ca
leaq 0x1d72(%rip), %rdi      # 0xb631
callq 0x2290
movl $0x4, %r14d
movl (%rbx), %eax
addl %eax, %r14d
movq -0x58(%rbp), %rcx
movl %r14d, (%rcx)
movsd -0x38(%rbp), %xmm2
subsd -0x60(%rbp), %xmm2
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
movapd %xmm2, %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, -0x30(%rbp)
leaq 0xf(,%r14,8), %rax
andq $-0x10, %rax
movq %rsp, %rcx
subq %rax, %rcx
movq %rcx, -0x60(%rbp)
movq %rcx, %rsp
movq %r15, %rdi
movq %rsp, %r15
subq %rax, %r15
movq %r15, %rsp
movq %rsp, %r12
subq %rax, %r12
movq %r12, %rsp
movq %rsp, %r13
subq %rax, %r13
movq %r13, %rsp
addsd 0x198d(%rip), %xmm2     # 0xb2c0
movsd %xmm2, -0x38(%rbp)
leaq 0x1903(%rip), %rsi      # 0xb242
movq %rdi, -0x80(%rbp)
callq 0x2090
testl %eax, %eax
je 0x99fb
leaq 0x18fe(%rip), %rsi      # 0xb255
movq -0x80(%rbp), %rdi
callq 0x2090
testl %eax, %eax
je 0x99fb
movq -0x58(%rbp), %rax
movslq (%rax), %rax
cmpq $0x3, %rax
jl 0x9acd
leal -0x1(%rax), %ecx
movsd 0x48(%rbx), %xmm0
decq %rcx
xorl %edx, %edx
movapd 0x1852(%rip), %xmm1     # 0xb1e0
movsd -0x50(%rbp), %xmm3
movsd -0x48(%rbp), %xmm4
movsd -0x40(%rbp), %xmm5
movsd -0x78(%rbp), %xmm6
movsd -0x70(%rbp), %xmm7
movsd -0x68(%rbp), %xmm8
movsd -0x30(%rbp), %xmm9
movsd -0x38(%rbp), %xmm10
xorps %xmm2, %xmm2
cvtsi2sd %edx, %xmm2
mulsd %xmm9, %xmm2
movsd %xmm2, 0x8(%r13,%rdx,8)
subsd %xmm0, %xmm2
andpd %xmm1, %xmm2
incq %rdx
ucomisd %xmm2, %xmm10
movl %edx, %esi
ja 0x99e3
movl %r14d, %esi
movl %esi, %r14d
movapd %xmm2, %xmm10
cmpq %rdx, %rcx
jne 0x99b9
movsd 0x8(%r13), %xmm0
jmp 0x9af5
movq -0x58(%rbp), %rax
movl (%rax), %eax
cmpl $0x5, %eax
jl 0x9a56
addl $-0x2, %eax
movsd 0x48(%rbx), %xmm0
addq $-0x2, %rax
xorl %ecx, %ecx
movapd 0x17c4(%rip), %xmm1     # 0xb1e0
movsd -0x30(%rbp), %xmm3
movsd -0x38(%rbp), %xmm4
xorps %xmm2, %xmm2
cvtsi2sd %ecx, %xmm2
mulsd %xmm3, %xmm2
movsd %xmm2, 0x10(%r13,%rcx,8)
subsd %xmm0, %xmm2
andpd %xmm1, %xmm2
ucomisd %xmm2, %xmm4
jbe 0x9a4a
leal 0x2(%rcx), %r14d
incq %rcx
movapd %xmm2, %xmm4
cmpq %rcx, %rax
jne 0x9a26
leaq 0x1be7(%rip), %rdi      # 0xb644
callq 0x2290
movsd 0x10(%r13), %xmm1
movsd -0x30(%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 -0x58(%rbp), %rax
movl (%rax), %edi
movslq %edi, %rax
movsd -0x18(%r13,%rax,8), %xmm1
addsd %xmm1, %xmm3
movsd %xmm3, -0x10(%r13,%rax,8)
addsd %xmm1, %xmm0
movsd -0x50(%rbp), %xmm3
movsd -0x48(%rbp), %xmm4
movsd -0x40(%rbp), %xmm5
movsd -0x78(%rbp), %xmm6
movsd -0x70(%rbp), %xmm7
movsd -0x68(%rbp), %xmm8
jmp 0x9b11
movl %r14d, %esi
movsd -0x50(%rbp), %xmm3
movsd -0x48(%rbp), %xmm4
movsd -0x40(%rbp), %xmm5
movsd -0x78(%rbp), %xmm6
movsd -0x70(%rbp), %xmm7
movsd -0x68(%rbp), %xmm8
movsd -0x30(%rbp), %xmm9
subsd %xmm9, %xmm0
movsd %xmm0, (%r13)
addsd -0x10(%r13,%rax,8), %xmm9
movapd %xmm9, %xmm0
movl %eax, %edi
movl %esi, %r14d
movsd %xmm0, -0x8(%r13,%rax,8)
movl %edi, %ebx
testl %edi, %edi
movq -0x60(%rbp), %rdx
jle 0x9b5e
movslq %r14d, %rax
xorl %ecx, %ecx
movapd %xmm4, %xmm0
movapd %xmm6, %xmm1
movapd %xmm8, %xmm2
cmpq %rax, %rcx
jg 0x9b45
movapd %xmm3, %xmm0
movapd %xmm5, %xmm1
movapd %xmm7, %xmm2
movsd %xmm0, (%rdx,%rcx,8)
movsd %xmm1, (%r12,%rcx,8)
movsd %xmm2, (%r15,%rcx,8)
incq %rcx
cmpq %rcx, %rbx
jne 0x9b27
movq %r15, -0x30(%rbp)
movslq %edi, %r14
movl $0x8, %esi
movl %edi, -0x38(%rbp)
movq %r14, %rdi
callq 0x2110
movq -0x58(%rbp), %r15
movq %rax, -0x50(%rbp)
movq %rax, 0x8(%r15)
movl $0x8, %esi
movq %r14, %rdi
callq 0x2110
movq %rax, -0x48(%rbp)
movq %rax, 0x10(%r15)
movl $0x8, %esi
movq %r14, %rdi
callq 0x2110
movq %rax, -0x40(%rbp)
movq %rax, 0x18(%r15)
movl $0x8, %esi
movq %r14, %rdi
callq 0x2110
movq %rax, 0x20(%r15)
cmpl $0x0, -0x38(%rbp)
jle 0x9c06
movq %rax, %r14
shlq $0x3, %rbx
movq -0x50(%rbp), %rdi
movq %r13, %rsi
movq %rbx, %rdx
callq 0x2160
movq -0x48(%rbp), %rdi
movq -0x60(%rbp), %rsi
movq %rbx, %rdx
callq 0x2160
movq -0x40(%rbp), %rdi
movq %r12, %rsi
movq %rbx, %rdx
callq 0x2160
movq %r14, %rdi
movq -0x30(%rbp), %rsi
movq %rbx, %rdx
callq 0x2160
xorl %eax, %eax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq