Skip to content

Commit f6d6400

Browse files
committed
- Fixes redundant IFAIL errors in IGT routines (see #252).
- Removes writing to stdout from Fortran files - this removes dependence on quadmath library (was causing problems in some compilation environments). Now ifail is checked in "interaction.c" - errors should appear only seldom (i.e. when `-eps 12` is used).
1 parent 22cd414 commit f6d6400

File tree

2 files changed

+33
-14
lines changed

2 files changed

+33
-14
lines changed

src/fort/propaesplibreintadda.f

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@
1313
c license: GNU GPL
1414

1515
subroutine propaespacelibreintadda(Rij,k0a,
16-
$ gridspacex,gridspacey,gridspacez,relreq,result)
16+
$ gridspacex,gridspacey,gridspacez,relreq,result,IFAIL)
1717
implicit none
1818
integer i,j
1919
c definition of the position of the dipole, observation, wavenumber
2020
c ,wavelength, spacing lattice
2121
double precision result(12)
2222
double precision k0a,gridspacexm,gridspaceym,gridspacezm
2323
double precision x,y,z,gridspacex,gridspacey,gridspacez
24-
double precision k0,xx0,yy0,zz0
24+
double precision k0,xx0,yy0,zz0,RR
2525
double precision Rij(3)
2626

2727
c The structure of the result is the following:
@@ -43,23 +43,33 @@ subroutine propaespacelibreintadda(Rij,k0a,
4343
y=Rij(2)
4444
z=Rij(3)
4545
k0=k0a
46-
gridspacexm=gridspacex*0.1d0
47-
gridspaceym=gridspacey*0.1d0
48-
gridspacezm=gridspacez*0.1d0
46+
gridspacexm=gridspacex*0.01d0
47+
gridspaceym=gridspacey*0.01d0
48+
gridspacezm=gridspacez*0.01d0
4949
c We perform the integration of the tensor
5050
c definition for the integration
5151
MINCLS = 1000
5252
MAXCLS = 1000000
5353
KEY = 0
54-
ABSREQ = 0.d0
55-
54+
55+
c Based on the conservative estimate from below of the largest
56+
c component of the integral. For moderate and large distances the
57+
c integral will actually scale as k^2/R, for small distances R^-3
58+
c dependence will lead to larger values than based on its center
59+
RR=x*x+y*y+z*z
60+
ABSREQ = RELREQ*gridspacex*gridspacey*gridspacez/(RR**1.5d0)
61+
c ABSREQ=0
62+
5663
A(1)=-gridspacex/2.d0
5764
A(2)=-gridspacey/2.d0
5865
A(3)=-gridspacez/2.d0
5966
B(1)=+gridspacex/2.d0
6067
B(2)=+gridspacey/2.d0
6168
B(3)=+gridspacez/2.d0
6269

70+
c If some of the coordinates are small, the corresponding
71+
c non-diagonal terms of the Green's tensor are further considered
72+
c null (during each integrand evaluation)
6373
xx0=1.d0
6474
yy0=1.d0
6575
zz0=1.d0
@@ -80,9 +90,12 @@ subroutine propaespacelibreintadda(Rij,k0a,
8090
result(N)=result(N)/gridspacex/gridspacey/gridspacez
8191
enddo
8292

83-
if (ifail.ne.0) then
84-
write(*,*) 'IFAIL in IGT routine',IFAIL
85-
endif
93+
c We return IFAIL instead of testing it here to avoid output to
94+
c terminal directly from Fortran, which leads to dependence on
95+
c quadmath library
96+
c if (ifail.ne.0) then
97+
c write(*,*) 'IFAIL in IGT routine',IFAIL
98+
c endif
8699

87100
end
88101
c*************************************************************

src/interaction.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ static __m128d exptbl[361];
6868
#ifndef NO_FORTRAN
6969
// fort/propaesplibreintadda.f
7070
void propaespacelibreintadda_(const double *Rij,const double *ka,const double *gridspacex,const double *gridspacey,
71-
const double *gridspacez,const double *relreq,double *result);
71+
const double *gridspacez,const double *relreq,double *result,int *ifail);
7272
#endif
7373
// sinint.c
7474
void cisi(double x,double *ci,double *si);
@@ -974,17 +974,23 @@ static inline void InterTerm_igt(double qvec[static 3],doublecomplex result[stat
974974
double rr,rn,invr3,kr,kr2; // |R|, |R/d|, |R|^-3, kR, (kR)^2
975975
doublecomplex expval; // exp(ikR)/|R|^3
976976
double tmp[12];
977-
int comp;
977+
int comp,ifail;
978978

979979
// the following looks complicated, but should be easy to optimize by compiler
980980
if (igt_lim==UNDEF || DotProd(qvec,qvec)<=maxRectScale*maxRectScale*igt_lim*igt_lim
981981
*(unitsGrid ? 1 : (gridspace*gridspace)) ) {
982982
if (unitsGrid) vMultScal(gridspace,qvec,qvec);
983-
/* passing complex vectors from Fortran to c is not necessarily portable (at least requires extra effort in
983+
/* passing complex vectors from Fortran to C is not necessarily portable (at least requires extra effort in
984984
* the Fortran code. So we do it through double. This is not bad for performance, since double is anyway used
985985
* internally for integration in this Fortran routine.
986986
*/
987-
propaespacelibreintadda_(qvec,&WaveNum,&gridSpaceX,&gridSpaceY,&gridSpaceZ,&igt_eps,tmp);
987+
propaespacelibreintadda_(qvec,&WaveNum,&gridSpaceX,&gridSpaceY,&gridSpaceZ,&igt_eps,tmp,&ifail);
988+
if (ifail!=0) {
989+
if (ifail==1) LogWarning(EC_WARN,ALL_POS,"Failed to reach relative accuracy of %g for Green's tensor "
990+
"integration for distance "GFORMDEF3V,igt_eps,COMP3V(qvec));
991+
else LogWarning(EC_WARN,ALL_POS,"Error in Green's tensor integration (code %d - see dcuhre.f) for distance "
992+
GFORMDEF3V,ifail,COMP3V(qvec));
993+
}
988994
for (comp=0;comp<6;comp++) result[comp] = tmp[comp] + I*tmp[comp+6];
989995
}
990996
else {

0 commit comments

Comments
 (0)