// File: /workspace/github_cpp_makefile_star2_O2/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
movupd %xmm0, 0x38(%rsp)
andq $0x0, 0x58(%rsp)
movupd %xmm0, 0x28(%rsp)
movabsq $-0x3fe6000000000000, %rax # imm = 0xC01A000000000000
movq %rax, 0x20(%rsp)
movaps 0x1ebda(%rip), %xmm0    # 0x32380
movups %xmm0, 0x30(%rsp)
movaps 0x1ebde(%rip), %xmm0    # 0x32390
movups %xmm0, 0x48(%rsp)
movsd 0x35ba9(%rip), %xmm2    # 0x49368
movapd %xmm2, %xmm0
mulsd %xmm1, %xmm0
addsd %xmm1, %xmm2
divsd %xmm2, %xmm0
pushq $0x7
popq %rdi
xorl %esi, %esi
pushq $0x2
popq %r8
leaq 0x1ebc1(%rip), %rcx     # 0x323a0
cmpl $0x6, %esi
jg 0x13803
leal (%rdi,%rsi), %eax
cltd
idivl %r8d
cltq
movsd (%rcx,%rax,8), %xmm1
ucomisd %xmm0, %xmm1
cmovbel %eax, %esi
cmoval %eax, %edi
leal 0x1(%rsi), %eax
cmpl %eax, %edi
jg 0x137df
movslq %esi, %rax
movsd 0x20(%rsp,%rax,8), %xmm3
leaq 0x1ebcd(%rip), %rdx     # 0x323e0
movsd (%rdx,%rax,8), %xmm2
subsd (%rcx,%rax,8), %xmm0
movapd %xmm3, %xmm4
mulsd %xmm0, %xmm4
addsd %xmm2, %xmm4
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm3
leaq 0x1ebe8(%rip), %rcx     # 0x32420
movsd (%rcx,%rax,8), %xmm1
movaps %xmm1, 0x10(%rsp)
movsd %xmm4, 0x8(%rsp)
jne 0x1386b
jp 0x1386b
movsd 0x35b34(%rip), %xmm1    # 0x49388
xorpd 0x1e0d4(%rip), %xmm1    # 0x31930
mulsd %xmm1, %xmm0
divsd %xmm2, %xmm0
callq 0x55c0
jmp 0x13884
divsd %xmm4, %xmm2
movsd 0x35b11(%rip), %xmm1    # 0x49388
divsd %xmm3, %xmm1
movapd %xmm2, %xmm0
callq 0x55a0
movapd 0x10(%rsp), %xmm1
mulsd %xmm0, %xmm1
movsd 0x8(%rsp), %xmm2
divsd 0x1ea54(%rip), %xmm2    # 0x322f0
movapd %xmm1, %xmm0
divsd %xmm2, %xmm0
unpcklpd %xmm1, %xmm0            # xmm0 = xmm0[0],xmm1[0]
movsd 0x35af0(%rip), %xmm1    # 0x493a0
movhpd 0x35ae0(%rip), %xmm1    # xmm1 = xmm1[0],mem[0]
mulpd %xmm0, %xmm1
leaq 0x60(%rsp), %rsi
movapd %xmm1, (%rsi)
mulsd 0x35ac3(%rip), %xmm2    # 0x49390
movsd %xmm2, 0x10(%rsi)
pushq $0x3
popq %rdx
leaq 0x7(%rsp), %rcx
movq %rbx, %rdi
callq 0x13a30
movq %rbx, %rax
addq $0x80, %rsp
popq %rbx
retq