WHERE statement can limit the ability to debug the code: see stack overflow. As mentioned in the thread, it could be converted into DO-ELSE-IF loop. However, It might not that charming if the array have several dimensions. As it implies to deal with multiple loops: nesting,…

  • DO-IF clauses: maximum flexibility. Ideal for debugging.

See below for alternatives:

  • DO CONCURRENT statement. Decent for debugging.
    • It allows for WRITE statements.
  • FORALL statement: nonetheless, considered obsolescent in favor of DO CONCURRENT
    • It does NOT allow WRITE statements

Run the example on www.onecompiler.com

Source code:

program hello

integer, parameter :: nc=2
integer, parameter :: nsl = 5
real :: ab_w_soil_fc_sl(nc,nsl)
real :: ab_w_soil_sl(nc,nsl)
real :: ab_moisture_sl_conc(nc,nsl)
real :: ab_moisture_sl_where(nc,nsl)
real :: ab_moisture_sl_forall(nc,nsl)
real :: ab_moisture_sl_doif(nc,nsl)

ab_moisture_sl_doif = 0.
ab_moisture_sl_conc = 0.
ab_moisture_sl_where = 0.
ab_moisture_sl_forall = 0.

ab_w_soil_fc_sl(1,:) = 2.
ab_w_soil_fc_sl(2,:) = 0.
ab_w_soil_sl = 1.

! original WHERE statement
WHERE (ab_w_soil_fc_sl > 0.) ! should it happen?
  ab_moisture_sl_where(:,:) = ab_w_soil_sl(:,:) / ab_w_soil_fc_sl(:,:)
END WHERE

! equivalent WHERE statement into DO-IF construct
DO ic=1, nc
  DO is=1, nsl
    IF (ab_w_soil_fc_sl(ic,is) > 0.0) THEN
      ab_moisture_sl_doif(ic,is) = ab_w_soil_sl(ic,is) / ab_w_soil_fc_sl(ic,is)
      write(*,*) "ic, is, do if:", ic, is, ab_moisture_sl_conc(ic,is)
    END IF
  END DO
END DO

! Alternative (recommended)
DO CONCURRENT (ic=1:nc, is=1:nsl, ab_w_soil_fc_sl(ic,is) > 0.0)
  ab_moisture_sl_conc(ic,is) = ab_w_soil_sl(ic,is) / ab_w_soil_fc_sl(ic,is)
  write(*,*) "ic, is, do conc:", ic, is, ab_moisture_sl_conc(ic,is)
END DO

! Alternative (but obsolete)
FORALL (ic=1:nc, is=1:nsl, ab_w_soil_fc_sl(ic,is) > 0.0)
  ab_moisture_sl_forall(ic,is) = ab_w_soil_sl(ic,is) / ab_w_soil_fc_sl(ic,is)
END FORALL

write(*,*) "doif=", ab_moisture_sl_doif
write(*,*) "conc=", ab_moisture_sl_conc
write(*,*) "where=", ab_moisture_sl_where
write(*,*) "forall=", ab_moisture_sl_forall

end program hello

Expected output:

ic, is, do if:           1           1   0.00000000    
ic, is, do if: 1 2 0.00000000
ic, is, do if: 1 3 0.00000000
ic, is, do if: 1 4 0.00000000
ic, is, do if: 1 5 0.00000000
ic, is, do conc: 1 1 0.500000000
ic, is, do conc: 1 2 0.500000000
ic, is, do conc: 1 3 0.500000000
ic, is, do conc: 1 4 0.500000000
ic, is, do conc: 1 5 0.500000000
doif= 0.500000000 0.00000000 0.500000000 0.00000000 0.500000000 0.00000000 0.500000000 0.00000000 0.500000000 0.00000000
conc= 0.500000000 0.00000000 0.500000000 0.00000000 0.500000000 0.00000000 0.500000000 0.00000000 0.500000000 0.00000000
where= 0.500000000 0.00000000 0.500000000 0.00000000 0.500000000 0.00000000 0.500000000 0.00000000 0.500000000 0.00000000
forall= 0.500000000 0.00000000 0.500000000 0.00000000 0.500000000 0.00000000 0.500000000 0.00000000 0.500000000 0.00000000

Leave a Reply

Your email address will not be published. Required fields are marked *