#include "WindInverserToolGPU.cuh" #include "GPUTool.cuh" // 使用 __device__ 限定符,使函数在GPU上执行且只能被其他GPU函数调用 __device__ float windspeedcmd5_device(float angle, float incidenceangle, float sigma0) { // CMOD5模型系数数组 - 常量内存通常更适合此类数据 const float cmod5_c[30] = { 1.0f, -0.688f, -0.793f, 0.338f, -0.173f, 0.0f, 0.004f, 0.111f, 0.0162f, 6.34f, 2.57f, -2.18f, 0.4f, -0.6f, 0.045f, 0.007f, 0.33f, 0.012f, 22.0f, 1.95f, 3.0f, 8.39f, -3.44f, 1.36f, 5.35f, 1.99f, 0.29f, 3.80f, 1.53f }; // 确保入射角不小于16度 if (incidenceangle + 0.5f <= 16.0f) { incidenceangle = 16.0f; } // 在0-26m/s范围内搜索风速 for (float U = 0.0f; U <= 26.0f; U += 0.01f) { // 计算归一化参数 float y0 = cmod5_c[19]; // 索引调整:C数组从0开始 float n = cmod5_c[20]; float a = y0 - (y0 - 1.0f) / n; float b = 1.0f / (n * powf(y0 - 1.0f, n - 1.0f)); // 使用powf而非^ // 归一化入射角 float x = (incidenceangle - 40.0f) / 25.0f; // 计算基础后向散射系数 float a0 = cmod5_c[1] + cmod5_c[2] * x + cmod5_c[3] * x * x + cmod5_c[4] * x * x * x; float a1 = cmod5_c[5] + cmod5_c[6] * x; float a2 = cmod5_c[7] + cmod5_c[8] * x; float gamma = cmod5_c[9] + cmod5_c[10] * x + cmod5_c[11] * x * x; float s0 = cmod5_c[12] + cmod5_c[13] * x; float s = a2 * U; // 计算饱和函数 float f; if (s < s0) { float g = 1.0f / (1.0f + expf(-s0)); // 使用expf float alpha = s0 * (1.0f - g); f = powf(s / s0, alpha) * g; // 使用powf } else { f = 1.0f / (1.0f + expf(-s)); } // 计算各向同性部分 float b0 = powf(f, gamma) * powf(10.0f, a0 + a1 * U); // 使用powf // 计算一阶调和系数 float b1_term = cmod5_c[15] * U * (0.5f + x - tanhf(4.0f * (x + cmod5_c[16] + cmod5_c[17] * U))); float b1 = (cmod5_c[14] * (1.0f + x) - b1_term) / (expf(0.34f * (U - cmod5_c[18])) + 1.0f); // 计算二阶调和系数 float v0 = cmod5_c[21] + cmod5_c[22] * x + cmod5_c[23] * x * x; float d1 = cmod5_c[24] + cmod5_c[25] * x + cmod5_c[26] * x * x; float d2 = cmod5_c[27] + cmod5_c[28] * x; float y = (U / v0 + 1.0f); float v2; if (y < y0) { v2 = a + b * powf(y - 1.0f, n); // 使用powf } else { v2 = y; } float b2 = (-d1 + d2 * v2) * expf(-v2); // 计算模拟后向散射系数并与实测值比较 float angle_rad = angle * 3.14159265f / 180.0f; float sigma0_model = 10.0f * log10f(b0 * powf(1.0f + b1 * cosf(angle_rad) + b2 * cosf(2.0f * angle_rad), 1.6f)); if (sigma0_model - sigma0 >= 0.0f) { return U; } } return 26.0f; // 如果未找到,返回最大风速 } __global__ void CUDA_WindSpeedInversered_Kernel(float* in_wind_dir_U_arr_cuda, float* in_wind_dir_V_arr_cuda, float* in_inc_angle_arr_cuda, float* in_sar_sigma0_arr_cuda, float* out_wind_speed_arr_cuda, int64_t pixelCount) { int64_t idx = blockIdx.x * blockDim.x + threadIdx.x; if (idx < pixelCount) { float sar_sigma0 = in_sar_sigma0_arr_cuda[idx]; if (isinf(sar_sigma0) || isnan(sar_sigma0)) { out_wind_speed_arr_cuda[idx] = -1; } else { float U10 = in_wind_dir_U_arr_cuda[idx]; float V10 = in_wind_dir_V_arr_cuda[idx]; float inc_angle = in_inc_angle_arr_cuda[idx]; float wind_dir_angle = 270 - atan2(V10, U10) * 180.0 / PI; wind_dir_angle = fmodf(wind_dir_angle, 360.0f); float out_wind_speed = windspeedcmd5_device(wind_dir_angle, inc_angle, sar_sigma0); //printf("windspeedcmd5(%f, %f, %f)-%f \n", wind_dir_angle, inc_angle, sar_sigma0, out_wind_speed); out_wind_speed_arr_cuda[idx] = out_wind_speed; } } } void WindSpeedInverseredFunc(float* in_wind_dir_U_arr_cuda, float* in_wind_dir_V_arr_cuda, float* in_inc_angle_arr_cuda, float* in_sar_sigma0_arr_cuda, float* out_wind_speed_arr_cuda, int64_t pixelCount) { // 设置 CUDA 核函数的网格和块的尺寸 int64_t blockSize = 256; // 每个块的线程数 int64_t numBlocks = (pixelCount + blockSize - 1) / blockSize; // 根据 pixelcount 计算网格大小 // 调用 CUDA 核函数 CUDA_WindSpeedInversered_Kernel << > > (in_wind_dir_U_arr_cuda, in_wind_dir_V_arr_cuda, in_inc_angle_arr_cuda, in_sar_sigma0_arr_cuda, out_wind_speed_arr_cuda, pixelCount); #ifdef __CUDADEBUG__ cudaError_t err = cudaGetLastError(); if (err != cudaSuccess) { printf("CUDAdistanceAB CUDA Error: %s\n", cudaGetErrorString(err)); exit(2); } #endif // __CUDADEBUG__ cudaDeviceSynchronize(); }