// File: /workspace/github_cpp_makefile_star2_O2/Luthaf[P]zeopp/network.cc
// Function: bool storeVoronoiNetwork<voro::container_periodic_poly>(voro::container_periodic_poly&, ATOM_NETWORK*, VORONOI_NETWORK*, double, double, double, std::vector<BASIC_VCELL, std::allocator<BASIC_VCELL>>&, std::vector<int, std::allocator<int>>&, bool, std::vector<VOR_CELL, std::allocator<VOR_CELL>>&)
bool storeVoronoiNetwork(c_option &con, ATOM_NETWORK *atmnet, VORONOI_NETWORK *vornet, double bx, double by, double bz,
			 vector<BASIC_VCELL> &basCells, vector<int> &atomShifts, bool storeAdvCells, vector<VOR_CELL> &advCells) {
  voronoi_network vnet (con, VOR_NODE_MERGE_THRESHOLD); // data structure defined in voro++ which is not to be confused with VORONOI_NETWORK
  int id;
  double vvol=0,x,y,z,r;
  voronoicell c(con);

  puts("Performing Voronoi decomposition.");

  basCells.clear(); advCells.clear();
  basCells.resize(atmnet->numAtoms, BASIC_VCELL());
  advCells.resize(atmnet->numAtoms, VOR_CELL());
  vector<int> numNodes;
  int cellIndex = 0;

  vector< vector<double> > vertices;

  // Compute Voronoi cells
  c_loop_all_periodic vl(con);
  vector<int> cellIDs;
  int **cellInfo;
  cellInfo = new int*[atmnet->numAtoms];
    if(vl.start()) {
      do { 
	if(con.compute_cell(c,vl)) {
	  vvol+=c.volume();
	  vl.pos(id,x,y,z,r);
	  	  
	  int *map;
	  vector<double> coords;
	  c.vertices(atmnet->atoms[id].x, atmnet->atoms[id].y, atmnet->atoms[id].z, coords);

	  numNodes.push_back(c.p);
	  cellIDs.push_back(id);
	  vertices.push_back(coords);

	  vnet.add_to_network(c,id,x,y,z,r, map);

	  cellInfo[cellIndex] = map;
	  
	  if(storeAdvCells){
	    VOR_CELL newCell;
	    createAdvCell(c, coords, map, newCell);
	    advCells[id] = newCell;
	  }
	} 
	else {
	  numNodes.push_back(0);
	  cellIDs.push_back(-1);
	  vertices.push_back(vector<double>());
	  
	  cellInfo[cellIndex] = NULL;
	}
	cellIndex++;
      } while(vl.inc());
    }
    else {
      fputs("Error: Unable to begin Voronoi decomposition.\nExiting...\n",stderr);
      exit(1);
    }

    // Carry out the volume check
    printf("Volume check:\n  Total domain volume  = %f\n",bx*by*bz);
    printf("  Total Voronoi volume = %f\n", vvol);
//    if(abs(vvol - bx*by*bz) > 0.00001) {
//    if(abs(vvol - bx*by*bz) > 0.0001) {
//      fputs("Error: Voronoi volume check failed.\nExiting...\n",stderr);
//      exit(1);
//    }
    double box_vol = bx*by*bz;
    double error_percent = 100*abs(vvol - box_vol)/box_vol;
    double error_percent_tolerance = 0.001; // former (before Voro++ fit default = 0.1; 
    if(error_percent > error_percent_tolerance) {
      printf("Error: Voronoi volume check failed (%.3f%% error, > %.3f%% tolerance).\nExiting...\n", error_percent, error_percent_tolerance);
      return false;
//      exit(1);
    }
    
    cout << "Voronoi decomposition finished. Rerouting Voronoi network information." << "\n";
    
    vnet.store_network(vornet->nodes, vornet->edges, false);
    for(int i = 0; i < atmnet->numAtoms; i++){
      if(numNodes[i] == 0){
	continue;
      }
      
      vector<int> nodeIDs;
      vector<Point> nodeLocations; 
      if((int)vertices[i].size() != 3*numNodes[i]){
	cerr << "Error: Improper number of node coordinates in Voronoi decomposition" << "\n"
	     << "Found " << vertices[i].size() << " but expected " << 3*numNodes[i] << "\n"
	     << "Exiting..." << "\n";
	exit(1);
      }

      for(int j = 0; j < numNodes[i]; j++){
	nodeLocations.push_back(Point(vertices[i][3*j], vertices[i][3*j+1], vertices[i][3*j+2])) ;
	nodeIDs.push_back(cellInfo[i][j*4]);
      }
      
      basCells[cellIDs[i]] = BASIC_VCELL(nodeLocations, nodeIDs);
      delete [] cellInfo[i];
    }
    delete [] cellInfo;
    cout << "Finished rerouting information." << "\n";
    return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x498, %rsp            # imm = 0x498
movl %r9d, 0x2c(%rsp)
movq %rcx, %r15
movsd %xmm2, 0xf0(%rsp)
movsd %xmm1, 0xe8(%rsp)
movsd %xmm0, 0x18(%rsp)
movq %rdx, 0xe0(%rsp)
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x2d0(%rsp), %rdi
movsd 0xf2b8f(%rip), %xmm0    # 0xfc030
movq %rbx, %rsi
callq 0x61534
leaq 0x3b0(%rsp), %rdi
movq %rbx, 0xb8(%rsp)
movq %rbx, %rsi
callq 0xb980
movq 0x4d0(%rsp), %rbx
leaq 0xf301c(%rip), %rdi     # 0xfc4ec
callq 0x4670
movq %r15, %rdi
callq 0xb99e
movq %rbx, %rdi
callq 0xb9a6
movslq 0x110(%r14), %rbx
leaq 0x1d0(%rsp), %rdi
callq 0x4f8c2
leaq 0x1d0(%rsp), %rdx
movq %r15, %rdi
movq %rbx, %rsi
callq 0xb9ae
leaq 0x1d0(%rsp), %rdi
callq 0xb3d4
movslq 0x110(%r14), %rbx
leaq 0x1d0(%rsp), %rdi
callq 0x4ea74
leaq 0x1d0(%rsp), %rdx
movq 0x4d0(%rsp), %rdi
movq %rbx, %rsi
callq 0xb9ea
leaq 0x1d0(%rsp), %rdi
callq 0xb450
xorpd %xmm0, %xmm0
movapd %xmm0, 0xa0(%rsp)
andq $0x0, 0xb0(%rsp)
movapd %xmm0, 0x80(%rsp)
andq $0x0, 0x90(%rsp)
leaq 0x170(%rsp), %rdi
movq 0xb8(%rsp), %rsi
callq 0xba2a
andq $0x0, 0xd0(%rsp)
xorpd %xmm0, %xmm0
movapd %xmm0, 0xc0(%rsp)
movslq 0x110(%r14), %rax
leaq (,%rax,8), %rcx
testq %rax, %rax
pushq $-0x1
popq %rdi
cmovnsq %rcx, %rdi
callq 0x4030
movq %rax, 0x10(%rsp)
leaq 0x170(%rsp), %rdi
callq 0xba7a
movq %r15, 0xf8(%rsp)
movq %r14, 0x20(%rsp)
testb %al, %al
je 0x9c0e
xorpd %xmm0, %xmm0
movapd %xmm0, 0x30(%rsp)
leaq 0x3b0(%rsp), %rbx
leaq 0x170(%rsp), %r12
leaq 0x40(%rsp), %r13
leaq 0x1d0(%rsp), %r14
movq 0x10(%rsp), %r15
movq 0xb8(%rsp), %rdi
movq %rbx, %rsi
movq %r12, %rdx
callq 0xbabe
testb %al, %al
je 0x9803
movq %rbx, %rdi
callq 0xd7fee
movsd %xmm0, 0x100(%rsp)
movq 0x188(%rsp), %rdx
movq 0x190(%rsp), %rax
movslq 0x1ac(%rsp), %rsi
movq (%rax,%rsi,8), %rax
movslq 0x1b0(%rsp), %rcx
movslq (%rax,%rcx,4), %rax
movl %eax, 0xc(%rsp)
movq (%rdx,%rsi,8), %rdx
movslq 0x184(%rsp), %rsi
imulq %rsi, %rcx
movsd 0xf29b2(%rip), %xmm0    # 0xfc038
cmpq $0x3, %rsi
je 0x9692
movsd 0x18(%rdx,%rcx,8), %xmm0
movsd %xmm0, 0x120(%rsp)
movsd (%rdx,%rcx,8), %xmm0
movsd %xmm0, 0x118(%rsp)
movsd 0x8(%rdx,%rcx,8), %xmm0
movsd %xmm0, 0x110(%rsp)
movsd 0x10(%rdx,%rcx,8), %xmm0
movsd %xmm0, 0x108(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x40(%rsp)
andq $0x0, 0x50(%rsp)
movq 0x20(%rsp), %rcx
movq 0x2f0(%rcx), %rcx
imulq $0x98, %rax, %rax
movsd (%rcx,%rax), %xmm0
movsd 0x8(%rcx,%rax), %xmm1
movsd 0x10(%rcx,%rax), %xmm2
movq %rbx, %rdi
movq %r13, %rsi
callq 0xd9c74
leaq 0xa0(%rsp), %rdi
leaq 0x3cc(%rsp), %rsi
callq 0x9434
leaq 0xc0(%rsp), %rdi
leaq 0xc(%rsp), %rsi
callq 0x9434
leaq 0x80(%rsp), %rdi
movq %r13, %rsi
callq 0xacaa
movl 0xc(%rsp), %edx
leaq 0x2d0(%rsp), %rdi
movq %rbx, %rsi
movsd 0x118(%rsp), %xmm0
movsd 0x110(%rsp), %xmm1
movsd 0x108(%rsp), %xmm2
movsd 0x120(%rsp), %xmm3
leaq 0x60(%rsp), %rcx
callq 0xbae4
movq 0x60(%rsp), %rax
movq %rax, (%r15)
cmpb $0x0, 0x2c(%rsp)
je 0x97e4
movq %r14, %rdi
callq 0x4ea74
leaq 0x158(%rsp), %rbp
movq %rbp, %rdi
movq %r13, %rsi
callq 0xbb60
movq 0x60(%rsp), %rdx
movq %rbx, %rdi
movq %rbp, %rsi
movq %r14, %rcx
callq 0x5894
movq %rbp, %rdi
callq 0xb25c
movslq 0xc(%rsp), %rax
imulq $0xf8, %rax, %rdi
movq 0x4d0(%rsp), %rax
addq (%rax), %rdi
movq %r14, %rsi
callq 0xbbae
movq %r14, %rdi
callq 0xb450
movapd 0x30(%rsp), %xmm0
addsd 0x100(%rsp), %xmm0
movapd %xmm0, 0x30(%rsp)
movq %r13, %rdi
callq 0xb25c
jmp 0x9865
andl $0x0, 0x1d0(%rsp)
leaq 0xa0(%rsp), %rdi
movq %r14, %rsi
callq 0x10324
orl $-0x1, 0x1d0(%rsp)
leaq 0xc0(%rsp), %rdi
movq %r14, %rsi
callq 0x10324
xorpd %xmm0, %xmm0
movapd %xmm0, 0x1d0(%rsp)
andq $0x0, 0x1e0(%rsp)
leaq 0x80(%rsp), %rdi
movq %r14, %rsi
callq 0xeafe
movq %r14, %rdi
callq 0xb25c
andq $0x0, (%r15)
movq %r12, %rdi
callq 0xbc20
addq $0x8, %r15
testb %al, %al
jne 0x9616
movsd 0x18(%rsp), %xmm0
mulsd 0xe8(%rsp), %xmm0
mulsd 0xf0(%rsp), %xmm0
movsd %xmm0, 0x18(%rsp)
leaq 0xf2caa(%rip), %rdi     # 0xfc548
movb $0x1, %al
callq 0x4050
leaq 0xf2cc7(%rip), %rdi     # 0xfc573
movaps 0x30(%rsp), %xmm0
movb $0x1, %al
callq 0x4050
movapd 0x30(%rsp), %xmm0
movsd 0x18(%rsp), %xmm1
subsd %xmm1, %xmm0
andpd 0xf27d0(%rip), %xmm0    # 0xfc0a0
mulsd 0xf2768(%rip), %xmm0    # 0xfc040
divsd %xmm1, %xmm0
ucomisd 0xf2764(%rip), %xmm0    # 0xfc048
movapd %xmm0, 0x30(%rsp)
ja 0x9ac0
movq 0x1466c9(%rip), %rdi    # 0x14ffc0
leaq 0xf2ce5(%rip), %rsi     # 0xfc5e3
callq 0x4480
leaq 0xf8c74(%rip), %rsi     # 0x10257e
movq %rax, %rdi
callq 0x4480
movq 0xe0(%rsp), %rdx
leaq 0x48(%rdx), %rsi
addq $0x60, %rdx
leaq 0x2d0(%rsp), %rdi
xorl %ecx, %ecx
callq 0x6047e
xorl %r13d, %r13d
leaq 0x1d0(%rsp), %rbx
movq 0x20(%rsp), %r14
movslq 0x110(%r14), %rax
cmpq %rax, %r13
jge 0x9ad8
movq 0xa0(%rsp), %rax
cmpl $0x0, (%rax,%r13,4)
je 0x9ab8
xorpd %xmm0, %xmm0
movapd %xmm0, 0x40(%rsp)
andq $0x0, 0x50(%rsp)
movapd %xmm0, 0x60(%rsp)
andq $0x0, 0x70(%rsp)
movq 0x80(%rsp), %rcx
imulq $0x18, %r13, %r15
movq 0x8(%rcx,%r15), %rdx
subq (%rcx,%r15), %rdx
shrq $0x3, %rdx
movl (%rax,%r13,4), %eax
leal (%rax,%rax,2), %ecx
cmpl %edx, %ecx
jne 0x9b6a
pushq $0x10
popq %rbp
xorl %r14d, %r14d
xorl %r12d, %r12d
cltq
cmpq %rax, %r12
jge 0x9a19
movq 0x80(%rsp), %rax
movq (%rax,%r15), %rax
movsd -0x10(%rax,%rbp), %xmm0
movsd -0x8(%rax,%rbp), %xmm1
movsd (%rax,%rbp), %xmm2
movq %rbx, %rdi
callq 0x63c46
leaq 0x60(%rsp), %rdi
movq %rbx, %rsi
callq 0xee82
movq 0x10(%rsp), %rax
movq (%rax,%r13,8), %rsi
addq %r14, %rsi
leaq 0x40(%rsp), %rdi
callq 0x9434
incq %r12
movq 0xa0(%rsp), %rax
movl (%rax,%r13,4), %eax
addq $0x10, %r14
addq $0x18, %rbp
jmp 0x99b1
leaq 0x140(%rsp), %r15
movq %r15, %rdi
leaq 0x60(%rsp), %rsi
callq 0xa66e
leaq 0x128(%rsp), %r12
movq %r12, %rdi
leaq 0x40(%rsp), %rsi
callq 0xa6ce
movq 0x20(%rsp), %r14
movq %rbx, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x4f922
movq 0xc0(%rsp), %rax
movslq (%rax,%r13,4), %rax
imulq $0x30, %rax, %rdi
movq 0xf8(%rsp), %rax
addq (%rax), %rdi
movq %rbx, %rsi
callq 0xbc5c
movq %rbx, %rdi
callq 0xb3d4
movq %r12, %rdi
callq 0xb290
movq %r15, %rdi
callq 0xb83e
movq 0x10(%rsp), %rax
movq (%rax,%r13,8), %rdi
testq %rdi, %rdi
je 0x9aa4
callq 0x4590
leaq 0x60(%rsp), %rdi
callq 0xb83e
leaq 0x40(%rsp), %rdi
callq 0xb290
incq %r13
jmp 0x9941
leaq 0xf2ac9(%rip), %rdi     # 0xfc590
movsd 0xf2579(%rip), %xmm1    # 0xfc048
movb $0x2, %al
callq 0x4050
jmp 0x9b04
movq 0x10(%rsp), %rdi
callq 0x4590
movq 0x1464d7(%rip), %rdi    # 0x14ffc0
leaq 0xf2b94(%rip), %rsi     # 0xfc684
callq 0x4480
leaq 0xf8a82(%rip), %rsi     # 0x10257e
movq %rax, %rdi
callq 0x4480
movapd 0x30(%rsp), %xmm0
ucomisd 0xf2536(%rip), %xmm0    # 0xfc048
setbe %bl
leaq 0xc0(%rsp), %rdi
callq 0xb290
leaq 0x80(%rsp), %rdi
callq 0xad30
leaq 0xa0(%rsp), %rdi
callq 0xb290
leaq 0x3b0(%rsp), %rdi
callq 0xd6d3c
leaq 0x2d0(%rsp), %rdi
callq 0x5fb2c
movl %ebx, %eax
addq $0x498, %rsp            # imm = 0x498
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x14647f(%rip), %rdi    # 0x14fff0
leaq 0xf2ab2(%rip), %rsi     # 0xfc62a
callq 0x4480
leaq 0xf89fa(%rip), %rsi     # 0x10257e
movq %rax, %rdi
callq 0x4480
leaq 0xf2adb(%rip), %rsi     # 0xfc66e
movq %rax, %rdi
callq 0x4480
movq 0x80(%rsp), %rcx
movq 0x8(%rcx,%r15), %rsi
subq (%rcx,%r15), %rsi
sarq $0x3, %rsi
movq %rax, %rdi
callq 0x42e0
leaq 0xf2ab6(%rip), %rsi     # 0xfc675
movq %rax, %rdi
callq 0x4480
movq 0xa0(%rsp), %rcx
imull $0x3, (%rcx,%r13,4), %esi
movq %rax, %rdi
callq 0x4760
leaq 0xf899b(%rip), %rsi     # 0x10257e
movq %rax, %rdi
callq 0x4480
leaq 0xf9a30(%rip), %rsi     # 0x103622
movq %rax, %rdi
callq 0x4480
leaq 0xf897d(%rip), %rsi     # 0x10257e
movq %rax, %rdi
callq 0x4480
callq 0x524c
movq 0x1463bb(%rip), %rax    # 0x14ffd0
movq (%rax), %rsi
leaq 0xf28ef(%rip), %rdi     # 0xfc50e
callq 0x44f0
callq 0x524c
movq %rax, %rbx
jmp 0x9d0a
movq %rax, %rbx
leaq 0x1d0(%rsp), %rdi
callq 0xb450
jmp 0x9d24
jmp 0x9c5d
movq %rax, %rbx
leaq 0x1d0(%rsp), %rdi
callq 0xb3d4
jmp 0x9d24
movq %rax, %rbx
jmp 0x9d24
movq %rax, %rbx
jmp 0x9d31
jmp 0x9cd0
jmp 0x9cd0
movq %rax, %rbx
leaq 0x158(%rsp), %rdi
callq 0xb25c
jmp 0x9cc1
jmp 0x9cd5
jmp 0x9ce6
jmp 0x9ce6
movq %rax, %rbx
jmp 0x9c9e
movq %rax, %rbx
leaq 0x128(%rsp), %rdi
callq 0xb290
leaq 0x140(%rsp), %rdi
callq 0xb83e
jmp 0x9ce9
jmp 0x9cd0
jmp 0x9cd0
movq %rax, %rbx
leaq 0x1d0(%rsp), %rdi
jmp 0x9cdd
movq %rax, %rbx
leaq 0x1d0(%rsp), %rdi
callq 0xb450
jmp 0x9cd8
movq %rax, %rbx
jmp 0x9cfd
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0xb25c
jmp 0x9cfd
jmp 0x9ce6
movq %rax, %rbx
leaq 0x60(%rsp), %rdi
callq 0xb83e
leaq 0x40(%rsp), %rdi
callq 0xb290
leaq 0xc0(%rsp), %rdi
callq 0xb290
leaq 0x80(%rsp), %rdi
callq 0xad30
leaq 0xa0(%rsp), %rdi
callq 0xb290
leaq 0x3b0(%rsp), %rdi
callq 0xd6d3c
leaq 0x2d0(%rsp), %rdi
callq 0x5fb2c
movq %rbx, %rdi
callq 0x4780