// File: Luthaf[P]zeopp/networkstorage.cc
// Function: ATOM_NETWORK::getSmallestSupercell(double)
TRIPLET ATOM_NETWORK::getSmallestSupercell(double diam) {
    //1) set lower bound based on lengths of cell axes
    int na = 1+ (diam/a);
    int nb = 1+ (diam/b);
    int nc = 1+ (diam/c);
    
    int fewest_cells = -1; //no supercell yet successful
    TRIPLET smallest_supercell(-1,-1,-1);
    
    //2) search all possible supercell sizes to find the smallest one satisfying
    // the minimum image convention for this radius
    TRIPLET lb(na, nb, nc);
    vector<TRIPLET> supercells;
    supercells.push_back(lb);
    while(supercells.size()>0) {
        //3) take the oldest candidate on the vector
        TRIPLET s = supercells.at(0); //oldest supercell candidate, s
        for(int i=0; i<supercells.size()-1; i++)
            supercells.at(i) = supercells.at(i+1); //shift vector up
        supercells.pop_back(); //delete last, which is now duplicated at last-1
        int num_cells = s.x*s.y*s.z;
        //4) is s a potential new smallest supercell?
        if(num_cells<fewest_cells || fewest_cells<0) {
            //5) does s satisfy the minimum image convention?
            int status = check_sphere_overlap(s.x, s.y, s.z, diam, this); //For time being
            if(status==-1) {
                printf("WARNING: bad unit cell angles!\n");
                return smallest_supercell;
            } else if(status==1) { //acceptable!
                fewest_cells = num_cells;
                smallest_supercell = s;
                //printf("smallest satisfactory supercell so far: (%d %d %d) =
                //%d cells\n", s.a, s.b, s.c, num_cells);
            } else { //unacceptable - try larger supercells in each direction
                TRIPLET s2(s.x+1, s.y, s.z);
                TRIPLET s3(s.x, s.y+1, s.z);
                TRIPLET s4(s.x, s.y, s.z+1);
                supercells.push_back(s2);
                supercells.push_back(s3);
                supercells.push_back(s4);
            }
        }
    }
    return smallest_supercell;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x120, %rsp            # imm = 0x120
movq %rdi, -0xf8(%rbp)
movq %rdi, %rax
movq %rax, -0xf0(%rbp)
movq %rsi, -0x8(%rbp)
movsd %xmm0, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xe8(%rbp)
movsd -0x10(%rbp), %xmm0
movsd 0x8(%rax), %xmm1
divsd %xmm1, %xmm0
movsd 0x15b3da(%rip), %xmm1   # 0x1f2050
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %ecx
movl %ecx, -0x14(%rbp)
movsd -0x10(%rbp), %xmm0
movsd 0x10(%rax), %xmm2
divsd %xmm2, %xmm0
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %ecx
movl %ecx, -0x18(%rbp)
movsd -0x10(%rbp), %xmm0
movsd 0x18(%rax), %xmm2
divsd %xmm2, %xmm0
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, -0x1c(%rbp)
movl $0xffffffff, -0x20(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
movl %ecx, %esi
movl %ecx, %edx
callq 0xea7c0
movl -0x14(%rbp), %esi
movl -0x18(%rbp), %edx
movl -0x1c(%rbp), %ecx
leaq -0x38(%rbp), %rdi
movq %rdi, -0xd8(%rbp)
callq 0xea7c0
leaq -0x50(%rbp), %rdi
movq %rdi, -0xe0(%rbp)
callq 0xae2e0
movq -0xe0(%rbp), %rdi
movq -0xd8(%rbp), %rsi
callq 0xae300
jmp 0x96d06
jmp 0x96d08
leaq -0x50(%rbp), %rdi
callq 0xae370
cmpq $0x0, %rax
jbe 0x96f2d
xorl %eax, %eax
movl %eax, %esi
leaq -0x50(%rbp), %rdi
callq 0xae3a0
movq %rax, -0x100(%rbp)
jmp 0x96d31
movq -0x100(%rbp), %rax
movq (%rax), %rcx
movq %rcx, -0x74(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0x6c(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0x64(%rbp)
movl $0x0, -0x78(%rbp)
movslq -0x78(%rbp), %rax
movq %rax, -0x108(%rbp)
leaq -0x50(%rbp), %rdi
callq 0xae370
movq %rax, %rcx
movq -0x108(%rbp), %rax
subq $0x1, %rcx
cmpq %rcx, %rax
jae 0x96df9
movl -0x78(%rbp), %eax
incl %eax
movslq %eax, %rsi
leaq -0x50(%rbp), %rdi
callq 0xae3a0
movq %rax, -0x110(%rbp)
jmp 0x96d97
movslq -0x78(%rbp), %rsi
leaq -0x50(%rbp), %rdi
callq 0xae3a0
movq %rax, -0x118(%rbp)
jmp 0x96dad
movq -0x118(%rbp), %rax
movq -0x110(%rbp), %rcx
movq (%rcx), %rdx
movq %rdx, (%rax)
movq 0x8(%rcx), %rdx
movq %rdx, 0x8(%rax)
movq 0x10(%rcx), %rcx
movq %rcx, 0x10(%rax)
movl -0x78(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x78(%rbp)
jmp 0x96d56
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x50(%rbp), %rdi
callq 0xae410
jmp 0x96f50
leaq -0x50(%rbp), %rdi
callq 0xae3e0
movl -0x68(%rbp), %eax
imull -0x64(%rbp), %eax
imull -0x60(%rbp), %eax
movl %eax, -0x7c(%rbp)
movl -0x7c(%rbp), %eax
cmpl -0x20(%rbp), %eax
jl 0x96e22
cmpl $0x0, -0x20(%rbp)
jge 0x96f28
movq -0xe8(%rbp), %rcx
movl -0x68(%rbp), %edi
movl -0x64(%rbp), %esi
movl -0x60(%rbp), %edx
movsd -0x10(%rbp), %xmm0
callq 0x96f60
movl %eax, -0x11c(%rbp)
jmp 0x96e44
movl -0x11c(%rbp), %eax
movl %eax, -0x80(%rbp)
cmpl $-0x1, -0x80(%rbp)
jne 0x96e72
leaq 0x160c74(%rip), %rdi    # 0x1f7ace
xorl %eax, %eax
callq 0x5070
jmp 0x96e63
movl $0x1, -0x84(%rbp)
jmp 0x96f37
cmpl $0x1, -0x80(%rbp)
jne 0x96ea1
movq -0xf8(%rbp), %rax
movl -0x7c(%rbp), %ecx
movl %ecx, -0x20(%rbp)
movq -0x74(%rbp), %rcx
movq %rcx, (%rax)
movq -0x6c(%rbp), %rcx
movq %rcx, 0x8(%rax)
movq -0x64(%rbp), %rcx
movq %rcx, 0x10(%rax)
jmp 0x96f24
movl -0x68(%rbp), %esi
movl -0x64(%rbp), %edx
incl %esi
movl -0x60(%rbp), %ecx
leaq -0x9c(%rbp), %rdi
callq 0xea7c0
jmp 0x96eba
movl -0x68(%rbp), %esi
movl -0x64(%rbp), %edx
incl %edx
movl -0x60(%rbp), %ecx
leaq -0xb4(%rbp), %rdi
callq 0xea7c0
jmp 0x96ed3
movl -0x68(%rbp), %esi
movl -0x64(%rbp), %edx
movl -0x60(%rbp), %ecx
incl %ecx
leaq -0xcc(%rbp), %rdi
callq 0xea7c0
jmp 0x96eec
leaq -0x50(%rbp), %rdi
leaq -0x9c(%rbp), %rsi
callq 0xae300
jmp 0x96efe
leaq -0x50(%rbp), %rdi
leaq -0xb4(%rbp), %rsi
callq 0xae300
jmp 0x96f10
leaq -0x50(%rbp), %rdi
leaq -0xcc(%rbp), %rsi
callq 0xae300
jmp 0x96f22
jmp 0x96f24
jmp 0x96f26
jmp 0x96f28
jmp 0x96d08
movl $0x1, -0x84(%rbp)
leaq -0x50(%rbp), %rdi
callq 0xae410
movq -0xf0(%rbp), %rax
addq $0x120, %rsp            # imm = 0x120
popq %rbp
retq
movq -0x58(%rbp), %rdi
callq 0x58f0
nopl (%rax)