// File: /workspace/github_cpp_makefile_star2_O2/Luthaf[P]zeopp/networkio.cc
// Function: writeToXYZ(char*, ATOM_NETWORK*, bool, bool)
bool writeToXYZ(char *filename, ATOM_NETWORK *cell, bool is_supercell, bool is_duplicate_perimeter_atoms){
  int num_cells = SUPERCELL_SIZE; //defined in networkio.h
  if(!is_supercell) num_cells = 1;
  fstream output;
  output.open(filename, fstream::out);
  if(!output.is_open()){
    cerr << "Error: Failed to open .xyz output file " << filename << endl;
    //cerr << "Exiting ..." << "\n";
    //exit(1);
    return false;
  }
  else{
    cout << "Writing atom network information to " << filename << "\n";

    //1) construct a new vector of atoms, which contains any supercell projections and duplicates
    vector<ATOM> new_atoms;
    for(int i=0; i<cell->numAtoms; i++) {
      ATOM atom = cell->atoms.at(i);
      Point orig_abc(atom.a_coord, atom.b_coord, atom.c_coord);
      Point uc_abc = cell->shiftABCInUC(orig_abc);
      //first, determine all the supercell images of this atom as required
      for(int a=0; a<num_cells; a++) {
        for(int b=0; b<num_cells; b++) {
          for(int c=0; c<num_cells; c++) {
            atom.a_coord=uc_abc[0]+a;
            atom.b_coord=uc_abc[1]+b;
            atom.c_coord=uc_abc[2]+c;
            // Do xyz conversion later, when needed for output
            new_atoms.push_back(atom);
            //now we have this atom, be it the original or a supercell projection, find the duplicates
            if(is_duplicate_perimeter_atoms) {
              double dupe_thresh = 0.001;
              if(atom.a_coord<dupe_thresh) {
                ATOM dupe = atom;
                dupe.a_coord = atom.a_coord+num_cells;
                new_atoms.push_back(dupe);
              }
              if(atom.b_coord<dupe_thresh) {
                ATOM dupe = atom;
                dupe.b_coord = atom.b_coord+num_cells;
                new_atoms.push_back(dupe);
              }
              if(atom.c_coord<dupe_thresh) {
                ATOM dupe = atom;
                dupe.c_coord = atom.c_coord+num_cells;
                new_atoms.push_back(dupe);
              }
              if(atom.a_coord<dupe_thresh && atom.b_coord<dupe_thresh) {
                ATOM dupe = atom;
                dupe.a_coord = atom.a_coord+num_cells;
                dupe.b_coord = atom.b_coord+num_cells;
                new_atoms.push_back(dupe);
              }
              if(atom.a_coord<dupe_thresh && atom.c_coord<dupe_thresh) {
                ATOM dupe = atom;
                dupe.a_coord = atom.a_coord+num_cells;
                dupe.c_coord = atom.c_coord+num_cells;
                new_atoms.push_back(dupe);
              }
              if(atom.b_coord<dupe_thresh && atom.c_coord<dupe_thresh) {
                ATOM dupe = atom;
                dupe.b_coord = atom.b_coord+num_cells;
                dupe.c_coord = atom.c_coord+num_cells;
                new_atoms.push_back(dupe);
              }
              if(atom.a_coord<dupe_thresh && atom.b_coord<dupe_thresh && atom.c_coord<dupe_thresh) {
                ATOM dupe = atom;
                dupe.a_coord = atom.a_coord+num_cells;
                dupe.b_coord = atom.b_coord+num_cells;
                dupe.c_coord = atom.c_coord+num_cells;
                new_atoms.push_back(dupe);
              }
              if(atom.a_coord>((double)(num_cells))-dupe_thresh) {
                ATOM dupe = atom;
                dupe.a_coord = atom.a_coord-num_cells;
                new_atoms.push_back(dupe);
              }
              if(atom.b_coord>((double)(num_cells))-dupe_thresh) {
                ATOM dupe = atom;
                dupe.b_coord = atom.b_coord-num_cells;
                new_atoms.push_back(dupe);
              }
              if(atom.c_coord>((double)(num_cells))-dupe_thresh) {
                ATOM dupe = atom;
                dupe.c_coord = atom.c_coord-num_cells;
                new_atoms.push_back(dupe);
              }
              if(atom.a_coord>((double)(num_cells))-dupe_thresh && atom.b_coord>((double)(num_cells))-dupe_thresh) {
                ATOM dupe = atom;
                dupe.a_coord = atom.a_coord-num_cells;
                dupe.b_coord = atom.b_coord-num_cells;
                new_atoms.push_back(dupe);
              }
              if(atom.a_coord>((double)(num_cells))-dupe_thresh && atom.c_coord>((double)(num_cells))-dupe_thresh) {
                ATOM dupe = atom;
                dupe.a_coord = atom.a_coord-num_cells;
                dupe.c_coord = atom.c_coord-num_cells;
                new_atoms.push_back(dupe);
              }
              if(atom.b_coord>((double)(num_cells))-dupe_thresh && atom.c_coord>((double)(num_cells))-dupe_thresh) {
                ATOM dupe = atom;
                dupe.b_coord = atom.b_coord-num_cells;
                dupe.c_coord = atom.c_coord-num_cells;
                new_atoms.push_back(dupe);
              }
              if(atom.a_coord>((double)(num_cells))-dupe_thresh && atom.b_coord>((double)(num_cells))-dupe_thresh && atom.c_coord>((double)(num_cells))-dupe_thresh) {
                ATOM dupe = atom;
                dupe.a_coord = atom.a_coord-num_cells;
                dupe.b_coord = atom.b_coord-num_cells;
                dupe.c_coord = atom.c_coord-num_cells;
                new_atoms.push_back(dupe);
              }
            }
          }
        }
      }
    }

    //2) write atom data
    output << new_atoms.size() << "\n" << "\n";
    for(int i=0; i<new_atoms.size(); i++) {
      Point p = cell->abc_to_xyz(new_atoms.at(i).a_coord, new_atoms.at(i).b_coord, new_atoms.at(i).c_coord);
      output << new_atoms.at(i).type << " " << p[0] << " " << p[1] << " " << p[2] << "\n";
    }
  }
  output.close();
  return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x428, %rsp            # imm = 0x428
movl %ecx, 0x5c(%rsp)
movl %edx, %r15d
movq %rsi, 0x48(%rsp)
movq %rdi, %rbx
leaq 0x218(%rsp), %r14
movq %r14, %rdi
callq 0x4540
pushq $0x10
popq %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x4410
leaq 0x298(%rsp), %rdi
callq 0x4130
movb %al, 0x27(%rsp)
testb %al, %al
je 0x238c0
movq 0x12ce12(%rip), %rdi    # 0x14ffc0
leaq 0xda215(%rip), %rsi     # 0xfd3ca
callq 0x4480
movq %rax, %rdi
movq %rbx, %rsi
callq 0x4480
leaq 0xdf3b2(%rip), %rsi     # 0x10257e
movq %rax, %rdi
callq 0x4480
incl %r15d
xorps %xmm0, %xmm0
leaq 0x110(%rsp), %r12
andq $0x0, 0x10(%r12)
movaps %xmm0, (%r12)
movq 0x48(%rsp), %rax
addq $0x2f0, %rax            # imm = 0x2F0
movq %rax, 0x130(%rsp)
cvtsi2sd %r15d, %xmm0
movsd 0xd990b(%rip), %xmm1    # 0xfcb18
addsd %xmm0, %xmm1
movsd %xmm1, 0x28(%rsp)
movapd %xmm0, 0x30(%rsp)
unpcklpd %xmm0, %xmm0            # xmm0 = xmm0[0,0]
movapd %xmm0, 0x60(%rsp)
xorl %esi, %esi
leaq 0x78(%rsp), %r13
leaq 0x200(%rsp), %r14
leaq 0x150(%rsp), %rbx
movq 0x48(%rsp), %rax
movslq 0x110(%rax), %rax
cmpq %rax, %rsi
jge 0x23909
movq 0x130(%rsp), %rdi
movq %rsi, 0x138(%rsp)
callq 0xa73a
movq %r13, %rdi
movq %rax, %rsi
callq 0xa75c
movsd 0x90(%rsp), %xmm0
movsd 0x98(%rsp), %xmm1
movsd 0xa0(%rsp), %xmm2
leaq 0x1e8(%rsp), %rdi
callq 0x63c46
movq 0x1f8(%rsp), %rax
movq %rax, 0x10(%rsp)
movupd 0x1e8(%rsp), %xmm0
movupd %xmm0, (%rsp)
movq %r14, %rdi
movq 0x48(%rsp), %rsi
callq 0x3f94a
xorl %eax, %eax
cmpl %r15d, %eax
je 0x238a8
movl %eax, 0x54(%rsp)
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0x140(%rsp)
xorl %eax, %eax
cmpl %r15d, %eax
je 0x2389d
movl %eax, 0x58(%rsp)
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0x148(%rsp)
xorl %ebp, %ebp
cmpl %ebp, %r15d
je 0x23892
movq %r14, %rdi
xorl %esi, %esi
callq 0x63c78
movsd (%rax), %xmm0
addsd 0x140(%rsp), %xmm0
movsd %xmm0, 0x90(%rsp)
movq %r14, %rdi
pushq $0x1
popq %rsi
callq 0x63c78
movsd (%rax), %xmm0
addsd 0x148(%rsp), %xmm0
movsd %xmm0, 0x98(%rsp)
movq %r14, %rdi
pushq $0x2
popq %rsi
callq 0x63c78
cvtsi2sd %ebp, %xmm0
addsd (%rax), %xmm0
movsd %xmm0, 0xa0(%rsp)
movq %r12, %rdi
movq %r13, %rsi
callq 0xa7d8
cmpb $0x0, 0x5c(%rsp)
je 0x2388b
movsd 0xd8cc7(%rip), %xmm1    # 0xfc048
ucomisd 0x90(%rsp), %xmm1
jbe 0x233ca
movq %rbx, %rdi
movq %r13, %rsi
callq 0xa75c
movsd 0x90(%rsp), %xmm0
addsd 0x30(%rsp), %xmm0
movsd %xmm0, 0x168(%rsp)
movq %r12, %rdi
movq %rbx, %rsi
callq 0xa7d8
movq %rbx, %rdi
callq 0xa808
movsd 0xd8c7e(%rip), %xmm1    # 0xfc048
ucomisd 0x98(%rsp), %xmm1
jbe 0x23413
movq %rbx, %rdi
movq %r13, %rsi
callq 0xa75c
movsd 0x98(%rsp), %xmm0
addsd 0x30(%rsp), %xmm0
movsd %xmm0, 0x170(%rsp)
movq %r12, %rdi
movq %rbx, %rsi
callq 0xa7d8
movq %rbx, %rdi
callq 0xa808
movsd 0xd8c35(%rip), %xmm1    # 0xfc048
ucomisd 0xa0(%rsp), %xmm1
jbe 0x2345c
movq %rbx, %rdi
movq %r13, %rsi
callq 0xa75c
movsd 0xa0(%rsp), %xmm0
addsd 0x30(%rsp), %xmm0
movsd %xmm0, 0x178(%rsp)
movq %r12, %rdi
movq %rbx, %rsi
callq 0xa7d8
movq %rbx, %rdi
callq 0xa808
movsd 0xd8bec(%rip), %xmm1    # 0xfc048
movsd 0x90(%rsp), %xmm0
ucomisd %xmm0, %xmm1
jbe 0x234b5
ucomisd 0x98(%rsp), %xmm1
jbe 0x234b5
movq %rbx, %rdi
movq %r13, %rsi
callq 0xa75c
movupd 0x90(%rsp), %xmm0
addpd 0x60(%rsp), %xmm0
movupd %xmm0, 0x168(%rsp)
movq %r12, %rdi
movq %rbx, %rsi
callq 0xa7d8
movq %rbx, %rdi
callq 0xa808
movsd 0x90(%rsp), %xmm0
movsd 0xd8b8b(%rip), %xmm1    # 0xfc048
ucomisd %xmm0, %xmm1
movsd 0xa0(%rsp), %xmm0
jbe 0x2352b
ucomisd %xmm0, %xmm1
jbe 0x2352b
movq %rbx, %rdi
movq %r13, %rsi
callq 0xa75c
movsd 0x90(%rsp), %xmm0
movapd 0x30(%rsp), %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, 0x168(%rsp)
movsd 0xa0(%rsp), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x178(%rsp)
movq %r12, %rdi
movq %rbx, %rsi
callq 0xa7d8
movq %rbx, %rdi
callq 0xa808
movsd 0xa0(%rsp), %xmm0
movsd 0x98(%rsp), %xmm1
movsd 0xd8b0c(%rip), %xmm2    # 0xfc048
ucomisd %xmm1, %xmm2
jbe 0x23590
ucomisd %xmm0, %xmm2
jbe 0x23590
movq %rbx, %rdi
movq %r13, %rsi
callq 0xa75c
movupd 0x98(%rsp), %xmm0
addpd 0x60(%rsp), %xmm0
movupd %xmm0, 0x170(%rsp)
movq %r12, %rdi
movq %rbx, %rsi
callq 0xa7d8
movq %rbx, %rdi
callq 0xa808
movsd 0x98(%rsp), %xmm1
movsd 0xa0(%rsp), %xmm0
movsd 0x90(%rsp), %xmm2
movsd 0xd8aa7(%rip), %xmm3    # 0xfc048
ucomisd %xmm2, %xmm3
jbe 0x2360a
ucomisd %xmm1, %xmm3
jbe 0x2360a
ucomisd %xmm0, %xmm3
jbe 0x2360a
movq %rbx, %rdi
movq %r13, %rsi
callq 0xa75c
movupd 0x90(%rsp), %xmm0
addpd 0x60(%rsp), %xmm0
movupd %xmm0, 0x168(%rsp)
movsd 0xa0(%rsp), %xmm0
addsd 0x30(%rsp), %xmm0
movsd %xmm0, 0x178(%rsp)
movq %r12, %rdi
movq %rbx, %rsi
callq 0xa7d8
movq %rbx, %rdi
callq 0xa808
movsd 0x90(%rsp), %xmm2
movsd 0x28(%rsp), %xmm3
ucomisd %xmm3, %xmm2
jbe 0x23652
movq %rbx, %rdi
movq %r13, %rsi
callq 0xa75c
movsd 0x90(%rsp), %xmm0
subsd 0x30(%rsp), %xmm0
movsd %xmm0, 0x168(%rsp)
movq %r12, %rdi
movq %rbx, %rsi
callq 0xa7d8
movq %rbx, %rdi
callq 0xa808
movsd 0x28(%rsp), %xmm3
movsd 0x98(%rsp), %xmm0
ucomisd %xmm3, %xmm0
jbe 0x2369d
movq %rbx, %rdi
movq %r13, %rsi
callq 0xa75c
movsd 0x98(%rsp), %xmm0
subsd 0x30(%rsp), %xmm0
movsd %xmm0, 0x170(%rsp)
movq %r12, %rdi
movq %rbx, %rsi
callq 0xa7d8
movq %rbx, %rdi
callq 0xa808
movsd 0x28(%rsp), %xmm3
movsd 0xa0(%rsp), %xmm0
ucomisd %xmm3, %xmm0
jbe 0x236e8
movq %rbx, %rdi
movq %r13, %rsi
callq 0xa75c
movsd 0xa0(%rsp), %xmm0
subsd 0x30(%rsp), %xmm0
movsd %xmm0, 0x178(%rsp)
movq %r12, %rdi
movq %rbx, %rsi
callq 0xa7d8
movq %rbx, %rdi
callq 0xa808
movsd 0x28(%rsp), %xmm3
movsd 0x90(%rsp), %xmm0
ucomisd %xmm3, %xmm0
jbe 0x23745
movsd 0x98(%rsp), %xmm1
ucomisd %xmm3, %xmm1
jbe 0x23745
movq %rbx, %rdi
movq %r13, %rsi
callq 0xa75c
movupd 0x90(%rsp), %xmm0
subpd 0x60(%rsp), %xmm0
movupd %xmm0, 0x168(%rsp)
movq %r12, %rdi
movq %rbx, %rsi
callq 0xa7d8
movq %rbx, %rdi
callq 0xa808
movsd 0x90(%rsp), %xmm0
movsd 0x28(%rsp), %xmm1
ucomisd %xmm1, %xmm0
movsd 0xa0(%rsp), %xmm0
jbe 0x237b9
ucomisd %xmm1, %xmm0
jbe 0x237b9
movq %rbx, %rdi
movq %r13, %rsi
callq 0xa75c
movsd 0x90(%rsp), %xmm0
movsd 0xa0(%rsp), %xmm1
movapd 0x30(%rsp), %xmm2
subsd %xmm2, %xmm0
movsd %xmm0, 0x168(%rsp)
subsd %xmm2, %xmm1
movsd %xmm1, 0x178(%rsp)
movq %r12, %rdi
movq %rbx, %rsi
callq 0xa7d8
movq %rbx, %rdi
callq 0xa808
movsd 0xa0(%rsp), %xmm0
movsd 0x98(%rsp), %xmm1
movsd 0x28(%rsp), %xmm2
ucomisd %xmm2, %xmm1
jbe 0x2381c
ucomisd %xmm2, %xmm0
jbe 0x2381c
movq %rbx, %rdi
movq %r13, %rsi
callq 0xa75c
movupd 0x98(%rsp), %xmm0
subpd 0x60(%rsp), %xmm0
movupd %xmm0, 0x170(%rsp)
movq %r12, %rdi
movq %rbx, %rsi
callq 0xa7d8
movq %rbx, %rdi
callq 0xa808
movsd 0x98(%rsp), %xmm1
movsd 0xa0(%rsp), %xmm0
movsd 0x90(%rsp), %xmm2
ucomisd 0x28(%rsp), %xmm2
jbe 0x2388b
ucomisd 0x28(%rsp), %xmm1
jbe 0x2388b
ucomisd 0x28(%rsp), %xmm0
jbe 0x2388b
movq %rbx, %rdi
movq %r13, %rsi
callq 0xa75c
movupd 0x90(%rsp), %xmm0
subpd 0x60(%rsp), %xmm0
movupd %xmm0, 0x168(%rsp)
movsd 0xa0(%rsp), %xmm0
subsd 0x30(%rsp), %xmm0
movsd %xmm0, 0x178(%rsp)
movq %r12, %rdi
movq %rbx, %rsi
callq 0xa7d8
movq %rbx, %rdi
callq 0xa808
incl %ebp
jmp 0x232fd
movl 0x58(%rsp), %eax
incl %eax
jmp 0x232e1
movl 0x54(%rsp), %eax
incl %eax
jmp 0x232c5
movq %r13, %rdi
callq 0xa808
movq 0x138(%rsp), %rsi
incq %rsi
jmp 0x2323e
movq 0x12c729(%rip), %rdi    # 0x14fff0
leaq 0xd9e1f(%rip), %rsi     # 0xfd6ed
callq 0x4480
movq %rax, %rdi
movq %rbx, %rsi
callq 0x4480
movq %rax, %rdi
callq 0x4230
leaq 0x218(%rsp), %rdi
callq 0x4120
movb 0x27(%rsp), %al
addq $0x428, %rsp            # imm = 0x428
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x228(%rsp), %rdi
movq 0x118(%rsp), %rax
subq 0x110(%rsp), %rax
movl $0x98, %ecx
cqto
idivq %rcx
movq %rax, %rsi
callq 0x42e0
leaq 0xdec44(%rip), %rsi     # 0x10257e
movq %rax, %rdi
callq 0x4480
leaq 0xdec35(%rip), %rsi     # 0x10257e
movq %rax, %rdi
callq 0x4480
xorl %r14d, %r14d
leaq 0x110(%rsp), %r15
leaq 0x78(%rsp), %r12
leaq 0xe0baa(%rip), %r13     # 0x104512
leaq 0xdec0f(%rip), %rbp     # 0x10257e
movq 0x118(%rsp), %rax
subq 0x110(%rsp), %rax
cqto
movl $0x98, %ecx
idivq %rcx
cmpq %r14, %rax
jbe 0x23a87
movq %r15, %rdi
movq %r14, %rsi
callq 0xa73a
movsd 0x18(%rax), %xmm0
movsd %xmm0, 0x28(%rsp)
movq %r15, %rdi
movq %r14, %rsi
callq 0xa73a
movsd 0x20(%rax), %xmm0
movsd %xmm0, 0x30(%rsp)
movq %r15, %rdi
movq %r14, %rsi
callq 0xa73a
movsd 0x28(%rax), %xmm2
movq %r12, %rdi
movq 0x48(%rsp), %rsi
movsd 0x28(%rsp), %xmm0
movsd 0x30(%rsp), %xmm1
callq 0x3f0e6
movq %r15, %rdi
movq %r14, %rsi
callq 0xa73a
addq $0x40, %rax
leaq 0x228(%rsp), %rdi
movq %rax, %rsi
callq 0x43f0
movq %rax, %rdi
movq %r13, %rsi
callq 0x4480
movq %rax, %rbx
movq %r12, %rdi
xorl %esi, %esi
callq 0x63c78
movsd (%rax), %xmm0
movq %rbx, %rdi
callq 0x46c0
movq %rax, %rdi
movq %r13, %rsi
callq 0x4480
movq %rax, %rbx
movq %r12, %rdi
pushq $0x1
popq %rsi
callq 0x63c78
movsd (%rax), %xmm0
movq %rbx, %rdi
callq 0x46c0
movq %rax, %rdi
movq %r13, %rsi
callq 0x4480
movq %rax, %rbx
movq %r12, %rdi
pushq $0x2
popq %rsi
callq 0x63c78
movsd (%rax), %xmm0
movq %rbx, %rdi
callq 0x46c0
movq %rax, %rdi
movq %rbp, %rsi
callq 0x4480
incq %r14
jmp 0x2396f
leaq 0x110(%rsp), %rdi
callq 0xb110
leaq 0x218(%rsp), %rdi
callq 0x4080
jmp 0x238e6
jmp 0x23ab3
jmp 0x23b00
jmp 0x23b00
jmp 0x23ab3
movq %rax, %rbx
jmp 0x23b1a
movq %rax, %rbx
jmp 0x23b0d
jmp 0x23aec
jmp 0x23aec
jmp 0x23b00
jmp 0x23b00
jmp 0x23aec
jmp 0x23b00
jmp 0x23aec
jmp 0x23b00
jmp 0x23aec
jmp 0x23b00
jmp 0x23b00
jmp 0x23aec
jmp 0x23aec
jmp 0x23aec
jmp 0x23b00
jmp 0x23b00
jmp 0x23aec
jmp 0x23b00
jmp 0x23aec
jmp 0x23b00
jmp 0x23aec
jmp 0x23b00
jmp 0x23aec
jmp 0x23b00
jmp 0x23aec
jmp 0x23b00
movq %rax, %rbx
leaq 0x150(%rsp), %rdi
callq 0xa808
jmp 0x23b03
jmp 0x23b00
movq %rax, %rbx
leaq 0x78(%rsp), %rdi
callq 0xa808
leaq 0x110(%rsp), %rdi
callq 0xb110
leaq 0x218(%rsp), %rdi
callq 0x4120
movq %rbx, %rdi
callq 0x4780