Python函数返回类型与fortran子例程声明类型不匹配

时间:2019-08-19 22:36:20

标签: python numpy fortran f2py

我有一些如下的Python代码,spherical.py

...
import f_utils

# (r, theta, phi)
class spherical_utilities(object):
    def __init__(self, ng, n, lab):
        self.n = n
        self.ng = ng
        self.set_ngauss()
        self.set_funcs_ang()
        self.set_all_layers(lab)

    def set_ngauss(self):
        k, w = ps_roots(self.ng)
        self.knots, self.weights = k * pi, w * pi
        self.thetas = self.knots
        self.sint = sin(self.thetas)
        self.cost = cos(self.thetas)
        self.tgt = tan(self.thetas)
        self.ctgt = 1 / self.tgt

    def set_funcs_ang(self):
        P = array([special.lpmn(self.n, self.n, ct) for ct in self.cost])
        self.data_Ang, self.data_Angd = P[:, 0, :, :], P[:, 1, :, :]

    def set_all_layers(self, lab):
        self.data_layers = [0]
        for bnd in lab.boundaries():
            r, rd, rdd = bnd.shape.R(self.knots)
            rdr = rd / r
            r2rd2 = r ** 2 + rd ** 2
            Rad = [0, {}, {}]
            Radd = [0, {}, {}]
            kis = [0, bnd.k1, bnd.k2]
            for i in [1, 2]:
                krs = kis[i] * r
                JY = array([special.sph_jnyn(self.n, kr) for kr in krs])[:, :, :]
                Rad[i] = {'j': JY[:, 0, :], 'h': JY[:, 0, :] + 1j * JY[:, 2, :]}
                Radd[i] = {'j': JY[:, 1, :], 'h': JY[:, 1, :] + 1j * JY[:, 3, :]}

            self.data_layers.append({'ki': kis,\
                                     'r': r,\
                                     'rd': rd,\
                                     'rdd': rdd,\
                                     'rdr': rdr,\
                                     'r2rd2': r2rd2,\
                                     'Rad': Rad,\
                                     'Radd': Radd})
...

def mat_ebcm_axi_tm(C, m, jh1, jh2, e12, e21):
    k1 = C.ki[1]
    k2 = C.ki[2]
    Rad1 = C.Rad(m, jh1, 1)
    Radd1 = C.Radd(m, jh1, 1)
    Rad2 = C.Rad(m, jh2, 2)
    Radd2 = C.Radd(m, jh2, 2)
    Angm = C.Ang(m)
    Angmd = C.Angd(m)
    return f_utils.axitm(Rad1, Radd1, Rad2, Radd2, Angm, Angmd,\
                         C.r, C.rd, C.sint, C.cost, k1, k2, e12, C.weights)

以及其他文件methods.py

...
import spherical
...
C = spherical.spherical_utilities(ng, n, lab)
... 
def ebcm_bnd_system(C, m, bnd, axisymm=False):
    lay = bnd.layer_no
    C.set_layer_no(lay)
    # Axisymmetric part
    if axisymm:
        Ajjtm = spherical.mat_ebcm_axi_tm(C, m, 'j', 'j', bnd.e12, bnd.e21)
...    
def methods_factory(meth_bnd_system):

...    

ebcm = methods_factory(ebcm_bnd_system)
...

f_utils.for中有一些与fortran对应的代码,如下所示:

SUBROUTINE axitm (NG,NN,Rad1,Radd1,Rad2,Radd2,Ang,Angd,
     &                        Rs,Rsd,SinT,CosT,k1,k2,ep12,w,O)
      implicit none
      INTEGER NG,NN
      COMPLEX*16 Rad1(NG,NN),Radd1(NG,NN),Rad2(NG,NN),Radd2(NG,NN)
      COMPLEX*16 Ang(NG,NN), Angd(NG,NN)
      COMPLEX*16 k1,k2,ep12
      REAL*8     SinT(NG),CosT(NG), Rs(NG),Rsd(NG)
      COMPLEX*16 O(NN,NN)
      COMPLEX*16 w(NG)
cf2py intent(out) O
cf2py intent(hide) NG,NN
      integer l,n,k
      complex*16 coef, j1,jd1,j2,jd2,pl,pdl,pn,pdn
      real*8 sn,cs,r,rd
      complex*16 fun1

      DO l=1,NN
      DO n=1,NN
        O(l,n)=0d0
      ENDDO
      ENDDO

      DO k=1,NG
      r  = Rs(k)
      rd = Rsd(k)
      cs = CosT(k)
      sn = SinT(k)

      DO l=1,NN
      DO n=1,NN

      j1  = Rad1(k,l)
      jd1 = Radd1(k,l)
      j2  = Rad2(k,n)
      jd2 = Radd2(k,n)
      pl  = Ang(k,l)
      pdl = Angd(k,l)
      pn  = Ang(k,n)
      pdn = Angd(k,n)

      fun1 = k1**2 * r**2 * ( jd1 * j2 -
     & ep12 * k2/k1 * j1 * jd2) *
     & pl * pn * sn
     & + k1 * rd * sn**2 * (pdl * pn - ep12*
     & pl * pdn) * j1 * j2
     & - (ep12 - 1) * (k1 * r * sn - k1 * rd * cs) *
     & j1 * j2 * pl * pn

      O(l,n) = O(l,n) + fun1*w(k)

      ENDDO
      ENDDO
      ENDDO

      DO l=1,NN
       coef = (0d0,1d0) * (2d0 * l + 1) / (2 * l * (l+1))
      DO n=1,NN
       O(l,n) = O(l,n) * coef
      ENDDO
      ENDDO

      end

对于Python:

  return f_utils.axitm(Rad1, Radd1, Rad2, Radd2, Angm, Angmd,\
                          C.r, C.rd, C.sint, C.cost, k1, k2, e12, C.weights)

对于fortran:

SUBROUTINE axitm (NG,NN,Rad1,Radd1,Rad2,Radd2,Ang,Angd,
      &                        Rs,Rsd,SinT,CosT,k1,k2,ep12,w,O)

我不想编辑我的fortran和Python原始文件。

正常运行spherical.py时,出现此错误:

  

ValueError:第0维必须固定为1,但必须为200

对于Python中的这一行代码:

return f_utils.axitm(Rad1, Radd1, Rad2, Radd2, Angm, Angmd,\
                          C.r, C.rd, C.sint, C.cost, k1, k2, e12, C.weights)

任何帮助将不胜感激。

0 个答案:

没有答案
相关问题