// File: /workspace/github_cpp_makefile_star2_O2/Luthaf[P]zeopp/networkstorage.cc
// Function: connect_molecules(std::vector<MOLECULE, std::allocator<MOLECULE>>*, ATOM_NETWORK*, std::vector<MOLECULE, std::allocator<MOLECULE>>*, std::vector<CONNECTION, std::allocator<CONNECTION>>*, double*, int, bool, bool, bool, double)
ATOM_NETWORK connect_molecules(vector<MOLECULE> *molecules, ATOM_NETWORK *cell, vector<MOLECULE> *assembled_molecules, vector<CONNECTION> *two_way_connections, double *mean_edge_length, int dimensionality, bool a_periodicity, bool b_periodicity, bool c_periodicity, double unit_edge_length) {
  bool verbose = false;
  ATOM_NETWORK unit_cell_any_matrix;
  //1) keep track of which molecules have been fixed in place already, and which connections were made
  vector<bool> placed;
  int num_mols = molecules->size();
  for(int i=0; i<num_mols; i++) placed.push_back(false);
  vector<bool> connected;
  int num_cons = two_way_connections->size();
  for(int i=0; i<num_cons; i++) connected.push_back(false);
  //2) fix each molecule in place
  for(int i=0; i<num_mols; i++) assembled_molecules->push_back(molecules->at(i)); //this vector starts out the same as the molecules vector, but the molecules are then each shifted into their relative positions to form the assembled_molecules
  int num_placed = 0;
  bool placed_ok = true;
  double sum_edge_lengths = 0;
  if(verbose) printf("DEBUG: about to place molecules\n");
  while(num_placed<num_mols && placed_ok) {
    int new_num_placed = place_molecule(molecules, two_way_connections, cell, &placed, &connected, assembled_molecules, num_placed, &sum_edge_lengths);
    if(verbose) printf("DEBUG: after calling place_molecule, %d molecules have been placed\n", new_num_placed);
    if(new_num_placed==num_placed+1) {
      num_placed = new_num_placed;
    } else placed_ok = false;
  }
  if(num_placed>1) (*mean_edge_length) = ((double)(sum_edge_lengths))/((double)(num_placed-1));
  if(num_placed!=num_mols) {
//    printf("ERROR: only %d of %d molecules were fixed in place during connection-based assembly method - this method should have been automatically bypassed if a disconnected net was provided\n", num_placed, num_mols);
//    exit(EXIT_FAILURE);
if(verbose) printf("NOTICE: only %d of %d molecules were fixed in place during connection-based assembly method - returning empty framework\n", num_placed, num_mols);
    return unit_cell_any_matrix;
  } else {
    if(verbose) printf("DEBUG: all %d of %d molecules were fixed in place successfully!\n", num_placed, num_mols);
  }

  //3) new new idea - look for loops in the two-way connections, and calculate their shifts, using this information to determine the net?
  vector<bool> edge_traversed;
  for(int i=0; i<num_cons; i++) edge_traversed.push_back(false);
  vector<int> vertices_visited;
  vector<int> loops_a, loops_b, loops_c;
  vector<XYZ> loops_xyz;
  vector<int> unit_cell_vector_IDs;
  vector<XYZ> unit_cell_vectors;
  vector<int> vertex_visit_a, vertex_visit_b, vertex_visit_c;
  vector<XYZ> vertex_visit_xyz;
  vector<bool> vertex_visited;
  int num_v = cell->vertices.size();
  for(int i=0; i<num_v; i++) {vertex_visited.push_back(false); vertex_visit_a.push_back(0); vertex_visit_b.push_back(0); vertex_visit_c.push_back(0); vertex_visit_xyz.push_back(origin);}
  bool found_all_uc_vectors = recursive_find_loops(0, 0, 0, 0, origin, two_way_connections, assembled_molecules, &edge_traversed, &vertex_visit_a, &vertex_visit_b, &vertex_visit_c, &vertex_visit_xyz, &vertex_visited, &loops_a, &loops_b, &loops_c, &loops_xyz, &unit_cell_vector_IDs, &unit_cell_vectors, dimensionality);
if(verbose) {
  int num_loops = loops_xyz.size();
  for(int i=0; i<num_loops; i++) {
    XYZ l = loops_xyz.at(i);
    printf("DEBUG: unique loop was found with periodicity (%d %d %d) and Cartesian shift %.3f %.3f %.3f\n", loops_a.at(i), loops_b.at(i), loops_c.at(i), l.x, l.y, l.z);
  }
}
  if(found_all_uc_vectors) {
if(verbose) printf("DEBUG: found all uc vectors from loop analysis\n");
  } else {
    printf("ERROR: did not find all uc vectors from loop analysis\n");
    exit(EXIT_FAILURE);
  }

  //if we are dealing with a 2D net (a layer), then we need to introduce a periodic connection running in that direction
  if(dimensionality==2) {
if(verbose) printf("DEBUG: imposing a three dimensional structure on this two-dimensional framework in order to define a unit cell\n");
    int num_override = 0;
    if(!a_periodicity) {
      XYZ vec((*mean_edge_length)*cell->a/unit_edge_length,0,0);
      unit_cell_vectors.push_back(vec);
      unit_cell_vector_IDs.push_back(0);
      num_override++;
    }
    if(!b_periodicity) {
      XYZ vec(0,(*mean_edge_length)*cell->b/unit_edge_length,0);
      unit_cell_vectors.push_back(vec);
      unit_cell_vector_IDs.push_back(1);
      num_override++;
    }
    if(!c_periodicity) {
      XYZ vec(0,0,(*mean_edge_length)*cell->c/unit_edge_length);
      unit_cell_vectors.push_back(vec);
      unit_cell_vector_IDs.push_back(2);
      num_override++;
    }
    if(num_override!=1) {
      printf("ERROR: was expecting to override exactly 1 cell side length value, but %d were overwritten - this is a bug\n", num_override);
      exit(EXIT_FAILURE);
    }
  }
  vector<XYZ> sorted_unit_cell_vectors;
  for(int i=0; i<3; i++) {
    bool pushed = false;
    for(int j=0; j<3 && !pushed; j++) {
      if(unit_cell_vector_IDs.at(j)==i) {
        sorted_unit_cell_vectors.push_back(unit_cell_vectors.at(j));
        pushed = true;
      }
    }
  }
  create_unit_cell_from_vectors(&sorted_unit_cell_vectors, &unit_cell_any_matrix);

  //6) put atoms into the cell, converting to fractional coords
  put_atoms_in_atom_network(&unit_cell_any_matrix, assembled_molecules);
  //7) that ATOM_NETWORK was constructed with matrices based on periodic connections, that may not conform to the standard axes relations - build a new cell with a normal matrix, based on this one, and copy the atom fractional coords into this system
  ATOM_NETWORK unit_cell;
  unit_cell_any_matrix.copy(&unit_cell);
  unit_cell.make(unit_cell_any_matrix.a, unit_cell_any_matrix.b, unit_cell_any_matrix.c, unit_cell_any_matrix.alpha, unit_cell_any_matrix.beta, unit_cell_any_matrix.gamma);
  return unit_cell;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x738, %rsp            # imm = 0x738
movsd %xmm0, 0xc0(%rsp)
movq %r9, 0x90(%rsp)
movq %r8, 0xc8(%rsp)
movq %rcx, 0x98(%rsp)
movq %rdx, 0x80(%rsp)
movq %rsi, %rbp
movq %rdi, 0x108(%rsp)
leaq 0x2d8(%rsp), %rdi
callq 0x3db30
leaq 0x288(%rsp), %rbx
andq $0x0, (%rbx)
andl $0x0, 0x8(%rbx)
andq $0x0, 0x10(%rbx)
andl $0x0, 0x18(%rbx)
andq $0x0, 0x20(%rbx)
movq 0x8(%rbp), %rax
subq (%rbp), %rax
movl $0xa8, %ecx
cqto
idivq %rcx
xorl %r13d, %r13d
testl %eax, %eax
movq %rax, 0x110(%rsp)
cmovgl %eax, %r13d
movl %r13d, %r14d
subl $0x1, %r14d
jb 0x45d8f
movq %rbx, %rdi
xorl %esi, %esi
callq 0xa8f6
jmp 0x45d7d
leaq 0x260(%rsp), %r12
andq $0x0, (%r12)
andl $0x0, 0x8(%r12)
andq $0x0, 0x10(%r12)
andl $0x0, 0x18(%r12)
andq $0x0, 0x20(%r12)
movq 0xc8(%rsp), %rcx
movq 0x8(%rcx), %rax
subq (%rcx), %rax
pushq $0x1c
popq %rcx
cqto
idivq %rcx
movq %rax, %rbx
xorl %eax, %eax
testl %ebx, %ebx
cmovlel %eax, %ebx
movl %ebx, %r14d
subl $0x1, %r14d
jb 0x45dea
movq %r12, %rdi
xorl %esi, %esi
callq 0xa8f6
jmp 0x45dd8
movl %r13d, %r14d
xorl %r12d, %r12d
cmpq %r12, %r14
je 0x45e15
movq %rbp, %rdi
movq %r12, %rsi
callq 0x4b9e8
movq 0x98(%rsp), %rdi
movq %rax, %rsi
callq 0x4bc3a
incq %r12
jmp 0x45df0
leaq 0x118(%rsp), %r15
andq $0x0, (%r15)
xorl %r14d, %r14d
movb $0x1, %cl
leaq 0x288(%rsp), %r12
leaq 0x260(%rsp), %r13
cmpl 0x110(%rsp), %r14d
jge 0x45e83
testb $0x1, %cl
je 0x45e83
movq %r15, 0x8(%rsp)
movl %r14d, (%rsp)
movq %rbp, %rdi
movq 0xc8(%rsp), %rsi
movq 0x80(%rsp), %rdx
movq %r12, %rcx
movq %r13, %r8
movq 0x98(%rsp), %r9
callq 0x43809
leal 0x1(%r14), %ecx
cmpl %ecx, %eax
sete %cl
cmovel %eax, %r14d
jmp 0x45e36
cmpl $0x2, %r14d
jl 0x45eaa
movsd 0x118(%rsp), %xmm0
leal -0x1(%r14), %eax
cvtsi2sd %eax, %xmm1
divsd %xmm1, %xmm0
movq 0x90(%rsp), %rax
movsd %xmm0, (%rax)
cmpl 0x110(%rsp), %r14d
jne 0x45ee5
leaq 0x238(%rsp), %r14
andq $0x0, (%r14)
andl $0x0, 0x8(%r14)
andq $0x0, 0x10(%r14)
andl $0x0, 0x18(%r14)
andq $0x0, 0x20(%r14)
subl $0x1, %ebx
jb 0x45f02
movq %r14, %rdi
xorl %esi, %esi
callq 0xa8f6
jmp 0x45ed4
leaq 0x2d8(%rsp), %rsi
movq 0x108(%rsp), %rbx
movq %rbx, %rdi
callq 0x4bd02
jmp 0x4645f
xorpd %xmm0, %xmm0
andq $0x0, 0x1f0(%rsp)
movapd %xmm0, 0x1e0(%rsp)
andq $0x0, 0x1d0(%rsp)
movapd %xmm0, 0x1c0(%rsp)
andq $0x0, 0x1b0(%rsp)
movapd %xmm0, 0x1a0(%rsp)
andq $0x0, 0x190(%rsp)
movapd %xmm0, 0x180(%rsp)
andq $0x0, 0x170(%rsp)
movapd %xmm0, 0x160(%rsp)
andq $0x0, 0x100(%rsp)
movapd %xmm0, 0xf0(%rsp)
andq $0x0, 0xe0(%rsp)
leaq 0x140(%rsp), %rax
andq $0x0, 0x10(%rax)
leaq 0x120(%rsp), %rcx
andq $0x0, 0x10(%rcx)
leaq 0x220(%rsp), %rdx
andq $0x0, 0x10(%rdx)
leaq 0x200(%rsp), %rsi
andq $0x0, 0x10(%rsi)
leaq 0x2b0(%rsp), %r15
andq $0x0, (%r15)
movapd %xmm0, 0xd0(%rsp)
andl $0x0, 0x8(%r15)
movapd %xmm0, (%rax)
andq $0x0, 0x10(%r15)
movapd %xmm0, (%rcx)
andl $0x0, 0x18(%r15)
movq %rdx, %r14
movapd %xmm0, (%rdx)
andq $0x0, 0x20(%r15)
movq %rsi, %r13
movapd %xmm0, (%rsi)
movq 0x80(%rsp), %rcx
movq 0x3c8(%rcx), %rax
subq 0x3c0(%rcx), %rax
pushq $0x70
popq %rcx
cqto
idivq %rcx
movq %rax, %rbp
xorl %eax, %eax
testl %ebp, %ebp
cmovlel %eax, %ebp
leaq 0xa0(%rsp), %r12
leaq 0x10a6b3(%rip), %rbx    # 0x1506d8
subl $0x1, %ebp
jb 0x46084
movq %r15, %rdi
xorl %esi, %esi
callq 0xa8f6
andl $0x0, 0xa0(%rsp)
leaq 0x140(%rsp), %rdi
movq %r12, %rsi
callq 0x10324
andl $0x0, 0xa0(%rsp)
leaq 0x120(%rsp), %rdi
movq %r12, %rsi
callq 0x10324
andl $0x0, 0xa0(%rsp)
movq %r14, %rdi
movq %r12, %rsi
callq 0x10324
movq %r13, %rdi
movq %rbx, %rsi
callq 0x4beaa
jmp 0x46025
movq 0x10a65d(%rip), %rax    # 0x1506e8
movq %rax, 0x10(%rsp)
movupd 0x10a640(%rip), %xmm0   # 0x1506d8
movupd %xmm0, (%rsp)
movl 0x770(%rsp), %eax
movl %eax, 0x78(%rsp)
leaq 0xd0(%rsp), %rax
movq %rax, 0x70(%rsp)
leaq 0xf0(%rsp), %rax
movq %rax, 0x68(%rsp)
leaq 0x160(%rsp), %rax
movq %rax, 0x60(%rsp)
leaq 0x180(%rsp), %rax
movq %rax, 0x58(%rsp)
leaq 0x1a0(%rsp), %rax
movq %rax, 0x50(%rsp)
leaq 0x1c0(%rsp), %rax
movq %rax, 0x48(%rsp)
movq %r15, 0x40(%rsp)
movq %r13, 0x38(%rsp)
movq %r14, 0x30(%rsp)
leaq 0x120(%rsp), %rax
movq %rax, 0x28(%rsp)
leaq 0x140(%rsp), %rax
movq %rax, 0x20(%rsp)
leaq 0x238(%rsp), %rax
movq %rax, 0x18(%rsp)
xorl %edi, %edi
xorl %esi, %esi
xorl %edx, %edx
xorl %ecx, %ecx
movq 0xc8(%rsp), %r8
movq 0x98(%rsp), %r9
callq 0x76b69
testb %al, %al
je 0x4649b
cmpl $0x2, 0x770(%rsp)
jne 0x462c1
xorl %ebx, %ebx
cmpb $0x0, 0x778(%rsp)
jne 0x461d2
movq 0x90(%rsp), %rax
movsd (%rax), %xmm0
movq 0x80(%rsp), %rax
mulsd 0x8(%rax), %xmm0
divsd 0xc0(%rsp), %xmm0
leaq 0xa0(%rsp), %rdi
xorpd %xmm1, %xmm1
xorpd %xmm2, %xmm2
callq 0x6402e
leaq 0xd0(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
callq 0x4beaa
leaq 0x8c(%rsp), %rsi
andl $0x0, (%rsi)
leaq 0xf0(%rsp), %rdi
callq 0x10324
pushq $0x1
popq %rbx
cmpb $0x0, 0x780(%rsp)
jne 0x46245
movq 0x90(%rsp), %rax
movsd (%rax), %xmm1
movq 0x80(%rsp), %rax
mulsd 0x10(%rax), %xmm1
divsd 0xc0(%rsp), %xmm1
leaq 0xa0(%rsp), %rdi
xorpd %xmm0, %xmm0
xorpd %xmm2, %xmm2
callq 0x6402e
leaq 0xd0(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
callq 0x4beaa
leaq 0x8c(%rsp), %rsi
movl $0x1, (%rsi)
leaq 0xf0(%rsp), %rdi
callq 0x10324
incl %ebx
cmpb $0x0, 0x788(%rsp)
jne 0x462b8
movq 0x90(%rsp), %rax
movsd (%rax), %xmm2
movq 0x80(%rsp), %rax
mulsd 0x18(%rax), %xmm2
divsd 0xc0(%rsp), %xmm2
leaq 0xa0(%rsp), %rdi
xorpd %xmm0, %xmm0
xorpd %xmm1, %xmm1
callq 0x6402e
leaq 0xd0(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
callq 0x4beaa
leaq 0x8c(%rsp), %rsi
movl $0x2, (%rsi)
leaq 0xf0(%rsp), %rdi
callq 0x10324
incl %ebx
cmpl $0x1, %ebx
jne 0x464a9
xorpd %xmm0, %xmm0
leaq 0xa0(%rsp), %rbx
andq $0x0, 0x10(%rbx)
movapd %xmm0, (%rbx)
xorl %ebp, %ebp
leaq 0xf0(%rsp), %r15
leaq 0xd0(%rsp), %r12
cmpl $0x3, %ebp
je 0x46331
xorl %r13d, %r13d
xorl %r14d, %r14d
cmpq $0x2, %r13
ja 0x4632d
testb $0x1, %r14b
jne 0x4632d
movq %r15, %rdi
movq %r13, %rsi
callq 0xac00
cmpl %ebp, (%rax)
sete %r14b
jne 0x46328
movq %r12, %rdi
movq %r13, %rsi
callq 0x4b6d6
movq %rbx, %rdi
movq %rax, %rsi
callq 0x4beaa
incq %r13
jmp 0x462f3
incl %ebp
jmp 0x462e8
leaq 0xa0(%rsp), %rdi
leaq 0x2d8(%rsp), %rsi
callq 0x43ea5
movq 0x108(%rsp), %rbx
leaq 0x2d8(%rsp), %rdi
movq 0x98(%rsp), %rsi
callq 0x4558a
movq %rbx, %rdi
callq 0x3db30
leaq 0x2d8(%rsp), %rdi
movq %rbx, %rsi
callq 0x3eada
movups 0x2e0(%rsp), %xmm0
movups %xmm0, 0x8(%rbx)
movups 0x2f0(%rsp), %xmm0
movups %xmm0, 0x18(%rbx)
movupd 0x300(%rsp), %xmm0
movupd %xmm0, 0x28(%rbx)
movq %rbx, %rdi
callq 0x3e5a4
leaq 0xa0(%rsp), %rdi
callq 0xb132
leaq 0x2b0(%rsp), %rdi
callq 0xa976
leaq 0x200(%rsp), %rdi
callq 0xb132
leaq 0x220(%rsp), %rdi
callq 0xb290
leaq 0x120(%rsp), %rdi
callq 0xb290
leaq 0x140(%rsp), %rdi
callq 0xb290
leaq 0xd0(%rsp), %rdi
callq 0xb132
leaq 0xf0(%rsp), %rdi
callq 0xb290
leaq 0x160(%rsp), %rdi
callq 0xb132
leaq 0x180(%rsp), %rdi
callq 0xb290
leaq 0x1a0(%rsp), %rdi
callq 0xb290
leaq 0x1c0(%rsp), %rdi
callq 0xb290
leaq 0x1e0(%rsp), %rdi
callq 0xb290
leaq 0x238(%rsp), %rdi
callq 0xa976
leaq 0x260(%rsp), %rdi
callq 0xa976
leaq 0x288(%rsp), %rdi
callq 0xa976
leaq 0x2d8(%rsp), %rdi
callq 0xaab6
movq %rbx, %rax
addq $0x738, %rsp            # imm = 0x738
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xbcb50(%rip), %rdi     # 0x102ff2
callq 0x4670
jmp 0x464b9
leaq 0xbc05d(%rip), %rdi     # 0x10250d
movl %ebx, %esi
xorl %eax, %eax
callq 0x4050
pushq $0x1
popq %rdi
callq 0x524c
jmp 0x464ec
jmp 0x464ec
jmp 0x464ec
jmp 0x464ec
jmp 0x464ec
jmp 0x464ec
jmp 0x464ec
movq %rax, %r14
movq %rbx, %rdi
callq 0xaab6
jmp 0x46508
jmp 0x46505
jmp 0x464ec
jmp 0x464ec
jmp 0x464ec
movq %rax, %r14
jmp 0x465b1
movq %rax, %r14
jmp 0x46515
jmp 0x464fd
jmp 0x464fd
movq %rax, %r14
jmp 0x465cb
movq %rax, %r14
jmp 0x465be
movq %rax, %r14
leaq 0xa0(%rsp), %rdi
callq 0xb132
leaq 0x2b0(%rsp), %rdi
callq 0xa976
leaq 0x200(%rsp), %rdi
callq 0xb132
leaq 0x220(%rsp), %rdi
callq 0xb290
leaq 0x120(%rsp), %rdi
callq 0xb290
leaq 0x140(%rsp), %rdi
callq 0xb290
leaq 0xd0(%rsp), %rdi
callq 0xb132
leaq 0xf0(%rsp), %rdi
callq 0xb290
leaq 0x160(%rsp), %rdi
callq 0xb132
leaq 0x180(%rsp), %rdi
callq 0xb290
leaq 0x1a0(%rsp), %rdi
callq 0xb290
leaq 0x1c0(%rsp), %rdi
callq 0xb290
leaq 0x1e0(%rsp), %rdi
callq 0xb290
leaq 0x238(%rsp), %rdi
callq 0xa976
leaq 0x260(%rsp), %rdi
callq 0xa976
leaq 0x288(%rsp), %rdi
callq 0xa976
leaq 0x2d8(%rsp), %rdi
callq 0xaab6
movq %r14, %rdi
callq 0x4780