// File: /workspace/github_cpp_makefile_star2_O1/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 %rbx
subq $0x80, %rsp
movapd %xmm0, %xmm1
movq %rdi, %rbx
xorpd %xmm0, %xmm0
movapd %xmm0, 0x20(%rsp)
movapd %xmm0, 0x30(%rsp)
movapd %xmm0, 0x40(%rsp)
movapd %xmm0, 0x50(%rsp)
movabsq $-0x3fe6000000000000, %rax # imm = 0xC01A000000000000
movq %rax, 0x20(%rsp)
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq %rax, 0x30(%rsp)
movabsq $0x4006666666666666, %rax # imm = 0x4006666666666666
movq %rax, 0x38(%rsp)
movabsq $-0x3ff999999999999a, %rax # imm = 0xC006666666666666
movq %rax, 0x48(%rsp)
movabsq $-0x4000000000000000, %rax # imm = 0xC000000000000000
movq %rax, 0x50(%rsp)
movsd 0x310e9(%rip), %xmm2    # 0x49370
movapd %xmm2, %xmm0
mulsd %xmm1, %xmm0
addsd %xmm1, %xmm2
divsd %xmm2, %xmm0
movl $0x7, %edx
xorl %ecx, %ecx
leaq 0x22973(%rip), %rax     # 0x3ac18
cmpl $0x6, %ecx
jg 0x182d1
leal (%rdx,%rcx), %edi
movl %edi, %esi
shrl $0x1f, %esi
addl %edi, %esi
sarl %esi
movslq %esi, %rdi
movsd (%rax,%rdi,8), %xmm1
ucomisd %xmm0, %xmm1
ja 0x182c8
movl %esi, %ecx
jmp 0x182ca
movl %esi, %edx
leal 0x1(%rcx), %esi
cmpl %esi, %edx
jg 0x182a5
movslq %ecx, %rcx
movsd 0x20(%rsp,%rcx,8), %xmm3
leaq 0x22977(%rip), %rdx     # 0x3ac58
movsd (%rdx,%rcx,8), %xmm2
subsd (%rax,%rcx,8), %xmm0
movapd %xmm3, %xmm4
mulsd %xmm0, %xmm4
addsd %xmm2, %xmm4
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm3
leaq 0x22992(%rip), %rax     # 0x3ac98
movsd (%rax,%rcx,8), %xmm1
movsd %xmm1, 0x18(%rsp)
movsd %xmm4, 0x10(%rsp)
jne 0x1833a
jp 0x1833a
movsd 0x3106d(%rip), %xmm1    # 0x49390
xorpd 0x223a5(%rip), %xmm1    # 0x3a6d0
mulsd %xmm1, %xmm0
divsd %xmm2, %xmm0
callq 0x55f0
jmp 0x18353
divsd %xmm4, %xmm2
movsd 0x3104a(%rip), %xmm1    # 0x49390
divsd %xmm3, %xmm1
movapd %xmm2, %xmm0
callq 0x55d0
movsd 0x18(%rsp), %xmm1
mulsd %xmm0, %xmm1
movsd 0x10(%rsp), %xmm2
divsd 0x22835(%rip), %xmm2    # 0x3aba0
movapd %xmm1, %xmm0
divsd %xmm2, %xmm0
mulsd 0x3102d(%rip), %xmm0    # 0x493a8
leaq 0x68(%rsp), %rsi
movsd %xmm0, (%rsi)
mulsd 0x31014(%rip), %xmm1    # 0x493a0
movsd %xmm1, 0x8(%rsi)
mulsd 0x30fff(%rip), %xmm2    # 0x49398
movsd %xmm2, 0x10(%rsi)
leaq 0xf(%rsp), %rcx
movl $0x3, %edx
movq %rbx, %rdi
callq 0x18500
movq %rbx, %rax
addq $0x80, %rsp
popq %rbx
retq