// File: sus304[P]ForRocket/src/environment/satmo1976.cpp
// Function: standardatmosphere1976::LowerAtmosphere(double)
std::vector<double> standardatmosphere1976::LowerAtmosphere(double geometric_altitude) {
    using Layer = std::array<double, 8>;
    Layer height_array = {0.0, 11.0, 20.0, 32.0, 47.0, 51.0, 71.0, 84.852};  // [km] geopotential height
    Layer temperature_gradient_array = {-6.5, 0.0, 1.0, 2.8, 0.0, -2.8, -2.0, 0.0};  // [K/km] Temperature gradient
    Layer temperature_array = {288.15, 216.65, 216.65, 228.65, 270.65, 270.65, 214.65, 186.946};  // [K]
    // Layer pressure_array = {101325.0, 22632.0, 5474.9, 868.02, 110.91, 66.939, 3.9564, 0.3734};  // [Pa]
    Layer pressure_gradient_array = {1.0, 2.233611e-1, 5.403295e-2, 8.5666784e-3, 1.0945601e-3, 6.6063531e-4, 3.9046834e-5, 3.68501e-6};

    double geopotential_height = geometric_altitude * earth_radius / (geometric_altitude + earth_radius);  // geopotential altitude

    int j = 7;  // Layer number
    int i = 0;
    for (; i < 7;) {
        int k = (i + j) / 2;
        if (geopotential_height < height_array[k]) {
            j = k;
        } else {
            i = k;
        }
        if (j <= i + 1) {
            break;
        }
    }

    double temp_gradient = temperature_gradient_array[i];
    double temp_base = temperature_array[i];
    double delta_height = geopotential_height - height_array[i];
    double temp_local = temp_base + temp_gradient * delta_height;
    double theta = temp_local / temperature_array[0];

    double delta; 
    if (temp_gradient == 0.0) {
        delta = pressure_gradient_array[i] * std::exp(-gmr * delta_height / temp_base);
    } else {
        delta = pressure_gradient_array[i] * std::pow(temp_base / temp_local, gmr / temp_gradient);
    }
    double sigma = delta / theta;

    std::vector<double> res = {sigma * density_sealevel, delta * pressure_sealevel, theta * temp_sealevel};
    return res;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1f0, %rsp            # imm = 0x1F0
movq %rdi, -0x1b8(%rbp)
movq %rdi, %rax
movq %rax, -0x1b0(%rbp)
movq %rdi, -0x8(%rbp)
movsd %xmm0, -0x10(%rbp)
leaq -0x50(%rbp), %rdi
leaq 0x620c8(%rip), %rsi     # 0x97168
movl $0x40, %edx
callq 0x63a0
leaq -0x90(%rbp), %rdi
xorl %esi, %esi
movl $0x40, %edx
callq 0x6270
movsd 0x62043(%rip), %xmm0    # 0x97108
movsd %xmm0, -0x90(%rbp)
movsd 0x60563(%rip), %xmm0    # 0x95638
movsd %xmm0, -0x80(%rbp)
movsd 0x6201e(%rip), %xmm0    # 0x97100
movsd %xmm0, -0x78(%rbp)
movsd 0x62009(%rip), %xmm0    # 0x970f8
movsd %xmm0, -0x68(%rbp)
movsd 0x61ff4(%rip), %xmm0    # 0x970f0
movsd %xmm0, -0x60(%rbp)
leaq -0xd0(%rbp), %rdi
leaq 0x62099(%rip), %rsi     # 0x971a8
movl $0x40, %edx
callq 0x63a0
leaq -0x110(%rbp), %rdi
leaq 0x620c1(%rip), %rsi     # 0x971e8
movl $0x40, %edx
callq 0x63a0
movsd -0x10(%rbp), %xmm0
mulsd 0xaf37a(%rip), %xmm0    # 0xe44b8
movsd -0x10(%rbp), %xmm1
addsd 0xaf36d(%rip), %xmm1    # 0xe44b8
divsd %xmm1, %xmm0
movsd %xmm0, -0x118(%rbp)
movl $0x7, -0x11c(%rbp)
movl $0x0, -0x120(%rbp)
cmpl $0x7, -0x120(%rbp)
jge 0x351f8
movl -0x120(%rbp), %eax
addl -0x11c(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, -0x124(%rbp)
movsd -0x118(%rbp), %xmm0
movsd %xmm0, -0x1c0(%rbp)
movslq -0x124(%rbp), %rsi
leaq -0x50(%rbp), %rdi
callq 0x35860
movsd -0x1c0(%rbp), %xmm1
movsd (%rax), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x351d2
movl -0x124(%rbp), %eax
movl %eax, -0x11c(%rbp)
jmp 0x351de
movl -0x124(%rbp), %eax
movl %eax, -0x120(%rbp)
movl -0x11c(%rbp), %eax
movl -0x120(%rbp), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
jg 0x351f3
jmp 0x351f8
jmp 0x3516b
movslq -0x120(%rbp), %rsi
leaq -0x90(%rbp), %rdi
callq 0x35860
movsd (%rax), %xmm0
movsd %xmm0, -0x130(%rbp)
movslq -0x120(%rbp), %rsi
leaq -0xd0(%rbp), %rdi
callq 0x35860
movsd (%rax), %xmm0
movsd %xmm0, -0x138(%rbp)
movsd -0x118(%rbp), %xmm0
movsd %xmm0, -0x1d0(%rbp)
movslq -0x120(%rbp), %rsi
leaq -0x50(%rbp), %rdi
callq 0x35860
movsd -0x1d0(%rbp), %xmm0
subsd (%rax), %xmm0
movsd %xmm0, -0x140(%rbp)
movsd -0x138(%rbp), %xmm1
movsd -0x130(%rbp), %xmm0
movsd -0x140(%rbp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x148(%rbp)
movsd -0x148(%rbp), %xmm0
movsd %xmm0, -0x1c8(%rbp)
leaq -0xd0(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x35860
movsd -0x1c8(%rbp), %xmm0
divsd (%rax), %xmm0
movsd %xmm0, -0x150(%rbp)
movsd -0x130(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x35345
jp 0x35345
movslq -0x120(%rbp), %rsi
leaq -0x110(%rbp), %rdi
callq 0x35860
movsd (%rax), %xmm0
movsd %xmm0, -0x1d8(%rbp)
movsd 0xaf1c0(%rip), %xmm0    # 0xe44c0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
mulsd -0x140(%rbp), %xmm0
divsd -0x138(%rbp), %xmm0
callq 0x6790
movaps %xmm0, %xmm1
movsd -0x1d8(%rbp), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, -0x158(%rbp)
jmp 0x353a0
movslq -0x120(%rbp), %rsi
leaq -0x110(%rbp), %rdi
callq 0x35860
movsd (%rax), %xmm0
movsd %xmm0, -0x1e0(%rbp)
movsd -0x138(%rbp), %xmm0
divsd -0x148(%rbp), %xmm0
movsd 0xaf144(%rip), %xmm1    # 0xe44c0
divsd -0x130(%rbp), %xmm1
callq 0x6750
movaps %xmm0, %xmm1
movsd -0x1e0(%rbp), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, -0x158(%rbp)
movsd -0x158(%rbp), %xmm0
movsd -0x150(%rbp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x160(%rbp)
movb $0x0, -0x161(%rbp)
movsd -0x160(%rbp), %xmm0
movsd 0xaf0c5(%rip), %xmm1    # 0xe4498
mulsd %xmm1, %xmm0
movsd %xmm0, -0x190(%rbp)
movsd -0x158(%rbp), %xmm0
movsd 0xaf0a1(%rip), %xmm1    # 0xe4490
mulsd %xmm1, %xmm0
movsd %xmm0, -0x188(%rbp)
movsd -0x150(%rbp), %xmm0
movsd 0xaf07d(%rip), %xmm1    # 0xe4488
mulsd %xmm1, %xmm0
movsd %xmm0, -0x180(%rbp)
leaq -0x190(%rbp), %rax
movq %rax, -0x178(%rbp)
movq $0x3, -0x170(%rbp)
leaq -0x191(%rbp), %rdi
movq %rdi, -0x1e8(%rbp)
callq 0x7ac0
movq -0x1b8(%rbp), %rdi
movq -0x1e8(%rbp), %rcx
movq -0x178(%rbp), %rsi
movq -0x170(%rbp), %rdx
callq 0x35890
jmp 0x35466
leaq -0x191(%rbp), %rdi
callq 0x87a0
movb $0x1, -0x161(%rbp)
testb $0x1, -0x161(%rbp)
jne 0x354b0
jmp 0x354a4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a0(%rbp)
movl %eax, -0x1a4(%rbp)
leaq -0x191(%rbp), %rdi
callq 0x87a0
jmp 0x354c0
movq -0x1b8(%rbp), %rdi
callq 0x7760
movq -0x1b0(%rbp), %rax
addq $0x1f0, %rsp            # imm = 0x1F0
popq %rbp
retq
movq -0x1a0(%rbp), %rdi
callq 0x6760
nopl (%rax)