#version 430

// Error estimation compute shader for adaptive step size control
// Computes element-wise error estimate between two solutions

layout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;

layout(std430, binding = 0) buffer Y1Buffer {
    float y1[];  // Solution from full step
};

layout(std430, binding = 1) buffer Y2Buffer {
    float y2[];  // Solution from two half steps
};

layout(std430, binding = 2) buffer ErrorBuffer {
    float error[];  // Output error estimates
};

uniform float rtol;  // Relative tolerance
uniform float atol;  // Absolute tolerance
uniform int n;       // Number of elements

void main() {
    uint index = gl_GlobalInvocationID.x;
    
    if (index >= n) return;
    
    float val1 = y1[index];
    float val2 = y2[index];
    
    // Compute error estimate using relative and absolute tolerances
    float scale = atol + rtol * max(abs(val1), abs(val2));
    float diff = abs(val2 - val1);
    
    // Normalized error
    error[index] = diff / scale;
}