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