0

I know similar questions have already been answered however I did not find exact help for my problem. In C++ I have an array double pf[2][4] and I want to pass it to a Fortran 95 subroutine which shall overwrite the entries and then return it.

How do I have to declare this array in my c++ file when Fortran follows a column-major order unlike c++? My naive first try just leaving it as above resulted in a segmentation fault error.

Originally the code has been entirely in Fortran and the corresponding array was declared as REAL*8 P(0:3,4) and I am searching how to give the subroutine an array in this form while declaring it in C++.

The code of the subroutine can be found here: https://www.pp.rhul.ac.uk/~cowan/computing/tutorial99/rambo.f

      SUBROUTINE RAMBO(N,ET,XM,P,WT,LW)
      IMPLICIT REAL*8(A-H,O-Z)                                          AAFU0020
      DIMENSION XM(N),P(4,N),Q(4,100),Z(100),R(4),                      AAFU0021
     .   B(3),P2(100),XM2(100),E(100),V(100),IWARN(5)                   AAFU0022 
...

It generates four-momenta for particles in collider events which obey momentum conservation and on-shellness.

Here is my c++ code in which I really just want to declare the array and call the subroutine to fill it with values.

#include <iostream>
#include <iomanip>
#include <cmath>

using namespace std;

extern "C"{ void rambo_(int n, double sqrts, const double mf[2], double pf[4][4], double fwgt);}

double integrand(double pf[4][4]){

  double p1[4],p2[4],fwgt; //declaration four vectors and weight
  
  //constants
  const double sqrts = 2000;
  const double mf[2]={0,173}; //array with particle masses
  
  rambo_(2,sqrts,mf,pf,fwgt);

  
  return 0;
  
}

int main(){
    double pf[4][4];
    double x = integrand(pf);
    std::cout << std::fixed;
        std::cout << std::setprecision(16);
        std::cout << "Msquared = " << x << endl;
}

I link the files via

gfortran -c rambo.f
g++ -c demo1.cpp
g++ demo1.o rambo.o -o demo -lgfortran

Running ./demo returns Segmentation fault (core dumped). Thanks for any help!

minits
  • 3
  • 3
  • Welcome, please take the [tour], read [ask] and [mcve]. If you have a problem - like a Segmentation fault - with some code, you should always show the code We cannot say what you are doing wrong when you do not show your code. Do not ask how it is done in general, we have existing questions about that. Ask what is wrong with your case, often it is just a small problem that can be fixed easily. There is no point to ask someone to write a whole example for you when you do not give any starting point. – Vladimir F Героям слава Jun 15 '21 at 11:22
  • Be aware that `REAL*8 P(0:3,4)` is 2x bigger than `double pf[2][4]`. One has 16 elements, the other has 8 elements. That can't work. Please show your actual code and make sure that the number of elements is the same. – Vladimir F Героям слава Jun 15 '21 at 11:25
  • Please supply your exact code and the exact error messages if my previous comment and the link https://stackoverflow.com/questions/4083490/how-do-i-pass-a-2d-array-in-c-to-a-fortran-subroutine do not explain the problem sufficiently. – Vladimir F Героям слава Jun 15 '21 at 12:31
  • I edited my question with some code. – minits Jun 15 '21 at 15:58
  • Your arguments are wrong, you need to pass your scalars by reference. Fortran, with some simplifications, expects the arguments by reference. Pass pointers. See the duplicate links above. – Vladimir F Героям слава Jun 15 '21 at 16:18
  • That means `(int *n, double *sqrts, const double mf[2], double pf[4][4], double *fwgt);` – Vladimir F Героям слава Jun 15 '21 at 16:26

0 Answers0