【问题标题】:Incompatible ranks 0 and 2 in assignment at (1)在 (1) 的分配中不相容的等级 0 和 2
【发布时间】:2017-04-05 21:52:57
【问题描述】:

我无法理解 gfortran 中的数组和标量。所以当试图运行这三个方程时

REAL(8), DIMENSION(1:NI, 1:NJ) :: Slope_rad, Aspect_rad

REAL(8) :: clearsky,theta,theta_PyrStat, &
    Transmissivity,I0,Pressure

REAL(8), DIMENSION(runl) :: SolarZenithAngleCorr_rad, &
                       SolarAzimuthAngle_rad, rm_r2, PRESS_in, Hillshade, P

theta = acos(cos(Slope_rad)) *cos(SolarZenithAngleCorr_rad(T)) & 
            +sin(Slope_rad)*sin(SolarZenithAngleCorr_rad(T)) & 
            *cos(SolarAzimuthAngle_rad(T)-Aspect_rad)           

clearsky = I0*rm_r2(T)*Transmissivity**(P/(Press_IN(T)*cos(SolarZenithAngleCorr_rad(T))))*cos(theta);

Hillshade(T) = 255*((cos(SolarZenithAngleCorr_rad(T))*cos(Slope_rad)) &
            +(sin(SolarZenithAngleCorr_rad(T)) * sin(Slope_rad)) &
            *cos(SolarAzimuthAngle_rad(T) - Aspect_rad))

我收到以下错误

main.f90:406:3:

theta = acos(cos(Slope_rad)) *cos(SolarZenithAngleCorr_rad(T)) & 

1 错误:在 (1) 的分配中不相容的等级 0 和 2 main.f90:411:3:

clearsky = I0*rm_r2(T)*Transmissivity**(P/(Press_IN(T)*cos(SolarZenithAngleCorr_rad(T))))*cos(theta);

1 错误:在 (1) 的分配中不相容的等级 0 和 1 main.f90:417:3:

Hillshade(T) = 255*((cos(SolarZenithAngleCorr_rad(T))*cos(Slope_rad)) &

1 错误:在 (1) 处的分配中不兼容的等级 0 和 2

【问题讨论】:

  • 你应该显示你的数组和变量的定义(见minimal reproducible example)。请使用标签 fortran 解决 Fortran 问题。当问题特定于版本时添加版本标签(这个不是)。
  • 右侧的变量之一是一个数组,可能是Slope_rad,但没有声明很难说是哪一个。我确定这是其他问题的重复,但我无法关闭它,因为我自己把 fortran 标签放在那里。
  • cos(Slope_rad) - Slope_rad 是一个二维(2 级)数组,cos 函数需要一个标量(0 级)参数。您需要指定使用Slope_rad 的哪个索引。例如。 cos(Slope_rad(1,1))
  • 同理P是rank 1数组,这里需要指定...Transmissivity**(P/...使用哪个索引。
  • @SteveES 这并不完全正确。 cos() 接受数组没有任何问题,它是一个基本函数。该错误稍后发生。

标签: arrays fortran gfortran


【解决方案1】:

您的Slope_rad 是一个数组。因此cos(Slope_rad) 仍然是一个数组。您不能将数组分配给标量 theta

先判断Slope_rad是什么意思,应该是数组还是标量,值是什么意思,然后研究什么

theta = acos(cos(Slope_rad)) *cos(SolarZenithAngleCorr_rad(T)) & 
            +sin(Slope_rad)*sin(SolarZenithAngleCorr_rad(T)) & 
            *cos(SolarAzimuthAngle_rad(T)-Aspect_rad)   

应该的意思。

正如 SteveES 所说,acos(cos(Slope_rad)) 不管Slope_rad 是什么,无论如何都用起来很奇怪。

【讨论】:

    【解决方案2】:

    让我们通过查看每个变量的排名来区分这个,从theta 的赋值开始:

    Rank(2, (1:NI, 1:NJ)) :: Slope_rad, Aspect_rad
    
    Rank(0) :: clearsky, theta, theta_PyrStat, Transmissivity, I0,Pressure
    
    Rank(1, (runl)) :: SolarZenithAngleCorr_rad, SolarAzimuthAngle_rad, &
                       rm_r2, PRESS_in, Hillshade, P
    

    请注意,我在这里发明了一个等级表示法 - Rank(N [, (D1, D2, ..., D<N>)]) 其中N 是数组等级(0 表示标量),(D1, D2, ..., D<N>) 是可选的维度列表(标量为空)。

    因此查看theta(根据 Vladimir F 的评论进行调整)并假设 T 是数组索引(相对于函数参数):

    theta = acos(cos(Slope_rad) * cos(SolarZenithAngleCorr_rad(T))   & 
                 + sin(Slope_rad) * sin(SolarZenithAngleCorr_rad(T)) & 
                 * cos(SolarAzimuthAngle_rad(T) - Aspect_rad))
    

    如果我们关注每个变量和函数的形状,我们应该会看到“等级守恒”:

    Rank(0) =? acos(cos(Rank(2)) * cos(Rank(1))        & 
                  + sin(Rank(2)) * sin(Rank(1))        & 
                  * cos(Rank(1) - Rank(2)))
    

    sincosacos 等数学函数是元素(函数在数组的每个元素上执行),返回值采用提供的参数的形式,例如,sin(Rank(2)) = Rank(2)。当您尝试计算 cos(SolarAzimuthAngle_rad(T) - Aspect_rad) 时会出现问题,因为 SolarAzimuthAngle_rad(T) - Aspect_rad = Rank(1) - Rank(2) 会引发不一致的排名错误。

    首先使用循环编写这些表达式并手动执行每个元素的操作可能会有所帮助,然后验证代码是否按预期工作,最后将其重构为更紧凑的数组操作形式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-17
      相关资源
      最近更新 更多