// File: Luthaf[P]zeopp/voro++/src/unitcell.cc
// Function: voro::unitcell::unitcell(double, double, double, double, double, double)
unitcell::unitcell(double bx_,double bxy_,double by_,double bxz_,double byz_,double bz_)
	: bx(bx_), bxy(bxy_), by(by_), bxz(bxz_), byz(byz_), bz(bz_),
	unit_voro(max_unit_voro_shells*max_unit_voro_shells*4*(bx*bx+by*by+bz*bz)) {
	int i,j,l=1;

	// Initialize the Voronoi cell to be a very large rectangular box
	const double ucx=max_unit_voro_shells*bx,ucy=max_unit_voro_shells*by,ucz=max_unit_voro_shells*bz;
	unit_voro.init(-ucx,ucx,-ucy,ucy,-ucz,ucz);

	// Repeatedly cut the cell by shells of periodic image particles
	while(l<2*max_unit_voro_shells) {

		// Check to see if any of the planes from the current shell
		// will cut the cell
		if(unit_voro_intersect(l)) {

			// If they do, apply the plane cuts from the current
			// shell
			unit_voro_apply(l,0,0);
			for(i=1;i<l;i++) {
				unit_voro_apply(l,i,0);
				unit_voro_apply(-l,i,0);
			}
			for(i=-l;i<=l;i++) unit_voro_apply(i,l,0);
			for(i=1;i<l;i++) for(j=-l+1;j<=l;j++) {
				unit_voro_apply(l,j,i);
				unit_voro_apply(-j,l,i);
				unit_voro_apply(-l,-j,i);
				unit_voro_apply(j,-l,i);
			}
			for(i=-l;i<=l;i++) for(j=-l;j<=l;j++) unit_voro_apply(i,j,l);
		} else {

			// Calculate a bound on the maximum y and z coordinates
			// that could possibly cut the cell. This is based upon
			// a geometric result that particles with z>l can't cut
			// a cell lying within the paraboloid
			// z<=(l*l-x*x-y*y)/(2*l). It is always a tighter bound
			// than the one based on computing the maximum radius
			// of a Voronoi cell vertex.
			max_uv_y=max_uv_z=0;
			double y,z,q,*pts=unit_voro.pts,*pp=pts;
			while(pp<pts+4*unit_voro.p) {
				q=*(pp++);y=*(pp++);z=*pp;pp+=2;q=sqrt(q*q+y*y+z*z);
				if(y+q>max_uv_y) max_uv_y=y+q;
				if(z+q>max_uv_z) max_uv_z=z+q;
			}
			max_uv_z*=0.5;
			max_uv_y*=0.5;
			return;
		}
		l++;
	}

	// If the routine makes it here, then the unit cell still hasn't been
	// completely bounded by the plane cuts. Give the memory error code,
	// because this is mainly a case of hitting a safe limit, than any
	// inherent problem.
	voro_fatal_error("Periodic cell computation failed",VOROPP_MEMORY_ERROR);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x8(%rbp)
movsd %xmm0, -0x10(%rbp)
movsd %xmm1, -0x18(%rbp)
movsd %xmm2, -0x20(%rbp)
movsd %xmm3, -0x28(%rbp)
movsd %xmm4, -0x30(%rbp)
movsd %xmm5, -0x38(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xa8(%rbp)
movsd -0x10(%rbp), %xmm0
movsd %xmm0, (%rax)
movsd -0x18(%rbp), %xmm0
movsd %xmm0, 0x8(%rax)
movsd -0x20(%rbp), %xmm0
movsd %xmm0, 0x10(%rax)
movsd -0x28(%rbp), %xmm0
movsd %xmm0, 0x18(%rax)
movsd -0x30(%rbp), %xmm0
movsd %xmm0, 0x20(%rax)
movsd -0x38(%rbp), %xmm0
movsd %xmm0, 0x28(%rax)
movq %rax, %rdi
addq $0x30, %rdi
movq %rdi, -0xa0(%rbp)
movsd (%rax), %xmm1
movsd 0x10(%rax), %xmm0
mulsd %xmm0, %xmm0
mulsd %xmm1, %xmm1
addsd %xmm0, %xmm1
movsd 0x28(%rax), %xmm0
mulsd %xmm0, %xmm0
addsd %xmm1, %xmm0
movsd 0x962d(%rip), %xmm1     # 0x5c2f8
mulsd %xmm1, %xmm0
callq 0x540e0
movq -0xa8(%rbp), %rax
movq -0xa0(%rbp), %rdi
movl $0x1, -0x44(%rbp)
movsd (%rax), %xmm0
movsd 0x960b(%rip), %xmm1     # 0x5c300
mulsd %xmm1, %xmm0
movsd %xmm0, -0x50(%rbp)
movsd 0x10(%rax), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, -0x58(%rbp)
movsd 0x28(%rax), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, -0x60(%rbp)
movsd -0x50(%rbp), %xmm1
movaps %xmm1, %xmm0
movapd 0x3316(%rip), %xmm6     # 0x56040
pxor %xmm6, %xmm0
movsd -0x58(%rbp), %xmm3
movaps %xmm3, %xmm2
pxor %xmm6, %xmm2
movsd -0x60(%rbp), %xmm5
movaps %xmm5, %xmm4
pxor %xmm6, %xmm4
callq 0x49730
jmp 0x52d4d
jmp 0x52d4f
cmpl $0x14, -0x44(%rbp)
jge 0x530f1
movq -0xa8(%rbp), %rdi
movl -0x44(%rbp), %esi
callq 0x53120
movb %al, -0xa9(%rbp)
jmp 0x52d70
movb -0xa9(%rbp), %al
testb $0x1, %al
jne 0x52d7f
jmp 0x52f2b
movq -0xa8(%rbp), %rdi
movl -0x44(%rbp), %esi
xorl %ecx, %ecx
movl %ecx, %edx
callq 0x54120
jmp 0x52d94
movl $0x1, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0x44(%rbp), %eax
jge 0x52dfb
movq -0xa8(%rbp), %rdi
movl -0x44(%rbp), %esi
movl -0x3c(%rbp), %edx
xorl %ecx, %ecx
callq 0x54120
jmp 0x52db9
movq -0xa8(%rbp), %rdi
movl -0x44(%rbp), %esi
negl %esi
movl -0x3c(%rbp), %edx
xorl %ecx, %ecx
callq 0x54120
jmp 0x52dd1
jmp 0x52dd3
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x52d9b
movq -0xa0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
callq 0x6810
jmp 0x5310d
xorl %eax, %eax
subl -0x44(%rbp), %eax
movl %eax, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0x44(%rbp), %eax
jg 0x52e2e
movq -0xa8(%rbp), %rdi
movl -0x3c(%rbp), %esi
movl -0x44(%rbp), %edx
xorl %ecx, %ecx
callq 0x54120
jmp 0x52e21
jmp 0x52e23
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x52e03
movl $0x1, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0x44(%rbp), %eax
jge 0x52ed5
xorl %eax, %eax
subl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
movl -0x40(%rbp), %eax
cmpl -0x44(%rbp), %eax
jg 0x52ec5
movq -0xa8(%rbp), %rdi
movl -0x44(%rbp), %esi
movl -0x40(%rbp), %edx
movl -0x3c(%rbp), %ecx
callq 0x54120
jmp 0x52e6b
movq -0xa8(%rbp), %rdi
movl -0x40(%rbp), %esi
negl %esi
movl -0x44(%rbp), %edx
movl -0x3c(%rbp), %ecx
callq 0x54120
jmp 0x52e84
movq -0xa8(%rbp), %rdi
movl -0x44(%rbp), %esi
negl %esi
movl -0x40(%rbp), %edx
negl %edx
movl -0x3c(%rbp), %ecx
callq 0x54120
jmp 0x52e9f
movq -0xa8(%rbp), %rdi
movl -0x40(%rbp), %esi
movl -0x44(%rbp), %edx
negl %edx
movl -0x3c(%rbp), %ecx
callq 0x54120
jmp 0x52eb8
jmp 0x52eba
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
jmp 0x52e4c
jmp 0x52ec7
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x52e35
xorl %eax, %eax
subl -0x44(%rbp), %eax
movl %eax, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0x44(%rbp), %eax
jg 0x52f26
xorl %eax, %eax
subl -0x44(%rbp), %eax
movl %eax, -0x40(%rbp)
movl -0x40(%rbp), %eax
cmpl -0x44(%rbp), %eax
jg 0x52f19
movq -0xa8(%rbp), %rdi
movl -0x3c(%rbp), %esi
movl -0x40(%rbp), %edx
movl -0x44(%rbp), %ecx
callq 0x54120
jmp 0x52f0c
jmp 0x52f0e
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
jmp 0x52eed
jmp 0x52f1b
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x52edd
jmp 0x530e3
movq -0xa8(%rbp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, 0x120(%rax)
xorps %xmm0, %xmm0
movsd %xmm0, 0x118(%rax)
movq 0x70(%rax), %rax
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0xa8(%rbp), %rdx
movq -0x98(%rbp), %rax
movq -0x90(%rbp), %rcx
movl 0x4c(%rdx), %edx
shll $0x2, %edx
movslq %edx, %rdx
shlq $0x3, %rdx
addq %rdx, %rcx
cmpq %rcx, %rax
jae 0x530aa
movq -0x98(%rbp), %rax
movq %rax, %rcx
addq $0x8, %rcx
movq %rcx, -0x98(%rbp)
movsd (%rax), %xmm0
movsd %xmm0, -0x88(%rbp)
movq -0x98(%rbp), %rax
movq %rax, %rcx
addq $0x8, %rcx
movq %rcx, -0x98(%rbp)
movsd (%rax), %xmm0
movsd %xmm0, -0x78(%rbp)
movq -0x98(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x80(%rbp)
movq -0x98(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x98(%rbp)
movsd -0x88(%rbp), %xmm1
movsd -0x88(%rbp), %xmm2
movsd -0x78(%rbp), %xmm0
mulsd -0x78(%rbp), %xmm0
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
movsd -0x80(%rbp), %xmm0
movsd -0x80(%rbp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
callq 0x20f0
movq -0xa8(%rbp), %rax
movsd %xmm0, -0x88(%rbp)
movsd -0x78(%rbp), %xmm0
addsd -0x88(%rbp), %xmm0
ucomisd 0x118(%rax), %xmm0
jbe 0x5306b
movq -0xa8(%rbp), %rax
movsd -0x78(%rbp), %xmm0
addsd -0x88(%rbp), %xmm0
movsd %xmm0, 0x118(%rax)
movq -0xa8(%rbp), %rax
movsd -0x80(%rbp), %xmm0
addsd -0x88(%rbp), %xmm0
ucomisd 0x120(%rax), %xmm0
jbe 0x530a5
movq -0xa8(%rbp), %rax
movsd -0x80(%rbp), %xmm0
addsd -0x88(%rbp), %xmm0
movsd %xmm0, 0x120(%rax)
jmp 0x52f61
movq -0xa8(%rbp), %rax
movsd 0x2f77(%rip), %xmm0     # 0x56030
mulsd 0x120(%rax), %xmm0
movsd %xmm0, 0x120(%rax)
movsd 0x2f5f(%rip), %xmm0     # 0x56030
mulsd 0x118(%rax), %xmm0
movsd %xmm0, 0x118(%rax)
jmp 0x53104
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x52d4f
leaq 0x9218(%rip), %rdi      # 0x5c310
movl $0x2, %esi
callq 0x1b690
jmp 0x53104
addq $0xb0, %rsp
popq %rbp
retq
movq -0x68(%rbp), %rdi
callq 0x2220
nopw %cs:(%rax,%rax)