WRF icon indicating copy to clipboard operation
WRF copied to clipboard

Simulation hangs indefinitely in function sort_turb in module_wind_mav

Open sgremmo opened this issue 5 months ago • 0 comments

Describe the bug The function sort_turb occasionally enters an infinite loop during the sorting of wind turbines based on upstream positioning. This issue is difficult to reproduce consistently and appears to depend on specific combinations of wind direction and turbine layout. The issue may occur after several hours of simulation (which suggests a role of the wind direction). Preliminary analysis suggests that the sorting algorithm may be encountering a cycle in the directed graph representing the turbine upstream indices, which leads to an infinite loop. It is unclear whether the root cause lies in the input arrays (e.g., improperly sorted or malformed data) or in the algorithm itself, which may lack proper cycle detection.

To Reproduce Steps to reproduce the behavior:

  1. WRF version: 4.6.1 (commit https://github.com/wrf-model/WRF/commit/d66e442fccc04111067e29274c9f9eaccc3cef28)
  2. Use compiler and version: gfortran 11.4.0
  3. Use namelist options windfarm_opt = 0 , 0 , 2 , windfarm_ij = 2, windfarm_wake_model = 0, 0, 5 (all wake models are concerned)

Expected behavior Do you have any suggestions on cycle detection methods or improvements to the current sorting logic? I currently have implemented a mitigation to jump out of the infinite loop by adding a control flag.

Proposed patch index 43458328..e02ac934 100644 --- a/phys/module_wind_mav.F +++ b/phys/module_wind_mav.F @@ -954,6 +954,7 @@ MODULE module_wind_mav integer, intent(in) :: num_ups(nt), ups_index(nt,nt) integer, intent(inout) :: tbindx(nt) integer :: ic_tb, indx, kt, tt, flag(nt) + logical :: progress

    flag(:) = 0
    ic_tb = 0
 @@ -967,6 +968,7 @@ MODULE module_wind_mav
        end do

        do while (ic_tb < nt)
 +      progress = .false.
        do kt = 1, nt
            if (flag(kt) == 1) cycle

 @@ -978,9 +980,13 @@ MODULE module_wind_mav
                     ic_tb = ic_tb + 1
                     flag(kt) = 1
                     tbindx(ic_tb) = kt 
 +                  progress = .true.
                   end if
               end do
           end do
 +      if (.not. progress) then
 +        exit
 +      end if
       enddo

       if (sum(flag) < nt) then

sgremmo avatar Jun 13 '25 12:06 sgremmo